It is currently Wed Oct 17, 2018 12:48 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3
Author Message
 Post subject:
PostPosted: Sun May 06, 2012 6:03 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Shiru wrote:
By the way, mic_, could you please clarify a thing about TCC816? I recall you said that the compiler declares every function as a superfree section, so the linker could put it anywhere it fits. Is it capable to put the code across the banks, or it is limited to a single bank only? I'm asking because it seems that there is a limitation for amount of code, after some point adding an extra line of code result in a 'game.s:85: INPUT_NUMBER: Out of 16bit range.
game.s:85: ERROR: Couldn't parse "sbc".' error message. It is always the same, no matter where the code is added. Rearranging data in other banks and splitting large functions into smaller ones does not seem to help.


It's the linker (wlalink) that decides where to put the sections. The compiler just instructs the linker to put the sections wherever they fit. I've never seen a section having crossed banks in any of my code, but I can't say for sure that it can't happen.

Are your functions outrageously large, or just larger than "normal"? I have some functions in my code that are maybe 300-400 lines of C code, and I don't get any problems when building my ROM.
Do you have any free banks left (with enough space to hold your function)?
From the error message it sounds like the instruction is trying to access some data in another bank using absolute addressing (.w). What does the line of assembly code that fails look like? And the lines around it?


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 1:37 pm 
Offline

Joined: Sat Jan 23, 2010 11:41 pm
Posts: 1161
The functions are mostly short. There are two large functions (400+ and ~800 lines), they were even larger, I tried to split them down, and nothing changed.

The error is always points to the same line, and it is always the same - very first line of a very first function:

There are no free banks, but some room in some banks that should be enough. Rearranging data to have more room in a bank does not help. Even more, when I extend the ROM to the next size (adds 8 empty banks), nothing changes - the code still does not compile.

Code:
.section ".text_0x0" superfree

rand:
.ifgr __rand_locals 0
tsa
sec
sbc #__rand_locals
tas
.endif
...


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 1:53 pm 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Hmm. What's the value of __rand_locals? It should be defined somewhere around the top of the assembly file.

It looks like the compiler has gone berserk and tried to allocate more than 64kB for local variables / temporaries in your function. You're not declaring any large non-static arrays/structs in the function, are you?


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 1:59 pm 
Offline

Joined: Sat Jan 23, 2010 11:41 pm
Posts: 1161
Code:
.define __rand_locals 997120


This function does not have any variables. All arrays in the whole code are global, and almost all local variables in functions are declated as static. No structs in the whole code.

Another thing is why not all variables are declared as static - at some point I started to get another error while adding a local static variable. Not saved this version of code, though, so can't tell what the error it was.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 2:52 pm 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Maybe looking at the assembly will give some hint of where the locals offset gets messed up. What's the largest value for NN in all ops that use "-NN + __rand_locals + 1,s" that it's actually using? And does the offset suddenly jump from a small value to a very large value at some point?


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 3:20 pm 
Offline

Joined: Sat Jan 23, 2010 11:41 pm
Posts: 1161
I don't really understand what this means, because here are all mentions of the _rand_locals in the code:

Code:
.define __rand_locals 997120
...
.section ".text_0x0" superfree

rand:
.ifgr __rand_locals 0
tsa
sec
sbc #__rand_locals
tas
.endif
lda.w __tccs_snes_rand_seed2 + 0
sta.b tcc__r0
lsr.b tcc__r0
lda.w __tccs_snes_rand_seed1 + 0
clc
adc.b tcc__r0
sta.w __tccs_snes_rand_seed1 + 0
lda.w __tccs_snes_rand_seed1 + 0
eor.w #15
sta.b tcc__r0
lda.w __tccs_snes_rand_seed2 + 0
sec
sbc.b tcc__r0
sta.b tcc__r1
sta.w __tccs_snes_rand_seed2 + 0
lda.w __tccs_snes_rand_seed1 + 0
sta.b tcc__r0
__local_0:
.ifgr __rand_locals 0
tsa
clc
adc #__rand_locals
tas
.endif
rtl
.ends


