Re: [cc65] c64 question

Date view Thread view Subject view

From: Ullrich von Bassewitz (uz_at_musoftware.de)
Date: 2001-03-06 15:58:05


On Tue, Mar 06, 2001 at 11:17:25AM +0000, Arvid Norberg wrote:
> My questions are:
>
> What am I missing? why doesn't it work the way I want it to?
> If I want to make a function that ends with an "rti" instead of "rts",
> is there a keyword/modifier in cc65 that does that to a function?
> in some compilers you can to write:
[...]

There is no such declaration for cc65, because the compiler does not have
enough information to generate the necessary code. Here is why:

An interrupt may not execute C code, without some helper code written in
assembler, because several routines may not interrupted and then called
recursively. This is not the fault of cc65, it's a problem of the 6502,
because it is not able to manipulate 16 bit values in one atomic transaction.

Assume for example the subroutine that is used to push an int parameter onto
the stack:

	pushax:	ldy	sp
		beq	@L1
		dey
		beq	@L2
		dey
	@L0:	sty	sp
		ldy	#0    		; get index
		sta	(sp),y		; store lo byte
		iny	      		; bump idx
		pha	      		; save it
		txa	      		; get hi byte
		sta	(sp),y		; store hi byte
		pla	    		; get A back
		rts	    		; done

	@L1:	dey
	@L2:	dey
		dec	sp+1
		jmp	@L0

If this routine is interrupted while the overflow from low to high byte of the
stack pointer is not corrected, any C routine using the stack (and most do)
that is called in an interrupt will overwrite parts of the stack that are not
owned by the function. The same is true for all other functions manipulating
the stack pointer.

So one condition for calling C code in an interrupt would be a separate stack.
This stack switching cannot be done by the compiler, because the second stack
has to be allocated somewhere, and the compiler has no knowledge how to do
that. This is the main reason that just using an additional keyword for
declaring interrupt handlers is not enough.

Another problem is that there are "registers" in the zeropage that may be
trashed by the code executed in the interrupt.

So, the second condition for calling C code in an interrupt handler would be
that the zero page locations needed by the compiler must be saved before
calling C code and restored afterwards.

A third problem may be performance: C code is slower than assembler code. How
much it is slower, and if this is a problem depends on your application. If in
doubt, check the generated assembler code.

A full solution would be to supply a library module that installs a short
wrapper, sets up a new stack, saves the zero pages registers and calls a C
routine via a pointer. On exit, the zeropage locations used by the compiler
and the old stack have to be restored before the rti.

In fact, the necessary routines exist, but not as part of a separate module.
They are part of the debug module, because the debugger faces the same
problems, if C code is interrupted by a BRK instruction. Just have a look into

	libsrc/dbg/dbgsupp.s
and	libsrc/c64/break.s

It would probably be worth extracting these routines, change them to handle
the interrupt instead of break, and place them into a new module. This way,
interrupt handler written in C could be supported. Having an interface similar
to the one for the BREAK stuff (see the debugger) would be nice. If someone
wants to do that, I would be happy to include this module in an upcoming cc65
release.

Apart from that, it is better to use a "void" parameter list for functions
that don't take any parameters. If the compiler knows that there are no
parameters, it is able to generate better code. An empty parameter list means
in C: "This function may take any number of arguments", which means that the
compiler has to generate code to remember the number of parameters passed.

Regards


	Uz


--
Ullrich von Bassewitz                                  uz_at_musoftware.de
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo_at_musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.


Date view Thread view Subject view

This archive was generated by hypermail 2.1.3 : 2001-12-14 22:05:39 CET