FPGAmstrad
This is a VHDL version of Amstrad CPC 6128 running on FPGA starter-kit NEXYS2 500k-gates from Digilent. A starter-kit is a standard board made for learning FPGA, so it is standard.
Games running on it are : Tempest, Fruity Frank, Boulder Dash, Classic Invader, Xevious, Wiz'lair, Ghost'n'Goblins, Chase HQ, Xor, P47, Bruce Lee.
Inconvenience known is that PS/2 keyboard has timeout and can't press more that a certain number of key at same time. So it's really encouraged to plug joystick (don't do as me, don't cut directly wires, just weld a male serial port lol), and sure to plug sound ;)
Contents
How to assemble it
You need :
- a "NEXYS2 500kgates" starter kit
- a "PMODSD" module for reading sdcard
- a alimentation (cause they don't give it with starter kit)
- optionally a DIGILENT USB JTAG (normally starter kit can be programmed directly by usb, but I didn't have test this way)
- a 4Go SDCARD (no more)
- The binary of this project, available by there : [[1]]
- Several ROM files :
-- OS6128.ROM BASIC1-1.ROM AMSDOS.ROM (from JavaCPC)
-- MAXAM.ROM (from CPCWiki)
- Several DSK files (one or more) :
-- TEMPEST.DSK ARKANOID.DSK FRUITY.DSK BRUCELEE.DSK CHASEHQ.DSK WIZLAIR.DSK XEVIOUS.DSK BOULDER.DSK CLASSIC_AXIENS.DSK CLASSIC_INVADERS.DSK
You have to :
- program FPGA with the binary file "amstrad_switch_z80_vga_sd.bit" of this project, for it I use Digilent Adept software and my USB JTAG cable
- format your 4Go SDCARD in FAT32 4096 byte allocation size
- copy ROM and DSK on SDCARD
- plug PMODSD on slot JC1 of starter kit, and set all switches to 0
- plug VGA, and turn on starter kit
You can :
- plug a PS/2 keyboard, and type "cat"
- increment switch to select another disk at boot, if screen became RED, it's that binary value done by switches is too big, leds are doing a small animation when a disk is correctly loaded
- plug joystick on slot JA1 (Vcc 3.3v is common)
- plug another joystick on slot JB1 (Vcc 3.3v is common)
- plug a jack on slot JD1, one at upper GND plug, and second wire at next plug, just at left of it (if it was 3.3v Vcc, is that in fact you had to take the right one)
Tests done
Several bug could disappear in TV mode... but TV mode is not implemented yet.
prince.dsk gryzor.dsk donkey.dsk : critical bug : always writing on memory, certainly performance, have to test it on TV mode to know if it came from my asynchronous RAM.
buggyboy.dsk barbarian.dsk : raster bug can be fight with anti-raster switch (last switch is anti-raster, stopping ink rotate...)
longshot : VSYNC alternate cut bug, it's so warrior dam
crazycar2.dsk : simple overscan, my vga buffer is full lol
a lot of demos don't pass, in fact I didn't find one that pass dam.
Others bugs is about dsk format, in fact a dsk is uncompressed into RAM at startup, so all dsk access are direct :
- ucpm format : normally it run, but in fact... it don't
- protected format : all format with sector size changed, and then not standard didn't pass
- double side format : you can change disk and then reboot to insert it, so it's not done for changing disk while you are playing
- save : save is done in RAM, so when you turn off or reset Amstrad, all change is lost. It's done for let's games saving score running correctly
Effort done
Instruction timing : I tested instruction timing of T80 compare to instruction timing of JavaCPC emulator, I deduce also the memory access that had to be slow down
Test of a real Zilog, in fact T80 of opencore run on rising_edge, and zilog run during low state, so for testing I had to indirectly do a downclock, it run, perhaps if I put buffer on zilog access I could clock it at normal speed, but as it run...
Alignment of HSYNC : a button of starter kit display HSYNC loopback lines, it's usefull to compare to a Maxam test that alternate color on them
Sniffing of real Amstrad, I listen on some wires of my Amstrad CPC 6128 plus, but I can't access to VSYNC/HSYNC output of CRTC, so I have to buy another model to do this test.
Agile method
This project result of a experiment of applying Agile method. Finally this project has taken 5 months. The result is a standalone platform that can run several games of Amstrad. Normaly, I had to dedicate 2 months on this project, but as the result was so great, I continue to a standalone and better version.
This project was done for my father birthday, so sorry that I can't deliver it yet :^)
One day one book, or a lot of wiki page by there, presenting step by step adventure :)
But I want really to validate project before doing it. So it will stand a few I think.
TODO :
-sniffing Classic Amstrad HSYNC and VSYNC CRTC output directly (validation test)
-implement a SCART TV mode (validation test)
-unlock in consequence Prince of Percia and Gryzor !
-wait JavaCPC plus version ;)
-unlock 1943 (I think that it run better in plus model, no ?)
-add USB keyboard for no more key timeout (but as joystick run... it's not important yet)
Source code
The project download contain in fact source code and the binary file (.bit)
It is in fact a simple zip of project folder.
The project was done using Xilinx webpack
It contains some direct drawn schematics, and VHDL components
Schematics
I explode into a task by component, so the schematics is big.
Starter kit use only one RAM physical component for RAM ROM and DSK, so I had to manage accesses (it is possible in fact because Z80 is a sequential processor)
My clock take 4 wires, in fact it exists a clock sequence (during 1 z80 tic, I do several think). Perhaps I have to explain a few about this point of view.
RAM is done for being dump
Components
sound chip is fpgaarcade one, patched.
PPI chip is CPCWiki one, patched.
PWM chip is fpga4fun one.
VGA display component use same parameters than unix modeline command
A component is dedicated to interrupt generation
Big components as SPI on BOOTLOAD use state-machine led debug : an integer contain the state of state machine, and this integer is displayed on 8 leds so you know where you are, it's for that I add several crash state in order to understand why and where component crash.
This project don't use IBM ROM of NEXYS2. Be careful if playing one day with it, physical IBM ROM is plugged on bottom of physical RAM and can put death bit for some byte address. In fact my 8th byte is death, it's why I turn always my upper RAM address bit into 1. I think that I have written one time on a ghost part of ROM, and it was fatal...