NES emulator written in Go.

Summary

This is an NES emulator written in Go.

Screenshots

Screenshots

Title Screens

http://www.michaelfogleman.com/static/nes/

Dependencies

github.com/go-gl/gl/v2.1/gl
github.com/go-gl/glfw/v3.1/glfw
github.com/gordonklaus/portaudio

The portaudio-go dependency requires PortAudio on your system:

To build portaudio-go, you must first have the PortAudio development headers and libraries installed. Some systems provide a package for this; e.g., on Ubuntu you would want to run apt-get install portaudio19-dev. On other systems you might have to install from source.

On Mac, you can use homebrew:

brew install portaudio

Installation

The go get command will automatically fetch the dependencies listed above, compile the binary and place it in your $GOPATH/bin directory.

go get github.com/fogleman/nes

Usage

nes [rom_file|rom_directory]
  1. If no arguments are specified, the program will look for rom files in the current working directory.

  2. If a directory is specified, the program will look for rom files in that directory.

  3. If a file is specified, the program will run that rom.

For 1 & 2, the program will display a menu screen to select which rom to play. The thumbnails are downloaded from an online database keyed by the md5 sum of the rom file.

Menu Screenshot

Controls

Joysticks are supported, although the button mapping is currently hard-coded. Keyboard controls are indicated below.

Nintendo Emulator
Up, Down, Left, Right Arrow Keys
Start Enter
Select Right Shift
A Z
B X
A (Turbo) A
B (Turbo) S
Reset R

Mappers

The following mappers have been implemented:

  • NROM (0)
  • MMC1 (1)
  • UNROM (2)
  • CNROM (3)
  • MMC3 (4)
  • AOROM (7)

These mappers cover about 85% of all NES games. I hope to implement more mappers soon. To see what games should work, consult this list:

NES Mapper List

Known Issues

  • there are some minor issues with PPU timing, but most games work OK anyway
  • the APU emulation isn't quite perfect, but not far off

Documentation

Interested in writing your own emulator? Curious about the NES internals? Here are some good resources:

Owner
Michael Fogleman
Software Engineer at Formlabs
Michael Fogleman
Comments
  • Error on install

    Error on install

    I run the following: go get github.com/fogleman/nes

    And get the following output: # pkg-config --cflags portaudio-2.0 Package portaudio-2.0 was not found in the pkg-config search path. Perhaps you should add the directory containing `portaudio-2.0.pc' to the PKG_CONFIG_PATH environment variable No package 'portaudio-2.0' found pkg-config: exit status 1

  • Module path should be

    Module path should be "github.com/fogleman/nes", not "nes"

    Background

    Module path is inconsistent with go import path. GO111MODULE=on, run go get github.com/fogleman/nes:

    $ go get: github.com/fogleman/[email protected]: parsing go.mod:
            module declares its path as: nes
                    but was required as: github.com/fogleman/nes
    

    Solution

    Fix the module path:

    Rename the module path to "github.com/fogleman/nes". https://github.com/fogleman/nes/blob/master/go.mod#L1

    module github.com/fogleman/nes
    go 1.14
    require (
    	…
    ) 
    
  • Zero Page Indexed

    Zero Page Indexed

    case modeZeroPageX:
        address = uint16(cpu.Read(cpu.PC+1) + cpu.X)
    
    case modeZeroPageY:
        address = uint16(cpu.Read(cpu.PC+1) + cpu.Y)
    

    I have yet to run or play with your code, Golang isn't exactly my domain. However, this doesn't appear to account for wrapping and always being on the zero page. Lets say 0xFF is in cpu.PC+1 and cpu.X is 3. The address returned would be 0x0102 not 0x0002. Same goes for Y.

    I'm writing my own 6502 at the moment so please feel free to call me nuts since your emulator seems to work from the screenshots.

    From: Emulator 101

    Zero-Page Indexed

    This works just like absolute indexed, but the target address is limited to the first 0xFF bytes.

    The target address will wrap around and will always be in the zero page. If the instruction is LDA $C0,X, and X is $60, then the target address will be $20. $C0+$60 = $120, but the carry is discarded in the calculation of the target address.

  • Failed when using

    Failed when using "go get"

    Go Version: go version go1.11.2 darwin/amd64 OS: MacOS 10.12.6

    When I run go get github.com/fogleman/nes, it failed. And here is the output:

    go: finding github.com/fogleman/nes latest
    go: downloading github.com/fogleman/nes v0.0.0-20180222220412-5a21a6273289
    go: finding github.com/gordonklaus/portaudio latest
    go: finding github.com/go-gl/glfw/v3.1/glfw latest
    go: finding github.com/go-gl/gl/v2.1/gl latest
    go: downloading github.com/gordonklaus/portaudio v0.0.0-20180817120803-00e7307ccd93
    go: finding github.com/go-gl/gl latest
    go: downloading github.com/go-gl/gl v0.0.0-20181026044259-55b76b7df9d2
    go: finding github.com/go-gl/glfw latest
    go: downloading github.com/go-gl/glfw v0.0.0-20181213070059-819e8ce5125f
    # pkg-config --cflags  -- portaudio-2.0
    Package portaudio-2.0 was not found in the pkg-config search path.
    Perhaps you should add the directory containing `portaudio-2.0.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'portaudio-2.0' found
    pkg-config: exit status 1
    
  • USB Support for Controller

    USB Support for Controller

    Hi,

    I wonder if it would be difficult to add USB Controller Support for an USB SNES Gamepad so I could run this on my Raspberry Pi and have an sort of Go based NES Classic MINI alternative..

  • How to reset the loaded rom?

    How to reset the loaded rom?

    Hi I know this is just an awesome pet project, but I have a strage problem I played a game which crashed the music plays but their are there only an background color but now other spirites like the charecter and level objects or the game menu.. Is there any trick to solve this?

  • Go 1.6 runtime error

    Go 1.6 runtime error

    Hello Michael,

    I am really impressed with your implementation of nes emulator, so much so that I'm trying to implement my own (Swift + Metal). Was playing with your implementation, however after the update to go 1.6 I am no longer able to due to runtime error.

    The problem exists for go version go1.6.2 darwin/amd64 and here is the stack trace.

    panic: runtime error: cgo argument has Go pointer to Go pointer
    
    goroutine 1 [running, locked to thread]:
    panic(0x44e4660, 0xc820111a30)
        /usr/local/opt/go/libexec/src/runtime/panic.go:481 +0x3e6
    github.com/gordonklaus/portaudio._cgoCheckPointer1(0x43ed9a0, 0xc820096080, 0x0, 0x0, 0x0, 0x43ccde0)
        ??:0 +0x4d
    github.com/gordonklaus/portaudio.OpenStream(0x0, 0x0, 0x0, 0xc82006a360, 0x2, 0xd5d4a5, 0x40e5888000000000, 0x0, 0x0, 0xc820111a00, ...)
        /Users/pawel/go/src/github.com/gordonklaus/portaudio/portaudio.go:504 +0x3d1
    github.com/fogleman/nes/ui.(*Audio).Start(0xc8200c9340, 0x0, 0x0)
        /Users/pawel/go/src/github.com/fogleman/nes/ui/audio.go:24 +0x192
    github.com/fogleman/nes/ui.Run(0xc820111980, 0x1, 0x1)
        /Users/pawel/go/src/github.com/fogleman/nes/ui/run.go:33 +0xce
    main.main()
        /Users/pawel/go/src/github.com/fogleman/nes/main.go:19 +0x13d
    

    Kind regards, Pawel

  • error with go get github.com/fogleman/nes

    error with go get github.com/fogleman/nes

    When I try to install the emulator I'm getting this output:

    "# github.com/go-gl/glfw/v3.1/glfw /usr/bin/ld: no se puede encontrar -lXi collect2: error: ld returned 1 exit status"

    When I look in $GOPATH/bin, nes is not installed.

    Thank you.

  • Can't install on Ubuntu 15.10

    Can't install on Ubuntu 15.10

    My Ubuntu system had upgraded to Ubuntu 15.10, when ran command "go get github.com/fogleman/nes", go-gl can't compile. @ubuntu:~$ go get github.com/fogleman/nes

    github.com/go-gl/glfw/v3.1/glfw

    In file included from GoProject/src/github.com/go-gl/glfw/v3.1/glfw/context.go:4:0: glfw/include/GLFW/glfw3.h:153:21: fatal error: GL/gl.h: No such file or directory compilation terminated.

    github.com/go-gl/gl/v2.1/gl

    GoProject/src/github.com/go-gl/gl/v2.1/gl/procaddr.go:52:21: fatal error: GL/glx.h: No such file or directory compilation terminated.

  • [Newb Question] Go-gl can't find headers

    [Newb Question] Go-gl can't find headers

    Alright, so admittedly this might be a stupid question, but I normally use a windows environment for development and have only recently started using Linux, mostly because it's damn hard to contribute to anything open source when you're running windows. Some of these configuration problems can be a bit baffling, so excuse the newbness.

    Following the directions, I installed portaudio without any issue. But when I ran go get github.com/fogleman/nes I get this error:

    # github.com/go-gl/gl/v2.1/gl
    gocode/src/github.com/go-gl/gl/v2.1/gl/procaddr.go:52:21: fatal error: GL/glx.h: No such file or directory
      #include <GL/glx.h>
                         ^
    compilation terminated.
    # github.com/go-gl/glfw/v3.1/glfw
    In file included from gocode/src/github.com/go-gl/glfw/v3.1/glfw/context.go:4:0: glfw/include/GLFW/glfw3.h:153:21: fatal error: GL/gl.h: No such file or directory
       #include <GL/gl.h>
                         ^
    compilation terminated.
    

    It's pretty obvious what's happening here: go-gl can't find the OpenGL headers. Why, I'm not quite sure. Does something in my system need to be pointing to the header files, or is this an actual bug? I'm running Xubuntu 14, if that's relevant.

  • Change BRK instruction size to 2 bytes

    Change BRK instruction size to 2 bytes

    BRK ($00) has a padding byte so it actually takes 2 bytes, instead of 1.

    Per http://nesdev.com/the%20%27B%27%20flag%20&%20BRK%20instruction.txt:

    Regardless of what ANY 6502 documentation says, BRK is a 2 byte opcode. The first is #$00, and the second is a padding byte. This explains why interrupt routines called by BRK always return 2 bytes after the actual BRK opcode, and not just 1.

    Because of this Your emulator doesn't pass blarrg's "instr_test_v5" (official_only.nes, test 15) from https://wiki.nesdev.com/w/index.php/Emulator_tests.

  • invalid import path?

    invalid import path?

    been trying to get this set up and going. I'm rather new to all this. anyway I run into this when I use the command.

    go get github.com/fogleman/nes

    go: github.com/fogleman/nes: invalid github.com import path "github.com/fogleman"

    like I said I'm rather new and probably doing something completely wrong.

  • APU fixes

    APU fixes

    Fixed the abnormal tone when Mario failed. According to the document, writing $4000 and $4004 (writeControl)do not need to start envelope, which will cause Super Mario Bros to make an abnormal tone when the character fails.

  • Save state doesn't work correctly for games that make use of CHR RAM

    Save state doesn't work correctly for games that make use of CHR RAM

    Since you're not saving the carts chr data when it's written to games such as Metroid have a black screen on state load. This same issue would apply to games making use of PRG RAM.

Related tags
Nintendo Entertainment System (NES) and Famicom emulator written in Go
Nintendo Entertainment System (NES) and Famicom emulator written in Go

go6502 Nintendo Entertainment System (NES) and Famicom emulator written in Go Dependencies go get -u github.com/go-gl/gl go get -u github.com/go-gl/gl

Apr 25, 2022
Gones - An attempt to program a NES emulator

Gones - An attempt to program a NES emulator The following resources were used for the project: The great work on wiki.nesdev.org R650X and R651X Data

Jan 10, 2022
A ZX Spectrum Emulator written in Go
A ZX Spectrum Emulator written in Go

GoSpeccy - An evolving ZX Spectrum 48k Emulator GoSpeccy is a free ZX Spectrum (Speccy for friends) emulator written in Go. Quick start Installing and

Nov 28, 2022
Mettaur is GBA emulator written in golang.
Mettaur is GBA emulator written in golang.

Mettaur Mettaur is GBA emulator written in golang. Warning: This emulator is WIP, so many ROMs don't work correctly now. Run Please download latest bi

Dec 25, 2022
A GameBoy emulator written in Go

gogoboy A GameBoy emulator written in Go About this project This project is a proof of concept of building emulators with test driven development. I'v

Aug 20, 2022
Magia is GBA emulator written in golang.
Magia is GBA emulator written in golang.

magia is GBA emulator written in golang.

Dec 25, 2022
A toy GameBoy Color emulator written in golang.
A toy GameBoy Color emulator written in golang.

?? worldwide 日本語のドキュメントはこちら GameBoyColor emulator written in golang. This emulator can play a lot of ROMs work without problems and has many features.

Jan 1, 2023
A Chip8 emulator written in Go

A Chip8 Emulator in Go chip8.go is a simple Chip8 emulator, compliant with the technical standard laid out in the Cowgod's Manual. Graphics and sound

Jun 6, 2022
CHIP-8 Emulator written in Go
CHIP-8 Emulator written in Go

dP oo 88 .d8888b. 88d888b. dP 88d888b. 88d888b. dP dP 88' `"" 88' `88 88 88' `88 88' `88 88 88 88. ... 88 88 88 88. .88

Nov 26, 2021
A simple CHIP-8 emulator written in Go

GoCHIP This is a simple CHIP-8 emulator written in Go. Check out this blogpost to learn more about CHIP-8 emulation: https://tobiasvl.github.io/blog/w

Jan 10, 2022
A CHIP-8 emulator written in Go

chip8 A CHIP-8 emulator written in Go. Usage Usage of chip8: -scaleFactor int Display scale factor (default 10) rom Path to ROM (m

May 25, 2022
🕹️ A basic gameboy emulator with terminal "Cloud Gaming" support
🕹️ A basic gameboy emulator with terminal

Gameboy.Live ??️ Gameboy.Live is a Gameboy emulator written in go for learning purposes. You can simply play Gameboy games on your desktop: Or, "Cloud

Jan 1, 2023
Gopher2600 is an Atari 2600/VCS Emulator.
Gopher2600 is an Atari 2600/VCS Emulator.

Gopher2600 Gopher2600 is an emulator for the Atari 2600 written in the Go language. The accuracy of the emulation is very high and the 6507, TIA and R

Dec 8, 2022
A chip-8 emulator built with Go

Introduction Chip-8 is an interpretted language designed to create programs/games on the 8bit systems like the COSMAC VIP and Telmac 1800. Chyp8 is an

Oct 3, 2021
Golang RISC-V emulator that can play DOOM
Golang RISC-V emulator that can play DOOM

RISC-V Emulator A toy Golang RISC-V emulator that can play DOOM For now it uses smunaut bootloader and riscv_doom from the ICE40 project. But since th

Dec 12, 2022
'mouseable' is keyboard-based mouse emulator for Windows.

Motivation Mouseable is intended to replace a mouse or trackpad. This program was inspired by Ultimate Hacking Keyboard Demo, Windows built-in functio

Dec 12, 2022
Sensor Emulator

Sensor Emulator This is a simple sensor emulator software implemented for IoT experiments. It emulates sensors sending data to an MQTT broker. Feature

Nov 28, 2021
VMAGI - Write an performant emulator in 24 hours!
VMAGI - Write an performant emulator in 24 hours!

VMAGI Welcome! VMAGI is a small emulator/interpreter my friend Matthew and I challenged each other to build in 24 hours. This includes both the implem

Nov 27, 2022
Chip-8 - A simple chip-8 emulator for golang
Chip-8 - A simple chip-8 emulator for golang

?? What the fuck is this A simple chip-8 emulator. Chip-8 is a simple, interpret

Aug 4, 2022