initial commit
This commit is contained in:
+484
@@ -0,0 +1,484 @@
|
||||
; -----------------------------------------------------------
|
||||
; common.asm - routines shared by the states: screen drawing,
|
||||
; text printing, input, RNG and the rabbit sprite positioning
|
||||
; -----------------------------------------------------------
|
||||
|
||||
; ---- clear screen RAM, fill color RAM with black ----
|
||||
clear_screen:
|
||||
ldx #0
|
||||
cls_loop:
|
||||
lda #$20 ; space
|
||||
sta SCREEN,x
|
||||
sta SCREEN+$100,x
|
||||
sta SCREEN+$200,x
|
||||
sta SCREEN+$2e8,x
|
||||
lda #BLACK
|
||||
sta COLRAM,x
|
||||
sta COLRAM+$100,x
|
||||
sta COLRAM+$200,x
|
||||
sta COLRAM+$2e8,x
|
||||
inx
|
||||
bne cls_loop
|
||||
rts
|
||||
|
||||
; ---- print a text line: txtlo/hi, prow, pcol, pcolor, plen ----
|
||||
print_text:
|
||||
ldx prow
|
||||
lda mul40lo,x
|
||||
clc
|
||||
adc pcol
|
||||
sta scrlo
|
||||
sta collo
|
||||
lda mul40hi,x
|
||||
adc #>SCREEN ; carry still valid from the low-byte add
|
||||
sta scrhi
|
||||
clc
|
||||
adc #$d4 ; COLRAM - SCREEN high byte distance
|
||||
sta colhi
|
||||
ldy #0
|
||||
pt_loop:
|
||||
lda (txtlo),y
|
||||
sta (scrlo),y
|
||||
lda pcolor
|
||||
sta (collo),y
|
||||
iny
|
||||
cpy plen
|
||||
bne pt_loop
|
||||
rts
|
||||
|
||||
; ---- the road: two diagonals from the horizon apex down to
|
||||
; the screen corners, plus a tree on the left shoulder ----
|
||||
draw_road:
|
||||
ldx #0
|
||||
dr_loop:
|
||||
txa
|
||||
clc
|
||||
adc #6 ; road runs from char row 6 to row 24
|
||||
tay
|
||||
lda mul40lo,y
|
||||
sta scrlo
|
||||
lda mul40hi,y
|
||||
clc
|
||||
adc #>SCREEN
|
||||
sta scrhi
|
||||
stx drtmp
|
||||
lda #19 ; left edge: one column left per row
|
||||
sec
|
||||
sbc drtmp
|
||||
tay
|
||||
lda #$4e ; '/' diagonal
|
||||
sta (scrlo),y
|
||||
lda #20 ; right edge: one column right per row
|
||||
clc
|
||||
adc drtmp
|
||||
tay
|
||||
lda #$4d ; '\' diagonal
|
||||
sta (scrlo),y
|
||||
inx
|
||||
cpx #19
|
||||
bne dr_loop
|
||||
; tree on the left shoulder
|
||||
lda #$51 ; ball
|
||||
sta SCREEN+10*40+3
|
||||
sta SCREEN+11*40+2
|
||||
sta SCREEN+11*40+3
|
||||
sta SCREEN+11*40+4
|
||||
lda #$5d ; trunk
|
||||
sta SCREEN+12*40+3
|
||||
rts
|
||||
|
||||
; ---- input ----
|
||||
|
||||
; read joystick port 2, return active-high bits in A and joyb
|
||||
read_joy:
|
||||
lda #$ff ; deselect every keyboard column first
|
||||
sta CIA1_PA
|
||||
lda CIA1_PA
|
||||
eor #$ff
|
||||
and #$1f
|
||||
sta joyb
|
||||
rts
|
||||
|
||||
; fire or space held? returns A != 0 when pressed
|
||||
start_pressed:
|
||||
jsr read_joy
|
||||
and #JOY_FIRE
|
||||
bne sp_done
|
||||
lda #$7f ; space: keyboard column 7, row bit 4
|
||||
sta CIA1_PA
|
||||
lda CIA1_PB
|
||||
and #$10
|
||||
eor #$10
|
||||
sp_done:
|
||||
rts
|
||||
|
||||
; edge-detected start: A = 1 only on the frame fire/space goes down
|
||||
start_edge:
|
||||
jsr start_pressed
|
||||
beq se_up
|
||||
lda fheld
|
||||
bne se_no
|
||||
lda #1
|
||||
sta fheld
|
||||
rts ; A = 1: fresh press
|
||||
se_up:
|
||||
lda #0
|
||||
sta fheld
|
||||
se_no:
|
||||
lda #0
|
||||
rts
|
||||
|
||||
; ---- RNG: 8-bit LFSR stirred with the free-running CIA timer
|
||||
; (the timer counts every cycle, so call timing = entropy) ----
|
||||
rand8:
|
||||
lda seed
|
||||
asl
|
||||
bcc r8_tap
|
||||
eor #$1d
|
||||
r8_tap:
|
||||
eor CIA1_TA
|
||||
sta seed
|
||||
rts
|
||||
|
||||
; random lane 0-4
|
||||
rand5:
|
||||
jsr rand8
|
||||
and #7
|
||||
cmp #LANES
|
||||
bcs rand5 ; every retry steps the LFSR, so it terminates
|
||||
rts
|
||||
|
||||
; ---- write the per-frame sprite register shadows ----
|
||||
write_shadows:
|
||||
lda en_sh
|
||||
sta SPR_EN
|
||||
lda msb_sh
|
||||
sta SPR_MSBX
|
||||
lda xex_sh
|
||||
sta SPR_XEX
|
||||
lda yex_sh
|
||||
sta SPR_YEX
|
||||
rts
|
||||
|
||||
; ============================================================
|
||||
; rab_pos - place rabbit slot X on hardware sprite X+1
|
||||
; reads r_thi/r_lane, picks size stage + hop frame, writes
|
||||
; the position registers and ORs the shadow bits; keeps X
|
||||
; ============================================================
|
||||
rab_pos:
|
||||
stx rslot
|
||||
lda r_thi,x
|
||||
sta rt
|
||||
lda r_lane,x
|
||||
sta rlane
|
||||
|
||||
; hop offset: 8-entry wave, one hop per 64 t units
|
||||
lda rt
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
and #7
|
||||
tay
|
||||
lda hoptab,y
|
||||
sta rhop
|
||||
|
||||
; animation frame 0-3
|
||||
lda rt
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
and #3
|
||||
sta rfrm
|
||||
|
||||
lda #0
|
||||
sta rexp
|
||||
lda rt
|
||||
cmp #T_BIG
|
||||
bcs rp_big
|
||||
; -- far: small frames --
|
||||
lda #SPRP_SMALL
|
||||
clc
|
||||
adc rfrm
|
||||
sta rptr
|
||||
lda #12
|
||||
sta ranchor
|
||||
jmp rp_y
|
||||
rp_big:
|
||||
; -- near: big frames, stronger hop --
|
||||
lda #SPRP_BIG
|
||||
clc
|
||||
adc rfrm
|
||||
sta rptr
|
||||
asl rhop
|
||||
lda #12
|
||||
sta ranchor
|
||||
lda rt
|
||||
cmp #T_EXP
|
||||
bcc rp_y
|
||||
; -- closest: the same frames double-sized --
|
||||
lda #1
|
||||
sta rexp
|
||||
lda #24
|
||||
sta ranchor
|
||||
rp_y:
|
||||
; sprite y: feet ride the perspective line (art bottom row)
|
||||
ldy rt
|
||||
lda ytab,y
|
||||
sec
|
||||
sbc rhop
|
||||
sec
|
||||
sbc #21
|
||||
ldx rexp
|
||||
beq rp_ydone
|
||||
sec
|
||||
sbc #21 ; expanded sprite is 42 tall
|
||||
rp_ydone:
|
||||
sta ry
|
||||
|
||||
; x center = ROAD_CX +/- lane offset on the t^2 curve
|
||||
ldy rt
|
||||
lda offtab,y
|
||||
sta roff
|
||||
lda #ROAD_CX
|
||||
sta rxlo
|
||||
lda #0
|
||||
sta rxhi
|
||||
ldy rlane
|
||||
cpy #2
|
||||
beq rp_xdone ; middle lane: stay on the center line
|
||||
bcs rp_right
|
||||
lda roff ; lanes 0-1: left of center
|
||||
cpy #1
|
||||
bne rp_lfull
|
||||
lsr ; lane 1 fans out half as far
|
||||
rp_lfull:
|
||||
sta rtmp
|
||||
lda rxlo
|
||||
sec
|
||||
sbc rtmp ; max offset is 107, never underflows
|
||||
sta rxlo
|
||||
jmp rp_xdone
|
||||
rp_right:
|
||||
lda roff ; lanes 3-4: right of center
|
||||
cpy #3
|
||||
bne rp_rfull
|
||||
lsr
|
||||
rp_rfull:
|
||||
sta rtmp
|
||||
lda rxlo
|
||||
clc
|
||||
adc rtmp
|
||||
sta rxlo
|
||||
lda rxhi
|
||||
adc #0
|
||||
sta rxhi
|
||||
rp_xdone:
|
||||
; sprite left edge = center - anchor (16 bit)
|
||||
lda rxlo
|
||||
sec
|
||||
sbc ranchor
|
||||
sta rxlo
|
||||
lda rxhi
|
||||
sbc #0
|
||||
sta rxhi
|
||||
|
||||
; ---- write the hardware registers + shadow bits ----
|
||||
ldx rslot
|
||||
ldy sprxreg,x
|
||||
lda rxlo
|
||||
sta SPRPOS,y
|
||||
lda ry
|
||||
sta SPRPOS+1,y
|
||||
lda rptr
|
||||
sta SPRPTR+1,x
|
||||
lda sprbit,x
|
||||
ora en_sh
|
||||
sta en_sh
|
||||
lda rxhi
|
||||
beq rp_nomsb
|
||||
lda sprbit,x
|
||||
ora msb_sh
|
||||
sta msb_sh
|
||||
rp_nomsb:
|
||||
lda rexp
|
||||
beq rp_done
|
||||
lda sprbit,x
|
||||
ora xex_sh
|
||||
sta xex_sh
|
||||
lda sprbit,x
|
||||
ora yex_sh
|
||||
sta yex_sh
|
||||
rp_done:
|
||||
rts
|
||||
|
||||
; ---- draw a text line with big 3x5 block letters ----
|
||||
; txtlo/hi = text (screen codes), bigrow/bigcol = top-left cell,
|
||||
; bigcolor = color, biglen = char count; each letter is 3 cells
|
||||
; wide + 1 gap, 5 cells tall
|
||||
draw_big:
|
||||
lda #0
|
||||
sta bigi
|
||||
db_char:
|
||||
ldy bigi
|
||||
lda (txtlo),y
|
||||
cmp #$20 ; space: leave the cell empty
|
||||
beq db_next
|
||||
tax
|
||||
lda bigmap,x ; screen code -> glyph index
|
||||
sta glyphbase
|
||||
asl ; glyph base = index * 5
|
||||
asl
|
||||
clc
|
||||
adc glyphbase
|
||||
sta glyphbase
|
||||
lda bigi ; cell x = bigcol + charindex * 4
|
||||
asl
|
||||
asl
|
||||
clc
|
||||
adc bigcol
|
||||
sta charx
|
||||
lda #0
|
||||
sta rowidx
|
||||
db_row:
|
||||
lda bigrow ; row pointers from the row*40 tables
|
||||
clc
|
||||
adc rowidx
|
||||
tax
|
||||
lda mul40lo,x
|
||||
sta scrlo
|
||||
sta collo
|
||||
lda mul40hi,x
|
||||
clc
|
||||
adc #>SCREEN
|
||||
sta scrhi
|
||||
clc
|
||||
adc #$d4
|
||||
sta colhi
|
||||
lda glyphbase
|
||||
clc
|
||||
adc rowidx
|
||||
tax
|
||||
lda bigglyphs,x
|
||||
asl ; 3-bit pattern up to bits 7-5
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
sta curbits
|
||||
ldy charx
|
||||
lda #3
|
||||
sta bitcnt
|
||||
db_bit:
|
||||
asl curbits ; leftmost pixel first
|
||||
bcc db_nobit
|
||||
lda #$a0 ; inverse space = solid block
|
||||
sta (scrlo),y
|
||||
lda bigcolor
|
||||
sta (collo),y
|
||||
db_nobit:
|
||||
iny
|
||||
dec bitcnt
|
||||
bne db_bit
|
||||
inc rowidx
|
||||
lda rowidx
|
||||
cmp #5
|
||||
bne db_row
|
||||
db_next:
|
||||
inc bigi
|
||||
lda bigi
|
||||
cmp biglen
|
||||
beq db_done
|
||||
jmp db_char ; too far for a relative branch
|
||||
db_done:
|
||||
rts
|
||||
|
||||
; ---- shared tables ----
|
||||
|
||||
; row * 40 lookup tables (25 rows)
|
||||
mul40lo:
|
||||
!byte $00, $28, $50, $78, $a0, $c8, $f0, $18, $40, $68
|
||||
!byte $90, $b8, $e0, $08, $30, $58, $80, $a8, $d0, $f8
|
||||
!byte $20, $48, $70, $98, $c0
|
||||
mul40hi:
|
||||
!byte $00, $00, $00, $00, $00, $00, $00, $01, $01, $01
|
||||
!byte $01, $01, $01, $02, $02, $02, $02, $02, $02, $02
|
||||
!byte $03, $03, $03, $03, $03
|
||||
|
||||
; 3x5 block font for the big title (5 bytes per glyph,
|
||||
; low 3 bits used, MSB side = left)
|
||||
bigglyphs:
|
||||
!byte 0, 0, 0, 0, 0 ; 0 space
|
||||
!byte 2, 5, 7, 5, 5 ; 1 A
|
||||
!byte 3, 4, 4, 4, 3 ; 2 C
|
||||
!byte 6, 5, 5, 5, 6 ; 3 D
|
||||
!byte 7, 4, 6, 4, 7 ; 4 E
|
||||
!byte 7, 4, 6, 4, 4 ; 5 F
|
||||
!byte 7, 2, 2, 2, 7 ; 6 I
|
||||
!byte 4, 4, 4, 4, 7 ; 7 L
|
||||
!byte 5, 7, 7, 5, 5 ; 8 M
|
||||
!byte 6, 5, 5, 5, 5 ; 9 N
|
||||
!byte 7, 5, 5, 5, 7 ; 10 O
|
||||
!byte 6, 5, 6, 4, 4 ; 11 P
|
||||
!byte 6, 5, 6, 5, 5 ; 12 R
|
||||
!byte 3, 4, 2, 1, 6 ; 13 S
|
||||
!byte 7, 2, 2, 2, 2 ; 14 T
|
||||
!byte 5, 5, 2, 2, 2 ; 15 Y
|
||||
!byte 3, 4, 5, 5, 7 ; 16 G
|
||||
!byte 6, 5, 6, 5, 6 ; 17 B
|
||||
|
||||
bigmap: ; screen code (a=1..z=26) -> glyph index
|
||||
!byte 0 ; (unused)
|
||||
!byte 1, 17, 2, 3, 4, 5, 16, 0, 6, 0 ; a-j
|
||||
!byte 0, 7, 8, 9, 10, 11, 0, 12, 13, 14 ; k-t
|
||||
!byte 0, 0, 0, 0, 15, 0 ; u-z
|
||||
|
||||
; ---- texts (screen codes) ----
|
||||
txt_score: !scr "score"
|
||||
txt_miss: !scr "miss"
|
||||
txt_rabbit: !scr "rabbit"
|
||||
txt_scooter: !scr "scooter"
|
||||
txt_press: !scr "press fire to start"
|
||||
txt_info: !scr "joystick 2 moves fire starts"
|
||||
txt_over: !scr "game over"
|
||||
txt_retry: !scr "fire = retry"
|
||||
txt_blank: !fill 19, $20
|
||||
|
||||
; ---- shared variables ----
|
||||
framectr: !byte 0 ; frame counter, incremented by the main loop
|
||||
seed: !byte $a7 ; rand8 LFSR state
|
||||
fheld: !byte 0 ; fire/space edge detection state
|
||||
joyb: !byte 0 ; joystick bits from read_joy (active high)
|
||||
en_sh: !byte 0 ; per-frame sprite register shadows
|
||||
msb_sh: !byte 0
|
||||
xex_sh: !byte 0
|
||||
yex_sh: !byte 0
|
||||
prow: !byte 0 ; print_text: row, column, color, length
|
||||
pcol: !byte 0
|
||||
pcolor: !byte 0
|
||||
plen: !byte 0
|
||||
bigrow: !byte 0 ; draw_big: row, column, color, length
|
||||
bigcol: !byte 0
|
||||
bigcolor: !byte 0
|
||||
biglen: !byte 0
|
||||
bigi: !byte 0 ; draw_big internals
|
||||
glyphbase: !byte 0
|
||||
charx: !byte 0
|
||||
rowidx: !byte 0
|
||||
bitcnt: !byte 0
|
||||
curbits: !byte 0
|
||||
drtmp: !byte 0 ; draw_road internals
|
||||
rslot: !byte 0 ; rab_pos internals
|
||||
rt: !byte 0
|
||||
rlane: !byte 0
|
||||
rhop: !byte 0
|
||||
rfrm: !byte 0
|
||||
rexp: !byte 0
|
||||
rptr: !byte 0
|
||||
ranchor: !byte 0
|
||||
roff: !byte 0
|
||||
rxlo: !byte 0
|
||||
rxhi: !byte 0
|
||||
ry: !byte 0
|
||||
rtmp: !byte 0
|
||||
rtmp2: !byte 0
|
||||
Reference in New Issue
Block a user