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.A < prev    next >
Text File  |  2000-06-30  |  17KB  |  822 lines

  1.     #TITLE    "FANLED - FANcy Line EDitor for TurboDOS 1.4x"
  2.     #PAGE    132,66
  3.     MODULE    "FanLEdit"
  4. ;
  5. ; THIS IS THE RELEASE VERSION OF FANLED
  6. ; v 1.10 as of 4-5-85
  7. ; v 1.11 as of 4-5-85 fixes ^Q problem
  8. ; v 1.30 as of 5-4-85 fixes ^Y problem, vers# in sync with 8 bit
  9. ;                     added ^U
  10. ; v 1.40 as of 7-13-85 now using COMSUB routines, fixed obscure bug
  11. ;
  12. ; ANOMALY:
  13. ;   The labels GN1, GN2, GN3 all point to GETNXT and are used
  14. ;   so save a few bytes.
  15. ;   FANLED is somewhat optimized, a more experienced programmer
  16. ;   may be able to squeeze a few more bytes out.  It shrunk over
  17. ;   250 bytes from the raw translation... 
  18. ;
  19. ;    +-------------------------------+
  20. ;    | COMMAND CHARACTER DEFINITIONS |
  21. ;    +-------------------------------+
  22. ;
  23. BEGLIN    ==    'A'-0X40        ; ^A - BEGINNING OF LINE
  24. BACKCH    ==    'B'-0X40        ; ^B - CURSOR BACKWARDS
  25. DELFOR    ==    'D'-0X40        ; ^D - DELETE CHAR FORWARD
  26. ENDLIN    ==    'E'-0X40        ; ^E - END OF LINE
  27. FORWCH    ==    'F'-0X40        ; ^F - CURSOR FORWARD
  28. DELBAK    ==    'H'-0X40        ; ^H - DELETE CHAR BACKWARD
  29. KILFOR    ==    'K'-0X40        ; ^K - KILL FORWARD
  30. QUOTE    ==    'Q'-0X40        ; ^Q - QUOTE NEXT CHAR
  31. RECALL    ==    'R'-0X40        ; ^R - RECALL PREVIOUS COMMAND LINE
  32. ABORT    ==    'U'-0X40        ; ^U - ABORT LINE
  33. KILBAK    ==    'X'-0X40        ; ^X - KILL BACKWARD
  34. YANK    ==    'Y'-0X40        ; ^Y - YANK (UNKILL)
  35. DELETE    ==    0X7F            ; DEL- SAME AS ^H
  36. ;
  37. ; EXPERIMENTAL EQUATES
  38. ;
  39. PUSHK    ==    'G'-0X40        ; PUSH KILL LINE
  40. POPK    ==    'T'-0X40
  41. ;
  42. ;    +---------------+
  43. ;    | OTHER EQUATES |
  44. ;    +---------------+
  45. ;
  46. CR    ==    0X0D        ; CARRIAGE RETURN
  47. BELL    ==    7        ; BELL CHARACTER
  48. LITC    ==    '^'        ; CARET (PREFIX FOR CONTROL CHAR DISPLAY)
  49. ;
  50. ;    +-------------------+
  51. ;    | DATA STORAGE AREA |
  52. ;    +-------------------+
  53. ;
  54.     LOC    Data#
  55. ;
  56. FORSPC::BYTE    'L'-0X40    ; NONDESTRUCTIVE FORWARD SPACE CHARACTER
  57. QFLAG:    BYTE    0XFF        ; QUOTE NEXT FLAG
  58. CLSAVE:    WORD    0        ; COMMAND LINE STRUCTURE POINTER SAVE
  59. CLEN:    BYTE    0        ; COMMAND LINE LENGTH
  60. INSY:    BYTE    0        ; INSERT YANK FLAG
  61. KILLEN:    BYTE    0        ; LENGTH OF KILL BUFFER
  62. KILBUF:    RES    162        ; 162 BYTE KILL BUFFER
  63. OLDLIN:    RES    163        ; OLD COMMAND LINE
  64. ; EXPERIMENTAL STORAGE:
  65. KILLEV:    BYTE    0        ; KILL (STACK) LEVEL
  66. KLEVAD:    WORD    0        ; LEVEL POINTER ADDRESS
  67. ;
  68. ;    +---------------------------------------+
  69. ;    | COMMAND TABLE (PATCHABLE IN PAR FILE) |
  70. ;    +---------------------------------------+
  71. ;
  72. ;    Each command occupies 3 bytes, the command character
  73. ;    followed by the address of the command routine.
  74. ;
  75. CMDTBL:
  76. FANBG::    BYTE    BEGLIN
  77.     WORD    CBEGLI
  78. FANBK::    BYTE    BACKCH
  79.     WORD    CBACKC
  80. FANEL::    BYTE    ENDLIN
  81.     WORD    CENDLI
  82. FANFC::    BYTE    FORWCH
  83.     WORD    CFORWC
  84. FANDF::    BYTE    DELFOR
  85.     WORD    CDELFO
  86. FANDB::    BYTE    DELBAK
  87.     WORD    CDELBA
  88. FANKF::    BYTE    KILFOR
  89.     WORD    CKILFO
  90. FANQU::    BYTE    QUOTE
  91.     WORD    CQUOTE
  92. FANRC::    BYTE    RECALL
  93.     WORD    CRECAL
  94. FANKB::    BYTE    KILBAK
  95.     WORD    CKILBA
  96. FANYA::    BYTE    YANK
  97.     WORD    CYANK
  98. FANAB::    BYTE    ABORT
  99.     WORD    CABORT
  100.     BYTE    DELETE
  101.     WORD    CDELBA
  102.     BYTE    CR
  103.     WORD    EXIT
  104. ; EXPERIMENTAL:
  105. FANPU::    BYTE    PUSHK
  106.     WORD    CPUSHK
  107. FANPO::    BYTE    POPK
  108.     WORD    CPOPK
  109. NCMDS    ==    ($-CMDTBL)/3        ; NUMBER OF COMMANDS
  110. ;
  111. ;    +--------------+
  112. ;    | CODE SECTION |
  113. ;    +--------------+
  114. ;
  115.     LOC    Code#
  116. ;
  117. ;    REGISTER USAGE:
  118. ;    ES:BX normally points to the current character in the command line
  119. ;       unless used otherwise
  120. ;    DX normally points to the kill buffer or the old line buffer
  121. ;    CH  always holds the current byte count for the main command line
  122. ;    CL  always holds the current cursor position in the command line
  123. ;    AL  usually holds a byte received from the keyboard and/or echoed
  124.  
  125. ;    +--------------------+
  126. ;    | COMMON SUBROUTINES |
  127. ;    +--------------------+
  128. ;
  129. ;    GETCH - get character in AL, preserve all regs
  130. ;
  131. GETCH:    PUSH    CX
  132.     PUSH    DX
  133.     PUSH    BX
  134.     PUSH    ES
  135.     CALL    CONIN#
  136.     JMPS    POPR
  137. ;
  138. ;    ERROR - ring the bell
  139. ;
  140. ERROR:    MOV    AL,=BELL
  141.     JMPS    PUTCH
  142. ;
  143. ;    BKSPC - backspace
  144. ;
  145. BKSPC:    MOV    AL,=8
  146. ;
  147. ;    PUTCH - display character in AL, preserve all regs
  148. ;
  149. PUTCH:    PUSH    CX
  150.     PUSH    DX
  151.     PUSH    BX
  152.     PUSH    ES
  153.     MOV    CL,AL
  154.     PUSH    AX
  155.     CALL    CONOUT#
  156.     POP    AX
  157. POPR:    POP    ES
  158.     POP    BX
  159.     POP    DX
  160.     POP    CX
  161.     RET
  162. ;
  163. ;    DELLFT - delete left character with pointer movement
  164. ;          assume: ES:BX points into command line, CH holds
  165. ;       current byte count
  166. ;
  167. DELLFT:    DEC    CH        ; DECREMENT COUNT
  168.     DEC    CL        ; DECREMENT CURSOR POINTER
  169.     DEC    BX        ; DECREMENT POINTER
  170.     ES
  171.     CMP    [BX],=' '
  172.     JNC    DELCHL        ; DELETE ONE CHAR IF NO CONTROL
  173.     INC    DH        ; INCREMENT CONTROL CHAR COUNTER
  174.     CALL    DELCHL
  175. ;
  176. ;    DELCHL - delete left character (bs,sp,bs)
  177. ;
  178. DELCHL:    PUSH    CX
  179.     PUSH    DX
  180.     PUSH    BX
  181.     PUSH    ES
  182.     CALL    DMS#
  183.     BYTE    8,' ',8,0
  184.     JMPS    POPR
  185. ;
  186. ;    GETCMD - AL=character, determine if it's an edit command
  187. ;       if edit command, DX=address, Z=reset
  188. ;
  189. GETCMD:    PUSH    BX
  190.     PUSH    CX
  191.     CMP    AL,=CR        ; IS IT A RETURN?
  192.     JZ    ISCR        ; YUP!
  193.     TEST    BYTE QFLAG,=0XFF ; SEE IF QUOTE FLAG SET
  194.     MOV    BYTE QFLAG,=0XFF ; RESET QUOTE FLAG ANYWAY
  195.     JZ    GETCMX        ; EXIT IF QUOTE FLAG
  196. ISCR:    MOV    CH,=NCMDS
  197.     MOV    BX,&CMDTBL    ; POINT TO COMMAND TABLE
  198. GETCML:    CMP    AL,[BX]
  199.     JZ    GOTCMD        ; GOT A COMMAND
  200.     INC    BX
  201.     INC    BX
  202.     INC    BX
  203.     DEC    CH        ; KEEP SEARCHING
  204.     JNZ    GETCML
  205.     MOV    CH,AL
  206.     XOR    AL,AL        ; SET ZERO FLAG
  207.     MOV    AL,CH
  208.     JMPS    GETCMX        ; EXIT
  209. ;
  210. GOTCMD:    INC    BX
  211.     MOV    DX,[BX]
  212.     OR    AL,AL        ; IF NOT ^@ TYPED
  213.     JNZ    GETCMX        ;    THEN SKIP
  214.     INC    AL        ; SPECIAL CASE WHERE ^@ IS NOT ATTENTION
  215.     MOV    AL,=0
  216. GETCMX:    POP    CX
  217.     POP    BX
  218.     RET
  219. ;
  220. ;    Two external move routines are used, LDIR# and LDDR#.
  221. ;    Both are contained in COMSUB and work as follows:
  222. ;    Move CX bytes from AX:BX to BP:DX
  223. ;    ---------------------------------
  224. ;    LDIR moves from bottom to top, LDDR moves from top to bottom
  225.  
  226. ;    +--------------------------+
  227. ;    | MAIN PROGRAM ENTRY POINT |
  228. ;    +--------------------------+
  229.  
  230.  
  231.  
  232. ; INPUT:
  233. ;   ES:BX points to a data structure:
  234. ;   <BX>   = CLBLEN (command line buffer length
  235. ;   <BX+1> = actual command line length
  236. ;   <BX+2> = first byte of command line
  237. ; OUTPUT:
  238. ;   BX     = pointer to actual command line length
  239. ;   A      = actual command line length
  240. ;
  241. INPLN::    XOR    CX,CX        ; ZERO COUNT AND CURSOR
  242.     MOV    BYTE QFLAG,=0XFF ;CLEAR QUOTE FLAG
  243.     ES
  244.     MOV    AL,[BX]        ; GET MAX BYTE COUNT
  245.     INC    BX        ; POINT TO CURRENT BYTE COUNT
  246.     MOV    CLSAVE,BX    ; SAVE POINTER
  247.     ES
  248.     MOV    BYTE [BX],=0    ; BE SURE COMMAND LINE IS EMPTY
  249.     INC    BX        ; POINT TO FIRST CHAR OF COMMAND LINE
  250.     MOV    CLEN,AL        ; STORE MAX COMMAND LINE LENGTH
  251. ;
  252. ;    MAIN ROUTINE LOOP
  253. ;
  254. GETNXT:    CALL    GETCH        ; GET A CHARACTER
  255.     CALL    GETCMD        ; CHECK IF COMMAND, RETURN ZERO IF NOT
  256.     JZ    ASCII        ; NO COMMAND, ENTER IT INTO CMD LINE
  257.     JMPI    DX        ; JUMP TO DE
  258. ;
  259. ;    enter AL into command line, echo character
  260. ;
  261. ASCII:    CMP    CH,CLEN        ; END OF LINE REACHED?
  262.     JNZ    NOLOV        ;   NOPE
  263.     CALL    ERROR        ;      ELSE BEEP
  264.     JMPS    GETNXT        ;         AND TRY AGAIN
  265. ;
  266. NOLOV:    CMP    CH,CL        ; SEE IF AT END OF LINE
  267.     JNZ    INSERT        ; INSIDE LINE, SO DO INSERT MODE
  268.     ES
  269.     MOV    [BX],AL
  270.     INC    BX        ; INCREMENT
  271.     INC    CH        ;    POINTERS
  272.     INC    CL
  273.     CALL    OUTCH
  274.     JMPS    GETNXT        ; GO GET ANOTHER
  275. ;
  276. ;    INSERT - insert a character, move all others right
  277. ;
  278. INSERT:    CMP    CH,CLEN
  279.     JNZ    __X
  280.     CALL    ERROR        ; COMPLAIN
  281.     JMPS    GETNXT        ;    AND EXIT IF TOO LONG
  282. ;
  283. __X:    PUSH    CX        ; SAVE POINTERS
  284.     SUB    CH,CL        ; SUBTRACT CURSOR POSITION
  285.     MOV    CL,CH        ; SET COUNTER
  286.     MOV    CH,=0        ; CX=NUMBER OF BYTES RIGHT OF CURSOR
  287.     ADD    BX,CX        ; POINT TO END OF LINE
  288.     MOV    DH,BH        ; DUPLICATE IN DX
  289.     MOV    DL,BL
  290.     INC    DX        ; DX POINTS PAST LINE
  291.     INC    CX
  292.     INC    CX
  293.     PUSH    AX
  294.     MOV    AX,ES
  295.     MOV    BP,ES
  296.     CALL    LDDR#        ; MOVE LINE UP ONE CHAR
  297.     POP    AX
  298.     INC    BX
  299.     POP    CX        ; GET COUNTERS BACK
  300.     INC    CH        ; INCREMENT CURSOR AND COUNT
  301.     INC    CL
  302.     INC    BX        ; INCREMENT POINTER
  303.     ES
  304.     MOV    [BX],AL        ; SAVE IT IN COMMAND LINE
  305.     PUSH    BX        ; SAVE POINTER
  306.     PUSH    CX        ; SAVE COUNTERS
  307.     SUB    CH,CL        ; COUNT AGAIN
  308.     INC    CH
  309.     MOV    CL,CH
  310.     ES
  311.     CMP    [BX],=' '    ; COMPENSATE FOR INSERTED CTL CHAR
  312.     JNC    INSL
  313.     DEC    CL
  314. INSL:    ES
  315.     MOV    AL,[BX]
  316.     CMP    AL,=' '
  317.     JNC    __X
  318.     INC    CL
  319. __X:    CALL    OUTCH        ; DISPLAY THE CHAR
  320.     INC    BX
  321.     DEC    CH
  322.     JNZ    INSL
  323. ;
  324. INSD:    DEC    CL
  325. INSDL:    CALL    BKSPC
  326.     DEC    CL
  327.     JNZ    INSDL
  328. ;
  329. INSE:    POP    CX
  330.     POP    BX
  331.     INC    BX
  332.     JMP    GETNXT
  333. ;
  334. ;    OUTCH - output a character, display control char if necessary
  335. ;
  336. OUTCH:    CMP    AL,=' '        ; CHECK IF CTL CHARACTER
  337.     JNC    NOCTL        ; SKIP IF NOT
  338.     PUSH    AX        ; SAVE CHAR
  339.     MOV    AL,=LITC    ; PREFIX CHAR
  340.     CALL    PUTCH        ; DISPLAY IT
  341.     POP    AX        ; GET CHAR BACK
  342.     ADD    AL,=0X40    ; MAKE IT ALPHA
  343. NOCTL:    JMP    PUTCH        ; DISPLAY CHAR
  344. ;
  345. ;    +----------------------------+
  346. ;    | COMMAND PROCESSOR ROUTINES |
  347. ;    +----------------------------+
  348. ;
  349. ;    CR typed -- exit back to turbodos
  350. ;
  351. EXIT:    CMP    CH,CL        ; SEE IF WE'RE AT END OF LINE
  352.     JZ    CNTXIT    
  353.     INC    BX        ; ELSE UP POINTERS
  354.     INC    CL
  355.     JMPS    EXIT
  356. ;
  357. CNTXIT:    PUSH    CX
  358.     MOV    AL,=CR
  359.     CALL    ECHO#        ; ECHO THE RETURN
  360.     POP    CX
  361.     MOV    BX,CLSAVE    ; GET COMMAND LINE POINTER
  362.     ES
  363.     MOV    [BX],CH        ; SAVE ACTUAL BYTE COUNT
  364.     PUSH    BX        ; SAVE
  365.     PUSH    CX        ;    REGISTERS
  366.     MOV    CL,CH        ; SET UP COUNT
  367.     MOV    CH,=0
  368.     INC    CL
  369.     MOV    DX,&OLDLIN
  370.     MOV    AX,ES
  371.     MOV    BP,DS
  372.     CALL    LDIR#
  373.     POP    CX        ; GET REGS BACK
  374.     POP    BX
  375.     MOV    AL,CH        ; BYTE COUNT IN A
  376.     RET
  377. ;
  378. ;    CBEGLI - go to beginning of line
  379. ;
  380. CBEGLI:    INC    CL        ; SET UP CURSOR POINTER
  381. CBEGL1:    DEC    CL        ; DECREMENT CURSOR PTR
  382.     JNZ    __X        ;    UNTIL ZERO
  383.     JMPS    GN1
  384. ;
  385. __X:    CALL    BKSPC
  386.     DEC    BX
  387.     ES
  388.     CMP    [BX],=' '
  389.     JNC    CBEGL1
  390.     CALL    BKSPC
  391.     JMPS    CBEGL1
  392. ;
  393. ;    CENDLI - go to end of line
  394. ;
  395. CENDLI:    CMP    CL,CH        ; IF CURSOR AT END OF LINE
  396.     JNZ    __X        ;    THEN GET NEXT CHAR
  397.     JMPS    GN1
  398. ;
  399. __X:    INC    CL        ; POINT TO NEXT CHAR
  400.     ES
  401.     MOV    AL,[BX]
  402.     INC    BX
  403.     CMP    AL,=' '
  404.     MOV    AL,FORSPC
  405.     JNC    __Y
  406.     CALL    PUTCH
  407. __Y:    CALL    PUTCH
  408.     JMP    CENDLI        ; AND SO ON
  409. ;
  410. ;    CBACKC - back 1 char
  411. ;
  412. CBACKC:    OR    CL,CL        ; IF AT LEFT
  413.     JZ    GN1        ;    DO NOTHING
  414.     CALL    BKSPC        ; ELSE BACKSPACE
  415.     DEC    CL        ; DECREMENT COUNTER
  416.     DEC    BX        ;    POINTER
  417.     ES
  418.     CMP    [BX],=' '
  419.     JNC    GN1
  420.     CALL    BKSPC
  421.     JMPS    GN1
  422. ;
  423. ;    CFORWC - forward 1 char
  424. ;
  425. CFORWC:    CMP    CL,CH        ; IF AT END
  426.     JZ    GN1        ;    DO NOTHING
  427.     INC    CL        ; INCREMENT COUNTER
  428.     ES
  429.     CMP    [BX],=' '
  430.     MOV    AL,FORSPC
  431.     JNC    __X
  432.     CALL    PUTCH
  433. __X:    CALL    PUTCH        ; MOVE CURSOR
  434.     INC    BX        ;    POINTER
  435. GN1:    JMP    GETNXT
  436. ;
  437. ;    CQUOTE - do next char literally
  438. ;
  439. CQUOTE:    MOV    BYTE QFLAG,=0
  440.     JMPS    GN1
  441. ;
  442. ;    CRECAL - recall previous command line
  443. ;
  444. CRECAL:    OR    CH,CH
  445.     JZ    __X        ; COUNT MUST BE 0
  446.     JMPS    GN1
  447. ;
  448. __X:    CMP    OLDLIN,=BYTE 0    ; ANYTHING IN?
  449.     JNZ    __Y        ;    NO, EMPTY
  450.     JMPS    GN1
  451. ;
  452. __Y:    PUSH    BX
  453.     MOV    DX,&OLDLIN    ; GET OLD LINE
  454.     XCHG    DX,BX        ; SET UP FOR MOVE
  455.     DEC    DX
  456.     MOV    CL,[BX]
  457.     MOV    CH,=0
  458.     PUSH    CX
  459.     INC    CL
  460.     MOV    AX,DS
  461.     MOV    BP,ES
  462.     CALL    LDIR#
  463.     POP    CX
  464.     MOV    CH,CL        ; GET COUNT INTO CH
  465.     POP    BX        ; GET POINTER
  466. DSLP:    ES
  467.     MOV    AL,[BX]        ; GET BYTE
  468.     CALL    OUTCH        ; DISPLAY IT WITH CTL CHAR EXPANSION
  469.     INC    BX        ; POINT TO NEXT
  470.     DEC    CH        ; UNTIL ALL DONE
  471.     JNZ    DSLP
  472.     MOV    CH,CL        ; COUNT = CURSOR
  473.     JMPS    GN1        ; EXIT
  474. ;
  475. ;    CDELBA - delete previous character, move following chars to left
  476. ;
  477. CDELBA:    OR    CL,CL        ; SEE IF AT START OF LINE
  478.     JZ    GN1
  479.     MOV    DX,=0
  480.     CALL    DELLFT        ; DELETE CHAR TO THE LEFT
  481.     CMP    CL,CH
  482.     JZ    GN2
  483.     JMPS    MOVDEL        ; MOVE AFTER DELETE
  484. ;
  485. ;    CDELFO - delete following character, move remainder left
  486. ;
  487. CDELFO:    CMP    CH,CL        ; IF CURSOR AT RIGHT END
  488.     JZ    GN2        ;    THEN DO NOTHING
  489.     MOV    DX,=0
  490.     DEC    CH
  491. MOVDEL:    MOV    AL,CH        ; SEE IF END OF LINE
  492.     PUSH    CX        ; SAVE COUNTERS
  493.     PUSH    BX        ; SAVE LINE PTR
  494.     SUB    AL,CL        ; AL=NUMBER OF CHARS
  495.     PUSH    AX
  496.     INC    AL
  497.     MOV    CL,AL
  498.     MOV    CH,=0
  499.     PUSH    DX        ; SAVE CONTROL CHAR COUNT
  500.     MOV    DH,BH
  501.     MOV    DL,BL
  502.     INC    BX
  503.     PUSH    AX
  504.     MOV    AX,ES
  505.     MOV    BP,AX
  506.     CALL    LDIR#
  507.     POP    AX
  508.     POP    DX        ; GET CONTROL CHAR COUNT (0/1)
  509.     POP    AX        ; GET BYTE COUNT
  510.     POP    BX        ; GET LINE POINTER
  511.     PUSH    BX        ; SAVE IT AGAIN
  512.     MOV    CH,AL
  513.     OR    AL,AL
  514.     JNZ    MVDELL    
  515.     MOV    AL,=' '
  516.     CALL    PUTCH
  517.     CALL    PUTCH
  518.     CALL    BKSPC
  519.     CALL    BKSPC
  520.     JMPS    MVDELQ
  521. ;
  522. MVDELL:    ES
  523.     MOV    AL,[BX]
  524.     CMP    AL,=' '
  525.     JNC    MVD1
  526.     INC    DL
  527. MVD1:    CALL    OUTCH
  528.     INC    DL        ; INCREMENT CHAR COUNT
  529.     INC    BX
  530.     DEC    CH
  531.     JNZ    MVDELL
  532.     MOV    AL,=' '
  533.     CALL    PUTCH        ; WIPE OUT LAST CHAR
  534.     CALL    PUTCH
  535.     CALL    BKSPC
  536. MVDEL1:    MOV    CH,DL
  537.     CALL    BKSPC
  538. MVDEL2:    CALL    BKSPC
  539.     DEC    CH
  540.     JNZ    MVDEL2
  541. MVDELQ:    POP    BX
  542.     POP    CX
  543. GN2:    JMP    GETNXT
  544. ;
  545. ;    CKILFO - kill all chars forward
  546. ;
  547. CKILFO:    CMP    CL,CH
  548.     JZ    GN2        ; NOTHING TO KILL
  549.     MOV    AL,CH
  550.     SUB    AL,CL        ; GET BYTE COUNT
  551.     MOV    CH,CL
  552.     PUSH    CX        ; SAVE COUNT, CURSOR
  553.     MOV    KILLEN,AL    ; STORE KILL BUFFER LENGTH
  554.     MOV    CL,AL
  555.     MOV    CH,=0
  556.     PUSH    CX
  557.     PUSH    BX        ; SAVE LINE POINTER
  558.     MOV    DX,&KILBUF
  559.     MOV    BP,DS
  560.     MOV    AX,ES
  561.     CALL    LDIR#        ; MOVE INTO KILL BUFFER (ES TO DS)
  562.     POP    BX
  563.     POP    CX
  564.     PUSH    BX
  565.     MOV    CH,CL
  566. CKILF1:    ES
  567.     MOV    AL,[BX]
  568.     INC    BX
  569.     CMP    AL,=' '
  570.     MOV    AL,=' '
  571.     JNC    CKILF2    
  572.     CALL    PUTCH
  573.     INC    CL
  574. CKILF2:    CALL    PUTCH
  575.     DEC    CH
  576.     JNZ    CKILF1
  577. CKILF3:    CALL    BKSPC
  578.     DEC    CL
  579.     JNZ    CKILF3
  580.     POP    BX
  581.     POP    CX
  582.     JMPS    GN2
  583. ;
  584. ;    CKILBA - kill all chars backward
  585. ;
  586. CKILBA:    OR    CL,CL
  587.     JZ    GN2        ; NOTHING TO KILL
  588.     PUSH    CX        ; SAVE COUNTERS
  589.     PUSH    BX        ; SAVE POINTER
  590.     MOV    DX,CLSAVE    ; GET POINTER TO START
  591.     INC    DX
  592.     SUB    BX,DX        ; BX IS NOW LENGTH
  593.     MOV    CH,BH
  594.     MOV    CL,BL
  595.     MOV    BX,&KILLEN    ; POINT TO KILL BUFFER
  596.     MOV    [BX],CL
  597.     INC    BX
  598.     XCHG    DX,BX
  599.     MOV    BP,DS
  600.     MOV    AX,ES
  601.     CALL    LDIR#        ; MOVE STUFF INTO KILL BUFFER (ES TO DS)
  602.     POP    BX        ; GET OLD PTR
  603.     POP    CX
  604.     PUSH    CX
  605.     PUSH    BX
  606. CKILB1:    DEC    BX
  607.     ES
  608.     CMP    [BX],=' '
  609.     JNC    __X
  610.     CALL    BKSPC
  611. __X:    CALL    BKSPC
  612.     DEC    CL
  613.     JNZ    CKILB1    
  614.     MOV    DL,=0
  615. CKILB2:    ES
  616.     MOV    AL,[BX]
  617.     INC    BX
  618.     CMP    AL,=' '
  619.     MOV    AL,=' '
  620.     JNC    CKILB3    
  621.     CALL    PUTCH
  622.     INC    DL
  623. CKILB3:    CALL    PUTCH
  624.     INC    DL
  625.     DEC    CH
  626.     JNZ    CKILB2
  627.     MOV    CH,DL
  628. CKILB4:    CALL    BKSPC
  629.     DEC    CH
  630.     JNZ    CKILB4
  631.     POP    BX        ; GET LINE PTR
  632.     POP    CX        ; GET COUNTERS
  633.     SUB    CH,CL        ; A NOW HAS BYTE COUNT
  634.     MOV    CL,CH
  635.     MOV    CH,=0
  636.     PUSH    CX
  637.     INC    CX
  638.     MOV    DX,CLSAVE
  639.     INC    DX
  640.     PUSH    DX
  641.     MOV    AX,DS
  642.     MOV    BP,ES
  643.     CALL    LDIR#        ; (DS TO ES)
  644.     POP    BX
  645.     POP    CX
  646.     MOV    CH,CL
  647.     MOV    CL,=0
  648.     OR    CH,CH
  649.     JZ    GN3
  650.     PUSH    BX
  651.     PUSH    CX
  652.     MOV    DL,=0
  653. CKILB5:    ES
  654.     MOV    AL,[BX]
  655.     CMP    AL,=' '
  656.     JNC    CKILB6    
  657.     INC    DL
  658.     PUSH    AX
  659.     MOV    AL,=LITC
  660.     CALL    PUTCH
  661.     POP    AX
  662.     ADD    AL,=0X40
  663. CKILB6:    CALL    PUTCH
  664.     INC    DL
  665.     INC    BX
  666.     DEC    CH
  667.     JNZ    CKILB5
  668.     MOV    CH,DL
  669. CKILB7:    CALL    BKSPC
  670.     DEC    CH
  671.     JNZ    CKILB7
  672.     POP    CX
  673.     POP    BX
  674. GN3:    JMP    GETNXT
  675. ;
  676. ;    CYANK - yank kill buffer to current cursor
  677. ;
  678. CYANK:    MOV    AL,KILLEN    ; GET KILL BUFFER LENGTH
  679.     OR    AL,AL
  680.     JZ    GN3        ; KILL BUFFER EMPTY
  681.     ADD    AL,CH        ; CHECK TOTAL SIZE
  682.     JC    __X        ; OVER 256 BYTES...
  683.     CMP    CLEN,AL
  684.     JNC    YNTL        ; GO AHEAD IF NOT TOO LONG
  685. __X:    CALL    ERROR        ; BEEP IF TOO LONG
  686.     JMPS    GN3
  687. ;
  688. YNTL:    MOV    INSY,=0    
  689.     CMP    CH,CL        ; CHECK IF CURSOR AT END OF LINE
  690.     MOV    AL,KILLEN    ; GET LENGTH OF KILL BUFFER
  691.     JZ    NOMOVE        ; SKIP IF AT END OF LINE
  692.     PUSH    CX        ; SAVE COUNT
  693.     PUSH    BX        ; SAVE POINTER
  694.     MOV    DL,AL
  695.     MOV    DH,=0        ; DX = NUMBER OF BYTES TO BE FREED
  696.     SUB    CH,CL
  697.     MOV    CL,CH
  698.     MOV    CH,=0        ; CX HAS BYTES TO BE MOVED
  699.     ADD    BX,CX        ; POINT TO END OF LINE
  700.     PUSH    BX
  701.     ADD    BX,DX        ; POINT TO NEW END OF LINE
  702.     XCHG    DX,BX
  703.     POP    BX
  704.     INC    CX
  705.     MOV    AX,ES
  706.     MOV    BP,AX
  707.     CALL    LDDR#
  708.     POP    BX
  709.     POP    CX
  710.     MOV    INSY,=0XFF    
  711.     MOV    AL,KILLEN    ; GET LENGTH DELETE CHAR FORWARD
  712. NOMOVE:    PUSH    CX
  713.     PUSH    BX
  714.     XCHG    BX,DX        ; DESTINATION TO DX
  715.     MOV    BX,&KILBUF
  716.     MOV    CL,AL
  717.     MOV    CH,=0
  718.     PUSH    CX
  719.     MOV    AX,DS
  720.     MOV    BP,ES
  721.     CALL    LDIR#
  722.     POP    DX
  723.     POP    BX
  724.     POP    CX
  725. YDSLP:    ES
  726.     MOV    AL,[BX]
  727.     CALL    OUTCH
  728.     INC    CH
  729.     INC    CL
  730.     INC    BX
  731.     DEC    DL
  732.     JNZ    YDSLP    
  733.     MOV    AL,INSY    
  734.     INC    AL
  735.     JNZ    GN4
  736. ;
  737. ;    now redisplay remainder of line, then step back
  738. ;
  739.     PUSH    BX        ; SAVE LINE PTR
  740.     MOV    DL,=0        ; CHARACTER COUNT
  741.     PUSH    CX
  742. YTL1:    CMP    CH,CL
  743.     JZ    YTL25
  744.     ES
  745.     MOV    AL,[BX]
  746.     INC    CL
  747.     CMP    AL,=' '
  748.     JNC    YTL2
  749.     INC    DL
  750. YTL2:    INC    DL
  751.     CALL    OUTCH
  752.     INC    BX
  753.     JMP    YTL1
  754. ;
  755. YTL25:    POP    CX
  756. YTL3:    CALL    BKSPC
  757.     DEC    DL
  758.     JNZ    YTL3
  759.     POP    BX
  760. GN4:    JMP    GN3
  761. ;
  762. ;    ABORT LINE
  763. ;
  764. CABORT:    MOV    CX,=0
  765.     MOV    BX,CLSAVE
  766.     INC    BX
  767.     JMP    EXIT
  768. ;
  769. ;    EXPERIMENTAL STUFF
  770. ;
  771. ;    PUSH KILLED LINE
  772. ;
  773. CPUSHK:    CMP    KILLEV,=0        ; IF NOTHING STACKED
  774.     JZ    __CPK            ;   THEN CONTINUE
  775. __CPUE:    CALL    ERROR            ;     ELSE BEEP
  776. __GNXT:    JMP    GETNXT            ;     AND CONTINUE
  777. ;
  778. __CPK:    PUSH    BX
  779.     PUSH    CX
  780.     MOV    BX,=170            ; WE NEED 163 BYTES
  781.     CALL    ALLOC#            ; GET THEM
  782.     TEST    AL,AL            ; IF WE CAN
  783.     JZ    __CP            ;   OK, SO WE DON'T GET IT
  784.     CALL    ERROR
  785. __GX:    POP    CX
  786.     POP    BX
  787.     JMPS    __GNXT
  788. ;
  789. __CP:    INC    KILLEV            ; INCREMENT KILL KEVEL
  790.     MOV    KLEVAD,BX        ; SAVE POINTER
  791.     MOV    DX,BX
  792.     MOV    BX,&KILLEN
  793.     MOV    AX,DS
  794.     MOV    BP,AX
  795.     MOV    CX,=163            ; 163 BYTES
  796.     CALL    LDIR#
  797.     JMPS    __GX
  798. ;
  799. ;    POP KILLED LINE
  800. ;
  801. CPOPK:    CMP    KILLEV,=1        ; IF STACK ACTIVE
  802.     JZ    __CPK            ;   THEN CONTINUE
  803.     CALL    ERROR            ;     ELSE BEEP
  804. __GNXT:    JMP    GETNXT
  805. ;
  806. __CPK:    PUSH    BX
  807.     PUSH    CX
  808.     MOV    KILLEV,=0        ; SET KILL LEVEL TO 0
  809.     MOV    BX,KLEVAD        ; GET STACK POINTER
  810.     MOV    DX,&KILLEN        ; GET DESTINATION ADDR
  811.     MOV    AX,DS
  812.     MOV    BP,AX
  813.     MOV    CX,=163            ; 163 BYTES
  814.     CALL    LDIR#            ; MOVE IT
  815.     MOV    BX,KLEVAD
  816.     CALL    DEALOC#            ; DEALLOCATE MEMORY
  817.     POP    CX
  818.     POP    BX
  819.     JMPS    __GNXT            ; QUIT
  820. ;
  821.     END    
  822.