TOM Cartridge Header Information R. Grieb 4/21/2016 Note: This information is based on the TOM code disassembly and some testing done with a Z80 ICE and a TOM unit, and may contain errors. Although cartridges are removable and the internal sound EPROMs were fixed, there is no actual difference in how they are handled. The header format is the same. In fact, cartridge EPROMs can be installed in the IC sockets inside the TOM if desired, although since the SCI cartridges only have seven sounds in them, you would no longer have eight different sounds available. Sound cartridges for the Sequential TOM may contain either one or two 27256 EPROMs or ROM chips. These chips contain sample data in 8-bit uLaw format (not 8-bit PCM). uLaw coding was used in many drum machines during this period, and requires a special companding DAC (DAC-86) to uncompress the samples on playback. It improves the signal-to-noise ratio without increasing the number of bits. Sampling frequency is 22.7 KHz but playback frequency can be varied in the TOM. In addition to the waveform samples, header information is provided that tells the TOM how many sounds there are, where they are located, how long they are, and whether or not to enable the filter when playing them. Only the low 4-bits of each EPROM byte can be read by the Z80, so the values in the header are only in D3-D0 and the upper bits are 0's. Also, the Wonder chip requires the data to be placed in every other byte, for access by the Z80. The header data is placed in the first 256 bytes of the EPROM. Sound data starts at address 256. This is not required by the hardware, but some bytes in the first 256 are actually sent out as samples in-between playing the sounds, so they need to be 00's. Here is the format for the header data: (any header bytes not listed would be 00's) Offset (in hex) Description of data in low 4 bits 03 0x05 byte. The TOM code checks for this value. If not found, this EPROM's header is not read 05 0x0A byte. The TOM code checks for this value. If not found, this EPROM's header is not read 07 Number of sounds in this header 09 Bits 4:1 of starting address value (first sound, note that bit 0 is not included). This nibble must be 0! 0B Bits 8:5 of starting address value 0D Bits 12:9 of starting address value 0F Bits 16:13 of starting address value (but A15 and A16 bits would be 0's) (Note that sound starting addresses must be exact multiples of 32) 11 Bits 4:1 of sample count value (first sound, note that bit 0 is not included) 13 Bits 8:5 of sample count value 15 Bits 12:9 of sample count value 17 Bits 16:13 of sample count value 19 Config Byte, If D0 is 1, a 12 dB/octave low-pass filter with a cutoff of 4.5 KHz is enabled for this sound. If D0 is 0, the filter is bypassed and no filtering takes place. (D2 is also set for some samples, but the TOM code does not seem to read this bit) 1B Bits 4:1 of starting address value for the second sound 1D Bits 8:5 of starting address value etc... It seems that the Wonder chip always clear the register data at offset 09, probably to save gates in the chip. So regardless of what you write here, the value will always be 0. This means that sounds must start on 32-byte boundaries in the EPROM. Also, I noticed that all of the sounds in the I610 ROM have at least 3 bytes of 00's after the last byte of each sound. In one of my EPROMs I had just 2 bytes, and I was getting a faint click at the end of the sound. So I would suggest making sure that you always have three 00 bytes after every sound to avoid any issues. In general, we might expect that the values in the header would correspond to samples stored in that same EPROM, but this is not always the case. If a cartridge contains two EPROMs, one option is to put all of the header information in one EPROM, pointing to waveforms stored in both chips. The Special Effects SCI cartridge is set up this way. The header of one of the EPROMS is all 00's. Also, it is possible for both EPROMs to have sound data in their headers, but to point to sounds that are in the other EPROM. One of the SCI cartridges is set up this way. There is no requirement to have two chips in a cartridge. The SCI Latin cartridge has just one EPROM which contains all seven sounds. When the TOM code reads the headers, it reads all four of them, starting with the internal chips first, and then the cartridge. It does this on power-up and whenever a cartridge is inserted or removed. The total number of sounds is limited to 15. These are assigned to the switches in order, so if the internal EPROMs only had 7 sounds in them, then the cartridge sounds would begin with the last switch to the right. The internal EPROMS I610 and I611 have 8 sounds in them. The SCI cartridges each have 7. The TOM code stops reading EPROM headers when the number of sounds in an EPROM would put the total over 15. So if we had the internal 8 sounds plus a cartridge with two EPROMs in it, each with 4 sounds in it, the TOM would not read the second EPROM of the cartridge, since that would put the total at 16. So we would end up with just 12 sounds in this case. I have modified my TOM code to read the first 15 if there are 16 sounds, which is important for my project. Why is that important? You might ask. My TOM16cart design allows placing any "cartridge" in either of the two actual "slots" (internal and cartridge). If I put only 7 sounds in each cartridge, as SCI did, then if those are placed in "slot 0", the next cartridge's sounds would start with switch 8, instead of switch 1. So the position of sounds relative to switches would vary depending on which slot a cartridge is placed in. That would be annoying. So the easy solution is to have 8 sounds in every cartridge. If that cartridge is placed in "slot 0", all 8 sounds will be available, and the next cartridge will start at switch 1. If the same cartridge is placed in "slot 1" instead, only the first 7 sounds will be available, so it's important to pick the least important sound to be the last sound on each cartridge. There is special code in the TOM firmware that checks to see if the button for sound 5 (normally closed hat) is pressed while open hat is playing. If this happens, the closed hat sound is assigned to the same hw channel that was playing open hat, so the open hat immediately stops when the closed hat starts playing. The code checks for instrument buttons 4 and 5, but not if the cartridge instruments are selected. Here are steps to make an EPROM for inclusion in a cartridge: 1) Pick wave files to be used. You may need to pick fewer or different ones later if they don't all fit. You can store a maximum of 1.43 seconds in each EPROM. 2) Edit wave files to remove silence before or after the sound, since it just takes up space. 3) Convert wave file sampling frequency to 22.7 KHz for TOM. 4) Convert sample files from 16-bit .wav to 8-bit uLaw-encoding. One way to do this is with Paul White's dmxwav program at electrongate. The DMX output format does not have any header, and works for the TOM as well. I should mention that there seem to be some subtle details involved in converting from 16-bit samples to 8-bit uLaw ones. I have found that Cool Edit 96 does a slightly better job than dmxwav in terms of the noise level of the uLaw waveform. I guess there are a number of programs that can do this conversion. One thing to watch out for: The uLaw std calls for the 8-bit values to be complemented after they are created. This had to do with optimizing transmission over telephone cables, I think, and doesn't apply here, of course. But some programs (Cool Edit 96, for instance) complement the samples before writing them to the file. To use these samples in the TOM, I had to complement them after reading from the file to get back the "real" uLaw values. The dmxwav program does not complement the values, so they can be used directly. 5) Select seven of the uLaw-encoded files that will fit into two EPROMs. Each EPROM has 32,768-256 or 32,512 bvtes in it that can store sounds. Split your sounds into two groups, based on what will fit into each chip. 6) Sounds need to start on addresses that are integer multiples of 32 in the EPROM. You will lose a little space due to this restriction. One way to accomplish this would be to add 0 bytes at the end of each sound dmx file to make its length a multiple of 32. 7) Merge sound files together to create part of an EPROM image. The total length should be 32512 bytes. Bytes after the last sample can be 00 or FF. Probably safest to add 00's to the last sample to make it a multiple of 32 bytes, then fill the rest of the EPROM with FF's. 8) Create a header that contains the starting addresses, lengths, and filter control for each sound, assuming that the sound data will start at address 256 (0100h) in the EPROM. The order of the sounds in the header will determine which instrument switch they are assigned to, and does not need to match their placement order in the EPROM. The TOM will select CS6/I610 (cartridge pin 18) first, then CS3/I611 (cartridge pin 2), and will assign sounds to switches in the order it finds them in the two headers. 9) Merge the header with the sound data to create a binary file that contains exactly 32,768 bytes. 10) Program a 27256 or 27C256 EPROM