If you type “WAIT6502,1” into a Commodore PET with BASIC V2 (1979), it will show the string “MICROSOFT!” at the top left corner of the screen. Legend has it Bill Gates himself inserted this easter egg “after he had had an argument with Commodore founder Jack Tramiel”, “just in case Commodore ever tried to claim that the code wasn’t from Microsoft”.
In this episode of “Computer Archeology“, we will not only examine this story, but also track down the history of Microsoft BASIC on various computers, and see see how Microsoft added a second easter egg to the TSR-80 Color Computer – because they had forgotten about the first one.
Stolen From Apple?
This whole story sounds similar to Apple embedding a “Stolen From Apple” icon into the Macintosh firmware in 1983, so that in case a cloner copies the ROM, in court, Steve Jobs could hit a few keys on the clone, revealing the icon and proving that not just a “functional mechanism” was copied but instead the whole software was copied verbatim.
Altair BASIC
Let’s dig into the history of Microsoft’s BASIC interpreters. In 1975, Microsoft (back then still spelled “Micro-soft”) released Altair BASIC, a 4 KB BASIC interpreter for the Intel 8080-based MITS Altair 8800, which, despite all its other limitations, included a 32 bit floating point library.
An extended version (BASIC-80) that consisted of 8 KB of code contained extra instructions and functions, and, most importantly, support for strings.
Microsoft BASIC for the 6502
In 1976, MOS Technology launched the KIM-1, an evaluation board based around the new 6502 CPU from the same company. Microsoft converted their BASIC for the Intel 8080 to run on the 6502, keeping both the architecture of the interpreter and its data structures the same, and created two versions: an 8 KB version with a 32 bit floating point library (6 digits), and a 9 KB system with 40 bit floating point support (9 digits).
Some sources claim that, while BASIC for the 8080 was 8 KB in size, Microsoft just couldn’t fit BASIC 6502 into 8 KB, while other sources claim there was an 8KB version for the 6502. The truth is somewhere in the middle. The BASIC ROMs of the Ohio Scientific Model 500/600 (KIM-like microcomputer kits from 1977/1978) and the Compukit UK101 were indeed 8 KB in size, but unlike the 8080 version, it didn’t leave enough room for the machine-specific I/O code that had to be added by the OEM, so these machines required an extra ROM chip containing this I/O code.
In 1977, Microsoft changed the 6 digit floating point code to support 9 digits and included actual error stings instead of two-character codes, while leaving everything else unchanged. A 6502 machine with BASIC in ROM needed more than 8 KB anyway, why not make it a little bigger to add extra features. The 6 digit math code was still an assembly time option; the 1981 Atari Microsoft BASIC used that code.
In 1977, Ohio Scientific introduced the “Model 500”, which was the first machine to contain (6 digit) Microsoft BASIC 1.0 in ROM. Upon startup, it printed:
OSI 6502 BASIC VERSION 1.0 REV 3.2 COPYRIGHT 1977 BY MICROSOFT CO. OK
In the same year, MOS started selling a tape version of 9 digit Microsoft BASIC 1.1 for the KIM-1. Its start message was:
MOS TECH 6502 BASIC V1.1 COPYRIGHT 1977 BY MICROSOFT CO. OK
Woz Integer BASIC
The 1976 Apple I was the first system besides the KIM to use the MOS 6502 CPU, but Steve Wozniak wrote his own 4KB BASIC interpreter instead of licensing Microsoft’s. An enhanced version of Woz’ “Integer BASIC” came in the ROM of the Apple II in 1977; Microsoft BASIC (called “AppleSoft”) was available as an option on tape. On the Apple II Plus (1978), AppleSoft II replaced Integer BASIC.
Commodore PET
Commodore had bought MOS in October 1976 and worked on converting the KIM platform into a complete computer system. They licensed Microsoft BASIC for 6502 (also October 1976), renamed it to Commodore BASIC, replaced the “OK” prompt with “READY.”, stripped out the copyright string and shipped it in the ROMs of the first Commodore PET in 1977.
The Easter Egg
In 1979, Commodore started shipping update ROMs with a version 2 of Commodore BASIC for existing PETs. Apart from updates in array handling, it also contained the WAIT 6502 easter egg.
This is what the easter egg code looks like:
.,D710 20 C6 D6 JSR $D6C6 fetch address and value .,D713 86 46 STX $46 save second parameter .,D715 A2 00 LDX #$00 default for third parameter .,D717 20 76 00 JSR $76 CHRGOT get last character .,D71A F0 29 BEQ $D745 no third parameter .,D71C 20 CC D6 JSR $D6CC check for comma and fetch parameter .,D71F 86 47 STX $47 save 3rd parameter .,D721 A0 00 LDY #$00 .,D723 B1 11 LDA ($11),Y read from WAIT address .,D725 45 47 EOR $47 second parameter .,D727 25 46 AND $46 first parameter .,D729 F0 F8 BEQ $D723 keep waiting .,D72B 60 RTS back to interpreter loop
On pre-V2 BASIC, the branch at $D71A just skipped the next line: If there is no third parameter, don’t fetch it. On V2, the line is subtly changed to make the two-parameter case branch to a small patch routine:
.,D745 A5 11 LDA $11 low byte of address .,D747 C9 66 CMP #$66 = low of $1966 (=6502) .,D749 D0 D4 BNE $D71F no, back to original code .,D74B A5 12 LDA $12 high byte of address .,D74D E9 19 SBC #$19 = high of $1966 (=6502) .,D74F D0 CE BNE $D71F no, back to original code .,D751 85 11 STA $11 low byte of screen buffer = 0 .,D753 A8 TAY index = 0 .,D754 A9 80 LDA #$80 high byte of screen buffer .,D756 85 12 STA $12 screen buffer := $8000 .,D758 A2 0A LDX #$0A 10 characters .,D75A BD 81 E0 LDA $E081,X read character .,D75D 29 3F AND #$3F throw away upper bits .,D75F 91 11 STA ($11),Y store into screen RAM .,D761 C8 INY .,D762 D0 02 BNE $D766 no carry .,D764 E6 12 INC $12 increment screen buffer high address .,D766 CA DEX .,D767 D0 F1 BNE $D75A next character .,D769 C6 46 DEC $46 .,D76B D0 EB BNE $D758 repeat n times .,D76D 60 RTS back to interpreter loop
The text “MICROSOFT!” is stored in 10 consecutive bytes at $E082, cleverly hidden after a table of coefficients that is used for the SIN() function:
.;E063 05 6 coefficients for SIN() .;E064 84 E6 1A 2D 1B -((2*PI)**11)/11! = -14.3813907 .;E069 86 28 07 FB F8 ((2*PI)**9)/9! = 42.0077971 .;E06E 87 99 68 89 01 -((2*PI)**7)/7! = -76.7041703 .;E073 87 23 35 DF E1 ((2*PI)**5)/5! = 81.6052237 .;E078 86 A5 5D E7 28 -((2*PI)**3)/3! = -41.3147021 .;E07D 83 49 0F DA A2
6 Comments
dang
Related. Others?
Bill Gates' Personal Easter Eggs in 8 Bit Basic – https://news.ycombinator.com/item?id=30110068 – Jan 2022 (1 comment)
csl
An excellent article. Bill Gates himself posted a comment: https://www.pagetable.com/?p=43#comment-1033
ilrwbwrkhv
Bill gates is the only remaining hacker one can look upto. Yes he was ruthless but also the amount of work he did for humanity was orders of magnitude more than others.
The current crop of rich folks are really the wrong uns and come from a deep history of bad families. Rotten blood really shows.
asadm
I have a question, can something like this survive in today's world? or have the disassembling tools now too advanced to easily wipe something like this when cloning.
amelius
If you copy someone's code, always add a bunch of easter eggs saying the code belongs to company X, Y and Z. Then nobody else can claim it as their own.
OpenLoong
interesting!