Wavestation Samples dissected |
So there was it, my new Wavestation. Of course, I had looked into the service manual way before the machine arrived to notice something interesting:
The TG88 tone generator can address a total of 16MW of sample memory as 16 banks per 1MW using a 4-bit wavebank WB[3:0] and a 20-bit wave address WA[19:0]. Much more than Korg ever equipped any WS with. So what's going on?
|
Step 1: Wave memory decoding |
Instead of making full use of all banks, waveform memory is only split into two major banks:
- WB3=0 signals access to PCM ROM, Cartridge and (on the AD) the external signal input.
- WB2=0 signals access to the internal connectors CN16/CN17 only found in the WS and EX (but not the AD; there, WB2 is n/c). A potentially perfect space for hacking in own samples -- assuming that the OS really checks this area. If not, OS hacking is required.
Quite wasteful! Properly decoding this would give 4 pages per 4MW instead of just two.
A page is broken down with the help of WB[1:0] and WA19. Let's treat them in this very order as a 3-bit number and get the following page structure with each part being 512MW (1MB) in size:
Page | Offset (W) | Offset (B) | PCM Data | Comment |
0 | 0x00.0000 | 0x00.0000 | classic ROM #1 | IC9 on WS/EX, IC8 on AD; MSB only |
1 | 0x08.0000 | 0x10.0000 | classic ROM #2 | IC8 on WS/EX, IC7 on AD; MSB only |
2 | 0x10.0000 | 0x20.0000 | classic ROM #3 | IC7/6 on WS/AD, IC6/5 on AD |
3 | 0x18.0000 | 0x30.0000 | external signal | WA18 separates left/right (only AD) |
4 | 0x20.0000 | 0x40.0000 | PCM card | only WA[17:0], no WA18 |
5 | 0x28.0000 | 0x50.0000 | EX ROM #1 | IC5 on WS/EX, IC3 on AD; MSB only |
6 | 0x30.0000 | 0x60.0000 | EX ROM #2 | IC4 on WS/EX, IC2 on AD; MSB only |
7 | 0x38.0000 | 0x70.0000 | EX ROM #3 | IC3/2 on WS/EX, IC4/1 on AD |
- In order to save cost, Korg stored single-cycle and other low-dynamic waveforms just as 8-bit quantities. For these, the LSB value is always 0x00 by hardware.
- Page 3 is only used in the AD, not the WS or EX (where it is empty). While WA18 separates the audio channels, there's seemingly no stereo wave signal processing in the other pages.
|
Step 2: PCM data decoding |
Now the fun begins. How does the WS access its PCM data? Luckily, I was able to get hold of the EX ROM dumps, so I didn't have to desolder these. (Anyone having a dump of the classic ROMs, feel free to send me the dump for further analysis!).
In case you want to join in, here's the two EX ROM #1 images fused into a single file, my quick and dirty analyzer tool, and an example log.
So let's concentrate on EX ROM #3 which, unlike #1 and #2, is fully attached (all 16 data lines). And, indeed, there we find management data:
Offset | Size | Data |
0x00000 | 4 | "KORG" marker |
0x00004 | 2 | Index marker (0x000f for EXROM, 0x001e for WS Classic, 0x001f for cartridges) |
0x00006 | 10 | Name (empty on ROMs / 0x00, seemingly only used on cartridge) |
0x00010 | 8 | User-wave reference #1 |
0x00018 | 8 | User-wave reference #2 (presumed, empty in EX ROM) |
0x00020 | 8 | Wave-map reference #1 |
0x00028 | 8 | Wave-pointer reference #1 |
0x00030 | 8 | Wave-map reference #2 (copy of #1 in EX ROM) |
0x00038 | 8 | Wave-pointer reference #2 (copy of #1 in EX ROM) |
0x00040 | ... | Data area, all samples are 16-bit signed |
Offset/Size given in bytes
The 8-byte references hold the following information:
Offset | Size | Data |
0x00 | 4 | Page-based offset to management data |
0x04 | 2 | Number of entries in referenced table |
0x06 | 2 | Flags: 0x0083 / 0x0059 for classic/EX WaveROM reference (classic / EX set), 0x0000 otherwise |
Comments:
- Interestingly, the number entry only holds true for references to user-waves and wave maps. For wave-pointer references, not the number of actually present wave pointers is given, but the number of wavemaps is repeated.
- Page-based offset assumes 16-bit data access, so it's only half of what you'd expect for a byte-sized dump.
- No idea about the flags yet.
User waves are simple beasts, consisting of just the following:
Offset | Size | Data |
0x00 | 2 | Index to wave map table (start entry) |
0x02 | 1 | Wave type: 0x00 (multi-cycle waves) or 0x01 (single-cycle waves / VS waves) |
0x03 | 1 | Number of entries (zones) in wave-map table (0x00 for VS waves) |
0x04 | 10 | Name as fixed-size ASCII char array |
Offset/Size given in bytes.
Comments:
- The VS waves don't have an entry in the wave-map or the wave-pointer list as they follow a simple mapping approach:
- Single-cycle waves (VS waves) are marked with 0x00 entries in the map table.
- They reside at the start of ROM #1.
- Each VS waveset comprises 2427 samples containing 9 individual mipmapped waves of fixed size: 514, 364, 514, 364, 258, 183, 130, 66, and 34 samples; seemingly for the lower 3 octaves there's a half-octave stepping (2^0.5=1.41=514/364=258/183), for the upper 3 octaves there's only full-octave stepping.
- Indexing hence is simple: zero-based wave no * 2427 + mipmap offset
Wave-map entries are already a little more obscure:
Offset | Size | Data |
0x00 | 2 | Index to wave pointer table |
0x02 | 1 | Zone top note as MIDI note number |
0x03 | 1 | Flags: seemingly always 0x05 |
0x04 | 1 | Fine-tuning as 8-bit signed quantity (possibly cents, max values -82 and +97) |
0x05 | 1 | Reference key as MIDI note number |
0x06 | 1 | Flag, mostly 0x00; only few discrete values in the [0xdf:0xff] range
(df,e8,e9,ed,f0,f2,f3,f4,f5,f6,f7,f8,f9,fa,fb,fc,ff)
ff only as ff/ff, f7 as f7/00 or f7/f6 (see flag 0x07)
|
0x07 | 1 | Flag, mostly 0x00; only two discrete values (0xf6, 0xff) |
0x08 | 2 | Flags, always 0x0000 |
Offset/Size given in bytes.
Wave-pointer entries, in term, are less of a mystery:
Offset | Size | Data |
0x00 | 2 | Flags, mostly 0x0000; only few distinct values found (0x0000, 0x0034, 0x03a5, 0x03b7, 0x0600, 0x0981, 0xfa00, 0xfda6, 0xfeed)
|
0x02 | 3 | Waveform start address |
0x05 | 1 | presumed unused, 0x00 |
0x06 | 3 | Loop start address |
0x09 | 1 | Loop flags: one-shot (0x00) or looped (0x04) wave |
0x0a | 3 | Loop/sample end address |
0x0d | 1 | presumed unused, 0x00 |
Offset/Size given in bytes.
Comments:
- For data cartridges, the above analysis holds true as well -- just that all management block data is word-aligned w/ only odd-address data being used as 8-bit quantity. Seemingly, the CPU treats cartridge memory differently from the ROM and allows only 16-bit accesses there.
- With 16M address space, only three address bytes are needed. However, the TG88 can only do word accesses and hence has to fetch 2*2 bytes. Consequently, the 4th address byte contains flags such as the loop flag (0x04).
- What also becomes obvious from looking at single-cycle wave lengths and loop-end vs. following sample-start addresses is an offset of two bytes (e.g. 514 byte wave-length instead of 512 or next sample starting 2 bytes after the previous sample's loop end). This most likely means that the TG88 does 3-point sample interpolation.
| Step 4: TG88 considerations |
Korg's TG88 aka MB87726 is another Fujitsu ASIC, like so many custom chips used in Japanese synthesizers (cf. also Casio). Looking at the schematics reveals the following:
- The Audio interface has 20-bit output data OD[19:0] and 5-bit voice number VN[4:0] plus output waveform enable OWEF. This feeds the digital filter chip DF88 (MB87727).
- It comprises a DRAM interface of four individual banks (4x RAS/CAS/WE). Not sure if this needs to be specifically activated by MMODE=1.
- The CPU interface is implemented in true 16-bit, i.e. an 8-bit address space of (256) 16-bit registers. (DMODE=1)
Following the schematics, TG88 occupies a memory region of 1k. OS analysis confirms this, TG88 sits between 08.0000 to 08.03ff and is seemingly divided into 32 blocks of 32 bytes (16 words), which nicely matches the 32 osc architecture. Unfortunately, the meaning of the individual registers is less obvious from a quick code analysis:
Offset | Register | Name |
00 | C/S | command/status (two status bits: 0/1) |
02 | | extra information contained in a 32-bit adress+flags word |
04 | | address pointer [15:0] |
06 | | address pointer [23:16] / (y&0x0f)|(z<:<4) |
08 | | updated before 0a |
0a | | updated after 08 / (y&0x0f)|(z<<3&0x80) / 0x60 |
0c | | address pointer [15:0] |
0e | | address pointer [31:16] |
10 | | frequency related (paired with 12); one of 100 16-bit values ranging 0000-7fff from 0xC02618 (pitch-ramp time?) go here. |
12 | | frequency related (paired with 10); frequently getting 0x8001 together with 10 cleared |
14 | | 0xffff written here |
16 | n/a | seemingly unused |
18 | n/a | seemingly unused |
1a | VNE | smells like voice number for getting initialized w/ 0-31 and later being updated. Bit 7 might be voice enable. This register might drive the VNx pins and maybe OWEF. |
1c | n/a | seemingly unused |
1e | n/a | seemingly unused |
What would I expect to be up there:
- PCM sample memory access (2x16 bit address register plus 16 bit data register), after all the wave management data including wave names need to be fetched from there (and there's PCMWx signals on the TG88).
- Wave and loop start addresses
- Wave and loop end addresses
(first ony only in case in case TG88 can do loops other than "loop end = sample end"
- Tuning / incrementum, at least 16 bits, probably more
- Control (play/stop, hard-sync, forward/alternate looping, loop/one-shot, loop repeat count if handled by TG88, output channel)
- Status (playing, sample-end reached, bus busy ...)
- Volume, if that is not handled by DF88
|
|