DELAYS??

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

User avatar
nineTENdo
Posts: 223
Joined: Sun Mar 19, 2006 12:37 am
Location: San ANto, TX
Contact:

DELAYS??

Post by nineTENdo »

WHats a good way to slow down movement of sprites on button presses.

Code: Select all

       lda X_POS
	ADC #20
	
	ASL a
	asl a
	sTA X_POS

	lda Y_POS
	ADC #80
	
	ASL a
	asl a
	sTA Y_POS
        BNE infinite
This code gets the sprite to move crazy is there any way i could input a delay so that im able to see each increment. The infinite just goes though Vblank and joy stobes

Thanks in Advance
EL
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Re: DELAYS??

Post by Disch »

nineTENdo wrote:WHats a good way to slow down movement of sprites on button presses.
Don't be constantly checking button presses. NMIs will occur at a steady 60 FPS. If you want your game to move at a constant, steady rate, let NMIs drive your program logic.

What does that mean? Well -- Strobe joypad and move the player (as well as do any other logic) only ONCE per frame:

1) Wait for VBlank
2) Strobe Joypad, move player, etc (only once!)
3) Wait for another VBlank
4) do step 2 again
5) wait for another VBlank
5) etc

if you move the player 1 pixel per frame, he'll move 60 pixels per second (which isn't blazing fast).
User avatar
nineTENdo
Posts: 223
Joined: Sun Mar 19, 2006 12:37 am
Location: San ANto, TX
Contact:

Post by nineTENdo »

Would it be best if use the waitvblank as a subroutine so i can leave it apart from strobing and moving. Heres what i have. Could i fit more vblanks to make it even slower.

Code: Select all

infinite
waitblank: 
	       
	lda $2002  
	bpl waitblank 

	lda #$00   ; these lines tell $2003
	sta $2003  ; to tell
	lda #$00   ; $2004 to start
	sta $2003  ; at $0000.

	lda #40 ; load Y value
	sta $2004 ; store Y value
	
	lda #$02 ; tile number 0
	sta $2004 ; store tile number
	
	lda #$00 ; no special junk
	sta $2004 ; store special junk
	
	lda X_Pos ; load X value
	sta $2004 ; store X value
	; and yes, it MUST go in that order.

 	lda #$01	; directly loads the Accumulator with 1
 	sta $4016	; stores the Accumulator value (1) into $4016
 	lda #$00	; directly loads the Accumulator with 0
 	sta $4016 
	
	
	lda $4016
	and #1
	bne KEYDN
	
	lda $4016 
	lda $4016  
	lda $4016  

	lda $4016
	lda $4016 
	lda $4016  
	lda $4016
	JMP infinite
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

It's best that you don't actually "wait" for VBlanks. It has been confirmed that code like this

Code: Select all

waitblank:
   lda $2002 
   bpl waitblank
will miss a few VBlanks along the way. NMI's are the way to make use of all VBlanks.

You should be sure to let NMI's enabled, and somewhere inside the NMI routine (preferably after all PPU operations) you read the controllers and update the character's coordinates accordingly.

After you do that, you'll be reading keys and processing them 60 times per second. If you're not carefull, even that may still be too much for you. To prevent things from moving insanely fast, you could turn your coordinates into fixed point values. And later, insert animation tables defining how many NES frames should each animation frame last, so that animation doesn't go too fast. Anyway, that's in the future.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg »

Take a look at my multithreading demo for more straight forward approach, where you can have each thread sit and wait until enough NMIs have gone by.
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

It could look like this:

Code: Select all

.segment "ZEROPAGE"
vblanked: .res 1

.segment "CODE"
nmiHandler:
  inc vblanked
  rti

waitVblank:
  lda vblanked
  beq waitVblank
  lda #0
  sta vblanked
  lda $2002  ; reset $2006 sub address
  rts
Last edited by tepples on Wed Jul 05, 2006 8:02 pm, edited 1 time in total.
User avatar
lord_Chile
Posts: 120
Joined: Thu Feb 02, 2006 7:07 am
Location: Chile (South America), Quilpué
Contact:

question

Post by lord_Chile »

reading $2002 reset 1st/2nd write flip flop (for $2005 and $2006). Also "the in vblank flag" is cleared. but for what it miss frames???, if NMI doesnt be affected by it no?
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
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

If vblank happens at the exact same cycle (?) as a $2002 read, then the vblank bit of $2002 never gets set for that frame.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Snippits from the readme included with blargg's VBL test ROMs:
2.vbl_timing
------------
Tests timing of VBL being set, and special case where reading VBL flag
as it would be set causes it to not be set for that frame.

8) Reading 1 PPU clock before VBL should suppress setting



5.nmi_suppression
-----------------
Tests timing of NMI suppression when reading VBL flag just as it's set,
and that this doesn't occur when reading one clock before or after.

3) Reading flag when it's set should suppress NMI
6) Reading flag 1 PPU clock after set should suppress NMI
9) Reading flag 1 PPU clock before set should suppress NMI

The bottom line:

You do not want to rely on $2002 polling for VBlank waiting (since you have roughly a 1 in 7 chance of a frame being skipped due to the flag suppresion). It's fine for the "warm up" time you have to do when the system powers up, but after that you should always fall back to good old reliable NMIs, which will never miss a frame (as long as they're enabled, and as long as you're not dicking with $2002 around the start of VBlank).
User avatar
nineTENdo
Posts: 223
Joined: Sun Mar 19, 2006 12:37 am
Location: San ANto, TX
Contact:

Re: DELAYS??

Post by nineTENdo »

Disch wrote:let NMIs drive your program logic.
Great idea!! That will help with experimenting. But i cant seem to get an NMI to run. Do i need certain conditions to run it? Do you know of a simple algorithm to just add X of a sprite movement?

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

Post by tepples »

NMI will execute if bit 7 of PPUCTRL ($2000) is set.
User avatar
nineTENdo
Posts: 223
Joined: Sun Mar 19, 2006 12:37 am
Location: San ANto, TX
Contact:

Post by nineTENdo »

OOOOOHHHH ok i forgot! Does it matter if i set it before or after the code in the code of the NMI routine. and when i set it do i have to turn it back off?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

I think it is up to you to found the best way to use the hardware. Usually you'd want to disable the NMIs at reset, to have the reset procedure execute normally. Then, once you're done and your game is ready to start, you'd want to enable NMI and keep them enabled always exept when loading a new level or something in that genre.
Since you have to write to $2000 in each VBlank in order to get proper scrolling values, you'd want a variable that contain the value to write to $2000 at the end of VBlank. It would first be initialised with NMI enabled, wich pattern tables use BG and Sprites, etc... and only its two low bits would be modified by the scrolling programm to change nametables.
Useless, lumbering half-wits don't scare us.
User avatar
nineTENdo
Posts: 223
Joined: Sun Mar 19, 2006 12:37 am
Location: San ANto, TX
Contact:

Post by nineTENdo »

Bregalad wrote: you'd want to enable NMI and keep them enabled always exept when loading a new level or something in that genre.
Does that include updating Sprite positions?

Just wanted to say that The Hex Editor in FCEUXD has changed my entire view of reading/writing code!!!!!

Thanks FCEUXD!!!!!!
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

Yes, I also had been very happy when I discovered all the debuggin features of FCEUXD. It really rocks.

I recommand to do you sprite position calculating outise of the NMI in the game logic, but it is up to you to know.
For example, most Konami and Nintendo games like to do EVERYTHING in NMI and just do infinite jumps outside of NMI. After some experitmenation I think it is the worst way to work, but they still did it.
Square seems to like do NOTHING in NMI, just return and continue the previous code that was just waiting a VBlank trigger.
Most other game companies (Capcom, Enix, HAL, etc...) seems to do timing critical routine in NMI plus other things like sound, and the game logic outinde of the NMI, wich is definitely the best way, for my viewpoint.
Useless, lumbering half-wits don't scare us.
Post Reply