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/Kemco: Difference between revisions

From SnesLab
Jump to: navigation, search
(Adding alternative way to interpret volume operation commands for V3.0-V3.1 only)
(Master Volume -> Main Volume)
 
(2 intermediate revisions by the same user not shown)
Line 3: Line 3:
__TOC__
__TOC__


Kemco is the first company outside of Nintendo themselves to release a game using their own variant of N-SPC (that being Bombuzal). The main customization that they did was to have the CPUIO registers play sounds on specific channels, and only the channels on the phrase list specified to be used by the corresponding CPUIO register would be used. One other CPUIO register was allocated mainly to perform volume fades.
Kemco is the first company outside of Nintendo themselves to release a game using their own variant of N-SPC (that being Bombuzal). The main customization that they did was to have the CPUIO registers play sounds on specific channels, and only the channels on the phrase list specified to be used by the corresponding CPUIO register would be used. All non-music CPUIO registers, when processing phrase data, also did not support the fast forward phrase commands. One other CPUIO register was allocated mainly to perform volume fades.


{| class="wikitable sortable"
{| class="wikitable sortable"
Line 80: Line 80:
! Command ID !! Description
! Command ID !! Description
|-
|-
|<tt>$00-$9F</tt> || Acknowledge
|<tt>$00-$9F</tt> || Pause Volume Operations + Acknowledge
|-
|-
|<tt>$A0</tt> || Halt Volume Operations (Channels 1-6)
|<tt>$A0</tt> || Reset Volume Operations (Channels 1-6)
|-
|-
|<tt>$A1</tt> || Fade Out (Channels 1-6)
|<tt>$A1</tt> || Fade Out (Channels 1-6)
Line 92: Line 92:
|<tt>$A4</tt> || Volume Restore (Channels 7-8)
|<tt>$A4</tt> || Volume Restore (Channels 7-8)
|-
|-
|<tt>$A5</tt> || Halt Volume Operations (Channels 7-8)
|<tt>$A5</tt> || Reset Volume Operations (Channels 7-8)
|-
|-
|<tt>$A6</tt> || Fade Out (Channels 7-8)
|<tt>$A6</tt> || Fade Out (Channels 7-8)
Line 102: Line 102:
|<tt>$A9</tt> || Volume Restore (Channels 7-8)
|<tt>$A9</tt> || Volume Restore (Channels 7-8)
|-
|-
|<tt>$AA-$FF</tt> || Acknowledge
|<tt>$AA-$FF</tt> || Pause Volume Operations + Acknowledge
|}
|}
====Commands (V3.0-V4.0)====
====Commands (V3.0-V4.0)====
Line 109: Line 109:
! Command ID !! Description !! Versions Supported
! Command ID !! Description !! Versions Supported
|-
|-
|<tt>$00-$7F</tt> || Acknowledge ||  
|<tt>$00-$7F</tt> || Pause Volume Operations + Acknowledge ||  
|-
|-
|<tt>$80</tt> || Halt Volume Operations (Channels 1-6) || V3.0-V3.1
|<tt>$80</tt> || Reset Volume Operations (Channels 1-6) || V3.0-V3.1
|-
|-
|<tt>$81</tt> || Fade Out (Channels 1-6) || V3.0-V3.1
|<tt>$81</tt> || Fade Out (Channels 1-6) || V3.0-V3.1
Line 121: Line 121:
|<tt>$84</tt> || Volume Restore (Channels 1-6) || V3.0-V3.1
|<tt>$84</tt> || Volume Restore (Channels 1-6) || V3.0-V3.1
|-
|-
|<tt>$85-$9F</tt> || Acknowledge ||
|<tt>$85-$9F</tt> || Pause Volume Operations + Acknowledge ||
|-
|-
|<tt>$A0</tt> || Halt Volume Operations (Channels 7-8) || V3.0-V3.1
|<tt>$A0</tt> || Reset Volume Operations (Channels 7-8) || V3.0-V3.1
|-
|-
|<tt>$A1</tt> || Fade Out (Channels 7-8) || V3.0-V3.1
|<tt>$A1</tt> || Fade Out (Channels 7-8) || V3.0-V3.1
Line 133: Line 133:
|<tt>$A4</tt> || Volume Restore (Channels 7-8) || V3.0-V3.1
|<tt>$A4</tt> || Volume Restore (Channels 7-8) || V3.0-V3.1
|-
|-
|<tt>$A5-$DF</tt> || Acknowledge ||  
|<tt>$A5-$DF</tt> || Pause Volume Operations + Acknowledge ||  
|-
|-
|<tt>$E0</tt> || Halt Volume Operations (Master Volume) || V3.0-V4.0
|<tt>$E0</tt> || Reset Volume Operations (Main Volume) || V3.0-V4.0
|-
|-
|<tt>$E1</tt> || Fade Out (Master Volume) || V3.0-V4.0
|<tt>$E1</tt> || Fade Out (Main Volume) || V3.0-V4.0
|-
|-
|<tt>$E2</tt> || Fade In (Master Volume) || V3.0-V4.0
|<tt>$E2</tt> || Fade In (Main Volume) || V3.0-V4.0
|-
|-
|<tt>$E3</tt> || Zero Volume (Master Volume) || V3.0-V4.0
|<tt>$E3</tt> || Zero Volume (Main Volume) || V3.0-V4.0
|-
|-
|<tt>$E4</tt> || Volume Restore (Master Volume) || V3.0-V4.0
|<tt>$E4</tt> || Volume Restore (Main Volume) || V3.0-V4.0
|-
|-
|<tt>$E5-$FF</tt> || Acknowledge ||
|<tt>$E5-$FF</tt> || Pause Volume Operations + Acknowledge ||
|}
|}


Line 151: Line 151:
<pre>%1yyxxxxx</pre>
<pre>%1yyxxxxx</pre>
* <tt>%xxxxx</tt> is a command ID. The commands are as following...
* <tt>%xxxxx</tt> is a command ID. The commands are as following...
** <tt>%00000</tt> (<tt>$00</tt>) - Halt Volume Operations
** <tt>%00000</tt> (<tt>$00</tt>) - Reset Volume Operations
** <tt>%00001</tt> (<tt>$01</tt>) - Fade Out
** <tt>%00001</tt> (<tt>$01</tt>) - Fade Out
** <tt>%00010</tt> (<tt>$02</tt>) - Fade In
** <tt>%00010</tt> (<tt>$02</tt>) - Fade In
** <tt>%00011</tt> (<tt>$03</tt>) - Zero Volume
** <tt>%00011</tt> (<tt>$03</tt>) - Zero Volume
** <tt>%00100</tt> (<tt>$04</tt>) - Volume Restore
** <tt>%00100</tt> (<tt>$04</tt>) - Volume Restore
** Any other value (<tt>$05-$1F</tt>) - Acknowledge
** Any other value (<tt>$05-$1F</tt>) - Pause Volume Operations + Acknowledge
* <tt>%yy</tt> defines what will be affected by the command. The values are...
* <tt>%yy</tt> defines what will be affected by the command. The values are...
** <tt>%00</tt> (<tt>$0</tt>) - Channels 1-6
** <tt>%00</tt> (<tt>$0</tt>) - Channels 1-6
** <tt>%01</tt> (<tt>$1</tt>) - Channels 7-8
** <tt>%01</tt> (<tt>$1</tt>) - Channels 7-8
** <tt>%10</tt> (<tt>$2</tt>) - Invalid (causes all values to merely acknowledge)
** <tt>%10</tt> (<tt>$2</tt>) - Invalid (causes all values to merely acknowledge)
** <tt>%11</tt> (<tt>$3</tt>) - Master Volume
** <tt>%11</tt> (<tt>$3</tt>) - Main Volume


====Acknowledge====
====Pause Volume Operations + Acknowledge====
Merely echoes back the value you just sent to $2143/$F7.
Echoes back the value you just sent to $2143/$F7. All volume operations are also paused, which includes fades, since the register is constantly polled.


