You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1218 lines
56 KiB
1218 lines
56 KiB
;/*
|
|
; * Microsoft Confidential
|
|
; * Copyright (C) Microsoft Corporation 1988 - 1991
|
|
; * All Rights Reserved.
|
|
; */
|
|
;************************************************************
|
|
;**
|
|
;** NAME: Support for HP PCL printers added to GRAPHICS.
|
|
;**
|
|
;** DESCRIPTION: I altered the procedure PARSE_VERB and added the new
|
|
;** procedure PARSE_DEFINE and made it public in order to handle
|
|
;** the new statement DEFINE. I also made the new variable
|
|
;** DATA_TYPE have the default of DATA_COL, so the default
|
|
;** assumes IBM type printers.
|
|
;**
|
|
;** BUG NOTES: Bug mda002 was completely fixed for the pre-release
|
|
;** version Q.01.02, whereas bug mda005 was only partially
|
|
;** fixed. In other words, part of bug mda005 is in the
|
|
;** released versions D.01.01 & D.01.02.
|
|
;**
|
|
;** BUG (mda002)
|
|
;** ------------
|
|
;**
|
|
;** NAME: GRAPHICS prints garbage on PCL printers if IBM printers are
|
|
;** listed after HP printers in the GRAPHICS profile.
|
|
;**
|
|
;** FILES & PROCEDURES AFFECTED: GRLOAD2.ASM - PARSE_PRINTER
|
|
;** GRLOAD2.ASM - PARSE_DEFINE
|
|
;**
|
|
;** CAUSES: 1) In the procedure Parse_Define I was moving values in the
|
|
;** variable DATA_TYPE for every DEFINE statement, instead of
|
|
;** just for the DEFINE statement that corresponded to the
|
|
;** printer we were using.
|
|
;**
|
|
;** 2) In the procedure Parse_Printer I was resetting DATA_TYPE to
|
|
;** DATA_COL if BUILD_STATE = YES, but I was doing it in a
|
|
;** section of code where BUILD_STATE would never be YES.
|
|
;**
|
|
;** FIXES: 1) Made a couple of changes in the procedure Parse_Define so
|
|
;** that values are moved into the variable DATA_TYPE just for
|
|
;** the DEFINE statement that corresponds to the printer
|
|
;** currently being used.
|
|
;**
|
|
;** 2) I moved a section of code from the procedure Parse_Printer
|
|
;** to the end of the procedure, because this is where it is
|
|
;** possible for BUILD_STATE to equal YES.
|
|
;**
|
|
;** BUG (mda005)
|
|
;** ------------
|
|
;**
|
|
;** NAME: If a picture is printed using a 3,1 printbox, the picture has
|
|
;** blank lines throughout the picture, which has the wrong aspect
|
|
;** ratio.
|
|
;**
|
|
;** FILES & PROCEDURES AFFECTED: GRLOAD2.ASM - PARSE_PRINTBOX
|
|
;**
|
|
;** CAUSE: The print buffer was being filled as follows,
|
|
;**
|
|
;** --------------------------
|
|
;** | o o o o o o o o |
|
|
;** --------------------------
|
|
;** |_____| | |_____| |
|
|
;** | | | |
|
|
;** | | | |
|
|
;** FROM: pixel 1 | pixel 2 |
|
|
;** | |
|
|
;** |___________|
|
|
;** |
|
|
;** |
|
|
;** |
|
|
;** Always left blank
|
|
;**
|
|
;** instead of as follows,
|
|
;**
|
|
;** --------------------------
|
|
;** | o o o o o o o o |
|
|
;** --------------------------
|
|
;** |_____| |_____| |__|
|
|
;** | | |
|
|
;** | | |
|
|
;** FROM: pixel 1 pixel 2 pixel 3
|
|
;**
|
|
;** Note that this not only resulted in a strange picture, but a
|
|
;** picture with the incorrect aspect ratio. Because in essence the
|
|
;** picture was printed indirectly with a 4,1 printbox because for
|
|
;** every pixel read four bits were sent to the printer.
|
|
;**
|
|
;** FIX: Because of time constraints it was decided to print the picture
|
|
;** directly with a 4,1 printbox. So even though the picture still
|
|
;** has the wrong aspect ratio, it at least does not have funny blank
|
|
;** lines throughout the entire picture. This fix was implemented by
|
|
;** changing a 3,1 printbox to a 4,1 printbox.
|
|
;**
|
|
;** DOCUMENTATION NOTES: This version of GRLOAD2.ASM differs from the previous
|
|
;** version only in terms of documentation.
|
|
;**
|
|
;**
|
|
;************************************************************
|
|
PAGE ,132 ;AN000;
|
|
TITLE DOS - GRAPHICS Command - Profile Load Modules #2 ;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 GRMSG.EQU ;; ;AN000;
|
|
INCLUDE GRINST.EXT ;; ;AN000;
|
|
INCLUDE GRLOAD.EXT ;; ;AN000;
|
|
INCLUDE GRPARSE.EXT ;; ;AN000;
|
|
INCLUDE GRPATTRN.STR ;; ;AN000;
|
|
INCLUDE GRPATTRN.EXT ;; ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Public Symbols ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
PUBLIC PARSE_VERB ;; ;AN000;
|
|
PUBLIC PARSE_PRINTER ;; ;AN000;
|
|
; \/ ~~mda(001) ---------------------------------
|
|
; Added procedure PARSE_DEFINE
|
|
;
|
|
PUBLIC PARSE_DEFINE ;
|
|
; /\ ~~mda(001) ---------------------------------
|
|
PUBLIC PARSE_DISPLAYMODE ;; ;AN000;
|
|
PUBLIC PARSE_PRINTBOX ;; ;AN000;
|
|
PUBLIC PARSE_SETUP ;; ;AN000;
|
|
PUBLIC PARSE_RESTORE ;; ;AN000;
|
|
PUBLIC TERMINATE_DISPLAYMODE ;; ;AN000;
|
|
PUBLIC TERMINATE_PRINTER ;; ;AN000;
|
|
PUBLIC CUR_PRINTER_TYPE ;; ;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;
|
|
RESULT_BUFFER LABEL BYTE ;; general purpose result buffer ;AN000;
|
|
DB ? ;; operand type ;AN000;
|
|
RESULT_TAG DB 0 ;; operand tag ;AN000;
|
|
DW ? ;; pointer to synonym/keyword ;AN000;
|
|
RESULT_VAL DB ?,?,?,? ;; returned numeric value ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; TERMINATE_DISPLAYMODE ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
TERMINATE_DISPLAYMODE PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV AX,STMTS_DONE ;; ;AN000;
|
|
.IF <PTD_FOUND EQ YES> AND ;; For the matched PTD ;AN000;
|
|
.IF <BIT AX NAND BOX> AND ;; issue "Invalid parm value" ;AN000;
|
|
.IF <PRT_BOX_ERROR EQ NO> ;; message if PRINTBOX ID not ;AN000;
|
|
;; matched in each DISPLAYMODE section ;AN000;
|
|
PUSH AX ;; Save STMT_DONE flags ;AN000;
|
|
MOV AX,INVALID_PB ;; ;AN000;
|
|
MOV CX,0 ;; ;AN000;
|
|
CALL DISP_ERROR ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
MOV PRT_BOX_ERROR,YES ;; Issue this message only once ;AN000;
|
|
POP AX ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
AND AX,GR ;; Check for missing statements is last ;AN000;
|
|
.IF <AX NE GR> ;; DISPLAYMODE section: ;AN000;
|
|
OR STMT_ERROR,MISSING ;; GRAPHICS stmt is required ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
RET ;; ;AN000;
|
|
;; ;AN000;
|
|
TERMINATE_DISPLAYMODE ENDP ;; ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; TERMINATE_PRINTER ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
TERMINATE_PRINTER PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV AX,BLOCK_END ;; ;AN000;
|
|
.IF <AX A MAX_BLOCK_END> ;; Keep track of the largest PRINTER ;AN000;
|
|
MOV MAX_BLOCK_END,AX ;; section so we can allow space for ;AN000;
|
|
.ENDIF ;; reload with a different printer ;AN000;
|
|
;; type. ;AN000;
|
|
;; ;AN000;
|
|
;; Check for missing statements ;AN000;
|
|
MOV AX,STMTS_DONE ;; ;AN000;
|
|
AND AX,DISP ;; At least one DISPLAYMODE ;AN000;
|
|
.IF <AX NE DISP> ;; must have been found in last ;AN000;
|
|
OR STMT_ERROR,MISSING ;; PRINTER section ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
RET ;; ;AN000;
|
|
;; ;AN000;
|
|
TERMINATE_PRINTER ENDP ;; ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; PARSE_PRINTER ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
PRINTER_PARSE_PARMS LABEL WORD ;; Parser control blocks ;AN000;
|
|
DW PRINTER_P ;; ;AN000;
|
|
DB 2 ;; # of lists ;AN000;
|
|
DB 0 ;; # items in delimeter list ;AN000;
|
|
DB 1 ;; # items in end-of-line list ;AN000;
|
|
DB ';' ;; ';' used for comments ;AN000;
|
|
;; ;AN000;
|
|
PRINTER_P DB 0,1 ;; Required, max parms ;AN000;
|
|
DW PRINTER_P1 ;; ;AN000;
|
|
DB 0 ;; # Switches ;AN000;
|
|
DB 0 ;; # keywords ;AN000;
|
|
;; ;AN000;
|
|
PRINTER_P1 DW 2000H ;; simple string ;AN000;
|
|
DW 0002H ;; Capitalize using character table ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW PRINTER_P1V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
PRINTER_P1V DB 3 ;; # of value lists ;AN000;
|
|
DB 0 ;; # of range numerics ;AN000;
|
|
DB 0 ;; # of discrete numerics ;AN000;
|
|
DB 1 ;; # of strings ;AN000;
|
|
DB 1 ;; tag: index into verb jump table ;AN000;
|
|
PRINTER_P1V1 DW ? ;; string offset ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
CUR_PRINTER_TYPE DB 0 ;; Type of printer currently being ;AN000;
|
|
;; parsed: 1-color 2-b&w ;AN000;
|
|
;; ;AN000;
|
|
PARSE_PRINTER PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV CUR_STMT,PRT ;; ;AN000;
|
|
MOV CUR_PRINTER_TYPE,BLACK_WHITE ;; Assume black & white until we hit ;AN000;
|
|
;; a COLORPRINT ;AN000;
|
|
;; ;AN000;
|
|
.IF <BIT STMTS_DONE AND PRT> ;; If not the first PRINTER section ;AN000;
|
|
CALL TERMINATE_DISPLAYMODE ;; then clean up the last one and ;AN000;
|
|
CALL TERMINATE_PRINTER ;; the last DISPLAYMODE section. ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV AX,FIRST_BLOCK ;; ;AN000;
|
|
MOV BLOCK_START,AX ;; Reset block pointers to start ;AN000;
|
|
MOV BLOCK_END,AX ;; of variable area ;AN000;
|
|
;; ;AN000;
|
|
MOV STMTS_DONE,PRT ;; Clear all bits except for PRT ;AN000;
|
|
MOV GROUPS_DONE,0 ;; Clear ;AN000;
|
|
;; ;AN000;
|
|
.IF <PTD_FOUND EQ YES> ;; PRINTER statement marks the end of ;AN000;
|
|
MOV PTD_FOUND,PROCESSED ;; the previous PTD ;AN000;
|
|
MOV BUILD_STATE,NO ;; Stop building shared data ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV CL,TAB_DIR_NB_ENTRIES ;; Reset the pattern table copy ;AN000;
|
|
XOR CH,CH ;; pointers. These pointers ;AN000;
|
|
MOV BX,OFFSET TAB_DIRECTORY ;; are established when a pattern ;AN000;
|
|
.REPEAT ;; table is copied to the shared ;AN000;
|
|
MOV [BX].TAB_COPY,-1 ;; data area. Initially they ;AN000;
|
|
ADD BX,SIZE TAB_ENTRY ;; are -1. ;AN000;
|
|
.LOOP ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV AX,OFFSET PRINTER_TYPE_PARM ;; Store printer type from command ;AN000;
|
|
MOV PRINTER_P1V1,AX ;; line in value list ;AN000;
|
|
MOV DI,OFFSET PRINTER_PARSE_PARMS ;; parse parms ;AN000;
|
|
;; SI => the line to parse ;AN000;
|
|
XOR DX,DX ;; ;AN000;
|
|
;; ;AN000;
|
|
.REPEAT ;; ;AN000;
|
|
XOR CX,CX ;; Don't worry about number of operands ;AN000;
|
|
CALL SYSPARSE ;; ;AN000;
|
|
.IF <AX EQ 9> ;; Syntax error is the only thing ;AN000;
|
|
OR STMT_ERROR,INVALID ;; which can go wrong ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.UNTIL <AX EQ 0> OR ;; ;AN000;
|
|
.UNTIL <AX EQ -1> ;; ;AN000;
|
|
;; Printer type parm matched one coded ;AN000;
|
|
;; on the PRINTER statement ;AN000;
|
|
.IF <AX EQ 0> ;; ;AN000;
|
|
.IF <PTD_FOUND EQ NO> ;; ;AN000;
|
|
MOV PTD_FOUND,YES ;; If the printer type matches and ;AN000;
|
|
.IF <PARSE_ERROR EQ NO> AND ;; no errors have been found yet ;AN000;
|
|
.IF <PRT_BOX_ERROR EQ NO> AND ;; ;AN000;
|
|
.IF <MEM_OVERFLOW EQ NO> ;; ;AN000;
|
|
MOV BUILD_STATE,YES ;; then start building the shared ;AN000;
|
|
.ENDIF ;; data ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ELSE ;; No match ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.IF <AX NE -1> ;; Error during parse ;AN000;
|
|
OR STMT_ERROR,INVALID ;; set error flag for caller ;AN000;
|
|
MOV PARSE_ERROR,YES ;; set error flag for caller ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
; \/ ~~mda(002) -----------------------------------------------------------------------
|
|
.IF <BUILD_STATE EQ YES> ;;
|
|
MOV [BP].DATA_TYPE,DATA_COL;; Set DATA_TYPE back to default of DATA_COL
|
|
.ENDIF ;; for new PTD.
|
|
; /\ ~~mda(002) -----------------------------------------------------------------------
|
|
;; ;AN000;
|
|
RET ;AN000;
|
|
;; ;AN000;
|
|
PARSE_PRINTER ENDP ;AN000;
|
|
;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
|
|
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; PARSE_DISPLAYMODE ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
DISPMODE_PARSE_PARMS LABEL WORD ;; Parser control blocks ;AN000;
|
|
DW DISPMODE_P ;; ;AN000;
|
|
DB 2 ;; # of lists ;AN000;
|
|
DB 0 ;; # items in delimeter list ;AN000;
|
|
DB 1 ;; # items in end-of-line list ;AN000;
|
|
DB ';' ;; ';' used for comments ;AN000;
|
|
;; ;AN000;
|
|
DISPMODE_P DB 0,1 ;; Required, max parms ;AN000;
|
|
DW DISPMODE_P1 ;; ;AN000;
|
|
DB 0 ;; # Switches ;AN000;
|
|
DB 0 ;; # keywords ;AN000;
|
|
;; ;AN000;
|
|
DISPMODE_P1 DW 8000H ;; Numeric ;AN000;
|
|
DW 0 ;; No Capitalize ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW DISPMODE_P1V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
DISPMODE_P1V DB 1 ;; # of value lists ;AN000;
|
|
DB 1 ;; # of range numerics ;AN000;
|
|
DB 1 ;; tag ;AN000;
|
|
DD 0,19 ;; range 0..19 ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_DISPLAYMODE PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV CUR_STMT,DISP ;; ;AN000;
|
|
;; Check for a preceeding PRINTER ;AN000;
|
|
.IF <BIT STMTS_DONE NAND PRT> ;; ;AN000;
|
|
OR STMT_ERROR,MISSING ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
.IF <BIT STMTS_DONE NAND DISP> ;; If first DISPLAYMODE... ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
MOV AX,BLOCK_END ;; ;AN000;
|
|
MOV [BP].DISPLAYMODE_PTR,AX ;; Set pointer to first DISPLAYMODE ;AN000;
|
|
MOV BLOCK_START,AX ;; New block starts after last one ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
CALL TERMINATE_DISPLAYMODE ;; If not the first DISPLAYMODE then ;AN000;
|
|
;; clean up the last one. ;AN000;
|
|
MOV DI,BLOCK_START ;; DI=pointer to DISPLAYMODE block just ;AN000;
|
|
MOV AX,BLOCK_END ;; built ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
MOV [BP+DI].NEXT_DISP_MODE,AX ;; Add new block to DISPLAYMODE chain ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
MOV BLOCK_START,AX ;; New block starts after last one ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV AX,SIZE DISPLAYMODE_STR ;; Allocate space for new DISPLAYMODE ;AN000;
|
|
CALL GROW_SHARED_DATA ;; block ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; Start of new block ;AN000;
|
|
MOV [BP+DI].NUM_SETUP_ESC,0 ;; SETUP, RESTORE are optional so set ;AN000;
|
|
MOV [BP+DI].NUM_RESTORE_ESC,0 ;; to defaults ;AN000;
|
|
MOV [BP+DI].SETUP_ESC_PTR,-1 ;; ;AN000;
|
|
MOV [BP+DI].RESTORE_ESC_PTR,-1 ;; ;AN000;
|
|
MOV [BP+DI].BOX_WIDTH,0 ;; ;AN000;
|
|
MOV [BP+DI].BOX_HEIGHT,0 ;; ;AN000;
|
|
MOV [BP+DI].PRINT_OPTIONS,0 ;; Default to NO print options ;AN000;
|
|
MOV [BP+DI].NUM_DISP_MODE,0 ;; Get ready to INC this ;AN000;
|
|
MOV [BP+DI].NEXT_DISP_MODE,-1 ;; This is the last DISPLAYMODE for now! ;AN000;
|
|
MOV AX,BLOCK_END ;; ;AN000;
|
|
MOV [BP+DI].DISP_MODE_LIST_PTR,AX;; Start mode list at end of new block ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
OR STMTS_DONE,DISP ;; Indicate DISPLAYMODE found ;AN000;
|
|
AND STMTS_DONE,NOT (BOX+GR+SET+REST) ;; Reset flags for PRINTBOX, GRAPHICS ;AN000;
|
|
;; stmts found ;AN000;
|
|
AND GROUPS_DONE,NOT (GR+SET+REST) ;; Reset flags for GRAPHICS, SETUP, ;AN000;
|
|
;; RESTORE groups processed ;AN000;
|
|
MOV DI,OFFSET DISPMODE_PARSE_PARMS ;; parse parms ;AN000;
|
|
;; SI => the line to parse ;AN000;
|
|
XOR DX,DX ;; ;AN000;
|
|
.REPEAT ;; ;AN000;
|
|
XOR CX,CX ;; ;AN000;
|
|
CALL SYSPARSE ;; ;AN000;
|
|
.IF <AX EQ 0> ;; If mode is valid ;AN000;
|
|
PUSH AX ;; ;AN000;
|
|
MOV AX,1 ;; Add a mode to the list ;AN000;
|
|
CALL GROW_SHARED_DATA ;; Update block end ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
PUSH DI ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
INC [BP+DI].NUM_DISP_MODE ;; Bump number of modes in list ;AN000;
|
|
MOV DI,BLOCK_END ;; ;AN000;
|
|
MOV AL,RESULT_VAL ;; Get mode from result buffer ;AN000;
|
|
MOV [BP+DI-1],AL ;; Store the mode at end of list ;AN000;
|
|
POP DI ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
POP AX ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX NE -1> ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; Mode is invalid ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.UNTIL <AX EQ -1> ;; ;AN000;
|
|
;; ;AN000;
|
|
RET ;AN000;
|
|
;; ;AN000;
|
|
PARSE_DISPLAYMODE ENDP ;AN000;
|
|
;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; PARSE_SETUP ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
SETUP_PARSE_PARMS LABEL WORD ;; Parser control blocks ;AN000;
|
|
DW SETUP_P ;; ;AN000;
|
|
DB 2 ;; # of lists ;AN000;
|
|
DB 0 ;; # items in delimeter list ;AN000;
|
|
DB 1 ;; # items in end-of-line list ;AN000;
|
|
DB ';' ;; ';' used for comments ;AN000;
|
|
;; ;AN000;
|
|
SETUP_P DB 0,1 ;; Required, max parms ;AN000;
|
|
DW SETUP_P1 ;; ;AN000;
|
|
DB 0 ;; # Switches ;AN000;
|
|
DB 0 ;; # keywords ;AN000;
|
|
;; ;AN000;
|
|
SETUP_P1 DW 08000H ;; Numeric ;AN000;
|
|
DW 0 ;; nO Capitalize ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW SETUP_P1V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
SETUP_P1V DB 1 ;; # of value lists ;AN000;
|
|
DB 1 ;; # of range numerics ;AN000;
|
|
DB 1 ;; tag ;AN000;
|
|
DD 0,255 ;; range 0..255 ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_SETUP PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV CUR_STMT,SET ;; ;AN000;
|
|
.IF <BIT STMTS_DONE NAND DISP> ;; DISPLAYMODE must preceed this ;AN000;
|
|
OR STMT_ERROR,MISSING ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
.IF <BIT GROUPS_DONE AND SET> ;; Check for previous group of SETUP ;AN000;
|
|
OR STMT_ERROR,SEQUENCE ;; stmts ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
.IF <BIT STMTS_DONE NAND SET> ;; If first SETUP... ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
MOV AX,BLOCK_END ;; ;AN000;
|
|
MOV [BP+DI].SETUP_ESC_PTR,AX ;; Set pointer to SETUP seq ;AN000;
|
|
MOV [BP+DI].NUM_SETUP_ESC,0 ;; Init sequence size ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
OR STMTS_DONE,SET ;; Indicate SETUP found ;AN000;
|
|
.IF <PREV_STMT NE SET> THEN ;; Terminate any preceeding groups ;AN000;
|
|
MOV AX,PREV_STMT ;; except for SETUP group ;AN000;
|
|
OR GROUPS_DONE,AX ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV DI,OFFSET SETUP_PARSE_PARMS ;; parse parms ;AN000;
|
|
;; SI => the line to parse ;AN000;
|
|
XOR DX,DX ;; ;AN000;
|
|
.REPEAT ;; ;AN000;
|
|
XOR CX,CX ;; ;AN000;
|
|
CALL SYSPARSE ;; ;AN000;
|
|
.IF <AX EQ 0> ;; If esc byte is valid ;AN000;
|
|
PUSH AX ;; ;AN000;
|
|
MOV AX,1 ;; Add a byte to the sequence ;AN000;
|
|
CALL GROW_SHARED_DATA ;; Update block end ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
PUSH DI ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
INC [BP+DI].NUM_SETUP_ESC ;; Bump number of bytes in sequence ;AN000;
|
|
MOV DI,BLOCK_END ;; ;AN000;
|
|
MOV AL,RESULT_VAL ;; Get esc byte from result buffer ;AN000;
|
|
MOV [BP+DI-1],AL ;; Store at end of sequence ;AN000;
|
|
POP DI ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
POP AX ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX NE -1> ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; parm is invalid ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.UNTIL <AX EQ -1> NEAR ;; ;AN000;
|
|
RET ;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_SETUP ENDP ;; ;AN000;
|
|
;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; PARSE_RESTORE ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
RESTORE_PARSE_PARMS LABEL WORD ;; Parser control blocks ;AN000;
|
|
DW RESTORE_P ;; ;AN000;
|
|
DB 2 ;; # of lists ;AN000;
|
|
DB 0 ;; # items in delimeter list ;AN000;
|
|
DB 1 ;; # items in end-of-line list ;AN000;
|
|
DB ';' ;; ';' used for comments ;AN000;
|
|
;; ;AN000;
|
|
RESTORE_P DB 0,1 ;; Required, max parms ;AN000;
|
|
DW RESTORE_P1 ;; ;AN000;
|
|
DB 0 ;; # Switches ;AN000;
|
|
DB 0 ;; # keywords ;AN000;
|
|
;; ;AN000;
|
|
RESTORE_P1 DW 08000H ;; Numeric ;AN000;
|
|
DW 0 ;; nO Capitalize ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW RESTORE_P1V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
RESTORE_P1V DB 1 ;; # of value lists ;AN000;
|
|
DB 1 ;; # of range numerics ;AN000;
|
|
DB 1 ;; tag ;AN000;
|
|
DD 0,255 ;; range 0..255 ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_RESTORE PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV CUR_STMT,SET ;; ;AN000;
|
|
.IF <BIT STMTS_DONE NAND DISP> ;; DISPLAYMODE must preceed this ;AN000;
|
|
OR STMT_ERROR,MISSING ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
.IF <BIT GROUPS_DONE AND REST> ;; Check for previous group of RESTORE ;AN000;
|
|
OR STMT_ERROR,SEQUENCE ;; stmts ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
.IF <BIT STMTS_DONE NAND REST> ;; If first RESTORE... ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
MOV AX,BLOCK_END ;; ;AN000;
|
|
MOV [BP+DI].RESTORE_ESC_PTR,AX ;; Set pointer to RESTORE seq ;AN000;
|
|
MOV [BP+DI].NUM_RESTORE_ESC,0 ;; Init sequence size ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
OR STMTS_DONE,REST ;; Indicate RESTORE found ;AN000;
|
|
.IF <PREV_STMT NE REST> THEN ;; Terminate any preceeding groups ;AN000;
|
|
MOV AX,PREV_STMT ;; except for RESTORE group ;AN000;
|
|
OR GROUPS_DONE,AX ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV DI,OFFSET RESTORE_PARSE_PARMS ;; parse parms ;AN000;
|
|
;; SI => the line to parse ;AN000;
|
|
XOR DX,DX ;; ;AN000;
|
|
.REPEAT ;; ;AN000;
|
|
XOR CX,CX ;; ;AN000;
|
|
CALL SYSPARSE ;; ;AN000;
|
|
.IF <AX EQ 0> ;; If esc byte is valid ;AN000;
|
|
PUSH AX ;; ;AN000;
|
|
MOV AX,1 ;; Add a byte to the sequence ;AN000;
|
|
CALL GROW_SHARED_DATA ;; Update block end ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
PUSH DI ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
INC [BP+DI].NUM_RESTORE_ESC ;; Bump number of bytes in sequence ;AN000;
|
|
MOV DI,BLOCK_END ;; ;AN000;
|
|
MOV AL,RESULT_VAL ;; Get esc byte from result buffer ;AN000;
|
|
MOV [BP+DI-1],AL ;; Store at end of sequence ;AN000;
|
|
POP DI ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
POP AX ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX NE -1> ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; parm is invalid ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.UNTIL <AX EQ -1> NEAR ;; ;AN000;
|
|
RET ;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_RESTORE ENDP ;; ;AN000;
|
|
;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; PARSE_PRINTBOX ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_PARSE_PARMS LABEL WORD ;; Parser control blocks ;AN000;
|
|
DW PRINTBOX_P ;; ;AN000;
|
|
DB 2 ;; # of lists ;AN000;
|
|
DB 0 ;; # items in delimeter list ;AN000;
|
|
DB 1 ;; # items in end-of-line list ;AN000;
|
|
DB ';' ;; ';' used for comments ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P DB 1,4 ;; Required, max parms ;AN000;
|
|
DW PRINTBOX_P0 ;; LCD/STD ;AN000;
|
|
DW PRINTBOX_P1 ;; width ;AN000;
|
|
DW PRINTBOX_P1 ;; height ;AN000;
|
|
DW PRINTBOX_P2 ;; rotate ;AN000;
|
|
DB 0 ;; # Switches ;AN000;
|
|
DB 0 ;; # keywords ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P0 DW 2000H ;; sTRING - display type ;AN000;
|
|
DW 2 ;; Capitalize ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW PRINTBOX_P0V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P0V DB 3 ;; # of value lists ;AN000;
|
|
DB 0 ;; # of range numerics ;AN000;
|
|
DB 0 ;; # of discrete numerics ;AN000;
|
|
DB 1 ;; # of strings ;AN000;
|
|
DB 1 ;; tag ;AN000;
|
|
PRINTBOX_P0V1 DW ? ;; string ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P1 DW 8001H ;; Numeric - BOX DIMENSIONS ;AN000;
|
|
DW 0 ;; No Capitalize ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW PRINTBOX_P1V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P1V DB 1 ;; # of value lists ;AN000;
|
|
DB 1 ;; # of range numerics ;AN000;
|
|
DB 1 ;; tag ;AN000;
|
|
DD 1,9 ;; range 1..9 ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P2 DW 2001H ;; sTRING - ROTATE PARM ;AN000;
|
|
DW 2 ;; Capitalize ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW PRINTBOX_P2V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_P2V DB 3 ;; # of value lists ;AN000;
|
|
DB 0 ;; # of range numerics ;AN000;
|
|
DB 0 ;; # of discrete numerics ;AN000;
|
|
DB 1 ;; # of strings ;AN000;
|
|
DB 1 ;; tag ;AN000;
|
|
DW ROTATE_STR ;; string ;AN000;
|
|
ROTATE_STR DB 'ROTATE',0 ;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PROF_BOX_W DB 0 ;; Box width and height extracted from ;AN000;
|
|
PROF_BOX_H DB 0 ;; the profile ;AN000;
|
|
PRINTBOX_MATCH DB 0 ;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_PRINTBOX PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV PRINTBOX_MATCH,NO ;; Start out assuming the PRINTBOX ID ;AN000;
|
|
MOV PROF_BOX_W,0 ;; does not match the one requested ;AN000;
|
|
MOV PROF_BOX_H,0 ;; ;AN000;
|
|
MOV CUR_STMT,BOX ;; ;AN000;
|
|
.IF <BIT STMTS_DONE NAND DISP> ;; DISPLAYMODE must preceed PRINTBOX ;AN000;
|
|
OR STMT_ERROR,MISSING ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; Multiple PRINTBOX stmts may be coded ;AN000;
|
|
;; We must decide if this one ;AN000;
|
|
;; matches the requested display type ;AN000;
|
|
;; If not, ignore the statement ;AN000;
|
|
MOV DI,OFFSET PRINTBOX_PARSE_PARMS ;; parse parms ;AN000;
|
|
;; SI => the line to parse ;AN000;
|
|
XOR DX,DX ;; ;AN000;
|
|
XOR CX,CX ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV AX,PRINTBOX_ID_PTR ;; Insert requested display type in ;AN000;
|
|
MOV PRINTBOX_P0V1,AX ;; parser value list ;AN000;
|
|
CALL SYSPARSE ;; PARSE display type ;AN000;
|
|
.IF <AX EQ 0> ;; If ID matches then set this flag. ;AN000;
|
|
MOV PRINTBOX_MATCH,YES ;; ;AN000;
|
|
OR STMTS_DONE,BOX ;; Indicate PRINTBOX found ;AN000;
|
|
MOV AX,PREV_STMT ;; Terminate any preceeding groups ;AN000;
|
|
OR GROUPS_DONE,AX ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
CALL SYSPARSE ;; PARSE horizontal dimension ;AN000;
|
|
.IF <AX EQ 0> ;; ;AN000;
|
|
MOV BL,RESULT_VAL ;; ;AN000;
|
|
|
|
; \/ ~~mda(005) -----------------------------------------------------------------------
|
|
; Presently a 3,1 printbox is not supported for HP PCL printers, but
|
|
; a 4,1 printbox is supported. The reason for this is that one byte
|
|
; is printed at a time and only two 3,1 print boxes are placed in
|
|
; the one byte print buffer, leaving two blank bits. This causes
|
|
; the picture to have blank lines running through it and results in
|
|
; a 4,1 printbox. Instead of placing only two 3,1 print boxes in
|
|
; the print buffer, two 3,1 print boxes plus a partial 3,1 printbox
|
|
; should be placed in the print buffer. Another solution is to
|
|
; make the print buffer be three bytes long, and place eight 3,1
|
|
; print boxes in the three byte long print buffer. Since the present
|
|
; implementation results in a faulty 4,1 printbox, we change the 3,1
|
|
; printbox to a 4,1 printbox up front. So even though we still
|
|
; have a 4,1 printbox, at least we will have an accurate picture.
|
|
.IF <[BP].DATA_TYPE EQ DATA_ROW> AND
|
|
.IF <BL EQ 3>
|
|
MOV BL,4
|
|
.ENDIF
|
|
; /\ ~~mda(005) -----------------------------------------------------------------------
|
|
|
|
MOV PROF_BOX_W,BL ;; Save in local var ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX EQ -1> ;; ;AN000;
|
|
JMP PRINTBOX_DONE ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
CALL SYSPARSE ;; PARSE vertical dimension ;AN000;
|
|
.IF <AX EQ 0> ;; ;AN000;
|
|
MOV BL,RESULT_VAL ;; ;AN000;
|
|
MOV PROF_BOX_H,BL ;; Save in local var ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX EQ -1> ;; ;AN000;
|
|
JMP SHORT PRINTBOX_DONE ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
CALL SYSPARSE ;; Parse ROTATE parm ;AN000;
|
|
.IF <AX EQ 0> ;; ;AN000;
|
|
.IF <BUILD_STATE EQ YES> AND ;; ;AN000;
|
|
.IF <PRINTBOX_MATCH EQ YES> ;; ;AN000;
|
|
PUSH DI ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
OR [BP+DI].PRINT_OPTIONS,ROTATE ;; ;AN000;
|
|
POP DI ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX EQ -1> ;; ;AN000;
|
|
JMP SHORT PRINTBOX_DONE ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
CALL SYSPARSE ;; CHECK FOR EXTRA PARMS ;AN000;
|
|
.IF <AX NE -1> ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PRINTBOX_DONE: ;; ;AN000;
|
|
;; ;AN000;
|
|
.IF <BUILD_STATE EQ YES> AND ;; Store the PRINTBOX dimensions ;AN000;
|
|
.IF <PRINTBOX_MATCH EQ YES> ;; ;AN000;
|
|
PUSH DI ;; in the DISPLAYMODE block ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
MOV AL,PROF_BOX_W ;; ;AN000;
|
|
MOV [BP+DI].BOX_WIDTH,AL ;; ;AN000;
|
|
MOV AL,PROF_BOX_H ;; ;AN000;
|
|
MOV [BP+DI].BOX_HEIGHT,AL ;; ;AN000;
|
|
POP DI ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
;; If we have a B&W printer then ;AN000;
|
|
;; load the grey patterns for the ;AN000;
|
|
;; requested print box size. ;AN000;
|
|
.IF <CUR_PRINTER_TYPE EQ BLACK_WHITE> NEAR ;AN000;
|
|
;; ;AN000;
|
|
.IF <PROF_BOX_W NE 0> AND NEAR ;; Dimensions could also be 0 if the ;AN000;
|
|
.IF <PROF_BOX_H NE 0> NEAR ;; printbox ID does not apply to this;AN000;
|
|
;; displaymode, so don't try for ;AN000;
|
|
;; a pattern! ;AN000;
|
|
MOV BX,OFFSET TAB_DIRECTORY ;; ;AN000;
|
|
MOV CL,TAB_DIR_NB_ENTRIES ;; ;AN000;
|
|
XOR CH,CH ;; ;AN000;
|
|
MOV DI,BLOCK_START ;; ;AN000;
|
|
MOV AL,PROF_BOX_W ;; Requested box width ;AN000;
|
|
MOV AH,PROF_BOX_H ;; Requested box height ;AN000;
|
|
.REPEAT ;; ;AN000;
|
|
.IF <[BX].BOX_W_PAT EQ AL> AND ;; ;AN000;
|
|
.IF <[BX].BOX_H_PAT EQ AH> ;; ;AN000;
|
|
.LEAVE ;; ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
ADD BX,SIZE TAB_ENTRY ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.LOOP ;; ;AN000;
|
|
.IF <ZERO CX> ;; ;AN000;
|
|
OR STMT_ERROR,INVALID ;; Unsupported box size ;AN000;
|
|
MOV PARSE_ERROR,YES ;; ;AN000;
|
|
MOV BUILD_STATE,NO ;; ;AN000;
|
|
.ELSE NEAR ;; Box size OK - pattern tab found ;AN000;
|
|
.IF <[BX].TAB_COPY NE -1> ;; Pointer is NOT null if the table ;AN000;
|
|
MOV AX,[BX].TAB_COPY ;; has already been copied to ;AN000;
|
|
;; the shared data area. ;AN000;
|
|
.IF <BUILD_STATE EQ YES> AND ;; Point to the copy. ;AN000;
|
|
.IF <PRINTBOX_MATCH EQ YES> ;; Establish pointer to table ONLY ;AN000;
|
|
MOV [BP+DI].PATTERN_TAB_PTR,AX ;; if the PB ID matched. ;AN000;
|
|
MOV AL,[BX].NB_INT ;; Number of table entries (intensitie;AN000;
|
|
MOV [BP+DI].NUM_PATTERNS,AL ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ELSE ;; Otherwise we have to copy it. ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; Copy the table even if the printbox ID didn't match! ;AN000;
|
|
;; This is a simple way to reserve enough space to allow reloading ;AN000;
|
|
;; with a different PRINTBOX ID specified on the command line. ;AN000;
|
|
;; This scheme avoids storing ;AN000;
|
|
;; duplicate tables but may reserve slightly more space ;AN000;
|
|
;; (probably only a hundred bytes or so) than ;AN000;
|
|
;; could ever be required. The optimal solution (too ;AN000;
|
|
;; complicated!) would involve keeping running totals for each ;AN000;
|
|
;; PRINTBOX ID coded. ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
MOV DI,BLOCK_END ;; Copy it onto the end of the ;AN000;
|
|
;; current block ;AN000;
|
|
MOV DX,DI ;; Save start addr of the copy ;AN000;
|
|
MOV [BX].TAB_COPY,DX ;; Store ptr to copy in the directory ;AN000;
|
|
MOV AX,[BX].TAB_SIZE ;; ;AN000;
|
|
CALL GROW_SHARED_DATA ;; Allocate room for the table ;AN000;
|
|
.IF <BUILD_STATE EQ YES> ;; ;AN000;
|
|
MOV CX,AX ;; Number of bytes to copy ;AN000;
|
|
PUSH SI ;; Save parse pointer ;AN000;
|
|
MOV SI,[BX].TAB_OFFSET ;; Source pointer ;AN000;
|
|
ADD DI,BP ;; make DI an absolute pointer (dest) ;AN000;
|
|
REP MOVSB ;; Move it! ;AN000;
|
|
POP SI ;; ;AN000;
|
|
.IF <PRINTBOX_MATCH EQ YES> ;; Establish pointer to table ONLY ;AN000;
|
|
MOV DI,BLOCK_START ;; Establish pointer in DISPLAYMODE;AN000;
|
|
MOV [BP+DI].PATTERN_TAB_PTR,DX ;; info ;AN000;
|
|
MOV AL,[BX].NB_INT ;; Number of table entries (intens);AN000;
|
|
MOV [BP+DI].NUM_PATTERNS,AL ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
RET ;; ;AN000;
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_PRINTBOX ENDP ;AN000;
|
|
;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
;; Module Name: ;AN000;
|
|
;; PARSE_VERB ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
;; ;AN000;
|
|
VERB_PARSE_PARMS LABEL WORD ;; Parser control blocks to parse verb ;AN000;
|
|
DW VERB_P ;; Parser control blocks to parse verb ;AN000;
|
|
DB 2 ;; # of lists ;AN000;
|
|
DB 0 ;; # items in delimeter list ;AN000;
|
|
DB 1 ;; # items in end-of-line list ;AN000;
|
|
DB ';' ;; ';' used for comments ;AN000;
|
|
;; ;AN000;
|
|
VERB_P DB 0,1 ;; Required, max parms ;AN000;
|
|
DW VERB_P1 ;; ;AN000;
|
|
DB 0 ;; # Switches ;AN000;
|
|
DB 0 ;; # keywords ;AN000;
|
|
;; ;AN000;
|
|
VERB_P1 DW 2000H ;; simple string ;AN000;
|
|
DW 0002H ;; Capitalize using character table ;AN000;
|
|
DW RESULT_BUFFER ;; Result buffer ;AN000;
|
|
DW VERB_P1V ;; Value list ;AN000;
|
|
DB 0 ;; Synomyms ;AN000;
|
|
;; ;AN000;
|
|
VERB_P1V DB 3 ;; # of value lists ;AN000;
|
|
DB 0 ;; # of range numerics ;AN000;
|
|
DB 0 ;; # of discrete numerics ;AN000;
|
|
;\/ ~~mda(001) ----------------------------------------------------------
|
|
; Changed the number of strings from 9 to 10 because of the
|
|
; new DEFINE statement.
|
|
DB 10 ;; # of strings ;AN000;
|
|
;/\ ~~mda(001) ----------------------------------------------------------
|
|
DB 0 ;; tag: index into verb jump table ;AN000;
|
|
DW PRINTER_STRING ;; string offset ;AN000;
|
|
DB 2 ;; tag ;AN000;
|
|
DW DISPLAYMODE_STRING ;; string offset ;AN000;
|
|
DB 4 ;; tag ;AN000;
|
|
DW PRINTBOX_STRING ;; string offset ;AN000;
|
|
DB 6 ;; tag ;AN000;
|
|
DW SETUP_STRING ;; string offset ;AN000;
|
|
DB 8 ;; tag ;AN000;
|
|
DW RESTORE_STRING ;; string offset ;AN000;
|
|
DB 10 ;; tag ;AN000;
|
|
DW GRAPHICS_STRING ;; string offset ;AN000;
|
|
DB 12 ;; tag ;AN000;
|
|
DW COLORPRINT_STRING ;; string offset ;AN000;
|
|
DB 14 ;; tag ;AN000;
|
|
DW COLORSELECT_STRING ;; string offset ;AN000;
|
|
DB 16 ;; tag ;AN000;
|
|
DW DARKADJUST_STRING ;; string offset ;AN000;
|
|
;\/ ~~mda(001) ----------------------------------------------------------
|
|
; Added DEFINE_STRING to the value list.
|
|
;
|
|
DB 18 ;; tag
|
|
DW DEFINE_STRING ;; string offset
|
|
;/\ ~~mda(001) ----------------------------------------------------------
|
|
PRINTER_STRING DB 'PRINTER',0 ;; ;AN000;
|
|
DISPLAYMODE_STRING DB 'DISPLAYMODE',0 ;; ;AN000;
|
|
PRINTBOX_STRING DB 'PRINTBOX',0 ;; ;AN000;
|
|
SETUP_STRING DB 'SETUP',0 ;; ;AN000;
|
|
RESTORE_STRING DB 'RESTORE',0 ;; ;AN000;
|
|
GRAPHICS_STRING DB 'GRAPHICS',0 ;; ;AN000;
|
|
COLORPRINT_STRING DB 'COLORPRINT',0 ;; ;AN000;
|
|
COLORSELECT_STRING DB 'COLORSELECT',0 ;; ;AN000;
|
|
DARKADJUST_STRING DB 'DARKADJUST',0 ;; ;AN000;
|
|
;\/ ~~mda(001) ----------------------------------------------------------
|
|
; Added the DEFINE_STRING.
|
|
;
|
|
DEFINE_STRING DB 'DEFINE',0 ;;
|
|
;/\ ~~mda(001) ----------------------------------------------------------
|
|
;; ;AN000;
|
|
;; ;AN000;
|
|
PARSE_VERB PROC ;; ;AN000;
|
|
;; ;AN000;
|
|
MOV DI,OFFSET VERB_PARSE_PARMS ;; parse parms ;AN000;
|
|
MOV SI,OFFSET STMT_BUFFER ;; the line to parse ;AN000;
|
|
XOR DX,DX ;; ;AN000;
|
|
XOR CX,CX ;; ;AN000;
|
|
CALL SYSPARSE ;; ;AN000;
|
|
.IF <AX EQ 0> ;; ;AN000;
|
|
MOV BL,RESULT_TAG ;; ;AN000;
|
|
XOR BH,BH ;; return tag in BX ;AN000;
|
|
.ELSE ;; ;AN000;
|
|
.IF <AX NE -1> ;; syntax error ;AN000;
|
|
OR STMT_ERROR,INVALID ;; set error flag for caller ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
.ENDIF ;; ;AN000;
|
|
RET ;AN000;
|
|
PARSE_VERB ENDP ;AN000;
|
|
;; ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
|
|
;\/ ~~mda(001) -----------------------------------------------------------------------
|
|
; This procedure parses the new statement DEFINE in the
|
|
; graphics profile. The reason for this new statement
|
|
; is to be able to define the new keyword, DATA, as DATA_ROW
|
|
; or DATA_COL. This is necessary in order to support HP PCL
|
|
; printers since they print in row format and IBM printers
|
|
; print in column format.
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;
|
|
;; Module Name:
|
|
;; PARSE_DEFINE
|
|
;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;;
|
|
DEFINE_PARSE_PARMS LABEL WORD ;; Parser control blocks
|
|
DW DEFINE_P ;;
|
|
DB 2 ;; # of lists
|
|
DB 0 ;; # items in delimeter list
|
|
DB 1 ;; # items in end-of-line list
|
|
DB ';' ;; ';' used for comments
|
|
;;
|
|
DEFINE_P DB 0,1 ;; Required, max parms. If have DEFINE
|
|
;; then must have DEFINE DATA,ROW or
|
|
;; DEFINE DATA,COLUMN
|
|
DW DEFINE_P1 ;;
|
|
DB 0 ;; # Switches
|
|
DB 0 ;; # keywords
|
|
;;
|
|
DEFINE_P1 DW 2000H ;; simple string
|
|
DW 2 ;; Capitalize
|
|
DW RESULT_BUFFER ;; Result buffer
|
|
DW DEFINE_P1V ;; Value list
|
|
DB 0 ;; Synomyms
|
|
;;
|
|
;;
|
|
DEFINE_P1V DB 3 ;; # of value lists
|
|
DB 0 ;; # of range numerics
|
|
DB 0 ;; # of discrete numerics
|
|
DB 3 ;; 3 STRING VALUES
|
|
DB 1 ;; tag
|
|
DW DATA_STR ;; ptr
|
|
DB 2 ;; tag
|
|
DW ROW_STR ;; ptr
|
|
DB 3 ;; tag
|
|
DW COL_STR ;; ptr
|
|
;;
|
|
DATA_STR DB 'DATA',0 ;;
|
|
ROW_STR DB 'ROW',0 ;;
|
|
COL_STR DB 'COLUMN',0 ;;
|
|
;;
|
|
;;
|
|
ROW_FOUND DB NO ;;
|
|
COL_FOUND DB NO ;; Assume column until told otherwise
|
|
DATA_FOUND DB NO ;;
|
|
;;
|
|
;;
|
|
PARSE_DEFINE PROC ;;
|
|
;;
|
|
MOV CUR_STMT,DEF ;;
|
|
.IF <BIT STMTS_DONE NAND PRT> ;; If no preceeding PRT stmt
|
|
OR STMT_ERROR,MISSING ;; then issue error
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
;;
|
|
.IF <BIT STMTS_DONE AND DISP> ;; DISPLAYMODE stmts
|
|
OR STMT_ERROR,SEQUENCE ;; should NOT have been processed
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
;;
|
|
.IF <BIT STMTS_DONE AND DEF> ;; If another DEF stmt within in this
|
|
OR STMT_ERROR,INVALID ;; PTD then issue error
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
;;
|
|
;;
|
|
MOV ROW_FOUND,NO ;; Flags to indicate whether the ROW,
|
|
MOV COL_FOUND,NO ;; COLUMN, or DATA parms were found.
|
|
MOV DATA_FOUND,NO ;;
|
|
;;
|
|
OR STMTS_DONE,DEF ;; Indicate DEFINE found
|
|
;;
|
|
MOV DI,OFFSET DEFINE_PARSE_PARMS ;; parse parms
|
|
;; SI => the line to parse
|
|
XOR DX,DX ;;
|
|
.REPEAT ;;
|
|
XOR CX,CX ;;
|
|
CALL SYSPARSE ;;
|
|
;;
|
|
.IF <AX EQ 0> NEAR ;; If PARM is valid
|
|
MOV BL,RESULT_TAG ;;
|
|
.SELECT ;;
|
|
.WHEN <BL EQ 1> ;; DATA string
|
|
CMP DATA_FOUND,NO ;; .IF <DATA_FOUND EQ NO> ... .ELSE ...
|
|
JNE DATA_ERROR ;; Not using .IF macro because jump is
|
|
MOV DATA_FOUND,YES ;; out of range.
|
|
JMP CONT_PARSE ;;
|
|
DATA_ERROR: ;;
|
|
OR STMT_ERROR,INVALID ;; Duplicate DATA parms
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
;;
|
|
.WHEN <BL EQ 2> ;; ROW
|
|
.IF <ROW_FOUND EQ NO> AND ;;
|
|
.IF <COL_FOUND EQ NO> ;;
|
|
MOV ROW_FOUND,YES ;;
|
|
.IF <BUILD_STATE EQ YES> ;; ~~mda(002) If this is the DEFINE stmt we're using
|
|
MOV [BP].DATA_TYPE,DATA_ROW ;; Set DATA_TYPE to DATA_ROW.
|
|
.ENDIF
|
|
.ELSE ;;
|
|
OR STMT_ERROR,INVALID ;; Duplicate ROW parms or combo of
|
|
;; parms ROW and COLUMN
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
;;
|
|
.WHEN <BL EQ 3> ;; COLUMN
|
|
.IF <COL_FOUND EQ NO> AND ;;
|
|
.IF <ROW_FOUND EQ NO> ;;
|
|
MOV COL_FOUND,YES ;;
|
|
.IF <BUILD_STATE EQ YES> ;; ~~mda(002) If this is the DEFINE stmt we're using
|
|
MOV [BP].DATA_TYPE,DATA_COL ;; Set DATA_TYPE to DATA_COL.
|
|
.ENDIF ;;
|
|
.ELSE ;;
|
|
OR STMT_ERROR,INVALID ;; Duplicate COLUMN parms or combo of
|
|
;; parms COLUMN and ROW
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
.ENDSELECT ;;
|
|
.ELSE NEAR ;;
|
|
.IF <AX NE -1> ;;
|
|
OR STMT_ERROR,INVALID ;; parm is invalid
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
.ENDIF ;;
|
|
CONT_PARSE: ;;
|
|
.UNTIL <AX EQ -1> NEAR ;;
|
|
;;
|
|
.IF <DATA_FOUND EQ NO> ;; Missing DATA parm
|
|
OR STMT_ERROR,INVALID ;;
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
;;
|
|
;;
|
|
.IF <ROW_FOUND EQ NO> AND ;; Missing ROW or COLUMN parm
|
|
.IF <COL_FOUND EQ NO> ;;
|
|
OR STMT_ERROR,INVALID ;;
|
|
MOV PARSE_ERROR,YES ;;
|
|
MOV BUILD_STATE,NO ;;
|
|
.ENDIF ;;
|
|
;;
|
|
RET ;;
|
|
;;
|
|
PARSE_DEFINE ENDP ;;
|
|
;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;/\ ~~mda(001) -----------------------------------------------------------------------
|
|
;AN000;
|
|
LIMIT LABEL NEAR ;; ;AN000;
|
|
CODE ENDS ;; ;AN000;
|
|
END ;AN000;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;AN000;
|
|
|