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 / TURBODSG / FANLED.MAC < prev    next >
Text File  |  2000-06-30  |  14KB  |  724 lines

  1. ; FANLED - FANcy Line EDitor for TurboDOS 1.4x
  2. ;
  3. ; RELEASE VERSION HISTORY
  4. ; 1.00    04/02/85 changed kill buffer logic to retain last kill buffer
  5. ;         contents until ^K or ^X (rather than erasing at the
  6. ;         beginning of each edit session).  This now allows
  7. ;         use of the kill buffer as "storage" for a frequently
  8. ;         used command.
  9. ; 1.10    04/05/85 Optimized code for size
  10. ; 1.11         fixed quote problem
  11. ; 1.20  04/09/85 Made edit keys global
  12. ; 1.30  05/04/85 Fixed problem in ^Y routine
  13. ;
  14.     name    ('FANLED')
  15. ;
  16. ; Input:
  17. ;   HL points to a data structure:
  18. ;   <HL>   = CLBLEN (command line buffer length
  19. ;   <HL+1> = actual command line length
  20. ;   <HL+2> = first byte of null-terminated command line
  21. ; Output:
  22. ;   HL     = pointer to actual command line length
  23. ;   A      = actual command line length
  24. ;
  25. .z80
  26. ;
  27. ; Externals used:
  28. ;
  29.     extrn    dms,echo,conin,conout
  30. ;
  31. ; Global entry point:
  32. ;
  33.     public    inpln
  34. ;
  35. ; Global patch point:
  36. ;
  37.     public    forspc
  38. ;
  39. ; command character equates
  40. ;
  41. beglin    equ    'A'-40h        ; ^A - beginning of line
  42. backch    equ    'B'-40h        ; ^B - cursor backwards
  43. delfor    equ    'D'-40h        ; ^D - delete char forward
  44. endlin    equ    'E'-40h        ; ^E - end of line
  45. forwch    equ    'F'-40h        ; ^F - cursor forward
  46. delbak    equ    'H'-40h        ; ^H - delete char backward
  47. kilfor    equ    'K'-40h        ; ^K - kill forward
  48. quote    equ    'Q'-40h        ; ^Q - quote next char
  49. recall    equ    'R'-40h        ; ^R - recall previous command line
  50. abort    equ    'U'-40h        ; ^U - abort line
  51. kilbak    equ    'X'-40h        ; ^X - kill backward
  52. yank    equ    'Y'-40h        ; ^Y - yank (unkill)
  53. delete    equ    7fh        ; DEL- same as ^H
  54. ;
  55. ; other equates
  56. ;
  57. cr    equ    0dh        ; carriage return
  58. bell    equ    7        ; bell character
  59. litc    equ    '^'        ; caret (prefix for control char display)
  60. ;
  61. ; data storage areas
  62. ;
  63.     dseg
  64. ;
  65. forspc:    db    'L'-40h        ; nondestructive forward space character
  66. qflag:    db    0ffh        ; quote next flag
  67. clsave:    dw    0        ; command line structure pointer save
  68. clen:    db    0        ; command line length
  69. insy:    db    0        ; insert yank flag
  70. killen:    db    0        ; length of kill buffer
  71. kilbuf:    ds    162        ; 162 byte kill buffer
  72. oldlin:    ds    162        ; old command line
  73. ;
  74. ; command table
  75. ;
  76. cmdtbl:
  77. fanbg::    db    beglin
  78.     dw    cbegli
  79. fanbk::    db    backch
  80.     dw    cbackc
  81. fanel::    db    endlin
  82.     dw    cendli
  83. fanfc::    db    forwch
  84.     dw    cforwc
  85. fandf::    db    delfor
  86.     dw    cdelfo
  87. fandb::    db    delbak
  88.     dw    cdelba
  89. fankf::    db    kilfor
  90.     dw    ckilfo
  91. fanqu::    db    quote
  92.     dw    cquote
  93. fanrc::    db    recall
  94.     dw    crecal
  95. fankb::    db    kilbak
  96.     dw    ckilba
  97. fanya::    db    yank
  98.     dw    cyank
  99. fanab::    db    abort
  100.     dw    cabort
  101.     db    delete
  102.     dw    cdelba
  103.     db    cr
  104.     dw    exit
  105. ncmds    equ    ($-cmdtbl)/3        ; number of commands
  106. ;
  107.     cseg
  108. ;
  109. ; REGISTER USAGE:
  110. ; HL normally points to the current character in the command line
  111. ;    unless used otherwise
  112. ; DE normally points to the kill buffer or the old line buffer
  113. ; B  always holds the current byte count for the main command line
  114. ; C  always holds the current cursor position in the command line
  115. ; A  usually holds a byte received from the keyboard and/or echoed
  116. ;
  117. ; SUBROUTINES:
  118. ;
  119. ; GETCH - get character in A, preserve all regs
  120. ;
  121. getch:    push    bc
  122.     push    de
  123.     push    hl
  124.     call    conin
  125.     jr    popr
  126. ;
  127. ; BKSPC - backspace
  128. ;
  129. bkspc:    ld    a,delbak
  130. ;
  131. ; PUTCH - display character in A, preserve all regs
  132. ;
  133. putch:    push    bc
  134.     push    de
  135.     push    hl
  136.     ld    c,a
  137.     push    af
  138.     call    conout
  139.     pop    af
  140. popr:    pop    hl
  141.     pop    de
  142.     pop    bc
  143.     ret
  144. ;
  145. ; ERROR - ring the bell
  146. ;
  147. error:    ld    a,bell
  148.     jr    putch
  149. ;
  150. ; DELLFT - delete left character with pointer movement
  151. ;          assume: HL points into command line, B holds
  152. ;       current byte count
  153. ;
  154. dellft:    dec    b        ; decrement count
  155.     dec    c        ; decrement cursor pointer
  156.     dec    hl        ; decrement pointer
  157.     ld    a,(hl)        ; get byte
  158.     cp    ' '        ; if control...
  159.     jr    nc,delchl    ; delete one char if no control
  160.     inc    d        ; increment control char counter
  161.     call    delchl
  162. ;
  163. ; DELCHL - delete left character (bs,sp,bs)
  164. ;
  165. delchl:    push    bc
  166.     push    de
  167.     push    hl
  168.     call    dms
  169.     db    8,' ',88h
  170.     jr    popr
  171. ;
  172. ; GETCMD - A=character, determine if it's an edit command
  173. ;
  174. getcmd:    push    hl
  175.     push    bc
  176.     cp    cr
  177.     jr    z,iscr
  178.     ld    hl,qflag
  179.     bit    0,(hl)
  180.     set    0,(hl)
  181.     jr    z,getcmx
  182. iscr:    ld    b,ncmds
  183.     ld    hl,cmdtbl    ; point to command table
  184. getcml:    cp    (hl)
  185.     jr    z,gotcmd    ; got a command
  186.     inc    hl
  187.     inc    hl
  188.     inc    hl
  189.     djnz    getcml        ; keep searching
  190.     ld    b,a
  191.     xor    a        ; set zero flag
  192.     ld    a,b
  193.     jr    getcmx        ; exit
  194. ;
  195. gotcmd:    inc    hl
  196.     ld    e,(hl)
  197.     inc    hl
  198.     ld    d,(hl)
  199.     xor    a
  200.     inc    a        ; reset zero flag
  201. getcmx:    pop    bc
  202.     pop    hl
  203.     ret
  204. ;
  205. ;
  206. ; MAIN PROGRAM ENTRY POINT
  207. ;
  208. ;
  209. inpln:    xor    a        ; zero byte count/cursor buffer
  210.     ld    b,a
  211.     ld    c,a
  212.     dec    a
  213.     ld    (qflag),a    ; reset quote flag
  214.     ld    a,(hl)        ; get max byte count
  215.     inc    hl        ; point to current byte count
  216.     ld    (clsave),hl    ; save pointer
  217.     ld    (hl),0        ; be sure command line is empty
  218.     inc    hl        ; point to first char of command line
  219.     ld    (clen),a    ; store max command line length
  220. ;
  221. ; this is the main loop
  222. ;
  223. getnxt:    call    getch        ; get a character
  224.     call    getcmd        ; check if command, return zero if not
  225.     jr    z,ascii        ; no command, enter it into cmd line
  226.     push    de        ; jump to de
  227.     ret
  228. ;
  229. ; enter A into command line, echo character
  230. ;
  231. ascii:    push    af
  232.     ld    a,(clen)    ; get max line length
  233.     cp    b        ; reached?
  234.     jr    nz,nolov    ;   nope
  235.     pop    af
  236.     call    error        ;      else beep
  237.     jr    getnxt        ;         and try again
  238. ;
  239. nolov:    ld    a,c        ; see if at end of line
  240.     cp    b
  241.     jr    nz,insert    ; inside line, so do insert mode
  242.     pop    af
  243.     ld    (hl),a
  244.     inc    hl        ; increment
  245.     inc    b        ;    pointers
  246.     inc    c
  247.     call    outch
  248.     jr    getnxt        ; go get another
  249. ;
  250. ; INSERT - insert a character, move all others right
  251. ;
  252. insert:    ld    a,(clen)    ; get allowed length
  253.     cp    b
  254.     jr    nz,insne
  255.     call    error        ; complain
  256.     pop    af
  257.     jr    getnxt        ;    and exit if too long
  258. ;
  259. insne:    ld    a,b        ; get total chars in line
  260.     sub    c        ; subtract cursor position
  261.     push    bc        ; save pointers
  262.     ld    c,a        ; set counter
  263.     ld    b,0        ; bc=number of bytes right of cursor
  264.     add    hl,bc        ; point to end of line
  265.     ld    d,h        ; duplicate in de
  266.     ld    e,l
  267.     inc    de        ; de points past line
  268.     inc    bc
  269.     inc    bc
  270.     lddr            ; move line up one char
  271.     inc    hl
  272.     pop    bc        ; get counters back
  273.     inc    b        ; increment cursor and count
  274.     inc    c
  275.     pop    af        ; now get character
  276.     inc    hl        ; increment pointer
  277.     ld    (hl),a        ; save it in command line
  278.     push    hl        ; save pointer
  279.     push    bc        ; save counters
  280.     ld    a,b
  281.     sub    c        ; count again
  282.     inc    a
  283.     ld    b,a
  284.     ld    c,a
  285.     ld    a,(hl)        ; compensate if ctl char inserted
  286.     cp    ' '
  287.     jr    nc,insl
  288.     dec    c
  289. insl:    ld    a,(hl)
  290.     cp    ' '
  291.     jr    nc,insnc
  292.     inc    c
  293. insnc:    call    outch        ; disply the char
  294.     inc    hl
  295.     djnz    insl
  296. ;
  297. insd:    ld    b,c
  298.     dec    b
  299. insdl:    call    bkspc
  300.     djnz    insdl
  301. ;
  302. inse:    pop    bc
  303.     pop    hl
  304.     inc    hl
  305.     jp    getnxt
  306. ;
  307. ; OUTCH - output a character, display control char if necessary
  308. ;
  309. outch:    cp    ' '        ; check if ctl character
  310.     jr    nc,noctl    ; skip if not
  311.     push    af        ; save char
  312.     ld    a,litc        ; prefix char
  313.     call    putch        ; display it
  314.     pop    af        ; get char back
  315.     add    a,40h        ; make it alpha
  316. noctl:    jp    putch        ; display char
  317. ;
  318. ;
  319. ; COMMAND PROCESSOR ROUTINES
  320. ;
  321. ; CR typed -- exit back to turbodos
  322. ;
  323. exit:    ld    a,c        ; see if we're at end of line
  324.     cp    b        ; if so continue
  325.     jr    z,cntxit
  326.     inc    hl        ; else up pointers
  327.     inc    c
  328.     jr    exit
  329. ;
  330. cntxit:    ld    (hl),0        ; terminate command line
  331.     push    bc
  332.     ld    a,cr
  333.     call    echo        ; echo the RETURN
  334.     pop    bc
  335.     ld    hl,(clsave)    ; get command line pointer
  336.     ld    (hl),b        ; save actual byte count
  337.     push    hl        ; save
  338.     push    bc        ;    registers
  339.     ld    c,b        ; set up count
  340.     ld    b,0
  341.     inc    c
  342.     ld    de,oldlin    ; point to previous line buffer
  343.     ldir            ; store current line there
  344.     pop    bc        ; get regs back
  345.     pop    hl
  346.     ld    a,b        ; byte count in A
  347.     ret
  348. ;
  349. ;
  350. ; CBEGLI - go to beginning of line
  351. ;
  352. cbegli:    inc    c        ; set up cursor pointer
  353. cbegl1:    dec    c        ; decrement cursor ptr
  354.     jr    z,..gn1        ;    until zero
  355.     call    bkspc
  356.     dec    hl
  357.     ld    a,(hl)
  358.     cp    ' '
  359.     call    c,bkspc
  360.     jr    cbegl1
  361. ;
  362. ; CENDLI - go to end of line
  363. ;
  364. cendli:    ld    a,c        ; get cursor
  365.     cp    b        ; if cursor at end of line
  366.     jr    z,..gn1        ;    then get next char
  367.     inc    c        ; point to next char
  368.     ld    a,(hl)
  369.     inc    hl
  370.     cp    ' '
  371.     ld    a,(forspc)
  372.     call    c,putch
  373.     call    putch
  374.     jr    cendli        ; and so on
  375. ;
  376. ; CBACKC - back 1 char
  377. ;
  378. cbackc:    ld    a,c        ; get count
  379.     or    a        ; if at left
  380.     jr    z,..gn1        ;    do nothing
  381.     call    bkspc        ; else backspace
  382.     dec    c        ; decrement counter
  383.     dec    hl        ;    pointer
  384.     ld    a,(hl)
  385.     cp    ' '
  386.     call    c,bkspc
  387.     jr    ..gn1
  388. ;
  389. ; CFORWC - forward 1 char
  390. ;
  391. cforwc:    ld    a,c        ; get count
  392.     cp    b        ; if at end
  393.     jr    z,..gn1        ;    do nothing
  394.     inc    c        ; increment counter
  395.     ld    a,(hl)
  396.     cp    ' '
  397.     ld    a,(forspc)
  398.     call    c,putch
  399.     call    putch        ; move cursor
  400.     inc    hl        ;    pointer
  401. ..gn1:    jp    getnxt
  402. ;
  403. ; CQUOTE - do next char literally
  404. ;
  405. cquote:    xor    a
  406.     ld    (qflag),a
  407.     jr    ..gn1
  408. ;
  409. ; CRECAL - recall previous command line
  410. ;
  411. crecal:    inc    b        ; test if b=0
  412.     dec    b
  413.     jr    nz,..gn1    ; count must be 0
  414.     ld    a,(oldlin)    ; anything in?
  415.     or    a
  416.     jr    z,..gn1        ;    no, empty
  417.     push    hl
  418.     ld    de,oldlin    ; get old line
  419.     ex    de,hl        ; set up for move
  420.     dec    de
  421.     ld    c,(hl)
  422.     ld    b,0
  423.     push    bc
  424.     inc    c
  425.     ldir
  426.     pop    bc
  427.     ld    b,c        ; get count into b
  428.     pop    hl        ; get pointer
  429. dslp:    ld    a,(hl)        ; get byte
  430.     call    outch        ; display it with ctl char expansion
  431.     inc    hl        ; point to next
  432.     djnz    dslp        ; until all done
  433.     ld    b,c        ; count = cursor
  434.     jr    ..gn1        ; exit
  435. ;
  436. ; CDELBA - delete previous character, move following chars to left
  437. ;
  438. cdelba:    ld    a,c        ; see if at start of line
  439.     or    a
  440.     jr    z,..gn2
  441.     ld    de,0
  442.     call    dellft        ; delete char to the left
  443.     ld    a,b
  444.     cp    c
  445.     jr    z,..gn2
  446.     jr    movdel        ; move after delete
  447. ;
  448. ; CDELFO - delete following character, move remainder left
  449. ;
  450. cdelfo:    ld    a,c        ; if cursor at right end
  451.     cp    b
  452.     jr    z,..gn2        ;    then do nothing
  453.     ld    de,0
  454.     dec    b
  455. movdel:    ld    a,b        ; see if end of line
  456.     push    bc        ; save counters
  457.     push    hl        ; save line ptr
  458.     sub    c        ; a=number of chars
  459.     push    af
  460.     inc    a
  461.     ld    c,a
  462.     ld    b,0
  463.     push    de        ; save control char count
  464.     ld    d,h
  465.     ld    e,l
  466.     inc    hl
  467.     ldir
  468.     pop    de        ; get control char count (0/1)
  469.     pop    af        ; get byte count
  470.     pop    hl        ; get line pointer
  471.     push    hl        ; save it again
  472.     ld    b,a
  473.     or    a
  474.     jr    nz,mvdell
  475.     ld    a,' '
  476.     call    putch
  477.     call    putch
  478.     call    bkspc
  479.     call    bkspc
  480.     jr    mvdelq
  481. ;
  482. mvdell:    ld    a,(hl)
  483.     cp    ' '
  484.     jr    nc,mvd1
  485.     inc    e
  486. mvd1:    call    outch
  487.     inc    e        ; increment char count
  488.     inc    hl
  489.     djnz    mvdell
  490.     ld    a,' '
  491.     call    putch        ; wipe out last char
  492.     call    putch
  493.     call    bkspc
  494. mvdel1:    ld    b,e
  495.     call    bkspc
  496. mvdel2:    call    bkspc
  497.     djnz    mvdel2
  498. mvdelq:    pop    hl
  499.     pop    bc
  500. ..gn2:    jp    getnxt
  501. ;
  502. ; CKILFO - kill all chars forward
  503. ;
  504. ckilfo:    ld    a,b
  505.     cp    c
  506.     jr    z,..gn2        ; nothing to kill
  507.     sub    c        ; get byte count
  508.     ld    b,c
  509.     push    bc        ; save count, cursor
  510.     ld    (killen),a    ; store kill buffer length
  511.     ld    c,a
  512.     ld    b,0
  513.     push    bc
  514.     push    hl        ; save line pointer
  515.     ld    de,kilbuf
  516.     ldir            ; move into kill buffer
  517.     pop    hl
  518.     pop    bc
  519.     push    hl
  520.     ld    b,c
  521. ckilf1:    ld    a,(hl)
  522.     inc    hl
  523.     cp    ' '
  524.     ld    a,' '
  525.     jr    nc,ckilf2
  526.     call    putch
  527.     inc    c
  528. ckilf2:    call    putch
  529.     djnz    ckilf1
  530.     ld    b,c
  531. ckilf3:    call    bkspc
  532.     djnz    ckilf3
  533.     pop    hl
  534.     pop    bc
  535.     ld    (hl),0
  536.     jr    ..gn2
  537. ;
  538. ; CKILBA - kill all chars backward
  539. ;
  540. ckilba:    ld    a,c
  541.     or    a
  542.     jr    z,..gn2        ; nothing to kill
  543.     push    bc        ; save counters
  544.     push    hl        ; save pointer
  545.     ld    de,(clsave)    ; get pointer to start
  546.     inc    de
  547.     or    a
  548.     sbc    hl,de        ; hl is now length
  549.     ld    b,h
  550.     ld    c,l
  551.     ld    hl,killen    ; point to kill buffer
  552.     ld    (hl),c
  553.     inc    hl
  554.     ex    de,hl
  555.     ldir            ; move stuff into kill buffer
  556.     pop    hl        ; get old ptr
  557.     pop    bc
  558.     push    bc
  559.     push    hl
  560. ckilb1:    dec    hl
  561.     ld    a,(hl)
  562.     cp    ' '
  563.     ld    a,8
  564.     call    c,putch
  565.     call    putch
  566.     dec    c
  567.     jr    nz,ckilb1
  568.     ld    e,0
  569. ckilb2:    ld    a,(hl)
  570.     inc    hl
  571.     cp    ' '
  572.     ld    a,' '
  573.     jr    nc,ckilb3
  574.     call    putch
  575.     inc    e
  576. ckilb3:    call    putch
  577.     inc    e
  578.     djnz    ckilb2
  579.     ld    b,e
  580. ckilb4:    call    bkspc
  581.     djnz    ckilb4
  582.     pop    hl        ; get line ptr
  583.     pop    bc        ; get counters
  584.     ld    a,b
  585.     sub    c        ; a now has byte count
  586.     ld    c,a
  587.     ld    b,0
  588.     push    bc
  589.     inc    bc
  590.     ld    de,(clsave)
  591.     inc    de
  592.     push    de
  593.     ldir
  594.     pop    hl
  595.     pop    bc
  596.     ld    b,c
  597.     ld    c,0
  598.     ld    a,b
  599.     or    a
  600.     jr    z,..gn3
  601.     push    hl
  602.     push    bc
  603.     ld    e,0
  604. ckilb5:    ld    a,(hl)
  605.     cp    ' '
  606.     jr    nc,ckilb6
  607.     inc    e
  608.     push    af
  609.     ld    a,litc
  610.     call    putch
  611.     pop    af
  612.     add    a,40h
  613. ckilb6:    call    putch
  614.     inc    e
  615.     inc    hl
  616.     djnz    ckilb5
  617.     ld    b,e
  618. ckilb7:    call    bkspc
  619.     djnz    ckilb7
  620.     pop    bc
  621.     pop    hl
  622. ..gn3:    jp    getnxt
  623. ;
  624. ; CYANK - yank kill buffer to current cursor
  625. ;
  626. cyank:    ld    a,(killen)    ; get kill buffer length
  627.     or    a
  628.     jr    z,..gn3        ; kill buffer empty
  629.     add    a,b        ; check total size
  630.     jr    c,er1        ; gee, much too much (>256)!
  631.     ld    e,a
  632.     ld    a,(clen)
  633.     cp    e
  634.     jr    nc,yntl        ; go ahead if not too long
  635. er1:    call    error        ; too long
  636.     jr    ..gn3
  637. ;
  638. yntl:    xor    a
  639.     ld    (insy),a
  640.     ld    a,b
  641.     cp    c        ; check if cursor at end of line
  642.     ld    a,(killen)    ; get length of kill buffer
  643.     jr    z,nomove    ; skip if at end of line
  644.     push    bc        ; save count
  645.     push    hl        ; save pointer
  646.     ld    e,a
  647.     ld    d,0        ; de = number of bytes to be freed
  648.     ld    a,b
  649.     sub    c        ; a has bytes to be moved
  650.     ld    c,a
  651.     ld    b,0        ; bc has bytes tbm
  652.     add    hl,bc        ; point to end of line
  653.     push    hl
  654.     add    hl,de        ; point to new end of line
  655.     ex    de,hl
  656.     pop    hl
  657.     inc    bc
  658.     inc    bc
  659.     lddr
  660.     pop    hl
  661.     pop    bc
  662.     ld    a,0ffh
  663.     ld    (insy),a
  664.     ld    a,(killen)    ; get length of kill buffer
  665. nomove:    push    bc
  666.     push    hl
  667.     ex    de,hl        ; destination to de
  668.     ld    hl,kilbuf
  669.     ld    c,a
  670.     ld    b,0
  671.     push    bc
  672.     ldir
  673.     pop    de
  674.     pop    hl
  675.     pop    bc
  676. ydslp:    ld    a,(hl)
  677.     call    outch
  678.     inc    b
  679.     inc    c
  680.     inc    hl
  681.     dec    e
  682.     jr    nz,ydslp
  683.     ld    a,(insy)
  684.     inc    a
  685.     jr    nz,..gn3
  686. ;
  687. ; now redisplay remainder of line, then step back
  688. ;
  689.     push    hl        ; save line ptr
  690.     push    bc
  691.     ld    e,0        ; character count
  692. ytl1:    ld    a,c
  693.     cp    b
  694.     jr    z,ytl25
  695.     inc    c
  696.     ld    a,(hl)
  697.     cp    ' '
  698.     jr    nc,ytl2
  699.     inc    e
  700. ytl2:    inc    e
  701.     call    outch
  702.     inc    hl
  703.     jr    ytl1
  704. ;
  705. ytl25:    pop    bc
  706. ytl3:    call    bkspc
  707.     dec    e
  708.     jr    nz,ytl3
  709.     pop    hl
  710.     jr    ..gn3
  711. ;
  712. ; abort line
  713. ;
  714. cabort:    ld    bc,0
  715.     ld    hl,(clsave)
  716.     inc    hl
  717.     jp    exit
  718. ;
  719.     END
  720. ointer
  721.     ld    e,a
  722.     ld    d,0        ; de = number of bytes to be freed
  723.     ld    a,b
  724.     sub    c        ; a has byt