====Halt Volume Operations====
====Reset Volume Operations====
The command ID used depends on the version...<br>
The command ID used depends on the version...<br>
<u>Channels 1-6</u>
<u>Channels 1-6</u>
Line 174: Line 174:
* V1.0: <tt>$A5</tt>
* V1.0: <tt>$A5</tt>
* V3.0-V3.1: <tt>$A0</tt>
* V3.0-V3.1: <tt>$A0</tt>
<u>Master Volume</u>
<u>Main Volume</u>
* V3.0-V4.0: <tt>$E0</tt>
* V3.0-V4.0: <tt>$E0</tt>


This command halts all volume-related operation. The effect is most noticeable on fades. $2143/$F7 outputs a zero.
This command resets all volume-related operations, specifically by resetting the flags that they were triggered for the first time. This also pauses fades. $2143/$F7 outputs a zero.


====Fade Out====
====Fade Out====
Line 187: Line 187:
* V1.0: <tt>$A6</tt>
* V1.0: <tt>$A6</tt>
* V3.0-V3.1: <tt>$A1</tt>
* V3.0-V3.1: <tt>$A1</tt>
<u>Master Volume</u>
<u>Main Volume</u>
* V3.0-V4.0: <tt>$E1</tt>
* V3.0-V4.0: <tt>$E1</tt>


Fades out the volume to 0. On V1.0, this is done at a rate of 3 per tempo tick: on other versions, it's 1 per tempo tick. On V3.0 and later, the original volume value is saved. $2143/$F7 outputs the current volume value of the last channel in the set (or the intended right echo volume value in the master volume's case).<br>
Fades out the volume to 0. On V1.0, this is done at a rate of 3 per tempo tick: on other versions, it's 1 per tempo tick. On V3.0 and later, the original volume value is saved. $2143/$F7 outputs the current volume value of the last channel in the set (or the intended right echo volume value in the main volume's case).<br>
The command does not properly function past V1.0 for channels 1-6. Technically it still works, but a wrong branching location causes the channel ID to use (and the number of channels to copy) to not be initialized properly, which causes the volume values to not be saved.
The command does not properly function past V1.0 for channels 1-6. Technically it still works, but a wrong branching location causes the channel ID to use (and the number of channels to copy) to not be initialized properly, which causes the volume values to not be saved.


Line 201: Line 201:
* V1.0: <tt>$A7</tt>
* V1.0: <tt>$A7</tt>
* V3.0-V3.1: <tt>$A2</tt>
* V3.0-V3.1: <tt>$A2</tt>
<u>Master Volume</u>
<u>Main Volume</u>
* V3.0-V4.0: <tt>$E2</tt>
* V3.0-V4.0: <tt>$E2</tt>


