From 8b584cb89fe4fa598c3fb16fb7ee215dffa20dea Mon Sep 17 00:00:00 2001 From: Laubzega Date: Sat, 25 Aug 2018 10:18:23 -0700 Subject: [PATCH 1/8] Add segment type "overlay". --- src/ld65/bin.c | 9 +++++-- src/ld65/config.c | 63 ++++++++++++++++++++++++++++++++++++---------- src/ld65/config.h | 1 + src/ld65/scanner.h | 1 + 4 files changed, 59 insertions(+), 15 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index c3efd9cd1..927719016 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,8 +193,13 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - WriteMult (D->F, M->FillVal, NewAddr-Addr); - PrintNumVal ("SF_OFFSET", NewAddr - Addr); + /* Seek back for "overlay" segments */ + if (NewAddr < Addr) { + fseek(D->F, NewAddr - M->Start, SEEK_SET); + } else { + WriteMult (D->F, M->FillVal, NewAddr-Addr); + PrintNumVal ("SF_OFFSET", NewAddr - Addr); + } } Addr = NewAddr; } diff --git a/src/ld65/config.c b/src/ld65/config.c index 5959067b2..f6603d628 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -653,6 +653,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, + { "OVERLAY", CFGTOK_OVERLAY }, }; unsigned Count; @@ -757,6 +758,7 @@ static void ParseSegments (void) case CFGTOK_RW: /* Default */ break; case CFGTOK_BSS: S->Flags |= SF_BSS; break; case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_OVERLAY: S->Flags |= SF_OVERLAY; break; default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); @@ -1795,6 +1797,7 @@ unsigned CfgProcess (void) for (I = 0; I < CollCount (&MemoryAreas); ++I) { unsigned J; unsigned long Addr; + unsigned Overlays = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1848,6 +1851,29 @@ unsigned CfgProcess (void) /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; + /* Take note of overlayed segments and make sure there are no other + ** segment types following them in current memory region. + */ + if (S->Flags & SF_OVERLAY) { + { + if (S->Flags & (SF_OFFSET | SF_START)) { + ++Overlays; + } else { + CfgError (GetSourcePos (M->LI), + "Segment `%s' of type `overlay' requires either" + " `Start' or `Offset' argument to be specified.", + GetString (S->Name)); + } + } + } else { + if (Overlays > 0) { + CfgError (GetSourcePos (M->LI), + "Segment `%s' is preceded by at least one segment" + " of type `overlay'", + GetString (S->Name)); + } + } + /* Some actions depend on whether this is the load or run memory ** area. */ @@ -1896,22 +1922,33 @@ unsigned CfgProcess (void) /* An offset was given, no address, make an address */ NewAddr += M->Start; } - if (NewAddr < Addr) { - /* Offset already too large */ - ++Overflows; - if (S->Flags & SF_OFFSET) { - CfgWarning (GetSourcePos (S->LI), - "Segment `%s' offset is too small in `%s' by %lu byte%c", - GetString (S->Name), GetString (M->Name), - Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + + if (S->Flags & SF_OVERLAY) { + if (NewAddr < M->Start) { + CfgError (GetSourcePos (S->LI), + "Segment `%s' begins before memory area `%s'.", + GetString (S->Name), GetString (M->Name)); } else { - CfgWarning (GetSourcePos (S->LI), - "Segment `%s' start address is too low in `%s' by %lu byte%c", - GetString (S->Name), GetString (M->Name), - Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + Addr = NewAddr; } } else { - Addr = NewAddr; + if (NewAddr < Addr) { + /* Offset already too large */ + ++Overflows; + if (S->Flags & SF_OFFSET) { + CfgWarning (GetSourcePos (S->LI), + "Segment `%s' offset is too small in `%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + } else { + CfgWarning (GetSourcePos (S->LI), + "Segment `%s' start address is too low in `%s' by %lu byte%c", + GetString (S->Name), GetString (M->Name), + Addr - NewAddr, (Addr - NewAddr == 1) ? ' ' : 's'); + } + } else { + Addr = NewAddr; + } } } diff --git a/src/ld65/config.h b/src/ld65/config.h index 6a36af6cc..a60580da3 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -96,6 +96,7 @@ struct SegDesc { #define SF_RUN_DEF 0x0200 /* RUN symbols already defined */ #define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */ #define SF_FILLVAL 0x0800 /* Segment has separate fill value */ +#define SF_OVERLAY 0x1000 /* Segment can be overlayed on another one */ diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 006ccfceb..e994c0547 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -105,6 +105,7 @@ typedef enum { CFGTOK_RW, CFGTOK_BSS, CFGTOK_ZP, + CFGTOK_OVERLAY, CFGTOK_O65, CFGTOK_BIN, From 1b0e2cf783751a0f3505b1986dcee13bed83db3e Mon Sep 17 00:00:00 2001 From: Laubzega Date: Sat, 25 Aug 2018 20:21:12 -0700 Subject: [PATCH 2/8] Fix for multiple overlay segments. --- src/ld65/bin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 927719016..f4d241add 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,8 +193,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek back for "overlay" segments */ - if (NewAddr < Addr) { + /* Seek in "overlay" segments */ + if (S->Flags & SF_OVERLAY) { fseek(D->F, NewAddr - M->Start, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); From cd9efd53fe1b4588e5473452304960f3072ed529 Mon Sep 17 00:00:00 2001 From: Laubzega Date: Tue, 4 Sep 2018 00:34:28 -0700 Subject: [PATCH 3/8] Segment OVERLAY renamed to REPLACE. Bugfix for read-only segments. Formatting. --- src/ld65/bin.c | 4 ++-- src/ld65/config.c | 24 +++++++++++------------- src/ld65/config.h | 2 +- src/ld65/scanner.h | 2 +- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index f4d241add..c94ac9319 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -194,8 +194,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) } if (DoWrite || (M->Flags & MF_FILL) != 0) { /* Seek in "overlay" segments */ - if (S->Flags & SF_OVERLAY) { - fseek(D->F, NewAddr - M->Start, SEEK_SET); + if (S->Flags & SF_REPLACE) { + fseek (D->F, NewAddr - M->Start, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); PrintNumVal ("SF_OFFSET", NewAddr - Addr); diff --git a/src/ld65/config.c b/src/ld65/config.c index f6603d628..5c61bdd3f 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -653,7 +653,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, - { "OVERLAY", CFGTOK_OVERLAY }, + { "REPLACE", CFGTOK_REPLACE }, }; unsigned Count; @@ -754,12 +754,12 @@ static void ParseSegments (void) FlagAttr (&S->Attr, SA_TYPE, "TYPE"); CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type"); switch (CfgTok) { - case CFGTOK_RO: S->Flags |= SF_RO; break; - case CFGTOK_RW: /* Default */ break; - case CFGTOK_BSS: S->Flags |= SF_BSS; break; - case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; - case CFGTOK_OVERLAY: S->Flags |= SF_OVERLAY; break; - default: Internal ("Unexpected token: %d", CfgTok); + case CFGTOK_RO: S->Flags |= SF_RO; break; + case CFGTOK_RW: /* Default */ break; + case CFGTOK_BSS: S->Flags |= SF_BSS; break; + case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_REPLACE: S->Flags |= (SF_REPLACE | SF_RO); break; + default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); break; @@ -1854,17 +1854,15 @@ unsigned CfgProcess (void) /* Take note of overlayed segments and make sure there are no other ** segment types following them in current memory region. */ - if (S->Flags & SF_OVERLAY) { - { + if (S->Flags & SF_REPLACE) { if (S->Flags & (SF_OFFSET | SF_START)) { ++Overlays; } else { CfgError (GetSourcePos (M->LI), "Segment `%s' of type `overlay' requires either" - " `Start' or `Offset' argument to be specified.", + " `Start' or `Offset' attribute to be specified", GetString (S->Name)); } - } } else { if (Overlays > 0) { CfgError (GetSourcePos (M->LI), @@ -1923,10 +1921,10 @@ unsigned CfgProcess (void) NewAddr += M->Start; } - if (S->Flags & SF_OVERLAY) { + if (S->Flags & SF_REPLACE) { if (NewAddr < M->Start) { CfgError (GetSourcePos (S->LI), - "Segment `%s' begins before memory area `%s'.", + "Segment `%s' begins before memory area `%s'", GetString (S->Name), GetString (M->Name)); } else { Addr = NewAddr; diff --git a/src/ld65/config.h b/src/ld65/config.h index a60580da3..d172560bd 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -96,7 +96,7 @@ struct SegDesc { #define SF_RUN_DEF 0x0200 /* RUN symbols already defined */ #define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */ #define SF_FILLVAL 0x0800 /* Segment has separate fill value */ -#define SF_OVERLAY 0x1000 /* Segment can be overlayed on another one */ +#define SF_REPLACE 0x1000 /* Segment can replace (part of) another one */ diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index e994c0547..2c60da975 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -105,7 +105,7 @@ typedef enum { CFGTOK_RW, CFGTOK_BSS, CFGTOK_ZP, - CFGTOK_OVERLAY, + CFGTOK_REPLACE, CFGTOK_O65, CFGTOK_BIN, From c7bb27bac9ee3a55d08692f250ab3763fc0b1dca Mon Sep 17 00:00:00 2001 From: Laubzega Date: Thu, 6 Sep 2018 00:18:39 -0700 Subject: [PATCH 4/8] Rename more stuff from "overlay" to "replace". --- src/ld65/bin.c | 2 +- src/ld65/config.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index c94ac9319..6f0e4ab36 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,7 +193,7 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek in "overlay" segments */ + /* Seek in "replace" segments */ if (S->Flags & SF_REPLACE) { fseek (D->F, NewAddr - M->Start, SEEK_SET); } else { diff --git a/src/ld65/config.c b/src/ld65/config.c index 5c61bdd3f..0e4d0c1e4 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -1797,7 +1797,7 @@ unsigned CfgProcess (void) for (I = 0; I < CollCount (&MemoryAreas); ++I) { unsigned J; unsigned long Addr; - unsigned Overlays = 0; + unsigned Replaces = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1851,23 +1851,23 @@ unsigned CfgProcess (void) /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; - /* Take note of overlayed segments and make sure there are no other + /* Take note of "replace" segments and make sure there are no other ** segment types following them in current memory region. */ if (S->Flags & SF_REPLACE) { if (S->Flags & (SF_OFFSET | SF_START)) { - ++Overlays; + ++Replaces; } else { CfgError (GetSourcePos (M->LI), - "Segment `%s' of type `overlay' requires either" + "Segment `%s' of type `replace' requires either" " `Start' or `Offset' attribute to be specified", GetString (S->Name)); } } else { - if (Overlays > 0) { + if (Replaces > 0) { CfgError (GetSourcePos (M->LI), "Segment `%s' is preceded by at least one segment" - " of type `overlay'", + " of type `replace'", GetString (S->Name)); } } From d293d766ef39363891d174cd8a6b6647e18bfb5d Mon Sep 17 00:00:00 2001 From: Laubzega Date: Sat, 8 Sep 2018 19:18:41 -0700 Subject: [PATCH 5/8] New segment type renamed to "overwrite". --- src/ld65/bin.c | 4 ++-- src/ld65/config.c | 32 ++++++++++++++++---------------- src/ld65/config.h | 2 +- src/ld65/scanner.h | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/ld65/bin.c b/src/ld65/bin.c index 6f0e4ab36..a77d49679 100644 --- a/src/ld65/bin.c +++ b/src/ld65/bin.c @@ -193,8 +193,8 @@ static void BinWriteMem (BinDesc* D, MemoryArea* M) NewAddr += M->Start; } if (DoWrite || (M->Flags & MF_FILL) != 0) { - /* Seek in "replace" segments */ - if (S->Flags & SF_REPLACE) { + /* Seek in "overwrite" segments */ + if (S->Flags & SF_OVERWRITE) { fseek (D->F, NewAddr - M->Start, SEEK_SET); } else { WriteMult (D->F, M->FillVal, NewAddr-Addr); diff --git a/src/ld65/config.c b/src/ld65/config.c index 0e4d0c1e4..73eee1caa 100644 --- a/src/ld65/config.c +++ b/src/ld65/config.c @@ -653,7 +653,7 @@ static void ParseSegments (void) { "RW", CFGTOK_RW }, { "BSS", CFGTOK_BSS }, { "ZP", CFGTOK_ZP }, - { "REPLACE", CFGTOK_REPLACE }, + { "OVERWRITE", CFGTOK_OVERWRITE }, }; unsigned Count; @@ -754,12 +754,12 @@ static void ParseSegments (void) FlagAttr (&S->Attr, SA_TYPE, "TYPE"); CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type"); switch (CfgTok) { - case CFGTOK_RO: S->Flags |= SF_RO; break; - case CFGTOK_RW: /* Default */ break; - case CFGTOK_BSS: S->Flags |= SF_BSS; break; - case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; - case CFGTOK_REPLACE: S->Flags |= (SF_REPLACE | SF_RO); break; - default: Internal ("Unexpected token: %d", CfgTok); + case CFGTOK_RO: S->Flags |= SF_RO; break; + case CFGTOK_RW: /* Default */ break; + case CFGTOK_BSS: S->Flags |= SF_BSS; break; + case CFGTOK_ZP: S->Flags |= (SF_BSS | SF_ZP); break; + case CFGTOK_OVERWRITE: S->Flags |= (SF_OVERWRITE | SF_RO); break; + default: Internal ("Unexpected token: %d", CfgTok); } CfgNextTok (); break; @@ -1797,7 +1797,7 @@ unsigned CfgProcess (void) for (I = 0; I < CollCount (&MemoryAreas); ++I) { unsigned J; unsigned long Addr; - unsigned Replaces = 0; + unsigned Overwrites = 0; /* Get the next memory area */ MemoryArea* M = CollAtUnchecked (&MemoryAreas, I); @@ -1851,23 +1851,23 @@ unsigned CfgProcess (void) /* Remember the start address before handling this segment */ unsigned long StartAddr = Addr; - /* Take note of "replace" segments and make sure there are no other - ** segment types following them in current memory region. + /* Take note of "overwrite" segments and make sure there are no + ** other segment types following them in current memory region. */ - if (S->Flags & SF_REPLACE) { + if (S->Flags & SF_OVERWRITE) { if (S->Flags & (SF_OFFSET | SF_START)) { - ++Replaces; + ++Overwrites; } else { CfgError (GetSourcePos (M->LI), - "Segment `%s' of type `replace' requires either" + "Segment `%s' of type `overwrite' requires either" " `Start' or `Offset' attribute to be specified", GetString (S->Name)); } } else { - if (Replaces > 0) { + if (Overwrites > 0) { CfgError (GetSourcePos (M->LI), "Segment `%s' is preceded by at least one segment" - " of type `replace'", + " of type `overwrite'", GetString (S->Name)); } } @@ -1921,7 +1921,7 @@ unsigned CfgProcess (void) NewAddr += M->Start; } - if (S->Flags & SF_REPLACE) { + if (S->Flags & SF_OVERWRITE) { if (NewAddr < M->Start) { CfgError (GetSourcePos (S->LI), "Segment `%s' begins before memory area `%s'", diff --git a/src/ld65/config.h b/src/ld65/config.h index d172560bd..d97675b21 100644 --- a/src/ld65/config.h +++ b/src/ld65/config.h @@ -96,7 +96,7 @@ struct SegDesc { #define SF_RUN_DEF 0x0200 /* RUN symbols already defined */ #define SF_LOAD_DEF 0x0400 /* LOAD symbols already defined */ #define SF_FILLVAL 0x0800 /* Segment has separate fill value */ -#define SF_REPLACE 0x1000 /* Segment can replace (part of) another one */ +#define SF_OVERWRITE 0x1000 /* Segment can overwrite (part of) another one */ diff --git a/src/ld65/scanner.h b/src/ld65/scanner.h index 2c60da975..2df952ebb 100644 --- a/src/ld65/scanner.h +++ b/src/ld65/scanner.h @@ -105,7 +105,7 @@ typedef enum { CFGTOK_RW, CFGTOK_BSS, CFGTOK_ZP, - CFGTOK_REPLACE, + CFGTOK_OVERWRITE, CFGTOK_O65, CFGTOK_BIN, From 1646acb26fef184992b653d835c03eef4a6be7d2 Mon Sep 17 00:00:00 2001 From: Laubzega Date: Sat, 8 Sep 2018 19:20:01 -0700 Subject: [PATCH 6/8] First cut of "overwrite" segment docs. --- doc/ld65.sgml | 60 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 5 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 8f9dd7093..48821797a 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -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 - 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 + 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. +OVERWRITE segments

+ +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: + + +MEMORY { + RAM: file = "", start = $6000, size = $2000, type=bss; + ROM: file = %O, start = $8000, size = $8000, type=ro; +} + + +Nothing unusual so far, just two memory blocks - one RAM, one ROM. Now let's +look at the segment configuration: + + +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; +} + + +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. + LOAD and RUN addresses (ROMable code)

Let us look now at a more complex example. Say, you've successfully tested From 3432788763595512d0c864ba5fc4c8d143c5eb3f Mon Sep 17 00:00:00 2001 From: Laubzega Date: Tue, 11 Sep 2018 22:14:45 -0700 Subject: [PATCH 7/8] Slight fixes to the documentation. --- doc/ld65.sgml | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 48821797a..17f4378b7 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -519,7 +519,7 @@ specify a segment attribute. There are five possible segment attributes: rw means read/write bss means that this is an uninitialized segment zp a zeropage segment - overwrite a segment that overwrites another one + overwrite a segment that overwrites (parts of) another one @@ -635,8 +635,8 @@ Here is an example: MEMORY { - RAM: file = "", start = $6000, size = $2000, type=bss; - ROM: file = %O, start = $8000, size = $8000, type=ro; + RAM: file = "", start = $6000, size = $2000, type=rw; + ROM: file = %O, start = $8000, size = $8000, type=ro; } @@ -655,14 +655,15 @@ SEGMENTS { 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. +a binary form (i.e. using +directive). 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" From 3bace79604146af289ab96da3337c8dc854e7fb6 Mon Sep 17 00:00:00 2001 From: Laubzega Date: Wed, 12 Sep 2018 23:51:38 -0700 Subject: [PATCH 8/8] Fixed reference link. --- doc/ld65.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/ld65.sgml b/doc/ld65.sgml index 17f4378b7..f4cbebbe9 100644 --- a/doc/ld65.sgml +++ b/doc/ld65.sgml @@ -655,8 +655,8 @@ SEGMENTS { Segment named ORIGINAL contains the original code, disassembled or provided in -a binary form (i.e. using -directive). Subsequent four segments will be relocated to addresses specified +a binary form (i.e. using