SDCC has six Rabbit-supporting ports: r2k for the Rabbit 2000, r2ka for the Rabbit 2000A, 2000B, 2000C and 3000, r3ka for the Rabbit 3000A, r4k for the Rabbit 4000, r5k for the Rabbit 5000, and r6k for the Rabbit 6000. Some Rabbits support two different memory types (Rabbit 4000 and later), two different memory access modes (Rabbit 5000 and later), four different instruction set modes (Rabbit 4000 and later). All SDCC ports assume 8-bit memories, 8-bit memory access mode. The code generated by the r2k, r2ka, r3ka ports uses 00/default instruction set mode (the code generated is also compatible with 10 and 01 instruction set mode, but not 11/enhanced instruction set mode). The code generated by the r4k, r5k, r6k ports uses 10 instruction set mode, and is not compatible with other instruction set modes.
| Port vs. Device | R2K | R2KA | R2KB | R2KC | R3K | R3KA | R4K | R5K | R6K |
| r2k | Y | y | y | y | y | y | y | N | N |
| r2ka | n | Y | Y | Y | Y | y | y | N | N |
| r3ka | N | N | N | N | N | Y | y | N | N |
| r4k | N | N | N | N | N | N | Y | N | N |
| r5k | N | N | N | N | N | N | y | Y | y |
| r6k | N | N | N | N | N | N | N | N | Y |
Legend:
Y - The code this port generates is the best for this CPU.
y - The code this port generates will work on this CPU.
N - The code this port generates will not work on this CPU.
n - The code this port generates will typically not work on this CPU.
There are multiple wait state bugs present in some of the the Rabbits. The difference between the r2k and r2ka port is additional wait state bug workarounds only. If all memory used has zero wait states, code from the r2ka backend can be safely run on the original Rabbit 2000.
The r2k and r2ka port assume that the whole stack has the same number of wait states (code from the r2k and r2ka ports can fail is the stack spans memories with a different amount of wait states).
The Rabbit 2000 has some wait state bugs that SDCC does not work around. These bugs result in the number of wait states used being one less than configured for some instructions. The workaround has to be supplied by the user, by configuring all memories that do use wait states to use on additional wait state.
For all Rabbit ports, SDCC assumes that all data memory is at least as fast (i.e. does not need more wait states) as all code memory. Code where this is not the case (e.g. code in fast Flash writing into slow battery-backed SRAM) will have to be written in assembler by hand.
| Bug | R2K | R2KA | R2KB | R2KC | R3K | R3KA | R4K | R5K | R6K |
| ioi / ioe prefix bug | x | ||||||||
| ddcb / fdcb wait state bug | U | ||||||||
| conditional jump wait state bug | U | ||||||||
| ldir / lddr wait state bug | U | ||||||||
| mul wait state bug | w | ||||||||
| ldir / lddr split bug | S | ||||||||
| new ldir / lddr wait state bug | w | w | w | w | w | ||||
| 16-bit mode alignment bug | x | ||||||||
| ioi / ioe bit bug | x | x | |||||||
| ret cc bug | x | x | |||||||
| rmw wait state bug | W | W | W | W | W | W | W | W | |
| 16-bit vs. 8-bit wait state bug | W | ||||||||
| dma vs stack prot. bug | X | ||||||||
| 16-bit dma vs. ldir / lddr / etc. bug | X | ||||||||
| cplx bug | x | ||||||||
| dma match bug | X | ||||||||
| ex jkhl, bcde alt reg bug | x | ||||||||
| ldbyte bug | x | ||||||||
| puma bug | x |
Legend:
x s w u - bug present, worked around by SDCC.
X S W U - bug present, not worked around by SDCC.
w W u U - wait state bug, only relevant when the Rabbit is configured to have wait states for some memory.
s S - instruction / data split bug, only relevant when instruction / data split is enabled, which is currently not supported by SDCC.
u U - bug can be worked around by the user by configuring memory that needs wait states to use one additional wait state.
The 16-bit mode alignment bug only affects 16-bit mode, which is not currently supported by SDCC.
The rmw wait state bug is only relevant when executing fast code writing to slow memory, such as code in fast RAM writing to slow battery-backed SRAM.
The 16-bit vs. 8-bit wait state bug is only relevant when the target system uses both 16-bit and 8-bit memories for code, and the 8-bit memory requires wait states.
The 16-bit dma vs. ldir / lddr / etc. bug is only relevant when using DMA and the target system uses 16-bit memory for code. Since SDCC uses the block move instructions like ldir, lddr, etc. without applying a workaround, this means that code execution and DMA may then not happen at the same time. A possible user workaround is to not use DMA when using 16-bit memory for code. Among all Rabbit 4000-based RCM and BL modules, only the RCM4000 and the RCM4010 use 16-bit memories.
The dma match bug is only relevant when a DMA termination mask register is set to a nonzero value.
External interrupts need to be handled via a custom crt0. For internal interrupts, there is compiler support that creates the internal interrupt table from the declared interrupt handlers in the file containing the main function.
void handler(void) __interrupt(0) __critical
{
… // A hardware interrupt handler that runs at the priority of the interrupt (i.e. it can only be interrupted by interrupts of higher priority)
… // Automatically inserted as internal interrupt 0 (periodic interrupt) in internal interrupt vector table if declared in the file containing the main function.
}
void handler(void) __interrupt(2)
{
… // A software interrupt handler (interrupt number 2 is rst 0x10)
… // Automatically inserted as internal interrupt 2 (rst 0x10) in internal interrupt vector table if declared in the file containing the main function.
}
void handler(void) __interrupt
{
… // A hardware interrupt handler suitable for use as handler for an external interrupt
… // Can be used jumped to in a custom crt0 containing the external interrupt vector table
}The internal interrupts 2 to 7 are software interrupts (for the rst and syscall instructions). Hardware interrupt handlers written in C either run at the priority of the interrupt (with __critical) or at the priority of the code executing before the interrupt (without __critical). More complex prioritites (changing priority while the handler is executing) require interrupt handlers written in assembler.
Most Rabbit instructions operate on a 64K logical address space. The Rabbits support a 1M (up to Rabbit 3000A) or 512K to 16M (from Rabbit 4000, configured via MECR register, default is 1M) physical address space, which the logical address space is mapped into via a memory management unit (MMU).
5#5
SDCC assumes a 1M physical address space, and that memory for the program and constant data (typically flash) is located from 0x0 in the physical address space, up to at most 0x7ffff. It assumes that memory for non-constant data (typically RAM) is mapped from 0x80000. This is the typical hardware configuration for Rabbit-based systems, including the Rabbit Control Modules (RCM).
The logical address space is divided into four segments, which the MMU maps into physical address space. SDCC uses the Rabbit ”Root” segment for the SDCC code, gsinit, etc segments (startup code, const data not in __far, program code in small memory model). It uses the ”Stack” segment for the SDCC data segment, stack and heap (non-const data no in __far). The SDCC xdata segment (non-const data in __far) is placed in physical memory above 0x80000 (exact location can be given by --xram-loc), the SDCC xconst segment (const data in __far) is placed in physical memory above 0x0 (directly after code, gsinit, etc). The Rabbit ”Data” segment is not used directly by SDCC. Its intended use is for user-defined named address spaces. The Rabbit ”XPC” segment is used for the SDCC xcode segment (program code in medium memory model).
The size of the Rabbit ”Root”, ”Data” and ”Stack” segments can be adjusted according to user needs by setting up the SEGSIZE register in __sdcc_external_startup and the --data-loc command line option (the value for the option shall be 0xS000, where S matches the upper nibble of the SEGSIZE register).
Pointers to objects that are not __far-qualified objects are represented by their logical address as 16-bit value. Pointers to objects that are __far-qualified are represented by their physical address as 24-bit value.
The default crt0 that ships with SDCC uses a 32KB ”Root” segment followed by a 8KB ”Data” segment, a 16KB ”Stack” segment and the 8KB ”XPC” segment.