It is currently Tue Oct 17, 2017 9:05 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 30 posts ]  Go to page Previous  1, 2
Author Message
 Post subject:
PostPosted: Wed Feb 22, 2006 12:45 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3470
Location: Indianapolis
I was gonna say pretty much the same as what tokumaru said, just do all your calculations during the frame and buffer them so during vblank you can unload the buffer quickly.

I don't put much in my NMI routine besides the needed stuff. I'd also normally do the controller reading and music playing there (after all the PPU stuff is done), because I want that going all the time even if the main loop slows down.

And definitely don't use $2002 polling for vblank waiting, like everyone said, that doesn't work the same on an emulator.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 12:45 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Polling $2002 doesn't offer much advantage.
NMI is definitely more usefull.
If your main code overflows and cannot follow the frames, you'll be happy to still have the music programm and some automatic frame buffering done in NMI routine, so that only a part of the gameplay effectively slows down.
Also, it allow you to place the usual code (stuff like writing sprite DMA) in an un-rolled style.
That means that you only time your NMI to do sprite DMA if its flag is set, but polling $2002 will require you to do sprite DMA manually each time you poll would end.
Eventually, I think there was one commerial game to use $2002 poll, but it wasn't an action game, and it used frame IRQ for the sound, so missing frame would be totally unimportant. This game is the game Enix released between Door Door and Dragon Quest, and his name was so complicated that I don't remember it.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 12:56 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Oh, everyone has posted while I was making my post... anoying.

Quote:
Why the hell did Nintendo think it was a good idea to clear the flag on read?

Imagine this :
Code:
-  bit $2002
    bpl -
-   bit $2002
    bpl -

You wanted to poll 2 frames, but it the flag doesn't get cleared, it waits only one frame... AS IT DOES WITH NESTICLE !

I'd personally not like doing controller reading in NMI, because detecting buttons is very anoying to code, and if you additionally have to admit that the button value could in theory change at any time (it a NMI occurs during your calculation parts check the joypad buttons), it sure make things harder. But some peolpe would prefer the other way arround, so it is up to each progammer to do as his/her wishes.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject: Re: oh i see
PostPosted: Wed Feb 22, 2006 12:58 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10047
Location: Rio de Janeiro - Brazil
lord_Chile wrote:
quietust give me a different thinking about vblanks because many and many people says me wait to vblank using bit 7 of $2002.

I guess it is still usefull for the first few tasks, where timing isn't critical. Missing a frame inside the main game would sure suck, but what would be the real difference when you're waiting for the PPU to warm up, and you wait 3 frames instead of 2? None. When you're about to turn the screen on for the first time, what's the problem in missing one single frame? No problem.

I'm still not really sure what the best way would be. Since a game has many different areas such as title screen, options screen, different kinds of in-game sections (depending on the game), the NMI would need to check where you are at the moment (some variable can say that) and jump to the appropriate code. But that decision has to be quick or you'll loose precious VBlank time.

Maybe the first thing inside the NMI should be an indirect jump, so that you could redirect it to any routine you wish just by writing it's address to the proper place. Then you could use only NMI's and stop pooling $2002 for good. But I guess it would be necessary to turn NMI's off when changing the address, to avoid the unfortunate, but unlikely case where the jump would happen between the writes of the 2 bytes that make up the address.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 1:03 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
That's very easy to overpass.
Have your NMI vertor pointing to RAM (yeah), and write $4c (jump opcode) followed by your real vector adress. It only delays 3 cycles, and the fact to have an NMI occuring in RAM is so cool !!
However, be carefull, when writing the adress to the RAM area, you'll anyway be unable to totally prevent writing the first byte, then the second byte. If an NMI *would* occur during theese two writes, your code will most likly frezee (at least mess up). So, be sure to disable NMI in hardware (write $00 to $2000) or in software (replace $4c per $60 (RTI) then turn it back to $4c when the vector is ready).

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 1:10 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10047
Location: Rio de Janeiro - Brazil
Bregalad wrote:
Imagine this :
Code:
-  bit $2002
    bpl -
-   bit $2002
    bpl -

You wanted to poll 2 frames, but it the flag doesn't get cleared, it waits only one frame... AS IT DOES WITH NESTICLE !

Yeah, I know this wouldn't work... but if Nintendo had designed tha hardware differently, programmers would have programmed differently than that (waiting for the flag to be clearead and then waiting for it to be set, twice) if they wanted to wait 2 frames. Nintendo certainly didn't choose to clear the flag so you could detect VBlank with less instructions, since their decision pretty much invalidated the use of the flag for the serious stuff, where speed is needed.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 1:17 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10047
Location: Rio de Janeiro - Brazil
Bregalad wrote:
or in software (replace $4c per $60 (RTI) then turn it back to $4c when the vector is ready).

