joypad polling

I use the following routine to poll pad status

GetPAD:

clr.l d0

clr.l d1

move.b #$40,$A10003

move.b $A10003,d0

andi.b #$3F,d0

move.b #$00,$A10003

move.b $a10003,d1

andi.b #$30,d1

lsl.b #2,d1

or.b d1,d0

not.b d0

move.b d0,PADSTATE

rts

Then, for making things easy, If any button is pressed, I call a routine to wait for all of them to be released...



WaitNoButton:

bsr GetPad

btst.b #PAD_A, PADSTATE

bne WaitNoButton

btst.b #PAD_B, PADSTATE

bne WaitNoButton

btst.b #PAD_C, PADSTATE

bne WaitNoButton

btst.b #PAD_START, PADSTATE

bne WaitNoButton

rts

But this does not work for UP, DOWN, RIGHT, LEFT.

If I do

-

jsr GetPad

btst.b #PAD_LEFT, PADSTATE

bne -

It seems to not wait in the loop...

BUT it works for any button (A,B,C and START)...

Anyone knows about this??

Thank you!
 
Originally posted by patroclus02@Tue, 2006-05-16 @ 05:25 AM

I use the following routine to poll pad status


Did you set $A10005 to $40 beforehand? You also need short delays (2-4 NOPs) after writing to $A10003.

Furthermore given the amount of time people hold down buttons, you want to not poll in a tight loop but instead do it once per V-Blank, or have a suitable software timed delay. If you poll it faster than that, you will detect multiple button presses as the 68000 polls much faster than a person can press and release a button.

The best way to check your pad routine is to poll once during VBlank and simply print the 'PADSTATE' value to the screen. Then you can press the inputs and see which bits work and which don't. Your polling routine might be fine, it could be a problem in how you are using the data. (for example)
 
That's what I do.

I poll once per VBlank.

BUT, when I detect a button pressed, I call a Wait for all button are release in a loop before going on. this is to get rid of repetitive button detection. I just want to detect once per button pressed. then you need to release the button and press again.

This is the easier scheme I found...

The only problem is what happends if the software is in the loop waiting for teh buttons to be realesed, and 50 new VBlank interrupt (PAL) come every second...

It works well, though, but I wonder what happends if a new interrupt comes when we are already in a VBlank interrupt... do you know??

By the, the problem I mentioned is a Gens' bug. It works well in a real system (I tested it today).
 
Originally posted by patroclus02@Tue, 2006-05-16 @ 03:54 PM

BUT, when I detect a button pressed, I call a Wait for all button are release in a loop before going on. this is to get rid of repetitive button detection. I just want to detect once per button pressed. then you need to release the button and press again.

This is the easier scheme I found...


If you want to remove repetitive button presses, you need to keep track of the old and new button states and calculate the changed buttons between those states. I'm too lazy to do it in 68K asm but here's the "C" pseudocode:

joy_old = joy_new; // save old state from last frame

joy_new = poll_joypad(); // get new state

joy_delta = (joy_new ^ joy_old) & joy_new; // calculate changed bits and keep only those that were just pressed

You'd want to carry out the above sequence once per frame and examine joy_delta to get the newly pressed buttons (where the user wasn't pressing it last frame, but was pressing it now) and joy_new to get the currently pressed buttons (where the user is pressing them right now).

If you are checking buttons in a short loop without V-Blank timing, call poll_joypad() before you enter the loop to initialize the variables. I'm just mentioning this because it took a while to figure out in a 68000 exception handler menu that I wrote. ;)
 
Yes, I was thinking on making that.

That is waht I do for more complex projects, I just wanted to make something easy for now, but it definitively is the best choice.

By the way, do you know what happends if a nes VBlank int comes while running the last VBlank int handler??
 
Originally posted by patroclus02@Wed, 2006-05-17 @ 12:16 PM

By the way, do you know what happends if a nes VBlank int comes while running the last VBlank int handler??

[post=146307]Quoted post[/post]​


Take a look at the 68000 programmer's manual, which explains all of this in detail in section 6.3.2.

As long as you don't modify SR during the V-Blank routine, other level 4 interrupts will be ignored until RTE is executed. When the interrupt is accepted, SR is changed to $0400 to mask level 4 and lower interrupts.
 
Back
Top