;
; INLINE --
; INPUT LINE EDITOR
; INPUT A LINE FROM CON: INTO THE BUFFER POINTED TO BY H&L
; INPUT PARAMETERS:
; HL PTS TO BUFFER
; A = ECHO FLAG (A=0 MEANS NO ECHO)
; OUTPUT PARAMETERS:
; NO REGS AFFECTED
; INPUT LINE EDITING CHARACTERS ARE --
; <BS> -- DELETE PREVIOUS CHAR AND BACK UP CURSOR (SOFTCOPY)
; <DEL> -- DELETE PREVIOUS CHAR AND ECHO IT (HARDCOPY)
; <CR> -- INPUT COMPLETE
; <LF> -- SKIP DOWN TO NEXT LINE AND INSERT <CR> <LF>
; CTRL-X -- ERASE CURRENT LINE AND BACK UP CURSOR (SOFTCOPY)
; CTRL-U -- ERASE CURRENT LINE (HARDCOPY)
; CTRL-R -- RETYPE CURRENT LINE
; CTRL-E -- GO TO NEXT LINE
;
EXT CCOUT
EXT CIN
EXT COUT
EXT CRLF
PUTRG MACRO
PUSH B ; SAVE BC, DE, HL
PUSH D
PUSH H
ENDM
GETRG MACRO
POP H ; RESTORE HL, DE, BC
POP D
POP B
ENDM
;
; MAIN INLINE ENTRY POINT
;
INLINE::
PUTRG ; SAVE REGISTERS
PUSH PSW ; SAVE PSW
STA ECHO ; SAVE ECHO FLAG
SHLD START ; SAVE START OF STRING
; INLINE RESTART LOOP
INL0:
LHLD START ; GET START OF STRING
MVI C,0 ; SET CHAR COUNT
; MAIN LOOP
INL1:
CALL CIN ; GET INPUT CHAR
CPI NULL ; DO NOT PERMIT <NULL>
JZ INL1
CPI BS ; BACKSPACE?
JZ INBS
CPI DEL ; DELETE?
JZ INDEL
CPI TAB ; TABULATE?
JZ INTAB
CPI CR ; CARRIAGE RETURN?
JZ INCR
CPI LF ; LINE FEED?
JZ INLF
CPI CTRLU ; CTRL-U?
JZ RESTRT
CPI CTRLX ; CTRL-X?
JZ REXSTRT
CPI CTRLR ; CTRL-R?
JZ RETYPE
CPI CTRLE ; CTRL-E?
JZ NEWLINE
MOV M,A ; STORE CHAR
INX H ; PT TO NEXT
CALL CTRL ; PRINT CHAR
INR C ; INCR CHAR CNT
JMP INL1
; TAB -- TABULATE TO NEXT TAB STOP
INTAB:
MOV M,A ; STORE <TAB>
INX H ; PT TO NEXT CHAR POSITION
CALL INTAB0 ; TABULATE
JMP INL1
; CTRL-R -- RETYPE CURRENT LINE
RETYPE:
MVI M,0 ; STORE END OF STRING CHAR
MVI C,0 ; RESET CHAR CNT
LHLD START ; GET START ADDRESS
CALL HASH ; PRINT HASH CHAR
RETY1:
MOV A,M ; GET CHAR
ORA A ; ZERO?
JZ INL1 ; CONTINUE
CALL CTRL ; PRINT IT
MOV A,M ; GET CHAR AGAIN
CPI TAB ; DON'T COUNT IF <TAB>
JZ RETY2
CPI BEL ; DON'T COUNT IF <BEL>
JZ RETY2
INR C ; INCR CHAR CNT
RETY2:
INX H ; PT TO NEXT CHAR
JMP RETY1
; CTRL-U -- ERASE LINE AND RESTART
RESTRT:
CALL HASH ; PRINT HASH CHAR
JMP INL0 ; START UP AGAIN
; CTRL-X -- ERASE (AND BACKSPACE) LINE AND RESTART
REXSTRT:
MOV A,C ; CHECK FOR EMPTY LINE
ORA A ; 0 CHARS?
JZ INL0
CALL EXBS ; <BS>
JMP REXSTRT
; LINE FEED -- INSERT <CR> <LF> AND ECHO <CR> <LF>
INLF:
MVI M,CR ; STORE <CR>
INX H ; PT TO NEXT
MVI M,LF ; STORE <LF>
INX H ; PT TO NEXT
MVI C,0 ; RESET CHAR CNT
LDA ECHO ; ECHO ON?
ORA A ; 0=NO
CNZ CRLF ; NEW LINE
JMP INL1
; DELETE -- DELETE PREVIOUS CHAR AND ECHO DELETED CHAR
INDEL:
CALL BOL ; BEGINNING OF LINE?
JZ INL1 ; CONTINUE
DCX H ; BACK UP
MOV A,M ; GET CHAR
CALL CTRL ; PRINT CHAR
CPI BEL ; DON'T CHANGE COUNT IF <BEL>
JZ INL1
INR C ; INCR DISPLAY CHAR COUNT
JMP INL1
; BACKSPACE -- DELETE PREVIOUS CHAR AND BACK UP CURSOR
INBS:
CALL EXBS ; EXECUTE <BS>
JMP INL1
; BACKSPACE ROUTINE
EXBS:
CALL BOL ; BEGINNING OF LINE?
RZ ; CONTINUE IF SO
DCR C ; DECR COUNT
DCX H ; BACK UP
LDA ECHO ; ECHO ON?
ORA A ; 0=NO
RZ
MVI A,BS ; PRINT <BS>
CALL COUT
MVI A,' ' ; <SP>
CALL COUT
MVI A,BS ; <BS>
CALL COUT
RET
; CARRIAGE RETURN -- DONE; STORE ENDING ZERO
INCR:
MVI M,0 ; STORE ENDING ZERO
LDA ECHO ; ECHO ON?
ORA A ; 0=NO
CNZ CRLF ; NEW LINE
POP PSW ; RESTORE PSW
GETRG ; RESTORE REGS
RET
;
; ** SUPPORT ROUTINES **
; BOL -- RETURNS W/ZERO FLAG SET IF USER AT BEGINNING OF LINE
BOL:
XCHG ; DE=HL
LHLD START ; GET START ADR
XCHG ; HL RESTORED
MOV A,D ; CHECK FOR MATCH
CMP H ; MATCH?
RNZ ; NO MATCH
MOV A,E ; CHECK FOR COMPLETE MATCH
CMP L
RNZ ; NO MATCH
PUSH PSW ; SAVE FLAGS
MVI A,BEL ; BEEP
CALL COUT
POP PSW
RET
; CTRL -- IF CHAR>=<SP>, PRINT IT; OTHERWISE, PRINT AS CTRL-CHAR
CTRL:
PUSH B ; SAVE BC
MOV B,A ; SAVE CHAR IN B
LDA ECHO ; CHECK ECHO FLAG
ORA A ; 0=NO ECHO
MOV A,B ; RESTORE CHAR
POP B ; RESTORE BC
RZ ; NO OUTPUT IF NO ECHO
CPI ' ' ; <SP>?
JC CTRL1
JMP COUT ; PRINT IT NORMALLY
CTRL1:
CPI TAB ; TRAP <TAB>
JZ INTAB0
JMP CCOUT ; PRINT WITH CTRL-CHAR PROCESSING
; HASH -- PRINT HASH MARK FOLLOWED BY <CR> <LF>
HASH:
MVI A,'#' ; PRINT HASH CHAR
CALL COUT
JMP CRLF
; BUFFERS
START:
DS 2 ; TEMPORARY STORAGE FOR BUFFER START ADDRESS
ECHO:
DS 1 ; ECHO FLAG (0=NO ECHO)
; INTAB0 -- TABULATE ON SCREEN
INTAB0:
MOV A,C ; GET CHAR CNT
ANI 7 ; MASK FOR DIFFERENCE FROM 8
MOV B,A ; STORE IN REG B TEMPORARILY
MVI A,8 ; SUBTRACT FROM 8
SUB B
MOV B,A ; <SP> COUNT IN B
ADD C ; ADD TO CHAR COUNT
MOV C,A
LDA ECHO ; ECHO ON?
ORA A ; 0=NO
RZ
MVI A,' ' ; <SP> IN A
INTAB1:
CALL COUT ; PRINT <SP>
DCR B ; COUNT DOWN
JNZ INTAB1
RET