aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Sabaté Solà <mssola@mssola.com>2026-04-10 15:42:46 +0200
committerMiquel Sabaté Solà <mssola@mssola.com>2026-04-10 15:42:46 +0200
commitddbdfb54a8ebabbeeeb6fe10518f1a548404d5ed (patch)
tree6bd938d5e391140c37fa3a01d9e8d0965a1130a0
parente14b6e623df4b2cc9375660fa3e5da73dba3e8c8 (diff)
downloadcode.nes-ddbdfb54a8ebabbeeeb6fe10518f1a548404d5ed.tar.gz
code.nes-ddbdfb54a8ebabbeeeb6fe10518f1a548404d5ed.zip
Add the noise channel to sound/select.s
Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
-rw-r--r--shared/apu.s3
-rw-r--r--sound/select.s39
2 files changed, 42 insertions, 0 deletions
diff --git a/shared/apu.s b/shared/apu.s
index f876d91..35e432f 100644
--- a/shared/apu.s
+++ b/shared/apu.s
@@ -10,6 +10,9 @@
m_triangle_control = $4008
m_triangle_low = $400A
m_triangle_high = $400B
+ m_noise_envelope = $400C
+ m_noise_mode = $400E
+ m_noise_counter = $400F
m_dmc = $4010
m_status = $4015
m_frame_counter = $4017
diff --git a/sound/select.s b/sound/select.s
index 887a585..8f15399 100644
--- a/sound/select.s
+++ b/sound/select.s
@@ -152,6 +152,34 @@
lda #$00
sta APU::m_triangle_high
+ ;; The noise channel produces noise with a pseudo-random bit generator. Its
+ ;; envelope register is pretty much the same as with the square channels,
+ ;; but the two most significant bits are unused as "duty" is, like with the
+ ;; triangle channel, not a thing on this context.
+ lda #%00110000
+ sta APU::m_noise_envelope
+
+ ;; NOTE: address $400D is unused from the APU.
+
+ ;; You then configure the mode of noise by writing to the $400E address. In the
+ ;; low nibble you configure the "noise period", which in turn is the index
+ ;; for a table that the APU will use as the real noise period (see:
+ ;; https://www.nesdev.org/wiki/APU_Noise for specifics). Finally, only the
+ ;; most significant bit is used on the high nibble, which sets the
+ ;; "mode". Long story short, it dramatically shortens the period if set,
+ ;; which will give you a more "metallic" sound. Change the current value
+ ;; from "$0A" to "$8A" and test it by yourself ;-)
+ lda #$0A
+ sta APU::m_noise_mode
+
+ ;; Finally, there is the counter register for the noise channel. Given that
+ ;; we have disabled when we configured 'APU::m_noise_envelope', you'd think
+ ;; that you wouldn't have to touch it, but you'd be wrong. This register
+ ;; needs to be written at least once so to trigger the enablement of this
+ ;; channel. We do it now with a zero value, which also does the trick.
+ lda #0
+ sta APU::m_noise_counter
+
cli
lda #%10001000
sta PPU::m_control
@@ -194,6 +222,17 @@
@set_triangle:
sta APU::m_triangle_control
+ ;; Mute/Play the noise channel
+ lda Joypad::zp_buttons1
+ and #%00010000
+ beq @reset_noise
+ lda #%00111000
+ bne @set_noise
+@reset_noise:
+ lda #%00110000
+@set_noise:
+ sta APU::m_noise_envelope
+
;; NOTE: done :)
lda #%10000000