Initial commit
This commit is contained in:
690
ID_RF_A.ASM
Normal file
690
ID_RF_A.ASM
Normal file
@@ -0,0 +1,690 @@
|
||||
; Catacomb 3-D Source Code
|
||||
; Copyright (C) 1993-2014 Flat Rock Software
|
||||
;
|
||||
; This program is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License along
|
||||
; with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
; 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
; ID_RF_A.ASM
|
||||
|
||||
IDEAL
|
||||
MODEL MEDIUM,C
|
||||
|
||||
INCLUDE "ID_ASM.EQU"
|
||||
|
||||
;============================================================================
|
||||
|
||||
TILESWIDE = 21
|
||||
TILESHIGH = 14
|
||||
|
||||
UPDATESIZE = (TILESWIDE+1)*TILESHIGH+1
|
||||
|
||||
DATASEG
|
||||
|
||||
EXTRN screenseg:WORD
|
||||
EXTRN updateptr:WORD
|
||||
EXTRN updatestart:WORD
|
||||
EXTRN masterofs:WORD ;start of master tile port
|
||||
EXTRN bufferofs:WORD ;start of current buffer port
|
||||
EXTRN screenstart:WORD ;starts of three screens (0/1/master) in EGA mem
|
||||
EXTRN grsegs:WORD
|
||||
EXTRN mapsegs:WORD
|
||||
EXTRN originmap:WORD
|
||||
EXTRN updatemapofs:WORD
|
||||
EXTRN tinf:WORD ;seg pointer to map header and tile info
|
||||
EXTRN blockstarts:WORD ;offsets from bufferofs for each update block
|
||||
|
||||
planemask db ?
|
||||
planenum db ?
|
||||
|
||||
CODESEG
|
||||
|
||||
screenstartcs dw ? ;in code segment for accesability
|
||||
|
||||
|
||||
|
||||
|
||||
IFE GRMODE-CGAGR
|
||||
;============================================================================
|
||||
;
|
||||
; CGA refresh routines
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
TILEWIDTH = 4
|
||||
|
||||
;=================
|
||||
;
|
||||
; RFL_NewTile
|
||||
;
|
||||
; Draws a composit two plane tile to the master screen and sets the update
|
||||
; spot to 1 in both update pages, forcing the tile to be copied to the
|
||||
; view pages the next two refreshes
|
||||
;
|
||||
; Called to draw newlly scrolled on strips and animating tiles
|
||||
;
|
||||
;=================
|
||||
|
||||
PROC RFL_NewTile updateoffset:WORD
|
||||
PUBLIC RFL_NewTile
|
||||
USES SI,DI
|
||||
|
||||
;
|
||||
; mark both update lists at this spot
|
||||
;
|
||||
mov di,[updateoffset]
|
||||
|
||||
mov bx,[updateptr] ;start of update matrix
|
||||
mov [BYTE bx+di],1
|
||||
|
||||
mov dx,SCREENWIDTH-TILEWIDTH ;add to get to start of next line
|
||||
|
||||
;
|
||||
; set di to the location in screenseg to draw the tile
|
||||
;
|
||||
shl di,1
|
||||
mov si,[updatemapofs+di] ;offset in map from origin
|
||||
add si,[originmap]
|
||||
mov di,[blockstarts+di] ;screen location for tile
|
||||
add di,[masterofs]
|
||||
|
||||
;
|
||||
; set BX to the foreground tile number and SI to the background number
|
||||
; If either BX or SI = 0xFFFF, the tile does not need to be masked together
|
||||
; as one of the planes totally eclipses the other
|
||||
;
|
||||
mov es,[mapsegs+2] ;foreground plane
|
||||
mov bx,[es:si]
|
||||
mov es,[mapsegs] ;background plane
|
||||
mov si,[es:si]
|
||||
|
||||
mov es,[screenseg]
|
||||
|
||||
or bx,bx
|
||||
jz @@singletile
|
||||
jmp @@maskeddraw ;draw both together
|
||||
|
||||
;=============
|
||||
;
|
||||
; Draw single background tile from main memory
|
||||
;
|
||||
;=============
|
||||
|
||||
@@singletile:
|
||||
shl si,1
|
||||
mov ds,[grsegs+STARTTILE16*2+si]
|
||||
|
||||
xor si,si ;block is segment aligned
|
||||
|
||||
REPT 15
|
||||
movsw
|
||||
movsw
|
||||
add di,dx
|
||||
ENDM
|
||||
movsw
|
||||
movsw
|
||||
|
||||
mov ax,ss
|
||||
mov ds,ax ;restore turbo's data segment
|
||||
ret
|
||||
|
||||
|
||||
;=========
|
||||
;
|
||||
; Draw a masked tile combo
|
||||
; Interupts are disabled and the stack segment is reassigned
|
||||
;
|
||||
;=========
|
||||
@@maskeddraw:
|
||||
cli ; don't allow ints when SS is set
|
||||
shl bx,1
|
||||
mov ss,[grsegs+STARTTILE16M*2+bx]
|
||||
shl si,1
|
||||
mov ds,[grsegs+STARTTILE16*2+si]
|
||||
|
||||
xor si,si ;first word of tile data
|
||||
|
||||
REPT 16
|
||||
mov ax,[si] ;background tile
|
||||
and ax,[ss:si] ;mask
|
||||
or ax,[ss:si+64] ;masked data
|
||||
stosw
|
||||
mov ax,[si+2] ;background tile
|
||||
and ax,[ss:si+2] ;mask
|
||||
or ax,[ss:si+66] ;masked data
|
||||
stosw
|
||||
add si,4
|
||||
add di,dx
|
||||
ENDM
|
||||
|
||||
mov ax,@DATA
|
||||
mov ss,ax
|
||||
sti
|
||||
mov ds,ax
|
||||
ret
|
||||
ENDP
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
|
||||
IFE GRMODE-EGAGR
|
||||
;===========================================================================
|
||||
;
|
||||
; EGA refresh routines
|
||||
;
|
||||
;===========================================================================
|
||||
|
||||
TILEWIDTH = 2
|
||||
|
||||
;=================
|
||||
;
|
||||
; RFL_NewTile
|
||||
;
|
||||
; Draws a composit two plane tile to the master screen and sets the update
|
||||
; spot to 1 in both update pages, forcing the tile to be copied to the
|
||||
; view pages the next two refreshes
|
||||
;
|
||||
; Called to draw newlly scrolled on strips and animating tiles
|
||||
;
|
||||
; Assumes write mode 0
|
||||
;
|
||||
;=================
|
||||
|
||||
PROC RFL_NewTile updateoffset:WORD
|
||||
PUBLIC RFL_NewTile
|
||||
USES SI,DI
|
||||
|
||||
;
|
||||
; mark both update lists at this spot
|
||||
;
|
||||
mov di,[updateoffset]
|
||||
|
||||
mov bx,[updatestart] ;page 0 pointer
|
||||
mov [BYTE bx+di],1
|
||||
mov bx,[updatestart+2] ;page 1 pointer
|
||||
mov [BYTE bx+di],1
|
||||
|
||||
;
|
||||
; set screenstartcs to the location in screenseg to draw the tile
|
||||
;
|
||||
shl di,1
|
||||
mov si,[updatemapofs+di] ;offset in map from origin
|
||||
add si,[originmap]
|
||||
mov di,[blockstarts+di] ;screen location for tile
|
||||
add di,[masterofs]
|
||||
mov [cs:screenstartcs],di
|
||||
|
||||
;
|
||||
; set BX to the foreground tile number and SI to the background number
|
||||
; If either BX or SI = 0xFFFF, the tile does not need to be masked together
|
||||
; as one of the planes totally eclipses the other
|
||||
;
|
||||
mov es,[mapsegs+2] ;foreground plane
|
||||
mov bx,[es:si]
|
||||
mov es,[mapsegs] ;background plane
|
||||
mov si,[es:si]
|
||||
|
||||
mov es,[screenseg]
|
||||
mov dx,SC_INDEX ;for stepping through map mask planes
|
||||
|
||||
or bx,bx
|
||||
jz @@singletile
|
||||
jmp @@maskeddraw ;draw both together
|
||||
|
||||
;=========
|
||||
;
|
||||
; No foreground tile, so draw a single background tile.
|
||||
;
|
||||
;=========
|
||||
@@singletile:
|
||||
|
||||
mov bx,SCREENWIDTH-2 ;add to get to start of next line
|
||||
shl si,1
|
||||
|
||||
mov ax,[cs:screenstartcs]
|
||||
mov ds,[grsegs+STARTTILE16*2+si]
|
||||
|
||||
xor si,si ;block is segment aligned
|
||||
|
||||
mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
|
||||
|
||||
mov cx,4 ;draw four planes
|
||||
@@planeloop:
|
||||
mov dx,SC_INDEX
|
||||
WORDOUT
|
||||
|
||||
mov di,[cs:screenstartcs] ;start at same place in all planes
|
||||
|
||||
REPT 15
|
||||
movsw
|
||||
add di,bx
|
||||
ENDM
|
||||
movsw
|
||||
|
||||
shl ah,1 ;shift plane mask over for next plane
|
||||
loop @@planeloop
|
||||
|
||||
mov ax,ss
|
||||
mov ds,ax ;restore turbo's data segment
|
||||
ret
|
||||
|
||||
|
||||
;=========
|
||||
;
|
||||
; Draw a masked tile combo
|
||||
; Interupts are disabled and the stack segment is reassigned
|
||||
;
|
||||
;=========
|
||||
@@maskeddraw:
|
||||
cli ; don't allow ints when SS is set
|
||||
shl bx,1
|
||||
mov ss,[grsegs+STARTTILE16M*2+bx]
|
||||
shl si,1
|
||||
mov ds,[grsegs+STARTTILE16*2+si]
|
||||
|
||||
xor si,si ;first word of tile data
|
||||
|
||||
mov ax,SC_MAPMASK+0001b*256 ;map mask for plane 0
|
||||
|
||||
mov di,[cs:screenstartcs]
|
||||
@@planeloopm:
|
||||
WORDOUT
|
||||
tileofs = 0
|
||||
lineoffset = 0
|
||||
REPT 16
|
||||
mov bx,[si+tileofs] ;background tile
|
||||
and bx,[ss:tileofs] ;mask
|
||||
or bx,[ss:si+tileofs+32] ;masked data
|
||||
mov [es:di+lineoffset],bx
|
||||
tileofs = tileofs + 2
|
||||
lineoffset = lineoffset + SCREENWIDTH
|
||||
ENDM
|
||||
add si,32
|
||||
shl ah,1 ;shift plane mask over for next plane
|
||||
cmp ah,10000b
|
||||
je @@done ;drawn all four planes
|
||||
jmp @@planeloopm
|
||||
|
||||
@@done:
|
||||
mov ax,@DATA
|
||||
mov ss,ax
|
||||
sti
|
||||
mov ds,ax
|
||||
ret
|
||||
ENDP
|
||||
|
||||
ENDIF
|
||||
|
||||
IFE GRMODE-VGAGR
|
||||
;============================================================================
|
||||
;
|
||||
; VGA refresh routines
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
|
||||
ENDIF
|
||||
|
||||
|
||||
;============================================================================
|
||||
;
|
||||
; reasonably common refresh routines
|
||||
;
|
||||
;============================================================================
|
||||
|
||||
|
||||
;=================
|
||||
;
|
||||
; RFL_UpdateTiles
|
||||
;
|
||||
; Scans through the update matrix pointed to by updateptr, looking for 1s.
|
||||
; A 1 represents a tile that needs to be copied from the master screen to the
|
||||
; current screen (a new row or an animated tiled). If more than one adjacent
|
||||
; tile in a horizontal row needs to be copied, they will be copied as a group.
|
||||
;
|
||||
; Assumes write mode 1
|
||||
;
|
||||
;=================
|
||||
|
||||
|
||||
; AX 0/1 for scasb, temp for segment register transfers
|
||||
; BX width for block copies
|
||||
; CX REP counter
|
||||
; DX line width deltas
|
||||
; SI source for copies
|
||||
; DI scas dest / movsb dest
|
||||
; BP pointer to UPDATETERMINATE
|
||||
;
|
||||
; DS
|
||||
; ES
|
||||
; SS
|
||||
|
||||
PROC RFL_UpdateTiles
|
||||
PUBLIC RFL_UpdateTiles
|
||||
USES SI,DI,BP
|
||||
|
||||
jmp SHORT @@realstart
|
||||
@@done:
|
||||
;
|
||||
; all tiles have been scanned
|
||||
;
|
||||
ret
|
||||
|
||||
@@realstart:
|
||||
mov di,[updateptr]
|
||||
mov bp,(TILESWIDE+1)*TILESHIGH+1
|
||||
add bp,di ; when di = bx, all tiles have been scanned
|
||||
push di
|
||||
mov cx,-1 ; definately scan the entire thing
|
||||
|
||||
;
|
||||
; scan for a 1 in the update list, meaning a tile needs to be copied
|
||||
; from the master screen to the current screen
|
||||
;
|
||||
@@findtile:
|
||||
pop di ; place to continue scaning from
|
||||
mov ax,ss
|
||||
mov es,ax ; search in the data segment
|
||||
mov ds,ax
|
||||
mov al,1
|
||||
repne scasb
|
||||
cmp di,bp
|
||||
je @@done
|
||||
|
||||
cmp [BYTE di],al
|
||||
jne @@singletile
|
||||
jmp @@tileblock
|
||||
|
||||
;============
|
||||
;
|
||||
; copy a single tile
|
||||
;
|
||||
;============
|
||||
EVEN
|
||||
@@singletile:
|
||||
inc di ; we know the next tile is nothing
|
||||
push di ; save off the spot being scanned
|
||||
sub di,[updateptr]
|
||||
shl di,1
|
||||
mov di,[blockstarts-4+di] ; start of tile location on screen
|
||||
mov si,di
|
||||
add di,[bufferofs] ; dest in current screen
|
||||
add si,[masterofs] ; source in master screen
|
||||
|
||||
mov dx,SCREENWIDTH-TILEWIDTH
|
||||
mov ax,[screenseg]
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
|
||||
;--------------------------
|
||||
|
||||
IFE GRMODE-CGAGR
|
||||
|
||||
REPT 15
|
||||
movsw
|
||||
movsw
|
||||
add si,dx
|
||||
add di,dx
|
||||
ENDM
|
||||
movsw
|
||||
movsw
|
||||
|
||||
ENDIF
|
||||
|
||||
;--------------------------
|
||||
|
||||
IFE GRMODE-EGAGR
|
||||
|
||||
REPT 15
|
||||
movsb
|
||||
movsb
|
||||
add si,dx
|
||||
add di,dx
|
||||
ENDM
|
||||
movsb
|
||||
movsb
|
||||
|
||||
ENDIF
|
||||
|
||||
;--------------------------
|
||||
|
||||
jmp @@findtile
|
||||
|
||||
;============
|
||||
;
|
||||
; more than one tile in a row needs to be updated, so do it as a group
|
||||
;
|
||||
;============
|
||||
EVEN
|
||||
@@tileblock:
|
||||
mov dx,di ; hold starting position + 1 in dx
|
||||
inc di ; we know the next tile also gets updated
|
||||
repe scasb ; see how many more in a row
|
||||
push di ; save off the spot being scanned
|
||||
|
||||
mov bx,di
|
||||
sub bx,dx ; number of tiles in a row
|
||||
shl bx,1 ; number of bytes / row
|
||||
|
||||
mov di,dx ; lookup position of start tile
|
||||
sub di,[updateptr]
|
||||
shl di,1
|
||||
mov di,[blockstarts-2+di] ; start of tile location
|
||||
mov si,di
|
||||
add di,[bufferofs] ; dest in current screen
|
||||
add si,[masterofs] ; source in master screen
|
||||
|
||||
mov dx,SCREENWIDTH
|
||||
sub dx,bx ; offset to next line on screen
|
||||
IFE GRMODE-CGAGR
|
||||
sub dx,bx ; bx is words wide in CGA tiles
|
||||
ENDIF
|
||||
|
||||
mov ax,[screenseg]
|
||||
mov ds,ax
|
||||
mov es,ax
|
||||
|
||||
REPT 15
|
||||
mov cx,bx
|
||||
IFE GRMODE-CGAGR
|
||||
rep movsw
|
||||
ENDIF
|
||||
IFE GRMODE-EGAGR
|
||||
rep movsb
|
||||
ENDIF
|
||||
add si,dx
|
||||
add di,dx
|
||||
ENDM
|
||||
mov cx,bx
|
||||
IFE GRMODE-CGAGR
|
||||
rep movsw
|
||||
ENDIF
|
||||
IFE GRMODE-EGAGR
|
||||
rep movsb
|
||||
ENDIF
|
||||
|
||||
dec cx ; was 0 from last rep movsb, now $ffff for scasb
|
||||
jmp @@findtile
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
;============================================================================
|
||||
|
||||
|
||||
;=================
|
||||
;
|
||||
; RFL_MaskForegroundTiles
|
||||
;
|
||||
; Scan through update looking for 3's. If the foreground tile there is a
|
||||
; masked foreground tile, draw it to the screen
|
||||
;
|
||||
;=================
|
||||
|
||||
PROC RFL_MaskForegroundTiles
|
||||
PUBLIC RFL_MaskForegroundTiles
|
||||
USES SI,DI,BP
|
||||
jmp SHORT @@realstart
|
||||
@@done:
|
||||
;
|
||||
; all tiles have been scanned
|
||||
;
|
||||
ret
|
||||
|
||||
@@realstart:
|
||||
mov di,[updateptr]
|
||||
mov bp,(TILESWIDE+1)*TILESHIGH+2
|
||||
add bp,di ; when di = bx, all tiles have been scanned
|
||||
push di
|
||||
mov cx,-1 ; definately scan the entire thing
|
||||
;
|
||||
; scan for a 3 in the update list
|
||||
;
|
||||
@@findtile:
|
||||
mov ax,ss
|
||||
mov es,ax ; scan in the data segment
|
||||
mov al,3
|
||||
pop di ; place to continue scaning from
|
||||
repne scasb
|
||||
cmp di,bp
|
||||
je @@done
|
||||
|
||||
;============
|
||||
;
|
||||
; found a tile, see if it needs to be masked on
|
||||
;
|
||||
;============
|
||||
|
||||
push di
|
||||
|
||||
sub di,[updateptr]
|
||||
shl di,1
|
||||
mov si,[updatemapofs-2+di] ; offset from originmap
|
||||
add si,[originmap]
|
||||
|
||||
mov es,[mapsegs+2] ; foreground map plane segment
|
||||
mov si,[es:si] ; foreground tile number
|
||||
|
||||
or si,si
|
||||
jz @@findtile ; 0 = no foreground tile
|
||||
|
||||
mov bx,si
|
||||
add bx,INTILE ;INTILE tile info table
|
||||
mov es,[tinf]
|
||||
test [BYTE PTR es:bx],80h ;high bit = masked tile
|
||||
jz @@findtile
|
||||
|
||||
;-------------------
|
||||
|
||||
IFE GRMODE-CGAGR
|
||||
;=================
|
||||
;
|
||||
; mask the tile CGA
|
||||
;
|
||||
;=================
|
||||
|
||||
mov di,[blockstarts-2+di]
|
||||
add di,[bufferofs]
|
||||
mov es,[screenseg]
|
||||
shl si,1
|
||||
mov ds,[grsegs+STARTTILE16M*2+si]
|
||||
|
||||
mov bx,64 ;data starts 64 bytes after mask
|
||||
|
||||
xor si,si
|
||||
|
||||
lineoffset = 0
|
||||
REPT 16
|
||||
mov ax,[es:di+lineoffset] ;background
|
||||
and ax,[si] ;mask
|
||||
or ax,[si+bx] ;masked data
|
||||
mov [es:di+lineoffset],ax ;background
|
||||
inc si
|
||||
inc si
|
||||
mov ax,[es:di+lineoffset+2] ;background
|
||||
and ax,[si] ;mask
|
||||
or ax,[si+bx] ;masked data
|
||||
mov [es:di+lineoffset+2],ax ;background
|
||||
inc si
|
||||
inc si
|
||||
lineoffset = lineoffset + SCREENWIDTH
|
||||
ENDM
|
||||
ENDIF
|
||||
|
||||
;-------------------
|
||||
|
||||
IFE GRMODE-EGAGR
|
||||
;=================
|
||||
;
|
||||
; mask the tile
|
||||
;
|
||||
;=================
|
||||
|
||||
mov [BYTE planemask],1
|
||||
mov [BYTE planenum],0
|
||||
|
||||
mov di,[blockstarts-2+di]
|
||||
add di,[bufferofs]
|
||||
mov [cs:screenstartcs],di
|
||||
mov es,[screenseg]
|
||||
shl si,1
|
||||
mov ds,[grsegs+STARTTILE16M*2+si]
|
||||
|
||||
mov bx,32 ;data starts 32 bytes after mask
|
||||
|
||||
@@planeloopm:
|
||||
mov dx,SC_INDEX
|
||||
mov al,SC_MAPMASK
|
||||
mov ah,[ss:planemask]
|
||||
WORDOUT
|
||||
mov dx,GC_INDEX
|
||||
mov al,GC_READMAP
|
||||
mov ah,[ss:planenum]
|
||||
WORDOUT
|
||||
|
||||
xor si,si
|
||||
mov di,[cs:screenstartcs]
|
||||
lineoffset = 0
|
||||
REPT 16
|
||||
mov cx,[es:di+lineoffset] ;background
|
||||
and cx,[si] ;mask
|
||||
or cx,[si+bx] ;masked data
|
||||
inc si
|
||||
inc si
|
||||
mov [es:di+lineoffset],cx
|
||||
lineoffset = lineoffset + SCREENWIDTH
|
||||
ENDM
|
||||
add bx,32 ;the mask is now further away
|
||||
inc [ss:planenum]
|
||||
shl [ss:planemask],1 ;shift plane mask over for next plane
|
||||
cmp [ss:planemask],10000b ;done all four planes?
|
||||
je @@drawn ;drawn all four planes
|
||||
jmp @@planeloopm
|
||||
|
||||
@@drawn:
|
||||
ENDIF
|
||||
|
||||
;-------------------
|
||||
|
||||
mov ax,ss
|
||||
mov ds,ax
|
||||
mov cx,-1 ;definately scan the entire thing
|
||||
|
||||
jmp @@findtile
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
END
|
||||
|
||||
Reference in New Issue
Block a user