blitbit.asm

来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 3,447 行 · 第 1/4 页

ASM
3,447
字号

	include ..\cwlib.inc
	scode

;-------------------------------------------------------------------------
;
;Blit a bitmap to/from video memory.
;
;On Entry:
;
;C style stack with following parameters,
;
;flags	- flags, bit significant if set.
;	0 - blit video to system memory.
;	1 - OR bitmap on, chroma value is used.
;bitmap	- pointer to bitmap.
;xcoord	- X co-ord to blit at.
;ycoord	- Y co-ord to blit at.
;xoff	- X offset within bitmap.
;yoff	- Y offset within bitmap.
;wide	- width to blit.
;depth	- depth to blit.
;chroma	- chroma value to use when OR'ing.
;
;On Exit:
;
;nothing.
;
;ALL registers preserved.
;
;Note: If bit 0 of flags is set all other flag bits are ignored.
;
VideoBlitBitmap:
_VideoBlitBitmap proc syscall Flags:dword, Bitmap:dword, XCoord:dword, \
	YCoord:dword, XOff:dword, YOff:dword, Wide:dword, \
	Depth:dword, Chroma:dword
	mov	eax,Flags
	pop	ebp
	test	eax,1
	jnz	VideoGetBitmap
	jmp	VideoPutBitmap
_VideoBlitBitmap endp


;-------------------------------------------------------------------------
;
;Blit a bitmap to video memory.
;
;On Entry:
;
;C style stack with following parameters,
;
;flags	- flags, bit significant if set.
;	0 - blit video to system memory.
;	1 - OR bitmap on, chroma value is used.
;bitmap	- pointer to bitmap.
;xcoord	- X co-ord to blit at.
;ycoord	- Y co-ord to blit at.
;xoff	- X offset within bitmap.
;yoff	- Y offset within bitmap.
;wide	- width to blit.
;depth	- depth to blit.
;chroma	- chroma value to use when OR'ing.
;
;On Exit:
;
;nothing.
;
;ALL registers preserved.
;
;Note: If bit 0 of flags is set all other flag bits are ignored.
;
VideoPutBitmap	proc syscall Flags:dword, Bitmap:dword, XCoord:dword, \
	YCoord:dword, XOff:dword, YOff:dword, Wide:dword, \
	Depth:dword, Chroma:dword
	local	@@Source:dword, @@Dest:dword, @@MouseHandle:dword, \
	@@YBreak:dword, @@Depth:dword
	pushad
	mov	eax,Chroma
	mov	_VBB_Chroma,eax
;
;Check for maximum width/depth
;
	mov	esi,Bitmap
	cmp	Wide,-1
	jnz	@@8
	mov	eax,BM_Wide[esi]
	mov	Wide,eax
@@8:	cmp	Depth,-1
	jnz	@@9
	mov	eax,BM_Depth[esi]
	mov	Depth,eax
;
;Check for daft width/depth.
;
@@9:	cmp	Wide,0
	js	@@BlitFinished
	jz	@@BlitFinished
	cmp	Depth,0
	js	@@BlitFinished
	jz	@@BlitFinished
;
;Clip offsets/width/depth to fit bitmap.
;
	cmp	XOff,0
	jns	@@0
	mov	eax,XOff
	neg	eax
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	add	XCoord,eax
	mov	XOff,0
;
@@0:	cmp	YOff,0
	jns	@@1
	mov	eax,YOff
	neg	eax
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	add	YCoord,eax
	mov	YOff,0
;
@@1:	mov	eax,XOff
	add	eax,Wide
	cmp	eax,BM_Wide[esi]
	jl	@@2
	sub	eax,BM_Wide[esi]
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
@@2:	mov	eax,YOff
	add	eax,Depth
	cmp	eax,BM_Depth[esi]
	jl	@@3
	sub	eax,BM_Depth[esi]
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
;Clip coords/width/depth to fit the screen.
;
@@3:	cmp	XCoord,0
	jns	@@4
	mov	eax,XCoord
	neg	eax
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	add	XOff,eax
	mov	XCoord,0
;
@@4:	cmp	YCoord,0
	jns	@@5
	mov	eax,YCoord
	neg	eax
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	add	YOff,eax
	mov	YCoord,0
