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

📄 iotty.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;	[DX] == prospective destination char. (cursor) position

	TEST	TEMPFLAG,SCN_CHR ; print char on screen?
	JZ	SCNOTC_XIT	; brif not

;Force CR if char in AX won't fit

	PUSH	AX		; save char
	CALL	B$CHKLASTCOL	; DH past last column of screen?
	JBE	NO_WRAP		; brif not -- no wrap required
	CALL	B$SCNCRLF	; output a CR/LF (updates DX)
NO_WRAP:			
	CALL	B$SCROUT 	; Send char in AX to BIOS at DX posn
	INC	DH		; increment cursor location
	CALL	B$UPDATE_CSR	; update cursor variables, and display
	POP	AX		; restore char

SCNOTC_XIT:

	TEST	TEMPFLAG,LPR_CHR ; Is printer echo wanted?
	JNE	SCNOTLE		; Brif want to echo
SCNOTLE_RETURN:			

	POP	DX		; end of SCNOUT
	POP	AX		;NOTE: caller must push AX ...
	RET			; end of B$TTY_SOUT



REDOUT:

;	Here if char to go to redirected file.  Map and output char to stdout.

	PUSH	BX		;save across next two calls
	CALL	REDMAP		; do redirection mapping
	CALL	PUTSTD		; Put char to stdout (if char exists)
	POP	BX
	JMP	SHORT REDOUT_RETURN    ; Jump back to main code sequence


SCNOTLE:
				;here if want to echo to line printer
	CMP	AX,0FF0DH	;test if code for CR
	JNE	SCNOTLE_NO_CR	;if not, then jump
	XOR	AH,AH		;make one-byte char for printer
SCNOTLE_NO_CR:
	CALL	[b$pLPTECHO]	;Echo to line printer if necessary
	JMP	SHORT SCNOTLE_RETURN	


CTLDP1_1:
				;here if function key display mode
	CMP	AH,1		; Set PSW.C if two byte character
	CMC
	cCALL	B$FKYMAP	; Map function key display character
	JMP	SHORT CTLEDT

CALL_PRTMAP2:
				;here if character in AL is <= 31d

	TEST	b$IOFLAG,F_KDSP ; Test for function key display mode
	JNZ	CTLDP1_1	; BRIF function key display mode

CALL_PRTMAP1:
		;here if we don't have a normal char, i.e., it must be mapped
	TEST	b$IOFLAG,F_EDIT ; Test for Screen Edit mode
	JNZ	CTLPRN		; BRIF edit mode
	CMP	AH,1		; Set PSW.C if one byte character
	CMC			; Set PSW.C if two byte character
	cCALL	B$PRTMAP 	; Map print function/output character codes
CTLEDT: JZ	SCNOTC_XIT	; Ignore this character
				; Print or perform the editor function
CTLPRN:
	CMP	AH,255		; Is it an editor function (&HFF)?
	JE	NOT_CTLDSX	;if so, then jump around
	JMP	CTLDSX		;if not, near jump
NOT_CTLDSX:			
	XOR	AH,AH		; Clear (no longer needed) editor function flag
	CMP	AL,177O		; Delete function?
	JNZ	CTLNDL		; BRIF not DEL
	MOV	AL," "		; DEL code
CTLNDL: CMP	AL,255		;++Compiler ignores 0FFh
	JZ	SCNOTC_XIT	; BRIF "mark line for deletion" - don't print
	CMP	AL," "+1 	; Test for legal function code
	JNB	CTLEND		
	TEST	TEMPFLAG,SCN_CHR; screen char?
	JZ	CTLEND		; brif not -- don't process control char

	PUSH	AX

	; get proper index into FUNTAB -- asumes AL in range [0..31]
	SUB	AL,7		; adjust so ascii [7..13] = [0..6]
	CMP	AL,6		; ascii chars [7..13]?
	JBE	TBL_ADJ		;	brif so -- table entry = [0..6]

	SUB	AL,14		; adjust so ascii [28..31] = [7..10]
	CMP	AL,7		; < ascii char 28?
	JL	CTLIGN		;	brif so -- don't process char
	CMP	AL,10		; ascii chars [28..31]?
	JG	CTLIGN		;	brif not -- don't process char

