This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

generic pointers and bad code problem

I have searched the entire knowlege base and have not found an answer to a specfic question.

how do you CAST a generic pointer to a memory specific pointer.

There are examples in the manual for casting a memory specific pointer to a generic, but not the other way around.

Specifically, I have an array of generic pointers to structures. the array is located in xram.
I have found a bug in the compiler where in it gets confused as to what kind of pointer it is dealing with
(more later). If I could type cast the pointer to generic it would most likely fix the problem.

The problem I'm currently up against, is the following where the compiler only generates the 0xFF identifier for a generic pointer when assigning a generic pointer read out of an array, to a generic pointer. to wit:

Below, is an abbreviated source. I'm not sure if this will exhibit the problem if compiled or not, but my code that uses the same lines of code below fails.
Specfically in this example, at address 37F The compiler fails to copy a generic pointer into another generic pointer. All it does is load the memory type specifier into the pointer. This is a 7.5 compiler.

The target part is a silabs 040

very strange problem with indexing and pointers.
Given the following structures, the code below breaks.

Sample values as examined in the silabs debugger show

in xdata, there is an array of pointers that is copied from flash.
After the copy the table looks something like this
32B 32C 32D 32E 32F 330
0xFF 0x02 0x01 0xFF 0x0A 0xB8 the result of the code is that

current_treatment winds up with the following in it. 0xFF 00 00 00

the table is at 0x032B
current_mode = 1;

Here is the listing code. As you can see, this does not copy the pointer, just the type.
Something is clearly wrong here. In other versions of this, that I was debugging prior to compiling this one,
I was seeing it index by 2, and pick up the values that way, which resulted in the current_treatment holding
0x01FF0A2B which is also wrong.

0361 7800 R MOV R0,#LOW current_mode
0363 E2 MOVX A,@R0
0364 FF MOV R7,A // here R7 = 1
0365 33 RLC A // double it
0366 95E0 SUBB A,ACC // results in 0 !
0368 FE MOV R6,A // R6=0
0369 EF MOV A,R7 // ACC now = 1
036A 25E0 ADD A,ACC // ACC now = 2 (should be 3)
036C FF MOV R7,A // R6R7 now are 0002
036D EE MOV A,R6 // since the value is 1, there will be nothing rotated into R6
036E 33 RLC A
036F FE MOV R6,A // R6R7 now are 0002
0370 7400 R MOV A,#LOW treatments // puts 2B into a
0372 2F ADD A,R7 // adds 2 to it resulting in 2D
0373 F582 MOV DPL,A // dp = 002D
0375 7400 R MOV A,#HIGH treatments // this puts 03 into A
0377 3E ADDC A,R6 // adds 0 to it resulting in 03
0378 F583 MOV DPH,A // dptr now is 032D
037A A3 INC DPTR // increments to 032E which is CORRECT
037B E0 MOVX A,@DPTR // picks up the 0xFF
037C 900000 R MOV DPTR,#current_treatment
037F F0 MOVX @DPTR,A // saves 0xFF. and never picks up anyting else ; SOURCE LINE # 2367
0380 ?C0034: ; SOURCE LINE # 2375
0380 120000 R LCALL LCDClearScreen ; SOURCE LINE # 2376
0383 120000 R LCALL L?0870

struct treatment_table idata * current_treatment;
struct treatment_table xdata * scroll_treatment;

code struct treatment_table user_control= { 1, /* only one step */ 0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xff,0xff,0xff,/* infinite time */ };
code struct treatment_table single_pulse_zero_d= { 1, /* only one step */ 0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xff,0xff,0xff,/* infinite time */ };

struct treatment_table xdata * treatments[]= { &user_control, // This is a holder for the user mode. 8-12-08 &single_pulse_zero_d };
//
// No memory specifier, means that this will be a generic pointer table, so it can point to xram OR code.
// the compiler takes care of this, though it generates much slower code 8-21-08
//
code struct treatment_table * treatment_tbl[]= { &user_control, // This is a holder for the user mode. 8-12-08 &single_pulse_zero_d };

unsigned char current_mode;
main()
{ current_mode=1;
//
// copies the treatment table from flash into xram. I can't make the keil compiler do this automatically for me.
// when xdata is examined, there is a table of GENERIC pointers there. Each pointer is 3 bytes long, and starts
// with an 0xFF which is correct, it says that it is a generic pointer to code memory.
// memcpy(treatments,treatment_tbl,sizeof(treatments)); // this works just fine
//
// This however fails. It indexes treatments by 2 bytes, rather than 3 bytes, so it gets bogus pointers into current
// treatment
// current_treatment is GENERIC pointer. So indexing into an array of generic pointers and assigning one to
// current_treatment SHOULD index by 3's and put the entire pointer there.

current_treatment=treatments[current_mode];

}

0