mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 10:12:06 +00:00
@@ -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);
|
||||||
|
|||||||
@@ -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(); }
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
29
test/asm/load-fragment.asm
Normal file
29
test/asm/load-fragment.asm
Normal 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
|
||||||
0
test/asm/load-fragment.err
Normal file
0
test/asm/load-fragment.err
Normal file
0
test/asm/load-fragment.out
Normal file
0
test/asm/load-fragment.out
Normal file
BIN
test/asm/load-fragment.out.bin
Normal file
BIN
test/asm/load-fragment.out.bin
Normal file
Binary file not shown.
29
test/asm/load-union.asm
Normal file
29
test/asm/load-union.asm
Normal 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
0
test/asm/load-union.err
Normal file
0
test/asm/load-union.out
Normal file
0
test/asm/load-union.out
Normal file
BIN
test/asm/load-union.out.bin
Normal file
BIN
test/asm/load-union.out.bin
Normal file
Binary file not shown.
Reference in New Issue
Block a user