ibmpc: Parity error detection

Used for Auto-Switching support: tested with Copam K-430
This commit is contained in:
tmk 2021-10-12 18:12:15 +09:00
parent f9a2e202b9
commit eea8b36f0d
2 changed files with 32 additions and 3 deletions

View file

@ -326,15 +326,39 @@ inline void IBMPC::isr(void)
protocol = IBMPC_PROTOCOL_XT_IBM;
goto DONE;
}
}
}
break;
case 0b00010000:
case 0b10010000:
case 0b01010000:
case 0b11010000:
// AT-done
// TODO: parity check?
isr_debug = isr_state;
// Detect AA with parity error for AT/XT Auto-Switching support
// https://github.com/tmk/tmk_keyboard/wiki/IBM-PC-Keyboard-Converter#atxt-auto-switching
// isr_state: st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0
// 1 '0' 1 0 1 0 1 0 | 1 0 0 *1 0 0 0 0
if (isr_state == 0xAA90) {
error = IBMPC_ERR_PARITY_AA;
goto ERROR;
}
// parit bit check
{
// isr_state: st pr b7 b6 b5 b4 b3 b2 | b1 b0 0 *1 0 0 0 0
uint8_t p = (isr_state & 0x4000) ? 1 : 0;
p ^= (isr_state >> 6);
while (p & 0xFE) {
p = (p >> 1) ^ (p & 0x01);
}
if (p == 0) {
error = IBMPC_ERR_PARITY;
goto ERROR;
}
}
// stop bit check
if (isr_state & 0x8000) {
protocol = IBMPC_PROTOCOL_AT;
@ -373,7 +397,11 @@ DONE:
// buffer overflow
error = IBMPC_ERR_FULL;
}
goto END;
ERROR:
// inhibit: Use clock_lo() instead of inhibit() for ISR optimization
clock_lo();
END:
// clear for next data
isr_state = 0x8000;
NEXT:

View file

@ -79,7 +79,8 @@ POSSIBILITY OF SUCH DAMAGE.
// Error numbers
#define IBMPC_ERR_NONE 0
#define IBMPC_ERR_RECV 0x00
#define IBMPC_ERR_PARITY 0x01
#define IBMPC_ERR_PARITY_AA 0x02
#define IBMPC_ERR_SEND 0x10
#define IBMPC_ERR_TIMEOUT 0x20
#define IBMPC_ERR_FULL 0x40