Implement LOAD UNION and LOAD FRAGMENT

Fix #632
This commit is contained in:
Rangi
2021-02-14 16:55:19 -05:00
committed by Eldred Habert
parent c67a696a87
commit 76d6ef8695
12 changed files with 76 additions and 9 deletions

View File

@@ -43,7 +43,8 @@ void out_NewSection(char const *name, uint32_t secttype, uint32_t org,
struct SectionSpec const *attributes, struct SectionSpec const *attributes,
enum SectionModifier mod); enum SectionModifier mod);
void out_SetLoadSection(char const *name, uint32_t secttype, uint32_t org, void out_SetLoadSection(char const *name, uint32_t secttype, uint32_t org,
struct SectionSpec const *attributes); struct SectionSpec const *attributes,
enum SectionModifier mod);
void out_EndLoadSection(void); void out_EndLoadSection(void);
struct Section *sect_GetSymbolSection(void); struct Section *sect_GetSymbolSection(void);

View File

@@ -853,8 +853,8 @@ shift : T_POP_SHIFT { macro_ShiftCurrentArgs(1); }
| T_POP_SHIFT const { macro_ShiftCurrentArgs($2); } | T_POP_SHIFT const { macro_ShiftCurrentArgs($2); }
; ;
load : T_POP_LOAD string T_COMMA sectiontype sectorg sectattrs { load : T_POP_LOAD sectmod string T_COMMA sectiontype sectorg sectattrs {
out_SetLoadSection($2, $4, $5, &$6); out_SetLoadSection($3, $5, $6, &$7, $2);
} }
| T_POP_ENDL { out_EndLoadSection(); } | T_POP_ENDL { out_EndLoadSection(); }
; ;

View File

@@ -719,6 +719,13 @@ The former is situated in ROM, where the code is stored, the latter in RAM, wher
You cannot nest You cannot nest
.Ic LOAD .Ic LOAD
blocks, nor can you change the current section within them. blocks, nor can you change the current section within them.
.Pp
.Ic LOAD
blocks can use the
.Ic UNION
or
.Ic FRAGMENT
modifiers, as described below.
.Ss Unionized Sections .Ss Unionized Sections
When you're tight on RAM, you may want to define overlapping blocks of variables, as explained in the When you're tight on RAM, you may want to define overlapping blocks of variables, as explained in the
.Sx Unions .Sx Unions

View File

@@ -30,7 +30,7 @@ struct SectionStackEntry {
struct SectionStackEntry *sectionStack; struct SectionStackEntry *sectionStack;
uint32_t curOffset; /* Offset into the current section (see sect_GetSymbolOffset) */ uint32_t curOffset; /* Offset into the current section (see sect_GetSymbolOffset) */
static struct Section *currentLoadSection = NULL; static struct Section *currentLoadSection = NULL;
uint32_t loadOffset; /* The offset of the LOAD section within its parent */ int32_t loadOffset; /* Offset into the LOAD section's parent (see sect_GetOutputOffset) */
struct UnionStackEntry { struct UnionStackEntry {
uint32_t start; uint32_t start;
@@ -387,7 +387,8 @@ void out_NewSection(char const *name, uint32_t type, uint32_t org,
* Set the current section by name and type * Set the current section by name and type
*/ */
void out_SetLoadSection(char const *name, uint32_t type, uint32_t org, void out_SetLoadSection(char const *name, uint32_t type, uint32_t org,
struct SectionSpec const *attribs) struct SectionSpec const *attribs,
enum SectionModifier mod)
{ {
checkcodesection(); checkcodesection();
@@ -397,11 +398,11 @@ void out_SetLoadSection(char const *name, uint32_t type, uint32_t org,
if (sect_HasData(type)) if (sect_HasData(type))
error("`LOAD` blocks cannot create a ROM section\n"); error("`LOAD` blocks cannot create a ROM section\n");
struct Section *sect = getSection(name, type, org, attribs, false); struct Section *sect = getSection(name, type, org, attribs, mod);
loadOffset = curOffset;
curOffset = 0; /* curOffset -= loadOffset; */
changeSection(); changeSection();
loadOffset = curOffset - (mod == SECTION_UNION ? 0 : sect->size);
curOffset -= loadOffset;
currentLoadSection = sect; currentLoadSection = sect;
} }
@@ -409,11 +410,11 @@ void out_EndLoadSection(void)
{ {
if (!currentLoadSection) if (!currentLoadSection)
error("Found `ENDL` outside of a `LOAD` block\n"); error("Found `ENDL` outside of a `LOAD` block\n");
currentLoadSection = NULL;
changeSection(); changeSection();
curOffset += loadOffset; curOffset += loadOffset;
loadOffset = 0; loadOffset = 0;
currentLoadSection = NULL;
} }
struct Section *sect_GetSymbolSection(void) struct Section *sect_GetSymbolSection(void)

View File

@@ -0,0 +1,29 @@
SECTION "A", ROM0
AData::
LOAD FRAGMENT "RAM", WRAM0
AMem::
db 0, 1, 2
AMemEnd::
ENDL
ADataEnd::
dw AMem
SECTION "B", ROM0
BData::
LOAD FRAGMENT "RAM", WRAM0
BMem::
db 3, 4, 5, 6, 7
BMemEnd::
ENDL
BDataEnd::
dw BMem
SECTION "C", ROM0
CData::
LOAD FRAGMENT "RAM", WRAM0
CMem::
db 8, 9
CMemEnd::
ENDL
CDataEnd::
dw CMem

View File

View File

Binary file not shown.

29
test/asm/load-union.asm Normal file
View File

@@ -0,0 +1,29 @@
SECTION "A", ROM0
AData::
LOAD UNION "RAM", WRAM0
AMem::
db 0, 1, 2
AMemEnd::
ENDL
ADataEnd::
dw AMem
SECTION "B", ROM0
BData::
LOAD UNION "RAM", WRAM0
BMem::
db 3, 4, 5, 6, 7
BMemEnd::
ENDL
BDataEnd::
dw BMem
SECTION "C", ROM0
CData::
LOAD UNION "RAM", WRAM0
CMem::
db 8, 9
CMemEnd::
ENDL
CDataEnd::
dw CMem

0
test/asm/load-union.err Normal file
View File

0
test/asm/load-union.out Normal file
View File

BIN
test/asm/load-union.out.bin Normal file

Binary file not shown.