45

According to his 1984 interview with Byte magazine, Steve Wozniak created the BASIC for the Apple 1 computer before he actually built the computer:

I sat down and wrote the BASIC first, and that took a lot more time than the computer design. Once it was written, I had to build the computer.

How was this actually done?

  • Was this simply a high-level concept, actual machine code for the 6502, or an actual implementation on a different system?
  • Was the development only on paper, or was a host computer involved (possibly at his work at HP)?
  • Did he test it elsewhere before putting it on the Apple 1?

This question is only about what Wozniak did. The question never was about whether hand-assembly is possible. In all revisions of the question, hand-assembly was always the first option in bullet #2.

Examples of others performing hand assembly does not answer whether Woz did it. Indeed, I have hand-assembled programs myself, so I have first-hand experience that it is possible.

Please stop using this question as a forum on hand assembly. This question is about what Wozniak did in practice.

17
  • 2
    @Raffzahn: I've altered the question, because you seem fixated on the word "possible". I was not implying that it is impossible, as I have done hand assembly myself. It is not difficult to translate opcodes, but my personal experience is that it is all too easy to mis-count at least one branch displacement in a significant portion of code. Thus, I am all the more surprised that a significant amount of untested code would work on the first try.
    – DrSheldon
    Commented Feb 12, 2021 at 5:38
  • 12
    Once upon a time, getting started on the software before you had a computer was the normal way to proceed. And you had to hand-assemble the first assembler. It was uphill in both directions.
    – dave
    Commented Feb 12, 2021 at 12:39
  • 12
    Long before that, Ada Lovelace was writing code for Babbage's analytical engine which was never even built, and there weren't any other computers available at the time either. It's not that far-fetched. Commented Feb 12, 2021 at 14:30
  • 2
    @another-dave It is quite common in embedded applications as well to start writing the firmware before the hardware is finalized. Commented Feb 12, 2021 at 19:05
  • 3
    @another-dave: You'd have a development bootstrapping problem. The assembler itself needs to be assembled, whether by hand or by another assembler, or needs to be written in a language like BASIC. In the BYTE interview, Woz says he originally wanted FORTRAN for his computer, but when someone introduced him to BASIC, he realized that it was a better choice. Makes me wonder how things would have turned out if he had seen FORTH.
    – DrSheldon
    Commented Feb 12, 2021 at 19:39

4 Answers 4

74

TL;DR:

As explained on Steven Weyhrich's great and authoritative Apple II History Site, Wozniak simply sat down and wrote his Integer-BASIC (*1) on paper, while assembling it at the same time by hand. In his own words:

I had no assembler, that was another thing. To use an assembler, they figured that somebody was going to buy this processor to use for a company, and their company can pay a few thousand dollars in time-sharing charges to use an assembler that was available in time-share. I didn’t have any money like that, so a friend taught me that you just sort of look at each instruction, you write your instructions on the right side of the page, you write the addresses over on the left side, and you then look up the hex data for each instruction–you could assemble it yourself. So I would just sit there and assemble it myself. The BASIC, which we shipped with the first Apple II’s, was never assembled – ever. There was one handwritten copy, all handwritten, all hand-assembled. So we were in an era that we could not afford tools.

This quote is taken from a transcription of a speech Wozniak held at he Apple World Convention in 1986. See here for the section about his BASIC.


The Question

Was this simply a high-level concept, actual machine code for the 6502, or an actual implementation on a different system?

Actual machine code on paper for the 6502. (*2,*3)

Was the development only on paper, or was a host computer involved (possibly at his work at HP)?

On paper. A computer was used to test the implementation of the stack machine evaluating expressions. It was written in ALGOL. In addition it is mentioned that he used a HP calculator as well to get used to stack-'thinking'

Did he test it elsewhere before putting it on the Apple 1?

Only on the Apple 1 - they didn't had the money to buy computing time for a cross assembler, as he mentions.


How was this possible?

While it's not a job for an extended weekend, writing a BASIC is not as hard as some may think. To start with, a BASIC is at the core a rather simple program consisting of a few fixed parts like

  • A line editor
  • A cruncher (tokenizer) (*4)
  • A fetch and execute loop
  • An expression evaluator
  • Memory (variable) access
  • (Garbage collection *5)
  • An error handling/output function
  • Startup (cold boot) and recovery (warm boot)

Each of them are rather short tasks and can be written down independent. Some just a few lines, some may require a up to a hundred instructions.

The rest of an interpreter is

  • a collection of functions

One for every BASIC command, every Instruction and every function. They are what the fetch and execute loop calls with every found token, which brings the last two parts:

  • A list of all commands, instructions and functions to be searched and pointing to its entry point
  • A list of error codes/messages

All of these parts are on their own quite manageable on paper and by hand. To give some rough numbers (*6), Integer BASIC occupies 6 KIB of code made up from about 2000 instructions (plus a bunch of tables). With over 50 user visible commands and function this would already average to less than 40 instructions per function. In reality most are way shorter, like PEEK or POKE being 4 instructions each. Even complex one like GOSUB and GOTO are only 14 and 26 instructions.

Programming is about organization of your task, BASIC is not only no exemption to this, but a perfect candidate due the way it operates. Or in his own words:

It was a very efficient approach that broke up a large task in a very orderly way.


*1 - The name Wozniak used, at the time and for the Apple 1, was Apple BASIC, but to a wider audience it was only introduced way later and with some extensions for the Apple II, now named Integer-BASIC. By now the term Apple BASIC is more closely associated with Apple's Microsoft dialect Applesoft. Thus the term Integer-BASIC is used thruout the answer, despite being not all exact.

*2 - Since he did it in 6500 assembly, it can be assumed that this happened after acquiring a first 6502 at Wescon in September 1975. What's interesting is that despite having a 6502 and writing a BASIC in 6500 Assembler he still made the board to accept a 6800 as well.

*3 - 6502 Assembler is rather easy to translate by hand, as every mnemonic plus addressing mode equals a single opcode and parameter encoding can as well be directly made according to addressing mode. No complex encoding to manage, like on a 8086 or 6800.

*4 - Optional, but Woz did add it to save on RAM.

*5 - Usually, but Integer BASIC worked without.

*6 - These numbers are taken from Integer BASIC for the Apple II, which is the only one I had a disassembly at hand). The original Apple 1 BASIC is only 4 KiB and had about a dozend functions less, but the basic considerations match.

17
  • 13
    You make it seem simple. Having written a couple of Lisp interpreters myself, in higher level languages, I think the line editor, the expression evaluator and the variable storage are not really "simple tasks".
    – chthon
    Commented Feb 12, 2021 at 8:38
  • 5
    @chthon Well, LISP's variables model has from the very beginnings been a lot more complex than BASIC's. BASIC had no concept of binding and unbinding, just plain static variables. Commented Feb 12, 2021 at 10:41
  • 7
    @chthon Well, it is. A line editor is simply a routine that takes a line (if there is no OS function to collect a line, it's adding each pressed key to the end of a buffer or removing one if BS is pressed, ending with CR - to be reused for INPUT), checks if there's a number in front, if yes it gets saved, the rest of the line is handed to the cruncher, and if no number handed to the fetch loop, otherwise the line number is used to search for a location and the crunched line inserted there. Done. This can be done in 50-100 instructions. Some tasks are less work in assembly than in a HLL :)
    – Raffzahn
    Commented Feb 12, 2021 at 11:44
  • 19
    I know it sounds implausible today, but I hand-wrote 6502 machine code back in the day, and I'm certainly not that rare. Commented Feb 12, 2021 at 14:16
  • 14
    I feel a surreal mixture of awe, envy and pity. Commented Feb 12, 2021 at 14:20
40

One thing is certain: Steve Wozniak was very good at hand assembling 6502. Instead of writing assembler mnemonics he could simply type in the necessary hex code.

I realize this isn't a proper answer but this anecdote is simply too good to relegate to a comment. It comes from Bill Atkinson remarking on Steve doing some assembler work:

The other thing that happened then is I had to plug in the disk routines, and their system was pretty big and that little 13-sector floppy disk didn't have a lot of capacity. Well, Woz had just come up with a different way of encoding the data on the disk so that we could get more data for the same disk size, and we needed the 16-sector disk routines. And so Woz came down, and I was there... I had never bothered to get a motel because I slept on the bench when I wasn't working. This is in the computer science lab at UC San Diego. I was busy, I didn't have time to go sleep.

But Woz came down, and I got to interact with him and it was really fun because he was working on installing these 16-sector disk driver routines, and he'd go 'type type type type type' -- and he didn't type in assembly language and have it assembled. No, he'd type in 6502 machine code. Hex. -- He'd type in hex, and then, you know, watching him type and he'd go 'type type type' -- pause -- 'type type type type', and when he finished I asked him what was the pause? And he said "forward branch, seven instructions, I had to compute the offset before I continued". So, he didn't back-patch the offset, he actually looked at what he was going to be typing, knew how many bytes it would take... he was brilliant.

