Cytrus Software Cytrus Software

PowerEmu banner hero artwork · 1688 × 844
Fresh from the grove

PowerEmu

PowerEmu hero hero artwork · 1688 × 723
Alpha 0.3 · Apple silicon · Tested on Tiger
A Tiger desktop with a Finder window and the Dock, running under PowerEmu
Tiger, running on an Apple silicon Mac.

The graphics card is the whole point

Most emulators hand the guest a fake framebuffer and leave Mac OS X to draw every pixel on the CPU. That is why windows crawl and games refuse to start. PowerEmu emulates an ATI Radeon 9000 instead, and routes its 3D through Metal on your real GPU.

Tiger loads its own ATI drivers, finds what it thinks is a real card, and switches Quartz Extreme on. OpenGL works. Warcraft III runs at around 30 fps, all settings high, at 1680×1050.

A clean Tiger desktop running in a window on a modern Mac
Display modes shaped like your own screen.

A desktop that behaves

Windows move the way they did on the hardware, with the transparency and glow that Quartz Extreme brings. The emulated card reports display modes matched to your actual panel rather than a menu of 1998 resolutions, so full screen really is full screen — including the strip beside the notch.

Clipboard sharing between the guest and the host Mac
Copy in one, paste in the other.

It talks to the Mac it runs on

A small agent inside the guest carries the clipboard both ways, mounts folders you share from the host, and keeps Tiger’s clock in step instead of letting it drift off by hours. Shut Down asks Mac OS X politely rather than pulling the virtual plug.

The PowerEmu Tools installer running inside the guest
PowerEmu Tools, installed in the guest.

The old system gets back online

Tiger’s own Mail app cannot do the TLS that iCloud and Gmail now require. PowerEmu signs in on its behalf and relays the mail, so the app works again with an app password.

A web accelerator does the same trick for pages: your modern Mac handles the handshakes and re-encodes the heavy images, and the old system gets something it can cope with.

The Applications folder in Tiger, showing Safari, iTunes, Mail and iCal
Classic runs inside Tiger, inside the emulator.

Classic, and everything before it

Mac OS 9 runs inside Tiger inside the emulator, which means software from before Mac OS X runs too. Yes, it is turtles.

Tiger running full screen, its Finder windows naming the machine a Power Mac G4
One of several machines you can keep.

A shelf full of Macs

Keep as many virtual Macs as you like, each with its own disks and settings, and hand them CDs, DVDs, disc images and USB devices from the machine they run on. A performance overlay shows frame rate, draw calls and VRAM — and what the host is doing, so a slow moment reads as “something else took the CPU” rather than as a mystery.

PowerEmu is built on QEMU, which already knows how to pretend to be a Power Mac. On its own, though, it stops a long way short of usable. Here’s what changed.

Plain QEMUPowerEmu
A dumb framebuffer. Mac OS X draws every window itself, on the CPU. An emulated Radeon 9000 that Tiger’s own ATI drivers bind to, unmodified.
No 3D at all, so games and screen savers either crawl or refuse to launch. 3D commands go to Metal on your real GPU. Warcraft III runs around 30 fps on high.
Quartz Extreme stays off, because Tiger looks for a real card and doesn’t find one. It finds one. The compositor turns on and windows move like they should.
The pointer smears trails across OpenGL windows. The host draws the cursor, so it stays clean.
A short list of old resolutions, none of them the shape of a modern display. Modes that match your panel, plus true full screen including the notch.
Audio crackles and cuts out constantly. Paced in real time, which fixed the dropouts. Some distortion is still being chased.
Plug in a USB device at the wrong moment and the whole thing wedges. The USB controller drops missed frames instead of livelocking. It keeps going.
Click another window and macOS quietly parks it on the efficiency cores. It tells macOS it’s busy, so it keeps running at full tilt in the background.
Stock settings that suit PowerPC code badly, so everything is slower than it needs to be. Retuned emulation internals. One guest benchmark went from 9–11 seconds to about 2.
No link to the host: no clipboard, no shared folders, no clock sync. All three, plus a real Shut Down instead of yanking the virtual power cable.
A second Dock icon and no way to manage more than one machine. One app, one icon, and a library of VMs with their own disks and settings.
Your Mac
An Apple silicon Mac. The renderer is Metal, so this is not optional
macOS
macOS 14 Sonoma or later — what the app is built against
Memory
Whatever you give the virtual Mac, 2 GB by default, on top of your own
Storage
Room for a guest disk. A working Tiger install runs to tens of gigabytes once you fill it
Video memory
64, 128 or 256 MB, your choice, inside the virtual Mac
Guest system
Mac OS X 10.4 Tiger, tested. Leopard is untested so far
You supply
A Tiger install disc or an existing disk image, and the ATI ROM images. None of that ships with PowerEmu
Price
Free. GPL-2.0-or-later, like QEMU underneath it

