From 76d6ef869582a3c714a4b8c7839c2d445b4bfcb1 Mon Sep 17 00:00:00 2001 From: Rangi Date: Sun, 14 Feb 2021 16:55:19 -0500 Subject: [PATCH] Implement LOAD UNION and LOAD FRAGMENT Fix #632 --- include/asm/section.h | 3 ++- src/asm/parser.y | 4 ++-- src/asm/rgbasm.5 | 7 +++++++ src/asm/section.c | 13 +++++++------ test/asm/load-fragment.asm | 29 +++++++++++++++++++++++++++++ test/asm/load-fragment.err | 0 test/asm/load-fragment.out | 0 test/asm/load-fragment.out.bin | Bin 0 -> 16 bytes test/asm/load-union.asm | 29 +++++++++++++++++++++++++++++ test/asm/load-union.err | 0 test/asm/load-union.out | 0 test/asm/load-union.out.bin | Bin 0 -> 16 bytes 12 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 test/asm/load-fragment.asm create mode 100644 test/asm/load-fragment.err create mode 100644 test/asm/load-fragment.out create mode 100644 test/asm/load-fragment.out.bin create mode 100644 test/asm/load-union.asm create mode 100644 test/asm/load-union.err create mode 100644 test/asm/load-union.out create mode 100644 test/asm/load-union.out.bin diff --git a/include/asm/section.h b/include/asm/section.h index 96ee481e..2799c983 100644 --- a/include/asm/section.h +++ b/include/asm/section.h @@ -43,7 +43,8 @@ void out_NewSection(char const *name, uint32_t secttype, uint32_t org, struct SectionSpec const *attributes, enum SectionModifier mod); 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); struct Section *sect_GetSymbolSection(void); diff --git a/src/asm/parser.y b/src/asm/parser.y index c95f6feb..43eb2c66 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -853,8 +853,8 @@ shift : T_POP_SHIFT { macro_ShiftCurrentArgs(1); } | T_POP_SHIFT const { macro_ShiftCurrentArgs($2); } ; -load : T_POP_LOAD string T_COMMA sectiontype sectorg sectattrs { - out_SetLoadSection($2, $4, $5, &$6); +load : T_POP_LOAD sectmod string T_COMMA sectiontype sectorg sectattrs { + out_SetLoadSection($3, $5, $6, &$7, $2); } | T_POP_ENDL { out_EndLoadSection(); } ; diff --git a/src/asm/rgbasm.5 b/src/asm/rgbasm.5 index 0e07750d..ccda63c1 100644 --- a/src/asm/rgbasm.5 +++ b/src/asm/rgbasm.5 @@ -719,6 +719,13 @@ The former is situated in ROM, where the code is stored, the latter in RAM, wher You cannot nest .Ic LOAD 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 When you're tight on RAM, you may want to define overlapping blocks of variables, as explained in the .Sx Unions diff --git a/src/asm/section.c b/src/asm/section.c index da46f7d2..89818368 100644 --- a/src/asm/section.c +++ b/src/asm/section.c @@ -30,7 +30,7 @@ struct SectionStackEntry { struct SectionStackEntry *sectionStack; uint32_t curOffset; /* Offset into the current section (see sect_GetSymbolOffset) */ 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 { 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 */ void out_SetLoadSection(char const *name, uint32_t type, uint32_t org, - struct SectionSpec const *attribs) + struct SectionSpec const *attribs, + enum SectionModifier mod) { checkcodesection(); @@ -397,11 +398,11 @@ void out_SetLoadSection(char const *name, uint32_t type, uint32_t org, if (sect_HasData(type)) 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(); + loadOffset = curOffset - (mod == SECTION_UNION ? 0 : sect->size); + curOffset -= loadOffset; currentLoadSection = sect; } @@ -409,11 +410,11 @@ void out_EndLoadSection(void) { if (!currentLoadSection) error("Found `ENDL` outside of a `LOAD` block\n"); - currentLoadSection = NULL; changeSection(); curOffset += loadOffset; loadOffset = 0; + currentLoadSection = NULL; } struct Section *sect_GetSymbolSection(void) diff --git a/test/asm/load-fragment.asm b/test/asm/load-fragment.asm new file mode 100644 index 00000000..a0225726 --- /dev/null +++ b/test/asm/load-fragment.asm @@ -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 diff --git a/test/asm/load-fragment.err b/test/asm/load-fragment.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/load-fragment.out b/test/asm/load-fragment.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/load-fragment.out.bin b/test/asm/load-fragment.out.bin new file mode 100644 index 0000000000000000000000000000000000000000..5b5d841ce1692996d721ce7abba9de921930f9e7 GIT binary patch literal 16 XcmZQ(VP#`yKES}p#BhLvlj8sY4dw!Q literal 0 HcmV?d00001 diff --git a/test/asm/load-union.asm b/test/asm/load-union.asm new file mode 100644 index 00000000..cadbe6f6 --- /dev/null +++ b/test/asm/load-union.asm @@ -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 diff --git a/test/asm/load-union.err b/test/asm/load-union.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/load-union.out b/test/asm/load-union.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/load-union.out.bin b/test/asm/load-union.out.bin new file mode 100644 index 0000000000000000000000000000000000000000..71675ec7ed4059b233554ed23839172e47c14d70 GIT binary patch literal 16 XcmZQ(VP#`yIKaTj#BhLvli>gW4YdMp literal 0 HcmV?d00001