Re: [cc65] __fastcall__

From: Alan Cox <>
Date: 2015-01-14 20:19:10
> It is no big problem to generate the stubs from within the linker. But there's
> additional information necessary to know in which bank a subroutine lives.
> Getting this right and configurable in a general way seems quite a task for
> me.

Yes - for any initial attempt I shall do something disgusting and
hardcoded as and when I get time to dig into it a bit further.

> Advantage is that no changes to assembler and linker are necessary, drawback
> is that all such calls have a runtime overhead. If later support is added in
> compiler, assembler and linker to mark these snippets in a special way, the
> linker could rewrite the ones where no bank switching is necessary as
>         jsr     _realroutine
>         nop
>         nop
>         nop
> to avoid most of the runtime cost.

Doing it via stubs avoids much of the cost and means if you are
sensible about how you lay out the binary (and in truth quite often
naturally) you get most of your calls to be efficient ones. Which is
the winner probably depends how the code is structured.

The linker does actually seem to have a lot of the framework in place
- I can declare ROM0, ROM and ROM2 to have the same addresses already
and put different code in each, and I think (need to test it for real)
that with the output file options I can also make it write them to
different files.

> Maybe you have ideas for simpler solutions. All bank switching ideas that have
> been discussed so far have been found to be quite some work.

For pure code banking the functions but with switches and shared stuff
in common usually works, and a lot of proprietary 8bit compilers of
old could do banking and overlays almost automatically - generally by
using stubs. I don't think cc65 is that different except that you'd
probably have no __fastcall (need registers for banking). As the
helpers in the library are called to work on registers they would need
to in common, and for speed that would I think be true anyway.

It does mean you can't easily bank data or even rodata (because you
take pointers to it and pass it out elsewhere eg in pritnf()) but for
pure code it's historically worked OK in the tools I've used. Not
perfectly, you get some spectacular new ways to shoot yourself in both
feet, it tends to break debuggers and if you are doing interrupt
handling it can be .. exciting 8)

There are details too - things like setjmp/longjmp need to be bank aware.

REU is certainly a bit different - that would be more like fast
overlays. You could use it, even with banking but you'd have to plan
very carefully so your "bank switch" occurred very rarely just like
with overlays. Not quite the same as casually building a big program.
Georam you'd probably have to use the same way - as if it was a
ramdisc. In theory you can use a 1541 8)

Other things like the 16K banks in the Atari boxes on the other hand
fit a banking model better.

Data banking is a whole different world and usually involves a lot of
clever compiler magic to work out which bank to use when and to manage
24bit pointers. SDCC can do bits of this on Z80 but it's not what I
would call trivial (in fact there is a paper on the algorithms
To unsubscribe from the list send mail to with
the string "unsubscribe cc65" in the body(!) of the mail.
Received on Wed Jan 14 20:19:17 2015

This archive was generated by hypermail 2.1.8 : 2015-01-14 20:19:19 CET