Close
0%
0%

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.

Similar projects worth following
One day I stumbled upon Chris Strellis' Korg DW-6000 256 Waveforms Mod. What a great mod, I thought, but unfortunately Chris didn't want to share his overengineered (at least that's what I was thinking back then...) CPLD design. Furthermore, I like the factory look of my gear, so cutting holes is definitely a no-go. My DW-6000 was broken, so I spent a reasonable amount of time fixing it. Reading schematics gave me this crazy idea, that if I could drive the unused half of upd7810's port B, I could address 16x more waveform memory than the DW does just by soldering 4 wires from the CPU to the ROM chips. That sounds way more simple than using a CPLD chip.

Well, let's see if I manage to reverse-engineer this thing and squeeze some code in 72 remaining bytes...

Korg DW-6000 is a 6 voice polyphonic synthesizer from 1985. It's hybrid, because its tone generators are digital (sample based), but amplifiers and filters are analog. DW-6000 has been superseded by his bigger brother, DW-8000 which featured more waveforms (16 instead of 8), more voices (8 instead of 6), digital effects section (well, I think that the DW-6000's analog chorus is way better than DW-8000's digital delay, but you know, back then - c'mon - it's digital dude, and digital is better).

Internally, DW-6000 consists of 3 main boards:

  • KLM-653 - programmer / assigner board - (this is the board I'm working on)
  • KLM-654 - generator (here be voice ROMs)
  • KLM-655 - analog board

This is how it looks like on a block diagram:

DW-6000 block diagram

The idea (at least from electrical point of view) is fairly simple:

  • replace the stock ROMs (KLM-654, IC29 and IC30 - HN613256, 256 kb) with bigger ones (4 Mb) and fill them with some new waveforms
  • connect four unused address lines (A15-A18) to PB4-PB7 of IC1 (uPD7811, KLM-653)
  • modify DW-6000s firmware to implement bank switching mechanism - add a new parameter (14) with 4 bit resolution (1-16), which will tell the CPU to set a value on PB4-PB7

more paint masteryP.S. I have started this project some time ago and I didn't pay much attention to logging activities, that's why I'm adding a whole bunch of stuff right now and that's also why I'm missing some dates. Once I'm happy with my backlog, I will make this project public and start logging things as they appear.

DWLUTION_1.0.zip

DWLUTION 1.0 a.k.a. everything you need to modify your DW6000.

x-zip-compressed - 2.84 MB - 04/07/2019 at 20:38

Download

  • RELEASE DAY! FINALLY!

    Isa Twospirit04/07/2019 at 20:46 0 comments

    Although it took some time (well, basically we've been doing all sorts of things leaving the release for 'the other day'), we made it. DWLUTION 1.0 - this is how we call our project - is finally here. You can download the file and expand your synthesizer - without drilling extra holes :)

    You probably don't want to dive too deeply into the rather uncommon format the DW6000 saves its waveforms - no problem, we got you covered with DWLUTION Waveform Manager.

    Since we have a few spare boards and a lot of stickers - shout if you'd like to have one.

    Oh, at the time of writing this, V2 is in the making and it's gonna be huge, so stay tuned for more :)

  • A way to manage waveforms

    Isa Twospirit03/01/2019 at 11:44 0 comments

    With the hardware part working and functional, it was about time to think about how to fill the expanded WaveROMs.
    Of course one could manually hack binary files, but - that's uncomforatable even with regular WaveROM formats, and a pest with the rather complex format used in DWGS synthesis.
    Luckily, someone (=me) had a bit too much time at hand and came up with a tool to make it easier:
    The DWLUTION Waveform Manager.
    Right now, we're in the process of doing some final tests before releasing it, but here's a little preview of what you can do with it.

    The Waveforms used need to come from $somewhere, so there's several options of importing or creating them:
    - Import WaveROM dumps or .wav files containing single-cycle waveforms:
    - Draw Samples:
    - Create complex Waveforms using... well, something probably best described as extended additive synthesis:
    With the Waveforms created or imported, we can create new WaveROMs (for standard DW6000 and DW8000 and, of course, the extended format for this mod):
    And because we (or at least I) don't want to remember where which waveform resides, the export function not only creates binary files that can be burned to EEPROMs, but also a Waveform cheat sheet that can be printed out and fits the dimensions of the waveform list on your DW6000:
    What's missing?
    Oh, of course you'll want to prelisten to the waveforms. No worries, we got you covered. The piano roll on the bottom of the main form will always play the currently selected waveform at the selected pitch:
    Stay tuned for more!

    Cheers,
    Isa


  • PCBs

    mateusz.kolanski12/14/2018 at 19:08 0 comments

    Some time ago I have designed and ordered a few adapter PCBs. Finally they have arrived!

    They are looking really good, I just messed up the silkscreen - JP1 should be labeled L321 instead of L123. And the whole PCB is kind of upside down, but I'm really happy how it turned out, not bad for a first PCB:) 

    This is how it looks after assembly:

    I have decided to put some LEDs (just in case). JP1 is not populated yet, they ran out of angled connectors in my local shop and I didn't want to wait the whole weekend. Fortunately I found an old floppy connector lying around and after some tweaking I got it installed.

    Looks nice!

  • ...fixed

    mateusz.kolanski11/19/2018 at 20:27 0 comments

    Looks like it helped, yay!

  • Debugging the hardware

    mateusz.kolanski11/19/2018 at 20:14 1 comment

    Hi there, since my last post I've been waiting for the new batch of memory chips. EEPROMS this time for convenience sake. I got them today, burned the new firmware (the one with bank switching routine surrounded with DI/EI), installed it, but unfortunately it's still glitching. I've (CAREFULLY) hooked up a logic analyzer and gave it a go. 

    No magic smoke this time :)

    I've found the reason why it sometimes fails. Look at this pic first:

    You can see, that D0 goes high, then after 6us CLK goes low and after 5us more it goes back high. This is when '374 does the switching (see transition @Q0 and Q1). So far, so good. But this is how it looks when it glitches:

    You can clearly see that the clock pulse is way longer than before and the rising edge misses whatever has been set ad D0..D2 inputs. Why? Well, normally I would say, it's an interrupt. But this code should be interrupt safe now!

    Yeeeah, should is a good word. Take a look at my 'smart' code again:

    .BSHND:	EQI	E, 22H		; ID == 22? (1-4 ,select bank)
    	JR	.NOBS		; nope, skip
    	LTI	D, 04H
    	JR	.MORE
    .LESS:	ANIW	82H, 3FH	; unset 6th bit @ $2682
    	JR	.BS		; that's all, we can set the bank number
    .MORE:	ORIW	82H, 40H	; set 6th bit @ $2682
    	ANIW	81H, 7FH	; unset 7th bit @ $2681
    	DI			; I wonder if it helps...
    .BS:	CALL	.BANKSWITCH	; call bank switch routine
    	EI
    	JR	.11E1H		; and skip KLM-654 transmission part

    It will clearly only work if you go through the .MORE branch. Going through .LESS causes the jump to .BS label which skips DI instruction! D'oh.... OK, let's move the .BS label to the previous line, build the binary again, burn it and test it. Se you later :)

  • It works!

    mateusz.kolanski11/12/2018 at 21:12 0 comments

    Yes, it does! Finally after too many hours spent on it I've installed everything inside of my DW6k, flipped the switch and... no magic smoke! But let's take a step back. 

    First I've desoldered the original ROMs and installed machined sockets.

    After making sure, that it still works, I've soldered some wires directly to the CPU (notice the battery:)) ...

    ... double checked and installed my ghetto adapter (since it works, I will make a nice PCB soon) with HC374 and two W49F020s full of waveforms ...

    ... looks nice, yet a little bit messy, "hardware debugger" on the right :) ...

    ... and it works! I've been playing a few minutes and the new waveforms sound really great. I'll post a few samples soon, maybe even a video to show you that I'm not making this out :)

    The only thing to address is the occasional glitch during bank switch, after that I'll order a small batch of PCBs, test it again and we're good with V1.0 :)

  • Another quickie

    mateusz.kolanski11/12/2018 at 17:46 0 comments

    I've added another feature to my emulator: now I can watch port B's upper half and the latch signal on port C. It looks like everything's fine, I couldn't reproduce the glitch I saw on the real hardware. But from the other hand, I'm emulating an isolated portion of the original hardware, so your mileage may vary. I suspect, that the bank change routine may be sensitive to interrupts, so once I get my 2864s, I'll try to disable interrupts before executing it.

    Other than that, I've assembled a memory adapter on a veroboard, but didn't have a chance to test it yet. I don't know if driving address lines connected in parallel it's something HC374 can do without hiccups, we'll see. First I need to prepare waveform banks, I will probably use Isa's wonderful piece of software for that purpose. 

  • Facepalm!

    mateusz.kolanski11/10/2018 at 20:30 0 comments

    Ok, it turns out that mame debugger can load/save memory from/to file. I've downloaded a sysex file containing 64 factory patches, cleaned it up and loaded it in debugger. I've edited first 8 patches again, setting bank number from 1 to 8. Save, restart, load - all was there. No idea why it didn't work on the hardware. Maybe I have saved patches 2-1 - 2-8 and loaded 1-1 - 1-8 instead? No clue. I have also added the NOP instruction between latch pulses - maybe that's why it sometimes doesn't work, who knows. At least I had one free byte for my disposal :)

    I got back to the synthesizer (of course with the old ROM, because I have nothing to write the firmware to), played with it a little bit only to confirm, that sometimes changing bank number from 2 to 3 doesn't work as it should - instead of 3 it sets 0. Other combinations seem to work fine, so I doubt it's a timing issue... Maybe I'll hook up my logic analyzer (be careful this time:>).

    Oh! I almost forgot! I know why the bank numbers were messed up after reboot - there's no SRAM battery on the mainboard! FACEPALM! But that solves one of my problems :)

  • Almost there

    mateusz.kolanski11/10/2018 at 16:53 0 comments

    Hi there, after some struggle I've managed to get even closer to the end. What I got now is an almost working version. Yes, this time I have burnt an EPROM (the last empty one I had - I don't have an eraser, but I've already ordered some EEPROMS) and tested in on real hardware.

    What works?
    • the new parameter 1-4 is unlocked and you can change its value from 1 to 8
    • LEDs connected to upd7810 show the correct binary value (i.e. port and latch are working fine)
    • you can save and recall the bank number to/from SRAM

    Looks nice, huh? So what's wrong?

    • sometimes even if the value is set properly (cycling from 1 to 8), it doesn't get send to the hardware (now I need to figure out if it's because of wrong value being read or set)
    • after restart, saved bank values are messed up

    I have an idea why the first problem occurs, it's probably because the bank switching handler is not interrupt safe. Even if the fix looks easy to implement, I have another problem - keep reading.

    As for the second part, I think I could modify my emulator so that the SRAM is not handled as an ordinary RAM but rather saved and loaded to a file. That would give me an opportunity to see how it behaves after reboot.

    Now, my biggest problem is the available memory, or lack of it. I managed to squeeze my code into the EPROM, but I had to sacrifice a few lines of code to do that. Some time ago I said, that my plan B would be to remove tape saving and loading routines, because that's someting nobody's gonna use, especially if there's MIDI available. So far I have removed the code that clears the value on displays before writing TAPE on them. Not a big deal, now it looks more like TAPE_1 or TAPE<whatever walue was set>. I think, I will remove saving to tape first, because even if there's a slightliest chance, that somebody has some old patches stored on tape or wave file, I really doubt that anybody would like to save anything back to tape...

    I may have another session with debugger this weekend. I'll keep you informed.

  • Stack Overflow!

    mateusz.kolanski11/07/2018 at 20:27 0 comments

    No, I'm not browsing SO looking for help. I'm experiencing it right now :) After I found the definitive places where I'm going to inject my code, I noticed that my .BANKSWITCH 'thingy' must become a callable subroutine. Blah blah blah... Wait a minute, I think I know why it fails. BRB

    [10 minutes later]

    Hi there. I started writing this post because - for some strange reason - my debugger decided to crash. Not once, not twice, but all the time. I didn't quite expect this kind of behaviour, but when I loaded vanilla ROM, it was rock stable again. OK, quick look into GIT and I quickly figured out that the only change was my dreadful subroutine I created yesterday. I needed a callable sub to be able to, well, call it from different places. The biggest limitation of the previous one was the arbitral jump into the place it should go back plus the fact, that it completely relied on values in registers. This is the old one:

    MOV	A, D		; bank number (0-7) stored in D, copy to A
    SLL	A		; store in high nibble
    SLL	A
    SLL	A
    SLL	A
    ;OFFIW 	82H, 40H	; check if $2682 bit 5 is set
    ;ORI	A, 40H		; yes, we have 'carry'
    MOV	B, A		; store in B
    DI			; enter critical section
    MOV	A, PB		; get current PB
    ANI	A, 0FH		; wipe high nibble
    ORA	A, B		; join together
    MOV	PB, A		; speak to hardware
    XRI	PC, 04H		; enable latch (PC2)
    NOP			; wait
    XRI	PC, 04H		; disable latch
    EI			; enable interrupts
    JMP	.11E1H		; go back (label is my guess:)

    The jump back was actually spot-on (I figured it out after some more cumbersome code analysis), but like I said it didn't fit at all in the other place. This is what I ended up with:

    LDAW	81H		; load word from $2681 to A
    SLR 	A		; shift right, now we have our value in b4-b5
    OFFIW	82H, 40H	; check if bit 6 @ $2682 is set
    ORI	A, 40H		; it is, so let's do the same with our data
    ANI	A, 70H		; clean-up
    MOV	B, A		; store in B
    DI			; enter critical section
    MOV	A, PB		; get current PB
    ANI	A, 0FH		; wipe high nibble
    ORA	A, B		; join together
    MOV	PB, A		; speak to hardware
    XRI	PC, 04H		; enable latch (PC2)
    NOP			; wait
    XRI	PC, 04H		; disable latch
    EI			; enable interrupts
    RET

    First off, I'm using absolute addresses instead of values from registers. They ain't gonna change, so I can hardcode them. And since the value I'm 'extracting' is already in bits b4-b5 and finally I'm writing it back to the upper half of PB, only one shift is necessary. Furthermore, if we store the high bit already on the 'right' position, all we need to do is to check if it's set and copy its state into our value. Neat. So far so good. But then MAME crashed a few times. I managed to go in step mode into my routine and then I saw that the value of the vector register (V) is not 0x26 but 0x27. I was pretty sure, that the context will be right, but it turned out that I was wrong. Maybe that's why it crashed, huh? OK, let's modify it one more time:

    PUSH    V
    MVI     V, 27H
    ...
    POP     V
    

    That should do the trick. I was only concerned about the stack size, cause it's pretty tiny, but I decided to give it another go instead. Nope, still the same. I set a breakpoint on my new code again and saw that each call of my sub causes the bottommost part of the memory (where the stack lives) to fill with some repeating pattern. Yup, stack overflow.

    That was the moment I decided to write a post, to share a laugh and maybe let my brain cool down a little bit. But after a few lines it struck me where the problem was.

    I have rewritten this code, because I needed to run it every time new patch is loaded. I found a suitable place inside of a piece of code that sends the patch data to KLM-654 (DWGS board). After each chunk of data, KLM-654 sends an ACK signal to say that it finished processing the previous one. It generates an interrupt and then the magic happens. After having sent the whole patch, the code branches and this is where my code is being called. I'm not going to show you the whole ISR, but here's something I have clearly missed:...

    Read more »

View all 31 project logs

Enjoy this project?

Share

Discussions

Mike F wrote 5 days ago point

This is supremely cool, will this work for the DW8k too??

  Are you sure? yes | no

Isa Twospirit wrote 4 days ago point

Hi Mike,
As is - no.
Sadly, neither Mateusz nor I own a DW8k, so there's not going to be a version for 8k in the foreseeable future.
BUT - If you unsolder the WaveROM EPROMs and replace them with Sockets, the DWLUTION Waveform Manager in the package allows you to feed your DW8K with new waveforms. Not more of them, though.

  Are you sure? yes | no

Mike F wrote 4 days ago point

hell yeah, that's still insanely cool! do yinz have the PCB's for sale or anything? 

  Are you sure? yes | no

Kay kay wrote 04/04/2019 at 09:48 point

any news?

  Are you sure? yes | no

mateusz.kolanski wrote 04/04/2019 at 15:17 point

Please be patient, this weekend we'll release V1. If nothing unexpected happens that is:)

  Are you sure? yes | no

Kay kay wrote 04/05/2019 at 17:45 point

yaaaa :D 

  Are you sure? yes | no

mateusz.kolanski wrote 03/18/2019 at 13:56 point

Well, we're almost done, just some documentation and we're ready to go. Unfortunately I'm a little bit sick right now and can't finish the docs. This weekend, maybe next should be ready.

  Are you sure? yes | no

Kay kay wrote 03/18/2019 at 22:52 point

Get well! and thanks for the quick response :) so pre-order is soon?

  Are you sure? yes | no

mateusz.kolanski wrote 03/18/2019 at 23:13 point

We're not going to sell it, just release firmware, PCB files and DWM for free. However I do have some spare boards and stickers.

  Are you sure? yes | no

Kay kay wrote 03/19/2019 at 08:15 point

alright, i would take some spare board and stuff , since i'm not very good at such things done by myself

  Are you sure? yes | no

Kay kay wrote 03/18/2019 at 11:47 point

any news?

  Are you sure? yes | no

Kay kay wrote 03/04/2019 at 14:40 point

LOL man i simply can't wait for your project to be ready xD 

  Are you sure? yes | no

Kay kay wrote 03/01/2019 at 20:55 point

ok, guess i have to be patient then. so this is only an expansion at the moment or did you guys to anything with the firmware as well

  Are you sure? yes | no

Isa Twospirit wrote 03/02/2019 at 22:33 point

Both.
To address the expanded Waveform memory, a change to the firmware is made.
For the time being, this is the only thing added.

We're pondering additional changes, but memory within the firmware is limited, and some stuff is simply not worth the hassle - think "Filter Switch" known from the Poly 800 as an example (been there, done that, kicked it out again. That 2069 filter just sounds sweetest at 24dB/O).

  Are you sure? yes | no

