The initialization routines, crtxclear.asm and crtxinit.asm use chip specific features of dual dptr's and paging in "external" ram. These do not work on all MCS51 chips. Specifically, I am using the Silicon Labs EFM8SB2 and they do not work. I have re-coded them using standard 8051 code and attached that code here. These do work on the SB2 and should work on most any 8051.
Oops, I accidentally left debug code (references to count) in the code. Here are the corrected ones.
Hello John,
Our crtxclear.asm and crtxinit.asm haven't changed since 2007 and use intel mcs51 supported paging using sfr P2. When all code memory is internal to a device there is usually another sfr that can perform the same functionality, freeing up P2 for real external use. Paging has always been supported by Cygnal and later SiLabs MCU's but they have used multiple names and addresses for this paging sfr. Unfortunately every 8051 derivative manufacturer uses a different name and address for the paging sfr. For the EFM8SB2 the sfr is named EMI0CN. That is why SDCC decided to use the sfr _XPAGE for this purpose and all you need to do is define (declare) it somewhere overlaid on the name chosen by the manufacturer.
So what really is needed is that manufacturers add _XPAGE to their headers, preferably in a compiler independent manner.
Maarten
Yup:
adding:
Sfr(_XPAGE, 0xAA); // Point to the EMI0CN register
to my si_EFM8SB2.h file
and
Sfr(_XPAGE, 0xF6); // Point to the PAGE register
to my at89lp51xy2.h file
does the trick for both. I'm not quite sure how I would have known to do that. Is there a guide to setting up such a file for a new MCS51 varient?
How about the SDCC manual 4.1.1?
I still think there is an issue. I have been using SDCC for a long time and really love it!! I have boards in service using the Atmel AT89C51, the AT89LP51 and the Silicon Labs EFM8SB. I had just assumed that SDCC didn't know how to initialize XRAM and so wrote my code to not depend on it. Now, I have more insight and realize it would, except that I have not configured correctly. However, the AT89C51 has dual DPTR's and no equivalent of XPAGE, the AT89LP51 has both and the EFM8SB has no dual DPTRS but has an XPAGE equivalent.
I have no desire for external stack (as I assume most users do not), but it would me nice to have a common configuration so I could compile initializer code for any of my targets without modifying my installation. The compiler generates code that works for all. Should not the startup code do the same? The code I submitted does exactly that by not using either XPAGE or dual DPTR's.
All it takes for an MCU with no XPAGE but dual DPTR is that you assemble crtxinit.asm manually with DUAL_DPTR set to 1. And then link the generated crtxinit.rel explicitly. You do not need to modify your installation.
If you don't use an external stack or pdata then crtxclear.asm won't touch XPAGE. If you do use it, but there is no XPAGE, you could overlay it on ACC or B if you don't want to see P2 touched.
Your proposed solution is considerably slower than what we currently do and will impact everyone. This discussion has been had before and AFAIK this was the outcome.