It is currently Thu Oct 19, 2017 6:06 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 30 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Wed Feb 22, 2006 4:44 am 
Offline

Joined: Thu Aug 25, 2005 7:36 pm
Posts: 4
I must do lots of calculations during VBlank.
And I must write VRAM during VBlank.
It course abnomal of PPU scanline refresh & destroy my screen view.
Who can tell me how to solve this problem.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 7:25 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10057
Location: Rio de Janeiro - Brazil
Why do you absolutelly must do the calculations in VBlank? In most cases you can perform the calculations during the frame and store the results in a buffer. Then, in VBlank, you only copy the bytes directly from the buffer to the PPU.

I can't see a case where it's absolutelly necessary to do calculations in VBlank time. In the game I'm working now, for example, when the screen scrolls and I have to draw a new part (row and/or column) of the level, I don't read the data directly from the level map, because it is heavily encoded and there would be no time to decode it all in time for drawing. So I decode the stuff I want to draw during the frame and a routine copies everything to the PPU in VBlank time.

Maybe you could be more specific on the reason you MUST do the calculations inside VBlank.


Top
 Profile  
 
PostPosted: Wed Feb 22, 2006 10:19 am 
Offline
User avatar

Joined: Thu Feb 02, 2006 7:07 am
Posts: 117
Location: Chile (South America), Quilpué
when i learn nes 6502, i see all routines for show frame are inside NMI. i think it's unique way in order to get running code to infinite or one condition.

example: I am confused..
is it correct??

Code:

wait for vblank.

NMI:
showing sprites and another stuff (calculations)

infinite:
     jmp infinite


yeah, just i can making stuff because nmi is executed..

if i dont have my code inside a nmi when vblanks occurs, it's running in infinite label, but i get nothing here..

any tips??? do you understan my confusion tokumaru?

then im going to wait until bit 7 is 0 (vblank time ends), then i am making calculations here and it's the frame drawing time???

ps: i played with fcultra x and see nametables of smb3, finally i understand for what smb3 use horizontal mirroring, it's because smb3 must having ground level and sky level in differents nametables ;o)

_________________
Good day to nesdev people. Lord..
Author of nothing =P
UTFSM Sansano programmer.. lord_Chile
Saludos a la Sede JMC de la UTFSM... Viña del Mar, CHILE


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 10:49 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10057
Location: Rio de Janeiro - Brazil
Well, lord_Chile, programs on the NES can be structured in many ways.

The NMI is a routine that runs everytime VBlanks starts, if you have them enabled. Some games have all their code inside the NMI routine. These will write what is needed to the PPU first, and them do the calculations for the next frame, and then finish the NMI with an RTI instruction. I would not recommend doing this in more complex programs, where an NMI could possibly fire while the previous one hasn't finished yet, and that may not be good.

Programs can have only the drawing (PPU writing) routines inside the NMI, and have the main code elsewhere. In this case, the main code wouldn't be "forever: jmp forever". In this case you would do all calculations, move the player and enemies, decode maps, etc., and when finished, set a flag indicating that the frame is ready to be copied to the PPU, and enter a loop that will repeat while this flag is set. When the NMI fires, you check for this flag, if it is set (frame ready for drawing) you can copy the whole stuff to the PPU, and then you clear the flag and return from the NMI (with RTI). Since the flag was cleared, the main code would get out of the loop and start calculating the next frame.

Programs could even not use the NMI at all. They can just calculate the whole frame, wait for VBlank the "traditional way" (wait: bit $2002 bpl wait) and then copy all the data to the PPU. This is cleaner and easier to understand, in my opinion.

The NMI can be really useful when the program is very complex and you have to write data to the PPU in consecutive blocks as they bocome ready, and the main program doesn't ever stop. I was gonna do this with my raycaster, where the program is always calculating new columns of walls and the NMI routine would draw them as they became ready.

lord_Chile, the code you posted is a bit incomplete, and I don't know exactly what you're trying to do there. I can see you are not returning from the interrupt, with the RTI instruction, but I don't know if that is your problem.


Top
 Profile  
 
 Post subject: ehem
PostPosted: Wed Feb 22, 2006 10:53 am 
Offline
User avatar

Joined: Thu Feb 02, 2006 7:07 am
Posts: 117
Location: Chile (South America), Quilpué
i dont have problem now, your explanation era justo mi respuesta.. gracias.

_________________
Good day to nesdev people. Lord..
Author of nothing =P
UTFSM Sansano programmer.. lord_Chile
Saludos a la Sede JMC de la UTFSM... Viña del Mar, CHILE


Top
 Profile  
 
PostPosted: Wed Feb 22, 2006 11:01 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10057
Location: Rio de Janeiro - Brazil
lord_Chile wrote:
then im going to wait until bit 7 is 0 (vblank time ends), then i am making calculations here and it's the frame drawing time???

I don't think you can do that. I think the VBlank flag is cleared as soon as you read it. So, if you read $2002 and the VBlank flag is set, all subsequent reads will return the flag cleared, even if you're still in VBlank, until the NEXT VBlank starts, when the flag will be set again. But you don't usually have a reason to wait for the end of VBlank. There is no problem in calculating the stuff for the next frame while VBlank is still occuring. The other way around is forbiden, you can't write to the PPU outside of VBlank.

Quote:
ps: i played with fcultra x and see nametables of smb3, finally i understand for what smb3 use horizontal mirroring, it's because smb3 must having ground level and sky level in differents nametables ;o)

There is a lot to learn a lot by watching the behavior of the name tables in commercial games.


Top
 Profile  
 
PostPosted: Wed Feb 22, 2006 11:09 am 
Offline
User avatar

Joined: Thu Feb 02, 2006 7:07 am
Posts: 117
Location: Chile (South America), Quilpué
it's the point:

if you calculations are very much, you dont have time to calculating stuff for next frame in vblank time!! then my question is: you say that you are calculating stuff when frame is drawed.. and in what time it is??? after vblank?? before vblank?? and how can i to know when frames are being drawed??

_________________
Good day to nesdev people. Lord..
Author of nothing =P
UTFSM Sansano programmer.. lord_Chile
Saludos a la Sede JMC de la UTFSM... Viña del Mar, CHILE


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 11:43 am 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3943
"After Vblank" is the same as "Before Vblank" if you are thinking about the next frame :)

You run your game logic while the screen is drawing, after vblank. Then you draw during vblank.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Wed Feb 22, 2006 11:44 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10057
Location: Rio de Janeiro - Brazil
Hum... let's try this...

lord_Chile wrote:
if you calculations are very much, you dont have time to calculating stuff for next frame in vblank time!!

No one should do during VBlank calculations that could be performed outside of it. All results of calculations should be buffered, and then directly written during VBlank.

Quote:
then my question is: you say that you are calculating stuff when frame is drawed.. and in what time it is??? after vblank?? before vblank?? and how can i to know when frames are being drawed??

You don't have to know exactly when it is. It is the time after you drew the graphics of the last frame to the PPU and before you write the graphics for the next.

Don't worry too much about it. If you just repeat this: calculate - wait vblank - draw, you'll be safe, as long as the drawing routines don't go past VBlank time. In case the calculation part takes too long, you may just loose a VBlank. You'll loose a frame and it will feel as a slow down to the player, but if it doesn't happen much it's not such a big deal.

To safely detect VBlank though, you should first verify that you are NOT in VBlank, and then wait for it. If you don't do it like this and your calculation/game logic step takes a little more time than a frame (calculations ended after VBlank has already started), you will find yourself inside an incomplete VBlank, meaning the time left may not be enough to do all your drawing. You'll have to ignore this Vblank and wait for the next, so you can use all avaliable time.

The same goes for the flag an NMI technique. If the NMI is triggered and the "ready to draw" flag is not set, you'll just have miss that frame. The calculations were not finished by the time VBlank started, so you can't draw anything yet. Just exit the NMI and leave it for the next time.


Top
 Profile  
 
PostPosted: Wed Feb 22, 2006 11:56 am 
Offline
User avatar

