VTL-2 SUBROUTINE RETURNS AND MACHINE CODE INTERFACING for the 6502 VTL-2C(u) version, running on an unexpanded PAL-1 Up front, I'll admit my bias for VTL-2 as a powerful little high-level language for small microcomputers. At 1.1K, it's got almost everything Tiny BASIC has, plus extra (string input, arrays...). On the unexpanded PAL-1, I have 3.2k of user RAM -- almost as much as my old VIC-20, back in the day -- which is a full kilobyte more than you have with Tiny BASIC. But one thing it does not have is a good way to return from a subroutine call. The #=! statement works fine...except when the subroutine you've called has other branching statements in it; a simple IF-THEN construction will overwrite the ! 'return' variable. An easy way around this limitation is to store the return line number in a different variable yourself. In the example below, line 1012 assigns the return line number to the variable ^ -- it's not used for anything, generally (along with [ / ] and _ -- all of which are valid numerical variables). I like it because it points "up." In any case, I've added line 1012 right before I want to 'gosub' to 1300. Once down there, the subroutine does its thing, including a comparison and potential jump at 1320, the execution of which changes the address in variable !. But, since I saved the line-of-return of the main program in ^ before I jumped to 1300, I can just make ^ equal the current line number (#) and "return" from the subroutine. 1000 ?="" 1001 ?="Total # of in-play dice to keep: "; 1003 I=? 1012 ^=1015 1013 #=1300 1015 #=I<1*1003 1020 #=I>(M+1)*1003 ... 1300 J=1 1305 T=0 1310 K=:J+6) 1320 #=K>6*1340 1325 #=^ 1330 ?="Not enough 1s and 5s for that many." 1340 #=1000 For repeated calls to the subroutine from different places in the program, just pop in a ^=xxx before branching there. Another example: 10 ^=30 20 #=100 30 ?="Rest of the main program" . . . 100 #=A=1*120 110 #=A>7*140 120 A=A+B 130 #=150 140 A=A+C 150 #=^ This "returns" from the subroutine to line 30 (^=30 in line 10), right after where it was called. MACHINE LANGUAGE THOUGHTS It's pretty easy to pass values to the accumulator and X register with VTL-2: set up the starting address for the ML code in question -- "=6016 ($1780) -- then call it with >=767 and your ML routine will find $02 in the accumulator and $FF in X. If I only care about having one 8-bit number passed, I can just call my routine with > equaling less than 256, then do a TXA if I need that number in the accumulator. The real problems come when retrieving values from a machine language routine. The > variable seems unreliable: sometimes it holds the result Ax, sometimes not. For me, the simplest way to deal with this is store the values *directly* into one of the rarely-used fixed variables of VTL-2. I usually use the [ variable. If I want to pass info back to my VTL-2 program, I do the following as the last lines of a routine: STX $B6 ; LSB of the variable [ (could also be STA or STY...) STA $B7 ; MSB (optional, if value is <#256) RTS When back in VTL-2, I can then do something like 100 A=[/256 110 X=% (remainder from last division) to get the accumulator and X out of a returned 16-bit value. If I only wanted to send back one 8-bit byte and didn't want to fuss with the division step, I could have the ML routine store $00 in $B7 before it exits (ala the 'PEEK' routine below) and just say 100 X=[ to get the value. PEEK AND POKE ***** NOTE! The information under the '===='s, while perfectly serviceable, is unnecessary. Mike Berry, who ported VTL-02 to the 6502 from the original 6800 version, informs me that the < and @ variables can be used to 'peek' and 'poke'. Information is included in his source code (how did I miss it?!?), but it's not mentioned in Frank McCoy's updated VTL-2 manual. It works very much like calling a machine language routine: POKE: <=9830 ; point to $2666 @=66 ; store $42 there PEEK: <=9830 ; point to $2666 A=@ ; assign A the value 66 That's a lot simpler/more elegant than what I previously came up with... ======================================================================================== If you want PEEK and POKE equivalents (as Tiny BASIC has), you'll have to call a small machine language program, perhaps hidden in the unused part of VTL-2's input buffer ($250-$2FF is safe for ML). Like this two-step process for POKE: VTL-2 "=640 ; $280 addr of POKE routine >=6016 ; $1780 addr to POKE "=645 ; $285 addr of store a VAL >=255 ; $FF the value (max.) ML * = $0280 ; decimal 640 STORAD STX $10 ; using $10 and $11 for addr storage STA $11 RTS POKEIT LDY #$00 ; location is decimal 645 TXA STA ($10),Y RTS This will store $FF into $1780. Again, X is the least significant byte, A the MSB. To PEEK a location, try something like: VTL-2 "=656 ; $290 addr of PEEK routine >=6032 ; $1790 addr to PEEK ML * = $0290 ; decimal 656 LDY #$00 STORIT STX $10 STA $11 LDA ($10),Y STA $B6 STY $B7 RTS This will put the value of the location in $10/$11 into the VTL-2 variable [. Storing Y ($00) in the MSB ensures that the result will be correct. --- D H H