sdcc code location - how to get file without padding when using start address greater than zero

176 Views Asked by At

using the SDCC compiler, I am looking to create a z80 file to load into a particular address in ram 0x8000) at a later stage. I have used for example the compiler line:

sdcc -mz80 --no-std-crt0 --code-loc 0x8000 --data-loc 0xE000 test1.c

However the output file is padded with zeros between location 0x0000 and 0x7FFF, followed by the code at the specified location. The reason I want to choose 0x8000 is because of the absolute addressing generated within the compiled z80 file by sdcc. If I instead set the code location to 0x0000 then load into 0x8000 at a later stage then the program will fail.

My option is to just edit the final image and remove the padded zeros, but I wondered if there is another option.

On a separate note, I wondered how older machines handled programs which were loaded in at variable memory addresses without affecting the absolute memory jumps / calls within the program. I'm assuming this wasn't an option for say the C64 or spectrum and the load address is predetermined at point of compilation and non changeable.

Interested in your thoughts.. Regards

1

There are 1 best solutions below

0
the busybee On

The problem is not with SDCC, but with the hex-to-binary converter you use. In a comment you revealed that you use HXD, most probably from this source.

The hex file generated by SDCC is correct, as it contains just the bytes for address 0x8000 and following.

The GUI-only tool HXD in contrast saves a binary file starting at address 0. Its documentation says something about its capability to split files, but this seems not the way to go.

Instead, use capable converter.

The SDCC distribution includes the simple tool makebin, but it also seems to miss the option to skip the range from 0x0000 to 0x7FFF.

Here on StackOverflow recommendations are off-topic, so please use your web search skills to find a better tool. Optimally it is controlled by command line parameters for easy integration into your build process by makefile or shell script. If you do, you will find for example srecord, which despite its name knows how to handle Intelhex and binary files, too.


On your second question in "a separate note", which should actually be a separate question, optimally at StackExchange/Retrocomputing.

Older machines cannot load programs with absolute addresses in them at arbitrary offsets and run them without changes. As you noticed, they will not work because the absolute addresses are correct only at the specific offset.

Older machines very rarely vary their load offset, near to never. So this is not a real or common issue.

Some machines have commands to load binary files with potentially executable code at arbitrary addresses, but the user needs to provide the correct address.

CP/M programs are loaded always at offset 0x0100, for example. If such a program wants to run at another offset, it starts by copying itself to the target range and patching all absolute addresses in its machine code. There is no automagic to do this, each program needs to provide its own patching routine. I did this many years ago for a debugger.

Not so old machines like the Atari ST enrich their executable files with relocation sections. These define in a general way how to patch the loaded binary to the target address. The loader of the operating system patches the loaded code before it jumps to the entry point of the program.

Some processors allow relative addresses for jumps or data access. However, these are commonly limited in their "mileage" to their near neighborhood. Some compilers even support the creation of such position-independent programs.