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

📄 screen.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;*	exit:	n/a

labelFP	<PUBLIC, MoveHardwareCursor>
	jmp	insj.lpfnMoveHwCursCsdInsj



;********** FQueryInft **********
;*	entry:	pinft, ifont
;*	* get font info
;*	exit:	AX = 0 => no more fonts

labelFP	<PUBLIC, FQueryInft>
	jmp	insj.lpfnFQueryInftCsdInsj


;********** GetCharMap **********
;*	entry:	pinft, ifont
;*	* get font info
;*	exit:	AX = 0 => no more fonts

labelFP	<PUBLIC, GetCharMap>
	jmp	insj.lpfnGetCharMapCsdInsj


ifdef	WINDOW_OVERLAP
;********** FAllocOverlapTable **********
;*	entry:	pfnAlloc => allocation function (supplied by App)
;*		pinst    => current INST infor
;*	* Allocate memory for the overlapping windows table
;*	* Note!! pinst must have been set up already (FQueryInst)
;*	exit:	AX != 0 if successful

cPublic	FAllocOverlapTable, <>, <SI>
	parmDP pinst		;* INST info
	parmD  pfnAlloc2		;* FAR PASCAL routine
cBegin	FAllocOverlapTable

	mov	si,pinst

	mov	al,[si].axMacInst
	mov	ah,[si].ayMacInst
	mul	ah
	mov	bx,ax

	mov	ax,fmemFixed
	Save	<bx>
	cCall	pfnAlloc2, <bx, ax>
	AssertEQ ax,0

	or	dx,dx
	jz	end_alloc_overlap		;* return AX == 0

	mov	psOverlap,dx

	mov	ax,sp				;* success

end_alloc_overlap:

cEnd	FAllocOverlapTable




;********** FreeOverlapTable **********
;*	entry:	pfnFree => free function (supplied by App)
;*	* free video driver buffers
;*	exit:	n/a

cPublic	FreeOverlapTable, <>, <SI>
	parmD  pfnFree2		;* FAR PASCAL routine
cBegin	FreeOverlapTable

	xor	cx,cx
	xchg	cx,psOverlap
	jcxz	done_overlap_free
	xor	ax,ax
	cCall	pfnFree2, <cx, ax>
done_overlap_free:

cEnd	FreeOverlapTable
endif	;*WINDOW_OVERLAP




;********** FAllocInstBuffers **********
;*	entry:	pinstAlloc => INST info to fill
;*		pfnAlloc => allocation function (supplied by App)
;*		fFonts => if secondary buffer wanted
;*	* Allocate memory for video driver buffers
;*	exit:	AX != 0 if successful

cPublic	FAllocInstBuffers, <>, <SI>
	parmDP pinstAlloc
	parmD  pfnAlloc		;* FAR PASCAL routine
	parmW  fFonts
cBegin	FAllocInstBuffers

	StartPublic

	mov	si,pinstAlloc

IFNDEF SCREEN_FFONT
	AssertEQ fFonts,0			;* not allowed
endif	;!SCREEN_FFONT

;*	* determine size of buffer (axMac * ayMac WORDS)
	mov	al,[si].axMacInst
	mov	ah,[si].ayMacInst
	mul	ah
	mov	bx,ax

	xor	ax,ax
	mov	[si].bits0Inst,ax		;* clear bits
;*	* first check to see if primary buffer needs allocation
	cmp	[si].psPrimInst,ax		;* == 0 ?
	jne	done_prim_alloc

	mov	ax,fmemFixed
	Save	<bx>
	cCall	pfnAlloc, <bx, ax>
	AssertEQ ax,0

	or	dx,dx
	jz	end_alloc			;* return AX == 0

	mov	[si].psPrimInst,dx
	or	[si].bits0Inst,MASK fAllocPrimInst
done_prim_alloc:

ifdef	SCREEN_FFONT
;*	* allocate secondary buffer if needed (bx = size of buffer)
	mov	cx,fFonts
	jcxz	no_sec_buffer
	test	[si].finstInst,finstFont
	jz	no_sec_buffer
	mov	ax,fmemFixed
	cCall	pfnAlloc, <bx, ax>
	AssertEQ ax,0

	or	dx,dx
	jz	end_alloc			;* return AX == 0

	mov	[si].psSecInst,dx
no_sec_buffer:
endif	;SCREEN_FFONT

;*	* allocate any needed driver specific memory
	mov	cx,[si].cwExtraInst
	jcxz	done_extra_alloc

	mov	ax,fmemFixed
	cCall	pfnAlloc, <cx, ax>
	AssertEQ ax,0

	or	dx,dx
	jz	end_alloc			;* return AX == 0

	mov	[si].psExtraInst,dx
