- isr_data = isr_data>>1;
- if (dbit) isr_data |= 0x8000;
-
- // isr_data:
- // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // -----------------------------------------------------
- // Initial: *1 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0
- // XT IBM: b7 b6 b5 b4 b3 b2 b1 b0 | s1 s0 *1 0 0 0 0 0 after receiving **
- // XT Clone: b7 b6 b5 b4 b3 b2 b1 b0 | s1 *1 0 0 0 0 0 0 after receiving
- // AT: st pr b7 b6 b5 b4 b3 b2 | b1 b0 s0 *1 0 0 0 0 after receiving
- // AT**: pr b7 b6 b5 b4 b3 b2 b1 | b0 s0 *1 0 0 0 0 0 before stop bit **
+
+ // Timeout check
+ uint8_t t;
+ // use only the least byte of millisecond timer
+ asm("lds %0, %1" : "=r" (t) : "p" (&timer_count));
+ //t = (uint8_t)timer_count; // compiler uses four registers instead of one
+ if (isr_state == 0x8000) {
+ timer_start = t;
+ } else {
+ // This gives 2.0ms at least before timeout
+ if ((uint8_t)(t - timer_start) >= 3) {
+ ibmpc_isr_debug = isr_state;
+ ibmpc_error = IBMPC_ERR_TIMEOUT;
+ goto ERROR;
+
+ // timeout error recovery - start receiving new data
+ // it seems to work somehow but may not under unstable situation
+ //timer_start = t;
+ //isr_state = 0x8000;
+ }
+ }
+
+ isr_state = isr_state>>1;
+ if (dbit) isr_state |= 0x8000;
+
+ // isr_state: state of receiving data from keyboard
+ //
+ // This should be initialized with 0x8000 before receiving data and
+ // the MSB '*1' works as marker to discrimitate between protocols.
+ // It stores sampled bit at MSB after right shift on each clock falling edge.