home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga ACS 1998 #6
/
amigaacscoverdisc1998-061998.iso
/
games
/
descent
/
source
/
2d
/
vesa.asm
< prev
next >
Wrap
Assembly Source File
|
1998-06-08
|
21KB
|
1,029 lines
;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-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
;
; $Source: f:/miner/source/2d/rcs/vesa.asm $
; $Revision: 1.20 $
; $Author: john $
; $Date: 1994/07/27 15:43:37 $
;
; Routines to access VESA VGA memory
;
; $Log: vesa.asm $
; Revision 1.20 1994/07/27 15:43:37 john
; Fixed bug with allocation dos memory more than once.
;
; Revision 1.19 1994/06/24 17:27:02 john
; Made rowsizes bigger than actual screen work with SVGA.
;
; Revision 1.18 1994/05/31 11:10:45 john
; *** empty log message ***
;
; Revision 1.17 1994/05/06 12:50:21 john
; Added supertransparency; neatend things up; took out warnings.
;
; Revision 1.16 1994/03/14 16:56:29 john
; Changed grs_bitmap structure to include bm_flags.
;
; Revision 1.15 1994/02/02 11:27:22 john
; *** empty log message ***
;
; Revision 1.14 1994/01/25 11:40:46 john
; Added gr_check_mode function.
;
; Revision 1.13 1994/01/13 14:41:51 unknown
; Fixed bug with Error 7 return Error 8.
;
; Revision 1.12 1993/12/21 19:58:38 john
; made rep movsb in scanline be rep movsw
;
; Revision 1.11 1993/12/09 16:05:51 john
; Made no VESA driver detection work correctly
;
; Revision 1.10 1993/12/09 15:02:41 john
; Changed palette stuff majorly
;
; Revision 1.9 1993/11/16 11:28:28 john
; *** empty log message ***
;
; Revision 1.8 1993/10/26 13:18:03 john
; *** empty log message ***
;
; Revision 1.7 1993/10/15 16:23:28 john
; y
;
; Revision 1.6 1993/09/29 17:31:10 john
; optimized gr_vesa_pixel
;
; Revision 1.5 1993/09/26 18:59:34 john
; fade stuff
;
; Revision 1.4 1993/09/20 14:47:20 john
; *** empty log message ***
;
; Revision 1.3 1993/09/13 17:54:07 john
; Minor bug fix
;
; Revision 1.2 1993/09/08 15:56:06 john
; Started adding DPMI support for SVGA paging.
;
; Revision 1.1 1993/09/08 11:41:25 john
; Initial revision
;
;
;
.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 ?
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
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 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
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.
xor ebx, ebx ; BH=Select window, BL=Window A
mov eax, 04f05h ; AX=Super VGA video memory window control
int 10h
pop ecx
pop ebx
pop edx
ret
PUBLIC gr_vesa_setaddress_
gr_vesa_setaddress_:
; EAX = Address of video memory to write to
push edx
push ebx
push ecx
mov edx, eax
shl edx, 12 ; Convert from address pages to 4k GranUnit pages.
xor ebx, ebx ; BH=Select window, BL=Window A
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
push ebx
push ecx
push edx
push ebp
inc LastPage
mov dl, LastPage
mov cl, PageSizeShift
shl edx, cl ; Convert from 64K pages to GranUnit pages.
xor ebx, ebx ; BH=Select window, BL=Window A
mov eax, 04f05h ; AX=Super VGA video memory window control
int 10h
pop ebp
pop edx
pop ecx
pop ebx
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
cmp al, LastPage
je @f
mov LastPage, al
push edx
push ecx
mov edx, eax
mov cl, PageSizeShift
shl edx, cl ; Convert from 64K pages to GranUnit pages.
xor ebx, ebx ; BH=Select window, BL=Window A
mov eax, 04f05h ; AX=Super VGA video memory window control
int 10h
pop ecx
pop edx
@@: 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
shld eax, edx, 16
and edx, 0ffffh
cmp al, LastPage
jne @f
shr eax, 16
mov [edx+0A0000h], al
ret
@@: mov LastPage, al
pushad
and eax, 0fh
mov edx, eax
mov cl, PageSizeShift
shl edx, cl ; Convert from 64K pages to GranUnit pages.
xor ebx, ebx ; BH=Select window, BL=Window A
mov eax, 04f05h ; AX=Super VGA video memory window control
int 10h
popad
shr eax, 16
mov [edx+0A0000h], al
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