done_extra_alloc:

	mov	ax,sp				;* success

end_alloc:

	StopPublic

cEnd	FAllocInstBuffers



;********** FreeInstBuffers **********
;*	entry:	pinstFree => INST info to free
;*		pfnFree => free function (supplied by App)
;*	* free video driver buffers
;*	exit:	n/a

cPublic	FreeInstBuffers, <>, <SI>
	parmDP pinstFree
	parmD  pfnFree		;* FAR PASCAL routine
cBegin	FreeInstBuffers

	StartPublic

	mov	si,pinstFree

	test	[si].bits0Inst,MASK fAllocPrimInst
	jz	done_prim_free

	xor	ax,ax
	cCall	pfnFree, <[si].psPrimInst, ax>

	and	[si].bits0Inst,NOT (MASK fAllocPrimInst)
done_prim_free:

ifdef	SCREEN_FFONT
	xor	cx,cx
	xchg	cx,[si].psSecInst
	jcxz	done_sec_free
	xor	ax,ax
	cCall	pfnFree, <cx, ax>
done_sec_free:
ELSE
	AssertEQ [si].psSecInst,0
endif	;!SCREEN_FFONT

;*	* free driver buffer
	xor	cx,cx
	xchg	cx,[si].psExtraInst
	jcxz	done_extra_free
	xor	ax,ax
	cCall	pfnFree, <cx, ax>

done_extra_free:

	StopPublic

cEnd	FreeInstBuffers



;*****************************************************************************


;********** FInitScreenInternal **********
;*	entry: pinst => INST structure (NULL => re-init previous mode)
;*	* Initialize the screen as needed
;*	* NOTE : this routine can be called ONLY ONCE.
;*	exit: AX != 0 => ok
;*		* NOTE: failure may destroy old instCur

cPublic FInitScreenInternal,<ATOMIC>, <SI, DI>
	parmW pinst
cBegin	FInitScreenInternal

	StartPublic

	mov	bx,dataOffset instCur
	mov	si,pinst
	or	si,si
	jz	use_current
;*	* set new INST (copy into instCur)
	push	ds
	pop	es
	mov	di,bx
	mov	cx,cbInstMin / 2
	rep movsw
use_current:	;* bx => instCur (instCur filled with *pinst)

	mov	ax,ds:[bx].finstInst
	and	ax,finstAvailable
	jnz	dont_end
end_init_jump:
	jmp	end_init			;* variant not available

dont_end:
	mov	ax,dataOffset inch
	Save	<bx>
	cCall	insj.lpfnFInitCsdInsj, <bx, ax>	;* (pinst, pinch)
	or	ax,ax
	jz	end_init_jump

;*	* move info from INCH to other globals, bx => instCur
	mov	al,[bx].axMacInst
	mov	axMac,al
	xor	ah,ah
	shl	ax,1
	mov	axMacTimes2,ax
	mov	al,[bx].ayMacInst
	mov	ayMac,al
	mov	ax,[bx].finstInst
	and	al,finstMonochrome	;* finstMonochrome in lower byte
	mov	fMonochrome,al

IFNDEF	CBOX
;*	* copy information from INCH into boxes
	lea	bx,inch
	push	ds
	pop	es			;* all in default data segment

;*	* copy single box
	lea	si,[bx]._chTopLeftCorner1Inch
	lea	di,boxSingle
	mov	cx,SIZE BOX / 2
	rep movsw
;*	* copy double box
	lea	si,[bx]._chTopLeftCorner2Inch
	lea	di,boxDouble
	mov	cx,SIZE BOX / 2
	rep movsw

	mov	al,[bx]._chShadowInitInch
	mov	chShadow,al

