So I took the plunge and decided to try and move away from NESASM due to its buggy behavior, switching to CC65 instead. The syntax isn't all that different, mostly labels and such. The thing that threw me for a loop for a few minutes was the notion of needing to use a seperate config file to setup the code segment and memory locations and such. There's a much appreciated simplicity with NESASM where I simply use .bank and .org to fill the gaps and such I need in a rom image.
In any case, I got the assembly aspect down for the most part, so I thought I'd look into including some C, in case I might ever want to whip up a function right quick for testing, and then do an assembler version later. Calling C functions from assembly seemed fairly straight forward and I had it working fairly quickly. The problem, however, involves the use of variables. The first time through, they simply don't work properly.
By first time through, I mean when I first execute the code in an emulator (FCE Ultra), it's messed up; any variable references are totally incorrect. But if I use the reset command, suddenly it works fine. It's as if it's setting up something during the first run, despite failing to work properly, which allows the second attempt work fine, since the reset command is apparently just a soft reset and doesn't reset memory (like a real NES from what I understand). Other emulators aren't as forgiving, and don't work with the rom at all.
For example:
unsigned char * const ppu_reg1 = (unsigned char*)0x2000;
...
*ppu_reg1 = 0x90;
Assigning a value to *ppu_reg1 does nothing the first time through. The second time, as mentioned above, it works correctly. Something to note is that if I don't use "const" on the pointer, it doesn't ever work, soft reset or not. However, if I use, for example:
*((char *)0x2000) = 0x90
It works every time, because obviously there's no variable references.
It's not just limited to accessing pointers, either. Something like..
unsigned char n = 0x90;
*((char *)0x2000) = n;
..ends up with the same results. $2000 gets set with a value, but it's not what it's supposed to be on the first pass.
One thing that came to mind is that maybe I'm supposed to initialize the C runtime library, but I'm at a loss for how to do so. The other thing is that my segment/memory file might be incorrect. But there's possibly so many reasons for it to not work, some of which I'm prolly not even thinking of, that I don't really know where to start.
I'd post code, but there's multiple files, so unless it's needed to diagnose such a problem, I'll leave it off for now. I figure somebody with more experience at CC65 might already know what I'm talking about.
The other small question is if anyone has a reference for the functions in nes.lib file. There seems to be many functions in there which aren't documented whatsoever in the stuff that comes in the cc65 documenation archive. Though that particular NES documentation seems to be lacking all around anyway.
Anyhoo, thanks in advance!
In any case, I got the assembly aspect down for the most part, so I thought I'd look into including some C, in case I might ever want to whip up a function right quick for testing, and then do an assembler version later. Calling C functions from assembly seemed fairly straight forward and I had it working fairly quickly. The problem, however, involves the use of variables. The first time through, they simply don't work properly.
By first time through, I mean when I first execute the code in an emulator (FCE Ultra), it's messed up; any variable references are totally incorrect. But if I use the reset command, suddenly it works fine. It's as if it's setting up something during the first run, despite failing to work properly, which allows the second attempt work fine, since the reset command is apparently just a soft reset and doesn't reset memory (like a real NES from what I understand). Other emulators aren't as forgiving, and don't work with the rom at all.
For example:
unsigned char * const ppu_reg1 = (unsigned char*)0x2000;
...
*ppu_reg1 = 0x90;
Assigning a value to *ppu_reg1 does nothing the first time through. The second time, as mentioned above, it works correctly. Something to note is that if I don't use "const" on the pointer, it doesn't ever work, soft reset or not. However, if I use, for example:
*((char *)0x2000) = 0x90
It works every time, because obviously there's no variable references.
It's not just limited to accessing pointers, either. Something like..
unsigned char n = 0x90;
*((char *)0x2000) = n;
..ends up with the same results. $2000 gets set with a value, but it's not what it's supposed to be on the first pass.
One thing that came to mind is that maybe I'm supposed to initialize the C runtime library, but I'm at a loss for how to do so. The other thing is that my segment/memory file might be incorrect. But there's possibly so many reasons for it to not work, some of which I'm prolly not even thinking of, that I don't really know where to start.
I'd post code, but there's multiple files, so unless it's needed to diagnose such a problem, I'll leave it off for now. I figure somebody with more experience at CC65 might already know what I'm talking about.
The other small question is if anyone has a reference for the functions in nes.lib file. There seems to be many functions in there which aren't documented whatsoever in the stuff that comes in the cc65 documenation archive. Though that particular NES documentation seems to be lacking all around anyway.
Anyhoo, thanks in advance!