Stock Microsoft Windows CE 2.11 running on a real Nintendo 64. A custom
HAL drops the unmodified nk.lib kernel onto VR4300, brings up the CE
2.11 GWES desktop and shell, mounts the EverDrive-64 X7's SD card under
\SDCard, treats the N64 controller as a mouse, plays sound through the
N64 AI hardware via the standard CE wave stack, and runs third-party CE
2.11 EXEs straight off the SD card.
This is a hobby reverse-engineering project: there is no official CE 2.11
port to N64 from Microsoft. Everything below the unmodified nk.lib
(HAL, OAL, display driver, FSD, kbd/mouse PDD, wave PDD, RDP-accelerated
GDI fill, ed64-X7 driver) is part of this repo.
Featured in https://www.youtube.com/watch?v=eGS9su_inBY
Boots fully on real N64 + EverDrive-64 X7. Working:
- Desktop, taskbar, file browser; window drag, close-X, modal dialogs
- N64 controller drives a visible cursor; A = left click, B = right click
\SDCard\*mounted via FatFS over X7 cartridge SD- Wave audio through
sndPlaySoundW/waveOutOpen→ N64 AI - Third-party CE 2.11 EXEs launchable from the SD card (e.g.
BeziersCE) - RDP-accelerated 3D demo (
cube3d.exe) rasterising flat-shaded triangles directly through the RDP
The unmodified nk.lib is the trunk: it owns PSL dispatch, scheduling
and TLB. Around it the standard CE 2.11 user-mode modules
(coredll.dll, gwes.exe, filesys.exe, device.exe, shell.exe)
load unchanged from the ROM image. The custom pieces are:
- HAL / OAL (
bsp/hal/) — boot, exception vectors, MIPS startup, timer, USB debug, two LE-mode RDRAM partial-word quirk workarounds. - Display driver (
bsp/drivers/display/) — VI framebuffer + RDP fill acceleration + a software cursor compositor that fills the gap CE 2.11's splitCURSOR.LIB/MCURSOR.LIBleaves on non-overlay hardware. - Mouse / keyboard PDD (
bsp/drivers/kbdmouse/) — SI Joybus poll, decodes both the N64 controller and the official N64 mouse. - SD filesystem (
bsp/drivers/sdfsd/) — FatFS-backed FSD that registers under\SDCard. Replaces libdragon's libcart with a PI-DMA-based EverDrive-X7 driver (edx_x7.c) to dodge a real-HW cart-bus read-after-write quirk that's invisible in emulation. - Wave PDD (
bsp/drivers/wavedev/) — polling-mode AI driver that layers under the stockwaveapi.dll. Polling instead of interrupts becauseMI_INTR_MASK_AIstalls the SysAD bus on real HW. commctrl.dll(bsp/drivers/commctrl/) — a tinyDllMainthat CE 2.11's commctrl.lib forgot to ship, so spinner controls (themsctls_updown32class) actually register.- Shell (
bsp/shell/) — Win9x-style desktop, taskbar, file browser. - RDP 3D library (
bsp/lib/rdp3d/) — minimal triangle rasteriser for user EXEs; used bybsp/apps/cube3d/.
For the long debugging history (cache quirks, TLB walks, GWES bring-up, CE-side wave stack idiosyncrasies, etc.) see the source-level comments in each driver.
This repo deliberately does not ship anything Microsoft- or Nintendo-proprietary. You have to provide the external trees yourself and place them next to this directory (or symlink them in):
| Path | What | Where |
|---|---|---|
wince211_sdk/ |
Microsoft Windows CE 2.11 Platform Builder / Embedded Toolkit | Long out of print, but can be found online. |
libdragon/ |
N64 homebrew toolchain (mips64-elf-gcc, n64.mk) + FatFS sources |
https://github.com/DragonMinded/libdragon — clone and run its install script so $N64_INST points at the toolchain. |
| EverDrive-64 X7 | Cart for actual hardware deployment | https://krikzz.com. Plus a copy of the official EverDrive firmware on the SD card. |
Tooling on the host side:
- Wine — the SDK's
CLMIPS.EXE/LINK.EXE/RC.EXE/ROMIMAGE.EXEall run under Wine. Tested on Linux. - Python 3 with Pillow
mips64-elf-gccfrom libdragon's toolchain (for the bootloader ROM).- libftdi1 if you want to upload over USB to a real X7 — required to
build
diag/ed64_upload.
After placing wince211_sdk/ and libdragon/ next to this directory:
This compiles the HAL + every driver DLL, runs LINK.EXE and
ROMIMAGE.EXE under Wine to produce bsp/build/nk.bin (the stock CE
ROM image), then chains into bootloader/Makefile to wrap it in a
libdragon IPL3 trampoline. Output: bootloader/n64ce.z64 (≈3.5 MB,
loadable directly by an X7).
A typical clean build runs in ~30s on modern hardware; the dominant
cost is Wine cold-start, which the build script amortises by keeping a
single wineserver alive for the whole run.
Build the USB uploader once:
cd diag && make ed64_uploadThen upload + boot:
diag/ed64_upload bootloader/n64ce.z64 # write + boot
diag/ed64_upload --listen bootloader/n64ce.z64 # also stream USB debug--listen keeps the FTDI handle open after the upload so no debug
output is dropped.
Earlier development used Ares with a small local patch for the LE-mode RDRAM partial-word quirk. However that gradually led to this turning into a "let's improve Ares" project rather than just testing on real hardware. Getting this to work on Ares is a deeper rabbit hole that I'm not interested in tackling. Have not tested in any other emulators.
bsp/ N64 BSP: HAL, OAL, drivers, shell, apps, ROM image
hal/ Custom HAL on top of stock nk.lib
drivers/ Display, kbd/mouse, sdfsd (FatFS), wavedev, commctrl
lib/rdp3d/ Triangle rasteriser used by user apps
apps/ cube3d, paint, notez (linked into the ROM)
shell/ Desktop, taskbar, file browser, icons
build.sh The whole build
ce.bib ROMIMAGE build-info file (memory map + module list)
bootloader/ libdragon IPL3 trampoline that loads nk.bin from cart
diag/ Bare-metal diagnostic ROMs (LE-mode quirk tests,
audio test, USB uploader, ed64 reboot)
docs/ Architecture diagram, HW debugging notes, N64 quirks
(external, not in this repo)
libdragon/ → clone of DragonMinded/libdragon
wince211_sdk/ → CE 2.11 SDK from the MS Embedded Toolkit
ed64-x-pub/ → krikzz/ed64-x-pub (reference; not built against)
Why?
Great question! I got the idea from the IBM Workpad Z50, which uses a very similar MIPS CPU as the N64 (VR4121 vs. the N64's VR4300). There's really no practical reason to run Windows on your N64, so this was more of a programming challenge.
Where do I get the prebuilt ROM?
You can't — there isn't one, and I won't be publishing one. Build it
yourself with bash bsp/build.sh. The resulting n64ce.z64 links in
Microsoft's CE 2.11 binaries (nk.exe, coredll.dll, gwes.exe,
filesys.exe, ddi.dll's MGDI / GPE libs, etc.) from the SDK's static
libraries; shipping a finished ROM would mean redistributing those,
which I have no license to do. My own source files in this repo are
MIT — the output of the build is not, and never will be.
Can I just buy a copy of the SDK?
No, not for ~20 years. The Microsoft Windows CE 2.11 Platform Builder (shipped inside the Microsoft Embedded Toolkit for Visual C++ 6.0) was last sold in the very early 2000s and quietly retired around 2004–2005. Microsoft never re-released it, open-sourced it, or replaced it on their download site. The EULA it originally shipped under was a per-developer development license: you could build embedded software with it and ship the resulting binaries inside an embedded device, but you couldn't redistribute the SDK itself or its static libraries on their own. Archived ISOs of the toolkit circulate online; tracking one down is left as an exercise.
Will it run in an emulator?
Maybe? See the "Running → Emulation" note above. Real HW is the testbed; I'm not maintaining an emulator path.
Can I run my own CE 2.11 MIPS EXEs?
Yes. Drop them on the SD card and launch from the file browser. BeziersCE is confirmed working end-to-end, including its commctrl spinner dialog. Apps that need hardware CE doesn't expose on the N64 (network stack, real keyboard, GAPI, etc.) will fail.
Why do the icons look weird?
Two reasons:
- The CE 2.11 SDK doesn't include any icons (other than some stray EXE icons)
- I can't add the classic Win9x icons to this repo for legal reasons
You can easily swap the ugly icons under bsp/shell/icons with some more authentic ones and it should work just fine.
How much of this is custom?
A lot. The CE 2.11 SDK / Platform Builder gives you the kernel
(nk.lib), coredll.dll, gwes.exe, filesys.exe, device.exe,
common controls, MGDI / GPE display abstractions, and the Win32 API
surface. What it does not ship is the desktop shell — no
Explorer, no taskbar, no Start menu, no Desktop window, no file
browser. OEMs were expected to build their own shell on top of the
plain GWES window-manager API. Microsoft did sell H/PC Pro devices
with a pre-built shell on them, but a reference shell source didn't
appear in Platform Builder until CE 3.0+ (the IESAMPLE / EXPLORER
samples). For 2.11 you're on your own.
So bsp/shell/ — the Win9x-style desktop, taskbar with clock + Start
button, file browser that walks \SDCard\ via FindFirstFileW, modal
dialogs with working commctrl spinners — is all original code written
against the standard CE 2.11 GWES API. Likewise for everything below
GWES: CE 2.11 ships the interfaces and expects the OEM to write the
device-specific driver underneath, so the HAL/OAL, display driver,
kbd/mouse PDD, SD FSD, wave PDD, RDP-fill code, ed64-X7 cartridge
driver, and the commctrl DllMain are all custom for the N64 target.
MIT, see LICENSE. The MIT scope is only the source files in this
repository. The Microsoft Windows CE 2.11 SDK / Platform Builder
binaries (which the build links against) carry their own license; you
must source them legitimately.
