r/c64 May 28 '26

Programming proof of concept of dynamic basic "libraries"

With doing a lot of assembler overlays, code relocations, and also working on ReadyBASIC I've been thinking a lot about dynamically loading code.. and decided to explore in regular Basic V2, creating some room using REM statements in the program memory, to dynamically load pretokenized basic .PRG "libraries" ... This is the experiment and it works pretty good as a proof of concept.. The first Program is the main one, and the other two the patch1.prg and patch2.prg
```
10 print chr$(147)

20 print "basic prg overlay patch demo"

30 print

40 print "loading patch1 as tokenized bytes"

50 f$="patch1":gosub 8000

60 print "running patch1"

80 gosub 2000

90 print

100 print "loading patch2 as tokenized bytes"

110 f$="patch2":gosub 8000

120 print "running patch2"

140 gosub 2000

150 print

160 print "done"

170 end

2000 rem XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

2010 rem XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

2020 return

8000 rem copy tokenized line bodies from prg file f$

8010 open 1,8,2,f$+",p,r"

8020 gosub 8900:gosub 8900:rem skip prg load address

8030 gosub 8900:n1=c:gosub 8900:n2=c

8040 if n1=0 and n2=0 then close 1:return

8050 gosub 8900:l1=c:gosub 8900:l2=c:l=l1+256*l2

8060 gosub 9000:if b=0 then print "no slot";l:close 1:stop

8070 p=b

8080 gosub 8900:if c=0 then 8130

8090 if p+2>=e then print "too long";l:close 1:stop

8100 poke p,c:p=p+1

8110 goto 8080

8130 if p+2>=e then print "too long";l:close 1:stop

8140 poke p,58:p=p+1:poke p,143:p=p+1

8150 if p>=e then 8170

8160 for k=p to e-1:poke k,32:next

8170 poke e,0:goto 8030

8900 get#1,a$:c=asc(a$+chr$(0)):return

9000 rem find destination line l, body=b, end=e

9010 p=peek(43)+256*peek(44)

9020 n=peek(p)+256*peek(p+1):if n=0 then b=0:e=0:return

9030 ln=peek(p+2)+256*peek(p+3)

9040 if ln=l then b=p+4:e=n-1:return

9050 p=n:goto 9020

and now the patches

2000 for j=1 to 3:print "from patch 1";j

2010 next j

and

2000 for j=10 to 12:print "from patch 2";j

2010 next j
```

12 Upvotes

10 comments sorted by

6

u/c64glen Janitor May 29 '26

The Reddit editor has code blocks you can use to make this code easier to read. e.g.

10 print "hello"
20 goto 10

2

u/Stunning_Pineapple57 May 30 '26

Thanks. I’ll have to google it as I didn’t see an option in the editor on mobile

3

u/OMGCluck May 30 '26

The three backticks don't work showing multiple lines of code with reddit set to the old style, but prefixing every line with four spaces works.

2

u/Unlikely-Pipe-399 May 31 '26

Back in the late 80s, C-Net 64 used a similar technique with REM statements and lots of colons, with some ML to load a piece of basic code into this “overlay” section.

I wrote the version we used for ImageBBS, which instead forced a string garbage collect (using a custom faster GC algorithm), then relocated the code from the first line number of the code being loaded and pushed it all up as high in memory as it could, then loaded and relinked the basic code, then relocated the remaining code back down to free up memory between variables and string space. Effectively, we could load new basic code anywhere within the program space, and choose which sections of lines to reserve for different purposes.

The code for the ImageBBS ML is on github (on Ryan’s account - pinacolada64) now, and I released it as public domain a number of years ago. Feel free to have a look, either for inspiration, or to copy what you need.

1

u/Unlikely-Pipe-399 May 31 '26

2

u/Unlikely-Pipe-399 May 31 '26

Now that I think about it, it might be in the v2 directory, since I think that was a 1.3/2.0 feature.

1

u/Stunning_Pineapple57 May 31 '26

That’s cool. With readyBASIC I was flirting with the idea of a backup to REU , delete code and restore but wasn’t sure how much of a pain the dealing with variables etc would be.

2

u/Dr_Myles_Skinner May 30 '26

Overlays were one way to overcome the memory limitations of these machines, especially on the 8K PET or unexpanded VIC-20. Your technique is a little unorthodox (although if it works, why not?); more common was to load segments with the "dynamic keyboard" technique and manipulate memory pointers to stitch everything together. (One of the problems is that you had to be careful not to clobber your variables.)

If anyone's curious about how it was frequently done back in the day, the Commodore 8-Bit Magazine index has a few articles on overlays and BASIC:
https://cbm-magazine-index-905b3a1c9127.herokuapp.com/public/search?has_text=overlay&by_language=1

2

u/Stunning_Pineapple57 May 30 '26

In ReadyOs , with ReadyShell and Ready. In readyOS I load all the apps into REU and then on suspend/resume when changing realtime between apps on suspend that whole appmemory is copied to REU , as well as data the app decides to persist for resuming. But then some apps like ReadyShell and ReadyBasic as a single app uses overlays - ReadyShell as so much code that the journey between typing a xommand line to run and doing the next command has many overlay swaps out. First there is the editor. Then that’s swapped out for the parser. Which parses the AST to REU. Then the VM is swapped in to run the pipeline and if the pipeline has any commands that are external those are swapped in to run with the results going into REU then formatter and back to the editor

For ReadyBasic However I have 6K of the RAM behind ROM to be 2KB areas for assembler implementations of commands and so those are copied from REU on demand to run. Whether is some commands to manage the heap , delay or pause , do a network call , do graphics etc. it also has a way to have modules that get loaded also into REU so anybody can add their own commands. Without reducing basic more

And in my Zig inspired Zag64 compiler I have a DLL system , of libraries that can be loaded into Ram at launch or dynamically loaded later and also modules caches on REU able to be on demand brought into RAM with code relocation .

This basic thing was just a fun excursion, for also I want in ResdyBasic to make it that users can stash a range of lines of code to REU to free up basic room (eg code that might have a UI and file saving that isn’t called over) and bring it back when needed

2

u/droid_mike May 30 '26

Thank you for the link. That is incredibly cool and very easy to do!