TBL_ADJ:			

	PUSH	BX
	PUSH	CX

	ADD	AX,AX		; Two bytes per entry
	XCHG	BX,AX		
	MOV	AX,OFFSET CS:CTLDPX
	PUSH	AX		; Put CTLPDX: as return address on stack
	CLC
	JMP	WORD PTR CS:FUNTAB[BX] ; Go do control routine

;All control chars come here after processing
; Update b$CURSOR, display new cursor, restore registers, return

CTLDPX:
	CALL	B$SCNLOC	; update B$CURSOR and display user cursor
	POP	CX
	POP	BX
CTLIGN:				
	POP	AX
CTLEND:	JMP	SCNOTC_XIT	; do not to print this char to screen

;--------------------------------------------------------------------------
;  Control character processing routines.
;  All routines will return to CTLDPX.


;-- END SUBROUTINE SCNOUT

	PAGE

	SUBTTL	Control Character processing
;CONTROL CHARACTER DISPATCH TABLE
;--
;Interpreter supports more control characters than compiler.
;		Dispatch address	Action (compiler ignores some)	[13]
FUNTAB:				
	DW	OFFSET B$BLEEP	; ^G  -  Beep
	DW	0		; unused position
	DW	OFFSET LTAB	; ^I  -  Destructive tab
	DW	OFFSET B$SCNCRLF ; ^J - Linefeed outputs CR/LF.
	DW	OFFSET WHOME	; ^K  -  Home within window
	DW	OFFSET CCLRSN	; ^L  -  Clear window, home cursor
	DW	OFFSET B$SCNCRLF ; ^M - carriage return


	DW	OFFSET WCSADV	; ^\  -  Cursor advance within window
	DW	OFFSET WCSREG	; ^]  -  Cursor regress within window
	DW	OFFSET WCSUP	; ^^  -  Cursor up within window
	DW	OFFSET WCSDWN	; ^_  -  Cursor down within window

;***
;LPTECHO
;Purpose:
;	Echo to the line printer.
;	Added with revision [32].
;Entry:
;	[AX] = character code
;Exit:
;	none
;Modifies:
;	None ([AX-DX] is preserved)
;****
cProc	LPTECHO,<NEAR>,<AX,BX,CX,DX>	; preserve the world
cBegin
EchoAnother:			
	PUSH	AX		;store byte in stack
	MOV	DX,SP		;[DS:DX] points to data to be output
	.ERRE	ID_SSEQDS	;assumes DS=SS
	MOV	BX,0004H	;file handle for stdprn
        MOV     CX,1            ;[CX] = # of bytes to be written
	MOV	AH,40H		;write operation
	INT	21H		;do the write
	POP	AX		;even stack and restore AX
	JNC	LPTECHOExit	;jump if no error on write
	JMP	B$ERR_IOE	;give generic Device I/O Error
LPTECHOExit:
	CMP	AL,ASCCR	; just printed a CR?
	MOV	AL,ASCLF	; Assume so -- then we want a LF, too
	JE	EchoAnother	; brif CR -- add a Line feed
cEnd

;***
; PUTSTD - Put character to redirected standard output.
;
; Purpose:
;	Writes a char to redirected stdout.  If given character is a <cr>, [13]
;	put out an <lf> also, as stdout needs one.  Adjust the redirected  [13]
;	file cursor position (used to do line wrapping) appropriately.	   [13]
;
; Entry:	[BX] = character (or zero)
; Exit:  none
; Modifies:
;	F, AX
;****
PUTSTD:
	OR	BX,BX		; Test to see if character exists
	JZ	PUTSTDX 	; BRIF not

	MOV	AX,BX		; place char in AX as well

	CMP	AX,0AH		; about to output an <lf>?
	je	PUT_CR_FIRST	; brif <lf> to put a <cr> first
PUTSTD2:
	CLC			;PWS.C reset indicates a 1 byte character
	CALL	B$STDPUT 	; Write the character
	MOV	AX,BX		; restore character into AX
	CMP	AL,9		; ASCII code < 9 (HT)?
	JB	INC_CSR 	; brif if so -- increment cursor.
	JE	TAB_CHAR	; brif HT
	CMP	AL,0DH		; <lf>,<vt>,<ff>,<cr> ?
	JE	PUT_LF_TOO	; brif <cr> to put an <lf> too
	JBE	RESET_CSR 	; brif <LF>,<VT>, or <FF>
INC_CSR:
	INC	b$REDCSRX	; increment redirected file cursor
