From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/GRAPHICS/GRLOAD.ASM | 840 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 840 insertions(+) create mode 100644 v4.0/src/CMD/GRAPHICS/GRLOAD.ASM (limited to 'v4.0/src/CMD/GRAPHICS/GRLOAD.ASM') diff --git a/v4.0/src/CMD/GRAPHICS/GRLOAD.ASM b/v4.0/src/CMD/GRAPHICS/GRLOAD.ASM new file mode 100644 index 0000000..dd16ca4 --- /dev/null +++ b/v4.0/src/CMD/GRAPHICS/GRLOAD.ASM @@ -0,0 +1,840 @@ + PAGE ,132 ;AN000; + TITLE DOS - GRAPHICS Command - Profile Load Modules ;AN000; + ;AN000; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000; +;; DOS - GRAPHICS Command +;; (C) Copyright 1988 Microsoft +;; ;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; + ;; ;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; + ;; ;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 ;; 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; + 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 AND ;; Keep parsing until end of file or ;AN000; + .WHILE ;; 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 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 THEN ;; ;AN000; + OR STMT_ERROR,INVALID ;; ;AN000; + MOV PARSE_ERROR,YES ;; ;AN000; + MOV BUILD_STATE,NO ;; ;AN000; + .ENDIF ;; ;AN000; + .IF ;; 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 ;; 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 ;; ;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 ;; ;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 ;; 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 OR ;; ;AN000; + .IF OR ;; ;AN000; + .IF ;; Set carry flag if profile load ;AN000; + STC ;; was unsuccessful ;AN000; + .ELSE ;; ;AN000; + .IF ;; Everthing else was OK BUT we ran ;AN000; + .IF ;; out of memory!!! ;AN000; + MOV AX,NB_FREE_BYTES ;; ;AN000; + .IF ;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 ;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 ;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 ;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 ;; 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 OR ;; Check for error other than ;AN000; + .IF ;; 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 OR ;; Check for file not found error ;AN000; + .IF ;; ;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 OR ;AN000; + .IF ;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 < 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 < 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 AND ;; Keep parsing until we find a stmt ;AN000; + .WHILE AND ;; or a file error occurs ;AN000; + .WHILE ;; or we reach end of file ;AN000; + .IF ;; ;AN000; + .IF ;; Return the line feed as well ;AN000; + .IF ;; 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 ;; 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 ;; 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 AND ;; ;AN000; + .IF ;; ;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 ;; ;AN000; + .IF ;; 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 ;; ;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 ;; 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 ;; 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 OR ;; ;AN000; + .IF ;; ;AN000; + STC ;; Unsuccessful get ;AN000; + .ELSE ;; ;AN000; + .IF < 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 ;; 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; -- cgit v1.2.3