Jump to content
IGNORED

Save and Run an Extended Basic program from EA5 or ROM


Gazoo

Recommended Posts

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. :-D

 

demo.dsk

 

Gazoo

Edited by Gazoo
  • Like 2
Link to comment
Share on other sites

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 by Gazoo
Link to comment
Share on other sites

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 ;)

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

  • Like 2
Link to comment
Share on other sites

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

 

Link to comment
Share on other sites

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

 

 

 

 

Link to comment
Share on other sites

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!

attachicon.gifXBPacker 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 by Gazoo
Link to comment
Share on other sites

gallery_34177_1071_498738.gif

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

BACKGAMMON.zip

Edited by senior_falcon
  • Like 1
Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

gallery_34177_1071_498738.gif

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]               ***********************************************************
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

gallery_34177_1071_498738.gif

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 by Gazoo
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

  • Like 1
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...