In February 2017, I visited Living Computers: Museum + Labs (LCM+L) and had a great time trying the various machines available. One of the systems in the vintage computers collection is the MITS Altair 8800, which is connected to a teletype. During my visit, I typed in two short BASIC programs, and was delighted to find that they ran well and made a tremendous noise on the teletype.
This is my attempt to better understand the Altair.
Table of contents:
A few simulators are available for the Altair. Here are the best two I’ve used:
Also available:
Which simulator you choose will depend on your need. If you like to visually see and manipulate the Altair front panel, perhaps altairsim is the best choice. If you need a “headless” system, perhaps altairz80 will suit better. (For reasons explained later, I think altairz80 is a better choice than SIMH altair.)
Also worth mentioning is the availability of the Altair 8080 Clone computer, by Mike Douglas. This remarkable device is a “fully functional replica” of the Altair 8800, using modern hardware on the inside. Mr Douglas has also provided a wealth of information, software, and excellent videos demonstrating the features of the Altair, which he makes available free of charge on his website.
This is my favourite Altair emulator, because I like watching the graphical front panel whilst computerizing. It should run on any system which has some UNIX and X support. altairsim comes with Makefiles for BSD, Cygwin (Windows), Linux, OS X, and Solaris.
First download and compile altairsim for your particular platform. Here is an example from OS X 10.11 (“El Capitan”).
Download and extract the software, then build the frontpanel component:
% curl -sO http://www.autometer.de/unix4fun/z80pack/ftp/z80pack-1.36.tgz % tar zxf z80pack-1.36.tgz % cd z80pack-1.36/frontpanel % make -f Makefile.osx [...] g++ ‑shared ‑L/usr/X11/lib ‑L/usr/local/lib ‑ljpeg ‑lGL ‑lGLU ‑lX11 jpeg.o lpanel.o lp_gfx.o lp_main.o lp_utils.o lp_window.o lp_switch.o lp_font.o lp_materials.o ‑o libfrontpanel.dylib Be sure to copy libfrontpanel.dylib to a shared library path!
Next, link the libfrontpanel.dylib file to the destination directory of the altairsim binary, and build the altairsim binary itself:
% cd ../altairsim % ln -s ../frontpanel/libfrontpanel.dylib % cd srcsim % make -f Makefile.osx [...] gcc sim0.o sim1.o sim1a.o sim2.o sim3.o sim4.o sim5.o sim6.o sim7.o simctl.o simint.o memory.o iosim.o simfun.o simglb.o unix_terminal.o unix_network.o config.o altair‑88‑sio.o altair‑88‑2sio.o tarbell_fdc.o cromemco‑dazzler.o proctec‑vdm.o ‑L../../frontpanel ‑L/usr/local/lib ‑L/opt/X11/lib ‑lfrontpanel ‑ljpeg ‑lGL ‑lGLU ‑lX11 ‑o ../altairsim Done.
The final preparatory step is to disable the Tarbell bootstrap ROM (via the tarbell_rom_enabled setting in conf/system.conf), as it will interfere with the normal boot-up sequence. (It’s possible to leave it enabled using a slightly different start-up sequence – see the later subsection.)
% cd ../conf % mv system.conf system.conf.bak % sed 's,^tarbell_rom_enabled,#tarbell_rom_enabled,' system.conf.bak > system.conf % cd .. %
Now altairsim is ready to use! Let’s load 4K BASIC, version 3.2:
% ./altairsim -x basic4k32.hex ##### ### ##### ### ##### ### # # # # # # # # # # # # # ## ## # # # # # # # # # # # # # # ##### # # ##### # # ##### ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##### ### ##### ### ##### ### # # Release 1.36, Copyright (C) 1987-2017 by Udo Munk Altair 8800 Simulation Release 1.17, Copyright (C) 2008-2017 by Udo Munk CPU speed is 2 MHz RAM size 252 pages, 0000H - fbffH ROM size 4 pages, fc00H - ffffH Boot switch address at fe00H Loader statistics for file basic4k32.hex: START : 0000H END : 0fffH LOADED: 1000H (4096) FrontPanel Simulator v2.1 Copyright (C) 2007-2015 by John Kichury
At this point, the front panel should hopefully open on the screen:
To start BASIC, click the ON switch to turn the Altair on; the terminal screen will clear, and the blinkenlights will illuminate (but not blinken just yet). Next, click RUN; this will begin execution at address 0. If all went well, BASIC will start, and you will see the following at the terminal:
MEMORY SIZE? [Enter] TERMINAL WIDTH? [Enter] WANT SIN? Y 61143 BYTES FREE BASIC VERSION 3.2 [4K VERSION] OK
The obligatory(?) “Hello, World!”-type program:
10 PRINT "HELLO, WORLD!" RUN HELLO, WORLD! OK
When you’re through with BASIC (or BASIC is through with you), just click the OFF switch to terminate altairsim. It will give you a parting shot:
System powered off, bye.
And that’s it! The same procedure works for 4K BASIC, version 4.0 (basic4k40.hex), and 8K BASIC versions 3.2, 4.0, and ’78 (basic8k32.hex, basic8k40.hex, and basic8k78.hex, respectively).
4K 3.2 4K 4.0 8K 3.2 8K 4.0 8K ’78 MEMORY SIZE? TERMINAL WIDTH? WANT SIN? Y 61143 BYTES FREE BASIC VERSION 3.2 [4K VERSION] OK MEMORY SIZE? TERMINAL WIDTH? SIN? Y 61132 BYTES FREE 4K BASIC 4.0 COPYRIGHT MITS 1976 OK MEMORY SIZE? TERMINAL WIDTH? WANT SIN-COS-TAN-ATN? Y 58440 BYTES FREE ALTAIR BASIC VERSION 3.2 [EIGHT-K VERSION] OK MEMORY SIZE? TERMINAL WIDTH? WANT SIN-COS-TAN-ATN? Y 57988 BYTES FREE ALTAIR BASIC REV. 4.0 [EIGHT-K VERSION] COPYRIGHT 1976 BY MITS INC. OK 11704 BYTES FREE BASIC, Version of 02/03/78 START OK *
There is a slight wrinkle when loading version 1.0, however: BASIC 1.0 expects an SIO rev 0 board. There are two strategies for dealing with this, both relatively straightforward.
The easiest solution if using altairsim is to emulate a rev 0 board instead of the default rev 1 board. To do that, change the sio0_revision option in conf/system.conf from a 1 to a 0:
% cd conf % mv system.conf system.conf.bak % sed 's,^\(sio0_revision[^0-9]*\)[0-9]$,\10,' system.conf.bak > system.conf % cd ..
Now BASIC 1.0 should load:
% ./altairsim -x basic4k10.hex ##### ### ##### ### ##### ### # # # # # # # # # # # # # ## ## # # # # # # # # # # # # # # ##### # # ##### # # ##### ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##### ### ##### ### ##### ### # # Release 1.36, Copyright (C) 1987-2017 by Udo Munk Altair 8800 Simulation Release 1.17, Copyright (C) 2008-2017 by Udo Munk CPU speed is 2 MHz RAM size 252 pages, 0000H - fbffH ROM size 4 pages, fc00H - ffffH Boot switch address at fe00H Loader statistics for file basic4k10.hex: START : 0000H END : 11deH LOADED: 11dfH (4575) FrontPanel Simulator v2.1 Copyright (C) 2007-2015 by John Kichury MEMSIZ? 8192 WANT SIN-COS-ATN? Y 3712 BYTES FREE 8080 BASIC VER 1.0 READY
Note that I entered 8192 for the memory size rather than just hit Enter; the memory size detection code wasn’t included in BASIC 1.0. (Thanks to Altair 8800 - Video #32 for this tip.)
The previous solution is simple, however it changes the configuration of altairsim for all programs. There is another option: patch BASIC to work ‘natively’ with a rev 1 SIO board. This has already been done by Mike Douglas (of Altair 8800 Clone fame); all that remains is to convert the punched tape file into an Intel HEX file which altairsim can load.
To convert binary files to Intel HEX, I’m using the intelhex Python library. Here’s how I did it:
First, download the BASIC 1.0 tape, and the intelhex package, then extract it. I don’t plan to keep the intermediate work, so I’m doing all this from a personal tmp directory.
% cd ~/tmp % curl -s -o basic10.tap http://altairclone.com/downloads/basic/Paper%20Tape%20and%20Cassette/BASIC%20Ver%201-0.tap % curl -sO https://pypi.python.org/packages/01/66/8fab869edcc0eaf8fc030472ff379b8eeee2ef3b42f8aec6bd84e9f735e3/intelhex-2.2.1.tar.gz % tar zxf intelhex-2.2.1.tar.gz
The accompanying documentation for the patched BASIC 1.0 tape says: “…the tape is pretty much just a binary dump of BASIC from memory. The image is preceded by a string of NULLs for leader and a sync byte of 6Ah to mark the start of the memory image.“ So it’s necessary to trim some bytes from the first part of the tape, essentially everything up to and including the first 0x6a byte.
The first chunk of the tape looks like this:
% hexdump -C basic10.tap | head -3 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000010 00 00 00 00 00 00 00 00 00 00 00 6a c3 7e 10 00 |...........j.~..| 00000020 00 00 00 00 e3 be 23 e3 c2 61 05 7f c5 7e 23 fe |......#..a...~#.|
The 0x6a byte is clearly visible at position 0x1c, or 28 in decimal. So that is how many bytes need to be trimmed. Do that with dd and check the result – it should begin with 0xc3:
% dd if=basic10.tap of=basic10.bin bs=1 skip=28 4480+0 records in 4480+0 records out 4480 bytes transferred in 0.013439 secs (333360 bytes/sec) % hexdump -C basic10.bin | head -3 00000000 c3 7e 10 00 00 00 00 00 e3 be 23 e3 c2 61 05 7f |.~........#..a..| 00000010 c5 7e 23 fe 20 c3 18 05 e6 7f c3 d4 03 00 00 00 |.~#. ...........| 00000020 7c 92 d8 c0 7d 93 c9 00 00 00 00 00 00 00 00 00 ||...}...........|
Convert the resulting file into Intel HEX format:
% PYTHONPATH=intelhex-2.2.1 python intelhex-2.2.1/scripts/bin2hex.py basic10.bin basic10.hex % head -3 basic10.hex :10000000C37E100000000000E3BE23E3C261057F51 :10001000C57E23FE20C31805E67FC3D4030000007D :100020007C92D8C07D93C900000000000000000051
Perfect! You can even see the first byte is 0xc3. Try it out with altairsim, leaving sio0_revision at 1 in conf/system.conf:
% cp basic10.hex ~/z80pack-1.36/altairsim % cd ~/z80pack-1.36/altairsim % grep ^sio0_revision conf/system.conf sio0_revision 1 % ./altairsim -x basic10.hex ##### ### ##### ### ##### ### # # # # # # # # # # # # # ## ## # # # # # # # # # # # # # # ##### # # ##### # # ##### ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##### ### ##### ### ##### ### # # Release 1.36, Copyright (C) 1987-2017 by Udo Munk Altair 8800 Simulation Release 1.17, Copyright (C) 2008-2017 by Udo Munk CPU speed is 2 MHz RAM size 48 pages, 0000H - 2fffH Boot switch address at 0000H Loader statistics for file basic10.hex: START : 0000H END : 117fH LOADED: 1180H (4480) FrontPanel Simulator v2.1 Copyright (C) 2007-2015 by John Kichury MEMSIZ? 8192 WANT SIN-COS-ATN? Y 3712 BYTES FREE 8080 BASIC VER 1.0 READY
(Thanks to Udo Munk for providing detail about how this works in a post to comp.os.cpm on 24 May 2018.)
There may be cases where you’d like to keep the Tarbell bootstrap ROM enabled; perhaps you are using disk-based systems with some regularity and don’t want to have to turn it off to load “diskless” BASIC. There is a way to disable the bootstrap ROM and thus load BASIC.
Essentially the trick is to read some data outside of the ROM addresses, that is, addresses greater than 0x1f (octal 037). This disables the shadow ROM, which effectively ‘unhides’ the BASIC that was loaded at RAM address 0.
The full procedure looks like this:
% ./altairsim -x basic4k32.hex ##### ### ##### ### ##### ### # # # # # # # # # # # # # ## ## # # # # # # # # # # # # # # ##### # # ##### # # ##### ##### # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ##### ### ##### ### ##### ### # # Release 1.36, Copyright (C) 1987-2017 by Udo Munk Altair 8800 Simulation Release 1.17, Copyright (C) 2008-2017 by Udo Munk CPU speed is 2 MHz RAM size 32 pages, 0000H - 1fffH Loader statistics for file basic4k32.hex: START : 0000H END : 0fffH LOADED: 1000H (4096) FrontPanel Simulator v2.1 Copyright (C) 2007-2015 by John Kichury
MEMORY SIZE? [Enter] TERMINAL WIDTH? [Enter] WANT SIN? Y 4823 BYTES FREE BASIC VERSION 3.2 [4K VERSION] OK
If you’re looking for a headless (text-only) emulator, I recommend altairz80. It has the added bonus of the familiar SIMH interface, so if you’re used to other SIMH-based emulators, you’ll feel right at home with this one.
As I already had SIMH installed for other platforms, I won’t go over the installation process here in any great detail. On OS X / macOS, it’s as simple as installing Homebrew, then running:
% brew install simh
Once installed, you’ll need some software to run. Unlike altairsim, which reads Intel HEX files, altairz80 reads raw binary images. Here are two places to get software:
Of course, you can use software from anywhere, including the Z80pack, though you may need to do some file format conversion.
Here’s an example session of downloading the software pack, and launching 4K BASIC, version 3.2:
% curl -sO https://schorn.ch/cpm/zip/altsw.zip % unzip -qd altsw altsw.zip % cd altsw % altairz80 bas432 Altair 8800 (Z80) simulator V3.9-0 4096 bytes [16 pages] loaded at 0. MEMORY SIZE? [Enter] TERMINAL WIDTH? [Enter] WANT SIN? Y 61911 BYTES FREE BASIC VERSION 3.2 [4K VERSION] OK [Control-E] Simulation stopped, PC: 00386 (JZ 0382h) sim> exit Goodbye %
The file bas432 contains all of the necessary SIMH commands to load and start 4K BASIC 3.2:
% grep -v ^\; bas432 set cpu 8080 set cpu noitrap set sio ansi set sio upper set cpu altairrom l 4kbas32.bin 0 d sr 8 g 0
SIMH users will be familiar with the syntax here. The script sets a few CPU and SIO options, loads the image starting at address 0, deposits 8 at the switch register (that is, sets the sense switch 11 on the front panel), and begins execution at address 0. The switch register setting selects the I/O board type for the console, in this case a 2SIO board.
The bas440 script loads 4K BASIC 4.0 and bas8 loads 8K BASIC 4.0. Technically the d sr 8 command isn’t necessary with 4K or 8K BASIC 4.0, as they default to the 2SIO board. However, raising sense switch 11 has no ill effect.
The documentation for altairz80 is quite good, and covers the above procedure and many others.
To run 8K BASIC 3.2, convert from the Intel HEX file shipped with altairsim. For example:
% cd ~/tmp % PYTHONPATH=intelhex-2.2.1 python intelhex-2.2.1/scripts/hex2bin.py ~/z80pack-1.36/altairsim/basic8k32.hex ~/altsw/8kbas32.bin % cd ~/altsw % sed 's,8kbas\.bin,8kbas32.bin,' bas8 > bas832 % altairz80 bas832 Altair 8800 (Z80) simulator V3.9-0 8192 bytes [32 pages] loaded at 0. MEMORY SIZE? [Enter] TERMINAL WIDTH? [Enter] WANT SIN-COS-TAN-ATN? Y 59208 BYTES FREE ALTAIR BASIC VERSION 3.2 [EIGHT-K VERSION] OK [Control-E] Simulation stopped, PC: 004DF (JZ 04DBh) sim> exit Goodbye %
To run BASIC 1.0, you must change the SIO port to the one used by the SIO Rev 1 board:
% cat << EOF > bas10 heredoc> reset cpu heredoc> set cpu 8080 heredoc> set cpu noitrap heredoc> set cpu altairrom heredoc> set sio ansi heredoc> set sio upper heredoc> set sio port=00/0/00/01/00/f/00/f heredoc> set sio port=01/0/00/00/00/f/00/t heredoc> l bas10.bin 0 heredoc> g 0 heredoc> EOF % altairz80 bas10 Altair 8800 (Z80) simulator V3.9-0 4480 bytes [18 pages] loaded at 0. MEMSIZ? 8192 WANT SIN-COS-ATN? Y 3712 BYTES FREE 8080 BASIC VER 1.0 READY [Control-E] Simulation stopped, PC: 003F1 (IN 00h) sim> exit Goodbye %
That set sio port bit was a bit of a head-scratcher. Initially I was just guessing at values until I got the MEMSIZ? prompt. Eventually I found an explanation that made sense to me in the 88-SIO manual, p. 2 (PDF p. 3). The table provided is this:
Data bit Logic low level Logic high level 7 Output device Ready (a ready pulse has been sent from the device).
Also causes a hardware interrupt to occur if interrupt enabled.Not Ready 6 (not used) (not used) 5 Data Available (a word of data is in the buffer on the I/O board) 4 Data Overflow (a new word of data has been received before the previous word was inputted to the accumulator) 3 Framing Error (data word has no valid stop bit) 2 Parity Error (received parity does not agree with selected parity) 1 X-mitter Buffer Empty (the previous data word has been X-mitted and a new data word may be outputted) 0 Input device Ready (a ready pulse has been sent from the device)
Here’s the breakdown of how that translates to the set sio port instructions. The first command sets up the control port:
set sio port=00/0/00/01/00/f/00/fPORT The two ports are 0 and 1 (as given by the table below). A snippet of the altairz80 SIO source gave me the clue that there are separate addresses for the control port (0) and the data port (1). set sio port=00/0/00/01/00/f/00/fREAD Which bits are set when the device is ready for reading? Bit 0 is set low (0), therefore this entire field is zero. set sio port=00/0/00/01/00/f/00/fNOT READ Which bits are set when the device is not ready for reading? That is the inverse of the above, ie bit 0 set high (1). set sio port=00/0/00/01/00/f/00/fWRITE Which bits are set when the device is ready for writing? Bit 7 is set low (0), therefore this entire field is zero. set sio port=00/0/00/01/00/f/00/fDATA This is not a data port, hence f for False.
And the second command sets up the data port:
set sio port=01/0/00/00/00/f/00/tPORT This is the data port (1). According to the 88-SIO manual, data ports are odd-numbered. set sio port=01/0/00/00/00/f/00/tDATA This is a data port, hence t for True.
This was all done using the SIO Rev 1-compatible image (patched by Mike Douglas), but you could theoretically use the original SIO Rev 0-compatible image, provided you found the right SIO port settings for altairz80.
First, convert the image using hex2bin.py (similar to 8K BASIC 3.2):
% cd ~/tmp % PYTHONPATH=intelhex-2.2.1 python intelhex-2.2.1/scripts/hex2bin.py ~/z80pack-1.36/altairsim/basic8k78.hex ~/altsw/8kbas78.bin % cd ~/altsw
Then make a new SIMH script for it. The trick here is to set the load and execute address to 0x100:
% cat << EOF > bas878 heredoc> reset cpu heredoc> set cpu 8080 heredoc> set cpu noitrap heredoc> set cpu altairrom heredoc> set sio ansi heredoc> set sio upper heredoc> l 8kbas78.bin 100 heredoc> g 100 heredoc> EOF % altairz80 bas878 Altair 8800 (Z80) simulator V3.9-0 8493 bytes [34 pages] loaded at 100. 11704 BYTES FREE BASIC, Version of 02/03/78 START OK * [Control-E] Simulation stopped, PC: 0011E (PUSH H) sim> exit Goodbye %
You can see that it’s 0x100 by examining the HEX file (address marked in red):
% head -1 ~/z80pack-1.36/altairsim/basic8k78.hex :20010000C39B21C36107DB10E602CA060179D311C9DB10E601C8DB1137C9C9C9C5D5E5CD07
The first Altair 8800 emulator written for SIMH, simply called altair is a bit simpler than altairz80. The documentation for altair is also somewhat sparse. It seems that this emulator hasn’t been updated recently; the last material change to the source was around April 2012, about six years ago at the time of this writing.
However, using information gained from experiences with altairsim and altairz80, it’s possible to get altair to boot various versions of Altair BASIC and, with a patch, even make it somewhat usable.
Generally speaking, altair starts up with the options you need, thus the SIMH script is quite short:
% cd ~/altsw % cat << EOF > abas440 heredoc> set 2sio ansi heredoc> l 4kbas40.bin heredoc> g 0 heredoc> EOF % cat << EOF > abas8 heredoc> set 2sio ansi heredoc> l 8kbas.bin heredoc> g 0 heredoc> EOF % altair abas440 Altair 8800 simulator V3.9-0 3833 Bytes loaded. MEMORY SIZE? [Enter] TERMINAL WIDTH? [Enter] SIN? Y 62156 BYTES FREE 4K BASIC 4.0 COPYRIGHT MITS 1976 OK [Control-E] Simulation stopped, PC: 001627 (JZ 1623) sim> exit Goodbye % altair abas8 Altair 8800 simulator V3.9-0 8192 Bytes loaded. MEMORY SIZE? [Enter] TERMINAL WIDTH? [Enter] WANT SIN-COS-TAN-ATN? Y 59012 BYTES FREE ALTAIR BASIC REV. 4.0 [EIGHT-K VERSION] COPYRIGHT 1976 BY MITS INC. OK [Control-E] Simulation stopped, PC: 002530 (ANI 1) sim> exit Goodbye %
All is not well, however, in BASIC land. Begin entering a program and you’ll soon see:
OK 10 DIM X(10) 20 PRINT LIST 10 ?IM X(10) 20 ?RINT OK
Hmmm. Looks like the first character of each line has the high bit (0x80) set. But isn’t set 2sio ansi supposed to take care of that?
The answer is: yes. However, it seems that the ansi option was created in the altair emulator without actually implementing it!
Apply the following patch to the altair_sio.c file, and the set 2sio ansi will do what it is supposed to do:
% diff -u altair_sio.c{.orig,} --- altair_sio.c.orig 2012-03-25 11:51:14.000000000 -0700 +++ altair_sio.c 2018-03-09 22:38:54.000000000 -0800 @@ -207,7 +207,7 @@ sio_unit.u3 = sio_unit.u3 > 0xFE; return (sio_unit.buf); } else { - sim_putchar(data); + sim_putchar(sio_unit.flags > UNIT_ANSI ? data & 0x7f : data); } return 0; }
Recompile it, etc, and then:
OK 10 DIM X(10) 20 PRINT LIST 10 DIM X(10) 20 PRINT OK
Et voilà !
I’ve noticed that, with the SIMH altair emulator, pasting code into BASIC can be a bit flaky. Generally the more complex a line is, the more likely the following line is to be missing characters at the beginning.
For example, if you paste lines 260 and 270 from Hunt the Wumpus (4K BASIC edition), you can see it in action:
OK 260 LET M(J)=INT(1+RND(1)*20) 0 NEXT J LIST 0 NEXT J 260 LET M(J)=INT(1+RND(1)*20) OK
Although I pasted 260 and 270, the ‘27’ part was chopped off. The statements execute out of order and, if there had been a line 0, it would’ve been clobbered.
Google says that iTerm2 on OS X / macOS can be used to slow down pastes. Probably other terminals do similar things. My suggestion, though, would be to just use altairz80 instead.
As with altairz80, the trick to getting BASIC ’78 to load is to put it at location 0x100 (octal 400):
% printf 'd pc 400\nl 8kbas78.bin\ng 400\n' > abas878 % altair abas878 Altair 8800 simulator V3.9-0 8493 Bytes loaded. 11704 BYTES FREE BASIC, Version of 02/03/78 START OK * [Control-E] Simulation stopped, PC: 000436 (PUSH H) sim> exit Goodbye %
Note the slightly different syntax to load binary data at an arbitrary position in memory; you deposit an address into the PC manually, then load.
As far as I can tell, ’78 BASIC doesn’t do funny things with the high-order bit. It also plays nice with altair when pasting text.
[Still an unsolved mystery, I’m afraid. I think for BASIC 1.0, you’d have to patch BASIC to use 2SIO, as the SIO Rev 0 and Rev 1 boards are not available in altair. For BASIC 3.2, setting sense switch 11 ought to do the trick, but does not. Requires more cogitation…]
There were three things that helped me to understand the purpose of the sense switches for I/O board configuration:
Here’s a close-up shot of the Altair 8800 sense switches:
Depositing decimal 8 (octal 10) into the sense register causes 11 to go high. And, according to the tables within the help file for Altair32, this tells 4K BASIC that a 2SIO board is present:
BASIC Configuration Settings (4K BASIC) Hardware Terminal Switches Octal Channel Status Bits Active Octal Masks SIOA, B, C (not Rev 0) (none) 0, 1 low 1/200 acr a15 6, 7 low 1/200 SIOA, B, C (Rev 0) a14 0, 1 high 40/2 88-pio a13 0, 1 high 2/1 4pio a12 20, 21 high 100/100 2sio a11 (A10 up=1stop; down=2stop) 20, 21 high 1/2 Note: Use the “ACR” setting when loading the paper tape or cassette using the toggle loader. Once BASIC starts then change the sense switches to the 2sio position.
Here is the table for 8K BASIC:
BASIC Configuration Settings (8K and Extended BASICs) Hardware Sense Switch Setting Terminal Switches Load Switches Channels/Device (octal) 2sio 0 (none) (none) 20, 21 (2 stop bits) 2sio 1 a12 a8 20, 21 (1 stop bit) sio 2 a13 a9 0, 1 acr 3 a13, a12 a9, a8 6, 7 4pio 4 a14 a10 40, 41, 42, 43 pio 5 a14, a12 a10, a8 4, 5 hsr 6 a14, a13 a10, a9 46, 47 non-standard terminal a14 (none) (none) no terminal a15 (none) (none) Note: Use the “ACR” setting when loading the paper tape or cassette using the toggle loader. BASIC will automatically start without having to change the sense switches to the 2sio position.
Notice that, according to the Altair32 help file, switch 11 is unused for 8K BASIC. [This needs some verification.]
Feel free to contact me with any questions, comments, or feedback.