mirror of
https://github.com/robmcmullen/fujirun.git
synced 2024-12-28 08:29:34 +00:00
492 lines
10 KiB
ArmAsm
492 lines
10 KiB
ArmAsm
|
|
; os memory map
|
|
KEYBOARD = $c000
|
|
KBDSTROBE = $c010
|
|
CLRTEXT = $c050
|
|
SETTEXT = $c051
|
|
CLRMIXED = $c052
|
|
SETMIXED = $c053
|
|
TXTPAGE1 = $c054
|
|
TXTPAGE2 = $c055
|
|
CLRHIRES = $c056
|
|
SETHIRES = $c057
|
|
|
|
|
|
set_hires bit CLRTEXT ; start with HGR page 1, full screen
|
|
bit CLRMIXED
|
|
bit TXTPAGE1
|
|
bit SETHIRES
|
|
rts
|
|
|
|
; clear all screens, hires and text
|
|
clrscr lda #$20
|
|
sta clrscr_smc+2
|
|
lda #$81
|
|
ldy #0
|
|
clrscr_smc sta $ff00,y
|
|
iny
|
|
bne clrscr_smc
|
|
inc clrscr_smc+2
|
|
ldx clrscr_smc+2
|
|
cpx #$40
|
|
bcc clrscr_smc
|
|
|
|
lda #0
|
|
ldx #39
|
|
?1 jsr text_put_col ; text page 1
|
|
jsr text_put_col2 ; text page 2
|
|
dex
|
|
bpl ?1
|
|
rts
|
|
|
|
|
|
clear_input lda KBDSTROBE
|
|
rts
|
|
|
|
; wait for any key
|
|
any_key lda KBDSTROBE
|
|
?1 lda KEYBOARD
|
|
bpl ?1
|
|
lda KBDSTROBE
|
|
rts
|
|
|
|
; process gameplay user input. Sets actor_input_dir and various debugging
|
|
; input
|
|
userinput lda KEYBOARD
|
|
pha
|
|
ldx #38
|
|
ldy #23
|
|
jsr debughex
|
|
ldx #0
|
|
pla
|
|
bpl input_not_movement ; stop movement of player if no direction input
|
|
|
|
; setting the keyboard strobe causes the key to enter repeat mode if held
|
|
; down, which causes a pause after the initial movement. Not setting the
|
|
; strobe allows smooth movement from the start, but there's no way to stop
|
|
;sta KBDSTROBE
|
|
|
|
check_up cmp #$8d ; up arrow
|
|
beq input_up
|
|
cmp #$c1 ; 'A' key
|
|
beq input_up
|
|
cmp #$c9 ; I
|
|
bne check_down
|
|
input_up lda #TILE_UP
|
|
sta actor_input_dir,x
|
|
rts
|
|
|
|
check_down cmp #$af ; down arrow
|
|
beq input_down
|
|
cmp #$bb ; ';' key (dvorak keyboards!)
|
|
beq input_down
|
|
cmp #$da ; 'Z' key
|
|
beq input_down
|
|
cmp #$d4 ; K
|
|
bne check_left
|
|
input_down lda #TILE_DOWN
|
|
sta actor_input_dir,x
|
|
rts
|
|
|
|
check_left cmp #$88 ; left arrow
|
|
beq input_left
|
|
cmp #$c8 ; J
|
|
bne check_right
|
|
input_left lda #TILE_LEFT
|
|
sta actor_input_dir,x
|
|
rts
|
|
|
|
check_right cmp #$95 ; right arrow
|
|
beq input_right
|
|
cmp #$ce ; L
|
|
bne input_not_movement
|
|
input_right lda #TILE_RIGHT
|
|
sta actor_input_dir,x
|
|
rts
|
|
|
|
input_not_movement lda #0
|
|
sta actor_input_dir,x
|
|
|
|
check_special cmp #$80 + 32
|
|
beq input_space
|
|
cmp #$80 + '.'
|
|
beq input_period
|
|
cmp #$80 + 'P'
|
|
beq input_period
|
|
rts
|
|
|
|
input_space
|
|
jmp debugflipscreens
|
|
|
|
input_period
|
|
jsr wait
|
|
lda KEYBOARD
|
|
bpl input_period
|
|
cmp #$80 + 'P'
|
|
beq input_period
|
|
rts
|
|
|
|
debugflipscreens
|
|
lda #20
|
|
sta scratch_count
|
|
debugloop
|
|
jsr pageflip
|
|
jsr wait
|
|
jsr pageflip
|
|
jsr wait
|
|
dec scratch_count
|
|
bne debugloop
|
|
rts
|
|
|
|
|
|
|
|
; delay for a while. 7 reps = 7 * (2 + 256*19 + 2 + 3) = 34097 cycles
|
|
wait
|
|
ldy #$06
|
|
wait_outer ; outer loop: 2 + 256 * (inner) + 2 + 3
|
|
ldx #$ff
|
|
wait_inner ; inner loop: 14 + 2 + 3
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
dex
|
|
bne wait_inner
|
|
dey
|
|
bne wait_outer
|
|
rts
|
|
|
|
; Offsets in pixels from upper left corner of sprite to where it should
|
|
; appear on screen given the tile coords of where the game logic thinks
|
|
; the sprite is.
|
|
|
|
; [i*7-3 for i in range(40)]
|
|
player_col_to_x .byte 0, 3, 10, 17, 24, 31, 38, 45, 52, 59, 66, 73, 80, 87, 94, 101, 108, 115, 122, 129, 136, 143, 150, 157, 164, 171, 178, 185, 192, 199, 206, 213, 220, 227, 234, 241, 248, 248, 248, 248, 248,
|
|
;.byte 0, 4, 11, 18, 25, 32, 39, 46, 53, 60, 67, 74, 81, 88, 95, 102, 109, 116, 123, 130, 137, 144, 151, 158, 165, 172, 179, 186, 193, 200, 207, 214, 221, 228, 235, 242, 249, 249, 249, 249, 249
|
|
|
|
; [i*8-5 for i in range(24)]
|
|
player_row_to_y .byte 0, 3, 11, 19, 27, 35, 43, 51, 59, 67, 75, 83, 91, 99, 107, 115, 123, 131, 139, 147, 155, 163, 171, 179
|
|
|
|
|
|
; defines the zone around the midpoint where the player can change to any
|
|
; direction, not just backtracking. On the apple, there are 7 x positions but
|
|
; 8 y positions
|
|
x_allowed_turn .byte 0, 0, 1, 1, 1, 0, 0
|
|
y_allowed_turn .byte 0, 0, 1, 1, 1, 0, 0, 0
|
|
|
|
|
|
; Returns address of tile in col 0 of row y
|
|
; row in Y
|
|
mazerow lda textrows_l,y
|
|
sta mazeaddr
|
|
lda textrows_h,y
|
|
sta mazeaddr+1
|
|
rts
|
|
|
|
|
|
; clear text page 2 where most of the variables are stored
|
|
init_vars ldx #0
|
|
txa
|
|
?1 sta $800,x
|
|
sta $900,x
|
|
sta $a00,x
|
|
sta $b00,x
|
|
dex
|
|
bne ?1
|
|
rts
|
|
|
|
|
|
; initialize screen to draw to page 1 (displays page 2)
|
|
init_screen_once nop
|
|
lda #0
|
|
sta KBDSTROBE
|
|
sta drawpage
|
|
jsr draw_to_page1
|
|
rts
|
|
|
|
|
|
; set an entire column (24 rows) of the HGR screen to the specified character
|
|
; on page 1
|
|
; character in A, col in X
|
|
text_put_col nop
|
|
sta $0400,x ; row 0
|
|
sta $0480,x ; row 1
|
|
sta $0500,x ; row 2
|
|
sta $0580,x ; row 3
|
|
sta $0600,x ; row 4
|
|
sta $0680,x ; row 5
|
|
sta $0700,x ; row 6
|
|
sta $0780,x ; row 7
|
|
sta $0428,x ; row 8
|
|
sta $04a8,x ; row 9
|
|
sta $0528,x ; row 10
|
|
sta $05a8,x ; row 11
|
|
sta $0628,x ; row 12
|
|
sta $06a8,x ; row 13
|
|
sta $0728,x ; row 14
|
|
sta $07a8,x ; row 15
|
|
sta $0450,x ; row 16
|
|
sta $04d0,x ; row 17
|
|
sta $0550,x ; row 18
|
|
sta $05d0,x ; row 19
|
|
sta $0650,x ; row 20
|
|
sta $06d0,x ; row 21
|
|
sta $0750,x ; row 22
|
|
sta $07d0,x ; row 23
|
|
rts
|
|
|
|
; ditto except for page 2
|
|
text_put_col2 nop
|
|
sta $0800,x ; row 0
|
|
sta $0880,x ; row 1
|
|
sta $0900,x ; row 2
|
|
sta $0980,x ; row 3
|
|
sta $0a00,x ; row 4
|
|
sta $0a80,x ; row 5
|
|
sta $0b00,x ; row 6
|
|
sta $0b80,x ; row 7
|
|
sta $0828,x ; row 8
|
|
sta $08a8,x ; row 9
|
|
sta $0928,x ; row 10
|
|
sta $09a8,x ; row 11
|
|
sta $0a28,x ; row 12
|
|
sta $0aa8,x ; row 13
|
|
sta $0b28,x ; row 14
|
|
sta $0ba8,x ; row 15
|
|
sta $0850,x ; row 16
|
|
sta $08d0,x ; row 17
|
|
sta $0950,x ; row 18
|
|
sta $09d0,x ; row 19
|
|
sta $0a50,x ; row 20
|
|
sta $0ad0,x ; row 21
|
|
sta $0b50,x ; row 22
|
|
sta $0bd0,x ; row 23
|
|
rts
|
|
|
|
; maze is text screen 1
|
|
textrows_l .byte $00, $80, $00, $80, $00, $80, $00, $80
|
|
.byte $28, $a8, $28, $a8, $28, $a8, $28, $a8
|
|
.byte $50, $d0, $50, $d0, $50, $d0, $50, $d0
|
|
textrows_h .byte $04, $04, $05, $05, $06, $06, $07, $07
|
|
.byte $04, $04, $05, $05, $06, $06, $07, $07
|
|
.byte $04, $04, $05, $05, $06, $06, $07, $07
|
|
|
|
|
|
; sets HGR page 1 to all white using a vertical wipe starting from the
|
|
; top moving down
|
|
wipeclear1 ldy #0
|
|
sty param_y
|
|
wipeclear1_loop lda HGRROWS_L,y
|
|
sta wipeclear1_save_smc+1
|
|
lda HGRROWS_H1,y
|
|
sta wipeclear1_save_smc+2
|
|
ldx #39
|
|
lda #$ff
|
|
wipeclear1_save_smc sta $ffff,x
|
|
dex
|
|
bpl wipeclear1_save_smc
|
|
ldx #WIPE_DELAY
|
|
wipeclear1_wait nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
dex
|
|
bne wipeclear1_wait
|
|
inc param_y
|
|
ldy param_y
|
|
cpy #192
|
|
bcc wipeclear1_loop
|
|
rts
|
|
|
|
|
|
; sets HGR page 1 to the contents of page 2 using a vertical wipe starting
|
|
; from the top moving down
|
|
wipe2to1 ldy #0
|
|
sty param_y
|
|
wipe2to1_loop lda HGRROWS_H2,y
|
|
sta wipe2to1_load_smc+2
|
|
lda HGRROWS_L,y
|
|
sta wipe2to1_load_smc+1
|
|
sta wipe2to1_save_smc+1
|
|
lda HGRROWS_H1,y
|
|
sta wipe2to1_save_smc+2
|
|
ldx #39
|
|
wipe2to1_load_smc lda $ffff,x
|
|
wipe2to1_save_smc sta $ffff,x
|
|
dex
|
|
bpl wipe2to1_load_smc
|
|
ldx #WIPE_DELAY
|
|
wipe2to1_wait nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
nop
|
|
dex
|
|
bne wipe2to1_wait
|
|
inc param_y
|
|
ldy param_y
|
|
cpy #192
|
|
bcc wipe2to1_loop
|
|
rts
|
|
|
|
|
|
; simple (slow, non-optimized) copy of the data from HGR page 2 to HGR page 1
|
|
copy2to1 lda #$40
|
|
sta ?source+2
|
|
lda #$20
|
|
sta ?dest+2
|
|
?outer ldy #0
|
|
?source lda $ff00,y
|
|
?dest sta $ff00,y
|
|
iny
|
|
bne ?source
|
|
inc ?source+2
|
|
inc ?dest+2
|
|
lda ?dest+2
|
|
cmp #$40
|
|
bcc ?outer
|
|
rts
|
|
|
|
|
|
; copy the entire text screen to the current HGR page. The dest_smc address
|
|
; is set in the pageflip routine below so they always point to the page
|
|
; in back, not the page currently being shown.
|
|
copytexthgr nop
|
|
ldy #0 ; y is rows
|
|
copytexthgr_outer
|
|
lda textrows_h,y
|
|
ora #4
|
|
sta copytexthgr_src_smc+2
|
|
lda textrows_l,y
|
|
sta copytexthgr_src_smc+1
|
|
ldx #0 ; x is columns
|
|
copytexthgr_src_smc
|
|
lda $ffff,x
|
|
copytexthgr_dest_smc
|
|
jsr $ffff
|
|
inx
|
|
cpx #40
|
|
bcc copytexthgr_src_smc
|
|
iny
|
|
cpy #24
|
|
bcc copytexthgr_outer
|
|
rts
|
|
|
|
|
|
; change pages based on the state of the drawpage variable. drawpage == 0
|
|
; is page 1, drawpage == $80 is page 2
|
|
pageflip nop
|
|
lda drawpage
|
|
eor #$80
|
|
bpl show_page1 ; pos = show 1, draw 2; neg = show 1, draw 1
|
|
|
|
show_page2 lda #$80
|
|
sta drawpage
|
|
bit TXTPAGE2 ; show page 2, work on page 1
|
|
draw_to_page1 lda #$00
|
|
sta hgrselect
|
|
lda #$20
|
|
sta hgrhi
|
|
lda damageindex ; save other page's damage pointer
|
|
sta damageindex2
|
|
|
|
lda #DAMAGEPAGE1 ; point to page 1's damage area
|
|
sta damageptr+1
|
|
lda damageindex1
|
|
sta damageindex
|
|
|
|
lda tdamageindex ; save other page's damage pointer
|
|
sta tdamageindex2
|
|
lda tdamageindex1 ; point to page 1's damage area
|
|
sta tdamageindex
|
|
lda #0
|
|
sta damagestart
|
|
|
|
; copy addresses for functions that write to one page or the other
|
|
lda #<FASTFONT_H1
|
|
sta fastfont_smc+1
|
|
sta fasttiles_smc+1
|
|
sta copytexthgr_dest_smc+1
|
|
lda #>FASTFONT_H1
|
|
sta fastfont_smc+2
|
|
sta fasttiles_smc+2
|
|
sta copytexthgr_dest_smc+2
|
|
rts
|
|
|
|
show_page1 lda #0
|
|
sta drawpage
|
|
bit TXTPAGE1 ; show page 1, work on page 2
|
|
draw_to_page2 lda #$60
|
|
sta hgrselect
|
|
lda #$40
|
|
sta hgrhi
|
|
lda damageindex ; save other page's damage pointer
|
|
sta damageindex1
|
|
|
|
lda #DAMAGEPAGE2 ; point to page 2's damage area
|
|
sta damageptr+1
|
|
lda damageindex2
|
|
sta damageindex
|
|
|
|
lda tdamageindex ; save other page's damage pointer
|
|
sta tdamageindex1
|
|
lda tdamageindex2 ; point to page 2's damage area
|
|
sta tdamageindex
|
|
lda #128
|
|
sta damagestart
|
|
|
|
lda #<FASTFONT_H2
|
|
sta fastfont_smc+1
|
|
sta fasttiles_smc+1
|
|
sta copytexthgr_dest_smc+1
|
|
lda #>FASTFONT_H2
|
|
sta fastfont_smc+2
|
|
sta fasttiles_smc+2
|
|
sta copytexthgr_dest_smc+2
|
|
rts
|
|
|
|
; tile for middle left/right (number 12) is a color tile and gets
|
|
; the wrong bit pattern when it's in an odd column -- replace the
|
|
; image with tile 15 when necessary
|
|
fastfont nop
|
|
cmp #12
|
|
bne fastfont_smc
|
|
txa
|
|
and #1
|
|
bne ?1
|
|
lda #15
|
|
bne fastfont_smc
|
|
?1 lda #12
|
|
fastfont_smc jmp $ffff
|
|
|
|
; restore a horizontal segment from the text page to the current screen
|
|
; param_col = text column
|
|
; param_row = text screen row
|
|
; param_count = number of characters to copy to hgr screen
|
|
fasttiles ldx param_col
|
|
ldy param_row
|
|
lda textrows_h,y
|
|
sta fasttiles_row_smc+2
|
|
lda textrows_l,y
|
|
sta fasttiles_row_smc+1
|
|
fasttiles_row_smc lda $ffff,x
|
|
cmp #12
|
|
bne fasttiles_smc
|
|
txa
|
|
and #1
|
|
bne ?1
|
|
lda #15
|
|
bne fasttiles_smc
|
|
?1 lda #12
|
|
fasttiles_smc jsr $ffff
|
|
inx
|
|
dec param_count
|
|
bne fasttiles_row_smc
|
|
rts
|