|
|
;/* ; * Microsoft Confidential ; * Copyright (C) Microsoft Corporation 1988 - 1991 ; * All Rights Reserved. ; */ ;************************************************************ ;** ;** NAME: Support for HP PCL printers added to GRAPHICS. ;** ;** DESCRIPTION: I added an entry in the VERB_JMP_TAB and the equate DEF to ;** handle the new statement DEFINE. I also made the new variable ;** DATA_TYPE have the default of DATA_COL in the procedure ;** LOAD_PROFILE, so the default assumes IBM type printers. ;** ;** DOCUMENTATION NOTES: This version of GRLOAD.ASM differs from the previous ;** version only in terms of documentation. ;** ;** ;************************************************************ PAGE ,132 ;AN000; TITLE DOS - GRAPHICS Command - Profile Load Modules ;AN000; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; DOS - GRAPHICS Command ;; ;; ;AN000; ;; File Name: GRLOAD.ASM ;AN000; ;; ---------- ;AN000; ;; ;AN000; ;; Description: ;AN000; ;; ------------ ;AN000; ;; This file contains the modules used to load the ;AN000; ;; GRAPHICS profile into resident memory. ;AN000; ;; ;AN000; ;; ************* The EGA Dynamic Save Area will be built (by ;AN000; ;; ** NOTE ** CHAIN_INTERRUPTS in file GRINST.ASM) over top of these ;AN000; ;; ************* modules to avoid having to relocate this save just before ;AN000; ;; terminating. This is safe since the maximum memory used is ;AN000; ;; 288 bytes and the profile loading modules are MUCH larger than ;AN000; ;; this. So GRLOAD.ASM MUST be linked before GRINST.ASM and after ;AN000; ;; GRPRINT.ASM. ;AN000; ;; ;AN000; ;; ;AN000; ;; Documentation Reference: ;AN000; ;; ------------------------ ;AN000; ;; PLACID Functional Specifications ;AN000; ;; OASIS High Level Design ;AN000; ;; OASIS GRAPHICS I1 Overview ;AN000; ;; ;AN000; ;; Procedures Contained in This File: ;AN000; ;; ---------------------------------- ;AN000; ;; LOAD_PROFILE - Main module for profile loading ;AN000; ;; ;AN000; ;; Include Files Required: ;AN000; ;; ----------------------- ;AN000; ;; ?????????? - Externals for profile loading modules ;AN000; ;; ;AN000; ;; External Procedure References: ;AN000; ;; ------------------------------ ;AN000; ;; None ;AN000; ;; ;AN000; ;; Linkage Instructions: ;AN000; ;; --------------------- ;AN000; ;; Refer to GRAPHICS.ASM ;AN000; ;; ;AN000; ;; Change History: ;AN000; ;; --------------- ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; ;AN000; CODE SEGMENT PUBLIC 'CODE' BYTE ;; ;AN000; ;; ;AN000; INCLUDE STRUC.INC ;; ;AN000; INCLUDE GRINST.EXT ;; Bring in external declarations ;AN000; ;; for transient command processing ;AN000; INCLUDE GRSHAR.STR ;; ;AN000; INCLUDE GRPARSE.EXT ;; ;AN000; INCLUDE GRLOAD2.EXT ;; ;AN000; INCLUDE GRLOAD3.EXT ;; ;AN000; INCLUDE GRMSG.EQU ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Public Symbols ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; PUBLIC LOAD_PROFILE ;AN000; PUBLIC GROW_SHARED_DATA ;AN000; PUBLIC BLOCK_START ;AN000; PUBLIC BLOCK_END ;AN000; PUBLIC FIRST_BLOCK ;AN000; PUBLIC MAX_BLOCK_END ;AN000; PUBLIC GROUPS_DONE ;AN000; PUBLIC STMTS_DONE ;AN000; PUBLIC STMTS_DONE ;AN000; PUBLIC PTD_FOUND ;AN000; PUBLIC BUILD_STATE ;AN000; PUBLIC STMT_ERROR ;AN000; PUBLIC FILE_ERROR ;AN000; PUBLIC PARSE_ERROR ;AN000; PUBLIC END_OF_FILE ;AN000; PUBLIC MEM_OVERFLOW ;AN000; PUBLIC STMT_BUFFER ;AN000; PUBLIC CUR_STMT ;AN000; PUBLIC PREV_STMT ;AN000; PUBLIC PRT_BOX_ERROR ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ASSUME CS:CODE,DS:CODE ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Profile Load Variables ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; NO EQU 0 ;; ;AN000; YES EQU 1 ;; ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; LOAD_PROFILE ;AN000; ;; ;AN000; ;; Input Parameters: ;AN000; ;; DS,ES,SS - points to our transient segment ;AN000; ;; ;AN000; ;; Output Parameters: ;AN000; ;; Temporary Shared Data Area ;AN000; ;; Carry flag set if errors in profile. ;AN000; ;; ;AN000; ;; Data Structures Referenced: ;AN000; ;; Shared Data Area ;AN000; ;; Profile Load Variables ;AN000; ;; ;AN000; ;; Description: ;AN000; ;; Build the profile information in the Temporary Shared Data Area. ;AN000; ;; The information will be built for the printer type parsed off ;AN000; ;; the command line. ALL Printer Type Descriptions will be ;AN000; ;; parsed to issue error messages and determine the maximum ;AN000; ;; amount of resident memory required for initial load. ;AN000; ;; The Shared Data Area begins with a fixed length section ;AN000; ;; and then has several variable length sections. PROFILE_BUILD_PTR ;AN000; ;; is used to build the variable length sections by serving ;AN000; ;; as a running pointer to the sections as they are built. ;AN000; ;; ;AN000; ;; Register Usage: ;AN000; ;; BP - points to beginning of Temp Shared Data ;AN000; ;; ;AN000; ;; Called By: ;AN000; ;; GRAPHICS_INSTALL ;AN000; ;; ;AN000; ;; External Calls: ;AN000; ;; PARSE_PRINTER, PARSE_DISPLAYMODE, PARSE_SETUP, PARSE_RESTORE ;AN000; ;; PARSE_PRINTBOX, PARSE_GRAPHICS, PARSE_COLORSELECT, ;AN000; ;; PARSE_COLORPRINT, GET_STATEMENT ;AN000; ;; SYSPARSE ;AN000; ;; ;AN000; ;; Logic: ;AN000; ;; IF profile path not specified THEN ;AN000; ;; PROFILE_PATH := "GRAPHICS.PRO" /* Current directory */ ;AN000; ;; Open profile using PROFILE_PATH ;AN000; ;; IF error during open THEN ;AN000; ;; PROFILE_PATH := ARG(V0) with "GRAPHICS.COM" replaced ;AN000; ;; by "GRAPHICS.PRO" ;AN000; ;; Open profile using PROFILE_PATH ;AN000; ;; IF error during open THEN ;AN000; ;; Issue "Cannot find profile" msg ;AN000; ;; Set carry flag ;AN000; ;; RETURN ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; ELSE ;AN000; ;; Open profile using specified path ;AN000; ;; IF error during open THEN ;AN000; ;; Issue "Cannot find profile" msg ;AN000; ;; Set carry flag ;AN000; ;; RETURN ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; /* don't start building until we find our printer type*/ ;AN000; ;; PARSE_MODE := NOBUILD ;AN000; ;; MAX_BUILD_PTR := 0 ;AN000; ;; CALL GROW_SHARED_DATA(PROFILE-BUILD_PTR,size of FIXED PART ;AN000; ;; of Shared Data Area) ;AN000; ;; WHILE (not end of file) AND (no I/O error) DO ;AN000; ;; CALL GET_STATEMENT ;AN000; ;; IF I/O error THEN ;AN000; ;; Issue error message ;AN000; ;; ELSE ;AN000; ;; CALL SYSPARSE to parse the statement verb ;AN000; ;; IF verb found THEN ;AN000; ;; IF invalid verb THEN ;AN000; ;; Issue error message ;AN000; ;; PARSE_MODE := ERROR ;AN000; ;; ELSE ;AN000; ;; CASE statement verb ;AN000; ;; PRINTER: ;AN000; ;; CALL PARSE_PRINTER ;AN000; ;; DISPLAYMODE: ;AN000; ;; CALL PARSE_DISPLAYMODE ;AN000; ;; PRINTBOX: ;AN000; ;; CALL PARSE_PRINTBOX ;AN000; ;; SETUP: ;AN000; ;; CALL PARSE_SETUP ;AN000; ;; RESTORE: ;AN000; ;; CALL PARSE_RESTORE ;AN000; ;; GRAPHICS: ;AN000; ;; CALL PARSE_GRAPHICS ;AN000; ;; COLORPRINT: ;AN000; ;; CALL PARSE_COLORPRINT ;AN000; ;; COLORSELECT: ;AN000; ;; CALL PARSE_COLORSELECT ;AN000; ;; ENDCASE ;AN000; ;; IF error on statement THEN ;AN000; ;; IF OVERFLOW bit set in RETURN_CODE THEN ;AN000; ;; Issue "Insufficient memory" message ;AN000; ;; RETURN to caller ;AN000; ;; ELSE ;AN000; ;; IF MISSING bit set in RETURN_CODE THEN ;AN000; ;; Issue "required statement missing" message ;AN000; ;; ENDIF ;AN000; ;; IF INVALID bit set in RETURN_CODE THEN ;AN000; ;; Issue "statement invalid" message ;AN000; ;; ENDIF ;AN000; ;; IF SEQUENCE bit set in RETURN_CODE THEN ;AN000; ;; Issue "out of sequence" message ;AN000; ;; ENDIF ;AN000; ;; display the statement in error ;AN000; ;; ENDIF ;AN000; ;; PARSE_MODE := ERROR ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; ENDWHILE ;AN000; ;; ;AN000; ;; /* Check length of last PTD */ ;AN000; ;; IF PROFILE_BUILD_PTR > MAX_BUILD_PTR THEN ;AN000; ;; MAX_BUILD_PTR := PROFILE_BUILD_PTR ;AN000; ;; ENDIF ;AN000; ;; ;AN000; ;; /* Make sure all required statements were in previous */ ;AN000; ;; /* Printer Type Description */ ;AN000; ;; /* Must have completed PRINTER, DISPLAYMODE, PRINTBOX and */ ;AN000; ;; /* GRAPHICS statements */ ;AN000; ;; IF PRT+DISP+BOX+GR bits not all set in STMTS_DONE THEN ;AN000; ;; Issue "required statement missing" message ;AN000; ;; Display "END OF FILE." ;AN000; ;; ENDIF ;AN000; ;; ;AN000; ;; IF errors during build THEN ;AN000; ;; set carry flag ;AN000; ;; ELSE ;AN000; ;; SD_TOTAL_SIZE := MAX_BUILD_PTR - TEMP_SHARED_DATA_PTR ;AN000; ;; ENDIF ;AN000; ;; RETURN ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; FILE_NOT_FOUND EQU 2 ;; DOS Int21H error codes ;AN000; PATH_NOT_FOUND EQU 3 ;; ;AN000; ;; ;AN000; SUBLIST LABEL BYTE ;; Message substituion list for stmt # ;AN000; DB 11 ;; sublist size ;AN000; DB 0 ;; ;AN000; DW STMT_NUM ;; \ Dword pointer to item ;AN000; SUBLIST_SEG DW ? ;; / ;AN000; DB 1 ;; Substitution # ;AN000; ;; Flag format a0sstttt ;; ;AN000; DB 00100001B ;; Unsigned binary word - left align ;AN000; ;;;; DB 00000000B ;; charcater ;AN000; DB 0 ;; max field width ;AN000; DB 1 ;; min width width ;AN000; DB ' ' ;; pad characeter ;AN000; ;; ;AN000; STMT_NUM DW 0 ;; ;AN000; ;; ;AN000; ;; ;AN000; FILE_ERROR DB 0 ;; Error opening or reading PROFILE ;AN000; PARSE_ERROR DB 0 ;; Syntax errors in PROFILE ;AN000; END_OF_FILE DB 0 ;; 1 if end of file ;AN000; MEM_OVERFLOW DB 0 ;; 1 if insufficient memory ;AN000; ;; ;AN000; STMT_ERROR DB 0 ;; Error flag for individual stmt errors ;AN000; MISSING EQU 1 ;; Required statement missing ;AN000; INVALID EQU 2 ;; Invalid statement format ;AN000; SEQUENCE EQU 4 ;; Statement out of sequence ;AN000; ;; ;AN000; DEFAULT_PATH DB "GRAPHICS.PRO",0 ;; ;AN000; BUFFER DB 64 DUP("$") ;; ;AN000; ;; ;AN000; HANDLE DW 0 ;; Profile handle ;AN000; ;; ;AN000; BUILD_STATE DB 0 ;; 1 if we are currently building ;AN000; ;; data. 0 means syntax checking ;AN000; ;; only ;AN000; ;; ;AN000; ;; Keep track of whether this PTD ;AN000; ;; matches the type requested ;AN000; PTD_FOUND DB 0 ;; Values are NO (0), YES (1) and ;AN000; PROCESSED EQU 2 ;; PROCESSED (2) ;AN000; ;; ;AN000; VERB DB 0 ;; PTR into VERB_JMP_TAB ;AN000; ;; ;AN000; VERB_JMP_TAB LABEL WORD ;; ;AN000; DW OFFSET PARSE_PRINTER ;; ;AN000; DW OFFSET PARSE_DISPLAYMODE ;; ;AN000; DW OFFSET PARSE_PRINTBOX ;; ;AN000; DW OFFSET PARSE_SETUP ;; ;AN000; DW OFFSET PARSE_RESTORE ;; ;AN000; DW OFFSET PARSE_GRAPHICS ;; ;AN000; DW OFFSET PARSE_COLORPRINT ;; ;AN000; DW OFFSET PARSE_COLORSELECT ;; ;AN000; DW OFFSET PARSE_DARKADJUST ;; ;AN000; ;\/ ~~mda(001) ---------------------------------------------------------- ; Added the following so that LOAD_PROFILE will parse the ; DEFINE statement. ; DW OFFSET PARSE_DEFINE ; ;/\ ~~mda(001) ---------------------------------------------------------- ;; ;AN000; STMTS_DONE DW 0 ;; ;AN000; GROUPS_DONE DW 0 ;; ;AN000; PREV_STMT DW 0 ;; ;AN000; CUR_STMT DW 0 ;; ;AN000; ;; ;AN000; PRT EQU 1 ;; Bit masks for STMTS_DONE and ;AN000; DISP EQU 2 ;; GROUPS_DONE. There is one ;AN000; BOX EQU 4 ;; bit for each statement except ;AN000; GR EQU 8 ;; DARKADJUST ;AN000; SET EQU 10H ;; ;AN000; REST EQU 20H ;; ;AN000; COLS EQU 40H ;; ;AN000; COLP EQU 80H ;; ;AN000; DARK EQU 100H ;; ;AN000; ;\/ ~~mda(001) ---------------------------------------------------------- ; Added the following for the DEFINE statement. ; DEF EQU 200H ;/\ ~~mda(001) ---------------------------------------------------------- ;; ;AN000; BLOCK_START DW ? ;; Extents of the variable size block ;AN000; BLOCK_END DW ? ;; currently being built ;AN000; ;; These are relative to the ;AN000; ;; start of the Shared Data Area ;AN000; ;; so the area can be relocated ;AN000; MAX_BLOCK_END DW 0 ;; End of largest PTD contained ;AN000; ;; in profile ;AN000; FIRST_BLOCK DW ? ;; Pointer to first variable block ;AN000; ;; (end of fixed part) ;AN000; PRT_BOX_ERROR DB 0 ;; ;AN000; ;; ;AN000; LOAD_PROFILE PROC NEAR ;; ;AN000; ;; ;AN000; PUSH CS ;; ;AN000; POP SUBLIST_SEG ;; setup segment for message sublist ;AN000; ;; ;AN000; CALL OPEN_FILE ;; ;AN000; .IF <FILE_ERROR EQ YES> ;; Check for error during open ;AN000; STC ;; ;AN000; RET ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; MOV BP,TEMP_SHARED_DATA_PTR ;; BP points to START of Shared Data ;AN000; MOV AX,SIZE SHARED_DATA_AREA_STR ;; size of fixed part of Shared Data ;AN000; MOV BLOCK_END,0 ;; Initialize BLOCK_START,BLOCK_END ;AN000; MOV [BP].DARKADJUST_VALUE,0 ;; Init some values in the fixed ;AN000; MOV [BP].NUM_PRT_COLOR,0 ;; area ;AN000; MOV [BP].COLORPRINT_PTR,-1 ;; ;AN000; MOV [BP].NUM_PRT_BANDS,0 ;; ;AN000; MOV [BP].COLORSELECT_PTR,-1 ;; ;AN000; MOV [BP].PRINTER_TYPE,BLACK_WHITE ;; ;AN000; ;\/ ~~mda(001) ---------------------------------------------------------- ; Make the default DATA_TYPE be DATA_COL for the IBM printers. ; MOV [BP].DATA_TYPE,DATA_COL ; ;/\ ~~mda(001) ---------------------------------------------------------- CALL GROW_SHARED_DATA ;; to the first byte after the ;AN000; ;; fixed part of Shared Data ;AN000; MOV AX,BLOCK_END ;; Variable size data will be built ;AN000; MOV BLOCK_START,AX ;; starting at BLOCK_START ;AN000; MOV FIRST_BLOCK,AX ;; Save start of variable data ;AN000; ;; ;AN000; MOV SI,BUFFER_PTR ;; Set up SI for GET_BYTE ;AN000; CALL GET_BYTE ;; Get first byte from file ;AN000; MOV NEXT_BYTE,AL ;; and store it ;AN000; MOV BUFFER_PTR,SI ;; Save SI for next GET_BYTE ;AN000; .WHILE <END_OF_FILE EQ NO> AND ;; Keep parsing until end of file or ;AN000; .WHILE <FILE_ERROR EQ NO> ;; file error occurs ;AN000; MOV STMT_ERROR,0 ;; Clear parse error flags ;AN000; CALL GET_STATEMENT ;; Get next profile statement ;AN000; INC STMT_NUM ;; ;AN000; .IF NC ;; Carry flag set if get unsuccessful ;AN000; CALL PARSE_VERB ;; Index into verb jump table returned ;AN000; ;; in BX ;AN000; .IF <AX EQ 0> THEN ;; AX=0 if there is a recognized ;AN000; MOV AX,CUR_STMT ;; ;AN000; MOV PREV_STMT,AX ;; Save last statement verb ;AN000; CALL VERB_JMP_TAB[BX] ;; statement to parse ;AN000; .ELSEIF <AX NE -1> THEN ;; ;AN000; OR STMT_ERROR,INVALID ;; ;AN000; MOV PARSE_ERROR,YES ;; ;AN000; MOV BUILD_STATE,NO ;; ;AN000; .ENDIF ;; ;AN000; .IF <STMT_ERROR NE 0> ;; An error was detected ;AN000; CALL SHOW_PARSE_ERROR ;; ;AN000; MOV PARSE_ERROR,YES ;; ;AN000; MOV STMT_ERROR,0 ;; ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; .ENDWHILE ;; ;AN000; ;; ;AN000; .IF <BIT STMTS_DONE AND PRT> ;; Must have at least one PRINTER ;AN000; CALL TERMINATE_DISPLAYMODE ;; Terminate the last PRINTER and ;AN000; CALL TERMINATE_PRINTER ;; DISPLAYMODE sections ;AN000; .ELSE ;; ;AN000; OR STMT_ERROR,MISSING ;; ;AN000; .ENDIF ;; ;AN000; .IF <STMT_ERROR NE 0> ;; ;AN000; CALL SHOW_PARSE_ERROR ;; Issue Profile syntax messages ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; ;; ;AN000; MOV AX,3E00H ;; Close the file ;AN000; MOV BX,HANDLE ;; ;AN000; INT 21H ;; ;AN000; ;; ;AN000; .IF <PARSE_ERROR EQ YES> ;; ;AN000; MOV AX,SYNTAX_ERRORS ;; Issue "Syntax errors found in ;AN000; MOV CX,0 ;; profile" message. ;AN000; CALL DISP_ERROR ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; .IF <PTD_FOUND EQ NO> ;; Did we find the requested printer ;AN000; MOV AX,INVALID_PRT ;; type? If not issue error ;AN000; MOV CX,0 ;; message. ;AN000; CALL DISP_ERROR ;; ;AN000; MOV PARSE_ERROR,YES ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; .IF <PARSE_ERROR EQ YES> OR ;; ;AN000; .IF <PRT_BOX_ERROR EQ YES> OR ;; ;AN000; .IF <FILE_ERROR EQ YES> ;; Set carry flag if profile load ;AN000; STC ;; was unsuccessful ;AN000; .ELSE ;; ;AN000; .IF <MEM_OVERFLOW EQ YES> ;; Everthing else was OK BUT we ran ;AN000; .IF <INSTALLED EQ YES> ;; out of memory!!! ;AN000; MOV AX,NB_FREE_BYTES ;; ;AN000; .IF <AX LT RESIDENT_SHARED_DATA_SIZE> ;AN000; MOV AX,NO_MEMORY ;; We ran out of physical memory! ;AN000; .ELSE ;; ;AN000; MOV AX,UNABLE_RELOAD ;; Allocated shared data is too small ;AN000; .ENDIF ;; ;AN000; .ELSE ;; ;AN000; MOV AX,NO_MEMORY ;; We ran out of physical memory ;AN000; .ENDIF ;; ;AN000; MOV CX,0 ;; ;AN000; CALL DISP_ERROR ;; ;AN000; STC ;; Indicate unsuccessful ;AN000; .ELSE ;; ;AN000; MOV AX,MAX_BLOCK_END ;; Extent of largest PRINTER section ;AN000; MOV [BP].SD_TOTAL_SIZE,AX ;; we parsed. ;AN000; CLC ;; SUCCESSFUL LOAD!!!! ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; RET ;; ;AN000; ;; ;AN000; LOAD_PROFILE ENDP ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; SHOW_PARSE_ERROR ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; CARRAIGE_RET EQU 13 ;; ;AN000; LINE_FEED EQU 10 ;; ;AN000; ;; ;AN000; SHOW_PARSE_ERROR PROC ;; ;AN000; ;; ;AN000; MOV ERROR_DEVICE,STDOUT ;; profile syntax messages to STDOUT ;AN000; ;; ;AN000; .IF <BIT STMT_ERROR AND MISSING> ;AN000; PUSH SI ;; ;AN000; MOV AX,MISSING_STMT ;; ;AN000; MOV CX,1 ;; ;AN000; MOV SI,OFFSET SUBLIST ;; ;AN000; CALL DISP_ERROR ;; ;AN000; POP SI ;; ;AN000; .ENDIF ;; ;AN000; .IF <BIT STMT_ERROR AND INVALID> ;AN000; PUSH SI ;; ;AN000; MOV AX,INVALID_STMT ;; ;AN000; MOV CX,1 ;AN000; MOV SI,OFFSET SUBLIST ;; ;AN000; CALL DISP_ERROR ;; ;AN000; POP SI ;; ;AN000; .ENDIF ;; ;AN000; .IF <BIT STMT_ERROR AND SEQUENCE> ;AN000; PUSH SI ;; ;AN000; MOV AX,OUT_SEQ_STMT ;; ;AN000; MOV CX,1 ;AN000; MOV SI,OFFSET SUBLIST ;; ;AN000; CALL DISP_ERROR ;; ;AN000; POP SI ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; MOV DI,STMT_END_INDEX ;; ;AN000; MOV STMT_BUFFER[DI],'$' ;; For display ;AN000; MOV AH,9 ;; ;AN000; MOV DX,OFFSET STMT_BUFFER ;AN000; INT 21H ;; ;AN000; MOV DL,CARRIAGE_RET ;; ;AN000; MOV AH,2 ;; ;AN000; INT 21H ;; ;AN000; MOV DL,LINE_FEED ;; ;AN000; MOV AH,2 ;; ;AN000; INT 21H ;; ;AN000; ;; ;AN000; MOV ERROR_DEVICE,STDERR ;; reset to STDERR ;AN000; ;; ;AN000; RET ;; ;AN000; ;; ;AN000; SHOW_PARSE_ERROR ENDP ;; ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; OPEN_FILE ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; ;AN000; OPEN_FILE PROC NEAR ;; ;AN000; ;; ;AN000; .IF <PROFILE_PATH NE 0> ;; If a path was specified then ;AN000; MOV DX,OFFSET PROFILE_PATH ;; try and open it ;AN000; MOV AX,3D00H ;; ;AN000; INT 21H ;; Open it ;AN000; .IF C ;; Open error if carry flag set ;AN000; .IF <AX EQ FILE_NOT_FOUND> OR ;; Check for error other than ;AN000; .IF <AX EQ PATH_NOT_FOUND> ;; file not found ;AN000; MOV AX,PROFILE_NOT_FOUND ;; ;AN000; MOV CX,0 ;; ;AN000; CALL DISP_ERROR ;; Issue "File not found" common msg ;AN000; MOV FILE_ERROR,YES ;; ;AN000; .ELSE ;; ;AN000; CALL FILE_ERROR_PROC ;; Issue "Open error" ;AN000; .ENDIF ;; ;AN000; .ELSE ;; ;AN000; MOV HANDLE,AX ;; ;AN000; .ENDIF ;; File opened OK ;AN000; .ELSE ;; No path parameter ;AN000; MOV DX,OFFSET DEFAULT_PATH ;; Try and open "GRAPHICS.PRO" ;AN000; MOV AX,3D00H ;; ;AN000; INT 21H ;; Open it ;AN000; .IF C ;; Open error if carry flag set ;AN000; .IF <AX EQ FILE_NOT_FOUND> OR ;; Check for file not found error ;AN000; .IF <AX EQ PATH_NOT_FOUND> ;; ;AN000; CALL COPY_ARGV0 ;; ;AN000; MOV DX,OFFSET PROFILE_PATH ;; Try and open "GRAPHICS.PRO" in ;AN000; MOV AX,3D00H ;; ARGV0 directory ;AN000; INT 21H ;; ;AN000; .IF C ;; Issue "File not found" common msg ;AN000; .IF <AX EQ FILE_NOT_FOUND> OR ;AN000; .IF <AX EQ PATH_NOT_FOUND> ;AN000; MOV AX,PROFILE_NOT_FOUND ;; ;AN000; MOV CX,0 ;; ;AN000; CALL DISP_ERROR ;; Issue "File not found"common MSG;AN000; MOV FILE_ERROR,YES ;; ;AN000; .ELSE ;; ;AN000; CALL FILE_ERROR_PROC ;; Issue "Open error" ;AN000; .ENDIF ;; ;AN000; .ELSE ;; ;AN000; MOV HANDLE,AX ;; ;AN000; .ENDIF ;; File opened OK ;AN000; .ELSE ;; ;AN000; CALL FILE_ERROR_PROC ;; Issue "Open error" ;AN000; .ENDIF ;; ;AN000; .ELSE ;; ;AN000; MOV HANDLE,AX ;; ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; RET ;; ;AN000; OPEN_FILE ENDP ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; COPY_ARGV0 ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; ;AN000; COPY_ARGV0 PROC ;; ;AN000; ;; ;AN000; PUSH ES ;; ;AN000; PUSH DI ;; ;AN000; PUSH SI ;; ;AN000; ;; ;AN000; MOV DI,2CH ;; Locate environment string ;AN000; MOV ES,[DI] ;; ;AN000; XOR SI,SI ;; ;AN000; .WHILE <<WORD PTR ES:[SI]> NE 0> ;; ;AN000; INC SI ;; ;AN000; .ENDWHILE ;; ;AN000; ADD SI,4 ;; ;AN000; LEA DI,PROFILE_PATH ;; Move string to work area ;AN000; .REPEAT ;; ;AN000; MOV AL,ES:[SI] ;; ;AN000; MOV [DI],AL ;; ;AN000; INC SI ;; ;AN000; INC DI ;; ;AN000; .UNTIL <<BYTE PTR ES:[SI]> EQ 0> ;; ;AN000; MOV BYTE PTR [DI],0 ;; ;AN000; MOV BYTE PTR [DI]-3,"P" ;; Change COM to PRO ;AN000; MOV BYTE PTR [DI]-2,"R" ;; ;AN000; MOV BYTE PTR [DI]-1,"O" ;; ;AN000; ;; ;AN000; POP SI ;; ;AN000; POP DI ;; ;AN000; POP ES ;; ;AN000; RET ;; ;AN000; ;; ;AN000; COPY_ARGV0 ENDP ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; FILE_ERROR_PROC ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; ;AN000; FILE_ERROR_PROC PROC ;; ;AN000; MOV AX,FILE_ERRORS ;; ;AN000; MOV CX,0 ;; ;AN000; CALL DISP_ERROR ;; ;AN000; MOV FILE_ERROR,YES ;; ;AN000; RET ;; ;AN000; FILE_ERROR_PROC ENDP ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; GET_STATEMENT ;AN000; ;; ;AN000; ;; Input Parameters: ;AN000; ;; NONE ;AN000; ;; ;AN000; ;; Output Parameters: ;AN000; ;; PROFILE_LINE ;AN000; ;; RETURN CODE : 0 - successfull read ;AN000; ;; : 1 - end of file ;AN000; ;; : 2 - error during read ;AN000; ;; ;AN000; ;; ;AN000; ;; Data Structures Referenced: ;AN000; ;; ;AN000; ;; Description: ;AN000; ;; Get a statement from the profile. ;AN000; ;; The file read in 512 byte buffers and parsed into ;AN000; ;; lines by the presence of a carriage return at the end of each line. ;AN000; ;; ;AN000; ;; Called By: ;AN000; ;; LOAD_PROFILE ;AN000; ;; ;AN000; ;; External Calls: ;AN000; ;; NONE ;AN000; ;; ;AN000; ;; Logic: ;AN000; ;; FOUND := FALSE ;AN000; ;; RETURN_CODE := 0 ;AN000; ;; WHILE NOT FOUND DO ;AN000; ;; IF end of buffer THEN ;AN000; ;; Read next profile record into buffer ;AN000; ;; IF successful read THEN ;AN000; ;; point to first byte in buffer ;AN000; ;; ELSE ;AN000; ;; IF end of file THEN ;AN000; ;; Close profile ;AN000; ;; RETURN_CODE := 1 ;AN000; ;; FOUND := TRUE ;AN000; ;; ELSE ;AN000; ;; RETURN_CODE := 2 ;AN000; ;; FOUND := TRUE ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; ENDIF ;AN000; ;; copy byte to PROFILE_LINE ;AN000; ;; IF byte in buffer is a CR THEN ;AN000; ;; FOUND := TRUE ;AN000; ;; ENDIF ;AN000; ;; ENDWHILE ;AN000; ;; RETURN ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; FOUND DB 0 ;; ;AN000; ;; ;AN000; CARRIAGE_RET EQU 13 ;; ;AN000; LINE_FEED EQU 10 ;; ;AN000; NEXT_BYTE DB 0 ;; Save area for byte just read ;AN000; BUFFER_SIZE EQU 512 ;; ;AN000; FILE_BUFFER DB 512 DUP(0) ;; ;AN000; BUFFER_PTR DW 512 ;; ;AN000; BUFFER_END DW 512 ;; ;AN000; STMT_BUFFER DB 255 DUP(0) ;; ;AN000; DB ? ;; In case we have to insert a CR ;AN000; DB ? ;; and a LF ;AN000; DB ? ;; Too put the "$" for displaying the ;AN000; ;; line. ;AN000; ;; ;AN000; STMT_END_INDEX DW ? ;; ;AN000; MAX_STMT_LEN EQU 255 ;; ;AN000; CR_FOUND DB 0 ;; 1 if we found a line terminator ;AN000; ;; ;AN000; GET_STATEMENT PROC ;; ;AN000; ;; ;AN000; MOV FOUND,NO ;; ;AN000; MOV STMT_ERROR,0 ;; Clear error flags ;AN000; XOR DI,DI ;; Index for extracted statement ;AN000; MOV SI,BUFFER_PTR ;; Init file buffer ptr ;AN000; ;; ;AN000; MOV AL,NEXT_BYTE ;; Restore current byte ;AN000; MOV CR_FOUND,NO ;; ;AN000; ;; ;AN000; ;; ;AN000; .WHILE <FOUND EQ NO> AND ;; Keep parsing until we find a stmt ;AN000; .WHILE <FILE_ERROR EQ NO> AND ;; or a file error occurs ;AN000; .WHILE <END_OF_FILE EQ NO> ;; or we reach end of file ;AN000; .IF <CR_FOUND EQ YES> ;; ;AN000; .IF <AL EQ LINE_FEED> ;; Return the line feed as well ;AN000; .IF <DI NA MAX_STMT_LEN> ;; Truncate lines longer than MAX ;AN000; MOV STMT_BUFFER[DI],AL ;; MOVE TO statement buffer ;AN000; INC DI ;; Point to next byte in file buffr ;AN000; .ELSE ;; ;AN000; OR STMT_ERROR,INVALID ;; Line has been truncated > ERROR ;AN000; MOV PARSE_ERROR,YES ;; ;AN000; MOV BUILD_STATE,NO ;; ;AN000; .ENDIF ;; ;AN000; CALL GET_BYTE ;; Get the first byte of next statement ;AN000; .ENDIF ;; ;AN000; MOV FOUND,YES ;; Time to leave this WHILE ;AN000; MOV NEXT_BYTE,AL ;; Save the byte we just read ;AN000; .ELSE ;; ;AN000; .IF <DI NA MAX_STMT_LEN> ;; Truncate lines longer than MAX ;AN000; MOV STMT_BUFFER[DI],AL ;; move byte to statement buffer ;AN000; INC DI ;; Point to next byte in file buffer ;AN000; .ELSE ;; ;AN000; OR STMT_ERROR,INVALID ;; Line has been truncated > ERROR ;AN000; MOV PARSE_ERROR,YES ;; ;AN000; MOV BUILD_STATE,NO ;; ;AN000; .ENDIF ;; ;AN000; .IF <AL EQ CARRIAGE_RET> ;; Found a line terminator ;AN000; MOV CR_FOUND,YES ;; Indicate carriage return found ;AN000; .ENDIF ;; and go through once more to ;AN000; CALL GET_BYTE ;; check for a line feed ;AN000; .ENDIF ;; ;AN000; .ENDWHILE ;; ;AN000; ;; ;AN000; .IF <STMT_BUFFER[DI-1] NE CARRIAGE_RET> AND ;; ;AN000; .IF <STMT_BUFFER[DI-1] NE LINE_FEED> ;; ;AN000; MOV STMT_BUFFER[DI],CARRIAGE_RET ;; ;AN000; MOV STMT_BUFFER[DI+1],LINE_FEED ;; ;AN000; INC DI ;; ;AN000; INC DI ;; ;AN000; .ENDIF ;; ;AN000; MOV STMT_END_INDEX,DI ;; ;AN000; MOV BUFFER_PTR,SI ;; Save buffer ptr for next time ;AN000; ;; ;AN000; .IF <END_OF_FILE EQ YES> ;; ;AN000; .IF <DI EQ 0> ;; Clear carry if we read something ;AN000; STC ;; and no file error occured otherwise ;AN000; .ELSE ;; set carry indicating unsuccessful ;AN000; CLC ;; get. ;AN000; .ENDIF ;; ;AN000; .ELSE ;; ;AN000; .IF <FILE_ERROR EQ YES> ;; ;AN000; STC ;; ;AN000; .ELSE ;; ;AN000; CLC ;; ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; RET ;; ;AN000; ;; ;AN000; GET_STATEMENT ENDP ;; ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; GET_BYTE ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; GET_BYTE PROC ;; ;AN000; ;; ;AN000; .IF <SI EQ BUFFER_END> ;; If buffer empty do another read ;AN000; MOV AH,3FH ;; ;AN000; MOV DX,OFFSET FILE_BUFFER ;; ;AN000; MOV CX,BUFFER_SIZE ;; ;AN000; MOV BX,HANDLE ;; ;AN000; INT 21H ;; ;AN000; .IF C ;; Carry set by DOS if file error ;AN000; CALL FILE_ERROR_PROC ;; ;AN000; .ELSE ;; ;AN000; .IF <AX EQ 0> ;; End of file if AX=0 ;AN000; MOV END_OF_FILE,YES ;; ;AN000; MOV AH,3EH ;; Close the file ;AN000; MOV BX,HANDLE ;; ;AN000; INT 21H ;; ;AN000; .ELSE ;; ;AN000; MOV BUFFER_END,AX ;; Number of bytes read ;AN000; XOR SI,SI ;; Buffer pointer := 0 ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; ;; ;AN000; .IF <FILE_ERROR EQ YES> OR ;; ;AN000; .IF <END_OF_FILE EQ YES> ;; ;AN000; STC ;; Unsuccessful get ;AN000; .ELSE ;; ;AN000; .IF <<FILE_BUFFER[SI]> EQ 1AH> ;; cHECK for EOF marker ;AN000; MOV END_OF_FILE,YES ;; ;AN000; STC ;; ;AN000; .ELSE ;; ;AN000; MOV AL,FILE_BUFFER[SI] ;; Return byte in AL ;AN000; INC SI ;; ;AN000; CLC ;; Successful get ;AN000; .ENDIF ;; ;AN000; .ENDIF ;; ;AN000; RET ;; ;AN000; ;; ;AN000; GET_BYTE ENDP ;; ;AN000; ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; ;; Module Name: ;AN000; ;; GROW_SHARED_DATA ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;; ;AN000; GROW_SHARED_DATA PROC ;; ;AN000; PUSH BX ;; ;AN000; ADD BLOCK_END,AX ;; Grow the current block by AX ;AN000; MOV BX,BLOCK_END ;; ;AN000; .IF <BX A NB_FREE_BYTES> ;; Check for overflow ;AN000; MOV BUILD_STATE,NO ;; Stop building shared data ;AN000; MOV MEM_OVERFLOW,YES ;; ;AN000; .ENDIF ;; ;AN000; POP BX ;; ;AN000; RET ;; ;AN000; GROW_SHARED_DATA ENDP ;; ;AN000; ;; ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; ;AN000; CODE ENDS ;; ;AN000; END ;AN000; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|