The function itself is

Code:
unsigned int rand(void)
{
   snes_rand_seed1+=(snes_rand_seed2>>1);
   snes_rand_seed2-=(15^snes_rand_seed1);

   return snes_rand_seed1;
}


All similar defines for other functions are in range of ~997120 to 1020021. The only define that is different is .define __main_locals 0


When I remove a function from the code, so it starts to compile, all the defines are in range 0..12, 0 for the most part. So I think the problem is not related to this particular function.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 11:01 pm 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Ah, right. Perhaps you've run into the same bug as I did once in the past. TCC has a hard limit of 1000 local labels (the ones that look like "__local_0" etc). Since these labels aren't really local it can't reuse the same ones for each function, so the 1000 limit is for an entire C file. There's no proper bounds checking, so if you surpass the limit you'll either get a compiler crash, or it'll output garbage because you overwrote something else.

If you start at the end of the assembly file and search backwards for "__local_", what's the first one you find? If it has a number >=1000 then that's most likely the problem. A workaround for this would be to split your code up into more C files.


Top
 Profile  
 
 Post subject:
PostPosted: Sun May 06, 2012 11:14 pm 
Offline

Joined: Sat Jan 23, 2010 11:41 pm
Posts: 1161
It is 1035. OK, many thanks, I'll try to split the code into few C files.

Would be nice to document these problems somewhere while this is not fixed, maybe in the snes-sdk project wiki.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 4:04 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
This particular bug is very easy to fix. Or at least to avoid; a proper fix would be to used a dynamically growing container (like a C++ list/vector), but increasing the limit from 1000 to 16000 or 32000 would make it very unlikely that you'd hit the limit.

I guess I could supply a patched compiler for Windows (Cygwin).

Quote:
Would be nice to document these problems somewhere while this is not fixed, maybe in the snes-sdk project wiki.

I think there's a bug tracker at the google code page for snes-sdk. But Ulrich (the guy that created the SDK) seems to have more or less abandoned it. It might be easier to just fork the project and upload fixes to a new repo.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 10:40 am 
Offline

Joined: Thu Oct 05, 2006 6:29 am
Posts: 911
Alright, here's an updated version of 816-tcc that allows up to 20,000 local labels.
I also fixed the problem where the compiler would put "gen_opi" comments containing non-ascii characters in the assembly code, which would make the 816-opt script fail.


Top
 Profile  
 
 Post subject:
PostPosted: Mon May 07, 2012 3:59 pm 
Offline

Joined: Sat Jan 23, 2010 11:41 pm
Posts: 1161
Oh, thanks. I thought to try to compile tcc-816 myself, but didn't manage to get it compile with VC2010.

However, this build does not work for me. It crashes with this error:

Code:
      6 [main] ? 224 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
Exception: STATUS_ACCESS_VIOLATION at eip=7C911561
eax=00400000 ebx=00000000 ecx=610E889C edx=0022FFE0 esi=01CD2CA3 edi=00400000
ebp=0022EECC esp=0022EEA4 program=, pid 0, thread main
cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023
Stack trace:
Frame     Function  Args
0022EECC  7C911561  (00400000, 00000000, 0022EEE8, 7C809F9F)
0022EEDC  7C911664  (00400000, 0022EF18, 6109A582, 00400000)
0022EEE8  7C809F9F  (00400000, 00000001, 0022EFF0, 6104F4A6)
0022EF18  6109A582  (00400000, 0022F08C, 00245648, 00000799)
0022EFD8  61004A78  (0022EFF0, FFFFFFFF, 0022EFF0, 00240178)
0022FF88  6100594F  (00000000, 00000000, 00000000, 00000000)
End of stack trace



Edit: figured it out, the problem was with the cygwin1.dll (older or something) - got the latest, and it worked. Now my code compiles without errors, great. Thanks again.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 41 posts ]  Go to page Previous  1, 2, 3

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group