Jump to content
IGNORED

Trying to figure out Keyboard Controllers / INPT*


hendersonn

Recommended Posts

Hello, I've come across two posts about polling the keyboard controller's inputs. (LINK; There was another for bB, but I'm not using that) as well as some outside sources (LINK). I don't know if I'm overthinking it or what, but I can't seem to get any readings from Stella. From what I can tell, you set the DDR bits to output(all or just one row at a time?), wait a moment (do I make them input again?) then read the column(s)? Stella's programmer's guide is pretty vague on this, so I've been kinda shooting in the dark and hoping something would work. ;-)

 

For good measure, here's some test code that I'm using, although it is totally useless.

	lda #%10011001
	sta PF1

	lda #$FF
	sta SWCHA

	ldy #120
Wait	dey
	bne Wait

	;lda #%00000001
	bit INPT4
	;bne Next
	bpl Next
	lda #%11111111
	sta PF1

Next

If I've missed a thread that explains this, please point me to it. Thanks.

Edited by hendersonn
Link to comment
Share on other sites

There's a couple of things that might be wrong. First is remember you have to tell Stella that you are using a keypad controller. You also have to do this each time you build a new rom, as Stella uses a checksum to determine the properties for a rom. For the left controller do this, and then close the rom and reload:

 

post-7074-0-63900500-1452148835_thumb.png

 

 

The second thing is make sure you set the DDR appropriately. You only need to do this once. Here it is for the left controller:

    lda    #$F0
    sta    SWACNT

I made a test rom using the code you linked to from alex_79. It works, you just have to tell Stella it is a keypad.

 

 

post-7074-0-30001900-1452149513_thumb.png

keypad.zip

 

 

In Stella, the left keypad maps like this to your computer keyboard:

Keypad      Computer
 1,2,3 ---> 1,2,3
 4,5,6 ---> Q,W,E
 7,8,9 ---> A,S,D
 *,0,# ---> Z,X,C
  • Like 1
Link to comment
Share on other sites

I've never had to change input settings when I ran SynthCart though Stella, same with Breakout and the paddle controllers... Unless my memory has completely failed.
I'll give it a try, thanks.

 

EDIT: My memory must have failed me. Thanks for the sample code, I'll comb through it.

Edited by hendersonn
Link to comment
Share on other sites

I've never had to change input settings when I ran SynthCart though Stella, same with Breakout and the paddle controllers... Unless my memory has completely failed.

I'll give it a try, thanks.

 

EDIT: My memory must have failed me. Thanks for the sample code, I'll comb through it.

Stella generates an MD5 code for the ROM that's being run and uses it to access an internal database. For Space Invaders the database has:

  { "72ffbef6504b75e69ee1045af9075f66", "Atari, Richard Maurer - Sears", "CX2632 - 49-75153", "Space Invaders (1980) (Atari)", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }, 

While Breakout has:

  { "f34f08e5eb96e500e851a80be3277a56", "Atari, Brad Stewart - Sears", "CX2622 - 6-99813, 49-75107", "Breakout (1978) (Atari)", "Uses the Paddle Controllers", "", "", "", "", "", "", "", "PADDLES", "PADDLES", "", "01", "", "", "", "", "" }, 

And Basic Programming has:

  { "9f48eeb47836cf145a15771775f0767a", "Atari, Warren Robinett", "CX2620", "Basic Programming (1979) (Atari)", "Uses Keypad Controllers", "Rare", "", "", "", "", "", "", "KEYBOARD", "KEYBOARD", "", "", "", "", "", "YES", "" }, 

Anything that's "" means default value. JOYSTICK is the default, so Space Invaders has "" for the controller entries. PADDLES (for Breakout) and KEYBOARD (for Basic) are listed twice because the database keeps track of what's in each port because it's possible for a game to use 2 different types controllers at the same time:

  { "c1fdd44efda916414be3527a47752c75", "Parker Brothers, John Emerson", "PB5920", "G.I. Joe - Cobra Strike (1983) (Parker Bros)", "Uses the Paddle (left) and Joystick (right) Controllers", "", "", "", "", "", "", "", "PADDLES", "", "", "", "", "30", "", "", "" }, 

Stella uses an external database for any settings you change for a game - nice because if you change the controller then Stella will remember that for next time. For a game you're working on the MD5 value will be different for each version, so you have to change those settings once per version.

Link to comment
Share on other sites

Are there any resources available that explain the input ports a little more, I think that's where I'm getting stuck. Even when porting over the code that reads the ports, it isn't really doing anything- even with Stella set to Keyboard, the only visible effect on screen is from toggling the Joystick's fire button.

 

Give me a second to upload a sample...

 

Just to get a feel of how it works, I'm just trying to manipulate PF1 to show the change, nothing fancy.

broken.asm

Edited by hendersonn
Link to comment
Share on other sites

Are there any resources available that explain the input ports a little more, I think that's where I'm getting stuck. Even when porting over the code that reads the ports, it isn't really doing anything- even with Stella set to Keyboard, the only visible effect on screen is from toggling the Joystick's fire button.

 

Just to get a feel of how it works, I'm just trying to manipulate PF1 to show the change, nothing fancy.

You need to configure the RIOT port A pins to output as Omegamatrix pointed out before, else writes to SWCHA won't have any effect:

The second thing is make sure you set the DDR appropriately. You only need to do this once. Here it is for the left controller:

    lda    #$F0
    sta    SWACNT

 

Edited by alex_79
Link to comment
Share on other sites

So did I miss something in the Stella Programmer's Guide? Going over the two source codes, I'm curious about something: How do you know which Input Port to check(and when)? From what I can tell, 0,1, and 4 deal with Player0 and 2,3, and 5 deal with Player1, but I'm confused on which order you check them- or if it even matters.

Link to comment
Share on other sites

So did I miss something in the Stella Programmer's Guide? Going over the two source codes, I'm curious about something: How do you know which Input Port to check(and when)? From what I can tell, 0,1, and 4 deal with Player0 and 2,3, and 5 deal with Player1, but I'm confused on which order you check them- or if it even matters.

We used the hardware schematics in the archive section for the 2600 on this website. From there you can learn the electrical connections, and after a little digging figure out what pins connect to register bits. Here is a summary of the results:

Left Port (P0)
Pin 9 ---> INPT1
Pin 6 ---> INPT4
Pin 5 ---> INPT0
Pin 4 ---> SWCHA [D7]
Pin 3 ---> SWCHA [D6]
pin 2 ---> SWCHA [D5]
Pin 1 ---> SWCHA [D4]


Right Port (P1)
Pin 9 ---> INPT3
Pin 6 ---> INPT5
Pin 5 ---> INPT2
Pin 4 ---> SWCHA [D3]
Pin 3 ---> SWCHA [D2]
pin 2 ---> SWCHA [D1]
Pin 1 ---> SWCHA [D0]

Now this is a keypad (also from the archives section):

 

post-7074-0-29901100-1452479591_thumb.png

 

The important thing here is SWCHA makes row connections while INPTx makes column connections. We are using SWCHA for outputs to the rows, and reading INPTx for inputs of the columns.

 

To scan a keypad you need to read a INPTx (column), and determine which button in that column is pressed. You can figure out which button for that column is pressed by controlling the row inputs. Start with all rows having the same ouput, and then systematically change one row at a time and check the input. You also need a delay between changing SWCHA and reading INPTx because there are capacitors connected to the inputs. The capacitors can't be discharged or charged instantly.

 

For Alex's routine order is important as it is an optimized routine. Also it is meant for only one key being pressed at a time. There is a priority in it. Keys to the right have priorty in a row, and keys lower in a column have priority. To see this in action press and hold Key 1. If you press button any other button at the same time then the other button will be returned. Key 1 has the lowest priority.

Link to comment
Share on other sites

This is a bit Off Topic, but the atari cx85 keypad (for the 8-bit computer line), can be read by the 2600 according to the description and schematic in the "Atari CX85 Numerical Keypad Technical Reference Notes" document you can find here: http://www.atarimania.com/documents-atari-400-800-xl-xe-technical-documents_3_8.html.
The device has 17 keys and integrates logic that decodes the key matrix and outputs a 5bit value on pins 1 to 5 of the controller port. Pin 6 indicates when a key is pressed.
post-10599-0-07276800-1452604656_thumb.jpg

Here is an extract from the pdf:

Hardware Notes:
Keypad Interface and Timing

The keypad uses eight signals on the controller port. Posi-
tive 5 volts (+ 5 v) is on pin 7, and signal ground on pin 8. A
5-bit binary code is presented on pins 1 through 5, correspond-
ing to the signals FWD, BACK, LEFT, RIGHT and BPOT. A data
valid signal, presented on pin 6, corresponds to TRIGGER.
TRIGGER goes low to indicate a valid code.

Timing is as follows:

- With no key pressed, the code for the previously
pressed key remains on pins 1 through 5 and TRIGGER
remains high (logic 1 or True).

- When a key is pressed, the TRIGGER signal goes low
(logic 0 or False) and the keycode for that key is
established on pins 1 through 5.

- TRIGGER stays low as long as the key remains pressed.
When the key is released, TRIGGER returns high but
the keycode does not change.

- Two-key rollover handles simultaneous or multiple
keystrokes. If one or more additional keys are pressed
while the first key is still pressed, nothing happens; the
additional keys are locked out. When the first key is
released, TRIGGER goes high and the scanning elec-
tronics searches for the next active key in the se-
quence. TRIGGER then goes low and the new keycode
is presented.

After the system receives the TRIGGER signal there
is a slight delay before BPOT data is valid. This can be com-
pensated for by inserting a delay in your program. Details
about this timing difference are provided on page 5.

And here is the schematic:
post-10599-0-23340800-1452604658_thumb.png

These are the corrisponding registers when used on the 2600:

LEFT CONTROLLER PORT

BPOT = INPT0 D7
STICK = SWCHA D7 to D4
TRIGGER = INPT4 D7


RIGHT CONTROLLER PORT

BPOT = INPT2 D7
STICK = SWCHA D3 to D0
TIGGER = INPT5 D7


You still need a delay before reading the value of INPT0/INPT2 after the TRIGGER goes from LOW to HIGH (the above doc indicates 150us, but that's on the 8bit computer, I suppose on the 2600 you still need 400 us like on the standard keypads). Anyway, by looking at the truth table in the schematic, you could ignore the PADDLE line and just read the SWCHA bits: in that case you cannot detect the "ESC" key anymore (it will be read the same as the "0" key) but you can avoid the delay and still read the other 16 keys.


While it's not a good idea to write a game/software that relies on an uncommon controller like this one, it could still be added as a switchable option instead of the standard 2600 keypads, maybe with an autodetection routine.

Note that I don't own a CX85 so I haven't tested it on real hardware, but I'm quite confident it should work and support for it could be added to Stella emulator.

Link to comment
Share on other sites

Interesting; I wonder if a similar method could be used for new peripherals. Now that I think of it, I wonder if the CX-3000 utilized matrix decoding as well...

 

Edit: I didn't bother looking into the graduate, I see the motherboard is well populated, so it probably does.

Edited by hendersonn
Link to comment
Share on other sites

  • 4 years later...

I'm bumping this thread because I have questions.

I can make it so pressing only * works,


.readkeypad
    lda    #$FF
    ldx    #12
    clc
.new_row:
    ror
    sta    SWCHA

    ldy    #120        
.wait:
    dey
    bne    .wait

    bit    INPT0
    bpl    KeyPressed

But I can't make it so pressing only 1 works. I know that INPT0 checks to see if the first column is used, but nothing else. Also, why is it when I open the binary file in Stella for the first time, it automatically senses a button press?

Link to comment
Share on other sites

I have finally unlocked the key to this all (no pun intended). It all depends on the number of 'ror's. For example, to detect the key 1 press, you'd do this:


.readkeypad
    lda    #$FF
    clc

    ror        ; bottom row (*, 0, #)
    ror        ; second row (7, 8, 9)
    ror        ; third row (4, 5, 6)
    ror        ; top row (1, 2, 3)
    sta    SWCHA

    ldy    #120        
.wait:
    dey
    bne    .wait

    bit    INPT0       ; #1 and not 2 nor 3
    bpl    OneGotPressed 

To check for the number 4, you'd just remove a 'ror' from the top 'ror' foursome. I tested this code and it works in Stella. (provided you have the keypad on.) I still don't know why if joystick is on that it acts like 1 has been pressed so it does the thing I want a 1 press to do.

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...