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