Jump to content
IGNORED

question about joysticks and how they are read


Shannon
 Share

Recommended Posts

5 hours ago, Pat Brady said:

Questions:

  1. Currently I don't set the controller flag in the a78 header. Should I?
  2. Can you see anything wrong with my code?
  3. Does the second write to INPTCTRL even do anything, since the first write locked it?

1. actually, a7800 isn't yet supporting auto-switch for controllers via the header, so it doesn't matter for it.

2. Nothing jumps out at me. It would be instructive to know if disabletwobutton actually ran or not. TBH I'm not really sure if INPT4 can actually be read reliably in two button mode, despite the caution and suggested action in the guide and forums.

3. Yes, even though the register is used with the INPTCTRL name, it's actually writing to the TIA vblank register. The two button controllers require the paddle lines to not be grounded out, for obvious reasons.

  • Thanks 1
Link to comment
Share on other sites

30 minutes ago, RevEng said:

1. actually, a7800 isn't yet supporting auto-switch for controllers via the header, so it doesn't matter for it.

2. Nothing jumps out at me. It would be instructive to know if disabletwobutton actually ran or not. TBH I'm not really sure if INPT4 can actually be read reliably in two button mode, despite the caution and suggested action in the guide and forums.

3. Yes, even though the register is used with the INPTCTRL name, it's actually writing to the TIA vblank register. The two button controllers require the paddle lines to not be grounded out, for obvious reasons.

 

1. Okay, that works for me.

