diff --git a/inc/keyboard.h b/inc/keyboard.h index 75b6a67..6ba0ac4 100644 --- a/inc/keyboard.h +++ b/inc/keyboard.h @@ -3,6 +3,7 @@ #include "type.h" +#define KEYBOARD_BUF_REG 0x60 void add_keyboard_buf(u8 ch); #endif /* MINIOS_KEYBOARD_H */ \ No newline at end of file diff --git a/inc/process.h b/inc/process.h index c8526e3..7d4d668 100644 --- a/inc/process.h +++ b/inc/process.h @@ -31,8 +31,11 @@ typedef struct s_proc { u32 pid; /* process id passed in from MM */ char p_name[16]; /* name of the process */ }PROCESS; - +#ifdef HAPPY_SNAKE +#define PCB_SIZE 1 +#else #define PCB_SIZE 3 +#endif /* 指向当前进程pcb的指针 */ extern PROCESS *p_proc_ready; /* pcb表 */ diff --git a/inc/time.h b/inc/time.h index b29a1a9..e1c9ff8 100644 --- a/inc/time.h +++ b/inc/time.h @@ -6,4 +6,10 @@ void timecounter_inc(); size_t clock(); +void change_8253Counter0(int hertz); +#define TIMER0 0x40 +#define TIMER_MODEREG 0x43 +#define TIMER_MODE 0x34 +#define TIMER_FREQ 1193182L + #endif \ No newline at end of file diff --git a/inc/trap.h b/inc/trap.h index b6c1d69..938752f 100644 --- a/inc/trap.h +++ b/inc/trap.h @@ -72,7 +72,7 @@ void exception_handler(int vec_no, int err_code, int eip, /* 外设中断实际处理函数(C接口) */ void default_interrupt_handler(int irq); void clock_interrupt_handler(int irq); - +void keyboard_interrupt_handler(int irq); /* 外设中断实际处理函数表 */ extern void (*irq_table[])(int); diff --git a/inc/type.h b/inc/type.h index 0a95dc3..895dcb7 100644 --- a/inc/type.h +++ b/inc/type.h @@ -4,6 +4,7 @@ #ifndef NULL #define NULL ((void*) 0) #endif +// #define HAPPY_SNAKE typedef _Bool bool; enum { false, true }; diff --git a/kern/keyboard.c b/kern/keyboard.c index 29a4792..8736226 100644 --- a/kern/keyboard.c +++ b/kern/keyboard.c @@ -1,6 +1,7 @@ #include "keymap.h" #include "stdio.h" #include "type.h" +#include "x86.h" #define KB_INBUF_SIZE 4 @@ -23,6 +24,14 @@ static KB_INPUT kb_input = { void add_keyboard_buf(u8 ch) { + if (kb_input.count < KB_INBUF_SIZE) { + *(kb_input.p_head) = ch; + kb_input.p_head ++; + if (kb_input.p_head == kb_input.buf + KB_INBUF_SIZE) { + kb_input.p_head = kb_input.buf; + } + kb_input.count ++; + } } /* @@ -32,5 +41,18 @@ add_keyboard_buf(u8 ch) u8 getch(void) { - return -1; + if (kb_input.count == 0) + return -1; + else { + // disable_int(); + // in user mode, cli and sti will only cause protection exception + u8 val = *(kb_input.p_tail); + kb_input.p_tail ++; + if (kb_input.p_tail == kb_input.buf + KB_INBUF_SIZE) { + kb_input.p_tail = kb_input.buf; + } + kb_input.count --; + // enable_int(); + return val; + } } \ No newline at end of file diff --git a/kern/main.c b/kern/main.c index 919620f..a60c7cd 100644 --- a/kern/main.c +++ b/kern/main.c @@ -6,6 +6,9 @@ #include "type.h" #include "trap.h" #include "x86.h" +#include "time.h" +#include "keyboard.h" +#include "game.h" /* * 三个测试函数,用户进程的执行流 @@ -13,8 +16,12 @@ void TestA() { int i = 0; + u8 ch; while(1){ - kprintf("A%d.",i++); + if ((ch = getch()) != 255) { + kprintf("%c", ch); + } + // kprintf("A%d.",i++); for (int j = 0 ; j < 5e7 ; j++) ;//do nothing } @@ -24,7 +31,7 @@ void TestB() { int i = 0; while(1){ - kprintf("B%d.",i++); + // kprintf("B%d.",i++); for (int j = 0 ; j < 5e7 ; j++) ;//do nothing } @@ -34,7 +41,7 @@ void TestC() { int i = 0; while(1){ - kprintf("C%d.",i++); + // kprintf("C%d.",i++); for (int j = 0 ; j < 5e7 ; j++) ;//do nothing } @@ -49,6 +56,14 @@ char process_stack[STACK_TOTSIZE]; PROCESS *p_proc_ready; // pcb表 PROCESS proc_table[PCB_SIZE]; +#ifdef HAPPY_SNAKE +void (*entry[]) = { + startGame +}; +char pcb_name[][16] = { + "SNAKE" +}; +#else void (*entry[]) = { TestA, TestB, @@ -59,7 +74,7 @@ char pcb_name[][16] = { "TestB", "TestC", }; - +#endif /* * 内核的main函数 * 用于初始化用户进程,然后将执行流交给用户进程 @@ -94,8 +109,9 @@ void kernel_main() p_proc_ready = proc_table; + change_8253Counter0(1000); enable_irq(CLOCK_IRQ); - + enable_irq(KEYBOARD_IRQ); restart(); assert(0); } \ No newline at end of file diff --git a/kern/time.c b/kern/time.c index e080889..385eea4 100644 --- a/kern/time.c +++ b/kern/time.c @@ -1,5 +1,6 @@ #include "type.h" #include "time.h" +#include "x86.h" static size_t timecounter; @@ -19,4 +20,17 @@ size_t clock() { return timecounter; +} + +void +change_8253Counter0(int hertz) { + outb(TIMER_MODEREG, TIMER_MODE); + outb(TIMER0, (u8)(TIMER_FREQ / hertz)); + outb(TIMER0, (u8)((TIMER_FREQ / hertz) >> 8)); + /* + 8253's counter is 2bytes long + port 0x43 be the Mode Control Register + Orange book writes 00_11_010_0 into this reg, which means + SelectCounter0 | RW low byte first and then high byte | rate generator mode | binary counter + */ } \ No newline at end of file diff --git a/kern/trap.c b/kern/trap.c index 7d268fb..fdd6c01 100644 --- a/kern/trap.c +++ b/kern/trap.c @@ -4,6 +4,8 @@ #include "time.h" #include "trap.h" #include "x86.h" +#include "keymap.h" +#include "keyboard.h" /* * 当前内核需要处理中断的数量 @@ -12,7 +14,7 @@ int k_reenter; void (*irq_table[16])(int) = { clock_interrupt_handler, - default_interrupt_handler, + keyboard_interrupt_handler, default_interrupt_handler, default_interrupt_handler, default_interrupt_handler, @@ -101,10 +103,29 @@ exception_handler(int vec_no, int err_code, int eip, int cs, int eflags) void clock_interrupt_handler(int irq) { - kprintf("#"); + static unsigned int _sched_count = 0; + // kprintf("i%d", clock()); timecounter_inc(); - p_proc_ready++; + _sched_count ++; + if (p_proc_ready == proc_table) { + _sched_count ++; + if (_sched_count >= 20) { + p_proc_ready ++; + _sched_count = 0; + } + } else { + p_proc_ready ++; + } if (p_proc_ready >= proc_table + PCB_SIZE) { p_proc_ready = proc_table; } +} + +void keyboard_interrupt_handler(int irq) { + // kprintf("K"); + u8 scode = inb(KEYBOARD_BUF_REG); + if (scode < sizeof(keymap) && keymap[scode] >= 'a' && keymap[scode] <= 'z') { + add_keyboard_buf(keymap[scode]); //only keep a-z MAKE CODE + // kprintf("%c", keymap[scode]); + } } \ No newline at end of file