Game Boy emulator library for embedded devices
Go to file
2025-02-22 05:52:38 +01:00
ppu Start rearranging things properly 2023-12-31 03:52:44 +01:00
test Move memory dispatch code separate from the microcode 2025-02-22 05:49:22 +01:00
.gitignore Ignore profiler-generated log files 2024-06-02 01:43:45 +02:00
apu.c Fix missing s/vol/is_on/ replacement 2024-11-23 02:08:51 +01:00
apu.h Try fix most APU bugs at once 2024-11-22 22:03:17 +01:00
config_gba.h Push platform config updates 2023-08-04 19:19:55 +02:00
config_pd.h Push platform config updates 2023-08-04 19:19:55 +02:00
config_rp2.h Push platform config updates 2023-08-04 19:19:55 +02:00
config.h Hack back flat ROM pointer support 2024-06-03 06:05:03 +02:00
dbg.h Initial commit 2023-02-20 16:48:41 +01:00
fabric.c Revert timer hack 2025-02-22 05:52:38 +01:00
fabric.h Add CGB mode switching support 2024-11-23 02:12:03 +01:00
LICENSE.txt Add license, placeholder, README, and make project public 2023-03-05 11:45:58 +01:00
lru.c Hard-to-read code doesn't run any faster 2024-06-02 04:03:20 +02:00
lru.h Prepare for region fitting 2023-03-10 17:33:16 +01:00
mi.c Hard-to-read code doesn't run any faster 2024-06-02 04:03:20 +02:00
mi.h Hack back flat ROM pointer support 2024-06-03 06:05:03 +02:00
microcode_dispatch.c Move memory dispatch code separate from the microcode 2025-02-22 05:49:22 +01:00
microcode_dispatch.h Move memory dispatch code separate from the microcode 2025-02-22 05:49:22 +01:00
microcode.c Move memory dispatch code separate from the microcode 2025-02-22 05:49:22 +01:00
microcode.h Split up cartridge mapper handler code 2024-06-02 21:50:50 +02:00
pgb_main.h Hard-to-read code doesn't run any faster 2024-06-02 04:03:20 +02:00
popcounter.h Update Playdate support 2023-03-18 23:56:10 +01:00
ppu.c Add CGB mode switching support 2024-11-23 02:12:03 +01:00
ppu.h Prepare for region fitting 2023-03-10 17:33:16 +01:00
README.md Clarify known limitations and pitfalls up-front 2024-12-21 06:13:12 +01:00
types.h Split up cartridge mapper handler code 2024-06-02 21:50:50 +02:00

PicoGB

A small emulator libraray, which is capable to play Game Boy games, and a limited amount of Game Boy Color games.

PicoGB is designed to be easy to embed, and run as fast as possible, with the least amount of resource usage as possible.

Embedding

See pgb_main.h for all the available functions to use.

The rest of the code has no dependencies, as it's the job of the embedder to implement callback functions not implemented in fabric.c.

Source code layout

Core:

  • microcode.c - actual CPU implementation, dispatches reads and writes (using a cache where possible)
  • mi.c - Memory Interface, currently only contains cache invalidation functions
  • ppu.c - Picture Processing Unit, contains all code regarding graphics, including scanline rendering, interrupts, and IO register handling
  • apu.c - Audio Processing Unit, contains all code regarding sound rendering, including IO register processing
  • fabric.c - IO register processing, and certain callback functions pre-implemented for Game Boy system

Extensions:

  • profi.c - gcc call stack profiler, used to find and optimize away function calls where inlining makes sense
  • lru.c - Last Recently Used cache, used to implement fast ROM bank cache on low-RAM systems (like the RP2040 port)
  • popcounter.h - line drawing algorithm implemented using a shift register

Executable:

  • test/winmain.c - Windows executable, sound doesn't work in wine (causes a hang due to unsupported sample rate)

Ports

  • Windows - see test/winmain.c
  • RP2040 - not publically released yet (available using VGA or SPI display output, broken audio)
  • Playdate - not publically released yet (available using upscaling or not, audio is inaccurate and crashes sometimes)
  • Game Boy Advanced - under construction

Known limitations

  • Instructions are not M-cycle accurate! Every instruction runs on the first M-cycle.
    Instructions with immediate bytes (mostly affecting a8 and a16 types) execute too early. This also includes $CB opcodes, as they execute in the $CB byte instead.
  • PPU is scanline-based.
    Mid-scanline BGP/SCX/SCY/LCDC changes do not show up.
  • Memory locking is not implemented.
    It's kind of difficult implement with the memory area cache without lots of overhead.
  • Instruction fetch at $FDFE with a16 or n16 immediate type will fetch the high byte of the immediate from out-of-bounds host memory.
    This is by design as an optimization of the logic.
  • CGB double-speed mode is not only broken, but it's also the responsibility of the frontend to implement properly.

License

PicoGB is licensed under the GNU Lesser GPL v2.1, see LICENSE.txt