From an interview: https://youtu.be/6tUWoy1tJkE?t=45m

I've borrowed this wholesale from: https://news.ycombinator.com/item?id=14824949

2
  • 8
    I suppose when you do antyhing enough, you get extremely good at it. Commented Feb 12, 2021 at 12:10
  • 3
    I got to see Woz speak once a few years ago. The guy is just on a different level from the rest of us. Absolutely brilliant engineer.
    – Seth R
    Commented Feb 12, 2021 at 16:13
13

Woz was exceptional, but not the only one with this (moderate level of ?) skill in machine language. Lots of teens/kids learned to poke (from Basic) absolute hex machine code into memory on several models of personal computers (not just the Apple I/II). I knew some who could speak out-loud a small subroutine in hex for the 6502, no assembly language or even paper coding form needed.

As for needing a computer to code, also not true. Tons of computer programming was done, not only in the 8-bit era, but in the punch card era on paper coding sheets, and hand assembled. Some programmers needed to debug their (Edsac, Manchester, Bendix, et.al.) code when the first run(s) failed. But a non-zero number of programmers did not, since the turn-around cost was high enough that some just hand checked their code sufficient to not have off-by-one branching errors, etc.

There are lots of lost arts due to modern technologies.

4
  • 2
    And a lot of BASICs didn't even have hex, so many were pretty good at writing these things in decimal
    – Artelius
    Commented Feb 13, 2021 at 0:23
  • 4
    I think this is the first time I've seen "lost arts due to modern technologies" applied to 70s/80s computer skills, and not, y'know, blacksmithing or firestarting or swordfighting or… Commented Feb 13, 2021 at 6:24
  • 3
    @DrSheldon The question has already been answered in full by another user; I don't think there's anything wrong with adding on with corrections, information, etc. that readers might find interesting, and that wouldn't fit well in comments.
    – yeah22
    Commented Feb 14, 2021 at 6:16
  • 3
    This does not answer the question, which is about what Wozniak did.
    – DrSheldon
    Commented Feb 14, 2021 at 16:11
1

I would like to note that it was the hand-entered code that ultimately did in Integer BASIC.

Jobs demanded floating point for the II, and although Woz had already written an FP library by that point, it had to be integrated into IB. It was simpler to just use the MS code they had licensed, as it was in assembler and somewhat documented, so porting their graphics code into that was easier than back-porting FP into Integer by hand-entering hex.

Which is sad, because had they done that I have zero doubt that we would have been using string slicing instead of MS's abysmal MID/LEFT/RIGHT. Every other BASIC I can find from that era uses slicing, only the PET used MS at the time, everyone else had their own variety.

8
  • Aside from the fact that the garbage collector was designed to be compact rather than efficient, what's wrong with the MS approach? It could have been improved perhaps with a function to compute mid$(a$, s, e-s) without having to repeat s, or to compute mid$(a$, s, 1) without having to evaluate the 1, but for many tasks it seems as or more convenient than the slicing approach used by e.g. HP BASIC.
    – supercat
    Commented Nov 15, 2021 at 18:10
  • @supercat - slicing does not produce a new string, just a pointer. MS functions create new strings. slicing uses less memory, is much faster, and doesn't eat up RAM. Commented Nov 16, 2021 at 14:31
  • Slicing requires that one know in advance the lengths of strings one will be using, or waste memory on oversized reservations. MS actually gets by with a very low memory footprint if the time spent on GC isn't a concern, and spending a little more effort and ROM space for the GC code would have made it possible to enormously improve its efficiency, especially if string literals (and other strings) had been stored prefixed by length or one were willing to waste a byte per allocation (if only strings with length of at least one were kept in memory, the length byte would suffice).
    – supercat
    Commented Nov 16, 2021 at 15:47
  • How efficiently could string-slicing BASICs hold e.g. a list of 100 strings with an average length of 8 but a maximum length of 32? In MS-BASIC, that would take 1100 bytes, but from what I understand in string-slicing dialects it would take 3200.
    – supercat
    Commented Nov 16, 2021 at 16:01
  • Atari BASIC parses everything at edit time, not runtime. As part of this process, it removes quotes from string constants and places a two-byte length token at the front. So the space is exactly that of the original constants, or in this case, 800 bytes. Perhaps I do not understand what you are asking. Commented Nov 17, 2021 at 12:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .