diff --git a/src/asm/section.cpp b/src/asm/section.cpp index b9e34233..b44f21f8 100644 --- a/src/asm/section.cpp +++ b/src/asm/section.cpp @@ -583,30 +583,33 @@ void sect_AlignPC(uint8_t alignment, uint16_t offset) { actualOffset ); } - } else if (uint32_t actualOffset = - ((sect->alignOfs + curOffset) % (1u << sect->align)) % alignSize; - sect->align != 0 && actualOffset != offset) { - error( - "Section is misaligned ($%04" PRIx32 " bytes into the section, expected ALIGN[%" PRIu32 - ", %" PRIu32 "], got ALIGN[%" PRIu32 ", %" PRIu32 "])\n", - curOffset, - alignment, - offset, - alignment, - actualOffset - ); - } else if (alignment >= 16) { - // Treat an alignment large enough as fixing the address. - // Note that this also ensures that a section's alignment never becomes 16 or greater. - if (alignment > 16) { - error("Alignment must be between 0 and 16, not %u\n", alignment); + } else { + if (uint32_t actualOffset = (sect->alignOfs + curOffset) % alignSize, + sectAlignSize = 1 << sect->align; + sect->align != 0 && actualOffset % sectAlignSize != offset % sectAlignSize) { + error( + "Section is misaligned ($%04" PRIx32 + " bytes into the section, expected ALIGN[%" PRIu32 ", %" PRIu32 + "], got ALIGN[%" PRIu32 ", %" PRIu32 "])\n", + curOffset, + alignment, + offset, + alignment, + actualOffset + ); + } else if (alignment >= 16) { + // Treat an alignment large enough as fixing the address. + // Note that this also ensures that a section's alignment never becomes 16 or greater. + if (alignment > 16) { + error("Alignment must be between 0 and 16, not %u\n", alignment); + } + sect->align = 0; // Reset the alignment, since we're fixing the address. + sect->org = offset - curOffset; + } else if (alignment > sect->align) { + sect->align = alignment; + // We need `(sect->alignOfs + curOffset) % alignSize == offset` + sect->alignOfs = (offset - curOffset) % alignSize; } - sect->align = 0; // Reset the alignment, since we're fixing the address. - sect->org = offset - curOffset; - } else if (alignment > sect->align) { - sect->align = alignment; - // We need `(sect->alignOfs + curOffset) % alignSize == offset` - sect->alignOfs = (offset - curOffset) % alignSize; } } diff --git a/test/asm/align-increasing.asm b/test/asm/align-increasing.asm new file mode 100644 index 00000000..e97e311c --- /dev/null +++ b/test/asm/align-increasing.asm @@ -0,0 +1,15 @@ +SECTION "test1", ROM0 +align 4 ; PC = $xxx0 +dw $0123 +align 4, 2 ; PC = $xxx2 +ds align [8, $C2] ; PC = $xxC2 (ds 0) +align 8, $C2 ; PC = $xxC2 +dw $4567 + +SECTION "test2", ROM0[$01C0] +align 4 ; PC = $01C0 +dw $89ab +align 4, 2 ; PC = $01C2 +ds align [8, $C2] ; PC = $01C2 (ds 0) +align 8, $C2 ; PC = $01C2 +dw $cdef diff --git a/test/asm/align-increasing.out.bin b/test/asm/align-increasing.out.bin new file mode 100644 index 00000000..0b0d4f70 Binary files /dev/null and b/test/asm/align-increasing.out.bin differ