-
Notifications
You must be signed in to change notification settings - Fork 0
Project Status and roadmap
This page owns: where the project actually is, and what is next. It is the page expected to change most often — check the date before trusting it.
Last updated: 17 September 2026.
If this page and the repository disagree, the repository is right.
STORY.md and the draft
pull request are kept current as work
happens; this page is a summary.
Windows NT 4.0 installs completely and reaches its desktop on an emulated Apple Network
Server 500, using a HAL built from this repository's source with clang and lld. The whole chain
runs: firmware → veneer → OSLOADER.EXE → registry → boot drivers → kernel and HAL → text-mode
Setup → GUI-mode Setup → logon → the shell, in graphics mode at 640x480 on the machine's
Cirrus, with keyboard and mouse through the HAL's own Cuda/ADB transport. Setup's own detection
names the parts: computer "Apple Network Server 500/700", display "cirrus compatible display
adapter". Nothing is written to the distribution CD: everything this project adds travels on
a floppy Setup reads as an ordinary support disk, which retired ledger rows 8 and 10 — see
The boot floppy. On 17 September a complete installation was built
from nothing on a fresh disk and cold-booted to its logon screen: text-mode Setup, GUI-mode
Setup through to "Windows NT 4.00 has been installed successfully", and the finished disk
booting on its own. It has never run on real hardware, and workarounds remain in the loop —
including the video resource bypass, which graphics-mode Setup still depends on, and two registry
values that have to be corrected by hand after Setup writes them wrongly.
| The HAL loads and the kernel runs | Microsoft (R) Windows NT (TM) Version 4.0 (Build 1381: Service Pack 1) |
| Its own identity | Setup's hardware menu offers "Apple Network Server 500/700" and installs HALSHINR.DLL as the system's hal.dll — a TXTSETUP.SIF entry of our own, not another machine's HAL borrowed |
| Storage | both Symbios 53C825A controllers found and bound, with adapters, interrupt vectors and real interrupts; disk.sys and fastfat mount volumes |
| Partition tables |
IoReadPartitionTable, IoWritePartitionTable and IoSetPartitionInformation, including the extended-partition chain Setup actually creates |
| Drive letters | one per recognised partition, in NT's order |
| ARC environment |
HalGetEnvironmentVariable / HalSetEnvironmentVariable, with SYSTEMPARTITION seeded from the loader's own disk list |
| Clock | the real time, read from Cuda, so installed files are dated correctly |
| Keyboard | ADB, through a Cuda transport in the HAL |
| Console | the machine's own Cirrus 54M30, driven directly by the HAL — this is what draws the boot text and any blue screen |
| Text-mode Setup | end to end, sixty-one screens, no bugcheck in the run |
| Booting the installed system | through I/O initialisation and on into user mode |
| Graphics-mode Setup | the NT Setup wizard, 640x480 on the Cirrus, copying E:\ppc\… to D:\WINNT\system32\… — win32k.sys, cirrus.sys and cirrus.dll all live |
| A clean install | every cluster chain covers its file, and all seven registry hives are complete |
Graphics-mode Setup runs, but it runs on top of a workaround. cirrus.sys claims the legacy VGA
aperture at 0xA0000 as system-physical memory — reasonable on a PC, meaningless here, because
the PCI bridge does not forward CPU accesses to it and on this machine that address is ordinary
RAM. NT's conflict scan rejects the claim, \Device\Video0 is never created, and without
intervention Setup stops with "a fatal error while initializing your computer's video"
(0xC0000034).
Today that check is defeated — a one-word patch to VIDEOPRT.SYS on the installed image, which
is ledger row 6 and the one patch in the loop that is not
defensible as a fix. Retiring it is the next real piece of work.
Two approaches are now ruled out by measurement rather than argument. The HAL cannot reserve the
aperture out of the loader's memory descriptors: it sits inside a loaded image under both
loaders — type 9 LoaderSystemCode under SETUPLDR, type 11 LoaderBootDriver under OSLOADER —
because both allocate from low memory. And nothing in the registry asks the miniport to stop
claiming it. The remaining lever is the veneer, which is where the memory descriptors come
from: firmware declaring a hole at 0xA0000..0xBFFFF would make the conflict scan pass on its
merits instead of being defeated, which is what a PC firmware does for that aperture.
→ The NT video stack
The keyboard currently uses a driver borrowed from another project — a binary this project may run but must never redistribute, because it is GPL-2.0 with no published source. Replacing it with our own port driver is outstanding; the HAL half of the interface already exists.
Nothing has been tried on a real machine, and several things in the current setup exist only because it runs under an emulator. → What is known and unknown
Untried. A 7500/8500/9500 has no ARC firmware of its own, so booting NT on one needs a loader as well as a HAL. → Desktop 7500/8500/9500
17 September 2026 — the BitBLT engine. GUI-mode Setup drew almost nothing because
cirrus.dll hands its fills to the GD5430's blitter through memory-mapped registers in the
legacy VGA window, and the emulated part had neither. Both are modelled now; the engine-drawn
wizard differs from a CPU-drawn reference in 0 of 307,200 pixels.
→ The NT video stack
17 September 2026 — NT's restart works. HalReturnToFirmware was a stub that spun, so
"Press ENTER to restart your computer" never restarted anything. It now sends Cuda a RESET
SYSTEM command, the same path Open Firmware's reset-all takes.
15 September 2026 — the boot floppy. Ledger rows 8 and 10 retired; a stock CD from here on.
Worth recording, because it explains why the project moved when it did.
Wall 51 — the display driver NT tried first. With a clean install the boot reached win32k
and stopped on "the required system file DISPLAY_DRIVER.DLL is bad or missing" — a placeholder
name that appears nowhere in the hive. Nothing was missing. Setup had written the x86-oriented
default InstalledDisplayDrivers = 'vga | cirrus | vga256 | vga64K', so NT reached for vga.dll
first and gave up. Reordering to cirrus | framebuf | vga — the driver matched to the miniport,
then the generic linear-framebuffer driver RISC NT normally uses — started the graphical
installer.
→ The NT video stack
Wall 50 — one file's data inside the file allocation table. Every install had been quietly
damaged since the first one: 70 to 98 files with a cluster chain shorter than their recorded
size. It was not an incomplete capture and not cache coherency, though both theories
fitted and both were tried. IoMapTransfer tested page contiguity at index run >> 12 instead
of (run + inpage) >> 12, so for any buffer not starting on a page boundary it compared a page
with itself, passed, and handed the SCSI chip a "contiguous" run spanning pages that were not.
Everything past the first page boundary landed on the neighbouring physical page — which is how
blocks of NOTEPAD.EXE ended up inside NT's cached FAT page and from there on disk. Found by
making the emulator log the host address of every bus-master transfer, not by reading the code.
→ Capturing the installed image
Wall 49 — the HAL was overwriting four bytes of every caller's stack frame. The project
compiles for SVR4, where 4(r1) is the link-register save slot; NT PowerPC keeps the caller's
saved TOC there. Every HAL export that saved its return address destroyed it, and the caller's
next access to its own globals then read outside its module. It had been live since the first
boot and presented as a page fault in an unrelated Matrox video miniport. Fixing it took eight
instructions per export — and took the installed system from a bugcheck straight through to I/O
initialisation.
→ The NT PowerPC ABI,
docs/2026-09-14-the-toc-slot.md
Ordered by what blocks what, not by ambition.
-
Retire ledger row 6 properly, rather than patching past it. The loader's memory
descriptors are ruled out — the aperture sits inside a loaded image under both loaders — so
the lever is the veneer, declaring
0xA0000..0xBFFFFa firmware hole so the conflict scan passes on its merits. Graphics-mode Setup depends on this workaround today. - Drive graphics-mode Setup to the end, which needs a mouse as well as a keyboard, and will say what the rest of the second stage wants.
- Look at the rendering. The desktop background draws noisily; nobody has yet established whether that is the display driver, the emulated Cirrus, or the mode being set.
- Replace the borrowed keyboard driver with our own.
- Reduce the veneer patch set, ideally to nothing, by replacing or upstreaming.
- An ARC environment that survives a reboot. Without one, booting an installed system needs values injected from outside — the largest remaining piece of scaffolding.
- Real hardware, when someone with a machine and a serial cable is willing.
- A desktop TNT, which needs a loader as well as a HAL.
git -C powermac-nt-hal log --oneline -5and read the top of
STORY.md. The last wall
described there is the real edge of the work. The
draft pull request is maintained as a
running status report and is usually the most current prose of all.
Corrections welcome — this wiki is edited directly, so nothing here has had a review. Repository · STORY.md · GPL-2.0-only
Start here
Theory
- Why NT on a Power Mac is hard
- Open Firmware
- ARC
- The veneer
- The NT boot chain
- The HAL contract
- The NT PowerPC ABI
- Little-endian PowerPC
- How Setup chooses a HAL
- The NT video stack
Machines
Emulator
- Getting Granny Smith
- Media you must supply
- Building the HAL
- The boot floppy
- Preparing disks
- Running text-mode Setup
- Capturing the installed image
- Booting the installed system
- Iterating on the HAL
- Checkpoints and deltas
- Making an OEM CD (retired)
Real hardware
Debugging
- The emulator shell
- Reading NT binaries
- Decoding a bugcheck
- When your instrumentation lies
- Debugging recipes
Reference
- HAL exports
- ARC environment variables
- The veneer's VrDebug bitmask
- Veneer patch catalogue
- Address and interrupt map
- Error codes seen
Project