home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / krt11.zip / krtedi.mac < prev    next >
Text File  |  1997-10-17  |  25KB  |  818 lines

  1.     .title    KRTEDI    SL editor
  2.     .ident    "V03.63"
  3.  
  4. ; /63/    27-Sep-97  Billy Youdelman  V03.63
  5. ;
  6. ;    fixed all possible sign extension problems now the LN$MAX > 127.
  7. ;    but keep it under 255. or you'll have to fix some other stuff!!
  8.  
  9. ; /62/    27-Jul-93  Billy Youdelman  V03.62
  10. ;
  11. ;    add bells: up arrow when nothing saved yet, down arrow at end
  12.  
  13. ; /BBS/     1-Dec-91  Billy Youdelman  V03.61
  14. ;
  15. ;    up/dn arrow command scrolling fixed
  16. ;    command dispatch table patched for VT-100 keypad (KED equivs)
  17. ;    dup cmds now not saved even when < max cmds are currently stored
  18. ;    extended keypad for adv, bkup, word, char, line, delete, undelete
  19. ;    added check for SS3 for VT-220 keypad
  20. ;    cleaned up various odds and ends..
  21. ;    WARNING:  If LN$MAX is made greater than 127., fix sxt stuff here
  22.  
  23. ;    18-Jul-86  12:00:29  Brian Nelson
  24.  
  25.  
  26.     .include "IN:KRTMAC.MAC"
  27.     .iif ndf  KRTINC  .error    <; .include for IN:KRTMAC.MAC failed>
  28.  
  29.     ; bits used in edists (the editor status word)
  30.     IN$MODE    =    1    ; if <> insert mode is on (default)
  31.     UP$MODE    =    2    ; down arrow wuz last, going up the list
  32.     DN$MODE    =    4    ; up arrow wuz last, going down the list
  33.     UP$END    =    10    ; up arrow has just dumped edicmd #0
  34.     FW$MODE    =    20    ; if <>, advance mode (default=backup=0)
  35.  
  36.  
  37.     .sbttl    Local data
  38.  
  39.     .psect    $pdata
  40. $ceol:    .asciz    <esc>"[K"    ; clear from cursor to end of line
  41. $cz:    .asciz    "^Z"<cr><lf>    ; to echo ^Z
  42. $left:    .asciz    <esc>"[D"    ; move cursor left one column
  43. $resto:    .asciz    <esc>"8"    ; restore cursor to previously saved position
  44. $right:    .asciz    <esc>"[C"    ; move cursor right one column
  45. $rubout:.byte    bs ,space ,bs ,0 ; echo this for a rubout
  46. $save:    .asciz    <esc>"7"    ; save current cursor position
  47. $setvt:    .byte    esc ,'= ,0    ; enable VT-100 keypad
  48. delimit:.byte    40 ,54 ,56 ,57 ,72 ,75 ,133 ,0    ; word delimiters (tab unused)
  49. edi.01:    .asciz    "?KRTEDI-W-Can't overlay HELP from here"<cr><lf> ; /63/
  50. edi.02:    .asciz    "SL F"        ; /63/ display SL Function keys topic
  51. edi.03:    .asciz    "SL K"        ; /63/ or do KED version if KED mode is on
  52.     .even
  53.  
  54.  
  55.     .psect    $code
  56.     .sbttl    SL editor main loop    ; /BBS/ minor mods..
  57.  
  58. ;     (r5)    = the prompt string
  59. ;    2(r5)    = buffer in which to return input string
  60. ;      r1    = length of string returned in 2(r5)
  61. ;      r0    = if <>, the error code
  62.  
  63. kbredi::save    <r2,r3,r4>
  64.     tst    sl.on            ; is SL on?
  65.     bne    10$            ; ya
  66.     wrtall    @r5            ; no, prompt and
  67.     calls    kbread    ,<2(r5)>    ; do hardcopy ttin
  68.     br    70$            ; done
  69.  
  70. 10$:    call    l$nolf            ; just a return
  71.     wrtall    @r5            ; print the prompt
  72.     tst    sl.ked            ; KED mode on?
  73.     beq    20$            ; no
  74.     wrtall    #$setvt            ; ya, force keypad to application mode
  75. 20$:    clr    edipos            ; cursor is at start of the line
  76.     clr    edilen            ; length=0
  77.     mov    2(r5)    ,r4        ; buffer address
  78.     clrb    @r4            ; ensure starting with .asciz
  79. 30$:    call    read1ch            ; get one char from the keyboard
  80.     mov    r0    ,r3        ; save a copy
  81.     beq    60$            ; nothing there, treat as a ^Z
  82.  
  83.     tst    sl.ked            ; KED mode on?
  84.     bne    40$            ; ya, dispatch accordingly
  85.     scan    r3    ,#scanlst    ; no, look for a match
  86.     asl    r0            ; word indexing
  87.     jsr    pc    ,@scandsp(r0)    ; dispatch
  88.     br    50$            ; skip past KED code
  89. 40$:    scan    r3    ,#kedlst    ; look for a match
  90.     asl    r0            ; word indexing
  91.     jsr    pc    ,@keddsp(r0)    ; dispatch
  92. 50$:    bcs    30$            ; not done yet
  93.     br    70$            ; done
  94.  
  95. 60$:    mov    #er$eof    ,r0        ; error, return end-of-file
  96.     clr    r1            ; length=0
  97. 70$:    unsave    <r4,r3,r2>
  98.     return
  99.  
  100.     .save
  101.     .psect    $pdata
  102. scanlst:.byte    'A&37    ,'B&37    ,'C&37    ,'D&37    ,'E&37    ,'F&37    ,lf
  103.     .byte    cr    ,'R&37    ,'U&37    ,'V&37    ,'W&37    ,'Z&37    ,33
  104.     .byte    177    ,217    ,233
  105.     .byte    0
  106.     .even
  107. scandsp:.word    insch
  108.     .word    toggle    ,prev    ,ctrlc    ,left    ,prev    ,right    ,lfproc
  109.     .word    done    ,retype    ,ctrlu    ,next    ,retype    ,eof    ,doesc
  110.     .word    dorub    ,do220    ,do220
  111.  
  112. kedlst:    .byte    'C&37    ,'H&37    ,'I&37    ,lf    ,cr    ,'R&37
  113.     .byte    'U&37    ,'Z&37    ,33    ,177    ,217    ,233
  114.     .byte    0
  115.     .even
  116. keddsp:    .word    insch
  117.     .word    ctrlc    ,dorub    ,toggle    ,lfproc    ,done    ,retype
  118.     .word    ctrlu    ,eof    ,doesc    ,dorub    ,do220    ,do220
  119.     .restore
  120.  
  121.  
  122.     .sbttl    Process escape sequence    ; /BBS/ minor mods..
  123.  
  124. doesc:    call    read1ch            ; get next char in escape sequence
  125.     cmpb    r0    ,#'[        ; CSI?
  126.     beq    do220            ; ya
  127.     cmpb    r0    ,#'O&137    ; from the keypad?
  128.     bne    beep            ; struck out..
  129.  
  130. do220:    call    read1ch            ; get next char in escape sequence
  131.     tst    sl.ked            ; is SL on?
  132.     bne    10$            ; ya
  133.     scan    r0    ,#esclst    ; no, index to process
  134.     asl    r0            ; word indexing
  135.     jmp    @escdsp(r0)        ; /62/ do it
  136. 10$:    scan    r0    ,#k.lst        ; index to process
  137.     asl    r0            ; word indexing
  138.     jmp    @k.dsp(r0)        ; /62/ do it
  139.  
  140.     .save
  141.     .psect    $pdata
  142. esclst:    .byte    'A&137    ,'B&137    ,'C&137    ,'D&137    ,'S&137    ,'P&137    ,'Q&137
  143.     .byte    0
  144.     .even
  145. escdsp:    .word    beep
  146.     .word    prev    ,next    ,right    ,left    ,pf$4    ,pf$1    ,pf$2
  147.  
  148. k.lst:    .byte    'A&137    ,'B&137    ,'C&137    ,'D&137    ,'p!40    ,'r!40    ,'M&137
  149.     .byte    'q!40    ,'s!40    ,'t!40    ,'u!40    ,'S&137    ,'m!40    ,'l!40
  150.     .byte    'P&137    ,'Q&137
  151.     .byte    0
  152.     .even
  153. k.dsp:    .word    beep
  154.     .word    prev    ,next    ,right    ,left    ,sol    ,eol    ,done
  155.     .word    kp$1    ,kp$3    ,kp$4    ,kp$5    ,pf$4    ,kp$min    ,kp$com
  156.     .word    pf$1    ,pf$2
  157.     .restore
  158.  
  159.  
  160.     .sbttl    Ring the bell        ; /BBS/ replaces noop
  161.  
  162. beep:    mov    #bell    ,r0        ; load a bell
  163.     call    writ1char        ; ship it to the terminal
  164.     sec                ; not done yet
  165.     return
  166.  
  167.  
  168.     .sbttl    PF2, Help        ; /BBS/ added..
  169.  
  170. pf$2:    tst    pf2$ok            ; could doing this destroy an overlay?
  171.     beq    10$            ; no
  172.     call    l$nolf            ; possibly..  goto column 1
  173.     wrtall    #$ceol            ; hose the line
  174.     wrtall    #edi.01            ; /63/ "Can't overlay HELP from here"
  175.     br    30$            ; and retype the command line
  176.  
  177. 10$:    mov    #edi.02    ,r0        ; preset normal mode
  178.     tst    sl.ked            ; KED mode on?
  179.     beq    20$            ; no
  180.     mov    #edi.03    ,r0        ; ya, use this help text
  181. 20$:    strcpy    argbuf    ,r0        ; /62/ pass desired topic to HELP
  182.     .newline            ; format display
  183.     save    <r5,r4>            ; preserve pointers
  184.     call    c$help            ; dump the help text to the terminal
  185.     unsave    <r4,r5>            ; recover pointers
  186. 30$:    call    retype            ; then re-display the command line
  187.     sec                ; not done yet
  188.     return
  189.  
  190.  
  191.     .sbttl    Post-PF1 processor    ; /BBS/ all new
  192.  
  193. pf$1:    call    read1ch            ; get next char
  194.     tst    sl.ked            ; KED mode on?
  195.     bne    10$            ; ya
  196.     scan    r0    ,#pf1lst    ; look for a match
  197.     asl    r0            ; word indexing
  198.     jmp    @pf1dsp(r0)        ; /62/ dispatch
  199. 10$:    scan    r0    ,#k1.lst    ; look for a match
  200.     asl    r0            ; word indexing
  201.     jmp    @k1.dsp(r0)        ; /62/ dispatch
  202.  
  203.     .save
  204.     .psect    $pdata
  205. pf1lst:    .byte    'C&37    ,lf    ,'U&37    ,'Z&37
  206.     .byte    33    ,177    ,217    ,233
  207.     .byte    0
  208.     .even
  209. pf1dsp:    .word    beep
  210.     .word    ctrlc    ,.lfproc,.ctrlu    ,eof
  211.     .word    .doesc    ,.dorub    ,.do220    ,.do220
  212.  
  213. k1.lst:    .byte    'C&37    ,'H&37    ,lf    ,'U&37    ,'Z&37
  214.     .byte    33    ,177    ,217    ,233
  215.     .byte    0
  216.     .even
  217. k1.dsp:    .word    beep
  218.     .word    ctrlc    ,.dorub    ,.lfproc,.ctrlu    ,eof
  219.     .word    .doesc    ,.dorub    ,.do220    ,.do220
  220.     .restore
  221.  
  222. .doesc:    call    read1ch            ; get next in esc seq
  223.     cmpb    r0    ,#'[        ; CSI?
  224.     beq    .do220            ; ya
  225.     cmpb    r0    ,#'O&137    ; from the keypad?
  226.     beq    .do220            ; ya
  227.     jmp    beep            ; struck out..
  228.  
  229. .do220:    call    read1ch            ; get next in esc seq
  230.     tst    sl.ked            ; SL on?
  231.     bne    20$            ; ya
  232.     scan    r0    ,#pfxlst    ; index to its process
  233.     asl    r0            ; word offset
  234.     jmp    @pfxdsp(r0)        ; /62/ dispatch
  235. 20$:    scan    r0    ,#kx.lst    ; index to its process
  236.     asl    r0            ; word offset
  237.     jmp    @kx.dsp(r0)        ; /62/ dispatch
  238.  
  239.     .save
  240.     .psect    $pdata
  241. pfxlst:    .byte    'S&137    ,'P&137
  242.     .byte    0
  243.     .even
  244. pfxdsp:    .word    beep
  245.     .word    .pf$4    ,pf$1
  246.  
  247. kx.lst:    .byte    'S&137    ,'m!40    ,'l!40    ,'P&137
  248.     .byte    0
  249.     .even
  250. kx.dsp:    .word    beep
  251.     .word    .pf$4    ,.kp$min,.kp$com,pf$1
  252.     .restore
  253.  
  254.  
  255.     .sbttl    Two ways to undel a char  ; /BBS/ all new
  256.  
  257. .kp$com:call    .dorub            ; undelete the char
  258.     tst    r0            ; did it work?  beep loads r0 if not..
  259.     bne    10$            ; no, leave cursor alone
  260.     call    left            ; ya, fix the cursor position
  261. 10$:    sec                ; not done yet
  262.     return
  263.  
  264. .dorub:    clr    r3            ; /63/ avoid possible sign extension
  265.     bisb    undchr    ,r3        ; /63/ recover char to undelete
  266.     bne    insch            ; /63/ there is a char
  267.     jmp    beep            ; nothing has been saved
  268.  
  269.  
  270.     .sbttl    Insert a char        ; /BBS/ cleaned up
  271.  
  272. insch:    cmpb    r3    ,#space        ; control characters that get
  273.     blo    10$            ; /63/ this far should be ignored..
  274.     cmp    edilen    ,#ln$max    ; too many chars?
  275.     blo    20$            ; no
  276. 10$:    jmp    beep            ; ring bell if line is full
  277.  
  278. 20$:    mov    edipos    ,r1        ; get the offset into line
  279.     add    r4    ,r1        ; where to stuff the data
  280.     tstb    (r1)            ; already at end of line?
  281.     bne    30$            ; no
  282.     movb    r3    ,(r1)+        ; ya, add current char to it
  283.     clrb    (r1)            ; reterminate
  284.     dec    r1            ; back up
  285.     wrtall    r1            ; echo
  286.     inc    edilen            ; line is now one char longer
  287.     inc    edipos            ; cursor is now here
  288.     br    60$            ; that's it..
  289.  
  290. 30$:    bit    #in$mode,edists        ; insert or overstrike?
  291.     bne    40$            ; insert
  292.     movb    r3    ,(r1)+        ; overstrike
  293.     br    50$            ; finish up
  294.  
  295. 40$:    sub    #ln$max+2,sp        ; a temp buffer
  296.     mov    sp    ,r2        ; pointer to it
  297.     strcpy    r2    ,r1        ; save from cursor to EOL
  298.     movb    r3    ,(r1)+        ; insert the new character
  299.     strcpy    r1    ,r2        ; put the trailing data back in
  300.     add    #ln$max+2,sp        ; pop buffer
  301.     inc    edilen            ; line is now one char longer
  302. 50$:    wrtall    #$save            ; save cursor position
  303.     dec    r1            ; back to to the new character
  304.     wrtall    r1            ; dump the data
  305.     wrtall    #$restore        ; put the cursor back now
  306.     call    right            ; move over on the display
  307. 60$:    clr    r0            ; no error
  308.     sec                ; not done yet
  309.     return
  310.  
  311.  
  312.     .sbttl    Move to start of line (Keypad 0)
  313.  
  314. sol:    tst    edipos            ; stop at position 0
  315.     ble    10$            ; /BBS/ done
  316.     call    left            ; /BBS/ move one column
  317.     br    sol            ; and check position
  318. 10$:    sec                ; not done yet
  319.     return
  320.  
  321.  
  322.     .sbttl    Move to end of line (Keypad 2)
  323.  
  324. eol:    cmp    edipos    ,edilen        ; /BBS/ end yet?
  325.     bhis    10$            ; yes
  326.     call    right            ; /BBS/ no, move one column
  327.     br    eol            ; and check position
  328. 10$:    sec                ; not done yet
  329.     return
  330.  
  331.  
  332.     .sbttl    Move cursor one word    ; /BBS/ all new
  333.  
  334. kp$1:    mov    edists    ,r2        ; so kp$3 can flip direction at ends
  335. loop:    mov    edipos    ,r1        ; copy of current cursor position
  336.     bit    #fw$mode,r2        ; check direction
  337.     bne    10$            ; it's advance
  338.     tst    r1            ; backup, any room left?
  339.     ble    30$            ; nope
  340.     br    20$            ; ya
  341. 10$:    cmp    r1    ,edilen        ; advance, any room left?
  342.     bhis    30$            ; no
  343. 20$:    call    kp$3            ; ya, move one char
  344.     mov    edipos    ,r1        ; refresh pointer
  345.     add    r4    ,r1        ; point to byte at hand
  346.     scan    (r1)    ,#delimit    ; check for a word delimiter
  347.     tst    r0            ; well?
  348.     bne    loop            ; found one, keep looking
  349.     scan    -1(r1)    ,#delimit    ; a char, does a delimiter precede it?
  350.     tst    r0            ; well?
  351.     beq    loop            ; no
  352. 30$:    sec                ; ya, but not done yet
  353.     return
  354.  
  355.  
  356.     .sbttl    Move cursor one char    ; /BBS/ added
  357.  
  358. kp$3:    bit    #fw$mode,edists        ; check current direction
  359.     beq    left            ; it's to the left
  360.     .br    right            ; /63/ or to the right..
  361.  
  362.  
  363.     .sbttl    Move right one char
  364.  
  365. right:    cmp    edipos    ,edilen        ; EOL?
  366.     bhis    10$            ; /63/ yes
  367.     wrtall    #$right            ; no, move cursor
  368.     inc    edipos            ; cursor is now here
  369.     cmp    edipos    ,edilen        ; /BBS/ EOL now?
  370.     blo    10$            ; /63/ no
  371.     bic    #fw$mode,edists        ; /BBS/ ya, flip direction
  372. 10$:    sec                ; not done yet
  373.     return
  374.  
  375.  
  376.     .sbttl    Move left one char
  377.  
  378. left:    tst    edipos            ; SOL?
  379.     ble    10$            ; no
  380.     wrtall    #$left            ; ya, backup a bit
  381.     dec    edipos            ; cursor is now here
  382.     bne    10$            ; /BBS/ when hitting SOL..
  383.     bis    #fw$mode,edists        ; /BBS/ ..flip direction
  384. 10$:    sec                ; not done yet
  385.     return
  386.  
  387.  
  388.     .sbttl    Set advance mode    ; /BBS/ added
  389.  
  390. kp$4:    bis    #fw$mode,edists        ; go forward
  391.     sec                ; not done yet
  392.     return
  393.  
  394.  
  395.     .sbttl    Set backup mode        ; /BBS/ added
  396.  
  397. kp$5:    bic    #fw$mode,edists        ; go backward
  398.     sec                ; not done yet
  399.     return
  400.  
  401.  
  402.     .sbttl    Process ^C, ^Z        ; /BBS/ fixed up..
  403.  
  404. ctrlc:    call    sol            ; move to start of line, clear edipos
  405.     wrtall    #$ceol            ; erase to EOL
  406.     clr    edilen            ; init length
  407.     clrb    @r4            ; no data left over
  408.     tst    edicmd            ; anything saved yet?
  409.     blt    10$            ; nope..
  410.     mov    #ln$cnt    ,edicmd        ; reset cmd recall ptr
  411.     dec    edicmd            ; offset so prev/next work ok
  412. 10$:    mov    #cmd$ab    ,r0        ; it's a ^C abort (NOT ^Z)
  413.     br    cz.fin            ; /63/ common exit code
  414.  
  415. eof:    call    eol            ; do this first
  416.     wrtall    #$cz            ; echo ^Z
  417.     mov    #cmd$ex    ,r0        ; flag ^Z exit
  418. cz.fin:    bic    #<up$mode!dn$mode!up$end!fw$mode>,edists  ; clear flags
  419.     clr    r1            ; byte_count=0, also clears carry
  420.     return
  421.  
  422.  
  423.     .sbttl    Process CR, store command line    ; /BBS/ fixed up..
  424.  
  425. done:    emt    340            ; eat possible LF after CR
  426.     .newline            ; kickoff the command..
  427.     tst    edilen            ; anything to do?
  428.     beq    110$            ; no
  429.  
  430.     clr    r2            ; ya, init index
  431.     mov    #ln$cnt    ,r3        ; number of lines to do
  432. 10$:    mov    lastli(r2),r0        ; look for a free spot
  433.     tstb    @r0            ; empty?
  434.     bne    20$            ; nope..
  435.     tst    r2            ; iz it the very first one?
  436.     beq    90$            ; ya, thus nothing to scroll
  437.     mov    r2    ,r3        ; no, put pointer in right spot
  438.     asr    r3            ; only scroll this many lines
  439.     br    30$            ; instead of them all
  440. 20$:    add    #2    ,r2        ; bump to next line and..
  441.     sob    r3    ,10$        ; ..keep looking, until..
  442.     clr    r2            ; ..all lines are in use
  443.     mov    #ln$cnt    ,r3        ; so do them all..
  444.  
  445. 30$:    mov    r4    ,-(sp)        ; save pointer to top of buffer
  446.     dec    r3            ; bump to line to test
  447.     asl    r3            ; word indexing
  448.     mov    lastli(r3),r1        ; this is its current address
  449.     mov    edilen    ,r0        ; length of string just typed in
  450.     cmpb    (r1)+    ,r0        ; is it same as stored string?
  451.     bne    50$            ; no
  452. 40$:    cmpb    (r4)+    ,(r1)+        ; ya, check for string equality
  453.     bne    50$            ; not the same
  454.     sob    r0    ,40$        ; same, check next byte
  455. 50$:    mov    (sp)+    ,r4        ; restore pointer to top of buffer
  456.     asr    r3            ; restore index
  457.     tst    r0            ; did strings match?
  458.     bne    60$            ; no
  459.     mov    r3    ,edicmd        ; yes, save index
  460.     br    110$            ; that's it
  461.  
  462. 60$:    tst    r2            ; are all buffers in use?
  463.     bne    90$            ; nope..
  464.                     ; ya, scroll back previous lines
  465. 70$:    mov    lastli(r2),r0        ; address where string will be written
  466.     mov    lastli+2(r2),r1        ; address of string to be moved
  467. 80$:    movb    (r1)+    ,(r0)+        ; copy the string now
  468.     bne    80$            ; until hitting the null terminator
  469.     add    #2    ,r2        ; bump pointer to next line
  470.     sob    r3    ,70$        ; next please
  471.  
  472. 90$:    mov    lastli(r2),r1        ; at last, copy the new line
  473.     movb    edilen    ,(r1)+        ; save the line length
  474. 100$:    movb    (r4)+    ,(r1)+        ; copy the data now
  475.     bne    100$            ; including null terminator
  476.     asr    r2            ; recover index to current command
  477.     mov    r2    ,edicmd        ; save it
  478.  
  479. 110$:    mov    edilen    ,r1        ; return line length
  480.     bic    #<up$mode!dn$mode!up$end!fw$mode>,edists  ; clear flags
  481.     clr    r0            ; no error, also clears carry
  482.     return
  483.  
  484.  
  485.     .sbttl    Recall a command    ; /BBS/ some changes..
  486.  
  487. next:    mov    #edicmd    ,r2        ; point to command number buffer
  488.     tst    @r2            ; anything been saved?
  489.     bge    10$            ; /62/ ya
  490.     call    beep            ; /62/ not yet, so there's
  491.     br    60$            ; /62/ nothing to recall
  492.  
  493. 10$:    cmp    @r2    ,#ln$cnt-1    ; /62/ can we move up?
  494.     blo    30$            ; /63/ ya
  495. 20$:    call    beep            ; /62/ no, beep
  496.     br    50$            ; /62/ and cleanup anyway
  497.  
  498. 30$:    inc    @r2            ; yes, move up
  499.  
  500.     bit    #dn$mode,edists        ; if down arrow was used last time
  501.     beq    40$            ; loop in one more bump up to fix pos
  502.     bic    #dn$mode,edists        ; when going back up, but only do this
  503.     br    10$            ; once when coming back here
  504.  
  505. 40$:    mov    @r2    ,r2        ; recover command number
  506.     asl    r2            ; word addressing
  507.     mov    lastli(r2),r2        ; at last
  508.     tstb    @r2            ; anything to copy?
  509.     beq    20$            ; /62/ no, ring bell and cleanup
  510.  
  511.     call    recover            ; ya, get the line
  512.     bis    #up$mode,edists        ; set mode flag
  513.     cmp    edicmd    ,#ln$cnt    ; poised at the last command?
  514.     blo    60$            ; /63/ no
  515.     dec    edicmd            ; ya, fix so prev works correctly
  516.     bic    #up$mode,edists        ; ditto
  517.     br    60$
  518.  
  519. 50$:    bic    #up$mode,edists        ; at the end, no extra bump please
  520.     call    l$nolf            ; /62/ goto start of line
  521.     wrtall    #$ceol            ; /62/ clear line on screen
  522.     wrtall    @r5            ; /62/ print prompt
  523.     clrb    @r4            ; no data left over
  524.     clr    edilen            ; length=0
  525.     clr    edipos            ; /62/ cursor is at beginning of line
  526.  
  527. 60$:    bic    #up$end,edists        ; no longer at the end of list
  528.     sec                ; not done yet
  529.     return
  530.  
  531.  
  532.     .sbttl    Up-arrow key        ; /BBS/ some changes..
  533.  
  534. prev:    bit    #up$end,edists        ; already at the firewall?
  535.     beq    10$            ; no
  536.     call    beep            ; ya, ring the bell
  537.  
  538. 10$:    mov    edicmd    ,r2        ; current command number
  539.     bge    20$            ; /62/ something has been saved
  540.     call    beep            ; /62/ never been here
  541.     br    60$            ; /62/ so nothing to recall yet
  542.  
  543. 20$:    bit    #up$mode,edists        ; down arrow been used?
  544.     bne    30$            ; ya, so bump edicmd to correct
  545.  
  546.     asl    r2            ; word indexing
  547.     mov    lastli(r2),r2        ; address of buffer
  548.     tstb    @r2            ; anything to copy?
  549.     bne    40$            ; yes
  550.  
  551. 30$:    bic    #up$mode,edists        ; only do this first time thru here
  552.     dec    edicmd            ; no, back up
  553.     br    10$            ; and try again..
  554.  
  555. 40$:    call    recover            ; ya, get the line
  556.  
  557.     tst    edicmd            ; check for underflow
  558.     bgt    50$            ; nope
  559.     clr    edicmd            ; just in case..
  560.     bic    #dn$mode,edists        ; no help needed coming off end
  561.     bis    #up$end,edists        ; no more stuff, edicmd=0
  562.     br    60$
  563.  
  564. 50$:    dec    edicmd            ; backup now and
  565.     bis    #dn$mode,edists        ; apply appropriate compensation
  566.  
  567. 60$:    sec                ; not done yet
  568.     return
  569.  
  570.  
  571.     .sbttl    Recover a command line    ; /BBS/ made this a subroutine
  572.  
  573. recover:call    l$nolf            ; goto start of line
  574.     wrtall    #$ceol            ; clear line on screen
  575.     wrtall    @r5            ; print prompt
  576.     clrb    (r4)            ; init buffer
  577.     clr    r3            ; /63/ avoid possible sign extension
  578.     bisb    (r2)+    ,r3        ; /63/ get length
  579.     beq    20$            ; nothing there
  580.     mov    r4    ,r1        ; copy of the destination address
  581. 10$:    movb    (r2)+    ,(r1)+        ; copy string
  582.     bne    10$            ; including null terminator
  583.     wrtall    r4            ; echo the string just copied
  584. 20$:    mov    r3    ,edilen        ; save length
  585.     mov    r3    ,edipos        ; cursor is now at EOL
  586.     bic    #fw$mode,edists        ; can only backup from here
  587.     return
  588.  
  589.  
  590.     .sbttl    Process ^U        ; /BBS/ all new
  591.  
  592. ctrlu:    mov    edipos    ,r1        ; get the offset into line
  593.     ble    30$            ; nothing to do
  594.     call    SOL            ; move to start of line, clear edipos
  595.     wrtall    #$ceol            ; erase to EOL
  596.     clr    edilen            ; init length
  597.     clr    r0            ; start at the top
  598.     call    undwrt            ; write deleted data into a buffer
  599.     mov    r4    ,r2        ; work copy of output pointer
  600. 10$:    movb    (r0)+    ,(r2)+        ; copy rest of line back into buffer
  601.     beq    20$            ; until null
  602.     inc    edilen            ; string is now one char longer
  603.     inc    edipos            ; cursor will be here
  604.     br    10$            ; next char
  605. 20$:    wrtall    r4            ; dump result to term
  606.     call    sol            ; go back to start of the line
  607. 30$:    sec                ; not done yet
  608.     return
  609.  
  610.  
  611.     .sbttl    Keypad minus        ; /BBS/ all new..
  612.  
  613. kp$min:    cmp    edipos    ,edilen        ; at end of the line?
  614.     bhis    10$            ; /63/ ya, can't do this
  615.     mov    edipos    ,r3        ; save current cursor position
  616.     call    savclr            ; save cursor position, erase to EOL
  617.     mov    edists    ,-(sp)        ; save current mode
  618.     bis    #fw$mode,edists        ; set advance mode
  619.     call    kp$1            ; bump to next word
  620.     mov    (sp)+    ,edists        ; restore old mode
  621.     mov    edipos    ,r1        ; end of the deleted data
  622.     sub    r3    ,r1        ; length of same
  623.     sub    r1    ,edilen        ; length of what remains in line
  624.     mov    r3    ,r0        ; begin copy from here
  625.     call    undwrt            ; copy deleted stuff into buffer
  626.     wrtall    #$restore        ; put cursor back
  627.     mov    r3    ,edipos        ; cursor is now here
  628.     call    outwrt            ; pull up trailing part of line
  629. 10$:    sec                ; not done yet
  630.     return
  631.  
  632.  
  633.     .sbttl    Line feed        ; /BBS/ all new
  634.  
  635. lfproc:    tst    edipos            ; at top of the line?
  636.     ble    10$            ; ya, can't do this
  637.     mov    edipos    ,r3        ; save current cursor position
  638.     mov    edists    ,-(sp)        ; save current mode
  639.     bic    #fw$mode,edists        ; set backup mode
  640.     call    kp$1            ; bump to next word
  641.     mov    (sp)+    ,edists        ; restore old mode
  642.     mov    r3    ,r1        ; end of deleted data
  643.     sub    edipos    ,r1        ; length of deleted part of line
  644.     sub    r1    ,edilen        ; new length of what's left in line
  645.     mov    edipos    ,r0        ; start from here
  646.     call    undwrt            ; write the undelete buffer
  647.     call    savclr            ; save cursor position, erase to EOL
  648.     call    outwrt            ; pull up trailing part of line
  649. 10$:    sec                ; not done yet
  650.     return
  651.  
  652.  
  653.     .sbttl    Write buffers        ; /BBS/ for the above two routines
  654.  
  655. undwrt:    mov    #undlin    ,r2        ; pointer to undelete line buffer
  656.     movb    r1    ,(r2)+        ; stash copy of the length
  657.     add    r4    ,r0        ; start from here
  658. 10$:    movb    (r0)+    ,(r2)+        ; stash the deleted
  659.     sob    r1    ,10$        ; part of the line
  660.     clrb    (r2)            ; null terminate it
  661.     return
  662.  
  663. outwrt:    wrtall    r0            ; restore undeleted part of line
  664.     wrtall    #$restore        ; put cursor back
  665.     mov    r4    ,r2        ; work copy of input pointer
  666.     add    edipos    ,r2        ; where old line left off
  667. 20$:    movb    (r0)+    ,(r2)+        ; pull up the rest of it
  668.     bne    20$            ; until hitting the null terminator
  669.     return
  670.  
  671.  
  672.     .sbttl    Un-do PF4, keypad comma    ; /BBS/ all new
  673.  
  674. .kp$min:                ; UNDEL WORD and LINE are same funct
  675. .pf$4:    call    .ctrlu            ; use this, then fix cursor
  676.     tst    r0            ; did it work?   beep sets r0 if not..
  677.     bne    20$            ; no   /63/ or r0 clear for bisb below
  678.     bisb    undlin    ,r0        ; /63/ recover length of insert
  679. 10$:    call    left            ; back cursor up to
  680.     sob    r0    ,10$        ; where it was
  681. 20$:    sec                ; not done yet
  682.     return
  683.  
  684.  
  685.     .sbttl    Un-do ^U, line feed    ; /BBS/ all new
  686.  
  687. .lfproc:                ; UNDO LF and UNDO ^U are same funct
  688. .ctrlu:    tstb    undlin            ; anything to undelete?
  689.     beq    10$            ; no
  690.     mov    #ln$max    ,r0        ; max possible line length
  691.     sub    edilen    ,r0        ; minus what is already in use
  692.     ble    10$            ; no room left
  693.     cmpb    undlin    ,r0        ; will new stuff fit?
  694.     blos    20$            ; /63/ ya
  695. 10$:    jmp    beep            ; it can't happen
  696.  
  697. 20$:    sub    #ln$max+2,sp        ; it can happen, get a temp buffer
  698.     mov    sp    ,r2        ; and a pointer to it
  699.  
  700.     mov    edipos    ,r1        ; get the offset into line
  701.     add    r4    ,r1        ; where to stuff the data
  702.  
  703.     mov    #undlin    ,r3        ; pointer to string to insert
  704.     clr    r0            ; /63/ avoid possible sign extension
  705.     bisb    (r3)+    ,r0        ; /63/ recover length
  706.     add    r0    ,edilen        ; add length of insert to total
  707.     add    r0    ,edipos        ; cursor will be here when done
  708.  
  709.     strcpy    r2    ,r1        ; save from cursor to EOL
  710. 30$:    movb    (r3)+    ,(r1)+        ; recover the insert data
  711.     bne    30$            ; copy up to null terminator
  712.     dec    r1            ; bump pointer back onto it
  713.     strcpy    r1    ,r2        ; put the trailing data back in
  714.     wrtall    #undlin+1        ; echo insert moving cursor to its end
  715.     wrtall    #$save            ; save cursor pos
  716.     wrtall    r2            ; restore trailing part of old line
  717.     wrtall    #$restore        ; put the cursor back now
  718.     add    #ln$max+2,sp        ; pop buffer
  719.     clr    r0            ; flag no error
  720.     sec                ; but not done yet
  721.     return
  722.  
  723.  
  724.     .sbttl    Process PF4        ; /BBS/ all new
  725.  
  726. pf$4:    mov    edilen    ,r1        ; length of the whole banana
  727.     sub    edipos    ,r1        ; length of deleted part of line
  728.     ble    20$            ; nothing to do
  729.     mov    #undlin    ,r2        ; pointer to undelete line buffer
  730.     movb    r1    ,(r2)+        ; stash copy of the length
  731.     mov    r4    ,r0        ; work copy of input pointer
  732.     add    edipos    ,r0        ; start from here
  733.     mov    r0    ,r1        ; save to terminate after copying..
  734. 10$:    movb    (r0)+    ,(r2)+        ; ..the deleted part of line..
  735.     bne    10$            ; ..and its null term
  736.     clrb    (r1)            ; now terminate the new string
  737.     wrtall    #$ceol            ; erase to the end of the line
  738.     mov    edipos    ,edilen        ; this is new length
  739. 20$:    sec                ; not done yet
  740.     return
  741.  
  742.  
  743.     .sbttl    Erase char under cursor    ; /BBS/ all new
  744.  
  745. kp$com:    cmp    edipos    ,edilen        ; at end of the line?
  746.     bhis    do.end            ; /63/ ya, nothing to do
  747.     mov    r4    ,r2        ; copy pointer to top of buffer
  748.     add    edipos    ,r2        ; now it's pointing to cursor position
  749.     tstb    (r2)            ; don't load a null into undchr!
  750.     beq    do.end            ; it's at EOL, nothing to do
  751.     br    do.com            ; fall thru to common code..
  752.  
  753.  
  754.     .sbttl    Erase char to left of cursor  ; /BBS/ fixed up..
  755.  
  756. dorub:    tst    edipos            ; at SOL?
  757.     ble    do.end            ; ya
  758.     mov    r4    ,r2        ; copy pointer to top of buffer
  759.     add    edipos    ,r2        ; now it's pointing to cursor position
  760.     tstb    (r2)            ; at EOL?
  761.     bne    10$            ; no
  762.     movb    -(r2)    ,undchr        ; ya, copy for undel_char
  763.     clrb    (r2)            ; then zap char
  764.     dec    edilen            ; new length
  765.     wrtall    #$rubout        ; fix display
  766.     dec    edipos            ; cursor is now here
  767.     br    do.end
  768.  
  769. 10$:    call    left            ; move back one char for a rubout
  770.     dec    r2            ; fix pointer
  771.  
  772. do.com:    movb    (r2)    ,undchr        ; /63/ stash copy for possible undel
  773.     mov    r2    ,r1        ; copy pointer for input
  774.     mov    r2    ,r3        ; copy pointer for output
  775.     inc    r1            ; bump past char that is hosed
  776. 20$:    movb    (r1)+    ,(r3)+        ; slide everything left down a byte
  777.     bne    20$            ; until null terminated
  778.     dec    edilen            ; line is now one less char long
  779.     call    savclr            ; save cursor position, erase to EOL
  780.     wrtall    r2            ; dump buffer
  781.     wrtall    #$restore        ; restore cursor position
  782. do.end:    sec                ; /63/ not done yet
  783.     return
  784.  
  785.  
  786.     .sbttl    Process ^R        ; /BBS/ minor clean up
  787.  
  788. retype:    call    l$nolf            ; start of line
  789.     wrtall    #$ceol            ; clear to end of line
  790.     wrtall    @r5            ; print the prompt
  791.     tst    sl.ked            ; KED mode on?
  792.     beq    10$            ; no
  793.     wrtall    #$setvt            ; ya, force keypad to application mode
  794. 10$:    wrtall    r4            ; dump the buffer
  795.     call    l$nolf            ; back to column 1
  796.     strlen    @r5            ; prompt is this long
  797.     add    edipos    ,r0        ; add expected cursor position
  798. 20$:    wrtall    #$right            ; go to it
  799.     sob    r0    ,20$        ; one column at a time until there
  800.     sec                ; not done yet
  801.     return
  802.  
  803.  
  804.     .sbttl    Toggle insert/overstrike mode
  805.  
  806. toggle:    mov    #in$mode,r0        ; copy of insert mode bit
  807.     xor    r0    ,edists        ; toggle it
  808.     sec                ; not done yet
  809.     return
  810.  
  811.     .sbttl    Save cursor then clear to EOL    ; /BBS/ added
  812.  
  813. savclr:    wrtall    #$save            ; save cursor position
  814.     wrtall    #$ceol            ; erase to EOL
  815.     return
  816.  
  817.     .end
  818.