aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mssola@mssola.com>2025-12-10 14:41:35 +0100
committerMiquel Sabaté Solà <mssola@mssola.com>2025-12-15 15:31:06 +0100
commit74b1003ab8abad2f8220de4f2f18a3b118f23f01 (patch)
treeb7f2d491d708fa900d4dd9649eb5bd7fab3e8686
parente6d9bd9f7acfd0e40025b2d579a7faff0d04ef0a (diff)
downloadjetpac.nes-74b1003ab8abad2f8220de4f2f18a3b118f23f01.tar.gz
jetpac.nes-74b1003ab8abad2f8220de4f2f18a3b118f23f01.zip
Adapt the code to play well with nasm's asan
The address sanitizer from nasm provides quite a few goodies, so let's adapt the code more to it to benefit from those. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
-rw-r--r--include/apu.s4
-rw-r--r--include/globals.s10
-rw-r--r--include/joypad.s10
-rw-r--r--include/oam.s19
-rw-r--r--include/ppu.s12
-rw-r--r--src/assets.s70
-rw-r--r--src/bullets.s2
-rw-r--r--src/driver.s20
-rw-r--r--src/enemies.s2
-rw-r--r--src/jetpac.s8
-rw-r--r--src/player.s68
-rw-r--r--src/title.s24
-rw-r--r--src/vectors.s40
13 files changed, 145 insertions, 144 deletions
diff --git a/include/apu.s b/include/apu.s
index 65d9876..bb0319f 100644
--- a/include/apu.s
+++ b/include/apu.s
@@ -1,4 +1,4 @@
.scope APU
- DMC = $4010
- FRAME_COUNTER = $4017
+ m_dmc = $4010
+ m_frame_counter = $4017
.endscope
diff --git a/include/globals.s b/include/globals.s
index 842de34..f9777e5 100644
--- a/include/globals.s
+++ b/include/globals.s
@@ -6,17 +6,17 @@
;; Argument values reserved passing arguments to functions in memory.
zp_arg0 = $00
zp_arg1 = $01
- zp_arg2 = $02
- zp_arg3 = $03
- zp_arg4 = $04
+ ;; zp_arg2 = $02
+ ;; zp_arg3 = $03
+ ;; zp_arg4 = $04
;;;
;; Random values that can be used inside of functions for temporary values
;; so `zp_argX` variables are not overwritten as often.
zp_tmp0 = $05
zp_tmp1 = $06
- zp_tmp2 = $07
- zp_tmp3 = $08
+ ;; zp_tmp2 = $07
+ ;; zp_tmp3 = $08
;;;
;; Reserve a byte of memory for preserving indices on memory. This is needed
diff --git a/include/joypad.s b/include/joypad.s
index 141877f..f7268e8 100644
--- a/include/joypad.s
+++ b/include/joypad.s
@@ -10,8 +10,8 @@
BUTTON_RIGHT = 1 << 0
;; Port addresses for controllers.
- JOYPAD1 = $4016
- JOYPAD2 = $4017
+ m_joypad1 = $4016
+ ;; m_joypad2 = $4017
;; After running a `read_*` function these two variables will contain the
;; given result.
@@ -49,14 +49,14 @@
.proc unsafe_read_x
;; Start the latch process.
lda #$01
- sta Joypad::JOYPAD1
+ sta Joypad::m_joypad1
sta Joypad::zp_buttons1, x ; Bit as a guard for the loop below.
lsr
- sta Joypad::JOYPAD1
+ sta Joypad::m_joypad1
;; Now the joypad is ready to accept reads.
@loop:
- lda Joypad::JOYPAD1, x
+ lda Joypad::m_joypad1, x
and #%00000011 ; Ignore bits other than controller.
cmp #$01 ; Set carry if and only if nonzero.
rol Joypad::zp_buttons1, x ; Carry -> bit 0; bit 7 -> Carry
diff --git a/include/oam.s b/include/oam.s
index 22935b2..a73494d 100644
--- a/include/oam.s
+++ b/include/oam.s
@@ -1,11 +1,12 @@
.scope OAM
- ADDRESS = $2003
- DMA = $4014
-.endscope
+ ;; Region in internal RAM where sprites are being allocated for later use in
+ ;; the DMA process. The entire page is reserved, as there are 64 sprites x 4
+ ;; bytes each = 256 bytes in total.
+ m_sprites = $200 ; asan:reserve $100
+
+ ;;;
+ ;; Actual addresses from OAM space.
-.macro OAM_WRITE_SPRITES
- lda #$00
- sta OAM::ADDR
- lda #$02
- sta OAM::DMA
-.endmacro
+ m_address = $2003
+ m_dma = $4014
+.endscope
diff --git a/include/ppu.s b/include/ppu.s
index a9c0ed2..7882809 100644
--- a/include/ppu.s
+++ b/include/ppu.s
@@ -1,10 +1,10 @@
.scope PPU
- CONTROL = $2000
- MASK = $2001
- STATUS = $2002
- SCROLL = $2005
- ADDRESS = $2006
- DATA = $2007
+ m_control = $2000
+ m_mask = $2001
+ m_status = $2002
+ m_scroll = $2005
+ m_address = $2006
+ m_data = $2007
;; Shadow for the PPU::CONTROL value. Touch this value instead of accessing
;; the PPU register directly.
diff --git a/src/assets.s b/src/assets.s
index 3d1a6a3..82b6a06 100644
--- a/src/assets.s
+++ b/src/assets.s
@@ -24,7 +24,7 @@
lda #.hibyte(main_screen)
sta Globals::zp_arg1
ldx #$28
- jsr load_screen_x
+ jsr load_screen_x ;; TODO: jal
rts
.endproc
@@ -33,17 +33,17 @@
;; Globals::zp_arg{0,1}. Set the `x` register to the high byte of the
;; nametable to be used.
.proc load_screen_x
- bit PPU::STATUS
+ bit PPU::m_status
- stx PPU::ADDRESS
+ stx PPU::m_address
lda #$00
- sta PPU::ADDRESS
+ sta PPU::m_address
ldy #0
ldx #4
@loop:
lda (Globals::zp_arg0), y
- sta PPU::DATA
+ sta PPU::m_data
iny
bne @loop
@@ -60,44 +60,44 @@
;; Performs all the needed tricks in order to get the first nametable as
;; expected.
.proc prepare_for_title_screen
- bit PPU::STATUS
+ bit PPU::m_status
lda #$23
- sta $2006
+ sta PPU::m_address
lda #$C8
- sta $2006
+ sta PPU::m_address
ldx #$10
@upper_title_bar_loop:
lda #%10101010
- sta $2007
+ sta PPU::m_data
dex
bne @upper_title_bar_loop
;; Update 2nd palette for background. This is redundant upon entering
;; the game, but it makes sense after a game over.
lda #$3F
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$09
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$28
- sta PPU::DATA
+ sta PPU::m_data
lda #$2C
- sta PPU::DATA
+ sta PPU::m_data
lda #$16
- sta PPU::DATA
+ sta PPU::m_data
;; Update 1st palette for foreground.
lda #$3F
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$11
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$30
- sta PPU::DATA
+ sta PPU::m_data
lda #$10
- sta PPU::DATA
+ sta PPU::m_data
lda #$30
- sta PPU::DATA
+ sta PPU::m_data
rts
.endproc
@@ -105,31 +105,31 @@
;; Performs all the needed tricks in order to get the second nametable as
;; expected.
.proc prepare_for_main_screen
- bit PPU::STATUS
+ bit PPU::m_status
;; Update 2nd palette for background.
lda #$3F
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$09
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$14
- sta PPU::DATA
+ sta PPU::m_data
lda #$2C
- sta PPU::DATA
+ sta PPU::m_data
lda #$28
- sta PPU::DATA
+ sta PPU::m_data
;; Update 1st palette for foreground.
lda #$3F
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$11
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$16
- sta PPU::DATA
+ sta PPU::m_data
lda #$10
- sta PPU::DATA
+ sta PPU::m_data
lda #$30
- sta PPU::DATA
+ sta PPU::m_data
rts
.endproc
@@ -137,14 +137,14 @@
;; Copies all the palettes for our game into the proper PPU address.
.proc init_palettes
lda #$3F
- sta PPU::ADDRESS
+ sta PPU::m_address
lda #$00
- sta PPU::ADDRESS
+ sta PPU::m_address
ldx #0
@load_palettes_loop:
lda palettes, x
- sta PPU::DATA
+ sta PPU::m_data
inx
cpx #$20
bne @load_palettes_loop
@@ -177,9 +177,9 @@
;; simple game, I have so much space left in the cartridge that I can go
;; bananas with it. This helps out loading the screen as we can go faster
;; and it is less error prone.
- title_screen:
+ title_screen:
.incbin "../assets/title.nam"
- main_screen:
+ main_screen:
.incbin "../assets/main.nam"
.endscope
diff --git a/src/bullets.s b/src/bullets.s
index db8bfd7..0f31d0c 100644
--- a/src/bullets.s
+++ b/src/bullets.s
@@ -18,7 +18,7 @@
;; bullet.
;; 2. Y coordinate.
;; 3. X coordinate.
- zp_bullets_pool_base = $A0
+ zp_bullets_pool_base = $A0 ; asan:reserve $1E
;; The current amount of bullets on screen.
zp_bullets_pool_size = $E0
diff --git a/src/driver.s b/src/driver.s
index 3ed0536..149eaa7 100644
--- a/src/driver.s
+++ b/src/driver.s
@@ -6,7 +6,7 @@
;;
;; NOTE: this memory address is shared with `zp_title_timer`, as they can
;; never conflict with each other.
- zp_player_timer = $30
+ zp_player_timer = $30 ; asan:ignore
PLAYER_TIMER_VALUE = HZ * 2
.ifdef PAL
@@ -165,7 +165,7 @@
;; It is a valid bullet! Set it now.
lda Bullets::zp_bullets_pool_base + 1, x
- sta $200, y
+ sta OAM::m_sprites, y
iny
;; The tile selection depends on how many moves the bullet has done.
@@ -183,14 +183,14 @@
@last_bullet_tile:
lda #$1E
@set_bullet_tile:
- sta $200, y
+ sta OAM::m_sprites, y
iny
lda #0
- sta $200, y
+ sta OAM::m_sprites, y
iny
lda Bullets::zp_bullets_pool_base + 2, x
- sta $200, y
+ sta OAM::m_sprites, y
iny
@after_first_bullet:
@@ -238,7 +238,7 @@
beq @next_bullet
lda Bullets::zp_bullets_pool_base + 1, x
- sta $200, y
+ sta OAM::m_sprites, y
iny
;; The tile selection depends on how many moves the bullet has done.
@@ -256,14 +256,14 @@
@other_last_bullet_tile:
lda #$1E
@other_set_bullet_tile:
- sta $200, y
+ sta OAM::m_sprites, y
iny
lda #0
- sta $200, y
+ sta OAM::m_sprites, y
iny
lda Bullets::zp_bullets_pool_base + 2, x
- sta $200, y
+ sta OAM::m_sprites, y
iny
@next_bullet:
@@ -287,7 +287,7 @@
;; need for the 'y' register to wrap around in order to quit.
lda #$EF
@reset_sprite:
- sta $200, y
+ sta OAM::m_sprites, y
iny
iny
iny
diff --git a/src/enemies.s b/src/enemies.s
index 377a9a5..dbd0e08 100644
--- a/src/enemies.s
+++ b/src/enemies.s
@@ -10,7 +10,7 @@
ENEMIES_INITIAL_X = $F0
;; TODO: 3 bytes a la bullets
- zp_enemies_pool_base = $60
+ zp_enemies_pool_base = $60 ; asan:reserve $09
zp_enemies_timer = $D0
zp_enemies_pool_size = $D1
diff --git a/src/jetpac.s b/src/jetpac.s
index 6708ed3..6e74d53 100644
--- a/src/jetpac.s
+++ b/src/jetpac.s
@@ -50,7 +50,7 @@
.proc main
;; Disable the PPU and zero out variables which shadow PPU registers.
lda #0
- sta PPU::MASK
+ sta PPU::m_mask
sta PPU::zp_mask
sta PPU::zp_control
@@ -89,13 +89,13 @@
jsr Driver::switch
lda PPU::zp_control
- sta PPU::CONTROL
+ sta PPU::m_control
.else
jsr Title::init
lda #%10001000
sta PPU::zp_control
- sta PPU::CONTROL
+ sta PPU::m_control
.endif
cli
@@ -103,7 +103,7 @@
;; Enable back the PPU
lda #%00011110
sta PPU::zp_mask
- sta PPU::MASK
+ sta PPU::m_mask
@main_game_loop:
READ_JOYPAD1
diff --git a/src/player.s b/src/player.s
index c7b65af..2a87b85 100644
--- a/src/player.s
+++ b/src/player.s
@@ -7,9 +7,9 @@
.macro FIXED_POINT_POSITION_TO_SCREEN POS_ADDR
;; We save the high byte into a temporary value, and we load the low byte
;; into the accumulator.
- lda POS_ADDR + 1
+ lda POS_ADDR + 1 ; asan:ignore
sta Globals::zp_tmp0
- lda POS_ADDR
+ lda POS_ADDR ; asan:ignore
;; And now it's a matter of rotating the high byte into the low one to
;; match a full byte.
@@ -73,12 +73,12 @@
.include "../config/values/player.s"
zp_screen_y = $40
- zp_position_y = $41 ; NOTE: 16-bit.
+ zp_position_y = $41 ; asan:reserve $02
zp_target_velocity_y = $43 ; TODO: needed?
zp_velocity_y = $44
zp_screen_x = $45
- zp_position_x = $46 ; NOTE: 16-bit.
+ zp_position_x = $46 ; asan:reserve $02
zp_target_velocity_x = $48 ; TODO: needed?
zp_velocity_x = $49
@@ -760,40 +760,40 @@
bvs @right
lda #$01
- sta $201
+ sta OAM::m_sprites + $01
lda #$00
- sta $205
+ sta OAM::m_sprites + $05
lda #$11
- sta $209
+ sta OAM::m_sprites + $09
lda #$10
- sta $20D
- stx $211
- sty $215
+ sta OAM::m_sprites + $0D
+ stx OAM::m_sprites + $11
+ sty OAM::m_sprites + $15
ldx #%01000000
bne @set_attributes
@right:
lda #$00
- sta $201
+ sta OAM::m_sprites + $01
lda #$01
- sta $205
+ sta OAM::m_sprites + $05
lda #$10
- sta $209
+ sta OAM::m_sprites + $09
lda #$11
- sta $20D
- stx $215
- sty $211
+ sta OAM::m_sprites + $0D
+ stx OAM::m_sprites + $15
+ sty OAM::m_sprites + $11
ldx #$00
;; The `x` register contains the tile attributes.
@set_attributes:
- stx $202
- stx $206
- stx $20A
- stx $20E
- stx $212
- stx $216
+ stx OAM::m_sprites + $02
+ stx OAM::m_sprites + $06
+ stx OAM::m_sprites + $0A
+ stx OAM::m_sprites + $0E
+ stx OAM::m_sprites + $12
+ stx OAM::m_sprites + $16
rts
.endproc
@@ -802,27 +802,27 @@
.proc update_sprites_coordinates
;; Y axis.
lda zp_screen_y
- sta $0200
- sta $0204
+ sta OAM::m_sprites
+ sta OAM::m_sprites + $04
clc
adc #8
- sta $0208
- sta $020C
+ sta OAM::m_sprites + $08
+ sta OAM::m_sprites + $0C
clc
adc #8
- sta $0210
- sta $0214
+ sta OAM::m_sprites + $10
+ sta OAM::m_sprites + $14
;; X axis.
lda zp_screen_x
- sta $0203
- sta $020B
- sta $0213
+ sta OAM::m_sprites + $03
+ sta OAM::m_sprites + $0B
+ sta OAM::m_sprites + $13
clc
adc #8
- sta $0207
- sta $020F
- sta $0217
+ sta OAM::m_sprites + $07
+ sta OAM::m_sprites + $0F
+ sta OAM::m_sprites + $17
rts
.endproc
diff --git a/src/title.s b/src/title.s
index 01d58f5..e3a2086 100644
--- a/src/title.s
+++ b/src/title.s
@@ -18,13 +18,13 @@
;; Initialize the sprite that guides the player on the menu.
lda #SPRITE_Y_POSITION0
- sta $200
+ sta OAM::m_sprites
lda #$30
- sta $201
+ sta OAM::m_sprites + 1
lda #$00
- sta $202
+ sta OAM::m_sprites + 2
lda #SPRITE_X_POSITION
- sta $203
+ sta OAM::m_sprites + 3
rts
.endproc
@@ -42,9 +42,9 @@
beq @check_down
lda #SPRITE_Y_POSITION0
- cmp $200
+ cmp OAM::m_sprites
beq @end
- sta $200
+ sta OAM::m_sprites
jmp @set_timer_and_end
@check_down:
@@ -53,9 +53,9 @@
beq @check_select
lda #SPRITE_Y_POSITION1
- cmp $200
+ cmp OAM::m_sprites
beq @end
- sta $200
+ sta OAM::m_sprites
jmp @set_timer_and_end
@check_select:
@@ -72,14 +72,14 @@
@do_select:
lda #SPRITE_Y_POSITION0
- cmp $200
+ cmp OAM::m_sprites
beq @down
- sta $200
+ sta OAM::m_sprites
bne @set_timer_and_end
@down:
lda #SPRITE_Y_POSITION1
- sta $200
+ sta OAM::m_sprites
@set_timer_and_end:
lda #TIMER_INIT_VALUE
@@ -94,7 +94,7 @@
.proc start
;; Hide the sprite from the menu.
lda #$EF
- sta $200
+ sta OAM::m_sprites
lda #1
rts
diff --git a/src/vectors.s b/src/vectors.s
index af343a7..e5d1a58 100644
--- a/src/vectors.s
+++ b/src/vectors.s
@@ -5,8 +5,8 @@
;; Debug utilities.
.scope Debug
- ;; Counter for frame drops.
- zp_frame_drops = $90
+ ;; Counter for frame drops. Only touched when PARTIAL is defined.
+ zp_frame_drops = $90 ; asan:ignore
.endscope
;; Pretty standard reset function, nothing crazy.
@@ -17,7 +17,7 @@
;; Disable APU frame counter.
ldx #$40
- stx APU::FRAME_COUNTER
+ stx APU::m_frame_counter
;; Setup the stack.
ldx #$FF
@@ -25,14 +25,14 @@
;; Disable NMIs and the APU's DMC.
inx
- stx PPU::CONTROL
- stx PPU::MASK
- stx APU::DMC
+ stx PPU::m_control
+ stx PPU::m_mask
+ stx APU::m_dmc
;; First PPU wait.
- bit PPU::STATUS
+ bit PPU::m_status
@vblankwait1:
- bit PPU::STATUS
+ bit PPU::m_status
bpl @vblankwait1
;; Initialize the counter for frame drops before any NMIs can come in.
@@ -45,7 +45,7 @@
lda #$EF
ldx #0
@sprite_reset_loop:
- sta $200, x
+ sta OAM::m_sprites, x
inx
inx
inx
@@ -54,13 +54,13 @@
;; DMA setup for sprite reset.
lda #$00
- sta OAM::ADDRESS
+ sta OAM::m_address
lda #$02
- sta OAM::DMA
+ sta OAM::m_dma
;; Second PPU wait. After that the PPU is stable.
@vblankwait2:
- bit PPU::STATUS
+ bit PPU::m_status
bpl @vblankwait2
;; NOTE: palettes are not initialized here as it's going to be one of the
@@ -89,9 +89,9 @@
;; Sprite DMA.
lda #$00
- sta OAM::ADDRESS
+ sta OAM::m_address
lda #$02
- sta OAM::DMA
+ sta OAM::m_dma
;; Are we paused? If so skip timers, PAL handler and the likes.
lda #%00001000
@@ -126,20 +126,20 @@
and Globals::zp_flags
sta Globals::zp_flags
- bit PPU::STATUS
+ bit PPU::m_status
;; Update the PPU control/mask registers with shadowed values.
lda PPU::zp_mask
- sta PPU::MASK
+ sta PPU::m_mask
lda PPU::zp_control
- sta PPU::CONTROL
+ sta PPU::m_control
@scroll:
;; Always reset the scroll just in case.
- bit PPU::STATUS
+ bit PPU::m_status
lda #$00
- sta PPU::SCROLL
- sta PPU::SCROLL
+ sta PPU::m_scroll
+ sta PPU::m_scroll
;; Unblock the main code.
lda #%01111111