vhelin / wla-dx

WLA DX - Yet Another GB-Z80/Z80/Z80N/6502/65C02/65CE02/65816/68000/6800/6801/6809/8008/8080/HUC6280/SPC-700/SuperFX Multi Platform Cross Assembler Package
Other
549 stars 98 forks source link

FREADSIZE: incorrect result ? #638

Closed RetroAntho closed 1 month ago

RetroAntho commented 2 months ago

Hello,

I think there are a regression on the FREADSIZE directive. When it has been implemented in wla (https://github.com/vhelin/wla-dx/commit/5c265948e4bd051bb3243cf70e31ea872e3595ac), i used it without any problem. I tried to build the code using wla-65816 10.6a (13.7.2023), the size returned seems to be wrong:

.include "hdr.asm"

.section ".rodata1" superfree

...

VFOREST4C_16_PIC0: .incbin "resources/tileset/forest4c_16.pic" SKIP 0 READ 19200 FREADSIZE VFOREST4C_16_PIC0_SIZE
VFOREST4C_16_PIC0_END:

.ends

.EXPORT VFOREST4C_16_PIC0_SIZE

The function using the value has this header: dmaCopyVram(u8 *source, u16 address, u16 size); and is called like that : dmaCopyVram(&VFOREST4C_16_PIC0, PIC_ADR, &VFOREST4C_16_PIC0_SIZE); => it does not provide the correct result.

By using it like that to have the size, it works correctly: dmaCopyVram(&VFOREST4C_16_PIC0, PIC_ADR, (&VFOREST4C_16_PIC0_END - &VFOREST4C_16_PIC0));

A minimal code is hard to provide as it use a SNES library (pvsneslib) but if required, i will do it in the coming days. Is it possible that something has change on the size calculated ?

Thanks in advance

vhelin commented 2 months ago

Hi!

Could you use something like .PRINTV to see what VFOREST4C_16_PIC0_SIZE is and what (&VFOREST4C_16_PIC0_END - &VFOREST4C_16_PIC0) is?

Quite hard for me to debug by looking at your message here as I don't have the file resources/tileset/forest4c_16.pic - also it's 23:40, getting late... :)

What if you try the latest sources / builds of WLA DX? It's been over a year since 13-Jul-2023...

vhelin commented 2 months ago

It is possible that if you are using exes built on 13-Jul-2023 then something in regards to FREADSIZE has changed since then... v10.6 was released on 19th of November 2023, little over four months after, and v10.6 added FREADSIZE so it might have been under work...

vhelin commented 2 months ago

Not seeing commits about FREADSIZE after 13-Jul-2023, though...

vhelin commented 2 months ago

I think if you just tell me the size of the file "resources/tileset/forest4c_16.pic" so with that info I can test the .INCBIN...

Or actually three cases exist: 1. the file is smaller than 19200 bytes, 2. the file is exactly 19200 bytes, and 3. the file is bigger than 19200 bytes. Let me test these cases...

...

  1. Did not work, got an error from the assembler about overreading the file
  2. Worked as expected
  3. Worked as expected

Is this again about some C compiler for SNES?

RetroAntho commented 2 months ago

I updated wla to the latest version but the issue is still there.

As the issue seems comes from the map (which override the picture), i did the tests with .PRINTV as you said and the returned value is correct ($800 => 2048 octets). By checking in the debugger, the line mapsize = (&VM_BG0_F0_MAP0_END - &VM_BG0_F0_MAP0); it produce : STZ $2000,X [mapsize] = $0800 so, i now have doubt about an issue in WLA...

I confirm that the piece of code i wrote is in C (converted to wla asm by the "tcc-816" compiler) but the functions used behind are all directly wrote in ASM.

I reduced the c code to :


#include <snes.h>

extern char VM_PAL0, VM_PAL0_SIZE;
extern char VFOREST4C_16_PIC0, VFOREST4C_16_PIC0_SIZE, VFOREST4C_16_PIC0_END;
extern char VM_BG0_F0_MAP0, VM_BG0_F0_MAP0_SIZE, VM_BG0_F0_MAP0_END;

#define PIC_ADR 0x0000
#define BG1_ADR 0x6000

