-
RELEASE DAY! FINALLY!
04/07/2019 at 20:46 • 2 commentsAlthough 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.
-
A way to manage waveforms
03/01/2019 at 11:44 • 0 comments -
PCBs
12/14/2018 at 19:08 • 0 commentsSome 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
11/19/2018 at 20:27 • 0 commentsLooks like it helped, yay!
-
Debugging the hardware
11/19/2018 at 20:14 • 1 commentHi 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!
11/12/2018 at 21:12 • 0 commentsYes, 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.
... 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
11/12/2018 at 17:46 • 0 commentsI'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!
11/10/2018 at 20:30 • 0 commentsOk, 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
11/10/2018 at 16:53 • 0 commentsHi 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!
11/07/2018 at 20:27 • 0 commentsNo, 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:
; ****************************************************************************** ; * INTERRUPT HANDLER FOR INT1 / INT1 (ACK from KLM-654) * ; ****************************************************************************** .ISR_INT1_2: PUSH EA PUSH V PUSH D PUSH H DI ... .0A5AH: POP H POP D POP V POP EA EI RETI
Got it? I was calling my code from an ISR which - surprise, surprise - disables and re-enables interrupts. Go back to my code now. See? Enabling interrupts in the middle of an interrupt handler is a bad idea. OK, getting back to work.