SDCC puts in code for initializing xdata that directly
writes to port 2. The xdata command in Cygnal's 8051's
accesses interal "extern data"--it is not external. As a
result, the direct control of P2 to set the proper page
before doing the movx @r0, a command fails on these
products.
robertr@hildalecity.com
Logged In: YES
user_id=589052
Hi,
you're probably talking about code that is generated by
_mcs51_genXINIT in sdcc/src/mcs51/main.c near line 172
you can adapt the code there (hopefully 'just' use another
paging
register?), then recompile sdcc and have a go at your code
again.
Could you give a pointer as to which/how the cygnal
devices differ?
Frieder
Logged In: NO
I am using W95 (not linux) but have MSVC 6 for programming
C++. I bought it but never got good at it; is SDCC adaptable
to MSVC 6 for a WIN32 console application? The place you
mentioned is the perfect place to put in my own initialization
code that doesn't use P2. Maybe you can give a pointer or
two on recompiling the source with MSVC Visual Studio.
While we are recompiling the source, there is a pointer to
function error that ought to be found where calling a function
from an array of function pointers generates bad code
because someone used the wrong addressing mode; this
should be a very simple fix of the proper fprintf statement.
Logged In: YES
user_id=603650
Check the sdcc manual, section 2.4.7: Building SDCC Using
Microsoft Visual C++ 6.0/NET (MSVC) at
http://sdcc.sourceforge.net/doc/sdccman.html/node14.html#S
ECTION00034700000000000000
Jesus
Logged In: YES
user_id=589052
Hi,
with the cygnal deviating from the standard 8051 core
patching the compiler currently seems the only way
to properly initialize it. This is not nice.
Maybe the 8051 port should switch to an initialization
via an external file crt0.s as the z80 port does?
Frieder
Logged In: YES
user_id=603650
There is a simpler solution to this problem than using an
external initialization file crt0.s: If option --no-xinit-opt is
used, the initialiazion of external RAM can be placed directly
in _sdcc_external_startup(). A bonus to this would be the
use of dual dptr registers when available.
Jesus
Logged In: NO
I did as advised; used the --no-xinit-opt and source code
something to this effect (actual tested source code not
available at time of posting)
main() {
... Variable declarations
_asm
mov r0, #l_XINIT
mov r1, #(l_XINIT >> 8)
mov r2, #s_XINIT
mov r3, #(s_XINIT >> 8)
mov r4, #s_XISEG
mov r5, #(s_XISEG >> 8)
00001$:
mov a, #255
add a, r0
mov r0, a
mov a, #255
addc r1, a
mov r1, a
jnc 00002$
mov dpl, r2
mov dph, r3
clr a
movc a, @a+dptr
inc dptr
mov r2, dpl
mov r3, dph
mov dpl, r4
mov dph, r5
movx @dptr, a
inc dptr
mov r4, dpl
mov r5, dph
sjmp 00001$
00002$:
_endasm;
I am wondering why not use something like what is shown
above so 8051 variants that don't accept P2 paging for xdata
will still work? This code is only executed once on startup, so
efficiency and code size are not a primary concern; I would
tend to side with greater reliability than code size or
efficiency in this case. I am posting this mostly as a solution
around this problem, since I consider the problem essentially
solved, now.
robertr@hildalecity.com
Logged In: YES
user_id=104682
Perhaps the "hard coded" initialization should be a simple
LCALL instruction, and move this code into the library.
This same approach is used for _sdcc_external_startup()
today, and it allows a "default" version to be in the
library, and users can easily code their own and the linker
will use their code rather than the default copy in the
standard library.
-Paul
Logged In: YES
user_id=591031
Hello Frieder,
Since nobody answers your question, I'll give you the answer.
The cygnal devices come in four different flavours with regard
to internal xram:
1) no xram, nor external memory interface: nothing to be done
with internal xram/external memory interface:
2) 'just' another paging register EMI0CN at 0xAF
3) 'just' another paging register EMI0CN at 0xAA
4) not 'just' another paging register, but a paging register
EMI0CN at 0xA2 in an sfr-page (0).
Especially the last one will give most problems I guess. The
best approach I see is either use the generic solution or use
the move-it-to-library option. The last one would be my
preferred option.
greetings,
Maarten Brock
Logged In: YES
user_id=589052
Hi,
> The cygnal devices come in four different
> flavours with regard to internal xram:
> 1) no xram, nor external memory interface: nothing to be
done
> 2) 'just' another paging register EMI0CN at 0xAF
> 3) 'just' another paging register EMI0CN at 0xAA
These could maybe be resolved with the help of the linker.
If SDCC would output "P2_ALIKE_PDATA_PAGING_SFR" instead
of "P2", then the linker could first try to link to
location "P2_ALIKE_PDATA_PAGING_SFR" (which would be
EMI0CN
on a cygnal and something else for f.e. a Triscend)
and if this fails fall back to "P2".
The long name is chosen here for clarity and not
as a real proposal - Comments?
> 4) not 'just' another paging register, but a paging
register
> EMI0CN at 0xA2 in an sfr-page (0).
Funny that the paging register itself is a paged register
=:O
Probably it will stay the responsibility of
the programmer to asure that EMI0CN is paged
in when it is needed - if that is true then the
above proposal should be OK.
Please note: If you want to use generic pointers
(on a cygnal) pointing to addresses in pdata
then you won't like the use of "p2" in:
sdcc/device/lib/_gptrget.c
(f.e. memcpy and friends are calling gptrget)
You probably have three options there:
a) cast your pointer to (xdata char*),
b) provide your own gptrget function
c) persuade users/developers to have a slightly
slower but cygnal compatible function;)
Greetings,
Frieder
Logged In: YES
user_id=591031
Hello,
I've seen in the logs that the use of P2 in _gptrget.c is
already disabled. Now I've looked in the source tree and found
only two other places where it is used: in mcs51/main.c in the
initialisation as already observed and I think this really should
be moved to a library function. And the other place is in
SDCCglue.c (line 1801) for setting up the xstack. I think this
should be moved into _sdcc_external_startup() where it can
be changed/overridden by the user.
Btw, two questions: Is it ensured that the xstack area starts
on a 256 byte aligned page? (And how?) And what happens if
one compiles _sdcc_external_startup() with --xstack? I think
this will go wrong and there should be a warning about it in
_startup.c and the documentation.
Greetings,
Maarten
Logged In: YES
user_id=635249
With the changes noted in ChangeLog 1.683, initialization
can now be easily compatible with Cygnal (Silicon Labs)
parts. For most cases, just define the sfr _PAGESFR at the
location of the EMI0CN register. For example, include the
declaration:
sfr at 0xaf _PAGESFR; /* EMI0CN at 0xAF */
in any C file linked in a project.
Most of the run-time startup/initialization is in a library
now and thus can be overridden at the local level if more
complex customizations are needed.
Logged In: YES
user_id=888171
Thanks Erik,
I was recently looking into this issue as well, but wasn't sure
how to implement the asm code into the libraries. Thanks for
this fix.
However, the sfr name you chose is not ideal for silabs
processors. Some of them have so many sfr's that they don't
fit in 128 positions. So they implemented sfr-paging with some
common sfr's in all pages and others at overlapping addresses
in different pages (EMI0CN is one of them). Now guess what,
the name they use to select the sfr-page is SFRPAGE. May I
suggest another name for _PAGESFR: _XPAGE.
Furthermore, if I were to create an example crtxinit.asm and
crtxstack.asm for one of those sfr-paging mcu's (F12x), could
it be added to the examples? After I hear from you, I will also
update the silabs header files.
Greets,
Maarten
Logged In: YES
user_id=635249
Ok, _PAGESFR is now _XPAGE. I had browsed a number of
Silicon Lab's databooks looking for one that described the
case in which EMI0CN itself was paged, but couldn't find it
(they have so many databooks to cover their myriad of
implementations!)
An example of customizing crt*.asm would be great.
Logged In: YES
user_id=888171
Hi Erik,
Looking into your code some more, I see you initialize
__start__xstack in src/mcs51/main.c (181) to the start of
xram. If however this is not on a page boundary, the
allocation for it overflows the page. See src/SDCCglue.c
(1760). Maybe it's wise to change this allocation to use only
the rest of this page (256 - (options.xdata_loc % 256)).
And why doesn't crtxinit.asm have some .globl entries? And
while you're at it, untabify the file please.
SDCC is getting better every day. Thanks.
Maarten