That's a very good idea! Write $60, then the address, and then $4c again. Pretty smart.

There is no chance an NMI would fire before you have the chance to turn them off in the beginning of the program, right? Or else the NES would try to run random crap from RAM... but I guess this is not the case.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 1:23 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
Well... at reset, you'll like writing pretty much imediatly $00 to $2000, instantly disabling NMIs.
If, for an obscure reason, an NMI would happen at reset, that could be disastrous in the very particular case of having the processor execute random code writing to SRAM, and possibly erasing/corrupting the game's saves. Else than that, it doesn't matter if it frezee at start up, since NES cartridges often doesn't work the first try, the player will just press the reset button again without caring if his cartridge isn't working because of the hardware or the software.
However, I doubt having an NMI between reset and the first write to $2000 is thinkable. Again, I think this will be very very very unlucky.

About $2002 polling, you're definitely right. But I don't think it is very usefull to ask why Nintendo did that. It sure is a good question, but any answer won't change facts.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 1:23 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10047
Location: Rio de Janeiro - Brazil
Memblers wrote:
I was gonna say pretty much the same as what tokumaru said, just do all your calculations during the frame and buffer them so during vblank you can unload the buffer quickly.

Yeah, but then I said one could just wait for VBlank by polling (sorry, I was writing "pooling" before) $2002... shame on me! =)

I usually use NMI's, but considered polling $2002 a valid option. I'll just keep in mind it's not.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 2:09 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
Bregalad wrote:
Quote:
Why the hell did Nintendo think it was a good idea to clear the flag on read?

Imagine this :
Code:
-  bit $2002
    bpl -
-   bit $2002
    bpl -

You wanted to poll 2 frames, but it the flag doesn't get cleared, it waits only one frame... AS IT DOES WITH NESTICLE !

Then you do what a lot of "Nesticle game" programmers did, as tokumaru points out:
Code:
-  bit $2002
    bpl -
-   bit $2002
    bmi -
-   bit $2002
    bpl -

But if you want the Nesticle-like behavior, such as if you plan to steal a few scanlines off the top of the NTSC overscan to do nametable or OAM updates, you can still coax that out of a real NES if you can ensure that sprite 0 will always be hit. Here, you'd use a bit/bvs loop.

Quote:
Have your NMI vertor pointing to RAM (yeah), and write $4c (jump opcode) followed by your real vector adress. It only delays 3 cycles, and the fact to have an NMI occuring in RAM is so cool !!

The Apple II "monitor" BIOS used exactly this technique.

Quote:
However, I doubt having an NMI between reset and the first write to $2000 is thinkable. Again, I think this will be very very very unlucky.

Even with the best reset code, you are likely to get an NMI before the STX completes on about one out of 3700 resets:
Code:
reset:
  sei
  ldx #0
  stx $2000
  stx $2001
  cld
  dex
  txs


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 23, 2006 3:11 am 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
tepples wrote:
Even with the best reset code, you are likely to get an NMI before the STX completes on about one out of 3700 resets.


Eh? Did you measure this? If so, bravo for sitting through hundreds of thousands of resets to get this to such an accurate value. I've found that the NMI is disabled at power-up, but perhaps you're saying it can occur at the beginning even so?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 23, 2006 6:04 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
blargg wrote:
tepples wrote:
Even with the best reset code, you are likely to get an NMI before the STX completes on about one out of 3700 resets.

Eh? Did you measure this?

No, I calculated it as 29780 cycles per frame divided by 8 cycles before the sta completes.

Quote:
I've found that the NMI is disabled at power-up

What about at soft reset?


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 23, 2006 10:17 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7224
Location: Chexbres, VD, Switzerland
After a soft reset, the vector from the previous reset would most probably be decent in the good area of RAM.
And it while changing the adress, you write $60 to the vector's destination as I said above, it will perform RTS, not RTI, which is $40. I just said something wrong.
This method can be fairly dangerous if NMI *could* be triggered between the reset and the first write to $2000 with bit 7 clear, at least on the first startup where most RAM contain only $ff.
But if it would contain data that *may* do something with $6000-$7fff, it *may* alter game saves and that would be really bad.

_________________
Life is complex: it has both real and imaginary components.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 23, 2006 12:00 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
tepples wrote:
What about at soft reset?


NMI is disabled after soft reset. Code enables NMI then loops. Reset vector waits half a second and NMI doesn't occur within that time.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Feb 23, 2006 2:49 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19093
Location: NE Indiana, USA (NTSC)
blargg wrote:
NMI is disabled after soft reset.

Is this true of Famicom, frontloading NES, and toploading NES? I seem to remember that they behave differently on reset, such that only the CPU gets reset on the Famicom, not the PPU.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 30 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 guests


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

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group