To solve the abi changes, I went through and converted my asm code to use the 4.2 conventions (ie a,hl,de) and then added wrapper code for old versions of sdcc to put the stack into the same registers. Anything I hadn't converted, I just added a __stackcall in the function declaration and it worked without changes. I'll slowly convert my asm over time as I do bug fixes on that code. I usually write my assembler as inline C functions, it's sort of all C then and I can mix C and asm (functions) as needed, so this may not help you. I tend to only write assembler if I really have to get the performance up, and then typically in low level rendering or maths functions, that needs fast looping.
sdcc 4.2 also supports undocumented instructions, so we can use ld a,iyl. Though I'd already written a macro to do this where I really needed more registers for performance (eg line rendering, 32 bit multiplies, decompressing). Unfortunately this feature has a side effect of producing a non-existent opcode in the compiler (bit 0,iyl), when there are too many if statements lined up, but I'm sure that'll get fixed soon.
Code: Select all
#if SDCCVER >= 420
#define __stackcall __sdcccall(0)
#else
#define SDCC_STACK_ABI
#define __stackcall
#endif
// Converted, works on both, but with 4.2's speed advantage
uint16_t add( uint16_t a, uint16_t b ) __naked {
(void)a;
(void)b;
__asm
#ifdef SDCC_STACK_ABI
pop af
pop hl
pop de
push de
push hl
push af
#endif
add hl, de
#ifndef SDCC_STACK_ABI
ex de, hl
#endif
ret
__endasm;
return 0;
}
// Not converted, still works on both, but all those stack calls.
uint16_t sub( uint16_t a, uint16_t b ) __naked __stackcall {
(void)a;
(void)b;
__asm
pop af
pop hl
pop bc
push bc
push hl
push af
sbc hl, bc
ret
__endasm;
return 0;
}