// Sending out a command. The controller command, if any, gets sent here. // This is followed by the first byte for the keyboard or mouse. The // remaining bytes and any retransmits will be handled by the interrupt // handler. static void ps2_send_command(int controller_command, unsigned char* command, int length, int mouse) { int status; CYG_PRECONDITION(NULL == ps2_command, "Only one send command is allowed at a time"); CYG_PRECONDITION((KC_CONTROL_NULL != controller_command) || (NULL != command), "no-op"); CYG_PRECONDITION(!mouse || (KC_CONTROL_NULL == controller_command), "cannot combine controller and mouse commands"); ps2_command = command; ps2_command_index = 0; ps2_command_length = length; ps2_command_mouse = 0; ps2_command_ack = 0; if (KC_CONTROL_NULL != controller_command) { do { HAL_READ_UINT8(KC_STATUS, status); } while (status & KC_STATUS_INPB); HAL_WRITE_UINT8(KC_CONTROL, controller_command); } if (length > 0) { if (mouse) { do { HAL_READ_UINT8(KC_STATUS, status); } while (status & KC_STATUS_INPB); HAL_WRITE_UINT8(KC_CONTROL, KC_CONTROL_WRITE_AUX); } do { HAL_READ_UINT8(KC_STATUS, status); } while (status & KC_STATUS_INPB); HAL_WRITE_UINT8(KC_INPUT, command[0]); } }
int main(int argc, char** argv) { CYG_ASSERT( true, message); CYG_ASSERT( false, message); CYG_ASSERTC(true); CYG_ASSERTC(false); CYG_FAIL(message); CYG_CHECK_DATA_PTR( &argc, message); CYG_CHECK_DATA_PTR( 0, message); CYG_CHECK_FUNC_PTR( &main, message); CYG_CHECK_FUNC_PTR( 0, message); CYG_CHECK_DATA_PTRC(&argc); CYG_CHECK_DATA_PTRC(0); CYG_CHECK_FUNC_PTRC(&main); CYG_CHECK_FUNC_PTRC(0); CYG_PRECONDITION(true, message); CYG_PRECONDITION(false, message); CYG_PRECONDITIONC(true); CYG_PRECONDITIONC(false); CYG_POSTCONDITION(true, message); CYG_POSTCONDITION(false, message); CYG_POSTCONDITIONC(true); CYG_POSTCONDITIONC(false); CYG_LOOP_INVARIANT(true, message); CYG_LOOP_INVARIANT(false, message); CYG_LOOP_INVARIANTC(true); CYG_LOOP_INVARIANTC(false); CYG_INVARIANT(true, message); CYG_INVARIANT(false, message); CYG_INVARIANTC(true); CYG_INVARIANTC(false); CYG_TEST_PASS_FINISH("disabled assertions in C code do nothing"); return 0; }
static void ps2kbd_process_scancodes(void) { static int e0_seen = 0; static MWKEY pending_up = MWKEY_UNKNOWN; static int pending_scancode = 0; static int discard = 0; int scancode; int i; CYG_PRECONDITION(MWKEY_UNKNOWN == ps2kbd_current_key, "There should be no pending key"); if (MWKEY_UNKNOWN != pending_up) { ps2kbd_current_key = pending_up; ps2kbd_current_scancode = pending_scancode; ps2kbd_current_keydown = 0; pending_up = MWKEY_UNKNOWN; return; } while (MWKEY_UNKNOWN == ps2kbd_current_key) { // The ISR will manipulate the scancode buffer directly, so // interrupts have to be disabled temporarily. scancode = -1; cyg_drv_isr_lock(); if (ps2kbd_scancode_buffer_head != ps2kbd_scancode_buffer_tail) { scancode = ps2kbd_scancode_buffer[ps2kbd_scancode_buffer_tail]; ps2kbd_scancode_buffer_tail = (ps2kbd_scancode_buffer_tail + 1) % PS2KBD_SCANCODE_BUFSIZE; } cyg_drv_isr_unlock(); if (scancode == -1) { // No more data to be processed. break; } // Are we in one of the special sequences, where bytes should be // discarded? if (discard > 0) { discard -= 1; continue; } // A real scancode has been extracted. Are we in an E0 sequence? if (e0_seen) { e0_seen = 0; ps2kbd_current_keydown = (0 == (scancode & 0x0080)); scancode &= 0x007F; if ((scancode >= PS2KBD_E0_MIN) && (scancode <= PS2KBD_E0_MAX)) { ps2kbd_current_key = ps2kbd_e0_map[scancode - PS2KBD_E0_MIN]; ps2kbd_current_scancode = 0x80 + scancode - PS2KBD_E0_MIN; // Invent a key scancode } // We may or may not have a valid keycode at this time, so go // around the loop again to check for MWKEY_UNKNOWN continue; } // Is this the start of an E0 sequence? if (0x00E0 == scancode) { e0_seen = 1; continue; } // How about E1? if (0x00E1 == scancode) { // For now there is only one key which generates E1 sequences ps2kbd_current_key = MWKEY_BREAK; ps2kbd_current_keydown = 1; ps2kbd_current_scancode = 0x00E1; // Invent another key scancode pending_up = MWKEY_BREAK; pending_scancode = 0x00E1; discard = 5; return; } // Must be an ordinary key. ps2kbd_current_keydown = (0 == (scancode & 0x0080)); scancode &= 0x007F; ps2kbd_current_scancode = scancode; ps2kbd_current_key = ps2kbd_keymap[scancode].normal; // Detect the modifier keys. for (i = 0; MWKEY_UNKNOWN != ps2kbd_modifier_map[i].key; i++) { if (ps2kbd_current_key == ps2kbd_modifier_map[i].key) { // capslock etc. behave differently. Toggle the current // status on the keyup event, ignore key down (because // of hardware autorepeat). if (ps2kbd_modifier_map[i].toggle) { if (!ps2kbd_current_keydown) { ps2kbd_current_modifiers ^= ps2kbd_modifier_map[i].modifier; } } else if (ps2kbd_current_keydown) { ps2kbd_current_modifiers |= ps2kbd_modifier_map[i].modifier; } else { ps2kbd_current_modifiers &= ~ps2kbd_modifier_map[i].modifier; } break; } } // Cope with some of the modifiers. if (0 != (ps2kbd_current_modifiers & (MWKMOD_LCTRL | MWKMOD_RCTRL))) { // Control key. a-z and A-Z go to ctrl-A - ctrl-Z, i.e. 1 to 26 // Other characters in the range 64 to 96, e.g. [ and ], also // get translated. This includes the A-Z range. if ((64 <= ps2kbd_current_key) && (ps2kbd_current_key < 96)) { ps2kbd_current_key -= 64; } else if (('a' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'z')) { ps2kbd_current_key -= 96; } } else if (ps2kbd_current_modifiers & (MWKMOD_LSHIFT | MWKMOD_RSHIFT)) { // Pick up the shift entry from the keymap ps2kbd_current_key = ps2kbd_keymap[scancode].shifted; } if (ps2kbd_current_modifiers & MWKMOD_CAPS) { // Capslock only affects a-z and A-z if ( ('a' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'z')) { ps2kbd_current_key = (ps2kbd_current_key -'a') + 'A'; } else if (('A' <= ps2kbd_current_key) && (ps2kbd_current_key <= 'Z')) { ps2kbd_current_key = (ps2kbd_current_key -'A') + 'a'; } } // If we have found a real key, the loop will exit. // Otherwise try again. } }