1340 lines
18 KiB
ArmAsm
1340 lines
18 KiB
ArmAsm
.segment "HEADER"
|
|
|
|
INES_MAPPER = 0
|
|
INES_MIRROR = 1
|
|
INES_SRAM = 0
|
|
|
|
.byte 'N', 'E', 'S', $1A
|
|
.byte $02
|
|
.byte $01
|
|
.byte INES_MIRROR
|
|
.byte (INES_MAPPER & %11110000)
|
|
.byte $0, $0, $0, $0, $0, $0, $0, $0
|
|
|
|
|
|
.segment "TILES"
|
|
.incbin "background.chr"
|
|
.incbin "sprite.chr"
|
|
|
|
|
|
.segment "VECTORS"
|
|
.word nmi
|
|
.word reset
|
|
.word irq
|
|
|
|
|
|
.segment "CODE"
|
|
reset:
|
|
sei
|
|
lda #0
|
|
sta $2000
|
|
lda #0
|
|
sta $2001
|
|
sta $4015
|
|
sta $4010
|
|
lda #40
|
|
sta $4017
|
|
cld
|
|
ldx #$FF
|
|
txs
|
|
|
|
bit $2002
|
|
:
|
|
bit $2002
|
|
bpl :-
|
|
|
|
lda #0
|
|
ldx #0
|
|
:
|
|
sta $0000, X
|
|
sta $0100, X
|
|
sta $0200, X
|
|
sta $0300, X
|
|
sta $0400, X
|
|
sta $0500, X
|
|
sta $0600, X
|
|
sta $0700, X
|
|
inx
|
|
bne :-
|
|
|
|
lda #255
|
|
ldx #0
|
|
:
|
|
sta oam, X
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
bne :-
|
|
|
|
:
|
|
bit $2002
|
|
bpl :-
|
|
|
|
lda #%10101000 ; NMI enable, 8x16 sprites, ignored due to 8x16 mode
|
|
sta $2000
|
|
jmp main
|
|
|
|
|
|
.segment "ZEROPAGE"
|
|
nmi_lock: .res 1
|
|
nmi_count: .res 1
|
|
nmi_ready: .res 1
|
|
nmt_update_len: .res 1
|
|
scroll_x: .res 1
|
|
scroll_y: .res 1
|
|
scroll_nmt: .res 1
|
|
temp: .res 1
|
|
|
|
.segment "BSS"
|
|
nmt_update: .res 256
|
|
palette: .res 32
|
|
|
|
.segment "OAM"
|
|
oam: .res 256
|
|
|
|
.segment "CODE"
|
|
nmi:
|
|
pha
|
|
txa
|
|
pha
|
|
tya
|
|
pha
|
|
|
|
lda nmi_lock
|
|
beq :+
|
|
jmp @nmi_end
|
|
|
|
:
|
|
lda #1
|
|
sta nmi_lock
|
|
|
|
lda nmi_ready
|
|
bne :+
|
|
jmp @ppu_update_end
|
|
|
|
:
|
|
cmp #2
|
|
bne :+
|
|
lda #%00000000
|
|
sta $2001
|
|
ldx #0
|
|
stx nmi_ready
|
|
jmp @ppu_update_end
|
|
|
|
:
|
|
ldx #0
|
|
stx $2003
|
|
lda #>oam
|
|
sta $4014
|
|
|
|
lda #%10101000 ; NMI enable, 8x16 sprites, ignored due to 8x16 mode
|
|
sta $2000
|
|
lda $2002
|
|
lda #$3F
|
|
sta $2006
|
|
stx $2006
|
|
ldx #0
|
|
:
|
|
lda palette, X
|
|
sta $2007
|
|
inx
|
|
cpx #32
|
|
bcc :-
|
|
|
|
ldx #0
|
|
cpx nmt_update_len
|
|
bcs @scroll
|
|
@nmt_update_loop:
|
|
lda nmt_update, X
|
|
sta $2006
|
|
inx
|
|
lda nmt_update, X
|
|
sta $2006
|
|
inx
|
|
lda nmt_update, X
|
|
sta $2007
|
|
cpx nmt_update_len
|
|
bcc @nmt_update_loop
|
|
|
|
lda #0
|
|
sta nmt_update_len
|
|
@scroll:
|
|
lda scroll_nmt
|
|
and #%00000011
|
|
ora #%10101000
|
|
sta $2000
|
|
lda scroll_x
|
|
sta $2005
|
|
lda scroll_y
|
|
sta $2005
|
|
|
|
lda #%00011110
|
|
sta $2001
|
|
|
|
ldx #0
|
|
stx nmi_ready
|
|
@ppu_update_end:
|
|
lda #0
|
|
sta nmi_lock
|
|
@nmi_end:
|
|
pla
|
|
tay
|
|
pla
|
|
tax
|
|
pla
|
|
rti
|
|
|
|
|
|
.segment "CODE"
|
|
irq:
|
|
rti
|
|
|
|
|
|
.segment "CODE"
|
|
ppu_update:
|
|
lda #1
|
|
sta nmi_ready
|
|
:
|
|
lda nmi_ready
|
|
bne :-
|
|
|
|
rts
|
|
|
|
ppu_skip:
|
|
lda nmi_count
|
|
:
|
|
cmp nmi_count
|
|
beq :-
|
|
|
|
rts
|
|
|
|
ppu_off:
|
|
lda #2
|
|
sta nmi_ready
|
|
:
|
|
lda nmi_ready
|
|
bne :-
|
|
|
|
rts
|
|
|
|
ppu_address_tile:
|
|
lda $2002
|
|
tya
|
|
lsr
|
|
lsr
|
|
lsr
|
|
ora #$20
|
|
sta $2006
|
|
tya
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sta temp
|
|
txa
|
|
ora temp
|
|
sta $2006
|
|
rts
|
|
|
|
ppu_update_tile:
|
|
pha
|
|
txa
|
|
pha
|
|
ldx nmt_update_len
|
|
tya
|
|
lsr
|
|
lsr
|
|
lsr
|
|
ora #$20
|
|
sta nmt_update, X
|
|
inx
|
|
tya
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sta temp
|
|
pla
|
|
ora temp
|
|
sta nmt_update, X
|
|
inx
|
|
pla
|
|
sta nmt_update, X
|
|
inx
|
|
stx nmt_update_len
|
|
rts
|
|
|
|
ppu_update_byte:
|
|
pha
|
|
tya
|
|
pha
|
|
ldy nmt_update_len
|
|
txa
|
|
sta nmt_update, Y
|
|
iny
|
|
pla
|
|
sta nmt_update, Y
|
|
iny
|
|
pla
|
|
sta nmt_update, Y
|
|
iny
|
|
sty nmt_update_len
|
|
rts
|
|
|
|
|
|
PAD_A = $01
|
|
PAD_B = $02
|
|
PAD_SELECT = $04
|
|
PAD_START = $08
|
|
PAD_U = $10
|
|
PAD_D = $20
|
|
PAD_L = $40
|
|
PAD_R = $80
|
|
|
|
.segment "ZEROPAGE"
|
|
gamepad: .res 1
|
|
|
|
.segment "CODE"
|
|
; gamepad_poll: this reads the gamepad state into the variable labelled "gamepad"
|
|
; This only reads the first gamepad, and also if DPCM samples are played they can
|
|
; conflict with gamepad reading, which may give incorrect results.
|
|
gamepad_poll:
|
|
; strobe the gamepad to latch current button state
|
|
lda #1
|
|
sta $4016
|
|
lda #0
|
|
sta $4016
|
|
; read 8 bytes from the interface at $4016
|
|
ldx #8
|
|
:
|
|
pha
|
|
lda $4016
|
|
; combine low two bits and store in carry bit
|
|
and #%00000011
|
|
cmp #%00000001
|
|
pla
|
|
; rotate carry into gamepad variable
|
|
ror
|
|
dex
|
|
bne :-
|
|
sta gamepad
|
|
rts
|
|
|
|
|
|
.segment "RODATA"
|
|
|
|
level:
|
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
.byte 0,1,0,0,1,0,0,0,0,1,0,0,2,7,7,3
|
|
.byte 0,0,0,0,0,0,0,0,0,1,0,0,6,0,0,9
|
|
.byte 0,1,0,0,1,0,0,0,0,1,0,0,6,0,0,9
|
|
.byte 0,0,1,1,0,0,0,0,0,1,0,0,4,8,8,5
|
|
.byte 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0
|
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
.byte 0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0
|
|
.byte 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0
|
|
.byte 0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0
|
|
.byte 0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0
|
|
.byte 0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0
|
|
.byte 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0
|
|
.byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
|
|
|
block_x: .res 1
|
|
block_y: .res 1
|
|
block_w: .res 1
|
|
block_h: .res 1
|
|
|
|
metatiles:
|
|
.byte 0,0,0,0,0
|
|
.byte $14,$15,$16,$17,1 ; Full block
|
|
.byte $14,$18,$1B,$0,1 ; up / left
|
|
.byte $18,$15,$0,$19,1 ; up / right
|
|
.byte $1B,$0,$16,$1A,1 ; down / left
|
|
.byte $0,$19,$1A,$17,1 ; down / right
|
|
.byte $1B,$0,$1B,$0,1 ; left
|
|
.byte $18,$18,$0,$0,1 ; up
|
|
.byte $0,$0,$1A,$1A,1 ; down
|
|
.byte $0,$19,$0,$19,1 ; right
|
|
.byte 3,3,3,3,0
|
|
.byte 3,4,5,6,0
|
|
|
|
example_palette:
|
|
.byte $0F,$00,$3D,$20 ; greyscale
|
|
.byte $0F,$09,$1A,$16 ; grass
|
|
.byte $0F,$15,$26,$37 ; bg0 purple/pink
|
|
.byte $0F,$09,$19,$29 ; bg1 green
|
|
.byte $0F,$2D,$10,$3D ; reboot bottom
|
|
.byte $0F,$2D,$10,$2C ; reboot eye
|
|
.byte $0F,$01,$11,$21 ; bg2 blue
|
|
.byte $0F,$00,$10,$30 ; bg3 greyscale
|
|
; .byte $0F,$18,$28,$38 ; sp0 yellow
|
|
; .byte $0F,$14,$24,$34 ; sp1 purple
|
|
; .byte $0F,$1B,$2B,$3B ; sp2 teal
|
|
; .byte $0F,$12,$22,$32 ; sp3 marine
|
|
|
|
.segment "ZEROPAGE"
|
|
buttons: .res 1
|
|
|
|
player_pos_x: .res 1
|
|
player_pos_y: .res 1
|
|
player_vel_x: .res 1
|
|
player_vel_y: .res 1
|
|
|
|
player_status: .res 1 ; 76543210 | 0: facing (0 right, 1 left)
|
|
; | 7: talking
|
|
|
|
cursor_x: .res 1
|
|
cursor_y: .res 1
|
|
temp_x: .res 1
|
|
temp_y: .res 1
|
|
temp_mul: .res 1
|
|
var_m: .res 1
|
|
var_n: .res 1
|
|
var_o: .res 1
|
|
var_p: .res 1
|
|
|
|
jump_pressed_last_frame: .res 1
|
|
|
|
frame_counter: .res 1
|
|
last_frame_jumped: .res 1
|
|
|
|
.segment "CODE"
|
|
main:
|
|
ldx #0
|
|
:
|
|
lda example_palette, X
|
|
sta palette, X
|
|
inx
|
|
cpx #32
|
|
bcc :-
|
|
|
|
jsr setup_background
|
|
jsr ppu_update
|
|
|
|
lda #$40
|
|
sta cursor_x
|
|
sta cursor_y
|
|
|
|
lda #0
|
|
sta frame_counter
|
|
sta last_frame_jumped
|
|
|
|
jsr init_objects
|
|
@loop:
|
|
lda frame_counter
|
|
clc
|
|
adc #1
|
|
sta frame_counter
|
|
|
|
jsr controller
|
|
jsr movement
|
|
|
|
@draw:
|
|
jsr update_background
|
|
jsr draw_player
|
|
jsr ppu_update
|
|
|
|
jmp @loop
|
|
|
|
draw_player:
|
|
lda player_pos_y
|
|
sec
|
|
sbc #1
|
|
sta oam + (4 * 2) + 0
|
|
sta oam + (4 * 3) + 0
|
|
sec
|
|
sbc #16
|
|
sta oam + (4 * 0) + 0
|
|
sta oam + (4 * 1) + 0
|
|
|
|
lda player_status
|
|
and #%00000001
|
|
cmp #0
|
|
bne :+
|
|
lda player_pos_x
|
|
sta oam + (4 * 1) + 3
|
|
sta oam + (4 * 3) + 3
|
|
sec
|
|
sbc #8
|
|
sta oam + (4 * 0) + 3
|
|
sta oam + (4 * 2) + 3
|
|
jmp :++
|
|
:
|
|
lda player_pos_x
|
|
sta oam + (4 * 0) + 3
|
|
sta oam + (4 * 2) + 3
|
|
sec
|
|
sbc #8
|
|
sta oam + (4 * 1) + 3
|
|
sta oam + (4 * 3) + 3
|
|
:
|
|
|
|
lda player_status
|
|
and #%10000000
|
|
cmp #0
|
|
bne :+
|
|
lda #$45
|
|
jmp :++
|
|
:
|
|
lda #$49
|
|
:
|
|
sta oam + (4 * 0) + 1
|
|
clc
|
|
adc #2
|
|
sta oam + (4 * 1) + 1
|
|
lda #$65
|
|
sta oam + (4 * 2) + 1
|
|
lda #$67
|
|
sta oam + (4 * 3) + 1
|
|
|
|
|
|
lda player_status
|
|
and #%00000001
|
|
cmp #0
|
|
beq :+
|
|
lda #%01000000
|
|
jmp :++
|
|
:
|
|
lda #%00000000
|
|
:
|
|
|
|
ora #%00000001
|
|
sta oam + (4 * 0) + 2
|
|
ora #%00000001
|
|
sta oam + (4 * 1) + 2
|
|
and #%11111100
|
|
sta oam + (4 * 2) + 2
|
|
and #%11111100
|
|
sta oam + (4 * 3) + 2
|
|
|
|
rts
|
|
|
|
init_objects:
|
|
lda #0
|
|
sta var_n
|
|
ldx #0
|
|
:
|
|
lda var_n
|
|
clc
|
|
adc #8
|
|
sta var_n
|
|
|
|
sta player_pos_y, X ; Set Y position
|
|
sta player_pos_x, X ; Set X position
|
|
|
|
txa
|
|
lsr
|
|
lsr
|
|
sta oam+1, X
|
|
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
cpx #(8*4)
|
|
bne :-
|
|
|
|
lda #0
|
|
sta player_vel_x
|
|
sta player_vel_y
|
|
sta player_status
|
|
|
|
lda #64
|
|
sta block_x
|
|
sta block_y
|
|
|
|
lda #16
|
|
sta block_w
|
|
sta block_h
|
|
|
|
rts
|
|
|
|
draw:
|
|
@end:
|
|
rts
|
|
|
|
movement:
|
|
; Talking
|
|
ldx #0
|
|
jsr btn_b
|
|
cmp #0
|
|
beq :+
|
|
lda player_status
|
|
ora #%10000000
|
|
sta player_status
|
|
jmp :++
|
|
:
|
|
lda player_status
|
|
and #%01111111
|
|
sta player_status
|
|
:
|
|
|
|
; Horizontal velocity
|
|
ldx #0
|
|
jsr btn_right
|
|
cmp #0
|
|
beq :+
|
|
ldx #1
|
|
lda #2
|
|
sta player_vel_x
|
|
|
|
lda player_status
|
|
and #%11111110
|
|
sta player_status
|
|
:
|
|
|
|
jsr btn_left
|
|
cmp #0
|
|
beq :+
|
|
ldx #1
|
|
lda #254
|
|
sta player_vel_x
|
|
|
|
lda player_status
|
|
ora #%00000001
|
|
sta player_status
|
|
:
|
|
|
|
cpx #1
|
|
beq @end
|
|
lda frame_counter
|
|
and #1
|
|
cmp #0
|
|
bne @end
|
|
|
|
lda #0
|
|
cmp player_vel_x
|
|
beq @end ; If player_vel_x = 0, skip decay
|
|
|
|
; If player_vel_x > 0, decrement
|
|
bpl :+
|
|
ldx player_vel_x
|
|
dex
|
|
stx player_vel_x
|
|
jmp @end
|
|
:
|
|
; Else if player_vel_x < 0, increment
|
|
ldx player_vel_x
|
|
inx
|
|
stx player_vel_x
|
|
@end:
|
|
|
|
; Jump
|
|
jsr btn_a
|
|
cmp #0
|
|
beq @fail_jump ; If jump not pressed, forget it
|
|
lda jump_pressed_last_frame
|
|
cmp #1
|
|
beq @fail_jump ; If jump last frame, forget it
|
|
|
|
; Jump newly pressed this frame
|
|
lda #249
|
|
sta player_vel_y
|
|
|
|
lda frame_counter
|
|
sta last_frame_jumped
|
|
|
|
@fail_jump:
|
|
|
|
jsr btn_a
|
|
sta jump_pressed_last_frame
|
|
|
|
|
|
; Gravity
|
|
lda frame_counter
|
|
sec
|
|
sbc last_frame_jumped
|
|
and #%00000001
|
|
cmp #0
|
|
bne :+
|
|
lda player_vel_y
|
|
clc
|
|
adc #1 ; Add 2 to velocity
|
|
sta player_vel_y
|
|
:
|
|
|
|
; Apply Y velocity
|
|
lda player_pos_y
|
|
clc
|
|
adc player_vel_y
|
|
sta player_pos_y
|
|
|
|
; Apply X velocity
|
|
lda player_pos_x
|
|
clc
|
|
adc player_vel_x
|
|
sta player_pos_x
|
|
|
|
; load x pos, filter blocks, check up and down
|
|
|
|
lda player_vel_y
|
|
cmp #0
|
|
bmi :+ ; branch if moving up
|
|
jsr downward_collision_check
|
|
jsr left_collision_check
|
|
jsr right_collision_check
|
|
jsr upward_collision_check
|
|
jmp :++
|
|
:
|
|
jsr upward_collision_check
|
|
jsr left_collision_check
|
|
jsr right_collision_check
|
|
jsr downward_collision_check
|
|
:
|
|
|
|
rts
|
|
|
|
; Keep grounded
|
|
cmp #200
|
|
bcc :+
|
|
lda #0
|
|
sta player_vel_y
|
|
lda #200
|
|
sta player_pos_y
|
|
:
|
|
; Bonk
|
|
lda #8
|
|
cmp player_pos_y
|
|
bcc :+
|
|
lda #0
|
|
sta player_vel_y
|
|
lda #8
|
|
sta player_pos_y
|
|
:
|
|
|
|
rts
|
|
|
|
update_background:
|
|
rts
|
|
;lda $2002
|
|
;lda #$20
|
|
;sta $2006
|
|
;lda #$00
|
|
;sta $2006
|
|
|
|
ldx #1
|
|
ldy #1
|
|
jsr ppu_update_tile
|
|
|
|
lda #1
|
|
sta $2007
|
|
|
|
rts
|
|
|
|
setup_background:
|
|
lda $2002 ; reset latch
|
|
lda #$20
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
; empty nametable
|
|
lda #0
|
|
ldy #30 ; 30 rows
|
|
:
|
|
ldx #32 ; 32 columns
|
|
:
|
|
sta $2007
|
|
dex
|
|
bne :-
|
|
dey
|
|
bne :--
|
|
|
|
lda $2002
|
|
lda #$20
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
ldy #0
|
|
@row_start:
|
|
ldx #0
|
|
:
|
|
txa
|
|
pha
|
|
|
|
; index is (Y * 16) + X
|
|
stx temp_x
|
|
lda #16
|
|
jsr mul_y
|
|
clc
|
|
adc temp_x
|
|
tax
|
|
|
|
lda level, X
|
|
ldx #5
|
|
jsr mul_x
|
|
tax
|
|
|
|
lda metatiles+0, X
|
|
sta $2007
|
|
lda metatiles+1, X
|
|
sta $2007
|
|
|
|
pla
|
|
tax
|
|
inx
|
|
cpx #16
|
|
bne :-
|
|
|
|
; again
|
|
ldx #0
|
|
:
|
|
txa
|
|
pha
|
|
|
|
; index is (Y * 16) + X
|
|
stx temp_x
|
|
lda #16
|
|
jsr mul_y
|
|
clc
|
|
adc temp_x
|
|
tax
|
|
|
|
lda level, X
|
|
ldx #5
|
|
jsr mul_x
|
|
tax
|
|
|
|
lda metatiles+2, X
|
|
sta $2007
|
|
lda metatiles+3, X
|
|
sta $2007
|
|
|
|
pla
|
|
tax
|
|
inx
|
|
cpx #16
|
|
bne :-
|
|
iny
|
|
cpy #15
|
|
bne @row_start
|
|
|
|
|
|
; clear attributes
|
|
lda #0
|
|
ldx #64 ; 64 bytes
|
|
:
|
|
lda #%11100100
|
|
|
|
sta $2007
|
|
dex
|
|
bne :-
|
|
|
|
rts
|
|
|
|
|
|
|
|
lda $2002 ; reset latch
|
|
lda #$20
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
; empty nametable
|
|
lda #0
|
|
ldy #30 ; 30 rows
|
|
:
|
|
ldx #32 ; 32 columns
|
|
:
|
|
sta $2007
|
|
dex
|
|
bne :-
|
|
dey
|
|
bne :--
|
|
; set all attributes to 0
|
|
lda #0
|
|
ldx #64 ; 64 bytes
|
|
:
|
|
txa
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sta temp
|
|
txa
|
|
and #%00000011
|
|
ora temp
|
|
lda #0
|
|
|
|
sta $2007
|
|
dex
|
|
bne :-
|
|
|
|
|
|
|
|
|
|
|
|
; fill in an area in the middle with 1/2 checkerboard
|
|
lda #1
|
|
ldy #0 ; start at row 8
|
|
:
|
|
pha ; temporarily store A, it will be clobbered by ppu_address_tile routine
|
|
ldx #8 ; start at column 8
|
|
jsr ppu_address_tile
|
|
pla ; recover A
|
|
|
|
ldx #8
|
|
:
|
|
sta $2007
|
|
eor #$3
|
|
inx
|
|
cpx #(32-8)
|
|
bcc :-
|
|
eor #$3
|
|
iny
|
|
cpy #(30-8)
|
|
bcc :--
|
|
|
|
lda #$24
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
lda #$00
|
|
ldy #30
|
|
:
|
|
ldx #32
|
|
:
|
|
sta $2007
|
|
clc
|
|
adc #1
|
|
and #3
|
|
dex
|
|
bne :-
|
|
clc
|
|
adc #1
|
|
and #3
|
|
dey
|
|
bne :--
|
|
|
|
lda #0
|
|
ldy #4
|
|
:
|
|
ldx #16
|
|
:
|
|
sta $2007
|
|
dex
|
|
bne :-
|
|
|
|
clc
|
|
adc #%01010101
|
|
dey
|
|
bne :--
|
|
|
|
rts
|
|
|
|
mul_x:
|
|
cmp #0
|
|
beq @zero
|
|
cpx #0
|
|
beq @zero
|
|
|
|
sta temp_mul
|
|
|
|
txa
|
|
pha
|
|
lda #0
|
|
:
|
|
clc
|
|
adc temp_mul
|
|
dex
|
|
bne :-
|
|
sta temp_mul
|
|
pla
|
|
tax
|
|
lda temp_mul
|
|
rts
|
|
|
|
@zero:
|
|
lda #0
|
|
rts
|
|
|
|
mul_y:
|
|
cmp #0
|
|
beq @zero
|
|
cpy #0
|
|
beq @zero
|
|
|
|
sta temp_mul
|
|
|
|
tya
|
|
pha
|
|
lda #0
|
|
:
|
|
clc
|
|
adc temp_mul
|
|
dey
|
|
bne :-
|
|
sta temp_mul
|
|
pla
|
|
tay
|
|
lda temp_mul
|
|
rts
|
|
|
|
@zero:
|
|
lda #0
|
|
rts
|
|
|
|
controller:
|
|
lda #1
|
|
sta $4016
|
|
sta buttons
|
|
lda #0
|
|
sta $4016
|
|
:
|
|
lda $4016
|
|
lsr
|
|
rol buttons
|
|
bcc :-
|
|
|
|
rts
|
|
|
|
btn_right:
|
|
lda buttons
|
|
and #%00000001
|
|
rts
|
|
|
|
btn_left:
|
|
lda buttons
|
|
and #%00000010
|
|
lsr
|
|
rts
|
|
|
|
btn_down:
|
|
lda buttons
|
|
and #%00000100
|
|
lsr
|
|
lsr
|
|
rts
|
|
|
|
btn_up:
|
|
lda buttons
|
|
and #%00001000
|
|
lsr
|
|
lsr
|
|
lsr
|
|
rts
|
|
|
|
btn_start:
|
|
lda buttons
|
|
and #%00010000
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
rts
|
|
|
|
btn_select:
|
|
lda buttons
|
|
and #%00100000
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
rts
|
|
|
|
btn_b:
|
|
lda buttons
|
|
and #%01000000
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
rts
|
|
|
|
btn_a:
|
|
lda buttons
|
|
and #%10000000
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
lsr
|
|
rts
|
|
|
|
downward_collision_check:
|
|
lda #0
|
|
sta var_n
|
|
@begin_check:
|
|
lda player_pos_x
|
|
ldx var_n
|
|
cpx #0
|
|
bne :+
|
|
sec
|
|
sbc #6
|
|
jmp :++
|
|
:
|
|
clc
|
|
adc #5
|
|
:
|
|
; divide by 16
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
sta temp_x
|
|
|
|
lda player_pos_y
|
|
; divide by 16
|
|
clc
|
|
adc #8
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
tay
|
|
|
|
lda #16
|
|
jsr mul_y
|
|
adc temp_x
|
|
tax
|
|
lda level, X
|
|
cmp #0
|
|
beq :+
|
|
tya
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sec
|
|
sbc #8
|
|
cmp player_pos_y
|
|
bcs :+
|
|
sta player_pos_y
|
|
lda #0
|
|
sta player_vel_y
|
|
:
|
|
|
|
ldx var_n
|
|
inx
|
|
stx var_n
|
|
cpx #1
|
|
beq @begin_check
|
|
|
|
rts
|
|
|
|
upward_collision_check:
|
|
lda #0
|
|
sta var_n
|
|
@begin_check:
|
|
lda player_pos_x
|
|
ldx var_n
|
|
cpx #0
|
|
bne :+
|
|
sec
|
|
sbc #6
|
|
jmp :++
|
|
:
|
|
clc
|
|
adc #5
|
|
:
|
|
; divide by 16
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
sta temp_x
|
|
|
|
lda player_pos_y
|
|
; divide by 16
|
|
sec
|
|
sbc #8
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
tay
|
|
|
|
lda #16
|
|
jsr mul_y
|
|
adc temp_x
|
|
tax
|
|
lda level, X
|
|
cmp #0
|
|
beq :+
|
|
iny
|
|
tya
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
clc
|
|
adc #8
|
|
cmp player_pos_y
|
|
bcc :+
|
|
sta player_pos_y
|
|
lda #0
|
|
sta player_vel_y
|
|
:
|
|
|
|
ldx var_n
|
|
inx
|
|
stx var_n
|
|
cpx #1
|
|
beq @begin_check
|
|
|
|
rts
|
|
|
|
right_collision_check:
|
|
lda #0
|
|
sta var_n
|
|
@begin_check:
|
|
lda player_pos_x
|
|
; divide by 16
|
|
clc
|
|
adc #8
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
sta temp_x
|
|
|
|
lda player_pos_y
|
|
ldx var_n
|
|
cpx #0
|
|
bne :+
|
|
sec
|
|
sbc #7
|
|
jmp :++
|
|
:
|
|
clc
|
|
adc #6
|
|
:
|
|
; divide by 16
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
tay
|
|
|
|
lda #16
|
|
jsr mul_y
|
|
adc temp_x
|
|
tax
|
|
lda level, X
|
|
cmp #0
|
|
beq :+
|
|
lda temp_x
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sec
|
|
sbc #8
|
|
cmp player_pos_x
|
|
bcs :+
|
|
sta player_pos_x
|
|
lda #0
|
|
sta player_vel_x
|
|
:
|
|
|
|
ldx var_n
|
|
inx
|
|
stx var_n
|
|
cpx #1
|
|
beq @begin_check
|
|
|
|
rts
|
|
|
|
left_collision_check:
|
|
lda #0
|
|
sta var_n
|
|
@begin_check:
|
|
lda player_pos_x
|
|
; divide by 16
|
|
sec
|
|
sbc #8
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
sta temp_x
|
|
|
|
lda player_pos_y
|
|
ldx var_n
|
|
cpx #0
|
|
bne :+
|
|
sec
|
|
sbc #7
|
|
jmp :++
|
|
:
|
|
clc
|
|
adc #6
|
|
:
|
|
; divide by 16
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
tay
|
|
|
|
lda #16
|
|
jsr mul_y
|
|
adc temp_x
|
|
tax
|
|
lda level, X
|
|
cmp #0
|
|
beq :+
|
|
lda temp_x
|
|
clc
|
|
adc #1
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
clc
|
|
adc #8
|
|
cmp player_pos_x
|
|
bcc :+
|
|
sta player_pos_x
|
|
lda #0
|
|
sta player_vel_x
|
|
:
|
|
|
|
ldx var_n
|
|
inx
|
|
stx var_n
|
|
cpx #1
|
|
beq @begin_check
|
|
|
|
rts
|