Giter Club home page Giter Club logo

goboy's Introduction

GoBoy

Build Status codecov Go Report Card GoDoc

GoBoy is a multi-platform Nintendo GameBoy and GameBoy Color emulator written in go. The emulator can run the majority of GB games and some CGB games. There is also colour and sound support. This emulator was primarily built as a development exercise and is still work in progress. Please feel free to contribute if you're interested in GameBoy emulator development.

The program includes debugging functions making it useful for understanding the emulator operation for building one yourself. These functions include printing of opcodes and register values to the console at each step (although will greatly slow down the emulation) and toggling of individual sound channels.

Installation

Download the latest release of GoBoy from the releases page.

Building from source

With go installed, you can install GoBoy into your go bin by running:

go get github.com/Humpheh/goboy/cmd/goboy

If you have Go 1.11 you can also do:

git clone https://github.com/Humpheh/goboy.git
cd goboy
go build -o goboy cmd/goboy/main.go

GoBoy is compatible with MacOS, Windows and Linux. Building on Windows 10 requires MinGW and on Linux, you'll need to install gtk.

GoBoy uses the go library pixel for control binding and graphics rendering, which requires OpenGL. You may need to install some requirements which can be found on the pixels readme.

Usage

goboy zelda.gb

Controls: Z X Enter Backspace

The colour palette can be cycled with = (in DMG mode), and the game can be made fullscreen with F.

Other options:

  -dmg
    	set to force dmg mode
  -mute
    	mute sound output

Debug or experimental options:

  -cpuprofile string
    	write cpu profile to file (debugging)
  -disableVsync
    	set to disable vsync (debugging)
  -stepthrough
    	step through opcodes (debugging)
  -unlocked
    	if to unlock the cpu speed (debugging)

Debugging

There are a few keyboard shortcuts useful for debugging:

Q - force toggle background
W - force toggle sprites
A - print gb background palette data (cgb)
S - print sprite palette data (cgb)
D - print background map to log
E - toggle opcode printing to console (will slow down execution)
7,8,9,0 - toggle sound channels 1 through 4.

Saving

If the loaded rom supports a battery a <rom-name>.sav (e.g. zelda.gb.sav) file will be created next to the loaded rom containing a dump of the RAM from the cartridge. A loop in the program will update this save file every second while the game is running.

Testing

GoBoy currently passes all of the tests in Blargg's cpu_instrs and instr_timing test roms.

These roms are included in the source code along with a test to check the output is as expected (instructions_test.go and timing_test.go). These tests are also run on each commit.

Contributing

Please feel free to open pull requests to this project or play around if you're interested! There are still plenty of small bugs that can easily be found through playing games on the emulator, or take a task from the TODO list below!

Known Bugs and TODO list

  • Sprites near edge of screen not drawing
  • Top half of sprite disappearing off top of screen
  • Small sprites row glitch
  • BG tile window offset issue - visible on Pokemon Red splash screen - possibly mistimed interrupt?
  • Harry Potter and The Chamber of Secrets has odd sprite issues
  • Request to set screen to white does not do so
  • MBC3 banking support
  • Improve APU (see Pokemon Yellow opening screen for reason why)
  • Resizable window
  • White screen when off
  • STOP opcode behaviour
  • Sprite Z-drawing bugs
  • Minor APU timing issues
  • Better APU buffering
  • Stop jittering
  • MBC3 clock support
  • Speed up CPU and PPU
  • Platform native UI?
  • More DMG colour palettes
  • Support save-states
  • Support boot roms
  • Blargg's test ROMs

Resources

A large variety of resources were used to understand and test the GameBoy hardware. Some of these include:

goboy's People

Contributors

bartelliott avatar ear7h avatar humpheh avatar lk16 avatar totallygamerjet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

goboy's Issues

Failed Blargg's cgb_sound.gb

What did you do?

./goboy cgb_sound.gb

What did you expect to see?

Tests passed

What did you see instead?

Hung on test 12:
deepinscreenshot_select-area_20181123122017

System details

go version go1.11.2 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bell/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bell/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/bell/github/goboy/go.mod"
GOROOT/bin/go version: go version go1.11.2 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.11.2
uname -sr: Linux 4.19.2-arch1-1-ARCH
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.28.
gdb --version: GNU gdb (GDB) 8.2