ifdef	WINDOW_OVERLAP
;*	* base window is single box
	lea	si,[bx]._chTopLeftCorner1Inch
	lea	di,boxActiveWindowOut
	mov	cx,SIZE BOX / 2
	rep movsw
	mov	al,[bx]._chCloseInch
	mov	boxActiveWindowOut.chTopLeftBox,al
	mov	al,[bx]._chZoomOutInch
	mov	boxActiveWindowOut.chTopRightBox,al
	mov	al,[bx]._chTopSide2Inch
	mov	boxActiveWindowOut.chTopBox,al
	lea	si,[bx]._chTopLeftCorner1Inch
	lea	di,boxInactiveWindowOut
	mov	cx,SIZE BOX / 2
	rep movsw
	mov	al,[bx]._chCloseInch
	mov	boxInactiveWindowOut.chTopLeftBox,al
	mov	al,[bx]._chZoomOutInch
	mov	boxInactiveWindowOut.chTopRightBox,al

	lea	si,[bx]._chTopLeftCorner1Inch
	lea	di,boxActiveWindowIn
	mov	cx,SIZE BOX / 2
	rep movsw
	mov	al,[bx]._chCloseInch
	mov	boxActiveWindowIn.chTopLeftBox,al
	mov	al,[bx]._chZoomInInch
	mov	boxActiveWindowIn.chTopRightBox,al
	mov	al,[bx]._chTopSide2Inch
	mov	boxActiveWindowIn.chTopBox,al
	lea	si,[bx]._chTopLeftCorner1Inch
	lea	di,boxInactiveWindowIn
	mov	cx,SIZE BOX / 2
	rep movsw
	mov	al,[bx]._chCloseInch
	mov	boxInactiveWindowIn.chTopLeftBox,al
	mov	al,[bx]._chZoomInInch
	mov	boxInactiveWindowIn.chTopRightBox,al
endif	;WINDOW_OVERLAP

endif	; !CBOX

ifdef	SCREEN_FFONT
;*	* set the fFontAvailable flag
	xor	ax,ax			;* assume off
	mov	cx,instCur.finstInst
	test	cx,finstFont
	jz	set_ffont_available	;* not available in this mode
	mov	cx,instCur.psSecInst
	jcxz	set_ffont_available	;* no secondary buffer => forget it
	inc	ax			;* yes, we can use ffonts
set_ffont_available:
	mov	fFontAvailable,ax
endif	;SCREEN_FFONT

	mov	ax,sp			;* success

end_init:	;* ax = return code

	StopPublic

cEnd	FInitScreenInternal



;********** BltArc **********
;*	entry : axSrc, aySrc : upper left of source
;*		axDest, ayDest : upper left of destination
;*		dax, day : shift amount
;*	* Move a rectangle from one portion of the screen to another.
;*	exit : n/a

cPrivate BltArc,<ATOMIC>,<SI,DI>
	parmB axDest
	parmB ayDest
	parmB dax 
	parmB day
	parmB axSrc
	parmB aySrc

	localW fMouseOn				;* FEnableMouse old state
	localW offDestLim				;* last offset written
cBegin	BltArc

	StartPublic

	xor	ax,ax
	cCall	FEnableMouse,<ax>		;* turn mouse off
	mov	fMouseOn,ax

	AssertUp

	mov	al,day
	or	al,al
	jz	blt_end1			;* trivial case (day == 0)

	CalcCoord axDest,ayDest
	mov	di,ax
	mov	offDrawFirst,ax			;* save for driver inform

;*	* Do either a Prep, Do, Done sequence or a fast BltArcCsd call
	test	instCur.finstInst,finstFastScroll
	jnz	skip_prep

;*	* Prepare screen driver for update
	mov	si,word ptr (dax)	;* low byte is all that's interesting
;*	* si = dax, di = offset in Prim buffer
;*	* ax = ayDest, cx = day
	xor	ax,ax
	mov	al,ayDest
	xor	cx,cx
	mov	cl,day
	push	di
loop_prep:
	Save	<ax,cx>
	cCall	insj.lpfnPrepUpdateCsdInsj, <ax, axDest, si, di, fRestoreDbcs>
	add	di,axMacTimes2			;* point to next row
	inc	ax
	loop	loop_prep
	pop	di
skip_prep:

	CalcCoord axSrc,aySrc
	mov	si,ax			; save pointer to source
	mov	dx,axMacTimes2		;* row modulus
	cmp	ax,di
	jge	blt_hilo		; going from high memory to low

; go from low memory to high.  Do backwards Blt  Blt Row by row either 
; fast or slow depending on the retrace parameter; ax has source, di
; destination of top left hand point

	mov	al,day
	dec	al
	mul	axMac
	mov	bl,dax
	xor	bh,bh
	add	ax,bx
	shl	ax,1
	dec	ax			;* back 1 byte (for movsb)

	add	di,ax			; move source to bottom right
	add	si,ax			; move dest to bottom, right 

	neg	dx			;* negate row modulus
	std				; bltting backwards
	jmp	short blt_go

blt_end1:	;* jump extender
	jmp	blt_end

blt_hilo:
;	cld				;* D flag already cleared
blt_go:
;*	* dx = row modulus (+ or - axMac * 2)
	mov	cl,dax			; setup number of columns
	xor	ch,ch
	jcxz	blt_end1			;* trivial case (dax == 0)
	shl	cx,1			;* ccol -> cb
	mov	bx,cx			;* CX = BX = cb

	push	ds
