📄 gwlin.asm
字号:
POP DX ;restore register from stack
POP AX
RET ;and return to caller
;********************************************************************
; BADCHR - process an illegal character
;********************************************************************
BADCHR:
CALL EDTSTR ;dump out INPSTR to b$INBUF
CALL OUTBEL ;sound bell for signal
RET ;return to caller
;********************************************************************
; FKYCHR - process nonexpanded function key
;********************************************************************
FKYCHR:
PUSH AX ;save register on stack
CALL EDTSTR ;dump out INPSTR to b$INBUF
SUB AL,20H ;subtract offset to keys
CMP AL,NUM_FKEYS ;test if legal key number
JL FKYCH1 ;if legal, then jump
CALL OUTBEL ;sound bell for signal
FKYCH1:
POP AX ;restore register from stack
RET ;and return to caller
;********************************************************************
; ASCCHR - process ASCII character
;********************************************************************
ASCCHR:
CMP BX,INPLEN ;test if INPSTR is full
JL ASCCH1 ;if not, then jump
CALL EDTSTR ;dump out INPSTR to b$INBUF
ASCCH1:
MOV INPSTR[BX],AL ;put ASCII byte in INPSTR
INC BX ;advance INPSTR pointer
RET ;and return to caller
;********************************************************************
; KANCHR - process KANJI character
; rewrite to support interim characters
;********************************************************************
;********************************************************************
; FRCSTR - force INPSTR out if no input character pending
;********************************************************************
FRCSTR:
PUSH AX ;save register on stack
test b$IOFLAG,RED_INP ; input redirected?
jnz frcst1 ; Yes, always a char ready.
CALL B$TTYST ;test for character pending
JNZ FRCST1 ;if one pending, then jump
CALL EDTSTR ;output INPSTR to b$INBUF
FRCST1:
POP AX ;restore register from stack
RET ;return to caller
;********************************************************************
; CTLCHR - process control character
;********************************************************************
; search in CTLTAB for entry (1-byte code, 2-byte address)
; if found, do processing, else signal bell for error
CTLCHR:
PUSH SI ; save register on stack
CALL EDTSTR ;dump out any INPSTR bytes
MOV SI,OFFSET CTLTAB ; initialize pointer to table
CTLCH1:
CMP SI,OFFSET CTLEND ; test if pointer at table end
JE CTLCH4 ;if at end, sound bell for undefined
CMP CS:[SI],AL ; test if entry matches
JE CTLCH2 ;if so, then jump
ADD SI,3 ; point to next table entry
JMP SHORT CTLCH1 ;and try to process it
; set to overwrite mode according to function index
CTLCH2:
CMP SI,OFFSET CTLINS ; check if function clears INSFLG
JAE CTLCH3 ;if not, then jump
MOV INSFLG,0 ;put into overwrite mode
CTLCH3:
CALL CS:[SI+1] ; call routine address in table
JMP SHORT CTLCH5 ;jump to return
; sound bell for undefined key input
CTLCH4:
CALL OUTBEL ;output control-G (BELL) to screen
CTLCH5:
POP SI ; restore register from stack
RET ;and return to caller
;********************************************************************
; TABCHR - print TAB character
;********************************************************************
TABCHR:
PUSH BX ;save registers on stack
PUSH CX
PUSH SI
MOV BX,CSRPTR ;get cursor pointer in b$INBUF
AND BX,7 ;get position within TAB field
MOV CX,8 ;size of TAB field
SUB CX,BX ;get spaces to process
MOV SI,OFFSET DGROUP:b$EightSpaces ; set to string of blanks
CALL PRTCHR ;process the character
POP SI ;restore registers from stack
POP CX
POP BX
RET ;and return to caller
;********************************************************************
; TOGINS - toggle between insert and overwrite mode
;********************************************************************
TOGINS:
XOR INSFLG,0FFH ;complement flag between 00 and FF
RET ;and return to caller
;********************************************************************
; IGNORE - Throw away this control char without beeping.
;********************************************************************
IGNORE: RET
;********************************************************************
; ENDLIN - signal end of line input
; Redisplays input line if: [13]
; LPR_ECHO OR RED_OUT [13]
;********************************************************************
ENDLIN:
AND b$IOFLAG,NOT IN_INPUT ; Tell B$TTY_SOUT to process edited
; buffer
PUSH b$CURSOR ; save previous screen cursor values
TEST b$IOFLAG,LPR_ECHO OR RED_OUT ; printer echo or ouput redir?
JZ ENDLI2 ; brif not -- don't re-display line.
CALL BEGIN ; Move cursor back to beginning of line
ENDLI2:
CALL APPEND ;move cursor to end-of-line, printing as we go
DEC ENDFLG ;set flag from 00 to FF
POP b$CURSOR ; restore previous cursor values
AND b$IOFLAG,NOT F_EDIT ; Re-enable $PRTMAP
RET ;and return
;********************************************************************
; BREAK - exit immediately from program
;********************************************************************
BREAK:
AND b$IOFLAG,NOT (F_EDIT OR IN_INPUT) ; Re-enable $PRTMAP
; and exiting INPUT statement.
CALL APPEND ;move cursor to end of line
JMP B$BREAK ; print Break message and terminate
;********************************************************************
; PRTCHR - process printing character on input line
;********************************************************************
; entry - CX - number of bytes to process
; SI - offset of string to be processed
; CSRPTR - b$INBUF pointer to cursor
; EOLPTR - b$INBUF pointer to end-of-line
; INSFLG - insert mode, 0=overwrite, 1=insert
PRTCHR:
PUSH BX ;save registers used to stack
PUSH DX
CALL SETLOC ;set display columns / UPDPTR
; set default values of insertion pointer BX and byte
; number DX
MOV DX,CX ;set number of bytes to insert
MOV BX,CSRPTR ;and the b$INBUF point to start
; test if insertion or overwrite
TEST INSFLG,0FFH ;test for insertion
JZ PRTCH2 ;if not, overwrite, jump
; try to allocate DX bytes at b$INBUF[BX] for insertion
CALL ALCBYT ;allocate new space in b$INBUF
JC PRTCH4 ;if not enough room, then jump
JMP SHORT PRTCH3 ;jump to common code
; overwrite - allocate any bytes that are appended to b$INBUF
PRTCH2:
SUB DX,EOLPTR ;DX=CX-EOLPTR
ADD DX,BX ;DX=CX-(EOLPTR-CSRPTR)
OR DX,DX ;test if any characters to append
JLE PRTCH3 ;if not, just jump to finish up
MOV BX,EOLPTR ;insertion pointer is at b$INBUF EOL
CALL ALCBYT ;allocate new space in b$INBUF
JC PRTCH4 ;if not enough room, then jump
MOV BX,CSRPTR ;restore pointer to cursor location
; BLKKAN converts any KANJI bytes whose partners are modified
; into ASCII spaces. (KANJI only)
; PUTCHR puts the character bytes entered into b$INBUF.
; UPDATE updates the display screen to reflect the new contents
; of b$INBUF.
PRTCH3:
CALL PUTCHR ;put new characters in b$INBUF
CALL UPDATE ;update screen display
JMP SHORT PRTCH5 ;processing successful - jump
; if error occurred on allocation, output a control-G (BELL)
PRTCH4:
CALL OUTBEL ;output BELL character for error
; done - restore registers and return
PRTCH5:
POP DX ;restore registers
POP BX
RET ;and return to caller
;********************************************************************
; ALCBYT - insert DX new ASCII spaces into b$INBUF indexed
; by BX. The substring from BX to the end-of-line
; is moved to the right DX places.
;********************************************************************
; entry - BX - b$INBUF pointer of insertion
; DX - number of spaces to insert
; exit - PSW.C=0 - insertion successful
; PSW.C=1 - no room - buffer unchanged
ALCBYT:
PUSH AX ;save registers on stack
PUSH CX
PUSH SI
PUSH DI
; test for room in b$INBUF
MOV CX,EOLPTR ;get present EOL index
ADD CX,DX ;add insertion count
CMP CX,BUFLEN ;test if room in buffer
JBE ALCBY1 ;if room, then jump
; no room - set PSW.C=1 and return
STC ;set carry bit in PSW
JMP SHORT ALCBY3 ;and jump to return
; move substring in b$INBUF located from index BX to EOLPTR
; over DX bytes to the right
ALCBY1:
PUSH BX ;save insertion pointer
MOV CX,EOLPTR ;get end-of-line value
SUB CX,BX ;now EOLPTR-BX
INC CX ;EOLPTR-BX+1 = length of substring
MOV BX,EOLPTR ;get end-of-line value
STD ;set flag for decrementing SI/DI
LEA SI,b$INBUF[BX] ;get source offset
MOV DI,SI ;move offset to destination
ADD DI,DX ;add bytes to move to right
REP MOVSB ;move b$INBUF substring
CLD ;clear flag
POP BX ;restore insertion pointer
; put in ASCII spaces in new locations
MOV AL,ASC_SP ;set AL to ASCII space
LEA DI,b$INBUF[BX] ;get address of allocation
MOV CX,DX ;get count of bytes allocated
REP STOSB ;put ASCII spaces in them
; update end-of-line pointer
ADD EOLPTR,DX ;add number of new bytes
; signal successful insertion
ALCBY2:
CLC ;carry cleared for success
; done - restore registers and return
ALCBY3:
POP DI ;restore registers
POP SI
POP CX
POP AX
RET ;and return to caller
;********************************************************************
; BLKKAN - change KANJI bytes to ASCII spaces if their
; partners are being modified. (KANJI only)
;********************************************************************
; entry - BX - b$INBUF index of start of modification
; CX - size of string modification
;********************************************************************
; PUTCHR - put new character(s) into b$INBUF
;********************************************************************
; entry - BX - b$INBUF pointer to start of insertion
; CX - number of bytes to insert
; SI - pointer to string being inserted
; CSRPTR - b$INBUF pointer to cursor
; EOLPTR - b$INBUF pointer to end-of-line
; exit - CSRPTR - updated b$INBUF pointer to cursor
PUTCHR:
PUSH SI ;save registers on stack
PUSH DI
; move CX bytes from string SI to b$INBUF indexed at BX
PUSH CX ;save insertion length
LEA DI,b$INBUF[BX] ;get insertion address
REP MOVSB ;put in characters from string at SI
POP CX ;restore insertion length
; adjust CSRPTR for new character(s) inserted
ADD CSRPTR,CX ;move CX bytes to the right
POP DI ;restore registers from stack
POP SI
RET ;and return from stack
;********************************************************************
; DELCSR - delete character positioned at the cursor
;********************************************************************
DELCSR:
PUSH BX ;save register on the stack
CALL SETLOC ;set display columns / UPDPTR
MOV BX,CSRPTR ;get cursor pointer into b$INBUF
CMP BX,EOLPTR ;test if cursor at EOL
JE DELCS1 ;at EOL, do nothing - just return
CALL DELETE ;delete character on cursor
CALL UPDATE ;and update the display
DELCS1:
POP BX ;restore register from stack
RET ;and return to caller
;********************************************************************
; DELLFT - delete character positioned left of the cursor
; if at start of line, delete character at cursor
;********************************************************************
DELLFT:
PUSH BX ;save register on the stack
CALL SETLOC ;set display columns / UPDPTR
MOV BX,CSRPTR ;get cursor pointer into b$INBUF
OR BX,BX ;test if cursor at start of line
JZ DELLF2 ;at start, try to delete at cursor
DEC BX ;move pointer to char before cursor
DEC CSRPTR ;also move cursor back
JMP SHORT DELLF3 ;jump to finish processing
; at line start - delete character at cursor
DELLF2:
CMP BX,EOLPTR ;test if empty line
JE DELLF4 ;if so, then just return
; delete the character and update
DELLF3:
CALL DELETE ;delete character before cursor
CALL UPDATE ;update the display screen
DELLF4:
POP BX ;restore register from stack
RET ;and return to caller
;********************************************************************
; DELETE - delete character at BX and move remaining
; substring to the left to fill in
;********************************************************************
DELETE:
PUSH CX ;save registers on the stack
PUSH DX
PUSH SI
PUSH DI
; If interim character is pending, just output bell and return.
; Cursor is on KANJI2 byte only from DELLFT.
MOV UPDPTR,BX ;update at start of substring
MOV DX,1 ;assume one byte to delete
MOV CX,EOLPTR ;CX will be length - get EOL pointer
SUB CX,BX ;CX=EOL-CSR
INC CX ;CX=EOL-CSR+1 - length of substring
SUB CX,DX ;subtract length of char deleted
LEA DI,b$INBUF[BX] ;get destination pointer
MOV SI,DI ;source is destination...
ADD SI,DX ;plus length of the deleted char
REP MOVSB ;move the substring in b$INBUF
SUB EOLPTR,DX ;move EOL pointer back
POP DI ;restore the registers from stack...
POP SI
POP DX
POP CX
RET ;and return to caller
;********************************************************************
; TRUNC - truncate input line at cursor
;********************************************************************
TRUNC:
PUSH BX ;save register on stack
CALL SETLOC ;set display columns / UPDPTR
MOV BX,CSRPTR ;get cursor b$INBUF index
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -