When the CPU checks for interrupts and find that the flip-flop is set, it pushes the processor status register and return address on the stack, reads the NMI handler's address from $FFFA-$FFFB, clears the flip-flop, and jumps to this address."

Thus the behavior of the CPU when servicing NMI is similar to the following pseudocode:

As the assembler goes line by line, converting ASM into machine code, it is also counting. BASE $8000, tells it to start counting at $8000. Why is it counting? So we can use Labels in our code.

The first thing the assembler sees after BASE $8000 is the label RESET. It assigns the value $8000 to the label RESET. Now, any time the assembler sees the word RESET, it replaces it (in the machine code) with the value $8000 (actually $00, $80, little endian style)

The advantage here, is, you should be able to move code around in your file, but the assembler should still be able to reassign a new value to RESET, if needed. Let's say that you wrote some code between the BASE $8000 and the label RESET. Now when it counts, it might be at $823c by the time it sees the RESET label... and would then replace all uses of that label with $823c.

The lines past .ORG FFFA, are addresses. DW = 2 bytes. The assembler will see the label for NMI, and replace that with the address of the NMI label. But, the important part, is the NMI label can be anywhere. You don't have to calculate its position and insert it at FFFA. The assembler will do that for you, if you put .DW NMI here.

_________________nesdoug.com -- blog/tutorial on programming for the NES

$FFFA is a ROM location. Doing bit $FFFA will not read the state of the PPU.

The state of the NMI generator is at $2002, but there's a race condition associated with reading it. Normally you want to make $FFFA point at a routine that modifies a variable in RAM, then make your main program wait for that variable to change.

If you want an analogy to high-level languages, then $FFFA, $FFFC, and $FFFE contain hardcoded function pointers to listeners for NMI, reset, and IRQ events respectively, and the NMI and IRQ listeners run in a separate thread with priority over the main thread.

What is a function pointer, and second, what does BASE $8000 and labels have to do with testing a bit? can't you just use a bit command? I don't understand why having the reset label be in $8000 would help test the state of the NMI.

Just to be clear, I was talking about RESET vectors as an example of how to set up a functional ROM, with a functioning NMI.

From tepples example earlier...

1. Make an NMI handler, which is a special kind of subroutine that ends with RTI instead of RTS.

2. Set the vector at $FFFA to point to the NMI handler. Exactly how this is done depends on the assembler you're using.

3. Set bit 7 of PPUCTRL ($2000) to 1. If bit 7 of PPUCTRL is 1, the CPU will call the NMI handler at the start of every vblank.

I was explaining part 2. Set the NMI vector to point to the NMI handler. I guess I was also explaining part 1...the NMI handler itself is everything between the label NMI: and the RTI.

To USE the NMI, you do part 3, and the PPU will generate an NMI Interrupt at the start of every v-blank, and your code will AUTOMATICALLY jump to the NMI code at this time (which happens 60 times a second).

EDIT, the NMI code should terminate in RTI. At which point it will return to your regular code.

_________________nesdoug.com -- blog/tutorial on programming for the NES

BASE changes the PC instantaneously, while ORG fills the ROM with the fill value up to the specified address. For this reason, BASE has to be used carefully, or you might end up with an invalid ROM. Normally you'll use BASE to switch to a different addressing space (from bank to bank, from PRG to CHR, etc.), but when advancing within the same space you probably want to use ORG.

Don't mix up assembler commands and the actual program. Things like BASE and ORG are used only by the assembler, to know where to put the code in the ROM and what addresses to use for labels, variables and such. The program running in the CPU doesn't care or know about any of that, it just needs everything to be in the correct places.

If you mean put it on an NES cartridge for testing, the PowerPak and EverDrive N8 are the most common choices for this. These adapters take digital camera memory (CompactFlash or Secure Digital respectively) and plug into an NES Control Deck.

If you mean put it on an NES cartridge for distribution to the public, you have a few options: DIY kits from RetroStage, preassembled user-flashable carts from Infinite NES Lives, or having RetroUSB or Infinite NES Lives manufacture and sell the things for you.

What is this thing about BASE? BASE is something you use to structure the ROM correctly. If you already have a working ROM, you don't need anymore BASE statements. If you put anymore of those you'll probably break the ROM's structure. Why are you insisting on that? What exactly are you trying to accomplish with it?

Who is online

Users browsing this forum: No registered users and 6 guests

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