FM-7
FM-7 is a compact emulator built here in JavaScript around a genuine Motorola 6809 core, running Fujitsu's 1982 home computer in the browser so it boots straight to the F-BASIC 3.0 "Ready" prompt with no downloads. The FM-7 is a dual-6809 design, so this build runs two copies of the core: a main 6809 for F-BASIC and the boot ROM, and a sub 6809 for the subsystem monitor that owns the 48 KB of video RAM and the keyboard. Every register, chip and byte of memory on both processors is a plain JavaScript object, so the whole machine can be paused, single-stepped and inspected live in the shared debugger.
Runs on: Web browser
FM-7 Online Emulator
Play FM-7 using JavaScript directly in your browser.
Controls
Configurations
| Configuration | Emulator | Machine | OS | Legal | |
|---|---|---|---|---|---|
| F-BASIC | FM-7 | Fujitsu FM-7 | grey | Open ⛶ |
Machines emulated
Chips
Notes
Embedding
There is no ready-made pure-JavaScript FM-7, so this build reuses the proven JavaScript Motorola 6809 core from JSVecX (e6809.js, a port of Valavan Manohararajah's e6809.c) and wraps the whole FM-7 around it. The FM-7 is a dual-6809 machine, so we run two copies of the core: a MAIN 6809 that runs F-BASIC and the boot ROM, and a SUB 6809 that runs the subsystem monitor ROM — the SUB owns all 48 KB of video RAM, draws the 8×8 ANK font in software and scans the keyboard.
Boot. Give each 6809 its own bus object with read8 / write8, map the ROMs, reset both, and drive them from an interleaved loop you own — one main instruction, then enough sub instructions to keep pace — so neither core hides a run loop from the debugger:
var main = new e6809(); main.init(mainBus); // F-BASIC + boot ROM
var sub = new e6809(); sub.init(subBus); // subsystem monitor ROM
main.e6809_reset(); sub.e6809_reset();
(function field(){
for (var c = 0; c < 33600; ) { // ~2 MHz / 60 Hz
c += main.e6809_sstep(mainIRQ(), mainFIRQ(), 0);
if (!subHalt) sub.e6809_sstep(subIRQ(), subFIRQ(), subNMI());
}
render(); requestAnimationFrame(field);
})();
The whole machine is plain objects. Everything the debugger needs is a field or method on the two e6809 instances or on window.EMU_BOOT — there is no wasm heap:
| Member | Kind | What it does |
|---|---|---|
mainCpu.e6809_sstep(irq, firq, nmi) | method | Execute exactly one 6809 instruction with the current interrupt lines; returns its cycle count. The single-step primitive (a third nmi argument was added for the sub's display timer). |
mainCpu.reg_a / reg_b / reg_dp / reg_cc / reg_pc | field | The 8- and 16-bit registers as numbers; reg_x/y/u/s are boxed (.value). |
EMU_BOOT.mainRead(a) / subRead(a) | method | Side-effect-free reads of either CPU's 64K bus (used by the debugger's memory views). |
EMU_BOOT.vram (48K) / shared (128B) / mainRAM (32K) | field | Raw byte arrays — the three video planes, the main/sub shared block and user RAM. |
EMU_BOOT.pressKey(code) | method | Inject one FM-7 keyboard code (drives the same latch the physical keyboard does). |
Because both CPUs, both buses and all RAM are ordinary JavaScript, the debugger single-steps the main 6809, reads and writes its registers directly, and implements breakpoints and watchpoints as host-side checks around the loop — no changes to the reused core beyond the added NMI entry.
Debugger integration
The plug-in (fm7-debug.js) reads the live machine from window.EMU_BOOT and hands the shared framework a description of the FM-7. Nothing is patched into the emulator; the whole surface is ordinary field access.
- Registers are the MAIN 6809's —
A B D X Y U S DP PC CCplus theE F H I N Z V Ccondition flags decoded fromreg_cc— read each refresh and written back the same way. Single-step and watch them change. - Memory is four chips: a side-effect-free MAIN CPU bus, the 32K user RAM, a side-effect-free SUB CPU bus and the 48K VRAM. Reads run with I/O side effects suppressed (so an auto-refreshing view never clears an interrupt flag or flips the CRT-enable strobe). Disassembly uses the shared
m6809decoder. - Single step is
mainCpu.e6809_sstep— one MAIN 6809 instruction, with the SUB 6809 advanced in lockstep so the shared-RAM handshake stays coherent. - Breakpoints are host-side: with any set, the loop compares
mainCpu.reg_pcbefore each instruction. Watchpoints wrap both CPUs' bus-write paths and pause on a write to a watched address. - Input is the real FM-7 encoder: the physical keyboard maps each character to its FM-7 code, and an on-screen FM-7 keyboard drives the same codes for touch.
Architecture
The FM-7 is a dual-6809 machine, and this build keeps each block as its own object:
- Two
e6809cores — a MAIN 6809 (F-BASIC + boot ROM) and a SUB 6809 (subsystem monitor ROM), run by one interleaved host loop and single-stepped bye6809_sstep. - Main bus — 32K RAM at
$0000, the F-BASIC 3.0 ROM at$8000(switchable to RAM via$FD0F), the shared-RAM window at$FC80, the$FD00I/O page and the boot ROM at$FE00. - Sub bus — 48K VRAM at
$0000(blue/green/red planes, 16K each), console and work RAM, the shared RAM at$D380, the display and keyboard ports at$D400, and the subsystem monitor ROM at$D800. - The handshake — the main CPU halts the sub through
$FD05to take the shared-RAM bus, drops a graphics command in, releases the sub and polls a busy flag ($D40A) until it is done. The sub raises an "attention" FIRQ on the main by reading$D404; the main's 2 ms timer and the sub's 20 ms display NMI keep both sides ticking. - Video — the sub software-renders the 8×8 ANK font into VRAM; the three planes are combined into a 640×200, eight-colour picture and drawn to the canvas. With no cassette or disk, F-BASIC sizes memory, prints its banner and drops to
Ready— a complete, inspectable machine that boots straight to BASIC.