4cade/src/fx/fx.shr.80boxes.a

487 lines
14 KiB
Plaintext

;license:MIT
;(c) 2021 by 4am & qkumba
;
!cpu 6502
!to "build/FX.INDEXED/SHR.80BOXES",plain
*=$A000
; The SHR screen in 320x200 mode is separated into 80 boxes.
; 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 48 49
; 50 51 52 53 54 55 56 57 58 59
; 60 61 62 63 64 65 66 67 68 69
; 70 71 72 73 74 75 76 77 78 79
;
; Each box is 32x25 pixels, so each row of each box is 16 consecutive
; bytes in memory (2 pixels per byte) once you calculate the SHR base
; address for that row.
;
; |BoxStages| defines the initial grid of stages for each box.
; Each stage is used as an index into the |StagesHi| array
; to find the drawing routine for that stage (if any).
; Each box's stage is incremented after each iteration through the main loop.
; When the main loop iterates through all 80 boxes without drawing anything,
; the program exits.
;
; There are 7 clear routines that set certain pixels to color 0 (usually black)
; labeled clear00..clear06. clear00 clears the inner-most box, and
; clear06 clears the outermost box (see diagram).
; There are 7 copy routines that copy certain pixels from the source
; image in mainmem to the destination image in auxmem, labeled copy00..copy06.
;
; row| pixels
; ---+.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
; 00 |66666666666666666666666666666666
; 01 |66666666666666666666666666666666
; 02 |66555555555555555555555555555566
; 03 |66555555555555555555555555555566
; 04 |66554444444444444444444444445566
; 05 |66554444444444444444444444445566
; 06 |66554433333333333333333333445566
; 07 |66554433333333333333333333445566
; 08 |66554433222222222222222233445566
; 09 |66554433222222222222222233445566
; 10 |66554433221111111111112233445566
; 11 |66554433221111111111112233445566
; 12 |66554433221100000000112233445566
; 13 |66554433221111111111112233445566
; 14 |66554433221111111111112233445566
; 15 |66554433222222222222222233445566
; 16 |66554433222222222222222233445566
; 17 |66554433333333333333333333445566
; 18 |66554433333333333333333333445566
; 19 |66554444444444444444444444445566
; 20 |66554444444444444444444444445566
; 21 |66555555555555555555555555555566
; 22 |66555555555555555555555555555566
; 23 |66666666666666666666666666666666
; 24 |66666666666666666666666666666666
;
; Each routine manipulates pixels in horizontal pairs, meaning we can copy
; bytes without having to worry about masking high and low nibbles.
; Each routine except copy00 is similar, defined by 4 parameters:
; - top row (absolute row, i.e. 00..C7)
; - bottom row (should probably use the first of the two, also absolute)
; - left (should probably be in bytes, also absolute)
; - right (should probably be in bytes, also absolute)
;
; On [top row] and [top row + 1], copy bytes from [left offset] to [right offset]
; While [current row] < [bottom row], draw 1 byte at [left offset] and 1 byte at [right offset]
; On [bottom row] and [bottom row + 1], copy bytes from [left offset] to [right offset]
shrlo = $201 ; [$C8 bytes]
shrhi = $301 ; [$C8 bytes]
!source "src/fx/macros.a"
!source "src/fx/fx.shr.common.a"
ldx #0
- ldy start, x
sty $00, x
sta EndStagesHi, x
inx
bne -
stx seta+1
stx sub1+1
ldx #-25
stx sub2+1
--- ldx #8
seta lda #0
-- pha
ldy #10-1
- sta (<src), y
sec
sub1 sbc #0
dey
bpl -
clc
lda <src
adc #10
sta <src
pla
sec
sub2 sbc #-25
dex
bne --
lda #$90
sta seta+1
lda #$10
sta sub1+1
stx sub2+1
bcc ---
+BUILD_SHR_LOOKUP_TABLES shrlo, shrhi
+COPY_SCB_AND_PALETTES
;WRITEAUXMEM active
jmp MainLoop
start
!pseudopc 0 {
MainLoop ldx #80
BoxLoop ldy <BoxStages-1, x ; for each box, get its current stage
inc <BoxStages-1, x ; increment every box's stage every time through the loop
lda StagesHi, y
beq NextBox ; if stage's drawing routine is 0, nothing to do
sta <j+2
lda BoxesX-1, x ; A = starting SHR row for this box
ldy BoxesY-1, x ; Y = starting byte offset for this box
clc
stx <ReBox+1
j jsr $0000 ; [SMC] call drawing routine for this stage
ReBox ldx #$00 ; [SMC]
NextBox dex
bne <BoxLoop
lda <j+2
beq <exit ; if we didn't draw anything in any box, we're done
stx <j+2 ; X=0 here
bit $C000
bpl MainLoop
exit sta WRITEMAINMEM
setV rts
src !word BoxesX
rowcount !byte 0
lefty !byte 0
righty !byte 0
; diagonal - VERY GOOD
BoxStages
!byte $F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2,$F1,$F0
!byte $FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2,$F1
!byte $FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3,$F2
!byte $FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4,$F3
!byte $FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5,$F4
!byte $FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6,$F5
!byte $FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7,$F6
!byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7
; diagonal
;BoxStages
; !byte $F2,$F0,$EE,$EC,$EA,$E8,$E6,$E4,$E2,$E0
; !byte $F4,$F2,$F0,$EE,$EC,$EA,$E8,$E6,$E4,$E2
; !byte $F6,$F4,$F2,$F0,$EE,$EC,$EA,$E8,$E6,$E4
; !byte $F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA,$E8,$E6
; !byte $FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA,$E8
; !byte $FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC,$EA
; !byte $FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE,$EC
; !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE
; spiral
;BoxStages
; !byte $E9,$E8,$E7,$E6,$E5,$E4,$E3,$E2,$E1,$00
; !byte $EA,$CF,$CE,$CD,$CC,$CB,$CA,$C9,$E0,$FF
; !byte $EB,$D0,$BD,$BC,$BB,$BA,$B9,$C8,$DF,$FE
; !byte $EC,$D1,$BE,$B3,$B2,$B1,$B8,$C7,$DE,$FD
; !byte $ED,$D2,$BF,$B4,$B5,$B6,$B7,$C6,$DD,$FC
; !byte $EE,$D3,$C0,$C1,$C2,$C3,$C4,$C5,$DC,$FB
; !byte $EF,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$DB,$FA
; !byte $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9
; snake
;BoxStages
; !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7
; !byte $ED,$EE,$EF,$F0,$F1,$F2,$F3,$F4,$F5,$F6
; !byte $EC,$EB,$EA,$E9,$E8,$E7,$E6,$E5,$E4,$E3
; !byte $D9,$DA,$DB,$DC,$DD,$DE,$DF,$E0,$E1,$E2
; !byte $D8,$D7,$D6,$D5,$D4,$D3,$D2,$D1,$D0,$CF
; !byte $C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE
; !byte $C4,$C3,$C2,$C1,$C0,$BF,$BE,$BD,$BC,$BB
; !byte $B1,$B2,$B3,$B4,$B5,$B6,$B7,$B8,$B9,$BA
; snake 2
;BoxStages
; !byte $00,$00,$FF,$FF,$FE,$FE,$FD,$FD,$FC,$FC
; !byte $F7,$F7,$F8,$F8,$F9,$F9,$FA,$FA,$FB,$FB
; !byte $F6,$F6,$F5,$F5,$F4,$F4,$F3,$F3,$F2,$F2
; !byte $ED,$ED,$EE,$EE,$EF,$EF,$F0,$F0,$F1,$F1
; !byte $EC,$EC,$EB,$EB,$EA,$EA,$E9,$E9,$E8,$E8
; !byte $E3,$E3,$E4,$E4,$E5,$E5,$E6,$E6,$E7,$E7
; !byte $E2,$E2,$E1,$E1,$E0,$E0,$DF,$DF,$DE,$DE
; !byte $D9,$D9,$DA,$DA,$DB,$DB,$DC,$DC,$DD,$DD
; l2r alternating - VERY GOOD
;BoxStages
; !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE
; !byte $ED,$EF,$F1,$F3,$F5,$F7,$F9,$FB,$FD,$FF
; !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE
; !byte $ED,$EF,$F1,$F3,$F5,$F7,$F9,$FB,$FD,$FF
; !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE
; !byte $ED,$EF,$F1,$F3,$F5,$F7,$F9,$FB,$FD,$FF
; !byte $00,$FE,$FC,$FA,$F8,$F6,$F4,$F2,$F0,$EE
; !byte $ED,$EF,$F1,$F3,$F5,$F7,$F9,$FB,$FD,$FF
; l2r alternating 2
;BoxStages
; !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7
; !byte $F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF,$00
; !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7
; !byte $F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF,$00
; !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7
; !byte $F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF,$00
; !byte $00,$FF,$FE,$FD,$FC,$FB,$FA,$F9,$F8,$F7
; !byte $F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF,$00
; u2d alternating
;BoxStages
; !byte $00,$F1,$00,$F1,$00,$F1,$00,$F1,$00,$F1
; !byte $FE,$F3,$FE,$F3,$FE,$F3,$FE,$F3,$FE,$F3
; !byte $FC,$F5,$FC,$F5,$FC,$F5,$FC,$F5,$FC,$F5
; !byte $FA,$F7,$FA,$F7,$FA,$F7,$FA,$F7,$FA,$F7
; !byte $F8,$F9,$F8,$F9,$F8,$F9,$F8,$F9,$F8,$F9
; !byte $F6,$FB,$F6,$FB,$F6,$FB,$F6,$FB,$F6,$FB
; !byte $F4,$FD,$F4,$FD,$F4,$FD,$F4,$FD,$F4,$FD
; !byte $F2,$FF,$F2,$FF,$F2,$FF,$F2,$FF,$F2,$FF
}
!macro INIT_DRAW .toprowoffset, .siderowcount, .leftoffset {
adc #.toprowoffset
ldx #.siderowcount
stx rowcount
tax
tya
adc #.leftoffset
sta lefty
}
!macro SET_ROW_X {
lda shrlo, x
sta <src
lda shrhi, x
sta <src+1
ldy lefty
}
!macro COPY_BYTE {
lda (src), y
sta (src), y
}
!macro COPY_BYTE_AND_INY {
+COPY_BYTE
iny
}
!macro SIDE_ROWS {
@siderows
sty righty
+SET_ROW_X
+COPY_BYTE
ldy righty
+COPY_BYTE
inx
dec rowcount
bne @siderows
}
!align $FF,0,0 ; align to page
copy00
+INIT_DRAW 12, 0, 6
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
rts
BoxesX ; starting row for each box
; !byte 0,0,0,0,0,0,0,0,0,0
; !byte 25,25,25,25,25,25,25,25,25,25
; !byte 50,50,50,50,50,50,50,50,50,50
; !byte 75,75,75,75,75,75,75,75,75,75
; !byte 100,100,100,100,100,100,100,100,100,100
; !byte 125,125,125,125,125,125,125,125,125,125
; !byte 150,150,150,150,150,150,150,150,150,150
; !byte 175,175,175,175,175,175,175,175,175,175
BoxesY = BoxesX + 10*8 ; starting byte offset for each box
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
; !byte $00,$10,$20,$30,$40,$50,$60,$70,$80,$90
!if (>BoxesY != >BoxesX) {
!error "Boxes array crosses a page"
}
!align $FF,0,0 ; align to page
copy01
+INIT_DRAW 10, 1, 5
bit <setV
-- clc
!byte $A9
- sec
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
inx
bcc -
bvc +
+SIDE_ROWS
clv
jmp --
+ rts
!align $FF,0,0 ; align to page
copy02
+INIT_DRAW 8, 5, 4
bit <setV
-- clc
!byte $A9
- sec
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
inx
bcc -
bvc +
+SIDE_ROWS
clv
jmp --
+ rts
!align $FF,0,0 ; align to page
copy03
+INIT_DRAW 6, 9, 3
bit <setV
-- clc
!byte $A9
- sec
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
inx
bcc -
bvc +
+SIDE_ROWS
clv
jmp --
+ rts
!align $FF,0,0 ; align to page
copy04
+INIT_DRAW 4, 13, 2
bit <setV
-- clc
!byte $A9
- sec
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
inx
bcc -
bvc +
+SIDE_ROWS
clv
jmp --
+ rts
!align $FF,0,0 ; align to page
copy05
+INIT_DRAW 2, 17, 1
bit <setV
-- clc
!byte $A9
- sec
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
inx
bcc -
bvc +
+SIDE_ROWS
clv
jmp --
+ rts
!align $FF,0,0 ; align to page
copy06
+INIT_DRAW 0, 21, 0
bit <setV
-- clc
!byte $A9
- sec
+SET_ROW_X
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE_AND_INY
+COPY_BYTE
inx
bcc -
bvc +
+SIDE_ROWS
clv
jmp --
+ rts
StagesHi ; high bytes of address of drawing routine for each stage
!byte >copy00
!byte >copy01
!byte >copy02
!byte >copy03
!byte >copy04
!byte >copy05
!byte >copy06
EndStagesHi