Monday, 21 January 2013
ROM and RAM banking
Previously I was emulating just 64KB of RAM and copying ROM images into the spare RAM. Now, the flash ROM is accessed in-place allowing me to expose the extra RAM as an expansion board.
Friday, 11 January 2013
Sounds and tapes and clocks, oh my!
So, with a bit of experimentation I discovered that dropping R19 down to about 8000 ohm fixes the tape input. Not only are the tape signal high/low bars equally sized now , it also sounds right when it's loading instead of the weird "high frequency" noises in the previous video. Here's an updated schematic where I've just added a 47K resistor R61 in parallel with R19 to drop it to approximately the right value:
I've also been learning over the last week about the importance of clock domains, more specifically the scarceness of global clocks. It seems doing innocent things like this will introduce severe unpredictability:
if rising_edge(hsync) then
...
something <= '1';
...
end if;
Obviously, this introduces a D flip-flop clocked on hsync. However, what this actually seems to do is put this into a pool of things that might be promoted to a global clock or might be routed all over the place. At first, everything seems to work fine and then suddenly, changing a small bit of code somewhere causes resources to be placed slightly differently which causes a different selection of clocks to be promoted to be global clocks.
Around the time I started using the DCM to generate a 32MHz clock from the standard 16MHz clock, I'd forced most of important clocks to be globals using BUFG, but I hadn't realised how unpredictable all the innocent looking clocks like the one above would be. Something trivial like changing the RAM banking logic would cause glitches in the CRTC (e.g. bit 2 of the width register always being set) or even complete screen failure.
So, what's the solution? It actually turns out that if you stick to only ever using a small number of clocks (there's 8 global clock lines on all the Spartan 3 chips), then everything works completely as expected. Replacing the multitude of clocks actually turns out to be remarkably easy, e.g.
if rising_edge(clk32) then
if hsync='1' and hsync'last_value='0' then
...
something <= '1';
...
end if;
end if;
It turns out that you end up needing very few clocks. I've gone from having too many clocks that the assignments were random, to only 5 clocks in total: 32MHz, 32MHz @ 180°, 16MHz, 1MHz (for CRTC/PSG) and 4MHz (for Z80).
The best result of this is that this fixing these clock issues also fixed a critical problem with the sound emulation. I'd noticed some glitches before with a couple of songs, e.g. the fantastic Hyperdragon by Reed/Fairlight, but I hadn't ever managed to figure out what was wrong. What was happening was due to this clock issue the first sample in each envelope was actually played with the volume of the last sample in that envelope. This was due to audio clock no longer being a global clock, so the audio events had stopped being precisely synchronised and the envelope counter was being reset 1/16 envelope period after it was being used. So, BASIC which didn't use envelopes was fine and most songs sounded fine, but some of the drum effects sounded very odd in others. I'll upload a video of this soon, but my phone just ran out of battery as I was recording a demo for the blog...
Friday, 28 December 2012
More tape loading analysis
Digging into some occasional read errors reveals that the on pulses are shorter than the off pulses:
For your interest, here's the circuit for the tape input:
I've also been fixing up some audio glitches - the tone pitches were all an octave too high, which is now fixed, and the white noise generator still doesn't seem to be working correctly.
Sunday, 23 December 2012
Tape loading
So, something I've been meaning to test ever since I designed this board back in March and got them made up in April is the tape input. So here is Rampage running on the emulator and loaded from real tape:
Since the first prototype, I've been pretty busy and not had much chance to work on the emulator and whenever I did get a chance I was stuck because the flash chip on the board didn't seem to work properly. There's a bunch of reason why it might not work - it might be dodgy soldering, although I reworked all the soldering on the FPGA pins and flash chip pins a number of times, and testing it with my scope suggests it should work. It could be the chip itself which is dead (2 of the 3 boards seem to have dead flash) or it could even just be because I forgot pull-up resistors. Reading the datasheet, these don't seem to be required, but who knows...
Anyway, the other day, I knocked up a small daughter board with a flash chip from a different manufacturer and that all seems to work fine, so I'm able to carry on with the testing I could have been doing 6 months ago!
Here's a close up of the board taken with a decent camera rather than my camera phone and also the emulator running 1943 (also loaded from tape):
Saturday, 27 October 2012
Too much going on!
As you know, I kind of put the emulator project on hold early on in the summer so I could focus on my demo for Sundown. Well, that's been and gone, but after winning the old school compo at Sundown and getting a PC-FX as my prize, I spent about a month doing nothing but trying to get some code running on that. Then, I went to the really fun poolside demoparty at Main and since then I've been looking into raymarching and WebGL...
Today, I had another look at the FPGA project. I thought I'd broken the JTAG scan again when I was trying to demo it at Sundown and something wasn't working, but it looks like there's a "feature" of the USB serial democode that causes a timeout to happen if the host isn't reading the AVR chip... and so my JTAG code was running at about 2 bits per second unless the virtual serial port was connected to. I've managed to speed this up a bit and so now the timeout overhead is only about 80%, but it's still something I'd like to fix properly.
Thursday, 13 September 2012
Sugarlumps came 1st place in the oldschool demo!
Best of all, I won a PC-FX as the prize. These are ultra-rare consoles only released in Japan between 1994 and 1998, so I've spent the last couple of evenings trying to get something to boot on it and read up about development on it... :)
Sadly, there was a really good Spectrum demo that then came 2nd and unfortunately a bunch of Russian Spectrum fanboys seem intent on trashing my demo everywhere it gets mentioned. Oh well. I guess haters gotta hate...
Saturday, 8 September 2012
My first demo release - sugarlumps
I've mostly been concerned myself writing a demo for the Amstrad CPC which will be released this weekend at the Sundown demo party. I won't provide a youtube link right now as it's not been officially presented yet, but here are some screenshots of the demo called sugarlumps (it's a chunky demo for the machine by Alan Sugar)...
Obviously, I'll post a youtube video and disk image when the demo has been officially released.
Back to CPCfpga, it's not been completely quiet. I've completely started again on the Atmega code and now have a reliable virtual serial port working which emulates the PACE serial adapter and instead of a "command monitor" on a serial port, I have a JTAG protocol so external programs can make arbitrary JTAG requests. That means all the JTAG boundary scan testing code I wrote for the raspberry pi can be used without massive changes and worrying about the memory space on the Atmega. The only problem is that the old JTAG interface sent and received a bit at a time, which is really slow over USB. I'm gradually migrating the important programs to use a block transfer which allows 512 bits to be transferred per USB packet.