$8000 and $C000

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

$8000 and $C000

Post 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.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post 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.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post 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.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

Post 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:

Code: Select all

.inesprg 1
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

Code: Select all

.ineschr 1
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. :wink:
User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

Post 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.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post 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.
User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

Post by 0x7c00 »

Thank you. May I ask things about cc65?
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Go ahead and ask us.
User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

Post 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.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

What happens in Nintendulator and Nestopia?
User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

Post by 0x7c00 »

Nestopia is OK.
nesasm is the only universe way?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post 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.
User avatar
0x7c00
Posts: 9
Joined: Fri Aug 14, 2009 1:19 am

Post 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.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post 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.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post 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.
Post Reply