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 / SUBMIT / EX15.LBR / EX15.AQM / EX15.ASM
Assembly Source File  |  2000-06-30  |  26KB  |  1,310 lines

  1. ;
  2. ;   EX15.ASM - An enhanced version of EXEC and EX.
  3. ;
  4. ;   START   05-09-82
  5. ;
  6. ;   DATE    10-19-84  *LAST MAJOR CHANGE
  7. ;
  8. ;   HISTORY:
  9. ;
  10. ;   1.5     10-19-84  Modified NWARM and NCONOT to allow execution of
  11. ;                     EX under other system extensions such as Jim
  12. ;                     Lopushinski's LBRDISK
  13. ;
  14. ;   1.4     11-20-82  fix for 1.3 modification to put CP/M serial # on
  15. ;              a page boundary and refresh it on warm starts.
  16. ;                   (Some programs are not subtracting 6 from the
  17. ;              BDOS+1 location when calculating high memory,
  18. ;              MBASIC is one of these)
  19. ;
  20. ;   1.3     11-07-82  fix for software that expects CP/M serial # below
  21. ;              BDOS JMP address.
  22. ;
  23. ;   1.2.1   09-16-82  fix for MBASIC execution under EX 1.2 .
  24. ;
  25. ;   1.2     08-11-82  added '^:' EX runtime re-execute logic function,
  26. ;                '^?' EX runtime wait for carriage return,
  27. ;                logic to prevent input/EX buffer overlap,
  28. ;                logic to insure (Xsub Already Present),
  29. ;                logic to prevent EX runtime recursion loop,
  30. ;            and prompt character logic       [Larry Steeger]
  31. ;
  32. ;   1.1     08-06-82  added ';;' EX comment's support,
  33. ;                '^.' print suppression function,
  34. ;                '^<...^>' immediate display support,
  35. ;                '^#' EX message suppression function,
  36. ;                '^$' default parameter support,
  37. ;            and '^|' cr,lf generation function [Larry Steeger]
  38. ;
  39. ;   1.0     08-03-82  corrected $^ error and ^<lowercase> error [Larry Steeger]
  40. ;
  41. ;   ?        06-19-82  added missing TRUE and FALSE equates [Ron Fowler]
  42. ;
  43. ;   ?        05-17-82  corrected last cold boot no active message
  44. ;
  45. DATE    EQU    1122H    ;SET UP DATE
  46. YEAR    EQU    82H    ;SET UP YEAR
  47. MARK    EQU    1    ;SET MARK
  48. VERS    EQU    5    ;SET VERSION
  49. ;
  50. ;    EX15.COM is an enhancement of EXEC.COM and EX.COM
  51. ;
  52. ;    Options:
  53. ;
  54. ;    EX <subfile> <parameters> cr
  55. ;
  56. ;    EX cr
  57. ;
  58. ;     ^<?> will give control character <?>
  59. ;
  60. ;     | will be CR
  61. ;
  62. ;     ^| will be CR,LF
  63. ;
  64. ;     ^: will cause EX to re-execute the .SUB file from the beginning
  65. ;
  66. ;     ^? will cause EX to wait for a Carriage Return
  67. ;        (^C will abort EX at this point also)
  68. ;
  69. ;     ^$ will cause the rest of the line to be treated as a
  70. ;        set of default parameters separated by blanks to be
  71. ;        used if the user has not provided one on EX's command line.
  72. ;
  73. ;     ^# will toggle print suppression of EX messages
  74. ;
  75. ;     ^. will start print suppression of all characters
  76. ;        from .SUB file until a subsequent ^. is encountered
  77. ;
  78. ;     ;; will indicate that the ;; and all characters following it
  79. ;        until a LF is encountered are not included in EX's
  80. ;        text buffer
  81. ;        (i.e. an EX only comment)
  82. ;
  83. ;     ^<  will start immediate display of characters from
  84. ;        the .SUB file until ^> is encountered
  85. ;        (i.e. display only .SUB input)
  86. ;
  87. ;     $<1-9> will replace parameter<1-9> in text from the command line
  88. ;
  89. ;     $$ will give $
  90. ;
  91. ;     $^ will give ^
  92. ;
  93. ;     $| will give |
  94. ;
  95. ;     |,CR,LF,1AH will eat last from | to end of buffer
  96. ;
  97. ;     ^C from console will abort EX
  98. ;
  99. FALSE    EQU    0
  100. TRUE    EQU    NOT FALSE
  101. ;
  102. DAY0    SET    (DATE AND 0FH)+'0'
  103. DAY1    SET    ((LOW DATE) SHR 4)+'0'
  104. MONTH0    SET    ((HIGH DATE)AND 0FH)+'0'
  105. MONTH1    SET    (DATE SHR 12)+'0'
  106. ;
  107. YEAR0    SET    (YEAR AND 0FH)+'0'
  108. YEAR1    SET    (YEAR SHR 4)+'0'
  109. ;
  110. MARK0    SET    MARK+'0'
  111. VERS0    SET    VERS+'0'
  112. ;
  113. BELL    EQU    7
  114. CR    EQU    0DH
  115. LF    EQU    0AH
  116. ;
  117. PSUP    EQU    80H    ;^. PRINT SUPPRESS FLAG
  118. IMON    EQU    81H    ;^< IMMEDIATE MODE START
  119. IMOFF    EQU    82H    ;^> IMMEDIATE MODE STOP
  120. MSUP    EQU    83H    ;^# EX MESSAGE SUPPRESS FLAG
  121. CRWAIT    EQU    84H    ;^? EX RUNTIME WAIT FOR CR FLAG
  122. REXEC    EQU    85H    ;^: EX RUNTIME RE-EXECUTE FLAG
  123. ;JMPMON  EQU     0FEH     ;^; EX JMP TO SYSTEM MONITOR
  124. ;
  125. WARM    EQU    0
  126. BDISK    EQU    4
  127. BDOS    EQU    5
  128. DFCB    EQU    5CH
  129. DBUFF    EQU    80H
  130. ;
  131. ;    NOTE: EX15.LIB IS CREATED BY THE EX14.SUB GENERATION PROCESS
  132. ;
  133.     MACLIB    EX15
  134. ;
  135. $-PRINT
  136.     IF    BASE
  137. $+PRINT
  138. ;
  139. ;    START OF EX INITIATOR CODE SEGMENT
  140. ;
  141.     ORG    100H
  142. ;
  143. START:    LXI    H,0
  144.     DAD    SP
  145.     SHLD    CCPSTK        ; CCP Stack Ptr
  146.     LXI    SP,BEGREL    ; User stack area
  147.     MVI    A,0C9H        ; (8080 RET)
  148.     STA    START        ; Prevent re-entrance by ZCPR
  149.     LXI    D,SIGNON    ; Logo
  150.     CALL    PRINT
  151.     CALL    EXACTV        ; Check for recursion
  152.     LHLD    RELOCL        ; Get reloc program length
  153.     PUSH    H
  154.     POP    B
  155.     PUSH    B        ; Save length for future use
  156.     LHLD    BDOS+1        ; Get base
  157.     LXI    D,-806H     ; Get before CCP
  158.     DAD    D
  159.     MOV    A,L        ; Subtract reloc length
  160.     SUB    C
  161.     MOV    E,A
  162.     MOV    A,H
  163.     SBB    B
  164.     MOV    D,A
  165.     PUSH    D        ; Save new top/start to move to
  166.     LXI    H,BEGREL    ; Start of move
  167. OMOVE:    MOV    A,B
  168.     ORA    C
  169.     JZ    MOVEND
  170.     DCX    B
  171.     MOV    A,M
  172.     STAX    D
  173.     INX    D
  174.     INX    H
  175.     JMP    OMOVE
  176. ;
  177. MOVEND: POP    D        ; Get start of moved program
  178.     POP    B        ; Length of move program
  179.     PUSH    H        ; Start of bit map
  180.     MOV    H,D        ; MSB offset
  181.     MOV    L,E        ; LSB offset
  182. OFFLUP: MOV    A,B        ; Test length
  183.     ORA    C        ; If 0
  184.     JZ    GOTO        ; Jump to relocated program
  185.     DCX    B        ; Decrement count
  186.     LDA    COUNT
  187.     INR    A
  188.     STA    COUNT
  189.     ANI    07H
  190.     JNZ    OFFBIT        ; No
  191.     XTHL            ; Yes, get bit map
  192.     MOV    A,M        ; Get next byte
  193.     INX    H        ; Increment bit map pointer
  194.     XTHL            ; Save for later
  195.     STA    BITMAP        ; Keep bit offset
  196. OFFBIT: LDA    BITMAP
  197.     RAL            ; Test for offset
  198.     STA    BITMAP        ; Save new byte
  199.     JNC    NOFSET        ; No
  200.     DCX    D        ; Get back to LSB
  201.     LDAX    D
  202.     ADD    L
  203.     STAX    D
  204.     INX    D        ; MSB
  205.     LDAX    D        ; Yes
  206.     ADC    H        ; Add in offset
  207.     STAX    D        ; Put in moved place
  208. NOFSET: INX    D        ; Increment moved pointer
  209.     JMP    OFFLUP        ; Continue with relocate
  210. ;
  211. GOTO:    POP    D        ; Restore stack
  212.     DCX    H        ; Relocate program-1
  213.     PUSH    H        ; Save to use in relocated program
  214.     SHLD    OUTBUF
  215.     INX    H        ; Get to beginning of relocated program
  216.     PUSH    H
  217.     LXI    D,DBUFF+1    ; Terminate command line with CR
  218.     PUSH    D
  219.     LDA    DBUFF
  220.     MOV    L,A
  221.     MVI    H,0
  222.     DAD    D
  223.     MVI    M,CR
  224.     LXI    H,PRMDMY    ; Start at dummy parameter for .SUB file spec
  225.     PUSH    H
  226.     LXI    B,PRMPNL+2
  227.     XRA    A
  228.     CALL    FILL        ; Clear ptr area
  229.     POP    H
  230.     POP    D
  231.     MVI    A,(PRMPNL/2)+1
  232.     STA    PRMMAX        ; Highest parameter # + 1 for .SUB spec
  233.     CALL    PARMS        ; Build pointers for command line parms
  234.     LDA    DBUFF        ; See if .SUB file present
  235.     ORA    A
  236.     JNZ    OPENSB        ; Open sub file
  237.     LXI    H,0
  238.     SHLD    LINES        ; Start line counter
  239.     MVI    A,7FH        ; Get buffer length
  240.     STA    DBUFF-1
  241.     LXI    H,BEGREL    ; Set up output buffer
  242.     SHLD    INBUF
  243. GETLIN: CALL    CRLF
  244.     LHLD    LINES
  245.     INX    H
  246.     SHLD    LINES
  247.     CALL    DECOUT        ; Print line #
  248.     MVI    E,':'        ; Get prompt
  249.     CALL    OUTCHR
  250.     MVI    E,' '
  251.     CALL    OUTCHR
  252.     LXI    D,DBUFF-1
  253.     MVI    C,10        ; Read console buffer
  254.     CALL    BDOS
  255.     LXI    D,DBUFF
  256.     LDAX    D        ; Get length
  257.     MOV    B,A
  258.     INX    D
  259.     LHLD    INBUF        ; Get input pointer
  260.     ORA    A        ; See if end
  261.     JZ    ENDSTR        ; Thats all folks
  262.     XCHG
  263.     CALL    MOVE        ;MOVE TO INPUT BUFFER
  264.     XCHG
  265.     MVI    M,CR
  266.     INX    H
  267.     MVI    M,LF
  268.     INX    H
  269.     SHLD    INBUF
  270.     JMP    GETLIN
  271. ;
  272. OPENSB:    LDA    DFCB+9
  273.     CPI    ' '
  274.     JNZ    OPNSB1
  275.     LXI    D,DFCB+9
  276.     LXI    H,SUBNAM    ; Move 'SUB' to DFCB file type
  277.     MVI    B,3
  278.     CALL    MOVE
  279. OPNSB1:    XRA    A
  280.     STA    DFCB+32
  281.     LXI    D,DFCB
  282.     MVI    C,15        ; Open file
  283.     CALL    BDOS
  284.     INR    A
  285.     JNZ    READTX
  286.     LXI    H,NOSBF2
  287.     LXI    D,DFCB+1
  288.     MVI    B,8        ; Name length
  289.     CALL    MOVEFN        ; Move file name
  290.     MVI    B,3        ; Type length
  291.     MVI    M,'.'
  292.     INX    H
  293.     LXI    D,DFCB+9    ; File type pointer
  294.     CALL    MOVEFN        ; Move file type
  295.     MVI    M,'$'        ; End terminator
  296.     JMP    NOSUB
  297. ;
  298. READTX: LHLD    INBUF
  299.     XCHG
  300.     LXI    H,80H        ; Get sector offset
  301.     DAD    D
  302.     SHLD    INBUF
  303.     MVI    C,26        ; Set DMA address
  304.     CALL    BDOS
  305.     LXI    D,DFCB
  306.     MVI    C,20        ; Read sequential
  307.     CALL    BDOS
  308.     ORA    A
  309.     JZ    READTX        ; Read complete .SUB file
  310.     LHLD    INBUF        ; Make sure buffer's terminated
  311.     LXI    D,-80H        ; Get back to end
  312.     DAD    D
  313. ENDSTR: MVI    M,1AH        ; EOF character
  314.     SHLD    ENDBUF        ; EOB address
  315.     MOV    A,L
  316.     SUI    LOW BEGREL+1    ; See if buffer's empty
  317.     MOV    A,H
  318.     SBI    HIGH BEGREL
  319.     JC    BUFLOW
  320.     XRA    A
  321.     STA    IMFLG1
  322.     STA    IMFLG2
  323.     STA    PRTFLG
  324.     STA    OUTCNT
  325.     LXI    H,1
  326.     SHLD    LINES
  327.     LHLD    OUTBUF
  328.     SHLD    OUTLNE
  329.     SHLD    BUFSTR
  330.     LXI    D,BEGREL
  331. MOVSTR: LDAX    D
  332.     INX    D
  333.     ANI    7FH        ; Make sure no parity
  334.     CPI    LF
  335.     JNZ    MOVST0
  336. MOVSTX: CALL    INCR
  337.     JMP    MOVSTR
  338. ;
  339. MOVST0: CPI    1AH
  340.     JZ    SETUP
  341.     CPI    '|'        ; Carriage Return
  342.     JNZ    MOVST1        ; Nope
  343.     PUSH    D        ; Save old pointer
  344.     INX    D
  345.     INX    D
  346.     LDAX    D        ; Get present location+3
  347.     POP    D        ; Get old pointer
  348.     CPI    1AH        ; End of buffer
  349.     JZ    SETUP        ; Thats all she wrote
  350.     MVI    A,CR
  351.     CALL    INCR        ; Increment lines for errors
  352.     JMP    MOVST4
  353. ;
  354. MOVST1: MOV    C,A
  355.     LDA    IMFLG1
  356.     CPI    IMON        ; Immediate mode on ?
  357.     MOV    A,C
  358.     JZ    MOVST2        ; Yes..skip EX comment processing
  359.     CPI    ';'
  360.     JZ    EXCOMM        ; Process possible EX comment
  361. MOVST2: CPI    '^'
  362.     JZ    MOVST5        ; Convert control characters
  363.     CPI    '$'
  364.     CZ    GTPARM        ; Substitute command parameter or control char
  365. MOVST3: STA    LCHR
  366.     CPI    CR        ; = CR?
  367.     JNZ    MOVST4
  368.     MOV    C,A
  369.     LDA    OUTCNT
  370.     ORA    A        ; Any char?
  371.     MOV    A,C
  372.     JZ    MOVSTR        ; No..use input CR only if other non-control
  373.                 ; ... characters in current line
  374. MOVST4: CALL    CHRSTR        ; Add to buffer
  375.     CALL    CNTINC        ; Increment count
  376.     JMP    MOVSTR
  377. ;
  378. MOVST5: CALL    GETCMD        ; Validate control characters
  379.     CPI    ':'
  380.     JZ    REXC        ; Re-execute
  381. ;    CPI    ';'
  382. ;    JZ    JMPMN        ; JMP to monitor
  383.     CPI    '?'
  384.     JZ    GCRW        ; CR wait
  385.     CPI    '|'
  386.     JZ    GCRLF        ; CR,LF generation
  387.     CPI    '$'
  388.     JZ    PRMDEF        ; Default parameters' line
  389.     CPI    '.'
  390.     JZ    PRTSUP        ; Print suppress toggle
  391.     CPI    '#'
  392.     JZ    MSGSUP        ; Message suppress toggle
  393.     CPI    '<'
  394.     JZ    IMPRTY        ; Immediate mode start
  395.     CPI    '>'
  396.     JZ    IMPRTN        ; Immediate mode stop
  397.     JMP    MOVST3        ; Other control codes
  398. ;
  399. REXC:    MVI    A,REXEC     ; Convert '^:' to re-execute flag
  400.     JMP    MOVST3
  401. ;
  402. ;JMPMN:  MVI     A,JMPMON     ; Convert '^;' to JMP to Monitor flag
  403. ;     JMP     MOVST3
  404. ;
  405. GCRW:    MVI    A,CRWAIT    ; Convert '^?' to CRWAIT flag
  406.     JMP    MOVST3
  407. ;
  408. GCRLF:    MVI    A,CR        ; Generate CR & LF
  409.     CALL    CHRSTR
  410.     MVI    A,LF
  411.     CALL    CHRSTR
  412.     STA    LCHR
  413.     JMP    MOVSTR
  414. ;
  415. PRMDEF: PUSH    H
  416.     LXI    H,PRMDFP
  417.     PUSH    H
  418.     LXI    B,PRMDFL
  419.     XRA    A
  420.     CALL    FILL        ; Clear ptr table
  421.     POP    H
  422.     MVI    A,PRMDFL/2
  423.     STA    PRMMAX        ; Highest parameter #
  424.     CALL    PARMS        ; Build default parameters ptrs
  425.     POP    H
  426.     INX    D        ; Skip CR
  427.     MVI    A,LF
  428.     JMP    MOVSTX        ; Continue at EOL
  429. ;
  430. EXCOMM: PUSH    H
  431.     LXI    H,LCHR
  432.     CMP    M        ; Double ;?
  433.     MOV    M,A
  434.     POP    H
  435.     JNZ    MOVST3        ; No...continue
  436.     MOV    C,A
  437.     LDA    PRTFLG
  438.     CPI    PSUP
  439.     MOV    A,C
  440.     JZ    MOVST3        ; Print suppress
  441.     LDA    IMFLG1
  442.     CPI    IMON
  443.     MOV    A,C
  444.     JZ    MOVST3        ; Immediate mode
  445.     INX    H        ; Yes..ignore previous ;
  446.     PUSH    H
  447.     LXI    H,LCHR
  448.     LDA    OUTCNT
  449.     DCR    A        ; Drop 1 char
  450.     STA    OUTCNT
  451. EXCOML: LDAX    D        ; Ignore characters until EOF or LF
  452.     INX    D
  453.     CPI    1AH        ; EOF
  454.     JZ    EXCOMX
  455.     CPI    LF        ; Line Feed
  456.     JNZ    EXCOML
  457.     MOV    M,A
  458.     LDA    OUTCNT
  459.     ORA    A        ; Any char on this line?
  460.     JZ    EXCOM2        ; No...skip CR
  461. EXCOM1: POP    H        ; Yes..force CR
  462.     MVI    A,CR
  463.     CALL    CHRSTR
  464.     MVI    A,LF
  465.     JMP    MOVSTX        ; Continue
  466. ;
  467. EXCOM2: POP    H
  468.     MVI    A,LF
  469.     JMP    MOVSTX        ; Continue
  470. ;
  471. EXCOMX: POP    H
  472.     JMP    SETUP
  473. ;
  474. MSGSUP: MVI    A,MSUP        ; Convert '^#' to Message Suppress Flag
  475.     JMP    MOVST3
  476. ;
  477. PRTSUP: MVI    A,PSUP        ; Convert '^.' to Print Suppress Flag
  478.     PUSH    H
  479.     LXI    H,PRTFLG
  480.     CMP    M        ; Already on?
  481.     JNZ    PRTSST        ; No...set flag
  482.     XRA    A        ; Yes..clear flag
  483. PRTSST: MOV    M,A        ; Set/reset flag
  484.     POP    H
  485.     MVI    A,PSUP
  486.     JMP    MOVST3
  487. ;
  488. IMPRTY: MVI    A,IMON        ; Convert '^<' to immediate mode start
  489.     STA    LCHR
  490.     PUSH    H
  491.     LXI    H,IMFLG1
  492.     CMP    M        ; Already on?
  493.     POP    H
  494.     JZ    MOVSTR        ; Yes..
  495.     STA    IMFLG1
  496.     STA    IMFLG2
  497.     JMP    MOVST3        ; No...
  498. ;
  499. IMPRTN: MVI    A,IMOFF     ; Convert '^>' to Immediate Mode Stop
  500.     STA    LCHR
  501.     PUSH    H
  502.     LXI    H,IMFLG2
  503.     CMP    M        ; Already off?
  504.     POP    H
  505.     JZ    MOVSTR        ; Yes..
  506.     STA    IMFLG2
  507.     STA    IMFLG1
  508.     JMP    MOVST3        ; No...
  509. ;
  510. CHRSTR: PUSH    PSW        ; Check for input/ex buffer overlap
  511.     PUSH    D
  512.     PUSH    H
  513.     LHLD    ENDBUF
  514.     XCHG
  515.     POP    H
  516.     MOV    A,L
  517.     CMP    E
  518.     JNZ    CHRSTX        ; LSB<>
  519.     MOV    A,H
  520.     CMP    D
  521.     JZ    OVERL        ; MSB =, overlap will occur; abort EX
  522. ;
  523. CHRSTX: POP    D        ; Add char to EX's buffer
  524.     POP    PSW
  525.     MOV    M,A
  526.     DCX    H
  527.     RET
  528. ;
  529. EXACTV: LHLD    BDOS+1        ; Check for EX recursion
  530.     INX    H
  531.     INX    H
  532.     INX    H        ; Skip 1st jump
  533.     MVI    A,'E'
  534.     CMP    M
  535.     RNZ            ; Not 'E'
  536.     INX    H
  537.     MVI    A,'X'
  538.     CMP    M
  539.     RNZ            ; Not 'X'
  540.     INX    H
  541.     MVI    A,0FFH
  542.     CMP    M
  543.     RNZ            ; Not 0FFH
  544.     LXI    D,EXACT
  545.     CALL    PRINT        ; EX already present
  546. CCPRET: LHLD    CCPSTK
  547.     SPHL
  548.     LDA    4
  549.     RET            ; Return to CCP
  550. ;
  551. SETUP:    MVI    M,0FFH        ; Setup end of data
  552.     DCX    H
  553.     MVI    M,0FFH
  554.     MOV    A,L        ; Setup EX recur ID, XSUB present, & CP/M S/N
  555.     CPI    11        ; 12 bytes on this page?
  556.     JNC    SETUP1        ; Yes..OK
  557.     DCR    H        ; No...drop down 1 page
  558. SETUP1: MVI    L,11        ; Force page boundary for CP/M S/N
  559.     MVI    M,0FFH        ; Setup EX recursion ID
  560.     DCX    H
  561.     MVI    M,'X'
  562.     DCX    H
  563.     MVI    M,'E'
  564.     DCX    H
  565.     LDA    BDOS+2        ; Set up BDOS jump to protect data
  566.     MOV    M,A
  567.     DCX    H
  568.     LDA    BDOS+1
  569.     MOV    M,A
  570.     DCX    H
  571.     MVI    M,JMP
  572.     PUSH    H
  573.     LXI    D,-6
  574.     DAD    D        ; Ptr to pseudo CP/M serial #
  575.     PUSH    H
  576.     LHLD    BDOS+1
  577.     DAD    D        ; Ptr to real CP/M serial #
  578.     POP    D
  579.     MVI    B,6
  580.     CALL    MOVE        ; Setup CP/M serial #
  581.     POP    H
  582.     XTHL            ; Get jump address; save top of memory
  583. ;
  584. ;    (SP)    Top of Memory Address
  585. ;    (SP+2)    Start of Buffer Address
  586. ;
  587.     PCHL            ; GOTO it
  588. ;
  589. ;    ERROR EXITS
  590. ;
  591. GETERR: LXI    D,CMDER     ; Control character invalid
  592.     CALL    PRINT
  593.     JMP    LINE        ; Print line # and line and exit
  594. ;
  595. NODEFP: LXI    D,NOPRM     ; Unknown parameter
  596.     CALL    PRINT
  597.     JMP    LINE        ; Print line # and line and exit
  598. ;
  599. PRMERR: LXI    D,PMERR
  600.     CALL    PRINT
  601.     JMP    LINE        ; Print line # and line and exit
  602. ;
  603. PRMTOO: LXI    D,TOOARG    ; Too many parameter arguments
  604.     CALL    PRINT
  605.     LHLD    ERRLNE
  606.     CALL    EPRT        ; Print parameter line
  607.     JMP    CCPRET
  608. ;
  609. BUFLOW: LXI    D,BUFMTY    ; Text buffer empty
  610.     CALL    PRINT
  611.     JMP    CCPRET
  612. ;
  613. NOSUB:    LXI    D,NOSBF1    ; .SUB file not found
  614.     CALL    PRINT
  615.     LXI    D,NOTHER
  616.     CALL    PRINT
  617.     JMP    CCPRET
  618. ;
  619. OVERL:    LXI    D,OVERLP    ; Input/EX buffer overlap
  620.     CALL    PRINT
  621.     JMP    LINE
  622. ;
  623. ;    SUBROUTINES
  624. ;
  625. ;    CONTROL CODES 0-1FH
  626. ;    WITH SUPPORT FOR $ . # < >
  627. ;
  628. GETCMD: LDAX    D        ; Get next character
  629.     INX    D        ; Increment pointer
  630.     CPI    '|'
  631.     RZ            ; CR,LF generation
  632.     CPI    'a'-1        ; Lowercase?
  633.     JC    GETUPR        ; Nope
  634.     CPI    'z'+1        ; a-z?
  635.     JNC    GETERR        ; Nope
  636.     sui    'a'-'A'     ; Get to uppercase
  637. GETUPR: CPI    '@'        ; 0-1FH control code?
  638.     JNC    GETCC
  639. ;    CPI    ';'
  640. ;    RZ            ; JMP to monitor
  641.     CPI    ':'
  642.     RZ            ; Re-execute
  643.     CPI    '?'
  644.     RZ            ; CR wait
  645.     CPI    '$'
  646.     RZ            ; Default parameters' line
  647.     CPI    '.'
  648.     RZ            ; Print suppress toggle
  649.     CPI    '#'
  650.     RZ            ; Message suppress toggle
  651.     CPI    '<'
  652.     RZ            ; Immediate mode start
  653.     CPI    '>'
  654.     RZ            ; Immediate mode stop
  655.     JMP    GETERR
  656. GETCC:    SUI    40H        ; Get control code
  657.     RNC
  658.     JMP    GETERR
  659. ;
  660. GTPARM: LDAX    D
  661.     INX    D
  662.     CPI    '$'
  663.     RZ
  664.     CPI    '^'        ; Up arrow
  665.     RZ
  666.     CPI    '|'        ; Carriage Return
  667.     RZ
  668.     CPI    '1'
  669.     JC    PRMERR
  670.     CPI    '9'+1
  671.     JNC    PRMERR
  672.     SUI    '1'        ; Get actual # (zero relative)
  673.     ADD    A        ; Double for offset
  674.     STA    PRMNUM
  675.     PUSH    D
  676.     PUSH    H
  677.     LXI    H,PRMPNT
  678.     CPI    PRMPNL-1
  679.     JNC    NOPARM        ; > highest #
  680.     MOV    E,A
  681.     MVI    D,0
  682.     DAD    D
  683.     MOV    E,M        ; Get parameter pointer
  684.     INX    H
  685.     MOV    D,M
  686.     POP    H
  687.     MOV    A,E
  688.     ORA    D
  689.     JZ    NOPARM        ; No parameter present, try defaults
  690. MOVPRM: LDAX    D        ; Move parameter to buffer
  691.     INX    D
  692.     ORA    A
  693.     JZ    ENDPAR
  694.     MOV    M,A
  695.     DCX    H
  696.     JMP    MOVPRM
  697. ;
  698. ENDPAR: POP    D
  699.     INX    H
  700.     MOV    A,M
  701.     RET
  702. ;
  703. NOPARM: PUSH    H
  704.     LXI    H,PRMDFP    ; Try default parameters
  705.     LDA    PRMNUM
  706.     CPI    PRMDFL-1
  707.     JNC    NODEFP        ; > highest #
  708.     MOV    E,A
  709.     MVI    D,0
  710.     DAD    D
  711.     MOV    E,M        ; Get parameter pointer
  712.     INX    H
  713.     MOV    D,M
  714.     POP    H
  715.     MOV    A,E
  716.     ORA    D
  717.     JZ    NODEFP        ; No parameter present
  718.     JMP    MOVPRM        ; Move parameter to buffer
  719. ;
  720. MOVEFN: LDAX    D
  721.     CPI    ' '        ; See if space
  722.     RZ
  723.     MOV    M,A
  724.     INX    D        ; Increment pointers
  725.     INX    H
  726.     DCR    B
  727.     JNZ    MOVEFN
  728.     RET
  729. ;
  730. INCR:    PUSH    H        ; Save output pointer
  731.     LHLD    LINES
  732.     INX    H        ; Increment line counter
  733.     SHLD    LINES
  734.     LXI    H,LCHR        ; Clear last character
  735.     MVI    M,0
  736.     LXI    H,OUTCNT    ; Clear character count
  737.     MVI    M,0
  738.     MOV    L,E        ; DE = HL
  739.     MOV    H,D
  740.     SHLD    BEGLIN
  741.     POP    H
  742.     SHLD    OUTLNE        ; Save new output line
  743.     RET
  744. ;
  745. CNTINC: CPI    ' '        ; Control character?
  746.     RC            ; Yes..
  747.     ANI    80H        ; Special control?
  748.     RNZ            ; Yes..
  749.     LDA    PRTFLG
  750.     CPI    PSUP        ; Print suppress flag?
  751.     RZ            ; Yes..
  752.     LDA    IMFLG1
  753.     CPI    IMON        ; Immediate mode?
  754.     RZ            ; Yes..
  755.     LDA    OUTCNT
  756.     INR    A
  757.     STA    OUTCNT
  758.     RET
  759. ;
  760. PARMS:    MVI    B,0        ; Clear parameter counter
  761.     XCHG
  762.     SHLD    ERRLNE        ; Save in case of error
  763.     XCHG
  764. ;
  765. PARMSL: LDAX    D        ; Ignore leading spaces
  766.     INX    D
  767.     CPI    CR
  768.     JZ    ENDLNE
  769.     CPI    ' '
  770.     JZ    PARMSL
  771.     DCX    D
  772.     MOV    M,E
  773.     INX    H
  774.     MOV    M,D
  775.     INX    H
  776.     INX    D
  777.     INR    B        ; Count + 1
  778.     LDA    PRMMAX
  779.     CMP    B
  780.     JC    PRMTOO        ; Too many arguments
  781. ;
  782. ENDPRM: LDAX    D        ; Get to end of parameter
  783.     INX    D
  784.     CPI    CR
  785.     JZ    ENDLNE
  786.     CPI    ' '
  787.     JNZ    ENDPRM
  788.     XRA    A
  789.     DCX    D
  790.     STAX    D        ; Terminate parameter
  791.     INX    D
  792.     JMP    PARMSL        ; Ignore spaces between parameters
  793. ENDLNE: XRA    A
  794.     DCX    D
  795.     STAX    D        ; Terminate last parameter
  796.     INX    D
  797.     MVI    A,CR
  798.     STAX    D
  799.     RET
  800. ;
  801. PRINT:    MVI    C,9        ; Print string at (DE)
  802.     CALL    BDOS
  803.     RET
  804. ;
  805. EPRT:    MOV    A,M        ; Print parameter line at (HL)
  806.     CPI    CR
  807.     RZ
  808.     CPI    0
  809.     JNZ    EPRT1
  810.     MVI    A,' '
  811. EPRT1:    INX    H
  812.     PUSH    H
  813.     MOV    E,A
  814.     MVI    C,2
  815.     CALL    BDOS
  816.     POP    H
  817.     JMP    EPRT
  818. ;
  819. CRLF:    LXI    D,CRLFS     ; Print CR/LF
  820.     CALL    PRINT
  821.     RET
  822. ;
  823. LINE:    LXI    D,LINEM     ; Print line # and line in error and exit
  824.     CALL    PRINT
  825.     LHLD    LINES
  826.     CALL    DECOUT        ; Print line #
  827.     CALL    CRLF
  828.     LHLD    BEGLIN
  829.     PUSH    H        ; Save beginning pointer
  830. FINDCR: MOV    A,M
  831.     INX    H
  832.     CPI    1AH        ; End of buffer
  833.     JZ    FOUND
  834.     CPI    CR
  835.     JNZ    FINDCR
  836. FOUND:    MVI    M,0        ; End of string
  837.     POP    H        ; Start of string
  838.     CALL    PRNTHL        ; Print bad line
  839.     JMP    CCPRET        ; Thats all folks
  840. ;
  841. PRNTHL: MOV    A,M        ; Print line at (HL)
  842.     INX    H
  843.     ORA    A
  844.     RZ
  845.     MOV    E,A
  846.     PUSH    H        ; Save pointer
  847.     CALL    OUTCHR
  848.     POP    H        ; Get pointer back
  849.     JMP    PRNTHL
  850. ;
  851. OUTCHR: MVI    C,2        ; Print character in E
  852.     JMP    BDOS
  853. ;
  854. DECOUT: PUSH    H        ; Print decimal line number
  855.     PUSH    D
  856.     PUSH    B
  857.     LXI    B,-10        ; Radix for conversion
  858.     LXI    D,-1        ; This becomes no divided by radix
  859. DX:    DAD    B        ; Subtract 10
  860.     INX    D
  861.     JC    DX
  862.     LXI    B,10
  863.     DAD    B        ; Add radix back in once
  864.     XCHG
  865.     MOV    A,H
  866.     ORA    L        ; Test for zero
  867.     CNZ    DECOUT        ; Recursive call
  868.     MOV    A,E
  869.     ADI    '0'        ; Convert from BCD to HEX
  870.     MOV    E,A        ; To E for output
  871.     MVI    C,2
  872.     CALL    BDOS
  873.     POP    B        ; Restore registers
  874.     POP    D
  875.     POP    H
  876.     RET
  877. ;
  878. MOVE:    MOV    A,M        ; Move string at (HL) to (DE) for length in B
  879.     INX    H
  880.     STAX    D
  881.     INX    D
  882.     DCR    B
  883.     JNZ    MOVE
  884.     RET
  885. ;
  886. FILL:    PUSH    D        ; Fill storage at (HL) with character in A
  887.     MOV    E,A        ; For length in BC
  888.     MOV    A,B
  889.     ORA    C
  890.     MOV    A,E
  891.     POP    D
  892.     RZ
  893.     DCX    B
  894.     MOV    M,A
  895.     INX    H
  896.     JMP    FILL
  897. ;
  898. ;    WORKING STORAGE AREA
  899. ;
  900. SUBNAM: DB    'SUB'
  901. LINEM:    DB    ' error line # $'
  902. EXACT:    DB    CR,LF,'(Ex Already Present)$'
  903. BUFMTY    DB    CR,LF,'Text buffer empty$'
  904. OVERLP: DB    CR,LF,'Input/EX Buffer Overlap$'
  905. NOPRM:    DB    CR,LF,'No parameter or default parameter$'
  906. PMERR:    DB    CR,LF,'Parameter$'
  907. NOSBF1: DB    CR,LF,'File '
  908. NOSBF2: DB    'filename.typ$'
  909. NOTHER: DB    ' not there$'
  910. CMDER:    DB    CR,LF,'Control character$'
  911. TOOARG: DB    CR,LF,'Too many arguments - $'
  912. SIGNON: DB    'EX ',MARK0,'.',VERS0
  913.     DB    '   ',MONTH1,MONTH0,'-',DAY1,DAY0,'-',YEAR1,YEAR0,'$'
  914. CRLFS:    DB    CR,LF,'$'
  915. ;
  916. CCPSTK: DW    0        ; CCP stack ptr
  917. IMFLG1: DB    0        ; = IMON encountered
  918. IMFLG2: DB    0        ; = IMOFF encountered
  919. PRTFLG: DB    0        ; = PSUP on
  920. LCHR:    DB    0        ; Last character read
  921. PRMMAX: DB    0        ; Highest parameter #
  922. PRMNUM: DB    0        ; Current $<1-9> number * 2 (zero relative)
  923. ERRLNE: DW    0
  924. BITMAP: DB    0        ; Present offset bit's
  925. COUNT:    DB    0FFH        ; Present offset bit count
  926. BEGLIN: DW    BEGREL        ; Beginning of old line pointer
  927. LINES:    DW    1
  928. INBUF:    DW    BEGREL
  929. ENDBUF: DW    0        ; End of input buffer
  930. OUTCNT: DB    0
  931. OUTLNE: DW    0
  932. OUTBUF: DW    0
  933. BUFSTR: DW    0
  934. RELOCL: DW    0        ; Length of reloc program (filled in by SID)
  935. PRMDFP:             ; Default parameter ptrs
  936.     REPT    9
  937.     DW    0
  938.     ENDM
  939.  
  940. PRMDFL    EQU    $-PRMDFP
  941. PRMDMY: DW    0        ; Dummy parameter for .SUB file spec
  942. PRMPNT:             ; Command line parameter ptrs
  943.     REPT    9
  944.     DW    0
  945.     ENDM
  946. PRMPNL    EQU    $-PRMPNT
  947. PATCH:                ; Patch area
  948.     REPT    32
  949.     DB    'p'
  950.     ENDM
  951.     REPT    30
  952.     DW    0
  953.     ENDM
  954. ;
  955. ;    Ensure 8 byte boundary for REL.UTL (RELS.UTL)
  956. ;
  957. ?PLOC    SET    $
  958.     IF    (?PLOC MOD 8) GT 0
  959. ?PLOC    SET    (?PLOC AND 0FFF8H)+8 ; Get next 8 byte boundary
  960.     ORG    ?PLOC
  961.     ENDIF
  962. ;
  963. BEGREL: DS    0    ; Reloc program starts here (also used as buffer)
  964. ;
  965.     ENDIF
  966. ;
  967. ;    End of EX initiator code segment
  968. ;
  969. $-PRINT
  970.     IF NOT    BASE
  971. $+PRINT
  972. ;
  973. ;    Start of EX relocated code segment
  974. ;
  975.     ORG    REL
  976. ;
  977. EX:    POP    H        ; Get top of memory
  978.     SHLD    MEMTOP
  979.     POP    H        ; Get start of buffer
  980.     SHLD    REVBUF
  981.     SHLD    SAVBUF
  982.     MOV    A,M
  983.     CPI    MSUP        ; 1st char = Message Suppress?
  984.     JNZ    EX1        ; No...
  985.     DCX    H        ; Yes..skip character
  986.     SHLD    REVBUF
  987.     STA    MSUPFL        ; Set initial flag
  988. EX1:    LXI    SP,MEMTOP
  989.     LHLD    WARM+1
  990.     SHLD    WARMPT
  991.     LXI    D,BSWARM
  992.     MVI    B,12
  993.     CALL    MOVE        ; Move BIOS jumps
  994.     LHLD    WARMPT
  995.     XCHG
  996.     LXI    H,LOCJMP
  997.     MVI    B,12
  998.     CALL    MOVE        ; Move new BIOS jumps to BIOS area
  999. ;
  1000. ;    EX RUNTIME BIOS INTERCEPT ROUTINES
  1001. ;
  1002. NWARM:    LXI    SP,MEMTOP
  1003.     LHLD    REVBUF        ; See if we're at buffers end
  1004.     MOV    A,M
  1005.     CPI    0FFH        ; Test it
  1006.     JZ    WARMR        ; Real warm start return
  1007.     MVI    A,0FFH        ; Set Warm Boot switch for reinit in
  1008.     STA    BOOTED        ; ... NCONOT routine
  1009.     LXI    H,STARTM    ; Tell user we're still here
  1010.     CALL    PMSG        ; ...
  1011.     JMP    BSWARM        ; Go do Warm Boot
  1012. ;
  1013. ;    JMP TABLE TO OVERLAY BIOS
  1014. ;
  1015. LOCJMP: JMP    NWARM        ; WARM
  1016.     JMP    BCONST        ; CONST
  1017.     JMP    NCONIN        ; CONIN
  1018.     JMP    NCONOT        ; CONOT
  1019. ;
  1020. ;    CONSOLE INPUT INTERCEPT ROUTINE
  1021. ;
  1022. NCONIN:
  1023.     LXI    H,0
  1024.     DAD    SP        ; Save return stack level
  1025.     SHLD    CONSTK
  1026.     LXI    H,MEMTOP    ; Set user stack
  1027. NCONNL: CALL    BCONST        ; Get console status
  1028.     ORA    A
  1029.     JZ    GETBUF        ; Get character from buffer
  1030.     CALL    BCONIN        ; Get character
  1031.     CPI    'C'-40H        ; See if terminate character
  1032.     JZ    EXABRT
  1033.     CPI    'S'-40H         ; 13H
  1034.     JNZ    NCONEX
  1035.     CALL    BCONIN        ; Wait for next character
  1036.     ANI    7FH
  1037.     LHLD    REVBUF
  1038.     INX    H
  1039.     MOV    M,A
  1040.     SHLD    REVBUF
  1041.     MVI    A,'S'-40H    ; 13H
  1042. NCONEX: LHLD    CONSTK        ; Restore caller's stack
  1043.     SPHL
  1044.     RET
  1045. ;
  1046. GETBUF: LDA    PSUPFL        ; Set Print Suppress flag for NCONOT
  1047.     STA    OUTFLG
  1048.     CALL    GETCHR        ; Get next character
  1049. ;    CPI    JMPMON        ; JMP to monitor?
  1050. ;    JZ    JPMON        ; Yes..do it
  1051.     CPI    REXEC        ; Re-execute?
  1052.     JZ    REXECR        ; Yes..reset buffer ptr
  1053.     CPI    CRWAIT        ; CR wait?
  1054.     JZ    CRWRTN        ; Yes..wait for CR
  1055.     CPI    MSUP        ; Message Suppress flag?
  1056.     JZ    MSUPCK        ; Yes..toggle flag
  1057.     CPI    PSUP        ; Print Suppress ?
  1058.     JZ    PSUPCK        ; Yes..toggle flag
  1059.     CPI    IMON        ; Immediate Mode start ?
  1060.     JZ    IMFLGS        ; Yes..set flag
  1061.     CPI    IMOFF        ; Immediate Mode stop?
  1062.     JZ    IMFLGS        ; Yes..reset flag
  1063.     CPI    CR        ; CR?
  1064.     JNZ    GETEXT        ; No...exit
  1065.     XRA    A
  1066.     STA    OUTFLG        ; Yes..reset Print Suppression
  1067.     MVI    A,CR
  1068. GETEXT: MOV    C,A
  1069.     LDA    IMFLG
  1070.     CPI    IMON        ; Immediate Mode ?
  1071.     MOV    A,C
  1072.     JNZ    NCONEX        ; No...return to caller with char
  1073.     CALL    BCONOT        ; Yes..immediate echo to console
  1074.     JMP    NCONNL        ; ... Loop until IMOFF
  1075. ;
  1076. REXECR: LHLD    SAVBUF        ; Start at top of buffer again
  1077.     SHLD    REVBUF
  1078.     XRA    A
  1079.     STA    IMFLG        ; Reset all flags
  1080.     STA    PSUPFL
  1081.     STA    MSUPFL
  1082.     JMP    NCONNL        ; ... Loop until ^C
  1083. ;
  1084. CRWRTN: CALL    BCONST        ; Wait for char
  1085.     JZ    CRWRTN
  1086.     CALL    BCONIN
  1087.     CPI    'C'-40H
  1088.     JZ    EXABRT        ; = ^C
  1089.     CPI    CR
  1090.     JZ    CRWRTX        ; = CR
  1091.     MVI    C,BELL
  1092.     CALL    BCONOT        ; <> CR
  1093.     JMP    CRWRTN
  1094. ;
  1095. CRWRTX: MOV    C,A        ; Echo CR/LF
  1096.     CALL    NCONOT
  1097.     MVI    C,LF
  1098.     CALL    NCONOT
  1099.     JMP    GETBUF
  1100. ;
  1101. PSUPCK: LXI    H,PSUPFL
  1102.     CMP    M
  1103.     JNZ    PSUPST        ; Set flags if not equal
  1104.     XRA    A        ; Else reset flags
  1105. PSUPST: MOV    M,A        ; Set/reset Saved Flag
  1106.     JMP    GETBUF        ; And get next character (sets EXEC flag)
  1107. ;
  1108. MSUPCK: LXI    H,MSUPFL
  1109.     CMP    M
  1110.     JNZ    MSUPST        ; Set flags if not equal
  1111.     XRA    A        ; Else reset flag
  1112. MSUPST: MOV    M,A        ; Set/reset flag
  1113.     JMP    GETBUF        ; And get next character
  1114. ;
  1115. IMFLGS: STA    IMFLG        ; Set/reset Immediate Mode flag
  1116.     JMP    GETBUF        ; Get next character
  1117. ;
  1118. ;    CONSOLE OUTPUT INTERCEPT ROUTINE
  1119. ;
  1120. NCONOT: LDA    OUTFLG        ; Print suppression?
  1121.     ORA    A
  1122.     JNZ    NCN1        ; Yes...ignore echo
  1123.     MOV    A,C
  1124.     STA    PMCHR
  1125.     CALL    BCONOT
  1126.  
  1127. NCN1:    LDA    BOOTED
  1128.     ORA    A
  1129.     RZ
  1130.     XRA    A
  1131.     STA    BOOTED
  1132.     LHLD    MEMTOP
  1133.     SHLD    BDOS+1
  1134.     PUSH    H        ; Restore CP/M S/N
  1135.     LXI    D,-6        ;
  1136.     DAD    D        ; HL = BDOS + 0
  1137.     XTHL            ; (SP) = Pseudo BDOS + 0; HL = Pseudo BDOS + 6
  1138.     INX    H        ; +1
  1139.     MOV    E,M        ; Get BDOS+6
  1140.     INX    H        ;
  1141.     MOV    D,M        ;
  1142.     XCHG            ; HL = BDOS+6
  1143.     LXI    D,-6        ;
  1144.     DAD    D        ; HL = BDOS+0
  1145.     POP    D        ; DE = Pseudo BDOS+0
  1146.     MVI    B,6        ; Length of S/N
  1147.     CALL    MOVE        ;
  1148.     RET
  1149. ;
  1150. GETCHR: LHLD    REVBUF
  1151.     MOV    A,M
  1152.     DCX    H
  1153.     SHLD    REVBUF
  1154.     CPI    0FFH        ; EOB?
  1155.     RNZ            ; No...return
  1156.     LHLD    REVBUF
  1157.     INX    H        ; Point to EOB
  1158.     SHLD    REVBUF
  1159.     CALL    MOVBAK        ; Move jumps back
  1160.     LHLD    MEMTOP        ; See if BDOS+1 = MEMTOP
  1161.     XCHG
  1162.     LHLD    BDOS+1
  1163.     MOV    A,E
  1164.     SUB    L
  1165.     MOV    A,D
  1166.     SBB    H
  1167.     JNZ    EXEND        ; Don't replace BDOS jump
  1168.     INX    D        ; Get to BDOS jump
  1169.     LDAX    D
  1170.     MOV    L,A        ; LSB
  1171.     INX    D
  1172.     LDAX    D
  1173.     MOV    H,A
  1174.     SHLD    BDOS+1
  1175. EXEND:    CALL    PMCHRS
  1176.     LXI    H,DONEM        ; Tell user we're done
  1177.     CALL    PMSG
  1178.     LHLD    CONSTK        ; Get old stack
  1179.     SPHL
  1180.     JMP    BCONIN
  1181. ;
  1182. ;    ^C ABORT EXIT
  1183. ;
  1184. EXABRT: LXI    SP,MEMTOP    ; ^C aborts EX
  1185.     LXI    H,ABORTD
  1186.     CALL    PMSG
  1187.     JMP    WARMX
  1188. ;
  1189. WARMR:    CALL    PMCHRS
  1190.     LXI    H,DONEM        ; End message
  1191.     CALL    PMSG
  1192. ;
  1193. WARMX:    CALL    MOVBAK        ; Move jumps back
  1194.     JMP    WARM
  1195. ;
  1196. ;    SUBROUTINES
  1197. ;
  1198. MOVBAK: LHLD    WARMPT        ; Move old jump table back to BIOS
  1199.     XCHG
  1200.     LXI    H,BSWARM
  1201.     MVI    B,12
  1202.     CALL    MOVE
  1203.     CALL    F121        ; CALL 1.2.1 FIX FOR MBASIC    1.1.2
  1204.     RET
  1205. ;
  1206. MOVE:    MOV    A,M        ; Move string from (HL) to (DE) for length in B
  1207.     INX    H
  1208.     STAX    D
  1209.     INX    D
  1210.     DCR    B
  1211.     JNZ    MOVE
  1212.     RET
  1213. ;
  1214. PMCHRS: LDA    PMCHR        ; Set prompt char only if special character
  1215.     CPI    ' '+1
  1216.     RC
  1217.     CPI    '0'
  1218.     JC    PMCHRX
  1219.     CPI    '9'+1
  1220.     RC
  1221.     CPI    'A'
  1222.     JC    PMCHRX
  1223.     CPI    'Z'+1
  1224.     RC
  1225.     CPI    'a'
  1226.     JC    PMCHRX
  1227.     CPI    'z'+1
  1228.     RC
  1229. PMCHRX: STA    DONEC
  1230.     RET
  1231. ;
  1232. PMSG:    LDA    MSUPFL        ; Print message at (HL)
  1233.     CPI    MSUP        ; Messages suppressed?
  1234.     RZ            ; Yes..exit
  1235.     PUSH    H
  1236. PMSGL:    POP    H
  1237.     MOV    A,M
  1238.     CPI    '$'        ; EOM?
  1239.     RZ            ; Yes..exit
  1240.     INX    H
  1241.     PUSH    H
  1242.     MOV    C,A
  1243.     CALL    BCONOT
  1244.     JMP    PMSGL
  1245. ;
  1246. F121:    LXI    H,BSWARM    ; Ensure only BIOS    1.1.2
  1247.     LXI    D,NWARM     ;  calls from now on    1.1.2
  1248.     MVI    B,3        ;   for programs    1.1.2
  1249.     CALL    MOVE        ;    that may have    1.1.2
  1250.     LXI    H,BCONIN    ;     copied our    1.1.2
  1251.     LXI    D,NCONIN    ;      addresses as    1.1.2
  1252.     MVI    B,3        ;    if they were    1.1.2
  1253.     CALL    MOVE        ;     in the bios.    1.1.2
  1254.     LXI    H,BCONOT    ;  (MBASIC does this)    1.1.2
  1255.     LXI    D,NCONOT    ;            1.1.2
  1256.     MVI    B,3        ;            1.1.2
  1257.     CALL    MOVE        ;            1.1.2
  1258.     RET            ;            1.1.2
  1259. ;
  1260. ;    WORKING STORAGE AREA
  1261. ;
  1262. ABORTD: DB    CR,LF,'>>>Ex Aborted<<<',CR,LF,'$'
  1263. STARTM: DB    CR,LF,'(Ex Active)$'
  1264. DONEM:    DB    CR,LF,'(Ex Completed)',CR,LF
  1265. DONEC:    DB    '>$'
  1266. ;
  1267.     REPT    10
  1268.     DW    0
  1269.     ENDM
  1270. MEMTOP: DW    0
  1271. REVBUF: DW    0
  1272. SAVBUF: DW    0
  1273. WARMPT: DW    0
  1274. ;
  1275. ;    ORIGINAL BIOS JMP TABLE
  1276. ;
  1277. BSWARM: JMP    $
  1278. BCONST: JMP    $
  1279. BCONIN: JMP    $
  1280. BCONOT: JMP    $
  1281. ;
  1282. PMCHR:    DB    0
  1283. PSUPFL: DB    0
  1284. BOOTED:    DB    0
  1285. OUTFLG: DB    0
  1286. IMFLG:    DB    0
  1287. MSUPFL: DB    0
  1288. CONSTK: DW    0
  1289. ;     DB     'BDOS>'
  1290. ;BDOSVE: DW     0
  1291. ;
  1292. ?PLEN    SET    $
  1293.     IF (?PLEN MOD 8) GT 0
  1294. ?PLEN    SET    (?PLEN AND 0FFF8H)+8 ; Get next boundary
  1295.     ENDIF
  1296. ;
  1297. DRVERL    EQU    ?PLEN
  1298. ;
  1299. DRVL8    EQU    DRVERL/8    ; Length of relocation bit map
  1300.     ORG    DRVERL
  1301. ;
  1302.     ENDIF
  1303. ;
  1304. ;    END OF EX RELOCATED CODE SEGMENT
  1305. ;
  1306.     END
  1307.     ;    that may have    1.1.2
  1308.     LXI    H,BCONIN    ;     copied our    1.1.2
  1309.     LXI    D,NCONIN    ;      addresses as    1.1.2
  1310.     MVI    B,3        ;    if they