9S08QG8 Long Variable

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

9S08QG8 Long Variable

3,756 Views
datamstr
Contributor II
Hi all,
 
I have essentially a 48 bit shift register in RAM, as 6 bytes end to end. Is there a way to shift left 1 bit at a time across the "48 Bit Variable" using C?
 
I can figure out how to do it in assembly with the accumulator, just wondering if C will do this with maybe a typedef.
 
Thanks,
David
Labels (1)
0 Kudos
Reply
17 Replies

1,280 Views
peg
Senior Contributor IV
Hi datamstr,
 
Multiply it by two?
 
Not sure where the accumulator comes in when using assembler, its normally:
 
ASL LSByte
ROL LSByte-1
ROL LSByte-2
ROL LSByte-3
ROL LSByte-4
ROL LSByte-5
 
You could just inline this also!


Message Edited by peg on 2007-09-11 11:13 AM
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Hi Peg,
 
Well, I need to keep shifting through all 6 bytes one bit at a time.
So, the MSB needs to move to the LSB of the next memory location in line and so on..
 
Thanks,
David
0 Kudos
Reply

1,280 Views
peg
Senior Contributor IV
Hi,
 
Yes, that is what I thought you wanted and it is what the assembly code does, utilising the carry bit.
Unfortunately C does not allow direct access to the carry bit and << will lose the MSB after a shift out of the current size.
 
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Hi Peg,
 
OK, that is neat! I see that in the manual for ROL and also worked through the sequence, thanks!
 
One other related question:
 
How do I reference the C Array using the in-line asm?
 
unsigned char MyData[6];

Thanks,
David
 
0 Kudos
Reply

1,280 Views
peg
Senior Contributor IV
Hi,
I don't use C in uC's so I am not sure, but I do know this subject has been discussed often here.
A search of this or the 8-bit CW forum should yield the answer.
 
0 Kudos
Reply

1,280 Views
bigmac
Specialist III
Hello David,
 
For inline assembly, each array element can be addressed with the following construct -
 
__asm {
  lsl  MyData:5;
  rol  MyData:4;
  rol  MyData:3;
  rol  MyData:2;
  rol  MyData:1;
  rol  MyData;
}
 
However, to use the LSL and ROL assembly instructions, the variable MyData must reside in page zero, or on the stack.  For a stack based local variable, there was no problem compiling, and the expected result was obtained.  But with MyData as a global variable, I did have problems compiling the above code, even with the attempt to explicitly define the variable to be allocated to page zero.
 
#pragma DATA_SEG MY_ZEROPAGE
char MyData[6];
#pragma DATA_SEG DEFAULT
 
In fact, the global variable did reside within page zero, but the compile continued to fail at the LSL and ROL inline instructions.  Perhaps others may be able to throw light on this issue.
 
Regards,
Mac
0 Kudos
Reply

1,280 Views
CompilerGuru
NXP Employee
NXP Employee
well, not time to try it out, but something like

Code:
unsigned char MyData[6];void fun() {__asm {    ldhx @MyData;  lsl  5,X;  rol  4,X;  rol  3,X;  rol  2,X;  rol  1,X;  rol  ,X;}}

 



should work for globals regardless of the memory model.

Daniel



0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Daniel,

Thanks for your help! I tried the code example you posted and am getting a linker error.
There are no other details listed.

Thanks,
David
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Daniel,

Sorry, I found an error in my code that generated the linker error.
Your code example compiles and Links just fine.

Thanks,
David
0 Kudos
Reply

1,280 Views
peg
Senior Contributor IV
Hi David,
 
Which method worked? Or did both?
Forcing the variable into zero page RAM and direct mode or using the indexed mode of access.
Both should work!
 
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Hi Peg,

I declared the MyData Variable both as Global and also using the #pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE method and they both worked. I have not yet tried the two dimensional arrary, but that should be just a change in the indexing.

Thanks,
David
0 Kudos
Reply

1,280 Views
bigmac
Specialist III
Hello Peg,
 
Yes, both methods did work for me for a global array.  The zero page method is marginally faster than the indexed method, but by very little.  The use of a local array is slowest since stack pointer indexing seems to be used.
 
Regards,
Mac
 
0 Kudos
Reply

1,280 Views
CompilerGuru
NXP Employee
NXP Employee
Did not try it out, but note that "MY_ZEROPAGE" is not telling the compiler anything else but the name of the section, it does not tell that its a zero page section. MY_ZEROPAGE is not a builtin/special name.
So I would try:
#pragma DATA_SEG __SHORT_SEG MY_ZEROPAGE
char MyData[6];
#pragma DATA_SEG DEFAULT


Daniel
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Hi Mac,
 
The following works if I put the asm code in a function even with the small model.
 
void foo(unsigned char MyData)
  {
   __asm
     {
     rol  MyData;
     }
  }
Now if I can figure out how to pass the array to the function.
 
Thanks,
David
 
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Hi Mac,
 
Also, I wonder if the syntax works for a 2 dimensional array.
 
char MyData[6][6];
 
__asm {
  lsl  MyData:0:5;
  rol  MyData:0:4;
  rol  MyData:0:3;
  rol  MyData:0:2;
  rol  MyData:0:1;
  rol  MyData;
}
 
Thanks,
David
0 Kudos
Reply

1,280 Views
CompilerGuru
NXP Employee
NXP Employee
The : syntax in HLI expects the byte offset, and not an array index.
Therefore its the same for one or two dimensinal arrays just as for non array types.
E.g.
...
rol  MyData:smileysad:0*6)+3;
...
Daniel
0 Kudos
Reply

1,280 Views
datamstr
Contributor II
Hi Mac,
 
I am using the small memory model, and I am getting the error "Unknown Opcode ..............".
 
I will do some experimenting.

Thanks,
David
 
 
0 Kudos
Reply