Rebuild PETSCII Aquarium

This commit is contained in:
Christian Johannesen 2026-10-16 02:33:51 +02:00
parent 7a583ee313
commit bca0ea2a9c
2 changed files with 398 additions and 91 deletions

View file

@ -1,4 +1,8 @@
!cpu 6510 !cpu 6510
; PETSCII Aquarium
; F feeds the fish, 1-3 change speed, Q returns to BASIC.
; Self-starting BASIC line: 10 SYS2061
* = $0801 * = $0801
!word basic_end !word basic_end
!word 10 !word 10
@ -8,154 +12,457 @@
basic_end: !word 0 basic_end: !word 0
* = $080d * = $080d
SCREEN = $0400
COLOR = $d800
GETIN = $ffe4
CHROUT = $ffd2
start: start:
lda $d020 lda $d020
sta old_border sta old_border
lda $d021 lda $d021
sta old_background sta old_background
lda #6
sta $d020
lda #14 lda #14
sta $d020
lda #6
sta $d021 sta $d021
lda #147 lda #147
jsr $ffd2 jsr CHROUT
ldx #0 ldx #0
title_loop: print_title:
lda title,x lda title,x
beq setup beq initialize
jsr $ffd2 jsr CHROUT
inx inx
bne title_loop bne print_title
setup:
lda #4 initialize:
sta speed lda #3
sta animation_speed
lda #0 lda #0
sta tick sta tick
sta food_y sta phase
main: sta food_active
jsr wait_frame lda $a2
jsr $ffe4 sta last_jiffy
jsr draw_tank
jsr draw_all_fish
jsr draw_all_bubbles
main_loop:
jsr GETIN
beq check_clock
cmp #81 cmp #81
bne not_quit bne check_feed
jmp exit jmp exit
not_quit: check_feed:
cmp #70 cmp #70
bne speed_keys bne check_speed_one
lda #3 lda food_active
bne check_clock
lda #1
sta food_active
lda phase
asl
asl
clc
adc #7
cmp #36
bcc save_food_x
sbc #33
save_food_x:
sta food_x sta food_x
lda #2 lda #3
sta food_y sta food_y
speed_keys: jmp check_clock
check_speed_one:
cmp #49 cmp #49
bne speed_two bne check_speed_two
lda #7 lda #6
sta speed sta animation_speed
speed_two: jmp check_clock
check_speed_two:
cmp #50 cmp #50
bne speed_three bne check_speed_three
lda #4 lda #3
sta speed sta animation_speed
speed_three: jmp check_clock
check_speed_three:
cmp #51 cmp #51
bne animate bne check_clock
lda #2 lda #1
sta speed sta animation_speed
animate:
check_clock:
lda $a2
cmp last_jiffy
beq main_loop
sta last_jiffy
inc tick inc tick
lda tick lda tick
cmp speed cmp animation_speed
bcc main bcc main_loop
lda #0 lda #0
sta tick sta tick
jsr animate_frame
jmp main_loop
animate_frame:
jsr erase_all_fish
jsr erase_all_bubbles
jsr erase_food
inc phase
jsr move_fish
jsr move_bubbles
jsr move_food
jsr draw_all_fish
jsr draw_all_bubbles
jsr draw_food
rts
; Fish are two characters wide. Half move every frame and half every other
; frame, giving the tank a less mechanical look.
erase_all_fish:
ldx #0 ldx #0
fish_loop: erase_fish_loop:
stx fish_index stx object_index
jsr erase_one_fish
ldx object_index
inx
cpx #6
bne erase_fish_loop
rts
erase_one_fish:
lda fish_x,x lda fish_x,x
sta old_x sta plot_x
ldy fish_y,x lda fish_y,x
ldx old_x sta plot_y
lda #32 lda #32
jsr plot ldy #6
ldx fish_index jsr plot_character
inc plot_x
lda #32
ldy #6
jsr plot_character
rts
move_fish:
ldx #0
move_fish_loop:
stx object_index
txa
eor phase
and #1
bne next_fish
lda fish_direction,x
bmi move_fish_left
move_fish_right:
inc fish_x,x inc fish_x,x
lda fish_x,x lda fish_x,x
cmp #39 cmp #37
bcc draw_fish bcc next_fish
lda #0 lda #36
sta fish_x,x sta fish_x,x
draw_fish: lda #$ff
sta old_x sta fish_direction,x
ldy fish_y,x jmp next_fish
ldx old_x move_fish_left:
dec fish_x,x
lda fish_x,x
cmp #2
bcs next_fish
lda #2
sta fish_x,x
lda #1
sta fish_direction,x
next_fish:
ldx object_index
inx
cpx #6
bne move_fish_loop
rts
draw_all_fish:
ldx #0
draw_fish_loop:
stx object_index
lda fish_x,x
sta plot_x
lda fish_y,x
sta plot_y
ldy fish_color,x
lda fish_direction,x
bmi draw_left_fish
lda #62 lda #62
jsr plot jsr plot_character
ldx fish_index inc plot_x
lda #41
ldy fish_color,x
jsr plot_character
jmp fish_drawn
draw_left_fish:
lda #40
jsr plot_character
inc plot_x
lda #60
ldy fish_color,x
jsr plot_character
fish_drawn:
ldx object_index
inx
cpx #6
bne draw_fish_loop
rts
erase_all_bubbles:
ldx #0
erase_bubble_loop:
stx object_index
lda bubble_x,x
sta plot_x
lda bubble_y,x
sta plot_y
lda #32
ldy #6
jsr plot_character
ldx object_index
inx inx
cpx #5 cpx #5
bne fish_loop bne erase_bubble_loop
rts
move_bubbles:
lda phase
and #1
bne bubbles_done
ldx #0
move_bubble_loop:
dec bubble_y,x
lda bubble_y,x
cmp #3
bcs next_bubble
lda #21
sta bubble_y,x
lda bubble_x,x
clc
adc #11
cmp #37
bcc store_bubble_x
sbc #34
store_bubble_x:
sta bubble_x,x
next_bubble:
inx
cpx #5
bne move_bubble_loop
bubbles_done:
rts
draw_all_bubbles:
ldx #0
draw_bubble_loop:
stx object_index
lda bubble_x,x
sta plot_x
lda bubble_y,x
sta plot_y
lda phase
and #2
beq small_bubble
lda #81
bne paint_bubble
small_bubble:
lda #46
paint_bubble:
ldy #3
jsr plot_character
ldx object_index
inx
cpx #5
bne draw_bubble_loop
rts
erase_food:
lda food_active
beq erase_food_done
lda food_x
sta plot_x
lda food_y lda food_y
bne move_food sta plot_y
jmp main
move_food:
ldx food_x
ldy food_y
lda #32 lda #32
jsr plot ldy #6
jsr plot_character
erase_food_done:
rts
move_food:
lda food_active
beq move_food_done
inc food_y inc food_y
lda food_y lda food_y
cmp #22 cmp #22
bcc draw_food bcc move_food_done
lda #0 lda #0
sta food_y sta food_active
jmp main move_food_done:
rts
draw_food: draw_food:
tay lda food_active
ldx food_x beq draw_food_done
lda food_x
sta plot_x
lda food_y
sta plot_y
lda #46 lda #46
jsr plot ldy #8
jmp main jsr plot_character
plot: draw_food_done:
sta char_value rts
lda row_lo,y
sta $fb draw_tank:
lda row_hi,y ; Top and bottom glass.
sta $fc ldx #0
horizontal_glass:
stx plot_x
lda #2
sta plot_y
lda #160
ldy #3
jsr plot_character
lda #23
sta plot_y
lda #160
ldy #3
jsr plot_character
inx
cpx #40
bne horizontal_glass
; Side glass.
ldx #3
vertical_glass:
stx plot_y
lda #0
sta plot_x
lda #160
ldy #3
jsr plot_character
lda #39
sta plot_x
lda #160
ldy #3
jsr plot_character
inx
cpx #23
bne vertical_glass
; Sandy floor.
ldx #1
sand_loop:
stx plot_x
lda #22
sta plot_y
txa txa
tay and #1
lda char_value beq sand_dot
lda #58
bne sand_plot
sand_dot:
lda #46
sand_plot:
ldy #7
jsr plot_character
inx
cpx #39
bne sand_loop
; Five clusters of seaweed.
ldx #0
plant_loop:
stx object_index
lda plant_x,x
sta plot_x
lda #21
sta plot_y
lda #93
ldy #5
jsr plot_character
dec plot_y
lda #94
ldy #5
jsr plot_character
dec plot_y
lda #93
ldy #5
jsr plot_character
ldx object_index
inx
cpx #5
bne plant_loop
rts
; A = screen code, X/Y are supplied through plot_x/plot_y, Y = color.
plot_character:
sta character
sty character_color
ldy plot_y
lda screen_row_lo,y
sta $fb
lda screen_row_hi,y
sta $fc
ldy plot_x
lda character
sta ($fb),y sta ($fb),y
; Color RAM uses the same row/column layout as screen RAM.
ldy plot_y
lda color_row_lo_table,y
sta $fd
lda color_row_hi_table,y
sta $fe
lda character_color
ldy plot_x
sta ($fd),y
rts rts
wait_frame:
lda #250
wait_raster:
cmp $d012
bne wait_raster
wait_leave:
cmp $d012
beq wait_leave
rts
exit: exit:
lda old_border lda old_border
sta $d020 sta $d020
lda old_background lda old_background
sta $d021 sta $d021
lda #147 lda #147
jsr $ffd2 jsr CHROUT
rts rts
title: !byte 147 title: !byte 147
!text "PETSCII AQUARIUM F FEED 1-3 SPEED Q QUIT" !text "PETSCII AQUARIUM F FEED 1-3 SPEED Q QUIT"
!byte 13,0 !byte 0
fish_x: !byte 2,9,16,23,30
fish_y: !byte 5,9,13,17,20 fish_x: !byte 4,28,12,33,7,23
row_lo: !for i,0,24 { !byte <($0400+i*40) } fish_y: !byte 5,8,11,14,17,20
row_hi: !for i,0,24 { !byte >($0400+i*40) } fish_direction: !byte 1,$ff,1,$ff,1,$ff
speed: !byte 0 fish_color: !byte 7,10,8,13,2,15
bubble_x: !byte 6,14,21,29,35
bubble_y: !byte 18,12,20,8,16
plant_x: !byte 5,12,20,28,35
screen_row_lo: !for i,0,24 { !byte <(SCREEN+i*40) }
screen_row_hi: !for i,0,24 { !byte >(SCREEN+i*40) }
color_row_lo_table: !for i,0,24 { !byte <(COLOR+i*40) }
color_row_hi_table: !for i,0,24 { !byte >(COLOR+i*40) }
animation_speed: !byte 0
tick: !byte 0 tick: !byte 0
phase: !byte 0
last_jiffy: !byte 0
food_active: !byte 0
food_x: !byte 0 food_x: !byte 0
food_y: !byte 0 food_y: !byte 0
fish_index: !byte 0 plot_x: !byte 0
old_x: !byte 0 plot_y: !byte 0
char_value: !byte 0 character: !byte 0
character_color: !byte 0
object_index: !byte 0
old_border: !byte 0 old_border: !byte 0
old_background: !byte 0 old_background: !byte 0