Fades in the volume to the original volume at a rate of 1 per tempo tick. If no value was saved beforehand, this can overflow back to zero. $2143/$F7 outputs the current volume value of the last channel in the set (or the intended right echo volume value in the master volume's case).
Fades in the volume to the original volume at a rate of 1 per tempo tick. If no value was saved beforehand, this can overflow back to zero. $2143/$F7 outputs the current volume value of the last channel in the set (or the intended right echo volume value in the main volume's case).


====Zero Volume====
====Zero Volume====
Line 214: Line 214:
* V1.0: <tt>$A8</tt>
* V1.0: <tt>$A8</tt>
* V3.0-V3.1: <tt>$A3</tt>
* V3.0-V3.1: <tt>$A3</tt>
<u>Master Volume</u>
<u>Main Volume</u>
* V3.0-V4.0: <tt>$E3</tt>
* V3.0-V4.0: <tt>$E3</tt>


Zeroes out the volume, saving the original volume for restoration later on. $2143/$F7 outputs the current volume value (or the intended right echo volume value in the master volume's case) for one tempo tick, then a $01 (or, for the master volume, always outputs a zero).<br>
Zeroes out the volume, saving the original volume for restoration later on. Unless this is done on the main volume, you must reset volume operations to use this command again. $2143/$F7 outputs the current volume value (or the intended right echo volume value in the main volume's case) for one tempo tick, then a $01 (or, for the main volume, always outputs a zero).<br>
The command does not properly function past V1.0 for channels 1-6 due to a wrong branching location.
The command does not properly function past V1.0 for channels 1-6 due to a wrong branching location.


Line 228: Line 228:
* V1.0: <tt>$A9</tt>
* V1.0: <tt>$A9</tt>
* V3.0-V3.1: <tt>$A4</tt>
* V3.0-V3.1: <tt>$A4</tt>
<u>Master Volume</u>
<u>Main Volume</u>
* V3.0-V4.0: <tt>$E4</tt>
* V3.0-V4.0: <tt>$E4</tt>


Restores the volumes to the saved value. $2143/$F7 outputs the current volume value for one tempo tick, then a $01 (or, for the master volume, always outputs the intended right echo volume value... which is saved to the left master volume by mistake).<br>
Restores the volumes to the saved value. Unless this is done on the main volume, you must reset volume operations to use this command again. $2143/$F7 outputs the current volume value for one tempo tick, then a $01 (or, for the main volume, always outputs the intended right echo volume value... which is saved to the left main volume by mistake).<br>
The command does not properly function past V1.0 for channels 1-6 due to a wrong branching location.<br>
The command does not properly function past V1.0 for channels 1-6 due to a wrong branching location.<br>
The master volume variant does not work properly due to a typo in the code: specifically, the right echo volume gets copied to the left master volume by mistake, overwriting the correct value that was copied earlier.
The main volume variant does not work properly due to a typo in the code: specifically, the right echo volume gets copied to the left main volume by mistake, overwriting the correct value that was copied earlier.


[[Category:SPC Sound Engines]]
[[Category:SPC Sound Engines]]
[[Category:N-SPC Variants]]
[[Category:N-SPC Variants]]

Latest revision as of 02:25, 21 May 2023

Go back to N-SPC Engine

Kemco is the first company outside of Nintendo themselves to release a game using their own variant of N-SPC (that being Bombuzal). The main customization that they did was to have the CPUIO registers play sounds on specific channels, and only the channels on the phrase list specified to be used by the corresponding CPUIO register would be used. All non-music CPUIO registers, when processing phrase data, also did not support the fast forward phrase commands. One other CPUIO register was allocated mainly to perform volume fades.

Game Name Version VCMD Table Location ($E0 and up) ROM Offset
Bombuzal 1.0 0x10EB, relative to 0x102B 0x04807A
Lagoon 2.0 0x1156, relative to 0x1096 0x0D80A4 (all versions)
Drakkhen 3.0 0x129E, relative to 0x11DE 0x1C805C (all versions)
Ka-blooey 3.0 0x129E, relative to 0x11DE 0x048080
First Samurai 3.1 0x129E, relative to 0x11DE 0x0DB15E (all versions)
Phalanx - The Enforce Fighter A-144 3.1 0x129E, relative to 0x11DE 0x1EB23E (all versions)
Super Drakkhen/Dragon View 3.1 0x129E, relative to 0x11DE 0x09B6F6 (all versions)
Super Full Metal 3.1 0x129E, relative to 0x11DE 0x0C80B6
X Zone 3.1 0x129E, relative to 0x11DE 0x0FAEE6 (all versions)
Kid Klown in Crazy Chase 4.0 0x12A1, relative to 0x11E1 0x1EC1E0 (all versions)

The raw build sorting notes can be found here.

Communication with the SNES

Each CPUIO register has an individual use.

CPUIO0 ($2140/$F4)

This register always controls which sound ID will play out of channels 1-6, regardless of which sound driver version is used. It also supports the source build's N-SPC/Kankichi commands. These same commands are not present in the other CPUIO ports that control the channels, and instead you can only play or stop them.

Command ID Description Register Values & Arguments
$00 Stop Sound $00 ?? ?? ??
$01-?? Play Sound (Channels 1-6) xx ?? ?? ??
$F0 Pause Sound (Channels 1-6) $F0 ?? ?? ??
$F1 Continue Sound (Channels 1-6) $F1 ?? ?? ??
$FF Load New Data $FF ?? xx xx

The output to $2140/$F4 is as following...

  • $00 - Sound is not playing (usually caused by the zero command)
  • $3F - Usually on the first tempo tick only, or sound is paused (caused by commands $F0 and $FF)
  • $40 - Sound is playing on channels 1-6

CPUIO1 ($2141/$F5)

This register controls which sound ID will play of of the following channel IDs, depending on the version...

  • V1.0, V3.0: Channels 7-8
  • V2.0, V4.0: Channel 7

The output is as following...

  • $00 - Most common output with V1.0 and V3.0 (even if sound is playing). Otherwise indicates that a sound is not playing.
  • $40 - Usually on the first tempo tick only for V2.0 and V4.0 after the sound is activated.
  • $80 - Sound is playing on channel 7.
  • $FF - Usually on the first tempo tick only for V1.0 and V3.0 after the sound is activated.

CPUIO2 ($2142/$F6)

Only used in V2.0 and V4.0. This register always controls which sound ID will play out of channel 8.
This register always outputs a zero on V1.0 and V3.0-V3.1. Otherwise, when it is used, the output is...

  • $00 - Most common output, even if sound is playing.
  • $80 - Usually on the first tempo tick only after the sound is activated.

CPUIO3 ($2143/$F7)

Never used in V2.0. It does output a value, though: namely, whatever you sent in $2142/$F6.
This CPUIO register is used to perform volume fades on either the note volumes of channels 1-8 or the MVOL DSP registers (The EVOL DSP registers are modified as well, but they get overwritten shortly afterwards). The values supported depend on the sound driver version.

Commands (V1.0)

Command ID Description
$00-$9F Pause Volume Operations + Acknowledge
$A0 Reset Volume Operations (Channels 1-6)
$A1 Fade Out (Channels 1-6)
$A2 Fade In (Channels 1-6)
$A3 Zero Volume (Channels 1-6)
$A4 Volume Restore (Channels 7-8)
$A5 Reset Volume Operations (Channels 7-8)
$A6 Fade Out (Channels 7-8)
$A7 Fade In (Channels 7-8)
$A8 Zero Volume (Channels 7-8)
$A9 Volume Restore (Channels 7-8)
$AA-$FF Pause Volume Operations + Acknowledge

Commands (V3.0-V4.0)

Command ID Description Versions Supported
$00-$7F Pause Volume Operations + Acknowledge
$80 Reset Volume Operations (Channels 1-6) V3.0-V3.1
$81 Fade Out (Channels 1-6) V3.0-V3.1
$82 Fade In (Channels 1-6) V3.0-V3.1
$83 Zero Volume (Channels 1-6) V3.0-V3.1
$84 Volume Restore (Channels 1-6) V3.0-V3.1
$85-$9F Pause Volume Operations + Acknowledge
$A0 Reset Volume Operations (Channels 7-8) V3.0-V3.1
$A1 Fade Out (Channels 7-8) V3.0-V3.1
$A2 Fade In (Channels 7-8) V3.0-V3.1
$A3 Zero Volume (Channels 7-8) V3.0-V3.1
$A4 Volume Restore (Channels 7-8) V3.0-V3.1
$A5-$DF Pause Volume Operations + Acknowledge
$E0 Reset Volume Operations (Main Volume) V3.0-V4.0
$E1 Fade Out (Main Volume) V3.0-V4.0
$E2 Fade In (Main Volume) V3.0-V4.0
$E3 Zero Volume (Main Volume) V3.0-V4.0
$E4 Volume Restore (Main Volume) V3.0-V4.0
$E5-$FF Pause Volume Operations + Acknowledge

For V3.0-V3.1, $80 and up can be transformed into this binary-based notation instead:

%1yyxxxxx
  • %xxxxx is a command ID. The commands are as following...
    • %00000 ($00) - Reset Volume Operations
    • %00001 ($01) - Fade Out
    • %00010 ($02) - Fade In
    • %00011 ($03) - Zero Volume
    • %00100 ($04) - Volume Restore
    • Any other value ($05-$1F) - Pause Volume Operations + Acknowledge
  • %yy defines what will be affected by the command. The values are...
    • %00 ($0) - Channels 1-6
    • %01 ($1) - Channels 7-8
    • %10 ($2) - Invalid (causes all values to merely acknowledge)
    • %11 ($3) - Main Volume

Pause Volume Operations + Acknowledge

Echoes back the value you just sent to $2143/$F7. All volume operations are also paused, which includes fades, since the register is constantly polled.

Reset Volume Operations

The command ID used depends on the version...
Channels 1-6

  • V1.0: $A0
  • V3.0-V3.1: $80

Channels 7-8

  • V1.0: $A5
  • V3.0-V3.1: $A0

Main Volume

  • V3.0-V4.0: $E0

This command resets all volume-related operations, specifically by resetting the flags that they were triggered for the first time. This also pauses fades. $2143/$F7 outputs a zero.

Fade Out

The command ID used depends on the version...
Channels 1-6

  • V1.0: $A1
  • V3.0-V3.1: $81

Channels 7-8

  • V1.0: $A6
  • V3.0-V3.1: $A1

Main Volume

  • V3.0-V4.0: $E1

Fades out the volume to 0. On V1.0, this is done at a rate of 3 per tempo tick: on other versions, it's 1 per tempo tick. On V3.0 and later, the original volume value is saved. $2143/$F7 outputs the current volume value of the last channel in the set (or the intended right echo volume value in the main volume's case).
The command does not properly function past V1.0 for channels 1-6. Technically it still works, but a wrong branching location causes the channel ID to use (and the number of channels to copy) to not be initialized properly, which causes the volume values to not be saved.

Fade In

The command ID used depends on the version...
Channels 1-6

  • V1.0: $A2
  • V3.0-V3.1: $82

Channels 7-8

  • V1.0: $A7
  • V3.0-V3.1: $A2

Main Volume

  • V3.0-V4.0: $E2

Fades in the volume to the original volume at a rate of 1 per tempo tick. If no value was saved beforehand, this can overflow back to zero. $2143/$F7 outputs the current volume value of the last channel in the set (or the intended right echo volume value in the main volume's case).

Zero Volume

The command ID used depends on the version...
Channels 1-6

  • V1.0: $A3
  • V3.0-V3.1: $83

Channels 7-8

  • V1.0: $A8
  • V3.0-V3.1: $A3

Main Volume

  • V3.0-V4.0: $E3

Zeroes out the volume, saving the original volume for restoration later on. Unless this is done on the main volume, you must reset volume operations to use this command again. $2143/$F7 outputs the current volume value (or the intended right echo volume value in the main volume's case) for one tempo tick, then a $01 (or, for the main volume, always outputs a zero).
The command does not properly function past V1.0 for channels 1-6 due to a wrong branching location.

Volume Restore

The command ID used depends on the version...
Channels 1-6

  • V1.0: $A4
  • V3.0-V3.1: $84

Channels 7-8

  • V1.0: $A9
  • V3.0-V3.1: $A4

Main Volume

  • V3.0-V4.0: $E4

Restores the volumes to the saved value. Unless this is done on the main volume, you must reset volume operations to use this command again. $2143/$F7 outputs the current volume value for one tempo tick, then a $01 (or, for the main volume, always outputs the intended right echo volume value... which is saved to the left main volume by mistake).
The command does not properly function past V1.0 for channels 1-6 due to a wrong branching location.
The main volume variant does not work properly due to a typo in the code: specifically, the right echo volume gets copied to the left main volume by mistake, overwriting the correct value that was copied earlier.