Page 8 of 9

Re: VBCC Optimizing C-compiler now supports NES

Posted: Fri Jul 31, 2020 2:22 am
by timschuerewegen
Another bug?

The following function ends up inlined in rom instead of ram. If I add "__noline" to the function then it ends up in ram.

Code: Select all

#pragma section data

void play_sound()
{
	IO8(0x4015) = 0x03;
	IO8(0x4000) = 0x9F;
	IO8(0x4002) = 0xFD;
	IO8(0x4003) = 0xF8;
}

#pragma section default

Re: VBCC Optimizing C-compiler now supports NES

Posted: Fri Jul 31, 2020 6:43 am
by timschuerewegen

Code: Select all

#include <lazynes.h>

ubyte data[0x10];

int main()
{
	memcpy(data, (void *)0x2000, 0x10);
	return 0;
}
does not compile

>EOF
error 158 in line 10 of "main.c": internal error 0 in line 3153 of file machines/6502/machine.c !!
aborting...

EDIT: if you remove the "(void *)" cast you get a different internal error: "internal error 0 in line 202 of file ic.c"

Re: VBCC Optimizing C-compiler now supports NES

Posted: Fri Jul 31, 2020 6:55 am
by Banshaku
@timschuerewegen

For now I didn't have any of those error since I'm not using the C library at all but a custom startup with no bss copy and strict minimum. It good though that those methods are tested for people that actually want to use it for other things than games.

@vbc

I was able to port a complete project that I'm working on (albeit without the sound driver since famitracker is too big to convert now and not my project) and it worked so mission accomplished for a working nes project with no far pointer, custom manual banking on every frame. The error that I mentioned but removed in my previous message was caused by an error in my makefile so now everything is fine.

I didn't have time yet to test zpage and LENGTH but now that it's compiling I should be able to test them soon. If I find any issues I will be more than glad to share them.

Re: VBCC Optimizing C-compiler now supports NES

Posted: Fri Jul 31, 2020 8:04 am
by vbc
timschuerewegen wrote:
Thu Jul 30, 2020 3:22 pm

Code: Select all

#define IO8(addr) (*(volatile ubyte *)(addr))

void test()
{
	ubyte val;
	IO8(0x4147) = IO8(0x4147) & 0xBF;
	val = IO8(0x4147) & 0xDF;
	IO8(0x4147) = val;
	IO8(0x4147) = val | 0x20;
}
results in the following reads/writes

Code: Select all

R 4147 41
W 4147 01 01 21
but it should be

Code: Select all

R 4147 41
W 4147 01
R 4147 41
W 4147 41 61
Adding "volatile" to "val" seems to fix it but that should not be necessary.
Ah, the sorrows of volatile...I fixed the bug that caused the assembly peephole optimizer to remove the second load.
I have updated the files on my page. Please let me know if this fixes the issue.
The following function ends up inlined in rom instead of ram. If I add "__noline" to the function then it ends up in ram.
That is how it is supposed to work.
timschuerewegen wrote:
Fri Jul 31, 2020 6:43 am

Code: Select all

#include <lazynes.h>

ubyte data[0x10];

int main()
{
	memcpy(data, (void *)0x2000, 0x10);
	return 0;
}
does not compile

>EOF
error 158 in line 10 of "main.c": internal error 0 in line 3153 of file machines/6502/machine.c !!
aborting...
And more dirty stuff that is not covered by my system-friendly portable test suite. :-) This should also be fixed with the new patch that I uploaded.

Thanks again for the reports. Much appreciated!

Re: VBCC Optimizing C-compiler now supports NES

Posted: Fri Jul 31, 2020 8:41 am
by timschuerewegen
vbc wrote:
Fri Jul 31, 2020 8:04 am
Ah, the sorrows of volatile...I fixed the bug that caused the assembly peephole optimizer to remove the second load.
I have updated the files on my page. Please let me know if this fixes the issue.

And more dirty stuff that is not covered by my system-friendly portable test suite. :-) This should also be fixed with the new patch that I uploaded.
Confirmed, the issues are fixed, thanks.

I love vbcc :)

Re: VBCC Optimizing C-compiler now supports NES

Posted: Fri Jul 31, 2020 11:25 pm
by timschuerewegen
vbc wrote:
Fri Jul 31, 2020 8:04 am
Ah, the sorrows of volatile...I fixed the bug that caused the assembly peephole optimizer to remove the second load.
I have updated the files on my page. Please let me know if this fixes the issue.
It's not 100% fixed, because when I compile the same code, sometimes I get a good $41xx r/w behaviour and sometimes a bad one. Uninitialised variable somewhere in the compiler? Most of the time it's good but sometimes it's bad, and because of the randomness difficult to reproduce.

Code: Select all

#define IO8(addr) (*(volatile ubyte *)(addr))

