📄 gwlin.asm
字号:
; cursor cannot be on KANJI2 byte - code removed.
MOV EOLPTR,BX ;truncate the line at the cursor
MOV b$INBUF[BX],0 ;set end-of-line byte
CALL UPDATE ;update the screen display
POP BX ;restore register from stack
RET ;return to caller
;********************************************************************
; BEGIN - move cursor to start of input line
;********************************************************************
BEGIN:
PUSH BX ;save register on stack
CALL SETLOC ;set display columns / UPDPTR
XOR BX,BX ;clear BX
MOV CSRPTR,BX ;move cursor to start of input line
CALL UPDATE ;update the screen display
POP BX ;restore register from stack
RET ;return to caller
;********************************************************************
; APPEND - move cursor to end of input line
;********************************************************************
APPEND:
PUSH BX ;save register on stack
CALL SETLOC ;set display columns / UPDPTR
MOV BX,EOLPTR ;set to EOL pointer
MOV CSRPTR,BX ;move cursor to end of input line
CALL UPDATE ;update the screen display
POP BX ;restore register from stack
RET ;return to caller
;********************************************************************
; ERASE - delete entire input line
;********************************************************************
ERASE:
PUSH BX ;save register on stack
CALL SETLOC ;set display columns / UPDPTR
XOR BX,BX ;clear BX
MOV CSRPTR,BX ;set cursor to start of input line
MOV UPDPTR,BX ;set update to start of input line
MOV EOLPTR,BX ;set EOL to start of input line
CALL UPDATE ;update the screen display
MOV b$INBUF,BL ;put end-of-line byte at start
POP BX ;restore register from stack
RET ;return to caller
;********************************************************************
; CSRLFT - move cursor once to the left
;********************************************************************
CSRLFT:
PUSH AX ;save registers on stack
PUSH BX
MOV BX,CSRPTR ;get b$INBUF cursor index
OR BX,BX ;test if cursor at line beginning
JZ CSRLF2 ;if so, then just jump to exit
; backspace over byte at cursor
; if extra display blank is now on cursor, backspace over it
DEC BX ;get byte before it
CALL OUTBS ;backspace over byte at cursor
DEC CSRPTR ;set pointer to previous byte
CSRLF2:
POP BX ;restore registers from stack
POP AX
RET ;return to caller
;********************************************************************
; CSRRGT - move cursor once to the right
; move over both bytes of KANJI character
;********************************************************************
;Entry BX = pointer in INPSTR
CSRRGT:
PUSH AX ;save registers on stack
PUSH BX
MOV BX,CSRPTR ;get b$INBUF cursor index
CMP BX,EOLPTR ;test if cursor is at EOL
JNE CSRRG0
POP BX
POP AX
MOV AL,ASC_SP ; if at EOL then put out a space
JMP ASCCHR
CSRRG0:
; CMP BX,EOLPTR ;test if cursor is at EOL
; JE CSRRG4 ;if so, then just jump to exit
; if byte at cursor is KANJI1, then output it and its
; partner and then backspace once
; do not backspace, but just output both characters
MOV AL,b$INBUF[BX] ;get KANJI2 (or ASCII) byte
CALL B$TTY_SOUT ;and output it also
; if cursor over extra blank, then pass over it
; update CSRPTR and call FRCLIN
INC CSRPTR ;update cursor pointer
CALL FRCLIN ;force cursor on new line if needed
CSRRG4:
POP BX ;restore registers from stack
POP AX
RET ;and return to caller
;*********************************************************************
; FORWRD - move cursor forward one word - first alphanumeric
; character after the first non-alphanumeric one
;*********************************************************************
FORWRD:
PUSH BX ;push register on stack
MOV BX,CSRPTR ;get cursor pointer
DEC BX ;BX is at cursor after INC next
FORWR1:
INC BX ;move pointer forward one byte
CMP BX,EOLPTR ;test if at line end
JZ FORWR3 ;if so, then jump
CALL TSTALN ;test if byte is alphanumeric
JC FORWR1 ;if so, then loop back
FORWR2:
CMP BX,EOLPTR ;test if at line end
JZ FORWR3 ;if so, then jump
INC BX ;move pointer forward one byte
CALL TSTALN ;test if byte is alphanumeric
JNC FORWR2 ;if not, then loop back
FORWR3:
CMP BX,CSRPTR ;is cursor at new value?
JE FORWR4 ;if so, then jump to finish up
CALL CSRRGT ;move cursor right, CSRPTR updated
JMP SHORT FORWR3 ;try for next one
FORWR4:
POP BX ;restore register from stack
RET ;return to caller
;*********************************************************************
; BAKWRD - move cursor backward one word - before first
; non-alphanumeric character after first alphanumeric
;*********************************************************************
BAKWRD:
PUSH BX ;push register on stack
MOV BX,CSRPTR ;get cursor pointer
BAKWR1:
OR BX,BX ;test if at line start
JZ BAKWR3 ;if so, then jump
DEC BX ;move pointer back one byte
CALL TSTALN ;test if byte is alphanumeric
JNC BAKWR1 ;if not, then loop back
BAKWR2:
OR BX,BX ;test if at line start
JZ BAKWR3 ;if so, then jump
DEC BX ;move pointer back one byte
CALL TSTALN ;test if byte is alphanumeric
JC BAKWR2 ;if so, then loop back
INC BX ;overshot, move to first alphanum
BAKWR3:
CMP BX,CSRPTR ;is cursor at new value?
JE BAKWR4 ;if so, then jump to finish up
CALL CSRLFT ;move cursor left, CSRPTR updated
JMP SHORT BAKWR3 ;try for next one
BAKWR4:
POP BX ;restore register from stack
RET ;return to caller
;*********************************************************************
; TSTALN - set carry if b$INBUF[BX] points to an alphanumeric
; character (KANJI, 0-9, A-Z, a-z).
;*********************************************************************
TSTALN:
PUSH AX ;save register on stack
MOV AL,b$INBUF[BX] ;get character to test
CMP AL,"0" ;test against lowest numeric
JB TSTAL1 ;if less, then non-alphanumeric
CMP AL,"9" ;test against highest numeric
JBE TSTAL2 ;if not greater, then alphanumeric
CMP AL,"A" ;test against lowest uppercase
JB TSTAL1 ;if less, then non-alphanumeric
CMP AL,"Z" ;test against highest uppercase
JBE TSTAL2 ;if not greater, then alphanumeric
CMP AL,"a" ;test against lowest lowercase
JB TSTAL1 ;if less, then non-alphanumeric
CMP AL,"z" ;test against highest lowercase
JBE TSTAL2 ;if not greater, then alphanumeric
TSTAL1:
CLC ;clear carry for non-alphanumeric
JMP SHORT TSTAL3 ;jump to return
TSTAL2:
STC ;set carry for alphanumeric
TSTAL3:
POP AX ;restore register from stack
RET ;return to caller
;********************************************************************
; SETLOC - set display column amounts for the cursor and
; end-of-line positions
; set default value of UPDPTR to CSRPTR
;********************************************************************
SETLOC:
PUSH BX ;save register on stack
MOV BX,CSRPTR ;get cursor pointer value
MOV UPDPTR,BX ;set default value for update
MOV CSRLOC,BX ;store for later use in UPDATE
MOV BX,EOLPTR ;get eol pointer value
MOV EOLLOC,BX ;store for later use in UPDATE
POP BX ;restore register on stack
RET ;and return to caller
;********************************************************************
; GETLOC - take b$INBUF pointer in BX and add the number of
; extra blanks to return the display column in BX.
;********************************************************************
;********************************************************************
; UPDATE - update screen display with the contents of b$INBUF
; entry - CSRLOC - display column of old b$INBUF cursor
; EOLLOC - display column of old b$INBUF EOL
; CSRPTR - b$INBUF index of new cursor position
; EOLPTR - b$INBUF index of new EOL position
; UPDPTR - b$INBUF index to start update
;********************************************************************
UPDATE:
PUSH AX ;save registers on the stack...
PUSH BX
PUSH CX
PUSH DX
; put update pointer in DX - decrement if on KANJI2 byte
; cursor cannot be on KANJI2 byte - remove code.
MOV DX,UPDPTR ;get update pointer
; backspace display to update pointer
MOV CX,CSRLOC ;get old cursor display column
SUB CX,DX ;result is number of backspaces
JCXZ UPDA06 ;if no backspaces, then jump
UPDA05:
CALL OUTBS ;backspace the display
LOOP UPDA05 ;repeat until at start of update
; output string in b$INBUF from update start to EOL
UPDA06:
; MOV BX,DX ;start output at update pointer
MOV BX,UPDPTR ;start output at update pointer
UPDA07:
CMP BX,EOLPTR ;test if string has been output
JE UPDA09 ;if so, then jump
; output the character at b$INBUF[BX]
MOV AL,b$INBUF[BX] ;get buffer character
CALL B$TTY_SOUT ; output character to screen
CMP AL,0FFH ; Test if char was 0ffH
JNE UPDA08_NOT_FF ; Brif not
CALL B$TTY_SOUT ; Send it again
UPDA08_NOT_FF:
INC BX ;advance update pointer for next
JMP SHORT UPDA07 ;and try to process it
; blank out trailing characters if new string was shorter
; backspace cursor back to EOL
UPDA09:
MOV CX,EOLLOC ;CX has display column of old EOL
SUB CX,BX ;CX now has old-new difference
OR CX,CX ;test if new string was shorter
JLE UPDA12 ;if not, then jump
PUSH CX ;save shrinkage count
MOV AL,ASC_SP ;put in ASCII space for output
UPDA10:
CALL B$TTY_SOUT ; output the space to cover old string
LOOP UPDA10 ;loop until old string covered
POP CX ;get shrinkage count again
UPDA11:
CALL OUTBS ;output backspace to screen
LOOP UPDA11 ;loop until back to new EOL
; backspace to location of the new cursor to complete update
UPDA12:
MOV CX,BX ;put new EOL display column in CX
MOV BX,CSRPTR ;BX has new cursor index
SUB CX,BX ;get backspaces from EOL to cursor
JCXZ UPDA14 ;if no backspaces, then jump
UPDA13:
CALL OUTBS ;output backspace
LOOP UPDA13 ;loop until back to new cursor
JMP SHORT UPDA15 ;jump to exit
; cursor is at end of input line - if also at end of display
; line, output space and backspace for new display line
UPDA14:
CALL FRCLIN ;force new line if present is full
; done - restore register and return
UPDA15:
POP DX ;restore registers from stack
POP CX
POP BX
POP AX
RET ;and return to caller
;********************************************************************
; OUTBS - output backspace to screen
;********************************************************************
OUTBS:
PUSH AX ;save register on stack
MOV AL,b$IOFLAG
AND AL,RED_INP OR RED_OUT ; redirected input and output?
CMP AL,RED_INP OR RED_OUT
JZ OUTBX ; brif so -- don't touch screen
PUSH DX ; save register
MOV DX,b$CURSOR ; get cursor location (1,1) relative
DEC DH ; decrement column and set flags
JNZ OUTBS1 ; jump if not now at column 0
MOV DH,BYTE PTR b$CRTWIDTH ; column 0 - put in one past end
DEC DX ; and decrement row counter
OUTBS1:
CALL B$SCNLOC ;display cursor at new location
POP DX ; restore register
OUTBX:
POP AX ;restore register from stack
RET ;and return to caller
;********************************************************************
; OUTBEL - output BELL character to screen
;********************************************************************
OUTBEL:
; PUSH AX ;save register on stack
; MOV AL,CNTL ; put control char flag in
; CALL B$TTY_SOUT ;and output it to the speaker
; MOV AL,CTL_G ;put control-G (BELL) in for output
; CALL B$TTY_SOUT ;and output it to the speaker
; POP AX ;restore register from stack
cCALL B$BLEEP ; sound bell on terminal
RET ;and return to caller
;********************************************************************
; FRCLIN - forces the cursor to the next display line if the
; present display line is full
;********************************************************************
FRCLIN:
PUSH AX ;save registers on stack
PUSH BX
CALL B$SCRN_GPOS ; get column position of cursor
CMP AH,BYTE PTR b$CRTWIDTH ; test if at end of display line
JNE FRCLI3 ;if not, then jump
; display line full - if at b$INBUF EOL, then output space
; and backspace
MOV BX,CSRPTR ;get cursor index
CMP BX,EOLPTR ;test if at b$INBUF EOL
JNE FRCLI1 ;if not, then jump
MOV AL,ASC_SP ;get ASCII space
CALL B$TTY_SOUT ;and output it
CALL OUTBS ;then output the backspace
JMP SHORT FRCLI3 ;jump to exit
; not EOL - byte must be KANJI1 or ASCII
FRCLI1:
; ASCII byte - output it and then backspace over it
MOV AL,b$INBUF[BX] ;get ASCII byte
CALL B$TTY_SOUT ;and output it
CALL OUTBS ;backspace over it
FRCLI3:
POP BX ;restore registers from stack
POP AX
RET ;return to caller
;********************************************************************
; TSTKJ1 - test for first byte of KANJI in b$INBUF[BX]
;********************************************************************
; entry - BX - b$INBUF index to byte tested
; exit - PSW.C=0 - byte tested is not KANJI1
; PSW.C=1 - byte tested is KANJI1
;********************************************************************
; TSTKJ2 - test for second byte of KANJI in b$INBUF[BX]
;********************************************************************
; entry - BX - b$INBUF index to byte tested
; exit - PSW.C=0 - byte tested is not KANJI2
; PSW.C=1 - byte tested is KANJI2
sEnd CN_TEXT
END ;textual end of module B$RDLIN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -