Jump to content
Sign in to follow this  
Clay Cowgill

5200: keyboard reading magic? (KBCODE $E809)

Recommended Posts

Hi everyone.

 

Ok, I'm getting myself pretty confused right now. (damn emulators! ;-)

 

Is there any magic required as far as reading KBCODE ($E809)? Is it only valid at particular times?

 

Is there any reason I can't poll KBCODE inside the VBI?

 

(I have a nice little 'pause' routine that works JUST FINE while emulated, but it appears on the real hardware I've never getting a value from KBCODE... KBCODE should be the results from the keyboard scan right? Is there something I need to set to make sure it's looking at the right port? I'm already setting the pots to scan in CONSOL...)

 

Thanks,

-Clay

Share this post


Link to post
Share on other sites

I would use the VKYBDF interrupt to read the keypad responce (others would differ). If you use the VKYBDF ($020A) then the BIOS will handle interputing the keypad value (if you point the VKYBDI vector to the BIOS routine at $FD02 of course). This way when you get to VKYBDF the accomulator will hold the keypad value for you.

 

Also, as noted in previous threads, you have to have a debounce routine too. The emulators don't show a key repeat but the real hardware does. Look at the Atari 5200 keypad repeat fix... SUCCESS !!! thread.

 

Also make sure you're setting CONSOL correctly. Here is a snip from the ANALOG article...

 

The bits in CONSOL, the 400/800's console switch port

(START, OPTION, SELECT and speaker), are used as outputs in

the 5200, Bit 3, the 400/800's speaker control can still be

toggled in the 5200 to produce sounds through the TV

speaker. Bit 2 controls the pots in the joystick

controllers. It must be set high to enable the pots.

 

Bits 1 and 0 select which controller port is to be active at

one time. 00 selects port #1 (the leftmost), 01 selects #2,

10 selects #3, and 11 selects #4. The trigger buttons and

pots are independent of this selection; it applies only to

the keypads and top side buttons on the controllers.

 

The emultors may let you get by without setting CONSOL correctly.

Share this post


Link to post
Share on other sites
I would use the VKYBDF interrupt to read the keypad responce (others would differ). If you use the VKYBDF ($020A) then the BIOS will handle interputing the keypad value (if you point the VKYBDI vector to the BIOS routine at $FD02 of course). This way when you get to VKYBDF the accomulator will hold the keypad value for you..

 

Yes, I've used that successfully elsewhere, but in this particular case I need to be inside the VBI while checking the keypad. AFAIK, POKEY *should* be merrily scanning the keyboard matrix and I'd think I should be able to read directly from the POKEY scan code register $E809-- and in fact it works that way with VSS and Atari800win.

 

Curiously enough, on the real hardware I never seem to get values that reflect the key being pressed. It's almost like the POKEY isn't scanning anymore. It's like I just get the old value over and over...

 

Maybe the converse is a good question-- is there anyway to turn OFF the POKEY keyscan? Does POTGO only work on the pots or could it be needed to re-scan the keys too?

 

Also, as noted in previous threads, you have to have a debounce routine too. The emulators don't show a key repeat but the real hardware does. Look at the Atari 5200 keypad repeat fix... SUCCESS !!! thread.

 

Yep, already took care of that myself. Just have a software timer in VBI to do the debounce.

 

Also make sure you're setting CONSOL correctly. Here is a snip from the ANALOG article...

[...]

 

I'm stuffing CONSOL with $0c (holding speaker line high, enabling pot reads, port 0 selected... Hmmmm. Maybe I need to switch to $08 to read the keypad? Have to look at the schematics...)

 

Thanks for the ideas. Got to be something in there...

 

-Clay

Share this post


Link to post
Share on other sites

Are you absolutely sure that you must do the Pause loop inside the VBI? You might instead set a flag, like:

 

LDA $01  

STA PAUSE

 

Then in the non VBI code you can test to see if PAUSE is non-zero, and if it is then do your wait-for-PAUSE loop. Something like this:

 

LDA   PAUSE

BEQ   NOPAUSE; was Pause mode set in the VBI?

PAUSE:       ; Yes

LDA   KEY    ;(this variable would be set by your keypad IRQ)

CMP   #$0D   ;Was Pause pressed?

BNE   PAUSE  ; If not, keep looking for it



NOPAUSE:

 

One thing I noticed when I first programmed for the 5200 (back in my early 5200 programming days when I was trying to do Moria) was that reading KBCODE in a loop never worked well at all. It would always miss keypresses, etc... so using the keypad interrupt is really the best way to go because you know you have a fresh keypress waiting. See if you can find a way to get around having to poll KBCODE directly, I suspect that is where the problem is.

 

calamari

Share this post


Link to post
Share on other sites
Are you absolutely sure that you must do the Pause loop inside the VBI?

 

Unfortunately, yes... Pretty much. :|

 

I have a rather large chunk of code that I'm not keen on monkeying with anymore than necessary (I didn't write it, just porting it). Once a game starts, the whole damn thing lives inside the VBI...

 

