Relocatable Sideways ROMs ========================= mdfs.net/ROMs/SROM/Modules J.G.Harston Introduction ------------ Many ROMs programs do not use the full 8K or 16K of the ROM, and have spare space in them. You can use this spare space to add extra ROM code. This is fairly easy to do as long as no more than one component of a multi-code ROM claims memory or provides a language. A service ROM that does not provide a language has no language entry, so the bytes at &8000-&8002 are unused. Usefully, this is the same size as a JSR instruction. Using this, you can find ROM images where two 8K ROMs have been joined together, with the second ROM starting at &A000 having the unused language entry replaced with a JSR to the first ROM's service code, and the first ROM's service entry jumping instead to the JSR at the start of the second ROM. The following shows an example of this: ; Lower ROM ; Lower ROM 8000 BRK:BRK:BRK --> 8000 BRK:BRK:BRK 8003 JMP &801E 8003 JMP &A000 801E Lower ROM service code 801E Lower ROM service code ; Upper ROM ; Upper ROM A000 BRK:BRK:BRK --> A000 JSR &801E A003 JMP &A03B A003 JMP &A03B A03B Upper ROM service code A03B Upper ROM service code You can see that in the joined ROM the service entry at &8003 jumps to the upper ROM, which then calls the lower ROM's service code before continuing into the upper ROM's service code. Obviously, the upper ROM code needs to be relocated or assembled at &A000 for it to work correctly. This is very close to how the combined DNFS ROM works, except that the upper ROM only has service code and none of the usual ROM header data. BBC Sideways ROMs (Relocatable Modules) --------------------------------------- 16-bit address must always be in adjacent bytes: don't use LDA #address AND 255:LDA #address DIV 256 must use LDA vector+0:lda vector+1 with .vector:EQUW address 16-bit addresses must always by 6502-style little-endian: don't use EQUB address DIV 256:EQUB address AND 255 must use EQUW address demo code SMLib Final byte must not be &00 or &FF to prevent merging into following empty space. The simplest method is to add purely service code to an existing ROM. I To do this, you need the image of the ROM you are adding to, and the source code (or a method of relocating the image) for the ROM code you want to add. This is done by changing the destination of the service call entry at &8003 to the start of the spare space at the end of the ROM. At the start of this spare space, the new code firstly calls the old service handler, and then continues with the new code's service handler:
8003   JMP SERV              -> 8003   JMP MYCODE
...
SERV   \ Service handler
...
                                MYCODE JSR SERV
                                ...    \ My service handler
The additional code can even be a relocated ROM image with the language entry point in the first three bytes changed to the JSR SERV instruction. The following instruction will then be the relocated jump to the additional service handler.

Any number of ROM code fragments can be joined together like this. However, as each fragment is independent of each other, only one can claim workspace and use the workspace byte at &DF0+rom, and only one can be a language and be entered at &8000. To be entered as a language, the entry at &8000 should be changed to jump to the ROM code fragment's entry point:

8000   BRK:BRK:BRK           -> 8000   JMP MYLANG
8003   JMP SERV              -> 8003   JMP MYCODE
...
SERV   \ Service handler     -> SERV
...
                                MYCODE JSR SERV
                                ...    \ My service handler
                                MYLANG \ My language startup







BootFix
ServROM
SWOsw7F
HADFS Support
DisAssem
MouseROM
LibMax
BLib.RelocROM

newmodes



Notes:
------
Service code *must* return X=ROM number as other service routines expect
X=ROM number on entry. Consequently, LDX &F4 inserted into linked headers
so X contains expected contents.

Load as:

20 xx xx JSR xxxx
xx xx    LDX &F4
4C xx xx JMP xxxx






CHAIN "SMJoin"
--------------
SMJoin joins a collection of sideways ROM modules into a single file. It
does the equivalent of *SMLoad but without loading them into sideways RAM.
You can then load the resultant file into sideways RAM in one go, or
program it into an EPROM to have present permanently.

When SMJoin is run it prompts you for the files to join. You can also
enter *commands at this prompt.

The first file can be a normal non-relocatable ROM or a ROM with a
language entry. All subsequent files must be relocatable modules. When you
have entered all the files to join, press . You will then be
prompted for the file to save the joined modules as.

*SMList
-------
Lists all relocatable modules in the following format:

No. Position Name                Version
  1 FFFF8000 TERMINAL             1.00               (C)1984 Acorn
  2 FFFC8000 BASIC                4.00               (C)1984 Acorn
  3 FFFB8000 Edit                 1.00               (C)1984 Acorn
  4 FFFA8000 ViewSheet            1.00               (C) 1984 Acornsoft
  5 FFF98000 DFS                  2.24               (C)1985 Acorn
  6 FFF78000 HADFS                5.62 (17 Feb 2012) (C)J.G.Harston
  7 FFF7B7E0 NullKeyboard         0.12 (01 Aug 1998) (C)JGH
  8 FFF7B80B SoftRTC              0.10 (23 Nov 1992) (C)JGH
  9 FFF58000 VIEW                 4.00               (C)JGH & Acornsoft
 10 FFF5BB79 BootFix              0.00 (10 Oct 2012) (C)J.G.Harston
 11 FFF5BBB9 Mouse                1.00 (12 Mar 2006) (C)J.G.Harston

The high word of the position is the ROM bank the module is in, the low word
is the address within the ROM bank of the start of the module.

*SMLoad 
------------------
Loads a relocatable module or sideways ROM to the highest available area of
sideways RAM large enough.

If the loaded file has a relocation table it is relocated and linked into
the module chain. If it does not have a relocation table then it will only
be enabled if it is loaded to the start of a bank of SRAM at &8000.

Possible errors are:
  133,Not enough SRAM
  214,File not found
  220,Syntax: SMLoad 

*SMFree
-------
Displays the amount of free sideways RAM, showing how much is free in each
bank.





Relocatable Module code layout
------------------------------
Standard sideways ROM header assembled to start at &8000, with the
language entry replaced with:

8000 EQUB &00
8001 EQUW RelocationTable

The relocation table must be the last item in the sideways ROM.

The relocation table is recognised by &8000 contining &00 and &8002
containing a byte with bit 7 set.