f05dc678f0
which included commits to RCS files with non-trunk default branches.
926 lines
17 KiB
NASM
926 lines
17 KiB
NASM
; THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
|
|
; SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
|
|
; END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
|
|
; ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
|
|
; IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
|
|
; SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
|
|
; FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
|
|
; CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
|
|
; AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
|
|
; COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|
.386
|
|
|
|
OPTION OLDSTRUCTS
|
|
INCLUDE VGAREGS.INC
|
|
INCLUDE GR.INC
|
|
|
|
_DATA SEGMENT BYTE PUBLIC USE32 'DATA'
|
|
|
|
PUBLIC __A0000
|
|
__A0000 dw ?
|
|
|
|
BufferPtr dd 0
|
|
BufferSeg dw 0
|
|
GoalMode dw ?
|
|
LastPage db 0FFh
|
|
|
|
BPR dw ?
|
|
TempReg dd ?
|
|
|
|
; Information from VESA return SuperVGA Information
|
|
|
|
VESAVersion dw ?
|
|
OEMStringPtr dd ?
|
|
Capabilities dd ?
|
|
VideoModePtr dd ?
|
|
TotalMemory dw ?
|
|
WinGranularity dw ?
|
|
WinSize dw ?
|
|
WinFuncPtr dd ?
|
|
PageSizeShift db ?
|
|
WinAttributes dw ?
|
|
|
|
|
|
VESA_Signature = 041534556h
|
|
|
|
REALREGS STRUCT
|
|
RealEDI dd ?
|
|
RealESI dd ?
|
|
RealEBP dd ?
|
|
Reserved dd ?
|
|
RealEBX dd ?
|
|
RealEDX dd ?
|
|
RealECX dd ?
|
|
RealEAX dd ?
|
|
RealFlags dw ?
|
|
RealES dw ?
|
|
RealDS dw ?
|
|
RealFS dw ?
|
|
RealGS dw ?
|
|
RealIP dw ?
|
|
RealCS dw ?
|
|
RealSP dw ?
|
|
RealSS dw ?
|
|
REALREGS ENDS
|
|
|
|
regs REALREGS < >
|
|
|
|
vesa_error dd ?
|
|
SourceInc dd ?
|
|
DestInc dw ?
|
|
RowWidth dd ?
|
|
|
|
extern _gr_var_color:dword, _gr_var_bwidth:dword
|
|
|
|
|
|
_DATA ENDS
|
|
|
|
DGROUP GROUP _DATA
|
|
|
|
|
|
_TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
|
|
|
|
ASSUME DS:_DATA
|
|
ASSUME CS:_TEXT
|
|
|
|
MyStosd MACRO Width:REQ
|
|
; Assumes: EDI = Dest Address
|
|
; Width = a 32-bit value, can't be ECX or EDI
|
|
; Trashes: ECX will be zero
|
|
; EDI = Dest Address + Width
|
|
; EDX = ????
|
|
; Width
|
|
LOCAL Aligned
|
|
cmp Width, 16
|
|
jbe Aligned
|
|
mov ecx, edi
|
|
and ecx, 3
|
|
jcxz Aligned
|
|
neg ecx
|
|
add ecx, 4
|
|
sub Width, ecx
|
|
rep stosb
|
|
Aligned: mov ecx, Width
|
|
shr ecx, 2
|
|
rep stosd
|
|
mov ecx, Width
|
|
and ecx, 3
|
|
rep stosb
|
|
ENDM
|
|
|
|
|
|
ENTER_PROC MACRO
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
push eax
|
|
push ebx
|
|
push ecx
|
|
push edx
|
|
ENDM
|
|
|
|
EXIT_PROC MACRO
|
|
|
|
cmp [esp-4], edx
|
|
je @f
|
|
; YOU TRASHED EDX !!!!!!!
|
|
int 3
|
|
@@: pop edx
|
|
|
|
cmp [esp-4], ecx
|
|
je @f
|
|
; YOU TRASHED ECX !!!!!!!
|
|
int 3
|
|
@@: pop ecx
|
|
|
|
cmp [esp-4], ebx
|
|
je @f
|
|
; YOU TRASHED EBX !!!!!!!
|
|
int 3
|
|
@@: pop ebx
|
|
|
|
cmp [esp-4], eax
|
|
je @f
|
|
; YOU TRASHED EAX !!!!!!!
|
|
int 3
|
|
@@: pop eax
|
|
|
|
cmp [esp-4], ebp
|
|
je @f
|
|
; YOU TRASHED EBP !!!!!!!
|
|
int 3
|
|
@@: pop ebp
|
|
|
|
cmp [esp-4], edi
|
|
je @f
|
|
; YOU TRASHED EDI !!!!!!!
|
|
int 3
|
|
@@: pop edi
|
|
|
|
cmp [esp-4], esi
|
|
je @f
|
|
; YOU TRASHED ESI !!!!!!!
|
|
int 3
|
|
@@: pop esi
|
|
|
|
ENDM
|
|
|
|
|
|
MyMovsd MACRO Width:REQ
|
|
; Assumes: EDI = Dest Address
|
|
; ESI = Source Address
|
|
; Width = a 32-bit value, can't be ECX or EDI or ESI
|
|
; Assumes that ESI is already aligned
|
|
; Trashes: ECX will be zero
|
|
; EDI = Dest Address + Width
|
|
; ESI = Source Address + Width
|
|
; EDX = ????
|
|
LOCAL Aligned
|
|
cmp Width, 16
|
|
jbe Aligned
|
|
mov ecx, edi
|
|
and ecx, 3
|
|
jcxz Aligned
|
|
neg ecx
|
|
add ecx, 4
|
|
sub Width, ecx
|
|
rep movsb
|
|
Aligned: mov ecx, Width
|
|
shr ecx, 2
|
|
rep movsd
|
|
mov ecx, Width
|
|
and ecx, 3
|
|
rep movsb
|
|
ENDM
|
|
|
|
|
|
EBXFarTo32:
|
|
push ecx
|
|
mov ecx, ebx
|
|
and ecx, 0FFFF0000h
|
|
shr ecx, 12
|
|
and ebx, 0FFFFh
|
|
add ebx, ecx
|
|
pop ecx
|
|
ret
|
|
|
|
PUBLIC gr_init_A0000_
|
|
|
|
gr_init_A0000_:
|
|
|
|
push ebx
|
|
mov ax, 0002h
|
|
mov bx, 0a000h
|
|
int 31h
|
|
jc NoGo
|
|
mov __A0000, ax
|
|
pop ebx
|
|
xor eax, eax
|
|
ret
|
|
NoGo: pop ebx
|
|
mov eax, 1
|
|
ret
|
|
|
|
PUBLIC gr_vesa_checkmode_
|
|
|
|
gr_vesa_checkmode_:
|
|
pushad
|
|
|
|
mov GoalMode, ax
|
|
cmp BufferSeg, 0
|
|
jne GotDosMemory
|
|
|
|
; Allocate a 256 byte block of DOS memory using DPMI
|
|
mov ax, 0100h
|
|
mov bx, 16
|
|
int 31h
|
|
jc NoMemory
|
|
|
|
; AX = real mode segment of allocated block
|
|
and eax, 0FFFFh
|
|
mov BufferSeg, ax
|
|
shl eax, 4 ; EAX = 32-bit pointer to DOS memory
|
|
mov BufferPtr, eax
|
|
GotDosMemory:
|
|
|
|
|
|
; Get SuperVGA information
|
|
mov ax, BufferSeg
|
|
mov regs.RealEDI, 0
|
|
mov regs.RealESI, 0
|
|
mov regs.RealEBP, 0
|
|
mov regs.Reserved, 0
|
|
mov regs.RealEBX, 0
|
|
mov regs.RealEDX, 0
|
|
mov regs.RealECX, 0
|
|
mov regs.RealEAX, 04f00h
|
|
mov regs.RealFlags, 0
|
|
mov regs.RealES, ax
|
|
mov regs.RealDS, 0
|
|
mov regs.RealFS, 0
|
|
mov regs.RealGS, 0
|
|
mov regs.RealIP, 0
|
|
mov regs.RealCS, 0
|
|
mov regs.RealSP, 0
|
|
mov regs.RealSS, 0
|
|
|
|
mov bl, 10h
|
|
xor bh, bh
|
|
xor ecx, ecx
|
|
mov edi, offset regs
|
|
mov ax, 0300h
|
|
int 31h
|
|
|
|
mov eax, regs.RealEAX
|
|
cmp ax, 04fh
|
|
jne NoVESADriver
|
|
|
|
; Make sure there is a VESA signature
|
|
mov eax, BufferPtr
|
|
cmp dword ptr[eax+0], VESA_Signature
|
|
jne NoVESADriver
|
|
|
|
; We now have a valid VESA driver loaded
|
|
|
|
mov bx, word ptr [eax+4]
|
|
mov VESAVersion, bx
|
|
|
|
mov ebx, dword ptr [eax+6]
|
|
call EBXFarTo32
|
|
mov OEMStringPtr, ebx
|
|
|
|
mov ebx, dword ptr [eax+10]
|
|
mov Capabilities, ebx
|
|
|
|
mov bx, word ptr [eax+18]
|
|
mov TotalMemory, bx
|
|
|
|
mov ebx, dword ptr [eax+14]
|
|
call EBXFarTo32
|
|
mov VideoModePtr, ebx
|
|
|
|
TryAnotherMode:
|
|
mov ax, word ptr [ebx]
|
|
add ebx, 2
|
|
cmp ax, GoalMode
|
|
je ModeSupported
|
|
cmp ax, -1
|
|
je ModeNotSupported
|
|
jmp TryAnotherMode
|
|
|
|
ModeSupported:
|
|
|
|
; Get SuperVGA information
|
|
mov ax, BufferSeg
|
|
movzx ecx, GoalMode
|
|
mov regs.RealEDI, 0
|
|
mov regs.RealESI, 0
|
|
mov regs.RealEBP, 0
|
|
mov regs.Reserved, 0
|
|
mov regs.RealEBX, 0
|
|
mov regs.RealEDX, 0
|
|
mov regs.RealECX, ecx
|
|
mov regs.RealEAX, 04f01h
|
|
mov regs.RealFlags, 0
|
|
mov regs.RealES, ax
|
|
mov regs.RealDS, 0
|
|
mov regs.RealFS, 0
|
|
mov regs.RealGS, 0
|
|
mov regs.RealIP, 0
|
|
mov regs.RealCS, 0
|
|
mov regs.RealSP, 0
|
|
mov regs.RealSS, 0
|
|
|
|
mov bl, 10h
|
|
xor bh, bh
|
|
xor cx, cx
|
|
mov edi, offset regs
|
|
mov ax, 0300h
|
|
int 31h
|
|
|
|
mov eax, regs.RealEAX
|
|
cmp ax, 04fh
|
|
jne BadStatus
|
|
|
|
; Check if this mode supported by hardware.
|
|
mov eax, BufferPtr
|
|
mov bx, [eax]
|
|
bt bx, 0
|
|
jnc HardwareNotSupported
|
|
|
|
|
|
mov bx, [eax+4]
|
|
cmp bx, 64
|
|
jne @f
|
|
mov PageSizeShift, 0
|
|
jmp GranularityOK
|
|
@@: cmp bx, 32
|
|
jne @f
|
|
mov PageSizeShift, 1
|
|
jmp GranularityOK
|
|
@@: cmp bx, 16
|
|
jne @f
|
|
mov PageSizeShift, 2
|
|
jmp GranularityOK
|
|
@@: cmp bx, 8
|
|
jne @f
|
|
mov PageSizeShift, 3
|
|
jmp GranularityOK
|
|
@@: cmp bx, 4
|
|
jne @f
|
|
mov PageSizeShift, 4
|
|
jmp GranularityOK
|
|
@@: cmp bx, 2
|
|
jne @f
|
|
mov PageSizeShift, 5
|
|
jmp GranularityOK
|
|
@@: cmp bx, 1
|
|
jne WrongGranularity
|
|
mov PageSizeShift, 6
|
|
|
|
GranularityOK:
|
|
shl bx, 10
|
|
mov WinGranularity, bx
|
|
|
|
mov bx, [eax+6]
|
|
mov WinSize, bx
|
|
|
|
mov ebx, [eax+12]
|
|
call EBXFarTo32
|
|
mov WinFuncPtr, ebx
|
|
|
|
mov bl, byte ptr [eax+2]
|
|
mov bh, byte ptr [eax+3]
|
|
mov word ptr WinAttributes, bx
|
|
|
|
movzx ebx, word ptr [eax+16]
|
|
|
|
NoError:
|
|
mov vesa_error, 0
|
|
jmp Done
|
|
|
|
WrongGranularity:
|
|
mov vesa_error, 2
|
|
jmp Done
|
|
|
|
HardwareNotSupported:
|
|
mov vesa_error, 3
|
|
jmp Done
|
|
|
|
ModeNotSupported:
|
|
mov vesa_error, 4
|
|
jmp Done
|
|
|
|
NoVESADriver:
|
|
mov vesa_error, 5
|
|
jmp Done
|
|
|
|
BadStatus:
|
|
mov vesa_error, 6
|
|
jmp Done
|
|
|
|
NoMemory:
|
|
mov vesa_error, 7
|
|
jmp Done
|
|
|
|
DPMIError:
|
|
mov vesa_error, 8
|
|
|
|
Done: popad
|
|
mov eax, vesa_error
|
|
|
|
ret
|
|
|
|
PUBLIC gr_get_dos_mem_
|
|
|
|
gr_get_dos_mem_:
|
|
|
|
; eax = how many bytes
|
|
|
|
push ebx
|
|
|
|
mov ebx, eax
|
|
shr ebx, 4
|
|
mov eax, 0100h
|
|
int 31h
|
|
jc nomem
|
|
and eax, 0ffffh
|
|
shl eax, 4
|
|
pop ebx
|
|
ret
|
|
|
|
nomem: pop ebx
|
|
mov eax,0
|
|
ret
|
|
|
|
|
|
|
|
|
|
PUBLIC gr_vesa_setmodea_
|
|
|
|
gr_vesa_setmodea_:
|
|
|
|
; eax = mode
|
|
pushad
|
|
mov LastPage,0ffh ;force page reset
|
|
mov ebx, eax
|
|
mov eax, 04f02h
|
|
int 10h
|
|
cmp ax, 04fh
|
|
jne BadStatus
|
|
jmp NoError
|
|
|
|
PUBLIC gr_vesa_setpage_
|
|
|
|
gr_vesa_setpage_:
|
|
|
|
; EAX = 64K Page number
|
|
and eax, 0ffh
|
|
cmp al, LastPage
|
|
jne @f
|
|
ret
|
|
@@: mov LastPage, al
|
|
push edx
|
|
push ebx
|
|
push ecx
|
|
mov edx, eax
|
|
mov cl, PageSizeShift
|
|
shl edx, cl ; Convert from 64K pages to GranUnit pages.
|
|
push edx
|
|
xor ebx, ebx ; BH=Select window, BL=Window A
|
|
mov eax, 04f05h ; AX=Super VGA video memory window control
|
|
int 10h
|
|
|
|
; New code to fix those ATI Mach64's with separate
|
|
; read/write pages.
|
|
mov bx, word ptr WinAttributes
|
|
and ebx, 0110b ; Set if PageA can read and write
|
|
cmp ebx, 0110b
|
|
jne WinACantReadAndWrite
|
|
pop edx
|
|
pop ecx
|
|
pop ebx
|
|
pop edx
|
|
ret
|
|
|
|
WinACantReadAndWrite: ; Page A can't read and write, so we need to update page B also!
|
|
pop edx ; DX=Window
|
|
mov ebx, 1 ; BH=Select window, BL=Window B
|
|
mov eax, 04f05h ; AX=Super VGA video memory window control
|
|
int 10h
|
|
pop ecx
|
|
pop ebx
|
|
pop edx
|
|
ret
|
|
|
|
PUBLIC gr_vesa_incpage_
|
|
|
|
gr_vesa_incpage_:
|
|
push eax
|
|
xor eax, eax
|
|
mov al, LastPage
|
|
inc eax
|
|
call gr_vesa_setpage_
|
|
pop eax
|
|
ret
|
|
|
|
PUBLIC gr_vesa_setstart_
|
|
|
|
gr_vesa_setstart_:
|
|
|
|
; EAX = First column
|
|
; EDX = First row
|
|
push ebx
|
|
push ecx
|
|
mov ecx, eax
|
|
mov eax, 4f07h
|
|
xor ebx, ebx
|
|
int 10h
|
|
pop ecx
|
|
pop ebx
|
|
ret
|
|
|
|
|
|
PUBLIC gr_vesa_setlogical_
|
|
|
|
gr_vesa_setlogical_:
|
|
|
|
; EAX = line width
|
|
push ebx
|
|
push ecx
|
|
push edx
|
|
|
|
mov cx, ax
|
|
mov ax, 04f06h
|
|
mov bl, 0
|
|
int 10h
|
|
and ebx, 0FFFFh
|
|
mov ax, cx
|
|
|
|
pop edx
|
|
pop ecx
|
|
pop ebx
|
|
ret
|
|
|
|
|
|
|
|
PUBLIC gr_vesa_scanline_
|
|
|
|
gr_vesa_scanline_:
|
|
|
|
; EAX = x1
|
|
; EDX = x2
|
|
; EBX = y
|
|
; ECX = color
|
|
|
|
push edi
|
|
cld
|
|
cmp edx, eax
|
|
jge @f
|
|
xchg edx, eax
|
|
|
|
@@: mov edi, ebx
|
|
imul edi, _gr_var_bwidth
|
|
add edi, eax ; EDI = y*bpr+x1
|
|
sub edx, eax ; ECX = x2-x1
|
|
inc edx
|
|
|
|
mov eax, edi
|
|
shr eax, 16
|
|
|
|
call gr_vesa_setpage_
|
|
|
|
and edi, 00FFFFh
|
|
or edi, 0A0000h
|
|
|
|
;mov eax, _Table8to32[ecx*4]
|
|
mov ch, cl
|
|
mov ax, cx
|
|
shl eax, 16
|
|
mov ax, cx
|
|
|
|
; edx = width in bytes
|
|
; edi = dest
|
|
mov bx, dx
|
|
add bx, di
|
|
jnc scanonepage
|
|
|
|
sub dx, bx
|
|
movzx ecx, dx
|
|
|
|
shr ecx, 1
|
|
rep stosw
|
|
adc ecx, ecx
|
|
rep stosb
|
|
|
|
movzx edx, bx
|
|
cmp edx, 0
|
|
je scandone
|
|
|
|
call gr_vesa_incpage_
|
|
mov edi, 0A0000h
|
|
|
|
scanonepage:
|
|
movzx ecx, dx
|
|
|
|
shr ecx, 1
|
|
rep stosw
|
|
adc ecx, ecx
|
|
rep stosb
|
|
|
|
scandone:
|
|
|
|
pop edi
|
|
ret
|
|
|
|
|
|
PUBLIC gr_vesa_set_logical_
|
|
|
|
gr_vesa_set_logical_:
|
|
|
|
; EAX = logical width in pixels
|
|
|
|
push ebx
|
|
push ecx
|
|
|
|
mov ecx, eax
|
|
mov eax, 04f06h
|
|
mov bl, 0
|
|
int 10h
|
|
and ebx, 0ffffh
|
|
|
|
movzx eax, cx
|
|
|
|
pop ecx
|
|
pop ebx
|
|
|
|
ret
|
|
|
|
|
|
PUBLIC gr_vesa_pixel_
|
|
|
|
gr_vesa_pixel_:
|
|
; EAX = color (in AL)
|
|
; EDX = offset from 0A0000
|
|
push ebx
|
|
mov bl, al
|
|
|
|
mov eax, edx
|
|
shr eax, 16
|
|
and edx, 0ffffh
|
|
|
|
call gr_vesa_setpage_
|
|
mov [edx+0A0000h], bl
|
|
pop ebx
|
|
ret
|
|
|
|
PUBLIC gr_vesa_bitblt_
|
|
|
|
gr_vesa_bitblt_:
|
|
|
|
; EAX = source_ptr
|
|
; EDX = vesa_address
|
|
; EBX = height
|
|
; ECX = width
|
|
|
|
push edi
|
|
push esi
|
|
|
|
mov esi, eax ; Point ESI to source bitmap
|
|
|
|
; Set the initial page
|
|
mov eax, edx ; Move offset into SVGA into eax
|
|
shr eax, 16 ; Page = offset / 64K
|
|
call gr_vesa_setpage_
|
|
|
|
mov edi, edx ; EDI = offset into SVGA
|
|
and edi, 0FFFFh ; EDI = offset into 64K page
|
|
add edi, 0A0000h ; EDI = ptr to dest
|
|
|
|
|
|
mov edx, _gr_var_bwidth
|
|
sub edx, ecx ; EDX = amount to step each row
|
|
|
|
|
|
mov eax, ecx
|
|
|
|
NextScanLine:
|
|
push eax
|
|
MyMovsd eax
|
|
pop eax
|
|
|
|
dec ebx
|
|
jz DoneBlt
|
|
|
|
add di, dx
|
|
jnc NextScanLine
|
|
|
|
; Need to increment page!
|
|
call gr_vesa_incpage_
|
|
jmp NextScanLine
|
|
|
|
DoneBlt: pop esi
|
|
pop edi
|
|
|
|
ret
|
|
|
|
PUBLIC gr_vesa_bitmap_
|
|
|
|
gr_vesa_bitmap_:
|
|
|
|
; EAX = Source bitmap (LINEAR)
|
|
; EDX = Destination bitmap (SVGA)
|
|
; EBX = x
|
|
; ECX = y
|
|
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
push es
|
|
|
|
push eax
|
|
mov eax, [edx].bm_data
|
|
imul ecx, _gr_var_bwidth
|
|
add eax, ecx
|
|
add eax, ebx
|
|
mov edi, eax ; EDI = offset into SVGA
|
|
shr eax, 16
|
|
call gr_vesa_setpage_
|
|
|
|
mov ax, __A0000
|
|
mov es, ax
|
|
pop eax
|
|
|
|
mov esi, [eax].bm_data
|
|
and edi, 0ffffh
|
|
|
|
movzx ecx, [eax].bm_h
|
|
|
|
NextScanLine1:
|
|
push ecx
|
|
movzx ecx, [eax].bm_w
|
|
mov bx, cx
|
|
add bx, di
|
|
jnc OnePage
|
|
|
|
sub cx,bx
|
|
mov ebp, ecx
|
|
MyMovsd ebp
|
|
and edi, 00ffffh ; IN CASE IT WENT OVER 64K
|
|
mov cx,bx
|
|
call gr_vesa_incpage_
|
|
jcxz DoneWithLine
|
|
OnePage:
|
|
mov ebp, ecx
|
|
MyMovsd ebp
|
|
and edi, 00ffffh ; IN CASE IT WENT OVER 64K
|
|
|
|
DoneWithLine: mov bx, [eax].bm_rowsize
|
|
sub bx, [eax].bm_w
|
|
and ebx, 0ffffh
|
|
add esi, ebx
|
|
mov bx, [edx].bm_rowsize
|
|
sub bx, [eax].bm_w
|
|
add di, bx
|
|
jnc NoPageInc
|
|
call gr_vesa_incpage_
|
|
NoPageInc: pop ecx
|
|
dec ecx
|
|
jz @f
|
|
jmp NextScanLine1
|
|
|
|
@@:
|
|
|
|
pop es
|
|
pop ebp
|
|
pop edi
|
|
pop esi
|
|
ret
|
|
|
|
|
|
|
|
|
|
PUBLIC gr_vesa_update_
|
|
|
|
gr_vesa_update_:
|
|
|
|
; EAX = Source bitmap (LINEAR)
|
|
; EDX = Destination bitmap (SVGA)
|
|
; EBX = Old source bitmap (LINEAR)
|
|
|
|
push ecx
|
|
push esi
|
|
push edi
|
|
push ebp
|
|
push fs
|
|
|
|
push eax
|
|
mov eax, [edx].bm_data
|
|
mov ebp, eax ; EDI = offset into SVGA
|
|
shr eax, 16
|
|
call gr_vesa_setpage_
|
|
|
|
mov ax, __A0000
|
|
mov fs, ax
|
|
pop eax
|
|
|
|
mov esi, [eax].bm_data
|
|
and ebp, 0ffffh
|
|
|
|
movzx ecx, [eax].bm_h
|
|
|
|
mov edi, [ebx].bm_data
|
|
|
|
movzx ebx, [eax].bm_rowsize
|
|
sub bx, [eax].bm_w
|
|
mov SourceInc, ebx
|
|
|
|
movzx ebx, [edx].bm_rowsize
|
|
sub bx, [eax].bm_w
|
|
mov DestInc, bx
|
|
|
|
movzx ebx, [eax].bm_w
|
|
mov RowWidth, ebx
|
|
|
|
NextScanLine3:
|
|
push ecx
|
|
mov ecx, RowWidth
|
|
mov dx, cx
|
|
add dx, bp
|
|
jnc OnePage3
|
|
|
|
sub cx,dx
|
|
mov ebx, esi
|
|
|
|
InnerLoop3: repe cmpsb
|
|
mov al, [esi-1]
|
|
sub esi, ebx
|
|
mov fs:[ebp+esi-1], al ; EDX = dest + size - bytes to end
|
|
add esi, ebx
|
|
cmp ecx, 0
|
|
jne InnerLoop3
|
|
|
|
sub esi, ebx
|
|
add ebp, esi
|
|
add esi, ebx
|
|
and ebp, 00ffffh ; IN CASE IT WENT OVER 64K
|
|
|
|
mov cx,dx
|
|
call gr_vesa_incpage_
|
|
jcxz DoneWithLine3
|
|
OnePage3:
|
|
mov ebx, esi
|
|
mov edx, ecx
|
|
and edx, 11b
|
|
shr ecx, 2
|
|
|
|
InnerLoop4: repe cmpsd
|
|
mov eax, [esi-4]
|
|
sub esi, ebx
|
|
mov fs:[ebp+esi-4], eax ; EDX = dest + size - bytes to end
|
|
add esi, ebx
|
|
cmp ecx, 0
|
|
jne InnerLoop4
|
|
|
|
mov ecx, edx
|
|
jecxz EvenWidth
|
|
InnerLoop5: repe cmpsb
|
|
mov al, [esi-1]
|
|
sub esi, ebx
|
|
mov fs:[ebp+esi-1], al ; EDX = dest + size - bytes to end
|
|
add esi, ebx
|
|
cmp ecx, 0
|
|
jne InnerLoop5
|
|
|
|
EvenWidth: sub esi, ebx
|
|
add ebp, esi
|
|
add esi, ebx
|
|
and ebp, 00ffffh ; IN CASE IT WENT OVER 64K
|
|
|
|
DoneWithLine3:
|
|
add esi, SourceInc
|
|
add edi, SourceInc
|
|
add bp, DestInc
|
|
jnc NoPageInc3
|
|
call gr_vesa_incpage_
|
|
NoPageInc3: pop ecx
|
|
dec ecx
|
|
jnz NextScanLine3
|
|
|
|
pop fs
|
|
pop ebp
|
|
pop edi
|
|
pop esi
|
|
pop ecx
|
|
ret
|
|
|
|
|
|
|
|
|
|
_TEXT ENDS
|
|
|
|
|
|
END
|
|
|
|
|