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
546 stars 98 forks source link

Unable to fullfill bank of 32k #587

Closed RetroAntho closed 1 year ago

RetroAntho commented 1 year ago

Hello,

I have an issue when managing resources in banks on 65c816 cpu. wla.zip

data.asm file:

.include "hdr.asm"
.section ".rodata1" superfree
VM0_PAL0: .incbin "resources/tileset//m0.pal" skip 0 read 256
VM0_PAL0_end:
VM0_0_PIC0: .incbin "resources/tileset//m0_0.pic" skip 0 read 4096
VM0_0_PIC0_end:
VM0_1_PIC0: .incbin "resources/tileset//m0_1.pic" skip 0 read 3584
VM0_1_PIC0_end:
VM0_2_PIC0: .incbin "resources/tileset//m0_2.pic" skip 0 read 6144
VM0_2_PIC0_end:
VM0_3_PIC0: .incbin "resources/tileset//m0_3.pic" skip 0 read 8192
VM0_3_PIC0_end:
VM0_BG0_F0_MAP0: .incbin "resources/maps//m0_bg0_f0.map" skip 0 read 2048
VM0_BG0_F0_MAP0_end:
VM0_BG1_F0_MAP0: .incbin "resources/maps//m0_bg1_f0.map" skip 0 read 2048
VM0_BG1_F0_MAP0_end:
VM0_BG2_F0_MAP0: .incbin "resources/maps//m0_bg2_f0.map" skip 0 read 2048
VM0_BG2_F0_MAP0_end:
VM0_BG3_F0_MAP0: .incbin "resources/maps//m0_bg3_f0.map" skip 0 read 2048
VM0_BG3_F0_MAP0_end:
VM3_PAL0: .incbin "resources/tileset//m3.pal" skip 0 read 32
VM3_PAL0_end:
;VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2270
VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272
VM3_0_PIC0_end:
.ends

.section ".rodata2" superfree
;VM3_0_PIC1: .incbin "resources/tileset//m3_0.pic" skip 2270 read 28194
VM3_0_PIC1: .incbin "resources/tileset//m3_0.pic" skip 2272 read 28192
VM3_0_PIC1_end:
VM3_BG0_F0_MAP0: .incbin "resources/maps//m3_bg0_f0.map" skip 0 read 2048
VM3_BG0_F0_MAP0_end:
.ends

The bank should be 100% full but i get this error on the wlalink step :

src/main.obj: src/main.asm:35: COMPUTE_PENDING_CALCULATIONS: Result (65536/$10000) of a computation is out of 16-bit range. In data.asm file, just change the comment on the lines VM3_0_PIC0 and VM3_0_PIC1 I read 2 bytes less in the last file of the bank. The compilation works successfully and the output mention :


ROM bank 1 (2 bytes (0.01%) free)
  - Free space at $7ffe-$7fff (2 bytes)

In other cases, i can sometimes fill the bank to 100% but i do not understand where is the difference.

I can provide the .asm/.obj files generated and used if required. The code has been built with the last commit of wla, the wlalink instruction used is : wlalink -d -s -v -A -c -L ${LIBDIRSOBJS} linkfile $@

Is it something i did wrong ? Thanks in advance for your help

vhelin commented 1 year ago

Please provide the files, that makes debugging this issue a lot more easier. :) I cannot take a look at this today, but perhaps later this week...

RetroAntho commented 1 year ago

bugwla.zip

I hope it will be more easy to test like that ! I created a buildInstructions.txt with few lines as the makefile cannot be used.

Only the sources of some .obj files are not provided because it is a part from the lib used (pvsneslib). If you need their content too, it will ask me more time to create a full autonomous sample (the time i check what is used exactly behind)

RetroAntho commented 1 year ago

Hello, I finally did an autonomous sample than you can test directly with make command to reproduce the issue : bugwla.zip

I added the files crt0_snes.asm and dmas.asm (+ some pieces of code inside it to avoid adding too much files).

The issue "main.obj: main.asm:17: COMPUTE_PENDING_CALCULATIONS: Result (65536/$10000) of a computation is out of 16-bit range." occurs with this minimal code (provided in asm too) :

extern char VM3_0_PIC0, VM3_0_PIC0_end;

int main(void)
{
    dmaCopyVram(&VM3_0_PIC0, 0x0, &VM3_0_PIC0_end - &VM3_0_PIC0);
    while (1) {
    }
    return 0;
}

