mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Change behavior of merging FRAGMENTs to constrain each fragment individually
Additionally, remove the deprecated merging of non-fragment SECTIONs
This commit is contained in:
@@ -1487,22 +1487,11 @@ sectattrs : %empty {
|
|||||||
$$.bank = -1;
|
$$.bank = -1;
|
||||||
}
|
}
|
||||||
| sectattrs T_COMMA T_OP_ALIGN T_LBRACK uconst T_RBRACK {
|
| sectattrs T_COMMA T_OP_ALIGN T_LBRACK uconst T_RBRACK {
|
||||||
if ($5 > 16)
|
$$.alignment = $5;
|
||||||
error("Alignment must be between 0 and 16, not %u\n", $5);
|
|
||||||
else
|
|
||||||
$$.alignment = $5;
|
|
||||||
}
|
}
|
||||||
| sectattrs T_COMMA T_OP_ALIGN T_LBRACK uconst T_COMMA uconst T_RBRACK {
|
| sectattrs T_COMMA T_OP_ALIGN T_LBRACK uconst T_COMMA uconst T_RBRACK {
|
||||||
if ($5 > 16) {
|
$$.alignment = $5;
|
||||||
error("Alignment must be between 0 and 16, not %u\n", $5);
|
$$.alignOfs = $7;
|
||||||
} else {
|
|
||||||
$$.alignment = $5;
|
|
||||||
if ($7 >= 1 << $$.alignment)
|
|
||||||
error("Alignment offset must not be greater than alignment (%u < %u)\n",
|
|
||||||
$7, 1 << $$.alignment);
|
|
||||||
else
|
|
||||||
$$.alignOfs = $7;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
| sectattrs T_COMMA T_OP_BANK T_LBRACK uconst T_RBRACK {
|
| sectattrs T_COMMA T_OP_BANK T_LBRACK uconst T_RBRACK {
|
||||||
/* We cannot check the validity of this now */
|
/* We cannot check the validity of this now */
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -98,36 +99,199 @@ struct Section *out_FindSectionByName(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define mask(align) ((1U << (align)) - 1)
|
||||||
|
#define fail(...) \
|
||||||
|
do { \
|
||||||
|
error(__VA_ARGS__); \
|
||||||
|
nbSectErrors++; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static unsigned int mergeSectUnion(struct Section *sect, enum SectionType type, uint32_t org,
|
||||||
|
uint8_t alignment, uint16_t alignOffset)
|
||||||
|
{
|
||||||
|
assert(alignment < 16); // Should be ensured by the caller
|
||||||
|
unsigned int nbSectErrors = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Unionized sections only need "compatible" constraints, and they end up with the strictest
|
||||||
|
* combination of both.
|
||||||
|
*/
|
||||||
|
if (sect_HasData(type))
|
||||||
|
fail("Cannot declare ROM sections as UNION\n");
|
||||||
|
|
||||||
|
if (org != -1) {
|
||||||
|
/* If both are fixed, they must be the same */
|
||||||
|
if (sect->org != -1 && sect->org != org)
|
||||||
|
fail("Section already declared as fixed at different address $%04"
|
||||||
|
PRIx32 "\n", sect->org);
|
||||||
|
else if (sect->align != 0 && (mask(sect->align) & (org - sect->alignOfs)))
|
||||||
|
fail("Section already declared as aligned to %u bytes (offset %"
|
||||||
|
PRIu16 ")\n", 1U << sect->align, sect->alignOfs);
|
||||||
|
else
|
||||||
|
/* Otherwise, just override */
|
||||||
|
sect->org = org;
|
||||||
|
|
||||||
|
} else if (alignment != 0) {
|
||||||
|
/* Make sure any fixed address given is compatible */
|
||||||
|
if (sect->org != -1) {
|
||||||
|
if ((sect->org - alignOffset) & mask(alignment))
|
||||||
|
fail("Section already declared as fixed at incompatible address $%04"
|
||||||
|
PRIx32 "\n", sect->org);
|
||||||
|
/* Check if alignment offsets are compatible */
|
||||||
|
} else if ((alignOffset & mask(sect->align))
|
||||||
|
!= (sect->alignOfs & mask(alignment))) {
|
||||||
|
fail("Section already declared with incompatible %" PRIu8
|
||||||
|
"-byte alignment (offset %" PRIu16 ")\n",
|
||||||
|
sect->align, sect->alignOfs);
|
||||||
|
} else if (alignment > sect->align) {
|
||||||
|
// If the section is not fixed, its alignment is the largest of both
|
||||||
|
sect->align = alignment;
|
||||||
|
sect->alignOfs = alignOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbSectErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int mergeFragments(struct Section *sect, enum SectionType type, uint32_t org,
|
||||||
|
uint8_t alignment, uint16_t alignOffset)
|
||||||
|
{
|
||||||
|
(void)type;
|
||||||
|
assert(alignment < 16); // Should be ensured by the caller
|
||||||
|
unsigned int nbSectErrors = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fragments only need "compatible" constraints, and they end up with the strictest
|
||||||
|
* combination of both.
|
||||||
|
* The merging is however performed at the *end* of the original section!
|
||||||
|
*/
|
||||||
|
if (org != -1) {
|
||||||
|
uint16_t curOrg = org - sect->size;
|
||||||
|
|
||||||
|
/* If both are fixed, they must be the same */
|
||||||
|
if (sect->org != -1 && sect->org != curOrg)
|
||||||
|
fail("Section already declared as fixed at incompatible address $%04"
|
||||||
|
PRIx32 " (cur addr = %04" PRIx32 ")\n",
|
||||||
|
sect->org, sect->org + sect->size);
|
||||||
|
else if (sect->align != 0 && (mask(sect->align) & (curOrg - sect->alignOfs)))
|
||||||
|
fail("Section already declared as aligned to %u bytes (offset %"
|
||||||
|
PRIu16 ")\n", 1U << sect->align, sect->alignOfs);
|
||||||
|
else
|
||||||
|
/* Otherwise, just override */
|
||||||
|
sect->org = curOrg;
|
||||||
|
|
||||||
|
} else if (alignment != 0) {
|
||||||
|
int32_t curOfs = (alignOffset - sect->size) % (1U << alignment);
|
||||||
|
|
||||||
|
if (curOfs < 0)
|
||||||
|
curOfs += 1U << alignment;
|
||||||
|
|
||||||
|
/* Make sure any fixed address given is compatible */
|
||||||
|
if (sect->org != -1) {
|
||||||
|
if ((sect->org - curOfs) & mask(alignment))
|
||||||
|
fail("Section already declared as fixed at incompatible address $%04"
|
||||||
|
PRIx32 "\n", sect->org);
|
||||||
|
/* Check if alignment offsets are compatible */
|
||||||
|
} else if ((curOfs & mask(sect->align)) != (sect->alignOfs & mask(alignment))) {
|
||||||
|
fail("Section already declared with incompatible %" PRIu8
|
||||||
|
"-byte alignment (offset %" PRIu16 ")\n",
|
||||||
|
sect->align, sect->alignOfs);
|
||||||
|
} else if (alignment > sect->align) {
|
||||||
|
// If the section is not fixed, its alignment is the largest of both
|
||||||
|
sect->align = alignment;
|
||||||
|
sect->alignOfs = curOfs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nbSectErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mergeSections(struct Section *sect, enum SectionType type, uint32_t org, uint32_t bank,
|
||||||
|
uint8_t alignment, uint16_t alignOffset, enum SectionModifier mod)
|
||||||
|
{
|
||||||
|
unsigned int nbSectErrors = 0;
|
||||||
|
|
||||||
|
if (type != sect->type)
|
||||||
|
fail("Section already exists but with type %s\n", typeNames[sect->type]);
|
||||||
|
|
||||||
|
if (sect->modifier != mod) {
|
||||||
|
fail("Section already declared as %s section\n", sectionModNames[sect->modifier]);
|
||||||
|
} else {
|
||||||
|
switch (mod) {
|
||||||
|
case SECTION_UNION:
|
||||||
|
case SECTION_FRAGMENT:
|
||||||
|
nbSectErrors += (mod == SECTION_UNION ? mergeSectUnion : mergeFragments)
|
||||||
|
(sect, type, org, alignment, alignOffset);
|
||||||
|
|
||||||
|
// Common checks
|
||||||
|
|
||||||
|
/* If the section's bank is unspecified, override it */
|
||||||
|
if (sect->bank == -1)
|
||||||
|
sect->bank = bank;
|
||||||
|
/* If both specify a bank, it must be the same one */
|
||||||
|
else if (bank != -1 && sect->bank != bank)
|
||||||
|
fail("Section already declared with different bank %" PRIu32 "\n",
|
||||||
|
sect->bank);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECTION_NORMAL:
|
||||||
|
// TODO: this should report where the section was defined
|
||||||
|
fail("Section already defined previously\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbSectErrors)
|
||||||
|
fatalerror("Cannot create section \"%s\" (%u error%s)\n",
|
||||||
|
sect->name, nbSectErrors, nbSectErrors == 1 ? "" : "s");
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef fail
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a section by name and type. If it doesn't exist, create it
|
* Find a section by name and type. If it doesn't exist, create it
|
||||||
*/
|
*/
|
||||||
static struct Section *getSection(char const *name, enum SectionType type,
|
static struct Section *getSection(char const *name, enum SectionType type, uint32_t org,
|
||||||
uint32_t org, struct SectionSpec const *attrs,
|
struct SectionSpec const *attrs, enum SectionModifier mod)
|
||||||
enum SectionModifier mod)
|
|
||||||
{
|
{
|
||||||
#define mask(align) ((1 << (align)) - 1)
|
|
||||||
uint32_t bank = attrs->bank;
|
uint32_t bank = attrs->bank;
|
||||||
uint8_t alignment = attrs->alignment;
|
uint8_t alignment = attrs->alignment;
|
||||||
uint16_t alignOffset = attrs->alignOfs;
|
uint16_t alignOffset = attrs->alignOfs;
|
||||||
|
|
||||||
|
// First, validate parameters, and normalize them if applicable
|
||||||
|
|
||||||
if (bank != -1) {
|
if (bank != -1) {
|
||||||
if (type != SECTTYPE_ROMX && type != SECTTYPE_VRAM
|
if (type != SECTTYPE_ROMX && type != SECTTYPE_VRAM
|
||||||
&& type != SECTTYPE_SRAM && type != SECTTYPE_WRAMX)
|
&& type != SECTTYPE_SRAM && type != SECTTYPE_WRAMX)
|
||||||
error("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections\n");
|
error("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections\n");
|
||||||
else if (bank < bankranges[type][0]
|
else if (bank < bankranges[type][0]
|
||||||
|| bank > bankranges[type][1])
|
|| bank > bankranges[type][1])
|
||||||
error("%s bank value $%" PRIx32 " out of range ($%" PRIx32 " to $%"
|
error("%s bank value $%04" PRIx32 " out of range ($%04" PRIx32 " to $%04"
|
||||||
PRIx32 ")\n", typeNames[type], bank,
|
PRIx32 ")\n", typeNames[type], bank,
|
||||||
bankranges[type][0], bankranges[type][1]);
|
bankranges[type][0], bankranges[type][1]);
|
||||||
|
} else if (nbbanks(type) == 1) {
|
||||||
|
// If the section type only has a single bank, implicitly force it
|
||||||
|
bank = bankranges[type][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alignOffset >= 1 << alignment) {
|
if (alignOffset >= 1 << alignment) {
|
||||||
error("Alignment offset must not be greater than alignment (%" PRIu16 " < %u)\n",
|
error("Alignment offset (%" PRIu16 ") must be smaller than alignment size (%u)\n",
|
||||||
alignOffset, 1U << alignment);
|
alignOffset, 1U << alignment);
|
||||||
alignOffset = 0;
|
alignOffset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (org != -1) {
|
||||||
|
if (org < startaddr[type] || org > endaddr(type))
|
||||||
|
error("Section \"%s\"'s fixed address %#" PRIx32
|
||||||
|
" is outside of range [%#" PRIx16 "; %#" PRIx16 "]\n",
|
||||||
|
name, org, startaddr[type], endaddr(type));
|
||||||
|
}
|
||||||
|
|
||||||
if (alignment != 0) {
|
if (alignment != 0) {
|
||||||
|
if (alignment > 16) {
|
||||||
|
error("Alignment must be between 0 and 16, not %u\n", alignment);
|
||||||
|
alignment = 16;
|
||||||
|
}
|
||||||
/* It doesn't make sense to have both alignment and org set */
|
/* It doesn't make sense to have both alignment and org set */
|
||||||
uint32_t mask = mask(alignment);
|
uint32_t mask = mask(alignment);
|
||||||
|
|
||||||
@@ -139,128 +303,20 @@ static struct Section *getSection(char const *name, enum SectionType type,
|
|||||||
} else if (startaddr[type] & mask) {
|
} else if (startaddr[type] & mask) {
|
||||||
error("Section \"%s\"'s alignment cannot be attained in %s\n",
|
error("Section \"%s\"'s alignment cannot be attained in %s\n",
|
||||||
name, typeNames[type]);
|
name, typeNames[type]);
|
||||||
|
} else if (alignment == 16) {
|
||||||
|
// Treat an alignment of 16 as being fixed at address 0
|
||||||
|
alignment = 0;
|
||||||
|
org = 0;
|
||||||
|
// The address is known to be valid, since the alignment is
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (org != -1) {
|
// Check if another section exists with the same name; merge if yes, otherwise create one
|
||||||
if (org < startaddr[type] || org > endaddr(type))
|
|
||||||
error("Section \"%s\"'s fixed address %#" PRIx32
|
|
||||||
" is outside of range [%#" PRIx16 "; %#" PRIx16 "]\n",
|
|
||||||
name, org, startaddr[type], endaddr(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nbbanks(type) == 1)
|
|
||||||
bank = bankranges[type][0];
|
|
||||||
|
|
||||||
struct Section *sect = out_FindSectionByName(name);
|
struct Section *sect = out_FindSectionByName(name);
|
||||||
|
|
||||||
if (sect) {
|
if (sect) {
|
||||||
unsigned int nbSectErrors = 0;
|
mergeSections(sect, type, org, bank, alignment, alignOffset, mod);
|
||||||
#define fail(...) \
|
|
||||||
do { \
|
|
||||||
error(__VA_ARGS__); \
|
|
||||||
nbSectErrors++; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
if (type != sect->type)
|
|
||||||
fail("Section \"%s\" already exists but with type %s\n",
|
|
||||||
sect->name, typeNames[sect->type]);
|
|
||||||
|
|
||||||
if (sect->modifier != mod)
|
|
||||||
fail("Section \"%s\" already declared as %s section\n",
|
|
||||||
sect->name, sectionModNames[sect->modifier]);
|
|
||||||
/*
|
|
||||||
* Normal sections need to have exactly identical constraints;
|
|
||||||
* but unionized sections only need "compatible" constraints,
|
|
||||||
* and they end up with the strictest combination of both
|
|
||||||
*/
|
|
||||||
if (mod == SECTION_UNION) {
|
|
||||||
/*
|
|
||||||
* WARNING: see comment about assumption in
|
|
||||||
* `EndLoadSection` if modifying the following check!
|
|
||||||
*/
|
|
||||||
if (sect_HasData(type))
|
|
||||||
fail("Cannot declare ROM sections as UNION\n");
|
|
||||||
if (org != -1) {
|
|
||||||
/* If both are fixed, they must be the same */
|
|
||||||
if (sect->org != -1 && sect->org != org)
|
|
||||||
fail("Section \"%s\" already declared as fixed at different address $%"
|
|
||||||
PRIx32 "\n",
|
|
||||||
sect->name, sect->org);
|
|
||||||
else if (sect->align != 0
|
|
||||||
&& (mask(sect->align)
|
|
||||||
& (org - sect->alignOfs)))
|
|
||||||
fail("Section \"%s\" already declared as aligned to %u bytes (offset %"
|
|
||||||
PRIu16 ")\n", sect->name, 1U << sect->align, sect->alignOfs);
|
|
||||||
else
|
|
||||||
/* Otherwise, just override */
|
|
||||||
sect->org = org;
|
|
||||||
} else if (alignment != 0) {
|
|
||||||
/* Make sure any fixed address is compatible */
|
|
||||||
if (sect->org != -1) {
|
|
||||||
if ((sect->org - alignOffset)
|
|
||||||
& mask(alignment))
|
|
||||||
fail("Section \"%s\" already declared as fixed at incompatible address $%"
|
|
||||||
PRIx32 "\n", sect->name, sect->org);
|
|
||||||
/* Check if alignment offsets are compatible */
|
|
||||||
} else if ((alignOffset & mask(sect->align))
|
|
||||||
!= (sect->alignOfs
|
|
||||||
& mask(alignment))) {
|
|
||||||
fail("Section \"%s\" already declared with incompatible %"
|
|
||||||
PRIu8 "-byte alignment (offset %" PRIu16 ")\n",
|
|
||||||
sect->name, sect->align, sect->alignOfs);
|
|
||||||
} else if (alignment > sect->align) {
|
|
||||||
/*
|
|
||||||
* If the section is not fixed,
|
|
||||||
* its alignment is the largest of both
|
|
||||||
*/
|
|
||||||
sect->align = alignment;
|
|
||||||
sect->alignOfs = alignOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If the section's bank is unspecified, override it */
|
|
||||||
if (sect->bank == -1)
|
|
||||||
sect->bank = bank;
|
|
||||||
/* If both specify a bank, it must be the same one */
|
|
||||||
else if (bank != -1 && sect->bank != bank)
|
|
||||||
fail("Section \"%s\" already declared with different bank %"
|
|
||||||
PRIu32 "\n", sect->name, sect->bank);
|
|
||||||
} else { /* Section fragments are handled identically in RGBASM */
|
|
||||||
/* However, concaternating non-fragments will be made an error */
|
|
||||||
if (sect->modifier != SECTION_FRAGMENT || mod != SECTION_FRAGMENT)
|
|
||||||
warning(WARNING_OBSOLETE,
|
|
||||||
"Concatenation of non-fragment sections is deprecated\n");
|
|
||||||
|
|
||||||
if (org != sect->org) {
|
|
||||||
if (sect->org == -1)
|
|
||||||
fail("Section \"%s\" already declared as floating\n",
|
|
||||||
sect->name);
|
|
||||||
else
|
|
||||||
fail("Section \"%s\" already declared as fixed at $%"
|
|
||||||
PRIx32 "\n", sect->name, sect->org);
|
|
||||||
}
|
|
||||||
if (bank != sect->bank) {
|
|
||||||
if (sect->bank == -1)
|
|
||||||
fail("Section \"%s\" already declared as floating bank\n",
|
|
||||||
sect->name);
|
|
||||||
else
|
|
||||||
fail("Section \"%s\" already declared as fixed at bank %"
|
|
||||||
PRIu32 "\n", sect->name, sect->bank);
|
|
||||||
}
|
|
||||||
if (alignment != sect->align) {
|
|
||||||
if (sect->align == 0)
|
|
||||||
fail("Section \"%s\" already declared as unaligned\n",
|
|
||||||
sect->name);
|
|
||||||
else
|
|
||||||
fail("Section \"%s\" already declared as aligned to %u bytes\n",
|
|
||||||
sect->name, 1U << sect->align);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nbSectErrors)
|
|
||||||
fatalerror("Cannot create section \"%s\" (%u errors)\n",
|
|
||||||
sect->name, nbSectErrors);
|
|
||||||
#undef fail
|
|
||||||
return sect;
|
return sect;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +335,6 @@ static struct Section *getSection(char const *name, enum SectionType type,
|
|||||||
sect->bank = bank;
|
sect->bank = bank;
|
||||||
sect->align = alignment;
|
sect->align = alignment;
|
||||||
sect->alignOfs = alignOffset;
|
sect->alignOfs = alignOffset;
|
||||||
sect->next = pSectionList;
|
|
||||||
sect->patches = NULL;
|
sect->patches = NULL;
|
||||||
|
|
||||||
/* It is only needed to allocate memory for ROM sections. */
|
/* It is only needed to allocate memory for ROM sections. */
|
||||||
@@ -294,14 +349,11 @@ static struct Section *getSection(char const *name, enum SectionType type,
|
|||||||
sect->data = NULL;
|
sect->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Add the new section to the list (order doesn't matter)
|
||||||
* Add the new section to the list
|
sect->next = pSectionList;
|
||||||
* at the beginning because order doesn't matter
|
|
||||||
*/
|
|
||||||
pSectionList = sect;
|
pSectionList = sect;
|
||||||
|
|
||||||
return sect;
|
return sect;
|
||||||
#undef mask
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -349,6 +349,8 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam
|
|||||||
section->bank = tmp;
|
section->bank = tmp;
|
||||||
tryGetc(byte, file, "%s: Cannot read \"%s\"'s alignment: %s",
|
tryGetc(byte, file, "%s: Cannot read \"%s\"'s alignment: %s",
|
||||||
fileName, section->name);
|
fileName, section->name);
|
||||||
|
if (byte > 16)
|
||||||
|
byte = 16;
|
||||||
section->isAlignFixed = byte != 0;
|
section->isAlignFixed = byte != 0;
|
||||||
section->alignMask = (1 << byte) - 1;
|
section->alignMask = (1 << byte) - 1;
|
||||||
tryReadlong(tmp, file, "%s: Cannot read \"%s\"'s alignment offset: %s",
|
tryReadlong(tmp, file, "%s: Cannot read \"%s\"'s alignment offset: %s",
|
||||||
|
|||||||
@@ -39,62 +39,123 @@ void sect_ForEach(void (*callback)(struct Section *, void *), void *arg)
|
|||||||
hash_ForEach(sections, forEach, &callbackArg);
|
hash_ForEach(sections, forEach, &callbackArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mergeSections(struct Section *target, struct Section *other, enum SectionModifier mod)
|
static void checkSectUnionCompat(struct Section *target, struct Section *other)
|
||||||
{
|
{
|
||||||
if (target->type != other->type)
|
|
||||||
errx(1, "Section \"%s\" is defined with conflicting types %s and %s",
|
|
||||||
other->name,
|
|
||||||
typeNames[target->type], typeNames[other->type]);
|
|
||||||
if (other->isAddressFixed) {
|
if (other->isAddressFixed) {
|
||||||
if (target->isAddressFixed) {
|
if (target->isAddressFixed) {
|
||||||
if (target->org != other->org)
|
if (target->org != other->org)
|
||||||
errx(1, "Section \"%s\" is defined with conflicting addresses $%" PRIx16 " and $%" PRIx16,
|
errx(1, "Section \"%s\" is defined with conflicting addresses $%04"
|
||||||
|
PRIx16 " and $%04" PRIx16,
|
||||||
other->name, target->org, other->org);
|
other->name, target->org, other->org);
|
||||||
} else if (target->isAlignFixed) {
|
} else if (target->isAlignFixed) {
|
||||||
if ((other->org - target->alignOfs) & target->alignMask)
|
if ((other->org - target->alignOfs) & target->alignMask)
|
||||||
errx(1, "Section \"%s\" is defined with conflicting %" PRIu16 "-byte alignment (offset %" PRIu16 ") and address $%" PRIx16,
|
errx(1, "Section \"%s\" is defined with conflicting %" PRIu16
|
||||||
|
"-byte alignment (offset %" PRIu16 ") and address $%04" PRIx16,
|
||||||
other->name, target->alignMask + 1,
|
other->name, target->alignMask + 1,
|
||||||
target->alignOfs, other->org);
|
target->alignOfs, other->org);
|
||||||
}
|
}
|
||||||
target->isAddressFixed = true;
|
target->isAddressFixed = true;
|
||||||
target->org = other->org;
|
target->org = other->org;
|
||||||
|
|
||||||
} else if (other->isAlignFixed) {
|
} else if (other->isAlignFixed) {
|
||||||
if (target->isAddressFixed) {
|
if (target->isAddressFixed) {
|
||||||
if ((target->org - other->alignOfs) & other->alignMask)
|
if ((target->org - other->alignOfs) & other->alignMask)
|
||||||
errx(1, "Section \"%s\" is defined with conflicting address $%" PRIx16 " and %" PRIu16 "-byte alignment (offset %" PRIu16 ")",
|
errx(1, "Section \"%s\" is defined with conflicting address $%04"
|
||||||
|
PRIx16 " and %" PRIu16 "-byte alignment (offset %" PRIu16 ")",
|
||||||
other->name, target->org,
|
other->name, target->org,
|
||||||
other->alignMask + 1, other->alignOfs);
|
other->alignMask + 1, other->alignOfs);
|
||||||
} else if (target->isAlignFixed
|
} else if (target->isAlignFixed
|
||||||
&& (other->alignMask & target->alignOfs)
|
&& (other->alignMask & target->alignOfs)
|
||||||
!= (target->alignMask & other->alignOfs)) {
|
!= (target->alignMask & other->alignOfs)) {
|
||||||
errx(1, "Section \"%s\" is defined with conflicting %" PRIu16 "-byte alignment (offset %" PRIu16 ") and %" PRIu16 "-byte alignment (offset %" PRIu16 ")",
|
errx(1, "Section \"%s\" is defined with conflicting %" PRIu16
|
||||||
other->name, target->alignMask + 1,
|
"-byte alignment (offset %" PRIu16 ") and %" PRIu16
|
||||||
target->alignOfs, other->alignMask + 1,
|
"-byte alignment (offset %" PRIu16 ")",
|
||||||
other->alignOfs);
|
other->name, target->alignMask + 1, target->alignOfs,
|
||||||
} else if (!target->isAlignFixed
|
other->alignMask + 1, other->alignOfs);
|
||||||
|| (other->alignMask > target->alignMask)) {
|
} else if (!target->isAlignFixed || (other->alignMask > target->alignMask)) {
|
||||||
target->isAlignFixed = true;
|
target->isAlignFixed = true;
|
||||||
target->alignMask = other->alignMask;
|
target->alignMask = other->alignMask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkFragmentCompat(struct Section *target, struct Section *other)
|
||||||
|
{
|
||||||
|
if (other->isAddressFixed) {
|
||||||
|
uint16_t org = other->org - target->size;
|
||||||
|
|
||||||
|
if (target->isAddressFixed) {
|
||||||
|
if (target->org != org)
|
||||||
|
errx(1, "Section \"%s\" is defined with conflicting addresses $%04"
|
||||||
|
PRIx16 " and $%04" PRIx16,
|
||||||
|
other->name, target->org, other->org);
|
||||||
|
|
||||||
|
} else if (target->isAlignFixed) {
|
||||||
|
if ((org - target->alignOfs) & target->alignMask)
|
||||||
|
errx(1, "Section \"%s\" is defined with conflicting %" PRIu16
|
||||||
|
"-byte alignment (offset %" PRIu16 ") and address $%04" PRIx16,
|
||||||
|
other->name, target->alignMask + 1,
|
||||||
|
target->alignOfs, other->org);
|
||||||
|
}
|
||||||
|
target->isAddressFixed = true;
|
||||||
|
target->org = org;
|
||||||
|
|
||||||
|
} else if (other->isAlignFixed) {
|
||||||
|
int32_t ofs = (other->alignOfs - target->size) % (other->alignMask + 1);
|
||||||
|
|
||||||
|
if (ofs < 0)
|
||||||
|
ofs += other->alignMask + 1;
|
||||||
|
|
||||||
|
if (target->isAddressFixed) {
|
||||||
|
if ((target->org - ofs) & other->alignMask)
|
||||||
|
errx(1, "Section \"%s\" is defined with conflicting address $%04"
|
||||||
|
PRIx16 " and %" PRIu16 "-byte alignment (offset %" PRIu16 ")",
|
||||||
|
other->name, target->org,
|
||||||
|
other->alignMask + 1, other->alignOfs);
|
||||||
|
|
||||||
|
} else if (target->isAlignFixed
|
||||||
|
&& (other->alignMask & target->alignOfs) != (target->alignMask & ofs)) {
|
||||||
|
errx(1, "Section \"%s\" is defined with conflicting %" PRIu16
|
||||||
|
"-byte alignment (offset %" PRIu16 ") and %" PRIu16
|
||||||
|
"-byte alignment (offset %" PRIu16 ")",
|
||||||
|
other->name, target->alignMask + 1, target->alignOfs,
|
||||||
|
other->alignMask + 1, other->alignOfs);
|
||||||
|
|
||||||
|
} else if (!target->isAlignFixed || (other->alignMask > target->alignMask)) {
|
||||||
|
target->isAlignFixed = true;
|
||||||
|
target->alignMask = other->alignMask;
|
||||||
|
target->alignOfs = ofs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mergeSections(struct Section *target, struct Section *other, enum SectionModifier mod)
|
||||||
|
{
|
||||||
|
// Common checks
|
||||||
|
|
||||||
|
if (target->type != other->type)
|
||||||
|
errx(1, "Section \"%s\" is defined with conflicting types %s and %s",
|
||||||
|
other->name, typeNames[target->type], typeNames[other->type]);
|
||||||
|
|
||||||
if (other->isBankFixed) {
|
if (other->isBankFixed) {
|
||||||
if (!target->isBankFixed) {
|
if (!target->isBankFixed) {
|
||||||
target->isBankFixed = true;
|
target->isBankFixed = true;
|
||||||
target->bank = other->bank;
|
target->bank = other->bank;
|
||||||
} else if (target->bank != other->bank) {
|
} else if (target->bank != other->bank) {
|
||||||
errx(1, "Section \"%s\" is defined with conflicting banks %" PRIu32 " and %" PRIu32,
|
errx(1, "Section \"%s\" is defined with conflicting banks %" PRIu32 " and %"
|
||||||
other->name, target->bank, other->bank);
|
PRIu32, other->name, target->bank, other->bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (mod) {
|
switch (mod) {
|
||||||
case SECTION_UNION:
|
case SECTION_UNION:
|
||||||
|
checkSectUnionCompat(target, other);
|
||||||
if (other->size > target->size)
|
if (other->size > target->size)
|
||||||
target->size = other->size;
|
target->size = other->size;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SECTION_FRAGMENT:
|
case SECTION_FRAGMENT:
|
||||||
|
checkFragmentCompat(target, other);
|
||||||
target->size += other->size;
|
target->size += other->size;
|
||||||
other->offset = target->size - other->size;
|
other->offset = target->size - other->size;
|
||||||
if (sect_HasData(target->type)) {
|
if (sect_HasData(target->type)) {
|
||||||
@@ -167,20 +228,20 @@ static void doSanityChecks(struct Section *section, void *ptr)
|
|||||||
fail("Section \"%s\" has an invalid type.", section->name);
|
fail("Section \"%s\" has an invalid type.", section->name);
|
||||||
if (is32kMode && section->type == SECTTYPE_ROMX) {
|
if (is32kMode && section->type == SECTTYPE_ROMX) {
|
||||||
if (section->isBankFixed && section->bank != 1)
|
if (section->isBankFixed && section->bank != 1)
|
||||||
fail("%s: ROMX sections must be in bank 1 with option -t.",
|
fail("%s: ROMX sections must be in bank 1 (if any) with option -t",
|
||||||
section->name);
|
section->name);
|
||||||
else
|
else
|
||||||
section->type = SECTTYPE_ROM0;
|
section->type = SECTTYPE_ROM0;
|
||||||
}
|
}
|
||||||
if (isWRA0Mode && section->type == SECTTYPE_WRAMX) {
|
if (isWRA0Mode && section->type == SECTTYPE_WRAMX) {
|
||||||
if (section->isBankFixed && section->bank != 1)
|
if (section->isBankFixed && section->bank != 1)
|
||||||
fail("%s: WRAMX sections must be in bank 1 with options -w or -d.",
|
fail("%s: WRAMX sections must be in bank 1 with options -w or -d",
|
||||||
section->name);
|
section->name);
|
||||||
else
|
else
|
||||||
section->type = SECTTYPE_WRAMX;
|
section->type = SECTTYPE_WRAMX;
|
||||||
}
|
}
|
||||||
if (isDmgMode && section->type == SECTTYPE_VRAM && section->bank == 1)
|
if (isDmgMode && section->type == SECTTYPE_VRAM && section->bank == 1)
|
||||||
fail("%s: VRAM bank 1 can't be used with option -d.",
|
fail("%s: VRAM bank 1 can't be used with option -d",
|
||||||
section->name);
|
section->name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -191,17 +252,13 @@ static void doSanityChecks(struct Section *section, void *ptr)
|
|||||||
section->isAlignFixed = false;
|
section->isAlignFixed = false;
|
||||||
|
|
||||||
/* Too large an alignment may not be satisfiable */
|
/* Too large an alignment may not be satisfiable */
|
||||||
if (section->isAlignFixed
|
if (section->isAlignFixed && (section->alignMask & startaddr[section->type]))
|
||||||
&& (section->alignMask & startaddr[section->type]))
|
fail("%s: %s sections cannot be aligned to $%04" PRIx16 " bytes",
|
||||||
fail("%s: %s sections cannot be aligned to $%" PRIx16 " bytes",
|
section->name, typeNames[section->type], section->alignMask + 1);
|
||||||
section->name, typeNames[section->type],
|
|
||||||
section->alignMask + 1);
|
|
||||||
|
|
||||||
uint32_t minbank = bankranges[section->type][0],
|
uint32_t minbank = bankranges[section->type][0], maxbank = bankranges[section->type][1];
|
||||||
maxbank = bankranges[section->type][1];
|
|
||||||
|
|
||||||
if (section->isBankFixed && section->bank < minbank
|
if (section->isBankFixed && section->bank < minbank && section->bank > maxbank)
|
||||||
&& section->bank > maxbank)
|
|
||||||
fail(minbank == maxbank
|
fail(minbank == maxbank
|
||||||
? "Cannot place section \"%s\" in bank %" PRIu32 ", it must be %" PRIu32
|
? "Cannot place section \"%s\" in bank %" PRIu32 ", it must be %" PRIu32
|
||||||
: "Cannot place section \"%s\" in bank %" PRIu32 ", it must be between %" PRIu32 " and %" PRIu32,
|
: "Cannot place section \"%s\" in bank %" PRIu32 ", it must be between %" PRIu32 " and %" PRIu32,
|
||||||
@@ -219,35 +276,26 @@ static void doSanityChecks(struct Section *section, void *ptr)
|
|||||||
section->isBankFixed = true;
|
section->isBankFixed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (section->isAlignFixed) {
|
if (section->isAddressFixed) {
|
||||||
enum SectionType type = section->type;
|
|
||||||
|
|
||||||
/* It doesn't make sense to have both org and alignment set */
|
/* It doesn't make sense to have both org and alignment set */
|
||||||
if (section->isAddressFixed) {
|
if (section->isAlignFixed) {
|
||||||
if (section->org & section->alignMask)
|
if ((section->org & section->alignMask) != section->alignOfs)
|
||||||
fail("Section \"%s\"'s fixed address doesn't match its alignment",
|
fail("Section \"%s\"'s fixed address doesn't match its alignment",
|
||||||
section->name);
|
section->name);
|
||||||
section->isAlignFixed = false;
|
section->isAlignFixed = false;
|
||||||
} else if ((endaddr(type) & section->alignMask)
|
|
||||||
== startaddr[type]) {
|
|
||||||
section->org = startaddr[type];
|
|
||||||
section->isAlignFixed = false;
|
|
||||||
section->isAddressFixed = true;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (section->isAddressFixed) {
|
|
||||||
/* Ensure the target address is valid */
|
/* Ensure the target address is valid */
|
||||||
if (section->org < startaddr[section->type]
|
if (section->org < startaddr[section->type]
|
||||||
|| section->org > endaddr(section->type))
|
|| section->org > endaddr(section->type))
|
||||||
fail("Section \"%s\"'s fixed address %#" PRIx16 " is outside of range [%#" PRIx16 "; %#" PRIx16 "]",
|
fail("Section \"%s\"'s fixed address %#" PRIx16 " is outside of range [%#"
|
||||||
section->name, section->org,
|
PRIx16 "; %#" PRIx16 "]", section->name, section->org,
|
||||||
startaddr[section->type], endaddr(section->type));
|
startaddr[section->type], endaddr(section->type));
|
||||||
|
|
||||||
if (section->org + section->size > endaddr(section->type) + 1)
|
if (section->org + section->size > endaddr(section->type) + 1)
|
||||||
fail("Section \"%s\"'s end address %#" PRIx16 " is greater than last address %#" PRIx16,
|
fail("Section \"%s\"'s end address %#" PRIx16
|
||||||
section->name, section->org + section->size,
|
" is greater than last address %#" PRIx16, section->name,
|
||||||
endaddr(section->type) + 1);
|
section->org + section->size, endaddr(section->type) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef fail
|
#undef fail
|
||||||
|
|||||||
8
test/asm/align-16.asm
Normal file
8
test/asm/align-16.asm
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
SECTION "Byte", ROM0
|
||||||
|
|
||||||
|
db 2
|
||||||
|
|
||||||
|
SECTION "ROM0", ROM0, ALIGN[16]
|
||||||
|
|
||||||
|
db 1
|
||||||
0
test/asm/align-16.err
Normal file
0
test/asm/align-16.err
Normal file
0
test/asm/align-16.out
Normal file
0
test/asm/align-16.out
Normal file
1
test/asm/align-16.out.bin
Normal file
1
test/asm/align-16.out.bin
Normal file
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
2
test/asm/align-large-ofs.asm
Normal file
2
test/asm/align-large-ofs.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
SECTION "Tesst", ROM0, ALIGN[1,2]
|
||||||
3
test/asm/align-large-ofs.err
Normal file
3
test/asm/align-large-ofs.err
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
ERROR: align-large-ofs.asm(2):
|
||||||
|
Alignment offset (2) must be smaller than alignment size (2)
|
||||||
|
error: Assembly aborted (1 errors)!
|
||||||
0
test/asm/align-large-ofs.out
Normal file
0
test/asm/align-large-ofs.out
Normal file
2
test/asm/align-large.asm
Normal file
2
test/asm/align-large.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
SECTION "You lost the game", ROM0[17]
|
||||||
0
test/asm/align-large.err
Normal file
0
test/asm/align-large.err
Normal file
0
test/asm/align-large.out
Normal file
0
test/asm/align-large.out
Normal file
27
test/asm/fragment-align-org-rev.asm
Normal file
27
test/asm/fragment-align-org-rev.asm
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
SECTION "Word", ROM0/*[5]*/
|
||||||
|
|
||||||
|
dw $78df
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[1]*/
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/,ALIGN[1,1]
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0[5]
|
||||||
0
test/asm/fragment-align-org-rev.err
Normal file
0
test/asm/fragment-align-org-rev.err
Normal file
0
test/asm/fragment-align-org-rev.out
Normal file
0
test/asm/fragment-align-org-rev.out
Normal file
1
test/asm/fragment-align-org-rev.out.bin
Normal file
1
test/asm/fragment-align-org-rev.out.bin
Normal file
@@ -0,0 +1 @@
|
|||||||
|
D@.{<7B>x
|
||||||
25
test/asm/fragment-align-org.asm
Normal file
25
test/asm/fragment-align-org.asm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0[1]
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION "Word", ROM0/*[6]*/
|
||||||
|
|
||||||
|
dw $78d5
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/,ALIGN[1]
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
0
test/asm/fragment-align-org.err
Normal file
0
test/asm/fragment-align-org.err
Normal file
0
test/asm/fragment-align-org.out
Normal file
0
test/asm/fragment-align-org.out
Normal file
1
test/asm/fragment-align-org.out.bin
Normal file
1
test/asm/fragment-align-org.out.bin
Normal file
@@ -0,0 +1 @@
|
|||||||
|
D@.{<7B>x
|
||||||
25
test/asm/fragment-align.asm
Normal file
25
test/asm/fragment-align.asm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[1]*/
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION "Word", ROM0/*[6]*/
|
||||||
|
|
||||||
|
dw $78d5
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/,ALIGN[1]
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2 ; Uh oh
|
||||||
3
test/asm/fragment-align.err
Normal file
3
test/asm/fragment-align.err
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
ERROR: fragment-align.asm(25):
|
||||||
|
Section's alignment fails required alignment (offset from section start = $0004)
|
||||||
|
error: Assembly aborted (1 errors)!
|
||||||
0
test/asm/fragment-align.out
Normal file
0
test/asm/fragment-align.out
Normal file
@@ -1,10 +1,4 @@
|
|||||||
ERROR: section-union.asm(37):
|
ERROR: section-union.asm(37):
|
||||||
Section "test" already declared as union section
|
Section already declared as union section
|
||||||
warning: section-union.asm(37): [-Wobsolete]
|
|
||||||
Concatenation of non-fragment sections is deprecated
|
|
||||||
ERROR: section-union.asm(37):
|
|
||||||
Section "test" already declared as fixed at $c000
|
|
||||||
ERROR: section-union.asm(37):
|
|
||||||
Section "test" already declared as aligned to 256 bytes
|
|
||||||
FATAL: section-union.asm(37):
|
FATAL: section-union.asm(37):
|
||||||
Cannot create section "test" (3 errors)
|
Cannot create section "test" (1 error)
|
||||||
|
|||||||
20
test/link/fragment-align/base-bad/a.asm
Normal file
20
test/link/fragment-align/base-bad/a.asm
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[1]*/
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION "Word", ROM0/*[6]*/
|
||||||
|
|
||||||
|
dw $78d5
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/,ALIGN[1]
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
5
test/link/fragment-align/base-bad/b.asm
Normal file
5
test/link/fragment-align/base-bad/b.asm
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2 ; Uh oh
|
||||||
1
test/link/fragment-align/base-bad/out.err
Normal file
1
test/link/fragment-align/base-bad/out.err
Normal file
@@ -0,0 +1 @@
|
|||||||
|
error: Section "Frag" is defined with conflicting 2-byte alignment (offset 1) and 4-byte alignment (offset 3)
|
||||||
20
test/link/fragment-align/base/a.asm
Normal file
20
test/link/fragment-align/base/a.asm
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[1]*/
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION "Word", ROM0/*[5]*/
|
||||||
|
|
||||||
|
dw $78d5
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/,ALIGN[1]
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
5
test/link/fragment-align/base/b.asm
Normal file
5
test/link/fragment-align/base/b.asm
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
0
test/link/fragment-align/base/out.err
Normal file
0
test/link/fragment-align/base/out.err
Normal file
1
test/link/fragment-align/base/out.gb
Normal file
1
test/link/fragment-align/base/out.gb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
D@.{<7B>x
|
||||||
8
test/link/fragment-align/org-bad/a.asm
Normal file
8
test/link/fragment-align/org-bad/a.asm
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0[0] ; Uh oh
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION "Word", ROM0/*[6]*/
|
||||||
|
|
||||||
|
dw $78d5
|
||||||
17
test/link/fragment-align/org-bad/b.asm
Normal file
17
test/link/fragment-align/org-bad/b.asm
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/,ALIGN[1]
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
1
test/link/fragment-align/org-bad/out.err
Normal file
1
test/link/fragment-align/org-bad/out.err
Normal file
@@ -0,0 +1 @@
|
|||||||
|
error: Section "Frag" is defined with conflicting address $0000 and 4-byte alignment (offset 2)
|
||||||
25
test/link/fragment-align/org-rev-bad/a.asm
Normal file
25
test/link/fragment-align/org-rev-bad/a.asm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
SECTION "Word", ROM0/*[5]*/
|
||||||
|
|
||||||
|
dw $78df
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[1]*/
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/,ALIGN[1,1]
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
2
test/link/fragment-align/org-rev-bad/b.asm
Normal file
2
test/link/fragment-align/org-rev-bad/b.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0[6] ; Uh oh
|
||||||
1
test/link/fragment-align/org-rev-bad/out.err
Normal file
1
test/link/fragment-align/org-rev-bad/out.err
Normal file
@@ -0,0 +1 @@
|
|||||||
|
error: Section "Frag" is defined with conflicting 4-byte alignment (offset 1) and address $0006
|
||||||
25
test/link/fragment-align/org-rev/a.asm
Normal file
25
test/link/fragment-align/org-rev/a.asm
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
SECTION "Word", ROM0/*[5]*/
|
||||||
|
|
||||||
|
dw $78df
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[1]*/
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/,ALIGN[1,1]
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
2
test/link/fragment-align/org-rev/b.asm
Normal file
2
test/link/fragment-align/org-rev/b.asm
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0[5]
|
||||||
0
test/link/fragment-align/org-rev/out.err
Normal file
0
test/link/fragment-align/org-rev/out.err
Normal file
1
test/link/fragment-align/org-rev/out.gb
Normal file
1
test/link/fragment-align/org-rev/out.gb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
D@.{<7B>x
|
||||||
8
test/link/fragment-align/org/a.asm
Normal file
8
test/link/fragment-align/org/a.asm
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0[1]
|
||||||
|
|
||||||
|
db $40
|
||||||
|
|
||||||
|
SECTION "Word", ROM0/*[6]*/
|
||||||
|
|
||||||
|
dw $78d5
|
||||||
17
test/link/fragment-align/org/b.asm
Normal file
17
test/link/fragment-align/org/b.asm
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[2]*/,ALIGN[1]
|
||||||
|
|
||||||
|
db $2e
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[3]*/
|
||||||
|
|
||||||
|
db $1f
|
||||||
|
|
||||||
|
SECTION "Byte", ROM0/*[0]*/
|
||||||
|
|
||||||
|
db $44
|
||||||
|
|
||||||
|
SECTION FRAGMENT "Frag", ROM0/*[4]*/
|
||||||
|
|
||||||
|
db $7b
|
||||||
|
align 2, 1
|
||||||
0
test/link/fragment-align/org/out.err
Normal file
0
test/link/fragment-align/org/out.err
Normal file
1
test/link/fragment-align/org/out.gb
Normal file
1
test/link/fragment-align/org/out.gb
Normal file
@@ -0,0 +1 @@
|
|||||||
|
D@.{<7B>x
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
error: Section "conflicting alignment" is defined with conflicting 4-byte alignment (offset 0) and address $cafe
|
error: Section "conflicting alignment" is defined with conflicting 4-byte alignment (offset 0) and address $cafe
|
||||||
---
|
---
|
||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Section "conflicting alignment" already declared as aligned to 4 bytes (offset 0)
|
Section already declared as aligned to 4 bytes (offset 0)
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "conflicting alignment" (1 errors)
|
Cannot create section "conflicting alignment" (1 error)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
error: Section "conflicting alignment" is defined with conflicting 8-byte alignment (offset 7) and 16-byte alignment (offset 14)
|
error: Section "conflicting alignment" is defined with conflicting 8-byte alignment (offset 7) and 16-byte alignment (offset 14)
|
||||||
---
|
---
|
||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Section "conflicting alignment" already declared with incompatible 3-byte alignment (offset 7)
|
Section already declared with incompatible 3-byte alignment (offset 7)
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "conflicting alignment" (1 errors)
|
Cannot create section "conflicting alignment" (1 error)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
error: Section "conflicting types" is defined with conflicting types HRAM and WRAM0
|
error: Section "conflicting types" is defined with conflicting types HRAM and WRAM0
|
||||||
---
|
---
|
||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Section "conflicting types" already exists but with type HRAM
|
Section already exists but with type HRAM
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "conflicting types" (1 errors)
|
Cannot create section "conflicting types" (1 error)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
error: Section "conflicting banks" is defined with conflicting banks 4 and 1
|
error: Section "conflicting banks" is defined with conflicting banks 4 and 1
|
||||||
---
|
---
|
||||||
ERROR: <stdin>(14):
|
ERROR: <stdin>(14):
|
||||||
Section "conflicting banks" already declared with different bank 4
|
Section already declared with different bank 4
|
||||||
FATAL: <stdin>(14):
|
FATAL: <stdin>(14):
|
||||||
Cannot create section "conflicting banks" (1 errors)
|
Cannot create section "conflicting banks" (1 error)
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ error: Section "overlaid data" is of type ROM0, which cannot be unionized
|
|||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Cannot declare ROM sections as UNION
|
Cannot declare ROM sections as UNION
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "overlaid data" (1 errors)
|
Cannot create section "overlaid data" (1 error)
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ error: Section "different data" is of type ROM0, which cannot be unionized
|
|||||||
ERROR: <stdin>(16):
|
ERROR: <stdin>(16):
|
||||||
Cannot declare ROM sections as UNION
|
Cannot declare ROM sections as UNION
|
||||||
FATAL: <stdin>(16):
|
FATAL: <stdin>(16):
|
||||||
Cannot create section "different data" (1 errors)
|
Cannot create section "different data" (1 error)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
error: Section "conflicting alignment" is defined with conflicting 8-byte alignment (offset 7) and 8-byte alignment (offset 6)
|
error: Section "conflicting alignment" is defined with conflicting 8-byte alignment (offset 7) and 8-byte alignment (offset 6)
|
||||||
---
|
---
|
||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Section "conflicting alignment" already declared with incompatible 3-byte alignment (offset 7)
|
Section already declared with incompatible 3-byte alignment (offset 7)
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "conflicting alignment" (1 errors)
|
Cannot create section "conflicting alignment" (1 error)
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ error: Section "different section sizes" is of type ROM0, which cannot be unioni
|
|||||||
ERROR: <stdin>(16):
|
ERROR: <stdin>(16):
|
||||||
Cannot declare ROM sections as UNION
|
Cannot declare ROM sections as UNION
|
||||||
FATAL: <stdin>(16):
|
FATAL: <stdin>(16):
|
||||||
Cannot create section "different section sizes" (1 errors)
|
Cannot create section "different section sizes" (1 error)
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ error: Section "different syntaxes" is of type ROM0, which cannot be unionized
|
|||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Cannot declare ROM sections as UNION
|
Cannot declare ROM sections as UNION
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "different syntaxes" (1 errors)
|
Cannot create section "different syntaxes" (1 error)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
error: Section "conflicting address" is defined with conflicting addresses $beef and $babe
|
error: Section "conflicting address" is defined with conflicting addresses $beef and $babe
|
||||||
---
|
---
|
||||||
ERROR: <stdin>(16):
|
ERROR: <stdin>(16):
|
||||||
Section "conflicting address" already declared as fixed at different address $beef
|
Section already declared as fixed at different address $beef
|
||||||
FATAL: <stdin>(16):
|
FATAL: <stdin>(16):
|
||||||
Cannot create section "conflicting address" (1 errors)
|
Cannot create section "conflicting address" (1 error)
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ error: Section "mutually-overlaid data" is of type ROM0, which cannot be unioniz
|
|||||||
ERROR: <stdin>(18):
|
ERROR: <stdin>(18):
|
||||||
Cannot declare ROM sections as UNION
|
Cannot declare ROM sections as UNION
|
||||||
FATAL: <stdin>(18):
|
FATAL: <stdin>(18):
|
||||||
Cannot create section "mutually-overlaid data" (1 errors)
|
Cannot create section "mutually-overlaid data" (1 error)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
export LC_ALL=C
|
export LC_ALL=C
|
||||||
|
set -o pipefail
|
||||||
|
|
||||||
otemp=$(mktemp)
|
otemp=$(mktemp)
|
||||||
gbtemp=$(mktemp)
|
gbtemp=$(mktemp)
|
||||||
@@ -13,16 +14,31 @@ bold=$(tput bold)
|
|||||||
resbold=$(tput sgr0)
|
resbold=$(tput sgr0)
|
||||||
red=$(tput setaf 1)
|
red=$(tput setaf 1)
|
||||||
rescolors=$(tput op)
|
rescolors=$(tput op)
|
||||||
|
|
||||||
tryDiff () {
|
tryDiff () {
|
||||||
diff -u --strip-trailing-cr $1 $2 || (echo "${bold}${red}${i%.asm}.out mismatch!${rescolors}${resbold}"; false)
|
if ! diff -u --strip-trailing-cr $1 $2; then
|
||||||
|
echo "${bold}${red}${i%.asm}.out mismatch!${rescolors}${resbold}"
|
||||||
|
false
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
tryCmp () {
|
tryCmp () {
|
||||||
cmp $1 $2 || (../../contrib/gbdiff.bash $1 $2; echo "${bold}${red}${i%.asm}.out.bin mismatch!${rescolors}${resbold}"; false)
|
if ! cmp $1 $2; then
|
||||||
|
../../contrib/gbdiff.bash $1 $2
|
||||||
|
echo "${bold}${red}${i%.asm}.out.bin mismatch!${rescolors}${resbold}"
|
||||||
|
false
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBASM=../../rgbasm
|
RGBASM=../../rgbasm
|
||||||
RGBLINK=../../rgblink
|
RGBLINK=../../rgblink
|
||||||
|
rgblink() {
|
||||||
|
out="$(env $RGBLINK "$@")" || return $?
|
||||||
|
if [[ -n "$out" ]]; then
|
||||||
|
echo "$bold${red}Linking shouldn't produce anything on stdout!$rescolors$resbold"
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
for i in *.asm; do
|
for i in *.asm; do
|
||||||
$RGBASM -o $otemp $i
|
$RGBASM -o $otemp $i
|
||||||
@@ -31,13 +47,13 @@ for i in *.asm; do
|
|||||||
ran_flag=
|
ran_flag=
|
||||||
for flag in '-d' '-t' '-w'; do
|
for flag in '-d' '-t' '-w'; do
|
||||||
if [ -f ${i%.asm}-no${flag}.out ]; then
|
if [ -f ${i%.asm}-no${flag}.out ]; then
|
||||||
$RGBLINK -o $gbtemp $otemp > $outtemp 2>&1
|
rgblink -o $gbtemp $otemp > $outtemp 2>&1
|
||||||
tryDiff ${i%.asm}-no${flag}.out $outtemp
|
tryDiff ${i%.asm}-no${flag}.out $outtemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
ran_flag=1
|
ran_flag=1
|
||||||
fi
|
fi
|
||||||
if [ -f ${i%.asm}${flag}.out ]; then
|
if [ -f ${i%.asm}${flag}.out ]; then
|
||||||
$RGBLINK ${flag} -o $gbtemp $otemp > $outtemp 2>&1
|
rgblink ${flag} -o $gbtemp $otemp > $outtemp 2>&1
|
||||||
tryDiff ${i%.asm}${flag}.out $outtemp
|
tryDiff ${i%.asm}${flag}.out $outtemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
ran_flag=1
|
ran_flag=1
|
||||||
@@ -49,7 +65,7 @@ for i in *.asm; do
|
|||||||
|
|
||||||
# Other tests have several linker scripts
|
# Other tests have several linker scripts
|
||||||
find . -name "${i%.asm}*.link" | while read script; do
|
find . -name "${i%.asm}*.link" | while read script; do
|
||||||
$RGBLINK -l $script -o $gbtemp $otemp > $outtemp 2>&1
|
rgblink -l $script -o $gbtemp $otemp > $outtemp 2>&1
|
||||||
tryDiff ${script%.link}.out $outtemp
|
tryDiff ${script%.link}.out $outtemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
ran_flag=1
|
ran_flag=1
|
||||||
@@ -59,7 +75,7 @@ for i in *.asm; do
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# The rest of the tests just links a file, and maybe checks the binary
|
# The rest of the tests just links a file, and maybe checks the binary
|
||||||
$RGBLINK -o $gbtemp $otemp > $outtemp 2>&1
|
rgblink -o $gbtemp $otemp > $outtemp 2>&1
|
||||||
if [ -f ${i%.asm}.out ]; then
|
if [ -f ${i%.asm}.out ]; then
|
||||||
tryDiff ${i%.asm}.out $outtemp
|
tryDiff ${i%.asm}.out $outtemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
@@ -75,41 +91,54 @@ done
|
|||||||
|
|
||||||
# These tests do their own thing
|
# These tests do their own thing
|
||||||
|
|
||||||
$RGBASM -o $otemp high-low/a.asm
|
|
||||||
$RGBLINK -o $gbtemp $otemp
|
|
||||||
$RGBASM -o $otemp high-low/b.asm
|
|
||||||
$RGBLINK -o $gbtemp2 $otemp
|
|
||||||
i="high-low.asm" tryCmp $gbtemp $gbtemp2
|
|
||||||
rc=$(($? || $rc))
|
|
||||||
|
|
||||||
$RGBASM -o $otemp bank-const/a.asm
|
$RGBASM -o $otemp bank-const/a.asm
|
||||||
$RGBASM -o $gbtemp2 bank-const/b.asm
|
$RGBASM -o $gbtemp2 bank-const/b.asm
|
||||||
$RGBLINK -o $gbtemp $gbtemp2 $otemp > $outtemp 2>&1
|
rgblink -o $gbtemp $gbtemp2 $otemp > $outtemp 2>&1
|
||||||
i="bank-const.asm" tryDiff bank-const/err.out $outtemp
|
i="bank-const.asm" tryDiff bank-const/err.out $outtemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
|
|
||||||
|
for i in fragment-align/*; do
|
||||||
|
$RGBASM -o $otemp $i/a.asm
|
||||||
|
$RGBASM -o $gbtemp2 $i/b.asm
|
||||||
|
rgblink -o $gbtemp $otemp $gbtemp2 2>$outtemp
|
||||||
|
tryDiff $i/out.err $outtemp
|
||||||
|
rc=$(($? || $rc))
|
||||||
|
if [[ -f $i/out.gb ]]; then
|
||||||
|
dd if=$gbtemp count=1 bs=$(printf %s $(wc -c < $i/out.gb)) > $otemp 2>/dev/null
|
||||||
|
tryCmp $i/out.gb $otemp
|
||||||
|
rc=$(($? || $rc))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
$RGBASM -o $otemp high-low/a.asm
|
||||||
|
rgblink -o $gbtemp $otemp
|
||||||
|
$RGBASM -o $otemp high-low/b.asm
|
||||||
|
rgblink -o $gbtemp2 $otemp
|
||||||
|
i="high-low.asm" tryCmp $gbtemp $gbtemp2
|
||||||
|
rc=$(($? || $rc))
|
||||||
|
|
||||||
$RGBASM -o $otemp section-union/good/a.asm
|
$RGBASM -o $otemp section-union/good/a.asm
|
||||||
$RGBASM -o $gbtemp2 section-union/good/b.asm
|
$RGBASM -o $gbtemp2 section-union/good/b.asm
|
||||||
$RGBLINK -o $gbtemp -l section-union/good/script.link $otemp $gbtemp2
|
rgblink -o $gbtemp -l section-union/good/script.link $otemp $gbtemp2
|
||||||
dd if=$gbtemp count=1 bs=$(printf %s $(wc -c < section-union/good/ref.out.bin)) > $otemp 2>/dev/null
|
dd if=$gbtemp count=1 bs=$(printf %s $(wc -c < section-union/good/ref.out.bin)) > $otemp 2>/dev/null
|
||||||
i="section-union/good.asm" tryCmp section-union/good/ref.out.bin $otemp
|
i="section-union/good.asm" tryCmp section-union/good/ref.out.bin $otemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
$RGBASM -o $otemp section-union/fragments/a.asm
|
$RGBASM -o $otemp section-union/fragments/a.asm
|
||||||
$RGBASM -o $gbtemp2 section-union/fragments/b.asm
|
$RGBASM -o $gbtemp2 section-union/fragments/b.asm
|
||||||
$RGBLINK -o $gbtemp $otemp $gbtemp2
|
rgblink -o $gbtemp $otemp $gbtemp2
|
||||||
dd if=$gbtemp count=1 bs=$(printf %s $(wc -c < section-union/fragments/ref.out.bin)) > $otemp 2>/dev/null
|
dd if=$gbtemp count=1 bs=$(printf %s $(wc -c < section-union/fragments/ref.out.bin)) > $otemp 2>/dev/null
|
||||||
i="section-union/fragments.asm" tryCmp section-union/fragments/ref.out.bin $otemp
|
i="section-union/fragments.asm" tryCmp section-union/fragments/ref.out.bin $otemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
for i in section-union/*.asm; do
|
for i in section-union/*.asm; do
|
||||||
$RGBASM -o $otemp $i
|
$RGBASM -o $otemp $i
|
||||||
$RGBASM -o $gbtemp2 $i -DSECOND
|
$RGBASM -o $gbtemp2 $i -DSECOND
|
||||||
if $RGBLINK $otemp $gbtemp2 > $outtemp 2>&1; then
|
if rgblink $otemp $gbtemp2 2>$outtemp; then
|
||||||
echo -e "${bold}${red}$i didn't fail to link!${rescolors}${resbold}"
|
echo -e "${bold}${red}$i didn't fail to link!${rescolors}${resbold}"
|
||||||
rc=1
|
rc=1
|
||||||
fi
|
fi
|
||||||
echo --- >> $outtemp
|
echo --- >> $outtemp
|
||||||
# Ensure RGBASM also errors out
|
# Ensure RGBASM also errors out
|
||||||
echo 'SECOND equs "1"' | cat $i - $i | $RGBASM - 2>> $outtemp
|
cat $i - $i <<<'SECOND equs "1"' | $RGBASM - 2>> $outtemp
|
||||||
tryDiff ${i%.asm}.out $outtemp
|
tryDiff ${i%.asm}.out $outtemp
|
||||||
rc=$(($? || $rc))
|
rc=$(($? || $rc))
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
warning: v1: VRAM bank 1 can't be used with option -d.
|
warning: v1: VRAM bank 1 can't be used with option -d
|
||||||
error: Sanity checks failed
|
error: Sanity checks failed
|
||||||
|
|||||||
Reference in New Issue
Block a user