mirror of
https://github.com/martinhaye/a2render.git
synced 2024-06-10 05:29:30 +00:00
1093 lines
16 KiB
ArmAsm
1093 lines
16 KiB
ArmAsm
LST OFF
|
|
|
|
ORG $900
|
|
|
|
XC ; Enable 65c02 ops
|
|
|
|
* This code is written bottom-up. That is,
|
|
* simple routines first, then routines that
|
|
* call those to build complexity. The main
|
|
* code is at the very end. We jump to it now.
|
|
JMP TEST
|
|
|
|
* Conditional assembly flags
|
|
DBLBUF = 0 ; whether to double-buffer
|
|
DEBUG = 0 ; turn on verbose logging
|
|
|
|
* Constants
|
|
TOPLINE = $2000
|
|
NLINES = 126
|
|
|
|
* My zero page
|
|
LINECT = $3 ; len 1
|
|
BUMP = $4 ; len 1
|
|
TXCOLNUM = $5 ; len 1
|
|
PLINE = $6 ; len 2
|
|
PDST = $8 ; len 2
|
|
PTEX = $A ; len 2
|
|
PBUMP = $C ; len 2
|
|
PIXNUM = $E ; len 1
|
|
BYTENUM = $F ; len 1
|
|
PTMP = $10 ; len 2
|
|
BACKBUF = $12 ; len 1 (value 0 or 1)
|
|
FRONTBUF = $13 ; len 1 (value 0 or 1)
|
|
PCAST = $14 ; len 2
|
|
|
|
* Monitor zero page
|
|
STARTADDR = $3C
|
|
ENDADDR = $3E
|
|
DESTADDR = $42
|
|
|
|
* Place to stick ProDOS names temporarily
|
|
NAMEBUF = $280
|
|
|
|
* Tables and buffers
|
|
SH0101 = $1000
|
|
SH0123 = $1100
|
|
SH0145 = $1200
|
|
SH0156 = $1300
|
|
SH0157 = $1400
|
|
SH4501 = $1500
|
|
SH4523 = $1600
|
|
SH4545 = $1700
|
|
SH4556 = $1800
|
|
SH4557 = $1900
|
|
BLITIDXL = $1A00 ; size $80
|
|
BLITIDXH = $1A80 ; size $80
|
|
DCMIDXL = $1B00 ; size $40 (one entry per two lines)
|
|
DCMIDXH = $1B40 ; size $40
|
|
X1B80 = $1B80 ; unused
|
|
DCMROLL = $1C00 ; size 11*(126/2) = 693 = $2B5, plus 1 for rts
|
|
CBLITROLL = $1F00 ; size 3*(126/2) = 189 = $BD, plus 1 for rts
|
|
|
|
PRODOSBUF = $1000 ; temporary, before tbls built
|
|
SCREEN = $2000
|
|
|
|
TEXTURES = $4000 ; size $5550 (5460 bytes x 4 textures)
|
|
TEXSIZE = 5460
|
|
TEX0 = TEXTURES
|
|
TEX1 = TEX0+TEXSIZE
|
|
TEX2 = TEX1+TEXSIZE
|
|
TEX3 = TEX2+TEXSIZE
|
|
UN9550 = $9550 ; unused
|
|
BLITROLL = $A000 ; size 29*126 = 3654 = $E80, plus 1 for rts
|
|
BUMPS = $AF00 ; len 64*64 = $1000
|
|
GLOBALPG = $BF00 ; ProDOS global page
|
|
MLI = GLOBALPG ; also the call point for ProDOS MLI
|
|
MEMMAP = $BF58
|
|
|
|
* I/O locations
|
|
KBD = $C000
|
|
CLRAUXRD = $C002
|
|
SETAUXRD = $C003
|
|
CLRAUXWR = $C004
|
|
SETAUXWR = $C005
|
|
CLRAUXZP = $C008
|
|
SETAUXZP = $C009
|
|
KBDSTRB = $C010
|
|
CLRTEXT = $C050
|
|
SETTEXT = $C051
|
|
CLRMIXED = $C052
|
|
SETMIXED = $C053
|
|
PAGE1 = $C054
|
|
PAGE2 = $C055
|
|
CLRHIRES = $C056
|
|
SETHIRES = $C057
|
|
|
|
* ROM routines
|
|
AUXMOVE = $C311
|
|
PRNTAX = $F941
|
|
RDKEY = $FD0C
|
|
CROUT = $FD8E
|
|
PRBYTE = $FDDA
|
|
COUT = $FDED
|
|
PRERR = $FF2D
|
|
MONITOR = $FF69
|
|
|
|
; Pixel offsets for even and odd blit lines
|
|
BLITOFFE DFB 5,8,11,1,17,20,24
|
|
BLITOFFO DFB 34,37,40,30,46,49,53
|
|
; texture addresses
|
|
TEXADRL DFB <TEX0,<TEX1,<TEX2,<TEX3
|
|
TEXADRH DFB >TEX0,>TEX1,>TEX2,>TEX3
|
|
; mip level offsets
|
|
MIPOFFL DFB <0,<4096,<5120,<5376,<5440,<5456,<5460
|
|
MIPOFFH DFB >0,>4096,>5120,>5376,>5440,>5456,>5460
|
|
|
|
NEXTLINE LDA PLINE+1 ; Hi byte of line
|
|
CLC
|
|
ADC #4 ; Next line is 1K up
|
|
TAX
|
|
EOR PLINE+1
|
|
AND #$20 ; Past end of screen?
|
|
BEQ :DONE ; If not, we're done
|
|
TXA
|
|
SEC
|
|
SBC #$20 ; Back to start
|
|
TAX
|
|
LDA PLINE ; Lo byte
|
|
CLC
|
|
ADC #$80 ; Inner blks offset by 128 bytes
|
|
STA PLINE
|
|
BCC :DONE
|
|
INX ; Next page
|
|
TXA
|
|
AND #7
|
|
CMP #4 ; Still inside inner blk?
|
|
BNE :DONE ; If so we're done
|
|
TXA
|
|
SEC
|
|
SBC #4 ; Back to start of inner blk
|
|
TAX
|
|
LDA PLINE
|
|
CLC
|
|
ADC #$28 ; Outer blks offset by 40 bytes
|
|
STA PLINE
|
|
:DONE STX PLINE+1
|
|
RTS
|
|
|
|
* Template for blitting code
|
|
|
|
BLITTPL ; comments show byte offset
|
|
* even rows
|
|
LDA SH0157 ; 0: pixel 3
|
|
ASL ; 3: save half of pix 3 in carry
|
|
ORA SH0101 ; 4: pixel 0
|
|
ORA SH0123 ; 7: pixel 1
|
|
ORA SH0145 ; 10: pixel 2
|
|
STA (0),Y ; 13: even column
|
|
INY ; 15: prep for odd
|
|
LDA SH0101 ; 16: pixel 4
|
|
ORA SH0123 ; 19: pixel 5
|
|
ROL ; 22: recover half of pix 3
|
|
ORA SH0156 ; 23: pixel 6 - after rol to ensure right hi bit
|
|
STA (0),Y ; 26: odd column
|
|
DEY ; 28: prep for even
|
|
* odd rows
|
|
LDA SH4557 ; 29: pixel 3
|
|
ASL ; 32: save half of pix 3 in carry
|
|
ORA SH4501 ; 33: pixel 0
|
|
ORA SH4523 ; 36: pixel 1
|
|
ORA SH4545 ; 39: pixel 2
|
|
STA (2),Y ; 42: even column
|
|
INY ; 44: prep for odd
|
|
LDA SH4501 ; 45: pixel 4
|
|
ORA SH4523 ; 48: pixel 5
|
|
ROL ; 51: recover half of pix 3
|
|
ORA SH4556 ; 52: pixel 6 - after rol to ensure right hi bit
|
|
STA (2),Y ; 55: odd column
|
|
DEY ; 57: prep for even
|
|
; 58: total
|
|
|
|
* Create the unrolled blit code
|
|
MAKEBLIT
|
|
LDA #0 ; Start with line zero
|
|
STA LINECT
|
|
LDA #<TOPLINE ; Begin with the first screen line
|
|
STA PLINE
|
|
LDA #>TOPLINE
|
|
STA PLINE+1
|
|
LDA #<BLITROLL ; Store to blit unroll code buf
|
|
STA PDST
|
|
LDA #>BLITROLL
|
|
STA PDST+1
|
|
:LINELUP
|
|
; Copy the template
|
|
LDY #57
|
|
:COPY LDA BLITTPL,Y
|
|
STA (PDST),Y
|
|
DEY
|
|
BPL :COPY
|
|
; Record the address for the even line
|
|
JSR :STIDX
|
|
; Set the even line pointers
|
|
LDY #14
|
|
JSR :STLINE
|
|
LDY #27
|
|
JSR :STLINE
|
|
; Get ready for odd line
|
|
JSR :ADVANCE
|
|
; Record the address for the odd line
|
|
JSR :STIDX
|
|
; Set the odd line pointers
|
|
LDY #14
|
|
JSR :STLINE
|
|
LDY #27
|
|
JSR :STLINE
|
|
; Prepare for next iteration
|
|
JSR :ADVANCE
|
|
; Loop until all lines are done
|
|
LDA LINECT
|
|
CMP #NLINES
|
|
BNE :LINELUP
|
|
JSR :STIDX ; Last addr to index
|
|
JMP STRTS ; Finish with RTS for cleanliness
|
|
:STLINE ; Subroutine to store PLINE to PDST
|
|
LDA LINECT
|
|
ASL
|
|
STA (PDST),Y
|
|
RTS
|
|
:STIDX ; Subroutine to store tbl ptr to index
|
|
LDY LINECT
|
|
LDA PDST
|
|
STA BLITIDXL,Y
|
|
LDA PDST+1
|
|
STA BLITIDXH,Y
|
|
RTS
|
|
:ADVANCE ; Subroutine to go to next unroll
|
|
LDA #29
|
|
JSR ADVPDST
|
|
INC LINECT
|
|
JMP NEXTLINE
|
|
|
|
* Create code to clear the blit
|
|
MAKECBLIT
|
|
LDX #0
|
|
LDY #0
|
|
:LUP LDA :ST
|
|
STA CBLITROLL,X
|
|
INX
|
|
LDA BLITIDXL,Y
|
|
STA CBLITROLL,X
|
|
INX
|
|
LDA BLITIDXH,Y
|
|
:ST STA CBLITROLL,X
|
|
INX
|
|
INY
|
|
INY
|
|
CPY #NLINES
|
|
BNE :LUP
|
|
LDA :RTS
|
|
STA CBLITROLL,X
|
|
:RTS RTS
|
|
|
|
* Clear the blit
|
|
CLRBLIT
|
|
LDA #0
|
|
CLRBLIT2
|
|
LDX BLITOFFE+0
|
|
JSR CBLITROLL
|
|
LDX BLITOFFE+1
|
|
JSR CBLITROLL
|
|
LDX BLITOFFE+2
|
|
JSR CBLITROLL
|
|
LDX BLITOFFE+3
|
|
JSR CBLITROLL
|
|
LDX BLITOFFE+4
|
|
JSR CBLITROLL
|
|
LDX BLITOFFE+5
|
|
JSR CBLITROLL
|
|
LDX BLITOFFE+6
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+0
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+1
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+2
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+3
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+4
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+5
|
|
JSR CBLITROLL
|
|
LDX BLITOFFO+6
|
|
JMP CBLITROLL
|
|
|
|
* Construct the shift tables
|
|
MAKESHIFT
|
|
LDX #0
|
|
:SH01
|
|
TXA
|
|
AND #3
|
|
:SH0101
|
|
STA SH0101,X
|
|
:SH0123
|
|
ASL
|
|
ASL
|
|
STA SH0123,X
|
|
:SH0145
|
|
ASL
|
|
ASL
|
|
ORA #$80
|
|
STA SH0145,X
|
|
:SH0156
|
|
ASL
|
|
ORA #$80
|
|
STA SH0156,X
|
|
:SH0157
|
|
ASL
|
|
ASL
|
|
PHP
|
|
LSR
|
|
PLP
|
|
ROR
|
|
STA SH0157,X
|
|
:SH45
|
|
TXA
|
|
LSR
|
|
LSR
|
|
LSR
|
|
LSR
|
|
AND #3
|
|
:SH4501
|
|
ORA #$80
|
|
STA SH4501,X
|
|
:SH4523
|
|
ASL
|
|
ASL
|
|
ORA #$80
|
|
STA SH4523,X
|
|
:SH4545
|
|
ASL
|
|
ASL
|
|
ORA #$80
|
|
STA SH4545,X
|
|
:SH4556
|
|
ASL
|
|
ORA #$80
|
|
STA SH4556,X
|
|
:SH4557
|
|
ASL
|
|
ASL
|
|
PHP
|
|
LSR
|
|
PLP
|
|
ROR
|
|
STA SH4557,X
|
|
:NEXT
|
|
INX
|
|
BNE :SH01
|
|
RTS
|
|
|
|
* Template for decimation. Offsets in comments
|
|
DCMTPL
|
|
LDA (PTEX),Y ; 0
|
|
STA BLITROLL,X ; 2
|
|
STA BLITROLL+29,X ; 5
|
|
LDA (PBUMP),Y ; 8
|
|
TAY ; 10
|
|
; 11
|
|
|
|
* Unroll the decimation code
|
|
MAKEDCM
|
|
LDX #0 ; Line counter
|
|
LDA #<DCMROLL
|
|
STA PDST
|
|
LDA #>DCMROLL
|
|
STA PDST+1
|
|
:ONESET
|
|
; Save address to the index
|
|
JSR :STIDX
|
|
LDY #11 ; Copy the template
|
|
:COPYSET LDA DCMTPL,Y
|
|
STA (PDST),Y
|
|
DEY
|
|
BPL :COPYSET
|
|
LDY #3
|
|
JSR :STBLIT
|
|
LDY #6
|
|
JSR :STBLIT
|
|
LDA #11
|
|
JSR ADVPDST
|
|
:MORE
|
|
; Loop until all lines done
|
|
CPX #NLINES
|
|
BCC :ONESET
|
|
JSR :STIDX ; Last addr to index
|
|
JMP STRTS ; Finish with an RTS for cleanliness
|
|
:STBLIT ; Store current blit addr
|
|
LDA BLITIDXL,X
|
|
STA (PDST),Y
|
|
INY
|
|
LDA BLITIDXH,X
|
|
STA (PDST),Y
|
|
INX ; Next line
|
|
RTS
|
|
:STIDX
|
|
TXA
|
|
LSR ; One entry per two lines
|
|
TAY
|
|
LDA PDST
|
|
STA DCMIDXL,Y
|
|
LDA PDST+1
|
|
STA DCMIDXH,Y
|
|
RTS
|
|
|
|
STRTS LDA #$60 ; Store an RTS at PDST
|
|
LDY #0
|
|
STA (PDST),Y
|
|
RTS
|
|
ADVPDST ; Add A to PDST
|
|
CLC
|
|
ADC PDST
|
|
STA PDST
|
|
BCC :RTS
|
|
INC PDST+1
|
|
:RTS RTS
|
|
|
|
* Clear all the memory we're going to fill
|
|
CLRMEM
|
|
LDX #$10
|
|
LDA #$BE
|
|
JMP CLRSCR2
|
|
|
|
* Clear the screens
|
|
CLRSCR
|
|
LDX #>SCREEN
|
|
DO DBLBUF
|
|
LDA #>SCREEN+$4000 ; both hi-res screens
|
|
ELSE
|
|
LDA #>SCREEN+$2000 ; one hi-res screen
|
|
FIN
|
|
CLRSCR2
|
|
STA :LIMIT+1
|
|
LDY #0
|
|
STY PDST
|
|
TYA
|
|
:OUTER STX PDST+1
|
|
:INNER STA (PDST),Y
|
|
INY
|
|
BNE :INNER
|
|
INX
|
|
:LIMIT CPX #>SCREEN+$2000
|
|
BNE :OUTER
|
|
RTS
|
|
|
|
* Make a simple texture with alternating colors.
|
|
* Input: Y = tex num
|
|
* A, X: color numbers, 0-3
|
|
SIMPLETEX
|
|
STA :LD1+1
|
|
TXA
|
|
ASL
|
|
ASL
|
|
ASL
|
|
ASL
|
|
STA :LD2+1
|
|
LDA TEXADRL,Y
|
|
STA PDST
|
|
LDA TEXADRH,Y
|
|
STA PDST+1
|
|
LDX #>TEXSIZE
|
|
LDY #0
|
|
STY :LIM+1
|
|
:OUTER
|
|
:LD1 LDA #0
|
|
:LD2 ORA #0
|
|
:LUP STA (PDST),Y
|
|
INY
|
|
:LIM CPY #0
|
|
BNE :LUP
|
|
INC PDST+1
|
|
DEX
|
|
BMI :DONE
|
|
BNE :OUTER
|
|
LDA #<TEXSIZE ; partial last page
|
|
STA :LIM+1
|
|
JMP :OUTER
|
|
:DONE
|
|
RTS
|
|
|
|
* Generate the table of "bumps" for decimation
|
|
MAKEBUMPS
|
|
LDA #63 ; 126/2 bump lists
|
|
STA LINECT
|
|
LDA #<BUMPS
|
|
STA PDST
|
|
LDA #>BUMPS
|
|
STA PDST+1
|
|
LDA #0
|
|
STA :RATIOL
|
|
LDA #1
|
|
STA :RATIOH
|
|
* Goal is to make ratio = 63 divided by targetSize.
|
|
* The calculation is cool & weird, but I verified
|
|
* in Python that the logic actually works. You
|
|
* start with hi=1, lo=0. To calculate the next
|
|
* step, add hi to low and take the sum mod the next
|
|
* target size. To use the ratio, increment by hi
|
|
* and lo. Whenever the low byte goes beyond the
|
|
* target size, add an extra to hi.
|
|
:ONEPASS
|
|
LDA LINECT ; Init A with the lo byte = target size
|
|
LSR ; ...div 2
|
|
LDX #0 ; Hi byte always starts at zero
|
|
LDY #0 ; Location to store at
|
|
:BUMPLUP
|
|
CLC ; increment lo byte by ratio
|
|
ADC :RATIOL
|
|
CMP LINECT ; if we wrap around, need extra hi-byte bump
|
|
BCC :NOBM
|
|
SEC
|
|
SBC LINECT
|
|
INX
|
|
:NOBM PHA ; save lo byte
|
|
TXA ; now work on hi byte
|
|
CLC
|
|
ADC :RATIOH
|
|
TAX
|
|
STA (PDST),Y ; store to the table
|
|
TAY ; next loc to store
|
|
CPX #63 ; check for end of column
|
|
PLA ; get lo byte back
|
|
BCC :BUMPLUP ; loop until whole column is done
|
|
LDA #64
|
|
JSR ADVPDST ; advance dst to next column
|
|
:NEXT
|
|
DEC LINECT ; all columns complete?
|
|
BEQ :DONE
|
|
LDA :RATIOL ; next ratio calculation (see explanation above)
|
|
CLC
|
|
ADC :RATIOH
|
|
:MODLUP CMP LINECT
|
|
BCC :NOMOD
|
|
INC :RATIOH
|
|
SEC
|
|
SBC LINECT
|
|
BNE :MODLUP ; this must indeed be a loop
|
|
:NOMOD STA :RATIOL
|
|
JMP :ONEPASS ; next column
|
|
:DONE RTS
|
|
:RATIOL DFB 0
|
|
:RATIOH DFB 0
|
|
|
|
* Decimate a column of the texture
|
|
* Input: Y - texture number
|
|
* TXCOLNUM - src column num in the texture
|
|
* PIXNUM - dst pixel num in the blit roll
|
|
* LINECT - height to render, in dbl lines
|
|
* The output will be vertically centered.
|
|
DCMCOL
|
|
; if height is zero, render nothing
|
|
LDA LINECT
|
|
BNE :NOTZERO
|
|
RTS
|
|
:NOTZERO
|
|
; determine mip level in X reg
|
|
LDX #0
|
|
LDA LINECT
|
|
STA :ADJHT
|
|
LDA TXCOLNUM
|
|
STA :ADJCOL
|
|
LDA #32
|
|
:MIPLUP CMP LINECT
|
|
BCC :GOTMIP
|
|
INX
|
|
ASL :ADJHT
|
|
LSR :ADJCOL
|
|
LSR
|
|
CMP #2
|
|
BCS :MIPLUP
|
|
:GOTMIP
|
|
DO DEBUG
|
|
LDA #"t"
|
|
JSR COUT
|
|
TYA
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
|
|
LDA #"h"
|
|
JSR COUT
|
|
LDA LINECT
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
|
|
LDA #"m"
|
|
JSR COUT
|
|
TXA
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
FIN
|
|
|
|
; calc addr of tex
|
|
LDA TEXADRL,Y
|
|
CLC
|
|
ADC MIPOFFL,X
|
|
STA PDST
|
|
LDA TEXADRH,Y
|
|
ADC MIPOFFH,X
|
|
STA PDST+1
|
|
|
|
DO DEBUG
|
|
LDA #"a"
|
|
JSR COUT
|
|
LDA PDST+1
|
|
JSR PRBYTE
|
|
LDA PDST
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
FIN
|
|
|
|
:CALCOFF ; calc offset within tex
|
|
LDA #0
|
|
STA PTEX+1
|
|
LDA :ADJCOL
|
|
:SHIFT ASL
|
|
ROL PTEX+1
|
|
INX ; Note: destroys mip level
|
|
CPX #6
|
|
BNE :SHIFT
|
|
|
|
DO DEBUG
|
|
PHA
|
|
LDA #"x"
|
|
JSR COUT
|
|
LDA :ADJCOL
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
|
|
LDA #"o"
|
|
JSR COUT
|
|
LDA PTEX+1
|
|
JSR PRBYTE
|
|
PLA
|
|
PHA
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
PLA
|
|
FIN
|
|
|
|
CLC
|
|
ADC PDST
|
|
STA PTEX
|
|
LDA PTEX+1
|
|
ADC PDST+1
|
|
STA PTEX+1
|
|
; calculate bump table ptr
|
|
LDX :ADJHT
|
|
JSR CALCBUMP
|
|
; figure first line in decim unroll
|
|
LDA #63
|
|
SEC
|
|
SBC LINECT ; height 63 is first in decim tbl
|
|
LSR
|
|
TAX
|
|
LDA DCMIDXL,X
|
|
STA :CALL+1
|
|
LDA DCMIDXH,X
|
|
STA :CALL+2
|
|
; figure last line of decim unroll
|
|
TXA
|
|
CLC
|
|
ADC LINECT
|
|
TAX
|
|
LDA DCMIDXL,X
|
|
STA PTMP
|
|
LDA DCMIDXH,X
|
|
STA PTMP+1
|
|
; determine blit offset for writing
|
|
LDY PIXNUM
|
|
LDX BLITOFFE,Y
|
|
; store RTS so decim returns @ right moment
|
|
LDY #0
|
|
LDA (PTMP),Y ; save existing byte
|
|
PHA
|
|
LDA :RTS
|
|
STA (PTMP),Y
|
|
|
|
DO DEBUG
|
|
PHX
|
|
PHY
|
|
JSR RDKEY
|
|
PHA
|
|
JSR CROUT
|
|
PLA
|
|
PLY
|
|
PLX
|
|
CMP #$9B
|
|
BNE :NOTESC
|
|
BRK
|
|
:NOTESC NOP
|
|
FIN
|
|
|
|
:CALL JSR DCMROLL
|
|
; fix RTS to what it was before
|
|
LDY #0
|
|
PLA
|
|
STA (PTMP),Y
|
|
|
|
DO DEBUG
|
|
LDY BYTENUM ; to see results early
|
|
STA SETAUXZP
|
|
JSR BLITROLL
|
|
STA CLRAUXZP
|
|
FIN
|
|
|
|
:RTS RTS
|
|
:ADJHT DFB 0
|
|
:ADJCOL DFB 0
|
|
|
|
* Calc pointer into the bump table
|
|
* Input: X - height to render in dbl lines
|
|
CALCBUMP
|
|
STX :SUB+1
|
|
LDA #0
|
|
STA PBUMP+1
|
|
LDA #63 ; bump 63 is actually first
|
|
SEC
|
|
:SUB SBC #0
|
|
BPL :NOTNEG
|
|
LDA #0
|
|
:NOTNEG
|
|
|
|
DO DEBUG
|
|
PHA
|
|
LDA #"b"
|
|
JSR COUT
|
|
PLA
|
|
PHA
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
PLA
|
|
FIN
|
|
|
|
LDX #6
|
|
:LUP ASL
|
|
ROL PBUMP+1
|
|
DEX
|
|
BNE :LUP
|
|
CLC
|
|
ADC #<BUMPS
|
|
STA PBUMP
|
|
LDA PBUMP+1
|
|
ADC #>BUMPS
|
|
STA PBUMP+1
|
|
|
|
DO DEBUG
|
|
LDA #"p"
|
|
JSR COUT
|
|
LDA PBUMP+1
|
|
JSR PRBYTE
|
|
LDA PBUMP
|
|
JSR PRBYTE
|
|
LDA #" "
|
|
JSR COUT
|
|
FIN
|
|
|
|
RTS
|
|
|
|
* Build table of screen line pointers
|
|
* on aux zero-page
|
|
MAKELINES
|
|
LDA #0
|
|
STA LINECT
|
|
LDA #<TOPLINE
|
|
STA PLINE
|
|
LDA #>TOPLINE
|
|
STA PLINE+1
|
|
:LUP
|
|
LDA LINECT
|
|
ASL
|
|
TAX
|
|
LDA PLINE
|
|
LDY PLINE+1
|
|
STA SETAUXZP
|
|
STA 0,X
|
|
STY 1,X
|
|
STA CLRAUXZP
|
|
JSR NEXTLINE
|
|
INC LINECT
|
|
LDA LINECT
|
|
CMP #NLINES
|
|
BNE :LUP
|
|
RTS
|
|
|
|
* Set screen lines to current back buf
|
|
SETBKBUF
|
|
; calculate screen start
|
|
LDA BACKBUF
|
|
ASL
|
|
ASL
|
|
ASL
|
|
ASL
|
|
ASL
|
|
CLC
|
|
ADC #$20
|
|
STA SETAUXZP
|
|
STA $FF
|
|
LDX #0
|
|
:LUP LDA 1,X
|
|
AND #$1F
|
|
ORA $FF
|
|
STA 1,X
|
|
INX
|
|
INX
|
|
BNE :LUP
|
|
STA CLRAUXZP
|
|
RTS
|
|
|
|
* Load file, len-prefixed name in A/X (hi/lo), to addr on stack
|
|
* (push hi byte first, then push lo byte)
|
|
BLOAD
|
|
STX :MLICMD+1 ; filename lo
|
|
STA :MLICMD+2 ; filename hi
|
|
LDA #<PRODOSBUF
|
|
STA :MLICMD+3
|
|
LDA #>PRODOSBUF
|
|
STA :MLICMD+4
|
|
LDA #$C8 ; open
|
|
LDX #3
|
|
JSR :DOMLI
|
|
LDA :MLICMD+5 ; get handle and put it in place
|
|
STA :MLICMD+1
|
|
PLY ; save ret addr
|
|
PLX
|
|
PLA
|
|
STA :MLICMD+2 ; load addr lo
|
|
PLA
|
|
STA :MLICMD+3 ; load addr hi
|
|
PHX ; restore ret addr
|
|
PHY
|
|
LDA #$CA ; read
|
|
STA :MLICMD+5 ; also length (more than enough)
|
|
LDX #4
|
|
JSR :DOMLI
|
|
:CLOSE
|
|
STZ :MLICMD+1 ; close all
|
|
LDA #$CC
|
|
LDX #1
|
|
; fall through
|
|
:DOMLI
|
|
STA :MLIOP
|
|
STX :MLICMD
|
|
JSR MLI
|
|
:MLIOP DFB 0
|
|
DA :MLICMD
|
|
BCS :ERR
|
|
RTS
|
|
:ERR JSR PRBYTE
|
|
JSR PRERR
|
|
LDX #$FF
|
|
TXS
|
|
JMP MONITOR
|
|
:MLICMD DS 10
|
|
|
|
* Copy X pages starting at pg Y to aux mem
|
|
CPTOAUX
|
|
STA SETAUXWR
|
|
STY PDST+1
|
|
LDY #0
|
|
STY PDST
|
|
:LUP LDA (PDST),Y
|
|
STA (PDST),Y
|
|
INY
|
|
BNE :LUP
|
|
INC PDST+1
|
|
DEX
|
|
BNE :LUP
|
|
STA CLRAUXWR
|
|
RTS
|
|
|
|
* Fetch the next byte from the pre-raycasted data
|
|
* Note this routine needs to be copied to aux mem.
|
|
GETCAST
|
|
LDY #0
|
|
STA SETAUXRD
|
|
LDA (PCAST),Y
|
|
STA CLRAUXRD
|
|
INC PCAST
|
|
BNE :DONE
|
|
INC PCAST+1
|
|
:DONE RTS
|
|
|
|
* Test code to see if things really work
|
|
TEST
|
|
; clear ProDOS mem map so it lets us load
|
|
LDX #$18
|
|
LDA #1
|
|
:MEMLUP
|
|
STA MEMMAP-1,X
|
|
LDA #0
|
|
DEX
|
|
BNE :MEMLUP
|
|
; load the pre-raycast data
|
|
LDA #$20 ; addr hi
|
|
PHA
|
|
LDA #0 ; addr lo
|
|
PHA
|
|
LDX #<:PRECASTNM
|
|
LDA #>:PRECASTNM
|
|
JSR BLOAD
|
|
; copy it to aux mem
|
|
LDY #$20
|
|
LDX #$60
|
|
JSR CPTOAUX
|
|
LDA #0 ; set ptr to it
|
|
STA PCAST
|
|
LDA #$20
|
|
STA PCAST+1
|
|
; copy the raycast fetcher to aux mem
|
|
LDY #>GETCAST
|
|
LDX #1
|
|
JSR CPTOAUX
|
|
; set up everything else
|
|
JSR CLRMEM
|
|
; load the textures
|
|
LDA #>TEX0
|
|
PHA
|
|
LDA #<TEX0
|
|
PHA
|
|
LDX #<:TEX0NAME
|
|
LDA #>:TEX0NAME
|
|
JSR BLOAD
|
|
|
|
LDA #>TEX1
|
|
PHA
|
|
LDA #<TEX1
|
|
PHA
|
|
LDX #<:TEX1NAME
|
|
LDA #>:TEX1NAME
|
|
JSR BLOAD
|
|
|
|
LDA #>TEX2
|
|
PHA
|
|
LDA #<TEX2
|
|
PHA
|
|
LDX #<:TEX2NAME
|
|
LDA #>:TEX2NAME
|
|
JSR BLOAD
|
|
|
|
LDA #>TEX3
|
|
PHA
|
|
LDA #<TEX3
|
|
PHA
|
|
LDX #<:TEX3NAME
|
|
LDA #>:TEX3NAME
|
|
JSR BLOAD
|
|
; build all the unrolls and tables
|
|
JSR MAKEBLIT
|
|
JSR MAKECBLIT
|
|
JSR MAKESHIFT
|
|
JSR MAKEDCM
|
|
JSR MAKEBUMPS
|
|
JSR MAKELINES
|
|
JSR CLRSCR
|
|
; set up front and back buffers
|
|
LDA #0
|
|
STA FRONTBUF
|
|
DO DBLBUF
|
|
LDA #1
|
|
FIN
|
|
STA BACKBUF
|
|
|
|
BIT CLRTEXT
|
|
BIT SETHIRES
|
|
|
|
LDA #63
|
|
STA LINECT
|
|
LDA #1
|
|
STA :DIR
|
|
JSR CLRBLIT
|
|
:ONELVL
|
|
LDA #0
|
|
STA PIXNUM
|
|
STA BYTENUM
|
|
DO DBLBUF
|
|
JSR SETBKBUF
|
|
FIN
|
|
|
|
DO DEBUG
|
|
LDA PCAST+1
|
|
JSR PRBYTE
|
|
LDA PCAST
|
|
JSR PRBYTE
|
|
JSR CROUT
|
|
FIN
|
|
|
|
:ONECOL
|
|
JSR GETCAST ; first byte is height
|
|
CMP #$FF
|
|
BNE :NORESET
|
|
; found end of cast data, start over
|
|
LDA #0
|
|
STA PCAST
|
|
LDA #$20
|
|
STA PCAST+1
|
|
JSR GETCAST
|
|
:NORESET
|
|
CMP #63
|
|
BCC :HTOK
|
|
LDA #62
|
|
:HTOK STA LINECT
|
|
JSR GETCAST ; second byte is tex num and tex col
|
|
PHA
|
|
AND #$3F
|
|
CMP #63
|
|
BCC :COLOK
|
|
LDA #62
|
|
:COLOK STA TXCOLNUM
|
|
PLA
|
|
LSR ; div by 64
|
|
LSR
|
|
LSR
|
|
LSR
|
|
LSR
|
|
LSR
|
|
TAY ; Y now holds tex num
|
|
JSR DCMCOL
|
|
INC PIXNUM
|
|
LDA PIXNUM
|
|
CMP #7
|
|
BNE :ONECOL
|
|
:FLUSH LDY BYTENUM
|
|
STA SETAUXZP
|
|
JSR BLITROLL
|
|
STA CLRAUXZP
|
|
JSR CLRBLIT
|
|
LDA #0
|
|
STA PIXNUM
|
|
INC BYTENUM
|
|
INC BYTENUM
|
|
LDA BYTENUM
|
|
CMP #18
|
|
BNE :ONECOL
|
|
:NEXTLVL
|
|
; flip onto the screen
|
|
DO DBLBUF
|
|
LDX BACKBUF
|
|
LDA FRONTBUF
|
|
STA BACKBUF
|
|
STX FRONTBUF
|
|
LDA PAGE1,X
|
|
FIN
|
|
; adv past FE in cast data
|
|
JSR GETCAST
|
|
CMP #$FE
|
|
BNE :ERR
|
|
JSR GETCAST
|
|
CMP #$FE
|
|
BEQ :INCDEC
|
|
:ERR BRK
|
|
:INCDEC
|
|
LDA KBD ; stop if ESC is pressed
|
|
CMP #$9B
|
|
BEQ :DONE
|
|
JMP :ONELVL
|
|
:DONE
|
|
STA KBDSTRB ; eat the keypress
|
|
BIT SETTEXT
|
|
BIT PAGE1
|
|
RTS
|
|
:DIR DFB 1
|
|
:TEX0NAME DFB 21
|
|
ASC "ASSETS/BUILDING01.BIN"
|
|
:TEX1NAME DFB 21
|
|
ASC "ASSETS/BUILDING02.BIN"
|
|
:TEX2NAME DFB 21
|
|
ASC "ASSETS/BUILDING03.BIN"
|
|
:TEX3NAME DFB 21
|
|
ASC "ASSETS/BUILDING04.BIN"
|
|
:PRECASTNM
|
|
DFB 18
|
|
ASC "ASSETS/PRECAST.BIN"
|
|
|
|
SAV RENDER
|