Skip navigation
Welcome, Guest! Please Login or Join

Loading...

Nerdy Nights Sound: Part 2 Square 2 and Triangle Basics

Aug 24, 2009 at 1:52:04 AM
MetalSlime (0)
avatar
(Thomas Hjelm) < Crack Trooper >
Posts: 140 - Joined: 08/14/2008
Japan
Profile
Last Week: APU Overview and Square 1 Basics

This week: We will learn how to makes sounds with the Square 2 and Triangle channels.

Square 2

Last time we produced a beep on the Square 1 channel by making writes to $4000-$4003.  Now we'll learn how to do it with Square 2.  This is very easy because Square 1 and Square 2 are almost identical.  We control the Square 2 channel with ports $4004-$4007, and they more or less mirror Square 1's $4000-4003.

SQ2_ENV ($4004)

76543210
||||||||
||||++++- Volume
|||+----- Saw Envelope Disable (0: use internal counter for volume; 1: use Volume for volume)
||+------ Length Counter Disable (0: use Length Counter; 1: disable Length Counter)
++------- Duty Cycle


SQ2_SWEEP ($4005)
Skip this for now.  This port, incidentally, is where Square 2 differs from Square 1.


SQ2_LO
($4006)


76543210
||||||||
++++++++- Low 8-bits of period


SQ2_HI
($4007)


76543210
||||||||
|||||+++- High 3-bits of period
+++++---- Length Counter

To produce a sound, first we enable the channel via $4015:

    lda #%00000010 ;enable Square 2
    sta $4015
    
Then we write to the Square 2 ports:

    lda #%00111000 ;Duty Cycle 00, Volume 8 (half volume)
    sta $4004
 
    lda #$A9   ;$0A9 is an E in NTSC mode
    sta $4006
 
    lda #$00
    sta $4007
    
Except for sweeps, the Square 2 channel works just like the Square 1 channel.
    
Triangle

The Triangle channel produces triangle waveforms which have a smooth sound to them.  Think of the flute-like melody in the Dragon Warrior overland song.  That's the Triangle.

Unlike the Square channels, we have no control over the Triangle channel's volume or tone.  It makes only one type of sound and it's either on (playing) or off (silent).  We manipulate the Triangle channel via ports $4008-$400B.

TRI_CTRL ($4008)

76543210
||||||||
|+++++++- Value
+-------- Control Flag (0: use internal counters; 1: disable internal counters)

The triangle channel has two internal counters that can be used to automatically control note duration.  We are going to disable them so that we can control note length manually.  We will set the Control Flag to 1 and forget about it.

When the internal counters are disabled, Value controls whether the channel is on or off.  To silence the channel, set Value to 0.  To turn the channel on (ie, unsilence), set Value to any non-zero value.  Here are some examples:

    lda #%10000000 ;silence the Triangle channel
    sta $4008
 
    lda #%10000001 ;Triangle channel on
    sta $4008
 
    lda #%10001111 ;Triangle channel on
    sta $4008
 
    lda #%11111111 ;Triangle channel on
    sta $4008
    
Note that the last three examples are functionally the same.  Any non-zero value in Value makes the Triangle channel play.

Unused Port
$4009 is unused

