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 / ZCPR33 / A-R / LONGSUB.ZZ0 / LONGSUB.Z80
Text File  |  2000-06-30  |  33KB  |  1,259 lines

  1. ; LONGSUB: SUBmit utility for ZCPR33 for long submit files.
  2. ;    by Thomas E. Croley II, 30 June 1987
  3. ;        * Requires modification of your ZCPR33 CCP !!!! (see below)
  4. ;        * Corrects ZCPR33 error in submit processing for $$$.SUB files
  5. ;            longer than can be accessed with a single directory
  6. ;            entry.
  7. ;        * Derived from SUB34.
  8. ;
  9. ; Submit file processing is (and has always been?) limited to short *.SUB file
  10. ; lengths (fewer than 128 lines for disk allocation blocks of 2k, 256 lines
  11. ; for disk allocation blocks of 4k, ...).  This is because ZCPR33 finds the
  12. ; last record in the $$$.SUB file for processing and attempts to close the file
  13. ; one record shorter to remove that record (command) from further processing;
  14. ; to do this, ZCPR33 decrements the record count in the FCB for the file before
  15. ; the close.  This works if there is only one directory entry in the directory
  16. ; for the $$$.SUB file but it does not work if there are more.  Subsequently,
  17. ; for longer $$$.SUB files, ZCPR33 neither finds the end of file correctly, nor
  18. ; is it able to reduce the file length past the point allocated to an earlier
  19. ; directory entry.  The proper way around this is to implement direct access
  20. ; ("random access" in old CP/M terminology) file manipulations to find the end
  21. ; of the file and to keep track of the last record processed.  The SUB utility
  22. ; must be modified also to use this method so that the last record (first
  23. ; command) to be accessed by the CCP is pointed to in the file (the last record
  24. ; of the file is used for this purpose here).  Also, file append (for nesting
  25. ; of SUB commands), must properly maintain this pointer.
  26. ;
  27. ; If you use this SUB command, you must modify your ZCPR33 CCP by adding the
  28. ; following code as instructed below.  The PENALTY is that it will slow submit
  29. ; file processing (hardly noticeable on a RAM disk but may be significant on a
  30. ; floppy) since additional disk reads and writes are required to find and
  31. ; maintain the next-command pointer.  These reads and writes are not to
  32. ; sequential records on the disk since the pointer is maintained in the last
  33. ; record of the file while commands are taken successively toward the
  34. ; beginning.  The ADVANTAGE is that it will allow arbitrary length submit files
  35. ; for processing.
  36. ;
  37. ; If you do not use this SUB command and do not modify your ZCPR33 CCP as
  38. ; follows, then BEWARE that submit files with line lengths exceeding the above
  39. ; limits will not be possible and there is no error message nor error checking
  40. ; for this condition within the CCP.
  41. ;
  42. ; MODIFICATIONS TO ZCPR33.Z80 (may require reconfiguration in Z33HDR.LIB to
  43. ;            make room for the additional code on your machine)
  44. ;
  45. ; Find the label "subfcr:" in ZCPR33.Z80 and add the code denoted by ";TEC" as
  46. ; follows:
  47. ;
  48. ;    subfcr:
  49. ;        defs    1        ; Current record number
  50. ;    subfr:                ;TEC
  51. ;        defs    3        ;TEC Random record no. (16 bits) + ovrflw byte
  52. ;
  53. ; Find the label "readbuf:" in ZCPR33.Z80 and modify or add the code as denoted
  54. ; by ";TEC" as follows:
  55. ;
  56. ;    readbuf:
  57. ;
  58. ;        ld    a,(zexrunfl)    ; Get ZEX-running flag
  59. ;        or    a
  60. ;        jp    nz,userinput    ; If ZEX running, go directly to user input
  61. ;
  62. ;         if    subon        ; If submit facility is enabled, check for it
  63. ;
  64. ;        ld    a,(subflag)    ; Test for submit file running
  65. ;        or    a
  66. ;        jr    z,shellinput    ; If not, go on to possible shell input
  67. ;
  68. ;        xor    a        ; Log into user 0
  69. ;        call    setuser
  70. ;        call    defltdma    ; Initialize DMA pointer
  71. ;        ld    de,subfcb    ; Point to submit file FCB
  72. ;        call    open        ; Try to open file
  73. ;        jr    z,readbuf1    ; Branch if open failed
  74. ;
  75. ;    ;TEC    ld    hl,subfrc    ; Point to record count in submit FCB
  76. ;    ;TEC    ld    a,(hl)        ; Get the number of records in file
  77. ;    ;TEC    dec    a        ; Reduce to number of last record
  78. ;    ;TEC    ld    (subfcr),a    ; ..and put into current record field
  79. ;        ld    c,23h        ;TEC "Compute file size" bdos call no.
  80. ;        call    bdossave    ;TEC DE still => subfcb; get file size in subfr
  81. ;        ld    hl,(subfr)    ;TEC Get file size
  82. ;        dec    hl        ;TEC Decrement to get last record no.
  83. ;        ld    (subfr),hl    ;TEC Replace in random record field
  84. ;        ld    c,21h        ;TEC "Read random" bdos call no.
  85. ;        call    bdossave    ;TEC DE still => subfcb; randm read last record
  86. ;        ld    hl,(tbuff)    ;TEC Get current "last record" from last record
  87. ;        dec    hl        ;TEC Point to next earlier record to read
  88. ;        ld    (tbuff),hl    ;TEC Save pointer in actual last record
  89. ;        inc    c        ;TEC ... and write back to file (c=22h)
  90. ;        call    bdossave    ;TEC DE still => subfcb; randm write last recrd
  91. ;        ld    (subfr),hl    ;TEC Now prepare to read new "last record"
  92. ;        dec    c        ;TEC (c=21h)
  93. ;        call    bdossave    ;TEC Random read record; DE still => subfcb
  94. ;    ;TEC    call    read        ; Attempt to read submit file
  95. ;    ;TEC    jr    nz,readbuf1    ; Branch if read failed
  96. ;
  97. ;    ;TEC    dec    (hl)        ; Reduce file record cound
  98. ;    ;TEC    dec    hl        ; Point to S2 byte of FCB (yes, this is req'd!)
  99. ;    ;TEC    ld    (hl),a        ; Stuff a zero in there (A=0 from call to READ)
  100. ;        ld    (subfrc-1),a    ;TEC Zero FCB S2 byte (A=0 from previous read)
  101. ;        call    close        ; Close the submit file one record smaller
  102. ;        jr    z,readbuf1    ; Branch if close failed
  103. ;
  104. ; END of ZCPR33.Z80 changes...
  105. ;
  106. ;
  107. ; The following program is SUB34.Z80 with ALL modifications denoted by ";TEC".
  108. ;
  109. ; PROGRAM NAME:  SUB
  110. ; AUTHOR:  RICHARD CONN (From SuperSUB Ver 1.1 by Ron Fowler)
  111. ; VERSION:  3.4  (Royce Shofner)
  112. ; DATE:  8 June 1987
  113. ;
  114. ; PREVIOUS VERSION:   3.3 (4 MAY 1987) HOWARD GOLDSTEIN
  115. ; PREVIOUS VERSION:  3.2 (27 APRIL 1987) JAY SAGE
  116. ; PREVIOUS VERSIONS:  3.1 (19 JAN 1985) JOE WRIGHT
  117. ; PREVIOUS VERSIONS:  3.0 (18 MAY 84) RELEASE VERSION
  118. ; PREVIOUS VERSIONS:  2.3 (6 Jan 83) - Called SUB2.ASM
  119. ; PREVIOUS VERSIONS:  2.2 (7 DEC 82), 2.1 (14 NOV 82), 2.0 (11 OCT 82)
  120. ; PREVIOUS VERSIONS:  1.4 (10 OCT 81), 1.3 (7 OCT 81)
  121. ; PREVIOUS VERSIONS:  1.2 (5 OCT 81), 1.1 (3 OCT 81), 1.0 (1 OCT 81)
  122. ; NOTE:  FOR USE WITH ZCPR3
  123. ;
  124. vers    equ    34        ; Modified for ZCPR33 compatibility
  125. ;
  126. z3env    defl    0f900h
  127. ;
  128. ;    SUB is derived from Ron's SuperSUB program; it provides a different
  129. ; format for the command line, a command-search hierarchy like ZCPR3, a
  130. ; resetting of the DMA address, several additional functions, and there are
  131. ; several other additions/changes.  Additionally, ZCPR3-specific enhancements,
  132. ; such as appending the rest of the multiple command line to the command file
  133. ; and allowing multiple commands on a single line, are permitted.
  134. ;
  135. ;    SuperSUB, VERSION 1.1 (09/13/81)        by Ron Fowler
  136. ;    2/18/81 (first written)             WESTLAND, MICH.
  137. ;
  138. ;
  139. ; Version 3.2    Modified to write $$$.SUB file to user 0 instead of current
  140. ; user.
  141.  
  142. ; Version 3.3        Deletes $$$.SUB file from user 0.  ALLOWS
  143. ; use of "^^" to represent "^".  Permits only 126 characters per line 
  144. ; so that there will always be a trailling null.  No longer CP/M
  145. ; compatible.  Requires ZCPR3 with multiple command line at least 127
  146. ; characters long.  Recognizes explicit directory spec for input file
  147. ; and does not search along path if so.
  148.  
  149. ; Version 3.4    Modified to take advantage of ZCPR33'S external running
  150. ; submit flag. SUB34 will set the flag after writing the submit file. If
  151. ; ZCPR33 is resident, SUB will just return to system; else, it will do
  152. ; the traditional warm boot.
  153.  
  154. ; This program is intended as a replacement for the
  155. ; SUBMIT program provided with CP/M.  It provides sev-
  156. ; eral new facilities:
  157. ;    1) Nestable SUBMIT runs
  158. ;    2) Interactive entry of SUBMIT job (no need
  159. ;       to use an editor for simple SUBMIT runs)
  160. ;    3) Command line entry of small SUBMIT jobs
  161. ;    4) Ability to enter blank lines in an edited
  162. ;       SUBMIT file
  163. ;    5) User customization of number of parameters
  164. ;       and drive to send $$$.SUB to
  165. ;
  166.  
  167. ;
  168. ; DEFINE BOOLEANS
  169. ;
  170. false    equ    0
  171. true    equ    not false
  172.  
  173. ;
  174. ;        --  User customizable options --
  175. ;
  176.  
  177. force$sub equ    false        ; True if submitted file must be of type .sub
  178. time$const equ    0c000h        ; Delay for ringing bell
  179. npar    equ    10        ; Number of allowable parameters
  180. cpbase    equ    0        ; Set to 4200h for heath cp/m
  181. opt    equ    '/'        ; Option delimiter char
  182. pdelim    equ    '$'        ; Parameter delimiter
  183.  
  184. ;
  185. ; SYSLIB AND Z3LIB ROUTINES
  186. ;
  187.     ext    z3init,pfind,getcl1,getmsg
  188.     ext    logud
  189.     ext    initfcb
  190.     ext    pstr,print,qprint,cout,crlf,caps,phldc
  191.     ext    codend
  192.  
  193. ;
  194. ; Z33LIB ROUTINES
  195. ;
  196.     ext    getsrun,subon
  197.  
  198. ;
  199. ; CP/M DEFINITIONS
  200. ;
  201. fgchar    equ    1        ; Get char function
  202. diriof    equ    6        ; Direct console i/o
  203. rdbuf    equ    10        ; Read console buffer
  204. login    equ    14        ; Log in disk
  205. openf    equ    15        ; Open file function
  206. closef    equ    16        ; Close file function
  207. deletf    equ    19        ; Delete file function
  208. readf    equ    20        ; Read record function
  209. writef    equ    21        ; Write record function
  210. makef    equ    22        ; Make (create) file function
  211. getdsk    equ    25        ; Return current disk
  212. setdma    equ    26        ; Set dma address
  213. ucode    equ    32        ; Get/set user code
  214. ;
  215. udflag    equ    cpbase+4
  216. bdos    equ    cpbase+5
  217. ;
  218. curind    equ    '$'        ; Current user/disk indicator
  219. fcb    equ    5ch        ; Default file control block
  220. fcbex    equ    12        ; Fcb offset to extent field
  221. fcbrc    equ    15        ; Fcb offset to record count
  222. fcbnr    equ    32        ; Fcb offset to next record
  223. fn    equ    1        ; Fcb offset to file name
  224. ft    equ    9        ; Fcb offset to file type
  225. tbuf    equ    cpbase+80h    ; Default buffer
  226. tpa    equ    cpbase+100h    ; Transient program area
  227. ;
  228. putcnt    equ    tbuf        ; Counter for output chars
  229. ;
  230. ; DEFINE SOME TEXT CHARACTERS
  231. ;
  232. ctrlc    equ    'C'-'@'
  233. ctrlz    equ    'Z'-'@'
  234. bel    equ    7        ; Ring bell
  235. cr    equ    13        ; Carriage return
  236. lf    equ    10        ; Line feed
  237. tab    equ    9
  238.  
  239. ;
  240. ; Environment Definition
  241. ;
  242.      if    z3env ne 0
  243. ;
  244. ; External ZCPR3 Environment Descriptor
  245. ;
  246.     jp    start
  247.     db    'Z3ENV'        ; This is a zcpr3 utility
  248.     db    1        ; External environment descriptor
  249. z3eadr:
  250.     dw    z3env
  251. start:
  252.     ld    hl,(z3eadr)    ; Pt to zcpr3 environment
  253. ;
  254.      else
  255. ;
  256. ; Internal ZCPR3 Environment Descriptor
  257. ;
  258.     maclib    z3base.lib
  259.     maclib    sysenv.lib
  260. z3eadr:
  261.     jp    start
  262.     sysenv
  263. start:
  264.     ld    hl,z3eadr    ; Pt to zcpr3 environment
  265.      endif
  266.  
  267. ;
  268. ; Start of Program -- Initialize ZCPR3 Environment
  269. ;
  270.     call    z3init        ; Initialize the zcpr3 env and the vlib env
  271.     ld    hl,0        ; Save stack in case
  272.     add    hl,sp        ; Only help requested
  273.     ld    (spsave),hl    ; (not otherwise used)
  274.     call    qprint
  275.     db    'SUB  Version ',vers/10+'0','.',(vers mod 10)+'0',0
  276.  
  277.     call    codend        ; Set up external buffers
  278.     ld    (clbuf),hl    ; Set ptr
  279.     ld    (hl),128    ; Allow 128 chars
  280.     ld    de,100h        ; Free space
  281.     add    hl,de        ; Pt to free area
  282.     ld    (fremem),hl    ; Set ptr to free memory area
  283.     ld    sp,hl        ; Set stack ptr
  284.  
  285.     ld    a,(fcb+1)    ; Anything on cmd line?
  286.     cp    ' '
  287.     jp    z,help        ; No, go print help
  288.     call    initvar        ; Initialize the variable area
  289.     call    getpar        ; Get command line parameters and extract option
  290.     call    abort        ; Perform abort if flag set
  291.     call    setup        ; Set up read of submit file
  292.     call    rdfile        ; Read the submit file
  293.     call    wrset        ; Set up write of "$$$.SUB"
  294.     call    wrsub        ; Write "$$$.SUB"
  295.  
  296.     call    getsrun        ; Is a submit file already active ?
  297.     jr    nz,subxit    ; If so, just return to zcpr33
  298.  
  299.     call    getmsg        ; else, set the submit running flag
  300.     ld    de,2dh
  301.     add    hl,de
  302.     ld    (hl),0ffh
  303. subxit:
  304.     call    subon        ; zcpr33 & submit enabled ?
  305.     jp    nz,gozcpr    ; Return to zcpr33 if posible
  306.     jp    cpbase        ; else, try a warm boot
  307. ;
  308. ;    SETUP SETS UP THE FILE CONTROL BLOCK
  309. ;    FOR READING IN THE .SUB TEXT FILE
  310. ;
  311. setup:
  312.     ld    hl,fcb+ft    ; Look at first char of
  313.     ld    a,(hl)        ; File type.  if it is
  314.     cp    ' '        ; Blank, then go move
  315.     jp    z,putsub    ; "sub" INTO FT FIELD
  316.  
  317.      if    force$sub    ; File type must be of .sub
  318.     ld    de,subtyp    ; File type must be .sub
  319.     ld    b,3        ; 3 bytes
  320.     call    compar
  321.     jp    nz,notfnd    ; File not found if no type match
  322.      endif
  323.  
  324.     ret            ; If not blank, then accept any file type
  325. ;
  326. ;    MOVE "SUB" INTO THE FILE TYPE
  327. ;
  328. putsub:
  329.     ex    de,hl        ; By convention, move from
  330.     ld    hl,subtyp    ; @hl to @de
  331.     ld    b,3
  332.     call    move
  333.     ret
  334. ;
  335. ; MOVE # BYTES IN B REGISTER FROM @HL TO @DE
  336. ;
  337. move:
  338.     ld    a,(hl)        ; Pick up
  339.     ld    (de),a        ; Put down
  340.     inc    hl        ; I'm sure
  341.     inc    de        ; You've seen this
  342.     dec    b        ; Before...
  343.     jp    nz,move        ; 100 times at least
  344.     ret            ; I know i have
  345.  
  346. ;
  347. ; GETPAR MOVES THE SUBSTITUTION PARAMETERS SPECIFIED
  348. ; IN THE COMMAND LINE INTO MEMORY, AND STORES THEIR
  349. ; ADDRESSES IN THE PARAMETER TABLE.  THIS ALLOWS
  350. ; SUBSTITUTION OF $1, $2, ETC., IN THE SUBMIT COMMANDS
  351. ; WITH THEIR ACTUAL VALUES SPECIFED IN THE COMMAND
  352. ; LINE.
  353. ;
  354. getpar:
  355.     xor    a        ; A=0
  356.     ld    (aflag),a    ; Turn off abort command
  357.     ld    hl,tbuf+1    ; Where we find the command tail
  358.     call    scanto        ; Skip submit file name
  359.     ld    (option),a    ; First char of cmd line is option
  360.     ret    c        ; Line ended?
  361.     cp    opt        ; No, check option
  362.     jp    nz,glp0        ; Not keyboard inp, read file
  363.     inc    hl        ; Point past '/'
  364.     ld    a,(hl)        ; Get option char
  365.     cp    'A'        ; Abort command
  366.     jp    z,gparabt
  367.     cp    'I'        ; Interactive mode
  368.     ret    z        ; Return if so
  369.     jp    help        ; Help otherwise
  370. gparabt:
  371.     ld    a,0ffh        ; Turn on abort flag
  372.     ld    (aflag),a
  373.     inc    hl        ; Get possible bell option
  374.     ld    a,(hl)
  375.     cp    'B'        ; Bell option
  376.     ret    nz
  377.     ld    a,0ffh        ; Set bell flag
  378.     ld    (bell$flag),a
  379.     ret
  380. glp0:
  381.     ld    a,(hl)        ; Input is from a .sub file..this
  382.     inc    hl        ; Code skips over the name of
  383.     or    a        ; The sub file to get to the
  384.     ret    z        ; Command line parameters
  385.     cp    ' '
  386.     jp    z,glp
  387.     cp    tab
  388.     jp    nz,glp0
  389. glp:
  390.     call    scanto        ; Pass up the blanks
  391.     ret    c        ; Cy returned if end of cmd line
  392.     call    putpar        ; Now put the parameter into mem
  393.     ret    c        ; Cy returned if end of cmd line
  394.     jp    glp        ; Get them all
  395. ;
  396. ; SCANTO SCANS PAST BLANKS TO THE FIRST NON-BLANK. IF
  397. ; END OF COMMAND LINE FOUND, RETURNS CARRY SET.
  398. ;
  399. scanto:
  400.     ld    a,(hl)
  401.     inc    hl
  402.     or    a        ; Set flags on zero
  403.     scf            ; In case zero found (end of cmd lin)
  404.     ret    z
  405.     cp    ' '
  406.     jp    z,scanto    ; Scan past blanks
  407.     cp    tab        ; Do tabs too, just for
  408.     jp    z,scanto    ; Good measure
  409.     dec    hl        ; Found char, point back to it
  410.     or    a        ; Insure carry clear
  411.     ret
  412. ;
  413. ; PUTPAR PUTS THE PARAMETER POINTED TO BY HL INTO
  414. ; MEMORY POINTED TO BY "TXTPTR".  ALSO STORES THE
  415. ; ADDRESS OF THE PARAMETER INTO THE PARAMETER TABLE
  416. ; FOR EASY ACCESS LATER, WHEN WE WRITE $$$.SUB
  417. ;
  418. putpar:
  419.     push    hl        ; Save pointer to parm
  420.     ld    hl,(txtptr)    ; Next free memory
  421.     ex    de,hl        ; Into de
  422.     ld    hl,(tblptr)    ; Next free area of table
  423.     ld    a,(hl)        ; Non-zero in table
  424.     or    a        ; Indicates table
  425.     jp    nz,parovf    ; Table overflow (too many parms)
  426.     ld    (hl),e        ; Store the parm adrs
  427.     inc    hl
  428.     ld    (hl),d
  429.     inc    hl
  430.     ld    (tblptr),hl    ; Save table pntr for next time
  431.     pop    hl        ; Get back parm pointer
  432.     push    de        ; Save free mem pointer because
  433.                 ; We will have to have it back
  434.                 ; Later to store the length
  435.     inc    de        ; Point past length storage
  436.     ld    b,0        ; Initialize length of parm
  437. pplp:
  438.     ld    a,(hl)        ; Get next byte of parm
  439.     inc    hl
  440.     or    a        ; Test for end of cmd line
  441.     jp    z,pp2        ; Jump if end
  442.     cp    ' '        ; Test for end of command
  443.     jp    z,pp2
  444.     cp    tab        ; Tab also ends command
  445.     jp    z,pp2
  446.     ld    (de),a        ; Put parameter byte-by-byte
  447.     inc    de        ; Into free memory
  448.     inc    b        ; Bump length
  449.     jp    pplp
  450. pp2:
  451.     ex    de,hl
  452.     ld    (txtptr),hl    ; New free memory pointer
  453.     pop    hl        ; Remember our length pointer?
  454.     ld    (hl),b        ; Store the length
  455.     ex    de,hl        ; Have to retn hl > cmd line
  456.     or    a        ; Now return end of line flag
  457.     scf
  458.     ret    z        ; Return cy if zero (eol mark)
  459.     ccf
  460.     ret
  461. ;
  462. ;
  463. ;    ABORT CHECKS TO SEE IF THE ABORT FLAG IS SET AND
  464. ;    EXECUTES THE ABORT FUNCTION IF SO
  465. ;
  466. ;
  467. abort:
  468.     ld    a,(aflag)    ; Get the flag
  469.     or    a        ; 0=no
  470.     ret    z
  471.     call    print
  472.     db    cr,lf,' Strike ^C to Abort Command File - ',0
  473.     call    charinb        ; Get response
  474.     cp    ctrlc        ; Abort?
  475.     jp    nz,abort1    ; Return to opsys
  476. abort0:
  477.     ld    e,0        ; Set user 0
  478.     ld    c,20h
  479.     call    bdos
  480.  
  481.     ld    de,subfcb    ; Delete submit file
  482.     ld    c,deletf
  483.     call    bdos
  484.     call    print
  485.     db    ' ... Aborted',0
  486.     jp    cpbase        ; Return to cp/m
  487. abort1:
  488.     call    print
  489.     db    ' ... Continuing',0
  490.     jp    cpbase        ; Return to cp/m
  491. ;
  492. ;    INPUT CHAR FROM CON:; RING BELL EVERY SO OFTEN IF FLAG SET
  493. ;
  494. charinb:
  495.     ld    a,(bell$flag)    ; Get flag
  496.     or    a        ; 0=no
  497.     jp    z,charin
  498.     push    hl        ; Save hl
  499. charinb$loop:
  500.     ld    hl,time$const    ; Get time constant
  501. charinb$loop1:
  502.     ex    (sp),hl        ; Long delay
  503.     ex    (sp),hl
  504.     dec    hl        ; Count down
  505.     ld    a,h
  506.     or    l
  507.     jp    nz,charinb$loop1
  508.     ld    e,0ffh        ; Request status
  509.     ld    c,diriof    ; Direct i/o
  510.     call    bdos
  511.     or    a        ; Any input?
  512.     jp    nz,charinb$done
  513.     ld    e,bel        ; Ring bell
  514.     ld    c,diriof
  515.     call    bdos
  516.     jp    charinb$loop
  517. charinb$done:
  518.     pop    hl        ; Restore hl
  519.     jp    caps        ; Capitalize char
  520.  
  521. ;
  522. ;    INPUT CHAR FROM CON:; CAPITALIZE IT AND ECHO <CRLF>
  523. ;
  524. charin:
  525.     ld    c,fgchar    ; Get char
  526.     call    bdos
  527.     jp    caps        ; Capitalize
  528. ;
  529. ;    RDFILE READS THE .SUB FILE SPECIFIED
  530. ;    IN THE SUBMIT COMMAND INTO MEMORY
  531. ;
  532. rdfile:
  533.     ld    hl,0        ; Init line number
  534.     ld    (linnum),hl
  535.     ld    a,(option)    ; Using a file?
  536.     cp    opt        ; Opt option tells
  537.     jp    nz,rdfile1    ; Jump if not
  538.     call    print
  539.     db    cr,lf,' Input Command Lines',0
  540.     call    clfill        ; Get first line
  541.     jp    line
  542. rdfile1:
  543.     call    print
  544.     db    cr,lf,' Processing SUB File',0
  545.  
  546. ;  CHECK FOR .SUB FILE IN SPECIFIED DIRECTORY OR ALONG PATH
  547.     ld    de,fcb        ; Pt to FCB
  548.     ld    a,(de)        ; Get drive byte
  549.     or    a        ; If zero, no dir specified (Z33 feature)
  550.     jr    z,rdfile2
  551.     dec    a        ; Gt drive in range 0..15
  552.     ld    b,a        ; Store drive in B
  553.     ld    a,(fcb+13)    ; Get user number
  554.     ld    c,a        ; ..into C
  555.     call    logud        ; Log in
  556.     call    initfcb        ; Initialize FCB
  557.     jr    rdfile3        ; ..and attempt to open file
  558.  
  559. rdfile2:
  560.     call    initfcb        ; Init fcb
  561.     ld    a,0ffh        ; Search current also
  562.     call    pfind        ; Look for file
  563.     jp    z,notfnd    ; File not found
  564.     call    logud        ; Log into directory
  565.     ld    de,fcb        ; Pt to fcb
  566.  
  567. rdfile3:
  568.     ld    c,openf        ; Open file
  569.     call    bdos
  570.     inc    a        ; Set zero flag if open failed
  571.     jp    z,notfnd
  572.     call    fill        ; Read first block
  573.     jp    nz,notext    ; Empty file
  574. line:
  575.     ld    hl,(linnum)    ; Bump line number
  576.     inc    hl
  577.     ld    (linnum),hl
  578.     ld    hl,(prev)    ; Get prev previous line pointer
  579.     ex    de,hl
  580.     ld    hl,(txtptr)    ; Get current free mem pointer
  581.     ld    (prev),hl    ; Make it the prev line (for nxt pass)
  582.     ld    (hl),e        ; Store at begin of current line,
  583.     inc    hl        ; A pointer to the previous
  584.     ld    (hl),d
  585.     inc    hl
  586.     push    hl        ; Later we will put length here
  587.     inc    hl        ; Skip past length
  588.     ld    c,1        ; Initialize length to one
  589. llp:
  590.     call    gnb        ; Get next byte from input source
  591.     cp    ctrlz        ; End of file?
  592.     jp    z,eof        ; Cy set if end of file found
  593.     and    7fh        ; Mask out msb
  594.     call    caps        ; Convert to upper case
  595.     cp    lf        ; Ignore linefeeds
  596.     jp    z,llp
  597.     cp    cr        ; If it's a carriage return,
  598.     jp    z,eol        ; Then do end of line
  599.     ld    (hl),a        ; Store all others into memory
  600.     inc    hl
  601.     call    size        ; Make sure no memory overflow
  602.     inc    c        ; Bump char count
  603.     jp    m,lenerr    ; Max of 126 chars per line
  604.     jp    llp        ; Go do next char
  605. ;
  606. ;    DO END OF LINE SEQUENCE
  607. ;
  608. eol:
  609.     ld    (txtptr),hl    ; Save free memory pointer
  610.     pop    hl        ; Current line's length pointer
  611.     dec    c        ; Adjust length
  612.     ld    (hl),c        ; Store length away
  613.     jp    line        ; Go do next line
  614. ;
  615. ;    END OF TEXT FILE
  616. ;
  617. eof:
  618.     ld    (txtptr),hl    ; Save free memory pointer
  619.     dec    c        ; Adjust line length
  620.     push    bc        ; Save line length
  621.     call    zmcl        ; Load rest of command line
  622.     pop    bc        ; Restore line length
  623.     pop    hl        ; Current line's length pointer
  624.     ld    (hl),c        ; Store length away
  625.     ret            ; All done reading sub file
  626. ;
  627. ;  COPY COMMAND LINE INTO MEMORY BUFFER
  628. ;
  629. zmcl:
  630.  
  631.     ld    hl,(linnum)    ; Bump line number
  632.     inc    hl
  633.     ld    (linnum),hl
  634.     ld    hl,(prev)    ; Get prev previous line pointer
  635.     ex    de,hl
  636.     ld    hl,(txtptr)    ; Get current free mem pointer
  637.     ld    (prev),hl    ; Make it the prev line (for nxt pass)
  638.     ld    (hl),e        ; Store at begin of current line,
  639.     inc    hl        ; A pointer to the previous
  640.     ld    (hl),d
  641.     inc    hl
  642.     push    hl        ; Later we will put length here
  643.     inc    hl        ; Skip past length
  644.     ld    c,1        ; Initialize length to one
  645.     ex    de,hl        ; De pts to next place to store a byte
  646.     call    getcl1        ; Get address of command line buffer
  647.     ld    a,(hl)        ; Get low
  648.     inc    hl
  649.     ld    h,(hl)        ; Get high
  650.     ld    l,a        ; Hl pts to first byte of multiple command line
  651.     ld    b,(hl)        ; Get first char in line
  652.     ld    (hl),0        ; Clear line
  653.     ld    a,b        ; Check to see if first char is a semicolon (cmd sep)
  654.     cp    ';'
  655.     jp    nz,zmcl0
  656.     inc    hl        ; Pt to 2nd char
  657.     ld    a,(hl)        ; First was a semicolon, so get second
  658. zmcl0:
  659.     ex    de,hl        ; Hl pts to next buffer space, de pts to mc line
  660.     jp    zmcl1a        ; A=first char in mc line
  661. ;
  662. ;  MAJOR LOOP TO STORE MULTIPLE COMMAND LINE
  663. ;
  664. zmcl1:
  665.     ld    a,(de)        ; Get next byte from multiple command line
  666. zmcl1a:
  667.     or    a        ; 0=eol
  668.     jp    z,zmcl2
  669.     and    7fh        ; Mask out msb
  670.     call    caps        ; Convert to upper case
  671.     ld    (hl),a        ; Store char into memory
  672.     inc    hl        ; Pt to next char
  673.     inc    de
  674.     call    size        ; Make sure no memory ovfl
  675.     inc    c        ; Incr char count
  676.     jp    m,lenerr    ; Max of 128 chars in line
  677.     jp    zmcl1
  678. ;
  679. ;  DONE WITH INPUT OF MULTIPLE COMMAND LINE -- SAVE CHAR CNT AND SET PTR
  680. ;
  681. zmcl2:
  682.     ld    (txtptr),hl    ; Save ptr
  683.     pop    hl        ; Pt to char count position
  684.     dec    c        ; Adjust char count
  685.     ld    (hl),c        ; Store char count
  686.     ret
  687.  
  688. ;
  689. ;    GET NEXT BYTE FROM INPUT FILE OR USER
  690. ;
  691. gnb:
  692.     push    hl        ; Don't alter anybody
  693.     push    de
  694.     push    bc
  695.     ld    a,(option)    ; Input from .sub file?
  696.     cp    opt        ; Told by orig cmd line option
  697.     jp    nz,gnbdisk    ; Get next char from disk buffer if not from user
  698.     call    gnbkbd        ; Get a byte from kbd input
  699.     jp    gnbxit        ; Then leave
  700. ;
  701. ;    GET NEXT BYTE FROM DISK FILE
  702. ;
  703. gnbdisk:
  704.     ld    a,(ibp)        ; Get buffer pointer
  705.     cp    128        ; Need another block from disk?
  706.     jp    c,gnbd1        ; Continue
  707.     call    fill        ; Get next block
  708.     jp    z,gnbd1        ; Continue if not empty
  709.     ld    a,1ah        ; Fake eof
  710.     jp    gnbxit
  711. gnbd1:
  712.     ld    e,a        ; Put offset in de
  713.     ld    d,0
  714.     inc    a        ; Point to next byte
  715.     ld    (ibp),a        ; Save for next
  716.     ld    hl,tbuf        ; Now offset into buffer
  717.     add    hl,de
  718.     ld    a,(hl)        ; Get char
  719. gnbxit:
  720.     pop    bc        ; Restore everybody
  721.     pop    de
  722.     pop    hl
  723.     or    a        ; Turn on carry
  724.     ret
  725. ;
  726. ;    FILL INPUT BUFFER FROM DISK
  727. ;
  728. fill:
  729.     xor    a        ; Clear input buffer ptr
  730.     ld    (ibp),a
  731.     ld    de,fcb        ; Pt to fcb
  732.     ld    c,readf        ; Bdos read block function
  733.     call    bdos
  734.     or    a        ; Return z if eof
  735.     ld    a,0        ; Set ptr to first char
  736.     ret
  737. ;
  738. ;    GET NEXT BYTE FROM USER (KEYBOARD INPUT)
  739. ;
  740. gnbkbd:
  741.     ld    hl,(clptr)    ; Pt to next char
  742.     ld    a,(hl)        ; Get it
  743.     inc    hl        ; Pt to following
  744.     ld    (clptr),hl    ; Reset ptr
  745.     cp    cr        ; End of line?
  746.     ret    nz
  747.     call    clfill        ; Get new line
  748.     jp    z,gkend        ; Empty line input - return eof
  749.     ld    a,cr        ; Return cr to indicate end of line
  750.     ret
  751. gkend:
  752.     ld    a,1ah        ; Return eof
  753.     ret
  754. ;
  755. ;    FILL THE COMMAND LINE FROM THE USER
  756. ;
  757. clfill:
  758.     call    print
  759.     db    cr,lf,' Command Line? ',0
  760.     ld    hl,(clbuf)    ; Now fill the buffer
  761.     ex    de,hl        ; De pts to it
  762.     ld    c,rdbuf
  763.     call    bdos
  764.     ld    hl,(clbuf)    ; Pt to command line buffer
  765.     inc    hl
  766.     ld    a,(hl)        ; Get char count
  767.     inc    hl
  768.     ld    (clptr),hl    ; Reset the command line ptr
  769.     or    a        ; Set zero flag
  770.     push    af        ; Save a
  771.     add    a,l        ; Pt to after last char
  772.     ld    l,a
  773.     ld    a,h
  774.     adc    0
  775.     ld    h,a
  776.     ld    (hl),cr        ; Set eol char
  777.     pop    af        ; Get char count
  778.     ret
  779. ;
  780. ;    MAKE SURE NO MEMORY OVERFLOW
  781. ;
  782. size:
  783.     ld    a,(bdos+2)    ; Highest page pointer
  784.     sub    9        ; Make it be under ccp
  785.     cp    h        ; Check it against current page
  786.     ret    nc        ; Nc=all okay
  787.     jp    memerr        ; Otherwise abort
  788. ;
  789. ;    SET UP THE $$$.SUB FILE
  790. ;    FOR WRITING
  791. ;
  792. wrset:
  793.     call    print
  794.     db    cr,lf,' Writing Command File to Disk',0
  795.  
  796.     ld    e,0        ; Set user 0
  797.     ld    c,20h
  798.     call    bdos
  799.  
  800.     ld    de,subfcb
  801.     ld    c,openf
  802.     call    bdos        ; Open the file
  803.     inc    a        ; Check cpm return
  804.     jp    z,none1        ; None exists already
  805. ;
  806. ;    $$$.SUB EXISTS, SO SET
  807. ;    FCB TO APPEND TO IT
  808. ;
  809.  
  810.     ld    de,subfcb    ;TEC Point to submit file FCB
  811.     ld    c,23h        ;TEC "Compute file size" bdos call no.
  812.     call    bdos        ;TEC Get file size in subfr
  813.     ld    hl,(subfr)    ;TEC Get file size
  814.     dec    hl        ;TEC Decrement to get last record no.
  815.     ld    (oldfsz),hl    ;TEC Save present file last record no.
  816.     ld    (subfr),hl    ;TEC Replace in random record field
  817.     ld    de,subfcb    ;TEC Point to submit file FCB again
  818.     ld    c,21h        ;TEC "Read random" bdos call no.
  819.     call    bdos        ;TEC Random read last record
  820.     ld    hl,(tbuf)    ;TEC Get current "last record" pointer
  821.     dec    hl        ;TEC Decr. to point to last unprocessed record
  822.     ld    (subfr),hl    ;TEC Now read "last record"
  823.     ld    de,subfcb    ;TEC Point to submit file FCB again
  824.     ld    c,21h        ;TEC "Read random" bdos call no.
  825.     call    bdos        ;TEC Random read record
  826.     ld    de,subfcb    ;TEC Prepare for sequential (re)write to update
  827.     ld    c,15h        ;TEC ... DOS pointers for further writes
  828.     call    bdos        ;TEC Write same info back to set DOS pointers
  829. ;TEC    ld    a,(subfcb+fcbrc) ; Get record count
  830. ;TEC    ld    (subfcb+fcbnr),a ; Make next record
  831.     ret
  832. oldfsz:    ds    2        ;TEC space for "old file size"
  833. ;
  834. ;    COME HERE WHEN NO $$$.SUB EXISTS
  835. ;
  836. none1:
  837.     xor    a        ;TEC
  838.     ld    (oldfsz),a    ;TEC Zero "old file size" since it did'nt exist
  839.     ld    (oldfsz+1),a    ;TEC
  840.     ld    de,subfcb
  841.     ld    c,makef
  842.     call    bdos
  843.     inc    a
  844.     jp    z,nomake    ; 0ffh=can't create file
  845.     ret
  846. ;
  847. ;    WRITE THE "$$$.SUB" FILE
  848. ;
  849. wrsub:
  850.     ld    hl,(prev)    ; This code scans backward
  851.     ld    a,h        ; Thru the file stored in
  852.     or    l        ; Memory to the first non-
  853.     jp    z,notext    ; Null line.  if none is
  854.     ld    e,(hl)        ; Found, aborts
  855.     inc    hl
  856.     ld    d,(hl)        ; Here, we pick up pntr to prev line
  857.     inc    hl        ; Now we point to length
  858.     ex    de,hl        ; We need to store away
  859.     ld    (prev),hl    ; Pointer to prev line
  860.     ex    de,hl
  861.     ld    a,(hl)        ; Now pick up the length
  862.     or    a        ; Set z flag on length
  863.     jp    nz,wrntry    ; Got line w/length: go do it
  864.     ld    hl,(linnum)    ; Nothing here, fix line number
  865.     dec    hl        ; (working backward now)
  866.     ld    (linnum),hl
  867.     jp    wrsub
  868. wrlop:
  869.     ld    hl,(prev)    ; Get prev line pointer
  870.     ld    a,h
  871.     or    l        ; If there is no prev line
  872.     jp    z,close        ; Then we are done
  873.     ld    e,(hl)        ; Else set up prev for next
  874.     inc    hl        ; Pass thru here
  875.     ld    d,(hl)
  876.     inc    hl
  877.     ex    de,hl        ; Now store it away
  878.     ld    (prev),hl
  879.     ex    de,hl
  880. wrntry:
  881.     call    putlin        ; Write the line to the file
  882.     ld    hl,(linnum)    ; Bump the line number
  883.     dec    hl        ; Down (working back now)
  884.     ld    (linnum),hl
  885.     jp    wrlop
  886. ;
  887. ;    $$$.SUB IS WRITTEN, CLOSE THE FILE
  888. ;
  889. close:
  890.     ld    de,subfcb    ;TEC
  891.     ld    c,24h        ;TEC Set random record number for record after
  892.     call    bdos        ;TEC ... last write
  893.     ld    hl,(subfr)    ;TEC Get rndm record no. for last record write
  894.     ld    (tbuf),hl    ;TEC Place in write buffer
  895.     ld    de,(oldfsz)    ;TEC DE = old last record number
  896.     xor    a        ;TEC Clear carry bit
  897.     sbc    hl,de        ;TEC Is new last record number >= old?
  898.     jr    nc,nfeok    ;TEC New file end O.K.
  899.     ld    (subfr),de    ;TEC ... else use old last record number
  900. nfeok:    ld    de,subfcb    ;TEC
  901.     ld    c,22h        ;TEC "Write random" bdos call no.
  902.     call    bdos        ;TEC Write current record no. to last record.
  903.     ld    de,subfcb
  904.     ld    c,closef
  905.     jp    bdos
  906. ;
  907. ;    THIS SUBROUTINE WRITES A LINE
  908. ;    TO THE $$$.SUB FILE BUFFER,
  909. ;    AND FLUSHES THE BUFFER AFTER
  910. ;    THE LINE IS WRITTEN.
  911. ;
  912. putlin:
  913.     ld    a,(hl)        ; Pick up length byte
  914.     inc    hl        ; Point past it
  915.     or    a
  916.     ret    z        ; Don't output 0 length line
  917.     ld    (getcnt),a    ; Make a count for "GET"
  918.     ld    (getptr),hl    ; Make a pointer for "GET"
  919.     ld    hl,tbuf+1    ; Text goes after length
  920.     ld    (putptr),hl    ; Make pointer for "PUT"
  921.     ld    a,1        ; Initialize put count
  922.     ld    (putcnt),a
  923.     ld    b,l        ; Count for clear loop
  924. clr:
  925.     ld    (hl),0        ; Zero out buffer loc
  926.     inc    hl
  927.     inc    b        ; Count
  928.     jp    nz,clr
  929. ;
  930. ;    THIS LOOP COLLECTS CHARACTERS
  931. ;    FROM THE LINE STORED IN MEMORY
  932. ;    AND WRITES THEM TO THE FILE.
  933. ;    IF THE "$" PARAMETER SPECIFIER
  934. ;    IS ENCOUNTERED, PARAMETER SUB-
  935. ;    STITUTION IS DONE
  936. ;
  937. putlp:
  938.     call    getchr        ; Pick up a character
  939.     jp    c,flush        ; Cy = no more char in line
  940.     cp    '^'        ; Control-char translate prefix?
  941.     jp    nz,notcx
  942.     call    getchr        ; Yes, get the next
  943.     jp    c,ccerr        ; Error: early end of input
  944.     cp    '^'        ; If "^^" just put "^" in text
  945.     jp    z,notcx
  946.     sub    '@'        ; Make it a control-char
  947.     jp    c,ccerr        ; Error: too small
  948.     cp    ' '
  949.     jp    nc,ccerr    ; Error: too large
  950. notcx:
  951.     cp    pdelim        ; Parameter specifier?
  952.     jp    nz,stobyt    ; If not, just write char
  953.     ld    a,(option)    ; Check option: '$' doesn't
  954.     cp    opt        ; Count in opt mode
  955.     ld    a,pdelim    ; (restore the '$')
  956.     jp    z,stobyt
  957.     call    lkahed        ; Peek at next char
  958.     jp    c,parerr    ; Line ending means param err
  959.     cp    pdelim        ; Another "$"?
  960.     jp    nz,subs        ; If not then go do substitution
  961.     call    getchr        ; Get the 2nd "$" (we only looked
  962.                 ; Ahead before)
  963. stobyt:
  964.     call    putchr        ; Write char to file
  965.     jp    putlp
  966. ;
  967. ;    PARAMETER SUBSTITUTION...LOOKS UP THE
  968. ;    PARAMETER # AFTER THE "$" AND PLUGS IT
  969. ;    IN IF IT EXISTS.
  970. ;
  971. subs:
  972.     call    numtst        ; It better be a number
  973.     jp    c,parerr    ; Otherwise param error
  974.     ld    b,0        ; Initialize parm #
  975.     jp    lpntry        ; We join loop in progress...
  976. sublp:
  977.     call    lkahed        ; Look at next char
  978.     jp    c,dosubs    ; If line empty, then plug in parm
  979.     call    numtst        ; Check for numeric
  980.     jp    c,dosubs    ; Done if not
  981. lpntry:
  982.     call    getchr        ; Now remove the char from input stream
  983.     sub    '0'        ; Remove ascii bias
  984.     ld    c,a        ; Save it
  985.     ld    a,b        ; Our accumulated count
  986.     add    a,a        ; Multiply  by ten
  987.     add    a,a
  988.     add    a,b
  989.     add    a,a
  990.     add    a,c        ; Then add in new digit
  991.     ld    b,a        ; Restore count
  992.     jp    sublp
  993. ;
  994. ;    PERFORM THE SUBSTITUTION
  995. ;
  996. dosubs:
  997.     ld    a,b        ; Get parm #
  998.     dec    a        ; Make zero relative
  999.     jp    m,parerr    ; Oops
  1000.     call    lookup        ; Look it up in parm table
  1001.     jp    c,parerr    ; It's not there
  1002.     ld    b,a        ; Length in b
  1003. sublp1:
  1004.     inc    b        ; Test b for zero
  1005.     dec    b
  1006.     jp    z,putlp        ; Done
  1007.     ld    a,(hl)        ; Get char of real parameter
  1008.     inc    hl        ; Point past for next time
  1009.     push    hl        ; Save real parm pointer
  1010.     call    putchr        ; Put it in the file
  1011.     pop    hl        ; Get back real parm pointer
  1012.     dec    b        ; Countdown
  1013.     jp    sublp1
  1014. ;
  1015. ;    COME HERE WHEN A LINE IS FINISHED,
  1016. ;    AND WE NEED TO WRITE THE BUFFER TO DISK
  1017. ;
  1018. flush:
  1019.     ld    hl,putcnt
  1020.     dec    (hl)        ; Adjust length
  1021.     ld    de,subfcb
  1022.     ld    c,writef
  1023.     call    bdos
  1024.     or    a
  1025.     jp    nz,wrerr    ; Cpm returned a write error
  1026.     ret
  1027. ;
  1028. ;    GETCHR GETS ONE CHAR FROM
  1029. ;    LINE STORED IN MEMORY
  1030. ;
  1031. getchr:
  1032.     ld    hl,getcnt
  1033.     ld    a,(hl)        ; Pick up count
  1034.     dec    a        ; Remove this char
  1035.     scf            ; Preset error
  1036.     ret    m        ; Return cy if out of chars
  1037.     ld    (hl),a        ; Update count
  1038.     ld    hl,(getptr)    ; Current char pointer
  1039.     ld    a,(hl)        ; Pick up char
  1040.     inc    hl        ; Bump pointer
  1041.     ld    (getptr),hl    ; Put it back
  1042.     ccf            ; Turn carry off
  1043.     ret
  1044. ;
  1045. ;    PUTCHR PUTS ONE CHAR TO
  1046. ;    THE OUTPUT BUFFER
  1047. ;
  1048. putchr:
  1049.     ld    hl,putcnt
  1050.     inc    (hl)        ; Increment count
  1051.     jp    m,lenerr    ; Line went to > 127 chars
  1052.     ld    hl,(putptr)    ; Get buffer pointer
  1053.     and    7fh        ; Mask out msb
  1054.     ld    (hl),a        ; Put char there
  1055.     inc    hl        ; Bump pointer
  1056.     ld    (putptr),hl    ; Put it back
  1057.     ret            ; All done
  1058. ;
  1059. ;    LOOK AHEAD ONE CHAR IN
  1060. ;    THE INPUT STREAM.  SET
  1061. ;    CARRY IF NONE LEFT.
  1062. ;
  1063. lkahed:
  1064.     ld    a,(getcnt)
  1065.     or    a        ; See if count is down to zero
  1066.     scf            ; Pre set indicator
  1067.     ret    z
  1068.     ld    a,(hl)        ; Pick up char
  1069.     ccf            ; Turn off carry flag
  1070.     ret
  1071. ;
  1072. ;    LOOK UP PARAMETER WITH NUMBER IN
  1073. ;    A REG. RETURN A=LENGTH OF PARM,
  1074. ;    AND HL => PARAMETER
  1075. ;
  1076. lookup:
  1077.     cp    npar
  1078.     jp    nc,parovf    ; Parm # too high
  1079.     ld    l,a
  1080.     ld    h,0        ; Now have 16 bit number
  1081.     add    hl,hl        ; Double for word offset
  1082.     ld    de,table
  1083.     add    hl,de        ; Do the offset
  1084.     ld    e,(hl)        ; Get address of parm
  1085.     inc    hl
  1086.     ld    d,(hl)
  1087.     ld    a,d        ; Anything there?
  1088.     or    e
  1089.     jp    nz,lkupok
  1090.     xor    a        ; No, zero length
  1091.     ret
  1092. lkupok:
  1093.     ex    de,hl        ; Now in de
  1094.     ld    a,(hl)        ; Pick up length
  1095.     inc    hl        ; Point past length
  1096.     ret
  1097. ;
  1098. ;    UTILITY COMPARE SUBROUTINE
  1099. ;
  1100. compar:
  1101.     ld    a,(de)
  1102.     cp    (hl)
  1103.     ret    nz
  1104.     inc    hl
  1105.     inc    de
  1106.     dec    b
  1107.     jp    nz,compar
  1108.     ret
  1109. ;
  1110. ;    NUMERIC TEST UTILITY SUBROUTINE
  1111. ;
  1112. numtst:
  1113.     cp    '0'
  1114.     ret    c
  1115.     cp    '9'+1
  1116.     ccf
  1117.     ret
  1118. ;
  1119. ;    ERROR HANDLERS
  1120. ;
  1121. wrerr:
  1122.     call    errxit
  1123.     db    'Disk Full',0
  1124. nomake:
  1125.     call    errxit
  1126.     db    'Dir Full',0
  1127. memerr:
  1128.     call    errxit
  1129.     db    'Mem Full',0
  1130. notfnd:
  1131.     call    errxit
  1132.     db    'SUB File Not Found',0
  1133. parerr:
  1134.     call    errxit
  1135.     db    'Param',0
  1136. parovf:
  1137.     call    errxit
  1138.     db    'Too Many Params',0
  1139. lenerr:
  1140.     call    errxit
  1141.     db    'Line too Long',0
  1142. notext:
  1143.     call    errxit
  1144.     db    'SUB File Empty',0
  1145. ccerr:
  1146.     call    errxit
  1147.     db    'Ctrl Char',0
  1148. errxit:
  1149.     call    crlf        ; New line
  1150.     pop    hl
  1151.     call    pstr        ; Print message
  1152.     call    print
  1153.     db    ' Error on Line ',0
  1154.     ld    hl,(linnum)    ; Tell line number
  1155.     call    phldc
  1156.     call    crlf
  1157.     ld    de,subfcb    ; Delete the $$$.sub file
  1158.     ld    c,deletf
  1159.     call    bdos
  1160.     jp    cpbase
  1161. ;
  1162. ;    INITIALIZE ALL VARIABLES
  1163. ;
  1164. initvar:
  1165.     ld    hl,var
  1166.     ld    bc,endvar-var
  1167. initlp:
  1168.     ld    (hl),0        ; Zero entire var area
  1169.     inc    hl
  1170.     dec    bc
  1171.     ld    a,b
  1172.     or    c
  1173.     jp    nz,initlp
  1174.     ld    hl,table    ; Init parm table pointer
  1175.     ld    (tblptr),hl
  1176.     ld    hl,0ffffh    ; Mark end of table
  1177.     ld    (endtbl),hl
  1178.     ld    hl,(fremem)    ; Free memory starts txt area
  1179.     ld    (txtptr),hl
  1180.     ret
  1181. ;
  1182. ; PRINT HELP WITH PROGRAM OPTIONS
  1183. ;
  1184. help:
  1185.     call    print
  1186.     db    cr,lf,'Syntax:'
  1187.     db    cr,lf,'  SUB                    - Print this HELP Message'
  1188.     db    cr,lf,'  SUB /A <text>          - Abort of SUBMIT File'
  1189.     db    cr,lf,'  SUB /AB <text> - Abort and Ring Bell'
  1190.     db    cr,lf,'  SUB /I<CR>             - Go into Interactive mode'
  1191.     db    cr,lf,'  SUB <FILE> <PARMS>     - Standard SUB File'
  1192.     db    0
  1193. gozcpr:
  1194.     ld    hl,(spsave)    ; Return to opsys
  1195.     ld    sp,hl
  1196.     ret
  1197. ;
  1198. ;    VARIABLE STORAGE
  1199. ;
  1200. var    equ    $
  1201. ;
  1202. aflag:
  1203.     db    0        ; Abort flag (0=no)
  1204. txtptr:
  1205.     dw    0        ; Free memory pointer
  1206. tblptr:
  1207.     dw    0        ; Pointer to parm table
  1208. duser:
  1209.     db    0        ; Default user number
  1210. linnum:
  1211.     dw    0        ; Current line number
  1212. prev:
  1213.     dw    0        ; Pointer to prev line
  1214. getcnt:
  1215.     db    0        ; Counter for 'get'
  1216. getptr:
  1217.     dw    0        ; Pointer for 'get'
  1218. putptr:
  1219.     dw    0        ; Pointer for 'put'
  1220. ibp:
  1221.     db    0        ; Input buffer pointer
  1222. clptr:
  1223.     dw    0        ; Command line pointer
  1224. bell$flag:
  1225.     db    0        ; Ring bell on abort flag
  1226. option:
  1227.     db    0        ; Opt option flag store
  1228. table:
  1229.     ds    npar*3        ; Parameter table
  1230. endtbl:
  1231.     dw    0ffffh        ; End of parameter table
  1232. ;
  1233. endvar    equ    $
  1234. spsave:
  1235.     dw    0        ; Stack pointer save
  1236. ;
  1237. ;
  1238. ;    FCB FOR $$$.SUB
  1239. ;
  1240. subfcb:
  1241.     db    1        ; Drive specifier (a selected)
  1242.     db    '$$$     '
  1243. subtyp:
  1244.     db    'SUB'
  1245.     dw    0,0,0,0        ; Initialize rest of fcb
  1246.     dw    0,0,0,0
  1247. ;TEC    dw    0,0,0,0
  1248.     dw    0,0        ;TEC
  1249.     db    0        ;TEC
  1250. subfr:    dw    0        ;TEC
  1251.     db    0        ;TEC
  1252. ;
  1253. clbuf:    ds    2        ; Ptr to command line buffer
  1254. fremem:    ds    2        ; Ptr to free memory area
  1255. ;
  1256.     end
  1257.  
  1258.