Web site to learn assembly language.
Find a file
2026-06-22 20:45:19 +02:00
dist feat: optimizing capstone 2026-06-20 14:43:25 +02:00
examples feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
lessons feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
resources feat: lessons and new presentation 2026-06-20 11:03:28 +02:00
runtime-server feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
scenarios feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
scripts feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
src feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
test feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
.dockerignore feat: docker file 2026-06-20 20:56:27 +02:00
.gitignore feat: hybrid mode with remote runtime 2026-06-22 13:44:47 +02:00
Dockerfile feat: docker file 2026-06-20 20:56:27 +02:00
favicon.ico feat: favicon & multisyntax, modal for uninmplemented menus 2022-08-16 19:11:46 +02:00
index.html feat: hybrid mode with remote runtime 2026-06-22 13:44:47 +02:00
Makefile feat: full running hybrid wasm runtime 2026-06-22 19:13:44 +02:00
package-lock.json feat: upgrading keystone and capstone 2026-06-20 14:30:36 +02:00
package.json feat: hybrid mode with remote runtime 2026-06-22 13:44:47 +02:00
README.md feat: new version with data/code/noinit directive 2026-06-22 20:45:19 +02:00
tsconfig.json feat: mligration to ts, 1st step 2026-06-20 00:19:49 +02:00
VERSION feat: version showed 2026-06-20 02:21:25 +02:00

IA64.CC

IA64.CC is a web x86 assembly learning environment with an MS-DOS style interface.

It includes an assembler, a debugger, scenario-based lessons, register and flag views, memory explorers, breakpoints, stack display, and a VGA text screen. The emulator uses Unicorn, Keystone, and Capstone in the browser.

Requirements

  • Node.js with npm
  • Python 3 for the local static server
  • Chrome or Chromium for smoke tests

Install

make install

Build And Check

make check
make test
make smoke

make check builds the generated browser files and runs TypeScript and syntax checks.

Run Locally

make serve

Open:

http://localhost:8000/index.html

make serve stops any existing process on the selected port before starting the server. Use PORT=8080 make serve to choose another port. The development server disables HTTP caching so rebuilt files are visible after a browser reload.

Scenarios

Scenario files live in scenarios/ as .scenario.json files. A scenario contains:

  • codemap data
  • title, description, icon, difficulty, and victory message
  • initial register state
  • tutorial steps and goals

The build creates a generated dist/scenarios.js manifest from the files in scenarios/.

CodeMap Runtime Contract

The browser keeps an authoring CodeMap for editing and debugging. In that file:

  • src at the top level is optional source metadata used to reopen the full assembler document.
  • zones[n].src is optional per-zone source metadata used by the debugger, labels and symbol views.
  • zones[n].kind is authoring/UI metadata: code zones appear in the debugger Code menu, while data and noinit zones appear in the Data menu for Memory1 and Memory2.
  • zones[n].asm, zones[n].address, zones[n].code and entry are the executable runtime data.

For a remote runtime, source fields are not authoritative. Before hashing or sending a program to a VM server, use the runtime projection from CodemapCore.toRuntimeCodemap() or CodemapCore.runtimeCodemapJson(). That projection strips src, zones[n].src, names and UI-only fields, then keeps only the stable executable payload:

  • format/version
  • target architecture
  • entrypoint
  • zones with address, code mode and base64 machine bytes

IA64.CC directives split that intent in source too: .code 16/32/64 marks an executable zone, .data 16/32/64 marks a loaded data zone, .noinit 16/32/64 marks a work/result zone, and offset @title resolves any loaded zone by title.

Hybrid Runtime Server

The project now includes a first Rust backend scaffold in runtime-server/. The browser still defaults to full-client execution. Hybrid mode is opt-in and uses IA64RuntimeClient to talk to http://localhost:8080. The mode, endpoint, log level, and text-screen transport can be selected from the debugger menu with Runtime > Configuration; the choice is stored in browser local storage.

Start the backend:

make runtime-up

Select the runtime implementation:

make runtime-up
make runtime-up RUNTIME_ENGINE=unicorn
make runtime-up RUNTIME_ENGINE=mock

unicorn is the default server runtime. It creates one Unicorn x86 VM instance per session, so multiple sessions can execute independently with isolated CPU and memory state. mock only advances the current address and exists to test the HTTP/WebSocket protocol. If a runtime queue itself becomes unavailable, the server returns 503 RUNTIME_UNAVAILABLE.

Run the backend unit tests without installing Rust locally:

make runtime-test

Useful client-side calls from the browser console:

IA64RuntimeClient.setRuntimeConfig({ mode: 'hybrid' })
IA64RuntimeClient.health()

The server accepts a standard ia64.codemap, validates it, strips authoring metadata into ia64.runtime-codemap, computes a stable hash, stores the runtime payload by hash, and creates lightweight sessions. The current execution engine is Unicorn by default; the mock runtime remains available for protocol tests.

The backend runtime is now hidden behind a small VmRuntime interface. The server can select UnicornRuntime or MockRuntime with IA64_RUNTIME_ENGINE, while the HTTP routes already depend on the interface rather than on one specific implementation.

In hybrid mode the debugger can store CodeMaps on the Rust runtime, create sessions, and exchange bounded step/run commands with the server runtime. Status logs show the remote hash, session id, snapshot current address, snapshot version, and execution delta so the protocol can be verified. After session creation, the debugger prefers the runtime WebSocket for step/run mirroring and falls back to HTTP if the socket is unavailable. Remote snapshots are mirrored in the debugger Status window and the remote instruction pointer is highlighted in the Code window when it is visible. Snapshots include mode-specific general registers, the instruction pointer, stack pointer, flags, segment registers, VGA text rows, small memory windows, and register deltas. The debugger Runtime menu can stay in Mirror mode or switch to Follow, which makes the local instruction pointer follow the remote snapshot current address as an explicit preview mode.

Hybrid execution is intentionally sliced. The browser sends bounded step or run commands instead of asking the backend to run forever. This keeps the UI responsive, gives the runtime a chance to accept keyboard/timer events between slices, and avoids long blocking Unicorn executions. The debugger sends the current breakpoint list with every remote step, run, and key command; the Unicorn runtime stops before executing a breakpoint address, while ignoring the breakpoint already under the instruction pointer at the start of the command so single-step remains usable.

The remote screen snapshot supports text rows plus attributes, 320x200 indexed graphics bytes, and compact WebP images. The debugger can render remote text mode either as DOM cells or as a WebP image. Graphics snapshots are sent as WebP when available. Keyboard IRQ1 is only injected when an explicit keyboard event is sent to the runtime; in the browser UI, physical keyboard events are forwarded only while the virtual keyboard overlay is open, which avoids accidental IRQs while using menus or shortcuts.

The server also exposes GET /api/sessions/{id}/vga.html?refresh=1000, which can be embedded in an iframe to display a VGA snapshot with periodic refresh. For streaming control, the server exposes GET /api/sessions/{id}/ws. The socket sends an initial hello snapshot, then accepts JSON commands such as {"command":"snapshot"}, {"command":"step","count":1}, {"command":"run","count":1000}, {"command":"key","key":"a"}, and {"command":"ping"}. Responses use the same snapshot/delta payload as HTTP.

Repository Layout

  • src/: TypeScript source
  • test/: unit and browser smoke tests
  • scenarios/: scenario JSON files
  • resources/: app images
  • dist/: vendored browser libraries and generated build outputs
  • scripts/build.mjs: build script

Generated files in dist/ are ignored where they are produced by this project. Vendored runtime libraries and assets remain versioned because the app is served as a static web application.