hendersonn Posted January 7, 2016 Share Posted January 7, 2016 (edited) 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 January 7, 2016 by hendersonn Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted January 7, 2016 Share Posted January 7, 2016 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: 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. 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 1 Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 7, 2016 Author Share Posted January 7, 2016 (edited) 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 January 7, 2016 by hendersonn Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 7, 2016 Share Posted January 7, 2016 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. Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 7, 2016 Author Share Posted January 7, 2016 (edited) 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 January 7, 2016 by hendersonn Quote Link to comment Share on other sites More sharing options...
+SpiceWare Posted January 7, 2016 Share Posted January 7, 2016 While I doubt anything will ever come of this project, I did get keyboard to work. The source might help you. 1 Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 7, 2016 Author Share Posted January 7, 2016 I'll check it out when I get the chance, I appreciate it. Quote Link to comment Share on other sites More sharing options...
alex_79 Posted January 7, 2016 Share Posted January 7, 2016 (edited) 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 January 7, 2016 by alex_79 Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 10, 2016 Author Share Posted January 10, 2016 Progress, thanks for all the help! Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 11, 2016 Author Share Posted January 11, 2016 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. Quote Link to comment Share on other sites More sharing options...
Omegamatrix Posted January 11, 2016 Share Posted January 11, 2016 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): 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. Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 11, 2016 Author Share Posted January 11, 2016 Fantastic, thank you. Quote Link to comment Share on other sites More sharing options...
alex_79 Posted January 12, 2016 Share Posted January 12, 2016 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.Here is an extract from the pdf: Hardware Notes:Keypad Interface and TimingThe keypad uses eight signals on the controller port. Posi-tive 5 volts (+ 5 v) is on pin 7, and signal ground on pin 8. A5-bit binary code is presented on pins 1 through 5, correspond-ing to the signals FWD, BACK, LEFT, RIGHT and BPOT. A datavalid 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 previouslypressed key remains on pins 1 through 5 and TRIGGERremains 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 isestablished on pins 1 through 5.- TRIGGER stays low as long as the key remains pressed.When the key is released, TRIGGER returns high butthe keycode does not change.- Two-key rollover handles simultaneous or multiplekeystrokes. If one or more additional keys are pressedwhile the first key is still pressed, nothing happens; theadditional keys are locked out. When the first key isreleased, 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 keycodeis presented.After the system receives the TRIGGER signal thereis a slight delay before BPOT data is valid. This can be com-pensated for by inserting a delay in your program. Detailsabout this timing difference are provided on page 5. And here is the schematic:These are the corrisponding registers when used on the 2600:LEFT CONTROLLER PORTBPOT = INPT0 D7STICK = SWCHA D7 to D4TRIGGER = INPT4 D7RIGHT CONTROLLER PORTBPOT = INPT2 D7STICK = SWCHA D3 to D0TIGGER = INPT5 D7You 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. Quote Link to comment Share on other sites More sharing options...
hendersonn Posted January 15, 2016 Author Share Posted January 15, 2016 (edited) 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 January 15, 2016 by hendersonn Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted August 5, 2020 Share Posted August 5, 2020 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? Quote Link to comment Share on other sites More sharing options...
+atari2600land Posted August 6, 2020 Share Posted August 6, 2020 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.