and if you change the comment on these lines in data.asm :

;VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2270
VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272
;VM3_0_PIC1: .incbin "resources/tileset//m3_0.pic" skip 2270 read 28194
VM3_0_PIC1: .incbin "resources/tileset//m3_0.pic" skip 2272 read 28192

The compilation works correctly but the output indicates you than 2 bytes are free in the bank.

Hope it will be enough clear and complete to debug.

vhelin commented 1 year ago

Thank you for these files! My summer vacation just started so I'm sure I can give this a look today or tomorrow!

vhelin commented 1 year ago

My initial suspicion is that you .incbin the bank 100% full of data and after all those bytes you define VM3_0_PIC0_end. Which would then be right outside the bank.

If you'd specify

lda.w #VM3_0_PIC0_end - 1

then would it work? Should VM3_0_PIC0_end point at the last byte of your data or one byte after it? If I read your assembly right it's now one byte after it.

EDIT: In the case of "lda.w #VM3_0_PIC0_end - 1" I think you'd need to adjust your data copy loops etc. so that the value you are loading there is the last byte of the data, not the one after it.

I'll get back to this tomorrow, need to investigate this further...

RetroAntho commented 1 year ago

Sorry for the delay, i just tested your solution lda.w #VM3_0_PIC0_end - 1 and i confirm that it build correctly. So if i understand correctly, it is not something which can be solved in wla and i have to take it into account in my code.

I guess i just need to do "-1" when the bank is full and the bin file continue in other one ? What is strange is that it seems to works in some other cases but i will do more tests.

The label "_end" is just a way to deduce the size of data (by doing &VM3_0_PIC0_end - &VM3_0_PIC0), i saw that it can be done with VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272 FSIZE size_of_VM3_0_PIC0 but the issue will probably be the same as size_of_VM3_0_PIC0 will be declared in the same bank which is already full.

vhelin commented 1 year ago

Without knowing 100% what you are actually doing I suspect that by using VM3_0_PIC0_end - 1 will result in all but the last byte copied? I know very little about 65816 asm. But I guess you are storing the start and the end labels and then executing the copy subroutine. In this case the problem is that the end is out of the bank if the bank is full and referencing it directly gives a value one byte outside 64k range. If you could give the starting address (VM3_0_PIC0) and the number of bytes to be copied (VM3_0_PIC0_end - VM3_0_PIC0) then it might just work? But that would require you to change how dmaCopyVram works...

vhelin commented 1 year ago

So if i understand correctly, it is not something which can be solved in wla and i have to take it into account in my code.

I'm not 100% certain, but I think this is the case.

RetroAntho commented 1 year ago

I wanted to test your solution by providing the number of bytes to be copied. I read in the doc :

You can also force WLA to create a definition holding the size of the file:

.INCBIN "kitten.bin" FSIZE size_of_kitten

but this instruction : VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272 FSIZE size_of_VM3_0_PIC0

return the error : src/main.obj: src/main.asm:16: PARSE_STACK: Unresolved reference to "size_of_VM3_0_PIC0". during the link :

.include "hdr.asm"
.accu 16
.index 16
.16bit
.define __main_locals 0

.SECTION ".text_0x0" SUPERFREE

main:
.ifgr __main_locals 0
tsa
sec
sbc #__main_locals
tas
.endif
lda.w #0
sep #$20
lda.l size_of_VM3_0_PIC0 + 0
rep #$20
xba
xba
bpl +
ora.w #$ff00
+
pha
pea.w 0
pea.w :VM3_0_PIC0
pea.w VM3_0_PIC0 + 0
jsr.l dmaCopyVram
tsa
clc
adc #8
tas
__local_0:
bra __local_0
lda.w #0
sta.b tcc__r0
__local_1:
.ifgr __main_locals 0
tsa
clc
adc #__main_locals
tas
.endif
rtl
.ENDS
.RAMSECTION "ramgGJUWrxhZh.data" APPENDTO "globram.data"
__local_dummygGJUWrxhZh.data dsb 1

.ENDS

As i am not fluent with ASM, is it used correctly ? Otherwise i will try to manage dynamically the "label - 1" when the bank is full

vhelin commented 1 year ago

