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 / BEEHIVE / UTILITYS / EASE10.ARC / EASE.Z80 < prev    next >
Text File  |  1990-07-21  |  37KB  |  1,863 lines

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