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/Nintendo/Koji Kondo/Prototype: Difference between revisions

From SnesLab
Jump to: navigation, search
(Record build differences for Super Mario World and Pilotwings)
(Adding communication protocols, which are game-specific. Pilotwings is going first, then Super Mario World.)
Line 17: Line 17:


The build difference between the other versions and the European version of Pilotwings is similar to Super Mario All Stars and Super Mario World, except it's more like a complete replacement since it changes the operation of the $FF command for $2141/$F5. The echo volume DSP registers are zeroed out, all notes are keyed off, the EON register is cleared, echo writes are disabled, then we activate and jump to the IPL boot program instead of using a variant of it embedded in the program.
The build difference between the other versions and the European version of Pilotwings is similar to Super Mario All Stars and Super Mario World, except it's more like a complete replacement since it changes the operation of the $FF command for $2141/$F5. The echo volume DSP registers are zeroed out, all notes are keyed off, the EON register is cleared, echo writes are disabled, then we activate and jump to the IPL boot program instead of using a variant of it embedded in the program.
==Communication with the SNES==
The communication protocol is game-specific. Both games have dedicated uses for each CPUIO register.
===Super Mario World===
====CPUIO0 ($2140/$F4)====
''TODO''
====CPUIO1 ($2141/$F5)====
''TODO''
====CPUIO2 ($2142/$F6)====
''TODO''
====CPUIO3 ($2143/$F7)====
''TODO''
===Pilotwings===
====CPUIO0 ($2140/$F4)====
This register plays the music and controls the BRR wind noise.
{| class="wikitable sortable"
|-
! Command ID !! Description
|-
|<tt>$00</tt> || NOP
|-
|<tt>%xyyzzzzz</tt> || Play Music/BRR Wind Noise Frequency
|-
|<tt>$FF</tt> || Fade Out
|}
=====NOP (Command <tt>$00</tt>)=====
Does absolutely nothing.
=====Play Music/BRR Wind Noise Frequency (Command <tt>$01-$FE</tt>)=====
<pre>%xyyzzzzz</pre>
Plays a piece of music.
* <tt>x</tt> disables BRR wind noise playback on channel 8. This is forced on IDs <tt>$02</tt>, <tt>$0D</tt> and <tt>$11</tt> if <tt>x</tt> and <tt>yy</tt> are both zero.
* <tt>yy</tt>, if non-zero and with <tt>x</tt> cleared, controls the general pitch that the wind plays at
* <tt>zzzzz</tt> is the music ID. If zero, then the music will keep playing normally. Although the absolute limit is <tt>$1F</tt>, in reality it's <tt>$15</tt> because the song table only goes that high up ID-wise. The ID currently playing is echoed back to $2140 on the SNES.
=====Fade Out (Command <tt>$FF</tt>)=====
Fades out the music by sliding the song volume to zero over 192 tempo ticks.
====CPUIO1 ($2141/$F5)====
This register controls the sound effects in channels 3 and 8.
{| class="wikitable sortable"
|-
! Command ID !! Description
|-
|<tt>$00</tt> || NOP
|-
|<tt>%xxxxyyyy</tt> || Play SFX Sequence
|-
|<tt>$FF</tt> || Load Data
|}
=====NOP (Command <tt>$00</tt>)=====
Does absolutely nothing.
=====Play SFX Sequence (Command <tt>$01-$FE</tt>)=====
<pre>%xxxxyyyy</pre>
Two SFX can be triggered at once. Plus, each one has its own SFX collection to use.
* <tt>xxxx</tt> is a four-bit SFX ID for channel 8.
** <tt>$0E</tt> mutes all other channels sound upon playing the SFX (including the music, which causes new values to not be acknowledged). Any other ID played afterwards unmutes the music.
** <tt>$05</tt> plays nothing, although it still works for unmuting music and other channels.
* <tt>yyyy</tt> is a four-bit SFX ID for channel 3.
** <tt>$0F</tt> plays nothing.
''TODO SFX Sequence Data Format (should be a simplified version of what is used in the music plus one new VCMD at $FF)''<br>
''TODO SFX Instrument Format (both for here and other I/O registers that use them, unless they don't quite match)''
=====Load Data (Command <tt>$FF</tt>)=====
The operation is slightly different depending on what build you're using. Both clean up DSP registers first: specifically by keying off all notes and zeroing out the EVOL DSP registers, along disabling echo writes. Additionally, the European version clears out the EON DSP register, and the other versions mute the amplifier until the loading routine exits.
The European version jumps directly to the IPL Boot ROM, while all other versions instead use a modified copy.
''TODO Loading Protocol (should be nearly identical to IPL Boot ROM)''
====CPUIO2 ($2142/$F6)====
This controls the aircraft engine noise in channels 5 and 6.
{| class="wikitable sortable"
|-
! Command ID !! Description
|-
|<tt>$00</tt> || NOP
|-
|<tt>%0xyyyyyy</tt> || Engine Control
|-
|<tt>%10xxxxxx</tt> || Break
|-
|<tt>%11??????</tt> || Skid
|-
|<tt>$FF</tt> || Stop Engine
|}
=====NOP (Command <tt>$00</tt>)=====
Does absolutely nothing.
=====Engine Control (Command <tt>$01-$7F</tt>)=====
<pre>%0xyyyyyy</pre>
* <tt>x</tt>, when starting the aircraft engine, determines what kind of noise it makes. A different command (other than NOP) must be used before changing the engine noise.
* <tt>yyyyy</tt> controls the engine noise frequency.
=====Break (Command <tt>$80-$BF</tt>)=====
<pre>%10xxxxxx</pre>
* <tt>xxxxxx</tt> only does something different when set to <tt>$01</tt>, which is a slight pitch variant. Otherwise, there's not much control here.
=====Skid (Command <tt>$C0-$FE</tt>)=====
<pre>%11??????</pre>
=====Stop Engine (Command <tt>$FF</tt>)=====
Basically acts as a reset for the aircraft engine back to default settings, in addition to stopping it.
====CPUIO3 ($2143/$F7)====
This controls a couple of pieces of miscellaneous SFX on channel 4.
{| class="wikitable sortable"
|-
! Command ID !! Description
|-
|<tt>$00, $03-$FF</tt> || NOP
|-
|<tt>$01</tt> || Engine-Controlled SFX
|-
|<tt>$02</tt> || Beep
|}
=====NOP (Command <tt>$00, $03-$FF</tt>)=====
Does absolutely nothing.
=====Engine-Controlled SFX (Command <tt>$01</tt>)=====
Plays a fixed sequence of notes on channel 4 at a variable tempo rate controlled by the engine frequency that goes faster the higher the frequency. Only works with a CPUIO2 value of <tt>$02-$11</tt>: otherwise, it's a NOP.
=====Beep (Command <tt>$02</tt>)=====
Plays a single note on channel 4. No other conditions are required here.


==Instrument Format==
==Instrument Format==

Revision as of 20:26, 23 October 2020

Go back to N-SPC Engine

The Prototype variant was used in two games: Super Mario World and Pilotwings. They are the only versions of the code that clearly pre-date the source code version provided with the IS-Sound unit. From a sound effect programming point of view, it can also be considered a predecessor to five other games that post-date the source code: SimCity, Legend of Zelda - A Link to the Past/Zelda no Densetsu - Kamigami no Triforce, Star Fox/Star Wing, Super Mario All-Stars/Super Mario Collection and Super Mario: Yoshi Island/Super Mario World 2: Yoshi's Island.

Game Name Music Version VCMD Table Location ($DA and up) ROM Offset
Super Mario World 0.0 0x0F90, relative to 0x0EDC (all other versions)
0x0FC4, relative to 0x0F10 (Super Mario All Stars + Super Mario World)
0x0E8000 (all other versions)
0x4E8000 (Super Mario All-Stars + Super Mario World)
Pilotwings 0.1 0x1317, relative to 0x1263 (US and Japanese versions)
0x12B4, relative to 0x1200 (European version)
0x0C8000 (all versions)

The build difference between the standalone Super Mario World and its variant in Super Mario All-Stars is an extra command for $2141/$F5: $F0. This command zeroes out the echo volume DSP registers, keys off all notes, zeroes out several memory locations then activates and jumps to the IPL boot program. The copy itself used for the $FF command is stored at $FE00 rather than in the middle of the program.

The build difference between the other versions and the European version of Pilotwings is similar to Super Mario All Stars and Super Mario World, except it's more like a complete replacement since it changes the operation of the $FF command for $2141/$F5. The echo volume DSP registers are zeroed out, all notes are keyed off, the EON register is cleared, echo writes are disabled, then we activate and jump to the IPL boot program instead of using a variant of it embedded in the program.

Communication with the SNES

The communication protocol is game-specific. Both games have dedicated uses for each CPUIO register.

Super Mario World

CPUIO0 ($2140/$F4)

TODO

CPUIO1 ($2141/$F5)

TODO

CPUIO2 ($2142/$F6)

TODO

CPUIO3 ($2143/$F7)

TODO

Pilotwings

CPUIO0 ($2140/$F4)

This register plays the music and controls the BRR wind noise.

Command ID Description
$00 NOP
%xyyzzzzz Play Music/BRR Wind Noise Frequency
$FF Fade Out
NOP (Command $00)

Does absolutely nothing.

Play Music/BRR Wind Noise Frequency (Command $01-$FE)
%xyyzzzzz

Plays a piece of music.

  • x disables BRR wind noise playback on channel 8. This is forced on IDs $02, $0D and $11 if x and yy are both zero.
  • yy, if non-zero and with x cleared, controls the general pitch that the wind plays at
  • zzzzz is the music ID. If zero, then the music will keep playing normally. Although the absolute limit is $1F, in reality it's $15 because the song table only goes that high up ID-wise. The ID currently playing is echoed back to $2140 on the SNES.
Fade Out (Command $FF)

Fades out the music by sliding the song volume to zero over 192 tempo ticks.

CPUIO1 ($2141/$F5)

This register controls the sound effects in channels 3 and 8.

Command ID Description
$00 NOP
%xxxxyyyy Play SFX Sequence
$FF Load Data
NOP (Command $00)

Does absolutely nothing.

Play SFX Sequence (Command $01-$FE)
%xxxxyyyy

Two SFX can be triggered at once. Plus, each one has its own SFX collection to use.

  • xxxx is a four-bit SFX ID for channel 8.
    • $0E mutes all other channels sound upon playing the SFX (including the music, which causes new values to not be acknowledged). Any other ID played afterwards unmutes the music.
    • $05 plays nothing, although it still works for unmuting music and other channels.
  • yyyy is a four-bit SFX ID for channel 3.
    • $0F plays nothing.

TODO SFX Sequence Data Format (should be a simplified version of what is used in the music plus one new VCMD at $FF)
TODO SFX Instrument Format (both for here and other I/O registers that use them, unless they don't quite match)

Load Data (Command $FF)

The operation is slightly different depending on what build you're using. Both clean up DSP registers first: specifically by keying off all notes and zeroing out the EVOL DSP registers, along disabling echo writes. Additionally, the European version clears out the EON DSP register, and the other versions mute the amplifier until the loading routine exits.

The European version jumps directly to the IPL Boot ROM, while all other versions instead use a modified copy.

TODO Loading Protocol (should be nearly identical to IPL Boot ROM)

CPUIO2 ($2142/$F6)

This controls the aircraft engine noise in channels 5 and 6.

Command ID Description
$00 NOP
%0xyyyyyy Engine Control
%10xxxxxx Break
%11?????? Skid
$FF Stop Engine
NOP (Command $00)

Does absolutely nothing.

Engine Control (Command $01-$7F)
%0xyyyyyy
  • x, when starting the aircraft engine, determines what kind of noise it makes. A different command (other than NOP) must be used before changing the engine noise.
  • yyyyy controls the engine noise frequency.
Break (Command $80-$BF)
%10xxxxxx
  • xxxxxx only does something different when set to $01, which is a slight pitch variant. Otherwise, there's not much control here.
Skid (Command $C0-$FE)
%11??????
Stop Engine (Command $FF)

Basically acts as a reset for the aircraft engine back to default settings, in addition to stopping it.

CPUIO3 ($2143/$F7)

This controls a couple of pieces of miscellaneous SFX on channel 4.

Command ID Description
$00, $03-$FF NOP
$01 Engine-Controlled SFX
$02 Beep
NOP (Command $00, $03-$FF)

Does absolutely nothing.

Engine-Controlled SFX (Command $01)

Plays a fixed sequence of notes on channel 4 at a variable tempo rate controlled by the engine frequency that goes faster the higher the frequency. Only works with a CPUIO2 value of $02-$11: otherwise, it's a NOP.

Beep (Command $02)

Plays a single note on channel 4. No other conditions are required here.

Instrument Format

Compared to common N-SPC, this is mostly the same, except it is missing the pitch base fractional multiplier, and V0.0 doesn't have noise support. Otherwise, it's the same as before: four direct DSP register references, and the pitch base multiplier as following in byte order:

  • SRCN
    • In V0.1, if this value is above $7F, noise is used, and the lowest five bits contains the noise clock rate.
  • ADSR1
  • ADSR2
  • GAIN
  • Pitch Base Multiplier

Percussion Format

Percussion is stored separately from the instrument format in the prototype version, because its format is nearly identical to an instrument, but it contains an extra byte at the end that defines the note to play.

Voice Command Format

The IDs are different due to being an earlier version, and some VCMDs may not be defined yet. The ones that are used are listed below.

VCMD ID Description Arguments
$00 Phrase Termination/End of Subroutine
$01-$7F Note Duration xy
$80-$C5 Note
$C6 Tie
$C7-$CF Rest
$D0-$D9 Percussion
$DA Instrument xx
$DB Panning %xyzzzzz
$DC Panning Fade xx yy
$DD Pitch Slide to Note xx yy zz
$DE Vibrato On xx yy zz
$DF Vibrato Off
$E0 Master Volume xx
$E1 Master Volme Fade xx yy zz
$E2 Tempo xx
$E3 Tempo Fade xx yy
$E4 Global Absolute Transposition xx
$E5 Tremolo On xx yy zz
$E6 Tremolo Off
$E7 Volume xx
$E8 Volume Fade xx yy
$E9 Subroutine xx xx yy
$EA Vibrato Fade In xx
$EB Note Pitch Envelope To xx yy zz
$EC Note Pitch Envelope From xx yy zz
$ED Invalid (supposed to be Note Pitch Envelope Off)
$EE Fine Tune xx
$EF Echo Bits and Volume %xxxxxxxx yy zz
$F0 Echo Off
$F1 Echo Parameter Setup xx yy zz
$F2 Echo Volume Fade xx yy zz
$F3-$FF Invalid

Most of these essentially act identically to the common versions (refer back to the main page for info on those), but two of the VCMDs don't work properly: Note Pitch Envelope Off, which has a zeroed out pointer but the code does exist, and Tremolo On, which has a memory location definition bug for one of the parameters that conflicts with an internal value utilized by the tremolo, causing constant overwriting and making the command not work in general.