Kay kay wrote 03/02/2019 at 23:23 point

 😍 well, i'm open to all possibilities, maybe bigger? eproms?

maybe arduino nano?  can't wait to get my hands on this expansion action

  Are you sure? yes | no

Isa Twospirit wrote 03/03/2019 at 09:50 point

Well, Mateusz is the Pro about the 7810/11 processors, but basically they do have a limited address space, so just bigger eproms won't do the trick.
Personally, I usually opt for "naked" ATMegas/Tinies to avoid the Arduino overhead. Did serve me quite well on the UI mod to my Poly.

  Are you sure? yes | no

mateusz.kolanski wrote 03/03/2019 at 12:51 point

Please don't call me that, the fact that I made some disassembly and wrote new code, doesn't make me one. Let's say I'm just a reincarnated dinosaur :) Oh, and don't tell anybody, that we already have some BIG ideas :>

  Are you sure? yes | no

Isa Twospirit wrote 03/03/2019 at 12:58 point

You know that one much better than I do, so from my perspective you're the pro there.
Doing my best to keep my mouth shut XD

  Are you sure? yes | no

Kay kay wrote 03/04/2019 at 14:39 point

Where are you guys located?

  Are you sure? yes | no

Isa Twospirit wrote 03/05/2019 at 19:11 point