Graphics

  • An emulated ATI Radeon 9000 (RV280/R200) — ppc-mac-gpu, with an MMIO register set, a PM4 command processor and ring buffer, a 2D engine (fills, blits, host data, clipping) and AGP/GART address translation. Mac OS X’s own ATI kexts bind to it unmodified.
  • A Metal renderer for the R200 3D pipeline. Draw packets go straight to Metal: hardware T&L (model-view-projection, lighting, spot lights and attenuation, texture matrices, fog), viewport and scissor, R200 texture combiners, alpha test, blending done in-shader through framebuffer fetch, plane masks, depth and stencil. Textures in ARGB8888, RGBA/ABGR8888, RGB565, ARGB1555, ARGB4444, I8, AI88, DXT1/3/5 and YUV 4:2:2, resident in VRAM or fetched over AGP. It renders into VRAM through linear Metal texture views — no shadow copies.
  • Quartz Extreme. The uni-north host bridge gets an AGP capability and a working GART, so Apple’s AppleMacRiscAGP drives the bus, the Radeon driver builds its AGP GART and reports AccelCaps = 1, and WindowServer switches on the OpenGL compositor.
  • A hardware cursor. A patched QEMU VGA NDRV reports cursor support and hands the image and position to the GPU model, which draws it on the host — fixing the stale save-under that left cursor-shaped notches over OpenGL windows.
  • Host-shaped display modes. The device’s EDID (Established Timings III) and the patched NDRV’s mode table add 1440×932, 1280×828, 1152×746 and 1680×1088, plus below-the-notch variants. Full-panel fullscreen covers the whole display including the notch strip.
  • 64, 128 or 256 MB of VRAM, behind a 1 GB uni-north PCI window.

Sound, input and stability

  • Screamer audio pulls DMA at the sample rate from a 1 ms virtual-clock timer into a 186 ms ring; the position register advances with it and a 40 ms jitter buffer fronts the host backend. A four-second 1 kHz capture went from 10–20 dropouts to zero.
  • Seamless pointer via a USB tablet taking absolute positions; captured mode remains for games.
  • OHCI bounds transfer descriptors per endpoint per frame and drops missed frames rather than replaying them, which used to livelock the emulator under host load.

Speed

  • Host scheduling. An NSActivityUserInitiated | LatencyCritical assertion plus QOS_CLASS_USER_INTERACTIVE on the TCG vCPU threads stops App Nap exiling the emulator to the efficiency cores. A guest benchmark loop dropped from 9–11 s to 3.4 s on that change alone.
  • TCG: a raised softmmu TLB floor (1024 entries) and a 64K-entry TB jump cache retired by a generation counter, so a flush stays O(1) — a game covers 100k+ translation blocks and every PowerPC blr is an indirect branch.
  • target/ppc: lmw/stmw expanded inline instead of a helper that probe_accesses the range, and a host-FPU fast path for A-form arithmetic when FPSCR is RN with no enables and no NaNs.
  • GPU batching: conflicting batches ordered on the GPU with shared events rather than waitUntilCompleted on the vCPU thread, hybrid fences, an AGP/GART page-to-host-pointer cache, and draw vertices bump-allocated from a recycled 8 MB buffer.
  • Net result: benchmark loop 9–11 s → 1.95 s. Warcraft III went from 4–5 fps to around 30 fps on all-high settings at 1680×1050.

The app and the guest

  • SwiftUI app driving QEMU over QMP. VMs are .poweremu packages; importing disks and ROMs uses APFS clones. The guest screen is drawn inside the app through a poweremu-display object over a Unix socket with shared memory and damage rectangles, so QEMU isn’t a second Dock icon.
  • PowerEmu Tools — a guest agent for 10.4+ PPC, installed per user with no administrator password: clipboard both ways, shutdown and restart through loginwindow (kAEShutDown/kAERestart), and an optional root clock daemon that steps errors over 1 s and slews smaller ones with adjtime.
  • Shared folders over a WebDAV server implementing enough of RFC 4918 for Tiger’s webdavfs, on a per-VM Unix socket so no TCP port is opened.
  • Service Hub: a mail proxy (the guest authenticates locally; PowerEmu does implicit TLS or STARTTLS to iCloud, Gmail, Yahoo or Fastmail with an app password) and a Web Accelerator on 10.0.2.100:7780 doing TLS 1.3 and HTTP/2, WebP/AVIF/HEIC transcoding, image downscaling and 204s for trackers.
  • Built on QEMU 10.0.2 as patched by UTM. GPL-2.0-or-later.

Alpha, and still moving. Tiger is tested; Leopard isn’t yet — if you try it, tell me how it went. Free and GPL, always.

The Garden

The Garden hero hero artwork · 1688 × 723
Alpha 0.3.6 · Mac OS X 10.4 and 10.5 · Universal
The Garden's Featured page, a grid of New and Noteworthy titles with ratings
Featured, with New & Noteworthy from the site’s own feed.

A store, not a directory listing

Thousands of archived Mac programs and games, arranged the way you would expect a store to arrange them: Featured, Apps, Games, Categories and Search. It runs natively on the old Mac, with no modern machine in the loop.

A game's item page, with screenshots, rating and every download listed
Screenshots, ratings and reviews from the site.

Know before you download

Every download carries a badge for the Mac you are sitting at: runs natively, needs Classic, needs Rosetta, or will not run here. Item pages carry screenshots, the rating, and the reviews people have written over the years.

Get is a pull-down — it offers the sensible file, and the menu lists every download with its size and what it would run on, so the choice stays yours.

HyperCard's item page in The Garden
Old formats, unpacked without you thinking about it.

One button does the whole job

Press Get and it downloads the file, checks the MD5, unpacks whatever 1997 archive it is wrapped in — StuffIt, BinHex, MacBinary, Compact Pro, zip — finds the actual application in the heap, and installs it. Software that shipped on five floppies gets mounted and stitched back together.

The Library tab, listing installed titles with their real icons
Everything you have installed, with its real icon.

A library that knows what you have

Open it, drag it to the Dock, show it in the Finder, or throw it out. The Garden works out which file is the program and skips the updaters, installers and read-mes, so double-clicking gets you the game rather than its patcher.

The Updates tab, showing titles with a newer version available
Updates, with the count on the Dock icon.

Updates, noticed and installed

It spots newer versions of what you have and installs them, with the progress staying put until the new copy is really in place. The count shows on the Dock icon, which it draws by hand — Tiger has no Dock tile API.

Search results in The Garden for Photoshop
Search, cached so a second look costs nothing.

Light on a slow machine, and on the site

Pages you have visited stay readable when the network does not cooperate, and The Garden only ever asks for the pages you open — there is no crawl. There is also a report window in the app, which shows you exactly what it is about to send.

You could do all of this by hand in a browser. Here is what The Garden does instead.

