Because it's not quite gold!
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).
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.
✔ = 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
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
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.
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.
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/*/
Not tested, should work? Follow linux directions.
Me
I'm writing a gameboy emulator.
Here.
In my very limited freetime.
Because I've always wanted too.
Mostly the Gameboy Programming Manual, and the gbdev wiki.