aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--assets/diskun.chrbin8192 -> 8192 bytes
-rw-r--r--basics/flicker.s2
-rw-r--r--fx/blink.s56
-rw-r--r--scroll/roulette.s17
5 files changed, 50 insertions, 27 deletions
diff --git a/README.md b/README.md
index 42302a5..50bb8dc 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ check out [this list](#other-projects).
You can build everything by just calling `make` and binaries will then be
available in the `out` directory. Before doing that, though, you will need a
-compiler for the 6052 platform. A good option is
+compiler for the 6502 platform. A good option is
[cc65](https://github.com/cc65/cc65), which is available on all major platforms,
and if you are feeling adventurous you can check out
[nasm](https://github.com/mssola/tools.nes). By default the Makefile uses `cc65`
diff --git a/assets/diskun.chr b/assets/diskun.chr
index 3ed0dc4..fe48e96 100644
--- a/assets/diskun.chr
+++ b/assets/diskun.chr
Binary files differ
diff --git a/basics/flicker.s b/basics/flicker.s
index 25f1d33..234c8a1 100644
--- a/basics/flicker.s
+++ b/basics/flicker.s
@@ -27,7 +27,7 @@
jsr init_sprites
cli
- lda #%10010000
+ lda #%10001000
sta $2000 ; PPUCTRL
lda #%00011110
sta $2001 ; PPUMASK
diff --git a/fx/blink.s b/fx/blink.s
index adf8553..4fdaa6b 100644
--- a/fx/blink.s
+++ b/fx/blink.s
@@ -183,8 +183,9 @@ reset:
;; span 4 banks (that is, the first pattern table on the PPU). We have to
;; account for that when writing into the first two registers (and that's
;; why they are set to 0 and 2 respectively). Other than that, R2-R5 hold
- ;; which bank goes into the other remaining regions which are 1KB each.
- ;; Because of this, we can simply assign one 1KB bank to each register.
+ ;; which bank goes into the other remaining regions which are 1KB each
+ ;; (hence, the second pattern table is controlled via R2-R5). Because of
+ ;; this, we can simply assign one 1KB bank to each register.
;;
;; To sum things up, on this setup the first pattern table is equally
;; divided by 2 and it's controlled by R0 and R1 respectively. The second
@@ -246,12 +247,28 @@ reset:
;;; NOTE: mainly as usual except that a bit of game loop has been added to
;;; handle the blinking state.
.proc main
+ ;; The code will iterate between banks 4 and 6 on the pattern table, as
+ ;; that's where sprites are located (check the CHARS segment for more info).
+ lda #4
+ sta Vars::last_bank
+
jsr Diskun::init_palettes
jsr init_sprites
cli
- lda #%10010000
+
+ ;; NOTE: This looks like other examples, but here having background tiles on
+ ;; the first pattern table and sprite tiles on the second pattern table is
+ ;; not a matter of personal taste, but there are technical reasons for it.
+ ;; If you check how IRQs work on the MMC3 chip:
+ ;; https://www.nesdev.org/wiki/MMC3#IRQ_Specifics; you will find that on 8x8
+ ;; tile mode having this arrangement actually spares us from a hardware bug.
+ ;; Long story short, placing background tiles first and sprite tiles second
+ ;; make scanline IRQs reliable. Hence, at least on all MMC3 examples, this
+ ;; will be guaranteed.
+ lda #%10001000
sta $2000
+
lda #%00011110
sta $2001
@@ -277,17 +294,19 @@ reset:
lda #0
sta Vars::counter
- ;; The whole trick is done on R0. So select it.
- lda #0
+ ;; The whole trick is done on R2, which points to $1000, where the sprite
+ ;; tiles begin. Hence, select it.
+ lda #2
sta MMC3::BANK_SELECT
- ;; The value for the register is either 0 or 2 depending on its last value.
+ ;; The value for the register is either 4 or 6 depending on its last value.
lda Vars::last_bank
+ cmp #4
beq :+
- lda #0
- beq @set
+ lda #4
+ jmp @set
:
- lda #2
+ lda #6
@set:
;; Save which is the bank being used both internally and onto the MMC3 chip.
sta Vars::last_bank
@@ -369,14 +388,21 @@ irq:
;;; too much for this example, but it's a reasonable size for an MMC3 game.
;;; Considering only one pair of pattern tables are available at any given
;;; moment (8KB), this means that we need space for 128 / 8 = 16 pairs of
-;;; pattern tables here. For this example the first 8KB are realy only used, and
-;;; the rest are left with a default value ($00).
+;;; pattern tables here. For this example the first 8KB are really only used,
+;;; and the rest are left with a default value ($00).
.segment "CHARS"
-;; First 8KB (note that diskun0.chr and diskun1.chr are both 2KB long)
-.incbin "../assets/diskun0.chr" ; First half of the first pattern table has the default diskun character.
-.incbin "../assets/diskun1.chr" ; Second half of the first pattern table simply has the blinking version.
-.res $1000, $00 ; Second pattern table is left with the default value.
+;; As explained when initializing the PPUCTRL register ($2000), it's actually
+;; important to place background tiles first and sprite tiles second on the
+;; MMC3. This is guaranteed here by setting the first pattern table as empty (we
+;; have no background on this example, really). The second pattern table is then
+;; filled with `diskun0.chr` and `diskun1.chr`, which are 2KB each. Hence, the
+;; 4th CHR bank contains the regular character, and the 6th CHR bank contains
+;; the blinking version. You can see these values used when initializing
+;; `Vars::last_bank`, or when performing bank switching.
+.res $1000, $00
+.incbin "../assets/diskun0.chr" ; First half of the second pattern table has the default diskun character.
+.incbin "../assets/diskun1.chr" ; Second half of the second pattern table simply has the blinking version.
;; The 15 other 8KB portions are left empty.
.res $2000, $00
diff --git a/scroll/roulette.s b/scroll/roulette.s
index ecf2569..4b13c22 100644
--- a/scroll/roulette.s
+++ b/scroll/roulette.s
@@ -1,6 +1,6 @@
;;;
;; Divide the screen in three rows and make them move in different
-;; directions/speed. This is achieved thanks to the MMC3 chip (check the
+;; directions/speed. This is achieved thanks to the MMC3 chip (check
;; `fx/blink.s` for further information on this chip). In particular, we are
;; using the scanline IRQ mechanism provided by this chip to react to different
;; parts of the screen being rendered:
@@ -208,7 +208,7 @@ reset:
;; NOTE: enable back interrupts so we can set them up later on `nmi` code.
cli
- lda #%10010000
+ lda #%10001000
sta $2000
lda #%00011110
sta $2001
@@ -386,9 +386,9 @@ nmi:
ldx #$00
stx MMC3::IRQ_DISABLE
- ;; The screen is made up of 240 scan lines. Since we are dividing the screen
- ;; by 3: 240 / 3 = 80. Hence, the next IRQ should happen on scanline 80,
- ;; where we would need to update the scroll value through the
+ ;; The screen is made up of 240 visible scan lines. Since we are dividing
+ ;; the screen by 3: 240 / 3 = 80. Hence, the next IRQ should happen on
+ ;; scanline 80, where we would need to update the scroll value through the
;; `{center/bottom}_scroll` values instead. Moreover, note that
;; `MMC3::IRQ_ENABLE` accepts any value, so the same value as the two other
;; registers is just fine.
@@ -493,15 +493,12 @@ irq:
rti
-;;; NOTE: pretty much the same as `fx/blink.s` but we also copy the same data on
-;;; the second pattern table as that's the one being used for background
-;;; elements.
+;;; NOTE: pretty much the same as `fx/blink.s`.
.segment "CHARS"
.incbin "../assets/diskun0.chr"
.incbin "../assets/diskun1.chr"
-.incbin "../assets/diskun0.chr"
-.incbin "../assets/diskun1.chr"
+.res $1000, $00
;; The 15 other 8KB portions are left empty.
.res $2000, $00