FPGAmstrad

From CPCWiki - THE Amstrad CPC encyclopedia!
Revision as of 06:55, 20 July 2011 by Freemac (Talk | contribs) (Effort done)

Jump to: navigation, search

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 ;)


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. In fact you can listen at clock of Amstrad and overclock it after using FPGA DCM component, resulting a clock sequence insertion that permit to insert 4 operations during one tic of real Amstrad, that's it with FPGA DCM you can overclock output Amstrad clock signal for insert more operation, I use this tips for listening signals and saving it in RAM (write, stop write, write, stop write... i'm a perfectionist paranoid...)


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)


Bootloader

I have written a FAT32 SDCARD bootloader that :

- deploy ROM file on physical RAM

- deploy Nth DSK file on physical RAM, N being the binary number selected by 8 switches

bootloader run only at boot, it just here for deploying informations in RAM at start up :)

Clock sequence

Original Gatearray of Amstrad is a sequencer, it manage synchronization between video card and z80 and memory access.

Historically there are a link between CU of CU/ALU, and... control bus and... making a own sequencer. But I will say no more in order to not disturb these text part xD

Whatever, I made my own sequencer here in form of a bus of 4 wires called CLK4. CLK4 execute a simple repetitive sequence like 0001 0010 0011... CLK4(3), the last wire is directly connected to Z80 clock entry. Component not using explicit CLK4 as clock entry are generally using a not(CLK4(3)) entry, in order to do operation not as same time than z80.

Real Amstrad use buffer memory in front of each address and data access, and real z80 is clock low state active. Normally if you follow datasheet of z80 you know how to map memory following CU comportment. Or you do as Amstrad, saying that z80 CU sucks, I create my own sequencer, managing all my memories access, alternating CRTC work and z80 work with little synchronization, insert by the way more pixels that can support my small CRTC...

Why NEXYS2 500kgates starter kit

The first response is that it's the one I have xP

Xilinx schematics

Xilinx webpack permit drawing schematics as book schematics, My point of view is : "For programming a FPGA, you draw a schematics as old book and just press one button. Each component on this schematic can be edit, in a language called VHDL".

My source code is not Altera compatible because of schematics drawn, but webpack can export vhdl code from schematics if you want.

RAM dump

A starter kit that contain a RAM component can dump it.

During power is on you can :

-programming FPGA with a program/schematics done for filling RAM

-programming FPGA with a program/schematics done for using RAM

-programming FPGA with a program/schematics done for dumping RAM

My own made program do it with poor serial port, so for dumping all RAM content it takes about 3 hours, and for dumping Amstrad RAM part it is about 15 minutes.

FPGA internal RAM size

It's to know that a FPGA chip contain 96KB internal RAM so you can't insert a dsk inside. This internal RAM is already used in part be T80 (z80 from opencores), the soundchip, and RAM asynchronous (RAM with two different speed one for writing another for reading) that I use for VGA mode.

VHDL components size

T80 (z80 processor) take 100kgates

Yamaha sound chip (from fpgaarcade) take 50kgates

InterruptGenerator + VGA mode take 50kgates

Bootloader (for standalone) take about 120kgates (FAT32 protocol, SPI protocol, DSK protocol)

Actually the project take about 99.9% of 500kgates. But I think that TV mode will take a lower size. A bigger size shall be great for Amstrad CPC Plus version, if JavaCPC evolve, and then if I evolve ;)


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 #Clock_sequence (during 1 z80 tic, I do several things)

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...