⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gwlin.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	TITLE	GWLIN - read and edit line from keyboard
;***
; GWLIN - read and edit line from keyboard
;
;	Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
;******************************************************************************
;
;	* entry point: B$RDLIN
;
;	* returns string in b$Buf1
;	  * byte vector up to length of 255
;	  * zero-byte terminated
;
;	* both ASCII and KANJI versions on switch FK_KANJI
;
;-------------------------------------------------------------------
;
;	Data structures used:
;
;	* b$INBUF - byte vector of length 256
;	  * contains ASCII/KANJI values of present state
;	    of string entered
;	  * end-of-line (EOL) indication is 0 value
;
;	* XBLTAB - word vector of length 8 (KANJI only)
;	  * entries, if any, defined up to index XBLNXT
;	  * entry contains b$INBUF location of KANJI character
;	    where an extra blank had to be inserted on the
;	    display screen to prevent splitting the KANJI
;	    character across rows.
;
;------------------------------------------------------------------
;
;	Editting functions supported:
;
;	* ^B  - move cursor back one word
;	* ^C  - exit program
;	* ^E  - truncate line at cursor
;	* ^F -	move cursor forward one word
;	* ^H  - delete character left of cursor
;	* ^I  - insert/overwrite to next tab field of length 8
;	* ^K  - move cursor to beginning of line
;	* ^M  - (carriage return) return string to program
;	* ^N  - move cursor to end of line
;	* ^R  - toggle between insertion and overwriting
;	* ^T  - toggle function key label display
;	* ^U  - erase line
;	* ^\  - (left cursor) move cursor left once
;	* ^]  - (right cursor) move cursor right once
;	* DEL - delete character over cursor
;==================================================================
				;      ASCII character definitions

	CTL_B=002D		;^B - control B
	CTL_C=003D		;^C - control C
	CTL_E=005D		;^E - control E
	CTL_F=006D		;^F - control F
	CTL_G=007D		;^G - control G (BELL)
	CTL_H=008D		;^H - control H (backspace)
	CTL_I=009D		;^I - control I (TAB)
	CTL_J=010D		;^J - control J (line feed)
	CTL_K=011D		;^K - control K
	CTL_M=013D		;^M - control M (carriage return)
	CTL_N=014D		;^N - control N
	CTL_R=018D		;^R - control R (insert map)
	CTL_T=020D		;^T - control T
	CTL_U=021D		;^U - control U (ESC map)
	CTL_BS=028D		;^\ - control \ (right arrow map)
	CTL_RB=029D		;^] - control ] (left arrow map)

	ASC_SP=032D		;ASCII space
	ASC_DL=127D		;ASCII DEL (delete map)

; Standard MS Keyboard codes (have FF as high byte)

	CNTL=0FFh		; Must be sent in front of control chars

;	other definitions

	.XLIST
	INCLUDE switch.inc	
	INCLUDE rmacros.inc	

	USESEG	_DATA		
	USESEG	CONST		
	USESEG	_BSS		
	USESEG	CN_TEXT 	

	INCLUDE seg.inc 	
	INCLUDE dc.inc
	INCLUDE messages.inc	; MS message
	INCLUDE const.inc	
	.LIST

	BUFLEN=255D		;length of b$INBUF

	.SALL			;suppress macro expansion

sBegin	_DATA			

	externW	b$CRTWIDTH	; width of display screen
	externW	b$CURSOR	; (1,1)-relative screen cursor
	externB	b$IOFLAG	; Misc. IO flags.  Defined in GWINI.ASM

sEnd	_DATA			

sBegin	CONST			

	globalB	b$EightSpaces,' ',8 ; string of eight spaces (for TAB)

sEnd	CONST			

sBegin	_BSS			

	externB b$Buf1		; defined in GWINI.ASM
	b$INBUF EQU b$Buf1	; (use b$Buf1 and b$Buf2)

	staticW CSRPTR,,1	;b$INBUF index to input cursor
	staticW EOLPTR,,1	;b$INBUF index to input end-of-line
	staticW UPDPTR,,1	;b$INBUF index to start of update
	staticW CSRLOC,,1	;display column of cursor
	staticW EOLLOC,,1	;display column of end-of-line
	staticB INSFLG,,1	;0=overwrite mode, 0FFH=insert mode
	staticB ENDFLG,,1	;0=process another char, 0FFH=done
	INPLEN=16D		;length of input string for insert
	externB b$Buf3		; defined in GWINI.ASM
INPSTR	EQU	b$Buf3		; string of bytes for character insert


sEnd	_BSS			

sBegin	CN_TEXT 		
	assumes CS,CN_TEXT	

	externNP B$TTYGetChar	; Wait for keyboard character, checking for
				; ^BREAK
	externNP B$TTYST	;determines if character input pending
	externNP B$BREAK	
	externNP B$TTY_SOUT	;output character in AL to screen
	externNP B$STDGET	; input char from keyboard or redir input
	externNP B$ERR_RPE	; INPUT PAST END error
	externNP B$BREAK_CHK	;check for break character entered
	externNP B$SCRN_GPOS	; get screen cursor position
	externNP B$SCNLOC	; update cursor position and variables
	externNP B$EDTMAP	;OEM mapping for keyboard characters
	externNP B$LABELK	;toggle function label display
	externNP B$OFFCSR	; off cursor
	externNP B$INSCSR	; insert mode cursor
	externNP B$OVWCSR	; overwrite mode cursor
	externNP B$USRCSR	; user cursor
	externNP B$BLEEP	; sound bell on display

;	TABLE macro to define entries in CTLTAB

TABLE	MACRO	FCODE,FADDR
	DB	FCODE
	DW	FADDR
	ENDM	TABLE

;	CTLTAB definition for control character processing

CTLTAB:
	TABLE	CTL_B,BAKWRD	;move cursor backward one word
	TABLE	CTL_C,BREAK	;exit from BASCOM program
	TABLE	CTL_E,TRUNC	;truncate input line at cursor
	TABLE	CTL_F,FORWRD	;move cursor forward one word
	TABLE	CTL_J,IGNORE	; process LF (follows CR in redirected input)
	TABLE	CTL_K,BEGIN	;move cursor to line beginning
	TABLE	CTL_M,ENDLIN	;process CR to end line input
	TABLE	CTL_N,APPEND	;move cursor to end of input line
	TABLE	CTL_U,ERASE	;erase entire input line
	TABLE	CTL_BS,CSRRGT	;move cursor once to the right
	TABLE	CTL_RB,CSRLFT	;move cursor once to the left

;	the above functions set INSFLG=0

CTLINS:
	TABLE	CTL_H,DELLFT	;delete character left of cursor
	TABLE	CTL_I,TABCHR	;process TAB printing character
	TABLE	CTL_R,TOGINS	;toggle insert/overwrite mode
	TABLE	CTL_T,B$LABELK	;toggle key label display
	TABLE	ASC_DL,DELCSR	;delete character on cursor
CTLEND: 			;end of CTLTAB


	page
;*** 
; B$RDLIN -- Read a line of input.
;
;Purpose:
;
;Entry:
;	Caller should hold (and subsequently release) b$Buf1 & b$Buf2
;Exit:
;	b$Buf1 (+ b$Buf2) contains the data input.
;Uses:
;	None
;Preserves:
;	All
;Exceptions:
;
;******************************************************************************

cProc	B$RDLIN,<NEAR,PUBLIC>,<AX,BX,CX,DX,ES>	
cBegin				


;	initialization

	PUSH	DS		; set ES=DS
	POP	ES		

	XOR	BX,BX		;clear BX for use as zero

	MOV	CSRPTR,BX	;cursor at start of input line
	MOV	EOLPTR,BX	;input line starts out null

	MOV	INSFLG,BL	;start with overwrite mode
	MOV	ENDFLG,BL	;input line is starting, not ending

	MOV	b$INBUF,BL	;clear EOL position of b$INBUF

	OR	b$IOFLAG,(F_EDIT OR IN_INPUT) ; Disable $PRTMAP
				; and tell B$TTY_SOUT not to echo to stdout
				; until final dump of edited buffer.

	CALL	FRCLIN		;force new line if cursor stuck
	CALL	OFFCSR		;turn off cursor

;********************************************************************
;	start of main program loop
;********************************************************************

;	get next keyboard character
;	  if PSW.Z=1, then ignore the character
;	  if PSW.C=0, then character is ASCII in AL

NXTCHR:

	; Update the state of the BIOS Insert bit to correspond to
	; the current state of our Insert flag.  This allows programs
	; that depend on this bit (i.e. screen readers for the blind)
	; to work properly.

	push	es
	push	ax
	push	bx

	xor	bx, bx
	mov	es, bx		;prepare ES for accessing BIOS
	cli			;No interrupts while munging Keyboard flags
	mov	al, es:[417h]	;get current shift states
	and	al, 7fh 	;assume insert mode off
	cmp	INSFLG, bl	;is insert mode off
	je	@F		;brif so, assumption correct
	or	al, 80h 	;otherwise, set insert mode on
@@:
	mov	es:[417h], al	;tell the BIOS of the change
	sti			;allow interrupts again.

	pop	bx		;Restore previous registers
	pop	ax
	pop	es


	CALL	FRCSTR		;force output if no char pending
	CALL	GETCHR		;get the next character
	JNZ	NXTCH1		;jump if input is legal
	CALL	BADCHR		;process illegal character
	JMP	SHORT NXTCHR	;and try for the next character

;	if one-byte character, process as ASCII printing code

NXTCH1:
	JC	NXTCH2		;jump if two-byte character
NXTCH1A:
	CALL	ASCCHR		;process as ASCII if carry clear
	JMP	SHORT NXTCHR	;and process the next character

;	two-byte character - test for function key code

NXTCH2:
	CMP	AH,080H 	;test if function key code
	JNE	NXTCH3		;if not, then jump
	CMP	AL,080H 	;test for 8080H -> 80H byte
	JE	NXTCH1A 	;if so, then just print it
	CALL	FKYCHR		;process function key
	JMP	SHORT NXTCHR	;and process the next character

;	test for control character code

NXTCH3:
	CMP	AH,0FFH 	;test if control character
	JNE	NXTCHR		; brif not -- process next char
	CMP	AL,010H 	;test for FF10H -> FEH
	JNE	NXTCH3A 	;if not, then jump
	MOV	AL,0FEH 	;force in mapped character
	JMP	SHORT NXTCH1A	;jump to print character
NXTCH3A:
	CMP	AL,0FFH 	;test for FFFFH -> FFH
	JE	NXTCH1A 	;if so, then print character
	CALL	CTLCHR		;process control character in AL

;	test if input line is finished - if so, leave module

	TEST	ENDFLG,0FFH	;test if input line has ended
	JNZ	RDEXIT		;if so, jump to exit the module
	JMP	SHORT NXTCHR	;jump to process the next char


RDEXIT:
	CALL	USRCSR		;turn on user cursor


cEnd				; restore registers and return to caller

	page


;********************************************************************
;	GETCHR - get keyboard character - remove 3-byte codes
;********************************************************************
; Note that the interpreter does character mapping on ouput only.
; Either B$EDTMAP and $PRTMAP is called when a character is printed
; on the screen, depending on whether in edit mode or not.
; The compiler, not having a full screen editor, only needs B$EDTMAP
; during the INPUT statement. So edit character mapping is done on the
; keyboard input, and print mapping is done on screen output. Since
; characters echoed from here have already been mapped, they must not
; be mapped in B$TTY_SOUT also, so F_EDIT [13] is set to nonzero on entry
; to B$RDLIN and cleared on the only three exits through ENDLIN, BREAK,
; and end of redirected IO.


