PAGE ,132 TITLE DOS - CONSOLE Code Page Switching Device Driver ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; FILENAME: DISPLAY.ASM ; PROGRAM: DISPLAY.SYS (Main module) ; LINK PROCEDURE: Linkk ; INSTALLATION: ; ; This routine is structured as a DOS Device Driver. ; IE it is installed via the CONFIG.SYS command: ; DEVICE=DISPLAY.SYS ; ; The following device commands are supported: ; ; 00 hex - INIT ; ------------- ; Install the CON device driver. This is used for downloading of ; the character sets (various Code Pages) according to the respective ; display adapter. The interface provided by the video BIOS is used ; to download a block of 256 characters (in various resolutions - ie. ; 8x8, 8x14, and 8x16). Also, the interrupt 2F hex is chained for ; communication between the CON device driver and the keyboard routine. ; ; Refer to INIT.ASM for code ; ; 13 hex - GENERIC IOCTL ; ---------------------- ; INVOKE ; ------ ; Invoke is use to activate the appropriate CP font. The mechanism ; is based soley on the code page value passed from the MODE & CHCP ; commands. Once a CP ahs benn INVOKED, it is loaded for ALL display ; modes on the respective display adapter - ONLY IF the proper font ; resolution can be accessed. ; ; Refer to CPS-FUNC.INC for code ; ; DESIGNATE START ; --------------- ; Designate start passes the list of designated code pages to load. ; It is sent just prior to the IOCTL WRITE calls containing the 'CPI' ; files. The list of designated code pages is check for duplicates ; and for invalids (-1). ; ; Refer to CPS-FUNC.INC for code ; ; DESIGNATE STOP ; -------------- ; Once the data (for a DESIGNATION) has been routed to the CPS driver, ; it is followed by a DESIGNATE STOP command. This confirms the completion ; of the DESIGNATE procedure. If there was an error detected during the ; DESIGNATE procedure, it must be followed by a DESIGNATE STOP. ; ; Refer to CPS-FUNC.INC for code ; ; ; 0C hex - IOCTL OUTPUT ; --------------------- ; Following a DESIGNATE START, the contents of the specified data file ; (expected .CPI format) is copied by DOS to the CPS driver. This is ; via the GENERIC IOCTL WRITE calls. During these calls, the data is ; parsed by the FONT-PARSER (F-PARSER.SRC) to select the CP and fonts ; required. ; ; Refer to CPS-FUNC.INC for code ; ; ; (C)Copyright 1988 Microsoft ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Request Header (Common portion) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IF1 ; %OUT .Compiling: DISPLAY.ASM %OUT . ô CPS-CON driver %OUT . õ Version 3.30 %OUT .Include Files: ENDIF ; INCLUDE MACROS.INC ; INCLUDE DEF-EQU.INC ; ; PUBLIC EOF_MARKER ; PUBLIC CPD_ACTIVE ; PUBLIC CPD_CLASS ; PUBLIC CPD_HDWR_N_MAX ; PUBLIC CPD_DESG_N_MAX ; PUBLIC CPD_HDWR_N ; PUBLIC CPD_DESG_N ; PUBLIC CPD_FONTS_N ; PUBLIC CPD_FONT_PNTER ; PUBLIC IRPT_2 ; PUBLIC IRPT_CMD_EXIT ; PUBLIC DEV_HDR ; EXTRN INIT:NEAR ; ; CODE SEGMENT BYTE PUBLIC 'CODE' ; ASSUME CS:CODE,DS:CODE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;**************************************** ;** Resident Code ** ;**************************************** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; START EQU $ ; begin resident data & code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; DEVICE HEADER - must be at offset zero within device driver ; (DHS is defined according to this structure) ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ORG 0000H ; ; DEV_HDR:DD -1 ; Pointer to next device header DW 0C053H ; Attribute (Char device) DW OFFSET STRATEGY ; Pnter to device "strategy" DW OFFSET INTERRUPT ; Pnter to device "interrupt" DB 'CON ' ; Device name ; and of course a descriptive name ; which can be viewed by a TYPE! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Console Description Table ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .XLIST ; STACK_END DW 1FFH+60H DUP(0) ; 200H + 'my' needs (re/ DOS 3.30 ref) STACK_START DW 0 ; OLD_STACK_S DW ? ; OLD_STACK_O DW ? ; .LIST ; ; BUF1: BUF_DATA <> ; exclude PAR_EXTRACTO ; CP_PNTER_TABLE DW OFFSET CPD_HDWR_N ; TABLE OF POINTERS TO CP INFO DW OFFSET CPD_DESG_N ; DW OFFSET CPD_FONT_PNTER; DW OFFSET CPD_FONT_WRITE; DW OFFSET CPD_FONT_DATA ; ; CPD_TABLE LABEL WORD ; TABLE DATA INFO FOR CP's CPD_ACTIVE DW -1 ; TEMPORARY CPD_CLASS DB '........' ; THIS IS SET TO (EGA, LCD) CPD_FONTS_N DW -1 ; CPD_HDWR_N DW 0 ; DW 12 DUP(-1) ; (HDWR_CP's) (MAX=12) CPD_HDWR_N_MAX EQU ($-CPD_HDWR_N)/2-1 ; CPD_DESG_N DW -1 ; # OF DESIG CP's DW 12 DUP(-1) ; (DESG CP's) (MAX=12) CPD_DESG_N_MAX EQU ($-CPD_DESG_N)/2-1 ; CPD_FONT_PNTER DW 12 DUP(0,0) ; SEG_OFFSET POINTER TO DATA BUFFERS CPD_FONT_WRITE DW 12 DUP(0,0) ; SEG_OFFSET OF FONTS BEING WRITTEN CPD_FONT_DATA DW 12 DUP(0) ; COUNT OF FONT DATA TO SKIP/COPY! FONT_PRIORITY DB 8 DUP(-1) ; USED TO CLASSIFY FONT PRIORITY NUM_FONT_PRIORITY EQU ($-FONT_PRIORITY) ; DURING A DESIGNATION CPD_TEMP_DESG DW 0 ; # OF DESIG CP's TEMP BUFFER DW 12 DUP(-1) ; (DESG CP's) (MAX=12) CPD_REQ_DESG DW 0 ; # OF DESIG CP's REQUESTED DW 12 DUP(-1) ; (DESG CP's) (MAX=12) ;;;;;;; ANSI_DA_INFO DA_INFO_PACKET <> ;J.K. Information packet to ANSI used for MODE SET INT10 call. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; CON Device "strategy" entry point ; Retain the Request Header address for use by Interrupt routine ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ASSUME DS:NOTHING ; STRATEGY PROC FAR ; PUSH BX ; PUSH BX ; LEA BX, BUF1 ; BUF = BUF1 CS:[BX] POP BUF.RH_PTRO ; OFFSET OF REQUEST HEADER MOV BUF.RH_PTRS,ES ; SEGMENT POP BX ; RET ; STRATEGY ENDP ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Table of command processing routine entry points ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; CMD_TABLE LABEL WORD ; DW OFFSET INIT ; 0 - Initialization DW OFFSET NO_OPERATION ; 1 - Media check DW OFFSET NO_OPERATION ; 2 - Build BPB DW OFFSET NO_OPERATION ; 3 - IOCTL input DW OFFSET NO_OPERATION ; 4 - Input DW OFFSET NO_OPERATION ; 5 - Non destructive input no wait DW OFFSET NO_OPERATION ; 6 - Input status DW OFFSET NO_OPERATION ; 7 - Input flush DW OFFSET NO_OPERATION ; 8 - Write DW OFFSET NO_OPERATION ; 9 - Output with verify DW OFFSET NO_OPERATION ; A - Output status DW OFFSET NO_OPERATION ; B - Output flush DW OFFSET DESG_WRITE ; C - IOCTL output DW OFFSET NO_OPERATION ; D - Device OPEN DW OFFSET NO_OPERATION ; E - Device CLOSE DW OFFSET NO_OPERATION ; F - Removable media DW OFFSET NO_OPERATION ; 10 - Removable media DW OFFSET NO_OPERATION ; 11 - Removable media DW OFFSET NO_OPERATION ; 12 - Removable media DW OFFSET GENERIC_IOCTL ; 13 - Removable media MAX_CMD EQU ($-CMD_TABLE)/2 ; highest valid command follows ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; CON Device "interrupt" entry point ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INTERRUPT PROC FAR ; device interrupt entry point PUSH AX ; PUSH BX ; PUSH CX ; PUSH DI ; PUSH SI ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Common interrupt entry : ; at entry, BUFn (CS:BX) of CON is defined ; ; Check if header link has to be set ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LEA BX, BUF1 ; MOV DI,OFFSET DEV_HDR ; CON Device header ; MOV BUF.DEV_HDRO,DI ; MOV BUF.DEV_HDRS,CS ; CLD ; all moves forward ; CMP BUF.CON_STRAO, -1 ; JNE L4 ; has been linked to DOS CON CMP BUF.CON_STRAS, -1 ; JNE L4 ; has been linked to DOS CON ; next device header : ES:[DI] LDS SI,DWORD PTR BUF.DEV_HDRO; LES DI,DWORD PTR HP.DH_NEXTO; ; ;$SEARCH WHILE ; pointer to next device header is NOT L1: ; PUSH ES ; -1 POP AX ; CMP AX,-1 ; ;$LEAVE E, AND ; leave if both offset and segment are JNE NOT0FFFF ; ; CMP DI,-1 ; 0FFFFH ;$LEAVE E ; JE L4 ; NOT0FFFF: ; PUSH DI ; PUSH SI ; MOV CX,NAME_LEN ; LEA DI,NHD.DH_NAME ; LEA SI,HP.DH_NAME ; REPE CMPSB ; POP SI ; POP DI ; AND CX,CX ; ;$EXITIF Z ; Exit if name is found in linked hd. JNZ L3 ; Name is not found ; Name is found in the linked header MOV AX,NHD.DH_STRAO ; Get the STRATEGY address MOV BUF.CON_STRAO,AX ; MOV AX,ES ; X1: MOV BUF.CON_STRAS,AX ; ; MOV AX,NHD.DH_INTRO ; Get the INTERRUPT address MOV BUF.CON_INTRO,AX ; MOV AX,ES ; X2: MOV BUF.CON_INTRS,AX ; ; ;$ORELSE ; FInd next header to have the same JMP L4 ; Device Name L3: ; LES DI,DWORD PTR NHD.DH_NEXTO; ;$ENDLOOP ; JMP L1 ; L4: ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; COMMAND REQUEST ; ES:DI REQUEST HEADER ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; LES DI,DWORD PTR BUF.RH_PTRO; GET RH ADDRESS PASSED TO ; "STRATEGY" INTO ES:DI MOV AL,RH.RHC_CMD ; COMMAND CODE FROM REQUEST HEADER CBW ; ZERO AH (IF AL > 7FH, NEXT COMPARE ; WILL CATCH THAT ERROR) CMP AL,MAX_CMD ; IF COMMAND CODE IS TOO HIGH JAE L6 ; JUMP TO ERROR ROUTINE ; ADD AX,AX ; DOUBLE COMMAND CODE FOR TABLE OFFSET MOV SI,AX ; PUT INTO INDEX REGISTER FOR JMP ; CALL CS:CMD_TABLE[SI] ; CALL ROUTINE TO HANDLE THE COMMAND JC IRPT_CMD_EXIT ; CY=1 IF NO PASS_CONTROL REQ'D CALL PASS_CONTROL ; JUMP IRPT_2 ; ; L6: CALL PASS_CONTROL ; CALL ROUTINE TO HANDLE THE COMMAND ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; At entry to command processing routine ; ; ES:DI = Request Header address ; CS:BX = Buffer for CON ; CS = code segment address ; AX = 0 ; ; top of stack is return address, IRPT_CMD_EXIT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IRPT_CMD_EXIT: ; RETURN FROM COMMAND ROUTINE LES DI,DWORD PTR BUF.RH_PTRO; RESTORE ES:DI AS REQUEST HEADER PTR XOR AX,AX ; OR AX,BUF.STATUS ; JE IRPT_0 ; XOR BUF.STATUS,AX ; SET STATUS BACK TO OK! OR AX,STAT_CMDERR ; JUMP IRPT_1 ; IRPT_0: OR AH,STAT_DONE ; ADD "DONE" BIT TO STATUS WORD IRPT_1: MOV RH.RHC_STA,AX ; STORE STATUS INTO REQUEST HEADER IRPT_2: POP SI ; RESTORE REGISTERS POP DI ; POP CX ; POP BX ; POP AX ; RET ; INTERRUPT ENDP ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PASS CONTROL ; ; This calls the attached device to perform any further ; action on the call! ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PASS_CONTROL PROC ; PUSH BX ; PUSH BX ; POP SI ; LES BX,DWORD PTR BUF.RH_PTRO; pass the request header to the CALL DWORD PTR CS:[SI].CON_STRAO ; CON strategy routine. POP BX ; CALL DWORD PTR BUF.CON_INTRO ; interrupt the CON RET ; PASS_CONTROL ENDP ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; NO_OPERATION PROC ; CLC ; RET ; NO_OPERATION ENDP ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; PULL IN THE CODE PAGE FUNCTION CODE ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; INCLUDE INT2FCOM.INC ; INCLUDE INT10COM.INC ; INCLUDE CPS-FUNC.INC ; INCLUDE WRITE.INC ; SPECIAL MARKER IN WRITE.INC INCLUDE F-PARSER.INC ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; Adjust the assembly-time instruction counter to a paragraph ; boundary ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IF ($-START) MOD 16 ; ORG ($-START)+16-(($-START) MOD 16); ENDIF ; EOF_MARKER EQU $ ; end of resident code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; END-OF-CODE ; ;;;;;;;;;;;;;;;;; CODE ENDS ; END ; ;;;;;;;;;;;;;;;;;