Using __SEG_START_  in .asm to address memory allocated in a PRM file

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

Using __SEG_START_  in .asm to address memory allocated in a PRM file

3,611 Views
CarlFST60L_3rd
Contributor I
Hi,

This is probably somthing simple, but have been having troubles finding where in the help files this is explained. (Also, I have this setup working fine in C, but for some reason cannot get it working in asm). (Note, this is just an example to show my problem, not what im actually doing)

These two lines were added to the PRM in the correct areas:
added "PhoneNumbers"
;*------------------------------------------------------------------------------------------
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
    PAGEflash_PhoneNumbers =  READ_ONLY    0x8000 TO 0x81FF;
END

PLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */
    PhoneNumbers                            INTO  PAGEflash_PhoneNumbers;
END
;*------------------------------------------------------------------------------------------


This is in another file added the data for PhoneNumbers:
;*------------------------------------------------------------------------------------------
PhoneNumbers: SECTION

;Factory default phone numbers
           
def_phone1      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
def_phone2      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
def_phone3      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
def_phone4      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
def_phone5      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
def_pin         dc '000000',0,0,0,0,0,0,0,0,0,0
def_start_msg   dc 'Watchguard Alarms  ',0
;*------------------------------------------------------------------------------------------

In main.asm added
;*------------------------------------------------------------------------------------------
ldhx   PhoneNumbers
;do somthing
ldhx  (PhoneNumbers+$10)
;do somthing else
;*------------------------------------------------------------------------------------------
Both of these lines cause " A1414: Cannot set fixup to constant "
I have tried many things, XDEF, __seg_start etc, things that wo...






Labels (1)
Tags (1)
0 Kudos
11 Replies

878 Views
CrasyCat
Specialist III
Hello
 
Be careful, the macro assembler is case sensitive so you have to write __SEG_START_PhoneNumbers to refer to the start address of the section PhoneNumbers.
 
I did a small test and the following code seems to work well.
Code:
     XREF __SEG_START_PhoneNumbers     XDEF test, def_phone1     PhoneNumbers: SECTION;Factory default phone numbers           def_phone1      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0def_phone2      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0def_phone3      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0def_phone4      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0def_phone5      dc 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0def_pin         dc '000000',0,0,0,0,0,0,0,0,0,0def_start_msg   dc 'Watchguard Alarms  ',0MyCode: SECTIONtest:  ldhx   __SEG_START_PhoneNumbers

 
make sure to either use one of the labels in section PhoneNumbers or to disable smart linking for one of them otherwise the linker will not link the section to the application (as it is not used).
 
To force linking of section PhoneNumbers just add an
    XDEF def_phone1
in your assembly source file, and the following in the .prm file:
  ENTRIES
    def_phone1
  END
I hope this helps.
CrasyCat
0 Kudos

878 Views
CompilerGuru
NXP Employee
NXP Employee
The problem with the initial posting is that section names cannot be used as labels in the assembler.
If you just need address of the section part the current assembly modules defines, use a label defined in the start of the section (e.g. SectionLabel below).
Code:
SectionName: SECTIONSectionLabel:

 
Using the __SEG_START_ syntax from assembly works too, it's advantage is that it provides the address of the first byte of the section regardless of where the section content was defined.
For content defined in the same file, I would not use it to keep the code simple.

Daniel

0 Kudos

878 Views
CarlFST60L_3rd
Contributor I
Thanks for your replies, this has solved problem 1, created problem 2

We are actually porting a project of 25K+ lines of ASM from

Pemicro to Codewarrior, which we wrote about 5 years ago.

 

The new problem is that we cannot get CW to do complex relocatable expressions

> A2401: Complex relocatable expression not supported

 

Is there a way to make the following work?

 

ldhx RAMBuffer + __SEG_START_PhoneNumbers

(RAMBuffer is a large mutipurpose buffer in general ram)

 

I realise that this could be re-written, but there are literally 25,0000 lines of code with a majority using complex relocatable expressions to many different areas of flash with many different names and labels (mostly more complex than the above example)...

0 Kudos

878 Views
CarlFST60L_3rd
Contributor I
This is a better example of what we currently do

RAMByte1 = Standard byte of RAM
RAMbuffer = Large RAM buffer for storing all sorts of temp data
FlashCopyRAMByte1 = The flash equivilant of RAMByte1
FlashVariblesPage1 = The Page of Flash we are using for storing this particular state

code:
lda    RAMByte1         ;Get some data value to be stored to updating flash
sta    (RAMbuffer+(FlashCopyRAMByte1-(FlashVariblesPage1+$100)))   ;

This is current code that i would like to still compile with Codewarrior as we did with Pemicro

0 Kudos

878 Views
bigmac
Specialist III
Hello,
 
This would seem to be specifically a problem with a relocatable assembly project.  I assume the original P&E code used absolute assembly, where the value of all labels were defined prior to their being referenced.
 
A similar problem occurred in an earlier thread -
 
Regards,
Mac
 


