1 ;********************************************************************************
4 ; Subroutines to read the printer profile file, extract the printer names,
5 ; build a scroll list for the cas services and retrieve addition information
6 ; from the file on a specific printer.
7 ; Also contains a subroutine to change the parameters for the SELECT command
8 ; in the autoexec.bat file.
10 ;********************************************************************************
14 INCLUDE MACROS
.INC ;AN000;
15 INCLUDE STRUC.INC ;AN000;
18 ;***************************************************************************
19 ; Define the public subroutines in this module
20 ;***************************************************************************
21 PUBLIC GET_PRINTER_TITLES_ROUTINE
;AN000;
22 PUBLIC GET_PRINTER_INFO_ROUTINE
;AN000;
23 PUBLIC RELEASE_PRINTER_INFO_ROUTINE
;AN000;
24 PUBLIC CHANGE_AUTOEXEC_ROUTINE
;AN000;
25 ;***************************************************************************
26 ; Define the public values in this module
27 ;***************************************************************************
28 PUBLIC SEG_LOC
;AN000; The segment where the printer data is stored
29 PUBLIC NAMES_OFF
;AN000; The offset in the segment of the names table
30 PUBLIC N_PRN_NAMES
;AN000; The number of printer definitions read from the profile
31 PUBLIC MAX_NAME
;AN000; The longest name in the list
32 PUBLIC SIZE_NAMES
;AN000; The number of bytes between each printer name (abs)
33 PUBLIC SEL_FLG
;AN000; AN000; SELECT runtime flag
35 EXTRN SYSPARSE
: FAR;AN000;
36 EXTRN POS_ZERO
: FAR;AN000;
37 EXTRN COPY_ROUTINE
: FAR;AN000;
38 EXTRN I_PRINTER
: WORD;AN000;
39 EXTRN N_PRINTER_TYPE
: BYTE;AN000;
40 EXTRN S_MODE_PARM
: WORD;AN000;
41 EXTRN S_CP_DRIVER
: WORD;AN000;
42 EXTRN S_CP_PREPARE
: WORD;AN000;
43 EXTRN S_GRAPH_PARM
: WORD;AN000;
44 EXTRN HOOK_INT_24
:FAR;AN000;
45 EXTRN RESTORE_INT_24
:FAR;AN000;
46 EXTRN INT_24_ERROR
:WORD;AN000;
49 EXTRN BIN_TO_CHAR_ROUTINE
:FAR;AN000;
51 DATA SEGMENT BYTE PUBLIC 'DATA';AN000;
54 SEL_FLG
DB 0 ;AN000; Select flag byte
55 ;INSTALLRW EQU 80H ;AN000; INSTALL diskette is R/W
57 SEG_LOC
DW 0 ;AN000; Location of the segment where the data is
58 NAMES_OFF
DW 0 ;AN000; The offset of the names table in the segment
59 SEGMENT_SIZE
DW 0 ;AN000; Amount of memory available
60 BUFFER_START
DW 0 ;AN000; Starting offset of the file data buffer
61 BUFFER_SIZE
DW 0 ;AN000; Number of bytes in the file data buffer
62 FILE_PTR_AT_START
DD 0 ;AN000; The file pointer for the data which is at
63 ; the beginning of the file data buffer
64 AMOUNT_OF_DATA
DW 0 ;AN000; The number of bytes in the file data buffer
65 CURRENT_PARSE_LOC
DW 0 ;AN000; The location to start the next parse.
66 END_CUR_LINE
DW 0 ;AN000; The address of the end of the line currently being parsed
67 CX_ORDINAL_VALUE
DW 0 ;AN000; The value returned by the parse for next call
68 NUM_PRINTER_DEFS
DB 0 ;AN000; The number of printer definitions in the file
69 N_PRN_NAMES
DW 0 ;AN000; The next free index into the names table
70 FILE_HANDLE
DW 0 ;AN000; Handle for the printer definition file.
71 MAX_NAME
DW 0 ;AN000; The length of the longest printer name found in the file
72 START_NEXT_LINE
DW 0 ;AN000; The starting offset of the next line to parse
73 APPEND_POINTER
DW 0 ;AN000; Offset of the ASCII-N string to append to the SELECT line
74 FILENAME
DW 0 ;AN000; Offset of the ASCII-N string containing the filename
75 CDP_FOUND
DB 0 ;AN000;
76 CPP_FOUND
DB 0 ;AN000;
80 STRING_N
DB 10 DUP(0);AN000;
83 ;AD000;JW BLANK_MODE DW END_BLANK_MODE - $ - 3 ; The blank line for inserting mode parameters
84 ;AD000;JW DB ' , , , , ',?
85 ;AD000;JW END_BLANK_MODE EQU $
87 BLANK_STRING
DW 0 ;AN000; Blank values for the other printer profile parameters
89 E_SIZE_CR_LF EQU
2 ;AN000; The number of bytes in W_CR_LF
90 W_CR_LF
DB 13,10 ;AN000; Carrage return and line feed to append to the select line
92 READ_FLAG
DB 0 ;AN000; Flag for use when reading data
93 AT_EOF EQU
1B ;AN000; Indicates when the end of file has been reached
94 LAST_LINE EQU
10B ;AN000; Indicates if this is the last line in the buffer
96 RESET_EOF EQU
11111110B ;AN000; Masks for resetting the flags
97 RESET_LST_LINE EQU
11111101B ;AN000;
99 PARSE_FLAG
DB 0 ;AN000; Flag for use when parsing the data
100 FIRST_PARSE EQU
1B ;AN000; Indicates if this is the first line being parsed
101 LINE_DONE EQU
10B ;AN000; Indicates if the current line has already been parsed
102 FIRST_NAME EQU
100B ;AN000; Indicates if a printer names has already been found
104 RESET_FIRST_PARSE EQU
11111110B ;AN000; Masks for resetting the flags
105 RESET_LINE_DONE EQU
11111101B ;AN000;
106 RESET_FIRST_NAME EQU
11111011B ;AN000;
108 ;***************************************************************************
109 ; Error codes returned.
110 ;***************************************************************************
111 ERR_NOT_ENOUGH_MEM EQU
1 ;AN000; There was not enough memory to build the names table
112 ERR_OPENING_FILE EQU
2 ;AN000; Error opening a file
113 ERR_READING_FILE EQU
3 ;AN000; Error reading from a file
114 ERR_FINDING_VALUE EQU
4 ;AN000; Error finding the number of prn defs at the beginning of the file
115 ERR_LINE_TOO_LONG EQU
5 ;AN000; There was a line too long for the buffer
116 ERR_FINDING_NAME EQU
6 ;AN000; There was an error locating a printer name after a P or S
117 ERR_ACCESSING_FILE EQU
7 ;AN000; There was an error updating the file pointer
118 ERR_TOO_MANY_DEFS EQU
8 ;AN000; There are too many defintion in the file
119 ERR_NUMBER_MATCH EQU
9 ;AN000; The number of actual definition do not match the number expected
120 ERR_ALLOCATING_MEM EQU
10 ;AN000; There was an error allocating memory
121 ERR_CDP_CPP EQU
11 ;AN000; A prn defn had either a CDP or CPP but not both
122 ERR_PRN_DEFN EQU
12 ;AN000;
130 E_FILE_TERM EQU 1
AH ;AN000;
132 E_MAX_PRN_NAME_LEN EQU
40 ;AN000; The maximum printer name length
133 LENGTH_FILE_PTR EQU
4 ;AN000; The number of bytes in the file pointer
134 MAX_NUM_PRINTER_DEFS EQU
31 ;AC089;SEH ;AC073; The maximum number of printer definitions
135 MIN_SIZE_FILE_BUFFER EQU
0400H ;AN000; The minimum amount of memory needed for the file data buffer
136 LENGTH_PRT_TYPE_IND EQU
1 ;AN000; The length of the printer type indicator
137 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
138 NAMES_TABLE_SIZE EQU SIZE_NAMES
* MAX_NUM_PRINTER_DEFS
;AN000; The size of the names table
139 MINIMUM_MEMORY EQU NAMES_TABLE_SIZE
+ MIN_SIZE_FILE_BUFFER
;AN000; The minimum amount of memory required
141 RANGE_ONLY EQU
1 ;AN000; The parser is only to look for ranges of values
142 RANGE_AND_STRING EQU
3 ;AN000; The parser is to look for ranges and strings
144 NUMERIC_VALUE EQU
08000H ;AN000; Parser constant for searching for numeric values
145 SIMPLE_STRING EQU
02000H ;AN000; Parser constant for searching for strings
148 ; Control blocks for the parser.
149 ; The PARMS INPUT BLOCK
150 PARMS
LABEL BYTE ;AN000;
151 PAR_EXTEN
DW OFFSET PARMSX
;AN000; Offset of the PARMS EXTENSION BLOCK
152 PAR_NUM
DB 2 ;AN000; The number of further definitions
157 ; The PARMS EXTENSION BLOCK
158 PARMSX
LABEL BYTE;AN000;
159 PAX_MINP
DB 0 ;AN000;
160 PAX_MAXP
DB 1 ;AN000;
161 DW CONTROL_P1
;AN000;
162 PAX_MAX_SW
DB 0;AN000;
163 PAX_MAX_K1
DB 0;AN000;
165 ; The control blocks for the definition of positional parameters, switch and
167 CONTROL_P1 EQU
$ ;AN000;
168 CTL_FUNC_FL
DW 2000H
;AN000;
171 DW VALUE_LIST_P1
;AN000;
174 VALUE_LIST_P1 EQU
$;AN000;
175 VAL_NUM
DB 1 ;AN000; Number of value definitions
176 DB 1 ;AN000; Number of range definitions
177 DB 8 ;AN000; Return value if parameter is in this range
180 DB 0 ;AN000; Number of actual value definitions
181 NUM_STRINGS
DB 2 ;AN000; Number of string definitions
182 DB 1 ;AN000; Value to be returned if this string is matched
183 DW OFFSET KEYWORD_PARALLEL
;AN000;
184 DB 2 ;AN000; Value to be returned if this string is matched
185 DW OFFSET KEYWORD_SERIAL
;AN000;
187 DB 3 ;AN000; Value to be returned if this string is matched
188 DW OFFSET KEYWORD_MODE
;AN000;
189 DB 4 ;AN000; Value to be returned if this string is matched
190 DW OFFSET KEYWORD_CODE_DRIVER
;AN000;
191 DB 5 ;AN000; Value to be returned if this string is matched
192 DW OFFSET KEYWORD_CODE_PREPARE
;AN000;
193 DB 6 ;AN000; Value to be returned if this string is matched
194 DW OFFSET KEYWORD_GRAPHICS
;AN000;
196 KEYWORD_PARALLEL
DB 'P',0;AN000;
197 KEYWORD_SERIAL
DB 'S',0;AN000;
198 KEYWORD_MODE
DB 'SP',0;AN000;
199 KEYWORD_CODE_DRIVER
DB 'CDP',0;AN000;
200 KEYWORD_CODE_PREPARE
DB 'CPP',0;AN000;
201 KEYWORD_GRAPHICS
DB 'GP',0;AN000;
203 RESULT_P1
LABEL BYTE;AN000;
204 DB 0 ;AN000; Type of operand returned
205 MATCHED_TAG
DB 0 ;AN000; Matched item tag
206 SYNONYM_PTR
DW 0 ;AN000; Offset of synonym returned
207 RESULT_FIELD
DB 0,0,0,0 ;AN000; Unsure what this is...
210 ;AD000;JW ;***************************************************************************
211 ;AD000;JW ; Parser control blocks for parsing the mode parameters
212 ;AD000;JW ;***************************************************************************
213 ;AD000;JW MODE_PARMS LABEL BYTE
214 ;AD000;JW DW MODE_PARMSX
217 ;AD000;JW MODE_PARMSX LABEL BYTE
221 ;AD000;JW DW OFFSET CNTL_BAUD
223 ;AD000;JW CNTL_BAUD LABEL BYTE
224 ;AD000;JW DW SIMPLE_STRING
226 ;AD000;JW DW RESULT_P1
227 ;AD000;JW DW MODE_VALUES
229 ;AD000;JW SYN_BAUD DB 'BAUD',0
230 ;AD000;JW SYN_PARITY DB 'PARITY',0
231 ;AD000;JW SYN_DATA DB 'DATA',0
232 ;AD000;JW SYN_STOP DB 'STOP',0
233 ;AD000;JW SYN_RETRY DB 'RETRY',0
235 ;AD000;JW MODE_VALUES LABEL BYTE
239 ;***************************************************************************
240 ; Parser control blocks for parsing the AUTOEXEC.BAT file for 'SELECT'
241 ;***************************************************************************
242 SELECT_PARMX
LABEL BYTE ;AN000;
244 DW SELECT_CONTROL
;AN000;
248 SELECT_CONTROL
LABEL BYTE;AN000;
252 DW SELECT_VALUE
;AN000;
255 SELECT_VALUE
LABEL BYTE ;AN000;
261 DW OFFSET SELECT_STR
;AN000;
263 SELECT_STR
DB 'SELECT',0;AN000;
270 CODE_FAR
SEGMENT BYTE PUBLIC 'CODE';AN000;
272 ASSUME
CS:CODE_FAR
, DS:DATA, ES:DATA;AN000;
274 ;***************************************************************************
275 ; Routines for extracting the printer names from the file data and storing
276 ; them in a table located in high memory. In addition to the name, the
277 ; type of printer, whether Parallel or Serial and the location in the file
278 ; of this printer name is also saved in the table.
279 ;***************************************************************************
281 ;******************************************************************************
283 ; Routine: GET_PRINTER_TITLES_ROUTINE - Reads the names of all the printers
284 ; and their location in the file into a data
285 ; buffer in high memory.
288 ; DI - The offset of name of the file which contains the printer definitions
292 ; If CY = 1: Indicates that an error has occured.
293 ; BX - The error code for the error which this subroutine detected.
294 ; AX - The error code which was returned if the error was as a result
296 ; If CY = 0: No error has occured.
297 ; AX, BX - Undefined.
299 ;******************************************************************************
300 GET_PRINTER_TITLES_ROUTINE PROC
FAR ;AN000;
302 CALL HOOK_INT_24
;AN000;
307 ;**********************************************************************
308 ; Allocate the necessary memory for the buffer. A maximum of 64K is
310 ;**********************************************************************
311 CALL ALLOCATE_MEMORY
;AN000; Allocate the memory for the printer data
312 .IF < C
> ;AN000; Was there an error?
313 JMP EXIT_WITH_ERROR
;AN000; If so, exit the subroutine
315 ;**********************************************************************
316 ; See if there is enough memory to continue.
317 ;**********************************************************************
318 .IF < SEGMENT_SIZE B MINIMUM_MEMORY
> ;AN000; Is there enough memory?
319 MOV BX, ERR_NOT_ENOUGH_MEM
;AN000; No! Return error code.
320 JMP EXIT_WITH_ERROR
;AN000; Exit the subroutine
322 ;**********************************************************************
323 ; Set the pointer for the file data buffer and save the size of this buffer.
324 ;**********************************************************************
325 MOV BUFFER_START
, NAMES_TABLE_SIZE
;AN000; Starting address of the file data buffer
326 MOV BX, SEGMENT_SIZE
;AN000; Total amount of memory available
327 SUB BX, NAMES_TABLE_SIZE
;AN000; Calculate the size of the file data buffer
328 MOV BUFFER_SIZE
, BX ;AN000; Save this size.
329 MOV NAMES_OFF
, 0 ;AN000; Offset of the printer names table
330 ;**********************************************************************
331 ; Open the printer definition file.
332 ;**********************************************************************
333 MOV INT_24_ERROR
, 0 ;AN000;
334 CALL POS_ZERO
;AN000; Turn the ASCII-N string into an ASCII-Z string
335 MOV DX, DI ;AN000; Get address of the ASCII-N string
336 ADD DX, 2 ;AN000; Address of the filename
337 MOV AX, 3D00H
;AN000; Open file for reading.
339 .IF < C
> ;AN000; Was there an error opening the file?
340 MOV BX, ERR_OPENING_FILE
;AN000; Yes! Return this error code
341 JMP EXIT_WITH_ERROR
;AN000;
343 MOV FILE_HANDLE
, AX ;AN000; Save the handle for the file
344 ;**********************************************************************
345 ; Initialize the variable which holds the file pointer at the beginning
347 ;**********************************************************************
348 MOV WORD PTR FILE_PTR_AT_START
, 0 ;AN000; Zero the low word
349 MOV WORD PTR FILE_PTR_AT_START
+2, 0 ;AN000; Zero the high word
350 AND READ_FLAG
, RESET_EOF
;AN000; Indicate we are not at EOF
351 ;**********************************************************************
352 ; Read data into the file buffer.
353 ;**********************************************************************
354 MOV DI, BUFFER_START
;AN000; Start reading at this offset
355 SUB DI, NAMES_TABLE_SIZE
;AN000; Make into an offset in the buffer instead of the segment
356 CALL READ_FROM_HERE
;AN000; Read in the data.
357 .IF < C
> ;AN000; Was there an error reading from the file?
358 MOV BX, ERR_READING_FILE
;AN000; Return this error code
359 JMP EXIT_WITH_ERROR
;AN000; Return from this subroutine
361 ;**********************************************************************
362 ; Initialize the variables needed for the parsing.
363 ;**********************************************************************
364 MOV CURRENT_PARSE_LOC
, NAMES_TABLE_SIZE
;AN000; Start parsing from the beginning.
365 MOV CX_ORDINAL_VALUE
, 0 ;AN000; The first parse, CX must be zero.
366 MOV N_PRN_NAMES
, 0 ;AN000; There are not names in the table now
367 AND PARSE_FLAG
, RESET_LINE_DONE
;AN000; The current line has NOT been parsed
368 OR PARSE_FLAG
, FIRST_PARSE
;AN000; Indicate that this is the first parse
369 ;**********************************************************************
370 ; Setup the control blocks for the parser
371 ;**********************************************************************
372 MOV PAR_EXTEN
, OFFSET PARMSX
;AN000; Load the address of the parse extention block
373 ;**********************************************************************
374 ; Parse the data. If this is the first parse, then look for the number
375 ; of printer definitions. If it is not, then look for the parameters
376 ; P and S which preface the printer names.
377 ;**********************************************************************
378 MOV VAL_NUM
, RANGE_ONLY
;AN000; Parse for a range of values only
379 MOV CTL_FUNC_FL
, NUMERIC_VALUE
;AN000; Indicate we are looking for numbers
380 MOV NUM_STRINGS
, 2 ;AN000; The number of parameters to look for
381 ;**********************************************************************
382 ; See if there is a complete line in the remainder of the buffer. If there
383 ; is not, then read more data into the buffer starting with the start of
385 ;**********************************************************************
386 PARSE_NEXT_LINE: ;AN000;
387 CALL SEARCH_LINE
;AN000; Search for the first parameter on the line
388 .IF < C
> ;AN000; Was there an error?
389 JMP EXIT_WITH_ERROR
;AN000; Yes! Exit the routine
391 .IF < BIT PARSE_FLAG
AND FIRST_PARSE
> ;AN000; Looking for a value or a string?
392 .IF < AX NE
0 > ;AN000; Was there an error?
393 MOV BX, ERR_FINDING_VALUE
;AN000; Yes! Return with this error code
394 JMP EXIT_WITH_ERROR
;AN000;
396 MOV AL, RESULT_FIELD
;AN000; Get the low order byte of the value
397 MOV NUM_PRINTER_DEFS
, AL ;AN000; Store the number of definitions
398 AND PARSE_FLAG
, RESET_FIRST_PARSE
;AN000; Indicate the first parse is finished
399 MOV VAL_NUM
, RANGE_AND_STRING
;AN000; Specify strings and ranges
400 MOV CTL_FUNC_FL
, SIMPLE_STRING
;AN000; Look for specific strings only.
402 ;**********************************************************************
403 ; See if we found a printer name
404 ;**********************************************************************
405 .IF < AX EQ 0 > ;AN000; Was an error found parsing the buffer
406 .IF < N_PRN_NAMES AE MAX_NUM_PRINTER_DEFS
> ;AN000; Are there more the 255 printer defs?
407 MOV BX, ERR_TOO_MANY_DEFS
;AN000; If so, return this error.
408 JMP EXIT_WITH_ERROR
;AN000; Terminate the subroutine.
410 ; DX contains the address of the result block
411 CALL COPY_PRINTER_NAME
;AN000; Copy the name to the table
412 .IF < C
> ;AN000; Was there an error?
413 MOV BX, ERR_FINDING_NAME
;AN000; Yes! Return this error code
414 JMP EXIT_WITH_ERROR
;AN000;
417 ;**********************************************************************
418 ; Start scanning the next line.
419 ;**********************************************************************
420 MOV DI, START_NEXT_LINE
;AN000; Get the address of the next line to parse
421 MOV CURRENT_PARSE_LOC
, DI ;AN000; Save it
422 .IF < CURRENT_PARSE_LOC
EQ 0 > ;AN000; Is there more data?
423 JMP EXIT_WITHOUT_ERROR
;AN000; No! Exit the routine
425 JMP PARSE_NEXT_LINE
;AN000; Start processing this line
427 EXIT_WITH_ERROR: ;AN000;
428 STC ;AN000; Set the carry flag, indicating error.
429 JMP EXIT_ROUTINE
;AN000;
430 EXIT_WITHOUT_ERROR: ;AN000;
431 MOV CX, N_PRN_NAMES
;AN000; The number of entries in the table
432 .IF < CL NE NUM_PRINTER_DEFS
> ;AN000; Did the number of definitions agree with the expected number?
433 MOV BX, ERR_NUMBER_MATCH
;AN000; Return this error message
434 JMP EXIT_WITH_ERROR
;AN000; Return, setting the carry flag.
436 CLC ;AN000; Clear the carry flag - No error.
437 EXIT_ROUTINE: ;AN000;
438 CALL DEALLOCATE_MEMORY
440 CALL RESTORE_INT_24
;AN000;
443 GET_PRINTER_TITLES_ROUTINE ENDP
;AN000;
444 ;********************************************************************************
446 ;SEARCH_LINE: Search for the first parameter on a line.
452 ; AX - Contains the return codes from the parser
453 ; If CY = 1: There was an error - BX contains an error code
454 ; if CY = 0: There were NO errors.
455 ; All the registers are set from the parser return.
459 ;********************************************************************************
460 SEARCH_LINE PROC
NEAR ;AN000;
462 MOV DI, CURRENT_PARSE_LOC
;AN000; Get the current location in the buffer
463 CALL SCAN_FOR_EOLN
;AN000; Search for the end of the line
464 MOV START_NEXT_LINE
, DI ;AN000; Save the start address of the next line
465 .IF < C
> ;AN000; Was the END OF LINE found?
466 .IF <BIT READ_FLAG
AND AT_EOF
> ;AN000; Are we at the end of the file?
467 MOV START_NEXT_LINE
, 0 ;AN000; Yes! Indicate that this is the last line
468 .ELSE ;AN000; We are not the the end of the file
469 MOV DI, CURRENT_PARSE_LOC
;AN000; The location to read from in the file
470 SUB DI, NAMES_TABLE_SIZE
;AN000; Make into an offset in the buffer instead of the segment
471 CALL READ_FROM_HERE
;AN000; Read in more data
472 .IF < C
> ;AN000; Was there an error reading from the file?
473 MOV BX, ERR_READING_FILE
;AN000; Return this error code
474 JMP EXIT_SEARCH_ERROR
;AN000; Return from this subroutine
476 MOV CURRENT_PARSE_LOC
, NAMES_TABLE_SIZE
;AN000; Start back at the beginning of the buffer
477 MOV DI, CURRENT_PARSE_LOC
;AN000; Get the current parse location again.
478 CALL SCAN_FOR_EOLN
;AN000; Once again look for the end of the line
479 MOV START_NEXT_LINE
, DI ;AN000; Save the start address of the nest line
480 .IF < C
> ;AN000; Was it found?
481 MOV BX, ERR_LINE_TOO_LONG
;AN000; No! Indicate an error.
482 JMP EXIT_SEARCH_ERROR
;AN000; Return with this error
486 ;**********************************************************************
487 ; Set up the input parameters for the parse subroutine
488 ;**********************************************************************
489 MOV DI, OFFSET PARMS
;AN000; Offset into ES of the PARMS control block
490 MOV SI, CURRENT_PARSE_LOC
;AN000; Where to start parsing
492 MOV CX, CX_ORDINAL_VALUE
;AN000; The value returned by the parse last time.
493 PUSH DS ;AN000; Save the current data segment
494 PUSH ES ;AN000; Save the file data segment
495 MOV AX, DATA ;AN000; Get the current data segment
496 MOV ES, AX ;AN000; This is the parser control blocks.
497 MOV AX, SEG_LOC
;AN000; Where the data to parse is located
499 CALL SYSPARSE
;AN000; Do the parsing
500 POP ES ;AN000; Restore the file data segment
501 POP DS ;AN000; Restore the data segment
502 CLC ;AN000; Indicate there were no errors
504 EXIT_SEARCH_ERROR: ;AN000; Here if there were errors
505 STC ;AN000; Indicate so to the calling program
508 SEARCH_LINE ENDP
;AN000;
509 ;********************************************************************************
510 ; ALLOCATE_MEMORY: Allocate a maximum of 64K of memory.
516 ; SEGMENT_SIZE = The size of the segment allocated.
517 ; SEG_LOC = The location of the segment allocated.
518 ; If CY = 1: There was an error - BX contains an error code
519 ; If CY = 0: There was NO errors.
523 ;********************************************************************************
524 ALLOCATE_MEMORY PROC
NEAR;AN000;
526 AND ALLOC_FLAG
,NOT ALLOCATED
527 MOV BX, 0FFFH ;AN000; Try to allocate this amount of memory
528 MOV SEGMENT_SIZE
, BX ;AN000; Save the amount of memory asked for
529 MOV AH, 48H
;AN000; DOS Fn. for allocating memory
530 DOSCALL
;AN000; Allocate the memory
531 .IF < C
> ;AN000; Was there an error?
532 MOV SEGMENT_SIZE
, BX ;AN000; Save the size asked for in this request
533 MOV AH, 48H
;AN000; DOS Fn. for allocating memory
534 DOSCALL
;AN000; Allocate the memory
536 .IF < C
> ;AN000; Was there an error allocating the memory?
537 MOV BX, ERR_ALLOCATING_MEM
;AN000; Yes! Return an error code
538 STC ;AN000; Indicate that there was an error
539 .ELSE ;AN000; Otherwise...
540 MOV SEG_LOC
, AX ;AN000; Save the location of the memory block allocated
541 MOV ES, AX ;AN000; Save in the extra segment
542 MOV CL, 4 ;AN000; Multiply the number of paragraphs by 16
543 SHL SEGMENT_SIZE
, CL ;AN000; to get the number of bytes.
544 OR ALLOC_FLAG
,ALLOCATED
545 CLC ;AN000; Indicate there was no error
549 ALLOCATE_MEMORY ENDP
;AN000;
552 ;********************************************************************************
553 ; DEALLOCATE_MEMORY: deallocate memory.
556 ; SEG_LOC previously allocated segment
561 ;********************************************************************************
562 DEALLOCATE_MEMORY PROC
NEAR
564 TEST ALLOC_FLAG
,ALLOCATED
575 DEALLOCATE_MEMORY ENDP
577 ;*******************************************************************************
579 ; Routine: SCAN_FOR_EOLN - Scan the given string, for CR and LF.
582 ; DI - Address of the string to scan for the eoln.
585 ; If CY = 0: The end of the line was found.
586 ; DI - Contains the address of the start of the next line in the buffer.
587 ; - If DI = 0, the data ends just after either the CR, LF or the
588 ; CR and LF. Therefore, more data must be read before the next line
591 ; If CY = 1: The end of the line was not found.
593 ;*******************************************************************************
594 SCAN_FOR_EOLN PROC
NEAR;AN000;
596 MOV CX, BUFFER_START
;AN000; The offset in the segment of the buffer
597 ADD CX, AMOUNT_OF_DATA
;AN000; Get the offset of the end of the data
598 SUB CX, DI ;AN000; Subtract the file data pointer
599 ; CX - Contains the amount of data after pointer
600 MOV AL, 0 ;AN000; Flag to indicate CR-LF has not been found yet
601 .WHILE < CX A
0 > ;AN000; Search until the end of the data
602 .IF < <BYTE PTR ES:[DI]> EQ E_FILE_TERM
>;AN000;
603 .IF < ZERO
AL > ;AN000;
604 MOV END_CUR_LINE
, DI ;AN000; Save this location in the string
605 DEC END_CUR_LINE
;AN000; Point to the real end of the line
609 JMP EXIT_SCAN
;AN000;
611 .IF < <BYTE PTR ES:[DI]> EQ E_LF
> OR ;AN000; Is this character a CR or a LF?
612 .IF < <BYTE PTR ES:[DI]> EQ E_CR
> ;AN000;
613 .IF < ZERO
AL > ;AN000; Has a CR or a LF already been found?
614 MOV END_CUR_LINE
, DI ;AN000; Save this location in the string
615 DEC END_CUR_LINE
;AN000; Point to the real end of the line
617 INC AL ;AN000; Indicate that a CR or a LF has been found
618 .ELSEIF
< NONZERO
AL > ;AN000; If we have passed the CR-LF,
619 CLC ;AN000; Indicate we have found EOLN
620 JMP EXIT_SCAN
;AN000; Leave the subroutine
622 DEC CX ;AN000; One less character to the end
623 INC DI ;AN000; Point to the next character
626 .IF < AL AE
2 > ;AN000; Does the data run out right after the CR-LF?
627 MOV DI, 0 ;AN000; Return 0 indicating so.
629 STC ;AN000; Indicate that the whole line is not there
634 SCAN_FOR_EOLN ENDP
;AN000;
635 ;*******************************************************************************
637 ; Routine: COPY_PRINTER_NAME - Copy the name of the printer from the file
638 ; into the buffer holding all the names.
641 ; SI - Contains the address of the start of the printer name.
642 ; DX - Contains the address of the parse result block
645 ; CY = 1: An error has occured. The name of the printer has not been found.
648 ; Operation: The name from the file buffer is copied to the printer name
649 ; table. Starting from the address passed in DI, the file buffer is
650 ; scanned until a valid character is found. Starting from this point
651 ; up to forty characters are transferred to the name table. If no
652 ; name is found, the carry flag is set, and nothing is recorded in the
654 ; After the name is copied, the remainder of the field in the table
657 ;*******************************************************************************
658 COPY_PRINTER_NAME PROC
NEAR;AN000;
662 PUSH DX ;AN000; Save the address of the result block
663 ;**********************************************************************
664 ; Calculate the offset into the file data table for this entry
665 ;**********************************************************************
666 MOV AX, N_PRN_NAMES
;AN000; The next free index into the names table
667 MOV BX, SIZE_NAMES
;AN000; Get the number of bytes per entry
668 MUL BX ;AN000; Multiply by the index into the table
669 MOV DI, AX ;AN000; Move the offset into an index register
670 ;**********************************************************************
671 ; Copy the type of printer first
672 ;**********************************************************************
673 POP BX ;AN000; Get the result block address
674 MOV AL, DS:[BX+1] ;AN000; Get the matched item tag
675 .IF < AL EQ 1 > ;AN000; Was the parameter a P?
676 MOV AL, 'P' ;AN000; Yes!
678 MOV AL, 'S' ;AN000; No! It was an S
680 MOV ES:[DI+40], AL ;AN000; Store in the table
681 ;**********************************************************************
682 ; Skip the spaces between the printer type indicator and the printer name
683 ;**********************************************************************
684 MOV AL, 32 ;AN000; Character to skip - space
685 XCHG SI, DI ;AN000; Point DI to the line being scanned
686 MOV CX, END_CUR_LINE
;AN000; Get address of the last char in line
687 SUB CX, DI ;AN000; Subtract start
688 INC CX ;AN000; Get the length of the line
689 CLD ;AN000; Scan forward
690 REPZ SCASB ;AN000; Repeat search until character found
691 JZ NAME_NOT_FOUND
;AN000; If all spaces, then it is an error
692 INC CX ;AN000; Increment character count
693 DEC DI ;AN000; Decrement pointer to character
694 ;***********************************************************************
695 ; Move the printer name to the names list
696 ;***********************************************************************
697 XCHG SI, DI ;AN000; Exchange the pointers again
698 MOV CX, END_CUR_LINE
;AN000; Get the address of the last char
699 SUB CX, SI ;AN000; Subtract start
700 INC CX ;AN000; Get the length of the line
701 .IF < CX A E_MAX_PRN_NAME_LEN
> ;AN000; Is the length of the line too long?
702 MOV CX, E_MAX_PRN_NAME_LEN
;AN000; Yes! Make the line length the maximum size
704 MOV DX, CX ;AN000; Save the line length for later use
705 .WHILE < NONZERO
CX > ;AN000; Do while there are more characters in the string
706 MOV AL, BYTE PTR ES:[SI] ;AN000; Get a character from the file data
707 .IF < AL NE
32 > ;AN000; Is this character a space?
708 MOV BX, DX ;AN000; Get the line length
709 SUB BX, CX ;AN000; Get the length of the line copied so far
711 .IF < MAX_NAME B
BX > ;AN000; Is this name longer than the longest so far?
712 MOV MAX_NAME
, BX ;AN000; Yes! This is the new maximum
715 MOV BYTE PTR ES:[DI], AL ;AN000; Put the character in the names table
716 INC SI ;AN000; Increment string pointers
718 DEC CX ;AN000; Decrement the number of characters left
720 ;***********************************************************************
721 ; Fill in the rest of the name area with spaces
722 ;***********************************************************************
723 MOV CX, E_MAX_PRN_NAME_LEN
;AN000; The maximum line length
724 ; DX contains the line length from last section
725 SUB CX, DX ;AN000; Calculate the space left in the line
726 MOV AL, 32 ;AN000; Character to store
727 REP STOSB ;AN000; Store the blank characters
728 ;***********************************************************************
729 ; Store the file pointer to this printer name in the name list
730 ;***********************************************************************
731 INC DI ;AN000; Point DI passed the printer type indicator
732 MOV SI, CURRENT_PARSE_LOC
;AN000; Get the start of the current line
733 SUB SI, NAMES_TABLE_SIZE
;AN000; Subtract offset of the start of the buffer
734 MOV CX, WORD PTR FILE_PTR_AT_START
;AN000; Get the low order word of the pointer
735 MOV DX, WORD PTR FILE_PTR_AT_START
[2] ;AN000; Get the high order word
736 ADD CX, SI ;AN000; Add the offset of the start of this line
737 ADC DX, 0 ;AN000; Add the high word
738 MOV WORD PTR ES:[DI], CX ;AN000; Store the low order word in the list
739 MOV WORD PTR ES:[DI+2], DX ;AN000; Store the high order word
740 INC N_PRN_NAMES
;AN000; Point to the next free area in the list
742 JMP EXIT_COPY
;AN000;
743 NAME_NOT_FOUND: ;AN000;
750 COPY_PRINTER_NAME ENDP
;AN000;
752 ;*******************************************************************************
753 ; Routine: READ_FROM_HERE - Read from the file into the buffer starting from
754 ; the file position pointed to by CURRENT_PARSE_LOC.
757 ; DI - Contains the current parsing location in the buffer.
760 ; FILE_PTR_AT_START - Updated for the new data read.
764 ;*******************************************************************************
765 READ_FROM_HERE PROC
NEAR;AN000;
767 ;**********************************************************************
768 ; Update the R/W pointer in the file.
769 ;**********************************************************************
770 MOV DX, WORD PTR FILE_PTR_AT_START
;AN000; Get the low order word of the pointer
771 MOV CX, WORD PTR FILE_PTR_AT_START
[2] ;AN000; Get the high order word of the pointer
772 ADD DX, DI ;AN000; Add the offset of where to start reading
773 ADC CX, 0 ;AN000; Take care of the carry condition
774 MOV WORD PTR FILE_PTR_AT_START
, DX ;AN000; Store the new starting position
775 MOV WORD PTR FILE_PTR_AT_START
[2], CX ;AN000; Store the high word of pointer
776 MOV INT_24_ERROR
, 0 ;AN000;
777 MOV AX, 4200H
;AN000; DOS Function for moving the file pointer
778 MOV BX, FILE_HANDLE
;AN000; Load the file handle
779 DOSCALL
;AN000; Move the file pointer
780 .IF < C
> ;AN000; Was an error encountered?
781 JMP RETURN_WITH_ERROR
;AN000; Yes! Exit the subroutine.
783 ;**********************************************************************
784 ; Read from the file into the data buffer
785 ;**********************************************************************
786 MOV CX, BUFFER_SIZE
;AN000; Number of bytes to read. As many as will fit.
787 MOV BX, FILE_HANDLE
;AN000; Load the DOS file handle for this file
788 MOV AH, 03FH ;AN000; The DOS function to perform
789 MOV DX, BUFFER_START
;AN000; The offset of the file data buffer
790 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
791 PUSH DS ;AN000; Save the current data segment
792 PUSH ES ;AN000; Push the file data buffer
793 POP DS ;AN000; DS now points to the file data buffer
794 DOSCALL
;AN000; Read from the file.
795 POP DS ;AN000; Restore the original data segment
796 ;**********************************************************************
797 ; See if the buffer was filled.
798 ;**********************************************************************
799 MOV AMOUNT_OF_DATA
, AX ;AN000; Save the amount of data that was read.
800 .IF < AX B BUFFER_SIZE
> ;AN000; Were less bytes read then we asked for?
801 OR READ_FLAG
, AT_EOF
;AN000; Yes! Indicate that we are at EOF
802 ; MOV DI, AX ; Move number of characters into an index pointer
803 ; MOV BYTE PTR ES:[DI+NAMES_TABLE_SIZE], 00 ; Place a terminator at the end
808 RETURN_WITH_ERROR: ;AN000;
812 READ_FROM_HERE ENDP
;AN000;
814 ;********************************************************************************
815 ; Routines for extracting all the information supplied in the profile for a
816 ; specific printer. Given the printer number, the location of its definition
817 ; is looked up in the names table. The file is them parsed for the information.
818 ;********************************************************************************
820 ;******************************************************************************
821 ; GET_PRINTER_INFO_ROUTINE - Get all the information contained in the printer
822 ; profile file for the specified printer.
825 ; AX - The number of the printer to return the information on. The number
826 ; is the index into the names table for this printer.
829 ; If CY = 0, there were no errors.
830 ; The following variable are updated with the information found in
839 ; If CY = 1, There were errors encountered.
840 ; BX = An error code indicating the type of error that occured.
842 ; = 3 There was an error reading the file
843 ; = 7 There was a error accessing the file
844 ; = 11 A printer definition has either a CDP or a CPP
845 ; Prefix, but BOTH were not present.
846 ; = 12 There was an error in the printer definition.
847 ; - A line was found with an invalid prefix
849 ; If the error was a result of a DOS function, then
850 ; on return, AX will contain the DOS error code.
855 ; The first printer name has an index of 1.
857 ;******************************************************************************
858 GET_PRINTER_INFO_ROUTINE PROC
FAR;AN000;
862 CALL HOOK_INT_24
;AN000;
866 PUSH ES ;AN000; Save the extra segment register
867 ;**********************************************************************
868 ; Calculate the address of the specifed printer
869 ;**********************************************************************
870 MOV I_PRINTER
, AX ;AN000; Save the printer index
871 DEC AX ;AN000; Make the first index a 0
872 MOV BX, SIZE_NAMES
;AN000; Number of bytes in each table entry
873 MUL BX ;AN000; Address is returned in AX
874 MOV DI, AX ;AN000; Move the address to an index register
875 ;**********************************************************************
876 ; Get the file location for this printer name
877 ;**********************************************************************
878 MOV AX, SEG_LOC
;AN000; Get the segment where the data is
879 MOV ES, AX ;AN000; Save in a segment register
880 MOV CX, WORD PTR ES:[DI+41] ;AN000; Get the low order word of the file location
881 MOV DX, WORD PTR ES:[DI+43] ;AN000; Get the high order word of the file location
882 ;**********************************************************************
883 ; Determine if the information is already in the buffer or do we have
884 ; to read more information from the printer profile.
885 ;**********************************************************************
886 .IF < DX B
<WORD PTR FILE_PTR_AT_START
+2>> ;AN000; Compare the high order words
887 JMP READ_MORE_INFORMATION
;AN000; Info in buffer is passed where we want.
889 .IF < DX EQ < WORD PTR FILE_PTR_AT_START
+2>> AND ;AN000; High words equal so
890 .IF < CX B
<WORD PTR FILE_PTR_AT_START
>> ;AN000; compare the low order words
891 JMP READ_MORE_INFORMATION
;AN000; Info in buffer is passed where we want.
894 MOV BX, WORD PTR FILE_PTR_AT_START
+2 ;AN000; File location at beginning of buffer
895 MOV SI, WORD PTR FILE_PTR_AT_START
;AN000; Low order word
896 ADD SI, AMOUNT_OF_DATA
;AN000; Get the file pointer of the end of the buffer
897 ADC BX, 0 ;AN000; Add in the high word
898 .IF < DX A
BX > ;AN000; If data we want is further in the file,
899 JMP READ_MORE_INFORMATION
;AN000; Read in more data
901 .IF < DX EQ BX > AND ;AN000; If the high words are equal do the
902 .IF < CX A
SI > ;AN000; comparison on the low order words
903 JMP READ_MORE_INFORMATION
;AN000; Still not there, so read more info
906 MOV AX, I_PRINTER
;AN000; Get the index of this printer name
907 .IF < AL EQ NUM_PRINTER_DEFS
> ;AN000; Is this the last one in the list?
908 .IF < BIT READ_FLAG
AND AT_EOF
> ;AN000; If it is, and all the data has been read, process it
909 JMP PARSE_HERE
;AN000;
911 JMP READ_MORE_INFORMATION
;AN000; Not EOF, so read in more data just for safety
914 MOV CX, WORD PTR ES:[DI+SIZE_NAMES
+41] ;AN000; Get the pointer to the NEXT printer name
915 MOV DX, WORD PTR ES:[DI+SIZE_NAMES
+43] ;AN000; Get the high order word
916 .IF < DX A
BX > ;AN000; See if the next printer name is in the buffer
917 JMP READ_MORE_INFORMATION
;AN000; If not, get more information
919 .IF < DX EQ BX > AND ;AN000; If the high order words are equal,
920 .IF < CX A
SI > ;AN000; Compare the low order. Is the name there?
921 JMP READ_MORE_INFORMATION
;AN000; If not, read more.
924 JMP PARSE_HERE
;AN000; The necessary info is there, so parse it.
925 ;**********************************************************************
926 ; The specified printer information is not currently in the buffer. It
927 ; is necessary to read it from the printer profile file.
928 ;**********************************************************************
929 READ_MORE_INFORMATION: ;AN000;
930 MOV CX, WORD PTR ES:[DI+43] ;AN000; Get the file pointer of this printer name
931 MOV DX, WORD PTR ES:[DI+41] ;AN000; Get the low order word of pointer
932 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
933 MOV AX, 4200H
;AN000; DOS Fn. for positioning file pointer
934 MOV BX, FILE_HANDLE
;AN000; Get the handle of the file
935 DOSCALL
;AN000; Position the pointer
936 .IF < C
> ;AN000; If CY = 1, there was an error
937 MOV BX, ERR_ACCESSING_FILE
;AN000; Return this error code
938 JMP ERROR_EXIT
;AN000; Jump to exit routine
940 MOV WORD PTR FILE_PTR_AT_START
, AX ;AN000; Set the new pointer at the beginning of the buffer
941 MOV WORD PTR FILE_PTR_AT_START
+2, DX ;AN000; Set the high order word
942 MOV AH, 3FH
;AN000; DOS Fn. for reading from a file
943 MOV DX, BUFFER_START
;AN000; Offset of the start of the data buffer
944 MOV BX, FILE_HANDLE
;AN000; Get the file handle
945 MOV CX, BUFFER_SIZE
;AN000; Read as many bytes as the buffer will hold
946 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
947 PUSH DS ;AN000; Save the current data segment
948 PUSH ES ;AN000; Push the segment of the data buffer
949 POP DS ;AN000; Load DS with the segment where to store the data
950 DOSCALL
;AN000; Read in the data
951 POP DS ;AN000; Restore the data segment
953 MOV BX, ERR_READING_FILE
;AN000;
954 JMP ERROR_EXIT
;AN000;
956 .IF < AX NE BUFFER_SIZE
> ;AN000; Were less bytes read then asked for?
957 OR READ_FLAG
, AT_EOF
;AN000; If so, then we are at the end of file
958 .ELSE ;AN000; Otherwise...
959 AND READ_FLAG
, RESET_EOF
;AN000; We are not at end of file
961 MOV AMOUNT_OF_DATA
, AX ;AN000; Save the amount of data actually read
962 ;**********************************************************************
963 ; The printer data is in the data buffer. Begin to parse the data.
964 ;**********************************************************************
966 MOV CDP_FOUND
, FALSE
;AN000;
967 MOV CPP_FOUND
, FALSE
;AN000;
968 PUSH DI ;AN000; Save the pointer into the names table
969 ;**********************************************************************
970 ; Load the printer profile fields with defaults.
971 ;**********************************************************************
972 COPY_STRING S_MODE_PARM
, 40, BLANK_STRING
;AC000;JW
973 COPY_STRING S_CP_DRIVER
, 22, BLANK_STRING
;AN000;
974 COPY_STRING S_CP_PREPARE
, 12, BLANK_STRING
;AN000;
975 COPY_STRING S_GRAPH_PARM
, 20, BLANK_STRING
;AN000;
976 POP DI ;AN000; Restore the pointer into the names table
977 ;**********************************************************************
978 ; Get the type of printer.
979 ;**********************************************************************
980 MOV AL, ES:[DI+40] ;AN000; Get the printer type - Parallel or Serial from the table
981 MOV N_PRINTER_TYPE
, AL ;AN000; Save in the appropriate variable
982 ;**********************************************************************
983 ; Get the offset of the start of this printer definition
984 ;**********************************************************************
985 MOV CX, ES:[DI+41] ;AN000; Get the low order word of the file pointer
986 MOV DX, ES:[DI+43] ;AN000; Get the high order word
987 SUB DX, WORD PTR FILE_PTR_AT_START
[2] ;AN000; Subtract the high order words
988 SBB CX, WORD PTR FILE_PTR_AT_START
;AN000; Subtract the low order words
989 ADD CX, BUFFER_START
;AN000; Get the offset of the start of the definition
990 MOV CURRENT_PARSE_LOC
, CX ;AN000; Save as the scan position
991 OR PARSE_FLAG
, FIRST_NAME
;AN000;
992 PARSE_NEXT_PARM: ;AN000;
993 MOV DI, CURRENT_PARSE_LOC
;AN000; Get the current scan position
994 CALL SCAN_FOR_EOLN
;AN000; Search for the end of this line
995 MOV START_NEXT_LINE
, DI ;AN000; Save the position of the start of the next line
996 MOV SI, CURRENT_PARSE_LOC
;AN000; The position in the buffer to scan
997 MOV NUM_STRINGS
, 6 ;AN000; Number of parameters to parse for
998 MOV DI, OFFSET PARMS
;AN000; Offset of the parameter blocks
999 MOV DX, 0 ;AN000; The parser wants DX = 0.
1000 MOV CX, 0 ;AN000; Tell the parser this is the first scan of this line
1001 PUSH DS ;AN000; Save the current data segment
1002 PUSH ES ;AN000; Save the file data segment
1003 MOV AX, DATA ;AN000; Get the current data segment
1004 MOV ES, AX ;AN000; This is the parser control blocks.
1005 MOV AX, SEG_LOC
;AN000; Where the data to parse is located
1007 CALL SYSPARSE
;AN000; Do the parsing
1008 POP ES ;AN000; Restore the file data segment
1009 POP DS ;AN000; Restore the data segment
1010 .IF < AX EQ 0FFFFH > ;AN000; Was the end of the line found?
1011 JMP UPDATE_PARSE_PTR
;AN000; If so, start the next one
1012 .ELSEIF
< NONZERO
AX > ;AN000; Was an error encountered parsing the line?
1013 MOV BX, ERR_PRN_DEFN
;AN000;
1014 JMP ERROR_EXIT
;AN000; If so, exit the subroutine
1016 MOV AL, MATCHED_TAG
;AN000; Get which string was matched
1017 .IF < AL EQ 1 > OR ;AN000; Was this a printer name and type?
1018 .IF < AL EQ 2 > ;AN000;
1019 .IF < BIT PARSE_FLAG
AND FIRST_NAME
> ;AN000; Is this the first name encountered?
1020 AND PARSE_FLAG
, RESET_FIRST_NAME
;AN000; Indicate that the a name has been found
1021 .ELSE ;AN000; Otherwise...
1022 JMP PARSING_DONE
;AN000; This is the second name. We are finished.
1024 .ELSEIF
< AL EQ 3 > ;AN000; AL = 3 ==> Mode parameters
1025 CALL HANDLE_MODE
;AN000; Process
1026 .ELSEIF
< AL EQ 4 > ;AN000; AL = 4 ==> Code page driver parameters
1027 MOV CDP_FOUND
, TRUE
;AN000;
1028 CALL HANDLE_CODE_DRIVER
;AN000; Process
1029 .ELSEIF
< AL EQ 5 > ;AN000; AL = 5 ==> Code page preparation parameters
1030 MOV CPP_FOUND
, TRUE
;AN000;
1031 CALL HANDLE_CODE_PREPARE
;AN000; Process
1032 .ELSEIF
< AL EQ 6 > ;AN000; AL = 6 ==> Graphics parameters
1033 CALL HANDLE_GRAPHICS
;AN000; Process
1035 ;**********************************************************************
1036 ; The current line has been parsed. Point to the next line.
1037 ;**********************************************************************
1038 UPDATE_PARSE_PTR: ;AN000;
1039 MOV AX, START_NEXT_LINE
;AN000; Get the address of the start of the next line
1040 MOV CURRENT_PARSE_LOC
, AX ;AN000; Save this as the start of the current line
1041 .IF < CURRENT_PARSE_LOC
EQ 0 > ;AN000; Is there any more data?
1042 JMP PARSING_DONE
;AN000; No. Exit the routine
1044 JMP PARSE_NEXT_PARM
;AN000; Start the parsing again
1045 ;**********************************************************************
1046 ; The subroutine is finished.
1047 ;**********************************************************************
1048 PARSING_DONE: ;AN000;
1049 MOV AL, CDP_FOUND
;AN000;
1050 XOR AL, CPP_FOUND
;AN000;
1052 MOV BX, ERR_CDP_CPP
;AN000;
1053 JMP ERROR_EXIT
;AN000;
1055 CLC ;AN000; Clear the carry - No errors
1056 JMP EXIT_INFO
;AN000; Exit the subroutine
1058 STC ;AN000; Set the carry - There were errors
1060 POP ES ;AN000; Restore the extra segment
1061 CALL RESTORE_INT_24
;AN000;
1064 GET_PRINTER_INFO_ROUTINE ENDP
;AN000;
1065 ;********************************************************************************
1066 ; HANDLE_MODE - Subroutine to process the mode parameter line in the printer
1070 ; SI - Points to the beginning of the line to process
1073 ; S_MODE_PARM - Filled with the information from the line. The line will be
1074 ; in a format for use as the parameters for the MODE command.
1076 ;********************************************************************************
1077 HANDLE_MODE PROC
NEAR;AN000;
1080 ;AD000;JW COPY_STRING S_MODE_PARM, 13, BLANK_MODE
1083 ;AD000;JW NEXT_MODE_SCAN: ; Scan for the next keyword.
1084 ;AD000;JW MOV DI, OFFSET MODE_PARMS ; Offset of the control blocks for parsing the mode parameters
1085 ;AD000;JW MOV CX, 0 ; Always tell the parser this is the first parse
1086 ;AD000;JW MOV DX, 0 ; The parse wants DX = 0
1087 ;AD000;JW PUSH ES ; Save the segment registers
1089 ;AD000;JW MOV AX, DATA ; Get the location of the data segment
1090 ;AD000;JW MOV ES, AX ; Load in the extra segment register - The segment of the control blocks
1091 ;AD000;JW MOV AX, SEG_LOC ; Get the location of the printer data
1092 ;AD000;JW MOV DS, AX ; Load into the data segment - The segment of the data to parse
1093 ;AD000;JW CALL SYSPARSE ; Parse the line.
1094 ;AD000;JW POP DS ; Restore the segment registers
1097 ;AD000;JW ; PUSHH <AX,BX,CX,DX,SI,DI>
1098 ;AD000;JW ; MOV W_VALUE, AX
1099 ;AD000;JW ; WORD_TO_CHAR W_VALUE, STRING_N
1100 ;AD000;JW ; PRINTN STRING_N
1102 ;AD000;JW ; POPP <DI,SI,DX,CX,BX,AX>
1104 ;AD000;JW .IF < NONZERO AX > ; If errors or the end of the line, end the routine
1105 ;AD000;JW JMP EXIT_MODE_SCAN
1107 ;AD000;JW MOV BX, DX ; Move result pointer into an index register
1108 ;AD000;JW .IF <<WORD PTR [BX+2]> EQ <OFFSET SYN_BAUD>> ; Was this the BAUD keyword?
1109 ;AD000;JW MOV AX, 5 ; Maximum number of character to copy
1110 ;AD000;JW MOV DI, OFFSET S_MODE_PARM+2 ; Where to put the baud parameters
1111 ;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_PARITY>> ; Was this the PARITY keyword?
1112 ;AD000;JW MOV AX, 1 ; Maximum number of character to copy
1113 ;AD000;JW MOV DI, OFFSET S_MODE_PARM+8 ; Where to put the parity parameters
1114 ;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_DATA>> ; Was this the DATA keyword?
1115 ;AD000;JW MOV AX, 1 ; Maximum number of character to copy
1116 ;AD000;JW MOV DI, OFFSET S_MODE_PARM+10 ; Where to put the data parameters
1117 ;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_STOP>> ; Was this the STOP keyword?
1118 ;AD000;JW MOV AX, 1 ; Maximum number of character to copy
1119 ;AD000;JW MOV DI, OFFSET S_MODE_PARM+12 ; Where to put the stop parameters
1120 ;AD000;JW .ELSEIF <<WORD PTR [BX+2]> EQ <OFFSET SYN_RETRY>> ; Was this the RETRY keyword?
1121 ;AD000;JW MOV AX, 1 ; Maximum number of character to copy
1122 ;AD000;JW MOV DI, OFFSET S_MODE_PARM+14 ; Where to put the retry parameters
1124 ;AD000;JW CALL COPY_RESULT ; Copy the string
1125 ;AD000;JW JMP NEXT_MODE_SCAN ; Scan for the next keyword
1126 ;AD000;JW EXIT_MODE_SCAN:
1127 ;AD000;JW CALL REMOVE_BLANKS ; Remove the blanks from the mode line
1130 MOV DI, OFFSET S_MODE_PARM
;AN000; Offset of the variable to load JW
1131 MOV CX, 40 ;AN000; Maximum width of the field JW
1132 CALL COPY_LINE
;AN000; Copy the information from the file data JW
1133 RET ;AN000; Return JW
1135 HANDLE_MODE ENDP
;AN000;
1136 ;AD000;JW ;********************************************************************************
1137 ;AD000;JW ; REMOVE_BLANKS: Remove the blanks from the S_MODE_PARM string. Any trailing
1138 ;AD000;JW ; commas are also removed.
1146 ;AD000;JW ; OPERATION:
1149 ;AD000;JW ;********************************************************************************
1150 ;AD000;JW REMOVE_BLANKS PROC NEAR
1152 ;AD000;JW MOV CX, WORD PTR S_MODE_PARM
1153 ;AD000;JW LEA SI, S_MODE_PARM
1155 ;AD000;JW ADD SI, CX
1156 ;AD000;JW MOV BX, CX
1157 ;AD000;JW .WHILE < CX AE 0 >
1158 ;AD000;JW .IF < <BYTE PTR [SI]> EQ <' '> > OR
1159 ;AD000;JW .IF < <BYTE PTR [SI]> EQ <','> >
1167 ;AD000;JW MOV WORD PTR S_MODE_PARM, BX
1169 ;AD000;JW MOV CX, BX
1170 ;AD000;JW LEA SI, S_MODE_PARM
1172 ;AD000;JW MOV DI, SI
1173 ;AD000;JW .WHILE < CX A 0 >
1174 ;AD000;JW .IF < <BYTE PTR [SI]> NE <' '>>
1175 ;AD000;JW .IF < SI NE DI >
1176 ;AD000;JW MOV AL, [SI]
1177 ;AD000;JW MOV [DI], AL
1186 ;AD000;JW MOV WORD PTR S_MODE_PARM, BX
1189 ;AD000;JW REMOVE_BLANKS ENDP
1190 ;********************************************************************************
1191 ; HANDLE_CODE_DRIVER - Subroutine to process the code page driver parameter
1192 ; line in the printer profile.
1195 ; SI - Points to the beginning of the line to process
1198 ; S_CP_DRIVER - Filled with the information from the line.
1200 ; OPERATION: The line from the file is copied to the S_CP_DRIVER variable.
1201 ; This variable is assumed to be a maximum of 22 characters wide.
1203 ;********************************************************************************
1204 HANDLE_CODE_DRIVER PROC
NEAR;AN000;
1206 MOV DI, OFFSET S_CP_DRIVER
;AN000; Offset of the variable to load
1207 MOV CX, 22 ;AN000; Maximum width of the field
1208 CALL COPY_LINE
;AN000; Copy the information from the file data
1211 HANDLE_CODE_DRIVER ENDP
;AN000;
1213 ;********************************************************************************
1214 ; HANDLE_CODE_PREPARE - Subroutine to process the code prepare parameter line
1215 ; in the printer profile.
1218 ; SI - Points to the beginning of the line to process
1221 ; S_CP_PREPARE - Filled with the information from the line.
1223 ; OPERATION: The line from the file is copied to the variable S_CP_PREPARE.
1224 ; The variable is assumed to be a maximum of 12 characters long.
1226 ;********************************************************************************
1227 HANDLE_CODE_PREPARE PROC
NEAR;AN000;
1229 MOV DI, OFFSET S_CP_PREPARE
;AN000; Offset of the variable to load
1230 MOV CX, 12 ;AN000; Maximum length of the variable
1231 CALL COPY_LINE
;AN000; Copy the information from the file data
1234 HANDLE_CODE_PREPARE ENDP
;AN000;
1236 ;********************************************************************************
1237 ; HANDLE_GRAPHICS - Subroutine to process the graphics parameter line in the
1241 ; SI - Points to the beginning of the line to process
1244 ; S_GRAPH_PARM - Filled with the information from the line.
1246 ; OPERATION: The line from the file is copied to the S_GRAPH_PARM variable.
1247 ; The variable is assumed to be a maximum of 20 characters long.
1249 ;********************************************************************************
1250 HANDLE_GRAPHICS PROC
NEAR;AN000;
1252 MOV DI, OFFSET S_GRAPH_PARM
;AN000; Offset of the variable to load
1253 MOV CX, 20 ;AN000; Maximum width of the variable
1254 CALL COPY_LINE
;AN000; Load the variable with the data from the file
1257 HANDLE_GRAPHICS ENDP
;AN000;
1259 ;********************************************************************************
1260 ; COPY_RESULT: Copy the string pointed to in the result block to the specified
1264 ; AX - The maximum length of the string to copy.
1265 ; DX - The offset in DS of the result block.
1266 ; DI - The offset of where the string is to be stored
1270 ; CX - The length of the string copied.
1272 ; Operation: The string is copied from the result block to the area pointed to
1273 ; by DS:DI. The string is copied until a null character is encountered.
1275 ;********************************************************************************
1276 COPY_RESULT PROC
NEAR;AN000;
1280 MOV BX, DX ;AN000; Put address into an index register
1281 LES SI, [BX+4] ;AN000; Get the address of the string to copy
1282 MOV CX, 0 ;AN000; Zero the string length indicator
1283 .WHILE < CX B
AX > ;AN000; Copy up to the number of character in AX
1284 MOV DL, BYTE PTR ES:[SI] ;AN000; Get the first byte
1285 .LEAVE < ZERO
DL > ;AN000; Terminate loop if this is a null char
1286 MOV BYTE PTR [DI], DL ;AN000; Save character in the destination string
1287 INC SI ;AN000; Increment source pointer
1288 INC DI ;AN000; Increment destination pointer
1289 INC CX ;AN000; Increment number of characters moved
1295 COPY_RESULT ENDP
;AN000;
1297 ;********************************************************************************
1298 ; COPY_LINE - Copy a line from the printer profile data to a specified area.
1301 ; DI - Points to the location the data is to be copied to.
1302 ; CX - Contains the maximum number of bytes copied.
1307 ; OPERATION: The current line being parsed is copied to the specified area.
1308 ; The length of the line is calculated with the use of the variable
1309 ; CUR_END_LINE. If the lenght of the line is longer then the number passed
1310 ; in CX, then only a portion of the line will be copied.
1312 ;********************************************************************************
1313 COPY_LINE PROC
NEAR;AN000;
1316 PUSH SI ;AN000; Save the index regiter used by the parser
1317 PUSH DI ;AN000; Save the pointer to the variable to load
1318 ADD DI, 2 ;AN000; Push pointer passed the lenght word
1319 MOV AX, END_CUR_LINE
;AN000; Get the pointer to the end of this line
1320 SUB AX, SI ;AN000; Get the distance to the end
1321 INC AX ;AN000; Add to get the length of the line
1322 .IF < AX B
CX > ;AN000; If length is greater then the maximum allowed,
1323 MOV CX, AX ;AN000; use the shorter length
1325 PUSH CX ;AN000; Save the length used.
1326 PUSH ES ;AN000; Swap the values in the segment registers
1330 CLD ;AN000; Move in the forward direction
1331 REP MOVSB ;AN000; Move the data
1332 POP CX ;AN000; Restore the line length
1333 POP DI ;AN000; Restore the pointer to the variable
1334 MOV WORD PTR ES:[DI], CX ;AN000; Save the length of the string
1335 POP SI ;AN000; Restore the parser pointer
1336 PUSH DS ;AN000; Swap the segment registers again
1342 COPY_LINE ENDP
;AN000;
1344 ;********************************************************************************
1345 ; Routine to deallocate the memory used for the storage of the printer profile
1346 ; data and the table of printer names. These routines also close the profile
1348 ;********************************************************************************
1350 ;********************************************************************************
1351 ; RELEASE_PRINTER_INFO_ROUTINE - Close the printer profile file and free the
1358 ; If CY = 0, There were no error encountered.
1359 ; If CY = 1, There was an error.
1360 ; AX = The DOS error code for the deallocate memory function
1362 ; OPERATION: Closes the printer file and deallocated the memory.
1364 ;********************************************************************************
1365 RELEASE_PRINTER_INFO_ROUTINE PROC
FAR;AN000;
1370 CALL HOOK_INT_24
;AN000;
1374 ;**********************************************************************
1375 ; Close the printer definition file
1376 ;**********************************************************************
1377 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
1378 MOV BX, FILE_HANDLE
;AN000; File handle of the profile file
1379 MOV AH, 3EH
;AN000; DOS Fn. for closing a file
1380 DOSCALL
;AN000; Close the file
1381 ;**********************************************************************
1382 ; Deallocate the memory used for the data buffer
1383 ;**********************************************************************
1384 MOV AX, SEG_LOC
;AN000; Location of the data buffer
1386 MOV AH, 49H
;AN000; DOS Fn. for freeing allocated memory
1387 DOSCALL
;AN000; Free the memory
1389 CALL RESTORE_INT_24
;AN000;
1392 RELEASE_PRINTER_INFO_ROUTINE ENDP
;AN000;
1394 ;*******************************************************************************
1395 ; Routines for changing the SELECT command line in the AUTOEXEC.BAT.
1396 ;*******************************************************************************
1398 ;********************************************************************************
1399 ; CHANGE_AUTOEXEC_ROUTINE: Search a file for a line beginning with SELECT, and
1400 ; change its parameters.
1403 ; DI - The offset of an ASCII-N string containing the file to search.
1404 ; SI - The offset of an ASCII-N string containing the data to append as
1412 ;********************************************************************************
1413 CHANGE_AUTOEXEC_ROUTINE PROC
FAR;AN000;
1417 TEST SEL_FLG
,INSTALLRW
;AN000; Is the install
1418 ;AN000; diskette read/write
1419 ;AN000; (has DISKCOPY occurred?)
1421 CLC ;AN000; no error
1422 JMP AUTO_EXIT_RO
;AN000; If not, exit
1425 CALL HOOK_INT_24
;AN000;
1427 MOV APPEND_POINTER
, SI ;AN000; Save the address of the string to be appended
1428 MOV FILENAME
, DI ;AN000; Save the address of the string containing the filename
1429 ;**********************************************************************
1430 ; Allocate the memory needed for reading the autoexec file. A maximum
1431 ; of 64K is allocated for use.
1432 ;**********************************************************************
1433 CALL ALLOCATE_MEMORY
;AN000; Allocate the memory needed
1434 .IF < C
> ;AN000; Was there an error?
1435 JMP AUTO_EXIT_ERROR
;AN000; Yes! Exit the subroutine
1437 MOV BUFFER_START
, 0 ;AN000; Save the offset of the start of the buffer
1438 COPY_WORD BUFFER_SIZE
, SEGMENT_SIZE
;AN000; Save the size of the buffer
1439 ;**********************************************************************
1440 ; Open the input file
1441 ;**********************************************************************
1442 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
1443 ; DI contains the address of the filename
1444 CALL POS_ZERO
;AN000; Make the string into an ASCII-Z string
1445 MOV DX, DI ;AN000; Load string offset
1446 ADD DX, 2 ;AN000; Adjust for length word
1447 MOV AX, 3D02H
;AN000; DOS Fn. for opening a file for reading and writing
1448 DOSCALL
;AN000; Open the file
1449 .IF < C
> ;AN000; Was there an error?
1450 JMP AUTO_EXIT_ERROR
;AN000; Exit the subroutine
1452 MOV FILE_HANDLE
, AX ;AN000; Save the file handle
1453 ;**********************************************************************
1454 ; Set the file pointer
1455 ;**********************************************************************
1456 MOV WORD PTR FILE_PTR_AT_START
[0], 0 ;AN000; Set the file pointer of the data in the buffer
1457 MOV WORD PTR FILE_PTR_AT_START
[2], 0 ;AN000; Set the high word
1458 MOV CURRENT_PARSE_LOC
, 0 ;AN000; Set the current parsing location
1459 AND READ_FLAG
, RESET_EOF
;AN000; Indicate that the end of file has not been reached
1460 ;**********************************************************************
1461 ; Read data into the buffer
1462 ;**********************************************************************
1463 MOV DI, CURRENT_PARSE_LOC
;AN000; Get the current parsing location
1464 CALL READ_FROM_HERE
;AN000; Read data starting from this position
1465 .IF < C
> ;AN000; Was there an error?
1466 JMP AUTO_EXIT_ERROR
;AN000; Yes! Exit the subroutine
1468 ;**********************************************************************
1469 ; Setup the control blocks for the parser
1470 ;**********************************************************************
1471 MOV PAR_EXTEN
, OFFSET SELECT_PARMX
;AN000; Address of the parameters extension block
1472 ;**********************************************************************
1473 ; Parse the file for 'SELECT'
1474 ;**********************************************************************
1475 PARSE_FOR_SELECT: ;AN000; Here to parse the line
1476 CALL SEARCH_LINE
;AN000; Parse the line.
1477 .IF < C
> ;AN000; Was there an error?
1478 JMP AUTO_EXIT_ERROR
;AN000; Yes! Exit the subroutine
1480 .IF < AX EQ 0 > ;AN000; Did the parser file 'SELECT'?
1481 MOV CURRENT_PARSE_LOC
, SI ;AN000; Yes! Save the position after select as parse location
1482 MOV DX, WORD PTR FILE_PTR_AT_START
[0];AN000;
1483 MOV CX, WORD PTR FILE_PTR_AT_START
[2];AN000;
1484 ADD DX, CURRENT_PARSE_LOC
;AN000;
1486 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
1487 MOV BX, FILE_HANDLE
;AN000;
1488 MOV AX, 4200H
;AN000;
1490 .IF < C
> ;AN000; Was there an error writing the data?
1491 JMP AUTO_EXIT_ERROR
;AN000; Yes! Exit the subroutine
1493 ;*****************************************************************
1494 ; Write the select parameters to the file
1495 ;*****************************************************************
1496 MOV SI, APPEND_POINTER
;AN000; Address of the string to add to the select line
1497 MOV CX, [SI] ;AN000; Size of the string
1498 MOV DX, SI ;AN000; Get the address again
1499 ADD DX, 2 ;AN000; Adjust pointer past length word
1500 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
1501 MOV BX, FILE_HANDLE
;AN000; Get the handle for this file
1502 MOV AH, 40H
;AN000; DOS Fn. number for writing data
1503 DOSCALL
;AN000; Write the data
1504 ;*****************************************************************
1505 ; Write a carrage return and a line feed to the file
1506 ;*****************************************************************
1507 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
1508 MOV DX, OFFSET W_CR_LF
;AN000; Address of string to write
1509 MOV CX, E_SIZE_CR_LF
;AN000; Size of the string
1510 MOV BX, FILE_HANDLE
;AN000; Get the file handle
1511 MOV AH, 40H
;AN000; DOS Fn. for writing data
1512 DOSCALL
;AN000; Write the data
1513 ;*****************************************************************
1514 ; Truncate the file at the current file position
1515 ;*****************************************************************
1516 MOV INT_24_ERROR
, 0 ;AN000; Indicate that no critical errors have occured yet
1518 MOV BX, FILE_HANDLE
;AN000;
1521 ;*****************************************************************
1523 ;*****************************************************************
1524 CALL RELEASE_PRINTER_INFO_ROUTINE
;AN000; Close the original autoexec file
1526 ;*****************************************************************
1527 ; Parse the next line.
1528 ;*****************************************************************
1529 MOV DI, START_NEXT_LINE
;AN000; Get the address of the next line
1530 MOV CURRENT_PARSE_LOC
, DI ;AN000; Save this as the current parse location
1531 .IF < CURRENT_PARSE_LOC
EQ 0 > ;AN000; If this is zero, then there is no more data
1532 JMP AUTO_EXIT_CLEAR
;AN000; Exit the subroutine - No errors
1534 JMP PARSE_FOR_SELECT
;AN000; Parse the next line
1536 JMP AUTO_EXIT_CLEAR
;AN000; Exit the subroutine - No errors
1538 AUTO_EXIT_ERROR: ;AN000; Here if there was an error
1539 CALL RELEASE_PRINTER_INFO_ROUTINE
;AN000; Close the original file
1540 STC ;AN000; Indicate that there was an error
1541 JMP AUTO_EXIT
;AN000; Exit the subroutine
1543 AUTO_EXIT_CLEAR: ;AN000; Exit here if NO errors.
1544 CLC ;AN000; Indicate there were no errors
1545 AUTO_EXIT: ;AN000; Here to exit
1546 CALL DEALLOCATE_MEMORY
1547 POP ES ;AN000; Restore the extra segment
1548 CALL RESTORE_INT_24
;AN000;
1549 AUTO_EXIT_RO: ;AN000;
1552 CHANGE_AUTOEXEC_ROUTINE ENDP
;AN000;
1554 CODE_FAR ENDS
;AN000;