GETCHR:
;   PUSH    DX		    ;save register on the stack

	CALL	ONCSR		;turn on cursor for input
	test	b$IOFLAG,RED_INP ; input redirected?
	jz	noredir
	call	B$STDGET 	; read char from standard input
	jnz	redir

; End of redirected input seen, flush input buffer and exit
	AND	b$IOFLAG,NOT (F_EDIT OR IN_INPUT) ; Re-enable $PRTMAP
				; Exiting INPUT statement
	CALL	APPEND		; move cursor to end of line
	JMP	B$ERR_RPE	; jump to "INPUT PAST END" error

noredir:

	MOV	DL,1		;Check for events while waiting
	CALL	B$TTYGetChar	;get character from keyboard

redir:
	cCALL	B$EDTMAP 	;map to OEM specifications
	PUSHF			;save flags on stack
	CALL	OFFCSR		;turn off cursor

;	if 3-byte code (AL=254D), clear AX to ignore character

	CMP	AL,254D 	;is this a 3-byte code?
	JNE	GETCH1		;if not, then branch
	POPF			;restore flags (and stack)
	XOR	AX,AX		;clear AX to be ignored

;   POP     DX		    ;restore register from stack
	RET			;and return to caller

;	not 3-byte code, just return AX to caller

GETCH1:
	POPF			;restore flags
;   POP     DX		    ;restore register from stack
	RET			;and return to caller

;********************************************************************
;	EDTSTR - edit string in INPSTR into input buffer
;********************************************************************

EDTSTR:
	PUSH	CX		;save registers on stack
	PUSH	SI

	MOV	CX,BX		;get length of INPSTR in bytes
	JCXZ	EDTST1		;if null, then just exit
	MOV	SI,OFFSET DGROUP:INPSTR ;get offset of string
	CALL	PRTCHR		;insert/overwrite string in b$INBUF
	XOR	BX,BX		;done - reset INPSTR pointer
EDTST1:
	POP	SI		;restore registers from stack
	POP	CX
	RET			;return to caller

;********************************************************************
;	ONCSR - turn on appropriate cursor
;********************************************************************

ONCSR:
	TEST	INSFLG,0FFH	;is insert mode active?
	JNZ	INSCSR		; brif so (returns to caller)
	JMP	SHORT OVRCSR	; otherwise, turn on overwrite cursor
				; and return to caller

;********************************************************************
;	OFFCSR - turn off cursor
;	INSCSR - turn on insert cursor (half-height)
;	OVRCSR - turn on overwrite cursor
;	USRCSR - turn on user cursor
;********************************************************************

OFFCSR:
	PUSH	AX		;save register on stack
	MOV	AX,OFFSET CS:B$OFFCSR	; turns off cursor
	JMP	SHORT CHGCSR	;jump to common code
INSCSR:
	PUSH	AX		;save register on stack
	MOV	AX,OFFSET CS:B$INSCSR	; displays insert cursor
	JMP	SHORT CHGCSR	;jump to common code
OVRCSR:
	PUSH	AX		;save register on stack
	MOV	AX,OFFSET CS:B$OVWCSR	; displays overwrite cursor
	JMP	SHORT CHGCSR	;jump to common code
USRCSR:
	PUSH	AX		;save register on stack
	MOV	AX,OFFSET CS:B$USRCSR	; displays user cursor
CHGCSR:
	PUSH	DX		;save register on stack

	MOV	DL,b$IOFLAG	
	AND	DL,RED_INP OR RED_OUT ; redirected input and output?
	CMP	DL,RED_INP OR RED_OUT 
	JZ	NO_CURSOR	; brif so -- don't touch cursor

	MOV	DX,b$CURSOR	; get cursor position
	CALL	AX 		; call appropriate cursor display routine
NO_CURSOR:			

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -