Jump to content
IGNORED

Save and Run an Extended Basic program from EA5 or ROM


Gazoo

Recommended Posts

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.

 

There will be enough work involved in disassembling it at that point in order to create a true EA5 set of files that doesn't load any other additional files. :) That's the format that would be necessary to store the program in the ROM of a cartridge, my original intent in creating this topic. As it stands now, I would need to disassemble the xxxVDP and xxxPAD files as data, modify the assembly file loaded by Extended Basic to include the data from those 2 files in the assembly process instead of loading them from somewhere else, and then reassembling and linking the whole thing again.

 

Wanna save me a step? :)

 

Gazoo

Edited by Gazoo
Link to comment
Share on other sites

This might do the trick for you. There are 4 files in this folder:

GAZOO.TXT

GAZOO.OBJ

GAMMON

BERNIE

Bernie and Gammon are XB programs and I have added CALL LINK("SAVE") at what I think are good points to make a memory image. To use them in Classic99 type:

OLD DSK1.BERNIE

CALL INIT

CALL LOAD("DSK1.GAZOO.OBJ") (be sure to do this after loading the XB program)

RUN

The XB program runs till it comes to CALL LINK("SAVE"). This subroutine copies the pertinent areas of cpu and vdp memory after a loader that starts at >A000. The last address of the program is stashed at >3000 in case you need that. Then the computer quits.

Press a key, then press 2. The memory comes through this intact as long as there is no LOAD program on DSK1.

To see if it runs, type CALL LINK("RESTOR") which runs the loader starting at >A000. The memory areas are restored and the program should resume at the next instruction after the CALL LINK("SAVE"). No provision is made for using low memory at this point, so huge XB programs won't fit.

 

(edit) Forgot to mention that the loader will probably need lines to set the VDP registers to the XB values and also VMBW and VWTR routines, since you can't be sure CALL INIT will have been done.

GAZOO.zip

Edited by senior_falcon
Link to comment
Share on other sites

This might do the trick for you. There are 4 files in this folder:

GAZOO.TXT

GAZOO.OBJ

GAMMON

BERNIE

Bernie and Gammon are XB programs and I have added CALL LINK("SAVE") at what I think are good points to make a memory image. To use them in Classic99 type:

OLD DSK1.BERNIE

CALL INIT

CALL LOAD("DSK1.GAZOO.OBJ") (be sure to do this after loading the XB program)

RUN

The XB program runs till it comes to CALL LINK("SAVE"). This subroutine copies the pertinent areas of cpu and vdp memory after a loader that starts at >A000. The last address of the program is stashed at >3000 in case you need that. Then the computer quits.

Press a key, then press 2. The memory comes through this intact as long as there is no LOAD program on DSK1.

To see if it runs, type CALL LINK("RESTOR") which runs the loader starting at >A000. The memory areas are restored and the program should resume at the next instruction after the CALL LINK("SAVE"). No provision is made for using low memory at this point, so huge XB programs won't fit.

 

(edit) Forgot to mention that the loader will probably need lines to set the VDP registers to the XB values and also VMBW and VWTR routines, since you can't be sure CALL INIT will have been done.

 

Thanks! Well it works mostly, but apparently the character re-defs aren't saved expect for sprites. Everything runs ok with the exception of getting a 'RETURN WITHOT GOSUB" near the end.

 

Interesting screenshot... :)

 

gallery_29515_833_6154.jpg

 

BERNIE.dsk

 

To test, type CALL LOAD("DSK1.BERNIE1",1) from XB v2.7 command line. It works better in MESS than Classic99 as the speech is more accurate.

 

Gazoo

Link to comment
Share on other sites

What I posted works fine for me in regular XB. Maybe XB 2.7 maps the memory a little different. You could try regular XB to see if it makes a difference. Tonight or tomorrow I will add the ability to make EA5 type files and then we can really give it a test.

(Edit) I'll bet it is running as an EA5 program with the registers set to the EA values, hence no graphics.

Edited by senior_falcon
Link to comment
Share on other sites

Here are revised files to try out:

GAZOO.TXT

GAZOO.OBJ will now set the registers to the XB values and have their own VMBW.

 

Use as described above:

OLD DSK4.BERNIE

CALL INIT

CALL LOAD("DSK3.GAZOO.OBJ")

RUN

 

The program starts at >A00 and ends at the address stored in >3000. Enter the program at >A000

As a test I added a few lines to clear the pad, vdp and the cpu memory above the address pointed to by >3000. Then B @>A000 and the XB program starts right up where it was saved. This is using standard TI Extended BASIC.

 

I made EA5 files using Classic99 and tried to run them using Funnelweb and the XB cartridge in the slot. They crashed. I have no idea whether this is some clash with the loader or something else.

 

Anyway, maybe you can make this work for you.