Bug: Sound is noisy on Windows

Describe the bug
Sound is clear on MacOS, but noisy on Windows10. Linux is unchecked.

To Reproduce

git clone https://github.com/Humpheh/goboy.git
cd goboy
go build -o goboy cmd/goboy/main.go
./goboy pokered.gb

Expected behaviour
A clear sound on Windows10.

System Details:

I tried Pokemon Red(en) & Legend of Zelda Link's Awakening DX(en), and both were noisy.

CPU: Intel Core i5-8250U
RAM: 16.0GB
OS: Windows 10 Home 1909
$ go version
go version go1.15.6 windows/amd64

Background tile window offset

Issue visible in Pokemon Red where the top line of the copyright moves with the scrolling Pokemon on the splash screen. Likely due to mistimed interrupts or incorrect scanline rendering.

Example:

image

Failed Blargg's dmg_sound.gb

What did you do?

./goboy -dmg dmg_sound.gb

What did you expect to see?

Tests passed

What did you see instead?

On the 12th test, goboy crashes:

panic: runtime error: index out of range

goroutine 19 [running]:
github.com/Humpheh/goboy/pkg/cart.(*MBC1).Read(0xc00012d700, 0xc000014000, 0x400000c0000a5400)
        /home/bell/github/goboy/pkg/cart/mbc1.go:30 +0xb7
github.com/Humpheh/goboy/pkg/gb.(*Memory).Read(0xc000116000, 0xc0000b4000, 0x4c000040)
        /home/bell/github/goboy/pkg/gb/memory.go:271 +0x1cf
github.com/Humpheh/goboy/pkg/gb.(*Gameboy).ExecuteOpcode(0xc0000f4000, 0xc0000d0b1a)
        /home/bell/github/goboy/pkg/gb/instructions.go:132 +0xad8
github.com/Humpheh/goboy/pkg/gb.(*Gameboy).ExecuteNextOpcode(0xc0000f4000, 0x0)
        /home/bell/github/goboy/pkg/gb/instructions.go:52 +0x62
github.com/Humpheh/goboy/pkg/gb.(*Gameboy).Update(0xc0000f4000, 0xc0000b1d01)
        /home/bell/github/goboy/pkg/gb/gameboy.go:81 +0x119
main.startGB(0xc0000f4000, 0x76d0a0, 0xc0000a28c0)
        /home/bell/github/goboy/cmd/goboy/main.go:136 +0x237
main.start(0x7ffd676cb33a, 0x2b)
        /home/bell/github/goboy/cmd/goboy/main.go:113 +0x43c
main.main.func1()
        /home/bell/github/goboy/cmd/goboy/main.go:60 +0x33
github.com/faiface/mainthread.Run.func1(0xc0000a2820, 0xc000078240)
        /home/bell/go/pkg/mod/github.com/faiface/[email protected]/mainthread.go:37 +0x27
created by github.com/faiface/mainthread.Run
        /home/bell/go/pkg/mod/github.com/faiface/[email protected]/mainthread.go:36 +0xb1

System details

go version go1.11.2 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bell/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bell/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/bell/github/goboy/go.mod"
GOROOT/bin/go version: go version go1.11.2 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.11.2
uname -sr: Linux 4.19.2-arch1-1-ARCH
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.28.
gdb --version: GNU gdb (GDB) 8.2

fatal error: unexpected signal during runtime execution

Since I can't access golang.org, I remove go.sum and go.mod. Then I manually download the dependencies from github. But now I am having problems running. I want to know what is wrong.

# github.com/go-gl/glfw/v3.2/glfw
In file included from ../../go/src/github.com/go-gl/glfw/v3.2/glfw/c_glfw_linbsd.go:24:0:
../../go/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/linux_joystick.c: In function ‘_glfwInitJoysticksLinux’:
../../go/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/linux_joystick.c:224:42: warning: ‘%s’ directive output may be truncated writing up to 255 bytes into a region of size 9 [-Wformat-truncation=]
             snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
                                          ^~~~~~~
In file included from /usr/include/stdio.h:862:0,
                 from /usr/include/X11/Xcursor/Xcursor.h:26,
                 from ../../go/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_platform.h:39,
                 from ../../go/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/internal.h:169,
                 from ../../go/src/github.com/go-gl/glfw/v3.2/glfw/glfw/src/x11_init.c:28,
                 from ../../go/src/github.com/go-gl/glfw/v3.2/glfw/c_glfw_linbsd.go:19:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:64:10: note: ‘__builtin___snprintf_chk’ output between 12 and 267 bytes into a destination of size 20
   return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        __bos (__s), __fmt, __va_arg_pack ());
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ws-zzy/code/goboy/go_build_main_go #gosetup
fatal error: unexpected signal during runtime execution
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x7fc12bdf0fa0]

runtime stack:
runtime.throw(0x71a5fa, 0x2a)
	/usr/local/go/src/runtime/panic.go:608 +0x72
runtime.sigpanic()
	/usr/local/go/src/runtime/signal_unix.go:374 +0x2f2

goroutine 1 [syscall, locked to thread]:
runtime.cgocall(0x6335e0, 0xc00009fb80, 0x25f50a0)
	/usr/local/go/src/runtime/cgocall.go:128 +0x5e fp=0xc00009fb50 sp=0xc00009fb18 pc=0x46653e
github.com/mattn/go-gtk/gtk._Cfunc_gtk_dialog_run(0x25f50a0, 0x0)
	_cgo_gotypes.go:7705 +0x49 fp=0xc00009fb80 sp=0xc00009fb50 pc=0x55e5a9
github.com/mattn/go-gtk/gtk.(*Dialog).Run.func1(0x25f50a0, 0x25f50a0)
	/home/ws-zzy/go/src/github.com/mattn/go-gtk/gtk/gtk.go:1236 +0x56 fp=0xc00009fbb8 sp=0xc00009fb80 pc=0x57a286
github.com/mattn/go-gtk/gtk.(*Dialog).Run(0xc0000100e0, 0xc00000e030)
	/home/ws-zzy/go/src/github.com/mattn/go-gtk/gtk/gtk.go:1236 +0x39 fp=0xc00009fbd8 sp=0xc00009fbb8 pc=0x56b729
github.com/Humpheh/goboy/dialog.chooseFile(0x70b346, 0x4, 0x0, 0xc00009fe30, 0x0, 0x0, 0x0, 0x0)
	/home/ws-zzy/go/src/github.com/Humpheh/goboy/dialog/dlgs_linux.go:68 +0x35e fp=0xc00009fd38 sp=0xc00009fbd8 pc=0x598c4e
github.com/Humpheh/goboy/dialog.(*FileBuilder).load(0xc00009fe30, 0x0, 0x6987a0, 0xc0000d0120, 0xc00005a100)
	/home/ws-zzy/go/src/github.com/Humpheh/goboy/dialog/dlgs_linux.go:40 +0x49 fp=0xc00009fd88 sp=0xc00009fd38 pc=0x598689
github.com/Humpheh/goboy/dialog.(*FileBuilder).Load(0xc00009fe30, 0x0, 0x0, 0x0, 0x1)
	/home/ws-zzy/go/src/github.com/Humpheh/goboy/dialog/dlgs.go:101 +0x2b fp=0xc00009fdc0 sp=0xc00009fd88 pc=0x59818b
main.getROM.func1()
	/home/ws-zzy/code/goboy/cmd/goboy/main.go:123 +0x1e8 fp=0xc00009fe78 sp=0xc00009fdc0 pc=0x62f6d8
github.com/faiface/mainthread.Call.func1()
	/home/ws-zzy/go/src/github.com/faiface/mainthread/mainthread.go:63 +0x2f fp=0xc00009fea0 sp=0xc00009fe78 pc=0x54312f
github.com/faiface/mainthread.Run(0x71ca48)
	/home/ws-zzy/go/src/github.com/faiface/mainthread/mainthread.go:44 +0xbd fp=0xc00009ff40 sp=0xc00009fea0 pc=0x542d2d
github.com/faiface/pixel/pixelgl.Run(0x71ca48)
	/home/ws-zzy/go/src/github.com/faiface/pixel/pixelgl/run.go:32 +0x57 fp=0xc00009ff80 sp=0xc00009ff40 pc=0x627df7
main.main()
	/home/ws-zzy/code/goboy/cmd/goboy/main.go:45 +0x32 fp=0xc00009ff98 sp=0xc00009ff80 pc=0x62eb32
runtime.main()
	/usr/local/go/src/runtime/proc.go:201 +0x207 fp=0xc00009ffe0 sp=0xc00009ff98 pc=0x48f507
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1333 +0x1 fp=0xc00009ffe8 sp=0xc00009ffe0 pc=0x4ba751

goroutine 19 [chan receive]:
github.com/faiface/mainthread.Call(0xc0000100d0)
	/home/ws-zzy/go/src/github.com/faiface/mainthread/mainthread.go:66 +0xc2
main.getROM(0x0, 0xc0000920e0)
	/home/ws-zzy/code/goboy/cmd/goboy/main.go:119 +0xbf
main.start()
	/home/ws-zzy/code/goboy/cmd/goboy/main.go:53 +0x5e
github.com/faiface/mainthread.Run.func1(0x71ca48, 0xc000068240)
	/home/ws-zzy/go/src/github.com/faiface/mainthread/mainthread.go:37 +0x27
created by github.com/faiface/mainthread.Run
	/home/ws-zzy/go/src/github.com/faiface/mainthread/mainthread.go:36 +0xb1

GBC sprites do not render correctly

This can be demonstrated in the Harry Potter and the Chamber of Secrets for gbc where from the first screen sprites are half rendered and the text box does not fully draw.

screenshot 2018-11-25 at 11 57 15

Failed Blargg's interrupt_time.gb

What did you do?

./goboy cgb_sound.gb

What did you expect to see?

Tests passed

What did you see instead?

Test Failed:

 Sound: true
 CGB  : true

2018/11/23 12:28:52 Cart type: 0x02 (MBC1)
2018/11/23 12:28:53 0x10 (STOP) unimplemented (is 0x00 follows)

deepinscreenshot_select-area_20181123122920

System details

go version go1.11.2 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bell/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bell/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/bell/github/goboy/go.mod"
GOROOT/bin/go version: go version go1.11.2 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.11.2
uname -sr: Linux 4.19.2-arch1-1-ARCH
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.28.
gdb --version: GNU gdb (GDB) 8.2

Speed up CPU

Just found this project and saw one of you goals was to speed up the CPU, I think I found an optimization that can be made in the following function. Currently there is a switch statement but I think a lookup table in the form of a map[byte]func(*Gameboy) or [numOpCodes]func(*Gameboy) (static size array) would be more efficient.

// ExecuteOpcode is a large switch statement containing the opcode operations.
func (gb *Gameboy) ExecuteOpcode(opcode byte) {

Game does not load from .sav file

Describe the bug
A clear and concise description of what the bug is. If applicable, add screenshots to help explain your problem.
When I start the game, it begins writing save state to .sav. When I relaunch the game it doesn't autoload from the .sav file and running Goboy with the .sav file doesn't work either.
To Reproduce
What did you run and do?
I started Pokemon Red and played for a bit. Closed out of the game and restarted the game and no save state.
Expected behaviour
A clear and concise description of what you expected to happen.
I expect the game to load from the .sav file.
System Details:
Please paste the outputs of go version and go env. If you were running from a binary, please detail your OS.
go version go1.10.3 linux/amd64

[dymurray@pups ~]$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/dymurray/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/dymurray/go"
GORACE=""
GOROOT="/usr/lib/golang"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build386047923=/tmp/go-build -gno-record-gcc-switches"

Failed Blargg's mem_timing.gb

What did you do?

./goboy mem_timing.gb

What did you expect to see?

Tests passed

What did you see instead?

Failed 3 tests:

 Sound: true
 CGB  : true

2018/11/23 12:31:48 Cart type: 0x01 (MBC1)

deepinscreenshot_select-area_20181123123215

System details

go version go1.11.2 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bell/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/bell/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/bell/github/goboy/go.mod"
GOROOT/bin/go version: go version go1.11.2 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.11.2
uname -sr: Linux 4.19.2-arch1-1-ARCH
/usr/lib/libc.so.6: GNU C Library (GNU libc) stable release version 2.28.
gdb --version: GNU gdb (GDB) 8.2

Add MBC3 clock support

The battery backed Real Time Clock (RTC) on some memory bank controllers is not implemented.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.