diff --git a/src/asm/parser.y b/src/asm/parser.y index 0ae82123..52ac6097 100644 --- a/src/asm/parser.y +++ b/src/asm/parser.y @@ -1487,22 +1487,11 @@ sectattrs : %empty { $$.bank = -1; } | sectattrs T_COMMA T_OP_ALIGN T_LBRACK uconst T_RBRACK { - if ($5 > 16) - error("Alignment must be between 0 and 16, not %u\n", $5); - else - $$.alignment = $5; + $$.alignment = $5; } | sectattrs T_COMMA T_OP_ALIGN T_LBRACK uconst T_COMMA uconst T_RBRACK { - if ($5 > 16) { - error("Alignment must be between 0 and 16, not %u\n", $5); - } 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; - } + $$.alignment = $5; + $$.alignOfs = $7; } | sectattrs T_COMMA T_OP_BANK T_LBRACK uconst T_RBRACK { /* We cannot check the validity of this now */ diff --git a/src/asm/section.c b/src/asm/section.c index f96de32a..3a6b5ed2 100644 --- a/src/asm/section.c +++ b/src/asm/section.c @@ -1,4 +1,5 @@ +#include #include #include #include @@ -98,36 +99,199 @@ struct Section *out_FindSectionByName(const char *name) 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 */ -static struct Section *getSection(char const *name, enum SectionType type, - uint32_t org, struct SectionSpec const *attrs, - enum SectionModifier mod) +static struct Section *getSection(char const *name, enum SectionType type, uint32_t org, + struct SectionSpec const *attrs, enum SectionModifier mod) { -#define mask(align) ((1 << (align)) - 1) uint32_t bank = attrs->bank; uint8_t alignment = attrs->alignment; uint16_t alignOffset = attrs->alignOfs; + // First, validate parameters, and normalize them if applicable + if (bank != -1) { if (type != SECTTYPE_ROMX && type != SECTTYPE_VRAM && type != SECTTYPE_SRAM && type != SECTTYPE_WRAMX) error("BANK only allowed for ROMX, WRAMX, SRAM, or VRAM sections\n"); else if (bank < bankranges[type][0] || 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, 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) { - error("Alignment offset must not be greater than alignment (%" PRIu16 " < %u)\n", - alignOffset, 1U << alignment); + error("Alignment offset (%" PRIu16 ") must be smaller than alignment size (%u)\n", + alignOffset, 1U << alignment); 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 > 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 */ uint32_t mask = mask(alignment); @@ -139,128 +303,20 @@ static struct Section *getSection(char const *name, enum SectionType type, } else if (startaddr[type] & mask) { error("Section \"%s\"'s alignment cannot be attained in %s\n", 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) { - 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]; + // Check if another section exists with the same name; merge if yes, otherwise create one struct Section *sect = out_FindSectionByName(name); if (sect) { - unsigned int nbSectErrors = 0; -#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 + mergeSections(sect, type, org, bank, alignment, alignOffset, mod); return sect; } @@ -279,7 +335,6 @@ static struct Section *getSection(char const *name, enum SectionType type, sect->bank = bank; sect->align = alignment; sect->alignOfs = alignOffset; - sect->next = pSectionList; sect->patches = NULL; /* 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; } - /* - * Add the new section to the list - * at the beginning because order doesn't matter - */ + // Add the new section to the list (order doesn't matter) + sect->next = pSectionList; pSectionList = sect; return sect; -#undef mask } /* diff --git a/src/link/object.c b/src/link/object.c index d3fe99cd..dcc05824 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -349,6 +349,8 @@ static void readSection(FILE *file, struct Section *section, char const *fileNam section->bank = tmp; tryGetc(byte, file, "%s: Cannot read \"%s\"'s alignment: %s", fileName, section->name); + if (byte > 16) + byte = 16; section->isAlignFixed = byte != 0; section->alignMask = (1 << byte) - 1; tryReadlong(tmp, file, "%s: Cannot read \"%s\"'s alignment offset: %s", diff --git a/src/link/section.c b/src/link/section.c index 4dde6eff..1cbc9ab1 100644 --- a/src/link/section.c +++ b/src/link/section.c @@ -39,62 +39,123 @@ void sect_ForEach(void (*callback)(struct Section *, void *), void *arg) 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 (target->isAddressFixed) { 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); } else if (target->isAlignFixed) { 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, target->alignOfs, other->org); } target->isAddressFixed = true; target->org = other->org; + } else if (other->isAlignFixed) { if (target->isAddressFixed) { 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->alignMask + 1, other->alignOfs); } else if (target->isAlignFixed && (other->alignMask & target->alignOfs) != (target->alignMask & other->alignOfs)) { - 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)) { + 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; } } +} + +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 (!target->isBankFixed) { target->isBankFixed = true; target->bank = other->bank; } else if (target->bank != other->bank) { - errx(1, "Section \"%s\" is defined with conflicting banks %" PRIu32 " and %" PRIu32, - other->name, target->bank, other->bank); + errx(1, "Section \"%s\" is defined with conflicting banks %" PRIu32 " and %" + PRIu32, other->name, target->bank, other->bank); } } switch (mod) { case SECTION_UNION: + checkSectUnionCompat(target, other); if (other->size > target->size) target->size = other->size; break; case SECTION_FRAGMENT: + checkFragmentCompat(target, other); target->size += other->size; other->offset = target->size - other->size; 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); if (is32kMode && section->type == SECTTYPE_ROMX) { 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); else section->type = SECTTYPE_ROM0; } if (isWRA0Mode && section->type == SECTTYPE_WRAMX) { 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); else section->type = SECTTYPE_WRAMX; } 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); /* @@ -191,17 +252,13 @@ static void doSanityChecks(struct Section *section, void *ptr) section->isAlignFixed = false; /* Too large an alignment may not be satisfiable */ - if (section->isAlignFixed - && (section->alignMask & startaddr[section->type])) - fail("%s: %s sections cannot be aligned to $%" PRIx16 " bytes", - section->name, typeNames[section->type], - section->alignMask + 1); + if (section->isAlignFixed && (section->alignMask & startaddr[section->type])) + fail("%s: %s sections cannot be aligned to $%04" PRIx16 " bytes", + section->name, typeNames[section->type], section->alignMask + 1); - uint32_t minbank = bankranges[section->type][0], - maxbank = bankranges[section->type][1]; + uint32_t minbank = bankranges[section->type][0], maxbank = bankranges[section->type][1]; - if (section->isBankFixed && section->bank < minbank - && section->bank > maxbank) + if (section->isBankFixed && section->bank < minbank && section->bank > 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 between %" PRIu32 " and %" PRIu32, @@ -219,35 +276,26 @@ static void doSanityChecks(struct Section *section, void *ptr) section->isBankFixed = true; } - if (section->isAlignFixed) { - enum SectionType type = section->type; - + if (section->isAddressFixed) { /* It doesn't make sense to have both org and alignment set */ - if (section->isAddressFixed) { - if (section->org & section->alignMask) + if (section->isAlignFixed) { + if ((section->org & section->alignMask) != section->alignOfs) fail("Section \"%s\"'s fixed address doesn't match its alignment", section->name); 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 */ if (section->org < startaddr[section->type] || section->org > endaddr(section->type)) - fail("Section \"%s\"'s fixed address %#" PRIx16 " is outside of range [%#" PRIx16 "; %#" PRIx16 "]", - section->name, section->org, + fail("Section \"%s\"'s fixed address %#" PRIx16 " is outside of range [%#" + PRIx16 "; %#" PRIx16 "]", section->name, section->org, startaddr[section->type], endaddr(section->type)); if (section->org + section->size > endaddr(section->type) + 1) - fail("Section \"%s\"'s end address %#" PRIx16 " is greater than last address %#" PRIx16, - section->name, section->org + section->size, - endaddr(section->type) + 1); + fail("Section \"%s\"'s end address %#" PRIx16 + " is greater than last address %#" PRIx16, section->name, + section->org + section->size, endaddr(section->type) + 1); } #undef fail diff --git a/test/asm/align-16.asm b/test/asm/align-16.asm new file mode 100644 index 00000000..3474dbfe --- /dev/null +++ b/test/asm/align-16.asm @@ -0,0 +1,8 @@ + +SECTION "Byte", ROM0 + + db 2 + +SECTION "ROM0", ROM0, ALIGN[16] + + db 1 diff --git a/test/asm/align-16.err b/test/asm/align-16.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/align-16.out b/test/asm/align-16.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/align-16.out.bin b/test/asm/align-16.out.bin new file mode 100644 index 00000000..71bd63e6 --- /dev/null +++ b/test/asm/align-16.out.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/asm/align-large-ofs.asm b/test/asm/align-large-ofs.asm new file mode 100644 index 00000000..19653d13 --- /dev/null +++ b/test/asm/align-large-ofs.asm @@ -0,0 +1,2 @@ + +SECTION "Tesst", ROM0, ALIGN[1,2] diff --git a/test/asm/align-large-ofs.err b/test/asm/align-large-ofs.err new file mode 100644 index 00000000..fa1951fd --- /dev/null +++ b/test/asm/align-large-ofs.err @@ -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)! diff --git a/test/asm/align-large-ofs.out b/test/asm/align-large-ofs.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/align-large.asm b/test/asm/align-large.asm new file mode 100644 index 00000000..748f1d52 --- /dev/null +++ b/test/asm/align-large.asm @@ -0,0 +1,2 @@ + +SECTION "You lost the game", ROM0[17] diff --git a/test/asm/align-large.err b/test/asm/align-large.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/align-large.out b/test/asm/align-large.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/fragment-align-org-rev.asm b/test/asm/fragment-align-org-rev.asm new file mode 100644 index 00000000..47fc2517 --- /dev/null +++ b/test/asm/fragment-align-org-rev.asm @@ -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] diff --git a/test/asm/fragment-align-org-rev.err b/test/asm/fragment-align-org-rev.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/fragment-align-org-rev.out b/test/asm/fragment-align-org-rev.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/fragment-align-org-rev.out.bin b/test/asm/fragment-align-org-rev.out.bin new file mode 100644 index 00000000..fa7fdafe --- /dev/null +++ b/test/asm/fragment-align-org-rev.out.bin @@ -0,0 +1 @@ +D@.{ßx \ No newline at end of file diff --git a/test/asm/fragment-align-org.asm b/test/asm/fragment-align-org.asm new file mode 100644 index 00000000..66a8599e --- /dev/null +++ b/test/asm/fragment-align-org.asm @@ -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 diff --git a/test/asm/fragment-align-org.err b/test/asm/fragment-align-org.err new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/fragment-align-org.out b/test/asm/fragment-align-org.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/fragment-align-org.out.bin b/test/asm/fragment-align-org.out.bin new file mode 100644 index 00000000..8a603dc3 --- /dev/null +++ b/test/asm/fragment-align-org.out.bin @@ -0,0 +1 @@ +D@.{Õx \ No newline at end of file diff --git a/test/asm/fragment-align.asm b/test/asm/fragment-align.asm new file mode 100644 index 00000000..21b1452b --- /dev/null +++ b/test/asm/fragment-align.asm @@ -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 diff --git a/test/asm/fragment-align.err b/test/asm/fragment-align.err new file mode 100644 index 00000000..cd9fa202 --- /dev/null +++ b/test/asm/fragment-align.err @@ -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)! diff --git a/test/asm/fragment-align.out b/test/asm/fragment-align.out new file mode 100644 index 00000000..e69de29b diff --git a/test/asm/section-union.err b/test/asm/section-union.err index c0c2921f..d5dce270 100644 --- a/test/asm/section-union.err +++ b/test/asm/section-union.err @@ -1,10 +1,4 @@ ERROR: section-union.asm(37): - Section "test" 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 + Section already declared as union section FATAL: section-union.asm(37): - Cannot create section "test" (3 errors) + Cannot create section "test" (1 error) diff --git a/test/link/fragment-align/base-bad/a.asm b/test/link/fragment-align/base-bad/a.asm new file mode 100644 index 00000000..61dd13fc --- /dev/null +++ b/test/link/fragment-align/base-bad/a.asm @@ -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 diff --git a/test/link/fragment-align/base-bad/b.asm b/test/link/fragment-align/base-bad/b.asm new file mode 100644 index 00000000..9d61cc4f --- /dev/null +++ b/test/link/fragment-align/base-bad/b.asm @@ -0,0 +1,5 @@ + +SECTION FRAGMENT "Frag", ROM0/*[4]*/ + + db $7b + align 2 ; Uh oh diff --git a/test/link/fragment-align/base-bad/out.err b/test/link/fragment-align/base-bad/out.err new file mode 100644 index 00000000..b7856ac4 --- /dev/null +++ b/test/link/fragment-align/base-bad/out.err @@ -0,0 +1 @@ +error: Section "Frag" is defined with conflicting 2-byte alignment (offset 1) and 4-byte alignment (offset 3) diff --git a/test/link/fragment-align/base/a.asm b/test/link/fragment-align/base/a.asm new file mode 100644 index 00000000..35f850e4 --- /dev/null +++ b/test/link/fragment-align/base/a.asm @@ -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 diff --git a/test/link/fragment-align/base/b.asm b/test/link/fragment-align/base/b.asm new file mode 100644 index 00000000..998771df --- /dev/null +++ b/test/link/fragment-align/base/b.asm @@ -0,0 +1,5 @@ + +SECTION FRAGMENT "Frag", ROM0/*[4]*/ + + db $7b + align 2, 1 diff --git a/test/link/fragment-align/base/out.err b/test/link/fragment-align/base/out.err new file mode 100644 index 00000000..e69de29b diff --git a/test/link/fragment-align/base/out.gb b/test/link/fragment-align/base/out.gb new file mode 100644 index 00000000..8a603dc3 --- /dev/null +++ b/test/link/fragment-align/base/out.gb @@ -0,0 +1 @@ +D@.{Õx \ No newline at end of file diff --git a/test/link/fragment-align/org-bad/a.asm b/test/link/fragment-align/org-bad/a.asm new file mode 100644 index 00000000..33f3251c --- /dev/null +++ b/test/link/fragment-align/org-bad/a.asm @@ -0,0 +1,8 @@ + +SECTION FRAGMENT "Frag", ROM0[0] ; Uh oh + + db $40 + +SECTION "Word", ROM0/*[6]*/ + + dw $78d5 diff --git a/test/link/fragment-align/org-bad/b.asm b/test/link/fragment-align/org-bad/b.asm new file mode 100644 index 00000000..c1d7baa0 --- /dev/null +++ b/test/link/fragment-align/org-bad/b.asm @@ -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 diff --git a/test/link/fragment-align/org-bad/out.err b/test/link/fragment-align/org-bad/out.err new file mode 100644 index 00000000..5618077d --- /dev/null +++ b/test/link/fragment-align/org-bad/out.err @@ -0,0 +1 @@ +error: Section "Frag" is defined with conflicting address $0000 and 4-byte alignment (offset 2) diff --git a/test/link/fragment-align/org-rev-bad/a.asm b/test/link/fragment-align/org-rev-bad/a.asm new file mode 100644 index 00000000..605b2438 --- /dev/null +++ b/test/link/fragment-align/org-rev-bad/a.asm @@ -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 diff --git a/test/link/fragment-align/org-rev-bad/b.asm b/test/link/fragment-align/org-rev-bad/b.asm new file mode 100644 index 00000000..315b764a --- /dev/null +++ b/test/link/fragment-align/org-rev-bad/b.asm @@ -0,0 +1,2 @@ + +SECTION FRAGMENT "Frag", ROM0[6] ; Uh oh diff --git a/test/link/fragment-align/org-rev-bad/out.err b/test/link/fragment-align/org-rev-bad/out.err new file mode 100644 index 00000000..3c284d29 --- /dev/null +++ b/test/link/fragment-align/org-rev-bad/out.err @@ -0,0 +1 @@ +error: Section "Frag" is defined with conflicting 4-byte alignment (offset 1) and address $0006 diff --git a/test/link/fragment-align/org-rev/a.asm b/test/link/fragment-align/org-rev/a.asm new file mode 100644 index 00000000..605b2438 --- /dev/null +++ b/test/link/fragment-align/org-rev/a.asm @@ -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 diff --git a/test/link/fragment-align/org-rev/b.asm b/test/link/fragment-align/org-rev/b.asm new file mode 100644 index 00000000..70fff8d2 --- /dev/null +++ b/test/link/fragment-align/org-rev/b.asm @@ -0,0 +1,2 @@ + +SECTION FRAGMENT "Frag", ROM0[5] diff --git a/test/link/fragment-align/org-rev/out.err b/test/link/fragment-align/org-rev/out.err new file mode 100644 index 00000000..e69de29b diff --git a/test/link/fragment-align/org-rev/out.gb b/test/link/fragment-align/org-rev/out.gb new file mode 100644 index 00000000..fa7fdafe --- /dev/null +++ b/test/link/fragment-align/org-rev/out.gb @@ -0,0 +1 @@ +D@.{ßx \ No newline at end of file diff --git a/test/link/fragment-align/org/a.asm b/test/link/fragment-align/org/a.asm new file mode 100644 index 00000000..21a1eae3 --- /dev/null +++ b/test/link/fragment-align/org/a.asm @@ -0,0 +1,8 @@ + +SECTION FRAGMENT "Frag", ROM0[1] + + db $40 + +SECTION "Word", ROM0/*[6]*/ + + dw $78d5 diff --git a/test/link/fragment-align/org/b.asm b/test/link/fragment-align/org/b.asm new file mode 100644 index 00000000..c1d7baa0 --- /dev/null +++ b/test/link/fragment-align/org/b.asm @@ -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 diff --git a/test/link/fragment-align/org/out.err b/test/link/fragment-align/org/out.err new file mode 100644 index 00000000..e69de29b diff --git a/test/link/fragment-align/org/out.gb b/test/link/fragment-align/org/out.gb new file mode 100644 index 00000000..8a603dc3 --- /dev/null +++ b/test/link/fragment-align/org/out.gb @@ -0,0 +1 @@ +D@.{Õx \ No newline at end of file diff --git a/test/link/section-union/align-conflict.out b/test/link/section-union/align-conflict.out index 0a9a98eb..3c76cee4 100644 --- a/test/link/section-union/align-conflict.out +++ b/test/link/section-union/align-conflict.out @@ -1,6 +1,6 @@ error: Section "conflicting alignment" is defined with conflicting 4-byte alignment (offset 0) and address $cafe --- ERROR: (18): - Section "conflicting alignment" already declared as aligned to 4 bytes (offset 0) + Section already declared as aligned to 4 bytes (offset 0) FATAL: (18): - Cannot create section "conflicting alignment" (1 errors) + Cannot create section "conflicting alignment" (1 error) diff --git a/test/link/section-union/align-ofs-conflict.out b/test/link/section-union/align-ofs-conflict.out index 6a545f34..73eaf453 100644 --- a/test/link/section-union/align-ofs-conflict.out +++ b/test/link/section-union/align-ofs-conflict.out @@ -1,6 +1,6 @@ error: Section "conflicting alignment" is defined with conflicting 8-byte alignment (offset 7) and 16-byte alignment (offset 14) --- ERROR: (18): - Section "conflicting alignment" already declared with incompatible 3-byte alignment (offset 7) + Section already declared with incompatible 3-byte alignment (offset 7) FATAL: (18): - Cannot create section "conflicting alignment" (1 errors) + Cannot create section "conflicting alignment" (1 error) diff --git a/test/link/section-union/bad-types.out b/test/link/section-union/bad-types.out index 1fcd01a1..c08a50fa 100644 --- a/test/link/section-union/bad-types.out +++ b/test/link/section-union/bad-types.out @@ -1,6 +1,6 @@ error: Section "conflicting types" is defined with conflicting types HRAM and WRAM0 --- ERROR: (18): - Section "conflicting types" already exists but with type HRAM + Section already exists but with type HRAM FATAL: (18): - Cannot create section "conflicting types" (1 errors) + Cannot create section "conflicting types" (1 error) diff --git a/test/link/section-union/bank-conflict.out b/test/link/section-union/bank-conflict.out index 2d16cff8..594cf47a 100644 --- a/test/link/section-union/bank-conflict.out +++ b/test/link/section-union/bank-conflict.out @@ -1,6 +1,6 @@ error: Section "conflicting banks" is defined with conflicting banks 4 and 1 --- ERROR: (14): - Section "conflicting banks" already declared with different bank 4 + Section already declared with different bank 4 FATAL: (14): - Cannot create section "conflicting banks" (1 errors) + Cannot create section "conflicting banks" (1 error) diff --git a/test/link/section-union/data-overlay.out b/test/link/section-union/data-overlay.out index d504ce95..834c1976 100644 --- a/test/link/section-union/data-overlay.out +++ b/test/link/section-union/data-overlay.out @@ -3,4 +3,4 @@ error: Section "overlaid data" is of type ROM0, which cannot be unionized ERROR: (18): Cannot declare ROM sections as UNION FATAL: (18): - Cannot create section "overlaid data" (1 errors) + Cannot create section "overlaid data" (1 error) diff --git a/test/link/section-union/different-data.out b/test/link/section-union/different-data.out index 4357cd59..8fe52c62 100644 --- a/test/link/section-union/different-data.out +++ b/test/link/section-union/different-data.out @@ -3,4 +3,4 @@ error: Section "different data" is of type ROM0, which cannot be unionized ERROR: (16): Cannot declare ROM sections as UNION FATAL: (16): - Cannot create section "different data" (1 errors) + Cannot create section "different data" (1 error) diff --git a/test/link/section-union/different-ofs.out b/test/link/section-union/different-ofs.out index ee86d285..ab9f0f79 100644 --- a/test/link/section-union/different-ofs.out +++ b/test/link/section-union/different-ofs.out @@ -1,6 +1,6 @@ error: Section "conflicting alignment" is defined with conflicting 8-byte alignment (offset 7) and 8-byte alignment (offset 6) --- ERROR: (18): - Section "conflicting alignment" already declared with incompatible 3-byte alignment (offset 7) + Section already declared with incompatible 3-byte alignment (offset 7) FATAL: (18): - Cannot create section "conflicting alignment" (1 errors) + Cannot create section "conflicting alignment" (1 error) diff --git a/test/link/section-union/different-size.out b/test/link/section-union/different-size.out index 16089d5e..747d263f 100644 --- a/test/link/section-union/different-size.out +++ b/test/link/section-union/different-size.out @@ -3,4 +3,4 @@ error: Section "different section sizes" is of type ROM0, which cannot be unioni ERROR: (16): Cannot declare ROM sections as UNION FATAL: (16): - Cannot create section "different section sizes" (1 errors) + Cannot create section "different section sizes" (1 error) diff --git a/test/link/section-union/different-syntaxes.out b/test/link/section-union/different-syntaxes.out index 8e5b8084..3e83dd6f 100644 --- a/test/link/section-union/different-syntaxes.out +++ b/test/link/section-union/different-syntaxes.out @@ -3,4 +3,4 @@ error: Section "different syntaxes" is of type ROM0, which cannot be unionized ERROR: (18): Cannot declare ROM sections as UNION FATAL: (18): - Cannot create section "different syntaxes" (1 errors) + Cannot create section "different syntaxes" (1 error) diff --git a/test/link/section-union/org-conflict.out b/test/link/section-union/org-conflict.out index 7c0140da..13dfcae4 100644 --- a/test/link/section-union/org-conflict.out +++ b/test/link/section-union/org-conflict.out @@ -1,6 +1,6 @@ error: Section "conflicting address" is defined with conflicting addresses $beef and $babe --- ERROR: (16): - Section "conflicting address" already declared as fixed at different address $beef + Section already declared as fixed at different address $beef FATAL: (16): - Cannot create section "conflicting address" (1 errors) + Cannot create section "conflicting address" (1 error) diff --git a/test/link/section-union/split-data.out b/test/link/section-union/split-data.out index 8bd67193..f5821fd6 100644 --- a/test/link/section-union/split-data.out +++ b/test/link/section-union/split-data.out @@ -3,4 +3,4 @@ error: Section "mutually-overlaid data" is of type ROM0, which cannot be unioniz ERROR: (18): Cannot declare ROM sections as UNION FATAL: (18): - Cannot create section "mutually-overlaid data" (1 errors) + Cannot create section "mutually-overlaid data" (1 error) diff --git a/test/link/test.sh b/test/link/test.sh index 45fb5321..7b1abf77 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -1,5 +1,6 @@ -#!/bin/sh +#!/bin/bash export LC_ALL=C +set -o pipefail otemp=$(mktemp) gbtemp=$(mktemp) @@ -13,16 +14,31 @@ bold=$(tput bold) resbold=$(tput sgr0) red=$(tput setaf 1) rescolors=$(tput op) + 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 () { - 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 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 $RGBASM -o $otemp $i @@ -31,13 +47,13 @@ for i in *.asm; do ran_flag= for flag in '-d' '-t' '-w'; do 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 rc=$(($? || $rc)) ran_flag=1 fi 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 rc=$(($? || $rc)) ran_flag=1 @@ -49,7 +65,7 @@ for i in *.asm; do # Other tests have several linker scripts 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 rc=$(($? || $rc)) ran_flag=1 @@ -59,7 +75,7 @@ for i in *.asm; do fi # 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 tryDiff ${i%.asm}.out $outtemp rc=$(($? || $rc)) @@ -75,41 +91,54 @@ done # 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 $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 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 $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 i="section-union/good.asm" tryCmp section-union/good/ref.out.bin $otemp rc=$(($? || $rc)) $RGBASM -o $otemp section-union/fragments/a.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 i="section-union/fragments.asm" tryCmp section-union/fragments/ref.out.bin $otemp rc=$(($? || $rc)) for i in section-union/*.asm; do $RGBASM -o $otemp $i $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}" rc=1 fi echo --- >> $outtemp # 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 rc=$(($? || $rc)) done diff --git a/test/link/vram-fixed-dmg-mode-d.out b/test/link/vram-fixed-dmg-mode-d.out index effbd5ba..16c50329 100644 --- a/test/link/vram-fixed-dmg-mode-d.out +++ b/test/link/vram-fixed-dmg-mode-d.out @@ -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