GAZOO.zip

Link to comment
Share on other sites

Here are revised files to try out:

GAZOO.TXT

GAZOO.OBJ will now set the registers to the XB values and have their own VMBW.

 

Use as described above:

OLD DSK4.BERNIE

CALL INIT

CALL LOAD("DSK3.GAZOO.OBJ")

RUN

 

The program starts at >A00 and ends at the address stored in >3000. Enter the program at >A000

As a test I added a few lines to clear the pad, vdp and the cpu memory above the address pointed to by >3000. Then B @>A000 and the XB program starts right up where it was saved. This is using standard TI Extended BASIC.

 

I made EA5 files using Classic99 and tried to run them using Funnelweb and the XB cartridge in the slot. They crashed. I have no idea whether this is some clash with the loader or something else.

 

Anyway, maybe you can make this work for you.

 

Thanks for all your assistance, Senior Falcon. Something's missing and I'm not sure what it is. :(

 

Memory image files created from the memory dump after following your instructions work ok when loaded from within XB v2.7 by the CALL MLOAD command, but will not work when loaded from EA in Grom page 2 or by memory moves from Rom at >6000. I'm stumped at this point. I started another thread in the hopes of finding out EXACTLY what happens when an Extended Basic program is loaded. Boot and Menu both do this, and maybe their source code will provide some valuable insight, if anyone has either in their possession.

 

Maybe RXB (Rich) might also have some insight. I'd like to know exactly what happens after XB finds a program image file on a device. Apparently it's put into a buffer in VDP by the DSR on the device as any program image file would be. Then XB "works some sort of magic" with the data in the VDP buffer, (moves it to memory expansion?) and starts the program. I'm looking for someone to describe the "works some sort of magic" part. :)

 

Gazoo

Edited by Gazoo
Link to comment
Share on other sites

I wonder if the >6000 ROM is set to the wrong page. That might explain things.

 

No, that's not it. I reset it to the first bank (write to >6000) upon completing the moves from Rom and before branching to the start of the program. Tried the 2nd bank (write to >6002) also to make sure. :)

If it's any help, the error in the case of loading the program from Rom is always a syntax error in the line of the CALL LINK("SAVE").

The current error is SYNTAX ERROR IN 345, the line 'fixed' by the assembly code. A listing of line 345 shows no obvious error.

 

gallery_29515_833_22023.jpg

 

I had this same problem when originally trying to implement your idea. The line that the assembly-saved XB program tries to start with returns a syntax error regardless if it is a syntactically correct line or not. Makes no sense. :(

 

Gazoo

Edited by Gazoo
Link to comment
Share on other sites

This whole thing is getting pretty strange. For one thing, after the program quits you can return to XB and CALL LINK("RESTOR") and the program run fine. If you look at >FFE7 it will be zero. However, once you make the EA5 files and try to run it, FFE7 is something else, i believe it is >0C. But everything else around it seems to be the same.

 

I was getting errors like that and found that in SVLV I had to AI R2,8. You could try making that larger, maybe 24 or even larger.

*save low VDP ram is below
MOV R1,@LOVAD
MOV @>836E,R2 looks like this is always even
AI R2,8
MOV R2,*R1+ store length
CLR R0 start reading at v0000
BLWP @VMBR
A R2,R1 add length to pointer
SAVHI
*save high VDP ram is below 831A 8370
MOV R1,@HIVAD
MOV @>8370,R2 start of disk buffers
MOV @>831A,R0
S R0,R2 now r8 has # bytes in this block
INC R2
MOV R0,*R1+ starting address
MOV R2,*R1+
BLWP @VMBR
A R2,R1

Link to comment
Share on other sites

I wonder if the >6000 ROM is set to the wrong page. That might explain things.

The upper 4K page needs to switch back and forth so normally like in Classic99 that page switches the same lower 4K page.

If you start with the wrong page yea that would create some issues.

 

Never mind Gazoo said he tried that. But shared some info privately with Senior_falcon and it may help.

Edited by RXB
Link to comment
Share on other sites

I finally figured this out. One thing that isn't saved (because it can't be) is the grom address that will be read from next. When running as an EA5 program the grom pointer is not the same as when you are running via CALL LINK. On my TI XB cartridge >C41D should be the next grom address to be read when returning to XB. When that is set by the loader the program runs as expected, whether from E/A or from XB.

 

Is this address consistent between the various versions of XB? (This is the next grom address to be read from when returning from a CALL LINK subroutine.) Rich, can you shed some light on this??

Link to comment
Share on other sites

I finally figured this out. One thing that isn't saved (because it can't be) is the grom address that will be read from next. When running as an EA5 program the grom pointer is not the same as when you are running via CALL LINK. On my TI XB cartridge >C41D should be the next grom address to be read when returning to XB. When that is set by the loader the program runs as expected, whether from E/A or from XB.

 

