Page 1 of 2

controller auto reset

Posted: Wed Jun 28, 2017 10:28 pm
by KanedaFr
Controller data is read by switching TL/TH
You have to switch them an even times.

What would happen if, by mistake, I switch them an odd times?
has the controller somekind of reset-to-defaut-after-X-ns feature ? or will my read be bugged for the rest of the game ? ;)

Re: controller auto reset

Posted: Wed Jun 28, 2017 10:53 pm
by TmEE co.(TM)
You'll eternally have wrong input if you don't do the switching right. TH and others remain what they were set by the code, they never magically change state if you wait, not even when you press reset. Only power-on-reset will reset controller ports IO to a predetermined state (and games use it to detect if there's a power on or a reset).

Re: controller auto reset

Posted: Thu Jun 29, 2017 9:19 am
by HardWareMan
I think it doesn't matter which level of TL/TH you will keep after periph access routine. Most important is switch it to default right before new periph access.

Some doubts I have with 6-button joypat. It is have timeout to fall back to LRUD from XYZM. But I don't know, will it work with TL/TH = 0 or not. We need it find out.

Re: controller auto reset

Posted: Thu Jun 29, 2017 11:53 am
by KanedaFr
It's exactly because of the 6B joypad that I asked this.

From what i know,

Code: Select all

asking ABC
wait vlank
asking XYZ
won't work

I remember a talk about how fast the reading should be to avoid "reset" for 6B pad, multiplayer,, .....

Re: controller auto reset

Posted: Thu Jun 29, 2017 5:45 pm
by Mask of Destiny
I'm not sure the exact reset value is known for the 6B controller. From looking at the PCB, it looks like it's probably using an RC-based timer which is probably going to vary in timing both from controller to controller and also with temperature. That said, the timing is such that if you have any kind of sane arrangement that polls the controllers once per frame, you'll never have a problem.

Re: controller auto reset

Posted: Thu Jun 29, 2017 6:43 pm
by Sik
On a 3 button controller it's literally just a MUX so it doesn't matter.

On a 6 button controller it increments a counter every time TH goes from 0 to 1. This part is important because a lot of people insist that the first step is $00 when it's $40, which can make things confusing if you aren't aware of it.

What I do is this:
  • $40 = first 3 button read (↑ ↓ ← → B C)
  • $00 = second 3 button read (A Start)
  • $40 = ignored
  • $00 = ignored
  • $40 = ignored
  • $00 = 6 button check
  • $40 = 6 button read (X Y Z Mode)
If the 6 button check fails, reading ends there since it must be a 3 button controller (where this doesn't matter). If the check passes, then the sequence ends at the $40, and when the controller resets, it'll be back at the first step. In other words, you probably want to make sure that TH = 1 when the reading is over if you know it's a 6 button controller.

If you leave TH = 0 at the end of the sequence, when it resets it'll go back to the second step on that list, and you need to adjust accordingly.

Re: controller auto reset

Posted: Thu Jun 29, 2017 11:58 pm
by Chilly Willy
I've done a TON of testing on official and third party controllers, and this is what I do for 6-button controllers:

Code: Select all

    pb = (vu8 *)0xa10003 + port*2;

    v1 = TH_CONTROL_PHASE(pb);                    /* - 0 s a 0 0 d u - 1 c b r l d u */
    val = TH_CONTROL_PHASE(pb);                   /* - 0 s a 0 0 d u - 1 c b r l d u */
    v2 = TH_CONTROL_PHASE(pb);                    /* - 0 s a 0 0 0 0 - 1 c b m x y z */
    val = TH_CONTROL_PHASE(pb);                   /* - 0 s a 1 1 1 1 - 1 c b r l d u */
where

Code: Select all

static u16 TH_CONTROL_PHASE(vu8 *pb)
{
    u16 val;

    *pb = 0x00; /* TH (select) low */
    asm volatile ("nop");
    asm volatile ("nop");
    val = *pb;

    *pb = 0x40; /* TH (select) high */
    val <<= 8;
    val |= *pb;

    return val;
}
6-button pads want TH high in between read cycles. So you start out with TH high. I don't read it because that data is superfluous. The pad keeps track of how many high-to-low-to-high transitions are done. After the last low-to-high transition, you MUST wait about 1/60th of a second or the pad won't respond correctly to the next read. That's why pad reading is generally done by the vblank int handler. I notice that sik's code doesn't do the last high-low-high cycle - that's needed to get the pad id (that sa1111 byte in the comment). That's part of identifying a six button controller from something else. Of course, Sega didn't make anything else that used the same protocol, but it's still part of it. I seem to remember a third party stick that didn't work right if you didn't do that last cycle. Official Sega pads can be stopped after any low-to-high transition and still respond correctly as long as you wait that 1/60th sec before trying to read it again. Some third party stick don't since all Sega games do the full four cycles.

Note, the code is from SGDK... which I helped with a few things, notably the controller code. I spent a lot of time with the Menacer, the Justifier, the Phazer, the SMS trackball, an SMS pad, sticks of all makes and models, a TeamPlayer, and a US mouse to get it all working on real hardware. :lol:

Re: controller auto reset

Posted: Fri Jun 30, 2017 12:53 am
by TmEE co.(TM)
Image

Technically you're not supposed to use the "1111" as ID, only the "0000" :P

Re: controller auto reset

Posted: Fri Jun 30, 2017 11:55 pm
by Miquel
And even more: you have to request z80 bus before anything. Sega hardware division making every day more sane people.

Re: controller auto reset

Posted: Sun Jul 02, 2017 5:58 pm
by Chilly Willy
TmEE co.(TM) wrote:Technically you're not supposed to use the "1111" as ID, only the "0000" :P
Yeah, sorry, misspoke on that... been a while (years) since I wrote that code. But you should still fetch it. His pseudo-code isn't doing that. Notice how they do four high-to-low-to-high transitions? His only does three. My point was that doesn't get the entire data packet, and a few odd-ball controllers won't work because of that.

Re: controller auto reset

Posted: Sun Jul 02, 2017 10:30 pm
by Sik
But wouldn't such controllers also break with games that only support 3 button controllers? (the whole point of automatic reset is to make that stuff work)

EDIT: I do recall some controllers break if you try to read too much though, and when the controller is just initialized it may be in an undefined state, so it's in your best interests to avoid using the controller as soon as you initialize the ports. Yeah, this problem has actually happened before.

Re: controller auto reset

Posted: Mon Jul 03, 2017 5:25 am
by r57shell
so short mind
viewtopic.php?f=23&t=2308

when I made ROM, was much smaller discussion :?

Re: controller auto reset

Posted: Mon Jul 03, 2017 6:36 pm
by Chilly Willy
Sik wrote:But wouldn't such controllers also break with games that only support 3 button controllers? (the whole point of automatic reset is to make that stuff work)

EDIT: I do recall some controllers break if you try to read too much though, and when the controller is just initialized it may be in an undefined state, so it's in your best interests to avoid using the controller as soon as you initialize the ports. Yeah, this problem has actually happened before.
From my memories (not always right), I had a third party six-button pad (with no mode button) that would work if you did ONE cycle per vblank (normal 3-button read), or if you did FOUR cycles per vblank (6-button read), and return garbage for anything else. My thought at the time was that whatever internal state machine (be it hardware or software) they used only checked for timeout at one cycle, or four cycles, but not two or three. Probably saved themselves two or three logic terms by skimping like that. :lol:

As to doing more cycles, I did once try this in a loop outside the vblank, and some controllers worked fine, but none of my official 6-button pads. Those needed the timeout period.

Re: controller auto reset

Posted: Wed Jul 05, 2017 6:22 pm
by Miquel
Chilly Willy wrote:Note, the code is from SGDK... which I helped with a few things, notably the controller code.
Chilly Willy wrote: From my memories (not always right), I had a third party six-button pad (with no mode button) that would work if you did ONE cycle per vblank (normal 3-button read), or if you did FOUR cycles per vblank (6-button read), and return garbage for anything else. My thought at the time was that whatever internal state machine (be it hardware or software) they used only checked for timeout at one cycle, or four cycles, but not two or three. Probably saved themselves two or three logic terms by skimping like that. :lol:
????
The SGDK reads the 3 button state in the 3rd cycle...

Re: controller auto reset

Posted: Wed Jul 05, 2017 8:03 pm
by Chilly Willy
You're looking at the 6-button code. The 3-button code does this

Code: Select all

static u16 read3Btn(u16 port)
{
    vu8 *pb;
    u16 val;

    pb = (vu8 *)0xa10003 + port*2;

    val = TH_CONTROL_PHASE(pb);                   /* - 0 s a 0 0 d u - 1 c b r l d u */
    val = ((val & 0x3000) >> 6) | (val & 0x003F); /* 0 0 0 0 0 0 0 0 s a c b r l d u */
    val ^= 0x00FF;                                /* 0 0 0 0 0 0 0 0 S A C B R L D U */

    return val | (JOY_TYPE_PAD3 << JOY_TYPE_SHIFT);
}
So it only does one cycle for the 3-button. Three button pads have a separate routine so that you spend as little time as possible banging on the hardware in the vblank. You can set the 6-button pad to use the 3-button routine if you want the most speed and don't need the extra features. Just do

Code: Select all

    JOY_setSupport(PORT_1, JOY_SUPPORT_3BTN);
Note that this won't work for pads connected to a team player or other tap, only pads connected directly to the console.