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
Assembly Source File  |  2000-06-30  |  47KB  |  2,286 lines

  1. ;
  2. ;  PROGRAM:  ZEX
  3. ;  AUTHOR:  RICHARD CONN (DERIVED FROM EX, WHICH WAS WRITTEN BY SOMEONE ELSE)
  4. ;  VERSION:  3.1
  5. ;  DATE:  24 Oct 84
  6. ;  PREVIOUS VERSIONS:  3.0 (8 Mar 84)
  7. ;
  8. VERS    EQU    31
  9. Z3ENV    EQU    0F400H
  10.  
  11. ;
  12. ;   ZEX 3.1 -- Richard Conn
  13. ;    Does not require to be reassembled for a target system; Z3INS
  14. ;    installation is sufficient
  15. ;   ZEX 3.0 -- Derived from ZEX 1.3 for ZCPR3 by Richard Conn
  16. ;    Extensions to ZEX 1.3 are:
  17. ;        ZCPR3 Message Passing Employed
  18. ;        ZCPR3 Structure
  19. ;        Omitted Parameters Allowed
  20. ;        Print Suppression During FALSE IFs (^&)
  21. ;
  22. ;   ZEX 1.0 -- EX 1.2.1 implemented for ZCPR2 by Richard Conn
  23. ;        DATE:  12 NOV 82
  24. ;    Extensions to EX are:
  25. ;        Multiple command buffer is preserved, and any commands
  26. ;            following the ZEX command are executed after
  27. ;            the ZEX command file is completed (ZEX T;DIR
  28. ;            will execute commands in T.SUB and then run DIR)
  29. ;        ZCPR3 Search Path is following when looking for the
  30. ;            file specified to ZEX
  31. ;        Command File Type may be SUB or ZEX
  32. ;        Added ^* form to simply ring the bell
  33. ;        Added ^/ form to act like ^? but ring bell periodically
  34. ;        Added ^" form to allow user input in the middle of a
  35. ;            command file operation
  36. ;        Major rewrite of EX to improve readability and to impose
  37. ;            a structured organization on the code for maintenance
  38. ;            purposes
  39. ;        Major change in the abort system so that the multiple command
  40. ;            line buffer of ZCPR3 will be properly cleared on
  41. ;            abort; without this change, ZEX would crash the system
  42. ;            in attempting to abort out of the ^/ and ^? forms;
  43. ;            EX will probably always crash a ZCPR3 system with
  44. ;            multiple commands enabled if an abort from ^? is
  45. ;            attempted
  46. ;
  47. ;   EX12.ASM - An enhanced version of EXEC and EX.
  48. ;
  49. ;   START   05-09-82
  50. ;
  51. ;   DATE    08-11-82  *LAST MAJOR CHANGE
  52. ;
  53. ;   HISTORY:
  54. ;
  55. ;   ZEX 1.0 11-12-82  modify for use under ZCPR2; main change is to place
  56. ;            rest of multiple command line at end of SUB file
  57. ;
  58. ;   1.2.1   09-16-82  fix for MBASIC execution under EX 1.2 .
  59. ;
  60. ;   1.2     08-11-82  added '^:' EX runtime re-execute logic function,
  61. ;                '^?' EX runtime wait for carriage return,
  62. ;                logic to prevent input/EX buffer overlap,
  63. ;                logic to insure (Xsub Already Present),
  64. ;                logic to prevent EX runtime recursion loop,
  65. ;            and prompt character logic       [Larry Steeger]
  66. ;
  67. ;   1.1     08-06-82  added ';;' EX comment's support,
  68. ;                '^.' print suppression function,
  69. ;                '^<...^>' immediate display support,
  70. ;                '^#' EX message suppression function,
  71. ;                '^$' default parameter support,
  72. ;            and '^|' cr,lf generation function [Larry Steeger]
  73. ;
  74. ;   1.0     08-03-82  corrected $^ error and ^<lowercase> error [Larry Steeger]
  75. ;
  76. ;   ?        06-19-82  added missing TRUE and FALSE equates [Ron Fowler]
  77. ;
  78. ;   ?        05-17-82  corrected last cold boot no active message
  79. ;
  80.  
  81. ;
  82. ;    EX12.COM IS AN ENHANCEMENT OF EXEC.COM AND EX.COM
  83. ;
  84. ;    OPTIONS:
  85. ;
  86. ;    EX <subfile> <parameters> cr
  87. ;
  88. ;    EX cr
  89. ;
  90. ;     ^<?> WILL GIVE CONTROL CHARACTER <?>
  91. ;
  92. ;     | WILL BE CR
  93. ;
  94. ;     ^| WILL BE CR,LF
  95. ;
  96. ;     ^: WILL CAUSE ZEX TO RE-EXECUTE THE .SUB FILE FROM THE BEGINNING
  97. ;
  98. ;     ^? WILL CAUSE ZEX TO WAIT FOR A CARRIAGE RETURN
  99. ;        (^C WILL ABORT ZEX AT THIS POINT ALSO)
  100. ;
  101. ;     ^/ WILL CAUSE ZEX TO RING THE BELL AND WAIT FOR A CARRIAGE RETURN
  102. ;        (^C WILL ABORT ZEX AT THIS POINT ALSO)
  103. ;
  104. ;     ^* WILL CAUSE ZEX TO RING THE BELL
  105. ;
  106. ;     ^" WILL CAUSE ZEX TO STOP PROVIDING INPUT UNTIL THE ZCPR3 MESSAGE
  107. ;        CONTROLLING ZEX IS CHANGED TO PERMIT CONTINUATION
  108. ;
  109. ;     ^$ WILL CAUSE THE REST OF THE LINE TO BE TREATED AS A
  110. ;        SET OF DEFAULT PARAMETERS SEPARATED BY BLANKS TO BE
  111. ;        USED IF THE USER HAS NOT PROVIDED ONE ON ZEX'S COMMAND LINE.
  112. ;
  113. ;     ^# WILL TOGGLE PRINT SUPPRESSION OF ZEX MESSAGES
  114. ;
  115. ;     ^. WILL START PRINT SUPPRESSION OF ALL CHARACTERS
  116. ;        FROM .SUB FILE UNTIL A SUBSEQUENT ^. IS ENCOUNTERED
  117. ;
  118. ;     ^& WILL INSTRUCT ZEX TO SUPPRESS PRINT IF WITHIN A FALSE IF
  119. ;
  120. ;     ;; WILL INDICATE THAT THE ;; AND ALL CHARACTERS FOLLOWING IT
  121. ;        UNTIL A LF IS ENCOUNTERED ARE NOT INCLUDED IN ZEX'S
  122. ;        TEXT BUFFER
  123. ;        (I.E. A ZEX ONLY COMMENT)
  124. ;
  125. ;     ^<  WILL START IMMEDIATE DISPLAY OF CHARACTERS FROM
  126. ;        THE .SUB FILE UNTIL ^> IS ENCOUNTERED
  127. ;        (I.E. DISPLAY ONLY .SUB INPUT)
  128. ;
  129. ;     $<1-9> WILL REPLACE PARAMETER<1-9> IN TEXT FROM THE COMMAND LINE
  130. ;
  131. ;     $$ WILL GIVE $
  132. ;
  133. ;     $^ WILL GIVE ^
  134. ;
  135. ;     $| WILL GIVE |
  136. ;
  137. ;     |,cr,lf,1ah will eat last from | to end of buffer
  138. ;
  139. ;     ^C FROM CONSOLE WILL ABORT ZEX
  140. ;
  141.  
  142. FALSE    EQU    0
  143. TRUE    EQU    NOT FALSE
  144.  
  145. ;
  146. ;  OFFSETS TO ZCPR3 ENVIRONMENT DESCRIPTOR ELEMENTS
  147. ;
  148. EPOFF    EQU    9    ;EXTERNAL PATH DATA
  149. MCOFF    EQU    24    ;COMMAND LINE DATA
  150. Z3MOFF    EQU    34    ;MESSAGE BUFFER
  151.  
  152. ;
  153. ;  GENERAL EQUATES
  154. ;
  155. BELL    EQU    7
  156. CTRLZ    EQU    1AH    ;^Z
  157. DELAY    EQU    6000H    ;DELAY CONSTANT FOR TIMER LOOP
  158. BS    EQU    'H'-'@'    ;BACKSPACE
  159. CR    EQU    0DH
  160. LF    EQU    0AH
  161.  
  162. ;
  163. ;  ZEX MONITOR COMMAND BYTES
  164. ;
  165. PSUP    EQU    80H    ;^. PRINT SUPPRESS FLAG
  166. IMON    EQU    81H    ;^< IMMEDIATE MODE START
  167. IMOFF    EQU    82H    ;^> IMMEDIATE MODE STOP
  168. MSUP    EQU    83H    ;^# ZEX MESSAGE SUPPRESS FLAG
  169. CRWAIT    EQU    84H    ;^? ZEX RUNTIME WAIT FOR CR FLAG
  170. REXEC    EQU    85H    ;^: ZEX RUNTIME RE-EXECUTE FLAG
  171. CRBWAIT    EQU    86H    ;^/ ZEX RUNTIME RING BELL AND WAIT FOR CR FLAG
  172. RNG    EQU    87H    ;^* ZEX RUNTIME RING BELL
  173. UICH    EQU    88H    ;^" USER INPUT COMMAND CHAR SEQUENCE
  174. IPS    EQU    89H    ;^& FALSE IF PRINT SUPPRESS
  175. ;
  176. ;  CP/M CONSTANTS
  177. ;
  178. WARM    EQU    0
  179. BDISK    EQU    4
  180. BDOS    EQU    5
  181. DFCB    EQU    5CH
  182. BUFF    EQU    80H
  183. ;
  184. ;    NOTE: ZEX30.LIB IS CREATED BY THE ZEX30.ZEX GENERATION PROCESS
  185. ;
  186.     MACLIB    ZEX30
  187. ;
  188. $-PRINT
  189.     IF    ZEXBASE
  190. $+PRINT
  191. ;
  192. ;    START OF ZEX INITIATOR CODE SEGMENT
  193. ;
  194.     ORG    100H
  195. ;
  196. ; Environment Definition
  197. ;
  198.     if    z3env ne 0
  199. ;
  200. ; External ZCPR3 Environment Descriptor
  201. ;
  202.     jmp    start
  203.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  204.     db    1    ;External Environment Descriptor
  205. z3eadr:
  206.     dw    z3env
  207. start:
  208.     lhld    z3eadr    ;pt to ZCPR3 environment
  209. ;
  210.     else
  211. ;
  212. ; Internal ZCPR3 Environment Descriptor
  213. ;
  214.     MACLIB    SYSENV.LIB
  215. z3eadr:
  216.     jmp    start
  217.     SYSENV
  218. start:
  219.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  220.     endif
  221.  
  222. ;
  223. ; Start of Program -- Initialize ZCPR3 Environment
  224. ;
  225.     call    z3init    ;initialize the ZCPR3 Env
  226.     JMP    START0
  227. ;
  228. ;  INITIAL COMMAND LINE AREA
  229. ;
  230.     DB    0FFH    ;SIZE OF COMMAND LINE
  231. DBUFF    EQU    $
  232.     DB    0FFH    ;SIZE OF BUFFER
  233.     DS    100H    ;SPACE FOR COMMAND LINE
  234. ;
  235. ;  START OF ZEX
  236. ;
  237. START0:
  238.     NOP        ;REPLACED WITH RET TO PREVENT REENTRY
  239.     LDA    DFCB+1    ;CHECK FOR HELP REQUEST
  240.     CPI    '/'    ;HELP?
  241.     JZ    HELP
  242.     LXI    H,0
  243.     DAD    SP
  244.     SHLD    CCPSTK    ;CCP STACK PTR
  245.     LXI    SP,CCPSTK    ;USER STACK AREA
  246.     MVI    A,0C9H    ; (8080 RET)
  247.     STA    START    ;PREVENT RE-ENTRANCE BY ZCPR
  248.     LXI    H,BUFF    ;COPY INPUT LINE INTO DBUFF
  249.     LXI    D,DBUFF
  250.     MVI    B,128    ;SIZE OF BUFFER
  251.     CALL    MOVE
  252.     LXI    D,SIGNON    ;LOGO
  253.     CALL    PRINT
  254.     CALL    ZEXACTV    ;CHECK FOR RECURSION
  255.     CALL    ZRELOC    ;RELOCATE ZEX MODULE
  256.     CALL    ZPARMS    ;EXTRACT PARAMETERS FROM COMMAND LINE
  257.     LDA    DFCB+1    ;CHECK TO SEE IF SUB FILE PRESENT
  258.     CPI    ' '    ;<SP>=NO
  259.     PUSH    PSW    ;SAVE FLAG
  260.     CNZ    OPENSB    ;OPEN AND LOAD ZEX FILE IF PRESENT OR ABORT
  261.     POP    PSW    ;GET FLAG
  262.     CZ    INPUTSB    ;INPUT COMMANDS FROM USER
  263. ;
  264. ;  HL NOW POINTS TO BYTE AFTER LOADED TEXT
  265. ;
  266.     CALL    ZMCL    ;STORE REST OF MULTIPLE COMMAND LINE
  267.     CALL    ZLINES    ;COPY AND PROCESS COMMAND LINES
  268. ;
  269. ;  SET UP FOR ZEX EXECUTION AND RUN; HL PTS TO BOTTOM OF DATA AREA
  270. ;
  271.     PUSH    H    ;SAVE PTR TO END OF DATA
  272.     LHLD    RELSTRT    ;GET PTR TO START OF ZEX
  273.     SHLD    GOADR    ;SET ADDRESS TO RUN TO
  274.     DCX    H    ;PT TO START OF DATA AREA
  275.     MVI    B,09H    ;MESSAGE OFFSET
  276.     CALL    MSHLD    ;STORE HL THERE (NEXT CHAR FOR ZEX)
  277.     MVI    B,0BH    ;MESSAGE OFFSET
  278.     CALL    MSHLD    ;STORE HL THERE (FIRST CHAR FOR ZEX)
  279.     MVI    A,0FFH    ;SET ZEX RUNNING FLAG
  280.     MVI    B,08H    ;MESSAGE OFFSET
  281.     CALL    MSTA    ;STORE A THERE (ZEX IS RUNNING)
  282.     POP    H    ;HL IS PTR TO END OF DATA
  283.     MOV    M,A    ;SET UP END OF DATA
  284.     DCX    H
  285.     LDA    BDOS+2    ;SET UP BDOS JUMP TO PROTECT DATA
  286.     MOV    M,A
  287.     DCX    H
  288.     LDA    BDOS+1
  289.     MOV    M,A
  290.     DCX    H
  291.     MVI    M,JMP
  292.     SHLD    BDOS+1    ;SET NEW BDOS ADDRESS
  293.     LXI    H,0    ;ASSUME NO MULTIPLE COMMANDS
  294.     LDA    MCAVAIL    ;GET FLAG
  295.     ORA    A    ;0=NONE
  296.     JZ    GOTOZEX    ;NO MULTIPLE COMMANDS, SO BC=0
  297.     LHLD    MCADR    ;GET ADDRESS OF MULTIPLE COMMAND BUFFER
  298. ;
  299. ;  ZEX MONITOR ENTRY PARAMETERS --
  300. ;    HL    ADDRESS OF MULTIPLE COMMAND BUFFER OR 0 IF NONE
  301. ;
  302. GOTOZEX:
  303.     XCHG        ;SAVE HL
  304.     LHLD    Z3MSGA    ;GET ADDRESS OF MESSAGES ...
  305.     XCHG        ; ... IN DE
  306.  
  307. GOADR    EQU    $+1
  308.     JMP    $
  309.  
  310. ;
  311. ; INIT ZCPR3 ENVIRONMENT
  312. ;
  313. Z3INIT:
  314.     PUSH    H    ;SAVE PTR TO ENVIRONMENT
  315.     PUSH    H
  316.     LXI    D,Z3MOFF    ;OFFSET TO MESSAGE BUFFER
  317.     DAD    D
  318.     MOV    A,M    ;GET LOW
  319.     INX    H
  320.     MOV    H,M    ;GET HIGH
  321.     MOV    L,A    ;HL IS ADDRESS OF MESSAGES
  322.     SHLD    Z3MSGA    ;SAVE ADDRESS
  323.     POP    H
  324.     LXI    D,MCOFF    ;OFFSET TO CL DATA
  325.     DAD    D
  326.     MOV    E,M    ;GET CL ADDRESS
  327.     INX    H
  328.     MOV    D,M
  329.     INX    H    ;GET CL SIZE
  330.     MOV    A,M
  331.     ORA    D    ;IF ALL THREE VALUES ARE 0, THEN NO COMMAND LINE
  332.     ORA    E
  333.     STA    MCAVAIL    ;SET AVAILABLE FLAG
  334.     XCHG        ;HL PTS TO CL
  335.     SHLD    MCADR
  336.     POP    H    ;GET PTR TO ENVIRONMENT
  337.     LXI    D,EPOFF    ;OFFSET TO EXTERNAL PATH DATA
  338.     DAD    D
  339.     MOV    E,M    ;GET EXTERNAL PATH ADDRESS
  340.     INX    H
  341.     MOV    D,M
  342.     MOV    A,D    ;CHECK FOR ANY
  343.     ORA    E
  344.     STA    EPAVAIL    ;SET AVAILABLE FLAG
  345.     XCHG
  346.     SHLD    EPADR    ;SET ADDRESS
  347.     RET
  348. ;
  349. ; Z3INIT BUFFERS
  350. ;
  351. INTPATH:        ;INTERNAL PATH
  352.     DB    1,0    ;DISK A, USER 0
  353.     DB    0,0    ;END OF PATH
  354. Z3MSGA:            ;ADDRESS OF MESSAGES
  355.     DW    0
  356. MCAVAIL:        ;MULTIPLE COMMAND LINE DATA
  357.     DB    0
  358. MCADR:
  359.     DW    0
  360. EPAVAIL:        ;EXTERNAL PATH DATA
  361.     DB    0
  362. EPADR:
  363.     DW    0
  364.  
  365. ;
  366. ;  PRINT HELP MESSAGE FOR ZEX
  367. ;
  368. HELP:
  369.     LXI    D,SIGNON    ;PRINT BANNER
  370.     CALL    PRINT
  371.     LXI    H,HMSG    ;PRINT MESSAGE
  372.     CALL    HPRINT
  373.     MVI    C,1    ;GET CHAR
  374.     CALL    BDOS
  375.     CPI    'C'-'@'    ;^C?
  376.     RZ
  377.     LXI    D,CRLFS
  378.     CALL    PRINT
  379.     LXI    D,SIGNON
  380.     CALL    PRINT
  381.     LXI    H,HMSG1
  382. HPRINT:
  383.     MOV    A,M    ;GET CHAR
  384.     ORA    A    ;DONE?
  385.     RZ
  386.     INX    H    ;PT TO NEXT
  387.     PUSH    H    ;SAVE PTR
  388.     MOV    E,A    ;CHAR IN E
  389.     MVI    C,2    ;CONSOLE OUTPUT
  390.     CALL    BDOS
  391.     POP    H    ;GET PTR
  392.     JMP    HPRINT
  393.  
  394. HMSG:
  395.     DB    CR,LF,'ZEX Syntax:'
  396.     DB    CR,LF,'        ZEX <zexfile> <parameters>'
  397.     DB    CR,LF,'or'
  398.     DB    CR,LF,'        ZEX'
  399.     DB    CR,LF
  400.     DB    CR,LF,'The first form executes the indicated command file'
  401.     DB    CR,LF,'(<subfile> may be of type ZEX or SUB, and if a ZEX and'
  402.     DB    CR,LF,'SUB both exist, the ZEX file is used), passing to it'
  403.     DB    CR,LF,'the parameters, similar to the way SUBMIT is used.'
  404.     DB    CR,LF
  405.     DB    CR,LF,'The second form allows the user to enter commands.'
  406.     DB    CR,LF,'ZEX presents the user with a prompt like "n:", where'
  407.     DB    CR,LF,'n is a line number, and the user may type in a command'
  408.     DB    CR,LF,'line.  Input is terminated by simply striking the'
  409.     DB    CR,LF,'RETURN key (empty input line).'
  410.     DB    CR,LF
  411.     DB    CR,LF,'ZEX can be aborted by ^C from console.'
  412.     DB    CR,LF
  413.     DB    CR,LF,'    Strike Any Key to Continue, ^C to Abort - ',0
  414.  
  415. HMSG1:
  416.     DB    CR,LF
  417.     DB    CR,LF,'ZEX supports an enhanced command processing facility'
  418.     DB    CR,LF,'which recognizes the following commands.  These may be'
  419.     DB    CR,LF,'embedded in the text of the command file or user'
  420.     DB    CR,LF,'input and will be executed after processing begins.'
  421.     DB    CR,LF
  422.     DB    CR,LF,'    Cmd Meaning        Cmd Meaning'
  423.     DB    CR,LF,'     |  insert <CR>        ^|  insert <CR> <LF>'
  424.     DB    CR,LF,'    ^:  rerun command file    ^.  suppress print of chars'
  425.     DB    CR,LF,'    ^#  toggle ZEX msgs    ^$  define default params'
  426.     DB    CR,LF,'    ^?  wait for user <CR>    ^/  ring and wait for <CR>'
  427.     DB    CR,LF,'    ^*  ring bell        ^"  allow user input'
  428.     DB    CR,LF,'    ^<  display chars only    ^>  stop display'
  429.     DB    CR,LF,'    ;;  ZEX comment        $n  1<=n<=9 for param'
  430.     DB    CR,LF,'    $$  =$            $^  =^'
  431.     DB    CR,LF,'    $|  =|            ^c  insert ctrl char c'
  432.     DB    CR,LF,CR,LF,0
  433.  
  434.  
  435. ;
  436. ;  RELOCATE ZEX MODULE INTO HIGH MEMORY JUST BELOW ZCPR3
  437. ;
  438. ZRELOC:
  439.     LHLD    RELOCL    ;GET RELOC PROGRAM LENGTH
  440.     MOV    B,H    ;BC=HL=RELOC PROGRAM LENGTH
  441.     MOV    C,L
  442.     PUSH    B    ;SAVE LENGTH FOR FUTURE USE
  443.     LHLD    BDOS+1    ;GET BASE
  444.     LXI    D,-806H ;GET BEFORE CCP
  445.     DAD    D
  446.     MOV    A,L    ;SUBTRACT RELOC LENGTH
  447.     SUB    C
  448.     MOV    E,A
  449.     MOV    A,H
  450.     SBB    B
  451.     MOV    D,A
  452.     PUSH    D    ;SAVE NEW TOP/START TO MOVE TO
  453.     LXI    H,BEGREL    ;START OF MOVE
  454. OMOVE:
  455.     MOV    A,B
  456.     ORA    C
  457.     JZ    MOVEND
  458.     DCX    B
  459.     MOV    A,M
  460.     STAX    D
  461.     INX    D
  462.     INX    H
  463.     JMP    OMOVE
  464. ;
  465. MOVEND:
  466.     POP    D    ;GET START OF MOVED PROGRAM
  467.     POP    B    ;LENGTH OF MOVE PROGRAM
  468.     PUSH    D    ;SAVE PTR TO START OF PROGRAM
  469.     PUSH    H    ;START OF BIT MAP
  470.     MOV    H,D    ;MSB OFFSET
  471.     MOV    L,E    ;LSB OFFSET
  472. OFFLUP:
  473.     MOV    A,B    ;TEST LENGTH
  474.     ORA    C    ;IF 0
  475.     JZ    GOTO    ;JUMP TO RELOCATED PROGRAM
  476.     DCX    B    ;DECREMENT COUNT
  477.     LDA    COUNT
  478.     INR    A
  479.     STA    COUNT
  480.     ANI    07H
  481.     JNZ    OFFBIT    ;NO
  482.     XTHL        ;YES, GET BIT MAP
  483.     MOV    A,M    ;GET NEXT BYTE
  484.     INX    H    ;INCREMENT BIT MAP POINTER
  485.     XTHL        ;SAVE FOR LATER
  486.     STA    BITMAP    ;KEEP BIT OFFSET
  487. OFFBIT:
  488.     LDA    BITMAP
  489.     RAL        ;TEST FOR OFFSET
  490.     STA    BITMAP    ;SAVE NEW BYTE
  491.     JNC    NOFSET    ;NO
  492.     DCX    D    ;GET BACK TO LSB
  493.     LDAX    D
  494.     ADD    L
  495.     STAX    D
  496.     INX    D    ;MSB
  497.     LDAX    D    ;YES
  498.     ADC    H    ;ADD IN OFFSET
  499.     STAX    D    ;PUT IN MOVED PLACE
  500. NOFSET:
  501.     INX    D    ;INCREMENT MOVED POINTER
  502.     JMP    OFFLUP    ;CONTINUE WITH RELOCATE
  503. ;
  504. GOTO:
  505.     POP    D    ;RESTORE STACK
  506.     POP    H    ;PT TO FIRST BYTE OF PROGRAM
  507.     SHLD    RELSTRT    ;SAVE PTR
  508.     DCX    H    ;RELOCATE PROGRAM-1
  509.     SHLD    OUTBUF    ;SAVE PTR TO BYTE IN FRONT OF RELOCATED PROGRAM
  510.     RET
  511. ;
  512. ;  GET PARAMETERS FROM COMMAND LINE
  513. ;    TERMINATE EACH PARAMETER WITH A BINARY ZERO, AND SET POINTERS
  514. ;    TO EACH PARAMETER
  515. ;
  516. ZPARMS:
  517.     LXI    D,DBUFF    ;TERMINATE COMMAND LINE WITH CR
  518.     LDAX    D    ;GET CHAR COUNT
  519.     INX    D    ;PT TO FIRST CHAR
  520.     PUSH    D
  521.     MOV    L,A    ;HL = NUMBER OF CHARS IN LINE
  522.     MVI    H,0
  523.     DAD    D    ;PT TO AFTER LAST CHAR
  524.     MVI    M,CR    ;STORE <CR>
  525.     LXI    H,PRMDMY    ;START AT DUMMY PARAMETER FOR .SUB FILE SPEC
  526.     PUSH    H
  527.     LXI    B,PRMPNL+2
  528.     XRA    A
  529.     CALL    FILL    ;CLEAR PTR AREA
  530.     POP    H    ;GET PTR TO POINTER FOR PARAMETER 0
  531.     POP    D    ;GET PTR TO FIRST CHAR IN LINE
  532.     MVI    A,(PRMPNL/2)+1    ;NUMBER OF PARAMETERS POSSIBLE, MAX
  533.     STA    PRMMAX    ;HIGHEST PARAMETER # + 1 for .SUB SPEC
  534. ;
  535. ;  PARAMETER EXTRACTION ROUTINE; HL PTS TO FIRST PARAM PTR, DE PTS TO LINE
  536. ;
  537. PARMS:
  538.     MVI    B,0    ;CLEAR PARAMETER COUNTER
  539.     XCHG
  540.     SHLD    ERRLNE    ;SAVE IN CASE OF ERROR
  541.     XCHG
  542. ;
  543. PARMSL:
  544.     LDAX    D    ;IGNORE LEADING SPACES
  545.     INX    D
  546.     CPI    CR
  547.     JZ    ENDLNE
  548.     CPI    ' '
  549.     JZ    PARMSL
  550.     DCX    D    ;BACK UP TO 1ST CHAR
  551.     MOV    M,E    ;SAVE ADDRESS IN TABLE
  552.     INX    H
  553.     MOV    M,D
  554.     INX    H
  555.     INR    B    ;COUNT+1
  556.     LDA    PRMMAX
  557.     CMP    B
  558.     JC    PRMTOO    ;TOO MANY ARGUMENTS
  559. ;
  560. ENDPRM:
  561.     LDAX    D    ;GO TO END OF PARAMETER
  562.     INX    D
  563.     CPI    CR
  564.     JZ    ENDLNE
  565.     CPI    ' '    ;SKIP UNTIL <SP>
  566.     JNZ    ENDPRM
  567.     XRA    A    ;A=0 TO TERMINATE PARAM
  568.     DCX    D    ;PT TO <SP> FOLLOWING PARAM
  569.     STAX    D    ;TERMINATE PARAMETER
  570.     INX    D    ;PT TO CHAR AFTER <SP>
  571.     JMP    PARMSL    ;IGNORE SPACES BETWEEN PARAMETERS
  572. ENDLNE:
  573.     XRA    A    ;STORE ZERO AFTER LAST PARAMETER
  574.     DCX    D    ;PT TO CR
  575.     STAX    D    ;TERMINATE LAST PARAMETER
  576.     INX    D    ;PT TO AFTER LAST PARAM
  577.     MVI    A,CR    ;STORE ENDING CR
  578.     STAX    D
  579.     RET
  580. ;
  581. ;  INPUT COMMAND LINES FROM USER
  582. ;
  583. INPUTSB:
  584.     LXI    H,0
  585.     SHLD    LINES    ;START LINE COUNTER
  586.     MVI    A,0FFH    ;SET BUFFER LENGTH
  587.     STA    DBUFF-1
  588.     LXI    H,BEGREL    ;SET UP OUTPUT BUFFER
  589.     SHLD    INBUF
  590. GETLIN:
  591.     CALL    CRLF
  592.     LHLD    LINES
  593.     INX    H
  594.     SHLD    LINES
  595.     CALL    DECOUT    ;PRINT LINE #
  596.     MVI    E,':'    ;GET PROMPT
  597.     CALL    OUTCHR
  598.     MVI    E,' '
  599.     CALL    OUTCHR
  600.     LXI    D,DBUFF-1
  601.     MVI    C,10    ;READ CONSOLE BUFFER
  602.     CALL    BDOS
  603.     LXI    D,DBUFF
  604.     LDAX    D    ;GET LENGTH
  605.     MOV    B,A
  606.     INX    D
  607.     LHLD    INBUF    ;GET INPUT POINTER
  608.     ORA    A    ;SEE IF END
  609.     RZ        ;DONE WITH INPUT
  610.     XCHG
  611.     CALL    MOVE    ;MOVE TO INPUT BUFFER
  612.     XCHG
  613.     MVI    M,CR
  614.     INX    H
  615.     MVI    M,LF
  616.     INX    H
  617.     SHLD    INBUF
  618.     JMP    GETLIN
  619. ;
  620. ;  OPEN AND LOAD SUB FILE
  621. ;
  622. OPENSB:
  623.     CALL    PUTUD    ;SAVE USER/DISK
  624. ;
  625. ;  SET UP TO READ ZEX FILE
  626. ;
  627.     LXI    D,DFCB+9
  628.     LXI    H,ZEXNAM    ;MOVE 'SUB' TO DFCB FILE TYPE
  629.     MVI    B,3
  630.     CALL    MOVE
  631.     XRA    A    ;ZERO CR FIELD
  632.     STA    DFCB+32
  633.     LXI    D,BUFF    ;SET DMA ADDRESS
  634.     MVI    C,26    ;SET DMA
  635.     CALL    BDOS
  636.     LXI    D,DFCB
  637.     LXI    H,INTPATH    ;PT TO INTERNAL PATH
  638.     LDA    EPAVAIL    ;EXTERNAL PATHS AVAILABLE?
  639.     ORA    A    ;0=NO
  640.     JZ    OSB1    ;USE INTERNAL PATH
  641.     LHLD    EPADR    ;PT TO EXTERNAL PATH
  642. OSB1:
  643.     PUSH    H    ;SAVE PATH PTR
  644.     CALL    FNDFILE    ;LOOK FOR FILE ALONG PATH AND SAY IF IT IS FOUND
  645.     POP    H    ;GET PATH PTR
  646.     JNZ    READSB
  647. ;
  648. ;  ZEX FILE NOT FOUND -- SET UP TO READ SUB FILE
  649. ;
  650.     PUSH    H    ;SAVE PATH PTR
  651.     CALL    GETUD    ;RESTORE USER/DISK
  652.     LXI    D,DFCB+9    ;SET TYPE TO SUB
  653.     LXI    H,SUBNAM
  654.     MVI    B,3
  655.     CALL    MOVE
  656.     XRA    A    ;ZERO CR FIELD
  657.     STA    DFCB+32
  658.     POP    H    ;PT TO PATH
  659.     LXI    D,DFCB    ;PT TO FCB
  660.     CALL    FNDFILE    ;LOOK FOR FILE
  661.     JNZ    READSB
  662. RSBERR:
  663.     CALL    GETUD    ;RESTORE USER/DISK
  664.     LXI    H,NOSBF2
  665.     LXI    D,DFCB+1
  666.     MVI    B,8    ;NAME LENGTH
  667.     CALL    MOVEFN    ;MOVE FILE NAME
  668.     MVI    B,3    ;TYPE LENGTH
  669.     MVI    M,'.'
  670.     INX    H
  671.     LXI    D,DFCB+9;FILE TYPE POINTER
  672.     CALL    MOVEFN    ;MOVE FILE TYPE
  673.     MVI    M,'$'    ;END TERMINATER
  674.     JMP    NOSUB
  675. *
  676. *  FNDFILE -- LOOK FOR FILE ALONG ZCPR3 PATH
  677. *  INPUT PARAMETERS:  HL = BASE ADDRESS OF PATH, DE = PTR TO FCB OF FILE
  678. *  OUTPUT PARAMETERS:  A=0 AND ZERO FLAG SET IF NOT FOUND, NZ IF FOUND
  679. *
  680. FNDFILE:
  681.     SHLD    PATH        ;SAVE PATH BASE ADDRESS
  682.     MVI    C,17        ;SEARCH FOR FIRST
  683.     CALL    BENTRY        ;LOOK FOR FILE
  684.     INR    A        ;SET FLAG
  685.     JNZ    FF5        ;FOUND IT -- RETURN FOUND FLAG
  686.     XCHG            ;HL=FCB PTR
  687.     SHLD    FCBPTR        ;SAVE IT
  688.     LHLD    PATH        ;PT TO PATH FOR FAILURE POSSIBILITY
  689.     MVI    C,32        ;GET CURRENT USER
  690.     MVI    E,0FFH
  691.     CALL    BENTRY
  692.     STA    TMPUSR        ;SAVE IT FOR LATER
  693. ;
  694. ; MAIN SEARCH LOOP
  695. ;
  696. FF1:
  697.     MOV    A,M        ;GET DRIVE
  698.     ANI    7FH        ;MASK MSB
  699.     ORA    A        ;0=DONE=COMMAND NOT FOUND
  700.     JNZ    FF2        ;NO ERROR ABORT?
  701. ;
  702. ; FILE NOT FOUND ERROR
  703. ;
  704.     XRA    A        ;ZERO FLAG MEANS NOT FOUND
  705.     RET
  706. ;
  707. ; LOOK FOR COMMAND IN DIRECTORY PTED TO BY HL; DRIVE IN A
  708. ;
  709. FF2:
  710.     MOV    E,A        ;DISK IN E
  711.     CPI    '$'        ;CURRENT DISK?
  712.     JNZ    FF3        ;SKIP DEFAULT DRIVE SELECTION IF SO
  713.     LDA    BDISK        ;GET DEFAULT USER/DISK
  714.     ANI    0FH        ;MASK FOR DEFAULT DISK
  715.     INR    A        ;PREP FOR FOLLOWING DCR A
  716.     MOV    E,A        ;DISK NUMBER IN E
  717. FF3:
  718.     DCR    E        ;ADJUST PATH 1 TO 0 FOR A, ETC
  719.     MVI    C,14        ;SELECT DISK FCT
  720.     CALL    BENTRY        ;SELECT DRIVE
  721.     INX    H        ;PT TO USER NUMBER
  722.     MOV    A,M        ;GET USER NUMBER
  723.     ANI    7FH        ;MASK OUT MSB
  724.     INX    H        ;PT TO NEXT ENTRY IN PATH
  725.     PUSH    H        ;SAVE PTR
  726.     MOV    E,A        ;SAVE IN E
  727.     CPI    '$'        ;MATCH?
  728.     JNZ    FF4        ;DO NOT SELECT CURRENT USER IF SO
  729.     LDA    TMPUSR        ;GET ORIGINAL USER NUMBER
  730.     MOV    E,A        ;SELECT USER
  731. FF4:
  732.     MVI    C,32
  733.     CALL    BENTRY
  734.     LHLD    FCBPTR        ;GET PTR TO FCB
  735.     XCHG            ;... IN DE
  736.     MVI    C,17        ;SEARCH FOR FIRST
  737.     CALL    BENTRY        ;LOOK FOR FILE
  738.     POP    H        ;GET PTR TO NEXT PATH ENTRY
  739.     INR    A        ;SET FLAG
  740.     JZ    FF1        ;CONTINUE PATH SEARCH IF SEARCH FAILED
  741. ;
  742. ; FILE FOUND -- PERFORM SYSTEM TEST AND PROCEED IF APPROVED
  743. ;
  744. FF5:
  745.     MVI    A,0FFH        ;SET OK RETURN
  746.     ORA    A
  747.     RET
  748.  
  749. ;
  750. ;  BDOS ROUTINE
  751. ;
  752. BENTRY:
  753.     PUSH    H    ;SAVE REGS
  754.     PUSH    D
  755.     PUSH    B
  756.     CALL    BDOS
  757.     POP    B    ;GET REGS
  758.     POP    D
  759.     POP    H
  760.     RET
  761.  
  762. * BUFFERS
  763. FCBPTR:
  764.     DS    2    ;POINTER TO FCB FOR FILE SEARCH
  765. TMPUSR:
  766.     DS    1    ;CURRENT USER NUMBER
  767. PATH:
  768.     DS    2    ;BASE ADDRESS OF PATH
  769. ;
  770. ;  PUTUD -- SAVE AWAY CURRENT USER/DISK
  771. ;  GETUD -- RESTORE CURRENT USER/DISK
  772. ;
  773. PUTUD:
  774.     MVI    E,0FFH    ;GET CURRENT USER
  775.     MVI    C,32    ;BDOS
  776.     CALL    BDOS
  777.     STA    CUSER    ;SAVE CURRENT USER AWAY
  778.     MVI    C,25    ;GET CURRENT DISK
  779.     CALL    BDOS
  780.     STA    CDISK
  781.     RET
  782. GETUD:
  783.     LDA    CDISK    ;GET CURRENT DISK
  784.     MOV    E,A    ;... IN E
  785.     MVI    C,14    ;SELECT DISK
  786.     CALL    BDOS
  787.     LDA    CUSER    ;GET CURRENT USER
  788.     MOV    E,A    ;... IN E
  789.     MVI    C,32    ;SELECT USER
  790.     CALL    BDOS
  791.     RET
  792. CDISK:
  793.     DS    1    ;CURRENT DISK NUMBER
  794. CUSER:
  795.     DS    1    ;CURRENT USER NUMBER
  796. ;
  797. ;  OPEN AND READ SUB FILE
  798. ;
  799. READSB:
  800.     MVI    C,15    ;OPEN FILE
  801.     CALL    BDOS    ;BDOS
  802.     INR    A    ;ERROR?
  803.     JZ    RSBERR
  804. ;
  805. ;  READ IN AND STORE SUB FILE
  806. ;
  807. READTX:
  808.     LHLD    INBUF    ;GET PTR TO NEXT BYTE
  809.     XCHG        ;SET PTR IN DE
  810.     LXI    H,80H    ;GET SECTOR OFFSET
  811.     DAD    D    ;HL PTS TO FOLLOWING BLOCK TO BE READ, DE PTS TO
  812.     SHLD    INBUF    ;  BLOCK TO READ; SAVE PTR TO FOLLOWING BLOCK
  813.     MVI    C,26    ;SET DMA ADDRESS
  814.     CALL    BDOS
  815.     LXI    D,DFCB
  816.     MVI    C,20    ;READ SEQUENTIAL
  817.     CALL    BDOS
  818.     ORA    A
  819.     JZ    READTX    ;READ COMPLETE .SUB FILE
  820.     CALL    GETUD    ;RESTORE CURRENT USER/DISK
  821.     LHLD    INBUF    ;MAKE SURE BUFFER'S TERMINATED
  822.     LXI    D,-100H    ;PT TO FIRST BYTE OF LAST BLOCK READ
  823.     DAD    D
  824.     MVI    B,80H    ;LOOK AT AT MOST 80H BYTES
  825. SKIP1A:
  826.     MOV    A,M    ;GET BYTE
  827.     CPI    CTRLZ    ;EOF?
  828.     JZ    SKIP1B
  829.     INX    H    ;PT TO NEXT
  830.     DCR    B    ;COUNT DOWN
  831.     JNZ    SKIP1A
  832. ;  HL NOW POINTS TO AFTER LAST VALID CHAR IN FILE
  833. SKIP1B:
  834.     SHLD    INBUF    ;SET PTR
  835.     RET        ;DONE WITH NO ERROR
  836.  
  837. ;
  838. ;  THIS PART OF THE CODE STORES THE REST OF THE COMMAND LINE AS PART OF THE
  839. ;  COMMAND FILE FOR ZCPR3; ON ENTRY, HL PTS TO NEXT AVAILABLE BYTE
  840. ;
  841. ZMCL:
  842.     XCHG        ;BUFFER PTED TO BY DE
  843.     LHLD    MCADR    ;GET BASE ADDRESS OF MULTIPLE COMMAND LINE
  844.     MOV    A,M    ;GET LOW
  845.     INX    H
  846.     MOV    H,M    ;GET HIGH
  847.     MOV    L,A    ;HL PTS TO NEXT CHAR IN MULTIPLE COMMAND LINE
  848.     XCHG        ;DE PTS TO NEXT CHAR IN COMMAND LINE, HL PTS TO BUF END
  849.     LDA    MCAVAIL    ;MULTIPLE COMMANDS ENABLED?
  850.     ORA    A    ;0=NO
  851.     JZ    ENDSTR    ;TERMINATE FILE; HL PTS TO NEXT BYTE
  852.     LDAX    D    ;GET FIRST BYTE
  853.     MOV    B,A    ;SAVE FIRST BYTE IN B
  854.     XRA    A    ;A=0
  855.     STAX    D    ;CLEAR COMMAND LINE
  856.     INX    D    ;PT TO NEXT BYTE
  857.     MOV    A,B    ;GET FIRST BYTE
  858.     CPI    ';'    ;SEPARATION CHAR?
  859.     JNZ    CMCMD1    ;PROCESS IF NOT
  860. ;
  861. ;  LOOP TO STORE REST OF MULTIPLE COMMAND LINE INTO LOADED FILE
  862. ;
  863. CMCMD:
  864.     LDAX    D    ;GET BYTE FROM LINE
  865. CMCMD1:
  866.     ORA    A    ;EOL IF ZERO
  867.     JZ    CMEND    ;READ IN FILE; HL PTS TO NEXT AVAILABLE BYTE
  868.     MOV    M,A    ;STORE BYTE
  869.     INX    H    ;PT TO NEXT
  870.     INX    D
  871.     JMP    CMCMD
  872. CMEND:
  873.     MVI    M,CR    ;STORE <CR> <LF>
  874.     INX    H
  875.     MVI    M,LF
  876.     INX    H    ;PT TO NEXT AVAILABLE BYTE
  877. ;
  878. ;  MARK END OF BUFFER AND CONTINUE
  879. ;
  880. ENDSTR:
  881.     MVI    M,1AH    ;EOF CHARACTER
  882.     SHLD    ENDBUF    ;EOB ADDRESS
  883.     MOV    A,L
  884.     SUI    LOW BEGREL+1    ;SEE IF BUFFER'S EMPTY
  885.     MOV    A,H
  886.     SBI    HIGH BEGREL
  887.     JC    BUFLOW
  888.     RET
  889. ;
  890. ;  COPY AND PROCESS COMMAND LINES, PLACING FINAL COMMAND LINE FORM UNDER ZEX
  891. ;    RETURN WITH HL PTING TO NEXT AVAILABLE BYTE IN MEMORY BUFFER UNDER ZEX
  892. ;
  893. ZLINES:
  894.     XRA    A
  895.     STA    IMFLG1
  896.     STA    IMFLG2
  897.     STA    PRTFLG
  898.     STA    OUTCNT
  899.     LXI    H,1
  900.     SHLD    LINES    ;SET LINE COUNT
  901.     LHLD    OUTBUF    ;PT TO BYTE JUST BELOW LOADED ZEX
  902.     SHLD    OUTLNE
  903.     SHLD    BUFSTR
  904.     LXI    D,BEGREL    ;PT TO FIRST BYTE OF COMMAND BUFFER
  905. ;
  906. ;  MAIN COPY LOOP TO COPY BUFFER AT BEGREL TO JUST UNDER ZEX WITH PROCESSING
  907. ;
  908. MOVSTR:
  909.     LDAX    D    ;GET NEXT COMMAND BYTE
  910.     INX    D    ;PT TO FOLLOWING
  911.     ANI    7FH    ;MAKE SURE NO PARITY
  912.     CPI    LF    ;NEW LINE?
  913.     JNZ    MOVST0
  914. ;
  915. ;  NEW LINE -- DON'T STORE <LF> AND INCREMENT LINE COUNT
  916. ;
  917. MOVSTX:
  918.     CALL    INCR    ;INCREMENT LINE COUNT
  919.     JMP    MOVSTR    ;CONTINUE
  920. ;
  921. ;  BEGIN CHARACTER PROCESSING
  922. ;    A CONTAINS CHAR, DE PTS TO BYTE AFTER CHAR, HL PTS TO NEXT BUFFER POS
  923. ;
  924. MOVST0:
  925.     CPI    1AH    ;END OF INPUT?
  926.     RZ        ;DONE IF SO
  927.     CPI    '|'    ;CARRIAGE RETURN?
  928.     JNZ    MOVST1    ;NOPE
  929. ;
  930. ;  PROCESS CARRIAGE RETURN FORM (|)
  931. ;
  932.     PUSH    D    ;SAVE OLD POINTER
  933.     INX    D    ;LOOK FOR EOF AFTER | (PT TO LF)
  934.     INX    D    ;PT TO POSSIBLE EOF
  935.     LDAX    D    ;GET PRESENT LOCATION+2
  936.     POP    D    ;GET OLD POINTER
  937.     CPI    1AH    ;END OF BUFFER
  938.     RZ        ;END, SO NO FOLLOWING <CR>
  939.     MVI    A,CR    ;MAKE CHAR A <CR>
  940.     CALL    INCR    ;INCREMENT LINES FOR ERRORS
  941.     JMP    MOVST4    ;STORE <CR> IN A
  942. ;
  943. ;  CHECK FOR NON-CR FORMS
  944. ;    AT THIS POINT, DE PTS TO NEXT CHAR IN LINE AND HL PTS TO NEXT
  945. ;    BYTE IN BUFFER (MOVING DOWN)
  946. ;
  947. MOVST1:
  948.     MOV    C,A    ;SAVE CHAR IN C
  949.     LDA    IMFLG1
  950.     CPI    IMON    ;IMMEDIATE MODE ON ?
  951.     MOV    A,C    ;GET CHAR BACK
  952.     JZ    MOVST2    ;YES..SKIP ZEX COMMENT PROCESSING
  953.     CPI    ';'    ;FIRST ';'?
  954.     JZ    EXCOMM    ;PROCESS POSSIBLE ZEX COMMENT
  955. MOVST2:
  956.     CPI    '^'    ;CONTROL CHAR?
  957.     JZ    MOVST5    ;CONVERT CONTROL CHARACTERS
  958.     CPI    '$'    ;PARAMETER OR CONTROL CHAR?
  959.     CZ    GTPARM    ;SUBSTITUTE COMMAND PARAMETER OR CONTROL CHAR.
  960. MOVST3:
  961.     STA    LCHR    ;SAVE LAST CHAR ENTERED
  962.     CPI    CR    ;=CR?
  963.     JNZ    MOVST4
  964.     MOV    C,A    ;SAVE CHAR TEMPORARILY
  965.     LDA    OUTCNT    ;GET CHAR OUTPUT FLAG
  966.     ORA    A    ;ANY CHAR?
  967.     MOV    A,C
  968.     JZ    MOVSTR    ;NO..USE INPUT CR ONLY IF OTHER NON-CONTROL
  969. ;                 CHARACTERS IN CURRENT LINE
  970. ;  PLACE CHAR IN BUFFER
  971. ;    CHAR IN A, HL PTS TO BUFFER LOC
  972. ;
  973. MOVST4:
  974.     CALL    CHRSTR    ;ADD TO BUFFER
  975.     CALL    CNTINC    ;INCREMENT COUNT
  976.     JMP    MOVSTR
  977. ;
  978. ;  PREFIX WAS AN UPARROW (^), SO PROCESS CONTROL CHARS
  979. ;
  980. MOVST5:
  981.     CALL    GETCMD    ;VALIDATE CONTROL CHARACTERS
  982.     CPI    ':'
  983.     JZ    REXC    ;RE-EXECUTE
  984.     CPI    '?'
  985.     JZ    GCRW    ;CR WAIT
  986.     CPI    '/'
  987.     JZ    GCRBW    ;RING BELL AND WAIT FOR <CR>
  988.     CPI    '"'
  989.     JZ    UISET    ;USER INPUT
  990.     CPI    '*'
  991.     JZ    GRNG    ;CONTINUALLY RING BELL WHILE WAITING FOR <CR>
  992.     CPI    '|'
  993.     JZ    GCRLF    ;CR,LF GENERATION
  994.     CPI    '$'
  995.     JZ    PRMDEF    ;DEFAULT PARAMETERS' LINE
  996.     CPI    '.'
  997.     JZ    PRTSUP    ;PRINT SUPPRESS TOGGLE
  998.     CPI    '#'
  999.     JZ    MSGSUP    ;MESSAGE SUPPRESS TOGGLE
  1000.     CPI    '<'
  1001.     JZ    IMPRTY    ;IMMEDIATE MODE START
  1002.     CPI    '>'
  1003.     JZ    IMPRTN    ;IMMEDIATE MODE STOP
  1004.     CPI    '&'
  1005.     JZ    IFPSUP    ;PRINT SUPPRESS DURING FALSE IF
  1006.     JMP    MOVST3    ;OTHER CONTROL CODES
  1007. ;
  1008. IFPSUP:
  1009.     MVI    A,IPS    ;CONVERT '^&' TO IF PRINT SUPPRESS FLAG
  1010.     JMP    MOVST3
  1011. ;
  1012. REXC:
  1013.     MVI    A,REXEC    ;CONVERT '^:' TO RE-EXECUTE FLAG
  1014.     JMP    MOVST3
  1015. ;
  1016. GCRW:
  1017.     MVI    A,CRWAIT    ;CONVERT '^?' TO CRWAIT FLAG
  1018.     JMP    MOVST3
  1019. ;
  1020. GCRBW:
  1021.     MVI    A,CRBWAIT    ;CONVERT '^/' TO CRBWAIT FLAG
  1022.     JMP    MOVST3
  1023. ;
  1024. ;  ALLOW USER INPUT FROM NOW ON, BUT FIRST SKIP OUT REST OF LINE
  1025. ;
  1026. UISET:
  1027.     LDAX    D        ;GET NEXT CHAR
  1028.     ANI    7FH        ;MASK IT
  1029.     CPI    LF        ;DONE?
  1030.     JZ    UISET1
  1031.     CPI    1AH        ;EOF?
  1032.     JZ    UISET1
  1033.     INX    D        ;PT TO NEXT CHAR
  1034.     JMP    UISET        ;CONTINUE SKIPPING
  1035. UISET1:
  1036.     MVI    A,UICH        ;CONTROL CHAR
  1037.     JMP    MOVST3
  1038. ;
  1039. GRNG:
  1040.     MVI    A,RNG        ;CONVERT '^*' TO RNG FLAG
  1041.     JMP    MOVST3
  1042. ;
  1043. GCRLF:
  1044.     MVI    A,CR    ;GENERATE CR & LF
  1045.     CALL    CHRSTR
  1046.     MVI    A,LF
  1047.     CALL    CHRSTR
  1048.     STA    LCHR
  1049.     JMP    MOVSTR
  1050. ;
  1051. PRMDEF:
  1052.     PUSH    H
  1053.     LXI    H,PRMDFP
  1054.     PUSH    H
  1055.     LXI    B,PRMDFL
  1056.     XRA    A
  1057.     CALL    FILL    ;CLEAR PTR TABLE
  1058.     POP    H
  1059.     MVI    A,PRMDFL/2
  1060.     STA    PRMMAX    ;HIGHEST PARAMETER #
  1061.     CALL    PARMS    ;BUILD DEFAULT PARAMETERS PTRS
  1062.     POP    H
  1063.     INX    D    ;SKIP CR
  1064.     MVI    A,LF
  1065.     JMP    MOVSTX    ;CONTINUE AT EOL
  1066. ;
  1067. ;  CHECK TO SEE IF PREVIOUS CHAR WAS ALSO A ; AND FLUSH AS ZEX COMMENT IF SO
  1068. ;
  1069. EXCOMM:
  1070.     PUSH    H
  1071.     LXI    H,LCHR    ;PT TO PREVIOUS CHAR
  1072.     CMP    M    ; DOUBLE ;?
  1073.     MOV    M,A    ;STORE CURRENT CHAR AS PREVIOUS CHAR
  1074.     POP    H
  1075.     JNZ    MOVST3    ;NO...CONTINUE
  1076.     MOV    C,A    ;SAVE CHAR
  1077.     LDA    PRTFLG
  1078.     CPI    PSUP
  1079.     MOV    A,C
  1080.     JZ    MOVST3    ;PRINT SUPPRESS
  1081.     LDA    IMFLG1
  1082.     CPI    IMON
  1083.     MOV    A,C
  1084.     JZ    MOVST3    ;IMMEDIATE MODE
  1085.     INX    H    ;YES..IGNORE PREVIOUS ;
  1086.     PUSH    H
  1087.     LXI    H,LCHR
  1088.     LDA    OUTCNT
  1089.     DCR    A    ;DROP 1 CHAR.
  1090.     STA    OUTCNT
  1091. EXCOML:
  1092.     LDAX    D    ;IGNORE CHARACTERS UNTIL EOF OR LF
  1093.     INX    D
  1094.     CPI    1AH    ;EOF
  1095.     JZ    EXCOMX
  1096.     CPI    LF    ;LINE FEED
  1097.     JNZ    EXCOML
  1098.     MOV    M,A
  1099.     LDA    OUTCNT
  1100.     ORA    A    ;ANY CHAR. ON THIS LINE?
  1101.     JZ    EXCOM2    ;NO...SKIP CR
  1102. EXCOM1:
  1103.     POP    H    ;YES..FORCE CR
  1104.     MVI    A,CR
  1105.     CALL    CHRSTR
  1106.     MVI    A,LF
  1107.     JMP    MOVSTX    ;CONTINUE
  1108. ;
  1109. EXCOM2:
  1110.     POP    H
  1111.     MVI    A,LF
  1112.     JMP    MOVSTX    ;CONTINUE
  1113. ;
  1114. EXCOMX:
  1115.     POP    H
  1116.     RET        ;RETURN TO MAIN FLOW, WITH HL PTING TO NEXT BYTE
  1117. ;
  1118. MSGSUP:
  1119.     MVI    A,MSUP    ;CONVERT '^#' TO MESSAGE SUPPRESS FLAG
  1120.     JMP    MOVST3
  1121. ;
  1122. PRTSUP:
  1123.     MVI    A,PSUP    ;CONVERT '^.' TO PRINT SUPPRESS FLAG
  1124.     PUSH    H
  1125.     LXI    H,PRTFLG
  1126.     CMP    M    ;ALREADY ON?
  1127.     JNZ    PRTSST    ;NO...SET FLAG
  1128.     XRA    A    ;YES..CLEAR FLAG
  1129. PRTSST:
  1130.     MOV    M,A    ;SET/RESET FLAG
  1131.     POP    H
  1132.     MVI    A,PSUP
  1133.     JMP    MOVST3
  1134. ;
  1135. IMPRTY:
  1136.     MVI    A,IMON    ;CONVERT '^<' TO IMMEDIATE MODE START
  1137.     STA    LCHR
  1138.     PUSH    H
  1139.     LXI    H,IMFLG1
  1140.     CMP    M    ;ALREADY ON?
  1141.     POP    H
  1142.     JZ    MOVSTR    ;YES..
  1143.     STA    IMFLG1
  1144.     STA    IMFLG2
  1145.     JMP    MOVST3    ;NO...
  1146. ;
  1147. IMPRTN:
  1148.     MVI    A,IMOFF ;CONVERT '^>' TO IMMEDIATE MODE STOP
  1149.     STA    LCHR
  1150.     PUSH    H
  1151.     LXI    H,IMFLG2
  1152.     CMP    M    ;ALREADY OFF?
  1153.     POP    H
  1154.     JZ    MOVSTR    ;YES..
  1155.     STA    IMFLG2
  1156.     STA    IMFLG1
  1157.     JMP    MOVST3    ;NO...
  1158. ;
  1159. ;  PLACE CHAR IN BUFFER; A=CHAR, HL PTS TO BUFFER LOC
  1160. ;
  1161. CHRSTR:
  1162.     PUSH    PSW    ;CHECK FOR INPUT/ZEX BUFFER OVERLAP
  1163.     PUSH    D
  1164.     PUSH    H
  1165.     LHLD    ENDBUF
  1166.     XCHG
  1167.     POP    H
  1168.     MOV    A,L
  1169.     CMP    E
  1170.     JNZ    CHRSTX    ;LSB<>
  1171.     MOV    A,H
  1172.     CMP    D
  1173.     JZ    OVERL    ;MSB=, OVERLAP WILL OCCUR/ABORT ZEX
  1174. ;
  1175. ; ADD CHAR TO ZEX'S BUFFER
  1176. ;
  1177. CHRSTX:
  1178.     POP    D    ;ADD CHAR. TO ZEX'S BUFFER
  1179.     POP    PSW
  1180.     MOV    M,A    ;STORE CHAR
  1181.     DCX    H    ;PT TO NEXT LOCATION (MOVING DOWN)
  1182.     RET
  1183. ;
  1184. ;  CHECK TO SEE IF ZEX IS ALREADY ACTIVE, AND ABORT IF SO
  1185. ;
  1186. ZEXACTV:
  1187.     MVI    B,08H    ;MESSAGE OFFSET
  1188.     CALL    MLDA    ;GET VALUE IN A
  1189.     ORA    A    ;0 IF NO
  1190.     RZ
  1191.     LXI    D,ZEXACT
  1192.     CALL    PRINT    ;ZEX ALREADY PRESENT
  1193. ;
  1194. ;  ABORT AND RETURN TO ZCPR3
  1195. ;
  1196. CCPRET:
  1197.     LHLD    CCPSTK    ;RESTORE STACK
  1198.     SPHL
  1199.     RET        ;RETURN TO CCP
  1200.  
  1201. ;
  1202. ;  ZCPR3 MESSAGE BUFFER ACCESS ROUTINES
  1203. ;
  1204.  
  1205. ;
  1206. ;  GETZ3MSG RETURNS HL POINTING TO DESIRED MESSAGE (OFFSET IN B)
  1207. ;
  1208. GETZ3MSG:
  1209.     PUSH    D    ;SAVE DE
  1210.     LHLD    Z3MSGA    ;GET ADDRESS OF MESSAGES
  1211.     MOV    E,B    ;GET OFFSET
  1212.     MVI    D,0
  1213.     DAD    D    ;HL PTS TO MESSAGE OF INTEREST
  1214.     POP    D
  1215.     RET
  1216.  
  1217. MSHLD:
  1218.     PUSH    D    ;SAVE DE
  1219.     XCHG
  1220.     CALL    GETZ3MSG    ;MAKE HL PT TO MESSAGE
  1221.     MOV    M,E    ;STORE LOW
  1222.     INX    H
  1223.     MOV    M,D    ;STORE HIGH
  1224.     XCHG        ;RESTORE HL
  1225.     POP    D    ;RESTORE DE
  1226.     RET
  1227.  
  1228. MSTA:
  1229.     PUSH    H    ;SAVE HL
  1230.     CALL    GETZ3MSG    ;PT TO MESSAGE WITH HL
  1231.     MOV    M,A    ;STORE MESSAGE
  1232.     POP    H
  1233.     RET
  1234.  
  1235. MLDA:
  1236.     PUSH    H    ;SAVE HL
  1237.     CALL    GETZ3MSG    ;PT TO MESSAGE WITH HL
  1238.     MOV    A,M    ;GET MESSAGE
  1239.     POP    H
  1240.     RET
  1241.  
  1242. ;
  1243. ;  END OF Z3MSG ACCESS ROUTINES
  1244. ;
  1245.  
  1246. ;
  1247. ;    ERROR EXITS
  1248. ;
  1249. GETERR:
  1250.     LXI    D,CMDER ;CONTROL CHARACTER INVALID
  1251.     CALL    PRINT
  1252.     JMP    LINE    ;PRINT LINE # AND LINE AND EXIT
  1253. ;
  1254. NUMERR:
  1255.     LXI    D,NONUM    ;EXCESSIVE NUMBER
  1256.     CALL    PRINT
  1257.     JMP    LINE    ;PRINT LINE # AND LINE AND EXIT
  1258. ;
  1259. PRMERR:
  1260.     LXI    D,PMERR
  1261.     CALL    PRINT
  1262.     JMP    LINE    ;PRINT LINE # AND LINE AND EXIT
  1263. ;
  1264. PRMTOO:
  1265.     LXI    D,TOOARG;TOO MANY PARAMETER ARGUMENTS
  1266.     CALL    PRINT
  1267.     LHLD    ERRLNE
  1268.     CALL    EPRT    ;PRINT PARAMETER LINE
  1269.     JMP    CCPRET
  1270. ;
  1271. BUFLOW:
  1272.     LXI    D,BUFMTY;TEXT BUFFER EMPTY
  1273.     CALL    PRINT
  1274.     JMP    CCPRET
  1275. ;
  1276. NOSUB:
  1277.     LXI    D,NOSBF1;.SUB FILE NOT FOUND
  1278.     CALL    PRINT
  1279.     LXI    D,NOTHER
  1280.     CALL    PRINT
  1281.     JMP    CCPRET
  1282. ;
  1283. OVERL:
  1284.     LXI    D,OVERLP;INPUT/ZEX BUFFER OVERLAP
  1285.     CALL    PRINT
  1286.     JMP    LINE
  1287. ;
  1288. ;    SUBROUTINES
  1289. ;
  1290. ;    CONTROL CODES 0-1FH
  1291. ;    WITH SUPPORT FOR $ . # < >
  1292. ;
  1293. GETCMD:
  1294.     LDAX    D    ;GET NEXT CHARACTER
  1295.     INX    D    ;INCREMENT POINTER
  1296.     CPI    '|'
  1297.     RZ        ;CR,LF GENERATION
  1298.     CPI    'a'-1    ;LOWERCASE?
  1299.     JC    GETUPR    ;NOPE
  1300.     CPI    'z'+1    ;a-z?
  1301.     JNC    GETERR    ;NOPE
  1302.     sui    'a'-'A' ;GET TO UPPERCASE
  1303. GETUPR:
  1304.     CPI    '@'    ;0-1FH CONTROL CODE?
  1305.     JNC    GETCC
  1306.     CPI    ':'
  1307.     RZ        ;RE-EXECUTE
  1308.     CPI    '?'
  1309.     RZ        ;CR WAIT
  1310.     CPI    '/'
  1311.     RZ        ;CR WAIT AND RING BELL
  1312.     CPI    '*'
  1313.     RZ        ;RING BELL
  1314.     CPI    '"'
  1315.     RZ        ;USER INPUT
  1316.     CPI    '$'
  1317.     RZ        ;DEFAULT PARAMETERS' LINE
  1318.     CPI    '.'
  1319.     RZ        ;PRINT SUPPRESS TOGGLE
  1320.     CPI    '#'
  1321.     RZ        ;MESSAGE SUPPRESS TOGGLE
  1322.     CPI    '<'
  1323.     RZ        ;IMMEDIATE MODE START
  1324.     CPI    '>'
  1325.     RZ        ;IMMEDIATE MODE STOP
  1326.     CPI    '&'
  1327.     RZ        ;FALSE IF PRINT SUPPRESS
  1328.     JMP    GETERR
  1329. GETCC:
  1330.     SUI    '@'    ;GET CONTROL CODE
  1331.     RNC
  1332.     JMP    GETERR
  1333. ;
  1334. ;  EXTRACT PARAMETER ELEMENT WHOSE $N SPECIFICATION IS POINTED TO BY DE
  1335. ;    DE PTS TO CHAR AFTER THE $
  1336. ;    BUFFER TO PLACE RESULTING PARAMETER IS PTED TO BY HL
  1337. ;
  1338. GTPARM:
  1339.     LDAX    D    ;GET CHAR AFTER THE $
  1340.     INX    D    ;PT TO NEXT CHAR
  1341.     CPI    '$'    ;IF DOUBLE $, THEN STORE AS $
  1342.     RZ
  1343.     CPI    '^'    ;UP ARROW
  1344.     RZ
  1345.     CPI    '|'    ;CARRIAGE RETURN
  1346.     RZ
  1347.     CPI    '1'    ;CHECK FOR VALID DIGIT (1-9)
  1348.     JC    PRMERR
  1349.     CPI    '9'+1    ;RANGE ERROR?
  1350.     JNC    PRMERR
  1351.     SUI    '1'    ;GET ACTUAL # (ZERO RELATIVE)
  1352.     ADD    A    ;DOUBLE FOR OFFSET
  1353.     STA    PRMNUM
  1354.     PUSH    D    ;SAVE PTRS
  1355.     PUSH    H
  1356.     LXI    H,PRMPNT    ;PT TO PARAMETER PTR TABLE
  1357.     CPI    PRMPNL-1    ;PARAMETER NUMBER WITHIN RANGE?
  1358.     JNC    NOPARM    ;> HIGHEST #
  1359.     MOV    E,A
  1360.     MVI    D,0
  1361.     DAD    D
  1362.     MOV    E,M    ;GET PARAMETER POINTER
  1363.     INX    H
  1364.     MOV    D,M
  1365.     POP    H    ;RESTORE PTR TO NEXT BYTE IN OUTPUT BUFFER BELOW ZEX
  1366.     MOV    A,E    ;ANY PARAM?
  1367.     ORA    D
  1368.     JZ    NOPARM    ;NO PARAMETER PRESENT, TRY DEFAULTS
  1369. ;
  1370. ;  MOVE PARAMETER PTED TO BY DE INTO BUFFER BELOW ZEX, 1ST BYTE PTED TO BY HL
  1371. ;
  1372. MOVPRM:
  1373.     LDAX    D    ;GET PARAMETER CHAR
  1374.     INX    D    ;PT TO NEXT
  1375.     ORA    A    ;DONE?
  1376.     JZ    ENDPAR
  1377.     CALL    CHRSTR    ;STORE CHARS
  1378.     JMP    MOVPRM
  1379. ;
  1380. ;  PARAMETER PLACED IN MEMORY -- CONTINUE
  1381. ;
  1382. ENDPAR:
  1383.     POP    D    ;GET PTR TO NEXT CHAR IN LINE
  1384.     POP    PSW    ;CLEAR STACK
  1385.     JMP    MOVSTR    ;RESUME PROCESSING
  1386. ;
  1387. ;  NO PARAMETER PTED TO
  1388. ;
  1389. NOPARM:
  1390.     PUSH    H    ;SAVE PTR TO NEXT BYTE IN BUFFER BELOW ZEX
  1391.     LXI    H,PRMDFP    ;TRY DEFAULT PARAMETERS
  1392.     LDA    PRMNUM
  1393.     CPI    PRMDFL-1
  1394.     JNC    NUMERR    ;> HIGHEST #
  1395.     MOV    E,A
  1396.     MVI    D,0
  1397.     DAD    D
  1398.     MOV    E,M    ;GET PARAMETER POINTER
  1399.     INX    H
  1400.     MOV    D,M
  1401.     POP    H
  1402.     MOV    A,E
  1403.     ORA    D
  1404.     JNZ    MOVPRM    ;MOVE PARAMETER INTO BUFFER
  1405.     JMP    ENDPAR    ;RESUME WITH NO PARAMETER
  1406. ;
  1407. MOVEFN:
  1408.     LDAX    D
  1409.     CPI    ' '    ;SEE IF SPACE
  1410.     RZ
  1411.     MOV    M,A
  1412.     INX    D    ;INCREMENT POINTERS
  1413.     INX    H
  1414.     DCR    B
  1415.     JNZ    MOVEFN
  1416.     RET
  1417. ;
  1418. ;  INCREMENT LINE COUNT, AND AFFECT ONLY HL (MUST NOT AFFECT A)
  1419. ;
  1420. INCR:
  1421.     PUSH    H    ;SAVE OUTPUT POINTER
  1422.     LHLD    LINES
  1423.     INX    H    ;INCREMENT LINE COUNTER
  1424.     SHLD    LINES
  1425.     LXI    H,LCHR    ;CLEAR LAST CHARACTER
  1426.     MVI    M,0
  1427.     LXI    H,OUTCNT;CLEAR CHARACTER COUNT
  1428.     MVI    M,0
  1429.     MOV    L,E    ;DE=HL
  1430.     MOV    H,D
  1431.     SHLD    BEGLIN
  1432.     POP    H
  1433.     SHLD    OUTLNE    ;SAVE NEW OUTPUT LINE
  1434.     RET
  1435. ;
  1436. CNTINC:
  1437.     CPI    ' '    ;CONTROL CHARACTER?
  1438.     RC        ;YES..
  1439.     CPI    UICH    ;USER INPUT CHAR?
  1440.     JZ    CNTIN1
  1441.     ANI    80H    ;SPECIAL CONTROL?
  1442.     RNZ        ;YES..
  1443.     LDA    PRTFLG
  1444.     CPI    PSUP    ;PRINT SUPPRESS FLAG?
  1445.     RZ        ;YES..
  1446.     LDA    IMFLG1
  1447.     CPI    IMON    ;IMMEDIATE MODE?
  1448.     RZ        ;YES..
  1449. CNTIN1:
  1450.     LDA    OUTCNT
  1451.     INR    A
  1452.     STA    OUTCNT
  1453.     RET
  1454. ;
  1455. PRINT:
  1456.     MVI    C,9    ;PRINT STRING AT (DE)
  1457.     JMP    BDOS
  1458. ;
  1459. EPRT:
  1460.     MOV    A,M    ;PRINT PARAMETER LINE AT (HL)
  1461.     CPI    CR
  1462.     RZ
  1463.     CPI    0
  1464.     JNZ    EPRT1
  1465.     MVI    A,' '
  1466. EPRT1:
  1467.     INX    H
  1468.     PUSH    H
  1469.     MOV    E,A
  1470.     MVI    C,2
  1471.     CALL    BDOS
  1472.     POP    H
  1473.     JMP    EPRT
  1474. ;
  1475. CRLF:
  1476.     LXI    D,CRLFS ;PRINT CR/LF
  1477.     JMP    PRINT
  1478. ;
  1479. LINE:
  1480.     LXI    D,LINEM ;PRINT LINE # AND LINE IN ERROR AND EXIT
  1481.     CALL    PRINT
  1482.     LHLD    LINES
  1483.     CALL    DECOUT    ;PRINT LINE #
  1484.     CALL    CRLF
  1485.     LHLD    BEGLIN
  1486.     PUSH    H    ;SAVE BEGGING POINTER
  1487. FINDCR:
  1488.     MOV    A,M
  1489.     INX    H
  1490.     CPI    1AH    ;END OF BUFFER
  1491.     JZ    FOUND
  1492.     CPI    CR
  1493.     JNZ    FINDCR
  1494. FOUND:
  1495.     MVI    M,0    ;END OF STRING
  1496.     POP    H    ;START OF STRING
  1497.     CALL    PRNTHL    ;PRINT BAD LINE
  1498.     JMP    CCPRET    ;THATS ALL FOLKS
  1499. ;
  1500. PRNTHL:
  1501.     MOV    A,M    ;PRINT LINE AT (HL)
  1502.     INX    H
  1503.     ORA    A
  1504.     RZ
  1505.     MOV    E,A
  1506.     PUSH    H    ;SAVE POINTER
  1507.     CALL    OUTCHR
  1508.     POP    H    ;GET POINTER BACK
  1509.     JMP    PRNTHL
  1510. ;
  1511. OUTCHR:
  1512.     MVI    C,2    ;PRINT CHARACTER IN E
  1513.     JMP    BDOS
  1514. ;
  1515. DECOUT:
  1516.     PUSH    H    ;PRINT DECIMAL LINE NUMBER
  1517.     PUSH    D
  1518.     PUSH    B
  1519.     LXI    B,-10    ;RADIX FOR CONVERSION
  1520.     LXI    D,-1    ;THIS BECOMES NO DIVIDED BY RADIX
  1521. DX:
  1522.     DAD    B    ;SUBTRACT 10
  1523.     INX    D
  1524.     JC    DX
  1525.     LXI    B,10
  1526.     DAD    B    ;ADD RADIX BACK IN ONCE
  1527.     XCHG
  1528.     MOV    A,H
  1529.     ORA    L    ;TEST FOR ZERO
  1530.     CNZ    DECOUT    ;RECURSIVE CALL
  1531.     MOV    A,E
  1532.     ADI    '0'    ;CONVERT FROM BCD TO HEX
  1533.     MOV    E,A    ;TO E FOR OUTPUT
  1534.     MVI    C,2
  1535.     CALL    BDOS
  1536.     POP    B    ;RESTORE REGISTERS
  1537.     POP    D
  1538.     POP    H
  1539.     RET
  1540. ;
  1541. MOVE:
  1542.     MOV    A,M    ;MOVE STRING AT (HL) TO (DE) FOR LENGTH IN B
  1543.     INX    H
  1544.     STAX    D
  1545.     INX    D
  1546.     DCR    B
  1547.     JNZ    MOVE
  1548.     RET
  1549. ;
  1550. FILL:
  1551.     PUSH    D    ; FILL STORAGE AT (HL) WITH CHARACTER IN A
  1552.     MOV    E,A    ; FOR LENGTH IN BC
  1553.     MOV    A,B
  1554.     ORA    C
  1555.     MOV    A,E
  1556.     POP    D
  1557.     RZ
  1558.     DCX    B
  1559.     MOV    M,A
  1560.     INX    H
  1561.     JMP    FILL
  1562. ;
  1563. ;    WORKING STORAGE AREA
  1564. ;
  1565. SUBNAM:
  1566.     DB    'SUB'
  1567. ZEXNAM:
  1568.     DB    'ZEX'
  1569. LINEM:
  1570.     DB    ' Error Line # $'
  1571. ZEXACT:
  1572.     DB    CR,LF,' ZEX Already Present$'
  1573. BUFMTY:
  1574.     DB    CR,LF,'Text Buffer Empty$'
  1575. OVERLP:
  1576.     DB    CR,LF,'Input/ZEX Buffer Overlap$'
  1577. NONUM:
  1578.     DB    CR,LF,'Parameter Number out of range$'
  1579. NOPRM:
  1580.     DB    CR,LF,'No Parameter or Default Parameter$'
  1581. PMERR:
  1582.     DB    CR,LF,'Parameter$'
  1583. NOSBF1:
  1584.     DB    CR,LF,'File '
  1585. NOSBF2:
  1586.     DB    'filename.typ$'
  1587. NOTHER:
  1588.     DB    ' not there$'
  1589. CMDER:
  1590.     DB    CR,LF,'Control character$'
  1591. TOOARG:
  1592.     DB    CR,LF,'Too many arguments - $'
  1593. SIGNON:
  1594.     DB    'ZEX, Version '
  1595.     DB    VERS/10+'0','.',(VERS MOD 10)+'0','$'
  1596. CRLFS:
  1597.     DB    CR,LF,'$'
  1598. ;
  1599.     DS    80    ;STACK SPACE
  1600. CCPSTK:
  1601.     DW    0    ;CCP STACK PTR
  1602. IMFLG1:
  1603.     DB    0    ;=IMON ENCOUNTERED
  1604. IMFLG2:
  1605.     DB    0    ;=IMOFF ENCOUNTERED
  1606. PRTFLG:
  1607.     DB    0    ;=PSUP ON
  1608. LCHR:
  1609.     DB    0    ;LAST CHARACTER READ
  1610. PRMMAX:
  1611.     DB    0    ;HIGHEST PARAMETER #
  1612. PRMNUM:
  1613.     DB    0    ;CURRENT $<1-9> NUMBER * 2 (ZERO RELATIVE)
  1614. ERRLNE:
  1615.     DW    0
  1616. BITMAP:
  1617.     DB    0    ;PRESENT OFFSET BIT'S
  1618. COUNT:
  1619.     DB    0FFH    ;PRESENT OFFSET BIT COUNT
  1620. BEGLIN:
  1621.     DW    BEGREL    ;BEGINNING OF OLD LINE POINTER
  1622. LINES:
  1623.     DW    1
  1624. INBUF:
  1625.     DW    BEGREL
  1626. ENDBUF:
  1627.     DW    0    ;END OF INPUT BUFFER
  1628. OUTCNT:
  1629.     DB    0
  1630. OUTLNE:
  1631.     DW    0
  1632. RELSTRT:
  1633.     DW    0
  1634. OUTBUF:
  1635.     DW    0
  1636. BUFSTR:
  1637.     DW    0
  1638. RELOCL:
  1639.     DW    0    ;LENGTH OF RELOC PROGRAM (FILLED IN BY SID)
  1640. PRMDFP:         ;DEFAULT PARAMETER PTRS
  1641.     REPT    9
  1642.     DW    0
  1643.     ENDM
  1644. PRMDFL    EQU    $-PRMDFP
  1645. PRMDMY:
  1646.     DW    0    ;DUMMY PARAMETER FOR .SUB FILE SPEC.
  1647. PRMPNT:         ;COMMAND LINE PARAMETER PTRS
  1648.     REPT    9
  1649.     DW    0
  1650.     ENDM
  1651. PRMPNL    EQU    $-PRMPNT
  1652. PATCH:            ;PATCH AREA
  1653.     REPT    32
  1654.     DB    'p'
  1655.     ENDM
  1656.     REPT    30
  1657.     DW    0
  1658.     ENDM
  1659. ;
  1660. ;    INSURE 8 BYTE BOUNDARY FOR REL.UTL(RELS.UTL)
  1661. ;
  1662. ?PLOC    SET    $
  1663.     IF    (?PLOC MOD 8) GT 0
  1664. ?PLOC    SET    (?PLOC AND 0FFF8H)+8 ;GET NEXT 8 BYTE BOUNDARY
  1665.     ORG    ?PLOC
  1666.     ENDIF
  1667. ;
  1668. BEGREL:
  1669.     DS    0    ;RELOC PROGRAM STARTS HERE (ALSO USED AS BUFFER)
  1670. ;
  1671.     ENDIF
  1672. ;
  1673. ;    END OF ZEX INITIATOR CODE SEGMENT
  1674. ;
  1675. $-PRINT
  1676.     IF NOT    ZEXBASE
  1677. $+PRINT
  1678. ;
  1679. ;    START OF ZEX RELOCATED CODE SEGMENT
  1680. ;        HL PTS TO MULTIPLE COMMAND BUFFER
  1681. ;         OR HL=0 IF NO MULTIPLE COMMANDS
  1682. ;
  1683.     ORG    ZEXREL
  1684. ;
  1685. ZEX:
  1686.     SHLD    EXMBASE    ;SAVE ADDRESS OF MCL BUFFER
  1687.     XCHG        ;HL=ADDRESS OF ZCPR3 MESSAGES
  1688.     SHLD    Z3MSGA    ;SAVE ADDRESS
  1689.     MVI    B,09H    ;MESSAGE OFFSET
  1690.     CALL    MLHLD    ;GET ADDRESS OF NEXT CHAR
  1691.     MOV    A,M    ;GET 1ST CHAR
  1692.     CPI    MSUP    ;1ST CHAR=MESSAGE SUPPRESS?
  1693.     JNZ    ZEX1    ;NO...
  1694.     DCX    H    ;YES..SKIP CHARACTER
  1695.     MVI    B,09H    ;MESSAGE OFFSET
  1696.     CALL    MSHLD    ;SET PTR TO NEXT CHAR
  1697.     STA    MSUPFL    ;SET INITIAL FLAG
  1698. ZEX1:
  1699.     LXI    SP,MEMTOP
  1700.     LHLD    BDOS+1    ;GET WARM JUMP FOR STANDARD CCP
  1701.     SHLD    MEMTOP    ;SET PTR TO TOP OF MEMORY
  1702.     INX    H
  1703.     MOV    E,M    ;DE = ADDRESS OF ACTUAL BDOS
  1704.     INX    H
  1705.     MOV    D,M
  1706.     XCHG        ;HL PTS TO ACTUAL BDOS
  1707.     MOV    A,H    ;SUBTRACT 8 FOR CCP ENTRY POINT
  1708.     SUI    8
  1709.     MOV    H,A
  1710.     MVI    L,3    ;SET UP FOR WARM CCP JUMP
  1711.     SHLD    CCPJMP
  1712.     LHLD    WARM+1    ;SAVE WARM BOOT ADDRESS
  1713.     SHLD    WARMPT
  1714.     LXI    D,BSWARM    ;SAVE OLD BIOS JUMPS
  1715.     MVI    B,12
  1716.     CALL    MOVE    ;MOVE BIOS JUMPS
  1717.     LHLD    WARMPT
  1718.     XCHG
  1719.     LXI    H,LOCJMP    ;STORE NEW BIOS JUMPS
  1720.     MVI    B,12
  1721.     CALL    MOVE    ;MOVE NEW BIOS JUMPS TO BIOS AREA
  1722. ;
  1723. ;    ZEX RUNTIME BIOS INTERCEPT ROUTINES
  1724. ;
  1725. NWARM:
  1726.     LXI    SP,MEMTOP
  1727.     MVI    B,09H    ;MESSAGE OFFSET
  1728.     CALL    MLHLD    ;GET ADDRESS OF NEXT CHAR
  1729.     MOV    A,M
  1730.     CPI    0FFH    ;TEST IT
  1731.     JZ    WARMX    ;WARM RETURN
  1732.     LHLD    WARMPT    ;SET WARM BOOT ADDRESS
  1733.     SHLD    WARM+1
  1734.     LHLD    MEMTOP    ;SET BDOS ENTRY ADDRESS
  1735.     SHLD    BDOS+1
  1736.     LXI    D,BUFF    ;DMA ADDRESS
  1737.     MVI    C,26    ;SET DMA
  1738.     CALL    BDOS
  1739.     LDA    BDISK
  1740.     MOV    C,A
  1741.     LHLD    CCPJMP
  1742.     PCHL        ;GOTO CONSOLE PROCESSOR
  1743. ;
  1744. ;    JMP TABLE TO OVERLAY BIOS WITH NEW ZEX-BASED JUMPS
  1745. ;
  1746. LOCJMP:
  1747.     JMP    NWARM    ;WARM
  1748.     JMP    BCONST    ;CONST
  1749.     JMP    NCONIN    ;CONIN
  1750.     JMP    NCONOT    ;CONOT
  1751. ;
  1752. ;  ZCPR3 MESSAGE BUFFER ACCESS ROUTINES
  1753. ;
  1754.  
  1755. ;
  1756. ;  GETZ3MSG RETURNS HL POINTING TO DESIRED MESSAGE (OFFSET IN B)
  1757. ;
  1758. Z3MSGA:
  1759.     DW    0    ;MESSAGES ADDRESS
  1760. GETZ3MSG:
  1761.     PUSH    D    ;SAVE DE
  1762.     LHLD    Z3MSGA    ;GET ADDRESS OF MESSAGES
  1763.     MOV    E,B    ;GET OFFSET
  1764.     MVI    D,0
  1765.     DAD    D    ;HL PTS TO MESSAGE OF INTEREST
  1766.     POP    D
  1767.     RET
  1768.  
  1769. MSHLD:
  1770.     PUSH    D    ;SAVE DE
  1771.     XCHG
  1772.     CALL    GETZ3MSG    ;MAKE HL PT TO MESSAGE
  1773.     MOV    M,E    ;STORE LOW
  1774.     INX    H
  1775.     MOV    M,D    ;STORE HIGH
  1776.     XCHG        ;RESTORE HL
  1777.     POP    D    ;RESTORE DE
  1778.     RET
  1779.  
  1780. MLHLD:
  1781.     PUSH    PSW    ;SAVE A
  1782.     CALL    GETZ3MSG    ;MAKE HL PT TO MESSAGE
  1783.     MOV    A,M    ;GET LOW
  1784.     INX    H
  1785.     MOV    H,M    ;GET HIGH
  1786.     MOV    L,A    ;PUT LOW
  1787.     POP    PSW    ;RESTORE A
  1788.     RET
  1789.  
  1790. MSTA:
  1791.     PUSH    H    ;SAVE HL
  1792.     CALL    GETZ3MSG    ;PT TO MESSAGE WITH HL
  1793.     MOV    M,A    ;STORE MESSAGE
  1794.     POP    H
  1795.     RET
  1796.  
  1797. MLDA:
  1798.     PUSH    H    ;SAVE HL
  1799.     CALL    GETZ3MSG    ;PT TO MESSAGE WITH HL
  1800.     MOV    A,M    ;GET MESSAGE
  1801.     POP    H
  1802.     RET
  1803.  
  1804. ;
  1805. ;  END OF Z3MSG ACCESS ROUTINES
  1806. ;
  1807.  
  1808. ;
  1809. ;    CONSOLE INPUT INTERCEPT ROUTINE
  1810. ;
  1811. NCONIN:
  1812.     MVI    B,07H    ;MESSAGE OFFSET
  1813.     CALL    GETZ3MSG    ;PT TO ZEX MESSAGE BYTE
  1814.     MOV    A,M    ;GET ZEX MESSAGE
  1815.     CPI    2    ;SUSPEND INTERCEPT?
  1816.     JZ    BCONIN    ;GET INPUT VIA BIOS IF USER INPUT ACTIVE
  1817.     CPI    1    ;PROMPT JUST PRINTED?
  1818.     JNZ    NCONNP
  1819.     MVI    M,0    ;CLEAR ZEX MESSAGE
  1820.     LXI    H,STARTM    ;PRINT MESSAGE
  1821.     CALL    PMSG
  1822. ;    LDA    PMCHR    ;PRINT PROMPT CHAR
  1823. ;    MOV    C,A
  1824. ;    CALL    BCONOT
  1825. NCONNP:
  1826.     MVI    B,08H    ;MESSAGE OFFSET
  1827.     CALL    MLDA    ;GET ZEX RUNNING MESSAGE
  1828.     ORA    A    ;0=NO
  1829.     JZ    WARMX    ;ABORT ZEX IF NOT
  1830.     LXI    H,0
  1831.     DAD    SP    ;SAVE RETURN STACK LEVEL
  1832.     SHLD    CONSTK
  1833.     LXI    SP,MEMTOP    ;SET USER STACK
  1834. NCONNL:
  1835.     CALL    BCONST    ;GET CONSOLE STATUS
  1836.     ORA    A
  1837.     JZ    GETBUF    ;GET CHARACTER FROM BUFFER
  1838.     CALL    BCONIN    ;GET CHARACTER
  1839.     CPI    'C'-'@' ;SEE IF TERMINATE CHARACTER
  1840.     JZ    ZEXABRT
  1841.     CPI    'S'-'@' ;13H
  1842.     JNZ    NCONEX
  1843.     CALL    BCONIN    ;WAIT FOR NEXT CHARACTER
  1844.     ANI    7FH
  1845.     MVI    B,09H    ;MESSAGE OFFSET
  1846.     CALL    MLHLD    ;PT TO NEXT CHAR
  1847.     INX    H
  1848.     MOV    M,A
  1849.     MVI    B,09H    ;MESSAGE OFFSET
  1850.     CALL    MSHLD    ;RESET PTR TO NEXT CHAR
  1851.     MVI    A,'S'-'@'    ;13H
  1852. NCONEX:
  1853.     LHLD    CONSTK    ;RESTORE CALLER'S STACK
  1854.     SPHL
  1855.     RET
  1856. ;
  1857. ;  RETURN NEXT CHAR FROM INPUT BUFFER
  1858. ;
  1859. GETBUF:
  1860.     LDA    IPSUPFL    ;COMBINE PSUPFL AND IPSUPFL TO SET PRINT FLAG
  1861.     ORA    A    ;0=NO SUPPRESS
  1862.     JZ    GBUF0
  1863.     MVI    B,01H    ;OFFSET TO IF FLAG
  1864.     CALL    GETZ3MSG    ;PT TO IF FLAG
  1865.     MOV    A,M    ;GET IF FLAG
  1866.     ORA    A    ;NO IF?
  1867.     JZ    GBUF0
  1868.     INX    H
  1869.     ANA    M    ;SET IF STATE
  1870.     JNZ    GBUF0    ;CURRENT IF IS TRUE
  1871.     MVI    A,0FFH    ;SUPPRESS PRINT
  1872.     STA    OUTFLG
  1873.     JMP    GBUF1
  1874. GBUF0:
  1875.     LDA    PSUPFL    ;SET PRINT SUPPRESS FLAG FOR NCONOT
  1876.     STA    OUTFLG
  1877. GBUF1:
  1878.     CALL    GETCHR    ;GET NEXT CHARACTER
  1879.     CPI    UICH    ;USER INPUT?
  1880.     JZ    UISTRT    ;YES..SET USER INPUT PENDING FLAG
  1881.     CPI    REXEC    ;RE-EXECUTE?
  1882.     JZ    REXECR    ;YES..RESET BUFFER PTR
  1883.     CPI    CRWAIT    ;CR WAIT?
  1884.     JZ    CRWRTN    ;YES..WAIT FOR CR
  1885.     CPI    CRBWAIT    ;CR WAIT WITH RING BELL?
  1886.     JZ    CRBWRTN    ;YES..WAIT FOR CR AND RING BELL
  1887.     CPI    RNG    ;RING BELL?
  1888.     JZ    RNGBELL    ;YES..JUST RING THE BELL
  1889.     CPI    MSUP    ;MESSAGE SUPPRESS FLAG?
  1890.     JZ    MSUPCK    ;YES..TOGGLE FLAG
  1891.     CPI    PSUP    ;PRINT SUPPRESS ?
  1892.     JZ    PSUPCK    ;YES..TOGGLE FLAG
  1893.     CPI    IPS    ;FALSE IF PRINT SUPPRESS?
  1894.     JZ    IPSUPCK
  1895.     CPI    IMON    ;IMMEDIATE MODE START ?
  1896.     JZ    IMFLGS    ;YES..SET FLAG
  1897.     CPI    IMOFF    ;IMMEDIATE MODE STOP?
  1898.     JZ    IMFLGS    ;YES..RESET FLAG
  1899.     CPI    CR    ;CR?
  1900.     JNZ    GETEXT    ;NO...EXIT
  1901. ;
  1902. ; CR, SO RESET PRINT SUPPRESSION BASED ONLY ON IPSUPFL
  1903. ;
  1904.     LDA    IPSUPFL    ;COMBINE PSUPFL AND IPSUPFL TO SET PRINT FLAG
  1905.     ORA    A    ;0=NO SUPPRESS
  1906.     JZ    GBUF2
  1907.     MVI    B,01H    ;MESSAGE OFFSET TO IF FLAG
  1908.     CALL    GETZ3MSG    ;PT TO IF FLAG
  1909.     MOV    A,M    ;GET IF FLAG
  1910.     ORA    A    ;NO IF?
  1911.     JZ    GBUF2
  1912.     INX    H
  1913.     ANA    M    ;SET IF STATE
  1914.     JNZ    GBUF2    ;CURRENT IF IS TRUE
  1915.     MVI    A,0FFH    ;SUPPRESS PRINT
  1916.     STA    OUTFLG
  1917.     MVI    A,CR
  1918.     JMP    GETEXT
  1919. GBUF2:
  1920.     XRA    A
  1921.     STA    OUTFLG    ;YES..RESET PRINT SUPPRESSION
  1922.     MVI    A,CR
  1923. GETEXT:
  1924.     MOV    C,A
  1925.     LDA    IMFLG
  1926.     CPI    IMON    ;IMMEDIATE MODE ?
  1927.     MOV    A,C
  1928.     JNZ    NCONEX    ;NO...RETURN TO CALLER WITH CHAR
  1929.     CALL    BCONOT    ;YES..IMMEDIATE ECHO TO CONSOLE
  1930.     JMP    NCONNL    ;...LOOP UNTIL IMOFF
  1931. ;
  1932. ;  ^" COMMAND
  1933. ;
  1934. UISTRT:
  1935.     MVI    A,2    ;SET MESSAGE TO SUSPEND INTERCEPT
  1936.     MVI    B,07H    ;MESSAGE OFFSET
  1937.     CALL    MSTA    ;SET MESSAGE
  1938.     LHLD    CONSTK    ;RESTORE CALLER'S STACK
  1939.     SPHL
  1940.     JMP    NCONIN    ;GET CHAR FROM USER FOR NOW
  1941. ;
  1942. ;  ^: COMMAND
  1943. ;
  1944. REXECR:
  1945.     MVI    B,0BH    ;MESSAGE OFFSET
  1946.     CALL    MLHLD    ;PT TO FIRST CHAR IN BUFFER
  1947.     MVI    B,09H    ;MESSAGE OFFSET
  1948.     CALL    MSHLD    ;SET PTR TO NEXT CHAR
  1949.     XRA    A
  1950.     STA    IMFLG    ;RESET ALL FLAGS
  1951.     STA    PSUPFL
  1952.     STA    IPSUPFL
  1953.     STA    MSUPFL
  1954.     JMP    NCONNL    ;...LOOP UNTIL ^C
  1955. ;
  1956. ;  ^? COMMAND
  1957. ;
  1958. CRWRTN:
  1959.     CALL    BCONIN    ;GET INPUT CHAR
  1960.     CPI    'C'-'@'
  1961.     JZ    ZEXABRT    ;=^C
  1962.     CPI    CR
  1963.     JZ    CRWRTX    ;=<CR>
  1964.     CPI    ' '
  1965.     JZ    CRWRTX    ;=<SP>
  1966.     MVI    C,BELL
  1967.     CALL    BCONOT    ;<>CR
  1968.     JMP    CRWRTN
  1969. ;
  1970. ;  ^/ COMMAND
  1971. ;
  1972. CRBWRTN:
  1973.     LXI    H,DELAY    ;SET COUNTER
  1974. CRBWR1:
  1975.     PUSH    H    ;SAVE COUNTER
  1976.     CALL    BCONST    ;CHECK STATUS
  1977.     POP    H    ;GET COUNTER
  1978.     ORA    A    ;SET FLAGS
  1979.     JNZ    CRBWR2
  1980.     DCX    H    ;COUNT DOWN
  1981.     MOV    A,H    ;DONE?
  1982.     ORA    L
  1983.     JNZ    CRBWR1
  1984.     MVI    C,BELL    ;RING BELL
  1985.     CALL    BCONOT
  1986.     JMP    CRBWRTN
  1987. CRBWR2:
  1988.     CALL    BCONIN    ;GET CHAR
  1989.     CPI    'C'-'@'    ;ABORT?
  1990.     JZ    ZEXABRT
  1991.     CPI    CR    ;CONT IF <CR>
  1992.     JNZ    CRBWRTN
  1993. ;
  1994. ;  ^| COMMAND
  1995. ;
  1996. CRWRTX:
  1997.     MOV    C,A    ;ECHO CR/LF
  1998.     CALL    NCONOT
  1999.     MVI    C,LF
  2000.     CALL    NCONOT
  2001.     JMP    GETBUF
  2002. ;
  2003. ;  ^* COMMAND
  2004. ;
  2005. RNGBELL:
  2006.     MVI    C,BELL    ;RING BELL
  2007.     CALL    NCONOT
  2008.     JMP    GETBUF
  2009. ;
  2010. ;  ^. COMMAND
  2011. ;
  2012. PSUPCK:
  2013.     LXI    H,PSUPFL
  2014.     CMP    M
  2015.     JNZ    PSUPST    ;SET FLAGS IF NOT EQUAL
  2016.     XRA    A    ;ELSE RESET FLAGS
  2017. PSUPST:
  2018.     MOV    M,A    ;SET/RESET SAVED FLAG
  2019.     JMP    GETBUF    ;AND GET NEXT CHARACTER (SETS EXEC FLAG)
  2020. ;
  2021. ;  ^& COMMAND
  2022. ;
  2023. IPSUPCK:
  2024.     LXI    H,IPSUPFL
  2025.     CMP    M
  2026.     JNZ    PSUPST    ;SET FLAGS IF NOT EQUAL
  2027.     XRA    A    ;ELSE RESET FLAGS
  2028.     JMP    PSUPST    ;SET/RESET FLAG IN A
  2029. ;
  2030. ;  ^# COMMAND
  2031. ;
  2032. MSUPCK:
  2033.     LXI    H,MSUPFL
  2034.     CMP    M
  2035.     JNZ    MSUPST    ;SET FLAGS IF NOT EQUAL
  2036.     XRA    A    ;ELSE RESET FLAG
  2037. MSUPST:
  2038.     MOV    M,A    ;SET/RESET FLAG
  2039.     JMP    GETBUF    ;AND GET NEXT CHARACTER
  2040. ;
  2041. ;  ^< AND ^> COMMANDS
  2042. ;
  2043. IMFLGS:
  2044.     STA    IMFLG    ;SET/RESET IMMEDIATE MODE FLAG
  2045.     JMP    GETBUF    ;GET NEXT CHARACTER
  2046. ;
  2047. ;    CONSOLE OUTPUT INTERCEPT ROUTINE
  2048. ;
  2049. NCONOT:
  2050.     LDA    OUTFLG    ;PRINT SUPPRESSION?
  2051.     ORA    A
  2052.     RNZ        ;YES...IGNORE ECHO
  2053.     MOV    A,C
  2054.     STA    PMCHR    ;SET LAST CHAR OUTPUT
  2055.     JMP    BCONOT
  2056. ;
  2057. ;  GET NEXT CHAR FROM BUFFER AND TERMINATE ZEX IF END OF BUFFER
  2058. ;
  2059. GETCHR:
  2060.     MVI    B,09H    ;MESSAGE OFFSET
  2061.     CALL    MLHLD    ;PT TO NEXT CHAR
  2062.     MOV    A,M    ;GET IT
  2063.     DCX    H    ;PT TO FOLLOWING
  2064.     MVI    B,09H    ;MESSAGE OFFSET
  2065.     CALL    MSHLD    ;SET PTR TO NEXT CHAR
  2066.     CPI    0FFH    ;EOB?
  2067.     RNZ        ;NO...RETURN
  2068. ;    LHLD    Z3MSG+09H    ;PT TO EOB
  2069.     INX    H    ;POINT TO EOB
  2070.     MVI    B,09H    ;MESSAGE OFFSET
  2071.     CALL    MSHLD    ;SET PTR TO NEXT CHAR (LAST CHAR)
  2072.     CALL    MOVBAK    ;MOVE JUMPS BACK
  2073.     CALL    BDOSRST    ;RESTORE BDOS ADDRESS
  2074.     CALL    PRDONEM
  2075.     XRA    A    ;TURN OFF ZEX
  2076.     MVI    B,08H    ;MESSAGE OFFSET
  2077.     CALL    MSTA    ;TURN OFF ZEX
  2078.     LHLD    CONSTK    ;GET OLD STACK
  2079.     SPHL
  2080.     MVI    A,CR    ;RETURN CARRIAGE RETURN
  2081.     RET
  2082.  
  2083. ;
  2084. ;  PRINT DONE MESSAGE WITH FOLLOWING PROMPT CHAR
  2085. ;
  2086. PRDONEM:
  2087.     LXI    H,DONEM    ;PRINT MESSAGE
  2088.     CALL    PMSG
  2089.     LDA    PMCHR    ;PRINT PROMPT CHAR
  2090.     MOV    C,A    ;IN C FOR BIOS
  2091.     JMP    BCONOT
  2092.  
  2093. ;
  2094. ;  RESTORE BDOS JMP IF NECESSARY
  2095. ;
  2096. BDOSRST:
  2097.     LHLD    MEMTOP    ;SEE IF BDOS+1=MEMTOP
  2098.     XCHG
  2099.     LHLD    BDOS+1
  2100.     MOV    A,E
  2101.     SUB    L
  2102.     MOV    A,D
  2103.     SBB    H
  2104.     RNZ        ;DON'T REPLACE BDOS JUMP
  2105.     INX    D    ;PT TO BDOS JUMP
  2106.     LDAX    D    ;GET LOW ADDRESS
  2107.     MOV    L,A    ;... IN L
  2108.     INX    D
  2109.     LDAX    D    ;GET HIGH ADDRESS
  2110.     MOV    H,A    ;... IN H
  2111.     SHLD    BDOS+1    ;RESET BDOS JUMP
  2112.     RET
  2113. ;
  2114. ;    ^C ABORT EXIT
  2115. ;
  2116. ZEXABRT:
  2117.     LXI    SP,MEMTOP    ;^C ABORTS ZEX
  2118.     LXI    H,ABORTD    ;ABORT
  2119.     CALL    PMSG
  2120.     JMP    WARMX1        ;DON'T PRINT DONE MESSAGE
  2121. ;
  2122. ;  ABORT ZEX AND RETURN TO ZCPR3
  2123. ;
  2124. WARMX:
  2125.     CALL    PRDONEM    ;PRINT DONE MESSAGE
  2126. ;
  2127. ;  ENTRY POINT TO ABORT ZEX WITHOUT MESSAGE
  2128. ;
  2129. WARMX1:
  2130.     XRA    A    ;SAY THAT ZEX IS NOT RUNNING
  2131.     MVI    B,08H    ;MESSAGE OFFSET
  2132.     CALL    MSTA    ;SET NOT RUNNING
  2133.     CALL    MOVBAK    ;MOVE JUMPS BACK
  2134.     CALL    BDOSRST    ;RESTORE BDOS JUMPS
  2135.     LHLD    EXMBASE    ;MULTIPLE COMMAND LINES ENABLED?
  2136.     MOV    A,H    ;ANY ON?
  2137.     ORA    L
  2138.     JZ    WARM    ;NONE ON IF ADDRESS IS ZERO, SO JUST WARM BOOT
  2139. ;
  2140. ;  THIS SECTION OF CODE CLEARS THE MULTIPLE COMMAND LINE BUFFER
  2141. ;
  2142.     MOV    D,H    ;DE PTS TO MULTIPLE COMMAND BUFFER ALSO
  2143.     MOV    E,L
  2144.     PUSH    H    ;SAVE PTR
  2145.     LXI    H,4    ;PT TO FIRST CHAR OF LINE
  2146.     DAD    D
  2147.     MVI    M,0    ;SET FIRST CHAR OF LINE TO ZERO FOR EOL
  2148.     XCHG        ;DE PTS TO FIRST CHAR OF LINE
  2149.     POP    H    ;GET PTR
  2150.     MOV    M,E    ;STORE ADDRESS OF EMPTY COMMAND (EOL)
  2151.     INX    H
  2152.     MOV    M,D
  2153.     JMP    WARM
  2154. ;
  2155. ;    SUBROUTINES
  2156. ;
  2157. MOVBAK:
  2158.     LHLD    WARMPT    ;MOVE OLD JUMP TABLE BACK TO BIOS
  2159.     XCHG
  2160.     LXI    H,BSWARM
  2161.     MVI    B,12
  2162.     CALL    MOVE
  2163.     JMP    F121    ;CALL 1.2.1 FIX FOR MBASIC    1.1.2
  2164. ;
  2165. MOVE:
  2166.     MOV    A,M    ;MOVE STRING FROM (HL) TO (DE) FOR LENGTH IN B
  2167.     INX    H
  2168.     STAX    D
  2169.     INX    D
  2170.     DCR    B
  2171.     JNZ    MOVE
  2172.     RET
  2173. ;
  2174. PMSG:
  2175.     PUSH    H
  2176.     LDA    IPSUPFL    ;COMBINE PSUPFL AND IPSUPFL TO SET PRINT FLAG
  2177.     ORA    A    ;0=NO SUPPRESS
  2178.     JZ    PMSG0
  2179.     MVI    B,01H    ;MESSAGE OFFSET TO IF FLAG
  2180.     CALL    GETZ3MSG    ;PT TO IF FLAG
  2181.     MOV    A,M    ;GET IF FLAG
  2182.     ORA    A    ;NO IF?
  2183.     JZ    PMSG0
  2184.     INX    H
  2185.     ANA    M    ;SET IF STATE
  2186.     POP    H    ;IN CASE OF RETURN
  2187.     RZ        ;SKIP MESSAGE IF SUPPRESSED
  2188.     PUSH    H
  2189. PMSG0:
  2190.     POP    H
  2191.     LDA    MSUPFL    ;PRINT MESSAGE AT (HL)
  2192.     CPI    MSUP    ;MESSAGES SUPPRESSED?
  2193.     RZ        ;YES..EXIT
  2194. PMSGL:
  2195.     MOV    A,M    ;GET NEXT CHAR
  2196.     ORA    A    ;END OF MESSAGE?
  2197.     RZ        ;YES..EXIT
  2198.     INX    H    ;PT TO NEXT CHAR
  2199.     PUSH    H    ;SAVE PTR
  2200.     MOV    C,A    ;OUTPUT CHAR
  2201.     CALL    BCONOT
  2202.     POP    H    ;RESTORE PTR
  2203.     JMP    PMSGL
  2204. ;
  2205. ;  REPLACE ZEX ROUTINE JUMPS WITH BIOS JUMPS
  2206. ;
  2207. F121:
  2208.     LXI    H,BSWARM    ; INSURE ONLY BIOS    1.1.2
  2209.     LXI    D,NWARM     ;  CALLS FROM NOW ON    1.1.2
  2210.     MVI    B,3        ;   FOR PROGRAMS    1.1.2
  2211.     CALL    MOVE        ;    THAT MAY HAVE    1.1.2
  2212.     LXI    H,BCONIN    ;     COPIED OUR    1.1.2
  2213.     LXI    D,NCONIN    ;      ADDRESSES AS    1.1.2
  2214.     MVI    B,3        ;    IF THEY WERE    1.1.2
  2215.     CALL    MOVE        ;     IN THE BIOS.    1.1.2
  2216.     LXI    H,BCONOT    ;  (MBASIC DOES THIS)    1.1.2
  2217.     LXI    D,NCONOT    ;            1.1.2
  2218.     MVI    B,3        ;            1.1.2
  2219.     JMP    MOVE        ;            1.1.2
  2220. ;
  2221. ;    WORKING STORAGE AREA
  2222. ;
  2223. ABORTD:
  2224.     DB    CR,LF,'[ZEX Aborted]',CR,LF,0
  2225. STARTM:
  2226.     DB    ' ZEX: ',0
  2227. DONEM:
  2228.     DB    'Done',0
  2229.  
  2230. ;
  2231.     REPT    12    ;12 ELT STACK
  2232.     DW    0
  2233.     ENDM
  2234. MEMTOP:
  2235.     DW    0
  2236. EXMBASE:
  2237.     DW    0
  2238. CCPJMP:
  2239.     DW    0
  2240. WARMPT:
  2241.     DW    0
  2242. ;
  2243. ;    ORIGINAL BIOS JMP TABLE
  2244. ;
  2245. BSWARM:
  2246.     JMP    $
  2247. BCONST:
  2248.     JMP    $
  2249. BCONIN:
  2250.     JMP    $
  2251. BCONOT:
  2252.     JMP    $
  2253. ;
  2254. PMCHR:
  2255.     DB    0
  2256. PSUPFL:
  2257.     DB    0
  2258. IPSUPFL:
  2259.     DB    0
  2260. OUTFLG:
  2261.     DB    0
  2262. NUICH:
  2263.     DB    0
  2264. IMFLG:
  2265.     DB    0
  2266. MSUPFL:
  2267.     DB    0
  2268. CONSTK:
  2269.     DW    0
  2270. ;
  2271. ?PLEN    SET    $
  2272.     IF (?PLEN MOD 8) GT 0
  2273. ?PLEN    SET    (?PLEN AND 0FFF8H)+8;GET NEXT BOUNDARY
  2274.     ENDIF
  2275. ;
  2276. DRVERL    EQU    ?PLEN
  2277. ;
  2278. DRVL8    EQU    DRVERL/8    ;LENGTH OF RELOCATION BIT MAP
  2279.     ORG    DRVERL
  2280. ;
  2281.     ENDIF
  2282. ;
  2283. ;    END OF ZEX RELOCATED CODE SEGMENT
  2284. ;
  2285.     END
  2286.