Is this address consistent between the various versions of XB? (This is the next grom address to be read from when returning from a CALL LINK subroutine.) Rich, can you shed some light on this??

 

The following code is how I bounce out of extended BASIC "TI" mode into "Geneve" mode to utilize the Geneve's operating system device routines. Perhaps it will be of assistance with respect to the GROM and ROM bank save/restore you might need. Disregard the Geneve- and 9995-specific mapper code (8000-8007), the CRU instructions, and saving of 0xf000-0xf0ff.

 

 

DSRLNK DATA DREGS,$+2
       LIMI 0
       MOV  @0(R13),@PABADR+2 SET address of PAB
       MOVB @GRMRA,@GROM      SAVE GROM GARBAGE
       MOVB @GRMRA,@GROM+1
       DEC  @GROM
       MOV  @>7000,@S7000

       MOV  @>8000,@SAVE0     SAVE PAGE 0
       MOV  @>8002,@SAVE0+2
       MOV  @>8004,@SAVE0+4
       MOV  @>8006,@SAVE0+6

       MOVB @>8100,@>8000     PULL IN THE GENEVE PAGE
       LI   R1,>F000          save area for registers
       LI   R2,>8200
       LI   R3,128
SAVRG1 MOV  *R1+,*R2+
       DEC  R3
       JNE  SAVRG1

       LWPI GENWS             change workspaces
       LIMI 0
       LI   R12,>1EF4
       SBO  0                 geneve mode

PABADR LI   R0,>0000
       XOP  @DSR,0

       LWPI DREGS             can't modify our workspace at same time!
       LI   R12,>1EF4
       SBZ  0

       MOV  @SAVE0,@>8000     RESTORE.. 0
       MOV  @SAVE0+2,@>8002
       MOV  @SAVE0+4,@>8004
       MOV  @SAVE0+6,@>8006

       LI   R1,>8200
       LI   R2,>F000
       LI   R3,128
RESRG1 MOV  *R1+,*R2+
       DEC  R3
       JNE  RESRG1

       LI   R10,>7000
       LI   R9,0
S7000  EQU  $-2
       C    *R10,R9
       JEQ  S7001
       MOVB *R10,*R10
       C    *R10+,R9
       JEQ  S7001
       MOVB *R10,*R10

S7001  MOVB @GROM,@GRMWA      restoer GROM
       MOVB @GROM+1,@GRMWA

       SZCB @HEX20,R15
       MOV  @PABADR+2,R1
*      MOV  @0(R13),R1        lets return the error code
       INCT R1
       MOVB *R1,R1            in R0 of the caller's WS
       SRL  R1,13
       JNE  DJUMP7
       RTWP                   returns EQ status

DJUMP7 SWPB R1
       MOVB R1,*R13
       SOCB @HEX20,R15
       RTWP

SAVR11 DATA 0
SAVE0  DATA 0,0,0,0
DSR    DATA 8
VID    DATA 6
GROM   DATA 0
Link to comment
Share on other sites

I finally figured this out. One thing that isn't saved (because it can't be) is the grom address that will be read from next. When running as an EA5 program the grom pointer is not the same as when you are running via CALL LINK. On my TI XB cartridge >C41D should be the next grom address to be read when returning to XB. When that is set by the loader the program runs as expected, whether from E/A or from XB.

 

Is this address consistent between the various versions of XB? (This is the next grom address to be read from when returning from a CALL LINK subroutine.) Rich, can you shed some light on this??

 

So if I jam the value >C41D into address >9C02 somewhere in the RESTOR area of the source, the EA5 version will then work?

As far as I know, I didn't change any code having to do with CALL LINK in XB v2.7, so I'm assuming it will work. Don't know about RXB & the other XB versions.

 

Gazoo

Link to comment
Share on other sites

Here's a more or less finished version of this program. It is called SNAPSHOT because it takes a picture of a running XB program and then restores it when running which makes the startup really fast. Here's how to use Snapshot. Running under Classic99, from the XB command line load the program with:

OLD DSKn.PROGRAMNAME

Add one of these lines to the XB program at a point where the characters are defined and the screen drawn:

100 CALL LINK("SAVE")

or

100 CALL LINK("GSAVE")::[$="X"::GOTO 100 ([$ is a legal name and shouldn't conflict with the program)

Then CALL INIT and CALL LOAD("DSK3.SNAPSHOT.OBJ")

Then RUN the program. The program will execute up to the SAVE or GSAVE line. Then all the pertinent memory locations are copied from CPU and VDP ram to memory starting at >A000 and the program quits and returns to the start screen.

At the start screen open the debugger and look at CPU memory at >3000 - that number is the ending address of the program. Press F1 to break the program. Click the box to "Make" then click "Save Memory as Program". Check high memory; addresses from >A000 to the number in >3000. Check "build" and enter a filename to save your XB program in EA5 format.

 

SAVE will save all the memory your program uses in the VDP. If memory is not a concern this would be fine.

GSAVE used as shown above will loop until a garbage collection is performed, and then make the EA5 format image. This can save quite a bit of memory, but be patient when creating the program - it can take a few seconds to force the garbage collection.

 

On the disk are the files GAMMON, GAMMON1, and GAMMON2. Also BERNIE, BERNIE1 and BERNIE2. GAMMON and BERNIE are the standard XB versions of the programs; the other files are the EA5 versions. LOADSSXB is an XB utility to load EA5 files created by Snapshot. It uses embedded code similar to SYSTEX. At the end of line 10 there is CALL LINK("LOADSS","DSK4.BERNIE1") This can be modified to load whatever program you want. If you want to make a menu program using this, you need to know that once CALL LINK("X") executes the program will finish that line and then erase itself. N.B. - although the files are in EA5 format, they still need the XB cartridge to work.

 

KWIKLOAD is similar to SYSTEX. I think SYSTEX saves the entire 8K low memory; KWIKLOAD only embeds the assembly programs you have loaded, so it can be more compact. Here's how to use it:

NEW
CALL INIT
CALL LOAD("DSK1.YOURSUBS")
CALL LOAD("DSK1.KWIKLOAD.OBJ") This loads KWIKLOAD
CALL LINK("X") Moves subs to high memory where they can be embedded.
Add this line of code by typing or merging:
10 CALL INIT::CALL LOAD(8192,255,154)::CALL LINK("X")::!add RUN
"DSK1.XBPROGRAM" or CALL LINK(XXX) as needed.

Then SAVE this program
When run, after the LOAD and LINK the subs are copied out of high memory and back into low memory where they started, then program is
erased, then it RUNs your program or does a CALL LINK per your program instructions.

SNAPSHOT.zip

  • Like 5
Link to comment
Share on other sites

Here's a more or less finished version of this program. It is called SNAPSHOT because it takes a picture of a running XB program and then restores it when running which makes the startup really fast.

 

 

I just tried it out on the BERNIE file (after a little editing so you can't break it or quit in the middle of it) and it works great!

 

Thank you sir, this is a wonderful utility. :-D

 

Gazoo

Link to comment
Share on other sites

Glad to know that it works for you. I checked the GROM at C41D and found it the same in RXB 2011, RXB 2012 and TI XB so it should be the same for all of them, which your experience bears out.

 

By the way, I've been wondering - are you "The Great Gazoo" or merely a lesser one?

 

Just Gazoo, I ain't so great. ;)

Link to comment
Share on other sites

 

Just Gazoo, I ain't so great. ;)

Yep, same here.

There are a couple of improvements you could make if you feel like tweaking the program a bit. Some error checking might be nice. More importantly, if your program is too big it will simply keep loading and try to go past >FFFF. The loader should detect this situation and skip the 8K block from >0000 to >1FFF. To make as much room as possible, you should use AORG to move the loader from the default location at >24F4 to as high up in low memory as is possible. You should have your own VMBR in with the loader because you will quickly overwrite the standard utilities in lowmem. With these mods you will be able to pack in almost 8K more. Even so, you will not be able to load a super long XB program which can have 24K of memory for the program and variables and around 14K more in the VDP. Be sure to use GSAVE when creating the EA5 files so you do the garbage collection before saving.

(edit) One other thing that would be helpful is to be able to do a garbage collection as part of the assembly subroutine. It is supposed to be an XML routine at >70 but all I get is an error with it.

Edited by senior_falcon
Link to comment
Share on other sites

KWIKLOAD is similar to SYSTEX. I think SYSTEX saves the entire 8K low memory; KWIKLOAD only embeds the assembly programs you have loaded, so it can be more compact. Here's how to use it:

 

FYI, SYSTEX does not save the entire 8K - it saves only the routines you load into low memory. You can then of course add XB code to the created program, though I don't recall if the combined program is able to exceed the usual program file limitation. That is, I don't know if a SYSTEX'd file will operate once it is large enough to become IV254.

Link to comment
Share on other sites

 

FYI, SYSTEX does not save the entire 8K - it saves only the routines you load into low memory. You can then of course add XB code to the created program, though I don't recall if the combined program is able to exceed the usual program file limitation. That is, I don't know if a SYSTEX'd file will operate once it is large enough to become IV254.

Thanks for that info. I don't see why a systex'd file would not work as an IV 254. One thing that might be a problem is if you add XB program lines to systex'd assembly files and then resequence the xb program. XB might make some changes to the A/L code if it see something that looks like a line number. I dunno for sure that this would happen.

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