2 TITLE DOS
- GRAPHICS Command
- Profile
Load Modules
;AN000;
4 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
5 ;; DOS - GRAPHICS Command
6 ;; (C) Copyright 1988 Microsoft
8 ;; File Name: GRLOAD.ASM ;AN000;
11 ;; Description: ;AN000;
12 ;; ------------ ;AN000;
13 ;; This file contains the modules used to load the ;AN000;
14 ;; GRAPHICS profile into resident memory. ;AN000;
16 ;; ************* The EGA Dynamic Save Area will be built (by ;AN000;
17 ;; ** NOTE ** CHAIN_INTERRUPTS in file GRINST.ASM) over top of these ;AN000;
18 ;; ************* modules to avoid having to relocate this save just before ;AN000;
19 ;; terminating. This is safe since the maximum memory used is ;AN000;
20 ;; 288 bytes and the profile loading modules are MUCH larger than ;AN000;
21 ;; this. So GRLOAD.ASM MUST be linked before GRINST.ASM and after ;AN000;
22 ;; GRPRINT.ASM. ;AN000;
25 ;; Documentation Reference: ;AN000;
26 ;; ------------------------ ;AN000;
27 ;; PLACID Functional Specifications ;AN000;
28 ;; OASIS High Level Design ;AN000;
29 ;; OASIS GRAPHICS I1 Overview ;AN000;
31 ;; Procedures Contained in This File: ;AN000;
32 ;; ---------------------------------- ;AN000;
33 ;; LOAD_PROFILE - Main module for profile loading ;AN000;
35 ;; Include Files Required: ;AN000;
36 ;; ----------------------- ;AN000;
37 ;; ?????????? - Externals for profile loading modules ;AN000;
39 ;; External Procedure References: ;AN000;
40 ;; ------------------------------ ;AN000;
43 ;; Linkage Instructions: ;AN000;
44 ;; --------------------- ;AN000;
45 ;; Refer to GRAPHICS.ASM ;AN000;
47 ;; Change History: ;AN000;
48 ;; --------------- ;AN000;
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
54 CODE SEGMENT PUBLIC 'CODE' BYTE ;; ;AN000;
56 INCLUDE STRUC.INC ;; ;AN000;
57 INCLUDE GRINST
.EXT
;; Bring in external declarations ;AN000;
58 ;; for transient command processing ;AN000;
59 INCLUDE GRSHAR
.STR ;; ;AN000;
60 INCLUDE GRPARSE
.EXT
;; ;AN000;
61 INCLUDE GRLOAD2
.EXT
;; ;AN000;
62 INCLUDE GRLOAD3
.EXT
;; ;AN000;
63 INCLUDE GRMSG
.EQU
;; ;AN000;
65 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
67 ;; Public Symbols ;AN000;
69 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
71 PUBLIC LOAD_PROFILE
;AN000;
72 PUBLIC GROW_SHARED_DATA
;AN000;
73 PUBLIC BLOCK_START
;AN000;
74 PUBLIC BLOCK_END
;AN000;
75 PUBLIC FIRST_BLOCK
;AN000;
76 PUBLIC MAX_BLOCK_END
;AN000;
77 PUBLIC GROUPS_DONE
;AN000;
78 PUBLIC STMTS_DONE
;AN000;
79 PUBLIC STMTS_DONE
;AN000;
80 PUBLIC PTD_FOUND
;AN000;
81 PUBLIC BUILD_STATE
;AN000;
82 PUBLIC STMT_ERROR
;AN000;
83 PUBLIC FILE_ERROR
;AN000;
84 PUBLIC PARSE_ERROR
;AN000;
85 PUBLIC END_OF_FILE
;AN000;
86 PUBLIC MEM_OVERFLOW
;AN000;
87 PUBLIC STMT_BUFFER
;AN000;
88 PUBLIC CUR_STMT
;AN000;
89 PUBLIC PREV_STMT
;AN000;
90 PUBLIC PRT_BOX_ERROR
;AN000;
92 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
94 ASSUME
CS:CODE,DS:CODE ;; ;AN000;
96 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
99 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
101 ;; Profile Load Variables ;AN000;
103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
111 ;; Module Name: ;AN000;
112 ;; LOAD_PROFILE ;AN000;
114 ;; Input Parameters: ;AN000;
115 ;; DS,ES,SS - points to our transient segment ;AN000;
117 ;; Output Parameters: ;AN000;
118 ;; Temporary Shared Data Area ;AN000;
119 ;; Carry flag set if errors in profile. ;AN000;
121 ;; Data Structures Referenced: ;AN000;
122 ;; Shared Data Area ;AN000;
123 ;; Profile Load Variables ;AN000;
125 ;; Description: ;AN000;
126 ;; Build the profile information in the Temporary Shared Data Area. ;AN000;
127 ;; The information will be built for the printer type parsed off ;AN000;
128 ;; the command line. ALL Printer Type Descriptions will be ;AN000;
129 ;; parsed to issue error messages and determine the maximum ;AN000;
130 ;; amount of resident memory required for initial load. ;AN000;
131 ;; The Shared Data Area begins with a fixed length section ;AN000;
132 ;; and then has several variable length sections. PROFILE_BUILD_PTR ;AN000;
133 ;; is used to build the variable length sections by serving ;AN000;
134 ;; as a running pointer to the sections as they are built. ;AN000;
136 ;; Register Usage: ;AN000;
137 ;; BP - points to beginning of Temp Shared Data ;AN000;
139 ;; Called By: ;AN000;
140 ;; GRAPHICS_INSTALL ;AN000;
142 ;; External Calls: ;AN000;
143 ;; PARSE_PRINTER, PARSE_DISPLAYMODE, PARSE_SETUP, PARSE_RESTORE ;AN000;
144 ;; PARSE_PRINTBOX, PARSE_GRAPHICS, PARSE_COLORSELECT, ;AN000;
145 ;; PARSE_COLORPRINT, GET_STATEMENT ;AN000;
149 ;; IF profile path not specified THEN ;AN000;
150 ;; PROFILE_PATH := "GRAPHICS.PRO" /* Current directory */ ;AN000;
151 ;; Open profile using PROFILE_PATH ;AN000;
152 ;; IF error during open THEN ;AN000;
153 ;; PROFILE_PATH := ARG(V0) with "GRAPHICS.COM" replaced ;AN000;
154 ;; by "GRAPHICS.PRO" ;AN000;
155 ;; Open profile using PROFILE_PATH ;AN000;
156 ;; IF error during open THEN ;AN000;
157 ;; Issue "Cannot find profile" msg ;AN000;
158 ;; Set carry flag ;AN000;
163 ;; Open profile using specified path ;AN000;
164 ;; IF error during open THEN ;AN000;
165 ;; Issue "Cannot find profile" msg ;AN000;
166 ;; Set carry flag ;AN000;
170 ;; /* don't start building until we find our printer type*/ ;AN000;
171 ;; PARSE_MODE := NOBUILD ;AN000;
172 ;; MAX_BUILD_PTR := 0 ;AN000;
173 ;; CALL GROW_SHARED_DATA(PROFILE-BUILD_PTR,size of FIXED PART ;AN000;
174 ;; of Shared Data Area) ;AN000;
175 ;; WHILE (not end of file) AND (no I/O error) DO ;AN000;
176 ;; CALL GET_STATEMENT ;AN000;
177 ;; IF I/O error THEN ;AN000;
178 ;; Issue error message ;AN000;
180 ;; CALL SYSPARSE to parse the statement verb ;AN000;
181 ;; IF verb found THEN ;AN000;
182 ;; IF invalid verb THEN ;AN000;
183 ;; Issue error message ;AN000;
184 ;; PARSE_MODE := ERROR ;AN000;
186 ;; CASE statement verb ;AN000;
188 ;; CALL PARSE_PRINTER ;AN000;
189 ;; DISPLAYMODE: ;AN000;
190 ;; CALL PARSE_DISPLAYMODE ;AN000;
192 ;; CALL PARSE_PRINTBOX ;AN000;
194 ;; CALL PARSE_SETUP ;AN000;
196 ;; CALL PARSE_RESTORE ;AN000;
198 ;; CALL PARSE_GRAPHICS ;AN000;
199 ;; COLORPRINT: ;AN000;
200 ;; CALL PARSE_COLORPRINT ;AN000;
201 ;; COLORSELECT: ;AN000;
202 ;; CALL PARSE_COLORSELECT ;AN000;
204 ;; IF error on statement THEN ;AN000;
205 ;; IF OVERFLOW bit set in RETURN_CODE THEN ;AN000;
206 ;; Issue "Insufficient memory" message ;AN000;
207 ;; RETURN to caller ;AN000;
209 ;; IF MISSING bit set in RETURN_CODE THEN ;AN000;
210 ;; Issue "required statement missing" message ;AN000;
212 ;; IF INVALID bit set in RETURN_CODE THEN ;AN000;
213 ;; Issue "statement invalid" message ;AN000;
215 ;; IF SEQUENCE bit set in RETURN_CODE THEN ;AN000;
216 ;; Issue "out of sequence" message ;AN000;
218 ;; display the statement in error ;AN000;
220 ;; PARSE_MODE := ERROR ;AN000;
227 ;; /* Check length of last PTD */ ;AN000;
228 ;; IF PROFILE_BUILD_PTR > MAX_BUILD_PTR THEN ;AN000;
229 ;; MAX_BUILD_PTR := PROFILE_BUILD_PTR ;AN000;
232 ;; /* Make sure all required statements were in previous */ ;AN000;
233 ;; /* Printer Type Description */ ;AN000;
234 ;; /* Must have completed PRINTER, DISPLAYMODE, PRINTBOX and */ ;AN000;
235 ;; /* GRAPHICS statements */ ;AN000;
236 ;; IF PRT+DISP+BOX+GR bits not all set in STMTS_DONE THEN ;AN000;
237 ;; Issue "required statement missing" message ;AN000;
238 ;; Display "END OF FILE." ;AN000;
241 ;; IF errors during build THEN ;AN000;
242 ;; set carry flag ;AN000;
244 ;; SD_TOTAL_SIZE := MAX_BUILD_PTR - TEMP_SHARED_DATA_PTR ;AN000;
249 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
251 FILE_NOT_FOUND EQU
2 ;; DOS Int21H error codes ;AN000;
252 PATH_NOT_FOUND EQU
3 ;; ;AN000;
254 SUBLIST
LABEL BYTE ;; Message substituion list for stmt # ;AN000;
255 DB 11 ;; sublist size ;AN000;
257 DW STMT_NUM
;; \ Dword pointer to item ;AN000;
258 SUBLIST_SEG
DW ?
;; / ;AN000;
259 DB 1 ;; Substitution # ;AN000;
260 ;; Flag format a0sstttt ;; ;AN000;
261 DB 00100001B ;; Unsigned binary word - left align ;AN000;
262 ;;;; DB 00000000B ;; charcater ;AN000;
263 DB 0 ;; max field width ;AN000;
264 DB 1 ;; min width width ;AN000;
265 DB ' ' ;; pad characeter ;AN000;
267 STMT_NUM
DW 0 ;; ;AN000;
270 FILE_ERROR
DB 0 ;; Error opening or reading PROFILE ;AN000;
271 PARSE_ERROR
DB 0 ;; Syntax errors in PROFILE ;AN000;
272 END_OF_FILE
DB 0 ;; 1 if end of file ;AN000;
273 MEM_OVERFLOW
DB 0 ;; 1 if insufficient memory ;AN000;
275 STMT_ERROR
DB 0 ;; Error flag for individual stmt errors ;AN000;
276 MISSING EQU
1 ;; Required statement missing ;AN000;
277 INVALID EQU
2 ;; Invalid statement format ;AN000;
278 SEQUENCE EQU
4 ;; Statement out of sequence ;AN000;
280 DEFAULT_PATH
DB "GRAPHICS.PRO",0 ;; ;AN000;
281 BUFFER
DB 64 DUP("$") ;; ;AN000;
283 HANDLE
DW 0 ;; Profile handle ;AN000;
285 BUILD_STATE
DB 0 ;; 1 if we are currently building ;AN000;
286 ;; data. 0 means syntax checking ;AN000;
289 ;; Keep track of whether this PTD ;AN000;
290 ;; matches the type requested ;AN000;
291 PTD_FOUND
DB 0 ;; Values are NO (0), YES (1) and ;AN000;
292 PROCESSED EQU
2 ;; PROCESSED (2) ;AN000;
294 VERB
DB 0 ;; PTR into VERB_JMP_TAB ;AN000;
296 VERB_JMP_TAB
LABEL WORD ;; ;AN000;
297 DW OFFSET PARSE_PRINTER
;; ;AN000;
298 DW OFFSET PARSE_DISPLAYMODE
;; ;AN000;
299 DW OFFSET PARSE_PRINTBOX
;; ;AN000;
300 DW OFFSET PARSE_SETUP
;; ;AN000;
301 DW OFFSET PARSE_RESTORE
;; ;AN000;
302 DW OFFSET PARSE_GRAPHICS
;; ;AN000;
303 DW OFFSET PARSE_COLORPRINT
;; ;AN000;
304 DW OFFSET PARSE_COLORSELECT
;; ;AN000;
305 DW OFFSET PARSE_DARKADJUST
;; ;AN000;
307 STMTS_DONE
DW 0 ;; ;AN000;
308 GROUPS_DONE
DW 0 ;; ;AN000;
309 PREV_STMT
DW 0 ;; ;AN000;
310 CUR_STMT
DW 0 ;; ;AN000;
312 PRT EQU
1 ;; Bit masks for STMTS_DONE and ;AN000;
313 DISP EQU
2 ;; GROUPS_DONE. There is one ;AN000;
314 BOX EQU
4 ;; bit for each statement except ;AN000;
315 GR EQU
8 ;; DARKADJUST ;AN000;
316 SET EQU 10H
;; ;AN000;
317 REST EQU 20H
;; ;AN000;
318 COLS EQU 40H
;; ;AN000;
319 COLP EQU 80H
;; ;AN000;
320 DARK EQU 100H
;; ;AN000;
322 BLOCK_START
DW ?
;; Extents of the variable size block ;AN000;
323 BLOCK_END
DW ?
;; currently being built ;AN000;
324 ;; These are relative to the ;AN000;
325 ;; start of the Shared Data Area ;AN000;
326 ;; so the area can be relocated ;AN000;
327 MAX_BLOCK_END
DW 0 ;; End of largest PTD contained ;AN000;
328 ;; in profile ;AN000;
329 FIRST_BLOCK
DW ?
;; Pointer to first variable block ;AN000;
330 ;; (end of fixed part) ;AN000;
331 PRT_BOX_ERROR
DB 0 ;; ;AN000;
333 LOAD_PROFILE PROC
NEAR ;; ;AN000;
336 POP SUBLIST_SEG
;; setup segment for message sublist ;AN000;
338 CALL OPEN_FILE
;; ;AN000;
339 .IF <FILE_ERROR
EQ YES
> ;; Check for error during open ;AN000;
344 MOV BP,TEMP_SHARED_DATA_PTR
;; BP points to START of Shared Data ;AN000;
345 MOV AX,SIZE SHARED_DATA_AREA_STR
;; size of fixed part of Shared Data ;AN000;
346 MOV BLOCK_END
,0 ;; Initialize BLOCK_START,BLOCK_END ;AN000;
347 MOV [BP].DARKADJUST_VALUE
,0 ;; Init some values in the fixed ;AN000;
348 MOV [BP].NUM_PRT_COLOR
,0 ;; area ;AN000;
349 MOV [BP].COLORPRINT_PTR
,-1 ;; ;AN000;
350 MOV [BP].NUM_PRT_BANDS
,0 ;; ;AN000;
351 MOV [BP].COLORSELECT_PTR
,-1 ;; ;AN000;
352 MOV [BP].PRINTER_TYPE
,BLACK_WHITE
;; ;AN000;
353 CALL GROW_SHARED_DATA
;; to the first byte after the ;AN000;
354 ;; fixed part of Shared Data ;AN000;
355 MOV AX,BLOCK_END
;; Variable size data will be built ;AN000;
356 MOV BLOCK_START
,AX ;; starting at BLOCK_START ;AN000;
357 MOV FIRST_BLOCK
,AX ;; Save start of variable data ;AN000;
359 MOV SI,BUFFER_PTR
;; Set up SI for GET_BYTE ;AN000;
360 CALL GET_BYTE
;; Get first byte from file ;AN000;
361 MOV NEXT_BYTE
,AL ;; and store it ;AN000;
362 MOV BUFFER_PTR
,SI ;; Save SI for next GET_BYTE ;AN000;
363 .WHILE <END_OF_FILE
EQ NO
> AND ;; Keep parsing until end of file or ;AN000;
364 .WHILE <FILE_ERROR
EQ NO
> ;; file error occurs ;AN000;
365 MOV STMT_ERROR
,0 ;; Clear parse error flags ;AN000;
366 CALL GET_STATEMENT
;; Get next profile statement ;AN000;
367 INC STMT_NUM
;; ;AN000;
368 .IF NC
;; Carry flag set if get unsuccessful ;AN000;
369 CALL PARSE_VERB
;; Index into verb jump table returned ;AN000;
371 .IF <AX EQ 0> THEN
;; AX=0 if there is a recognized ;AN000;
372 MOV AX,CUR_STMT
;; ;AN000;
373 MOV PREV_STMT
,AX ;; Save last statement verb ;AN000;
374 CALL VERB_JMP_TAB
[BX] ;; statement to parse ;AN000;
375 .ELSEIF
<AX NE
-1> THEN
;; ;AN000;
376 OR STMT_ERROR
,INVALID
;; ;AN000;
377 MOV PARSE_ERROR
,YES
;; ;AN000;
378 MOV BUILD_STATE
,NO
;; ;AN000;
380 .IF <STMT_ERROR NE
0> ;; An error was detected ;AN000;
381 CALL SHOW_PARSE_ERROR
;; ;AN000;
382 MOV PARSE_ERROR
,YES
;; ;AN000;
383 MOV STMT_ERROR
,0 ;; ;AN000;
388 .IF <BIT STMTS_DONE
AND PRT
> ;; Must have at least one PRINTER ;AN000;
389 CALL TERMINATE_DISPLAYMODE
;; Terminate the last PRINTER and ;AN000;
390 CALL TERMINATE_PRINTER
;; DISPLAYMODE sections ;AN000;
392 OR STMT_ERROR
,MISSING
;; ;AN000;
394 .IF <STMT_ERROR NE
0> ;; ;AN000;
395 CALL SHOW_PARSE_ERROR
;; Issue Profile syntax messages ;AN000;
399 MOV AX,3E00H
;; Close the file ;AN000;
400 MOV BX,HANDLE
;; ;AN000;
403 .IF <PARSE_ERROR
EQ YES
> ;; ;AN000;
404 MOV AX,SYNTAX_ERRORS
;; Issue "Syntax errors found in ;AN000;
405 MOV CX,0 ;; profile" message. ;AN000;
406 CALL DISP_ERROR
;; ;AN000;
409 .IF <PTD_FOUND
EQ NO
> ;; Did we find the requested printer ;AN000;
410 MOV AX,INVALID_PRT
;; type? If not issue error ;AN000;
411 MOV CX,0 ;; message. ;AN000;
412 CALL DISP_ERROR
;; ;AN000;
413 MOV PARSE_ERROR
,YES
;; ;AN000;
416 .IF <PARSE_ERROR
EQ YES
> OR ;; ;AN000;
417 .IF <PRT_BOX_ERROR
EQ YES
> OR ;; ;AN000;
418 .IF <FILE_ERROR
EQ YES
> ;; Set carry flag if profile load ;AN000;
419 STC ;; was unsuccessful ;AN000;
421 .IF <MEM_OVERFLOW
EQ YES
> ;; Everthing else was OK BUT we ran ;AN000;
422 .IF <INSTALLED
EQ YES
> ;; out of memory!!! ;AN000;
423 MOV AX,NB_FREE_BYTES
;; ;AN000;
424 .IF <AX LT RESIDENT_SHARED_DATA_SIZE
> ;AN000;
425 MOV AX,NO_MEMORY
;; We ran out of physical memory! ;AN000;
427 MOV AX,UNABLE_RELOAD
;; Allocated shared data is too small ;AN000;
430 MOV AX,NO_MEMORY
;; We ran out of physical memory ;AN000;
433 CALL DISP_ERROR
;; ;AN000;
434 STC ;; Indicate unsuccessful ;AN000;
436 MOV AX,MAX_BLOCK_END
;; Extent of largest PRINTER section ;AN000;
437 MOV [BP].SD_TOTAL_SIZE
,AX ;; we parsed. ;AN000;
438 CLC ;; SUCCESSFUL LOAD!!!! ;AN000;
444 LOAD_PROFILE ENDP
;; ;AN000;
446 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
448 ;; Module Name: ;AN000;
449 ;; SHOW_PARSE_ERROR ;AN000;
451 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
453 CARRAIGE_RET EQU
13 ;; ;AN000;
454 LINE_FEED EQU
10 ;; ;AN000;
456 SHOW_PARSE_ERROR PROC
;; ;AN000;
458 MOV ERROR_DEVICE
,STDOUT
;; profile syntax messages to STDOUT ;AN000;
460 .IF <BIT STMT_ERROR
AND MISSING
> ;AN000;
462 MOV AX,MISSING_STMT
;; ;AN000;
464 MOV SI,OFFSET SUBLIST
;; ;AN000;
465 CALL DISP_ERROR
;; ;AN000;
468 .IF <BIT STMT_ERROR
AND INVALID
> ;AN000;
470 MOV AX,INVALID_STMT
;; ;AN000;
472 MOV SI,OFFSET SUBLIST
;; ;AN000;
473 CALL DISP_ERROR
;; ;AN000;
476 .IF <BIT STMT_ERROR
AND SEQUENCE
> ;AN000;
478 MOV AX,OUT_SEQ_STMT
;; ;AN000;
480 MOV SI,OFFSET SUBLIST
;; ;AN000;
481 CALL DISP_ERROR
;; ;AN000;
485 MOV DI,STMT_END_INDEX
;; ;AN000;
486 MOV STMT_BUFFER
[DI],'$' ;; For display ;AN000;
488 MOV DX,OFFSET STMT_BUFFER
;AN000;
490 MOV DL,CARRIAGE_RET
;; ;AN000;
493 MOV DL,LINE_FEED
;; ;AN000;
497 MOV ERROR_DEVICE
,STDERR
;; reset to STDERR ;AN000;
501 SHOW_PARSE_ERROR ENDP
;; ;AN000;
504 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
506 ;; Module Name: ;AN000;
509 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
512 OPEN_FILE PROC
NEAR ;; ;AN000;
514 .IF <PROFILE_PATH NE
0> ;; If a path was specified then ;AN000;
515 MOV DX,OFFSET PROFILE_PATH
;; try and open it ;AN000;
516 MOV AX,3D00H
;; ;AN000;
517 INT 21H
;; Open it ;AN000;
518 .IF C
;; Open error if carry flag set ;AN000;
519 .IF <AX EQ FILE_NOT_FOUND
> OR ;; Check for error other than ;AN000;
520 .IF <AX EQ PATH_NOT_FOUND
> ;; file not found ;AN000;
521 MOV AX,PROFILE_NOT_FOUND
;; ;AN000;
523 CALL DISP_ERROR
;; Issue "File not found" common msg ;AN000;
524 MOV FILE_ERROR
,YES
;; ;AN000;
526 CALL FILE_ERROR_PROC
;; Issue "Open error" ;AN000;
529 MOV HANDLE
,AX ;; ;AN000;
530 .ENDIF
;; File opened OK ;AN000;
531 .ELSE ;; No path parameter ;AN000;
532 MOV DX,OFFSET DEFAULT_PATH
;; Try and open "GRAPHICS.PRO" ;AN000;
533 MOV AX,3D00H
;; ;AN000;
534 INT 21H
;; Open it ;AN000;
535 .IF C
;; Open error if carry flag set ;AN000;
536 .IF <AX EQ FILE_NOT_FOUND
> OR ;; Check for file not found error ;AN000;
537 .IF <AX EQ PATH_NOT_FOUND
> ;; ;AN000;
538 CALL COPY_ARGV0
;; ;AN000;
539 MOV DX,OFFSET PROFILE_PATH
;; Try and open "GRAPHICS.PRO" in ;AN000;
540 MOV AX,3D00H
;; ARGV0 directory ;AN000;
542 .IF C
;; Issue "File not found" common msg ;AN000;
543 .IF <AX EQ FILE_NOT_FOUND
> OR ;AN000;
544 .IF <AX EQ PATH_NOT_FOUND
> ;AN000;
545 MOV AX,PROFILE_NOT_FOUND
;; ;AN000;
547 CALL DISP_ERROR
;; Issue "File not found"common MSG;AN000;
548 MOV FILE_ERROR
,YES
;; ;AN000;
550 CALL FILE_ERROR_PROC
;; Issue "Open error" ;AN000;
553 MOV HANDLE
,AX ;; ;AN000;
554 .ENDIF
;; File opened OK ;AN000;
556 CALL FILE_ERROR_PROC
;; Issue "Open error" ;AN000;
559 MOV HANDLE
,AX ;; ;AN000;
564 OPEN_FILE ENDP
;; ;AN000;
566 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
568 ;; Module Name: ;AN000;
569 ;; COPY_ARGV0 ;AN000;
571 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
574 COPY_ARGV0 PROC
;; ;AN000;
580 MOV DI,2
CH ;; Locate environment string ;AN000;
581 MOV ES,[DI] ;; ;AN000;
583 .WHILE <<WORD PTR ES:[SI]> NE
0> ;; ;AN000;
587 LEA DI,PROFILE_PATH
;; Move string to work area ;AN000;
589 MOV AL,ES:[SI] ;; ;AN000;
590 MOV [DI],AL ;; ;AN000;
593 .UNTIL
<<BYTE PTR ES:[SI]> EQ 0> ;; ;AN000;
594 MOV BYTE PTR [DI],0 ;; ;AN000;
595 MOV BYTE PTR [DI]-3,"P" ;; Change COM to PRO ;AN000;
596 MOV BYTE PTR [DI]-2,"R" ;; ;AN000;
597 MOV BYTE PTR [DI]-1,"O" ;; ;AN000;
604 COPY_ARGV0 ENDP
;; ;AN000;
606 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
608 ;; Module Name: ;AN000;
609 ;; FILE_ERROR_PROC ;AN000;
611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
614 FILE_ERROR_PROC PROC
;; ;AN000;
615 MOV AX,FILE_ERRORS
;; ;AN000;
617 CALL DISP_ERROR
;; ;AN000;
618 MOV FILE_ERROR
,YES
;; ;AN000;
620 FILE_ERROR_PROC ENDP
;; ;AN000;
622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
624 ;; Module Name: ;AN000;
625 ;; GET_STATEMENT ;AN000;
627 ;; Input Parameters: ;AN000;
630 ;; Output Parameters: ;AN000;
631 ;; PROFILE_LINE ;AN000;
632 ;; RETURN CODE : 0 - successfull read ;AN000;
633 ;; : 1 - end of file ;AN000;
634 ;; : 2 - error during read ;AN000;
637 ;; Data Structures Referenced: ;AN000;
639 ;; Description: ;AN000;
640 ;; Get a statement from the profile. ;AN000;
641 ;; The file read in 512 byte buffers and parsed into ;AN000;
642 ;; lines by the presence of a carriage return at the end of each line. ;AN000;
644 ;; Called By: ;AN000;
645 ;; LOAD_PROFILE ;AN000;
647 ;; External Calls: ;AN000;
651 ;; FOUND := FALSE ;AN000;
652 ;; RETURN_CODE := 0 ;AN000;
653 ;; WHILE NOT FOUND DO ;AN000;
654 ;; IF end of buffer THEN ;AN000;
655 ;; Read next profile record into buffer ;AN000;
656 ;; IF successful read THEN ;AN000;
657 ;; point to first byte in buffer ;AN000;
659 ;; IF end of file THEN ;AN000;
660 ;; Close profile ;AN000;
661 ;; RETURN_CODE := 1 ;AN000;
662 ;; FOUND := TRUE ;AN000;
664 ;; RETURN_CODE := 2 ;AN000;
665 ;; FOUND := TRUE ;AN000;
669 ;; copy byte to PROFILE_LINE ;AN000;
670 ;; IF byte in buffer is a CR THEN ;AN000;
671 ;; FOUND := TRUE ;AN000;
676 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
678 FOUND
DB 0 ;; ;AN000;
680 CARRIAGE_RET EQU
13 ;; ;AN000;
681 LINE_FEED EQU
10 ;; ;AN000;
682 NEXT_BYTE
DB 0 ;; Save area for byte just read ;AN000;
683 BUFFER_SIZE EQU
512 ;; ;AN000;
684 FILE_BUFFER
DB 512 DUP(0) ;; ;AN000;
685 BUFFER_PTR
DW 512 ;; ;AN000;
686 BUFFER_END
DW 512 ;; ;AN000;
687 STMT_BUFFER
DB 255 DUP(0) ;; ;AN000;
688 DB ?
;; In case we have to insert a CR ;AN000;
689 DB ?
;; and a LF ;AN000;
690 DB ?
;; Too put the "$" for displaying the ;AN000;
693 STMT_END_INDEX
DW ?
;; ;AN000;
694 MAX_STMT_LEN EQU
255 ;; ;AN000;
695 CR_FOUND
DB 0 ;; 1 if we found a line terminator ;AN000;
697 GET_STATEMENT PROC
;; ;AN000;
699 MOV FOUND
,NO
;; ;AN000;
700 MOV STMT_ERROR
,0 ;; Clear error flags ;AN000;
701 XOR DI,DI ;; Index for extracted statement ;AN000;
702 MOV SI,BUFFER_PTR
;; Init file buffer ptr ;AN000;
704 MOV AL,NEXT_BYTE
;; Restore current byte ;AN000;
705 MOV CR_FOUND
,NO
;; ;AN000;
708 .WHILE <FOUND
EQ NO
> AND ;; Keep parsing until we find a stmt ;AN000;
709 .WHILE <FILE_ERROR
EQ NO
> AND ;; or a file error occurs ;AN000;
710 .WHILE <END_OF_FILE
EQ NO
> ;; or we reach end of file ;AN000;
711 .IF <CR_FOUND
EQ YES
> ;; ;AN000;
712 .IF <AL EQ LINE_FEED
> ;; Return the line feed as well ;AN000;
713 .IF <DI NA MAX_STMT_LEN
> ;; Truncate lines longer than MAX ;AN000;
714 MOV STMT_BUFFER
[DI],AL ;; MOVE TO statement buffer ;AN000;
715 INC DI ;; Point to next byte in file buff\er ;AN000;
717 OR STMT_ERROR
,INVALID
;; Line has been truncated > ERROR ;AN000;
718 MOV PARSE_ERROR
,YES
;; ;AN000;
719 MOV BUILD_STATE
,NO
;; ;AN000;
721 CALL GET_BYTE
;; Get the first byte of next statement ;AN000;
723 MOV FOUND
,YES
;; Time to leave this WHILE ;AN000;
724 MOV NEXT_BYTE
,AL ;; Save the byte we just read ;AN000;
726 .IF <DI NA MAX_STMT_LEN
> ;; Truncate lines longer than MAX ;AN000;
727 MOV STMT_BUFFER
[DI],AL ;; move byte to statement buffer ;AN000;
728 INC DI ;; Point to next byte in file buffer ;AN000;
730 OR STMT_ERROR
,INVALID
;; Line has been truncated > ERROR ;AN000;
731 MOV PARSE_ERROR
,YES
;; ;AN000;
732 MOV BUILD_STATE
,NO
;; ;AN000;
734 .IF <AL EQ CARRIAGE_RET
> ;; Found a line terminator ;AN000;
735 MOV CR_FOUND
,YES
;; Indicate carriage return found ;AN000;
736 .ENDIF
;; and go through once more to ;AN000;
737 CALL GET_BYTE
;; check for a line feed ;AN000;
741 .IF <STMT_BUFFER
[DI-1] NE CARRIAGE_RET
> AND ;; ;AN000;
742 .IF <STMT_BUFFER
[DI-1] NE LINE_FEED
> ;; ;AN000;
743 MOV STMT_BUFFER
[DI],CARRIAGE_RET
;; ;AN000;
744 MOV STMT_BUFFER
[DI+1],LINE_FEED
;; ;AN000;
748 MOV STMT_END_INDEX
,DI ;; ;AN000;
749 MOV BUFFER_PTR
,SI ;; Save buffer ptr for next time ;AN000;
751 .IF <END_OF_FILE
EQ YES
> ;; ;AN000;
752 .IF <DI EQ 0> ;; Clear carry if we read something ;AN000;
753 STC ;; and no file error occured otherwise ;AN000;
754 .ELSE ;; set carry indicating unsuccessful ;AN000;
758 .IF <FILE_ERROR
EQ YES
> ;; ;AN000;
766 GET_STATEMENT ENDP
;; ;AN000;
769 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
771 ;; Module Name: ;AN000;
774 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
776 GET_BYTE PROC
;; ;AN000;
778 .IF <SI EQ BUFFER_END
> ;; If buffer empty do another read ;AN000;
779 MOV AH,3FH
;; ;AN000;
780 MOV DX,OFFSET FILE_BUFFER
;; ;AN000;
781 MOV CX,BUFFER_SIZE
;; ;AN000;
782 MOV BX,HANDLE
;; ;AN000;
784 .IF C
;; Carry set by DOS if file error ;AN000;
785 CALL FILE_ERROR_PROC
;; ;AN000;
787 .IF <AX EQ 0> ;; End of file if AX=0 ;AN000;
788 MOV END_OF_FILE
,YES
;; ;AN000;
789 MOV AH,3EH
;; Close the file ;AN000;
790 MOV BX,HANDLE
;; ;AN000;
793 MOV BUFFER_END
,AX ;; Number of bytes read ;AN000;
794 XOR SI,SI ;; Buffer pointer := 0 ;AN000;
799 .IF <FILE_ERROR
EQ YES
> OR ;; ;AN000;
800 .IF <END_OF_FILE
EQ YES
> ;; ;AN000;
801 STC ;; Unsuccessful get ;AN000;
803 .IF <<FILE_BUFFER
[SI]> EQ 1
AH> ;; cHECK for EOF marker ;AN000;
804 MOV END_OF_FILE
,YES
;; ;AN000;
807 MOV AL,FILE_BUFFER
[SI] ;; Return byte in AL ;AN000;
809 CLC ;; Successful get ;AN000;
814 GET_BYTE ENDP
;; ;AN000;
817 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
819 ;; Module Name: ;AN000;
820 ;; GROW_SHARED_DATA ;AN000;
822 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
824 GROW_SHARED_DATA PROC
;; ;AN000;
826 ADD BLOCK_END
,AX ;; Grow the current block by AX ;AN000;
827 MOV BX,BLOCK_END
;; ;AN000;
828 .IF <BX A NB_FREE_BYTES
> ;; Check for overflow ;AN000;
829 MOV BUILD_STATE
,NO
;; Stop building shared data ;AN000;
830 MOV MEM_OVERFLOW
,YES
;; ;AN000;
834 GROW_SHARED_DATA ENDP
;; ;AN000;
836 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
840 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;