/** * 키보드 LED의 ON/OFF를 변경 */ BOOL kChangeKeyboardLED( BOOL bCapsLockOn, BOOL bNumLockOn, BOOL bScrollLockOn ) { int i, j; BOOL bPreviousInterrupt; BOOL bResult; BYTE bData; // 인터럽트 불가 bPreviousInterrupt = kSetInterruptFlag( FALSE ); // 키보드에 LED 변경 커맨드 전송하고 커맨드가 처리될 때까지 대기 for( i = 0 ; i < 0xFFFF ; i++ ) { // 출력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능 if( kIsInputBufferFull() == FALSE ) { break; } } // 출력 버퍼(포트 0x60)로 LED 상태 변경 커맨드(0xED) 전송 kOutPortByte( 0x60, 0xED ); for( i = 0 ; i < 0xFFFF ; i++ ) { // 입력 버퍼(포트 0x60)가 비어있으면 키보드가 커맨드를 가져간 것임 if( kIsInputBufferFull() == FALSE ) { break; } } // ACK가 올때까지 대기함 bResult = kWaitForACKAndPutOtherScanCode(); if( bResult == FALSE ) { // 이전 인터럽트 상태 복원 kSetInterruptFlag( bPreviousInterrupt ); return FALSE; } // LED 변경 값을 키보드로 전송하고 데이터가 처리가 완료될 때까지 대기 kOutPortByte( 0x60, ( bCapsLockOn << 2 ) | ( bNumLockOn << 1 ) | bScrollLockOn ); for( i = 0 ; i < 0xFFFF ; i++ ) { // 입력 버퍼(포트 0x60)가 비어있으면 키보드가 LED 데이터를 가져간 것임 if( kIsInputBufferFull() == FALSE ) { break; } } // ACK가 올 때까지 대기함 bResult = kWaitForACKAndPutOtherScanCode(); // 이전 인터럽트 상태 복원 kSetInterruptFlag( bPreviousInterrupt ); return bResult; }
BOOL kChangeKeyboardLED( BOOL bCapsLockOn, BOOL bNumLockOn, BOOL bScrollLockOn ) { int i, j; BOOL bPreviousInterrupt; BOOL bResult; BYTE bData; // 인터럽트 불가 bPreviousInterrupt = kSetInterruptFlag( FALSE ); for( i = 0 ; i < 0xFFFF ; i++ ) { if( kIsInputBufferFull() == FALSE ) // 입력버퍼가 빌때까지 기다림 { break; } } // 출력 버퍼에 LED 상태 변경 한다는 커맨드 전송(0xED) kOutPortByte(0x60, 0xED); for( i = 0 ; i < 0xFFFF ; i++ ) { if(kIsInputBufferFull() == FALSE) // 입력 버퍼가 빌때까지 기다림 break; } // ACK를 기다림 bResult = kWaitForACKAndPutOtherScanCode(); if( bResult == FALSE ) { kSetInterruptFlag( bPreviousInterrupt ); return FALSE; } if ( j>= 100 ) // 일정 시간 이상 ACK가 안옴 return FALSE; // 2비트 , 1비트, 0비트에 따라 온을 시켜줌 kOutPortByte( 0x60, (bCapsLockOn << 2) | (bNumLockOn << 1) | bScrollLockOn ); for( i = 0 ; i < 0xFFFF ; i++ ) { if(kIsInputBufferFull() == FALSE) { break; } } bResult = kWaitForACKAndPutOtherScanCode(); kSetInterruptFlag(bPreviousInterrupt); return bResult; }
/** * 키보드를 활성화 함 */ BOOL kActivateKeyboard( void ) { int i, j; BOOL bPreviousInterrupt; BOOL bResult; // 인터럽트 불가 bPreviousInterrupt = kSetInterruptFlag( FALSE ); // 컨트롤 레지스터(포트 0x64)에 키보드 활성화 커맨드(0xAE)를 전달하여 키보드 디바이스 활성화 kOutPortByte( 0x64, 0xAE ); // 입력 버퍼(포트 0x60)가 빌 때까지 기다렸다가 키보드에 활성화 커맨드를 전송 // 0xFFFF만큼 루프를 수행할 시간이면 충분히 커맨드가 전송될 수 있음 // 0xFFFF 루프를 수행한 이후에도 입력 버퍼(포트 0x60)가 비지 않으면 무시하고 전송 for( i = 0 ; i < 0xFFFF ; i++ ) { // 입력 버퍼(포트 0x60)가 비어있으면 키보드 커맨드 전송 가능 if( kIsInputBufferFull() == FALSE ) { break; } } // 입력 버퍼(포트 0x60)로 키보드 활성화(0xF4) 커맨드를 전달하여 키보드로 전송 kOutPortByte( 0x60, 0xF4 ); // ACK가 올 때까지 대기함 bResult = kWaitForACKAndPutOtherScanCode(); // 이전 인터럽트 상태 복원 kSetInterruptFlag( bPreviousInterrupt ); return bResult; }
/** * 프로세서를 리셋(Reset) */ void kReboot( void ) { int i; // 입력 버퍼(포트 0x60)에 데이터가 비어있으면 출력 포트에 값을 쓰는 커맨드와 출력 포트 데이터 전송 for( i = 0 ; i < 0xFFFF ; i++ ) { // 입력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능 if( kIsInputBufferFull() == FALSE ) { break; } } // 커맨드 레지스터(0x64)에 출력 포트 설정 커맨드(0xD1)을 전달 kOutPortByte( 0x64, 0xD1 ); // 입력 버퍼(0x60)에 0을 전달하여 프로세서를 리셋(Reset)함 kOutPortByte( 0x60, 0x00 ); while( 1 ) { ; } }
BOOL kActivateKeyboard(void) { int i; int j; BOOL bPreviousInterrupt; BOOL bResult; // 인터럽트 막아놓고 원래의 상태를 저장 bPreviousInterrupt = kSetInterruptFlag( FALSE ); kOutPortByte(0x64, 0xAE); // 0x64(컨트롤(쓰기)레지스터에 0xAE 신호 발송 (키보드 디바이스 활성화) ) for( i = 0 ; i < 0xFFFF ; i++ ) { if (!kIsInputBufferFull()) // inputbuffer가 비었으면 키보드 활성화(디바이스X) 신호 보낼것 { break; } } kOutPortByte(0x60, 0xF4); // 0x60에 0xF4 전송 (입력버퍼로 키보드 활성화 키 전송) // ACK가 올때까지 기다림 bResult = kWaitForACKAndPutOtherScanCode(); // 이전 인터럽트 상태 복원 kSetInterruptFlag(bPreviousInterrupt); return bResult; }
void kEnableA20Gate( void ) { BYTE bOutputPortData; int i; // 키보드 컨트롤러 정보를 읽거나 쓰려면 미리 D0, D1 커맨드 신호를 보내야 한다. kOutPortByte( 0x64, 0xD0 ); // 키보드 컨트롤러의 출력 포트 값을 읽는 함수 for( i = 0 ; i < 0xFFFF ; i++ ) { if( kIsOutputBufferFull()) // 출력값이 있으면 { break; } } bOutputPortData = kInPortByte(0x60); // 출력값을 읽어냄 bOutputPortData |= 0x01; // 1인경우 A20Gate, 0인경우 리붓 for( i = 0 ; i < 0xFFFF ; i++ ) { if ( kIsInputBufferFull() == FALSE ) // 입력 버퍼에 데이터가 비어있으면 { break; } } kOutPortByte(0x64, 0xD1); // 키보드 컨트롤러의 출력 포트 값을 보내는 커맨드 kOutPortByte(0x60, bOutputPortData); // A20 Gate On }
/// Reset a processor void kKeyboard::kReboot(void) { // If the input buffer (port 0x60) is empty, // send a command which write data to the output port // and the output port data. for (int i = 0; i < 0xFFFF; i++) { // If the input buffer (port 0x60) is empty, // it is available to send. if (kIsInputBufferFull() == false) { break; } } // Send the output port setting command (0xD1) // to the command register (0x64). a_pclPort->kOutPortByte(0x64, 0xD1); // reset a processor by sending 0 to the inputer buffer (0x60). a_pclPort->kOutPortByte(0x60, 0x00); while (1) { ; } }
/// Activate A20 gate. void kKeyboard::kEnableA20Gate(void) { BYTE bOutputPortData; // Send a command which read the output port value // of the keyboard controller to the control register (port 0x64). a_pclPort->kOutPortByte(0x64, 0xD0); // Wait data of the output port and read. for (int i = 0; i < 0xFFFF; i++) { // If the output buffer (port 0x60) is full, // kOdin can read data. if (kIsOutputBufferFull() == true) { break; } } // Read the output port value of the keyboard controller // from the output port (0x60). bOutputPortData = a_pclPort->kInPortByte(0x60); // Set A20 gate activating bit bOutputPortData |= 0x01; // Send a command which write a data to the output port // and the output port data, if the input buffer (port 0x60) is empty. for (int i = 0; i < 0xFFFF; i++) { // If the input buffer (port 0x60) is empty, // it is available to send. if (kIsInputBufferFull() == false) { break; } } // Send the output port setting command (0xD1) // to the command register (0x64). a_pclPort->kOutPortByte(0x64, 0xD1); // Send setting value for A20 gate to the input buffer (port 0x60). a_pclPort->kOutPortByte(0x60, bOutputPortData); return; }
void kReboot( void ) { int i; for(i = 0 ; i < 0xFFFF ; i++ ) { if( kIsInputBufferFull() == FALSE) break; } kOutPortByte(0x64, 0xD1); // 키보드 버퍼에 컨트롤 입력값을 입력할것이다. kOutPortByte(0x60, 0x00); while(1) { ; // 재부팅 } }
/** * A20 게이트를 활성화 */ void kEnableA20Gate( void ) { BYTE bOutputPortData; int i; // 컨트롤 레지스터(포트 0x64)에 키보드 컨트롤러의 출력 포트 값을 읽는 커맨드(0xD0) 전송 kOutPortByte( 0x64, 0xD0 ); // 출력 포트의 데이터를 기다렸다가 읽음 for( i = 0 ; i < 0xFFFF ; i++ ) { // 출력 버퍼(포트 0x60)가 차있으면 데이터를 읽을 수 있음 if( kIsOutputBufferFull() == TRUE ) { break; } } // 출력 포트(포트 0x60)에 수신된 키보드 컨트롤러의 출력 포트 값을 읽음 bOutputPortData = kInPortByte( 0x60 ); // A20 게이트 비트 설정 bOutputPortData |= 0x01; // 입력 버퍼(포트 0x60)에 데이터가 비어있으면 출력 포트에 값을 쓰는 커맨드와 출력 포트 데이터 전송 for( i = 0 ; i < 0xFFFF ; i++ ) { // 입력 버퍼(포트 0x60)가 비었으면 커맨드 전송 가능 if( kIsInputBufferFull() == FALSE ) { break; } } // 커맨드 레지스터(0x64)에 출력 포트 설정 커맨드(0xD1)을 전달 kOutPortByte( 0x64, 0xD1 ); // 입력 버퍼(0x60)에 A20 게이트 비트가 1로 설정된 값을 전달 kOutPortByte( 0x60, bOutputPortData ); }
/// Activate keyboard. bool kKeyboard::kActivateKeyboard(void) { bool bPreviousInterrupt; bool bResult; // Disable an interrupt bPreviousInterrupt = g_pclIH->kSetInterruptFlag(false); // Activate a keyboard device by sending keyboard activating command (0xAE) // to the control register (0x64). a_pclPort->kOutPortByte(0x64, 0xAE); // Wait for the input buffer (port 0x60) being empty. // If it is empty, send the command. // The maximum wait time is 0xFFFF. // If it is not empty until 0xFFFF, ignore previous data and send it. for (int i = 0; i < 0xFFFF; i++) { // If the input buffer (port 0x60) is empty, send the message. if (kIsInputBufferFull() == false) { break; } } // Activate a keyboard by sending keyboard activating command (0xF4) // to the input buffer (0x60). a_pclPort->kOutPortByte(0x60, 0xF4); // Wait for the ACK signal bResult = kWaitForACKAndPushOtherScanCode(); // Restore the previous state of the interrupt flag g_pclIH->kSetInterruptFlag(bPreviousInterrupt); return bResult; }
/// Change the sate of LEDs. bool kKeyboard::kChangeKeyboardLED(bool bCapsLockOn, bool bNumLockOn, bool bScrollLockOn) { bool bPreviousInterrupt; bool bResult; // Disable an interrupt bPreviousInterrupt = g_pclIH->kSetInterruptFlag(false); // Send LED commands to a keyboard and wait until the command is done. for (int i = 0; i < 0xFFFF; i++) { // Send command if the input buffer (port 0x60) is empty. if (kIsInputBufferFull() == false) { break; } } // Send LED state change command (0xED) to the output buffer (port 0x60). a_pclPort->kOutPortByte(0x60, 0xED); for (int i = 0; i < 0xFFFF; i++) { // If the inpur buffer (port 0x60) is empty, // the keyboard takes the data. if (kIsInputBufferFull() == false) { break; } } // Wait for the ACK signal bResult = kWaitForACKAndPushOtherScanCode(); if (bResult == false) { // Restore the previous state of the interrupt flag g_pclIH->kSetInterruptFlag(bPreviousInterrupt); return false; } // Send new LED state value to a keyboard until the command is done a_pclPort->kOutPortByte(0x60, (bCapsLockOn << 2) | (bNumLockOn << 1) | bScrollLockOn); for (int i = 0; i < 0xFFFF; i++) { // If the input buffer (port 0x60) is empty // a keyboard takes LED data if (kIsInputBufferFull() == false) { break; } } // Wait for the ACK signal bResult = kWaitForACKAndPushOtherScanCode(); // Restore the previous state of the interrupt flag g_pclIH->kSetInterruptFlag(bPreviousInterrupt); return bResult; }