;
@@5:	mov	eax,XCoord
	add	eax,Wide
	cmp	eax,VideoXResolution
	jl	@@6
	sub	eax,VideoXResolution
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
@@6:	mov	eax,YCoord
	add	eax,Depth
	cmp	eax,VideoYResolution
	jl	@@7
	sub	eax,VideoYResolution
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
;Now work out the source address and width.
;
@@7:	mov	eax,Bitmap
	add	eax,size BM
	mov	@@Source,eax
	mov	eax,YOff
	mul	BM_PWide[esi]
	mul	BM_Wide[esi]
	add	@@Source,eax
	mov	eax,XOff
	mul	BM_PWide[esi]
	add	@@Source,eax
;
;Work out the destination address.
;
	mov	eax,YCoord
	mul	VideoHardwareWidth
	mov	@@Dest,eax
	mov	eax,XCoord
	mul	VideoPixelWidth
	add	@@Dest,eax
;
;Remove mouse if installed.
;
	push	ebp
	mov	eax,0		;setting it.
	mov	ecx,XCoord
	mov	ebx,YCoord
	mov	edx,Wide
	mov	ebp,Depth
	call	MouseExcludeCall
	pop	ebp
	mov	@@MouseHandle,ebx
;
;Start copying.
;
	mov	edi,@@Dest
	mov	esi,@@Source
@@CarryON:	bank	edi		;make sure we start in the right bank.
;
;work out line we split on in this bank.
;
	mov	eax,edi		;get current destination.
	mov	ax,-1		;and extremity in low word.
	mov	ecx,VideoHardwareWidth	;width of each line.
	xor	edx,edx
	div	ecx		;get last Y coord.
	mov	@@YBreak,eax		;line on which to break.
	cmp	eax,YCoord
	jnz	@@GetDepth
	mov	@@Depth,1
	jmp	@@ok0
;
;Now work out how much of this block we can do as normal.
;
@@GetDepth:	sub	eax,YCoord		;get distance from current position.
	jz	@@Force
	js	@@Force
	mov	@@Depth,eax		;and set depth.
	cmp	eax,Depth		;>than remaining depth?
	jc	@@ok0
@@Force:	mov	eax,Depth		;get whats left.
	mov	@@Depth,eax
@@ok0:	cmp	@@Depth,0
	jz	@@BlitDone
	js	@@BlitDone
	mov	ebx,YCoord
	xor	ebx,@@YBreak
	mov	ecx,Wide
	mov	edx,@@Depth
;
;Select appropriate method.
;
	test	Flags,2
	jz	@@PUT
;
;Now select appropriate blit routine.
;
@@PUTOR:	push	es
	push	ebp
	mov	es,VideoSelector
	mov	ebp,Bitmap
	mov	eax,VideoModeFlags
	and	eax,15
	call	d[PutOrRoutines+eax*4]
	pop	ebp
	pop	es
	jmp	@@BlitNext
;
;Now select appropriate blit routine.
;
@@PUT:	push	es
	push	ebp
	mov	es,VideoSelector
	mov	ebp,Bitmap
	mov	eax,VideoModeFlags
	and	eax,15
	call	d[PutRoutines+eax*4]
	pop	ebp
	pop	es
;
;Move onto next section.
;
@@BlitNext:	mov	eax,@@Depth
	add	YCoord,eax
	sub	Depth,eax
	jnz	@@CarryON
;
;Common exits for all of them.
;
@@BlitDone:	mov	ebx,@@MouseHandle
	mov	eax,1
	call	MouseExcludeCall
;
;Common exit for not on screen.
;
@@BlitFinished:
	popad
	ret
VideoPutBitmap	endp


;-------------------------------------------------------------------------
;
;Blit a bitmap from video memory.
;
;On Entry:
;
;C style stack with following parameters,
;
;flags	- flags, bit significant if set.
;	0 - blit video to system memory.
;	1 - OR bitmap on, chroma value is used.
;bitmap	- pointer to bitmap.
;xcoord	- X co-ord to blit at.
;ycoord	- Y co-ord to blit at.
;xoff	- X offset within bitmap.
;yoff	- Y offset within bitmap.
;wide	- width to blit.
;depth	- depth to blit.
;chroma	- chroma value to use when OR'ing.
;
;On Exit:
;
;nothing.
;
;ALL registers preserved.
;
;Note: If bit 0 of flags is set all other flag bits are ignored.
;
VideoGetBitmap	proc syscall Flags:dword, Bitmap:dword, XCoord:dword, \
	YCoord:dword, XOff:dword, YOff:dword, Wide:dword, \
	Depth:dword, Chroma:dword
	local	@@Source:dword, @@Dest:dword, @@MouseHandle:dword, \
	@@YBreak:dword, @@Depth:dword
	pushad