Message Edited by bigmac on 2007-09-26 05:29 PM
0 Kudos

878 Views
CarlFST60L_3rd
Contributor I
Ok, i see the problem, however, I cannot see how to re write this code to work:

memory
RAMByte1 = Standard byte of RAM
RAMbuffer = Large RAM buffer for storing all sorts of temp data
FlashCopyRAMByte1 = The flash equivilant of RAMByte1
FlashVariblesPage1 = The Page of Flash we are using for storing this particular state

code:
lda    RAMByte1         ;Get some data value to be stored to updating flash
sta    (RAMbuffer+(FlashCopyRAMByte1-(FlashVariblesPage1+$100)))   ;


0 Kudos

878 Views
bigmac
Specialist III
Hello,
 
I don't really understand what your sample code is trying to achieve.  However, the destination address is calculated using three labels.  How many of these are declared as an external reference (using XREF directive)?
 
If you continue with relocatable assembly, probably two of the labels would need to have been explicitly defined as constants (using the EQU directive) prior to the assembly of the sample lines.
 
Another approach might possibly be the use of indexed addressing.
 
Of course, it may well be simpler to stay with absolute assembly for the old project.
 
Regards,
Mac
 
0 Kudos

878 Views
CarlFST60L_3rd
Contributor I
Thanks again for your reply

The code is accessing varibles in tables of flash which are stored in a RAM buffer. Essentially, there are all these diffrent tables that need to have bytes updated as they are changed from user inputs (actually from a modem)

Example below with details

The code is only used to update flash data in a ram buffer then another routine updates the flash
Address            memory
$0100 - RAMByte1 = Standard byte of RAM
$0200 - RAMbuffer = Large RAM buffer for storing all sorts of temp data
$8110 - XDEF FlashCopyRAMByte1 = The flash equivilant of RAMByte1
$8000 - XREF __SEG_START_FlashVariblesPage1 = The Page of Flash we are using for storing this particular state

code:
lda    RAMByte1         ;Get some data value to be stored to updating flash
sta    (RAMbuffer+(FlashCopyRAMByte1-(__SEG_START_FlashVariblesPage1+$100)))   ;
So this will load a single ram byte and update it in a the RAMBuffer i.e.
sta   ($0200+($8110-($8000+$0100)))
($8000+$0100) = $8100 simply adds an offset as we are using what is refered to as the second page
($8110-$8100) = $0010 The offset of this varible in the second page of the table
($0200+$0010) = The byte in the RAMBuffer to be updated is 10 bytes from the start of the buffer.

Can this be done using indexing?










Message Edited by CarlFST60L_3rd on 2007-09-27 03:35 AM
0 Kudos

878 Views
bigmac
Specialist III
Hello,
 
If my understanding is correct, you wish to copy data into RAMbuffer, which starts at address $200, and the contents of RAMbuffer will eventually be written to flash, commencing at address $8000.  It is also my understanding that the destination of the variable data will have identical offset for both RAM and flash, namely $110 from the start of each memory block.
 
If this be the case, you could simply define the offset required for the buffer storage of each variable, and presumably this would be defined as a constant using the EQU directive.  The location of the flash block need not even be considered here, as the programming process is handled elsewhere.
 
    xref RAMbuffer  ; Location of buffer defined elswhere
Var1Off: equ $110   ; Constant offset for storage of this variable
Var2Off: equ $111
etc.
 
    lda  Var1
    sta  RAMbuffer+Var1Off
 
or using indexed addressing -
 
    lda  Var1
    ldhx Var1Off
    sta  RAMbuffer,x
 
 
Regards,
Mac
 


Message Edited by bigmac on 2007-09-28 06:08 AM
0 Kudos

878 Views
CarlFST60L_3rd
Contributor I
Thanks for your reply.

I would use equates, but the table is actually 1024 bytes, and there are two of them, so that means way to many equates to work out (espically when there are so many diffrent types of data, strings, tables etc). Back to absolute i go.
0 Kudos

878 Views
bigmac
Specialist III
Hello,
 
But don't you already use equates to map the variables into flash, as represented by the constant FlashCopyRAMByte1?  The basis of my suggestion was that you replace each absolute address value with an offset value (that can be applied to both RAM and flash memory blocks), so the quantity of equates would be no greater than you currently have.  To calculate the offset value, I suspect only requires to subtract $8000 from the current mapping addresses.
 
If you have a large number of "random" buffer locations to be defined, another method would be to use a table of offsets, where each entry of the new look-up table would correspond to the required offset word vallue.  The following example is for a HCS08 device, with the quantity of defined offsets not exceeding 127.
 
OFF_TAB:
    DC.W  $233,$110,$000,$100 ; Offset values for Var0 -> Var3
   
 
    LDA   Var3
    LDHX  #3         ; Table index value for Var3
    LSLX             ; Offset is word value
    LDHX  OFF_TAB,X  ; Fetch offset value
    STA   RAMBuffer,X
 
Regards,
Mac
 
0 Kudos