I can't check this now, and I'll be travelling for the whole day tomorrow, but I'll try to check the FZISE issue on the plane and will report back on Friday.

vhelin commented 1 year ago

A super quick question? Does it work if you .EXPORT size_of_VM3_0_PIC0 in this file?

vhelin commented 1 year ago

As you specify the read size in here

VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272 FSIZE size_of_VM3_0_PIC0

I'm kind of guessing that you could also .DEFINE size_of_VM3_0_PIC0 yourself to be 2272... ?

RetroAntho commented 1 year ago

Does it work if you .EXPORT size_of_VM3_0_PIC0 in this file?

Yes, the compilation works successfully after adding the EXPORT command (but not the rom itself, probably related to the code which is wrong)

I did not tried the solution with .DEFINE but i tried this one (by reusing the size_of variable) :

.include "hdr.asm"
.section ".rodata1" superfree
...
VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272 FSIZE size_of_VM3_0_PIC0
.ends

.section ".rodata2" superfree
VM3_0_PIC1: .incbin "resources/tileset//m3_0.pic" skip size_of_VM3_0_PIC0 read 28192
...
.ends

which fail (with or without .EXPORT instruction) with this error :

data.asm:33: INCBIN_FILE: SKIP value (30464) is more than the size (30464) of file "resources/tileset//m3_0.pic".
data.asm:33: ERROR: Couldn't parse ".incbin".

I do not know if can be used like that (it could improve the readability!)

Even if i think than FSIZE is the better solution, i have an other question about the initial issue (the label declared outside the bank when the bank is fulled). Does a label take any space in the bank ? If no, does WLA should not be able to store it in its corresponding bank even if you declare it when the bank is full?

vhelin commented 1 year ago

Does it work if you .EXPORT size_of_VM3_0_PIC0 in this file?

Yes, the compilation works successfully after adding the EXPORT command (but not the rom itself, probably related to the code which is wrong)

I did not tried the solution with .DEFINE but i tried this one (by reusing the size_of variable) :

.include "hdr.asm"
.section ".rodata1" superfree
...
VM3_0_PIC0: .incbin "resources/tileset//m3_0.pic" skip 0 read 2272 FSIZE size_of_VM3_0_PIC0
.ends

.section ".rodata2" superfree
VM3_0_PIC1: .incbin "resources/tileset//m3_0.pic" skip size_of_VM3_0_PIC0 read 28192
...
.ends

which fail (with or without .EXPORT instruction) with this error :


data.asm:33: INCBIN_FILE: SKIP value (30464) is more than the size (30464) of file "resources/tileset//m3_0.pic".
data.asm:33: ERROR: Couldn't parse ".incbin".

That's because FSIZE in .INCBIN is set to contain the full size of the file you are reading from, not the number of bytes read from the file...

I could add another option like FREADSIZE etc. that would take a definition name and put there the number of bytes read, but you could also have that in an .DEFINE already...



I do not know if can be used like that (it could improve the readability!)

Even if i think than **FSIZE** is the better solution, i have an other question about the initial issue (the label declared outside the bank when the bank is fulled). Does a label take any space in the bank ? If no, does WLA should not be able to store it in its corresponding bank even if you declare it when the bank is full?

Label doesn't have a size, or it's always 0, but if you first include 65536 bytes and then define a label then that label's address will be 65536.

vhelin commented 1 year ago

I could add another option like FREADSIZE etc. that would take a definition name and put there the number of bytes read, but you could also have that in an .DEFINE already...

I think I'll add this as it might make life easier...

RetroAntho commented 1 year ago

thanks a lot :) I tried it and it works !

Does the .EXPORT size_of_VM3_0_PIC0 will still be mandatory or it is something than you will plan to change in the future to mange it "automatically" ?

Otherwise i can close the issue, everything is now clear for me :)

vhelin commented 1 year ago

.EXPORT size_of_VM3_0_PIC0 is and will be mandatory in the future as exporting every definition by default would totally break compatibility with many projects out there...

Or how I understand your case is that you create size_of_VM3_0_PIC0 in file A and then reference it in file B - by default a definition is local to the file where it was created, but if you want it to be seen outside of that file then you need to .EXPORT it.

RetroAntho commented 1 year ago

Or how I understand your case is that you create size_of_VM3_0_PIC0 in file A and then reference it in file B

Yes, it is exactly this case. Thank you, see you next time !