I've been spending some time investigating the two Apple I BASIC files in the software list, and I'm now certain that "Apple I Basic" (basic.zip), the one labeled with an Apple part number and clearly recorded from a real cassette, is nevertheless a patched version, while "Apple I Basic (Alt)" (basica.zip), even though it seems to be a modern rerecording, still contains Apple's original code. I think we should keep both versions, but we need to relabel them.
(For those who haven't been able to load basic.zip, see my earlier posting
on how to get it to load.)
The two BASIC images differ in only three areas: $EE53-$EE62, $EEA6-$EEC7, and $EF86-$EFB2; the rest of the code is identical. All three of these differing regions cover handler routines for various BASIC commands.
The first two areas include handlers for some commands which were undocumented in Apple I BASIC and were either disabled or nonfunctional. Some of these are recognizable from the Apple II as Integer BASIC commands; others were apparently abandoned. Wozniak was working on the Apple II design at the same time he was developing his BASIC, and it looks like he was writing the BASIC for both systems using a common code base, disabling certain functions which couldn't work on the Apple I.
The third region covers the handlers for the HIMEM=
commands, which reset the upper and lower bounds of the memory available to BASIC. In Apple I BASIC, these commands could not be included within a program, and they automatically erased any program in memory at the time. However, the basic.zip version has patched the handlers for these commands so that they always preserve the program in memory
In the original version, both commands check to make sure that HIMEM will never be below LOMEM. (LOMEM=
prints an error in this case, but HIMEM=
In the patched version, LOMEM=
checks to make sure that the new value will not overlap the program, and prints an error if it would. Otherwise it resets the LOMEM boundary and clears all variables. HIMEM=
checks to make sure that the new value is not lower (it is impossible to lower the HIMEM boundary with HIMEM=
in this version), and if successful it moves the whole program up to the new HIMEM boundary. This last operation is the most complex of the changes, and it is spread over all three altered regions, overwriting the handlers for the undocumented, nonfunctional commands I already mentioned. These include:
- HIMEM and LOMEM (functions to report the current HIMEM and LOMEM values, not to be confused with HIMEM= and LOMEM=)
- COLOR (a function to report the current drawing color, not to be confused with COLOR=)
- OFF (which became MAN in Integer BASIC, and turns off the automatic line-numbering mode started with the AUTO command)
- HLIN col1 , col2 AT row
- VLIN row1 , row2 AT col
- VTAB row
Even in the original BASIC, none of these commands work properly; some will crash the interpreter.
command "works" but is practically useless, since once AUTO
is activated, every input line gets a line number prefix and is treated as a program line, so the OFF
command (which isn't legal in a program) will be rejected. The documented way to turn AUTO
off is to press Control-D. (There are ways to force OFF
to work; if you cause an input line to be canceled by typing Escape, by deleting all its characters, or by entering too many characters, AUTO
will then be ignored for one input line, so there will be no line number and a non-program command like OFF
will be accepted.)
command is recognized by the parser but obviously required the Apple II's color graphics to work, and it crashes the interpreter due to an improperly terminated token handler.
, and COLOR
functions are also recognized by the parser but don't work right; HIMEM
returns the wrong value, while LOMEM
puts the interpreter in a confused state, and COLOR
(also clearly not applicable to the Apple I) isn't even implemented (it gives a *** RANGE ERR
, but this may be a lucky accident).VLIN
were disabled in the parser's syntax table, so trying to enter them will trigger syntax errors, but their identity can be determined both by their syntax table positions, which determined the token values assigned to them, matching the tokens for Integer BASIC's VLIN
, and by the code in their corresponding token handlers, which likewise matches up with Integer BASIC's VLIN
Since none of these undocumented commands worked, it's obvious why their handlers were chosen to be replaced by the patched version's HIMEM=
There's further evidence pointing to what happened. If I understand correctly, the software list for apple1 was added to MESS in February 2012 by this commit
(with an incorrect dataarea size parameter, fixed soon after), and the recording in basic.zip had been published in MP3 form in July 2008 on Michael Steil's weblog
. Steil reveals that this recording came from Achim Breidenbach, creator of an early Apple I emulator, who in turn got it from a tape from Larry Nelson, one of the early Apple I owners. Likewise, Michael J. Mahon's disassembly
was also created by first loading Achim Breidenbach's disassembly of the version from the Larry Nelson tape. (The code in Mahon's disassembly and the code in basic.zip match, except for a few differing bytes which are clearly errors in Mahon's code.)
Well, while looking up further information on Apple I BASIC and its HIMEM=
commands, at Tom Owad's "Applefritter" website I found two letters sent by Larry Nelson in March 1980
and January 1981
, in which he talks about inoperative areas in the BASIC and putting his own code in there; in the second letter he specifically mentions having changed HIMEM=
... Before that I was working on BASIC.
I've broken a lot of the code and am working
on cleaning out a lot of trash. It looks like
they threw this thing together to get a computer
on the market fast. Probably other used bits
and pieces from other listings, since there
are several places with bad listings. Also found
USR, RNDX, and OFF statements on commands in
there. USR and RNDX don't work, but OFF
turns off the auto-line #. (Try it by typing AUTO 10(r),
then type "escape", then OFF(r)).
We have COLOR=, PLOT, HLIN, too. It adds
up to 120 bytes in there + several commands that
we can't use.
Now, if I can decipher how the ASCII is
coded for each command, I'll have it made! Then
I'll be able to pull out those unused commands and
replace them with something useful.
The INKEY function could be put in
code. The problem is that I've used some of
BASIC empty spots, and now I'm not sure
which places I've filled (HIMEM= and LOMEM=
changes, and that routine to randomize).
I goofed and didn't save a hard copy of
the changes. (I make up for my stupidity with
In the original Apple BASIC, there are
several areas we could put "fixes":
E61C thru E622 = 7 Bytes
E98D " E997 = 11 Bytes
EE3E " EE67 = 37 Bytes (PLOT, COLOR=, OFF commands)
EEA6 thru EECA = 37 Bytes (HLIN, COLOR, Value of HIMEM and
plus another 34 bytes strung over the 4K program in
banks of 6 or less.
Larry Nelson's remarks and interest in improving the BASIC explain a lot. It seems very likely to me that when he provided his Apple I BASIC cassette recording to Achim Breidenbach, the version he provided had his early patches to HIMEM= and LOMEM=. He might even have recorded them on the original cassette, and then forgotten about them; or maybe he just didn't think to mention the changes.
By contrast, another disassembly of Apple I BASIC can be found on Eric Smith's site
; this one clearly came from a different source. Comparing its hexadecimal bytes with the version in basica.zip, they turn out to be byte-for-byte identical.
As I said at the start of this post, I think we should still keep both versions (Larry Nelson's patched version strikes me as itself an interesting historical artifact), but definitely rename and relabel them to better indicate their origins.
I will include direct comparisons of the unpatched and patched code in an additional post in this thread.