Applecorn/fdraw/fdraw.tables.s
2021-09-21 22:59:11 -04:00

342 lines
10 KiB
ArmAsm

********************************
* *
* Fast Apple II Graphics *
* By Andy McFadden *
* Version 0.3, Aug 2015 *
* *
* Pre-computed data and *
* large internal buffers. *
* (Included by FDRAW.S) *
* *
* Developed with Merlin-16 *
* *
********************************
* Expected layout with alignment:
*
* P1 ylooklo, misc tables
* P2 ylookhi, colorline
* P3 rastx0l
* P4 rastx0h
* P5 rastx1l
* P6 rastx1h, div7hi, mod7hi
* P7 div7lo
* P8 mod7lo
* P9 rast_unroll, rastunidx
*
* Tables should be just under $900 bytes.
PG_ALIGN
* Hi-res Y lookup, low part (192 bytes).
ylooklo HEX 0000000000000000
HEX 8080808080808080
HEX 0000000000000000
HEX 8080808080808080
HEX 0000000000000000
HEX 8080808080808080
HEX 0000000000000000
HEX 8080808080808080
HEX 2828282828282828
HEX a8a8a8a8a8a8a8a8
HEX 2828282828282828
HEX a8a8a8a8a8a8a8a8
HEX 2828282828282828
HEX a8a8a8a8a8a8a8a8
HEX 2828282828282828
HEX a8a8a8a8a8a8a8a8
HEX 5050505050505050
HEX d0d0d0d0d0d0d0d0
HEX 5050505050505050
HEX d0d0d0d0d0d0d0d0
HEX 5050505050505050
HEX d0d0d0d0d0d0d0d0
HEX 5050505050505050
HEX d0d0d0d0d0d0d0d0
* Color masks for odd/even bytes, colors 0-7.
evencolor dfb $00,$2a,$55,$7f,$80,$aa,$d5,$ff
oddcolor dfb $00,$55,$2a,$7f,$80,$d5,$aa,$ff
* XOR mask for colors 0-7 - non-BW flip on odd/even.
xormask dfb $00,$7f,$7f,$00,$00,$7f,$7f,$00
* AND mask for the 7 pixel positions, high bit set
* for the color shift.
andmask dfb $81,$82,$84,$88,$90,$a0,$c0
* These are pixel AND masks, used with the modulo 7
* result. Entry #2 in leftmask means we're touching
* the rightmost 5 pixels, and entry #2 in rightmask
* means we're touching the 3 leftmost pixels.
*
* The high bit is always set, because we want to
* keep the color's high bit.
leftmask dfb $ff,$fe,$fc,$f8,$f0,$e0,$c0
rightmask dfb $81,$83,$87,$8f,$9f,$bf,$ff
PG_ALIGN
* Hi-res Y lookup, high part (192 bytes).
* OR with $20 or $40.
ylookhi HEX 0004080c1014181c
HEX 0004080c1014181c
HEX 0105090d1115191d
HEX 0105090d1115191d
HEX 02060a0e12161a1e
HEX 02060a0e12161a1e
HEX 03070b0f13171b1f
HEX 03070b0f13171b1f
HEX 0004080c1014181c
HEX 0004080c1014181c
HEX 0105090d1115191d
HEX 0105090d1115191d
HEX 02060a0e12161a1e
HEX 02060a0e12161a1e
HEX 03070b0f13171b1f
HEX 03070b0f13171b1f
HEX 0004080c1014181c
HEX 0004080c1014181c
HEX 0105090d1115191d
HEX 0105090d1115191d
HEX 02060a0e12161a1e
HEX 02060a0e12161a1e
HEX 03070b0f13171b1f
HEX 03070b0f13171b1f
* Masks for current color (even/odd), e.g. 55 2a 55 2a ...
* Updated whenever the color changes.
colorline ds 40
PG_ALIGN
rastx0l ds NUM_ROWS
PG_ALIGN
rastx0h ds NUM_ROWS
ds 1 ;repeat mode can overstep
PG_ALIGN
rastx1l ds NUM_ROWS
PG_ALIGN
rastx1h ds NUM_ROWS
* Lookup tables for dividing 0-279 by 7. The "hi"
* parts are 24 bytes each, so they fit inside
* the previous 192-byte entry. The "lo" parts
* each fill a page.
div7hi HEX 2424242525252525
HEX 2525262626262626
HEX 2627272727272727
mod7hi HEX 0405060001020304
HEX 0506000102030405
HEX 0600010203040506
PG_ALIGN
div7lo HEX 0000000000000001
HEX 0101010101010202
HEX 0202020202030303
HEX 0303030304040404
HEX 0404040505050505
HEX 0505060606060606
HEX 0607070707070707
HEX 0808080808080809
HEX 0909090909090a0a
HEX 0a0a0a0a0a0b0b0b
HEX 0b0b0b0b0c0c0c0c
HEX 0c0c0c0d0d0d0d0d
HEX 0d0d0e0e0e0e0e0e
HEX 0e0f0f0f0f0f0f0f
HEX 1010101010101011
HEX 1111111111111212
HEX 1212121212131313
HEX 1313131314141414
HEX 1414141515151515
HEX 1515161616161616
HEX 1617171717171717
HEX 1818181818181819
HEX 1919191919191a1a
HEX 1a1a1a1a1a1b1b1b
HEX 1b1b1b1b1c1c1c1c
HEX 1c1c1c1d1d1d1d1d
HEX 1d1d1e1e1e1e1e1e
HEX 1e1f1f1f1f1f1f1f
HEX 2020202020202021
HEX 2121212121212222
HEX 2222222222232323
HEX 2323232324242424
mod7lo HEX 0001020304050600
HEX 0102030405060001
HEX 0203040506000102
HEX 0304050600010203
HEX 0405060001020304
HEX 0506000102030405
HEX 0600010203040506
HEX 0001020304050600
HEX 0102030405060001
HEX 0203040506000102
HEX 0304050600010203
HEX 0405060001020304
HEX 0506000102030405
HEX 0600010203040506
HEX 0001020304050600
HEX 0102030405060001
HEX 0203040506000102
HEX 0304050600010203
HEX 0405060001020304
HEX 0506000102030405
HEX 0600010203040506
HEX 0001020304050600
HEX 0102030405060001
HEX 0203040506000102
HEX 0304050600010203
HEX 0405060001020304
HEX 0506000102030405
HEX 0600010203040506
HEX 0001020304050600
HEX 0102030405060001
HEX 0203040506000102
HEX 0304050600010203
* RastFill unrolled loop. At each step we store the current
* color value, XOR it to flip the bits if needed, and advance.
* The caller needs to set the appropriate initial value based
* on whether the address is odd or even.
*
* We can use a 3-cycle "EOR dp" or a 2-cycle "EOR imm". The
* former is one cycle slower, the latter requires us to
* self-mod 40 instructions when the color changes.
*
* This must be page-aligned so that we can take the value
* from the rastunidx table and self-mod a JMP without having
* to do a 16-bit add. We have just enough room for the
* unrolled loop (40*5+3) and x5 table (41) = 244 bytes, fits
* on a single page.
do USE_FAST ;*****
ds \
]hbasl equ zptr0 ;must match FillRaster
rast_unroll equ *
lst off
lup BYTES_PER_ROW
sta (]hbasl),y ;6
eor #$00 ;2
iny ;2 10 cycles, 5 bytes
--^
jmp rastlinedone
* Index into rast_unroll. If we need to output N bytes,
* we want to jump to (rast_unroll + (40 - N) * 5) (where
* 5 is the number of bytes per iteration).
rastunidx
]offset = BYTES_PER_ROW*5
lup BYTES_PER_ROW+1 ;0-40
dfb ]offset
]offset = ]offset-5
--^
fin ;*****
********************************
*
* Code used to generate tables above. If you want to
* decrease load size, use these functions to generate
* the data into empty memory, then discard the code.
* (Maybe use a negative DS and overlap with rastx0l?)
*
********************************
DO 0 ;*****
init_ylook
]hbasl equ zptr1
]hbash equ zptr1+1
* Initialize Y-lookup table. We just call the bascalc
* function.
ldx #NUM_ROWS
ldy #NUM_ROWS-1
]loop tya
jsr bascalc
lda hbasl
sta ylooklo,y
lda hbash
ora #$20 ;remove for $0000 base
sta ylookhi,y
dey
dex
bne ]loop
rts
* Hi-res base address calculation. This is based on the
* HPOSN routine at $F411.
*
* Call with the line in A. The results are placed into
* zptr1. X and Y are not disturbed.
*
* The value is in the $0000-1fff range, so you must OR
* the desired hi-res page in.
*
bascalc
pha
and #$c0
sta ]hbasl
lsr
lsr
ora ]hbasl
sta ]hbasl
pla
sta ]hbash
asl
asl
asl
rol ]hbash
asl
rol ]hbash
asl
ror ]hbasl
lda ]hbash
and #$1f
sta ]hbash
rts
*
* Create divide-by-7 tables.
*
mkdivtab
]val equ zloc0
ldy #0
sty ]val
ldx #0
]loop lda ]val
sta div7lo,y
txa
sta mod7lo,y
inx
iny
beq :lodone
cpx #7
bne ]loop
inc ]val
ldx #0
beq ]loop ;always
:lodone ;safe to ignore ]va update
]loop lda ]val
sta div7hi,y
txa
sta mod7hi,y
iny
cpy #280-256
beq :hidone
inx
cpx #7
bne ]loop
inc ]val
ldx #0
beq ]loop ;always
:hidone rts
FIN ;*****