📄 cninit.asm
字号:
TITLE CNINIT.ASM - Console I/O Initialization/Termination module
;***
;CNINIT.ASM - Console I/O initialization/termination module
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; This module contains screen and keyboard initialization and termination
; support for the BASIC 3.0 runtime. This module will only be present
; in a user's program when a program contains I/O statements.
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc
;
; Code Segments
;
USESEG <INIT_CODE> ;Initialization
USESEG <CN_TEXT> ;Console I/O
USESEG <RT_TEXT> ;Runtime core
USESEG <ST_TEXT> ;String
USESEG <DV_TEXT>
;
; Data Segments
;
USESEG <_BSS> ;runtime data (uninitialized)
USESEG <_DATA> ;runtime data (initialized)
USESEG <XIB> ; initializer segment
USESEG <XI> ;initializer segment
USESEG <XIE> ; initializer segment
INCLUDE seg.inc
INCLUDE compvect.inc ;component vectors
INCLUDE messages.inc ;messages and associated numbers
INCLUDE files.inc
INCLUDE dc.inc
INCLUDE idmac.inc
INCLUDE const.inc
INITIALIZER B$xCNINI ;put B$xCNINI in initializer list.
SUBTTL Runtime code externals
PAGE
sBegin DV_TEXT
externNP B$NearRet ;for disp vectors in compvect.inc
sEnd DV_TEXT
sBegin RT_TEXT
externNP B$PUTNUM ;print message from message number
sEnd RT_TEXT
sBegin ST_TEXT
sEnd ST_TEXT
sBegin CN_TEXT
externNP B$CLREOL ; clear to end of line
externNP B$LastLine ; clear last line
externNP B$KEYDSP ; display function keys if on
externNP B$KYBINI
externNP B$TTYIN
externNP B$SCNLOC ; update b$CURSOR & displ user csr
externNP B$GETCSRDATA ; get active page cursor position
externNP B$OFFCSR ; display user cursor
externNP B$RESETSCN ; reset screen to entry-time state
externNP B$GWTERM ; OEM's routine
sEnd CN_TEXT
SUBTTL Runtime data definitions for BASIC Console I/O
PAGE
sBegin _DATA
;
; External data
;
externW b$ini_disp ;One time initialization dispatch table
externW b$term_disp ;One time termination dispatch table
externW b$run_disp ;RUN time initialization dispatch table
externW b$shli_disp ;SHELL time initialization dispatch table
externW b$shlt_disp ;SHELL time termination dispatch table
externW b$errnum ;error number - non-zero after error
externB b$Chaining ;non-zero if we are CHAINing.
externB b$IOFLAG ; Misc. IO flags. Defined in GWINI.ASM
externW b$CURSOR ; (1,1)-relative screen cursor
externW b$CurPages ; current active page and visual page
externB b$ActPage ; current active page
sEnd _DATA
sBegin _BSS
;
; Local data
;
staticB ctlcsave,? ;Intial Control C processing state.
sEnd _BSS
SUBTTL Runtime Console I/O Initialization
PAGE
assumes CS,INIT_CODE
sBegin INIT_CODE
;***
;B$xCNINI - Console I/O initializer
;PLM B$xCNINI()
;
;Purpose:
; Initializer for Console I/O component. This routine is called
; by the Crt0 startup before _main is called. It will update the
; indirect dispatch tables for the console I/O routines. This
; insures that the only time that Console I/O is accessed is when
; this module is linked into the user program.
;
;Entry:
; None.
;
;Exit:
; b$ini_disp.CN_IVEC - contains pointer to B$CNINI
; b$term_disp.CN_TVEC - contains pointer to B$CNTERM
; b$run_disp.CN_RVEC - contains pointer to B$CNRUNINI
; b$shli_disp.CN_SIVEC - contains pointer to B$CNKBDSET
; b$shlt_disp.CN_STVEC - contains pointer to B$CNKBDRESET
;
;Uses:
; None.
;
;Exceptions:
; None.
;****
cProc B$xCNINI,<FAR>
cBegin
;
; update "ONE" time initialization dispatch address to B$CNINI
;
MOV WORD PTR [b$ini_disp].CN_IVEC,CN_TEXTOFFSET B$CNINI
;
; update "ONE" time termination dispatch address to B$CNTERM
;
MOV WORD PTR [b$term_disp].CN_TVEC,CN_TEXTOFFSET B$CNTERM
;
; update "RUN" time initialization dispatch address to B$CNRUNINI
;
MOV WORD PTR [b$run_disp].CN_RVEC,CN_TEXTOFFSET B$CNRUNINI
;
; update SHELL "initialization" dispatch address to B$CNKBDSET
;
MOV WORD PTR [b$shli_disp].CN_SIVEC,CN_TEXTOFFSET B$CNKBDSET
;
; update SHELL "termination" dispatch address to B$CNKBDRESET
;
MOV WORD PTR [b$shlt_disp].CN_STVEC,CN_TEXTOFFSET B$CNKBDRESET
cEnd
sEnd INIT_CODE
PAGE
assumes CS,CN_TEXT
sBegin CN_TEXT
;***
;B$CNINI - One time initialization for Console I/O
;void pascal B$CNINI()
;
;Purpose:
; BC3
; ---
; Initializes screen and keyboard for standard character
; I/O. B$CNINI does the following:
; Determines if input and/or output is redirected, and sets
; the appropriate bits in b$IOFLAG.
; Saves high level screen dimensions
; Save initial screen variables (low level)
; DOS 3 specific:
; Save CTL-C state
; Set ignore CTL-C
; Save/Set keyboard interupt vector (low level)
; DOS 5 specific:
; Set ignore ctl-c signal
; Key board key trapping (??)
;
; QB3
; ---
; Same as above. (WHO/HOW does CTL-C get handled for QB3??)
;
;Entry:
; None.
;
;Exit:
;
;Uses:
;
;Exceptions:
;
;****
cProc B$CNINI,<PUBLIC,NEAR>
cBegin
; Get the DOS information for file handles 0 and 1, and set the
; appropriate bit of b$IOFLAG if I/O is redirected.
MOV BX,STDOUT ; start with stdout
MOV CL,RED_OUT ; test for redirected output
REDIR_LOOP: ; loop will only go through twice
; CL = bit mask RED_INP (when BX = stdin) or RED_OUT (when BX = stdout)
MOV AX,C_IOCTL SHL 8 + 0 ; prepare to issue IOCTL(0)
CALLOS ; get device info
TEST DL,FL_CHAR ; is handle a file?
JZ REDIR_IO ; brif so -- redirected
; DX = device information
TEST DL,FL_CONINP OR FL_CONOUT ; console device?
JNZ NO_REDIR_IO ; brif so -- not redirected
REDIR_IO:
OR b$IOFLAG,CL ; set appropriate redir flag
NO_REDIR_IO:
MOV CL,RED_INP ; prepare to check stdin
DEC BX ; for redirected input
JZ REDIR_LOOP ; brif stdin not processed yet
CALL B$CNKBDSET ;initialize the keyboard
CNINIExit:
cEnd
PAGE
;***
;B$CNRUNINI - RUN time console i/o initialization.
;void pascal B$CNRUNINI()
;
;Purpose:
; BC3 - void pascal B$CNRUNINI()
; ---
; B$CNRUNINI does the following:
; Set initial cursor variables (low level)
; Set initial Window boundaries (high and low level)
; Clear screen and home cursors.
; Redisplay function keys if ON.
;
; QB3 - void pascal B$CNRUNINI()
; ---
; Same as above. (How about Function Keys???)
;
;Entry:
; None.
;
;Exit:
; ??
;
;Uses:
; None.
;
;Exceptions:
; None.
;****
cProc B$CNRUNINI,<NEAR>
cBegin
cEnd
PAGE
;***
;B$CNKBDSET - Keyboard Initialization
;void pascal B$CNKBDSET()
;
;Purpose:
; This routine is responsible for initializing the keyboard.
; It gets called during system initializaition, RUN, CHAIN,
; and SHELL.
; BC3
; ---
; Initializes keyboard for standard character I/O.
; DOS 3 specific:
; Save CTL-C state
; Set ignore CTL-C
; Save/Set keyboard interupt vector (low level)
; DOS 5 specific:
; Set ignore ctl-c signal
; Put Keyboard in Binary mode [25]
; Key board key trapping (??)
;
; QB3
; ---
; Same as above. (WHO/HOW does CTL-C get handled for QB3??)
;
;Entry:
; None.
;
;Exit:
; ctlcsave - contains current control c processing state.
;
;Uses:
; None.
;
;Exceptions:
; None.
;
;****
cProc B$CNKBDSET,<NEAR>
cBegin
XOR AL,AL ;Get control c function code
CALLOS CTRLC ;Read control c processing state.
MOV ctlcsave,DL ;save initial control c state.
XOR DL,DL ;turn off control C processing
MOV AL,1 ;Set control c function code
CALLOS CTRLC ;turn off control c processing.
cEnd
SUBTTL Runtime Console I/O termination routines
PAGE
;***
;B$CNKBDRESET - Keyboard Termination
;void pascal B$CNKBDRESET()
;
;Purpose:
; This routine is responsible for resetting the keyboard.
; It gets called during system termination, RUN, CHAIN,
; and SHELL.
; BC3
; ---
; resets keyboard for standard character I/O.
; reset CTL-C state
; reset keyboard interupt vector (low level)
;
;Entry:
; ctlcsave - contains control c processing state upon entry.
;
;Exit:
; None.
;
;Uses:
; None.
;
;Exceptions:
; None.
;
;****
cProc B$CNKBDRESET,<NEAR>
cBegin
MOV DL,ctlcsave ;get initial control c state.
MOV AL,1 ;Set control c function code
CALLOS CTRLC ;reset control c processing.
cEnd
sEnd CN_TEXT
PAGE
assumes CS,CN_TEXT
sBegin CN_TEXT
;***
;B$CNTERM - One time initialization for Console I/O
;void pascal B$CNTERM()
;
;Purpose:
; BC3
; ---
; Initializes screen and keyboard for standard character
; I/O. B$CNTERM does the following:
; Saves high level screen dimensions
; Save initial screen variables (low level)
; DOS 3 specific:
; Save CTL-C state
; Set ignore CTL-C
; Save/Set keyboard interupt vector (low level)
; DOS 5 specific:
; Set ignore ctl-c signal
; Key board key trapping (??)
;
; QB3
; ---
; Same as above. (WHO/HOW does CTL-C get handled for QB3??)
;
;Entry:
; None.
;
;Exit:
;
;Uses:
;
;Exceptions:
;
;****
cProc B$CNTERM,<NEAR>
cBegin
CMP b$errnum,0 ;Has an error occurred?
JZ NOPAUSE ;brif not.
CALL FAR PTR B$Pause ;Yes: display message and wait for char.
NOPAUSE:
CMP b$Chaining,0 ;Are we in the process of chaining?
JNZ Chaining ;brif so.
TEST b$IOFLAG,SCN_INIT ; have we done any output yet?
JZ NoReset ; brif not -- don't reset screen
CALL B$RESETSCN ; reset screen to entry time state
NoReset:
CALL B$GWTERM ; OEM termination
Chaining:
cCall B$CNKBDRESET ;RESET the keyboard
cEnd
;***
;B$Pause - wait until user hits a key to return.
;
;Purpose:
; This module is needed on machines that clear the screen when resetting
; screen mode. The error message would just flash on the screen before
; being erased in B$CNTERM (which calls OEM's B$GWTERM routine).
; Also used when QBI compile dialog spawns processes which have
; errors. The Hit any key message will be displayed before returning
; to the user interface, which will redisplay the editting window.
;
;Entry:
; None.
;
;Exit:
; None.
;
;Uses:
; Per convention.
;
;Exceptions:
; None.
;****
cProc B$Pause,<PUBLIC,FAR>
cBegin
TEST b$IOFLAG,RED_INP+RED_OUT ; input or output redirected?
JNZ PauseExit ; brif so -- do nothing
MOV DX,b$CURSOR ; DX = logical cursor for this page
PUSH DX ; save it for later
MOV AX,b$CurPages ; AX = [visual|active] pages
PUSH AX ; save old page values
CMP AH,AL ; were active and visual pages the same?
JE SamePages ; brif so -- don't read cursor position,
; since it may be wrong.
MOV b$ActPage,AH ; active page = visual page
CALL B$GETCSRDATA ; DX = cursor position for this page
SamePages:
PUSH DX ; save cursor for visual page
CALL B$LastLine ; DX = b$CURSOR = first column of last line
CALL B$CLREOL ; erase last line (cursor left at start)
MOV AX,MS_HITTORETURN ;"Hit any key to return to system"
cCall B$PUTNUM ;print the message
CALL B$KYBINI ; Erase any typeahead
CALL B$TTYIN ; Wait for any key
CALL B$LastLine ; DX = b$CURSOR = first column of last line
CALL B$CLREOL ; erase last line (cursor left at start)
POP DX ; DX = original cursor for visual page
CALL B$OFFCSR ; display off cursor at original location
; on visual page (forces relocation)
POP AX ; restore active page to old value
MOV b$ActPage,AL
POP DX ; DX = old logical cursor for active page
CMP AH,AL ; were active and visual pages the same?
JNE NoDisp ; brif not -- don't display function keys
CALL B$KEYDSP ; display function keys in active page if
; on (clears last line and restores cursor)
NoDisp:
CALL B$SCNLOC ; update b$CURSOR and display user cursor
PauseExit:
cEnd
sEnd CN_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -