XSG MSX BASIC Extensions

CALL Statements

For the purposes of this document, optional parameters will be written between square brackets ([]), while mandatory parameters will be written between angled brackets (<>).

CALL XSG

This statement is used to initialize the XSG sound chip and the corresponding BASIC extensions.

CALL XSG[(1,0,<#ch1>[,#ch2[,#ch3[,#ch4[,#ch5[,#ch6]]]]])]

The first two parameters must be always 1 and 0, respectively. The following parameters define how many sound channels will be used by each of the strings in the PLAY statement. These channels will be chosen in sequence from sound unit 1 to sound unit 2. This statement works pretty much like the corresponding statements in MSX-AUDIO and MSX-MUSIC extensios.

Default: CALL XSG, without any parameters, is equivalent to CALL XSG(1,0,1,1,1)

CALL BGM

This statement is used to set the background playing mode.

CALL BGM(<mode>)

The value of mode can be 0 or 1. If it is 0, then background playing is disabled. If it is 1, then background playing is enabled.

Default: Background playing is enabled by default.

CALL PAN

This statement is used to set the stereo panning position for each sound channel.

CALL PAN[([#panchA][,[#panchB][,[#panchC][,[#panchD][,[#panchE][,[#panchF]]]]]])]

Each parameter is optional, and it has a value from 0 to 3. Notice each parameter corresponds to a different sound channel, not to the PLAY strings. This statement may be combined with the CALL WAVE statement to create rich soundscapes, combining different waveforms with different stereo settings in different sound channels, but controlled by a single PLAY string. The values have the following meaning:

Default: CALL PAN without parameters will not change any stereo setting. By default, all channels are set to output sound to both left and right.

Obs.: These values don't align perfectly with the XSG stereo control registers. This is intentional. When XSG is in monoaural mode, this statement will still write the correct values to the stereo control registers.

CALL PLAY

This statement is used to check if background music is being played.

CALL PLAY(<string number>,<variable>)

The value of string number corresponds to one of the strings played by the PLAY statement, whether this string is being played by a XSG or a PSG channel. If it is 0, all channels will be checked. If the tested channel or channels are currently playing background music, the value -1 (true) will be put in the variable. Otherwise, 0 (false) will be put in the variable.

CALL STEREO

This statement is used to set the monoaural / stereo mode.

CALL STEREO[(<mode>)]

The value of mode can be 0 or 1. If it is 0, then monoaural mode is enabled, and XSG will ignore stereo settings. If it is 1, then monoaural mode is disabled, and XSG will output stereo sound.

Default: XSG outputs stereo sound by default. CALL STEREO, without any parameters, is equivalent to CALL STEREO(1).

Obs.: This is the exact opposite of the monoaural mode control bit setting. This is intentional.

CALL STOPM

This statement is used to stop playing background music.

CALL STOPM

When called, this statement immediately stops any background music. It has no effect if background music playing is disabled.

CALL WAVE

This statement is used to set waveforms to each sound channel.

CALL WAVE[([@#wavechA][,[@#wavechB][,[@#wavechC][,[@#wavechD][,[@#wavechE][,[@#wavechF]]]]]])]

Each parameter is optional, but when used it must be written with the character @ followed by a number from 0 to 127, corresponding to one position in the internal waveform storage memory. Notice each parameter corresponds to a different sound channel, not to the PLAY strings. This way, it is possible to have one string play simultaneously two (or more) different waveforms in two (or more) different channels.

Default: CALL WAVE without parameters will not change any waveform. By default, waveforms are set to @0.

CALL WAVE COPY

This statement is used to copy waveforms to and from the internal waveform storage memory, and also between internal waveform storage memory positions.

CALL WAVE COPY(@<#wave from>|<variable from> TO @<#wave to>|<variable to>)

Both from and to parameters can be either a position in the internal waveform storage memory (indicated by a @ character, just like the CALL WAVE statement) or an array variable. If you use an array variable as the from parameter, its contents will be copied to the position in the internal waveform storage memory indicated by the to parameter. Conversely, if you use an array variable as the to parameter, the internal waveform storage memory position indicated by the from parameter will be retrieved and loaded into the array variable.

The array variable must be integer and have 16 positions (similar to the arrays used for MSX-MUSIC and MSX-AUDIO instruments). The waveform is stored in a straightforward manner: its 32 bytes correspond to the 16 first positions of the array variable, starting from index 0 up to index 15. All 32 bytes are used; there are no bytes reserved for instrument information or future use like in MSX-AUDIO and MSX-MUSIC.

Example and default value:

10 CALL XSG
20 DIM A%(15)
30 DATA FFFF,FFFF,FFFF,FFFF
40 DATA FFFF,FFFF,FFFF,FFFF
50 DATA 0000,0000,0000,0000
60 DATA 0000,0000,0000,0000
70 FOR I=0 TO 15
80 READ A$
90 A%(I)=VAL("&H"+A$)
100 NEXT I
110 CALL WAVE COPY(A% TO @0)
120 FOR W=1 TO 127
130 FOR I=0 TO 15
140 A%(I)=&H8080
150 NEXT I
160 CALL WAVE COPY(A% TO @W)
170 NEXT W

The code snippet above loads the first position in the internal waveform storage memory with a 50% duty-cycle pulse wave, which is the default and sounds exactly like the original PSG. Every other position is filled with 8016, representing a mute waveform.

CALL XSGREG

This statement is used to write values directly to the XSG registers.

CALL WAVE COPY(<register>,<value>)

Both numbers must be integer and in the range from 0 to 255. If you try to write to a non-existing register, an error will be thrown.

PLAY Statement

The MSX-BASIC PLAY statement is used to play music with XSG. It has some new features beyond what MSX-BASIC normally provides. In this regard, it works in a similar fashion to the PLAY statement under MSX-AUDIO and MSX-MUSIC.

PLAY #2

This statement is used to play strings containing music sequences in MML (Music Macro Language). Each string correspond to one or more sound channels, according to the settings in the CALL XSG statement. The PLAY statement isn't new, but it has several new features after CALL XSG. These features are similar to the ones introduced by CALL AUDIO or CALL MUSIC.

PLAY #2,<string 1>[,[string 2][,[string 3](...)[,[string N]]]]

Only the first string is required; all others are optional. It works just like the same statement in MSX-AUDIO and MSX-MUSIC, meaning you can play music in both XSG and the internal PSG.

Music Macro Language (MML)

The accepted MML commands are described in the following tables:

Commands supported by the vanilla PLAY statement
Command Name Description Default
C, D, E, F, G, A, B Play note The note can be followed by a # or a +, meaning sharp (one half-tone higher pitch), or a -, meaning flat (one half-tone lower pitch). It can also be followed by a number from 1 to 64, meaning the duration of the note (see command L). It can also be followed by one or more . characters, meaning a dotted note (the note's duration is lengthened by one-half). When the duration is omitted, the note will play with the same value as the most recent L command.
L Length of note Sets the duration of the notes. It is followed by a number from 1 to 64, with the following meaning:
  • 1: Whole note (semibreve)
  • 2: Half note (minim)
  • 4: Quarter note (crotchet)
  • 8: Eighth note (quaver)
  • 16: Sixteenth note (semiquaver)
  • 32: Thirty-second note (demisemiquaver)
  • 64: Sixth-fourth note (hemidemisemiquaver)
Every note after this command is affected, until the next L command.
The duration value may not be omitted, but after reset the duration will be set at 4, meaning all notes will be considered as quarter notes.
M Period of envelope Sets the period of the envelope generator. It is followed by a number from 0 to 65535, corresponding to the values of XSG's envelope generator frequency registers. Keep in mind there is only one envelope generator each for channels from A to C, and from D to F. The period value may not be omitted, but after reset the period will be set at 255.
N Note number It is followed by a number from 0 to 96. Each number corresponds to a note, except 0 which corresponds to a rest. It will play (or rest) for the length specified by the previous L command.
O Octave Sets the octave. It is followed by a number from 1 to 8. The octave value may not be omitted, but after reset the octave will be set at 4.
R Rest No sound will be played for the duration of the rest. It can also be followed by a number from 1 to 64, meaning the duration of the rest (see command L). It can also be followed by one or more . characters, meaning a dotted rest (the rest's duration is lengthened by one-half). When the duration is omitted, the rest will play with the value of 4 (a quarter note).
S Shape of envelope Sets the shape of the envelope generator. It is followed by a number from 0 to 15, corresponding to the values of XSG's envelope generator shape registers. Keep in mind there is only one envelope generator each for channels from A to C, and from D to F. When set, volume setting is ignored for the corresponding sound channels. The shape value may not be omitted, but after reset the shape value will be set at 0.
T Tempo Sets the tempo. It is followed by a number from 32 to 255, representing the number of quarter notes in a minute. The tempo value may not be omitted, but after reset the tempo will be set at 120, meaning a quarter note will play for half a second.
V Volume Sets the volume. It is followed by a number from 0 to 15. When set, it disables the envelope generator for the corresponding sound channels. The volume value may not be omitted, but after reset the volume will be set at 8.
X String Includes a substring within the string, overcoming the 255-character limit.
Commands previously supported for PSG only after calling CALL MUSIC or CALL AUDIO
Command Name Description Default
<, > Octave change Changes the current octave. < lowers the octave and > rises. It throws an error if the new value isn't inside the valid range.
& Tie The preceding note will play until the next note starts playing. It previously didn't have any effect since all PSG notes were already tied, but it was considered valid MML in PSG sound channels anyway. Now, it just makes the preceding note ignore the Q command setting. After reset it has no effect, since Q's default value is 8.
{, } Tuplet All notes inside brackets will play inside the duration of a regular note. In other words, the tuplet has the duration of a regular note, and all notes inside the tuplet have the same duration. It can be followed by a number from 1 to 64, meaning the duration of the tuplet (see command L). It can also be followed by one or more . characters, meaning the tuplet's duration is lengthened by one-half. When the duration is omitted, the tuplet will play with the same value as the most recent L command.
New commands
Command Name Description Default
@ Waveform change Changes the waveform for the corresponding sound channels. It is followed by a number from 0 to 127, corresponding to one waveform index in the internal waveform memory. The waveform value may not be omitted, but after reset all waveforms will be set to 0.
@F Frequency of noise Sets the noise generator frequency for the corresponding sound units. It is followed by a number from 0 to 31. Please notice channels A, B and C share the same sound unit, as do channels D, E and F. The frequency value may not be omitted, but after reset all noise generators will be set to 0.
@N Noise set Sets the corresponding channels to play noise. It is followed by 0, meaning noise will not be produced, or 1, meaning noise will be produced. After reset, all channels are configured to not play noise.
@S Stereo panning Sets the stereo panning. It is followed by a number from 0 to 3, and it works just like the CALL PAN statement: 0 means sound will be output to both left and right, 1 means sound will be output only to the left, 2 means sound will be output only to the right and 3 means sound will be output to both left and right, but the right waveform will be inverted for a pseudo surround effect. The panning value may not be omitted, but after reset all channels will produce sound in both left and right output channels.
@T Tone set Sets the corresponding channels to play tones. It is followed by 0, meaning a tone will not be produced, or 1, meaning a tone will be produced. After reset, all channels are configured to play tones.
Q Note expression Sets the ratio of sound to silence of a note relative to its duration. It is followed by a number n from 1 to 8, meaning n/8 of the note will be played. For example, Q4 means all notes will only play for half its actual length, being silent for the remaing time, giving a staccato effect. The ratio value may not be omitted, but after reset it will be set to 8, meaning there will be no silence between notes and they will play for the entire length of their duration.