diff --git a/src/fx/fx.hgr.48boxes.a b/src/fx/fx.hgr.48boxes.a index 23216b01d..6887094e2 100644 --- a/src/fx/fx.hgr.48boxes.a +++ b/src/fx/fx.hgr.48boxes.a @@ -5,308 +5,8 @@ !to "build/FX/BOXES48",plain *=$6000 -box = $F8 ; [byte] -stage = $F9 ; [byte] -any = $FA ; [byte] -rowcount = $FB ; [byte] -src = $FC ; [word] -dst = $FE ; [word] -hgrlo = $00 ; [$C0 bytes] -hgrhi = $300 ; [$C0 bytes] -BoxStages = $C0 ; [$30 bytes] + !source "src/fx/fx.hgr.48boxes.common.a" -; recalculate HGR base addresses -; in: X = HGR row (00..BF) -; out: preserves X, Y -; clobbers A -!macro RECALC .copyflag { - lda hgrlo, x -!if .copyflag { - sta src -} - sta dst - lda hgrhi, x - sta dst+1 -!if .copyflag { - eor #$60 - sta src+1 -} -} - -; increase X by an arbitrary amount, and recalculate HGR base addresses -; clobbers A -!macro INX_BY .val, .copyflag { - txa - clc - adc #.val - tax - +RECALC .copyflag -} - -; increase X, and recalculate HGR base addresses -!macro INX .copyflag { - inx - +RECALC .copyflag -} - -; clear or copy 1 byte -!macro COPY .copyflag { -!if .copyflag { - lda (src), y -} else { - lda #0 -} - sta (dst), y -} - -; clear or copy certain bits based on bitmask -!macro MASKCOPY .mask, .copyflag { - lda (dst), y -!if .copyflag { - eor (src), y -} - and #.mask - eor (dst), y - sta (dst), y -} - -!macro STAGE0 .copyflag { - +INX_BY $0F, .copyflag - iny - iny - +MASKCOPY %10111110, .copyflag - +INX .copyflag - +MASKCOPY %10111110, .copyflag - rts -} - -!macro STAGE1 .copyflag { - +INX_BY $0E, .copyflag - iny - iny - +COPY .copyflag - +INX .copyflag - +COPY .copyflag - +INX .copyflag - +COPY .copyflag - +INX .copyflag - +COPY .copyflag - rts -} - -!macro MIDDLE_STAGE .firstrow, .rowcount, .edgeleftmask, .edgerightmask, .leftmask, .rightmask, .copyflag { - lda #.rowcount - sta rowcount - +INX_BY .firstrow, .copyflag - iny --- -!if .edgeleftmask != .leftmask { - +MASKCOPY .edgeleftmask, .copyflag -} - iny - +COPY .copyflag -!if .edgerightmask != .rightmask { - iny - +MASKCOPY .edgerightmask, .copyflag - dey -} - dey -- - +MASKCOPY .leftmask, .copyflag - iny - iny - +MASKCOPY .rightmask, .copyflag - dey - dey - +INX .copyflag - dec rowcount - beq -- - bpl - - rts -} - -!macro OUTER_STAGE .firstrow, .rowcount, .edgeleftmask, .edgerightmask, .leftmask, .rightmask, .copyflag { - lda #.rowcount - sta rowcount - +INX_BY .firstrow, .copyflag --- -!if .edgeleftmask != .leftmask { - +MASKCOPY .edgeleftmask, .copyflag -} - iny - +COPY .copyflag - iny - +COPY .copyflag - iny - +COPY .copyflag -!if .edgerightmask != .rightmask { - iny - +MASKCOPY .edgerightmask, .copyflag - dey -} - dey - dey - dey -- - +MASKCOPY .leftmask, .copyflag - iny - iny - iny - iny - +MASKCOPY .rightmask, .copyflag - dey - dey - dey - dey - +INX .copyflag - dec rowcount - beq -- - bpl - - rts -} - - !source "src/fx/macros.a" - -; actual code starts here - - +BUILD_HGR_LOOKUP_TABLES hgrlo, hgrhi - ldx #47 -- lda BoxInitialStages, x - sta BoxStages, x - dex - bpl - -MainLoop lda #0 - sta any - ldx #47 -BoxLoop stx box - lda BoxStages, x ; for each box, get its current stage - bmi NextBox ; if stage >= $80, nothing to do - tax - lda StagesHi, x - beq NextBox ; if stage's drawing routine is 0, nothing to do - sta j+2 - lda StagesLo, x - sta j+1 - ldx box - lda BoxesX, x - ldy BoxesY, x ; Y = starting byte offset for this box - tax ; X = starting HGR row for this box - inc any -j jsr $FDFD ; [SMC] call drawing routine for this stage -NextBox ldx box - inc BoxStages, x ; increment every box's stage every time through the loop, - ; even if we didn't call a drawing routine - dex - bpl BoxLoop - lda any - beq + ; if we didn't draw anything in any box, we're done - bit $C000 - bpl MainLoop -+ rts - - !source "src/wait.a" - -; box drawing routines for each stage -; in: X = starting HGR row for this box -; Y = starting byte offset for this box -clear00 - +STAGE0 0 -clear01 - +STAGE1 0 -clear02 - +MIDDLE_STAGE $0D, $05, %11000000, %10000001, %11000000, %10000001, 0 -clear03 - +MIDDLE_STAGE $0C, $07, %11100000, %10000011, %10100000, %10000010, 0 -clear04 - +MIDDLE_STAGE $0B, $09, %11110000, %10000111, %10010000, %10000100, 0 -clear05 - +MIDDLE_STAGE $0A, $0B, %11111000, %10001111, %10001000, %10001000, 0 -clear06 - +MIDDLE_STAGE $09, $0D, %11111100, %10011111, %10000100, %10010000, 0 -clear07 - +MIDDLE_STAGE $08, $0F, %11111110, %10111111, %10000010, %10100000, 0 -clear08 - +MIDDLE_STAGE $07, $11, %11111111, %11111111, %10000001, %11000000, 0 -clear09 - +OUTER_STAGE $06, $13, %11000000, %10000001, %11000000, %10000001, 0 -clear0A - +OUTER_STAGE $05, $15, %11100000, %10000011, %10100000, %10000010, 0 -clear0B - +OUTER_STAGE $04, $17, %11110000, %10000111, %10010000, %10000100, 0 -clear0C - +OUTER_STAGE $03, $19, %11111000, %10001111, %10001000, %10001000, 0 -clear0D - +OUTER_STAGE $02, $1B, %11111100, %10011111, %10000100, %10010000, 0 -clear0E - +OUTER_STAGE $01, $1D, %11111110, %10111111, %10000010, %10100000, 0 -clear0F - +OUTER_STAGE $00, $1F, %11111111, %11111111, %10000001, %11000000, 0 -copy00 - +STAGE0 1 -copy01 - +STAGE1 1 -copy02 - +MIDDLE_STAGE $0D, $05, %11000000, %10000001, %11000000, %10000001, 1 -copy03 - +MIDDLE_STAGE $0C, $07, %11100000, %10000011, %10100000, %10000010, 1 -copy04 - +MIDDLE_STAGE $0B, $09, %11110000, %10000111, %10010000, %10000100, 1 -copy05 - +MIDDLE_STAGE $0A, $0B, %11111000, %10001111, %10001000, %10001000, 1 -copy06 - +MIDDLE_STAGE $09, $0D, %11111100, %10011111, %10000100, %10010000, 1 -copy07 - +MIDDLE_STAGE $08, $0F, %11111110, %10111111, %10000010, %10100000, 1 -copy08 - +MIDDLE_STAGE $07, $11, %11111111, %11111111, %10000001, %11000000, 1 -copy09 - +OUTER_STAGE $06, $13, %11000000, %10000001, %11000000, %10000001, 1 -copy0A - +OUTER_STAGE $05, $15, %11100000, %10000011, %10100000, %10000010, 1 -copy0B - +OUTER_STAGE $04, $17, %11110000, %10000111, %10010000, %10000100, 1 -copy0C - +OUTER_STAGE $03, $19, %11111000, %10001111, %10001000, %10001000, 1 -copy0D - +OUTER_STAGE $02, $1B, %11111100, %10011111, %10000100, %10010000, 1 -copy0E - +OUTER_STAGE $01, $1D, %11111110, %10111111, %10000010, %10100000, 1 -copy0F - +OUTER_STAGE $00, $1F, %11111111, %11111111, %10000001, %11000000, 1 - -; -; Boxes are laid out in a grid, left-to-right, top-down: -; 0 1 2 3 4 5 6 7 -; 8 9 10 11 12 13 14 15 -; 16 17 18 19 20 21 22 23 -; 24 25 26 27 28 29 30 31 -; 32 33 34 35 36 37 38 39 -; 40 41 42 43 44 45 46 47 -; -; Each box is 35x32 pixels, so each row of each box is 5 consecutive -; bytes in memory once you calculate the HGR base address for that row. -; -BoxesX ; starting HGR row for each box - !byte $00,$00,$00,$00,$00,$00,$00,$00 - !byte $20,$20,$20,$20,$20,$20,$20,$20 - !byte $40,$40,$40,$40,$40,$40,$40,$40 - !byte $60,$60,$60,$60,$60,$60,$60,$60 - !byte $80,$80,$80,$80,$80,$80,$80,$80 - !byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 -BoxesY ; starting byte offset for each box - !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 - !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 - !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 - !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 - !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 - !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 - -; The initial grid of stages for each box. -; Each box's stage is incremented on each iteration. -; Negative stages (80..FF) are no-ops. -; Positive stages (00..7F) are indexes into StagesLo/Hi array -; to find the actual drawing routine for this stage (if any). -BoxInitialStages !byte $EC,$E8,$E4,$E0,$DC,$D8,$D4,$D0 !byte $F0,$EC,$E8,$E4,$E0,$DC,$D8,$D4 !byte $F4,$F0,$EC,$E8,$E4,$E0,$DC,$D8 @@ -314,46 +14,6 @@ BoxInitialStages !byte $FC,$F8,$F4,$F0,$EC,$E8,$E4,$E0 !byte $00,$FC,$F8,$F4,$F0,$EC,$E8,$E4 -!align $FF,0,0 ; align to page -StagesLo ; low bytes of address of drawing routine for each stage - !byte clear00 !byte >clear01 @@ -389,7 +49,4 @@ StagesHi ; high bytes of address of drawing routine for each stage !byte >copy02 !byte >copy01 !byte >copy00 - !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - !byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +EndStagesHi diff --git a/src/fx/fx.hgr.48boxes.common.a b/src/fx/fx.hgr.48boxes.common.a new file mode 100644 index 000000000..98bc583ae --- /dev/null +++ b/src/fx/fx.hgr.48boxes.common.a @@ -0,0 +1,522 @@ +;license:MIT +;(c) 2020 by 4am & qkumba +; + +src = $00 ; [word, must be at $00] +dst = $02 ; [word] +box = $04 ; [byte] +stage = $05 ; [byte] +any = $06 ; [byte] +x = $07 +rowcount = $07 ; [byte] +BoxStages = $10 ; [$30 bytes][must be at $10] +hgrhi = $40 ; [$C0 bytes] +hgrlo = $300 ; [$C0 bytes] + +!macro RECALC_HIGH_ONLY { + lda hgrhi, x + sta dst+1 + eor #$60 + sta src+1 +} + +; recalculate HGR base addresses +; in: X = HGR row (00..BF) +; out: preserves X, Y +; clobbers A +!macro RECALC { + lda hgrlo, x + sta src + sta dst + +RECALC_HIGH_ONLY +} + + !source "src/fx/macros.a" + +; actual code starts here + + ldx #0 +- lda BoxInitialStages-BoxStages, x + sta $00, x + lda CLEAR_STAGE0, x + sta clear00, x + lda CLEAR_STAGE1, x + sta clear01, x + lda COPY_STAGE0, x + sta copy00, x + lda COPY_STAGE1, x + sta copy01, x + lda #0 + sta EndStagesHi, x + dex + bne - + + ldx #13 + stx x +-- ldx x + ldy #$7F +- lda MIDDLE_STAGE, y + sta ($0C), y + lda OUTER_STAGE, y + sta ($0E), y + dey + bpl - + + lda MiddleRowCounts, x + ldy #m_rowcount + sta ($0C), y + lda OuterRowCounts, x + ldy #o_rowcount + sta ($0E), y + + lda MiddleFirstRows, x + ldy #m_firstrow + sta ($0C), y + lda OuterFirstRows, x + ldy #o_firstrow + sta ($0E), y + + lda EdgeLeftMasks, x + ldy #m_edgeleftmask + sta ($0C), y + ldy #o_edgeleftmask + sta ($0E), y + + lda EdgeRightMasks, x + ldy #m_edgerightmask + sta ($0C), y + ldy #o_edgerightmask + sta ($0E), y + + lda LeftMasks, x + ldy #m_leftmask + sta ($0C), y + ldy #o_leftmask + sta ($0E), y + + lda RightMasks, x + ldy #m_rightmask + sta ($0C), y + ldy #o_rightmask + sta ($0E), y + + lda CopyFlags, x + bne + + + lda #$A9 + ldy #m_lda + sta ($0C), y + ldy #o_lda1 + sta ($0E), y + + lda #$24 + ldx #5 +- ldy MiddleBits, x + sta ($0C), y + ldy OuterBits, x + sta ($0E), y + dex + bpl - + ++ dec $0D + dec $0F + dec x + +LBPL -- + + +BUILD_HGR_LOOKUP_TABLES hgrlo, hgrhi + +MainLoop lda #0 + sta any + ldx #47 +BoxLoop stx box + lda BoxStages, x ; for each box, get its current stage + bmi NextBox ; if stage >= $80, nothing to do + tax + lda StagesHi, x + beq NextBox ; if stage's drawing routine is 0, nothing to do + sta j+2 + ldx box + lda BoxesX, x + ldy BoxesY, x ; Y = starting byte offset for this box + tax ; X = starting HGR row for this box + inc any + clc +j jsr $FD00 ; [SMC] call drawing routine for this stage +NextBox ldx box + inc BoxStages, x ; increment every box's stage every time through the loop, + ; even if we didn't call a drawing routine + dex + bpl BoxLoop + lda any + beq Exit ; if we didn't draw anything in any box, we're done + bit $C000 + bpl MainLoop +Exit rts + + !source "src/wait.a" + +CLEAR_STAGE0 + bit Exit + !byte $A9 +COPY_STAGE0 + clv + php + txa + adc #$0F + tax + plp + +RECALC + iny + iny + lda (dst), y + bvs + + eor (src), y ++ and #%10111110 + eor (dst), y + sta (dst), y + inx + +RECALC + lda (dst), y + bvs + + eor (src), y ++ and #%10111110 + eor (dst), y + sta (dst), y + rts +CLEAR_STAGE1 + bit Exit + !byte $A9 +COPY_STAGE1 + clv + php + txa + adc #$0E + tax + plp + +RECALC + iny + iny + lda #0 + bvs + + lda (src), y ++ sta (dst), y + inx + +RECALC_HIGH_ONLY + lda #0 + bvs + + lda (src), y ++ sta (dst), y + inx + +RECALC + lda #0 + bvs + + lda (src), y ++ sta (dst), y + inx + +RECALC_HIGH_ONLY + lda #0 + bvs + + lda (src), y ++ sta (dst), y + rts +MIDDLE_STAGE +m_rowcount=*+1-MIDDLE_STAGE + lda #$FD ; SMC + sta rowcount + txa +m_firstrow=*+1-MIDDLE_STAGE + adc #$FD ; SMC + tax + +RECALC + iny +-- + lda (dst), y +m_bit1=*-MIDDLE_STAGE + eor (src), y ; SMC +m_edgeleftmask=*+1-MIDDLE_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + iny + +m_lda=*-MIDDLE_STAGE + lda (src), y + sta (dst), y + + iny + + lda (dst), y +m_bit2=*-MIDDLE_STAGE + eor (src), y ; SMC +m_edgerightmask=*+1-MIDDLE_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + dey + dey +- + lda (dst), y +m_bit3=*-MIDDLE_STAGE + eor (src), y ; SMC +m_leftmask=*+1-MIDDLE_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + iny + iny + + lda (dst), y +m_bit4=*-MIDDLE_STAGE + eor (src), y ; SMC +m_rightmask=*+1-MIDDLE_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + dey + dey + inx + +RECALC + dec rowcount + beq -- + bpl - + rts +MIDDLE_STAGE_END + +OUTER_STAGE +o_rowcount=*+1-OUTER_STAGE + lda #$FD ; SMC + sta rowcount + txa +o_firstrow=*+1-OUTER_STAGE + adc #$FD ; SMC + tax + +RECALC +-- + lda (dst), y +o_bit1=*-OUTER_STAGE + eor (src), y ; SMC +o_edgeleftmask=*+1-OUTER_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + iny + +o_lda1=*-OUTER_STAGE + lda (src), y ; SMC + sta (dst), y + + iny + +o_lda2=*-OUTER_STAGE + lda (src), y ; SMC + sta (dst), y + + iny + +o_lda3=*-OUTER_STAGE + lda (src), y ; SMC + sta (dst), y + + iny + + lda (dst), y +o_bit2=*-OUTER_STAGE + eor (src), y ; SMC +o_edgerightmask=*+1-OUTER_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + dey + dey + dey + dey +- + lda (dst), y +o_bit3=*-OUTER_STAGE + eor (src), y ; SMC +o_leftmask=*+1-OUTER_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + iny + iny + iny + iny + + lda (dst), y +o_bit4=*-OUTER_STAGE + eor (src), y ; SMC +o_rightmask=*+1-OUTER_STAGE + and #$FD ; SMC + eor (dst), y + sta (dst), y + + dey + dey + dey + dey + inx + +RECALC + dec rowcount + beq -- + bpl - + rts +OUTER_STAGE_END + +clear00=$9C00 +clear01=$9D00 +clear02=$8000 +clear03=$8100 +clear04=$8200 +clear05=$8300 +clear06=$8400 +clear07=$8500 +clear08=$8600 +clear09=$8E00 +clear0A=$8F00 +clear0B=$9000 +clear0C=$9100 +clear0D=$9200 +clear0E=$9300 +clear0F=$9400 +copy00=$9E00 +copy01=$9F00 +copy02=$8700 +copy03=$8800 +copy04=$8900 +copy05=$8A00 +copy06=$8B00 +copy07=$8C00 +copy08=$8D00 +copy09=$9500 +copy0A=$9600 +copy0B=$9700 +copy0C=$9800 +copy0D=$9900 +copy0E=$9A00 +copy0F=$9B00 + +MiddleFirstRows + !byte $0D,$0C,$0B,$0A,$09,$08,$07 + !byte $0D,$0C,$0B,$0A,$09,$08,$07 +OuterFirstRows + !byte $06,$05,$04,$03,$02,$01,$00 + !byte $06,$05,$04,$03,$02,$01,$00 +MiddleRowCounts + !byte $05,$07,$09,$0B,$0D,$0F,$11 + !byte $05,$07,$09,$0B,$0D,$0F,$11 +OuterRowCounts + !byte $13,$15,$17,$19,$1B,$1D,$1F + !byte $13,$15,$17,$19,$1B,$1D,$1F +EdgeLeftMasks + !byte %11000000 + !byte %11100000 + !byte %11110000 + !byte %11111000 + !byte %11111100 + !byte %11111110 + !byte %11111111 + !byte %11000000 + !byte %11100000 + !byte %11110000 + !byte %11111000 + !byte %11111100 + !byte %11111110 + !byte %11111111 +EdgeRightMasks + !byte %10000001 + !byte %10000011 + !byte %10000111 + !byte %10001111 + !byte %10011111 + !byte %10111111 + !byte %11111111 + !byte %10000001 + !byte %10000011 + !byte %10000111 + !byte %10001111 + !byte %10011111 + !byte %10111111 + !byte %11111111 +LeftMasks + !byte %11000000 + !byte %10100000 + !byte %10010000 + !byte %10001000 + !byte %10000100 + !byte %10000010 + !byte %10000001 + !byte %11000000 + !byte %10100000 + !byte %10010000 + !byte %10001000 + !byte %10000100 + !byte %10000010 + !byte %10000001 +RightMasks + !byte %10000001 + !byte %10000010 + !byte %10000100 + !byte %10001000 + !byte %10010000 + !byte %10100000 + !byte %11000000 + !byte %10000001 + !byte %10000010 + !byte %10000100 + !byte %10001000 + !byte %10010000 + !byte %10100000 + !byte %11000000 +CopyFlags + !byte 0,0,0,0,0,0,0 + !byte 1,1,1,1,1,1,1 +MiddleBits + !byte m_bit1, m_bit2, m_bit3, m_bit4, m_bit4, m_bit4 +OuterBits + !byte o_lda2, o_lda3, o_bit1, o_bit2, o_bit3, o_bit4 + +; +; Boxes are laid out in a grid, left-to-right, top-down: +; 0 1 2 3 4 5 6 7 +; 8 9 10 11 12 13 14 15 +; 16 17 18 19 20 21 22 23 +; 24 25 26 27 28 29 30 31 +; 32 33 34 35 36 37 38 39 +; 40 41 42 43 44 45 46 47 +; +; Each box is 35x32 pixels, so each row of each box is 5 consecutive +; bytes in memory once you calculate the HGR base address for that row. +; +BoxesX ; starting HGR row for each box + !byte $00,$00,$00,$00,$00,$00,$00,$00 + !byte $20,$20,$20,$20,$20,$20,$20,$20 + !byte $40,$40,$40,$40,$40,$40,$40,$40 + !byte $60,$60,$60,$60,$60,$60,$60,$60 + !byte $80,$80,$80,$80,$80,$80,$80,$80 + !byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0 +BoxesY ; starting byte offset for each box + !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 + !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 + !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 + !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 + !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 + !byte $00,$05,$0A,$0F,$14,$19,$1E,$23 + +CopyParams ; must be immediately before BoxInitialStages + !word $8D00 + !word $9B00 + +; The initial grid of stages for each box. +; Each box's stage is incremented on each iteration. +; Negative stages (80..FF) are no-ops. +; Positive stages (00..7F) are indexes into StagesHi array +; to find the actual drawing routine for this stage (if any). +BoxInitialStages