Altair 8800 Simulator
The 1975 computer that started the personal computer revolution, in your browser: its switches and lamps, its Teletype, Microsoft's first BASIC, and the whole machine in 3D, down to the cards inside.
▶ Try it online - nothing to install, on a desktop or a phone, in ten languages.
What you can do
| Switch it on and run a program Lamps, switches and a real 8080 at 2 MHz. ![]() |
Take it apart in 3D The lid, the cards, the power supply, in the order the real one allows. ![]() |
| Boot Microsoft 4K BASIC Bill Gates and Paul Allen's 1975 BASIC, unmodified, on a Teletype. ![]() |
Write 8080 assembly Intel's own language, macros and all, assembled as you type. ![]() |
| Watch the CPU work Registers, the next instruction and memory, a step at a time. ![]() |
Learn as you go Four lessons, from meeting the machine to running BASIC. ![]() |
Try it in a minute
- Open the simulator, online
- Open Load, and choose Pattern shift under *Front Panel
- Click RUN.
The guide
Everything in more detail, for when you want it: the front panel · a program by hand · around the simulator · the machine in 3D · the Teletype · 4K BASIC · assembly · more programs · for developers.
Meet the front panel
The Altair 8800 had no screen and no keyboard. This panel was the whole of the way in and out.
The lamps show the machine as it is:
| Lamps | Show | | --- | --- | | A15–A0 | The address bus: the memory address the CPU is at | | D7–D0 | The data bus: the byte at that address | | STATUS, WAIT | What the CPU is doing. WAIT is lit while it is stopped, and HLTA too when a HLT stopped it | | INTE | Interrupts are enabled: lit by EI, put out by DI and RESET | | PROT | The memory board at the address shown is protected |
The switches are how you talk to it:
| Switch | What it does | | --- | --- | | OFF/ON | Power. Memory comes up full of random bytes, as on the real one | | A15–A0 | An address, up for 1 and down for 0. A7–A0 is also the byte to store. Programs can read A15–A8 as the sense switches | | EXAMINE · EXAMINE NEXT | Show the byte at the address on the switches · at the next address | | DEPOSIT · DEPOSIT NEXT | Store A7–A0 at the address shown · at the next address | | RESET · CLR | Send the CPU back to 0000H · clear the serial boards, dropping keys typed and not yet read | | RUN · STOP | Run the program from where the CPU is · stop it | | SINGLE STEP | Run one instruction | | PROTECT · UNPROTECT | Protect the memory board at the address shown (EXAMINE an address on it first), so that neither DEPOSIT nor a program can change it · unprotect it. Each 4 KB board has its own; everything starts unprotected | | AUX | Nothing: MITS left both spare, for boards added later |
The switches come in groups of three because 8080 programmers wrote
bytes in octal: 00 111 010 is 072 octal, or 3AH. Click the panel's
own switches, or the large buttons on the strip under it, which are
easier to hit and show which switches are up. The small arrow on the
strip's top edge folds it away.
One simplification. SINGLE STEP here always runs one whole instruction, as the Altair's Operator's Manual describes it. The circuit itself, MITS's Theory of Operation says, stopped after each machine cycle, so one instruction could take up to five presses. Stopping only between instructions keeps a step about the program rather than the bus. It also means the STATUS lamps always show the CPU about to fetch its next instruction - MEMR, M1 and WO - or, after a HLT, MEMR, HLTA and WO. INP, OUT and STACK belong to cycles inside an instruction, so they stay dark; and while a program runs the lamps hold still, rather than glowing with every cycle as the real ones did.
Your first program, by hand
This is how an Altair owner put in a program in 1975: one byte at a time, on the switches. It adds 1 and 2. The same steps are in the simulator's Tutorial, under the panel, to follow as you go.
LDA 0080H ; 00 111 010
; 10 000 000
; 00 000 000
MOV B,A ; 01 000 111
LDA 0081H ; 00 111 010
; 10 000 001
; 00 000 000
ADD B ; 10 000 000
STA 0082H ; 00 110 010
; 10 000 010
; 00 000 000
JMP 0000H ; 11 000 011
; 00 000 000
; 00 000 000
1. Turn on the Altair 8800 with the OFF/ON switch. 1. Set switches A7–A0 to 00 111 010 (up for 1, down for 0). 1. Click DEPOSIT. 1. Set switches A7–A0 to 10 000 000. 1. Click DEPOSIT NEXT. 1. Repeat steps 4–5 to enter the following bytes one by one: 00 000 000, 01 000 111, 00 111 010, 10 000 001, 00 000 000, 10 000 000, 00 110 010, 10 000 010, 00 000 000, 11 000 011, 00 000 000, 00 000 000. 1. Set switches A7–A0 to 10 000 000. 1. Click EXAMINE. 1. Set switches A7–A0 to 00 000 001 (the first number to be added, or 1 in decimal). 1. Click DEPOSIT. 1. Set switches A7–A0 to 00 000 010 (the second number to be added, or 2 in decimal). 1. Click DEPOSIT NEXT. 1. Click RESET. 1. Click RUN and wait for a few seconds. 1. Click STOP. 1. Set switches A7–A0 to 10 000 010 (the address that holds the sum). 1. Click EXAMINE. 1. The data lamps D7–D0 show the result 00 000 011 (3 in decimal). 1. Turn off the Altair 8800.
At step 18, A7 and A1 are lit on the address lamps for 0082H, and D1 and D0 on the data lamps for the answer.
Around the simulator
Everything is on one screen: the panel, a toolbar above it, a dock of tools below it, and a status line along the foot.
- The toolbar. Load puts a program in. Memory installs
- The dock holds five tabs, one at a time: the Teletype, the
- The status line says what just happened, and why a greyed-out
- 2D | 3D, at the top right of the panel, swaps the front panel for
The Debugger is a view the real Altair never had. Step through a program with SINGLE STEP and watch it work:
- The registers, with the flags S Z AC P CY lit when set.
- The next instruction: its address, its bytes, its mnemonic with
LDA a16,
MVI B,d8), and the operand's value this time.
- The memory dump, one 256-byte page at a time, with the
- Changing a byte: with the machine stopped, click a byte in the
3e8cd3ff fills four in a row; the arrow keys move, and
Esc stops. A protected board refuses, as it refuses DEPOSIT.
The machine in 3D
3D shows the whole box: the case, the chassis, the power supply, the bus, and each card in its slot. It is the same machine as the 2D panel, not a picture of it: click a switch on it and it does what the 2D switch does, and its lamps light as the 2D lamps do.
- Look around: drag to turn it, right-drag or two fingers to move
- Views picks where to look from - the front panel, the whole
- Take it apart: switch the machine OFF, then click the lid to
- No power while it is apart. OFF/ON will not switch on a machine
- The cards follow the Memory menu: 256 bytes is the 1K card, 4 KB
- The Tutorial's first lesson, Meet the Machine, walks through
The 3D view needs WebGL 2, and loads only the first time you choose it (about 5 MB). How the model was made, and from what, is in docs/3d-model.md.
The Teletype
The Altair's terminal was a Teletype ASR-33: a keyboard and a printer on paper, upper case only. Here it sits on an 88-SIO serial board, at ports 00H and 01H (and an 88-2SIO at 10H and 11H). Nothing echoes by itself: a program has to be running and reading the board.
Try the Teletype Examples from the Load menu, in this order:
- Teletype hello prints
HELLO, WORLD!and stops. - Teletype echo prints whatever you type.
- Teletype echo with lamps does the same, and shows each key's
01000001 lights up.
- Guess my letter is a game. It thinks of a letter and says
The keys a PC keyboard lacks, such as BREAK, RUBOUT and LINE FEED, are along the top of the paper.
Microsoft 4K BASIC
The Altair's first piece of software was Microsoft's first product: Altair BASIC 3.2, written in 1975 by Bill Gates, Paul Allen and Monte Davidoff. It runs here, unmodified.
- In Memory, choose 4 KB (or 8 KB, for more room).
- In Load, choose Microsoft 4K BASIC.
- Click RUN, and open the Teletype.
- Answer BASIC's questions: Enter, Enter, then Y.
MEMORY SIZE?
TERMINAL WIDTH?
WANT SIN? Y
727 BYTES FREE
BASIC VERSION 3.2
[4K VERSION]
OK
PRINT 3.14 * 9
28.26
OK
727 bytes is all a 4 KB machine leaves you, which is exactly what the name means. Load it and look at the memory map in the Debugger before pressing RUN, and you can see BASIC filling fifteen of the sixteen pages. The Tutorial walks through it, including what loading it here skips: toggling in a 28-byte boot loader by hand, then waiting seven minutes for the paper tape.
The BASIC tape is in roms/, and roms/NOTICE explains what it is and why it is not under this repository's licence. Binary File… in the Load menu loads an image of your own instead.
Write it in assembly
Your first program went in byte by byte, the way an owner did in 1975.
Intel's answer, the same year, was assembly language: you write
ADD B, and an assembler works out that it is 80. The Assembler
tab, under the panel, takes the language exactly as Intel's *8080
Assembly Language Programming Manual* defines it, macros and all.
Here is that first program again, with names for its addresses instead of the numbers. It makes exactly the bytes you toggled in:
FIRST EQU 80H ; the first number
SECOND EQU FIRST+1 ; the second, the byte after it
SUM EQU FIRST+2 ; and where the sum goes
START: LDA FIRST ; A = the first number
MOV B,A ; keep it in B
LDA SECOND ; A = the second
ADD B ; A = A + B
STA SUM ; store the sum
JMP START ; and do it all again
- Open the Assembler tab and type it in, or choose
- Beside each line, the listing shows its address and the bytes it
- Click Assemble (or press Ctrl+Enter, ⌘+Enter on a Mac). The
- DEPOSIT 1 at 0080H and 2 at 0081H, as by hand, then RUN, STOP
What it takes is the whole of the manual's language: every
instruction, labels, EQU and SET, DB, DW and DS, expressions
and $, IF and ENDIF, and macros, whose labels are local to each
use as Intel specified. Its Examples menu has every example
program, from switches to lamps to macros (examples/).
Once a program is assembled, the line the program counter is on is
marked in green as you SINGLE STEP or STOP, and the line the caret is
on is banded across to its bytes. In the editor's corner, Copy
takes the source with you, and Clear starts afresh (Undo brings it
back). On a phone, the source and its bytes take turns, under the
Source and Bytes tabs. The design and its decisions are in
docs/assembler.md.
More programs
- Kill the Bit, the 1975 front-panel
- Fourteen example programs in all, each written in assembly
- Your own, in assembly language: in the Assembler tab
- Your own, as bytes: paste them in hex with Load › Hex Bytes…,
- Share one as a link: Share copies a link that opens the
For developers
Run it locally
Serve the directory over HTTP and open it. With no web server installed, Python has one built in:
python3 -m http.server 8000
Then open
Opening index.html straight off the disk does not work, since
v1.7.0: the page's scripts are ES modules, and a browser runs no module
in a file:// page. Opened that way, the page shows only a notice that
says so and gives the command above.
Deploying behind a cache
Every file index.html names carries the version, css/style.css?v=1.7.0,
and so does every module the scripts import, through the page's import
map. A release asks for new names, so a cache can keep each file as long
as it likes and still never give an old one to the new page. Only
index.html itself must not be kept. On a server or a CDN that lets you
set the headers:
| What | Cache-Control |
| --- | --- |
| index.html (and /) | no-cache: kept, but checked with the server each time, which costs a reply with no body when nothing changed |
| Everything asked for with ?v= | public, max-age=31536000, immutable |
| package.json, examples/, roms/ | no-cache; the page fetches these itself, and asks for a check anyway |
A CDN must count the query string in its cache key (most do unless told
not to), and should be told to purge index.html on each deploy.
GitHub Pages sets no headers you can change and keeps everything for 10
minutes, so there a release reaches everyone within 10 minutes.
The version is kept in one place, package.json; the names in
index.html are copies, written from it and never by hand. Set it with
npm, which writes them too:
npm version 1.7.0 # or: npm version patch | minor | major
It sets the version, then runs npm run stamp
(tools/stamp.mjs) to write it into index.html's
file names and import map, and stops there: it does not commit or tag
(.npmrc), since a release is tagged on GitHub, on its merge
commit. Commit the two files as usual. A version changed any other way,
by hand in package.json, needs npm run stamp after it; until then
npm test fails and says so, so a release cannot go out half stamped.
The logo and icons
The logo is in images/ in three forms: the machine alone, 16:9
(8800-simulator-logo.svg), and the machine with its name, 8:1, in
white for dark backgrounds and black for light ones
(8800-simulator-logo-text-white.svg, -text-black.svg). The toolbar
shows the one with the name, and on a phone the machine alone; this
README shows the name in whichever colour suits the reader's theme.
The favicons and home screen icons are drawn from the 16:9 one, and
kept with it in images/: favicon.svg, favicon.ico (16, 32 and 48
pixels), and the 180, 192 and 512 pixel PNGs that index.html and
manifest.webmanifest name. After a change to
the logo, draw them again (it needs Chrome, as the browser checks do):
npm run icons
npm test fails until they have been, since it checks that the SVG
favicon still has the logo's drawing.
How it is built
| File | What it is |
| --- | --- |
| index.html, css/style.css | The page: toolbar, panel, dock, dialogs |
| js/main.js, js/app.js | The page's one script, and the app it starts; every file is an ES module |
| js/8080.js | The Intel 8080 CPU core, maly/8080js |
| js/sim8800.js | The machine: memory, the front panel's logic, the ports |
| js/sio.js, js/teletype.js | The serial boards, and the Teletype's paper |
| js/panel.js | The page's own logic, at its core: the status line, About, and building the page |
| js/panel-front.js | The front panel: its switches, lamps and sounds, and the big switches under it |
| js/panel-load.js | Putting a program in: Load, the examples, 4K BASIC, files, the Memory menu |
| js/panel-debug.js | The Debugger: the memory dump and its editing, the next instruction, the memory map |
| js/panel-link.js, js/panel-tty.js, js/panel-dock.js | Program links and Share; the Teletype; the dock and its tabs |
| js/link.js | The program link format |
| js/asm8080.js, js/asmtab.js | The 8080 assembler, and its tab |
| js/dropdown.js, js/dialog.js | The menus and the dialogs |
| js/l10n.js, js/l10n-3d.js | Every message, in ten languages |
| js/panel-view.js, js/panel-tutorial.js | The 2D / 3D toggle; the Tutorial's lessons, remembered, and Show chips |
| js/box.js | The machine's box: which parts are out, in what order they come out, and so whether it may switch on |
| js/view3d/ | The 3D view, loaded when first chosen: the renderer and camera, the 3D panel, the box's parts, the Views and Show menus, and its state machine (stage-state.js) |
| model/ | The 3D model: its params, its Blender build (npm run build:model), its research, and the built .glb |
| vendor/three/ | three.js, pinned (node tools/vendor.mjs) |
| tools/stamp.mjs, tools/icons.mjs, tools/vendor.mjs | Not part of the page: the version stamp, drawing the icons from the logo, and vendoring three.js |
| tools/shots.mjs, tools/video.mjs | Not part of the page either: the screenshots and the video clips, below |
The design notes say why things are the way they are: docs/ui-design.md for the layout and its principles, docs/ms-basic-4k.md for the memory, the serial boards, the Teletype and BASIC, docs/assembler.md for the assembler and the language it takes, docs/kill-the-bit.md for the address-bus trick Kill the Bit relies on, and docs/3d-view.md and docs/3d-model.md for the 3D view and its model.
Tests
npm test
Node.js 24, nothing to install. The suite covers the 8080 CPU, the front panel, the serial boards and the Teletype, the page's own logic and translations, the link format, the assembler against Intel's manual, every program in examples/, 4K BASIC booting and running end to end, and the 3D view's logic: the box and the power, the model against its params, framing, the toggle, and a walk of every state its state machine can reach. It runs on each push and pull request.
The page itself - clicks, menus, the Assembler's editor, the layout - is checked in a headless Chrome:
npm run test:browser
npm run test:browser -- sync clear
It takes a minute or so and needs Chrome installed (or CHROME set to
its path, Chromium too), so it is not part of CI: run it by hand
before a release. The checks are in tests/browser/.
The JSDoc types are checked against the code by TypeScript's checker,
which npx fetches for the run; nothing is compiled, and the page
runs the files as they are. CI runs it after the tests:
npm run typecheck
Only the files that start with // @ts-check are checked, so far
js/asm8080.js, js/sim8800.js, js/box.js and the 3D view's
framing, views and state; tsconfig.json
says how strictly.
Screenshots and videos
The pictures in this README, and a larger set for posts, are taken from the page itself in a headless Chrome, as a reader would leave it:
npm run shots -- --readme # English, and this README's pictures into screenshots/
npm run shots -- --lang en,zh # any languages, into ~/Downloads/8800-simulator-v<version>-media/shots/
npm run video -- --lang en,zh # 1080p clips into .../videos/ (needs ffmpeg)
--only takes the shots or clips whose names hold it. The clips
are rendered frame by frame on a clock the tool moves on, so they are
smooth however slowly the frames are taken, and the 8080 runs at its own
2 MHz in them. The shots and scenes are listed in
tools/shots.mjs and tools/video.mjs.
The link format
A link opens the simulator with a program loaded at 0000H, ready to
RUN. The fields go after ? or #:
https://wixette.github.io/8800-simulator/?hex=3E8CD3FF76
Try it:
the bytes are MVI A,8CH, OUT 0FFH and HLT. Click RUN and the
data lamps show 10001100.
The bytes of hex can run together, or be separated by + or %20.
Memory is installed to fit, and zeros at the end do not count.
Share writes its links after #, which is never sent to the web
server, so a long one is not turned away (GitHub Pages refuses a link
of 16,000 characters). It leaves out whatever a machine just switched
on would have anyway. Memory in use that fits in 256 bytes is written
as hex, so it can be read in the link; past that it is compressed under
zip, and 4K BASIC comes to about 4,500 characters instead of 8,300.
Every field is optional:
| Field | Holds |
|---|---|
| hex | Memory from 0000H up, in hex |
| zip | The same memory, deflated and in URL-safe base64, in place of hex |
| mem | Installed memory: 256, 4096 or 8192 (decimal) |
| pc, sp | The 16-bit registers, in hex |
| a, b, c, d, e, h, l, f | The 8-bit registers, in hex, f being the flags |
| sw | The address switches, A15–A0, as a 16-bit hex word |
| view | 3d to open in the 3D view, 2d for the front panel (since v1.8.0); a link from Share in 3D carries view=3d |
A linked machine always opens stopped. The Teletype's paper and the interrupt enable are not in the link. The format is a promise to everyone who has put a link in a document: fields may be added, but never renamed or read differently (js/link.js).
References
- Wikipedia: Altair 8800
- Wikipedia: Intel 8080 CPU
- Intel 8080 instruction set - an opcode encoding quick reference (text)
- Original Altair 8800 manuals - scanned PDFs archived at altairclone.com
- Altair 8800 Operator's Manual - the original manual as a scanned PDF
- Altair 8800 Operator's Manual v2.0 - an HTML edition by Kevin Cole
- Intel 8080 Assembly Language Programming Manual - Intel's original manual as a scanned PDF
- Intel 8080 Assembly Language Programming Manual - an HTML edition by the Grace Hopper Center
- Demystifying Computers - an open source book by Chris Jones and Jeff Elkner
- Wikipedia: Altair BASIC - what it is, and how Microsoft started with it
- MITS Altair BASIC Reference Manual (1975) - the language itself, the startup questions and the error codes
- Altair BASIC 3.2 (4K) - an annotated disassembly of the exact program this simulator runs
- MITS Altair Simulator - another JavaScript simulator, running Microsoft BASIC on a simulated teletype
Acknowledgements
The Intel 8080 CPU core is maly/8080js.
The 3D view is drawn with three.js (MIT). Its model rests on MITS's 1975-76 manuals and board artwork (archived by bitsavers.org and deramp.com; facts only), the Smithsonian's and the Computer History Museum's records, and freely licensed photographs by Wikimedia Commons and Flickr contributors, credited in model/research/photo-credits.md. The model and its data are CC BY-SA 4.0 (model/LICENSE); the rest of this repository, apart from the BASIC tape, is Apache 2.0.
The Tutorial's Your First Program lesson uses an example program from the original Altair 8800 Operator's Manual.
The photo that opens the Tutorial, an Altair 8800 beside a Model 33 Teletype, is by Tim Colegrove, CC BY-SA 4.0, from Wikimedia Commons, scaled down; see images/tutorial/CREDITS.md.
The interaction design took another Altair 8800 simulator as a reference.





