我们重写了缓冲区,使其能进行键盘和鼠标的读取
效果地址:http://blog.csdn.net/ucan23/article/details/17111431点击打开链接
/* filename: fifo.c
* description: 包含了有关缓冲区的操作
* author: Howard
* date: 2013-12-03
* version: v1.0
*/
#include "bootpack.h"
#define FLAGS_OVERRUN 0x0001
void fifo32_init(struct FIFO32 *fifo, int size, int *buf)
{
fifo->size = size;
fifo->buf = buf;
fifo->free = size;
fifo->flags = 0;
fifo->p = 0;
fifo->q = 0;
return;
}
int fifo32_put(struct FIFO32 *fifo, int data)
{
/*向FIFO传送数据并保存*/
if (0==fifo->free){
/*溢出*/
fifo->flags |= FLAGS_OVERRUN;
return -1;
}
fifo->buf[fifo->p] = data;
fifo->p ++;
if (fifo->p == fifo->size){
fifo->p = 0;
}
fifo->free --;
return;
}
int fifo32_get(struct FIFO32 *fifo)
{
/*从FIFO读取一个数据*/
int data;
if (fifo->free == fifo->size){
/*缓冲区为空,没有数据*/
return -1;
}
data = fifo->buf[fifo->q];
fifo->q ++;
if (fifo->q == fifo->size){
fifo->q = 0;
}
fifo->free ++;
return data;
}
int fifo32_status(struct FIFO32 *fifo)
{
/*返回缓冲区中还有多少数据*/
return (fifo->size - fifo->free);
}
键盘操作也做了相应的修改
/* filename: keyboard.c
* description: 包含了有关键盘的操作
* author: Howard
* date: 2013-12-01
* version: v1.0
*/
#include "bootpack.h"
struct FIFO32 *keyfifo;
int keydata0;
void inthandler21(int *esp)
{
/*ps/2键盘中断*/
//struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO;
int data;
io_out8(PIC0_OCW2, 0x61);
data = io_in8(PORT_KEYDAT);
fifo32_put(keyfifo, data+keydata0);
/*if (keybuf.len<32){
keybuf.data[keybuf.next_w] = data;
keybuf.len ++;
keybuf.next_w ++;
if (keybuf.next_w == 32) {
keybuf.next_w = 0;
}
}
*/
return;
}
void wait_KBC_sendready(void)
{
for (;;){
if (0==(io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY)){
break;
}
}
return;
}
void init_keyboard(struct FIFO32 *fifo, int data0)
{
keyfifo = fifo;
keydata0 = data0;
wait_KBC_sendready();
io_out8(PORT_KEYCMD, KEYCMD_WRITE_MODE);
wait_KBC_sendready();
io_out8(PORT_KEYDAT, KBC_MODE);
return;
}
注:凡是原来是fifo8(FIFO8)的地方都改为了fifo32(FIFO32),因为我们的结构体的定义发生了变化
为了提供对高分辨率的支持我们修改了开机后系统的启动代码
; ucan23-os boot asm
; TAB=4
; 此程序前一个版本存在的错误:将skip写成了ship
; 将[INSTRSET "i486p"]写成了[INSTREST "i486p"]
; 将waitkbdout写成了waitkdbout
[INSTRSET "i486p"]
VBEMODE EQU 0x105
BOTPAK EQU 0x00280000
DSKCAC EQU 0x00100000
DSKCAC0 EQU 0x00008000
; 有关BOOT_INFO
CYLS EQU 0x0ff0
LEDS EQU 0x0ff1
VMODE EQU 0x0ff2
SCRNX EQU 0x0ff4
SCRNY EQU 0x0ff6
VRAM EQU 0x0ff8
ORG 0xc200
;确认VBE是否存在
MOV AX, 0x9000
MOV ES, AX
MOV DI, 0
MOV AX, 0x4f00
INT 0x10
CMP AX, 0x004f
JNE scrn320 ;为了使用320*200模式这里做出了修改
;检查VBE的版本
MOV AX, [ES:DI+4]
CMP AX, 0x0200
JB scrn320
;取得画面模式信息
MOV CX, VBEMODE
MOV AX, 0x4f01
INT 0x10
CMP AX, 0x004f
JNE scrn320
;画面模式信息的确认
CMP BYTE [ES:DI+0x19],8
JNE scrn320
CMP BYTE [ES:DI+0x1b],4
JNE scrn320
MOV AX,[ES:DI+0x00]
AND AX,0x0080
JZ scrn320
;画面模式的切换
MOV BX,VBEMODE+0x4000
MOV AX,0x4f02
INT 0x10
MOV BYTE [VMODE],8
MOV AX,[ES:DI+0x12]
MOV [SCRNX],AX
MOV AX,[ES:DI+0x14]
MOV [SCRNY],AX
MOV EAX,[ES:DI+0x28]
MOV [VRAM],EAX
JMP keystatus
; MOV BX, 0x4105
; MOV AX, 0x4f02
; INT 0x10
; MOV BYTE [VMODE], 8
; MOV WORD [SCRNX], 1024
; MOV WORD [SCRNY], 768
; MOV DWORD [VRAM], 0xe0000000
scrn320:
MOV AL, 0x13
MOV AH, 0x00
INT 0x10
MOV BYTE [VMODE], 8
MOV WORD [SCRNX], 320
MOV WORD [SCRNY], 200
MOV DWORD [VRAM], 0x000a0000
; 用BIOS获取LED指示灯的状态
keystatus:
MOV AH, 0x02
INT 0x16 ; keyboard BIOS
MOV [LEDS], AL
MOV AL, 0xff
OUT 0x21, AL
NOP
OUT 0xa1, AL
CLI
CALL waitkbdout
MOV AL, 0xd1
OUT 0x64, AL
CALL waitkbdout
MOV AL, 0xdf
OUT 0x60, AL
CALL waitkbdout
[INSTRSET "i486p"]
LGDT [GDTR0]
MOV EAX,CR0
AND EAX, 0x7fffffff
OR EAX, 0x00000001
MOV CR0, EAX
JMP pipelineflush
pipelineflush:
MOV AX, 1*8
MOV DS, AX
MOV ES, AX
MOV FS, AX
MOV GS, AX
MOV SS, AX
MOV ESI, bootpack
MOV EDI, BOTPAK
MOV ECX, 512*1024/4
CALL memcpy
MOV ESI, 0x7c00
MOV EDI, DSKCAC
MOV ECX, 512/4
CALL memcpy
MOV ESI, DSKCAC0+512
MOV EDI, DSKCAC+512
MOV ECX, 0
MOV CL, BYTE [CYLS]
IMUL ECX, 512*18*2/4
SUB ECX, 512/4
CALL memcpy
MOV EBX, BOTPAK
MOV ECX, [EBX+16]
ADD ECX, 3
SHR ECX, 2
JZ skip
MOV ESI, [EBX+20]
ADD ESI, EBX
MOV EDI, [EBX+12]
CALL memcpy
skip:
MOV ESP, [EBX+12]
JMP DWORD 2*8:0x0000001b
waitkbdout:
IN AL, 0x64
AND AL, 0x02
JNZ waitkbdout
RET
memcpy:
MOV EAX, [ESI]
ADD ESI, 4
MOV [EDI], EAX
ADD EDI, 4
SUB ECX, 1
JNZ memcpy
RET
ALIGNB 16
GDT0:
RESB 8
DW 0xffff,0x0000,0x9200,0x00cf
DW 0xffff,0x0000,0x9a28,0x0047
DW 0
GDTR0:
DW 8*3-1
DD GDT0
ALIGNB 16
bootpack:
最后给出主函数的修改:
/* filename: bootpack.c
* description: the UcanMain()file
* author: Howard
* date: 2013-11-28
* version: v1.0
*/
#include <stdio.h>
#include "bootpack.h"
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l);
void set490(struct FIFO32 *fifo, int mode);
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c);
void UcanMain(void)
{
char *vram;
char s[50];
int fifobuf[128];//mcursor[256], keybuf[32], mousebuf[128], timerbuf[8], timerbuf2[8], timerbuf3[8];
int mx, my, cursor_x, cursor_c;//鼠标的(x,y)
int xsize, ysize;
int i , count = 0;;
unsigned int memtotal;
struct MOUSE_DEC mdec; /*鼠标解码缩放的数据*/
struct SHTCTL *shtctl;
struct FIFO32 fifo;
struct FIFO32 timerfifo, timerfifo2, timerfifo3;
struct TIMER *timer, *timer2, *timer3;
struct SHEET *sht_back, *sht_mouse, *sht_win;
unsigned char *buf_back, buf_mouse[256], *buf_win;
static char keytable[0x54] = {
0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '^', 0, 0,
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '@', '[', 0, 0, 'A', 'S',
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', ':', 0, 0, ']', 'Z', 'X', 'C', 'V',
'B', 'N', 'M', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
'2', '3', '0', '.'
};
struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;
init_gdtidt();
init_pic();
io_sti();
fifo32_init(&fifo, 128, fifobuf);
//fifo8_init(&mousefifo, 128, mousebuf);
//fifo8_init(&timerfifo, 8, timerbuf);
//fifo8_init(&timerfifo2, 8, timerbuf2);
//fifo8_init(&timerfifo3, 8, timerbuf3);
init_pit();
init_keyboard(&fifo, 256);
enable_mouse(&fifo, 512, &mdec);
io_out8(PIC0_IMR, 0xf8);
io_out8(PIC1_IMR, 0xef);
timer = timer_alloc();
timer2 = timer_alloc();
timer3 = timer_alloc();
timer_init(timer, &fifo, 10);
timer_init(timer2, &fifo, 3);
timer_init(timer3, &fifo, 1);
timer_settime(timer, 1000);
timer_settime(timer2, 300);
timer_settime(timer3, 50);
//settimer(1000, &timerfifo, 1);
memtotal = memtest(0x00400000, 0xbfffffff);
memman_init(memman);
memman_free(memman, 0x00001000, 0x0009e000);
memman_free(memman, 0x00400000, memtotal - 0x00400000);
init_palette();
shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
sht_back = sheet_alloc(shtctl);
sht_mouse = sheet_alloc(shtctl);
sht_win = sheet_alloc(shtctl);
buf_back = (unsigned char *)memman_alloc_4k(memman, binfo->scrnx*binfo->scrny);
buf_win = (unsigned char *)memman_alloc_4k(memman, 160*52);
sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1);
sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99);
sheet_setbuf(sht_win, buf_win, 160, 52, -1);
//init_screen(binfo->vram, binfo->scrnx, binfo->scrny);
init_screen(buf_back, binfo->scrnx, binfo->scrny);
init_mouse_cursor8(buf_mouse, 99);
make_window8(buf_win, 160, 52, "Counter");
make_textbox8(sht_win, 8, 28, 144, 16, COL8_FFFFFF);
cursor_x = 8;
cursor_c = COL8_FFFFFF;
//putfonts8_asc(buf_win, 160, 24, 28, COL8_000000, "Welcome to");
//putfonts8_asc(buf_win, 160, 24, 44, COL8_000000, " Ucan-OS!");
sheet_slide(sht_back, 0, 0);
//init_mouse_cursor8(mcursor, 99);
xsize = (*binfo).scrnx;
ysize = (*binfo).scrny;
vram = (*binfo).vram;
mx = (binfo->scrnx-16) / 2;
my = (binfo->scrny-28-16) /2;
sheet_slide(sht_mouse, mx, my);
sheet_slide(sht_win, 80, 72);
sheet_updown(sht_back, 0);
sheet_updown(sht_win, 1);
sheet_updown(sht_mouse, 2);
//putblock8_8(buf_back, binfo->scrnx, 16, 16, mx, my, buf_mouse, 16);
putfonts8_asc(buf_back, binfo->scrnx, 8, 8, COL8_FFFFFF, "Hello, world!");
putfonts8_asc(buf_back, binfo->scrnx, 31, 31, COL8_000000, "Ucan23-OS");
putfonts8_asc(buf_back, binfo->scrnx, 30, 30, COL8_FFFFFF, "Ucan23-OS");
//putfonts8_asc_sht(sht_back, binfo->scrnx, 8, 0, COL8_FFFFFF, "Hello, world", 1);
//putfonts8_asc_sht(sht_back, binfo->scrnx, 31, 0, COL8_000000, "Ucan23-OS", 4);
//putfonts8_asc_sht(sht_back, binfo->scrnx, 30, 0, COL8_FFFFFF, "Ucan23-OS", 4);
sprintf(s, "scrnx = %d", binfo->scrnx);
putfonts8_asc(buf_back, binfo->scrnx, 16, 64, COL8_FFFFFF, s);
sprintf(s, "(%d, %d)", mx, my);
putfonts8_asc(buf_back, binfo->scrnx, mx+16, my+16, COL8_FFFFFF, s);
//io_out8(PIC0_IMR, 0xf9);
//io_out8(PIC1_IMR, 0xef);
sprintf(s, "Memory %dMB free: %dKB", memtotal/(1024*1024), memman_total(memman)/1024);
putfonts8_asc(buf_back, binfo->scrnx, 0, 136, COL8_FFFFFF, s);
sheet_refresh(sht_back, 0, 0, binfo->scrnx, binfo->scrny);
for (;;){
/*计数器程序*/
//count ++;
//sprintf(s, "%010d", timerctl.count);
//boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);
//putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);
//sheet_refresh(sht_win, 40, 28, 120, 44);
io_cli(); /*执行nashfunc.nas里的_io_hlt*/
if (0==fifo32_status(&fifo)){
io_sti();
} else {
i = fifo32_get(&fifo);
io_sti();
if (i>=256 && i<=511){ /*键盘数据*/
sprintf(s, "%02X", i-256);
boxfill8(buf_back, binfo->scrnx, COL8_000000, 0, 120, 15, 135);
putfonts8_asc(buf_back, binfo->scrnx, 0, 120, COL8_FFFFFF, s);
sheet_refresh(sht_back, 0, 120, 15*8, 136);
if (i<256+0x54)
{
if (keytable[i-256]!=0 && cursor_x<144){
s[0] = keytable[i-256];
s[1] = 0;
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, s, 1);
cursor_x += 8;
}
}
if (256+0x0e==i && cursor_x>8){
putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_FFFFFF, " ", 1);
cursor_x -= 8;
}
boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
} else if (i>=512 && i<=767){ /*鼠标数据*/
if (0 != mouse_decode(&mdec, i-512)){
sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);
if ((mdec.btn & 0x01)!=0){
s[1] = 'L';
}
if ((mdec.btn & 0x02)!=0){
s[3] = 'R';
}
if ((mdec.btn & 0x04)!=0){
s[2] = 'C';
}
boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 120, 32+15*8-1,135);
putfonts8_asc(buf_back, binfo->scrnx, 32, 120, COL8_FFFFFF, s);
sheet_refresh(sht_back, 32, 120, 32+15*8, 136);
/*鼠标指针的移动*/
//boxfill8(buf_back, binfo->scrnx, COL8_008484, mx, my, mx+15, my+15);/*隐藏鼠标*/
mx += mdec.x;
my += mdec.y;
if (mx<0){
mx = 0;
}
if (my<0){
my = 0;
}
if (mx>binfo->scrnx-1){
mx = binfo->scrnx-1;
}
if (my>binfo->scrny-1){
my = binfo->scrny-1;
}
sprintf(s, "(%3d, %3d)", mx, my);
boxfill8(buf_back, binfo->scrnx, COL8_008484,binfo->scrnx-100,120,binfo->scrnx , 136);
putfonts8_asc(buf_back, binfo->scrnx, binfo->scrnx-100, 120, COL8_FFFFFF,s);
sheet_refresh(sht_back, binfo->scrnx-100, 120, binfo->scrnx, 136);
//putblock8_8(binfo->vram,binfo->scrnx, 16, 16, mx, my, mcursor, 16);
sheet_slide(sht_mouse, mx, my);
if (0!=(mdec.btn&0x01)){
/*按下左键、移动sht_win*/
sheet_slide(sht_win, mx-80, my-8);
}
}
} else if (10==i){
//boxfill8(buf_back, binfo->scrnx, COL8_008484,binfo->scrnx-100,0,binfo->scrnx , 16);
putfonts8_asc(buf_back, binfo->scrnx, binfo->scrnx-100, 0, COL8_FFFFFF, "10[sec]" );
sheet_refresh(sht_back, binfo->scrnx-100, 0, binfo->scrnx, 16);
//sprintf(s, "%010d", count);
//putfonts8_asc(sht_win, binfo->scrnx, 40, 28, COL8_000000, s);
//sheet_refresh(sht_win, 0, 64, 56, 80);
//putfonts8_asc_sht(sht_win, 40, 28, COL8_000000, COL8_C6C6C6, s, 10);
} else if(3==i) {
putfonts8_asc(buf_back, binfo->scrnx, binfo->scrnx-100, 16, COL8_FFFFFF, "3[sec]" );
sheet_refresh(sht_back, binfo->scrnx-100, 16, binfo->scrnx, 32);
//count = 0;
} else if (i<=1){
if (i != 0) {
timer_init(timer3, &fifo, 0); /* 師偼0傪 */
cursor_c = COL8_000000;
} else {
timer_init(timer3, &fifo, 1); /* 師偼1傪 */
cursor_c = COL8_FFFFFF;
}
timer_settime(timer3, 50);
boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43);
sheet_refresh(sht_win, cursor_x, 28, cursor_x + 8, 44);
}
}
}
}
void make_window8(unsigned char *buf, int xsize, int ysize, char *title)
{
static char closebtn[14][16] = {
"OOOOOOOOOOOOOOO@",
"OQQQQQQQQQQQQQ$@",
"OQQQQQQQQQQQQQ$@",
"OQQQ@@QQQQ@@QQ$@",
"OQQQQ@@QQ@@QQQ$@",
"OQQQQQ@@@@QQQQ$@",
"OQQQQQQ@@QQQQQ$@",
"OQQQQQ@@@@QQQQ$@",
"OQQQQ@@QQ@@QQQ$@",
"OQQQ@@QQQQ@@QQ$@",
"OQQQQQQQQQQQQQ$@",
"OQQQQQQQQQQQQQ$@",
"O$$$$$$$$$$$$$$@",
"@@@@@@@@@@@@@@@@"
};
int x, y;
char c;
boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0 );
boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1 );
boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1);
boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2);
boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2);
boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1);
boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3);
boxfill8(buf, xsize, COL8_000084, 3, 3, xsize - 4, 20 );
boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2);
boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1);
putfonts8_asc(buf, xsize, 24, 4, COL8_FFFFFF, title);
for (y = 0; y < 14; y++) {
for (x = 0; x < 16; x++) {
c = closebtn[y][x];
if (c == '@') {
c = COL8_000000;
} else if (c == '$') {
c = COL8_848484;
} else if (c == 'Q') {
c = COL8_C6C6C6;
} else {
c = COL8_FFFFFF;
}
buf[(5 + y) * xsize + (xsize - 21 + x)] = c;
}
}
return;
}
void putfonts8_asc_sht(struct SHEET *sht, int x, int y, int c, int b, char *s, int l)
{
boxfill8(sht->buf, sht->bxsize, b, x, y, x+l*8-1, y+15);
putfonts8_asc(sht->buf, sht->bxsize, x, y, c, s);
sheet_refresh(sht, x, y, x+l*8, y+16);
return;
}
void set490(struct FIFO32 *fifo, int mode)
{
int i;
struct TIMER *timer;
if (0!=mode){
for (i=0; i<490; i++){
timer = timer_alloc();
timer_init(timer, fifo, 1024+i);
timer_settime(timer, 100*60*60*24*50+i*100);
}
}
return;
}
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c)
{
int x1 = x0 + sx, y1 = y0 + sy;
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 2, y0 - 3, x1 + 1, y0 - 3);
boxfill8(sht->buf, sht->bxsize, COL8_848484, x0 - 3, y0 - 3, x0 - 3, y1 + 1);
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x0 - 3, y1 + 2, x1 + 1, y1 + 2);
boxfill8(sht->buf, sht->bxsize, COL8_FFFFFF, x1 + 2, y0 - 3, x1 + 2, y1 + 2);
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 1, y0 - 2, x1 + 0, y0 - 2);
boxfill8(sht->buf, sht->bxsize, COL8_000000, x0 - 2, y0 - 2, x0 - 2, y1 + 0);
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x0 - 2, y1 + 1, x1 + 0, y1 + 1);
boxfill8(sht->buf, sht->bxsize, COL8_C6C6C6, x1 + 1, y0 - 2, x1 + 1, y1 + 1);
boxfill8(sht->buf, sht->bxsize, c, x0 - 1, y0 - 1, x1 + 0, y1 + 0);
return;
}
由于篇幅有限这里只给出部分代码,要是想要全部的代码的话,可以联系我,留下邮箱,我会给你们发送过去。
转载请注明出处:http://blog.csdn.net/ucan23/article/details/17111553点击打开链接