The monitor
This document is one of two short documents about how to use altairsim itself. altairsim is the
program that you run, and the machines that it simulates are a different subject. This document
is about the monitor. The monitor is the altairsim> prompt, where you start, stop, examine
and change the machine. The other document, The Debugger, tells you what to do in the monitor
when a guest does not work correctly.
Both documents are companions to the User Manual. The User Manual describes the hardware: the
boards, the machines, the disks and the tapes. altairsim simulates the MITS Altair 8800 and
its S-100 bus. If you do not know these, start with the first chapter of the User Manual.
The altairsim> prompt is the monitor. The monitor is the front panel of the machine, and
it is also the debugger. In altairsim, the front panel and the debugger are one thing. The monitor can do all that the front panel
of a real Altair could do, and much more. It sets breakpoints, single-steps and disassembles. It
also shows you the bus: which board decodes each address, which board asserts each
interrupt line, and where two boards decode the same address. The Debugger describes these
debug tools. The debug tools are the main reason that altairsim exists.
The monitor operates the machine directly. It is not a menu that stands between you and the machine and lets you examine a fixed set of things. There is no debug mode to enter, and no process watches the machine from outside. A breakpoint is the machine stopping. It is not a script that sees afterward that the machine should have stopped.
IN and OUT do real bus cycles, with all the side effects of a real cycle. If you read a
UART's data port in the monitor, you take the byte from the UART, as the guest would. The front panel
and the debugger are one object because on an Altair they were one object. The operator set the
switches and read the lamps.
The monitor works while the machine is stopped. Most of the tasks that follow work with the power on and the processor stopped. Examples are examining memory, doing a bus cycle and adding a board. The front panel was also made for a machine with the power on and the processor stopped.
Commands resolve by prefix
The monitor finds a command from the first letters that you type. It has no aliases and no abbreviations to learn. Type enough letters to make the command unambiguous. The first command that matches is the one that runs.
HELP prints the full list of commands, with the shortest form of each command outside the
brackets:
BO[ARDS] B[REAK] COM[PARE] C[ONFIG]
CONN[ECT] CONS[OLE] DE[POSIT] DI[SASM]
DISC[ONNECT] DO D[UMP] E[DIT]
EX[AMINE] F[ILL] HE[LP] H[ISTORY]
I[N] L[OAD] MA[CHINE] M[OUNT]
MOV[E] N[EXT] NO[BREAK] O[UT]
P[OWER] Q[UIT] REGI[ON] RE[GS]
RES[ET] REST[ORE] R[UN] SA[VE]
SEA[RCH] SE[T] SH[OW] SN[APSHOT]
STA[RTUP] S[TEP] SY[MBOLS] T[RACE]
TY[PE] U[NMOUNT] W[HO]
Type the part before the bracket. D is DUMP, DE is DEPOSIT and RES is RESET. Upper
case and lower case are the same, in a command and in the name of a board.
HELP <command> shows the usage and examples for one command. ? is the same as HELP.
Some commands are shortcuts for a longer command. The help of a shortcut says which command
it is short for. CONSOLE is a shortcut for SET CONSOLE and SHOW CONSOLE. Thus
HELP CONSOLE prints the full help of SET CONSOLE, which is also what HELP SET CONSOLE
prints.
RisRUN, notRESET. To reset, typeRES. You typeRUNin every session, and an unwantedRUNdoes no damage. IfRreset the machine, one wrong key could make you set up the machine again.
Editing the command line
The monitor has a full line editor. The key with the label Backspace erases the character to the left of the cursor. It does this for each byte that a terminal can send for that key. The arrow keys move the cursor in the line. The line editor also keeps a command history. The up arrow goes back through the lines that you typed, and the down arrow goes forward to the line that you were typing.
The history is saved between sessions, for each directory. When you quit, the monitor
writes your last commands to a hidden file, .altairsim_history, in the directory where you
started altairsim. The next time you start altairsim in that directory, the up arrow
shows those commands. Each project directory keeps its own list. The monitor writes the history file
only when you type at a real terminal. A script, a pipe or an automated run never makes a
history file.
The history setting on the console sets how many lines the history file keeps. The default is 50. Type
SET CONSOLE history=200 to keep more lines. Type SET CONSOLE history=0 to stop saving the
history file.
Completing with Tab
Tab completes the word that you are typing. It gets the possible words from the current
machine. When you add a board, Tab can complete the board's id at once. There is no list to keep up to date. Tab completes these words:
- at the start of a line, a command:
SH⇥ →SHOW - after
SET, a board id, orCONSOLEorDISPLAY:SET me⇥ →SET mem0 - after a board id, one of the board's property names, with the
=added:SET mem0 fi⇥ →SET mem0 fill= - after the
=, one of the property's legal values: forSET mem0 fill=⇥ the choices arezeroandrandom
When more than one word fits, Tab adds the letters that all of the words share, and then
stops. Press Tab again to see the list. When no word fits, Tab does nothing.
Editing keys
| Key | Does |
|---|---|
← → |
move one character |
Ctrl-A / Home |
move to the start of the line |
Ctrl-E / End |
move to the end of the line |
Alt-B / Ctrl-← |
move back one word |
Alt-F / Ctrl-→ |
move forward one word |
Backspace |
erase the character before the cursor |
Delete |
erase the character under the cursor |
Ctrl-W |
erase the word before the cursor |
Ctrl-K |
erase from the cursor to the end of the line |
Ctrl-U |
erase the full line |
↑ ↓ |
move back and forward through the command history |
Tab |
complete the word at the cursor |
Ctrl-D |
on an empty line, quit, the same as QUIT |
In the monitor,
Ctrl-Emoves to the end of the line. In the monitor you type to the line editor. When a running guest has the console,Ctrl-Eis STOP.Ctrl-Estops the machine and starts the monitor, so you have the keyboard again (see below). The same key does two jobs in two places.
Repeating the last command: .
Type . alone on a line to run your last command again. The monitor does not echo the
command, so you see only its output. The commands that you usually repeat continue from where
they stopped. A bare DISASM disassembles the next screen, a bare DUMP shows the next page,
and STEP steps again. To go forward through a routine, type DI one time and then . . ..
To single-step, type S and then ..
Each . repeats the original command, not the previous .. Ten presses of . run the original command ten times. If you type . before any other command, the monitor tells you
that there is nothing to repeat.
Reaching the host: !
A line that starts with ! goes to your host shell. The monitor sends all the text after
the ! to the shell with no changes, spaces included. The monitor waits until the command ends,
and then it shows the altairsim> prompt again:
!ls list the directory you started from
!vi HELLO.PRN open a file in your editor, then :q to return to the monitor
!cp game.dsk save.dsk copy a disk and keep it mounted
! runs your shell, with your own permissions. The shell is not part of the machine,
and the guest cannot see it or use it. An editor works because the monitor releases the keyboard
before it starts the command. vi gets a normal terminal, and it gives the terminal back when it exits. The machine stays stopped while the command runs, as it always is while the monitor runs.
A bare ! with no command shows how to use !.
Numbers: one fixed rule
On the wire → hex. Never on the wire → decimal.
If the processor can see a number, the number is hex. Addresses, ports, data bytes and registers are hex. If the processor never sees a number, the number is decimal. Counts, widths, sizes and drive numbers are decimal.
Hex is only the default for the wire class. If you set the console to octal, the monitor reads and prints the wire class in octal. The MITS manuals and the front panel used octal. The rule stays the same. Octal replaces hex for the wire class, and counts stay decimal. Reading and writing in octal, below, tells you how to use octal.
DUMP 100 address -> 0100 hex
STEP 10 a count -> ten instructions
OUT FF 55 port and byte -> both hex
SET sio0:a baud=9600 a baud rate -> nine thousand six hundred
A prefix or a suffix sets the base of one number:
| Write | Base |
|---|---|
0x, $, or a trailing h |
hex |
0o, or a trailing q |
octal |
% |
binary. Use it for the front panel's sense switches: one digit for each switch. |
0b |
binary, but only where the number is decimal or octal. Where the number is hex, B is a digit: 0B10 is the address 0B10. |
a leading # |
decimal |
a K or M suffix |
always decimal. 48K is 49,152. |
The monitor rejects a number with two bases, such as 0x10K. It does not guess.
The same rule applies in the monitor, in a machine file and in the settings of every board. You learn only one rule.
The classes are fixed. Each kind of number is always in the same class. You can change the base in which the monitor prints the wire class, and the next section tells you how to change it.
Reading and writing in octal
The MITS manuals and the Altair front panel used octal, not hex. You can use octal too:
SET CONSOLE base=octal
After this command, the wire class is octal. The monitor reads and prints addresses, ports, data
bytes and registers in split octal. Each byte is a group from 000 to 377, and a 16-bit
address is two groups. The front-panel address lamps are grouped the same way:
EXAMINE 100 -> 000 100 076 (the byte 0x3E at address 0x40)
DUMP 100-100 -> 000 100 076
DISASM 0 -> JMP 022 064 (a jump to 0x1234)
A bare number is octal now too, so 100 is address 0x40. The decimal class, such as counts,
widths and baud rates, does not change. The prefixes and suffixes still work in both modes, so
you can always type a number in the base that you want. 0x1234 is hex in octal mode, and
0o377 is octal in hex mode. base=hex, the default, sets hex again. To start in octal every
time, set [console] base = octal in a machine file.
Naming a board: <id>[:<unit>]
Every board in the machine has an id. The id is a name that you give the board when you add
it, in a machine file or with BOARDS ADD. An id can be any name, such as sio0 or serial.
Upper case and lower case are the same.
The machines that come with altairsim use a short type name and a number, such as cpu0,
sio0 and dsk0. The number has no special meaning. It only tells two boards of the same kind
apart, such as sio0 and sio1.
Some boards also have units. A unit is a part of a board that has its own name. For example,
a 2SIO serial board has two channels, a and b. A floppy controller has four drives, drive0
to drive3. A memory board has a ROM socket, rom0. To name a unit, type the board id, a colon
and the unit name:
SHOW sio0 the board
SET sio0:a baud=1200 channel a of the board
MOUNT dsk0:drive1 my.dsk drive1 of the board
Shorter names
When you type in the monitor, you can shorten the id, and you can omit the unit.
You can omit the digits at the end of an id. sio finds sio0, and dsk finds dsk0. A shorter id
works only when one board has that id with digits after it. If the machine has sio0 and sio1,
sio is ambiguous. The monitor then lists sio0 and sio1 and stops. You can omit only the
digits at the end, so si does not find sio0.
You can omit the unit when the board has only one unit that the command can use. For MOUNT,
the monitor counts only the units that take a medium, such as a drive or a tape. For CONNECT,
it counts only the serial units. For example, MOUNT acr tape.bin puts a cassette in the one tape unit of
acr0. A floppy controller has four drives, so MOUNT dsk0 my.dsk does not work. The monitor
lists the four drives and stops.
To change a property of a unit, SET always needs the unit name. Without a colon, SET changes
a property of the board.
Shorter names work only in monitor commands. A machine file, and an MCP tool that takes a board id, must use the full id and the full unit name.
Seeing the machine
altairsim> BOARDS
ID TYPE I/O UNITS MEMORY
---- ---------- -------- -------------------------- ------------------------------
fp0 fp FF - -
cpu0 8080 - 1 cpu: 8080 -
sio0 2sio 10,12 2 serial: a*, b -
dsk0 dcdd 08,09,0A 4 disk: drive0(empty), ... -
hb0 hostbridge B0,B1 - -
mem0 memory - 1 rom: rom0 0000-DFFF ram 56K
FF00-FFFF rom dbl phantom:all
* holds the console
The BOARDS output is the backplane. It shows each board in the machine, the ports and memory that the board
decodes, and what is in its units.
| Command | Shows |
|---|---|
BOARDS |
the backplane |
SHOW <id> |
one board: each setting, its value, and the values that it accepts |
SHOW MACHINE |
the whole machine |
SHOW CONSOLE |
which unit has your keyboard, and which transforms apply to its bytes |
SHOW DISPLAY |
the windows altairsim opens: whether a window comes to the front when it opens, where its keys go, and whether the CRT look is on |
SHOW JOYSTICKS |
the host game controllers that a board can read, such as a D+7A (needs an SDL3 build) |
SHOW SERIAL |
the serial ports on your computer, and the unit that holds each port |
SHOW BUS |
the whole backplane at one time: MEMORY, I/O and a short INTERRUPTS summary |
SHOW BUS MAP |
which board decodes each address, and which addresses float |
SHOW BUS IO |
which board decodes each port |
SHOW BUS IRQ |
which board is strapped to each interrupt line, and which board asserts it |
SHOW BUS CONTENTION |
where two boards decode the same address or port |
Look closely at SHOW <id>, because it is the only command that you need to configure a
board. It lists every property, its value and its legal values. The property names are the
keys that you write in a machine file. altairsim has no second schema. The board reference
in the User Manual is printed from the same tables. (The reference at the end of this document
is for the monitor's commands.)
Changing the machine
SET cpu0 clock_hz=2000000 run at the real 2 MHz clock
SET mem0 fill=zero RAM starts as zeros, not random bytes
SET fp0 sense=80 set the SENSE switches
BOARDS ADD 2sio sio1 port=20 add a second serial board
BOARDS REMOVE sio1 remove it
CONFIG SAVE mine.toml save the machine as it is now
altairsim mine.toml starts the same machine that CONFIG SAVE saved.
Running, and stopping
RUN FF00 set the PC and start: the same two steps as on the front panel's switches
RUN continue from where the processor stopped
RUN <addr> is EXAMINE followed by RUN, as on the front panel. altairsim has no BOOT
command, and this is deliberate. A machine starts only when a RUN tells it to start, as a real
Altair started only when the operator pressed RUN.
If a board holds the console, the guest gets the keyboard. The guest gets every key,
including Ctrl-C, because a CP/M program can read Ctrl-C.
Ctrl-E stops the machine and starts the monitor
Ctrl-E is the front-panel STOP switch. altairsim reads Ctrl-E before the guest can see
the byte. The guest never gets Ctrl-E, and it cannot disable Ctrl-E. Ctrl-E always stops the
machine.
If the guest needs Ctrl-E, move STOP to a different control key. For example, type
SET CONSOLE stop=1D to use Ctrl-]. The value is the key's control code, from 01
(Ctrl-A) to 1F (Ctrl-_). To use the new key every time, set [console] stop = 0x1D in a
machine file.
Ctrl-E stops the machine and starts the monitor. The guest no longer has the keyboard, and you
type to the monitor. No instruction executes while the monitor runs.
A>
STOP -- the machine is still at CA9C. RUN resumes.
altairsim>
STOP does not change the machine, because STOP is not RESET and not POWER.
The registers, the memory and the disks stay as the guest left them. A bare RUN, with no
address, continues at the instruction that the processor was about to execute. The message
"still at CA9C" tells you this.
How a run ends
A RUN ends when it reaches a breakpoint, or a HLT that no interrupt can end. It always
tells you which. If no board holds the console, the guest does not get the keyboard. To stop
that run, press Ctrl-C.
After a HLT, the processor stays halted until RESET. On a halted processor, RUN,
EXAMINE and DEPOSIT do nothing, as the front-panel switches do. The monitor tells you:
"processor halted at PC=0101 -- RESET ends the halt." The Debugger has the details.
RUN and Ctrl-E are the front panel's RUN and STOP switches. RUN starts the processor. STOP, a
breakpoint or a HLT stops the processor and starts the monitor. The monitor is
available only while the machine is stopped. While the machine runs, the guest has the keyboard
and there is no altairsim> prompt. Every SET, DEPOSIT and EXAMINE acts on a stopped machine. A property never changes during an instruction. No property is locked while the machine
runs, and no property can be set only while it runs.
Speed
By default, the machine runs as fast as the host can run it. clock_hz on the CPU board is
0. For example, a cassette that took 110 seconds on a real Altair loads in about one second.
Type SET cpu0 clock_hz=2000000 to run at the speed of a real 2 MHz Altair. The guest sees the
same result at either speed, because the cassette uses the same number of T-states. The real clock
speed changes how the machine feels, not how it behaves. SHOW cpu0 shows achieved_hz
next to clock_hz. achieved_hz is the clock speed that the run loop reached. You can read it,
but you cannot set it.
A crystal is always kept: at the prompt, from a script, from a pipe and under --mcp. A script
that must be fast leaves clock_hz at 0, or starts with SET cpu0 clock_hz=0. SHOW CLOCK
tells you which: its pacing line reads paced or free.
The speed matters to a guest that measures time against the outside world. An XMODEM transfer
needs the real clock speed, and a cassette does not. For more information, see clock_hz and
idle in the Boards chapter of the User Manual, and see its Troubleshooting chapter.
RESET is not POWER
RESET |
the bus's RESET line. The processor restarts at 0000. Memory stays the same*, and the disks stay mounted. |
POWER |
a power cycle. This is the only command that loses the contents of RAM. It also reads the ROM images again. |
RESET does not clear memory, because RESET on a real Altair did not clear memory. Much period
software needs this behavior.
RESET* is a line on the backplane. It is not an instruction that altairsim does for
you. Every board receives it, and each board does what its real hardware did. The result is different for each board. The memory board clears its bank latch, but it does not change RAM, because a
RAM chip has no reset pin. The floppy controller flushes the sector that it was writing and
deselects the drive.
The 2SIO does nothing, because the 6850 has no reset pin for RESET*. Its baud rate, word
format and interrupt enables stay the same after a reset, as on real hardware. If you type
RESET during a disk write, you get the result that the hardware gave. You get a half-written
sector and a serial port that is still set as the failed guest left it. All of RAM stays the
same.
POWER uses a different line. When the machine powers on, it drives POC* (Power-On
Clear), which is a separate backplane line. A board can respond to POC* and RESET* in
different ways, because the real cards did. The 88-VI/RTC is an example. POC* disables the
board, and RESET* is not connected to it. If a crashed guest left the interrupt controller armed, the controller stays armed after a RESET. Only POWER clears it.
POC* is also the only time when RAM loses its contents. On POWER, the memory board fills RAM
again, with random bytes by default, because static RAM does not start with zeros. It also
reads every ROM image again.
| The processor | The boards | RAM | |
|---|---|---|---|
RESET |
restarts at 0000 |
RESET* on the bus. Each board does what its hardware did, and some do nothing. |
stays the same |
POWER |
restarts at 0000 |
POC* on the bus. Each board starts as it did at power-on. |
filled again, ROMs read again |