Skip to content

zawata/SilverGB

Repository files navigation

SilverGB

Because it's not quite gold!

Summary

SilverGB is a gameboy emulator I'm writing to apply the knowledge and concepts of my senior-year class regarding CPU execution pipelines, and my general knowledge of embedded development.

I'm writing this code(and commenting it with what I learn) to hopefully interest other people who were like me when I first tried to start this project(as a sophmore in highschool ha!): minor knowledge of programming but major interest in doing something cool.

The emulator attempts to remain compilable on all Major Operating Systems(as I'm using SDL and OpenGL for OS interfacing).

Major TODOs

Slight TODOs are littered throughout the code, the bigger ones are placed here:

  • M-Cycle accurate CPU rewrite(see src/gb/new_cpu.c)
    • Basic structure is done and designed, just need to actually implement all 499 instructions
  • Accurate PPU timing
    • Most of this isn't centrally documented but spread across 3-4 documents and dozens of test-roms. So yay.

Progress:

✔ = Done
➕ = In Progress
🚫 = Not Working
- = Not Tested

➕ CPU
    🚫 STOP handling
➕ Cartridge
    ✔ Header Parsing
    ➕ Memory Bank Controllers
        ✔ ROM(+RAM)
        ✔ MBC1
        ➕️ MBC2
        ✔ MBC3
            ➕ RTC
        ➕️ MBC5
        🚫 Others
➕ Sound
    ➕ APU
        ➕ Square Channel 1
            🚫 Frequency Sweep
            ➕️ Volume Envelope
            ✔ Frequency Timer
        ➕ Square Channel 2
            ➕️ Volume Envelope
            ✔ Frequency Timer
        🚫 Wave Channel
        ➕ Noise Channel
            ➕️ Volume Envelope
            ➕️ Configurable Timer
            ➕️ LFSR
    ✔ Async Audio Playback
    ➕ Mixing?
    🚫 Volume Control
➕ PPU
    ✔ VRAM
    ✔ Pixel Fifo
        ✔ OAM Search
        ✔ VRAM Process
            ✔ Background
            ✔ Window
            ✔ Tile Fetching
            ✔ Sprite Fetching
        ️✔ HBLANK
        ️✔ VBLANK
    ➕ Display timing
    ✔ DMA
✔ Input
    ✔ Input
    ✔ Interrupts
➕ GBC Functions
    ✔ Palette Storage
    ➕ PPU Color Support
    ✔ New DMA
        ➕ GDMA
        ➕ HDMA
    ✔ VRAM Banking
    ➕ Speed Switching
🚫 SGB Functions
    🚫 SGB Commands
    🚫 Border Display

Features

Blargg Rom Tests:
    ✔ cpu_instrs
    ✔ halt_bug

Gekkio's Acceptance Tests:
    ➕ bits
        ✔ mem_oam.gb
        ✔ reg_f.gb
        🚫 unused_hwio-GS.gb
    ✔ instr
        ✔ daa.gb
    🚫 interrupts
        🚫 ie_push.gb
    ➕ oam_dma
        ✔ basic.gb
        🚫 reg_read.gb
        🚫 sources-dmgABCmgbS.gb
    ➕ ppu
        🚫 hblank_ly_scx_timing-GS.gb
        ✔ intr_1_2_timing-GS.gb
        ✔ intr_2_0_timing.gb
        ➕ intr_2_mode0_timing.gb
        🚫 intr_2_mode0_timing_sprites.gb
        ➕ intr_2_mode3_timing.gb
        ➕ intr_2_oam_ok_timing.gb
        🚫 lcdon_timing-dmgABCmgbS.gb
        🚫 lcdon_write_timing-GS.gb
        🚫 stat_irq_blocking.gb
        ✔ stat_lyc_onoff.gb
        🚫 vblank_stat_intr-GS.gb
    ➕ timer
        ✔ div_write
        🚫 rapid_toggle
        ✔ tim00
        ✔ tim00_div_trigger
        ✔ tim01
        ✔ tim01_div_trigger
        ✔ tim10
        ✔ tim10_div_trigger
        ✔ tim11
        ✔ tim11_div_trigger
        🚫 tima_reload
        🚫 tima_write_reloading
        🚫 tma_write_reloading
    - add_sp_e_timing.gb
    - boot_div2-S.gb
    - boot_div-dmg0.gb
    - boot_div-dmgABCmgb.gb
    - boot_div-S.gb
    - boot_hwio-dmg0.gb
    - boot_hwio-dmgABCmgb.gb
    - boot_hwio-S.gb
    - boot_regs-dmg0.gb
    ✔ boot_regs-dmgABC.gb
    - boot_regs-mgb.gb
    - boot_regs-sgb2.gb
    - boot_regs-sgb.gb
    - call_cc_timing2.gb
    - call_cc_timing.gb
    - call_timing2.gb
    - call_timing.gb
    - di_timing-GS.gb
    - div_timing.gb
    ✔ ei_sequence.gb
    ✔ ei_timing.gb
    ✔ halt_ime0_ei.gb
    🚫 halt_ime0_nointr_timing.gb
    - halt_ime1_timing2-GS.gb
    ✔ halt_ime1_timing.gb
    ✔ if_ie_registers.gb
    - intr_timing.gb
    - jp_cc_timing.gb
    - jp_timing.gb
    - ld_hl_sp_e_timing.gb
    🚫 oam_dma_restart.gb
    🚫 oam_dma_start.gb
    - oam_dma_timing.gb
    - pop_timing.gb
    - push_timing.gb
    - rapid_di_ei.gb
    - ret_cc_timing.gb
    - reti_intr_timing.gb
    - reti_timing.gb
    - ret_timing.gb
    - rst_timing.gb

Compilation

Cmake is used for the build system.
clang is the preferred compiler(as it's my favorite) but msvc and gcc should work as well
ninja is recommended as a generator but any generator will do.

Vcpkg is used as a package manager where possible. You should be able to either use the submodule(make sure to git submodule update --init if so) or integrate an existing install if you prefer. Cmake will attempt to find a vcpkg installation at start or fallback the one in the submodule.

We are also using vcpkg's new "manifest mode" meaning you don't even need to install packages, it will pull dependencies on build(from ./vcpkg.json); meaning in most cases you just need to configure and build everything will be downloaded. OS specific config is below.

Windows

Note that vcpkg will default to x86-32. for 64bit set the env var VCPKG_TARGET_ARCHITECTURE=x64 when building

You'll also need to install wxwidgets for the wx UI. this should be done from the website as the vcpkg is broken(as of writing this).

Visual Studio 2019+ is probably the easiest solution as it contains built in support for cmake but otherwise set the wx root directory when configuring from the command line:

mkdir build
cd build
cmake -DwxWidgets_ROOT_DIR=<dir with include/ and lib/> ..

Executables are located at ./build/src/ui/*/ or ./out/<arch>/configuration/src/ui/*/ for Visual Studio.

Linux

For the wx UI, install wxwidgets through your package manager. Less than v3 is not supported(and probably broken).

Compile the normal CMake way:

mkdir -p build
cd build

#Make
cmake ..
make

#Ninja
cmake .. -GNinja
cmake --build .

note that you may need to specify your preferred wx-config:

WX_CONFIG=$(which wx-config-gtk3) cmake ..

Executables are located at ./build/src/ui/*/

macOS

Not tested, should work? Follow linux directions.

Questions

Who?

Me

What?

I'm writing a gameboy emulator.

Where?

Here.

When?

In my very limited freetime.

Why?

Because I've always wanted too.

How?

Mostly the Gameboy Programming Manual, and the gbdev wiki.