PUTSTDX:			
	RET

PUT_CR_FIRST:			;here if we're about to put out an lf
	MOV	AX,0DH		; output a <cr> first
	CLC			;Writing a single byte
	CALL	B$STDPUT	; write it out
	MOV	AX,0AH		; restore <lf>
	JMP	SHORT PUTSTD2

PUT_LF_TOO:			;here if we've just sent a <cr> to stdout and
				;need to put in an <lf> now
	MOV	AX,0Ah		;put <lf> in AX
	CLC			;Writing a single byte
	CALL	B$STDPUT 	; write it out, and reset cursor position

RESET_CSR:			
	XOR	AX,AX		; reset redirected file cursor to 1 for
	JMP	SHORT TAB_DONE	; <LF>,<VT>,<FF>,<CR>

TAB_CHAR:			; adjust cursor when TAB printed
	MOV	AL,b$REDCSRX	; load redirected file cursor (1-relative)
	ADD	AL,8		; move to next modulo-8 position.
	AND	AL,0F8H		
TAB_DONE:			
	INC	AX		; make it 1-relative
	MOV	b$REDCSRX,AL	; store redirected file cursor
	RET			; and return from PUTSTD



;*** 
; B$CHKLASTCOL -- check for last column on screen.  Added with revision [19]
;
;Purpose:
;	Sets flags according to whether DH is [<,=,>] the last printable
;	screen location.
;
;Entry:
;	DH = 1-relative screen column
;Exit:
;	Flags set as if CMP DH,LAST_POS was done.
;Uses:
;	None
;Preserves:
;	All
;Exceptions:
;	None
;
;******************************************************************************
cProc	B$CHKLASTCOL,<PUBLIC,NEAR>
cBegin
	CMP	b$PTRFIL,0	; Test if TTY (=0) or SCRN: (>0)
	JE	CHK_PHYS	; If TTY then check physical width
	CMP	DH,b$SCRNWIDTH	; Test if over logical (SCRN:) width
	JAE	CHK_EXIT	; Brif if greater than or equal
CHK_PHYS:
	CMP	DH,b$CRTWIDTH	; Check for last physical column
CHK_EXIT:
cEnd


;*** 
; B$UPDATE_CSR -- Update cursor after a screen write.
;			 Added with revision [19]
;
;Purpose:
;	Updates the high-level cursor position, and displays the user
;	cursor at the appropriate place.  If we have just printed into
;	the last column of the screen, the cursor is NOT displayed at
;	the first position of the next line.  Instead, it is backed up
;	on top of the character just written.
;
;Entry:
;	DX = new cursor position
;Exit:
;	b$CURSOR updated
;
;	DX = position at which cursor was displayed
;Uses:
;	None
;Preserves:
;	All
;Exceptions:
;	None
;
;******************************************************************************
cProc	B$UPDATE_CSR,<PUBLIC,NEAR>
cBegin
	MOV	b$CURSOR,DX	; update logical cursor b$CURSOR
	CALL	B$CHKLASTCOL	; past last column?
	JBE	NO_DEC		; brif not
	DEC	DH		; back up one position to display cursor
NO_DEC:
	JMP	B$USRCSR	; Redisplay user cursor and return
cEnd	<nogen>


