Gazoo Posted August 16, 2014 Share Posted August 16, 2014 (edited) I decided to start a new topic for this, as it's getting mucked up in the topic that it's currently in. I don't know if anyone has previously done this, but I've managed to store an XB program and run it from cartridge ROM. Senior Falcon and Insane Multitasker have provided valuable insight on how to do this. Thanks, Guys! The memory areas of the program including VDP, scratchpad, and the program itself need to be saved after loading, but BEFORE running the program. This can be accomplished by a memory dump in Classic99. The EA5 program must then restore those areas and GPLLNK into XB at address >64DA. The program I used is a decimal to hex converter that I was unable to find in EA5 format. To test, load the XB v2.7 Suite cart in Classic99, select the disk I've attached as DSK1, select B from the main menu (TI Writer/Assembler), then 6 (Run Program File), then enter to run DSK1.UTIL1. If you hit F4 real quick after doing that, you can break the program before it starts. Then you can list it, or save it back into it's original XB format. This opens the door for an ubergrom cart with a bunch of XB programs on it, way cool. demo.dsk Gazoo Edited August 17, 2014 by Gazoo 2 Quote Link to comment Share on other sites More sharing options...
RXB Posted August 17, 2014 Share Posted August 17, 2014 Hmm using XB 2.7 does not work. Where is XB 2.7 Suite cart? Would like to see what you have done here it looks intriguing. Quote Link to comment Share on other sites More sharing options...
Gazoo Posted August 17, 2014 Author Share Posted August 17, 2014 (edited) Yes, it does work. I would not have posted it if it didn't. Follow the directions in post #1 in this topic and you will succeed. Link to XB v 2.7 suite: http://atariage.com/forums/topic/223979-setting-up-a-632k-cart/page-4?do=findComment&comment=3025559 What all of sudden is not "messed up" about my programming approach and how did I miss something "so freaking simple" that really has nothing to do with this? What a messed up way to fix the problem using >64DA in XB. My RXB CALL EXECUTE(cpu-address) avoids all that and can be used like a CALL LINK with none of the hassles. 1 hidden loader here with EA5 program in XB program 10 CALL EXECUTE(CPU ADDRESS) As the RXB EXECUTE uses BLWP you can even use the entire FAST RAM if you just do a move the 256 bytes to a safe location, then before you end the EA5 program move the 256 bytes back and do a RTWP How freaking simple can that get? Edited August 17, 2014 by Gazoo Quote Link to comment Share on other sites More sharing options...
Tursi Posted August 17, 2014 Share Posted August 17, 2014 If you're interested in an enhancement - when we did the code that saved and restored a TI BASIC program, we disabled FCTN-4 to break the program by installing an interrupt hook that checked for FCTN-4 itself, and reset if it was detected. Not sure if you already did something or there's a better way already Quote Link to comment Share on other sites More sharing options...
Gazoo Posted August 17, 2014 Author Share Posted August 17, 2014 If you're interested in an enhancement - when we did the code that saved and restored a TI BASIC program, we disabled FCTN-4 to break the program by installing an interrupt hook that checked for FCTN-4 itself, and reset if it was detected. Not sure if you already did something or there's a better way already Once the program starts up, fctn4 is disabled. But you get a chance to break it before that command is run, which is ok as it's not that important. I am curious as to who "we" are and what "we" did to save and restore a TI Basic program, though. Gazoo Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 17, 2014 Share Posted August 17, 2014 Sounds like you are making good progress! I still think it is possible to make a memory image of the computer and then start up an already running program. I am on vacation and don't have access to my computer to test this stuff but let me throw out a couple more ideas: Consider this outline for an XB program: 100-390 Program statements to define characters and print the screen 400 CALL LINK("IMAGE") 410 Program goes on... And the A/L sub is pretty simple: IMAGE JMP IMAGE So now when you run the program the screen and characters are set up and the program hangs up at line 400. It sounds like you can make an image of the entire computer memory using Classic99 at this point. Then, if your loader restores the memory in toto it will think you are at line 400 inside the A/L sub. At this point you should be able to return to XB with LWPI >83E0 and B @>006A. Here's another idea: If the XB program is not huge you can use a CALL LOAD to turn off the memory expansion, then load the program. Now it is running in VDP and only VDP and the scratchpad need to be saved. Since I don't think you can do A/L subs with the memory turned off try 400 GOTO 400. The program hangs up at line 400 and you can make an image of VDP and scratchpad. Now when your loader restores the program have it then look in the line number table for line 400 and modify the code in that line to be GOTO 410. If the program counter, workspace and status are restored it should resume where it left off but now jumps out of the endless loop when it finds GOTO 410. I don't remember the CALL LINK but if you can't find out, it is in the PLAYGROUND docs in the section on how to run a PLAYGROUND program in XB. Running XB out of VDP will be about 1% slower which shouldn't even be noticeable. Sorry to keep bringing this up, it seems silly to do all the startup processes in XB if it can be avoided. 2 Quote Link to comment Share on other sites More sharing options...
Gazoo Posted August 17, 2014 Author Share Posted August 17, 2014 This one starts up much faster and cleaner than the other one. Same directions as before. I've got it on a real cart and have never seen an XB program start up so fast before. This demo is a little slower as it loads an EA5 image instead of a direct ROM to RAM move as in the cart. But it's still real quick. demo1.dsk Gazoo Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted August 17, 2014 Share Posted August 17, 2014 I found what I was looking for in Brad's XBPacker. I included the source disk for reference. BANKX2 LWPI GPLWS get ready for return to XB CB @FF,@>8344 is an XB program running? JNE BANKX if not, just exit CLR @>8342 else, zero out current token LI R6,>601E and restart the new XB program using "run" from B @GPL (>60) GPL branch table. Thanks Winfried Winkler! XBPacker AMS SAMS 12 SourcePC99.DSK Quote Link to comment Share on other sites More sharing options...
Gazoo Posted August 17, 2014 Author Share Posted August 17, 2014 (edited) I found what I was looking for in Brad's XBPacker. I included the source disk for reference. BANKX2 LWPI GPLWS get ready for return to XB CB @FF,@>8344 is an XB program running? JNE BANKX if not, just exit CLR @>8342 else, zero out current token LI R6,>601E and restart the new XB program using "run" from B @GPL (>60) GPL branch table. Thanks Winfried Winkler! XBPacker AMS SAMS 12 SourcePC99.DSK Interesting. Thanks! One of the changes I had to make in my program was to place an >FF at >8344 to avoid the color change from dark blue to cyan. This example code should prove enlightening. Gazoo EDIT: And it includes the Miller/Warren GPLLNK code!!!! I've been trying to re-find that for like forever!!!!!! Edited August 17, 2014 by Gazoo Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 23, 2014 Share Posted August 23, 2014 (edited) This is a "proof of concept" demo. I have taken the old HCM backgammon game and am running it in VDP ram which simplifies things a bit. To turn off the memory expansion simply CALL INIT::CALL LOAD(-31868,0,0). I was surprised to find that CALL LOAD, CALL LINK, etc. which depend on the memory expansion still work normally! I wrote a small subroutine that saves the contents of VDP from >0000 to >37D7 and also the contents of the scratchpad. I added 305 CALL LINK("START") to create the memory image at that point. Another short program runs from XB (but could easily be modified to run in EA5) and restores the VDP and scratchpad, then returns to XB at line 305. This bypasses the prescan, character definitions, and other initialization lines in the XB program, so it starts up much faster. This is NOT compiled as the program listing shows and the program can be run if desired from the beginning with RUN. The source code is attached and you are welcome to build on this idea. (edit) Here is what to do If you want to try this out for yourself on a different XB program. First re-download the zip file which now has the object code files and unpack it. Then:CALL INIT::CALL LOAD("DSK4,IMAGESAV-O") (IMAGESAV-S.TXT is the source code for this)CALL LOAD(-31868,0,0) to turn off memory expansion for XBLoad the XB program - it must fit in about 12K and use no assembly subroutines.Determine the line where you want to save the memory image and add CALL LINK("START") after that line.RUN the program. When START is performed two files will be written to DSK4; BKGMVDP and BKGMPAD, then the computer quits. Go back into XB and load the XB program GAMMON2. This is a short XB program with IMAGERES-O embedded in high memory. When you RUN this program it uses DSK4.BKGMVDP and DSK4.BKGMPAD to restore the VDP and scratchpad, and then returns to XB from the A/L sub it thinks it is in and resumes running the program right after the CALL LINK("START") If you want to change the filenames or disk number you have to modify the source code and reassemble. This needs to be made more universal by allowing for different filenames, as well as adding some intelligence to what gets saved. i.e. low memory if A/L subs are used and high memory if running XB without turning off the memory expansion. Also, just save the memory locations actually used by the program. One other minor change is necessary: when you restore the scratchpad you are also restoring the random number seed and will always get the same random number. HMLOADER was used to embed the object file IMAGERES-O in an XB program and then a couple of XB lines were added: CALL INIT and CALL LINK("START") For more info see the docs for HMLOADER in The Missing Link manual BACKGAMMON.zip Edited August 24, 2014 by senior_falcon 1 Quote Link to comment Share on other sites More sharing options...
ti99_forever Posted August 23, 2014 Share Posted August 23, 2014 Just curious, can you test something for me? The ability to run from GROM has always been possible (such as the PRK module). I played with this, but there is a bug in RESTORE. It is coded to expect to be executing from VDP. Of course this is TI BASIC, not Extended BASIC. So, wondering if you'd test RESTORE? Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 23, 2014 Share Posted August 23, 2014 Just curious, can you test something for me? The ability to run from GROM has always been possible (such as the PRK module). I played with this, but there is a bug in RESTORE. It is coded to expect to be executing from VDP. Of course this is TI BASIC, not Extended BASIC. So, wondering if you'd test RESTORE? I have no idea how to test something like that. Quote Link to comment Share on other sites More sharing options...
ti99_forever Posted August 23, 2014 Share Posted August 23, 2014 Easy. Something like: 10 DATA 1,2,3,4,5 15 FOR I=1 TO 5 20 READ A,B,C,D,E 30 PRINT A,B,C,D,E 40 RESTORE 10 ! or just RESTORE 50 NEXT I The bug will show when it hits the RESTORE statement in line 40. You'll get an error. It has been a while since I did this... Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 23, 2014 Share Posted August 23, 2014 This works fine for me in both XB and BASIC running normally. I have no idea how to run a BASIC program out of GROM. Quote Link to comment Share on other sites More sharing options...
ti99_forever Posted August 23, 2014 Share Posted August 23, 2014 I mean running from ROM. Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 23, 2014 Share Posted August 23, 2014 I guess I wasn't clear that the memory images are saved as disk files, not stored in RAM or ROM somewhere. When GAMMON2 runs it reads those disk files and restores the memory areas from them. This should be totally compatible with real iron running with 32K and a disk drive. Quote Link to comment Share on other sites More sharing options...
RXB Posted August 24, 2014 Share Posted August 24, 2014 This is a "proof of concept" demo. I have taken the old HCM backgammon game and am running it in VDP ram which simplifies things a bit. To turn off the memory expansion simply CALL INIT::CALL LOAD(-31868,0,0). I was surprised to find that CALL LOAD, CALL LINK, etc. which depend on the memory expansion still work normally! I wrote a small subroutine that saves the contents of VDP from >0000 to >37D7 and also the contents of the scratchpad. I added 305 CALL LINK("START") to create the memory image at that point. Another short program runs from XB (but could easily be modified to run in EA5) and restores the VDP and scratchpad, then returns to XB at line 305. This bypasses the prescan, character definitions, and other initialization lines in the XB program, so it starts up much faster. This is NOT compiled as the program listing shows and the program can be run if desired from the beginning with RUN. The source code is attached and you are welcome to build on this idea. Try this without a 32K memory expansion as I am pretty sure that without Lower 8K CALL LINK does not use any other memory unless you use the EA cart or Mini Memory CALL LINK but those do not work the same a the XB CALL LINK does.. I have the GPL source code for both in RXB and REA. Look at line 1354 it shows it only executes from >2000 so the memory explains has to have been on as CALL LINK("ANYNAME") will only function from XB lower 8K. *********************************************************** [1161] * LINK INSTRUCTION : SE Sep 1980 [1162] *********************************************************** [1163] * FORMAT: [1164] * CALL LINK("file-name",parameter1,parameter2,...) [1165] * [1166] * LINK ROUTINE READS THE FILE NAME SPECIFIED BY THE USER A [1167] * SAVE THE ADDRESS OF THE NAME FOR LATER USE. THE FILE WIL [1168] * BE SEARCHED IN UTILITY CODE LATER ON. [1169] * [1170] * PARAMETERS ARE PASSED EITHER BY REFERENCE OR BY VALUE. [1171] * NUMERIC OR STRING VARIABLES AND NUMERIC OR STRING ARRAYS [1172] * ARE PASSED BY REFERENCE AND ALL OTHERS INCLUDING A USER [1173] * DEFINED FUNCTION ARE PASSED BY VALUE. [1174] * [1175] * PARAMETER INFORMATION IS STORED IN CPU >8300 THROUGH >83 [1176] * THAT GIVES A PARAMETER TYPE CODE OF EACH PARAMETER. [1177] * CODE 0 ... Numeric expression [1178] * CODE 1 ... String experession [1179] * CODE 2 ... Numeric variable [1180] * CODE 3 ... String variable [1181] * CODE 4 ... Numeric array [1182] * CODE 5 ... String array [1183] * [1184] * IF A PARAMETER IS PASSED AS A NUMERIC EXPRESSION ITSL [1185] * ACTUAL VALUE GETS PUSHED INTO THE VALUE STACK. IN CASE O [1186] * A STRING EXPRESSION , ITS VALUE STACK CONTAINS AN ID(>65 [1187] * POINTER TO THE VALUE SPACE AND ITS LENGTH. IF A PARAMETE [1188] * GETS PASSED AS A REFERENCE THE PRODUCT OF XML SYM AND XM [1189] * SMB IN THE @FAC AREA GETS PUSHED INTO STACK. [1190] * [1191] * AFTER AN ASSEMBLY LANGUAGE SUBPROGRAM IS EXECUTED LINK [1192] * ROUTINE WILL POP THE STACK TO GET RID OF PARAMETER [1193] * INFORMATION. CONTROL WILL BE TRANSFERED TO THE XB MAIN [1194] * PROGRAM AFTERWARDS. [1195] * [1196] *********************************************************** [1197] * CALL LINK program [1198] *********************************************************** [1199] C325 06,C1,EB LINKIT CALL CHKIN Check if INIT has been called [1200] C328 BD,10,6E DST @VSPTR,@OLDS Save VSPTR for later use [1201] C32B D6,42,B7 CEQ LPARZ,@CHAT Check for "(" [1202] C32E 45,33 BR ERRSYN [1203] C330 0F,79 XML PGMCHR Advance program pointer [1204] C332 0F,74 XML PARSE Get the routine name. [1205] C334 B6 BYTE RPARZ * Read up to ")" [1206] C335 D6,4C,65 CEQ >65,@FAC2 Should be a string [1207] C338 45,9A BR ERRBA [1208] C33A 8F,50 DCZ @FAC6 Don't accept null string [1209] C33C 65,9A BS ERRBA [1210] C33E C6,51,06 CH 6,@FAC7 Should be less then 6 char [1211] C341 65,9A BS ERRBA [1212] C343 0F,77 XML VPUSH Push to make it semi-permanen [1213] C345 86,12 CLR @COUNT Initialize parameter counter [1214] *********************************************************** [1215] * PARAMETERS get evaluated here [1216] *********************************************************** 99/4 GPL-ASSEMBLER (Pass 2) aborted PAGE 0021 EQUATES ALCS-359 [1217] C347 D6,42,B6 PAR01 CEQ RPARZ,@CHAT No arg. So execute it [1218] C34A 64,05 BS EXE01 [1219] C34C D6,42,B3 CEQ COMMAZ,@CHAT Should have a comma [1220] C34F 45,33 BR ERRSYN [1221] C351 BD,22,2C DST @PGMPTR,@ERRCOD Save text pointer [1222] C354 0F,79 XML PGMCHR Get the character [1223] C356 CA,42,80 CHE >80,@CHAT Must be an expression [1224] C359 63,C7 BS VAL01 [1225] * If CHAT = LPARZ then pass by expression [1226] C35B 06,C4,2C CALL CLRFAC Clear FAC entry for SYM [1227] C35E 0F,7A XML SYM Read in the symbol table info [1228] * After XML SYM @FAC area contains a pointer to symbo table [1229] * Below statement checks if it is a UDF. [1230] C360 DA,B0,4A CLOG >40,V*FAC Pass by value C363 40 [1231] C364 43,C7 BR VAL01 [1232] C366 D6,42,B3 CEQ COMMAZ,@CHAT Pass by reference [1233] C369 63,E5 BS REF01 [1234] C36B D6,42,B6 CEQ RPARZ,@CHAT Pass by reference [1235] C36E 63,E5 BS REF01 [1236] C370 D6,42,B7 CEQ LPARZ,@CHAT An array [1237] C373 63,7C BS ARRAY [1238] C375 CA,42,80 CHE >80,@CHAT Pass by value [1239] C378 63,C7 BS VAL01 [1240] C37A 45,33 BR ERRSYN [1241] *********************************************************** [1242] * ARRAY case gets checked here [1243] *********************************************************** [1244] * Should look like A(,,) etc. [1245] * Stack entry for an array will look like [1246] * +--------------+-------+---+-------------+--------------- [1247] * | Pointer to | >00 | | Pointer to | [1248] * | symbol table | or | | dim info in | [1249] * | entry | >65 | | real v.s. | [1250] * +- FAC --------+ FAC2 -+---+- FAC4 ------+- FAC6 -------- [1251] * [1252] C37C 0F,79 ARRAY XML PGMCHR Get the next character [1253] C37E D6,42,B6 CEQ RPARZ,@CHAT Pass by reference [1254] C381 63,8F BS ARRAY2 [1255] C383 D6,42,B3 CEQ COMMAZ,@CHAT More array information [1256] C386 63,7C BS ARRAY [1257] C388 93,2C DDEC @PGMPTR Adjust the pointer [1258] C38A BE,42,B7 ST LPARZ,@CHAT [1259] C38D 43,E5 BR REF01 Pass by reference [1260] * In array cases the symbol table address gets stored at FA [1261] * area, and the pointer to the value space (dimension info) [1262] * goes into FAC4 [1263] C38F 0F,79 ARRAY2 XML PGMCHR Advance the program pointer [1264] C391 DA,B0,4A CLOG >80,V*FAC Test string bit C394 80 [1265] C395 43,9D BR GC39D [1266] C397 BE,90,12 ST 4,*COUNT Numeric array C39A 04 [1267] C39B 43,A1 BR GC3A1 [1268] C39D BE,90,12 GC39D ST 5,*COUNT String array case C3A0 05 [1269] * Check if array is being shared. If it is then go back [1270] * through the linkage to get the actuals symbol table [1271] * pointer. Put the pointer to the value space (dimension in [1272] * into FAC4. [1273] C3A1 DA,B0,4A GC3A1 CLOG >20,V*FAC Shared array? C3A4 20 [1274] C3A5 63,BE BS GC3BE [1275] C3A7 35,00,02 MOVE 2,V@6(@FAC),@FAC4 If so, get pointer 99/4 GPL-ASSEMBLER (Pass 2) aborted PAGE 0022 EQUATES ALCS-359 C3AA 4E,E0,06 C3AD 4A [1276] C3AE DA,EF,FF CLOG >20,V@-6(@FAC4) Shared also? C3B1 FA,4E,20 [1277] C3B4 63,BC BS GC3BC [1278] C3B6 35,00,02 MOVE 2,V*FAC4,@FAC4 Array is not shared C3B9 4E,B0,4E [1279] C3BC 43,C5 GC3BC BR GC3C5 [1280] C3BE BD,4E,4A GC3BE DST @FAC,@FAC4 Array is not shared [1281] C3C1 A3,4E,00 DADD 6,@FAC4 Point to value space C3C4 06 [1282] C3C5 43,FA GC3C5 BR PUSH [1283] *********************************************************** [1284] * VALUE [1285] * Passing the parameter by value [1286] *********************************************************** [1287] C3C7 BD,2C,22 VAL01 DST @ERRCOD,@PGMPTR Restore program pointer [1288] C3CA 0F,79 XML PGMCHR Skip the first character [1289] C3CC BD,16,0C DST @BYTES,@TEMP In case of passing a string [1290] C3CF 0F,74 XML PARSE Parsing up to comma [1291] C3D1 B6 BYTE RPARZ [1292] C3D2 BD,0C,16 DST @TEMP,@BYTES Restore the value in >0C area [1293] * After parsing @FAC area contains its actual numeric value [1294] * in a numeric case, and the following information in a [1295] * string case. [1296] * +----------------+-----+--+------------+----------------- [1297] * | >001C or | >65 | | Pointer to | Length of string [1298] * | value pointer | | | string | string [1299] * | address | | | | [1300] * +- FAC ----------+-FAC2+--+-FAC4 ------+- FAC6 ---------- [1301] * [1302] C3D5 CE,4C,63 CGT >63,@FAC2 If more then 99 then [1303] C3D8 43,E0 BR GC3E0 [1304] C3DA BE,90,12 ST 1,*COUNT Store flag for string express C3DD 01 [1305] C3DE 43,E3 BR GC3E3 [1306] C3E0 86,90,12 GC3E0 CLR *COUNT Otherwise it is a numeric exp [1307] C3E3 43,FA GC3E3 BR PUSH Push into stack [1308] *********************************************************** [1309] * REFERENCE [1310] * Passing the parameter by reference [1311] *********************************************************** [1312] * Variables, array element and whole array passing. [1313] * [1314] * After SMB @FAC entry shold look like; [1315] * +--------------+------+-----+-------------+-------------- [1316] * | Pointer to | >00 | | Pointer to | [1317] * | symbol table | | | value space | [1318] * | entry | | | | [1319] * +-- FAC -------+ FAC2 +-----+- FAC4 ------+- FAC6 ------- [1320] * for numeric case, and [1321] * +--------------+------+-----+-------------+-------------- [1322] * | Pointer to | >65 | | Pointer to | String [1323] * | value space | | | string | length [1324] * | entry | | | | [1325] * +- FAC --------+ FAC2 +-----+- FAC4 ------+- FAC6 ------- [1326] * for a string case. [1327] C3E5 0F,7B REF01 XML SMB Get the location [1328] C3E7 CA,42,B8 CHE >B8,@CHAT Pass array expression [1329] C3EA 63,C7 BS VAL01 [1330] C3EC 8E,4C CZ @FAC2 [1331] C3EE 43,F6 BR GC3F6 [1332] C3F0 BE,90,12 ST 2,*COUNT Must be a numeric variable C3F3 02 99/4 GPL-ASSEMBLER (Pass 2) aborted PAGE 0023 EQUATES ALCS-359 [1333] C3F4 43,FA BR PUSH [1334] C3F6 BE,90,12 GC3F6 ST 3,*COUNT Must be a string variable C3F9 03 [1335] *********************************************************** [1336] * PUSH routine [1337] * Pushes @FAC entry into a value stack. [1338] *********************************************************** [1339] C3FA 90,12 PUSH INC @COUNT [1340] C3FC CE,12,10 CGT 16,@COUNT Too many parameters [1341] C3FF 65,9A BS ERRBA [1342] C401 0F,77 XML VPUSH [1343] C403 43,47 BR PAR01 Get the next argument. [1344] *********************************************************** [1345] * EXECUTE routine [1346] * Restore file name info transfer control over to ALC [1347] *********************************************************** [1348] C405 BE,4A,20 EXE01 ST >20,@FAC Store blank in the FAC area. [1349] C408 35,00,05 MOVE 5,@FAC,@FAC1 C40B 4B,4A [1350] C40D 35,00,04 MOVE 4,V@12(@OLDS),@STORE Get the file name info C410 14,E0,0C C413 10 [1351] C414 34,16,4A MOVE @STORE+2,V*STORE,@FAC Move to FAC C417 B0,14 [1352] C419 87,22 DCLR @ERRCOD Clear program pointer for [1353] * error code [1354] C41B 0F,20 XML ALSUP Go to CPU at >2000 to execute [1355] C41D 64,C9 BS ERROR Error found [1356] * If no error, start checking s [1357] *********************************************************** [1358] * RETURN to the XB main program. [1359] *********************************************************** [1360] C41F C5,6E,10 NOERR DCH @OLDS,@VSPTR Pop the stack [1361] C422 44,29 BR GC429 [1362] C424 0F,78 XML VPOP Pop the stack [1363] C426 05,C4,1F B NOERR [1364] C429 05,A0,1C GC429 B LNKRTN Check ")" and end of statemen [1365] *********************************************************** [1366] * SUBROUTINES used in this file. [1367] *********************************************************** [1368] C42C 86,4A CLRFAC CLR @FAC [1369] C42E 35,00,07 MOVE 7,@FAC,@FAC1 C431 4B,4A [1370] C433 00 RTN [1371] *********************************************************** [1372] * CHARPAT ROUTINE 99/4A - JDH 10/01/80 [1373] *********************************************************** Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 24, 2014 Share Posted August 24, 2014 Rich, clearly the memory expansion is not fully turned off, otherwise the assembly language subroutines would have no place to be loaded into or run from. So CALL LINK, CALL LOAD, etc work normally and use the normal memory locations in low memory. However, the BASIC part of XB thinks there is no memory expansion after CALL INIT::CALL LOAD(-31868,0,0) as you can see in the second part of the video where it reports a SIZE of 422 bytes. Turning off the memory expansion as described opens up the possibility of having an XB program supported by 32K of assembly subroutines! Pretty cool, huh? I was in a hurry to post this this AM and neglected to include any instructions on using the subroutines. I will edit post #10 above and add some simple instructions in case someone wants to try this out using a different XB program. 1 Quote Link to comment Share on other sites More sharing options...
Gazoo Posted August 30, 2014 Author Share Posted August 30, 2014 (edited) This is a "proof of concept" demo. I have taken the old HCM backgammon game and am running it in VDP ram which simplifies things a bit. To turn off the memory expansion simply CALL INIT::CALL LOAD(-31868,0,0). I was surprised to find that CALL LOAD, CALL LINK, etc. which depend on the memory expansion still work normally! I wrote a small subroutine that saves the contents of VDP from >0000 to >37D7 and also the contents of the scratchpad. I added 305 CALL LINK("START") to create the memory image at that point. Another short program runs from XB (but could easily be modified to run in EA5) and restores the VDP and scratchpad, then returns to XB at line 305. This bypasses the prescan, character definitions, and other initialization lines in the XB program, so it starts up much faster. This is NOT compiled as the program listing shows and the program can be run if desired from the beginning with RUN. The source code is attached and you are welcome to build on this idea. (edit) Here is what to do If you want to try this out for yourself on a different XB program. First re-download the zip file which now has the object code files and unpack it. Then: CALL INIT::CALL LOAD("DSK4,IMAGESAV-O") (IMAGESAV-S.TXT is the source code for this) CALL LOAD(-31868,0,0) to turn off memory expansion for XB Load the XB program - it must fit in about 12K and use no assembly subroutines. Determine the line where you want to save the memory image and add CALL LINK("START") after that line. RUN the program. When START is performed two files will be written to DSK4; BKGMVDP and BKGMPAD, then the computer quits. Go back into XB and load the XB program GAMMON2. This is a short XB program with IMAGERES-O embedded in high memory. When you RUN this program it uses DSK4.BKGMVDP and DSK4.BKGMPAD to restore the VDP and scratchpad, and then returns to XB from the A/L sub it thinks it is in and resumes running the program right after the CALL LINK("START") If you want to change the filenames or disk number you have to modify the source code and reassemble. This needs to be made more universal by allowing for different filenames, as well as adding some intelligence to what gets saved. i.e. low memory if A/L subs are used and high memory if running XB without turning off the memory expansion. Also, just save the memory locations actually used by the program. One other minor change is necessary: when you restore the scratchpad you are also restoring the random number seed and will always get the same random number. HMLOADER was used to embed the object file IMAGERES-O in an XB program and then a couple of XB lines were added: CALL INIT and CALL LINK("START") For more info see the docs for HMLOADER in The Missing Link manual Would you mind trying to convert this one? I've tried several different methods without success. BERNIE.dsk Gazoo Edited August 30, 2014 by Gazoo Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted August 30, 2014 Share Posted August 30, 2014 BERNIE is too large to run from the VDP ram, so the method of saving just the VDP will not work. In order to do this, the program that saves the memory image has to be expanded as outlined above so that it saves the high memory areas. Quote Link to comment Share on other sites More sharing options...
Gazoo Posted August 30, 2014 Author Share Posted August 30, 2014 BERNIE is too large to run from the VDP ram, so the method of saving just the VDP will not work. In order to do this, the program that saves the memory image has to be expanded as outlined above so that it saves the high memory areas. I've been able to make a working version using the Insane Multitasker method, the Senior Falcon method was unsuccessful no matter what I did. Disk is attached. Source, object, and UTIL1/2 files are included. ERNBRT.DSK Gazoo Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted September 1, 2014 Share Posted September 1, 2014 I've been doing a bit of work on this program. Now it can make an image from an XB program running in either VDP or memory expansion. The random number bug is fixed. In the attached folder: BKGMXB, BKGMVDP, BKGMPAD are the backgammon program. BKGMXB can run from any disk but looks in disk 4 for BKGMVDP and BKGMPAD BERTXB, BERTVDP, BERTPAD are the files for the Bert & Ernie program. Setup is same as for backgammon above. If you want to try converting your on XB programs: IMAGESAVE.TXT and IMAGESAVE.OBJ are used to make the memory image files for VDP and PAD You can change the names and the disk number in the TXT file and reassemble. Determine where you want to save the XB program and add CALL LINK("MSAVE") at that point. Be sure to move any SCREEN and MAGNIFY so they are after MSAVE. Run the XB program and it will create the memory image files when it comes to MSAVE. This is smart enough to know whether the program is running out of VDP or expansion memory. IMAGEREST.TXT and IMAGEREST.OBJ are used to restore the memory image files. As before, modify the TXT file and reassemble if you want to change the file name or disk number. IMAGEREST.OBJ can be converted to an EA5 format program if desired. Here's how to make the XB loader: NEW CALL INIT CALL LOAD("DSK4.IMAGEREST.OBJ") CALL LOAD("DSK4.KWIKLOAD") - this is a loader similar to systex CALL LINK("X") then make this XB line: 10 CALL INIT::CALL LOAD(8192,255,154)::CALL LINK("X")::CALL LINK("MREST") The XB program must be less than about 12K long at present. More work must be done to save the full contents of the expansion memory. XB Memory image programs.zip 1 Quote Link to comment Share on other sites More sharing options...
+Ksarul Posted September 1, 2014 Share Posted September 1, 2014 Very nice bit of work! Quote Link to comment Share on other sites More sharing options...
Gazoo Posted September 1, 2014 Author Share Posted September 1, 2014 I agree with Ksarul, very nice! I see that the CALL QUIT in the original BERNIE program was REM'd out. Can you provide a version where that is restored to the original version so the program quits when it's finished? It would be nice to be able to create an EA5 version of this file that starts immediately and quits when done without the delay like in the one I created. Gazoo Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted September 1, 2014 Share Posted September 1, 2014 C'mon Gazoo - all the information and necessary files are in post #22. Give it a try and if you can't figure it out then I'll do it for you. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.