Renesas R8C/M13B
The Renesas R8C/M13B is a 16 Bit Cisc Microconttroller with an 8 Bit bus.
Softgun can emulate its instruction set.
Corrections to the R8C/M13B Hardware Manual Rev. 2.0
Changing intXen bits
Chapter 11.9.4 states that the intXen bits can be changed without disabling the global Interrupt Flag with the "FCLR I" instruction. In this case it is recommended to switch the Interrupt level of only the affected Interrupt to "0" by changing ilvlXY.
But Chapter 11.9.7 states that it is necessary to disable the Interrupts with "FCLR I" before changing ilvle. This is a contradiction. A test showed that 11.9.4. is correct. It is possible to change the ilvlX registers without disabling interrupts
Changing and saving the Interrupt privilege level
- if the "ldipl" instruction is less than 3 cycles away from a "STC FLG"
instruction while Interrupts are enabled the CPU will halt.
- if an Interrupt occurs at 1 cycle behind an ldipl instruction the CPU will halt
Here a bad method to save the flags and change the IPL:
#define SAVE_FLAGS_SET_IPL_BAD(flags,ipl) { \
_asm("STC FLG,$@",(flags));\
_asm("NOP");\
_asm("NOP");\
_asm("NOP");\
_asm("LDIPL " ipl);\
_asm("NOP");\
_asm("NOP"); \
_asm("NOP");\
}
Renesas recommends to disable the interrupts when changing flags or the Interrupt privilege level. But I have a very timing critical application, so I never want to disable interrupts at all. I'm using the following trick:
No Interrupt can happen one cycle after the LDIPL instruction if the
instruction behind ldipl needs many cycles because instructions can not
be interrupted in the middle.
Here the good version:
#define SAVE_FLAGS_SET_IPL(flags,ipl) { \
_asm("STC FLG,$@",(flags));\
_asm("NOP"); \
_asm("NOP"); \
_asm("NOP"); \
_asm("LDIPL " ipl );\
_asm("ADD.B #0H,0400H ");\
}