From: Arvid Norberg (c99ang_at_cs.umu.se)
Date: 2001-03-10 10:53:33
On Wed, 7 Mar 2001, Ullrich von Bassewitz wrote:
> Saving registers is not done by the 6502 itself but must be done by the
> interrupt routine. The 6502 saves the condition codes (flags) and the return
> address.
>
> > I don't see what pushing ints onto the stack has to do with this.
> [...]
> > This means that I don't understand why the stack get messed up.
>
> Have a look at the following routine. It has the purpose to increment the
> stack. I've made it samewhat simpler than the last example (which was the
> actual routine minus 65C02 code and was optimized for speed):
>
> incsp: inc sp ; Increment low byte
> ; <-- Assume interrupt here
> bne @L1 ; Jump if no overflow
> inc sp+1 ; Overflow, increment high byte
> @L1: rts
>
> Now assume that the value of the stackpointer is $CBFF. This means that the
> low byte will overflow and the high byte has to be incremented, too. The final
> value (after calling the function) should be $CC00.
>
> If an interrupt occurs after incrementing the low byte (marked with an arrow),
> the value of the stack pointer at this point is $DB00 - which is not only
> wrong, but may also be outside the stack area.
>
> Now, if you call a C function, this C function will use the stack, and this
> means that it will use an invalid stack pointer.
>
> The problem here is, that the increment of the stack pointer is not atomic, so
> it may have an invalid value if the routine is interrupted.
>
I see what you mean. But isn't the stack pointer increamented
automatically by pha?
if so, wouldn't it be possible to write an interrupt handler like this:
handler:
pha
txa
pha
tya
pha
[..] ; push all the zero-page registers
[..] ; free for a C-function to do watever it wants
[..] ; pull back the zero-page registers
pla
tay
pla
tax
pla
rti
?
> The zero page locations are the working variables of the C compiler
> (comparable to real registers on other CPUs). Not saving these locations would
> be equal to not saving registers in an interrupt routine.
ok.
> >[..]
>
> The compiler is correct here. Characters are unsigned, so variable a can never
> be less than zero. If you want signed characters, you have to declare them
> explicitly as such:
>
> signed char a = -1;
> if (a < 0 || a > 2) cputs("a < 0 or a > 2\n");
>
> This code will not longer produce the warning. Please note however, that
> operations on signed data types are usually slower compared to the same
> operations on the equivalent unsigned data type, because the 6502 does not
> support signed data very good, so the compiler must generate additional code.
> For best performance avoid signed data types if you can.
ah, I thought it meant the entire expression. Now I see.
thanks,
---
Arvid Norberg
----------------------------------------------------------------------
To unsubscribe from the list send mail to majordomo_at_musoftware.de with
the string "unsubscribe cc65" in the body(!) of the mail.
This archive was generated by hypermail 2.1.3 : 2001-12-14 22:05:39 CET