Jump to content
IGNORED

TI Basic memory


Bones-69

Recommended Posts

I wanted to test out an idea I have for moving characters around in XB and came up with a game to build around the concept. I've been working on it pretty compulsively now for about 4 days and was happy with the potential so last night I started programming. However, just as I am making some progress I get the old 'MEMORY FULL IN....".

 

This problem came way earlier than expected so I dug out the green book to try and work out what was going on. Am I understanding correctly that only 16K is available in BASIC even with the Expansion memory added (emulated)? I've dimmed a bunch of Arrays at the start which are causing the TI to blow a fuse. i always assumed I had 32K to play with?

 

Don't I feel silly.... :)

 

  

IMG_2451.jpg

Link to comment
Share on other sites

They're kinda big..... But even at 16K I am am surprised I hit the ceiling already.

 

[code]

100 DIM Y(144),X(144),L(144,4),K(12),CI$(3)
105 REM MEMORY WHEN ADDING LY(144),LX(144)
110 FOR A=1 TO 25
120 READ I,A$
130 CALL CHAR(I,A$)
140 IF I<121 THEN 160
150 CALL CHAR(I+8,A$)
160 NEXT A
170 FOR A=1 TO 15
180 READ I,B
190 CALL COLOR(A,I,B)
200 NEXT A
210 CALL CLEAR
220 CALL SCREEN(2)
230 READ A,B,C,N,M
240 IF A=-1 THEN 370
250 GOSUB 4100
260 GOTO 230
370 FOR A=7 TO 19
380 CALL HCHAR(A,11,118,12)
390 NEXT A
400 FOR A=122 TO 125
410 CI$(1)=CI$(1)&CHR$(A)
420 CI$(2)=CI$(2)&CHR$(A+8)
430 CI$(3)=CI$(3)&CHR$(A-24)
440 NEXT A
450 A$="SCORE:00000"
460 B=3
470 C=12
480 GOSUB 4000
490 A$=CI$(1)
500 B=19
510 C=12
520 GOSUB 4000
530 A$=CI$(2)
540 C=17
550 GOSUB 4000
560 A$=CI$(3)
570 B=20
580 C=12
590 GOSUB 4000
600 C=17
610 GOSUB 4000
613 A=0
615 FOR D=7 TO 18
618 FOR I=11 TO 22
620 A=A+1
630 L(A,1)=A-12
640 L(A,2)=A+1
650 L(A,3)=A+12
660 L(A,4)=A-1
670 REM LY(A)=D
680 REM LX(A)=I
690 NEXT I
700 NEXT D
710 FOR A=1 TO 4
720 READ B,C,I
730 FOR D=B TO C STEP I
740 L(D,A)=D
750 NEXT D
760 NEXT A
770 GOTO 770


4000 FOR A=1 TO LEN(A$)
4010 CALL HCHAR(B,C-1+A,ASC(SEG$(A$,A,1)))
4020 NEXT A
4030 RETURN

4100 ON A GOTO 4110, 4130
4110 CALL HCHAR(B,C,N,M)
4120 RETURN
4130 CALL VCHAR(B,C,N,M)
4140 RETURN

5000 DATA 34,202020FF2020202,42,0000AA00AA00AA,43,1F171F171F171F17,44,FFFF55FFFF,45,E8F8E8F8E8F8E8F8,58,0,91
5010 DATA 001818,98,03,99,FFFF7537353707,100,FF7B78606,101,C,102,0,106,83C66C383C66C381,114,183C6666BDBDE7C3
5020 DATA 115,F0CC7E33337ECCF0,116,C3E7BDBD66663C18,117,0F337ECCCC7E330F,118,0,122,0000000000000003,123
5030 DATA 000737353775FFFF,124,0000006078787BFF,125,00000000000000C,126,0,138,003C7E5A7E244242,139,0882241040244801
5060 DATA 9,2,12,2,16,2,16,2,16,2,16,2,16,2,16,2,6,5,15,3,8,1,15,1,15,1,9,1,4,1

