fix bug,check A-H

This commit is contained in:
xiaoxiao 2022-12-26 01:47:46 +08:00
parent 25c762a8ed
commit b3f160accf
3 changed files with 419 additions and 278 deletions

View File

@ -15,7 +15,6 @@
#include "assert.h" #include "assert.h"
#include "minix_keymap.h" #include "minix_keymap.h"
static KB_INPUT kb_in; static KB_INPUT kb_in;
static MOUSE_INPUT mouse_in; static MOUSE_INPUT mouse_in;
static int mouse_init; static int mouse_init;
@ -36,46 +35,57 @@ static u8 get_byte_from_kb_buf();
static void set_leds(); static void set_leds();
static void set_mouse_leds(); static void set_mouse_leds();
static void kb_wait(); static void kb_wait();
static void ps2_push(NTTY* tty, u32 key); static void ps2_push(NTTY *tty, u32 key);
static void kbd_process(unsigned char scode); static void kbd_process(unsigned char scode);
// static void kb_ack(); // static void kb_ack();
/* /*
* Helper Procedures for PS/2 Mouse Operation * Helper Procedures for PS/2 Mouse Operation
* */ * */
static void mouse_wait(u8 a_type) { static void mouse_wait(u8 a_type)
int _time_out=100000; {
if(a_type==0) { int _time_out = 100000;
while(_time_out--) if((inb(PS2_PORT_CMD) & 1)==1) return; if (a_type == 0)
{
while (_time_out--)
if ((inb(PS2_PORT_CMD) & 1) == 1)
return;
return; return;
} }
else { else
while(_time_out--) if((inb(PS2_PORT_CMD) & 2)==0) return; {
while (_time_out--)
if ((inb(PS2_PORT_CMD) & 2) == 0)
return;
return; return;
} }
} }
static void mouse_write(u8 a_write) { static void mouse_write(u8 a_write)
mouse_wait(1);//Wait to be able to send a command {
outb(PS2_PORT_CMD, PS2_CMD_2ND_OUT);//Tell the mouse we are sending a command mouse_wait(1); // Wait to be able to send a command
mouse_wait(1);//Wait for the final part outb(PS2_PORT_CMD, PS2_CMD_2ND_OUT); // Tell the mouse we are sending a command
outb(PS2_PORT_DATA, a_write);//Finally write mouse_wait(1); // Wait for the final part
outb(PS2_PORT_DATA, a_write); // Finally write
} }
//Get's response from mouse // Get's response from mouse
static u8 mouse_read() { static u8 mouse_read()
{
mouse_wait(0); mouse_wait(0);
return inb(PS2_PORT_DATA); return inb(PS2_PORT_DATA);
} }
static void mouse_set_rate(u8 rate) { static void mouse_set_rate(u8 rate)
{
mouse_write(0xf3); // set sample rate cmd mouse_write(0xf3); // set sample rate cmd
assert(mouse_read() == PS2_ACK); assert(mouse_read() == PS2_ACK);
mouse_write(rate); mouse_write(rate);
assert(mouse_read() == PS2_ACK); assert(mouse_read() == PS2_ACK);
} }
static u8 mouse_get_id() { static u8 mouse_get_id()
{
mouse_write(PS2_CMD_DATA_REPORT_DIS); mouse_write(PS2_CMD_DATA_REPORT_DIS);
assert(mouse_read() == PS2_ACK); assert(mouse_read() == PS2_ACK);
mouse_write(PS2_CMD_GET_DEVICE); // report mouse_write(PS2_CMD_GET_DEVICE); // report
@ -86,16 +96,19 @@ static u8 mouse_get_id() {
return device_type; return device_type;
} }
void kb_handler(int irq){ void kb_handler(int irq)
{
u8 scan_code = inb(PS2_PORT_DATA); u8 scan_code = inb(PS2_PORT_DATA);
#ifdef DEBUGNEW #ifdef DEBUGNEW
kbd_process(scan_code); kbd_process(scan_code);
// kprintf("shit"); // kprintf("shit");
#else #else
if(kb_in.count < KB_IN_BYTES){ if (kb_in.count < KB_IN_BYTES)
{
*(kb_in.p_head) = scan_code; *(kb_in.p_head) = scan_code;
kb_in.p_head++; kb_in.p_head++;
if(kb_in.p_head==kb_in.buf+KB_IN_BYTES){ if (kb_in.p_head == kb_in.buf + KB_IN_BYTES)
{
kb_in.p_head = kb_in.buf; kb_in.p_head = kb_in.buf;
} }
kb_in.count++; kb_in.count++;
@ -103,8 +116,8 @@ void kb_handler(int irq){
#endif #endif
}; };
void mouse_handler(int irq)
void mouse_handler(int irq){ {
u8 scan_code = inb(PS2_PORT_DATA); u8 scan_code = inb(PS2_PORT_DATA);
static int aux_state = 0; static int aux_state = 0;
int i; int i;
@ -112,12 +125,15 @@ void mouse_handler(int irq){
if (mouse_in.count == 0 && !(scan_code & 0x08)) if (mouse_in.count == 0 && !(scan_code & 0x08))
return; // resync return; // resync
mouse_in.buf[mouse_in.count++] = scan_code; mouse_in.buf[mouse_in.count++] = scan_code;
if (mouse_in.count < 4) return; if (mouse_in.count < 4)
return;
mouse_in.count = 0; mouse_in.count = 0;
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++)
{
pack = ISMOUSE | MOUSEBTN; pack = ISMOUSE | MOUSEBTN;
if ((aux_state ^ mouse_in.buf[0]) & (1 << i)) { if ((aux_state ^ mouse_in.buf[0]) & (1 << i))
{
aux_state ^= (1 << i); aux_state ^= (1 << i);
pack |= !!(aux_state & (1 << i)) ? MOUSEBTN_CLICK : MOUSEBTN_RELEASE; pack |= !!(aux_state & (1 << i)) ? MOUSEBTN_CLICK : MOUSEBTN_RELEASE;
pack |= (1 << i); pack |= (1 << i);
@ -125,37 +141,44 @@ void mouse_handler(int irq){
} }
} }
pack = ISMOUSE | MOUSESCR; pack = ISMOUSE | MOUSESCR;
if ((signed char)mouse_in.buf[3] > 0) { if ((signed char)mouse_in.buf[3] > 0)
{
// actually it is 0x1 // actually it is 0x1
pack |= MOUSESCR_DOWN; pack |= MOUSESCR_DOWN;
ps2_push(cur_ntty, pack); ps2_push(cur_ntty, pack);
} else if ((signed char)mouse_in.buf[3] < 0) { }
else if ((signed char)mouse_in.buf[3] < 0)
{
// actually it is 0xff // actually it is 0xff
pack |= MOUSESCR_UP; pack |= MOUSESCR_UP;
ps2_push(cur_ntty, pack); ps2_push(cur_ntty, pack);
} }
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++)
{
pack = mouse_in.buf[1 + i]; pack = mouse_in.buf[1 + i];
if (pack != 0) { if (pack != 0)
{
pack |= ISMOUSE | MOUSEPOS; pack |= ISMOUSE | MOUSEPOS;
if (mouse_in.buf[0] & (0x10 << i)) if (mouse_in.buf[0] & (0x10 << i))
pack |= MOUSEPOS_NEG; pack |= MOUSEPOS_NEG;
if (i == 1) pack |= MOUSEPOS_XY; if (i == 1)
pack |= MOUSEPOS_XY;
ps2_push(cur_ntty, pack); ps2_push(cur_ntty, pack);
} }
} }
// kprintf("0x%02x 0x%02x 0x%02x 0x%02x\n", mouse_in.buf[0], mouse_in.buf[1], mouse_in.buf[2], mouse_in.buf[3]); // kprintf("0x%02x 0x%02x 0x%02x 0x%02x\n", mouse_in.buf[0], mouse_in.buf[1], mouse_in.buf[2], mouse_in.buf[3]);
} }
void init_mouse(){ void init_mouse()
{
mouse_in.count = 0; mouse_in.count = 0;
put_irq_handler(MOUSE_IRQ,mouse_handler); put_irq_handler(MOUSE_IRQ, mouse_handler);
enable_irq(MOUSE_IRQ); enable_irq(MOUSE_IRQ);
mouse_wait(1); mouse_wait(1);
outb(PS2_PORT_CMD, PS2_CMD_2ND_ENB); // Enable second PS/2 port outb(PS2_PORT_CMD, PS2_CMD_2ND_ENB); // Enable second PS/2 port
mouse_wait(1); mouse_wait(1);
outb(PS2_PORT_CMD, PS2_CMD_READRAM);// Read "byte 0" from internal RAM outb(PS2_PORT_CMD, PS2_CMD_READRAM); // Read "byte 0" from internal RAM
mouse_wait(0); mouse_wait(0);
u8 _status = inb(PS2_PORT_DATA) | 0x2; // bit-1 <=> Second PS/2 port interrupt u8 _status = inb(PS2_PORT_DATA) | 0x2; // bit-1 <=> Second PS/2 port interrupt
mouse_wait(1); mouse_wait(1);
@ -176,7 +199,8 @@ void init_mouse(){
assert(mouse_read() == PS2_ACK); assert(mouse_read() == PS2_ACK);
} }
void init_kb(){ void init_kb()
{
kb_in.count = 0; kb_in.count = 0;
kb_in.p_head = kb_in.p_tail = kb_in.buf; kb_in.p_head = kb_in.p_tail = kb_in.buf;
@ -187,18 +211,16 @@ void init_kb(){
num_lock = 1; num_lock = 1;
scroll_lock = 0; scroll_lock = 0;
set_leds(); set_leds();
put_irq_handler(KEYBOARD_IRQ, kb_handler); put_irq_handler(KEYBOARD_IRQ, kb_handler);
enable_irq(KEYBOARD_IRQ); enable_irq(KEYBOARD_IRQ);
init_mouse(); init_mouse();
set_mouse_leds(); set_mouse_leds();
} }
#ifndef DEBUGNEW #ifndef DEBUGNEW
static int column; static int column;
void keyboard_read(TTY* p_tty) void keyboard_read(TTY *p_tty)
{ {
u8 scan_code; u8 scan_code;
@ -215,53 +237,64 @@ void keyboard_read(TTY* p_tty)
*/ */
u32 key = 0; u32 key = 0;
/** /**
* This var points to a row in keymap[]. I don't use two-dimension * This var points to a row in keymap[]. I don't use two-dimension
* array because I don't like it. * array because I don't like it.
*/ */
u32* keyrow; u32 *keyrow;
while (kb_in.count > 0) { while (kb_in.count > 0)
{
code_with_E0 = 0; code_with_E0 = 0;
scan_code = get_byte_from_kb_buf(); scan_code = get_byte_from_kb_buf();
/* parse the scan code below */ /* parse the scan code below */
if (scan_code == 0xE1) { if (scan_code == 0xE1)
{
int i; int i;
u8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5}; u8 pausebreak_scan_code[] = {0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5};
int is_pausebreak = 1; int is_pausebreak = 1;
for (i = 1; i < 6; i++) { for (i = 1; i < 6; i++)
if (get_byte_from_kb_buf() != pausebreak_scan_code[i]) { {
if (get_byte_from_kb_buf() != pausebreak_scan_code[i])
{
is_pausebreak = 0; is_pausebreak = 0;
break; break;
} }
} }
if (is_pausebreak) { if (is_pausebreak)
{
key = PAUSEBREAK; key = PAUSEBREAK;
} }
} }
else if (scan_code == 0xE0) { else if (scan_code == 0xE0)
{
code_with_E0 = 1; code_with_E0 = 1;
scan_code = get_byte_from_kb_buf(); scan_code = get_byte_from_kb_buf();
/* PrintScreen is pressed */ /* PrintScreen is pressed */
if (scan_code == 0x2A) { if (scan_code == 0x2A)
{
code_with_E0 = 0; code_with_E0 = 0;
if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { if ((scan_code = get_byte_from_kb_buf()) == 0xE0)
{
code_with_E0 = 1; code_with_E0 = 1;
if ((scan_code = get_byte_from_kb_buf()) == 0x37) { if ((scan_code = get_byte_from_kb_buf()) == 0x37)
{
key = PRINTSCREEN; key = PRINTSCREEN;
make = 1; make = 1;
} }
} }
} }
/* PrintScreen is released */ /* PrintScreen is released */
else if (scan_code == 0xB7) { else if (scan_code == 0xB7)
{
code_with_E0 = 0; code_with_E0 = 0;
if ((scan_code = get_byte_from_kb_buf()) == 0xE0) { if ((scan_code = get_byte_from_kb_buf()) == 0xE0)
{
code_with_E0 = 1; code_with_E0 = 1;
if ((scan_code = get_byte_from_kb_buf()) == 0xAA) { if ((scan_code = get_byte_from_kb_buf()) == 0xAA)
{
key = PRINTSCREEN; key = PRINTSCREEN;
make = 0; make = 0;
} }
@ -269,7 +302,8 @@ void keyboard_read(TTY* p_tty)
} }
} }
if ((key != PAUSEBREAK) && (key != PRINTSCREEN)) { if ((key != PAUSEBREAK) && (key != PRINTSCREEN))
{
int caps; int caps;
/* make or break */ /* make or break */
@ -292,7 +326,8 @@ void keyboard_read(TTY* p_tty)
key = keyrow[column]; key = keyrow[column];
switch(key) { switch (key)
{
case SHIFT_L: case SHIFT_L:
shift_l = make; shift_l = make;
break; break;
@ -312,19 +347,22 @@ void keyboard_read(TTY* p_tty)
alt_l = make; alt_l = make;
break; break;
case CAPS_LOCK: case CAPS_LOCK:
if (make) { if (make)
{
caps_lock = !caps_lock; caps_lock = !caps_lock;
set_leds(); set_leds();
} }
break; break;
case NUM_LOCK: case NUM_LOCK:
if (make) { if (make)
{
num_lock = !num_lock; num_lock = !num_lock;
set_leds(); set_leds();
} }
break; break;
case SCROLL_LOCK: case SCROLL_LOCK:
if (make) { if (make)
{
scroll_lock = !scroll_lock; scroll_lock = !scroll_lock;
set_leds(); set_leds();
} }
@ -334,13 +372,16 @@ void keyboard_read(TTY* p_tty)
} }
} }
if(make){ /* Break Code is ignored */ if (make)
{ /* Break Code is ignored */
int pad = 0; int pad = 0;
/* deal with the numpad first */ /* deal with the numpad first */
if ((key >= PAD_SLASH) && (key <= PAD_9)) { if ((key >= PAD_SLASH) && (key <= PAD_9))
{
pad = 1; pad = 1;
switch(key) { /* '/', '*', '-', '+', switch (key)
{ /* '/', '*', '-', '+',
* and 'Enter' in num pad * and 'Enter' in num pad
*/ */
case PAD_SLASH: case PAD_SLASH:
@ -362,14 +403,17 @@ void keyboard_read(TTY* p_tty)
/* the value of these keys /* the value of these keys
* depends on the Numlock * depends on the Numlock
*/ */
if (num_lock) { /* '0' ~ '9' and '.' in num pad */ if (num_lock)
{ /* '0' ~ '9' and '.' in num pad */
if (key >= PAD_0 && key <= PAD_9) if (key >= PAD_0 && key <= PAD_9)
key = key - PAD_0 + '0'; key = key - PAD_0 + '0';
else if (key == PAD_DOT) else if (key == PAD_DOT)
key = '.'; key = '.';
} }
else{ else
switch(key) { {
switch (key)
{
case PAD_HOME: case PAD_HOME:
key = HOME; key = HOME;
break; break;
@ -414,34 +458,44 @@ void keyboard_read(TTY* p_tty)
key |= alt_l ? FLAG_ALT_L : 0; key |= alt_l ? FLAG_ALT_L : 0;
key |= alt_r ? FLAG_ALT_R : 0; key |= alt_r ? FLAG_ALT_R : 0;
key |= pad ? FLAG_PAD : 0; key |= pad ? FLAG_PAD : 0;
in_process(p_tty,key); in_process(p_tty, key);
} }
} }
} }
#endif #endif
static u16 map_key(int code) { static u16 map_key(int code)
{
int caps, column; int caps, column;
int shift = shift_l | shift_r; int shift = shift_l | shift_r;
int alt = alt_l | alt_r; int alt = alt_l | alt_r;
int ctrl = ctrl_l | ctrl_r; int ctrl = ctrl_l | ctrl_r;
u16 *keyrow = minix_keymap[code]; u16 *keyrow = minix_keymap[code];
caps = shift_l | shift_r; caps = shift_l | shift_r;
if (num_lock&& (keyrow[0] & HASNUM)) caps = !caps; if (num_lock && (keyrow[0] & HASNUM))
if (caps_lock && (keyrow[0] & HASCAPS)) caps = !caps; caps = !caps;
if (caps_lock && (keyrow[0] & HASCAPS))
caps = !caps;
if (alt) { if (alt)
{
column = 2; column = 2;
if (ctrl || alt_r) column = 3; /* Ctrl + Alt == AltGr */ if (ctrl || alt_r)
if (caps) column = 4; column = 3; /* Ctrl + Alt == AltGr */
} else { if (caps)
column = 4;
}
else
{
// if (sticky_alt_mode && (lk & ALT_LOCK)) { // if (sticky_alt_mode && (lk & ALT_LOCK)) {
// column = 2; // column = 2;
// if (caps) column = 4; // if (caps) column = 4;
// } else { // } else {
column = 0; column = 0;
if (caps) column = 1; if (caps)
if (ctrl) column = 5; column = 1;
if (ctrl)
column = 5;
// } // }
} }
return keyrow[column] & ~(HASNUM | HASCAPS); return keyrow[column] & ~(HASNUM | HASCAPS);
@ -455,7 +509,8 @@ static void kbd_process(unsigned char scode)
press = !(scode & SCAN_RELEASE) ? INPUT_PRESS : INPUT_RELEASE; press = !(scode & SCAN_RELEASE) ? INPUT_PRESS : INPUT_RELEASE;
index = scode & ~SCAN_RELEASE; index = scode & ~SCAN_RELEASE;
switch (kbd_state) { switch (kbd_state)
{
case 1: case 1:
page = scanmap_escaped[index].page; page = scanmap_escaped[index].page;
code = scanmap_escaped[index].code; code = scanmap_escaped[index].code;
@ -464,14 +519,16 @@ static void kbd_process(unsigned char scode)
kbd_state = (index == SCAN_CTRL) ? 3 : 0; kbd_state = (index == SCAN_CTRL) ? 3 : 0;
return; return;
case 3: case 3:
if (index == SCAN_NUMLOCK) { if (index == SCAN_NUMLOCK)
{
page = INPUT_PAGE_KEY; page = INPUT_PAGE_KEY;
code = INPUT_KEY_PAUSE; code = INPUT_KEY_PAUSE;
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
switch (scode) { switch (scode)
{
case SCAN_EXT0: case SCAN_EXT0:
kbd_state = 1; kbd_state = 1;
return; return;
@ -484,40 +541,50 @@ static void kbd_process(unsigned char scode)
break; break;
} }
if (page) { if (page)
{
switch (code) switch (code)
{ {
case INPUT_KEY_LEFT_SHIFT: case INPUT_KEY_LEFT_SHIFT:
shift_l = press; break; shift_l = press;
break;
case INPUT_KEY_RIGHT_SHIFT: case INPUT_KEY_RIGHT_SHIFT:
shift_r = press; break; shift_r = press;
break;
case INPUT_KEY_LEFT_CTRL: case INPUT_KEY_LEFT_CTRL:
ctrl_l = press; break; ctrl_l = press;
break;
case INPUT_KEY_RIGHT_CTRL: case INPUT_KEY_RIGHT_CTRL:
ctrl_r = press; break; ctrl_r = press;
break;
case INPUT_KEY_LEFT_ALT: case INPUT_KEY_LEFT_ALT:
alt_l = press; break; alt_l = press;
break;
case INPUT_KEY_RIGHT_ALT: case INPUT_KEY_RIGHT_ALT:
alt_r = press; break; alt_r = press;
break;
case INPUT_KEY_NUM_LOCK: case INPUT_KEY_NUM_LOCK:
if (press) num_lock = !num_lock; if (press)
num_lock = !num_lock;
break; break;
case INPUT_KEY_CAPS_LOCK: case INPUT_KEY_CAPS_LOCK:
if (press) caps_lock = !caps_lock; if (press)
caps_lock = !caps_lock;
break; break;
case INPUT_KEY_SCROLL_LOCK: case INPUT_KEY_SCROLL_LOCK:
if (press) scroll_lock = !scroll_lock; if (press)
scroll_lock = !scroll_lock;
break; break;
} }
// inputdriver_send_event(FALSE /*mouse*/, page, code, press, 0); // inputdriver_send_event(FALSE /*mouse*/, page, code, press, 0);
if (press) ps2_push(cur_ntty, map_key(code)); if (press)
ps2_push(cur_ntty, map_key(code));
} }
kbd_state = 0; kbd_state = 0;
} }
/***************************************************************************** /*****************************************************************************
* get_byte_from_kb_buf * get_byte_from_kb_buf
*****************************************************************************/ *****************************************************************************/
@ -530,12 +597,15 @@ static u8 get_byte_from_kb_buf()
{ {
u8 scan_code; u8 scan_code;
while (kb_in.count <= 0) {} /* wait for a byte to arrive */ while (kb_in.count <= 0)
{
} /* wait for a byte to arrive */
disable_int(); /* for synchronization */ disable_int(); /* for synchronization */
scan_code = *(kb_in.p_tail); scan_code = *(kb_in.p_tail);
kb_in.p_tail++; kb_in.p_tail++;
if (kb_in.p_tail == kb_in.buf + KB_IN_BYTES) { if (kb_in.p_tail == kb_in.buf + KB_IN_BYTES)
{
kb_in.p_tail = kb_in.buf; kb_in.p_tail = kb_in.buf;
} }
kb_in.count--; kb_in.count--;
@ -544,7 +614,6 @@ static u8 get_byte_from_kb_buf()
return scan_code; return scan_code;
} }
/***************************************************************************** /*****************************************************************************
* kb_wait * kb_wait
*****************************************************************************/ *****************************************************************************/
@ -556,13 +625,13 @@ static void kb_wait() /* 等待 8042 的输入缓冲区空 */
{ {
u8 kb_stat; u8 kb_stat;
do { do
{
kb_stat = inb(KB_CMD); kb_stat = inb(KB_CMD);
} while (kb_stat & 0x02); } while (kb_stat & 0x02);
} }
/***************************************************************************** /*****************************************************************************
* set_leds * set_leds
*****************************************************************************/ *****************************************************************************/
@ -578,9 +647,10 @@ static void set_leds()
outb(KB_DATA, KBC_MODE); outb(KB_DATA, KBC_MODE);
} }
static void set_mouse_leds(){ static void set_mouse_leds()
{
kb_wait(); kb_wait();
outb(KB_CMD,KBCMD_EN_MOUSE_INTFACE); outb(KB_CMD, KBCMD_EN_MOUSE_INTFACE);
kb_wait(); kb_wait();
outb(KB_CMD, KEYCMD_SENDTO_MOUSE); outb(KB_CMD, KEYCMD_SENDTO_MOUSE);
kb_wait(); kb_wait();
@ -597,31 +667,36 @@ static struct spinlock buflock;
#define NEXTKEY(x) NEXT(x, TTY_IN_BYTES) #define NEXTKEY(x) NEXT(x, TTY_IN_BYTES)
static u8 keybuf[3][TTY_IN_BYTES]; static u8 keybuf[3][TTY_IN_BYTES];
void ps2_tty_init(NTTY* tty) { void ps2_tty_init(NTTY *tty)
{
static int _cnt = 0; static int _cnt = 0;
assert(tty->driver_type == 1); assert(tty->driver_type == 1);
assert(tty->input_buf); assert(tty->input_buf);
keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; keyboard_buf *kbd = (keyboard_buf *)tty->input_buf;
kbd->buf = (void*)keybuf[_cnt ++]; kbd->buf = (void *)keybuf[_cnt++];
kbd->head = kbd->tail = kbd->readable = 0; kbd->head = kbd->tail = kbd->readable = 0;
kbd->len = 0; kbd->len = 0;
buflock.locked = 0; buflock.locked = 0;
} }
int ps2_tty_read(NTTY* tty, char* buf, int nr) { int ps2_tty_read(NTTY *tty, char *buf, int nr)
{
assert(tty->input_buf); assert(tty->input_buf);
keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; keyboard_buf *kbd = (keyboard_buf *)tty->input_buf;
assert(kbd->buf); assert(kbd->buf);
int i = 0; int i = 0;
while(1) { while (1)
if (kbd->readable) { {
if (kbd->readable)
{
disable_int(); disable_int();
break; break;
} }
} }
u8* ibuf = kbd->buf; u8 *ibuf = kbd->buf;
for (; i < nr && i < kbd->readable; ++ i) { for (; i < nr && i < kbd->readable; ++i)
*(buf+i) = *(ibuf+kbd->head); {
*(buf + i) = *(ibuf + kbd->head);
// kprintf("read %p\n", ibuf+kbd->head); // kprintf("read %p\n", ibuf+kbd->head);
kbd->head = NEXTKEY(kbd->head); kbd->head = NEXTKEY(kbd->head);
} }
@ -631,77 +706,106 @@ int ps2_tty_read(NTTY* tty, char* buf, int nr) {
return i; return i;
} }
void ps2_tty_flush(NTTY* tty) { void ps2_tty_flush(NTTY *tty)
{
disable_int(); disable_int();
assert(tty->input_buf); assert(tty->input_buf);
keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; keyboard_buf *kbd = (keyboard_buf *)tty->input_buf;
kbd->head = kbd->tail = kbd->len = kbd->readable = 0; kbd->head = kbd->tail = kbd->len = kbd->readable = 0;
enable_int(); enable_int();
} }
static void ps2_push(NTTY* tty, u32 key) { static void ps2_push(NTTY *tty, u32 key)
{
// kprintf("%x\n", key); // kprintf("%x\n", key);
disable_int(); disable_int();
assert(tty->input_buf); assert(tty->input_buf);
keyboard_buf* kbd = (keyboard_buf*)tty->input_buf; keyboard_buf *kbd = (keyboard_buf *)tty->input_buf;
if (key & ISMOUSE) { if (key & ISMOUSE)
if (key & MOUSESCR) { {
if (key & MOUSESCR_UP) { if (key & MOUSESCR)
{
if (key & MOUSESCR_UP)
{
// kprintf("scroll up\n"); // kprintf("scroll up\n");
vga_tty_scroll(tty, MOUSESCR_UP); vga_tty_scroll(tty, MOUSESCR_UP);
} else { }
else
{
// kprintf("scroll down\n"); // kprintf("scroll down\n");
vga_tty_scroll(tty, MOUSESCR_DOWN); vga_tty_scroll(tty, MOUSESCR_DOWN);
} }
} }
else if (key & MOUSEBTN) { else if (key & MOUSEBTN)
if ((key & MOUSEBTN_CLICK) && (key & MOUSEBTN_M)) { {
if ((key & MOUSEBTN_CLICK) && (key & MOUSEBTN_M))
{
kprintf("middle btn click %x\n", key); kprintf("middle btn click %x\n", key);
vga_tty_scroll(tty, 3); vga_tty_scroll(tty, 3);
} }
} }
} }
else if (key & EXT) { else if (key & EXT)
{
switch (key) switch (key)
{ {
case F1: case F2: case F3: case F4: case F5: case F6: case F1:
case F7: case F8: case F9: case F10: case F11: case F12: case F2:
case F3:
case F4:
case F5:
case F6:
case F7:
case F8:
case F9:
case F10:
case F11:
case F12:
// select_console((key & 0xff) - (F1 & 0xff)); // TODO // select_console((key & 0xff) - (F1 & 0xff)); // TODO
{
int conno = (key & 0xff) - (F1 & 0xff); int conno = (key & 0xff) - (F1 & 0xff);
if (conno < NR_CONSOLES) { if (conno < NR_CONSOLES)
{
kprintf("select console %d\n", conno); kprintf("select console %d\n", conno);
vga_tty_select(default_ntty + conno); vga_tty_select(default_ntty + conno);
} }
break; break;
}
default: default:
break; break;
} }
} }
else { else
{
switch (key) switch (key)
{ {
case '\r': case '\n': // escape ENTER case '\r':
case '\n': // escape ENTER
vga_tty_write(tty, '\n'); vga_tty_write(tty, '\n');
((u8*)kbd->buf)[kbd->tail] = '\n'; ((u8 *)kbd->buf)[kbd->tail] = '\n';
kbd->len ++; kbd->len++;
kbd->tail = NEXTKEY(kbd->tail); kbd->tail = NEXTKEY(kbd->tail);
kbd->readable = CYCLE_SUB(kbd->head, kbd->tail, TTY_IN_BYTES); kbd->readable = CYCLE_SUB(kbd->head, kbd->tail, TTY_IN_BYTES);
// kprintf("len=%d, h=%d, t=%d, rd=%d\n", kbd->len, kbd->head, kbd->tail, kbd->readable); // kprintf("len=%d, h=%d, t=%d, rd=%d\n", kbd->len, kbd->head, kbd->tail, kbd->readable);
break; break;
case '\b': case '\b':
if (kbd->len > kbd->readable) { if (kbd->len > kbd->readable)
{
vga_tty_backspace(tty); vga_tty_backspace(tty);
kbd->len --; kbd->len--;
kbd->tail = LASTKEY(kbd->tail); kbd->tail = LASTKEY(kbd->tail);
} }
break; break;
default: default:
if ((key & 0xff) == 0) return; if ((key & 0xff) == 0)
if (kbd->len == TTY_IN_BYTES - 1) return; // leave one space for ctrl ascii return;
if (kbd->len == TTY_IN_BYTES - 1)
return; // leave one space for ctrl ascii
vga_tty_write(tty, key); vga_tty_write(tty, key);
((u8*)kbd->buf)[kbd->tail] = key & 0xff; ((u8 *)kbd->buf)[kbd->tail] = key & 0xff;
kbd->len ++; kbd->len++;
kbd->tail = NEXTKEY(kbd->tail); kbd->tail = NEXTKEY(kbd->tail);
// kprintf("len=%d, h=%d, t=%d, rd=%d\n", kbd->len, kbd->head, kbd->tail, kbd->readable); // kprintf("len=%d, h=%d, t=%d, rd=%d\n", kbd->len, kbd->head, kbd->tail, kbd->readable);
break; break;
@ -711,4 +815,4 @@ static void ps2_push(NTTY* tty, u32 key) {
enable_int(); enable_int();
} }
//TODO: 1. 修改键盘驱动 2. 添加测试代码 3. 添加鼠标并调试滚动 // TODO: 1. 修改键盘驱动 2. 添加测试代码 3. 添加鼠标并调试滚动

View File

@ -142,7 +142,7 @@ void vga_tty_init(NTTY *tty)
kprintf("%p 0x%x %d\n", vga->buf, ((u32 *)vga->buf)[20], vga->scr_cur_line); kprintf("%p 0x%x %d\n", vga->buf, ((u32 *)vga->buf)[20], vga->scr_cur_line);
} }
#define INDEX(row, col) ((row) * SCR_WIDTH + (col)) #define INDEX(row, col) ((row)*SCR_WIDTH + (col))
#define NEXTLINE(row) NEXT(row, SCR_MAXLINE) #define NEXTLINE(row) NEXT(row, SCR_MAXLINE)
#define LASTLINE(row) LAST(row, SCR_MAXLINE) #define LASTLINE(row) LAST(row, SCR_MAXLINE)
#define ADDLINE(row, add_num) (((row) + add_num) % SCR_MAXLINE) #define ADDLINE(row, add_num) (((row) + add_num) % SCR_MAXLINE)
@ -156,43 +156,52 @@ static void csi_scroll(vga_buf *vgabuf, i16 scroll_num)
// down // down
scroll_num--; scroll_num--;
if (vgabuf->scr_top_line == vgabuf->scr_cur_line) if (vgabuf->scr_top_line == vgabuf->scr_cur_line)
{
vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line);
if (vgabuf->scr_top_line == vgabuf->head_line)
{
vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line);
return; return;
}
vgabuf->scr_bot_line = NEXTLINE(vgabuf->scr_bot_line);
vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line);
}
vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line);
} }
while (scroll_num < 0) while (scroll_num < 0)
{ {
// up
scroll_num++; scroll_num++;
if (vgabuf->scr_top_line == vgabuf->head_line) if (vgabuf->scr_top_line == vgabuf->head_line)
return; return;
vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line); vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line);
} if (CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE) == SCR_HEIGHT)
vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line); vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line);
if (vgabuf->cur_row >= SCR_HEIGHT) // if (CYCLE_SUB(vgabuf->scr_bot_line, vgabuf->scr_bot_line, SCR_MAXLINE) == SCR_HEIGHT)
{ // vgabuf->scr_bot_line = LASTLINE(vgabuf->scr_bot_line);
vga_disable_cursor();
}
else
{
vga_enable_cursor(0, 15);
} }
} }
static void newline(vga_buf* vga) { static void newline(vga_buf *vga)
u16* buf = vga->buf; {
u16 *buf = vga->buf;
vga->cur_col = 0; vga->cur_col = 0;
// kprintf("bf %x\n", vgabuf->scr_cur_line); // kprintf("bf %x\n", vgabuf->scr_cur_line);
vga->scr_cur_line = NEXTLINE(vga->scr_cur_line); vga->scr_cur_line = NEXTLINE(vga->scr_cur_line);
// kprintf("af %x\n", vgabuf->scr_cur_line); // kprintf("af %x\n", vgabuf->scr_cur_line);
vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE);
if (vga->cur_row == SCR_HEIGHT) { if (vga->cur_row == SCR_HEIGHT)
{
// auto scroll // auto scroll
vga->scr_top_line = NEXTLINE(vga->scr_top_line); vga->scr_top_line = NEXTLINE(vga->scr_top_line);
} }
if(vga->scr_cur_line == vga->head_line) { if (vga->scr_cur_line == vga->head_line)
{
vga->head_line = NEXTLINE(vga->head_line); vga->head_line = NEXTLINE(vga->head_line);
// remember to fill blank the old line // remember to fill blank the old line
u32* ptr_buf = (u32*) (vga->buf + sizeof(u16) * vga->scr_cur_line * SCR_WIDTH); u32 *ptr_buf = (u32 *)(vga->buf + sizeof(u16) * vga->scr_cur_line * SCR_WIDTH);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i) { for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
{
*ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space *ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space
} }
// for (int i = 0; i < SCR_WIDTH; ++ i) { // for (int i = 0; i < SCR_WIDTH; ++ i) {
@ -210,39 +219,51 @@ static void nextcol(vga_buf *vgabuf)
} }
} }
static void cursor_locate(i16 row, i16 col, vga_buf *vgabuf)
{
if (row == 0)
{
vgabuf->scr_cur_line = vgabuf->scr_top_line;
}
while (row > 0 && row < SCR_HEIGHT - 1)
{
row--;
vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_top_line);
if (vgabuf->scr_cur_line == vgabuf->scr_bot_line)
break;
}
if (col >= 0 && col <= SCR_WIDTH - 1)
{
vgabuf->cur_col = col;
}
}
static void cursor_move(i16 move_row, i16 move_col, vga_buf *vgabuf) static void cursor_move(i16 move_row, i16 move_col, vga_buf *vgabuf)
{ {
// kprintf("%d,%d", move_row, move_col);
while (move_row > 0) // down while (move_row > 0) // down
{ {
move_col--; move_row--;
if (vgabuf->scr_cur_line == vgabuf->scr_bot_line)
break;
vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line); vgabuf->scr_cur_line = NEXTLINE(vgabuf->scr_cur_line);
vgabuf->cur_row = abs(vgabuf->scr_cur_line - vgabuf->scr_top_line); vgabuf->cur_row = CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE);
if (vgabuf->cur_row == SCR_HEIGHT) if (vgabuf->cur_row == SCR_HEIGHT)
{ {
// auto scroll // auto scroll
vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line); vgabuf->scr_top_line = NEXTLINE(vgabuf->scr_top_line);
if (vgabuf->scr_cur_line == vgabuf->head_line)
{
vgabuf->head_line = NEXTLINE(vgabuf->head_line);
// remember to fill blank the old line
u32 *ptr_buf = (u32 *)(vgabuf->buf + sizeof(u16) * vgabuf->head_line * SCR_WIDTH);
for (int i = 0; i < SCR_WIDTH * sizeof(u16) / sizeof(u32); ++i)
{
*ptr_buf++ = (BLANK << 16) | BLANK; // bg-black, fg-white, ascii-space
}
}
} }
} }
while (move_row < 0) // up while (move_row < 0) // up
{ {
move_col++; move_row++;
// vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line); vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line);
if (vgabuf->scr_cur_line == vgabuf->scr_top_line) if (vgabuf->scr_cur_line == vgabuf->scr_top_line)
{ {
if (vgabuf->scr_top_line == vgabuf->head_line) if (vgabuf->scr_top_line == vgabuf->head_line)
break; break;
vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line); // vgabuf->scr_cur_line = LASTLINE(vgabuf->scr_cur_line);
vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line); vgabuf->scr_top_line = LASTLINE(vgabuf->scr_top_line);
vgabuf->scr_bot_line = LASTLINE(vgabuf->scr_bot_line);
} }
} }
vgabuf->cur_row = CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE); vgabuf->cur_row = CYCLE_SUB(vgabuf->scr_top_line, vgabuf->scr_cur_line, SCR_MAXLINE);
@ -389,12 +410,12 @@ static void CSI_handler(u8 terminator, vga_buf *vgabuf)
case 'C': case 'C':
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)
vgabuf->param1 == 1; vgabuf->param1 == 1;
cursor_move(0, -vgabuf->param1, vgabuf); // nothing cursor_move(0, +vgabuf->param1, vgabuf);
break; break;
case 'D': case 'D':
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)
vgabuf->param1 == 1; vgabuf->param1 == 1;
cursor_move(0, +vgabuf->param1, vgabuf); cursor_move(0, -vgabuf->param1, vgabuf); // nothing
break; break;
case 'E': case 'E':
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)
@ -407,10 +428,17 @@ static void CSI_handler(u8 terminator, vga_buf *vgabuf)
cursor_move(-vgabuf->param1, -vgabuf->cur_col, vgabuf); cursor_move(-vgabuf->param1, -vgabuf->cur_col, vgabuf);
break; break;
case 'G': // added case 'G': // added
cursor_move(0, vgabuf->param1 - vgabuf->cur_col, vgabuf); if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
cursor_locate(vgabuf->scr_cur_line, vgabuf->param1 - 1, vgabuf);
break; break;
case 'H': case 'H':
cursor_move(vgabuf->param1 - vgabuf->scr_cur_line, vgabuf->param1 - vgabuf->cur_col, vgabuf); if (vgabuf->param1 == 0)
vgabuf->param1 == 1;
if (vgabuf->param2 == 0)
vgabuf->param2 == 1;
cursor_locate(vgabuf->param1 - 1, vgabuf->param2 - 1, vgabuf);
break; break;
case 'J': case 'J':
if (vgabuf->param1 == 0) if (vgabuf->param1 == 0)
@ -551,7 +579,8 @@ void vga_tty_write(NTTY *tty, char ch)
} }
} }
vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE); vga->cur_row = CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE);
if (CYCLE_SUB(vga->head_line, vga->scr_cur_line, SCR_MAXLINE) >= CYCLE_SUB(vga->head_line, vga->scr_bot_line, SCR_MAXLINE)){ if (CYCLE_SUB(vga->head_line, vga->scr_cur_line, SCR_MAXLINE) >= CYCLE_SUB(vga->head_line, vga->scr_bot_line, SCR_MAXLINE))
{
vga->scr_bot_line = vga->scr_cur_line; vga->scr_bot_line = vga->scr_cur_line;
} }
// kprintf("row: %d; ", vga->cur_row); // kprintf("row: %d; ", vga->cur_row);
@ -620,8 +649,10 @@ void vga_tty_scroll(NTTY *tty, int direction)
return; return;
vga->scr_top_line = LASTLINE(vga->scr_top_line); vga->scr_top_line = LASTLINE(vga->scr_top_line);
} }
else { else
if (CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE) >= SCR_HEIGHT) { {
if (CYCLE_SUB(vga->scr_top_line, vga->scr_cur_line, SCR_MAXLINE) >= SCR_HEIGHT)
{
vga->scr_top_line = CYCLE_SUB(SCR_HEIGHT / 2, vga->scr_cur_line, SCR_MAXLINE); vga->scr_top_line = CYCLE_SUB(SCR_HEIGHT / 2, vga->scr_cur_line, SCR_MAXLINE);
} }

View File

@ -20,20 +20,26 @@ int main(int arg, char *argv[])
{ {
printf("test %d\n", i); printf("test %d\n", i);
} }
for (int i = 0; i < 2; ++i) // for (int i = 0; i < 2; ++i)
// {
// printf("\x1b[42;31m1111111111");
// // printf("\x1b[m1111111111");
// printf("2222222222");
// printf("3333333333");
// printf("4444444444");
// printf("5555555555");
// printf("6666666666");
// printf("7777777777");
// // printf("\x1b[5F");
// printf("8888888888");
// printf("9999999999\r\b\b\n");
// }
for (int i = 0; i < 10; i++)
{ {
printf("\x1b[42;31m1111111111"); printf("11111111111111111\n");
// printf("\x1b[m1111111111");
printf("2222222222");
printf("3333333333");
printf("4444444444");
printf("5555555555");
printf("6666666666");
printf("7777777777");
// printf("\x1b[5F");
printf("8888888888");
printf("9999999999\r\b\b\n");
} }
printf("111111111");
printf("\x1b[2S");
while (1) while (1)
; ;