WonderfulToolchain / wf-issues

Issue tracker for the Wonderful toolchain.
1 stars 0 forks source link

[target/wswan] Compiler bug: Not restoring data segment register value in specific nested for loops with optimizations enabled #15

Open RSDuck opened 1 year ago

RSDuck commented 1 year ago

There are probably multiple bugs contained here, but they all together create a wonderful mess.

sprites.zip

See src/main.c. In line 25 there are three different ways for defining the array SwanOffset.

// this gives the intended effect (doesn't work with bitfields):
int SwanOffset[NUM_SWANS] = {0, 8, 16, 48, 10};

grafik

// all the swans end up on one place (doesn't work with bitfields):
const int SwanOffset[NUM_SWANS] = {0, 8, 16, 48, 10};

grafik

What happens when bitfields are used with the two preceeding ones: grafik

// there is a full Swan visible, but also a white tile (only the first iteration works?):
// (which likely didn't get the right palette assigned)
// works with both bitfields and manual assignment
const int __wf_rom SwanOffset[NUM_SWANS] = {0, 8, 16, 48, 10};

grafik

In line 79 it is accessed, but independently from that the behaviour changes based on whether the attr field of the sprite struct is set using bitfields or manually.

    // Setup the Swan sprites
    for (int swan = 0; swan < NUM_SWANS; swan++)
    {
        for (int tile = 0; tile < 4; tile++) {
            sprites[swan*4+tile].x = (tile & 1) * 8;
            sprites[swan*4+tile].y = (tile >> 1) * 8 + SwanOffset[swan];
            // When bitfields are used nothing works
            // (there is only one white square, so not even the palette is properly assigned)
            //sprites[swan*4+tile].palette = SPRITE_PALETTE;
            //sprites[swan*4+tile].tile = tile;
            // When the attribute field is composed manually some things work
            sprites[swan*4+tile].attr = tile | (SPRITE_PALETTE << 9);
        }
    }
asiekierka commented 1 year ago

There are a few issues here:

In Wonderful-generated code, after the first loop, the data segment DS is clobbered with the ROM segment for the table, and never restored, leading subsequent sprites to be written to ROM.

https://github.com/tkchia/gcc-ia16/issues/142

In Wonderful-generated code, the sprite table (relocated to 0x200) is written to location 0x600 instead. This is because, for whatever reason, the offset of the SwanOffset array is written to DS????

  3b:   ba 00 00                mov    $0x0,%dx
                        3c: R_386_16    SwanOffset
                        3c: R_386_SUB16 SwanOffset!
  3e:   8e da                   mov    %dx,%ds

https://github.com/tkchia/gcc-ia16/issues/143