Jump to content
IGNORED

Low Memory Loading Woes


Cheung

Recommended Posts

So I've been working on Warlords and it's gotten to be too big to all fit in high memory so I use the option to load it into low memory when I build the executables.

The loader creates a WARLOR-X and a WARLOR-Y file which run fine when running the loader. But if I try to run WARLOR-X in the normal TI XB prompt, all hell breaks loose and it starts squeaking and sqwaking, presumably because of some weird memory issues.

Anybody have any idea what I need to do to run these new "low memory" executables?

Link to comment
Share on other sites

When I compile XB256 the program, I use the option to load it into Low Memory. When it's finished compiling, a WARLOR-X and WARLOR-Y are created. After the Loader creates these files, it has an option to run them, which I select. When running it this way, everything runs perfectly. If I try to run WARLOR-X without using the Loader (when the executables are built) it doesn't work and acts like it is accessing some random memory location (starts emitting high frequency tones).

Link to comment
Share on other sites

1 minute ago, 1980gamer said:

Did you try loading and running the -Y file?

 

I have had issues in the past.  What XB are you running and Classic99 version etc. I am assuming Juwel 4.

 

 

Yes, that didn't do anything. The -X runs the -Y as it's last statement

Edited by Cheung
Link to comment
Share on other sites

1 hour ago, senior_falcon said:

Hard to say what it could be. This has always worked for me. If you PM me the original XB program and the -X and -Y files and I will take a look and see if I can duplicate your problem.

Kere are the required files. The DATA files will need to go in DSK1 if you want to run it.

INSTDAT WARDATA WARLOR WARLOR-X WARLOR-Y

Link to comment
Share on other sites

This looks like a lot of fun!!

 

I put these files on disk 3 and tried loading WARLOR-X which then loads WARLOR-Y (after changing RUN "DSK1.WARLOR-Y" to DSK3), and although it didn't crash, it just returned to XB. So I looked a little deeper into the XB source.

Lines 9000+ open a disk file for data, and lines 13000+ open an instruction file. Those lines are:


9000 OPEN #1:"DSK1.WARDATA",SEQUENTIAL,DISPLAY ,INPUT ,VARIABLE

13000 CALL CLEAR :: CALL COLOR(#28,1):: V,I=1 :: OPEN #2:"DSK1.INSTDAT",SEQUENTIAL,DISPLAY ,INPUT ,VARIABLE

 

Disk handling is not the compiler's strongest asset, and I suspected the SEQUENTIAL was causing trouble. Just to be sure, I also changed the order a little (although that shouldn't matter) and specified VARIABLE 80. (which also should not matter) And of course, changed to DSK3.

 

9000 OPEN #1:"DSK3.WARDATA",INPUT ,DISPLAY ,VARIABLE 80

