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?