Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid Intel HEX output #35

Open
zxmak opened this issue Nov 29, 2024 · 3 comments
Open

Invalid Intel HEX output #35

zxmak opened this issue Nov 29, 2024 · 3 comments

Comments

@zxmak
Copy link

zxmak commented Nov 29, 2024

The assembler produces invalid Intel HEX output containing many unwanted zeros, which can overwrite important data on the target device without any request.

For example here is test-ihex.asm file:

    org    $4000
    defb    $ca
    
    org    $4010
    defb    $fe
    
    org    $4020
    defb    $ba
        
    org    $f000
    defb    $ba

You can compile it with old-school z80 assembler zmac with command zmac -h -o build/test-ihex.hex -x build/test-ihex.lst test-ihex.asm and get the following result:

:01400000CAF5
:01401000FEB1
:01402000BAE5
:01F00000BA55
:0000000000

This is expected Intel HEX result and works ok.

You can also try more modern modifications of zmac, like this one.

Now, try to compile the same test-ihex.asm file with zasm and you will get this:

test-ihex.hex output from zasm

:20000000CA000000000000000000000000000000FE00000000000000000000000000000018
:20002000BA0000000000000000000000000000000000000000000000000000000000000006
:200040000000000000000000000000000000000000000000000000000000000000000000A0
:20006000000000000000000000000000000000000000000000000000000000000000000080
:20008000000000000000000000000000000000000000000000000000000000000000000060
:2000A000000000000000000000000000000000000000000000000000000000000000000040
:2000C000000000000000000000000000000000000000000000000000000000000000000020
:2000E000000000000000000000000000000000000000000000000000000000000000000000
:200100000000000000000000000000000000000000000000000000000000000000000000DF
:200120000000000000000000000000000000000000000000000000000000000000000000BF
:2001400000000000000000000000000000000000000000000000000000000000000000009F
:2001600000000000000000000000000000000000000000000000000000000000000000007F
:2001800000000000000000000000000000000000000000000000000000000000000000005F
:2001A00000000000000000000000000000000000000000000000000000000000000000003F
:2001C00000000000000000000000000000000000000000000000000000000000000000001F
:2001E0000000000000000000000000000000000000000000000000000000000000000000FF
:200200000000000000000000000000000000000000000000000000000000000000000000DE
:200220000000000000000000000000000000000000000000000000000000000000000000BE
:2002400000000000000000000000000000000000000000000000000000000000000000009E

<skip a lot of lines with zeros>

:20AF80000000000000000000000000000000000000000000000000000000000000000000B1
:20AFA000000000000000000000000000000000000000000000000000000000000000000091
:20AFC000000000000000000000000000000000000000000000000000000000000000000071
:20AFE000000000000000000000000000000000000000000000000000000000000000000051
:01B00000BA95
:00000001FF

This is incorrect Intel HEX output and contains incorrect addresses and a lot of unwanted zeros.

It appears that ZASM simply ignores the Intel HEX format's ability to specify addresses and uses it as a continuous binary file, filling all gaps with zeros. However, these gaps may contain important data or code on the target platform, and these zeros will overwrite them without justification.

Please fix it.

@Megatokio
Copy link
Owner

Hello, thanks for your report.
i don't think it is 'wrong' because i don't know that the Intel hex file specification requires this, but you may prove me wrong and possibly this is what most assemblers do and i certainly want to stick with the majority and don't behave unexpectedly.
Actually this is already on the 'could be changed' list, but i'm working on zasm only on demand now.
Until then there is a way how to do it with zasm:
use the #code directive instead of org. This will create segments and the space between segments is not included in the Intel hex file. e.g.:

#target ram
#code    $4000
    defb    $ca
    
#code    $4010
    defb    $fe
    
#code    $4020
    defb    $ba
        
#code    $f000
    defb    $ba

please try whether this works for you.
until then i'll tick up the importance of this issue and work on it next time i work on zasm. but there is some internal change required, so i won't do it right away if the above solution is ok for you.

kio !

@zxmak
Copy link
Author

zxmak commented Dec 5, 2024

Thank you for suggesting the use of the #code directive instead of org.
This one works:

#target ram

    ; org $4000
#code  AAA,  $4000, *
    defb    $ca

    ; org $4010    
#code  BBB,  $4010, *
    defb    $fe

    ; org $4020    
#code  CCC,  $4020, *
    defb    $ba

    ; org $f000        
#code  DDD,  $f000, *
    defb    $ba

But while this approach does produce the desired result, using such a specific directive in existing code causes compatibility issues with other assemblers that already support the standard org directive syntax and generate correct Intel HEX output without requiring additional directives. Unfortunately, code often contains a significant number of org directives, and maintaining their specific syntax for a single assembler would be problematic.

The standard org directive is a widely accepted way to specify code address (especially for z80 code), commonly used in assemblers and familiar to most developers. It simplifies code migration between different assemblers and ensures the readability of the source code. It would be preferable to have support for proper Intel HEX output using the standard org directive.

It would be great to get a working Intel HEX output using the standard org directive. Is that possible?

Thanks

@Megatokio
Copy link
Owner

I understand your point and support it. As said, i will work on it next time i work on zasm. But it is not an easy fix at the point where the hex file is created because at that point i already lack the required information. I need to change the way zasm keeps track of the locations with generated code.
Until then please use the #code directive. You can leave the org directive in (after #code) and only surround #code with #if and #endif which makes it slightly less cumbersome and of course you only need to use #code segments where you actually need to preserve the gap.
The update will probably not be in December but hopefully in January. if we all live by then.
Kio !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants