[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: cc65 / ca65: how to interface C and assembly?
- Subject: Re: cc65 / ca65: how to interface C and assembly?
- From: uz@spamtrap.musoftware.de (U. v. Bassewitz)
- Date: Tue, 6 Dec 2005 22:02:39 +0000 (UTC)
- Newsgroups: comp.sys.apple2, comp.sys.cbm, comp.sys.atari.8bit
- Organization: MU Softwareentwicklung
- References: <4395b60d$0$9636$9b4e6d93@newsread2.arcor-online.net>
- Xref: g2news1.google.com comp.sys.apple2:7147 comp.sys.cbm:12794 comp.sys.atari.8bit:3634
In comp.sys.cbm Linards Ticmanis <ticmanis@gmx.de> wrote:
> I'd like best to use inline assembly ("asm") statements inside a C frame
> function, but the code is not allowed to cross a page boundary, since
> this would destroy the timing of branch instructions; and it seems that
> ".align" is not allowed in asm statements.
The builtin inline assembler is not a full featured assembler, therefore
control commands (like .align) aren't accepted. A second reason is that
the inline assembler code is processed by the the optimizer, and handling
control commands in this stage would be too complex.
> Is there any way to tell the
> compiler that you want a piece of inline assembly to be page-aligned?
Alignment is done by the linker. If you want to embed your inline
assembler code in a C function, you can place this C function in it's own
segment using something as
#pragma codeseg (push, FASTCODE);
void fastcode (void)
{
/* Your code here */
}
#pragma codeseg (pop);
Using your own linker configuration, you can the place the FASTCODE
segment whereever you like. See the linker docs for more information on
how to do this. The FAQ does also have a paragraph that talks about code
placement:
http://www.cc65.org/faq.php#ORG
> I understand that there's a software-implemented stack, using "sp" for a
> stack pointer / base pointer, local variables and parameters are both
> stored on this stack, and addressed with "(sp),y" type instructions, and
> that for a number of stack manipulation operations, there are a couple
> of standardized "jsr"s to library code; but exactly how the different
> data types are stored remains unclear to me, also how to use zero page
> in a compatible way.
MagerValp has already given a good example. I can add a few things here:
The low 16 bit of a 32 bit value are returned in A/X as with 16 bit
values. The high 16 bit are returned in the zero page location named
"sreg". If you're using inline asm, you don't have to care about the
declaration, the compiler will do that for you. If you're writing
assembler modules, either use one of
.import sreg:zp
.importzp sreg
or include the file "zeropage.inc", which will give you access to all zero
page locations, the compiler knows about.
The following zero page variables can be used freely by assembler
functions:
ptr1, ptr2, ptr3, ptr4
tmp1, tmp2, tmp3, tmp3
But beware, other functions will also use these locations, so if you're
calling a subroutine, they may get clobbered.
regbank
is a 6 byte zero page space used for register variables. It has the
disadvantage that any caller expects the current to survive the function
call, so you need to save it somewhere. The advantage is that you can
expect to behave other functions in this way.
For more examples on how to interface with assembler, just have a look at
the library sources, which can be found in the source archive.
Regards
Uz
--
Ullrich von Bassewitz uz@spamtrap.musoftware.de
22:38:08 up 62 days, 6:25, 11 users, load average: 0.00, 0.02, 0.03