ifdef	DEBUG
	cmp	instCur.psPrimInst,0	;* no buffer! (FAllocInstBuffers)
	jne	@F
	cCall	CowAssertFailed
	DB	"no primary buffer for current mode$"
@@:
endif	;DEBUG
	mov	es,instCur.psPrimInst
	push	es
	pop	ds			;* DS & ES set to video segment

	xor	ax,ax
	mov	al,day
ifdef	SCREEN_FFONT
	Save	<ax,bx,cx,dx,si,di>	;* needed for second call
	cCall	DoBltArc
	pop	ds
	cmp	fFontAvailable,0
	jz	no_blt_ffont

	push	ds
	mov	es,instCur.psSecInst
	push	es
	pop	ds			;* DS & ES set to video segment
endif	;SCREEN_FFONT
	cCall	DoBltArc
	pop	ds
no_blt_ffont:

	cld					;* Clear D flag (convention)

;* Check for fast scrolling in graphics text modes	
	test	instCur.finstInst,finstFastScroll
	jz	no_fast
	cCall	insj.lpfnBltArcCsdInsj, <axDest, ayDest, dax, day, axSrc, aySrc>
	jmp	skip_updatedone
no_fast:
	
;*	* Inform screen driver of the destination area
	mov	si,word ptr (dax)	;* low byte is all that's interesting
	mov	di,offDrawFirst
;*	* si = dax, di = offset in Prim buffer
loop_inform_blt:
	cCall	insj.lpfnDoUpdateCsdInsj, <ayDest, axDest, si, di, fRestoreDbcs>
	add	di,axMacTimes2			;* point to next row
	inc	ayDest
	dec	day
	jnz	loop_inform_blt

;*	* all done, refresh
	cCall	insj.lpfnDoneUpdateCsdInsj		;* ()

blt_end:

	cld					;* Clear D flag (convention)

skip_updatedone:

	cCall	FEnableMouse,<fMouseOn>		;* restore mouse state

	StopPublic

cEnd	BltArc


;********** DoBltArc **********
;*	entry : ax = day, bx = cx = cb, dx = row modulus, si = source,
;*		di = dest, es and ds => video segment
;*	* blt screen memory
;*	* NOTE: direction flag either set or clear on entry.
;*	exit : n/a

cProc	DoBltArc,<NEAR,PUBLIC,ATOMIC>
cBegin	DoBltArc

	assumes ds,nothing

ifdef	WINDOW_OVERLAP
	push	bp			;* current window do blt
	mov	bp,pwndCur
endif	;WINDOW_OVERLAP

blt_row:
	push	si
	push	di

blt_fast:
;*	* We can BLT fast
ifdef	WINDOW_OVERLAP
	or	bp,bp
	jz	blt_fast_allowed
blt_overlap:
	push	di
	and	di,not 1
	push	ds
	mov	ds,ss:psOverlap
	cmp	bp,[di]
	pop	ds
	je	move_two
;*	* skip this movement
	push	ax
	mov	di,si			;* old position
	lodsw				;* bump by 2 in right direction
	mov	ax,si
	sub	ax,di			;* ax = delta (+2 or -2)
	pop	di			;* old DI
	add	di,ax			;* DI points to new position
	pop	ax
	jmp	short move_overlap_next
move_two:
	pop	di
ifdef	BUILTIN_SNOW
	push	ax
	push	dx
	mov	dx,3DAh			;* CGA video status port
	StartDrawCrit
endif	;BUILTIN_SNOW	
	movsb
	movsb
ifdef	BUILTIN_SNOW
	EndDrawCrit
	pop	dx
	pop	ax
endif	;BUILTIN_SNOW
move_overlap_next:
	dec	cx
	loop	blt_overlap
	jmp	short blt_next_row

blt_fast_allowed:	;* fall through to rep move
endif	;WINDOW_OVERLAP
ifdef	BUILTIN_SNOW
	push	ax
	push	dx
	mov	dx,3DAh			;* CGA video status port
SnowL1:
	StartDrawCrit
	movsb
	EndDrawCrit
	loop	SnowL1
	pop	dx
	pop	ax
ELSE	;NOT DEFINED BUILTIN_SNOW
	rep	movsb			;* move byte to keep backward case
endif	;BUILTIN_SNOW
					;* simple.
blt_next_row:
	pop	di
	pop	si
	mov	cx,bx			;* restore cx as cb
	add	di,dx
	add	si,dx			; move to next/previous row
	dec	ax
	jnz	blt_row

ifdef	WINDOW_OVERLAP
	pop	bp
endif	;WINDOW_OVERLAP

cEnd	DoBltArc

sEnd	SCREEN

;----------------------------------------------------------------------------

	END

⌨️ 快捷键说明

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