Skip to content
PeterFidelman edited this page Jan 9, 2016 · 1 revision

Song Format

File Layout

field start length value
Magic 0x00 0x01 'X'
Version number 0x01 0x01 0,1,...
Number of Channels 0x02 0x01 0x09 for Adlib
Artist Name 0x03 0x10 padded to fit
Song Title 0x13 0x10 padded to fit
Start of Instruments 0x23 0x02 offset to start of instrument table (LSB first)
Start of SpFX 0x25 0x02 offset to start of SpFx table (LSB first)
Start of Orders 0x27 0x02 offset to start of orders (LSB first)
Start of Patterns 0x29 0x02 offset to start of patterns table (LSB first)
Instruments 0x2B ??? Instruments
SpFX ??? ??? SpFX
Orders ??? ??? Orders
Patterns ??? ??? Patterns

Orders

The starting address of a given order is:

[aSong] + [aSong + koStartOfOrders] + [numChannels]*Order#

The internal structure of each order is:

offset field
0x00 pattern # for channel 0
0x01 pattern # for channel 1
0x02 pattern # for channel 2
...
[numChannels]-1 pattern # for channel [numChannels]-1

Patterns

The starting address of a given pattern is:

[aSong] + [aSong + koStartOfPatterns] + 32*4*Pattern#

The internal structure of a pattern line is:

byte bitmask contents description
0x00 0x80 ΔN 1 for new note frequency, 0 for no change
0x00 0x7f Note frequency of desired note, as # semitones above C-0
0x01 0x80 ΔV 1 for new volume, 0 for no change
0x01 0x40 ΔI 1 for new instrument and Note-On, 0 for no change
0x01 0x3f Vol carrier volume column
0x02 0xF0 Instr instrument column
0x02 0x0F Cmd command column
0x03 0xFF Param command parameter

A pattern always contains 32 lines (although the player code breaks this out as a constant).

A 32-line x 4-byte pattern weighs 128 bytes.

Instruments (AdLib specific)

The starting address of a given instrument is:

[aSong] + [aSong + koStartOfInstruments] + 16*Instr#

The internal structure of each instrument is:

operator offset value register
modulator 0x00 Amp mod/Vibrato/EG type/Key scaling/Multiple 0x20+X
0x01 KSR/Volume 0x40+X
0x02 AD 0x60+X
0x03 SR 0x80+X
0x04 Wave Select 0xE0+X
carrier 0x05 Amp mod/Vibrato/EG type/Key scaling/Multiple 0x20+X+3
0x06 KSR/Volume 0x40+X+3
0x07 AD 0x60+X+3
0x08 SR 0x80+X+3
0x09 Wave Select 0xE0+X+3
both 0x0A Feedback/Connection 0xC0+Y
0x0B -- --
0x0C -- --
0x0D -- --
0x0E -- --
0x0F -- --

Notice the modulator comes BEFORE the carrier.

SpFX (AdLib specific)

TBD

Player

Variables

"Position" within a song needs: (order, line, tick).

If you are cranking through channel-by-channel setting registers, you will also need to internally track (channel, pattern). (channel is simply [0..kNumChannels) in order, pattern is lookup'd from order and channel). There is no point in exposing these variables as they only are mutated while the player is crunching on a tick and they do not carry over between ticks.

"Player state" is (speed, playing, vregs). playing is only toggled from outside. speed is only set by the player itself through 'F' commands. vregs is only set by the player itself via pattern lines.

"Song info" is (numChannels, startOfInstruments, startOfSpFX, startOfOrders, startOfPatterns). It only changes on song load.

Commands

Cmd Purpose
0 Arp
1 Slide Up
2 Slide Down
3 Slide to Note
4 Vibrato
5 --
6 --
7 --
8 --
9 --
A --
B Position Jump
C Fine Note Cut
D Pattern Break
E Modulator Volume
F Speed

Clone this wiki locally