My last public “announcement” was, that I wanted to play some games on PS4. I did that, I played thru The Last of Us (Part 1 and 2). Great games IMHO.
I bought a new computer (my iMac is slowly falling apart) – and will probably continue to play some games which I couldn’t play before – my first new computer since over 10 years – I have some catching up to do!
Nonetheless I am near the baltic sea again and my new computer is at home, and here I am sitting in front of my laptop and think about “the old days”.
This is what THIS is about:
Ok. Forget that on my Laptop I have not configured Vide correctly – and all vectors are open (and I don’t have openGL)…
What you might discern though is a “BANK 0” in the middle!
This is my first test to do bankswitching in “C”! – The “BANK 0” is output in bank 0 (what a surprise) and the rest is as usual printed in bank 1.
In the following I will go into detail how I did that. At one stage this will be automated in Vide – but not yet – for now it is manual “labour”.
(And the current stage will give Peer the creeps – because I didn’t do it “right”. But you know me – this started as a proof of concept, and now that it is working – it will not change soon 🙂 ).
In order to achieve bankswitching a couple of thing must be ensured/considdered:
- there ARE two banks (64k)
- the switching of banks must be done “supervised” – in a controlled known “stable” area
For now this is ensured by building two different “bin” files. At least the bank 0 – must be exact 32768 bytes long.
The second bank must be concatinated to the first bank. This can be manually done in VIDE using the
(and I am sure there are Unix/Windows commands that can also be used).
The Bank 1 must start at exactly the offset 32768!
The switching must be done in “neutral” zones. These are areas of the program which are EXACTLY the same for both banks. For the time being I chose the “beginning” of each bank.
My first try for this was to use the section “.cartridge” – define the bankswitching functions within that region.
This is not possible using GCC – since that section contains per default “data”. When I put a function within that section, than gcc replies with an error: “… causes a section type conflict”. This can not be easily circumvented.
The “cleanest” way to circumvent this would probably be to define a “.cartridgeBoot” section, which would start right after the “.cartridge” section. This is probably what Peer would have (me) done.
But in order to do that I had to build a new CRT0 file – and actually I wanted to just “test it out” and not build a new “C” environment.
After a couple of tests – I came up with the following.
Still using the “cartridge.c” file – but adding “direct” assembler.
This is the source:
Everything from line 42 to line 106 is “new” and needed for bankswitching support.
The “cartridge.c” file in both “banks” must be “nearly” equal.
“Nearly” means – they must be the SAME size, everything must be at exactly the SAME position. The only thing you are allowed to change is the contents (but NOT the length!!!) of the array “bankFunctions”.
In your “bank 0” definition here go all functions that should be accessable from bank 1.
In your “bank 1” definition here go all functions that should be accessable from bank 0.
In my example I only filled in one “test” function – and it is called “bank0FunctionTest” – and all it does is to print the “BANK 0” string:
The exact function name – and the address of the function is only known to “bank 0”.
Within bank 1 you do not have any information about its address or its name.
But since the function was put (manually) first in the function array – and even bank 1 “knows” that… we can call the bank 0 function via its index (in this case 0).
Thus the call from bank 1 looks like this (line 8):
What one probably should do is a “#define BANK0_FUNCTIONNAME 0” and than use that definition in the call – it makes the code more readable.
If in bank 0 you want to call a function from bank 1 – than exactly the same must be done –
- use the subBank1(xxx) function (instead of the subBank0(xxx) function)
- “declare” callable bank 1 functions in the “cartridge.c” file of bank 1.
The “subBankX” functions are the “usual” bank switching functions and are documented somewhere in Vide and this blog – so I will not repeat myself here.
All things considered – it was actually pretty straight forward and “easy” to add multiple banks for “C”.
It is a bit of a bore to actually work with it right now, because you have to always “pad” bank 0 to 32k and concatinate both bin files. For the time being – if you use it – you probably should write a script for that.
But sooner or later I will (most likely) support this in Vide – and it should than be largely automated.
All this was done because I am thinking about getting Aklabeth II out of it’s beta stage.
To do that I think I may want to add:
- more text (instruction/intro)
- saving of current game (DS 2431)
… since the beta is already scratching the 32k mark… I think I will go for 64k … and this obviously “needs” bankswitching.
64kB PCB’s can now be found “everywhere” so this cart will still fit/and be available for every vectrex – and not “just” VecFevers or “PiTrexes”.