Using the key interrupts works just fine on the attract screen, but once the game fires up-- no more interrupts (since it's all inside VBI). Humph.

 

I think I've got it about working now though. I was setting CONSOL in close proximity to reading KBCODE... I'm wondering it that wasn't somehow making it angry. Odd at any rate.

 

Once I get pause happy I'll post a binary if anyone wants to check it out...

 

Thanks,

-Clay

Share this post


Link to post
Share on other sites
I forgot about SKCTL. Are you setting it for a keypad scan?

 

SKCTL is set to #$02, so I think that's OK. It is limping along now with polling in the VBI. I am getting a what I'm guessing is key-repeat. (Press 'pause' once and my code sees it indefinitely until another key is pressed.) I'll have to investigate that now...

 

-Clay

Share this post


Link to post
Share on other sites

Clay,

Could you print on the screen the value you read from $KBCODE?

You could write a short "debug" routine to print a byte on the screen and use it for that purpose. From my short experience it could speed things up.

I could send you mine if you wanted.

 

OG.

Share this post


Link to post
Share on other sites

Clay,

Could you print on the screen the value you read from $KBCODE?

You could write a short "debug" routine to print a byte on the screen and use it for that purpose. From my short experience it could speed things up.

I could send you mine if you wanted.

 

OG.

Share this post


Link to post
Share on other sites
Clay,

Could you print on the screen the value you read from $KBCODE?

You could write a short "debug" routine to print a byte on the screen and use it for that purpose. From my short experience it could speed things up.

I could send you mine if you wanted.

 

I'm in a bitmapped mode-- not 100% I know the string print routines well enough to get that to work. ;) I have been just writing KBCODE to screen memory to see if it "works" but it's a little tricky to read four-pixels worth of color on a TV...

 

I might just mod the display list to give me a text line and spit something out there.

 

Thanks!

-Clay

Share this post


Link to post
Share on other sites

I guess I don't understand the issue Clay. Even if you have the keypad inturrupt set it will fire even though your game resides in VBI. Is it the timing of the keypad? It shouldn't be noticable given that the VBI happens every 1/60th of a second.

 

Scanning KBCODE will be difficult. IIRC KBCODE will hold the last key press value until another key is pressed.

 

Try something like this ...

   gameState = $80                   ; any free RAM location you have

                                    ; now you could have the values be

                                    ; $00 = game in progress

                                    ; $40 = game paused

                                    ; $80 = game in menu

.

.

.

KeypadInterupt

.

.

.

PauseButtonPressed

  bit gameState

  bmi DoSomthingWithPauseInMenu
;
; game is either paused or in progress
;

  lda gameState

  eor #$40

  sta gameState

ExitInterupt

  jmp $FCB2                         ; the BIOS routine for pulling values

                                    ; from the stack and restoring them

Share this post


Link to post
Share on other sites
I guess I don't understand the issue Clay. Even if you have the keypad inturrupt set it will fire even though your game resides in VBI. Is it the timing of the keypad? It shouldn't be noticable given that the VBI happens every 1/60th of a second.

 

I don't think so... The 6502 sets the interrupt disable bit (bit 2 in the status register) when it's servicing an interrupt, so as long as that interrupt is being handled nobody else is getting any attention. The issue is that the code seems to go into VBI and never comes out-- since NMI is generated by Vblank from ANTIC and since the key IRQ (and serial and timers and all that) are from POKEY, if ANTIC has an NMI pending when the first NMI ends none of the POKEY interrupts will ever be serviced.

 

I'm not quite 100% sure what's going on at this point, but I do know that my keyboard interrupts work just fine until the game starts, at which point the status word seems to have bit 2 set indefinitely. There are no direct accesses to the interrupt disable bit (like from an SEI) and there does not appear to be any access indirectly (like from a PLP). What there *is* is a VBI that seems to never exit... I can dig into the engine in more detail, but I have better things to do than reverse engineer the whole thing, so I'm trying to hack it to make it work without understanding the whole thing. :D

 

(I guess I could maybe poll POKEY's IRQST register from inside NMI and jump out to a copy of the keyboard interrupt without an RTI when I see the key interrupt bit set. Hmmmm. That might work.)

 

Scanning KBCODE will be difficult. IIRC KBCODE will hold the last key press value until another key is pressed.

 

Yep. That is the behavior I'm seeing. I guess I'll need to setup a secondary variable that reports the keystate for a while and then resets after a few loops through my VBI interception hack...

 

Thanks for the ideas...

-Clay

Share this post


Link to post
Share on other sites

*light buld comes on*

 

Now, I understand. Your VBI is not doing a RTI at all. It's jumping back to the start of VBI.

 

I guess you could poll for the interrupt yourself as you stated.

 

You also could use a combination of KBCODE and bit 3 of SKSTAT to determine when the key is pressed.

Share this post


Link to post
Share on other sites
*light buld comes on*

You also could use a combination of KBCODE and bit 3 of SKSTAT to determine when the key is pressed.

 

Ding! We have a winner.

 

What I ended up doing was to just watch bit 3 of SKSTAT and use that as my method of entry to the key check routine. Works quite well now.

 

Here's a link to my project if you're interested in a look:

 

http://www.multigame.com/cc52e.rom

 

It's still a little early (no high-score table, no music on the title screen, title screen options don't carry through to the main game, but it's working well). I limited this to four levels and clear 'demo' status so as not to have any turn up as 'prototypes' on eBay or something!

 

The debug line on the bottom of the screen obscures the lives remaining display. The values shown are:

 

debug aa bb cc dd

aa= KBCODE

bb= SKCTL

cc= IRQST

dd= my debounce/lockout timer

 

the byte on the far right (cycling) is showing my VBI intercept is working.

 

If you push the 2nd fire button before the game starts you'll see a color change-- that was just proving that BRK interrupt was working then. Pressing a keypad button before the game starts will flash the background color, again just showing that that interrupt was working.

 

-Clay

Share this post


Link to post
Share on other sites

I KNEW IT!!! This had to be the game you were working on :) Excellent!!! I had thought of doing it myself too.

 

BTW are you doing Trakball support too?

Share this post


Link to post
Share on other sites

DEBRO wrote:

 

I KNEW IT!!! This had to be the game you were working on  Excellent!!! I had thought of doing it myself too.  

 

BTW are you doing Trakball support too?

 

HooooHoooooo!!!!! YEESS!! YIPEEE!! TTTHHHIISSS RROOCCKKSS!!!!!

 

Clay,

That's twice you have made my week. It looks awesome!! This also inspires me to get on the ball and get back to learning Assembly. As soon as I finish my secret project, (an interest to any of you old time Atari 8-bitters.) I am going to start messing around the 5200Bas as well as assembly. Now I am going to play CC52e on my 8-bit to get me in the mode.

 

By the way, as programmers on the Atari 8-bit/5200, is there any docs any of you would like to see other than whats at www.atariarchives.org and www.atarimagazines.com? Remember, I'm not the boss, just a worker, but I can certainly make suggestions to the big honcho. :)

 

Allan

Share this post


Link to post
Share on other sites
I KNEW IT!!! This had to be the game you were working on :) Excellent!!! I had thought of doing it myself too.

 

BTW are you doing Trakball support too?

 

Hee-hee. :) I'm about 11 days into it now. The first three were spent disassembling and hand-patching. I actually got the screen up on the first try in the emulator!

 

Spent another few days on graphics convertors, fonts, and the title screen. Then about two days making it work on a real 5200. My pause hack took a LOT longer than expected (the screen dim and stuff was easy, just that $#@!#$ pause key reading in VBI sucked).

 

Trakball is planned-- that's what the ability to choose one controller for two players is for. Being a hardware geek I'm doing high-score saves in the cartridge. I figure that'll be an interesting thing. AFAIK nobody did that yet?

 

-Clay

Share this post


Link to post
Share on other sites
HooooHoooooo!!!!! YEESS!! YIPEEE!! TTTHHHIISSS RROOCCKKSS!!!!!

 

Clay,

That's twice you have made my week. It looks awesome!!   This also inspires me to get on the ball and get back to learning Assembly.[...]

 

Glad you like it. As you can see the game engine is running 100%. No bugs that I've found yet. (At least nothing that isn't in the computer version. ;-)

 

I'm going to do a high-score table (with save) and maybe roll some more of the arcade stuff back in in spots. Also some more stuff on the title screen (music, graphic effects, etc.)

 

By the way, as programmers on the Atari 8-bit/5200, is there any docs any of you would like to see other than whats at www.atariarchives.org and www.atarimagazines.com? Remember, I'm not the boss, just a worker, but I can certainly make suggestions to the big honcho. :)

 

I still have all my stuff from 'back in the day', so I'm pretty set. For this project I used:

 

Mapping the Atari

Hardware Manual OS Listing

Atari Graphics and Arcade Game Design

 

...and then the 5200 BIOS disassembly from DanB's page and another BIOS listing with labels from some European site (maybe Czech?)

 

Oh, and a set of old engineering schematics for the 5200...

 

-Clay

Share this post


Link to post
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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...