Files
2026-07-19 18:05:04 +02:00

106 lines
4.2 KiB
Markdown

# WebMetal
**WebMetal** is a browser-only, backend-free web app for designing custom CPU
architectures visually - a Scratch-3-inspired block/flow editor where you wire
up registers, ALUs, memory, and control logic; define your own instruction set;
write assembly for it; and run or step through programs in a built-in
emulator/debugger. Everything exports to (and re-imports from) a single JSON
file, with the visual layout preserved.
## What WebMetal does
1. **Design a CPU visually** - registers, register files, program counter,
flags, ALU, memory, instruction decoder, control unit, and comment notes as
draggable, connectable, documentable blocks, with live structural
validation (unwired inputs, bus-width mismatches, missing components).
2. **Define its instruction set** - mnemonics, operands, bit-level encodings,
flags affected, and execution behavior written as micro-ops, all checked
against the designed machine.
3. **Write assembly for it** - a CodeMirror editor whose highlighting and
diagnostics are generated from _your_ ISA, with labels, `.org`/`.word`/
`.byte` directives, and inline assemble-on-type errors.
4. **Run and debug** - a C++->WebAssembly emulation core with step/run/pause,
speed presets, breakpoints in the source gutter, register/flag/memory
views (editable while stopped), and a trace log.
5. **Export/import everything** - one versioned `.webmetal.json` document
(architecture, ISA, programs, layout, docs) with format migrations, plus
localStorage autosave.
6. **Learn from bundled examples** - three original CPUs in difficulty order
(EDU-CORE -> TOY-CPU -> RETRO-8).
## Tech stack
| Layer | Choice |
| ------------------ | ------------------------------------------------------------ |
| Frontend | React + TypeScript + Vite (static build, no backend) |
| Graph editor | React Flow (`@xyflow/react`) |
| Assembly editor | CodeMirror 6 |
| Simulation core | C++20 -> WebAssembly (Emscripten + embind, CMake) |
| State / validation | Zustand / Zod |
| Tests | Vitest (TS), doctest (C++), shared JSON conformance vectors |
| CI | GitHub Actions (single required `CI passed` aggregate check) |
The execution model is two-layered: the visual graph compiles to a flat
machine model, instruction behaviors are micro-op sequences, and the same
micro-op semantics are implemented twice - a TypeScript reference executor
and the C++/wasm engine - pinned to each other by shared conformance vectors
(`conformance/`) that run in Vitest, native CTest, and Node-on-wasm.
## Repository layout
```txt
frontend/ Vite + React + TypeScript app (UI, editors, assembler, model)
wasm/ C++ emulator core, built to WebAssembly (CMake + Emscripten)
examples/ Bundled example CPU projects (.webmetal.json)
conformance/ Micro-op conformance vectors shared by all executors
scripts/ Build helpers (wasm build, Node conformance runner)
.github/ CI workflow
```
## Building
Requires [Node.js](https://nodejs.org/) > 20. From a clean checkout:
```sh
cd frontend
npm ci
npm run dev # development server with hot reload
```
The app runs without the engine (design/ISA/assembler work; the Run view
reports the engine as unavailable). To build the emulator core too:
```sh
scripts/build-wasm.sh --install # first time: installs pinned emsdk into .emsdk/
scripts/build-wasm.sh # builds into frontend/public/wasm/
```
Production build (static files in `frontend/dist/`):
```sh
cd frontend
npm run build
npm run preview # serve dist/ locally to inspect it
```
Checks (all also run in CI):
```sh
npm run lint && npm run format:check && npm run typecheck && npm test
```
Native C++ unit tests (no Emscripten required):
```sh
cmake -S wasm -B wasm/build-native && cmake --build wasm/build-native --parallel
ctest --test-dir wasm/build-native --output-on-failure
```
## Deployment
`dist/` is a plain static site - any web server or object store can host it.
## License
[MIT](LICENSE).