I'm seeing odd behaviour with initialised xdata which somehow prevents my code jumping to the Nordic bootloader on the nRF24lu1+. I have isolated it to a fairly small test case, viz.:
__sbit __at 0x83 P0_B_D3;
#define bootloader() __asm ljmp 0x7800 __endasm
static unsigned char __xdata testvar = 'A'; /* Works if its __data, or if initialisation is performed from within main(). */
if (!P0_B_D3) /* Test if a button in P0.3 is pressed. */
I'm building using the SDCC defaults, 'sdcc test.c; packihx test.ihx > test.hex'.
It seems that SDCC is doing something strange with the initialisation of xdata (xinit) which is screwing with the ljmp. NB it also seems to upset interrupts. Anyone with a bit more understanding of .lst files than I care to hazard a guess as to what is going on?
I believe its because it has a dual data pointer - see nRF24lu1+ Product Spec v1.1, section 15.1.9 and the SDCC manual, section 4.1.1.
Thus the default crtxinit.asm requires reassembling with DUAL_DPTR set to 1 and the test code needs:
__sfr __at 0x92 DPS; /* Data Pointer Select register, used by SDCC's startup xdata initialisation. */
This now works.
Checking the rest of the startup code, the XPAGE register is used by the xstack functionality in crtxstack.asm, so I'm guessing that won't work on the nRF chip (or others with a dual data pointer instead of XPAGE) . Its also used by the XRAM clear in crtxclear.asm, so this may mean XRAM isn't properly cleared at startup.
It looks like these should also have DUAL_DPTR conditional code.
No, crtxstack.asm and crtxclear.asm cannot use DUAL_DPTR.
The xstack and pdata together use at most one page of 256 bytes. The problem is that we need something to select the page. On the original 8051/52 the high byte of the address was on P2. On modern devices with internal XRAM P2 is free for I/O and we need a special sfr to set the page. But some devices don't have such an sfr! Luckily most if not all these devices have dual dptrs so that can be used as an alternative for crtxinit.asm. Without the page sfr all MOVX @Ri usually/probably refer to the first page. Thus if you keep xstack and pdata between 0x0000 and 0x00FF this will work.
In crtxclear.asm the xdata is cleared with the dptr so no problem here.