asmgen/demo/sprite_compiler/multitest.s

334 lines
6.2 KiB
ArmAsm

; os memory map
CLRTEXT = $c050
SETTEXT = $c051
CLRMIXED = $c052
SETMIXED = $c053
TXTPAGE1 = $c054
TXTPAGE2 = $c055
CLRHIRES = $c056
SETHIRES = $c057
; ROM entry points
COUT = $fded
ROMWAIT = $fca8
; Zero page locations we use (unused by Monitor, Applesoft, or ProDOS)
PARAM0 = $06
PARAM1 = $07
PARAM2 = $08
PARAM3 = $09
SCRATCH0 = $19
SCRATCH1 = $1a
SPRITEPTR_L = $1b
SPRITEPTR_H = $1c
RENDERCOUNT = $ce
DRAWPAGE = $d7 ; pos = page1, neg = page2
BGSTORE = $fa
TEMPADDR = $fc
BGTOP = $c0 ; page number of first byte beyond top of backing store stack
; constants
MAXPOSX = 250
MAXPOSY = 192 - 16
*= $6000
start
bit CLRTEXT ; start with HGR page 1, full screen
bit CLRMIXED
bit TXTPAGE1
bit SETHIRES
jsr clrscr
jsr initonce
jsr initsprites
gameloop
jsr renderstart
jsr pageflip
jsr movestart
dec fasttoggle
bpl gofast
jsr wait
gofast
jsr restorebg_driver
jmp gameloop
fasttoggle
.byte 0
initonce
lda #0
sta DRAWPAGE
rts
initsprites
jsr restorebg_init
rts
pageflip
lda DRAWPAGE
eor #$80
sta DRAWPAGE
bpl pageflip1
bit TXTPAGE2
rts
pageflip1
bit TXTPAGE1
rts
; Draw sprites by looping through the list of sprites
renderstart
lda #sprite_l - sprite_active
sta RENDERCOUNT
inc renderroundrobin_smc+1
renderroundrobin_smc
ldy #0
sty PARAM3
renderloop
lda PARAM3
and #sprite_l - sprite_active - 1
tay
lda sprite_active,y
beq renderskip ; skip if zero
lda sprite_l,y
sta jsrsprite_smc+1
lda sprite_h,y
sta jsrsprite_smc+2
lda sprite_x,y
sta PARAM0
lda sprite_y,y
sta PARAM1
jsrsprite_smc
jsr $ffff ; wish you could JSR ($nnnn)
renderskip
inc PARAM3
dec RENDERCOUNT
bne renderloop
renderend
rts
movestart
lda #sprite_l - sprite_active
sta RENDERCOUNT
ldy #0
moveloop
lda sprite_active,y
bmi moveend
beq movenext
movex
; Apply X velocity to X coordinate
lda sprite_dirx,y
bpl move_right
sec
lda sprite_x,y
sbc sprite_dx,y
cmp #MAXPOSX
bcc movex_end
lda #1
sta sprite_dirx,y
lda #0
sta sprite_x,y
bpl movey
move_right
clc
lda sprite_x,y
adc sprite_dx,y
cmp #MAXPOSX
bcc movex_end
lda #-1
sta sprite_dirx,y
lda #MAXPOSX
movex_end
; Store the new X
sta sprite_x,y
movey
; Apply Y velocity to Y coordinate
lda sprite_diry,y
bpl move_down
sec
lda sprite_y,y
sbc sprite_dy,y
cmp #MAXPOSY ; checking wraparound
bcc movey_end ; less than => not wrapped
lda #1
sta sprite_diry,y
lda #0
sta sprite_y,y
bpl movenext
move_down
clc
lda sprite_y,y
adc sprite_dy,y
cmp #MAXPOSY
bcc movey_end
lda #-1
sta sprite_diry,y
lda #MAXPOSY
movey_end
; Store the new X
sta sprite_y,y
movenext
iny
dec RENDERCOUNT
bne moveloop
moveend
rts
wait
ldy #$06 ; Loop a bit
wait_outer
ldx #$ff
wait_inner
nop
nop
nop
nop
nop
nop
nop
dex
bne wait_inner
dey
bne wait_outer
rts
clrscr
lda #0
sta clr1+1
sta clr2+1
lda #$20
sta clr1+2
lda #$40
sta clr2+2
clr0
lda #0
ldy #0
clr1
sta $ffff,y
clr2
sta $ffff,y
iny
bne clr1
inc clr1+2
inc clr2+2
ldx clr1+2
cpx #$40
bcc clr1
; put the same info on both screens
clrscr2
ldy #1
clrouter
ldx #0
clrloop
lda HGRROWS_H1,x
sta SCRATCH1
lda HGRROWS_H2,x
sta TEMPADDR+1
lda HGRROWS_L,x
sta SCRATCH0
sta TEMPADDR
lda tophalf,y
cpx #96
bcc clrwrite
lda bothalf,y
clrwrite
sta (SCRATCH0),y
sta (TEMPADDR),y
inx
cpx #192
bcc clrloop
iny
cpy #40
bcs clrend
bne clrouter
clrend
rts
tophalf
.byte 0
.byte $88, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101
.byte $08, ~00101010, ~01010101, ~00101010, ~01010101, ~00101010
.byte $10, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101
.byte $1c, ~00101010, ~01010101, ~00101010, ~01010101, ~00101010
.byte $88, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101
.byte $9c, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101
.byte $9c, ~00101010, ~01010101, ~00101010, ~01010101, ~00101010
.byte $1c, ~01010101, ~00101010, ~01010101, ~00101010, ~01010101
bothalf
.byte 0
.byte $9c, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101
.byte ~10001000, ~10101010, ~11010101, ~10101010, ~11010101, ~10101010
.byte ~00010000, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101
.byte $08, ~10101010, ~11010101, ~10101010, ~11010101, ~10101010
.byte $9c, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101
.byte $9c, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101
.byte $88, ~11010101, ~10101010, ~11010101, ~10101010, ~11010101
.byte $08, ~10101010, ~11010101, ~10101010, ~11010101, ~10101010
; Sprite data is interleaved so a simple indexed mode can be used. This is not
; convenient to set up but makes faster accessing because you don't have to
; increment the index register. For example, all the info about sprite #2 can
; be indexed using Y = 2 on the indexed operators, e.g. "lda sprite_active,y",
; "lda sprite_x,y", etc.
;
; Number of sprites must be a power of 2
sprite_active
.byte 1, 1, 1, 1, 1, 1, 1, 1 ; 1 = active, 0 = skip
sprite_l
.byte <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <APPLE_SPRITE9X11, <MOLDY_BURGER, <MOLDY_BURGER
sprite_h
.byte >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >APPLE_SPRITE9X11, >MOLDY_BURGER, >MOLDY_BURGER
sprite_x
.byte 80, 164, 33, 245, 4, 9, 255, 18
sprite_y
.byte 116, 126, 40, 60, 80, 100, 120, 140
sprite_dx
.byte 1, 2, 3, 4, 1, 2, 3, 4
sprite_dirx
.byte -1, -1, -1, -1, 1, 1, 1, 1
sprite_dy
.byte 4, 3, 2, 1, 4, 3, 2, 1
sprite_diry
.byte 1, 1, 1, 1, -1, -1, -1, -1
.include multitest-sprite-driver.s