1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
|
;********************************************************************************
; File: PRN_DEF.ASM
;
; Subroutines to read the printer profile file, extract the printer names,
; build a scroll list for the cas services and retrieve addition information
; from the file on a specific printer.
; Also contains a subroutine to change the parameters for the SELECT command
; in the autoexec.bat file.
;
;********************************************************************************
PAGE , 132 ;AN000;
.ALPHA ;AN000;
.XLIST ;AN000;
INCLUDE MACROS.INC ;AN000;
INCLUDE STRUC.INC ;AN000;
.LIST ;AN000;
;***************************************************************************
; Define the public subroutines in this module
;***************************************************************************
PUBLIC GET_PRINTER_TITLES_ROUTINE ;AN000;
PUBLIC GET_PRINTER_INFO_ROUTINE ;AN000;
PUBLIC RELEASE_PRINTER_INFO_ROUTINE ;AN000;
PUBLIC CHANGE_AUTOEXEC_ROUTINE ;AN000;
;***************************************************************************
; Define the public values in this module
;***************************************************************************
PUBLIC SEG_LOC ;AN000; The segment where the printer data is stored
PUBLIC NAMES_OFF ;AN000; The offset in the segment of the names table
PUBLIC N_PRN_NAMES ;AN000; The number of printer definitions read from the profile
PUBLIC MAX_NAME ;AN000; The longest name in the list
PUBLIC SIZE_NAMES ;AN000; The number of bytes between each printer name (abs)
PUBLIC SEL_FLG ;AN000; AN000; SELECT runtime flag
EXTRN SYSPARSE: FAR;AN000;
EXTRN POS_ZERO: FAR;AN000;
EXTRN COPY_ROUTINE: FAR;AN000;
EXTRN I_PRINTER: WORD;AN000;
EXTRN N_PRINTER_TYPE: BYTE;AN000;
EXTRN S_MODE_PARM: WORD;AN000;
EXTRN S_CP_DRIVER: WORD;AN000;
EXTRN S_CP_PREPARE: WORD;AN000;
EXTRN S_GRAPH_PARM: WORD;AN000;
EXTRN HOOK_INT_24:FAR;AN000;
EXTRN RESTORE_INT_24:FAR;AN000;
EXTRN INT_24_ERROR:WORD;AN000;
EXTRN BIN_TO_CHAR_ROUTINE:FAR;AN000;
DATA SEGMENT BYTE PUBLIC 'DATA';AN000;
SEL_FLG DB 0 ;AN000; Select flag byte
;INSTALLRW EQU 80H ;AN000; INSTALL diskette is R/W
SEG_LOC DW 0 ;AN000; Location of the segment where the data is
NAMES_OFF DW 0 ;AN000; The offset of the names table in the segment
SEGMENT_SIZE DW 0 ;AN000; Amount of memory available
BUFFER_START DW 0 ;AN000; Starting offset of the file data buffer
BUFFER_SIZE DW 0 ;AN000; Number of bytes in the file data buffer
FILE_PTR_AT_START DD 0 ;AN000; The file pointer for the data which is at
; the beginning of the file data buffer
AMOUNT_OF_DATA DW 0 ;AN000; The number of bytes in the file data buffer
CURRENT_PARSE_LOC DW 0 ;AN000; The location to start the next parse.
END_CUR_LINE DW 0 ;AN000; The address of the end of the line currently being parsed
CX_ORDINAL_VALUE DW 0 ;AN000; The value returned by the parse for next call
NUM_PRINTER_DEFS DB 0 ;AN000; The number of printer definitions in the file
N_PRN_NAMES DW 0 ;AN000; The next free index into the names table
FILE_HANDLE DW 0 ;AN000; Handle for the printer definition file.
MAX_NAME DW 0 ;AN000; The length of the longest printer name found in the file
START_NEXT_LINE DW 0 ;AN000; The starting offset of the next line to parse
APPEND_POINTER DW 0 ;AN000; Offset of the ASCII-N string to append to the SELECT line
FILENAME DW 0 ;AN000; Offset of the ASCII-N string containing the filename
CDP_FOUND DB 0 ;AN000;
CPP_FOUND DB 0 ;AN000;
W_VALUE DW 0 ;AN000;
STRING_N DB 10 DUP(0);AN000;
;AD000;JW BLANK_MODE DW END_BLANK_MODE - $ - 3 ; The blank line for inserting mode parameters
;AD000;JW DB ' , , , , ',?
;AD000;JW END_BLANK_MODE EQU $
BLANK_STRING DW 0 ;AN000; Blank values for the other printer profile parameters
E_SIZE_CR_LF EQU 2 ;AN000; The number of bytes in W_CR_LF
W_CR_LF DB 13,10 ;AN000; Carrage return and line feed to append to the select line
READ_FLAG DB 0 ;AN000; Flag for use when reading data
AT_EOF EQU 1B ;AN000; Indicates when the end of file has been reached
LAST_LINE EQU 10B ;AN000; Indicates if this is the last line in the buffer
RESET_EOF EQU 11111110B ;AN000; Masks for resetting the flags
RESET_LST_LINE EQU 11111101B ;AN000;
PARSE_FLAG DB 0 ;AN000; Flag for use when parsing the data
FIRST_PARSE EQU 1B ;AN000; Indicates if this is the first line being parsed
LINE_DONE EQU 10B ;AN000; Indicates if the current line has already been parsed
FIRST_NAME EQU 100B ;AN000; Indicates if a printer names has already been found
RESET_FIRST_PARSE EQU 11111110B ;AN000; Masks for resetting the flags
RESET_LINE_DONE EQU 11111101B ;AN000;
RESET_FIRST_NAME EQU 11111011B ;AN000;
;***************************************************************************
; Error codes returned.
;***************************************************************************
ERR_NOT_ENOUGH_MEM EQU 1 ;AN000; There was not enough memory to build the names table
ERR_OPENING_FILE EQU 2 ;AN000; Error opening a file
ERR_READING_FILE EQU 3 ;AN000; Error reading from a file
ERR_FINDING_VALUE EQU 4 ;AN000; Error finding the number of prn defs at the beginning of the file
ERR_LINE_TOO_LONG EQU 5 ;AN000; There was a line too long for the buffer
ERR_FINDING_NAME EQU 6 ;AN000; There was an error locating a printer name after a P or S
ERR_ACCESSING_FILE EQU 7 ;AN000; There was an error updating the file pointer
ERR_TOO_MANY_DEFS EQU 8 ;AN000; There are too many defintion in the file
ERR_NUMBER_MATCH EQU 9 ;AN000; The number of actual definition do not match the number expected
ERR_ALLOCATING_MEM EQU 10 ;AN000; There was an error allocating memory
ERR_CDP_CPP EQU 11 ;AN000; A prn defn had either a CDP or CPP but not both
ERR_PRN_DEFN EQU 12 ;AN000;
TRUE EQU 1 ;AN000;
FALSE EQU 0 ;AN000;
E_CR EQU 13 ;AN000;
E_LF EQU 10 ;AN000;
E_FILE_TERM EQU 1AH ;AN000;
E_MAX_PRN_NAME_LEN EQU 40 ;AN000; The maximum printer name length
LENGTH_FILE_PTR EQU 4 ;AN000; The number of bytes in the file pointer
MAX_NUM_PRINTER_DEFS EQU 31 ;AC089;SEH ;AC073; The maximum number of printer definitions
MIN_SIZE_FILE_BUFFER EQU 0400H ;AN000; The minimum amount of memory needed for the file data buffer
LENGTH_PRT_TYPE_IND EQU 1 ;AN000; The length of the printer type indicator
SIZE_NAMES EQU E_MAX_PRN_NAME_LEN+LENGTH_FILE_PTR+LENGTH_PRT_TYPE_IND ;AN000; The size of one entry in the names table
NAMES_TABLE_SIZE EQU SIZE_NAMES * MAX_NUM_PRINTER_DEFS ;AN000; The size of the names table
MINIMUM_MEMORY EQU NAMES_TABLE_SIZE + MIN_SIZE_FILE_BUFFER ;AN000; The minimum amount of memory required
RANGE_ONLY EQU 1 ;AN000; The parser is only to look for ranges of values
RANGE_AND_STRING EQU 3 ;AN000; The parser is to look for ranges and strings
NUMERIC_VALUE EQU 08000H ;AN000; Parser constant for searching for numeric values
SIMPLE_STRING EQU 02000H ;AN000; Parser constant for searching for strings
; Control blocks for the parser.
; The PARMS INPUT BLOCK
PARMS LABEL BYTE ;AN000;
PAR_EXTEN DW OFFSET PARMSX ;AN000; Offset of the PARMS EXTENSION BLOCK
PAR_NUM DB 2 ;AN000; The number of further definitions
DB 0 ;AN000;
DB 1 ;AN000;
DB 1AH ;AN000;
; The PARMS EXTENSION BLOCK
PARMSX LABEL BYTE;AN000;
PAX_MINP DB 0 ;AN000;
PAX_MAXP DB 1 ;AN000;
DW CONTROL_P1 ;AN000;
PAX_MAX_SW DB 0;AN000;
PAX_MAX_K1 DB 0;AN000;
; The control blocks for the definition of positional parameters, switch and
; keywords.
CONTROL_P1 EQU $ ;AN000;
CTL_FUNC_FL DW 2000H;AN000;
DW 0002H ;AN000;
DW RESULT_P1 ;AN000;
DW VALUE_LIST_P1 ;AN000;
DB 0 ;AN000;
VALUE_LIST_P1 EQU $;AN000;
VAL_NUM DB 1 ;AN000; Number of value definitions
DB 1 ;AN000; Number of range definitions
DB 8 ;AN000; Return value if parameter is in this range
DD 0 ;AN000;
DD 255 ;AN000;
DB 0 ;AN000; Number of actual value definitions
NUM_STRINGS DB 2 ;AN000; Number of string definitions
DB 1 ;AN000; Value to be returned if this string is matched
DW OFFSET KEYWORD_PARALLEL;AN000;
DB 2 ;AN000; Value to be returned if this string is matched
DW OFFSET KEYWORD_SERIAL;AN000;
DB 3 ;AN000; Value to be returned if this string is matched
DW OFFSET KEYWORD_MODE;AN000;
DB 4 ;AN000; Value to be returned if this string is matched
DW OFFSET KEYWORD_CODE_DRIVER;AN000;
DB 5 ;AN000; Value to be returned if this string is matched
DW OFFSET KEYWORD_CODE_PREPARE;AN000;
DB 6 ;AN000; Value to be returned if this string is matched
DW OFFSET KEYWORD_GRAPHICS;AN000;
KEYWORD_PARALLEL DB 'P',0;AN000;
KEYWORD_SERIAL DB 'S',0;AN000;
KEYWORD_MODE DB 'SP',0;AN000;
KEYWORD_CODE_DRIVER DB 'CDP',0;AN000;
KEYWORD_CODE_PREPARE DB 'CPP',0;AN000;
KEYWORD_GRAPHICS DB 'GP',0;AN000;
RESULT_P1 LABEL BYTE;AN000;
DB 0 ;AN000; Type of operand returned
MATCHED_TAG DB 0 ;AN000; Matched item tag
SYNONYM_PTR DW 0 ;AN000; Offset of synonym returned
RESULT_FIELD DB 0,0,0,0 ;AN000; Unsure what this is...
;AD000;JW ;***************************************************************************
;AD000;JW ; Parser control blocks for parsing the mode parameters
;AD000;JW ;***************************************************************************
;AD000;JW MODE_PARMS LABEL BYTE
;AD000;JW DW MODE_PARMSX
;AD000;JW DB 0
;AD000;JW
;AD000;JW MODE_PARMSX LABEL BYTE
;AD000;JW DB 0,0
;AD000;JW DB 0
;AD000;JW DB 1
;AD000;JW DW OFFSET CNTL_BAUD
;AD000;JW
;AD000;JW CNTL_BAUD LABEL BYTE
;AD000;JW DW SIMPLE_STRING
;AD000;JW DW 2
;AD000;JW DW RESULT_P1
;AD000;JW DW MODE_VALUES
;AD000;JW DB 5
;AD000;JW SYN_BAUD DB 'BAUD',0
;AD000;JW SYN_PARITY DB 'PARITY',0
;AD000;JW SYN_DATA DB 'DATA',0
;AD000;JW SYN_STOP DB 'STOP',0
;AD000;JW SYN_RETRY DB 'RETRY',0
;AD000;JW
;AD000;JW MODE_VALUES LABEL BYTE
;AD000;JW DB 0
;***************************************************************************
; Parser control blocks for parsing the AUTOEXEC.BAT file for 'SELECT'
;***************************************************************************
SELECT_PARMX LABEL BYTE ;AN000;
DB 1,1 ;AN000;
DW SELECT_CONTROL ;AN000;
DB 0 ;AN000;
DB 0 ;AN000;
SELECT_CONTROL LABEL BYTE;AN000;
DW 2000H ;AN000;
DW 2 ;AN000;
DW RESULT_P1 ;AN000;
DW SELECT_VALUE ;AN000;
DB 0 ;AN000;
SELECT_VALUE LABEL BYTE ;AN000;
DB 3 ;AN000;
DB 0 ;AN000;
DB 0 ;AN000;
DB 1 ;AN000;
DB 1 ;AN000;
DW OFFSET SELECT_STR;AN000;
SELECT_STR DB 'SELECT',0;AN000;
ALLOC_FLAG DB 0
ALLOCATED EQU 80H
DATA ENDS ;AN000;
CODE_FAR SEGMENT BYTE PUBLIC 'CODE';AN000;
ASSUME CS:CODE_FAR, DS:DATA, ES:DATA;AN000;
;***************************************************************************
; Routines for extracting the printer names from the file data and storing
; them in a table located in high memory. In addition to the name, the
; type of printer, whether Parallel or Serial and the location in the file
; of this printer name is also saved in the table.
;***************************************************************************
;******************************************************************************
;
; Routine: GET_PRINTER_TITLES_ROUTINE - Reads the names of all the printers
; and their location in the file into a data
; buffer in high memory.
;
; Input:
; DI - The offset of name of the file which contains the printer definitions
; in ASCII-N format.
;
; Output:
; If CY = 1: Indicates that an error has occured.
; BX - The error code for the error which this subroutine detected.
; AX - The error code which was returned if the error was as a result
; of a DOS call.
; If CY = 0: No error has occured.
; AX, BX - Undefined.
;
;******************************************************************************
GET_PRINTER_TITLES_ROUTINE PROC FAR ;AN000;
;
CALL HOOK_INT_24 ;AN000;
;; int 3
;; nop
PUSH ES ;AN000;
;**********************************************************************
; Allocate the necessary memory for the buffer. A maximum of 64K is
; allocated.
;**********************************************************************
CALL ALLOCATE_MEMORY ;AN000; Allocate the memory for the printer data
.IF < C > ;AN000; Was there an error?
JMP EXIT_WITH_ERROR ;AN000; If so, exit the subroutine
.ENDIF ;AN000;
;**********************************************************************
; See if there is enough memory to continue.
;**********************************************************************
.IF < SEGMENT_SIZE B MINIMUM_MEMORY> ;AN000; Is there enough memory?
MOV BX, ERR_NOT_ENOUGH_MEM ;AN000; No! Return error code.
JMP EXIT_WITH_ERROR ;AN000; Exit the subroutine
.ENDIF ;AN000;
;**********************************************************************
; Set the pointer for the file data buffer and save the size of this buffer.
;**********************************************************************
MOV BUFFER_START, NAMES_TABLE_SIZE ;AN000; Starting address of the file data buffer
MOV BX, SEGMENT_SIZE ;AN000; Total amount of memory available
SUB BX, NAMES_TABLE_SIZE ;AN000; Calculate the size of the file data buffer
MOV BUFFER_SIZE, BX ;AN000; Save this size.
MOV NAMES_OFF, 0 ;AN000; Offset of the printer names table
;**********************************************************************
; Open the printer definition file.
;**********************************************************************
MOV INT_24_ERROR, 0 ;AN000;
CALL POS_ZERO ;AN000; Turn the ASCII-N string into an ASCII-Z string
MOV DX, DI ;AN000; Get address of the ASCII-N string
ADD DX, 2 ;AN000; Address of the filename
MOV AX, 3D00H ;AN000; Open file for reading.
DOSCALL ;AN000;
.IF < C > ;AN000; Was there an error opening the file?
MOV BX, ERR_OPENING_FILE ;AN000; Yes! Return this error code
JMP EXIT_WITH_ERROR ;AN000;
.ENDIF ;AN000;
MOV FILE_HANDLE, AX ;AN000; Save the handle for the file
;**********************************************************************
; Initialize the variable which holds the file pointer at the beginning
; of the buffer.
;**********************************************************************
MOV WORD PTR FILE_PTR_AT_START, 0 ;AN000; Zero the low word
MOV WORD PTR FILE_PTR_AT_START+2, 0 ;AN000; Zero the high word
AND READ_FLAG, RESET_EOF ;AN000; Indicate we are not at EOF
;**********************************************************************
; Read data into the file buffer.
;**********************************************************************
MOV DI, BUFFER_START ;AN000; Start reading at this offset
SUB DI, NAMES_TABLE_SIZE ;AN000; Make into an offset in the buffer instead of the segment
CALL READ_FROM_HERE ;AN000; Read in the data.
.IF < C > ;AN000; Was there an error reading from the file?
MOV BX, ERR_READING_FILE ;AN000; Return this error code
JMP EXIT_WITH_ERROR ;AN000; Return from this subroutine
.ENDIF ;AN000;
;**********************************************************************
; Initialize the variables needed for the parsing.
;**********************************************************************
MOV CURRENT_PARSE_LOC, NAMES_TABLE_SIZE ;AN000; Start parsing from the beginning.
MOV CX_ORDINAL_VALUE, 0 ;AN000; The first parse, CX must be zero.
MOV N_PRN_NAMES, 0 ;AN000; There are not names in the table now
AND PARSE_FLAG, RESET_LINE_DONE ;AN000; The current line has NOT been parsed
OR PARSE_FLAG, FIRST_PARSE ;AN000; Indicate that this is the first parse
;**********************************************************************
; Setup the control blocks for the parser
;**********************************************************************
MOV PAR_EXTEN, OFFSET PARMSX ;AN000; Load the address of the parse extention block
;**********************************************************************
; Parse the data. If this is the first parse, then look for the number
; of printer definitions. If it is not, then look for the parameters
; P and S which preface the printer names.
;**********************************************************************
MOV VAL_NUM, RANGE_ONLY ;AN000; Parse for a range of values only
MOV CTL_FUNC_FL, NUMERIC_VALUE ;AN000; Indicate we are looking for numbers
MOV NUM_STRINGS, 2 ;AN000; The number of parameters to look for
;**********************************************************************
; See if there is a complete line in the remainder of the buffer. If there
; is not, then read more data into the buffer starting with the start of
; the current line.
;**********************************************************************
PARSE_NEXT_LINE: ;AN000;
CALL SEARCH_LINE ;AN000; Search for the first parameter on the line
.IF < C > ;AN000; Was there an error?
JMP EXIT_WITH_ERROR ;AN000; Yes! Exit the routine
.ENDIF ;AN000;
.IF < BIT PARSE_FLAG AND FIRST_PARSE > ;AN000; Looking for a value or a string?
.IF < AX NE 0 > ;AN000; Was there an error?
MOV BX, ERR_FINDING_VALUE ;AN000; Yes! Return with this error code
JMP EXIT_WITH_ERROR ;AN000;
.ENDIF ;AN000;
MOV AL, RESULT_FIELD ;AN000; Get the low order byte of the value
MOV NUM_PRINTER_DEFS, AL ;AN000; Store the number of definitions
AND PARSE_FLAG, RESET_FIRST_PARSE ;AN000; Indicate the first parse is finished
MOV VAL_NUM, RANGE_AND_STRING ;AN000; Specify strings and ranges
MOV CTL_FUNC_FL, SIMPLE_STRING ;AN000; Look for specific strings only.
.ENDIF ;AN000;
;**********************************************************************
; See if we found a printer name
;**********************************************************************
.IF < AX EQ 0 > ;AN000; Was an error found parsing the buffer
.IF < N_PRN_NAMES AE MAX_NUM_PRINTER_DEFS > ;AN000; Are there more the 255 printer defs?
MOV BX, ERR_TOO_MANY_DEFS ;AN000; If so, return this error.
JMP EXIT_WITH_ERROR ;AN000; Terminate the subroutine.
.ENDIF ;AN000;
; DX contains the address of the result block
CALL COPY_PRINTER_NAME ;AN000; Copy the name to the table
.IF < C > ;AN000; Was there an error?
MOV BX, ERR_FINDING_NAME ;AN000; Yes! Return this error code
JMP EXIT_WITH_ERROR ;AN000;
.ENDIF ;AN000;
.ENDIF ;AN000;
;**********************************************************************
; Start scanning the next line.
;**********************************************************************
MOV DI, START_NEXT_LINE ;AN000; Get the address of the next line to parse
MOV CURRENT_PARSE_LOC, DI ;AN000; Save it
.IF < CURRENT_PARSE_LOC EQ 0 > ;AN000; Is there more data?
JMP EXIT_WITHOUT_ERROR ;AN000; No! Exit the routine
.ENDIF ;AN000;
JMP PARSE_NEXT_LINE ;AN000; Start processing this line
;
EXIT_WITH_ERROR: ;AN000;
STC ;AN000; Set the carry flag, indicating error.
JMP EXIT_ROUTINE ;AN000;
EXIT_WITHOUT_ERROR: ;AN000;
MOV CX, N_PRN_NAMES ;AN000; The number of entries in the table
.IF < CL NE NUM_PRINTER_DEFS > ;AN000; Did the number of definitions agree with the expected number?
MOV BX, ERR_NUMBER_MATCH ;AN000; Return this error message
JMP EXIT_WITH_ERROR ;AN000; Return, setting the carry flag.
.ENDIF ;AN000;
CLC ;AN000; Clear the carry flag - No error.
EXIT_ROUTINE: ;AN000;
CALL DEALLOCATE_MEMORY
POP ES ;AN000;
CALL RESTORE_INT_24;AN000;
RET ;AN000;
;
GET_PRINTER_TITLES_ROUTINE ENDP ;AN000;
;********************************************************************************
;
;SEARCH_LINE: Search for the first parameter on a line.
;
;INPUT:
; None.
;
;OUTPUT:
; AX - Contains the return codes from the parser
; If CY = 1: There was an error - BX contains an error code
; if CY = 0: There were NO errors.
; All the registers are set from the parser return.
;
;OPERATION:
;
;********************************************************************************
SEARCH_LINE PROC NEAR ;AN000;
MOV DI, CURRENT_PARSE_LOC ;AN000; Get the current location in the buffer
CALL SCAN_FOR_EOLN ;AN000; Search for the end of the line
MOV START_NEXT_LINE, DI ;AN000; Save the start address of the next line
.IF < C > ;AN000; Was the END OF LINE found?
.IF <BIT READ_FLAG AND AT_EOF> ;AN000; Are we at the end of the file?
MOV START_NEXT_LINE, 0 ;AN000; Yes! Indicate that this is the last line
.ELSE ;AN000; We are not the the end of the file
MOV DI, CURRENT_PARSE_LOC ;AN000; The location to read from in the file
SUB DI, NAMES_TABLE_SIZE ;AN000; Make into an offset in the buffer instead of the segment
CALL READ_FROM_HERE ;AN000; Read in more data
.IF < C > ;AN000; Was there an error reading from the file?
MOV BX, ERR_READING_FILE ;AN000; Return this error code
JMP EXIT_SEARCH_ERROR ;AN000; Return from this subroutine
.ENDIF ;AN000;
MOV CURRENT_PARSE_LOC, NAMES_TABLE_SIZE ;AN000; Start back at the beginning of the buffer
MOV DI, CURRENT_PARSE_LOC ;AN000; Get the current parse location again.
CALL SCAN_FOR_EOLN ;AN000; Once again look for the end of the line
MOV START_NEXT_LINE, DI ;AN000; Save the start address of the nest line
.IF < C > ;AN000; Was it found?
MOV BX, ERR_LINE_TOO_LONG ;AN000; No! Indicate an error.
JMP EXIT_SEARCH_ERROR ;AN000; Return with this error
.ENDIF ;AN000;
.ENDIF ;AN000;
.ENDIF ;AN000;
;**********************************************************************
; Set up the input parameters for the parse subroutine
;**********************************************************************
MOV DI, OFFSET PARMS ;AN000; Offset into ES of the PARMS control block
MOV SI, CURRENT_PARSE_LOC ;AN000; Where to start parsing
MOV DX, 0 ;AN000;
MOV CX, CX_ORDINAL_VALUE ;AN000; The value returned by the parse last time.
PUSH DS ;AN000; Save the current data segment
PUSH ES ;AN000; Save the file data segment
MOV AX, DATA ;AN000; Get the current data segment
MOV ES, AX ;AN000; This is the parser control blocks.
MOV AX, SEG_LOC ;AN000; Where the data to parse is located
MOV DS, AX ;AN000;
CALL SYSPARSE ;AN000; Do the parsing
POP ES ;AN000; Restore the file data segment
POP DS ;AN000; Restore the data segment
CLC ;AN000; Indicate there were no errors
RET ;AN000;
EXIT_SEARCH_ERROR: ;AN000; Here if there were errors
STC ;AN000; Indicate so to the calling program
RET ;AN000;
SEARCH_LINE ENDP;AN000;
;********************************************************************************
; ALLOCATE_MEMORY: Allocate a maximum of 64K of memory.
;
; INPUT:
; None.
;
; OUTPUT:
; SEGMENT_SIZE = The size of the segment allocated.
; SEG_LOC = The location of the segment allocated.
; If CY = 1: There was an error - BX contains an error code
; If CY = 0: There was NO errors.
;
; Operation:
;
;********************************************************************************
ALLOCATE_MEMORY PROC NEAR;AN000;
AND ALLOC_FLAG,NOT ALLOCATED
MOV BX, 0FFFH ;AN000; Try to allocate this amount of memory
MOV SEGMENT_SIZE, BX ;AN000; Save the amount of memory asked for
MOV AH, 48H ;AN000; DOS Fn. for allocating memory
DOSCALL ;AN000; Allocate the memory
.IF < C > ;AN000; Was there an error?
MOV SEGMENT_SIZE, BX ;AN000; Save the size asked for in this request
MOV AH, 48H ;AN000; DOS Fn. for allocating memory
DOSCALL ;AN000; Allocate the memory
.ENDIF ;AN000;
.IF < C > ;AN000; Was there an error allocating the memory?
MOV BX, ERR_ALLOCATING_MEM ;AN000; Yes! Return an error code
STC ;AN000; Indicate that there was an error
.ELSE ;AN000; Otherwise...
MOV SEG_LOC, AX ;AN000; Save the location of the memory block allocated
MOV ES, AX ;AN000; Save in the extra segment
MOV CL, 4 ;AN000; Multiply the number of paragraphs by 16
SHL SEGMENT_SIZE, CL ;AN000; to get the number of bytes.
OR ALLOC_FLAG,ALLOCATED
CLC ;AN000; Indicate there was no error
.ENDIF ;AN000;
RET ;AN000;
ALLOCATE_MEMORY ENDP;AN000;
;********************************************************************************
; DEALLOCATE_MEMORY: deallocate memory.
;
; INPUT:
; SEG_LOC previously allocated segment
;
; OUTPUT:
; None.
;
;********************************************************************************
DEALLOCATE_MEMORY PROC NEAR
TEST ALLOC_FLAG,ALLOCATED
JZ DEM10
PUSH ES
MOV AX,SEG_LOC
MOV ES,AX
MOV AH,49H
INT 21H
POP ES
DEM10:
RET
DEALLOCATE_MEMORY ENDP
;*******************************************************************************
;
; Routine: SCAN_FOR_EOLN - Scan the given string, for CR and LF.
;
; Input:
; DI - Address of the string to scan for the eoln.
;
; Output:
; If CY = 0: The end of the line was found.
; DI - Contains the address of the start of the next line in the buffer.
; - If DI = 0, the data ends just after either the CR, LF or the
; CR and LF. Therefore, more data must be read before the next line
; can be parsed.
;
; If CY = 1: The end of the line was not found.
;
;*******************************************************************************
SCAN_FOR_EOLN PROC NEAR;AN000;
MOV CX, BUFFER_START ;AN000; The offset in the segment of the buffer
ADD CX, AMOUNT_OF_DATA ;AN000; Get the offset of the end of the data
SUB CX, DI ;AN000; Subtract the file data pointer
; CX - Contains the amount of data after pointer
MOV AL, 0 ;AN000; Flag to indicate CR-LF has not been found yet
.WHILE < CX A 0 > ;AN000; Search until the end of the data
.IF < <BYTE PTR ES:[DI]> EQ E_FILE_TERM >;AN000;
.IF < ZERO AL > ;AN000;
MOV END_CUR_LINE, DI ;AN000; Save this location in the string
DEC END_CUR_LINE ;AN000; Point to the real end of the line
.ENDIF ;AN000;
STC ;AN000;
MOV DI, 0 ;AN000;
JMP EXIT_SCAN ;AN000;
.ENDIF ;AN000;
.IF < <BYTE PTR ES:[DI]> EQ E_LF > OR ;AN000; Is this character a CR or a LF?
.IF < <BYTE PTR ES:[DI]> EQ E_CR > ;AN000;
.IF < ZERO AL > ;AN000; Has a CR or a LF already been found?
MOV END_CUR_LINE, DI ;AN000; Save this location in the string
DEC END_CUR_LINE ;AN000; Point to the real end of the line
.ENDIF ;AN000;
INC AL ;AN000; Indicate that a CR or a LF has been found
.ELSEIF < NONZERO AL > ;AN000; If we have passed the CR-LF,
CLC ;AN000; Indicate we have found EOLN
JMP EXIT_SCAN ;AN000; Leave the subroutine
.ENDIF ;AN000;
DEC CX ;AN000; One less character to the end
INC DI ;AN000; Point to the next character
.ENDWHILE ;AN000;
.IF < AL AE 2 > ;AN000; Does the data run out right after the CR-LF?
MOV DI, 0 ;AN000; Return 0 indicating so.
.ENDIF ;AN000;
STC ;AN000; Indicate that the whole line is not there
EXIT_SCAN: ;AN000;
RET ;AN000;
SCAN_FOR_EOLN ENDP;AN000;
;*******************************************************************************
;
; Routine: COPY_PRINTER_NAME - Copy the name of the printer from the file
; into the buffer holding all the names.
;
; Input:
; SI - Contains the address of the start of the printer name.
; DX - Contains the address of the parse result block
;
; Output:
; CY = 1: An error has occured. The name of the printer has not been found.
; CY = 0: No error.
;
; Operation: The name from the file buffer is copied to the printer name
; table. Starting from the address passed in DI, the file buffer is
; scanned until a valid character is found. Starting from this point
; up to forty characters are transferred to the name table. If no
; name is found, the carry flag is set, and nothing is recorded in the
; name table.
; After the name is copied, the remainder of the field in the table
; is cleared.
;
;*******************************************************************************
COPY_PRINTER_NAME PROC NEAR;AN000;
PUSH DS ;AN000;
PUSH ES ;AN000;
PUSH DX ;AN000; Save the address of the result block
;**********************************************************************
; Calculate the offset into the file data table for this entry
;**********************************************************************
MOV AX, N_PRN_NAMES ;AN000; The next free index into the names table
MOV BX, SIZE_NAMES ;AN000; Get the number of bytes per entry
MUL BX ;AN000; Multiply by the index into the table
MOV DI, AX ;AN000; Move the offset into an index register
;**********************************************************************
; Copy the type of printer first
;**********************************************************************
POP BX ;AN000; Get the result block address
MOV AL, DS:[BX+1] ;AN000; Get the matched item tag
.IF < AL EQ 1 > ;AN000; Was the parameter a P?
MOV AL, 'P' ;AN000; Yes!
.ELSE ;AN000;
MOV AL, 'S' ;AN000; No! It was an S
.ENDIF ;AN000;
MOV ES:[DI+40], AL ;AN000; Store in the table
;**********************************************************************
; Skip the spaces between the printer type indicator and the printer name
;**********************************************************************
MOV AL, 32 ;AN000; Character to skip - space
XCHG SI, DI ;AN000; Point DI to the line being scanned
MOV CX, END_CUR_LINE ;AN000; Get address of the last char in line
SUB CX, DI ;AN000; Subtract start
INC CX ;AN000; Get the length of the line
CLD ;AN000; Scan forward
REPZ SCASB ;AN000; Repeat search until character found
JZ NAME_NOT_FOUND ;AN000; If all spaces, then it is an error
INC CX ;AN000; Increment character count
DEC DI ;AN000; Decrement pointer to character
;***********************************************************************
; Move the printer name to the names list
;***********************************************************************
XCHG SI, DI ;AN000; Exchange the pointers again
MOV CX, END_CUR_LINE ;AN000; Get the address of the last char
SUB CX, SI ;AN000; Subtract start
INC CX ;AN000; Get the length of the line
.IF < CX A E_MAX_PRN_NAME_LEN > ;AN000; Is the length of the line too long?
MOV CX, E_MAX_PRN_NAME_LEN ;AN000; Yes! Make the line length the maximum size
.ENDIF ;AN000;
MOV DX, CX ;AN000; Save the line length for later use
.WHILE < NONZERO CX > ;AN000; Do while there are more characters in the string
MOV AL, BYTE PTR ES:[SI] ;AN000; Get a character from the file data
.IF < AL NE 32 > ;AN000; Is this character a space?
MOV BX, DX ;AN000; Get the line length
SUB BX, CX ;AN000; Get the length of the line copied so far
INC BX ;AN000;
.IF < MAX_NAME B BX > ;AN000; Is this name longer than the longest so far?
MOV MAX_NAME, BX ;AN000; Yes! This is the new maximum
.ENDIF ;AN000;
.ENDIF ;AN000;
MOV BYTE PTR ES:[DI], AL ;AN000; Put the character in the names table
INC SI ;AN000; Increment string pointers
INC DI ;AN000;
DEC CX ;AN000; Decrement the number of characters left
.ENDWHILE ;AN000;
;***********************************************************************
; Fill in the rest of the name area with spaces
;***********************************************************************
MOV CX, E_MAX_PRN_NAME_LEN ;AN000; The maximum line length
; DX contains the line length from last section
SUB CX, DX ;AN000; Calculate the space left in the line
MOV AL, 32 ;AN000; Character to store
REP STOSB ;AN000; Store the blank characters
;***********************************************************************
; Store the file pointer to this printer name in the name list
;***********************************************************************
INC DI ;AN000; Point DI passed the printer type indicator
MOV SI, CURRENT_PARSE_LOC ;AN000; Get the start of the current line
SUB SI, NAMES_TABLE_SIZE ;AN000; Subtract offset of the start of the buffer
MOV CX, WORD PTR FILE_PTR_AT_START ;AN000; Get the low order word of the pointer
MOV DX, WORD PTR FILE_PTR_AT_START[2] ;AN000; Get the high order word
ADD CX, SI ;AN000; Add the offset of the start of this line
ADC DX, 0 ;AN000; Add the high word
MOV WORD PTR ES:[DI], CX ;AN000; Store the low order word in the list
MOV WORD PTR ES:[DI+2], DX ;AN000; Store the high order word
INC N_PRN_NAMES ;AN000; Point to the next free area in the list
CLC ;AN000;
JMP EXIT_COPY ;AN000;
NAME_NOT_FOUND: ;AN000;
STC ;AN000;
EXIT_COPY: ;AN000;
POP ES ;AN000;
POP DS ;AN000;
RET ;AN000;
COPY_PRINTER_NAME ENDP ;AN000;
;*******************************************************************************
; Routine: READ_FROM_HERE - Read from the file into the buffer starting from
; the file position pointed to by CURRENT_PARSE_LOC.
;
; Input:
; DI - Contains the current parsing location in the buffer.
;
; Output:
; FILE_PTR_AT_START - Updated for the new data read.
;
; Operation:
;
;*******************************************************************************
READ_FROM_HERE PROC NEAR;AN000;
;
;**********************************************************************
; Update the R/W pointer in the file.
;**********************************************************************
MOV DX, WORD PTR FILE_PTR_AT_START ;AN000; Get the low order word of the pointer
MOV CX, WORD PTR FILE_PTR_AT_START[2] ;AN000; Get the high order word of the pointer
ADD DX, DI ;AN000; Add the offset of where to start reading
ADC CX, 0 ;AN000; Take care of the carry condition
MOV WORD PTR FILE_PTR_AT_START, DX ;AN000; Store the new starting position
MOV WORD PTR FILE_PTR_AT_START[2], CX ;AN000; Store the high word of pointer
MOV INT_24_ERROR, 0 ;AN000;
MOV AX, 4200H ;AN000; DOS Function for moving the file pointer
MOV BX, FILE_HANDLE ;AN000; Load the file handle
DOSCALL ;AN000; Move the file pointer
.IF < C > ;AN000; Was an error encountered?
JMP RETURN_WITH_ERROR ;AN000; Yes! Exit the subroutine.
.ENDIF ;AN000;
;**********************************************************************
; Read from the file into the data buffer
;**********************************************************************
MOV CX, BUFFER_SIZE ;AN000; Number of bytes to read. As many as will fit.
MOV BX, FILE_HANDLE ;AN000; Load the DOS file handle for this file
MOV AH, 03FH ;AN000; The DOS function to perform
MOV DX, BUFFER_START ;AN000; The offset of the file data buffer
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
PUSH DS ;AN000; Save the current data segment
PUSH ES ;AN000; Push the file data buffer
POP DS ;AN000; DS now points to the file data buffer
DOSCALL ;AN000; Read from the file.
POP DS ;AN000; Restore the original data segment
;**********************************************************************
; See if the buffer was filled.
;**********************************************************************
MOV AMOUNT_OF_DATA, AX ;AN000; Save the amount of data that was read.
.IF < AX B BUFFER_SIZE > ;AN000; Were less bytes read then we asked for?
OR READ_FLAG, AT_EOF ;AN000; Yes! Indicate that we are at EOF
; MOV DI, AX ; Move number of characters into an index pointer
; MOV BYTE PTR ES:[DI+NAMES_TABLE_SIZE], 00 ; Place a terminator at the end
.ENDIF ;AN000;
CLC ;AN000;
RET ;AN000;
RETURN_WITH_ERROR: ;AN000;
STC ;AN000;
RET ;AN000;
READ_FROM_HERE ENDP ;AN000;
;********************************************************************************
; Routines for extracting all the information supplied in the profile for a
; specific printer. Given the printer number, the location of its definition
; is looked up in the names table. The file is them parsed for the information.
;********************************************************************************
;******************************************************************************
; GET_PRINTER_INFO_ROUTINE - Get all the information contained in the printer
; profile file for the specified printer.
;
; INPUT:
; AX - The number of the printer to return the information on. The number
; is the index into the names table for this printer.
;
; OUTPUT:
; If CY = 0, there were no errors.
; The following variable are updated with the information found in
; the file:
; I_PRINTER
; N_PRINTER_TYPE
; S_MODE_PARM
; S_CP_DRIVER
; S_CP_PREPARE
; S_GRAPH_PARM
;
; If CY = 1, There were errors encountered.
; BX = An error code indicating the type of error that occured.
;
; = 3 There was an error reading the file
; = 7 There was a error accessing the file
; = 11 A printer definition has either a CDP or a CPP
; Prefix, but BOTH were not present.
; = 12 There was an error in the printer definition.
; - A line was found with an invalid prefix
;
; If the error was a result of a DOS function, then
; on return, AX will contain the DOS error code.
;
; Operation:
;
; Note:
; The first printer name has an index of 1.
;
;******************************************************************************
GET_PRINTER_INFO_ROUTINE PROC FAR;AN000;
CALL HOOK_INT_24 ;AN000;
PUSH ES ;AN000; Save the extra segment register
;**********************************************************************
; Calculate the address of the specifed printer
;**********************************************************************
MOV I_PRINTER, AX ;AN000; Save the printer index
DEC AX ;AN000; Make the first index a 0
MOV BX, SIZE_NAMES ;AN000; Number of bytes in each table entry
MUL BX ;AN000; Address is returned in AX
MOV DI, AX ;AN000; Move the address to an index register
;**********************************************************************
; Get the file location for this printer name
;**********************************************************************
MOV AX, SEG_LOC ;AN000; Get the segment where the data is
MOV ES, AX ;AN000; Save in a segment register
MOV CX, WORD PTR ES:[DI+41] ;AN000; Get the low order word of the file location
MOV DX, WORD PTR ES:[DI+43] ;AN000; Get the high order word of the file location
;**********************************************************************
; Determine if the information is already in the buffer or do we have
; to read more information from the printer profile.
;**********************************************************************
.IF < DX B <WORD PTR FILE_PTR_AT_START+2>> ;AN000; Compare the high order words
JMP READ_MORE_INFORMATION ;AN000; Info in buffer is passed where we want.
.ELSE ;AN000;
.IF < DX EQ < WORD PTR FILE_PTR_AT_START+2>> AND ;AN000; High words equal so
.IF < CX B <WORD PTR FILE_PTR_AT_START>> ;AN000; compare the low order words
JMP READ_MORE_INFORMATION ;AN000; Info in buffer is passed where we want.
.ENDIF ;AN000;
.ENDIF ;AN000;
MOV BX, WORD PTR FILE_PTR_AT_START+2 ;AN000; File location at beginning of buffer
MOV SI, WORD PTR FILE_PTR_AT_START ;AN000; Low order word
ADD SI, AMOUNT_OF_DATA ;AN000; Get the file pointer of the end of the buffer
ADC BX, 0 ;AN000; Add in the high word
.IF < DX A BX > ;AN000; If data we want is further in the file,
JMP READ_MORE_INFORMATION ;AN000; Read in more data
.ELSE ;AN000;
.IF < DX EQ BX > AND ;AN000; If the high words are equal do the
.IF < CX A SI > ;AN000; comparison on the low order words
JMP READ_MORE_INFORMATION ;AN000; Still not there, so read more info
.ENDIF ;AN000;
.ENDIF ;AN000;
MOV AX, I_PRINTER ;AN000; Get the index of this printer name
.IF < AL EQ NUM_PRINTER_DEFS > ;AN000; Is this the last one in the list?
.IF < BIT READ_FLAG AND AT_EOF > ;AN000; If it is, and all the data has been read, process it
JMP PARSE_HERE ;AN000;
.ELSE ;AN000;
JMP READ_MORE_INFORMATION ;AN000; Not EOF, so read in more data just for safety
.ENDIF ;AN000;
.ENDIF ;AN000;
MOV CX, WORD PTR ES:[DI+SIZE_NAMES+41] ;AN000; Get the pointer to the NEXT printer name
MOV DX, WORD PTR ES:[DI+SIZE_NAMES+43] ;AN000; Get the high order word
.IF < DX A BX > ;AN000; See if the next printer name is in the buffer
JMP READ_MORE_INFORMATION ;AN000; If not, get more information
.ELSE ;AN000;
.IF < DX EQ BX > AND ;AN000; If the high order words are equal,
.IF < CX A SI > ;AN000; Compare the low order. Is the name there?
JMP READ_MORE_INFORMATION ;AN000; If not, read more.
.ENDIF ;AN000;
.ENDIF ;AN000;
JMP PARSE_HERE ;AN000; The necessary info is there, so parse it.
;**********************************************************************
; The specified printer information is not currently in the buffer. It
; is necessary to read it from the printer profile file.
;**********************************************************************
READ_MORE_INFORMATION: ;AN000;
MOV CX, WORD PTR ES:[DI+43] ;AN000; Get the file pointer of this printer name
MOV DX, WORD PTR ES:[DI+41] ;AN000; Get the low order word of pointer
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
MOV AX, 4200H ;AN000; DOS Fn. for positioning file pointer
MOV BX, FILE_HANDLE ;AN000; Get the handle of the file
DOSCALL ;AN000; Position the pointer
.IF < C > ;AN000; If CY = 1, there was an error
MOV BX, ERR_ACCESSING_FILE ;AN000; Return this error code
JMP ERROR_EXIT ;AN000; Jump to exit routine
.ENDIF ;AN000;
MOV WORD PTR FILE_PTR_AT_START, AX ;AN000; Set the new pointer at the beginning of the buffer
MOV WORD PTR FILE_PTR_AT_START+2, DX ;AN000; Set the high order word
MOV AH, 3FH ;AN000; DOS Fn. for reading from a file
MOV DX, BUFFER_START ;AN000; Offset of the start of the data buffer
MOV BX, FILE_HANDLE ;AN000; Get the file handle
MOV CX, BUFFER_SIZE ;AN000; Read as many bytes as the buffer will hold
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
PUSH DS ;AN000; Save the current data segment
PUSH ES ;AN000; Push the segment of the data buffer
POP DS ;AN000; Load DS with the segment where to store the data
DOSCALL ;AN000; Read in the data
POP DS ;AN000; Restore the data segment
.IF < C > ;AN000;
MOV BX, ERR_READING_FILE;AN000;
JMP ERROR_EXIT;AN000;
.ENDIF ;AN000;
.IF < AX NE BUFFER_SIZE > ;AN000; Were less bytes read then asked for?
OR READ_FLAG, AT_EOF ;AN000; If so, then we are at the end of file
.ELSE ;AN000; Otherwise...
AND READ_FLAG, RESET_EOF ;AN000; We are not at end of file
.ENDIF ;AN000;
MOV AMOUNT_OF_DATA, AX ;AN000; Save the amount of data actually read
;**********************************************************************
; The printer data is in the data buffer. Begin to parse the data.
;**********************************************************************
PARSE_HERE: ;AN000;
MOV CDP_FOUND, FALSE ;AN000;
MOV CPP_FOUND, FALSE ;AN000;
PUSH DI ;AN000; Save the pointer into the names table
;**********************************************************************
; Load the printer profile fields with defaults.
;**********************************************************************
COPY_STRING S_MODE_PARM, 40, BLANK_STRING ;AC000;JW
COPY_STRING S_CP_DRIVER, 22, BLANK_STRING ;AN000;
COPY_STRING S_CP_PREPARE, 12, BLANK_STRING ;AN000;
COPY_STRING S_GRAPH_PARM, 20, BLANK_STRING ;AN000;
POP DI ;AN000; Restore the pointer into the names table
;**********************************************************************
; Get the type of printer.
;**********************************************************************
MOV AL, ES:[DI+40] ;AN000; Get the printer type - Parallel or Serial from the table
MOV N_PRINTER_TYPE, AL ;AN000; Save in the appropriate variable
;**********************************************************************
; Get the offset of the start of this printer definition
;**********************************************************************
MOV CX, ES:[DI+41] ;AN000; Get the low order word of the file pointer
MOV DX, ES:[DI+43] ;AN000; Get the high order word
SUB DX, WORD PTR FILE_PTR_AT_START[2] ;AN000; Subtract the high order words
SBB CX, WORD PTR FILE_PTR_AT_START ;AN000; Subtract the low order words
ADD CX, BUFFER_START ;AN000; Get the offset of the start of the definition
MOV CURRENT_PARSE_LOC, CX ;AN000; Save as the scan position
OR PARSE_FLAG, FIRST_NAME ;AN000;
PARSE_NEXT_PARM: ;AN000;
MOV DI, CURRENT_PARSE_LOC ;AN000; Get the current scan position
CALL SCAN_FOR_EOLN ;AN000; Search for the end of this line
MOV START_NEXT_LINE, DI ;AN000; Save the position of the start of the next line
MOV SI, CURRENT_PARSE_LOC ;AN000; The position in the buffer to scan
MOV NUM_STRINGS, 6 ;AN000; Number of parameters to parse for
MOV DI, OFFSET PARMS ;AN000; Offset of the parameter blocks
MOV DX, 0 ;AN000; The parser wants DX = 0.
MOV CX, 0 ;AN000; Tell the parser this is the first scan of this line
PUSH DS ;AN000; Save the current data segment
PUSH ES ;AN000; Save the file data segment
MOV AX, DATA ;AN000; Get the current data segment
MOV ES, AX ;AN000; This is the parser control blocks.
MOV AX, SEG_LOC ;AN000; Where the data to parse is located
MOV DS, AX ;AN000;
CALL SYSPARSE ;AN000; Do the parsing
POP ES ;AN000; Restore the file data segment
POP DS ;AN000; Restore the data segment
.IF < AX EQ 0FFFFH > ;AN000; Was the end of the line found?
JMP UPDATE_PARSE_PTR ;AN000; If so, start the next one
.ELSEIF < NONZERO AX > ;AN000; Was an error encountered parsing the line?
MOV BX, ERR_PRN_DEFN ;AN000;
JMP ERROR_EXIT ;AN000; If so, exit the subroutine
.ENDIF ;AN000;
MOV AL, MATCHED_TAG ;AN000; Get which string was matched
.IF < AL EQ 1 > OR ;AN000; Was this a printer name and type?
.IF < AL EQ 2 > ;AN000;
.IF < BIT PARSE_FLAG AND FIRST_NAME > ;AN000; Is this the first name encountered?
AND PARSE_FLAG, RESET_FIRST_NAME ;AN000; Indicate that the a name has been found
.ELSE ;AN000; Otherwise...
JMP PARSING_DONE ;AN000; This is the second name. We are finished.
.ENDIF ;AN000;
.ELSEIF < AL EQ 3 > ;AN000; AL = 3 ==> Mode parameters
CALL HANDLE_MODE ;AN000; Process
.ELSEIF < AL EQ 4 > ;AN000; AL = 4 ==> Code page driver parameters
MOV CDP_FOUND, TRUE ;AN000;
CALL HANDLE_CODE_DRIVER ;AN000; Process
.ELSEIF < AL EQ 5 > ;AN000; AL = 5 ==> Code page preparation parameters
MOV CPP_FOUND, TRUE ;AN000;
CALL HANDLE_CODE_PREPARE ;AN000; Process
.ELSEIF < AL EQ 6 > ;AN000; AL = 6 ==> Graphics parameters
CALL HANDLE_GRAPHICS ;AN000; Process
.ENDIF ;AN000;
;**********************************************************************
; The current line has been parsed. Point to the next line.
;**********************************************************************
UPDATE_PARSE_PTR: ;AN000;
MOV AX, START_NEXT_LINE ;AN000; Get the address of the start of the next line
MOV CURRENT_PARSE_LOC, AX ;AN000; Save this as the start of the current line
.IF < CURRENT_PARSE_LOC EQ 0 > ;AN000; Is there any more data?
JMP PARSING_DONE ;AN000; No. Exit the routine
.ENDIF ;AN000;
JMP PARSE_NEXT_PARM ;AN000; Start the parsing again
;**********************************************************************
; The subroutine is finished.
;**********************************************************************
PARSING_DONE: ;AN000;
MOV AL, CDP_FOUND ;AN000;
XOR AL, CPP_FOUND ;AN000;
.IF < NZ > ;AN000;
MOV BX, ERR_CDP_CPP ;AN000;
JMP ERROR_EXIT ;AN000;
.ENDIF ;AN000;
CLC ;AN000; Clear the carry - No errors
JMP EXIT_INFO ;AN000; Exit the subroutine
ERROR_EXIT: ;AN000;
STC ;AN000; Set the carry - There were errors
EXIT_INFO: ;AN000;
POP ES ;AN000; Restore the extra segment
CALL RESTORE_INT_24;AN000;
RET ;AN000; return
GET_PRINTER_INFO_ROUTINE ENDP;AN000;
;********************************************************************************
; HANDLE_MODE - Subroutine to process the mode parameter line in the printer
; profile.
;
; INPUT:
; SI - Points to the beginning of the line to process
;
; OUTPUT:
; S_MODE_PARM - Filled with the information from the line. The line will be
; in a format for use as the parameters for the MODE command.
;
;********************************************************************************
HANDLE_MODE PROC NEAR;AN000;
;AD000;JW PUSH SI
;AD000;JW COPY_STRING S_MODE_PARM, 13, BLANK_MODE
;AD000;JW POP SI
;AD000;JW
;AD000;JW NEXT_MODE_SCAN: ; Scan for the next keyword.
;AD000;JW MOV DI, OFFSET MODE_PARMS ; Offset of the control blocks for parsing the mode parameters
;AD000;JW MOV CX, 0 ; Always tell the parser this is the first parse
;AD000;JW MOV DX, 0 ; The parse wants DX = 0
;AD000;JW PUSH ES ; Save the segment registers
;AD000;JW PUSH DS
;AD000;JW MOV AX, DATA ; Get the location of the data segment
;AD000;JW MOV ES, AX ; Load in the extra segment register - The segment of the control blocks
;AD000;JW MOV AX, SEG_LOC ; Get the location of the printer data
;AD000;JW MOV DS, AX ; Load into the data segment - The segment of the data to parse
;AD000;JW CALL SYSPARSE ; Parse the line.
;AD000;JW POP DS ; Restore the segment registers
;AD000;JW POP ES
;AD000;JW
;AD000;JW ; PUSHH <AX,BX,CX,DX,SI,DI>
;AD000;JW ; MOV W_VALUE, AX
;AD000;JW ; WORD_TO_CHAR W_VALUE, STRING_N
;AD000;JW ; PRINTN STRING_N
;AD000;JW ; CR_LF
;AD000;JW ; POPP <DI,SI,DX,CX,BX,AX>
;AD000;JW
;AD000;JW .IF < NONZERO AX > ; If errors or the end of the line, end the routine
;AD000;JW JMP EXIT_MODE_SCAN
;AD000;JW .ENDIF
;AD000;JW MOV BX, DX ; Move result pointer into an index register
;AD000;JW .IF <<WORD PTR [BX+2]> EQ <OFFSET SYN_BAUD>> ; Was this the BAUD keyword?
;AD000;JW MOV AX, 5 ; Maximum number of character to copy
;AD000;JW MOV DI, OFFSET S_MODE_PARM+2 ; Where to put the baud parameters
;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_PARITY>> ; Was this the PARITY keyword?
;AD000;JW MOV AX, 1 ; Maximum number of character to copy
;AD000;JW MOV DI, OFFSET S_MODE_PARM+8 ; Where to put the parity parameters
;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_DATA>> ; Was this the DATA keyword?
;AD000;JW MOV AX, 1 ; Maximum number of character to copy
;AD000;JW MOV DI, OFFSET S_MODE_PARM+10 ; Where to put the data parameters
;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_STOP>> ; Was this the STOP keyword?
;AD000;JW MOV AX, 1 ; Maximum number of character to copy
;AD000;JW MOV DI, OFFSET S_MODE_PARM+12 ; Where to put the stop parameters
;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_RETRY>> ; Was this the RETRY keyword?
;AD000;JW MOV AX, 1 ; Maximum number of character to copy
;AD000;JW MOV DI, OFFSET S_MODE_PARM+14 ; Where to put the retry parameters
;AD000;JW .ENDIF
;AD000;JW CALL COPY_RESULT ; Copy the string
;AD000;JW JMP NEXT_MODE_SCAN ; Scan for the next keyword
;AD000;JW EXIT_MODE_SCAN:
;AD000;JW CALL REMOVE_BLANKS ; Remove the blanks from the mode line
;AD000;JW
MOV DI, OFFSET S_MODE_PARM ;AN000; Offset of the variable to load JW
MOV CX, 40 ;AN000; Maximum width of the field JW
CALL COPY_LINE ;AN000; Copy the information from the file data JW
RET ;AN000; Return JW
HANDLE_MODE ENDP;AN000;
;AD000;JW ;********************************************************************************
;AD000;JW ; REMOVE_BLANKS: Remove the blanks from the S_MODE_PARM string. Any trailing
;AD000;JW ; commas are also removed.
;AD000;JW ;
;AD000;JW ; INPUT:
;AD000;JW ; None.
;AD000;JW ;
;AD000;JW ; OUTPUT:
;AD000;JW ; None.
;AD000;JW ;
;AD000;JW ; OPERATION:
;AD000;JW ;
;AD000;JW ;
;AD000;JW ;********************************************************************************
;AD000;JW REMOVE_BLANKS PROC NEAR
;AD000;JW
;AD000;JW MOV CX, WORD PTR S_MODE_PARM
;AD000;JW LEA SI, S_MODE_PARM
;AD000;JW INC SI
;AD000;JW ADD SI, CX
;AD000;JW MOV BX, CX
;AD000;JW .WHILE < CX AE 0 >
;AD000;JW .IF < <BYTE PTR [SI]> EQ <' '> > OR
;AD000;JW .IF < <BYTE PTR [SI]> EQ <','> >
;AD000;JW DEC BX
;AD000;JW .ELSE
;AD000;JW .LEAVE
;AD000;JW .ENDIF
;AD000;JW DEC SI
;AD000;JW DEC CX
;AD000;JW .ENDWHILE
;AD000;JW MOV WORD PTR S_MODE_PARM, BX
;AD000;JW
;AD000;JW MOV CX, BX
;AD000;JW LEA SI, S_MODE_PARM
;AD000;JW ADD SI, 2
;AD000;JW MOV DI, SI
;AD000;JW .WHILE < CX A 0 >
;AD000;JW .IF < <BYTE PTR [SI]> NE <' '>>
;AD000;JW .IF < SI NE DI >
;AD000;JW MOV AL, [SI]
;AD000;JW MOV [DI], AL
;AD000;JW .ENDIF
;AD000;JW INC DI
;AD000;JW .ELSE
;AD000;JW DEC BX
;AD000;JW .ENDIF
;AD000;JW INC SI
;AD000;JW DEC CX
;AD000;JW .ENDWHILE
;AD000;JW MOV WORD PTR S_MODE_PARM, BX
;AD000;JW RET
;AD000;JW
;AD000;JW REMOVE_BLANKS ENDP
;********************************************************************************
; HANDLE_CODE_DRIVER - Subroutine to process the code page driver parameter
; line in the printer profile.
;
; INPUT:
; SI - Points to the beginning of the line to process
;
; OUTPUT:
; S_CP_DRIVER - Filled with the information from the line.
;
; OPERATION: The line from the file is copied to the S_CP_DRIVER variable.
; This variable is assumed to be a maximum of 22 characters wide.
;
;********************************************************************************
HANDLE_CODE_DRIVER PROC NEAR;AN000;
MOV DI, OFFSET S_CP_DRIVER ;AN000; Offset of the variable to load
MOV CX, 22 ;AN000; Maximum width of the field
CALL COPY_LINE ;AN000; Copy the information from the file data
RET ;AN000;
HANDLE_CODE_DRIVER ENDP;AN000;
;********************************************************************************
; HANDLE_CODE_PREPARE - Subroutine to process the code prepare parameter line
; in the printer profile.
;
; INPUT:
; SI - Points to the beginning of the line to process
;
; OUTPUT:
; S_CP_PREPARE - Filled with the information from the line.
;
; OPERATION: The line from the file is copied to the variable S_CP_PREPARE.
; The variable is assumed to be a maximum of 12 characters long.
;
;********************************************************************************
HANDLE_CODE_PREPARE PROC NEAR;AN000;
MOV DI, OFFSET S_CP_PREPARE ;AN000; Offset of the variable to load
MOV CX, 12 ;AN000; Maximum length of the variable
CALL COPY_LINE ;AN000; Copy the information from the file data
RET ;AN000;
HANDLE_CODE_PREPARE ENDP;AN000;
;********************************************************************************
; HANDLE_GRAPHICS - Subroutine to process the graphics parameter line in the
; printer profile.
;
; INPUT:
; SI - Points to the beginning of the line to process
;
; OUTPUT:
; S_GRAPH_PARM - Filled with the information from the line.
;
; OPERATION: The line from the file is copied to the S_GRAPH_PARM variable.
; The variable is assumed to be a maximum of 20 characters long.
;
;********************************************************************************
HANDLE_GRAPHICS PROC NEAR;AN000;
MOV DI, OFFSET S_GRAPH_PARM ;AN000; Offset of the variable to load
MOV CX, 20 ;AN000; Maximum width of the variable
CALL COPY_LINE ;AN000; Load the variable with the data from the file
RET ;AN000;
HANDLE_GRAPHICS ENDP;AN000;
;********************************************************************************
; COPY_RESULT: Copy the string pointed to in the result block to the specified
; destination.
;
; INPUT:
; AX - The maximum length of the string to copy.
; DX - The offset in DS of the result block.
; DI - The offset of where the string is to be stored
;
;
; OUTPUT:
; CX - The length of the string copied.
;
; Operation: The string is copied from the result block to the area pointed to
; by DS:DI. The string is copied until a null character is encountered.
;
;********************************************************************************
COPY_RESULT PROC NEAR;AN000;
PUSH ES ;AN000;
PUSH SI ;AN000;
MOV BX, DX ;AN000; Put address into an index register
LES SI, [BX+4] ;AN000; Get the address of the string to copy
MOV CX, 0 ;AN000; Zero the string length indicator
.WHILE < CX B AX > ;AN000; Copy up to the number of character in AX
MOV DL, BYTE PTR ES:[SI] ;AN000; Get the first byte
.LEAVE < ZERO DL > ;AN000; Terminate loop if this is a null char
MOV BYTE PTR [DI], DL ;AN000; Save character in the destination string
INC SI ;AN000; Increment source pointer
INC DI ;AN000; Increment destination pointer
INC CX ;AN000; Increment number of characters moved
.ENDWHILE ;AN000;
POP SI ;AN000;
POP ES ;AN000;
RET ;AN000;
COPY_RESULT ENDP;AN000;
;********************************************************************************
; COPY_LINE - Copy a line from the printer profile data to a specified area.
;
; INPUT:
; DI - Points to the location the data is to be copied to.
; CX - Contains the maximum number of bytes copied.
;
; OUTPUT:
; None.
;
; OPERATION: The current line being parsed is copied to the specified area.
; The length of the line is calculated with the use of the variable
; CUR_END_LINE. If the lenght of the line is longer then the number passed
; in CX, then only a portion of the line will be copied.
;
;********************************************************************************
COPY_LINE PROC NEAR;AN000;
PUSH SI ;AN000; Save the index regiter used by the parser
PUSH DI ;AN000; Save the pointer to the variable to load
ADD DI, 2 ;AN000; Push pointer passed the lenght word
MOV AX, END_CUR_LINE ;AN000; Get the pointer to the end of this line
SUB AX, SI ;AN000; Get the distance to the end
INC AX ;AN000; Add to get the length of the line
.IF < AX B CX > ;AN000; If length is greater then the maximum allowed,
MOV CX, AX ;AN000; use the shorter length
.ENDIF ;AN000;
PUSH CX ;AN000; Save the length used.
PUSH ES ;AN000; Swap the values in the segment registers
PUSH DS ;AN000;
POP ES ;AN000;
POP DS ;AN000;
CLD ;AN000; Move in the forward direction
REP MOVSB ;AN000; Move the data
POP CX ;AN000; Restore the line length
POP DI ;AN000; Restore the pointer to the variable
MOV WORD PTR ES:[DI], CX ;AN000; Save the length of the string
POP SI ;AN000; Restore the parser pointer
PUSH DS ;AN000; Swap the segment registers again
PUSH ES ;AN000;
POP DS ;AN000;
POP ES ;AN000;
RET ;AN000;
COPY_LINE ENDP;AN000;
;********************************************************************************
; Routine to deallocate the memory used for the storage of the printer profile
; data and the table of printer names. These routines also close the profile
; file.
;********************************************************************************
;********************************************************************************
; RELEASE_PRINTER_INFO_ROUTINE - Close the printer profile file and free the
; allocated memory.
;
; INPUT:
; None.
;
; OUTPUT:
; If CY = 0, There were no error encountered.
; If CY = 1, There was an error.
; AX = The DOS error code for the deallocate memory function
;
; OPERATION: Closes the printer file and deallocated the memory.
;
;********************************************************************************
RELEASE_PRINTER_INFO_ROUTINE PROC FAR;AN000;
CALL HOOK_INT_24 ;AN000;
PUSH ES ;AN000;
;**********************************************************************
; Close the printer definition file
;**********************************************************************
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
MOV BX, FILE_HANDLE ;AN000; File handle of the profile file
MOV AH, 3EH ;AN000; DOS Fn. for closing a file
DOSCALL ;AN000; Close the file
;**********************************************************************
; Deallocate the memory used for the data buffer
;**********************************************************************
MOV AX, SEG_LOC ;AN000; Location of the data buffer
MOV ES, AX ;AN000;
MOV AH, 49H ;AN000; DOS Fn. for freeing allocated memory
DOSCALL ;AN000; Free the memory
POP ES ;AN000;
CALL RESTORE_INT_24;AN000;
RET ;AN000;
RELEASE_PRINTER_INFO_ROUTINE ENDP;AN000;
;*******************************************************************************
; Routines for changing the SELECT command line in the AUTOEXEC.BAT.
;*******************************************************************************
;********************************************************************************
; CHANGE_AUTOEXEC_ROUTINE: Search a file for a line beginning with SELECT, and
; change its parameters.
;
; INPUT:
; DI - The offset of an ASCII-N string containing the file to search.
; SI - The offset of an ASCII-N string containing the data to append as
; parameters.
;
; OUTPUT:
; None.
;
; Operation:
;
;********************************************************************************
CHANGE_AUTOEXEC_ROUTINE PROC FAR;AN000;
TEST SEL_FLG,INSTALLRW ;AN000; Is the install
;AN000; diskette read/write
;AN000; (has DISKCOPY occurred?)
JNZ AUTO_OK ;AN000;
CLC ;AN000; no error
JMP AUTO_EXIT_RO ;AN000; If not, exit
AUTO_OK: ;AN000;
CALL HOOK_INT_24 ;AN000;
PUSH ES ;AN000;
MOV APPEND_POINTER, SI ;AN000; Save the address of the string to be appended
MOV FILENAME, DI ;AN000; Save the address of the string containing the filename
;**********************************************************************
; Allocate the memory needed for reading the autoexec file. A maximum
; of 64K is allocated for use.
;**********************************************************************
CALL ALLOCATE_MEMORY ;AN000; Allocate the memory needed
.IF < C > ;AN000; Was there an error?
JMP AUTO_EXIT_ERROR ;AN000; Yes! Exit the subroutine
.ENDIF ;AN000;
MOV BUFFER_START, 0 ;AN000; Save the offset of the start of the buffer
COPY_WORD BUFFER_SIZE, SEGMENT_SIZE ;AN000; Save the size of the buffer
;**********************************************************************
; Open the input file
;**********************************************************************
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
; DI contains the address of the filename
CALL POS_ZERO ;AN000; Make the string into an ASCII-Z string
MOV DX, DI ;AN000; Load string offset
ADD DX, 2 ;AN000; Adjust for length word
MOV AX, 3D02H ;AN000; DOS Fn. for opening a file for reading and writing
DOSCALL ;AN000; Open the file
.IF < C > ;AN000; Was there an error?
JMP AUTO_EXIT_ERROR ;AN000; Exit the subroutine
.ENDIF ;AN000;
MOV FILE_HANDLE, AX ;AN000; Save the file handle
;**********************************************************************
; Set the file pointer
;**********************************************************************
MOV WORD PTR FILE_PTR_AT_START[0], 0 ;AN000; Set the file pointer of the data in the buffer
MOV WORD PTR FILE_PTR_AT_START[2], 0 ;AN000; Set the high word
MOV CURRENT_PARSE_LOC, 0 ;AN000; Set the current parsing location
AND READ_FLAG, RESET_EOF ;AN000; Indicate that the end of file has not been reached
;**********************************************************************
; Read data into the buffer
;**********************************************************************
MOV DI, CURRENT_PARSE_LOC ;AN000; Get the current parsing location
CALL READ_FROM_HERE ;AN000; Read data starting from this position
.IF < C > ;AN000; Was there an error?
JMP AUTO_EXIT_ERROR ;AN000; Yes! Exit the subroutine
.ENDIF ;AN000;
;**********************************************************************
; Setup the control blocks for the parser
;**********************************************************************
MOV PAR_EXTEN, OFFSET SELECT_PARMX ;AN000; Address of the parameters extension block
;**********************************************************************
; Parse the file for 'SELECT'
;**********************************************************************
PARSE_FOR_SELECT: ;AN000; Here to parse the line
CALL SEARCH_LINE ;AN000; Parse the line.
.IF < C > ;AN000; Was there an error?
JMP AUTO_EXIT_ERROR ;AN000; Yes! Exit the subroutine
.ENDIF ;AN000;
.IF < AX EQ 0 > ;AN000; Did the parser file 'SELECT'?
MOV CURRENT_PARSE_LOC, SI ;AN000; Yes! Save the position after select as parse location
MOV DX, WORD PTR FILE_PTR_AT_START[0];AN000;
MOV CX, WORD PTR FILE_PTR_AT_START[2];AN000;
ADD DX, CURRENT_PARSE_LOC ;AN000;
ADC CX, 0 ;AN000;
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
MOV BX, FILE_HANDLE ;AN000;
MOV AX, 4200H ;AN000;
DOSCALL ;AN000;
.IF < C > ;AN000; Was there an error writing the data?
JMP AUTO_EXIT_ERROR ;AN000; Yes! Exit the subroutine
.ENDIF ;AN000;
;*****************************************************************
; Write the select parameters to the file
;*****************************************************************
MOV SI, APPEND_POINTER ;AN000; Address of the string to add to the select line
MOV CX, [SI] ;AN000; Size of the string
MOV DX, SI ;AN000; Get the address again
ADD DX, 2 ;AN000; Adjust pointer past length word
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
MOV BX, FILE_HANDLE ;AN000; Get the handle for this file
MOV AH, 40H ;AN000; DOS Fn. number for writing data
DOSCALL ;AN000; Write the data
;*****************************************************************
; Write a carrage return and a line feed to the file
;*****************************************************************
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
MOV DX, OFFSET W_CR_LF ;AN000; Address of string to write
MOV CX, E_SIZE_CR_LF ;AN000; Size of the string
MOV BX, FILE_HANDLE ;AN000; Get the file handle
MOV AH, 40H ;AN000; DOS Fn. for writing data
DOSCALL ;AN000; Write the data
;*****************************************************************
; Truncate the file at the current file position
;*****************************************************************
MOV INT_24_ERROR, 0 ;AN000; Indicate that no critical errors have occured yet
MOV CX, 0 ;AN000;
MOV BX, FILE_HANDLE ;AN000;
MOV AH, 40H ;AN000;
DOSCALL ;AN000;
;*****************************************************************
; Close the file.
;*****************************************************************
CALL RELEASE_PRINTER_INFO_ROUTINE ;AN000; Close the original autoexec file
.ELSE ;AN000;
;*****************************************************************
; Parse the next line.
;*****************************************************************
MOV DI, START_NEXT_LINE ;AN000; Get the address of the next line
MOV CURRENT_PARSE_LOC, DI ;AN000; Save this as the current parse location
.IF < CURRENT_PARSE_LOC EQ 0 > ;AN000; If this is zero, then there is no more data
JMP AUTO_EXIT_CLEAR ;AN000; Exit the subroutine - No errors
.ENDIF ;AN000;
JMP PARSE_FOR_SELECT ;AN000; Parse the next line
.ENDIF ;AN000;
JMP AUTO_EXIT_CLEAR ;AN000; Exit the subroutine - No errors
AUTO_EXIT_ERROR: ;AN000; Here if there was an error
CALL RELEASE_PRINTER_INFO_ROUTINE ;AN000; Close the original file
STC ;AN000; Indicate that there was an error
JMP AUTO_EXIT ;AN000; Exit the subroutine
AUTO_EXIT_CLEAR: ;AN000; Exit here if NO errors.
CLC ;AN000; Indicate there were no errors
AUTO_EXIT: ;AN000; Here to exit
CALL DEALLOCATE_MEMORY
POP ES ;AN000; Restore the extra segment
CALL RESTORE_INT_24;AN000;
AUTO_EXIT_RO: ;AN000;
RET ;AN000;
CHANGE_AUTOEXEC_ROUTINE ENDP;AN000;
CODE_FAR ENDS;AN000;
END ;AN000;
|