Setting the Note
$400A and $400B control the period of the wave, or in other words what note you hear (A, C#, G, etc).  Like the Squares, Triangle periods are 11-bits long.  $400A holds the low 8-bits and $400B holds the high 3-bits of the period.  We'll learn more about periods next week, but for now just know that changing the values written to these ports will change the note that is played.

TRI_LO ($400A)

76543210
||||||||
++++++++- Low 8-bits of period

TRI_HI ($400B)

76543210
||||||||
|||||+++- High 3-bits of period
+++++---- Length Counter

The Length Counter, if enabled, controls how long the note is played.  We disabled it up in the $4008 section, so we can forget about it for now.

Here is some code to play an eternal beep on the Triangle channel:

    lda #%00000100 ;enable Triangle channel
    sta $4015

    lda #%10000001 ;disable counters, non-zero Value turns channel on
    sta $4008
 
    lda #$42   ;a period of $042 plays a G# in NTSC mode.
    sta $400A
 
    lda #$00
    sta $400B
    
Multiple Beeps
We now know how to use the Square 1, Square 2 and Triangle channels to make sound.  It doesn't take too much extra work to make them all play at the same time.  We just have to enable all three channels via $4015 and then write to the ports.  Here's some code that will play a C#m chord (C# E G#) using the knowledge we have gained up to now:

    lda #%00000111  ;enable Sq1, Sq2 and Tri channels
    sta $4015
 
    ;Square 1
    lda #%00111000  ;Duty 00, Volume 8 (half volume)
    sta $4000
    lda #$C9        ;$0C9 is a C# in NTSC mode
    sta $4002       ;low 8 bits of period
    lda #$00
    sta $4003       ;high 3 bits of period
 
    ;Square 2
    lda #%01110110  ;Duty 01, Volume 6
    sta $4004
    lda #$A9        ;$0A9 is an E in NTSC mode
    sta $4006
    lda #$00
    sta $4007
 
    ;Triangle
    lda #%10000001  ;Triangle channel on
    sta $4008
    lda #$42        ;$042 is a G# in NTSC mode
    sta $400A
    lda #$00
    sta $400B
    
Putting It All Together
Download and unzip the triad.zip sample files. All the code above is in the triad.asm file. Make sure triad.asm and triad.bat are all in the same folder as NESASM3, then double click triad.bat. That will run NESASM3 and should produce the triad.nes file. Run that NES file in FCEUXD SP to listen to your C#m chord!  Edit triad.asm to change the Volume and Duty Cycle for the square waves.  Try changing the Periods to produce different notes.

Try to silence the various channels by either disabling them via $4015 or silencing them via $4000/$4004/$4008.

Finally try writing some code that will silence/unsilence the individual channels based on user input, like so:

A: toggle Square 1 channel on/off
B: toggle Square 2 channel on/off
Select: toggle Triangle channel on/off

Next Week: Periods and Lookup Tables

-------------------------
MetalSlime runs away

My nesdev blog: http://tummaigames.com/blog...


Edited: 10/23/2009 at 04:46 AM by MetalSlime

Aug 24, 2009 at 2:27:56 AM
udisi (88)
avatar
< King Solomon >
Posts: 3261 - Joined: 11/15/2006
United States
Profile
it's times like this I wish I actually spent more time on music theory. I played guitar, bass, and drums, but I was all by ear. I have some chord books somewhere, may have to bust them out.

Aug 24, 2009 at 2:42:38 AM
MetalSlime (0)
avatar
(Thomas Hjelm) < Crack Trooper >
Posts: 140 - Joined: 08/14/2008
Japan
Profile
If you play guitar and bass by ear you'll be fine as long as you can identify what note you are playing on the fretboard (by the counting method ). If you are playing a chord on the guitar, just figure out the individual notes one at a time. There's no reason you'd have to know the technical name of the chord to transpose from the guitar to the NES.

-------------------------
MetalSlime runs away

My nesdev blog: http://tummaigames.com/blog...

Aug 24, 2009 at 2:51:22 AM
udisi (88)
avatar
< King Solomon >
Posts: 3261 - Joined: 11/15/2006
United States
Profile
oh, I know, but if I actually knew the note combinations, it would be much faster.

Aug 24, 2009 at 10:15:27 AM
MODERATOR
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7581 - Joined: 06/21/2007
Florida
Profile
Yeah, I'm very happy that I took so many theory classes. It helps me a lot on deciding where to go.

Dec 9, 2014 at 11:37:04 PM
Mega Mario Man (39)
avatar
< Kraid Killer >
Posts: 2067 - Joined: 02/13/2014
United States
Profile
Taking some time to finally work through this. Glad I took some music theory. I can see it is going to come in handy. Great tutorials so far.

-------------------------
Current Project
Tailgate Party

My Homebrews - Orab Games - On Facebook
  
Happy Hour , Power Pad Demo

Dec 10, 2014 at 1:03:47 AM
SoleGooseProductions (120)
avatar
(Beau ) < Kraid Killer >
Posts: 2474 - Joined: 04/22/2013
Indiana
Profile
No theory classes here, but I cannot wait to get to doing music. If only everything else didn't take so much time .

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com