;
;Check for daft width/depth.
;
	cmp	Wide,0
	js	@@BlitFinished
	jz	@@BlitFinished
	cmp	Depth,0
	js	@@BlitFinished
	jz	@@BlitFinished
;
;Clip offsets/width/depth to fit bitmap.
;
	mov	esi,Bitmap
	cmp	XOff,0
	jns	@@0
	mov	eax,XOff
	neg	eax
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	mov	XOff,0
;
@@0:	cmp	YOff,0
	jns	@@1
	mov	eax,YOff
	neg	eax
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	mov	YOff,0
;
@@1:	mov	eax,XOff
	add	eax,Wide
	cmp	eax,BM_Wide[esi]
	jl	@@2
	sub	eax,BM_Wide[esi]
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
@@2:	mov	eax,YOff
	add	eax,Depth
	cmp	eax,BM_Depth[esi]
	jl	@@3
	sub	eax,BM_Depth[esi]
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
;Clip coords/width/depth to fit the screen.
;
@@3:	cmp	XCoord,0
	jns	@@4
	mov	eax,XCoord
	neg	eax
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	add	XOff,eax
	mov	XCoord,0
;
@@4:	cmp	YCoord,0
	jns	@@5
	mov	eax,YCoord
	neg	eax
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
	add	YOff,eax
	mov	YCoord,0
;
@@5:	mov	eax,XCoord
	add	eax,Wide
	cmp	eax,VideoXResolution
	jl	@@6
	sub	eax,VideoXResolution
	sub	Wide,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
@@6:	mov	eax,YCoord
	add	eax,Depth
	cmp	eax,VideoYResolution
	jl	@@7
	sub	eax,VideoYResolution
	sub	Depth,eax
	js	@@BlitFinished
	jz	@@BlitFinished
;
;Now work out the destination address and width.
;
@@7:	mov	eax,Bitmap
	add	eax,size BM
	mov	@@Dest,eax
	mov	eax,YOff
	mul	BM_PWide[esi]
	mul	BM_Wide[esi]
	add	@@Dest,eax
	mov	eax,XOff
	mul	BM_PWide[esi]
	add	@@Dest,eax
;
;Work out the source address.
;
	mov	eax,YCoord
	mul	VideoHardwareWidth
	mov	@@Source,eax
	mov	eax,XCoord
	mul	VideoPixelWidth
	add	@@Source,eax
;
;Remove mouse if installed.
;
	push	ebp
	mov	eax,0		;setting it.
	mov	ecx,XCoord
	mov	ebx,YCoord
	mov	edx,Wide
	mov	ebp,Depth
	call	MouseExcludeCall
	pop	ebp
	mov	@@MouseHandle,ebx
;
;Start copying.
;
	mov	edi,@@Dest
	mov	esi,@@Source
@@CarryON:	bank	esi		;make sure we start in the right bank.
;
;work out line we split on in this bank.
;
	mov	eax,esi		;get current destination.
	mov	ax,-1		;and extremity in low word.
	mov	ecx,VideoHardwareWidth	;width of each line.
	xor	edx,edx
	div	ecx		;get last Y coord.
	mov	@@YBreak,eax		;line on which to break.
	cmp	eax,YCoord
	jnz	@@GetDepth
	mov	@@Depth,1
	jmp	@@ok0
;
;Now work out how much of this block we can do as normal.
;
@@GetDepth:	sub	eax,YCoord		;get distance from current position.
	jz	@@Force
	js	@@Force
	mov	@@Depth,eax		;and set depth.
	cmp	eax,Depth		;>than remaining depth?
	jc	@@ok0
@@Force:	mov	eax,Depth		;get whats left.
	mov	@@Depth,eax
@@ok0:	cmp	@@Depth,0
	jz	@@BlitDone
	js	@@BlitDone
	mov	ebx,YCoord
	xor	ebx,@@YBreak
	mov	ecx,Wide
	mov	edx,@@Depth
;
;Now select appropriate blit routine.
;
	push	es
	push	ebp
	mov	es,VideoSelector
	mov	ebp,Bitmap
	mov	eax,VideoModeFlags
	and	eax,15
	call	d[GetRoutines+eax*4]
	pop	ebp
	pop	es
