{"id":774,"date":"2015-01-13T12:00:45","date_gmt":"2015-01-13T20:00:45","guid":{"rendered":"http:\/\/www.pagetable.com\/?p=774"},"modified":"2015-01-13T12:00:45","modified_gmt":"2015-01-13T20:00:45","slug":"microsoft-basic-for-6502-original-source-code","status":"publish","type":"post","link":"https:\/\/www.pagetable.com\/?p=774","title":{"rendered":"Microsoft BASIC for 6502 Original Source Code [1978]"},"content":{"rendered":"<p>This is the original 1978 source code of Microsoft BASIC for 6502 with all original comments, documentation and easter eggs:<\/p>\n<p><iframe loading=\"lazy\" width=\"100%\" height=\"300\" src=\"docs\/M6502.MAC.txt\">bah<\/iframe><\/p>\n<p><a href=\"docs\/M6502.MAC.txt\">M6502.MAC<\/a> (1978-07-27, 6955 lines, 161,685 bytes)<\/p>\n<p>This is currently the oldest publicly available piece of source written by Bill Gates.<\/p>\n<h2>Language<\/h2>\n<p>Like the 8080 version, the 6502 version was developed on a PDP-10, using the MACRO-10 assembler. A set of macros developed by Paul Allen allowed MACRO-10 to understand and translate 6502 assembly, albeit in a modified format to fit the syntax of macros, for example:<\/p>\n<table border=\"1\">\n<tr>\n<th>MOS 6502<\/th>\n<th>MACRO-10<\/th>\n<\/tr>\n<tr>\n<td><tt>LDA #0<\/tt><\/td>\n<td><tt>LDAI 0<\/tt><\/td>\n<\/tr>\n<tr>\n<td><tt>LDA (ADDR),Y<\/tt><\/td>\n<td><tt>LDADY ADDR<\/tt><\/td>\n<\/tr>\n<\/table>\n<p>MACRO-10 did not support hex numbers, which is why most numbers are in decimal format. In the floating point code, all numbers are octal. The <tt>RADIX<\/tt> statement switches between the two. Octal can also be forced with a <tt>^O<\/tt> prefix.<\/p>\n<p>Conditional translation is done using the <tt>IFE<\/tt> and <tt>IFN<\/tt> statements, which test whether the argument is zero. The following only adds the string to the binary if <tt>REALIO<\/tt> is equal to 4:<\/p>\n<pre>\nIFE     REALIO-4,&lt;DT\"APPLE BASIC V1.1\"&gt;\n<\/pre>\n<h2>Macros<\/h2>\n<p>The source defines many macros that make development easier. There are some examples:<\/p>\n<table border=\"1\">\n<tr>\n<th>Macro<\/th>\n<th>Definition<\/th>\n<th>Comment<\/th>\n<\/tr>\n<tr>\n<td><tt>SYNCHK (Q)<\/tt><\/td>\n<td><tt>LDAI &lt;Q&gt;<br \/>JSR SYNCHR<\/tt><\/td>\n<td>Get the next character and make sure it&#8217;s <tt>Q<\/tt>, otherwise <tt>SYNTAX ERROR<\/tt>. This pattern is used a lot.<\/td>\n<\/tr>\n<tr>\n<td><tt>LDWD (WD)<\/tt><\/td>\n<td><tt>LDA WD<br \/>LDY &lt;WD&gt;+1<\/tt><\/td>\n<td>Most 16 bit constants are loaded into A\/Y with this macro, but macros for A\/X and X\/Y also exist.<\/td>\n<\/tr>\n<tr>\n<td><tt>LDWDI (WD)<\/tt><\/td>\n<td><tt>LDAI &lt;&lt;WD&gt;&amp;^O377&gt;<br \/>LDYI &lt;&lt;WD&gt;\/^O400><\/tt><\/td>\n<td>This loads an immediate constant into A\/Y.<\/td>\n<\/tr>\n<tr>\n<td><tt>PSHWD (WD)<\/tt><\/td>\n<td><tt>LDA &lt;WD&gt;+1<br \/>PHA<br \/>LDA WD<br \/>PHA<\/tt><\/td>\n<td>This pushes a 16 bit value from memory (absolute or zero page) onto the stack.<\/td>\n<\/tr>\n<tr>\n<td><tt>JEQ (WD)<\/tt><\/td>\n<td><tt>BNE .+5<br \/>JMP WD<\/tt><\/td>\n<td>A compact way to express out-of-bounds branches. Macros exist for all branches.<\/td>\n<\/tr>\n<tr>\n<td><tt>SKIP2<\/tt><\/td>\n<td><tt>XWD ^O1000,^O054<\/tt><\/td>\n<td>This emits a byte value of 0x2C (<tt>BIT<\/tt> absolute), which skips the next instruction. (The <tt>^O1000<\/tt> part wraps the byte in a PDP-10 instruction &#8211; see below.)<\/td>\n<\/tr>\n<\/table>\n<h2>Configurations<\/h2>\n<p>The BASIC source supports several compile-time configuration options:<\/p>\n<table border=\"1\">\n<tr>\n<th>Name<\/th>\n<th>Comment<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<td><tt>INTPRC<\/tt><\/td>\n<td><tt>INTEGER ARRAYS<\/tt><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><tt>ADDPRC<\/tt><\/td>\n<td><tt>FOR ADDITIONAL PRECISION<\/tt><\/td>\n<td>40 bit (9 digit) vs 32 bit (7 digit) float<\/td>\n<\/tr>\n<tr>\n<td><tt>LNGERR<\/tt><\/td>\n<td><tt>LONG ERROR MESSAGES<\/tt><\/td>\n<td>Error message strings instead of two-character codes<\/td>\n<\/tr>\n<tr>\n<td><tt>TIME<\/tt><\/td>\n<td><tt>CAPABILITY TO SET AND READ A CLK<\/tt><\/td>\n<td>TI and TI$ support<\/td>\n<\/tr>\n<tr>\n<td><tt>EXTIO<\/tt><\/td>\n<td><tt>EXTERNAL I\/O<\/tt><\/td>\n<td><tt>PRINT#<\/tt>, <tt>INPUT#<\/tt>, <tt>CMD<\/tt>, <tt>SYS<\/tt> (!), <tt>OPEN<\/tt> and <tt>CLOSE<\/tt> support<\/td>\n<\/tr>\n<tr>\n<td><tt>DISKO<\/tt><\/td>\n<td><tt>SAVE AND LOAD COMMANDS<\/tt><\/td>\n<td><tt>LOAD<\/tt>, <tt>SAVE<\/tt> (and on Commodore: <tt>VERIFY<\/tt>) support<\/td>\n<\/tr>\n<tr>\n<td><tt>NULCMD<\/tt><\/td>\n<td><tt>FOR THE \"NULL\" COMMAND<\/tt><\/td>\n<td><tt>NULL<\/tt> support, a command to configure the number of NUL characters to print to the terminal after each line break<\/td>\n<\/tr>\n<tr>\n<td><tt>GETCMD<\/tt><\/td>\n<td><tt><\/tt><\/td>\n<td><tt>GET<\/tt> support<\/td>\n<\/tr>\n<tr>\n<td><tt>RORSW<\/tt><\/td>\n<td><tt><\/tt><\/td>\n<td>If 1, the <a href=\"http:\/\/www.pagetable.com\/?p=406\"><tt>ROR<\/tt> instruction<\/a> is <a href=\"http:\/\/www.pagetable.com\/?p=45\">not used<\/a><\/td>\n<\/tr>\n<tr>\n<td><tt>ROMSW<\/tt><\/td>\n<td><tt>TELLS IF THIS IS ON ROM<\/tt><\/td>\n<td>The RAM version can optionally jetison the <tt>SIN<\/tt>, <tt>COS<\/tt>, <tt>TAN<\/tt> and <tt>ATN<\/tt> commands at startup<\/td>\n<\/tr>\n<tr>\n<td><tt>CLMWID<\/tt><\/td>\n<td><tt><\/tt><\/td>\n<td>Column width for <tt>TAB()<\/tt>&#8220;<\/td>\n<\/tr>\n<tr>\n<td><tt>LONGI<\/tt><\/td>\n<td><tt>LONG INITIALIZATION SWITCH<\/tt><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><tt>STKEND<\/tt><\/td>\n<td><tt><\/tt><\/td>\n<td>The top of stack at startup<\/td>\n<\/tr>\n<tr>\n<td><tt>BUFPAG<\/tt><\/td>\n<td><tt><\/tt><\/td>\n<td>Page of the input buffer; if 0, the buffer uses <i>parts<\/i> of the zero page<\/td>\n<\/tr>\n<tr>\n<td><tt>BUFLEN<\/tt><\/td>\n<td><tt>INPUT BUFFER SIZE<\/tt><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><tt>LINLEN<\/tt><\/td>\n<td><tt>TERMINAL LINE LENGTH<\/tt><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><tt>ROMLOC<\/tt><\/td>\n<td><tt>ADDRESS OF START OF PURE SEGMENT<\/tt><\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td><tt>KIMROM<\/tt><\/td>\n<td><tt><\/tt><\/td>\n<td>KIM-specific smaller config<\/td>\n<\/tr>\n<\/table>\n<h2>Targets<\/h2>\n<p>The constant <tt>REALIO<\/tt> is used to configure what computer system to generate the binary for. It has one of the following values:<\/p>\n<table border=\"1\">\n<tr>\n<th>Value<\/th>\n<th>Comment<\/th>\n<th>Banner<\/th>\n<th>Machine<\/th>\n<\/tr>\n<tr>\n<td>0<\/td>\n<td><tt>PDP-10 SIMULATING 6502<\/tt><\/td>\n<td><tt>SIMULATED BASIC FOR THE 6502 V1.1<\/tt><\/td>\n<td>Paul Allen&#8217;s Simulator on PDP-10<\/td>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td><tt>MOS TECH,KIM<\/tt><\/td>\n<td><tt>KIM BASIC V1.1<\/tt><\/td>\n<td>MOS KIM-1<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td><tt>OSI<\/tt><\/td>\n<td><tt>OSI 6502 BASIC VERSION 1.1<\/tt><\/td>\n<td>OSI Model 500<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td><tt>COMMODORE<\/tt><\/td>\n<td><tt>### COMMODORE BASIC ###<\/tt><\/td>\n<td>Commodore PET 2001<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td><tt>APPLE<\/tt><\/td>\n<td><tt>APPLE BASIC V1.1<\/tt><\/td>\n<td>Apple II<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td><tt>STM<\/tt><\/td>\n<td><tt>STM BASIC V1.1<\/tt><\/td>\n<td>(unreleased)<\/td>\n<\/tr>\n<\/table>\n<p>All versions except Commodore also print &#8220;<tt>COPYRIGHT 1978 MICROSOFT<\/tt>&#8221; in a new line.<\/p>\n<p>The target defines the setting of the configuration constants, but some code is also conditionally compiled depending on a specific target.<\/p>\n<p>What is interesting is that initially it was Microsoft adapting their source for the different computers, instead of giving source to the different vendors and having them adapt it. Features like file I\/O and time support seem to have been specifically developed for Commodore, for example. Later, the computer companies would get the source from Microsoft and develop themselves &#8211; source code of the <a href=\"http:\/\/apple3.org\/Documents\/SourceCode\/Apple3_Business_BASIC_1.3.pdf\">Apple<\/a> and <a href=\"http:\/\/www.davidviner.com\/cbm9.html\">Commodore<\/a> derivatives is available; they both contain Microsoft comments.<\/p>\n<p>By the way, the numbering of these targets probably indicated in which order Microsoft signed contracts with computer manufacturers. MOS was first (for the KIM), then OSI, then Commodore\/MOS again (this time for the PET), then Apple.<\/p>\n<h3>The PDP-10 Target<\/h3>\n<p>Paul Allen&#8217;s additional macros for 6502 development made the MACRO-10 assembler output one 36 bit PDP-10 instruction word for every 6502 byte. When targeting a real 6502 machine, the 6502 binary could be created by simply extracting one byte from every PDP-10 word.<\/p>\n<p>In the case of targeting the simulator, the code created by the assembler could just be run without modification, since every emitted PDP-10 instruction was constructed so that it would trap &#8211; the linked-in simulator would then extract the 6502 opcode from the instruction and emulate the 6502 behavior.<\/p>\n<p>While this trick was mostly abstracted by the (unreleased) macro package, its workings can be seen in a few cases in the BASIC source. Here, it defines <tt>SKIP1<\/tt> and <tt>SKIP2<\/tt>. Instead of just emitting 0x24 or 0x2C, respectively, it combines it with the octal value of 01000 to make it a PDP-10 instruction that traps:<\/p>\n<pre>\nDEFINE  SKIP1,  &lt;XWD ^O1000,^O044&gt;      ;BIT ZERO PAGE TRICK.\nDEFINE  SKIP2,  &lt;XWD ^O1000,^O054&gt;      ;BIT ABS TRICK.\n<\/pre>\n<p>In the initialization code, it writes a <tt>JMP<\/tt> instruction into RAM. On the simulator, it has to patch up the opcode of JMP (0x4C, decimal 76) to be the correct PDP-10 instruction:<\/p>\n<pre>\n        LDAI    76              ;JMP INSTRUCTION.\nIFE     REALIO,&lt;HRLI 1,^O1000&gt;  ;MAKE AN INST.\n<\/pre>\n<p>With this information, we can reconstruct what the set of 6502 macros, which is not part of this source, probably looked like. Here is <tt>LDAI<\/tt> (<tt>LDA<\/tt> immediate):<\/p>\n<pre>\nDEFINE  LDAI    (Q),&lt;\n        XWD ^O1000,^O251        ;EMIT OPCODE\n        XWD ^O1000,&lt;Q&gt;          ;EMIT OPERAND\n&gt;\n<\/pre>\n<p>You can also see native <tt>TJSR<\/tt> PDP-10 assembly instructions for character I\/O:<\/p>\n<pre>\nIFE     REALIO,&lt;\n        TJSR    INSIM##&gt;        ;GET A CHARACTER FROM SIMULATOR\n<\/pre>\n<pre>\nIFE     REALIO,&lt;\n        TJSR    OUTSIM##&gt;       ;CALL SIMULATOR OUTPUT ROUTINE\n<\/pre>\n<p>The <tt>DDT<\/tt> command, which breaks into the PDP-10&#8217;s DDT debugger, only exists in this config:<\/p>\n<pre>\nIFE     REALIO,&lt;\nDDT:    PLA                     ;GET RID OF NEWSTT RETURN.\n        PLA\n        HRRZ    14,.JBDDT##\n        JRST    0(14)&gt;\n<\/pre>\n<h3>The KIM and OSI Targets<\/h3>\n<p>The KIM target is meant for the <a href=\"http:\/\/www.pagetable.com\/?p=359\">MOS KIM-1<\/a> and Ohio Scientific OSI Model 500 single-board computers. These are the first ports to specific computers, and also the cleanest, i.e. except for the character I\/O interface and the very simple LOAD\/SAVE implementation for the KIM, there is nothing specific about these targets.<\/p>\n<h3>The Commodore Target<\/h3>\n<p>The Commodore target is meant for the Commodore PET 2001. It includes <tt>LOAD<\/tt>\/<tt>SAVE<\/tt>\/<tt>VERIFY<\/tt> (the commands jump directly to outside &#8220;KERNAL&#8221; ROM code), the I\/O commands (<tt>SYS<\/tt>, <tt>PRINT#<\/tt>, <tt>OPEN<\/tt> etc.), the <tt>GET<\/tt> command and the <tt>&pi;<\/tt>, <tt>ST<\/tt>, <tt>TI<\/tt> and <tt>TI$<\/tt> symbols. <tt>CLEAR<\/tt> is renamed to <tt>CLR<\/tt>, <tt>\"OK\"<\/tt> is renamed to <tt>\"READY.\"<\/tt>, the BEL character is not printed, and character I\/O code behaves differently to account for the more featureful screen editor of the PET.<\/p>\n<p>Oh, and the Commodore version of course includes the <a href=\"http:\/\/www.pagetable.com\/?p=43\">Bill Gates WAIT 6502,1 easter egg<\/a>! This is the <tt>WAIT<\/tt> instruction:<\/p>\n<pre>\n; THE WAIT LOCATION,MASK1,MASK2 STATEMENT WAITS UNTIL THE CONTENTS\n; OF LOCATION IS NONZERO WHEN XORED WITH MASK2\n; AND THEN ANDED WITH MASK1. IF MASK2 IS NOT PRESENT, IT\n; IS ASSUMED TO BE ZERO.\n\nFNWAIT: JSR     GETNUM\n        STX     ANDMSK\n        LDXI    0\n        JSR     CHRGOT\n        BEQ     <b><font color=\"red\">ZSTORDO<\/font><\/b>\n        JSR     COMBYT          ;GET MASK2.\n<b><font color=\"red\">STORDO<\/font><\/b>: STX     EORMSK\n        LDYI    0\nWAITER: LDADY   POKER\n        EOR     EORMSK\n        AND     ANDMSK\n        BEQ     WAITER\nZERRTS: RTS                     ;GOT A NONZERO.\n<\/pre>\n<p>Note how the <tt>BEQ<\/tt> instruction references <tt>ZSTORDO<\/tt>, not <tt>STORDO<\/tt> &#8211; execution sneaks out of this function here.<\/p>\n<p>Well, on non-Commodore machines, <tt>ZSTORDO<\/tt> is assigned to be the same as <tt>STORDO<\/tt>, so everything is fine:<\/p>\n<pre>\nIFN     REALIO-3,&lt;ZSTORDO=STORDO&gt;\n<\/pre>\n<p>But on Commodore, we have this code hidden near the top of the floating point math package &#8211; close enough so the <tt>BEQ<\/tt> can reach it, but inside code that is least likely to get touched:<\/p>\n<pre>\nIFE     REALIO-3,&lt;\nZSTORD:!        LDA     POKER\n        CMPI    146\n        BNE     STORDO\n        LDA     POKER+1\n        SBCI    31\n        BNE     STORDO\n        STA     POKER\n        TAY\n        LDAI    200\n        STA     POKER+1\nMRCHKR: LDXI    12\nIF1,&lt;\nMRCHR:  LDA     60000,X,&gt;\nIF2,&lt;\nMRCHR:  LDA     <b>SINCON<\/b>+36,X,&gt;\n        ANDI    77\n        STADY   POKER\n        INY\n        BNE     PKINC\n        INC     POKER+1\nPKINC:  DEX\n        BNE     MRCHR\n        DEC     ANDMSK\n        BNE     MRCHKR\n        RTS\nIF2,&lt;PURGE ZSTORD&gt;&gt;\n<\/pre>\n<p>(<tt>IF1<\/tt> and <tt>IF2<\/tt> are true on the first and the second assembler pass, respectively, so the conditional there is to hint to the assembler in the first pass that <tt>SINCON+36<\/tt> is not a zero page address. Also note that all numbers here are octal, since this code is in the floating point package.)<\/p>\n<p>First of all, the final line here removes <tt>ZSTORD<\/tt> from the list of symbols after the second pass, so that Commodore would not notice it in a printout of all symbols &#8211; very smart!<\/p>\n<p><a href=\"http:\/\/www.pagetable.com\/?p=43\">As has been discussed before<\/a>, this code writes the string &#8220;MICROSOFT!&#8221; into the PET&#8217;s screen RAM if the argument to WAIT is &#8220;6502&#8221;. The encoded string is hidden as two extra 40 bit floating point numbers appended to the coefficients used by the SIN function:<\/p>\n<pre>\nIFN     ADDPRC,&lt;\nSINCON: 5               ;DEGREE-1.\n        204     ; -14.381383816\n        346\n        032\n        055\n        033\n        206     ; 42.07777095\n        050\n        007\n        373\n        370\n        207     ; -76.704133676\n        231\n        150\n        211\n        001\n        207     ; 81.605223690\n        043\n        065\n        337\n        341\n        206     ; -41.34170209\n        245\n        135\n        347\n        050\n        203     ; 6.2831853070\n        111\n        017\n        332\n        242\n        241     ; 7.2362932E7\n        124\n        106\n        217\n        23\n        217     ; 73276.2515\n        122\n        103\n        211\n        315&gt;\n<\/pre>\n<p>These last ten bytes, nicely disguised as octal values of floating point constants, spell out &#8220;MICROSOFT!&#8221; backwards after clearing the upper two bits. What&#8217;s interesting is that the floating point values next to them are actually incorrect: They should be 7.12278788E9 and 26913.7691 instead.<\/p>\n<p>Also note that these constants are not conditionally assembled! All versions built since the Commodore easter egg was introduced also contained these 10 bytes &#8211; <a href=\"http:\/\/www.pagetable.com\/?p=43\">including BASIC for the Motorola 6800<\/a>!<\/p>\n<h3>The Apple Target<\/h3>\n<p>The Apple target is meant for the Apple II, and contains no customizations other than some changes around I\/O handling (which calls into the monitor ROM). Note that this is not yet the &#8220;AppleSoft&#8221; version of BASIC, which was a more customized version modified by Apple later.<\/p>\n<h3>The STM Target<\/h3>\n<p>&#8220;STM&#8221; most likely stands for &#8220;Semi-Tech Microelectronics&#8221; &#8211; a company that never shipped a 6502-based computer. Their first machine was the &#8220;Pied Piper&#8221;, a Z80-based system, and they later made a PC clone. It seems they had a 6502-based computer in development that never shipped &#8211; or at least they were considering making one, and Microsoft added the target; this target doesn&#8217;t actually change any of the defaults.<\/p>\n<h2>Organization of the Source<\/h2>\n<p>The source uses the <tt>PAGE<\/tt> and <tt>SUBTTL<\/tt> keywords for organization. Here are the headings:<\/p>\n<pre>\nSUBTTL  SWITCHES,MACROS.\nSUBTTL  INTRODUCTION AND COMPILATION PARAMETERS.\nSUBTTL  SOME EXPLANATION.\nSUBTTL  PAGE ZERO.\nSUBTTL  RAM CODE.\nSUBTTL  DISPATCH TABLES, RESERVED WORDS, AND ERROR TEXTS.\nSUBTTL  GENERAL STORAGE MANAGEMENT ROUTINES.\nSUBTTL  ERROR HANDLER, READY, TERMINAL INPUT, COMPACTIFY, NEW, REINIT.\nSUBTTL  THE \"LIST\" COMMAND.\nSUBTTL  THE \"FOR\" STATEMENT.\nSUBTTL  NEW STATEMENT FETCHER.\nSUBTTL  RESTORE,STOP,END,CONTINUE,NULL,CLEAR.\nSUBTTL  LOAD AND SAVE SUBROUTINES.\nSUBTTL  RUN,GOTO,GOSUB,RETURN.\nSUBTTL  \"IF ... THEN\" CODE.\nSUBTTL  \"ON ... GO TO ...\" CODE.\nSUBTTL  LINGET -- READ A LINE NUMBER INTO LINNUM\nSUBTTL  \"LET\" CODE.\nSUBTTL  PRINT CODE.\nSUBTTL  INPUT AND READ CODE.\nSUBTTL  THE NEXT CODE IS THE \"NEXT CODE\"\nSUBTTL  DIMENSION AND VARIABLE SEARCHING.\nSUBTTL  MULTIPLE DIMENSION CODE.\nSUBTTL  INTEGER ARITHMETIC ROUTINES.\nSUBTTL  FRE FUNCTION AND INTEGER TO FLOATING ROUTINES.\nSUBTTL  SIMPLE-USER-DEFINED-FUNCTION CODE.\nSUBTTL  STRING FUNCTIONS.\nSUBTTL  PEEK, POKE, AND FNWAIT.\nSUBTTL  FLOATING POINT ADDITION AND SUBTRACTION.\nSUBTTL  NATURAL LOG FUNCTION.\nSUBTTL  FLOATING MULTIPLICATION AND DIVISION.\nSUBTTL  FLOATING POINT MOVEMENT ROUTINES.\nSUBTTL  SIGN, SGN, FLOAT, NEG, ABS.\nSUBTTL  COMPARE TWO NUMBERS.\nSUBTTL  GREATEST INTEGER FUNCTION.\nSUBTTL  FLOATING POINT INPUT ROUTINE.\nSUBTTL  FLOATING POINT OUTPUT ROUTINE.\nSUBTTL  EXPONENTIATION AND SQUARE ROOT FUNCTION.\nSUBTTL  EXPONENTIATION FUNCTION.\nSUBTTL  POLYNOMIAL EVALUATOR AND THE RANDOM NUMBER GENERATOR.\nSUBTTL  SINE, COSINE AND TANGENT FUNCTIONS.\nSUBTTL  ARCTANGENT FUNCTION.\nSUBTTL  SYSTEM INITIALIZATION CODE.\n<\/pre>\n<h2>Paul Allen vs. Bill Gates<\/h2>\n<p>The source of the 8080 version states:<\/p>\n<pre>\nPAUL ALLEN WROTE THE NON-RUNTIME STUFF.\nBILL GATES WROTE THE RUNTIME STUFF.\nMONTE DAVIDOFF WROTE THE MATH PACKAGE.\n<\/pre>\n<p>People have since <a href=\"http:\/\/harry-lewis.blogspot.com\/2011\/03\/who-wrote-how-much-of-original.html\">wondered<\/a> what runtime vs. non-runtime meant, especially since Paul Allen&#8217;s <a href=\"http:\/\/www.wsj.com\/articles\/SB10001424052748703806304576232051635476200\">recent debate<\/a> on whether the company&#8217;s ownership was faily split.<\/p>\n<p>The BASIC for 6502 source sheds some light on this:<\/p>\n<pre>\nNON-RUNTIME STUFF\n        THE CODE TO INPUT A LINE, CRUNCH IT, GIVE ERRORS,\n        FIND A SPECIFIC LINE IN THE PROGRAM,\n        PERFORM A \"NEW\", \"CLEAR\", AND \"LIST\" ARE\n        ALL IN THIS AREA. [...]\n<\/pre>\n<p>So by &#8220;runtime&#8221; they just literally mean &#8220;at run time&#8221;: all code that is active when the program runs, as opposed to non-runtime, which is all code that assists editing the program.<\/p>\n<p>By this understanding, we can assume this:<\/p>\n<ul>\n<li>Paul Allen wrote the macro package for the MACRO-10 assembler, the 6502 simulator, the tokenizer, the detokenizer, as well as finding, inserting and deleting BASIC lines.\n<li>Bill Gates implemented all BASIC statements, functions, operators, expression evaluation, stack management for FOR and GOSUB, the memory manager, as well as the array and string library.<\/li>\n<li>Monte Davidoff wrote the floating point math package.<\/li>\n<\/ul>\n<h2>Version and Date<\/h2>\n<p>The last entry in the change log has a date of 1978-07-27. Both the comment in the first line of the file and the message printed at startup call it version 1.1.<\/p>\n<p>What does this say about the version of the source? Is it the last version? Let&#8217;s look at the last bug fix and compare which BASIC binaries contain this fix, and let&#8217;s see whether there are fixes in BASIC binaries that are not in the source.<\/p>\n<p>I have previously compared binaries of derivatives of BASIC for 6502 and compiled the information at <a href=\"https:\/\/github.com\/mist64\/msbasic\">github.com\/mist64\/msbasic<\/a>. The last entry in the log of this source is about a bug that failed to correctly invalidate a pointer in the <tt>RETURN<\/tt> statement. According to <a href=\"https:\/\/github.com\/mist64\/msbasic\/blob\/master\/README.md\">my analysis of BASIC 6502 versions<\/a>, this is fixed in the BASIC binaries for AIM-65, SYM-1, Commodore v2, KBD BASIC and MicroTAN, i.e. on everything my previous analysis calls <tt>CONFIG_2A<\/tt> and higher.<\/p>\n<p>The same analysis also came to the conclusion that there were two successors, <tt>CONFIG_2B<\/tt> and <tt>CONFIG_2C<\/tt>. At least the two <tt>CONFIG_2B<\/tt> fixes exist in two BASIC binaries: KBD BASIC and MicroTAN, but they don&#8217;t exist in this source. It&#8217;s very unlikely that both these bugs (and only these!) got fixed by the two computer manufacturers independently, so it&#8217;s safe to assume that this source is not the final version &#8211; but pretty close to it!<\/p>\n<h2>Interesting Finds<\/h2>\n<ul>\n<li>This code is comparing a keyboard input character to the BEL code. <a href=\"http:\/\/www.amazon.com\/Bob-Albrecht\/e\/B000APLRMU\">Bob Albrecht<\/a> is a computer educator that &#8220;was instrumental in helping bring about a public-domain version of Basic (called <a href=\"http:\/\/en.wikipedia.org\/wiki\/Tiny_BASIC\">Tiny Basic<\/a>) for early microcomputers.&#8221;.\n<pre>\nCMPI    7               ;IS IT BOB ALBRECHT RINGING THE BELL\n                        ;FOR SCHOOL KIDS?\n<\/pre>\n<\/li>\n<li>External documentation usually calls the conversion of ASCII BASIC text into the compressed format &#8220;tokenizing&#8221;. The source calls this &#8220;crunching&#8221;.<\/li>\n<li>Microsoft is still spelled &#8220;Micro-Soft&#8221;.<\/li>\n<li>Apparently the multiplication function could use some performance improvements:\n<pre>\nBNE     MLTPL2          ;SLOW AS A TURTLE !\n<\/pre>\n<\/li>\n<li>The <tt>NEW<\/tt> command is actually called <tt>SCRATCH<\/tt> in labels and comments &#8211; maybe other BASIC dialects called it that, and they decided to rename it to <tt>NEW<\/tt> later?<\/li>\n<li>The math package documentation says:\n<pre>\nMATH PACKAGE\n        THE MATH PACKAGE CONTAINS FLOATING INPUT (FIN),\n        FLOATING OUTPUT (FOUT), FLOATING COMPARE (FCOMP)\n        ... AND ALL THE NUMERIC OPERATORS AND FUNCTIONS.\n        THE FORMATS, CONVENTIONS AND ENTRY POINTS ARE ALL\n        DESCRIBED IN THE MATH PACKAGE ITSELF.\n<\/pre>\n<p><a href=\"http:\/\/www.davidviner.com\/cbm9.html\">Commodore&#8217;s derived source<\/a> changes this to:<\/p>\n<pre>\n; MATH PACKAGE\n;       THE MATH PACKAGE CONTAINS FLOATING INPUT FIN, OUTPUT\n;       FOUT, COMPARE FCOMP...AND ALL THE NUMERIC OPERATORS\n;       AND FUNCTIONS.  THE FORMATS, CONVENTIONS AND ENTRY\n;       POINTS ARE ALL DESCRIBED IN THE MATH PACKAGE ITSELF.\n;       <b><i>(HA,HA...)<\/i><\/b>\n<\/pre>\n<\/li>\n<li>CHRGET is a central piece of BASIC for 6502. Here it is in its entirety:\n<pre>\n; THIS CODE GETS CHANGED THROUGHOUT EXECUTION.\n; IT IS MADE TO BE FAST THIS WAY.\n; ALSO, [X] AND [Y] ARE NOT DISTURBED\n;\n; \"CHRGET\" USING [TXTPTR] AS THE CURRENT TEXT PNTR\n; FETCHES A NEW CHARACTER INTO ACCA AFTER INCREMENTING [TXTPTR]\n; AND SETS CONDITION CODES ACCORDING TO WHAT'S IN ACCA.\n;       NOT C=  NUMERIC   (\"0\" THRU \"9\")\n;       Z=      \":\" OR END-OF-LINE (A NULL)\n;\n; [ACCA] = NEW CHAR.\n; [TXTPTR]=[TXTPTR]+1\n;\n; THE FOLLOWING EXISTS IN ROM IF ROM EXISTS AND IS LOADED\n; DOWN HERE BY INIT. OTHERWISE IT IS JUST LOADED INTO THIS\n; RAM LIKE ALL THE REST OF RAM IS LOADED.\n;\nCHRGET: INC     CHRGET+7        ;INCREMENT THE WHOLE TXTPTR.\n        BNE     CHRGOT\n        INC     CHRGET+8\nCHRGOT: LDA     60000           ;A LOAD WITH AN EXT ADDR.\nTXTPTR= CHRGOT+1\n        CMPI    \" \"             ;SKIP SPACES.\n        BEQ     CHRGET\nQNUM:   CMPI    \":\"             ;IS IT A \":\"?\n        BCS     CHRRTS          ;IT IS .GE. \":\"\n        SEC\n        SBCI    \"0\"             ;ALL CHARS .GT. \"9\" HAVE RET'D SO\n        SEC\n        SBCI    256-\"0\"         ;SEE IF NUMERIC.\n                                ;TURN CARRY ON IF NUMERIC.\n                                ;ALSO, SETZ IF NULL.\nCHRRTS: RTS                     ;RETURN TO CALLER.\n<\/pre>\n<p>\tDid you ever wonder why <a href=\"http:\/\/www.pagetable.com\/c64rom\/c64rom_en.html#E3A2\">all<\/a> <a href=\"http:\/\/www.txbobsc.com\/scsc\/scdocumentor\/EFEA.html\">versions<\/a> have $EA60 encoded into the <tt>LDA<\/tt> instruction that later gets overwritten? Because it&#8217;s 60000 decimal. That&#8217;s why! The source actually uses 60000 as a placeholder for 16 bit values in several places.<\/li>\n<li>The handling of <tt>&pi;<\/tt>, <tt>ST<\/tt>, <tt>TI<\/tt> and <tt>TI$<\/tt> (all Commodore-specific) looks wonky: Instead of making them tokens, they are special cased in several places. I always assumed it was Commodore adding this without understanding (or wanting to disrupt) the existing code, but it was Microsoft adding these features. Maybe they were added by someone other than the original developers?<\/li>\n<\/ul>\n<h2>Origin of the File<\/h2>\n<p>The source was posted on the Korean-language blog <a href=\"http:\/\/6502.tistory.com\/468\">6502.tistory.com<\/a> without further comment, in a marked-up format:<\/p>\n<pre>\n================================================================================================\nFILE: \"david mac g5 b:m6502.asm\"\n================================================================================================\n\n000001  TITLE   BASIC M6502 8K VER 1.1 BY MICRO-SOFT\n[...]\n006955          END     $Z+START\n\nEnd of File -- Lines: 6955 Characters: 154740\n\nSUMMARY:\n\n  Total number of files : 1\n  Total file lines      : 6955\n  Total file characters : 154740\n<\/pre>\n<p>This formatting was created by an unpublished tool by David T. Craig, who published a lot of Apple-related soure code (Apple II, Apple III, Lisa) <a href=\"https:\/\/duckduckgo.com\/?q=%22Total+number+of+files%22+%22Total+file+lines%22+%22Total+file+characters%22\">in this format<\/a> in as early as 1993, first <a href=\"http:\/\/apple3.applearchives.com\/other_apple_resources\/system_source_code\/apple3sos13list.pdf\">anonymously<\/a>, later <a href=\"ftp:\/\/ftp.apple.asimov.net\/pub\/apple_II\/documentation\/apple3\/dtca3doc\/DTCA3DOC-180B%20apple%203%20sos%2013%20source%20listing.pdf\">with his name<\/a>).<\/p>\n<p>The filename &#8220;<tt>david mac g5 b:m6502.asm<\/tt>&#8221; (disk name &#8220;david mac g5 b&#8221;, file name &#8220;m6502.asm&#8221;, since it was a classic Mac OS tool) confirms David Craig&#8217;s involvement, and it means the line numbers were added no earlier than 2003.<\/p>\n<p>Given all this, it is safe to assume the file with the Microsoft BASIC for 6502 source originated at Apple, and was given to David Craig together with the other source he published.<\/p>\n<p>The version I posted is a reconstruction of the original file, with the header, the footer and the line numbers removed, and the spaces converted back into tabs. I chose the name &#8220;M6502.MAC&#8221; to be consistent with the MACRO-10 file extension used by the <a href=\"http:\/\/altairbasic.org\/other%20versions\/ian.htm\">Microsoft BASIC for 8080 sources<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is the original 1978 source code of Microsoft BASIC for 6502 with all original comments, documentation and easter eggs: bah M6502.MAC (1978-07-27, 6955 lines, 161,685 bytes) This is currently the oldest publicly available piece of source written by Bill Gates. Language Like the 8080 version, the 6502 version was developed on a PDP-10, using &#8230; <a title=\"Microsoft BASIC for 6502 Original Source Code [1978]\" class=\"read-more\" href=\"https:\/\/www.pagetable.com\/?p=774\" aria-label=\"Read more about Microsoft BASIC for 6502 Original Source Code [1978]\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,5,6,23],"tags":[],"class_list":["post-774","post","type-post","status-publish","format-standard","hentry","category-2","category-archeology","category-basic","category-pet"],"_links":{"self":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/774","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=774"}],"version-history":[{"count":0,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/774\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=774"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=774"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=774"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}