PAGE ,132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; FILENAME: CPS Printer Device Driver INIT module (CPSPInn) ;; MODULE NAME: ;; TYPE: Assemble file (non-resident code) ;; LINK PROCEDURE: Link CPSPMnn+CPSFONT+CPSPInn into .EXE format. CPSPM01 ;; must be first. CPSPInn must be last. Everything ;; before CPSPInn will be resident. ;; INCLUDE FILES: ;; CPSPEQU.INC ;; ;; LAYOUT : This file is divided into two main section : ;; ++++++++++++++++++++++++ ;; ++ DEVICE Parser ++ ;; ++++++++++++++++++++++++ ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Command ++ ;; ++++++++++++++++++++++++ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; INCLUDE CPSPEQU.INC ;; ;; PUBLIC INIT ;; PUBLIC CODE_END ;; for MAP listing only PUBLIC RESIDENT_END ;; PUBLIC STACK_ALLOCATED ;; ;; ;; EXTRN PRINTER_DESC_NUM:WORD ;; EXTRN PRINTER_DESC_TBL:WORD ;; EXTRN INIT_CHK:WORD,TABLE:WORD ;; EXTRN HARD_SL1:BYTE,RAM_SL1:BYTE ;; EXTRN HARD_SL2:BYTE,RAM_SL2:BYTE ;; EXTRN HARD_SL3:BYTE,RAM_SL3:BYTE ;; EXTRN HARD_SL4:BYTE,RAM_SL4:BYTE ;; EXTRN RESERVED1:WORD,RESERVED2:WORD ;; ;; EXTRN MSG_NO_INIT_P:BYTE ;; EXTRN MSG_NO_INIT:BYTE ;; EXTRN MSG_BAD_SYNTAX:BYTE ;; EXTRN MSG_INSUFF_MEM:BYTE ;; ;; ;; CSEG SEGMENT PARA PUBLIC 'CODE' ;; ASSUME CS:CSEG ;; ;; ;; CODE_END EQU $ ;; end of resident code ;; DW 0 ;; -- there are 16 bytes kept, ;; including this word ;; RESIDENT_END DW 0FFFH ;; end of extended resident area STACK_ALLOCATED DW -1 ;; end of extended resident area ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; End of resident code ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Incorporating Device Command Parser : ;; ;; -- extracted from PARSE4E.ASM, size 49582 bytes ;; ;; (some modifications have to be made in the section right after the parser's ;; document and before the GET_PARMS_A, one of them is :) ;; ;; -- move the TABLE to the printer device driver's main module ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ++++++++++++++++++++++++ ;; ++ DEVICE Parser ++ ;; ++++++++++++++++++++++++ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; PARSER's code -- non resident ;; ;; -- set ES:[DI] pointing to the Request Header before calling PARSER ;; ;; to be called as PARSER with ES:[DI] defined as Request Header ;; If there is any syntax error in the DEVICE command line, the ;; Parser return a 0 in the first word (NUMBER)of the first table. ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ; ; Description: A command parser for DEVICE command in the CONFIG.SYS file. ; ------------ ; ; Procedures contained in the file: ; --------------------------------- ; PARSER: Main routine for command processing. ; GET_CHAR: Gets a character from command line. ; IS_ALPH: Checks if character is an alpha character. ; IS_DIGIT: Checks if character is a digit. ; IS_DELIM: Checks if character is a DOS delimiter. ; DEVICE_PARSE: Pulls device name from command line and ; inserts in table. ; ID_PARSE: Pulls id name from command line and insers in table ; HWCP_PARMS: Extract HWCP number, converts it to binary and ; inserts it in table. ; HWCP_PARSE: Extracts HWCP number if only one number is given. ; MUL_HWCP: Extracts multiple HWCP's numbers, if they are given ; in a list. ; DESG_PARMS: Extracts designate number, converts it to binary ; and inserts it in table. ; DESG_FONT: Extracts the designate and the font if both were ; given in command line. ; DESG_PARSE: Pulls designate number if it is the only one given. ; GET_NUMBER: Converts a number to binary. ; OFFSET_TABLE: Updates the counter in table #1. ; FIND_RIGHT_BR: Looks for a right bracket. ; ; ; Change history: ; --------------- ; ; ;LOGIC: ;------ ; Establish addressability to parameters. ; Skip until end of path and file name -first delimiter ; ; Loop: ; Isolate the first non-delimiter or non delimeter characters. ; If End_of_Line_Delimiter then ; return an error_code ; Else ; If first non-delimiter is ALPHA then ; (assume a device name) ; Extracts device name ; Update offset counter ; ; Isolate the first non-delimiter characters after id name. ; If End_of_Line_Delimiter then ; return an error_code ; Else ; If first non-delimiter is ALPHA-NUMARIC or ; If character is '(' then ; (assume an id name) ; Extracts id name ; Update offset counter ; ; Pull out HWCP ; If error flag is set then exit ; Else if end of line flag is set then exit ; ; Pull out DESG parms ; If error_flag is set then exit. ; Else if end of line flag is set then exit ; Else if Number of devices is four then Exit ; Else Loop ; ; ;Subroutines Logic: ;------------------ ; ; GET_CHAR: ; --------- ; Load character in AL ; If character less than 20h then ; turn Z-flag on ; ; IS_ALPHA: ; --------- ; Save character ; 'Convert character to upper case' ; If character >=A and <=Z then ; turn Z-flag on ; exit ; Else ; Restore character ; exit. ; ; IS_DIGIT: ; --------- If Character >=0 and <=9 then ; turn Z-flag on ; ; IS_DELIMITER: ; ------------- ; If character a dos delimiter (' ','=',',',';',TAB) ; then turn Z-flag on ; ; DEVICE_PARSE: ; ------------- ; Set device name length counter. ; Loop ; If a dos delimiter then ; add spaces to name (if require) ; Else if char is ALPHA-NUM then ; save in table ; If name >8 character thne ; error; exit ; Else ; error; exit ; ; ID_PARSE: ; --------- Set id name length counter. ; Loop ; If a dos delimiter then ; add spaces to name (if require) ; Else if char is ALPHA-NUM then ; save in table ; If name >8 character then ; error; exit ; Else if char is ')' or '(' then ; set flags ; Else ; error; exit ; ; HWCP_PARMS: ; ----------- ; Loop: Set flags off ; If char is a DIGIT then ; convert number to binary ; update table ; Else if char is ',' then ; no HWCP was given ; exit ; Else if char is '(' then ; assume multiple HWCP ; Else if char is ')' then ; end of parms, exit ; Else if not a delimiter then ; error, exit set carry flag set carry flag ; Loop ; ; HWCP_PARSE: ; ----------- Increment counter ; Get number and convert to binary ; Update the table ; Set table_5 pointer ; ; MUL_HWCP: ; --------- ; Loop: If char is ')' then ; end of list, exit ; If char is a DIGIT ; Get number and convert to binary ; Update table. ; If char is not a delimiter then ; error, exit set carry flag ; Loop ; ; DESG_PARMS: ; ----------- ; Loop: If char is a DIGIT then ; Get number and convert to binary ; Update table. ; If char is a ')' then ; end of parms, exit ; If char is a '(' then ; assume given desg. and font ; If char is a ',' then ; no desg ginven ; scane for ')' ; If char is not a delimiter then ; error, exit set carry flag ; Loop ; ; DESG_FONT: ; ---------- ; Loop: If char is a ',' then ; no desg number was given ; update table ; If char is a ')' then ; end of desg-font pair, exit ; If char is a DIGIT then ; Get number and convert to binary ; Update table ; If char not a delimiter then ; error, exit set carry flag ; Loop ; ; DESG_PARSE: ; ----------- Get number and conver to binary ; Update table ; ; GET_NUMBER: ; ----------- Get ASCII number from parms ; conver to binary ; add to total ; ; OFFSET_TABLE: ; ------------- ; Increment the number of parms ; ; FIND_RIGHT_BR: ; -------------- ; Loop: If char is ')' then ; found bracket exit ; If char is not ' ' then ; error, exit set carry flag ; Loop ; END ;------------------------------------------------------ ; ; The following is the table structure of the parser. All fields are ; two bytes field (accept for the device and id name) ; ; TABLE HEADER : ; ÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ N = Number of devices. ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ Device # 1 offset ÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄ>ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ; ³ Device # 2 offset ³ ³ Table_1 (a) ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ; ³ Device # 3 offset ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ Device # 4 offset ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; ; N = 1,2,3 or 4. A two bytes number indicating the number of device specified. ; DEVICE # N OFFSET : a two bytes offset address to table_1. (ie. Device #1 offset ; is a pointer to table_1 (a). Device #2 offset is a pointer to table_1 ; (b)...etc.). If an error was detected in the command N is set to zero. ; ; ; ; TABLE_1 : ; ÍÍÍÍÍÍÍÍÍ ; ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ N = Number of Offsets. ³ ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÚÄÄÄÄÄij Table_2 (a) ³ ; ³ Device Name offset ÄÅÄÄÄÄÙ ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ³ Device Id offset ÄÅÄÄÄÄÄÄ¿ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ Device HWCP offset ÄÅÄÄÄÄ¿ ³ ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ÀÄÄÄij Table_3 (a) ³ ; ³ Device Desg offset ÄÅÄÄ¿ ³ ³ ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ³ "Reserved" ³ ³ ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ³ ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ ³ ³ ³ ; ³ ÀÄÄÄÄÄij Table_4 (a) ³ ; ³ ³ ³ ; ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ³ ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ ³ ³ ; ÀÄÄÄÄÄÄÄij Table_5 (a) ³ ; ³ ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; ; N=Length of table_1, or the number of offsets contained in table_1. ; The offsets are pointers (two bytes) to the parameters value of the device. ; "Reserved" : a two byte memory reserved for future use of the "PARMS" option. ; ; ; TABLE_2 : ; ÍÍÍÍÍÍÍÍÍ ; ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ N = Length of devices name ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ Device name ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; N = Length of device name. Device length is always 8 byte long. ; Device Name : the name of the device (eg. LPT1, CON, PRN). The name ; is paded with spaces to make up the rest of the 8 characters. ; ; ; ; TABLE_3 : ; ÍÍÍÍÍÍÍÍÍ ; ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ N = Length of Id name. ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ Id Name ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; N = Length of id name. Id name length is always 8 byte long. ; Id Name : the name of the id (eg. EGA, VGA, 3812). The name ; is paded with spaces to make up the rest of the 8 character. ; ; ; ; TABLE_4 : ; ÍÍÍÍÍÍÍÍÍ ; ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ N = Length of table. ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ HWCP # 1 ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ HWCP # 2 ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ . ³ ; ³ . ³ ; ³ . ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ HWCP # 10 ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; ; N = Length of table in words. Or the number of HWCP's. ; HWCP # N : a hardware code page number converted to binary. The maximum ; number of pages allowed is 10. ; ; ; ; TABLE_5 : ; ÍÍÍÍÍÍÍÍÍ ; ; ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ ; ³ N = Length of table. ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ Designate ³ ; ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ ; ³ Font ³ ; ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ ; ; N = Lenght of table. 0 - nothing was specified ; 1 - Only a designate was specified. ; 2 - Designate and font were given. If the Desg field ; was left empty in the DEVICE command then the ; Designate field is filled with 0FFFFH. ; Designate, Font : Are the Desg. and Font binary numbers. ; ;------------------------------------------------------ ; ;RESERVED MEMORY: TABLE_1 DW ? ; Pointer at offsets. TABLE_2 DW ? ; Pointer at device name. TABLE_3 DW ? ; Pointer at id name. TABLE_4 DW ? ; Pointer at hwcp. TABLE_5 DW ? ; Pointer at desg and font. ;TABLE DB 290 DUP (?) ; Table of parsed parms. Max 4 devices. DEVNUM DW ? ; Counter to number of devices. RIGHT_FLAG DB ? ; Flag to indicate a left bracket. DEV_ERR_FLG DB ? ; Device name error flag. ID_ERR_FLG DB ? ; Id name error flag. ERROR_FLAG DB ? ; Error flag_terminate program if set to 1. COMMA_FLAG DB ? ; Indicate the number of commas incounterd. HWCP_FLAG DB ? ; Flag for multiple hwcps. DESG_FLAG DB ? ; Flag indicates desg. and font. ;Main part of program-links different sumbroutines together PARSER PROC PUSH AX ; ;;;;;;;;;;;;;;;;;; PUSH BX ; ; PUSH CX ; ; SAVE PUSH DX ; ; ALL PUSH DS ; ; REGISTERS. PUSH ES ; ; PUSH DI ; ; PUSH SI ; ;;;;;;;;;;;;;;;;;; LES SI,RH.RH0_BPBA ; Point at all after DEVICE= ; in the CONFIG.SYS file. ;Skip to end of file name, to the first DOS delimiter. MOV DEVNUM,02H ; Number of devices counter. GET_PARMS_A: CALL GET_CHAR ; Get command character in AL . JZ EXIT_B ; No parms found. CALL IS_DELIM ; If not a delimiter then. JNE GET_PARMS_A ; Check next character. MOV DI,OFFSET TABLE ; Get the table address. ADD DI,02H ; Point at devices offsets. MOV BX,DI ; ADD BX,08H ; Point BX at parms offsets. TAB2: CALL UPDATE_TABLE ; Update table pointers value. CLR_DELIM: CALL GET_CHAR ; Get character into AL. JZ EXIT_B ; No parms found. CALL IS_ALPHA ; If alpha then assume. JZ DEVICE ; A device name. CALL IS_DELIM ; Is it a delimiter JNE EXIT_A ; If not then error. JMP CLR_DELIM ; Get next character. DEVICE: MOV DEV_ERR_FLG,00H ; Set device error flag off; CALL DEVICE_PARSE ; Call routine to parse device name. CMP DEV_ERR_FLG,01H ; If error flag is JZ EXIT_A ; set then exit. CALL OFFSET_TABLE ; Update table. ID_PARMS: CALL GET_CHAR ; Load a character in AL. JZ EXIT_A ; Exit if end of line (error). CMP AL,'(' ; If AL is a '(' then JE ID ; Parse ID name. CALL IS_ALPHA ; If an Alpha JE ID ; Then parse ID name. CALL IS_DIGIT ; If a digit JE ID ; Then parse ID name. CALL IS_DELIM ; If not a delimiter JNE EXIT_A ; Then error, exit JMP ID_PARMS ; Get another number EXIT_B: CMP DEVNUM,02H ; If device number above 2 then JA EXIT_C ; Exit parse. JMP EXIT_A ; Else error, exit ID: MOV ID_ERR_FLG,00H ; Set id error flag off. CALL ID_PARSE ; Parse ID name. CMP ID_ERR_FLG,01H ; Was error flag set, then JE EXIT_A ; Print error message. CALL OFFSET_TABLE ; Update table of offsets. CALL HWCP_PARMS ; Get code page number CMP ERROR_FLAG,01H ; If error, then JE EXIT_A ; Print error message and exit CMP ERROR_FLAG,02H ; If end of string JE EXIT_H ; Then exit. CALL DESG_PARMS ; Get designate number CMP ERROR_FLAG,01H ; If error, then JE EXIT_A ; Print error message and exit JMP EXIT_H ; Then exit. EXIT_A: MOV DI,OFFSET TABLE ; Load table offset MOV DS:WORD PTR [DI],00H ; Set error to on. STC ; Set carry flag JMP EXIT_P ; Exit parse. EXIT_H: MOV DI,OFFSET TABLE ; Load table offset. ADD DS:WORD PTR [DI],01H ; Increment number of devices. CMP DEVNUM,08H ; If 4 devices loaded JE EXIT_C ; Then exit parse. ADD DEVNUM,02H ; Increment the number of devices ADD DI,DEVNUM ; Point at next devices offset. MOV BX,TABLE_5 ; BX point at ADD BX,06H ; end of previous table. JMP TAB2 ; Get next device. EXIT_C: CLC EXIT_P: POP SI ; ;;;;;;;;;;;;;;;;;; POP DI ; ; POP ES ; ; RESTORE POP DS ; ; ALL POP DX ; ; REGISTERS. POP CX ; ; POP BX ; ; POP AX ; ;;;;;;;;;;;;;;;;;; RET PARSER ENDP ;******************************************************** ;** GET_CHAR : a routine to get next character pointed ** ;** to by ES:SI into AL. ** ;******************************************************** GET_CHAR PROC MOV AL,ES:BYTE PTR [SI] ; Load character pointed to CMP AL,09H ; by ES:[SI] in AL. JE ZOFF ; If tab then O.K CMP AL,20H ; Turn Z-flag on JL TURN_Z_ON ; if character ZOFF: INC SI ; is below JMP GET_CHAR_X ; 20h. ; ( End of line TURN_Z_ON: CMP AL,AL ; delimiters ). GET_CHAR_X: RET GET_CHAR ENDP ;******************************************************** ;** IS_ALPHA : a routine to check the character in ** ;** AL if it is an alpha character (a...z,A...Z). ** ;** If character is lower case, convert to upper case. ** ;******************************************************** IS_ALPHA PROC PUSH AX ; Save value of AL AND AL,0DFH ; Convert to upper case CMP AL,'A' ; If <'A', then JB IS_ALPHA_X ; NZ-flag is set, exit CMP AL,'Z' ; If >'Z', then JA IS_ALPHA_X ; NZ-flag is set, exit CMP AL,AL ; Force Z-flag POP DX ; Discard lower case. JMP IA_X ; Exit. IS_ALPHA_X: POP AX ; Restore value of AL IA_X: RET IS_ALPHA ENDP ;******************************************************** ;** IS_DIGIT : a routine to check if the character in ** ;** AL register is a digit (i.e. 1..9). ** ;******************************************************** IS_DIGIT PROC CMP AL,'0' ; If < '0' then JB IS_NUM_X ; NZ-flag is set, exit CMP AL,'9' ; If > '9' then JA IS_NUM_X ; NZ-flag is set, exit CMP AL,AL ; Set Z-flag to indecate digit IS_NUM_X: RET IS_DIGIT ENDP ;******************************************************** ;** IS_DELIM : This routine check if the character in ** ;** AL is a delimiter. ('+',' ',';',',','=',tab) ** ;******************************************************** IS_DELIM PROC CMP AL,' ' ; Test for space. JE IS_DELIM_X ; Z-flag is set, exit CMP AL,',' ; Test for comma. JE IS_DELIM_X ; Z-flag is set, exit CMP AL,';' ; Test for semicolon. JE IS_DELIM_X ; Z-flag is set, exit CMP AL,'=' ; Test for equal sign. JE IS_DELIM_X ; Z-flag is set, exit CMP AL,09h ; Test for TAB. IS_DELIM_X: RET ; Exit IS_DELIM ENDP ;******************************************************** ;** DEVICE_PARSE : Parse the device driver name and ** ;** store in table. Update offset. ** ;******************************************************** DEVICE_PARSE PROC MOV DI,TABLE_2 MOV DS:WORD PTR [DI],0008H ; Save dev name size. ADD DI,02H ; Increment DI. MOV CX,9 ; Set counter. NEXT_C: CALL IS_ALPHA ; if Check then. JZ SAVE_C ; Save it. CALL IS_DIGIT ; if Digit then. JZ SAVE_C ; Save it. CMP AL,'-' ; If '-' then. JZ SAVE_C ; Save it. CALL IS_DELIM ; If a delimiter then. JZ ADD_SPACE1 ; Pad with spaces. CMP AL,':' ; If a colon JE ADD_SPACE1 ; then end device parse JMP ERR_DEV_PAR ; Else an error. SAVE_C: DEC CX ; Decrement counter. CMP CX,0 ; If counter zero then. JE ERR_DEV_PAR ; Error. MOV DS:BYTE PTR [DI],AL ; Save char in table. INC DI ; Increment pointer. CALL GET_CHAR ; Get another char. JZ ERR_DEV_PAR JMP NEXT_C ; Check char. ERR_DEV_PAR: MOV DEV_ERR_FLG,01H ; Set error flag. JMP DEV_PAR_X ; Exit. ADD_SPACE1: DEC CX ; Check counter. CMP CX,1 JL DEV_PAR_X ; Exit if already 8. LL1: MOV DS:BYTE PTR [DI],' ' ; Pad name with spaces. INC DI ; Increment pointer. LOOP LL1 ; Loop again. DEV_PAR_X: RET DEVICE_PARSE ENDP ;******************************************************** ;** ID_PARSE : Parse the id driver name and ** ;** store in table. Update offset. ** ;******************************************************** ID_PARSE PROC MOV DI,TABLE_3 MOV DS:WORD PTR [DI],0008H ; Save dev name size. ADD DI,02H ; Increment DI. MOV RIGHT_FLAG,00H ; Clear flag. MOV CX,9 ; Set counter. NEXT_I: CALL IS_ALPHA ; If Check then. JZ SAVE_I ; Save it. CALL IS_DIGIT ; if Digit then. JZ SAVE_I ; Save it. CMP AL,'-' ; If '-' then. JZ SAVE_I ; Save it. CMP AL,'(' ; If '(' then. JE RIG_BR_FLG ; Set flag. CMP AL,')' ; If ')' then JE BR_FLG_LEF ; Pad with spaces. CALL IS_DELIM ; If a delimiter then. JZ ADD_SPACE2 ; Pad with spaces. JMP ERR_ID_PAR ; Else an error. SAVE_I: DEC CX ; Decrement counter. CMP CX,0 ; If counter zero then. JLE ERR_ID_PAR ; Error. MOV DS:BYTE PTR [DI],AL ; Save char in table. INC DI ; Increment pointer. CALL GET_CHAR ; Get another char. JZ ADD_SPACE2 ; Exit routine. JMP NEXT_I ; Check char. ERR_ID_PAR: MOV ID_ERR_FLG,01H ; Set error falg on. JMP ID_PAR_X ; Exit. BR_FLG_LEF: CMP RIGHT_FLAG,01H ; If left bracket was JNE ERR_ID_PAR ; found and no previous JMP ADD_SPACE2 ; Bracket found, then error RIG_BR_FLG: CMP RIGHT_FLAG,01H ; If more than one bracket JE ERR_ID_PAR ; then error. CMP CX,09 ; If '(' and already id JB ERR_ID_PAR ; then error. MOV RIGHT_FLAG,01H ; Set flag for. CALL GET_CHAR ; Left brackets. JZ ERR_ID_PAR ; If end of line,exit. JMP NEXT_I ; Check character. ADD_SPACE2: DEC CX ; Check counter. CMP CX,1 JL ID_PAR_X ; Exit if already 8. LL2: MOV DS:BYTE PTR [DI],' ' ; Pad name with spaces. INC DI ; Increment pointer. LOOP LL2 ; Loop again. ID_PAR_X: RET ID_PARSE ENDP ;******************************************************** ;** HWCP_PARMS : Scane for the hardware code page, and ** ;** parse it if found. Flag codes set to: ** ;** ERROR_FLAG = 0 - parsing completed. No error. ** ;** ERROR_FLAG = 1 - error found exit parse. ** ;** ERROR_FLAG = 2 - end of line found, exit parse. ** ;******************************************************** HWCP_PARMS PROC MOV COMMA_FLAG,00H ; Set the comma flag off. MOV ERROR_FLAG,00H ; Set the error flag off. DEC SI ; Point at current char in Al. CMP RIGHT_FLAG,01H ; If no left brackets then JNE LEFT_BR ; Exit parse. HWCP_1: CALL GET_CHAR ; Load character in AL. JZ LEFT_BR ; Exit, if end of line. CALL IS_DIGIT ; Check if digit, then JE HP1 ; Parse hwcp parms. CMP AL,',' ; If a comma JE COMMA_1 ; Jump to comma_1 CMP AL,')' ; If a ')' then JE RIGHT_BR ; end of current dev parms. CMP AL,'(' ; If a '(' then JE HWCP_2 ; There are multible hwcp. CALL IS_DELIM ; Else, if not a delimiter JNE EXIT_2 ; Then error, exit JMP HWCP_1 ; Get another character. LEFT_BR: CMP RIGHT_FLAG,01H ; If no left bracket JE EXIT_2 ; Then error, exit JMP RB1 ; Jump to rb1 COMMA_1: CMP COMMA_FLAG,01H ; If comma flag set JE COM_2_HC ; Then exit hwcp parse. MOV COMMA_FLAG,01H ; Else set comma flag. JMP HWCP_1 ; Get another character. HWCP_2: CMP RIGHT_FLAG,01H ; If left bracket not set JNE EXIT_2 ; then error. CALL MUL_HWCP ; else call multiple hwcp ADD DI,02H ; routine. Increment DI MOV TABLE_5,DI ; Desg. Table starts at end CALL OFFSET_TABLE ; Update table of offsets. JMP HP_X ; Exit. HP1: JMP HWCP ; Jump too long. COM_2_HC: MOV DI,TABLE_4 ; DI points at hwcp table MOV DS:WORD PTR [DI],0000H ; Set number of pages to MOV COMMA_FLAG,00H ; Zero and reset comma flag. ADD DI,02H ; Increment DI. MOV TABLE_5,DI ; Desg. Table starts at end CALL OFFSET_TABLE ; Update table of offsets. JMP HP_X ; of hwcp table. Exit. RIGHT_BR: CMP RIGHT_FLAG,01H ; If left brackets not JNE EXIT_2 ; Found then error. RB1: MOV ERROR_FLAG,02H ; Set end of line flag. MOV BX,TABLE_4 ; Point at hwcp table ADD BX,02H ; Adjust pointer to desg MOV TABLE_5,BX ; table, and save in table_5 MOV DI,TABLE_1 ; Point at table of offsets ADD DI,08H ; Set at DESG offset MOV DS:WORD PTR [DI],BX ; Update table. JMP HP_X ; Exit EXIT_2: MOV ERROR_FLAG,01H ; Set error flag. JMP HP_X ; and exit. HWCP: CMP RIGHT_FLAG,01H ; If left brackets not JNE EXIT_2 ; Found then error. CALL HWCP_PARSE ; Call parse one hwcp. CMP ERROR_FLAG,01H ; If error flag set JE HP_X ; Then exit, else CALL OFFSET_TABLE ; Update table of offsets. HP_X: RET HWCP_PARMS ENDP ;******************************************************** ;** HWCP_PARSE : Parse the hardware code page page ** ;** number and change it from hex to binary. ** ;******************************************************** HWCP_PARSE PROC MOV DI,TABLE_4 ; Load address of hwcpages. ADD DS:WORD PTR [DI],0001H ; Set count to 1 CALL GET_NUMBER ; Convert number to binary. CMP ERROR_FLAG,01H ; If error then JE HWCP_X ; Exit. MOV DS:WORD PTR [DI+2],BX ; Else, save binary page number ADD DI,04H ; Increment counter MOV TABLE_5,DI ; Set pointer of designate num HWCP_X: RET HWCP_PARSE ENDP ;******************************************************** ;** MUL_HWCP : Parse multiple hardware code pages ** ;** and convert them from hex to binary numbers. ** ;******************************************************** MUL_HWCP PROC MOV DI,TABLE_4 ; Load offset of table_4 MOV BX,DI ; in DI and Bx. MOV HWCP_FLAG,00H ; Set hwcp flag off. MH1: CALL GET_CHAR ; Load character in AL. JZ MH3 ; Exit if end of line. CMP AL,')' ; If ')' then exit JE MH2 ; end of parms. CALL IS_DIGIT ; If a digit, then JE MH4 ; Convert number to binary. CALL IS_DELIM ; If not a delimiter JNE MH3 ; then error, exit JMP MH1 ; get another character. MH2: CALL GET_CHAR ; Get next character JMP MH_X ; and exit. MH3: MOV ERROR_FLAG,01H ; Set error flag on. JMP MH_X ; Exit. MH4: ADD HWCP_FLAG,01H ; Set hwcp flag on (0 off) ADD DI,02H ; Increment table pointer PUSH BX ; Save Bx CALL GET_NUMBER ; Convert number to binary. MOV DS:WORD PTR [DI],BX ; Add number to table POP BX ; Restore BX. CMP ERROR_FLAG,01H ; If error then JE MH_X ; Exit. ADD DS:WORD PTR [BX],01H ; Increment hwcp count. DEC SI ; Point at character in AL JMP MH1 ; (delimeter or ')'). MH_X: RET MUL_HWCP ENDP ;******************************************************** ;** DESG_PARMS : Scane for the designate numbers, and ** ;** parse it if found. Flag codes set to: ** ;** ERROR_FLAG = 0 - parsing completed. No error. ** ;** ERROR_FLAG = 1 - error found exit parse. ** ;** ERROR_FLAG = 2 - end of line found, exit parse. ** ;******************************************************** DESG_PARMS PROC MOV DI,TABLE_1 ; Get offset of dev in DI MOV BX,TABLE_5 ; & offset of desg. in BX. ADD DI,08 ; Location of desg offset in table. MOV DS:WORD PTR [DI],BX ; Update table. MOV COMMA_FLAG,00H ; Set comma flag off. cmp al,'(' je df cmp al,')' je right_br2 cmp al,',' jne desg_parm1 mov comma_flag,01h DESG_PARM1: CALL GET_CHAR ; Get character in AL. JZ EXIT_3 ; Error, if end of line CALL IS_DIGIT ; If character is a digit JE DESG ; Then convert to binary. CMP AL,')' ; If a ')', then JE RIGHT_BR2 ; end of parameters. CMP AL,'(' ; If a '(' then JE DF ; parse desg and font. CMP AL,',' ; If a comma then JE DP3 ; set flag. CALL IS_DELIM ; If not a delimiter JNE EXIT_3 ; then error. JMP DESG_PARM1 ; Get another character. RIGHT_BR2: CMP RIGHT_FLAG,01H ; IF no '(' encountered, JNE EXIT_3 ; then error, exit JMP DP_x ; Jump to DP1. EXIT_3: MOV ERROR_FLAG,01H ; Set error flag on JMP DP_X ; Exit. DF: CMP RIGHT_FLAG,01H ; If no '(' encountered JB EXIT_3 ; then error, exit CALL DESG_FONT ; Parse desg and font. JMP DP1 ; Jump to DP1. DP2: CALL FIND_RIGHT_BR ; Check for ')' JMP DP_X ; Exit. DP3: CMP COMMA_FLAG,01H ; If comma flag set JE DP2 ; then error MOV COMMA_FLAG,01H ; Else set comma flag on. JMP DESG_PARM1 ; Get another character. DESG: MOV ERROR_FLAG,00H ; Set error flag off. CALL DESG_PARSE ; Parse desg. DP1: CMP ERROR_FLAG,01H ; If error flag on then JE DP_X ; Exit, CALL FIND_RIGHT_BR ; Else check for ')' CALL OFFSET_TABLE ; Update table DP_X: RET DESG_PARMS ENDP ;******************************************************** ;** DESG_FONT : Parse the designate and font numbers & ** ;** change them from decimal to binary. ** ;******************************************************** DESG_FONT PROC MOV DI,TABLE_5 ; Get desg font table. MOV COMMA_FLAG,00H ; Set comma flag off. DF1: CALL GET_CHAR ; Load a character in AL. JZ DF3 ; Error if end of line. CMP AL,',' ; Check if a comma. JE DF2 ; Set flag. CALL IS_DIGIT ; If a digit, then JE DF5 ; Convert number to binary. CMP AL,')' ; If a ')' then JE DF4 ; Exit. CALL IS_DELIM ; If not a delimiter JNE DF3 ; then error, exit JMP DF1 ; Get another character. DF2: CMP COMMA_FLAG,01H ; If comma flag on JE DF3 ; then error, exit MOV COMMA_FLAG,01H ; Set comma flag on ADD DS:WORD PTR [DI],01H ; Increment desg counter. MOV DS:WORD PTR [DI+2],0FFFFH ; Load ffffh for desg empty JMP DF1 ; field. DF3: MOV ERROR_FLAG,01H ; Set error flag on. JMP DF_X ; Exit. DF4: CMP DESG_FLAG,00H ; If desg flag off JE DF3 ; then error, exit JMP DF_X ; Else exit. DF5: ADD DS:WORD PTR [DI],01H ; Increment desg font count. CMP DESG_FLAG,01H ; If desg flag is on JE DF6 ; then get font. CMP COMMA_FLAG,01H ; if comma flag is on JE DF6 ; then get font. MOV DESG_FLAG,01H ; Set desg flag on JMP DF7 ; Get desg number. DF6: ADD DI,02H ; adjust pointer to font. MOV DESG_FLAG,02H ; Set desg and font flag. DF7: CALL GET_NUMBER ; Get a number & convert to CMP ERROR_FLAG,01H ; binary. JE DF_X ; If error flag set, Exit. MOV DS:WORD PTR [DI+2],BX ; Store number in table. CMP DESG_FLAG,02H ; If desg and font flag JNE DF1 ; not set, then get char. CALL FIND_RIGHT_BR ; Check for right bracket. DF_X: RET DESG_FONT ENDP ;******************************************************** ;** DESG_PARSE : Parse the designate number and ** ;** change it from decimal to binary. ** ;******************************************************** DESG_PARSE PROC MOV DI,TABLE_5 ; Load designate location ADD DS:WORD PTR [DI],0001H ; Update table count. CALL GET_NUMBER ; Get the ascii number and CMP ERROR_FLAG,01H ; conver it to binary JE DESG_X ; If error then exit MOV DS:WORD PTR [DI+2],BX ; Else, save desg number DESG_X: RET DESG_PARSE ENDP ;******************************************************** ;** GET_NUMBER : Convert the number pointed to by SI ** ;** to a binary number and store it in BX ** ;******************************************************** GET_NUMBER PROC MOV CX,0AH ; Set multiplying factor XOR BX,BX ; Clear DX NEXT_NUM: SUB AL,30H ; Conver number to binary CBW ; Clear AH XCHG AX,BX ; Switch ax and bx to mul MUL CX ; already converted number by 10. JO ERR_NUM ; On over flow jump to error. ADD BX,AX ; Add number to total. JC ERR_NUM ; On over flow jump to error. XOR AX,AX ; Clear AX (clear if al=0a). CALL GET_CHAR ; Get next character JZ GET_NUM_X ; Exit, if end of line. CALL IS_DIGIT ; Call is digit. JNZ GET_NUM_X ; Exit if not a number. JMP NEXT_NUM ; Loop. ERR_NUM: MOV ERROR_FLAG,01H ; Set error code to 1. GET_NUM_X: RET GET_NUMBER ENDP ;******************************************************** ;** UPDATE_TABLE : This routine set up pointers to the ** ;** different offsets of the different tables ** ;******************************************************** UPDATE_TABLE PROC MOV DS:WORD PTR [DI],BX ; Offset of offsets MOV TABLE_1,BX ; Table_1 points at offsets MOV DI,BX ; ADD BX,0CH ; MOV DS:WORD PTR [DI+2],BX ; Offset of DEVICE name. MOV TABLE_2,BX ; Table_2 point at device name. ADD BX,0AH ; MOV DS:WORD PTR [DI+4],BX ; Offset of ID name. MOV TABLE_3,BX ; Table_3 point at ID name. ADD BX,0AH ; MOV DS:WORD PTR [DI+6],BX ; Offset of HWCP pages. MOV TABLE_4,BX ; Table_4 point at HWCP pages. RET UPDATE_TABLE ENDP ;******************************************************** ;** OFFSET_TABLE : This routine set up pointers of ** ;** tables number one and two. ** ;******************************************************** OFFSET_TABLE PROC MOV DI,TABLE_1 ; Increment the number ADD DS:WORD PTR [DI],01H ; of parms foun. (ie. id,hwcp RET ; and desg) OFFSET_TABLE ENDP ;******************************************************** ;** FIND_RIGHT_BR :This routine scane the line for a ** ;** ')' if cannot find it turns error flag on ** ;******************************************************** FIND_RIGHT_BR PROC FBR1: CMP AL,')' ; If a right bracket JE FBR_X ; then exit. CMP AL,' ' ; If not a space JNE FBR2 ; Then error. CALL GET_CHAR ; Get a character JZ FBR2 ; If end of line then exit. JMP FBR1 ; Else get another character. FBR2: MOV ERROR_FLAG,01H ; Set error flag on FBR_X: MOV AL,20H ; Erase character from AL. RET FIND_RIGHT_BR ENDP ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Command ++ ;; ++++++++++++++++++++++++ ;; ;;==== Command Code 0 - Initialization ====== ;; ;; messages returned : ;; ;; msg_bad_syntax -- syntax error from parser, no driver installation ;; msg_no_init -- device cannot be initialised ;; msg_insuff_mem -- insufficient memory ;; ;; layout : the initialization is done in two stages : ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Stage 1 ++ to examine and extract the ;; ++++++++++++++++++++++++ parameters defined for the ;; device_id in DEVICE command, ;; according to the printer ;; description table for the ;; device_id. ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Stage 2 ++ to set the BUFfer for the LPTn ;; ++++++++++++++++++++++++ or PRN according to device_id's ;; parameters ;; ;; ;; ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; DEV_NUM dw ? ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Tables for the deivce_id parameters in the order of device_id in the ; PARSE table ; === the tables serves as the link between LPTn to be defined in the 2nd ; stage, and the device_id that is processed in the first stage. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; device ID indicators : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DID_MAX EQU 4 ;; device entris exepcted in PARSE ;; not more than 16. ;; table ;; DID_STATUS DW 0 ;; status of parsing device id ;; = 0 : all Device-ID bad ;; -- see DID_BIT ;; DID_MATCH DW 0 ;; this DID has device_name matched ;; DID_FAIL DW 0 ;; to fail the good DID_STATUS and ;; the matched name. (due to ;; inconsistency among the same LPTn ;; or between PRN and LPT1.) ;; ;; (DID_STATUS) AND (DID_MATCH) XOR (DID_FAIL) determines the success of DID ;; initialization ;; DID_ONE EQU 00001H ;; first device-ID DID_TWO EQU 00002H ;; second " DID_THREE EQU 00004H ;; third " DID_FOUR EQU 00008H ;; fourth " ;;maximun number of device_id = 16 ;; ;; DID_BIT LABEL WORD ;; DW DID_ONE ;; DW DID_TWO ;; DW DID_THREE ;; DW DID_FOUR ;; ;;maximun number of device_id = 16 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; device paramters according to the ;; device_id defined in DEVICE and the ;; parameters defined for the device_id ;; in the printer description table. ;; HRMAX LABEL word ;; number of hwcp+cart slots supported DW 0 ;; did = 1 DW 0 ;; did = 2 DW 0 ;; did = 3 DW 0 ;; did = 4 ;upto max DID_MAX ;; ;; CTMAX LABEL word ;; number of cart slots supported DW 0 ;; did = 1 DW 0 ;; did = 2 DW 0 ;; did = 3 DW 0 ;; did = 4 ;upto max DID_MAX ;; ;; RMMAX LABEL word ;; number of ram-slots supported DW 0 ;; did = 1 DW 0 ;; did = 2 DW 0 ;; did = 3 DW 0 ;; did = 4 ;upto max DID_MAX ;; ;; RBUMAX LABEL word ;; number of ram-designate slots DW 0 ;; did = 1 DW 0 ;; did = 2 DW 0 ;; did = 3 DW 0 ;; did = 4 ;upto max DID_MAX ;; ;; DESCO LABEL word ;; offset to the description table ;; where the device_id is defined. DW -1 ;; did = 1 DW -1 ;; did = 2 DW -1 ;; did = 3 DW -1 ;; did = 4 ;upto max DID_MAX ;; ;; FSIZE LABEL word ;; font size of the device DW 0 ;; did = 1 DW 0 ;; did = 2 DW 0 ;; did = 3 DW 0 ;; did = 4 ;upto max DID_MAX ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Hard/RAM slots table in the order of DEVICE parameters ; ; number of entries in all HARD_SLn is determined by the max. {HSLOTS}, and ; number of entries in all RAM_SLn is determined by the max. {RSLOTS} ; ; -- they are initialized according to the device_id defined in the DEVICE. ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; HARD_SLA LABEL word ;; index in the order of device in DW OFFSET (HARD_SL1) ;; the PARSE-talbes DW OFFSET (HARD_SL2) ;; DW OFFSET (HARD_SL3) ;; DW OFFSET (HARD_SL4) ;; ; up to DID_MAX ;; ;; RAM_SLA LABEL word ;; DW OFFSET (RAM_SL1) ;; DW OFFSET (RAM_SL2) ;; DW OFFSET (RAM_SL3) ;; DW OFFSET (RAM_SL4) ;; ; up to DID_MAX ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Command ++ ;; ++++++++++++++++++++++++ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; INIT PROC NEAR ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; parse the initialization parameters in DEVICE command ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; CMP BUF.BFLAG,BF_PRN ;; since PRN is the FIRST device header JNE NOT_PRN ;; ;; ;; MOV AX,OFFSET CODE_END ;; defined only once for each DEVICE XOR CX,CX ;; MOV CL,4 ;; SHR AX,CL ;; PUSH CS ;; POP CX ;; ADD AX,CX ;; INC AX ;; leave 16 bytes,room for resident_end MOV RESIDENT_END,AX ;; ;; CALL PARSER ;; call only once, for PRM ;; JMP PROCESS_TABLE ;; ;; NOT_PRN : ;; CMP DEV_NUM,1 ;; ;; JNB PROCESS_TABLE ;; ;; JMP SYNTAX_ERROR ;; ;; ;; ;; ;; ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Stage 1 ++ ;; ++++++++++++++++++++++++ ;; ;; INIT - FIRST STAGE : ;; ;; == test and extract if the parameters on device-id is valid ;; == determine the DID_STATUS according to the validity of the parameters ;; == procedure(s) called -- DID_EXTRACT ;; ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; PROCESS_TABLE : ;; ;; PUSH CS ;; POP ES ;; PSE points to Device offsets MOV DI,OFFSET(table) ;; ES:[DI] MOV DX,PSE.PAR_DEV_NUM ;; MOV DEV_NUM,DX ;; ;; CMP DEV_NUM,0 ;; JNZ NO_SYNTAX_ERR ;; ;; XOR AX,AX ;; MOV AH,09H ;; MOV DX,OFFSET MSG_BAD_SYNTAX;; INT 21H ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SYNTAX_ERROR : ;; set the request header status ;; according to the STATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV AX, RESIDENT_END ;; PUSH CS ;; POP CX ;; CX=CS SUB AX,Cx ;; additional segment required. CS_LOOP1: ;; CMP AX,1000H ;; JB CS_LPEND1 ;; ADD CX,1000H ;; SUB AX,1000H ;; JMP CS_LOOP1 ;; ;; CS_LPEND1: ;; SHL AX,1 ;; SHL AX,1 ;; SHL AX,1 ;; SHL AX,1 ;; ;; LES DI,dword ptr buf.rh_ptro ;; get Request Header address ; MOV RH.RH0_ENDO,AX ;; MOV RH.RH0_ENDO,0 ;; MOV RH.RH0_ENDS,CX ;; MOV RH.RHC_STA,stat_cmderr ;; set status in request header ;; JMP INIT_RETurn ;; ;; ;; NO_SYNTAX_ERR : ;; ;; CMP DX,DID_MAX ;; JNA NEXT_DID ;; ;; MOV INIT_CHK,0001H ;; ERROR 0001 JMP BAD_DID ;; more than supported no. of device ;; NEXT_DID: ;; PUSH DI ;; pointer to PAR_OT (table 1) AND DX,DX ;; JNZ SCAN_DESC ;; JMP END_DID ;; DI = offset to the 1st PARSE table ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SCAN_DESC: ;; MOV DI,PSE.PAR_OFF ;; points to the nth device ;; ;; find the description for the ;;device-id ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV CX,PRINTER_DESC_NUM ;; MOV SI, OFFSET(PRINTER_DESC_TBL); offset to the description table PUSH CS ;; POP DS ;; ; $SEARCH ;; $$DO1: PUSH CX ;; save device count PUSH SI ;; pointer to printer-descn's offset MOV SI,CS:WORD PTR[SI] ;; AND CX,CX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $LEAVE Z ;; LEAVE if no more device description JZ $$EN1 PUSH DI ;; save offset to PAR_DEVOT MOV DI,PSE.PAR_DIDO ;; MOV CX,PSE.PAR_DIDL ;; length of parsed device name LEA DI,PSE.PAR_DID ;; pointer to parse device name ;; PUSH SI ;; LEA SI,[SI].TYPEID ;; offset to name of device-id REPE CMPSB ;; POP SI ;; POP DI ;; get back offset to PAR_DEVOT ;;;;;;;;;;;;;;;;;;;;;;;; ; $EXITIF Z ;; EXIT if name matched JNZ $$IF1 ;; CALL DID_EXTRACT ;; get the parameters ;; POP SI ;; balance push-pop POP CX ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $ORELSE ;; try next description : JMP SHORT $$SR1 $$IF1: ;; POP SI ;; of printer_descn offset table INC SI ;; INC SI ;; next offset to PRINTER_DESCn ;; POP CX ;; one description less DEC CX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $ENDLOOP ;; DEVICE-ID not defined in JMP SHORT $$DO1 $$EN1: ;; printer_desc; ;; MOV AX,INIT_CHK ;; AND AX,AX ;; JNZ UNCHANGED ;; MOV INIT_CHK,0004H ;; ERROR 0004 UNCHANGED: ;; POP SI ;; balance push-pop POP CX ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $ENDSRCH ;; End of scanning printer_desc $$SR1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; POP DI ;; INC DI ;; INC DI ;; points to next device in PART_OT DEC DX ;; ;; JMP NEXT_DID ;; ;; END_DID : ;; POP DI ;; BAD_DID : ;; ;; MOV AX,DID_STATUS ;; AND AX,AX ;; JNZ DEF_BUFFER ;; ;; JMP END_LPT ;; ;; ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; ;; ++++++++++++++++++++++++ ;; ++ INIT Stage 2 ++ ;; ++++++++++++++++++++++++ ;; ;; INIT -- SECOND STAGE : ;; ;; == match the device_name extracted in stage 1 with the name of PRN or ;; LPTn ;; ;; == if the PRN/LPTn has never been defined before, then set up the BUF ;; for the PRN/LPTn if the DID_STATUS is good; otherwise message will ;; be generated indicating it cannot be initilized. ;; ;; == if there is PRN, LPT1 is also setup, and vice vera. IF both PRN and ;; LPT1 are on the DEVICE command, or there are multiple entries for ;; the same LPTn, the consistency is checked. It they are inconsistent ;; the associated LPTn or PRN is forced to fail by : DID_FAIL. ;; ;; == if the device_name on the DEVICE command is not one of the supported ;; PRN or LPTn, then DID_MATCH bit will not be set. An error message ;; will be generated for the device_name indicating it cannot be ;; initialized. ;; ;; == procedure(s) called : CHK_DID .. check DID parameters for device ;; whose name matched. ;; DEV_CHECK .. if device-name duplicated, or ;; there are both PRN/LPT1 : check ;; for consistent parameters. ;; ;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ DEF_BUFFER : ;; PUSH CS ;; POP ES ;; PSE points to Device offsets MOV DI,OFFSET(table) ;; ES:[DI] xor cx,cx ;; device order in parse table ;SEARCH ;; $$DO7: PUSH DI ;; pointer to PAR_OT PUSH CX ;; save device count MOV DI,PSE.PAR_OFF ;; " " PAR_DEVOT cmp cx,dev_num ;; ;; ;LEAVE NB ;; LEAVE if no more device entry jb MORE_DEVICE ;; JMP $$EN7 MORE_DEVICE : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; more parsed_device to be checked PUSH DI ;; save offset to PAR_DEVOT MOV DI,PSE.PAR_DNMO ;; MOV CX,PSE.PAR_DNML ;; length of parsed device name LEA DI,PSE.PAR_DNM ;; pointer to parse device name ;; LDS SI,DWORD PTR BUF.DEV_HDRO ; get the offset to device-n header LEA SI,HP.DH_NAME ;; " offset to name of device-n REPE CMPSB ;; POP DI ;; get back offset to PAR_DEVOT ;; ;;;;;;;;;;;;;;;;;;;;;;;;;; ;EXITIF Z ;; EXIT if name matched JZ NAME_MATCHED ;; ;; JMP MORE_PARSED_DEVICE ;; ;; NAME_MATCHED : ;; ;; POP CX ;; the DID order PUSH BX ;; MOV BX,CX ;; ADD BX,BX ;; MOV AX,DID_BIT[BX] ;; OR DID_MATCH,AX ;; this DID matched POP BX ;; PUSH CX ;; ;; LEA SI,BUF.PAR_EXTRACTO ;; was the LPT1/PRN defined before ? MOV AX,CS:[SI].PAR_DNMO ;; CMP AX,0FFFFH ;; ;; JNE DEV_COMPARE ;; DI = PAR_DEVOT ;;----------------------------------- ;; ;; no device previousely defined MOV AX,PSE.PAR_DNMO ;; MOV CS:[SI].PAR_DNMO,AX ;; define device parameters for LPTn ;; MOV AX,PSE.PAR_DIDO ;; MOV CS:[SI].PAR_DIDO,AX ;; ;; MOV AX,PSE.PAR_HWCPO ;; MOV CS:[SI].PAR_HWCPO,AX ;; ;; MOV AX,PSE.PAR_DESGO ;; MOV CS:[SI].PAR_DESGO,AX ;; ;; MOV AX,PSE.PAR_PARMO ;; MOV CS:[SI].PAR_PARMO,AX ;; ;; ;;--------------------------------- CALL CHK_DID ;; define the STATE according to ;; DID_STATUS JMP MORE_PARSED_DEVICE ;; ;; DEV_COMPARE : ;;------------------------------- ;; e.g. LPT1 and PRN shares one BUF. ;; or duplicated device name CALL DEV_CHECK ;; ;; CMP BUF.STATE,CPSW ;; JNE DEV_COMPARE_FAIL ;; ;; JMP MORE_PARSED_DEVICE ;; ;; DEV_COMPARE_FAIL : ;; ;; POP CX ;; POP DI ;; balance push-pop ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;$ORELSE ;; JMP END_LPT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MORE_PARSED_DEVICE : ;; name does not match ;; POP CX ;; INC CX ;; POP DI ;; INC DI ;; INC DI ;; points to next device in PART_OT ;; jmp $$DO7 ;; ;$ENDLOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $$EN7: ;; no device found for LPTn ;; POP CX ;; POP DI ;; balance push-pop ;; CMP BUF.STATE,CPSW ;; JE END_LPT ;; for LPT1/PRN pair ;; MOV BUF.STATE,NORMAL ;; no device defined for the LPTn ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; End of defining LPTn Buffer ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;$ENDSRCH ;; END_LPT : ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; set the request header status ;; according to the STATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; MOV AX, RESIDENT_END ;; PUSH CS ;; POP CX ;; CX=CS SUB AX,Cx ;; additional segment required. CS_LOOP2: ;; CMP AX,1000H ;; JB CS_LPEND2 ;; ADD CX,1000H ;; SUB AX,1000H ;; JMP CS_LOOP2 ;; ;; CS_LPEND2: ;; SHL AX,1 ;; SHL AX,1 ;; SHL AX,1 ;; SHL AX,1 ;; ;; LES DI,dword ptr buf.rh_ptro ;; get Request Header address MOV RH.RH0_ENDO,AX ;; MOV RH.RH0_ENDS,CX ;; XOR AX,AX ;; clear error code to be returned MOV CX,BUF.STATE ;; CMP CX,CPSW ;; JE MATCH_GOOD ;; MOV AX,STAT_CMDERR ;; ;; MATCH_GOOD : ;; MOV RH.RHC_STA,AX ;; set status in request header ;; BUF_END : ;; ;; CMP BUF.BFLAG,BF_LPT1 ;; JNE BUF_MESSAGES ;; ;; CMP BUF.STATE,CPSW ;; JNE BUF_MESSAGES ;; ;; set PRN to the same setting as LPT1 PUSH BX ;; ;; LEA SI,BUF.RNORMO ;; LEA CX,BUF.BUFEND ;; SUB CX,SI ;; MOV BX,BUF.PRN_BUFO ;; where PRN buffer is LEA DI,BUF.RNORMO ;; PUSH CS ;; POP ES ;; PUSH CS ;; POP DS ;; REP MOVSB ;; ;; POP BX ;; ;; BUF_MESSAGES : ;; CMP BUF.BFLAG,BF_LPT3 ;; generate error message is this is je last_round ;; the last LPTn Jmp INIT_RETURN ;; ;; ERROR messages will be generated ;; at the end of initialization of all ;; the LPT devices last_round : ;; MOV AX,RESIDENT_END ;; ADD AX,STACK_SIZE ;; MOV RESIDENT_END,AX ;; PUSH CS ;; POP CX ;; CX=CS SUB AX,Cx ;; additional segment required. CS_LOOP3: ;; CMP AX,1000H ;; JB CS_LPEND3 ;; ADD CX,1000H ;; SUB AX,1000H ;; JMP CS_LOOP3 ;; ;; CS_LPENd3: ;; SHL AX,1 ;; SHL AX,1 ;; SHL AX,1 ;; SHL AX,1 ;; ;; MOV RH.RH0_ENDO,AX ;; STACK !!!!! MOV STACK_ALLOCATED,0 ;; from now on, internal stack is used ;; MOV AX,DID_STATUS ;; what is the DID combination ? AND AX,DID_MATCH ;; XOR AX,DID_FAIL ;; ;; AND AX,AX ;; JNZ CODE_STAYED ;; ; MOV RH.RH0_ENDO,0 ;; none of the devices are good ;; ;; CODE_STAYED : ;; MOV DI,OFFSET TABLE ;; push CS ;; POP ES ;; ;; XOR CX,CX ;; MSG_LOOP : ;; CMP CX,DEV_NUM ;; JNB INIT_RETURN ;; SHR AX,1 ;; JC MSG_NEXT ;; ;; this device in parse table is bad PUSH DI ;; PUSH CX ;; PUSH AX ;; ;; MOV DI,PSE.PAR_OFF ;; MOV SI,PSE.PAR_DNMO ;; ;; PUSH CS ;; POP ES ;; PUSH CS ;; POP DS ;; ;; MOV CX,8 ;; LEA SI,[SI].PAR_DNM ;; ;; MOV DI,SI ;; ADD DI,7 ;; skip backward the blanks MOV AL,20H ;; STD ;; REPE SCASB ;; CLD ;; ;; MOV DI, OFFSET MSG_NO_INIT_P;; MOV DX,DI ;; for INT 21H XOR AX,AX ;; MOV AH,09H ;; INT 21H ;; ;; ;; MOV DI, OFFSET MSG_NO_INIT ;; MOV DX,DI ;; for INT 21H ;; INC CX ;; ;; PUSH CX ;; remaining name that is non blank MOV AX,CX ;; MOV CX,8 ;; SUB CX,AX ;; ADD DI,CX ;; MOV DX,DI ;; POP CX ;; REP MOVSB ;; ;; ;; XOR AX,AX ;; MOV AH,09H ;; INT 21H ;; ;; POP AX ;; POP CX ;; POP DI ;; ;; MSG_NEXT : ;; INC CX ;; INC DI ;; INC DI ;; JMP MSG_LOOP ;; ;; ;; INIT_RETURN : ;; ;; ;; RET ;; ;; INIT ENDP ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Call by INIT to extract parameters for the deivce_id ;; ;; on rntry : ;; ES:[DI] PARSE Table 2, offsets of all parameters ;; DS:[SI] Printer Description table whose TYPEID matched ;; DX "inverse" order of devices in the PARSE tables ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; DID_EXTRACT PROC ;; ;; PUSH DX ;; ;;----------------------------- ;; define the DID_parameters PUSH BX ;; ;; MOV BX,DEV_NUM ;; SUB BX,DX ;; order in the Parse table add bx,bx ;; double to index [bx] MOV DX,BX ;; ;; MOV AX,DS:[SI].FONTSZ ;; MOV FSIZE[BX],AX ;; size of font buffer to be created ;; MOV AX,DS:[SI].HSLOTS ;; CMP AX,HARDSL_MAX ;; JNA LESS_HARDSL ;; MOV INIT_CHK, 0010H ;; ERROR 0010H POP BX ;; JMP END_MATCH_BAD ;; LESS_HARDSL : ;; CMP AX,DS:[SI].HWCPMIN ;; JNB VALID_HARDSL ;; MOV INIT_CHK, 0012H ;; ERROR 0012H POP BX ;; JMP END_MATCH_BAD ;; VALID_HARDSL : ;; MOV HRMAX[BX],AX ;; MOV CTMAX[BX],AX ;; will be reduced by the no. of hwcp ;; MOV AX,DS:[SI].RSLOTS ;; CMP AX,RAMSL_MAX ;; JNA LESS_RAMSL ;; MOV INIT_CHK, 0011H ;; ERROR 0011H POP BX ;; JMP END_MATCH_BAD ;; LESS_RAMSL : ;; MOV RMMAX[BX],AX ;; see also designate ;; MOV DESCO[BX],SI ;; ;; POP BX ;; ;;---------------------------------- ;; PUSH CX ;; ;; HWCPgt: PUSH DI ;; get the hwcp ;; MOV DI,PSE.PAR_HWCPO ;; MOV CX,PSE.PAR_HWCPL ;; no. of hwcp AND CX,CX ;; JNZ chk_hwcp ;; push bx ;; mov bx,dx ;; MOV HRMAX[BX],CX ;; MOV CX,DS:[SI].HWCPMIN ;; SUB CTMAX[BX],CX ;; what is left becomes cartridge slot pop bx ;; JMP DESIGN ;; ;; hwcp to be defined chk_hwcp: MOV AX,DS:[SI].HSLOTS ;; defined in printer_desc CMP CX,AX ;; JA BAD_MATCH2 ;; CMP CX,HARDSL_MAX ;; JNA HWCP_GOOD ;; jump if system error MOV INIT_CHK,0003H ;; ERROR 0003 JMP END_MATCH ;; BAD_MATCH2: ;; MOV INIT_CHK,0002H ;; ERROR 0002 JMP END_MATCH ;; ;; HWCP_GOOD: ;; there are sufficient hard-slot for ;; HWCP PUSH SI ;; printer description table of TYPEID PUSH BX ;; ;; MOV BX,DX ;; MOV AX,CTMAX[BX] ;; ;; PUSH CX ;; calculate what is left for cart_slot CMP CX,DS:[SI].HWCPMIN ;; JNB MORE_THAN_HWCPMIN ;; MOV CX,DS:[SI].HWCPMIN ;; MORE_THAN_HWCPMIN : ;; SUB AX,CX ;; POP CX ;; mov HRMAX[BX],CX ;; ;; MOV CTMAX[BX],AX ;; no of cart-slot for designate MOV SI,HARD_SLA[BX] ;; get the corresponding hard-slots ;; POP BX ;; ;; push bx ;; push dx ;; mov bx,si ;; mov dx,cx ;; mov reserved1,dx ;; IF THERE IS ANY REPETITIVE HWCP mov reserved2,bx ;; IF THERE IS ANY REPETITIVE HWCP ;; FILL_HWCP: ;; AND CX,CX ;; JZ DESIGN_P ;; INC DI ;; next code page in PARSE table INC DI ;; MOV AX,ES:[DI] ;; get code page value ;; ;; IF THERE IS ANY REPETITIVE HWCP push dx ;; push bx ;; hwcp_norep : ;; cmp ax,cs:[bx].slt_cp ;; jne hwcp_repnext ;; pop bx ;; pop dx ;; pop dx ;; pop bx ;; pop si ;; jmp end_match ;; ;; hwcp_repnext: ;; inc bx ;; inc bx ;; inc bx ;; inc bx ;; dec dx ;; jnz hwcp_norep ;; pop bx ;; pop dx ;; ;; MOV CS:[SI].SLT_CP,AX ;; MOV AX,CS:[SI].SLT_AT ;; get the attributes OR AX,AT_OCC ;; occupied OR AX,AT_HWCP ;; hwcp slot MOV CS:[SI].SLT_AT,AX ;; INC SI ;; INC SI ;; next slot INC SI ;; next slot INC SI ;; next slot DEC CX ;; JMP FILL_HWCP ;; DESIGN_P: ;; pop dx ;; pop bx ;; POP SI ;; ;;--------------------- DESIGN: POP DI ;; get the designate no. PUSH DI ;; ;; MOV DI,PSE.PAR_DESGO ;; MOV AX,PSE.PAR_DESGL ;; CMP AX,1 ;; JA END_MATCH ;; there should have no font entry AND AX,AX ;; JZ DEF_RBUFMAX ;; ;; MOV AX,PSE.PAR_DESG ;; AND AX,AX ;; JZ DEF_RBUFMAX ;; ;; CMP CS:[SI].CLASS,1 ;; JNE DESIG_NOt_CLASS1 ;; ;; PUSH BX ;; if there is any cartridge slot ? PUSH AX ;; MOV BX,DX ;; MOV AX,ctmax[BX] ;; AND AX,AX ;; POP AX ;; POP BX ;; JZ END_MATCH ;; fail, as there is no physical RAM. ;; CMP AX,HARDSL_MAX ;; is the designate more than max ? JA END_MATCH ;; ;; ;; JMP DEF_RBUFMAX ;; ;; ;; ;; DESIG_NOT_CLASS1 : ;; PUSH BX ;; if there is any physical RAM slot ? PUSH AX ;; MOV BX,DX ;; MOV AX,RMMAX[BX] ;; AND AX,AX ;; POP AX ;; POP BX ;; JZ END_MATCH ;; fail, as there is no physical RAM. ;; ;; CMP AX,RAMSL_MAX ;; is the designate more than max ? JA END_MATCH ;; ;; DEF_RBUFMAX : ;; PUSH BX ;; MOV BX,DX ;; MOV RBUMAX[BX],AX ;; POP BX ;; ;; ;; PARAM : ;; ;PARM: POP DI ;; ; PUSH DI ;; ;; MOV DI,PSE.PAR_PARMO ;; ;; ;,-------------------------- ;; GOOD device_id parameters shr dx,1 ;; MOV AX,DID_ONE ;; MOV CX,DX ;; AND CX,CX ;; JZ NO_SHL ;; SHL AX,CL ;; NO_SHL: OR DID_STATUS,AX ;; is defined ;;------------------------- END_MATCH: POP DI ;; end of extract POP CX ;; END_MATCH_BAD : ;; POP DX ;; ;; RET ;; ;; DID_EXTRACT ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Called by INIT to define the STATE and BUF for the LPTn according to ;; the DID_STATUS. Create font buffer if requested through the "desi*nate" ;; ;; at entry : CX = device order in parse table ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CHK_DID PROC ;; ;; push cx ;; push di ;; push dx ;; ;; MOV AX,DID_STATUS ;; ;; PUSH CX ;; order 0 to m POP DI ;; ADD DI,DI ;; indexing : [DI] ;; INC CX ;; SHR AX,CL ;; is the device parameter valid ? ;; JC DEFINE_BUFFER ;; JMP LPT_FAIL ;;-------------------------- ;; DEFINE_BUFFER : ;; ;; good device parameters as determined MOV AX,DESCO[DI] ;; MOV BUF.PDESCO,AX ;; ;; PUSH DI ;; MOV DI,AX ;; MOV AX,CS:[DI].CLASS ;; MOV BUF.PCLASS,AX ;; POP DI ;; ;; MOV AX,HARD_SLA[DI] ;; in the DID_EXTRACT MOV BUF.HARDSO,AX ;; ;; MOV AX,RAM_SLA[DI] ;; MOV BUF.RAMSO,AX ;; ;; MOV AX,HRMAX[DI] ;; MOV BUF.HARDMX,AX ;; ;; MOV AX,CTMAX[DI] ;; MOV BUF.HCARMX,AX ;; ;; ADD AX,HRMAX[DI] ;; defore "designate" MOV BUF.HSLMX,AX ;; ;; ;; MOV AX,RMMAX[DI] ;; MOV BUF.RAMMX,AX ;; ;; XOR AX,AX ;; PUSH CX ;; calculate the max. length of control MOV CX,2 ;; sequence that is allowed for the CMP BUF.PCLASS,1 ;; room reserved for physical slots. JNE CTL_LOOP ;; MOV CX,1 ;; class 1 printer has one control seq. CTL_LOOP : ;; ADD AX,CTL_MAX ;; DEC AX ;; leave one byte for the length DEC CX ;; JNZ CTL_LOOP ;; MOV BUF.FSELMAX,AX ;; POP CX ;; ;; MOV AX,FSIZE[DI] ;; MOV BUF.FTSZPA,AX ;; FTSIZE in paragraph ;; PUSH AX ;; ;; MOV DX,4 ;; FT_PARA: ;; ADD AX,AX ;; DEC DX ;; JNZ FT_PARA ;; font size MOV BUF.FTSIZE,AX ;; font size in bytes (used with.RBUFMX) ;; POP DX ;; FTSIZE in paragraph ;; MOV CX,RBUMAX[DI] ;; create font buffer per .RBUFMX and MOV BUF.RBUFMX,CX ;; assume sufficient memory for all the ;; "designate request" PUSH CX ;; ;; CMP BUF.PCLASS,1 ;; always create font buffer for class1 JNE CLASS_NOT_1 ;; ;; AND CX,CX ;; JZ CLASS1_NOCX ;; ADD CX,BUF.HARDMX ;; MOV BUF.HSLMX,CX ;; JMP CLASS_NOT_1 ;; ;; CLASS1_NOCX: ;; MOV CX,BUF.HSLMX ;; ;; CLASS_NOT_1 : ;; AND CX,CX ;; JZ MULTIPLE_DONE ;; MOV AX,RESIDENT_END ;; MULTIPLE_FT : ;; ADD AX,DX ;; allocate the font buffers at the end DEC CX ;; of the resident codes JNZ MULTIPLE_FT ;; ;; ;; MOV CX,RESIDENT_END ;; MOV BUF.FTSTART,CX ;; MOV RESIDENT_END,AX ;; ;; ;; MULTIPLE_DONE : ;; POP CX ;; designate requested ;; CMP BUF.PCLASS,1 ;; JNE DEF_RBUF ;; ;; CLASS 1 CMP BUF.HARDMX,0 ;; JE DEFBUF_DONE ;; ;; PUSH CX ;; STACKS... PUSH SI ;; PUSH DS ;; PUSH ES ;; PUSH DI ;; PUSH DX ;; ;; MOV DX,BUF.HARDMX ;; PUSH DX ;; STACK +1 -- # of HWCP ;; PUSH CS ;; POP DS ;; MOV BUF.RBUFMX,0 ;; MOV SI,BUF.PDESCO ;; MOV SI,CS:[SI].SELH_O ;; XOR CX,CX ;; MOV CL,CS:BYTE PTR [SI] ;; INC CX ;; including the length byte ;; MOV DI,BUF.FTSTART ;; control template DEF_FTBUF: ;; fill the font buffer with the PUSH DI ;; POP ES ;; XOR DI,DI ;; ;; PUSH CX ;; PUSH SI ;; REP MOVSB ;; POP SI ;; POP CX ;; ;; PUSH ES ;; POP DI ;; ADD DI,BUF.FTszpa ;; DEC DX ;; JNZ DEF_FTBUF ;; ;; POP DX ;; STACK -1 ;; MOV SI,BUF.HARDSO ;; MOV DI,BUF.FTSTART ;; define the HWCP values DEF_FThwcp : ;; PUSH DI ;; POP ES ;; MOV DI,CTL5202_OFFS ;; offset to the HWCP words ;; MOV AX,CS:[SI].SLT_CP ;; MOV ES:WORD PTR [DI],AX ;; ;; INC SI ;; INC SI ;; INC SI ;; INC SI ;; ;; PUSH ES ;; POP DI ;; ADD DI,BUF.FTSZPA ;; DEC DX ;; JNZ DEF_FThwcp ;; ;; POP DX ;; POP DI ;; POP ES ;; POP DS ;; POP SI ;; POP CX ;; ;; JMP DEFBUF_DONE ;; ;; ;; DEF_RBUF : ;; MOV BUF.RSLMX,CX ;; the no. of ram slots supported CMP CX,RMMAX[DI] ;; JNB DEFBUF_DONE ;; MOV AX,RMMAX[DI] ;; MOV BUF.RSLMX,AX ;; the max. of .RAMMX and .RBUFMX ;; DEFBUF_DONE : ;; MOV BUF.STATE,CPSW ;; the LPTn is CPSW ----- STATE ;; CMP BUF.BFLAG,BF_PRN ;; JNE RET_CHK_DID ;; MOV AX,DID_BIT[DI] ;; MOV BUF.DID_PRN,AX ;; ;; ;; JMP RET_CHK_DID ;; ;; LPT_FAIL: ;; ;; MOV BUF.STATE,NORMAL ;; the LPTn is NORMAL --- STATE ;; ;; RET_CHK_DID: ;; ;; pop dx ;; pop di ;; pop cx ;; ;; RET ;; ;; CHK_DID ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Called by INIT to check for consistency between duplicated device name and ;; between PRN and LPT1 ;; ;; at entry : DI = pointer to PAR_DEVOT ;; BUF.STATE = any state ;; CX = DID order ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DEV_CHECK PROC ;; ;; LEA SI,BUF.PAR_EXTRACTO ;; ;; PUSH CX ;; ;; PUSH SI ;; compare device id PUSH DI ;; mov SI,[SI].PAR_DIDO ;; MOV DI,PSE.PAR_DIDO ;; MOV CX,PSE.PAR_DNML ;; INC CX ;; including length INC CX ;; REPE CMPSB ;; POP DI ;; POP SI ;; Jz hwcp_check ;; mov init_chk,0021h ;; error 0021h Jmp FORCE_LPT_BAD ;; ;; hwcp_check : ;; PUSH SI ;; compare HWCP PUSH DI ;; mov SI,[SI].PAR_HWCPO ;; MOV DI,PSE.PAR_HWCPO ;; MOV AX,PSE.PAR_HWCPL ;; MOV CX,2 ;; SHL AX,CL ;; multiply by two INC AX ;; including length INC AX ;; MOV CX,AX ;; REPE CMPSB ;; POP DI ;; POP SI ;; Jz desig_check ;; mov init_chk,0022h ;; error 0022h Jmp FORCE_LPT_BAD ;; ;; desig_check : ;; PUSH SI ;; compare DESIGNATE PUSH DI ;; mov SI,[SI].PAR_DESGO ;; MOV DI,PSE.PAR_DESGO ;; MOV AX,PSE.PAR_DESGL ;; MOV CX,2 ;; SHL AX,CL ;; multiply by two INC AX ;; including length INC AX ;; MOV CX,AX ;; REPE CMPSB ;; POP DI ;; POP SI ;; Jz param_check ;; mov init_chk,0023h ;; error 0023h Jmp FORCE_LPT_BAD ;; ;; param_check : ;; PUSH SI ;; compare parameters PUSH DI ;; mov SI,[SI].PAR_PARMO ;; MOV DI,PSE.PAR_PARMO ;; MOV CX,PSE.PAR_PARML ;; INC CX ;; including length INC CX ;; REPE CMPSB ;; POP DI ;; POP SI ;; JZ M_END ;; mov init_chk,0024h ;; error 0024h ;; FORCE_LPT_BAD : ;; the second set of parameters is MOV BUF.STATE,NORMAL ;; bad ;; CMP BUF.BFLAG,BF_LPT1 ;; JNE M_END ;; ;; ;; since LPT1 is bad, force PRN to bad push bx ;; force prn to be bad too mov bx,buf.prn_bufo ;; MOV BUF.STATE,NORMAL ;; pop bx ;; ;; mov AX,BUF.DID_PRN ;; if PRN was not good, DID_PRN = 0 OR DID_FAIL,AX ;; ;; ;; M_END: ;; force the good did_status to fail if ;; STATE is bad POP CX ;; PUSH CX ;; order 0 to m MOV AX,DID_STATUS ;; ;; INC CX ;; SHR AX,CL ;; POP CX ;; JNC DEV_CHECK_RET ;; already failed ;; CMP BUF.STATE,CPSW ;; JE DEV_CHECK_RET ;; ;; PUSH BX ;; MOV BX,CX ;; ADD BX,BX ;; MOV AX,DID_BIT[BX] ;; OR DID_FAIL,AX ;; force DID to fail POP BX ;; ;; ;; DEV_CHECK_RET : ;; ;; RET ;; ;; ;; DEV_CHECK ENDP ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CSEG ENDS END