$8000 and $C000
Moderator: Moderators
$8000 and $C000
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.
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.
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.
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!
Oh, this can explain why in NESASM codes' head there always be a declaration:tepples wrote:one iNES bank or two NESASM banks
Code: Select all
.inesprg 1
But the next line
Code: Select all
.ineschr 1
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.
Thank you.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.
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.
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.
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.
Ah...Say I use most simple code here:
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.
Code: Select all
#include <conio.h>
void main()
{
clrscr();
gotoxy(10,10);
cprintf("Hello, world");
while(1);
}
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.
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.
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.
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.