home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga ACS 1998 #6
/
amigaacscoverdisc1998-061998.iso
/
games
/
descent
/
source
/
2d
/
modex.asm
< prev
next >
Wrap
Assembly Source File
|
1998-06-08
|
17KB
|
836 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/modex.asm $
; $Revision: 1.19 $
; $Author: john $
; $Date: 1995/03/01 15:37:46 $
;
; Routines to access ModeX VGA memory
;
; $Log: modex.asm $
; Revision 1.19 1995/03/01 15:37:46 john
; Better ModeX support.
;
; Revision 1.18 1994/11/24 13:24:20 john
; Made sure that some rep movs had the cld set first.
; Took some unused functions out.
;
; Revision 1.17 1994/09/22 18:15:02 john
; Made flip page wait for retrace.
;
; Revision 1.16 1994/09/22 16:08:27 john
; Fixed some palette stuff.
;
; Revision 1.15 1994/07/13 12:03:05 john
; Added assembly modex line-drawer.
;
; Revision 1.14 1994/05/06 12:50:34 john
; Added supertransparency; neatend things up; took out warnings.
;
; Revision 1.13 1994/05/03 19:39:04 john
; *** empty log message ***
;
; Revision 1.12 1994/02/18 15:32:32 john
; *** empty log message ***
;
; Revision 1.11 1993/12/21 11:40:36 john
; *** empty log message ***
;
; Revision 1.10 1993/12/09 15:02:26 john
; Changed palette stuff majorly
;
; Revision 1.9 1993/12/03 12:11:32 john
; fixed cx/ecx loop bugs.
;
; Revision 1.8 1993/11/16 11:28:18 john
; *** empty log message ***
;
; Revision 1.7 1993/10/15 16:23:23 john
; y
;
; Revision 1.6 1993/09/28 19:07:19 john
; stripped the waitforretrace out of fade to speed things up.
;
; Revision 1.5 1993/09/26 18:58:58 john
; fade stuff
;
; Revision 1.4 1993/09/21 14:01:15 john
; turned off video before mode set to reduce flicker.
;
; Revision 1.3 1993/09/08 11:38:36 john
; changed rcs stuff at beginning.
;
;
;
.386
_DATA SEGMENT BYTE PUBLIC USE32 'DATA'
INCLUDE psmacros.inc
INCLUDE TWEAK.INC
INCLUDE VGAREGS.INC
extd _gr_var_bwidth
extd _modex_line_vertincr
extd _modex_line_incr1
extd _modex_line_incr2
_modex_line_routine dd ?
extd _modex_line_x1
extd _modex_line_y1
extd _modex_line_x2
extd _modex_line_y2
extb _modex_line_Color
SavedColor db ?
LEFT_MASK1 = 1000b
LEFT_MASK2 = 1100b
LEFT_MASK3 = 1110b
RIGHT_MASK1 = 0001b
RIGHT_MASK2 = 0011b
RIGHT_MASK3 = 0111b
ALL_MASK = 1111b
tmppal db 768 dup (0)
fb_pal dd ?
fb_add dw ?
fb_count dd ?
MaskTable1 db ALL_MASK AND RIGHT_MASK1,
ALL_MASK AND RIGHT_MASK2,
ALL_MASK AND RIGHT_MASK3,
ALL_MASK,
LEFT_MASK3 AND RIGHT_MASK1,
LEFT_MASK3 AND RIGHT_MASK2,
LEFT_MASK3 AND RIGHT_MASK3,
LEFT_MASK3,
LEFT_MASK2 AND RIGHT_MASK1,
LEFT_MASK2 AND RIGHT_MASK2,
LEFT_MASK2 AND RIGHT_MASK3,
LEFT_MASK2,
LEFT_MASK1 AND RIGHT_MASK1,
LEFT_MASK1 AND RIGHT_MASK2,
LEFT_MASK1 AND RIGHT_MASK3,
LEFT_MASK1,
MaskTable2 db ALL_MASK,RIGHT_MASK1,
ALL_MASK,RIGHT_MASK2,
ALL_MASK,RIGHT_MASK3,
ALL_MASK,ALL_MASK,
LEFT_MASK3,RIGHT_MASK1,
LEFT_MASK3,RIGHT_MASK2,
LEFT_MASK3,RIGHT_MASK3,
LEFT_MASK3,ALL_MASK,
LEFT_MASK2,RIGHT_MASK1,
LEFT_MASK2,RIGHT_MASK2,
LEFT_MASK2,RIGHT_MASK3,
LEFT_MASK2,ALL_MASK,
LEFT_MASK1,RIGHT_MASK1,
LEFT_MASK1,RIGHT_MASK2,
LEFT_MASK1,RIGHT_MASK3,
LEFT_MASK1,ALL_MASK
DrawTable dd DrawMR,
DrawMR,
DrawMR,
DrawM,
DrawLMR,
DrawLMR,
DrawLMR,
DrawLM,
DrawLMR,
DrawLMR,
DrawLMR,
DrawLM,
DrawLMR,
DrawLMR,
DrawLMR,
DrawLM
_DATA ENDS
DGROUP GROUP _DATA
_TEXT SEGMENT BYTE PUBLIC USE32 'CODE'
ASSUME DS:_DATA
ASSUME CS:_TEXT
PUBLIC gr_sync_display_
gr_sync_display_:
push ax
push dx
mov dx, VERT_RESCAN
VS2A: in al, dx
and al, 08h
jnz VS2A ; Loop until not in vertical retrace
VS2B: in al, dx
and al, 08h
jz VS2B ; Loop until in vertical retrace
pop dx
pop ax
ret
PUBLIC gr_modex_uscanline_
gr_modex_uscanline_:
push edi
; EAX = X1 (X1 and X2 don't need to be sorted)
; EDX = X2
; EBX = Y
; ECX = Color
mov SavedColor, cl
;mov ebx, _RowOffset[ebx*4]
mov edi, _gr_var_bwidth
imul edi, ebx
add edi, 0A0000h
cmp eax, edx
jle @f
xchg eax, edx
@@: mov bl, al
shl bl, 2
mov bh, dl
and bh, 011b
or bl, bh
and ebx, 0fh
; BX = LeftRight switch command. (4bit)
shr eax, 2
shr edx, 2
add edi, eax
; EDI = Offset into video memory
mov ecx, edx
sub ecx, eax
; ECX = X2/4 - X1/4 - 1
jnz LargerThan4
;======================= ONE GROUP OF 4 OR LESS TO DRAW ====================
mov dx, SC_INDEX
mov al, SC_MAP_MASK
out dx, al
inc dx
mov al, MaskTable1[ebx]
out dx, al
mov al, SavedColor
mov [edi], al ; Write the one pixel
pop edi
ret
LargerThan4:
dec ecx
jnz LargerThan8
;===================== TWO GROUPS OF 4 OR LESS TO DRAW ====================
mov cx, WORD PTR MaskTable2[ebx*2]
mov bl, SavedColor
mov dx, SC_INDEX
mov al, SC_MAP_MASK
out dx, al
inc dx
mov al, cl
out dx, al
mov [edi], bl ; Write the left pixel
mov al, ch
out dx, al
mov [edi+1], bl ; Write the right pixel
pop edi
ret
;========================= MANY GROUPS OF 4 TO DRAW ======================
LargerThan8:
mov dx, SC_INDEX
mov al, SC_MAP_MASK
out dx, al
inc dx
; DX = SC_INDEX
mov al, SavedColor
mov ah, al
; AL,AH = color of pixel
jmp NEAR32 PTR DrawTable[ebx*4]
DrawM: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov al, ALL_MASK
out dx, al
mov al, ah
cld
add ecx, 2
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: pop edi
ret
DrawLM:
;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov al, BYTE PTR MaskTable2[ebx*2]
out dx, al
mov [edi], ah ; Write leftmost pixels
inc edi
mov al, ALL_MASK
out dx, al
mov al, ah
cld
inc ecx
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: pop edi
ret
DrawLMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov bx, WORD PTR MaskTable2[ebx*2]
mov al, bl
out dx, al
mov [edi], ah ; Write leftmost pixels
inc edi
mov al, ALL_MASK
out dx, al
mov al, ah
cld
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: mov al, bh
out dx, al
mov [edi], ah ; Write the rightmost pixels
pop edi
ret
DrawMR: ;AH=COLOR, EDI=DEST, CX=X2/4-X1/4-1, BX=Table Index
mov bx, WORD PTR MaskTable2[ebx*2]
mov al, ALL_MASK
out dx, al
mov al, ah
cld
inc ecx
shr ecx, 1
rep stosw ; Write the middle pixels
jnc @F
stosb ; Write the middle odd pixel
@@: mov al, bh
out dx, al
mov [edi], ah ; Write the rightmost pixels
pop edi
ret
PUBLIC gr_modex_setmode_
gr_modex_setmode_:
push ebx
push ecx
push edx
push esi
push edi
mov ecx, eax
dec ecx
cmp ecx, LAST_X_MODE
jbe @f
mov ecx, 0
@@:
;call turn_screen_off
push ecx ; some bios's dont preserve cx
;mov ax, 1201h
;mov bl, 31h ; disable palette loading at mode switch
;int 10h
mov ax,13h ; let the BIOS set standard 256-color
int 10h ; mode (320x200 linear)
;mov ax, 1200h
;mov bl, 31h ; enable palette loading at mode switch
;int 10h
pop ecx
mov dx,SC_INDEX
mov ax,0604h
out dx,ax ; disable chain4 mode
mov dx,SC_INDEX
mov ax,0100h
out dx,ax ; synchronous reset while setting Misc
; Output for safety, even though clock
; unchanged
mov esi, dword ptr ModeTable[ecx*4]
lodsb
or al,al
jz DontSetDot
mov dx,MISC_OUTPUT
out dx,al ; select the dot clock and Horiz
; scanning rate
;mov dx,SC_INDEX
;mov al,01h
;out dx,al
;inc dx
;in al, dx
;or al, 1000b
;out dx, al
DontSetDot:
mov dx,SC_INDEX
mov ax,0300h
out dx,ax ; undo reset (restart sequencer)
mov dx,CRTC_INDEX ; reprogram the CRT Controller
mov al,11h ; VSync End reg contains register write
out dx,al ; protect bit
inc dx ; CRT Controller Data register
in al,dx ; get current VSync End register setting
and al,07fh ; remove write protect on various
out dx,al ; CRTC registers
dec dx ; CRT Controller Index
cld
xor ecx,ecx
lodsb
mov cl,al
SetCRTParmsLoop:
lodsw ; get the next CRT Index/Data pair
out dx,ax ; set the next CRT Index/Data pair
loop SetCRTParmsLoop
mov dx,SC_INDEX
mov ax,0f02h
out dx,ax ; enable writes to all four planes
mov edi, 0A0000h ; point ES:DI to display memory
xor ax,ax ; clear to zero-value pixels
mov ecx,8000h ; # of words in display memory
rep stosw ; clear all of display memory
; Set pysical screen dimensions
xor eax, eax
lodsw ; Load scrn pixel width
mov cx, ax
shl eax, 16
mov dx,CRTC_INDEX
mov al,CRTC_OFFSET
out dx,al
inc dx
mov ax,cx
shr ax,3
out dx,al
;mov si, 360
;@@:
;mov ax, 04f06h
;mov bl, 0
;mov cx, si
;int 10h
;cmp cx, si
;je @f
;inc si
;jmp @B
;@@:
;movzx eax, si
lodsw ; Load Screen Phys. Height
;call turn_screen_on
pop edi
pop esi
pop edx
pop ecx
pop ebx
ret
PUBLIC gr_modex_setplane_
gr_modex_setplane_:
push cx
push dx
mov cl, al
; SELECT WRITE PLANE
and cl,011b ;CL = plane
mov ax,0100h + MAP_MASK ;AL = index in SC of Map Mask reg
shl ah,cl ;set only the bit for the required
; plane to 1
mov dx,SC_INDEX ;set the Map Mask to enable only the
out dx,ax ; pixel's plane
; SELECT READ PLANE
mov ah,cl ;AH = plane
mov al,READ_MAP ;AL = index in GC of the Read Map reg
mov dx,GC_INDEX ;set the Read Map to read the pixel's
out dx,ax ; plane
pop dx
pop cx
ret
PUBLIC gr_modex_setstart_
gr_modex_setstart_:
; EAX = X
; EDX = Y
; EBX = Wait for retrace
push ebx
push ecx
push ebx
mov ecx, _gr_var_bwidth
imul ecx, edx
shr eax, 2
add eax, ecx
mov ch, ah
mov bh, al
mov bl, CC_START_LO
mov cl, CC_START_HI
cli
mov dx, VERT_RESCAN
WaitDE: in al, dx
test al, 01h
jnz WaitDE
mov dx, CRTC_INDEX
mov ax, bx
out dx, ax ; Start address low
mov ax, cx
out dx, ax ; Start address high
sti
pop ebx
cmp ebx, 0
je NoWaitVS
mov dx, VERT_RESCAN
WaitVS: in al, dx
test al, 08h
jz WaitVS ; Loop until in vertical retrace
NoWaitVS:
pop ecx
pop ebx
ret
ModeXAddr macro
; given: ebx=x, eax=y, return cl=plane mask, ebx=address, trash eax
mov cl, bl
and cl, 3
shr ebx, 2
imul eax, _gr_var_bwidth
add ebx, eax
add ebx, 0A0000h
endm
;-----------------------------------------------------------------------
;
; Line drawing function for all MODE X 256 Color resolutions
; Based on code from "PC and PS/2 Video Systems" by Richard Wilton.
PUBLIC gr_modex_line_
gr_modex_line_:
pusha
mov dx,SC_INDEX ; setup for plane mask access
; check for vertical line
mov esi,_gr_var_bwidth
mov ecx,_modex_line_x2
sub ecx,_modex_line_x1
jz VertLine
; force x1 < x2
jns L01
neg ecx
mov ebx,_modex_line_x2
xchg ebx,_modex_line_x1
mov _modex_line_x2,ebx
mov ebx,_modex_line_y2
xchg ebx,_modex_line_y1
mov _modex_line_y2,ebx
; calc dy = abs(y2 - y1)
L01:
mov ebx,_modex_line_y2
sub ebx,_modex_line_y1
jnz short skip
jmp HorizLine
skip: jns L03
neg ebx
neg esi
; select appropriate routine for slope of line
L03:
mov _modex_line_vertincr,esi
mov _modex_line_routine,offset LoSlopeLine
cmp ebx,ecx
jle L04
mov _modex_line_routine,offset HiSlopeLine
xchg ebx,ecx
; calc initial decision variable and increments
L04:
shl ebx,1
mov _modex_line_incr1,ebx
sub ebx,ecx
mov esi,ebx
sub ebx,ecx
mov _modex_line_incr2,ebx
; calc first pixel address
push ecx
mov eax,_modex_line_y1
mov ebx,_modex_line_x1
ModeXAddr
mov edi,ebx
mov al,1
shl al,cl
mov ah,al ; duplicate nybble
shl al,4
add ah,al
mov bl,ah
pop ecx
inc ecx
jmp [_modex_line_routine]
; routine for verticle lines
VertLine:
mov eax,_modex_line_y1
mov ebx,_modex_line_y2
mov ecx,ebx
sub ecx,eax
jge L31
neg ecx
mov eax,ebx
L31:
inc ecx
mov ebx,_modex_line_x1
push ecx
ModeXAddr
mov ah,1
shl ah,cl
mov al,MAP_MASK
out dx,ax
pop ecx
mov ax, word ptr _modex_line_Color
; draw the line
L32:
mov [ebx],al
add ebx,esi
loop L32
jmp Lexit
; routine for horizontal line
HorizLine:
mov eax,_modex_line_y1
mov ebx,_modex_line_x1
ModeXAddr
mov edi,ebx ; set dl = first byte mask
mov dl,00fh
shl dl,cl
mov ecx,_modex_line_x2 ; set dh = last byte mask
and cl,3
mov dh,00eh
shl dh,cl
not dh
; determine byte offset of first and last pixel in line
mov eax,_modex_line_x2
mov ebx,_modex_line_x1
shr eax,2 ; set ax = last byte column
shr ebx,2 ; set bx = first byte column
mov ecx,eax ; cx = ax - bx
sub ecx,ebx
mov eax,edx ; mov end byte masks to ax
mov dx,SC_INDEX ; setup dx for VGA outs
mov bl,_modex_line_Color
; set pixels in leftmost byte of line
or ecx,ecx ; is start and end pt in same byte
jnz L42 ; no !
and ah,al ; combine start and end masks
jmp short L44
L42: push eax
mov ah,al
mov al,MAP_MASK
out dx,ax
mov al,bl
stosb
dec ecx
; draw remainder of the line
L43:
mov ah,0Fh
mov al,MAP_MASK
out dx,ax
mov al,bl
rep stosb
pop eax
; set pixels in rightmost byte of line
L44:
mov al,MAP_MASK
out dx, ax
mov byte ptr [edi],bl
jmp Lexit
; routine for dy >= dx (slope <= 1)
LoSlopeLine:
mov al,MAP_MASK
mov bh,byte ptr _modex_line_Color
L10:
mov ah,bl
L11:
or ah,bl
rol bl,1
jc L14
; bit mask not shifted out
or esi,esi
jns L12
add esi,_modex_line_incr1
loop L11
out dx,ax
mov [edi],bh
jmp short Lexit
L12:
add esi,_modex_line_incr2
out dx,ax
mov [edi],bh
add edi,_modex_line_vertincr
loop L10
jmp short Lexit
; bit mask shifted out
L14: out dx,ax
mov [edi],bh
inc edi
or esi,esi
jns L15
add esi,_modex_line_incr1
loop L10
jmp short Lexit
L15:
add esi,_modex_line_incr2
add edi,_modex_line_vertincr
loop L10
jmp short Lexit
; routine for dy > dx (slope > 1)
HiSlopeLine:
mov ebx,_modex_line_vertincr
mov al,MAP_MASK
L21: out dx,ax
push eax
mov al,_modex_line_Color
mov [edi],al
pop eax
add edi,ebx
L22:
or esi,esi
jns L23
add esi,_modex_line_incr1
loop L21
jmp short Lexit
L23:
add esi,_modex_line_incr2
rol ah,1
adc edi,0
lx21: loop L21
; return to caller
Lexit:
popa
ret
_TEXT ENDS
END