How do I use Vblank?
Moderator: Moderators
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: How do I use Vblank?
Sorry, I thought the BASE statement was something like a .db statement that wouldn't work on the actual hardware. If I were to write the binary file to an actual EPROM, would the NMI code appear in that section?
Re: How do I use Vblank?
.db reserves space in memory (RAM or ROM, depending on usage and the assembler), and it works just fine on hardware.
Generally speaking, anything in a compiled .nes file that runs in emulator will work the same on hardware when burned on an EPROM. There are tons of exceptions (buggy emulators, startup state, improper mapper usage, lua scripting), but generally speaking the features are the same, especially when talking about how assemblers work.
NMI code will appear in the NES hardware's address space the same way it will in an emulator, regardless of whether you use .BANK for linker relocation, or .SEGMENT directives, or whatever.
Generally speaking, anything in a compiled .nes file that runs in emulator will work the same on hardware when burned on an EPROM. There are tons of exceptions (buggy emulators, startup state, improper mapper usage, lua scripting), but generally speaking the features are the same, especially when talking about how assemblers work.
NMI code will appear in the NES hardware's address space the same way it will in an emulator, regardless of whether you use .BANK for linker relocation, or .SEGMENT directives, or whatever.
Last edited by dustmop on Thu Mar 16, 2017 11:08 am, edited 1 time in total.
Re: How do I use Vblank?
The .nes file you run on emulators contains the exact same binary data you burn on EPROMs to run on real hardware, you don't need 2 separate builds when coding the program. To burn EPROMs you just need to take the .nes file and use a tool or an hex editor to split it into header, PRG-ROM and CHR-ROM, and then burn the PRG and CHR to different chips.
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: How do I use Vblank?
Then how would the actual NES know where to go when the NMI is true?
Re: How do I use Vblank?
Tepples mentioned this earlier. The address at $FFFA contains the NMI "vector", which is just an address that points to the NMI function. So for example, if your NMI function gets compiled such that it is in the ROM at $8123, then the value at $FFFA is $23, and the value at $FFFB is $81 (little-endian order swaps the bytes of the address). You maybe were confused and thought that the vectors were "metadata", like the 16 byte header at the start of the ROM, but they're not. They exist in the binary even when on hardware.
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: How do I use Vblank?
If the NMI vector is at $FFFA, would that mean I'm limited to only 4 bytes of NMI code?
Re: How do I use Vblank?
The vector $FFFA can point anywhere in ROM or RAM.
The vast majority of Super Mario Bros., for instance, is its NMI handler. That's because it's structured roughly like the following pseudocode:
The vast majority of Super Mario Bros., for instance, is its NMI handler. That's because it's structured roughly like the following pseudocode:
Code: Select all
main() {
setup_hardware();
init_globals();
enable_nmi();
for (;;) { }
}
__interrupt__ void nmi() {
PUSH_ALL;
if (vram_data_ready) {
copy_data_to_vram();
vram_data_ready = 0;
}
read_controllers();
game_logic();
prepare_data_for_vram();
vram_data_ready = 1;
POP_ALL;
}
Re: How do I use Vblank?
Nothing at fffa but an address.
When the processor gets an Interrupt signal, it will jump somewhere. Fffa tells it where to jump.
When the processor gets an Interrupt signal, it will jump somewhere. Fffa tells it where to jump.
nesdoug.com -- blog/tutorial on programming for the NES
- mikejmoffitt
- Posts: 1353
- Joined: Sun May 27, 2012 8:43 pm
Re: How do I use Vblank?
Think of it as a function pointer.DementedPurple wrote:If the NMI vector is at $FFFA, would that mean I'm limited to only 4 bytes of NMI code?
Re: How do I use Vblank?
DementedPurple wrote:What is a function pointer
Re: How do I use Vblank?
No the interrupt vectors just points to your interrupt handlers. They don't contain any code, just addresses (addresses are 2 byte each). The interrupt handlers contains the code.DementedPurple wrote:If the NMI vector is at $FFFA, would that mean I'm limited to only 4 bytes of NMI code?
The templates you are using looks something like this:
Code: Select all
;iNES header here
.org $8000
RESET:
;init code here
main:
;main loop code here
jmp main
NMI:
;nmi code here
rti
IRQ:
;irq code here
rti
;Interrupt vectors:
.org $FFFA
.dw NMI
.dw RESET
.dw IRQ
The order of the three interrupt handlers (RESET, NMI and IRQ) doesn't matter, they can be anywhere in the ROM (or RAM as Tepples said). Just make sure that NMI and IRQ handlers ends with an RTI instruction, and the RESET handler ends with an endless loop.
The order of the interrupt vectors DO matter however.
Last edited by Pokun on Fri Mar 17, 2017 5:53 pm, edited 1 time in total.
- mikejmoffitt
- Posts: 1353
- Joined: Sun May 27, 2012 8:43 pm
Re: How do I use Vblank?
Think of it as the NES doing something similar to every time there is an NMI. That's not literally what's going on, but the point is that $FFFA stores the address of your NMI routine, and the 6502 reads that memory to find where to jump. We say that $FFFA points to a location in memory.
Code: Select all
JSR $FFFA
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: How do I use Vblank?
So it goes to the NMI code automatically, no matter what the CPU is doing. So if I where to have a loop like the one down below:
would it still go to the NMI? And also, does the NROM template have that built in? Also, could I just do BASE $FFFA before the header?
Code: Select all
example:
jmp example
Re: How do I use Vblank?
Yes, as long as NMI generation is enabled in the PPU (bit 7 of register $2000), which you normally do at the end of the initialization code.DementedPurple wrote:would it still go to the NMI?
All mappers behave the same way in regard to NMIs.And also, does the NROM template have that built in?
Again, what's with this BASE stuff, man? No more BASE, forget about BASE. Specially before the header, that makes no sense whatsoever. Just out of curiosity, what would you be trying to accomplish with a BASE before the header anyway?Also, could I just do BASE $FFFA before the header?
-
- Posts: 318
- Joined: Mon Jan 30, 2017 5:20 pm
- Location: Colorado USA
Re: How do I use Vblank?
I don't know, I think that a BASE command is like a header, I honestly have no idea. How would the NES know where $FFFA is?