We've just updated MediaWiki and its underlying software. If anything doesn't look or work quite right, please mention it to us. --RanAS

N-SPC Engine: Difference between revisions

From SnesLab
Jump to: navigation, search
(Another minor terminology modification for percussion's base instrument ID definition)
(Caught a typo in Hong Kong '97 with its ID of the ESA DSP register. The other SM Choukyoushi Hitomi games are not affected.)
 
(22 intermediate revisions by 2 users not shown)
Line 8: Line 8:
! Game Name !! VCMD Table Location ($E0 and up) !! ROM Offset
! Game Name !! VCMD Table Location ($E0 and up) !! ROM Offset
|-
|-
| Hong Kong '97 || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x0F800A</tt> (both versions)
| ''Hong Kong '97'' || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x0F800A</tt> (both versions)
|-
|-
| SM Choukyoushi Hitomi - Bangai Hen || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01801C</tt>
| ''SM Choukyoushi Hitomi - Bangai Hen'' || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01801C</tt>
|-
|-
| SM Choukyoushi Hitomi Vol. 2 Trial Version || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01801C</tt>
| ''SM Choukyoushi Hitomi Vol. 2'' Trial Version || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01801C</tt>
|-
|-
| SM Choukyoushi Hitomi Vol. 2 || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x03801C</tt>
| ''SM Choukyoushi Hitomi Vol. 2'' || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x03801C</tt>
|-
|-
| SM Choukyoushi Hitomi Vol. 2 Remix || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01801C</tt>
| ''SM Choukyoushi Hitomi Vol. 2 Remix'' || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01801C</tt>
|-
|-
| SM Choukyoushi Hitomi Vol. 3 Trial Version || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x018058</tt>
| ''SM Choukyoushi Hitomi Vol. 3'' Trial Version || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x018058</tt>
|-
|-
| SM Choukyoushi Hitomi Vol. 3 (Alt 1) || <tt>0x0DF0</tt>, relative to <tt>0x0D30</tt> || <tt>0x018076</tt>
| ''SM Choukyoushi Hitomi Vol. 3'' (Alt 1) || <tt>0x0DF0</tt>, relative to <tt>0x0D30</tt> || <tt>0x018076</tt>
|-
|-
| Wheel of Fortune - Deluxe Edition || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01D842</tt>
| ''Wheel of Fortune - Deluxe Edition'' ''(unused)'' || <tt>0x0DEC</tt>, relative to <tt>0x0D2C</tt> || <tt>0x01D842</tt>
|}
|}
Of the games listed here, two of them are very minor edits...
Of the games listed here, three of them are very minor edits...
* Wheel of Fortune - Deluxe Edition's build is unused and is missing an opcode near the *Ver S1.20* string. In addition, that section is actually unused, because instead new code at $0700 is used to substitute for this one... which happens to be an exact match to the original IPL Boot ROM.
* ''Hong Kong '97'' has a typo in the ESA DSP register setup due to using register ID $FE instead of $6D that is not present in the others.
* SM Choukyoushi Hitomi Vol. 3 (Alt 1)'s program starts with a JMP opcode, and contains a NOP between the first and second opcodes of the actual program.
* ''Wheel of Fortune - Deluxe Edition'''s build is unused and is missing an opcode near the *Ver S1.20* string. In addition, that section is actually unused, because instead new code at $0700 is used to substitute for this one... which happens to be an exact match to the original IPL Boot ROM.
* ''SM Choukyoushi Hitomi Vol. 3'' (Alt 1)'s program starts with a JMP opcode, and contains a NOP between the first and second opcodes of the actual program.


The raw build sorting notes can be found [[N-SPC Engine/Source Variant Build Sorting|here]] (along with all of the other source variant builds that don't have a significant enough difference execution-wise).
The raw build sorting notes can be found [[N-SPC Engine/Source Variant Build Sorting|here]] (along with all of the other source variant builds that don't have a significant enough difference execution-wise).
Line 33: Line 34:
NOTE: This is not representative of every single variant. Instead, it represents the collection of commands from the source code included in the IS-Sound unit, which in turn may be carried over to most variants.
NOTE: This is not representative of every single variant. Instead, it represents the collection of commands from the source code included in the IS-Sound unit, which in turn may be carried over to most variants.


The only register that is used for communication in the source build is $2140 (SNES side)/$F4 (SPC side), except for the load command. Other registers are still read and recorded, just that they don't do anything. When a value is written, it is echoed back after a couple of tempo ticks.
The only register that is used for communication in the source build is $2140 (SNES side)/$F4 (SPC side), except for the load command. Other registers are not even read from, though the code itself sets up the framework to do so.


===Output to the SNES===
<pre>xx ?? ?? ??</pre>
* <tt>xx</tt> is the currently piece of music playing. It takes a couple of tempo ticks for this to echo back after initializing the music.
===Command IDs===
{| class="wikitable sortable"
{| class="wikitable sortable"
|-
|-
Line 68: Line 74:


==Instrument Format==
==Instrument Format==
The instrument format is most commonly defined as direct writes to DSP registers for the first four bytes, followed by two pitch-related bytes. They are defined in this order, from top to bottom...
The instrument format is most commonly defined as direct writes to DSP registers for the first four bytes, followed by two pitch-related bytes. They are defined like this....
* SRCN
<pre>%xyyyyyyy zz aa bb cc dd</pre>
** If this value is above <tt>$7F</tt>, noise is used, and the lowest five bits contains the noise clock rate.
* <tt>%x</tt> is a [[S-DSP/Noise|noise clock]] switch.
* ADSR1
** If set, noise is used and <tt>%??yyyyy</tt> represents the noise clock rate.
* ADSR2
** If cleared, <tt>%0yyyyyyy</tt> is a direct write to the VxSRCN DSP register.
* GAIN
* <tt>zz</tt> is a direct write to the VxADSR1 DSP register.
* Pitch Base Multiplier
* <tt>aa</tt> is a direct write to the VxADSR2 DSP register.
* Pitch Base Fractional Multiplier (in 256ths)
* <tt>bb</tt> is a direct write to the VxGAIN DSP register.
* <tt>cc</tt> is a pitch base multiplier.
* <tt>dd</tt> is a fractional pitch base multiplier, defined in 256ths.


==Phrase Format==
==Phrase Format==
Line 86: Line 94:
|<tt>$00 $00</tt> || End of Song ||
|<tt>$00 $00</tt> || End of Song ||
|-
|-
|<tt>$00 %0xxxxxxx</tt>|| Jump x Times || <tt>%0xxxxxxx yy yy</tt>
|<tt>%0xxxxxxx $00</tt><br><tt>$01-$7F $00</tt>|| Jump x Times || <tt>yy yy</tt>
|-
|-
|<tt>$00 $80</tt> || Fast Forward On ||
|<tt>$80 $00</tt> || Fast Forward On ||
|-
|-
|<tt>$00 $81</tt> || Fast Forward Off ||
|<tt>$81 $00</tt> || Fast Forward Off ||
|-
|-
|<tt>$00 %1???????</tt> || Always Jump || <tt>xx xx</tt>
|<tt>%1??????? $00</tt><br><tt>$82-$FF $00</tt> || Always Jump || <tt>xx xx</tt>
|-
|-
|<tt>xx xx</tt> || Play Pattern || <tt>xx xx</tt>
|<tt>xx xx</tt> || Play Pattern || <tt>xx xx</tt>
Line 99: Line 107:
===Play Pattern===
===Play Pattern===
<pre>xx xx</pre>
<pre>xx xx</pre>
* <tt>xx xx</tt> is a [[little endian]] pointer to a set of eight pointers to track data, one for each channel. If the pointer is zero, there is no track data.
* <tt>xx xx</tt> is a [[little endian]] pointer to a set of eight pointers to track data, one for each channel.


===End of Song===
====Pattern Entry Format====
<pre>xx xx yy yy zz zz aa aa bb bb cc cc dd dd ee ee</pre>
* <tt>xx xx</tt> is a [[little endian]] pointer to a pattern order list for channel 1. If the pointer is zero, there is no track data.
* <tt>yy yy</tt> is a [[little endian]] pointer to a pattern order list for channel 2. If the pointer is zero, there is no track data.
* <tt>zz zz</tt> is a [[little endian]] pointer to a pattern order list for channel 3. If the pointer is zero, there is no track data.
* <tt>aa aa</tt> is a [[little endian]] pointer to a pattern order list for channel 4. If the pointer is zero, there is no track data.
* <tt>bb bb</tt> is a [[little endian]] pointer to a pattern order list for channel 5. If the pointer is zero, there is no track data.
* <tt>cc cc</tt> is a [[little endian]] pointer to a pattern order list for channel 6. If the pointer is zero, there is no track data.
* <tt>dd dd</tt> is a [[little endian]] pointer to a pattern order list for channel 7. If the pointer is zero, there is no track data.
* <tt>ee ee</tt> is a [[little endian]] pointer to a pattern order list for channel 8. If the pointer is zero, there is no track data.
 
===End of Song (Command <tt>$00 $00</tt>)===
<pre>$00 $00</pre>
<pre>$00 $00</pre>
Terminates the song.
Terminates the song.


===Jump x Times===
===Jump x Times (Command <tt>$00 $01-$7F</tt>)===
<pre>$00 %0xxxxxxx yy yy</pre>
<pre>%0xxxxxxx $00 yy yy</pre>
* <tt>xxxxxxx</tt> is the number of times to jump.
* <tt>%xxxxxxx</tt> is the number of times to jump.
* <tt>yy yy</tt> is a [[little endian]] pointer to a phrase to jump to.
* <tt>yy yy</tt> is a [[little endian]] pointer to a phrase to jump to.


===Fast Forward On===
===Fast Forward On (Command <tt>$00 $80</tt>)===
<pre>$00 $80</pre>
<pre>$80 $00</pre>
Fast Forward causes the song to stop playing and the player rapidly progresses throughout the song. Thus, this can effectively act as a skip.
Fast Forward causes the song to stop playing and the player rapidly progresses throughout the song. Thus, this can effectively act as a skip.


===Fast Forward Off===
===Fast Forward Off (Command <tt>$00 $81</tt>)===
<pre>$00 $81</pre>
<pre>$81 $00</pre>
Disables Fast Forward and continues playing the song normally.
Disables Fast Forward and continues playing the song normally.


===Always Jump===
===Always Jump (Command <tt>$00 $82-$FF</tt>)===
<pre>$00 %1??????? xx xx</pre>
<pre>%1??????? $00 xx xx</pre>
Only executes if the fast forward commands are not triggered.
Only executes if the fast forward commands are not triggered.
* <tt>xx xx</tt> is a [[little endian]] pointer to a phrase to jump to.
* <tt>xx xx</tt> is a [[little endian]] pointer to a phrase to jump to.
Line 132: Line 151:


===NOP (VCMD <tt>$FB</tt>)===
===NOP (VCMD <tt>$FB</tt>)===
<pre>$FB ??</pre>
<pre>$FB ?? ??</pre>
Reads a single byte, then does absolutely nothing with the command.
Reads two bytes, then does absolutely nothing with the command.


===Phrase Termination/End of Subroutine (VCMD <tt>$00</tt>)===
===Phrase Termination/End of Subroutine (VCMD <tt>$00</tt>)===
Line 141: Line 160:


===Note Duration (VCMD <tt>$01-$7F</tt>)===
===Note Duration (VCMD <tt>$01-$7F</tt>)===
<pre>%0xxxxxxx (yz)</pre>
<pre>%0xxxxxxx (%0yyyzzzz)</pre>


* <tt>xxxxxxx</tt> represents your note length (as seven bits) in tempo ticks.
* <tt>%xxxxxxx</tt> represents your note length (as seven bits) in tempo ticks.
* <tt>y</tt>, if less than <tt>$8</tt>, defines the quantization. It is an index value to a table of values that indicate, in 256ths, how far along the note to play before keying it off. This table can vary on a per-game basis.
* <tt>%yyy</tt>, if the highest bit of the byte is not set, defines the quantization. It is an index value to a table of values that indicate, in 256ths, how far along the note to play before keying it off. This table can vary on a per-game basis.
* <tt>z</tt>, which is only defined if y is less than <tt>$8</tt>, defines the velocity. It is an index to a table of values that indicate the volume in a decibel-like number (due to the final volume calculation being multiplied by itself at the end). This table can vary on a per-game basis.
* <tt>%zzzz</tt>, which is only defined if the highest bit of the byte is not set, defines the velocity. It is an index to a table of values that indicate the volume in a decibel-like number (due to the final volume calculation being multiplied by itself at the end). This table can vary on a per-game basis.


Notes and/or special VCMDs, by default, are forced after the parameter byte is read. Attempting to use <tt>$00-$7F</tt> again results in an invalid note.
Notes and/or special VCMDs, by default, are forced after the parameter byte is read. Attempting to use <tt>$00-$7F</tt> again results in an invalid note.
Line 170: Line 189:


===Panning (VCMD <tt>$E1</tt>)===
===Panning (VCMD <tt>$E1</tt>)===
<pre>$E1 %xyzzzzz</pre>
<pre>$E1 %xy?zzzzz</pre>
* <tt>x</tt> defines a phase inversion switch for the left channel.
* <tt>%x</tt> defines a phase inversion switch for the left channel.
* <tt>y</tt> defines a phase inversion switch for the right channel.
* <tt>%y</tt> defines a phase inversion switch for the right channel.
* <tt>zzzzz</tt> is five bits for the panning. This refers to an array of values to multiply the volume by after calculating the voice volume via various other parameters set by the VCMDs. Under normal circumstances, center is defined as <tt>$0A</tt> and the maximum value is <tt>$14</tt>.
* <tt>%zzzzz</tt> is five bits for the panning. This refers to an array of values to multiply the volume by after calculating the voice volume via various other parameters set by the VCMDs. Under normal circumstances, center is defined as <tt>$0A</tt> and the maximum value is <tt>$14</tt>.


===Panning Fade (VCMD <tt>$E2</tt>)===
===Panning Fade (VCMD <tt>$E2</tt>)===
Line 222: Line 241:


===Tremolo Off (VCMD <tt>$EC</tt>)===
===Tremolo Off (VCMD <tt>$EC</tt>)===
Disables vibrato set by VCMD <tt>$E3</tt>.
Disables tremolo set by VCMD <tt>$EB</tt>.


===Volume (VCMD <tt>$ED</tt>)===
===Volume (VCMD <tt>$ED</tt>)===
Line 266: Line 285:
===Echo Enable Bits and Volume (VCMD <tt>$F5</tt>)===
===Echo Enable Bits and Volume (VCMD <tt>$F5</tt>)===
<pre>$F5 %xxxxxxxx yy zz</pre>
<pre>$F5 %xxxxxxxx yy zz</pre>
* <tt>xxxxxxxx</tt> defines the channels to turn on for the echo (one per bit), which translates to a direct write to the EON DSP register.
* <tt>%xxxxxxxx</tt> defines the channels to turn on for the echo (one per bit), which translates to a direct write to the EON DSP register.
* <tt>yy</tt> defines a value for EVOLL DSP register.
* <tt>yy</tt> defines a value for EVOLL DSP register.
* <tt>zz</tt> defines a value for EVOLR DSP register.
* <tt>zz</tt> defines a value for EVOLR DSP register.
Line 310: Line 329:
! Game Name !! VCMD Table Location ($E0 and up) !! ROM Offset
! Game Name !! VCMD Table Location ($E0 and up) !! ROM Offset
|-
|-
| Shijou Saikyou no Quiz Ou Ketteisen Super || <tt>0x0DF7</tt>, relative to <tt>0x0D37</tt> || <tt>0x038062</tt>/<tt>0x04805C</tt>/<tt>0x058062</tt>
| ''Shijou Saikyou no Quiz Ou Ketteisen Super'' || <tt>0x0DF7</tt>, relative to <tt>0x0D37</tt> || <tt>0x038062</tt>/<tt>0x04805C</tt>/<tt>0x058062</tt>
|}
|}


The raw build sorting notes can be found [[N-SPC Engine/Source Variant Build Sorting|here]] (along with all of the other source variant builds that don't have a significant enough difference execution-wise).
The raw build sorting notes can be found [[N-SPC Engine/Source Variant Build Sorting|here]] (along with all of the other source variant builds that don't have a significant enough difference execution-wise).


This is the closest match to a standard source N-SPC/Kankichi build used in a licensed game. This is because the only modifications made to it are to echo what was sent to $2140/$F4 to $2141/$F5 (keeping the music ID being played in $2140/$F4) and zero out $2140/$F4 when the song is done playing when a zero pointer is read from a phase.
This is the closest match to a standard source N-SPC/Kankichi build used in a licensed game. This is because the only modifications made to it are to echo what was sent to any register to $2141/$F5 (although in practice only $2140/$F4 is read from, thus de facto giving it the same output, otherwise it would be cycling between the last register read code-wise as output) and zero out both $2140/$F4 and $2141/$F5 when the song is done playing when a zero pointer is read from a phase.
 
====Output to the SNES====
<pre>xx yy ?? ??</pre>
* <tt>xx</tt> is the currently piece of music playing. It takes a couple of tempo ticks for this to echo back after initializing the music.
* <tt>yy</tt> is a de-facto mirror of <tt>xx</tt> output-wise. The feedback is a little faster, though, since the output is immediately upon $2140/$F4 being read, rather than when the music is initialized.


===Controller Test/World Class Service Super Nintendo Tester===
===Controller Test/World Class Service Super Nintendo Tester===
Line 333: Line 357:
===Subpages===
===Subpages===
{{Subpages}}
{{Subpages}}
Not created yet...
* [[N-SPC Engine/64WD Creation|64WD Creation]]
* [[N-SPC Engine/Advance Communication|Advance Communication]]
* [[N-SPC Engine/Aisystem Tokyo|Aisystem Tokyo]]
* [[N-SPC Engine/Argonaut|Argonaut]]
* [[N-SPC Engine/Axes Art Amuse|Axes Art Amuse]]
* [[N-SPC Engine/Bit Managers|Bit Managers]]
* [[N-SPC Engine/Capcom|Capcom]]
* [[N-SPC Engine/Chatnoir|Chatnoir]]
* [[N-SPC Engine/Chip Level Designs|Chip Level Designs]]
* [[N-SPC Engine/CP.BRAiN|CP.BRAiN]]
* [[N-SPC Engine/Cream|Cream]]
* [[N-SPC Engine/Crosstalk|Crosstalk]]
* [[N-SPC Engine/Cube|Cube]]
* [[N-SPC Engine/CUE|CUE]]
* [[N-SPC Engine/Culture Brain|Culture Brain]]
* [[N-SPC Engine/Daft|Daft]]
* [[N-SPC Engine/Data East|Data East]]
* [[N-SPC Engine/EJ Corporation|EJ Corporation]]
* [[N-SPC Engine/Electronic Arts|Electronic Arts]]
* [[N-SPC Engine/Falcom|Falcom]]
* [[N-SPC Engine/Funcom|Funcom]]
* [[N-SPC Engine/Gremlin|Gremlin]]
* [[N-SPC Engine/HAL|HAL]]
* [[N-SPC Engine/Hanari Exp|Hanari Exp]]
* [[N-SPC Engine/Hect|Hect]]
* [[N-SPC Engine/Hikoshi Hashimoto|Hikoshi Hashimoto]]
* [[N-SPC Engine/Home Data|Home Data]]
* [[N-SPC Engine/Human (earlier)|Human (earlier)]]
* [[N-SPC Engine/Human|Human]]
* [[N-SPC Engine/Imagesoft|Imagesoft]]
* [[N-SPC Engine/Infogrames|Infogrames]]
* [[N-SPC Engine/Intelligent Systems|Intelligent Systems]]
* [[N-SPC Engine/Japan Art Media|Japan Art Media]]
* [[N-SPC Engine/Jorudan|Jorudan]]
* [[N-SPC Engine/Kazuo Sawa|Kazuo Sawa]]
* [[N-SPC Engine/Kennosuke Suemura|Kennosuke Suemura]]
* [[N-SPC Engine/Khaos|Khaos]]
* [[N-SPC Engine/Koei|Koei]]
* [[N-SPC Engine/Konami|Konami]]
* [[N-SPC Engine/LaserSoft|LaserSoft]]
* [[N-SPC Engine/Make Software|Make Software]]
* [[N-SPC Engine/Metro|Metro]]
* [[N-SPC Engine/Mitsuhito Tanaka|Mitsuhito Tanaka]]
* [[N-SPC Engine/Monolith|Monolith]]
* [[N-SPC Engine/MSQ|MSQ]]
* [[N-SPC Engine/Namco|Namco]]
* [[N-SPC Engine/Naohisa Morota|Naohisa Morota]]
* [[N-SPC Engine/Natsume|Natsume]]
* [[N-SPC Engine/Nichibutsu or Make Software|Nichibutsu/Make Software]] (NOTE: Refers to three of the Super Nichibutsu Mahjong games)
* [[N-SPC Engine/Nova|Nova]]
* [[N-SPC Engine/Ocean|Ocean]]
* [[N-SPC Engine/Pure Sound|Pure Sound]]
* [[N-SPC Engine/Quest|Quest]]
* [[N-SPC Engine/Quintet|Quintet]]
* [[N-SPC Engine/Robert C. Ashworth|Robert C. Ashworth]]
* [[N-SPC Engine/Sakata SAS|Sakata SAS]]
* [[N-SPC Engine/Saurus|Saurus]]
* [[N-SPC Engine/Sunsoft|Sunsoft]]
* [[N-SPC Engine/Syscom|Syscom]]
* [[N-SPC Engine/System Sacom|System Sacom]]
* [[N-SPC Engine/Systemsoft|Systemsoft]]
* [[N-SPC Engine/T's Music|T's Music]]
* [[N-SPC Engine/TamTam|TamTam]]
* [[N-SPC Engine/Team X-Fade|Team X-Fade]]
* [[N-SPC Engine/Technos Japan|Technos Japan]]
* [[N-SPC Engine/Technosoft|Technosoft]]
* [[N-SPC Engine/Tecmo|Tecmo]]
* [[N-SPC Engine/Tose|Tose]]
* [[N-SPC Engine/Tsukasa Masuko|Tsukasa Masuko]]
* [[N-SPC Engine/Virgin|Virgin]]
* [[N-SPC Engine/Wave|Wave]]
* [[N-SPC Engine/Yoshikazu Yao|Yoshikazu Yao]]
* [[N-SPC Engine/Yoshiyuki Ishii|Yoshiyuki Ishii]]


''TODO: There are a lot of variants... these will be split into sub-pages depending on the modifications made''
''TODO: There are a lot of variants... these will be split into sub-pages depending on the modifications made''
Line 342: Line 441:
* [http://gdri.smspower.org/wiki/index.php/Super_Famicom/Super_NES_Sound_Driver_List GDRI - Super Famicom/Super NES Sound Driver List]
* [http://gdri.smspower.org/wiki/index.php/Super_Famicom/Super_NES_Sound_Driver_List GDRI - Super Famicom/Super NES Sound Driver List]
* [https://github.com/vgmtrans/vgmtrans/issues/173 Github - N-SPC VCMD $FB-$FE identifications]
* [https://github.com/vgmtrans/vgmtrans/issues/173 Github - N-SPC VCMD $FB-$FE identifications]
* [https://archive.org/details/GameBoyProgManVer1.1/page/n187/mode/2up Game Boy Development Manual - Super Game Boy Sound] (see pages 187-213)


[[Category:SPC Sound Engines]]
[[Category:SPC Sound Engines]]

Latest revision as of 19:48, 9 January 2024

Nintendo SPC Sound Engine, abbreviated N-SPC and officially known as Kankichi-kun [1], is the most common sound engine used in all of the SNES/SFC games. Only the music portion was initially provided in the source code included in the IS-Sound unit along with some templating for a protocol for music and sound effects [2]: usually it was modified by developers on an individual basis, resulting in many different variants, some of them more heavily modifying the sound driver than others. Usually what was added on was sound effect support, but sometimes the music VCMDs were modified as well.

The following games are purely based off of the source code provided with the IS-Sound unit, and are either unmodified or barely modified, if at all:

Game Name VCMD Table Location ($E0 and up) ROM Offset
Hong Kong '97 0x0DEC, relative to 0x0D2C 0x0F800A (both versions)
SM Choukyoushi Hitomi - Bangai Hen 0x0DEC, relative to 0x0D2C 0x01801C
SM Choukyoushi Hitomi Vol. 2 Trial Version 0x0DEC, relative to 0x0D2C 0x01801C
SM Choukyoushi Hitomi Vol. 2 0x0DEC, relative to 0x0D2C 0x03801C
SM Choukyoushi Hitomi Vol. 2 Remix 0x0DEC, relative to 0x0D2C 0x01801C
SM Choukyoushi Hitomi Vol. 3 Trial Version 0x0DEC, relative to 0x0D2C 0x018058
SM Choukyoushi Hitomi Vol. 3 (Alt 1) 0x0DF0, relative to 0x0D30 0x018076
Wheel of Fortune - Deluxe Edition (unused) 0x0DEC, relative to 0x0D2C 0x01D842

Of the games listed here, three of them are very minor edits...

  • Hong Kong '97 has a typo in the ESA DSP register setup due to using register ID $FE instead of $6D that is not present in the others.
  • Wheel of Fortune - Deluxe Edition's build is unused and is missing an opcode near the *Ver S1.20* string. In addition, that section is actually unused, because instead new code at $0700 is used to substitute for this one... which happens to be an exact match to the original IPL Boot ROM.
  • SM Choukyoushi Hitomi Vol. 3 (Alt 1)'s program starts with a JMP opcode, and contains a NOP between the first and second opcodes of the actual program.

The raw build sorting notes can be found here (along with all of the other source variant builds that don't have a significant enough difference execution-wise).

Communication with the SNES

NOTE: This is not representative of every single variant. Instead, it represents the collection of commands from the source code included in the IS-Sound unit, which in turn may be carried over to most variants.

The only register that is used for communication in the source build is $2140 (SNES side)/$F4 (SPC side), except for the load command. Other registers are not even read from, though the code itself sets up the framework to do so.

Output to the SNES

xx ?? ?? ??
  • xx is the currently piece of music playing. It takes a couple of tempo ticks for this to echo back after initializing the music.

Command IDs

Command ID Description Register Values & Arguments
$00 Stop Music $00 ?? ?? ??
$01-?? Play Music xx ?? ?? ??
$F0 Pause Music $F0 ?? ?? ??
$F1 Continue Music $F1 ?? ?? ??
$FF Load New Data $FF ?? xx xx

Stop Music (Command $00)

Initializes an invalid phrase pointer, then stops the previous piece of music. This is not compatible with the resume command, as it is irrevocable, unlike the other one.

Play Music (Command $01-??)

Stops a previous piece of music, then plays a piece of music by the ID specified in the command.

Pause Music (Command $F0)

Stops music, allowing it to be resumed later.

Continue Music (Command $F1)

Resumes a paused song.

Load New Data (Command $FF)

Jumps to a modified copy of the IPL Boot ROM (except for Wheel of Fortune - Deluxe Edition, where there is an opcode missing, the jump location is different, and it contains an exact copy of the IPL Boot ROM).

TODO Loading New Data (the loading protocol is nearly identical to IPL Boot ROM, with a couple of differences)

Instrument Format

The instrument format is most commonly defined as direct writes to DSP registers for the first four bytes, followed by two pitch-related bytes. They are defined like this....

%xyyyyyyy zz aa bb cc dd
  • %x is a noise clock switch.
    • If set, noise is used and %??yyyyy represents the noise clock rate.
    • If cleared, %0yyyyyyy is a direct write to the VxSRCN DSP register.
  • zz is a direct write to the VxADSR1 DSP register.
  • aa is a direct write to the VxADSR2 DSP register.
  • bb is a direct write to the VxGAIN DSP register.
  • cc is a pitch base multiplier.
  • dd is a fractional pitch base multiplier, defined in 256ths.

Phrase Format

Song entries, stored as little endian pointers, point to a list of phrases for the song to play.

Command ID Description Arguments
$00 $00 End of Song
%0xxxxxxx $00
$01-$7F $00
Jump x Times yy yy
$80 $00 Fast Forward On
$81 $00 Fast Forward Off
%1??????? $00
$82-$FF $00
Always Jump xx xx
xx xx Play Pattern xx xx

Play Pattern

xx xx
  • xx xx is a little endian pointer to a set of eight pointers to track data, one for each channel.

Pattern Entry Format

xx xx yy yy zz zz aa aa bb bb cc cc dd dd ee ee
  • xx xx is a little endian pointer to a pattern order list for channel 1. If the pointer is zero, there is no track data.
  • yy yy is a little endian pointer to a pattern order list for channel 2. If the pointer is zero, there is no track data.
  • zz zz is a little endian pointer to a pattern order list for channel 3. If the pointer is zero, there is no track data.
  • aa aa is a little endian pointer to a pattern order list for channel 4. If the pointer is zero, there is no track data.
  • bb bb is a little endian pointer to a pattern order list for channel 5. If the pointer is zero, there is no track data.
  • cc cc is a little endian pointer to a pattern order list for channel 6. If the pointer is zero, there is no track data.
  • dd dd is a little endian pointer to a pattern order list for channel 7. If the pointer is zero, there is no track data.
  • ee ee is a little endian pointer to a pattern order list for channel 8. If the pointer is zero, there is no track data.

End of Song (Command $00 $00)

$00 $00

Terminates the song.

Jump x Times (Command $00 $01-$7F)

%0xxxxxxx $00 yy yy
  • %xxxxxxx is the number of times to jump.
  • yy yy is a little endian pointer to a phrase to jump to.

Fast Forward On (Command $00 $80)

$80 $00

Fast Forward causes the song to stop playing and the player rapidly progresses throughout the song. Thus, this can effectively act as a skip.

Fast Forward Off (Command $00 $81)

$81 $00

Disables Fast Forward and continues playing the song normally.

Always Jump (Command $00 $82-$FF)

%1??????? $00 xx xx

Only executes if the fast forward commands are not triggered.

Voice Command Format

NOTE: This is not representative of every single variant. Instead, it represents the collection of VCMDs from the source code included in the IS-Sound unit, which in turn is carried over to most variants.

VCMD ID Description Arguments
$00 Phrase Termination/End of Subroutine
$01-$7F Note Duration (%0yyyzzzz)
$80-$C7 Note
$C8 Tie
$C9 Rest
$CA-$DF Percussion
$E0 Instrument xx
$E1 Panning %xy?zzzzz
$E2 Panning Fade xx yy
$E3 Vibrato On xx yy zz
$E4 Vibrato Off
$E5 Song Volume xx
$E6 Song Volume Fade xx yy zz
$E7 Tempo xx
$E8 Tempo Fade xx yy
$E9 Global Absolute Transposition xx
$EA Single Channel Absolute Transposition xx
$EB Tremolo On xx yy zz
$EC Tremolo Off
$ED Volume xx
$EE Volume Fade xx yy
$EF Subroutine xx xx yy
$F0 Vibrato Fade In xx
$F1 Note Pitch Envelope To xx yy zz
$F2 Note Pitch Envelope From xx yy zz
$F3 Note Pitch Envelope Off
$F4 Fine Tune xx
$F5 Echo Enable Bits and Volume %xxxxxxxx yy zz
$F6 Echo Off
$F7 Echo Parameter Setup xx yy zz
$F8 Echo Volume Fade xx yy zz
$F9 Pitch Slide to Note xx yy zz
$FA Percussion Base Instrument ID Redefine xx
$FB NOP ?? ??
$FC Channel Mute
$FD Fast Forward On
$FE Fast Forward Off
$FF Invalid

Invalid (VCMD $FF)

Crashes the sound driver due to being outside of the array of pointers, and thus jumping to an invalid pointer.

NOP (VCMD $FB)

$FB ?? ??

Reads two bytes, then does absolutely nothing with the command.

Phrase Termination/End of Subroutine (VCMD $00)

This VCMD's operation depends on whether or not it is inside a subroutine or not. If it is inside a subroutine, it exits the subroutine and song execution continues. Otherwise, the phrase is terminated. This affects all channels in the music: any other channels still playing are interrupted.

Note Duration (VCMD $01-$7F)

%0xxxxxxx (%0yyyzzzz)
  • %xxxxxxx represents your note length (as seven bits) in tempo ticks.
  • %yyy, if the highest bit of the byte is not set, defines the quantization. It is an index value to a table of values that indicate, in 256ths, how far along the note to play before keying it off. This table can vary on a per-game basis.
  • %zzzz, which is only defined if the highest bit of the byte is not set, defines the velocity. It is an index to a table of values that indicate the volume in a decibel-like number (due to the final volume calculation being multiplied by itself at the end). This table can vary on a per-game basis.

Notes and/or special VCMDs, by default, are forced after the parameter byte is read. Attempting to use $00-$7F again results in an invalid note.

Note (VCMD $80-$C7)

Plays a note and delays the channel for one note length before reading another VCMD.

Tie (VCMD $C8)

Continues playing the previous note and delays the channel for one note length before reading another VCMD.

Rest (VCMD $C9)

Keys off the previous note and delays the channel for one note length before reading another VCMD.

Percussion (VCMD $CA-$DF)

Plays a percussion note.

By default, percussion uses the same instrument set as the song, and all percussion is keyed on with a note of $A4. The starting ID to use for all channels can be redefined by VCMD $FA.

Instrument (VCMD $E0)

$E0 xx
  • xx is an instrument ID to an array of instruments. See Instrument Format above for the format.

Panning (VCMD $E1)

$E1 %xy?zzzzz
  • %x defines a phase inversion switch for the left channel.
  • %y defines a phase inversion switch for the right channel.
  • %zzzzz is five bits for the panning. This refers to an array of values to multiply the volume by after calculating the voice volume via various other parameters set by the VCMDs. Under normal circumstances, center is defined as $0A and the maximum value is $14.

Panning Fade (VCMD $E2)

$E2 xx yy
  • xx defines the number of tempo ticks to fade for.
  • yy is the target pan value. Phase inversion is not taken into account here, thus only the low five bits should be used here.

Vibrato On (VCMD $E3)

$E3 xx yy zz
  • xx is the number of tempo ticks to delay the vibrato for.
  • yy is the rate of the vibrato: specifically, how much to change the pitch on a per-tempo tick basis.
  • zz is the depth of the vibrato: that is, the maximum pitch offset to use. $00-$F0 are normal, but $F1 and up act more like said value ANDed by $0F and multiplied by $0100, meaning the highest values have drastic differences compared to the lower ones.

Vibrato Off (VCMD $E4)

Disables vibrato set by VCMD $E3.

Song Volume (VCMD $E5)

$E5 xx
  • xx is the song volume value. This sets the volume for all of the channels in the song. The value used is a decibel-like value due to the final volume being multiplied by itself to get the final result.

Song Volume Fade (VCMD $E6)

$E6 xx yy
  • xx defines the number of tempo ticks to fade for.
  • yy is the target song volume.

Tempo (VCMD $E7)

$E7 xx
  • xx defines one tempo tick as one timer 0 tick multiplied by . Zero freezes the song.

Tempo Fade (VCMD $E8)

$E8 xx yy
  • xx defines the number of tempo ticks to fade for.
  • yy is the target tempo.

Global Absolute Transposition (VCMD $E9)

$E9 xx
  • xx is a signed value defining the number of semitones to transpose subsequent notes. Note that this affects all channels, not just one channel.

Single Channel Absolute Transposition (VCMD $EA)

$EA xx
  • xx is a signed value defining the number of semitones to transpose subsequent notes.

Tremolo On (VCMD $EB)

$EB xx yy zz
  • xx is the number of tempo ticks to delay the tremolo for.
  • yy is the rate of the tremolo: specifically, how much to change the volume on a per-tempo tick basis.
  • zz is the depth of the tremolo: that is, the maximum volume offset to use.

Tremolo Off (VCMD $EC)

Disables tremolo set by VCMD $EB.

Volume (VCMD $ED)

$ED xx
  • xx is the volume value. The value used is a decibel-like value due to the final volume being multiplied by itself to get the final result.

Volume Fade (VCMD $EE)

$EE xx yy
  • xx defines the number of tempo ticks to fade for.
  • yy is the target volume.

Subroutine (VCMD $EF)

$EF xx xx yy
  • xx xx is a little endian pointer containing the section of music to play.
  • yy is the number of times to loop the sub-routine.

Vibrato Fade In (VCMD $F0)

$F0 xx
  • xx is the number of tempo ticks to fade the vibrato for.

The moment this VCMD is executed, the depth is faded in from zero.

Note Pitch Envelope To (VCMD $F1)

$F1 xx yy zz

This VCMD is applied to all subsequent notes until turned off or overwritten.

  • xx is the number of tempo ticks to delay before applying the pitch envelope.
  • yy is the length of the pitch slide in tempo ticks.
  • zz is a signed offset in semitones to slide the note to.

Note Pitch Envelope From (VCMD $F2)

$F2 xx yy zz

This VCMD is applied to all subsequent notes until turned off or overwritten.

  • xx is the number of tempo ticks to delay before applying the pitch envelope.
  • yy is the length of the pitch slide in tempo ticks.
  • zz is a signed offset in semitones to slide the note from: that is, unlike Note Pitch Envelope To (VCMD $F1), this is a starting note offset, rather than an end of pitch envelope note offset.

Note Pitch Envelope Off (VCMD $F3)

Disables a pitch envelope.

Fine Tune (VCMD $F4)

$F4 xx
  • xx defines the amount to shift the pitch up. This is in 256ths of a semitone, albeit done via measuring the distance between note and multiplying it by this value.

Echo Enable Bits and Volume (VCMD $F5)

$F5 %xxxxxxxx yy zz
  • %xxxxxxxx defines the channels to turn on for the echo (one per bit), which translates to a direct write to the EON DSP register.
  • yy defines a value for EVOLL DSP register.
  • zz defines a value for EVOLR DSP register.

Echo Off (VCMD $F6)

This disables echo for all channels, as well as zeroing out the echo volume and disabling echo writes.

Echo Parameter Setup (VCMD $F7)

$F7 xx yy zz
  • xx defines a value for the EDL DSP register.
  • yy defines a value for the EFB DSP register.
  • zz defines an ID to an array of FIR coefficient values.

Echo Volume Fade (VCMD $F8)

$F8 xx yy zz
  • xx defines the number of tempo ticks to fade for.
  • yy defines the target value for EVOLL DSP register.
  • zz defines the target value for EVOLR DSP register.

Pitch Slide To Note (VCMD $F9)

$F9 xx yy zz
  • xx defines the number of tempo ticks to delay the slide for.
  • yy defines the length of the pitch slide in tempo ticks.
  • zz is the target note.

Percussion Base Instrument ID Redefine (VCMD $FA)

$FA xx
  • xx is the starting instrument ID. Note that this affects all channels.

Channel Mute (VCMD $FC)

Causes the channel to not key on subsequent notes.

Fast Forward On (VCMD $FD)

Fast Forward causes the song to stop playing and the player rapidly progresses throughout the song. Thus, this can effectively act as a skip.

Fast Forward Off (VCMD $FE)

Disables Fast Forward and continues playing the song normally.

Variants

Shijou Saikyou no Quiz Ou Ketteisen Super

Game Name VCMD Table Location ($E0 and up) ROM Offset
Shijou Saikyou no Quiz Ou Ketteisen Super 0x0DF7, relative to 0x0D37 0x038062/0x04805C/0x058062

The raw build sorting notes can be found here (along with all of the other source variant builds that don't have a significant enough difference execution-wise).

This is the closest match to a standard source N-SPC/Kankichi build used in a licensed game. This is because the only modifications made to it are to echo what was sent to any register to $2141/$F5 (although in practice only $2140/$F4 is read from, thus de facto giving it the same output, otherwise it would be cycling between the last register read code-wise as output) and zero out both $2140/$F4 and $2141/$F5 when the song is done playing when a zero pointer is read from a phase.

Output to the SNES

xx yy ?? ??
  • xx is the currently piece of music playing. It takes a couple of tempo ticks for this to echo back after initializing the music.
  • yy is a de-facto mirror of xx output-wise. The feedback is a little faster, though, since the output is immediately upon $2140/$F4 being read, rather than when the music is initialized.

Controller Test/World Class Service Super Nintendo Tester

Game Name VCMD Table Location ($E0 and up) ROM Offset
Controller Test 0x0DEC, relative to 0x0D2C 0x009319 (Controller Test Cassette)
0x00BFFF (SNES Burn-In Test Cartridge)
0x00D8D2 (World Class Service Super Nintendo Tester (not used))
World Class Service Super Nintendo Tester (only build used across all tests) 0x0DEC, relative to 0x0D2C 0x0B8068

The raw build sorting notes can be found here (along with all of the other source variant builds that don't have a significant enough difference execution-wise).

These two sound driver builds (the one for the controller test being found in three different known testing cartridges, with one of them not used) merely have code optimizations in their sound code, thus making them completely identical execution-wise to the source build variant. In addition, the build used for World Class Service Super Nintendo Tester adds a BMI opcode in a readahead routine, but is otherwise identical.

Subpages

Not created yet...

TODO: There are a lot of variants... these will be split into sub-pages depending on the modifications made

References