Skip to content

Add Nintendo DS port (Embedded Swift)#2

Merged
colemancda merged 1 commit into
masterfrom
feature/nds
Jul 13, 2026
Merged

Add Nintendo DS port (Embedded Swift)#2
colemancda merged 1 commit into
masterfrom
feature/nds

Conversation

@colemancda

Copy link
Copy Markdown
Member

Overview

Adds ports/NDS: a Nintendo DS homebrew port of ClassicUI built with Embedded Swift, modeled on MillerTechnologyPeru/swift-embedded-nds and junkbot-swift's ports/NDS — a Makefile-driven build targeting armv5te-none-none-eabi (an exact match for the DS's ARM946E-S), linked against calico-based libnds and packaged with ndstool using calico's prebuilt ARM7.

Both screens are 256×192: the bottom (touch) screen hosts the iPod UI through a software rasterizer drawn into a double-buffered 16bpp bitmap background (map-base flip, vblank-synced); the top screen shows a static controls banner in a second bitmap background.

Design

Same engine/port split as ports/3DS (#1): the desktop SwiftUI-subset core cannot compile under Embedded Swift (no Mirror, no any View existentials, no Foundation, no Observation), so the port uses the embedded mini-core — source/ClassicCore.swift and tools/gen_font.py are byte-identical to the 3DS port's, and source/Renderer.swift differs only in:

  • screen size: 256×192 (7 visible menu rows instead of 9, same metrics)
  • pixel format: ARGB1555 (red in the low bits, bit 15 = opaque) instead of RGB565
  • present path: halfword copy into the bitmap background's VRAM instead of the 3DS's transposing shim

Everything else carries over: menus with selection restore and scroll windowing, settings value rows, Notes-style wrapped text pages, Now Playing with a live progress bar, the eased navigation slide with pinned status bar, and antialiased 8-bit-coverage text from the same build-time Helvetica rasterization.

common/shim.c carries the ARMv5TE runtime support the Embedded Swift object needs: posix_memalign, arc4random_buf, the _swift_stdlib_strto*_clocale wrappers, and the __atomic_* outline helpers (the ARM946E-S has no atomic instructions; a short IRQ lock makes each operation atomic with respect to interrupt handlers).

Once this and #1 both land, the shared embedded mini-core is a candidate for extraction into a common ports/ location.

Controls

Input Action
D-pad up/down rotate the click wheel
A center button (select)
B Menu (back), with the slide animation
X / Y play/pause
L / R previous / next track
START exit

Building

export DEVKITPRO=/opt/devkitpro
export DEVKITARM=$DEVKITPRO/devkitARM
cd ports/NDS && make SWIFTC=/path/to/nightly/swiftc

Requires devkitPro with nds-dev, a Swift toolchain whose Embedded stdlib ships an armv5te-none-none-eabi slice (main-branch nightly snapshots; release toolchains only ship armv4t), and python3 with Pillow. Verified: builds a 175 KB ClassicUI.nds.

CI / Testing

  • A Nintendo DS workflow builds the ROM on every push (devkitPro pacman + nightly Swift toolchain resolved at run time) and uploads ClassicUI.nds as an artifact — green, alongside the existing macOS/Linux jobs.
  • Host-side snapshot renders of the 256×192 screens (main menu, Now Playing, song list) pixel-verified through the ARGB1555 path before the console build.
  • Not yet run on hardware or in an emulator.

Build system modeled on MillerTechnologyPeru/swift-embedded-nds and
junkbot-swift's ports/NDS: the port compiles whole-module for
armv5te-none-none-eabi (the DS's ARM946E-S; needs a nightly toolchain's
Embedded stdlib slice -- release toolchains only ship armv4t), links
against calico-based libnds, and packages with ndstool using calico's
prebuilt ARM7.

Both screens are 256x192: the bottom (touch) screen hosts the iPod UI
through the shared software rasterizer, drawn into a double-buffered
16bpp ARGB1555 bitmap background (map-base flip); the top screen shows
a static controls banner. The embedded mini-core (ClassicCore.swift)
is identical to ports/3DS's; Renderer.swift differs only in screen
size, pixel format (ARGB1555, red in the low bits), and present path.
common/shim.c carries the ARMv5TE runtime support: posix_memalign,
arc4random_buf, the _swift_stdlib_strto* wrappers, and the __atomic_*
outline helpers (no atomic instructions on the ARM946E-S).

Controls: D-pad up/down = click wheel, A = select, B = Menu (back),
X/Y = play/pause, L/R = previous/next track, START = exit. A CI
workflow builds and uploads the .nds on every push.
@colemancda
colemancda merged commit 4cff215 into master Jul 13, 2026
3 checks passed
@colemancda
colemancda deleted the feature/nds branch July 13, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant