diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/GRAPHICS/GRINST.ASM | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/CMD/GRAPHICS/GRINST.ASM')
| -rw-r--r-- | v4.0/src/CMD/GRAPHICS/GRINST.ASM | 973 |
1 files changed, 973 insertions, 0 deletions
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 @@ | |||
| 1 | PAGE ,132 ;AN000; | ||
| 2 | TITLE DOS - GRAPHICS Command - Installation Modules ;AN000; | ||
| 3 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 4 | ;; DOS - GRAPHICS Command | ||
| 5 | ;; (C) Copyright 1988 Microsoft | ||
| 6 | ;; ;AN000; | ||
| 7 | ;; File Name: GRINST.ASM ;AN000; | ||
| 8 | ;; ---------- ;AN000; | ||
| 9 | ;; ;AN000; | ||
| 10 | ;; Description: ;AN000; | ||
| 11 | ;; ------------ ;AN000; | ||
| 12 | ;; This file contains the installation modules for the ;AN000; | ||
| 13 | ;; GRAPHICS command. ;AN000; | ||
| 14 | ;; ;AN000; | ||
| 15 | ;; GRAPHICS_INSTALL is the main module. ;AN000; | ||
| 16 | ;; ;AN000; | ||
| 17 | ;; GRAPHICS_INSTALL calls modules in GRLOAD.ASM to load ;AN000; | ||
| 18 | ;; the GRAPHICS profile and GRPARMS.ASM to parse the command line. ;AN000; | ||
| 19 | ;; ;AN000; | ||
| 20 | ;; ;AN000; | ||
| 21 | ;; Documentation Reference: ;AN000; | ||
| 22 | ;; ------------------------ ;AN000; | ||
| 23 | ;; OASIS High Level Design ;AN000; | ||
| 24 | ;; OASIS GRAPHICS I1 Overview ;AN000; | ||
| 25 | ;; DOS 3.3 Message Retriever Interface Supplement. ;AN000; | ||
| 26 | ;; TUPPER I0 Document - PARSER HIGH LEVEL DESIGN REVIEW ;AN000; | ||
| 27 | ;; ;AN000; | ||
| 28 | ;; Procedures Contained in This File: ;AN000; | ||
| 29 | ;; ---------------------------------- ;AN000; | ||
| 30 | ;; GRAPHICS_INSTALL - Main installation module ;AN000; | ||
| 31 | ;; CHAIN_INTERRUPTS - Chain interrupts 5, 2F, EGA Save Pointers ;AN000; | ||
| 32 | ;; COPY_PRINT_MODULES - Throw away one set of print modules ;AN000; | ||
| 33 | ;; ;AN000; | ||
| 34 | ;; ;AN000; | ||
| 35 | ;; Include Files Required: ;AN000; | ||
| 36 | ;; ----------------------- ;AN000; | ||
| 37 | ;; GRLOAD.EXT - Externals for profile load ;AN000; | ||
| 38 | ;; GRLOAD2.EXT - Externals for profile load ;AN000; | ||
| 39 | ;; GRCTRL.EXT - Externals for print screen control ;AN000; | ||
| 40 | ;; GRPRINT.EXT - Externals for print modules ;AN000; | ||
| 41 | ;; GRCPSD.EXT - Externals for COPY_SHARED_DATA module ;AN000; | ||
| 42 | ;; GRPARMS.EXT - External for GRAPHICS command line parsing ;AN000; | ||
| 43 | ;; GRPARSE.EXT - External for DOS parser ;AN000; | ||
| 44 | ;; GRBWPRT.EXT - Externals for Black and white printing modules ;AN000; | ||
| 45 | ;; GRCOLPRT.EXT - Externals for color printing modules ;AN000; | ||
| 46 | ;; GRINT2FH.EXT - Externals for Interrupt 2Fh driver. ;AN000; | ||
| 47 | ;; ;AN000; | ||
| 48 | ;; GRMSG.EQU - Equates for the GRAPHICS error messages ;AN000; | ||
| 49 | ;; SYSMSG.INC - DOS message retriever ;AN000; | ||
| 50 | ;; ;AN000; | ||
| 51 | ;; GRSHAR.STR - Shared Data Area Structure ;AN000; | ||
| 52 | ;; ;AN000; | ||
| 53 | ;; STRUC.INC - Macros for using structured assembly language ;AN000; | ||
| 54 | ;; ;AN000; | ||
| 55 | ;; External Procedure References: ;AN000; | ||
| 56 | ;; ------------------------------ ;AN000; | ||
| 57 | ;; FROM FILE GRLOAD.ASM: ;AN000; | ||
| 58 | ;; LOAD_PROFILE - Main module for profile loading ;AN000; | ||
| 59 | ;; SYSPARSE - DOS system parser ;AN000; | ||
| 60 | ;; SYSDISPMSG - DOS message retriever ;AN000; | ||
| 61 | ;; ;AN000; | ||
| 62 | ;; Linkage Instructions: ;AN000; | ||
| 63 | ;; -------------------- ;AN000; | ||
| 64 | ;; Refer to GRAPHICS.ASM ;AN000; | ||
| 65 | ;; ;AN000; | ||
| 66 | ;; Change History: ;AN000; | ||
| 67 | ;; --------------- ;AN000; | ||
| 68 | ;; ;AN000; | ||
| 69 | ;; ;AN000; | ||
| 70 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 71 | ;; ;AN000; | ||
| 72 | CODE SEGMENT PUBLIC 'CODE' ;; ;AN000; | ||
| 73 | ASSUME CS:CODE,DS:CODE ;; ;AN000; | ||
| 74 | ;; ;AN000; | ||
| 75 | .XLIST ;; ;AN000; | ||
| 76 | INCLUDE GRSHAR.STR ;; Include the Shared data area structure;AN000; | ||
| 77 | INCLUDE SYSMSG.INC ;; Include DOS message retriever ;AN000; | ||
| 78 | INCLUDE STRUC.INC ;; Include macros - Structured Assembler ;AN000; | ||
| 79 | INCLUDE GRLOAD.EXT ;; Bring in external declarations ;AN000; | ||
| 80 | INCLUDE GRLOAD2.EXT ;; ;AN000; | ||
| 81 | INCLUDE GRLOAD3.EXT ;; ;AN000; | ||
| 82 | INCLUDE GRCTRL.EXT ;; ;AN000; | ||
| 83 | INCLUDE GRBWPRT.EXT ;; ;AN000; | ||
| 84 | INCLUDE GRCOLPRT.EXT ;; ;AN000; | ||
| 85 | INCLUDE GRCPSD.EXT ;; ;AN000; | ||
| 86 | INCLUDE GRINT2FH.EXT ;; ;AN000; | ||
| 87 | INCLUDE GRCTRL.EXT ;; ;AN000; | ||
| 88 | INCLUDE GRPARSE.EXT ;; ;AN000; | ||
| 89 | INCLUDE GRPARMS.EXT ;; ;AN000; | ||
| 90 | INCLUDE GRMSG.EQU ;; ;AN000; | ||
| 91 | ;; ;AN000; | ||
| 92 | MSG_UTILNAME <GRAPHICS> ;; Identify ourself to Message retriever.;AN000; | ||
| 93 | ;; Include messages ;AN000; | ||
| 94 | MSG_SERVICES <MSGDATA> ;; ;AN000; | ||
| 95 | MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg> ;; ;AN000; | ||
| 96 | MSG_SERVICES <GRAPHICS.CL1,GRAPHICS.CL2,GRAPHICS.CLA,GRAPHICS.CLB,GRAPHICS.CLC> ;AN000; | ||
| 97 | .LIST ;; ;AN000; | ||
| 98 | ;; ;AN000; | ||
| 99 | PUBLIC GRAPHICS_INSTALL ;; ;AN000; | ||
| 100 | PUBLIC TEMP_SHARED_DATA_PTR ;; ;AN000; | ||
| 101 | PUBLIC PRINTER_TYPE_PARM ;; ;AN000; | ||
| 102 | PUBLIC PRINTER_TYPE_LENGTH ;; ;AN000; | ||
| 103 | PUBLIC PROFILE_PATH ;; ;AN000; | ||
| 104 | PUBLIC PRINTBOX_ID_PTR ;; ;AN000; | ||
| 105 | PUBLIC PRINTBOX_ID_LENGTH ;; ;AN000; | ||
| 106 | PUBLIC DEFAULT_BOX ;; ;AN000; | ||
| 107 | PUBLIC LCD_BOX ;; ;AN000; | ||
| 108 | PUBLIC NB_FREE_BYTES ;; ;AN000; | ||
| 109 | PUBLIC SYSDISPMSG ;; ;AN000; | ||
| 110 | PUBLIC DISP_ERROR ;; ;AN000; | ||
| 111 | PUBLIC INSTALLED ;; ;AN000; | ||
| 112 | PUBLIC ERROR_DEVICE ;; ;AN000; | ||
| 113 | PUBLIC STDERR ;; ;AN000; | ||
| 114 | PUBLIC STDOUT ;; ;AN000; | ||
| 115 | PUBLIC RESIDENT_SHARED_DATA_SIZE ;; ;AN000; | ||
| 116 | ;; ;AN000; | ||
| 117 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 118 | ;; ;AN000; | ||
| 119 | ;; Install Variables ;AN000; | ||
| 120 | ;; ;AN000; | ||
| 121 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 122 | ;; ;AN000; | ||
| 123 | NO EQU 0 ;; ;AN000; | ||
| 124 | YES EQU 1 ;; ;AN000; | ||
| 125 | INSTALLED DB NO ;; YES if GRAPHICS already installed ;AN000; | ||
| 126 | ;; ;AN000; | ||
| 127 | ;; ;AN000; | ||
| 128 | BYTES_AVAIL_PSP_OFF EQU 6 ;; Word number 6 of the PSP is the ;AN000; | ||
| 129 | ;; number of bytes available in the ;AN000; | ||
| 130 | ;; current segment ;AN000; | ||
| 131 | ;; ;AN000; | ||
| 132 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 133 | ;; ;AN000; | ||
| 134 | ;; GRLOAD (PROFILE LOADING) INPUT PARMS: ;AN000; | ||
| 135 | ;; ;AN000; | ||
| 136 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 137 | PRINTER_TYPE_PARM DB "GRAPHICS",9 DUP(0) ; Printer type ;AN000; | ||
| 138 | ;; (default=GRAPHICS) ;AN000; | ||
| 139 | PRINTER_TYPE_LENGTH DB 17 ;; Printer type maximum length of ASCIIZ ;AN000; | ||
| 140 | PROFILE_PATH DB 128 DUP(0) ;; Profile name with full path ;AN000; | ||
| 141 | ;; (Max size for ASCIIZ is 128) ;AN000; | ||
| 142 | PRINTBOX_ID_PTR DW DEFAULT_BOX ;; Offset of ASCIIZ string containing ;AN000; | ||
| 143 | DEFAULT_BOX DB "STD",14 DUP(0); the printbox id. (DEFAULT = STD) ;AN000; | ||
| 144 | LCD_BOX DB "LCD",14 DUP(0); ASCIIZ string for the LCD printboxID;AN000; | ||
| 145 | PRINTBOX_ID_LENGTH DB 17 ;; Max. length for the printbox id. ;AN000; | ||
| 146 | ;; ASCIIZ string ;AN000; | ||
| 147 | NB_FREE_BYTES DW ? ;; Number of bytes available in our ;AN000; | ||
| 148 | ;; resident segment ;AN000; | ||
| 149 | RESIDENT_SHARED_DATA_SIZE DW ? ;; Size in bytes of the RESIDENT Shared ;AN000; | ||
| 150 | ;; data area (if GRAPHICS already ;AN000; | ||
| 151 | ;; installed). ;AN000; | ||
| 152 | END_OF_RESIDENT_CODE DW ? ;; Offset of the end of the code that ;AN000; | ||
| 153 | ;; has to be made resident. ;AN000; | ||
| 154 | TEMP_SHARED_DATA_PTR DW ? ;; Offset of the temporary Shared area ;AN000; | ||
| 155 | ;; ;AN000; | ||
| 156 | ERROR_DEVICE DW STDERR ;; Device DISP_ERROR will output ;AN000; | ||
| 157 | ;; messages to (STDERR or STDOUT) ;AN000; | ||
| 158 | PAGE ;AN000; | ||
| 159 | ;===============================================================================;AN000; | ||
| 160 | ; ;AN000; | ||
| 161 | ; GRAPHICS_INSTALL : INSTALL GRAPHICS.COM ;AN000; | ||
| 162 | ; ;AN000; | ||
| 163 | ;-------------------------------------------------------------------------------;AN000; | ||
| 164 | ; ;AN000; | ||
| 165 | ; INPUT: Command line parameters ;AN000; | ||
| 166 | ; GRAPHICS profile - A file describing printer characteristics and ;AN000; | ||
| 167 | ; attributes. ;AN000; | ||
| 168 | ; ;AN000; | ||
| 169 | ; OUTPUT: If first time invoked: ;AN000; | ||
| 170 | ; INT 5 VECTOR and INT 2FH VECTOR are replaced; only the required ;AN000; | ||
| 171 | ; code for printing the screen is made resident. ;AN000; | ||
| 172 | ; else, ;AN000; | ||
| 173 | ; The resident code is updated to reflect changes in printing ;AN000; | ||
| 174 | ; options. ;AN000; | ||
| 175 | ; ;AN000; | ||
| 176 | ;-------------------------------------------------------------------------------;AN000; | ||
| 177 | ;; ;AN000; | ||
| 178 | ;; DESCRIPTION: ;AN000; | ||
| 179 | ;; ;AN000; | ||
| 180 | ;; This module intalls GRAPHICS code and data. ;AN000; | ||
| 181 | ;; ;AN000; | ||
| 182 | ;; An INT 2FH driver is also installed. ;AN000; | ||
| 183 | ;; ;AN000; | ||
| 184 | ;; If this driver is already present then, we assume GRAPHICS was installed ;AN000; | ||
| 185 | ;; and do not install it again but, simply update the resident code. ;AN000; | ||
| 186 | ;; ;AN000; | ||
| 187 | ;; The resident code contains ONLY the code and data needed for Printing ;AN000; | ||
| 188 | ;; the screen. The code needed is determined according to the command line ;AN000; | ||
| 189 | ;; parameters and the information extracted from the printer profile. ;AN000; | ||
| 190 | ;; ;AN000; | ||
| 191 | ;; The printer profile is parsed according to the current hardware setting ;AN000; | ||
| 192 | ;; and also to the command line options. The information extracted from ;AN000; | ||
| 193 | ;; the profile is stored in a Data area shared between the installation ;AN000; | ||
| 194 | ;; process and the Print Screen process. ;AN000; | ||
| 195 | ;; ;AN000; | ||
| 196 | ;; A temporary Shared Data Area is FIRST built at the end of the .COM file ;AN000; | ||
| 197 | ;; Before building it, we verify that there is ;AN000; | ||
| 198 | ;; enough memory left in the current segment. If not, the installation ;AN000; | ||
| 199 | ;; process is aborted. ;AN000; | ||
| 200 | ;; ;AN000; | ||
| 201 | ;; This temporary Data area when completed will be copied over the ;AN000; | ||
| 202 | ;; installation code. Therefore, the file comprising GRAPHICS must be ;AN000; | ||
| 203 | ;; linked in a specific order with the installation modules being last. ;AN000; | ||
| 204 | ;; ;AN000; | ||
| 205 | ;; These modules will be overwritten by the Shared Data area and the EGA ;AN000; | ||
| 206 | ;; dynamic save area before we exit and stay resident. ;AN000; | ||
| 207 | ;; ;AN000; | ||
| 208 | ;; The end of the resident code is the end of the Shared Data area, anything ;AN000; | ||
| 209 | ;; else beyond that is not made resident. ;AN000; | ||
| 210 | ;; ;AN000; | ||
| 211 | ;; The pointer to the resident Shared Data area is declared within the ;AN000; | ||
| 212 | ;; Interrupt 2Fh driver. This pointer is initialized by the installation ;AN000; | ||
| 213 | ;; process and points to the shared data area at Print Screen time. ;AN000; | ||
| 214 | ;; ;AN000; | ||
| 215 | ;; Depending on the type of printer attached (i.e., Black and white or Color) ;AN000; | ||
| 216 | ;; only one set of modules is made resident during the installation. ;AN000; | ||
| 217 | ;; ;AN000; | ||
| 218 | ;; The set of print modules required is copied over the previous one at ;AN000; | ||
| 219 | ;; location "PRINT_MODULE_START". This location is declared within ;AN000; | ||
| 220 | ;; GRCOLPRT which must be linked before GRBWPRT ;AN000; | ||
| 221 | ;; ;AN000; | ||
| 222 | ;; When copying one of the 2 sets of print modules we reserve enough space ;AN000; | ||
| 223 | ;; for the larger of them. Therefore, if GRAPHICS is already installed but ;AN000; | ||
| 224 | ;; is reinvoked with a different printer type which needs a bigger set of ;AN000; | ||
| 225 | ;; modules: this new set of modules is simply recopied over the existing ;AN000; | ||
| 226 | ;; one in the resident code. ;AN000; | ||
| 227 | ;; ;AN000; | ||
| 228 | ;; The Shared Data area is copied rigth after the set of modules that we keep ;AN000; | ||
| 229 | ;; that is, over the unused set of modules. ;AN000; | ||
| 230 | ;; ;AN000; | ||
| 231 | ;; ;AN000; | ||
| 232 | ;-------------------------------------------------------------------------------;AN000; | ||
| 233 | ;; ;AN000; | ||
| 234 | ;; Register Conventions: ;AN000; | ||
| 235 | ;; BP - points to start of Temp Shared Data (Transiant code) ;AN000; | ||
| 236 | ;; ;AN000; | ||
| 237 | ;; Called By: ;AN000; | ||
| 238 | ;; Entry point for GRAPHICS command processing. ;AN000; | ||
| 239 | ;; ;AN000; | ||
| 240 | ;; External Calls: ;AN000; | ||
| 241 | ;; INT 2FH, LOAD_MESSAGES, LOAD_PROFILE, PARSE_PARMS ;AN000; | ||
| 242 | ;; CHAIN_INTERRUPTS, COPY_SHARED_DATA, DISPLAY_MESSAGE ;AN000; | ||
| 243 | ;; COPY_PRINT_MODULES ;AN000; | ||
| 244 | ;; ;AN000; | ||
| 245 | ;-------------------------------------------------------------------------------;AN000; | ||
| 246 | ;; ;AN000; | ||
| 247 | ;; LOGIC: ;AN000; | ||
| 248 | ;; Load the message retriever ;AN000; | ||
| 249 | ;; IF carry flag is set (incorrect DOS version) THEN ;AN000; | ||
| 250 | ;; Issue message (COMMON1) ;AN000; | ||
| 251 | ;; Exit ;AN000; | ||
| 252 | ;; ENDIF ;AN000; | ||
| 253 | ;; ;AN000; | ||
| 254 | ;; Get number of bytes available in the segment from PSP (word 6) ;AN000; | ||
| 255 | ;; /* This is needed since we construct a temporary Shared data area at the ;AN000; | ||
| 256 | ;; of the .COM file */ ;AN000; | ||
| 257 | ;; ;AN000; | ||
| 258 | ;; /* Build Shared Data in temporary area */ ;AN000; | ||
| 259 | ;; END_OF_RESIDENT_CODE := (end of .COM file) ;AN000; | ||
| 260 | ;; NB_FREE_BYTES := Number of bytes availables ;AN000; | ||
| 261 | ;; ;AN000; | ||
| 262 | ;; CALL PARSE_PARMS ;AN000; | ||
| 263 | ;; IF error THEN /* PARSE_PARMS will issue messages */ ;AN000; | ||
| 264 | ;; Exit ;AN000; | ||
| 265 | ;; ENDIF ;AN000; | ||
| 266 | ;; ;AN000; | ||
| 267 | ;; CALL LOAD_PROFILE ;AN000; | ||
| 268 | ;; IF profile errors THEN ;AN000; | ||
| 269 | ;; Exit /* LOAD_PROFILE will issue messages */ ;AN000; | ||
| 270 | ;; ENDIF ;AN000; | ||
| 271 | ;; ;AN000; | ||
| 272 | ;; Issue INT 2FH Install Check call (AX=1500H) ;AN000; | ||
| 273 | ;; /* INT 2FH returns ES:[DI] pointing to the shared data area */ ;AN000; | ||
| 274 | ;; IF already installed THEN ;AN000; | ||
| 275 | ;; THEN ;AN000; | ||
| 276 | ;; Move NO to PRINT_SCREEN_ALLOWED in resident Shared Data ;AN000; | ||
| 277 | ;; SHARED_DATA_AREA_PTR := DI ;AN000; | ||
| 278 | ;; ELSE ;AN000; | ||
| 279 | ;; MOV PRINT_SCREEN_ALLOWED,NO ;AN000; | ||
| 280 | ;; CALL CHAIN_INTERRUPTS /* Install INT 5 and INT 2FH vectors */ ;AN000; | ||
| 281 | ;; ES := Our segment ;AN000; | ||
| 282 | ;; ENDIF ;AN000; | ||
| 283 | ;; /* Keep only Print Black and White or Print Color: */ ;AN000; | ||
| 284 | ;; CALL COPY_PRINT_MODULES ;AN000; | ||
| 285 | ;; /* COPY_SHARED_DATA will terminate & stay resident */ ;AN000; | ||
| 286 | ;; Set up registers for copy & terminate call ;AN000; | ||
| 287 | ;; /* reserve enough memory to handle any printer in the profile*/ ;AN000; | ||
| 288 | ;; jump to COPY_SHARED_DATA module ;AN000; | ||
| 289 | ;; ELSE ;AN000; | ||
| 290 | ;; /* Shared Data has been built in place */ ;AN000; | ||
| 291 | ;; move YES to PRINT_SCREEN_ALLOWED ;AN000; | ||
| 292 | ;; Return to DOS ;AN000; | ||
| 293 | ;; ENDIF ;AN000; | ||
| 294 | ;; ;AN000; | ||
| 295 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 296 | GRAPHICS_INSTALL PROC NEAR ; ;AN000; | ||
| 297 | ;AN000; | ||
| 298 | ;-------------------------------------------------------------------------------;AN000; | ||
| 299 | ; Load the error messages ;AN000; | ||
| 300 | ;-------------------------------------------------------------------------------;AN000; | ||
| 301 | CALL SYSLOADMSG ; Load messages ;AN000; | ||
| 302 | .IF C ; If error when loading messages ;AN000; | ||
| 303 | .THEN ; then, ;AN000; | ||
| 304 | MOV CX,0 ; CX := No substitution in message ;AN000; | ||
| 305 | MOV AX,1 ; AX := msg nb. for "Invalid DOS version" ;AN000; | ||
| 306 | CALL DISP_ERROR ; Display error message ;AN000; | ||
| 307 | JMP ERROR_EXIT ; and quit ;AN000; | ||
| 308 | .ENDIF ;AN000; | ||
| 309 | ;AN000; | ||
| 310 | ;-------------------------------------------------------------------------------;AN000; | ||
| 311 | ; Get offset of where to build the TEMPORARY Shared Data area (always built) ;AN000; | ||
| 312 | ;-------------------------------------------------------------------------------;AN000; | ||
| 313 | MOV BP,OFFSET LIMIT ; Build it at the end of this .COM file ;AN000; | ||
| 314 | ; (LIMIT = the offset of the last byte ;AN000; | ||
| 315 | ; of the last .OBJ file linked with ;AN000; | ||
| 316 | ; GRAPHICS) ;AN000; | ||
| 317 | MOV TEMP_SHARED_DATA_PTR,BP ; ;AN000; | ||
| 318 | ;AN000; | ||
| 319 | ;-------------------------------------------------------------------------------;AN000; | ||
| 320 | ; Determine if GRAPHICS is already installed; get the resident segment value ;AN000; | ||
| 321 | ;-------------------------------------------------------------------------------;AN000; | ||
| 322 | MOV AH,PRT_SCR_2FH_NUMBER ; Call INT 2FH (the Multiplex interrupt) ;AN000; | ||
| 323 | XOR AL,AL ; for Print Screen handler ;AN000; | ||
| 324 | INT 2FH ; ;AN000; | ||
| 325 | ;AN000; | ||
| 326 | .IF <AH EQ 0FFH> ; IF already installed ;AN000; | ||
| 327 | .THEN ; then, ;AN000; | ||
| 328 | ;----------------------------------------------------------------------------;AN000; | ||
| 329 | ; GRAPHICS is already installed: Get pointer to the EXISTING Shared Data area;AN000; | ||
| 330 | ;----------------------------------------------------------------------------;AN000; | ||
| 331 | MOV INSTALLED,YES ; Say it's installed ;AN000; | ||
| 332 | MOV AX,ES ; Get the segment and offset of the ;AN000; | ||
| 333 | MOV SHARED_DATA_AREA_PTR,DI; resident Shared Data area. ;AN000; | ||
| 334 | MOV RESIDENT_CODE_SEG,AX ; (returned in ES:DI) ;AN000; | ||
| 335 | ; Disable print screen because we will ;AN000; | ||
| 336 | MOV ES:PRINT_SCREEN_ALLOWED,NO ; be updating the resident code. ;AN000; | ||
| 337 | .ELSE ; ELSE, not installed: ;AN000; | ||
| 338 | ;------------------------------------------------------------------------ ;AN000; | ||
| 339 | ; GRAPHICS is NOT installed: RESIDENT shared data area is in OUR segment ;AN000; | ||
| 340 | ;------------------------------------------------------------------------ ;AN000; | ||
| 341 | PUSH CS ; The Shared Data area will be in our ;AN000; | ||
| 342 | POP RESIDENT_CODE_SEG ; segment. ;AN000; | ||
| 343 | .ENDIF ;AN000; | ||
| 344 | ;AN000; | ||
| 345 | ;-------------------------------------------------------------------------------;AN000; | ||
| 346 | ; Determine in AX how many bytes are available for building the TEMPORARY SHARED;AN000; | ||
| 347 | ; DATA AREA: ;AN000; | ||
| 348 | ;-------------------------------------------------------------------------------;AN000; | ||
| 349 | MOV AX,ES:BYTES_AVAIL_PSP_OFF;AX := Number of bytes availables in ;AN000; | ||
| 350 | ; the current segment (as indicated in PSP);AN000; | ||
| 351 | .IF <AX B <OFFSET LIMIT>> ; If there is no bytes available past ;AN000; | ||
| 352 | .THEN ; the end of our .COM file ;AN000; | ||
| 353 | XOR AX,AX ; then, AX := 0 bytes available ;AN000; | ||
| 354 | .ELSE ; ;AN000; | ||
| 355 | SUB AX,OFFSET LIMIT ; else, AX := Number of FREE bytes ;AN000; | ||
| 356 | .ENDIF ; in this segment ;AN000; | ||
| 357 | ;AN000; | ||
| 358 | ;---AX = Number of bytes in our segment available for building the Temp Shared ;AN000; | ||
| 359 | ;---data area. ;AN000; | ||
| 360 | ;---IF ALREADY INSTALLED: Get the size of the existing Shared data area. ;AN000; | ||
| 361 | ;---Since the temporary shared data area will be copied over the resident ;AN000; | ||
| 362 | ;---shared data area, we do not want to build it any bigger than the one ;AN000; | ||
| 363 | ;---it will overwrite. Therefore we do not give to LOAD_PROFILE more space ;AN000; | ||
| 364 | ;---than the size of the existing Shared data area. ;AN000; | ||
| 365 | .IF <INSTALLED EQ YES> ; If already installed then, ;AN000; | ||
| 366 | .THEN ;AN000; | ||
| 367 | PUSH CS:RESIDENT_CODE_SEG ; ES:[DI] := Resident Shared data area ;AN000; | ||
| 368 | POP ES ; ;AN000; | ||
| 369 | MOV DI,SHARED_DATA_AREA_PTR ; ;AN000; | ||
| 370 | MOV CX,ES:[DI].SD_TOTAL_SIZE ; CX := Size of the existing Shared area ;AN000; | ||
| 371 | MOV RESIDENT_SHARED_DATA_SIZE,CX ; Save size for LOAD_PROFILE ;AN000; | ||
| 372 | .IF <AX A CX> ; If AX > size of existing SDA ;AN000; | ||
| 373 | MOV AX,CX ; then, AX := Size of existing Shared area ;AN000; | ||
| 374 | .ENDIF ; ;AN000; | ||
| 375 | .ENDIF ;AN000; | ||
| 376 | ; NB_FREE_BYTES := Number of bytes ;AN000; | ||
| 377 | MOV NB_FREE_BYTES,AX ; available for ;AN000; | ||
| 378 | ; building the TEMPORARY shared area ;AN000; | ||
| 379 | ;-------------------------------------------------------------------------------;AN000; | ||
| 380 | ; Parse the command line parameters ;AN000; | ||
| 381 | ;-------------------------------------------------------------------------------;AN000; | ||
| 382 | MOV BYTE PTR CS:[BP].SWITCHES,0 ; Init. the command line switches ;AN000; | ||
| 383 | PUSH CS ; Set ES to segment containing the PSP ;AN000; | ||
| 384 | POP ES ;AN000; | ||
| 385 | CALL PARSE_PARMS ; Set switches in the Temp. Shared Area ;AN000; | ||
| 386 | .IF C ; If error when parsing the command ;AN000; | ||
| 387 | .THEN ; line then, EXIT ;AN000; | ||
| 388 | JMP ERROR_EXIT ;AN000; | ||
| 389 | .ENDIF ;AN000; | ||
| 390 | ;AN000; | ||
| 391 | ;-------------------------------------------------------------------------------;AN000; | ||
| 392 | ; Parse the printer profile - Build the temporary Shared data area ;AN000; | ||
| 393 | ;-------------------------------------------------------------------------------;AN000; | ||
| 394 | CALL LOAD_PROFILE ; Builds profile info in Temporary Shared ;AN000; | ||
| 395 | ; Data ;AN000; | ||
| 396 | .IF C ; If error when loading the profile ;AN000; | ||
| 397 | .THEN ; then, EXIT ;AN000; | ||
| 398 | JMP ERROR_EXIT ;AN000; | ||
| 399 | .ENDIF ;AN000; | ||
| 400 | ;AN000; | ||
| 401 | ;-------------------------------------------------------------------------------;AN000; | ||
| 402 | ; Check if /B was specified with a BLACK and WHITE printer:(invalid combination);AN000; | ||
| 403 | ;-------------------------------------------------------------------------------;AN000; | ||
| 404 | .IF <CS:[BP].PRINTER_TYPE EQ BLACK_WHITE> AND ;AN000; | ||
| 405 | .IF <BIT CS:[BP].SWITCHES NZ BACKGROUND_SW> ;AN000; | ||
| 406 | .THEN ;AN000; | ||
| 407 | MOV AX,INVALID_B_SWITCH ; Error := /B invalid with B&W prt. ;AN000; | ||
| 408 | MOV CX,0 ; No substitution ;AN000; | ||
| 409 | CALL DISP_ERROR ; Display error message ;AN000; | ||
| 410 | JMP ERROR_EXIT ; and quit ;AN000; | ||
| 411 | .ENDIF ;AN000; | ||
| 412 | ;AN000; | ||
| 413 | ;-------------------------------------------------------------------------------;AN000; | ||
| 414 | ; ;AN000; | ||
| 415 | ; RELOCATE THE TEMPORARY SHARED DATA AREA AND THE SET OF REQUIRED PRINT MODULES ;AN000; | ||
| 416 | ; ;AN000; | ||
| 417 | ; (Discard the set of print modules not needed with the printer attached and ;AN000; | ||
| 418 | ; discard all the code not used at print screen time). ;AN000; | ||
| 419 | ; ;AN000; | ||
| 420 | ; If GRAPHICS is already installed then, we copy the ;AN000; | ||
| 421 | ; Shared Data area and the print modules over the previous ones installed in ;AN000; | ||
| 422 | ; resident memory. ;AN000; | ||
| 423 | ; ;AN000; | ||
| 424 | ; If we are installed for the first time then, we copy those over the ;AN000; | ||
| 425 | ; installation modules before we exit and stay resident. ;AN000; | ||
| 426 | ; ;AN000; | ||
| 427 | ; A temporaty Shared Data area is always created even if a resident one ;AN000; | ||
| 428 | ; already exist (it is then, copied over), a set of print modules is recopied ;AN000; | ||
| 429 | ; only if needed. ;AN000; | ||
| 430 | ; ;AN000; | ||
| 431 | ; NOTE: END_OF_RESIDENT_CODE points to the first location over which code ;AN000; | ||
| 432 | ; may be relocated. After data or code is relocated, END_OF_RESIDENT_CODE;AN000; | ||
| 433 | ; is updated and points to the next available location for copying code ;AN000; | ||
| 434 | ; that will stay resident. ;AN000; | ||
| 435 | ;-------------------------------------------------------------------------------;AN000; | ||
| 436 | ;-------------------------------------------------------------------------------;AN000; | ||
| 437 | ; Initialize the pointer to the next available location for resident code: ;AN000; | ||
| 438 | ;-------------------------------------------------------------------------------;AN000; | ||
| 439 | .IF <INSTALLED EQ NO> ; If not installed ;AN000; | ||
| 440 | .THEN ; then, ;AN000; | ||
| 441 | MOV END_OF_RESIDENT_CODE,OFFSET PRINT_MODULE_START ;AN000; | ||
| 442 | .ENDIF ; we make everything up to the print ;AN000; | ||
| 443 | ; modules resident code. ;AN000; | ||
| 444 | ;-------------------------------------------------------------------------------;AN000; | ||
| 445 | ; Keep only the set of print modules that is needed: ;AN000; | ||
| 446 | ;-------------------------------------------------------------------------------;AN000; | ||
| 447 | CALL COPY_PRINT_MODULES ; Updates END_OF_RESIDENT_CODE ;AN000; | ||
| 448 | ;-------------------------------------------------------------------------------;AN000; | ||
| 449 | ; Replace the interrupt vectors and install the EGA dynamic area (if needed) ;AN000; | ||
| 450 | ;-------------------------------------------------------------------------------;AN000; | ||
| 451 | .IF <INSTALLED EQ NO> ; If not already installed ;AN000; | ||
| 452 | .THEN ; then, ;AN000; | ||
| 453 | ;------Release evironment vector ;AN002; | ||
| 454 | CALL RELEASE_ENVIRONMENT ; release unneeded environment vector ;AN002; | ||
| 455 | ;------Replace the interrupt vectors ;AN000; | ||
| 456 | MOV PRINT_SCREEN_ALLOWED,NO ; Disable Print Screen ;AN000; | ||
| 457 | CALL CHAIN_INTERRUPTS ; Replace the interrupt vectors ;AN000; | ||
| 458 | ; (END_OF_RESIDENT_CODE is updated) ;AN000; | ||
| 459 | CALL DET_HW_CONFIG ; Find what display adapter we got ;AN000; | ||
| 460 | .IF <CS:[BP].HARDWARE_CONFIG EQ EGA>;If EGA is present ;AN000; | ||
| 461 | .THEN ; then, ;AN000; | ||
| 462 | CALL INST_EGA_SAVE_AREA ; Install the EGA dynamic save area ;AN000; | ||
| 463 | .ENDIF ; (END_OF_RESIDENT_CODE is updated) ;AN000; | ||
| 464 | ;------Calculate the size of the resident code ;AN000; | ||
| 465 | MOV DX,END_OF_RESIDENT_CODE ; DX := End of resident code ;AN000; | ||
| 466 | ADD DX,CS:[BP].SD_TOTAL_SIZE; Add size of Shared Data area ;AN000; | ||
| 467 | MOV CL,4 ; ;AN000; | ||
| 468 | SHR DX,CL ; convert to paragraphs ;AN000; | ||
| 469 | INC DX ; and add 1 ;AN000; | ||
| 470 | ;------Set AX to DOS exit function call - (COPY_SHARED_DATA will exit to DOS) ;AN000; | ||
| 471 | MOV AH,31H ; Function call to terminate but stay ;AN000; | ||
| 472 | XOR AL,AL ; resident ;AN000; | ||
| 473 | .ELSE ;AN000; | ||
| 474 | MOV AH,4CH ; Function call to terminate ;AN000; | ||
| 475 | XOR AL,AL ; (EXIT to calling process) ;AN000; | ||
| 476 | .ENDIF ;AN000; | ||
| 477 | ;AN000; | ||
| 478 | ;-------------------------------------------------------------------------------;AN000; | ||
| 479 | ; Copy the temporary shared data area in the resident code ;AN000; | ||
| 480 | ;-------------------------------------------------------------------------------;AN000; | ||
| 481 | MOV CX,CS:[BP].SD_TOTAL_SIZE; CX := MOVSB count for COPY_SHARED_DATA ;AN000; | ||
| 482 | MOV SI,BP ; DS:SI := Temporary Shared data area ;AN000; | ||
| 483 | PUSH RESIDENT_CODE_SEG ; ES:DI := Resident Shared data area: ;AN000; | ||
| 484 | POP ES ; ;AN000; | ||
| 485 | .IF <INSTALLED EQ NO> ; If not installed ;AN000; | ||
| 486 | .THEN ; then, ;AN000; | ||
| 487 | MOV DI,END_OF_RESIDENT_CODE; DI := End of resident code ;AN000; | ||
| 488 | MOV BP,DI ; BP := New resident Shared data area ;AN000; | ||
| 489 | MOV SHARED_DATA_AREA_PTR,DI; Update pointer to resident Shar. area ;AN000; | ||
| 490 | .ELSE ; else, ;AN000; | ||
| 491 | MOV DI,SHARED_DATA_AREA_PTR ; DI := Existing Shared data area ;AN000; | ||
| 492 | MOV BP,DI ; BP = DI:= Existing Shared data area ;AN000; | ||
| 493 | .ENDIF ;AN000; | ||
| 494 | JMP COPY_SHARED_DATA ; Jump to proc that copies area in new ;AN000; | ||
| 495 | ; part of memory and exits to DOS ;AN000; | ||
| 496 | ERROR_EXIT: ;AN000; | ||
| 497 | .IF <INSTALLED EQ YES> ; If we are already installed, re-enable ;AN000; | ||
| 498 | MOV ES,RESIDENT_CODE_SEG ; print screens ;AN000; | ||
| 499 | MOV ES:PRINT_SCREEN_ALLOWED,YES ;AN000; | ||
| 500 | .ENDIF ; ;AN000; | ||
| 501 | ; ;AN000; | ||
| 502 | MOV AH,4CH ; Function call to terminate ;AN000; | ||
| 503 | MOV AL,1 ; (EXIT to calling process) ;AN000; | ||
| 504 | INT 21H ;AN000; | ||
| 505 | GRAPHICS_INSTALL ENDP ;AN000; | ||
| 506 | ;AN000; | ||
| 507 | PAGE ;AN000; | ||
| 508 | ;===============================================================================;AN000; | ||
| 509 | ; ;AN000; | ||
| 510 | ; INST_EGA_SAVE_AREA : INSTALL A DYNAMIC SAVE AREA FOR THE EGA PALETTE REGISTERS;AN000; | ||
| 511 | ; ;AN000; | ||
| 512 | ;-------------------------------------------------------------------------------;AN000; | ||
| 513 | ; ;AN000; | ||
| 514 | ; INPUT: DS = Data segment for our code ;AN000; | ||
| 515 | ; END_OF_RESIDENT_CODE = Offset of the end of the resident code ;AN000; | ||
| 516 | ; ;AN000; | ||
| 517 | ; OUTPUT: END_OF_RESIDENT_CODE is updated to point to the end of the code ;AN000; | ||
| 518 | ; that will stay resident. ;AN000; | ||
| 519 | ; SAVE_AREA_PTR in BIOS segment is updated. ;AN000; | ||
| 520 | ; ;AN000; | ||
| 521 | ;-------------------------------------------------------------------------------;AN000; | ||
| 522 | ;; ;AN000; | ||
| 523 | ;; Data Structures Referenced: ;AN000; | ||
| 524 | ;; Shared Data Area ;AN000; | ||
| 525 | ;; ;AN000; | ||
| 526 | ;; Description: ;AN000; | ||
| 527 | ;; ************* The EGA Dynamic Save Area will be built over top ;AN000; | ||
| 528 | ;; ** NOTE ** of the profile loading modules (file GRLOAD.ASM) ;AN000; | ||
| 529 | ;; ************* to avoid having to relocate this area just before ;AN000; | ||
| 530 | ;; terminating. This is safe since the maximum memory used is ;AN000; | ||
| 531 | ;; 288 bytes and the profile loading modules are MUCH larger than ;AN000; | ||
| 532 | ;; this. So GRLOAD.ASM MUST be linked before GRINST.ASM and after ;AN000; | ||
| 533 | ;; GRPRINT.ASM. ;AN000; | ||
| 534 | ;; ;AN000; | ||
| 535 | ;; BIOS will update the dynamic save area whenener it's aware the palette ;AN000; | ||
| 536 | ;; registers have been updated. ;AN000; | ||
| 537 | ;; ;AN000; | ||
| 538 | ;; BIOS 4A8H BIOS SAVE EGA DYNAMIC ;AN000; | ||
| 539 | ;; POINTER: POINTER TABLE SAVE AREA ;AN000; | ||
| 540 | ;; ÚÄÄÄÄÄÄÄÄ¿ ÚÄÄÄÄÄÄÄÄÄÄÄÄ¿ (16 first bytes are the 16 ;AN000; | ||
| 541 | ;; ³ *ÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄ>³ ³ EGA palette registers) ;AN000; | ||
| 542 | ;; ÀÄÄÄÄÄÄÄÄÙ ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÚÄÄÄÄÄÄÄÄÄÄÄ¿ ;AN000; | ||
| 543 | ;; ³ *ÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ>ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 544 | ;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 545 | ;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 546 | ;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ . ;AN000; | ||
| 547 | ;; ³ ³ . ;AN000; | ||
| 548 | ;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ . 256 bytes ;AN000; | ||
| 549 | ;; ³ ³ . ;AN000; | ||
| 550 | ;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ . ;AN000; | ||
| 551 | ;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 552 | ;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 553 | ;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 554 | ;; ÃÄÄÄÄÄÄÄÄÄÄÄÄ´ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 555 | ;; ³ ³ ÃÄÄÄÄÄÄÄÄÄÄÄ´ ;AN000; | ||
| 556 | ;; ÀÄÄÄÄÄÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÄÄÄÄÙ ;AN000; | ||
| 557 | ;; ;AN000; | ||
| 558 | ;; Called By: ;AN000; | ||
| 559 | ;; GRAPHICS_INSTALL ;AN000; | ||
| 560 | ;; ;AN000; | ||
| 561 | ;; External Calls: ;AN000; | ||
| 562 | ;; ;AN000; | ||
| 563 | ;; Logic: ;AN000; | ||
| 564 | ;; IF EGA Dynamic Save Area NOT established THEN ;AN000; | ||
| 565 | ;; /* Required since default table is in ROM */ ;AN000; | ||
| 566 | ;; IF Save Table is in ROM ;AN000; | ||
| 567 | ;; Replicate all the Save Area Table in resident RAM just before ;AN000; | ||
| 568 | ;; the Shared Data Area ;AN000; | ||
| 569 | ;; ENDIF ;AN000; | ||
| 570 | ;; Allocate 256 bytes for EGA Dynamic Save Area just before the ;AN000; | ||
| 571 | ;; Shared Data Area ;AN000; | ||
| 572 | ;; Update END_OF_RESIDENT_CODE ;AN000; | ||
| 573 | ;; ENDIF ;AN000; | ||
| 574 | ;; RETURN ;AN000; | ||
| 575 | ;; ;AN000; | ||
| 576 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 577 | ;; ;AN000; | ||
| 578 | BIOS_SAVE_PTR EQU 4A8H ;; Offset of the BIOS Save Ptr area ;AN000; | ||
| 579 | SAVE_AREA_LEN EQU 8*4 ;; There are 8 pointers in the Save area ;AN000; | ||
| 580 | EGA_DYNAMIC_LEN EQU 256 ;; Length of the EGA dynamic save area ;AN000; | ||
| 581 | ; Standard default colours for the Enhanced Graphics Adapter: (rgbRGB values) ;AN000; | ||
| 582 | ; The following table is necessary in order to initialize the EGA DYNAMIC ;AN000; | ||
| 583 | ; SAVE AREA when creating it. ;AN000; | ||
| 584 | EGA_DEFAULT_COLORS DB 00h ;; Black ;AN000; | ||
| 585 | DB 01h ;; Blue ;AN000; | ||
| 586 | DB 02h ;; Green ;AN000; | ||
| 587 | DB 03h ;; Cyan ;AN000; | ||
| 588 | DB 04h ;; Red ;AN000; | ||
| 589 | DB 05h ;; Magenta ;AN000; | ||
| 590 | DB 14h ;; Brown ;AN000; | ||
| 591 | DB 07h ;; White ;AN000; | ||
| 592 | DB 38h ;; Dark Grey ;AN000; | ||
| 593 | DB 39h ;; Light Blue ;AN000; | ||
| 594 | DB 3Ah ;; Light Green ;AN000; | ||
| 595 | DB 3Bh ;; Light Cyan ;AN000; | ||
| 596 | DB 3Ch ;; Light Red ;AN000; | ||
| 597 | DB 3Dh ;; Light Magenta ;AN000; | ||
| 598 | DB 3Eh ;; Yellow ;AN000; | ||
| 599 | DB 3Fh ;; Bright white ;AN000; | ||
| 600 | DB 00h ;; OVERSCAN register ;AN000; | ||
| 601 | ;AN000; | ||
| 602 | INST_EGA_SAVE_AREA PROC NEAR ;AN000; | ||
| 603 | PUSH AX ;AN000; | ||
| 604 | PUSH CX ;AN000; | ||
| 605 | PUSH DX ;AN000; | ||
| 606 | PUSH SI ;AN000; | ||
| 607 | PUSH DI ;AN000; | ||
| 608 | PUSH ES ;AN000; | ||
| 609 | ;-------------------------------------------------------------------------------;AN000; | ||
| 610 | ; Get the BIOS save pointer table ;AN000; | ||
| 611 | ;-------------------------------------------------------------------------------;AN000; | ||
| 612 | XOR AX,AX ; ES := segment 0 ;AN000; | ||
| 613 | MOV ES,AX ;AN000; | ||
| 614 | LES SI,ES:DWORD PTR BIOS_SAVE_PTR ; ES:[SI] =Current BIOS save table ;AN000; | ||
| 615 | .IF <<WORD PTR ES:[SI]+4> EQ 0> AND ; IF the dynamic save are pointer is ;AN000; | ||
| 616 | .IF <<WORD PTR ES:[SI]+6> EQ 0> ; null then, it's not defined ;AN000; | ||
| 617 | .THEN ; and we have to define it: ;AN000; | ||
| 618 | ;---------------------------------------------------------------------------;AN000; | ||
| 619 | ; The Dynamic EGA save area is NOT DEFINED: ;AN000; | ||
| 620 | ;---------------------------------------------------------------------------;AN000; | ||
| 621 | MOV BYTE PTR ES:[SI]+4,0FFH ; Try to write a byte in the table ;AN000; | ||
| 622 | PUSH AX ; (PUSH AX, POP AX used to create a ;AN000; | ||
| 623 | POP AX ; small delay) ;AN000; | ||
| 624 | .IF <<WORD PTR ES:[SI]+4> NE 0FFH>;If we can't read our byte back then, ;AN000; | ||
| 625 | .THEN ; the Save Ptrs table is in ROM ;AN000; | ||
| 626 | ;------------------------------------------------------------------------;AN000; | ||
| 627 | ; The Save pointer table is in ROM; ;AN000; | ||
| 628 | ; Copy the BIOS save pointer table from ROM to within our .COM file ;AN000; | ||
| 629 | ;------------------------------------------------------------------------;AN000; | ||
| 630 | PUSH ES ; DS:SI := Offset of BIOS save ptrs table ;AN000; | ||
| 631 | POP DS ; ;AN000; | ||
| 632 | PUSH CS ; ES:DI := The next available location ;AN000; | ||
| 633 | POP ES ; for installing resident code ;AN000; | ||
| 634 | MOV DI,CS:END_OF_RESIDENT_CODE ; within our .COM file ;AN000; | ||
| 635 | MOV CS:OUR_SAVE_TAB_OFF,DI ; ;AN000; | ||
| 636 | MOV CX,SAVE_AREA_LEN ; CX := Length of the table to copy ;AN000; | ||
| 637 | REP MOVSB ; Replicate the Save Table ;AN000; | ||
| 638 | PUSH CS ;AN000; | ||
| 639 | POP DS ; Reestablish our data segment ;AN000; | ||
| 640 | ;------------------------------------------------------------------------;AN000; | ||
| 641 | ; Adjust END_OF_RESIDENT_CODE to the next offset available for copying ;AN000; | ||
| 642 | ; resident code and data. ;AN000; | ||
| 643 | ;------------------------------------------------------------------------;AN000; | ||
| 644 | ADD END_OF_RESIDENT_CODE,SAVE_AREA_LEN ;AN000; | ||
| 645 | ;------------------------------------------------------------------------;AN000; | ||
| 646 | ; Set the pointer in OUR Save ptr table to our EGA dynamic save area ;AN000; | ||
| 647 | ; which we create right after the Save pointer table. ;AN000; | ||
| 648 | ;------------------------------------------------------------------------;AN000; | ||
| 649 | MOV DI,OUR_SAVE_TAB_OFF ; DS:[DI] := Our BIOS save ptr tab ;AN000; | ||
| 650 | MOV AX,END_OF_RESIDENT_CODE; Store its offset ;AN000; | ||
| 651 | MOV DS:[DI]+4,AX ; ;AN000; | ||
| 652 | MOV WORD PTR DS:[DI]+6,DS ; Store its segment ;AN000; | ||
| 653 | ;------------------------------------------------------------------------;AN000; | ||
| 654 | ; Initialize our DYNAMIC SAVE AREA with the 16 standard EGA colors ;AN000; | ||
| 655 | ;------------------------------------------------------------------------;AN000; | ||
| 656 | ;AN000; | ||
| 657 | LEA SI,EGA_DEFAULT_COLORS ; DS:[SI] := EGA 16 Default colors ;AN000; | ||
| 658 | MOV DI,END_OF_RESIDENT_CODE ; ES:[DI] := DYNAMIC SAVE AREA ;AN000; | ||
| 659 | MOV CX,17 ; CX := Number of colors ;AN000; | ||
| 660 | REP MOVSB ; Initialize the Dynamic save area ;AN000; | ||
| 661 | ;------------------------------------------------------------------------;AN000; | ||
| 662 | ; Set the BIOS Save Pointer to our table of Save pointers: ;AN000; | ||
| 663 | ;------------------------------------------------------------------------;AN000; | ||
| 664 | CLI ;AN000; | ||
| 665 | XOR AX,AX ; ES:BIOS_SAVE_PTR := Our save table: ;AN000; | ||
| 666 | MOV ES,AX ;AN000; | ||
| 667 | MOV AX,OUR_SAVE_TAB_OFF ;AN000; | ||
| 668 | MOV ES:BIOS_SAVE_PTR,AX ;AN000; | ||
| 669 | MOV ES:BIOS_SAVE_PTR+2,DS ;AN000; | ||
| 670 | STI ;AN000; | ||
| 671 | .ELSE ; ELSE save pointer table is in RAM ;AN000; | ||
| 672 | ;------------------------------------------------------------------------;AN000; | ||
| 673 | ; ELSE, the BIOS save pointer table is in RAM: ;AN000; | ||
| 674 | ;------------------------------------------------------------------------;AN000; | ||
| 675 | ;------------------------------------------------------------------------;AN000; | ||
| 676 | ; Set the pointer in THEIR Save ptr table to OUR EGA dynamic save area ;AN000; | ||
| 677 | ;------------------------------------------------------------------------;AN000; | ||
| 678 | MOV WORD PTR ES:[SI]+6,DS ; ES:[SI] = The existing table in RAM ;AN000; | ||
| 679 | MOV AX,END_OF_RESIDENT_CODE ;AN000; | ||
| 680 | MOV ES:[SI]+4,AX ;AN000; | ||
| 681 | .ENDIF ; ENDIF save pointer table is in ROM ;AN000; | ||
| 682 | ;-----------------------------------------------------------------------------;AN000; | ||
| 683 | ; Adjust END_OF_RESIDENT_CODE to the next offset available for copying ;AN000; | ||
| 684 | ; resident code and data. ;AN000; | ||
| 685 | ;-----------------------------------------------------------------------------;AN000; | ||
| 686 | ADD END_OF_RESIDENT_CODE,EGA_DYNAMIC_LEN ;AN000; | ||
| 687 | .ENDIF ;AN000; | ||
| 688 | POP ES ;AN000; | ||
| 689 | POP DI ;AN000; | ||
| 690 | POP SI ;AN000; | ||
| 691 | POP DX ;AN000; | ||
| 692 | POP CX ;AN000; | ||
| 693 | POP AX ;AN000; | ||
| 694 | ;AN000; | ||
| 695 | RET ;AN000; | ||
| 696 | OUR_SAVE_TAB_OFF DW ? ;AN000; | ||
| 697 | INST_EGA_SAVE_AREA ENDP ;AN000; | ||
| 698 | PAGE ;AN000; | ||
| 699 | ;===============================================================================;AN000; | ||
| 700 | ; ;AN000; | ||
| 701 | ; CHAIN_INTERRUPTS : INSTALL INT 5 AND INT 2FH VECTORS ;AN000; | ||
| 702 | ; ;AN000; | ||
| 703 | ;-------------------------------------------------------------------------------;AN000; | ||
| 704 | ; ;AN000; | ||
| 705 | ; INPUT: DS = Data segment for our code ;AN000; | ||
| 706 | ; END_OF_RESIDENT_CODE = Offset of the end of the resident code ;AN000; | ||
| 707 | ; ;AN000; | ||
| 708 | ; OUTPUT: OLD_INT_2FH (within INT_2FH_DRIVER) ;AN000; | ||
| 709 | ; BIOS_INT_5H (within PRT_SCR module) ;AN000; | ||
| 710 | ; END_OF_RESIDENT_CODE is updated to point to the end of the code ;AN000; | ||
| 711 | ; that will stay resident. ;AN000; | ||
| 712 | ; SAVE_AREA_PTR in BIOS segment is updated if an EGA adapter is found ;AN000; | ||
| 713 | ; ;AN000; | ||
| 714 | ;-------------------------------------------------------------------------------;AN000; | ||
| 715 | ;; ;AN000; | ||
| 716 | ;; Data Structures Referenced: ;AN000; | ||
| 717 | ;; Shared Data Area ;AN000; | ||
| 718 | ;; ;AN000; | ||
| 719 | ;; Description: ;AN000; | ||
| 720 | ;; Install Interrupts 5 and 2FH. The old vectors are saved. ;AN000; | ||
| 721 | ;; ;AN000; | ||
| 722 | ;; Called By: ;AN000; | ||
| 723 | ;; GRAPHICS_INSTALL ;AN000; | ||
| 724 | ;; ;AN000; | ||
| 725 | ;; External Calls: ;AN000; | ||
| 726 | ;; DOS INT 21H Replace vector AH=25h ;AN000; | ||
| 727 | ;; DOS INT 21H Get vector AH=35h ;AN000; | ||
| 728 | ;; ;AN000; | ||
| 729 | ;; Logic: ;AN000; | ||
| 730 | ;; Save interrupt 5 vector in BIOS_INT_5H ;AN000; | ||
| 731 | ;; Point interrupt 5 to PRT_SCR module ;AN000; | ||
| 732 | ;; Save interrupt 2FH vector in BIOS_INT_2FH ;AN000; | ||
| 733 | ;; Point interrupt 2FH to INT_2FH_DRIVER module ;AN000; | ||
| 734 | ;; RETURN ;AN000; | ||
| 735 | ;; ;AN000; | ||
| 736 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 737 | ;; ;AN000; | ||
| 738 | CHAIN_INTERRUPTS PROC NEAR ;; ;AN000; | ||
| 739 | PUSH ES ;AN000; | ||
| 740 | PUSH BX ;AN000; | ||
| 741 | ;AN000; | ||
| 742 | ;-------------------------------------------------------------------------------;AN000; | ||
| 743 | ; Replace INTERRUPT 5 vector ;AN000; | ||
| 744 | ;-------------------------------------------------------------------------------;AN000; | ||
| 745 | MOV AH,35H ; Get vector for ;AN000; | ||
| 746 | MOV AL,5 ; interrupt 5 request ;AN000; | ||
| 747 | INT 21H ; Call DOS ;AN000; | ||
| 748 | ;AN000; | ||
| 749 | MOV BIOS_INT_5H,BX ; Save the old vector ;AN000; | ||
| 750 | MOV BIOS_INT_5H+2,ES ;AN000; | ||
| 751 | ;AN000; | ||
| 752 | MOV DX,OFFSET PRT_SCR ; DS:DX := Offset of our Print Screen ;AN000; | ||
| 753 | ;AN000; | ||
| 754 | MOV AH,25H ; Replace vector for ;AN000; | ||
| 755 | MOV AL,5 ; interrupt 5 request ;AN000; | ||
| 756 | INT 21H ; Call DOS ;AN000; | ||
| 757 | ;AN000; | ||
| 758 | ;-------------------------------------------------------------------------------;AN000; | ||
| 759 | ; Replace INTERRUPT 2FH vector ;AN000; | ||
| 760 | ;-------------------------------------------------------------------------------;AN000; | ||
| 761 | MOV AH,35H ; Get vector for ;AN000; | ||
| 762 | MOV AL,2FH ; interrupt 2FH request ;AN000; | ||
| 763 | INT 21H ; Call DOS ;AN000; | ||
| 764 | ;AN000; | ||
| 765 | MOV WORD PTR OLD_INT_2FH,BX ; Save the old vector ;AN000; | ||
| 766 | MOV WORD PTR OLD_INT_2FH+2,ES ;AN000; | ||
| 767 | ;AN000; | ||
| 768 | MOV DX,OFFSET INT_2FH_DRIVER; DS:DX := Offset of our 2FH handler ;AN000; | ||
| 769 | ;AN000; | ||
| 770 | MOV AH,25H ; Replace vector for ;AN000; | ||
| 771 | MOV AL,2FH ; interrupt 2FH request ;AN000; | ||
| 772 | INT 21H ; Call DOS ;AN000; | ||
| 773 | ;AN000; | ||
| 774 | POP BX ;AN000; | ||
| 775 | POP ES ;AN000; | ||
| 776 | RET ;AN000; | ||
| 777 | CHAIN_INTERRUPTS ENDP ;AN000; | ||
| 778 | ;AN000; | ||
| 779 | ;===============================================================================;AN000; | ||
| 780 | ; ;AN000; | ||
| 781 | ; COPY_PRINT_MODULES: COPY THE SET OF PRINT MODULES NEEDED OVER THE PREVIOUS ONE;AN000; | ||
| 782 | ; ;AN000; | ||
| 783 | ;-------------------------------------------------------------------------------;AN000; | ||
| 784 | ; ;AN000; | ||
| 785 | ; INPUT: BP = Offset of the temporary Shared Data area ;AN000; | ||
| 786 | ; END_OF_RESIDENT_CODE = Location of the set of COLOR modules ;AN000; | ||
| 787 | ; (if first time installed) ;AN000; | ||
| 788 | ; CS:[BP].PRINTER_TYPE = Printer type NEEDED ;AN000; | ||
| 789 | ; RESIDENT_CODE_SEG = Segment containing the resident code ;AN000; | ||
| 790 | ; ;AN000; | ||
| 791 | ; OUTPUT: END_OF_RESIDENT_CODE = End of the print modules IS UPDATED ;AN000; | ||
| 792 | ; (If first time installed) ;AN000; | ||
| 793 | ; ;AN000; | ||
| 794 | ;-------------------------------------------------------------------------------;AN000; | ||
| 795 | ;; ;AN000; | ||
| 796 | ;; Data Structures Referenced: ;AN000; | ||
| 797 | ;; Control Variables ;AN000; | ||
| 798 | ;; Shared Data Area ;AN000; | ||
| 799 | ;; ;AN000; | ||
| 800 | ;; Description: ;AN000; | ||
| 801 | ;; This module trashes one set of print modules (Color or Black & White) ;AN000; | ||
| 802 | ;; depending on the type of printer attached. Since the Shared Data ;AN000; | ||
| 803 | ;; (resident version) will reside immediately after the print modules, ;AN000; | ||
| 804 | ;; END_OF_RESIDENT_CODE will be set by this modules. ;AN000; | ||
| 805 | ;; ;AN000; | ||
| 806 | ;; The set of COLOR modules is already at the rigth located when installing ;AN000; | ||
| 807 | ;; GRAPHICS for the first time. This is true since, the color modules are ;AN000; | ||
| 808 | ;; linked before the black and white modules. ;AN000; | ||
| 809 | ;; ;AN000; | ||
| 810 | ;; Therefore, if we are installing GRAPHICS for the first time and we need ;AN000; | ||
| 811 | ;; the color modules then, we do not need to relocate any print modules. ;AN000; | ||
| 812 | ;; ;AN000; | ||
| 813 | ;; When installing GRAPHICS again we first check what is the resident set, ;AN000; | ||
| 814 | ;; we recopy a new set only if needed. ;AN000; | ||
| 815 | ;; ;AN000; | ||
| 816 | ;; Called By: ;AN000; | ||
| 817 | ;; GRAPHICS_INSTALL ;AN000; | ||
| 818 | ;; ;AN000; | ||
| 819 | ;; Logic: ;AN000; | ||
| 820 | ;; IF color printer THEN ;AN000; | ||
| 821 | ;; SI := Offset of BW_PRINT_MODULES ;AN000; | ||
| 822 | ;; ELSE ;AN000; | ||
| 823 | ;; SI := Offset of COLOR_PRINT_MODULES ;AN000; | ||
| 824 | ;; ENDIF ;AN000; | ||
| 825 | ;; REP MOVSB ; Copy the set of modules ;AN000; | ||
| 826 | ;; END_OF_RESIDENT_CODE := end of the set of modules ;AN000; | ||
| 827 | ;; RETURN ;AN000; | ||
| 828 | ;; ;AN000; | ||
| 829 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; | ||
| 830 | COPY_PRINT_MODULES PROC NEAR ;AN000; | ||
| 831 | PUSH AX ;AN000; | ||
| 832 | PUSH BX ;AN000; | ||
| 833 | PUSH CX ;AN000; | ||
| 834 | PUSH SI ;AN000; | ||
| 835 | PUSH DI ;AN000; | ||
| 836 | PUSH ES ;AN000; | ||
| 837 | ;AN000; | ||
| 838 | ;-------------------------------------------------------------------------------;AN000; | ||
| 839 | ; Determine if we need to relocate the set of print modules, if so, set the ;AN000; | ||
| 840 | ; source address (DS:SI), the destination address (ES:DI) and the number of ;AN000; | ||
| 841 | ; bytes to copy (CX). ;AN000; | ||
| 842 | ;-------------------------------------------------------------------------------;AN000; | ||
| 843 | PUSH CS:RESIDENT_CODE_SEG ; ES := Segment containing the resident ;AN000; | ||
| 844 | POP ES ; code (Where to copy modules) ;AN000; | ||
| 845 | MOV DI,OFFSET PRINT_MODULE_START ; ES:[DI] := Resident print modules ;AN000; | ||
| 846 | ;AN000; | ||
| 847 | .IF <INSTALLED EQ NO> ; IF not installed ;AN000; | ||
| 848 | .THEN ; THEN, ;AN000; | ||
| 849 | ; We relocate the print modules ;AN000; | ||
| 850 | ; at the end of the resident code: ;AN000; | ||
| 851 | ; (this is where the color set is) ;AN000; | ||
| 852 | .IF <CS:[BP].PRINTER_TYPE EQ BLACK_WHITE> ; IF we don't want the color set ;AN000; | ||
| 853 | .THEN ; THEN, ;AN000; | ||
| 854 | MOV NEED_NEW_PRINT_MODULES,YES ; Say we need new modules ;AN000; | ||
| 855 | MOV SI,OFFSET PRINT_BW_APA ; DS:[SI] := Black and white modules;AN000; | ||
| 856 | MOV CX,LEN_OF_BW_MODULES ; CX := Length of B&W modules ;AN000; | ||
| 857 | .ENDIF ; ;AN000; | ||
| 858 | ;AN000; | ||
| 859 | .ELSE ; ELSE, (We are already installed) ;AN000; | ||
| 860 | MOV BX,SHARED_DATA_AREA_PTR ; BX := Offset of Shared Data area ;AN000; | ||
| 861 | MOV AL,ES:[BX].PRINTER_TYPE ; AL := Type of the resident set ;AN000; | ||
| 862 | .IF <AL NE CS:[BP].PRINTER_TYPE> ; IF resident set is not the one ;AN000; | ||
| 863 | .THEN ; we need THEN, ;AN000; | ||
| 864 | MOV NEED_NEW_PRINT_MODULES,YES ; Say we need a new set. ;AN000; | ||
| 865 | .IF <CS:[BP].PRINTER_TYPE EQ COLOR>; IF its color we need then, ;AN000; | ||
| 866 | MOV SI,OFFSET PRINT_COLOR ; DS:[SI] := Color set ;AN000; | ||
| 867 | MOV CX,LEN_OF_COLOR_MODULES ; CX := Length of color mod. ;AN000; | ||
| 868 | .ELSE ; ELSE ;AN000; | ||
| 869 | MOV SI,OFFSET PRINT_BW_APA ; DS:[SI] := B&W set ;AN000; | ||
| 870 | MOV CX,LEN_OF_BW_MODULES ; CX := Length of B&W mod. ;AN000; | ||
| 871 | .ENDIF ; ENDIF we need the color set ;AN000; | ||
| 872 | .ENDIF ; ENDIF we need a new set ;AN000; | ||
| 873 | .ENDIF ; ENDIF we are not installed ;AN000; | ||
| 874 | ;AN000; | ||
| 875 | ;AN000; | ||
| 876 | ;-------------------------------------------------------------------------------;AN000; | ||
| 877 | ; If needed: Copy the required set of print modules ;AN000; | ||
| 878 | ;-------------------------------------------------------------------------------;AN000; | ||
| 879 | .IF <NEED_NEW_PRINT_MODULES EQ YES> ;AN000; | ||
| 880 | .THEN ;AN000; | ||
| 881 | CLD ; Clear the direction flag ;AN000; | ||
| 882 | REP MOVSB ; Copy the set of print modules ;AN000; | ||
| 883 | .ENDIF ; ENDIF needs to copy the print modules ;AN000; | ||
| 884 | ;AN000; | ||
| 885 | ;-------------------------------------------------------------------------------;AN000; | ||
| 886 | ; Set END_OF_RESIDENT_CODE pointer to the end of the print modules: ;AN000; | ||
| 887 | ; (Reserve enough space to store the larger set of modules on a ;AN000; | ||
| 888 | ; subsequent install) ;AN000; | ||
| 889 | ;-------------------------------------------------------------------------------;AN000; | ||
| 890 | .IF <INSTALLED EQ NO> ; IF first time installed ;AN000; | ||
| 891 | .THEN ; THEN, ;AN000; | ||
| 892 | MOV CX,LEN_OF_COLOR_MODULES ; Adjust END_OF_RESIDENT_CODE to ;AN000; | ||
| 893 | .IF <CX G LEN_OF_BW_MODULES> ; contains the larger set of modules. ;AN000; | ||
| 894 | .THEN ; ;AN000; | ||
| 895 | ADD END_OF_RESIDENT_CODE,LEN_OF_COLOR_MODULES ;AN000; | ||
| 896 | .ELSE ;AN000; | ||
| 897 | ADD END_OF_RESIDENT_CODE,LEN_OF_BW_MODULES ;AN000; | ||
| 898 | .ENDIF ; ;AN000; | ||
| 899 | .ENDIF ;AN000; | ||
| 900 | ;AN000; | ||
| 901 | POP ES ;AN000; | ||
| 902 | POP DI ;AN000; | ||
| 903 | POP SI ;AN000; | ||
| 904 | POP CX ;AN000; | ||
| 905 | POP BX ;AN000; | ||
| 906 | POP AX ;AN000; | ||
| 907 | RET ;AN000; | ||
| 908 | NEED_NEW_PRINT_MODULES DB NO ; True if print modules needed must be ;AN000; | ||
| 909 | ; copied over the other set of print ;AN000; | ||
| 910 | ; modules ;AN000; | ||
| 911 | COPY_PRINT_MODULES ENDP ;AN000; | ||
| 912 | ;AN002; | ||
| 913 | PAGE ;AN002; | ||
| 914 | ;===============================================================================;AN002; | ||
| 915 | ; ;AN002; | ||
| 916 | ; PROCEDURE_NAME: RELEASE_ENVIRONMENT ;AN002; | ||
| 917 | ; ;AN002; | ||
| 918 | ; INPUT: None. ;AN002; | ||
| 919 | ; ;AN002; | ||
| 920 | ; OUTPUT: Environment vector released. ;AN002; | ||
| 921 | ; ;AN002; | ||
| 922 | ;-------------------------------------------------------------------------------;AN002; | ||
| 923 | RELEASE_ENVIRONMENT PROC NEAR ;AN002; | ||
| 924 | PUSH AX ; save regs ;AN002; | ||
| 925 | PUSH BX ;AN002; | ||
| 926 | PUSH ES ;AN002; | ||
| 927 | MOV AH,62H ; function for get the PSP segment ;AN002; | ||
| 928 | INT 21H ; invoke INT 21h ;AN002; | ||
| 929 | MOV ES,BX ; BX contains PSP segment - put in ES ;AN002; | ||
| 930 | MOV BX,WORD PTR ES:[2CH] ; get segment of environmental vector ;AN002; | ||
| 931 | MOV ES,BX ; place segment in ES for Free Memory ;AN002; | ||
| 932 | MOV AH,49H ; Free Allocated Memory function call ;AN002; | ||
| 933 | INT 21H ; invoke INT 21h ;AN002; | ||
| 934 | POP ES ; restore regs ;AN002; | ||
| 935 | POP BX ;AN002; | ||
| 936 | POP AX ;AN002; | ||
| 937 | RET ;AN002; | ||
| 938 | RELEASE_ENVIRONMENT ENDP ;AN002; | ||
| 939 | ;AN000; | ||
| 940 | PAGE ;AN000; | ||
| 941 | ;===============================================================================;AN000; | ||
| 942 | ; ;AN000; | ||
| 943 | ; PROCEDURE_NAME: DISP_ERROR ;AN000; | ||
| 944 | ; ;AN000; | ||
| 945 | ; INPUT: AX := GRAPHICS message number (documented in GRMSG.EQU) ;AN000; | ||
| 946 | ; CX := Number of substitutions (Needed by SYSDISPMSG) ;AN000; | ||
| 947 | ; DS:[SI] := Substitution list (needed only if CX <> 0) ;AN000; | ||
| 948 | ; ;AN000; | ||
| 949 | ; OUTPUT: Error message is displayed on STANDARD ERROR OUTPUT (STDERR) ;AN000; | ||
| 950 | ; ;AN000; | ||
| 951 | ;-------------------------------------------------------------------------------;AN000; | ||
| 952 | DISP_ERROR PROC NEAR ;AN000; | ||
| 953 | PUSH BX ;AN000; | ||
| 954 | PUSH DI ;AN000; | ||
| 955 | PUSH SI ;AN000; | ||
| 956 | PUSH BP ;AN000; | ||
| 957 | ;AN000; | ||
| 958 | MOV BX,ERROR_DEVICE ; Issue message to standard error ;AN000; | ||
| 959 | XOR DL,DL ; No input ;AN000; | ||
| 960 | MOV DH,UTILITY_MSG_CLASS;It's one of our messages ;AN000; | ||
| 961 | CALL SYSDISPMSG ; display error message ;AN000; | ||
| 962 | ;AN000; | ||
| 963 | POP BP ;AN000; | ||
| 964 | POP SI ;AN000; | ||
| 965 | POP DI ;AN000; | ||
| 966 | POP BX ;AN000; | ||
| 967 | RET ;AN000; | ||
| 968 | DISP_ERROR ENDP ;AN000; | ||
| 969 | |||
| 970 | include msgdcl.inc ;AN000; | ||
| 971 | ;AN000; | ||
| 972 | CODE ENDS ;AN000; | ||
| 973 | END ;AN000; | ||