📄 llinit.asm
字号:
TITLE LLINIT - GW-BASIC Interface Initialization
;***
; LLINIT.ASM - GW-BASIC Interface Initialization
;
; Copyright <C> 1986, Microsoft Corporation
;
;Purpose:
;
;******************************************************************************
INCLUDE switch.inc ;switch file [new]
INCLUDE rmacros.inc ;useseg macro
USESEG RT_TEXT ;core runtime segment
USESEG _DATA
USESEG CONST
USESEG _BSS
INCLUDE seg.inc ;segment definitions
INCLUDE idmac.inc ;internal debug macros
INCLUDE oscalls.inc ;Dos 5 structures
INCLUDE ibmunv.inc
INCLUDE intmac.inc
INCLUDE const.inc ; b$IOFLAG field definitions.
INCLUDE llgrp.inc ; Constant definitions
INCLUDE baslibma.inc ; SKIP macro
sBegin _DATA
globalW b$pChkOlivetti,B$NearRet ; pointer to routine in lloga.asm
labelW <PUBLIC,b$DSP> ;b$BLDSP and b$WHDSP in one word
globalB b$BLDSP,70H,1 ;encoded attr for fct. key reverse video
globalB b$WHDSP,7,1 ;encoded attr for fct. key reverse video
labelW <PUBLIC,b$InsCsrTyp> ; insert mode cursor (init to 1/2 block)
globalB b$InsCsrStop,7,1 ; cursor stop line (*)
staticB InsCsrStart,4,1 ; cursor start line (*)
labelW <PUBLIC,b$UsrCsrTyp> ; user defined cursor
globalB b$UsrCsrStop,7,1 ; cursor stop line (*)
globalB b$UsrCsrStart,7,1 ; cursor start line (*)
globalW b$OrgCsrTyp,,1 ;startup cursor type
globalW b$OrgScrBst,,1 ;screen BASIC mode and burst at startup
globalB b$OrgBiosMode,,1 ;entry BIOS mode save [23] made public
globalW b$OrgPages,,1 ;active and visual pages at startup
labelW <PUBLIC,b$OrgScrDim> ;screen dimensions at startup in one word
staticB ,,1 ;width
labelB <PUBLIC,b_orglen> ;Interpreter reachable label
globalB b$orglen,25,1 ;height
externB b$IOFLAG ; Misc. IO flags. Defined in GWINI.ASM
externW b$CURSOR ; Screen cursor. Defined in GWDATA.ASM
externW b$CurPages
staticB b$SCNFLAG,0,1 ;screen initialization flags
SCN_RESET = 1 ;screen startup mode change
SCN_GIOINI= 1 ;force SetMode for GIO initialization
sEnd _DATA
sBegin CONST
;translation table to translate from BIOS mode to BASIC screen mode
HSMTBL DB 0,0,0,0,1,1,2,0,3,0,0,0,0,7,8,10,9
DB 11,12,13
sEnd CONST
sBegin _BSS
externB b$ScrWidth
externB b$ScrHeight
externB b$ScreenMode
externB b$BiosMode
globalW b$VGAmodesL,,1 ; flag for VGA BIOS modes 0-F
globalB b$VGAmodesH,,1 ; flag for VGA BIOS modes 10h-13h
staticB VgaMiscInfo,,1 ; miscellaneous VGA-MCGA-PS/2 info
externB b$Burst
externW b$SetMode
externW b$SetPages
externW b$PalReset
globalB b$EgaPalSup,,1 ;EGA palette hardware support flag
externB b$Buf1
labelW Equip ;b$OrgEquip and b$CurEquip in one word
globalB b$OrgEquip,,1 ;startup BiosEquip flags
globalB b$CurEquip,,1 ;current BiosEquip flags
globalW b$KBDVEC_SAVE,,2 ;ROM keyboard vector saved here
globalW b$CLKVEC_SAVE,,2 ;ROM clock vector saved here
globalB b$NetCard,,1 ;boolean indicating if netcard installed
; under DOS 3.xx
; b$NetCard=1 --> netcard installed
; b$NetCard=0 --> not installed
globalB b$DOS_INT_MASK,,1 ;8259 interrupt mask is saved here
;on BASIC entry (IRQ2 set if AT)
globalB b$MACHID,,1 ;machine ID. This byte is set by the
;routine B$GWINI as follows:
; 0FFH if PC
; 0FEH if PC XT
; 0FDH if PC Jr
; 0FCH if PC AT
; or PS/2 model 50 (Centurion)
; or PS/2 model 60 (Skylane)
; 0FAH if PS/2 model 30 (Icarus)
; 0F8H if PS/2 model 80 (Cardinal)
; b$Adapter and b$Monitor must be contiguous
labelB <PUBLIC,b_Adapter> ; Interpreter reachable label
globalB b$Adapter,0,1 ;current graphics adapter; !0 indicates GWINI called
; 00000001 = Monochrome Display Adapter (MDPA)
; 00000010 = Color Graphics Adapter (CGA)
; 00000100 = Enhanced Graphics Adapter (EGA)
; 00001000 = Video Graphics Array (VGA)
; 00010000 = MultiColor Graphics Array (MCGA)
; 00100000 = Hercules Graphics Card (HGC)
; 0100xxx0 = Olivetti Graphics Adapter (OGA)
; The VGA is limited to color modes if an MDPA is found in the machine,
; and limited to monochrome modes if a CGA is found in the machine. If
; the VGA is the only adapter in the machine it can use all modes.
; b$Adapter and b$Monitor must be contiguous
globalB b$Monitor,,1 ;current display monitor
; 00000001 = Monochrome
; 00000010 = Color (or Enhanced emulating color)
; 00000100 = Enhanced Color
; 00001000 = Analog (supporting mono modes)
; 00010000 = Analog (supporting color modes)
globalW b$VideoMem,,1 ;graphics adapter video memory in K
sEnd _BSS
sBegin RT_TEXT
assumes CS,RT_TEXT
externNP B$NearRet
externNP B$VIEWINIT
externNP B$SETSCNDATA ; init the low-level screen variables
externNP B$GRMODE
externNP B$SCROLL
externNP B$GETCSRDATA
externNP B$SCNIO ; used in SCNIOS macro!!!!!
externNP B$FixTextPage
globalD b$OldClkTic,,1 ;label storing the vectors of
;of old interrupt 1CH
globalW b$BASDSG,,1 ;address of BASIC data segment
;***
;B$GWINI - OEM initialization
;OEM-interface routine
;
;Purpose:
; This routine is called once during initialization. It contains
; machine specific code to put the system into a deterministic
; initial state.
;
;Responsibilities:
; After executing this routine, the following items must have
; occurred:
; 1) B$VIEWINIT must have been called.
; 2) B$SCNSWI must have been called.
; 3) The initial screen state must have been saved so that
; screen termination (B$RESETSCN) can restore it.
; 4) if this runtime is for a QB interpreter, B$SCINIT must
; have been called.
; 5) The variables listed in the Exit: section must be set.
;
; B$GWINI should not reset the physical screen. This is done by
; B$SCINIT which is called before any screen activity.
;
; This routine is called FAR.
;
; NOTE: This is one of a pair of OEM-Dependent initialization
; routines. This one deals mainly with Screen and Interrupt
; initialization. See B$RTLLINI for more details.
;
;Entry:
; None.
;
;Exit:
; b$IOFLAG - Set fields SCN_INIT and SCN_SCROLL properly
; b$CurPages - contains initial active and visual pages
; b$CURSOR - contains current cursor position.
; b$ScreenMode - contains current BASIC screen mode
; b$CurPages - contains current visual and active pages
;
; PSW.C is set to indicate an error. The runtime will abort
; with a fatal error condition.
;
;Uses:
; Per convention
;
;Exceptions:
; None
;****
;
;Algorithm:
; get initial screen mode
; store mode for exit
; compute screen length and width
; get current cursor position and type
; save cursor type for exit
; set up the initial cursor rasters
; compute BASIC screen mode and color burst toggle
; call section of SCREEN statement code that initializes
; the screen variables
; clear carry before exiting
;#****
cProc B$GWINI,<PUBLIC,FAR>
cBegin
CMP [b$Adapter],0 ; make sure first time called (mixed lang.)
JZ FirstTime ; brif not
JMP INIRET ; otherwise abort
FirstTime:
and b$IOFLAG,NOT SCN_INIT ;clear screen init flag
PUSH ES
XOR BX,BX
MOV ES,BX
mov al,es:[BiosEquip] ;get the equipment flags
mov ah,al ;copy to AH
mov Equip,ax ;save b$OrgEquip and b$CurEquip values
dec bx ;segment 0FFFFH
MOV ES,BX ;address using the ES register
MOV AL,ES:[000EH] ;get the machine ID in [AL]
MOV b$MACHID,AL ;store it in b$MACHID
POP ES
; If machine is an AT, enable IRQ2. In any case, save the
; current interrupt mask register contents in b$DOS_INT_MASK.
MOV DX,INTA1 ;get interrupt mask register address
CLI ;disable interrupts
IN AL,DX ;get interrupt mask (IRQ7->IRQ0)
CMP b$MACHID,0FCH ;test if machine is AT
JNZ NOT_AT ;jump if not an AT machine
AND AL,NOT 4 ;clear bit 3 (IRQ2) for AT
OUT DX,AL ;and write it out to enable it
NOT_AT:
STI ;re-enable interrupts
MOV b$DOS_INT_MASK,AL ;save as the DOS interrupt mask
CLI ;disable interrupts
;The 3 SAVINTs are required since
;B$SNDOFF and B$GWTERM restore them.
;Interrupts turned on in SNDOFF.
PUSH ES
SAVINT b$KBDVEC_SAVE,KBDVEC ;save INT EF vector
SAVINT b$CLKVEC_SAVE,CLKVEC ;save INT F0 vector
POP ES ;restore segments...
XFRINT KBDVEC/4,KBDINT/4 ;move INT 09H to INT EFH
XFRINT CLKVEC/4,CLKINT/4 ;move INT 04H to INT F0H
PUSH DS ;save DS...
xor ax,ax
mov ds,ax
push es
SAVINT DS:TICSAV,TIMADR ; save get control on timer INT VEC
pop es
pop ds
SCNIOS vGetVideoState ;get current screen mode
mov dl,bh ;let the current active page AND visual
mov dh,bh ; page be the visual page from entry
MOV b$OrgBiosMode,AL ;save inital screen mode
MOV CL,AH ;CL = screen width
CMP AL,40h ; check for Olivetti 640x400 mode
JNE Not40h ; brif not
MOV AL,4 ; BASIC Screen mode 4
JMP SHORT NoBurst ; no burst for Screen 4
Not40h:
MOV AH,AL ;AH = bios mode
MOV BX,OFFSET DGROUP:HSMTBL ;get init scrn mode table offset
XLAT ;AL = screen mode
and ah,1 ;strip bios mode to get color burst
cmp al,1 ;screen 0 or 1?
jbe UseBurst ;go if so, burst is valid
NoBurst:
xor ah,ah ;no burst for other modes
UseBurst:
push ax ;save: screen mode and burst
push dx ; pages
push cx ; width
CALL B$SetAdapter ; Determine display hardware configuration
MOV AL,30h
XOR BX,BX
XOR CX,CX
MOV DX,24 ; default to 25 lines (incremented below)
PUSH ES ; Preserve (it's a return value)
SCNIOS vCharGen
POP ES
INC DX
pop cx
mov ch,dl ;CH = height
pop dx
pop ax
push ax ;save: screen mode and burst
push cx ; width and height
call B$SETSCNDATA ;set up screen data for entry mode
pop cx
pop ax
;The entry mode may not be one supported by our software
;configuration. If something is different than what was
;requested, set a flag so screen initialization will set
;the new mode when the time comes.
cmp al,b$ScreenMode;mode changed?
jne ModeChgd ;go if so
cmp cl,b$ScrWidth ;width?
jne ModeChgd ;go if so
cmp ch,b$ScrHeight ;height?
je NoChange ;go if not
ModeChgd:
OR b$SCNFLAG,SCN_RESET ;set screen reset flag for B$SCINIT
NoChange:
mov al,b$ScreenMode;save entry screen mode
mov ah,b$Burst ; burst
mov b$OrgScrBst,ax
mov ax,b$CurPages ; pages
mov b$OrgPages,ax
mov ax,word ptr [b$ScrWidth] ; width and height in 1 word
mov b$OrgScrDim,ax ;(sets b$orglen)
; If we're in 25 line mode, the cursor start/stop lines vary depending
; on how many scan lines are on the screen. If we're in a mode with
; other than 25 lines, the cursor is from 7 to 7 regardless of scan line
; count.
CMP AH,25 ; 25 line mode?
JNZ Use7_7 ; no, use 7,7 cursor.
CMP b$BiosMode,7 ; is it b/w mode? (indicates 350 scan lines)
JNZ Use7_7 ; no, use default
MOV AX,0C0CH ; b/w cursor raster is 12,12
MOV b$UsrCsrTyp,AX ; save new user cursor
MOV b$InsCsrStop,AL ; save new insert cursor stop line
Use7_7:
CALL B$GETCSRDATA ; load cursor position into DX
; and cursor type into CX
; (updates B$CSRPOS, B$CSRTYP)
mov b$OrgCsrTyp,cx ; save entry cursor type
test b$SCNFLAG,SCN_RESET ;will we reset screen?
jnz HomeCsr ;go if so to home cursor
CALL B$GRMODE ; graphics mode?
JZ NOT_GRAPH ; brif not -- use current cursor location
HomeCsr:
MOV DX,0101h ; use (1,1) as initial high-level cursor
NOT_GRAPH:
CMP DL,b$ScrHeight ; is cursor presently on last line?
JNZ NOT_LST ; brif not
; note: graphics modes will always branch
DEC DX ; we want it on previous line
OR b$IOFLAG,SCN_SCROLL ; signal B$SCINIT to scroll the
; screen before first screen operation.
NOT_LST:
MOV b$CURSOR,DX ; update high-level cursor position
CALL B$VIEWINIT ; initialize viewports and graphics cursor
call B$SCINIT ;initialization. Do it all now to
sti
mov ah,30h ; if dos 3 then if network installed
int 21h ; then do not eat CTRL-ALT-BRK.
cmp al,3 ; version 3 and above
jb not3 ; brif less than 3.xx
xor ah,ah ; netcard installation check
int 2ah
or ah,ah ; [ah] = 0 --> network not installed
jz not3 ; brif network not installed
mov b$NetCard,1 ; else set b$NetCard for use in -cevt
not3:
CLC ;clear carry to indicate no error
INIRET:
cEnd
;
; Added as part of revision [17].
;***
;B$SCINIT -- Initialize the screen.
;OEM-interface routine
;
;Purpose:
;
; This routine exists to delay initialization operations that
; actually effect the screen until such time as it is determined
; that an actual screen operation (text output, graphics, etc.)
; is to take place. Thus a program which does not use the screen
; (such as those doing only file I/O or redirection) will never
; change the screen mode or appearance.
;
; Performs the remaining screen initialization required before a
; screen operation can be done. If bit SCN_INIT of b$IOFLAG is not
; set, it initializes the cursor raster and initializes the palette.
; Scrolls the screen if bit SCN_SCROLL of b$IOFLAG is set. Sets
; bit SCN_INIT of b$IOFLAG to indicate that screen initialization
; has been done.
;
; If running under OS/2, the screen should to be cleared by a
; call to B$CLRSCN with a parameter of 0.
;
; In the OEM code, the following routines must either call B$SCINIT
; or make sure that B$SCINIT has been called.
;
; LLASCN.ASM
;
; B$PCOPYS
;
; LLCSCN.ASM
;
; B$SCREEN, B$SCRSTT, B$SWIDTH, B$SETCLR
;
; LLSCNIO.ASM
;
; B$OFFCSR, B$OVWCSR, B$INSCSR, B$USRCSR
; B$CLRSCN
;
;Entry:
; Bits SCN_INIT and SCN_SCROLL of b$IOFLAG properly set.
;
;Exit:
; Bit SCN_INIT of b$IOFLAG set.
;
;Uses:
; Per convention.
;
;Preserves:
; AX, BX, CX, DX
;
;Exceptions:
; None.
;**********************************************************************
;
; Bit SCN_RESET of b$SCNFLAG may also be set indicating that the
; startup (current) screen mode is unsupported. If so, a new mode
; has already been determined and setup by B$SETSCNDATA (called
; from B$GWINI) and all that remains here is to actually change the
; screen to that mode and set valid page data.
;
; There must be a call to B$SCINIT before each screen operation.
; The following is a list of where each of the calls are, and what
; screen statements they handle:
;
; CIRCLE.ASM:
; B$CIRC: Handles CIRCLE.
;
; DRAW.ASM:
; B$DRAW: Handles DRAW.
;
; GETPUT.ASM:
; B$GGET: Handles GET.
; B$GPUT: Handles PUT.
;
; GRLINE.ASM:
; B$LINE: Handles LINE.
;
; GRPOINT.ASM:
; B$PNI2, B$PNR4: Handles POINT.
; DO_PSET: Handles PSET, PRESET.
;
; GW2GRP.ASM:
; B$VIEW, B$VEW0: Handles VIEW.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -