diff --git a/10_day/Makefile b/10_day/Makefile index 7546fc3..71add12 100644 --- a/10_day/Makefile +++ b/10_day/Makefile @@ -1,5 +1,5 @@ OBJS_BOOTPACK = bootpack.obj naskfunc.obj hankaku.obj graphic.obj dsctbl.obj \ - int.obj fifo.obj keyboard.obj mouse.obj memory.obj + int.obj fifo.obj keyboard.obj mouse.obj memory.obj sheet.obj TOOLPATH = ../z_tools/ INCPATH = ../z_tools/haribote/ diff --git a/10_day/bootpack.c b/10_day/bootpack.c index 4f13ff3..7dd7d2c 100644 --- a/10_day/bootpack.c +++ b/10_day/bootpack.c @@ -9,6 +9,9 @@ void HariMain(void) char s[40], mcursor[256], keybuf[32], mousebuf[128]; int mx, my, i; struct MOUSE_DEC mdec; + struct SHTCTL *shtctl; + struct SHEET *sht_back, *sht_mouse; + unsigned char *buf_back, buf_mouse[256]; unsigned int memtotal; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; @@ -30,16 +33,25 @@ void HariMain(void) memman_free(memman, 0x00400000, memtotal - 0x00400000); init_palette(); - init_screen8(binfo->vram, binfo->scrnx, binfo->scrny); - mx = (binfo->scrnx - 16) / 2; /* 计算画面中心坐标 */ + shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny); + sht_back = sheet_alloc(shtctl); + sht_mouse = sheet_alloc(shtctl); + buf_back = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny); + sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 没有透明色 */ + sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99); /* 透明色号99 */ + init_screen8(buf_back, binfo->scrnx, binfo->scrny); + init_mouse_cursor8(buf_mouse, 99); /* 背景色号99 */ + sheet_slide(shtctl, sht_back, 0, 0); + mx = (binfo->scrnx - 16) / 2; /* 按显示在画面中央来计算坐标 */ my = (binfo->scrny - 28 - 16) / 2; - init_mouse_cursor8(mcursor, COL8_008484); - putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16); - sprintf(s, "(%d, %d)", mx, my); - putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); - + sheet_slide(shtctl, sht_mouse, mx, my); + sheet_updown(shtctl, sht_back, 0); + sheet_updown(shtctl, sht_mouse, 1); + sprintf(s, "(%3d, %3d)", mx, my); + putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); sprintf(s, "memory %dMB free : %dKB", memtotal / (1024 * 1024), memman_total(memman) / 1024); - putfonts8_asc(binfo->vram, binfo->scrnx, 0, 32, COL8_FFFFFF, s); + putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s); + sheet_refresh(shtctl); for (;;) { io_cli(); @@ -50,8 +62,9 @@ void HariMain(void) i = fifo8_get(&keyfifo); io_sti(); sprintf(s, "%02X", i); - boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 16, 15, 31); - putfonts8_asc(binfo->vram, binfo->scrnx, 0, 16, COL8_FFFFFF, s); + boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 16, 15, 31); + putfonts8_asc(buf_back, binfo->scrnx, 0, 16, COL8_FFFFFF, s); + sheet_refresh(shtctl); } else if (fifo8_status(&mousefifo) != 0) { i = fifo8_get(&mousefifo); io_sti(); @@ -67,10 +80,9 @@ void HariMain(void) if ((mdec.btn & 0x04) != 0) { s[2] = 'C'; } - boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31); - putfonts8_asc(binfo->vram, binfo->scrnx, 32, 16, COL8_FFFFFF, s); - /* 鼠标指针的移动 */ - boxfill8(binfo->vram, binfo->scrnx, COL8_008484, mx, my, mx + 15, my + 15); /* 隐藏鼠标 */ + boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31); + putfonts8_asc(buf_back, binfo->scrnx, 32, 16, COL8_FFFFFF, s); + /* 移动光标 */ mx += mdec.x; my += mdec.y; if (mx < 0) { @@ -86,9 +98,9 @@ void HariMain(void) my = binfo->scrny - 16; } sprintf(s, "(%3d, %3d)", mx, my); - boxfill8(binfo->vram, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 隐藏坐标 */ - putfonts8_asc(binfo->vram, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 显示坐标 */ - putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16); /* 描画鼠标 */ + boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 消坐标 */ + putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 写坐标 */ + sheet_slide(shtctl, sht_mouse, mx, my); /* 包含sheet_refresh含sheet_refresh */ } } } diff --git a/10_day/bootpack.h b/10_day/bootpack.h index 3e572bb..e6a6809 100644 --- a/10_day/bootpack.h +++ b/10_day/bootpack.h @@ -13,14 +13,19 @@ struct BOOTINFO { /* 0x0ff0-0x0fff */ void io_hlt(void); void io_cli(void); void io_sti(void); +void io_stihlt(void); +int io_in8(int port); void io_out8(int port, int data); int io_load_eflags(void); void io_store_eflags(int eflags); void load_gdtr(int limit, int addr); void load_idtr(int limit, int addr); +int load_cr0(void); +void store_cr0(int cr0); void asm_inthandler21(void); void asm_inthandler27(void); void asm_inthandler2c(void); +unsigned int memtest_sub(unsigned int start, unsigned int end); /* fifo.c */ struct FIFO8 { @@ -119,7 +124,7 @@ extern struct FIFO8 mousefifo; /* memory.c */ #define MEMMAN_FREES 4090 /* 大约是32KB*/ -#define MEMMAN_ADDR 0x003c0000 +#define MEMMAN_ADDR 0x003c0000 struct FREEINFO { /* 可用信息 */ unsigned int addr, size; @@ -133,6 +138,30 @@ unsigned int memtest(unsigned int start, unsigned int end); void memman_init(struct MEMMAN *man); unsigned int memman_total(struct MEMMAN *man); unsigned int memman_alloc(struct MEMMAN *man, unsigned int size); -unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size); int memman_free(struct MEMMAN *man, unsigned int addr, unsigned int size); +unsigned int memman_alloc_4k(struct MEMMAN *man, unsigned int size); int memman_free_4k(struct MEMMAN *man, unsigned int addr, unsigned int size); + +/* sheet.c */ +#define MAX_SHEETS 256 +#define SHEET_USE 1 + +struct SHEET { + unsigned char *buf; + int bxsize, bysize, vx0, vy0, col_inv, height, flags; +}; + +struct SHTCTL { + unsigned char *vram; + int xsize, ysize, top; + struct SHEET *sheets[MAX_SHEETS]; + struct SHEET sheets0[MAX_SHEETS]; +}; + +struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize); +struct SHEET *sheet_alloc(struct SHTCTL *ctl); +void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv); +void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height); +void sheet_refresh(struct SHTCTL *ctl); +void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0); +void sheet_free(struct SHTCTL *ctl, struct SHEET *sht); diff --git a/10_day/sheet.c b/10_day/sheet.c new file mode 100644 index 0000000..dd05ca9 --- /dev/null +++ b/10_day/sheet.c @@ -0,0 +1,142 @@ +/* sheet */ + +#include "bootpack.h" + +#define SHEET_USE 1 + +struct SHTCTL *shtctl_init(struct MEMMAN *memman, unsigned char *vram, int xsize, int ysize) +{ + struct SHTCTL *ctl; + int i; + ctl = (struct SHTCTL *) memman_alloc_4k(memman, sizeof (struct SHTCTL)); + if (ctl == 0) { + goto err; + } + ctl->vram = vram; + ctl->xsize = xsize; + ctl->ysize = ysize; + ctl->top = -1; /* �V�[�g�͈ꖇ���Ȃ� */ + for (i = 0; i < MAX_SHEETS; i++) { + ctl->sheets0[i].flags = 0; /* 标记为未使用 */ + } +err: + return ctl; +} + +struct SHEET *sheet_alloc(struct SHTCTL *ctl) +{ + struct SHEET *sht; + int i; + for (i = 0; i < MAX_SHEETS; i++) { + if (ctl->sheets0[i].flags == 0) { + sht = &ctl->sheets0[i]; + sht->flags = SHEET_USE; /* 标记为正在使用*/ + sht->height = -1; /* 隐藏 */ + return sht; + } + } + return 0; /* 所有的SHEET都处于正在使用状态*/ +} + +void sheet_setbuf(struct SHEET *sht, unsigned char *buf, int xsize, int ysize, int col_inv) +{ + sht->buf = buf; + sht->bxsize = xsize; + sht->bysize = ysize; + sht->col_inv = col_inv; + return; +} + +void sheet_updown(struct SHTCTL *ctl, struct SHEET *sht, int height) +{ + int h, old = sht->height; /* 存储设置前的高度信息 */ + if (height > ctl->top + 1) { + height = ctl->top + 1; + } + if (height < -1) { + height = -1; + } + sht->height = height;/* 设定高度 */ + + /* 下面主要是进行sheets[ ]的重新排列 */ + if (old > height) { /* 比以前低 */ + if (height >= 0) { + /* 把中间的往上提 */ + for (h = old; h > height; h--) { + ctl->sheets[h] = ctl->sheets[h - 1]; + ctl->sheets[h]->height = h; + } + ctl->sheets[height] = sht; + } else { /* 隐藏 */ + if (ctl->top > old) { + /* 把上面的降下来 */ + for (h = old; h < ctl->top; h++) { + ctl->sheets[h] = ctl->sheets[h + 1]; + ctl->sheets[h]->height = h; + } + } + ctl->top--; /* 由于显示中的图层减少了一个,所以最上面的图层高度下降 */ + } + sheet_refresh(ctl); /* 按新图层的信息重新绘制画面 */ + } else if (old < height) { /* 比以前高 */ + if (old >= 0) { + /* 把中间的拉下去 */ + for (h = old; h < height; h++) { + ctl->sheets[h] = ctl->sheets[h + 1]; + ctl->sheets[h]->height = h; + } + ctl->sheets[height] = sht; + } else { /* 由隐藏状态转为显示状态 */ + /* 将已在上面的提上来 */ + for (h = ctl->top; h >= height; h--) { + ctl->sheets[h + 1] = ctl->sheets[h]; + ctl->sheets[h + 1]->height = h + 1; + } + ctl->sheets[height] = sht; + ctl->top++; /* 由于已显示的图层增加了1个,所以最上面的图层高度增加 */ + } + sheet_refresh(ctl); /* 按新图层信息重新绘制画面 */ + } + return; +} + +void sheet_refresh(struct SHTCTL *ctl) +{ + int h, bx, by, vx, vy; + unsigned char *buf, c, *vram = ctl->vram; + struct SHEET *sht; + for (h = 0; h <= ctl->top; h++) { + sht = ctl->sheets[h]; + buf = sht->buf; + for (by = 0; by < sht->bysize; by++) { + vy = sht->vy0 + by; + for (bx = 0; bx < sht->bxsize; bx++) { + vx = sht->vx0 + bx; + c = buf[by * sht->bxsize + bx]; + if (c != sht->col_inv) { + vram[vy * ctl->xsize + vx] = c; + } + } + } + } + return; +} + +void sheet_slide(struct SHTCTL *ctl, struct SHEET *sht, int vx0, int vy0) +{ + sht->vx0 = vx0; + sht->vy0 = vy0; + if (sht->height >= 0) { /* 如果正在显示*/ + sheet_refresh(ctl); /* 按新图层的信息刷新画面 */ + } + return; +} + +void sheet_free(struct SHTCTL *ctl, struct SHEET *sht) +{ + if (sht->height >= 0) { + sheet_updown(ctl, sht, -1); /* 如果处于显示状态,则先设定为隐藏 */ + } + sht->flags = 0; /* "未使用"标志 */ + return; +}