Alley Cat Tandy Music Format

From ModdingWiki
Jump to navigation Jump to search
Alley Cat Tandy Music Format
Format typeMusic
Notation typeCustom
InstrumentsSN76496
Max channel count3
Max track countUnknown
Max pattern countUnknown
Max order countUnknown
Tags?None
Games

The Tandy edition of Alley Cat stores a three-voice title tune in TANDYCAT.EXE. Separate byte lists supply notes and durations for each voice. The format and player differ from the IBM PC title tune.

File format

All offsets on this page are native Tandy DS offsets. Add 0x6940 to obtain a file offset; do not apply the IBM-to-Tandy address map. Words are little-endian.

DS offset Data type Contents
0x1014 UINT16LE[] Tone-divisor lookup data
0x1231, 0x123A, 0x1243 9-byte voice records Per-voice playback state and list pointers
0x124C UINT16LE[3] Pointers to the three voice records
0x1254 UINT16LE Runtime arrangement pass, stepped by 2
0x1256 UINT16LE[4] Highest active voice offset per pass: 0, 2, 4, 4

The RE notes describe each voice record as countdown, attenuation, index word, channel bits, note-list pointer and duration-list pointer. The viewer directly decodes the two pointers as follows:

Record-relative offset Data type Meaning
5 UINT16LE DS pointer to note bytes 7 UINT16LE DS pointer to duration bytes

The other fields are mutable player state; the viewer reconstructs countdown, attenuation and index in its own objects. At sequence index i, read notes[i] and durations[i]. There is no stored sequence count.

Note byte Meaning
0x00 Mute this voice
0x86 Reset this voice index to zero and fetch again; voice 0 also advances the arrangement pass by 2
Other Read a UINT16LE at DS:(0x1014 + note) and use its low 10 bits as the tone divisor

As in the IBM tune, the note byte is a byte offset, not a word index. The parallel duration byte supplies the countdown. Validated playback should follow the decrement-before-fetch behaviour of tandyTune(); a zero duration is not documented as an end marker.

Playback

The player runs once per BIOS tick with PIT channel 0 programmed to CFFFh:

secondsPerTick = 53247 / 1193182
frequencyHz = 3579545 / (32 * divisor)  (for a non-zero divisor)

This gives about 22.41 ticks per second. A new audible note sets attenuation to 3. On subsequent ticks while the note's countdown remains non-zero, attenuation increases by 2 until 0Fh (silent). A rest immediately mutes the voice.

Voice 0 is enabled on the first pass, voices 0–1 on the second and all three on the third and fourth. The arrangement table is indexed by (pass & 6) / 2; its values are compared against 2 * voiceNumber. The loop markers allow continued playback; the viewer chooses to reconstruct four passes rather than treating the fourth pass as an encoded end marker.

Notes

  • The RE notes report 288 ticks per voice sequence, 1152 ticks for four passes, and an exact comparison of reconstructed audible divisors and attenuation against 4214 writes to port C0h over 1153 player ticks in DOSBox.
  • The full Tandy game is not ported. This article describes the independently reconstructed title player and its tables, not a complete Tandy sound-effect decoder.
  • The viewer guards reconstruction at 20000 ticks and limits consecutive loop-marker retries. Those are reader safeguards, not fields in the executable.

Source code

From re-alleycat, the open-source HTML5 port (revision b003aa63ffbb):

  • viewer.html – tandyTune(), playTandy() and native Tandy pointers
  • docs/RE_NOTES.md – Tandy player analysis, timing and chip-write validation

Credits

This file format was reverse engineered by VorticonCmdr. Please credit the original research when using this information in your own project, and include a link back to this wiki.