Hi folks, that didn’t take long – did it?
Two updates on the same day… one last night (after midnight) and one this evening. The thing is Peer suprised me with a huge update of the “C”-BIOS headers.
I updated all example files (where update was needed), included a new switch into the project configuration window and changed some “C” default settings.
The main change for the user is:
FRAMEPOINTER usage as of now is depricated!
You can still use them if you really are in love with them – but they appear not to be needed anymore in order to ensure correct calling of BIOS functions. For people who used framepointers before this will be a huge performance boost. Also it seems that most “-O” options work good now (for debugging perhaps you should still turn optimization off).
For some compatibilty reasons I also keep the compiler options:
Please … be our guest to experiment with the new “system headers”.
A short translation of Peers accompanying notes in regard to the changed headers:
I nearly changed “everything”. I created an “inline”-version of the system interface and a “function”-version. Both now work without Framepointer usage, that is with the CCFLAG “–fomit-frame-pointer”.
I have rewritten all macros of the inline version, since I now have quite a better understanding concerning gcc asm constraints (result of diverse empirical experiments). One significant factor: Even if one sets a constraint that a dedicated register should be used, there is no guarantee that the register actually WILL be used. If the register one wants to use is not otherwise “occupied” the compiler happily gives it to you. But if it is already in use – than you will get another one – even if that is in opposition to the given constraint. If there is no free register at all – than the compiler exits with a “spill”- error. That is the reason I formerly made use of the framepointer. With the new gotten knowledge the current non-frame-pointer variant was build – which results in quite a performance boost.
Within the function-version I have now implemented all BIOS calls and called upon all tricks I could muster and that are compliant to the gcc calling conventions. Lots of cool things are possible. A major part of the BIOS calls could be mapped DIRECTLY to “C” functions. For all others the overhead for parameter passing, register save/restore and return values and additional jsr/jmp/rts has been reduced to a minimum.
First rudimentary test with “The Count” (and comparing to old RC01 version) show that a speedup of about 2300 cycles could be acchieved with the inline version and about 2800 cycles by using the functional version. Using the functional version the size of binary was additionally reduced to about 25KB (from 29KB), the inline version was still smaller than the “original” with about 26.5 KB. Of course additional tests have to follow. Additional finding: -Os results sometimes in a better performing binary than the other -On variants.
One major reason for the performance gain using the function version lies in the fact that the compiler internal optimizations are much more effective if the programmer does not interfere with additional “asm” statements all the time. Exactly this comes to bear using the function version, since the main handling of parameters and return values is being left to gcc and its internal mechanisms.
An additonal bonus: The generated assembler code now shows the correct symbols (namings) of all BIOS calls and no mere plain addresses anymore (also for RAM/ROM BIOS variables). Even from the point of view of an assembler programmer, the generated code looks much better than before. Naturally – not everything is perfect – but as a compile result – it actually does not look half bad.
Alltogether I had to build 4 versions of every BIOS function (1 x for the inline version, and 3 for the function version). That took quite a lot of diligence and concentration, there just might be some typos hidden somewhere.
We now have direct-page adressing in “C”, we do not need Framepointers anymore and we have a solid interface to the BIOS – where I can’t think of any additional performance gains.
Do play around with the current version, and look at the generated assembler code and the *.lst and *.rst files! Much of that looks really well now, at least much better than before – in my humble opinion anyway.
I still need to clean up some system files, add comments and get rid of superfluous volatiles, perhaps there are still some inconsistencies with datatypes that also require some attention. But this is all small stuff.
Also on my schedule is to build a document that includes all function headers and systems calls – as an API reference and documentation for the “C” programmer.
Feedback, comments, suggestions and bugfixes as always are welcome!