课程链接
代码
1.kernel.asm
%include "pm.inc"
org 8000h
VRAM_ADDRESS equ 0x000a0000
jmp LABEL_BEGIN
[SECTION .gdt]
; 段基址 段界限 属性
LABEL_GDT: Descriptor 0, 0, 0
LABEL_DESC_CODE32: Descriptor 0, 0fffffh, DA_CR | DA_32 | DA_LIMIT_4K
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0fffffh, DA_DRW
LABEL_DESC_VRAM: Descriptor 0, 0fffffh, DA_DRWA | DA_LIMIT_4K
LABEL_DESC_STACK: Descriptor 0, LenOfStackSection, DA_DRWA | DA_32
LABEL_DESC_FONT: Descriptor 0, 0fffffh, DA_DRW | DA_LIMIT_4K
LABEL_DESC_6: Descriptor 0, 0fffffh, 0409Ah
LABEL_DESC_7: Descriptor 0, 0, 0
LABEL_DESC_8: Descriptor 0, 0, 0
LABEL_DESC_9: Descriptor 0, 0, 0
GdtLen equ $ - LABEL_GDT
GdtPtr dw GdtLen - 1
dd 0
SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
SelectorStack equ LABEL_DESC_STACK - LABEL_GDT
SelectorVram equ LABEL_DESC_VRAM - LABEL_GDT
SelectorFont equ LABEL_DESC_FONT - LABEL_GDT
LABEL_IDT:
%rep 32
Gate SelectorCode32, SpuriousHandler,0, DA_386IGate
%endrep
.020h:
Gate SelectorCode32, timerHandler,0, DA_386IGate
.021h:
Gate SelectorCode32, KeyBoardHandler,0, DA_386IGate
%rep 10
Gate SelectorCode32, SpuriousHandler,0, DA_386IGate
%endrep
.2CH:
Gate SelectorCode32, mouseHandler,0, DA_386IGate
IdtLen equ $ - LABEL_IDT
IdtPtr dw IdtLen - 1
dd 0
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0100h
;calculate memory
ComputeMemory:
mov ebx, 0
mov di, MemChkBuf
.loop:
mov eax, 0E820h
mov ecx, 20
mov edx, 0534D4150h
int 15h
jc LABEL_MEM_CHK_FAIL
add di, 20
inc dword [dwMCRNumber]
cmp ebx, 0
jne .loop
jmp LABEL_MEM_CHK_OK
LABEL_MEM_CHK_FAIL:
mov dword [dwMCRNumber], 0
LABEL_MEM_CHK_OK:
mov bx, 0x4101
mov ax, 0x4f02
int 0x10
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32 + 2], ax
shr eax, 16
mov byte [LABEL_DESC_CODE32 + 4], al
mov byte [LABEL_DESC_CODE32 + 7], ah
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_STACK
mov word [LABEL_DESC_STACK + 2], ax
shr eax, 16
mov byte [LABEL_DESC_STACK + 4], al
mov byte [LABEL_DESC_STACK + 7], ah
xor eax, eax
mov ax, cs
shl eax, 4
add eax, LABEL_SYSTEM_FONT
mov word [LABEL_DESC_FONT + 2], ax
shr eax, 16
mov byte [LABEL_DESC_FONT + 4], al
mov byte [LABEL_DESC_FONT + 7], ah
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_GDT
mov dword [GdtPtr + 2], eax
lgdt [GdtPtr]
cli ;关中断
call init8259A
;prepare for loading IDT
xor eax, eax
mov ax, ds
shl eax, 4
add eax, LABEL_IDT
mov dword [IdtPtr + 2], eax
lidt [IdtPtr]
in al, 92h
or al, 00000010b
out 92h, al
mov eax, cr0
or eax , 1
mov cr0, eax
cli
jmp dword 1*8: 0
init8259A:
mov al, 011h
out 020h, al
call io_delay
out 0A0h, al
call io_delay
mov al, 020h
out 021h, al
call io_delay
mov al, 028h
out 0A1h, al
call io_delay
mov al, 004h
out 021h, al
call io_delay
mov al, 002h
out 0A1h, al
call io_delay
mov al, 001h
out 021h, al
call io_delay
out 0A1h, al
call io_delay
mov al, 11111000b ;允许键盘和时钟中断
out 021h, al
call io_delay
mov al, 11101111b ;允许鼠标中断
out 0A1h, al
call io_delay
ret
io_delay:
nop
nop
nop
nop
ret
[SECTION .s32]
[BITS 32]
LABEL_SEG_CODE32:
;initialize stack for c code
mov ax, SelectorStack
mov ss, ax
mov esp, TopOfStack1
mov ax, SelectorVram
mov ds, ax
mov ax, SelectorVideo
mov gs, ax
cli ;change
%include "ckernel.asm"
jmp $
_SpuriousHandler:
SpuriousHandler equ _SpuriousHandler - $$
iretd
_KeyBoardHandler:
KeyBoardHandler equ _KeyBoardHandler - $$
pushad
push ds
push es
push fs
push gs
call intHandlerFromC
pop gs
pop fs
pop es
pop ds
popad
iretd
_mouseHandler:
mouseHandler equ _mouseHandler - $$
pushad
push ds
push es
push fs
push gs
call intHandlerForMouse
pop gs
pop fs
pop es
pop ds
popad
iretd
_timerHandler:
timerHandler equ _timerHandler - $$
pushad
push ds
push es
push fs
push gs
call intHandlerForTimer
pop gs
pop fs
pop es
pop ds
popad
iretd
get_font_data:
mov ax, SelectorFont
mov es, ax
xor edi, edi
mov edi, [esp + 4] ;char
shl edi, 4
add edi, [esp + 8]
xor eax, eax
mov al, byte [es:edi]
ret
io_hlt: ;void io_hlt(void);
HLT
RET
io_cli:
CLI
RET
io_sti:
STI
RET
io_stihlt:
STI
HLT
RET
io_in8:
mov edx, [esp + 4]
mov eax, 0
in al, dx
ret
io_in16:
mov edx, [esp + 4]
mov eax, 0
in ax, dx
ret
io_in32:
mov edx, [esp + 4]
in eax, dx
ret
io_out8:
mov edx, [esp + 4]
mov al, [esp + 8]
out dx, al
ret
io_out16:
mov edx, [esp + 4]
mov eax, [esp + 8]
out dx, ax
ret
io_out32:
mov edx, [esp + 4]
mov eax, [esp + 8]
out dx, eax
ret
io_load_eflags:
pushfd
pop eax
ret
io_store_eflags:
mov eax, [esp + 4]
push eax
popfd
ret
get_memory_block_count:
mov eax, [dwMCRNumber]
ret
get_adr_buffer:
mov eax, MemChkBuf
ret
get_addr_gdt:
mov eax, LABEL_GDT
ret
get_code32_addr:
mov eax, LABEL_SEG_CODE32
ret
load_tr:
LTR [esp + 4]
ret
taskswitch8:
jmp 8*8:0
ret
taskswitch7:
jmp 7*8:0
ret
taskswitch6:
jmp 6*8:0
ret
taskswitch9:
jmp 9*8:0
ret
SegCode32Len equ $ - LABEL_SEG_CODE32
[SECTION .data]
ALIGN 32
[BITS 32]
MemChkBuf: times 256 db 0
dwMCRNumber: dd 0
[SECTION .gs]
ALIGN 32
[BITS 32]
LABEL_STACK:
times 512 db 0
TopOfStack1 equ $ - LABEL_STACK
times 512 db 0
TopOfStack2 equ $ - LABEL_STACK
LenOfStackSection equ $ - LABEL_STACK
LABEL_SYSTEM_FONT:
%include "fontData.inc"
SystemFontLength equ $ - LABEL_SYSTEM_FONT
2.multi_task.c
#include "multi_task.h"
void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{
if (limit > 0xfffff) {
ar |= 0x8000; /* G_bit = 1 */
limit /= 0x1000;
}
sd->limit_low = limit & 0xffff;
sd->base_low = base & 0xffff;
sd->base_mid = (base >> 16) & 0xff;
sd->access_right = ar & 0xff;
sd->limit_high = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);
sd->base_high = (base >> 24) & 0xff;
return;
}
3.write_vga_desktop.c
#define COL8_000000 0
#define COL8_FF0000 1
#define COL8_00FF00 2
#define COL8_FFFF00 3
#define COL8_0000FF 4
#define COL8_FF00FF 5
#define COL8_00FFFF 6
#define COL8_FFFFFF 7
#define COL8_C6C6C6 8
#define COL8_840000 9
#define COL8_008400 10
#define COL8_848400 11
#define COL8_000084 12
#define COL8_840084 13
#define COL8_008484 14
#define COL8_848484 15
#define PORT_KEYDAT 0x0060
#define PIC_OCW2 0x20
#define PIC1_OCW2 0xA0
#include "mem_util.h"
#include "win_sheet.h"
#include "timer.h"
#include "global_define.h"
#include "multi_task.h"
struct MEMMAN* memman = (struct MEMMAN*)0x100000;
char get_font_data(int c, int offset);
void io_hlt(void);
void io_cli(void);
void io_sti(void);
int io_load_eflags(void);
void io_store_eflags(int eflags);
void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);
void boxfill8(unsigned char *vram,int xsize, unsigned char c, int x, int y,
int x0, int y0);
void taskswitch8();
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 BOOTINFO {
char* vgaRam;
short screenX, screenY;
};
void initBootInfo(struct BOOTINFO *pBootInfo);
extern char systemFont[16];
void showFont8(char *vram, int xsize, int x, int y, char c, char* font);
void showString(struct SHTCTL *shtctl, struct SHEET *sht, int x, int y, char color, unsigned char *s );
void putblock(char* vram, int vxsize, int pxsize,
int pysize, int px0, int py0, char* buf, int bxsize);
void init_mouse_cursor(char* mouse, char bc);
void intHandlerFromC(char* esp);
static struct BOOTINFO bootInfo;
static char keyval[5] = {'0', 'X', 0, 0, 0};
static struct FIFO8 keyinfo;
static struct FIFO8 mouseinfo;
static char keybuf[32];
static char mousebuf[128];
struct MOUSE_DEC {
unsigned char buf[3], phase;
int x, y, btn;
};
static struct MOUSE_DEC mdec;
static struct FIFO8 timerinfo;
static char timerbuf[8];
char charToHexVal(char c);
char* charToHexStr(unsigned char c);
char* intToHexStr(unsigned int d);
void init_keyboard(void);
void enable_mouse(struct MOUSE_DEC *mdec);
void show_mouse_info(struct SHTCTL *shtctl, struct SHEET* sht_back, struct SHEET *sht_mouse);
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat);
struct AddrRangeDesc {
unsigned int baseAddrLow;
unsigned int baseAddrHigh;
unsigned int lengthLow;
unsigned int lengthHigh;
unsigned int type;
};
int get_memory_block_count(void);
char* get_adr_buffer(void);
void showMemoryInfo(struct SHTCTL *shtctl, struct SHEET *sht,struct AddrRangeDesc* desc, char* vram, int page, int xsize,int color);
void init_screen8(char *vram, int x, int y);
struct SHEET* message_box(struct SHTCTL *shtctl, char* title);
void make_window8(struct SHTCTL *shtctl, struct SHEET *sht, char *title);
static int mx = 0, my = 0;
static int xsize = 0, ysize = 0;
static unsigned char *buf_back, buf_mouse[256];
#define COLOR_INVISIBLE 99
void make_textbox8(struct SHEET *sht, int x0, int y0, int sx, int sy, int c);
static struct SHEET* shtMsgBox;
static struct SHTCTL *shtctl;
static struct SHEET *sht_back, *sht_mouse;
void task_b_main(void);
void CMain(void) {
initBootInfo(&bootInfo);
char*vram = bootInfo.vgaRam;
xsize = bootInfo.screenX, ysize = bootInfo.screenY;
struct TIMER *timer, *timer2, *timer3;
init_pit();
fifo8_init(&timerinfo, 8, timerbuf);
timer = timer_alloc();
timer_init(timer, &timerinfo, 10);
timer_settime(timer, 500);
timer2 = timer_alloc();
timer_init(timer2, &timerinfo, 2);
timer_settime(timer2, 300);
timer3 = timer_alloc();
timer_init(timer3, &timerinfo, 1);
timer_settime(timer3, 50);
fifo8_init(&keyinfo, 32, keybuf);
fifo8_init(&mouseinfo, 128, mousebuf);
init_palette();
init_keyboard();
int memCnt = get_memory_block_count();
struct AddrRangeDesc* memDesc = (struct AddrRangeDesc*)get_adr_buffer();
memman_init(memman);
memman_free(memman, 0x001008000, 0x3FEE8000);
shtctl = shtctl_init(memman, vram, xsize, ysize);
sht_back = sheet_alloc(shtctl);
sht_mouse = sheet_alloc(shtctl);
buf_back = (unsigned char*)memman_alloc_4k(memman, xsize*ysize);
sheet_setbuf(sht_back, buf_back, xsize, ysize, COLOR_INVISIBLE);
sheet_setbuf(sht_mouse, buf_mouse, 16, 16, COLOR_INVISIBLE);
init_screen8(buf_back, xsize, ysize);
init_mouse_cursor(buf_mouse, COLOR_INVISIBLE);
sheet_slide(shtctl, sht_back, 0, 0);
mx = (xsize - 16) / 2;
my = (ysize - 28 - 16) / 2;
sheet_slide(shtctl, sht_mouse, mx, my);
int cursor_x = 8, cursor_c=COL8_FFFFFF;
shtMsgBox = message_box(shtctl, "counter");
sheet_updown(shtctl, sht_back, 0);
sheet_updown(shtctl, sht_mouse, 100);
io_sti();
enable_mouse(&mdec);
//switch task
int addr_code32 = get_code32_addr();
// char *p = intToHexStr(addr_code32);
//showString(shtctl, sht_back, 0, 32, COL8_FFFFFF, p);
// p = intToHexStr(task_b_main);
// showString(shtctl, sht_back, 0, 64, COL8_FFFFFF, p);
static struct TSS32 tss_a, tss_b;
struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *)get_addr_gdt();
tss_a.ldtr = 0;
tss_a.iomap = 0x40000000;
tss_b.ldtr = 0;
tss_b.iomap = 0x40000000;
set_segmdesc(gdt + 7, 103, (int) &tss_a, AR_TSS32);
set_segmdesc(gdt + 8, 103, (int) &tss_a, AR_TSS32);
set_segmdesc(gdt + 9, 103, (int) &tss_b, AR_TSS32);
set_segmdesc(gdt + 6, 0xffff, task_b_main, 0x409a);
load_tr(7*8);
taskswitch8();
char *p = intToHexStr(tss_a.eflags);
showString(shtctl, sht_back, 0, 0, COL8_FFFFFF, p);
p = intToHexStr(tss_a.esp);
showString(shtctl, sht_back, 0, 16, COL8_FFFFFF, p);
p = intToHexStr(tss_a.es / 8);
showString(shtctl, sht_back, 0, 32, COL8_FFFFFF, p);
p = intToHexStr(tss_a.cs / 8);
showString(shtctl, sht_back, 0, 48, COL8_FFFFFF, p);
p = intToHexStr(tss_a.ss / 8);
showString(shtctl, sht_back, 0, 64, COL8_FFFFFF, p);
p = intToHexStr(tss_a.ds / 8);
showString(shtctl, sht_back, 0, 80, COL8_FFFFFF, p);
p = intToHexStr(tss_a.gs / 8);
showString(shtctl, sht_back, 0, 96, COL8_FFFFFF, p);
p = intToHexStr(tss_a.fs / 8);
showString(shtctl, sht_back, 0, 112, COL8_FFFFFF, p);
p = intToHexStr(tss_a.cr3);
showString(shtctl, sht_back, 0, 128, COL8_FFFFFF, p);
int task_b_esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024;
tss_b.eip = (task_b_main - addr_code32);
tss_b.eflags = 0x00000202;
tss_b.eax = 0;
tss_b.ecx = 0;
tss_b.edx = 0;
tss_b.ebx = 0;
tss_b.esp = 1024;//tss_a.esp;
tss_b.ebp = 0;
tss_b.esi = 0;
tss_b.edi = 0;
tss_b.es = tss_a.es;
tss_b.cs = tss_a.cs;//6 * 8;
tss_b.ss = tss_a.ss;
tss_b.ds = tss_a.ds;
tss_b.fs = tss_a.fs;
tss_b.gs = tss_a.gs;
// taskswitch9();
//switch task
int data = 0;
int count = 0;
int i = 0;
for(;;) {
io_cli();
if (fifo8_status(&keyinfo) + fifo8_status(&mouseinfo) +
fifo8_status(&timerinfo) == 0) {
io_sti();
} else if(fifo8_status(&keyinfo) != 0){
io_sti();
data = fifo8_get(&keyinfo);
if (data == 0x1C) {
showMemoryInfo(shtctl, sht_back, memDesc + count, buf_back, count, xsize, COL8_FFFFFF);
count = (count+1);
if (count > memCnt) {
count = 0;
}
} else if (keytable[data] != 0 && cursor_x < 144) {
boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, COL8_FFFFFF,cursor_x,
28, cursor_x + 7, 43);
sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
char buf[2] = {keytable[data], 0};
showString(shtctl, shtMsgBox, cursor_x, 28, COL8_000000, buf);
cursor_x += 8;
boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, cursor_c, cursor_x,
28, cursor_x + 7, 43);
sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
}
} else if (fifo8_status(&mouseinfo) != 0) {
show_mouse_info(shtctl, sht_back, sht_mouse);
} else if (fifo8_status(&timerinfo) != 0) {
io_sti();
int i = fifo8_get(&timerinfo);
if (i == 10) {
showString(shtctl, sht_back, 0, 176, COL8_FFFFFF, "switch to task b");
//switch task
taskswitch9();
} else if (i == 2) {
// showString(shtctl, sht_back, 0, 32, COL8_FFFFFF, "3[sec]");
} else {
if (i != 0) {
timer_init(timer3, &timerinfo, 0);
cursor_c = COL8_000000;
} else {
timer_init(timer3, &timerinfo, 1);
cursor_c = COL8_FFFFFF;
}
timer_settime(timer3, 50);
boxfill8(shtMsgBox->buf, shtMsgBox->bxsize, cursor_c, cursor_x,
28, cursor_x + 7, 43);
sheet_refresh(shtctl, shtMsgBox, cursor_x, 28, cursor_x+8, 44);
}
}
}
}
void task_b_main(void) {
showString(shtctl, sht_back, 0, 144, COL8_FFFFFF, "enter task b");
struct FIFO8 timerinfo_b;
char timerbuf_b[8];
struct TIMER *timer_b = 0;
int i = 0;
fifo8_init(&timerinfo_b, 8, timerbuf_b);
timer_b = timer_alloc();
timer_init(timer_b, &timerinfo_b, 123);
timer_settime(timer_b, 500);
for(;;) {
io_cli();
if (fifo8_status(&timerinfo_b) == 0) {
io_sti();
} else {
i = fifo8_get(&timerinfo_b);
io_sti();
if (i == 123) {
showString(shtctl, sht_back, 0, 160, COL8_FFFFFF, "switch back");
taskswitch7();
}
}
}
}
void init_screen8(char* vram, int xsize, int ysize) {
boxfill8(vram, xsize, COL8_008484, 0, 0, xsize-1, ysize-29);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-28, xsize-1, ysize-28);
boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize-27, xsize-1, ysize-27);
boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-26, xsize-1, ysize-1);
boxfill8(vram, xsize, COL8_FFFFFF, 3, ysize-24, 59, ysize-24);
boxfill8(vram, xsize, COL8_FFFFFF, 2, ysize-24, 2, ysize-4);
boxfill8(vram, xsize, COL8_848484, 3, ysize-4, 59, ysize-4);
boxfill8(vram, xsize, COL8_848484, 59, ysize-23, 59, ysize-5);
boxfill8(vram, xsize, COL8_000000, 2, ysize-3, 59, ysize-3);
boxfill8(vram, xsize, COL8_000000, 60, ysize-24, 60, ysize-3);
boxfill8(vram, xsize, COL8_848484, xsize-47, ysize-24, xsize-4, ysize-24);
boxfill8(vram, xsize, COL8_848484, xsize-47, ysize-23, xsize-47, ysize-4);
boxfill8(vram, xsize, COL8_FFFFFF, xsize-47, ysize-3, xsize-4, ysize-3);
boxfill8(vram, xsize, COL8_FFFFFF, xsize-3, ysize-24, xsize-3, ysize-3);
}
void computeMousePosition(struct SHTCTL *shtctl, struct SHEET *sht,struct MOUSE_DEC* mdec) {
mx += mdec->x;
my += mdec->y;
if (mx < 0) {
mx = 0;
}
if (my < 0) {
my = 0;
}
if (mx > xsize - 1) {
mx = xsize - 1;
}
if (my > ysize - 1) {
my = ysize - 1;
}
}
void show_mouse_info(struct SHTCTL *shtctl, struct SHEET *sht_back,struct SHEET *sht_mouse) {
char*vram = buf_back;
unsigned char data = 0;
io_sti();
data = fifo8_get(&mouseinfo);
if (mouse_decode(&mdec, data) != 0) {
computeMousePosition(shtctl, sht_back, &mdec);
sheet_slide(shtctl, sht_mouse, mx, my);
if ((mdec.btn & 0x01) != 0) {
sheet_slide(shtctl, shtMsgBox, mx - 80, my - 8);
}
}
}
void initBootInfo(struct BOOTINFO *pBootInfo) {
pBootInfo->vgaRam = (char*)0xe0000000;
pBootInfo->screenX = 640;
pBootInfo->screenY = 480;
}
void showString(struct SHTCTL *shtctl ,struct SHEET *sht, int x, int y, char color, unsigned char *s ) {
int begin = x;
for (; *s != 0x00; s++) {
showFont8(sht->buf, sht->bxsize, x, y,color, systemFont+ *s * 16);
x += 8;
}
sheet_refresh(shtctl, sht, begin, y, x , y + 16);
}
void init_palette(void) {
static unsigned char table_rgb[16 *3] = {
0x00, 0x00, 0x00,
0xff, 0x00, 0x00,
0x00, 0xff, 0x00,
0xff, 0xff, 0x00,
0x00, 0x00, 0xff,
0xff, 0x00, 0xff,
0x00, 0xff, 0xff,
0xff, 0xff, 0xff,
0xc6, 0xc6, 0xc6,
0x84, 0x00, 0x00,
0x00, 0x84, 0x00,
0x84, 0x84, 0x00,
0x00, 0x00, 0x84,
0x84, 0x00, 0x84,
0x00, 0x84, 0x84,
0x84, 0x84, 0x84,
};
set_palette(0, 15, table_rgb);
return;
}
void set_palette(int start, int end, unsigned char* rgb) {
int i, eflags;
eflags = io_load_eflags();
io_cli();
io_out8(0x03c8, start); //set palette number
for (i = start; i <=end; i++ ) {
io_out8(0x03c9, rgb[0] / 4);
io_out8(0x03c9, rgb[1] / 4);
io_out8(0x03c9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags);
return;
}
void boxfill8(unsigned char* vram, int xsize, unsigned char c,
int x0, int y0, int x1, int y1) {
int x, y;
for (y = y0; y <= y1; y++)
for (x = x0; x <= x1; x++) {
vram[y * xsize + x] = c;
}
}
void showFont8(char *vram, int xsize, int x, int y, char c, char* font) {
int i;
char d;
for (i = 0; i < 16; i++) {
d = font[i];
if ((d & 0x80) != 0) {vram[(y+i)*xsize + x + 0] = c;}
if ((d & 0x40) != 0) {vram[(y+i)*xsize + x + 1] = c;}
if ((d & 0x20) != 0) {vram[(y+i)*xsize + x + 2] = c;}
if ((d & 0x10) != 0) {vram[(y+i)*xsize + x + 3] = c;}
if ((d & 0x08) != 0) {vram[(y+i)*xsize + x + 4] = c;}
if ((d & 0x04) != 0) {vram[(y+i)*xsize + x + 5] = c;}
if ((d & 0x02) != 0) {vram[(y+i)*xsize + x + 6] = c;}
if ((d & 0x01) != 0) {vram[(y+i)*xsize + x + 7] = c;}
}
}
void init_mouse_cursor(char* mouse, char bc) {
static char cursor[16][16] = {
"**************..",
"*OOOOOOOOOOO*...",
"*OOOOOOOOOO*....",
"*OOOOOOOOO*.....",
"*OOOOOOOO*......",
"*OOOOOOO*.......",
"*OOOOOOO*.......",
"*OOOOOOOO*......",
"*OOOO**OOO*.....",
"*OOO*..*OOO*....",
"*OO*....*OOO*...",
"*O*......*OOO*..",
"**........*OOO*.",
"*..........*OOO*",
"............*OO*",
".............***"
};
int x, y;
for (y = 0; y < 16; y++) {
for (x = 0; x < 16; x++) {
if (cursor[y][x] == '*') {
mouse[y*16 + x] = COL8_000000;
}
if (cursor[y][x] == 'O') {
mouse[y*16 + x] = COL8_FFFFFF;
}
if (cursor[y][x] == '.') {
mouse[y*16 + x] = bc;
}
}
}
}
void putblock(char* vram, int vxsize, int pxsize,
int pysize, int px0, int py0, char* buf, int bxsize) {
int x, y;
for (y = 0; y < pysize; y++)
for (x = 0; x < pxsize; x++) {
vram[(py0+y) * vxsize + (px0+x)] = buf[y * bxsize + x];
}
}
void intHandlerFromC(char* esp) {
char*vram = bootInfo.vgaRam;
int xsize = bootInfo.screenX, ysize = bootInfo.screenY;
io_out8(PIC_OCW2, 0x20);
unsigned char data = 0;
data = io_in8(PORT_KEYDAT);
fifo8_put(&keyinfo, data);
return;
}
char charToHexVal(char c) {
if (c >= 10) {
return 'A' + c - 10;
}
return '0' + c;
}
char* charToHexStr(unsigned char c) {
int i = 0;
char mod = c % 16;
keyval[3] = charToHexVal(mod);
c = c / 16;
keyval[2] = charToHexVal(c);
return keyval;
}
char* intToHexStr(unsigned int d) {
static char str[11];
str[0] = '0';
str[1] = 'X';
str[10] = 0;
int i = 2;
for(; i < 10; i++) {
str[i] = '0';
}
int p = 9;
while (p > 1 && d > 0) {
int e = d % 16;
d /= 16;
if (e >= 10) {
str[p] = 'A' + e - 10;
} else {
str[p] = '0' + e;
}
p--;
}
return str;
}
#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() {
for(;;) {
if ((io_in8(PORT_KEYSTA) & KEYSTA_SEND_NOTREADY) == 0) {
break;
}
}
}
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);
mdec->phase = 0;
return;
}
void intHandlerForMouse(char* esp) {
unsigned char data;
io_out8(PIC1_OCW2, 0x20);
io_out8(PIC_OCW2, 0x20);
data = io_in8(PORT_KEYDAT);
fifo8_put(&mouseinfo, data);
}
int mouse_decode(struct MOUSE_DEC *mdec, unsigned char dat) {
if (mdec->phase == 0) {
if (dat == 0xfa) {
mdec->phase = 1;
}
return 0;
}
if (mdec->phase == 1) {
if ((dat & 0xc8) == 0x08) {
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;
}
mdec->y = -mdec->y;
return 1;
}
return -1;
}
void showMemoryInfo(struct SHTCTL *shtctl, struct SHEET *sht,struct AddrRangeDesc* desc, char* vram, int page,int xsize, int color) {
int x = 0, y = 0, gap = 13*8, strLen = 10* 8;
init_screen8(sht->buf, xsize, ysize);
showString(shtctl, sht, x, y, color, "page is: ");
char* pPageCnt = intToHexStr(page);
showString(shtctl, sht, gap, y, color, pPageCnt);
y += 16;
showString(shtctl, sht, x, y, color, "BaseAddrL: ");
char* pBaseAddrL = intToHexStr(desc->baseAddrLow);
showString(shtctl, sht, gap, y, color, pBaseAddrL);
y += 16;
showString(shtctl, sht, x, y, color, "BaseAddrH: ");
char* pBaseAddrH = intToHexStr(desc->baseAddrHigh);
showString(shtctl, sht, gap, y, color, pBaseAddrH);
y += 16;
showString(shtctl, sht, x, y, color, "lengthLow: ");
char* pLengthLow = intToHexStr(desc->lengthLow);
showString(shtctl, sht, gap, y, color, pLengthLow);
y+= 16;
showString(shtctl, sht, x, y, color, "lengthHigh: ");
char* pLengthHigh = intToHexStr(desc->lengthHigh);
showString(shtctl, sht, gap, y, color, pLengthHigh);
y+= 16;
showString(shtctl, sht, x, y, color, "type: ");
char* pType = intToHexStr(desc->type);
showString(shtctl, sht, gap, y, color, pType);
}
struct SHEET* message_box(struct SHTCTL *shtctl, char *title) {
struct SHEET *sht_win;
unsigned char *buf_win;
sht_win = sheet_alloc(shtctl);
buf_win = (unsigned char *)memman_alloc_4k(memman, 160 * 68);
sheet_setbuf(sht_win, buf_win, 160, 68, -1);
make_window8(shtctl, sht_win, title);
make_textbox8(sht_win, 8, 28, 144, 16, COL8_FFFFFF);
sheet_slide(shtctl, sht_win, 160, 72);
sheet_updown(shtctl, sht_win, 2);
return sht_win;
}
void make_window8(struct SHTCTL *shtctl, struct SHEET *sht, 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;
int bxsize = sht->bxsize;
int bysize = sht->bysize;
boxfill8(sht->buf, bxsize, COL8_C6C6C6, 0, 0, bxsize - 1, 0);
boxfill8(sht->buf, bxsize, COL8_FFFFFF, 1, 1, bxsize - 2, 1);
boxfill8(sht->buf, bxsize, COL8_C6C6C6, 0, 0, 0, bysize - 1);
boxfill8(sht->buf, bxsize, COL8_FFFFFF, 1, 1, 1, bysize - 1);
boxfill8(sht->buf, bxsize, COL8_848484, bxsize - 2, 1, bxsize - 2, bysize - 2);
boxfill8(sht->buf, bxsize, COL8_000000, bxsize - 1, 0, bxsize - 1, bysize - 1);
boxfill8(sht->buf, bxsize, COL8_C6C6C6, 2, 2, bxsize - 3, bysize - 3);
boxfill8(sht->buf, bxsize, COL8_000084, 3, 3, bxsize - 4, 20);
boxfill8(sht->buf, bxsize, COL8_848484, 1, bysize - 2, bxsize - 2, bysize - 2);
boxfill8(sht->buf, bxsize, COL8_000000, 0, bysize - 1, bxsize - 1, bysize - 1);
showString(shtctl, sht, 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;
}
sht->buf[(5+y) * sht->bxsize + (sht->bxsize - 21 + x)] = c;
}
}
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);
}
分析