On Thu, 9 Jan 2020 16:45:58 +0100
Philipp Klaus Krause <p...@spth.de> wrote:

> Currently, for the z80-related backends, there is some limited support
> for banked functions in SDCC (for calls that do not go through function
> pointers, the compiler can insert some glue code to a custom banked_call
> function).
> 
> What would need to be done to improve that?
> 
> For Z180 and eZ80 we know the hardware. But there are still many ways to
> set up stuff (different sizes of banked areas, etc).

No you don't actually. There are many of Z180 systems with a flat 64K
address space because the Z180 was an upgrade board to the Z80 originally
present and the original banking is used. Some of the more common old
ones are even hybrids (eg the XLR8R cards for the TRS80 have 256K of
Z180 linear space but the base system memory is 128K banked in 32K
chunks).

Not as common as with 65C816 (where some poor design decisions in the CPU
make it often better to use external banking) but still not unusual, and
in fact present even on current retrobrew hardware when you for example
put a Z180 CPU board in an existing RC2014 Z80 system.

> For Z80 and GameBoy we don't know anything: There are many different
> bank layouts and ways to switch banks.
> 
> What I would like is: A flexible scheme that allows code in banked
> memory, and also supports function pointers.
> Banked code should be able to call nonbanked code, code in the same or
> in other banks.
> 
> Should there be support in the linker? If yes, in what form?
> 
> What does FUZIX currently use?

Fuzix does the following

1. A small patch that adds a compiler option to selecte 'banked' compiles

This just changes the argument offset on the stack by two bytes, and
causes the compiler to emit

                push af
                call foo
                pop af

for function calls.

The existing stuff to set the code segment name is used so you compile
stuff into _CODE1 _CODE2 _CODE3 etc (and some names for common).

The compiler piece is trivial but important because those extra two bytes
are essential in order to make bank unwinding work properly in all cases.

2. Some hacks for the linker (and these are currently rather Fuzix
specific so would need cleaning up)

The linker hack uses the segment names (some of its it is hackish in the
sense the linker stuff is hardwired for some fuzix names like COMMONMEM
VIDEO FONT etc too).

The linker looks for calls that go between banks or banks and common

If a relocation is from code to code then it swaps the push af/call/pop af
with

                call __bank_n_m  ; where n/m are the banks
                .word funcaddr

and the platform provides specific banking functions according to need.
The extra push/pop af is removed and the extra 2 bytes on the stack are
needed by the bank switching code (it uses it to push the address of the
correct stub to switch back)

If a relocation is from data to code then it generates a small piece of
new code in the STUBS segment (in common) that does the inter bank call
and uses that address.

To ensure function pointer comparison works and to save space two
references to the same function via data use the same stub segment entry.
There is a little bit of additional linker ugly here in my changes to deal
with the case of ld hl,#funcaddr type stuff the compiler generates.

The actual linker relocation changes are pretty simple. What is hackish
is a) the way it turns names into banks and b) the way I generate the
output - I should have written a new linker output file format but I just
hacked something together outputting ihx files with the bank number then
the ihx data, and a tool that turns it into a bunch of ihx.

The other thing the linker code do with btw is the ability to output a
relocation map so you can make relocatable binaries nicely with it. Right
now I link it twice and tools analyze the binary to generate Fuzix
relocatable binaries or CP/M object files.

3. Not needed for Fuzix because I only bank the kernel at this point so
not present - setjmp/longjmp support for bank switching on the longjmp.


I have this in use on a variety of systems with both simple cases (2 x
32K kernel banks) to complex setups like the ZX Spectrum 128K with 4 x
16K banks of kernel code in the same window, and in ROM with the Tom's
SBC design where the kernel is banked 4 x 16K in EPROM in the low 16K.

Alan


_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to