;
;Move onto next section.
;
@@BlitNext:	mov	eax,@@Depth
	add	YCoord,eax
	sub	Depth,eax
	jnz	@@CarryON
;
;Common exits for all of them.
;
@@BlitDone:	mov	ebx,@@MouseHandle
	mov	eax,1
	call	MouseExcludeCall
;
;Common exit for not on screen.
;
@@BlitFinished:
	popad
	ret
VideoGetBitmap	endp


;-------------------------------------------------------------------------
;
;Blit a bitmap in 256 colour mode.
;
;On Entry:
;
;EBX	- state, 0=broken, !=0=clean.
;ECX	- width.
;EDX	- depth.
;ESI	- source.
;EDI	- destination.
;EBP	- Bitmap (BM) header.
;
vPutBitmap256	proc	near
	push	edx
	mov	eax,BM_Wide[ebp]
	mul	BM_PWide[ebp]
	pop	edx
	mov	ebp,BM_Flags[ebp]
	xchg	ebp,eax
	and	eax,15
	jz	@@256
	dec	eax
	jz	@@32k
	dec	eax
	jz	@@64k
	dec	eax
	jz	@@16m
	jmp	@@9
;
;256 colour bitmap.
;
@@256:	or	ebx,ebx
	jz	@@b256
	sub	edi,d[CurrentBankBig]
@@256_0:	pushm	ecx,esi,edi
	rep_movsb
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	dec	edx
	jnz	@@256_0
	add	edi,d[CurrentBankBig]
	jmp	@@9
;
@@b256:	pushm	ecx,esi,edi
	sub	edi,d[CurrentBankBig]
	movsx	eax,di
	neg	eax
	cmp	eax,ecx
	jc	@@b256_1
	mov	eax,ecx
@@b256_1:	push	ecx
	mov	ecx,eax
	rep_movsb
	pop	ecx
	sub	ecx,eax
	jz	@@b256_2
	;
	add	edi,d[CurrentBankBig]
	bank	edi
	sub	edi,d[CurrentBankBig]
	rep_movsb
	;
@@b256_2:	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	jmp	@@9
;
;32k colour bitmap.
;
@@32k:	or	ebx,ebx
	jz	@@b32k
	sub	edi,d[CurrentBankBig]
@@32k_0:	pushm	ecx,esi,edi
@@32k_1:	lodsw
	mov	ebx,eax
	shl	ebx,16+1
	shld	eax,ebx,5
	shl	eax,3
	shl	ebx,5
	shld	eax,ebx,5
	shl	eax,3
	shl	ebx,5
	shld	eax,ebx,5
	shl	eax,3
;	call	SearchRGB
	stosb
	loop	@@32k_1
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	dec	edx
	jnz	@@32k_0
	add	edi,d[CurrentBankBig]
	jmp	@@9
;
@@b32k:	pushm	ecx,esi,edi
@@b32k_0:	bank	edi
	sub	edi,d[CurrentBankBig]
	lodsw
	mov	ebx,eax
	shl	ebx,16+1
	shld	eax,ebx,5
	shl	eax,3
	shl	ebx,5
	shld	eax,ebx,5
	shl	eax,3
	shl	ebx,5
	shld	eax,ebx,5
	shl	eax,3
;	call	SearchRGB
	stosb
	add	edi,d[CurrentBankBig]
	dec	ecx
	jnz	@@b32k_0
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	jmp	@@9
;
;64k colour bitmap.
;
@@64k:	or	ebx,ebx
	jz	@@b64k
	sub	edi,d[CurrentBankBig]
@@64k_0:	pushm	ecx,esi,edi
@@64k_1:	lodsw
	mov	ebx,eax
	shl	ebx,16
	shld	eax,ebx,5
	shl	eax,3
	shl	ebx,5
	shld	eax,ebx,6
	shl	eax,2
	shl	ebx,6
	shld	eax,ebx,5
	shl	eax,3
;	call	SearchRGB
	stosb
	dec	ecx
	jnz	@@64k_1
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	dec	edx
	jnz	@@64k_0
	add	edi,d[CurrentBankBig]
	jmp	@@9
