Quick update

A project log for Project 72 - Korg DW-6000 wave memory expansion

An attempt to reverse engineer and modify Korg DW-6000s firmware in order to expand its wave memory.

mateusz.kolanskimateusz.kolanski 11/04/2018 at 18:050 Comments

Hi there. I finally managed to find some time and motivation to get back to business. Quick recap: I knew that my new code worked to some extent, but it wasn't triggering automatically and furthermore, it violated MIDI specification.

Let's analyze the second problem again (I know, I can repeat myself, but it's been a long time): in order to store more than two bits of data, I'm gonna need to split this variable into two memory addresses and do some masking and shifting. The handling of parameters is done in pretty flexible way - there's a generic handler that can use metadata provided with each parameter. This ease of use comes with some limitations though - of course it's not possible to span one parameter across multiple offsets and there's no 4-bit panel value handler too (like there's no parameter that takes values from 1 to 15, only 1-8, 0-31 and 0-63 plus some custom ones). From this point on I must consider possible routes:

a) use only 2 bits available in one adress, expand waveform memory to 4 banks, changes needed: write a 2-bit value handler (quite easy, but some memory reorganization will be necessary)

b) use the existing 3-bit handler, expand waveform memory to 8 banks, changes needed: store one bit somewhere, add custom parameter handler which will be able to read and write this bit in an adjacent address (probably hardcoded)

c) a + b - use 4 bits of memory, changes needed: custom value handler and custom parameter/memory handler

Should be doable in, well, finite time, but I'm a little bit concerned if I manage to squeeze it into available memory.

Now let's get back to the first problem: my recent hack worked only on value change. That's nice, however setting the bank number once the patch is loaded should be a no-brainer. I spent a considerable amount of time trying to track down when this happens, but without any luck. Today I tried to do it once again: I fired up my emulator and set a watchpoint on the memory area occupied by the working patch (I've probably done that before) - that's basically your buffer, each time you recall a patch from the memory, it gets copied here and each modification is stored there as long as you keep the same patch number. Well, if it gets written, then it must be also read, right? Makes sense, but I couldn't capture it. I took a closer look at the schematic again. DW6000 consists of two processor boards connected by a parallel interface. But it's TCP-like, so instead of fireing and forgetting you need to wait for an ACK signal before you can send more data, right? The ACK signal coming from the DWGS board generates an interrupt which then gets handled by our lil board. OK, that might be a clue. Let's get back to the drawing board. Uhm, to the text editor and MAME source code I mean :) I have quickly appended following code to the write handler:

if (offset == 0x4000)
  logerror("[%.4X]: write to KLM-654, data=%.2X\n", m_maincpu->pc(), data);
  m_maincpu->set_input_line(UPD7810_INTF2, CLEAR_LINE);
  m_maincpu->set_input_line(UPD7810_INTF2, ASSERT_LINE);

It's a simple mock that reacts on each write to 0x6000 (that's right, but I'm using addresses relative to 0x2000 which is the beginning of external RAM) by generating an interrupt.

And what do you know, it worked! Shortly I was able to see the whole transmission. It is basically a whole patch dump with a header (or message ID) after power on / patch change and another short message after each parameter change. 

It seems that I need to put another hook before or after patch transmission, because KLM-653 doesn't give a shit about all the parameters. It only needs to know a few: assign mode and currently displayed parameter's value. And the others are read whenever they're being modified. That's it.

More to come SOON.