A realtime Commodore 64 emulator in a FPGA.
FPGA-64 is a re-implementation of the Commodore-64 computer using reconfigurable logic chips.
It is implemented (programmed) in VHDL, a hardware description language designed for high-density logic chips (like FPGAs).
FPGA-64 consists of the following building blocks:
- 6502/6510 compatible CPU (including the original instruction timing, bugs and 'reserved' opcodes)
- VIC-II video chip emulation with scandoubler (or scan-converter) for VGA display.
- PS/2 keyboard interface connected to an emulated 8x8 keyboard matrix. Numeric keys emulate joystick movement.
- CIA replacement (incomplete) providing timers, I/O and diskdrive interface
- PLA-chip and bus multiplexing emulation for bankswitching and cartridge support
The source-code (VHDL) of FPGA-64 is made available strictly for personal educational purposes.
It is not allowed to copy, upload or redistribute this work in any way,
neither in original form nor with additional files or changes.
Contact the author if you want a commercial license for (part of) FPGA-64.
Current version (C-One binary, no source):
Because this version contains code from the Chameleon project, I can't release the VHDL sources. So this version is for C-One owners only.
zip contains vhdl source code, project files, documentation and binaries for the C-One Reconfigurable computer.
Although the core is configured to run on a C-One board, it is not too difficult to port it to another FPGA.
|Game||Game version||core version||Result||Comments|
|Barbarian 1||RDI||0.24||100%||OK. Game hangs after some time, but this happens in VICE too.|
|Exploding Fist 2||0.16||100%||OK|
|Giana Sisters Intro||REMEMBER||0.22||100%||OK|
|Rags to riches||Alpha14||100%||OK|
|COM.DOS.DEMO/WHZ||Commodore Dossier Demos||0.22||100%||OK|
|> PUSH IT! </TRX||Commodore Dossier Demos||0.22||100%||OK|
|IN DULCE DECORUM||Commodore Dossier Demos||0.22||100%||OK|
|ANO.CONTRIBUTION||Commodore Dossier Demos||0.22||100%||OK|
|EUH1||Commodore Dossier Demos||0.22||100%||OK|
|Krestage 3||0.22||98%||50 pixel wide sprites are not properly displayed. (C-One related timing issue, the VIC-II emulator can do it!)|
|D011H3||frodo4.1||0.17||10%||Does 'something', but not the effect it should.|
|CIAA A||Wilfred Bos||0.20||100%||OK|
|CIAB A||Wilfred Bos||0.20||100%||OK|
|64 Emulator Test Suite||0.19||50%||Stops at test ARRB. Yeah the pirate opcode Arrrr. :-)|
|100%||No errors detected|
|50%||It runs, but has issues or incompatibilities
|50%||Doesn't run at all (crash)|
Known open Issues/Bugs
Using DMA input on cartridge port crashes machine.
'ICR01' from testsuite goed wrong.... same behaviour is in VICE.
There are some problems with One-Shot mode in the CIA timers. Shouldn't influence too much software.
TOD clock (Timer of day) and alarm is not working correctly in CIAs.
KCS cartridge unsupported (garbage video)
MMC-Replay unsupported (it works 'sometimes')
- Swapped joystick ports and pot-X/Y registers. 1351 mouse (and clones) can now be used on the C-One.
- Some VIC-II emulation fixes for the sprites.
- Fixed IRQ/NMI pins on cartridge port. Signals are now bidirectional.
- Second SID is now mapped at $D420-$D43F allowing playback of stereo music.
- Left/Up cursor keys force right-shift down (this used to be the left-shift). This solves MMC-64 keyboard issues.
- Uses VIC-II emulation from the Chameleon dev-tree. Results in better graphics compatibility.
- Fixed 'picture is shifted to the left' bug in the scan-converter.
- Fixed bug in buslogic preventing use of MMC-Replay.
- Reading from SID chip now implemented. (emulated registers removed)
- Fixed decimal mode of ARR instruction
- CPU speed changes together when the video mode is changed by pressing F12.
- Fixed speed of dotclock and phi. System now runs at 0.9850Mhz for PAL
and 1.026Mhz for NTSC. Most floppy turbo loaders can now operate.
- VGA frame refresh rate now correct at 50Hz and 60Hz.
- Catridge port stability improved by adding data register that buffers on read.
- Shifted pixelclock phase for C-One cartridge port so it looks more like a real C64.
(cpu clock changes when pixel-clock level is high)
- Added IRQ and NMI input from C-One cartridge port.
- Fixed bug in sprite logic introduced during VIC-II rewrite. MCurrentPixel didn't get reset.
- Mapped BA to FPGA pin 149 (PCI pad1). It enables better cartridge emulation (requires a PCB patch).
- Increased length of the 'write' signal so a RetroReplay cartridge can freeze the machine.
- Partial support for the cartridge port on the C-One.
- Fixed bug in keyboard matrix, it had problems recognising the first key-press after boot.
- Merged Mark McDougall's keyboard extensions. Numeric keypad on ps/2 keyboard can be used as a joystick.
Use the 0 key as fire button. F11 switches between emulation of joystick A or joystick B.
- Increased number of reset cycles to 4095 in example toplevel. Prevents problems during startup on other FPGA boards.
- Lots of small fixes to the CPU. There is only one opcode bug remaining (ARR in decimal mode).
- Rewritten large parts of the VIC-II code. Now it properly supports delayed-dma tricks.
- Sprite-stretching by toggling Y-expansion bit is now supported.
- 9th sprite is displayed on correct position in the Krestage 3 demo.
- Timing between $D020 and screen pixels is cycle correct.
- Implemented "ANE" undocumented opcode.
- Implemented "SHA" undocumented opcode.
- Implemented "SHX" undocumented opcode.
- Implemented "SHY" undocumented opcode.
- Implemented "LAS" undocumented opcode.
- Fixed CPU behaviour when NMI interrupts pending IRQ or BRK.
- Fixed Clear CIA IRQ, so will not block TimerA/B IRQ occuring in exact same cycle.
- Fixed CIA behaviour during toggle oneshot bit.
- Fixed IRQ and NMI timing of 6510 cpu.
- Fixed 8 bit vs 9 bit compare for sprite Y position. This fixes missing sprites in the game 'Delta'.
- Implemented "LXA imm" undocumented opcode.
- Implemented CIA timers underflow toggle for I/O-pin PB6 and PB7.
- Fixed CIA chain mode (timerA controls timerB).
- Fixed reload behaviour during CIA timer underflow.
- Renamed interrupt flags in CIA.
- VIC registers are directly connected to cpu. They are not routed through buslogic anymore.
- Replaced 'mob' structure in VIC source with separate signals as some vhdl compilers don't like it.
- Added other FPGA platform files.
- Changed reset moment of an internal sprite flag. Now sprites can be displayed in right side border.
- CIA has flag_n input (cassette, rs232 and SRQ line).
- Implemented "SBX imm" (aka AXS imm) undocumented opcode.
- Optimised CIA Timer to save around 100 logic-elements in FPGA.
- Fixed cpu IO registers at $0000/$0001 and moved them from buslogic to separate vhdl file.
- Fixed a CIA TOD bug preventing starting of TOD in some cases.
- Fixed IRQ/NMI timing of the branch instructions. Interrupts are delayed one cycle if branch is taken, but there is no page crossing.
- Created build and release scripts, so it is easier and less error prone to make release versions.
- Fixed F7 key (was wrongly mapped to F4)
- Implemented 'pulseRd' signal so CIA/VIC-II special readonly registers are only triggered on read not write.
- Did a lot of CIA timer fixes. The crX_inmode flags work correctly now. (So timerB can be slaved to timerA)
- Added one cycle delay while writing to the VIC-II registers. The side-border can be opened now!
- Added one cycle delay to NMI.
- Fixed the cycle count of indexed read-modify-write opcodes.
- Splitted 65xx ALU in two for implementation of undoc-opcodes.
- Implemented undoc-opcodes: SLO(ASO) RLA SRE RRA SAX DCP ISC ANC
- Fixed readback of VIC-II sprite expansion registers (fixes random sprite corruption in Paradroid).
- Fixed reading of memory location 3FFF/39FF in VIC-II idle mode.
- Eliminated extra character that appeared on the left side after poke53270,15
- Fixed 2 pixel offset of sprite when it was expanded in X direction. (allows 'Impossible Mission' to be played)
- Changed IRQ timing in cpu (necessary for certain VIC-II tricks to work).
- Increased blanking area to remove artifacts in the first lines of the screen.
- Changed I flag behaviour for 'RTI'. No interrupts are possible just after a RTI.
- Fixed VIC-II emulation so number of cycles/line is 63.
- Fixed bug in generation of (virtual) BA signal.
- Moved cycle of the sprite calculations to enable sprite multiplexing.
- Fixed 8 pixel left shift of bitmap graphics. Lots of games had distored graphics
- Optimised some of the bus-logic, somewhat easier for the vhdl compiler.
- Fixed video sync issue introduced in Alpha9
- Because reading from real SID isn't yet possible, a dummy register $1B is created for games that need it.
- Partial implementation of CIA TOD (time of day)
- Enabled NMI interrupt (did fix in alpha8 but forgot to enable it)
- Fixed crash when "BRK" was encountered after a branch across page boundary.
- Implemented various undocumented "NOP" opcodes.
- Implemented Sprite priority
- Optimised VIC-II graphic modes for less FPGA resources use.
- Fixed NMI interrupts
- Fixed "CMP abs,y" instruction
- Fixed "ORA (zp,x)" instruction
- Fixed "BIT xxx" instructions
- Fixed crash when TXS instruction was executed while interrupt pending.
- Fixed zp,x so it wraps around staying in page 0.
- Fixed "STX zp,x"
- Note: Alpha7 has introduced alot of CPU bugs as it contained a complete new 6510 core
All of these problems are rectified in Alpha8 and later.
- Implemented Sprite X expansion.
- Implemented Sprite Y expansion.
- Added support for multi-color sprites.
- Added sprite-background collision detection.
- New 6510 emulation for less FPGA resources use.
Added sprite-sprite collision detection + interrupt.
VIC-II emulation should be cycle exact now.
After a long delay and some very usefull help from Tobias.
There is another alpha release of the "PAL" core for your c-one.
- Contains preliminary sprite support in VIC-II
- Improved flicker-fixer (hopefully all monitors support the 50Hz mode now...)
- FPGA64 specific MMU/bootload disabled in this version, it uses
currently the same rom/memory layout as Jerry's ntsc core.
Use F12 to switch between PAL (50Hz) or NTSC (60Hz) mode.
First visible result
Although the startup-screen was recognisable, it was not correct. After debugging I discovered the instructions 'TAX' and 'INC abs', didn't produce the correct result. The 'TAX' error is responsable for the left/down shifted line. The incorrect 'INC abs' distorted the number of free bytes calculation.
Newer versions emulate more VIC tricks
Here FPGA-64 is running the "Krestage 2" demo, showing that delay-DMA effects are emulated correctly.
(notice there is some debugging info at the top and left of the screen. This logic is not included in release versions.)