Restricting BASIC to the +3K expanded RAM area

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
AndyH
Vic 20 Afficionado
Posts: 364
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Restricting BASIC to the +3K expanded RAM area

Post by AndyH »

I'm working with a fully expanded Vic, 35k (that's the 3K RAM at $400 and the full 32K in the other blocks).

What I'd like to achieve:
  • Load a BASIC program (on disk) that reconfigures RAM so BASIC starts at $0400 and ends at $1000 with the screen starting at $1000
  • The above loads a second BASIC program into $0400 and this then loads my game (a machine code prog) at address $1200 (about 24k) and $a000 (about 8k)
  • Additional, just for information: My game re-uses memory at $0400 at runtime, and the game never needs to return to BASIC
For the first BASIC program I've come up with the following which is working:

Code: Select all

10 poke43,1:poke44,4:poke36869,192:clr
20 load"loader",8
My BASIC program "loader" is loaded at $0400 as expected and it lowers end of BASIC to $1000 with

Code: Select all

POKE55,0:POKE56,28:CLR
which I guess I could put in the first program instead of here.

This is all working and it achieves what I need, but I wonder if I have missed anything or if there is a better way to do this? What are your thoughts?
--
AndyH
HEWCO | Vic 20 blog
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Restricting BASIC to the +3K expanded RAM area

Post by Mike »

AndyH wrote:[...] I wonder if I have missed anything [...]
LOAD in program mode does not set the pointer in 45/46 (start of variables, a.k.a. "end of program"), rather it retains the value from the program that does the load. In your case, the value of your 2-line boot program.

If the chained-through program is 'just' of the sort "BASIC stub + machine code", then it probably doesn't matter. If however the loaded program is in BASIC, then the BASIC interpreter will start searching for variables amidst of the program ... with usually fatal results.

I'd recommend you use this boot loader instead:

Code: Select all

10 POKE55,0:POKE56,30:CLR:POKE648,30:SYS58648
11 DN=PEEK(186):PRINT"{CLR}LOAD"CHR$(34)"LOADER"CHR$(34)","MID$(STR$(DN),2)
12 POKE631,19:POKE632,131:POKE198,2
13 POKE1024,0:POKE43,1:POKE44,4:NEW
to explain:
  • Line 10 lowers BASIC top as for unexpanded or +3K and puts the screen at $1E00,
  • Line 11 prints the LOAD statement on screen to be executed in direct mode (with DN set from the last used device, so drive numbers other than 8 also work),
  • Line 12 puts a {HOME} and a {RUN} character in the keyboard buffer. {RUN} executes LOAD and RUN (LOAD actually overtypes the "LOAD" put on screen before, which does do no harm), and
  • Line 13 prepares the BASIC start and sets the byte before the BASIC start to 0 (this also was missing in your implementation!).
As soon as the BASIC start is moved as in the example program above, the currently running program effectively loses all access to its own context ... neither variable access nor any GOTOs, etc. can anymore be guaranteed to work. The only sensible actions that can be taken are NEW or RUN. For RUN, see a similar example in another thread.

Any further preparations of BASIC memory (for protecting the character set), setting the character base, etc. should go in the loaded program actually. That program simply has to assume it runs with +3K expanded RAM - and it consequenctly should be able to run on its own when the user runs it directly with a +3K RAM expansion.


P.S. I saw the extended RAM requirement (i.e. you actually use all the RAM once again) only on second sight. With your use case above, I'd rather write out the whole executable from $0400 to $7FFF, including an empty screenbuffer, exomize that, and then let that program load the contents of BLK5 from disk.

You should actually have posed your question in this way: you have certain blocks of the main executable at certain addresses, what is the simplest way (preferably with least number of files on disk) to put them all in place, given a +35K RAM expansion?
User avatar
AndyH
Vic 20 Afficionado
Posts: 364
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Restricting BASIC to the +3K expanded RAM area

Post by AndyH »

Wonderful. Thanks Mike, that works (tested in emulator, will try on a real machine later).

Why am I doing it this way? In brief, it's temporary.

In my code, for convenience, I have my project to produce a huge cart image starting at $1210 in my case and ending at $c000. This of course is not a valid PRG as it crosses the ROM area (and other things) but my copy of VICE is overly forgiving and takes it. With the magic bytes in $a000 the game is recognised as a cart and starts up. From build/run to the game starting in VICE takes about 2-3 seconds, so it makes development really quick and easy for me.

The problem posed in this post was I wanted to send the game to a tester, and also to allow me to test on a real Vic (edit: so I was looking for a way to do that). Your solution appears to do the job nicely for this. Although it is slow to load it is working in the emulator and I'll see if I have the same luck loading from an SD2IEC on a real vic later.

I think when I am finished I will come back to the best way to allow others to play it if they so wish. The slow loading will work but not a pleasant experience to wait all that time. I like your idea to exomize the 24k block and my game to load the last 8k from disk. If I drop the requirement to use the 3k expanded area at $400 I could still make a 32k physical cartridge I guess.

I've made games in sizes of unexpanded through to 24k and various standard cartridge sizes. I thought it about time I tried filling 32k or 35k :)
memorymap.png
Here's my memory map so far, I have hardly filled it at this point but plan is to make many levels and see how big I can make it. I am compressing the level data too, so not sure how big it will get to be at this stage.
--
AndyH
HEWCO | Vic 20 blog
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Restricting BASIC to the +3K expanded RAM area

Post by Mike »

With a cartridge as intended medium, filling up BLK1..3 and BLK5 with all ROM is the most likely scenario and supported out-of-the-box by VICE.

Here's how I would fill these address ranges from disk, on real hardware:

Code: Select all

1 POKE55,0:POKE56,32:CLR:DN=PEEK(186)
2 N$="BLK123":GOSUB6
3 N$="BLK5":GOSUB6
4 SYS64802
5 :
6 SYS57809(N$),DN,1:POKE780,0:SYS65493:RETURN
The files "BLK123" and "BLK5" should be pretty self-explanatory, with $2000 and $A000 as their respective load addresses. SYS64802 does the reset.

As there is no direct way to initialise the internal RAM other than from data tables plus code in the cartridge ROM, you should effectively treat that area as undefined before starting your program.

When it comes to the RAMx area, please bear in mind that some people have installed these +3K as permanent internal expansion ... ;) ... so it's probably best to treat it as "RAM only" resource (and supply it on the cartridge as RAM chip, regardless).
User avatar
AndyH
Vic 20 Afficionado
Posts: 364
Joined: Thu Jun 17, 2004 5:51 am
Website: https://www.hewco.uk
Location: UK
Occupation: Developer

Re: Restricting BASIC to the +3K expanded RAM area

Post by AndyH »

Ah good, that's pretty much what my loader looks like. My tester was able to easily get it to run on the real hardware so thanks once again for helping me get there.
--
AndyH
HEWCO | Vic 20 blog
Post Reply