G
YouTube TikTok Games
Skip to content
devgyurakPublic

About

A dual-screen handheld emulator that runs inside your terminal. Written from scratch in Rust. No BIOS needed. Ghostty & kitty.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ninge

A terminal-native dual-screen handheld emulator, written from scratch in Rust

CI License: Apache-2.0 Rust 1.99.1 Terminals: Ghostty · kitty Last commit

Status · Install · Run · Documentation · Contributing · Korean

ninge (said "ninji"; a twist on hinge, the joint between two screens) emulates a Nintendo DS–compatible handheld inside the terminal. Both screens are drawn with the kitty graphics protocol, so it runs in Ghostty and kitty only. The core is our own, with no code from another emulator, and it boots without any BIOS or firmware dump.

Status

ninge is early. Work follows the phases in docs/PLAN.md; the current one is in docs/STATUS.md.

Works today Not yet
Both CPUs (ARMv5TE and ARMv4T) on a deterministic event scheduler The bottom screen (2D engine B)
Shared work RAM, video RAM bank A, IPC, interrupts, timers, DMA Input: the keypad always reads "nothing pressed"
HLE BIOS calls and direct boot: no dump needed Touch screen, cartridge reads and its file system
Text backgrounds on the top screen Sprites, 3D and sound
A homebrew program's console output on the top screen The real-time clock (reads 0)

The limits of each release are in docs/release-notes/.

Install

ninge needs Rust (the version pinned in rust-toolchain.toml is the one CI uses). From crates.io, from version 0.1.0 on:

cargo install ninge

From a clone of this repository:

cargo install --locked --path crates/frontend

macOS (Apple Silicon first) and Linux are supported; Windows is planned.

Run

Open Ghostty or kitty, then:

ninge path/to/program.nds   # run a ROM
ninge                       # no ROM: show a test pattern

Quit with q, Esc or Ctrl-C. ninge runs programs you have the right to run, such as homebrew you built yourself; it ships no ROMs and never needs a BIOS or firmware file.

Build and test

./scripts/verify.sh            # the whole gate: config checks, fmt, clippy, tests, 90% coverage
./scripts/build_testroms.sh    # build our own test ROMs into testroms/build/ (needs Docker)

The test ROMs are bare-metal programs in testroms/, built with the BlocksDS SDK from a Docker image pinned by digest, so verify.sh needs Docker. ninge-runner runs a ROM headlessly and prints a hash of each screen:

cargo run -p ninge-runner -- testroms/build/smoke.nds --frames 3
# frames=3 top=<hash> bottom=<hash>

Branches and releases

develop and main only change through pull requests, and CI must be green:

<prefix>/<summary>  ──PR──▶  develop  ──release PR──▶  main  ──tag vX.Y.Z──▶  crates.io

A branch off develop is merged by a PR whose title starts with a prefix (ADD:, FIX:, REF:, DEL:, DOCS:, UPT:). A release is a PR from develop into main that bumps the version, followed by a vX.Y.Z tag on main. The tag runs release.yml, which publishes ninge-core and ninge to crates.io after the maintainer approves it, and creates the GitHub Release with the notes from docs/release-notes/. ninge-runner and ninge-tracediff are repository tools and are not published.

Clean room

  • No commercial ROM, save, BIOS or firmware dump, or anything extracted from one, is in this repository — not even our own built test ROMs. Tests use only programs built from testroms/.
  • Hardware behavior is implemented from notes written in our own words in docs/hw/, mainly from GBATEK. Uncertain behavior is marked unverified, not guessed.
  • No code from another emulator is copied or translated. A reference emulator's release binary is used only as a black-box oracle.

The full rules are in AGENTS.md §3.

Repository layout

crates/core/       ninge-core       the emulator: pure logic, no IO
crates/frontend/   ninge            the TUI and the `ninge` binary
crates/runner/     ninge-runner     headless runner: tests, traces, golden frames
crates/tracediff/  ninge-tracediff  trace comparison against a reference emulator
testroms/          our own bare-metal test ROM sources
tests/             integration tests, golden-frame hashes
docs/hw/           hardware notes in our own words
docs/              the plan, the current status, release notes, the logo
scripts/           verify.sh, test-ROM build, agent hooks
AGENTS.md          project conventions for every coding agent and contributor

Documentation

Document What is in it
docs/PLAN.md (Korean) Goals, architecture, the phased roadmap (§5), references (§9)
docs/STATUS.md The current phase, each phase's done-when, settled decisions
docs/release-notes/ What each release can and cannot do
docs/hw/ Hardware notes in our own words: the clean-room boundary
AGENTS.md Architecture rules (§2), clean room (§3), tests (§5)
testroms/README.md Each test ROM and what it checks
tests/golden/README.md How golden-frame hashes are made and when they may change
Issues labeled decision Design decisions with their context and alternatives

Contributing

Read AGENTS.md first: it holds the architecture rules, the clean-room rules and the test conventions, and ./scripts/verify.sh must pass before a pull request. Pull requests go to develop.

License

Apache License 2.0.

About

A dual-screen handheld emulator that runs inside your terminal. Written from scratch in Rust. No BIOS needed. Ghostty & kitty.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages