Menu

#26 no 64k wrap around for segmented addresses

v1.0.12
open
nobody
None
5
2021-09-30
2021-09-07
Anonymous
No

Hi!
While testing hex2bin I checked the handling of segment addresses and found it to be not according to the standard.
For example, look at this intel hex file:
:020000020000FC
:02FFFF001122CD
:020000020001FB
:02FFFF00334489
:00000001FF

The tool hex2bin generates the following output:

hex2bin v2.5, Copyright (C) 2017 Jacques Pelletier & contributors

Allocate_Memory_and_Rewind:
Lowest address: 0000FFFF
Highest address: 00010010
Starting address: 0000FFFF
Max Length: 18

Binary file start = 0000FFFF
Records start = 0000FFFF
Highest address = 00010010
Pad Byte = FF

As one can see it concatenates the bytes as they are defined in the file.
The problem is: when using hex record type 02 (Extended Segment Address Record ) and the data record starts just before a 64K boundary, and would finish after that 64K boundary, the later part of the record wraps around to address 0 within the same segment (NOT the next segment).

This is what srec_info outputs:

Format: Intel Hexadecimal (MCS-86)
srec_info: probleme\test-wrap64k-FFFF.hex: 2: warning: data records not in
strictly ascending order (expected >= 0x10000, got 0x0000)
Data: 000000 - 000000
000010 - 000010
00FFFF - 00FFFF
01000F - 01000F

As one can see, the wrap around of segment 0 creates one byte at 0x000000. And the wrap around of segment 1 creates one byte at 0x000010.

Discussion

  • Jacques Pelletier

    Thanks for your post.

    It's indeed not doing it correctly and srecord does it right according to the Intel Hex spec.
    I suppose most generators would produce correct Intel Hex without resorting to the wrap around trick.
    After a quick check, a fix for this may be a bit long to do.
    If this is a show stopper for programming a specific binary, let me know.

     
  • Jacques Pelletier

    To get a warning, after this line in hex2bin.c,

                    /* Set the lowest address as base pointer. */
                    if (Phys_Addr < Lowest_Address)
                        Lowest_Address = Phys_Addr;
    

    put this:

                    if (Phys_Addr + Nb_Bytes -1 > 65535)
                        if (Verbose_Flag) fprintf(stderr,"Warning: data record wrap around 64k\n");