void test()
{
	ubyte val;
	IO8(0x414A) = IO8(0x414A) | 0x02;
	IO8(0x4147) = IO8(0x4147) & 0xBF;
	val = IO8(0x4147) & 0xDF;
	IO8(0x4147) = val;
	IO8(0x4147) = val | 0x20;
	IO8(0x4147) = IO8(0x4147) | 0x40;
}
good (although the STA $1F is not necessary)

Code: Select all

LDA     $414A
ORA     #$02
STA     $414A
LDA     $4147
AND     #$BF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
STA     $1F
ORA     #$20
STA     $4147
LDA     $4147
ORA     #$40
STA     $4147
RTS
bad

Code: Select all

LDA     $414A
ORA     #$02
STA     $414A
LDA     $4147
AND     #$BF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
STA     $1F
ORA     #$20
STA     $4147
LDA     $1F
STA     $1F
ORA     #$60
STA     $4147
RTS

Re: VBCC Optimizing C-compiler now supports NES

Posted: Sat Aug 01, 2020 2:12 am
by timschuerewegen
... and this piece of code also suffers from the good/bad/random issue

Code: Select all

...
IO8(0x414B) = IO8(0x414B) & 0xFD;
IO8(0x4147) = IO8(0x4147) & 0xBF;
IO8(0x4147) = IO8(0x4147) & 0xDF;
IO8(0x4147) = IO8(0x4147) & 0xDF;
IO8(0x4147) = IO8(0x4147) & 0xDF;
IO8(0x4147) = IO8(0x4147) | 0x20;
IO8(0x4147) = IO8(0x4147) | 0x40;
...
good

Code: Select all

...
LDA     $414B
AND     #$FD
STA     $414B
LDA     $4147
AND     #$BF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
LDA     $4147
ORA     #$20
STA     $4147
LDA     $4147
ORA     #$40
STA     $4147
...
bad

Code: Select all

...
LDA     $414B
AND     #$FD
STA     $414B
LDA     $4147
AND     #$BF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
LDA     $4147
AND     #$DF
STA     $4147
LDA     $4147
ORA     #$20
STA     $4147
LDA     $4147
ORA     #$60
STA     $4147
..

Re: VBCC Optimizing C-compiler now supports NES

Posted: Sat Aug 01, 2020 6:26 am
by timschuerewegen
... and another one, sorry :)

Code: Select all

void bin_to_hex(const ubyte *data, ubyte size, char *text)
{
	static const char HEX[] = "0123456789ABCDEF";
	while (size-- > 0)
	{
		ubyte val = *data++;
		*text++ = HEX[(val >> 4) & 0xF];
		*text++ = HEX[(val >> 0) & 0xF];
	}
}
bin_to_hex(data, 1, text) => "XX" (ok)
bin_to_hex(data, 2, text) => "XX" (not ok, should be "XXXX")

If I change the while loop to a for loop then it works as expected.

Code: Select all

void bin_to_hex(const ubyte *data, ubyte size, char *text)
{
	static const char HEX[] = "0123456789ABCDEF";
	ubyte i;
	for (i = 0; i < size; i++)
	{
		ubyte val = *data++;
		*text++ = HEX[(val >> 4) & 0xF];
		*text++ = HEX[(val >> 0) & 0xF];
	}
}

Re: VBCC Optimizing C-compiler now supports NES

Posted: Sat Aug 01, 2020 7:51 am
by Banshaku
@timschuerewegen

I think you shouldn't be sorry, the more you find, the better it will become ;)

Just a quick question, most bugs found are with volatile when you try to access the hardware directly? The last example seems different though. I rarely do data parsing or accessing hardware directly in C so maybe those issue I may not end up on it but the last one seem troublesome (changing while to for then the issue is fixed).

One of the reason I'm migrating code to vbcc is because of strange behavior in cc65 so if I end up with new strange behavior then that's a little bit worrisome.

Re: VBCC Optimizing C-compiler now supports NES

Posted: Sat Aug 01, 2020 9:08 am
by timschuerewegen

Code: Select all

void wait()
{
	__asm(" ldx #$10");
	__asm(".1:");
	__asm("	dex");
	__asm(" bne .1");
}

