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