📄 dvinit.asm
字号:
TITLE DVINIT.ASM - Device I/O Initialization/Termination module
;***
;DVINIT.ASM - Device I/O initialization/termination module
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
; This module contains Device I/O 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 statements which need
; generalized device I/O.
;
;******************************************************************************
INCLUDE switch.inc
INCLUDE rmacros.inc
;
; Code Segments
;
USESEG <INIT_CODE> ;Initialization
USESEG <DV_TEXT> ;Device I/O
USESEG <OI_TEXT> ;comm/printer I/O
USESEG <RT_TEXT>
;
; Data Segments
;
USESEG <_BSS> ;runtime data (uninitialized)
USESEG <_DATA> ;runtime data (initialized)
USESEG <XIB> ; XIB and XIE must bracket XI!
USESEG <XI> ;initializer segment
USESEG <XIE>
INCLUDE seg.inc
INCLUDE baslibma.inc
INCLUDE devdef.inc
INCLUDE files.inc
INCLUDE nhutil.inc
INCLUDE const.inc
INCLUDE rtps.inc
INCLUDE compvect.inc ;component vectors
INITIALIZER B$xDVINI ;put B$xDVINI in initializer list.
SUBTTL Code Externals
PAGE
sBegin OI_TEXT
externNP B$LPTECHO
sEnd OI_TEXT
sBegin DV_TEXT
externNP B$NearRet ;for disp vectors in compvect.inc
externNP B$CommSave
externNP B$CommRestore
sEnd DV_TEXT
SUBTTL Runtime data definitions for BASIC Device I/O
PAGE
sBegin _BSS
externW b$LPTFDB
externB b$FILMOD ;GLOBAL.INC -
externB b$TTY_BAKCHR ;defined in iotty
sEnd _BSS
sBegin _DATA
;
; external data
;
externW b$pDevTable
externW b$run_disp ;RUN time initialization dispatch table
externW b$pLPTECHO ; conditional vector to B$LPTECHO
externW b$pKYBD_OPEN ; conditional vector to KYBD_OPEN
externW b$pSCRN_OPEN ; conditional vector to SCRN_OPEN
externB b$SCRNWIDTH ; logical width of SCRN:
externW b$pCommSave ; conditional vector to B$CommSave
externW b$pCommRestore ; conditional vector to B$CommRestore
sEnd _DATA
sBegin RT_TEXT
PUBLIC b$devused ; The compiler will generate a reference
b$devused equ 0 ; to b$devused if it decides that a user
; program needs device I/O support. This
; causes dvinit to get drug in.
externNP B$OPEN_DEV
assumes cs,RT_TEXT
; These macros are used to define the dispatch table entry
; equates for the communication and cassette devices. The
; macro is invoked with the device operation (I or C), the device
; type (COM or CAS), and the number of devices (NUM_RS232 or
; NUM_CASS).
DevDspEquates MACRO Dop,Dtype,Dnum
Dindex = 0 ;;value to pass to item generation macro
REPT Dnum ;;one item for each device defined
Dindex = Dindex + 1 ;;update the counter
DevItem Dop,Dtype,%Dindex ;;define item with op (I or C), type (COM
;;or CAS), and counter
ENDM
ENDM ;;DevDspEquates
DevItem MACRO Dop,Dtype,Dindex
externNP B$&Dop&_&Dtype&Dindex ;;define ext (e.g., externNP $I_COM3)
Dop&_&Dtype&Dindex EQU B$&Dop&_&Dtype&Dindex ;;define the equate...
;;(e.g., I_COM3 EQU $I_COM3)
ENDM ;;DevItem
; Device initialization dispatch address generator
DEVMAC MACRO ARG
DW I_&ARG
ENDM
; Define the equates in the form "I_CASx EQU B$I_CASx".
DevDspEquates I,CAS,NUM_CASS
; Define the equates in the form "I_COMx EQU B$I_COMx".
DevDspEquates I,COM,NUM_RS232
INIDEV_TABLE LABEL WORD
DEVNAM ;Device initialization addresses
INIDEV_END LABEL WORD ;End of table
iniwid= 80 ;Initial printer width
sEnd RT_TEXT
SUBTTL Runtime Device I/O Initialization
PAGE
assumes CS,INIT_CODE
sBegin INIT_CODE
;***
;B$xDVINI - Device I/O initializer
;PLM B$xDVINI()
;
;Purpose:
; Initializer for Device I/O component. This routine is called
; by the Crt0 startup before _main is called. It will update the
; indirect dispatch tables for the Device I/O routines. This
; insures that the only time that Device I/O is accessed is when
; this module is linked into the user program.
;
;Entry:
; None.
;
;Exit:
; b$run_disp.DV_RVEC - contains pointer to B$INIDEV
;
;Uses:
; None.
;
;Exceptions:
; None.
;****
cProc B$xDVINI,<FAR>
cBegin
;
; update "RUN" time initialization dispatch address to B$INIDEV
;
MOV WORD PTR [b$run_disp].DV_RVEC,DV_TEXTOFFSET B$INIDEV
;
; initialize granularity dispatchers.
MOV b$pLPTECHO, OI_TEXTOFFSET B$LPTECHO ; Set vector to point
; to real routine
MOV b$pKYBD_OPEN, DV_TEXTOFFSET KYBD_OPEN ; Set vector to point
; to real routine
MOV b$pSCRN_OPEN, DV_TEXTOFFSET SCRN_OPEN ; Set vector to point
; to real routine
MOV b$pDevTable, DV_TEXTOFFSET DevTable ; Set vector to point
; to full table
MOV b$pCommSave, DV_TEXTOFFSET B$CommSave ; Set vector to point
; to real routine
MOV b$pCommRestore,DV_TEXTOFFSET B$CommRestore ; Set vector to
; real routine
cEnd
sEnd INIT_CODE
SUBTTL RUN time initialization for device independent I/O
PAGE
assumes CS,DV_TEXT
sBegin DV_TEXT
SUBTTL Device Dispatch Routines
PAGE
;***
; B$INIDEV - Device initialization dispatcher
;
; This routine calls initialization routines for each device
; in the device table.
;****
cProc B$INIDEV,<NEAR>,<BX,DI>
cBegin
MOV BX,OFFSET INIDEV_TABLE-2 ;Adjust for no disk entry
MOV DI,LAST_DEVICE_OFFSET-2 ;Use actual offset of last device
devlp: PUSH BX
PUSH DI
CALL WORD PTR CS:[BX+DI] ;Dispatch to device routine
POP DI
POP BX
DEC DI
DEC DI
JNZ devlp ;Loop until device offset = 0
cEnd
PAGE
;----- Device Action Routines ---------------------------------------------
; These routines are always called from special device dispatchers.
; The registers are set up as follows:
; (DI) = device offset
; The remaining registers are used to pass parameters.
devio PROC NEAR
; Device initialization routines
; Device control blocks are initialized in data segment.
; ENTRY (DI) = Device offset
; USES any but DI
I_LPT1:
MOV b$LPTFDB.FD_MODE,MD_SQO ; Initialize LPRINT file data block
MOV b$LPTFDB.FD_DEVICE,DN_LPT1
MOV b$LPTFDB.FD_WIDTH,iniwid
I_LPT2: ;no special initialization (at Basic Start-up)
I_LPT3:
I_LPT4:
I_KYBD:
I_SCRN:
I_CONS:
I_PIPE:
RET ; just return
; Device close routines
; ENTRY (DI) = Device offset
; USES any but DI
KYBD_OPEN:
XOR DL,DL ; DL = width
MOV BYTE PTR [b$TTY_BAKCHR],DL ; Clear keyboard backup flag/char
MOV AH,MD_SQI ;Valid open modes
JMP B$OPEN_DEV ; allocate FDB with no buffer
;***
; SCRN_OPEN - open the SCRN: device as a file. Re-written as part of [16].
;
; Purpose:
; Create an Fdb associated with a given file number for the screen
; Allows SCRN: to be opened as either OUTPUT or RANDOM.
; Input:
; [AL] == file device (?)
; [BX] == file #
; Output:
; (ES:)[SI] = *FDB
; Modifies:
; AX,DX
;****
SCRN_OPEN:
MOV DL,[b$SCRNWIDTH] ;(DL) = width
MOV AH,MD_SQO+MD_RND ;Set legal modes
CALL B$OPEN_DEV ; allocate FDB with no buffer
FDB_PTR ES,SI,SI ;(ES:)[SI] = *FDB
MOV b$FILMOD,MD_SQO ;Force sequential output
MOV FileDB.FD_MODE,MD_SQO ;Force sequential output
RET
DEVIO ENDP
SUBTTL device table & device dispatch routine
page
;***
;DevTable -- contains address of all individual device dispatch tables
;
;Purpose:
; It contains address of all individual device dispatch tables. The
; procedure of I/O dispatching is first to get the address of
; individual device table from here (DevTable) by refering the
; device number (major #, formed by DN_<device>), and second, to
; dispatch to the address of desired I/O function from individual
; device table by refering the function number (minor #, formed by
; DV_<func>).
;
; Each individual device dispatch table has the name formed by the
; prefix $D_ and the device name, e.g. B$D_DISK.
;
; Each entry in the DevTable is associated with one device number
; (major #), which has the symbolic name formed by the prefix DN_ and
; the device name, e.g. DN_KYBD is the device number for keyboard and
; its value is -1.
;
; The following table contains names of each individual device table,
; the associated symbols of device numbers and values, and the module
; they reside. DevTable is acutally the first column of the
; following table.
; _________________________________________________
; | B$D_DISK | DN_DISK | 0 | iodisk |
; |----------|---------|-----|--------------------|
; | B$D_KYBD | DN_KYBD | - 1 | iotty |
; |----------|---------|-----|--------------------|
; | B$D_SCRN | DN_SCRN | - 2 | iotty |
; |----------|---------|-----|--------------------|
; | B$D_CONS | DN_CONS | - 3 | iocons |
; |----------|---------|-----|--------------------|
; | $D_CAS1 | DN_CAS1 | - 4 | gwcass |
; \..........|.........|.....|....................\
; | $D_CAS4 | DN_CAS4 | - 7 | gwcass |
; |----------|---------|-----|--------------------|
; | B$D_COM1 | DN_COM1 | - 8 | gwcom |
; \..........|.........|.....|....................\
; | $D_COM8 | DN_COM8 | -15 | gwcom |
; |----------|---------|-----|--------------------|
; | B$D_LPT1 | DN_LPT1 | -16 | iolpt |
; \..........|.........|.....|....................\
; | B$D_LPT4 | DN_LPT4 | -19 | iolpt |
; |__________|_________|_____|____________________|
; * the number of CAS, COM & LPT may vary.
;
;-------
;Individual device dispatch table ($D_<device name>):
;-------
; Each device dispatch table, which is similar to one column of the
; following table, contains addresses of all routines (I/O functions)
; performing special device functions. Each entry in the device
; dispatch table is associated with one function number (minor #,
; actually the offset to that table), which has the symbolic name
; formed by the prefix DV_ and the function name, e.g. DV_CLOSE (=6).
;
; All dispatching routines have the name formed by
; <DeviceName>_<FunctionName>, e.g. DISK_OPEN is the routine which opens
; the disk file, and COM_CLOSE is the one which closes COM port.
;
; The following table shows:
; (1) the functions for each device (in the first column), and
; (2) the actual working routines for I/O functions of KYBD, SCRN, CONS
; and LPT. (The symbolic name of each routine is still formed as
; usual, but there doesn't have actual code for that label. Each
; label is defined by EQU to the actual working routine. For
; example, label KYBD_EOF is defined by KYBD_EOF EQU B$ERR_FC.)
; DISK & COM don't have equates.
; ______________________________________________________________
; | func | KYBD | SCRN | CONS | LPT |
; |________|____________|____________|____________|____________|
; | EOF | B$ERR_FC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | LOC | B$ERR_FC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | LOF | B$ERR_FC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | CLOSE | B$LHDALC | B$LHDALC | B$LHDALC | B$LPTCLOSE |
; |--------|------------|------------|------------|------------|
; | WIDTH | B$ERR_FC | $SCRNWID | | |
; |--------|------------|------------|------------|------------|
; | RANDIO | B$ERR_FC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | OPEN | | | | |
; |--------|------------|------------|------------|------------|
; | BAKC | B$TTY_BAKC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | SINP | B$TTY_SINP | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | SOUT | B$ERR_FC | B$TTY_SOUT | | B$LPTOUT |
; |--------|------------|------------|------------|------------|
; | GPOS | B$ERR_FC | B$TTY_GPOS | | |
; |--------|------------|------------|------------|------------|
; | GWID | B$ERR_FC | B$TTY_GWID | | |
; |--------|------------|------------|------------|------------|
; | BLKIN | B$ERR_FC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |--------|------------|------------|------------|------------|
; | BLKOUT | B$ERR_FC | B$ERR_FC | B$ERR_BFM | B$ERR_FC |
; |________|____________|____________|____________|____________|
;
; The following table shows where the routines reside.
; _________________________________
; | DISK_xxxx | dkio.asm |
; |---------------|---------------|
; | KYBD_xxxx | iotty.asm |
; |---------------|---------------|
; | SCRN_xxxx | iotty.asm |
; |---------------|---------------|
; | CON_xxxx | iocons.asm |
; |---------------|---------------|
; | CAS_xxxx | gwcass.asm |
; |---------------|---------------|
; | COM_xxxx | gwcom.asm |
; |---------------|---------------|
; | LPT_xxxx | iolpt.asm |
; |_______________|_______________|
;
;*******************************************************************************
page
;***
;DevTable -- device dispatch table
;
;Purpose:
; Device dispatch table, which is generated by macros DEVMAC & DEVNAM,
; is used to select the individual device dispatch table.
; Note: DEVMAC redefins DEVMAC in devdef.inc.
; DEVNAM is defined in devdef.inc
;Entry:
; none
;Exit:
; DevTable is set up
;Uses:
; none
;*******************************************************************************
DEVMAC MACRO DeviceName
EXTRN B$D_&DeviceName:NEAR ;;all entries are externals
DW B$D_&DeviceName ;;each entry is the address of
;; individual device table
ENDM
labelW DevTable ;device table
DW EndOfDevTable-DevTable-2 ; count of bytes in table (not
; including count word)
DEVMAC DISK ;Disks are treated as device type 0
DEVNAM ;Rest of devices
EndOfDevTable: ; label for count calculation
sEnd DV_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -