Jump to content
IGNORED

Atari 5200 keypad repeat fix... SUCCESS !!!


Recommended Posts

Woohoo!!

 

I found what I needed in the Atari System Reference Manual, Chapter 5 "THE KEYBOARD HANDLER".

 

When the Keypad IRQ is entered., what you do is check to see if this key is the same as the last key. If not, cool, accept the key and go on. If it's the same, check a debounce counter (we make this ourselves). If this counter is zero, then the key is accepted, otherwise its discarded as a held down key. In all cases of entry into the Keypad IRQ the debounce is reset to 3 (you can experiment with other values but this seems okay). This resets the counter.. so when a key is held down this will always be 3.

 

Now, in the deferred VBI, the debounce counter is decremented until its zero, one step at a time (3 2 1 0). If my math is correct, this means once you let go of a key, you have to wait 1/20 of a second before pushing it again. Considering the 5200 keypads, this should not be a serious problem Here is source code for the Keypad DLI and deferred VBI routines. This code has been tested and is working great on the real 5200!:

 

code:


; Zero page equates

KEY .EQU $2A ; this is similar to the Atari 800 CH

KEYLAST .EQU $2B

KEYDB .EQU $2C

 

;---------------------------------------------------------------------

; KEYPAD -- Keypad buffer handler

; On entry: A=key just pressed

;---------------------------------------------------------------------

.ORG $BC00

CMP KEYLAST ;same key as last time?

BNE KEYOK

LDX KEYDB ;same key, check debounce timer

BNE KEYDONE ;if debounce isn't 0, reject the key

KEYOK STA KEY

STA KEYLAST ;store keypress

KEYDONE LDA #$03 ;reset debounce timer

STA KEYDB

PLA

TAY ;POP Y

PLA

TAX ;POP X

PLA ;POP A

RTI

 

;---------------------------------------------------------------------

; Deferred VBI handler

;---------------------------------------------------------------------

.ORG $BC20

LDA KEYDB ;check key debounce counter

BEQ VBIDONE ;if zero, skip

DEC KEYDB ;otherwise decrease by one

VBIDONE PLA

TAY ;POP Y

PLA

TAX ;POP X

PLA ;POP A

RTI


 

I'm glad that's finally out of the way!

calamari

 

[ 03-04-2002: Message edited by: calamari ]

Link to comment
Share on other sites

Okay you're going to have to explain this one to me. The ANALOG article mentions that the debounce circuit does not have to be set on the 5200.

 

I also looked at the BIOS and I don't see where this count down is taking place. Am I missing it? The VBI does the timer, checks the critical code, updates DLISTH, DLISTL , and DMACTL from the shadows, check the attract mode, and update the POT registers. Where is it?

Link to comment
Share on other sites

DEBRO,

 

Okay, let me try again! Take a look at the code while you read this, too.

 

You're right, we aren't going to use any debounce circuitry (I tried setting that debounce enable bit and it would lock up the keypad on the real 5200). So, that means we have to make our own little debouncer algorithm.

 

The first step to doing that is understanding where the problems are and what we want to happen instead. On the real 5200, SKSTAT doesn't act like it does on the emulator (take a look at DEBUG52, and view address $E80F.. see how it is $FF then stays $FB while a key is pressed? Not so on the 5200, it is mostly $FF with an occasional $FB). So, we can't use SKSTAT to tell us when the key is no longer held. And there is no interrupt that is fired when a key is released, so it would seem that we are out of options... except we can use time to our advantage.

 

Have you ever used a tape recorder with the little counter on it, where if you push the button it resets the counter to all zeros, then if you let go it starts counting upward again? That's exactly what we are going to do. When a keypad button is held it continually sets our fake debounce counter to 3. Then, when we let go of the keypad button the vertical blanking interrupt subtracts 1 from it each time it's called (every 1/60th of a second or so). So, if a key is not pushed then this counter will eventually hit zero, but it will take time to do so.

 

When we are deciding whether to accept a new keystroke or not, first we'll check this counter.. if its zero, then we are pretty sure there is no key being held so we accept the new key.

 

If its not zero, then the key might still be held.. but, if the key is different from last time then the last one its obviously not being held so we accept the new key.

 

Otherwise, the new key is rejected.

 

Hope that helps,

calamari

Link to comment
Share on other sites

Sorry, I see what you're doing now. You are writing your own debounce routine. When I first read it I thought you were using a routine from the BIOS.

 

Did you try using the keypad interrupt for your repeat check? Since the keypad interrupt is only called when a key is pressed (at least on the emulators )then the repeat could be solved that way. You could use a gamestate variable to hold off whether the player is on the selection screen or in game play. Then only use the keys that are relevent to the gamestate. Then you would use possibly two bytes (key pressed and gamestate) as opposed to 3.

 

Just a thought but your idea is a good one too.

Link to comment
Share on other sites

  • 2 months later...

* BUMP *

 

OldGuru tried the technique I described above and confirmed that the key repeat problem happens with the interrupt too. After looking at the Tempest disassembly I saw that they use a debounce routine too.

 

Here is what is done...

 

Variable $029E is incremented in the VBI until it reaches #$80.

 

This variable is then used in the keypad interrupt. When ever the keypad is pressed the variable is reset to #$00. If the value before entering the routine is less than #$05 the keypad routine is skipped.

 

Here's a snipplet:

code:


VBIDeferred

.

.

.

L8106

lda keypadDebounce

bmi L810E

inc keypadDebounce

 

L810E

jsr L9C00

.

.

.

KBCodeVector

ldx keypadDebounce ; Get keypad debounce value

ldy #$00

sty keypadDebounce ; Reset keypad debounce value

sty ATRACT ; Reset attract mode

cpx #$05 ; if keypad debounce < #$05 leave keypad routine

bcc ExitKBCodeVector

.

.

.

Link to comment
Share on other sites

Wow that's not too far off from my routine (of course it looks to be a little more efficient). That's cool.. it makes me feel like I know what I'm doing

 

Thanks,

calamari

 

p.s. I haven't been doing much on Solitare lately.. All I've been doing is going to work and school. I still need to write my new sprite routine, and it's turning out to be more of a challenge than I expected. Once I get it, it will be great though!

Link to comment
Share on other sites

I still haven't put in a keypad debounce into Koffi. The most irritating thing is to try and select which level / stage with a repeating keypad button!

 

Once I get the Pocket Programmer, I'll feel safer about throwing this in & testing it out for myself.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...