home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1993 #2
/
Image.iso
/
graphics
/
acksrc.zip
/
ACKASM.VGA
< prev
next >
Wrap
Text File
|
1993-06-19
|
11KB
|
438 lines
PAGE 80,132
TITLE - XTASM.ASM - Assembly routines for 3D engine
;;;.286P
;==============================================================================
; COMMAND LINE ASSEMBLY
; MASM /B63 /Z /D_Mx FILENAME;
;
; WHERE Mx SPECIFIES MODEL (l OR c) FOR LARGE OR COMPACT MODELS
;==============================================================================
INCLUDE ET.EQU
INCLUDE ET.MAC
ANGLE_30 equ 160
ANGLE_360 equ 1920
extrn _bMaps:DWORD
extrn _oMaps:DWORD
extrn _bdfp:DWORD
extrn _PageBegin:WORD
extrn _InvCosTable:DWORD
extrn _InvSinTable:DWORD
extrn _LongCosTable:DWORD
extrn _DistanceTable:WORD
extrn _AdjustTable:DWORD
extrn _CenterRow:WORD
extrn _MaxDistance:WORD
extrn _TopColor:WORD
extrn _BottomColor:WORD
extrn _ScreenBuffer:DWORD
extrn _VidRow:WORD
extrn _lowmask:BYTE
extrn _Walls:WORD
extrn _xRay:NEAR
extrn _yRay:NEAR
extrn N_LDIV@:FAR
PUBLIC _graphinit
PUBLIC _usepage
PUBLIC _flippage
PUBLIC _SetPalette
PUBLIC _DrawWalls
PUBLIC _DrawOneObject
SC_INDEX equ 03c4h ;Sequence Controller Index
CRTC_INDEX equ 03d4h ;CRT Controller Index
MISC_OUTPUT equ 03c2h ;Miscellaneous Output register
SCREEN_SEG equ 0a000h ;segment of display memory in mode X
_TEXT segment byte public 'CODE'
DGROUP group _DATA,_BSS
assume cs:_TEXT,ds:DGROUP
_ViewPage dw 0 ; The address of the current view page
_WritePage dw 0 ; The address of the current write page
PageTable dw 4 dup (0) ; Address of 4 pages
ScreenWidth dw 320/4 ; The width of the screen
PageSize dw 320/4*240 ; The size of each page
CRTParms label word
dw 00d06h ;vertical total
dw 03e07h ;overflow (bit 8 of vertical counts)
dw 04109h ;cell height (2 to double-scan)
dw 0ea10h ;v sync start
dw 0ac11h ;v sync end and protect cr0-cr7
dw 0df12h ;vertical displayed
dw 00014h ;turn off dword mode
dw 0e715h ;v blank start
dw 00616h ;v blank end
dw 0e317h ;turn on byte mode
CRT_PARM_LENGTH equ (($-CRTParms)/2)
_TEXT ends
_DATA segment word public 'DATA'
; Index/data pairs for CRT Controller registers that differ between
; mode 13h and mode X.
_d@ label byte
_DATA ends
_BSS segment word public 'BSS'
_b@ label byte
_BSS ends
public _graphinit
public _ViewPage,_WritePage
public ScreenWidth,PageSize,PageTable
_TEXT SEGMENT byte public 'CODE'
ASSUME cs:_TEXT
;==============================================================================
; void graphinit(int width,int psize,int mask)
; width - width of the screen in bytes/plane (defaults to 320/4 if 0)
; psize - size of each page in bytes/plane (defaults to 320*200/4 if 0)
;==============================================================================
PBEGIN _graphinit
mov ax,13h
int 10h
ret
_graphinit endp
;==============================================================================
; void SetVGAmode(void);
;==============================================================================
PBEGIN _SetVGAmode
push bp
mov ax,13h
int 10h ; Set 320x200x256
pop bp
ret
_SetVGAmode endp
;==============================================================================
; void usepage(int page)
;==============================================================================
UPnum equ [bp+ABASE]
PBEGIN _usepage
ret
_usepage endp
;==============================================================================
; void flippage()
;
; NOTE: Some lines have been commented out for test purposes. If you experience
; flicker when the page flips, un-comment the lines waiting for vertical
; retrace.
;==============================================================================
PBEGIN _flippage
push ds
push si
push di
mov ax,0A000H
mov es,ax
xor di,di
lds si,DGROUP:_ScreenBuffer
mov cx,32000
; cli
rep movsw
; sti
pop di
pop si
pop ds
ret
_flippage endp
;==============================================================================
; void SetPalette(unsigned char far *PalBuf);
;==============================================================================
SPbuf equ [bp+ABASE]
PBEGIN _SetPalette
push bp
mov bp,sp
push ds
push si
lds si,dword ptr SPbuf
mov cx,256
xor bx,bx
cld
mov dx,3C8H
sp010:
mov al,bl
out dx,al
inc dx
lodsb
out dx,al
lodsb
out dx,al
lodsb
out dx,al
dec dx
inc bx
loop sp010
pop si
pop ds
pop bp
ret
_SetPalette endp
;==============================================================================
; void DrawWalls(void);
;==============================================================================
Y2 equ [bp-2]
AVLOW equ [bp-4]
AVHI equ [bp-6]
VCOL equ [bp-8]
BOFFLOW equ [bp-10]
BOFFHI equ [bp-12]
sColor equ [bp-14]
fColor equ [bp-16]
PBEGIN _DrawWalls
push bp
mov bp,sp
sub sp,18
push ds
push si
push di
les di,dword ptr ds:_ScreenBuffer
mov cx,16000
mov ax,ds:_TopColor
mov ah,al
rep stosw
mov cx,16000
mov ax,ds:_BottomColor
mov ah,al
rep stosw
xor ax,ax ;Initial loop/plane counter
mov VCOL,ax ;Set beginning video column
mov si,offset _Walls ; Point to wall array
mov cx,320 ;Number of walls to display
drw020:
push ds ;save data segment
push si ;save wall pointer
push cx ;save wall count
lodsw ;Get bitmap number
xchg ax,bx ;use bx as the index
shl bx,1
shl bx,1 ;dword index into bitmap table
mov di,word ptr DGROUP:_bMaps[bx] ;offset to bitmap
mov es,word ptr DGROUP:_bMaps[bx+2] ;segment of bitmap
lodsw ;get bitmap column to display
mov cl,6
shl ax,cl ;x64 to get correct row
add di,ax ;and add to bitmap offset
lodsw ;get bitmap distance
shl ax,1 ; Make word index for table lookup
mov si,ax ;save distance
mov bx,word ptr DGROUP:_DistanceTable[si] ;get height of bitmap
mov cx,word ptr DGROUP:_CenterRow
mov ax,bx ; Pick up the height
shr ax,1 ; Divide by two
sub cx,ax ; And subtract from center for Y1
mov ax,cx ; Start with Y1
add ax,bx ; and add height to it for Y2
cmp ax,199 ; Don't let Y2 go beyond screen height
jle short drw030
mov ax,199 ; Else force it to screen height
drw030:
mov Y2,ax ;save y2
shl si,1 ; Turn object distance into dword index
mov ax,word ptr DGROUP:_AdjustTable[si+2]
mov dx,word ptr DGROUP:_AdjustTable[si]
mov AVHI,ax ; Get (64 * 65536) / height
mov AVLOW,dx
xchg si,di ;si now points to bitmap
mov ax,es ; Pick up segment to bitmap
les di,dword ptr DGROUP:_ScreenBuffer
add di,word ptr VCOL
mov word ptr BOFFLOW,0 ; Initialize the current bitmap offset
mov word ptr BOFFHI,0
cmp cx,word ptr Y2 ; is Y1 > Y2?
jge short drw090 ; Yes, get on out
or cx,cx ; Y1 <= 0?
jle drw050 ; Yes, no sky color needed
mov bx,cx ; determine video row
shl bx,1
add di,word ptr ds:_VidRow[bx]
drw050:
mov ds,ax ;ds:si->bitmap
mov bx,319 ; Offset to next video row
mov dx,AVLOW ; Hold onto lsb of adjustment
mov ax,AVHI ; Pick up msb of bitmap adjustment
;------------------------------------------------------------------------------
; Here is where the actual bitmap is transferred to the screen. Better
; optimization could be done by precalculating the adjustment factor instead
; of looping until Y1 >= 0. This has not been tried so I don't know if the
; speed would make it worth it....
;------------------------------------------------------------------------------
drw060:
or cx,cx ; Is Y1 still < 0 ?
jl short drw070 ; Yes, don't start drawing yet
movsb ;Move bitmap to video
dec si
add di,bx ;next row of video
drw070:
add word ptr BOFFLOW,dx ; Add lsb to current offset
adc si,ax ; Use msb to get next bitmap location
inc cx ; Next y1
cmp cx,word ptr Y2 ; Beyond Y2 yet?
jl short drw060 ; Nope, keep looping
drw090:
pop cx ;get wall count
pop si ;recover structure pointer
pop ds
add si,8 ;Wall structure size * 4
inc word ptr VCOL ;next video column to display at
dec cx
jz drw100
jmp drw020 ;next wall to display
drw100:
drwDone:
mov dx,3c5H
mov al,0FFH ;Enable all planes again
out dx,al
pop di
pop si
pop ds
mov sp,bp
pop bp
ret
_DrawWalls endp
;==============================================================================
; +4 +6 +8 +10 +12
; void DrawOneObject(int ObjNum,int ObjCol,int ObjDist,int VidCol,int PageNum);
;==============================================================================
PBEGIN _DrawOneObject
push bp
mov bp,sp
sub sp,20
push si
push di
push ds
mov bx,word ptr [bp+8] ; Get the distance to the bitmap
shl bx,1 ; Make word index for table lookup
mov si,bx ; Save index for now
mov bx,word ptr DGROUP:_DistanceTable[bx]
dob010:
mov cx,100
mov ax,bx ; Pick up the height
shr ax,1 ; Divide by two
sub cx,ax ; And subtract from center for Y1
mov di,cx ; Start with Y1
add di,bx ; and add height to it for Y2
cmp di,199 ; Don't let Y2 go beyond screen height
jle short dob020
mov di,199 ; Else force it to screen height
dob020:
mov word ptr [bp-2],di ;save y2
shl si,1 ; Turn object distance into dword index
mov ax,word ptr DGROUP:_AdjustTable[si+2]
mov dx,word ptr DGROUP:_AdjustTable[si]
mov word ptr [bp-14],ax ; Get (64 * 65536) / height
mov word ptr [bp-16],dx
mov bx,word ptr [bp+4] ; Bitmap number to display
shl bx,1 ; dword index
shl bx,1 ; dword index
mov ax,word ptr DGROUP:_oMaps[bx+2]
mov dx,word ptr DGROUP:_oMaps[bx]
mov bx,word ptr [bp+6] ; Bitmap column to display
shl bx,1
shl bx,1
shl bx,1
shl bx,1
shl bx,1
shl bx,1 ; x 64 to get correct bitmap row
add dx,bx ; then add to start of bitmap
mov word ptr [bp-6],ax
mov word ptr [bp-8],dx
les di,dword ptr DGROUP:_ScreenBuffer
add di,word ptr [bp+10] ; Video column to display at
mov word ptr [bp-18],0 ; Initialize the current bitmap offset
mov word ptr [bp-20],0
or cx,cx ; Is Y1 > 0 ?
jle short dob030 ; Nope, start above video
mov ax,320
imul cx
add di,ax
dob030:
cmp cx,word ptr [bp-2] ; is Y1 > Y2?
jge short dob090 ; Yes, get on out
mov bx,320 ;Amount to next row of video
lds si,dword ptr [bp-8] ;Get image buffer
mov dx,word ptr [bp-16] ; Hold onto lsb of adjustment
dob040:
or cx,cx ; Is Y1 still < 0 ?
jl short dob080 ; Yes, don't start drawing yet
lodsb
dec si
or al,al ;Transparent color?
jz dob050 ;Yes, don't write it to video
mov byte ptr es:[di],al ;place character in video
dob050:
add di,bx ;next row of video
dob080:
mov ax,word ptr [bp-14] ; Pick up msb of bitmap adjustment
add word ptr [bp-20],dx ; and add to current offset
adc si,ax ; Keep the msb correct
inc cx ; Next y1
cmp cx,word ptr [bp-2] ; Beyond Y2 yet?
jl short dob040 ; Nope, keep looping
dob090:
pop ds
pop di
pop si
mov sp,bp
pop bp
ret
_DrawOneObject endp
_TEXT ENDS
END