📄 iotty.asm
字号:
; Runtime Entry Point.
; beep the speaker
; Input:
; NONE
; Output:
; NONE
; Modifies:
; NONE
;****
cProc B$BEEP,<PUBLIC,FAR>
cBegin
cCALL B$BLEEP
cEnd
;Clear the screen
CCLRSN:
MOV AL,2 ; specify text only
CALL B$CLRSCN ; OEM supplied Clear-Screen Routine
CALL [b$vKEYDSP] ; clear or output status line
; fall into WHOME
;***
; WHOME - Home the text cursor [36]
; Public equivalent B$WHOME moved into gwini.asm with revision [36].
; Note: These 2 routines (WHONE & B$WHOME) must be kept in sync!
;
; Input:
; b$WDOTOP set
; Output:
; [DL] == home row of cursor
; [DH] == home column of cursor
; Modifies:
; NONE
;****
WHOME: ; moved public version to gwini.asm
MOV DL,b$WDOTOP
MOV DH,1
SHORT_RET: ; label to jump to for a RET
RET
; LTAB - Destructive TAB to modulo 8 column
LTAB:
MOV AX,OFFSET CODE:LTAB_RET ;push the return address first
PUSH AX ;and then the letter value...
MOV AX,0020h ;Blank out chars
PUSH AX ;NOTE: SCNOUT pops AX, but doesn't push it -
; this is for B$TTY_SOUT speed
JMP SCNOUT ;jump with stack set up
LTAB_RET:
MOV DX,b$CURSOR ; put b$CSRY in DL, b$CSRX in DH
DEC DH ;TAB stops at 8th column, 16th, ...
TEST DH,7
JNZ LTAB ;More spacing to next column
INC DH
RET ;New position set on exit.
PAGE
SUBTTL CONTROL CHARACTER ROUTINES
;***
; B$SCNCRLF -- Output a CR/LF to the screen. Re-written with [19].
;
;Purpose:
; This code is used for either <CR> or <LF>.
; This routine may find that erasing function key line,scrolling
; whole screen and redisplaying function key line, is faster than
; scrolling 1-24.
;
;Entry:
; DX = present cursor position
;
;Exit:
; DX = new cursor position
; Screen possibly scrolled
;Uses:
; None
;Preserves:
; AX,BX,CX
;Exceptions:
; None
;
;******************************************************************************
cProc B$SCNCRLF,<NEAR>
cBegin
CALL B$CRLF ; adjust DX if necessary
JNZ SHORT_RET ; if no need to scroll, just return
JMP B$SCROLL ; scroll screen and return
cEnd <nogen>
PAGE
SUBTTL CONTROL CHARACTER ROUTINES - Function key display and advance
;B$LABELK - If function key display is off then turn on and exit.
; If function key display is on then advance display line and
; redisplay.
;ENTRY - DX = cursor position
;EXIT - None [13]
;USES - None [13]
PUBLIC B$LABELK ;Can be called by $RDLIN directly.
B$LABELK:
NOT b$KEY_SW ; toggle function key display switch
JMP [b$vKEYDSP] ; Display function keys
PAGE
SUBTTL CONTROL CHARACTER ROUTINES - Cursor movement by character and line
; The control character routines are entered with DH=current column and
; DL=current line. They return updated posn in the same registers. They
; can modify AX, BX, CX but must save any other registers used.
;***
; WCSADV, WCSREG, WCSUP, WCSDWN - cursor control
;
; Purpose:
; CURSOR CONTROL
; The cursor control routines allow moving the cursor right (and left)
; with wraparound to following (or previous) line unless it is at the
; very bottom (or top) of the screen. Attempts to move the cursor up
; from the top line of the screen or to move the cursor down from the
; bottom line on the screen are ignored.
;
; Inputs:
; [DL] == current line
; [DH] == current column
; Outputs:
; updated line position in DL
; updated column position in DH
;
; These routines return CF=1 when they do not change the posn.
; Modify:
; AL
;****
;Cursor right within window
WCSADV:
INC DH ; Next column
CALL B$CHKLASTCOL ; past last valid column?
JBE CSRRET ; BRIF Good value
CSRADV_DOWN:
DEC DH
CALL WCSDWN
JB CSRRET ; BRIF can't change physical lines
MOV DH,1 ;First column
CSRRET:
RET ; update position and redisplay cursor
;Cursor left within window(or within physical line if outside window)
WCSREG:
DEC DH ; Previous column
JNZ CSRRET ; BRIF good value (1 or greater)
INC DH ; Restore column
CALL WCSUP
JB CSRRET ; BRIF can't change physical lines
; fall into B$GETLASTCOL
B$GETLASTCOL: ; DH = last column (anybody need this FN?)
MOV DH,BYTE PTR b$CRTWIDTH ; Last column of physical screen
CMP b$PTRFIL,0 ; Test if TTY (=0) or SCRN: (>0)
JE CSRRET ; If TTY, then jump to redisplay cursor
CMP b$SCRNWIDTH,255 ; Check for infinite width
JE CSRRET ; If so, then use b$CRTWIDTH, redisplay
MOV DH,b$SCRNWIDTH ; Else use logical width
RET ; return and redisplay cursor
;Cursor up within window(or NOP if outside window)
WCSUP:
CMP b$WDOBOT,DL
JB CSRRET ; BRIF outside of window
CMP DL,b$WDOTOP
JB CSRRET
STC
JZ CSRRET ; BRIF at top or outside of window
CLC
DEC DX
RET ; return and redisplay cursor
;Cursor down within window(or NOP if outside window)
WCSDWN:
CMP DL,b$WDOTOP
JB CSRRET ; BRIF outside window
CMP b$WDOBOT,DL
JB CSRRET ; BRIF at bottom or outside of window
STC
JZ CSRRET
CLC
INC_DX:
INC DX ; Next line
RET ; return and redisplay cursor
;***
; B$TTY_GPOS, B$SCRN_GPOS - return screen position
;
; Input:
; b$CSRX contains current cursor position on screen
; or b$REDCSRX contains the current redirected file position [13]
; Output:
; [AH] == screen position
; Modifies:
; F
;****
labelNP <PUBLIC,B$TTY_GPOS>
TEST b$IOFLAG,RED_OUT ; redirected output?
MOV AH,b$REDCSRX ; return redirected file position
JNZ GPOS_RET ; brif so -- return redir file cursor
labelNP <PUBLIC,B$SCRN_GPOS>
SCRN_GPOS:
MOV AH,b$CSRX ; return screen cursor position
GPOS_RET:
DEC AH ; return 0-relative value
RET
;***
; B$TTY_GWID, SCRN_GWID - return screen width
;
; Input:
; b$CRTWIDTH contains current tty width
; b$SCRNWIDTH contains current SCRN: width
; Output:
; [AH] == screen width
; Modifies:
; NONE
;****
B$TTY_GWID:
MOV AH,b$CRTWIDTH ; (AH) = physical screen width
RET
SCRN_GWID:
MOV AH,b$SCRNWIDTH ; (AH) = logical screen width
RET
PAGE
;***
; B$TTY_BLKIN - block input
; NOT IMPLENTED --DMA support for BLOAD
; Entry [bx] = offset of destination
; [cx] = maximum number of bytes to read
; [dx] = DS of destination
; [di] -> device number
; [si] -> FDB of file to be loaded
; exit ? (This routine is provided to allow the user
; to trash himself beyond all recognition!
; Exit [bx] = 1 past last byte read
; CF set if EOF encountered
;****
B$TTY_BLKIN: ;fall into B$ERR_FC jump
;***
; B$TTY_BLKOUT - block output
; NOT IMPLEMENTED --DMA support for BSAVE
; Entry [bx] = offset of source
; [cx] = maximum number of bytes to write
; [dx] = DS of source
; [di] = device number
; [si] -> FDB of file to be loaded
; Exit [bx] = 1 past last byte written
; CF set if insufficient space
;****
B$TTY_BLKOUT:
width_error: jmp B$ERR_FC
devio ENDP
;
; Moved here from GWINI with [41]
;
;***
;B$SCNSWD - set screen width (called by WIDTH"scrn:",n)
;
;Purpose:
; Sets the width of the SCRN: device to the specified amount.
;
;Entry:
; DL = new width
;
;Exit
; b$SCRNWIDTH (logical width) set
; physical screen width possibly changed (if 80 or 40 columns specified)
;
;Uses:
; Per convention
;****
cProc B$SCNSWD,<NEAR>
cBegin
XCHG AX,DX ;keep width in AL
DEC AX ;map [1-255] to [0-254]
CMP AX,254 ;in range [0-254]?
JA WIDTH_ERROR ;brif not -- illegal function call error
INC AX ;restore width from entry
CMP AL,255 ;infinite width?
JZ SCNWD2 ;Brif so
SCNWD1:
CMP AL,b$CRTWIDTH ;new width different from physical?
JE SCNWD2 ;brif not
PUSH AX ;save logical width
MOV CL,B$LINCNT ;pass Height in CL
cCALL B$SWIDTH ;Let OEM call B$SCNSWI if legal
;if OEM didn't like it, b$CRTWIDTH unchanged
POP AX ;restore logical width
CMP AL,b$CRTWIDTH ;Test if logical < physical width
JB SCNWD2 ;If so, then use given width
MOV AL,b$CRTWIDTH ;Get physical width
SCNWD2:
MOV b$SCRNWIDTH,AL ;set the SCRN: logical screen width
cEnd
;
;Merged in B$SCNWID from GWINI.ASM
;
;***
;B$WIDT - WIDTH wid,hgt statement
;
;Purpose:
; Runtime Entry Point.
; Set the WIDTH for the screen
;
;Input:
; wid - requested width (-1 if default)
; height - requested height (-1 if default)
;
;Output:
; None
;
;Uses:
; Per Convention
;
;Exceptions:
; NONE
;****
cProc B$WIDT,<PUBLIC,FAR>
parmW wid
parmW height
cBegin
MOV BX,wid ;get width
MOV DX,height ;get height
CMP DX,-1 ;Is height specified?
JNE H_Specified ; Yes:
MOV DL,B$LINCNT ; No: set to full screen
XOR DH,DH
H_Specified:
OR DH,DH ;Height < 256?
JNZ width_error
CMP BX,-1 ; Is Width specified?
JNE W_Specified ; Yes:
MOV BL,b$CRTWIDTH ; No: set to full screen
XOR BH,BH ; Make Hi-Byte zero
W_specified:
OR BH,BH ;Width < 256?
JNZ width_error
CMP BL,b$CRTWIDTH ; Test if physical width changed
JNE SCNWID0 ;Yes:
CMP DL,B$LINCNT ; Has height changed?
JE SCNRET ; wrong jump sense
;Yes: call B$SWIDTH to set $CRTWID if legal.
SCNWID0: ;if either changed, go set hardware.
PUSH CX ;If width has changed, set hardware
PUSH AX
XCHG AX,BX ; pass Width in AL
XCHG CX,DX ; pass Height in CL
CALL B$SWIDTH ;Let OEM call B$SCNSWI if legal
JB WIDTH_ERROR ;OEM didn't like it.
POP AX
POP CX
SCNRET:
cEnd
;***
; B$IfScrnDev - Check if current device printing to screen.
;
; Purpose:
; Used by QB4 to determine if they have to do debug screen swapping.
; Added with [20].
;
; Returns true if the current I/O device is TTY, SCRN:, CONS:,
; or a console I/O DOS file.
;
; Note: This routine MUST preserve ES and CANNOT cause heap movement.
; Entry:
; b$PTRFIL set correctly.
; Exit:
; AX = 0 if no screen output possible
; AX = -1 if screen output possible
; Modifies:
; BX,CX
; Preserves:
; DX,ES
; Exceptions:
; None
;****
cProc B$IfScrnDev,<PUBLIC,FAR>
cBegin
XOR AX,AX ; assume no screen output
MOV BX,b$PTRFIL ; pointer to current file/device
OR BX,BX ; TTY?
JZ ScrnDevice ; brif so -- screen device
MOV CL,[BX].FD_DEVICE ; AX = device number
XOR CH,CH ; clear high byte
JCXZ DiskFile ; brif disk file
CMP CL,DN_SCRN ; SCRN:?
JE ScrnDevice ; brif so -- screen device
CMP CL,DN_CONS ; CONS:?
JE ScrnDevice ; brif so -- screen device
JMP SHORT NoScrnDevice ; otherwise, not a screen device
DiskFile:
TEST [BX].FD_FLAGS,FL_CONOUT+FL_CONINP ; console I/O?
JZ NoScrnDevice ; brif not -- not a screen device
ScrnDevice:
DEC AX ; AX = -1 ==> screen output
NoScrnDevice:
cEnd
sEnd DV_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -