From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/GRAPHICS/GRINST.ASM | 973 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 973 insertions(+) create mode 100644 v4.0/src/CMD/GRAPHICS/GRINST.ASM (limited to 'v4.0/src/CMD/GRAPHICS/GRINST.ASM') diff --git a/v4.0/src/CMD/GRAPHICS/GRINST.ASM b/v4.0/src/CMD/GRAPHICS/GRINST.ASM new file mode 100644 index 0000000..cdb8b17 --- /dev/null +++ b/v4.0/src/CMD/GRAPHICS/GRINST.ASM @@ -0,0 +1,973 @@ + PAGE ,132 ;AN000; + TITLE DOS - GRAPHICS Command - Installation Modules ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +;; DOS - GRAPHICS Command +;; (C) Copyright 1988 Microsoft +;; ;AN000; +;; File Name: GRINST.ASM ;AN000; +;; ---------- ;AN000; +;; ;AN000; +;; Description: ;AN000; +;; ------------ ;AN000; +;; This file contains the installation modules for the ;AN000; +;; GRAPHICS command. ;AN000; +;; ;AN000; +;; GRAPHICS_INSTALL is the main module. ;AN000; +;; ;AN000; +;; GRAPHICS_INSTALL calls modules in GRLOAD.ASM to load ;AN000; +;; the GRAPHICS profile and GRPARMS.ASM to parse the command line. ;AN000; +;; ;AN000; +;; ;AN000; +;; Documentation Reference: ;AN000; +;; ------------------------ ;AN000; +;; OASIS High Level Design ;AN000; +;; OASIS GRAPHICS I1 Overview ;AN000; +;; DOS 3.3 Message Retriever Interface Supplement. ;AN000; +;; TUPPER I0 Document - PARSER HIGH LEVEL DESIGN REVIEW ;AN000; +;; ;AN000; +;; Procedures Contained in This File: ;AN000; +;; ---------------------------------- ;AN000; +;; GRAPHICS_INSTALL - Main installation module ;AN000; +;; CHAIN_INTERRUPTS - Chain interrupts 5, 2F, EGA Save Pointers ;AN000; +;; COPY_PRINT_MODULES - Throw away one set of print modules ;AN000; +;; ;AN000; +;; ;AN000; +;; Include Files Required: ;AN000; +;; ----------------------- ;AN000; +;; GRLOAD.EXT - Externals for profile load ;AN000; +;; GRLOAD2.EXT - Externals for profile load ;AN000; +;; GRCTRL.EXT - Externals for print screen control ;AN000; +;; GRPRINT.EXT - Externals for print modules ;AN000; +;; GRCPSD.EXT - Externals for COPY_SHARED_DATA module ;AN000; +;; GRPARMS.EXT - External for GRAPHICS command line parsing ;AN000; +;; GRPARSE.EXT - External for DOS parser ;AN000; +;; GRBWPRT.EXT - Externals for Black and white printing modules ;AN000; +;; GRCOLPRT.EXT - Externals for color printing modules ;AN000; +;; GRINT2FH.EXT - Externals for Interrupt 2Fh driver. ;AN000; +;; ;AN000; +;; GRMSG.EQU - Equates for the GRAPHICS error messages ;AN000; +;; SYSMSG.INC - DOS message retriever ;AN000; +;; ;AN000; +;; GRSHAR.STR - Shared Data Area Structure ;AN000; +;; ;AN000; +;; STRUC.INC - Macros for using structured assembly language ;AN000; +;; ;AN000; +;; External Procedure References: ;AN000; +;; ------------------------------ ;AN000; +;; FROM FILE GRLOAD.ASM: ;AN000; +;; LOAD_PROFILE - Main module for profile loading ;AN000; +;; SYSPARSE - DOS system parser ;AN000; +;; SYSDISPMSG - DOS message retriever ;AN000; +;; ;AN000; +;; Linkage Instructions: ;AN000; +;; -------------------- ;AN000; +;; Refer to GRAPHICS.ASM ;AN000; +;; ;AN000; +;; Change History: ;AN000; +;; --------------- ;AN000; +;; ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; + ;; ;AN000; +CODE SEGMENT PUBLIC 'CODE' ;; ;AN000; + ASSUME CS:CODE,DS:CODE ;; ;AN000; + ;; ;AN000; +.XLIST ;; ;AN000; + INCLUDE GRSHAR.STR ;; Include the Shared data area structure;AN000; + INCLUDE SYSMSG.INC ;; Include DOS message retriever ;AN000; + INCLUDE STRUC.INC ;; Include macros - Structured Assembler ;AN000; + INCLUDE GRLOAD.EXT ;; Bring in external declarations ;AN000; + INCLUDE GRLOAD2.EXT ;; ;AN000; + INCLUDE GRLOAD3.EXT ;; ;AN000; + INCLUDE GRCTRL.EXT ;; ;AN000; + INCLUDE GRBWPRT.EXT ;; ;AN000; + INCLUDE GRCOLPRT.EXT ;; ;AN000; + INCLUDE GRCPSD.EXT ;; ;AN000; + INCLUDE GRINT2FH.EXT ;; ;AN000; + INCLUDE GRCTRL.EXT ;; ;AN000; + INCLUDE GRPARSE.EXT ;; ;AN000; + INCLUDE GRPARMS.EXT ;; ;AN000; + INCLUDE GRMSG.EQU ;; ;AN000; + ;; ;AN000; +MSG_UTILNAME ;; Identify ourself to Message retriever.;AN000; + ;; Include messages ;AN000; +MSG_SERVICES ;; ;AN000; +MSG_SERVICES ;; ;AN000; +MSG_SERVICES ;AN000; +.LIST ;; ;AN000; + ;; ;AN000; +PUBLIC GRAPHICS_INSTALL ;; ;AN000; +PUBLIC TEMP_SHARED_DATA_PTR ;; ;AN000; +PUBLIC PRINTER_TYPE_PARM ;; ;AN000; +PUBLIC PRINTER_TYPE_LENGTH ;; ;AN000; +PUBLIC PROFILE_PATH ;; ;AN000; +PUBLIC PRINTBOX_ID_PTR ;; ;AN000; +PUBLIC PRINTBOX_ID_LENGTH ;; ;AN000; +PUBLIC DEFAULT_BOX ;; ;AN000; +PUBLIC LCD_BOX ;; ;AN000; +PUBLIC NB_FREE_BYTES ;; ;AN000; +PUBLIC SYSDISPMSG ;; ;AN000; +PUBLIC DISP_ERROR ;; ;AN000; +PUBLIC INSTALLED ;; ;AN000; +PUBLIC ERROR_DEVICE ;; ;AN000; +PUBLIC STDERR ;; ;AN000; +PUBLIC STDOUT ;; ;AN000; +PUBLIC RESIDENT_SHARED_DATA_SIZE ;; ;AN000; + ;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +;; ;AN000; +;; Install Variables ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; + ;; ;AN000; +NO EQU 0 ;; ;AN000; +YES EQU 1 ;; ;AN000; +INSTALLED DB NO ;; YES if GRAPHICS already installed ;AN000; + ;; ;AN000; + ;; ;AN000; +BYTES_AVAIL_PSP_OFF EQU 6 ;; Word number 6 of the PSP is the ;AN000; + ;; number of bytes available in the ;AN000; + ;; current segment ;AN000; + ;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +;; ;AN000; +;; GRLOAD (PROFILE LOADING) INPUT PARMS: ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +PRINTER_TYPE_PARM DB "GRAPHICS",9 DUP(0) ; Printer type ;AN000; + ;; (default=GRAPHICS) ;AN000; +PRINTER_TYPE_LENGTH DB 17 ;; Printer type maximum length of ASCIIZ ;AN000; +PROFILE_PATH DB 128 DUP(0) ;; Profile name with full path ;AN000; + ;; (Max size for ASCIIZ is 128) ;AN000; +PRINTBOX_ID_PTR DW DEFAULT_BOX ;; Offset of ASCIIZ string containing ;AN000; +DEFAULT_BOX DB "STD",14 DUP(0); the printbox id. (DEFAULT = STD) ;AN000; +LCD_BOX DB "LCD",14 DUP(0); ASCIIZ string for the LCD printboxID;AN000; +PRINTBOX_ID_LENGTH DB 17 ;; Max. length for the printbox id. ;AN000; + ;; ASCIIZ string ;AN000; +NB_FREE_BYTES DW ? ;; Number of bytes available in our ;AN000; + ;; resident segment ;AN000; +RESIDENT_SHARED_DATA_SIZE DW ? ;; Size in bytes of the RESIDENT Shared ;AN000; + ;; data area (if GRAPHICS already ;AN000; + ;; installed). ;AN000; +END_OF_RESIDENT_CODE DW ? ;; Offset of the end of the code that ;AN000; + ;; has to be made resident. ;AN000; +TEMP_SHARED_DATA_PTR DW ? ;; Offset of the temporary Shared area ;AN000; + ;; ;AN000; +ERROR_DEVICE DW STDERR ;; Device DISP_ERROR will output ;AN000; + ;; messages to (STDERR or STDOUT) ;AN000; +PAGE ;AN000; +;===============================================================================;AN000; +; ;AN000; +; GRAPHICS_INSTALL : INSTALL GRAPHICS.COM ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +; ;AN000; +; INPUT: Command line parameters ;AN000; +; GRAPHICS profile - A file describing printer characteristics and ;AN000; +; attributes. ;AN000; +; ;AN000; +; OUTPUT: If first time invoked: ;AN000; +; INT 5 VECTOR and INT 2FH VECTOR are replaced; only the required ;AN000; +; code for printing the screen is made resident. ;AN000; +; else, ;AN000; +; The resident code is updated to reflect changes in printing ;AN000; +; options. ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +;; ;AN000; +;; DESCRIPTION: ;AN000; +;; ;AN000; +;; This module intalls GRAPHICS code and data. ;AN000; +;; ;AN000; +;; An INT 2FH driver is also installed. ;AN000; +;; ;AN000; +;; If this driver is already present then, we assume GRAPHICS was installed ;AN000; +;; and do not install it again but, simply update the resident code. ;AN000; +;; ;AN000; +;; The resident code contains ONLY the code and data needed for Printing ;AN000; +;; the screen. The code needed is determined according to the command line ;AN000; +;; parameters and the information extracted from the printer profile. ;AN000; +;; ;AN000; +;; The printer profile is parsed according to the current hardware setting ;AN000; +;; and also to the command line options. The information extracted from ;AN000; +;; the profile is stored in a Data area shared between the installation ;AN000; +;; process and the Print Screen process. ;AN000; +;; ;AN000; +;; A temporary Shared Data Area is FIRST built at the end of the .COM file ;AN000; +;; Before building it, we verify that there is ;AN000; +;; enough memory left in the current segment. If not, the installation ;AN000; +;; process is aborted. ;AN000; +;; ;AN000; +;; This temporary Data area when completed will be copied over the ;AN000; +;; installation code. Therefore, the file comprising GRAPHICS must be ;AN000; +;; linked in a specific order with the installation modules being last. ;AN000; +;; ;AN000; +;; These modules will be overwritten by the Shared Data area and the EGA ;AN000; +;; dynamic save area before we exit and stay resident. ;AN000; +;; ;AN000; +;; The end of the resident code is the end of the Shared Data area, anything ;AN000; +;; else beyond that is not made resident. ;AN000; +;; ;AN000; +;; The pointer to the resident Shared Data area is declared within the ;AN000; +;; Interrupt 2Fh driver. This pointer is initialized by the installation ;AN000; +;; process and points to the shared data area at Print Screen time. ;AN000; +;; ;AN000; +;; Depending on the type of printer attached (i.e., Black and white or Color) ;AN000; +;; only one set of modules is made resident during the installation. ;AN000; +;; ;AN000; +;; The set of print modules required is copied over the previous one at ;AN000; +;; location "PRINT_MODULE_START". This location is declared within ;AN000; +;; GRCOLPRT which must be linked before GRBWPRT ;AN000; +;; ;AN000; +;; When copying one of the 2 sets of print modules we reserve enough space ;AN000; +;; for the larger of them. Therefore, if GRAPHICS is already installed but ;AN000; +;; is reinvoked with a different printer type which needs a bigger set of ;AN000; +;; modules: this new set of modules is simply recopied over the existing ;AN000; +;; one in the resident code. ;AN000; +;; ;AN000; +;; The Shared Data area is copied rigth after the set of modules that we keep ;AN000; +;; that is, over the unused set of modules. ;AN000; +;; ;AN000; +;; ;AN000; +;-------------------------------------------------------------------------------;AN000; +;; ;AN000; +;; Register Conventions: ;AN000; +;; BP - points to start of Temp Shared Data (Transiant code) ;AN000; +;; ;AN000; +;; Called By: ;AN000; +;; Entry point for GRAPHICS command processing. ;AN000; +;; ;AN000; +;; External Calls: ;AN000; +;; INT 2FH, LOAD_MESSAGES, LOAD_PROFILE, PARSE_PARMS ;AN000; +;; CHAIN_INTERRUPTS, COPY_SHARED_DATA, DISPLAY_MESSAGE ;AN000; +;; COPY_PRINT_MODULES ;AN000; +;; ;AN000; +;-------------------------------------------------------------------------------;AN000; +;; ;AN000; +;; LOGIC: ;AN000; +;; Load the message retriever ;AN000; +;; IF carry flag is set (incorrect DOS version) THEN ;AN000; +;; Issue message (COMMON1) ;AN000; +;; Exit ;AN000; +;; ENDIF ;AN000; +;; ;AN000; +;; Get number of bytes available in the segment from PSP (word 6) ;AN000; +;; /* This is needed since we construct a temporary Shared data area at the ;AN000; +;; of the .COM file */ ;AN000; +;; ;AN000; +;; /* Build Shared Data in temporary area */ ;AN000; +;; END_OF_RESIDENT_CODE := (end of .COM file) ;AN000; +;; NB_FREE_BYTES := Number of bytes availables ;AN000; +;; ;AN000; +;; CALL PARSE_PARMS ;AN000; +;; IF error THEN /* PARSE_PARMS will issue messages */ ;AN000; +;; Exit ;AN000; +;; ENDIF ;AN000; +;; ;AN000; +;; CALL LOAD_PROFILE ;AN000; +;; IF profile errors THEN ;AN000; +;; Exit /* LOAD_PROFILE will issue messages */ ;AN000; +;; ENDIF ;AN000; +;; ;AN000; +;; Issue INT 2FH Install Check call (AX=1500H) ;AN000; +;; /* INT 2FH returns ES:[DI] pointing to the shared data area */ ;AN000; +;; IF already installed THEN ;AN000; +;; THEN ;AN000; +;; Move NO to PRINT_SCREEN_ALLOWED in resident Shared Data ;AN000; +;; SHARED_DATA_AREA_PTR := DI ;AN000; +;; ELSE ;AN000; +;; MOV PRINT_SCREEN_ALLOWED,NO ;AN000; +;; CALL CHAIN_INTERRUPTS /* Install INT 5 and INT 2FH vectors */ ;AN000; +;; ES := Our segment ;AN000; +;; ENDIF ;AN000; +;; /* Keep only Print Black and White or Print Color: */ ;AN000; +;; CALL COPY_PRINT_MODULES ;AN000; +;; /* COPY_SHARED_DATA will terminate & stay resident */ ;AN000; +;; Set up registers for copy & terminate call ;AN000; +;; /* reserve enough memory to handle any printer in the profile*/ ;AN000; +;; jump to COPY_SHARED_DATA module ;AN000; +;; ELSE ;AN000; +;; /* Shared Data has been built in place */ ;AN000; +;; move YES to PRINT_SCREEN_ALLOWED ;AN000; +;; Return to DOS ;AN000; +;; ENDIF ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +GRAPHICS_INSTALL PROC NEAR ; ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Load the error messages ;AN000; +;-------------------------------------------------------------------------------;AN000; + CALL SYSLOADMSG ; Load messages ;AN000; + .IF C ; If error when loading messages ;AN000; + .THEN ; then, ;AN000; + MOV CX,0 ; CX := No substitution in message ;AN000; + MOV AX,1 ; AX := msg nb. for "Invalid DOS version" ;AN000; + CALL DISP_ERROR ; Display error message ;AN000; + JMP ERROR_EXIT ; and quit ;AN000; + .ENDIF ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Get offset of where to build the TEMPORARY Shared Data area (always built) ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV BP,OFFSET LIMIT ; Build it at the end of this .COM file ;AN000; + ; (LIMIT = the offset of the last byte ;AN000; + ; of the last .OBJ file linked with ;AN000; + ; GRAPHICS) ;AN000; + MOV TEMP_SHARED_DATA_PTR,BP ; ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Determine if GRAPHICS is already installed; get the resident segment value ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV AH,PRT_SCR_2FH_NUMBER ; Call INT 2FH (the Multiplex interrupt) ;AN000; + XOR AL,AL ; for Print Screen handler ;AN000; + INT 2FH ; ;AN000; + ;AN000; + .IF ; IF already installed ;AN000; + .THEN ; then, ;AN000; + ;----------------------------------------------------------------------------;AN000; + ; GRAPHICS is already installed: Get pointer to the EXISTING Shared Data area;AN000; + ;----------------------------------------------------------------------------;AN000; + MOV INSTALLED,YES ; Say it's installed ;AN000; + MOV AX,ES ; Get the segment and offset of the ;AN000; + MOV SHARED_DATA_AREA_PTR,DI; resident Shared Data area. ;AN000; + MOV RESIDENT_CODE_SEG,AX ; (returned in ES:DI) ;AN000; + ; Disable print screen because we will ;AN000; + MOV ES:PRINT_SCREEN_ALLOWED,NO ; be updating the resident code. ;AN000; + .ELSE ; ELSE, not installed: ;AN000; + ;------------------------------------------------------------------------ ;AN000; + ; GRAPHICS is NOT installed: RESIDENT shared data area is in OUR segment ;AN000; + ;------------------------------------------------------------------------ ;AN000; + PUSH CS ; The Shared Data area will be in our ;AN000; + POP RESIDENT_CODE_SEG ; segment. ;AN000; + .ENDIF ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Determine in AX how many bytes are available for building the TEMPORARY SHARED;AN000; +; DATA AREA: ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV AX,ES:BYTES_AVAIL_PSP_OFF;AX := Number of bytes availables in ;AN000; + ; the current segment (as indicated in PSP);AN000; + .IF > ; If there is no bytes available past ;AN000; + .THEN ; the end of our .COM file ;AN000; + XOR AX,AX ; then, AX := 0 bytes available ;AN000; + .ELSE ; ;AN000; + SUB AX,OFFSET LIMIT ; else, AX := Number of FREE bytes ;AN000; + .ENDIF ; in this segment ;AN000; + ;AN000; +;---AX = Number of bytes in our segment available for building the Temp Shared ;AN000; +;---data area. ;AN000; +;---IF ALREADY INSTALLED: Get the size of the existing Shared data area. ;AN000; +;---Since the temporary shared data area will be copied over the resident ;AN000; +;---shared data area, we do not want to build it any bigger than the one ;AN000; +;---it will overwrite. Therefore we do not give to LOAD_PROFILE more space ;AN000; +;---than the size of the existing Shared data area. ;AN000; + .IF ; If already installed then, ;AN000; + .THEN ;AN000; + PUSH CS:RESIDENT_CODE_SEG ; ES:[DI] := Resident Shared data area ;AN000; + POP ES ; ;AN000; + MOV DI,SHARED_DATA_AREA_PTR ; ;AN000; + MOV CX,ES:[DI].SD_TOTAL_SIZE ; CX := Size of the existing Shared area ;AN000; + MOV RESIDENT_SHARED_DATA_SIZE,CX ; Save size for LOAD_PROFILE ;AN000; + .IF ; If AX > size of existing SDA ;AN000; + MOV AX,CX ; then, AX := Size of existing Shared area ;AN000; + .ENDIF ; ;AN000; + .ENDIF ;AN000; + ; NB_FREE_BYTES := Number of bytes ;AN000; + MOV NB_FREE_BYTES,AX ; available for ;AN000; + ; building the TEMPORARY shared area ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Parse the command line parameters ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV BYTE PTR CS:[BP].SWITCHES,0 ; Init. the command line switches ;AN000; + PUSH CS ; Set ES to segment containing the PSP ;AN000; + POP ES ;AN000; + CALL PARSE_PARMS ; Set switches in the Temp. Shared Area ;AN000; + .IF C ; If error when parsing the command ;AN000; + .THEN ; line then, EXIT ;AN000; + JMP ERROR_EXIT ;AN000; + .ENDIF ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Parse the printer profile - Build the temporary Shared data area ;AN000; +;-------------------------------------------------------------------------------;AN000; + CALL LOAD_PROFILE ; Builds profile info in Temporary Shared ;AN000; + ; Data ;AN000; + .IF C ; If error when loading the profile ;AN000; + .THEN ; then, EXIT ;AN000; + JMP ERROR_EXIT ;AN000; + .ENDIF ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Check if /B was specified with a BLACK and WHITE printer:(invalid combination);AN000; +;-------------------------------------------------------------------------------;AN000; + .IF AND ;AN000; + .IF ;AN000; + .THEN ;AN000; + MOV AX,INVALID_B_SWITCH ; Error := /B invalid with B&W prt. ;AN000; + MOV CX,0 ; No substitution ;AN000; + CALL DISP_ERROR ; Display error message ;AN000; + JMP ERROR_EXIT ; and quit ;AN000; + .ENDIF ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; ;AN000; +; RELOCATE THE TEMPORARY SHARED DATA AREA AND THE SET OF REQUIRED PRINT MODULES ;AN000; +; ;AN000; +; (Discard the set of print modules not needed with the printer attached and ;AN000; +; discard all the code not used at print screen time). ;AN000; +; ;AN000; +; If GRAPHICS is already installed then, we copy the ;AN000; +; Shared Data area and the print modules over the previous ones installed in ;AN000; +; resident memory. ;AN000; +; ;AN000; +; If we are installed for the first time then, we copy those over the ;AN000; +; installation modules before we exit and stay resident. ;AN000; +; ;AN000; +; A temporaty Shared Data area is always created even if a resident one ;AN000; +; already exist (it is then, copied over), a set of print modules is recopied ;AN000; +; only if needed. ;AN000; +; ;AN000; +; NOTE: END_OF_RESIDENT_CODE points to the first location over which code ;AN000; +; may be relocated. After data or code is relocated, END_OF_RESIDENT_CODE;AN000; +; is updated and points to the next available location for copying code ;AN000; +; that will stay resident. ;AN000; +;-------------------------------------------------------------------------------;AN000; +;-------------------------------------------------------------------------------;AN000; +; Initialize the pointer to the next available location for resident code: ;AN000; +;-------------------------------------------------------------------------------;AN000; + .IF ; If not installed ;AN000; + .THEN ; then, ;AN000; + MOV END_OF_RESIDENT_CODE,OFFSET PRINT_MODULE_START ;AN000; + .ENDIF ; we make everything up to the print ;AN000; + ; modules resident code. ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Keep only the set of print modules that is needed: ;AN000; +;-------------------------------------------------------------------------------;AN000; + CALL COPY_PRINT_MODULES ; Updates END_OF_RESIDENT_CODE ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Replace the interrupt vectors and install the EGA dynamic area (if needed) ;AN000; +;-------------------------------------------------------------------------------;AN000; + .IF ; If not already installed ;AN000; + .THEN ; then, ;AN000; +;------Release evironment vector ;AN002; + CALL RELEASE_ENVIRONMENT ; release unneeded environment vector ;AN002; +;------Replace the interrupt vectors ;AN000; + MOV PRINT_SCREEN_ALLOWED,NO ; Disable Print Screen ;AN000; + CALL CHAIN_INTERRUPTS ; Replace the interrupt vectors ;AN000; + ; (END_OF_RESIDENT_CODE is updated) ;AN000; + CALL DET_HW_CONFIG ; Find what display adapter we got ;AN000; + .IF ;If EGA is present ;AN000; + .THEN ; then, ;AN000; + CALL INST_EGA_SAVE_AREA ; Install the EGA dynamic save area ;AN000; + .ENDIF ; (END_OF_RESIDENT_CODE is updated) ;AN000; +;------Calculate the size of the resident code ;AN000; + MOV DX,END_OF_RESIDENT_CODE ; DX := End of resident code ;AN000; + ADD DX,CS:[BP].SD_TOTAL_SIZE; Add size of Shared Data area ;AN000; + MOV CL,4 ; ;AN000; + SHR DX,CL ; convert to paragraphs ;AN000; + INC DX ; and add 1 ;AN000; +;------Set AX to DOS exit function call - (COPY_SHARED_DATA will exit to DOS) ;AN000; + MOV AH,31H ; Function call to terminate but stay ;AN000; + XOR AL,AL ; resident ;AN000; + .ELSE ;AN000; + MOV AH,4CH ; Function call to terminate ;AN000; + XOR AL,AL ; (EXIT to calling process) ;AN000; + .ENDIF ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Copy the temporary shared data area in the resident code ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV CX,CS:[BP].SD_TOTAL_SIZE; CX := MOVSB count for COPY_SHARED_DATA ;AN000; + MOV SI,BP ; DS:SI := Temporary Shared data area ;AN000; + PUSH RESIDENT_CODE_SEG ; ES:DI := Resident Shared data area: ;AN000; + POP ES ; ;AN000; + .IF ; If not installed ;AN000; + .THEN ; then, ;AN000; + MOV DI,END_OF_RESIDENT_CODE; DI := End of resident code ;AN000; + MOV BP,DI ; BP := New resident Shared data area ;AN000; + MOV SHARED_DATA_AREA_PTR,DI; Update pointer to resident Shar. area ;AN000; + .ELSE ; else, ;AN000; + MOV DI,SHARED_DATA_AREA_PTR ; DI := Existing Shared data area ;AN000; + MOV BP,DI ; BP = DI:= Existing Shared data area ;AN000; + .ENDIF ;AN000; + JMP COPY_SHARED_DATA ; Jump to proc that copies area in new ;AN000; + ; part of memory and exits to DOS ;AN000; +ERROR_EXIT: ;AN000; + .IF ; If we are already installed, re-enable ;AN000; + MOV ES,RESIDENT_CODE_SEG ; print screens ;AN000; + MOV ES:PRINT_SCREEN_ALLOWED,YES ;AN000; + .ENDIF ; ;AN000; + ; ;AN000; + MOV AH,4CH ; Function call to terminate ;AN000; + MOV AL,1 ; (EXIT to calling process) ;AN000; + INT 21H ;AN000; +GRAPHICS_INSTALL ENDP ;AN000; + ;AN000; +PAGE ;AN000; +;===============================================================================;AN000; +; ;AN000; +; INST_EGA_SAVE_AREA : INSTALL A DYNAMIC SAVE AREA FOR THE EGA PALETTE REGISTERS;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +; ;AN000; +; INPUT: DS = Data segment for our code ;AN000; +; END_OF_RESIDENT_CODE = Offset of the end of the resident code ;AN000; +; ;AN000; +; OUTPUT: END_OF_RESIDENT_CODE is updated to point to the end of the code ;AN000; +; that will stay resident. ;AN000; +; SAVE_AREA_PTR in BIOS segment is updated. ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +;; ;AN000; +;; Data Structures Referenced: ;AN000; +;; Shared Data Area ;AN000; +;; ;AN000; +;; Description: ;AN000; +;; ************* The EGA Dynamic Save Area will be built over top ;AN000; +;; ** NOTE ** of the profile loading modules (file GRLOAD.ASM) ;AN000; +;; ************* to avoid having to relocate this area just before ;AN000; +;; terminating. This is safe since the maximum memory used is ;AN000; +;; 288 bytes and the profile loading modules are MUCH larger than ;AN000; +;; this. So GRLOAD.ASM MUST be linked before GRINST.ASM and after ;AN000; +;; GRPRINT.ASM. ;AN000; +;; ;AN000; +;; BIOS will update the dynamic save area whenener it's aware the palette ;AN000; +;; registers have been updated. ;AN000; +;; ;AN000; +;; BIOS 4A8H BIOS SAVE EGA DYNAMIC ;AN000; +;; POINTER: POINTER TABLE SAVE AREA ;AN000; +;; ÚÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ (16 first bytes are the 16 ;AN000; +;; ³ *ÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ>³ ³ EGA palette registers) ;AN000; +;; ÀÄÄÄÄÄÄÄÄÙ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ;AN000; +;; ³ *ÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ>ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ . ;AN000; +;; ³ ³ . ;AN000; +;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ . 256 bytes ;AN000; +;; ³ ³ . ;AN000; +;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ . ;AN000; +;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; +;; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ;AN000; +;; ;AN000; +;; Called By: ;AN000; +;; GRAPHICS_INSTALL ;AN000; +;; ;AN000; +;; External Calls: ;AN000; +;; ;AN000; +;; Logic: ;AN000; +;; IF EGA Dynamic Save Area NOT established THEN ;AN000; +;; /* Required since default table is in ROM */ ;AN000; +;; IF Save Table is in ROM ;AN000; +;; Replicate all the Save Area Table in resident RAM just before ;AN000; +;; the Shared Data Area ;AN000; +;; ENDIF ;AN000; +;; Allocate 256 bytes for EGA Dynamic Save Area just before the ;AN000; +;; Shared Data Area ;AN000; +;; Update END_OF_RESIDENT_CODE ;AN000; +;; ENDIF ;AN000; +;; RETURN ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; + ;; ;AN000; +BIOS_SAVE_PTR EQU 4A8H ;; Offset of the BIOS Save Ptr area ;AN000; +SAVE_AREA_LEN EQU 8*4 ;; There are 8 pointers in the Save area ;AN000; +EGA_DYNAMIC_LEN EQU 256 ;; Length of the EGA dynamic save area ;AN000; +; Standard default colours for the Enhanced Graphics Adapter: (rgbRGB values) ;AN000; +; The following table is necessary in order to initialize the EGA DYNAMIC ;AN000; +; SAVE AREA when creating it. ;AN000; +EGA_DEFAULT_COLORS DB 00h ;; Black ;AN000; + DB 01h ;; Blue ;AN000; + DB 02h ;; Green ;AN000; + DB 03h ;; Cyan ;AN000; + DB 04h ;; Red ;AN000; + DB 05h ;; Magenta ;AN000; + DB 14h ;; Brown ;AN000; + DB 07h ;; White ;AN000; + DB 38h ;; Dark Grey ;AN000; + DB 39h ;; Light Blue ;AN000; + DB 3Ah ;; Light Green ;AN000; + DB 3Bh ;; Light Cyan ;AN000; + DB 3Ch ;; Light Red ;AN000; + DB 3Dh ;; Light Magenta ;AN000; + DB 3Eh ;; Yellow ;AN000; + DB 3Fh ;; Bright white ;AN000; + DB 00h ;; OVERSCAN register ;AN000; + ;AN000; +INST_EGA_SAVE_AREA PROC NEAR ;AN000; +PUSH AX ;AN000; +PUSH CX ;AN000; +PUSH DX ;AN000; +PUSH SI ;AN000; +PUSH DI ;AN000; +PUSH ES ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Get the BIOS save pointer table ;AN000; +;-------------------------------------------------------------------------------;AN000; +XOR AX,AX ; ES := segment 0 ;AN000; +MOV ES,AX ;AN000; +LES SI,ES:DWORD PTR BIOS_SAVE_PTR ; ES:[SI] =Current BIOS save table ;AN000; +.IF < EQ 0> AND ; IF the dynamic save are pointer is ;AN000; +.IF < EQ 0> ; null then, it's not defined ;AN000; +.THEN ; and we have to define it: ;AN000; + ;---------------------------------------------------------------------------;AN000; + ; The Dynamic EGA save area is NOT DEFINED: ;AN000; + ;---------------------------------------------------------------------------;AN000; + MOV BYTE PTR ES:[SI]+4,0FFH ; Try to write a byte in the table ;AN000; + PUSH AX ; (PUSH AX, POP AX used to create a ;AN000; + POP AX ; small delay) ;AN000; + .IF < NE 0FFH>;If we can't read our byte back then, ;AN000; + .THEN ; the Save Ptrs table is in ROM ;AN000; + ;------------------------------------------------------------------------;AN000; + ; The Save pointer table is in ROM; ;AN000; + ; Copy the BIOS save pointer table from ROM to within our .COM file ;AN000; + ;------------------------------------------------------------------------;AN000; + PUSH ES ; DS:SI := Offset of BIOS save ptrs table ;AN000; + POP DS ; ;AN000; + PUSH CS ; ES:DI := The next available location ;AN000; + POP ES ; for installing resident code ;AN000; + MOV DI,CS:END_OF_RESIDENT_CODE ; within our .COM file ;AN000; + MOV CS:OUR_SAVE_TAB_OFF,DI ; ;AN000; + MOV CX,SAVE_AREA_LEN ; CX := Length of the table to copy ;AN000; + REP MOVSB ; Replicate the Save Table ;AN000; + PUSH CS ;AN000; + POP DS ; Reestablish our data segment ;AN000; + ;------------------------------------------------------------------------;AN000; + ; Adjust END_OF_RESIDENT_CODE to the next offset available for copying ;AN000; + ; resident code and data. ;AN000; + ;------------------------------------------------------------------------;AN000; + ADD END_OF_RESIDENT_CODE,SAVE_AREA_LEN ;AN000; + ;------------------------------------------------------------------------;AN000; + ; Set the pointer in OUR Save ptr table to our EGA dynamic save area ;AN000; + ; which we create right after the Save pointer table. ;AN000; + ;------------------------------------------------------------------------;AN000; + MOV DI,OUR_SAVE_TAB_OFF ; DS:[DI] := Our BIOS save ptr tab ;AN000; + MOV AX,END_OF_RESIDENT_CODE; Store its offset ;AN000; + MOV DS:[DI]+4,AX ; ;AN000; + MOV WORD PTR DS:[DI]+6,DS ; Store its segment ;AN000; + ;------------------------------------------------------------------------;AN000; + ; Initialize our DYNAMIC SAVE AREA with the 16 standard EGA colors ;AN000; + ;------------------------------------------------------------------------;AN000; + ;AN000; + LEA SI,EGA_DEFAULT_COLORS ; DS:[SI] := EGA 16 Default colors ;AN000; + MOV DI,END_OF_RESIDENT_CODE ; ES:[DI] := DYNAMIC SAVE AREA ;AN000; + MOV CX,17 ; CX := Number of colors ;AN000; + REP MOVSB ; Initialize the Dynamic save area ;AN000; + ;------------------------------------------------------------------------;AN000; + ; Set the BIOS Save Pointer to our table of Save pointers: ;AN000; + ;------------------------------------------------------------------------;AN000; + CLI ;AN000; + XOR AX,AX ; ES:BIOS_SAVE_PTR := Our save table: ;AN000; + MOV ES,AX ;AN000; + MOV AX,OUR_SAVE_TAB_OFF ;AN000; + MOV ES:BIOS_SAVE_PTR,AX ;AN000; + MOV ES:BIOS_SAVE_PTR+2,DS ;AN000; + STI ;AN000; + .ELSE ; ELSE save pointer table is in RAM ;AN000; + ;------------------------------------------------------------------------;AN000; + ; ELSE, the BIOS save pointer table is in RAM: ;AN000; + ;------------------------------------------------------------------------;AN000; + ;------------------------------------------------------------------------;AN000; + ; Set the pointer in THEIR Save ptr table to OUR EGA dynamic save area ;AN000; + ;------------------------------------------------------------------------;AN000; + MOV WORD PTR ES:[SI]+6,DS ; ES:[SI] = The existing table in RAM ;AN000; + MOV AX,END_OF_RESIDENT_CODE ;AN000; + MOV ES:[SI]+4,AX ;AN000; + .ENDIF ; ENDIF save pointer table is in ROM ;AN000; + ;-----------------------------------------------------------------------------;AN000; + ; Adjust END_OF_RESIDENT_CODE to the next offset available for copying ;AN000; + ; resident code and data. ;AN000; + ;-----------------------------------------------------------------------------;AN000; + ADD END_OF_RESIDENT_CODE,EGA_DYNAMIC_LEN ;AN000; +.ENDIF ;AN000; +POP ES ;AN000; +POP DI ;AN000; +POP SI ;AN000; +POP DX ;AN000; +POP CX ;AN000; +POP AX ;AN000; + ;AN000; +RET ;AN000; +OUR_SAVE_TAB_OFF DW ? ;AN000; +INST_EGA_SAVE_AREA ENDP ;AN000; +PAGE ;AN000; +;===============================================================================;AN000; +; ;AN000; +; CHAIN_INTERRUPTS : INSTALL INT 5 AND INT 2FH VECTORS ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +; ;AN000; +; INPUT: DS = Data segment for our code ;AN000; +; END_OF_RESIDENT_CODE = Offset of the end of the resident code ;AN000; +; ;AN000; +; OUTPUT: OLD_INT_2FH (within INT_2FH_DRIVER) ;AN000; +; BIOS_INT_5H (within PRT_SCR module) ;AN000; +; END_OF_RESIDENT_CODE is updated to point to the end of the code ;AN000; +; that will stay resident. ;AN000; +; SAVE_AREA_PTR in BIOS segment is updated if an EGA adapter is found ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +;; ;AN000; +;; Data Structures Referenced: ;AN000; +;; Shared Data Area ;AN000; +;; ;AN000; +;; Description: ;AN000; +;; Install Interrupts 5 and 2FH. The old vectors are saved. ;AN000; +;; ;AN000; +;; Called By: ;AN000; +;; GRAPHICS_INSTALL ;AN000; +;; ;AN000; +;; External Calls: ;AN000; +;; DOS INT 21H Replace vector AH=25h ;AN000; +;; DOS INT 21H Get vector AH=35h ;AN000; +;; ;AN000; +;; Logic: ;AN000; +;; Save interrupt 5 vector in BIOS_INT_5H ;AN000; +;; Point interrupt 5 to PRT_SCR module ;AN000; +;; Save interrupt 2FH vector in BIOS_INT_2FH ;AN000; +;; Point interrupt 2FH to INT_2FH_DRIVER module ;AN000; +;; RETURN ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; + ;; ;AN000; +CHAIN_INTERRUPTS PROC NEAR ;; ;AN000; + PUSH ES ;AN000; + PUSH BX ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Replace INTERRUPT 5 vector ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV AH,35H ; Get vector for ;AN000; + MOV AL,5 ; interrupt 5 request ;AN000; + INT 21H ; Call DOS ;AN000; + ;AN000; + MOV BIOS_INT_5H,BX ; Save the old vector ;AN000; + MOV BIOS_INT_5H+2,ES ;AN000; + ;AN000; + MOV DX,OFFSET PRT_SCR ; DS:DX := Offset of our Print Screen ;AN000; + ;AN000; + MOV AH,25H ; Replace vector for ;AN000; + MOV AL,5 ; interrupt 5 request ;AN000; + INT 21H ; Call DOS ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Replace INTERRUPT 2FH vector ;AN000; +;-------------------------------------------------------------------------------;AN000; + MOV AH,35H ; Get vector for ;AN000; + MOV AL,2FH ; interrupt 2FH request ;AN000; + INT 21H ; Call DOS ;AN000; + ;AN000; + MOV WORD PTR OLD_INT_2FH,BX ; Save the old vector ;AN000; + MOV WORD PTR OLD_INT_2FH+2,ES ;AN000; + ;AN000; + MOV DX,OFFSET INT_2FH_DRIVER; DS:DX := Offset of our 2FH handler ;AN000; + ;AN000; + MOV AH,25H ; Replace vector for ;AN000; + MOV AL,2FH ; interrupt 2FH request ;AN000; + INT 21H ; Call DOS ;AN000; + ;AN000; + POP BX ;AN000; + POP ES ;AN000; + RET ;AN000; +CHAIN_INTERRUPTS ENDP ;AN000; + ;AN000; +;===============================================================================;AN000; +; ;AN000; +; COPY_PRINT_MODULES: COPY THE SET OF PRINT MODULES NEEDED OVER THE PREVIOUS ONE;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +; ;AN000; +; INPUT: BP = Offset of the temporary Shared Data area ;AN000; +; END_OF_RESIDENT_CODE = Location of the set of COLOR modules ;AN000; +; (if first time installed) ;AN000; +; CS:[BP].PRINTER_TYPE = Printer type NEEDED ;AN000; +; RESIDENT_CODE_SEG = Segment containing the resident code ;AN000; +; ;AN000; +; OUTPUT: END_OF_RESIDENT_CODE = End of the print modules IS UPDATED ;AN000; +; (If first time installed) ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +;; ;AN000; +;; Data Structures Referenced: ;AN000; +;; Control Variables ;AN000; +;; Shared Data Area ;AN000; +;; ;AN000; +;; Description: ;AN000; +;; This module trashes one set of print modules (Color or Black & White) ;AN000; +;; depending on the type of printer attached. Since the Shared Data ;AN000; +;; (resident version) will reside immediately after the print modules, ;AN000; +;; END_OF_RESIDENT_CODE will be set by this modules. ;AN000; +;; ;AN000; +;; The set of COLOR modules is already at the rigth located when installing ;AN000; +;; GRAPHICS for the first time. This is true since, the color modules are ;AN000; +;; linked before the black and white modules. ;AN000; +;; ;AN000; +;; Therefore, if we are installing GRAPHICS for the first time and we need ;AN000; +;; the color modules then, we do not need to relocate any print modules. ;AN000; +;; ;AN000; +;; When installing GRAPHICS again we first check what is the resident set, ;AN000; +;; we recopy a new set only if needed. ;AN000; +;; ;AN000; +;; Called By: ;AN000; +;; GRAPHICS_INSTALL ;AN000; +;; ;AN000; +;; Logic: ;AN000; +;; IF color printer THEN ;AN000; +;; SI := Offset of BW_PRINT_MODULES ;AN000; +;; ELSE ;AN000; +;; SI := Offset of COLOR_PRINT_MODULES ;AN000; +;; ENDIF ;AN000; +;; REP MOVSB ; Copy the set of modules ;AN000; +;; END_OF_RESIDENT_CODE := end of the set of modules ;AN000; +;; RETURN ;AN000; +;; ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +COPY_PRINT_MODULES PROC NEAR ;AN000; + PUSH AX ;AN000; + PUSH BX ;AN000; + PUSH CX ;AN000; + PUSH SI ;AN000; + PUSH DI ;AN000; + PUSH ES ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Determine if we need to relocate the set of print modules, if so, set the ;AN000; +; source address (DS:SI), the destination address (ES:DI) and the number of ;AN000; +; bytes to copy (CX). ;AN000; +;-------------------------------------------------------------------------------;AN000; + PUSH CS:RESIDENT_CODE_SEG ; ES := Segment containing the resident ;AN000; + POP ES ; code (Where to copy modules) ;AN000; + MOV DI,OFFSET PRINT_MODULE_START ; ES:[DI] := Resident print modules ;AN000; + ;AN000; + .IF ; IF not installed ;AN000; + .THEN ; THEN, ;AN000; + ; We relocate the print modules ;AN000; + ; at the end of the resident code: ;AN000; + ; (this is where the color set is) ;AN000; + .IF ; IF we don't want the color set ;AN000; + .THEN ; THEN, ;AN000; + MOV NEED_NEW_PRINT_MODULES,YES ; Say we need new modules ;AN000; + MOV SI,OFFSET PRINT_BW_APA ; DS:[SI] := Black and white modules;AN000; + MOV CX,LEN_OF_BW_MODULES ; CX := Length of B&W modules ;AN000; + .ENDIF ; ;AN000; + ;AN000; + .ELSE ; ELSE, (We are already installed) ;AN000; + MOV BX,SHARED_DATA_AREA_PTR ; BX := Offset of Shared Data area ;AN000; + MOV AL,ES:[BX].PRINTER_TYPE ; AL := Type of the resident set ;AN000; + .IF ; IF resident set is not the one ;AN000; + .THEN ; we need THEN, ;AN000; + MOV NEED_NEW_PRINT_MODULES,YES ; Say we need a new set. ;AN000; + .IF ; IF its color we need then, ;AN000; + MOV SI,OFFSET PRINT_COLOR ; DS:[SI] := Color set ;AN000; + MOV CX,LEN_OF_COLOR_MODULES ; CX := Length of color mod. ;AN000; + .ELSE ; ELSE ;AN000; + MOV SI,OFFSET PRINT_BW_APA ; DS:[SI] := B&W set ;AN000; + MOV CX,LEN_OF_BW_MODULES ; CX := Length of B&W mod. ;AN000; + .ENDIF ; ENDIF we need the color set ;AN000; + .ENDIF ; ENDIF we need a new set ;AN000; + .ENDIF ; ENDIF we are not installed ;AN000; + ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; If needed: Copy the required set of print modules ;AN000; +;-------------------------------------------------------------------------------;AN000; + .IF ;AN000; + .THEN ;AN000; + CLD ; Clear the direction flag ;AN000; + REP MOVSB ; Copy the set of print modules ;AN000; + .ENDIF ; ENDIF needs to copy the print modules ;AN000; + ;AN000; +;-------------------------------------------------------------------------------;AN000; +; Set END_OF_RESIDENT_CODE pointer to the end of the print modules: ;AN000; +; (Reserve enough space to store the larger set of modules on a ;AN000; +; subsequent install) ;AN000; +;-------------------------------------------------------------------------------;AN000; + .IF ; IF first time installed ;AN000; + .THEN ; THEN, ;AN000; + MOV CX,LEN_OF_COLOR_MODULES ; Adjust END_OF_RESIDENT_CODE to ;AN000; + .IF ; contains the larger set of modules. ;AN000; + .THEN ; ;AN000; + ADD END_OF_RESIDENT_CODE,LEN_OF_COLOR_MODULES ;AN000; + .ELSE ;AN000; + ADD END_OF_RESIDENT_CODE,LEN_OF_BW_MODULES ;AN000; + .ENDIF ; ;AN000; + .ENDIF ;AN000; + ;AN000; + POP ES ;AN000; + POP DI ;AN000; + POP SI ;AN000; + POP CX ;AN000; + POP BX ;AN000; + POP AX ;AN000; + RET ;AN000; +NEED_NEW_PRINT_MODULES DB NO ; True if print modules needed must be ;AN000; + ; copied over the other set of print ;AN000; + ; modules ;AN000; +COPY_PRINT_MODULES ENDP ;AN000; + ;AN002; +PAGE ;AN002; +;===============================================================================;AN002; +; ;AN002; +; PROCEDURE_NAME: RELEASE_ENVIRONMENT ;AN002; +; ;AN002; +; INPUT: None. ;AN002; +; ;AN002; +; OUTPUT: Environment vector released. ;AN002; +; ;AN002; +;-------------------------------------------------------------------------------;AN002; +RELEASE_ENVIRONMENT PROC NEAR ;AN002; + PUSH AX ; save regs ;AN002; + PUSH BX ;AN002; + PUSH ES ;AN002; + MOV AH,62H ; function for get the PSP segment ;AN002; + INT 21H ; invoke INT 21h ;AN002; + MOV ES,BX ; BX contains PSP segment - put in ES ;AN002; + MOV BX,WORD PTR ES:[2CH] ; get segment of environmental vector ;AN002; + MOV ES,BX ; place segment in ES for Free Memory ;AN002; + MOV AH,49H ; Free Allocated Memory function call ;AN002; + INT 21H ; invoke INT 21h ;AN002; + POP ES ; restore regs ;AN002; + POP BX ;AN002; + POP AX ;AN002; + RET ;AN002; +RELEASE_ENVIRONMENT ENDP ;AN002; + ;AN000; +PAGE ;AN000; +;===============================================================================;AN000; +; ;AN000; +; PROCEDURE_NAME: DISP_ERROR ;AN000; +; ;AN000; +; INPUT: AX := GRAPHICS message number (documented in GRMSG.EQU) ;AN000; +; CX := Number of substitutions (Needed by SYSDISPMSG) ;AN000; +; DS:[SI] := Substitution list (needed only if CX <> 0) ;AN000; +; ;AN000; +; OUTPUT: Error message is displayed on STANDARD ERROR OUTPUT (STDERR) ;AN000; +; ;AN000; +;-------------------------------------------------------------------------------;AN000; +DISP_ERROR PROC NEAR ;AN000; + PUSH BX ;AN000; + PUSH DI ;AN000; + PUSH SI ;AN000; + PUSH BP ;AN000; + ;AN000; + MOV BX,ERROR_DEVICE ; Issue message to standard error ;AN000; + XOR DL,DL ; No input ;AN000; + MOV DH,UTILITY_MSG_CLASS;It's one of our messages ;AN000; + CALL SYSDISPMSG ; display error message ;AN000; + ;AN000; + POP BP ;AN000; + POP SI ;AN000; + POP DI ;AN000; + POP BX ;AN000; + RET ;AN000; +DISP_ERROR ENDP ;AN000; + +include msgdcl.inc ;AN000; + ;AN000; +CODE ENDS ;AN000; + END ;AN000; -- cgit v1.2.3