RUNTIME

The library as 6502 source in the style of Apple's DOS Toolkit assembler. Address and bytes on the left; labels in operands link to their definitions; point at a name from the equates for its meaning. The source assembles to the library byte for byte. Equates

Routines (66)
  1. INIT INIT: START A COMPILED PROGRAM. EVERY OBJECT FILE BEGINS WITH JSR INIT FOLLOWED BY A 17-BYTE HEADER: THE FIRST
  2. CLRCOM CLRCOM: CLEAR COMMON (REM! CLEAR COMMON). CLEAR: THE CLEAR STATEMENT. BOTH, AND THE END OF INIT, SHARE ONE ROU
  3. HIMEM HIMEM: (THE STATEMENT): THE NEW HIMEM ADDRESS IS IN FAC. STRING SPACE IS EMPTIED BELOW IT; VARIABLES ARE NOT C
  4. RESETSTK RESETSTK: EMPTY THE STACK, DROPPING EVERY PENDING GOSUB AND FOR, AND RESET THE DATA POINTER. THE BOTTOM OF THE
  5. RESTORE RESTORE: POINT THE DATA POINTER AT THE FIRST DATA ITEM.
  6. CHRPATCH CHRPATCH: 15 BYTES THAT INIT COPIES OVER CHRGET AT $BA-$C8. THEY RUN THERE, SO THEY ARE SHOWN AS THEY RUN AT $
  7. POP POP (THE STATEMENT): DROP THE MOST RECENT GOSUB RETURN ADDRESS, PASSING OVER ANY FOR FRAMES ABOVE IT. ERROR RE
  8. FORUNWND FORUNWND: EVERY FOR FRAME STARTS WITH THE ADDRESS IN FORPOP ($09B0), WHICH IS ALSO A RETURN ADDRESS. WHEN A SU
  9. NORET NORET: RETURN WITHOUT GOSUB. RESETSTK LEAVES A RETURN ADDRESS TO HERE AT THE BOTTOM OF THE STACK.
  10. FINDFOR FINDFOR: IS THERE A FOR FRAME ON THE STACK AT X? CARRY SET IF THE 16 BYTES ABOVE X START WITH THE FOR MARKER.
  11. IFORINR FOR, THE START OF A LOOP. FOUR ENTRIES BY THE LOOP VARIABLE'S TYPE AND THE INITIAL VALUE'S: IFORINR INTEGER VA
  12. NEXT NEXT: THE CALL IS FOLLOWED BY THE VARIABLE'S ADDRESS, 0 FOR A BARE NEXT. FRAMES OF INNER LOOPS ARE DROPPED UNT
  13. ARRREAL ARRAY ELEMENTS. EVERY ARRAY HAS A ROUTINE IN THE PROGRAM: SEC (LOAD) OR CLC (ADDRESS) THEN JSR ARRREAL, ARRSTR
  14. IMULT IMULT: INTEGER OPERATION 4: IACC = IACC * THE INTEGER AT (Y,A). SIGNS ARE TAKEN OUT (COUNTED IN $AB), THE MAGN
  15. ARRLOAD ARRLOAD: LOAD THE ELEMENT AT (Y,A) BY ITS TYPE (X: 0 REAL, 1 INTEGER, 2 STRING).
  16. ARRSTORE ARRSTORE: STORE THE VALUE INTO THE ARRAY ELEMENT WHOSE ADDRESS AND TYPE THE ARRAY ROUTINE LEFT IN $DC/$DD AND
  17. DISPSTR DISPSTR: THE STRING VARIABLE DISPATCHER. A STRING VARIABLE'S ROUTINE IS SEC (OR CLC), LDA #, LDY #HIGH, LDA #L
  18. ILOAD INTEGER OPERATIONS 0 AND 1, ENTERED FROM DISPINT WITH (Y,A) = THE VARIABLE'S ADDRESS. INTEGERS ARE STORED HIGH
  19. INEG INEG: IACC = -IACC. IRSUB (INTEGER OPERATION 3): IACC = VARIABLE - IACC. ISUBT: IACC = IARG - IACC. IADD (OPER
  20. DISPINT DISPINT: THE INTEGER VARIABLE DISPATCHER. A NUMERIC VARIABLE'S ROUTINE LOADS X WITH THE OPERATION AND (Y,A) WI
  21. ICOMP ICOMP: INTEGER OPERATION 5: COMPARE IACC WITH THE VARIABLE. A = -1, 0 OR 1 AS FCOMP GIVES IT, FOR THE RELATION
  22. ISTOREF ISTOREF: INTEGER OPERATION 7: STORE FAC IN THE INTEGER VARIABLE THROUGH APPLESOFT'S OWN LET, WHICH ROUNDS AND
  23. IREAL IREAL: THE REAL OPERATIONS ON AN INTEGER VARIABLE. X: 0 LOAD, 1 ADD, 2 MULTIPLY, 3 COMPARE, 4 LOAD ARG OR (WIT
  24. DRAWAT HI-RES: DRAW AND XDRAW AT X,Y, HPLOT TO AND HPLOT. EACH HAS A REAL ENTRY (JSR AYINT) AND AN INTEGER ENTRY 3 BY
  25. DRAW DRAW AND XDRAW: THE SHAPE NUMBER IS CHECKED AGAINST THE COUNT AT THE START OF THE SHAPE TABLE, THE SHAPE'S ADD
  26. COLOR COLOR=. LIKE MOST STATEMENTS WITH ONE NUMBER, A REAL ENTRY (JSR AYINT) FALLS INTO THE INTEGER ENTRY, WHICH TAK
  27. VALFN VALFN: VAL OF THE STRING ACCUMULATOR. THE BYTE AFTER THE STRING IS REPLACED BY 0 WHILE THE ROM'S FIN READS THE
  28. ASCFN ASCFN: ASC OF THE STRING ACCUMULATOR INTO IACC (ERROR $35 FOR AN EMPTY STRING). LENFN: ITS LENGTH INTO IACC.
  29. STRLITP STRLITP AND STRLIT: A STRING LITERAL IN THE CODE: THE CALL IS FOLLOWED BY THE LITERAL'S ADDRESS. THE STRING AC
  30. PRSTR PRSTR: PRINT THE STRING ACCUMULATOR.
  31. CLRCHAIN CLRCHAIN (REM! CLEAR CHAIN) AND FREFN (FRE): BOTH COLLECT GARBAGE. CLEAR CHAIN LEAVES THE LOCAL STRINGS OUT, S
  32. GARBAG GARBAG: THE GARBAGE COLLECTOR. EACH ROUND FINDS THE HIGHEST STRING STILL IN USE THAT IS BELOW THE STRINGS ALRE
  33. OLDTEXT OLDTEXT: 45 BYTES OF TEXT LEFT IN MEMORY BY THE ASSEMBLER: NEVER EXECUTED. THE BRANCH BEFORE THEM IS ALWAYS TA
  34. GETSTR GETSTR: GET A$: A NEW ONE-CHARACTER STRING FROM THE KEYBOARD.
  35. CONCATT CONCAT: THE PUSHED STRING FOLLOWED BY THE LOADED STRING, AS A NEW STRING (ERROR $B0, STRING TOO LONG, PAST 255
  36. PUSHSTR PUSHSTR: COPY THE LOADED STRING TO THE PUSHED STRING.
  37. NEWSTR NEWSTR: MAKE ROOM FOR A NEW STRING OF ($0D) BYTES BELOW THE BOTTOM OF STRING SPACE, COLLECTING GARBAGE IF IT D
  38. CHRFN CHR$: A ONE-CHARACTER STRING.
  39. STRFN STR$: FOUT CONVERTS FAC TO TEXT AT $0100; THE TEXT BECOMES A NEW STRING.
  40. LEFT LEFT$, RIGHT$ AND MID$. THE STRING IS IN THE STRING ACCUMULATOR; THE COUNT (AND FOR MID$ THE START, PUSHED BY
  41. INPSTRQ INPUT. INPSTR AND INPNUM READ THE FIRST ITEM (PRINTING "?"), THE P ENTRIES THE FIRST ITEM AFTER A PROMPT, THE
  42. STOP STOP: PRINT BREAK IN AND THE OBJECT ADDRESS OF THE STOP, THEN END.
  43. PGMEND PGMEND (END, AND NEW): PUT CHRGET BACK FROM THE ROM, MAKE THE PROGRAM SPACE AN EMPTY PROGRAM AND GO BACK TO TH
  44. INPEND INPEND: THE END OF AN INPUT STATEMENT: ?EXTRA IGNORED IF THE LINE HAS MORE.
  45. GETNUM GETNUM: GET X: A DIGIT KEY GIVES ITS VALUE, ANY OTHER KEY 0.
  46. READSTR READ. THE DATA POINTER WALKS THE DATA ITEMS IN THE CODE: EACH IS A LENGTH BYTE AND ITS TEXT; $FF IS FOLLOWED B
  47. ERREXIT ERREXIT: EVERY LIBRARY ERROR ENDS HERE WITH THE ERROR NUMBER IN X. WITHOUT ONERR THE OBJECT ADDRESS OF THE CAL
  48. DEBUG DEBUG: CALLED BEFORE EACH STATEMENT WITH THE RESUME/DEBUG OPTION. IT KEEPS THE STACK POINTER AND THE STATEMENT
  49. PRNUM STATEMENTS WITH ONE BYTE ARGUMENT: PR#, IN#, POKE (THE VALUE), WAIT (THE MASKS), TAB(, SPC(. THE REAL ENTRY CO
  50. COMMA COMMA: A COMMA IN PRINT: TO THE NEXT 16-COLUMN FIELD, OR A NEW LINE PAST COLUMN 24.
  51. ONGOTO ON ... GOTO AND ON ... GOSUB: THE CALL IS FOLLOWED BY THE NUMBER OF LINES AND THEIR ADDRESSES. AN INDEX OF 0 O
  52. LOGORI AND, OR AND THE RELATIONS. THE CODE BEFORE THE CALL HAS SET THE FLAGS: FOR AND/OR BY LOADING ONE OPERAND, FOR
  53. STRGE STRING RELATIONS ON THE PUSHED STRING (LEFT) AND THE LOADED STRING (RIGHT). STRLT AND STRGE SWAP THEM AND USE
  54. ROT STATEMENTS AND ARGUMENTS THAT KEEP A BYTE FOR LATER: ROT=, SCALE=, THE SHAPE NUMBER, THE THIRD WAIT ARGUMENT,
  55. INPBEG INPBEG: THE START OF AN INPUT STATEMENT: KEEP ITS OBJECT ADDRESS FOR ?REENTER.
  56. ONERR ONERR: THE CALL IS FOLLOWED BY THE HANDLER'S ADDRESS, WHICH GOES INTO THE ONERR VECTOR AT $5B.
  57. RESUME RESUME: BACK TO THE STATEMENT THAT FAILED (ITS DEBUG CALL) WITH THE STACK AS IT WAS.
  58. PUSHSUB PUSHSUB: PUSH A SUBSCRIPT UNDER THE RETURN ADDRESS FOR THE ARRAY ROUTINE.
  59. FLOATI FLOATI: FAC = IACC. THE JMP AT $58 COMES HERE. IMOVE: IARG = IACC.
  60. IFORST1 LOOP LIMIT AND STEP, CALLED AFTER THE LOOP START. THEY PUT THE VALUES INTO THE FRAME UNDER THE CALLER'S RETURN
  61. SCRN SCRN(: THE FIRST ARGUMENT WAS PUSHED WITH PUSHBYTE. POS: THE CURSOR COLUMN. THE RESULT GOES TO IACC.
  62. PLOT PLOT, HLIN, VLIN, PDL: THE LAST ARGUMENT; THE OTHERS WERE SAVED BEFORE. PDL GIVES ITS RESULT IN IACC.
  63. CALLI STATEMENTS AND FUNCTIONS WITH AN ADDRESS: CALL, POKE AND WAIT (THE ADDRESS, SVADDR), PEEK. GETADR TAKES ANY VA
  64. PRINTI PRINT A NUMBER: PRINTI FLOATS IACC FIRST.
  65. DISPREAL DISPREAL: THE REAL VARIABLE DISPATCHER: X = OPERATION, (Y,A) = THE VARIABLE. 0 LOAD FAC (AND SET THE FLAGS), 1
  66. COPYRT COPYRT: THE COPYRIGHT NOTICE.
ORG$0803THE LIBRARY'S USUAL ADDRESS

INIT

INIT: START A COMPILED PROGRAM. EVERY OBJECT FILE BEGINS WITH JSR INIT FOLLOWED BY A 17-BYTE HEADER: THE FIRST DATA ITEM, THE HIGHEST ADDRESS, THE COMMON BOUNDS (START-1, NUMERIC END, STRING END), THE LOCAL BOUNDS (THE SAME THREE), TWO BYTES EACH, AND THE COMMON FLAG (0 NONE OR DEFINE, $FF USE).

INIT POINTS THE & VECTOR AT THE PROGRAM (& RUNS IT AGAIN), SETS UP THE JMP VECTORS AT $58 (FLOAT THE INTEGER ACCUMULATOR) AND $5B (ONERR), FINDS THE LIBRARY'S OWN ADDRESS FROM THE OPERAND OF THE CALLER'S JSR, SO THE LIBRARY RUNS WHEREVER IT IS LOADED, PATCHES CHRGET FOR ONERR, COPIES THE HEADER TO PAGE ZERO AND CLEARS THE VARIABLES. IT RETURNS PAST THE HEADER.

080320 8B FDINITJSRCROUT1CLEAR TO THE END OF THE LINE, NEW LINE
0806A9 4CLDA#$4C$4C, JMP, FOR THE THREE VECTORS
08088D F5 03STAAMPER& VECTOR
080B85 5BSTAERRVECONERR VECTOR AT $5B
080D85 58STAFLTVECFLOAT VECTOR AT $58
080F68PLATHE CALLER'S RETURN ADDRESS: THE LAST BYTE OF ITS JSR
0810AATAX
081118CLC
081269 11ADC#$11+$11: PAST THE 17-BYTE HEADER
0814A8TAY
081568PLAHIGH BYTE
08168D F7 03STAAMPER+2
081985 63STARESULT+1RESULT WILL POINT AT THE CALLER'S JSR
081B69 00ADC#$00PUSH THE ADDRESS AFTER THE HEADER FOR THE FINAL RTS
081D48PHA
081E98TYA
081F48PHA
0820E0 02CPX#$02THE JSR BEGINS 2 BYTES BEFORE: BORROW IF THE LOW BYTE IS BELOW 2
0822B0 05BCSINIT1
0824CE F7 03DECAMPER+2
0827C6 63DECRESULT+1
0829CAINIT1DEXLOW BYTE - 2
082ACADEX
082B8E F6 03STXAMPER+1THE & VECTOR JUMPS TO THE PROGRAM'S START: & RUNS IT AGAIN
082E86 62STXRESULTRESULT = ADDRESS OF THE CALLER'S JSR INIT
0830A0 BBLDY#$BBONERR TEXT POINTER = $00BB, INSIDE THE CHRGET PATCH
083284 F4STYTXTPSV
0834A0 00LDY#$00
083684 F5STYTXTPSV+1
083884 76STYCURLIN+1NO STATEMENT ADDRESS YET
083A84 75STYCURLIN
083C84 D8STYERRFLGONERR OFF
083EC8INYTHE JSR'S OPERAND IS THIS LIBRARY'S ADDRESS, L
083FB1 62LDA(RESULT),Y
084118CLC
084269 69ADC#$69L+$169 = CHRPATCH
084485 83STARETADR
0846AATAX
0847C8INY
0848B1 62LDA(RESULT),Y
084A69 01ADC#$01
084C85 84STARETADR+1
084EA8TAY
084F8ATXA
085069 44ADC#$44L+$1AD = $09B0, THE FOR MARKER (SEE FORUNWND)
085285 AFSTAFORPOP
085498TYA
085569 00ADC#$00
085785 B0STAFORPOP+1
08598ATXAL+$0E6B = FLOATI: $58 IS NOW JMP FLOATI
085A69 02ADC#$02
085C85 59STAFLTVEC+1
085E98TYA
085F69 0DADC#$0D
086185 5ASTAFLTVEC+2
0863A0 0ELDY#$0ECOPY THE 15 BYTES OF THE PATCH TO $BA-$C8
0865B1 83INIT2LDA(RETADR),Y
086799 BA 00STACHRPAT,Y
086A88DEY
086B10 F8BPLINIT2
086DA9 55LDA#$55APPLESOFT'S TEMPORARY STRING STACK, EMPTY
086F85 52STATEMPPT
0871A9 06LDA#$06$33 = 6
087385 33STAPROMPT
0875A0 13LDY#$13OFFSET 19 FROM THE JSR: THE COMMON FLAG
0877B1 62LDA(RESULT),Y
087985 16STAHDRFLAG
087B88INIT3DEYTHE HEADER, LAST WORD FIRST
087CB1 62LDA(RESULT),Y
087EC0 0DCPY#$0DOFFSETS 13-18: THE LOCAL BOUNDS TO $7B-$80
088090 05BCCINIT4
088299 6E 00STASTRCEND+1,Y
0885B0 F4BCSINIT3
0887C0 07INIT4CPY#$07OFFSETS 7-12: THE COMMON BOUNDS TO $69-$6E ...
088990 12BCCINIT6
088B24 16BITHDRFLAG... A PROGRAM THAT USES COMMON MUST FIND THEM AS THE PROGRAM BEFORE LEFT THEM
088D10 09BPLINIT5
088FD9 62 00CMPRESULT,Y
0892F0 E7BEQINIT3
0894A2 A3LDX#$A3A DIFFERENT COMMON BLOCK: ERROR $A3 (163, TYPE MISMATCH)
0896D0 3EBNECLEAR5
089899 62 00INIT5STARESULT,YNO COMMON OR DEFCOMMON: SET THEM
089B10 DEBPLINIT3
089D99 0F 00INIT6STANUMDIM,YOFFSETS 3-6: THE FIRST DATA ITEM AND THE HIGHEST ADDRESS TO $12-$15
08A0C0 03CPY#$03
08A2D0 D7BNEINIT3
08A4A5 16LDAHDRFLAGMODE = THE COMMON FLAG: 0 CLEARS COMMON AND LOCALS, $FF ONLY THE LOCALS
08A62CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES

CLRCOM

CLRCOM: CLEAR COMMON (REM! CLEAR COMMON). CLEAR: THE CLEAR STATEMENT. BOTH, AND THE END OF INIT, SHARE ONE ROUTINE WITH A IN THE ROLE OF A MODE: 1 CLEARS THE COMMON BLOCK, $FF THE LOCAL VARIABLES, 0 BOTH (INIT, NO COMMON OR DEFCOMMON).

NUMERIC VARIABLES BECOME ZERO; STRING VARIABLES POINT AT AN EMPTY STRING KEPT AT HIMEM-1. MODE 0 ALSO EMPTIES STRING SPACE. THE ROUTINE ENDS BY RESETTING THE STACK (RESETSTK).

08A7A9 01CLRCOMLDA#$01MODE 1: THE COMMON BLOCK
08A92CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
08AAA9 FFCLEARLDA#$FFMODE $FF: THE LOCAL VARIABLES
08ACA4 73LDYMEMSIZHIMEM
08AEA6 74LDXMEMSIZ+1
08B086 16STXHDRFLAGNOT ZERO: CLEAR VARIABLES AFTERWARDS
08B248CLEAR1PHAKEEP THE MODE
08B398TYA
08B4D0 01BNECLEAR2
08B6CADEX
08B788CLEAR2DEY
08B886 7ASTXSTRPSH+1STRPSH = HIMEM-1, AN EMPTY STRING (ITS LENGTH BYTE IS SET BELOW)
08BA84 79STYSTRPSH
08BC68PLAMODE 0: ALSO EMPTY STRING SPACE ...
08BD48PHA
08BED0 09BNECLEAR4
08C098TYA
08C1D0 01BNECLEAR3
08C3CADEX
08C488CLEAR3DEY
08C586 70STXFRETOP+1... FRETOP = HIMEM-2
08C784 6FSTYFRETOP
08C9A4 6FCLEAR4LDYFRETOPSTRING SPACE MUST STAY ABOVE THE PROGRAM AND ITS VARIABLES
08CBC4 14CPYHIGHEST
08CDA5 70LDAFRETOP+1
08CFE5 15SBCHIGHEST+1
08D1B0 1BBCSHIMEM2
08D368PLA
08D4A2 4DLDX#$4DELSE OUT OF MEMORY, ERROR $4D
08D6D0 6DCLEAR5BNEHIMEM10ON TO THE ERROR EXIT (X = ERROR NUMBER)
08D820 58 00JSRFLTVECINTEGER ENTRY: FLOAT THE INTEGER ACCUMULATOR FIRST

HIMEM

HIMEM: (THE STATEMENT): THE NEW HIMEM ADDRESS IS IN FAC. STRING SPACE IS EMPTIED BELOW IT; VARIABLES ARE NOT CLEARED.

08DB20 52 E7HIMEMJSRGETADRTHE ADDRESS IN FAC TO LINNUM
08DEA6 51LDXLINNUM+1HIMEM = THE ADDRESS
08E086 74STXMEMSIZ+1
08E2A4 50LDYLINNUM
08E484 73STYMEMSIZ
08E6A9 00LDA#$00MODE 0 AND NO VARIABLE CLEARING
08E885 16STAHDRFLAG
08EAF0 C6BEQCLEAR1
08EC68HIMEM1PLA
08ED60RTS
08EEA0 00HIMEM2LDY#$00THE EMPTY STRING: LENGTH 0
08F098TYA
08F191 79STA(STRPSH),Y
08F3A5 16LDAHDRFLAGHIMEM: DONE
08F5F0 F5BEQHIMEM1
08F7A2 00LDX#$00
08F968PLA
08FA48HIMEM3PHACLEAR ONE BLOCK: X = 0 THE COMMON BOUNDS ...
08FB10 02BPLHIMEM4
08FDA2 12LDX#$12... X = $12 THE LOCAL BOUNDS ($7B-$80)
08FFB5 6AHIMEM4LDACOMBEG+1,XA1 = THE BLOCK'S START-1
090185 3DSTAA1L+1
0903B5 69LDACOMBEG,X
090585 3CSTAA1L
0907A0 00LDY#$00
0909E6 3CHIMEM5INCA1LNUMBERS: ZERO EVERY BYTE UP TO THE NUMERIC END
090BD0 02BNEHIMEM6
090DE6 3DINCA1L+1
090FB5 6BHIMEM6LDANUMCEND,X
0911C5 3CCMPA1L
0913B5 6CLDANUMCEND+1,X
0915E5 3DSBCA1L+1
091790 05BCCHIMEM7
091998TYA
091A91 3CSTA(A1L),Y
091CF0 EBBEQHIMEM5
091EA5 3CHIMEM7LDAA1LSTRINGS: EVERY POINTER UP TO THE STRING END ...
0920D5 6DCMPSTRCEND,X
0922A5 3DLDAA1L+1
0924F5 6ESBCSTRCEND+1,X
0926B0 16BCSHIMEM9
0928A5 79LDASTRPSH... POINTS AT THE EMPTY STRING
092A91 3CSTA(A1L),Y
092CE6 3CINCA1L
092ED0 02BNEHIMEM8
0930E6 3DINCA1L+1
0932A5 7AHIMEM8LDASTRPSH+1
093491 3CSTA(A1L),Y
0936E6 3CINCA1L
0938D0 E4BNEHIMEM7
093AE6 3DINCA1L+1
093CD0 E0BNEHIMEM7
093E68HIMEM9PLAMODE 0: NOW THE LOCALS TOO
093FD0 06BNERESETSTK
0941A9 FFLDA#$FF
094330 B5BMIHIMEM3
0945D0 68HIMEM10BNEPOP7ON TO THE ERROR EXIT

RESETSTK

RESETSTK: EMPTY THE STACK, DROPPING EVERY PENDING GOSUB AND FOR, AND RESET THE DATA POINTER. THE BOTTOM OF THE NEW STACK IS A RETURN ADDRESS INTO NORET, SO A RETURN WITH NO GOSUB REPORTS RETURN WITHOUT GOSUB. PASS 0, 1 AND 2 OF THE COMPILER CALL THIS ROUTINE AFTER AN ERROR.

094768RESETSTKPLATHE CALLER'S RETURN ADDRESS
094885 62STARESULT
094A68PLA
094B85 63STARESULT+1
094DA2 FFLDX#$FFAN EMPTY STACK
094F9ATXS
0950A5 AFLDAFORPOPPUSH FORPOP+8 = $09B8, THE RTS BEFORE NORET: A RETURN WITHOUT GOSUB RETURNS TO NORET
095218CLC
095369 08ADC#$08
0955AATAX
0956A5 B0LDAFORPOP+1
095869 00ADC#$00
095A48PHA
095B8ATXA
095C48PHA
095DA5 63LDARESULT+1AND THE CALLER'S RETURN ADDRESS
095F48PHA
0960A5 62LDARESULT
096248PHA

RESTORE

RESTORE: POINT THE DATA POINTER AT THE FIRST DATA ITEM.

0963A5 12RESTORELDADATFIRSTDATA POINTER = FIRST DATA ITEM
096585 F6STADATPTR
0967A5 13LDADATFIRST+1
096985 F7STADATPTR+1
096B60RTS

CHRPATCH

CHRPATCH: 15 BYTES THAT INIT COPIES OVER CHRGET AT $BA-$C8. THEY RUN THERE, SO THEY ARE SHOWN AS THEY RUN AT $BA.

FOR THE INTERPRETER NOTHING CHANGES: SPACES ARE SKIPPED AND THE ROM'S CHRGET GOES ON AT $F114. BUT WHEN THE ROM'S ERROR HANDLER, WITH ONERR ACTIVE, SETS THE TEXT POINTER TO $00BB (TXTPSV, SET BY INIT) AND CALLS CHRGOT, THE BYTE READ IS THE $20 OF THE PATCH'S OWN CMP, THE TEXT POINTER IS ON PAGE ZERO, AND THE PATCH JUMPS THROUGH THE ONERR VECTOR AT $5B INTO THE COMPILED HANDLER.

096CC9 20CHRPATCHDFB$C9,$20$BA: CMP #$20
096ED0 08DFB$D0,$08$BC: BNE $00C6
0970A5 B9DFB$A5,$B9$BE: LDA $B9
0972D0 EFDFB$D0,$EF$C0: BNE $00B1
0974E6 B9DFB$E6,$B9$C2: INC $B9
0976D0 95DFB$D0,$95$C4: BNE $005B
09784C 14 F1DFB$4C,$14,$F1$C6: JMP $F114

POP

POP (THE STATEMENT): DROP THE MOST RECENT GOSUB RETURN ADDRESS, PASSING OVER ANY FOR FRAMES ABOVE IT. ERROR RETURN WITHOUT GOSUB IF THERE IS NONE.

097B68POPPLATHE CALLER'S RETURN ADDRESS
097C85 62STARESULT
097E68PLA
097F85 63STARESULT+1
0981BATSX
0982A0 03POP1LDY#$03Y = 3: FINDFOR GOES ON AT POP2
0984D0 38BNEFINDFOR
098690 03POP2BCCPOP3A FOR FRAME: DROP IT AND LOOK AGAIN
09889ATXS
0989B0 F7BCSPOP1
098BA5 AFPOP3LDAFORPOPIS THE TOP THE STACK'S BOTTOM ENTRY (THE RETURN TO NORET)?
098D69 08ADC#$08
098FA8TAY
0990A5 B0LDAFORPOP+1
099269 00ADC#$00
0994BATSX
0995DD 02 01CMPSTACK+2,XCOMPARE HIGH BYTE ...
0998D0 07BNEPOP4
099A98TYA
099BDD 01 01CMPSTACK+1,X... AND LOW BYTE
099E38SEC
099FF0 03BEQPOP5
09A118POP4CLCNO: DROP THE GOSUB RETURN ADDRESS
09A268PLA
09A368PLA
09A4A5 63POP5LDARESULT+1RETURN TO THE CALLER
09A648PHA
09A7A5 62LDARESULT
09A948PHA
09AAB0 01BCSPOP6
09AC60RTS
09ADA2 16POP6LDX#$16RETURN WITHOUT GOSUB: ERROR $16
09AFD0 2BPOP7BNEFINDF3ON TO THE ERROR EXIT

FORUNWND

FORUNWND: EVERY FOR FRAME STARTS WITH THE ADDRESS IN FORPOP ($09B0), WHICH IS ALSO A RETURN ADDRESS. WHEN A SUBROUTINE RETURNS WITH UNFINISHED LOOPS ON THE STACK, ITS RTS PULLS THAT ADDRESS AND COMES HERE, ONE PAST IT: THE REST OF THE FRAME IS DROPPED AND RTS IS TRIED AGAIN, SO RETURN UNWINDS THE LOOPS.

09B1BAFORUNWNDTSXTHE MARKER'S 2 BYTES ARE GONE; DROP THE OTHER 14 ...
09B28ATXA
09B318CLC
09B469 0EADC#$0E
09B6AATAX
09B79ATXS
09B860RTS... AND RETURN AGAIN

NORET

NORET: RETURN WITHOUT GOSUB. RESETSTK LEAVES A RETURN ADDRESS TO HERE AT THE BOTTOM OF THE STACK.

09B9A2 16NORETLDX#$16ERROR $16: RETURN WITHOUT GOSUB
09BB4C 12 D4JMPERROR

FINDFOR

FINDFOR: IS THERE A FOR FRAME ON THE STACK AT X? CARRY SET IF THE 16 BYTES ABOVE X START WITH THE FOR MARKER. SHARED BY NEXT (Y = 1), FOR (Y = 2) AND POP (Y = 3); Y SAYS WHERE TO GO ON.

09BE8AFINDFORTXAX+16: THE STACK ABOVE THE FRAME
09BF18CLC
09C069 10ADC#$10
09C2B0 0FBCSFINDF1NOT 16 BYTES LEFT: NO FRAME
09C4AATAX
09C5BD F1 00DFB$BD,$F1,$00LDA $00F1,X (ABSOLUTE ON PURPOSE); THE FRAME'S FIRST TWO BYTES ...
09C8C5 AFCMPFORPOP... ARE THEY THE MARKER?
09CAD0 07BNEFINDF1
09CCBD F2 00DFB$BD,$F2,$00LDA $00F2,X (ABSOLUTE ON PURPOSE)
09CFC5 B0CMPFORPOP+1
09D1F0 01BEQFINDF2
09D318FINDF1CLCCARRY CLEAR: NO FRAME
09D488FINDF2DEYY = 1: NEXT, 2: FOR, 3: POP
09D5F0 66BEQNEXT2
09D788DEY
09D8F0 3DBEQFORIN5
09DAD0 AABNEPOP2
09DCD0 6CFINDF3BNENEXT3ON TO THE ERROR EXIT

IFORINR

FOR, THE START OF A LOOP. FOUR ENTRIES BY THE LOOP VARIABLE'S TYPE AND THE INITIAL VALUE'S: IFORINR INTEGER VARIABLE, REAL VALUE; IFORINIT BOTH INTEGER; FORINITI REAL VARIABLE, INTEGER VALUE; FORINIT BOTH REAL. THE CALL IS FOLLOWED BY THE VARIABLE'S ADDRESS.

THE VALUE IS STORED IN THE VARIABLE; A FRAME FOR THE SAME VARIABLE STILL ON THE STACK IS REMOVED (AS IN APPLESOFT); THE VARIABLE'S ADDRESS IS PUSHED AS THE FIRST PART OF THE NEW FRAME. THE LIMIT AND STEP ROUTINES PUSH THE REST.

09DE20 0C E1IFORINRJSRAYINTREAL VALUE TO AN INTEGER IN IACC
09E1A2 01IFORINITLDX#$01X = 1: STORE IACC
09E3D0 05BNEFORIN1
09E520 58 00FORINITIJSRFLTVECINTEGER VALUE TO A REAL IN FAC
09E8A2 00FORINITLDX#$00X = 0: STORE FAC
09EA68FORIN1PLATHE RETURN ADDRESS POINTS BEFORE THE INLINE WORD
09EB85 83STARETADR
09ED68PLA
09EE85 84STARETADR+1
09F0A0 01LDY#$01TPTR = THE LOOP VARIABLE'S ADDRESS
09F2B1 83LDA(RETADR),Y
09F485 55STATPTR
09F6C8INY
09F7B1 83LDA(RETADR),Y
09F985 56STATPTR+1
09FBCADEXINTEGER: STORE IACC, HIGH BYTE FIRST
09FC30 0EBMIFORIN2
09FEA0 00LDY#$00
0A00A5 A0LDAIACC
0A0291 55STA(TPTR),Y
0A04C8INY
0A05A5 A1LDAIACC+1
0A0791 55STA(TPTR),Y
0A0998TYA
0A0AD0 06BNEFORIN3
0A0CA8FORIN2TAYREAL: STORE FAC ROUNDED AT (Y,X)
0A0DA6 55LDXTPTR
0A0F20 2B EBJSRMOVMF
0A12BAFORIN3TSXLOOK FOR A FRAME FOR THE SAME VARIABLE
0A13A0 02FORIN4LDY#$02
0A15D0 A7BNEFINDFOR
0A1790 0FFORIN5BCCFORIN6A FRAME: IS IT FOR THIS VARIABLE?
0A19BD FF 00DFB$BD,$FF,$00LDA $00FF,X (ABSOLUTE ON PURPOSE)
0A1CC5 55CMPTPTR
0A1ED0 F3BNEFORIN4
0A20BD 00 01LDASTACK,X
0A23C5 56CMPTPTR+1
0A25D0 ECBNEFORIN4
0A279ATXSYES: DROP IT
0A28A5 56FORIN6LDATPTR+1START THE NEW FRAME: THE VARIABLE'S ADDRESS
0A2A48PHA
0A2BA5 55LDATPTR
0A2D48PHA
0A2E18CLC
0A2F90 74BCCNEXT7AND RETURN PAST THE INLINE WORD

NEXT

NEXT: THE CALL IS FOLLOWED BY THE VARIABLE'S ADDRESS, 0 FOR A BARE NEXT. FRAMES OF INNER LOOPS ARE DROPPED UNTIL THE VARIABLE'S FRAME IS FOUND (ERROR NEXT WITHOUT FOR IF NONE). THE STEP IS ADDED TO THE VARIABLE AND THE RESULT COMPARED WITH THE LIMIT IN THE DIRECTION OF THE STEP: THE LOOP GOES ON BY RETURNING TO THE LOOP ADDRESS KEPT IN THE FRAME, OR ENDS BY DROPPING THE FRAME AND RETURNING PAST THE CALL.

FOR FRAME, 16 BYTES FROM THE TOP: MARKER (FORPOP), LOOP ADDRESS-1, STEP (5 BYTES PACKED), LIMIT (5), VARIABLE ADDRESS. AN INTEGER LOOP HAS 0 IN THE 4TH BYTE, THE STEP IN BYTES 5-6, THE LOOP ADDRESS IN 8-9 AND THE LIMIT IN 10-11.

0A3168NEXTPLATHE RETURN ADDRESS POINTS BEFORE THE INLINE WORD
0A3285 83STARETADR
0A3468PLA
0A3585 84STARETADR+1
0A37BATSX
0A389ANEXT1TXSDROP THE FRAME AT X (AN INNER LOOP) AND LOOK FURTHER
0A39A0 01LDY#$01
0A3BD0 81BNEFINDFOR
0A3DA0 02NEXT2LDY#$02Y = 2: THE HIGH BYTE OF THE INLINE ADDRESS
0A3FB0 0BBCSNEXT4A FRAME
0A41A5 84LDARETADR+1NONE: NEXT WITHOUT FOR (ERROR 0)
0A4348PHA
0A44A5 83LDARETADR
0A4648PHA
0A47A2 00LDX#$00
0A4998TYA
0A4AD0 66NEXT3BNENEXT8
0A4CB1 83NEXT4LDA(RETADR),Y0: A BARE NEXT TAKES THE INNERMOST LOOP
0A4EF0 0DBEQNEXT5
0A50DD 00 01CMPSTACK,XTHE FRAME'S VARIABLE?
0A53D0 E3BNENEXT1
0A5588DEY
0A56B1 83LDA(RETADR),Y
0A58DD FF 00DFB$DD,$FF,$00CMP $00FF,X (ABSOLUTE ON PURPOSE)
0A5BD0 DBBNENEXT1
0A5DBANEXT5TSXTHE FRAME IS AT X+1
0A5EBD 04 01LDASTACK+4,XA ZERO 4TH BYTE: AN INTEGER LOOP
0A61F0 51BEQNEXT9
0A638ATXAREAL: FAC = STEP
0A6418CLC
0A6569 05ADC#$05
0A67A0 01LDY#$01
0A6920 F9 EAJSRMOVFM
0A6C20 82 EBJSRSIGNTHE SIGN OF THE STEP
0A6F85 65STARESULT+3
0A71BATSXFAC = STEP + VARIABLE
0A72BC 10 01LDY$0110,X
0A75BD 0F 01LDA$010F,X
0A7820 BE E7JSRFADD
0A7BBATSXSTORE IT IN THE VARIABLE
0A7CBC 10 01LDY$0110,X
0A7FBD 0F 01LDA$010F,X
0A82AATAX
0A8320 2B EBJSRMOVMF
0A86BATSXCOMPARE WITH THE LIMIT
0A878ATXA
0A8818CLC
0A8969 0AADC#$0A
0A8BA0 01LDY#$01
0A8D20 B2 EBJSRFCOMP
0A90C5 65CMPRESULT+3PAST THE LIMIT IN THE STEP'S DIRECTION: THE LOOP IS DONE
0A92F0 0ABEQNEXT6
0A94BATSXAGAIN: RETURN TO THE LOOP ADDRESS KEPT IN THE FRAME
0A95BD 04 01LDASTACK+4,X
0A9848PHA
0A99BD 03 01LDASTACK+3,X
0A9C48PHA
0A9D60RTS
0A9EBANEXT6TSXDONE: DROP THE 16-BYTE FRAME
0A9F8ATXA
0AA018CLC
0AA169 10ADC#$10
0AA3AATAX
0AA49ATXS
0AA5A5 83NEXT7LDARETADRRETURN PAST THE INLINE WORD
0AA769 02ADC#$02
0AA9AATAX
0AAAA5 84LDARETADR+1
0AAC69 00ADC#$00
0AAE48PHA
0AAF8ATXA
0AB048PHA
0AB160RTS
0AB2D0 28NEXT8BNENEXT10
0AB4BD 05 01NEXT9LDASTACK+5,XINTEGER LOOP: IACC = STEP
0AB785 A0STAIACC
0AB9BD 06 01LDA$0106,X
0ABC85 A1STAIACC+1
0ABEBD 0F 01LDA$010F,XRESULT = THE VARIABLE'S ADDRESS
0AC185 62STARESULT
0AC3BD 10 01LDA$0110,X
0AC685 63STARESULT+1
0AC8A0 01LDY#$01VARIABLE += STEP, LOW BYTE ...
0ACAB1 62LDA(RESULT),Y
0ACC18CLC
0ACD65 A1ADCIACC+1
0ACF91 62STA(RESULT),Y
0AD185 A1STAIACC+1
0AD388DEY... HIGH BYTE
0AD4B1 62LDA(RESULT),Y
0AD665 A0ADCIACC
0AD850 04BVCNEXT11OVERFLOW: ERROR $45
0ADAA2 45LDX#$45
0ADCD0 31NEXT10BNENEXT17
0ADE91 62NEXT11STA(RESULT),Y
0AE0A8TAY
0AE15D 0A 01EOR$010A,XSAME SIGN AS THE LIMIT?
0AE410 0ABPLNEXT13
0AE698TYA
0AE710 1FBPLNEXT16
0AE9BD 05 01NEXT12LDASTACK+5,X
0AEC10 11BPLNEXT15
0AEE30 AEBMINEXT6
0AF098NEXT13TYA
0AF1DD 0A 01CMP$010A,X
0AF490 F3NEXT14BCCNEXT12
0AF6D0 10BNENEXT16
0AF8A5 A1LDAIACC+1
0AFADD 0B 01CMP$010B,X
0AFDD0 F5BNENEXT14
0AFFBD 09 01NEXT15LDA$0109,XNOT PAST THE LIMIT: BACK TO THE LOOP
0B0248PHA
0B03BD 08 01LDA$0108,X
0B0648PHA
0B0760RTS
0B08BD 05 01NEXT16LDASTACK+5,X
0B0B30 F2BMINEXT15
0B0D10 8FBPLNEXT6
0B0FD0 53NEXT17BNEARRDIM2

ARRREAL

ARRAY ELEMENTS. EVERY ARRAY HAS A ROUTINE IN THE PROGRAM: SEC (LOAD) OR CLC (ADDRESS) THEN JSR ARRREAL, ARRSTR OR ARRINT, FOLLOWED BY THE ARRAY'S DESCRIPTOR: ITS ADDRESS, THE NUMBER OF DIMENSIONS AND THE HIGHEST INDEX OF EACH, LAST DIMENSION FIRST.

THE FIRST SUBSCRIPT IS IN IACC; THE OTHERS WERE PUSHED BY PUSHSUB. EACH IS CHECKED AGAINST ITS HIGHEST INDEX (ERROR $6B, BAD SUBSCRIPT) AND THE OFFSET IS BUILT AS OFFSET*(HIGHEST+1)+SUBSCRIPT, THEN SCALED BY THE ELEMENT SIZE (5 REAL, 2 INTEGER OR STRING).

LOAD: THE ELEMENT GOES TO FAC, IACC OR THE STRING ACCUMULATOR. ADDRESS: THE ELEMENT'S ADDRESS GOES TO $DC/$DD AND ITS TYPE TO $D9 FOR ARRSTORE, WHICH STORES THE VALUE COMPUTED IN BETWEEN.

0B11A2 00ARRREALLDX#$00X = ELEMENT TYPE: 0 REAL ...
0B132CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
0B14A2 02ARRSTRLDX#$02... 2 STRING ...
0B162CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
0B17A2 01ARRINTLDX#$01... 1 INTEGER
0B1908PHPKEEP THE CARRY: 1 LOAD, 0 ADDRESS
0B1A68PLA
0B1B85 64STARESULT+2
0B1D86 65STXRESULT+3AND THE TYPE
0B1F68PLATPTR = THE DESCRIPTOR - 1 (THE ROUTINE'S RETURN ADDRESS)
0B2085 55STATPTR
0B2268PLA
0B2385 56STATPTR+1
0B2568PLARETADR = THE COMPILED CODE'S RETURN ADDRESS
0B2685 83STARETADR
0B2868PLA
0B2985 84STARETADR+1
0B2BA5 A0LDAIACCTHE FIRST SUBSCRIPT JOINS THE OTHERS ON THE STACK
0B2D48PHA
0B2EA5 A1LDAIACC+1
0B3048PHA
0B31A0 00LDY#$00OFFSET = 0
0B3384 A1STYIACC+1
0B3584 A0STYIACC
0B37A0 03LDY#$03Y = 2 * DIMENSIONS + 3: THE LAST HIGHEST INDEX
0B39B1 55LDA(TPTR),Y
0B3B0AASLA
0B3CA8TAY
0B3DC8INY
0B3EC8INY
0B3FC8ARRDIMINYEACH DIMENSION: ADD THE NEXT SUBSCRIPT TO THE OFFSET
0B4068PLA
0B41AATAX
0B4218CLC
0B4365 A1ADCIACC+1
0B4585 A1STAIACC+1
0B4768PLA
0B4848PHA
0B4965 A0ADCIACC
0B4B85 A0STAIACC
0B4D68PLACHECK IT AGAINST THE HIGHEST INDEX
0B4ED1 55CMP(TPTR),Y
0B5090 14BCCARRSUB
0B52D0 08BNEARRDIM1
0B5488DEY
0B558ATXA
0B56D1 55CMP(TPTR),Y
0B5890 0DBCCARRSUB1
0B5AF0 0BBEQARRSUB1
0B5CA5 84ARRDIM1LDARETADR+1TOO LARGE (OR NEGATIVE): BAD SUBSCRIPT, ERROR $6B
0B5E48PHA
0B5FA5 83LDARETADR
0B6148PHA
0B62A2 6BLDX#$6B
0B64D0 60ARRDIM2BNEARRAD1
0B6688ARRSUBDEYNEXT DIMENSION
0B6788ARRSUB1DEY
0B6888DEY
0B69C0 02CPY#$02ALL DONE
0B6BF0 18BEQARRSIZE
0B6D84 8ESTYTEMP3+4OFFSET *= HIGHEST+1 OF THE NEXT DIMENSION
0B6FB1 55LDA(TPTR),Y
0B7118CLC
0B7269 01ADC#$01
0B7485 9FSTAIARG+1
0B76C8INY
0B77B1 55LDA(TPTR),Y
0B7969 00ADC#$00
0B7B85 9ESTAIARG
0B7DA2 00LDX#$00X = 0 (KEPT IN $16): MULSHARE COMES BACK TO $0B81
0B7FF0 75BEQMULSHARE
0B81A4 8EARRSUB2LDYTEMP3+4
0B83D0 BABNEARRDIM
0B85A6 65ARRSIZELDXRESULT+3TIMES THE ELEMENT SIZE: 2 ...
0B87F0 06BEQARRSI1
0B8906 A1ASLIACC+1
0B8B26 A0ROLIACC
0B8D90 15BCCARRADDR
0B8FA4 A0ARRSI1LDYIACC... OR 5 (4+1) FOR A REAL
0B91A5 A1LDAIACC+1
0B9385 16STAHDRFLAG
0B950AASLA
0B9626 A0ROLIACC
0B980AASLA
0B9926 A0ROLIACC
0B9B65 16ADCHDRFLAG
0B9D85 A1STAIACC+1
0B9F98TYA
0BA065 A0ADCIACC
0BA285 A0STAIACC
0BA4A5 84ARRADDRLDARETADR+1RETURN ADDRESS BACK FOR THE COMPILED CODE
0BA648PHA
0BA7A5 83LDARETADR
0BA948PHA
0BAAA0 01LDY#$01ELEMENT ADDRESS = ARRAY ADDRESS + OFFSET
0BAC18CLC
0BADA5 A1LDAIACC+1
0BAF71 55ADC(TPTR),Y
0BB1AATAX
0BB2C8INY
0BB3A5 A0LDAIACC
0BB571 55ADC(TPTR),Y
0BB7A8TAY
0BB88ATXA
0BB9A6 65LDXRESULT+3
0BBB46 64LSRRESULT+2LOAD?
0BBDB0 4FBCSMULSH1
0BBF84 DDSTYERRPOS+1NO: KEEP THE ADDRESS AND TYPE FOR ARRSTORE
0BC185 DCSTAERRPOS
0BC386 D9STXELTYPE
0BC560RTS
0BC6D0 79ARRAD1BNEMULLO3

IMULT

IMULT: INTEGER OPERATION 4: IACC = IACC * THE INTEGER AT (Y,A). SIGNS ARE TAKEN OUT (COUNTED IN $AB), THE MAGNITUDES MULTIPLIED BY SHIFT AND ADD, AND THE SIGN PUT BACK. ERROR $45 (OVERFLOW) IF THE PRODUCT DOES NOT FIT. MULSHARE IS THE SAME MULTIPLY WITHOUT SIGNS, USED BY THE ARRAY CODE.

0BC884 63IMULTSTYRESULT+1THE VARIABLE INTO IARG
0BCA85 62STARESULT
0BCCA0 00LDY#$00
0BCEB1 62LDA(RESULT),Y
0BD085 9ESTAIARG
0BD2C8INY
0BD3B1 62LDA(RESULT),Y
0BD585 9FSTAIARG+1
0BD7A2 02LDX#$02MAKE IARG AND IACC POSITIVE, COUNTING NEGATIVES
0BD986 ABSTXSGNCPR
0BDBB5 9EIMULT1LDAIARG,X
0BDD10 13BPLIMULT3
0BDF10 A0IMULT2BPLARRSUB2
0BE1C6 ABDECSGNCPRONE MORE NEGATIVE
0BE3A9 00LDA#$00
0BE538SEC
0BE6F5 9FSBCIARG+1,X
0BE895 9FSTAIARG+1,X
0BEAA9 00LDA#$00
0BECF5 9ESBCIARG,X
0BEE95 9ESTAIARG,X
0BF070 4DBVSMULLO2-32768 HAS NO POSITIVE: OVERFLOW
0BF2CAIMULT3DEX
0BF3CADEX
0BF4F0 E5BEQIMULT1
0BF686 16MULSHARESTXHDRFLAGTHE SMALLER FACTOR GOES IN THE SHIFT REGISTER
0BF8A6 9FLDXIARG+1
0BFAE4 A1CPXIACC+1
0BFCA5 9ELDAIARG
0BFEE5 A0SBCIACC
0C00B0 0EBCSMULSH2
0C02A4 9ELDYIARG
0C04A5 A0LDAIACC
0C0685 9ESTAIARG
0C08A5 A1LDAIACC+1
0C0A85 9FSTAIARG+1
0C0C90 06BCCMULSH3
0C0EB0 3EMULSH1BCSARRLOAD
0C10A4 A0MULSH2LDYIACC
0C12A6 A1LDXIACC+1
0C1484 A2MULSH3STYFACSIGNY,X: THE MULTIPLIER, SHIFTED OUT BIT BY BIT
0C1686 A3STXSERLEN
0C18A9 00LDA#$00PRODUCT = 0
0C1A85 A0STAIACC
0C1C85 A1STAIACC+1
0C1E46 A2MULLOOPLSRFACSIGNNEXT BIT OF THE MULTIPLIER
0C2066 A3RORSERLEN
0C2290 0FBCCMULLO1
0C24A5 9FLDAIARG+1SET: ADD THE MULTIPLICAND
0C2618CLC
0C2765 A1ADCIACC+1
0C2985 A1STAIACC+1
0C2BA5 9ELDAIARG
0C2D65 A0ADCIACC
0C2F85 A0STAIACC
0C3130 0CBMIMULLO2PAST 32767: OVERFLOW
0C33A5 A2MULLO1LDAFACSIGNNO BITS LEFT: DONE
0C3505 A3ORASERLEN
0C37F0 0CBEQMULLO5
0C3906 9FASLIARG+1MULTIPLICAND * 2
0C3B26 9EROLIARG
0C3D10 DFBPLMULLOOP
0C3FA2 45MULLO2LDX#$45OVERFLOW: ERROR $45
0C41D0 58MULLO3BNEDISPS2
0C43F0 83MULLO4BEQIMULT
0C4524 16MULLO5BITHDRFLAGFROM THE ARRAY CODE: BACK TO IT
0C4710 96BPLIMULT2
0C49C6 ABDECSGNCPRONE NEGATIVE FACTOR: NEGATE THE PRODUCT
0C4BF0 76BEQINEG
0C4D60RTS

ARRLOAD

ARRLOAD: LOAD THE ELEMENT AT (Y,A) BY ITS TYPE (X: 0 REAL, 1 INTEGER, 2 STRING).

0C4ECAARRLOADDEXREAL ...
0C4F10 08BPLARRLO1
0C5120 F9 EAJSRMOVFMFAC = THE ELEMENT, FLAGS SET
0C54A5 AALDAARGSIGN
0C564C 59 DEJMPSGNEXIT
0C59F0 44ARRLO1BEQILOADINTEGER: ILOAD ...
0C5B84 63STYRESULT+1... STRING: BOTH STRING ACCUMULATORS
0C5D85 62STARESULT
0C5FA0 00LDY#$00
0C61B1 62LDA(RESULT),Y
0C6385 77STASTRACC
0C6585 79STASTRPSH
0C67C8INY
0C68B1 62LDA(RESULT),Y
0C6A85 78STASTRACC+1
0C6C85 7ASTASTRPSH+1
0C6E60RTS

ARRSTORE

ARRSTORE: STORE THE VALUE INTO THE ARRAY ELEMENT WHOSE ADDRESS AND TYPE THE ARRAY ROUTINE LEFT IN $DC/$DD AND $D9.

0C6FA4 DDARRSTORELDYERRPOS+1THE ELEMENT'S ADDRESS ...
0C71A5 DCLDAERRPOS
0C73A6 D9LDXELTYPE... AND TYPE
0C75D0 04BNEARRST1
0C77AATAXREAL: STORE FAC ROUNDED
0C784C 2B EBJMPMOVMF
0C7BCAARRST1DEXINTEGER: STORE IACC; STRING: FALL INTO THE STRING STORE WITH CARRY CLEAR
0C7CF0 33BEQISTORE
0C7E18CLC

DISPSTR

DISPSTR: THE STRING VARIABLE DISPATCHER. A STRING VARIABLE'S ROUTINE IS SEC (OR CLC), LDA #, LDY #HIGH, LDA #LOW, JMP DISPSTR: CARRY SET LOADS THE VARIABLE'S POINTER INTO THE STRING ACCUMULATOR $77/$78, CARRY CLEAR STORES IT.

0C7F85 55DISPSTRSTATPTR
0C8184 56STYTPTR+1
0C83A0 00LDY#$00
0C8590 0ABCCDISPS1CARRY CLEAR: STORE
0C87B1 55LDA(TPTR),YLOAD: THE VARIABLE'S POINTER INTO $77/$78
0C8985 77STASTRACC
0C8BC8INY
0C8CB1 55LDA(TPTR),Y
0C8E85 78STASTRACC+1
0C9060RTS
0C91A5 77DISPS1LDASTRACCSTORE: $77/$78 INTO THE VARIABLE
0C9391 55STA(TPTR),Y
0C95C8INY
0C96A5 78LDASTRACC+1
0C9891 55STA(TPTR),Y
0C9A60RTS
0C9BD0 4EDISPS2BNEISUBT2
0C9DF0 A4DISPS3BEQMULLO4

ILOAD

INTEGER OPERATIONS 0 AND 1, ENTERED FROM DISPINT WITH (Y,A) = THE VARIABLE'S ADDRESS. INTEGERS ARE STORED HIGH BYTE FIRST. BOTH LEAVE THE FLAGS SET BY THE VALUE.

0C9F84 63ILOADSTYRESULT+1LOAD IACC FROM THE VARIABLE
0CA185 62STARESULT
0CA3A0 00LDY#$00
0CA5B1 62LDA(RESULT),Y
0CA785 A0STAIACC
0CA9C8INY
0CAAB1 62LDA(RESULT),Y
0CAC85 A1STAIACC+1
0CAE05 A0ORAIACC
0CB060RTS
0CB184 63ISTORESTYRESULT+1STORE IACC IN THE VARIABLE
0CB385 62STARESULT
0CB5A0 00LDY#$00
0CB7A5 A0LDAIACC
0CB991 62STA(RESULT),Y
0CBBC8INY
0CBCA5 A1LDAIACC+1
0CBE91 62STA(RESULT),Y
0CC005 A0ORAIACC
0CC260RTS

INEG

INEG: IACC = -IACC. IRSUB (INTEGER OPERATION 3): IACC = VARIABLE - IACC. ISUBT: IACC = IARG - IACC. IADD (OPERATION 2): IACC = IACC + VARIABLE. ERROR $45 ON OVERFLOW.

0CC3A9 00INEGLDA#$00IARG = 0, THEN 0 - IACC
0CC585 9ESTAIARG
0CC785 9FSTAIARG+1
0CC9F0 0FBEQISUBT
0CCB84 63IRSUBSTYRESULT+1IARG = THE VARIABLE
0CCD85 62STARESULT
0CCFA0 00LDY#$00
0CD1B1 62LDA(RESULT),Y
0CD385 9ESTAIARG
0CD5C8INY
0CD6B1 62LDA(RESULT),Y
0CD885 9FSTAIARG+1
0CDAA5 9FISUBTLDAIARG+1IACC = IARG - IACC
0CDC38SEC
0CDDE5 A1SBCIACC+1
0CDF85 A1STAIACC+1
0CE1A5 9ELDAIARG
0CE3E5 A0SBCIACC
0CE585 A0STAIACC
0CE750 1CBVCIADD1
0CE9A2 45ISUBT1LDX#$45OVERFLOW: ERROR $45
0CEBD0 6EISUBT2BNEICOMP5
0CED84 63IADDSTYRESULT+1IACC = IACC + THE VARIABLE
0CEF85 62STARESULT
0CF1A0 00LDY#$00
0CF3B1 62LDA(RESULT),Y
0CF5AATAX
0CF6C8INY
0CF7B1 62LDA(RESULT),Y
0CF918CLC
0CFA65 A1ADCIACC+1
0CFC85 A1STAIACC+1
0CFE8ATXA
0CFF65 A0ADCIACC
0D0185 A0STAIACC
0D0370 E4BVSISUBT1
0D0560IADD1RTS

DISPINT

DISPINT: THE INTEGER VARIABLE DISPATCHER. A NUMERIC VARIABLE'S ROUTINE LOADS X WITH THE OPERATION AND (Y,A) WITH THE VARIABLE'S ADDRESS AND JUMPS HERE.

0 LOAD IACC, 1 STORE IACC, 2 ADD, 3 VARIABLE MINUS IACC, 4 MULTIPLY, 5 COMPARE; 6-13 ARE THE REAL OPERATIONS 0-7 WITH THE VARIABLE USED AS A REAL: 6 LOAD FAC, 7 STORE FAC (ROUNDED, RANGE CHECKED), 8 ADD, 9 SUBTRACT, 10 MULTIPLY, 11 COMPARE, 12 LOAD ARG, 13 DIVIDE.

0D06CADISPINTDEXOPERATION 0
0D0730 96BMIILOAD
0D09F0 A6BEQISTORE1
0D0BCADEX2
0D0CF0 DFBEQIADD
0D0ECADEX3
0D0FF0 BABEQIRSUB
0D11CADEX4
0D12F0 89BEQDISPS3
0D14CADEX5
0D15F0 1EBEQICOMP
0D17CADEX6: LOAD AS A REAL
0D18F0 43BEQICOMP6
0D1ACADEX7: STORE FAC
0D1BF0 42BEQISTOREF
0D1DCADEX8: ADD AS A REAL
0D1EF0 65BEQISTOR6
0D20CADEX9: SUBTRACT: FAC = -FAC, THEN ADD
0D21F0 5DBEQISTOR5
0D23CADEX10: MULTIPLY
0D24F0 51BEQISTOR3
0D26CADEX11: COMPARE
0D27F0 3DBEQISTOR1
0D29CADEX12: LOAD ARG
0D2AF0 62BEQISTOR8
0D2CA2 01LDX#$0113: DIVIDE
0D2ED0 60BNEISTOR9
0D30A5 9DDISPI1LDAFACFAC = ARG / FAC
0D324C 69 EAJMPFDIVT

ICOMP

ICOMP: INTEGER OPERATION 5: COMPARE IACC WITH THE VARIABLE. A = -1, 0 OR 1 AS FCOMP GIVES IT, FOR THE RELATIONS.

0D3584 63ICOMPSTYRESULT+1Y = HIGH BYTE, X = LOW BYTE OF THE VARIABLE
0D3785 62STARESULT
0D39A0 01LDY#$01
0D3BB1 62LDA(RESULT),Y
0D3DAATAX
0D3E88DEY
0D3FB1 62LDA(RESULT),Y
0D41A8TAY
0D4245 A0EORIACCDIFFERENT SIGNS: THE NEGATIVE ONE IS SMALLER
0D4410 06BPLICOMP2
0D4698TYA
0D4730 0FBMIICOMP4
0D49A9 FFICOMP1LDA#$FF
0D4B60RTS
0D4CC4 A0ICOMP2CPYIACCSAME SIGN: COMPARE HIGH, THEN LOW
0D4E90 08ICOMP3BCCICOMP4
0D50D0 F7BNEICOMP1
0D528ATXA
0D53E5 A1SBCIACC+1
0D55D0 F7BNEICOMP3
0D5760RTS
0D58A9 01ICOMP4LDA#$01
0D5A60RTS
0D5BD0 4DICOMP5BNEISTOR12
0D5DF0 4DICOMP6BEQISTOR13

ISTOREF

ISTOREF: INTEGER OPERATION 7: STORE FAC IN THE INTEGER VARIABLE THROUGH APPLESOFT'S OWN LET, WHICH ROUNDS AND CHECKS THE RANGE.

0D5F84 86ISTOREFSTYFORPNT+1THE VARIABLE'S ADDRESS FOR LET
0D6185 85STAFORPNT
0D634C 65 DAJMPLET2
0D66A2 03ISTOR1LDX#$03
0D68D0 44BNEIREAL
0D6A20 21 EBISTOR2JSRMOV1FCOMPARE: THE OLD FAC (IN ARG) WITH THE VARIABLE
0D6D20 53 EBJSRMOVFA
0D70A0 00LDY#$00
0D72A9 93LDA#$93
0D744C B2 EBJMPFCOMP
0D77A2 02ISTOR3LDX#$02
0D79D0 33BNEIREAL
0D7BA5 9DISTOR4LDAFACFAC = ARG * FAC
0D7D4C 82 E9JMPFMULTT
0D8048ISTOR5PHA
0D8120 D0 EEJSRNEGOP
0D8468PLA
0D85A2 01ISTOR6LDX#$01
0D87D0 25BNEIREAL
0D89A5 9DISTOR7LDAFACFAC = ARG + FAC
0D8B4C C1 E7JMPFADDT
0D8EA2 00ISTOR8LDX#$00
0D9086 64ISTOR9STXRESULT+2
0D92A2 04LDX#$04
0D94D0 18BNEIREAL
0D96A2 05ISTOR10LDX#$05LOAD ARG / DIVIDE: SWAP FAC AND ARG
0D98B4 9DISTOR11LDYFAC,X
0D9AB5 A5LDAARG,X
0D9C94 A5STYARG,X
0D9E95 9DSTAFAC,X
0DA0CADEX
0DA110 F5BPLISTOR11
0DA3A6 64LDXRESULT+2
0DA5D0 89BNEDISPI1
0DA7A5 9DLDAFAC
0DA960RTS
0DAAD0 3FISTOR12BNEXDRAW3
0DACA2 00ISTOR13LDX#$00

IREAL

IREAL: THE REAL OPERATIONS ON AN INTEGER VARIABLE. X: 0 LOAD, 1 ADD, 2 MULTIPLY, 3 COMPARE, 4 LOAD ARG OR (WITH $64 SET) DIVIDE. FOR ALL BUT A LOAD THE CURRENT FAC IS MOVED TO ARG; THE VARIABLE IS LOADED INTO FAC AS A REAL AND THE OPERATION APPLIED.

0DAE86 16IREALSTXHDRFLAGX: WHICH REAL OPERATION
0DB0CADEX
0DB130 09BMIIREAL1
0DB348PHATHE CURRENT FAC TO ARG
0DB498TYA
0DB548PHA
0DB620 63 EBJSRMOVAF
0DB968PLA
0DBAA8TAY
0DBB68PLA
0DBC84 A1IREAL1STYIACC+1VPNT = THE VARIABLE'S ADDRESS
0DBE85 A0STAIACC
0DC020 E9 DEJSRINTVARFAC = THE INTEGER AS A REAL
0DC3A5 AALDAARGSIGN
0DC520 59 DEJSRSGNEXITSIGNS COMPARED; A = THE EXPONENT
0DC8A6 16LDXHDRFLAG
0DCAD0 02BNEIREAL2A LOAD: DONE
0DCCAATAX
0DCD60RTS
0DCECAIREAL2DEX
0DCFF0 B8BEQISTOR7
0DD1CADEX
0DD2F0 A7BEQISTOR4
0DD4CADEX
0DD5F0 93BEQISTOR2
0DD7D0 BDBNEISTOR10

DRAWAT

HI-RES: DRAW AND XDRAW AT X,Y, HPLOT TO AND HPLOT. EACH HAS A REAL ENTRY (JSR AYINT) AND AN INTEGER ENTRY 3 BYTES LATER. X WAS SAVED IN $50/$51 BY SAVEHX AND THE SHAPE NUMBER IN $F0; Y IS THE ARGUMENT NOW. X MUST BE BELOW 280 AND Y BELOW 192 (ERROR $35, ILLEGAL QUANTITY).

0DD920 0C E1DRAWATJSRAYINT
0DDCA9 01DRAWATILDA#$01
0DDED0 05BNEXDRAW2
0DE020 0C E1XDRAWATJSRAYINT
0DE3A9 02XDRAWATILDA#$02
0DE585 65XDRAW2STARESULT+3
0DE7A9 02LDA#$02
0DE9D0 0EBNEHGRPOINT
0DEBD0 45XDRAW3BNEHGRPO5
0DED20 0C E1HPLOTTOJSRAYINT
0DF0A9 00HPLOTTOILDA#$00
0DF2F0 05BEQHGRPOINT
0DF420 0C E1HPLOTJSRAYINT
0DF7A9 01HPLOTILDA#$01
0DF985 16HGRPOINTSTAHDRFLAG$64: 0 HPLOT TO, 1 HPLOT, 2 DRAW/XDRAW AT
0DFB20 FE E6JSRCONINT2Y COORDINATE
0DFEE0 C0CPX#$C0BELOW 192
0E00B0 2EBCSHGRPO4
0E02A4 51LDYLINNUM+1X (SAVED IN $50/$51) BELOW 280
0E04A6 50LDXLINNUM
0E06C0 01CPY#$01
0E0890 06BCCHGRPO1
0E0AD0 24BNEHGRPO4
0E0CE0 18CPX#$18
0E0EB0 20BCSHGRPO4
0E10A5 16HGRPO1LDAHDRFLAG
0E12F0 12BEQHGRPO3
0E14A5 A1LDAIACC+1HPLOT: POSITION AND PLOT
0E16C6 16DECHDRFLAG
0E18F0 09BEQHGRPO2
0E1A20 11 F4JSRHPOSNDRAW AT: POSITION, THEN DRAW SHAPE $F0
0E1DA6 F0LDXFIRST
0E1FA9 01LDA#$01
0E21D0 22BNESHAPE1
0E234C 57 F4HGRPO2JMPHPLOT0
0E268AHGRPO3TXAHPLOT TO: A LINE TO X,Y
0E2748PHA
0E2898TYA
0E29AATAX
0E2A68PLA
0E2BA4 A1LDYIACC+1
0E2D4C 3A F5JMPHGLIN
0E30A2 35HGRPO4LDX#$35ILLEGAL QUANTITY: ERROR $35
0E32D0 7EHGRPO5BNEASCFN1

DRAW

DRAW AND XDRAW: THE SHAPE NUMBER IS CHECKED AGAINST THE COUNT AT THE START OF THE SHAPE TABLE, THE SHAPE'S ADDRESS LOOKED UP, AND THE ROM DRAWS IT WITH THE CURRENT ROTATION.

0E3420 0C E1DRAWJSRAYINT
0E37A9 01DRAWILDA#$01
0E39D0 05BNESHAPEARG
0E3B20 0C E1XDRAWJSRAYINT
0E3EA9 02XDRAWILDA#$02
0E4085 65SHAPEARGSTARESULT+31 DRAW, 2 XDRAW
0E4220 FE E6JSRCONINT2
0E45A5 E8SHAPE1LDASHAPETBLTHE SHAPE TABLE
0E4785 1ASTAHGRSHAPE
0E49A5 E9LDASHAPETBL+1
0E4B85 1BSTAHGRSHAPE+1
0E4D8ATXASHAPE NUMBER, NOT ABOVE THE COUNT IN THE TABLE'S FIRST BYTE
0E4EA2 00LDX#$00
0E50C1 1ACMP(HGRSHAPE,X)
0E52F0 02BEQSHAPE2
0E54B0 DABCSHGRPO4
0E560ASHAPE2ASLATHE SHAPE'S OFFSET, 2 BYTES PER NUMBER ...
0E5790 03BCCSHAPE3
0E59E6 1BINCHGRSHAPE+1
0E5B18CLC
0E5CA8SHAPE3TAY
0E5DB1 1ALDA(HGRSHAPE),Y... GIVES ITS ADDRESS
0E5F65 1AADCHGRSHAPE
0E61AATAX
0E62C8INY
0E63B1 1ALDA(HGRSHAPE),Y
0E6565 E9ADCSHAPETBL+1
0E6785 1BSTAHGRSHAPE+1
0E6986 1ASTXHGRSHAPE
0E6BA5 F9LDAHGRROTWITH THE CURRENT ROTATION
0E6DC6 65DECRESULT+3
0E6FF0 03BEQSHAPE4
0E714C 61 F6JMPXDRAW1
0E744C 05 F6SHAPE4JMPDRAW1

COLOR

COLOR=. LIKE MOST STATEMENTS WITH ONE NUMBER, A REAL ENTRY (JSR AYINT) FALLS INTO THE INTEGER ENTRY, WHICH TAKES THE BYTE WITH CONINT AND GOES ON INTO THE ROM'S OWN CODE FOR THE STATEMENT.

0E7720 0C E1COLORJSRAYINT
0E7A20 FE E6COLORIJSRCONINT2
0E7D4C 52 F2JMPCOLOR2

VALFN

VALFN: VAL OF THE STRING ACCUMULATOR. THE BYTE AFTER THE STRING IS REPLACED BY 0 WHILE THE ROM'S FIN READS THE NUMBER, THEN PUT BACK.

0E80A0 00VALFNLDY#$00THE STRING'S LENGTH
0E82B1 77LDA(STRACC),Y
0E84A6 77LDXSTRACCTXTPTR = THE STRING
0E86A4 78LDYSTRACC+1
0E8886 B8STXTXTPTR
0E8A84 B9STYTXTPTR+1
0E8CE8INX
0E8DD0 01BNEVALFN1
0E8FC8INY
0E9086 83VALFN1STXRETADRRETADR = ITS TEXT
0E9284 84STYRETADR+1
0E94A8TAYTHE BYTE AFTER THE TEXT ...
0E9585 16STAHDRFLAG
0E97B1 83LDA(RETADR),Y
0E9948PHA
0E9AA9 00LDA#$00... BECOMES 0 FOR NOW
0E9C91 83STA(RETADR),Y
0E9E20 B1 00JSRCHRGETFIN READS THE NUMBER
0EA120 4A ECJSRFIN
0EA468PLAPUT THE BYTE BACK
0EA5A4 16LDYHDRFLAG
0EA791 83STA(RETADR),Y
0EA960RTS

ASCFN

ASCFN: ASC OF THE STRING ACCUMULATOR INTO IACC (ERROR $35 FOR AN EMPTY STRING). LENFN: ITS LENGTH INTO IACC.

0EAAA0 00ASCFNLDY#$00THE LENGTH
0EACB1 77LDA(STRACC),Y
0EAED0 04BNEASCFN2
0EB0A2 35LDX#$35EMPTY: ERROR $35
0EB2D0 55ASCFN1BNEPRSTR3
0EB4C8ASCFN2INYY = 1: THE FIRST CHARACTER (THE BIT SKIPS LENFN'S LDY #0)
0EB52CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
0EB6A0 00LENFNLDY#$00
0EB8B1 77LDA(STRACC),YIACC = THE BYTE
0EBA85 A1STAIACC+1
0EBCA0 00LDY#$00
0EBE84 A0STYIACC
0EC0A8TAY
0EC160RTS

STRLITP

STRLITP AND STRLIT: A STRING LITERAL IN THE CODE: THE CALL IS FOLLOWED BY THE LITERAL'S ADDRESS. THE STRING ACCUMULATOR POINTS AT IT (IT IS NOT COPIED) AND THE CALL RETURNS PAST THE WORD; STRLITP ALSO PRINTS IT (AN INPUT PROMPT).

0EC2A2 01STRLITPLDX#$01X = 1: ALSO PRINT
0EC42CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
0EC5A2 00STRLITLDX#$00X = 0
0EC786 16STXHDRFLAG
0EC968PLATHE RETURN ADDRESS POINTS BEFORE THE INLINE WORD
0ECA85 62STARESULT
0ECCAATAX
0ECD68PLA
0ECE85 63STARESULT+1
0ED0A0 01LDY#$01$77/$78 = THE LITERAL'S ADDRESS
0ED2B1 62LDA(RESULT),Y
0ED485 77STASTRACC
0ED6C8INY
0ED7B1 62LDA(RESULT),Y
0ED985 78STASTRACC+1
0EDBA4 63LDYRESULT+1RETURN PAST THE WORD
0EDDE8INX
0EDED0 01BNESTRLIT1
0EE0C8INY
0EE1E8STRLIT1INX
0EE2D0 01BNESTRLIT2
0EE4C8INY
0EE598STRLIT2TYA
0EE648PHA
0EE78ATXA
0EE848PHA
0EE9A5 16LDAHDRFLAG
0EEBD0 01BNEPRSTR
0EED60RTS

PRSTR

PRSTR: PRINT THE STRING ACCUMULATOR.

0EEEA0 00PRSTRLDY#$00THE LENGTH
0EF0B1 77LDA(STRACC),Y
0EF285 0ESTAENDCHR
0EF4C8INY
0EF584 16STYHDRFLAG
0EF7A5 0ELDAENDCHR
0EF9F0 0DBEQPRSTR2
0EFBA4 16PRSTR1LDYHDRFLAGEACH CHARACTER
0EFDB1 77LDA(STRACC),Y
0EFF20 5C DBJSROUTDO
0F02E6 16INCHDRFLAG
0F04C6 0EDECENDCHR
0F06D0 F3BNEPRSTR1
0F0860PRSTR2RTS
0F09D0 68PRSTR3BNEGARBAG6

CLRCHAIN

CLRCHAIN (REM! CLEAR CHAIN) AND FREFN (FRE): BOTH COLLECT GARBAGE. CLEAR CHAIN LEAVES THE LOCAL STRINGS OUT, SO ONLY THE COMMON STRINGS SURVIVE, PACKED AT THE TOP OF STRING SPACE, FOR THE NEXT PROGRAM; IT THEN GOES ON INTO CLEAR, WHICH CLEARS THE LOCAL VARIABLES.

0F0BA5 80CLRCHAINLDALOCSEND+1KEEP THE LOCAL STRING END'S HIGH BYTE ...
0F0D48PHA
0F0EA9 00LDA#$00... AND MAKE IT 0: NO LOCAL STRINGS ARE KEPT
0F1085 80STALOCSEND+1
0F122CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
0F13A9 01FREFNLDA#$01FRE: COLLECT, THEN RETURN THE FREE SPACE

GARBAG

GARBAG: THE GARBAGE COLLECTOR. EACH ROUND FINDS THE HIGHEST STRING STILL IN USE THAT IS BELOW THE STRINGS ALREADY MOVED, COPIES IT TO THE TOP OF STRING SPACE AND REWRITES EVERY POINTER TO IT. THE POINTERS ARE THE COMMON STRINGS, THE LOCAL STRINGS AND THE TWO STRING ACCUMULATORS. LITERALS IN THE PROGRAM LIE BELOW STRING SPACE AND ARE LEFT ALONE.

FRE RETURNS THE FREE SPACE, FROM THE BOTTOM OF STRINGS DOWN TO THE HIGHEST ADDRESS USED BY THE PROGRAM. ERROR $4D, OUT OF MEMORY, WHEN A STRING DOES NOT FIT.

0F1548GARBAGPHATHE MODE: 0 CLEAR CHAIN, 1 FRE, $FF A NEW STRING THAT DID NOT FIT
0F16A5 6FLDAFRETOPTEMP1 = THE OLD BOTTOM OF STRINGS
0F1885 93STATEMP1
0F1AA5 70LDAFRETOP+1
0F1C85 94STATEMP1+1
0F1EA5 73LDAMEMSIZTHE MOVED STRINGS WILL GROW DOWN FROM HIMEM-2
0F2038SEC
0F21E9 02SBC#$02
0F2385 6FSTAFRETOP
0F2585 95STATEMP1+2
0F27A5 74LDAMEMSIZ+1
0F29E9 00SBC#$00
0F2B85 70STAFRETOP+1
0F2D85 96STATEMP1+3
0F2FA2 00GARBAG1LDX#$00START A ROUND: THE HIGHEST STRING FOUND SO FAR = NONE
0F3186 66STXRESULT+4
0F3386 82STXVARNAM+1
0F352CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
0F36A2 12GARBAG2LDX#$12THE POINTERS: FIRST THE COMMON STRINGS (X = 0), THEN THE LOCAL ONES (X = $12)
0F38B5 6BLDANUMCEND,X
0F3A38SEC
0F3BE9 01SBC#$01
0F3D85 55STATPTR
0F3FB5 6CLDANUMCEND+1,X
0F41E9 00SBC#$00
0F4385 56STATPTR+1
0F45D0 2ABNEGARBAG5
0F47A0 01GARBAG3LDY#$01ONE POINTER
0F49B1 55LDA(TPTR),Y
0F4B24 66BITRESULT+4REWRITING THE POINTERS TO THE STRING JUST MOVED?
0F4D10 26BPLGARBAG7
0F4FC5 82CMPVARNAM+1
0F51D0 6BBNEGARBAG15
0F5388DEY
0F54B1 55LDA(TPTR),Y
0F56C5 81CMPVARNAM
0F58D0 64BNEGARBAG15
0F5AA0 00GARBAG4LDY#$00YES: POINT AT ITS NEW PLACE
0F5CA5 62LDARESULT
0F5E91 55STA(TPTR),Y
0F60C8INY
0F61A5 63LDARESULT+1
0F6391 55STA(TPTR),Y
0F65A5 55LDATPTR
0F67C5 ADCMPSERPNT
0F69D0 53BNEGARBAG15
0F6BA5 56LDATPTR+1
0F6DC5 AECMPSERPNT+1
0F6FF0 BEBEQGARBAG1
0F71D0 4BGARBAG5BNEGARBAG15
0F73D0 73GARBAG6BNEGARBAG20
0F75C5 82GARBAG7CMPVARNAM+1SEARCHING: IS THIS STRING HIGHER THAN THE BEST SO FAR?
0F7790 45BCCGARBAG15
0F79D0 15BNEGARBAG9
0F7B88DEY
0F7CB1 55LDA(TPTR),Y
0F7EC5 81CMPVARNAM
0F8090 3CBCCGARBAG15
0F82D0 0CBNEGARBAG9
0F84A5 55LDATPTR
0F8685 ADSTASERPNT
0F88A5 56LDATPTR+1
0F8A85 AESTASERPNT+1
0F8CB0 30BCSGARBAG15
0F8ED0 85GARBAG8BNEGARBAG
0F90A0 00GARBAG9LDY#$00AND BELOW THE STRINGS ALREADY MOVED?
0F92B1 55LDA(TPTR),Y
0F94C5 95CMPTEMP1+2
0F96C8INY
0F97B1 55LDA(TPTR),Y
0F99E5 96SBCTEMP1+3
0F9BB0 21BCSGARBAG15
0F9D90 08BCCGARBAG14
0F9F30 B9GARBAG10BMIGARBAG4
0FA190 A4GARBAG11BCCGARBAG3
0FA3F0 91GARBAG12BEQGARBAG2
0FA5F0 88GARBAG13BEQGARBAG1
0FA7B1 55GARBAG14LDA(TPTR),YTHE NEW BEST
0FA985 82STAVARNAM+1
0FAB88DEY
0FACB1 55LDA(TPTR),Y
0FAE85 81STAVARNAM
0FB086 64STXRESULT+2
0FB2A5 55LDATPTR
0FB485 8ASTATEMP3
0FB685 ADSTASERPNT
0FB8A5 56LDATPTR+1
0FBA85 8BSTATEMP3+1
0FBC85 AESTASERPNT+1
0FBE8AGARBAG15TXANEXT POINTER
0FBF30 2BBMIGARBAG22
0FC1A5 55LDATPTR
0FC318CLC
0FC469 02ADC#$02
0FC685 55STATPTR
0FC890 02BCCGARBAG16
0FCAE6 56INCTPTR+1
0FCCD5 6DGARBAG16CMPSTRCEND,X
0FCEA5 56LDATPTR+1
0FD0F5 6ESBCSTRCEND+1,X
0FD290 CDGARBAG17BCCGARBAG11
0FD48ATXA
0FD5F0 CCBEQGARBAG12
0FD7A2 80LDX#$80THEN THE TWO STRING ACCUMULATORS ($77, $79)
0FD9A9 77LDA#$77
0FDB85 55STATPTR
0FDDA9 00LDA#$00
0FDF85 56STATPTR+1
0FE118CLC
0FE290 BDBCCGARBAG11
0FE430 B9GARBAG18BMIGARBAG10
0FE6D0 A6GARBAG19BNEGARBAG8
0FE8D0 79GARBAG20BNEGARBAG31
0FEAF0 B9GARBAG21BEQGARBAG13
0FECA9 79GARBAG22LDA#$79
0FEEC5 55CMPTPTR
0FF085 55STATPTR
0FF218CLC
0FF3D0 DDBNEGARBAG17
0FF5A4 81LDYVARNAMTHE ROUND IS OVER
0FF784 95STYTEMP1+2
0FF9A5 82LDAVARNAM+1
0FFBF0 68BEQGARBAG32NONE FOUND: DONE
0FFD85 96STATEMP1+3
0FFFA6 80LDXLOCSEND+1CLEAR CHAIN: A STRING BELOW THE OLD BOTTOM IS NOT A COMMON STRING TO KEEP
1001F0 06BEQGARBAG23
1003C4 93CPYTEMP1
1005E5 94SBCTEMP1+1
100790 5CBCCGARBAG32
1009A0 00GARBAG23LDY#$00AN EMPTY STRING: POINT AT THE EMPTY STRING AT HIMEM-1
100BB1 81LDA(VARNAM),Y
100DD0 0FBNEGARBAG25
100FA4 74LDYMEMSIZ+1
1011A6 73LDXMEMSIZ
1013D0 01BNEGARBAG24
101588DEY
1016CAGARBAG24DEX
101786 62STXRESULT
101984 63STYRESULT+1
101B38SEC
101CB0 33BCSGARBAG29
101E18GARBAG25CLCMOVE IT: ROOM BELOW THE BOTTOM OF STRINGS?
101FA5 6FLDAFRETOP
1021F1 81SBC(VARNAM),Y
1023AATAX
1024A5 70LDAFRETOP+1
1026E9 00SBC#$00
1028A8TAY
1029E4 14CPXHIGHESTNOT ABOVE THE PROGRAM: OUT OF MEMORY
102BE5 15SBCHIGHEST+1
102D90 54BCCGARBAG34
102F86 6FSTXFRETOP
103184 70STYFRETOP+1
1033E8INX
1034D0 01BNEGARBAG26
1036C8INY
103786 62GARBAG26STXRESULT
103984 63STYRESULT+1
103BE4 81CPXVARNAMALREADY THERE: NOTHING TO COPY
103DD0 04BNEGARBAG27
103FC4 82CPYVARNAM+1
1041F0 A7BEQGARBAG21
1043A0 00GARBAG27LDY#$00COPY THE LENGTH AND THE TEXT
1045B1 81LDA(VARNAM),Y
1047A8TAY
1048B1 81GARBAG28LDA(VARNAM),Y
104A91 62STA(RESULT),Y
104C88DEY
104DC0 FFCPY#$FF
104FD0 F7BNEGARBAG28
1051A5 8AGARBAG29LDATEMP3NOW REWRITE EVERY POINTER TO IT
105385 55STATPTR
1055A5 8BLDATEMP3+1
105785 56STATPTR+1
1059A6 64LDXRESULT+2
105BA9 80LDA#$80
105D85 66STARESULT+4
105F30 83BMIGARBAG18
1061D0 83GARBAG30BNEGARBAG19
1063D0 65GARBAG31BNEOLDTE2
106538GARBAG32SECFREE SPACE = BOTTOM OF STRINGS - HIGHEST ADDRESS
1066A5 6FLDAFRETOP
1068E5 14SBCHIGHEST
106AA8TAY
106BA5 70LDAFRETOP+1
106DE5 15SBCHIGHEST+1
106FAATAX
107068PLAMODE 1, FRE: RETURN IT IN FAC
1071F0 15BEQGARBAG35
107330 04BMIGARBAG33
10758ATXA
10764C F2 E2JMPGIVAYF
107938GARBAG33SECA NEW STRING: DOES IT FIT NOW?
107A8ATXA
107BD0 1CBNEGARBAG36
107DC4 0DCPYCHARAC
107FF0 02BEQGARBAG34
1081B0 16BCSGARBAG36
1083A2 4DGARBAG34LDX#$4DOUT OF MEMORY: ERROR $4D
10854C 12 D4JMPERROR
108868GARBAG35PLACLEAR CHAIN: PUT THE LOCAL STRING END BACK ...
108985 80STALOCSEND+1
108BA5 AFLDAFORPOP... AND RETURN INTO CLEAR: FORPOP-$107 = $08A9, ONE BEFORE CLEAR, SO THE LOCAL VARIABLES ARE CLEARED AND THE STACK RESET
108D38SEC
108EE9 07SBC#$07
1090AATAX
1091A5 B0LDAFORPOP+1
1093E9 01SBC#$01
109548PHA
10968ATXA
109748PHA
109860RTS
1099B0 42GARBAG36BCSGETSTR2

OLDTEXT

OLDTEXT: 45 BYTES OF TEXT LEFT IN MEMORY BY THE ASSEMBLER: NEVER EXECUTED. THE BRANCH BEFORE THEM IS ALWAYS TAKEN.

109B4C 45 3F 20 22 3B 3A B0OLDTEXTDFB$4C,$45,$3F,$20,$22,$3B,$3A,$B0"LE? ";:0"
10A331 31 32 30 3A 52 46 D0DFB$31,$31,$32,$30,$3A,$52,$46,$D0"1120:RFP"
10AB32 3A AB 31 33 36 30 3ADFB$32,$3A,$AB,$31,$33,$36,$30,$3A"2:+1360:"
10B3B2 20 20 20 20 49 46 20DFB$B2,$20,$20,$20,$20,$49,$46,$20"2 IF "
10BB41 20 44 49 53 4B 20 43DFB$41,$20,$44,$49,$53,$4B,$20,$43"A DISK C"
10C34F 4D 4D 41 4EDFB$4F,$4D,$4D,$41,$4E"OMMAN"
10C8D0 97OLDTE1BNEGARBAG30
10CAD0 7BOLDTE2BNEPUSHS2

GETSTR

GETSTR: GET A$: A NEW ONE-CHARACTER STRING FROM THE KEYBOARD.

10CCA2 01GETSTRLDX#$01A ONE-BYTE STRING, KIND 5
10CEA9 05LDA#$05
10D0D0 79BNENEWSTR
10D220 53 D5GETSTR1JSRINCHRTHE KEY
10D5A0 01LDY#$01
10D791 55STA(TPTR),Y
10D9A9 00LDA#$00
10DBF0 45BEQCONCAT4
10DDB0 6FGETSTR2BCSNEWSTR1

CONCATT

CONCAT: THE PUSHED STRING FOLLOWED BY THE LOADED STRING, AS A NEW STRING (ERROR $B0, STRING TOO LONG, PAST 255). CONCATT SWAPS THE TWO FIRST.

10DFA5 77CONCATTLDASTRACCSWAP THE TWO STRINGS
10E1A6 79LDXSTRPSH
10E385 79STASTRPSH
10E586 77STXSTRACC
10E7A5 78LDASTRACC+1
10E9A6 7ALDXSTRPSH+1
10EB85 7ASTASTRPSH+1
10ED86 78STXSTRACC+1
10EFA0 00CONCATLDY#$00THE LOADED STRING EMPTY: THE RESULT IS THE PUSHED ONE
10F1B1 77LDA(STRACC),Y
10F3F0 49BEQPUSHS1
10F585 0ESTAENDCHR
10F7B1 79LDA(STRPSH),YTHE PUSHED STRING EMPTY: THE RESULT IS THE LOADED ONE
10F9F0 3ABEQPUSHSTR
10FB18CLCTHE TOTAL LENGTH
10FC65 0EADCENDCHR
10FE90 04BCCCONCAT1
1100A2 B0LDX#$B0PAST 255: STRING TOO LONG, ERROR $B0
1102D0 43BNEPUSHS2
1104AACONCAT1TAXA NEW STRING, KIND 0
110598TYA
1106C8INY
1107D0 42BNENEWSTR
1109EANOP
110AEANOP
110BA4 0ECONCAT2LDYENDCHRCOPY THE LOADED STRING TO THE END ...
110DB1 77LDA(STRACC),Y
110FA4 0DLDYCHARAC
111191 55STA(TPTR),Y
1113C6 0DDECCHARAC
1115C6 0EDECENDCHR
1117D0 F2BNECONCAT2
1119A4 0DLDYCHARAC
111BB1 79CONCAT3LDA(STRPSH),Y... AND THE PUSHED STRING BEFORE IT
111D91 55STA(TPTR),Y
111F88DEY
1120D0 F9BNECONCAT3
1122A5 55CONCAT4LDATPTRBOTH STRING ACCUMULATORS = THE NEW STRING
112485 77STASTRACC
112685 79STASTRPSH
1128A5 56LDATPTR+1
112A85 78STASTRACC+1
112C85 7ASTASTRPSH+1
112E60RTS
112FD0 97CONCAT5BNEOLDTE1
1131D0 9FCONCAT6BNEGETSTR1
1133EANOP
1134EANOP

PUSHSTR

PUSHSTR: COPY THE LOADED STRING TO THE PUSHED STRING.

1135A5 77PUSHSTRLDASTRACC
113785 79STASTRPSH
1139A5 78LDASTRACC+1
113B85 7ASTASTRPSH+1
113D60RTS
113EA5 79PUSHS1LDASTRPSH
114085 77STASTRACC
1142A5 7ALDASTRPSH+1
114485 78STASTRACC+1
114660RTS
1147D0 47PUSHS2BNENEWSTR4
1149F0 D7PUSHS3BEQCONCAT4

NEWSTR

NEWSTR: MAKE ROOM FOR A NEW STRING OF ($0D) BYTES BELOW THE BOTTOM OF STRING SPACE, COLLECTING GARBAGE IF IT DOES NOT FIT, AND FILL IT FOR THE CALLER: A SAYS WHICH (0 CONCAT, 1 CHR$, 2 STR$, 3 LEFT$/MID$, 4 RIGHT$, 5 GET).

114B48NEWSTRPHAKEEP THE KIND; $0D = THE LENGTH
114C86 0DSTXCHARAC
114EA5 6FNEWSTR1LDAFRETOPITS PLACE: BELOW THE BOTTOM OF STRINGS
115038SEC
1151E5 0DSBCCHARAC
115385 55STATPTR
1155A5 70LDAFRETOP+1
1157E9 00SBC#$00
115985 56STATPTR+1
115BA5 14LDAHIGHESTABOVE THE PROGRAM?
115DC5 55CMPTPTR
115FA5 15LDAHIGHEST+1
1161E5 56SBCTPTR+1
116390 04BCCNEWSTR2
1165A9 FFLDA#$FFNO: COLLECT GARBAGE AND TRY AGAIN
1167D0 C6BNECONCAT5
1169A0 00NEWSTR2LDY#$00THE LENGTH BYTE
116BA5 0DLDACHARAC
116D91 55STA(TPTR),Y
116FA4 56LDYTPTR+1THE NEW BOTTOM OF STRINGS
1171A6 55LDXTPTR
1173D0 01BNENEWSTR3
117588DEY
1176CANEWSTR3DEX
117786 6FSTXFRETOP
117984 70STYFRETOP+1
117B68PLAFILL IT BY KIND
117CA8TAY
117DF0 8CBEQCONCAT2
117F88DEY
1180F0 1BBEQCHRFNI1
118288DEY
1183F0 33BEQSTRFN3
118588DEY
1186F0 5DBEQLEFTI4
118888DEY
1189F0 65BEQLEFTI6
118BD0 A4BNECONCAT6
118DEANOP
118EEANOP
118FEANOP
1190D0 6BNEWSTR4BNERIGHTI1

CHRFN

CHR$: A ONE-CHARACTER STRING.

119220 0C E1CHRFNJSRAYINT
119520 FE E6CHRFNIJSRCONINT2THE CHARACTER, A ONE-BYTE STRING, KIND 1
1198A2 01LDX#$01
119A8ATXA
119BD0 AEBNENEWSTR
119DA6 A1CHRFNI1LDXIACC+1
119FA0 01LDY#$01
11A18ATXA
11A291 55STA(TPTR),Y
11A488DEY
11A5F0 A2CHRFNI2BEQPUSHS3
11A7F0 8CCHRFNI3BEQPUSHSTR

STRFN

STR$: FOUT CONVERTS FAC TO TEXT AT $0100; THE TEXT BECOMES A NEW STRING.

11A920 34 EDSTRFNJSRFOUTTHE NUMBER AS TEXT AT $0100
11ACA2 00LDX#$00ITS LENGTH
11AEE8STRFN1INX
11AFBD 00 01LDASTACK,X
11B2D0 FABNESTRFN1
11B4A9 02LDA#$02KIND 2
11B6D0 93STRFN2BNENEWSTR
11B8A4 0DSTRFN3LDYCHARACCOPY THE TEXT
11BAB9 FF 00STRFN4LDAZPFF,Y
11BD91 55STA(TPTR),Y
11BF88DEY
11C0D0 F8BNESTRFN4
11C2F0 E1BEQCHRFNI2

LEFT

LEFT$, RIGHT$ AND MID$. THE STRING IS IN THE STRING ACCUMULATOR; THE COUNT (AND FOR MID$ THE START, PUSHED BY PUSHBYTE) ARE BYTES. A ZERO COUNT IS ERROR $35. WHEN THE RESULT IS THE WHOLE STRING NO NEW STRING IS MADE; AN EMPTY RESULT POINTS AT THE EMPTY STRING.

11C420 0C E1LEFTJSRAYINT
11C720 FE E6LEFTIJSRCONINT2THE COUNT
11CA8ATXA
11CBD0 04BNELEFTI1
11CDA2 35LDX#$350: ERROR $35
11CFD0 2CBNERIGHTI1
11D1A0 00LEFTI1LDY#$00THE STRING'S LENGTH
11D3B1 77LDA(STRACC),Y
11D5F0 D0BEQCHRFNI3
11D785 0ESTAENDCHR
11D9E4 0ELEFTI2CPXENDCHRTHE COUNT COVERS THE WHOLE STRING: KEEP IT
11DB90 04BCCLEFTI3
11DDA9 00LDA#$00
11DFF0 C6BEQCHRFNI3
11E1A9 03LEFTI3LDA#$03OTHERWISE A NEW STRING OF THAT LENGTH, KIND 3
11E3D0 D1BNESTRFN2
11E5A4 0DLEFTI4LDYCHARACCOPY THE FIRST CHARACTERS
11E7B1 77LEFTI5LDA(STRACC),Y
11E991 55STA(TPTR),Y
11EB88DEY
11ECD0 F9BNELEFTI5
11EEF0 B5BEQCHRFNI2
11F0F0 21LEFTI6BEQRIGHTI5
11F220 0C E1RIGHTJSRAYINT
11F520 FE E6RIGHTIJSRCONINT2
11F88ATXA
11F9D0 04BNERIGHTI2
11FBA2 35LDX#$35
11FDD0 42RIGHTI1BNEMID3I2
11FFA0 00RIGHTI2LDY#$00
1201B1 77LDA(STRACC),Y
1203F0 A2RIGHTI3BEQCHRFNI3
120585 0ESTAENDCHR
1207E4 0ECPXENDCHR
120990 04BCCRIGHTI4
120BA9 00LDA#$00
120DF0 F4BEQRIGHTI3
120FA9 04RIGHTI4LDA#$04A NEW STRING, KIND 4
1211D0 A3BNESTRFN2
121338RIGHTI5SECRIGHT$: START AT LENGTH-COUNT
1214A5 0ELDAENDCHR
1216E5 0DSBCCHARAC
121818CLC
121965 77ADCSTRACC
121B85 77STASTRACC
121D90 02BCCRIGHTI6
121FE6 78INCSTRACC+1
1221D0 C2RIGHTI6BNELEFTI4
1223F0 B4RIGHTI7BEQLEFTI2
1225B0 BARIGHTI8BCSLEFTI3
122720 0C E1MID2JSRAYINT
122A20 FE E6MID2IJSRCONINT2
122DA9 FFLDA#$FFMID$ WITHOUT A COUNT: 255
122FD0 09BNEMID3I1
123120 0C E1MID3JSRAYINT
123420 FE E6MID3IJSRCONINT2
12378ATXAMID$ WITH A COUNT: THE START WAS PUSHED IN $10
1238A6 10LDXDIMFLG
123A85 16MID3I1STAHDRFLAG
123C8ATXA
123DD0 04BNEMID3I3
123FA2 35LDX#$35
1241D0 3FMID3I2BNEMID3I11
1243A0 00MID3I3LDY#$00
1245B1 77LDA(STRACC),Y
1247F0 BABEQRIGHTI3
124985 0ESTAENDCHR
124B8ATXA
124CA6 16LDXHDRFLAG
124ED0 10BNEMID3I6
1250A4 74MID3I4LDYMEMSIZ+1THE START IS PAST THE END: THE EMPTY STRING
1252A6 73LDXMEMSIZ
1254D0 01BNEMID3I5
125688DEY
1257CAMID3I5DEX
125886 77STXSTRACC
125A84 78STYSTRACC+1
125CA9 00LDA#$00
125EF0 A3BEQRIGHTI3
126038MID3I6SECSTART-1
1261E9 01SBC#$01
1263F0 BEBEQRIGHTI7
126585 64STARESULT+2
1267C5 0ECMPENDCHR
1269B0 E5BCSMID3I4
126B65 16ADCHDRFLAGSTART+COUNT PAST THE END?
126DB0 04BCSMID3I7
126FC5 0ECMPENDCHR
127190 07BCCMID3I8
1273A5 0EMID3I7LDAENDCHRTHEN TO THE END
1275E5 64SBCRESULT+2
1277AATAX
1278D0 95BNERIGHTI4
127A85 0EMID3I8STAENDCHR
127CD0 91BNERIGHTI4
127EB0 A5MID3I9BCSRIGHTI8
1280F0 CEMID3I10BEQMID3I4
1282D0 74MID3I11BNEINPST9

INPSTRQ

INPUT. INPSTR AND INPNUM READ THE FIRST ITEM (PRINTING "?"), THE P ENTRIES THE FIRST ITEM AFTER A PROMPT, THE N ENTRIES THE NEXT ITEMS. A NEW LINE IS READ WITH INLIN INTO $0200 WHEN NEEDED; $71 IS THE POSITION IN IT ($FF A NEW LINE, $FE USED UP).

STRINGS MAY BE QUOTED; ITEMS ARE SEPARATED BY COMMAS. A NUMBER IS CONVERTED BY FIN; A BAD ONE PRINTS ?REENTER AND THE WHOLE STATEMENT STARTS AGAIN AT THE ADDRESS INPBEG SAVED. CONTROL-C AS THE LINE'S FIRST CHARACTER STOPS THE PROGRAM.

128420 5A DBINPSTRQJSROUTQUESENTRY AFTER ?REENTER FOR A STRING
128720 5A DBINPSTRJSROUTQUESPRINT ?
128A20 2C D5INPSTRPJSRINLINREAD A LINE
128DAD 00 02LDAINBUFCONTROL-C FIRST: STOP
1290C9 03CMP#$03
1292F0 76BEQINPNU1
1294A9 FFLDA#$FFA NEW LINE: POSITION $FF
129685 71STAINPOS
1298A5 71INPSTRNLDAINPOSTHE LINE IS USED UP: ASK FOR MORE
129AC9 FECMP#$FE
129CF0 E6BEQINPSTRQ
129EAATAX
129FE8INPST1INXSKIP SPACES
12A0BD 00 02LDAINBUF,X
12A3C9 20CMP#$20
12A5F0 F8BEQINPST1
12A7C9 22CMP#$22A QUOTED STRING ENDS AT THE QUOTE ...
12A9F0 06BEQINPST2
12ABA0 2CLDY#$2C... ANOTHER AT A COMMA
12AD84 16STYHDRFLAG
12AFD0 06BNEINPST3
12B185 16INPST2STAHDRFLAG
12B3E8INX
12B4BD 00 02LDAINBUF,X
12B786 0EINPST3STXENDCHR
12B9A4 0ELDYENDCHR
12BBA2 00LDX#$00
12BDC9 00INPST4CMP#$00FIND THE END OF THE ITEM
12BFF0 20BEQINPST7
12C1C5 16CMPHDRFLAG
12C3F0 07BEQINPST5
12C5C8INY
12C6B9 00 02LDAINBUF,Y
12C9E8INX
12CAD0 F1BNEINPST4
12CCC9 2CINPST5CMP#$2CAFTER A QUOTE: SKIP SPACES TO THE COMMA OR THE END
12CEF0 13BEQINPST8
12D0C8INPST6INY
12D1B9 00 02LDAINBUF,Y
12D4C9 20CMP#$20
12D6F0 F8BEQINPST6
12D8C9 00CMP#$00
12DAF0 05BEQINPST7
12DCC9 2CCMP#$2C
12DED0 57BNEINPNU4ANYTHING ELSE: ?REENTER
12E02CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
12E1A0 FEINPST7LDY#$FETHE LINE IS USED UP
12E384 71INPST8STYINPOSTHE NEXT POSITION
12E58ATXA
12E6F0 98BEQMID3I10
12E818CLCTHE ITEM IS IN THE INPUT BUFFER: $77/$78 POINTS AT THE BYTE BEFORE IT, THE LENGTH
12E9A9 FFLDA#$FF
12EB65 0EADCENDCHR
12ED85 77STASTRACC
12EFA9 01LDA#$01
12F169 00ADC#$00
12F385 78STASTRACC+1
12F538SEC
12F6B0 86BCSMID3I9
12F8D0 12INPST9BNEINPNU2
12FA20 5A DBINPNUMQJSROUTQUESENTRY AFTER ?REENTER FOR A NUMBER
12FD20 5A DBINPNUMJSROUTQUES
130020 2C D5INPNUMPJSRINLIN
1303AD 00 02LDAINBUF
1306C9 03CMP#$03
1308D0 04BNEINPNU3
130AA2 FFINPNU1LDX#$FFCONTROL-C: X = $FF, A BREAK
130CD0 77INPNU2BNEPGMEND3
130EA9 FFINPNU3LDA#$FF
131085 71STAINPOS
1312A6 71INPNUMNLDXINPOSTHE LINE IS USED UP: ASK FOR MORE
1314E0 FECPX#$FE
1316F0 E2BEQINPNUMQ
1318E8INXTXTPTR = THE ITEM IN THE BUFFER AT $0200
131986 B8STXTXTPTR
131B86 16STXHDRFLAG
131DA9 02LDA#$02
131F85 B9STATXTPTR+1
132120 B7 00JSRCHRGOT
132420 4A ECJSRFINFIN CONVERTS IT
1327A6 B8LDXTXTPTRNOTHING READ: ?REENTER
1329E4 16CPXHDRFLAG
132BF0 0ABEQINPNU4
132D20 B7 00JSRCHRGOT
1330A8TAY
1331F0 10BEQINPNU5THE END OF THE LINE ...
1333C9 2CCMP#$2C... OR A COMMA
1335F0 0FBEQINPNU6
133720 87 DBINPNU4JSRREENTER?REENTER, OR THE ONERR ERROR $FE
133AEANOPFOUR BYTES THAT DO NOTHING
133BEANOP
133CEANOP
133DEANOP
133E68PLADROP THE RETURN ADDRESS AND START THE INPUT STATEMENT AGAIN AT THE ADDRESS INPBEG SAVED
133F68PLA
13406C 50 00JMP(LINNUM)
1343A9 FEINPNU5LDA#$FETHE LINE IS USED UP
13452CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
1346A5 B8INPNU6LDATXTPTR
134885 71STAINPOS
134A60RTS

STOP

STOP: PRINT BREAK IN AND THE OBJECT ADDRESS OF THE STOP, THEN END.

134B68STOPPLATHE STATEMENT'S OBJECT ADDRESS = RETURN ADDRESS - 2
134C38SEC
134DE9 02SBC#$02
134F85 75STACURLIN
135168PLA
1352E9 00SBC#$00
135485 76STACURLIN+1
1356A9 5DLDA#$5D"BREAK" FROM THE ROM ($D35D)
1358A0 D3LDY#$D3
135A20 3A DBJSRSTROUT
135D20 19 EDJSRINPRT" IN " AND THE ADDRESS
136020 FB DAJSRCRDO

PGMEND

PGMEND (END, AND NEW): PUT CHRGET BACK FROM THE ROM, MAKE THE PROGRAM SPACE AN EMPTY PROGRAM AND GO BACK TO THE INTERPRETER.

1363A2 17PGMENDLDX#$17PUT THE ROM'S CHRGET BACK AT $B1-$C8
1365BD 0B F1PGMEND1LDACHRGIMG,X
136895 B1STACHRGET,X
136ACADEX
136B10 F8BPLPGMEND1
136DA4 68LDYTXTTAB+1AN EMPTY PROGRAM: A ZERO BEFORE TXTTAB ...
136FA6 67LDXTXTTAB
1371D0 01BNEPGMEND2
137388DEY
1374CAPGMEND2DEX
137586 62STXRESULT
137784 63STYRESULT+1
1379A0 00LDY#$00
137B98TYA
137C91 62STA(RESULT),Y
137E18CLC
137F20 4B D6JSRSCRTCH... NEW, THEN BACK TO THE INTERPRETER
13824C 66 D5JMPRUNCLR
1385D0 2FPGMEND3BNEREADN2

INPEND

INPEND: THE END OF AN INPUT STATEMENT: ?EXTRA IGNORED IF THE LINE HAS MORE.

1387A5 71INPENDLDAINPOSTHE LINE USED UP?
1389C9 FECMP#$FE
138BF0 0BBEQINPEND1
138DA9 DFLDA#$DFNO: ?EXTRA IGNORED ($DCDF)
138FA0 DCLDY#$DC
139120 3A DBJSRSTROUT
1394A9 FELDA#$FE
139685 71STAINPOS
139860INPEND1RTS

GETNUM

GETNUM: GET X: A DIGIT KEY GIVES ITS VALUE, ANY OTHER KEY 0.

139920 53 D5GETNUMJSRINCHRTHE KEY
139CE9 30SBC#$30A DIGIT GIVES ITS VALUE ...
139E90 04BCCGETNUM1
13A0C9 0ACMP#$0A
13A290 02BCCGETNUM2
13A4A9 00GETNUM1LDA#$00... ANYTHING ELSE 0
13A64C 93 EBGETNUM2JMPFLOAT

READSTR

READ. THE DATA POINTER WALKS THE DATA ITEMS IN THE CODE: EACH IS A LENGTH BYTE AND ITS TEXT; $FF IS FOLLOWED BY THE ADDRESS OF THE NEXT DATA BLOCK (0 AFTER THE LAST: ERROR $2A, OUT OF DATA). A STRING ITEM IS USED IN PLACE; A NUMBER IS CONVERTED BY FIN (ERROR $10, SYNTAX, IF ANYTHING IS LEFT).

13A9A9 01READSTRLDA#$01A STRING ITEM ...
13AB2CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
13ACA9 00READNUMLDA#$00... OR A NUMBER
13AE48PHA
13AFA5 F7READN1LDADATPTR+1NO DATA LEFT: OUT OF DATA, ERROR $2A
13B1D0 05BNEREADN3
13B368PLA
13B4A2 2ALDX#$2A
13B6D0 4DREADN2BNEREADN7
13B8A0 00READN3LDY#$00THE ITEM'S LENGTH, OR $FF
13BAB1 F6LDA(DATPTR),Y
13BC85 16STAHDRFLAG
13BEC9 FFCMP#$FF
13C0D0 13BNEREADN5
13C2E6 F6INCDATPTR$FF: GO TO THE NEXT DATA BLOCK
13C4D0 02BNEREADN4
13C6E6 F7INCDATPTR+1
13C8B1 F6READN4LDA(DATPTR),Y
13CAAATAX
13CBC8INY
13CCB1 F6LDA(DATPTR),Y
13CE86 F6STXDATPTR
13D085 F7STADATPTR+1
13D288DEY
13D3F0 DABEQREADN1
13D5A6 F6READN5LDXDATPTRTHE ITEM
13D7A4 F7LDYDATPTR+1
13D968PLA
13DAF0 06BEQREADN6
13DC86 77STXSTRACCA STRING: USED WHERE IT IS
13DE84 78STYSTRACC+1
13E0D0 25BNEREADN8
13E286 B8READN6STXTXTPTRA NUMBER: TXTPTR = THE ITEM ...
13E484 B9STYTXTPTR+1
13E6A4 16LDYHDRFLAG... WITH A ZERO AFTER IT FOR NOW
13E8C8INY
13E9B1 F6LDA(DATPTR),Y
13EB48PHA
13ECA9 00LDA#$00
13EE91 F6STA(DATPTR),Y
13F020 B1 00JSRCHRGETFIN CONVERTS IT
13F320 4A ECJSRFIN
13F620 B7 00JSRCHRGOTANYTHING LEFT?
13F9AATAX
13FAA4 16LDYHDRFLAG
13FCC8INY
13FD68PLA
13FE91 F6STA(DATPTR),Y
14008ATXA
1401F0 04BEQREADN8
1403A2 10LDX#$10SYNTAX ERROR, $10
1405D0 0CREADN7BNEERREXIT
140738READN8SECTHE DATA POINTER PASSES THE ITEM
1408A5 F6LDADATPTR
140A65 16ADCHDRFLAG
140C85 F6STADATPTR
140E90 02BCCREADN9
1410E6 F7INCDATPTR+1
141260READN9RTS

ERREXIT

ERREXIT: EVERY LIBRARY ERROR ENDS HERE WITH THE ERROR NUMBER IN X. WITHOUT ONERR THE OBJECT ADDRESS OF THE CALL THAT FAILED BECOMES THE LINE NUMBER OF THE MESSAGE. X = $FF IS A CONTROL-C BREAK.

1413A5 D8ERREXITLDAERRFLGONERR ACTIVE?
1415F0 12BEQDEBUG1
1417E0 FFERREX1CPX#$FFX = $FF: A CONTROL-C BREAK
1419F0 03BEQERREX2
141B4C 12 D4JMPERRORERROR X
141EA9 03ERREX2LDA#$03
14204C 63 D8JMPSTOPCC

DEBUG

DEBUG: CALLED BEFORE EACH STATEMENT WITH THE RESUME/DEBUG OPTION. IT KEEPS THE STACK POINTER AND THE STATEMENT'S OBJECT ADDRESS, SO THAT AFTER AN ERROR RESUME CAN START THE STATEMENT AGAIN.

1423BADEBUGTSXTHE STACK POINTER BEFORE THE CALL
1424E8INX
1425E8INX
142686 F8STXREMSTK
14288ATXA
142985 16DEBUG1STAHDRFLAGA = 0 FROM ERREXIT
142B68PLACURLIN = RETURN ADDRESS - 2, THE OBJECT ADDRESS OF THE STATEMENT (OR OF THE CALL THAT FAILED)
142CA8TAY
142D38SEC
142EE9 02SBC#$02
143085 75STACURLIN
143268PLA
143348PHA
1434E9 00SBC#$00
143685 76STACURLIN+1
143898TYA
143948PHA
143AA5 16LDAHDRFLAGFROM ERREXIT: ON TO THE ERROR
143CF0 D9BEQERREX1
143E60RTS

PRNUM

STATEMENTS WITH ONE BYTE ARGUMENT: PR#, IN#, POKE (THE VALUE), WAIT (THE MASKS), TAB(, SPC(. THE REAL ENTRY CONVERTS FAC WITH AYINT; THE INTEGER ENTRY, 3 BYTES LATER, TAKES THE BYTE WITH CONINT (ERROR $35 PAST 255).

143F20 0C E1PRNUMJSRAYINT
144220 FE E6PRNUMIJSRCONINT2
14454C E8 F1JMPPRSLOTTHE ROM'S PR#
144820 0C E1INNUMJSRAYINT
144B20 FE E6INNUMIJSRCONINT2
144E4C E1 F1JMPINSLOT
145120 0C E1POKEJSRAYINT
145420 FE E6POKEIJSRCONINT2
14574C 7E E7JMPPOKE2
145A20 0C E1WAITJSRAYINT
145D20 FE E6WAITIJSRCONINT2
146086 85STXFORPNTWAIT WITH TWO ARGUMENTS: THE MASK, NO XOR VALUE
1462A2 00LDX#$00
1464F0 06BEQWAIT3I1
146620 0C E1WAIT3JSRAYINT
146920 FE E6WAIT3IJSRCONINT2
146C4C 93 E7WAIT3I1JMPWAIT2THE ROM'S WAIT
146F20 0C E1TABJSRAYINT
147220 FE E6TABIJSRCONINT2
1475CADEXTAB(N): N-1 - CURSOR COLUMN SPACES
14768ATXA
147738SEC
1478E5 24SBCCH
147A90 21BCCCOMMA2
147CAATAX
147DB0 08BCSSPCI2
147F20 0C E1SPCJSRAYINT
148220 FE E6SPCIJSRCONINT2
1485E8INXSPC(N): N SPACES
1486CASPCI1DEX
1487F0 14SPCI2BEQCOMMA2
148920 57 DBJSROUTSP
148CD0 F8BNESPCI1

COMMA

COMMA: A COMMA IN PRINT: TO THE NEXT 16-COLUMN FIELD, OR A NEW LINE PAST COLUMN 24.

148EA5 24COMMALDACHPAST COLUMN 24: A NEW LINE
1490C9 18CMP#$18
149290 03BCCCOMMA1
14944C FB DAJMPCRDO
149769 10COMMA1ADC#$10TO THE NEXT MULTIPLE OF 16
149929 F0AND#$F0
149B85 24STACH
149D60COMMA2RTS
149E20 0C E1VTABJSRAYINT
14A120 FE E6VTABIJSRCONINT2
14A44C 59 F2JMPVTAB2
14A720 0C E1HTABJSRAYINT
14AA20 FE E6HTABIJSRCONINT2
14AD4C EA F7JMPHTAB2

ONGOTO

ON ... GOTO AND ON ... GOSUB: THE CALL IS FOLLOWED BY THE NUMBER OF LINES AND THEIR ADDRESSES. AN INDEX OF 0 OR PAST THE LIST GOES ON AFTER THE LIST; OTHERWISE CONTROL GOES TO THE LINE, FOR GOSUB WITH A RETURN ADDRESS PAST THE LIST.

14B020 0C E1ONGOTOJSRAYINT
14B3A2 00ONGOTOILDX#$00X = 0: GOTO
14B5F0 05BEQONGOS1
14B720 0C E1ONGOSUBJSRAYINT
14BAA2 01ONGOSUBILDX#$01X = 1: GOSUB
14BC86 16ONGOS1STXHDRFLAG
14BE20 FE E6JSRCONINT2THE INDEX
14C168PLATHE RETURN ADDRESS POINTS AT THE COUNT - 1
14C285 50STALINNUM
14C468PLA
14C585 51STALINNUM+1
14C7A0 01LDY#$01THE COUNT
14C9B1 50LDA(LINNUM),Y
14CBA8TAY
14CC0AASLARETURN ADDRESS PAST THE LIST: COUNT*2+1
14CD38SEC
14CE65 50ADCLINNUM
14D0AATAX
14D1A5 51LDALINNUM+1
14D369 00ADC#$00
14D548PHA
14D68ATXA
14D748PHA
14D898TYAINDEX 0 OR ABOVE THE COUNT: CONTINUE AFTER THE LIST
14D9C5 A1CMPIACC+1
14DB90 04BCCONGOS2
14DDA5 A1LDAIACC+1
14DFD0 01BNEONGOS3
14E160ONGOS2RTS
14E2A6 16ONGOS3LDXHDRFLAGGOTO: DROP THE RETURN ADDRESS; GOSUB KEEPS IT
14E4D0 02BNEONGOS4
14E668PLA
14E768PLA
14E8A5 A1ONGOS4LDAIACC+1THE LINE'S ADDRESS - 1 ...
14EA0AASLA
14EBA8TAY
14ECB1 50LDA(LINNUM),Y
14EEAATAX
14EFC8INY
14F0B1 50LDA(LINNUM),Y
14F2A8TAY
14F38ATXA
14F4D0 01BNEONGOS5
14F688DEY
14F7CAONGOS5DEX
14F898TYA... PUSHED, AND RTS GOES THERE
14F948PHA
14FA8ATXA
14FB48PHA
14FC60RTS

LOGORI

AND, OR AND THE RELATIONS. THE CODE BEFORE THE CALL HAS SET THE FLAGS: FOR AND/OR BY LOADING ONE OPERAND, FOR A RELATION BY COMPARING (A = -1, 0, 1). THE RESULT IN FAC IS 1 (TRUE) OR 0 (FALSE). THE ENTRIES SHARE CODE BY FALLING THROUGH ONE ANOTHER.

14FD05 A1LOGORIORAIACC+1INTEGER OR: EITHER OPERAND NOT ZERO
14FF05 A0ORAIACC
1501D0 1ABNERELTRUE
1503F0 25LOGANDIBEQRELFALSEINTEGER AND: BOTH NOT ZERO
1505A5 A1LDAIACC+1
150705 A0ORAIACC
1509F0 1FBEQRELFALSE
150BD0 10LOGORBNERELTRUEREAL OR
150DA5 9DLDAFAC
150FD0 0CBNERELTRUE
1511F0 17LOGANDBEQRELFALSEREAL AND
1513A5 9DLDAFAC
1515F0 13BEQRELFALSE
1517D0 04RELNEBNERELTRUE
1519F0 0FRELGTBEQRELFALSE
151B30 0DRELGEBMIRELFALSE
151DA9 13RELTRUELDA#$13TRUE: FAC = 1.0 (THE ROM'S CONSTANT AT $E913)
151FA0 E9LDY#$E9
15214C F9 EAJMPMOVFM
1524D0 04RELEQBNERELFALSE
1526F0 F5RELLEBEQRELTRUE
152830 F3RELLTBMIRELTRUE
152AA9 00RELFALSELDA#$00FALSE: FAC = 0
152C85 9DSTAFAC
152E60RTS

STRGE

STRING RELATIONS ON THE PUSHED STRING (LEFT) AND THE LOADED STRING (RIGHT). STRLT AND STRGE SWAP THEM AND USE THE CODE OF STRGT AND STRLE. EQUAL OR NOT EQUAL COMPARE LENGTHS FIRST.

152FA9 01STRGELDA#$01STRGE: STRLE WITH THE STRINGS SWAPPED
15312CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
1532A9 00STRLTLDA#$00STRLT: STRGT WITH THE STRINGS SWAPPED
1534A4 77LDYSTRACC
1536A6 79LDXSTRPSH
153884 79STYSTRPSH
153A86 77STXSTRACC
153CA4 78LDYSTRACC+1
153EA6 7ALDXSTRPSH+1
154084 7ASTYSTRPSH+1
154286 78STXSTRACC+1
1544D0 05BNESTRGT1
1546A9 01STRLELDA#$01STRLE: NOT GREATER
15482CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
1549A9 00STRGTLDA#$00STRGT
154B48STRGT1PHA
154CA0 00LDY#$00COMPARE UP TO THE SHORTER LENGTH
154EB1 79LDA(STRPSH),Y
1550D1 77CMP(STRACC),Y
1552F0 0ABEQSTRGT2
155490 08BCCSTRGT2
1556B1 77LDA(STRACC),Y
1558AATAX
1559C8INY
155A84 66STYRESULT+4
155CD0 04BNESTRGT3
155E84 66STRGT2STYRESULT+4
1560C8INY
1561AATAX
15628ASTRGT3TXA
1563F0 0CBEQSTRGT5
1565B1 79STRGT4LDA(STRPSH),Y
1567D1 77CMP(STRACC),Y
156990 0ABCCSTRGT6
156BD0 10BNESTRGT8
156DC8INY
156ECADEX
156FD0 F4BNESTRGT4
1571A5 66STRGT5LDARESULT+4ALL EQUAL: THE LONGER STRING IS GREATER
1573D0 08BNESTRGT8
157568STRGT6PLA
1576D0 30BNESTREQ5
1578A9 00STRGT7LDA#$00
157A85 9DSTAFAC
157C60RTS
157D68STRGT8PLA
157ED0 F8BNESTRGT7
1580F0 26BEQSTREQ5
1582A9 00STREQLDA#$00STREQ
158448STREQ1PHA
1585A5 77LDASTRACCTHE SAME STRING: EQUAL
1587C5 79CMPSTRPSH
1589D0 06BNESTREQ2
158BA5 78LDASTRACC+1
158DC5 7ACMPSTRPSH+1
158FF0 14BEQSTREQ4
1591A0 00STREQ2LDY#$00THE SAME LENGTH ...
1593B1 77LDA(STRACC),Y
1595D1 79CMP(STRPSH),Y
1597D0 16BNESTREQ6
1599A8TAY
159AF0 09BEQSTREQ4
159CB1 77STREQ3LDA(STRACC),Y... AND THE SAME CHARACTERS
159ED1 79CMP(STRPSH),Y
15A0D0 0DBNESTREQ6
15A288DEY
15A3D0 F7BNESTREQ3
15A568STREQ4PLA
15A6D0 0ABNESTREQ7
15A8A9 13STREQ5LDA#$13
15AAA0 E9LDY#$E9
15AC4C F9 EAJMPMOVFM
15AF68STREQ6PLA
15B0D0 F6BNESTREQ5
15B2A9 00STREQ7LDA#$00
15B485 9DSTAFAC
15B660RTS
15B7A9 01STRNELDA#$01STRNE
15B9D0 C9BNESTREQ1

ROT

STATEMENTS AND ARGUMENTS THAT KEEP A BYTE FOR LATER: ROT=, SCALE=, THE SHAPE NUMBER, THE THIRD WAIT ARGUMENT, A BYTE FOR SCRN( OR MID$, THE HI-RES X (16 BITS, SAVEHX), HCOLOR=, THE LO-RES X (SAVEX) AND THE OTHER END OF HLIN/VLIN (SAVEY), SPEED=.

15BB20 0C E1ROTJSRAYINT
15BE20 FE E6ROTIJSRCONINT2
15C186 F9STXHGRROTROTATION
15C360RTS
15C420 0C E1SCALEJSRAYINT
15C720 FE E6SCALEIJSRCONINT2
15CA86 E7STXHGRSCALESCALE
15CC60RTS
15CD20 0C E1SVSHAPEJSRAYINT
15D020 FE E6SVSHAPEIJSRCONINT2
15D386 F0STXFIRSTSHAPE NUMBER
15D560RTS
15D620 0C E1SVARG3JSRAYINT
15D920 FE E6SVARG3IJSRCONINT2
15DC86 85STXFORPNTTHIRD ARGUMENT OF WAIT
15DE60RTS
15DF20 0C E1PUSHBYTEJSRAYINT
15E220 FE E6PUSHBYTIJSRCONINT2
15E586 10STXDIMFLGFIRST ARGUMENT OF SCRN( OR THE START OF MID$
15E760RTS
15E820 0C E1SAVEHXJSRAYINT
15EBA5 A0SAVEHXILDAIACCHI-RES X, 16 BITS, TO $50/$51
15ED85 51STALINNUM+1
15EFA5 A1LDAIACC+1
15F185 50STALINNUM
15F360RTS
15F420 0C E1HCOLORJSRAYINT
15F720 FE E6HCOLORIJSRCONINT2
15FA4C EC F6JMPHCOLOR2THE ROM'S HCOLOR=
15FD20 0C E1SAVEXJSRAYINT
160020 FE E6SAVEXIJSRCONINT2
160386 F0STXFIRSTLO-RES X
16054C 20 F2JMPPLOTCHK
160820 0C E1SAVEYJSRAYINT
160B20 FE E6SAVEYIJSRCONINT2
160E20 FD F1JSRLINCHKHLIN/VLIN: ORDER THE TWO ENDS
1611E4 F0CPXFIRST
1613B0 08BCSSAVEYI1
1615A5 F0LDAFIRST
161785 2CSTAH2
161985 2DSTAV2
161B86 F0STXFIRST
161D60SAVEYI1RTS
161E20 0C E1SPEEDJSRAYINT
162120 FE E6SPEEDIJSRCONINT2
16244C 65 F2JMPSPEED2

INPBEG

INPBEG: THE START OF AN INPUT STATEMENT: KEEP ITS OBJECT ADDRESS FOR ?REENTER.

162768INPBEGPLARETURN ADDRESS - 2: THE INPUT STATEMENT'S ADDRESS, FOR ?REENTER
1628AATAX
162938SEC
162AE9 02SBC#$02
162C85 50STALINNUM
162E68PLA
162F48PHA
1630E9 00SBC#$00
163285 51STALINNUM+1
16348ATXA
163548PHA
163660RTS

ONERR

ONERR: THE CALL IS FOLLOWED BY THE HANDLER'S ADDRESS, WHICH GOES INTO THE ONERR VECTOR AT $5B.

1637A2 80ONERRLDX#$80ONERR ON
163986 D8STXERRFLG
163B68PLARETURN PAST THE INLINE WORD
163C85 62STARESULT
163E18CLC
163F69 02ADC#$02
1641AATAX
164268PLA
164385 63STARESULT+1
164569 00ADC#$00
164748PHA
16488ATXA
164948PHA
164AA0 01LDY#$01THE HANDLER'S ADDRESS INTO THE ONERR VECTOR
164CB1 62LDA(RESULT),Y
164E85 5CSTAERRVEC+1
1650C8INY
1651B1 62LDA(RESULT),Y
165385 5DSTAERRVEC+2
165560RTS

RESUME

RESUME: BACK TO THE STATEMENT THAT FAILED (ITS DEBUG CALL) WITH THE STACK AS IT WAS.

1656A6 DFRESUMELDXERRSTKTHE STACK AS IT WAS BEFORE THE STATEMENT
16589ATXS
16596C DA 00JMP(ERRLIN)AND BACK TO THE STATEMENT'S DEBUG CALL

PUSHSUB

PUSHSUB: PUSH A SUBSCRIPT UNDER THE RETURN ADDRESS FOR THE ARRAY ROUTINE.

165C20 0C E1PUSHSUBJSRAYINT
165F68PUSHSUBIPLAPUSH IACC UNDER THE RETURN ADDRESS
1660AATAX
166168PLA
1662A8TAY
1663A5 A0LDAIACC
166548PHA
1666A5 A1LDAIACC+1
166848PHA
166998TYA
166A48PHA
166B8ATXA
166C48PHA
166D60RTS

FLOATI

FLOATI: FAC = IACC. THE JMP AT $58 COMES HERE. IMOVE: IARG = IACC.

166EA5 A0FLOATILDAIACC
1670A4 A1LDYIACC+1
16724C F2 E2JMPGIVAYF
1675A5 A0IMOVELDAIACC
167785 9ESTAIARG
1679A5 A1LDAIACC+1
167B85 9FSTAIARG+1
167D60RTS

IFORST1

LOOP LIMIT AND STEP, CALLED AFTER THE LOOP START. THEY PUT THE VALUES INTO THE FRAME UNDER THE CALLER'S RETURN ADDRESS; THE LIMIT ALSO PUSHES THE LOOP ADDRESS (THE RETURN ADDRESS OF THE STEP CALL) AND THE MARKER. INTEGER LOOPS: IFORLIM, IFORSTEP (IFORST1 = STEP 1); REAL LOOPS: FORLIM, FORSTEP (FORSTEP1 = STEP 1). THE R AND I ENTRIES CONVERT THE VALUE FIRST.

167EA2 01IFORST1LDX#$01IACC = 1
168086 A1STXIACC+1
1682CADEX
168386 A0STXIACC
1685F0 03BEQIFORSTEP
168720 0C E1IFORSTRJSRAYINT
168AA9 00IFORSTEPLDA#$00STEP: A = 0
168CF0 05BEQIFORL1
168E20 0C E1IFORLIMRJSRAYINT
1691A9 01IFORLIMLDA#$01LIMIT: A = 1
169385 16IFORL1STAHDRFLAG
169568PLATHE RETURN ADDRESS
169685 64STARESULT+2
169868PLA
169985 65STARESULT+3
169B48PHAPUT IT BACK TWICE
169CA5 64LDARESULT+2
169E48PHA
169F48PHA
16A0A5 A1LDAIACC+1AND THE INTEGER VALUE
16A248PHA
16A3A5 A0LDAIACC
16A548PHA
16A6A5 16LDAHDRFLAGTHE LIMIT ALSO PUSHES THE MARKER
16A8F0 30BEQFORPU1
16AAD0 38BNEFORPU2
16ACA0 E9FORSTEP1LDY#$E9STEP 1.0 (THE ROM'S CONSTANT AT $E913)
16AEA9 13LDA#$13
16B020 F9 EAJSRMOVFM
16B3D0 03BNEFORSTEP
16B520 58 00FORSTEPIJSRFLTVEC
16B8A9 00FORSTEPLDA#$00STEP: A = 0
16BAF0 05BEQFORPUSH
16BC20 58 00FORLIMIJSRFLTVEC
16BFA9 01FORLIMLDA#$01LIMIT: A = 1
16C185 16FORPUSHSTAHDRFLAG
16C3BATSXMAKE ROOM FOR 5 BYTES UNDER THE RETURN ADDRESS ...
16C4CADEX
16C5CADEX
16C6CADEX
16C768PLA
16C885 64STARESULT+2
16CA68PLA
16CB85 65STARESULT+3
16CD9ATXS
16CEE8INX
16CFA0 01LDY#$01... AND STORE FAC THERE
16D120 2B EBJSRMOVMF
16D4A5 16LDAHDRFLAG
16D6D0 0CBNEFORPU2
16D8A5 65LDARESULT+3THE LOOP ADDRESS AND THE MARKER
16DA48FORPU1PHA
16DBA5 64LDARESULT+2
16DD48PHA
16DEA5 B0LDAFORPOP+1
16E048PHA
16E1A5 AFLDAFORPOP
16E348PHA
16E4A5 65FORPU2LDARESULT+3RETURN
16E648PHA
16E7A5 64LDARESULT+2
16E948PHA
16EA60RTS

SCRN

SCRN(: THE FIRST ARGUMENT WAS PUSHED WITH PUSHBYTE. POS: THE CURSOR COLUMN. THE RESULT GOES TO IACC.

16EB20 0C E1SCRNJSRAYINT
16EE20 FE E6SCRNIJSRCONINT2
16F120 20 F2JSRPLOTCHKX: 0-47
16F48ATXA
16F5A6 10LDXDIMFLG
16F720 20 F2JSRPLOTCHKY: 0-47
16FAA4 10LDYDIMFLG
16FC20 71 F8JSRMONSCRNTHE ROM'S SCRN
16FF2CDFB$2CBIT ABSOLUTE: SKIPS THE NEXT 2 BYTES
1700A5 24POSLDACHPOS: THE CURSOR COLUMN
170285 A1POS1STAIACC+1IACC = A
1704A0 00LDY#$00
170684 A0STYIACC
1708A8TAY
170960RTS

PLOT

PLOT, HLIN, VLIN, PDL: THE LAST ARGUMENT; THE OTHERS WERE SAVED BEFORE. PDL GIVES ITS RESULT IN IACC.

170A20 0C E1PLOTJSRAYINT
170D20 FE E6PLOTIJSRCONINT2
171020 20 F2JSRPLOTCHK
17134C 28 F2JMPPLOT2
171620 0C E1HLINJSRAYINT
171920 FE E6HLINIJSRCONINT2
171C20 20 F2JSRPLOTCHK
171F4C 35 F2JMPHLIN2
172220 0C E1VLINJSRAYINT
172520 FE E6VLINIJSRCONINT2
17284C 44 F2JMPVLIN2
172B20 0C E1PDLJSRAYINT
172E20 FE E6PDLIJSRCONINT2
173120 1E FBJSRPREADREAD THE PADDLE
173498PDLI1TYA
173538SEC
1736B0 CABCSPOS1

CALLI

STATEMENTS AND FUNCTIONS WITH AN ADDRESS: CALL, POKE AND WAIT (THE ADDRESS, SVADDR), PEEK. GETADR TAKES ANY VALUE FROM -65535 TO 65535. THE INTEGER ENTRY, 3 BYTES EARLIER, FLOATS IACC FIRST, SO -16384 IS A GOOD ADDRESS.

173820 58 00CALLIJSRFLTVEC
173B4C D8 F1CALLJMPCALLROMTHE ROM'S CALL
173E20 58 00SVADDRIJSRFLTVEC
17414C 52 E7SVADDRJMPGETADRTHE ADDRESS TO $50/$51
174420 58 00PEEKIJSRFLTVEC
1747A5 51PEEKLDALINNUM+1PEEK KEEPS $50/$51 (THE POKE ADDRESS)
174948PHA
174AA5 50LDALINNUM
174C48PHA
174D20 52 E7JSRGETADR
1750A0 00LDY#$00THE BYTE
1752B1 50LDA(LINNUM),Y
1754A8TAY
175568PLA
175685 50STALINNUM
175868PLA
175985 51STALINNUM+1
175B38SEC
175CB0 D6BCSPDLI1

PRINTI

PRINT A NUMBER: PRINTI FLOATS IACC FIRST.

175E20 58 00PRINTIJSRFLTVEC
17614C 2E EDPRINTNJMPPRNTFACTHE ROM PRINTS FAC

DISPREAL

DISPREAL: THE REAL VARIABLE DISPATCHER: X = OPERATION, (Y,A) = THE VARIABLE. 0 LOAD FAC (AND SET THE FLAGS), 1 STORE FAC, 2 ADD, 3 VARIABLE MINUS FAC, 4 MULTIPLY, 5 COMPARE, 6 LOAD ARG, 7 VARIABLE DIVIDED BY FAC.

1764CADISPREALDEXOPERATION 0
176530 27BMIDISPR7
1767D0 04BNEDISPR11: STORE FAC ROUNDED AT (Y,X)
1769AATAX
176A4C 2B EBJMPMOVMF
176DCADISPR1DEX2 ADD
176EF0 18BEQDISPR5
1770CADEX3 SUBTRACT
1771F0 12BEQDISPR4
1773CADEX4 MULTIPLY
1774F0 0CBEQDISPR3
1776CADEX5 COMPARE
1777F0 06BEQDISPR2
1779CADEX6 LOAD ARG
177AF0 0FBEQDISPR6
177C4C 66 EAJMPFDIV7 DIVIDE
177F4C B2 EBDISPR2JMPFCOMP
17824C 7F E9DISPR3JMPFMULT
17854C A7 E7DISPR4JMPFSUB
17884C BE E7DISPR5JMPFADD
178B4C E3 E9DISPR6JMPCONUPK
178E20 F9 EADISPR7JSRMOVFMLOAD FAC; SIGNS COMPARED; A = THE EXPONENT (FLAGS SET)
1791A5 AALDAARGSIGN
17934C 59 DEJMPSGNEXIT

COPYRT

COPYRT: THE COPYRIGHT NOTICE.

1796C3 CF D0 D9 D2 C9 C7 C8COPYRTDFB$C3,$CF,$D0,$D9,$D2,$C9,$C7,$C8"COPYRIGH"
179ED4 A8 C3 A9 B1 B9 B8 B1DFB$D4,$A8,$C3,$A9,$B1,$B9,$B8,$B1"T(C)1981"
17A6AC CD C9 C3 D2 CF D3 CFDFB$AC,$CD,$C9,$C3,$D2,$CF,$D3,$CF",MICROSO"
17AEC6 D4DFB$C6,$D4"FT"

Equates

NameValueMeaning
CHARAC$0DTEMPORARY
ENDCHR$0ETEMPORARY
NUMDIM$0FTEMPORARY: DIMENSION COUNT
DIMFLG$10TEMPORARY
DATFIRST$12HEADER: ADDRESS OF THE FIRST DATA ITEM (2 BYTES)
HIGHEST$14HEADER: HIGHEST ADDRESS USED BY LIBRARY, PROGRAM OR VARIABLES (2)
HDRFLAG$16HEADER: COMMON FLAG; ALSO A TEMPORARY
HGRSHAPE$1AHI-RES SHAPE POINTER (2)
CH$24MONITOR: CURSOR COLUMN
H2$2CMONITOR: RIGHT END OF A LO-RES LINE
V2$2DMONITOR: BOTTOM END OF A LO-RES LINE
PROMPT$33MONITOR: PROMPT CHARACTER
A1L$3CMONITOR: A1 (2)
LINNUM$50ADDRESS TEMPORARY (2)
TEMPPT$52TEMPORARY
TPTR$55TEMPORARY POINTER (2)
FLTVEC$58JMP TO THE ROUTINE THAT FLOATS THE INTEGER ACCUMULATOR (3)
ERRVEC$5BJMP TO THE CODE HANDLING ONERR (3)
RESULT$62TEMPORARIES (5)
TXTTAB$67APPLESOFT START OF PROGRAM (2)
COMBEG$69START OF THE COMMON BLOCK - 1 (2)
NUMCEND$6BEND OF NUMERIC COMMON (2)
STRCEND$6DEND OF STRING COMMON (2)
FRETOP$6FBOTTOM OF STRINGS - 1 (2)
INPOS$71INPUT BUFFER POSITION ($FF NEW LINE, $FE USED UP)
MEMSIZ$73HIMEM (2)
CURLIN$75ADDRESS OF THE OBJECT CODE BEING EXECUTED (2)
STRACC$77STRING ACCUMULATOR: THE LOADED STRING (2)
STRPSH$79THE PUSHED STRING (2)
LOCBEG$7BSTART OF LOCAL VARIABLES - 1 (2)
LOCNEND$7DEND OF LOCAL NUMERIC VARIABLES (2)
LOCSEND$7FEND OF LOCAL STRING VARIABLES (2)
VARNAM$81TEMPORARY (2)
RETADR$83TEMPORARY: A SAVED RETURN ADDRESS (2)
FORPNT$85TEMPORARY POINTER (2)
TEMP3$8ATEMPORARIES (5)
TEMP1$93TEMPORARIES; ALSO THE COLLECTOR'S POINTERS (5)
FAC$9DFLOATING POINT ACCUMULATOR (EXPONENT, 4 MANTISSA BYTES, SIGN AT $A2)
IARG$9EINTEGER ARGUMENT (HIGH, LOW)
IACC$A0INTEGER ACCUMULATOR (HIGH, LOW)
FACSIGN$A2SIGN OF FAC
SERLEN$A3TEMPORARY
ARG$A5SECOND FLOATING POINT ACCUMULATOR (5, SIGN AT $AA)
ARGSIGN$AASIGN OF ARG
SGNCPR$ABTEMPORARY: SIGN COMPARISON, NEGATION COUNT
SERPNT$ADTEMPORARY (2)
FORPOP$AFADDRESS OF THE ROUTINE THAT POPS FOR ENTRIES (2)
CHRGET$B1APPLESOFT CHRGET (MODIFIED)
CHRGOT$B7CHRGOT, INSIDE CHRGET
TXTPTR$B8TEXT POINTER, INSIDE CHRGET (2)
CHRPAT$BAWHERE THE CHRGET PATCH GOES
ERRFLG$D8$80 WHEN ONERR IS ACTIVE
ELTYPE$D9TEMPORARY: ARRAY ELEMENT TYPE
ERRLIN$DAOBJECT ADDRESS OF THE STATEMENT THAT FAILED (2)
ERRPOS$DCTEMPORARY: ARRAY ELEMENT ADDRESS (2)
ERRSTK$DFSTACK POINTER BEFORE THE FAILED STATEMENT
HGRSCALE$E7HI-RES SCALE
SHAPETBL$E8ADDRESS OF THE SHAPE TABLE (2)
FIRST$F0TEMPORARY: LO-RES / SHAPE ARGUMENT
SPEEDZ$F1OUTPUT SPEED
TRCFLG$F2TRACE FLAG
TXTPSV$F4ONERR TEXT POINTER (2)
DATPTR$F6POINTER INTO THE DATA ITEMS (2)
REMSTK$F8STACK POINTER BEFORE THE STATEMENT
HGRROT$F9HI-RES ROTATION
ZPFF$FFLAST BYTE OF PAGE ZERO
STACK$0100THE 6502 STACK
INBUF$0200INPUT BUFFER
AMPER$03F5AMPERSAND VECTOR (3)
ERROR$D412ROM: REPORT ERROR X
INLIN$D52CROM: READ A LINE INTO THE INPUT BUFFER
INCHR$D553ROM: READ A KEY
RUNCLR$D566ROM: RUN, AFTER CLEARING VARIABLES
SCRTCH$D64BROM: NEW
STOPCC$D863ROM: CONTROL-C BREAK
LET2$DA65ROM: STORE FAC IN AN INTEGER VARIABLE (ROUND, RANGE CHECK)
CRDO$DAFBROM: PRINT A CARRIAGE RETURN
STROUT$DB3AROM: PRINT A STRING AT (Y,A)
OUTSP$DB57ROM: PRINT A SPACE
OUTQUES$DB5AROM: PRINT A QUESTION MARK
OUTDO$DB5CROM: PRINT THE CHARACTER IN A
REENTER$DB87ROM: ?REENTER (INSIDE INPERR)
SGNEXIT$DE59ROM: SAVE THE SIGN COMPARISON, RETURN THE FAC EXPONENT (SETS THE FLAGS)
INTVAR$DEE9ROM: LOAD THE INTEGER AT (VPNT) INTO FAC
AYINT$E10CROM: FAC TO A 16-BIT INTEGER IN FAC+3/FAC+4 ($A0/$A1)
GIVAYF$E2F2ROM: FLOAT THE INTEGER (A HIGH, Y LOW) INTO FAC
CONINT2$E6FEROM: INSIDE CONINT: FAC+3/4 TO A BYTE IN X (0-255)
GETADR$E752ROM: FAC TO A 16-BIT ADDRESS IN LINNUM
POKE2$E77EROM: INSIDE POKE: STORE X AT (LINNUM)
WAIT2$E793ROM: INSIDE WAIT
FSUB$E7A7ROM: FAC = (Y,A) - FAC
FADD$E7BEROM: FAC = (Y,A) + FAC
FADDT$E7C1ROM: FAC = ARG + FAC
FMULT$E97FROM: FAC = (Y,A) * FAC
FMULTT$E982ROM: FAC = ARG * FAC
CONUPK$E9E3ROM: LOAD ARG FROM (Y,A)
FDIV$EA66ROM: FAC = (Y,A) / FAC
FDIVT$EA69ROM: FAC = ARG / FAC
MOVFM$EAF9ROM: LOAD FAC FROM (Y,A)
MOV1F$EB21ROM: PACK FAC INTO TEMP1
MOVMF$EB2BROM: STORE FAC, ROUNDED, AT (Y,X)
MOVFA$EB53ROM: COPY ARG TO FAC
MOVAF$EB63ROM: COPY FAC, ROUNDED, TO ARG
SIGN$EB82ROM: SIGN OF FAC IN A
FLOAT$EB93ROM: FLOAT THE SIGNED BYTE IN A
FCOMP$EBB2ROM: COMPARE FAC WITH (Y,A): A = -1, 0 OR 1
FIN$EC4AROM: CONVERT THE NUMBER AT TXTPTR INTO FAC
INPRT$ED19ROM: PRINT " IN " AND THE LINE NUMBER
PRNTFAC$ED2EROM: PRINT FAC
FOUT$ED34ROM: CONVERT FAC TO A STRING AT $0100
NEGOP$EED0ROM: FAC = -FAC
CHRGIMG$F10BROM: THE COPY OF CHRGET THAT INITIALIZES $B1-$C8
CHRCONT$F114ROM: THE REST OF CHRGET AFTER THE SPACE CHECK
CALLROM$F1D8ROM: INSIDE CALL: JSR (LINNUM)
INSLOT$F1E1ROM: INSIDE IN#
PRSLOT$F1E8ROM: INSIDE PR#
LINCHK$F1FDROM: LO-RES COORDINATE CHECK
PLOTCHK$F220ROM: LO-RES COORDINATE CHECK (BELOW 48)
PLOT2$F228ROM: INSIDE PLOT
HLIN2$F235ROM: INSIDE HLIN
VLIN2$F244ROM: INSIDE VLIN
COLOR2$F252ROM: INSIDE COLOR=
VTAB2$F259ROM: INSIDE VTAB
SPEED2$F265ROM: INSIDE SPEED=
HPOSN$F411ROM: POSITION THE HI-RES CURSOR
HPLOT0$F457ROM: PLOT A HI-RES POINT
HGLIN$F53AROM: DRAW A HI-RES LINE
DRAW1$F605ROM: DRAW A SHAPE
XDRAW1$F661ROM: XDRAW A SHAPE
HCOLOR2$F6ECROM: INSIDE HCOLOR=
HTAB2$F7EAROM: INSIDE HTAB
MONSCRN$F871ROM: MONITOR SCRN
PREAD$FB1EROM: READ A PADDLE
CROUT1$FD8BROM: CLEAR TO END OF LINE, CARRIAGE RETURN