Joined: Thu Feb 02, 2006 7:07 am
Posts: 117
Location: Chile (South America), Quilpué
i know wait to vblank in asm 6502..

but which is the code in order to know that you are NOT in vblank???

_________________
Good day to nesdev people. Lord..
Author of nothing =P
UTFSM Sansano programmer.. lord_Chile
Saludos a la Sede JMC de la UTFSM... Viña del Mar, CHILE


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 11:57 am 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1389
One note, though: you should NOT poll $2002 to wait for VBLANK within your game logic, as you'll have a 14% chance of entirely missing the frame due to a timing glitch - if you read $2002 just as VBLANK starts (either on the exact cycle or on the previous cycle), you will read it as being clear but it will actually be set; it will then be cleared, and you will effectively miss the frame. You should use NMI in your game code, even if it does nothing more than set a variable, since it always triggers (when enabled).

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


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

Joined: Thu Feb 02, 2006 7:07 am
Posts: 117
Location: Chile (South America), Quilpué
totally confused, but i understand something, i will try..

_________________
Good day to nesdev people. Lord..
Author of nothing =P
UTFSM Sansano programmer.. lord_Chile
Saludos a la Sede JMC de la UTFSM... Viña del Mar, CHILE


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 22, 2006 12:10 pm 
Offline

Joined: Wed Mar 09, 2005 9:08 am
Posts: 348
Q is right. Many homebrewn programs. (the only programs I know of that do NOT use the NMI) suffer from this bug. Don't repeat that mistake.

The only reason where polling $2002 to get vblank status would be needed is if you want to execute vblank without having a valid interrupt vector at $FFFA. i.e., to execute code after you pull the cart out with the power still on.

The only program I know of that does this is Chris Covells Theremin program for the NES. (and it doesn't do any vblank updates) But a small EPROM cart with a NES2serial cable could make a neat "poor man's copyNES" device by doing this.

EDIT: Then again, having no cart in the NES anymore leaves you with little reason to draw anything to vblank at all. I must've somehow confused this idea with the one of "hijacking" unmodified carts with battery RAM using a (modified) Game Genie.


Last edited by Bananmos on Wed Feb 22, 2006 12:34 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: oh i see
PostPosted: Wed Feb 22, 2006 12:14 pm 
Offline
User avatar

Joined: Thu Feb 02, 2006 7:07 am
Posts: 117
Location: Chile (South America), Quilpué
quietust give me a different thinking about vblanks because many and many people says me wait to vblank using bit 7 of $2002.

This discussion is very interesting, tokumaru, memblers what do you say about it??

_________________
Good day to nesdev people. Lord..
Author of nothing =P
UTFSM Sansano programmer.. lord_Chile
Saludos a la Sede JMC de la UTFSM... Viña del Mar, CHILE


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

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10057
Location: Rio de Janeiro - Brazil
Quietust wrote:
One note, though: you should NOT poll $2002 to wait for VBLANK within your game logic, as you'll have a 14% chance of entirely missing the frame due to a timing glitch

It would indeed be really bad loosing these random frames here and there. I'm sorry for saying that was an option. You heard it people? Avoid it. =)

Quote:
if you read $2002 just as VBLANK starts (either on the exact cycle or on the previous cycle), you will read it as being clear but it will actually be set; it will then be cleared, and you will effectively miss the frame.

I wouldn't know that exactly, as I don't know what operations are performed on each cycle of the instructions. If the flag didn't get cleared this method would work. Why the hell did Nintendo think it was a good idea to clear the flag on read? The other flags ("sprite 0 hit" and "more than 8 sprites in one scanline") don't get cleared, right?

Quote:
You should use NMI in your game code, even if it does nothing more than set a variable, since it always triggers (when enabled).

You mean you could have your main code pool that variable instead of $2002? But if the game logic takes too long and you're not yet pooling the variable when it gets set, you'll get an incomplete VBlank. Maybe we could still check for "not in VBlank" by reading $2002, but wait for VBlank by pooling the variable. If the read from $2002 returns the flag set, the frame was missed. Yeah, it could work like this...


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: Yahoo [Bot] and 10 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