2. It turned out my reset-switch debounce loop covered almost all of my initialization code. (I certainly don't remember why I ever thought that was a good idea.) Not sure why that matters, I wasn't holding down the reset switch, but after I reduced that loop to the minimum (lda SWCHB, lsr, bcc), the 2600 one-button controller works fine. So now just gotta make Genesis work. I think I have the polarity wrong on button C, not sure that completely explains what's happening, but hopefully I can figure it out from here.

3. I think I understand. INPTCTRL is a MARIA register, VBLANK is a TIA register, both are mapped to $01, and the idea is to enable and lock INPTCTRL, then write the desired VBLANK values.

  • Like 2
Link to comment
Share on other sites

Got all 3 controller types working. Thanks to @Trebor and @RevEng for your help. Here is my startup code:

 

start
        sei ; disable maskable interrupts
        cld ; clear decimal mode

        lda #$07
        sta INPTCTRL ; lock into 7800 mode (7800 Stds&Procs)
        ldy #$00 ; use Y: it will persist while A does other stuff
        sty VBLANK ; aka INPTCTRL; also enables HALT per enhanced 7800 SG

        sty OFFSET ; "for future expansion" (7800 SG, 7800 Stds&Procs)
        sty CTLSWA ; controllers are input-only

        ; do any other startup code here

        lda INPT1
        bmi initgenesis ; b if pin 9 (7800 L or Genesis C) is 1

        ; if Genesis not detected, assume 7800 2-button controller, can change
        ; to 2600 1-button later
        lda #$04
        sta CTLSWB ; enable 2-button 7800 controller 1: set pin 6 to output
        sty SWCHB ; enable 2-button 7800 controller 2: pull pin 6 (INPT4) high
        sty ctrltype ; 0: 2-button 7800 controller
        bne reset ; based on lda #$04; always b

initgenesis
        sty CTLSWB ; set all pins to input
        iny
        sty ctrltype ; any non-0 +ve: Genesis controller

reset
        lda #$63
        sta CTRL ; disable DMA (for now) (7800 Stds&Procs)
        ldy #$00 ; use Y: it will persist while A does other stuff
        ; turn off audio
        sty AUDV0
        sty AUDV1
        ldx #$FF
        txs ; initialize stack pointer

 

And here is my button-read routine:

        subroutine ; jsr
readbuttons
        ; read controller buttons
        ; return value: $00: no button, $80: left/B button, $40: right/A button
        ; preserves X,Y
        lda ctrltype
        bne .readgssor2600
        bit INPT4 ; 2600 button (or Genesis B)
        bmi .read7800

        ; disable 2-button 7800 controller
        lda #$04
        sta SWCHB ; don't pull pin 6 (INPT4) high
        lda #$00
        sta CTLSWB ; set pin 6 to input
        lda #$FF
        sta ctrltype ; any -ve number: send next read to .read2600
.lbuttonpressed
        lda #$80 ; bit 7
        rts

.readgssor2600 ; Genesis or 2600 controller
        bmi .read2600
        bit INPT4 ; Genesis B
        bpl .lbuttonpressed
        bit INPT1 ; Genesis C
        bmi .nobutton
.rbuttonpressed
        lda #$40 ; bit 6
        rts

.read7800
        bit INPT4L ; L button
        bmi .lbuttonpressed
        bit INPT4R ; R button
        bmi .rbuttonpressed
.nobutton
        lda #$00 ; no button
        rts

.read2600 ; 2600 (1-button) controller
        ; separate from Genesis handler to prevent spurious Genesis C reads
        bit INPT4
        bpl .lbuttonpressed
        bmi .nobutton ; always b

 

Everyone feel free to use this in your project, with or without modifications. (Depending on your project, you might want to swap the button prioritization, or detect both buttons pressed…)

 

EDIT: my game is one-player. For a two-player game (or a one-player game using two controllers), initialize CTLSWB to #$14 instead of #$04. You may also want to add code for mixed controllers.

  • Like 6
  • Thanks 1
Link to comment
Share on other sites

18 hours ago, Pat Brady said:

Got all 3 controller types working. Thanks to @Trebor and @RevEng for your help. Here is my startup code:

 


start
        sei ; disable maskable interrupts
        cld ; clear decimal mode

        lda #$07
        sta INPTCTRL ; lock into 7800 mode (7800 Stds&Procs)
        ldy #$00 ; use Y: it will persist while A does other stuff
        sty VBLANK ; aka INPTCTRL; also enables HALT per enhanced 7800 SG

        sty OFFSET ; "for future expansion" (7800 SG, 7800 Stds&Procs)
        sty CTLSWA ; controllers are input-only

        ; do any other startup code here

        lda INPT1
        bmi initgenesis ; b if pin 9 (7800 L or Genesis C) is 1

        ; if Genesis not detected, assume 7800 2-button controller, can change
        ; to 2600 1-button later
        lda #$04
        sta CTLSWB ; enable 2-button 7800 controller 1: set pin 6 to output
        sty SWCHB ; enable 2-button 7800 controller 2: pull pin 6 (INPT4) high
        sty ctrltype ; 0: 2-button 7800 controller
        bne reset ; based on lda #$04; always b

initgenesis
        sty CTLSWB ; set all pins to input
        iny
        sty ctrltype ; any non-0 +ve: Genesis controller

reset
        lda #$63
        sta CTRL ; disable DMA (for now) (7800 Stds&Procs)
        ldy #$00 ; use Y: it will persist while A does other stuff
        ; turn off audio
        sty AUDV0
        sty AUDV1
        ldx #$FF
        txs ; initialize stack pointer

 

And here is my button-read routine:


        subroutine ; jsr
readbuttons
        ; read controller buttons
        ; return value: $00: no button, $80: left/B button, $40: right/A button
        ; preserves X,Y
        lda ctrltype
        bne .readgssor2600
        bit INPT4 ; 2600 button (or Genesis B)
        bmi .read7800

        ; disable 2-button 7800 controller
        lda #$04
        sta SWCHB ; don't pull pin 6 (INPT4) high
        lda #$00
        sta CTLSWB ; set pin 6 to input
        lda #$FF
        sta ctrltype ; any -ve number: send next read to .read2600
.lbuttonpressed
        lda #$80 ; bit 7
        rts

.readgssor2600 ; Genesis or 2600 controller
        bmi .read2600
        bit INPT4 ; Genesis B
        bpl .lbuttonpressed
        bit INPT1 ; Genesis C
        bmi .nobutton
.rbuttonpressed
        lda #$40 ; bit 6
        rts

.read7800
        bit INPT4L ; L button
        bmi .lbuttonpressed
        bit INPT4R ; R button
        bmi .rbuttonpressed
.nobutton
        lda #$00 ; no button
        rts

.read2600 ; 2600 (1-button) controller
        ; separate from Genesis handler to prevent spurious Genesis C reads
        bit INPT4
        bpl .lbuttonpressed
        bmi .nobutton ; always b

 

Everyone feel free to use this in your project, with or without modifications. (Depending on your project, you might want to swap the button prioritization, or detect both buttons pressed…)

 

EDIT: my game is one-player. For a two-player game (or a one-player game using two controllers), initialize CTLSWB to #$14 instead of #$04. You may also want to add code for mixed controllers.

Thanks! I was just creating the joystick driver in cc65 and this appears to be a pretty good base for an atari7800-stdjoy driver. In the cc65 you need to query separately for joystick 1 and joystick 2 so my code would return a byte with RLDU..21 meaning:
Right
Left
Down
Up
X

X

Button 2
Button1
 

The returned byte would look identical for both joysticks.

 

  • Like 2
Link to comment
Share on other sites

  • 1 month later...

Is there a conflict in 2 joystick mode with the Genesis joystick and the 2-button 7800 joystick?

 

In the Genesis case CTLSWB has all pins as inputs while 2-button 7800 has CTLSWB $14 (two pins as outputs).

 

I am trying to figure out a good stdjoy driver for cc65 that would allow people to use the hardware they have. The best option right now is to have this driver for a single joystick. But I wonder if it is safe to use the Genesis stick with CTLSWB pins required by 2-button 7800 joystick set as outputs?

 

Edit: I found a wonderful description about these issues! "Universal" Joystick schematic for 2600, 7800, SMS, Untested - Hardware - AtariAge Forums

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

  • Recently Browsing   0 members

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