⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 llinit.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
;	    GWPAL.ASM:
;		B$PAL0, B$PAL2,	Handles PALETTE.
;		B$PALU
;
;	    GWSCR.ASM:
;		B$CSRL:		Handles CSRLIN.  No changes.
;
;	    IOTTY.ASM:
;		B$FPOS:		Handles POS.  No changes.
;
;	    LLASCN:
;		B$PCOPYS:		Handles PCOPY.
;
;	    LLCSCN:
;		B$SCREEN:		Handles SCREEN().
;		B$SCRSTT:		Handles SCREEN.
;		B$SWIDTH:		Handles WIDTH.
;		B$SETCLR:		Handles COLOR.
;
;	    LLSCNIO:
;		B$CSRDSP:		Handles INPUT, LINE INPUT, PRINT,
;						WRITE, LOCATE, KEY, SHELL,
;						VIEW PRINT, TAB, SPC, WINDOW.
;		B$CLRSCN:		Handles CLS.
;		B$SCROUT, B$STRSOUT:	Handles PRINT, WRITE.
;
;	    PAINT.ASM:
;		B$PAIN, B$PNTC:	Handles PAINT.
;
;

cProc	B$SCINIT,<PUBLIC,NEAR>
cBegin
	TEST	b$IOFLAG,SCN_INIT ; init done already?
	JZ	DO_INIT		; brif not -- do it now
INIT_DONE:			; took initialization code out of here
				; so that most calls will fall through
cEnd


cProc	DO_INIT,<NEAR>,<AX,BX,CX,DX>	
cBegin				
	OR	b$IOFLAG,SCN_INIT ; signal screen init done

	test	b$SCNFLAG,SCN_RESET	;startup screen mode change?
	jz	NoReset 	;go if not
	call	B$ChkMonitor	; Set VGA monitor type before setting mode
	call	[b$SetMode]	;set the new screen mode
	call	B$FixTextPage	; fix b$CurrPSize, b$PageTable

NoReset:			
	mov	ax,b$CurPages	
	call	[b$SetPages]	; Set current page data

	; move up one line if on the last one
	TEST	b$IOFLAG,SCN_SCROLL ; are we to scroll the screen?
	JZ	NOT_LAST	; brif not

	CALL	B$SCROLL	; scroll up 1 line
NOT_LAST:

	CALL	[b$PalReset]	;initialize the palette

cEnd				; restore registers & return


;***
; B$SetAdapter
;
;Purpose:
;	Determine configuration of video adapter, monitor and memory.
;	Major rewrite (from $SETCL4) with [21].
;Entry:
;Exit:
;	b$Adapter, b$Monitor, and b$VideoMem updated
;	b$EgaPalSup set as appropriate
;Uses:
;Exceptions:
;****

cProc	B$SetAdapter,<PUBLIC,NEAR>,<AX,BX,CX>
cBegin
	PUSH	ES		
	PUSH	DI		

	
	mov	ax,StdColor	;AH gets 0, AL gets CGA mask
	mov	b$Adapter,al	;Assume CGA, no EGA or VGA card present
	mov	b$VideoMem,16	;  w/16K video memory
	mov	b$Monitor,al	;Assume std color monitor
	mov	b$EgaPalSup,ah ;  no EGA palette support

	PUSH	DS		;set ES=DS
	POP	ES		;  for vGetVgaInfo call
	MOV	DI,OFFSET DGROUP:b$Buf1 ; dest. buffer for VGA info
	XOR	BX,BX		;Bios sub-function to return VGA info
	SCNIOS	vGetVgaInfo	;Returns: [AL] = 1B (vGetVgaInfo) if VGA
				;	      if VGA, 64 bytes of info at ES:DI

	CMP	AL,vGetVgaInfo	;is VGA present?
	JNE	NOTVGA		;no, go check for EGA
	MOV	BL,[DI+31H]	; available video memory
	MOV	AL,[DI+2Dh]	; VGA-MCGA-PS/2 Miscellaneous state info
	MOV	[VgaMiscInfo],AL ; save state info for B$ChkMonitor
	LES	DI,[DI] 	;long pointer to static functionality table
	MOV	AX,ES:[DI]	; find out which VGA modes hardware supports
	MOV	[b$VGAmodesL],AX ; save for Screen mode validation
	MOV	AL,ES:[DI+2]	; same for modes 10h-13h
	MOV	[b$VGAmodesH],AL ; save for Screen mode validation

;	The first three bytes of the static functionality table define (by bit
;	flags) which bios modes are supported by the current graphics adapter.
;	Bios mode 12H is supported by the VGA but not by the MCGA.  We can tell
;	which of these two we are working with by testing the bit which
;	corresponds to that bios mode.

	MOV	b$Adapter,MCGA	;assume MCGA
	MOV	b$Monitor,AnalogColor ; analog color monitor (in case MCGA)
	TEST	AL,VGAmode12h	; is bios mode 12H supported?
	JZ	MonOK		;no, we must have an MCGA
; At this point we know we have a VGA, but we must check if there is
; a second adapter (MDPA, HGC, CGA) installed and, if so, which one is
; currently active.  ADJUST_VGA returns with PSW.C set if VGA not active.
; Also, b$Monitor, b$VGAmodeL, and b$VGAmodeH are adjusted accordingly.
	MOV	b$Monitor,AnalogColor + AnalogMono ; analog monitor
	CALL	ADJUST_VGA	; check/adjust for 2nd adapter
	JC	TRANS		; brif VGA not active adapter
	MOV	b$Adapter,VGA	;using VGA
	MOV	b$EgaPalSup,1	;have EGA palette support
	JMP	SHORT MonOK	;translate video memory size and then exit
NOTVGA: 			

	MOV	BL,10h		;% Bios sub-function to return EGA information
	SCNIOS	vAltSelect	;% Returns: [BH] = 0=color/1=mono mode
				;%	    [BL] = memory on ega card
				;	    [CH] = feature bits
				;	    [CL] = switch settings (monitor)

	TEST	BL,11111100B	;if EGA support, only bit 0,1 have values
	JNZ	TRANS		;exit if no EGA

;	At this point we know we have an EGA card, and whether it has
;	monochrome monitor attached.
;	Use the 30H bits in b$CurEquip to determine
;	the active display. 10H for COLOR40, 20H for COLOR80 or 30h for
;	Monochrome.

	mov	al,b$CurEquip	; Read the current equipment setting
	AND	AX,30H		; Knock off unwanted bits : AH = 0
	CMP	AL,30H		; Is it monochrome?
	JNE	COLOR_ACTIVE	; Brif not - color monitor
	INC	AH		; AH = 1 for Monochrome
COLOR_ACTIVE:			
	CMP	AH,BH		; init mode same as EGA mode?
	JNE	TRANS		; Brif not
	mov	b$Adapter,EGA	;using EGA
	mov	b$EgaPalSup,1	;have EGA palette support
	and	cl,0FH		;monitor 7=color,8=enh as color,9=enh,B=mono
	sub	cl,9		;<0=color,0=enh,2=mono
	jc	MonOk		;go if color (the above assumption)
	MOV	CH,EnhColor	; assume enh (cl=0)
	JZ	IsEnh		; it is enh, CH has bit mask we want
	MOV	CH,Monochrome	; must be mono, set up bit mask accordingly
IsEnh:				
	MOV	b$Monitor,CH	; save it
MonOk:
	;BL=amount of EGA memory: 0 -- 64K, 1 -- 128K, 2 -- 192K,3 -- 256K
	inc	bl		;now increments of 64K
	xor	bh,bh
	mov	cl,6
	shl	bx,cl		;times 64 to put in increments of 1K
	mov	b$VideoMem,bx	;save it
	JMP	SHORT SETEXT	;exit

; this label reached only if EGA card is not installed or is not the
; current active card.

TRANS:

	mov	al,b$CurEquip	;check if equipment set for MDPA
	AND	AL,00110000B	;by isolating bits 4 and 5
	CMP	AL,00110000B	;and checking for both set
	JNZ	SETEXT		;BRIF color correct (not MDPA)
	dec	b$Monitor	;else MDPA
	dec	b$Adapter	;  and mono monitor
	mov	b$VideoMem,4	;w/4K video memory

SETEXT:				
; check for OGA here if CGA, EGA, or VGA
	test	[b$Adapter],CGA+EGA+VGA ; only these could be Olivetti
	jz	ChkHerc		; brif cannot be Olivetti
	xor	ax,ax		; ensure AX = 0 if lloga.ob3 not linked in
	call	[b$pChkOlivetti] ; check if Olivetti 640x400 mode supported
	jz	ChkHerc		; returns AL=0, PSW.Z = 1 if not supported
	or	[b$Adapter],al	; Assumes b$Adapter never CMPed in runtime!
	cmp	[b$VideoMem],32	; will have at least 32K
	ja	ChkHerc		; brif already set
	mov	[b$VideoMem],32 ; set 32K video memory
ChkHerc:			
	mov	dx,-1		; DX will not change if no driver
	SCNIOS	0EFH		;test for Hercules INT10 driver
	cmp	dl,-1		;DL returns -1 if no driver or no HGC
; code to handle CGA plus HGC 
	je	setext2		; brif so, already set to CGA or MDPA above
	test	[b$Adapter],MDPA ; do we have a monochrome display?
	jz	half_mode	; brif not, make CGA work with HGC
	mov	b$Adapter,HGC	;set adapter to HGC
	mov	b$VideoMem,64	;w/64K video memory
	or	dh,dh		; see if driver indicated HALF mode
	jnz	setext2		; brif not, assume only card
	shr	[b$VideoMem],1	; only 32K with second card
half_mode:			; make HGC work with CGA
	mov	dx,03BFh	; Hercules configuration port
	mov	al,HALF		; make sure only in HALF mode
	out	dx,al		; write to HGC config. port

setext2:			

	POP	DI		
	POP	ES		
cEnd

;*** 
;ADJUST_VGA - Check if VGA is active and which modes it supports
;
;Purpose:
;	Checks for multiple adapters when one is a VGA.
;
;Entry:
;	b$Monitor = AnalogColor + AnalogMono
;
;Exit:
;	b$CurEquip possibly updated.
;	PSW.C set if VGA not active adapter.
;	b$VGAmodeL and b$VGAModeH adjusted as necessary.
;	b$Monitor adjusted for active display (if PSW.C, = StdColor)
;
;Uses:
;	AX.
;
;Preserves:
;	ES.
;
;Exceptions:
;	None.
;
;******************************************************************************
cProc	ADJUST_VGA,<NEAR>,<ES>
cBegin				; entire routine
	XOR	AX,AX
	mov	ES,AX
	MOV	AX,ES:[488h]
	TEST	AH,1		; see if VGA handles all modes
	JNZ	vga_exit	; brif so
	TEST	AL,8		; see if display attached
	JNZ	got_display
	XOR	AL,2		; reverse BIT 1
got_display:
	MOV	AH,ES:[BiosEquip] ; read current BiosEquip
	mov	b$CurEquip,ah	; update the current equipment setting
	AND	AH,30H		; Knock off unwanted bits
	CMP	AH,30H		; Is it monochrome?
	JE	flag_Set	; Brif so
	XOR	AL,2		; invert for color monitor
flag_set:
	TEST	AL,2
	JZ	no_vga		; VGA not active
	CMP	AH,30h		; MONO?
	je	setvgamono	; brif so
	and	b$VGAmodesL, NOT (VGAMode7h+VGAModeFh)
	MOV	b$Monitor,AnalogColor
	jmp	short vga_exit
setvgamono:
	mov	b$VGAmodesH,0
	and	b$VGAmodesL, VGAMode7h+VGAModeFh
	MOV	b$Monitor,AnalogMono
	jmp	short vga_exit
no_vga:
	XOR	AX,AX
	MOV	b$VGAmodesH,AL
	MOV	b$VGAmodesL,AX
	MOV	AL,StdColor	; reset back to defaults:
	MOV	b$Adapter,AL	; CGA
	MOV	b$Monitor,AL	; StdColor monitor
	STC			; PSW.C indicates VGA not active
vga_exit:
cEnd







;*** 
;B$ChkMonitor - Make sure VGA set for mono or color appropriately
;
;Purpose:
;	This routine ensures that a VGA card is properly set up for whatever
;	Bios mode we are about to go into, monochrome or color.
;	Added with revision [49].
;	Rewritten with revision [64].
;	Note: this is unnecessary for PS/2 VGA and Olivetti VGA
;
;Entry:
;	[b$BiosMode] set to desired BIOS mode
;	B$Adapter & VgaMiscInfo initialized.
;
;Exit:
;	[b$CurEquip] updated.
;	VGA card set up for desired mode.
;
;Uses:
;	Per convention.
;
;Preserves:
;	ES.
;
;Exceptions:
;	None.
;
;******************************************************************************

cProc	B$ChkMonitor,<PUBLIC,NEAR>
cBegin
	CMP	[b$Adapter],VGA ; VGA? (not MCGA or Olivetti VGA)
	JNE 	EndOfChk	; no - nothing to do
	PUSH	ES		; preserve ES
	XOR	AX,AX		; ES = 0
	MOV	ES,AX
	MOV	AH,ES:[BiosEquip] ; read current BiosEquip
DbAssertTst	AX,NZ,2000h,RT_TEXT,<Unexpected BiosEquip flag in B$ChkMonitor>
	OR	AH,30h		; set equipment flag for MONO (default)
	MOV	AL,[b$BiosMode] ; check desired BIOS mode for 7 of F.
DbAssertRelB	AL,B,17h,RT_TEXT,<Advanced BIOS mode in B$ChkMonitor>
	AND	AL,7		
	SUB	AL,7		; Is it a monochrome mode?
	JZ     NeedMono		; brif & set Adapter to monochrome
	AND	AH,0EFh		; set equipment flag for Color80
	MOV	AL,1		; turn off summing if color monitor
NeedMono:
	MOV	[B$CurEquip],AH ; update [b$CurEquip]
	MOV	ES:[BiosEquip],AH ; update current BiosEquip
	POP	ES
	TEST	[VgaMiscInfo],4	; monochrome analog monitor?
	JNZ	EndOfChk	; brif so -- okay as is
	MOV	BL,33h		; turn gray-scale summing on/off
	SCNIOS	vAltSelect	
EndOfChk:

cEnd


;***
;B$GWTERM - OEM termination
;OEM-interface routine
;
;Purpose:
;	This routine is called once immediately before BASIC terminates.
;	It contains machine specific code to put the system into
;	a deterministic final state.  The final state should be as close
;	to the initial startup state as possible.
;
;	NOTE: All of the screen termination is done by a call to
;	      B$RESETSCN from a different part of the runtime.  This
;	      routine should not try to reset the screen in any way.
;
;Entry:
;	None
;
;Exit:
;	None
;
;Uses:
;	Per convention
;
;Exceptions:
;	None
;****

cProc	B$GWTERM,<PUBLIC,NEAR> 
cBegin

; All of the screen restoration code has been moved from here
; into B$CNTERM.


	IN	AL,MSKREG	; get IMR into [AL]
	OR	AL,01H		; mask out timer interrupt
	PAUSE			; make sure instruction fetch has occurred
	OUT	MSKREG,AL	; write mask to IMR

	CLI
	PUSH	DS
	XOR	AX,AX
	MOV	DS,AX
	ASSUME	DS:NOTHING
	RSTVEC	TMRCTL,DS:TICSAV ;restore clock interrupt
	POP	DS

	ASSUME	DS:DGROUP

	XFRINT	KYBINT,KBDVEC/4 ;move INT EFH to INT 09H

	PUSH	DS		;save seg register...
	RSTVEC	KBDVEC/4,b$KBDVEC_SAVE ;restore INT EF vector
	POP	DS		;restore seg register
	PUSH	DS		;save seg register...
	RSTVEC	CLKVEC/4,b$CLKVEC_SAVE ;restore INT F0 vector
	POP	DS		;restore seg register

	IN	AL,MSKREG	; get IMR into [AL]
	AND	AL,0FEH 	; unmask timer interrupt
	PAUSE			; make sure instruction fetch has occurred
	OUT	MSKREG,AL	; write mask to IMR
	STI

cEnd				


;***
;B$SEGINI - Initialize Variable for B$GETDS
;OEM-interface routine
;
;Purpose:
;	This routine stores the address of the runtime data segment.
;	The value is stored in the code segment so that it can be
;	retrieved later by a call to B$GETDS. These two routines
;	are used to save the data segment across a run, chain, or
;	shell command.	The runtime will call B$SEGINI before it
;	needs to call B$GETDS.
;
;	Note that it is possible that B$SEGINI is called multiple
;	times throughout the execution of a program.
;
;	This is a DOS 3 only routine.
;
;Entry:
;	DS = Final runtime data segment address
;
;Exit:
;	DS stored.
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, BX, CX, DX, FLAGS
;
;Exceptions:
;	none
;****

cProc	B$SEGINI,<PUBLIC,NEAR>	
cBegin
	MOV	[b$BASDSG],DS	  ;store addr of BASIC data segment
cEnd


;***
;B$GETDS - Get Data Segment for Runtime
;OEM-interface routine
;
;Purpose:
;	This routine is used to obtain the location of
;	the  BASIC data segment. The value is kept in the
;	basic code segment, where it is put by B$SEGINI.
;
;	See also B$SEGINI.
;
;Entry:
;	None.
;
;Exit:
;	[BX] = BASIC data segment
;
;Uses:
;	Per Convention
;
;Preserves:
;	AX, CX, DX, FLAGS
;
;Exceptions:
;	None
;****

cProc	B$GETDS,<PUBLIC,NEAR>	
cBegin				
	MOV	BX,[b$BASDSG]
cEnd				



sEnd	RT_TEXT 		
	END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -