A universal Windows CE emulator: a virtual hardware platform that boots real CE and Windows Mobile ROMs on modern Windows.
Warning
Early stage. There are some bugs and boards are just MVP implementations. Some boards lack proper clocks, timings, caches, etc. - take into account. Today this is rather proof-of-concept. Contributions are welcome!
Download WIP build (5.1) from artifacts to use all the latest features or go to latest release
Tip
Stock touch input is misbehaving in some devices/requires some additional effort. If your clicks do not register, try holding the left button and wiggling the cursor a bit.
The easiest way to run CERF is launcher.exe - a GUI app shipped next to cerf.exe that downloads publicly available ROM bundles and boots them. Pick a device from the list, tweak launch options (resolution, logging, network) if you want, click Launch CERF.
For direct invocation without the launcher:
| Command | Action |
|---|---|
cerf.exe |
Boot default device (cerfos) |
cerf.exe --device=devemu_ce6 |
Boot specific device |
cerf.exe --log=ALL |
Enable every log channel |
cerf.exe --flush-outputs |
Force-flush logs (avoid truncation on crash, extremely slow) |
Logs are written to cerf.log next to the executable. On a fatal crash, every other thread's register state and a top-of-stack snapshot is dumped to cerf.crash.log next to it. Run cerf.exe --help for the full CLI.
Note
cerf.log is quiet by default - only critical CERF / CAUTION lines are written. Pass --log=ALL (or a channel list, e.g. --log=BOOT,JIT,MMU) to turn channels on.
Important
CERF is not a "drop any CE ROM and go" emulator. It emulates a whole device - the SoC, the board wiring, the memory map (OAT), and every peripheral the ROM's drivers touch. A ROM only boots if that exact board has been implemented in CERF. A matching SoC is not enough: the same chip on a different board has different RAM/flash addresses, a different display controller, different GPIO wiring, etc., and the ROM will fail immediately without them. Random ROMs pulled from the internet will not boot unless their board is on the supported list.
Use launcher.exe - it downloads the right ROM bundle and boots it. That's the whole flow for normal use.
If you have your own dump for a board that's already supported (e.g. a different region/revision of the same device), drop it in by hand:
- Create a folder under
devices/(next tocerf.exe), e.g.devices/mydump/. - Put the ROM image in it - any
*.nb0or*.bin; the filename doesn't matter, CERF auto-detects it. - Run
cerf.exe --device=mydump.
No cerf.json is required for this - it's optional and only carries display metadata plus a few board overrides. (Multi-partition ROMs, configurable-resolution boards, and network tweaks are the cases that need one; see device_config.h for the schema.)
This is real emulator development, not a config tweak and not something you can hand to an AI and expect magic. The board's exact memory map (OAT), every peripheral its drivers touch, the SoC quirks - all of it has to be implemented in C++, correctly, by someone who understands the hardware. It takes real skill. There are two honest paths:
- Contribute a proper implementation. Do it right - the code quality bar is whatever CERF already ships, no lower. That means a correct OAT (not a reused one from another board with
ifcases bolted on), real per-board peripherals (not board-specific behavior stuffed into shared SoC code), and accuracy grounded in datasheets/BSP/RE - not values that happen to "work." Contributions below that bar create more debugging cost than they save and won't be accepted. - Just submit the ROM. If you can't implement it yourself, share the dump and the board details. Maybe someone picks it up someday - no promises, no timeline.
CERF does ship a Claude Code dev environment and a /start-board-implementation skill that can assist a capable contributor (see Claude Development Environment below), but it is a tool for someone who already knows what a correct bring-up looks like - not a substitute for that knowledge.
Requires Visual Studio 2026 with the C++ desktop development workload.
Note
First build on a fresh machine takes 1+ hour. vcpkg compiles dependencies from source before CERF starts linking. This happens once per machine - subsequent builds reuse the cached vcpkg_installed/ tree and finish in a few minutes. Do not interrupt the first build.
Initialise source/dependency submodules:
git submodule update --init --recursive
Build via the helper script:
powershell -ExecutionPolicy Bypass -File build.ps1
Or invoke msbuild directly:
msbuild cerf.sln /p:Configuration=Release /p:Platform=Win32
| CERF Version | Changes |
|---|---|
| v5.1 (NOT RELEASED YET) |
|
| v5.0 |
|
| v4.0 |
|
| Previous versions - see the full changelog. | |
See launcher's boards details database for per-board issues.
Caution
DO NOT USE CERF CODEBASE AS REFERENCE FOR SoCs, BOARDS, PERIPHERALS - AI WRITTEN CODE CAN'T BE TRUSTED!
100% generated by Claude via Claude Code - no human-written code. Not production-grade.
CERF ships a Claude Code-based development environment for working on the emulator - including bringing up brand-new boards from their ROMs. Launch it from the repo root with:
run_claude.cmd
It runs Claude Code with a custom system prompt that injects the entire project documentation (CLAUDE.md plus every agent_docs/ reference page) into every agent, so each session starts fully briefed on the project's rules, architecture, and subsystems - no "please read the docs first" needed.
The environment provides the /start-board-implementation skill: drop your ROM into bundled/devices/ (or just point the agent at it) and run the skill. The agent identifies the board and SoC straight from the ROM, checks what CERF already supports, estimates the effort, and - on your go-ahead - starts the bring-up with a cross-session tracking document. So you can literally drop in your ROM and start the procedure of bringing it up.
Warning
The dev environment runs Claude in skip-permissions mode - it can execute anything on your machine without prompting. It also force-kills its own Claude instance, and any clangd.exe, that leaks memory past a threshold. The first launch shows a one-time explanation; press Enter to acknowledge it.
- QEMU
- The Linux kernel
- nlohmann-json
- libslirp
- JIT studied/inspired by Microsoft's Device Emulator (Shared Source Academic License, 2006)

