Bill Gates - Microsoft BASIC for 6502 Original Source Code [1978] - Tekst piosenki, lyrics - teksciki.pl

Microsoft BASIC for 6502 Original Source Code [1978]

Bill Gates

45

Tech

Tekst piosenki
TITLE BASIC M6502 8K VER 1.1 BY MICRO-SOFT SEARCH M6502 SALL RADIX 10 ;THROUGHOUT ALL BUT MATH-PAK. $Z:: ;STARTING POINT FOR M6502 SIMULATOR ORG 0 ;START OFF AT LOCATION ZERO. SUBTTL SWITCHES,MACROS. REALIO=4 ;5=STM ;4=APPLE. ;3=COMMODORE. ;2=OSI ;1=MOS TECH,KIM ;0=PDP-10 SIMULATING 6502 INTPRC==1 ;INTEGER ARRAYS. ADDPRC==1 ;FOR ADDITIONAL PRECISION. LNGERR==0 ;LONG ERROR MESSAGES. TIME== 0 ;CAPABILITY TO SET AND READ A CLK. EXTIO== 0 ;EXTERNAL I/O. DISKO== 0 ;SAVE AND LOAD COMMANDS NULCMD==1 ;FOR THE "NULL" COMMAND GETCMD==1 RORSW==1 ROMSW==1 ;TELLS IF THIS IS ON ROM. CLMWID==14 LONGI==1 ;LONG INITIALIZATION SWITCH. STKEND=511 BUFPAG==0 LINLEN==72 ;TERMINAL LINE LENGTH. BUFLEN==72 ;INPUT BUFFER SIZE. ROMLOC= ^O20000 ;ADDRESS OF START OF PURE SEGMENT. KIMROM=1 IFE ROMSW, IFN REALIO-1, IFN ROMSW, RAMLOC= ^O40000 ;USED ONLY IF ROMSW=1 IFE REALIO, RAMLOC=^O1400>> IFE REALIO-3, DISKO==1 RAMLOC==^O2000 ROMLOC=^O140000 NULCMD==0 GETCMD==1 linlen==40 BUFLEN==81 CQOPEN=^O177700 CQCLOS=^O177703 CQOIN= ^O177706 ;OPEN CHANNEL FOR INPUT CQOOUT=^O177711 ;FILL FOR COMMO. CQCCHN=^O177714 CQINCH=^O177717 ;INCHR'S CALL TO GET A CHARACTER OUTCH= ^O177722 CQLOAD=^O177725 CQSAVE=^O177730 CQVERF=^O177733 CQSYS= ^O177736 ISCNTC=^O177741 CZGETL=^O177744 ;CALL POINT FOR "GET" CQCALL=^O177747 ;CLOSE ALL CHANNELS CQTIMR=^O215 BUFPAG==2 BUF==256*BUFPAG STKEND==507 CQSTAT=^O226 CQHTIM=^O164104 EXTIO==1 TIME==1 GETCMD==1 CLMWID==10 PI=255 ;VALUE OF PI CHARACTER FOR COMMODORE. ROMSW==1 RORSW==1 TRMPOS=^O306> IFE REALIO-1, JSR SYNCHR> DEFINE DT(Q), IRPC Q,,>> DEFINE LDWD (WD), LDA WD LDY +1> DEFINE LDWDI (WD), LDAI LDYI ^O400>> DEFINE LDWX (WD), LDA WD LDX +1> DEFINE LDWXI (WD), LDAI LDXI ^O400>> DEFINE LDXY (WD), LDX WD LDY +1> DEFINE LDXYI (WD), LDXI LDYI ^O400>> DEFINE STWD (WD), STA WD STY +1> DEFINE STWX (WD), STA WD STX +1> DEFINE STXY (WD), STX WD STY +1> DEFINE CLR (WD), LDAI 0 STA WD> DEFINE COM (WD), LDA WD EORI ^O377 STA WD> DEFINE PULWD (WD), PLA STA WD PLA STA +1> DEFINE PSHWD (WD), LDA +1 PHA LDA WD PHA> DEFINE JEQ (WD), BNE .+5 JMP WD> DEFINE JNE (WD), BEQ .+5 JMP WD> DEFINE BCCA(Q), ;BRANCHES THAT ALWAYS BRANCH DEFINE BCSA(Q), ;THESE ARE USED ON THE 6502 BECAUSE DEFINE BEQA(Q), ;THERE IS NO UNCONDITIONAL BRANCH DEFINE BNEA(Q), DEFINE BMIA(Q), DEFINE BPLA(Q), DEFINE BVCA(Q), DEFINE BVSA(Q), DEFINE INCW(R), INC R BNE %Q INC R+1 %Q:> DEFINE SKIP1, ;BIT ZERO PAGE TRICK. DEFINE SKIP2, ;BIT ABS TRICK. IF1, IFE REALIO, IFE REALIO-1, IFE REALIO-2, IFE REALIO-3, IFE REALIO-4, IFE REALIO-5, IFN ADDPRC, IFN INTPRC, IFN LNGERR, IFN DISKO, IFE ROMSW, IFN ROMSW, IFE RORSW, IFN RORSW,> PAGE SUBTTL INTRODUCTION AND COMPILATION PARAMETERS. COMMENT * --------- ---- -- --------- COPYRIGHT 1976 BY MICROSOFT --------- ---- -- --------- 7/27/78 FIXED BUG WHERE FOR VARIABLE AT BYTE FF MATCHED RETURN SEARCHING FOR GOSUB ENTRY ON STACK IN FNDFOR CALL BY CHANGING STA FORPNT TO STA FORPNT+1. THIS IS A SERIOUS BUG IN ALL VERSIONS. 7/27/78 FIXED BUG AT NEWSTT UNDER IFN BUFPAG WHEN CHECK OF CURLIN WAS DONE BEFORE CURLIN SET UP SO INPUT RETRIES OF FIRST STATEMENT WAS GIVING SYNTAX ERROR INSTEAD OF REDO FROM START (CODE WAS 12/1/77 FIX) 7/1/78 SAVED A FEW BYTES IN INIT FOR COMMODORE (14) 7/1/78 FIXED BUG WHERE REPLACING A LINE OVERFLOWING MEMORY LEFT LINKS IN A BAD STATE. (CODE AT NODEL AND FINI) BUG#4 7/1/78 FIXED BUG WHERE GARBAGE COLLECTION NEVER(!) COLLECTS TEMPS (STY GRBPNT AT FNDVAR, LDA GRBPNT ORA GRBPNT+1 AT GRBPAS) THIS WAS COMMODORE BUG #2 7/1/78 FIXED BUG WHERE DELETE/INSERT OF LINE COULD CAUSE A GARBAGE COLLECTION WITH BAD VARTAB IF OUT OF MEMORY (LDWD MEMSIZ STWD FRETOP=JSR RUNC CLC ALSO AT NODEL) 3/9/78 EDIT TO FIX COMMO TRMPOS AND CHANGE LEFT$ AND RIGHT$ TO ALLOW A SECOND ARGUMENT OF 0 AND RETURN A NULL STRING 2/25/78 FIXED BUG THAT INPFLG WAS SET WRONG WHEN BUFPAG.NE.0 INCREASED NUMLEV FROM 19 TO 23 2/11/78 DISALLOWED SPACES IN RESERVED WORDS. PUT IN SPECIAL CHECK FOR "GO TO" 2/11/78 FIXED BUG WHERE ROUNDING OF THE FAC BEFORE PUSHING COULD CAUSE A STRING POINTER IN THE FAC TO BE INCREMENTED 1/24/78 fixed problem where user defined function undefined check fix was smashing error number in [x] 12/1/77 FIXED PROBLEM WHERE PEEK WAS SMASHING (POKER) CAUSING POKE OF PEEK TO FAIL 12/1/77 FIXED PROBLEM WHERE PROBLEM WITH VARTXT=LINNUM=BUF-2 CAUSING BUF-1 COMMA TO DISAPPEAR 12/1/77 FIXED BUFPAG.NE.0 PROBLEM AT NEWSTT AND STOP : CODE WAS STILL ASSUMING TXTPTR+1.EQ.0 IFF STATEMENT WAS DIRECT * NUMLEV==23 ;NUMBER OF STACK LEVELS RESERVED ;BY AN EXPLICIT CALL TO "GETSTK". STRSIZ==3 ;# OF LOCS PER STRING DESCRIPTOR. NUMTMP==3 ;NUMBER OF STRING TEMPORARIES. CONTW==15 ;CHARACTER TO SUPPRESS OUTPUT. PAGE SUBTTL SOME EXPLANATION. COMMENT * M6502 BASIC CONFIGURES BASIC AS FOLLOWS LOW LOCATIONS PAGE ZERO STARTUP: INITIALLY A JMP TO INITIALIZATION CODE BUT CHANGED TO A JMP TO "READY". RESTARTING THE MACHINE AT LOC 0 DURING PROGRAM EXECUTION CAN LEAVE THINGS MESSED UP. LOC OF FAC TO INTEGER AND INTEGER TO FAC ROUTINES. "DIRECT" MEMORY: THESE ARE THE MOST COMMONLY USED LOCATIONS. THEY HOLD BOOKKEEPING INFO AND ALL OTHER FREQUENTLY USED INFORMATION. ALL TEMPORARIES, FLAGS, POINTERS, THE BUFFER AREA, THE FLOATING ACCUMULATOR, AND ANYTHING ELSE THAT IS USED TO STORE A CHANGING VALUE SHOULD BE LOCATED IN THIS AREA. CARE MUST BE MADE IN MOVING LOCATIONS IN THIS AREA SINCE THE JUXTAPOSITION OF TWO LOCATIONS IS OFTEN DEPENDED UPON. STILL IN RAM WE HAVE THE BEGINNING OF THE "CHRGET" SUBROUTINE. IT IS HERE SO [TXTPTR] CAN BE THE EXTENDED ADDRESS OF A LOAD INSTRUCTION. THIS SAVES HAVING TO BOTHER ANY REGISTERS. PAGE ONE THE STACK. STORAGE PAGE TWO AND ON IN RAM VERSIONS THESE DATA STRUCTURES COME AT THE END OF BASIC. IN ROM VERSON THEY ARE AT RAMLOC WHICH CAN EITHER BE ABOVE OR BELOW ROMLOC, WHICH IS WHERE BASIC ITSELF RESIDES. A ZERO. [TXTTAB] POINTER TO NEXT LINE'S POINTER. LINE # OF THIS LINE (2 BYTES). CHARACTERS ON THIS LINE. ZERO. POINTER AT NEXT LINE'S POINTER (POINTED TO BY THE ABOVE POINTER). ... REPEATS ... LAST LINE: POINTER AT ZERO POINTER. LINE # OF THIS LINE. CHARACTERS ON THIS LINE. ZERO. DOUBLE ZERO (POINTED TO BY THE ABOVE POINTER). [VARTAB] SIMPLE VARIABLES. 6 BYTES PER VALUE. 2 BYTES GIVE THE NAME, 4 BYTES THE VALUE. ... REPEATS ... [ARYTAB] ARRAY VARIABLES. 2 BYTES NAME, 2 BYTE LENGTH, NUMBER OF DIMENSIONS , EXTENT OF EACH DIMENSION (2BYTES/), VALUES ... REPEATS ... [STREND] FREE SPACE. ... REPEATS ... [FRETOP] STRING SPACE IN USE. ... REPEATS ... [MEMSIZ] HIGHEST MACHINE LOCATION. UNUSED EXCEPT BY THE VAL FUNCTION. ROM -- CONSTANTS AND CODE. FUNCTION DISPATCH ADDRESSES (AT ROMLOC) "FUNDSP" CONTAINS THE ADDRESSES OF THE FUNCTION ROUTINES IN THE ORDER OF THE FUNCTION NAMES IN THE CRUNCH LIST. THE FUNCTIONS THAT TAKE MORE THAN ONE ARGUMENT ARE AT THE END. SEE THE EXPLANATION AT "ISFUN". THE OPERATOR LIST THE "OPTAB" LIST CONTAINS AN OPERATOR'S PRECEDENCE FOLLOWED BY THE ADDRESS OF THE ROUTINE TO PERFORM THE OPERATION. THE INDEX INTO THE OPERATOR LIST IS MADE BY SUBTRACTING OFF THE CRUNCH VALUE OF THE LOWEST NUMBERED OPERATOR. THE ORDER OF OPERATORS IN THE CRUNCH LIST AND IN "OPTAB" IS IDENTICAL. THE PRECEDENCES ARE ARBITRARY EXCEPT FOR THEIR COMPARATIVE SIZES. NOTE THAT THE PRECEDENCE FOR UNARY OPERATORS SUCH AS "NOT" AND NEGATION ARE SETUP SPECIALLY WITHOUT USING THE LIST. THE RESERVED WORD OR CRUNCH LIST WHEN A COMMAND OR PROGRAM LINE IS TYPED IN IT IS STORED IN "BUF". AS SOON AS THE WHOLE LINE HAS BEEN TYPED IN ("INLIN" RETURNS) "CRUNCH" IS CALLED TO CONVERT ALL RESERVED WORDS TO THEIR CRUNCHED VALUES. THIS REDUCES THE SIZE OF THE PROGRAM AND SPEEDS UP EXECUTION BY ALLOWING LIST DISPATCHES TO PERFORM FUNCTIONS, STATEMENTS, AND OPERATIONS. THIS IS BECAUSE ALL THE STATEMENT NAMES ARE STORED CONSECUTIVELY IN THE CRUNCH LIST. WHEN A MATCH IS FOUND BETWEEN A STRING OF CHARACTERS AND A WORD IN THE CRUNCH LIST THE ENTIRE TEXT OF THE MATCHED WORD IS TAKEN OUT OF THE INPUT LINE AND A RESERVED WORD TOKEN IS PUT IN ITS PLACE. A RESERVED WORD TOKEN IS ALWAYS EQUAL TO OCTAL 200 PLUS THE POSITION OF THE MATCHED WORD IN THE CRUNCH LIST. STATEMENT DISPATCH ADDRESSES WHEN A STATEMENT IS TO BE EXECUTED, THE FIRST CHARACTER OF THE STATEMENT IS EXAMINED TO SEE IF IT IS LESS THAN THE RESERVED WORD TOKEN FOR THE LOWEST NUMBERED STATEMENT NAME. IF SO, THE "LET" CODE IS CALLED TO TREAT THE STATEMENT AS AN ASSIGNMENT STATEMENT. OTHERWISE A CHECK IS MADE TO MAKE SURE THE RESERVED WORD NUMBER IS NOT TOO LARGE TO BE A STATEMENT TYPE NUMBER. IF NOT THE ADDRESS TO DISPATCH TO IS FETCHED FROM "STMDSP" (THE STATEMENT DISPATCH LIST) USING THE RESERVED WORD NUMBER FOR THE STATEMENT TO CALCULATE AN INDEX INTO THE LIST. ERROR MESSAGES WHEN AN ERROR CONDITION IS DETECTED, [ACCX] MUST BE SET UP TO INDICATE WHICH ERROR MESSAGE IS APPROPRIATE AND A BRANCH MUST BE MADE TO "ERROR". THE STACK WILL BE RESET AND ALL PROGRAM CONTEXT WILL BE LOST. VARIABLES VALUES AND THE ACTUAL PROGRAM REMAIN INTACT. ONLY THE VALUE OF [ACCX] IS IMPORTANT WHEN THE BRANCH IS MADE TO ERROR. [ACCX] IS USED AS AN INDEX INTO "ERRTAB" WHICH GIVES THE TWO CHARACTER ERROR MESSAGE THAT WILL BE PRINTED ON THE USER'S TERMINAL. TEXTUAL MESSAGES CONSTANT MESSAGES ARE STORED HERE. UNLESS THE CODE TO CHECK IF A STRING MUST BE COPIED IS CHANGED THESE STRINGS MUST BE STORED ABOVE PAGE ZERO, OR ELSE THEY WILL BE COPIED BEFORE THEY ARE PRINTED. FNDFOR MOST SMALL ROUTINES ARE FAIRLY SIMPLE AND ARE DOCUMENTED IN PLACE. "FNDFOR" IS USED FOR FINDING "FOR" ENTRIES ON THE STACK. WHENEVER A "FOR" IS EXECUTED, A 16-BYTE ENTRY IS PUSHED ONTO THE STACK. BEFORE THIS IS DONE, HOWEVER, A CHECK MUST BE MADE TO SEE IF THERE ARE ANY "FOR" ENTRIES ALREADY ON THE STACK FOR THE SAME LOOP VARIABLE. IF SO, THAT "FOR" ENTRY AND ALL OTHER "FOR" ENTRIES THAT WERE MADE AFTER IT ARE ELIMINATED FROM THE STACK. THIS IS SO A PROGRAM THAT JUMPS OUT OF THE MIDDLE OF A "FOR" LOOP AND THEN RESTARTS THE LOOP AGAIN AND AGAIN WON'T USE UP 18 BYTES OF STACK SPACE EVERY TIME. THE "NEXT" CODE ALSO CALLS "FNDFOR" TO SEARCH FOR A "FOR" ENTRY WITH THE LOOP VARIABLE IN THE "NEXT". AT WHATEVER POINT A MATCH IS FOUND THE STACK IS RESET. IF NO MATCH IS FOUND A "NEXT WITHOUT FOR" ERROR OCCURS. GOSUB EXECUTION ALSO PUTS A 5-BYTE ENTRY ON STACK. WHEN A RETURN IS EXECUTED "FNDFOR" IS CALLED WITH A VARIABLE POINTER THAT CAN'T BE MATCHED. WHEN "FNDFOR" HAS RUN THROUGH ALL THE "FOR" ENTRIES ON THE STACK IT RETURNS AND THE RETURN CODE MAKES SURE THE ENTRY THAT WAS STOPPED ON IS A GOSUB ENTRY. THIS ASSURES THAT IF YOU GOSUB TO A SECTION OF CODE IN WHICH A FOR LOOP IS ENTERED BUT NEVER EXITED THE RETURN WILL STILL BE ABLE TO FIND THE MOST RECENT GOSUB ENTRY. THE "RETURN" CODE ELIMINATES THE "GOSUB" ENTRY AND ALL "FOR" ENTRIES MADE AFTER THE GOSUB ENTRY. NON-RUNTIME STUFF THE CODE TO INPUT A LINE, CRUNCH IT, GIVE ERRORS, FIND A SPECIFIC LINE IN THE PROGRAM, PERFORM A "NEW", "CLEAR", AND "LIST" ARE ALL IN THIS AREA. GIVEN THE EXPLANATION OF PROGRAM STORAGE SET FORTH ABOVE, THESE ARE ALL STRAIGHTFORWARD. NEWSTT WHENEVER A STATEMENT FINISHES EXECUTION IT DOES A "RTS" WHICH TAKES EXECUTION BACK TO "NEWSTT". STATEMENTS THAT CREATE OR LOOK AT SEMI-PERMANENT STACK ENTRIES MUST GET RID OF THE RETURN ADDRESS OF "NEWSTT" AND JMP TO "NEWSTT" WHEN DONE. "NEWSTT" ALWAYS CHRGETS THE FIRST CHARACTER AFTER THE STATEMENT NAME BEFORE DISPATCHING. WHEN RETURNING BACK TO "NEWSTT" THE ONLY THING THAT MUST BE SET UP IS THE TEXT POINTER IN "TXTPTR". "NEWSTT" WILL CHECK TO MAKE SURE "TXTPTR" IS POINTING TO A STATEMENT TERMINATOR. IF A STATEMENT SHOULDN'T BE PERFORMED UNLESS IT IS PROPERLY FORMATTED (I.E. "NEW") IT CAN SIMPLY DO A RETURN AFTER READING ALL OF ITS ARGUMENTS. SINCE THE ZERO FLAG BEING OFF INDICATES THERE IS NOT A STATEMENT TERMINATOR "NEWSTT" WILL DO THE JMP TO THE "SYNTAX ERROR" ROUTINE. IF A STATEMENT SHOULD BE STARTED OVER IT CAN DO LDWD OLDTXT, STWD TXTPTR RTS SINCE THE TEXT PNTR AT "NEWSTT" IS ALWAYS STORED IN "OLDTXT". THE ^C CODE STORES [CURLIN] (THE CURRENT LINE NUMBER) IN "OLDLIN" SINCE THE ^C CHECK IS MADE BEFORE THE STATEMENT POINTED TO IS EXECUTED. "STOP" AND "END" STORE THE TEXT POINTER FROM "TXTPTR", WHICH POINTS AT THEIR TERMINATING CHARACTER, IN "OLDTXT". STATEMENT CODE THE INDIVIDUAL STATEMENT CODE COMES NEXT. THE APPROACH USED IN EXECUTING EACH STATEMENT IS DOCUMENTED IN THE STATEMENT CODE ITSELF. FRMEVL, THE FORMULA EVALUATOR GIVEN A TEXT POINTER POINTING TO THE STARTING CHARACTER OF A FORMULA, "FRMEVL" EVALUATES THE FORMULA AND LEAVES THE VALUE IN THE FLOATING ACCUMULATOR (FAC). "TXTPTR" IS RETURNED POINTING TO THE FIRST CHARACTER THAT COULD NOT BE INTERPRETED AS PART OF THE FORMULA. THE ALGORITHM USES THE STACK TO STORE TEMPORARY RESULTS: 0. PUT A DUMMY PRECEDENCE OF ZERO ON THE STACK. 1. READ LEXEME (CONSTANT,FUNCTION, VARIABLE,FORMULA IN PARENS) AND TAKE THE LAST PRECEDENCE VALUE OFF THE STACK. 2. SEE IF THE NEXT CHARACTER IS AN OPERATOR. IF NOT, CHECK PREVIOUS ONE. THIS MAY CAUSE OPERATOR APPLICATION OR AN ACTUAL RETURN FROM "FRMEVL". 3. IF IT IS, SEE WHAT PRECEDENCE IT HAS AND COMPARE IT TO THE PRECEDENCE OF THE LAST OPERATOR ON THE STACK. 4. IF = OR LESS REMEMBER THE OPERATOR POINTER OF THIS OPERATOR AND BRANCH TO "QCHNUM" TO CAUSE APPLICATION OF THE LAST OPERATOR. EVENTUALLY RETURN TO STEP 2 BY RETURNING TO JUST AFTER "DOPREC". 5. IF GREATER PUT THE LAST PRECEDENCE BACK ON, SAVE THE OPERATOR ADDRESS, CURRENT TEMPORARY RESULT, AND PRECEDENCE AND RETURN TO STEP 1. RELATIONAL OPERATORS ARE ALL HANDLED THROUGH A COMMON ROUTINE. SPECIAL CARE IS TAKEN TO DETECT TYPE MISMATCHES SUCH AS 3+"F". EVAL -- THE ROUTINE TO READ A LEXEME "EVAL" CHECKS FOR THE DIFFERENT TYPES OF ENTITIES IT IS SUPPOSED TO DETECT. LEADING PLUSES ARE IGNORED, DIGITS AND "." CAUSE "FIN" (FLOATING INPUT) TO BE CALLED. FUNCTION NAMES CAUSE THE FORMULA INSIDE THE PARENTHESES TO BE EVALUATED AND THE FUNCTION ROUTINE TO BE CALLED. VARIABLE NAMES CAUSE "PTRGET" TO BE CALLED TO GET A POINTER TO THE VALUE, AND THEN THE VALUE IS PUT INTO THE FAC. AN OPEN PARENTHESIS CAUSES "FRMEVL" TO BE CALLED (RECURSIVELY), AND THE ")" TO BE CHECKED FOR. UNARY OPERATORS (NOT AND NEGATION) PUT THEIR PRECEDENCE ON THE STACK AND ENTER FORMULA EVALUATION AT STEP 1, SO THAT EVERYTHING UP TO AN OPERATOR GREATER THAN THEIR PRECEDENCE OR THE END OF THE FORMULA WILL BE EVALUATED. DIMENSION AND VARIABLE SEARCHING SPACE IS ALLOCATED FOR VARIABLES AS THEY ARE ENCOUNTERED. THUS "DIM" STATEMENTS MUST BE EXECUTED TO HAVE EFFECT. 6 BYTES ARE ALLOCATED FOR EACH SIMPLE VARIABLE, WHETHER IT IS A STRING, NUMBER OR USER DEFINED FUNCTION. THE FIRST TWO BYTES GIVE THE NAME OF THE VARIABLE AND THE LAST FOUR GIVE ITS VALUE. [VARTAB] GIVES THE FIRST LOCATION WHERE A SIMPLE VARIABLE NAME IS FOUND AND [ARYTAB] GIVES THE LOCATION TO STOP SEARCHING FOR SIMPLE VARIABLES. A "FOR" ENTRY HAS A TEXT POINTER AND A POINTER TO A VARIABLE VALUE SO NEITHER THE PROGRAM OR THE SIMPLE VARIABLES CAN BE MOVED WHILE THERE ARE ACTIVE "FOR" ENTRIES ON THE STACK. USER DEFINED FUNCTION VALUES ALSO CONTAIN POINTERS INTO SIMPLE VARIABLE SPACE SO NO USER-DEFINED FUNCTION VALUES CAN BE RETAINED IF SIMPLE VARIABLES ARE MOVED. ADDING A SIMPLE VARIABLE IS JUST ADDING SIX TO [ARYTAB] AND [STREND], BLOCK TRANSFERING THE ARRAY VARIABLES UP BY SIX AND MAKING SURE THE NEW [STREND] IS NOT TOO CLOSE TO THE STRINGS. THIS MOVEMENT OF ARRAY VARIABLES MEANS THAT NO POINTER TO AN ARRAY WILL STAY VALID WHEN NEW SIMPLE VARIABLES CAN BE ENCOUNTERED. THIS IS WHY ARRAY VARIABLES ARE NOT ALLOWED FOR "FOR" LOOP VARIABLES. SETTING UP A NEW ARRAY VARIABLE MERELY INVOLVES BUILDING THE DESCRIPTOR, UPDATING [STREND], AND MAKING SURE THERE IS STILL ENOUGH ROOM BETWEEN [STREND] AND STRING SPACE. "PTRGET", THE ROUTINE WHICH RETURNS A POINTER TO A VARIABLE VALUE, HAS TWO IMPORTANT FLAGS. ONE IS "DIMFLG" WHICH INDICATES WHETHER "DIM" CALLED "PTRGET" OR NOT. IF SO, NO PRIOR ENTRY FOR THE VARIABLE IN QUESTION SHOULD BE FOUND, AND THE INDEX INDICATES HOW MUCH SPACE TO SET ASIDE. SIMPLE VARIABLES CAN BE "DIMENSIONED", BUT THE ONLY EFFECT WILL BE TO SET ASIDE SPACE FOR THE VARIABLE IF IT HASN'T BEEN ENCOUNTERED YET. THE OTHER IMPORTANT FLAG IS "SUBFLG" WHICH INDICATES WHETHER A SUBSCRIPTED VARIABLE SHOULD BE ALLOWED IN THE CURRENT CONTEXT. IF [SUBFLG] IS NON-ZERO THE OPEN PARENTHESIS FOR A SUBSCRIPTED VARIABLE WILL NOT BE SCANNED BY "PTRGET", AND "PTRGET" WILL RETURN WITH A TEXT POINTER POINTING TO THE "(", IF THERE WAS ONE. STRINGS IN THE VARIABLE TABLES STRINGS ARE STORED JUST LIKE NUMERIC VARIABLES. SIMPLE STRINGS HAVE THREE VALUE BYTES WHICH ARE INITIALIZED TO ALL ZEROS (WHICH REPRESENTS THE NULL STRING). THE ONLY DIFFERENCE IN HANDLING IS THAT WHEN "PTRGET" SEES A "$" AFTER THE NAME OF A VARIABLE, "PTRGET" SETS [VALTYP] TO NEGATIVE ONE AND TURNS ON THE MSB (MOST-SIGNIFIGANT-BIT) OF THE VALUE OF THE FIRST CHARACTER OF THE VARIABLE NAME. HAVING THIS BIT ON IN THE NAME OF THE VARIABLE ENSURES THAT THE SEARCH ROUTINE WILL NOT MATCH 'A' WITH 'A$' OR 'A$' WITH 'A'. THE MEANING OF THE THREE VALUE BYTES ARE: LOW LENGTH OF THE STRING LOW 8 BITS HIGH 8 BITS OF THE ADDRESS OF THE CHARACTERS IN THE STRING IF LENGTH.NE.0. MEANINGLESS OTHERWISE. HIGH THE VALUE OF A STRING VARIABLE (THESE 3 BYTES) IS CALLED THE STRING DESCRIPTOR TO DISTINGUISH IT FROM THE ACTUAL STRING DATA. WHENEVER A STRING CONSTANT IS ENCOUNTERED IN A FORMULA OR AS PART OF AN INPUT STRING, OR AS PART OF DATA, "STRLIT" IS CALLED, CAUSING A DESCRIPTOR TO BE BUILT FOR THE STRING. WHEN ASSIGNMENT IS MADE TO A STRING POINTING INTO "BUF" THE VALUE IS COPIED INTO STRING SPACE SINCE [BUF] IS ALWAYS CHANGING. STRING FUNCTIONS AND THE ONE STRING OPERATOR "+" ALWAYS RETURN THEIR VALUES IN STRING SPACE. ASSIGNING A STRING A CONSTANT VALUE IN A PROGRAM THROUGH A "READ" OR ASSIGNMENT STATEMENT WILL NOT USE ANY STRING SPACE SINCE THE STRING DESCRIPTOR WILL POINT INTO THE PROGRAM ITSELF. IN GENERAL, COPYING IS DONE WHEN A STRING VALUE IS IN "BUF", OR IT IS IN STRING SPACE AND THERE IS AN ACTIVE POINTER TO IT. THUS F$=G$ WILL CAUSE COPYING IF G$ HAS ITS STRING DATA IN STRING SPACE. F$=CHR$(7) WILL USE ONE BYTE OF STRING SPACE TO STORE THE NEW ONE CHARACTER STRING CREATED BY "CHR$", BUT THE ASSIGNMENT ITSELF WILL CAUSE NO COPYING SINCE THE ONLY POINTER AT THE NEW STRING IS A TEMPORARY DESCRIPTOR CREATED BY "FRMEVL" WHICH WILL GO AWAY AS SOON AS THE ASSIGNMENT IS DONE. IT IS THE NATURE OF GARBAGE COLLECTION THAT DISALLOWS HAVING TWO STRING DESCRIPTORS POINT TO THE SAME AREA IN STRING SPACE. STRING FUNCTIONS AND OPERATORS MUST PROCEED AS FOLLOWS: 1) FIGURE OUT THE LENGTH OF THEIR RESULT. 2) CALL "GETSPA" TO FIND SPACE FOR THEIR RESULT. THE ARGUMENTS TO THE FUNCTION OR OPERATOR MAY CHANGE SINCE GARBAGE COLLECTION MAY BE INVOKED. THE ONLY THING THAT CAN BE SAVED DURING THE CALL TO "GETSPA" IS A POINTER TO THE DESCRIPTORS OF THE ARGUMENTS. 3) CONSTRUCT THE RESULT DESCRIPTOR IN "DSCTMP". "GETSPA" RETURNS THE LOCATION OF THE AVAILABLE SPACE. 4) CREATE THE NEW VALUE BY COPYING PARTS OF THE ARGUMENTS OR WHATEVER. 5) FREE UP THE ARGUMENTS BY CALLING "FRETMP". 6) JUMP TO "PUTNEW" TO GET THE DESCRIPTOR IN "DSCTMP" TRANSFERRED INTO A NEW STRING TEMPORARY. THE REASON FOR STRING TEMPORARIES IS THAT GARBAGE COLLECTION HAS TO KNOW ABOUT ALL ACTIVE STRING DESCRIPTORS SO IT KNOWS WHAT IS AND ISN'T IN USE. STRING TEMPORARIES ARE USED TO STORE THE DESCRIPTORS OF STRING EXPRESSIONS. INSTEAD OF HAVING AN ACTUAL VALUE STORED IN THE FAC, AND HAVING THE VALUE OF A TEMPORARY RESULT BEING SAVED ON THE STACK, AS HAPPENS WITH NUMERIC VARIABLES, STRINGS HAVE THE POINTER TO A STRING DESCRIPTOR STORED IN THE FAC, AND IT IS THIS POINTER THAT GETS SAVED ON THE STACK BY FORMULA EVALUATION. STRING FUNCTIONS CANNOT FREE THEIR ARGUMENTS UP RIGHT AWAY SINCE "GETSPA" MAY FORCE GARBAGE COLLECTION AND THE ARGUMENT STRINGS MAY BE OVER-WRITTEN SINCE GARBAGE COLLECTION WILL NOT BE ABLE TO FIND AN ACTIVE POINTER TO THEM. FUNCTION AND OPERATOR RESULTS ARE BUILT IN "DSCTMP" SINCE STRING TEMPORARIES ARE ALLOCATED (PUTNEW) AND DEALLOCATED (FRETMP) IN A FIFO ORDERING (I.E. A STACK) SO THE NEW TEMPORARY CANNOT BE SET UP UNTIL THE OLD ONE(S) ARE FREED. TRYING TO BUILD A RESULT IN A TEMPORARY AFTER FREEING UP THE ARGUMENT TEMPORARIES COULD RESULT IN ONE OF THE ARGUMENT TEMPORARIES BEING OVERWRITTEN TOO SOON BY THE NEW RESULT. STRING SPACE IS ALLOCATED AT THE VERY TOP OF MEMORY. "MEMSIZ" POINTS BEYOND THE LAST LOCATION OF STRING SPACE. STRINGS ARE STORED IN HIGH LOCATIONS FIRST. WHENEVER STRING SPACE IS ALLOCATED (GETSPA). [FRETOP], WHICH IS INITIALIZED TO [MEMSIZ], IS UPDATED TO GIVE THE HIGHEST LOCATION IN STRING SPACE THAT IS NOT IN USE. THE RESULT IS THAT [FRETOP] GETS SMALLER AND SMALLER, UNTIL SOME ALLOCATION WOULD MAKE [FRETOP] LESS THAN OR EQUAL TO [STREND]. THIS MEANS STRING SPACE HAS RUN INTO THE THE ARRAYS AND THAT GARBAGE COLLECTION MUST BE CALLED. GARBAGE COLLECTION: 0. [MINPTR]=[STREND] [FRETOP]=[MEMSIZ] 1. [REMMIN]=0 2. FOR EACH STRING DESCRIPTOR (TEMPORARIES, SIMPLE STRINGS, STRING ARRAYS) IF THE STRING IS NOT NULL AND ITS POINTER IS .GT.MINPTR AND .LT.FRETOP, [MINPTR]=THIS STRING DESCRIPTOR'S POINTER, [REMMIN]=POINTER AT THIS STRING DESCRIPTOR. END. 3. IF REMMIN.NE.0 (WE FOUND AN UNCOLLECTED STRING), BLOCK TRANSFER THE STRING DATA POINTED TO IN THE STRING DESCRIPTOR POINTED TO BY "REMMIN" SO THAT THE LAST BYTE OF STRING DATA IS AT [FRETOP]. UPDATE [FRETOP] SO THAT IT POINTS TO THE LOCATION JUST BELOW THE ONE THE STRING DATA WAS MOVED INTO. UPDATE THE POINTER IN THE DESCRIPTOR SO IT POINTS TO THE NEW LOCATION OF THE STRING DATA. GO TO STEP 1. AFTER CALLING GARBAGE COLLECTION "GETSPA" AGAIN CHECKS TO SEE IF [ACCA] CHARACTERS ARE AVAILABLE BETWEEN [STREND] AND [FRETOP]; IF NOT, AN "OUT OF STRING" ERROR IS INVOKED. MATH PACKAGE THE MATH PACKAGE CONTAINS FLOATING INPUT (FIN), FLOATING OUTPUT (FOUT), FLOATING COMPARE (FCOMP) ... AND ALL THE NUMERIC OPERATORS AND FUNCTIONS. THE FORMATS, CONVENTIONS AND ENTRY POINTS ARE ALL DESCRIBED IN THE MATH PACKAGE ITSELF. INIT -- THE INITIALIZATION ROUTINE THE AMOUNT OF MEMORY, TERMINAL WIDTH, AND WHICH FUNCTIONS TO BE RETAINED ARE ASCERTAINED FROM THE USER. A ZERO IS PUT DOWN AT THE FIRST LOCATION NOT USED BY THE MATH-PACKAGE AND [TXTTAB] IS SET UP TO POINT AT THE NEXT LOCATION. THIS DETERMINES WHERE PROGRAM STORAGE WILL START. SPECIAL CHECKS ARE MADE TO MAKE SURE ALL QUESTIONS IN "INIT" ARE ANSWERED REASONABLY, SINCE ONCE "INIT" FINISHES, THE LOCATIONS IT USES ARE USED FOR PROGRAM STORAGE. THE LAST THING "INIT" DOES IS CHANGE LOCATION ZERO TO BE A JUMP TO "READY" INSTEAD OF "INIT". ONCE THIS IS DONE THERE IS NO WAY TO RESTART "INIT". HIGH LOCATIONS * PAGE SUBTTL PAGE ZERO. IFN REALIO-3, START: JMP INIT ;INITIALIZE - SETUP CERTAIN LOCATIONS ;AND DELETE FUNCTIONS IF NOT NEEDED, ;AND CHANGE THIS TO "JMP READY" ;IN CASE USER RESTARTS AT LOC ZERO. RDYJSR: JMP INIT ;CHANGED TO "JMP STROUT" BY "INIT" ;TO HANDLE ERRORS. ADRAYI: ADR(AYINT) ;STORE HERE THE ADDR OF THE ;ROUTINE TO TURN THE FAC INTO A ;TWO BYTE SIGNED INTEGER IN [Y,A] ADRGAY: ADR(GIVAYF)> ;STORE HERE THE ADDR OF THE ;ROUTINE TO CONVERT [Y,A] TO A FLOATING ;POINT NUMBER IN THE FAC. IFN ROMSW, USRPOK: JMP FCERR> ;SET UP ORIG BY INIT. ; ; THIS IS THE "VOLATILE" STORAGE AREA AND NONE OF IT ; CAN BE KEPT IN ROM. ANY CONSTANTS IN THIS AREA CANNOT ; BE KEPT IN A ROM, BUT MUST BE LOADED IN BY THE ; PROGRAM INSTRUCTIONS IN ROM. ; ; --- GENERAL RAM ---: CHARAC: BLOCK 1 ;A DELIMITING CHARACTER. INTEGR= CHARAC ;A ONE-BYTE INTEGER FROM "QINT". ENDCHR: BLOCK 1 ;THE OTHER DELIMITING CHARACTER. COUNT: BLOCK 1 ;A GENERAL COUNTER. ; --- FLAGS ---: DIMFLG: BLOCK 1 ;IN GETTING A POINTER TO A VARIABLE ;IT IS IMPORTANT TO REMEMBER WHETHER IT ;IS BEING DONE FOR "DIM" OR NOT. ;DIMFLG AND VALTYP MUST BE ;CONSECUTIVE LOCATIONS. KIMY= DIMFLG ;PLACE TO PRESERVE Y DURING OUT. VALTYP: BLOCK 1 ;THE TYPE INDICATOR. ;0=NUMERIC 1=STRING. IFN INTPRC, INTFLG: BLOCK 1> ;TELLS IF INTEGER. DORES: BLOCK 1 ;WHETHER CAN OR CAN'T CRUNCH RES'D WORDS. ;TURNED ON WHEN "DATA" ;BEING SCANNED BY CRUNCH SO UNQUOTED ;STRINGS WON'T BE CRUNCHED. GARBFL= DORES ;WHETHER TO DO GARBAGE COLLECTION. SUBFLG: BLOCK 1 ;FLAG WHETHER SUB'D VARIABLE ALLOWED. ;"FOR" AND USER-DEFINED FUNCTION ;POINTER FETCHING TURN ;THIS ON BEFORE CALLING "PTRGET" ;SO ARRAYS WON'T BE DETECTED. ;"STKINI" AND "PTRGET" CLEAR IT. ;ALSO DISALLOWS INTEGERS THERE. INPFLG: BLOCK 1 ;FLAGS WHETHER WE ARE DOING "INPUT" ;OR "READ". TANSGN: BLOCK 1 ;USED IN DETERMINING SIGN OF TANGENT. IFN REALIO, CNTWFL: BLOCK 1> ;SUPPRESS OUTPUT FLAG. ;NON-ZERO MEANS SUPPRESS. ;RESET BY "INPUT", READY AND ERRORS. ;COMPLEMENTED BY INPUT OF ^O. IFE REALIO-4, ;ROOM FOR APPLE PAGE 0 STUFF. ; --- RAM DEALING WITH TERMINAL HANDLING ---: IFN EXTIO, CHANNL: BLOCK 1> ;HOLDS CHANNEL NUMBER. IFN NULCMD, NULCNT: 0> ;NUMBER OF NULLS TO PRINT. IFN REALIO-3, TRMPOS: BLOCK 1> ;POSITION OF TERMINAL CARRIAGE. LINWID: LINLEN ;LENGTH OF LINE (WIDTH). NCMWID: NCMPOS ;POSITION BEYOND WHICH THERE ARE ;NO MORE FIELDS. LINNUM: 0 ;LOCATION TO STORE LINE NUMBER BEFORE BUF ;SO THAT "BLTUC" CAN STORE IT ALL AWAY AT ONCE. 44 ;A COMMA (PRELOAD OR FROM ROM) ;USED BY INPUT STATEMENT SINCE THE ;DATA POINTER ALWAYS STARTS ON A ;COMMA OR TERMINATOR. IFE BUFPAG, BUF: BLOCK BUFLEN> ;TYPE IN STORED HERE. ;DIRECT STATEMENTS EXECUTE OUT OF ;HERE. REMEMBER "INPUT" SMASHES BUF. ;MUST BE ON PAGE ZERO ;OR ASSIGNMENT OF STRING ;VALUES IN DIRECT STATEMENTS WON'T COPY ;INTO STRING SPACE -- WHICH IT MUST. ;N.B. TWO NONZERO BYTES MUST PRECEDE "BUFLNM". ; --- STORAGE FOR TEMPORARY THINGS ---: TEMPPT: BLOCK 1 ;POINTER AT FIRST FREE TEMP DESCRIPTOR. ;INITIALIZED TO POINT TO TEMPST. LASTPT: BLOCK 2 ;POINTER TO LAST-USED STRING TEMPORARY. TEMPST: BLOCK STRSIZ*NUMTMP ;STORAGE FOR NUMTMP TEMP DESCRIPTORS. INDEX1: BLOCK 2 ;INDEXES. INDEX= INDEX1 INDEX2: BLOCK 2 RESHO: BLOCK 1 ;RESULT OF MULTIPLIER AND DIVIDER. IFN ADDPRC, RESMOH: BLOCK 1> ;ONE MORE BYTE. RESMO: BLOCK 1 RESLO: BLOCK 1 ADDEND= RESMO ;TEMPORARY USED BY "UMULT". 0 ;OVERFLOW FOR RES. ; --- POINTERS INTO DYNAMIC DATA STRUCTURES ---; TXTTAB: BLOCK 2 ;POINTER TO BEGINNING OF TEXT. ;DOESN'T CHANGE AFTER BEING ;SETUP BY "INIT". VARTAB: BLOCK 2 ;POINTER TO START OF SIMPLE ;VARIABLE SPACE. ;UPDATED WHENEVER THE SIZE OF THE ;PROGRAM CHANGES, SET TO [TXTTAB] ;BY "SCRATCH" ("NEW"). ARYTAB: BLOCK 2 ;POINTER TO BEGINNING OF ARRAY ;TABLE. ;INCREMENTED BY 6 WHENEVER ;A NEW SIMPLE VARIABLE IS FOUND, AND ;SET TO [VARTAB] BY "CLEARC". STREND: BLOCK 2 ;END OF STORAGE IN USE. ;INCREASED WHENEVER A NEW ARRAY ;OR SIMPLE VARIABLE IS ENCOUNTERED. ;SET TO [VARTAB] BY "CLEARC". FRETOP: BLOCK 2 ;TOP OF STRING FREE SPACE. FRESPC: BLOCK 2 ;POINTER TO NEW STRING. MEMSIZ: BLOCK 2 ;HIGHEST LOCATION IN MEMORY. ; --- LINE NUMBERS AND TEXTUAL POINTERS ---: CURLIN: BLOCK 2 ;CURRENT LINE #. ;SET TO 0,255 FOR DIRECT STATEMENTS. OLDLIN: BLOCK 2 ;OLD LINE NUMBER (SETUP BY ^C,"STOP" ;OR "END" IN A PROGRAM). POKER= LINNUM ;SET UP LOCATION USED BY POKE. ;TEMPORARY FOR INPUT AND READ CODE OLDTXT: BLOCK 2 ;OLD TEXT POINTER. ;POINTS AT STATEMENT TO BE EXEC'D NEXT. DATLIN: BLOCK 2 ;DATA LINE # -- REMEMBER FOR ERRORS. DATPTR: BLOCK 2 ;POINTER TO DATA. INITIALIZED TO POINT ;AT THE ZERO IN FRONT OF [TXTTAB] ;BY "RESTORE" WHICH IS CALLED BY "CLEARC". ;UPDATED BY EXECUTION OF A "READ". INPPTR: BLOCK 2 ;THIS REMEMBERS WHERE INPUT IS COMING FROM. ; --- STUFF USED IN EVALUATIONS ---: VARNAM: BLOCK 2 ;VARIABLE'S NAME IS STORED HERE. VARPNT: BLOCK 2 ;POINTER TO VARIABLE IN MEMORY. FDECPT= VARPNT ;POINTER INTO POWER OF TENS OF "FOUT". FORPNT: BLOCK 2 ;A VARIABLE'S POINTER FOR "FOR" LOOPS ;AND "LET" STATEMENTS. LSTPNT= FORPNT ;PNTR TO LIST STRING. ANDMSK= FORPNT ;THE MASK USED BY WAIT FOR ANDING. EORMSK= FORPNT+1 ;THE MASK FOR EORING IN WAIT. OPPTR: BLOCK 2 ;POINTER TO CURRENT OP'S ENTRY IN "OPTAB". VARTXT= OPPTR ;POINTER INTO LIST OF VARIABLES. OPMASK: BLOCK 1 ;MASK CREATED BY CURRENT OPERATOR. DOMASK=TANSGN ;MASK IN USE BY RELATION OPERATIONS. DEFPNT: BLOCK 2 ;POINTER USED IN FUNCTION DEFINITION. GRBPNT= DEFPNT ;ANOTHER USED IN GARBAGE COLLECTION. DSCPNT: BLOCK 2 ;POINTER TO A STRING DESCRIPTOR. IFN ADDPRC, ;FOR TEMPF3. FOUR6: EXP STRSIZ ;VARIABLE CONSTANT USED BY GARB COLLECT. ; --- ET CETERA ---: JMPER: JMP 60000 SIZE= JMPER+1 OLDOV= JMPER+2 ;THE OLD OVERFLOW. TEMPF3= DEFPNT ;A THIRD FAC TEMPORARY (4 BYTES). TEMPF1: IFN ADDPRC, ;FOR TEMPF1S EXTRA BYTE. HIGHDS: BLOCK 2 ;DESINATION OF HIGHEST ELEMENT IN BLT. HIGHTR: BLOCK 2 ;SOURCE OF HIGHEST ELEMENT TO MOVE. TEMPF2: IFN ADDPRC, ;FOR TEMPF2S EXTRA BYTE. LOWDS: BLOCK 2 ;LOCATION OF LAST BYTE TRANSFERRED INTO. LOWTR: BLOCK 2 ;LAST THING TO MOVE IN BLT. ARYPNT= HIGHDS ;A POINTER USED IN ARRAY BUILDING. GRBTOP= LOWTR ;A POINTER USED IN GARBAGE COLLECTION. DECCNT= LOWDS ;NUMBER OF PLACES BEFORE DECIMAL POINT. TENEXP= LOWDS+1 ;HAS A DPT BEEN INPUT? DPTFLG= LOWTR ;BASE TEN EXPONENT. EXPSGN= LOWTR+1 ;SIGN OF BASE TEN EXPONENT. ; --- THE FLOATING ACCUMULATOR ---: FAC: FACEXP: 0 FACHO: 0 ;MOST SIGNIFICANT BYTE OF MANTISSA. IFN ADDPRC, FACMOH: 0> ;ONE MORE. FACMO: 0 ;MIDDLE ORDER OF MANTISSA. FACLO: 0 ;LEAST SIG BYTE OF MANTISSA. FACSGN: 0 ;SIGN OF FAC (0 OR -1) WHEN UNPACKED. SGNFLG: 0 ;SIGN OF FAC IS PRESERVED BERE BY "FIN". DEGREE= SGNFLG ;A COUNT USED BY POLYNOMIALS. DSCTMP= FAC ;THIS IS WHERE TEMP DESCS ARE BUILT. INDICE= FACMO ;INDICE IS SET UP HERE BY "QINT". BITS: 0 ;SOMETHING FOR "SHIFTR" TO USE. ; --- THE FLOATING ARGUMENT (UNPACKED) ---: ARGEXP: 0 ARGHO: 0 IFN ADDPRC, ARGMO: 0 ARGLO: 0 ARGSGN: 0 ARISGN: 0 ;A SIGN REFLECTING THE RESULT. FACOV: 0 ;OVERFLOW BYTE OF THE FAC. STRNG1= ARISGN ;POINTER TO A STRING OR DESCRIPTOR. FBUFPT: BLOCK 2 ;POINTER INTO FBUFFR USED BY FOUT. BUFPTR= FBUFPT ;POINTER TO BUF USED BY "CRUNCH". STRNG2= FBUFPT ;POINTER TO STRING OR DESC. POLYPT= FBUFPT ;POINTER INTO POLYNOMIAL COEFFICIENTS. CURTOL= FBUFPT ;ABSOLUTE LINEAR INDEX IS FORMED HERE. PAGE SUBTTL RAM CODE. ; THIS CODE GETS CHANGED THROUGHOUT EXECUTION. ; IT IS MADE TO BE FAST THIS WAY. ; ALSO, [X] AND [Y] ARE NOT DISTURBED ; ; "CHRGET" USING [TXTPTR] AS THE CURRENT TEXT PNTR ; FETCHES A NEW CHARACTER INTO ACCA AFTER INCREMENTING [TXTPTR] ; AND SETS CONDITION CODES ACCORDING TO WHAT'S IN ACCA. ; NOT C= NUMERIC ("0" THRU "9") ; Z= ":" OR END-OF-LINE (A NULL) ; ; [ACCA] = NEW CHAR. ; [TXTPTR]=[TXTPTR]+1 ; ; THE FOLLOWING EXISTS IN ROM IF ROM EXISTS AND IS LOADED ; DOWN HERE BY INIT. OTHERWISE IT IS JUST LOADED INTO THIS ; RAM LIKE ALL THE REST OF RAM IS LOADED. ; CHRGET: INC CHRGET+7 ;INCREMENT THE WHOLE TXTPTR. BNE CHRGOT INC CHRGET+8 CHRGOT: LDA 60000 ;A LOAD WITH AN EXT ADDR. TXTPTR= CHRGOT+1 CMPI " " ;SKIP SPACES. BEQ CHRGET QNUM: CMPI ":" ;IS IT A ":"? BCS CHRRTS ;IT IS .GE. ":" SEC SBCI "0" ;ALL CHARS .GT. "9" HAVE RET'D SO SEC SBCI 256-"0" ;SEE IF NUMERIC. ;TURN CARRY ON IF NUMERIC. ;ALSO, SETZ IF NULL. CHRRTS: RTS ;RETURN TO CALLER. RNDX: 128 ;LOADED OR FROM ROM. 79 ;THE INITIAL RANDOM NUMBER. 199 82 IFN ADDPRC, ;ONE MORE BYTE. ORG 255 ;PAGE 1 STUFF COMING UP. LOFBUF: BLOCK 1 ;THE LOW FAC BUFFER. COPYABLE. ;--- PAGE ZERO/ONE BOUNDARY ---. ;MUST HAVE 13 CONTIGUOUS BYTES. FBUFFR: BLOCK 3*ADDPRC+13 ;BUFFER FOR "FOUT". ;ON PAGE 1 SO THAT STRING IS NOT COPIED. ;STACK IS LOCATED HERE. IE FROM THE END OF FBUFFR TO STKEND. PAGE SUBTTL DISPATCH TABLES, RESERVED WORDS, AND ERROR TEXTS. ORG ROMLOC STMDSP: ADR(END-1) ADR(FOR-1) ADR(NEXT-1) ADR(DATA-1) IFN EXTIO, ADR(INPUTN-1)> ADR(INPUT-1) ADR(DIM-1) ADR(READ-1) ADR(LET-1) ADR(GOTO-1) ADR(RUN-1) ADR(IF-1) ADR(RESTORE-1) ADR(GOSUB-1) ADR(RETURN-1) ADR(REM-1) ADR(STOP-1) ADR(ONGOTO-1) IFN NULCMD, ADR(NULL-1)> ADR(FNWAIT-1) IFN DISKO, IFE REALIO-3, ADR(CQLOAD-1) ADR(CQSAVE-1) ADR(CQVERF-1)> IFN REALIO, IFN REALIO-2, IFN REALIO-3, IFN REALIO-5, ADR(LOAD-1) ADR(SAVE-1)>>>> IFN REALIO-1, IFN REALIO-3, IFN REALIO-4, ADR(511) ;ADDRESS OF LOAD ADR(511)>>>> ;ADDRESS OF SAVE ADR(DEF-1) ADR(POKE-1) IFN EXTIO, ADR(PRINTN-1)> ADR(PRINT-1) ADR(CONT-1) IFE REALIO, ADR(DDT-1)> ADR(LIST-1) ADR(CLEAR-1) IFN EXTIO, ADR(CMD-1) ADR(CQSYS-1) ADR(CQOPEN-1) ADR(CQCLOS-1)> IFN GETCMD, ADR(GET-1)> ;FILL W/ GET ADDR. ADR(SCRATH-1) FUNDSP: ADR(SGN) ADR(INT) ADR(ABS) IFE ROMSW, USRLOC: ADR(FCERR)> ;INITIALLY NO USER ROUTINE. IFN ROMSW, USRLOC: ADR(USRPOK)> ADR(FRE) ADR(POS) ADR(SQR) ADR(RND) ADR(LOG) ADR(EXP) IFN KIMROM, REPEAT 4, ADR(FCERR)>> IFE KIMROM, COSFIX: ADR(COS) SINFIX: ADR(SIN) TANFIX: ADR(TAN) ATNFIX: ADR(ATN)> ADR(PEEK) ADR(LEN) ADR(STR) ADR(VAL) ADR(ASC) ADR(CHR) ADR(LEFT) ADR(RIGHT) ADR(MID) OPTAB: 121 ADR(FADDT-1) 121 ADR(FSUBT-1) 123 ADR(FMULTT-1) 123 ADR(FDIVT-1) 127 ADR(FPWRT-1) 80 ADR(ANDOP-1) 70 ADR(OROP-1) NEGTAB: 125 ADR(NEGOP-1) NOTTAB: 90 ADR(NOTOP-1) PTDORL: 100 ;PRECEDENCE. ADR (DOREL-1) ;OPERATOR ADDRESS. ; ; TOKENS FOR RESERVED WORDS ALWAYS HAVE THE MOST ; SIGNIFICANT BIT ON. ; THE LIST OF RESERVED WORDS: ; Q=128-1 DEFINE DCI(A), ;IGNORE ADR(NEWSTT) AND RTS ADDR. FFLOOP: LDA 257,X ;GET STACK ENTRY. CMPI FORTK ;IS IT A "FOR" TOKEN? BNE FFRTS ;NO, NO "FOR" LOOPS WITH THIS PNTR. LDA FORPNT+1 ;GET HIGH. BNE CMPFOR LDA 258,X ;PNTR IS ZERO, SO ASSUME THIS ONE. STA FORPNT LDA 259,X STA FORPNT+1 CMPFOR: CMP 259,X BNE ADDFRS ;NOT THIS ONE. LDA FORPNT ;GET DOWN. CMP 258,X BEQ FFRTS ;WE GOT IT! WE GOT IT! ADDFRS: TXA CLC ;ADD 16 TO X. ADCI FORSIZ TAX ;RESULT BACK INTO X. BNE FFLOOP FFRTS: RTS ;RETURN TO CALLER. ; ; THIS IS THE BLOCK TRANSFER ROUTINE. ; IT MAKES SPACE BY SHOVING EVERYTHING FORWARD. ; ; ON ENTRY: ; [Y,A]=[HIGHDS] (FOR REASON). ; [HIGHDS]= DESTINATION OF [HIGH ADDRESS]. ; [LOWTR]= LOWEST ADDR TO BE TRANSFERRED. ; [HIGHTR]= HIGHEST ADDR TO BE TRANSFERRED. ; ; A CHECK IS MADE TO ASCERTAIN THAT A REASONABLE ; AMOUNT OF SPACE REMAINS BETWEEN THE BOTTOM ; OF THE STRINGS AND THE HIGHEST LOCATION TRANSFERRED INTO. ; ; ON EXIT: ; [LOWTR] ARE UNCHANGED. ; [HIGHTR]=[LOWTR]-200 OCTAL. ; [HIGHDS]=LOWEST ADDR TRANSFERRED INTO MINUS 200 OCTAL. ; BLTU: JSR REASON ;ASCERTAIN THAT STRING SPACE WON'T ;BE OVERRUN. STWD STREND BLTUC: SEC ;PREPARE TO SUBTRACT. LDA HIGHTR SBC LOWTR ;COMPUTE NUMBER OF THINGS TO MOVE. STA INDEX ;SAVE FOR LATER. TAY LDA HIGHTR+1 SBC LOWTR+1 TAX ;PUT IT IN A COUNTER REGISTER. INX ;SO THAT COUNTER ALGORITHM WORKS. TYA ;SEE IF LOW PART OF COUNT IS ZERO. BEQ DECBLT ;YES, GO START MOVING BLOCKS. LDA HIGHTR ;NO, MUST MODIFY BASE ADDR. SEC SBC INDEX ;BORROW IS OFF SINCE [HIGHTR].GT.[LOWTR]. STA HIGHTR ;SAVE MODIFIED BASE ADDR. BCS BLT1 ;IF NO BORROW, GO SHOVE IT. DEC HIGHTR+1 ;BORROW IMPLIES SUB 1 FROM HIGH ORDER. SEC BLT1: LDA HIGHDS ;MOD BASE OF DEST ADDR. SBC INDEX STA HIGHDS BCS MOREN1 ;NO BORROW. DEC HIGHDS+1 ;DECREMENT HIGH ORDER BYTE. BCC MOREN1 ;ALWAYS SKIP. BLTLP: LDADY HIGHTR ;FETCH BYTE TO MOVE STADY HIGHDS ;MOVE IT IN, MOVE IT OUT. MOREN1: DEY BNE BLTLP LDADY HIGHTR ;MOVE LAST OF THE BLOCK. STADY HIGHDS DECBLT: DEC HIGHTR+1 DEC HIGHDS+1 ;START ON NEW BLOCKS. DEX BNE MOREN1 RTS ;RETURN TO CALLER. ; ; THIS ROUTINE IS USED TO ASCERTAIN THAT A GIVEN ; NUMBER OF LOCS REMAIN AVAILABLE FOR THE STACK. ; THE CALL IS: ; LDAI NUMBER OF 2-BYTE ENTRIES NEEDED. ; JSR GETSTK ; ; THIS ROUTINE MUST BE CALLED BY ANY ROUTINE WHICH PUTS ; AN ARBITRARY AMOUNT OF STUFF ON THE STACK, ; I.E., ANY RECURSIVE ROUTINE LIKE "FRMEVL". ; IT IS ALSO CALLED BY ROUTINES SUCH AS "GOSUB" AND "FOR" ; WHICH MAKE PERMANENT ENTRIES ON THE STACK. ; ; ROUTINES WHICH MERELY USE AND FREE UP THE GUARANTEED ; NUMLEV LOCATIONS NEED NOT CALL THIS. ; ; ; ON EXIT: ; [A] AND [X] HAVE BEEN MODIFIED. ; GETSTK: ASL A, ;MULT [A] BY 2. NB, CLEARS C BIT. ADCI 2*NUMLEV++13 ;MAKE SURE 2*NUMLEV+13 LOCS ;(13 BECAUSE OF FBUFFR) BCS OMERR ;WILL REMAIN IN STACK. STA INDEX TSX ;GET STACKED. CPX INDEX ;COMPARE. BCC OMERR ;IF STACK.LE.INDEX1, OM. RTS ; ; [Y,A] IS A CERTAIN ADDRESS. "REASON" MAKES SURE ; IT IS LESS THAN [FRETOP]. ; REASON: CPY FRETOP+1 BCC REARTS BNE TRYMOR ;GO GARB COLLECT. CMP FRETOP BCC REARTS TRYMOR: PHA LDXI 8+ADDPRC ;IF TEMPF2 HAS ZERO IN BETWEEN. TYA REASAV: PHA LDA HIGHDS-1,X ;SAVE HIGHDS ON STACK. DEX BPL REASAV ;PUT 8 OF THEM ON STK. JSR GARBA2 ;GO GARB COLLECT. LDXI 256-8-ADDPRC REASTO: PLA STA HIGHDS+8+ADDPRC,X ;RESTORE AFTER GARB COLLECT. INX BMI REASTO PLA TAY PLA ;RESTORE A AND Y. CPY FRETOP+1 ;COMPARE HIGHS BCC REARTS BNE OMERR ;HIGHER IS BAD. CMP FRETOP ;AND THE LOWS. BCS OMERR REARTS: RTS PAGE SUBTTL ERROR HANDLER, READY, TERMINAL INPUT, COMPACTIFY, NEW, REINIT. OMERR: LDXI ERROM ERROR: IFN REALIO, LSR CNTWFL> ;FORCE OUTPUT. IFN EXTIO, LDA CHANNL ;CLOSE NON-TERMINAL CHANNEL. BEQ ERRCRD JSR CQCCHN ;CLOSE IT. LDAI 0 STA CHANNL> ERRCRD: JSR CRDO ;OUTPUT CRLF. JSR OUTQST ;PRINT A QUESTION MARK IFE LNGERR, LDA ERRTAB,X, ;GET FIRST CHR OF ERR MSG. JSR OUTDO ;OUTPUT IT. LDA ERRTAB+1,X, ;GET SECOND CHR. JSR OUTDO> ;OUTPUT IT. IFN LNGERR, GETERR: LDA ERRTAB,X PHA ANDI 127 ;GET RID OF HIGH BIT. JSR OUTDO ;OUTPUT IT. INX PLA ;LAST CHAR OF MESSAGE? BPL GETERR> ;NO. GO GET NEXT AND OUTPUT IT. TYPERR: JSR STKINI ;RESET THE STACK AND FLAGS. LDWDI ERR ;GET PNTR TO " ERROR". ERRFIN: JSR STROUT ;OUTPUT IT. LDY CURLIN+1 INY ;WAS NUMBER 64000? BEQ READY ;YES, DON'T TYPE LINE NUMBER. JSR INPRT READY: IFN REALIO, LSR CNTWFL> ;TURN OUTPUT BACK ON IF SUPRESSED LDWDI REDDY ;SAY "OK". IFN REALIO-3, JSR RDYJSR> ;OR GO TO INIT IF INIT ERROR. IFE REALIO-3, JSR STROUT> ;NO INIT ERRORS POSSIBLE. MAIN: JSR INLIN ;GET A LINE FROM TERMINAL. STXY TXTPTR JSR CHRGET TAX ;SET ZERO FLAG BASED ON [A] ;THIS DISTINGUISHES ":" AND 0 BEQ MAIN ;IF BLANK LINE, GET ANOTHER. LDXI 255 ;SET DIRECT LINE NUMBER. STX CURLIN+1 BCC MAIN1 ;IS A LINE NUMBER. NOT DIRECT. JSR CRUNCH ;COMPACTIFY. JMP GONE ;EXECUTE IT. MAIN1: JSR LINGET ;READ LINE NUMBER INTO "LINNUM". JSR CRUNCH STY COUNT ;RETAIN CHARACTER COUNT. JSR FNDLIN BCC NODEL ;NO MATCH, SO DON'T DELETE. LDYI 1 LDADY LOWTR STA INDEX1+1 LDA VARTAB STA INDEX1 LDA LOWTR+1 ;SET TRANSFER TO. STA INDEX2+1 LDA LOWTR DEY SBCDY LOWTR ;COMPUTE NEGATIVE LENGTH. CLC ADC VARTAB ;COMPUTE NEW VARTAB. STA VARTAB STA INDEX2 ;SET LOW OF TRANS TO. LDA VARTAB+1 ADCI 255 STA VARTAB+1 ;COMPUTE HIGH OF VARTAB. SBC LOWTR+1 ;COMPUTE NUMBER OF BLOCKS TO MOVE. TAX SEC LDA LOWTR SBC VARTAB ;COMPUTE OFFSET. TAY BCS QDECT1 ;IF VARTAB.LE.LOWTR, INX ;DECR DUE TO CARRY, AND DEC INDEX2+1 ;DECREMENT STORE SO CARRY WORKS. QDECT1: CLC ADC INDEX1 BCC MLOOP DEC INDEX1+1 CLC ;FOR LATER ADCQ MLOOP: LDADY INDEX1 STADY INDEX2 INY BNE MLOOP ;BLOCK DONE? INC INDEX1+1 INC INDEX2+1 DEX BNE MLOOP ;DO ANOTHER BLOCK. ALWAYS. NODEL: JSR RUNC ;RESET ALL VARIABLE INFO SO GARBAGE ;COLLECTION CAUSED BY REASON WILL WORK JSR LNKPRG ;FIX UP THE LINKS LDA BUF ;SEE IF ANYTHNG THERE BEQ MAIN CLC LDA VARTAB STA HIGHTR ;SETUP HIGHTR. ADC COUNT ;ADD LENGTH OF LINE TO INSERT. STA HIGHDS ;THIS GIVES DEST ADDR. LDY VARTAB+1 STY HIGHTR+1 ;SAME FOR HIGH ORDERS. BCC NODELC INY NODELC: STY HIGHDS+1 JSR BLTU IFN BUFPAG, LDWD LINNUM ;POSITION THE BINARY LINE NUMBER STWD BUF-2> ;IN FRONT OF BUF LDWD STREND STWD VARTAB LDY COUNT DEY STOLOP: LDA BUF-4,Y STADY LOWTR DEY BPL STOLOP FINI: JSR RUNC ;DO CLEAR & SET UP STACK. ;AND SET [TXTPTR] TO [TXTTAB]-1. JSR LNKPRG ;FIX UP PROGRAM LINKS JMP MAIN LNKPRG: LDWD TXTTAB ;SET [INDEX] TO [TXTTAB]. STWD INDEX CLC ; ; CHEAD GOES THROUGH PROGRAM STORAGE AND FIXES ; UP ALL THE LINKS. THE END OF EACH LINE IS FOUND ; BY SEARCHING FOR THE ZERO AT THE END. ; THE DOUBLE ZERO LINK IS USED TO DETECT THE END OF THE PROGRAM. ; CHEAD: LDYI 1 LDADY INDEX ;ARRIVED AT DOUBLE ZEROES? BEQ LNKRTS LDYI 4 CZLOOP: INY ;THERE IS AT LEAST ONE BYTE. LDADY INDEX BNE CZLOOP ;NO, CONTINUE SEARCHING. INY ;GO ONE BEYOND. TYA ADC INDEX TAX LDYI 0 STADY INDEX LDA INDEX+1 ADCI 0 INY STADY INDEX STX INDEX STA INDEX+1 BCCA CHEAD ;ALWAYS BRANCHES. LNKRTS: RTS ; ; THIS IS THE LINE INPUT ROUTINE. ; IT READS CHARACTERS INTO BUF USING BACKARROW (UNDERSCORE, OR ; SHIFT O) AS THE DELETE CHARACTER AND @ AS THE ; LINE DELETE CHARACTER. IF MORE THAN BUFLEN CHARACTERS ; ARE TYPED, NO ECHOING IS DONE UNTIL A BACKARROW OR @ OR CR ; IS TYPED. CONTROL-G WILL BE TYPED FOR EACH EXTRA CHARACTER. ; THE ROUTINE IS ENTERED AT INLIN. ; IFE REALIO-4, INLIN: LDXI 128 ;NO PROMPT CHARACTER STX CQPRMP JSR CQINLN ;GET A LINE ONTO PAGE 2 CPXI BUFLEN-1 BCS GDBUFS ;NOT TOO MANY CHARACTERS LDXI BUFLEN-1 GDBUFS: LDAI 0 ;PUT A ZERO AT THE END STA BUF,X TXA BEQ NOCHR LOPBHT: LDA BUF-1,X ANDI 127 STA BUF-1,X DEX BNE LOPBHT NOCHR: LDAI 0 LDXYI ;POINT AT THE BEGINNING RTS> IFN REALIO-4, IFN REALIO-3, LINLIN: IFE REALIO-2, JSR OUTDO> ;ECHO IT. DEX ;BACKARROW SO BACKUP PNTR AND BPL INLINC ;GET ANOTHER IF COUNT IS POSITIVE. INLINN: IFE REALIO-2, JSR OUTDO> ;PRINT THE @ OR A SECOND BACKARROW ;IF THERE WERE TOO MANY. JSR CRDO> INLIN: LDXI 0 INLINC: JSR INCHR ;GET A CHARACTER. IFN REALIO-3, CMPI 7 ;IS IT BOB ALBRECHT RINGING THE BELL ;FOR SCHOOL KIDS? BEQ GOODCH> CMPI 13 ;CARRIAGE RETURN? BEQ FININ1 ;YES, FINISH UP. IFN REALIO-3, CMPI 32 ;CHECK FOR FUNNY CHARACTERS. BCC INLINC CMPI 125 ;IS IT TILDA OR DELETE? BCS INLINC ;BIG BAD ONES TOO. CMPI "@" ;LINE DELETE? BEQ INLINN ;YES. CMPI "_" ;CHARACTER DELETE? BEQ LINLIN> ;YES. GOODCH: IFN REALIO-3, CPXI BUFLEN-1 ;LEAVE ROOM FOR NULL. ;COMMO ASSURES US NEVER MORE THAN BUFLEN. BCS OUTBEL> STA BUF,X INX IFE REALIO-2, IFN REALIO-2, IFN REALIO-3, OUTBEL: LDAI 7 IFN REALIO, JSR OUTDO> ;ECHO IT. BNE INLINC> ;CYCLE ALWAYS. FININ1: JMP FININL> ;GO TO FININL FAR, FAR AWAY. INCHR: IFE REALIO-3, JSR CQINCH> ;FOR COMMODORE. IFE REALIO-2, INCHRL: LDA ^O176000 REPEAT 4, LSR A, BCC INCHRL LDA ^O176001 ;GET THE CHARACTER. REPEAT 4, ANDI 127> IFE REALIO-1, JSR ^O17132> ;1E5A FOR MOS TECH. IFE REALIO-4, JSR CQINCH ;FD0C FOR APPLE COMPUTER. ANDI 127> IFE REALIO, TJSR INSIM##> ;GET A CHARACTER FROM SIMULATOR IFN REALIO, IFN EXTIO, LDY CHANNL ;CNT-O HAS NO EFFECT IF NOT FROM TERM. BNE INCRTS> CMPI CONTW ;SUPPRESS OUTPUT CHARACTER (^W). BNE INCRTS ;NO, RETURN. PHA COM CNTWFL ;COMPLEMENT ITS STATE. PLA> INCRTS: RTS ;END OF INCHR. ; ; ALL "RESERVED" WORDS ARE TRANSLATED INTO SINGLE ; BYTES WITH THE MSB ON. THIS SAVES SPACE AND TIME ; BY ALLOWING FOR TABLE DISPATCH DURING EXECUTION. ; THEREFORE ALL STATEMENTS APPEAR TOGETHER IN THE ; RESERVED WORD LIST IN THE SAME ORDER THEY ; APPEAR IN STMDSP. ; BUFOFS=0 ;THE AMOUNT TO OFFSET THE LOW BYTE ;OF THE TEXT POINTER TO GET TO BUF ;AFTER TXTPTR HAS BEEN SETUP TO POINT INTO BUF IFN BUFPAG, BUFOFS=*256> CRUNCH: LDX TXTPTR ;SET SOURCE POINTER. LDYI 4 ;SET DESTINATION OFFSET. STY DORES ;ALLOW CRUNCHING. KLOOP: LDA BUFOFS,X IFE REALIO-3, BPL CMPSPC ;GO LOOK AT SPACES. CMPI PI ;PI?? BEQ STUFFH ;GO SAVE IT. INX ;SKIP NO PRINTING. BNE KLOOP> ;ALWAYS GOES. CMPSPC: CMPI " " ;IS IT A SPACE TO SAVE? BEQ STUFFH ;YES, GO SAVE IT. STA ENDCHR ;IF IT'S A QUOTE, THIS WILL ;STOP LOOP WHEN OTHER QUOTE APPEARS. CMPI 34 ;QUOTE SIGN? BEQ STRNG ;YES, DO SPECIAL STRING HANDLING. BIT DORES ;TEST FLAG. BVS STUFFH ;NO CRUNCH, JUST STORE. CMPI "?" ;A QMARK? BNE KLOOP1 LDAI PRINTK ;YES, STUFF A "PRINT" TOKEN. BNE STUFFH ;ALWAYS GO TO STUFFH. KLOOP1: CMPI "0" ;SKIP NUMERICS. BCC MUSTCR CMPI 60 ;":" AND ";" ARE ENTERED STRAIGHTAWAY. BCC STUFFH MUSTCR: STY BUFPTR ;SAVE BUFFER POINTER. LDYI 0 ;LOAD RESLST POINTER. STY COUNT ;ALSO CLEAR COUNT. DEY STX TXTPTR ;SAVE TEXT POINTER FOR LATER USE. DEX RESER: INY RESPUL: INX RESCON: LDA BUFOFS,X SEC ;PREPARE TO SUBSTARCT. SBC RESLST,Y ;CHARACTERS EQUAL? BEQ RESER ;YES, CONTINUE SEARCH. CMPI 128 ;NO BUT MAYBE THE END IS HERE. BNE NTHIS ;NO, TRULY UNEQUAL. ORA COUNT GETBPT: LDY BUFPTR ;GET BUFFER PNTR. STUFFH: INX INY STA BUF-5,Y LDA BUF-5,Y BEQ CRDONE ;NULL IMPLIES END OF LINE. SEC ;PREPARE TO SUBSTARCT. SBCI ":" ;IS IT A ":"? BEQ COLIS ;YES, ALLOW CRUNCHING AGAIN. CMPI DATATK-":" ;IS IT A DATATK? BNE NODATT ;NO, SEE IF IT IS REM TOKEN. COLIS: STA DORES ;SETUP FLAG. NODATT: SEC ;PREP TO SBCQ SBCI REMTK-":" ;REM ONLY STOPS ON NULL. BNE KLOOP ;NO, CONTINUE CRUNCHING. STA ENDCHR ;REM STOPS ONLY ON NULL, NOT : OR ". STR1: LDA BUFOFS,X BEQ STUFFH ;YES, END OF LINE, SO DONE. CMP ENDCHR ;END OF GOBBLE? BEQ STUFFH ;YES, DONE WITH STRING. STRNG: INY ;INCREMENT BUFFER POINTER. STA BUF-5,Y INX BNE STR1 ;PROCESS NEXT CHARACTER. NTHIS: LDX TXTPTR ;RESTORE TEXT POINTER. INC COUNT ;INCREMENT RES WORD COUNT. NTHIS1: INY LDA RESLST-1,Y, ;GET RES CHARACTER. BPL NTHIS1 ;END OF ENTRY? LDA RESLST,Y, ;YES. IS IT THE END? BNE RESCON ;NO, TRY THE NEXT WORD. LDA BUFOFS,X ;YES, END OF TABLE. GET 1ST CHR. BPL GETBPT ;STORE IT AWAY (ALWAYS BRANCHES). CRDONE: STA BUF-3,Y, ;SO THAT IF THIS IS A DIR STATEMENT ;ITS END WILL LOOK LIKE END OF PROGRAM. IFN 256>-256>, DEC TXTPTR+1> LDAI -1 ;MAKE TXTPTR POINT TO STA TXTPTR ;CRUNCHED LINE. LISTRT: RTS ;RETURN TO CALLER. ; ; FNDLIN SEARCHES THE PROGRAM TEXT FOR THE LINE ; WHOSE NUMBER IS PASSED IN "LINNUM". ; THERE ARE TWO POSSIBLE RETURNS: ; ; 1) CARRY SET. ; LOWTR POINTS TO THE LINK FIELD IN THE LINE ; WHICH IS THE ONE SEARCHED FOR. ; ; 2) CARRY NOT SET. ; LINE NOT FOUND. [LOWTR] POINTS TO THE LINE IN THE ; PROGRAM GREATER THAN THE ONE SOUGHT AFTER. ; FNDLIN: LDWX TXTTAB ;LOAD [X,A] WITH [TXTTAB] FNDLNC: LDYI 1 STWX LOWTR ;STORE [X,A] INTO LOWTR LDADY LOWTR ;SEE IF LINK IS 0 BEQ FLINRT INY INY LDA LINNUM+1 ;COMP HIGH ORDERS OF LINE NUMBERS. CMPDY LOWTR BCC FLNRTS ;NO SUCH LINE NUMBER. BEQ FNDLO1 DEY BNE AFFRTS ;ALWAYS BRANCH. FNDLO1: LDA LINNUM DEY CMPDY LOWTR ;COMPARE LOW ORDERS. BCC FLNRTS ;NO SUCH NUMBER. BEQ FLNRTS ;GO TIT. AFFRTS: DEY LDADY LOWTR ;FETCH LINK. TAX DEY LDADY LOWTR BCS FNDLNC ;ALWAYS BRANCHES. FLINRT: CLC ;C MAY BE HIGH. FLNRTS: RTS ;RETURN TO CALLER. ; ; THE "NEW" COMMAND CLEARS THE PROGRAM TEXT AS WELL ; AS VARIABLE SPACE. ; SCRATH: BNE FLNRTS ;MAKE SURE THERE IS A TERMINATOR. SCRTCH: LDAI 0 ;GET A CLEARER. TAY ;SET UP INDEX. STADY TXTTAB ;CLEAR FIRST LINK. INY STADY TXTTAB LDA TXTTAB CLC ADCI 2 STA VARTAB ;SETUP [VARTAB]. LDA TXTTAB+1 ADCI 0 STA VARTAB+1 RUNC: JSR STXTPT LDAI 0 ;SET ZERO FLAG ; ; THIS CODE IS FOR THE CLEAR COMMAND. ; CLEAR: BNE STKRTS ;SYNTAX ERROR IF NO TERMINATOR. ; ; CLEAR INITIALIZES THE VARIABLE AND ; ARRAY SPACE BY RESETING ARYTAB (THE END OF SIMPLE VARIABLE SPACE) ; AND STREND (THE END OF ARRAY STORAGE). IT FALLS INTO "STKINI" ; WHICH RESETS THE STACK. ; CLEARC: LDWD MEMSIZ ;FREE UP STRING SPACE. STWD FRETOP IFN EXTIO, JSR CQCALL> ;CLOSE ALL OPEN FILES. LDWD VARTAB ;LIBERATE THE STWD ARYTAB ;VARIABLES AND STWD STREND ;ARRAYS. FLOAD: JSR RESTOR ;RESTORE DATA. ; ; STKINI RESETS THE STACK POINTER ELIMINATING ; GOSUB AND FOR CONTEXT. STRING TEMPORARIES ARE FREED ; UP, SUBFLG IS RESET. CONTINUING IS PROHIBITED. ; AND A DUMMY ENTRY IS LEFT AT THE BOTTOM OF THE STACK SO "FNDFOR" WILL ALWAYS ; FIND A NON-"FOR" ENTRY AT THE BOTTOM OF THE STACK. ; STKINI: LDXI TEMPST ;INITIALIZE STRING TEMPORARIES. STX TEMPPT PLA ;SETUP RETURN ADDRESS. TAY PLA LDXI STKEND-257 TXS PHA TYA PHA LDAI 0 STA OLDTXT+1 ;DISALLOWING CONTINUING STA SUBFLG ;ALLOW SUBSCRIPTS. STKRTS: RTS STXTPT: CLC LDA TXTTAB ADCI 255 STA TXTPTR LDA TXTTAB+1 ADCI 255 STA TXTPTR+1 ;SETUP TEXT POINTER. RTS PAGE SUBTTL THE "LIST" COMMAND. LIST: BCC GOLST ;IT IS A DIGIT. BEQ GOLST ;IT IS A TERMINATOR. CMPI MINUTK ;DASH PRECEDING? BNE STKRTS ;NO, SO SYNTAX ERROR. GOLST: JSR LINGET ;GET LINE NUMBER INTO NUMLIN. JSR FNDLIN ;FIND LINE .GE. [NUMLIN]. JSR CHRGOT ;GET LAST CHARACTER. BEQ LSTEND ;IF END OF LINE, # IS THE END. CMPI MINUTK ;DASH? BNE FLNRTS ;IF NOT, SYNTAX ERROR. JSR CHRGET ;GET NEXT CHAR. JSR LINGET ;GET END #. BNE FLNRTS ;IF NOT TERMINATOR, ERROR. LSTEND: PLA PLA ;GET RID OF "NEWSTT" RTS ADDR. LDA LINNUM ;SEE IF IT WAS EXISTENT. ORA LINNUM+1 BNE LIST4 ;IT WAS TYPED. LDAI 255 STA LINNUM STA LINNUM+1 ;MAKE IT HUGE. LIST4: LDYI 1 IFE REALIO-3, STY DORES> LDADY LOWTR ;IS LINK ZERO? BEQ GRODY ;YES, GO TO READY. IFN REALIO, JSR ISCNTC> ;LISTEN FOR CONT-C. JSR CRDO ;PRINT CRLF TO START WITH. INY LDADY LOWTR TAX INY LDADY LOWTR ;GET LINE NUMBER. CMP LINNUM+1 ;SEE IF BEYOND LAST. BNE TSTDUN ;GO DETERMINE RELATION. CPX LINNUM ;WAS EQUAL SO TEST LOW ORDER. BEQ TYPLIN ;EQUAL, SO LIST IT. TSTDUN: BCS GRODY ;IF LINE IS GR THAN LAST, THEN DUNE. TYPLIN: STY LSTPNT JSR LINPRT ;PRINT AS INT WITHOUT LEADING SPACE. LDAI " " ;ALWAYS PRINT SPACE AFTER NUMBER. PRIT4: LDY LSTPNT ;GET POINTER TO LINE BACK. ANDI 127 PLOOP: JSR OUTDO ;PRINT CHAR. IFE REALIO-3, CMPI 34 BNE PLOOP1 COM DORES> ;IF QUOTE, COMPLEMENT FLAG. PLOOP1: INY BEQ GRODY ;IF WE HAVE PRINTED 256 CHARACTERS ;THE PROGRAM MUST BE MISFORMATED IN ;MEMORY DUE TO A BAD LOAD OR BAD ;HARDWARE. LET THE GUY RECOVER LDADY LOWTR ;GET NEXT CHAR. IS IT ZERO? BNE QPLOP ;YES. END OF LINE. TAY LDADY LOWTR TAX INY LDADY LOWTR STX LOWTR STA LOWTR+1 BNE LIST4 ;BRANCH IF SOMETHING TO LIST. GRODY: JMP READY ;IS IT A TOKEN? QPLOP: BPL PLOOP ;NO, HEAD FOR PRINTER. IFE REALIO-3, CMPI PI BEQ PLOOP BIT DORES ;INSIDE QUOTE MARKS? BMI PLOOP> ;YES, JUST TYPE THE CHARACTER. SEC SBCI 127 ;GET RID OF SIGN BIT AND ADD 1. TAX ;MAKE IT A COUNTER. STY LSTPNT ;SAVE POINTER TO LINE. LDYI 255 ;LOOK AT RES'D WORD LIST. RESRCH: DEX ;IS THIS THE RES'D WORD? BEQ PRIT3 ;YES, GO TOSS IT UP.. RESCR1: INY LDA RESLST,Y, ;END OF ENTRY? BPL RESCR1 ;NO, CONTINUE PASSING. BMI RESRCH PRIT3: INY LDA RESLST,Y BMI PRIT4 ;END OF RESERVED WORD. JSR OUTDO ;PRINT IT. BNE PRIT3 ;END OF ENTRY? NO, TYPE REST. PAGE SUBTTL THE "FOR" STATEMENT. ; ; A "FOR" ENTRY ON THE STACK HAS THE FOLLOWING FORMAT: ; ; LOW ADDRESS ; TOKEN (FORTK) 1 BYTE ; A POINTER TO THE LOOP VARIABLE 2 BYTES ; THE STEP 4+ADDPRC BYTES ; A BYTE REFLECTING THE SIGN OF THE INCREMENT 1 BYTE ; THE UPPER VALUE 4+ADDPRC BYTES ; THE LINE NUMBER OF THE "FOR" STATEMENT 2 BYTES ; A TEXT POINTER INTO THE "FOR" STATEMENT 2 BYTES ; HIGH ADDRESS ; ; TOTAL 16+2*ADDPRC BYTES. ; FOR: LDAI 128 ;DON'T RECOGNIZE STA SUBFLG ;SUBSCRIPTED VARIABLES. JSR LET ;READ THE VARIABLE AND ASSIGN IT ;THE CORRECT INITIAL VALUE AND STORE ;A POINTER TO THE VARIABLE IN VARPNT. JSR FNDFOR ;PNTR IS IN VARPNT, AND FORPNT. BNE NOTOL ;IF NO MATCH, DON'T ELIMINATE ANYTHING. TXA ;MAKE IT ARITHMETICAL. ADCI FORSIZ-3 ;ELIMINATE ALMOST ALL. TAX ;NOTE C=1, THEN PLA, PLA. TXS ;MANIFEST. NOTOL: PLA ;GET RID OF NEWSTT RETURN ADDRESS PLA ;IN CASE THIS IS A TOTALLY NEW ENTRY. LDAI 8+ADDPRC JSR GETSTK ;MAKE SURE 16 BYTES ARE AVAILABLE. JSR DATAN ;GET A COUNT IN [Y] OF THE NUMBER OF ;CHACRACTERS LEFT IN THE "FOR" STATEMENT ;[TXTPTR] IS UNAFFECTED. CLC ;PREP TO ADD. TYA ;SAVE IT FOR PUSHING. ADC TXTPTR PHA LDA TXTPTR+1 ADCI 0 PHA PSHWD CURLIN ;PUT LINE NUMBER ON STACK. SYNCHK TOTK ;"TO" IS NECESSARY. JSR CHKNUM ;VALUE MUST BE A NUMBER. JSR FRMNUM ;GET UPPER VALUE INTO FAC. LDA FACSGN ;PACK FAC. ORAI 127 AND FACHO STA FACHO ;SET PACKED SIGN BIT. LDWDI LDFONE STWD INDEX1 JMP FORPSH ;PUT FAC ONTO STACK, PACKED. LDFONE: LDWDI FONE ;PUT 1.0 INTO FAC. JSR MOVFM JSR CHRGOT CMPI STEPTK ;A STEP IS GIVEN? BNE ONEON ;NO. ASSUME 1.0. JSR CHRGET ;YES. ADVANCE POINTER. JSR FRMNUM ;READ THE STEP. ONEON: JSR SIGN ;GET SIGN IN ACCA. JSR PUSHF ;PUSH FAC ONTO STACK (THRU A). PSHWD FORPNT ;PUT PNTR TO VARIABLE ON STACK. NXTCON: LDAI FORTK ;PUT A FORTK ONTO STACK. PHA ; BNEA NEWSTT ;SIMULATE BNE TO NEWSTT. JUST FALL IN. PAGE SUBTTL NEW STATEMENT FETCHER. ; ; BACK HERE FOR NEW STATEMENT. CHARACTER POINTED TO BY TXTPTR ; IS ":" OR END-OF-LINE. THE ADDRESS OF THIS LOC IS LEFT ; ON THE STACK WHEN A STATEMENT IS EXECUTED SO THAT ; IT CAN MERELY DO A RTS WHEN IT IS DONE. ; NEWSTT: IFN REALIO, JSR ISCNTC> ;LISTEN FOR CONTROL-C. LDWD TXTPTR ;LOOK AT CURRENT CHARACTER. IFN BUFPAG, CPYI BUFPAG> ;SEE IF IT WAS DIRECT BY CHECK FOR BUF'S PAGE NUMBER BEQ DIRCON STWD OLDTXT ;SAVE IN CASE OF RESTART BY INPUT. IFN BUFPAG, LDYI 0 IFE BUFPAG, LDADY TXTPTR BNE MORSTS ;NOT NULL -- CHECK WHAT IT IS LDYI 2 ;LOOK AT LINK. LDADY TXTPTR ;IS LINK 0? CLC ;CLEAR CARRY FOR ENDCON AND MATH THAT FOLLOWS JEQ ENDCON ;YES - RAN OFF THE END. INY ;PUT LINE NUMBER IN CURLIN. LDADY TXTPTR STA CURLIN INY LDADY TXTPTR STA CURLIN+1 TYA ADC TXTPTR STA TXTPTR BCC GONE INC TXTPTR+1 GONE: JSR CHRGET ;GET THE STATEMENT TYPE. JSR GONE3 JMP NEWSTT GONE3: BEQ ISCRTS ;IF TERMINATOR, TRY AGAIN. ;NO NEED TO SET UP CARRY SINCE IT WILL ;BE ON IF NON-NUMERIC AND NUMERICS ;WILL CAUSE A SYNTAX ERROR LIKE THEY SHOULD GONE2: SBCI ENDTK ;" ON ... GOTO AND GOSUB" COME HERE. BCC GLET CMPI SCRATK-ENDTK+1 BCS SNERRX ;SOME RES'D WORD BUT NOT ;A STATEMENT RES'D WORD. ASL A, ;MULTIPLY BY TWO. TAY ;MAKE AN INDEX. LDA STMDSP+1,Y PHA LDA STMDSP,Y PHA ;PUT DISP ADDR ONTO STACK. JMP CHRGET GLET: JMP LET ;MUST BE A LET MORSTS: CMPI ":" BEQ GONE ;IF A ":" CONTINUE STATEMENT SNERR1: JMP SNERR ;NEITHER 0 OR ":" SO SYNTAX ERROR SNERRX: CMPI GOTK-ENDTK BNE SNERR1 JSR CHRGET ;READ IN THE CHARACTER AFTER "GO " SYNCHK TOTK JMP GOTO PAGE SUBTTL RESTORE,STOP,END,CONTINUE,NULL,CLEAR. RESTOR: SEC LDA TXTTAB SBCI 1 LDY TXTTAB+1 BCS RESFIN DEY RESFIN: STWD DATPTR ;READ FINISHES COME TO "RESFIN". ISCRTS: RTS IFE REALIO-1, ISCNTC: LDAI 1 BIT ^O13500 BMI ISCRTS LDXI 8 LDAI 3 CMPI 3> IFE REALIO-2, ISCNTC: LDA ^O176000 REPEAT 4, LSR A, BCC ISCRTS JSR INCHR ;EAT CHAR THAT WAS TYPED CMPI 3> ;WAS IT A CONTROL-C?? IFE REALIO-4, ISCNTC: LDA ^O140000 ;CHECK THE CHARACTER CMPI ^O203 BEQ ISCCAP RTS ISCCAP: JSR INCHR CMPI ^O203> STOP: BCS STOPC ;MAKE [C] NONZERO AS A FLAG. END: CLC STOPC: BNE CONTRT ;RETURN IF NOT CONT-C OR ;IF NO TERMINATOR FOR STOP OR END. ;[C]=0 SO WILL NOT PRINT "BREAK". LDWD TXTPTR IFN BUFPAG, LDX CURLIN+1 INX> BEQ DIRIS STWD OLDTXT STPEND: LDWD CURLIN STWD OLDLIN DIRIS: PLA ;POP OFF NEWSTT ADDR. PLA ENDCON: LDWDI BRKTXT IFN REALIO, LDXI 0 STX CNTWFL> BCC GORDY ;CARRY CLEAR SO DON'T PRINT "BREAK". JMP ERRFIN GORDY: JMP READY ;TYPE "READY". IFE REALIO, DDT: PLA ;GET RID OF NEWSTT RETURN. PLA HRRZ 14,.JBDDT## JRST 0(14)> CONT: BNE CONTRT ;MAKE SURE THERE IS A TERMINATOR. LDXI ERRCN ;CONTINUE ERROR. LDY OLDTXT+1 ;A STORED TXTPTR OF ZERO IS SETUP ;BY STKINI AND INDICATES THERE IS ;NOTHING TO CONTINUE. JEQ ERROR ;"STOP", "END", TYPING CRLF TO ;"INPUT" AND ^C SETUP OLDTXT. LDA OLDTXT STWD TXTPTR LDWD OLDLIN STWD CURLIN CONTRT: RTS ;RETURN TO CALLER. IFN NULCMD, NULL: JSR GETBYT BNE CONTRT ;MAKE SURE THERE IS TERMINATOR. INX CPXI 240 ;IS THE NUMBER REASONABLE? BCS FCERR1 ;"FUNCTION CALL" ERROR. DEX ;BACK -1 STX NULCNT RTS FCERR1: JMP FCERR> PAGE SUBTTL LOAD AND SAVE SUBROUTINES. IFE REALIO-1, SAVE: TSX ;SAVE STACK POINTER STX INPFLG LDAI STKEND-256-200 STA ^O362 ;SETUP DUMMY STACK FOR KIM MONITOR LDAI 254 ;MAKE ID BYTE EQUAL TO FF HEX STA ^O13771 ;STORE INTO KIM ID LDWD TXTTAB ;START DUMPING FROM TXTTAB STWD ^O13765 ;SETUP SAL,SAH LDWD VARTAB ;STOP AT VARTAB STWD ^O13767 ;SETUP EAL,EAH JMP ^O14000 RETSAV: LDX INPFLG ;RESORE THE REAL STACK POINTER TXS LDWDI TAPMES ;SAY IT WAS DONE JMP STROUT GLOAD: DT"LOADED" 0 TAPMES: DT"SAVED" ACRLF 0 PATSAV: BLOCK 20 LOAD: LDWD TXTTAB ;START DUMPING IN AT TXTTAB STWD ^O13765 ;SETUP SAL,SAH LDAI 255 STA ^O13771 LDWDI RTLOAD STWD ^O1 ;SET UP RETURN ADDRESS FOR LOAD JMP ^O14163 ;GO READ THE DATA IN RTLOAD: LDXI STKEND-256 ;RESET THE STACK TXS LDWDI READY STWD ^O1 LDWDI GLOAD ;TELL HIM IT WORKED JSR STROUT LDXY ^O13755 ;GET LAST LOCATION TXA ;ITS ONE TOO BIG BNE DECVRT ;DECREMENT [X,Y] NOP DECVRT: NOP STXY VARTAB ;SETUP NEW VARIABLE LOCATION JMP FINI> ;RELINK THE PROGRAM IFE REALIO-4, SAVE: SEC ;CALCLUATE PROGRAM SIZE IN POKER LDA VARTAB SBC TXTTAB STA POKER LDA VARTAB+1 SBC TXTTAB+1 STA POKER+1 JSR VARTIO JSR CQCOUT ;WRITE PROGRAM SIZE [POKER] JSR PROGIO JMP CQCOUT ;WRITE PROGRAM. LOAD: JSR VARTIO JSR CQCSIN ;READ SIZE OF PROGRAM INTO POKER CLC LDA TXTTAB ;CALCULATE VARTAB FROM SIZE AND ADC POKER ;TXTTAB STA VARTAB LDA TXTTAB+1 ADC POKER+1 STA VARTAB+1 JSR PROGIO JSR CQCSIN ;READ PROGRAM. LDWDI TPDONE JSR STROUT JMP FINI TPDONE: DT"LOADED" 0 VARTIO: LDWDI POKER STWD ^O74 LDAI POKER+2 STWD ^O76 RTS PROGIO: LDWD TXTTAB STWD ^O74 LDWD VARTAB STWD ^O76 RTS> PAGE SUBTTL RUN,GOTO,GOSUB,RETURN. RUN: JEQ RUNC ;IF NO LINE # ARGUMENT. JSR CLEARC ;CLEAN UP -- RESET THE STACK. JMP RUNC2 ;MUST REPLACE RTS ADDR. ; ; A GOSUB ENTRY ON THE STACK HAS THE FOLLOWING FORMAT: ; ; LOW ADDRESS: ; THE GOSUTK ONE BYTE ; THE LINE NUMBER OF THE GOSUB STATEMENT TWO BYTES ; A POINTER INTO THE TEXT OF THE GOSUB TWO BYTES ; ; HIGH ADDRESS. ; ; TOTAL FIVE BYTES. ; GOSUB: LDAI 3 JSR GETSTK ;MAKE SURE THERE IS ROOM. PSHWD TXTPTR ;PUSH ON THE TEXT POINTER. PSHWD CURLIN ;PUSH ON THE CURRENT LINE NUMBER. LDAI GOSUTK PHA ;PUSH ON A GOSUB TOKEN. RUNC2: JSR CHRGOT ;GET CHARACTER AND SET CODES FOR LINGET. JSR GOTO ;USE RTS SCHEME TO "NEWSTT". JMP NEWSTT GOTO: JSR LINGET ;PICK UP THE LINE NUMBER IN "LINNUM". JSR REMN ;SKIP TO END OF LINE. LDA CURLIN+1 CMP LINNUM+1 BCS LUK4IT TYA SEC ADC TXTPTR LDX TXTPTR+1 BCC LUKALL INX BCSA LUKALL ;ALWAYS GOES. LUK4IT: LDWX TXTTAB LUKALL: JSR FNDLNC ;[X,A] ARE ALL SET UP. QFOUND: BCC USERR ;GOTO LINE IS NONEXISTANT. LDA LOWTR SBCI 1 STA TXTPTR LDA LOWTR+1 SBCI 0 STA TXTPTR+1 GORTS: RTS ;PROCESS THE STATEMENT. ; ; "RETURN" RESTORES THE LINE NUMBER AND TEXT PNTR FROM THE STACK ; AND ELIMINATES ALL THE "FOR" ENTRIES IN FRONT OF THE "GOSUB" ENTRY. ; RETURN: BNE GORTS ;NO TERMINATOR=BLOW HIM UP. LDAI 255 STA FORPNT+1 ;MAKE SURE THE VARIABLE'S PNTR ;NEVER GETS MATCHED. JSR FNDFOR ;GO PAST ALL THE "FOR" ENTRIES. TXS CMPI GOSUTK ;RETURN WITHOUT GOSUB? BEQ RETU1 LDXI ERRRG SKIP2 USERR: LDXI ERRUS ;NO MATCH SO "US" ERROR. JMP ERROR ;YES. SNERR2: JMP SNERR RETU1: PLA ;REMOVE GOSUTK. PULWD CURLIN ;GET LINE NUMBER "GOSUB" WAS FROM. PULWD TXTPTR ;GET TEXT PNTR FROM "GOSUB". DATA: JSR DATAN ;SKIP TO END OF STATEMENT, ;SINCE WHEN "GOSUB" STUCK THE TEXT PNTR ;ONTO THE STACK, THE LINE NUMBER ARG ;HADN'T BEEN READ YET. ADDON: TYA CLC ADC TXTPTR STA TXTPTR BCC REMRTS INC TXTPTR+1 REMRTS: RTS ;"NEWSTT" RTS ADDR IS STILL THERE. DATAN: LDXI ":" ;"DATA" TERMINATES ON ":" AND NULL. SKIP2 REMN: LDXI 0 ;THE ONLY TERMINATOR IS NULL. STX CHARAC ;PRESERVE IT. LDYI 0 ;THIS MAKES CHARAC=0 AFTER SWAP. STY ENDCHR EXCHQT: LDA ENDCHR LDX CHARAC STA CHARAC STX ENDCHR REMER: LDADY TXTPTR BEQ REMRTS ;NULL ALWAYS TERMINATES. CMP ENDCHR ;IS IT THE OTHER TERMINATOR? BEQ REMRTS ;YES, IT'S FINISHED. INY ;PROGRESS TO NEXT CHARACTER. CMPI 34 ;IS IT A QUOTE? BNE REMER ;NO, JUST CONTINUE. BEQA EXCHQT ;YES, TIME TO TRADE. PAGE SUBTTL "IF ... THEN" CODE. IF: JSR FRMEVL ;EVALUATE A FORMULA. JSR CHRGOT ;GET CURRENT CHARACTER. CMPI GOTOTK ;IS TERMINATING CHARACTER A GOTOTK? BEQ OKGOTO ;YES. SYNCHK THENTK ;NO, IT MUST BE "THEN". OKGOTO: LDA FACEXP ;0=FALSE. ALL OTHERS TRUE. BNE DOCOND ;TRUE ! REM: JSR REMN ;SKIP REST OF STATEMENT. BEQA ADDON ;WILL ALWAYS BRANCH. DOCOND: JSR CHRGOT ;TEST CURRENT CHARACTER. BCS DOCO ;IF A NUMBER, GOTO IT. JMP GOTO DOCO: JMP GONE3 ;INTERPRET NEW STATEMENT. PAGE SUBTTL "ON ... GO TO ..." CODE. ONGOTO: JSR GETBYT ;GET VALUE IN FACLO. PHA ;SAVE FOR LATER. CMPI GOSUTK ;AN "ON ... GOSUB" PERHAPS? BEQ ONGLOP ;YES. SNERR3: CMPI GOTOTK ;MUST BE "GOTOTK". BNE SNERR2 ONGLOP: DEC FACLO BNE ONGLP1 ;SKIP ANOTHER LINE NUMBER. PLA ;GET DISPATCH CHARACTER. JMP GONE2 ONGLP1: JSR CHRGET ;ADVANCE AND SET CODES. JSR LINGET CMPI 44 ;IS IT A COMMA? BEQ ONGLOP PLA ;REMOVE STACK ENTRY (TOKEN). ONGRTS: RTS ;EITHER END-OF-LINE OR SYNTAX ERROR. PAGE SUBTTL LINGET -- READ A LINE NUMBER INTO LINNUM ; ; "LINGET" READS A LINE NUMBER FROM THE CURRENT TEXT POSITION. ; ; LINE NUMBERS RANGE FROM 0 TO 64000-1. ; ; THE ANSWER IS RETURNED IN "LINNUM". ; "TXTPTR" IS UPDATED TO POINT TO THE TERMINATING CHARCTER ; AND [A] = THE TERMINATING CHARACTER WITH CONDITION ; CODES SET UP TO REFLECT ITS VALUE. ; LINGET: LDXI 0 STX LINNUM ;INITIALIZE LINE NUMBER TO ZERO. STX LINNUM+1 MORLIN: BCS ONGRTS ;IT IS NOT A DIGIT. SBCI "0"-1 ;-1 SINCE C=0. STA CHARAC ;SAVE CHARACTER. LDA LINNUM+1 STA INDEX CMPI 25 ;LINE NUMBER WILL BE .LT. 64000? BCS SNERR3 LDA LINNUM ASL A, ;MULTIPLY BY 10. ROL INDEX ASL A ROL INDEX ADC LINNUM STA LINNUM LDA INDEX ADC LINNUM+1 STA LINNUM+1 ASL LINNUM ROL LINNUM+1 LDA LINNUM ADC CHARAC ;ADD IN DIGIT. STA LINNUM BCC NXTLGC INC LINNUM+1 NXTLGC: JSR CHRGET JMP MORLIN PAGE SUBTTL "LET" CODE. LET: JSR PTRGET ;GET PNTR TO VARIABLE INTO "VARPNT". STWD FORPNT ;PRESERVE POINTER. SYNCHK EQULTK ;"=" IS NECESSARY. IFN INTPRC, LDA INTFLG ;SAVE FOR LATER. PHA> LDA VALTYP ;RETAIN THE VARIABLE'S VALUE TYPE. PHA JSR FRMEVL ;GET VALUE OF FORMULA INTO "FAC". PLA ROL A, ;CARRY SET FOR STRING, OFF FOR ;NUMERIC. JSR CHKVAL ;MAKE SURE "VALTYP" MATCHES CARRY. ;AND SET ZERO FLAG FOR NUMERIC. BNE COPSTR ;IF NUMERIC, COPY IT. COPNUM: IFN INTPRC, PLA ;GET NUMBER TYPE. QINTGR: BPL COPFLT ;STORE A FLTING NUMBER. JSR ROUND ;ROUND INTEGER. JSR AYINT ;MAKE 2-BYTE NUMBER. LDYI 0 LDA FACMO ;GET HIGH. STADY FORPNT ;STORE IT. INY LDA FACLO ;GET LOW. STADY FORPNT RTS> COPFLT: JMP MOVVF ;PUT NUMBER @FORPNT. COPSTR: IFN INTPRC, ;IF STRING, NO INTFLG. INPCOM: IFN TIME, LDY FORPNT+1 ;TI$? CPYI ZERO/256 ;ONLY TI$ CAN BE THIS ON ASSIG. BNE GETSPT ; WAS NOT TI$. JSR FREFAC ;WE WONT NEEDIT. CMPI 6 ;LENGTH CORRECT? BNE FCERR2 LDYI 0 ;YES. DO SETUP. STY FACEXP ;ZERO FAC TO START WITH. STY FACSGN TIMELP: STY FBUFPT ;SAVE POSOTION. JSR TIMNUM ;GET A DIGIT. JSR MUL10 ;WHOLE QTY BY 10. INC FBUFPT LDY FBUFPT JSR TIMNUM JSR MOVAF TAX ;IF NUM=0 THEN NO MULT. BEQ NOML6 ;IF =0, GO TIT. INX ;MULT BY TWO. TXA JSR FINML6 ;ADD IN AND MULT BY 2 GIVES *6. NOML6: LDY FBUFPT INY CPYI 6 ;DONE ALL SIX? BNE TIMELP JSR MUL10 ;ONE LAST TIME. JSR QINT ;SHIFT IT OVER TO THE RIGHT. LDXI 2 SEI ;DISALLOW INTERRUPTS. TIMEST: LDA FACMOH,X STA CQTIMR,X DEX BPL TIMEST ;LOOP 3 TIMES. CLI ;TURN ON INTS AGAIN. RTS TIMNUM: LDADY INDEX ;INDEX SET UP BY FREFAC. JSR QNUM BCC GOTNUM FCERR2: JMP FCERR ;MUST BE NUMERIC STRING. GOTNUM: SBCI "0"-1 ;C IS OFF. JMP FINLOG> ;ADD IN DIGIT TO FAC. GETSPT: LDYI 2 ;GET PNTR TO DESCRIPTOR. LDADY FACMO CMP FRETOP+1 ;SEE IF IT POINTS INTO STRING SPACE. BCC DNTCPY ;IF [FRETOP],GT.[2&3,FACMO], DON'T COPY. BNE QVARIA ;IT IS LESS. DEY LDADY FACMO CMP FRETOP ;COMPARE LOW ORDERS. BCC DNTCPY QVARIA: LDY FACLO CPY VARTAB+1 ;IF [VARTAB].GT.[FACMO], DON'T COPY. BCC DNTCPY BNE COPY ;IT IS LESS. LDA FACMO CMP VARTAB ;COMPARE LOW ORDERS. BCS COPY DNTCPY: LDWD FACMO JMP COPYZC COPY: LDYI 0 LDADY FACMO JSR STRINI ;GET ROOM TO COPY STRING INTO. LDWD DSCPNT ;GET POINTER TO OLD DESCRIPTOR, SO STWD STRNG1 ;MOVINS CAN FIND STRING. JSR MOVINS ;COPY IT. LDWDI DSCTMP ;GET POINTER TO OLD DESCRIPTOR. COPYZC: STWD DSCPNT ;REMEMBER POINTER TO DESCRIPTOR. JSR FRETMS ;FREE UP THE TEMPORARY WITHOUT ;FREEING UP ANY STRING SPACE. LDYI 0 LDADY DSCPNT STADY FORPNT INY ;POINT TO STRING PNTR. LDADY DSC
Tłumaczenie
Brak

Najnowsze teksty piosenek

Sprawdź teksty piosenek i albumy dodane w ciągu ostatnich 7 dni