My problem is like that: I'm writing my first OS and currently i'm writing keyboard driver. It works properly, but when I turn scancodes into ASCII codes using scancode set 2, it was wrong. E.g when I type
Code: Select all
asdfghjkl[Enter]
Code: Select all
~~cxde43~w
Code: Select all
char mosKbdToASCII( Key k, unsigned st ) // st - keyboard state bit enum
{
const int maxKeynum = 0x66; // max implemented key
if( st &( unsigned ) KbdState::Shift )
{
// with shift
static char shiftMp[ maxKeynum + 1 ] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, '\t', '~', 0, 0, 0, 0, 0,
'Q', '!', 0, 0, 0, 'Z', 'S', 'A', 'W', '@',
0, 0, 'C', 'X', 'D', 'E', '$', '#', 0, 0,
' ', 'V', 'F', 'T', 'R', '%', 0, 0, 'N',
'B', 'H', 'G', 'Y', '^', 0, 0, 0, 'M', 'J',
'U', '&', '*', 0, 0, '<', 'K', 'I', 'O', ')',
'(', 0, 0, '>', '?', 'L', ':', 'P', '_', 0,
0, 0, '\"', 0, '{', '+', 0, 0, 0, 0,
'\n', '}', 0, '|', 0, 0, 0, 0, '\b'
};
if(( int ) k > maxKeynum + 1 )
return 0;
else
return shiftMp[( int ) k ];
}
// normal
static char mp[ maxKeynum + 1 ] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, '\t', '`', 0, 0, 0, 0, 0,
'q', '1', 0, 0, 0, 'z', 's', 'a', 'w', '2',
0, 0, 'c', 'x', 'd', 'e', '4', '3', 0, 0,
' ', 'v', 'f', 't', 'r', '5', 0, 0, 'n',
'b', 'h', 'g', 'y', '6', 0, 0, 0, 'm', 'j',
'u', '7', '8', 0, 0, ',', 'k', 'i', 'o', '0',
'9', 0, 0, '.', '/', 'l', ';', 'p', '-', 0,
0, 0, '\'', 0, '[', '=', 0, 0, 0, 0,
'\n', ']', 0, '\\', 0, 0, 0, 0, '\b',
};
if(( int ) k > maxKeynum + 1 )
return 0;
else
return mp[( int ) k ];
}
// funcs to reading keys
Key mosReadKey()
{
// mosReadKbd() gets key form keyboard without timeout
// kbdBuf is simple queue
if( kbdBuf.empty() ) // buffer is empty
{
Key k = mosReadKbd(); // mosReadKbd() wait until is any key is pressed and returns it
while( !processKey( k ) || k == Key::None ) // processKey() support 'break' codes and keyboard states (e.g shift pressed), returns true if key can be gived to user
k = mosReadKbd();
return k;
}
else
return kbdBuf.pop();
}
char mosReadChar() // simply read key and translate it into ASCII
{
Key k = mosReadKey();
return mosKbdToASCII( k, kbdSt );
}
Code: Select all
// add record to IDT
#define _set_gate(gate_addr,type,dpl,addr) \
__asm__ __volatile__("movw %%dx,%%ax\n\t" \
"movw %0,%%dx\n\t" \
"movl %%eax,%1\n\t" \
"movl %%edx,%2\n\t" \
: :"i"((short)(0x8000+(dpl<<13)+(type<<8))), \
"o"(*((char *)(gate_addr))), \
"o"(*(4+(char *)(gate_addr))), \
"d"((char *)(addr)),"a"(0x00080000)) \
void mosSetIntGate( int n, void * p ) // register interrupt
{
_set_gate( & mosIDT[ n ], 14, 0, p );
}
// enable IRQ
void mosEnableIRQ( unsigned int num )
{
unsigned int mask = ~( 1 << num );
cached_irq_mask &= mask;
if( irq & 8 ) {
mosWritePort( cached_A1, 0xA1 );
} else {
mosWritePort( cached_21, 0x21 );
}
}
#define ASMCALL extern "C" // to avoid c++ compiler name conversation
ASMCALL void doIrq1() // keyboard interrupt code
{
Key k =( Key ) mosReadPort( KBD_DATA_PORT );
if( processKey( k ) ) kbdBuf.push( k );
}
ASMCALL void irq1(); // asm interrupt function
void mosInitKbd()
{
kbdSt = 0;
while( !kbdBuf.empty() ) kbdBuf.pop(); // clear buffer
mosSetIntGate( 0x21,( void * ) irq1 ); // set interrupt to propely address
mosEnableIRQ( 1 );
}