| 134 | } |
| 135 | |
| 136 | void Sio2::Pad() |
| 137 | { |
| 138 | MultitapProtocol& mtap = g_MultitapArr.at(port); |
| 139 | PadBase* pad = Pad::GetPad(port, mtap.GetPadSlot()); |
| 140 | |
| 141 | // Update the third nibble with which ports have been accessed |
| 142 | if (this->CmdStat & CmdStat::ONE_PORT_OPEN) |
| 143 | { |
| 144 | this->CmdStat &= ~(CmdStat::ONE_PORT_OPEN); |
| 145 | this->CmdStat |= CmdStat::TWO_PORTS_OPEN; |
| 146 | } |
| 147 | else |
| 148 | { |
| 149 | this->CmdStat |= CmdStat::ONE_PORT_OPEN; |
| 150 | } |
| 151 | |
| 152 | // This bit is always set, whether the pad is present or missing |
| 153 | this->CmdStat |= CmdStat::NO_DEVICES_MISSING; |
| 154 | |
| 155 | // If the currently accessed pad is missing, also tick those bits |
| 156 | if (pad->GetType() == Pad::ControllerType::NotConnected || pad->ejectTicks) |
| 157 | { |
| 158 | if (!port) |
| 159 | { |
| 160 | this->CmdStat |= CmdStat::PORT_1_MISSING; |
| 161 | } |
| 162 | else |
| 163 | { |
| 164 | this->CmdStat |= CmdStat::PORT_2_MISSING; |
| 165 | } |
| 166 | } |
| 167 | |
| 168 | g_Sio2FifoOut.push_back(0xff); |
| 169 | pad->SoftReset(); |
| 170 | |
| 171 | // Then for every byte in g_Sio2FifoIn, pass to PAD and see what it kicks back to us. |
| 172 | while (!g_Sio2FifoIn.empty()) |
| 173 | { |
| 174 | // If the pad is "ejected", respond with nothing |
| 175 | if (pad->ejectTicks) |
| 176 | { |
| 177 | g_Sio2FifoIn.pop_front(); |
| 178 | g_Sio2FifoOut.push_back(0xff); |
| 179 | } |
| 180 | // Else, actually forward to the pad. |
| 181 | else |
| 182 | { |
| 183 | const u8 commandByte = g_Sio2FifoIn.front(); |
| 184 | g_Sio2FifoIn.pop_front(); |
| 185 | const u8 responseByte = pad->SendCommandByte(commandByte); |
| 186 | g_Sio2FifoOut.push_back(responseByte); |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | // If the pad is "ejected", then decrement one tick. |
| 191 | // This needs to happen AFTER anything else which might |
| 192 | // consider if the pad is "ejected"! |
| 193 | if (pad->ejectTicks) |
no test coverage detected