AS65 Assembler for R6502 [1.42]. Page 1 ------------------------------- tinybasic.asm -------------------------------- 2198 lines read, no errors in pass 1. ;***************************************************** ; ; Tom Pittman's 6502 Tiny Basic ; ; <>> ; ; Disassembly provided by Dwight Elvey (dwight.elvey@a ; I put out a request on the cctech mailing list. Dwi ; the only person who kept a functional copy of 6502 T ; ; Re-constructed source by Bob Applegate (bob@applegat ; the comments are from my perspective, so references ; refer to Bob. ; ;***************************************************** ; ; Began reconstruction of the source code 06/07/2004 f ; cross assembler. Converted to AS65 format 05/04/201 ; be with you!). ; ; Some of the comments were taken directly from the or ; Tiny Basic User Manual and/or the C version of the c ; Tom posted in May 2004 to his website. Others were ; personal additions. Comments might be wrong! If yo ; error, please fix it, expand the explanation, etc, a ; send updates to at least Tom. I'd appreciate them a ; ;***************************************************** ; ; These are used to control the target environment. Y ; exactly one of these options or else you won't get w ; ; The GENERIC option builds a generic 6502 TB located ; need to manually poke in your I/O routines. ; ; The KIM1 option builds for the KIM with the code loc ; It also builds a KIM-specific I/O function at addres ; 0000 = false equ 0 ffff = true equ ~false ; 0000 = GENERIC equ false ffff = KIM1 equ true ; ;***************************************************** ; ; ASCII Constants ; 0001 = CTRL_A equ $01 0002 = CTRL_B equ $02 0003 = CTRL_C equ $03 0004 = CTRL_D equ $04 0005 = CTRL_E equ $05 0006 = CTRL_F equ $06 0007 = CTRL_G equ $07 0008 = CTRL_H equ $08 0009 = CTRL_I equ $09 000a = CTRL_J equ $0a 000b = CTRL_K equ $0b 000c = CTRL_L equ $0c 000d = CTRL_M equ $0d AS65 Assembler for R6502 [1.42]. Page 2 ------------------------------- tinybasic.asm -------------------------------- 000e = CTRL_N equ $0e 000f = CTRL_O equ $0f 0010 = CTRL_P equ $10 0011 = CTRL_Q equ $11 0012 = CTRL_R equ $12 0013 = CTRL_S equ $13 0014 = CTRL_T equ $14 0015 = CTRL_U equ $15 0016 = CTRL_V equ $16 0017 = CTRL_W equ $17 0018 = CTRL_X equ $18 0019 = CTRL_Y equ $19 001a = CTRL_Z equ $1a ; ; More common names for common ASCII symbols ; 0000 = NUL equ $00 0007 = BELL equ $07 0008 = BS equ $08 000a = LF equ $0a 000d = CR equ $0d 007f = DEL equ $7f ; ;***************************************************** ; These are (some of) the IL opcodes. See Tom's C cod ; Basic Experimenter's book if you want to learn what ; 0000 = SX equ $00 0000 = SX0 equ $00 0001 = SX1 equ $01 0002 = SX2 equ $02 0003 = SX3 equ $03 0004 = SX4 equ $04 0005 = SX5 equ $05 0006 = SX6 equ $06 0007 = SX7 equ $07 0008 = NO equ $08 ;No-op 0009 = LB equ $09 000a = LN equ $0a 000b = DS equ $0b 000c = SP equ $0c 0010 = SB equ $10 0011 = RB equ $11 0012 = FV equ $12 0013 = SV equ $13 0014 = GS equ $14 0015 = RS equ $15 0016 = GO equ $16 0017 = NE equ $17 0018 = AD equ $18 0019 = SU equ $19 001a = MP equ $1a 001b = DV equ $1b 001c = CP equ $1c 001d = NX equ $1d 001f = LS equ $1f 0020 = PN equ $20 0021 = PQ equ $21 0022 = PT equ $22 0023 = NL equ $23 0024 = PC equ $24 0027 = GL equ $27 AS65 Assembler for R6502 [1.42]. Page 3 ------------------------------- tinybasic.asm -------------------------------- 002a = IL equ $2a 002b = MT equ $2b 002c = XQ equ $2c 002d = WS equ $2d 002e = US equ $2e 002f = RT equ $2f 0040 = BR equ $40 page AS65 Assembler for R6502 [1.42]. Page 4 ------------------------------- tinybasic.asm -------------------------------- ; ;***************************************************** ; Zero page storage. Tom seems to be fairly consistan ; the versions of TB, so I used the 1802 and C version ; and figure out what these variables do. There are s ; comments in here from what I discovered, what Tom do ; ; The lower bound is stored in locations 0020-0021 and ; upper bound is in locations 0022-0023. ; ;0020-0021 Lowest address of user program space ;0022-0023 Highest address of program space ;0024-0025 Program end + stack reserve ;0026-0027 Top of GOSUB stack ;0028-002F Interpreter parameters ;0030-007F Input line buffer & Computation stack ;0080-0081 Random Number Generator workspace ;00B6-00C7 Interpreter temporaries ;00B8 Start of User program (PROTO) ; bss 0020 = org $20 0020 = UserProg ds 2 ;Start of user program area 0022 = EndUser ds 2 ;End of user program/stack 0024 = EndProg ds 2 ;End of Basic program 0026 = GoStkTop ds 2 ;Top of Gosub stack 0028 = LineNumber ds 2 ;Current Basic line number 002a = IlPtr ds 2 ;pointer to current IL statement 002c = LinePtr ds 2 ;pointer to/in current user statement 002e = Source ds 2 ;source pointer for memory moves ; ; 0030-007F Input line buffer & Computation stac ; 0050 = EXPRESS_STACK_SIZE equ $50 0030 = ExpressStack ds EXPRESS_STACK_SIZE 0080 = ExpressStackTop equ * ; ; 0080-0081 Random Number Generator workspace ; 0080 = RandNum ds 2 ; ; Variables are pretty simple. The ASCII character (A ; is multiplied by two, giving an address in page zero ; contains the data. Because of this, you can't just ; move the Variables array to someplace else in memory ; ; 0082-0083 Variable "A" ; 0084-0085 Variable "B" ; ... ... ; 00B4-00B5 Variable "Z" ; 0082 = Variables ds 26*2 00b6 = org $b6 00b6 = Temp2 ds 2 ;$b6 - Another 16 bit temp 00b8 = Dest ds 2 ;destination for memory moves 00ba = ds 2 ;$ba - ??? 00bc = Temp1 ds 2 ;$bc temp 16 bit value for many routines ; ; If this is non-zero, then we're currently running a ; 00be = Running ds 1 AS65 Assembler for R6502 [1.42]. Page 5 ------------------------------- tinybasic.asm -------------------------------- ; ; This is the count of the number of characters on the ; line. Also used to count characters on user input. ; 00bf = CharCount ds 1 ; ; $C1/$C2 = expression stack pointer ; $C0 = bottom of expression stack ; 00c0 = org $c0 00c0 = ExStackBottm ds 1 00c1 = ExStackPtr ds 2 00c3 = pp_temp ds 1 ;another temp for peek/poke 00c4 = ds 2 00c6 = GosubStkPtr ds 2 ;Gosub stack pointer ; ;***************************************************** ; code if GENERIC org $2000 endif if KIM1 0200 = org $0200 endif ; ; This is the cold-start entry point. This should be ; bit of code executed when TB is started. ; 0200 : 4c8502 COLD jmp ColdEntry ; ; This is the warm-start entry point. ; 0203 : 4cbd02 WARM jmp WarmEntry ; ; Subroutine INCHAR is a jmp to a subroutine to read o ; character from the console/terminal. Subroutine OUT ; subroutine to type or display one ASCII character on ; console/terminal. In both cases the character is in ; accumulator, but the subroutine need not preserve th ; other registers. It is assumed that the character i ; simultaneously display each character as it is input ; the case, the jmp instruction in location 0106 may b ; JSR, so that each character input flows through the ; (which in this case must preserve A) before being fe ; Users with terminals using Baudot or some other non- ; perform the character conversion in the Input and Ou ; If your console is a CRT and/or you have no need to ; display extra pad characters with each Carriage Retu ; you may intercept these in the output routine to byp ; display. Each input prompt by TINY is followed by a ; character (ASCII DC1) with the sign bit set to 1 (al ; characters except rubout are output with the sign bi ; these are also readily detected and deleted from the ; Appendix C shows how to perform these tests. ; if GENERIC INCHAR jmp INCHAR OUTCHAR jmp OUTCHAR endif if KIM1 1e5a = GETCH equ $1e5a AS65 Assembler for R6502 [1.42]. Page 6 ------------------------------- tinybasic.asm -------------------------------- 1ea0 = OUTCH equ $1ea0 0206 : 4c5a1e INCHAR jmp GETCH 0209 : 4ca01e OUTCHAR jmp OUTCH endif ; ; A third subroutine provided by you is optional, and ; a means to test for the BREAK condition in your syst ; shows how this subroutine may be implemented for dif ; I/O devices. If you choose to omit this subroutine, ; that a BREAK condition never happens; to include it, ; locations 010C-010E with a jmp to your subroutine, w ; the break condition recorded in the Carry flag (1 = ; BREAK). The Break condition is used to interrupt pr ; or to prematurely terminate a LIST operation. Tiny ; Break condition any time in the LIST, or just before ; next statement in program execution. If a LIST stat ; within a program is aborted by the Break condition, ; condition must be held over to the next statement fe ; to stop program execution also. ; if GENERIC TSTBRK nop ;dummy function always returns "no break" clc ;default to no-break rts endif if KIM1 020c : 4c0001 TSTBRK jmp KIMBT endif ; ; Next are ASCII characters that the user can change t ; keys do what sort of editing functions. ; ; The Backspace code is located near the beginning of ; (location 010F), and is set by default to "left-arro ; Underline (shift-O on your Teletype). To change thi ; Standard Backspace code (or anything else you choose ; of location 010F may be changed to the desired code. ; Cancel code is located at memory address 0110, and i ; to the ASCII Cancel code (Control-X). ; 020f : 5f BACKKEY db "_" 0210 : 18 CANKEY db CTRL_X ; ; When Tiny ends a line (either input or output), it t ; two pad characters, a Linefeed, and one more pad cha ; character used is defined by the sign bit in locatio ; set by default to the "Rubout" or Delete code (hex F ; Bit 7 = 1) to minimize synchronization loss for bit- ; routines. The pad character may be changed to a Nul ; setting the sign of location 0111 to 0. The remaind ; defines the number of Pad characters between the CR ; More than two pad characters may be required if larg ; are to be loaded from tape (see comments on Tape Mod ; if GENERIC OutPad db $82 endif if KIM1 0211 : 00 OutPad db 0 endif ; ; TINY BASIC has a provision for suppressing output (i AS65 Assembler for R6502 [1.42]. Page 7 ------------------------------- tinybasic.asm -------------------------------- ; particular line prompts) when using paper tape for l ; or inputting data. This is activated by the occurre ; in the input stream (note that the user normally has ; a Linefeed since it is echoed in response to each CR ; all output (including program output) until the tape ; deactivated. This is especially useful in half-dupl ; such as that supported by Mikbug, since any output w ; with incoming tape data. The tape mode is turned of ; occurrence of an X-OFF character (ASCII DC3, or Cont ; input, by the termination of an executing program du ; after the execution of any statement or command whic ; the command mode. The tape mode may be disabled com ; replacing the contents of memory location 0112 with ; 0212 : 80 SupOut db $80 ; ; Memory location 0113 is of interest to those 6800 us ; extensive operating systems. Normally Tiny reserves ; stack space for use by the interpreter and I/O routi ; interrupts). Up to half of these may be used by Tin ; operation, leaving not more than 16 bytes on the sta ; your system allows nested interrupts or uses much mo ; twelve stack bytes for any purpose, additional space ; allocated on the stack. Location 0113 contains the ; space parameter used by Tiny, and is normally set to ; your system requires more reserve, this value should ; accordingly before attempting to run the interpreter ; 0213 : 04 StackReserve db $04 ; ; 0114 Subroutine to read one Byte ; from RAM to A (address in X) ; 0118 Subroutine to store A into RAM ; at address in X ; ; These are not directly used by the 6502 assembly lan ; of the IL interpreter, but do get used by BASIC prog ; implement things like PEEK and POKE. ; 0214 : 86c3 stx pp_temp 0216 : 9005 bcc BOB1 0218 : 86c3 stx pp_temp 021a : 91c2 sta (ExStackPtr+1),y 021c : 60 rts 021d : b1c2 BOB1 lda (ExStackPtr+1),y 021f : a000 ldy #0 0221 : 60 rts ; ; Original code from disassembly, to verify my code is ; ;2014 DB 86,C3, 90,05, 86,C3, 91,C2, 60, B1 ;201E ; 1 ;201E DB C2 ;201F ; 1 ;201F DB A0,00,60 ; ; ; This is the IL vector table. The 7th entry and on a ; indexed. The first 6 entries take a rather odd rout ; index is calculated in a different manner. ; 0222 : il_dispatch AS65 Assembler for R6502 [1.42]. Page 8 ------------------------------- tinybasic.asm -------------------------------- 0222 : 6203 dw L004 ; 2162 - BR ($40 - $5F) 0224 : 6403 dw L005 ; 2164 - BR ($60 - $7F) 0226 : d803 dw DoBC ; 21D8 - BC ($80 - $9F) 0228 : 0504 dw DoBV ; 2205 - BV ($A0 - $BF) 022a : 3304 dw DoBN ; 2233 - BN ($C0 - $DF) 022c : fd03 dw DoBE ; 21FD - BE ($E0 - $FF) ; 022e : 9f05 dw DoNoOp ; 239F - NO ($08) 0230 : 4209 dw DoLB ; 2742 - LB n ($09) 0232 : 3f09 dw DoLN ; 273F - LN ($0a) 0234 : 7a05 dw DoDS ; 237A - DS ($0b) 0236 : fc06 dw DoSP ; 24FC - SP ($0c) 0238 : 9505 dw PopExByte ; 2395 023a : 9f05 dw DoNoOp ; 239F - Undefined 023c : 9f05 dw DoNoOp ; 239F - Undefined 023e : bd08 dw DoSB ; 26BD - SB ($10) 0240 : c108 dw DoRB ; 26C1 - RB ($11) 0242 : 8a08 dw DoFV ; 268A - FV ($12) 0244 : 9b08 dw DoSV ; 269B - SV ($13) 0246 : e908 dw DoGS ; 26E9 - GS ($14) 0248 : 6105 dw DoRS ; 2361 - RS ($15) 024a : 5105 dw DoGO ; 2351 - GO ($16) 024c : 4108 dw DoNE ; 2641 - NE ($17) 024e : 5208 dw DoAD ; 2652 - AD ($18) 0250 : 4f08 dw DoSU ; 264F - SU ($19) 0252 : 6208 dw DoMP ; 2662 - MP ($1a) 0254 : e707 dw DoDV ; 25E7 - DV ($1b) 0256 : cd04 dw DoCP ; 22CD - CP ($1c) 0258 : 0605 dw DoNX ; 2306 - NX ($1d) 025a : 9f05 dw DoNoOp ; 239F - Undefined 025c : 1506 dw DoLS ; 2415 - LS ($1f) 025e : a705 dw DoPN ; 23A7 - PN ($20) 0260 : b704 dw DoPQ ; 22B7 - PQ ($21) 0262 : bf04 dw DoPT ; 22BF - PT ($22) 0264 : 8306 dw DoNL ; 2483 - NL ($23) 0266 : a104 dw DoPC ; 22A1 - PC ($24) 0268 : 9f05 dw DoNoOp ; 239F - Undefined 026a : 9f05 dw DoNoOp ; 239F - Undefined 026c : a806 dw DoGL ; 24A8 - GL ($27) 026e : 4f09 dw L037 ; 274F - Beats me... I don't see this opcode 0270 : 4d09 dw L038 ; 274D - Beats me... same excuse 0272 : 0707 dw DoIL ; 2507 - IL ($2a) 0274 : aa02 dw DoMT ; 20AA - MT ($2b) 0276 : 3705 dw DoXQ ; 2337 - XQ ($2c) 0278 : bd02 dw WarmEntry ; 20BD - WS ($2d) 027a : 1b09 dw DoUS ; 271B - US ($2e) 027c : b108 dw DoRT ; 26B1 - RT ($2f) ; 027e : 20415420 AtMsg db " AT " 0282 : 80 db $80 ; ; This contains the start of the IL code that the IL i ; is supposed to read/execute. By default, it points ; Tiny Basic IL at the end of this file. ; 0283 : 7009 IlStart dw DefaultIL ; ;***************************************************** ; This is the cold-start entry point. ; 0285 : ColdEntry 0285 : a900 lda #0 ;always force to page boundary... AS65 Assembler for R6502 [1.42]. Page 9 ------------------------------- tinybasic.asm -------------------------------- 0287 : 8520 sta UserProg 0289 : 8522 sta EndUser 028b : a90b lda #((codeend + $ff) >> 8) ;...one page past end of 028d : 8521 sta UserProg+1 028f : 8523 sta EndUser+1 ; ; Looks like an attempt to find the end of memory and ; Non-destructive to whatever might have been there. ; 0291 : a001 ldy #1 0293 : b122 L171 lda (EndUser),y 0295 : aa tax ;save for restoration 0296 : 49ff eor #$FF 0298 : 9122 sta (EndUser),y 029a : d122 cmp (EndUser),y 029c : 08 php 029d : 8a txa ;restore 029e : 9122 sta (EndUser),y 02a0 : e622 inc EndUser 02a2 : d002 bne L170 02a4 : e623 inc EndUser+1 02a6 : 28 L170 plp 02a7 : f0ea beq L171 02a9 : 88 dey ; ; Found first memory location that failed. ; 02aa : d8 DoMT cld 02ab : a520 lda UserProg 02ad : 6d1302 adc StackReserve 02b0 : 8524 sta EndProg 02b2 : 98 tya 02b3 : 6521 adc UserProg+1 02b5 : 8525 sta EndProg+1 02b7 : 98 tya 02b8 : 9120 sta (UserProg),y 02ba : c8 iny 02bb : 9120 sta (UserProg),y ; ;***************************************************** ; This is the warm-start entry point. ; 02bd : WarmEntry 02bd : a522 lda EndUser 02bf : 85c6 sta GosubStkPtr 02c1 : 8526 sta GoStkTop 02c3 : a523 lda EndUser+1 02c5 : 85c7 sta GosubStkPtr+1 02c7 : 8527 sta GoStkTop+1 02c9 : 208706 jsr CrLf 02cc : ad8302 L053: lda IlStart ;set pointer to default IL program 02cf : 852a sta IlPtr 02d1 : ad8402 lda IlStart+1 02d4 : 852b sta IlPtr+1 02d6 : a980 lda #(ExpressStackTop & $ff) 02d8 : 85c1 sta ExStackPtr 02da : a930 lda #(ExpressStack & $ff) 02dc : 85c0 sta ExStackBottm 02de : a200 ldx #(ExpressStackTop >> 8) ; ; Tricky... even though we're loading the high byte of ; address of ExStackTop, this logic assumes it is zero AS65 Assembler for R6502 [1.42]. Page 10 ------------------------------- tinybasic.asm -------------------------------- ; 02e0 : 86be stx Running ;not running right now 02e2 : 86c2 stx ExStackPtr+1 02e4 : ca dex 02e5 : 9a txs ; ; This is the main IL processing loop. Get the next I ; call the interpreter, then do it again. ; 02e6 : d8 IlLoop cld ;paranoid? 02e7 : 20f904 jsr GetIlByte ;get the next IL opcode 02ea : 20f202 jsr Interp ;interpret the opcode 02ed : 4ce602 jmp IlLoop ;...and do it again! ; ; Unknown data bytes. Can't find any reference to the ; Tom thinks they might have been a serial number. ; 02f0 : 8365 db $83, $65 ; ;***************************************************** ; This interprets the current IL opcode in A. This as ; which it should be from the call to GetIlByte. ; 02f2 : c930 Interp cmp #RT+1 ;Is it a simple opcode to handle? 02f4 : b07b bcs L057 ;Nope. Jump elsewhere. 02f6 : c908 cmp #SX7+1 ;Is it an SX opcode? 02f8 : 900c bcc DoSX ;Yes... handle differently 02fa : 0a asl a ;else, do a table lookup 02fb : aa tax ; ; Note to self... this actually looks up the pointer f ; table, but the base address of the lookup is before ; actual table. The opcode index is in X. Look up th ; then do an indirect call to the subroutine. ; 02fc : bd1f02 L066 lda il_dispatch-3,x ;pointer should be $201F 02ff : 48 pha 0300 : bd1e02 lda il_dispatch-4,x ;pointer should be $201E 0303 : 48 pha 0304 : 08 php 0305 : 40 rti ;Call the opcode handler ; ;***************************************************** ; Handler for the SX opcode. The opcode value is a nu ; which indicates which computation stack entry to swa ; of the stack. ; 0306 : 65c1 DoSX adc ExStackPtr 0308 : aa tax 0309 : b1c1 lda (ExStackPtr),y ;Get current byte at that offset 030b : 48 pha ;save for later 030c : b500 lda $00,x ;get current top of stack... 030e : 91c1 sta (ExStackPtr),y ;...save it back into stack 0310 : 68 pla 0311 : 9500 sta $00,x ;and save new top of stack value. 0313 : 60 rts ; ;***************************************************** ; Error handler ; 0314 : 208706 Error jsr CrLf ; 2487 0317 : a921 lda #'!' AS65 Assembler for R6502 [1.42]. Page 11 ------------------------------- tinybasic.asm -------------------------------- 0319 : 200902 jsr OUTCHAR ;print "!" to start error message ; ; Compute the offset into the IL area where the error ; IL gets an error, it's reported as the address in th ; counter where the errored instruction is located. ; 031c : a52a lda IlPtr 031e : 38 sec 031f : ed8302 sbc IlStart 0322 : aa tax 0323 : a52b lda IlPtr+1 0325 : ed8402 sbc IlStart+1 0328 : 20a005 jsr PrintPositive ;X = MSB, A = LSB - print address ; 032b : a5be lda Running ;are we running a program? 032d : f012 beq nolinnm ;nope, so don't print the line number ; ; Print the phrase " AT " followed by the current line ; 032f : a97e lda #(AtMsg & $ff) 0331 : 852a sta IlPtr 0333 : a902 lda #(AtMsg >> 8) 0335 : 852b sta IlPtr+1 0337 : 20a104 jsr DoPC ; 033a : a628 ldx LineNumber ;pick up the line number 033c : a529 lda LineNumber+1 033e : 20a005 jsr PrintPositive ;print line number 0341 : a907 nolinnm lda #BELL ;"Hey, BOZO, there's an error!" 0343 : 200902 jsr OUTCHAR 0346 : 208706 jsr CrLf 0349 : a526 L139 lda GoStkTop 034b : 85c6 sta GosubStkPtr 034d : a527 lda GoStkTop+1 034f : 85c7 sta GosubStkPtr+1 0351 : 4ccc02 jmp L053 ; 20CC ; ; Make sure we aren't about to underflow the expressio ; then return X bumped down one 16 bit value - ??? ; 0354 : a27c L146 ldx #(ExpressStackTop-4) 0356 : e4c1 L140 cpx ExStackPtr 0358 : 90ba L062 bcc Error 035a : a6c1 ldx ExStackPtr 035c : e6c1 inc ExStackPtr 035e : e6c1 inc ExStackPtr 0360 : 18 clc 0361 : 60 rts ; ; These are the entry points for the BR opcode handler ; first is for opcodes $40-$5F. The second is for opc ; from $60-$7F. Note that an opcode of $60 implies a ; branch of "0" which is illegal, and results in an er ; 0362 : c6bd L004 dec Temp1+1 0364 : a5bd L005 lda Temp1+1 0366 : f0ac beq Error ;0 is bad. Otherwise, fall into... ; ; This handles a Jump instruction. Load the new desti ; IL address and put into the IlPtr. ; AS65 Assembler for R6502 [1.42]. Page 12 ------------------------------- tinybasic.asm -------------------------------- 0368 : a5bc ProcJ lda Temp1 036a : 852a sta IlPtr 036c : a5bd lda Temp1+1 036e : 852b sta IlPtr+1 0370 : 60 rts ; ; Handle more complex IL opcodes ; 0371 : c940 L057 cmp #BR ;Start of BR instructions 0373 : b043 bcs L059 ;Value is >= $40 ; ; The opcode is between $31 and $3f inclusive ; 0375 : 48 pha 0376 : 20f904 jsr GetIlByte ;Get lower 8 bits of target offset 0379 : 6d8302 adc IlStart 037c : 85bc sta Temp1 037e : 68 pla 037f : 48 pha 0380 : 2907 and #$07 ;get upper 3 bits of target offset 0382 : 6d8402 adc IlStart+1 0385 : 85bd sta Temp1+1 ;Temp1 contains the target IL 0387 : 68 pla ; ; Now we have the opcode in A again. If bit 3 is set, ; is a J(ump) instruction. If not set, it's a JS (Jum ; 0388 : 2908 and #$08 038a : d0dc bne ProcJ ;it's a Jump. ; ; Process a JS opcode. The target address is already ; 038c : a5bc lda Temp1 ;Swap Temp1 with IlPtr 038e : a62a ldx IlPtr 0390 : 852a sta IlPtr 0392 : 86bc stx Temp1 0394 : a5bd lda Temp1+1 0396 : a62b ldx IlPtr+1 0398 : 852b sta IlPtr+1 039a : 86bd stx Temp1+1 ; ; Decrement the gosub stack pointer, then make sure we ; have room for this new entry. ; 039c : a5c6 L160 lda GosubStkPtr 039e : e901 sbc #1 03a0 : 85c6 sta GosubStkPtr 03a2 : b002 bcs L061 03a4 : c6c7 dec GosubStkPtr+1 03a6 : c524 L061 cmp EndProg 03a8 : a5c7 lda GosubStkPtr+1 03aa : e525 sbc EndProg+1 03ac : 90aa bcc L062 ;gosub stack overflow ; ; Save return address on the gosub stack. ; 03ae : a5bc lda Temp1 03b0 : 91c6 sta (GosubStkPtr),y 03b2 : c8 iny 03b3 : a5bd lda Temp1+1 03b5 : 91c6 sta (GosubStkPtr),y 03b7 : 60 rts AS65 Assembler for R6502 [1.42]. Page 13 ------------------------------- tinybasic.asm -------------------------------- ; ; Opcode is greater than $40 ; 03b8 : 48 L059 pha ;save opcode 03b9 : 4a lsr a ;move top nibble into bottom 03ba : 4a lsr a 03bb : 4a lsr a 03bc : 4a lsr a 03bd : 290e and #$0E ;only keep top three bits 03bf : aa tax ;this will be an index in jump table! ; ; Just a quick note about X now. It has a value of 2, ; or 14. Since the jump table really begins 4 bytes b ; we know that X can not contain a 2 or else the vecto ; That leaves 6 possible values, which are used to ind ; six entries of the jump table to get to the next par ; ; BTW, the next 13 lines of code (until the jmp L066) ; sense to me. Still need to think about this for a w ; what Tom is really doing here. It's setting up a re ; and is saving the address in Temp1, but the logic co ; 03c0 : 68 pla ;restore opcode 03c1 : c960 cmp #$60 03c3 : 291f and #$1F 03c5 : b002 bcs L064 ;branch if A >= $60 03c7 : 09e0 ora #$E0 03c9 : 18 L064 clc 03ca : f007 beq L065 ;branch if A >= $60 && bottom 5 bits all 0 03cc : 652a adc IlPtr 03ce : 85bc sta Temp1 03d0 : 98 tya 03d1 : 652b adc IlPtr+1 03d3 : 85bd L065 sta Temp1+1 03d5 : 4cfc02 jmp L066 ;use the first entries in the jump table ; ; BC handler. The ASCII character string in IL follo ; opcode is compared to the string beginning with the ; of the BASIC pointer, ignoring blanks in BASIC progr ; comparison continues until either a mismatch, or an ; with the most significant bit set to one. This is t ; the string in the IL, compared as a 7-bit character; ; BASIC pointer is positioned after the last matching ; BASIC program and the IL continues with the next ins ; sequence. Otherwise the BASIC pointer is not altere ; bits of the Branch opcode are added to the IL progra ; the address of the next IL instruction. If the stri ; and the branch offset is zero an error stop occurs. ; 03d8 : a52c DoBC lda LinePtr 03da : 85b8 sta Dest 03dc : a52d lda LinePtr+1 03de : 85b9 sta Dest+1 03e0 : 202504 L167 jsr L162 ; 2225 03e3 : 201404 jsr FetchByte ; 2214 03e6 : 512a eor (IlPtr),y 03e8 : aa tax 03e9 : 20f904 jsr GetIlByte ; 22F9 03ec : 8a txa 03ed : f0f1 beq L167 ; 21E0 03ef : 0a asl a 03f0 : f012 beq L168 ; 2204 AS65 Assembler for R6502 [1.42]. Page 14 ------------------------------- tinybasic.asm -------------------------------- 03f2 : a5b8 lda Dest 03f4 : 852c sta LinePtr 03f6 : a5b9 lda Dest+1 03f8 : 852d sta LinePtr+1 03fa : 4c6403 L163 jmp L005 ; 2164 ; ; Branch if Not Endline. If the next non-blank charac ; the BASIC pointer is a carriage return, the IL progr ; next instruction in sequence; otherwise the low five ; opcode (if not 0) are added to the IL program counte ; address of next IL instruction. In either case the ; is left pointing to the first non-blank character; t ; instruction will not pass over the carriage return, ; remain for testing by the NX instruction. As with t ; conditional branches, the branch may only advance th ; counter from 1 to 31 bytes; an offset of zero result ; stop. ; 03fd : 202504 DoBE jsr L162 ;get next non-space character 0400 : c90d cmp #CR 0402 : d0f6 bne L163 ;not eol, so take branch 0404 : 60 L168 rts ; ; Branch if Not Variable. If the next non-blank chara ; by the BASIC pointer is a capital letter, its ASCII ; and] pushed onto the expression stack and the IL pro ; next instruction in sequence, leaving the BASIC poin ; after the letter; if not a letter the branch is take ; pointer is left pointing to that character. An error ; if the next character is not a letter and the offset ; is zero, or on stack overflow. ; 0405 : 202504 DoBV jsr L162 ;Get next non-space character 0408 : c95b cmp #'Z'+1 040a : b0ee bcs L163 ;branch if not a variable 040c : c941 cmp #'A' 040e : 90ea bcc L163 ;branch if not a variable 0410 : 0a asl a 0411 : 208705 jsr PushExByte ;push index onto stack ; ; Another mini subroutine. This gets the character cu ; pointed to by LinePtr, increments LinePtr, returns w ; character in A, *and* Z set if the character is a CR ; is always clear upon return. ; 0414 : FetchByte 0414 : a000 ldy #0 0416 : b12c lda (LinePtr),y ;get character 0418 : e62c inc LinePtr ;move to next location 041a : d002 bne checkcr 041c : e62d inc LinePtr+1 041e : c90d checkcr cmp #CR ;end of the line? 0420 : 18 clc 0421 : 60 rts ; ;***************************************************** ; Call this to find the next non-space in (lineptr),y ; 0422 : 201404 L164 jsr FetchByte ; 2214 0425 : b12c L162 lda (LinePtr),y 0427 : c920 cmp #' ' 0429 : f0f7 beq L164 ; 2222 AS65 Assembler for R6502 [1.42]. Page 15 ------------------------------- tinybasic.asm -------------------------------- 042b : c93a cmp #':' ;0x3a 042d : 18 clc 042e : 1002 bpl L165 ; 2232 0430 : c930 cmp #'0' 0432 : 60 L165 rts ; ; Branch if Not a Number. If the next non-blank chara ; by the BASIC pointer is not a decimal digit, the low ; opcode are added to the IL program counter, or if ze ; stop occurs. If the next character is a digit, then ; decimal digits following it (ignoring blanks) are co ; 16-bit binary number which is pushed onto the expres ; either case the BASIC pointer is positioned at the n ; which is neither blank nor digit. Stack overflow wi ; error stop. ; 0433 : 202504 DoBN jsr L162 ; 2225 0436 : 90c2 bcc L163 ; 21FA 0438 : 84bc sty Temp1 043a : 84bd sty Temp1+1 043c : a5bc L166 lda Temp1 043e : a6bd ldx Temp1+1 0440 : 06bc asl Temp1 0442 : 26bd rol Temp1+1 0444 : 06bc asl Temp1 0446 : 26bd rol Temp1+1 0448 : 18 clc 0449 : 65bc adc Temp1 044b : 85bc sta Temp1 044d : 8a txa 044e : 65bd adc Temp1+1 0450 : 06bc asl Temp1 0452 : 2a rol a 0453 : 85bd sta Temp1+1 0455 : 201404 jsr FetchByte 0458 : 290f and #$0F 045a : 65bc adc Temp1 045c : 85bc sta Temp1 045e : 98 tya 045f : 65bd adc Temp1+1 0461 : 85bd sta Temp1+1 0463 : 202504 jsr L162 ; 2225 0466 : b0d4 bcs L166 ; 223C 0468 : 4c8005 jmp L117 ; 2380 ; ; Does something with line numbers ; 046b : 20fc06 L092 jsr DoSP ;Pop top 16 bit value from stack... 046e : a5bc lda Temp1 ;...and see if the value is zero. 0470 : 05bd ora Temp1+1 0472 : f048 beq L111 ;If zero, branch to error handler ; 0474 : a520 L158 lda UserProg ;Set starting location of program 0476 : 852c sta LinePtr 0478 : a521 lda UserProg+1 047a : 852d sta LinePtr+1 047c : 206d05 L114 jsr L087 ; 236D 047f : f012 beq L112 ; 2293 0481 : a528 lda LineNumber 0483 : c5bc cmp Temp1 0485 : a529 lda LineNumber+1 AS65 Assembler for R6502 [1.42]. Page 16 ------------------------------- tinybasic.asm -------------------------------- 0487 : e5bd sbc Temp1+1 0489 : b008 bcs L112 ; 2293 048b : 201404 L113 jsr FetchByte ; 2214 048e : d0fb bne L113 ; 228B 0490 : 4c7c04 jmp L114 ; 227C 0493 : a528 L112 lda LineNumber 0495 : 45bc eor Temp1 0497 : d004 bne L115 ; 229D 0499 : a529 lda LineNumber+1 049b : 45bd eor Temp1+1 049d : 60 L115 rts ; ; This is part of the PC handler. If the last byte pi ; positive (ie, not end of string), then jump here. T ; print routine, then returns. ; 049e : 20a604 L082 jsr InDoPc ; ;***************************************************** ; Handler for PC opcode. The literal string to print ; follows the opcode. Print characters until we find ; the MSB set. ; 04a1 : 20f904 DoPC jsr GetIlByte ;get byte to print 04a4 : 10f8 bpl L082 ;if not end, do weird stuff 04a6 : e6bf InDoPc inc CharCount 04a8 : 3003 bmi L081 04aa : 4c0902 jmp OUTCHAR ;let it return to caller 04ad : c6bf L081 dec CharCount 04af : 60 L126 rts 04b0 : c922 L127 cmp #'"' ;quote? 04b2 : f0fb beq L126 ; 22AF 04b4 : 20a604 jsr InDoPc ; 22A6 ; ;***************************************************** ; The ASCII characters beginning with the current posi ; pointer are printed on the console. The string to b ; terminated by quotation mark ("), and the BASIC poin ; the character following the terminal quote. An erro ; a carriage return is imbedded in the string. ; 04b7 : 201404 DoPQ jsr FetchByte ; 2214 04ba : d0f4 bne L127 ; 22B0 04bc : 4c1403 L111 jmp Error ; ;***************************************************** ; Print one or more spaces on the console, ending at t ; of eight character positions (from the left margin). ; 04bf : a920 DoPT lda #' ' 04c1 : 20a604 jsr InDoPc ;output a space 04c4 : a5bf lda CharCount 04c6 : 2987 and #$87 04c8 : 30e5 bmi L126 ; 22AF 04ca : d0f3 bne DoPT ; 22BF 04cc : 60 rts AS65 Assembler for R6502 [1.42]. Page 17 ------------------------------- tinybasic.asm -------------------------------- ; ;***************************************************** ; The number in the top two bytes of the expression st ; to (subtracted from) the number in the 4th and fifth ; stack, and the result is determined to be Greater, E ; The low three bits of the third byte mask a conditio ; IL program to test these conditions; if the result c ; one bit, the next byte of the IL code is skipped and ; The three bits correspond to the conditions as follo ; ; bit 0 Result is Less ; bit 1 Result is Equal ; bit 2 Result is Greater ; ; Whether the skip is taken or not, all five bytes are ; the stack. This is a signed (two's complement) compa ; any positive number is greater than any negative num ; conditions, such as greater-than-or-equal or unequal ; than-or-less-than), may be tested by forming the con ; byte of the sum of the respective bits. In particula ; of 7 will force an unconditional skip and a mask byt ; force no skip. The other 5 bits of the control byte ; Stack underflow results in an error stop. ; 04cd : a27b DoCP ldx #$7B 04cf : 205603 jsr L140 ; 2156 04d2 : e6c1 inc ExStackPtr 04d4 : e6c1 inc ExStackPtr 04d6 : e6c1 inc ExStackPtr 04d8 : 38 sec 04d9 : b503 lda $03,x 04db : f500 sbc $00,x 04dd : 9500 sta $00,x 04df : b504 lda $04,x 04e1 : f501 sbc $01,x 04e3 : 5004 bvc L141 ; 22E9 04e5 : 4980 eor #$80 04e7 : 0901 ora #$01 04e9 : 300a L141 bmi L142 ; 22F5 04eb : d004 bne L143 ; 22F1 04ed : 1500 ora $00,x 04ef : f002 beq L144 ; 22F3 04f1 : 5602 L143 lsr $02,x 04f3 : 5602 L144 lsr $02,x 04f5 : 5602 L142 lsr $02,x 04f7 : 900c bcc L145 ; 2305 ; ;***************************************************** ; Get the next byte in the IL code. Moves pointer to ; next byte, then sets flags to reflect the contents o ; the accumulator. Y is always set to 0 upon return. ; 04f9 : GetIlByte 04f9 : a000 ldy #0 04fb : b12a lda (IlPtr),y 04fd : e62a inc IlPtr 04ff : d002 bne L063 ; 2303 0501 : e62b inc IlPtr+1 0503 : 0900 L063 ora #0 ;Set flags 0505 : 60 L145 rts ; ;***************************************************** AS65 Assembler for R6502 [1.42]. Page 18 ------------------------------- tinybasic.asm -------------------------------- ; Advance to next line in the BASIC program, if in RUN ; restart the IL program if in the command mode. The r ; of the current line is ignored. In the Run mode if t ; another line it becomes current with the pointer pos ; its beginning. At this time, if the Break condition ; execution is aborted and the IL program is restarted ; printing an error message. Otherwise IL execution pr ; the saved IL address (see the XQ instruction). If th ; more BASIC statements in the program an error stop o ; 0506 : a5be DoNX lda Running 0508 : f028 beq L135 ;not running! 050a : 201404 L136 jsr FetchByte ; 2214 050d : d0fb bne L136 ; 230A 050f : 206d05 jsr L087 ; 236D 0512 : f01b beq L088 ; 232F 0514 : 204c05 L156 jsr MarkRun 0517 : 200c02 jsr TSTBRK ; 200C 051a : b009 bcs L138 ; 2325 051c : a5c4 lda $C4 051e : 852a sta IlPtr 0520 : a5c5 lda $C5 0522 : 852b sta IlPtr+1 0524 : 60 rts 0525 : ad8302 L138 lda IlStart 0528 : 852a sta IlPtr 052a : ad8402 lda IlStart+1 052d : 852b sta IlPtr+1 052f : 4c1403 L088 jmp Error ; 2114 0532 : 85bf L135 sta CharCount 0534 : 4c4903 jmp L139 ; 2149 ; ;***************************************************** ; Turns on RUN mode. This instruction also saves the c ; value of the IL program counter for use of the NX in ; and sets the BASIC pointer to the beginning of the B ; program space. An error stop occurs if there is no B ; program. This instruction must be executed at least ; the first execution of a NX instruction. ; 0537 : a520 DoXQ lda UserProg 0539 : 852c sta LinePtr 053b : a521 lda UserProg+1 053d : 852d sta LinePtr+1 053f : 206d05 jsr L087 ;See if there is a program or not 0542 : f0eb beq L088 ;no program, so it's an error 0544 : a52a lda IlPtr 0546 : 85c4 sta $C4 0548 : a52b lda IlPtr+1 054a : 85c5 sta $C5 ; ; This is a mini-subroutine to turn on the Running fla ; 054c : a901 MarkRun lda #$01 054e : 85be sta Running ;run flag? 0550 : 60 rts ; ;***************************************************** AS65 Assembler for R6502 [1.42]. Page 19 ------------------------------- tinybasic.asm -------------------------------- ; Make current the BASIC line whose line number is equ ; of the top two bytes in the expression stack. That ; bytes are popped off the computational stack, and th ; is searched until a matching line number is found. ; is then positioned at the beginning of that line and ; flag is turned on. Stack underflow and non-existent ; result in error stops. ; 0551 : 206b04 DoGO jsr L092 ; 226B 0554 : f0be beq L156 ; 2314 0556 : a5bc L159 lda Temp1 0558 : 8528 sta LineNumber 055a : a5bd lda Temp1+1 055c : 8529 sta LineNumber+1 055e : 4c1403 jmp Error ; 2114 ; ;***************************************************** ; Pop the top two bytes off the BASIC region of the co ; making them the current line number. Set the BASIC ; beginning of that line. Note that this is the line ; GOSUB which caused the line number to be saved. As ; opcode, it is essential that the IL region of the co ; empty. If the line number popped off the stack does ; to a line in the BASIC program an error stop occurs. ; also results from stack underflow. ; 0561 : 20fd08 DoRS jsr L045 ; 26FD 0564 : 20f408 jsr L157 ; 26F4 0567 : 207404 jsr L158 ; 2274 056a : d0ea bne L159 ; 2356 056c : 60 rts ; ;***************************************************** ; Get line numbers from somewhere, save them in LineNu ; then set/clear the Z flag if the number is zero or n ; On entry, it is assumed if Y = 0, then (LinePtr),Y w ; the binary line number of a line. ; 056d : 201404 L087 jsr FetchByte ;get next byte pointer to by (Line 0570 : 8528 sta LineNumber 0572 : 201404 jsr FetchByte 0575 : 8529 sta LineNumber+1 0577 : 0528 ora LineNumber 0579 : 60 rts ; ;***************************************************** ; Duplicate Top Number (two bytes) on Stack. An error ; if there are less than 2 bytes (1 int) on the expres ; the stack overflows. ; 057a : 20fc06 DoDS jsr DoSP ; 24FC 057d : 208005 jsr L117 ; 2380 0580 : a5bd L117 lda Temp1+1 0582 : 208705 L084 jsr PushExByte ; 2387 0585 : a5bc lda Temp1 ; ;***************************************************** ; Push the byte in A onto the expression stack. Decre ; stack pointer and make sure we haven't just overflow ; 0587 : PushExByte 0587 : a6c1 ldx ExStackPtr ;get current stack pointer... AS65 Assembler for R6502 [1.42]. Page 20 ------------------------------- tinybasic.asm -------------------------------- 0589 : ca dex ;...move down one entry... 058a : 9500 sta $00,x ;...save it onto stack... 058c : 86c1 stx ExStackPtr ;...and save the pointer 058e : e4c0 cpx ExStackBottm 0590 : d00d bne DoNoOp ;all done 0592 : 4c1403 L086 jmp Error ; ;***************************************************** ; Pop one byte off the top of the expression stack. G ; an error if the stack is underflowed. ; 0595 : PopExByte 0595 : a6c1 ldx ExStackPtr ;current stack pointer 0597 : e080 cpx #(ExpressStackTop & $ff) 0599 : 10f7 bpl L086 ;did we under-run the stack? 059b : b500 lda $00,x ;get value from stack 059d : e6c1 inc ExStackPtr ;point to next entry ; ; This rts is also a No-Op handler ; 059f : 60 DoNoOp rts ; ;***************************************************** ; The value in A & X are printed as an unsigned decima ; LSB, X is MSB. Since the sign is not printed, the v ; have the MSBit set. ; 05a0 : PrintPositive 05a0 : 85bd sta Temp1+1 05a2 : 86bc stx Temp1 05a4 : 4cb805 jmp L072 ; 23B8 ; ;***************************************************** ; The number represented by the top two bytes of the e ; is printed in decimal with leading zero suppression. ; negative, it is preceded by a minus sign and the mag ; printed. Stack underflow is possible. ; 05a7 : a6c1 DoPN ldx ExStackPtr 05a9 : b501 lda $01,x 05ab : 1008 bpl L128 ;branch if positive number ; ; Else, make two's complement and print the negative s ; 05ad : 204108 jsr DoNE ; 2641 05b0 : a92d lda #'-' 05b2 : 20a604 jsr InDoPc ;print minus sign 05b5 : 20fc06 L128 jsr DoSP ; 24FC ; ; Print the contents of Temp1 as a decimal number. ; 05b8 : a91f L072 lda #$1F 05ba : 85b8 sta Dest 05bc : 85ba sta $BA 05be : a92a lda #$2A 05c0 : 85b9 sta Dest+1 05c2 : 85bb sta $BB 05c4 : a6bc ldx Temp1 05c6 : a4bd ldy Temp1+1 05c8 : 38 sec 05c9 : e6b8 L073 inc Dest 05cb : 8a txa AS65 Assembler for R6502 [1.42]. Page 21 ------------------------------- tinybasic.asm -------------------------------- 05cc : e910 sbc #(10000 & $ff) 05ce : aa tax 05cf : 98 tya 05d0 : e927 sbc #(10000 >> 8) 05d2 : a8 tay 05d3 : b0f4 bcs L073 ; 23C9 05d5 : c6b9 L074 dec Dest+1 05d7 : 8a txa 05d8 : 69e8 adc #(1000 & $ff) 05da : aa tax 05db : 98 tya 05dc : 6903 adc #(1000 >> 8) 05de : a8 tay 05df : 90f4 bcc L074 ; 23D5 05e1 : 8a txa 05e2 : 38 L076 sec 05e3 : e6ba L075 inc $BA 05e5 : e964 sbc #100 05e7 : b0fa bcs L075 ; 23E3 05e9 : 88 dey 05ea : 10f6 bpl L076 ; 23E2 05ec : c6bb L077 dec $BB 05ee : 690a adc #10 05f0 : 90fa bcc L077 ; 23EC 05f2 : 0930 ora #$30 05f4 : 85bc sta Temp1 05f6 : a920 lda #$20 05f8 : 85bd sta Temp1+1 05fa : a2fb ldx #$FB 05fc : 86c3 L080 stx pp_temp 05fe : b5bd lda Temp1+1,x 0600 : 05bd ora Temp1+1 0602 : c920 cmp #$20 0604 : f009 beq L078 ; 240F 0606 : a030 ldy #'0' 0608 : 84bd sty Temp1+1 060a : 05bd ora Temp1+1 060c : 20a604 jsr InDoPc ; 22A6 060f : a6c3 L078 ldx pp_temp 0611 : e8 inx 0612 : d0e8 bne L080 ; 23FC 0614 : 60 rts ; ;***************************************************** ; The expression stack is assumed to have two 2-byte n ; number is the line number of the last line to be lis ; is the line number of the first line to be listed. ; line numbers do not exist in the program, the next a ; (i.e. with the next higher line number) is assumed i ; case. If the last line to be listed comes before th ; are listed. If Break condition comes true during a ; the remainder of the listing is aborted. Zero is no ; number, and an error stop occurs if either line numb ; is zero. The line number specifications are deleted ; 0615 : a52d DoLS lda LinePtr+1 ;save the pointer to the current l 0617 : 48 pha 0618 : a52c lda LinePtr 061a : 48 pha ; 061b : a520 lda UserProg ;set ptr to start of program 061d : 852c sta LinePtr AS65 Assembler for R6502 [1.42]. Page 22 ------------------------------- tinybasic.asm -------------------------------- 061f : a521 lda UserProg+1 0621 : 852d sta LinePtr+1 0623 : a524 lda EndProg 0625 : a625 ldx EndProg+1 0627 : 205b06 jsr L129 ;??? 062a : f003 beq L130 ;if Z set, expression stack empty! 062c : 205b06 jsr L129 ;??? ; ; See if LinePtr has passed the end of the user progra ; jump to L131 to finish, otherwise print the current ; 062f : a52c L130 lda LinePtr 0631 : 38 sec 0632 : e5b6 sbc Temp2 0634 : a52d lda LinePtr+1 0636 : e5b7 sbc Temp2+1 0638 : b042 bcs L131 ;past the end ; 063a : 206d05 jsr L087 ;Get line number of current line 063d : f03d beq L131 ;zero indicates end? ; ; Print the line number in decimal, followed by a spac ; 063f : a628 ldx LineNumber 0641 : a529 lda LineNumber+1 0643 : 20a005 jsr PrintPositive ;print line number in decimal 0646 : a920 lda #' ' 0648 : 20a604 L133 jsr InDoPc ;print a space 064b : 200c02 jsr TSTBRK ;did user hit BREAK? 064e : b02c bcs L131 ;yes! 0650 : 201404 jsr FetchByte ;get next char on line... 0653 : d0f3 bne L133 ;if Z not set, then not at EOL 0655 : 208306 jsr DoNL ;force a newline 0658 : 4c2f06 jmp L130 ;...and continue the loop. ; ; Used only by the DoLS routine. Called with the poin ; end of the current basic program in A (LSB) and X (M ; this exits, Temp2 points to the end of the program + ; 065b : 85b6 L129 sta Temp2 ;add one to the pointer, then... 065d : e6b6 inc Temp2 ;...save it into Temp2 065f : d001 bne L134 0661 : e8 inx 0662 : 86b7 L134 stx Temp2+1 ; ; See if expression stack is empty ; 0664 : a4c1 ldy ExStackPtr 0666 : c080 cpy #(ExpressStackTop & $ff) 0668 : f018 beq L125 ;branch if expression stack is empty ; 066a : 206b04 jsr L092 ; 226B 066d : a52c L093 lda LinePtr 066f : a62d ldx LinePtr+1 0671 : 38 sec 0672 : e902 sbc #$02 0674 : b001 bcs L109 ; 2477 0676 : ca dex 0677 : 852c L109 sta LinePtr 0679 : 4c4809 jmp StxLinePtr ; AS65 Assembler for R6502 [1.42]. Page 23 ------------------------------- tinybasic.asm -------------------------------- ; All done. Restore where we were, then return. ; 067c : 68 L131 pla 067d : 852c sta LinePtr 067f : 68 pla 0680 : 852d sta LinePtr+1 0682 : 60 L125 rts ; ;***************************************************** ; Output a carriage-return-linefeed sequence to the co ; 0683 : a5bf DoNL lda CharCount 0685 : 30fb bmi L125 ;only up to 127 characters ; ;***************************************************** ; Do a CR/LF. After sending the CR, see what characte ; use as a pad, then insert the appropriate number of ; sending the LF. ; 0687 : a90d CrLf lda #CR ;force a new line 0689 : 200902 jsr OUTCHAR 068c : ad1102 lda OutPad 068f : 297f and #$7F 0691 : 85bf sta CharCount ;save count for loop 0693 : f007 beq L067 ;if zero, don't pad at all 0695 : 206409 L069 jsr Padding 0698 : c6bf dec CharCount 069a : d0f9 bne L069 ;loop until we sent enough pads 069c : a90a L067 lda #LF ;output LF and then another pad 069e : 4c6109 jmp L070 ; ;***************************************************** ; Main routine to get a line of text from the user ; 06a1 : ac1202 L120 ldy SupOut 06a4 : 84bf L119 sty CharCount 06a6 : b00b bcs KeyLoop ; ;***************************************************** ; ASCII characters are accepted from console input to ; buffer. If the line length exceeds the available sp ; characters are ignored and bell characters are outpu ; terminated by a carriage return. On completing one ; the BASIC pointer is set to point to the first chara ; line buffer, and a carriage-return-linefeed sequence ; 06a8 : a930 DoGL lda #(ExpressStack & $ff) 06aa : 852c sta LinePtr 06ac : 85c0 sta ExStackBottm 06ae : 842d sty LinePtr+1 06b0 : 208005 jsr L117 06b3 : 4580 KeyLoop eor RandNum ;Feeding the random number? 06b5 : 8580 sta RandNum 06b7 : 200602 jsr INCHAR ;Get a key from the user 06ba : a000 ldy #00 06bc : a6c0 ldx ExStackBottm 06be : 297f and #$7F ;remove parity 06c0 : f0f1 beq KeyLoop ;loop if a nul byte ; 06c2 : c97f cmp #DEL 06c4 : f0ed beq KeyLoop 06c6 : c913 cmp #$13 AS65 Assembler for R6502 [1.42]. Page 24 ------------------------------- tinybasic.asm -------------------------------- 06c8 : f0da beq L119 06ca : c90a cmp #LF 06cc : f0d3 beq L120 06ce : cd1002 cmp CANKEY ;cancel line key? 06d1 : f009 beq GotCanc 06d3 : cd0f02 cmp BACKKEY ;backspace (delete) key? 06d6 : d00a bne NotBS ; ; User pressed the backspace key. If we're not alread ; of the stack, delete it. ; 06d8 : e030 cpx #(ExpressStack & $ff) 06da : d016 bne L123 ;string isn't empty, so continue 06dc : a62c GotCanc ldx LinePtr 06de : 84bf sty CharCount 06e0 : a90d lda #CR 06e2 : e4c1 NotBS cpx ExStackPtr 06e4 : 3008 bmi L124 06e6 : a907 lda #BELL 06e8 : 20a604 jsr InDoPc ;beep at the bozo 06eb : 4cb306 jmp KeyLoop ;get/process next key ; ; Save the key! Character is in A, index in X. Note ; index from the start of page zero, not from the star ; 06ee : 9500 L124 sta $00,x ;save it 06f0 : e8 inx ;move to next char 06f1 : e8 inx ;inc extra time for dex... ; ; Delete the current character ; 06f2 : ca L123 dex 06f3 : 86c0 stx ExStackBottm 06f5 : c90d cmp #CR 06f7 : d0ba bne KeyLoop ;not a CR, so go process next key ; ; We just saved a CR. Time to finish the line. ; 06f9 : 208306 jsr DoNL ; 2483 ; ;***************************************************** ; The top two bytes are removed from the expression st ; in Temp1. Underflow results in an error stop. ; 06fc : 209505 DoSP jsr PopExByte ; 2395 06ff : 85bc sta Temp1 0701 : 209505 jsr PopExByte ; 2395 0704 : 85bd sta Temp1+1 0706 : 60 rts ; ;***************************************************** ; Beginning with the current position of the BASIC poi ; continuing to the [end of it], the line is inserted ; program space; for a line number, the top two bytes ; stack are used. If this number matches a line alread ; it is deleted and the new one replaces it. If the n ; of only a carriage return, it is not inserted, thoug ; line with the same number will have been deleted. Th ; maintained in the program space sorted by line numbe ; line to be inserted is a different size than the old ; replaced, the remainder of the program is shifted ov ; or to close up the gap as necessary. If there is in AS65 Assembler for R6502 [1.42]. Page 25 ------------------------------- tinybasic.asm -------------------------------- ; to fit in the new line, the program space is unchang ; stop occurs (with the IL address decremented). A nor ; occurs on expression stack underflow or if the numbe ; is not a valid line number. After completing the ins ; program is restarted in the command mode. ; 0707 : 20d608 DoIL jsr L091 ; 26D6 070a : 206b04 jsr L092 ; 226B 070d : 08 php 070e : 206d06 jsr L093 ; 246D 0711 : 85b8 sta Dest 0713 : 86b9 stx Dest+1 0715 : a5bc lda Temp1 0717 : 85b6 sta Temp2 0719 : a5bd lda Temp1+1 071b : 85b7 sta Temp2+1 071d : a200 ldx #0 071f : 28 plp 0720 : d00b bne L094 ; 252D 0722 : 206d05 jsr L087 ; 236D 0725 : ca dex 0726 : ca dex 0727 : ca L095 dex 0728 : 201404 jsr FetchByte ; 2214 072b : d0fa bne L095 ; 2527 072d : 8428 L094 sty LineNumber 072f : 8429 sty LineNumber+1 0731 : 20d608 jsr L091 ; 26D6 0734 : a90d lda #CR 0736 : d12c cmp (LinePtr),y 0738 : f011 beq L096 ; 254B 073a : e8 inx 073b : e8 inx 073c : e8 inx 073d : e8 L097 inx 073e : c8 iny 073f : d12c cmp (LinePtr),y 0741 : d0fa bne L097 ; 253D 0743 : a5b6 lda Temp2 0745 : 8528 sta LineNumber 0747 : a5b7 lda Temp2+1 0749 : 8529 sta LineNumber+1 074b : a5b8 L096 lda Dest 074d : 85bc sta Temp1 074f : a5b9 lda Dest+1 0751 : 85bd sta Temp1+1 0753 : 18 clc 0754 : a000 ldy #0 0756 : 8a txa 0757 : f06e beq L098 ; 25C7 0759 : 1029 bpl L099 ; 2584 075b : 652e adc Source 075d : 85b8 sta Dest 075f : a52f lda Source+1 0761 : e900 sbc #0 0763 : 85b9 sta Dest+1 0765 : b12e L103 lda (Source),y 0767 : 91b8 sta (Dest),y 0769 : a62e ldx Source 076b : e424 cpx EndProg 076d : d006 bne L100 ; 2575 076f : a52f lda Source+1 AS65 Assembler for R6502 [1.42]. Page 26 ------------------------------- tinybasic.asm -------------------------------- 0771 : c525 cmp EndProg+1 0773 : f04a beq L101 ; 25BF 0775 : e8 L100 inx 0776 : 862e stx Source 0778 : d002 bne L102 ; 257C 077a : e62f inc Source+1 077c : e6b8 L102 inc Dest 077e : d0e5 bne L103 ; 2565 0780 : e6b9 inc Dest+1 0782 : d0e1 bne L103 ; 2565 0784 : 6524 L099 adc EndProg 0786 : 85b8 sta Dest 0788 : 852e sta Source 078a : 98 tya 078b : 6525 adc EndProg+1 078d : 85b9 sta Dest+1 078f : 852f sta Source+1 0791 : a52e lda Source 0793 : e5c6 sbc GosubStkPtr 0795 : a52f lda Source+1 0797 : e5c7 sbc GosubStkPtr+1 0799 : 9005 bcc L104 ; 25A0 079b : c62a dec IlPtr 079d : 4c1403 jmp Error ; 2114 07a0 : b124 L104 lda (EndProg),y 07a2 : 912e sta (Source),y 07a4 : a624 ldx EndProg 07a6 : d002 bne L105 ; 25AA 07a8 : c625 dec EndProg+1 07aa : c624 L105 dec EndProg 07ac : a62e ldx Source 07ae : d002 bne L106 ; 25B2 07b0 : c62f dec Source+1 07b2 : ca L106 dex 07b3 : 862e stx Source 07b5 : e4bc cpx Temp1 07b7 : d0e7 bne L104 ; 25A0 07b9 : a62f ldx Source+1 07bb : e4bd cpx Temp1+1 07bd : d0e1 bne L104 ; 25A0 07bf : a5b8 L101 lda Dest 07c1 : 8524 sta EndProg 07c3 : a5b9 lda Dest+1 07c5 : 8525 sta EndProg+1 07c7 : a528 L098 lda LineNumber 07c9 : 0529 ora LineNumber+1 07cb : f017 beq L107 ; 25E4 07cd : a528 lda LineNumber 07cf : 91bc sta (Temp1),y 07d1 : c8 iny 07d2 : a529 lda LineNumber+1 07d4 : 91bc sta (Temp1),y 07d6 : c8 L108 iny 07d7 : 84b6 sty Temp2 07d9 : 201404 jsr FetchByte ; 2214 07dc : 08 php 07dd : a4b6 ldy Temp2 07df : 91bc sta (Temp1),y 07e1 : 28 plp 07e2 : d0f2 bne L108 ; 25D6 07e4 : 4ccc02 L107 jmp L053 ; 20CC AS65 Assembler for R6502 [1.42]. Page 27 ------------------------------- tinybasic.asm -------------------------------- ; ;***************************************************** ; Divide the top two items on the stack. ; 07e7 : 205403 DoDV jsr L146 ; 2154 07ea : b503 lda $03,x 07ec : 2980 and #$80 07ee : f002 beq L147 ; 25F2 07f0 : a9ff lda #$FF 07f2 : 85bc L147 sta Temp1 07f4 : 85bd sta Temp1+1 07f6 : 48 pha 07f7 : 7502 adc $02,x 07f9 : 9502 sta $02,x 07fb : 68 pla 07fc : 48 pha 07fd : 7503 adc $03,x 07ff : 9503 sta $03,x 0801 : 68 pla 0802 : 5501 eor $01,x 0804 : 85bb sta $BB 0806 : 1003 bpl L148 ; 260B 0808 : 204308 jsr L149 ; 2643 080b : a011 L148 ldy #$11 080d : b500 lda $00,x ;divide by zero check? 080f : 1501 ora $01,x 0811 : d003 bne L150 0813 : 4c1403 jmp Error ;divide by zero 0816 : 38 L150 sec 0817 : a5bc lda Temp1 0819 : f500 sbc $00,x 081b : 48 pha 081c : a5bd lda Temp1+1 081e : f501 sbc $01,x 0820 : 48 pha 0821 : 45bd eor Temp1+1 0823 : 300a bmi L151 ; 262F 0825 : 68 pla 0826 : 85bd sta Temp1+1 0828 : 68 pla 0829 : 85bc sta Temp1 082b : 38 sec 082c : 4c3208 jmp L152 ; 2632 ; 082f : 68 L151 pla 0830 : 68 pla 0831 : 18 clc 0832 : 3602 L152 rol $02,x 0834 : 3603 rol $03,x 0836 : 26bc rol Temp1 0838 : 26bd rol Temp1+1 083a : 88 dey 083b : d0d9 bne L150 ; 2616 083d : a5bb lda $BB 083f : 100d bpl L153 ; 264E ; ;***************************************************** ; Do the NE opcode. Negate the top item on the stack. ; Clobbers A and X. ; 0841 : a6c1 DoNE ldx ExStackPtr 0843 : 38 L149 sec AS65 Assembler for R6502 [1.42]. Page 28 ------------------------------- tinybasic.asm -------------------------------- 0844 : 98 tya 0845 : f500 sbc $00,x 0847 : 9500 sta $00,x 0849 : 98 tya 084a : f501 sbc $01,x 084c : 9501 sta $01,x 084e : 60 L153 rts ; ;***************************************************** ; Tricky and clever re-use of the add logic. The subt ; negates the top item on the expression stack, then f ; DoAD subroutine which adds the top two items on the ; 084f : 204108 DoSU jsr DoNE ;make TOS negative 0852 : 205403 DoAD jsr L146 ;get index to TOS 0855 : b500 lda $00,x 0857 : 7502 adc $02,x 0859 : 9502 sta $02,x 085b : b501 lda $01,x 085d : 7503 adc $03,x 085f : 9503 sta $03,x 0861 : 60 rts ; ;***************************************************** ; Multiply the top two items on the stack. ; 0862 : 205403 DoMP jsr L146 ; 2154 0865 : a010 ldy #$10 0867 : b502 lda $02,x 0869 : 85bc sta Temp1 086b : b503 lda $03,x 086d : 85bd sta Temp1+1 086f : 1602 L155 asl $02,x 0871 : 3603 rol $03,x 0873 : 26bc rol Temp1 0875 : 26bd rol Temp1+1 0877 : 900d bcc L154 ; 2686 0879 : 18 clc 087a : b502 lda $02,x 087c : 7500 adc $00,x 087e : 9502 sta $02,x 0880 : b503 lda $03,x 0882 : 7501 adc $01,x 0884 : 9503 sta $03,x 0886 : 88 L154 dey 0887 : d0e6 bne L155 ; 266F 0889 : 60 rts ; ;***************************************************** ; The top byte of the computational stack is used to i ; It is replaced by the two bytes fetched. Error stop ; stack overflow or underflow. ; 088a : 209505 DoFV jsr PopExByte ; 2395 088d : aa tax 088e : b500 lda $00,x 0890 : b401 ldy $01,x 0892 : c6c1 dec ExStackPtr 0894 : a6c1 ldx ExStackPtr 0896 : 9400 sty $00,x 0898 : 4c8705 jmp PushExByte ; 2387 ; AS65 Assembler for R6502 [1.42]. Page 29 ------------------------------- tinybasic.asm -------------------------------- ;***************************************************** ; The top two bytes of the computational stack are sto ; at the Page 00 address specified by the third byte o ; three bytes are deleted from the stack. Underflow r ; error stop. ; 089b : a27d DoSV ldx #$7D 089d : 205603 jsr L140 ; 2156 08a0 : b501 lda $01,x 08a2 : 48 pha 08a3 : b500 lda $00,x 08a5 : 48 pha 08a6 : 209505 jsr PopExByte ; 2395 08a9 : aa tax 08aa : 68 pla 08ab : 9500 sta $00,x 08ad : 68 pla 08ae : 9501 sta $01,x 08b0 : 60 rts ; ;***************************************************** ; The IL control stack is popped to give the address o ; instruction. An error stop occurs if the entire cont ; BASIC) is empty. ; 08b1 : 20fd08 DoRT jsr L045 ; 26FD 08b4 : a5bc lda Temp1 08b6 : 852a sta IlPtr 08b8 : a5bd lda Temp1+1 08ba : 852b sta IlPtr+1 08bc : 60 rts ; ;***************************************************** ; If BASIC pointer is pointing into the input line buf ; to the Saved Pointer; otherwise the two pointers are ; 08bd : a22c DoSB ldx #$2C 08bf : d002 bne L161 ; 26C3 08c1 : a22e DoRB ldx #Source 08c3 : b500 L161 lda $00,x 08c5 : c980 cmp #$80 08c7 : b00d bcs L091 ; 26D6 08c9 : b501 lda $01,x 08cb : d009 bne L091 ; 26D6 08cd : a52c lda LinePtr 08cf : 852e sta Source 08d1 : a52d lda LinePtr+1 08d3 : 852f sta Source+1 08d5 : 60 rts 08d6 : a52c L091 lda LinePtr 08d8 : a42e ldy Source 08da : 842c sty LinePtr 08dc : 852e sta Source 08de : a52d lda LinePtr+1 08e0 : a42f ldy Source+1 08e2 : 842d sty LinePtr+1 08e4 : 852f sta Source+1 08e6 : a000 ldy #0 08e8 : 60 rts ; ;***************************************************** AS65 Assembler for R6502 [1.42]. Page 30 ------------------------------- tinybasic.asm -------------------------------- ; The current BASIC line number is pushed onto the BAS ; control stack. It is essential that the IL stack be ; work properly but no check is made for that conditio ; occurs on stack overflow. ; 08e9 : a528 DoGS lda LineNumber 08eb : 85bc sta Temp1 08ed : a529 lda LineNumber+1 08ef : 85bd sta Temp1+1 08f1 : 209c03 jsr L160 ; 219C 08f4 : a5c6 L157 lda GosubStkPtr 08f6 : 8526 sta GoStkTop 08f8 : a5c7 lda GosubStkPtr+1 08fa : 8527 sta GoStkTop+1 08fc : 60 L048 rts 08fd : b1c6 L045 lda (GosubStkPtr),y 08ff : 85bc sta Temp1 0901 : 200809 jsr L046 ; 2708 0904 : b1c6 lda (GosubStkPtr),y 0906 : 85bd sta Temp1+1 0908 : e6c6 L046 inc GosubStkPtr 090a : d002 bne L047 ; 270E 090c : e6c7 inc GosubStkPtr+1 090e : a522 L047 lda EndUser 0910 : c5c6 cmp GosubStkPtr 0912 : a523 lda EndUser+1 0914 : e5c7 sbc GosubStkPtr+1 0916 : b0e4 bcs L048 ; 26FC 0918 : 4c1403 jmp Error ; 2114 ; ;***************************************************** ; The top six bytes of the expression stack contain th ; the following interpretations: The top number is loa ; (or A and B) register; the next number is loaded int ; Index register; the third number is interpreted as t ; machine language subroutine to be called. These six ; expression stack are replaced with the 16-bit result ; subroutine. Stack underflow results in an error stop ; 091b : 202409 DoUS jsr L083 ; 2724 091e : 85bc sta Temp1 0920 : 98 tya 0921 : 4c8205 jmp L084 ; 2382 0924 : 20fc06 L083 jsr DoSP ; 24FC 0927 : a5bc lda Temp1 0929 : 85b6 sta Temp2 092b : 20fc06 jsr DoSP ; 24FC 092e : a5bd lda Temp1+1 0930 : 85b7 sta Temp2+1 0932 : a4bc ldy Temp1 0934 : 20fc06 jsr DoSP ; 24FC 0937 : a6b7 ldx Temp2+1 0939 : a5b6 lda Temp2 093b : 18 clc 093c : 6cbc00 jmp ($00BC) ; ;***************************************************** ; This handles the LN opcode. Push the following 16 b ; the expression stack. Pretty tricky... call DoLB to ; byte, then fall into DoLB to do the second! ; AS65 Assembler for R6502 [1.42]. Page 31 ------------------------------- tinybasic.asm -------------------------------- 093f : 204209 DoLN jsr DoLB ;call DoLB to push one byte ; ;***************************************************** ; LB handler... next byte gets pushed onto the express ; 0942 : 20f904 DoLB jsr GetIlByte ;get the byte... 0945 : 4c8705 jmp PushExByte ;...then push it. ; ; Store X in LinePtr+1, then compare it to 0. Returns ; X is now zero, else Z clear. ; 0948 : StxLinePtr 0948 : 862d stx LinePtr+1 094a : e000 cpx #0 094c : 60 rts ; ;***************************************************** ; These routines appear to process opcodes that I can' ; definition of in the C version of Tiny Basic. ; 094d : a002 L038 ldy #$02 ;start of user program + 2? 094f : 84bc L037 sty Temp1 0951 : a029 ldy #$29 ;start of user program? 0953 : 84bd sty Temp1+1 0955 : a000 ldy #$00 0957 : b1bc lda (Temp1),y ;pick up first char in program 0959 : c908 cmp #$08 ;see if it's a backspace??? 095b : d003 bne L116 ; 2760 ;if not, just exit??? 095d : 4c6803 jmp ProcJ ; 2168 0960 : 60 L116 rts ; ;***************************************************** ; Print the character in A, then fall into Padding and ; pad character. ; 0961 : 200902 L070 jsr OUTCHAR ; ;***************************************************** ; Based on the MSB of OutPad, determine whether to sen ; $FF or a single $00 as pad characters. ; 0964 : a9ff Padding lda #$FF ;assume $ff as the default 0966 : 2c1102 bit OutPad 0969 : 3002 bmi PadOut ;Yep, use the $ff 096b : a900 lda #$00 ;else, use $00 096d : 4c0902 PadOut jmp OUTCHAR ;print it! ; ;***************************************************** ; The IL code for TB. Need to pull the more detailed ; Tom's web site, but this works for now. ; 0970 : DefaultIL if 1 ; ; This was from the original disassembly I got for the ; The IL code on Tom's web page has some minor fixes, ; instead. This is just here in case we ever need it. ; 0970 : 243a912710e159.. db $24,$3A,$91,$27,$10,$E1,$59,$C5,$2A,$56,$10,$11,$2 0980 : d4a080bd30bce0.. db $D4,$A0,$80,$BD,$30,$BC,$E0,$13,$1D,$94,$47,$CF,$8 0990 : bce01011168053.. db $BC,$E0,$10,$11,$16,$80,$53,$55,$C2,$30,$BC,$E0,$1 09a0 : d283494ed4e571.. db $D2,$83,$49,$4E,$D4,$E5,$71,$88,$BB,$E1,$1D,$8F,$A AS65 Assembler for R6502 [1.42]. Page 32 ------------------------------- tinybasic.asm -------------------------------- 09b0 : 83ac225583ba24.. db $83,$AC,$22,$55,$83,$BA,$24,$93,$E0,$23,$1D,$30,$B 09c0 : 49c630bc313430.. db $49,$C6,$30,$BC,$31,$34,$30,$BC,$84,$54,$48,$45,$C 09d0 : 0d9a494e5055d4.. db $0D,$9A,$49,$4E,$50,$55,$D4,$A0,$10,$E7,$24,$3F,$2 09e0 : 5981ac30bc1311.. db $59,$81,$AC,$30,$BC,$13,$11,$82,$AC,$4D,$E0,$1D,$8 09f0 : 5552cee0151d85.. db $55,$52,$CE,$E0,$15,$1D,$85,$45,$4E,$C4,$E0,$2D,$9 0a00 : d4ec2400000000.. db $D4,$EC,$24,$00,$00,$00,$00,$0A,$80,$1F,$24,$93,$2 0a10 : e15080ac598552.. db $E1,$50,$80,$AC,$59,$85,$52,$55,$CE,$38,$0A,$86,$4 0a20 : d22b845245cd1d.. db $D2,$2B,$84,$52,$45,$CD,$1D,$A0,$80,$BD,$38,$14,$8 0a30 : 176481ab30d385.. db $17,$64,$81,$AB,$30,$D3,$85,$AB,$30,$D3,$18,$5A,$8 0a40 : 19542f30e285aa.. db $19,$54,$2F,$30,$E2,$85,$AA,$30,$E2,$1A,$5A,$85,$A 0a50 : 542f98524ec40a.. db $54,$2F,$98,$52,$4E,$C4,$0A,$80,$80,$12,$0A,$09,$2 0a60 : 85181309801201.. db $85,$18,$13,$09,$80,$12,$01,$0B,$31,$30,$61,$72,$0 0a70 : 05031b1a190b09.. db $05,$03,$1B,$1A,$19,$0B,$09,$06,$0A,$00,$00,$1C,$1 0a80 : 53d280a830bc31.. db $53,$D2,$80,$A8,$30,$BC,$31,$2A,$31,$2A,$80,$A9,$2 0a90 : 2fc12f80a830bc.. db $2F,$C1,$2F,$80,$A8,$30,$BC,$80,$A9,$2F,$83,$AC,$3 0aa0 : 80a8522f84bd09.. db $80,$A8,$52,$2F,$84,$BD,$09,$02,$2F,$8E,$BC,$84,$B 0ab0 : 84be09052f0991.. db $84,$BE,$09,$05,$2F,$09,$91,$2F,$80,$BE,$84,$BD,$0 0ac0 : bc09952f09042f.. db $BC,$09,$95,$2F,$09,$04,$2F,$00,$00,$00 else IL_6502 equ false ;. ORIGINAL TINY BASIC INTERMEDIATE INTERPRETER ;. ;. EXECUTIVE INITIALIZATION ;. db $24,$3a,$91 ;:STRT PC ":Q^" COLON, X-ON db $27 ; GL db $10 ; SB db $e1 ; BE L0 BRANCH IF NOT EMPTY db $59 ; BR STRT TRY AGAIN IF NULL LINE db $c5 ;:L0 BN STMT TEST FOR LINE NUMBER db $2a ; IL IF SO, INSERT INTO PRO db $56 ; BR STRT GO GET NEXT db $10 ;:XEC SB SAVE POINTERS FOR RUN db $11 ; RB CONCATENATED INPUT db $2c ; XQ ;. ;. STATEMENT EXECUTOR ;. db $8b,$4c,$45,$d4 ;:STMT BC GOTO "LET" db $a0 ; BV * MUST BE A VARIABLE NAM db $80,$bd ; BC * "=" db $30,$bc ;:LET JS EXPR GO GET EXPRESSION db $e0 ; BE * IF STATEMENT END, db $13 ; SV STORE RESULT db $1d ; NX ;. db $94,$47,$cf ;:GOTO BC PRNT "GO" db $88,$54,$cf ; BC GOSB "TO" db $30,$bc ; JS EXPR GET LINE NUMBER db $e0 ; BE * db $10 ; SB (DO THIS FOR STARTING) db $11 ; RB db $16 ; GO GO THERE ;. db $80,$53,$55,$c2 ;:GOSB BC * "SUB" NO OTHER WO db $30,$bc ; JS EXPR db $e0 ; BE * if IL_6502 db $14 ; ??? else db $e4 ; GS endif AS65 Assembler for R6502 [1.42]. Page 33 ------------------------------- tinybasic.asm -------------------------------- db $16 ; GO ;. db $90,$50,$d2 ;:PRNT BC SKIP "PR" db $83,$49,$4e,$d4 ; BC P0 "INT" OPTIONALLY db $e5 ;:P0 BE P3 db $71 ; BR P6 IF DONE, GO TO END db $88,$bb ;:P1 BC P4 ";" db $e1 ;:P2 BE P3 db $1d ; NX NO CRLF IF ENDED BY ; db $8f,$a2 ;:P3 BC P7 '"' db $21 ; PQ QUOTE MARKS STRING db $58 ; BR P1 GO CHECK DELIMITER db $6f ;:SKIP BR IF (ON THE WAY THRU) db $83,$ac ;:P4 BC P5 "," db $22 ; PT COMMA SPACING db $55 ; BR P2 db $83,$ba ;:P5 BC P6 ":" db $24,$93 ; PC "S^" OUTPUT X-OFF db $e0 ;:P6 BE * db $23 ; NL THEN CRLF db $1d ; NX db $30,$bc ;:P7 JS EXPR TRY FOR AN EXPRESS db $20 ; PN db $48 ; BR P1 ;. db $91,$49,$c6 ;:IF BC INPT "IF" db $30,$bc ; JS EXPR db $31,$34 ; JS RELO db $30,$bc ; JS EXPR db $84,$54,$48 ; BC I1 "THEN" OPTIONAL NOISEW db $45,$ce ; db $1c ;:I1 CP COMPARE SKIPS NEXT IF db $1d ; NX FALSE. db $38,$0d ; J STMT TRUE. GO PROCESS S ;. db $9a,$49,$4e ;:INPT BC RETN "INPUT" db $50,$55,$d4 db $a0 ;:I2 BV * GET VARIABLE db $10 ; SB SWAP POINTERS\ db $e7 ; BE I4 db $24,$3f,$20,$91 ;:I3 PC "? Q^" LINE IS EMP db $27 ; GL READ INPUT LINE db $e1 ; BE I4 DID ANYTHING COME? db $59 ; BR I3 NO, TRY AGAIN db $81,$ac ;:I4 BC I5 "," OPTIONAL COMMA db $30,$bc ;:I5 JS EXPR READ A NUMBER db $13 ; SV STORE INTO VARIABLE db $11 ; RB SWAP BACK db $82,$ac ; BC I6 "," ANOTHER? db $4d ; BR I2 YES IF COMMA db $e0 ;:I6 BE * OTHERWISE QUIT db $1d ; NX ;. db $89,$52,$45,$54 ;:RETN BC END "RETURN" db $55,$52,$ce db $e0 ; BE * db $15 ; RS RECOVER SAVED LINE db $1d ; NX ;. AS65 Assembler for R6502 [1.42]. Page 34 ------------------------------- tinybasic.asm -------------------------------- db $85,$45,$4e,$c4 ;:END BC LIST "END" ; db $e0 ; BE * db $2d ; WS ;. db $98,$4c,$49,$53 ;:LIST BC RUN "LIST" db $d4 ; db $ec ; BE L2 db $24,$00,$00,$00 ;:L1 PC "@^@^@^@^J^@^" PUNCH LEA db $00,$0a,$80 ;. db $1f ; LS LIST db $24,$93 ; PC "S^" PUNCH X-OFF db $23 ; NL db $1d ; NX db $30,$bc ;:L2 JS EXPR GET A LINE NUMBER db $e1 ; BE L3 db $50 ; BR L1 db $80,$ac ;:L3 BC * "," SEPARATED BY COMMA db $59 ; BR L2 ;. db $85,$52,$55,$ce ;:RUN BC CLER "RUN" ; db $38,$0a ; J XEC ;. db $86,$43,$4c,$45 ;:CLER BC REM "CLEAR" db $41,$d2 ; db $2b ; MT ;. db $84,$52,$45,$cd ;:REM BC DFLT "REM" ; db $1d ; NX ;. db $a0 ;:DFLT BV * NO KEYWORD... db $80,$bd ; BC * "=" TRY FOR LET db $38,$14 ; J LET IT'S A GOOD BET. ;. ;. SUBROUTINES ;. db $85,$ad ;:EXPR BC E0 "-" TRY FOR UNARY MINU db $30,$d3 ; JS TERM AHA db $17 ; NE db $64 ; BR E1 db $81,$ab ;:E0 BC E4 "+" IGNORE UNARY PLUS db $30,$d3 ;:E4 JS TERM db $85,$ab ;:E1 BC E2 "+" TERMS SEPARATED BY db $30,$d3 ; JS TERM db $18 ; AD db $5a ; BR E1 db $85,$ad ;:E2 BC E3 "-" TERMS SEPARATED BY db $30,$d3 ; JS TERM db $19 ; SU db $54 ; BR E1 db $2f ;:E3 RT ;. db $30,$e2 ;:TERM JS FACT db $85,$aa ;:T0 BC T1 "*" FACTORS SEPARATED db $30,$e2 ; JS FACT db $1a ; MP db $5a ; BR T0 AS65 Assembler for R6502 [1.42]. Page 35 ------------------------------- tinybasic.asm -------------------------------- db $85,$af ;:T1 BC T2 "/" FACTORS SEPARATED db $30,$e2 ; JS FACT db $1b ; DV db $54 ; BR T0 db $2f ;:T2 RT ;. if IL_6502 db $98,$52,$4e,$c4 ;:FACT BC F0 "RND" *RND FUNCTI else db $97,$52,$4e,$c4 ;:FACT BC F0 "RND" *RND FUNCTI endif ; db $0a,$80,$80 ; LN 257*128 STACK POINTER F ; db $12 ; FV THEN GET RNDM db $0a,$09,$29 ; LN 2345 R:=R*2345+6789 ; db $1a ; MP db $0a,$1a,$85 ; LN 6789 ; db $18 ; AD db $13 ; SV db $09,$80 ; LB 128 GET IT AGAIN db $12 ; FV if IL_6502 db $01 endif db $0b ; DS db $31,$30 ; JS FUNC GET ARGUMENT db $61 ; BR F1 if IL_6502 db $72 ;:F0 BR F2 (SKIPPING) else db $73 ;:F0 BR F2 (SKIPPING) endif db $0b ;:F1 DS ; db $02 ; SX 2 PUSH TOP INTO STACK db $04 ; SX 4 db $02 ; SX 2 db $03 ; SX 3 db $05 ; SX 5 db $03 ; SX 3 db $1b ; DV PERFORM MOD FUNCTION db $1a ; MP db $19 ; SU db $0b ; DS PERFORM ABS FUNCTION db $09,$06 ; LB 6 db $0a,$00,$00 ; LN 0 ; db $1c ; CP (SKIP IF + OR 0) db $17 ; NE db $2f ; RT db $8f,$55,$53,$d2 ;:F2 BC F3 "USR" *USR FUNCTI ; db $80,$a8 ; BC * "(" 3 ARGUMENTS POSSIB db $30,$bc ; JS EXPR ONE REQUIRED db $31,$2a ; JS ARG db $31,$2A ; JS ARG db $80,$a9 ; BC * ")" db $2e ; US GO DO IT db $2f ; RT db $a2 ;:F3 BV F4 VARIABLE? AS65 Assembler for R6502 [1.42]. Page 36 ------------------------------- tinybasic.asm -------------------------------- db $12 ; FV YES. GET IT db $2f ; RT db $c1 ;:F4 BN F5 NUMBER?\n"); db $2f ; RT GOT IT. db $80,$a8 ;:F5 BC * "(" OTHERWISE MUST BE db $30,$bc ;:F6 JS EXPR db $80,$a9 ; BC * ")" db $2f ; RT ;. db $83,$ac ;:ARG BC A0 "," COMMA? db $38,$bc ; J EXPR YES, GET EXPRESSI db $0b ;:A0 DS NO, DUPLICATE STACK T db $2f ; RT ;. db $80,$a8 ;:FUNC BC * "(" db $52 ; BR F6 db $2f ; RT ;. db $84,$bd ;:RELO BC R0 "=" CONVERT RELATION db $09,$02 ; LB 2 TO CODE BYTE ON S db $2f ; RT = db $8e,$bc ;:R0 BC R4 "<" db $84,$bd ; BC R1 "=" if IL_6502 db $09,$93 ; LB 3 <= else db $09,$03 ; LB 3 <= endif db $2f ; RT db $84,$be ;:R1 BC R3 ">" db $09,$05 ; LB 5 <> db $2f ; RT if IL_6502 db $09,$91 ;:R3 LB 1 < else db $09,$01 ;:R3 LB 1 < endif db $2f ; RT db $80,$be ;:R4 BC * ">" db $84,$bd ; BC R5 "=" db $09,$06 ; LB 6 >= db $2f ; RT db $84,$bc ;:R5 BC R6 "<" if IL_6502 db $09,$95 ; LB 5 >< else db $09,$05 ; LB 5 >< endif db $2f ; RT db $09,$04 ;:R6 LB 4 > db $2f ; RT ;. if IL_6502 db $00,$00,$00 endif endif ; ;***************************************************** ; This is the start of the program area where the user ; gets stored. ; 0aca = codeend equ * AS65 Assembler for R6502 [1.42]. Page 37 ------------------------------- tinybasic.asm -------------------------------- ; ;***************************************************** ; This is a KIM function to emulate the BREAK key dete ; this in the original TB user manual. ; if KIM1 1740 = KTTY equ $1740 0100 = org $0100 0100 : ad4017 KIMBT lda KTTY ;LOOK AT TTY 0103 : 18 clc ;C=O IF IDLE 0104 : 300e bmi KIMX ;IDLE 0106 : ad4017 lda KTTY ;WAIT FOR END 0109 : 10fb bpl *-3 010b : 200e01 KLDY jsr KIMDL 010e : a9ff KIMDL lda #255 ;DELAY 2 RUBOUT TIMES 0110 : 20a01e jsr OUTCH 0113 : 38 sec ;C=1 IF BREAK 0114 : 60 KIMX rts endif ; end No errors in pass 2.