Ozawa Driver - grgowski/WSGSound GitHub Wiki

The "Ozawa" driver has been used in four titles: The Tower of Druaga, Dig Dug 2 and Motos (Super Pacman hardware) and Toy Pop (System 16 Universal). The hardware is very similar featuring a Mappy hardware board consisting of two 6809 CPUs: the main and sound one. The RAM memory is mapped between both CPUs so that addresses starting from 0x4000 for the main CPU correspond to addresses starting from 0x0000 for the sound CPU. The sound driver is located in 0xE000.

The songs and sound effects are stored as patterns. The address table for the patterns is hardcoded for each game (see Table below). The pattern data contains a series of addresses for individual tracks followed by a byte indicating the note tuning (0-2, or -12,0,12 cents) and terminated by 0xE0. The note scales contain 3-byte frequency register values for 12 notes. The patterns are assigned to specific voices by RAM address mapping. The scales and RAM mappings are stored in values depicted in Table 2. [It looks like specific RAM addresses are dedicated to specific voice assignments e.g. 8-track music at 0x02C2 but 4-track music at 0x023B allowing sound effects to be played simultaneously. This requires further investigation.].

The individual tracks contain commands responsible for voice, volume and track control, and notes. The commands are indicated by bytes >= 0xF0 followed by a number of value bytes (0-1). The notes are represented by two bytes: AB CD, where A indicates the note (0-B), B indicates the octave (freq. divider) and CD is the duration in clock ticks * F2.

command value description
F0 X0 waveform number
F1 XX volume envelope
F2 XX duration multiplier
F3 - end of track
F4 XX YY YY conditional jump to address YYYY XX-1 times
F5 XX YY YY conditional jump to address YYYY after XX-1 repetitions
F6 YY YY jump to absolute address XXYY
parameter The Tower of Druaga Dig Dug 2
notes $E685 0xE581
songs 0xE5E5 0xE46D
volume fx $E517 0xE4DB
RAM map $E645 0xE4AF

Waveforms

The WSG 15xx is internally clocked at 24 kHz (rather than 96kHz as in the original Pacman 3-voice hardware). The 15xx features 8 voices each featuring a 20-bit accumulator which is used to select a 4-bit volume value from one of the 8 waveforms (32 values each). The value of the accumulator is increased by the value of the freq register and the top 5 bits of the accumulator are used as an index for the wavetable. The relationship between register values and actual frequencies are represented by the following expression: freq = reg_val * clock_freq / 2^reg_size, which results in freq = reg_val * 24000 / 2^20 for the WSG.

Scales

The three note scale lookups store WSG register values corresponding to the notes on a 12-note scale. The 0 index represents an A7 midi note (105) and the consecutive indices represent half-note increments. The final entry ($C) contains all zeros and is equivalent to note off. The 12 WSG register values can be further divided by an octave parameter to cover the entire range of musical notes (/2^octave). The following table presents an example mapping between index values and midi notes for octave divider 3 resulting in the first note being A4.

command note
0 A4
1 A#4
2 B4
3 C5
4 C#5
5 D5
6 D#5
7 E5
8 F5
9 F#5
A G5
B G#5
C note off

The three lookup tables correspond to the scales with a small offset in base frequency (for the chorus effect) corresponding to the A4 note base frequency of 437, 440, 443 Hz respectively (-12, 0, 12 cents).

Volume Envelopes

There are 27 volume envelopes. Each envelope consists of a series of volume values and/or modifiers terminated by $10. All modifiers are indicated by bytes >= $10.

modifier description
10 ends the envelope, keeps the last value
11 ramps down to the next value
12 ramps down with decreasing note duration
13 resets the envelope (repeat)
14 does not reset the envelope on new note

Track info in RAM

offset description
00-01 current event ptr
02
05 current volume
06 wave nr (F0)
07 current duration in ticks
08 duration multiplier (F2)
09 volume command (F1)
0A-0B volume envelope pointer
0C scale nr (track info)
0D repetition counter for conditional jump F4
0E repetition counter for conditional jump F5

Interesting Bits

The sound routine stops playing a song after the first F3 command is encountered. This implementation hides some peculiar behaviour in songs 7 and 28.

In song 7, the second conditional jump (F4) in track 4 goes back to $FD76 which takes it before the first conditional jump taking it to the same place. This causes an infinite loop which is prevented only by the aforementioned behaviour of the sound driver. The most likely command in that track should have been F4 03 FD 7C which would correspond to a conditional jump just after the first one, similar to other two tracks.

In song 28, tracks 3-5 use the same pattern which has a missing F3 command at the end.

In song 5, there is potentially miscoded note which sounds off but that is difficult to judge as it might be an intentional procedure.