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 + -
显示快捷键?