Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
hi!
I was digging into the sdcc, and found out, that transparent bank switching is almost working!
It was always! The only thing that was missing - a correct bank number in the structure, that
is generated for every far call. The trampoline functions always existed in crt, and there is
no problem with them. You may even call a subroutine in bank2 from a subroutine in bank1, and
that all works perfectly, the banks are saved, switch is done at the proper moment, and banks
restored after all correctly!
So, i wrote a very simple postprocessor, that identifies the bank number of a symbol and fills
the compiler-magic structure with the correct values.
This postprocessor takes names of object files, which are passed through a command line, loads
symbols from them, make a "name --> bank number" dict, then takes the last object file, parses
it (it has a trivial structure) and patches the bank number in the object file and outputs the
result to stdout.
The patch target is:
call banked_call dw <far_function_offset> dw 0 <--- HERE
Postprocessor identifies a call to banked_call, ensures that it is really a call, identifies
that there is a
dw <far_function_offset>
after it (another reloc), finds a bank in the "name --> bank number" dict, patches the
dw <bank>
with a bank number.
This is the early alpha version of a postprocessor, it may contain some bugs, so i appriciate
your help with testing and fixing it.
So. In your code, everything you should do is to declare a function, with a __banked keyword.
Every call to such function is made by SDCC through a trampoline function call generated by it
and is fixed by my postprocessor then. Watch through the make.bat script for the details on
how it is done.
Your code in some .c file that is may be compiled, say, with -bo2 switch or a #pragma bank 2:
int some_bank2_proc(int a, int b, int c) __banked { printf(" in %s\n", hello2); return a + b + c; }
and in the other place, say main(), you just call this function:
int somevar = some_bank2_proc(16, 32, 64);
Compile both files. Fix the object file from which the far call is made, with far_fixer.py,
by passing BOTH objects to it in right order. You must fix EVERY object file, that contain far
calls (only one in this example). If you forget one, there will be a crash. Then you just link
patched files.
GITHUB: https://github.com/untoxa/sdcc4_farcalls_example
any questions? welcome.
Last edited by toxa (2020-04-25 15:59:57)
Offline
this is the difference, between the sdcc-generated object file and a patched object file:
Offline
i just fixed a vexing bug in far_fixer
Offline
i fixed one more issue, when the target function is in the same file. not an extern. v0.2 now.
Offline
one more issue with object-local banked functions fixed. v0.3a now.
Offline