Saturday, July 16, 2016

Solid progress...

So much progress since the last update! First up, I finally found why esxDOS wasn't working properly on Prism. Turns out that the divMMC automapper was working perfectly. The problem was actually with the SPI port. +3eMMC was working fine because it uses the SPI port slightly differently to esxDOS. A couple of tweaks to the SPI port implementation's sorted everything out - now both esxDOS and +3eMMC work perfectly.

I was just about to give up on ever seeing this....

Getting esxDOS working means that I can use emulated TRDOS to try out some of the Russian software, some of which works best with no memory contention, or needs more than 128K of memory.

Fire And Ice running from TRD file. A fun and pretty platform puzzle game, similar to Solomon's Key
Mortal Kombat, running from TRD

Graphics modes, graphics modes... What would a Prism update be without more graphics modes? Firstly, I revisited Gigablend mode - this is a mode which blends the main and shadow screen together to give more colours - basically a hardware implementaiton of the software "Gigascreen" effect found in many Russion demos.

Gigablend mode
I'm afraid I don't know the artist to credit them
Probably one of my favourite gigascreen pictures, displayed using Gigablend mode.
I'm really sorry I don't know the artist to credit them.

Looking back through the blog, I noted that I'd not said much about the 4 plane (16 colour) 256x192 mode. This works in a similar way to the Amiga - 4 bitplanes of pixel data which mean each pixel can be one of 16 colours (ie there is no colour clash). Of course, being Prism, this isn't restricted to the 16 default colours, they can be user defined. Here's a few examples

But what about brand new modes?

How about a completely bonkers 4096 colour mode? Brainbow mode is a 3 plane 256x192 resolution mode with a twist. Each pixel can be one of 8 colours (black, blue, red, magenta, green, cyan, yellow or white/grey) the twist is that each 8x8 "attribute" square has a defined red, green and blue element intensity level. Probably of limited usefulness, but hey - it's up to 4096 colours on screen at once.

It really is quite bonkers... 
What else? Well definitely more useful are the new linear modes. In addition to the Radastan and Zesarux linear modes, Prism's ULA2 also has its own linear modes - two of which have been implemented to date.

Firstly, the 128x128 resolution 256 colour mode which uses 16K of VRAM

256 colour linear (clashless) 128x128 mode
...and secondly, the 256x128 resolution 256 colour mode which uses all 32K of VRAM

256 colour linear (clashless) 256x128 mode

Hand-converted from a 256 colour BMP... ignore the couple of alignment errors ;)

Due to the data needed to be moved around, these modes are probably more useful for splash screens or perhaps static pictures in adventure type games than they would be for actual arcade games (happy to be proven wrong though!)

Saturday, January 16, 2016

Happy New Year

Hi folks, Happy New Year.

There's been quite a few developments with Prism in the past few months, though again a lot of them are "under the hood" and not particularly visual. A lot's been done to improve stability at higher CPU speeds, and there's also been a large amount of refactoring of Prism's microcode to make it easier to work on and add new features.

Over Christmas, I did a lot of compatibility testing (also known as just playing games), as well as some playing around with palettes...

Gauntlet II with a modified palette

Of course it wasn't ALL playing games and refactoring... I did do some work on adding new features, including Radstian mode (a 128x192 16 colour "chunky" mode with no colour clash). I also started adding César Hernández Bañó's additional screen modes (similar to Radstian mode but with different resolutions)

SpongeBob Radastanpants gazing lovingly at a ZX Uno prototype
Another Radastan mode demo pic (though personally I think Robot Chicken did it better)

I've also been working on a boot rom, based on a test ROM that César Hernández Bañó created. I'm re-learning Z80 after a break of several years, so César has been increadibly helpful, thanks mate! The boot ROM lets you chose which ROM you want to boot to, and lets you set a couple of options. It also displays the Prism logo which is based on a mock-up which Andrew Owen created for me a while ago. You can probably guess where I got the idea from ;)

Shine on, you crazy ROM selector.
The boot rom utilises Prism's 16 colour (4 plane) clashless mode and as you can see it also departs from the Spectrum's standard colours - for example non-bright yellow's orange.

Saturday, August 29, 2015

New graphics modes

Today I did a little bit of poggling around with the VGA driver and started adding some new functionality to it. There's still some tweaking to be done, but here's a taster.

Last year, I did some experimentation around a hardware GigaScreen mode which did some tricky work interpolating pixels from the main and shadow screens depending on if it was an odd or even frame. This was an interesting experiment but the results left a lot to be desired on most monitors. Today I tried a different method - looking up the physical colour for the corresponding pixels on the main and shadow display, then blending the two. This seems to work quite nicely.

Some blended colours, yesterday.

A couple of days ago I was reading up on the various graphics modes on other computers and came across documentation on the Commodore 64's low-res multicolour mode which halves the number of pixels per colour cell (from 8x8 to 4x8) but increases the number of colours per colour cell from 2 to 4. I decided that this sort of thing would be easy to add to Prism.

I toyed with two different ideas - the first maintained the usual 256x192 resolution, and the second halved it, like the C64 mode. In both cases, a pixel is defined by two bits instead of the usual 1 bit - but in the first case pixel data bits are read 'progressively' and in the second they're read in pairs:

256x192 res: (Bit 7 + Bit 6)   (Bit 6+Bit 5)   (Bit 5 + Bit 4)   (Bit 4 + Bit 3)  (Bit 3 + Bit 2) etc
128x192 res: (Bit 7 + Bit 6)   (Bit 5+Bit 4)   (Bit 3 + Bit 2)   (Bit 1 + Bit 0)

Normally, this pixel data would be 1 or 0 indicating ink or paper, the colours of which are defined in the associated attribute byte. In both these modes, the pixel data has 4 states: paper, ink 1, ink2 and ink 3. Paper is defined by the attribute byte in the usual way - bits 3 to 5 of the byte give the paper colour 0-7 and bit 6 indicates bright or not.  The ink colours ignore the bright bit (bit 6) and instead, inks 1, 2 and 3 are all the colour 0 to 7 as defined by bits 0 to 2 of the attribute byte but their intensity differs:

00 - Paper (colour 0-7, bright 0 or 1)
01 - Ink (colour 0-7, brightness intensity 1)
10 - Ink (colour 0-7, brightness intensity 2)
11 - Ink (colour 0-7, brightness intensity 3)

This isn't quite how the C64 chooses the colours, but it's sufficient for this experiment.

In short, the first method produces a sort of "anti-alias" effect, and the second is similar to the Commodore's "rectangular pixel" mode. Whilst some spectrum owners laughed at the blockiness of the Commodore mode, there's no denying that in the right application and with a little bit of thought, it can produce some great results.

The following pictures show these modes in action on Prism. The images were basically chosen at random to show the effect, rather than being selected to showcase it....

"Antialias" or "progressive" 256x192 4 colour-per cell mode

Glorious Chunk-o-vision! 128x192 4 colour-per-cell mode

X-Out in Chunk-o-vision

Mr Heli's scoreboard in chunk-o-vision.
More or less readable even though the resolution's halved 

X-Out in-game Chunk-o-vision. Not too bad if you squint.
(apologies for the bad picture but you get the idea)

Mr Heli in-game Chunk-o-vision
It looks a little better when it's all moving

This is all early stuff anyway - future experiments may include centring the screen and making the pixels square again so it's less chunky. I'll also experiment with different ways of deriving the ink colours - currently its 3 intensities of the same base colour... The C64 has registers for selecting the other two inks. I could also try making the new 2 colours being blends of the ink and paper. Hmmm.

Tuesday, August 25, 2015

Refactoring complete

For the last couple of months I've been doing some major refactoring of Prism's glue logic, data bus mux, MMU and SRAM/flash memory control subsystem. This has been a heck of a lot of work for very little in the way of new features - however it's reduced the delay on a lot of signals which means that hopefully, with a little tweaking, Prism should be able to run stable at faster CPU speeds.

