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
/
ZSYS
/
SIMTEL20
/
ZCPR3
/
ZEX.AQM
/
ZEX.ASM
Wrap
Assembly Source File
|
2000-06-30
|
47KB
|
2,286 lines
;
; PROGRAM: ZEX
; AUTHOR: RICHARD CONN (DERIVED FROM EX, WHICH WAS WRITTEN BY SOMEONE ELSE)
; VERSION: 3.1
; DATE: 24 Oct 84
; PREVIOUS VERSIONS: 3.0 (8 Mar 84)
;
VERS EQU 31
Z3ENV EQU 0F400H
;
; ZEX 3.1 -- Richard Conn
; Does not require to be reassembled for a target system; Z3INS
; installation is sufficient
; ZEX 3.0 -- Derived from ZEX 1.3 for ZCPR3 by Richard Conn
; Extensions to ZEX 1.3 are:
; ZCPR3 Message Passing Employed
; ZCPR3 Structure
; Omitted Parameters Allowed
; Print Suppression During FALSE IFs (^&)
;
; 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)
; ZCPR3 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 ZCPR3 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 ZCPR3 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 ZEX TO RE-EXECUTE THE .SUB FILE FROM THE BEGINNING
;
; ^? WILL CAUSE ZEX TO WAIT FOR A CARRIAGE RETURN
; (^C WILL ABORT ZEX 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 ZCPR3 MESSAGE
; CONTROLLING ZEX IS CHANGED TO PERMIT CONTINUATION
;
; ^$ 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 ZEX'S COMMAND LINE.
;
; ^# WILL TOGGLE PRINT SUPPRESSION OF ZEX MESSAGES
;
; ^. WILL START PRINT SUPPRESSION OF ALL CHARACTERS
; FROM .SUB FILE UNTIL A SUBSEQUENT ^. IS ENCOUNTERED
;
; ^& WILL INSTRUCT ZEX TO SUPPRESS PRINT IF WITHIN A FALSE IF
;
; ;; WILL INDICATE THAT THE ;; AND ALL CHARACTERS FOLLOWING IT
; UNTIL A LF IS ENCOUNTERED ARE NOT INCLUDED IN ZEX'S
; TEXT BUFFER
; (I.E. A ZEX 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 ZEX
;
FALSE EQU 0
TRUE EQU NOT FALSE
;
; OFFSETS TO ZCPR3 ENVIRONMENT DESCRIPTOR ELEMENTS
;
EPOFF EQU 9 ;EXTERNAL PATH DATA
MCOFF EQU 24 ;COMMAND LINE DATA
Z3MOFF EQU 34 ;MESSAGE BUFFER
;
; GENERAL EQUATES
;
BELL EQU 7
CTRLZ EQU 1AH ;^Z
DELAY EQU 6000H ;DELAY CONSTANT FOR TIMER LOOP
BS EQU 'H'-'@' ;BACKSPACE
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 ;^# ZEX MESSAGE SUPPRESS FLAG
CRWAIT EQU 84H ;^? ZEX RUNTIME WAIT FOR CR FLAG
REXEC EQU 85H ;^: ZEX RUNTIME RE-EXECUTE FLAG
CRBWAIT EQU 86H ;^/ ZEX RUNTIME RING BELL AND WAIT FOR CR FLAG
RNG EQU 87H ;^* ZEX RUNTIME RING BELL
UICH EQU 88H ;^" USER INPUT COMMAND CHAR SEQUENCE
IPS EQU 89H ;^& FALSE IF PRINT SUPPRESS
;
; CP/M CONSTANTS
;
WARM EQU 0
BDISK EQU 4
BDOS EQU 5
DFCB EQU 5CH
BUFF EQU 80H
;
; NOTE: ZEX30.LIB IS CREATED BY THE ZEX30.ZEX GENERATION PROCESS
;
MACLIB ZEX30
;
$-PRINT
IF ZEXBASE
$+PRINT
;
; START OF ZEX INITIATOR CODE SEGMENT
;
ORG 100H
;
; Environment Definition
;
if z3env ne 0
;
; External ZCPR3 Environment Descriptor
;
jmp start
db 'Z3ENV' ;This is a ZCPR3 Utility
db 1 ;External Environment Descriptor
z3eadr:
dw z3env
start:
lhld z3eadr ;pt to ZCPR3 environment
;
else
;
; Internal ZCPR3 Environment Descriptor
;
MACLIB SYSENV.LIB
z3eadr:
jmp start
SYSENV
start:
lxi h,z3eadr ;pt to ZCPR3 environment
endif
;
; Start of Program -- Initialize ZCPR3 Environment
;
call z3init ;initialize the ZCPR3 Env
JMP START0
;
; 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
;
START0:
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 ZEXACTV ;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 ZEX 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
DCX H ;PT TO START OF DATA AREA
MVI B,09H ;MESSAGE OFFSET
CALL MSHLD ;STORE HL THERE (NEXT CHAR FOR ZEX)
MVI B,0BH ;MESSAGE OFFSET
CALL MSHLD ;STORE HL THERE (FIRST CHAR FOR ZEX)
MVI A,0FFH ;SET ZEX RUNNING FLAG
MVI B,08H ;MESSAGE OFFSET
CALL MSTA ;STORE A THERE (ZEX IS RUNNING)
POP H ;HL IS PTR TO END OF DATA
MOV M,A ;SET UP END OF DATA
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
SHLD BDOS+1 ;SET NEW BDOS ADDRESS
LXI H,0 ;ASSUME NO MULTIPLE COMMANDS
LDA MCAVAIL ;GET FLAG
ORA A ;0=NONE
JZ GOTOZEX ;NO MULTIPLE COMMANDS, SO BC=0
LHLD MCADR ;GET ADDRESS OF MULTIPLE COMMAND BUFFER
;
; ZEX MONITOR ENTRY PARAMETERS --
; HL ADDRESS OF MULTIPLE COMMAND BUFFER OR 0 IF NONE
;
GOTOZEX:
XCHG ;SAVE HL
LHLD Z3MSGA ;GET ADDRESS OF MESSAGES ...
XCHG ; ... IN DE
GOADR EQU $+1
JMP $
;
; INIT ZCPR3 ENVIRONMENT
;
Z3INIT:
PUSH H ;SAVE PTR TO ENVIRONMENT
PUSH H
LXI D,Z3MOFF ;OFFSET TO MESSAGE BUFFER
DAD D
MOV A,M ;GET LOW
INX H
MOV H,M ;GET HIGH
MOV L,A ;HL IS ADDRESS OF MESSAGES
SHLD Z3MSGA ;SAVE ADDRESS
POP H
LXI D,MCOFF ;OFFSET TO CL DATA
DAD D
MOV E,M ;GET CL ADDRESS
INX H
MOV D,M
INX H ;GET CL SIZE
MOV A,M
ORA D ;IF ALL THREE VALUES ARE 0, THEN NO COMMAND LINE
ORA E
STA MCAVAIL ;SET AVAILABLE FLAG
XCHG ;HL PTS TO CL
SHLD MCADR
POP H ;GET PTR TO ENVIRONMENT
LXI D,EPOFF ;OFFSET TO EXTERNAL PATH DATA
DAD D
MOV E,M ;GET EXTERNAL PATH ADDRESS
INX H
MOV D,M
MOV A,D ;CHECK FOR ANY
ORA E
STA EPAVAIL ;SET AVAILABLE FLAG
XCHG
SHLD EPADR ;SET ADDRESS
RET
;
; Z3INIT BUFFERS
;
INTPATH: ;INTERNAL PATH
DB 1,0 ;DISK A, USER 0
DB 0,0 ;END OF PATH
Z3MSGA: ;ADDRESS OF MESSAGES
DW 0
MCAVAIL: ;MULTIPLE COMMAND LINE DATA
DB 0
MCADR:
DW 0
EPAVAIL: ;EXTERNAL PATH DATA
DB 0
EPADR:
DW 0
;
; 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,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,'ZEX Syntax:'
DB CR,LF,' ZEX <zexfile> <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 CR,LF,'SUB both exist, the ZEX file is used), passing to it'
DB CR,LF,'the parameters, similar to the way SUBMIT is used.'
DB CR,LF
DB CR,LF,'The second form allows the user to enter 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 type in a command'
DB CR,LF,'line. Input is terminated by simply striking the'
DB CR,LF,'RETURN key (empty input line).'
DB CR,LF
DB CR,LF,'ZEX can be aborted by ^C from console.'
DB CR,LF
DB CR,LF,' Strike Any Key to Continue, ^C to Abort - ',0
HMSG1:
DB CR,LF
DB CR,LF,'ZEX supports an enhanced command processing facility'
DB CR,LF,'which recognizes the following commands. These may be'
DB CR,LF,'embedded in the text of the command file or user'
DB CR,LF,'input and will be executed after processing begins.'
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,CR,LF,0
;
; RELOCATE ZEX MODULE INTO HIGH MEMORY JUST BELOW ZCPR3
;
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 ;TERMINATE COMMAND LINE WITH CR
LDAX D ;GET CHAR COUNT
INX D ;PT TO FIRST CHAR
PUSH D
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 ZCPR3 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
CPI '$' ;CURRENT DISK?
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
CPI '$' ;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 ZCPR3; 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 ;SET LINE COUNT
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 ZEX 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 ZEX COMMENT PROCESSING
CPI ';' ;FIRST ';'?
JZ EXCOMM ;PROCESS POSSIBLE ZEX 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
CPI '&'
JZ IFPSUP ;PRINT SUPPRESS DURING FALSE IF
JMP MOVST3 ;OTHER CONTROL CODES
;
IFPSUP:
MVI A,IPS ;CONVERT '^&' TO IF PRINT SUPPRESS FLAG
JMP MOVST3
;
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/ZEX 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 ZEX
;
; ADD CHAR TO ZEX'S BUFFER
;
CHRSTX:
POP D ;ADD CHAR. TO ZEX'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
;
ZEXACTV:
MVI B,08H ;MESSAGE OFFSET
CALL MLDA ;GET VALUE IN A
ORA A ;0 IF NO
RZ
LXI D,ZEXACT
CALL PRINT ;ZEX ALREADY PRESENT
;
; ABORT AND RETURN TO ZCPR3
;
CCPRET:
LHLD CCPSTK ;RESTORE STACK
SPHL
RET ;RETURN TO CCP
;
; ZCPR3 MESSAGE BUFFER ACCESS ROUTINES
;
;
; GETZ3MSG RETURNS HL POINTING TO DESIRED MESSAGE (OFFSET IN B)
;
GETZ3MSG:
PUSH D ;SAVE DE
LHLD Z3MSGA ;GET ADDRESS OF MESSAGES
MOV E,B ;GET OFFSET
MVI D,0
DAD D ;HL PTS TO MESSAGE OF INTEREST
POP D
RET
MSHLD:
PUSH D ;SAVE DE
XCHG
CALL GETZ3MSG ;MAKE HL PT TO MESSAGE
MOV M,E ;STORE LOW
INX H
MOV M,D ;STORE HIGH
XCHG ;RESTORE HL
POP D ;RESTORE DE
RET
MSTA:
PUSH H ;SAVE HL
CALL GETZ3MSG ;PT TO MESSAGE WITH HL
MOV M,A ;STORE MESSAGE
POP H
RET
MLDA:
PUSH H ;SAVE HL
CALL GETZ3MSG ;PT TO MESSAGE WITH HL
MOV A,M ;GET MESSAGE
POP H
RET
;
; END OF Z3MSG ACCESS ROUTINES
;
;
; 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
;
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/ZEX 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
CPI '&'
RZ ;FALSE IF PRINT SUPPRESS
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
CALL CHRSTR ;STORE CHARS
JMP MOVPRM
;
; PARAMETER PLACED IN MEMORY -- CONTINUE
;
ENDPAR:
POP D ;GET PTR TO NEXT CHAR IN LINE
POP PSW ;CLEAR STACK
JMP MOVSTR ;RESUME PROCESSING
;
; NO PARAMETER PTED TO
;
NOPARM:
PUSH H ;SAVE PTR TO NEXT BYTE IN BUFFER BELOW ZEX
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
JNZ MOVPRM ;MOVE PARAMETER INTO BUFFER
JMP ENDPAR ;RESUME WITH NO PARAMETER
;
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)
JMP BDOS
;
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
JMP PRINT
;
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 # $'
ZEXACT:
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 ZEX INITIATOR CODE SEGMENT
;
$-PRINT
IF NOT ZEXBASE
$+PRINT
;
; START OF ZEX RELOCATED CODE SEGMENT
; HL PTS TO MULTIPLE COMMAND BUFFER
; OR HL=0 IF NO MULTIPLE COMMANDS
;
ORG ZEXREL
;
ZEX:
SHLD EXMBASE ;SAVE ADDRESS OF MCL BUFFER
XCHG ;HL=ADDRESS OF ZCPR3 MESSAGES
SHLD Z3MSGA ;SAVE ADDRESS
MVI B,09H ;MESSAGE OFFSET
CALL MLHLD ;GET ADDRESS OF NEXT CHAR
MOV A,M ;GET 1ST CHAR
CPI MSUP ;1ST CHAR=MESSAGE SUPPRESS?
JNZ ZEX1 ;NO...
DCX H ;YES..SKIP CHARACTER
MVI B,09H ;MESSAGE OFFSET
CALL MSHLD ;SET PTR TO NEXT CHAR
STA MSUPFL ;SET INITIAL FLAG
ZEX1:
LXI SP,MEMTOP
LHLD BDOS+1 ;GET WARM JUMP FOR STANDARD CCP
SHLD MEMTOP ;SET PTR TO TOP OF MEMORY
INX H
MOV E,M ;DE = ADDRESS OF ACTUAL BDOS
INX H
MOV D,M
XCHG ;HL PTS TO ACTUAL BDOS
MOV A,H ;SUBTRACT 8 FOR CCP ENTRY POINT
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
;
; ZEX RUNTIME BIOS INTERCEPT ROUTINES
;
NWARM:
LXI SP,MEMTOP
MVI B,09H ;MESSAGE OFFSET
CALL MLHLD ;GET ADDRESS OF NEXT CHAR
MOV A,M
CPI 0FFH ;TEST IT
JZ WARMX ;WARM RETURN
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
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
;
; ZCPR3 MESSAGE BUFFER ACCESS ROUTINES
;
;
; GETZ3MSG RETURNS HL POINTING TO DESIRED MESSAGE (OFFSET IN B)
;
Z3MSGA:
DW 0 ;MESSAGES ADDRESS
GETZ3MSG:
PUSH D ;SAVE DE
LHLD Z3MSGA ;GET ADDRESS OF MESSAGES
MOV E,B ;GET OFFSET
MVI D,0
DAD D ;HL PTS TO MESSAGE OF INTEREST
POP D
RET
MSHLD:
PUSH D ;SAVE DE
XCHG
CALL GETZ3MSG ;MAKE HL PT TO MESSAGE
MOV M,E ;STORE LOW
INX H
MOV M,D ;STORE HIGH
XCHG ;RESTORE HL
POP D ;RESTORE DE
RET
MLHLD:
PUSH PSW ;SAVE A
CALL GETZ3MSG ;MAKE HL PT TO MESSAGE
MOV A,M ;GET LOW
INX H
MOV H,M ;GET HIGH
MOV L,A ;PUT LOW
POP PSW ;RESTORE A
RET
MSTA:
PUSH H ;SAVE HL
CALL GETZ3MSG ;PT TO MESSAGE WITH HL
MOV M,A ;STORE MESSAGE
POP H
RET
MLDA:
PUSH H ;SAVE HL
CALL GETZ3MSG ;PT TO MESSAGE WITH HL
MOV A,M ;GET MESSAGE
POP H
RET
;
; END OF Z3MSG ACCESS ROUTINES
;
;
; CONSOLE INPUT INTERCEPT ROUTINE
;
NCONIN:
MVI B,07H ;MESSAGE OFFSET
CALL GETZ3MSG ;PT TO ZEX MESSAGE BYTE
MOV A,M ;GET ZEX MESSAGE
CPI 2 ;SUSPEND INTERCEPT?
JZ BCONIN ;GET INPUT VIA BIOS IF USER INPUT ACTIVE
CPI 1 ;PROMPT JUST PRINTED?
JNZ NCONNP
MVI M,0 ;CLEAR ZEX MESSAGE
LXI H,STARTM ;PRINT MESSAGE
CALL PMSG
; LDA PMCHR ;PRINT PROMPT CHAR
; MOV C,A
; CALL BCONOT
NCONNP:
MVI B,08H ;MESSAGE OFFSET
CALL MLDA ;GET ZEX RUNNING MESSAGE
ORA A ;0=NO
JZ WARMX ;ABORT ZEX IF NOT
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
MVI B,09H ;MESSAGE OFFSET
CALL MLHLD ;PT TO NEXT CHAR
INX H
MOV M,A
MVI B,09H ;MESSAGE OFFSET
CALL MSHLD ;RESET PTR TO NEXT CHAR
MVI A,'S'-'@' ;13H
NCONEX:
LHLD CONSTK ;RESTORE CALLER'S STACK
SPHL
RET
;
; RETURN NEXT CHAR FROM INPUT BUFFER
;
GETBUF:
LDA IPSUPFL ;COMBINE PSUPFL AND IPSUPFL TO SET PRINT FLAG
ORA A ;0=NO SUPPRESS
JZ GBUF0
MVI B,01H ;OFFSET TO IF FLAG
CALL GETZ3MSG ;PT TO IF FLAG
MOV A,M ;GET IF FLAG
ORA A ;NO IF?
JZ GBUF0
INX H
ANA M ;SET IF STATE
JNZ GBUF0 ;CURRENT IF IS TRUE
MVI A,0FFH ;SUPPRESS PRINT
STA OUTFLG
JMP GBUF1
GBUF0:
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 IPS ;FALSE IF PRINT SUPPRESS?
JZ IPSUPCK
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
;
; CR, SO RESET PRINT SUPPRESSION BASED ONLY ON IPSUPFL
;
LDA IPSUPFL ;COMBINE PSUPFL AND IPSUPFL TO SET PRINT FLAG
ORA A ;0=NO SUPPRESS
JZ GBUF2
MVI B,01H ;MESSAGE OFFSET TO IF FLAG
CALL GETZ3MSG ;PT TO IF FLAG
MOV A,M ;GET IF FLAG
ORA A ;NO IF?
JZ GBUF2
INX H
ANA M ;SET IF STATE
JNZ GBUF2 ;CURRENT IF IS TRUE
MVI A,0FFH ;SUPPRESS PRINT
STA OUTFLG
MVI A,CR
JMP GETEXT
GBUF2:
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,2 ;SET MESSAGE TO SUSPEND INTERCEPT
MVI B,07H ;MESSAGE OFFSET
CALL MSTA ;SET MESSAGE
LHLD CONSTK ;RESTORE CALLER'S STACK
SPHL
JMP NCONIN ;GET CHAR FROM USER FOR NOW
;
; ^: COMMAND
;
REXECR:
MVI B,0BH ;MESSAGE OFFSET
CALL MLHLD ;PT TO FIRST CHAR IN BUFFER
MVI B,09H ;MESSAGE OFFSET
CALL MSHLD ;SET PTR TO NEXT CHAR
XRA A
STA IMFLG ;RESET ALL FLAGS
STA PSUPFL
STA IPSUPFL
STA MSUPFL
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
;
IPSUPCK:
LXI H,IPSUPFL
CMP M
JNZ PSUPST ;SET FLAGS IF NOT EQUAL
XRA A ;ELSE RESET FLAGS
JMP PSUPST ;SET/RESET FLAG IN A
;
; ^# 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 ;SET LAST CHAR OUTPUT
JMP BCONOT
;
; GET NEXT CHAR FROM BUFFER AND TERMINATE ZEX IF END OF BUFFER
;
GETCHR:
MVI B,09H ;MESSAGE OFFSET
CALL MLHLD ;PT TO NEXT CHAR
MOV A,M ;GET IT
DCX H ;PT TO FOLLOWING
MVI B,09H ;MESSAGE OFFSET
CALL MSHLD ;SET PTR TO NEXT CHAR
CPI 0FFH ;EOB?
RNZ ;NO...RETURN
; LHLD Z3MSG+09H ;PT TO EOB
INX H ;POINT TO EOB
MVI B,09H ;MESSAGE OFFSET
CALL MSHLD ;SET PTR TO NEXT CHAR (LAST CHAR)
CALL MOVBAK ;MOVE JUMPS BACK
CALL BDOSRST ;RESTORE BDOS ADDRESS
CALL PRDONEM
XRA A ;TURN OFF ZEX
MVI B,08H ;MESSAGE OFFSET
CALL MSTA ;TURN OFF ZEX
LHLD CONSTK ;GET OLD STACK
SPHL
MVI A,CR ;RETURN CARRIAGE RETURN
RET
;
; PRINT DONE MESSAGE WITH FOLLOWING PROMPT CHAR
;
PRDONEM:
LXI H,DONEM ;PRINT MESSAGE
CALL PMSG
LDA PMCHR ;PRINT PROMPT CHAR
MOV C,A ;IN C FOR BIOS
JMP BCONOT
;
; 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 ZEX
LXI H,ABORTD ;ABORT
CALL PMSG
JMP WARMX1 ;DON'T PRINT DONE MESSAGE
;
; ABORT ZEX AND RETURN TO ZCPR3
;
WARMX:
CALL PRDONEM ;PRINT DONE MESSAGE
;
; ENTRY POINT TO ABORT ZEX WITHOUT MESSAGE
;
WARMX1:
XRA A ;SAY THAT ZEX IS NOT RUNNING
MVI B,08H ;MESSAGE OFFSET
CALL MSTA ;SET NOT RUNNING
CALL MOVBAK ;MOVE JUMPS BACK
CALL BDOSRST ;RESTORE BDOS JUMPS
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
;
; 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
;
PMSG:
PUSH H
LDA IPSUPFL ;COMBINE PSUPFL AND IPSUPFL TO SET PRINT FLAG
ORA A ;0=NO SUPPRESS
JZ PMSG0
MVI B,01H ;MESSAGE OFFSET TO IF FLAG
CALL GETZ3MSG ;PT TO IF FLAG
MOV A,M ;GET IF FLAG
ORA A ;NO IF?
JZ PMSG0
INX H
ANA M ;SET IF STATE
POP H ;IN CASE OF RETURN
RZ ;SKIP MESSAGE IF SUPPRESSED
PUSH H
PMSG0:
POP H
LDA MSUPFL ;PRINT MESSAGE AT (HL)
CPI MSUP ;MESSAGES SUPPRESSED?
RZ ;YES..EXIT
PMSGL:
MOV A,M ;GET NEXT CHAR
ORA A ;END OF MESSAGE?
RZ ;YES..EXIT
INX H ;PT TO NEXT CHAR
PUSH H ;SAVE PTR
MOV C,A ;OUTPUT CHAR
CALL BCONOT
POP H ;RESTORE PTR
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,0
STARTM:
DB ' ZEX: ',0
DONEM:
DB 'Done',0
;
REPT 12 ;12 ELT STACK
DW 0
ENDM
MEMTOP:
DW 0
EXMBASE:
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
IPSUPFL:
DB 0
OUTFLG:
DB 0
NUICH:
DB 0
IMFLG:
DB 0
MSUPFL:
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 ZEX RELOCATED CODE SEGMENT
;
END