int main()
{
	wait();
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> ok

vc +nrom256v -+ -O0 main.c -o main.nes
=> error 3005: reloc type 2, size 8, mask 0xffffffff (symbol l14 1 + 0xffffffff) not supported

Re: VBCC Optimizing C-compiler now supports NES

Posted: Mon Aug 03, 2020 12:07 am
by timschuerewegen

Code: Select all

#include <lazynes.h>

int main()
{
	const ubyte DATA[] = { 1, 2, 3, 4 };
	memcpy((void *)0x4000, DATA, 2);
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> >EOF error 158 in line 20 of "main.c": internal error 0 in line 776 of file opt.c !! aborting...

Re: VBCC Optimizing C-compiler now supports NES

Posted: Mon Aug 03, 2020 12:23 am
by timschuerewegen

Code: Select all

#include <lazynes.h>

#define IO8(addr) (*(volatile ubyte *)(addr))

int main()
{
	IO8(0x4FF5) = 0x00;
	while (IO8(0x4FF5) == 0x00);
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> vbcc6502 -I%VBCC%/targets/6502-nes/include -quiet -mainargs -cmd= "C:\Users\Tim\AppData\Local\Temp\vbcc068e" -o= "C:\Users\Tim\AppData\Local\Temp\vbcc068d.scs" -+ -unsigned-char -O=-1 failed

Re: VBCC Optimizing C-compiler now supports NES

Posted: Mon Aug 03, 2020 2:58 pm
by vbc
timschuerewegen wrote:
Fri Jul 31, 2020 11:25 pm
It's not 100% fixed, because when I compile the same code, sometimes I get a good $41xx r/w behaviour and sometimes a bad one. Uninitialised variable somewhere in the compiler? Most of the time it's good but sometimes it's bad, and because of the randomness difficult to reproduce.
Seems there was a code path in an optimization that did not handle absolute addresses correctly. I have updated the files. I think that should fix it (although I could not reproduce the randomness on Linux).
... and this piece of code also suffers from the good/bad/random issue
That should have been the same bug.
bin_to_hex(data, 1, text) => "XX" (ok)
bin_to_hex(data, 2, text) => "XX" (not ok, should be "XXXX")
This was a case of incorrectly eliminating a cmp #0 instruction. Should be fixed.

Code: Select all

void wait()
{
	__asm(" ldx #$10");
	__asm(".1:");
	__asm("	dex");
	__asm(" bne .1");
}

int main()
{
	wait();
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> ok

vc +nrom256v -+ -O0 main.c -o main.nes
=> error 3005: reloc type 2, size 8, mask 0xffffffff (symbol l14 1 + 0xffffffff) not supported
Local labels in vasm only work between other labels. As the code is made out of several separate __asm statements, some non-local labels will be inserted by the compiler (without optimizatio), causing problems with local labels. You can use a single __asm statement to prevent this, e.g.:

Code: Select all

        __asm(" ldx #$10\n"
              ".1:\n"
              " dex\n"
              " bne .1");

Code: Select all

#include <lazynes.h>

int main()
{
	const ubyte DATA[] = { 1, 2, 3, 4 };
	memcpy((void *)0x4000, DATA, 2);
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> >EOF error 158 in line 20 of "main.c": internal error 0 in line 776 of file opt.c !! aborting...
The optimized constant memcpy had a problem with absolute addresses. Should be fixed.

Code: Select all

#include <lazynes.h>

#define IO8(addr) (*(volatile ubyte *)(addr))

int main()
{
	IO8(0x4FF5) = 0x00;
	while (IO8(0x4FF5) == 0x00);
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> vbcc6502 -I%VBCC%/targets/6502-nes/include -quiet -mainargs -cmd= "C:\Users\Tim\AppData\Local\Temp\vbcc068e" -o= "C:\Users\Tim\AppData\Local\Temp\vbcc068d.scs" -+ -unsigned-char -O=-1 failed
Similar problem like the first one. Should also be fixed.

Thanks again for the bug reports! They are very helpful!

Re: VBCC Optimizing C-compiler now supports NES

Posted: Tue Aug 04, 2020 8:56 am
by timschuerewegen
vbc wrote:
Mon Aug 03, 2020 2:58 pm
Seems there was a code path in an optimization that did not handle absolute addresses correctly. I have updated the files. I think that should fix it (although I could not reproduce the randomness on Linux).
...
That should have been the same bug.
...
This was a case of incorrectly eliminating a cmp #0 instruction. Should be fixed.
...
The optimized constant memcpy had a problem with absolute addresses. Should be fixed.
...
Similar problem like the first one. Should also be fixed.!
Thanks. I removed all my workarounds and no more errors or strange behaviour with the new version :)

Re: VBCC Optimizing C-compiler now supports NES

Posted: Wed Aug 05, 2020 2:45 am
by timschuerewegen
Found another bug :)

Code: Select all

#include <lazynes.h>

#define IO8(addr) (*(volatile ubyte *)(addr))

void test(const ubyte *data)
{
	ubyte x = 0;
	IO8(0x484F) = 0xAA;
	IO8(0x4830+x) = data[0];
	IO8(0x4831+x) = data[1];
	IO8(0x4832+x) = data[2];
	IO8(0x484F) = 0xBB;
}

int main()
{
	static const ubyte DATA[] = { 1, 2, 3 };
	test(DATA);
	return 0;
}
vc +nrom256v -+ -O3 main.c -o main.nes
=> not ok
W 484F AA BB

vc +nrom256v -+ -O2 main.c -o main.nes
=> ok
W 484F AA
W 4830 01
W 4831 02
W 4832 03
W 484F BB