home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug144.arc / EASE16.LBR / EASE.ZZ0 / EASE.Z80
Text File  |  1979-12-31  |  38KB  |  1,970 lines

  1. ; PROGRAM:    Error And Shell Editor
  2. ; AUTHOR:    Paul Pomerleau and Jay Sage
  3. ; DATE:        October 23, 1987
  4. ; VERSION:    1.6
  5.  
  6. ; Copyright 1987, Paul Pomerleau
  7.  
  8. ; This program provides a history shell and error handler for ZCPR3.3
  9. ;   A complex line editor is used to edit command lines.
  10.  
  11. ; Run EASEDOC.COM to get a listing of Key-Command Bindings.
  12.  
  13. ; This file assembles with SLR's Z80ASM
  14.  
  15. ;=============================================================================
  16. ;
  17. ;        D E F I N I T I O N S    S E C T I O N
  18. ;
  19. ;=============================================================================
  20.  
  21. version    equ    16
  22. betastage    equ    ' '
  23.  
  24. no    equ    0
  25. yes    equ    0ffh
  26.  
  27. cr    equ    0dh
  28. lf    equ    0ah
  29. bell    equ    07h
  30. tab    equ    09h
  31.  
  32. bdos    equ    0005h
  33. bios    equ    0000h
  34. fcb    equ    005ch
  35. secbuf    equ    0080h
  36. sectop    equ    0100h
  37. killlen    equ    300
  38. maxsec    equ    8
  39.  
  40.     public    cout,ccout,print,pstr,crlf
  41.     extrn    qerror, getsrun, haltsub, z33chk, stopxsub, subon
  42.     extrn    getefcb
  43.     extrn    getmsg,getcst,putcst,putzex
  44. ;    extrn    print,pstr,cout,ccout,crlf    ; TOO LONG!!!!  Grr!!!
  45.     extrn    z3init,z3log,getquiet
  46.     extrn    getzrun,stopzex,haltzex
  47.     extrn    erradr,getcl1
  48.     extrn    acase2
  49.     extrn    getwhl,getduok,dutdir
  50.     extrn    getsh,qshell,shpush,shpop
  51.  
  52. ;=============================================================================
  53. ;
  54. ;        S T A N D A R D    P R O G R A M    H E A D E R
  55. ;
  56. ;=============================================================================
  57.  
  58. ENTRY:
  59.     jp    START
  60.     defb    'Z3ENV'
  61.     defb    3        ; Type-3 environment
  62. ENVADDR:
  63.     dw    0f300h
  64.     dw    ENTRY
  65.     defb    version
  66.  
  67.                 ; To go to the Error Handler, just
  68.                 ;   go to START with error flag set.
  69.  
  70. ;=============================================================================
  71. ;
  72. ;        C O N F I G U R A T I O N    A R E A
  73. ;
  74. ;=============================================================================
  75.  
  76. NAME:    db    'EASE    VAR'            ; Command history file
  77.  
  78. WIDTH:    dw    80                ; Length of line
  79.  
  80. TOOSHORT:
  81.     dw    02                ; Don't store in history 
  82.                         ;   if shorter than...
  83. GOBEGFLG:
  84.     db    yes
  85.  
  86. BEEPFLG:
  87.     db    yes
  88.  
  89. SMARTSAV:
  90.     db    no
  91.  
  92. NOP1:    db    0                ; Future expansion
  93. NOP34:    dw    0
  94.  
  95. TABLE:    db    [[LASTCASE - VECTOR] / 3]    ; Number of cases
  96.     dw    BEEP                ; Default case ring bell
  97.  
  98. VECTOR:    db    'Q'
  99.     dw    SHIFTED        ; Meta Key
  100.     db    'D'
  101.     dw    FCHR        ; Right Char
  102.     db    'S'
  103.     dw    BCHR        ; Left Char
  104.     db    'E'
  105.     dw    UP        ; Up line
  106.     db    'X'
  107.     dw    DOWN        ; Down line
  108.     db    'A'
  109.     dw    MBWORD        ; Left word
  110.     db    'F'
  111.     dw    MFWORD        ; Right word
  112.     db    'S'+80h
  113.     dw    GOBOLN        ; Start of line
  114.     db    'D'+80h
  115.     dw    GOEOLN        ; End of line
  116.     db    'G'
  117.     dw    FDEL        ; Del char right
  118.     db    'H'
  119.     dw    DELCHR        ; Del char left
  120.     db    127
  121.     dw    DELCHR        ; Del char left
  122.     db    'T'
  123.     dw    FDWORD        ; Del word right
  124.     db    127 + 80h
  125.     dw    BDWORD        ; Del word left
  126.     db    'R'
  127.     dw    CMDKILL        ; Kill to semi-colon
  128.     db    'Y'+80h
  129.     dw    DELTOEND    ; Delete to end of line
  130.     db    'Y'
  131.     dw    DELLIN        ; Delete line
  132.     db    'U'
  133.     dw    UNDO        ; Reinsert deleted text
  134.     db    'B'
  135.     dw    BACKLINE    ; Back in history shell
  136.     db    'N'
  137.     dw    NEXTLINE    ; Forward in history shell
  138.     db    'O'
  139.     dw    BSEARCH        ; Search for first char
  140.     db    'V'
  141.     dw    TOGLIN        ; Toggle insert
  142.     db    'I'
  143.     dw    ITAB        ; Insert Tab char
  144.     db    'P'
  145.     dw    QINSERT        ; Insert any char
  146.     db    'W'
  147.     dw    REPLOT        ; Redraw line
  148.     db    'C'
  149.     dw    WARM        ; Warm Boot
  150.     db    'M'
  151.     dw    DONE        ; End edit
  152.     db    '_'+80h
  153.     dw    QUITSH        ; End EASE
  154. LASTCASE:
  155.  
  156. PUNC:    db    ',.:!#%^&<>[]{}()_+-=`~/\|; ',tab
  157. PUNCLEN    equ    $ - PUNC
  158. ;=============================================================================
  159. ;
  160. ;        M A I N    C O D E    S E C T I O N
  161. ;
  162. ;=============================================================================
  163.  
  164. start:
  165.  
  166.     ld    hl,(envaddr)    ; Get environment address
  167.     call    z3init        ; Initialize library routines
  168.     call    z33chk
  169.     ret    nz
  170.     call    qerror        ; See if error handler invocation
  171.     jp    z,errorh    ; If so, branch to error processing
  172.     call    qshell
  173.     jp    z,RUNSH        ; Yes, don't install
  174.  
  175. ;=============================================================================
  176. ;
  177. ;        I N S T A L L A T I O N    C O D E
  178. ;
  179. ;=============================================================================
  180.  
  181. ; Program was invoked manually, so we need to set it up shell and error handler.
  182.  
  183. ;----------------------------------------
  184.  
  185. ; Subtask 1 -- determine whether to use a DU or a DIR prefix
  186. ;
  187. ; The program can examine the ZCPR33 option bytes to determine what features
  188. ; are supported (DU and/or DIR forms, which one first, wheel control over DU
  189. ; use, etc.).  For now we will just assume that a DU prefix will be used and
  190. ; will omit coding this block.
  191.  
  192. ;----------------------------------------
  193.  
  194. ; Get user option: if null, do both.  If E, then install the error handler
  195. ; else install the shell.
  196.  
  197.     ld    a,(5dh)
  198.     cp    'C'
  199.     jp    z,RUNSH
  200.     call    header
  201.     cp    ' '            ; Error handler and shell
  202.     jr    z,BOTH
  203.     cp    'E'            ; Only error handler
  204.     jr    z,ERRONLY
  205.     jr    ISHELL            ; Only the shell
  206. BOTH:    call    ISHELL
  207.  
  208. ;----------------------------------------
  209.  
  210. ; Subtask 2 -- build error handling command line including directory prefix
  211. ; using data from the external FCB.  We use the fact that the drive and user
  212. ; where the program was actually found along the path are stored in the
  213. ; command file control block.  The user number is kept in the usual place;
  214. ; the drive is kept in the following byte.  The drive is in the range 1..16
  215. ; (unless the command is resident, in which case the drive byte is 0).
  216.  
  217. ERRONLY:
  218.     call    getmsg        ; Get pointer to error command line
  219.     ld    de,10h        ; ..in message buffer
  220.     add    hl,de
  221.     call    PUT_NAME_TO_HL
  222.     call    getquiet
  223.     ret    nz
  224.     call    CLPRINT
  225.     dc    ' Error Handler'
  226.     jr    P_CLST
  227.  
  228. ISHELL:    call    GETSH        ; Is there a shell stack?
  229.     jr    nz,SHFINE    ; Yes
  230. SHBAD:    call    CLPRINT
  231. SHERR:    dc    'Shell Error'
  232.     ret
  233. SHFINE:    ld    hl,BUFFER
  234.     call    PUT_NAME_TO_HL
  235.     call    SHPUSH        ; Store the shell name
  236.     jr    nz,SHBAD    ; Push to deep?  Then abort
  237.     push    hl
  238.     call    SETFILE
  239.     call    RECOVER        ; Use existing file
  240.     call    PUTSEC
  241.     pop    hl
  242.     call    getquiet
  243.     ret    nz
  244. PRWELC:    call    CLPRINT
  245.     dc    ' Shell'
  246. P_CLST:    call    PRINT
  247.     dc    ': '
  248.     jp    PSTR        ; PRINT the string there and quit
  249.  
  250. RECOVER:
  251.     ld    hl,SSEC
  252.     ld    bc,BUFFER-SSEC-1
  253.     call    ZERO
  254.     call    SET
  255.     call    OPEN
  256.     jr    z,DELSET
  257. DOFNO:    call    FNOWRITE
  258.     jr    nz,DOFNO
  259.     call    FNOWRITE
  260.     jr    nz,DOFNO
  261.     jp    BNOWRITE
  262.  
  263. DELSET:    
  264.     ld    c,19        ; Delete
  265.     call    FBDOS
  266. SET:    xor    a
  267.     ld    (SSEC),a    ; First sector
  268.     ld    hl,SECBUF + 1    ; +1==So no long pause -- at least at first.
  269.     ld    (SFP),hl
  270.     jp    SAVETOWORK
  271.  
  272. PUT_NAME_TO_HL:
  273.     push    hl        ; Save pointer for way below
  274.     ex    de,hl        ; Switch pointer into DE
  275.  
  276.     call    getefcb        ; Get address of the command FCB
  277.     inc    hl        ; Advance pointer to name of program
  278.                 ; Get drive user from Z33's FCB.
  279.     push    hl
  280.     ld    bc,13        ; Offset to drive number
  281.     add    hl,bc        ; HL now points to the drive number
  282.  
  283. ; Here we get the drive where the program was found.  Since we know that this
  284. ; is not a resident program, there is no need to check for a zero value.
  285.  
  286.     ld    a,(hl)        ; Get it and
  287.     add    a,'A'-1        ; ..convert to a letter
  288.     ld    (de),a        ; Save in error command line
  289.     inc    de        ; Increment command line pointer
  290.  
  291.     dec    hl        ; Back up to user number
  292.     ld    a,(hl)        ; Get it and
  293.     call    mafdc        ; ..convert to decimal in command line
  294.  
  295.     ld    a,':'        ; Put in the colon
  296.     ld    (de),a
  297.     inc    de
  298.  
  299. cont1:
  300.     pop    hl        ; Restore the pointer to the command name
  301.     ld    bc,8        ; Copy 8 characters of name
  302.     ldir            ; ..into error command line
  303.  
  304.     xor    a        ; Store terminating null
  305.     ld    (de),a
  306.     pop    hl
  307.     ret
  308.  
  309. ;=============================================================================
  310. ;
  311. ;        E R R O R    H A N D L I N G    C O D E
  312. ;
  313. ;=============================================================================
  314.  
  315. ; This is the main entry point for error handling
  316.  
  317. errorh:
  318.     ld    a,(BEEPFLG)    ; Did the user want a Beep?
  319.     or    a
  320.     call    nz,BEEP
  321.  
  322. ;----------------------------------------
  323.  
  324. ; Subtask 1 -- Display program signon message
  325.  
  326. task1:
  327.     call    header
  328.  
  329. ;----------------------------------------
  330.  
  331. ; Subtask 2 -- Display system status
  332.  
  333. ; This task determines whether ZEX and/or SUBMIT are running.  Input
  334. ; redirection from either of them is turned off while error handling is
  335. ; performed (so user can provide the input).
  336.  
  337. task2:
  338.     call    stopzex        ; Stop ZEX input redirection
  339.  
  340.     call    CLPRINT
  341.     dc    lf,tab,'(ZEX '
  342.  
  343.     call    getzrun        ; Find out if ZEX is running
  344.     ld    e,a
  345.     ld    (ZEXORSUB),a
  346.     call    ponoff        ; Print on/off
  347.  
  348.     call    subon
  349.     jr    z,task2a    ; Branch if submit not supported
  350.  
  351.     call    PRINT
  352.     dc    ', SUBMIT '
  353.  
  354. ; See if submit is supported by the command processor
  355.  
  356.  
  357.     call    stopxsub    ; Stop XSUB input redirection
  358.     call    getsrun        ; Get submit running flag
  359.     call    ponoff        ; PRINT on/off
  360.     or    e
  361.     ld    (ZEXORSUB),a
  362.  
  363. ; See if wheel byte is on or off
  364.  
  365. task2a:
  366.     call    PRINT
  367.     dc    ', WHEEL '
  368.  
  369.     call    getwhl
  370.     call    ponoff
  371.     ld    a,')'
  372.     call    COUT
  373.  
  374. ;----------------------------------------
  375.  
  376. ; Subtask 3 -- Determine source of the error (internal or external) and
  377. ; display that information.
  378.  
  379. task3:
  380. ;    call    qerror
  381. ;    ret    nz        ; If not an error, then don't show the rest
  382.     call    CLPRINT
  383.     dc    tab
  384.     call    getcst        ; Get command status flag
  385.     bit    3,a        ; See if external command bit is set
  386.     jr    nz,external    ; Branch if external error
  387.  
  388.     call    PRINT        ; "IN"ternal
  389.     dc    'In'
  390.     jr    task3a
  391.  
  392. external:
  393.     call    PRINT        ; "EX"ternal
  394.     dc    'Ex'
  395.  
  396. task3a:
  397.     call    PRINT        ; "TERNAL ERROR"
  398.     dc    'ternal error #'
  399.  
  400.     call    xcmdoff        ; Clear the external command bit (and ECP bit)
  401.  
  402. ;----------------------------------------
  403.  
  404. ; Subtask 4 -- Determine the error return code and display information about
  405. ; the nature of the error.  This section of the code can be expanded to cover
  406. ; more error types as they are defined.
  407.  
  408. task4:
  409. ;    call    PRINT
  410. ;    defb    '#'
  411. ;    defb    0
  412.  
  413.     call    getmsg
  414.     ld    a,(hl)        ; Get the error return code
  415.     push    af        ; Save for use below
  416.     call    pafdc        ; Display the number
  417.     
  418.     call    PRINT
  419.     dc    ' -- '
  420.  
  421.     pop    af        ; Get error code back
  422.     cp    14
  423.     jr    c,OKERR
  424.     ld    a,4
  425. OKERR:    add    a        ; Make 8 bit skip into 16 bit
  426.     ld    e,a
  427.     ld    d,0
  428.     ld    hl,ERRSTRS - 2    ; Add to first string index
  429.     add    hl,de
  430.     ld    e,(hl)
  431.     inc    hl
  432.     ld    d,(hl)        ; Pull in string location
  433.     ex    de,hl
  434.     call    pstr        ; PRINT it
  435.     call    CRLF
  436.  
  437. ;----------------------------------------
  438.  
  439. ; Subtask 5 -- Display bad command line
  440. ;
  441. ; In the final code, much more elaborate error processing would be performed
  442. ; here (or more likely, the code here will be used as a framework for existing
  443. ; error handlers).
  444.  
  445. task5:
  446.     call    erradr        ; Get pointer to bad command line
  447.     push    hl        ; Save for reuse below
  448.     ld    de,BUFFER
  449.  
  450. scan:                ; Find end of this command
  451.     ld    a,(hl)
  452.     ld    (de),a
  453.     or    a        ; See if end of command line buffer
  454.     jr    z,GOTEND
  455.     cp    ';'        ; See if at command separator
  456.     jr    z,task5a
  457.     inc    hl        ; Point to next character
  458.     inc    de
  459.     jr    scan        ; Continue scanning
  460.  
  461. task5a:
  462.     push    af
  463.     push    hl
  464. FILLREST:
  465.     inc    hl
  466.     inc    de
  467.     ld    a,(hl)
  468.     ld    (de),a
  469.     or    a
  470.     jr    nz,FILLREST
  471.     pop    hl
  472.     pop    af
  473. GOTEND:
  474. OKT5A:    ld    a,(hl)
  475.     ld    (hl),0        ; Mark end of string
  476.     ld    (delimptr),hl    ; Save ptr to bad command's delimiter
  477.     ld    (delim),a    ; Store delimiter
  478.     push    af
  479.     ld    a,(ZEXORSUB)
  480.     or    a
  481.     jp    z,ERREDIT
  482.     call    CLPRINT
  483.     dc    tab,'Bad Command:',tab
  484.     pop    af
  485.     pop    hl        ; Restore pointer to beginning of command
  486.     push    af        ; Save delimiting character
  487.     call    pstr        ; Display the bad command
  488.  
  489.     pop    af
  490.     or    a
  491.     jr    z,task6        ; If no rest of line, get out without output
  492.     push    hl        ; Save pointer to rest of command line
  493.     call    CLPRINT
  494.     dc    tab,'Rest of Line:',tab
  495.     pop    hl
  496.  
  497. task5b:
  498.     dec    hl        ; Pt back to bad command delimiter
  499.     ld    (hl),a        ; Put semicolon back
  500.     inc    hl
  501.     call    pstr        ; PRINT rest of command line
  502.                 ;   AND RETURN!
  503.  
  504. ;----------------------------------------
  505.  
  506. ; Subtask 6 -- Deal with the bad command
  507.  
  508. ; This is where the real error handling is performed.  Here we just flush
  509. ; the entire command line and abort any submit job, but in a real error
  510. ; handler, several other functions would be performed.  With normal command
  511. ; lines (ZEX and SUBMIT not running), the user has the following three basic
  512. ; choices: fix the bad command, skip the bad command, or abort the entire
  513. ; command line.  If ZEX is running, there is an additional choice that should
  514. ; be available: abort the entire ZEX script.  Similarly, if SUBMIT is running,
  515. ; the user must be given the option to abort the entire submit job.
  516. ; This code implements all of the above with the additional feature
  517. ; that if the bad command is the last on the line, the option to skip
  518. ; to next command is not presented as it would be meaningless.
  519.  
  520. task6:
  521.     call    CLPRINT
  522.     dc    cr,lf,tab,'(E)dit/(A)bort'
  523.     ld    a,(delim)    ; Get bad command delimiter
  524.     or    a
  525.     jr    z,task6a    ; No trailing commands; skip next option
  526.     call    PRINT
  527.     dc    '/(C)ontinue'
  528. task6a:
  529.     call    PRINT
  530.     dc    ': '
  531.  
  532. task6c:    call    capin        ; get response
  533.     ld    b,a        ; Save for a moment
  534.     ld    a,(delim)    ; Get command delimiter again
  535.     or    a
  536.     ld    a,b        ; Response back in A
  537.     jr    z,task6b    ; Don't allow 's' choice if no trailing command
  538.     cp    'C'        ; Continue?
  539.     jr    z,skip
  540.  
  541. task6b:
  542.     cp    'A'        ; Abort?
  543.     jr    z,abort
  544.     cp    'E'        ; Edit?
  545.     jp    z,edit
  546.     call    beep        ; Bad input
  547.     jr    task6c
  548.  
  549. ;-----------------------------------------------------------------------------
  550.  
  551. ; Skip over bad command and resume with next in line
  552.  
  553. skip:
  554.     call    getcl1        ; Pt to command line buffer
  555.     ld    de,(delimptr)    ; DE pts to bad command's delimiter
  556.     inc    de        ; Now pointing to next command
  557.     ld    (hl),e        ; Stuff address in
  558.     inc    hl        ; ..first two bytes
  559.     ld    (hl),d        ; ..of multiple command line buffer
  560.  
  561.     call    PRINT
  562.     defb    'Continuing...',1
  563.     ret            ; Resume command execution with next command
  564.  
  565.  
  566. ;-----------------------------------------------------------------------------
  567.  
  568. ; Abort (flush) command line
  569.  
  570. abort:
  571.     call    abortmsg
  572.     call    getzrun        ; See if ZEX is running
  573.     jr    z,abort2    ; Branch if not
  574.  
  575. ; Deal with running ZEX script
  576.  
  577.     call    CLPRINT
  578.     dc    tab,'Abort ZEX script (Y/N)? '
  579.  
  580.     call    getyesno    ; Get user's answer
  581.     jr    nz,abort1    ; Branch if negative response
  582.  
  583.     call    haltzex        ; Abort ZEX
  584.     call    abortmsg
  585.     jr    abort2
  586.  
  587. abort1:
  588.     call    abort3
  589.  
  590. ; Deal with running SUBMIT job
  591.  
  592. abort2:
  593.     call    getsrun        ; Is a submit job running
  594.     ret    z        ; If not, return to command processor
  595.  
  596.     call    CLPRINT
  597.     dc    tab,'Abort SUBMIT job (Y/N)? '
  598.  
  599.     call    getyesno    ; Get user's answer
  600.     jr    nz,abort3    ; Branch if negative response
  601.  
  602.     call    haltsub        ; Abort SUBMIT
  603.  
  604. abortmsg:
  605.     call    PRINT
  606.     defb    'Aborted',1
  607.     ret
  608.  
  609. abort3:
  610.     call    PRINT
  611.     defb    ' No',1
  612.  
  613.     ret            ; Back to command processor
  614.  
  615. ;-----------------------------------------------------------------------------
  616.  
  617. ; XCMDOFF -- turn off external command flag
  618.  
  619. ; This routine turns off the external command bit and the ECP bit in the
  620. ; command status flag.
  621.  
  622. xcmdoff:
  623.     call    getcst        ; Get the command status flag
  624.     and    11110011b
  625. ;    res    3,a        ; Reset the external command bit
  626. ;    res    2,a        ; Reset the ECP bit also to prevent reentering
  627.                 ; ..the error handler on return
  628.     jp    putcst        ; Put new value back and return
  629.  
  630. ;-----------------------------------------------------------------------------
  631.  
  632. ; GETYESNO -- get yes/no answer from user
  633.  
  634. ; Only 'Y' or 'y' accepted as affirmative answers.  Routine returns Z if
  635. ; affirmative, NZ otherwise.
  636.  
  637. getyesno:
  638.     call    capin        ; Get user response
  639.     cp    'Y'
  640.     ret
  641.  
  642. ;-----------------------------------------------------------------------------
  643.  
  644. ; PONOFF -- PRINT ON or OFF in message
  645. ;
  646. ; If the Z flag is set on entry, 'OFF' is displayed; otherwize 'ON' is
  647. ; displayed.
  648.  
  649. ponoff:
  650.     jr    z,poff
  651.  
  652.     call    PRINT
  653.     dc    'ON'
  654.     ret
  655.  
  656. poff:
  657.     call    PRINT
  658.     dc    'OFF'
  659.     ret
  660.  
  661. ; ------------------------------
  662. ; header -- PRINT program name and version
  663. ;
  664. header:    call    CLPRINT
  665.     defb    'Z33 Error And Shell Editor, Vers. '
  666.     defb    version / 10 + '0'
  667.     defb    '.'
  668.     defb    version mod 10 + '0'
  669.     dc    betastage
  670.     ret
  671.  
  672. ; ------------------------------
  673. ; CLPRINT -- PRINT CR LF and then following string.
  674. CLPRINT:
  675.     call    CRLF
  676.     jp    PRINT
  677.  
  678. ;-----------------------------------------------------------------------------
  679. ; Prompt -- PRINT a DU/DIR prompt.
  680. ;
  681. PROMPT:    call    QPROMPT        ; PRINT the DU:DIR
  682.     ld    a,(INSFLG)
  683. INSPROMPT:
  684.     or    a
  685.     ld    a,'>'        ; For insert
  686.     jr    nz,INSOK
  687.     ld    a,'}'        ; For no insert
  688. INSOK:    call    COUT
  689.     ld    a,'>'
  690.     jp    COUT
  691.  
  692. QPROMPT:
  693.     call    QERROR
  694.     jr    nz,NOTERR
  695.     call    PRINT
  696.     dc    '[Error] '
  697. NOTERR:    call    getmsg
  698.     ld    bc,2eh
  699.     add    hl,bc
  700.     ld    c,(hl)
  701.     inc    hl
  702.     ld    b,(hl)
  703.     call    getduok
  704.     jr    z,NODU
  705.     ld    a,b
  706.     add    a,'A'        ; Make it a letter    
  707.     call    COUT        ; Write it
  708.     ld    a,c
  709.     call    pafdc        ; Write it as a number
  710. NODU:    call    dutdir        ; Get the NDR
  711.     ret    z
  712.     push    hl
  713.     call    getduok
  714.     ld    a,':'
  715.     call    nz,COUT        ; And the colon to separate
  716.     pop    hl
  717.     ld    b,8        ; Eight chars max
  718. NAMELOOP:
  719.     ld    a,(hl)        ; Get the first char
  720.     cp    ' '        ; Is it the last
  721.     ret    z        ; YUP.  done
  722.     call    COUT        ; Write it
  723.     inc    hl
  724.     djnz    NAMELOOP    ; Repeat
  725.     ret
  726.  
  727. ; -----------------------------------------------------------
  728. ; FillLine
  729. ;  Check length of the new, edited, command line.  If it will 
  730. ; fit, copy it to the Z3 multiple command line buffer and 
  731. ; return to the CPR to execute it.  Otherwise, display error 
  732. ; message and branch back to the editor.
  733.  
  734. GETLEN:    ld    hl,BUFFER
  735.     push    hl
  736.     xor    a
  737.     ld    bc,302
  738.     cpir            ; Find the ZERO
  739.  
  740.     dec    hl
  741.     pop    de
  742.     push    hl
  743.     sbc    hl,de        ; Get the length
  744.     ld    b,h
  745.     ld    c,l
  746.     pop    hl
  747.     ret
  748.  
  749. FILL:    xor    a
  750.     call    putcst        ; No errors
  751.     call    getcl1        ; Get Z3 command line addr in hl,
  752.                 ; ..length in a
  753.     cp    c        ; Compare with length of new line
  754.     jr    c,FILLERR    ; Branch if new line too long
  755.     ld    a,b        ; High order byte of length should be 0
  756.     or    a
  757.     jr    nz,FILLERR    ; Branch if not
  758.     push    hl        ; Save Z3CL
  759.     ld    de,4        ; Offset to first character in buffer
  760.     add    hl,de
  761.     ex    de,hl        ; First char address in DE
  762.     pop    hl        ; Z3CL address in HL
  763.     ld    (hl),e        ; Store ptr to first command
  764.     inc    hl        ; At Z3CL
  765.     ld    (hl),d
  766.     ld    hl,BUFFER    ; Get back pointer to new command
  767.     push    hl
  768.     inc    bc        ; Adjust length to include trailing null
  769.     ldir            ; Copy to system command line
  770.     call    qerror
  771.     pop    hl
  772.     ret    z        ; Return if it was an error
  773.     ld    a,(SAVFLG)
  774.     or    a
  775.     ret    z        ; Didn't change from read: Don't save
  776.     push    hl
  777.     call    GETLEN        ; Get length again
  778.     ld    hl,(TOOSHORT)
  779.     sbc    hl,bc
  780.     pop    hl
  781.     ret    nc        ; Too short to save
  782.     push    hl
  783.     call    OPEN        ; Open 'er up
  784.     call    SAVETOWORK    ; Move the values around
  785.     call    RRAND        ; Read in the current record
  786.     xor    a
  787.     call    WFFILE        ; Put the null to space the lines
  788.     pop    hl
  789. FILLWRITE:
  790.     ld    a,(hl)        ; Loop to put in the whole line
  791.     push    hl
  792.     call    WFFILE        ; Put in the next char of the line
  793.     pop    hl
  794.     ld    a,(hl)
  795.     inc    hl
  796.     or    a
  797.     jr    nz,FILLWRITE
  798.     call    BNOWRITE
  799.     call    PUTSEC
  800.     xor    a
  801.     call    WFFILE        ; Write final spacer null
  802. FLUSH:    call    WRAND
  803. CLOSE:    ld    c,16        ; Close the file
  804. FBDOS:    ld    de,FCB
  805.     jp    BDOS        ; Go back to CPR to execute it
  806.  
  807. FILLERR:            ; To long for CCP to digest
  808.     call    CLPRINT
  809.     defb    bell,tab
  810.     defb    'Too long!',1
  811.     jr    EDIT2
  812.  
  813. FINDSEC:
  814.     call    getsh        ; Get the sector number from the shell stack
  815.     ld    bc,128
  816.     xor    a
  817.     cpir            ; Find the ZERO
  818.     ld    a,(hl)        ; ?? Must be 0 -- but it isn't -- It's the SEC
  819.     ret
  820.  
  821. GETSEC:    call    FINDSEC        ; Put the new SEC to the saved var SEC
  822.     ld    (SSEC),a
  823.     inc    hl
  824.     ld    a,(hl)
  825.     inc    hl
  826.     ld    h,(hl)
  827.     ld    l,a
  828.     ld    (SFP),hl    ; Put the File Pointer to saved FP
  829. SAVETOWORK:
  830.     ld    a,(SSEC)    ; Move the saved vars to the working vars 
  831.     ld    (SEC),a
  832.     ld    hl,(SFP)
  833.     ld    (FP),hl
  834.     ret
  835.  
  836. PUTSEC:    call    FINDSEC        ; Get location of SEC
  837.     ld    a,(SEC)
  838.     ld    de,(FP)        ; Get SEC & FP
  839.     ld    (hl),a
  840.     inc    hl
  841.     ld    (hl),e
  842.     inc    hl
  843.     ld    (hl),d        ; Put the into the Shell Stack 
  844.     ret
  845.  
  846. ;-----------------------------------------------------------------------------
  847. ; Edit -- He, He, He...
  848. ;
  849. ERREDIT:
  850.     pop    af
  851.     pop    hl
  852.     jr    EDITNOE
  853. EDIT:    call    PRINT
  854.     db    'Edit',1    ; PRINT the 'E' for edit choice
  855. EDITNOE:
  856.     call    CRLF
  857.     ld    bc,BUFFER - ENDFLG - 1    ; Setup for zeroing out
  858.     jr    SETUP
  859.  
  860. ;--------------------------
  861.  
  862. ; Run Shell (RUNSH) -- clear out the buffers and go to the editor.
  863.  
  864. RUNSH1:    call    CRLF
  865.  
  866. RUNSH:    call    GETSEC        ; Get the sector number
  867.     ld    a,1        ; Z3 Cmd line for ZEX
  868.     call    putzex        ; Make ZEX think we are Z3
  869.     ld    bc,BUFFER - ENDFLG
  870. SETUP:    ld    hl,INSFLG    ; Fill and Zap
  871.     ld    (hl),0ffh
  872.     inc    hl
  873.     ld    (hl),0ffh
  874.     inc    hl
  875.     call    ZERO        ; Zero out to exhaustion of bc
  876.  
  877. EDIT2:
  878. ;    ld    hl,(envaddr)    ; Get environment address
  879. ;    call    z3init
  880.     call    OUTPUT1
  881. ELOOP:    xor    a
  882.     ld    (NOOUT+1),a    ; OK for output
  883.     call    GETKEY
  884.     ld    b,a
  885.     ld    a,(SHIFT)    ; Get shift mask
  886.     or    b
  887.     push    af
  888.     xor    a
  889.     ld    (SHIFT),a    ; Clear shift mask
  890.     pop    af
  891.     cp    ' '
  892.     jr    c,CONTROL    ; Yes, it's a command
  893.     cp    127
  894.     jr    nc,CONTROL
  895.     call    INSERT        ; No, it's just a letter
  896.     jr    ELOOP
  897.  
  898. CONTROL:
  899.     ld    hl,ELOOP    ; Return to...
  900.     push    hl
  901.     ld    de,TABLE    ; Go to proper command
  902.     call    UCASE
  903.     call    acase2
  904.  
  905. SHIFTED:
  906.     ld    a,10000000b    ; Make shift mask set high bit
  907.     ld    (SHIFT),a
  908.     ret
  909.  
  910. DELCHR:    call    DPOS        ; Back up and delete forward
  911.     ret    z
  912.     call    DELETE
  913.     jp    SHOWTOEND
  914.  
  915. FCHR:    call    FWRAP        ; Go ahead a char and wrap if EOL
  916.     jp    IPOS
  917.  
  918. FWRAP:    ld    hl,(POS)    ; Check for forward wrap
  919.     ld    a,(hl)
  920.     or    a
  921.     ret    nz
  922.     pop    hl
  923.     jp    GOBOLN
  924.  
  925. BCHR:    call    BWRAP        ; Go back and wrap if BOL
  926.     jp    DPOS
  927.  
  928. BWRAP:    ld    hl,(POS)    ; Check for back wrap
  929.     dec    hl
  930.     ld    a,(hl)
  931.     or    a
  932.     ret    nz
  933.     pop    hl
  934.     jp    GOEOLN
  935.  
  936. MBWORD:    call    BWRAP        ; Word forward with wrap
  937. BWORD:    call    DPOS        ; Word forward without
  938.     ret    z
  939.     inc    de
  940.     call    PUNCCP        ; Looking for punctuation
  941.     jr    z,BWORD        ; Skip punct
  942. BWORD2:    call    DPOS
  943.     ret    z
  944.     inc    de
  945.     call    PUNCCP        ; Go till we hit punct
  946.     jr    nz,BWORD2
  947.     dec    de
  948.     jp    IPOS
  949.  
  950. PUNCCP:    ld    hl,PUNC        ; Check for punctuation
  951.     ld    bc,PUNCLEN
  952.     cpir
  953.     ret
  954.  
  955. FDWORD:    ld    de,0        ; Delete forward a word
  956.     call    FWORD        ; Word forward
  957.     push    de
  958. FDWBACK:
  959.     ld    a,d
  960.     or    e
  961.     jr    z,FDWENDBACK
  962.     dec    de
  963.     call    DPOS        ; Back up same number of Chars
  964.     jr    FDWBACK
  965. FDWENDBACK
  966.     pop    de        ; Delete same number of chars
  967.     jr    BDWRD1
  968.  
  969. BDWORD:    ld    de,0        ; Delete a word backwards
  970.     call    BWORD
  971. BDWRD1:    ld    a,d
  972.     or    e
  973.     jp    z,SHOWTOEND
  974.     dec    de
  975.     push    de
  976.     call    DELETE        ; Delete same number
  977.     pop    de
  978.     jr    BDWRD1
  979.  
  980. MFWORD:    call    FWRAP        ; Forward word with wrap
  981. FWORD:    call    IPOS
  982.     ret    z
  983.     inc    de
  984.     call    PUNCCP        ; Skip until punct
  985.     jr    nz,FWORD
  986. FWORD2:    call    IPOS
  987.     ret    z
  988.     inc    de
  989.     call    PUNCCP        ; Skip punct
  990.     jr    z,FWORD2
  991.     dec    de
  992.     jp    DPOS        ; Back up one
  993.  
  994. UP:    ld    hl,(WIDTH)    ; Back 80 chars
  995. BACKUP:    ld    a,h
  996.     or    l
  997.     ret    z
  998.     dec    hl
  999.     push    hl
  1000.     call    DPOS        ; back up that many
  1001.     pop    hl
  1002.     ret    z
  1003.     cp    ' '
  1004.     jr    nc,BACKUP    ; Control chars count double
  1005.     ld    a,h
  1006.     or    l
  1007.     ret    z
  1008.     dec    hl
  1009.     jr    BACKUP
  1010.  
  1011. DOWN:    ld    hl,(WIDTH)    ; Go down a line
  1012. DOWNLOOP:
  1013.     ld    a,h
  1014.     or    l
  1015.     ret    z
  1016.     dec    hl
  1017.     push    hl
  1018.     call    IPOS        ; Forward 'til hl = zero
  1019.     pop    hl
  1020.     ret    z
  1021.     cp    ' '        ; Control chars count double
  1022.     jr    nc,DOWNLOOP
  1023.     ld    a,h
  1024.     or    l
  1025.     ret    z
  1026.     dec    hl
  1027.     jr    DOWNLOOP
  1028.  
  1029. WARM:    call    DONEOUT
  1030.     jp    0
  1031.  
  1032. DONE:    pop    hl        ; Save it and run it
  1033.     call    DONEOUT
  1034.     call    GETLEN        ; Get the length in BC
  1035. ;    call    qerror        ; Was it an error?
  1036. ;    jp    z,FILLL2
  1037.     ld    a,(BUFFER)
  1038.     cp    ';'        ; Comment?
  1039.     jr    z,JRUNSH
  1040.     or    a        ; Empty?
  1041.     jp    nz,FILL        ; Stuff the buffer
  1042. JRUNSH:    call    qerror
  1043.     ret    z
  1044.     call    qshell
  1045.     ret    nz
  1046.     jp    RUNSH1
  1047.  
  1048. FDEL:    call    DELETE        ; Delete forward a char
  1049.     ret    z
  1050.     jp    SHOWTOEND    ; Redisplay
  1051.  
  1052. QINSERT:
  1053.     call    GETKEY        ; Get a key and insert it -- whatever it is
  1054.     or    a
  1055.     ret    z
  1056.     jr    IJP
  1057.  
  1058. ITAB:    ld    a,tab        ; Insert a tab
  1059. IJP:    jp    INSERT
  1060.  
  1061. TOGLIN:    ld    hl,INSFLG    ; Toggle the insert flag
  1062.     ld    a,(hl)
  1063.     cpl
  1064.     ld    (hl),a
  1065.     ld    hl,(POS)
  1066.     push    hl
  1067.     push    af
  1068.     call    GOBOLN
  1069.     call    BACK
  1070.     call    BACK        ; Back up to the begining and back to ICHAR
  1071.     pop    af
  1072.     call    INSPROMPT
  1073.     pop    de
  1074. TOGLP:    ld    hl,(POS)    ; Go fwd to where we were
  1075.     sbc    hl,de
  1076.     ret    z
  1077.     call    IPOS
  1078.     jr    TOGLP
  1079.  
  1080. CMDKILL:
  1081.     ld    hl,(POS)
  1082.     ld    de,KILL
  1083.     push    de
  1084.     ld    bc,killlen    ; Stop before NULL in KILL
  1085.     ldir            ; Move it
  1086.     pop    hl
  1087. CKL:    push    hl
  1088.     call    DELETE        ; Delete to a semi-colon
  1089.     pop    hl
  1090.     inc    hl
  1091.     cp    ';'
  1092.     jr    z,CKDONE
  1093.     or    a        ; Or a NULL
  1094.     jr    nz,CKL
  1095. CKDONE:    ld    (hl),0
  1096.     jp    SHOWTOEND    ; Redisplay
  1097.  
  1098. DELLIN:    ld    hl,BUFFER
  1099.     ld    de,KILL
  1100.     ld    bc,killlen    ; Stop at NULL in KILL
  1101.     ldir            ; Move it
  1102. DELLN1:    call    GOBOLN        ; Go to start
  1103. DELTOEND:
  1104.     call    CLRTOEND    ; Wipe everything on screen
  1105.     ld    hl,(POS)
  1106.     ld    (hl),0        ; Put a null at the start
  1107.     ret
  1108.  
  1109. GOEOLN:    call    IPOS        ; Move to end of line
  1110.     jr    nz,GOEOLN
  1111.     ret
  1112.  
  1113. GOBOLN:    call    DPOS        ; Move to start of line
  1114.     jr    nz,GOBOLN
  1115.     ret
  1116.  
  1117. REPLOT:    ld    hl,(POS)    ; RePRINT entire line
  1118.     push    hl
  1119.     call    GOEOLN        ; Go to end and give us a CR LF
  1120. REPLT1:    call    CRLF
  1121.     call    OUTPUT        ; Redisplay
  1122.     pop    de
  1123. GOTOPOS:
  1124.     or    a
  1125.     call    IPOS        ; Move fwd to old position
  1126.     sbc    hl,de
  1127.     ret    z
  1128.     jr    c,GOTOPOS
  1129. GP2:    call    DPOS
  1130.     ret    z
  1131.     sbc    hl,de        ; Done?
  1132.     ret    z
  1133.     jr    GP2
  1134.  
  1135. CAPIN:    call    cin
  1136.     ; Fall through to UPCASE
  1137.  
  1138. UCASE:    push    bc        ; Upcase A
  1139.     push    af
  1140.     and    80h
  1141.     ld    b,a
  1142.     pop    af
  1143.     and    7fh        ; Keep high bit
  1144.     call    UCASE2        ; Real upcase
  1145.     or    b
  1146.     pop    bc
  1147.     ret
  1148.  
  1149. UCASE2:
  1150.     cp    ' '        ; Standard blah blah upcase funct
  1151.     jr    nc,NOTCTL
  1152.     add    '@'
  1153. NOTCTL:    cp    'a'
  1154.     ret    c        ; Not a lowercase
  1155.     cp    'z'+1
  1156.     ret    nc        ; Not a lowercase
  1157.     sub    ' '        ; Yes, a lowercase
  1158.     ret
  1159.  
  1160. BSEARCH:
  1161.     call    OPEN        ; Check for open, etc.
  1162.     ld    hl,(FP)        ; Get our locations
  1163.     ld    a,(SEC)
  1164.     push    af
  1165.     push    hl
  1166.     ld    a,(ENDFLG)    ; Did we hit the end?
  1167.     or    a
  1168.     jr    z,BBDONE
  1169.     ld    a,(BACKFLG)    ; Did we back up right before this?
  1170.     or    a
  1171.     jr    nz,BBDONE
  1172.     call    BNOWRITE
  1173.     jr    z,BSRCHNO1
  1174. BBACK:    call    BNOWRITE    ; Find the NULL
  1175.     jr    nz,BBACK
  1176. BBDONE:    ld    bc,BUFFER
  1177.     push    bc
  1178. BSRCHL:    call    BNOWRITE    ; Is this the end?
  1179. BSRCHL2:
  1180.     call    BNOWRITE
  1181.     jr    z,BSRCHNO
  1182.     call    FNOWRITE    ; No, Place us properly
  1183. BSRCL1:    call    BNOWRITE
  1184.     jr    nz,BSRCL1
  1185.     call    FNOWRITE
  1186.     ld    c,0
  1187.     pop    de
  1188.     push    de
  1189. BSRCHECKING:
  1190.     inc    c
  1191.     call    UCASE
  1192.     ld    b,a
  1193.     ld    a,(de)
  1194.     ld    hl,(POS)
  1195.     sbc     hl,de
  1196.     jr    z,BSRGOTIT
  1197.     inc    de
  1198.     call    UCASE        ; Make all upcase
  1199.     cp    b
  1200.     jr    nz,BSRGOTIT    ; Same?
  1201.     push    de
  1202.     push    bc
  1203.     call    FNOWRITE
  1204.     pop    bc
  1205.     pop    de
  1206.     jr    BSRCHECKING
  1207. BSRGOTIT:
  1208.     push    af
  1209.     ld    b,c
  1210. BSR_BACKING_UP:
  1211.     push    bc
  1212.     call    BNOWRITE
  1213.     pop    bc
  1214.     djnz    BSR_BACKING_UP
  1215.     pop    af
  1216.     jr    nz,BSRCHL2
  1217.     call    DELTOEND
  1218.     xor    a
  1219.     call    BESET        ; We went back -- Indicate it
  1220.     cpl
  1221.     ld    de,(POS)
  1222.     ld    (NOOUT+1),a
  1223.     pop    bc
  1224.     pop    hl
  1225.     pop    af
  1226.     push    de
  1227.     call    GETLINE        ; Get a whole line in
  1228.     pop    hl
  1229.     ld    (POS),hl
  1230.     call    NOSAV
  1231. ;    xor    a        ; Getline always ends with a null
  1232.     ld    (NOOUT+1),a
  1233.     jp    SHOWTOEND
  1234. BSRCHNO:
  1235.     pop    bc
  1236. BSRCHNO1:
  1237.     call    BEEP        ; Not found do the beep thing
  1238. PUTBACK:
  1239.     pop    hl
  1240.     pop    af
  1241.     ld    (FP),hl        ; Restore our pointers
  1242.     ld    (SEC),a
  1243. RRAND:    ld    c,21h
  1244.     call    DORAND        ; Read that first one back in
  1245.     or    a
  1246.     ret    z
  1247. ZBUF:    push    de
  1248.     ld    hl,SECBUF    ; Zero out our record
  1249.     ld    bc,127
  1250.     call    ZERO
  1251.     pop    de
  1252.     ret
  1253.  
  1254. QUITSH:    call    qerror        ; Pop the shell stack
  1255.     ret    z        ; Unless we are an error handler
  1256.     pop    hl
  1257.     call    SHPOP
  1258. DONEOUT:
  1259.     call    GOEOLN        ; Go to the end and CR
  1260.     ld    a,13
  1261. JCOUT:    jp    COUT
  1262.  
  1263. BEEP:    ld    a,bell
  1264.     jr    JCOUT
  1265.  
  1266. BACKLINE:            ; Go to previous command line
  1267.     call    OPEN
  1268.     ld    a,(ENDFLG)
  1269.     or    a
  1270.     call    z,EZER        ; Till we get to start
  1271. BGET:    call    BNOWRITE
  1272.     call    z,FNOWRITE
  1273.     jr    z,BEEP        ; No command line before
  1274.     ld    hl,TBUF
  1275.     ld    (hl),0
  1276.     inc    hl
  1277. BINSERT:            ; Insert the line backing up
  1278.     ld    (hl),a
  1279.     inc    hl
  1280.     push    hl
  1281.     call    BNOWRITE
  1282.     pop    hl
  1283.     jr    nz,BINSERT
  1284.     push    hl
  1285.     ld    hl,BACKFLG    ; Did we just go backwards?
  1286.     ld    a,(hl)
  1287.     ld    (hl),0ffh
  1288.     or    a
  1289.     pop    hl
  1290.     jr    z,BGET
  1291.     push    hl
  1292.     call    DELLN1        ; Kill existing line
  1293.     pop    hl
  1294.     dec    hl
  1295. BIN2:    ld    a,(hl)
  1296.     dec    hl
  1297.     or    a
  1298.     jr    z,GOBEGINOPTION    ; Put her there
  1299.     push    hl
  1300.     call    INSERT
  1301.     pop    hl
  1302.     jr    BIN2
  1303.  
  1304. GOBEGINOPTION:
  1305.     push    af
  1306.     ld    a,(GOBEGFLG)
  1307.     or    a
  1308.     call    nz,GOBOLN
  1309.     call    NOSAV
  1310.     pop    af
  1311.     ret
  1312.  
  1313. NEXTLINE:
  1314.     ld    a,(ENDFLG)    ; Are we at the end?
  1315.     or    a
  1316.     ret    z
  1317.     call    OPEN        ; Open the sucker if it ain't already
  1318. GETLINE:
  1319. FGET:    call    FNOWRITE
  1320.     jr    z,CHKTOP    ; At the end?
  1321.     push    af
  1322.     call    NOTTOP        ; Set flag
  1323.     pop    af
  1324.     ld    hl,TBUF
  1325. FINSERT:
  1326.     ld    (hl),a
  1327.     inc    hl
  1328.     push    hl
  1329.     call    FNOWRITE    ; Bring 'em in
  1330.     pop    hl
  1331.     jr    nz,FINSERT
  1332.     ld    (hl),0
  1333.     ld    hl,BACKFLG    ; Did we go back?
  1334.     ld    a,(hl)
  1335.     ld    (hl),0
  1336.     or    a
  1337.     jr    nz,FGET
  1338.     call    DELLN1        ; Delete the line
  1339.     ld    hl,TBUF
  1340. FIN2:    ld    a,(hl)
  1341.     inc    hl
  1342.     or    a
  1343.     jr    z,GOBEGINOPTION
  1344.     push    hl
  1345.     call    INSERT        ; Push the chars in
  1346.     pop    hl
  1347.     jr    FIN2
  1348.  
  1349. CHKTOP:    call    DELLN1        ; Clean out existing line
  1350.     call    BNOWRITE
  1351.     xor    a
  1352.     jr    ESET        ; Fix End Flag
  1353.  
  1354. NOTTOP:    xor    a
  1355.     cpl
  1356.     jr    ESET
  1357.  
  1358. EZER:    xor    a        ; Set the lot of them
  1359.     cpl
  1360. BESET:    ld    (BACKFLG),a
  1361. ESET:    ld    (ENDFLG),a
  1362.     ret
  1363.  
  1364. ; ---------------------------------------
  1365. ; Support routines for the commands above
  1366. ;
  1367. SETSCAN:
  1368.     push    af        ; Delete line and quiet terminal
  1369.     call    DELLN1
  1370.     xor    a
  1371.     cpl
  1372.     ld    (NOOUT+1),a
  1373.     pop    af
  1374.     ret
  1375.  
  1376. INSERT:    call    DOSAV
  1377.     ld    e,a        ; Put the char in
  1378.     ld    a,(INSFLG)
  1379.     or    a
  1380.     jr    nz,YAINS
  1381.     ld    hl,(POS)
  1382.     ld    a,(hl)
  1383.     or    a
  1384.     ld    a,e
  1385.     jr    nz,OVERWRITE    ; Do we insert?
  1386. YAINS:    xor    a
  1387.     ld    b,a
  1388.     push    de
  1389.     call    MOVEUP        ; Push them up
  1390.     pop    de
  1391.     jp    z,BEEP        ; No room
  1392.     ld    a,e
  1393. OVERWRITE:
  1394.     ld    hl,(POS)
  1395.     ld    (hl),a
  1396.     call    IPOS        ; Skip over it (PRINTing it)
  1397.     jr    SHOWTOEND    ; Redisplay
  1398.  
  1399. DELETE:    call    DOSAV
  1400.     ld    de,(POS)    ; Kill a char quiet-like
  1401.     ld    a,(de)
  1402.     or    a
  1403.     ret    z
  1404.     push    af
  1405.     ld    hl,DELETED
  1406.     inc    (hl)
  1407.     cp    ' '
  1408.     jr    nc,NOINC2    ; Increment DELETED as neccessary
  1409.     inc    (hl)
  1410. NOINC2:    call    MOVEDOWN    
  1411.     pop    af
  1412.     or    a
  1413.     ret
  1414.  
  1415. OUTPUT:    call    crlf        ; New line
  1416. OUTPUT1:
  1417.     call    PROMPT        ; Redisplay prompt
  1418. OUTPUT2:
  1419.     ld    hl,BUFFER    ; And command line
  1420.     ld    (POS),hl
  1421.     jp    SHOWTOEND
  1422.  
  1423. CLRTOEND:
  1424.     ld    hl,(POS)    ; Wipe out command line from cursor to right
  1425.     ld    de,0
  1426.     call    DOSAV
  1427. CLRLOOP:
  1428.     ld    a,(hl)        ; Loop until NULL
  1429.     or    a
  1430.     jr    z,NOWBACK
  1431.     cp    ' '
  1432.     jr    nc,CLR2
  1433.     inc    de
  1434.     call    SPACE        ; Two for Control Chars
  1435. CLR2:    call    SPACE        ; Overwrite it
  1436.     inc    hl
  1437.     inc    de
  1438.     jr    CLRLOOP
  1439. NOWBACK:
  1440.     ld    a,d
  1441.     or    e
  1442.     ret    z
  1443.     dec    de
  1444.     call    BACK        ; And return to old location
  1445.     jr    NOWBACK
  1446.  
  1447. IPOS:    ld    hl,(POS)    ; Get current char and PRINT it
  1448.     ld    a,(hl)
  1449.     or    a
  1450.     ret    z        ; Return zero if NULL
  1451.     push    af
  1452.     inc    hl
  1453.     ld    (POS),hl
  1454.     push    bc
  1455.     ld    b,a
  1456.     ld    a,(NOOUT + 1)    ; Silence?
  1457.     or    a
  1458.     ld    a,b
  1459.     pop    bc
  1460.     call    z,CCOUT
  1461.     pop    af
  1462.     ret
  1463.  
  1464. DPOS:    ld    hl,(POS)    ; Back up (^H)
  1465.     dec    hl
  1466.     ld    a,(hl)
  1467.     or    a
  1468.     ret    z
  1469.     push    af
  1470.     ld    (POS),hl
  1471.     cp    ' '
  1472.     call    c,BACK        ; Two for Control Char
  1473.     call    BACK
  1474.     pop    af
  1475.     ret
  1476.  
  1477. SHOWTOEND:
  1478.     call    PRINTHL        ; Show line to end
  1479.     jr    nz,SHOWLP
  1480.     ld    hl,DELETED    ; With spaces for deleted text
  1481.     ld    a,(hl)
  1482.     or    a
  1483.     jr    z,SHOWLP
  1484. SHW1:    push    af
  1485.     call    SPACE
  1486.     pop    af
  1487.     dec    a
  1488.     jr    nz,SHW1
  1489. SHW2:    call    BACK
  1490.     dec    (hl)
  1491.     jr    nz,SHW2
  1492. SHOWLP:    ld    a,d
  1493.     or    e
  1494.     ret    z
  1495.     dec    de
  1496.     call    DPOS
  1497.     jr    SHOWLP
  1498.  
  1499. PRINTHL:
  1500.     ld    de,0        ; Show text at HL to NULL
  1501. PHLOOP:    call    IPOS
  1502.     ret    z
  1503.     inc    de
  1504. KILLFLG:
  1505.     ld    a,0        ; Check for UNDO
  1506.     or    a
  1507.     ret    nz
  1508.     push    hl
  1509.     push    de
  1510.     push    bc
  1511.     ld    c,11        ; Check for console in
  1512.     call    BDOS
  1513.     pop    bc
  1514.     pop    de
  1515.     pop    hl
  1516.     or    a
  1517.     jr    z,PHLOOP
  1518.     call    cin        ; Check for previous input
  1519.     ld    (GETKEY+1),a
  1520.     cp    ' '
  1521.     jr    c,PHLOOP
  1522.     cp    127        ; If it's an input, don't redisplay
  1523.     ret    nz
  1524.     jr    PHLOOP
  1525.  
  1526. GETKEY:    ld    b,0
  1527.     xor    a
  1528.     ld    (GETKEY+1),a    ; Save the previous key
  1529.     ld    a,b
  1530.     or    a
  1531.     call    z,cin
  1532.     ret
  1533.  
  1534. MOVEUP:    ld    hl,(POS)    ; Move the text up to accept new char
  1535.     ld    a,' '
  1536. UPLOOP:    ld    b,(hl)
  1537.     ld    (hl),a
  1538.     inc    hl
  1539.     ld    a,b
  1540.     or    a
  1541.     jr    nz,UPLOOP
  1542.     ld    (hl),a
  1543.     ld    de,BUFFER + 300
  1544.     sbc    hl,de        ; Until the end
  1545.     jr    z,MOVEDOWN    ; No good, move it back
  1546.     or    1
  1547.     ret
  1548.  
  1549. MOVEDOWN:            ; Move a char out -- Delete
  1550.     ld    hl,(POS)
  1551.     ld    d,h
  1552.     ld    e,l
  1553. DNLOOP:    inc    hl
  1554.     ld    a,(hl)        ; Pull them down till we find a NULL
  1555.     ld    (de),a
  1556.     or    a
  1557.     inc    de
  1558.     jr    nz,DNLOOP
  1559.     ret
  1560.  
  1561. UNDO:    ld    hl,kill        ; Insert Kill buffer
  1562.     xor    a
  1563.     cpl
  1564.     ld    (KILLFLG + 1),a
  1565.     call    undo1
  1566.     xor    a
  1567.     ld    (KILLFLG + 1),a
  1568.     jp    SHOWTOEND
  1569. UNDO1:    ld    a,(hl)        ; insert at HL until NULL
  1570.     inc    hl
  1571.     or    a
  1572.     ret    z
  1573.     push    hl
  1574.     call    INSERT
  1575.     pop    hl
  1576.     jr    UNDO1
  1577.  
  1578. WFFILE:    call    RCHECK        ; Forward a char in the file with write
  1579.     ld    de,(FP)
  1580.     ld    (de),a
  1581.     ld    hl,SECTOP-1
  1582.     sbc    hl,de
  1583.     jr    nz,FNOWRITE
  1584.     call    WRAND
  1585. FNOWRITE:            ; Forward a char
  1586.     call    RCHECK
  1587.     ld    de,(FP)
  1588.     inc    de
  1589.     ld    hl,SECTOP
  1590.     sbc    hl,de
  1591.     jr    nz,NOREAD
  1592.     ld    hl,SEC
  1593.     inc    (hl)
  1594.     call    RRAND
  1595.     ld    de,SECBUF
  1596. NOREAD:    ld    a,(de)
  1597.     ld    (FP),de
  1598.     or    a
  1599.     ret
  1600.  
  1601. WBFILE:    call    RCHECK        ; Back a char in file with write
  1602.     ld    de,(FP)
  1603.     ld    (de),a
  1604.     ld    hl,SECBUF
  1605.     sbc    hl,de
  1606.     jr    nz,BNOWRITE
  1607.     call    WRAND
  1608. BNOWRITE:            ; Back a char
  1609.     call    RCHECK
  1610.     or    a
  1611.     ld    de,(FP)
  1612.     dec    de
  1613.     ld    hl,SECBUF-1
  1614.     sbc    hl,de
  1615.     jr    nz,NOREAD
  1616.     ld    hl,SEC
  1617.     dec    (hl)        ; Should never get to be ZERO... Honest.
  1618.     jr    nc,BNOZERO
  1619.     ld    (hl),0        ; But, what the hell, it's free.
  1620. BNOZERO:
  1621.     call    RRAND
  1622.     ld    de,SECTOP-1
  1623.     jr    NOREAD
  1624.  
  1625. WRAND:    ld    c,22h        ; Write random
  1626.     call    DORAND
  1627.     or    a
  1628.     ret    z
  1629.     jp    nz,WMERR
  1630.  
  1631. DORAND:    ld    a,(SEC)        ; Put random record in right place in FCB
  1632.     ld    hl,FCB+33    ; Set the DMA and call BDOS
  1633.     ld    (hl),a
  1634.     inc    hl
  1635.     xor    a
  1636.     ld    (hl),a
  1637.     inc    hl
  1638.     ld    (hl),a
  1639.     push    de
  1640.     call    SETDMA
  1641.     call    FBDOS
  1642.     pop    de
  1643.     ret
  1644.  
  1645. SETDMA:    push    bc        ; Set the DMA to the SECBUF
  1646.     ld    c,1ah
  1647.     ld    de,SECBUF
  1648.     call    BDOS
  1649.     pop    bc
  1650.     ret
  1651.  
  1652. BCD2:    push    bc        ; Format two digit numbers
  1653.     ld    c,0ffh
  1654. BCD2A:    inc    c
  1655.     sub    10
  1656.     jr    nc,BCD2A    ; Put them in BCD (??) form
  1657.     add    a,10
  1658.     ld    b,a
  1659.     ld    a,c
  1660.     rlca
  1661.     rlca
  1662.     rlca
  1663.     rlca
  1664.     or    b
  1665.     pop    bc
  1666.     ret
  1667.  
  1668. PAFDC:    ld    d,0        ; PRINT them out
  1669.  
  1670. MAFDC:    push    af        ; Put them in a memory location
  1671.     call    BCD2
  1672.     push    af
  1673.     rra
  1674.     rra
  1675.     rra
  1676.     rra
  1677.     and    1111b
  1678.     call    nz,DEPUT    ; Output tens
  1679.     pop    af
  1680.     call    DEPUT        ; Output ones
  1681.     pop    af
  1682.     ret
  1683. DEPUT:    and    1111b
  1684.     add    '0'
  1685.     inc    d
  1686.     dec    d        ; Check for output
  1687.     jp    z,COUT
  1688.     ld    (de),a        ; Else memory stuff
  1689.     inc    de
  1690.     ret
  1691.  
  1692. ;
  1693. ; Bdos console in. With no echo.
  1694. ;
  1695. CIN:    push    hl
  1696.     push    de
  1697.     push    bc
  1698.     ld    hl,(1)
  1699.     ld    de,9
  1700.     add    hl,de
  1701.     ld    (hl),0C9h
  1702.     push    hl
  1703.     ld    c,1
  1704.     call    BDOS
  1705.     pop    hl
  1706.     ld    (hl),0c3h
  1707.     pop    bc
  1708.     pop    de
  1709.     pop    hl
  1710.     ret
  1711.  
  1712. RCHECK:    push    af        ; Have we read already?
  1713.     ld    a,(RDFLG)
  1714.     or    a
  1715.     jr    nz,RCK1        ; Yes
  1716.     cpl
  1717.     ld    (RDFLG),a    ; No, now yes
  1718.     push    hl
  1719.     push    bc
  1720.     call    RRAND        ; And read
  1721.     pop    bc
  1722.     pop    hl
  1723. RCK1:    pop    af
  1724.     ret
  1725.  
  1726. SETFILE:            ; Make FCB ok w/respect to Z33 FCB
  1727.     ld    hl,FCB
  1728.     ld    bc,35 + 80h    ; Zero out FCB and DMA.
  1729.     call    ZERO
  1730.     ld    hl,NAME
  1731.     ld    de,FCB+1
  1732.     ld    bc,11
  1733.     ldir
  1734.     call    getefcb
  1735.     ld    bc,14        ; Offset to drive number
  1736.     add    hl,bc        ; HL now points to the drive number
  1737.  
  1738. ; Here we get the drive where the program was found.  Since we know that this
  1739. ; is not a resident program, there is no need to check for a zero value.
  1740.  
  1741.     ld    a,(hl)        ; Get it and
  1742.     ld    de,FCB
  1743.     ld    (de),a
  1744.     dec    hl        ; Back up to user number
  1745.     ld    a,(hl)        ; Get it and
  1746.     ld    (FCB+13),a    ; put it in our FCB
  1747.     ld    de,FCB
  1748.     jp    z3log
  1749.  
  1750. OPEN:    call    qerror
  1751.     ret    z        ; Don't perform any file operations!
  1752.     ld    hl,OPENFLG    ; Open the file
  1753.     ld    a,(hl)
  1754.     or    a
  1755.     ret    nz
  1756.     ld    (hl),0ffh
  1757.     call    SETFILE
  1758.     ld    c,15        ; Open
  1759.     call    FBDOS
  1760.     inc    a
  1761.     ret    nz
  1762. YANEW:    call    DELSET
  1763.     ld    c,22        ; Make
  1764.     call    FBDOS
  1765.     inc    a
  1766.     jr    z,WMERR
  1767.     call    ZBUF
  1768.     call    SETDMA
  1769.     xor    a
  1770.     ret
  1771.  
  1772. NOSAV:    push    af
  1773.     xor    a
  1774. SAVSTO:    push    bc
  1775.     ld    b,a
  1776.     ld    a,(SMARTSAV)
  1777.     or    b
  1778.     ld    (SAVFLG),a
  1779.     pop    bc
  1780.     pop    af
  1781.     ret
  1782.  
  1783. DOSAV:    push    af
  1784.     xor    a
  1785.     cpl
  1786.     jr    SAVSTO
  1787.  
  1788. ZERO:    ld    d,h        ; Fill and area with zeros
  1789.     ld    e,l
  1790.     inc    de
  1791.     ld    (hl),0
  1792.     ldir
  1793.     ret
  1794.  
  1795. WMERR:    call    GOEOLN        ; Write and error message
  1796.     call    crlf
  1797.     ld    hl,DISKFULL
  1798.     call    pstr
  1799.     ld    a,'!'
  1800.     ld    (OPENFLG),a
  1801.     call    COUT
  1802.     pop    hl
  1803.     jp    REPLOT
  1804.  
  1805. PRINT:    ex    (sp),hl        ; PRINT a string
  1806.     call    PSTR
  1807.     ex    (sp),hl
  1808.     ret
  1809.  
  1810. PSTR:    push    af        ; PRINT a string at HL
  1811.     ld    a,(hl)
  1812.     inc    hl
  1813.     or    a
  1814.     jr    z,PSTR1
  1815.     cp    1
  1816.     jr    z,DCRLF        ; If 1, then end with a CRLF
  1817.     push    af
  1818.     and    01111111b
  1819.     call    COUT
  1820.     pop    af
  1821.     and    10000000b
  1822.     jr    nz,PSTR1
  1823.     pop    af
  1824.     jr    PSTR
  1825. DCRLF:    call    CRLF
  1826. PSTR1:    pop    af
  1827.     ret
  1828.  
  1829. CCOUT:    push    af
  1830. ;    cp    8        ; For valid CCOUT, these are needed...
  1831. ;    jr    z,OK        ;   But who's gonna know?
  1832. ;    cp    13
  1833. ;    jr    z,OK
  1834. ;    cp    10
  1835. ;    jr    z,OK
  1836.     cp    ' '
  1837.     jr    nc,OK
  1838.     push    af
  1839.     ld    a,'^'
  1840.     call    COUT
  1841.     pop    af
  1842.     add    '@'
  1843. OK:    call    COUT
  1844.     pop    af
  1845.     ret
  1846.  
  1847. SPACE:    ld    a,' '        ; PRINT a space
  1848.     jr    COUT
  1849.  
  1850. BACK:    ld    a,8        ; PRINT a ^H
  1851.  
  1852. COUT:    push    af        ; Output
  1853.     push    bc
  1854.     push    de
  1855.     push    hl
  1856.     ld    e,a
  1857.  
  1858. NOOUT:    ld    a,0        ; Being quiet
  1859.     or    a
  1860.     ld    c,6
  1861.     call    z,pbdos        ; And the real PRINT
  1862.     pop    hl
  1863.     pop    de
  1864.     pop    bc
  1865. CPOP:    pop    af
  1866.     ret
  1867.  
  1868. PBDOS:    ld    a,e
  1869.     ld    hl,SPOS
  1870.     cp    8
  1871.     jr    z,BACKP
  1872.     cp    13
  1873.     jr    z,ZEROP
  1874.     cp    7
  1875.     jr    z,NOIP
  1876.     cp    10
  1877.     jr    z,NOIP
  1878.     cp    9
  1879.     jr    z,TABCHR
  1880.     inc    (hl)
  1881. NOIP:    jp    BDOS        ; BIOS COUT
  1882. ZEROP:    ld    (hl),1
  1883. BACKP:    dec    (hl)
  1884.     jr    NOIP
  1885. TABCHR:    ld    a,' '        ; Expand Tab
  1886.     call    COUT
  1887.     ld    a,7
  1888.     and    (hl)
  1889.     ret    z
  1890.     jr    TABCHR
  1891.  
  1892. CRLF:    call    PRINT        ; PRINT a CRLF
  1893.     dc    cr,lf
  1894.     ret
  1895.  
  1896.  
  1897. ;============================================================================= 
  1898. ;               C O N S T A N T S
  1899. ;=============================================================================
  1900. ERRSTRS:
  1901.     defw    duchange    ; Illegal attempt to change directory
  1902.     defw    baddu        ; Invalid directory
  1903.     defw    badpw        ; Incorrect password
  1904.     defw    unknown
  1905.     defw    badform        ; Bad command form (wild or type given)
  1906.     defw    badecp        ; Command not found (even by ECP)
  1907.     defw    badcmd        ; Command file not found (ECP skipped)
  1908.     defw    ambig        ; Ambiguous file spec
  1909.     defw    badnum        ; Bad numerical value
  1910.     defw    nofile        ; Object file not found
  1911.     defw    diskfull    ; Disk is full
  1912.     defw    overflow    ; TPA overflow
  1913.     defw    duplicate    ; Source filespec=destination <crw>
  1914.  
  1915. duchange:
  1916.     dc    'Illegal attempt to change directory'
  1917. baddu:
  1918.     dc    'Invalid directory'
  1919. badpw:
  1920.     dc    'Incorrect password'
  1921. badform:
  1922.     dc    'Bad command name (file type or wild card used)'
  1923. badecp:
  1924.     dc    'Command not found (even by ECP)'
  1925. badcmd:
  1926.     dc    'Requested load file not found on disk'
  1927. ambig:
  1928.     dc    'Ambiguous or missing file name'
  1929. badnum:
  1930.     dc    'Bad numerical expression'
  1931. nofile:
  1932.     dc    'Source file not found'
  1933. diskfull:
  1934.     dc    'Disk full'
  1935. overflow:
  1936.     dc    'TPA overflow'
  1937. duplicate:
  1938.     dc    'Duplicate file specifications'
  1939. unknown:
  1940.     dc    'Unknown error'
  1941. ;============================================================================= 
  1942. ;               B U F F E R S 
  1943. ;=============================================================================
  1944. SSEC    equ    entry + 1100h
  1945. SEC    equ    ssec + 1
  1946. SFP    equ    sec + 2
  1947. FP    equ    sfp + 2
  1948. POS    equ    fp + 2
  1949. DELIMPTR    equ    pos + 2
  1950. DELIM    equ    delimptr + 2
  1951. ZEXORSUB    equ    delim + 2
  1952. INSFLG    equ    zexorsub + 1
  1953. BACKFLG    equ    insflg + 1
  1954. ENDFLG    equ    backflg + 1
  1955. RDFLG    equ    endflg + 1
  1956. OPENFLG    equ    rdflg + 1
  1957. SHIFT    equ    openflg + 1
  1958. SAVFLG    equ    shift + 1
  1959. SPOS    equ    savflg + 1
  1960. DELETED    equ    spos + 1
  1961. TBUF    equ    deleted + 2
  1962. KILL    equ    tbuf + 302
  1963. BUFFER    equ    kill + killlen + 2
  1964. DEFAULT_TOP_OF_BUFFER    equ    buffer + 300
  1965.     end
  1966. s + 1
  1967. TBUF    equ    deleted + 2
  1968. KILL    equ    tbuf + 302
  1969. BUFFER    equ    kill + killlen + 2
  1970. DEFAU