asmgen/cpbg.s

541 lines
10 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. Using the whole thing because we aren't using any
; ROM routines
*= $0006
; parameters: these should not be changed by child subroutines
param_x .ds 1
param_y .ds 1
param_col .ds 1
param_row .ds 1
param_index .ds 1
param_count .ds 1
*= $0010
; scratch areas: these may be modified by child subroutines
scratch_addr .ds 2
scratch_ptr .ds 2
scratch_0 .ds 1
scratch_1 .ds 1
scratch_index .ds 1
scratch_col .ds 1
*= $0020
; required variables for HiSprite
bgstore .ds 2
damage_w .ds 1
damage_h .ds 1
damageptr .ds 2
damageindex .ds 1
damageptr1 .ds 2
damageindex1 .ds 1
damageptr2 .ds 2
damageindex2 .ds 1
hgrhi .ds 1 ; either $20 or $40, the base of each hgr screen
hgrselect .ds 1 ; either $00 or $60, used as xor mask for HGRROWS_H1
*= $0030
; global variables for this program
rendercount .ds 1
drawpage .ds 1 ; pos = page1, neg = page2
tempaddr .ds 2
counter1 .ds 1
textptr .ds 2
hgrptr .ds 2
temprow .ds 1
tempcol .ds 1
DAMAGEPAGE1 = $bf ; page number of first byte beyond top of backing store stack
DAMAGEPAGE2 = $be
; constants
MAXPOSX = 250
MAXPOSY = 192 - 16
*= $6000
start
bit CLRTEXT ; start with HGR page 1, full screen
bit CLRMIXED
bit TXTPAGE2
bit SETHIRES
jsr clrscr
jsr initonce
jsr initsprites
jsr initbackground
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
sta damageindex1
sta damageindex2
sta damageptr
sta damageptr1
sta damageptr2
lda #damagepage1
sta damageptr+1
sta damageptr1+1
sta damageptr2+1
rts
initsprites
jsr restorebg_init
rts
initbackground
jsr filltext
jsr pageflip
bit TXTPAGE1
jsr copytexthgr
jsr copytexthgrslow
jsr copytexthgr
jsr copytexthgrslow
jsr copytexthgr
jsr pageflip
jsr copytexthgr
rts
filltext
ldy #0 ; Loop a bit
sty COUNTER1
ib_outer
lda textrow_h,y
ora #4
sta textptr+1
lda textrow_l,y
sta textptr
tya
adc #32
ldx #0
ldy #0
ib_inner
sta (textptr),y
adc #1
inx
iny
cpy #40
bcc ib_inner
ldy counter1
iny
sty counter1
cpy #24
bcc ib_outer
rts
copytexthgr
lda HGRSELECT
beq copytexthgr_page1
ldx #<FASTFONT_H2
ldy #>FASTFONT_H2
bne copytexthgr_store_dest ; always true: hi byte of subroutine is > 0
copytexthgr_page1 ldx #<FASTFONT_H1
ldy #>FASTFONT_H1
copytexthgr_store_dest
stx copytexthgr_dest_smc+1
sty copytexthgr_dest_smc+2
ldy #0 ; y is rows
copytexthgr_outer
lda textrow_h,y
ora #4
sta copytexthgr_src_smc+2
lda textrow_l,y
sta copytexthgr_src_smc+1
ldx #0 ; x is columns
copytexthgr_src_smc
lda $ffff,x
copytexthgr_dest_smc
jsr FASTFONT_H1
inx
cpx #40
bcc copytexthgr_src_smc
iny
cpy #24
bcc copytexthgr_outer
rts
copytexthgrslow
LDA #0
STA temprow
?1 LDY temprow ; Y = row
CPY #24 ; 24 rows is #$18
BCS ?3 ; Y >= 24
LDX #0
STX tempcol ; X = col
JSR SetCursorColRow
and ~10011111
clc ; A = HgrHiY[ row ]
adc #4 ; Convert HgrHiY to TextHiY byte
STA TEXTPTR+1 ; A -= 0x1C -> TxtHi
LDA hgrptr ; A = HgrLoY[ row ]
STA TEXTPTR ; -> TxtLo
LDY tempcol
?2 LDA (TEXTPTR),Y
AND #$7F
JSR DrawCharCol
CPY #$28 ; 40 cols is #$28
BCC ?2 ; Y < 40
INC temprow
BNE ?1 ; always
?3 RTS
rts
pageflip
lda drawpage
eor #$80
sta drawpage
bpl pageflip1 ; pos = show 1, draw 2; neg = show 1, draw 1
bit TXTPAGE2 ; show page 2, work on page 1
lda #$00
sta hgrselect
lda #$20
sta hgrhi
lda damageptr ; save other page's damage pointer
sta damageptr2
lda damageptr1
sta damageptr
lda damageptr1+1
sta damageptr+1
lda damageindex1
sta damageindex
rts
pageflip1
bit TXTPAGE1 ; show page 1, work on page 2
lda #$60
sta hgrselect
lda #$40
sta hgrhi
lda damageptr ; save other page's damage pointer
sta damageptr1
lda damageptr2
sta damageptr
lda damageptr2+1
sta damageptr+1
lda damageindex2
sta damageindex
rts
restorebg_init
rts
restorebg_driver
; copy damaged characters back to screen
rts
; Draw sprites by looping through the list of sprites
renderstart
lda #sprite_l - sprite_active
sta param_count
inc renderroundrobin_smc+1
renderroundrobin_smc
ldy #0
sty param_index
renderloop
lda param_index
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 param_x
lda sprite_y,y
sta param_y
jmp jsrsprite_smc
jsrsprite_smc
jsr $ffff ; wish you could JSR ($nnnn)
ldy damageindex
lda scratch_col ; contains the byte index into the line
sta (damageptr),y
iny
clc
adc damage_w
sta (damageptr),y
iny
; need to convert hgr y values to char rows
lda param_y
lsr a
lsr a
lsr a
sta (damageptr),y
iny
lda param_y
clc
adc damage_h
lsr a
lsr a
lsr a
sta (damageptr),y
iny
sty damageindex
renderskip
inc param_index
dec param_count
bne renderloop
renderend
rts
movestart
lda #sprite_l - sprite_active
sta param_count
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 param_count
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 scratch_addr+1
lda HGRROWS_H2,x
sta scratch_ptr+1
lda HGRROWS_L,x
sta scratch_addr
sta scratch_ptr
lda tophalf,y
cpx #96
bcc clrwrite
lda bothalf,y
clrwrite
sta (scratch_addr),y
sta (scratch_ptr),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 cpbg-sprite-driver.s
.include drawfont.s
.include fatfont.s