📄 iotty.asm
字号:
TITLE IOTTY - Console driver for BASCOM-86
;***
; IOTTY - Console driver for BASCOM-86
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
; BASIC Syntax mapping to included runtime entry points:
;
; - BEEP Statement:
;
; BEEP
; |
; B$BEEP
;
; - WIDTH Statement:
;
; WIDTH size
; |
; B$WIDT
;
;******************************************************************************
include switch.inc
INCLUDE rmacros.inc ; Runtime Macro Defintions
USESEG _DATA
USESEG _BSS
USESEG DV_TEXT
USESEG OI_TEXT
INCLUDE seg.inc
include baslibma.inc
include devdef.inc
include files.inc
include ascii.inc
INCLUDE const.inc
INCLUDE rtps.inc ; constants shared with QBI
sBegin _DATA
globalW b$pLHDALC_CPCT,Near_Ret,1
globalW b$pKYBD_OPEN,Near_Ret,1
globalW b$pSCRN_OPEN,Near_Ret,1
globalW b$pLPTECHO,LPTECHO,1 ; conditional vector to B$LPTECHO
externW b$CURSOR ; (1,1)-relative screen cursor
externB b$CSRX ; 1-relative x-coordinate cursor
externB b$LINCNT
externB b$WDOTOP
externB b$WDOBOT
externB b$KEY_SW
externW b$vKEYDSP ; vector for indirect call to B$KEYDSP
externB b$CRTWIDTH ; physical width of screen (40 or 80)
externB b$SCRNWIDTH ; logical width of SCRN:
externB b$IOFLAG ; Misc. IO flags. Defined in GWINI.ASM
staticB b$REDCSRX,01h ; 1-relative X-coordinate cursor for
; redirected output.
sEnd _DATA
sBegin _BSS
externW b$PTRFIL ;defined in GOSTOP.ASM
externB b$LPTFDB ; defined in GLOBAL.INC
externB b$FILMOD ; defined in GLOBAL.INC
globalB b$TTY_BAKCHR,?,1 ; <>0 <=> contains pushed char for TTY
staticB TWOBYT,?,1 ; <>0 means it contains the first half of a
; two-byte (not necessarily KANJI) character
staticB TEMPFLAG,?,1 ; temporary flag to store results of
; CHKCHAR
; equates for use with the results of CHKCHAR
SCN_CHR = 01h ; char should be printed on the screen
RED_CHR = 02h ; char should be printed to redirected file
LPR_CHR = 04h ; char should be echoed to line printer
sEnd _BSS
sBegin OI_TEXT
externNP B$ERR_IOE
sEnd OI_TEXT
assumes CS,DV_TEXT
sBegin DV_TEXT
; Run-time entries
PUBLIC B$D_KYBD
PUBLIC B$D_SCRN
PUBLIC B$TTY_BAKC
PUBLIC B$TTY_SINP
PUBLIC B$TTY_SOUT
PUBLIC B$TTY_GWID
PUBLIC B$TTY_BLKIN
PUBLIC B$TTY_BLKOUT
; Run-time externals
externNP B$ERR_FC
externNP B$SWIDTH
externNP B$SCROUT
externNP B$INFMAP ; OEM's mapping routine
externNP B$PRTMAP
externNP B$BLEEP
externNP B$USRCSR ; display user cursor
externNP B$SCNLOC ; update b$CURSOR and display user cursor
externNP B$TTYGetChar
externNP B$CLRSCN ; clear screen
externNP B$CRLF ; update cursor for scrolling
externNP B$FKYMAP
externNP B$SCROLL ; OEM scroll routine
externNP B$STDPUT
; Illegal Device Functions
KYBD_EOF EQU B$ERR_FC
KYBD_LOC EQU B$ERR_FC
KYBD_LOF EQU B$ERR_FC
KYBD_WIDTH EQU B$ERR_FC
KYBD_RANDIO EQU B$ERR_FC
KYBD_SOUT EQU B$ERR_FC
KYBD_GPOS EQU B$ERR_FC
KYBD_GWID EQU B$ERR_FC
KYBD_BLKIN EQU B$ERR_FC
KYBD_BLKOUT EQU B$ERR_FC
KYBD_DWID EQU B$ERR_FC
SCRN_EOF EQU B$ERR_FC
SCRN_LOC EQU B$ERR_FC
SCRN_LOF EQU B$ERR_FC
SCRN_RANDIO EQU B$ERR_FC
SCRN_BAKC EQU B$ERR_FC
SCRN_SINP EQU B$ERR_FC
SCRN_BLKIN EQU B$ERR_FC
SCRN_BLKOUT EQU B$ERR_FC
; Device Close Routines
SCRN_WIDTH EQU B$SCNSWD
SCRN_DWID EQU B$SCNSWD
;
; SCRN_DWID: ; set width for next open
; MOV b$SCRNWIDTH,DL ; set logical screen width
; RET
;
; Device Independent Console Interface
DSPMAC MACRO func
DW SCRN_&func
ENDM
B$D_SCRN:
DSPNAM
DSPMAC MACRO func
DW KYBD_&func
ENDM
B$D_KYBD:
DSPNAM
PAGE
devio PROC NEAR
KYBD_CLOSE:
SCRN_CLOSE:
JMP [b$pLHDALC_CPCT]
KYBD_OPEN:
JMP [b$pKYBD_OPEN]
SCRN_OPEN:
JMP [b$pSCRN_OPEN]
;***
;B$TTY_SINP,KYBD_SINP - Get a byte from the keyboard (non-redirectable)
;
;Purpose:
; Retreive a byte from the keyboard and return it to the user.
; This routine also alows a one character push back though
; the routine B$TTY_BAKC. If a character is not immediately
; ready, this routine will wait until one becomes available.
; There is no echoing of characters.
;
; Note that when supporting double byte characters, the low
; level routines will return two bytes of data. Since this routine
; will only return one byte, the second byte has to be saved. It
; is saved in the backup mechanism, which is extended to hold
; two bytes.
;
;Entry:
; None.
;
;Exit:
; AL = character
; PSW.C = clear (indicates character available)
;
;Uses:
; Per Convention
;
;Preserves:
; BX, CX, DX
;
;Exceptions:
; None.
;****
B$TTY_SINP:
KYBD_SINP:
XOR AL,AL ;Get a zero value
XCHG AL,[b$TTY_BAKCHR] ;Get the value of/zero out BACKUP flag/char
OR AL,AL ;Was there a character pushed back?
JNE NoDblCh ;Yes, return it.
keyin:
PUSH DX ; DX gets 2nd and 3rd of 3 byte codes
XOR DL,DL ;No ^BREAK checking
cCALL B$TTYGetChar ;And get the character
cCALL B$INFMAP ; OEM's mapping routine
POP DX
JZ keyin ; OEM filtered out the key - get the next
jnc NoDblCh ; BRIF not 2 byte char (kanji or scan)
call B$TTY_BAKC ; save second half of 2-byte code
mov al,ah ; Return first half
KYBD_Clr_Ret:
xor ah,ah ; Clear High order byte
NoDblCh:
CLC ;Clear carry
Near_Ret: ;Near return for vectors
RET
;***
;B$TTY_BAKC, KYBD_BAKC - Back up a byte for the keyboard
;
;Purpose:
; Push a single character "back into the keyboard" so that the
; next call to B$TTY_SINP will re-read it. There is room for
; only one byte of data.
;
; The value is stored in the variable [b$TTY_BAKCHR]. If this
; variable has a zero value, there is no character pushed back.
; If it is non-zero, the value is the byte that was pushed back.
;
; If Double Byte Characters are supported, then this routine is
; enhanced to be able to store two bytes of information. This is
; not to store a full character, but to store 1/2 of a character
; gotten from B$TTYIN and 1/2 of a charcter that was pushed back.
; In this case, b$TTY_BAKCHR is a word and has the following possible
; values:
; HIGH BYTE LOW BYTE MEANING
; undef 0 No bytes pushed back
; 0 non 0 One Byte (Low) pushed back
; non 0 non 0 Two Bytes pushed back
; (HI, then LOW)
;
;Entry:
; AL = byte to be saved
;
;Exit:
; None (state variables updated)
;
;Uses:
; Per Convention
;
;Preserves:
; AX, BX, CX, DX
;
;Exceptions:
; None.
;****
B$TTY_BAKC:
KYBD_BAKC:
MOV [b$TTY_BAKCHR],AL ;Save Char (non-zero value indicates char)
RET
SUBTTL B$TTY_SOUT and B$KanjiFlush
PAGE
; Support code for B$TTY_SOUT/SCRN_SOUT - - - code that has been pulled
; out of the "mainstream" code, so typical use of B$TTY_SOUT falls through
; all conditional jumps
SCND_BYTE: ;here if just got second of 2 bytes
;AX = two byte character
MOV TWOBYT,0 ;Clear TWOBYT flag
CMP AL,0FFH ;test if FFFF needs to be mapped
JNE SCNSO3 ;if not, just output both bytes
; AL = FF only if it is FFFF.
XOR AH,AH ;change FFFF to FF for output
JMP SHORT SCNSO3 ;jump to output the one byte
FIRST_BYTE:
;here if have the first byte of a two-byte char
MOV TWOBYT,AL ;save char for next time
POP AX
RET
CR_OUT:
;here if char received is a CR
MOV AH,0FFh ; carriage return is NEVER
JMP SHORT SCNOUT ; graphics character! (Prevents
; infinite recursion in CHWRAP)
SCNSO6:
;here if F_EDIT was non-zero, i.e., in INPUT mode
MOV AH,TWOBYT ;if 2nd of two bytes, first byte was
;0FFh, and was put in TWOBYT
OR AH,AH ;is this the second of two bytes?
JNZ SCND_BYTE ;brif so
CMP AL,255 ;first of two bytes?
JZ FIRST_BYTE ;brif so
JMP SHORT SCNSO3 ;back to mainstream
;***
; B$TTY_SOUT, SCRN_SOUT - send a character to the screen
;
;Purpose:
; Send a char to the screen. Handle 2-byte chars at this level.
; A two byte character is managed by calling this routine twice,
; once with the first byte and once with the second byte. After
; the second call, the two byte character will be processed.
;
; If we do not have FK_KANJI, then the only legal two byte
; characters are FFxx (Screen Editor Function Code) and then only
; if F_EDIT is true. Everything else must be a single byte. Note
; that 0x80 and 0xFE are codes to be printed, not part of multiple
; character sequences.
;
; If we do have FK_KANJI on, then we can also print any two byte
; character that has a first byte that is valid according to
; B$CKDBLC.
;
; Note that any control characters or double byte characters are
; sent through B$PRTMAP before printing. This may introduce
; a Screen Editor Function which will be resolved internally or
; it might indicate that there is no character to be printed.
;
;Input:
; [AL] == character to send to screen
;
;Output:
; NONE
;
;Modifies:
; F
;****
B$TTY_SOUT:
SCRN_SOUT:
PUSH AX
;
;If last char B$TTY_SOUT was called with was the 1st byte of a 2-byte char,
; B$TTY_SOUT saved it in TWOBYT so they will be both output as one 16-bit
; character. If we are not running with FK_KANJI, then the only possible
; 2-byte characters are FFxx (for function codes and special characters).
XOR AH,AH
;if not KANJI, can only be a non-zero value in
;TWOBYT if F_EDIT is TRUE - - - use this to
;reduce code executed in typical case.
TEST b$IOFLAG,F_EDIT ; in INPUT statement?
JNZ SCNSO6 ;brif in INPUT
SCNSO3: ;AH guaranteed 0 if single byte char
CMP AL,ASCCR ; Is this a carriage return?
JZ CR_OUT ; BRIF so
; Fall through into SCNOUT
;***
; SCNOUT - Output character
;
;Purpose:
; Output a character to one or more of three places: the screen, [13]
; redirected stdout, and the line printer. [13]
; For each char processed, checks to see which of the possible [13]
; destinations are to be written to. Handles chars requiring [13]
; mapping (???), and escape sequences. Only updates the screen [13]
; if there is a char to go to the screen. SCNOUT is recursively [13]
; called in order to output a destructive tab to the screen. [13]
;
;Input:
; [AL] == character
; [AH] == 0 if standard character, 0xFF if [AL] == <CR>
; IF FO_REDIRECT , RED_OUT is set if we're going to redirect stdout [13]
; b$PTRFIL == 0 if stdout is tty
; LPR_ECHO is set if we're going to echo to line printer [13]
; NOTE: Expects AX to be on stack, pops it back to AX at end
;
;Output:
; NONE
;
;Modifies:
; F
;****
SCNOUT:
PUSH DX
MOV DL,SCN_CHR ; assume only SCN_CHAR (speed)
TEST b$IOFLAG,RED_OUT OR LPR_ECHO ; Printer echo or redir out?
JZ SAV_FLGS ; brif not -- don't do slow checks
CALL CHKCHAR ; set RED_CHR, SCN_CHR and LPR_CHR flags
SAV_FLGS:
MOV TEMPFLAG,DL ; save flags in TEMPFLAG
MOV DX,b$CURSOR ; put b$CSRY in DL, b$CSRX in DH
TEST TEMPFLAG,RED_CHR ; Is output redirected?
JNZ REDOUT ; BRIF redirection of output
REDOUT_RETURN:
; Do control char logic
; Input:
; [AX] == control character
; [DH] == Current screen column position
; [DL] == Current screen row position
; Jumps to CTLDSX if AX=valid character to output, else
; Jumps to SCNOTC_XIT if AX is undefined, and not to be printed to screen
; Map the given character to a new character. This is where we take
; our internal representation of a character and turn it into something
; useful. If after mapping the character it contains a screen editor
; function implement the function at this point.
;
; Note that if we are in the screen editor (GWLIN.ASM), we have already
; done the mapping (using EDTMAP instead of PRTMAP). We know to avoid
; the mapping because F_EDIT was set in __bIOFLAG.
OR AH,AH ;test if two-byte character
JNZ CALL_PRTMAP1 ;[12] jump to map the character
CMP AL,31 ; is this a CTL character?
JBE CALL_PRTMAP2 ;[12] branch if so
CTLDSX: ; end of CTLDSP
; PUTSCR - Now print the char to the screen
; [AX] == character to put to screen
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -