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

📄 saveega.asm

📁 [随书类]Dos6.0源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:

;*
;*	CW : Character Windows
;*
;*	ega.asm : DOS3 TWIN compatible screen driver
;*
;*****************************************************************************

;*	* Special screen save
NonStandard	CbSizeVidsCsd
NonStandard	FSaveVidsCsd
NonStandard	FRestoreVidsCsd
NonStandard	SetVideoMode
NonStandard	SaveVidDataCsd
NonStandard	RestoreVidDataCsd
NonStandard	EnableVidsMonitorCsd

;********** CbSizeVidsCsd **********
;*	* CSD entry point (see documentation for interface)

cProc	CbSizeVidsCsd, <FAR, PUBLIC, ATOMIC>
cBegin	CbSizeVidsCsd

	mov	ax,SIZE EGA_VIDS
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
	jnz	notCGAVids

	sub	ax,24				;for EGA palette settings
	jmp	short CbSizeExit
notCGAVids:
	test	[bx].fvmCurAdap, fvmMCGA or fvmVGA
	jz	CbSizeExit

	add	ax,255*3			;for PS2 palette settings
CbSizeExit:
	inc	ax				;get even cb
	and	ax,0FFFEh      
cEnd	CbSizeVidsCsd


;********** FSaveVidsCsd ********
;*	entry:	pvidsSave = near pointer to VIDS structure
;*		pinst = near pointer to INST for new mode
;*	* fill *pvidsSave with state of current screen mode (not screen data)
;*	exit:	AX != 0 if ok, == 0 if error

cProc	FSaveVidsCsd, <FAR, PUBLIC, ATOMIC>, <si, di>
    parmDP pvidsSave
    parmDP pinst
cBegin	FSaveVidsCsd

	mov	di,pvidsSave

	mov	ah,0Fh
	int	10h				;* GetMode and page
	and 	al,07Fh				; clear msb
	mov	[di].modeVids,al
	mov	[di].pageVids,bh

	mov	[di].fClearRegenVids,00H
				      
	mov	ax,SIZE EGA_VIDS - cbVidsMin	;default EGA
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
	jnz	notFSCGA
	
	sub	ax,24			;EGA palette regs
	jmp	short notFSPS2
notFSCGA:
	test	[bx].fvmCurAdap, fvmMCGA or fvmVGA
	jz	notFSPS2

	add	ax,255*3		;DAC color regs
notFSPS2:
	inc	ax			;get even cb
	and	ax,0FFFEh      
	shr	ax,1
	mov	[di].cwExtraVids,ax

	mov	ah,3
	int	10h				;* GetCursorPos
	mov	[di].vparmCursorVids,cx

	mov	ax,ds
	mov	es,ax
	mov	dx,di
	lea	di,[di].rgwCursorPosVids	;* save cursor positions here

	push	ds
	xor	ax,ax
	mov	ds,ax
	mov	si,BIOS_cursor_posn		;* 8 Cursor positions in BIOS

	mov	cx,8
	rep movsw
	pop	ds
	mov	di,dx			; restore di

public saveCGAPal			;UNDONE - remove these two lines
saveCGAPal:				;UNDONE
	;
	; Assumes bCGABg is immediately before bCGAPal
	; and bCGABgVids is immediately before bCGAPalVids
	;
	.errnz	(bCGABgVids+1) - bCGAPalVids
	.errnz	(bCGABg+1) - bCGAPal
	mov	ax, word ptr cs:[bCGABg]
	mov	word ptr [di].bCGABgVids, ax

	mov	dl, [di].modeVids
	cmp	dl,40H			;Olivetti
	jz	@F

	test	[bx].fvmCurAdap, fvmCGA
	jz	skipCGA
@@:

;* for CGA only
	xor	ax,ax
	mov	es,ax
	mov	al, byte ptr es:[466H]
	mov	[di].ayOverScanVids, al
	mov	ax, 80*25	; Maybe we can get by just saving what we use (4k b).
	cmp	dl, 2
	je	save_not_graphics
	cmp	dl, 3
	je	save_not_graphics
	mov	ax, 8*1024	; Must mode switch (4,5,6) so must save all of regen(16k b)
	cmp	dl, 40H		; Is this an Olivetti graphics screen mode?
	jne	@F
	add	ax, ax		; Yes, there is twice as much memory to save
@@:

save_graphics:
	and	[di].fvidsVids,not fvidsChAttr	;graphics modes 
save_not_graphics:	;* ax = # of words to swap
	mov	[di].cwSwapVids,ax
	jmp	EgaSS_Exit

skipCGA:
	test	[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
	jz	@F
	cCall	EgaSavePalette		;save palette regs
@@:	
	push	bp
	mov	ax,1130h		; get info
	xor	bx,bx
	xor	cx,cx
	int	10h
	pop	bp

	inc	dl			; dl = scan lines
	mov	[di].ayMacVids,dl	; rows
	mov	[di].ayPointsVids,cl	; cl = number of lines in char

	cmp	[di].modeVids,4		;check simple graphics
	jb	notmode4to6

	cmp	[di].modeVids,6
	ja	notmode4to6

	mov	ax,8*1024	; Must mode switch (4,5,6) so must save all of regen(16k b)
	mov	[di].cwSwapVids,ax
	and	[di].fvidsVids,not fvidsChAttr	;graphics modes 
	jmp	EgaSS_Exit

notmode4to6:
	mov	ax,80			;default 80 columns
	mov	si,pinst
	cmp	dl,[si].ayMacInst	;rows
	ja	AboveNewAy

	mov	dl,[si].ayMacInst	;assume going into text mode
AboveNewAy:
	mul	dl			;columns * rows
	mov	cl,[di].modeVids
	cmp	cl, 08H
	ja	EgaSS_Hard
	cmp	cl, 07H
	jb	NotHerc

; We are in mode 7 or 8 so we might have a Hercules card.
	push	ax			;Save cwSwap
	mov	ah,0efH
	mov	dl, -1
	int	10H
	pop	ax			;restore cwSwap
	inc	dl
	jz	NotHerc			;DL not changed by INT 10 unless herc.
	mov	ax,8*1024		;Must save 8k words for herc
					;We would only have to save 4K words
					;If it weren't for Compaq's stupid
					;BIOS which always clears 16K bytes
					;when switching into mode 7.
	mov	[di].fClearRegenVids,80H
NotHerc:
	mov	[di].cwSwapVids,ax	
	mov	[di].fvidsVids,fvidsChAttr	;Text modes 
	jmp	EgaSS_Exit

; *** Graphics Text ***
; Ok, we are in one of the difficult graphics modes.
; We must save cLines*80 words from bit plane 0 and the same from bit plane 1
; and we must save 4k words from bit plane 2 (because the character
; generator gets loaded into this area when we switch to alpha mode).

EgaSS_Hard:
	mov	[di].cwSwapVids,ax	
	and	[di].fvidsVids,not fvidsChAttr	;graphics modes 
	mov	ax, 2*1024			; MCGA uses 2k words
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmMCGA
	jnz	EgaSS_Alloc

	mov	ax,[di].cwSwapVids		; ax == cLines*cColumns words
	shl	ax,1				; for bit plane 0 and 1
EgaSS_Alloc:
	add	ax, 4*1024		; Save 4k words of bit plane 2
	test	[bx].fvmCurAdap, fvm64KEGA
	jz	EgaSS_Exit

; More memory gets trashed by the BIOS doing a mode reset on a 64k Ega.
; Note: On a 64k Ega, the 4k words starting at 16k of bit plane 2 also get
;       trashed by the BIOS for some reason (so we gotta save that too).

	add	ax,4*1024

EgaSS_Exit:
	mov	[di].cwVidDataVids,ax
	mov	ax,sp				;* success

cEnd	FSaveVidsCsd


;********** EgaSavePalette ********
;*
;*	entry: ds:[di] => Vids

cProc EgaSavePalette,<NEAR,PUBLIC>,<SI,DI,ES>
cBegin EgaSavePalette

	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	mov	ax,ds
	mov	es,ax
	test	[bx].fvmCurAdap, fvmMCGA or fvmVGA 	;PS2 ?
	jz	@F

	lea	dx, [di].rgbPS2PaletteVids		
	mov	ax, 1017H			; Read block of Palette regs
	xor	bx,bx				;    start at reg 0
	mov	cx, 256				;    read 256 regs
	int	10H
@@:
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
	jz	@F

	push	ds
	pop	es
	lea	di, [di].rgbEgaPaletteVids	;es:[di] -> buffer
	push	cs
	pop	ds
	mov	si, DrvOffset EGAPaletteMirror
	mov	cx,17				;16 palette + overscan regs
	rep	movsb
	push	ss
	pop	ds				;restore ds
@@:
cEnd EgaSavePalette


;********** FRestoreVidsCsd ********
;*	entry:	pvidsRestore = near pointer to VIDS structure
;*	* restore video state with data in *pvidsRestore (not screen data)
;*	exit:	AX != 0 if ok, == 0 if error

cProc	FRestoreVidsCsd, <FAR, PUBLIC, ATOMIC>, <si, di>
    parmDP pvidsRestore
cBegin	FRestoreVidsCsd

	mov	di,pvidsRestore
	mov	al, [di].modeVids
	cmp	al, 2
	je	EgaFRS_Text

	cmp	al, 3
	je	EgaFRS_Text

	cmp	al, 40H				;[==] Olivetti
	je	EgaFRS_SimpleGraphics		;[==]

	cmp	al, 8
	ja	EgaFRs_HardGraphics
	cmp	al, 7
	jae	EgaFRS_Text

EgaFRS_SimpleGraphics:			;mode 4,5 & 6
	cCall	SetVideoMode
	jmp	EgaFRS_Common

EgaFRS_Text:	; mode 2,3 and 7
ifndef	KANJI
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	cmp	[bx].fBlinkEnable,0
	je	@F				;trash ax,dx

	mov	[bx].fBlinkEnable,0		;disable Blink
	cCall	DiddleBlinkbit
	jmp short RestoreBlink
@@:
	mov	[bx].fBlinkEnable,1		;enable Blink
	cCall	EnableBlinkbit
RestoreBlink:
endif	; !KANJI
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmVGA 	;VGA ?
	jz	EgaFRs_SetScanLines_done

	mov	al,2			;default 400 lines
	cmp	[di].ayMacVids,43     	; 43 line mode
	jne	useDefaultLine

	dec	al			;set 350 scan line

useDefaultLine:
	mov	ah,12h			;set vertical scan line
	mov	bl,30h
	int	10h			;takes effect on next mode set

EgaFRs_SetScanLines_done:
	cCall	SetVideoMode
	or	ax,ax			;mode set ?
	jz	EgaFRS_Common
	cmp	[di].ayPointsVids,8	;8x8 font ?
	jne	EgaFRS_Common

	mov	ax,1112h
	mov	bh,8
	xor	bl,bl
	int	10h
	jmp	EgaFRS_Common

EgaFRS_HardGraphics:
	cCall	ClearRegen
	cCall	SetVideoMode
	cmp	[di].ayPointsVids, 8
	jne	EgaFRs_NoLoad8

	mov	ax,1123h
	xor	bh,bh
	mov	bl,[di].modeVids
	sub	bl,0dh
	mov	dl,cs:[GraphicsModeRows+bx]
	xor	bl,bl
	int	10h

EgaFRs_NoLoad8:

EgaFRs_Common:
	mov	al,[di].pageVids
	mov	ah,5
	int	10h				;* SetPage

	mov	dx,di
	xor	ax,ax
	mov	es,ax
	lea	si,[di].rgwCursorPosVids
	mov	di,BIOS_cursor_posn
	mov	cx,8
	rep movsw
	mov	di,dx

	mov	bl,[di].pageVids
	xor	bh,bh
	shl	bx,1
	mov	dx,[di+bx].rgwCursorPosVids	;* get cursor pos for this page
	shr	bx,1
	mov	bh,bl
	mov	ah,2
	int	10h				;* SetCursorPos

	mov	cx,[di].vparmCursorVids
	mov	ah,1
	int	10h				;* SetCursor

	cmp	[di].modeVids,40H		;Don't EgaRestore palette for
	je	@F				; Olivetti
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM or fvmMCGA
	jz	@F

	cCall	EgaRestorePalette
@@:
public restoreCGAPal				;UNDONE - remove
restoreCGAPal:					;UNDONE - remove

	push	bx
	mov	bl, [di].bCGAPalVids
	or	bl,bl
	js	@F				;* skip if negative
	mov	bh,1
	mov	ah,0BH
	int	10H				;* set color palette
@@:
	mov	bl, [di].bCGABgVids
	or	bl,bl
	js	@F				;* skip if negative
	xor	bh,bh
	mov	ah,0BH
	int	10H				;* set background color
@@:
	pop	bx

	test	[bx].fvmCurAdap, fvmCGA 		;CGA ?
	jz	@F

	xor	ax,ax
	mov	es,ax
	mov	al, [di].ayOverScanVids
	mov	byte ptr es:[466H],al
	mov	dx, 3d9H
	out	dx, al
@@:
	mov	ax,sp				;* success

cEnd	FRestoreVidsCsd


;********** EgaRestorePalette ********
;*
;*
cProc	EgaRestorePalette,<NEAR,PUBLIC>,<SI,DI,ES>
cBegin  EgaRestorePalette

	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	mov	ax,ds
	mov	es,ax
	test	[bx].fvmCurAdap, fvmMCGA or fvmVGA 	;PS2 ?
	jz	@F

	lea	dx, [di].rgbPS2PaletteVids		
	mov	ax, 1012H			; write block of Palette regs
	xor	bx,bx				;    start at reg 0
	mov	cx, 256				;    read 256 regs
	int	10H

@@:
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
	jz	@F

	cmp	cs:[lpbBIOSINT10_Offset],0	;save check
	je	@F
	
	mov	ax,1002h
	lea	dx, [di].rgbEGAPaletteVids	;es:[dx] -> buffer
	int	10h
@@:	
cEnd	EgaRestorePalette


;***********************
cProc	EnableBlinkBit, <NEAR, ATOMIC, PUBLIC>, <DS>
cBegin	EnableBlinkBit

;*	* Diddle blink bit via BIOS call (or diddle CGA bit)

	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	[bx].fvmCurAdap, fvmCGA or fvmMDA
	jz	EBB_NotCGA

	xor	ax,ax
	mov	ds,ax
	mov	dx,ds:[BIOS_addr_6845]
	add	dx,PORT_mode
;*	* set the mode set flag
	or	byte ptr ds:[BIOS_crt_mode_set],20H
	mov	al,ds:[BIOS_crt_mode_set]
	out	dx,al				;* send to port

;*	* EGA etc has a BIOS call for this
EBB_NotCGA:
	mov	ax,1003H			;* set intensify/blink
	mov	bl,1				;* enable blink
	int	10h

cEnd	EnableBlinkBit


;********** SetVideoMode **********
;*	entry:	al = video mode
;*	* Set specified video mode
;*	exit:	trash ax,cx,es
;*	ax = 0 same mode,-1 mode set

cProc	SetVideoMode,<NEAR>,<es>
cBegin	SetVideoMode
	mov	ah,0Fh
	int	10h				;* GetMode
	and	al,7fh
	cmp	al,[di].modeVids
	jne	SVM_SetMode	    		;reset

;same mode, check rows		
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	ss:[bx].fvmCurAdap, fvmCGA	;CGA only support 25 rows
	jnz	mode_already_set
	push	bp
	mov	ax,1130h		; get info
	xor	bx,bx
	xor	cx,cx
	int	10h
	pop	bp
	inc	dl			; dl = scan lines
	cmp	dl,[di].ayMacVids	; rows
	jne	SVM_SetMode
	jmp	mode_already_set

SVM_SetMode:
	mov	al,[di].modeVids
	or	al,[di].fClearRegenVids
	
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	test	ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
	jz	TrashRegen	;CGA doesn't support the function below
	cmp	al, 40H		;Olivetti doesn't support it either.
	je	TrashRegen

	or	al,80h				;* don't clear RGEN

TrashRegen:
	xor	ah,ah
	push	ax				;save mode
	int	10h				;* set mode
	pop	ax				;restore
;*	* Delay so that we won't start writting to the display before it has
;*	* settled down.
	mov	cx,500
delay_me:
	loop	delay_me

;
; When the olivetti is in mode 40H the value at BIOS_info is a pointer to
; the character set (NOT flags as it is in EGA modes)
; So let's not trash the pointer by clearing the "don't clear regen" bit.
;
	cmp	al, 40H
	je	@F

	test	ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmMCGA or fvmEGAM
	jz	@F

;* Clear the "don't clear regen" bit in the BIOS image
	xor	ax,ax
	mov	es,ax
	and	byte ptr es:[BIOS_info],7fH	;487H
	mov	ax,40h
	mov	es,ax
	mov	al,[di].ayMacVids		;
	dec	al				; rows - 1
	mov	byte ptr es:[0084H],al		;* update BIOS rows
@@:
;
;	The following is provided only to overcome a bug in the EGA BIOS
;	routines which support the graphics "compatibility mode" (BIOS 4)
;	so that the two calls related to PALETTE (INT10 AH = 0BH and
;	INT10H AH = 10H) work correctly.  If we use the first call once
;	when user invokes SCREEN 1 to set the background color, then the
;	BIOS will subsequently reference the correct (low-intensity)
;	color values for the 4 palette attributes whenever the call using
;	INT10H, AH = 0BH is used to toggle the palette, and whenever the
;	call INT10H, AH = 10H is used to set an individual palette regis-
;	ter.  In the absence of this initialization, the high-intensity
;	color values for both palettes are referenced.
;
	test	ss:[bx].fvmCurAdap, fvmEGA or fvmVGA or fvm64KEGA or fvmEGAM
	jz	SkipKludge
	mov	al, [di].modeVids
	cmp	al,4
	je	@F
	cmp	al,5
	jne	SkipKludge
@@:
	push	bx
	xor	bx,bx
	mov	ah, 0BH
	int	10H		;set background color
	pop	bx
SkipKludge:
	mov	ax,-1		;mode set
	jmp short @F
mode_already_set:
	xor	ax,ax		;same mode
@@:
cEnd	SetVideoMode


;********** SaveVidDataCsd ********
;*	entry:	pvidsSaveData = near pointer to VIDS structure
;*		lpwBuffer = buffer to save data
;*	* save screen data into buffer
;*	exit:	n/a

cProc	SaveVidDataCsd, <FAR, PUBLIC, ATOMIC>, <DS, SI, DI>
    parmDP pvidsSaveData
    parmD  lpwBuffer
cBegin	SaveVidDataCsd

	mov	di,pvidsSaveData
	mov	si,di
	mov	dl,[di].modeVids
	mov	cx,0B800h
	cmp	dl,7			
	jb	@F
	cmp	dl,8			
	ja	@F
	mov	cx,0B000h			;video segment for mono mode
@@:
	mov	ax,[di].cwSwapVids
	les	di,lpwBuffer			;es:[di] -> buffer
	cmp	dl,40h				;Olivetti ?
	je	@F
	cmp	dl,8			
	ja	save_graphics_text
@@:						;Text modes or mode 6
	cCall	SaveRegen
	mov	di,si
	cCall 	ClearRegen
	jmp	SaveVidsDataExit

save_graphics_text:
	mov	bx,OFF_lpwDataCsd		;* Data in data segment
	mov	ax, 0a000H			; Address of bit planes
	mov	ds, ax				;ds:[si] -> video buffer
	test	ss:[bx].fvmCurAdap, fvmMCGA

⌨️ 快捷键说明

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