6000 DATA 1,1,1,34,768, 2,1,6,106,528, 2,9,9,45,12, 2,9,24,43,12, 2,7,10,45,16
6010 DATA 2,7,23,43,16, 1,20,11,102,12, 1,21,11,102,12, 1,22,11,102,12, 1,2,8,58,18
6020 DATA 1,3,8,58,18,1,4,8,58,18,1,23,11,42,12,1,6,11,44,12,-1,0,0,0,0

6050 DATA 1,12,1,12,144,12,1,133,12,133,144,1

[/code]

 

 

Edited by Bones-69
Link to comment
Share on other sites

1 hour ago, Bones-69 said:

Am I understanding correctly that only 16K is available in BASIC even with the Expansion memory added (emulated)?

 

You can access the expansion RAM in TI Basic with the E/A cartridge in place. The E/A cartridge adds commands like LOAD and PEEK that allow expansion RAM access, but using arrays set up that way would likely be painful without delving into a little Assembly language to help out.

 

...lee

  • Like 3
Link to comment
Share on other sites

You can't access expansion memory from BASIC for /basic/. You could peek and poke it, yes, but that doesn't sound like what you're after. You have to use XB.

 

The full 16k is not available to you for programming. The character set takes up some space, as does the screen itself, and the disk system allocates some file buffers. All this combined leaves you about 12k for program and data.

 

If you are not using multiple open files at once, use CALL FILES(1) to free up some memory before you load your program. The disk system normally allocates enough space for 3 files to be open at the same time - it's rare that is needed. Going down to 1 will give you an extra 1036 bytes - not quite 1k. You can do zero buffers on a cassette-only system (or Classic99's CALL FILES(0) - but note this impacts compatibility with real hardware.)

 

  • Like 6
Link to comment
Share on other sites

As far as memory goes - there are things you can do to save RAM. All numbers are 8 bytes long, so each of your 144 entry arrays takes 1152 bytes just to hold the data. You have 6 sets of 144 entries (Y, X, and four sets of L), so that's half your RAM in those three arrays. If we take all your arrays (including LY and LX), we'd be looking at 9312 of roughly 12246 bytes used up just for the DIMs.

 

Unfortunately, TI BASIC doesn't support integer variables. Fortunately, the numbers in the DATA statements /are/ saved as if they were string data, so take only as many bytes as you typed. But, if you can afford the time to VAL() them, you can store your data as strings instead of numbers for a pretty good saving.

 

In general, you'll have to resort to using inline math more often than pre-calculating values, just because of that cost. I don't really see how the tables are being used in there so I am not sure what other suggestions to make. Reuse any code you can in subroutines rather than duplicating it. Control strings -- although they only consume the RAM they use, every time you modify them a new string is allocated from RAM, and the program will pause to clean up old ones when it runs out of space (which can be frequent when RAM is tight). One trick I've used is to encode the screen position in the string for the HCHAR print loop:

1 A$="HI"

2 R=3

3 C=5

4 GOSUB 1000

 

This takes about 46 bytes, but this:

 

1 A$=CHR$(3)&CHR$(5)&"HI"

2 GOSUB 1000

 

takes 36 bytes. Only saves about 10 bytes, but the speed difference is negligable (maybe a little slower due to the need to encode/decode the positions), so if you do it a lot it may help.

An old trick is saving standard values into a variable - for instance, @=0 and using '@' instead of 0 everywhere. This can save a little bit - in my testing it's only 1 byte smaller due to the way a number is encoded instead of a variable -- but in either case the memory usage is however long the string is. The actual encoding of instructions is pretty good.

 

Anyway, you can fit a lot of code into 12k... just... not a lot of data. ;)


 

Edited by Tursi
  • Like 5
Link to comment
Share on other sites

3 hours ago, Bones-69 said:

They're kinda big..... But even at 16K I am am surprised I hit the ceiling already.

 

[code]

