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/F-Zero

From SnesLab
Jump to: navigation, search

Go back to N-SPC Engine/Nintendo

F-Zero is the first released game to use the standard N-SPC VCMD set starting at $E0. VCMDs $FB-$FF don't exist, though, and the fast forward phrase commands also don't exist here.

Game Name VCMD Table Location ($E0 and up) ROM Offset
F-Zero 0x0EE9, relative to 0x0E29 0x01E538 (US & Japanese versions)
0x01841E (European version)

The raw build sorting notes can be found here for all variants by Nintendo.

Communication with the SNES

Each CPUIO register has its own individual usage.

CPUIO0 ($2140/$F4)

Command ID Description
%xyyzzzzz
$00-$FE
Play Music/Looping SFX/Second Engine Control
$FF Load New Data

Play Music/Looping SFX/Second Engine Control (Command $00-$FE)

Input

%xyyyzaaa

Output

bb
  • %x, when set, fades out the MVOL and EVOL DSP registers over 84 SFX tempo ticks (unless bit %x of CPUIO2 being set was the last thing done, in which the fade out is done in 127 SFX tempo ticks). It causes music VCMD $F5 (echo enable bits and volume) to effectively act as a NOP when this happens.
  • %yyy is a looping SFX ID for channel 6, with a range of %001($1)-%100($4), and looping back to $1 after $4. Except for $3, they also don't restore the instrument ID after playing them.
  • %z, when set, causes the BRR engine noise generator from $2143/$F7 to output on channels 4-7.
  • %aaa is a music ID that is output to the SNES via $2140. %110($6) is a special case, as it utilizes an ID that is defined via loading a single byte to a specific memory location, rather than its own (the ID itself is illegal if forced due to a zero pointer). Music data does not actually need to be loaded in this particular case, as it is all stored in one go.
  • bb is the music ID currently playing. This is equal to %00000aaa unless %110($6) was the last input.

Load New Data (Command $FF)

Loads new data when set to $FF. See the source build's Load New Data command for the loading protocol, as it is identical binary-wise to the copy used in this one minus the *Ver S1.20* string.

CPUIO1 ($2141/$F5)

Input

%xyzzzzzz

Output

%00zzzzzz
  • %x increases the overall BRR engine noise generator frequency on channel 8. The BRR engine noise generator frequency is designed to hiccup like a gearshift when activating.
  • %y plays a continuous beeping tone on channel 6... if there is either no music playing or it is $04 or $05. Otherwise, a different SFX plays on channels 6 and 8.
  • %zzzzzz controls the BRR engine noise generator frequency on channel 8. Disable with zero. This value is what is output to the SNES via $2141.

CPUIO2 ($2142/$F6)

%xyzzaaaa

The value output to the SNES via $2142 is which bits are being utilized to play the SFX. Higher bits have more priority, but CPUIO0's channel 6 SFX has higher priority, which in turn is out-prioritized by CPUIO1's channel 6 SFX.

  • %x stops the music and goes BOOM! Channels 3-8 are used, with 5-8 being continuously used afterwards.
  • %y plays a UFO-like SFX on channel 6.
  • %zz controls the BRR engine noise with vibrato on channel 6.
  • %aaaa controls incidental SFX on channel 6. $4 doesn't play anything, and the values wrap around to $1 after $8, except for $C, which plays $8.

CPUIO3 ($2143/$F7)

Input

xy

Output

0x
  • x controls the panning of the second vehicle on channel 7, with zero representing left and $E representing right. Sets up a whole bunch of vehicle noises on channels 4-7 if set to $F instead that are not pitch-controllable. This nibble is output to the SNES via $2143 as the low nibble.
  • y controls the BRR engine noise generator frequency (and volume) of the second vehicle on channel 7, or several at once on channels 1-5 and 7 if bit %z on $2140/$F4 is set.

SFX Sequence Format

Most of the SFX is hard-coded and the instrument format, when utilized outside of the actual instrument table, is identical to a music instrument's. The only SFX that actually uses a SFX sequence format beyond an array of notes is CPUIO0's bit %yyy ID %010 ($2) (there's actually a second one defined, but it appears to never have been used). These are headerless, unlike a song, and they only support one channel at a time, with the channel used being fixed.

VCMD ID Description Arguments
$00 End of SFX
$01-$7F Note Duration (xx)
$80-$C7 Note
$C8 Tie
$C9 Rest
$CA-$DF Percussion
$E0 Instrument xx
$E1-$FE Invalid Note
$FF Restart SFX

End of SFX (VCMD $00)

Terminates the SFX.

Note Duration (VCMD $01-$7F)

%0xxxxxxx (yy)
  • %xxxxxxx represents your note length (as seven bits) in tempo ticks.
  • yy, if less than $80, represents the volume of the 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. Note that there is no way to define the base instrument ID used for percussion for the SFX, so it is bound to the music's base instrument ID for percussion instead.

Instrument (VCMD $E0)

$E0 xx
  • xx is an instrument ID to an array of instruments. The array used is the same one used for the music.

Invalid Note (VCMD $E1-$FE)

Doesn't crash the sound driver, but does play an invalid note.

Restart SFX (VCMD $FF)

Restarts the SFX from the beginning.

TODO use a template to duplicate all of the phrase and VCMD documentation as needed