Tuesday, 7 July 2020

UM3481A Series - Multi-Instrument Melody Generator

The UM348x family of sound generating devices is currently unemulated mainly due to a lack of understanding of the chip internal rom structure and data.

The sound of these devices should be familiar to many of you as they have been broadly used in many 80s and 90s low end gadgets, doorbells, etc. Bootleg arcade games have used these chips as a way to integrate music at a minimum cost.

Each chip contains a fixed number of melodies hardcoded in the silicon during manufacturing.

Sean Riddle and ClawGrip have made extensive efforts to document these devices, full decap images, sound recordings, and main mask rom dump available for UM3481A and UM3482A here: http://www.seanriddle.com/um348x/

The following notes taken during my analysis of the mask ROM array structure:

Overall view of the UM3481A chips internals with metal removed. Mask ROMs highlighted. 

Zoomed structure view of the main internal mask rom, metal removed.

To obtain usable data, individual bits from each bank are grouped together to form 7-bit words. 

The resulting data consist of 8 banks of 7 bit words containing the melody information. The pattern 100011 marks the beginning of the data space, this pattern is also used at the very end in any unused remaining space. Perhaps it resets the oscillators to not generate sound.

The word pattern 000011 signals the end of every melody. The UM3481A chip contains 8 songs, therefore we find 8x 000011 words in the data. 

The eight melodies occupy the corresponding space according to their length, melody #6 is the shorter of them all by far. 

These lengths are also observable in the WAV, the recording matches all observed melodies in the mask rom.

Most notes seem to take just one word, here's an example from the first UM3481A melody "Jingle Bells", in the song three notes repeat almost at the very beginning, this is clearly visible in the data itself. 

Longer duration notes seem to take two words, in the following example also from the beginning of "Jingle Bells",  two longer duration notes are played after the initial repeating single notes.

That's all from my observation notes, I hope the better understanding of the data structure helps the emulation of this family of sound generating devices. 

1 comment:

  1. Thanks for working on this!

    The little 16x9 ROM contains the starting offset of each song in the array:

    000 058 0A5 0D5 10F 149 166 1A5
    1F3 1F3 1F3 1F3 1F3 1F3 1F3 1F3

    These offsets match your end of song word patterns. The last 8 offsets point to the unused area at the end of the melody ROM. Interestingly, the UM3482A's 16x9 ROM has 16 unique indices, although the chip only has 12 songs.

    The number of notes in a song might not directly relate to the song's length in seconds, since one song might have lots of short duration notes and another might have fewer longer duration notes.

    I tried to interpret the wav file as notes by counting the number of cycles of square waves of different widths, and got this for Jingle Bells (note/duration):

    C5/1 A5/1 G5/1 F5/1 C5/5 A5/1 G5/1 F5/1 D5/5 A#5/1 A5/1
    G5/1 E5/4 C6/2 A#5/1 G5/1 A5/4 C5/1 A5/1 G5/1 F5/1 C5/5
    A5/1 G5/1 F5/1 D5/5 A#5/1 A5/1 G5/1 C6/4 D6/1 C6/1 A#5/1
    G5/1 F5/4 A5/9 C6/1 F5/1 G5/1 A5/4 A#5/5 A5/4 G5/2 A5/1
    G5/2 C6/2 A5/5 A5/4 C6/1 F5/1 G5/1 A5/4 A#5/5 A5/3 C6/2
    A#5/1 G5/1 F5/4

    Counting each note with a duration>1 as 2 bytes, that totals 81 bytes, although the length in ROM is 88.

    Rudolph and Happy Birthday are odd; the waveforms look weird and I count a lot more notes in those songs than in the others. So there's more to figure out.

    The 2nd byte for a long note might be a "repeat" or "hold" command. The 14th note in Jingle Bells has a duration of 2, and it looks like the byte is duplicated in the ROM (no harm, since a repeat command would also take 2 bytes).

    Wording in the datasheet made me think that there were 3 bits for duration and 4 bits for frequency in each 7-bit note, but then the longer notes wouldn't need 2 bytes.