mirror of
https://github.com/bobbimanners/Applecorn.git
synced 2024-11-15 19:07:03 +00:00
342 lines
10 KiB
ArmAsm
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 ;*****
|
|
|
|
|