;
@@b64k:	pushm	ecx,esi,edi
@@b64k_0:	bank	edi
	sub	edi,d[CurrentBankBig]
	lodsw
	mov	ebx,eax
	shl	ebx,16
	shld	eax,ebx,5
	shl	eax,3
	shl	ebx,5
	shld	eax,ebx,6
	shl	eax,2
	shl	ebx,6
	shld	eax,ebx,5
	shl	eax,3
;	call	SearchRGB
	stosb
	add	edi,d[CurrentBankBig]
	dec	ecx
	jnz	@@b64k_0
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	jmp	@@9
;
;16m colour bitmap.
;
@@16m:	or	ebx,ebx
	jz	@@b16m
	sub	edi,d[CurrentBankBig]
@@16m_0:	pushm	ecx,esi,edi
@@16m_1:	lodsd
	dec	esi

	or	ah,al
	shr	eax,8
	or	al,ah

;	call	SearchRGB

	stosb
	dec	ecx
	jnz	@@16m_1
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	dec	edx
	jnz	@@16m_0
	add	edi,d[CurrentBankBig]
	jmp	@@9
;
@@b16m:	pushm	ecx,esi,edi
@@b16m_0:	bank	edi
	sub	edi,d[CurrentBankBig]
	lodsd
	dec	esi

	or	ah,al
	shr	eax,8
	or	al,ah

;	call	SearchRGB

	stosb
	add	edi,d[CurrentBankBig]
	dec	ecx
	jnz	@@b16m_0
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
;
@@9:	ret
vPutBitmap256	endp


;-------------------------------------------------------------------------
;
;Blit a bitmap in 32k colour mode.
;
;On Entry:
;
;EBX	- state, 0=broken, !=0=clean.
;ECX	- width.
;EDX	- depth.
;ESI	- source.
;EDI	- destination.
;EBP	- Bitmap (BM) header.
;
vPutBitmap32k	proc	near
	push	edx
	mov	eax,BM_Wide[ebp]
	mul	BM_PWide[ebp]
	pop	edx
	mov	ebp,BM_Flags[ebp]
	xchg	ebp,eax
	and	eax,15
	jz	@@256
	dec	eax
	jz	@@32k
	dec	eax
	jz	@@64k
	dec	eax
	jz	@@16m
	jmp	@@9
;
;256 colour bitmap.
;
@@256:	or	ebx,ebx
	jz	@@b256
	sub	edi,d[CurrentBankBig]
@@256_0:	pushm	ecx,esi,edi
@@256_1:	xor	eax,eax
	lodsb
	mov	eax,d[HardwarePalette+eax+eax*2]
	mov	bl,al
	shr	eax,8
	xchg	ah,bl
	shl	eax,8
	mov	al,bl
	mov	ebx,eax
	shl	ebx,2+8		;Convert 0-63 value to 0-255 value.
	xor	eax,eax
	shld	eax,ebx,5
	shl	ebx,8
	shld	eax,ebx,5
	shl	ebx,8
	shld	eax,ebx,5
	stosw
	dec	ecx
	jnz	@@256_1
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	dec	edx
	jnz	@@256_0
	add	edi,d[CurrentBankBig]
	jmp	@@9
;
@@b256:	pushm	ecx,esi,edi
@@b256_0:	bank	edi
	sub	edi,d[CurrentBankBig]
	xor	eax,eax
	lodsb
	mov	eax,d[HardwarePalette+eax+eax*2]
	mov	bl,al
	shr	eax,8
	xchg	ah,bl
	shl	eax,8
	mov	al,bl
	mov	ebx,eax
	shl	ebx,2+8		;Convert 0-63 value to 0-255 value.
	xor	eax,eax
	shld	eax,ebx,5
	shl	ebx,8
	shld	eax,ebx,5
	shl	ebx,8
	shld	eax,ebx,5
	stosw
	add	edi,d[CurrentBankBig]
	dec	ecx
	jnz	@@b256_0
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	jmp	@@9
;
;32k colour version.
;
@@32k:	or	ebx,ebx
	jz	@@b32k
	sub	edi,d[CurrentBankBig]
@@32k_0:	pushm	ecx,esi,edi
	rep_movsw
	popm	ecx,esi,edi
	add	esi,ebp
	add	edi,VideoHardwareWidth
	dec	edx
	jnz	@@32k_0
	add	edi,d[CurrentBankBig]
	jmp	@@9
;
@@b32k:	pushm	ecx,esi,edi

⌨️ 快捷键说明

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