How do I use Vblank?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: How do I use Vblank?

Post by DementedPurple » Thu Mar 16, 2017 9:57 am

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?

User avatar
dustmop
Posts: 136
Joined: Wed Oct 16, 2013 7:55 am

Re: How do I use Vblank?

Post by dustmop » Thu Mar 16, 2017 10:06 am

.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.
Last edited by dustmop on Thu Mar 16, 2017 11:08 am, edited 1 time in total.

User avatar
tokumaru
Posts: 11559
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How do I use Vblank?

Post by tokumaru » Thu Mar 16, 2017 10:40 am

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.

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: How do I use Vblank?

Post by DementedPurple » Thu Mar 16, 2017 11:25 am

Then how would the actual NES know where to go when the NMI is true?

User avatar
dustmop
Posts: 136
Joined: Wed Oct 16, 2013 7:55 am

Re: How do I use Vblank?

Post by dustmop » Thu Mar 16, 2017 11:29 am

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.

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: How do I use Vblank?

Post by DementedPurple » Fri Mar 17, 2017 10:09 am

If the NMI vector is at $FFFA, would that mean I'm limited to only 4 bytes of NMI code?

tepples
Posts: 21874
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How do I use Vblank?

Post by tepples » Fri Mar 17, 2017 10:20 am

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:

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;
}

User avatar
dougeff
Posts: 2650
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: How do I use Vblank?

Post by dougeff » Fri Mar 17, 2017 10:26 am

Nothing at fffa but an address.

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

User avatar
mikejmoffitt
Posts: 1348
Joined: Sun May 27, 2012 8:43 pm

Re: How do I use Vblank?

Post by mikejmoffitt » Fri Mar 17, 2017 10:33 am

DementedPurple wrote:If the NMI vector is at $FFFA, would that mean I'm limited to only 4 bytes of NMI code?
Think of it as a function pointer.

tepples
Posts: 21874
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: How do I use Vblank?

Post by tepples » Fri Mar 17, 2017 10:51 am

DementedPurple wrote:What is a function pointer

Pokun
Posts: 1350
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: How do I use Vblank?

Post by Pokun » Fri Mar 17, 2017 12:31 pm

DementedPurple wrote:If the NMI vector is at $FFFA, would that mean I'm limited to only 4 bytes of NMI code?
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.

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
You use labels like "RESET" so you don't have to hard-code the addresses for your interrupt handlers. Of course when the ROM is assembled the vectors will contain constant addresses, but that is the assemblers job to solve. Instructions like .org and .base is for the assembler to know where in the output file everything should be placed. The reason we start at $8000 (or $C000 if ROM is small) is because $8000 is where the ROM area starts in the address space. If we would use .org $0000 as start address, the interrupt vectors (if we don't change their start addresses) would be in the wrong place and the assembled ROM would become too big. It makes more sense to start counting from a number that matches the start address in the ROM area in the address space.

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.

User avatar
mikejmoffitt
Posts: 1348
Joined: Sun May 27, 2012 8:43 pm

Re: How do I use Vblank?

Post by mikejmoffitt » Fri Mar 17, 2017 12:55 pm

Think of it as the NES doing something similar to

Code: Select all

JSR $FFFA
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.

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: How do I use Vblank?

Post by DementedPurple » Fri Mar 17, 2017 1:06 pm

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:

Code: Select all

example:
jmp example
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?

User avatar
tokumaru
Posts: 11559
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: How do I use Vblank?

Post by tokumaru » Fri Mar 17, 2017 1:50 pm

DementedPurple wrote:would it still go to the NMI?
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.
And also, does the NROM template have that built in?
All mappers behave the same way in regard to NMIs.
Also, could I just do BASE $FFFA before the header?
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?

DementedPurple
Posts: 318
Joined: Mon Jan 30, 2017 5:20 pm
Location: Colorado USA

Re: How do I use Vblank?

Post by DementedPurple » Fri Mar 17, 2017 3:56 pm

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?

Post Reply