Hello,
I use a ST10F269 (SMALL-modell) with Keil C166 v6. I try to call a RAM-routine (in XRAM2) from ROM (in Segment 2 => all code is located within 64kB in Segment 2) via assembler routine:
BCLR IEN CALLS #0,#SOF fls_ram BSET IEN
fls_ram is a variable at address 0xDBBE
What I expect is, that the call is to address 0xDBBE but it is to address 0x9BBE (14bit address).
When I use: MOV R4, #SOF fls_ram it works fine, I have the 16bit-address in register R4 but not with CALLS, JMPS, ..
Are there restrictions for the use of #SOF? How can I jump to the RAM-area (in a different segment)?
Thanks for the help!
Best Regards, Josef Aspelmayr
Maybe this is not what you are asking but did you try this.
CALLS #SEG fls_ram, #SOF fls_ram
Regards, Chris
Yes,
I tried:
The result is the same, segment is 0x0 and address is 0x9BBE and not 0xDBBE..
What is really strange for me is the fact, that when I use..
MOV R4, #SOF fls_ram
..I have the correct value in R4 but not when I use CALLS/JMPS.
Thanks and best regards Josef Aspelmayr
I think you mean routine or symbol?
Did you double check the map/.m66 file? And the linker file?
According to http://www.keil.com/support/docs/688.htm : This function combines the segment (DPP register) and offset to get a real 16-bit address.
Could it be that the fls_ram routine is in DPP space and the DPP contains 0? Naah, that doesn't make sense either...
It -is- weird...
Good luck! Joost Leeuwesteijn
fls_ram is a variable (array) in XRAM. I copy the code to XRAM, then I want to start the code. Thats the reason why I call/jump to a RAM-address.
And the address (0xDBBE) is from map-file..
I am not sure how you have everything defined in your project. But if I try a sample program everything is working as I would expect.
unsigned int fls_ram[50]; extern void MyFunc (void); void main(void) { fls_ram[0] = 0x00DB; /* RETS instruction */ MyFunc(); for(;;); }
I defined a RAM section from 0x40000--0x4FFFF 040140H fls_ram VAR --- NDATA0 ?ND0?MAIN
Here is the assembly file:
$NOMACRO $SEGMENTED CASE $MODINF (43) NAME MYASM NCODE CGROUP ?PR?MYASM ASSUME DPP3 : SYSTEM REGDEF R0 - R15 EXTERN fls_ram:WORD ?PR?MYASM SECTION CODE WORD 'NCODE' MyFunc PROC NEAR PUBLIC MyFunc CALLS #SEG fls_ram, #SOF fls_ram RET MyFunc ENDP ?PR?MYASM ENDS END
If you run this code it jumps to the RAM location (0x40140) and then does a RETS, just as expected.
5: void main(void) { 6: 7: fls_ram[0] = 0x00DB; /* RETS instruction */ 00020000 E6F4DB00 MOV R4,#0x00DB 00020004 F6F44081 MOV DPP2:0x0140,R4 8: MyFunc(); 9: 00020008 CA000E00 CALLA CC_UC,MyFunc(0x2000E) 10: for(;;); 0002000C 0DFF JMPR CC_UC,0x02000C 18: CALLS #SEG fls_ram, #SOF fls_ram 0002000E DA044001 CALLS 0x040140 19: RET
Sorry not sure how to help you. Perhaps you can reduce your problem to a small working code snippet then others could look to find the problem?
Best regards, Chris
Hello Chris,
thanks for the help!
I have tried your code-snippet, but with variable located in XRAM-area:
00C200H fls_ram VAR --- NDATA0 ?ND0?TEST
And it works!
But I have tried to do the same with #pragma ASM and I get the same failure:
unsigned int fls_ram[50]; void MyFunc(void); void main(void) { fls_ram[0] = 0x00DB; /* RETS instruction */ MyFunc(); for(;;); } void MyFunc(void) { #pragma ASM CALLS #0, #SOF fls_ram #pragma ENDASM }
In that case I have a:
CALLS 0x8200
.. so this is wrong!
Best Regards, Josef
I left off the reference to the DPP in the extern reference in the separate assembly file.
It appears the environment always assumes a data access (which it should) and this is why the DPP is causing you an issue (you don't want this).
If you want to jump to a variable then I would create a function pointer assigned to the data variable address and then call it (keeping everything in C). Here is an example.
unsigned int fls_ram[50]; void (far *MyFunc)(void) = (void far *)(&fls_ram[0]); void main (void) { fls_ram[0] = 0x00DB; /* RETS instruction */ (*MyFunc)(); /* call MyFunc in XRAM */ for(;;); }
Despite the DPP-addressing, the SOF-Operator shall use the 16bit-address (and this should be done with any opcode-variant).
I was in contact with Keil and according to Support-Team this is a compiler-issue and will be solved.
Thanks for all the help!
Seems like you've found a bug! Nice work (reporting it)!
I was thinking it might help to explicitly declare the fls_ram variable as huge/xhuge in the C file? To make sure it doesn't use near/DPP. But this would generate the same #SOF instruction I guess, not sure.
Regards, Joost Leeuwesteijn