/* Hook for MIDI serial driver */ void (*atari_MIDI_interrupt_hook) (void); /* Hook for keyboard inputdev driver */ void (*atari_input_keyboard_interrupt_hook) (unsignedchar, char); /* Hook for mouse inputdev driver */ void (*atari_input_mouse_interrupt_hook) (char *);
EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
/* variables for IKBD self test: */
/* state: 0: off; >0: in progress; >1: 0xf1 received */ staticvolatileint ikbd_self_test; /* timestamp when last received a char */ staticvolatileunsignedlong self_test_last_rcv; /* bitmap of keys reported as broken */ staticunsignedlong broken_keys[128/(sizeof(unsignedlong)*8)] = { 0, };
/* ++roman: If a keyboard overrun happened, we can't tell in general how much *byteshavebeenlostandinwhichstateofthepacketstructurewearenow. *Thisusuallycauseskeyboardsbytestobeinterpretedasmousemovements *andviceversa,whichisveryannoying.Itseemsbettertothrowawaysome *bytes(thatareusuallymousebytes)thantomisinterpretthem.ThereforeI *introducedtheRESYNCstateforIKBDdata.Inthisstate,thebytesupto *onethatreallylookslikeakeyevent(0x04..0xf2)orthestartofamouse *packet(0xf8..0xfb)arethrownaway,butatmost2bytes.Thisatleast *speedsuptheresynchronizationoftheeventstructure,evenifmaybea *mousemovementislost.However,nothingisperfect.Forbytes0x01..0x03, *it'sreallyhardtodecidewhetherthey'remouseorkeyboardbytes.Since *overrunsusuallyoccurwhenmovingtheAtarimouserapidly,they'reseenas *mousebyteshere.Ifthisiswrong,onlyamakecodeofthekeyboardgets *lost,whichisn'ttoobad.Losingabreakcodewouldbedisastrous, *becausethenthekeyboardrepeatstrikes...
*/
static irqreturn_t atari_keyboard_interrupt(int irq, void *dummy)
{
u_char acia_stat; int scancode; int break_flag;
repeat: if (acia.mid_ctrl & ACIA_IRQ) if (atari_MIDI_interrupt_hook)
atari_MIDI_interrupt_hook();
acia_stat = acia.key_ctrl; /* check out if the interrupt came from this ACIA */ if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ)) return IRQ_HANDLED;
if (acia_stat & ACIA_OVRN) { /* a very fast typist or a slow system, give a warning */ /* ...happens often if interrupts were disabled for too long */
pr_debug("Keyboard overrun\n");
scancode = acia.key_data; if (ikbd_self_test) /* During self test, don't do resyncing, just process the code */ goto interpret_scancode; elseif (IS_SYNC_CODE(scancode)) { /* This code seem already to be the start of a new packet or a
* single scancode */
kb_state.state = KEYBOARD; goto interpret_scancode;
} else { /* Go to RESYNC state and skip this byte */
kb_state.state = RESYNC;
kb_state.len = 1; /* skip max. 1 another byte */ goto repeat;
}
}
if (acia_stat & ACIA_RDRF) { /* received a character */
scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */
interpret_scancode: switch (kb_state.state) { case KEYBOARD: switch (scancode) { case0xF7:
kb_state.state = AMOUSE;
kb_state.len = 0; break;
case0xF1: /* during self-test, note that 0xf1 received */ if (ikbd_self_test) {
++ikbd_self_test;
self_test_last_rcv = jiffies; break;
}
fallthrough;
default:
break_flag = scancode & BREAK_MASK;
scancode &= ~BREAK_MASK; if (ikbd_self_test) { /* Scancodes sent during the self-test stand for broken *keys(keysbeingdown).Thecode*should*beabreak *code,butneverthelesssomeATkeyboardinterfacessend *makecodesinstead.Therefore,simplyignore *break_flag...
*/ int keyval, keytyp;
pr_warn("Key with scancode %d ", scancode); if (keytyp == KT_LATIN || keytyp == KT_LETTER) { if (keyval < ' ')
pr_cont("('^%c') ", keyval + '@'); else
pr_cont("('%c') ", keyval);
}
pr_cont("is broken -- will be ignored.\n"); break;
} elseif (test_bit(scancode, broken_keys)) break;
if (atari_input_keyboard_interrupt_hook)
atari_input_keyboard_interrupt_hook((unsignedchar)scancode, !break_flag); break;
} break;
case AMOUSE:
kb_state.buf[kb_state.len++] = scancode; if (kb_state.len == 5) {
kb_state.state = KEYBOARD; /* not yet used */ /* wake up someone waiting for this */
} break;
case RMOUSE:
kb_state.buf[kb_state.len++] = scancode; if (kb_state.len == 3) {
kb_state.state = KEYBOARD; if (atari_input_mouse_interrupt_hook)
atari_input_mouse_interrupt_hook(kb_state.buf);
} break;
ikbd_self_test = 1;
ikbd_reset(); /* wait for a period of inactivity (here: 0.25s), then assume the IKBD's
* self-test is finished */
self_test_last_rcv = jiffies; while (time_before(jiffies, self_test_last_rcv + HZ/4))
barrier(); /* if not incremented: no 0xf1 received */ if (ikbd_self_test == 1)
pr_err("Keyboard self test failed!\n");
ikbd_self_test = 0;
// flag init done
atari_keyb_done = 1; return0;
}
EXPORT_SYMBOL_GPL(atari_keyb_init);
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.