Page 1 of 2
$8000 and $C000
Posted: Fri Aug 14, 2009 1:24 am
by 0x7c00
I read that in the structure of NES bus Program Code begin from $8000.
But I saw lots of code write :
.bank 0
.org $C000
Why do this ?
And when I use ".org $8000", however, using Debugger find in position $C000 my codes appear again. How can it be done?
My knowledge about NES Asm is all from the nesasm_Tutorial.pdf document.
Thanks a lot.
Posted: Fri Aug 14, 2009 5:28 am
by tepples
If you have mapper 0, 16 KiB of PRG (one iNES bank or two NESASM banks), and 8 KiB of CHR, you have the NROM-128 board. This board
mirrors the same 16 KiB of code in $C000-$FFFF and $8000-$BFFF.
Posted: Fri Aug 14, 2009 5:31 am
by Dwedit
This stuff all depends on the memory map.
If you have a 16K PRG game, it will be mirrored across the full 32K ROM address space.
If you have a 32K PRG game, it will fill the entire 32K ROM address space.
If you have a bigger ROM which requires bankswitching, it depends on the mapper. Most mappers which use 16K sized banks make the C000 bank fixed, and the 8000 bank is switchable. Some mappers switch the entire 32K bank. Other mappers can use different banking methods, see documentation on each individual mapper.
Also remember that the address of the first executed instruction is determined by the Reset Vector at address $FFFC, it won't automatically jump to $8000 or $C000 on bootup unless that happens to be the address the Reset Vector is pointing to.
Posted: Fri Aug 14, 2009 7:52 am
by 0x7c00
tepples wrote:one iNES bank or two NESASM banks
Oh, this can explain why in NESASM codes' head there always be a declaration:
Is it mean that "I am declaring a iNES file format" so even NESASM need two banks, the coder should write like that( .inesprg 1)?
But the next line
show 1 bank, this mean both in iNES and NESASM need only one bank for CHR?
And...(forgive me) iNES is a file format, NESASM is a kind of asm language for nes. why they are not same at those places?
Thanks for your patient.

Posted: Fri Aug 14, 2009 7:59 am
by 0x7c00
Dwedit wrote:This stuff all depends on the memory map.
If you have a 16K PRG game, it will be mirrored across the full 32K ROM address space.
If you have a 32K PRG game, it will fill the entire 32K ROM address space.
If you have a bigger ROM which requires bankswitching, it depends on the mapper. Most mappers which use 16K sized banks make the C000 bank fixed, and the 8000 bank is switchable. Some mappers switch the entire 32K bank. Other mappers can use different banking methods, see documentation on each individual mapper.
Also remember that the address of the first executed instruction is determined by the Reset Vector at address $FFFC, it won't automatically jump to $8000 or $C000 on bootup unless that happens to be the address the Reset Vector is pointing to.
Thank you.
I notice $C000-$8000 = 16K is half of 32K(the PRG size)
so I understand the mapper function.
Through Debugger I saw code run start from $C000, is this depends on different mappers? I mean where to start. In Reset Vector the first code is start from $8000.
Posted: Fri Aug 14, 2009 8:40 am
by tepples
The first instruction that the CPU executes is always JMP ($FFFC). That would go to $8000 if the bytes at $FFFC are $00 $80.
Some mappers allow switching $FFFC. In this case, the reset vector would depend on what bank number was floating in the latch at power-on. Games using these mappers have to put the reset vector and about a dozen bytes of reset code into all banks, switch, and then jump to the rest of the reset code.
Despite the name, NESASM was originally designed to target the TurboGrafx-16 system, whose built-in mapper uses 8 KiB banks. NES support was an afterthought, and the bank numbers were a happy coincidence for NES mappers that use 8 KiB banks such as MMC3 and FME-7. But most simpler mappers use 16 KiB or 32 KiB banks.
Posted: Fri Aug 14, 2009 6:31 pm
by 0x7c00
Thank you. May I ask things about cc65?
Posted: Fri Aug 14, 2009 11:24 pm
by tepples
Go ahead and ask us.
Posted: Sat Aug 15, 2009 5:41 pm
by 0x7c00
Ah...Say I use most simple code here:
Code: Select all
#include <conio.h>
void main()
{
clrscr();
gotoxy(10,10);
cprintf("Hello, world");
while(1);
}
When it was compiled, I dragged the nes file to FCEUX, but nothing happen.
However, when I use fceu dsp , "Hello, world" came out.
That mean different emu. has different running environment? How to write an universe program by cc65? Or only nesasm could do that work?
Thank you.
Posted: Sat Aug 15, 2009 5:43 pm
by tepples
What happens in Nintendulator and Nestopia?
Posted: Sat Aug 15, 2009 6:03 pm
by 0x7c00
Nestopia is OK.
nesasm is the only universe way?
Posted: Sat Aug 15, 2009 7:52 pm
by tokumaru
0x7c00 wrote:nesasm is the only universe way?
No, any assembler will be fine, as long as your code does not contain errors. The C compiler you are using most likely failed because the person who made it made mistakes with the generated assembly code.
Posted: Sat Aug 15, 2009 8:03 pm
by 0x7c00
But I don't think it's ca65's mistake. I mean the problem showed up in different emulator environment. The emulator provides a virtual environment to run nes, as far I know, there is not a standard for all developers who work on emulator. So I think the different may be a common question.
Posted: Sat Aug 15, 2009 8:20 pm
by tokumaru
When a program works differently on different emulators, it's hard to tell where the problem is. Not necessarily the emulator that runs the program well is the correct one, it might very well be forgiving something that the program is doing wrong, while other emulators and real consoles are more strict.
But the truth is that a well coded program should run mostly the same across different emulators, unless it uses all sorts of complex tricks. Hello World is as simple as it gets, and if it doesn't work the same in all emulators, something went really wrong during the creation of the program.
Posted: Sat Aug 15, 2009 8:22 pm
by tepples
In that case, there is a defect either in the startup code (which runs before main()) or in one or more emulators. The defect could in fact be in both the startup code and the emulator, if the startup code does something no game from the NES's commercial era ever did (possibly because the game would fail lot check if it did) and emulators aren't prepared to handle it.