Doh! Thanks (and sorry). I learned something new todayvbc wrote: ↑Wed Aug 12, 2020 1:07 pmNo, DATA2 is defined as an array of pointers to constant char, not an array of constant pointers to char. This should work:Code: Select all
const unsigned char *const DATA2[] = { DATA1, DATA1, DATA1, DATA1 };
VBCC Optimizing C-compiler now supports NES
Moderator: Moderators
-
- Posts: 38
- Joined: Wed Dec 04, 2019 10:42 am
Re: VBCC Optimizing C-compiler now supports NES
Re: VBCC Optimizing C-compiler now supports NES
Thanks for getting it to build, lazycow. My cat also likes this demo, haha.
I did notice another thing in lnAddSpr that could be optimized, maybe a little controversial though. The INX INX INX INX sequence could be replaced with TXA / AXS #$FC unofficial opcode (it trashes A, but the loop trashes it already). That will be 4 cycles faster per iteration. I never paid much attention to the unofficial NMOS 6502 ops, but AXS immediate ($CB) seems to be one of the most useful ones. It's sure to break something somewhere though (the Project Nested emulator comes to mind, dunno what else).
I was doing a funny experiment with vbcc last night, and ran into a bug or something I don't understand. I'm compiling a 6502 emulator (fake6502). It's set up so every emulated memory read simply returns $EA to make it NOP forever.It barely fits into memory, rodata overflows unless I combine -size with -O2 (or higher). (see edit below) It compiles, but doesn't assemble because some labels are missing.
vc +nrom256v -c99 -+ -O3 -size cpu.c fake6502.c -o cpu.nes
If I build with -O2, there is a longer list of undefined symbols. -O3 and -O4 appears to be the same.
If I build with -S and look at the source, I can indeed see the references to the labels that look like this, but no label anywhere (in this copy/paste l230 is missing, surrounded by references to labels that do exist).
edit:
I was mistaken, the version I posted does compile if I exclude the -size option. The above error only happens with -size. The resulting program crashes (invalid op in Mesen) when run though. Removed calls to reset6502() step6502(), and it's still a black screen (but no invalid op, at least). Removing fake6502.c from the build lets it work again (as in, the blue blackground is there and printf works).
I did notice another thing in lnAddSpr that could be optimized, maybe a little controversial though. The INX INX INX INX sequence could be replaced with TXA / AXS #$FC unofficial opcode (it trashes A, but the loop trashes it already). That will be 4 cycles faster per iteration. I never paid much attention to the unofficial NMOS 6502 ops, but AXS immediate ($CB) seems to be one of the most useful ones. It's sure to break something somewhere though (the Project Nested emulator comes to mind, dunno what else).
I was doing a funny experiment with vbcc last night, and ran into a bug or something I don't understand. I'm compiling a 6502 emulator (fake6502). It's set up so every emulated memory read simply returns $EA to make it NOP forever.
vc +nrom256v -c99 -+ -O3 -size cpu.c fake6502.c -o cpu.nes
Code: Select all
\Users\membl\AppData\Local\Temp\vbcc068c.o: In "_callexternal":
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xf): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x13): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x2f): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x33): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x4f): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x53): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x6f): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x73): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x8f): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x93): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xaf): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xb3): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xcf): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xd3): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xef): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0xf3): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x10f): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x113): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x12f): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x133): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x139): Reference to undefined symbol l38.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x13b): Reference to undefined symbol l38.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x14f): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x153): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x16f): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x173): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x179): Reference to undefined symbol l38.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x17b): Reference to undefined symbol l38.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x18f): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x193): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x1af): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x1b3): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x1cf): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x1d3): Reference to undefined symbol l62.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x1ef): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x1f3): Reference to undefined symbol l65.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x35d): Reference to undefined symbol l459.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x38d): Reference to undefined symbol l230.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x395): Reference to undefined symbol l230.
Error 21: \Users\membl\AppData\Local\Temp\vbcc068c.o (data+0x3a5): Reference to undefined symbol l230.
vlink -b rawbin1 -Cvbcc -T%VBCC%/targets/6502-nes/nrom256v.cmd -L%VBCC%/targets/6502-nes/lib %VBCC%/targets/6502-nes/lib/startup.o "C:\Users\membl\AppData\Local\Temp\vbcc068c.o" -o cpu.nes -lvc failed
If I build with -S and look at the source, I can indeed see the references to the labels that look like this, but no label anywhere (in this copy/paste l230 is missing, surrounded by references to labels that do exist).
Code: Select all
word l230
word l206
word l350
word l507
word l230
word l206
word l242
word l507
word l296
word l206
word l251
word l350
word l230
I was mistaken, the version I posted does compile if I exclude the -size option. The above error only happens with -size. The resulting program crashes (invalid op in Mesen) when run though. Removed calls to reset6502() step6502(), and it's still a black screen (but no invalid op, at least). Removing fake6502.c from the build lets it work again (as in, the blue blackground is there and printf works).
- Attachments
-
- fake6502.c
- (28.69 KiB) Downloaded 174 times
-
- cpu.c
- (481 Bytes) Downloaded 174 times
Re: VBCC Optimizing C-compiler now supports NES
Thanks for the report. The code compressor apparently got confused by some static functions that are only called through function pointers. I will have a look at it. In the meantime you can probably work around it by avoiding static functions (e.g. using -Dstatic= ).Memblers wrote: ↑Thu Aug 13, 2020 4:55 pm I was doing a funny experiment with vbcc last night, and ran into a bug or something I don't understand. I'm compiling a 6502 emulator (fake6502). It's set up so every emulated memory read simply returns $EA to make it NOP forever.It barely fits into memory, rodata overflows unless I combine -size with -O2 (or higher).(see edit below) It compiles, but doesn't assemble because some labels are missing.
Thanks! There is a stupid typo in the startup code leading to an incorrectly initialized data segment:edit:
I was mistaken, the version I posted does compile if I exclude the -size option. The above error only happens with -size. The resulting program crashes (invalid op in Mesen) when run though. Removed calls to reset6502() step6502(), and it's still a black screen (but no invalid op, at least). Removing fake6502.c from the build lets it work again (as in, the blue blackground is there and printf works).
Code: Select all
; copy initialized data from ROM to RAM
lda #<__DS
sta r0
lda #>__DE <= should be __DS of course!
Btw. if you declare the function pointer arrays like this
Code: Select all
static void (*const addrtable[256])() = {
...
static void (*const optable[256])() = {
- Attachments
-
- startupfix.zip
- (3.5 KiB) Downloaded 180 times
-
- Posts: 38
- Joined: Wed Dec 04, 2019 10:42 am
Re: VBCC Optimizing C-compiler now supports NES
Code: Select all
#include <lazynes.h>
#include <string.h>
void draw_text_1(ubyte x, ubyte y, const char *text)
{
uword addr = lnNameTab0 + (y * 32) + x;
lnPush(addr, strlen(text), text);
}
void draw_text_2(ubyte x, ubyte y, const char *text)
{
lnPush(lnNameTab0 + (y * 32) + x, strlen(text), text);
}
int main()
{
static const ubyte COLORS[] = { 2, 33 };
lnSync(lfBlank);
lnPush(lnBackCol, 2, COLORS);
draw_text_1(13, 13, "TEXT 1");
draw_text_2(13, 15, "TEXT 2");
lnSync(0);
return 0;
}
vc +nrom256v -c99 -O1 lazyhello.c lazydata.s -llazynes -o lazyhello.nes not good:
vc +nrom256v -c99 -O0 lazyhello.c lazydata.s -llazynes -o lazyhello.nes
Re: VBCC Optimizing C-compiler now supports NES
Thanks for the tip, changing those to const does fix it, and with that fake6502 uses less than 64 bytes of RAM. I also tested the startupfix, initializing now works, for this demo I'll leave the initialized part in because it actually sounds kind of cool (I'm outputting the emulated 6502 bus through the $4011 audio DAC).vbc wrote: ↑Fri Aug 14, 2020 8:13 am
Btw. if you declare the function pointer arrays like thisthen they will be placed in ROM only rather than being copied from ROM to RAM.Code: Select all
static void (*const addrtable[256])() = { ... static void (*const optable[256])() = {
Compiled with vbcc6502 it's running quite a bit faster than the cc65 version. This is awesome! Sometime I'll run a 6502 test ROM through it, which will exercise all that code in fake6502.c.
I posted it with some more details over here, will attach the demo here and update that post:
viewtopic.php?f=22&t=20673
Here's what I think we're hearing in the vbcc-built version:
seconds
00~05 - polling $2002?
06~06 - clearing NES RAM
07~13 - loading initialized data
13+ - emulated CPU is stuck in an infinite loop
Note this demo is was written expecting it to crash, as there are 2 emulated 6502s stepping all over eachothers RAM. Emulator must support NROM+WRAM.
- Attachments
-
- cpu2.zip
- (16.65 KiB) Downloaded 179 times
Re: VBCC Optimizing C-compiler now supports NES
Who would want to use -O0?timschuerewegen wrote: ↑Fri Aug 14, 2020 1:46 pm good:
vc +nrom256v -c99 -O1 lazyhello.c lazydata.s -llazynes -o lazyhello.nes
not good:
vc +nrom256v -c99 -O0 lazyhello.c lazydata.s -llazynes -o lazyhello.nes
I have updated my page with a fixed version (including also the startup fix).
Thanks for the report.
Re: VBCC Optimizing C-compiler now supports NES
Thanks for the new compiler! Which version contains latest fixes? The latest beta I got from the website, has latest updated file dated August 9th. Or should I build the latest from the provided source code?
edit:
Not sure if you figured it out. I wrote simple Python script to convert vicelabels to mesen labels.Banshaku wrote: ↑Fri Jul 17, 2020 6:01 pm Regarding the vice label, yes, that should be a lot easier to parse than the map file so I should look into this. I will ask Sour if there is a simple way to convert a vice file to make it compatible with mesen. Even just for the asm symbols, that would already help a lot.
edit2:
I have couple of questions.
Can I link to assembly file (without __reg(X)) or use inline assembler and preserve Register Allocation optimization? I guess not, as even std library uses __reg(X).
Who's responsible for preserving a/x/y and rN registers, caller or callee? Or compiler will see their usage and work around it?
- Attachments
-
- convertlabels.txt
- (869 Bytes) Downloaded 171 times
Re: VBCC Optimizing C-compiler now supports NES
Apparently I forgot to update the link (the text mentioned patch e, but the link still pointed to patch d). Now it correctly points to vbcc6502_3e.zip which includes the latest updates. Thanks for the hint.
Thank you!Not sure if you figured it out. I wrote simple Python script to convert vicelabels to mesen labels.
This is listed in the documentation under 6502 Backend=>ABI: r16..r27 are callee-save, all other are caller-save. vbcc assumes that all called functions adhere to this convention. If vbcc knows that a called function does not modify some caller-save registers, it can make use of that information - but it will not fix a function that clobbers callee-save registers.I have couple of questions.
Can I link to assembly file (without __reg(X)) or use inline assembler and preserve Register Allocation optimization? I guess not, as even std library uses __reg(X).
Who's responsible for preserving a/x/y and rN registers, caller or callee? Or compiler will see their usage and work around it?
Re: VBCC Optimizing C-compiler now supports NES
Mesen labels specifically target NES memory model, not sure if it's good idea to integrate into the your compiler. But as you can see from the script, it's very easy. You can find documentation here:
I'm sorry. I spent 3 hours yesterday reading forum and vbcc, vasm, vlink documentation. I have probably missed it...vbc wrote: ↑Mon Aug 24, 2020 4:49 am This is listed in the documentation under 6502 Backend=>ABI: r16..r27 are callee-save, all other are caller-save. vbcc assumes that all called functions adhere to this convention. If vbcc knows that a called function does not modify some caller-save registers, it can make use of that information - but it will not fix a function that clobbers callee-save registers.
Re: VBCC Optimizing C-compiler now supports NES
yaros wrote: ↑Mon Aug 24, 2020 9:34 amMesen labels specifically target NES memory model, not sure if it's good idea to integrate into the your compiler. But as you can see from the script, it's very easy. You can find documentation here:
I'm sorry. I spent 3 hours yesterday reading forum and vbcc, vasm, vlink documentation. I have probably missed it...vbc wrote: ↑Mon Aug 24, 2020 4:49 am This is listed in the documentation under 6502 Backend=>ABI: r16..r27 are callee-save, all other are caller-save. vbcc assumes that all called functions adhere to this convention. If vbcc knows that a called function does not modify some caller-save registers, it can make use of that information - but it will not fix a function that clobbers callee-save registers.
edit:
If I export subroutine with r0/r1 as input parameters, will compiler know that I also clobber r2/r3?
Re: VBCC Optimizing C-compiler now supports NES
Mesen labels specifically target NES memory model, not sure if it's good idea to integrate into the your compiler. But as you can see from the script, it's very easy. You can find documentation here:
I'm sorry. I spent 3 hours yesterday reading forum and vbcc, vasm, vlink documentation. I have probably missed it...vbc wrote: ↑Mon Aug 24, 2020 4:49 am This is listed in the documentation under 6502 Backend=>ABI: r16..r27 are callee-save, all other are caller-save. vbcc assumes that all called functions adhere to this convention. If vbcc knows that a called function does not modify some caller-save registers, it can make use of that information - but it will not fix a function that clobbers callee-save registers.
edit:
If I export subroutine with r0/r1 as input parameters, will compiler know that I also clobber r2/r3?
Re: VBCC Optimizing C-compiler now supports NES
I was able to convert one project up to the sound driver and converting famitracker to vasm is no easy task so for now it's on hold. To get back to write asm, I converted that project back to complete asm and later I may be more up to the challenge to do it.yaros wrote: ↑Sun Aug 23, 2020 3:48 pmNot sure if you figured it out. I wrote simple Python script to convert vicelabels to mesen labels.Banshaku wrote: ↑Fri Jul 17, 2020 6:01 pm Regarding the vice label, yes, that should be a lot easier to parse than the map file so I should look into this. I will ask Sour if there is a simple way to convert a vice file to make it compatible with mesen. Even just for the asm symbols, that would already help a lot.
So for now this project is on hold until I work back on it. If I do work back and convert the driver, I will share it but it may take time.
Re: VBCC Optimizing C-compiler now supports NES
Found a bug with #pragma dontwarn. It still warns.
Code:
Result:
Edit:
I have something weird going on. Simple hello world stopped working. I got new version of VBCC downloaded and replaced, just in case, because I was playing with configurations. Instead of "Hello world" it simply shows blue screen.
Edit2:
Looks like a bug. It doesn't print without \n. The following works.
Code:
Code: Select all
int main()
{
unsigned char i = 0;
// comment
#pragma dontwarn 208
while(1) {
i++;
}
#pragma popwarn
}
Code: Select all
PS D:\...\test_vbcc> vc +nes -O3 -c99 main.c -o test_vbcc.nes
warning 208 in function "main": suspicious loop
I have something weird going on. Simple hello world stopped working. I got new version of VBCC downloaded and replaced, just in case, because I was playing with configurations. Instead of "Hello world" it simply shows blue screen.
Code: Select all
// build with vc +nrom256v -+ -c99 main.c -o test_vbcc2.nes
#include <stdio.h>
int main()
{
printf("Hello World");
}
Looks like a bug. It doesn't print without \n. The following works.
Code: Select all
#include <stdio.h>
int main()
{
printf("hello world\n");
}
Re: VBCC Optimizing C-compiler now supports NES
This warning is produced by a global optimizer pass and can not be disabled locally. You can only disable it globally.yaros wrote: ↑Tue Aug 25, 2020 2:27 pm Result:Code: Select all
PS D:\...\test_vbcc> vc +nes -O3 -c99 main.c -o test_vbcc.nes warning 208 in function "main": suspicious loop
stdio is line-buffered on NES. Either print a linefeed or use fflush(stdout); to make the output appear.Looks like a bug. It doesn't print without \n. The following works.Code: Select all
#include <stdio.h> int main() { printf("hello world\n"); }