aboutsummaryrefslogtreecommitdiff
path: root/scroll/include/driver.s
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mikisabate@gmail.com>2025-03-10 22:55:41 +0100
committerMiquel Sabaté Solà <mikisabate@gmail.com>2025-03-10 23:22:22 +0100
commitba0cf9e5293f258c58ced1fcc47f558e7419dae4 (patch)
treeb620422506e5b8a951f7e52756c116bfb1498ea3 /scroll/include/driver.s
parent1a74e6a1856673072a61abd0861759901bc2d939 (diff)
downloadcode.nes-ba0cf9e5293f258c58ced1fcc47f558e7419dae4.tar.gz
code.nes-ba0cf9e5293f258c58ced1fcc47f558e7419dae4.zip
Provide an example on multiscreen scrolling
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'scroll/include/driver.s')
-rw-r--r--scroll/include/driver.s98
1 files changed, 98 insertions, 0 deletions
diff --git a/scroll/include/driver.s b/scroll/include/driver.s
new file mode 100644
index 0000000..abb3f5e
--- /dev/null
+++ b/scroll/include/driver.s
@@ -0,0 +1,98 @@
+;; The runtime of the game.
+.scope Driver
+ ;; Index of the current level.
+ zp_level = $77
+
+ ;; Whenever "Select" is pressed, it's used to count how many cycles have to
+ ;; pass before allowing another level switch.
+ zp_counter = $97
+
+ ;; Value that will be set for the `zp_counter` whenever the "Select" button
+ ;; is pressed for the first time.
+ SELECT_COUNTER_VALUE = $20
+
+ ;; Initialize global variables and other variables which have an impact on
+ ;; the runtime of the game.
+ .proc init
+ lda #0
+ sta Globals::zp_arg0
+ sta Globals::zp_arg1
+ sta Globals::zp_arg2
+ sta Globals::zp_arg3
+ sta Globals::zp_arg4
+ sta Globals::zp_tmp0
+ sta Globals::zp_tmp1
+ sta Globals::zp_tmp2
+ sta Globals::zp_tmp3
+ sta Globals::zp_idx
+ sta Globals::zp_flags
+ sta zp_level
+ sta zp_counter
+
+ rts
+ .endproc
+
+ ;; Function to be called at each iteration of the game loop. It loads any
+ ;; pending background columns and checks for level selection.
+ .proc update
+ ;; Are we actually loading a new level?
+ lda #%00100000
+ and Globals::zp_flags
+ beq @new_level
+
+ ;; Is the user actually allowed to hit the 'Select' button?
+ lda zp_counter
+ beq @check_select
+ dec zp_counter
+ jmp @check_column
+
+ @check_select:
+ ;; If `select` is pressed, then go for a new level. Otherwise check
+ ;; whether there is a pending column to be loaded.
+ lda #Joypad::BUTTON_SELECT
+ and Joypad::m_buttons1
+ beq @check_column
+
+ ;; Set the counter.
+ lda #SELECT_COUNTER_VALUE
+ sta zp_counter
+
+ ;; 'Select' was pressed and we weren't loading another level. Hence,
+ ;; increase the level index and load it.
+ inc zp_level
+ @new_level:
+ ;; Check the level index.
+ ldx zp_level
+ cpx #$02
+ bne :+
+ ldx #$00
+ :
+ ;; And load the computed level.
+ stx zp_level
+ jsr Background::load_level_x
+ beq :+
+
+ ;; Level could be rendered, enable back the PPU.
+ lda PPU::zp_mask
+ sta PPU::MASK
+
+ ;; Set the player back to its position.
+ RESET_PLAYER_POSITION
+ :
+ rts
+
+ @check_column:
+ ;; Do nothing if the `column` flag is not set.
+ lda #%00010000
+ and Globals::zp_flags
+ beq @end
+
+ ;; Continue loading the pending column.
+ jsr Background::load_column
+ beq @end
+ JAL Background::prepare_next_column
+
+ @end:
+ rts
+ .endproc
+.endscope