diff --git a/src/link/assign.cpp b/src/link/assign.cpp index 4c5f51c4..c7485924 100644 --- a/src/link/assign.cpp +++ b/src/link/assign.cpp @@ -114,25 +114,25 @@ static bool isLocationSuitable(struct Section const *section, static struct FreeSpace *getPlacement(struct Section const *section, struct MemoryLocation *location) { - static uint16_t curScrambleROM = 1; - static uint8_t curScrambleWRAM = 1; - static uint8_t curScrambleSRAM = 1; + static uint16_t curScrambleROM = 0; + static uint8_t curScrambleWRAM = 0; + static int8_t curScrambleSRAM = 0; // Determine which bank we should start searching in if (section->isBankFixed) { location->bank = section->bank; } else if (scrambleROMX && section->type == SECTTYPE_ROMX) { - location->bank = curScrambleROM++; - if (curScrambleROM > scrambleROMX) - curScrambleROM = 1; + if (curScrambleROM < 1) + curScrambleROM = scrambleROMX; + location->bank = curScrambleROM--; } else if (scrambleWRAMX && section->type == SECTTYPE_WRAMX) { - location->bank = curScrambleWRAM++; - if (curScrambleWRAM > scrambleWRAMX) - curScrambleWRAM = 1; + if (curScrambleWRAM < 1) + curScrambleWRAM = scrambleWRAMX; + location->bank = curScrambleWRAM--; } else if (scrambleSRAM && section->type == SECTTYPE_SRAM) { - location->bank = curScrambleSRAM++; - if (curScrambleSRAM > scrambleSRAM) - curScrambleSRAM = 0; + if (curScrambleSRAM < 0) + curScrambleSRAM = scrambleSRAM; + location->bank = curScrambleSRAM--; } else { location->bank = sectionTypeInfo[section->type].firstBank; } @@ -168,8 +168,7 @@ static struct FreeSpace *getPlacement(struct Section const *section, // Ensure we're there (e.g. on first check) location->address &= ~section->alignMask; // Go to next align boundary and add offset - location->address += section->alignMask + 1 - + section->alignOfs; + location->address += section->alignMask + 1 + section->alignOfs; } else { // Any location is fine, so, next free block space = space->next; @@ -179,20 +178,43 @@ static struct FreeSpace *getPlacement(struct Section const *section, // If that location is past the current block's end, // go forwards until that is no longer the case. - while (space && location->address >= - space->address + space->size) + while (space && location->address >= space->address + space->size) space = space->next; // Try again with the new location/free space combo } - if (section->isBankFixed) + // Try again in the next bank, if one is available. + // Try scrambled banks in descending order until no bank in the scrambled range is available. + // Otherwise, try in ascending order. + if (section->isBankFixed) { return NULL; - - // Try again in the next bank - location->bank++; - if (location->bank > sectionTypeInfo[section->type].lastBank) + } else if (scrambleROMX && section->type == SECTTYPE_ROMX && location->bank <= scrambleROMX) { + if (location->bank > sectionTypeInfo[section->type].firstBank) + location->bank--; + else if (scrambleROMX < sectionTypeInfo[section->type].lastBank) + location->bank = scrambleROMX + 1; + else + return NULL; + } else if (scrambleWRAMX && section->type == SECTTYPE_WRAMX && location->bank <= scrambleWRAMX) { + if (location->bank > sectionTypeInfo[section->type].firstBank) + location->bank--; + else if (scrambleWRAMX < sectionTypeInfo[section->type].lastBank) + location->bank = scrambleWRAMX + 1; + else + return NULL; + } else if (scrambleSRAM && section->type == SECTTYPE_SRAM && location->bank <= scrambleSRAM) { + if (location->bank > sectionTypeInfo[section->type].firstBank) + location->bank--; + else if (scrambleSRAM < sectionTypeInfo[section->type].lastBank) + location->bank = scrambleSRAM + 1; + else + return NULL; + } else if (location->bank < sectionTypeInfo[section->type].lastBank) { + location->bank++; + } else { return NULL; + } #undef BANK_INDEX } } diff --git a/test/asm/test.sh b/test/asm/test.sh index bbae18b2..27d40358 100755 --- a/test/asm/test.sh +++ b/test/asm/test.sh @@ -122,7 +122,7 @@ for i in *.asm; do desired_binname=${i%.asm}.out.bin if [ -f "$desired_binname" ]; then "$RGBLINK" -o "$gb" "$o" - rom_size=$(wc -c < "$desired_binname") + rom_size=$(printf %s $(wc -c <"$desired_binname")) dd if="$gb" count=1 bs="$rom_size" >"$output" 2>/dev/null tryCmp "$desired_binname" "$output" gb (( our_rc = our_rc || $? )) diff --git a/test/link/scramble-romx/a.asm b/test/link/scramble-romx/a.asm new file mode 100644 index 00000000..b9647076 --- /dev/null +++ b/test/link/scramble-romx/a.asm @@ -0,0 +1,5 @@ +SECTION "fixed", ROMX, BANK[3] +ds $4000, 1 + +SECTION "floating", ROMX +db 2 diff --git a/test/link/scramble-romx/out.err b/test/link/scramble-romx/out.err new file mode 100644 index 00000000..e69de29b diff --git a/test/link/test.sh b/test/link/test.sh index 4abd7268..01e1b631 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -41,7 +41,7 @@ tryCmp () { fi } tryCmpRom () { - # `printf` lets us keep only the first returned word. + # `printf` lets us keep only the first returned word from `wc`. rom_size=$(printf %s $(wc -c <"$1")) dd if="$gbtemp" count=1 bs="$rom_size" >"$otemp" 2>/dev/null tryCmp "$1" "$otemp" @@ -146,6 +146,17 @@ tryDiff overlay/out.err "$outtemp" tryCmp overlay/out.gb "$gbtemp" (( rc = rc || $? )) +i="scramble-romx.asm" +startTest +"$RGBASM" -o "$otemp" scramble-romx/a.asm +rgblinkQuiet -o "$gbtemp" -S romx=3 "$otemp" >"$outtemp" 2>&1 +tryDiff scramble-romx/out.err "$outtemp" +(( rc = rc || $? )) +# This test does not compare its exact output with 'tryCmpRom' because no scrambling order is guaranteed +rom_size=$(printf %s $(wc -c <"$gbtemp")) +test "$rom_size" = 65536 # Check for exactly 3 ROMX banks +(( rc = rc || $? )) + i="section-fragment/jr-offset.asm" startTest "$RGBASM" -o "$otemp" section-fragment/jr-offset/a.asm