home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR2 / ZEX.AQM / ZEX.ASM
Assembly Source File  |  2000-06-30  |  46KB  |  2,210 lines

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