aboutsummaryrefslogtreecommitdiff
path: root/basics
diff options
context:
space:
mode:
Diffstat (limited to 'basics')
-rw-r--r--basics/chr-ram.s37
-rw-r--r--basics/flicker.s14
-rw-r--r--basics/input.s23
-rw-r--r--basics/persist.s16
-rw-r--r--basics/sprite.s26
-rw-r--r--basics/unrom.s18
6 files changed, 69 insertions, 65 deletions
diff --git a/basics/chr-ram.s b/basics/chr-ram.s
index 20e1b30..bb2186e 100644
--- a/basics/chr-ram.s
+++ b/basics/chr-ram.s
@@ -29,7 +29,8 @@
.segment "BANK0"
-chr: .incbin "../assets/basic.chr"
+chr:
+ .incbin "../assets/basic.chr"
.segment "BANK1"
.byte $00
@@ -56,33 +57,18 @@ chr: .incbin "../assets/basic.chr"
.segment "FIXED"
;;;
-;; Bank switching code as with `basics/unrom.s`. Not used here.
-
-banktable:
- .byte $00, $01, $02, $03, $04, $05, $06
-
-m_current_bank = $00
-
-bankswitch:
- sty m_current_bank
-bankswitch_nosave:
- tya
- sta banktable, y
- rts
-
-;;;
;; From here on the code is basically the same as `basics/sprite.s`, but with a
;; special twist that will be commented in. For comments on the rest of the code
;; just check `basics/sprite.s`.
-reset:
+.proc reset
sei
cld
- ldx #$40
+ ldx #$FF
stx $4017
- ldx #$ff
+ ldx #$FF
txs
inx
stx $2000
@@ -139,6 +125,7 @@ reset:
bne @palettes_reset_loop
jmp main
+.endproc
;;;
;; Transfer the CHR data from PRG-ROM into RAM.
@@ -166,17 +153,17 @@ reset:
;; - x contains the number of 256-byte pages to copy.
;; - y will index within the page ($00-$FF).
ldx #32
-loop:
+@loop:
;; First part of the loop: copy each byte of the current page.
lda ($00), y
sta $2007
iny
- bne loop
+ bne @loop
;; Go to the next page and repeat the first part of the loop.
inc $01
dex
- bne loop
+ bne @loop
rts
.endproc
@@ -274,7 +261,7 @@ initial_sprite_data:
.byte $B0, $00, %01000000, $82
.endproc
-nmi:
+.proc nmi
bit $20
bpl @next
@@ -305,6 +292,8 @@ nmi:
pla
@next:
rti
+.endproc
-irq:
+.proc irq
rti
+.endproc
diff --git a/basics/flicker.s b/basics/flicker.s
index 8db03e8..2522cb2 100644
--- a/basics/flicker.s
+++ b/basics/flicker.s
@@ -61,7 +61,6 @@
jmp @main_game_loop
.endproc
-
;;;
;; NOTE: this is the actual meat of the example :D
.proc apply_flicker
@@ -135,7 +134,7 @@
;;;
;; NOTE: and from here on stuff that is not relevant for sprite flickering.
-nmi:
+.proc nmi
bit $20
bpl @next
@@ -168,15 +167,16 @@ nmi:
pla
@next:
rti
+.endproc
-reset:
+.proc reset
sei
cld
ldx #$40
stx $4017 ; APU Frame Counter
- ldx #$ff
+ ldx #$FF
txs
inx
@@ -201,7 +201,7 @@ reset:
inx
bne @ram_reset_loop ; if x overflows back to #00, then we are done.
- lda #$ef
+ lda #$EF
@sprite_reset_loop:
sta $200, x
inx
@@ -229,9 +229,11 @@ reset:
bne @palettes_reset_loop
jmp main
+.endproc
-irq:
+.proc irq
rti
+.endproc
.proc init_sprites
NUM_SPRITES = 20
diff --git a/basics/input.s b/basics/input.s
index b773fd7..df49a66 100644
--- a/basics/input.s
+++ b/basics/input.s
@@ -13,12 +13,10 @@
;; which brings some other considerations when reading from controllers. That
;; is, the algorithm shown below is not entirely "safe" due to a hardware bug
;; which might give unreliable inputs on some spikes.
-;;;
;;;
;; You can safely ignore all of this up until the `ReadController` subroutine.
;; This is boilerplate that is explained on the `sprite.s` example.
-;;;
.segment "HEADER"
.byte 'N', 'E', 'S', $1A
@@ -34,17 +32,23 @@
.segment "CODE"
-nmi:
-irq:
- rti
+;; Unused
+.proc nmi
+ rti
+.endproc
+
+;; Unused
+.proc irq
+ rti
+.endproc
-reset:
+.proc reset
sei
cld
ldx #$40
stx $4017
- ldx #$ff
+ ldx #$FF
txs
inx
@@ -75,6 +79,7 @@ reset:
bpl @vblankwait2
jmp main
+.endproc
.proc ReadController
;; The status of the eight buttons fits into a single byte. We start the whole
@@ -117,7 +122,7 @@ reset:
;; `rol` instruction. At this point, we have already read the full byte.
read_loop:
lda $4016
- lsr a
+ lsr
rol $20
bcc read_loop
@@ -166,8 +171,6 @@ pressed:
;; There and back again.
jmp loop
-
- rts
.endproc
.segment "CHARS"
diff --git a/basics/persist.s b/basics/persist.s
index 3e7c439..e7dfb07 100644
--- a/basics/persist.s
+++ b/basics/persist.s
@@ -43,19 +43,24 @@
.segment "BANK1"
;; Unused
-nmi:
-irq:
- rti
+.proc nmi
+ rti
+.endproc
+
+;; Unused
+.proc irq
+ rti
+.endproc
;; Check `basics/sprite.s` for a deeper look on the logic below. I have only
;; added comments to MMC1-specific stuff.
-reset:
+.proc reset
sei
cld
ldx #$40
stx $4017
- ldx #$ff
+ ldx #$FF
txs
inx
@@ -165,6 +170,7 @@ reset_mmc1:
;; Loop forever, there's nothing to be done here.
@loop:
jmp @loop
+.endproc
;; Unused
.segment "CHR0"
diff --git a/basics/sprite.s b/basics/sprite.s
index 1892ce5..6fcdad3 100644
--- a/basics/sprite.s
+++ b/basics/sprite.s
@@ -23,7 +23,6 @@
;; basic identification, it defines some relevant things like PRG and CHR sizes,
;; plus mapping if desired. See https://www.nesdev.org/wiki/NES_2.0#Header for
;; documentation on this, or also: https://www.nesdev.org/neshdr20.txt.
-;;;
.segment "HEADER"
;; The first thing to do is to define the magic "NES\0" string identifier
;; ($1A is the ASCII that MS-DOS wanted as end of string). Some people write
@@ -82,7 +81,6 @@
;; actually removes this segment in its linker configuration down the road).
;; This is also removed by the configuration provided in `config/nrom.cfg`,
;; which is the one being used in the end for this example.
-;;;
;; .segment "STARTUP"
.segment "CODE"
@@ -94,8 +92,7 @@
;; NesDev wiki which is pretty much followed by everyone as I could see. The
;; main idea is to leave the hardware in a known state and then jump into the
;; main game subroutine.
-;;;
-reset:
+.proc reset
;; We first instruct the NES to disable everything. That is, we don't want
;; any pesky interrupt to make us jump into the `nmi` section, for example,
;; before we have configured everything.
@@ -200,10 +197,10 @@ reset:
;;
;; "Resetting sprites" is just a matter of giving them a value which will
;; not bother us in the future. One way to do this is to set each value to
- ;; $ef, which will give each "sprite" off-screen Y-coordinates. How any of
+ ;; $EF, which will give each "sprite" off-screen Y-coordinates. How any of
;; this is the case will be shown whenever we deal with loading proper
;; sprites below.
- lda #$ef
+ lda #$EF
@sprite_reset_loop:
sta $200, x
inx
@@ -217,7 +214,7 @@ reset:
;; the byte given at the OAMADDR, thus XX = #$00; and N = 2 (see `lda
;; #$02`). Therefore, we are telling the PPU to start the DMA process from
;; $200. The PPU will assume that the following 256 bytes of memory are the
- ;; ones to be copied, resulting in a DMA copy of $200-$2ff, right where we
+ ;; ones to be copied, resulting in a DMA copy of $200-$2FF, right where we
;; stored the sprite data in advance.
lda #$00
sta $2003 ; OAMADDR
@@ -238,7 +235,7 @@ reset:
;; stored. Palettes are the answer from old systems like the NES to: how can
;; you display this amount of colors on screen without taking too much
;; memory? The NES allows developers to store eight palettes (four
- ;; background, four foreground), and each palette group four colors. This
+ ;; background, four foreground), and each palette groups four colors. This
;; way, whenever we want to draw a sprite or a piece of background, we don't
;; specify which colors to pick for each pixel, but we rather apply a
;; palette to a sprite or background tile definition.
@@ -268,12 +265,12 @@ reset:
;; jump into our main subroutine and start loading sprites, palettes, etc.;
;; and start the game proper.
jmp main
+.endproc
;;;
;; This is our main subroutine. At this point we can assume that the hardware
;; has already been set to a proper and defined state. So now we can load all
;; the data we need for our game and enter the main game loop.
-;;;
.proc main
;; Before starting the game loop proper we initialize all our assets: load
;; the palettes, nametables and sprites for this game.
@@ -341,7 +338,7 @@ reset:
.proc init_palettes
;; Remember these four instructions? That's what we also did when resetting
;; palettes on the reset code. That is, we are preparing the PPU to write
- ;; data starting from $3f00.
+ ;; data starting from $3F00.
lda #$3F
sta $2006 ; PPUADDR
lda #$00
@@ -500,7 +497,7 @@ palettes:
;; This is tied to the number of sprites stored in the `initial_sprite_data`
;; section. Remember that this can be 64 *maximum*: 64 sprites * 4 bytes per
;; sprite = 256 bytes; which is the reserved space in memory we have for
- ;; sprites: $0200-$02ff.
+ ;; sprites: $0200-$02FF.
NUM_SPRITES = 2
;; The loading is quite straight-forward. We just store whatever is on
@@ -551,8 +548,7 @@ initial_sprite_data:
;; we ought to keep things as simple and fast as possible. You can take a look
;; at the examples from `scroll` for more complex NMI code that have to handle
;; stuff like VRAM buffering or setting other PPU registers.
-;;;
-nmi:
+.proc nmi
;; As mentioned on the `main` subroutine, rendering will be skipped until
;; the proper flag is set.
bit $20
@@ -601,6 +597,7 @@ nmi:
pla
@next:
rti
+.endproc
;;;
;; Interrupt Requests handler. This is triggered by the NES' sound processor
@@ -608,8 +605,9 @@ nmi:
;; mapper). In our case we don't have to do anything here, so we just return
;; from the interrupt.
;;;
-irq:
+.proc irq
rti
+.endproc
;;;
;; Include into this all the data that needs to go into the CHR ROM. One typical
diff --git a/basics/unrom.s b/basics/unrom.s
index b6deb4d..eb49b17 100644
--- a/basics/unrom.s
+++ b/basics/unrom.s
@@ -101,32 +101,37 @@ banktable:
;; Variable containing the bank we are currently in. It's useful to keep track
;; of the bank so the NMI handler can restore it if it does some bank switching
;; of its own.
-m_current_bank = $00
+zp_current_bank = $00
;; Perform a bankswitch by using the value on the `y` register. Note that you
;; can use the `bankswitch_nosave` variant, which is useful if you just want to
;; perform a temporary bankswitch (e.g. on NMI code).
bankswitch:
- sty m_current_bank
+ sty zp_current_bank
bankswitch_nosave:
tya
sta banktable, y
rts
;; Unused
-nmi:
-irq:
+.proc nmi
rti
+.endproc
+
+;; Unused
+.proc irq
+ rti
+.endproc
;; Check `basics/sprite.s` for a deeper look on the logic below. I have only
;; added code after configuration/reset is done.
-reset:
+.proc reset
sei
cld
ldx #$40
stx $4017
- ldx #$ff
+ ldx #$FF
txs
inx
@@ -178,3 +183,4 @@ reset:
;; Loop forever, there's nothing to be done here.
@loop:
jmp @loop
+.endproc