home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / ZCPR33 / A-R / GETVAR12.LBR / GETVAR12.ZZ0 / GETVAR12.Z80
Text File  |  2000-06-30  |  20KB  |  996 lines

  1. ; GETVAR.MAC
  2. ;
  3. ; ZCPR3-Specific Utility.
  4. ; Prints a user-specified prompt, accepts a response, and assigns the response
  5. ; to a user-specified shell variable.
  6. ; Syntax is:
  7. ;
  8. ;        GETVAR <varname> <prompt text>
  9. ;
  10. ; The only option is help, which is exclusive (it must appear first on the
  11. ; command line, and the rest of the command line will not be processed).
  12. ; Note that this program does NOT check to see that the user is a Wheel, but
  13. ; does prevent the user from aborting with a Control-C.
  14. ;
  15. ; Author: Dreas Nielsen
  16. ;
  17. ; History --
  18. ;    Version        Date        Comments
  19. ;    -------        ----        --------
  20. ;    1.0        3/8/86        Off the ground - RDN
  21. ;    1.1        1/17/87        Changed to use Z3VARLIB routines
  22. ;                    and turned ZEX off if necessary.
  23. ;    1.2        9/6/87        Incorporated scrolling line editor
  24. ;                    instead of SYSLIB's INLINE.
  25. ;                    Control-C aborts with no change to
  26. ;                    shell variable.
  27. ;
  28. ;
  29. VERS    EQU    12
  30. ;
  31. ;
  32. PARMFL    EQU    '/'        ; flag indicating parameter follows
  33. CTRLZ    EQU    1AH        ;^Z for EOF
  34. EOF    EQU    1AH
  35. BELL    EQU    07H
  36. FCB    EQU    5CH
  37. TBUFF    EQU    80H
  38. BDOS    EQU    5
  39. BS    EQU    8
  40. CR    EQU    0DH
  41. LF    EQU    0AH
  42. ;
  43. CMDLIN    EQU    80H    ; CP/M's command line buffer
  44. ;
  45. ;
  46. ; ====  Input Control Keys  ====
  47. ;
  48. ; Line editor:
  49. ;    ^S or left-arrow key defined in TCAP : move left 1 char
  50. ;    ^D or right-arrow key defined in TCAP : move right 1 char
  51. ;    ^E : erase to [E]nd of line
  52. ;    ^U : delete char [U]nder cursor
  53. ;    ^W : delete [W]ord forward
  54. ;    ^X : kill entire line
  55. ;    DEL : delete char before cursor
  56. ;    TAB : move to end of line, or if at end, to beginning
  57. ;    ^A : move to beginning of previous word
  58. ;    ^F : move to beginning of next word
  59. ;    ^H : delete char before cursor
  60. ;    ^Q : [Q]uote next char--insert char literal
  61. ;    ^C : abort if at beginning of line.
  62. ;
  63. ; Cursor keys are evaluated first, and may override others if they
  64. ; generate a corresponding code.  For instance, on '83 Kaypros the backspace
  65. ; key will move left rather than deleting left.  Use of CP/M standard line
  66. ; editing keys (^E, ^U, ^R, & ^X) will, it is hoped, reduce other such 
  67. ; conflicts.
  68. ;
  69. ; Note that the ^P printer toggle does not work inside this input editor;
  70. ; the keystroke now defaults to another function.
  71. ;
  72. ;
  73. TOGKEY    EQU    'I'-'@'        ;Toggles between beginning & end of line.
  74. DELBAK    EQU    127        ;Deletes previous character.
  75. DELUND    EQU    'U'-'@'        ;Deletes current character.
  76. CLREND    EQU    'E'-'@'        ;Erases to the end of the line.
  77. FORWRD    EQU    'F'-'@'        ;Move to next word forward.
  78. BAKWRD    EQU    'A'-'@'        ;Move to next word backward.
  79. QUOTE    EQU    'Q'-'@'        ;Quote next character.
  80. KILWRD    EQU    'W'-'@'        ;Delete word forward.
  81. CTRLC    EQU    'C'-'@'        ;Aborts if at beginning of line.
  82. CTRLX    EQU    'X'-'@'        ;Erases entire line.
  83. ;
  84. ;
  85. ; SYSLIB and Z3LIB routines
  86. ;
  87.     EXT    Z3INIT,PUTER2,ROOT,INLINE,GETFN1,QPRINT,PSTR
  88.     EXT    SKSP,PUTUD,LOGUD,INITFCB,FILLB,F$DELETE,F$RENAME,F$MAKE
  89.     EXT    F$OPEN,F$CLOSE,GETUD,CAPS,PRINT,CRLF,COUT,CODEND
  90.     EXT    PUTZEX
  91.     EXT    GETCRT,GETVID,CIN
  92. ;
  93. ; Z3VARS routines
  94. ;
  95.     EXT    VARDEF,VARLOAD,DELVAR,ADDVAR,WRTVARS
  96. ;
  97. ;
  98. ; Locate environment pointer and version # at absolute address
  99. ;
  100. ;
  101.     DB    'Z3ENV'
  102.     DB    1
  103. Z3ENV:    DW    00
  104.     DB    VERS        ;embed version number
  105. ;
  106. ;
  107.     CSEG
  108. ;
  109. ; Program beginning
  110. ;
  111. ;
  112. ; Initialize environment for Z3 routines
  113. START:    LD    HL,(Z3ENV)
  114.     CALL    Z3INIT
  115. ;
  116. ; Reset error flag
  117.     XOR    A
  118.     CALL    PUTER2
  119. ;
  120. ; Save stack and set a new one
  121.     LD    (SAVESP),SP
  122.     LD    HL,STK
  123.     LD    SP,HL
  124. ;
  125. ; Print signon message
  126.     CALL    QPRINT
  127. ;    DB    'GETVAR v. ',(VERS/10)+'0','.',(VERS MOD 10)+'0',CR,LF,0
  128.     DB    'GETVAR v. ',[VERS/10]+'0','.',[VERS MOD 10]+'0',CR,LF,0
  129. ;
  130. ; Allocate storage
  131.     CALL    CODEND
  132.     LD    (LINEBUF),HL    ;variable definition
  133.     LD    DE,255
  134.     ADD    HL,DE
  135.     LD    (VARLIST),HL    ;list of variables
  136. ;
  137. ; Save currently logged DU
  138.     CALL    PUTUD
  139. ;
  140. ; Patch RAWOUT routine to use BIOS console output
  141. ;
  142.     LD    HL,(1)
  143.     LD    DE,9
  144.     ADD    HL,DE
  145.     LD    (CONOUT),HL
  146. ; Load index register IX with base address of data structure for recording
  147. ; editing position.
  148. ;
  149.     LD    IX,EDIDAT
  150. ;
  151. ; Patch SYSLIB 'cout' routine so that chars printed can be recorded
  152. ;
  153.     LD    HL,COUT
  154.     LD    A,0C3H        ;1st byte of JP instruction
  155.     LD    (HL),A
  156.     INC    HL
  157.     LD    DE,ADVANCE    ;patch routine
  158.     LD    A,E
  159.     LD    (HL),A
  160.     INC    HL
  161.     LD    A,D
  162.     LD    (HL),A
  163. ;
  164. ; Get screen line length and cursor keys
  165. ;
  166.     CALL    GETCRT
  167.     LD    A,(HL)
  168.     LD    (SCRWID),A
  169.     CALL    GETVID
  170.     JR    Z,OPTCHK    ;If no TCAP, use default cursor keys
  171.     LD    DE,16        ;Point to arrow keys.
  172.     ADD    HL,DE
  173.     LD    A,(HL)
  174.     OR    A        ;Is key defined?
  175.     JR    Z,OPTCHK
  176.     INC    HL
  177.     INC    HL
  178.     LD    A,(HL)
  179.     LD    (RT),A
  180.     INC    HL
  181.     LD    A,(HL)
  182.     LD    (LFT),A
  183. ;
  184. ; Check for option designator or no command line
  185. OPTCHK:    LD    HL,FCB+1
  186.     LD    A,(HL)
  187.     CP    PARMFL
  188.     JP    Z,HELP
  189.     CP    '?'
  190.     JP    Z,HELP
  191.     CP    ' '
  192.     JP    Z,HELP
  193. ;
  194. ; Load variable name into SHVAR buffer
  195.     LD    HL,CMDLIN    ;store null at end of command line
  196.     LD    A,(HL)        ;get length
  197.     INC    A
  198.     LD    E,A
  199.     XOR    A
  200.     LD    D,A
  201.     ADD    HL,DE
  202.     LD    (HL),A
  203. ;
  204.     LD    HL,CMDLIN+1
  205.     CALL    SKSP
  206.     PUSH    HL
  207.     LD    HL,SHVAR    ;pt to shell variable buffer
  208.     LD    B,8        ;8 chars max
  209.     LD    A,' '        ;space fill
  210.     CALL    FILLB
  211.     EX    DE,HL        ;DE pts to shell variable buffer
  212.     POP    HL        ;pt to shell variable
  213.     LD    B,8        ;8 chars max
  214. ;
  215. ; Place Shell Variable into Buffer
  216. ;
  217. EXPV1:
  218.     LD    A,(HL)        ;get char
  219.     CALL    DELCK        ;check for delimiter
  220.     JR    Z,PTPMT        ;done if delimiter
  221.     LD    (DE),A        ;save char
  222.     INC    HL        ;pt to next
  223.     INC    DE
  224.     DJNZ    EXPV1
  225. ;
  226. ; Flush Overflow of Shell Variable
  227. ;
  228. EXPV2:
  229.     LD    A,(HL)        ;get char
  230.     INC    HL        ;pt to next
  231.     CALL    DELCK        ;check for delimiter
  232.     JR    NZ,EXPV2
  233.     DEC    HL        ;pt to delimiter
  234. ;
  235. ; Shell Variable in buffer SHVAR
  236. ;    HL pts to delimiter after variable in user line
  237. ;
  238. ; Point to prompt and save position
  239. PTPMT:    CALL    SKSP
  240.     LD    (PMTPTR),HL
  241. ;
  242. ; Find shell variable file and load variables
  243.     LD    HL,(VARLIST)
  244.     CALL    VARLOAD
  245.     JR    Z,OFFZEX    ;if variables loaded OK
  246.     CALL    PRINT        ;else print error msg and exit
  247.     DB    CR,LF,BELL,'Can''t load shell variable file ',0
  248.     JP    EXIT
  249. ;
  250. ; Turn off ZEX if it's running
  251. OFFZEX:    LD    A,2
  252.     CALL    PUTZEX
  253. ;
  254. ; Print prompt to user
  255. PRPRMPT:
  256.     CALL    CRLF
  257.     LD    (IX),0        ;Chars out = 0
  258.     LD    HL,(PMTPTR)
  259.     CALL    PSTR
  260.     LD    A,' '
  261.     CALL    COUT
  262. ;
  263. ; Get user's response
  264.     LD    HL,(LINEBUF)
  265.     XOR    A
  266.     LD    (HL),A
  267.     LD    HL,SCRWID    ;Compute chars remaining on screen line.
  268.     LD    A,(IX)        ;First see if prompt wrapped.
  269. CLINE1:    CP    (HL)        ;If chars printed > screen width, subtract
  270.     JR    C,CLINE2    ; screen width and repeat test.
  271.     SUB    (HL)
  272.     JR    CLINE1
  273. CLINE2:    LD    B,A
  274.     LD    A,(HL)        ;Now find chars remaining (scroll space).
  275.     SUB    B        ; Subtract chars printed for prompt...
  276.     DEC    A        ; ...and an extra position for the cursor.
  277.     LD    (IX+1),A
  278.     CALL    SCROLLIN
  279. ;
  280. ; Quit if no line entered
  281. QLINE:    LD    A,(HL)
  282.     OR    A
  283.     JP    Z,EXIT
  284. ;
  285. ; Put variable name and text onto end of list in memory
  286.     LD    HL,SHVAR
  287.     LD    DE,(LINEBUF)
  288.     CALL    ADDVAR
  289. ;
  290. ; Write out shell variable file
  291. WRTV:    CALL    WRTVARS
  292.     JP    Z,EXIT
  293. ;
  294. ; File write error.  Set error message byte,
  295. ;  print error message, and exit.
  296. WRERR:
  297.     CALL    SETERR
  298.     CALL    PRINT
  299.     DB    CR,LF,BELL,'Write error on shell variable file.',0
  300.     JR    EXIT
  301. ;
  302. ; Print help message and fall through to exit
  303. HELP:
  304.     CALL    PRINT
  305.     DB    'GETVAR -- Prompts for and gets a shell variable.',CR,LF
  306.     DB    'Syntax is:',CR,LF
  307.     DB    '       GETVAR <varname> <prompt text>',CR,LF
  308.     DB    0
  309. ;
  310. ; Return to ZCPR3
  311. ;
  312. EXIT:
  313.     CALL    GETUD
  314.     LD    HL,(SAVESP)
  315.     LD    SP,HL
  316.     RET
  317. ;
  318. ;================[ Subroutines ]================
  319. ;
  320. ;--- DELCK
  321. ;
  322. ; Check to see if char in A is a delimiter
  323. ;    Return with Z if so
  324. ;
  325. DELCK:
  326.     PUSH    HL        ;pt to table
  327.     PUSH    BC        ;save BC
  328.     CALL    CAPS        ;capitalize char
  329.     LD    B,A        ;char in B
  330.     LD    HL,DTABLE    ;pt to delimiter table
  331. DELCK1:
  332.     LD    A,(HL)        ;get delimiter
  333.     OR    A        ;done?
  334.     JR    Z,NOTDEL
  335.     CP    B        ;compare
  336.     JR    Z,YESDEL
  337.     INC    HL        ;pt to next
  338.     JR    DELCK1
  339. NOTDEL:
  340.     LD    A,B        ;get char
  341.     OR    A        ;set Z if null, else NZ
  342. YESDEL:
  343.     LD    A,B        ;restore char
  344.     POP    BC        ;restore regs
  345.     POP    HL
  346.     RET    
  347. ;
  348. ; Delimiter Table
  349. ;
  350. DTABLE:
  351.     DB    '<>;:,.=-_ ',0
  352. ;
  353. ;----------------
  354. ;
  355. ; --- SETERR
  356. ;
  357. ; Set program error code
  358. SETERR:
  359.     PUSH    AF
  360.     XOR    A
  361.     DEC    A
  362.     CALL    PUTER2
  363.     POP    AF
  364.     RET
  365. ;
  366. ;
  367. ;----------------------------------------------------------------
  368. ;    ---  SCROLLIN  ---
  369. ;
  370. ;    Scrolling Line Editor
  371. ;
  372. ;
  373. ; Table of line-editor execution vectors.
  374. ;
  375.     DB    'EDCMDS'
  376. EDCMDS:
  377. RT:    DB    'D'-'@'
  378. LFT:    DB    'S'-'@'
  379.     DB    DELUND
  380.     DB    DELBAK
  381.     DB    BS
  382.     DB    TOGKEY
  383.     DB    CTRLX
  384.     DB    CLREND
  385.     DB    FORWRD
  386.     DB    BAKWRD
  387.     DB    KILWRD
  388.     DB    QUOTE
  389.     DB    CTRLC
  390. NUMEDS    EQU    $-EDCMDS
  391. ;
  392. ;  Table of line-editor functions
  393. ;
  394. EDFUNCS:
  395.     DW    FORWARD        ;Move ahead 1 char.
  396.     DW    BACKUP        ;Move back 1 char.
  397.     DW    DELETE        ;Delete char under cursor.
  398.     DW    BEHIND        ;Delete char behind cursor.
  399.     DW    BEHIND        ;Delete char behind cursor.
  400.     DW    TOGGLE        ;Move to end or beginning of line.
  401.     DW    ERASE        ;Erase line.
  402.     DW    EREOL        ;Erase to end of line.
  403.     DW    NXTWRD        ;Move forward 1 word.
  404.     DW    PRVWRD        ;Move backward 1 word.
  405.     DW    ERAWRD        ;Erase word forward.
  406.     DW    LITCHAR        ;Next char literal.
  407.     DW    QABORT        ;Abort if at beginning.
  408. ;
  409. ;
  410. ;----------------
  411. ;
  412. SCROLLIN:
  413.     LD    HL,(LINEBUF)
  414.     LD    (CURRPOS),HL
  415.     LD    (BEGLINE),HL
  416.     XOR    A
  417.     LD    (HL),A        ;Empty line to start.
  418.     LD    (IX),A        ;Cursor position at beginning.
  419.     LD    (IX+2),A    ;0 characters entered.
  420. ;
  421. SCRIN1:
  422.     CALL    CIN
  423.     CP    CR
  424.     JR    Z,SCREND
  425. ;
  426. ; Scan table of editing commands for a match.
  427. ;
  428.     LD    HL,EDCMDS
  429.     LD    BC,NUMEDS
  430.     CPIR
  431.     JR    Z,SCRIN3
  432.     CALL    INSERT        ;Not a command character, so insert it.
  433.     JR    SCRIN1
  434. ;
  435. SCRIN3:                ;Char is a command.
  436.     DEC    HL        ;Point to pointer to command address.
  437.     LD    DE,EDCMDS
  438.     OR    A
  439.     SBC    HL,DE
  440.     SLA    L
  441.     LD    DE,EDFUNCS
  442.     ADD    HL,DE
  443.     LD    E,(HL)        ;Get command address.
  444.     INC    HL
  445.     LD    D,(HL)
  446.     LD    HL,SCRIN1    ;Put return address on stack.
  447.     EX    DE,HL
  448.     PUSH    DE
  449.     JP    (HL)        ;Execute routine.
  450. ;
  451. SCREND:
  452.     CALL    CURSBAK
  453.     LD    HL,(LINEBUF)
  454.     CALL    PSTR
  455.     RET            ;Done editing.
  456. ;
  457. ;
  458. ;----------------
  459. ;
  460. RETREAT:
  461.     PUSH    AF
  462.     LD    A,8
  463.     CALL    RAWOUT
  464.     DEC    (IX)
  465.     POP    AF
  466.     RET
  467. ;
  468. ;----------------
  469. ;
  470. SCRPUT:            ;prints 1 char, or 2 if control-char
  471.     CP    32
  472.     JR    C,PUT2
  473.     CALL    ADVANCE
  474.     RET
  475. PUT2:    LD    B,A
  476.     LD    A,'^'
  477.     CALL    ADVANCE
  478.     LD    A,B
  479.     SET    6,A
  480.     CALL    ADVANCE
  481.     RET
  482. ;
  483. ;----------------
  484. ; Send cursor to beginning of line
  485. ;
  486. CURSBAK:
  487.     LD    A,(IX)
  488.     OR    A
  489.     RET    Z
  490.     LD    B,A
  491.     LD    A,8
  492. CB1:    CALL    RETREAT
  493.     DJNZ    CB1
  494.     RET
  495. ;
  496. ;----------------
  497. ; Send pointer to beginning of line, at beginning of window.
  498. ;
  499. TOBEG:
  500.     CALL    CURSBAK
  501.     LD    HL,(LINEBUF)    ;Reset 'begline' & 'currpos' to 'linebuf'.
  502.     LD    (BEGLINE),HL
  503.     LD    (CURRPOS),HL
  504.     CALL    UPDATE        ;Redraw line.
  505.     RET
  506. ;
  507. ;----------------
  508. ; Send cursor to end of line, at end of window if line is longer than window.
  509. ;
  510. TOEND:                ;Send cursor to end of line.
  511.     LD    HL,(CURRPOS)
  512.     LD    A,(IX+1)    ;(printable chars allowed)
  513.     CP    (IX+2)        ;(chars actually entered)
  514.     JR    NC,TOEND6    ;Skip calculation of new beginning position
  515. TOEND1:    LD    A,(HL)        ;Use HL for 'currpos'.
  516.     INC    HL
  517.     OR    A
  518.     JR    NZ,TOEND1
  519.     DEC    HL        ;Now HL points to terminating null.
  520. TOEND2:    LD    B,(IX+1)    ;Move 'currpos' back by 'printable' chars.
  521. TOEND3:    DEC    HL
  522.     LD    A,(HL)
  523.     CP    32        ;Is it control char?
  524.     JR    NC,TOEND4
  525.     DEC    B        ;If so, subtract an extra position.
  526.     JR    Z,TOEND5
  527. TOEND4:    DJNZ    TOEND3
  528. ;
  529. TOEND5:    LD    (BEGLINE),HL    ;Now save 'begline'.
  530.     CALL    CURSBAK        ;Back up cursor.
  531. TOEND6:                ;Write chars up to end of line.
  532.     LD    A,(HL)
  533.     OR    A
  534.     JR    Z,TOEND7
  535.     PUSH    HL
  536.     CALL    WRTCHAR
  537.     POP    HL
  538.     INC    HL
  539.     JR    TOEND6
  540. TOEND7:    LD    (CURRPOS),HL    ;Now save modified 'currpos'
  541.     RET
  542. ;
  543. ;----------------
  544. ; Toggle between beginning and end of line.  Go to end, or go to beginning
  545. ; if already at end.
  546. ;
  547. TOGGLE:    LD    HL,(CURRPOS)
  548.     LD    A,(HL)
  549.     OR    A
  550.     JR    Z,TOG1
  551.     CALL    TOEND
  552.     RET
  553. TOG1:    CALL    TOBEG
  554.     RET
  555. ;
  556. ;----------------
  557. ; Write the character in A, scrolling left if necessary.
  558. ;
  559. WRTCHAR:
  560.     PUSH    AF        ;Save character.
  561.     CP    32        ;Is it a control character?
  562.     JR    NC,WRTC2    ;If not, just check for cursor at end of window.
  563.     LD    A,(IX+1)    ;Compute 'printable' - 'curspos'.
  564.     SUB    (IX)
  565.     CP    2        ;Within 2 places of end?
  566.     JR    NC,WRTC3    ;If not, just go print character.
  567.     OR    A        ;Just one position?
  568.     JR    NZ,WRTC4
  569.     CALL    SCROLL
  570. WRTC4:    CALL    SCROLL
  571.     JR    WRTC3        ;Done scrolling for control char.
  572. WRTC2:    LD    A,(IX)        ;For non-ctrl-char: is cursor at end of window?
  573.     CP    (IX+1)
  574.     JR    NZ,WRTC3    ;If not, don't scroll.
  575.     CALL    SCROLL
  576. WRTC3:    POP    AF        ;Get character back.
  577.     CALL    SCRPUT
  578.     RET
  579. ;
  580. ;----------------
  581. ; Scroll the window left by one character.
  582. ;
  583. SCROLL:
  584.     PUSH    HL        ;For when FORWRD calls WRTCHAR calls SCROLL.
  585.     CALL    CURSBAK
  586.     LD    DE,(CURRPOS)
  587.     LD    HL,(BEGLINE)    ;Get & increment 'begline'.
  588.     INC    HL
  589.     LD    (BEGLINE),HL
  590.     DEC    DE        ;Decrement 'currpos' for comparison
  591. SCROLL1:
  592.     PUSH    HL
  593.     OR    A
  594.     SBC    HL,DE        ;is HL up to DE yet?
  595.     LD    A,H
  596.     OR    L
  597.     POP    HL
  598.     JR    Z,SCROLL2    ;If so, quit.
  599.     LD    A,(HL)
  600.     CALL    SCRPUT        ;Else print the char.
  601.     INC    HL
  602.     JR    SCROLL1
  603. SCROLL2:
  604.     CALL    UPDATE
  605.     POP    HL
  606.     RET
  607. ;
  608. ;----------------
  609. ; Updates the line from the current position to the end of the window.
  610. ; This will print characters until either the end of the line or the end
  611. ; of the window is reached.  Up to 2 blanks will be printed following the
  612. ; line, if there is room in the window, to obliterate previously printed
  613. ; characters in case a control character has just been deleted.
  614. ;
  615. UPDATE:
  616.     LD    HL,(CURRPOS)    ;HL = next char to print.
  617.     LD    D,0        ;B = # of chars printed.
  618. UPD1:
  619.     LD    A,(IX)        ;Is 'curspos' = 'printable'?
  620.     CP    (IX+1)
  621.     JR    Z,UPDEND    ;If Z, we've reached end of window.
  622.     LD    A,(HL)
  623.     OR    A        ;Is character 0?
  624.     JR    Z,UPDFILL    ;If Z, we've reached end of line.
  625.     CP    32        ;Is it a control char?
  626.     JR    NC,UPD2        ;If not, go on and print it.
  627.     LD    C,A        ;Save char temporarily.
  628.     LD    A,(IX+1)    ;Is there only one space left in window?
  629.     SUB    (IX)
  630.     CP    1
  631.     JR    NZ,UPD3        ;If not, go print char(s)
  632.     LD    A,' '        ;If so, print just a space...
  633.     CALL    ADVANCE
  634.     INC    D
  635.     JR    UPDEND        ;...and go back up cursor.
  636. UPD3:    LD    A,C        ;Get control char back.
  637.     INC    D        ;Increment D for extra char to be printed.
  638. UPD2:    CALL    SCRPUT
  639.     INC    D
  640.     INC    HL        ;Point to next char in buffer.
  641.     JR    UPD1
  642. UPDFILL:            ;Pad with 1 or 2 spaces if possible.
  643.     LD    A,(IX)
  644.     CP    (IX+1)
  645.     JR    NC,UPDEND
  646.     LD    A,' '
  647.     CALL    ADVANCE
  648.     INC    D
  649.     LD    A,(IX)
  650.     CP    (IX+1)
  651.     JR    NC,UPDEND
  652.     LD    A,' '
  653.     CALL    ADVANCE
  654.     INC    D
  655. UPDEND:    LD    A,D
  656.     OR    A        ;Any chars printed?
  657.     RET    Z
  658.     LD    B,D
  659. UPD4:    CALL    RETREAT        ;Back up cursor to initial position.
  660.     DJNZ    UPD4
  661.     RET
  662. ;
  663. ;----------------
  664. ; Move the cursor and current position pointer forward in sync.
  665. ; Return the character at the next position.
  666. ;
  667. FORWARD:
  668.     LD    HL,(CURRPOS)
  669.     LD    A,(HL)
  670.     OR    A
  671.     RET    Z
  672.     INC    HL
  673.     LD    (CURRPOS),HL
  674.     CALL    WRTCHAR
  675.     LD    A,(HL)
  676.     OR    A
  677.     RET
  678. ;
  679. ;----------------
  680. ; Back up the cursor and buffer pointer in sync, ensuring that the screen
  681. ; is scrolled if necessary.
  682. ;
  683. BACKUP:
  684.     LD    A,(IX)        ;Is cursor at beginning of line?
  685.     OR    A
  686.     JR    NZ,BACK1    ;If not, go on.
  687.     CALL    POSCHK        ;Are we at beginning of buffer?
  688.     RET    Z        ;Do nothing if so.
  689.     LD    DE,(CURRPOS)
  690.     DEC    DE
  691.     LD    (BEGLINE),DE
  692.     LD    (CURRPOS),DE
  693.     CALL    UPDATE        ;Cursor doesn't move.
  694.     RET
  695. BACK1:
  696.     LD    DE,(CURRPOS)
  697.     DEC    DE        ;Dec 'currpos'
  698.     LD    (CURRPOS),DE
  699.     LD    A,(DE)
  700.     CP    32        ;Is it a control-char?
  701.     JR    NC,BACK2    ;If not, back up just once.
  702.     CALL    RETREAT
  703. BACK2:    CALL    RETREAT
  704.     RET
  705. ;
  706. ;----------------
  707. ; Erase word forward.  If at beginning of word, erase trailing blank also.
  708. ;
  709. ERAWRD:
  710.     LD    HL,(CURRPOS)
  711.     LD    A,(IX)
  712.     OR    A
  713.     JR    Z,ERAWD1
  714.     DEC    HL
  715.     LD    A,(HL)
  716.     CP    ' '
  717.     JR    Z,ERAWD1
  718.     CP    ';'
  719.     JR    NZ,ERAWD2
  720. ERAWD1:    XOR    A
  721. ERAWD2:    LD    (SPDEL),A
  722. ERAWD3:    LD    HL,(CURRPOS)
  723.     LD    A,(HL)
  724.     OR    A
  725.     RET    Z
  726.     CP    ';'
  727.     RET    Z
  728.     CP    ' '
  729.     JR    Z,ERAWD4
  730.     CALL    DELETE
  731.     JR    ERAWD3
  732. SPDEL    EQU    $+1
  733. ERAWD4:    LD    A,0
  734.     OR    A
  735.     RET    NZ
  736.     CALL    DELETE
  737.     RET
  738. ;
  739. ;----------------
  740. ; Abort if at the beginning of the line, else insert a ^C.
  741. ;
  742. QABORT:    CALL    POSCHK
  743.     JP    NZ,QAB2
  744.     CALL    ERASE
  745.     CALL    PRINT
  746.     DB    '<aborted>',0
  747.     JP    EXIT
  748. QAB2:    LD    A,CTRLC
  749.     CALL    INSERT
  750.     RET
  751. ;
  752. ;----------------
  753. ; Insert the character in A at the current position
  754. ;
  755. INSERT:
  756.     OR    A
  757.     RET    Z        ;Don't insert a null.
  758.     LD    C,A
  759.     LD    A,(IX+2)    ;Max chars already?
  760.     CP    (IX+3)
  761.     RET    Z
  762.     LD    HL,(CURRPOS)
  763. INS1:    LD    A,(HL)        ;Move all chars up.
  764.     LD    B,A        ;Ring-around-the-rosy in the registers.
  765.     LD    A,C        ;Using 'LDDR' is an alternative, but requires
  766.     LD    C,B        ; that a pointer be kept to the end of the
  767.     LD    (HL),A        ; line, and code is no smaller.
  768.     INC    HL
  769.     OR    A        ;Have we just stored the null?
  770.     JR    NZ,INS1
  771.     CALL    FORWARD
  772.     INC    (IX+2)
  773.     CALL    UPDATE
  774.     RET
  775. ;
  776. ;----------------
  777. ; Delete the character at the cursor
  778. ;
  779. DELETE:
  780.     LD    HL,(CURRPOS)
  781.     LD    A,(HL)
  782.     OR    A
  783.     RET    Z
  784.     LD    E,L
  785.     LD    D,H
  786.     INC    DE
  787. DEL1:    LD    A,(DE)
  788.     LD    (HL),A
  789.     INC    DE
  790.     INC    HL
  791.     OR    A
  792.     JR    NZ,DEL1
  793.     DEC    (IX+2)
  794.     CALL    UPDATE
  795.     RET
  796. ;
  797. ;----------------
  798. ; Delete the character behind the cursor.
  799. ;
  800. BEHIND:
  801.     CALL    POSCHK
  802.     RET    Z
  803.     CALL    BACKUP
  804.     CALL    DELETE
  805.     RET
  806. ;
  807. ;----------------
  808. ; Skip forward to next word.
  809. ;
  810. NXTWRD:
  811.     LD    HL,(CURRPOS)
  812.     LD    A,(HL)
  813.     OR    A
  814. NXTW1:    RET    Z
  815.     CP    ' '        ;If in whitespace, go skip to its end
  816.     JR    Z,NXTW2
  817.     CP    ';'
  818.     JR    Z,NXTW2
  819.     CALL    FORWARD
  820.     JR    NXTW1
  821. NXTW2:    CALL    FORWARD
  822.     RET    Z
  823.     CP    ' '
  824.     JR    Z,NXTW2
  825.     CP    ';'
  826.     JR    Z,NXTW2
  827.     CALL    FORWARD
  828.     CALL    BACKUP
  829.     RET
  830. ;
  831. ;----------------
  832. ; Skip backward to beginning of previous word.
  833. ;
  834. PRVWRD:
  835.     CALL    BACKUP
  836.     CALL    POSCK2
  837.     RET    Z
  838.     CP    ' '
  839.     JR    Z,PRVWRD
  840.     CP    ';'
  841.     JR    Z,PRVWRD
  842. PRVW1:    CALL    BACKUP
  843.     CALL    POSCK2
  844.     RET    Z
  845.     CP    ' '
  846.     JR    Z,PRVW2
  847.     CP    ';'
  848.     JR    NZ,PRVW1
  849. PRVW2:    CALL    FORWARD
  850.     RET
  851. ;
  852. ;----------------
  853. ; Check to see if current position is at the beginning of the buffer.
  854. ; Return Z if so, NZ otherwise.
  855. ;
  856. POSCHK:
  857.     LD    HL,(CURRPOS)
  858.     LD    DE,(LINEBUF)
  859.     OR    A
  860.     SBC    HL,DE
  861.     LD    A,L
  862.     OR    H
  863.     RET
  864. ;
  865. ;----------------
  866. ; Do POSCHK but always return character at current position.
  867. ;
  868. POSCK2:
  869.     CALL    POSCHK
  870.     PUSH    AF
  871.     LD    HL,(CURRPOS)
  872.     LD    A,(HL)
  873.     LD    B,A
  874.     POP    AF
  875.     LD    A,B
  876.     RET
  877. ;
  878. ;----------------
  879. ; Quote next char (insert next char literally, even if it is a command
  880. ; character).
  881. ;
  882. LITCHAR:
  883.     CALL    CIN
  884.     CALL    INSERT
  885.     RET
  886. ;
  887. ;----------------
  888. ; Erase entire line
  889. ;
  890. ERASE:
  891.     CALL    CURSBAK
  892.     LD    A,(IX+1)
  893.     CALL    WIPE
  894.     XOR    A
  895.     LD    (IX),A
  896.     LD    (IX+2),A
  897.     LD    HL,(LINEBUF)
  898.     LD    (HL),A
  899.     LD    (CURRPOS),HL
  900.     LD    (BEGLINE),HL
  901.     RET
  902. ;
  903. ;----------------
  904. ; Erase to end of line.
  905. ;
  906. EREOL:
  907.     LD    HL,(CURRPOS)
  908.     XOR    A
  909.     LD    (HL),A
  910.     LD    DE,(LINEBUF)
  911.     SBC    HL,DE
  912.     LD    (IX+2),L
  913.     LD    A,(IX+1)
  914.     SUB    (IX)
  915.     OR    A
  916.     CALL    NZ,WIPE
  917.     RET
  918. ;
  919. ;----------------
  920. ;
  921. WIPE:                ;Blanks the number of chars in A
  922.     LD    C,A
  923.     LD    B,A
  924.     LD    A,' '
  925. WIPE1:    CALL    RAWOUT
  926.     DJNZ    WIPE1
  927.     LD    B,C
  928.     LD    A,8
  929. WIPE2:    CALL    RAWOUT
  930.     DJNZ    WIPE2
  931.     RET
  932. ;
  933. ;
  934. ;----------------------  END OF EDITOR  --------------------------
  935. ;
  936. ;
  937. ;----------------  UTILITY FUNCTIONS  ----------------
  938. ;
  939. RAWOUT:    
  940.     PUSH    AF
  941.     PUSH    BC
  942.     PUSH    DE
  943.     PUSH    HL
  944.     LD    C,A
  945. CONOUT    EQU    $+1
  946.     CALL    00
  947.     POP    HL
  948.     POP    DE
  949.     POP    BC
  950.     POP    AF
  951.     RET
  952. ;
  953. ;----------------
  954. ;
  955. ADVANCE:            ;Outputs the char in A and increments 'curspos'.
  956.     CALL    RAWOUT
  957.     INC    (IX)
  958.     RET
  959. ;
  960. ;----------------
  961. ;
  962. ;
  963. ;================[ Buffers ]================
  964. ;
  965. SAVESP:
  966.     DS    2
  967. SHVAR:
  968.     DB    '        '    ;shell variable
  969. VARLIST:
  970.     DS    2        ;ptr to named variable list
  971. PMTPTR:
  972.     DS    2        ;ptr to prompt line
  973. STKBOT:
  974.     DS    36
  975. STK:    DS    2
  976. ;
  977. ; Storage for scrolling line editor variables.  The following block of storage
  978. ; is indexed by IX.
  979. ;
  980. EDIDAT:
  981.     DB    0    ;(IX) curspos - cursor offset from left marg.
  982.     DB    0    ;(IX+1) printable - maximum printable chars on line
  983.     DB    0    ;(IX+2) numchars - # of chars actually entered
  984.     DB    127    ;(IX+3) maxchars - maximum # of chars allowed
  985.  
  986. SCRWID:
  987.     DS    1
  988. LINEBUF:
  989.     DW    00    ;(IX+4,5) linebuf - ptr to internal editing line
  990. BEGLINE:
  991.     DW    00    ;(IX+6,7) begline - ptr to beginning char of screen window
  992. CURRPOS:
  993.     DW    00    ;(IX+8,9) currpos - current char position
  994. ;
  995.     END    START
  996.