Files
nes/plat.s

2143 lines
37 KiB
ArmAsm
Raw Normal View History

2026-02-14 18:08:10 -05:00
.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
2026-02-17 09:53:46 -05:00
lda #0
2026-02-14 18:08:10 -05:00
sta $2000
2026-02-16 00:27:56 -05:00
lda #0
2026-02-14 18:08:10 -05:00
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 :-
2026-02-17 09:53:46 -05:00
lda #%10101000 ; NMI enable, 8x16 sprites, ignored due to 8x16 mode
2026-02-14 18:08:10 -05:00
sta $2000
jmp main
.segment "ZEROPAGE"
nmi_lock: .res 1
nmi_count: .res 1
nmi_ready: .res 1
nmt_update_len: .res 1
2026-03-16 22:01:56 -04:00
nmt_column: .res 1
2026-03-18 14:56:40 -04:00
nmt_update_frame: .res 1
2026-02-14 18:08:10 -05:00
scroll_x: .res 1
scroll_y: .res 1
scroll_nmt: .res 1
2026-03-16 22:01:56 -04:00
scroll_page: .res 1
2026-02-14 18:08:10 -05:00
temp: .res 1
2026-03-16 22:01:56 -04:00
PPUCTRL_default = %10101000
2026-02-14 18:08:10 -05:00
.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
2026-02-17 09:53:46 -05:00
lda #%10101000 ; NMI enable, 8x16 sprites, ignored due to 8x16 mode
2026-02-14 18:08:10 -05:00
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
2026-03-16 22:01:56 -04:00
lda PPUCTRL_default
;ora #%00000100
sta $2000
ldy #0
2026-03-18 14:56:40 -04:00
ldx #0
2026-02-14 18:08:10 -05:00
@nmt_update_loop:
2026-03-18 14:56:40 -04:00
lda nmt_update_frame
cmp #0
bne :+
lda nmt_update+0, X
sta $2006
lda nmt_update+1, X
sta $2006
2026-03-16 22:01:56 -04:00
2026-03-18 14:56:40 -04:00
lda nmt_update+2, X
sta $2007
lda nmt_update+3, X
sta $2007
2026-03-16 22:01:56 -04:00
2026-03-18 14:56:40 -04:00
jmp :++
:
lda nmt_update+0, X
sta $2006
lda nmt_update+1, X
clc
adc #32
sta $2006
2026-03-16 22:01:56 -04:00
2026-03-18 14:56:40 -04:00
lda nmt_update+4, X
sta $2007
lda nmt_update+5, X
sta $2007
:
2026-03-16 22:01:56 -04:00
2026-03-18 14:56:40 -04:00
inx
inx
inx
inx
inx
inx
2026-03-16 22:01:56 -04:00
iny
cpy nmt_update_len
2026-02-14 18:08:10 -05:00
bcc @nmt_update_loop
2026-03-16 22:01:56 -04:00
lda PPUCTRL_default
sta $2000
2026-03-18 14:56:40 -04:00
inc nmt_update_frame
lda nmt_update_frame
cmp #2
bne :+
lda #0
sta nmt_update_frame
sta nmt_update_len
:
2026-02-14 18:08:10 -05:00
@scroll:
lda scroll_nmt
and #%00000011
2026-02-17 09:53:46 -05:00
ora #%10101000
2026-02-14 18:08:10 -05:00
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"
2026-02-16 00:27:56 -05:00
2026-03-16 22:01:56 -04:00
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
2026-03-16 22:01:56 -04: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
2026-03-16 22:01:56 -04: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
2026-03-16 22:01:56 -04:00
.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:
2026-02-21 14:31:21 -05:00
;.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
2026-02-21 14:31:21 -05:00
;.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
2026-02-21 14:31:21 -05:00
;.byte 0,0,0,0,0,0,0,0,0,0,0,11,11,11,11,11
2026-02-19 14:04:29 -05:00
2026-02-16 20:33:50 -05:00
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
2026-02-16 20:33:50 -05:00
2026-02-14 18:08:10 -05:00
example_palette:
2026-02-16 00:27:56 -05:00
.byte $0F,$00,$3D,$20 ; greyscale
2026-02-18 15:04:42 -05:00
.byte $0F,$3D,$30,$00 ; whitescale
2026-02-16 00:27:56 -05:00
.byte $0F,$09,$1A,$16 ; grass
2026-02-14 18:08:10 -05:00
.byte $0F,$15,$26,$37 ; bg0 purple/pink
2026-02-17 11:19:51 -05:00
.byte $0F,$2D,$10,$3D ; reboot bottom
.byte $0F,$2D,$10,$2C ; reboot eye
2026-02-14 18:08:10 -05:00
.byte $0F,$01,$11,$21 ; bg2 blue
.byte $0F,$00,$10,$30 ; bg3 greyscale
2026-02-17 11:19:51 -05:00
; .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
2026-02-14 18:08:10 -05:00
2026-03-16 22:01:56 -04:00
terrain:
; page pos struct
.byte $00, $00, $00
2026-02-14 18:08:10 -05:00
.segment "ZEROPAGE"
2026-02-16 00:27:56 -05:00
buttons: .res 1
2026-02-17 09:26:32 -05:00
player_pos_x: .res 1
2026-02-19 16:52:08 -05:00
player_nmt_x: .res 1
2026-02-17 09:26:32 -05:00
player_pos_y: .res 1
2026-02-18 15:04:42 -05:00
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
2026-02-14 18:08:10 -05:00
2026-02-17 11:19:51 -05:00
player_status: .res 1 ; 76543210 | 0: facing (0 right, 1 left)
2026-02-19 16:52:08 -05:00
; | 1: nametable X
; | 2: nametable Y
2026-02-17 11:19:51 -05:00
; | 7: talking
2026-02-18 15:04:42 -05:00
horizontal_speed: .res 1
2026-02-21 16:40:26 -05:00
camera_speed: .res 1
2026-02-17 11:19:51 -05:00
2026-02-14 18:08:10 -05:00
cursor_x: .res 1
cursor_y: .res 1
temp_x: .res 1
temp_y: .res 1
2026-02-16 00:27:56 -05:00
temp_mul: .res 1
2026-02-14 18:08:10 -05:00
var_m: .res 1
var_n: .res 1
var_o: .res 1
var_p: .res 1
var_wide1:.res 2
var_wide2:.res 2
2026-02-14 18:08:10 -05:00
2026-02-16 20:33:50 -05:00
jump_pressed_last_frame: .res 1
2026-02-14 18:08:10 -05:00
frame_counter: .res 1
2026-02-17 22:52:47 -05:00
last_frame_jumped: .res 1
2026-02-18 16:56:16 -05:00
last_frame_moving: .res 1
2026-02-14 18:08:10 -05:00
column_pattern_pointer: .res 2
tile_update_pos: .res 1
2026-03-16 22:01:56 -04:00
2026-03-18 14:56:40 -04:00
pointer: .res 2
2026-03-16 22:01:56 -04:00
.segment "BSS"
level: .res 240
level2: .res 240
room_buffer: .res 240
2026-03-16 22:01:56 -04:00
2026-02-14 18:08:10 -05:00
.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
2026-02-17 22:52:47 -05:00
sta last_frame_jumped
2026-02-14 18:08:10 -05:00
jsr init_objects
2026-02-18 15:04:42 -05:00
jsr update_room_buffer
2026-02-14 18:08:10 -05:00
@loop:
2026-02-18 15:04:42 -05:00
lda $2002
2026-02-14 18:08:10 -05:00
lda frame_counter
clc
adc #1
sta frame_counter
2026-02-16 00:27:56 -05:00
jsr controller
jsr movement
2026-02-21 14:31:21 -05:00
jsr move_camera
2026-02-16 00:27:56 -05:00
@draw:
2026-02-17 09:26:32 -05:00
jsr draw_player
2026-02-16 00:27:56 -05:00
jsr ppu_update
2026-02-14 18:08:10 -05:00
jmp @loop
2026-02-21 14:31:21 -05:00
move_camera:
2026-02-21 16:40:26 -05:00
jmp @no
lda player_pos_x
2026-02-21 14:31:21 -05:00
clc
2026-02-21 16:40:26 -05:00
adc #240
2026-02-21 14:31:21 -05:00
cmp scroll_x
2026-02-21 16:40:26 -05:00
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
2026-02-21 14:31:21 -05:00
:
2026-02-21 16:40:26 -05:00
@end:
2026-03-16 22:01:56 -04:00
jsr add_scroll_x
jsr check_column_update
2026-02-21 14:31:21 -05:00
rts
2026-02-19 16:52:08 -05:00
2026-02-21 14:31:21 -05:00
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
2026-02-19 16:52:08 -05:00
; 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
2026-02-19 16:52:08 -05:00
bcs :+
@skip_bcs_right:
2026-02-21 14:31:21 -05:00
lda player_nmt_x
2026-02-19 16:52:08 -05:00
eor scroll_nmt
bne @hide_player_right
2026-02-19 16:52:08 -05:00
jmp :++
:
; if nothing, nametable bits must be same to continue
2026-02-21 14:31:21 -05:00
lda player_nmt_x
2026-02-19 16:52:08 -05:00
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
2026-02-19 16:52:08 -05:00
:
@end_hide_player_right:
2026-02-19 16:52:08 -05:00
; 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
2026-02-21 14:31:21 -05:00
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
2026-02-21 14:31:21 -05:00
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:
2026-02-19 16:52:08 -05:00
2026-02-17 11:19:51 -05:00
lda player_status
and #%00000001
cmp #0
bne :+
lda player_pos_x
2026-02-19 13:07:55 -05:00
sec
sbc scroll_x
2026-02-17 11:19:51 -05:00
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
2026-02-19 13:07:55 -05:00
sec
sbc scroll_x
2026-02-17 11:19:51 -05:00
sta oam + (4 * 0) + 3
sta oam + (4 * 2) + 3
sec
sbc #8
sta oam + (4 * 1) + 3
sta oam + (4 * 3) + 3
:
2026-02-19 16:52:08 -05:00
2026-02-17 11:19:51 -05:00
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
2026-02-17 09:26:32 -05:00
rts
2026-02-14 18:08:10 -05:00
init_objects:
2026-02-21 16:40:26 -05:00
lda #96
sta player_pos_x ; Set X position
lda #128
sta player_pos_y ; Set Y position
2026-02-14 18:08:10 -05:00
2026-02-16 00:27:56 -05:00
lda #0
2026-02-17 09:26:32 -05:00
sta player_vel_x
sta player_vel_y
2026-02-17 11:19:51 -05:00
sta player_status
2026-02-21 16:40:26 -05:00
sta scroll_nmt
sta player_nmt_x
2026-02-16 00:27:56 -05:00
2026-02-18 20:02:49 -05:00
lda #%00101000
2026-02-18 15:04:42 -05:00
sta horizontal_speed
2026-02-17 22:52:47 -05:00
2026-02-21 16:40:26 -05:00
lda #0
sta camera_speed
sta tile_update_pos
2026-02-21 16:40:26 -05:00
2026-02-14 18:08:10 -05:00
rts
draw:
2026-02-16 00:27:56 -05:00
@end:
rts
2026-02-14 18:08:10 -05:00
2026-02-16 00:27:56 -05:00
movement:
2026-02-17 11:19:51 -05:00
; 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
:
2026-02-16 00:27:56 -05:00
; Horizontal velocity
2026-02-14 18:08:10 -05:00
ldx #0
2026-02-16 00:27:56 -05:00
jsr btn_right
cmp #0
beq :+
ldx #1
2026-02-18 15:04:42 -05:00
lda horizontal_speed
2026-02-17 09:26:32 -05:00
sta player_vel_x
2026-02-17 11:19:51 -05:00
lda player_status
and #%11111110
sta player_status
2026-02-18 16:56:16 -05:00
lda frame_counter
sta last_frame_moving
2026-02-16 00:27:56 -05:00
:
jsr btn_left
cmp #0
beq :+
ldx #1
2026-02-18 15:04:42 -05:00
lda horizontal_speed
2026-02-18 16:56:16 -05:00
eor #%11111111
clc
adc #1
2026-02-17 09:26:32 -05:00
sta player_vel_x
2026-02-17 11:19:51 -05:00
lda player_status
ora #%00000001
sta player_status
2026-02-18 16:56:16 -05:00
lda frame_counter
sta last_frame_moving
2026-02-16 00:27:56 -05:00
:
2026-02-18 16:56:16 -05:00
cpx #1 ; skip decay if right or left pressed
2026-02-16 00:27:56 -05:00
beq @end
lda frame_counter
2026-02-18 16:56:16 -05:00
clc
sbc last_frame_moving
and #3
2026-02-16 00:27:56 -05:00
cmp #0
bne @end
2026-02-18 16:56:16 -05:00
lda player_vel_x
and #%01111111
cmp #0
2026-02-17 09:26:32 -05:00
beq @end ; If player_vel_x = 0, skip decay
2026-02-16 00:27:56 -05:00
2026-02-18 16:56:16 -05:00
lda player_vel_x
and #%10000000
; If player_vel_x positive, decrement
2026-02-18 20:02:49 -05:00
bne :++
2026-02-18 15:04:42 -05:00
lda player_vel_x
sec
sbc #16
2026-02-18 16:56:16 -05:00
sta player_vel_x
2026-02-18 20:02:49 -05:00
cmp #0
bpl :+
; negative, clamp to 0
lda #0
sta player_vel_x
:
2026-02-16 00:27:56 -05:00
jmp @end
:
2026-02-17 09:26:32 -05:00
; Else if player_vel_x < 0, increment
2026-02-18 15:04:42 -05:00
lda player_vel_x
clc
adc #16
sta player_vel_x
2026-02-18 20:02:49 -05:00
cmp #0
beq :+
bmi :+
; positive, clamp to 0
lda #0
sta player_vel_x
:
2026-02-16 00:27:56 -05:00
@end:
2026-02-19 16:52:08 -05:00
2026-02-16 00:27:56 -05:00
; Jump
2026-02-16 20:33:50 -05:00
jsr btn_a
2026-02-16 00:27:56 -05:00
cmp #0
2026-02-16 20:33:50 -05:00
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
2026-02-17 22:52:47 -05:00
lda #249
2026-02-17 09:26:32 -05:00
sta player_vel_y
2026-02-16 20:33:50 -05:00
2026-02-17 22:52:47 -05:00
lda frame_counter
sta last_frame_jumped
2026-02-16 20:33:50 -05:00
@fail_jump:
jsr btn_a
sta jump_pressed_last_frame
2026-02-16 00:27:56 -05:00
; Gravity
lda frame_counter
2026-02-17 22:52:47 -05:00
sec
sbc last_frame_jumped
and #%00000001
2026-02-16 00:27:56 -05:00
cmp #0
bne :+
2026-02-17 09:26:32 -05:00
lda player_vel_y
2026-02-14 18:08:10 -05:00
clc
adc #1 ; Add 2 to velocity
2026-02-17 09:26:32 -05:00
sta player_vel_y
2026-02-16 00:27:56 -05:00
:
2026-02-14 18:08:10 -05:00
2026-02-16 00:27:56 -05:00
; Apply Y velocity
2026-02-17 09:26:32 -05:00
lda player_pos_y
2026-02-16 00:27:56 -05:00
clc
2026-02-17 09:26:32 -05:00
adc player_vel_y
sta player_pos_y
2026-02-14 18:08:10 -05:00
2026-02-17 22:52:47 -05:00
; Apply X velocity
2026-02-18 15:04:42 -05:00
; Position
lda player_vel_x
and #%10000000
cmp #0
bne :+
; 0: right
lda player_vel_x
2026-02-21 14:31:21 -05:00
sta var_o ; store initial velocity in o
2026-02-18 16:56:16 -05:00
and #%01111111
2026-02-18 15:04:42 -05:00
clc
ror
clc
ror
clc
ror
clc
ror
2026-02-18 16:56:16 -05:00
clc
adc player_pos_x
sta player_pos_x ; add pixels
2026-02-21 14:31:21 -05:00
bcc @end_pixel_overflow_right
lda player_nmt_x
eor #%00000001
sta player_nmt_x
@end_pixel_overflow_right:
2026-02-18 15:04:42 -05:00
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
2026-02-18 20:02:49 -05:00
sta player_subpos_x
beq @end_add_subpos
bcs @end_add_subpos ; so skip if subpos is smaller than result
2026-02-21 14:31:21 -05:00
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:
2026-02-18 15:04:42 -05:00
@end_add_subpos:
jmp :++
:
; 1: left
lda player_vel_x
2026-02-21 14:31:21 -05:00
sta var_o
2026-02-18 16:56:16 -05:00
sec
2026-02-18 15:04:42 -05:00
ror
2026-02-18 16:56:16 -05:00
sec
2026-02-18 15:04:42 -05:00
ror
2026-02-18 16:56:16 -05:00
sec
2026-02-18 15:04:42 -05:00
ror
2026-02-18 16:56:16 -05:00
sec
2026-02-18 15:04:42 -05:00
ror
2026-02-18 16:56:16 -05:00
ora #%10000000
2026-02-18 20:02:49 -05:00
clc
2026-02-18 16:56:16 -05:00
adc player_pos_x
sta player_pos_x ; add pixels
2026-02-21 14:31:21 -05:00
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:
2026-02-18 16:56:16 -05:00
2026-02-18 15:04:42 -05:00
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
2026-02-18 20:02:49 -05:00
sta player_subpos_x
beq @end_sub_subpos
bcc @end_sub_subpos ; so skip if subpos is bigger than result
2026-02-21 14:31:21 -05:00
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:
2026-02-18 15:04:42 -05:00
@end_sub_subpos:
:
2026-02-21 14:31:21 -05:00
2026-02-17 22:52:47 -05:00
; 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
2026-02-16 00:27:56 -05:00
; Keep grounded
cmp #200
bcc :+
lda #0
2026-02-17 09:26:32 -05:00
sta player_vel_y
2026-02-16 00:27:56 -05:00
lda #200
2026-02-17 09:26:32 -05:00
sta player_pos_y
2026-02-16 00:27:56 -05:00
:
2026-02-16 20:33:50 -05:00
; Bonk
lda #8
2026-02-17 09:26:32 -05:00
cmp player_pos_y
2026-02-16 20:33:50 -05:00
bcc :+
lda #0
2026-02-17 09:26:32 -05:00
sta player_vel_y
2026-02-16 20:33:50 -05:00
lda #8
2026-02-17 09:26:32 -05:00
sta player_pos_y
2026-02-16 20:33:50 -05:00
:
2026-02-16 00:27:56 -05:00
rts
2026-02-14 18:08:10 -05:00
setup_background:
2026-03-16 22:01:56 -04:00
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 :-
2026-02-16 20:33:50 -05:00
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 :--
2026-02-19 14:04:29 -05:00
; ------------- Nametable 1: level
2026-02-16 20:33:50 -05:00
lda $2002
2026-02-19 14:04:29 -05:00
lda #$20
2026-02-16 20:33:50 -05:00
sta $2006
lda #$00
sta $2006
ldy #0
2026-02-19 14:04:29 -05:00
@row_start_nmt1:
2026-02-16 20:33:50 -05:00
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
2026-02-16 20:33:50 -05:00
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
2026-02-16 20:33:50 -05:00
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
2026-02-19 14:04:29 -05:00
bne @row_start_nmt1
2026-02-16 20:33:50 -05:00
; clear attributes
2026-02-18 15:04:42 -05:00
;lda #0
;ldx #64 ; 64 bytes
;:
; lda #%11100100
;
; sta $2007
; dex
; bne :-
2026-02-16 20:33:50 -05:00
lda #0
2026-02-18 15:04:42 -05:00
sta $50
2026-02-16 20:33:50 -05:00
2026-02-18 15:04:42 -05:00
ldy #0
:
tya
pha
2026-02-16 20:33:50 -05:00
2026-02-18 15:04:42 -05:00
ldx #0
:
tya
pha
txa
pha
2026-02-16 20:33:50 -05:00
2026-02-18 15:04:42 -05:00
tya
asl
asl
asl
asl
asl
sta temp_y
2026-02-16 20:33:50 -05:00
2026-02-18 15:04:42 -05:00
txa
asl
2026-02-16 20:33:50 -05:00
2026-02-18 15:04:42 -05:00
clc
adc temp_y
2026-02-16 00:27:56 -05:00
2026-02-18 15:04:42 -05:00
tax
2026-02-16 00:27:56 -05:00
2026-02-18 15:04:42 -05:00
lda level, X
and #%01111111
2026-02-18 15:04:42 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-18 15:04:42 -05:00
sta temp_x
2026-02-16 00:27:56 -05:00
2026-02-18 15:04:42 -05:00
lda level+1, X
and #%01111111
2026-02-18 15:04:42 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-18 15:04:42 -05:00
asl
asl
adc temp_x
sta temp_x
2026-02-16 00:27:56 -05:00
2026-02-18 15:04:42 -05:00
lda level+16, X
and #%01111111
2026-02-18 15:04:42 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-18 15:04:42 -05:00
asl
asl
asl
asl
adc temp_x
sta temp_x
2026-02-16 00:27:56 -05:00
2026-02-18 15:04:42 -05:00
lda level+17, X
and #%01111111
2026-02-18 15:04:42 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-18 15:04:42 -05:00
asl
asl
asl
asl
asl
asl
adc temp_x
sta $2007
2026-02-16 00:27:56 -05:00
2026-02-18 15:04:42 -05:00
ldx $50
inx
stx $50
2026-02-14 18:08:10 -05:00
2026-02-18 15:04:42 -05:00
sta $60, X
2026-02-14 18:08:10 -05:00
2026-02-18 15:04:42 -05:00
pla
tax
pla
tay
inx
cpx #8
beq @left_jump
jmp :-
@left_jump:
2026-02-14 18:08:10 -05:00
2026-02-18 15:04:42 -05:00
pla
tay
iny
cpy #8
beq :+
jmp :--
:
2026-02-19 14:04:29 -05:00
; ---------------- 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
2026-02-14 18:08:10 -05:00
2026-02-19 14:04:29 -05:00
; index is (Y * 16) + X
stx temp_x
lda #16
jsr mul_y
clc
adc temp_x
tax
lda level2, X
and #%01111111
2026-02-19 14:04:29 -05:00
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
2026-02-19 14:04:29 -05:00
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
2026-02-19 13:07:55 -05:00
:
2026-02-19 14:04:29 -05:00
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
2026-02-19 14:04:29 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-19 14:04:29 -05:00
sta temp_x
lda level2+1, X
and #%01111111
2026-02-19 14:04:29 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-19 14:04:29 -05:00
asl
asl
adc temp_x
sta temp_x
lda level2+16, X
and #%01111111
2026-02-19 14:04:29 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-19 14:04:29 -05:00
asl
asl
asl
asl
adc temp_x
sta temp_x
lda level2+17, X
and #%01111111
2026-02-19 14:04:29 -05:00
tay
lda #5
jsr mul_y
tay
lda metatiles+4, Y
and #%00000011
2026-02-19 14:04:29 -05:00
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:
2026-02-19 14:04:29 -05:00
pla
tay
iny
cpy #8
beq :+
jmp :--
:
2026-02-19 13:07:55 -05:00
2026-02-18 15:04:42 -05:00
rts
2026-02-14 18:08:10 -05:00
2026-03-16 22:01:56 -04:00
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
2026-03-16 22:01:56 -04:00
bne :+
jsr load_column_pattern
2026-03-18 20:47:38 -04:00
; Apply pattern
2026-03-16 22:01:56 -04:00
jsr update_nmt_column
2026-03-18 20:47:38 -04:00
; Increment tile_update_pos
lda tile_update_pos
2026-03-16 22:01:56 -04:00
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
2026-03-16 22:01:56 -04:00
:
lda column_pattern_pointer
clc
adc #16
sta column_pattern_pointer
lda column_pattern_pointer+1
adc #0
sta column_pattern_pointer+1
2026-03-16 22:01:56 -04:00
dex
cpx #0
bne :-
2026-03-16 22:01:56 -04:00
rts
update_nmt_column:
2026-03-18 14:56:40 -04:00
; X represents the row of the current tile being updated
2026-03-16 22:01:56 -04:00
ldx #0
2026-03-18 14:56:40 -04:00
@row_loop:
lda tile_update_pos
2026-03-18 14:56:40 -04:00
clc
2026-03-18 16:56:37 -04:00
; Add offset in tiles from left edge of screen
2026-03-18 20:47:38 -04:00
adc #16
2026-03-18 14:56:40 -04:00
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
2026-03-16 22:01:56 -04:00
lda #16
jsr mul_x
clc
2026-03-18 14:56:40 -04:00
adc var_p
2026-03-16 22:01:56 -04:00
tay
2026-03-18 20:47:38 -04:00
2026-03-18 14:56:40 -04:00
; 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
2026-03-18 20:47:38 -04:00
; 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
2026-03-18 14:56:40 -04:00
sta (pointer), Y
2026-03-16 22:01:56 -04:00
; ...and actually perform a nametable update
2026-03-16 22:01:56 -04:00
and #%01111111
ldy #5
jsr mul_y
tay
2026-03-18 14:56:40 -04:00
; Preserve X
2026-03-16 22:01:56 -04:00
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
2026-03-18 14:56:40 -04:00
; Recover X (to Y)
2026-03-16 22:01:56 -04:00
pla
tay
lsr
lsr
2026-03-18 14:56:40 -04:00
; Add nametable base
2026-03-16 22:01:56 -04:00
clc
2026-03-18 14:56:40 -04:00
adc var_o
2026-03-16 22:01:56 -04:00
sta nmt_update+0, X
lda #64
jsr mul_y
clc
2026-03-18 14:56:40 -04:00
adc var_p
2026-03-16 22:01:56 -04:00
clc
2026-03-18 14:56:40 -04:00
adc var_p
2026-03-16 22:01:56 -04:00
sta nmt_update+1, X
tya
tax
inx
cpx #15
2026-03-18 14:56:40 -04:00
beq :+
jmp @row_loop
:
2026-03-16 22:01:56 -04:00
2026-03-18 16:56:37 -04:00
lda #15
2026-03-16 22:01:56 -04:00
sta nmt_update_len
rts
update_room_buffer:
ldx #0
:
lda default_level2, X
sta room_buffer, X
inx
cpx #240
bne :-
rts
2026-02-16 00:27:56 -05:00
mul_x:
2026-02-16 20:33:50 -05:00
cmp #0
beq @zero
cpx #0
beq @zero
2026-02-16 00:27:56 -05:00
sta temp_mul
2026-02-16 20:33:50 -05:00
txa
pha
2026-02-16 00:27:56 -05:00
lda #0
:
clc
adc temp_mul
dex
bne :-
2026-02-16 20:33:50 -05:00
sta temp_mul
pla
tax
lda temp_mul
rts
@zero:
lda #0
2026-02-16 00:27:56 -05:00
rts
mul_y:
2026-02-16 20:33:50 -05:00
cmp #0
beq @zero
cpy #0
beq @zero
2026-02-16 00:27:56 -05:00
sta temp_mul
2026-02-16 20:33:50 -05:00
tya
pha
2026-02-16 00:27:56 -05:00
lda #0
:
clc
adc temp_mul
dey
bne :-
2026-02-16 20:33:50 -05:00
sta temp_mul
pla
tay
lda temp_mul
rts
@zero:
lda #0
2026-02-16 00:27:56 -05:00
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
2026-02-17 22:52:47 -05:00
downward_collision_check:
lda #0
sta var_n
@begin_check:
lda player_pos_x
ldx var_n
cpx #0
bne :+
sec
2026-02-18 20:02:49 -05:00
sbc #5
2026-02-17 22:52:47 -05:00
jmp :++
:
clc
2026-02-18 20:02:49 -05:00
adc #4
2026-02-17 22:52:47 -05:00
:
; 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
2026-02-17 22:52:47 -05:00
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
2026-02-18 20:02:49 -05:00
sbc #5
2026-02-17 22:52:47 -05:00
jmp :++
:
clc
2026-02-18 20:02:49 -05:00
adc #4
2026-02-17 22:52:47 -05:00
:
; 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
2026-02-17 22:52:47 -05:00
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
2026-02-17 22:52:47 -05:00
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
2026-02-17 22:52:47 -05:00
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