diff --git a/09_day/Makefile b/09_day/Makefile index 2bda89c..8fa0b87 100644 --- a/09_day/Makefile +++ b/09_day/Makefile @@ -1,5 +1,5 @@ OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \ - int.obj fifo.obj + int.obj fifo.obj keyboard.obj mouse.obj TOOLPATH = ../z_tools/ INCPATH = ../z_tools/haribote/ @@ -56,7 +56,7 @@ haribote.img : ipl10.bin haribote.sys Makefile # 其他指令 -%.gas : %.c Makefile +%.gas : %.c bootpack.h Makefile $(CC1) -o $*.gas $*.c %.nas : %.gas Makefile diff --git a/09_day/bootpack.c b/09_day/bootpack.c index b0a023f..f6fe864 100644 --- a/09_day/bootpack.c +++ b/09_day/bootpack.c @@ -3,17 +3,6 @@ #include "bootpack.h" #include -extern struct FIFO8 keyfifo, mousefifo; - -struct MOUSE_DEC { - unsigned char buf[3], phase; - int x, y, btn; -}; - -void enable_mouse(struct MOUSE_DEC *mdec); -int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat); -void init_keyboard(void); - void HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; @@ -97,85 +86,3 @@ void HariMain(void) } } -#define PORT_KEYDAT 0x0060 -#define PORT_KEYSTA 0x0064 -#define PORT_KEYCMD 0x0064 -#define KEYSTA_SEND_NOTREADY 0x02 -#define KEYCMD_WRITE_MODE 0x60 -#define KBC_MODE 0x47 - -void wait_KBC_sendready(void) -{ - /* 等待键盘控制电路准备完毕 */ - for (;;) { - if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) { - break; - } - } - return; -} - -void init_keyboard(void) -{ - /* 初始化键盘控制电路 */ - wait_KBC_sendready(); - io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE); - wait_KBC_sendready(); - io_out8(PORT_KEYDAT, KBC_MODE); - return; -} - -#define KEYCMD_SENDTO_MOUSE 0xd4 -#define MOUSECMD_ENABLE 0xf4 - -void enable_mouse(struct MOUSE_DEC *mdec){ - /* 鼠标有效 */ - wait_KBC_sendready(); - io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); - wait_KBC_sendready(); - io_out8(PORT_KEYDAT, MOUSECMD_ENABLE); - /* 顺利的话,ACK(0xfa)会被送过来 */ - mdec->phase = 0; /* 等待0xfa的阶段 */ - return; -} - -int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat){ - if (mdec->phase == 0) { - /* 等待鼠标的0xfa的阶段 */ - if (dat == 0xfa) { - mdec->phase = 1; - } - return 0; - } - if (mdec->phase == 1) { - /* 等待鼠标第一字节的阶段 */ - mdec->buf[0] = dat; - mdec->phase = 2; - return 0; - } - if (mdec->phase == 2) { - /* 等待鼠标第二字节的阶段 */ - mdec->buf[1] = dat; - mdec->phase = 3; - return 0; - } - if (mdec->phase == 3) { - /* 等待鼠标第二字节的阶段 */ - mdec->buf[2] = dat; - mdec->phase = 1; - mdec->btn = mdec->buf[0] & 0x07; - mdec->x = mdec->buf[1]; - mdec->y = mdec->buf[2]; - if ((mdec->buf[0] & 0x10) != 0) { - mdec->x |= 0xffffff00; - } - if ((mdec->buf[0] & 0x20) != 0) { - mdec->y |= 0xffffff00; - } - /* 鼠标的y方向与画面符号相反 */ - mdec->y = - mdec->y; - return 1; - } - /* 应该不可能到这里来 */ - return -1; -} diff --git a/09_day/bootpack.h b/09_day/bootpack.h index 650af9c..a143478 100644 --- a/09_day/bootpack.h +++ b/09_day/bootpack.h @@ -85,9 +85,7 @@ void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar); /* int.c */ void init_pic(void); -void inthandler21(int *esp); void inthandler27(int *esp); -void inthandler2c(int *esp); #define PIC0_ICW1 0x0020 #define PIC0_OCW2 0x0020 #define PIC0_IMR 0x0021 @@ -100,3 +98,21 @@ void inthandler2c(int *esp); #define PIC1_ICW2 0x00a1 #define PIC1_ICW3 0x00a1 #define PIC1_ICW4 0x00a1 + +/* keyboard.c */ +void inthandler21(int *esp); +void wait_KBC_sendready(void); +void init_keyboard(void); +extern struct FIFO8 keyfifo; +#define PORT_KEYDAT 0x0060 +#define PORT_KEYCMD 0x0064 + +/* mouse.c */ +struct MOUSE_DEC { + unsigned char buf[3], phase; + int x, y, btn; +}; +void inthandler2c(int *esp); +void enable_mouse(struct MOUSE_DEC *mdec); +int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat); +extern struct FIFO8 mousefifo; diff --git a/09_day/int.c b/09_day/int.c index 729510c..7c4226b 100644 --- a/09_day/int.c +++ b/09_day/int.c @@ -26,32 +26,6 @@ void init_pic(void) #define PORT_KEYDAT 0x0060 -struct FIFO8 keyfifo; - -void inthandler21(int *esp) -/* 来自PS/2键盘的中断 */ -{ - struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; - unsigned char data, s[4]; - io_out8(PIC0_OCW2, 0x61); /* 通知PIC IRQ-01 已经受理完毕 */ - data = io_in8(PORT_KEYDAT); - fifo8_put(&keyfifo, data); - return; -} - -struct FIFO8 mousefifo; - -void inthandler2c(int *esp) -/* 来自PS/2鼠标的中断 */ -{ - unsigned char data; - io_out8(PIC1_OCW2, 0x64); /* 通知PIC IRQ-12 已经受理完毕 */ - io_out8(PIC0_OCW2, 0x62); /* 通知PIC IRQ-02 已经受理完毕 */ - data = io_in8(PORT_KEYDAT); - fifo8_put(&mousefifo, data); - return; -} - void inthandler27(int *esp) /* PIC0中断的不完整策略 */ /* 这个中断在Athlon64X2上通过芯片组提供的便利,只需执行一次 */ diff --git a/09_day/keyboard.c b/09_day/keyboard.c new file mode 100644 index 0000000..3d0b190 --- /dev/null +++ b/09_day/keyboard.c @@ -0,0 +1,39 @@ +/* 键盘控制代码 */ + +#include "bootpack.h" + +struct FIFO8 keyfifo; + +void inthandler21(int *esp) { + /* 来自PS/2键盘的中断 */ + struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; + unsigned char data, s[4]; + io_out8(PIC0_OCW2, 0x61); /* 通知PIC IRQ-01 已经受理完毕 */ + data = io_in8(PORT_KEYDAT); + fifo8_put(&keyfifo, data); + return; +} + +#define PORT_KEYSTA 0x0064 +#define KEYSTA_SEND_NOTREADY 0x02 +#define KEYCMD_WRITE_MODE 0x60 +#define KBC_MODE 0x47 + +void wait_KBC_sendready(void) { + /* 等待键盘控制电路准备完毕 */ + for (;;) { + if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) { + break; + } + } + return; +} + +void init_keyboard(void) { + /* 初始化键盘控制电路 */ + wait_KBC_sendready(); + io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE); + wait_KBC_sendready(); + io_out8(PORT_KEYDAT, KBC_MODE); + return; +} diff --git a/09_day/mouse.c b/09_day/mouse.c new file mode 100644 index 0000000..8979b35 --- /dev/null +++ b/09_day/mouse.c @@ -0,0 +1,70 @@ +/* 鼠标控制代码 */ + +#include "bootpack.h" + +struct FIFO8 mousefifo; + +void inthandler2c(int *esp) { + /* 来自PS/2鼠标的中断 */ + unsigned char data; + io_out8(PIC1_OCW2, 0x64); /* 通知PIC IRQ-12 已经受理完毕 */ + io_out8(PIC0_OCW2, 0x62); /* 通知PIC IRQ-02 已经受理完毕 */ + data = io_in8(PORT_KEYDAT); + fifo8_put(&mousefifo, data); + return; +} + +#define KEYCMD_SENDTO_MOUSE 0xd4 +#define MOUSECMD_ENABLE 0xf4 + +void enable_mouse(struct MOUSE_DEC *mdec) { + /* 鼠标有效 */ + wait_KBC_sendready(); + io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); + wait_KBC_sendready(); + io_out8(PORT_KEYDAT, MOUSECMD_ENABLE); + /* 顺利的话,ACK(0xfa)会被送过来 */ + mdec->phase = 0; /* 等待0xfa的阶段 */ + return; +} + +int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat) { + if (mdec->phase == 0) { + /* 等待鼠标的0xfa的阶段 */ + if (dat == 0xfa) { + mdec->phase = 1; + } + return 0; + } + if (mdec->phase == 1) { + /* 等待鼠标第一字节的阶段 */ + mdec->buf[0] = dat; + mdec->phase = 2; + return 0; + } + if (mdec->phase == 2) { + /* 等待鼠标第二字节的阶段 */ + mdec->buf[1] = dat; + mdec->phase = 3; + return 0; + } + if (mdec->phase == 3) { + /* 等待鼠标第二字节的阶段 */ + mdec->buf[2] = dat; + mdec->phase = 1; + mdec->btn = mdec->buf[0] & 0x07; + mdec->x = mdec->buf[1]; + mdec->y = mdec->buf[2]; + if ((mdec->buf[0] & 0x10) != 0) { + mdec->x |= 0xffffff00; + } + if ((mdec->buf[0] & 0x20) != 0) { + mdec->y |= 0xffffff00; + } + /* 鼠标的y方向与画面符号相反 */ + mdec->y = - mdec->y; + return 1; + } + /* 应该不可能到这里来 */ + return -1; +}