100 DIM Y(144),X(144),L(144,4),K(12),CI$(3)
105 REM MEMORY WHEN ADDING LY(144),LX(144)
110 FOR A=1 TO 25
120 READ I,A$
130 CALL CHAR(I,A$)
140 IF I<121 THEN 160
150 CALL CHAR(I+8,A$)
160 NEXT A
170 FOR A=1 TO 15
180 READ I,B
190 CALL COLOR(A,I,B)
200 NEXT A
210 CALL CLEAR
220 CALL SCREEN(2)
230 READ A,B,C,N,M
240 IF A=-1 THEN 370
250 GOSUB 4100
260 GOTO 230
370 FOR A=7 TO 19
380 CALL HCHAR(A,11,118,12)
390 NEXT A
400 FOR A=122 TO 125
410 CI$(1)=CI$(1)&CHR$(A)
420 CI$(2)=CI$(2)&CHR$(A+8)
430 CI$(3)=CI$(3)&CHR$(A-24)
440 NEXT A
450 A$="SCORE:00000"
460 B=3
470 C=12
480 GOSUB 4000
490 A$=CI$(1)
500 B=19
510 C=12
520 GOSUB 4000
530 A$=CI$(2)
540 C=17
550 GOSUB 4000
560 A$=CI$(3)
570 B=20
580 C=12
590 GOSUB 4000
600 C=17
610 GOSUB 4000
613 A=0
615 FOR D=7 TO 18
618 FOR I=11 TO 22
620 A=A+1
630 L(A,1)=A-12
640 L(A,2)=A+1
650 L(A,3)=A+12
660 L(A,4)=A-1
670 REM LY(A)=D
680 REM LX(A)=I
690 NEXT I
700 NEXT D
710 FOR A=1 TO 4
720 READ B,C,I
730 FOR D=B TO C STEP I
740 L(D,A)=D
750 NEXT D
760 NEXT A
770 GOTO 770


4000 FOR A=1 TO LEN(A$)
4010 CALL HCHAR(B,C-1+A,ASC(SEG$(A$,A,1)))
4020 NEXT A
4030 RETURN

4100 ON A GOTO 4110, 4130
4110 CALL HCHAR(B,C,N,M)
4120 RETURN
4130 CALL VCHAR(B,C,N,M)
4140 RETURN

5000 DATA 34,202020FF2020202,42,0000AA00AA00AA,43,1F171F171F171F17,44,FFFF55FFFF,45,E8F8E8F8E8F8E8F8,58,0,91
5010 DATA 001818,98,03,99,FFFF7537353707,100,FF7B78606,101,C,102,0,106,83C66C383C66C381,114,183C6666BDBDE7C3
5020 DATA 115,F0CC7E33337ECCF0,116,C3E7BDBD66663C18,117,0F337ECCCC7E330F,118,0,122,0000000000000003,123
5030 DATA 000737353775FFFF,124,0000006078787BFF,125,00000000000000C,126,0,138,003C7E5A7E244242,139,0882241040244801
5060 DATA 9,2,12,2,16,2,16,2,16,2,16,2,16,2,16,2,6,5,15,3,8,1,15,1,15,1,9,1,4,1

6000 DATA 1,1,1,34,768, 2,1,6,106,528, 2,9,9,45,12, 2,9,24,43,12, 2,7,10,45,16
6010 DATA 2,7,23,43,16, 1,20,11,102,12, 1,21,11,102,12, 1,22,11,102,12, 1,2,8,58,18
6020 DATA 1,3,8,58,18,1,4,8,58,18,1,23,11,42,12,1,6,11,44,12,-1,0,0,0,0

6050 DATA 1,12,1,12,144,12,1,133,12,133,144,1

[/code]

 

 

Temporary variables including string variables and numeric variables and your program and files all live in that 16K of VDP.

The only way to access the 32K RAM is using the Editor Assembler cartridge.

 

Link to comment
Share on other sites

I kept track of the free memory with this little trick:

 

30000 x=0

30010 x=x+8

30020 gosub 30010

 

>run 30000

 

Each GOSUB will take 8 byte on the stack. After you get a "Memory full" error, just PRINT X and get the free space you have left ...

 

 

 

 

  • Like 3
Link to comment
Share on other sites

6 hours ago, Lee Stewart said:

You can access the expansion RAM in TI Basic with the E/A cartridge in place. The E/A cartridge adds commands like LOAD and PEEK that allow expansion RAM access, but using arrays set up that way would likely be painful without delving into a little Assembly language to help out.

 

4 hours ago, RXB said:

The only way to access the 32K RAM is using the Editor Assembler cartridge.

Poor old MINI MEMORY, not good for nothin' +UTILs in ROM, and 4K RAM.;)

  • Like 2
Link to comment
Share on other sites

21 hours ago, Tursi said:

As far as memory goes - there are things you can do to save RAM.


 

Thanks for the detailed response Tursi. Some good stuff in there. Ironically, the idea of these Arrays was to control character location and to save the math and processing during program execution - so some of the "unzipping" to save a little memory would negate the original effort. Also, I had never heard of the @ trick!  

Link to comment
Share on other sites

Yo Bones, its been a long time.
 
Without running a program to check, I have used strings to set arrays when Dimentioned arrays memory load has failed me, 144 charcters long, and a chr$ locator, and replacer routines. 
I am suffering from these issues even on a 64bit AMD due the size of the arrays (19683) ^8 and I have had to reduce my expectations slightly due to this barrier. Being creative, the TI99 will always help you create an alternative route.  Regards Arto.

  • Like 1
Link to comment
Share on other sites

11 hours ago, Bones-69 said:

Thanks for the detailed response Tursi. Some good stuff in there. Ironically, the idea of these Arrays was to control character location and to save the math and processing during program execution - so some of the "unzipping" to save a little memory would negate the original effort. Also, I had never heard of the @ trick!  

Haha, well, it could be 'A' just as easily.. just that TI allowed a few punctuation characters to be used as variable names, and I saw people using them for constants back in the day. IIRC "_" is another one. "_=1" just looks weird. ;)

 

Link to comment
Share on other sites

On 1/1/2023 at 10:57 PM, Tursi said:

As far as memory goes - there are things you can do to save RAM. All numbers are 8 bytes long, so each of your 144 entry arrays takes 1152 bytes just to hold the data. You have 6 sets of 144 entries (Y, X, and four sets of L), so that's half your RAM in those three arrays. If we take all your arrays (including LY and LX), we'd be looking at 9312 of roughly 12246 bytes used up just for the DIMs.

 

Unfortunately, TI BASIC doesn't support integer variables. Fortunately, the numbers in the DATA statements /are/ saved as if they were string data, so take only as many bytes as you typed. But, if you can afford the time to VAL() them, you can store your data as strings instead of numbers for a pretty good saving.

 

In general, you'll have to resort to using inline math more often than pre-calculating values, just because of that cost. I don't really see how the tables are being used in there so I am not sure what other suggestions to make. Reuse any code you can in subroutines rather than duplicating it. Control strings -- although they only consume the RAM they use, every time you modify them a new string is allocated from RAM, and the program will pause to clean up old ones when it runs out of space (which can be frequent when RAM is tight). One trick I've used is to encode the screen position in the string for the HCHAR print loop:

1 A$="HI"

2 R=3

3 C=5

4 GOSUB 1000

 

This takes about 46 bytes, but this:

 

1 A$=CHR$(3)&CHR$(5)&"HI"

2 GOSUB 1000

SteveB

On 1/1/2023 at 10:57 PM, Tursi said:

I kept track of the free memory with this little trick:

 

30000 x=0

30010 x=x+8

30020 gosub 30010

 

>run 30000

 

Each GOSUB will take 8 byte on the stack. After you get a "Memory full" error, just PRINT X and get the free space you have left ...

I've been meaning to look into finding ways to save memory in TI Basic. Some very good tips here. Thanks everyone!

  • Like 1
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...