home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
ZCPR2
/
ZEX.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
46KB
|
2,210 lines
;
; PROGRAM: ZEX
; AUTHOR: RICHARD CONN (DERIVED FROM EX, WHICH WAS WRITTEN BY SOMEONE ELSE)
; VERSION: 1.3
; DATE: 6 JAN 83
; PREVIOUS VERSIONS: 1.0 (12 NOV 82), 1.1 (8 DEC 82), 1.2 (3 JAN 83)
;
VERS EQU 13
;
; ZEX 1.0 -- EX 1.2.1 implemented for ZCPR2 by Richard Conn
; DATE: 12 NOV 82
; Extensions to EX are:
; Multiple command buffer is preserved, and any commands
; following the ZEX command are executed after
; the ZEX command file is completed (ZEX T;DIR
; will execute commands in T.SUB and then run DIR)
; ZCPR2 Search Path is following when looking for the
; file specified to ZEX
; Command File Type may be SUB or ZEX
; Added ^* form to simply ring the bell
; Added ^/ form to act like ^? but ring bell periodically
; Added ^" form to allow user input in the middle of a
; command file operation
; Major rewrite of EX to improve readability and to impose
; a structured organization on the code for maintenance
; purposes
; Major change in the abort system so that the multiple command
; line buffer of ZCPR2 will be properly cleared on
; abort; without this change, ZEX would crash the system
; in attempting to abort out of the ^/ and ^? forms;
; EX will probably always crash a ZCPR2 system with
; multiple commands enabled if an abort from ^? is
; attempted
;
; EX12.ASM - An enhanced version of EXEC and EX.
;
; START 05-09-82
;
; DATE 08-11-82 *LAST MAJOR CHANGE
;
; HISTORY:
;
; ZEX 1.0 11-12-82 modify for use under ZCPR2; main change is to place
; rest of multiple command line at end of SUB file
;
; 1.2.1 09-16-82 fix for MBASIC execution under EX 1.2 .
;
; 1.2 08-11-82 added '^:' EX runtime re-execute logic function,
; '^?' EX runtime wait for carriage return,
; logic to prevent input/EX buffer overlap,
; logic to insure (Xsub Already Present),
; logic to prevent EX runtime recursion loop,
; and prompt character logic [Larry Steeger]
;
; 1.1 08-06-82 added ';;' EX comment's support,
; '^.' print suppression function,
; '^<...^>' immediate display support,
; '^#' EX message suppression function,
; '^$' default parameter support,
; and '^|' cr,lf generation function [Larry Steeger]
;
; 1.0 08-03-82 corrected $^ error and ^<lowercase> error [Larry Steeger]
;
; ? 06-19-82 added missing TRUE and FALSE equates [Ron Fowler]
;
; ? 05-17-82 corrected last cold boot no active message
;
;
; EX12.COM IS AN ENHANCEMENT OF EXEC.COM AND EX.COM
;
; OPTIONS:
;
; EX <subfile> <parameters> cr
;
; EX cr
;
; ^<?> WILL GIVE CONTROL CHARACTER <?>
;
; | WILL BE CR
;
; ^| WILL BE CR,LF
;
; ^: WILL CAUSE EX TO RE-EXECUTE THE .SUB FILE FROM THE BEGINNING
;
; ^? WILL CAUSE EX TO WAIT FOR A CARRIAGE RETURN
; (^C WILL ABORT EX AT THIS POINT ALSO)
;
; ^/ WILL CAUSE ZEX TO RING THE BELL AND WAIT FOR A CARRIAGE RETURN
; (^C WILL ABORT ZEX AT THIS POINT ALSO)
;
; ^* WILL CAUSE ZEX TO RING THE BELL
;
; ^" WILL CAUSE ZEX TO STOP PROVIDING INPUT UNTIL THE NUICH CHAR IS
; OUTPUT
;
; ^$ WILL CAUSE THE REST OF THE LINE TO BE TREATED AS A
; SET OF DEFAULT PARAMETERS SEPARATED BY BLANKS TO BE
; USED IF THE USER HAS NOT PROVIDED ONE ON EX'S COMMAND LINE.
;
; ^# WILL TOGGLE PRINT SUPPRESSION OF EX MESSAGES
;
; ^. WILL START PRINT SUPPRESSION OF ALL CHARACTERS
; FROM .SUB FILE UNTIL A SUBSEQUENT ^. IS ENCOUNTERED
;
; ;; WILL INDICATE THAT THE ;; AND ALL CHARACTERS FOLLOWING IT
; UNTIL A LF IS ENCOUNTERED ARE NOT INCLUDED IN EX'S
; TEXT BUFFER
; (I.E. AN EX ONLY COMMENT)
;
; ^< WILL START IMMEDIATE DISPLAY OF CHARACTERS FROM
; THE .SUB FILE UNTIL ^> IS ENCOUNTERED
; (I.E. DISPLAY ONLY .SUB INPUT)
;
; $<1-9> WILL REPLACE PARAMETER<1-9> IN TEXT FROM THE COMMAND LINE
;
; $$ WILL GIVE $
;
; $^ WILL GIVE ^
;
; $| WILL GIVE |
;
; |,cr,lf,1ah will eat last from | to end of buffer
;
; ^C FROM CONSOLE WILL ABORT EX
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
; GENERAL EQUATES
;
BELL EQU 7
CTRLZ EQU 1AH ;^Z
DELAY EQU 6000H ;DELAY CONSTANT FOR TIMER LOOP
CR EQU 0DH
LF EQU 0AH
;
; ZEX MONITOR COMMAND BYTES
;
PSUP EQU 80H ;^. PRINT SUPPRESS FLAG
IMON EQU 81H ;^< IMMEDIATE MODE START
IMOFF EQU 82H ;^> IMMEDIATE MODE STOP
MSUP EQU 83H ;^# EX MESSAGE SUPPRESS FLAG
CRWAIT EQU 84H ;^? EX RUNTIME WAIT FOR CR FLAG
REXEC EQU 85H ;^: EX RUNTIME RE-EXECUTE FLAG
CRBWAIT EQU 86H ;^/ EX RUNTIME RING BELL AND WAIT FOR CR FLAG
RNG EQU 87H ;^* EX RUNTIME RING BELL
UICH EQU 88H ;^" USER INPUT COMMAND CHAR SEQUENCE
DNUICH EQU '>'+80H ;USER INPUT TERMINATION CHAR
;
; CP/M CONSTANTS
;
WARM EQU 0
BDISK EQU 4
BDOS EQU 5
DFCB EQU 5CH
BUFF EQU 80H
;
; NOTE: ZEX10.LIB IS CREATED BY THE ZEX10.SUB GENERATION PROCESS
;
MACLIB ZEX10
;
$-PRINT
IF BASE
$+PRINT
;
; START OF EX INITIATOR CODE SEGMENT
;
ORG 100H
;
; Branch to Start of Program
;
jmp start
;
;******************************************************************
;
; SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
;
; This data block precisely defines the data format for
; initial features of a ZCPR2 system which are required for proper
; initialization of the ZCPR2-Specific Routines in SYSLIB.
;
;
; EXTERNAL PATH DATA
;
EPAVAIL:
DB 0FFH ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
EPADR:
DW 40H ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
;
; INTERNAL PATH DATA
;
INTPATH:
DB 0,0 ; DISK, USER FOR FIRST PATH ELEMENT
; DISK = 1 FOR A, '$' FOR CURRENT
; USER = NUMBER, '$' FOR CURRENT
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0
DB 0,0 ; DISK, USER FOR 8TH PATH ELEMENT
DB 0 ; END OF PATH
;
; MULTIPLE COMMAND LINE BUFFER DATA
;
MCAVAIL:
DB 0FFH ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
MCADR:
DW 0FF00H ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
;
; DISK/USER LIMITS
;
MDISK:
DB 4 ; MAXIMUM NUMBER OF DISKS
MUSER:
DB 31 ; MAXIMUM USER NUMBER
;
; FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
;
DOK:
DB 0FFH ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
UOK:
DB 0FFH ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
;
; PRIVILEGED USER DATA
;
PUSER:
DB 10 ; BEGINNING OF PRIVILEGED USER AREAS
PPASS:
DB 'chdir',0 ; PASSWORD FOR MOVING INTO PRIV USER AREAS
DS 41-($-PPASS) ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
;
; CURRENT USER/DISK INDICATOR
;
CINDIC:
DB '$' ; USUAL VALUE (FOR PATH EXPRESSIONS)
;
; DMA ADDRESS FOR DISK TRANSFERS
;
DMADR:
DW 80H ; TBUFF AREA
;
; NAMED DIRECTORY INFORMATION
;
NDRADR:
DW 00000H ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
NDNAMES:
DB 64 ; MAX NUMBER OF DIRECTORY NAMES
DNFILE:
DB 'NAMES ' ; NAME OF DISK NAME FILE
DB 'DIR' ; TYPE OF DISK NAME FILE
;
; REQUIREMENTS FLAGS
;
EPREQD:
DB 0FFH ; EXTERNAL PATH?
MCREQD:
DB 0FFH ; MULTIPLE COMMAND LINE?
MXREQD:
DB 000H ; MAX USER/DISK?
UDREQD:
DB 000H ; ALLOW USER/DISK CHANGE?
PUREQD:
DB 000H ; PRIVILEGED USER?
CDREQD:
DB 0FFH ; CURRENT INDIC AND DMA?
NDREQD:
DB 000H ; NAMED DIRECTORIES?
Z2CLASS:
DB 4 ; CLASS 4
DB 'ZCPR2'
DS 10 ; RESERVED
;
; END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
;
;******************************************************************
;
;
; END USER INPUT COMMAND CHAR
;
TNUICH:
DB DNUICH ;INIT TO DEFAULT VALUE
;
; INITIAL COMMAND LINE AREA
;
DB 0FFH ;SIZE OF COMMAND LINE
DBUFF EQU $
DB 0FFH ;SIZE OF BUFFER
DS 100H ;SPACE FOR COMMAND LINE
;
; START OF ZEX
;
START:
NOP ;REPLACED WITH RET TO PREVENT REENTRY
LDA DFCB+1 ;CHECK FOR HELP REQUEST
CPI '/' ;HELP?
JZ HELP
LXI H,0
DAD SP
SHLD CCPSTK ;CCP STACK PTR
LXI SP,CCPSTK ;USER STACK AREA
MVI A,0C9H ; (8080 RET)
STA START ;PREVENT RE-ENTRANCE BY ZCPR
LXI H,BUFF ;COPY INPUT LINE INTO DBUFF
LXI D,DBUFF
MVI B,128 ;SIZE OF BUFFER
CALL MOVE
LXI D,SIGNON ;LOGO
CALL PRINT
CALL EXACTV ;CHECK FOR RECURSION
CALL ZRELOC ;RELOCATE ZEX MODULE
CALL ZPARMS ;EXTRACT PARAMETERS FROM COMMAND LINE
LDA DFCB+1 ;CHECK TO SEE IF SUB FILE PRESENT
CPI ' ' ;<SP>=NO
PUSH PSW ;SAVE FLAG
CNZ OPENSB ;OPEN AND LOAD SUB FILE IF PRESENT OR ABORT
POP PSW ;GET FLAG
CZ INPUTSB ;INPUT COMMANDS FROM USER
;
; HL NOW POINTS TO BYTE AFTER LOADED TEXT
;
CALL ZMCL ;STORE REST OF MULTIPLE COMMAND LINE
CALL ZLINES ;COPY AND PROCESS COMMAND LINES
;
; SET UP FOR ZEX EXECUTION AND RUN; HL PTS TO BOTTOM OF DATA AREA
;
PUSH H ;SAVE PTR TO END OF DATA
LHLD RELSTRT ;GET PTR TO START OF ZEX
SHLD GOADR ;SET ADDRESS TO RUN TO
MOV D,H ;DE IS START OF DATA AREA ALSO
MOV E,L
DCX H ;PT TO START OF DATA AREA
XTHL ;HL IS PTR TO END OF DATA, (SP) IS BEGINNING OF DATA
; FROM TOP DOWN
MVI M,0FFH ;SET UP END OF DATA
DCX H
MVI M,'X' ;SET UP EX RECURSION ID
DCX H
MVI M,'E'
DCX H
MVI M,'Z' ;ZEX BACKWARDS (FROM TOP DOWN)
DCX H
LDA BDOS+2 ;SET UP BDOS JUMP TO PROTECT DATA
MOV M,A
DCX H
LDA BDOS+1
MOV M,A
DCX H
MVI M,JMP
POP D ;GET START OF BUFFER ADDRESS IN DE
LXI B,0 ;ASSUME NO MULTIPLE COMMANDS
LDA MCAVAIL ;GET FLAG
ORA A ;0=NONE
JZ GOTOZEX ;NO MULTIPLE COMMANDS, SO BC=0
PUSH H ;SAVE HL
LHLD MCADR ;GET ADDRESS OF MULTIPLE COMMAND BUFFER
MOV B,H ;... IN BC
MOV C,L
POP H
;
; ZEX MONITOR ENTRY PARAMETERS --
; HL TOP OF MEMORY ADDRESS
; DE START OF BUFFER ADDRESS
; BC ADDRESS OF MULTIPLE COMMAND BUFFER OR 0 IF NONE
; A END OF USER INPUT CHAR
;
GOTOZEX:
LDA TNUICH ;GET END OF USER INPUT CHAR
GOADR EQU $+1
JMP $
;
; PRINT HELP MESSAGE FOR ZEX
;
HELP:
LXI D,SIGNON ;PRINT BANNER
CALL PRINT
LXI H,HMSG ;PRINT MESSAGE
CALL HPRINT
MVI C,1 ;GET CHAR
CALL BDOS
CPI 'C'-'@' ;^C?
RZ
LXI D,CRLFS
CALL PRINT
LXI D,SIGNON
CALL PRINT
LXI H,HMSG0
CALL HPRINT
MVI C,1 ;GET CHAR
CALL BDOS
CPI 'C'-'@' ;^C?
RZ
LXI D,CRLFS
CALL PRINT
LXI D,SIGNON
CALL PRINT
LXI H,HMSG1
HPRINT:
MOV A,M ;GET CHAR
ORA A ;DONE?
RZ
INX H ;PT TO NEXT
PUSH H ;SAVE PTR
MOV E,A ;CHAR IN E
MVI C,2 ;CONSOLE OUTPUT
CALL BDOS
POP H ;GET PTR
JMP HPRINT
HMSG:
DB CR,LF,LF
DB 'ZEX is an indirect command file processing facility, similar'
DB CR,LF,'to the standard CP/M SUBMIT facility and the other '
DB 'ZCPR2'
DB CR,LF,'indirect command file processing facility, SUB2.'
DB CR,LF,'The major difference between the SUBMIT-like programs'
DB CR,LF,'and ZEX is that ZEX is memory-based, storing a command'
DB CR,LF,'processor and the interpreted command file itself in'
DB CR,LF,'memory, just under ZCPR2.'
DB CR,LF,LF
DB 'There is a basic tradeoff to be considered when using ZEX'
DB CR,LF,'as opposed to SUB2. Since ZEX is memory-based, it '
DB 'offers'
DB CR,LF,'the advantage of greatly increased operating speed '
DB 'over'
DB CR,LF,'SUB2. Also, ZEX intercepts all input unless user '
DB 'input'
DB CR,LF,'is explicitly enabled (the ^" command), in which case'
DB ' the user'
DB CR,LF,'is allowed to enter text from his console during a '
DB 'ZEX run.'
DB CR,LF,'SUB2, on the other hand, inputs from the command file'
DB ' only'
DB CR,LF,'at the command line prompt unless XSUB is active. ZEX'
DB ' acts like'
DB CR,LF,'SUB2 and XSUB combined. The only bad feature of ZEX is'
DB ' that'
DB CR,LF,'ZEX significantly shortens the TPA work area, so '
DB 'programs which'
DB CR,LF,'require a lot of memory may have trouble running under'
DB ' ZEX.'
DB CR,LF,'This is why SUB2 is provided to the ZCPR2 user along '
DB 'with ZEX.'
DB CR,LF,LF,'Strike Any Key to Continue, ^C to Abort - ',0
HMSG0:
DB CR
DB LF,LF,'ZEX is invoked by one of the following command lines --'
DB CR,LF
DB CR,LF,' ZEX <subfile> <parameters>'
DB CR,LF,'or'
DB CR,LF,' ZEX'
DB CR,LF
DB CR,LF,'The first form executes the indicated command file'
DB CR,LF,'(<subfile> may be of type ZEX or SUB, and if a ZEX and'
DB ' SUB both'
DB CR,LF,'exist, the ZEX file is used), passing to it the '
DB 'indicated '
DB CR,LF,'parameters, similar to the way SUBMIT is used.'
DB CR,LF
DB CR,LF,'The second form allows the user to enter a series of '
DB 'commands.'
DB CR,LF,'ZEX presents the user with a prompt like "n:", where'
DB CR,LF,'n is a line number, and the user may enter any command'
DB CR,LF,'line. Input is terminated by simply striking the'
DB CR,LF,'RETURN key.'
DB CR,LF,LF,'ZEX can be aborted by ^C from console.'
DB CR,LF,LF,'The following screen displays the ZEX control codes.'
DB CR,LF,LF,'Strike Any Key to Continue, ^C to Abort - ',0
HMSG1:
DB CR,LF,LF
DB ' **** ZEX Embedded Command Processing Facility ****'
DB CR,LF,LF
DB 'ZEX supports an enhanced command processing facility which '
DB 'includes the'
DB CR,LF,'following escaped character commands which may be'
DB CR,LF,'embedded in the text of the command file or user'
DB CR,LF,'input and will be executed after the command run begins'
DB ' --'
DB CR,LF
DB CR,LF,' Cmd Meaning Cmd Meaning'
DB CR,LF,' | insert <CR> ^| insert <CR> <LF>'
DB CR,LF,' ^: rerun command file ^. suppress print of chars'
DB CR,LF,' ^# toggle ZEX msgs ^$ define default params'
DB CR,LF,' ^? wait for user <CR> ^/ ring and wait for <CR>'
DB CR,LF,' ^* ring bell ^" allow user input'
DB CR,LF,' ^< display chars only ^> stop display'
DB CR,LF,' ;; ZEX comment $n 1<=n<=9 for param'
DB CR,LF,' $$ =$ $^ =^'
DB CR,LF,' $| =| ^c insert ctrl char c'
DB CR,LF,LF,LF,LF,0
;
; RELOCATE ZEX MODULE INTO HIGH MEMORY JUST BELOW ZCPR2
;
ZRELOC:
LHLD RELOCL ;GET RELOC PROGRAM LENGTH
MOV B,H ;BC=HL=RELOC PROGRAM LENGTH
MOV C,L
PUSH B ;SAVE LENGTH FOR FUTURE USE
LHLD BDOS+1 ;GET BASE
LXI D,-806H ;GET BEFORE CCP
DAD D
MOV A,L ;SUBTRACT RELOC LENGTH
SUB C
MOV E,A
MOV A,H
SBB B
MOV D,A
PUSH D ;SAVE NEW TOP/START TO MOVE TO
LXI H,BEGREL ;START OF MOVE
OMOVE:
MOV A,B
ORA C
JZ MOVEND
DCX B
MOV A,M
STAX D
INX D
INX H
JMP OMOVE
;
MOVEND:
POP D ;GET START OF MOVED PROGRAM
POP B ;LENGTH OF MOVE PROGRAM
PUSH D ;SAVE PTR TO START OF PROGRAM
PUSH H ;START OF BIT MAP
MOV H,D ;MSB OFFSET
MOV L,E ;LSB OFFSET
OFFLUP:
MOV A,B ;TEST LENGTH
ORA C ;IF 0
JZ GOTO ;JUMP TO RELOCATED PROGRAM
DCX B ;DECREMENT COUNT
LDA COUNT
INR A
STA COUNT
ANI 07H
JNZ OFFBIT ;NO
XTHL ;YES, GET BIT MAP
MOV A,M ;GET NEXT BYTE
INX H ;INCREMENT BIT MAP POINTER
XTHL ;SAVE FOR LATER
STA BITMAP ;KEEP BIT OFFSET
OFFBIT:
LDA BITMAP
RAL ;TEST FOR OFFSET
STA BITMAP ;SAVE NEW BYTE
JNC NOFSET ;NO
DCX D ;GET BACK TO LSB
LDAX D
ADD L
STAX D
INX D ;MSB
LDAX D ;YES
ADC H ;ADD IN OFFSET
STAX D ;PUT IN MOVED PLACE
NOFSET:
INX D ;INCREMENT MOVED POINTER
JMP OFFLUP ;CONTINUE WITH RELOCATE
;
GOTO:
POP D ;RESTORE STACK
POP H ;PT TO FIRST BYTE OF PROGRAM
SHLD RELSTRT ;SAVE PTR
DCX H ;RELOCATE PROGRAM-1
SHLD OUTBUF ;SAVE PTR TO BYTE IN FRONT OF RELOCATED PROGRAM
RET
;
; GET PARAMETERS FROM COMMAND LINE
; TERMINATE EACH PARAMETER WITH A BINARY ZERO, AND SET POINTERS
; TO EACH PARAMETER
;
ZPARMS:
LXI D,DBUFF+1 ;TERMINATE COMMAND LINE WITH CR
PUSH D
LDA DBUFF
MOV L,A ;HL = NUMBER OF CHARS IN LINE
MVI H,0
DAD D ;PT TO AFTER LAST CHAR
MVI M,CR ;STORE <CR>
LXI H,PRMDMY ;START AT DUMMY PARAMETER FOR .SUB FILE SPEC
PUSH H
LXI B,PRMPNL+2
XRA A
CALL FILL ;CLEAR PTR AREA
POP H ;GET PTR TO POINTER FOR PARAMETER 0
POP D ;GET PTR TO FIRST CHAR IN LINE
MVI A,(PRMPNL/2)+1 ;NUMBER OF PARAMETERS POSSIBLE, MAX
STA PRMMAX ;HIGHEST PARAMETER # + 1 for .SUB SPEC
;
; PARAMETER EXTRACTION ROUTINE; HL PTS TO FIRST PARAM PTR, DE PTS TO LINE
;
PARMS:
MVI B,0 ;CLEAR PARAMETER COUNTER
XCHG
SHLD ERRLNE ;SAVE IN CASE OF ERROR
XCHG
;
PARMSL:
LDAX D ;IGNORE LEADING SPACES
INX D
CPI CR
JZ ENDLNE
CPI ' '
JZ PARMSL
DCX D ;BACK UP TO 1ST CHAR
MOV M,E ;SAVE ADDRESS IN TABLE
INX H
MOV M,D
INX H
INR B ;COUNT+1
LDA PRMMAX
CMP B
JC PRMTOO ;TOO MANY ARGUMENTS
;
ENDPRM:
LDAX D ;GO TO END OF PARAMETER
INX D
CPI CR
JZ ENDLNE
CPI ' ' ;SKIP UNTIL <SP>
JNZ ENDPRM
XRA A ;A=0 TO TERMINATE PARAM
DCX D ;PT TO <SP> FOLLOWING PARAM
STAX D ;TERMINATE PARAMETER
INX D ;PT TO CHAR AFTER <SP>
JMP PARMSL ;IGNORE SPACES BETWEEN PARAMETERS
ENDLNE:
XRA A ;STORE ZERO AFTER LAST PARAMETER
DCX D ;PT TO CR
STAX D ;TERMINATE LAST PARAMETER
INX D ;PT TO AFTER LAST PARAM
MVI A,CR ;STORE ENDING CR
STAX D
RET
;
; INPUT COMMAND LINES FROM USER
;
INPUTSB:
LXI H,0
SHLD LINES ;START LINE COUNTER
MVI A,0FFH ;SET BUFFER LENGTH
STA DBUFF-1
LXI H,BEGREL ;SET UP OUTPUT BUFFER
SHLD INBUF
GETLIN:
CALL CRLF
LHLD LINES
INX H
SHLD LINES
CALL DECOUT ;PRINT LINE #
MVI E,':' ;GET PROMPT
CALL OUTCHR
MVI E,' '
CALL OUTCHR
LXI D,DBUFF-1
MVI C,10 ;READ CONSOLE BUFFER
CALL BDOS
LXI D,DBUFF
LDAX D ;GET LENGTH
MOV B,A
INX D
LHLD INBUF ;GET INPUT POINTER
ORA A ;SEE IF END
RZ ;DONE WITH INPUT
XCHG
CALL MOVE ;MOVE TO INPUT BUFFER
XCHG
MVI M,CR
INX H
MVI M,LF
INX H
SHLD INBUF
JMP GETLIN
;
; OPEN AND LOAD SUB FILE
;
OPENSB:
CALL PUTUD ;SAVE USER/DISK
;
; SET UP TO READ ZEX FILE
;
LXI D,DFCB+9
LXI H,ZEXNAM ;MOVE 'SUB' TO DFCB FILE TYPE
MVI B,3
CALL MOVE
XRA A ;ZERO CR FIELD
STA DFCB+32
LXI D,BUFF ;SET DMA ADDRESS
MVI C,26 ;SET DMA
CALL BDOS
LXI D,DFCB
LXI H,INTPATH ;PT TO INTERNAL PATH
LDA EPAVAIL ;EXTERNAL PATHS AVAILABLE?
ORA A ;0=NO
JZ OSB1 ;USE INTERNAL PATH
LHLD EPADR ;PT TO EXTERNAL PATH
OSB1:
PUSH H ;SAVE PATH PTR
CALL FNDFILE ;LOOK FOR FILE ALONG PATH AND SAY IF IT IS FOUND
POP H ;GET PATH PTR
JNZ READSB
;
; ZEX FILE NOT FOUND -- SET UP TO READ SUB FILE
;
PUSH H ;SAVE PATH PTR
CALL GETUD ;RESTORE USER/DISK
LXI D,DFCB+9 ;SET TYPE TO SUB
LXI H,SUBNAM
MVI B,3
CALL MOVE
XRA A ;ZERO CR FIELD
STA DFCB+32
POP H ;PT TO PATH
LXI D,DFCB ;PT TO FCB
CALL FNDFILE ;LOOK FOR FILE
JNZ READSB
RSBERR:
CALL GETUD ;RESTORE USER/DISK
LXI H,NOSBF2
LXI D,DFCB+1
MVI B,8 ;NAME LENGTH
CALL MOVEFN ;MOVE FILE NAME
MVI B,3 ;TYPE LENGTH
MVI M,'.'
INX H
LXI D,DFCB+9;FILE TYPE POINTER
CALL MOVEFN ;MOVE FILE TYPE
MVI M,'$' ;END TERMINATER
JMP NOSUB
*
* FNDFILE -- LOOK FOR FILE ALONG ZCPR2 PATH
* INPUT PARAMETERS: HL = BASE ADDRESS OF PATH, DE = PTR TO FCB OF FILE
* OUTPUT PARAMETERS: A=0 AND ZERO FLAG SET IF NOT FOUND, NZ IF FOUND
*
FNDFILE:
SHLD PATH ;SAVE PATH BASE ADDRESS
MVI C,17 ;SEARCH FOR FIRST
CALL BENTRY ;LOOK FOR FILE
INR A ;SET FLAG
JNZ FF5 ;FOUND IT -- RETURN FOUND FLAG
XCHG ;HL=FCB PTR
SHLD FCBPTR ;SAVE IT
LHLD PATH ;PT TO PATH FOR FAILURE POSSIBILITY
MVI C,32 ;GET CURRENT USER
MVI E,0FFH
CALL BENTRY
STA TMPUSR ;SAVE IT FOR LATER
;
; MAIN SEARCH LOOP
;
FF1:
MOV A,M ;GET DRIVE
ANI 7FH ;MASK MSB
ORA A ;0=DONE=COMMAND NOT FOUND
JNZ FF2 ;NO ERROR ABORT?
;
; FILE NOT FOUND ERROR
;
XRA A ;ZERO FLAG MEANS NOT FOUND
RET
;
; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
;
FF2:
MOV E,A ;DISK IN E
LDA CINDIC ;CURRENT DRIVE SPECIFIED?
CMP E
JNZ FF3 ;SKIP DEFAULT DRIVE SELECTION IF SO
LDA BDISK ;GET DEFAULT USER/DISK
ANI 0FH ;MASK FOR DEFAULT DISK
INR A ;PREP FOR FOLLOWING DCR A
MOV E,A ;DISK NUMBER IN E
FF3:
DCR E ;ADJUST PATH 1 TO 0 FOR A, ETC
MVI C,14 ;SELECT DISK FCT
CALL BENTRY ;SELECT DRIVE
INX H ;PT TO USER NUMBER
MOV A,M ;GET USER NUMBER
ANI 7FH ;MASK OUT MSB
INX H ;PT TO NEXT ENTRY IN PATH
PUSH H ;SAVE PTR
MOV E,A ;SAVE IN E
LDA CINDIC ;CURRENT USER SPECIFIED?
CMP E ;MATCH?
JNZ FF4 ;DO NOT SELECT CURRENT USER IF SO
LDA TMPUSR ;GET ORIGINAL USER NUMBER
MOV E,A ;SELECT USER
FF4:
MVI C,32
CALL BENTRY
LHLD FCBPTR ;GET PTR TO FCB
XCHG ;... IN DE
MVI C,17 ;SEARCH FOR FIRST
CALL BENTRY ;LOOK FOR FILE
POP H ;GET PTR TO NEXT PATH ENTRY
INR A ;SET FLAG
JZ FF1 ;CONTINUE PATH SEARCH IF SEARCH FAILED
;
; FILE FOUND -- PERFORM SYSTEM TEST AND PROCEED IF APPROVED
;
FF5:
MVI A,0FFH ;SET OK RETURN
ORA A
RET
;
; BDOS ROUTINE
;
BENTRY:
PUSH H ;SAVE REGS
PUSH D
PUSH B
CALL BDOS
POP B ;GET REGS
POP D
POP H
RET
* BUFFERS
FCBPTR:
DS 2 ;POINTER TO FCB FOR FILE SEARCH
TMPUSR:
DS 1 ;CURRENT USER NUMBER
PATH:
DS 2 ;BASE ADDRESS OF PATH
;
; PUTUD -- SAVE AWAY CURRENT USER/DISK
; GETUD -- RESTORE CURRENT USER/DISK
;
PUTUD:
MVI E,0FFH ;GET CURRENT USER
MVI C,32 ;BDOS
CALL BDOS
STA CUSER ;SAVE CURRENT USER AWAY
MVI C,25 ;GET CURRENT DISK
CALL BDOS
STA CDISK
RET
GETUD:
LDA CDISK ;GET CURRENT DISK
MOV E,A ;... IN E
MVI C,14 ;SELECT DISK
CALL BDOS
LDA CUSER ;GET CURRENT USER
MOV E,A ;... IN E
MVI C,32 ;SELECT USER
CALL BDOS
RET
CDISK:
DS 1 ;CURRENT DISK NUMBER
CUSER:
DS 1 ;CURRENT USER NUMBER
;
; OPEN AND READ SUB FILE
;
READSB:
MVI C,15 ;OPEN FILE
CALL BDOS ;BDOS
INR A ;ERROR?
JZ RSBERR
;
; READ IN AND STORE SUB FILE
;
READTX:
LHLD INBUF ;GET PTR TO NEXT BYTE
XCHG ;SET PTR IN DE
LXI H,80H ;GET SECTOR OFFSET
DAD D ;HL PTS TO FOLLOWING BLOCK TO BE READ, DE PTS TO
SHLD INBUF ; BLOCK TO READ; SAVE PTR TO FOLLOWING BLOCK
MVI C,26 ;SET DMA ADDRESS
CALL BDOS
LXI D,DFCB
MVI C,20 ;READ SEQUENTIAL
CALL BDOS
ORA A
JZ READTX ;READ COMPLETE .SUB FILE
CALL GETUD ;RESTORE CURRENT USER/DISK
LHLD INBUF ;MAKE SURE BUFFER'S TERMINATED
LXI D,-100H ;PT TO FIRST BYTE OF LAST BLOCK READ
DAD D
MVI B,80H ;LOOK AT AT MOST 80H BYTES
SKIP1A:
MOV A,M ;GET BYTE
CPI CTRLZ ;EOF?
JZ SKIP1B
INX H ;PT TO NEXT
DCR B ;COUNT DOWN
JNZ SKIP1A
; HL NOW POINTS TO AFTER LAST VALID CHAR IN FILE
SKIP1B:
SHLD INBUF ;SET PTR
RET ;DONE WITH NO ERROR
;
; THIS PART OF THE CODE STORES THE REST OF THE COMMAND LINE AS PART OF THE
; COMMAND FILE FOR ZCPR2; ON ENTRY, HL PTS TO NEXT AVAILABLE BYTE
;
ZMCL:
XCHG ;BUFFER PTED TO BY DE
LHLD MCADR ;GET BASE ADDRESS OF MULTIPLE COMMAND LINE
MOV A,M ;GET LOW
INX H
MOV H,M ;GET HIGH
MOV L,A ;HL PTS TO NEXT CHAR IN MULTIPLE COMMAND LINE
XCHG ;DE PTS TO NEXT CHAR IN COMMAND LINE, HL PTS TO BUF END
LDA MCAVAIL ;MULTIPLE COMMANDS ENABLED?
ORA A ;0=NO
JZ ENDSTR ;TERMINATE FILE; HL PTS TO NEXT BYTE
LDAX D ;GET FIRST BYTE
MOV B,A ;SAVE FIRST BYTE IN B
XRA A ;A=0
STAX D ;CLEAR COMMAND LINE
INX D ;PT TO NEXT BYTE
MOV A,B ;GET FIRST BYTE
CPI ';' ;SEPARATION CHAR?
JNZ CMCMD1 ;PROCESS IF NOT
;
; LOOP TO STORE REST OF MULTIPLE COMMAND LINE INTO LOADED FILE
;
CMCMD:
LDAX D ;GET BYTE FROM LINE
CMCMD1:
ORA A ;EOL IF ZERO
JZ CMEND ;READ IN FILE; HL PTS TO NEXT AVAILABLE BYTE
MOV M,A ;STORE BYTE
INX H ;PT TO NEXT
INX D
JMP CMCMD
CMEND:
MVI M,CR ;STORE <CR> <LF>
INX H
MVI M,LF
INX H ;PT TO NEXT AVAILABLE BYTE
;
; MARK END OF BUFFER AND CONTINUE
;
ENDSTR:
MVI M,1AH ;EOF CHARACTER
SHLD ENDBUF ;EOB ADDRESS
MOV A,L
SUI LOW BEGREL+1 ;SEE IF BUFFER'S EMPTY
MOV A,H
SBI HIGH BEGREL
JC BUFLOW
RET
;
; COPY AND PROCESS COMMAND LINES, PLACING FINAL COMMAND LINE FORM UNDER ZEX
; RETURN WITH HL PTING TO NEXT AVAILABLE BYTE IN MEMORY BUFFER UNDER ZEX
;
ZLINES:
XRA A
STA IMFLG1
STA IMFLG2
STA PRTFLG
STA OUTCNT
LXI H,1
SHLD LINES
LHLD OUTBUF ;PT TO BYTE JUST BELOW LOADED ZEX
SHLD OUTLNE
SHLD BUFSTR
LXI D,BEGREL ;PT TO FIRST BYTE OF COMMAND BUFFER
;
; MAIN COPY LOOP TO COPY BUFFER AT BEGREL TO JUST UNDER EX WITH PROCESSING
;
MOVSTR:
LDAX D ;GET NEXT COMMAND BYTE
INX D ;PT TO FOLLOWING
ANI 7FH ;MAKE SURE NO PARITY
CPI LF ;NEW LINE?
JNZ MOVST0
;
; NEW LINE -- DON'T STORE <LF> AND INCREMENT LINE COUNT
;
MOVSTX:
CALL INCR ;INCREMENT LINE COUNT
JMP MOVSTR ;CONTINUE
;
; BEGIN CHARACTER PROCESSING
; A CONTAINS CHAR, DE PTS TO BYTE AFTER CHAR, HL PTS TO NEXT BUFFER POS
;
MOVST0:
CPI 1AH ;END OF INPUT?
RZ ;DONE IF SO
CPI '|' ;CARRIAGE RETURN?
JNZ MOVST1 ;NOPE
;
; PROCESS CARRIAGE RETURN FORM (|)
;
PUSH D ;SAVE OLD POINTER
INX D ;LOOK FOR EOF AFTER | (PT TO LF)
INX D ;PT TO POSSIBLE EOF
LDAX D ;GET PRESENT LOCATION+2
POP D ;GET OLD POINTER
CPI 1AH ;END OF BUFFER
RZ ;END, SO NO FOLLOWING <CR>
MVI A,CR ;MAKE CHAR A <CR>
CALL INCR ;INCREMENT LINES FOR ERRORS
JMP MOVST4 ;STORE <CR> IN A
;
; CHECK FOR NON-CR FORMS
; AT THIS POINT, DE PTS TO NEXT CHAR IN LINE AND HL PTS TO NEXT
; BYTE IN BUFFER (MOVING DOWN)
;
MOVST1:
MOV C,A ;SAVE CHAR IN C
LDA IMFLG1
CPI IMON ;IMMEDIATE MODE ON ?
MOV A,C ;GET CHAR BACK
JZ MOVST2 ;YES..SKIP EX COMMENT PROCESSING
CPI ';' ;FIRST ';'?
JZ EXCOMM ;PROCESS POSSIBLE EX COMMENT
MOVST2:
CPI '^' ;CONTROL CHAR?
JZ MOVST5 ;CONVERT CONTROL CHARACTERS
CPI '$' ;PARAMETER OR CONTROL CHAR?
CZ GTPARM ;SUBSTITUTE COMMAND PARAMETER OR CONTROL CHAR.
MOVST3:
STA LCHR ;SAVE LAST CHAR ENTERED
CPI CR ;=CR?
JNZ MOVST4
MOV C,A ;SAVE CHAR TEMPORARILY
LDA OUTCNT ;GET CHAR OUTPUT FLAG
ORA A ;ANY CHAR?
MOV A,C
JZ MOVSTR ;NO..USE INPUT CR ONLY IF OTHER NON-CONTROL
; CHARACTERS IN CURRENT LINE
; PLACE CHAR IN BUFFER
; CHAR IN A, HL PTS TO BUFFER LOC
;
MOVST4:
CALL CHRSTR ;ADD TO BUFFER
CALL CNTINC ;INCREMENT COUNT
JMP MOVSTR
;
; PREFIX WAS AN UPARROW (^), SO PROCESS CONTROL CHARS
;
MOVST5:
CALL GETCMD ;VALIDATE CONTROL CHARACTERS
CPI ':'
JZ REXC ;RE-EXECUTE
CPI '?'
JZ GCRW ;CR WAIT
CPI '/'
JZ GCRBW ;RING BELL AND WAIT FOR <CR>
CPI '"'
JZ UISET ;USER INPUT
CPI '*'
JZ GRNG ;CONTINUALLY RING BELL WHILE WAITING FOR <CR>
CPI '|'
JZ GCRLF ;CR,LF GENERATION
CPI '$'
JZ PRMDEF ;DEFAULT PARAMETERS' LINE
CPI '.'
JZ PRTSUP ;PRINT SUPPRESS TOGGLE
CPI '#'
JZ MSGSUP ;MESSAGE SUPPRESS TOGGLE
CPI '<'
JZ IMPRTY ;IMMEDIATE MODE START
CPI '>'
JZ IMPRTN ;IMMEDIATE MODE STOP
JMP MOVST3 ;OTHER CONTROL CODES
;
REXC:
MVI A,REXEC ;CONVERT '^:' TO RE-EXECUTE FLAG
JMP MOVST3
;
GCRW:
MVI A,CRWAIT ;CONVERT '^?' TO CRWAIT FLAG
JMP MOVST3
;
GCRBW:
MVI A,CRBWAIT ;CONVERT '^/' TO CRBWAIT FLAG
JMP MOVST3
;
; ALLOW USER INPUT FROM NOW ON, BUT FIRST SKIP OUT REST OF LINE
;
UISET:
LDAX D ;GET NEXT CHAR
ANI 7FH ;MASK IT
CPI LF ;DONE?
JZ UISET1
CPI 1AH ;EOF?
JZ UISET1
INX D ;PT TO NEXT CHAR
JMP UISET ;CONTINUE SKIPPING
UISET1:
MVI A,UICH ;CONTROL CHAR
JMP MOVST3
;
GRNG:
MVI A,RNG ;CONVERT '^*' TO RNG FLAG
JMP MOVST3
;
GCRLF:
MVI A,CR ;GENERATE CR & LF
CALL CHRSTR
MVI A,LF
CALL CHRSTR
STA LCHR
JMP MOVSTR
;
PRMDEF:
PUSH H
LXI H,PRMDFP
PUSH H
LXI B,PRMDFL
XRA A
CALL FILL ;CLEAR PTR TABLE
POP H
MVI A,PRMDFL/2
STA PRMMAX ;HIGHEST PARAMETER #
CALL PARMS ;BUILD DEFAULT PARAMETERS PTRS
POP H
INX D ;SKIP CR
MVI A,LF
JMP MOVSTX ;CONTINUE AT EOL
;
; CHECK TO SEE IF PREVIOUS CHAR WAS ALSO A ; AND FLUSH AS ZEX COMMENT IF SO
;
EXCOMM:
PUSH H
LXI H,LCHR ;PT TO PREVIOUS CHAR
CMP M ; DOUBLE ;?
MOV M,A ;STORE CURRENT CHAR AS PREVIOUS CHAR
POP H
JNZ MOVST3 ;NO...CONTINUE
MOV C,A ;SAVE CHAR
LDA PRTFLG
CPI PSUP
MOV A,C
JZ MOVST3 ;PRINT SUPPRESS
LDA IMFLG1
CPI IMON
MOV A,C
JZ MOVST3 ;IMMEDIATE MODE
INX H ;YES..IGNORE PREVIOUS ;
PUSH H
LXI H,LCHR
LDA OUTCNT
DCR A ;DROP 1 CHAR.
STA OUTCNT
EXCOML:
LDAX D ;IGNORE CHARACTERS UNTIL EOF OR LF
INX D
CPI 1AH ;EOF
JZ EXCOMX
CPI LF ;LINE FEED
JNZ EXCOML
MOV M,A
LDA OUTCNT
ORA A ;ANY CHAR. ON THIS LINE?
JZ EXCOM2 ;NO...SKIP CR
EXCOM1:
POP H ;YES..FORCE CR
MVI A,CR
CALL CHRSTR
MVI A,LF
JMP MOVSTX ;CONTINUE
;
EXCOM2:
POP H
MVI A,LF
JMP MOVSTX ;CONTINUE
;
EXCOMX:
POP H
RET ;RETURN TO MAIN FLOW, WITH HL PTING TO NEXT BYTE
;
MSGSUP:
MVI A,MSUP ;CONVERT '^#' TO MESSAGE SUPPRESS FLAG
JMP MOVST3
;
PRTSUP:
MVI A,PSUP ;CONVERT '^.' TO PRINT SUPPRESS FLAG
PUSH H
LXI H,PRTFLG
CMP M ;ALREADY ON?
JNZ PRTSST ;NO...SET FLAG
XRA A ;YES..CLEAR FLAG
PRTSST:
MOV M,A ;SET/RESET FLAG
POP H
MVI A,PSUP
JMP MOVST3
;
IMPRTY:
MVI A,IMON ;CONVERT '^<' TO IMMEDIATE MODE START
STA LCHR
PUSH H
LXI H,IMFLG1
CMP M ;ALREADY ON?
POP H
JZ MOVSTR ;YES..
STA IMFLG1
STA IMFLG2
JMP MOVST3 ;NO...
;
IMPRTN:
MVI A,IMOFF ;CONVERT '^>' TO IMMEDIATE MODE STOP
STA LCHR
PUSH H
LXI H,IMFLG2
CMP M ;ALREADY OFF?
POP H
JZ MOVSTR ;YES..
STA IMFLG2
STA IMFLG1
JMP MOVST3 ;NO...
;
; PLACE CHAR IN BUFFER; A=CHAR, HL PTS TO BUFFER LOC
;
CHRSTR:
PUSH PSW ;CHECK FOR INPUT/EX BUFFER OVERLAP
PUSH D
PUSH H
LHLD ENDBUF
XCHG
POP H
MOV A,L
CMP E
JNZ CHRSTX ;LSB<>
MOV A,H
CMP D
JZ OVERL ;MSB=, OVERLAP WILL OCCUR/ABORT EX
;
CHRSTX:
POP D ;ADD CHAR. TO EX'S BUFFER
POP PSW
MOV M,A ;STORE CHAR
DCX H ;PT TO NEXT LOCATION (MOVING DOWN)
RET
;
; CHECK TO SEE IF ZEX IS ALREADY ACTIVE, AND ABORT IF SO
;
EXACTV:
LHLD BDOS+1 ;CHECK FOR EX RECURSION
INX H ;SKIP JMP
INX H ;SKIP LOW
INX H ;SKIP HIGH
MVI A,'Z' ;LOOK FOR ZEX STORED JUST ABOVE THE BDOS JMP
CMP M
RNZ
INX H
MVI A,'E'
CMP M
RNZ ;NOT 'E'
INX H
MVI A,'X'
CMP M
RNZ ;NOT 'X'
INX H
MVI A,0FFH
CMP M
RNZ ;NOT 0FFH
LXI D,EXACT
CALL PRINT ;ZEX ALREADY PRESENT
;
; ABORT AND RETURN TO ZCPR2
;
CCPRET:
LHLD CCPSTK ;RESTORE STACK
SPHL
RET ;RETURN TO CCP
;
; ERROR EXITS
;
GETERR:
LXI D,CMDER ;CONTROL CHARACTER INVALID
CALL PRINT
JMP LINE ;PRINT LINE # AND LINE AND EXIT
;
NUMERR:
LXI D,NONUM ;EXCESSIVE NUMBER
CALL PRINT
JMP LINE ;PRINT LINE # AND LINE AND EXIT
;
NODEFP:
LXI D,NOPRM ;UNKNOWN PARAMETER
CALL PRINT
JMP LINE ;PRINT LINE # AND LINE AND EXIT
;
PRMERR:
LXI D,PMERR
CALL PRINT
JMP LINE ;PRINT LINE # AND LINE AND EXIT
;
PRMTOO:
LXI D,TOOARG;TOO MANY PARAMETER ARGUMENTS
CALL PRINT
LHLD ERRLNE
CALL EPRT ;PRINT PARAMETER LINE
JMP CCPRET
;
BUFLOW:
LXI D,BUFMTY;TEXT BUFFER EMPTY
CALL PRINT
JMP CCPRET
;
NOSUB:
LXI D,NOSBF1;.SUB FILE NOT FOUND
CALL PRINT
LXI D,NOTHER
CALL PRINT
JMP CCPRET
;
OVERL:
LXI D,OVERLP;INPUT/EX BUFFER OVERLAP
CALL PRINT
JMP LINE
;
; SUBROUTINES
;
; CONTROL CODES 0-1FH
; WITH SUPPORT FOR $ . # < >
;
GETCMD:
LDAX D ;GET NEXT CHARACTER
INX D ;INCREMENT POINTER
CPI '|'
RZ ;CR,LF GENERATION
CPI 'a'-1 ;LOWERCASE?
JC GETUPR ;NOPE
CPI 'z'+1 ;a-z?
JNC GETERR ;NOPE
sui 'a'-'A' ;GET TO UPPERCASE
GETUPR:
CPI '@' ;0-1FH CONTROL CODE?
JNC GETCC
CPI ':'
RZ ;RE-EXECUTE
CPI '?'
RZ ;CR WAIT
CPI '/'
RZ ;CR WAIT AND RING BELL
CPI '*'
RZ ;RING BELL
CPI '"'
RZ ;USER INPUT
CPI '$'
RZ ;DEFAULT PARAMETERS' LINE
CPI '.'
RZ ;PRINT SUPPRESS TOGGLE
CPI '#'
RZ ;MESSAGE SUPPRESS TOGGLE
CPI '<'
RZ ;IMMEDIATE MODE START
CPI '>'
RZ ;IMMEDIATE MODE STOP
JMP GETERR
GETCC:
SUI '@' ;GET CONTROL CODE
RNC
JMP GETERR
;
; EXTRACT PARAMETER ELEMENT WHOSE $N SPECIFICATION IS POINTED TO BY DE
; DE PTS TO CHAR AFTER THE $
; BUFFER TO PLACE RESULTING PARAMETER IS PTED TO BY HL
;
GTPARM:
LDAX D ;GET CHAR AFTER THE $
INX D ;PT TO NEXT CHAR
CPI '$' ;IF DOUBLE $, THEN STORE AS $
RZ
CPI '^' ;UP ARROW
RZ
CPI '|' ;CARRIAGE RETURN
RZ
CPI '1' ;CHECK FOR VALID DIGIT (1-9)
JC PRMERR
CPI '9'+1 ;RANGE ERROR?
JNC PRMERR
SUI '1' ;GET ACTUAL # (ZERO RELATIVE)
ADD A ;DOUBLE FOR OFFSET
STA PRMNUM
PUSH D ;SAVE PTRS
PUSH H
LXI H,PRMPNT ;PT TO PARAMETER PTR TABLE
CPI PRMPNL-1 ;PARAMETER NUMBER WITHIN RANGE?
JNC NOPARM ;> HIGHEST #
MOV E,A
MVI D,0
DAD D
MOV E,M ;GET PARAMETER POINTER
INX H
MOV D,M
POP H ;RESTORE PTR TO NEXT BYTE IN OUTPUT BUFFER BELOW ZEX
MOV A,E ;ANY PARAM?
ORA D
JZ NOPARM ;NO PARAMETER PRESENT, TRY DEFAULTS
;
; MOVE PARAMETER PTED TO BY DE INTO BUFFER BELOW ZEX, 1ST BYTE PTED TO BY HL
;
MOVPRM:
LDAX D ;GET PARAMETER CHAR
INX D ;PT TO NEXT
ORA A ;DONE?
JZ ENDPAR
MOV M,A ;STORE IN BUFFER
DCX H ;MOVE DOWN
JMP MOVPRM
;
; PARAMETER PLACED IN MEMORY -- CONTINUE
;
ENDPAR:
POP D ;GET PTR TO NEXT CHAR IN LINE
INX H ;PT TO LAST CHAR AND GET IT
MOV A,M ;UPON RETURN, LAST CHAR STORED NORMALLY SO THAT
RET ; OVERFLOW CHECK MAY BE DONE
;
; NO PARAMETER PTED TO
;
NOPARM:
PUSH H
LXI H,PRMDFP ;TRY DEFAULT PARAMETERS
LDA PRMNUM
CPI PRMDFL-1
JNC NUMERR ;> HIGHEST #
MOV E,A
MVI D,0
DAD D
MOV E,M ;GET PARAMETER POINTER
INX H
MOV D,M
POP H
MOV A,E
ORA D
JZ NODEFP ;NO PARAMETER PRESENT
JMP MOVPRM ;MOVE PARAMETER TO BUFFER
;
MOVEFN:
LDAX D
CPI ' ' ;SEE IF SPACE
RZ
MOV M,A
INX D ;INCREMENT POINTERS
INX H
DCR B
JNZ MOVEFN
RET
;
; INCREMENT LINE COUNT, AND AFFECT ONLY HL (MUST NOT AFFECT A)
;
INCR:
PUSH H ;SAVE OUTPUT POINTER
LHLD LINES
INX H ;INCREMENT LINE COUNTER
SHLD LINES
LXI H,LCHR ;CLEAR LAST CHARACTER
MVI M,0
LXI H,OUTCNT;CLEAR CHARACTER COUNT
MVI M,0
MOV L,E ;DE=HL
MOV H,D
SHLD BEGLIN
POP H
SHLD OUTLNE ;SAVE NEW OUTPUT LINE
RET
;
CNTINC:
CPI ' ' ;CONTROL CHARACTER?
RC ;YES..
CPI UICH ;USER INPUT CHAR?
JZ CNTIN1
ANI 80H ;SPECIAL CONTROL?
RNZ ;YES..
LDA PRTFLG
CPI PSUP ;PRINT SUPPRESS FLAG?
RZ ;YES..
LDA IMFLG1
CPI IMON ;IMMEDIATE MODE?
RZ ;YES..
CNTIN1:
LDA OUTCNT
INR A
STA OUTCNT
RET
;
PRINT:
MVI C,9 ;PRINT STRING AT (DE)
CALL BDOS
RET
;
EPRT:
MOV A,M ;PRINT PARAMETER LINE AT (HL)
CPI CR
RZ
CPI 0
JNZ EPRT1
MVI A,' '
EPRT1:
INX H
PUSH H
MOV E,A
MVI C,2
CALL BDOS
POP H
JMP EPRT
;
CRLF:
LXI D,CRLFS ;PRINT CR/LF
CALL PRINT
RET
;
LINE:
LXI D,LINEM ;PRINT LINE # AND LINE IN ERROR AND EXIT
CALL PRINT
LHLD LINES
CALL DECOUT ;PRINT LINE #
CALL CRLF
LHLD BEGLIN
PUSH H ;SAVE BEGGING POINTER
FINDCR:
MOV A,M
INX H
CPI 1AH ;END OF BUFFER
JZ FOUND
CPI CR
JNZ FINDCR
FOUND:
MVI M,0 ;END OF STRING
POP H ;START OF STRING
CALL PRNTHL ;PRINT BAD LINE
JMP CCPRET ;THATS ALL FOLKS
;
PRNTHL:
MOV A,M ;PRINT LINE AT (HL)
INX H
ORA A
RZ
MOV E,A
PUSH H ;SAVE POINTER
CALL OUTCHR
POP H ;GET POINTER BACK
JMP PRNTHL
;
OUTCHR:
MVI C,2 ;PRINT CHARACTER IN E
JMP BDOS
;
DECOUT:
PUSH H ;PRINT DECIMAL LINE NUMBER
PUSH D
PUSH B
LXI B,-10 ;RADIX FOR CONVERSION
LXI D,-1 ;THIS BECOMES NO DIVIDED BY RADIX
DX:
DAD B ;SUBTRACT 10
INX D
JC DX
LXI B,10
DAD B ;ADD RADIX BACK IN ONCE
XCHG
MOV A,H
ORA L ;TEST FOR ZERO
CNZ DECOUT ;RECURSIVE CALL
MOV A,E
ADI '0' ;CONVERT FROM BCD TO HEX
MOV E,A ;TO E FOR OUTPUT
MVI C,2
CALL BDOS
POP B ;RESTORE REGISTERS
POP D
POP H
RET
;
MOVE:
MOV A,M ;MOVE STRING AT (HL) TO (DE) FOR LENGTH IN B
INX H
STAX D
INX D
DCR B
JNZ MOVE
RET
;
FILL:
PUSH D ; FILL STORAGE AT (HL) WITH CHARACTER IN A
MOV E,A ; FOR LENGTH IN BC
MOV A,B
ORA C
MOV A,E
POP D
RZ
DCX B
MOV M,A
INX H
JMP FILL
;
; WORKING STORAGE AREA
;
SUBNAM:
DB 'SUB'
ZEXNAM:
DB 'ZEX'
LINEM:
DB ' Error Line # $'
EXACT:
DB CR,LF,'(ZEX Already Present)$'
BUFMTY:
DB CR,LF,'Text Buffer Empty$'
OVERLP:
DB CR,LF,'Input/ZEX Buffer Overlap$'
NONUM:
DB CR,LF,'Parameter Number out of range$'
NOPRM:
DB CR,LF,'No Parameter or Default Parameter$'
PMERR:
DB CR,LF,'Parameter$'
NOSBF1:
DB CR,LF,'File '
NOSBF2:
DB 'filename.typ$'
NOTHER:
DB ' not there$'
CMDER:
DB CR,LF,'Control character$'
TOOARG:
DB CR,LF,'Too many arguments - $'
SIGNON:
DB 'ZEX, Version '
DB VERS/10+'0','.',(VERS MOD 10)+'0','$'
CRLFS:
DB CR,LF,'$'
;
DS 80 ;STACK SPACE
CCPSTK:
DW 0 ;CCP STACK PTR
IMFLG1:
DB 0 ;=IMON ENCOUNTERED
IMFLG2:
DB 0 ;=IMOFF ENCOUNTERED
PRTFLG:
DB 0 ;=PSUP ON
LCHR:
DB 0 ;LAST CHARACTER READ
PRMMAX:
DB 0 ;HIGHEST PARAMETER #
PRMNUM:
DB 0 ;CURRENT $<1-9> NUMBER * 2 (ZERO RELATIVE)
ERRLNE:
DW 0
BITMAP:
DB 0 ;PRESENT OFFSET BIT'S
COUNT:
DB 0FFH ;PRESENT OFFSET BIT COUNT
BEGLIN:
DW BEGREL ;BEGINNING OF OLD LINE POINTER
LINES:
DW 1
INBUF:
DW BEGREL
ENDBUF:
DW 0 ;END OF INPUT BUFFER
OUTCNT:
DB 0
OUTLNE:
DW 0
RELSTRT:
DW 0
OUTBUF:
DW 0
BUFSTR:
DW 0
RELOCL:
DW 0 ;LENGTH OF RELOC PROGRAM (FILLED IN BY SID)
PRMDFP: ;DEFAULT PARAMETER PTRS
REPT 9
DW 0
ENDM
PRMDFL EQU $-PRMDFP
PRMDMY:
DW 0 ;DUMMY PARAMETER FOR .SUB FILE SPEC.
PRMPNT: ;COMMAND LINE PARAMETER PTRS
REPT 9
DW 0
ENDM
PRMPNL EQU $-PRMPNT
PATCH: ;PATCH AREA
REPT 32
DB 'p'
ENDM
REPT 30
DW 0
ENDM
;
; INSURE 8 BYTE BOUNDARY FOR REL.UTL(RELS.UTL)
;
?PLOC SET $
IF (?PLOC MOD 8) GT 0
?PLOC SET (?PLOC AND 0FFF8H)+8 ;GET NEXT 8 BYTE BOUNDARY
ORG ?PLOC
ENDIF
;
BEGREL:
DS 0 ;RELOC PROGRAM STARTS HERE (ALSO USED AS BUFFER)
;
ENDIF
;
; END OF EX INITIATOR CODE SEGMENT
;
$-PRINT
IF NOT BASE
$+PRINT
;
; START OF EX RELOCATED CODE SEGMENT
; HL PTS TO TOP OF AVAILABLE MEMORY, DE PTS TO START OF
; TEXT BUFFER TO BE PROCESSED, BC PTS TO MULTIPLE COMMAND BUFFER
; OR BC=0 IF NO MULTIPLE COMMANDS
;
ORG REL
;
ZEX:
STA NUICH ;SAVE END OF USER INPUT CHAR
SHLD MEMTOP ;SAVE PTR TO TOP OF MEMORY
XCHG ;PT TO START OF BUFFER
SHLD REVBUF ;PTR TO FIRST CHAR
SHLD SAVBUF
PUSH H ;SAVE MULTIPLE COMMAND BUFFER LOCATION
MOV H,B
MOV L,C
SHLD EXMBASE
POP H
MOV A,M ;GET 1ST CHAR
CPI MSUP ;1ST CHAR=MESSAGE SUPPRESS?
JNZ EX1 ;NO...
DCX H ;YES..SKIP CHARACTER
SHLD REVBUF
STA MSUPFL ;SET INITIAL FLAG
EX1:
LXI SP,MEMTOP
LHLD BDOS+1 ;GET WARM JUMP FOR STANDARD CCP
MOV A,H
SUI 8
MOV H,A
MVI L,3 ;SET UP FOR WARM CCP JUMP
SHLD CCPJMP
LHLD WARM+1 ;SAVE WARM BOOT ADDRESS
SHLD WARMPT
LXI D,BSWARM ;SAVE OLD BIOS JUMPS
MVI B,12
CALL MOVE ;MOVE BIOS JUMPS
LHLD WARMPT
XCHG
LXI H,LOCJMP ;STORE NEW BIOS JUMPS
MVI B,12
CALL MOVE ;MOVE NEW BIOS JUMPS TO BIOS AREA
;
; EX RUNTIME BIOS INTERCEPT ROUTINES
;
NWARM:
LXI SP,MEMTOP
LHLD REVBUF ;SEE IF WE'RE AT BUFFERS END
MOV A,M
CPI 0FFH ;TEST IT
JZ WARMR ;WARM RETURN
XRA A ;A=0
STA UIFLG ;SET NO USER INPUT
LHLD WARMPT ;SET WARM BOOT ADDRESS
SHLD WARM+1
LHLD MEMTOP ;SET BDOS ENTRY ADDRESS
SHLD BDOS+1
LXI D,BUFF ;DMA ADDRESS
MVI C,26 ;SET DMA
CALL BDOS
LXI H,STARTM ;TELL USER WE'RE STILL HERE
CALL PMSG
LDA BDISK
MOV C,A
LHLD CCPJMP
PCHL ;GOTO CONSOLE PROCESSOR
;
; JMP TABLE TO OVERLAY BIOS WITH NEW ZEX-BASED JUMPS
;
LOCJMP:
JMP NWARM ;WARM
JMP BCONST ;CONST
JMP NCONIN ;CONIN
JMP NCONOT ;CONOT
;
; CONSOLE INPUT INTERCEPT ROUTINE
;
NCONIN:
LDA UIFLG ;USER INPUT ACTIVE?
ORA A ;0=NO
JNZ BCONIN ;GET INPUT VIA BIOS IF USER INPUT ACTIVE
LXI H,0
DAD SP ;SAVE RETURN STACK LEVEL
SHLD CONSTK
LXI SP,MEMTOP ;SET USER STACK
NCONNL:
CALL BCONST ;GET CONSOLE STATUS
ORA A
JZ GETBUF ;GET CHARACTER FROM BUFFER
CALL BCONIN ;GET CHARACTER
CPI 'C'-'@' ;SEE IF TERMINATE CHARACTER
JZ ZEXABRT
CPI 'S'-'@' ;13H
JNZ NCONEX
CALL BCONIN ;WAIT FOR NEXT CHARACTER
ANI 7FH
LHLD REVBUF
INX H
MOV M,A
SHLD REVBUF
MVI A,'S'-'@' ;13H
NCONEX:
LHLD CONSTK ;RESTORE CALLER'S STACK
SPHL
RET
;
; RETURN NEXT CHAR FROM INPUT BUFFER
;
GETBUF:
LDA PSUPFL ;SET PRINT SUPPRESS FLAG FOR NCONOT
STA OUTFLG
GBUF1:
CALL GETCHR ;GET NEXT CHARACTER
CPI UICH ;USER INPUT?
JZ UISTRT ;YES..SET USER INPUT PENDING FLAG
CPI REXEC ;RE-EXECUTE?
JZ REXECR ;YES..RESET BUFFER PTR
CPI CRWAIT ;CR WAIT?
JZ CRWRTN ;YES..WAIT FOR CR
CPI CRBWAIT ;CR WAIT WITH RING BELL?
JZ CRBWRTN ;YES..WAIT FOR CR AND RING BELL
CPI RNG ;RING BELL?
JZ RNGBELL ;YES..JUST RING THE BELL
CPI MSUP ;MESSAGE SUPPRESS FLAG?
JZ MSUPCK ;YES..TOGGLE FLAG
CPI PSUP ;PRINT SUPPRESS ?
JZ PSUPCK ;YES..TOGGLE FLAG
CPI IMON ;IMMEDIATE MODE START ?
JZ IMFLGS ;YES..SET FLAG
CPI IMOFF ;IMMEDIATE MODE STOP?
JZ IMFLGS ;YES..RESET FLAG
CPI CR ;CR?
JNZ GETEXT ;NO...EXIT
XRA A
STA OUTFLG ;YES..RESET PRINT SUPPRESSION
MVI A,CR
GETEXT:
MOV C,A
LDA IMFLG
CPI IMON ;IMMEDIATE MODE ?
MOV A,C
JNZ NCONEX ;NO...RETURN TO CALLER WITH CHAR
CALL BCONOT ;YES..IMMEDIATE ECHO TO CONSOLE
JMP NCONNL ;...LOOP UNTIL IMOFF
;
; ^" COMMAND
;
UISTRT:
MVI A,0FFH ;TURN ON FLAG
STA UIFLG ;SET USER INPUT PENDING
LHLD CONSTK ;RESTORE CALLER'S STACK
SPHL
JMP NCONIN ;GET CHAR FROM USER FOR NOW
;
; ^: COMMAND
;
REXECR:
LHLD SAVBUF ;START AT TOP OF BUFFER AGAIN
SHLD REVBUF
XRA A
STA IMFLG ;RESET ALL FLAGS
STA PSUPFL
STA MSUPFL
STA UIFLG
JMP NCONNL ;...LOOP UNTIL ^C
;
; ^? COMMAND
;
CRWRTN:
CALL BCONIN ;GET INPUT CHAR
CPI 'C'-'@'
JZ ZEXABRT ;=^C
CPI CR
JZ CRWRTX ;=<CR>
CPI ' '
JZ CRWRTX ;=<SP>
MVI C,BELL
CALL BCONOT ;<>CR
JMP CRWRTN
;
; ^/ COMMAND
;
CRBWRTN:
LXI H,DELAY ;SET COUNTER
CRBWR1:
PUSH H ;SAVE COUNTER
CALL BCONST ;CHECK STATUS
POP H ;GET COUNTER
ORA A ;SET FLAGS
JNZ CRBWR2
DCX H ;COUNT DOWN
MOV A,H ;DONE?
ORA L
JNZ CRBWR1
MVI C,BELL ;RING BELL
CALL BCONOT
JMP CRBWRTN
CRBWR2:
CALL BCONIN ;GET CHAR
CPI 'C'-'@' ;ABORT?
JZ ZEXABRT
CPI CR ;CONT IF <CR>
JNZ CRBWRTN
;
; ^| COMMAND
;
CRWRTX:
MOV C,A ;ECHO CR/LF
CALL NCONOT
MVI C,LF
CALL NCONOT
JMP GETBUF
;
; ^* COMMAND
;
RNGBELL:
MVI C,BELL ;RING BELL
CALL NCONOT
JMP GETBUF
;
; ^. COMMAND
;
PSUPCK:
LXI H,PSUPFL
CMP M
JNZ PSUPST ;SET FLAGS IF NOT EQUAL
XRA A ;ELSE RESET FLAGS
PSUPST:
MOV M,A ;SET/RESET SAVED FLAG
JMP GETBUF ;AND GET NEXT CHARACTER (SETS EXEC FLAG)
;
; ^# COMMAND
;
MSUPCK:
LXI H,MSUPFL
CMP M
JNZ MSUPST ;SET FLAGS IF NOT EQUAL
XRA A ;ELSE RESET FLAG
MSUPST:
MOV M,A ;SET/RESET FLAG
JMP GETBUF ;AND GET NEXT CHARACTER
;
; ^< AND ^> COMMANDS
;
IMFLGS:
STA IMFLG ;SET/RESET IMMEDIATE MODE FLAG
JMP GETBUF ;GET NEXT CHARACTER
;
; CONSOLE OUTPUT INTERCEPT ROUTINE
;
NCONOT:
LDA OUTFLG ;PRINT SUPPRESSION?
ORA A
RNZ ;YES...IGNORE ECHO
MOV A,C
STA PMCHR
LDA NUICH ;END OF USER INPUT?
CMP C
JNZ BCONOT
XRA A ;A=0
STA UIFLG ;CLEAR USER INPUT
JMP BCONOT
;
; GET NEXT CHAR FROM BUFFER AND TERMINATE ZEX IF END OF BUFFER
;
GETCHR:
LHLD REVBUF
MOV A,M
DCX H
SHLD REVBUF
CPI 0FFH ;EOB?
RNZ ;NO...RETURN
LHLD REVBUF
INX H ;POINT TO EOB
SHLD REVBUF
CALL MOVBAK ;MOVE JUMPS BACK
CALL BDOSRST ;RESTORE BDOS ADDRESS
CALL PMCHRS ;RESTORE PROMPT
LXI H,DONEM ;TELL USER WE'RE DONE
CALL PMSG
LHLD CONSTK ;GET OLD STACK
SPHL
JMP BCONIN
;
; RESTORE BDOS JMP IF NECESSARY
;
BDOSRST:
LHLD MEMTOP ;SEE IF BDOS+1=MEMTOP
XCHG
LHLD BDOS+1
MOV A,E
SUB L
MOV A,D
SBB H
RNZ ;DON'T REPLACE BDOS JUMP
INX D ;PT TO BDOS JUMP
LDAX D ;GET LOW ADDRESS
MOV L,A ;... IN L
INX D
LDAX D ;GET HIGH ADDRESS
MOV H,A ;... IN H
SHLD BDOS+1 ;RESET BDOS JUMP
RET
;
; ^C ABORT EXIT
;
ZEXABRT:
LXI SP,MEMTOP ;^C ABORTS EX
LXI H,ABORTD ;ABORT
CALL PMSG ;FALL THRU TO WARMX
;
; ABORT ZEX AND RETURN TO ZCPR2
;
WARMX:
LXI H,DONEC ;CLASSIC FINISH
CALL PMSG
WARMX1:
CALL MOVBAK ;MOVE JUMPS BACK
LHLD EXMBASE ;MULTIPLE COMMAND LINES ENABLED?
MOV A,H ;ANY ON?
ORA L
JZ WARM ;NONE ON IF ADDRESS IS ZERO, SO JUST WARM BOOT
;
; THIS SECTION OF CODE CLEARS THE MULTIPLE COMMAND LINE BUFFER
;
; MOV D,H ;DE PTS TO MULTIPLE COMMAND BUFFER ALSO
; MOV E,L
; PUSH H ;SAVE PTR
; LXI H,4 ;PT TO FIRST CHAR OF LINE
; DAD D
; MVI M,0 ;SET FIRST CHAR OF LINE TO ZERO FOR EOL
; XCHG ;DE PTS TO FIRST CHAR OF LINE
; POP H ;GET PTR
; MOV M,E ;STORE ADDRESS OF EMPTY COMMAND (EOL)
; INX H
; MOV M,D
JMP WARM
;
WARMR:
CALL PMCHRS ;RESTORE PROMPT
LXI H,DONEM ;END MESSAGE
CALL PMSG
JMP WARMX1
;
; SUBROUTINES
;
MOVBAK:
LHLD WARMPT ;MOVE OLD JUMP TABLE BACK TO BIOS
XCHG
LXI H,BSWARM
MVI B,12
CALL MOVE
JMP F121 ;CALL 1.2.1 FIX FOR MBASIC 1.1.2
;
MOVE:
MOV A,M ;MOVE STRING FROM (HL) TO (DE) FOR LENGTH IN B
INX H
STAX D
INX D
DCR B
JNZ MOVE
RET
;
PMCHRS:
LDA PMCHR ;SET PROMPT CHAR ONLY IF SPECIAL CHARACTER
CPI ' '+1
RC
CPI '0'
JC PMCHRX
CPI '9'+1
RC
CPI 'A'
JC PMCHRX
CPI 'Z'+1
RC
CPI 'a'
JC PMCHRX
CPI 'z'+1
RC
PMCHRX:
STA DONEC
RET
;
PMSG:
LDA MSUPFL ;PRINT MESSAGE AT (HL)
CPI MSUP ;MESSAGES SUPPRESSED?
RZ ;YES..EXIT
PUSH H
PMSGL:
POP H
MOV A,M
CPI '$' ;EOM?
RZ ;YES..EXIT
INX H
PUSH H
MOV C,A
CALL BCONOT
JMP PMSGL
;
; REPLACE ZEX ROUTINE JUMPS WITH BIOS JUMPS
;
F121:
LXI H,BSWARM ; INSURE ONLY BIOS 1.1.2
LXI D,NWARM ; CALLS FROM NOW ON 1.1.2
MVI B,3 ; FOR PROGRAMS 1.1.2
CALL MOVE ; THAT MAY HAVE 1.1.2
LXI H,BCONIN ; COPIED OUR 1.1.2
LXI D,NCONIN ; ADDRESSES AS 1.1.2
MVI B,3 ; IF THEY WERE 1.1.2
CALL MOVE ; IN THE BIOS. 1.1.2
LXI H,BCONOT ; (MBASIC DOES THIS) 1.1.2
LXI D,NCONOT ; 1.1.2
MVI B,3 ; 1.1.2
JMP MOVE ; 1.1.2
;
; WORKING STORAGE AREA
;
ABORTD:
DB CR,LF,'(ZEX Aborted)',CR,LF,'$'
STARTM:
DB CR,LF,'(ZEX Active)$'
DONEM:
DB CR,LF,'(ZEX Completed)',CR,LF
DONEC:
DB '>$'
;
REPT 12
DW 0
ENDM
MEMTOP:
DW 0
EXMBASE:
DW 0
REVBUF:
DW 0
SAVBUF:
DW 0
CCPJMP:
DW 0
WARMPT:
DW 0
;
; ORIGINAL BIOS JMP TABLE
;
BSWARM:
JMP $
BCONST:
JMP $
BCONIN:
JMP $
BCONOT:
JMP $
;
PMCHR:
DB 0
PSUPFL:
DB 0
OUTFLG:
DB 0
NUICH:
DB 0
IMFLG:
DB 0
MSUPFL:
DB 0
UIFLG:
DB 0
CONSTK:
DW 0
;
?PLEN SET $
IF (?PLEN MOD 8) GT 0
?PLEN SET (?PLEN AND 0FFF8H)+8;GET NEXT BOUNDARY
ENDIF
;
DRVERL EQU ?PLEN
;
DRVL8 EQU DRVERL/8 ;LENGTH OF RELOCATION BIT MAP
ORG DRVERL
;
ENDIF
;
; END OF EX RELOCATED CODE SEGMENT
;
END