I'm located in Germany.

  Are you sure? yes | no

Kay kay wrote 01/23/2019 at 14:52 point

hey there!  still working on this project? 

in case is it possible to change some of the stock sysex information,

for example VCA_env_release and OSC1_octave both have a parameter offset value of 19 but bits 0..4 set the parameter value of the VCA_env_release while bits 5 and 6 set the value of OCS1_octave, changing these values would make it a lot easier for external control 

  Are you sure? yes | no

Isa Twospirit wrote 03/01/2019 at 11:51 point

It definitely would... right now, the SysEx format pretty much mirrors the layout of the patches in RAM.
Maybe, at some point, and depending on how the project continues, something might be done about it - but most likely not before an additional MCU is utilized.

  Are you sure? yes | no

Kay kay wrote 03/01/2019 at 18:26 point

Makes sense.  When it comes to the WaveExpansion when could i buy the PCB from you? i'm at a crossroads, since i find the sound of the dw6k awesome but the waves boring...so if there's a chance i'd like to get hands on your creation asap

  Are you sure? yes | no

Isa Twospirit wrote 03/01/2019 at 18:36 point

Let's just say - we're nearing public release of the first version (...I'm not the boss here, just contributing a bit where I can).
Absolutely with you on the DW6Ks sound. And, when fed with more classic waveforms, it goes really FAT. (My favorite bank right now consists of samples from Behringer D and TT303)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates