Commodore 64 BASIC 2.0 garbage collection, strings assignments in loops

Strings assignments inside loops are very likely to create garbage. Even when a new string is assigned to an already existing string variable, the old content is not deleted from memory and becomes garbage. I had took advantage from this feature to code a simple bitmap screen clear routine.  By the way, it is actually possible to create a string with multiple assignments of the same variable without RAM memory waste.

The programs being discussed on this article are available for download:

Download: string assignment on a loop

 

Let’s start from the beginning. The following program will create a string variable containing a string made up of 255 “a” characters.

10 fort=1to255:a$=a$+"a":next
20 print a$, len(a$)

This program is very simple and it seems nothing worth talking about. But, let’s add some code to this program so that we can see how much memory is wasted during the process.

4 gosub 100:lg=255
10 fort=1tolg:a$=a$+"a":next
20 print a$, len(a$)
25 gosub 100
40 b$ = ""+"hello"
50 printb$, len(b$)
60 gosub 100
99 end
100 print"string pointer: ";peek(51)+256*peek(52):return

As you can see from the address referenced by the string pointer, nearly 32K bytes of strings have been created by this program!

 

This is due to the fact that on the loop in line 10, on each assignment a new string is created. The BASIC interpreter just doesn’t care it’s the same variable being re-assigned on each loop. So the memory gets populated of garbage strings. We have already dealt with garbage collection on the Commodore 64 on this article.

The program also creates another variable. The apparently useless string concatenation on line 40 actually forces the BASIC interpreter to store the string for the variable B$ in the String Storage Area (this is the same technique used on this article). There is still room in the string storage area, so the variable B$ is properly assigned.

After this program will be modified, the creation of the variable B$ will be useful to check that the program works properly.

As we know from this article, it is possible to force the String Pointer to a desired value in order to avoid garbage creation. On line 10, if we reset the String Pointer after each assignment, no garbage will be created. In other words, before the loop we store the initial value of the String Pointer (two bytes), then on each iteration we make the assignment and then we retrieve the initial value of the String Pointer.

As you can see from the following version of the program, this approach prevents any memory waste to happen.

4 gosub 100
5 p1=peek(51):p2=peek(52):lg=255
10 fort=1tolg:a$=a$+"a":poke51,p1:poke52,p2:next
15 nl=(p1+p2*256)-lg:hi=int(nl/256):poke52,hi:poke51,nl-hi*256
20 print a$, len(a$)
25 gosub 100
40 b$ = ""+"hello"
50 printb$, len(b$)
60 gosub 100
99 end
100 print "string pointer: ";peek(51)+256*peek(52):return
Running the fixed version of the program. Now, no garbage is being created and memory use is efficient.

 

Line 15 is very important. When we exit the loop, the String Pointer is being reset to its initial value. At this point, the Pointer must be set according to the lenght of the string created. Line 15 does just this. If we don’t do this, any other string variable that will be created will just corrupt the content of the variable A$.

As you can see, the string variable B$ is properly created and assigned. The strings “AAA….AAA” and “HELLO” are adjiacent in memory, just as required.

 

Precedente "Hi-res" bitmap graphics with Commodore 64 BASIC 2.0, fast screen clearing routine Successivo Commodore 1541 disk drive maintenance, part 2: head alignment

Lascia un commento

*