summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/GRAPHICS/GRINST.ASM
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/GRAPHICS/GRINST.ASM
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/GRAPHICS/GRINST.ASM')
-rw-r--r--v4.0/src/CMD/GRAPHICS/GRINST.ASM973
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;
72CODE 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;
92MSG_UTILNAME <GRAPHICS> ;; Identify ourself to Message retriever.;AN000;
93 ;; Include messages ;AN000;
94MSG_SERVICES <MSGDATA> ;; ;AN000;
95MSG_SERVICES <LOADmsg,DISPLAYmsg,CHARmsg,NUMmsg> ;; ;AN000;
96MSG_SERVICES <GRAPHICS.CL1,GRAPHICS.CL2,GRAPHICS.CLA,GRAPHICS.CLB,GRAPHICS.CLC> ;AN000;
97.LIST ;; ;AN000;
98 ;; ;AN000;
99PUBLIC GRAPHICS_INSTALL ;; ;AN000;
100PUBLIC TEMP_SHARED_DATA_PTR ;; ;AN000;
101PUBLIC PRINTER_TYPE_PARM ;; ;AN000;
102PUBLIC PRINTER_TYPE_LENGTH ;; ;AN000;
103PUBLIC PROFILE_PATH ;; ;AN000;
104PUBLIC PRINTBOX_ID_PTR ;; ;AN000;
105PUBLIC PRINTBOX_ID_LENGTH ;; ;AN000;
106PUBLIC DEFAULT_BOX ;; ;AN000;
107PUBLIC LCD_BOX ;; ;AN000;
108PUBLIC NB_FREE_BYTES ;; ;AN000;
109PUBLIC SYSDISPMSG ;; ;AN000;
110PUBLIC DISP_ERROR ;; ;AN000;
111PUBLIC INSTALLED ;; ;AN000;
112PUBLIC ERROR_DEVICE ;; ;AN000;
113PUBLIC STDERR ;; ;AN000;
114PUBLIC STDOUT ;; ;AN000;
115PUBLIC RESIDENT_SHARED_DATA_SIZE ;; ;AN000;
116 ;; ;AN000;
117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
118;; ;AN000;
119;; Install Variables ;AN000;
120;; ;AN000;
121;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
122 ;; ;AN000;
123NO EQU 0 ;; ;AN000;
124YES EQU 1 ;; ;AN000;
125INSTALLED DB NO ;; YES if GRAPHICS already installed ;AN000;
126 ;; ;AN000;
127 ;; ;AN000;
128BYTES_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;
137PRINTER_TYPE_PARM DB "GRAPHICS",9 DUP(0) ; Printer type ;AN000;
138 ;; (default=GRAPHICS) ;AN000;
139PRINTER_TYPE_LENGTH DB 17 ;; Printer type maximum length of ASCIIZ ;AN000;
140PROFILE_PATH DB 128 DUP(0) ;; Profile name with full path ;AN000;
141 ;; (Max size for ASCIIZ is 128) ;AN000;
142PRINTBOX_ID_PTR DW DEFAULT_BOX ;; Offset of ASCIIZ string containing ;AN000;
143DEFAULT_BOX DB "STD",14 DUP(0); the printbox id. (DEFAULT = STD) ;AN000;
144LCD_BOX DB "LCD",14 DUP(0); ASCIIZ string for the LCD printboxID;AN000;
145PRINTBOX_ID_LENGTH DB 17 ;; Max. length for the printbox id. ;AN000;
146 ;; ASCIIZ string ;AN000;
147NB_FREE_BYTES DW ? ;; Number of bytes available in our ;AN000;
148 ;; resident segment ;AN000;
149RESIDENT_SHARED_DATA_SIZE DW ? ;; Size in bytes of the RESIDENT Shared ;AN000;
150 ;; data area (if GRAPHICS already ;AN000;
151 ;; installed). ;AN000;
152END_OF_RESIDENT_CODE DW ? ;; Offset of the end of the code that ;AN000;
153 ;; has to be made resident. ;AN000;
154TEMP_SHARED_DATA_PTR DW ? ;; Offset of the temporary Shared area ;AN000;
155 ;; ;AN000;
156ERROR_DEVICE DW STDERR ;; Device DISP_ERROR will output ;AN000;
157 ;; messages to (STDERR or STDOUT) ;AN000;
158PAGE ;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;
296GRAPHICS_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;
496ERROR_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;
505GRAPHICS_INSTALL ENDP ;AN000;
506 ;AN000;
507PAGE ;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;
578BIOS_SAVE_PTR EQU 4A8H ;; Offset of the BIOS Save Ptr area ;AN000;
579SAVE_AREA_LEN EQU 8*4 ;; There are 8 pointers in the Save area ;AN000;
580EGA_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;
584EGA_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;
602INST_EGA_SAVE_AREA PROC NEAR ;AN000;
603PUSH AX ;AN000;
604PUSH CX ;AN000;
605PUSH DX ;AN000;
606PUSH SI ;AN000;
607PUSH DI ;AN000;
608PUSH ES ;AN000;
609;-------------------------------------------------------------------------------;AN000;
610; Get the BIOS save pointer table ;AN000;
611;-------------------------------------------------------------------------------;AN000;
612XOR AX,AX ; ES := segment 0 ;AN000;
613MOV ES,AX ;AN000;
614LES 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;
688POP ES ;AN000;
689POP DI ;AN000;
690POP SI ;AN000;
691POP DX ;AN000;
692POP CX ;AN000;
693POP AX ;AN000;
694 ;AN000;
695RET ;AN000;
696OUR_SAVE_TAB_OFF DW ? ;AN000;
697INST_EGA_SAVE_AREA ENDP ;AN000;
698PAGE ;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;
738CHAIN_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;
777CHAIN_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;
830COPY_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;
908NEED_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;
911COPY_PRINT_MODULES ENDP ;AN000;
912 ;AN002;
913PAGE ;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;
923RELEASE_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;
938RELEASE_ENVIRONMENT ENDP ;AN002;
939 ;AN000;
940PAGE ;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;
952DISP_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;
968DISP_ERROR ENDP ;AN000;
969
970include msgdcl.inc ;AN000;
971 ;AN000;
972CODE ENDS ;AN000;
973 END ;AN000;