void loadm()
{
    dmaCopyCGram(&VM_PAL0, 0, &VM_PAL0_SIZE);
    WaitForVBlank();
    dmaCopyVram(&VFOREST4C_16_PIC0, PIC_ADR, &VFOREST4C_16_PIC0_SIZE);
    WaitForVBlank();
    bgSetGfxPtr(0, PIC_ADR);
    bgInitMapSet(0, &VM_BG0_F0_MAP0, (&VM_BG0_F0_MAP0_END - &VM_BG0_F0_MAP0), SC_32x32, BG1_ADR);
    //bgInitMapSet(0, &VM_BG0_F0_MAP0, &VM_BG0_F0_MAP0_SIZE, SC_32x32, BG1_ADR);
    WaitForVBlank();
    setMode(BG_MODE1, 0);
    bgSetDisable(1);
    bgSetDisable(2);
    setScreenOn();
}

int main(void)
{
    loadm();
    while (1) {
        WaitForVBlank();
    }
    return 0;
}

and the data.asm:

.include "hdr.asm"

.section ".rodata1" superfree

VM_PAL0: .incbin "resources/tileset/m.pal" SKIP 0 READ 32 FREADSIZE VM_PAL0_SIZE

VFOREST4C_16_PIC0: .incbin "resources/tileset/forest4c_16.pic" SKIP 0 READ 19200 FREADSIZE VFOREST4C_16_PIC0_SIZE
VFOREST4C_16_PIC0_END:

VM_BG0_F0_MAP0: .incbin "resources/maps/m_bg0_f0.map" SKIP 0 READ 2048 FREADSIZE VM_BG0_F0_MAP0_SIZE
VM_BG0_F0_MAP0_END:

.PRINTT "Value of \"VM_BG0_F0_MAP0_SIZE\" = $"
.PRINTV HEX VM_BG0_F0_MAP0_SIZE
.PRINTT "\n"

.ends

.EXPORT VM_PAL0_SIZE,VFOREST4C_16_PIC0_SIZE,VM_BG0_F0_MAP0_SIZE

If i replace the bgInitMapSet line by the commented one, the issue occurs. I compared the .asm generated and the result is strange: Tha adc instruction are different !

image

As i am not fluent with asm, i need more time to understand. I propose to let the ticket open and i will update it as soon as possible?

RetroAntho commented 2 months ago

How can i check the value of the exported variable outside the file where it is created? The .PRINTV directive return the right value but when i use it in an other file, the value is not the correct one.

the value seems to be replaced when files are linked. In the .c file, i tried to do:

If (VM_BG0_F0_MAP0_SIZE == the real size)

and the condition is never true: the value seems to be 255 but should be on 16 bits.

If ((u16)VM_BG0_F0_MAP0_SIZE == the real size) is equal to true for the value 65535

vhelin commented 2 months ago

That .EXPORT VM_BG0_F0_MAP0_SIZE you have there should make VM_BG0_F0_MAP0_SIZE visible for other .asm files. I think I'll make a testcase to WLA DX where I test that this works...

As you read 2048 bytes and put the FREADSIZE to VM_BG0_F0_MAP0_SIZE, it should be 2048...

No idea about that 65816 assembly, I don't know anything about 65816 asm :) But I can try to figure out what that means, takes just time.

vhelin commented 2 months ago

Just improved FREADSIZE tests in WLA DX - the export works as it should so I guess the problem is in the 65816 ASM your C compiler generates.

If you .EXPORT say VAR_A in file1.asm then you can use VAR_A in file2.asm, but you cannot .PRINT it as the .EXPORT lies in file1.o and only the linker (WLALINK) will put it into file2.o

You could compile a debug version of WLALINK so it would then print out all the .EXPORTs:

Edit main.c in wlalink folder, enable this definition: kuva

Then compile WLALINK and it'll print out .EXPORTs among labels when it links files: kuva

Here "readSize*" are all .EXPORTs, "address" shows the value they hold

RetroAntho commented 1 month ago

Thanks for the details provided and your time. I am still not able to solve my case and are still looking about it but as it is not related to WLA, i close the issue.

See you next time :)

vhelin commented 1 month ago

Good luck, I hope you can solve that issue! If not, let me know, perhaps I could take a deeper look into the C compiler, what is going wrong inside it...

RetroAntho commented 1 month ago

Thanks! For now, i have only some theory and workaround but nothing to explain the root cause. I saw that you have an other project to create a compiler. The one we use is probably not the best and most standard but if you are interested to see the content (not especially for this issue), the repository is here: https://github.com/alekmaul/tcc/tree/main