13000 CALL CLEAR :: CALL COLOR(#28,1):: V,I=1 :: OPEN #2:"DSK3.INSTDAT",INPUT ,DISPLAY ,VARIABLE 80

 

I first checked to be sure it ran properly in XB using XB256, then compiled with runtime routines in low memory. After saving the -X and -Y files, I can do a cold reset, select XB or XB 2.9 G.E.M., RUN "DSK3.WARLOR-X" and the program seems to load and run properly.

 

It would be nice if you did not have to load the data and instructions from disk, but the program is pretty large (1856 bytes left in XB), so that is probably not practical.

 

If you have trouble with this I could post a video of the steps taken, but it looks like you have a good handle on this.

  • Like 4
  • Thanks 1
Link to comment
Share on other sites

Well, this is interesting. I tried what you wrote, only changing the DSK3, but leaving in the SEQUENTIAL and not specifying the length. It compiles just fine. Can be run as EA5 or XB.

So I do not know why it failed for you.

As I said before, if you have trouble I can post a video showing the steps that I took.

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

27 minutes ago, senior_falcon said:

This looks like a lot of fun!!

 

I put these files on disk 3 and tried loading WARLOR-X which then loads WARLOR-Y (after changing RUN "DSK1.WARLOR-Y" to DSK3), and although it didn't crash, it just returned to XB. So I looked a little deeper into the XB source.

Lines 9000+ open a disk file for data, and lines 13000+ open an instruction file. Those lines are:


9000 OPEN #1:"DSK1.WARDATA",SEQUENTIAL,DISPLAY ,INPUT ,VARIABLE

13000 CALL CLEAR :: CALL COLOR(#28,1):: V,I=1 :: OPEN #2:"DSK1.INSTDAT",SEQUENTIAL,DISPLAY ,INPUT ,VARIABLE

 

Disk handling is not the compiler's strongest asset, and I suspected the SEQUENTIAL was causing trouble. Just to be sure, I also changed the order a little (although that shouldn't matter) and specified VARIABLE 80. (which also should not matter) And of course, changed to DSK3.

 

9000 OPEN #1:"DSK3.WARDATA",INPUT ,DISPLAY ,VARIABLE 80

13000 CALL CLEAR :: CALL COLOR(#28,1):: V,I=1 :: OPEN #2:"DSK3.INSTDAT",INPUT ,DISPLAY ,VARIABLE 80

 

I first checked to be sure it ran properly in XB using XB256, then compiled with runtime routines in low memory. After saving the -X and -Y files, I can do a cold reset, select XB or XB 2.9 G.E.M., RUN "DSK3.WARLOR-X" and the program seems to load and run properly.

 

It would be nice if you did not have to load the data and instructions from disk, but the program is pretty large (1856 bytes left in XB), so that is probably not practical.

 

If you have trouble with this I could post a video of the steps taken, but it looks like you have a good handle on this.

Thanks, I'll see if I can get it working with your changes. not sure why the disk loads would keep the program from running but it's all magic and voodoo to me. I still have to add sound and work out the special case for Sauron, but then it should be finished.

  • Like 1
Link to comment
Share on other sites

1 minute ago, Cheung said:

Thanks, I'll see if I can get it working with your changes. not sure why the disk loads would keep the program from running but it's all magic and voodoo to me. I still have to add sound and work out the special case for Sauron, but then it should be finished.

Read my next post.

  • Like 1
Link to comment
Share on other sites

Just to make things totally confusing, I recopied what you posted.

Copied WARLOR-X and WARLOR-Y onto disk 3. Changed WARLOR-X to RUN "DSK3.WARLOR-Y" and saved it.

Copied INSTDAT and WARDATA onto disk 1.

RUN "DSK3.WARLOR-X" and all seems to work fine.

So I am mystified as to why it would not work for you.

 

  • Like 2
Link to comment
Share on other sites

I need to ask a question and hoped this was a relevant thread.  In a game, what is the best solution if I have lots of variables,  using two or three byte variables throughout , or setting up an array?
eg ... R1 , R2 , R3   vs A(1), A(2) ... to me the most obvious thing would be the array takes three bytes and R1 takes two bytes (just to declare the variable and array without the contents of it....) until I get to R10 +    ?

  • Like 1
Link to comment
Share on other sites

11 hours ago, senior_falcon said:

Just to make things totally confusing, I recopied what you posted.

Copied WARLOR-X and WARLOR-Y onto disk 3. Changed WARLOR-X to RUN "DSK3.WARLOR-Y" and saved it.

Copied INSTDAT and WARDATA onto disk 1.

RUN "DSK3.WARLOR-X" and all seems to work fine.

So I am mystified as to why it would not work for you.

 

But does it not work for you too when you run everything from disk 1?

Link to comment
Share on other sites

When compiled, the length of the name does not matter anymore. An array access is slightly more complex than a flat variable, so my guess would be multiple variables.

 

In order not to get lost in cryptic variable-names you may use TiCodEd with long variable names and assign short names for the export to XB. The table checks for uniqueness, but does not prevent you from using a short name directly in the code, on purpose or accidently.

image.thumb.png.9245d7979cf934bbf8eee2cca6050e10.png

You then work with long names in the editor and short names on the TI, preserving memory where it is needed.

 

  • Like 2
Link to comment
Share on other sites

3 minutes ago, SteveB said:

When compiled, the length of the name does not matter anymore. An array access is slightly more complex than a flat variable, so my guess would be multiple variables.

 

In order not to get lost in cryptic variable-names you may use TiCodEd with long variable names and assign short names for the export to XB. The table checks for uniqueness, but does not prevent you from using a short name directly in the code, on purpose or accidently.

image.thumb.png.9245d7979cf934bbf8eee2cca6050e10.png

You then work with long names in the editor and short names on the TI, preserving memory where it is needed.

 

Didn't know about TICoded. I've been using Notepad++ for this and have had to resort to short names to keep the memory usage low prior to compiling.

  • Like 2
Link to comment
Share on other sites

4 hours ago, Retrospect said:

I need to ask a question and hoped this was a relevant thread.  In a game, what is the best solution if I have lots of variables,  using two or three byte variables throughout , or setting up an array?
eg ... R1 , R2 , R3   vs A(1), A(2) ... to me the most obvious thing would be the array takes three bytes and R1 takes two bytes (just to declare the variable and array without the contents of it....) until I get to R10 +    ?

I like to use arrays for some things so I can group and organize certain variables into a more struct/class like form. For instance I'm using the ST(4,8) array to represent the game play field SECTOR (which is what it was called prior to memory becoming a big issue). This array contains information for each of the 4 sectors such as which player is in that sector (values 1-4), what character type (Aragorn etc), the location of the paddle (just an index), killed flag, and a few other flags and counters. I figured it would be easier to track and manipulate this data through the main game loop using the loop index than trying to track each variable individually. Can't speak to how this might be designed in pure assembly but the possible small hit in memory seemed worth it to me.

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

3 hours ago, Cheung said:

But does it not work for you too when you run everything from disk 1?

Yes, it should work from DSK1. As far as the XB interpreter is concerned, WARLOR-X and WARLOR-Y are just XB programs and so it does not matter what disk they are loaded from. Since you said it did not work, I assumed some troubleshooting would be necessary. If you saw how much junk I have on DSK1 you would understand why I wanted to use a different disk for troubleshooting this.

  • Like 2
Link to comment
Share on other sites

12 hours ago, Retrospect said:

I need to ask a question and hoped this was a relevant thread.  In a game, what is the best solution if I have lots of variables,  using two or three byte variables throughout , or setting up an array?
eg ... R1 , R2 , R3   vs A(1), A(2) ... to me the most obvious thing would be the array takes three bytes and R1 takes two bytes (just to declare the variable and array without the contents of it....) until I get to R10 +    ?

I think this is a question worthy of its own thread and can break it out if desired @Cheung.  It has been touched tangentially in other threads but I cannot recall one which goes into details.

 

It depends upon the purpose.  For your example, if you plan to iterate through or randomly select objects labeled with the variable R, then an array would probably be best.  Otherwise R1, R2, skip-a-few, R9 could make sense if each variable represents a global value or a value which would be statically addressed.

 

As an exercise, In Laser Strike, I had this big 2x10x10 array for the game grids.  Since I had grid 1 and and 2, I though I would use second-level element 0 to store variables for each user and first-level element 0 to store game variables, i.e. G(0,,) would hold game values, while G(P,0,x) holds x-utility for P-player.

 

This became incredibly cumbersome to use, and consumed more program memory than dedicated short variables.  Just pulling out of the air, instead of G(P,0,4) and G(P,0,5), where P is the current player number (P in {1,2}), to hold the player's cursor X,Y position, using something like CX and CY or even CX(P) and CY(P) was much, much easier to keep track of, and it consumed fewer program bytes than naming the G(,,) array.  DIMing CX() and CY() to only two elements saves on stack memory, and OPTION BASE 1 to eliminate the first-level 0 element saves more stack memory if you are not indexing by zero.

 

I used arrays in this example because I have a single purpose which iterates with each user.  But it was even more confusing when I was using the first-level element 0 to store game variables.  Why in the hell did I think using G(0,x,y) instead of variables like R, C, H, V, &c, was a good idea??  Again, just naming the G array costs several more bytes then using single- or two-letter variables for each use!

 

Does this matter for compiling?  Not a question I can confidently answer, but it definitely saves while working in Extended BASIC.

 

In memory:

G(0,1,4) is represented tokenized as G{open parens}{unquoted value}{length}0{comma}{unquoted value}{length}1{comma}{unquoted value}{length}4{close parens} ==> 14 bytes

CX(P) is represented as CX{open parens}P{close parens} ==> 5 bytes

CX is represented as CX ==> 2 bytes

 

This gets into many other posts which indicate using a variable instead of a number saves bytes, as well.  For instance, using the variable @ as 0, or the variable [ as some larger constant (say, 2450,) assuming each gets used multiple times throughout your program.  Every number in a program consumes its text plus two extra bytes, so the number 0 is >C8>01 followed by 0 (three bytes,) and 2450 is >C8>04 followed by the text 2450 (six bytes.)  Whereas variables are simply referenced by their text representation (one byte each in this example.)  You do, however, trade off program space for stack space, as each variable requires a stack entry with its name and two-byte pointer to its value, and its value in eight-byte RADIX-100 representation.

 

In my game example, the monolithic three-element array G(,,) to hold game and user data was far more cumbersome to use and consumed more program memory than my final variable table:

Spoiler
// Dimension arrays, minimum element of 1
// G(P,10,10)	Player game grid
// SP(P,4)	Ship parts remaining
// SR|SC(P,4)	Ship last hit R/C coordinate
// SH|SV(P,4)	Ship horizontal/vertical layout (-1..1)
// PL(4)	Proposed ship layout direction this move
// UR|UC(P)	Player (user) cursor R/C coordinate
// CP(P)	Computer player flag
// P$(P)	Player name (10 characters max, or "COMPUTER")
// K$(2)	String of keys accepted by UserInput subroutine
// S$(4)	Ship name for type
//
// Other variables
// K		CALL KEY() key press
// S		CALL KEY() status
// I		Loop and utility variable
// J		Loop, utilitiy, and user input return value
// L		Length of ship in focus
// T		Ship type currently in focus
// Z		Utility variable and flag
// X,Y		X,Y grid position during deploy and fit checks
// R,C		Player cursor grid row and column position; DispAt row and column position

 

 

Hope I expressed myself clear as mud, here :)

  • Like 2
Link to comment
Share on other sites

On 2/5/2023 at 10:04 AM, Cheung said:

Can someone download INSTDAT, WARDATA, WARLOR-X, and WARLOR-Y

Put them on Disk 1 and then RUN "DSK1.WARLOR-X"

These are the files that Cheung created and uploaded. They do not work for him, but seem to work fine for me. I am trying to find out where the problem is.

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, senior_falcon said:

Can someone download INSTDAT, WARDATA, WARLOR-X, and WARLOR-Y

Put them on Disk 1 and then RUN "DSK1.WARLOR-X"

These are the files that Cheung created and uploaded. They do not work for him, but seem to work fine for me. I am trying to find out where the problem is.

I was just able to get WARLOR-X running on XB 2.9, but not XB256, guess XB256 is using up additional memory? It works on Plain old XB for me also on QI399.063 but not 057. Not sure what's going on with your Instruction Display issues, it seems to display OK for me on .063, the font is definitely different from when I was running it from the Loader on 057, so maybe you have different Font that's hosing things up? The graphics display differently between XB and XB2.9 also (at least on Classic99). Not that that matters, I just thought it was interesting. thanks for looking into this. 

Edited by Cheung
Link to comment
Share on other sites

3 hours ago, senior_falcon said:

Can someone download INSTDAT, WARDATA, WARLOR-X, and WARLOR-Y

Put them on Disk 1 and then RUN "DSK1.WARLOR-X"

These are the files that Cheung created and uploaded. They do not work for him, but seem to work fine for me. I am trying to find out where the problem is.

Don't know if it's relevant at all, but in Js99er I had to remove the padding on the WARLOR-Y filename in WARLOR-X before it worked. This is probably a peculiarity of the JS99er disk DSR.

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

  • 3 weeks later...

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