Quick start
Getting started
Launch emulator opens the app. The loading card boots the
WebAssembly core, then scans this server's /roms directory — the exact
directory layout a desktop PCem install uses. The footer of the left sidebar shows
the result: ROMs: N of 97 machines ready. A machine appears in the
editor only when its complete ROM set was found.
- Boot something hosted here: use a card in Ready-to-boot systems
— it opens the emulator with that machine's profile and boots it automatically.
- Or build your own: in the emulator, click + New,
pick a machine on the Machine tab, attach media on the Media tab, then
Save system and Boot from its
sidebar card.
One-time browser requirement: the emulator needs
cross-origin isolation (SharedArrayBuffer, used for its threads). A proper host sends
two headers (COOP/COEP — serve.py does); on static hosts that can't, a
built-in service worker adds them and the page reloads itself once. If you see the
isolation message, that reload is all it's asking for.
Your systems are saved in this browser (localStorage) and reappear on the next
visit. Media you attach from local files is re-attached per session — the profile
remembers the slot, you re-pick the file.
This page
Getting started
The cards under Ready-to-boot systems are exported machines hosted on this
site. Each card's Boot this machine → link carries a
?system= deep link: the emulator fetches the machine's
profile.json, restores its CMOS, attaches its disks lazily (nothing big
downloads up front) and boots.
- Your session is yours. Everything the guest writes to disk stays in your
browser's memory for that session. Close the tab and the hosted machine is exactly
as published for the next visitor.
- Linked machines aren't saved to your systems list automatically — they run
as one-off sessions. Build your own copy in the emulator if you want to keep one.
Machine tab
Machine editor · tab 1 of 6
The editor is generated from the same hardware tables the native PCem GUI reads, so
everything here has a desktop counterpart.
- Machine — the motherboard/BIOS model. Only machines whose ROM set is on the
server are listed. The ⚙ button next to it opens the board's own options
when it has any (same dialog the desktop version generates).
- CPU family / CPU / FPU — what this board accepts, from PCem's CPU tables.
Fast models carry honest cost labels: “— demanding” (≥60 MHz-class) and
“— very demanding” (≥120 MHz-class) mean the browser may not hold 100%
speed. Start slower; the status bar tells you what your host actually achieves.
- Memory — sized to the machine (XT-class machines count KB, AT-class MB,
stepping at the board's granularity).
- Wait states — 8088/8086-era memory timing. Default is correct unless
you know the software needs otherwise.
- Mouse — serial (Microsoft 2-button / Logitech 3-button / Intellimouse),
PS/2 flavours, Amstrad, Olivetti M24, MSystems. Match what the guest OS's driver
expects; DOS setups usually want a serial Microsoft mouse.
- CPU recompiler — optional, per system, 386+. It converts hot guest code to
WebAssembly at runtime and is verified instruction-for-instruction against the
interpreter. It wins clearly on tight compute (number crunching, inner loops) but
the per-block overhead makes a Windows 9x desktop slower — the interpreter
is the honest default. Tick it only if the status bar measures better for your
workload.
Display tab
Machine editor · tab 2 of 6
- Video card — every card the desktop build registers, plus Built-in
video on machines that have it (fixed-video machines lock the select). The
⚙ opens the card's own options (memory size, refresh, card-specific
toggles) generated from its device table.
- Video speed — how fast the emulated bus lets the card go, from 8-bit
bus to Fast VLB/PCI. Default picks the card's period-correct
setting; raising it can help software that's video-bound, at the cost of
authenticity.
- 3Dfx Voodoo add-on card — a PCI board, so it's only available on PCI
machines (greyed out elsewhere, same rule as the desktop GUI).
Configure… sets the model, framebuffer and
texture memory, bilinear filtering, and how many render threads the rasteriser
may use. The pixel pipeline is recompiled to WebAssembly at runtime and
oracle-verified against PCem's reference rasteriser.
Sound tab
Machine editor · tab 3 of 6
- Sound card — AdLib through SB16/AWE32-class, from the same device list as
the desktop build. The ⚙ dialog is where the card's address / IRQ / DMA /
OPL options live — the values your DOS
SET BLASTER line and game
setup programs must match. It's also where MIDI out device appears once
WebMIDI is enabled (see Input / Network).
- Game Blaster / Gravis Ultrasound / SSI-2001 — extra boards that can sit
alongside the main card, like real ISA slots.
The game port (joystick) comes with the sound card, as on real
hardware — pick the emulated stick type on the Input / Network tab.
Storage tab
Machine editor · tab 4 of 6
- HDD controller — MFM, ESDI, IDE or SCSI-class controllers appropriate to
the era, with a ⚙ for controllers that have options (e.g. the XTIDE's BIOS
address). The controller decides how many drives exist and how big they can be —
and the CD-ROM drive rides the IDE bus, so an IDE-class controller is what makes
the CD drive exist at all.
- Drive A: / B: type — the physical floppy drive fitted: 5.25" 360k / 1.2M
(incl. dual-RPM), 3.5" 720k / 1.44M / 3-mode / 2.88M, or Disabled. The
drive must be able to read the image you insert (a 1.2M image needs a 1.2M
5.25" drive). Disabled drives disappear from the Media tab and the
💿 Media menu.
- The panel below lists attached hard disks with their geometry — attach the images
themselves on the Media tab.
Screen, mouse & keyboard
Running a machine
- Mouse capture: click the screen to capture the mouse (pointer lock — the
guest gets relative movement, exactly what DOS/Win9x drivers expect).
Ctrl+End releases it, mirroring native PCem. The hint pill
under the screen reminds you.
- Keyboard goes to the guest while the screen has focus. Switching away from
the tab releases everything, so no stuck keys when you come back.
- Aspect & scaling: the canvas presents at the aspect ratio the emulated
card asks for (CGA line-doubling included), scaled to fit.
⛶ goes fullscreen.
The status bar, left to right
| Item | Meaning |
| Machine name | What's running. |
| State | idle / running / paused. |
| Speed % | Emulated speed relative to the real hardware. 100% = the guest experiences real time. If it sits below ~90% for a while, a one-time toast explains the fix (pick a cheaper CPU model — see Performance). |
| fps | Frames the emulated video card is producing. |
| Net pill | Appears when networking is on: link state, LAN mode and peers, frames sent/received. Hover for full counters. |
| 🔊 | Mute/unmute host audio (the guest keeps playing either way). |
| 💿 Media | Hot-swap floppies and CDs on the running machine — see Hot-swapping media. |
| Pause / Resume | Freezes the whole machine; resumes exactly where it was. |
| Reset | Hard reset — the power switch, not Ctrl-Alt-Del. Unsaved guest work is gone. |
| Stop | Shuts the machine down and returns to the welcome screen. Session disk writes stay in memory until the tab closes — Download images you want to keep first. |
| ⛶ | Fullscreen. |
Export & deep links
Sharing · a machine is a link
Exporting a system
Export on a system card writes a self-contained, hostable
folder (Chromium-family browsers — it uses the folder picker):
profile.json — the hardware profile with a media manifest pointing
at the files below.
- Every disk image, with your session's guest writes merged in (fixed VHDs
come out as valid VHDs). Floppies and CDs included.
- Saved CMOS (
.nvr) so the BIOS remembers its setup.
LINK.txt — the exact URL recipe for wherever you upload the folder.
The deep link
Upload the folder anywhere static (same origin as the emulator, or CORS-enabled) and
share pcem/?system=…/profile.json. Visitors boot your exact machine;
their changes stay in their own browser session — your hosted images are read-only.
Every visitor gets a fresh random MAC, so several people on the shared relay LAN
don't collide.
| URL parameter | Effect |
?system=<url> | Profile to fetch and boot (required for auto-boot). |
&autostart=0 | Add the machine to the sidebar but don't boot it. |
&disk= &disk2= | Attach hosted hard-disk images to hd0/hd1 (streamed lazily via Range requests). |
&fd= &fd2= | Fetch hosted floppy images into A:/B:. |
&cd= | Attach a hosted ISO (lazy, any size). |
Hosting requirements: a plain static host works. Disks stream
fastest when the server honours HTTP Range requests (most do;
serve.py
does). The emulator page itself needs the COOP/COEP headers or its bundled
service-worker fallback (see
Quick start).
Troubleshooting
Reference
| Symptom | Fix |
| “No ROM sets found” | Copy a PCem roms/ directory onto the server (web/roms/, or point serve.py --roms at it), then Rescan. Machines only appear when their complete set is present. BIOS ROMs are not distributed with this site. |
| Page asks for “cross-origin isolation” | Serve with COOP/COEP headers (python3 serve.py does), or let the built-in service-worker shim reload the page once. Private/incognito windows sometimes block service workers. |
| “CD image could not be opened” | The file isn't a readable ISO/CUE. For .cue discs, select the .cue with its .bin file(s) in the 💿 Media menu. The machine still boots, with an empty drive — insert a good disc live. |
| “No free browser-disk slots (8 max)” | Too many lazily-attached images registered in this tab session. Slots recycle automatically when a disc is replaced everywhere it's referenced; a page reload clears everything. |
| Machine exited / “Emulator not responding” | The core logs its tail to the browser console (F12) — a missing ROM file or bad configuration is the usual cause. Reload the page to restart the core. |
| No sound | Audio starts with a user click (browser rule) — booting via a button counts. Check the 🔊 pill isn't muted. If audio crackles, the machine is probably under 100% speed: pick a cheaper CPU model. |
| Mouse trapped / keys stuck | Ctrl+End releases the mouse. Switching away from the tab auto-releases all keys. |
| Export button does nothing | Folder export needs a Chromium-family browser (File System Access API). On others, use JSON for the profile and the Media tab's Download per disk image. |
| Huge file refuses to stage | Staged media (floppies, .cue sets, dynamic VHDs) live in browser memory — 800 MB per file cap, dynamic VHDs 256 MB. Hard disks and single ISOs avoid the cap entirely: attach them as local files and they stream lazily. |
Privacy & data
Reference
- Nothing you attach is uploaded. Local images are read in place with the
browser's File API; staged copies live in the tab's memory and die with it.
- Guest disk writes never touch your files. They live in a session overlay;
the only way they reach your computer is when you click Download/Export.
- Profiles (hardware descriptions, no disk contents) are stored in this
browser's localStorage.
- Networking is opt-in per machine. When enabled, the guest's LAN frames go
to the relay you chose — the shared public one, your own, or tabs-only which
never leaves your browser. Everything else is client-side; the server only
serves static files and ROMs.
No topics match — try a different word, or clear the search.