Hi Neil,
Just in case you're not already doing it, there are other little bits of memory you can use - for example the space between $400...$7FF is free, as is $900...$CFF. Then, of course, you have the whole of $E00...$2FFF to use, the only caveat being that older DFSs on the B/B+ require at least $E00...$10FF for themselves, so you have to load the code to a higher address in memory and relocate it down to its correct place when everything's loaded (see later).
You can also use $D00...$DFF, provided you put an RTI instruction at $D00 (as it is the NMI entry point), and you reset all the vectors to their defaults in the OS with some code which looks a bit like:
Code:
SEI
LDX #0
LDA $FFB7
STA resetvectorloop + 1
LDA $FFB8
STA resetvectorloop + 2
resetvectorloop:
LDA $FFFF,X ; self modified to the default vector table in the OS
STA $200,X
INX
CPX $FFB6
BNE resetvectorloop
CLI
(see Advanced User Guide P265)
This is because some paged ROMs can claim the vectors for themselves, but they then use a table at $D9F to indicate this (which if you overwrite with code, could potentially screw up calls to OS routines in your game - AUG P326).
In fact quite a lot of games have their code assembled at a low address like $900, but then load at $1900, with their execution address set to a small routine at the end of the executable which selects the tape filing system (to release the DFS workspace at $E00...$10FF), resets the vectors, and relocates the entire code block to its 'real' location in memory.
When you get
really desperate, there are also other little bits, e.g.
$880...$8BF
$380...$3DF
and even, the bottom of the stack from $100 upwards (as much as you dare use), provided you set the stack pointer to the top of the stack with
Code:
LDX #255
TXS
first.
I'll check out the latest build before I leave work tonight (no internet at home, the horror!)