1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-06 16:29:30 +00:00

First cut of "overwrite" segment docs.

This commit is contained in:
Laubzega 2018-09-08 19:20:01 -07:00
parent d293d766ef
commit 1646acb26f

View File

@ -512,13 +512,15 @@ What we are doing here is telling the linker, that all segments go into the
the linker will first write the <tt/CODE/ segment, then the <tt/RODATA/
segment, then the <tt/DATA/ segment - but it will not write the <tt/BSS/
segment. Why? Here enters the segment type: For each segment specified, you may also
specify a segment attribute. There are four possible segment attributes:
specify a segment attribute. There are five possible segment attributes:
<tscreen><verb>
ro means readonly
rw means read/write
bss means that this is an uninitialized segment
zp a zeropage segment
ro means readonly
rw means read/write
bss means that this is an uninitialized segment
zp a zeropage segment
overwrite a segment that overwrites another one
</verb></tscreen>
So, because we specified that the segment with the name BSS is of type bss,
@ -618,6 +620,54 @@ the command line, with "-1.bin" and "-2.bin" appended respectively. Because
'%' is used as an escape char, the sequence "%%" has to be used if a single
percent sign is required.
<sect1>OVERWRITE segments<p>
There are situations when you may wish to overwrite some part (or parts) of a
segment with another one. Perhaps you are modifying an OS ROM that has its
public subroutines at fixed, well-known addresses, and you want to prevent them
from shifting to other locations in memory if your changed code takes less
space. Or you are updating a block of code available in binary-only form with
fixes that are scattered in various places. Generally, whenever you want to
minimize disturbance to an existing code brought on by your updates, OVERWRITE
segments are worth considering.
Here is an example:
<tscreen><verb>
MEMORY {
RAM: file = "", start = $6000, size = $2000, type=bss;
ROM: file = %O, start = $8000, size = $8000, type=ro;
}
</verb></tscreen>
Nothing unusual so far, just two memory blocks - one RAM, one ROM. Now let's
look at the segment configuration:
<tscreen><verb>
SEGMENTS {
RAM: load = RAM, type = bss;
ORIGINAL: load = ROM, type = ro;
FASTCOPY: load = ROM, start=$9000, type = overwrite;
JMPPATCH1: load = ROM, start=$f7e8, type = overwrite;
DEBUG: load = ROM, start=$8000, type = overwrite;
VERSION: load = ROM, start=$e5b7, type = overwrite;
}
</verb></tscreen>
Segment named ORIGINAL contains the original code, disassembled or provided in
a binary form. Subsequent four segments will be relocated to addresses
specified by their "start" attributes ("offset" can also be used) and then will
overwrite whatever was at these locations in the ORIGINAL segment. In the end,
resulting binary output file will thus contain original data with the exception
of four sequences starting at $9000, $f7e8, $8000 and $e5b7, which will sport
code from their respective segments. How long these sequences will be depends
on the lengths of corresponding segments - they can even overlap, so think what
you're doing.
Finally, note that OVERWRITE segments should be the final segments loaded to a
particular memory area, and that they need at least one of "start" or "offset"
attributes specified.
<sect1>LOAD and RUN addresses (ROMable code)<p>
Let us look now at a more complex example. Say, you've successfully tested