2143 lines
37 KiB
ArmAsm
2143 lines
37 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
|
|
nmt_column: .res 1
|
|
nmt_update_frame: .res 1
|
|
scroll_x: .res 1
|
|
scroll_y: .res 1
|
|
scroll_nmt: .res 1
|
|
scroll_page: .res 1
|
|
temp: .res 1
|
|
|
|
PPUCTRL_default = %10101000
|
|
|
|
.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
|
|
|
|
lda PPUCTRL_default
|
|
;ora #%00000100
|
|
sta $2000
|
|
|
|
ldy #0
|
|
ldx #0
|
|
@nmt_update_loop:
|
|
lda nmt_update_frame
|
|
cmp #0
|
|
bne :+
|
|
lda nmt_update+0, X
|
|
sta $2006
|
|
lda nmt_update+1, X
|
|
sta $2006
|
|
|
|
lda nmt_update+2, X
|
|
sta $2007
|
|
lda nmt_update+3, X
|
|
sta $2007
|
|
|
|
jmp :++
|
|
:
|
|
lda nmt_update+0, X
|
|
sta $2006
|
|
lda nmt_update+1, X
|
|
clc
|
|
adc #32
|
|
sta $2006
|
|
|
|
lda nmt_update+4, X
|
|
sta $2007
|
|
lda nmt_update+5, X
|
|
sta $2007
|
|
:
|
|
|
|
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
inx
|
|
|
|
iny
|
|
cpy nmt_update_len
|
|
bcc @nmt_update_loop
|
|
|
|
lda PPUCTRL_default
|
|
sta $2000
|
|
|
|
inc nmt_update_frame
|
|
lda nmt_update_frame
|
|
cmp #2
|
|
bne :+
|
|
lda #0
|
|
sta nmt_update_frame
|
|
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
|
|
|
|
|
|
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 "RODATA"
|
|
|
|
default_level:
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80,$80
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
;.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
;.byte $00,$00,$00,$00,$00,$00,$00,$81,$00,$81,$00,$81,$00,$81,$00,$00
|
|
;.byte $82,$83,$00,$00,$00,$00,$00,$00,$81,$00,$0C,$00,$81,$00,$00,$00
|
|
;.byte $84,$85,$00,$00,$00,$00,$00,$81,$00,$81,$00,$81,$00,$81,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$0C,$00,$0C,$00,$0C,$00,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$81,$00,$81,$00,$81,$00,$81,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$81,$00,$0C,$00,$81,$00,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$81,$00,$81,$00,$81,$00,$81,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$8C,$87
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
;.byte $0F,$8C,$87,$87,$87,$87,$87,$87,$87,$87,$87,$87,$87,$87,$87,$87
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
;.byte $0F,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
|
|
default_level2:
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$8C,$8C,$8C,$8C,$8C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$09,$01,$01,$01,$8C,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$8C,$8C,$8C,$01,$06,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
|
|
.byte $00,$09,$01,$01,$01,$8C,$00,$00,$00,$00,$00,$82,$83,$00,$00,$00
|
|
.byte $00,$8C,$8C,$8C,$8C,$8C,$00,$00,$00,$00,$00,$84,$85,$00,$00,$00
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0F,$0E,$00,$82,$83
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$0F,$0E,$00,$84,$85
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$82,$83,$00,$0F,$0E,$00,$0F,$0E
|
|
.byte $87,$8C,$00,$00,$00,$00,$00,$00,$84,$85,$00,$0F,$0E,$00,$0F,$0E
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$0F,$0E,$00,$0F,$0E,$00,$0F,$0E
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$0F,$0E,$00,$0F,$0E,$00,$0F,$0E
|
|
.byte $87,$87,$87,$87,$87,$8C,$00,$00,$0F,$0E,$00,$0F,$0E,$00,$0F,$0E
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$0F,$0E,$00,$8A,$8A,$8A,$8A,$0E
|
|
.byte $00,$00,$00,$00,$00,$00,$00,$00,$0F,$0E,$00,$8B,$8B,$8B,$8B,$0E
|
|
|
|
;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,0,0,0,6,0,0,9
|
|
;.byte 0,1,0,0,1,7,7,7,7,1,7,7,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,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,10,10,10,10,10
|
|
;.byte 0,0,1,0,0,0,0,1,0,0,0,11,11,11,11,11
|
|
;.byte 0,1,2,3,4,5,6,7,8,9,0,11,11,11,11,11
|
|
;.byte 0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11
|
|
|
|
metatiles:
|
|
.byte 0,0,0,0,0
|
|
.byte $14,$15,$16,$17,%00000000 ; 1: Full block
|
|
.byte $14,$18,$1B,$00,%00000000 ; 2: up / left
|
|
.byte $18,$15,$00,$19,%00000000 ; 3: up / right
|
|
.byte $1B,$00,$16,$1A,%00000000 ; 4: down / left
|
|
.byte $00,$19,$1A,$17,%00000000 ; 5: down / right
|
|
.byte $1B,$00,$1B,$00,%00000000 ; 6: left
|
|
.byte $18,$18,$00,$00,%00000000 ; 7: up
|
|
.byte $00,$00,$1A,$1A,%00000000 ; 8: down
|
|
.byte $00,$19,$00,$19,%00000000 ; 9: right
|
|
.byte $10,$11,$12,$13,%00000010 ; A: grass top
|
|
.byte $12,$12,$12,$12,%00000010 ; B: grass bottom
|
|
.byte $14,$15,$16,$17,%00000001 ; C: Intangible full block
|
|
.byte $01,$01,$01,$01,%00000001 ; D: Intangible grey
|
|
.byte $1B,$00,$1B,$00,%00000000 ; E: Intangible left
|
|
.byte $00,$19,$00,$19,%00000000 ; F: Intangible right
|
|
|
|
example_palette:
|
|
.byte $0F,$00,$3D,$20 ; greyscale
|
|
.byte $0F,$3D,$30,$00 ; whitescale
|
|
.byte $0F,$09,$1A,$16 ; grass
|
|
.byte $0F,$15,$26,$37 ; bg0 purple/pink
|
|
.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
|
|
|
|
|
|
terrain:
|
|
; page pos struct
|
|
.byte $00, $00, $00
|
|
|
|
.segment "ZEROPAGE"
|
|
buttons: .res 1
|
|
|
|
player_pos_x: .res 1
|
|
player_nmt_x: .res 1
|
|
player_pos_y: .res 1
|
|
player_subpos_x: .res 1 ; XXXXYYYY | first 4 bits X subposition, last 4 bits Y
|
|
player_subpos_y: .res 1 ; XXXXYYYY | first 4 bits X subposition, last 4 bits Y
|
|
player_vel_x: .res 1 ; +PPPSSSS | first bit sign, next 3 pixels, last subpixels
|
|
player_vel_y: .res 1 ; in subpixels
|
|
|
|
player_status: .res 1 ; 76543210 | 0: facing (0 right, 1 left)
|
|
; | 1: nametable X
|
|
; | 2: nametable Y
|
|
; | 7: talking
|
|
horizontal_speed: .res 1
|
|
camera_speed: .res 1
|
|
|
|
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
|
|
var_wide1:.res 2
|
|
var_wide2:.res 2
|
|
|
|
jump_pressed_last_frame: .res 1
|
|
|
|
frame_counter: .res 1
|
|
last_frame_jumped: .res 1
|
|
last_frame_moving: .res 1
|
|
|
|
column_pattern_pointer: .res 2
|
|
tile_update_pos: .res 1
|
|
|
|
pointer: .res 2
|
|
|
|
.segment "BSS"
|
|
level: .res 240
|
|
level2: .res 240
|
|
room_buffer: .res 240
|
|
|
|
.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
|
|
|
|
jsr update_room_buffer
|
|
|
|
@loop:
|
|
lda $2002
|
|
lda frame_counter
|
|
clc
|
|
adc #1
|
|
sta frame_counter
|
|
|
|
jsr controller
|
|
jsr movement
|
|
jsr move_camera
|
|
|
|
@draw:
|
|
jsr draw_player
|
|
jsr ppu_update
|
|
|
|
jmp @loop
|
|
|
|
move_camera:
|
|
jmp @no
|
|
lda player_pos_x
|
|
clc
|
|
adc #240
|
|
cmp scroll_x
|
|
bmi :++
|
|
lda #1
|
|
clc
|
|
adc scroll_x
|
|
cmp scroll_x
|
|
sta scroll_x
|
|
bcs :+
|
|
lda scroll_nmt
|
|
eor #%00000001
|
|
sta scroll_nmt
|
|
:
|
|
:
|
|
rts
|
|
@no:
|
|
|
|
|
|
jsr btn_select
|
|
cmp #0
|
|
beq :+
|
|
lda #%11111111
|
|
sta camera_speed
|
|
jmp @end
|
|
:
|
|
|
|
jsr btn_start
|
|
cmp #0
|
|
beq :+
|
|
lda #1
|
|
sta camera_speed
|
|
:
|
|
@end:
|
|
|
|
|
|
jsr add_scroll_x
|
|
jsr check_column_update
|
|
rts
|
|
|
|
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
|
|
|
|
|
|
; RIGHT HALF LOGIC
|
|
; see if we can skip drawing the player because it's off screen
|
|
lda player_pos_x
|
|
sec
|
|
sbc scroll_x
|
|
cmp player_pos_x ; if underflow, nametable bits must be different to continue
|
|
beq @skip_bcs_right
|
|
bcs :+
|
|
@skip_bcs_right:
|
|
lda player_nmt_x
|
|
eor scroll_nmt
|
|
bne @hide_player_right
|
|
jmp :++
|
|
:
|
|
; if nothing, nametable bits must be same to continue
|
|
lda player_nmt_x
|
|
eor scroll_nmt
|
|
beq @hide_player_right
|
|
:
|
|
jmp @end_hide_player_right
|
|
|
|
@hide_player_right:
|
|
lda player_status
|
|
and #%00000001
|
|
cmp #0
|
|
bne :+
|
|
lda #250
|
|
sta oam + (4 * 1) + 0
|
|
sta oam + (4 * 3) + 0
|
|
jmp :++
|
|
:
|
|
lda #250
|
|
sta oam + (4 * 0) + 0
|
|
sta oam + (4 * 2) + 0
|
|
:
|
|
|
|
@end_hide_player_right:
|
|
|
|
; LEFT HALF LOGIC
|
|
; store what nametable the player's left half is on in var_n
|
|
; store what position the player's left half is at in var_p
|
|
lda player_pos_x
|
|
sec
|
|
sbc #8
|
|
sta var_p
|
|
bcs :+
|
|
lda player_nmt_x
|
|
eor #%00000001
|
|
sta var_n
|
|
jmp :++
|
|
:
|
|
lda player_nmt_x
|
|
sta var_n
|
|
:
|
|
|
|
lda var_p
|
|
sec
|
|
sbc scroll_x
|
|
cmp var_p ; if underflow, nametable bits must be different to continue
|
|
beq @skip_bcs_left
|
|
bcs :+
|
|
@skip_bcs_left:
|
|
lda var_n
|
|
eor scroll_nmt
|
|
bne @hide_player_left
|
|
jmp :++
|
|
:
|
|
; if nothing, nametable bits must be same to continue
|
|
lda var_n
|
|
eor scroll_nmt
|
|
beq @hide_player_left
|
|
:
|
|
jmp @end_hide_player_left
|
|
|
|
@hide_player_left:
|
|
lda player_status
|
|
and #%00000001
|
|
cmp #0
|
|
bne :+
|
|
lda #250
|
|
sta oam + (4 * 0) + 0
|
|
sta oam + (4 * 2) + 0
|
|
jmp :++
|
|
:
|
|
lda #250
|
|
sta oam + (4 * 1) + 0
|
|
sta oam + (4 * 3) + 0
|
|
:
|
|
|
|
@end_hide_player_left:
|
|
|
|
lda player_status
|
|
and #%00000001
|
|
cmp #0
|
|
bne :+
|
|
lda player_pos_x
|
|
sec
|
|
sbc scroll_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
|
|
sec
|
|
sbc scroll_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 #96
|
|
sta player_pos_x ; Set X position
|
|
lda #128
|
|
sta player_pos_y ; Set Y position
|
|
|
|
lda #0
|
|
sta player_vel_x
|
|
sta player_vel_y
|
|
sta player_status
|
|
sta scroll_nmt
|
|
sta player_nmt_x
|
|
|
|
lda #%00101000
|
|
sta horizontal_speed
|
|
|
|
lda #0
|
|
sta camera_speed
|
|
sta tile_update_pos
|
|
|
|
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 horizontal_speed
|
|
sta player_vel_x
|
|
|
|
lda player_status
|
|
and #%11111110
|
|
sta player_status
|
|
|
|
lda frame_counter
|
|
sta last_frame_moving
|
|
:
|
|
|
|
jsr btn_left
|
|
cmp #0
|
|
beq :+
|
|
ldx #1
|
|
lda horizontal_speed
|
|
eor #%11111111
|
|
clc
|
|
adc #1
|
|
sta player_vel_x
|
|
|
|
lda player_status
|
|
ora #%00000001
|
|
sta player_status
|
|
|
|
lda frame_counter
|
|
sta last_frame_moving
|
|
:
|
|
|
|
cpx #1 ; skip decay if right or left pressed
|
|
beq @end
|
|
lda frame_counter
|
|
clc
|
|
sbc last_frame_moving
|
|
and #3
|
|
cmp #0
|
|
bne @end
|
|
|
|
lda player_vel_x
|
|
and #%01111111
|
|
cmp #0
|
|
beq @end ; If player_vel_x = 0, skip decay
|
|
|
|
lda player_vel_x
|
|
and #%10000000
|
|
; If player_vel_x positive, decrement
|
|
bne :++
|
|
lda player_vel_x
|
|
sec
|
|
sbc #16
|
|
sta player_vel_x
|
|
cmp #0
|
|
bpl :+
|
|
; negative, clamp to 0
|
|
lda #0
|
|
sta player_vel_x
|
|
:
|
|
jmp @end
|
|
:
|
|
; Else if player_vel_x < 0, increment
|
|
lda player_vel_x
|
|
clc
|
|
adc #16
|
|
sta player_vel_x
|
|
cmp #0
|
|
beq :+
|
|
bmi :+
|
|
; positive, clamp to 0
|
|
lda #0
|
|
sta 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
|
|
; Position
|
|
lda player_vel_x
|
|
and #%10000000
|
|
cmp #0
|
|
bne :+
|
|
; 0: right
|
|
lda player_vel_x
|
|
sta var_o ; store initial velocity in o
|
|
and #%01111111
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
ror
|
|
clc
|
|
adc player_pos_x
|
|
sta player_pos_x ; add pixels
|
|
bcc @end_pixel_overflow_right
|
|
lda player_nmt_x
|
|
eor #%00000001
|
|
sta player_nmt_x
|
|
@end_pixel_overflow_right:
|
|
|
|
|
|
lda player_vel_x
|
|
; A contains signed subpixels
|
|
|
|
clc
|
|
adc player_subpos_x ; add subposition and velocity subpixels
|
|
and #%00001111
|
|
cmp player_subpos_x ; if A (result) is less than current subpos, overflow occurred
|
|
sta player_subpos_x
|
|
beq @end_add_subpos
|
|
bcs @end_add_subpos ; so skip if subpos is smaller than result
|
|
lda player_pos_x
|
|
clc
|
|
adc #1
|
|
sta player_pos_x
|
|
bcc @end_subpixel_overflow_right
|
|
lda player_nmt_x
|
|
eor #%00000001
|
|
sta player_nmt_x
|
|
@end_subpixel_overflow_right:
|
|
@end_add_subpos:
|
|
|
|
jmp :++
|
|
:
|
|
; 1: left
|
|
lda player_vel_x
|
|
sta var_o
|
|
sec
|
|
ror
|
|
sec
|
|
ror
|
|
sec
|
|
ror
|
|
sec
|
|
ror
|
|
ora #%10000000
|
|
clc
|
|
adc player_pos_x
|
|
sta player_pos_x ; add pixels
|
|
bcs @end_pixel_overflow_left
|
|
lda player_nmt_x
|
|
eor #%00000001
|
|
sta player_nmt_x
|
|
@end_pixel_overflow_left:
|
|
; :|
|
|
lda player_pos_x
|
|
clc
|
|
adc #1
|
|
sta player_pos_x ; add... correction?
|
|
bcc @end_correction
|
|
lda player_nmt_x
|
|
eor #%00000001
|
|
sta player_nmt_x
|
|
@end_correction:
|
|
|
|
|
|
lda player_vel_x
|
|
; A contains signed subpixels
|
|
|
|
clc
|
|
adc player_subpos_x ; add subposition and velocity subpixels
|
|
and #%00001111
|
|
cmp player_subpos_x ; if A (result) is greater than current subpos, underflow occurred
|
|
sta player_subpos_x
|
|
beq @end_sub_subpos
|
|
bcc @end_sub_subpos ; so skip if subpos is bigger than result
|
|
lda player_pos_x
|
|
sec
|
|
sbc #1
|
|
sta player_pos_x
|
|
bcs @end_subpixel_overflow_left
|
|
lda player_nmt_x
|
|
eor #%00000001
|
|
sta player_nmt_x
|
|
@end_subpixel_overflow_left:
|
|
@end_sub_subpos:
|
|
:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; 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
|
|
|
|
setup_background:
|
|
ldx #0
|
|
:
|
|
lda default_level, X
|
|
sta level, X
|
|
|
|
inx
|
|
cpx #240
|
|
bne :-
|
|
|
|
ldx #0
|
|
:
|
|
lda default_level2, X
|
|
sta level2, X
|
|
|
|
inx
|
|
cpx #240
|
|
bne :-
|
|
|
|
ldx #0
|
|
:
|
|
lda default_level, X
|
|
sta level, X
|
|
|
|
inx
|
|
cpx #240
|
|
bne :-
|
|
|
|
ldx #0
|
|
:
|
|
lda default_level2, X
|
|
sta level2, X
|
|
|
|
inx
|
|
cpx #240
|
|
bne :-
|
|
|
|
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 :--
|
|
|
|
; ------------- Nametable 1: level
|
|
lda $2002
|
|
lda #$20
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
ldy #0
|
|
@row_start_nmt1:
|
|
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
|
|
and #%01111111
|
|
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
|
|
and #%01111111
|
|
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_nmt1
|
|
|
|
; clear attributes
|
|
;lda #0
|
|
;ldx #64 ; 64 bytes
|
|
;:
|
|
; lda #%11100100
|
|
;
|
|
; sta $2007
|
|
; dex
|
|
; bne :-
|
|
|
|
lda #0
|
|
sta $50
|
|
|
|
ldy #0
|
|
:
|
|
tya
|
|
pha
|
|
|
|
ldx #0
|
|
:
|
|
tya
|
|
pha
|
|
txa
|
|
pha
|
|
|
|
tya
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sta temp_y
|
|
|
|
txa
|
|
asl
|
|
|
|
clc
|
|
adc temp_y
|
|
|
|
tax
|
|
|
|
lda level, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
sta temp_x
|
|
|
|
lda level+1, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
adc temp_x
|
|
sta temp_x
|
|
|
|
lda level+16, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
adc temp_x
|
|
sta temp_x
|
|
|
|
lda level+17, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
adc temp_x
|
|
sta $2007
|
|
|
|
ldx $50
|
|
inx
|
|
stx $50
|
|
|
|
sta $60, X
|
|
|
|
pla
|
|
tax
|
|
pla
|
|
tay
|
|
inx
|
|
cpx #8
|
|
beq @left_jump
|
|
jmp :-
|
|
@left_jump:
|
|
|
|
pla
|
|
tay
|
|
iny
|
|
cpy #8
|
|
beq :+
|
|
jmp :--
|
|
:
|
|
; ---------------- End nametable 1: Level
|
|
; ---------------- Begin nametable 2: Level 2
|
|
lda $2002
|
|
lda #$24
|
|
sta $2006
|
|
lda #$00
|
|
sta $2006
|
|
ldy #0
|
|
@row_start_nmt2:
|
|
ldx #0
|
|
:
|
|
txa
|
|
pha
|
|
|
|
; index is (Y * 16) + X
|
|
stx temp_x
|
|
lda #16
|
|
jsr mul_y
|
|
clc
|
|
adc temp_x
|
|
tax
|
|
|
|
lda level2, X
|
|
and #%01111111
|
|
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 level2, X
|
|
and #%01111111
|
|
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_nmt2
|
|
|
|
|
|
; clear attributes
|
|
;lda #0
|
|
;ldx #64 ; 64 bytes
|
|
;:
|
|
; lda #%11100100
|
|
;
|
|
; sta $2007
|
|
; dex
|
|
; bne :-
|
|
|
|
lda #0
|
|
sta $50
|
|
|
|
ldy #0
|
|
:
|
|
tya
|
|
pha
|
|
|
|
ldx #0
|
|
:
|
|
tya
|
|
pha
|
|
txa
|
|
pha
|
|
|
|
tya
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
sta temp_y
|
|
|
|
txa
|
|
asl
|
|
|
|
clc
|
|
adc temp_y
|
|
|
|
tax
|
|
|
|
lda level2, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
sta temp_x
|
|
|
|
lda level2+1, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
adc temp_x
|
|
sta temp_x
|
|
|
|
lda level2+16, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
adc temp_x
|
|
sta temp_x
|
|
|
|
lda level2+17, X
|
|
and #%01111111
|
|
tay
|
|
lda #5
|
|
jsr mul_y
|
|
tay
|
|
lda metatiles+4, Y
|
|
and #%00000011
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
asl
|
|
adc temp_x
|
|
sta $2007
|
|
|
|
ldx $50
|
|
inx
|
|
stx $50
|
|
|
|
sta $60, X
|
|
|
|
pla
|
|
tax
|
|
pla
|
|
tay
|
|
inx
|
|
cpx #8
|
|
beq @right_jump
|
|
jmp :-
|
|
@right_jump:
|
|
|
|
pla
|
|
tay
|
|
iny
|
|
cpy #8
|
|
beq :+
|
|
jmp :--
|
|
:
|
|
|
|
rts
|
|
|
|
add_scroll_x:
|
|
lda camera_speed
|
|
bmi @left
|
|
clc
|
|
adc scroll_x
|
|
cmp scroll_x
|
|
sta scroll_x
|
|
bcs :+
|
|
lda scroll_nmt
|
|
eor #%00000001
|
|
sta scroll_nmt
|
|
ldx scroll_page
|
|
inx
|
|
sta scroll_page
|
|
:
|
|
rts
|
|
@left:
|
|
clc
|
|
adc scroll_x
|
|
cmp scroll_x
|
|
sta scroll_x
|
|
bcc :+
|
|
lda scroll_nmt
|
|
eor #%00000001
|
|
sta scroll_nmt
|
|
ldx scroll_page
|
|
dex
|
|
sta scroll_page
|
|
:
|
|
rts
|
|
|
|
check_column_update:
|
|
clc
|
|
lda scroll_nmt
|
|
beq :+
|
|
sec
|
|
:
|
|
|
|
lda scroll_x
|
|
ror
|
|
lsr
|
|
lsr
|
|
lsr
|
|
|
|
|
|
; Thought: Level layout will be decoded from somewhere into the room_buffer_r or _l buffers, then they will be indexed into by this to load their column patterns
|
|
|
|
cmp tile_update_pos
|
|
bne :+
|
|
jsr load_column_pattern
|
|
|
|
; Apply pattern
|
|
jsr update_nmt_column
|
|
|
|
; Increment tile_update_pos
|
|
lda tile_update_pos
|
|
clc
|
|
adc #1
|
|
and #%00011111
|
|
sta tile_update_pos
|
|
:
|
|
|
|
rts
|
|
|
|
load_column_pattern:
|
|
; Based on tile update pos r, use that row to index in to the room buffer. Columns in the room buffer are stored as rows for sequential access.
|
|
;
|
|
; IDEA: Do we only need one tile update position? If for example we're going right and updating there, we don't need to do anything going left until that point is reached again on the left side. But it's the same point. It's the "seam" in the level. Maybe just an offset by one or something.
|
|
lda #<room_buffer
|
|
sta column_pattern_pointer
|
|
lda #>room_buffer
|
|
sta column_pattern_pointer+1
|
|
|
|
; Since column pattern pointer points to the current column we need to draw, we start it at the beginning of the room buffer (which stores columns as rows), then we add 16 (going to the next "row" in memory which is the next column in reality) how many ever times in column_pattern_pointer to point to the correct row. From there, anything can just loop 16 times from that pointer to get the currently drawing row.
|
|
lda tile_update_pos
|
|
and #%00001111
|
|
tax
|
|
:
|
|
lda column_pattern_pointer
|
|
clc
|
|
adc #16
|
|
sta column_pattern_pointer
|
|
lda column_pattern_pointer+1
|
|
adc #0
|
|
sta column_pattern_pointer+1
|
|
|
|
dex
|
|
cpx #0
|
|
bne :-
|
|
rts
|
|
|
|
update_nmt_column:
|
|
; X represents the row of the current tile being updated
|
|
ldx #0
|
|
@row_loop:
|
|
lda tile_update_pos
|
|
clc
|
|
; Add offset in tiles from left edge of screen
|
|
adc #16
|
|
sta var_n
|
|
|
|
; Nametable base
|
|
lda #$20
|
|
sta var_o
|
|
|
|
lda #<level
|
|
sta pointer
|
|
lda #>level
|
|
sta pointer+1
|
|
|
|
|
|
lda var_n
|
|
and #%00010000
|
|
cmp #0
|
|
beq:+
|
|
lda pointer
|
|
clc
|
|
adc #240
|
|
sta pointer
|
|
|
|
lda pointer+1
|
|
adc #0
|
|
sta pointer+1
|
|
|
|
lda #$24
|
|
sta var_o
|
|
:
|
|
|
|
lda var_n
|
|
and #%00001111
|
|
sta var_p
|
|
|
|
|
|
lda #16
|
|
jsr mul_x
|
|
clc
|
|
adc var_p
|
|
tay
|
|
|
|
|
|
; Specifies what tile gets written to the column
|
|
;
|
|
; T------>
|
|
;lda column_pattern
|
|
;ror
|
|
;sta var_wide1
|
|
; >-----BX
|
|
;lda column_pattern+1
|
|
;ror
|
|
;sta var_wide1+1
|
|
|
|
;stx var_m
|
|
;:
|
|
;lda var_wide1+1
|
|
;rol
|
|
;sta var_wide1+1
|
|
;lda var_wide1
|
|
;rol
|
|
;sta var_wide1
|
|
;dec var_m
|
|
;bpl :-
|
|
|
|
;lda var_wide1
|
|
;and #%10000000
|
|
;cmp #0
|
|
;beq :+
|
|
; What metatile do we load for a non-empty shape?
|
|
;lda #%10000001
|
|
;:
|
|
|
|
; Preserve Y (our index in to level)
|
|
tya
|
|
pha
|
|
|
|
; Transfer X to Y (our current row in the updated column)
|
|
txa
|
|
tay
|
|
|
|
; Instead of all that nonsense constructing the tile that we want to draw, just index in to the column_pattern_pointer
|
|
; Storing in var wide 1 because I know it's not used
|
|
lda (column_pattern_pointer), Y
|
|
sta var_wide1
|
|
|
|
; Restore Y
|
|
pla
|
|
tay
|
|
; Write our new metatile to level (for collision mostly)
|
|
lda var_wide1
|
|
sta (pointer), Y
|
|
|
|
; ...and actually perform a nametable update
|
|
and #%01111111
|
|
ldy #5
|
|
jsr mul_y
|
|
tay
|
|
|
|
|
|
; Preserve X
|
|
txa
|
|
pha
|
|
|
|
lda #6
|
|
jsr mul_x
|
|
tax
|
|
|
|
lda metatiles+0, Y
|
|
sta nmt_update+2, X
|
|
lda metatiles+1, Y
|
|
sta nmt_update+3, X
|
|
lda metatiles+2, Y
|
|
sta nmt_update+4, X
|
|
lda metatiles+3, Y
|
|
sta nmt_update+5, X
|
|
|
|
|
|
; Recover X (to Y)
|
|
pla
|
|
tay
|
|
|
|
lsr
|
|
lsr
|
|
; Add nametable base
|
|
clc
|
|
adc var_o
|
|
sta nmt_update+0, X
|
|
|
|
lda #64
|
|
jsr mul_y
|
|
clc
|
|
adc var_p
|
|
clc
|
|
adc var_p
|
|
sta nmt_update+1, X
|
|
|
|
|
|
|
|
tya
|
|
tax
|
|
|
|
inx
|
|
cpx #15
|
|
beq :+
|
|
jmp @row_loop
|
|
:
|
|
|
|
|
|
lda #15
|
|
sta nmt_update_len
|
|
|
|
rts
|
|
|
|
update_room_buffer:
|
|
ldx #0
|
|
:
|
|
lda default_level2, X
|
|
sta room_buffer, X
|
|
inx
|
|
cpx #240
|
|
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 #5
|
|
jmp :++
|
|
:
|
|
clc
|
|
adc #4
|
|
:
|
|
; 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 player_nmt_x
|
|
cmp #0
|
|
beq :+
|
|
lda level2, X
|
|
jmp :++
|
|
:
|
|
lda level, X
|
|
:
|
|
and #%10000000
|
|
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 #5
|
|
jmp :++
|
|
:
|
|
clc
|
|
adc #4
|
|
:
|
|
; 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 player_nmt_x
|
|
cmp #0
|
|
beq :+
|
|
lda level2, X
|
|
jmp :++
|
|
:
|
|
lda level, X
|
|
:
|
|
and #%10000000
|
|
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 player_nmt_x
|
|
cmp #0
|
|
beq :+
|
|
lda level2, X
|
|
jmp :++
|
|
:
|
|
lda level, X
|
|
:
|
|
and #%10000000
|
|
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 player_nmt_x
|
|
cmp #0
|
|
beq :+
|
|
lda level2, X
|
|
jmp :++
|
|
:
|
|
lda level, X
|
|
:
|
|
and #%10000000
|
|
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
|
|
|