Skip to content
The Original Nintendo Gameboy in Verilog
Verilog Python Makefile
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
boot Added boot rom for dmg gameboy Dec 2, 2014
memory
ops
scripts Created better opcode generation with seperate file for bus specs Dec 12, 2014
README.md
REPORT.md
apu.v
audio.v
boot.v
div.v
dma.v Implemented controller support and sprites Dec 1, 2014
gb.qpf
gb.sdc
gb.v Reduced tram to be only 1-port due to using 42 instances Dec 10, 2014
gbc.qsf
hdmi.v
inthandle.v
joypad.v Assigned clock frequencies to fix uart/gb clock transfer issue Dec 4, 2014
link.v
mbc1.v
mmap.v
ppu.v Fixed window offset Dec 10, 2014
seg7.v Created project and added current implementation of the lr35902 Nov 22, 2014
sram.v
timer.v
uart.v
z80.v
z80_alu.v
z80_ucode.v

README.md

The Very Gameboy Emulator

Current Repo

The Very Gameboy Emulator, as I'm calling it, is a functional implementation of the original Nintendo Gameboy in Verilog targeting the Cyclone V GX. The Emulator communicates over UART for controller input and displays the Gameboy's graphics over HDMI along with the Gameboy's audio. The Emulator was implemented for CS 350c, the Advanced Computer Architecture class taught by Professor Ahmed Gheith at UT.

Unfortunately, the emulator not completely accurate and has a few major limitations. The biggest limitation currently is the restriction to 512kbyte roms or less due to the size of the external SRAM and lack of functioning DDR controller. Additionally, battery backed RAM is not fully implemented, which both prevents saving, and can cause very interesting artifacts on games that expect a consistent initial state.

For a more depth explanation of how the Gameboy is implemented, feel free to look at the Report required for the class.

Instructions

These quick instructions are going to assume you are already able to load images onto the Cyclone V.

First, you will need to connect the board over HDMI and run the initial image until the test picture is displayed. This is due to the HDMI chip needing several I2C registers initialized which would require significant overhead to take care of in the emulator.

Next, you should be able to load the emulator's image onto the board. The screen should appear slightly greenish, and the state machine shown on the 7-seg displays should initialize to the default state "0041"

Several switches are used to configure the running emulator:

 Switches           
[9 8 7 6 5 4 3 2 1 0]
 | | | | | | \-----/- Used to select the current display on the 7-segs
 | | | | | \- 1/16th clock
 | | | | \- 1/8th clock
 | | | \- 1/4th clock
 | | \- normal clock
 | \- 2x clock
 \- enable flashing

To run the emulator at normal speed, you will want to enable only switch 7. If no rom has been flashed, you should see a corrupted square slide down the screen. This is actually normal behaviour for the original Gameboy.

To flash the emulator with a rom, you will need to enable switch 9. If you leave the emulator itself running, very strange things can happen, so it is suggested to leave the other switches disabled. You should then plug the board to a Linux machine over a USB cable and connect through UART. The "gbflash" script can then be used to flash the Emulator with a Gameboy rom. The offset and size of the ROM must be specified in hexadecimal. These can be found by using the hexdump command on the rom itself. The following commands can be used assuming the device appears as /dev/ttyUSB0.

sudo chmod 777 /dev/ttyUSB0
stty -F /dev/ttyUSB0 115200
./scripts/gbflash.py 0 80000 rom.gb /dev/ttyUSB0

To send controller input over UART, the "controls" script can be used as long as an xsession is currently running.

./scripts/controls.py /dev/ttyUSB0

By default controls are mapped as such, although this can easily be changed by modifying the python script to use different PyGame key values.

  • Up/Left/Down/Right = W/A/S/D
  • A/B = Enter/Quote
  • Start/Select = Space/E

Debugging

There are several displays to assist with debugging. First the leds on the board can be used to get a large amount of information of the processor state

 Red LEDS
[9 8 7 6 5 4 3 2 1 0]
 | | | | |       \-/- PPU Display mode
 | | | | \- VBlank interrupt
 | | | \- Display status interrupt
 | | \- Timer interrupt
 | \- Link cable interrupt
 \- Joypad interrupt

 Green LEDS
[7 6 5 4 3 2 1 0]
 | | | | \-/ \-/- CPU load and store signals
 | | | |  \- DMA load and store signals
 | | | \- Carry flag
 | | \- Half-carry flag
 | \- Subtraction flag
 \- Zero flag

Additionally, the 4 on board 7-segs can display a 16-bit hex value specified by the lowest 4 switches

  • 0000 = State machine state
  • 0100 = Timer value
  • 1000 = AF Register pair
  • 1001 = BC Register pair
  • 1010 = DE Register pair
  • 1011 = HL Register pair
  • 1100 = Stack Pointer
  • 1101 = Program Counter

Finally, the link cable is transmits all written data through the UART connection and can be monitored like so.

screen /dev/ttyUSB0 115200

Resources

The following are very useful resources for Gameboy information and are really what made this project possible.

  • Opcode Listing A very useful listing of the LR35902 instructions
  • Gameboy Manual Documentation on the Gameboy for writing software which covers the expected functionality.
  • Gameboy Dev Wiki A collection of important information regarding the Gameboy for emulation.
You can’t perform that action at this time.