notwhoyouthink #1 Posted July 11, 2017 (edited) I know for a fact that assembly can be directly loaded and executed by the console, see the game morphy's special loader program from cassette. (using a fake header on cs1) That said, would it be possible to use that technique to inject a program to mimic call load in extended basic? Or at least trick extended basic into thinking a call init had been done, without having a 32k memory attached? Edited July 11, 2017 by notwhoyouthink Quote Share this post Link to post Share on other sites
+RXB #2 Posted July 11, 2017 (edited) No XB has a MAJOR BUG using CALL LOAD requires CALL INIT to be used first. RXB fixed this XB bug in 2001 and with RXB you can use CALL LOAD without the need for CALL INIT first. You can see the XB CALL INIT bug in RXB source code where I commented out that sections. Edited July 11, 2017 by RXB Quote Share this post Link to post Share on other sites
Tursi #3 Posted July 12, 2017 Morphy was a cool trick, but the Playground technique by Senior Falcon really broke the console wide open for TI BASIC, since it doesn't require any additional loads and works from disk, tape, or what-have-you. It's based on a buffer overflow in the OPEN command, it's not inconceivable that the same bug exists in XB...? I don't remember if anyone tried it. But what would you gain? Once you're running assembly code, does it matter if you launched it from BASIC or XB? 3 Quote Share this post Link to post Share on other sites
apersson850 #4 Posted July 12, 2017 The fact that you can't do CALL LOAD in Extended BASIC without first doing CALL INIT isn't a bug. It's by design. CALL LOAD calls the assembly program loader, designed to load assembly programs into expansion memory, and to do the bookkeeping of the loading using data structures set up by CALL INIT. Thus it's pointless without the memory expansion. The different fact that CALL LOAD can be used as what's normally called POKE as well, that's also by design. That you in fact can't do a POKE without having the memory expansion, now that's a limitation, of course. Not a very big one, since most of what you POKE without the memory expansion will destroy Extended BASIC anyway, but yes, it's a limitation. But it's still by design, so it's not a bug. Quote Share this post Link to post Share on other sites
+RXB #5 Posted July 12, 2017 (edited) The fact that you can't do CALL LOAD in Extended BASIC without first doing CALL INIT isn't a bug. It's by design. CALL LOAD calls the assembly program loader, designed to load assembly programs into expansion memory, and to do the bookkeeping of the loading using data structures set up by CALL INIT. Thus it's pointless without the memory expansion. The different fact that CALL LOAD can be used as what's normally called POKE as well, that's also by design. That you in fact can't do a POKE without having the memory expansion, now that's a limitation, of course. Not a very big one, since most of what you POKE without the memory expansion will destroy Extended BASIC anyway, but yes, it's a limitation. But it's still by design, so it's not a bug. LOL WRONG! It is stupid bug. Why would you restrict a CALL LOAD from working if you are not using CALL LOAD(FILE)????? You can do CALL LOAD to SCRATCH RAM all the time to do many things, why do you need a 32K for that?????? There is a whole list of them to do..... Edited July 12, 2017 by RXB Quote Share this post Link to post Share on other sites
+arcadeshopper #6 Posted July 12, 2017 ok well its a feature that you disagree with how's that? In the meantime.. someone want to try the overflow exploit in xb? Greg Quote Share this post Link to post Share on other sites
+RXB #7 Posted July 12, 2017 ok well its a feature that you disagree with how's that? In the meantime.. someone want to try the overflow exploit in xb? Greg Show me other computers that do this stupid move? Every other Basic or Language does not restrict you to ONLY LOADING FILES with CALL LOAD or CALL POKE in this case. Quote Share this post Link to post Share on other sites
+chue #8 Posted July 12, 2017 In the meantime.. someone want to try the overflow exploit in xb? I just tried the exploit in XB (Triton SXB and TI XB) and it also works there. 3 Quote Share this post Link to post Share on other sites
apersson850 #9 Posted July 12, 2017 (edited) LOL WRONG! It is stupid bug. Since you seem not to know what a "bug" is, I can inform you about that it's something that doesn't work as intended. Thus this is not a bug. It's as intended, by design. TI choose to provide the Extended BASIC with a more advanced version than then ordinary POKE, and gave us a tagged object code loader, which also can poke values into RAM. Since the main purpose is to work as an object code loader, it works without any bugs I've heard about. They also made a more advanced way to call assembly routines, by name via the CALL LINK statement, instead of just some version of EXEC at a memory location, which otherwise was common on contemporary computers. Then if there should be a POKE, specifically to do just that, that's something else. It was available on other computers, but I've not seen any other computer of the same style which didn't have any CPU RAM (except for the 256 bytes). So it's much more meaningful on other machines. Edited July 12, 2017 by apersson850 Quote Share this post Link to post Share on other sites
notwhoyouthink #10 Posted July 12, 2017 (edited) I just tried the exploit in XB (Triton SXB and TI XB) and it also works there. Have not got my Extended basic in the mail yet, but by overflow exploit, do you mean the trick morphy uses? Or like the loader for playground? Or something else? And does it work with out 32k? Edited July 12, 2017 by notwhoyouthink Quote Share this post Link to post Share on other sites
+chue #11 Posted July 12, 2017 (edited) This is the buffer overflow exploit that Tursi talks about above. It works in BASIC, as well as XB. I forget where I got the code from (probably somewhere on this site). Edit: here's the original post: http://atariage.com/forums/topic/162941-assembly-on-the-994a/?p=2849894 Anyways, here is the code - It is a TI BASIC program that calls an assembly language routine that moves the words "hello world" across the screen: 10 REM Escape the BASIC sandbox 20 REM by James Abbatiello <[email protected]> 30 REM Displays an animated Hello, World! 40 REM message using machine language. 50 REM Works even without Extended BASIC 60 REM and without the 32K memory expansion. 100 CALL CLEAR 110 PRINT "PRESS" 120 PRINT "1 FOR TI-99/4A" 130 PRINT "2 FOR TI-99/4A (alt)" 140 PRINT "3 FOR TI-99/4A V2.2" 150 CALL KEY(5,C,S) 160 IF (C < 49) + (C > 51) THEN 150 170 PRINT "INITIALIZING ..." 180 V(0)=885 190 V(1)=882 200 V(2)=846 210 L=V(C-49) 220 A$=CHR$(INT(L/256))&CHR$(L-256*INT(L/256)) 230 FOR I = 1 TO 126 240 READ C 250 A$=A$&CHR$( C ) 260 NEXT I 270 OPEN #1:A$ 800 DATA 128,168,165,172,172,175,140,128 810 DATA 183,175,178,172,164,129,0,0 820 DATA 0,0,0,0,0,0,0,0 830 DATA 0,0,0,0,0,0,0,0 840 DATA 0,0,0,0,0,0,0,74 850 DATA 0,0,0,0,0,0,0,0 860 DATA 0,0,0,0,131,130,2,0 870 DATA 2,244,2,11,64,0,6,0 880 DATA 19,250,208,111,252,0,10,17 890 DATA 23,252,215,224,131,247,2,2 900 DATA 131,76,215,203,5,139,208,114 910 DATA 19,242,219,193,255,254,16,251 920 DATA 0,0,0,0,0,0,0,0 930 DATA 0,0,0,0,0,0,0,0 940 DATA 0,0,0,0,0,0,0,0 950 DATA 0,0,0,0,0,0 Edited July 12, 2017 by chue Quote Share this post Link to post Share on other sites
Opry99er #12 Posted July 12, 2017 Sooooooooo slick.... 1 Quote Share this post Link to post Share on other sites
+RXB #13 Posted July 12, 2017 Since you seem not to know what a "bug" is, I can inform you about that it's something that doesn't work as intended. Thus this is not a bug. It's as intended, by design. TI choose to provide the Extended BASIC with a more advanced version than then ordinary POKE, and gave us a tagged object code loader, which also can poke values into RAM. Since the main purpose is to work as an object code loader, it works without any bugs I've heard about. They also made a more advanced way to call assembly routines, by name via the CALL LINK statement, instead of just some version of EXEC at a memory location, which otherwise was common on contemporary computers. Then if there should be a POKE, specifically to do just that, that's something else. It was available on other computers, but I've not seen any other computer of the same style which didn't have any CPU RAM (except for the 256 bytes). So it's much more meaningful on other machines. TI XB uses CALL LOAD as a CALL POKE, trouble is I know the source one hell of lot better than you do. It was a mistake, bug, stupid oversight or whatever you want to call it. Who in right mind would make a CALL POKE that will not work unless you have Expanded memory? Why? As I know the GPL source inside out for over 20 years I think I know a bug when I see one. This is why when using just console and RXB you can use the CALL LOAD routines that everyone is fond of to do things: 8192 , P USE (PEEK,P) IF P<> 70 OR <>121 THEN DO A CALL INIT 8194 , FIRST FREE ADDRESS IN LOW MEMORY 8196 , LAST FREE ADDRESS IN LOW MEMORY -28672 , P P=0 SPEECH NOT ATTACHED P=96 OR P=255 SPEECH IS ATTACHED -31572 , 0 TO 255 VARY KEYBOARD RESPONSE -31740 , P , Q PUT IN DIFFERENT TO CHANGE BEEPS,WARNINGS, ETC -31744 , 0 TO 15 CONTINUATION OF LAST SOUND (0=LOUD AND 15=SOFT) -31748 , 0 TO 255 CHANGE THE CURSOR FLASHING AND RESPONSE TONE RATES -31788 , 160 BLANK OUT THE SCREEN (MUST PUSH A KEY TO ACTIVATE) , 192 NO AUTOMATIC SPRITE MOTION OR SOUND , 224 NORMAL OPERATION , 225 MAGNIFIED SPRITES , 226 DOUBLE SIZE SPRITES , 227 MAGNIFIED & DOUBLE SIZED SPRITES , 232 MULTICOLOR MODE (48 BY 64 SQUARES) -31794 , P TIMER FOR CALL SOUND (COUNTS FROM 255 TO 0) -31804 , X , Y RETURN TO THE TITLE SCREEN (USE "PEEK (2,X,Y)") , P CHANGE THE CURSOR FLASH RATE (0 TO 255) -31806 , 0 NORMAL OPERATION , 16 DISABLE QUIT KEY (FCTN =) , 32 DISABLE SOUND (USE NEG DUR FOR CONTINOUS SOUND) , 48 DISABLE SOUND & QUIT KEY , 64 DISABLE AUTO SPRITE MOTION , 80 DISABLE SPRITES & QUIT KEY , 96 DISABLE SPRITES AND SOUND , 128 DISABLE ALL THREE -31808 , P , Q DOUBLE RANDOM NUMBERS (0 TO 255) NEED "RANDOMIZE" -31860 , 4 GO FROM EX-BASIC TO CONSOLE BASIC (NEED "NEW") , 8 AUTO RUN OF DSK1.LOAD -31866 , P , Q END OF CPU PROGRAM ADDRESS (P*256+Q) -31868 , 0 NO "RUN" OR "LIST" AFTER "BREAK" IS USED , 0 , 0 TURNS OFF THE 32K MEMORY EXPANSION , 255 , 231 TURNS ON THE 32K MEMORY EXPANSION -31873 , 3 TO 30 SCREEN COLUMN TO START AT WITH A "PRINT" -31877 , P P&32 = SPRITE COINCIDENCE P&64 = 5 SPRITES ON A LINE -31878 , P HIGHEST NUMBER SPRITE IN MOTION (0 STOPS ALL) -31879 , P TIMER FOR VDP INTERRUPTS EVERY 1/60 OF A SEC (0 TOP 255) -31880 , P RANDOM NUMBER (0 TO 99) NEED "RANDOMIZE" -31884 , 0 TO 5 CHANGE KEYBOARD MODE (LIKE "CALL KEY(K,...)") -31888 , 63 , 255 DISABLE ALL DISK DRIVES (USE "NEW" TO FREE MEMORY) , 55 , 215 ENABLE ALL DISK DRIVES (USE "NEW" TO FREE DRIVES) -31931 , 0 UNPROTECT X-B PROTECTION , 2 SET "ON WARNING NEXT" COMMAND , 4 SET "ON WARNING STOP" COMMAND , 14 SET "UNTRACE" COMMAND , 15 SET "UNTRACE" COMMAND & "NUM" COMMAND , 16 SET "TRACE" COMMAND , 64 SET "ON BREAK NEXT" COMMAND , 128 PROTECT X/B PROGRAM -31952 , P PEEK P=55 THEN 32K EXPANSION MEMORY IS OFF <>55 MEANS ON -31962 , 32 RETURN TO THE TITLE SCREEN , 255 RESTART X/B W/DSK1.LOAD . -31974 , P , Q END OF VDP STACK ADDRESS (P*256+Q) -32112 , 8 SEARCHES DISK FOR ? -32114 , 2 RANDOM GARBAGE , 13 SCREEN GOES WILD , 119 PRODUCE LINES -32116 , 2 RANDOM CHARACTERS ON SCREEN , 4 GO FROM X/BASIC TO BASIC -32187 , 0 UNPROTECT XB PROGRAM , 2 SET "ON WARNING NEXT" COMMAND , 4 SET "ON WARNING STOP" COMMAND , 9 SET 0 LINE NUMBER , 14 SET "UNTRACE" COMMAND , 15 SET "UNTRACE" COMMAND & "NUM" COMMAND , 16 SET "TRACE" COMMAND , 64 SET "ON BREAK NEXT" COMMAND , 128 PROTECT XB PROGRAM -32188 , 1 CHANGE COLOR AND RECEIVE SYNTAX ERROR , 127 CHANGE COLOR AND RECEIVE BREAKPOINT -32630 , 128 RESET TO TITLE SCREEN -32699 , 0 UNPROTECT XB PROGRAM , 2 SET "ON WARNING NEXT" COMMAND , 4 SET "ON WARNING STOP" COMMAND , 14 SET "UNTRACE" COMMAND , 15 SET "UNTRACE" & "NUM" COMMAND , 16 SET "TRACE" COMMAND , 64 SET "ON BREAK NEXT" , 128 PROTECT XB PROGRAM -32700 , 0 CLEARS CREEN FOR AN INSTANT -32729 , 0 RUN "DSK1.LOAD" -32730 , 32 RESET TO TITLE SCREEN -32961 , 51 RESET TO TITLE SCREEN , 149 SETS "ON BREAK GOTO" LOCKS SYSTEM Quote Share this post Link to post Share on other sites
mizapf #14 Posted July 13, 2017 The fact that you can make some good use of CALL LOAD does not imply that Texas Instruments had any intention that you actually do that. I suppose that TI indeed tried to hide those features under higher-layer functions. Quote Share this post Link to post Share on other sites
+RXB #15 Posted July 13, 2017 (edited) The fact that you can make some good use of CALL LOAD does not imply that Texas Instruments had any intention that you actually do that. I suppose that TI indeed tried to hide those features under higher-layer functions. GPL code from TI XB source: [0004] GROM >C000 [0005] *********************************************************** [0006] TITL 'EQUATES ALCS-359' [0007] *********************************************************** [0008] 2002 FSLOC EQU >2002 Free Start LOCation in ERAM [0009] * Free end must follow it. [0010] 2006 INITF EQU >2006 INIT flag address INIT has be [0011] * called if ERAM (INITF)=>AA55 [0012] * Free end initialized to >4000, (>FFF8 for debugger) [0013] * Free start is initialized to the first useable memory [0014] * location for assembly language code [0015] A040 CPUBAS EQU >A040 Expansion RAM base [0016] ********************************************************** After some EQUats: [0664] *********************************************************** [0665] * ASSEMBLY LANGUAGE SUPPORT FOR 99/4 [0666] * [0667] * LOAD, INIT, PEEK, LINK, CHARPAT JDH 08/21/80 [0668] *********************************************************** [0669] * FORMAT FOR LOAD: [0670] * CALL LOAD open load-directive (comma load-directive) [0671] * close [0672] * load-directive = file-name / address (comma data) [0673] * (null / file-name) [0674] * file-name = string-expression [0675] * address = numeric-expression [0676] * data = numeric-expression [0677] * [0678] * FILE TYPE = FIXED 80, DISPLAY , SEQUENTIAL FILE [0679] * [0680] * FUNCTION: [0681] * LOADS ASSEMBLY LANGUAGE CODE INTO EXPANSION RAM [0682] * ADDRESSES: >2000 - >>3FFF RELOCATING [0683] * RELOCATABLE CODE INTO AVAILABLE MEMORY, ABSOLUTE CODE [0684] * IS LOADED [0685] * INTO ITS ABSOLUTE ADDRESS, ENTRY POINTS ARE DEFINED BY [0686] * 'DEF' STATEMENTS, AND ARE LOADED INTO HIGH END OF ERAM [0687] * [0688] * RELOACATABLE OR ABSOLUTE CODE MAY BE STORED ON A FILE [0689] * 9900 OBJECT CODE FORMAT. [0690] * VALID TAGS = 0, 5, 6, 7, 9, A, B, C, F,: [0691] * TAGS 1, 2, I, M, ARE IGNORED [0692] * THE SYMT OPTION IS NOT SUPPORTED. [0693] * ABSOLUTE CODE MAY BE LOADED DIRECTLY FROM PROGRAM [0694] * BY SPECIFYING AN ADDRESS INSTEAD OF A FILE NAME, [0695] * FOLLOWED BY THE DATA TO BE LOADED (WHICH IS PUT IN THE [0696] * RANGE 0 to 255 [0697] * THE RANGE OF THE ADDRESS OR DATA IS LIMITED TO [0698] * 32767 to -32768 [0699] * MULTIPLE DIRECT LOADS CAN BE IN THE SAME LOAD COMMAND [0700] * PROVIDED THEY ARE SEPARATED BY EITHER A FILENAME OR A [0701] * NULL STRING. [0702] * [0703] * MVUP WAS USED TO TRANSFER DATA FROM CPU RAM TO ERAM [0704] * SINCE IT WAS NOT KNOWN AT FIRST THAT THE MOVE [0705] * INSTRUCTION COULD TRANSFER FROM CPU RAM TO ERAM 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0012 EQUATES ALCS-359 [0706] * (PROVIDED THAT >8300 IS SUBTRACTED FROM THE ADDRESSES) [0707] *********************************************************** Please note the last few lines in these comments about the GPL MOVE instruction was not known by the Assembly programming team. Now for the GRAMKRACKER fixing what I call bugs in XB and then my futher fixing the bug of CALL INIT before you can use any CALL LOAD: 0731] * LOAD - LDP1 - LDP4 - LDP5 [0732] ** CHKSUM is also used as a flag to test if a file has been [0733] ** opened (so that it gets closed) [0734] ** it is initialized to >0001 and will be changed to some [0735] ** other value if a file is used [0736] C040 BF,02,00 LOAD DST >0001,@CHKSUM {INITIALIZE FILE FLAG} C043 01 [0737] * GKXB Change load routine. Delete check for INIT [0738] * add to clear flag bits. [0739] C044 06,C6,14 CALL GKLOAD [0740] C047 D6,42,B7 GC047 CEQ LPARZ,@CHAT SYNTAX ERROR if no "(" [0741] C04A 45,30 BR ERRSY1 [0742] C04C 0F,79 XML PGMCHR Skip over [0743] * MAIN PARESE LOOP * [0744] * Check for file-name or address [0745] C04E 0F,74 LDP1 XML PARSE [0746] C050 B6 BYTE RPARZ * PARSE up to ")" or "," [0747] C051 D6,4C,65 CEQ STRING,@FAC2 Process file name [0748] C054 60,90 BS LDP2 [0749] * Otherwise it is an address [0750] * Convert address to integer, save in @PC [0751] C056 0F,12 XML CFI Convert FAC to integer [0752] C058 D6,54,03 CEQ 3,@FAC10 Check for overflow [0753] C05B 65,29 BS ERRN01 [0754] C05D BD,04,4A DST @FAC,@PC Save in ERAM location pointer [0755] * Check for "," if there then data should folow [0756] * else end of load statement, goto LDP5 [0757] C060 D6,42,B3 LDP4 CEQ COMMAZ,@CHAT [0758] C063 40,88 BR LDP5 [0759] * DATA follows or a STRING if no more data [0760] C065 0F,79 XML PGMCHR Skip "," 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0013 EQUATES ALCS-359 [0761] C067 0F,74 XML PARSE Get data value or string if [0762] * end of data [0763] C069 B6 BYTE RPARZ * Parse up to ")" or "," [0764] C06A D6,4C,65 CEQ STRING,@FAC2 No more data [0765] C06D 60,90 BS LDP2 [0766] * FAC contains a numeric [0767] C06F 0F,12 XML CFI FAC to INTEGER [0768] C071 D6,54,03 CEQ 3,@FAC10 Check for overflow [0769] C074 65,29 BS ERRN01 [0770] * GKXB Code for CPU write moved to LOADDT. Add code to [0771] * check VDP or GRAM bits and write to VDP. [0772] C076 DA,80,C2 CLOG >08,@GKFLAG Check VDP bit C079 08 [0773] C07A 66,8A BS LDGRAM No, check GRAM bit [0774] C07C BC,B0,04 ST @FAC1,V*PC Yes, write to VDP C07F 4B [0775] C080 91,04 DINC @PC Point to next byte [0776] C082 05,C0,60 B LDP4 Continue with LOAD routine [0777] * RXB PATCH FILL EMPTY SPACE ***************************** [0778] C085 05,C0,60 B LDP4 [0779] * GROM ADDRESS >C088 FOR LDP5 [0780] * Check for ")" IF there return ELSE SYNTAX ERROR [0781] C088 D6,42,B6 LDP5 CEQ RPARZ,@CHAT Return [0782] C08B 61,E1 BS LDRET [0783] C08D 05,C5,30 B ERRSY1 SYNTAX ERROR [0784] * LDP2 [0785] * Process file name [0786] C090 8E,51 LDP2 CZ @FAC7 Check for null string [0787] C092 61,D2 BS LDNE2 [0788] * GKXB Change 'LOAD FILE' to check for INIT [0789] C094 06,C6,2D CALL GKINIT [0790] *************** LOAD DATA INTO ERAM *********************** [0791] * LOAD FRESTA, FREEND from ERAM [0792] C097 BF,16,20 DST FSLOC,@VARB Source C09A 02 [0793] C09B BF,00,83 DST FRESTA,@VAR0 Destination C09E 08 [0794] C09F BF,5C,00 DST 4,@ARG # of bytes to move C0A2 04 [0795] C0A3 0F,89 XML MVUP Load [0796] * Initialize PC, OFFSET in case of no "0" tag [0797] C0A5 BD,04,08 DST @FRESTA,@PC [0798] C0A8 BD,06,08 DST @FRESTA,@OFFADD Base address for load module [0799] * Read in one record, evaluate the TAG field [0800] * LDRD - LDTG [0801] C0AB BF,02,00 LDRD DST 0,@CHKSUM Clear check sum C0AE 00 [0802] C0AF 06,C2,63 CALL READIT Rear in a record [0803] C0B2 35,00,05 LDTG MOVE 5,V*BUFPNT,@TAG Get TAG & field C0B5 10,B0,0E [0804] C0B8 06,C2,00 CALL LDIPCS Add 5 to BUFPNT, add ASCII [0805] C0BB 05 BYTE 5 * Value of chars. Read to check [0806] * Convert @FIELD to numeric (from ASCII hex value) [0807] * Store result: HIGH BYTE to FIELD, LOW BYTE to FIELD+1 [0808] * Convert HIGH BYTE first: @FIELD & @FIELD+1 [0809] * Store result in field [0810] C0BC A6,11,30 SUB >30,@FIELD >30 = "0" [0811] C0BF CE,11,09 CGT 9,@FIELD Subtract ASCII difference [0812] * between "9" and "A" [0813] C0C2 40,C7 BR GC0C7 [0814] C0C4 A6,11,07 SUB 7,@FIELD [0815] C0C7 E2,11,04 GC0C7 SLL 4,@FIELD FIELD=FILED*32 [0816] C0CA A6,12,30 SUB >30,@FIELD+1 [0817] C0CD CE,12,09 CGT 9,@FIELD+1 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0014 EQUATES ALCS-359 [0818] C0D0 40,D5 BR GC0D5 [0819] C0D2 A6,12,07 SUB 7,@FIELD+1 [0820] C0D5 A0,11,12 GC0D5 ADD @FIELD+1,@FIELD Add to HIGH BYTE [0821] * Now convert LOW BYTE: @FIELD+2 & @FIELD+3 [0822] * Store result in LOW BYTE of FIELD to FIELD+1 [0823] C0D8 A6,13,30 SUB >30,@FIELD+2 [0824] C0DB CE,13,09 CGT 9,@FIELD+2 [0825] C0DE 40,E3 BR GC0E3 [0826] C0E0 A6,13,07 SUB 7,@FIELD+2 [0827] C0E3 BC,12,13 GC0E3 ST @FIELD+2,@FIELD+1 Store in LOW byte of result [0828] C0E6 E2,12,04 SLL 4,@FIELD+1 FIELD+1 = FIELD+1*32 [0829] C0E9 A6,14,30 SUB >30,@FIELD+3 [0830] C0EC CE,14,09 CGT 9,@FIELD+3 [0831] C0EF 40,F4 BR GC0F4 [0832] C0F1 A6,14,07 SUB 7,@FIELD+3 [0833] C0F4 A0,12,14 GC0F4 ADD @FIELD+3,@FIELD+1 Add to low byte [0834] * Branch to evaluation procedure for TAG [0835] C0F7 A6,10,30 SUB >30,@TAG >30 = "0" [0836] C0FA D2,10,00 CGE 0,@TAG If TAG < "0" ILLEGAL CHAR [0837] C0FD 45,C5 BR ERRUC1 [0838] C0FF CE,10,0A CGT >0A,@TAG TAGS "0" to ":" [0839] C102 61,1C BS GC11C [0840] C104 8A,10 CASE @TAG [0841] C106 41,48 BR TAG0 "0" RELOCATABLE LENGTH [0842] C108 40,B2 BR LDTG IGNORE "1" TAG [0843] C10A 40,B2 BR LDTG IGNORE "2" TAG [0844] C10C 45,C5 BR ERRUC1 No external REF "3" [0845] C10E 45,C5 BR ERRUC1 No external REF "4" [0846] C110 41,5D BR TAG5 "5" relocatable entry DEF [0847] C112 41,60 BR TAG6 "6" Absolute entry DEF [0848] C114 41,92 BR TAG7 "7" check sum [0849] C116 40,B2 BR LDTG "8" ignore check sum [0850] C118 41,9F BR TAG9 "9" Absolute LOAD address [0851] C11A 41,BA BR LDDNE ":" end of file [0852] C11C A6,10,11 GC11C SUB >11,@TAG Subtract offset so [0853] * that "A" is =0 [0854] C11F D2,10,00 CGE 0,@TAG ";" to "@" illegal char [0855] C122 45,C5 BR ERRUC1 [0856] * Skip over "I" tag - 8 char, program ID that follows [0857] C124 D6,10,08 CEQ 8,@TAG [0858] C127 61,56 BS LDTG2 [0859] * Skip over "M" TAG -10 char, program ID that follows [0860] C129 D6,10,0C CEQ 12,@TAG [0861] C12C 41,35 BR LDTG3 [0862] C12E 06,C2,00 CALL LDIPCS [0863] C131 0A BYTE 10 [0864] C132 05,C0,B2 B LDTG [0865] C135 CE,10,05 LDTG3 CGT 5,@TAG TAGS "G" are legal [0866] C138 65,C5 BS ERRUC1 [0867] C13A 8A,10 CASE @TAG [0868] C13C 41,9C BR TAGA "A" RELOCATABLE PROGRAM ADDRE [0869] C13E 41,A8 BR TAGB "B" ABSOLUTE VALUE [0870] C140 41,A5 BR TAGC "C" RELATIVE ADDRESS [0871] C142 45,C5 BR ERRUC1 "D" ERROR [0872] C144 45,C5 BR ERRUC1 "E" ERROR - UNDEFINED [0873] C146 40,AB BR LDRD "F" END OF RECORD [0874] * TAG0 to TAGB [0875] * EVALUATE TAG FIELDS [0876] C148 BD,06,08 TAG0 DST @FRESTA,@OFFADD NEW BASE ADDRESS [0877] C14B BD,04,08 DST @FRESTA,@PC NEW PC [0878] C14E A1,08,11 DADD @FIELD,@FRESTA ADD LENGTH TO FIND END OF [0879] * RELOCATABLE PROGRAM WHICH IS [0880] * START OF NEXT PROGRAM [0881] * Make sure we won't run into routine name table now, so we 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0015 EQUATES ALCS-359 [0882] * don't have to check every time we load a value into ERAM [0883] * routine table must make sure it doesn't run into [0884] * relocatable assembly language code through. [0885] C151 C9,08,0A DCHE @FREEND,@FRESTA OUT OF MEMORY [0886] C154 65,53 BS ERRMF1 [0887] * SKIP OVER PROGRAM ID - 8 BYTES [0888] C156 06,C2,00 LDTG2 CALL LDIPCS [0889] C159 08 BYTE 8 * INC BUFPNT, COMPUTE CHECKSUM [0890] C15A 05,C0,B2 B LDTG [0891] C15D A1,11,06 TAG5 DADD @OFFADD,@FIELD Add starting offset [0892] * TAG6 is an absolute address so do not need to add offset [0893] C160 35,00,06 TAG6 MOVE 6,V*BUFPNT,@INDEX Get symbol name C163 5E,B0,0E [0894] C166 06,C2,00 CALL LDIPCS INC BUPNT, COMPUT CHECKSUM [0895] C169 06 BYTE 6 * We read 6 chars [0896] * Add symbol and its address - stopped in field - to the [0897] * routine entry table. It is put at the end of the table [0898] * (the end of the table is towards the low end of memory) [0899] * Since the table is searched from the end first, if there [0900] * are any duplicate labels the last one entered will have [0901] * precedence over the early one(s). [0902] C16A 97,0A DDECT @FREEND Set to address field [0903] * Load address (stored in field in CPU RAM) into routine [0904] * Name table which is in expansion RAM [0905] C16C BF,16,83 DST FIELD,@VARB Source C16F 11 [0906] C170 BD,00,0A DST @FREEND,@VAR0 Destination [0907] C173 BF,5C,00 DST 2,@ARG # bytes to move C176 02 [0908] C177 0F,89 XML MVUP CPUR RAM to ERAM [0909] * Load symbol into routine name table [0910] C179 A7,0A,00 DSUB 6,@FREEND Set to symbol field C17C 06 [0911] C17D BF,16,83 DST INDEX,@VARB Source C180 5E [0912] C181 BD,00,0A DST @FREEND,@VAR0 Destination [0913] C184 BF,5C,00 DST 6,@ARG Move 6 bytes C187 06 [0914] C188 0F,89 XML MVUP CPU RAM to ERAM [0915] * Check to see if we've run into assembly language code [0916] C18A C9,08,0A DCHE @FREEND,@FRESTA Out of memory [0917] C18D 65,53 BS ERRMF1 [0918] C18F 05,C0,B2 B LDTG If not then continue [0919] *********************************************************** [0920] * ROUTINE NAME TABLE ENTRY [0921] * [0922] * 0 1 2 3 4 5 6 7 [0923] * ----------------------------------- [0924] * FREEND | S | Y | M | B | O | L | ADDRESS | [0925] * (AFTER ENTRY) ----------------------------------- [0926] * FREEND | | | | | | | | [0927] * (BEFORE ENTRY) ----------------------------------- [0928] * [0929] * FREEND is initialized to >4000 by INIT, address is at [0930] * a higher memory location then symbol [0931] *********************************************************** [0932] C192 83,11 TAG7 DNEG @FIELD Checksum is 1's compelement [0933] C194 D5,02,11 DCEQ @FIELD,@CHKSUM Check sum error [0934] C197 45,AE BR ERRDE1 [0935] C199 05,C0,B2 B LDTG [0936] C19C A1,11,06 TAGA DADD @OFFADD,@FIELD PC = OFFADD ^ FIELD [0937] * TAG 9 is an absolute address so no need to add offset [0938] C19F BD,04,11 TAG9 DST @FIELD,@PC [0939] C1A2 05,C0,B2 B LDTG 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0016 EQUATES ALCS-359 [0940] C1A5 A1,11,06 TAGC DADD @OFFADD,@FIELD [0941] * TAG B is an absolute entry so no need to add offset [0942] * Relocatable code is checked to see if it will run into [0943] * is no need to check now. Absolute code can go anywhere. [0944] * [0945] * Load field into expansion RAM using MVUP routine [0946] C1A8 BD,00,04 TAGB DST @PC,@VAR0 Destination [0947] C1AB BF,16,83 DST FIELD,@VARB Source C1AE 11 [0948] C1AF BF,5C,00 DST 2,@ARG Move 2 bytes C1B2 02 [0949] C1B3 0F,89 XML MVUP CPU RAM to ERAM [0950] C1B5 95,04 DINCT @PC We loaded 2 bytes [0951] C1B7 05,C0,B2 B LDTG [0952] ********* END OF LOAD FOR CURRENT FILE ******************** [0953] * [0954] * FRESTA & FREEND are stored in CPU RAM (>8308) [0955] * While loading a file into expansion RAM. [0956] * So if the values of FRESTA or FREEND are to be changed [0957] * then word locations >8308 and >830A must be changed and [0958] * not expansion RAM. [0959] * [0960] * LDDNE - LDNE2 [0961] * [0962] * DONE WITH LOAD [0963] * Put FRESTA, FREEND back into expansion RAM [0964] * If FRESTA is odd then make it even [0965] * so that the next program starts on an even boundry [0966] C1BA DA,09,01 LDDNE CLOG 1,@FRESTA+1 Low byte odd? [0967] C1BD 61,C1 BS GC1C1 [0968] C1BF 91,08 DINC @FRESTA Force to next even boundry [0969] C1C1 BF,16,83 GC1C1 DST FRESTA,@VARB Source C1C4 08 [0970] C1C5 BF,00,20 DST FSLOC,@VAR0 Destination C1C8 02 [0971] C1C9 BF,5C,00 DST 4,@ARG Load 4 bytes C1CC 04 [0972] C1CD 0F,89 XML MVUP CPU RAM to ERAM [0973] C1CF 06,C2,77 CALL CLSIT Close file [0974] * Check for end of load command ")" [0975] C1D2 D6,42,B6 LDNE2 CEQ RPARZ,@CHAT Check for ")" [0976] C1D5 61,E1 BS LDRET [0977] C1D7 D6,42,B3 CEQ COMMAZ,@CHAT Syntax error [0978] C1DA 45,30 BR ERRSY1 [0979] C1DC 0F,79 XML PGMCHR Skip comma [0980] C1DE 05,C0,4E B LDP1 Continue in main loop [0981] *************** LDRET - LDRET2 **************************** [0982] * [0983] * Return to calling routine [0984] C1E1 0F,79 LDRET XML PGMCHR Skip over [0985] * Entry point for INIT [0986] C1E3 06,6A,78 LDRET2 CALL CHKEND Check for end of statement [0987] C1E6 45,30 BR ERRSY1 If not end then syntax error [0988] C1E8 06,00,12 CALL RPL Return to caller [0989] ********************** CHKIN ****************************** [0990] * Check for INIT-FLAG = >AA55 [0991] * MOVE ERAM(INITF) to CPU *FAC [0992] C1EB PAGE EQU $ [0993] C1EB BF,00,83 CHKIN DST FAC,@VAR0 Destination C1EE 4A [0994] C1EF BF,16,20 DST INITF,@VARB Source C1F2 06 [0995] C1F3 BF,5C,00 DST 2,@ARG 2 bytes C1F6 02 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0017 EQUATES ALCS-359 [0996] C1F7 0F,89 XML MVUP Move it [0997] C1F9 D7,4A,AA DCEQ >AA55,@FAC Syntax error C1FC 55 [0998] C1FD 45,33 BR ERRSYN [0999] * No files have been opened so if there is a syntax error [1000] * goto ERRSYN! [1001] C1FF 00 RTN [1002] *********************** FILE ROUTINES ********************* [1003] *********************************************************** [1004] * INCREMENT BUFFER POINTER by value after call statement [1005] * ADD VALUES READ TO CHECKSUM unless the first character [1006] * is a "7" = >37 , then add only "7" character to checksum [1007] * (other value is the checksum) [1008] * [1009] *************************** LDIPCS ************************ [1010] C200 88,15 LDIPCS FETCH @INDEXC Index = # of bytes read [1011] C202 D6,B0,0E CEQ >37,V*BUFPNT C205 37 [1012] C206 42,13 BR GC213 [1013] C208 A3,02,00 DADD >0037,@CHKSUM Add value of "7" to checksum C20B 37 [1014] C20C A3,0E,00 DADD 5,@BUFPNT 1 for "7", 4 for checksum C20F 05 [1015] C210 05,C2,24 B GC224 [1016] C213 BC,4B,B0 GC213 ST V*BUFPNT,@FAC1 Convert to 2 byte value C216 0E [1017] C217 86,4A CLR @FAC ----------------------------- [1018] C219 A1,02,4A DADD @FAC,@CHKSUM Add char to checksum [1019] C21C 91,0E DINC @BUFPNT [1020] C21E 92,15 DEC @INDEXC Do it index # of times [1021] C220 8E,15 CZ @INDEXC [1022] C222 42,13 BR GC213 [1023] C224 00 GC224 RTN [1024] ********************** OPENIT ***************************** [1025] C225 BD,0C,50 OPENIT DST @FAC6,@BYTES Store actual spec length [1026] C228 A3,0C,00 DADD PABLEN+80,@BYTES Add in the PAB length and C22B 5A [1027] * buffer length [1028] C22C 0F,77 XML VPUSH Push possible temp string [1029] C22E 0F,71 XML GETSTR and try to allocate space [1030] C230 0F,78 XML VPOP Restore original string data [1031] * [1032] * THE FOLLOWING VARIABLES CONTAIN IMPORTANT INFO [1033] * [1034] * FAC4, FAC5 Start address of original device specific [1035] * FAC6, FAC7 Length of original device specifications [1036] * SREF Location of PAB in VDP memory [1037] * BYTES Length of entire PAB including specificat [1038] C232 34,50,E0 MOVE @FAC6,V*FAC4,[email protected](@SREF) C235 0A,1C,B0 C238 4E [1039] C239 86,B0,1C CLR V*SREF Clear the entire PAB [1040] C23C 35,00,09 MOVE PABLEN-1,V*SREF,[email protected](@SREF) C23F E0,01,1C C242 B0,1C [1041] C244 BC,E0,09 ST @FAC7,[email protected](@SREF) Copy specifications length C247 1C,51 [1042] C249 BE,E0,08 ST >60,[email protected](@SREF) Screen offset C24C 1C,60 [1043] C24E BE,E0,01 ST 4,[email protected](@SREF) Dis, fix, seq, input C251 1C,04 [1044] C253 A1,50,1C DADD @SREF,@FAC6 Calculate the address of [1045] C256 A3,50,00 DADD PABLEN,@FAC6 the buffer C259 0A 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0018 EQUATES ALCS-359 [1046] C25A BD,E0,02 DST @FAC6,[email protected](@SREF) Store buffer address in PAB C25D 1C,50 [1047] C25F 06,C2,7B CALL DSRCAL [1048] C262 00 RTN [1049] *********************************************************** [1050] C263 BD,0E,E0 READIT DST [email protected](@SREF),@BUFPNT INIT buffer pointer C266 02,1C [1051] C268 BE,B0,1C ST 2,V*SREF C26B 02 [1052] C26C BC,E0,05 ST [email protected](@SREF),[email protected](@SREF) C26F 1C,E0,04 C272 1C [1053] C273 06,C2,7B CALL DSRCAL [1054] C276 00 RTN [1055] ************************* CLSIT *************************** [1056] C277 BE,B0,1C CLSIT ST 1,V*SREF Prepare to close C27A 01 [1057] ******************** DSRCAL - DSKERR ********************** [1058] C27B BD,56,1C DSRCAL DST @SREF,@FAC12 Compute start address of spec [1059] C27E A3,56,00 DADD NLEN,@FAC12 Ready to call DSR routine C281 09 [1060] C282 06,00,10 CALL DSR Call DSR thourgh program link [1061] C285 08 BYTE 8 * Type = DSR ( [1062] C286 62,90 BS DSKERR Couldn't find the DSR [1063] C288 DA,E0,01 CLOG >E0,[email protected](@SREF) Set condition bit if no error C28B 1C,E0 [1064] C28D 42,90 BR DSKERR [1065] C28F 00 RTN [1066] C290 BD,04,40 DSKERR DST @FREPTR,@PABPTR Set up dummy PAB [1067] C293 A7,04,00 DSUB 6,@PABPTR Make it standard size C296 06 [1068] C297 BD,E0,04 DST V*SREF,[email protected](@PABPTR) Store error code C29A 04,B0,1C [1069] C29D 06,C2,A4 CALL CLSNOE Close File [1070] C2A0 06,6A,84 CALL ERRZZ Issue I/O error [1071] C2A3 24 BYTE 36 * [1072] ********************** CLSNOE ***************************** [1073] * Try to close the current file [1074] * Ignore any errors from the closing of the file. [1075] * Since the PAB is not in the normal PAB list [1076] * then we have to close the file in the load routine. [1077] * ERRZZ will close the rest of the files. [1078] * [1079] ** CLOSE IT ONLY IF IT HAS BEEN OPENED [1080] C2A4 D7,02,00 CLSNOE DCEQ 1,@CHKSUM Check file flag C2A7 01 [1081] C2A8 62,B9 BS GC2B9 [1082] C2AA BE,B0,1C ST 1,V*SREF Store close file code C2AD 01 [1083] C2AE BD,56,1C DST @SREF,@FAC12 Compute start address of spec [1084] C2B1 A3,56,00 DADD NLEN,@FAC12 Ready to CALL DSR C2B4 09 [1085] C2B5 06,00,10 CALL DSR CALL DSR through program link [1086] C2B8 08 BYTE 8 * "8" is type of DSR [1087] C2B9 00 GC2B9 RTN [1088] *********************************************************** [1089] * INIT JDH 9/02/80 [1090] *********************************************************** [1091] * Check if expansion RAM present [1092] * Load support into expansion RAM from GROM [1093] C2BA 8E,80,84 INIT CZ @RAMTOP If no ERAM, SYNTAX ERROR [1094] C2BD 65,33 BS ERRSYN [1095] ** Load Assembly header, support routines ** [1096] * GKXB Correct INIT routine. 99/4 GPL-ASSEMBLER (Pass 3) correct PAGE 0019 EQUATES ALCS-359 [1097] C2BF 31,04,EA MOVE >04EA,[email protected],@>2000 C2C2 8F,9D,00 C2C5 98,00 [1098] C2C7 05,C1,E3 B LDRET2 [1099] *********************************************************** Missed this stuff in original post so have to edit this post: [1624] C62D 0F,77 GKINIT XML VPUSH Save FAC [1625] C62F 06,C1,EB CALL CHKIN Check for GKINIT [1626] C632 0F,78 XML VPOP Restore FAC [1627] C634 DA,80,C2 CLOG >C,@GKFLAG Error if POKEG or POKEV C637 0C [1628] C638 45,33 BR ERRSYN [1629] C63A 05,C2,25 B OPENIT Open the file Just look at he freaking code and it shows the Assembly people did not know that GPL had the MOVE instruction or that requirements of CALL INIT before CALL LOAD was implemented despite using CALL LOAD instead of a separate CALL POKE like everyone else in Basic or Extended Basic's! It must have been extremely frustrating for the GPL to be forced to accommodate the Assembly people in measures like this. I assume Assembly MANAGEMENT insisted on this ignorant short sided use of same CALL LOAD for both files and POKE. And Miller Graphics also agreed with me on this BUG that created so many issues. Why would you need to use CALL INIT if you wanted to CALL LOAD with just data into Expansion RAM anywhere in the RAM and use that RAM? And you are right if the entire point is to hamstring the system users on purpose, goal accomplished. Edited July 13, 2017 by RXB Quote Share this post Link to post Share on other sites
apersson850 #16 Posted July 13, 2017 TI XB uses CALL LOAD as a CALL POKE, trouble is I know the source one hell of lot better than you do. It was a mistake, bug, stupid oversight or whatever you want to call it. Who in right mind would make a CALL POKE that will not work unless you have Expanded memory? Why? As I know the GPL source inside out for over 20 years I think I know a bug when I see one. The point I was making is that it's not "whatever you want to call it". A bug is something that doesn't work as intended. Period. The behavior of CALL LOAD is clearly intended. By design. One can argue that it was anything from the right thing to do via a slight oversight down to downright stupid to not allow POKE, PEEK, POKEV and PEEKV in Extended BASIC, regardless of whether there is any memory expansion or not. But it's not a bug. If you take a step back and look at what TI probably had in their mind, when they originally designed the TI 99/4, then it makes more sense. They came from the calculator division. They had been successful with the TI-59 and its software modules. They thought they'd make a super calculator, with a rather limited BASIC and pre-programmed modules for most everything they imagined people would otherwise. It took them a long time to even come up with the Editor/Assembler package, as they thought software was better developed on a TI-990, using the DX10 assembler, than on the TI 99/4A itself. From that point of view, not allowing the user's to poke into memory unless they do intend to load assembly programs (they've executed CALL INIT) seems rather logical. TI obviously didn't think too much about the exploring users, who want to dig into the interior of the system. Like you have done with Extended BASIC and I've done with the UCSD p-system. But there it was a bit easier, since the p-system wasn't designed by TI, but by people who actually thought you may want to port it to another computer system. Thus the internal architecture is described in good detail, and in documents that are published. But it's not a bug. It's bad design choice. 2 Quote Share this post Link to post Share on other sites
+RXB #17 Posted July 13, 2017 (edited) OK BAD DESIGN, BAD CHOICE, BAD CONCEPT. Also pretty much non standard and goofy. This reminds me of the old USSR that made 1.2 million left shoes and no right shoes as a management choice. Edited July 13, 2017 by RXB Quote Share this post Link to post Share on other sites
Casey #18 Posted July 13, 2017 This discussion leaves me curious. Extended BASIC with no memory expansion returns * SYNTAX ERROR for CALL LINK/LOAD/INIT/PEEK - yet it seems the code is in the Extended BASIC GROM and not added by the 32K memory expansion peripheral as it would seem. It seems odd to me that the error handling would be such to return a syntax error on a statement that is legal. If nothing else, why not a * NO MEMORY EXPANSION error message? CALL LOAD is even worse. It returns a syntax error until you've run CALL INIT. Oddly, with Editor/Assembler in place, it's version of CALL LOAD does not require CALL INIT, but it's version of CALL LOAD also does not allow you to do CALL LOAD("CS1") where the one in Extended BASIC does. Just strange to me they would behave differently. Quote Share this post Link to post Share on other sites
+RXB #19 Posted July 14, 2017 This discussion leaves me curious. Extended BASIC with no memory expansion returns * SYNTAX ERROR for CALL LINK/LOAD/INIT/PEEK - yet it seems the code is in the Extended BASIC GROM and not added by the 32K memory expansion peripheral as it would seem. It seems odd to me that the error handling would be such to return a syntax error on a statement that is legal. If nothing else, why not a * NO MEMORY EXPANSION error message? CALL LOAD is even worse. It returns a syntax error until you've run CALL INIT. Oddly, with Editor/Assembler in place, it's version of CALL LOAD does not require CALL INIT, but it's version of CALL LOAD also does not allow you to do CALL LOAD("CS1") where the one in Extended BASIC does. Just strange to me they would behave differently. YES! As one of the few GPL programmers I see this code and just shake my head in disbelief at how stupid this programming looks. Really SYNTAX ERROR for CALL INIT and no Expansion RAM???? This is a logical standard? Why Miller Graphics GRAM KRACKER XB fixed this and added CALL POKEV, CALL PEEKV and CALL POKE as an option to be a more logical standard. Quote Share this post Link to post Share on other sites
notwhoyouthink #20 Posted July 14, 2017 (edited) I'll just be as blunt as i can here: RXB, you are know gpl. Probably better then anyone else here. Would it or would it not be possible to write a program (loaded from tape, with something like playground) that patches TI-XB to act like your Rich extended basic, that is, allow load without init? That is, force the init, direct from gpl/assembly, then jump back to XB? Edited July 14, 2017 by notwhoyouthink Quote Share this post Link to post Share on other sites
+RXB #21 Posted July 14, 2017 (edited) I'll just be as blunt as i can here: RXB, you are know gpl. Probably better then anyone else here. Would it or would it not be possible to write a program (loaded from tape, with something like playground) that patches TI-XB to act like your Rich extended basic, that is, allow load without init? That is, force the init, direct from gpl/assembly, then jump back to XB? Unfortunately only way is to do something like Playground that exploits a bug in the TI99/4A. LOAD DST >0001,@CHKSUM {INITIALIZE FILE FLAG} This is first line of XB CALL LOAD in GPL and as you can see it just assumes CALL LOAD is ONLY for FILES! Adding the later code for CALL LOAD to do a CALL POKE was clearly a afterthought, as was the idiotic idea that no one would ever use CALL LOAD for anything else? What should happen is it looks for a string (path.file) and set the file flag, if not string assumes it is a address POKE so does not need to set CHKSUM as no file loaded. But instead it does 3 things wrong, first assumes only file access, second assumes init for file must be loaded before you can POKE a address, third says SYNTAX ERROR? Unless you bypass the GPL code like RXB, how would you get this to work? Edited July 14, 2017 by RXB Quote Share this post Link to post Share on other sites