aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: 2b19c652f3c9e4f206beb3c370b03421ebff9176 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# gbc — a Game Boy Color emulator in C, rendered to the terminal

A from-scratch Game Boy / Game Boy Color emulator written in plain C11. It
renders graphics directly to the terminal using 24-bit (truecolor) ANSI escape
codes and the Unicode upper-half-block trick (`▀`): each character cell packs
two vertical pixels (foreground = top pixel, background = bottom pixel),
giving a 160×144 GB screen in 160×72 terminal cells.

## Build & run

```sh
make
./build/gbc path/to/rom.gb        # interactive
./build/gbc rom.gb --test 30      # headless: run 30s, log serial (test roms)
./build/gbc rom.gb --shot 60 out.ppm   # run 60 frames, dump a PPM screenshot
```

Requires a truecolor-capable terminal (`COLORTERM=truecolor`) at least
160 columns wide.

## Controls

| Key            | Button  |
|----------------|---------|
| arrows / WASD  | D-pad   |
| `z` / `j`      | A       |
| `x` / `k`      | B       |
| enter          | Start   |
| space          | Select  |
| `q` / Ctrl-C   | Quit    |

Since terminals don't report key-release, buttons are held for a few frames
after each keypress (relying on the terminal's key-repeat for sustained holds).

## Architecture

| File        | Responsibility                                            |
|-------------|-----------------------------------------------------------|
| `types.h`   | fixed-width integer typedefs                              |
| `cart.c`    | ROM loading, header parsing, MBC1/2/3/5, battery saves    |
| `gb.c`      | system bus / memory map, joypad, OAM-DMA, HDMA/GDMA, reset|
| `cpu.c`     | Sharp SM83 core (full opcode set, cycle-accurate accesses)|
| `timer.c`   | DIV/TIMA/TMA/TAC with falling-edge accuracy               |
| `ppu.c`     | LCD controller, scanline renderer (BG/window/sprites), CGB|
| `render.c`  | terminal truecolor output + raw-mode keyboard input       |
| `main.c`    | argument parsing, frame loop, timing, screenshot/test modes|

## Emulation status

Passing:
- **blargg `cpu_instrs`** — all 11 sub-tests
- **blargg `instr_timing`**
- **blargg `mem_timing`** — all 3
- **dmg-acid2** — PPU test renders correctly
- **cgb-acid2** — CGB PPU test renders correctly

Implemented:
- Full SM83 CPU incl. HALT bug, EI delay, interrupt dispatch
- Accurate timer edge behavior
- PPU modes 0–3, STAT/LYC/VBlank interrupts, window line counter
- CGB: double VRAM banks, BG/OBJ color palettes, tile attributes,
  master priority, WRAM banking, double-speed (KEY1), HDMA/GDMA
- MBC1/2/3/5 with RAM banking and battery `.sav` files

Not yet implemented:
- APU (audio) — registers are stubbed
- MBC3 RTC advancement
- Sub-instruction PPU FIFO timing edge cases

## License

For educational use. Test ROMs are downloaded separately and not included.