The new features added during this time are minimal but potentially useful:

  1. Spectrum +2A/+3 special memory modes added. Not much software that I'm aware of uses this "CP/M" or "all RAM" memory configuration - except CP/M of course and John Elliott's wonderful ZxZvm (which lets you play various Infocom adventures like Zork and Hitchiker's Guide to the Glalaxy on the Spectrum). A number of people, including me, have also written utilities to run ROM images (like the Interface 1 ROM cartridges) using this memory configuration.
  2. A selectable "Video RAM Aperture". Select between VRAM being accessible by the CPU at memory addresses 0x4000 - 0x5AFF (default) or VRAM being the entire 16K between 0x4000 and 0x7FFF.  The advantages of the default mode are that the system variables, printer buffer and the beginning of BASIC don't get stored in video memory and so allow the user to use video modes which use more VRAM than the standard Spectrum screen mode from BASIC without crashing (careful use of the "planar write mask" lets you write to other parts of VRAM). The disadvantage of the default mode is that software which uses certain Timex screen modes expect VRAM to be at 0x4000 - 0x5AFF and 0x6000 - 0x7AFF. So both modes have their uses. If using SE Basic in double-width mode for example, you will need to switch to the 16K VRAM aperture. 

So just a quick update despite the fact I've just finished a bucketload of work (and still have a metric shitload of testing and tweaking to do!). I'll leave you with an "actual Prism screenshot!!!" teaser from when I was testing the VRAM aperture - a 16 colour, no colour clash image displayed using the 4-plane planar mode:

Saturday, April 11, 2015

Easter Update

So yet again I've managed to go a couple of months without updating the Prism blog. Mister Polo poked me again, so here we go. In my last update I listed a number of things that I'd be working on this year. I'm happy to say that a number of them have already been successfully achieved.

Firstly, the MMU (memory control functionality) has been rewritten to make it easier to modify in future. It also now handles all memory as 8K pages instead of 16K pages which means that I could add the Timex/Spectrum SE/Chloe 280SE memory paging model.  The Spectrum 128/Pentagon memory paging model still works exactly as expected. 

Secondly, I've added in support for the Timex/Spectrum SE/Chloe 280SE screen modes. The shadow screens that the Spectrum SE and Chloe has were already implemented as Prism implements it's screen selection in the same way. Likewise, the Timex "Hi-Color" mode is the same as Prism's. The Timex/SE/Chloe 512x192 mode is different to Prism's however - where Prism's is full colour and is basically screen 0 and screen 1 side-by-side, the Timex/SE/Chloe mode is monochrome and interlaces alternate sets of 8 pixels.  This screen mode is used in SE Basic's 80 column mode, which is the main reason I implemented it (Prism's 512x192 mode is better!)

Here's a video of Prism running Andrew Owen's (Chloe) MMUtest program:


To make my life easier, I wrote a small menu program which auto-loads from SD card when Prism boots. It lets me switch between different configurations - ZX Basic with 512 or 48K, SE Basic, the ZX81 emulator etc. It also shows off 256 colour mode - though as you can see the default palette has a number of blacks and whites at the moment!

I also fixed a bug in the T80 soft CPU core where incorrect flag behaviour was observed following an LD A,R or LD A,I instruction. This fix was based on one done by the Speccy2010 team. This finally fixes Midnight Resistance, Greeen Beret, Hypersports, Gutz, King's Valley and a number of other things. After that, I was on a roll with getting games working so I also updated the floating bus emulation so now Sidewize works too (albeit with flickering sprites due to the timing diferences between Prism and a real Spectrum).

Finally, after all this time I've actually gotten around to adding support for the "flash" attribute in standard attribute decoding mode! The Manic Miner loading screen works properly for the first time!

As a bonus to make up for so long without an update, the following three pictures are a teaser of something I'm working on (and definitely not an April fool - that was over a week ago). What could this be the first stirrings of I wonder?


Monday, February 2, 2015

Happy New Year!

Belated New Years greetings to you, special reader! Special because I doubt that too many people read the blog regularly especially now that I'm only updating every couple of months. So there you go, you're probably more or less unique. Rejoice in your individuality you little retrotechnohipster you.

So 2015 found me taking a brief hiatus from working on ZX Prism as I was in the UK for a month visiting family. On my return, I used the space the month had given me to take a step back and plot out the next few months' worth of work on ZX Prism.

More on that later, firstly let me fill you in on the work done on ZX Prism since the last update:

ZX Prism's "ROMs" are now stored in flash memory, and ZX Prism has been configured to use flash instead of on-FPGA emulated ROM. The flash chip provides 256 x 16K "ROMs". At power-on, ZX Prism boots from "ROM" 0.   ROM switching is done by OUT 60987,x where X is the ROM number you wish to page in, with "X" being an 8 bit byte of course. Additionally, the Spectrum 128 and +2A/+3 ROM switching mechanism is implemented. Port 7FFD bit 4 alters bit 0 of the ROM  number and Port 1FFD bit 2 alters bit 1 of the ROM number.

Added "SAFE" ROM mode. This is entered by holding reset (F12) and tapping F9. It maps a predefined ROM image stored in on-FPGA emulated ROM into memory location 0x0000. Therefore, ZX Prism will be bootable even if the flash chip is blank or corrupted. Currently on the development ZX Prism, this ROM image is the standard 48K spectrum ROM but will be replaced with a specific ZX Prism boot/utility ROM in future (containing, amongst other things, firmware for "flashing" ROM images into the flash memory)

Added "Programming" ROM mode. This moves the selected flash "ROM" page to 0x8000 in memory, enables the WR (write) signal to the flash chip, and presents the SAFE mode "ROM" at 0x0000. This mode is only used when programming or erasing the flash memory.

Wrote a rudimentary flash memory programmer/eraser in BASIC. Programmed the development ZX Prism's flash memory with the following ROMs for testing purposes:
  • Sinclair Spectrum 16K/48K ROM
  • Sinclair Spectrum 128K ROM 0
  • Sinclair Spectrum 128K ROM 1
  • +3eMMC ROM 0 (hacked to use DivMMC's SPI ports)
  • +3eMMC ROM 1 (hacked to use DivMMC's SPI ports)
  • +3eMMC ROM 2 (hacked to use DivMMC's SPI ports)
  • +3eMMC ROM 3 (hacked to use DivMMC's SPI ports)
  • Some interface 2 ROM cartridge images
All worked as expected after a little bit of refactoring of the CPU data bus MUX :)

Added support for DivMMC. Much time was spent trying to debug this. To date, it's a partial success. Whilst the DivMMC memory control and automapper are not working (and have been temporarily disabled), the card control and SPI ports are working fine. These were tested by using the +3e ROMS for ZXMMC which were hacked to use the DivMMC port addresses. I've successfully loaded, saved and renamed files on a +3eDOS partition on an SD Card.   For many this would be an acceptable solution, but I'd like to get the memory control and automapper working so that I can use esxDOS in the future.

Fixed an intermittent crash when booting to +3eMMC ROMs. Debugging this, along with trying to debug the DivMMC automapper, took up much of November. When I finally found the cause of the crash I could have slapped myself. The +3eMMC ROMs check for a disk in the floppy drive. As ZX Prism doesn't have a floppy controller but does emulate the floating bus, this meant that a read of the floppy controller port would sometimes return 255 (as a +2A/+2B does, indicating no floppy controller is present so fall back to +2A mode) but would sometimes return the last byte read by the video circuit - and it was this scenario that was causing the crash. The fix was therefore simple - return 255 for any read of the floppy controller's IO ports. The emulated floating bus is still returned for any other unused IO port.

So that's where I am today - ZX Prism can load and save to SD Cards which have been formatted to work on a +3e. For compatibility, I can switch to use the original Spectrum ROM. I can run the image of an Interface 2 cartridge. I can write new ROMs to the flash memory and boot from them. Plus all the other groovy stuff that's been discussed elsewhere on this blog.

A pretty good place to start out from in 2015 :)

So what's on the cards for this year? A small list of what I'll be working on next:
  • Refactor the MMU and data bus MUX so that they're easier to add to/modify.
  • Update the MMU so that it can switch in either 8K or 16K pages easily.
  • Add support for the Chloe 280SE "sideways" memory paging model.
  • Add support for the Timex/Chloe screen modes
  • Hardware: interface an audio codec to the FPGA
  • Hardware: simple kempston joystick interface
  • Hardware: improve the VGA DAC
  • Add AY audio chip support; investigate modelling other audio chips (SAA, turbosound etc)

There are other things on the list of course, but that's enough for starters I think!

Friday, October 10, 2014

Another small update for September and the beginning of October

Apologies once more for the lack of updates in the last month or so. Mister Polomint prodded me a week ago to make some kind of post, so here it is. Steady progress is being made with a whole heap of testing and tuning and a few new features added. No pretty pictures or videos just yet, but there's been some more sceen modes added

Again, rather than write an essay, I'll just post the last few additions to the changelog for now.

ZX Prism version 0.16 10/10/2014 (non-released, flashed to board)

  • Added an extra bit to the Flash ROM address bus so the whole chip can be utilised.
  • Added check for CPU_RD on data bus multiplex (fixed Shadow Warriors and several others)
  • Added switch to limit memory to 128K (when used, fixes turbo outrun amongst others): OUT 36411,24 limits the page at 0xC000 to pages 0 to 7. OUT 36411,16 re-enables 512K.
  • Hooked MMC signals into the glue logic (but the associated IO registers not implemented yet)
  • More interrupt tuning for different CPU speeds. Speeds 0-6 (3.5MHz - 28Mhz) work with all games/demos tested. Speed 7 (56MHz) needs further tuning

ZX Prism version 0.15 19/9/2014 (non-released, flashed to board)

  • Fixed the main ZX Prism palette. (until this fix, all 3 colour elements were getting set at the same time, meaning you could only select from black and 15 shades of grey!)
  • Added write masks for writes to 0x4000 - 0x5FFF (0=currently paged, 1-15=combos of planes). This makes working with the new video modes easier - for example, you can write to multiple planes of a planar mode at the same time, or quickly modify existing software to work in an overlay mode by adding an OUT to the beginning and end of the sprite routine so sprites are written to the shadow screen and overlaid over the main screen to avoid colour clash... etc etc. Care must be taken when using this feature from BASIC (so as not to stop writes to system variables...) 
  • Removed "64 ink, 4 paper" mode and replaced it with 3 plane planar mode (as defined by Andrew Owen) This mode avoids using memory at 0x6000
  • Added overlay options register which selects the attribute decode methods for upper and lower overlays
  • Added readable register IN 0x8E3B (36411) returns CPU speed and available system memory:

D4-D7 = Available memory
0000 – 48K
0001 – 128K
0010 – 256K
0011 – 512K
0100 – 1024K
0101 – 2048K
0110 – 4096K
0111 – 8192K
D0-D3 = CPU speed

  • Added readable register IN 0x9E3B (40507) returns microcode version (mainly to save me wondering which build of the FPGA code is currently running whilst I'm testing different versions!)

ZX Prism version 0.14 10/9/2014 (non-released, flashed to board)

  • In Quartus: Turned on "Auto RAM to Logic Cell Conversion" in Analysis&Synthesis More Settings
  • In Quartus: Changed optimization technique to "speed" (from "Balanced") in Analysis&Synthesis More Settings
  • In Quartus: Changed Optimization technique to "speed" (from "Balanced") in the Analysis & Synthesis page (diff to above)
  • Added attribute decode method 0111 - 64 inks (colours 0-63), 4 papers (colours 0-4) PpIiiiii  (this mode was removed in version 0.15)
  • -Swapped default colours 0-15 with colours 24-31 so difference between bright 0 and bright 1 is more spectrum-like
  • Added a rudimentary floating bus (127 if reading screen, 255 if drawing border) - enough for Arkanoid to run (though the bat and ball flicker!)
  • Added overlay mode 1 (Polo Mode) - ink and paper colour 0 and 8 on top layer are treated as transparent and reveal the lower layer.
  • Added overlay mode 2 - ink and paper colour 0 on top layer are treated as transparent and reveal the lower layer
  • Added 256 colour mode 2 screen 0/1=ink1 colour + pixel data, screen 2/3=ink2 colour+pixel data, paper=border
  • Switched to spectrum 128/+2 partial decoding of IO 7FFD to see if that helps with some of the compatibility issues. This will need to change back if port 1FFD etc are used in future.
  • Added check for interrupt on function keys (to avoid crashes when changing CPU speeds)
  • Started adding an OSD

ZX Prism version 0.13 31/8/2014 (non-released, flashed to board)

  • Refactored cpu speed code. Default speed (speed 0000) is now 3.5MHz
  • As SRAM and FLASH share FPGA pins, wrote pin multiplexor to facilitate use of both. SRAM signals are mapped to the pins when SRAM_nCS is 0, FLASH signals are mapped when FLASH_nCE is 0. When bothare '1' the pins are set to high impedence so they can be used for other things (eg ROM cartridge, SID, general sound etc - will require fast bus transceiver to translate voltage levels and leave bus at high impedence when FLASH/SRAM are in use)
  • For the time being, the memory multiplex is "locked" to talk to SRAM only
  • Changed memory mapping so that VRAM is used by both video and cpu for page 5 and 7 (previously CPU writes were being mirrored by VRAM, with CPU reads using SRAM and video reads using VRAM..) this frees up 32K of SRAM for other uses.
  • More interrupt tuning (frame length, int start, int duration for speed 0) to fix Mikie (was freezing) and others which weren't detecting keypresses. FUSETEST now detects this as a 48K spectrum due to frame length