Doing it yourselfThe Garden
Tiger’s browser cannot complete a handshake with the site any more, so you need a modern machine just to fetch the file. Bundled TLS, so the old Mac talks to the site directly.
You find out whether something runs by downloading it and trying. A badge on every download, worked out for the Mac you are on.
Unpack a StuffIt archive, work out which of nine files is the program, drag it somewhere sensible. One button: download, verify, unpack, install, in the right place.
Nothing tells you a newer version exists. Updates are spotted and installed, with a count on the Dock icon.
Nothing records what you already have. A library with real icons, and one click to open or remove.
Every page is a fresh download over a slow link. Pages are cached and revalidated, and still readable offline.
Mac
Any PowerPC G3 or later, or any Intel Mac. One universal binary covers both
System
Mac OS X 10.4 Tiger or 10.5 Leopard
Memory
256 MB is fine. It was built with small machines in mind
Storage
Whatever your installs need, plus a little for cached pages
Internet
Any connection. Modern TLS is bundled in, so there’s nothing to configure and no helper Mac required
Plays well with
Mac OS 9 for the oldest titles, and PowerEmu if you’d rather do all this on a modern Mac
Version
0.3.6, alpha
Price
Free. MIT licensed

Reaching the site at all

  • Bundled TLS. Every transfer runs through a statically linked libcurl 8 and OpenSSL 3. Tiger and Leopard’s own TLS stops at 1.0 and can no longer negotiate with the site, so the system stack is bypassed entirely.
  • One thread, one curl multi handle. A thread per request costs too much on a 256 MB G3; a single handle reuses connections, DNS answers and TLS sessions.
  • Persistent page cache with per-request TTLs (item pages 3 days, listings 6 h, the feed 1 h), revalidated with If-None-Match and If-Modified-Since, with offline fallback.
  • PowerEmu Web Accelerator client. Inside a virtual Mac it is found at 10.0.2.100:7780; on a real Mac over Bonjour with a pairing code. Pages and images go through it; downloads, form posts and the search token always go direct, so a file’s MD5 and the session are never in doubt. A Tiger G3 item page: 0.95 s direct, 0.20 s through PowerEmu — the difference is the TLS handshake. Absent, nothing changes.
  • A custom NSURLProtocol puts the system WebKit on the same stack, so a WebView can reach the site on Tiger and shares the app’s cookies.

Store, install and library

  • Featured (New & Noteworthy from rss.xml), Apps and Games A–Z, Categories and Search. Item pages carry screenshots, the rating, reviews parsed from the site’s comments, and rows of More by author and Related.
  • Compatibility badges computed per download against the host: native, Rosetta, Classic, or unsupported.
  • Install pipeline: MD5 verification, disk images via hdiutil, archives through the bundled XADMaster (StuffIt, BinHex, MacBinary, Compact Pro, zip and the rest), applications to /Applications, Mac OS 9 software to Applications (Mac OS 9), packages handed to Installer. Multi-floppy sets, including headerless raw images via CRawDiskImage, are mounted and copied out.
  • Launchable selection prefers the binary whose name matches the title and skips updaters, installers, read-mes and launchers; existing library entries are re-checked at launch.
  • Updates compare version numbers when both file names carry one and upload dates when neither does. The Dock icon is drawn by hand for progress and the badge, since Tiger has no NSDockTile.

Build

  • Universal ppc + i386, deployment target 10.4, built with Apple gcc-4.0 against the 10.4u SDK — Xcode 2.5 on Tiger or 3.1 on Leopard. PowerPC is -mcpu=G3 -mtune=G4; Intel is -march=prescott.
  • MIT licensed. XADMaster and UniversalDetector are the unmodified Universal builds from The Unarchiver 3.11.1, under the LGPL-2.1.

Version 0.3.6, and rough in spots. Not affiliated with the Macintosh Garden — just a fan with a compiler.

Captain Polliwog

Captain Polliwog hero hero artwork · 1688 × 723
Alpha 0.3.4 · Mac OS X 10.4 and 10.5 · PowerPC G3+ / Intel
Captain Polliwog rendering the current apple.com on Mac OS X
apple.com, today, on Mac OS X.

Modern sites actually load

Two things broke the browser your Mac came with. Sites started using encryption it was never taught, and pages started using features it had never heard of. Captain Polliwog replaces both halves: its own modern TLS, and a newer engine.

Wikipedia loaded over HTTPS in Captain Polliwog
Wikipedia, rendered by WebKit 604.

A 2018 engine, rebuilt for PowerPC

It runs WebKit 604 — the engine from Safari 11 — compiled from source for PowerPC, with a JavaScript JIT that JavaScriptCore has never had on this architecture. Flexbox and grid, :has(), modern JavaScript, WebGL and web fonts all work.

On a PowerBook G4 it scores 0.345 on Speedometer 3.1 against PowerFox 26.4’s 0.189, and wins 18 of the 20 suites.

The bookmarks window, with folders
Bookmarks, with Safari’s imported.

Everything a browser ought to have

Tabs that release their pages when memory runs short and reload when you come back. Bookmarks with folders, imported from Safari if you have them. Find on page, printing, saving, and the tab you closed by accident.

The downloads window, showing progress
Downloads you can pause and resume.

Downloads that survive a bad connection

Stop one, come back tomorrow, and it carries on from where it stopped rather than starting again.

Captain Polliwog's preferences
Per-site settings, and a lighter view on request.

Video, handed to something that can decode it

A green button appears over a video you point at. Press it and the video opens in VLC or MPlayer, which can actually decode it on this hardware — and the copy in the page pauses so you are not decoding it twice. Nothing plays until you ask.

A private browsing window
Private browsing, forgotten on close.

Reading, quietly

Reader strips a page back to the article. Private browsing writes nothing down and drops its cookies when the window closes. AutoFill keeps passwords, addresses and cards in your Mac’s own keychain.

Your Mac already has a browser, and there is a well-loved alternative in PowerFox. Here is where Captain Polliwog differs.

The browser your Mac came withCaptain Polliwog
TLS stops at 1.0, so most sites refuse the connection outright. Bundled OpenSSL 3 and libcurl 8. The handshake completes.
An engine from 2010: missing icons, broken layouts, scripts that fail. WebKit 604, from 2018, built from source for PowerPC.
JavaScript runs in an interpreter, because PowerPC never had a JIT. A PowerPC baseline JIT, 1.5–3.5× the interpreter.
Slower than PowerFox on most of Speedometer. 0.345 against PowerFox’s 0.189, winning 18 suites of 20.
Ten tabs and the machine starts swapping. Background tabs release their pages and reload on return.
Video is a still frame and a spinning beachball. Handed to VLC or MPlayer, which can decode it.
IPv6 lookups stall about fifteen seconds on networks without it. Both families tried at once, so the page just starts.
Mac
Any PowerPC G3 or later, or any Intel Mac. One universal binary covers both
System
Mac OS X 10.4 Tiger or 10.5 Leopard
Memory
256 MB will run it — current Wikipedia loads on a 500 MHz G3 in about 53 MB. A gigabyte makes a real difference once you open a few tabs
Storage
Room for the app and its page cache
Internet
Any connection. TLS is built in, so there’s nothing to set up
For video
VLC or MPlayer, if you want to hand videos off to something that can decode them
Plays well with
PowerEmu, if you’d rather browse from a virtual Mac
Version
0.3.4, alpha
Price
Free. MPL 2.0

Networking

  • Its own TLS. Every request goes through a bundled OpenSSL 3.5, libcurl 8.22 and zlib. The system stack stops at TLS 1.0 and cannot reach most sites any more.
  • Plain HTTP goes the same way. Tiger and Leopard try a site’s IPv6 address first and wait about fifteen seconds for it to fail on networks without IPv6; libcurl tries both at once.
  • One thread through a single curl multi handle, browser-level connection limits, and a disk cache that lets a repeat visit skip the network entirely.
  • PowerEmu Web Accelerator client, for when it runs inside a virtual Mac.
  • Current Wikipedia and DuckDuckGo load on a 500 MHz PowerBook G3 with 256 MB of RAM, in about 53 MB of memory.

The engine

  • WebKit 604.5.7 — Safari 11, 2018 — built from source for PowerPC. Cross-compiled on an Apple silicon Mac in a Linux VM with a PowerPC toolchain (about 40 minutes from clean) and packaged as frameworks the browser loads, following Leopard WebKit’s structure. Built through WebKit’s CMake Mac port rather than the Xcode projects Apple used.
  • It has to be a fork. Upstream WebKit removed big-endian support on August 1, 2026 (commit 232cebab), so no future WebKit will ever compile for a PowerPC Mac. This one is frozen on a branch with fixes carried back by hand.

Speed

  • A PowerPC baseline JIT for JavaScriptCore — something it has never had. An offlineasm PowerPC backend runs the LLInt as native code, with a new assembler and macro assembler for the JIT, and the big-endian work that goes with it: EncodedJSValue returned tag-first from C but payload-first from JS, tag-first JSValue arguments, call frame payloads at +4, and byte-reversed loads for typed arrays. 1.5–3.5× the interpreter on micro-benchmarks.
  • Layout that doesn’t redo itself. RenderLayer::updateLayerPositions used to walk every layer in the page after every layout. Each RenderElement now carries a four-bit generation number in spare bitfield room, marked up the ancestor chain by anything that moved and expiring on its own as the view advances the generation; the walk skips subtrees that didn’t change. Checked pixel for pixel against a full re-render via CGWindowListCreateImage. TodoMVC-Svelte-Complex-DOM: 3532 ms → 1277 ms.
  • Speedometer 3.1 on a PowerBook G4: 0.259 → 0.345, against PowerFox 26.4’s 0.189. Eighteen of twenty suites now beat PowerFox; the two left are Charts-chartjs (Core Graphics path rasterization) and TodoMVC-ES5 (relayout boundaries).

What it supports

  • Platform: flexbox and grid with gap, :has(), :focus-visible, unprefixed position: sticky, cascade layers, range media queries, :is()/:where(), logical properties, constructable style sheets; ES2017+ — classes and private members, async/await, generators and async generators, modules and import maps, BigInt; fetch, Web Timing, WebGL through ANGLE, WOFF2 via OTS, and full ICU with all 683 locales.
  • The browser’s own code is under the MPL 2.0.

Version 0.3.4. Still early, rough in places, and improving most weeks.

About

Cytrus Software is one person making small, honest software with a taste for the old ways — hand-built tools in the spirit of the early web. Quiet, durable, and a little bit strange.

No trackers, no newsletters, no upsells. Just software that does a thing and then gets out of the way.

If you want to say hello, you can reach me at adam.cipoletti@me.com.

Support

All three of these are free and open source, and they’ll stay that way. There’s no paid tier, no license key, and nothing here is counting you. Everything below is optional.

Give what you like

$

Venmo carries your note with the payment. PayPal can only carry the amount, so if you’ve written something, send it with Just send the note as well.

Or donate a vintage Mac

All three of these are built against real hardware, and the range I can test on is whatever is on my desk. If you have a PowerPC Mac gathering dust — a G3, G4 or G5, laptop or desktop, working or nearly — it would go straight into testing. I’ll pay the shipping.

Don’t ship anything before we’ve talked — I’ll cover the label and make sure it’s worth the trip first. A heavy tower coming a long way sometimes isn’t, and I’d rather tell you than leave you out of pocket. Machines that don’t boot are still interesting; say so and we’ll figure it out.

No tier buys support or a deadline — this is one person and a compiler. An email telling me you got something working is worth just as much as any of it.