Skip to content

Commit bd08305

Browse files
committed
Initial release commit
1 parent c545eae commit bd08305

18 files changed

+2230
-2
lines changed

README.md

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,104 @@
1-
# varaboy
2-
A Game Boy emulator written in tal
1+
# Varaboy
2+
3+
Varaboy is a Game Boy emulator written in uxntal for the Varvara system.
4+
5+
## Special Thanks
6+
7+
- Devine Lu Linvega (and collaborators) for [uxn](https://100r.co/site/uxn.html) and [Varvara](https://wiki.xxiivv.com/site/varvara.html), the reason this exists at all
8+
- Andrew Richards for [uxn32](https://github.com/randrew/uxn32), without which debugging this would have been a nightmare
9+
- Calindro for [Emulicious](https://emulicious.net/) and all his guidance on this silly project
10+
- binji for his writeup on [POKEGB](https://binji.github.io/posts/pokegb/), and the emulator code itself
11+
- Everyone that's contributed to the [Pandocs](https://gbdev.io/pandocs/)
12+
- Nintendo for making the Game Boy, which has consumed far too much of my life
13+
14+
## Features
15+
16+
- ROM/MBC1/MBC3/MBC5 games (only basic ROM/RAM banking support, extended bank bits not handled, no RTC for MBC3)
17+
- Variable frameskip (default: 3), adjustable with number keys 0-9
18+
- .theme file support
19+
- No sound support
20+
21+
## Stability
22+
23+
Note that due to the incomplete MBC implementations and SRAM not being repacked unless you quit with the escape key I **strongly discourage** playing any game seriously with this emulator at this time. Games will almost certainly break, and save files will almost certainly be lost/corrupted.
24+
25+
## Usage
26+
27+
This emulator requires a [UXN emulator](https://100r.co/site/uxn.html) to run. The name of the Game Boy ROM to run is provided on the command line, for example:
28+
29+
```
30+
uxnemu varaboy.rom tetris.gb
31+
```
32+
33+
Note: Since [uxngb](https://github.com/tbsp/uxngb) (my UXN VM written for Game Boy) only supports up to 8KiB UXN ROMs, it's not possible to run this Game Boy emulator inside uxngb. It is entirely possible to run UXN ROMs 8KiB or smaller inside uxngb inside varaboy though!
34+
35+
## Screenshots
36+
37+
![cpu_instrs](https://user-images.githubusercontent.com/10489588/206598200-41defefa-eca2-4bd9-82ec-38a91720051f.png)
38+
![dmg_acid2](https://user-images.githubusercontent.com/10489588/206787383-e8560e41-8bd5-411e-a122-65590a3451d3.png)
39+
![sml](https://user-images.githubusercontent.com/10489588/206598205-648f7803-ef93-48bf-941c-fd6364377f26.png)
40+
![tetris](https://user-images.githubusercontent.com/10489588/206598212-73f4ea28-b395-48c3-8b4e-1f3fa53ce066.png)
41+
![megaman](https://user-images.githubusercontent.com/10489588/206598220-17d24d65-aad9-40ff-99aa-296304af2537.png)
42+
![sml2](https://user-images.githubusercontent.com/10489588/206598226-99623113-ee35-4cfb-9c0d-18776744a003.png)
43+
![megaman5](https://user-images.githubusercontent.com/10489588/206598232-b11c6275-c0e3-44f0-872e-68553066a54c.png)
44+
![ffl3](https://user-images.githubusercontent.com/10489588/206787415-c6e668c9-e108-400f-b57e-59eb941aa9f0.png)
45+
![shocklobster](https://user-images.githubusercontent.com/10489588/206598263-3e502dc6-36a7-42fd-a832-41fba7d70fa4.png)
46+
![fruitpursuit](https://user-images.githubusercontent.com/10489588/206598268-7ce553ee-7a00-46e8-a54f-bbced9f2336c.png)
47+
![deathplanet](https://user-images.githubusercontent.com/10489588/206598279-2072e63b-05da-40fb-a9f0-cc11933b387c.png)
48+
![uxn_screen](https://user-images.githubusercontent.com/10489588/206768329-aad8e609-1f79-458d-9824-f29eb0f9bdbe.png)
49+
50+
## Compatibility
51+
52+
Note that unless otherwise noted, only a few minutes of testing per game was performed.
53+
54+
| Game | Notes |
55+
| --- | --- |
56+
| Tetris | Playable |
57+
| Super Mario Land | Playable |
58+
| The Legend of Zelda: Link's Awakening | Playable |
59+
| Mega Man: Dr. Wily's Revenge | Payable |
60+
| Mega Man V | Playable |
61+
| Mario's Picross | Playable |
62+
| Final Fantasy Legend III | Playable |
63+
| Wario Land II | Playable |
64+
| Super Mario Land 2: Six Golden Coins | Map corrupt, levels playable |
65+
| Donkey Kong | Freezes after first level, visual glitches in cutscenes |
66+
| Dr. Mario | Freezes when you try to start the game |
67+
| [Shock Lobster](https://tbsp.itch.io/shock-lobster) (Homebrew) | Playable |
68+
| [Fruit Pursuit Beta](https://tbsp.itch.io/fruit-pursuit) (Homebrew) | Playable |
69+
| Adjustris (Homebrew) | Playable |
70+
| [uxngb](https://github.com/tbsp/uxngb) (Homebrew) | Playable |
71+
| [Death Planet](https://makrill.itch.io/death-planet) (Homebrew) | Playable |
72+
| [Libbet](https://github.com/pinobatch/libbet) (Homebrew) | Playable |
73+
| [Geometrix](https://github.com/AntonioND/geometrix) (Homebrew) | Playable |
74+
| [Sam Mallard](https://snorpung.itch.io/sam-mallard-gb) (Homebrew) | Hangs on startup |
75+
| [Quartet](https://makrill.itch.io/quartet) (Homebrew) | Works, but RNG is broken |
76+
77+
## How it works
78+
79+
Both the Game Boy and UXN use a 16bit address space ($0000-$ffff). The Game Boy has a large region of "echo RAM" from $e000 to $fdff, which mirrors the contents of WRAM (c000~ddff) and was considered off-limits for Game Boy software by Nintendo.
80+
81+
Varaboy starts at the UXN entry point ($0100, the same as the Game Boy entry point), sets up some basic stuff, reads the GB ROM header to load the appropriate MBC handler code, and then jumps to the main runtime code inside echo RAM. As long as we can fit all UXN runtime code inside echo RAM the Game Boy code is able to access the rest of memory using native addresses, which I find super fun!
82+
83+
Note that this means we don't have access to the UXN zero page, which contains the Game Boy RST and interrupt vectors.
84+
85+
## Performance
86+
87+
This emulator is *very slow*. On a Ryzen 5600X running in [uxnemu](https://sr.ht/~rabbits/uxn/) some games could almost be considered playable with a frameskip setting of 3 or so. Performance in [uxn32](https://github.com/randrew/uxn32) is much worse, making it very hard to get inputs to register at all (perhaps due to differences in how vectors are handled). A i5-540M with a frameskip of 9 isn't close to playable. Performance on the Nintendo DS UXN VM is even worse, which isn't surprising.
88+
89+
I've sped up instruction dispatch by using jump tables, which in certain cases "wastes" as much as 126 bytes for the ~64 "ld r8,r8" instructions, but overall I believe the performance gain is worth it. I've also tried to pre-calculate as much as possible in the PPU scanline renderer to reduce redundant calculations as I'm not considering mid-scanline register writes. Background/window tiles are cached for reuse for up to 8 pixels, which provides a slight performance gain, though the presence of that code also slows things down a bit, so the net gain isn't huge. In addition, several common operations (ticks, reads, etc) have been converted to macros for speed over size, though the gains are minor.
90+
91+
Save files are unpacked into a file per bank on startup for faster access during SRAM banking. The individual bank files are repacked on shutdown if you quit by pressing the Escape key. Quitting by closing the VM any other way will not properly write SRAM contents back to the SAV file. Without file seeking, games which use lots of ROM banks (and bank often) could also suffer a notable performance hit which could be reduced by unpacking ROM banks in a similar manner.
92+
93+
The only "big" idea I have to speed things up right now is:
94+
- Write 8 full rows of pixels to a buffer of 20 2bpp UXN tiles and draw them to screen with two .Screen/sprite (auto) writes instead of 1280 .Screen/pixel writes. It's unclear if the extra VM instructions to juggle the buffering would be worth the reduction in .Screen calls though, and the benefits may vary by VM implementation.
95+
96+
In addition, I'm still very new at writing uxntal, so there are likely a whole bunch of smart optimizations which could be done to speed things up. Anything that could speed up the main CPU and PPU loops would likely yield huge speed benefits.
97+
98+
## Accuracy
99+
100+
- Passes [blargg's cpu_instrs tests](https://github.com/retrio/gb-test-roms)
101+
- Fails [blargg's instr_timing test](https://github.com/retrio/gb-test-roms), possibly due to a flawed timer implementation which mis-measures instruction timing
102+
- Passes most of Matt Currie's [dmg-acid2](https://github.com/mattcurrie/dmg-acid2), except for sprite x priority and 10 spr/line limit (which are not implemented)
103+
- Fails most other test ROMs
104+
- Still manages to run a surprising number of commercial/homebrew games, despite the above!

screenshots/cpu_instrs.png

1.3 KB
Loading

screenshots/deathplanet.png

3.51 KB
Loading

screenshots/dmg_acid2.png

1.49 KB
Loading

screenshots/ffl3.png

3.23 KB
Loading

screenshots/fruitpursuit.png

4.57 KB
Loading

screenshots/megaman.png

3.34 KB
Loading

screenshots/megaman5.png

3.21 KB
Loading

screenshots/shocklobster.png

3.96 KB
Loading

screenshots/sml.png

1.82 KB
Loading

0 commit comments

Comments
 (0)