;***
; CHKCHAR -- Sets fields of DL to facilitate complicated checks.  Added with
;		revision [13].
;
; Purpose:
;    Decide whether a character should be printed on the screen, to the
;    redirected file, and/or to the printer, according to the following chart:
;
;------------------------------------------------------------------------
;		|	|	|	|        INPUT statement	|
; Redirection	| FKEY	| SCRN:	| CONS:	|   with edits	| without edits	|
;---------------|-------|-------|-------|---------------|---------------|
; No redirection|   S	|  S,P	|  S,P	|	S	|      S,P	|
; Red OUT	|  ---	|  S,P	|  F	|	S	|      F,P	|
; Red INP	|   S	|  S,P	|  S,P	|	S	|      S,P	|
; Red INP & OUT	|  ---	|  S,P	|  F	|      ---	|      F	|
;------------------------------------------------------------------------
;
;	S = print char to screen
;	P = print char to printer
;	F = print char to redirected output
;
; Function key display when F_KDSP.
; Printing to SCRN: when b$PTRFIL <> 0.
; INPUT statement with user edits when IN_INPUT.
; INPUT statement without user edits when
;	(F_EDIT and NOT IN_INPUT).
; Printing to CONS: at all other times.
;
;
; Algorithm summary:
;
;   Char should be printed to redirected file (RED_CHR) if:
;	RED_OUT and NOT (SCRN: or IN_INPUT or F_KDSP)
;
;   Character should be printed to the screen (SCN_CHR) if:
;	SCRN: or NOT RED_OUT or (NOT RED_INP and IN_INPUT)
;
;   Character should be echoed to the printer (LPR_CHR) if:
;	LPR_ECHO and NOT F_KDSP and NOT IN_INPUT and
;	(SCRN: or NOT RED_OUT or
;	(RED_OUT and NOT IN_INPUT and F_EDIT))
; Input:
;	b$PTRFIL set correctly.
; Exit:	
;	SCN_CHR, RED_CHR, and LPR_CHR fields of DL set correctly.
; Modifies:
;	DX, F
;****
cProc	CHKCHAR,<NEAR>,<AX>
cBegin

	XOR	DX,DX			; initially all flags are false 
	MOV	AL,b$IOFLAG		; keep b$IOFLAG in AL

	TEST	AL,RED_OUT		; is output redirected?
	JZ	SCN_CHAR		;   brif not -- screen char
	CMP	b$PTRFIL,DX		; Test if TTY (=0) or SCRN: (>0)
	JNZ	SCN_CHAR		;   brif SCRN: -- screen char
	TEST	AL,F_KDSP OR IN_INPUT	; function key display or
					; INPUT statement?
	JNZ	CHK_SCN			;	brif so -- not a redir char
	OR	DL,RED_CHR		; set bit to indicate redir char
	JMP	SHORT CHK_LPR		; skip check for screen char

CHK_SCN:				; RED_OUT = TRUE here
	TEST	AL,RED_INP		; redirected input?
	JNZ	CHK_LPR			; 	brif so -- not screen char
	TEST	AL,IN_INPUT		; INPUT statement?
	JZ	CHK_LPR			; 	brif not -- not screen char
SCN_CHAR:
	OR	DL,SCN_CHR		; set bit to indicate screen char

CHK_LPR:
	TEST	AL,LPR_ECHO		; printer echo wanted?
	JZ	CHKCHAR_EXIT		;	brif not -- not a printer char
	TEST	AL,F_KDSP OR IN_INPUT	; function key display or IN_INPUT?
	JNZ	CHKCHAR_EXIT		;	brif so -- not a printer char
	CMP	b$PTRFIL,0		; Test if TTY (=0) or SCRN: (>0)
	JNZ	LPR_CHAR		;	brif SCRN: -- printer char
	TEST	AL,RED_OUT		; redirected output?
	JZ	LPR_CHAR		;	brif not -- printer char

	AND	AL,RED_INP OR F_EDIT	; redisplaying line and not
	CMP	AL,F_EDIT		; redirected input ?
	JNZ	CHKCHAR_EXIT		; 	brif not -- not a printer char
LPR_CHAR:
	OR	DL,LPR_CHR		; set bit to indicate printer char

CHKCHAR_EXIT:
cEnd


;***
; REDMAP - Map character for redirected std. output file
;
; Purpose:
;	Given a character to be printed to redirected stdout, return
;	the mapped character in BX or 0 character should be ignored.
; Input:
;	[AX] = unmapped control character for screen
; Output:
;	[BX] = mapped char for std output (0 if it should be ignored)
;		may be a 1- or a 2-byte character
; Modifies:
;	F
;****

REDMAP: PUSH	AX
	XOR	BX,BX		;Assume no character for standard output
	CMP	AH,1		;Set PSW.C for two byte character
	CMC
	cCALL	B$PRTMAP 	; Map as if a print statement
	JZ	REDMAX		;No character to print
	MOV	BX,AX		;Assume character will be used as mapped
	JNB	REDMAX		;Print character as mapped
	CMP	AH,255D		;Test for control character
	JNZ	REDMAX		;Must be KANJI or other FK_KANJI
	XOR	BH,BH		;Map to single byte char
REDMAX:
	POP	AX
	RET

	PAGE
	SUBTTL	CONTROL CHARACTER ROUTINES - Beep, form feed, home, backspace, tab.

;***
; B$BEEP - BEEP stmt
;
; Purpose:

⌨️ 快捷键说明

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