Monday, September 19, 2011

Integration

Much recent development on the ZX Prism has been to integrate the video modes from the orignal (48K) Prism development into the new 256K one. This has thus far been pain free but of course there's nothing new to show! The only component I'd implemented in the original Prism which hasn't been integrated yet is the palette memory, and that's next on my list.

Remembering the issue with "offset" screen attributes in the original paletted solution, and having identified some other timing issues relating to the video output and interrupts, I'm rewriting the video creation module including making the clock resolution higher. This allows me to fit the palette lookups into the standard video read/store cycle. It should also mean a resolution of 512x384 will be possible.

The new video module will be written with the additional screen resolutions and colour decoding modes in mind (rather than them being retrofitted to Mike Stirling's video module).

Whilst designing the new video module, ideas for additional video modes have arisen, including an "overlay" mode where the shadow screen is used as a background for the main screen - any areas of the main screen which are colour 0 will allow the shadow screen to show through. This could be used, for instance, for games - where the sprites are animated on the main screen, and coloured backgrounds are drawn on the shadow screen. There'd still be attribute clash between the sprites, but not between the sprites and the background.  It's only 3 colours rather than two in each 8x8 attribute square, but it would provide a relatively easy way of sprucing up existing software.

Wednesday, September 7, 2011

A matter of contention

Once interrupts were fixed, I turned my attention to emulating the Spectrum's floating bus. Basically, I keep a copy of the last byte read by the video circuit. If the CPU reads an I/O address where the LSB is FF, I feed it a copy of that  last byte when the screen is being drawn, otherwise I send back 0xFF. At some point in the future, I'll alter this so that this is the response to ANY unused I/O address but it suffices for now.

The next thing to tackle was memory and IO contention. Whilst ZX Prism currently timeslices the bus between the video circuit and the CPU to avoid bus collisions, quite a lot of software uses precise timings (for screen efects etc).  After much messing around with alternatives, I bit the bullet and implemented IO and memory contention based on the 6C0001 ULA's circuit as described in detail in Chris Smith's ULA book. It didn't work. At all. In fact the screen erupted in a multicoloured mess.



Puzzled, I poked around and tried various things to the point of calculating propegation delays around the circuit, but to no avail. It was then I realised that I hadn't inverted the incoming clock signal. Hey presto. Prism initialised.



I didn't have much time for further testing at this point, but the couple of tests I did perform were encouraging although there's definitely a couple of things still need fixing:
  • Aquaplane - Split border effect is almost correct (it occurs just under 1 line early)
  • Fusetest - runs without crashing, but shows a contended frame length which is shorter than expected and most other tests show as failed
  • ULATEST3, Floatspy - both still crash
  • IR_contention - A very interesting effect here. This test shows four coloured boxes in the top and bottom border which should be parellel to each other. They are... however they are twice as long on ZXprism as they are on a real spectrum (or on the Spin emulator in 48k mode) - in fact the whole line wraps round on-screen. Looks like I need to take another look at the video and interrupt generation.




You will notice that I've implemented a 48K Spectrum contention solution on a machine which is compatible with the 128K Spectrum. I will be changing the contention so that it contends the appropriate memory pages in the future.

Sunday, September 4, 2011

Interrupts...

This last week has seen me working with interrupts of various types.

Firstly, the literal. Mike Stirling released a new version of FPGASpectrum during the week and I took some time from working on ZX Prism to check it out. I was impressed. Mike has very quickly added a number of new features

  • AY Soundchip core
  • IO Port 7FFD controlling RAM/ROM paging as on all 128K Spectrums
  • IO Port 1FFD controlling ROM and CP/M memory modes as on the +2A and +3
  • ZXMMC+ (allowing the Spectrum to access SD Cards and adding another 128K of RAM and 128K of ROM)
This left me in a quandry. I'd been going to add 128K support to ZX Prism as part of the memory expansion to 512K (or 1MB if I could get the DE1's DRAM working), and whilst I'd been going to add IDE support to ZXPrism (via a divIDE interface), the ZXMMC+ allows access to the SD Card slot which is already on-board.... So... do I use THIS as the new foundation for ZX Prism and start merging in the changes I'd made to Mike's original VHDL, or do I try to merge Mike's changes into ZX Prism? 

Either way, I had to rethink how I was going to do Prism's expanded memory (as ZXMMC support uses 256K of the DE1's SRAM)

I decided on the former - after all, I knew exactly what changes and additions I'd made for Prism. Memory-wise, the upper 256K of the SRAM is used by the ZXMMC+ implementation. The lower 256K of the SRAM will be switchable in 16x16K pages at 0xC000 (using the Pentagon 256 decoding of port 0x7FFD to switch it). I'll be using on-FPGA memory cells for the video ram (pages 5,7,D and F) due to the way the video subsystem will be reading it - this gives another 64K of the SRAM available for.. something.

So, much of my time recently has been spent on integrating my changes into Mike's new codebase. As I'm new to VHDL and FPGAs, this has been a learning experience as Mike has changed from using a schematic  top level to using a VHDL top level - therefore my progress is slower than it might have been otherwise. All good learning though.

As part of integrating the ZX Prism code, I decided to take a look at how the Spectrum's interrupt was being generated (aha, there's the other tie-in with the post's title). 

Some code on the Spectrum relies heavily on certain features of the Spectrum hardware:
  • accurate generation and duration of the Spectrum's video interrupt
  • accurate emulation of memory/IO contention (ZX Prism's bus is arbitrated by timeslicing so there's no need for contention in order for things to work, but it IS needed for Spectrum code to run at predictable speeds)
  • the Spectrum's floating bus

I'll be looking at all of these things (as I know Mike is,), but the easiest thing to look at was the video interrupt, which I coded to behave precisely as Chris Smith describes in the ULA book.  Once this was done, I tried running some of the software which wasn't working correctly:

  • ULATEST3 - still crashed
  • Aquaplane - border effect still starts too early on the screen
  • FUSETEST - no longer crashes

Tiny steps...