# 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).