📄 gwio.asm
字号:
TITLE GWIO - Basic I/O and initialization
PAGE 56,132
;***
; GWIO - Basic I/O and initialization
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; This module contains code for doing initialization and termination
; and code for calling the lowest level OEM dependent screen I/O routines.
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc ; Runtime Macro Defintions
USESEG _DATA
USESEG _BSS
USESEG DV_TEXT
useSeg RT_TEXT
INCLUDE seg.inc
INCLUDE baslibma.inc
INCLUDE files.inc
INCLUDE intmac.inc
INCLUDE devdef.inc
INCLUDE addr.inc
INCLUDE event.inc ; functions for $RDevt routines
INCLUDE dc.inc
INCLUDE messages.inc
INCLUDE stack.inc
INCLUDE idmac.inc
.LIST
sBegin _DATA
globalW b$pTEST_CLOSE,B$NearRet
externW b$ERDEVP
externB __osmajor
; initial indirect jumps for no /v, no /d
globalW b$IPOLKEY,B$NearRet
globalW b$fInt24Err,-1 ;On entry, non-zero means IGNORE int24
;on exit from int24, low 15 bits contain
;INT 24 error code.
externB fInt24Error ; flag to COW than an INT 24 occurred.
globalB b$EventFlags,,1
sEnd _DATA
sBegin _BSS
externW b$SOFT_KEYS ;defined in GWDATA.ASM
externW B$SOFT_KEY_LEN ;defined in GWDATA.ASM
externW B$SOFT_KEY_INDEX ;defined in GWDATA.ASM
externW b$ERDEV ;defined in GWDATA.ASM
staticW DIV0_SAVE,,2
staticW OVRF_SAVE,,2
staticW DEVR_SAVE,,2 ;Disk error interrupt save
staticW DERRCD,,1 ; Disk error error code save area
staticW CHAR_SAVE,,1
staticW DCHAR_SAVE,,1
staticB DEVICE,,1
staticB WPRFLG,,1 ;Write Protect Flag for INT 24 hndlr
staticB EXTFLG,,1 ;set if sharing violation
sEnd _BSS
sBegin RT_TEXT
externNP B$GETDS
sEnd RT_TEXT
sBegin DV_TEXT
assumes CS,DV_TEXT
externNP B$BREAK
externNP B$DIV0
externNP B$OVFR
externNP B$ERR_DME
externNP B$ERR_DNR
externNP B$ERR_FWP
externNP B$ERR_IOE
externNP B$ERR_DVF
externNP B$ERR_OTP
externNP B$ERR_DNA
externNP B$ERR_DTO
externNP B$KEYINP ; oem routine
;B$NearRet -- near return
;Called by something that thinks there is event trapping when there isn't any
labelNP <PUBLIC,B$NearRet>
RET ;near RETURN
SUBTTL B$IOINI - MS-DOS special I/O initialization
;***
; B$IOINI - Run-time initialization
;
;Purpose: To install handlers for Divide by zero, Oveflow and I/O interrupts.
;
;Entry:
; None
;Exit:
; None
;Modifies:
; Per Convention
;Exceptions:
; None
;****
cProc B$IOINI,<PUBLIC,NEAR>
cBegin
PUSHF ;save interrupt status
XOR AX,AX ;Clear segment
PUSH DS ;Save DS
PUSH ES ; new savint trashes [es]
CLI ; Turn off interrupts
SAVINT DGROUP:DIV0_SAVE,0
SAVINT DGROUP:OVRF_SAVE,4*4
SAVINT DGROUP:DEVR_SAVE,36D*4
POP ES
MOV AX,CS
MOV DS,AX ; All interrupt vectors point to code segment
ASSUME DS:NOTHING
SETVEC 0,B$DIV0 ; Divide by zero
SETVEC 4,B$OVFR ; Overflow
SETVEC 24h,DEVR_INT ; Fatal Error Abort Address
POP DS ;Restore DS
ASSUME DS:DGROUP
POPF ;restore interrupts
cEnd ; End of B$IOINI
PAGE
SUBTTL DOSIO utility subroutines
;B$KYBINI puts the keyboard device server in an initial state.
; It is called at initialization time and after CTL-C.
; On exit, all registers are preserved.
PUBLIC B$KYBINI
B$KYBINI:
push ax
xor ax,ax
mov [B$SOFT_KEY_LEN],ax ;soft key expansion terminated.
mov [char_save],ax
mov [dchar_save],ax
inc ax ; psw.z reset so keyinp wont wait
kywait: cCall B$KEYINP ; any chars present?
jnz kywait ; read them until none left
pop ax
ret
;***
;B$BREAK_CHK - check for keyboard interrupts (CNTL-BREAK)
;OEM-callback routine
;
;Purpose:
; This routine checks if the user has tried to interrupt
; the program with a CNTL-C. If this has occured, then
; branch to the break handler, else return.
; NOTE: A /D switch to the compiler is required for this
; routine to have any effect.
;
;Entry:
; None.
;
;Exit:
; None.
;
;Uses:
; Per convention.
;
;Preserves:
; AX, BX, CX, DX
;
;Exceptions:
; May not return.
;
;****************************************************************************
labelNP <PUBLIC,B$CHKKYB>
cProc B$BREAK_CHK,<PUBLIC,NEAR>
cBegin
CALL [B$IPOLKEY]
TEST b$EventFlags,CNTLC ; bit CNTLC = 0 if no ^Break
JNZ BREAK ; brif ^Break
cEnd
BREAK:
AND b$EventFlags,NOT CNTLC ; Clear it to avoid recursion
; (for COMM close if output still busy).
JMP B$BREAK ; print Break message and die..
;***
; B$TTYST - TTY status
;
; Inputs:
; None.
; Function:
; Check console for pending character.
; Outputs:
; PSW.Z set if if no char waiting.
; AL = character
; AH = 0 if single byte, NZ if double byte
; char_save and dchar_save have the byte(s) receive by keyinp
; Registers:
; Only AX and F affected.
;****
cProc B$TTYST,<NEAR,PUBLIC>,<DX>
cBegin
cmp [B$SOFT_KEY_LEN],0 ; Processing soft key?
jnz tty_ret ; If so, then have char...
mov ax,[char_save]
or al,al ; Was the pending char already input ?
jnz tty_ret ; Yes, note presence
or sp,sp ; Psw.z reset so keyinp wont wait
cCall B$KEYINP
jz tty_ret ; No char available
mov [char_save],ax ; Save high byte(s)
mov [dchar_save],dx ; Save low bytes (if present)
tty_ret:
cEnd
; Added with revision [47]
; OS/2 support totally rewritten with [49]
;
;***
;B$TTYGetChar - Wait for character from keyboard, using polling
;
;Purpose:
; This routine will Poll the keyboard until a character is
; ready. The character is returned as in B$TTYIN. B$BREAK_CHK
; can be called between the polls by setting DX non-zero.
;
; If OM_DOS5, we can't poll waiting for a keystroke as it
; hogs the CPU. Giving up our time slice between polls does
; not work as the forground process of the current screen
; group has extra priority, so we frequently get the time slice
; back before anyone else can run.
;
; If we do not have a keyboard monitor installed, or we are not
; suspose to do polling, then we go directly to B$TTYIN and ask
; it to wait for a charcter. This is safe, as no keyboard events
; could happen without the keyboard monitor.
;
; If we do have a keyboard monitor, then it will clear the sleep
; semaphore whenever a keystroke is recognized. Thus, we block
; on the sleep semaphore and only check for events/keys when it
; is clear.
;
;Entry:
; DL = 0 : don't call B$BREAK_CHK between checks for a character
; DL != 0 : call B$BREAK_CHK
;
;Exit:
; [AL] Has character if not Scan Code. Zero Flag not set.
; [AH] Has 128D, [AL] has Scan Code; or AX has Kanji char
; [DX] May have OEM's special code, AL=254d if so, exit with NZ,NC
; Z flag set if Scan Code, C flag set if two byte code
;
;Uses:
; AX,DX,Flags
;
;Exceptions:
; None.
;****
cProc B$TTYGetChar,<PUBLIC,NEAR>
cBegin
TryAgain:
CALL B$TTYST ;Is a character available?
JNZ CharReady ;yes, get char and return (Use code in B$TTYIN)
OR DL,DL ;Should we call B$BREAK_CHK
JZ TryAgain ;no, just loop
CALL B$BREAK_CHK ;Check if ^BREAK has been hit
JMP SHORT TryAgain ;try to get the character again
cEnd <nogen>
;***
; B$TTYIN - TTY input
;
; Inputs:
; None.
; Function:
; Get character from console keyboard
; Outputs:
; [AL] Has character if not Scan Code. Zero Flag not set.
; [AH] Has 128D, [AL] has Scan Code; or AX has Kanji char
; [DX] May have OEM's special code, AL=254d if so, exit with NZ,NC
; Z flag set if Scan Code, C flag set if two byte code
;
; Registers:
; Only AX and F affected.
; DX affected too.
;
;Note: this code assumes that the first byte of a
; two byte code will be in the range [80h..0FFh].
;****
cProc B$TTYIN,<NEAR,PUBLIC>
cBegin
CALL B$TTYST ; check for presence of char
jz ttwait ; none present so wait for one
CharReady: ; Common entry point: B$TTYIN/B$TTYGetChar
cmp [B$SOFT_KEY_LEN],0 ; processing soft key?
jnz skey_rd ; if so, return its next char
mov ax,[char_save] ; fetch char read by B$TTYST
mov dx,[dchar_save]
jmp short ttyin2
;Second Entry point for B$TTYGetChar
ttwait: xor ax,ax ; tell keyinp to wait for char
cCall B$KEYINP
jnc ttyx ; PSW.C set if exactly 2 bytes
ttyin2: CMP AH,LOW 128D ;start checking for function key
JNE TTYINX0 ;branch if not function key
CMP AL,LOW 32D ;[AL]=' ' for 1st function key
JB TTYINX
CMP AL,NUM_FKEYS+32D ;see if its a function key
JB SKEY_SET ; go setup and return 1st char
TTYINX:
CMP AH,128D ;Zero flag set if returning Scan Code..
TTYINX0:
CMC ;Carry set if 2 byte.
ttyx:
mov [char_save],0 ; char no longer waiting
cEnd
PAGE
;SKEY_SET - Soft Key detected. Store index into B$SOFT_KEYS
; and return 1st char of Soft Key. SKEY_RD will
; return the rest...
;Entry:
; [AX] Has Scan Code.
;Exit:
; [AL] Has Soft Key char if assigned, else...
; [AH] Has Scan Code if not.
SKEY_SET:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -