void init_gdtidt(void) { struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT; int i; /* initialize GDT */ for (i = 0; i < 8192; i++) { set_segmdesc(gdt + i, 0, 0, 0); } set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092); // it represents all the memory that CPU can manage. limit = 4G // 0x4092 0100 0000 10010010 -> 32-bit mode, system special, read and write, not execute set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a); // 512K, from 0x00280000, prepared for bootpack.hrb // 0x409a -> 32-bit mode, system special(ring0), execute and read, not write load_gdtr(0xffff, ADR_GDT); // with the help of assembly /* initialize IDT */ for (i = 0; i < 256; i++) { set_gatedesc(idt + i, 0, 0, 0); } load_idtr(0x7ff, ADR_IDT); // with the help of assembly /* setting IDT */ set_gatedesc(idt + 0x21, (int) asm_inthandler21, 2 * 8, AR_INTGATE32); set_gatedesc(idt + 0x2c, (int) asm_inthandler2c, 2 * 8, AR_INTGATE32); set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32); return; }
void init_gdtidt(void){ struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *)0x00270000; struct GATE_DESCRIPTOR *idt= (struct GATE_DESCRIPTOR*)0x0026f800; int i; //gdt initialize for(i=0; i<8192; i++){ set_segmdesc(gdt+i, 0, 0, 0); } set_segmdesc(gdt+1, 0xffffffff, 0x00000000, 0x4092); set_segmdesc(gdt+2, 0x000fffff, 0x00000000, 0x409a); set_segmdesc(gdt+3, 0x000fffff, 0x00280000, 0x409a); load_gdtr(0xfff, 0x00270000);//??or 0xfff? //idt initialize for(i=0; i<256; i++){ set_gatedesc(idt+i, 0, 0, 0); } for(i=0; i<256; i++){ set_gatedesc(idt+i, (int)asm_inthandler21, 3*8, 0x008e); } set_gatedesc(idt+0x21, (int)asm_inthandler21-0x280000, 3*8, 0x008e); set_gatedesc(idt+0x2c, (int)asm_inthandler2c, 2*8, AR_INTGATE32); load_idtr(0x7ff, 0x0026f800); return; }
//初始化GDT、IDT void init_gdtidt(void) { struct SEGMENT_DESCRIPTOR *gdt=(struct SEGMENT_DESCRIPTOR *)0x00270000; struct GATE_DESCRIPTOR *idt=(struct GATE_DESCRIPTOR *)0x0026f800; int i; /*GDT的初始化*/ for(i=0;i<8192;i++){ set_segmdesc(gdt+i,0,0,0); } set_segmdesc(gdt+1,0xffffffff,0x00000000,AR_DATA32_RW); set_segmdesc(gdt + 2, LIMIT_BOTPAK, ADR_BOTPAK, AR_CODE32_ER); load_gdtr(LIMIT_GDT, ADR_GDT); /*IDT的初始化*/ for(i=0;i<256;i++){ set_gatedesc(idt+i,0,0,0); } load_idtr(LIMIT_IDT, ADR_IDT); /*IDT的设定*/ set_gatedesc(idt+0x21,(int)asm_inthandler21,2*8,AR_INTGATE32); set_gatedesc(idt + 0x27, (int) asm_inthandler27, 2 * 8, AR_INTGATE32); set_gatedesc(idt+0x2c,(int)asm_inthandler2c,2*8,AR_INTGATE32); return ; }
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char name[13], *p, *q; struct TASK *task = task_now(); int i, segsiz, datsiz, esp, dathrb; /* コマンドラインからファイル名を生成 */ for (i = 0; i < 8; i++) { if (cmdline[i] <= ' ') { break; } name[i] = cmdline[i]; } name[i] = 0; /* とりあえずファイル名の後ろを0にする */ /* ファイルを探す */ finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo == 0) { /* 見つからなかったので後ろに".HRB"をつけてもう一度探してみる */ name[i ] = '.'; name[i + 1] = 'H'; name[i + 2] = 'R'; name[i + 3] = 'B'; name[i + 4] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { /* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo->size); file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); if (finfo->size >= 36 && strncmp(p + 4, "Hari", 4) == 0 && *p == 0x00) { segsiz = *((int *) (p + 0x0000)); esp = *((int *) (p + 0x000c)); datsiz = *((int *) (p + 0x0010)); dathrb = *((int *) (p + 0x0014)); q = (char *) memman_alloc_4k(memman, segsiz); *((int *) 0xfe8) = (int) q; set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60); set_segmdesc(gdt + 1004, segsiz - 1, (int) q, AR_DATA32_RW + 0x60); for (i = 0; i < datsiz; i++) { q[esp + i] = p[dathrb + i]; } start_app(0x1b, 1003 * 8, esp, 1004 * 8, &(task->tss.esp0)); memman_free_4k(memman, (int) q, segsiz); } else { cons_putstr0(cons, ".hrb file format error.\n"); } memman_free_4k(memman, (int) p, finfo->size); cons_newline(cons); return 1; } /* ファイルが見つからなかった場合 */ return 0; }
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char name[18], *p, *q; struct TASK *task = task_now(); int i; /* コマンドラインからファイル名を生成 */ for (i = 0; i < 13; i++) { if (cmdline[i] <= ' ') { break; } name[i] = cmdline[i]; } name[i] = 0; /* とりあえずファイル名の後ろを0にする */ /* ファイルを探す */ finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo == 0 && name[i - 1] != '.') { /* 見つからなかったので後ろに".HRB"をつけてもう一度探してみる */ name[i ] = '.'; name[i + 1] = 'H'; name[i + 2] = 'R'; name[i + 3] = 'B'; name[i + 4] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { /* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo->size); q = (char *) memman_alloc_4k(memman, 64 * 1024); *((int *) 0xfe8) = (int) p; file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60); set_segmdesc(gdt + 1004, 64 * 1024 - 1, (int) q, AR_DATA32_RW + 0x60); if (finfo->size >= 8 && strncmp(p + 4, "Hari", 4) == 0) { start_app(0x1b, 1003 * 8, 64 * 1024, 1004 * 8, &(task->tss.esp0)); } else { start_app(0, 1003 * 8, 64 * 1024, 1004 * 8, &(task->tss.esp0)); } memman_free_4k(memman, (int) p, finfo->size); memman_free_4k(memman, (int) q, 64 * 1024); cons_newline(cons); return 1; } /* ファイルが見つからなかった場合 */ return 0; }
int cmd_app (struct CONSOLE *cons, int *fat, char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *)MEMMAN_ADDR; struct FILEINFO *finfo; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *)ADR_GDT; char name [18]; int i; struct TASK *task = task_now (); for (i = 0; i < 13; i++) { if (cmdline[i] <= ' ') { break; } name[i] = cmdline[i]; } name[i] = 0; finfo = file_search (name, (struct FILEINFO *)(ADR_DISKIMG + 0x002600), 224); if (finfo == 0 && name[i-1] != '.') { name [i+0] = '.'; name [i+1] = 'H'; name [i+2] = 'R'; name [i+3] = 'B'; name [i+4] = 0; finfo = file_search (name, (struct FILEINFO *)(ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { char *p = (char *)memman_alloc_4k (memman, finfo->size); char *q = (char *)memman_alloc_4k (memman, 64 * 1024); *((int *) 0xfe8) = (int) p; file_loadfile (finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc (gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER + 0x60); set_segmdesc (gdt + 1004, 64 * 1024 - 1, (int) q, AR_DATA32_RW + 0x60); if (finfo->size >= 8 && strncmp (p + 4, "Hari", 4) == 0) { p[0] = 0xe8; p[1] = 0x16; p[2] = 0x00; p[3] = 0x00; p[4] = 0x00; p[5] = 0xcb; } start_app (0, 1003 * 8, 64 * 1024, 1004 * 8, &(task->tss.esp0)); memman_free_4k (memman, (int) p, finfo->size); memman_free_4k (memman, (int) q, 64 * 1024); cons_newline (cons); return 1; } return 0; }
void _benmain(void) { struct FIFO32 fifo; int keybuf[128]={0}; fifo32_init(&fifo, 128, keybuf); struct TSS32 tss_a = {0}; cons_init(); env_init(); /* keyboard setting */ init_kb(&fifo, 256); tss_a.ldtr = 0; tss_a.iomap = 0x40000000; set_segmdesc(gdt + 0, 103, (int) &tss_a, AR_TSS32); task_init(memman); /* Unfortunate try the switch back to 0*8 (_benmain) with farjmp but not working. * And the reason still unknown. * So that I use another thread_kb_io() to catch the keyboard interrupt. */ load_tr(0 * 8); // record current working task to tss_a task_create((int) &thread_kb_io, memman, "bshell", 1); task_create((int) &thread_events, memman, "events", 0); /* strange issue encountered if run pci_init at the setup_hw() */ puts("pci scan bus\n"); pci_init(); farjmp(0, 4*8); puts("\nSystem Halted \n"); _syshalt(); }
//一个小应用程序 void cmd_hlt(CONSOLE *console, int *fat) { MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR; FILEINFO *finfo = file_search("HLT.HRB", (FILEINFO *)(ADR_DISKIMG + 0x002600), 224); SEGMENT_DESCRIPTOR *gdt = (SEGMENT_DESCRIPTOR *)ADR_GDT; char *img_adr; /*找到这个应用程序的情况*/ if(0 != finfo) { //文件内容开始的地址赋值给img_adr img_adr = (char *)memmanage_alloc_4K(memmanage, finfo->size); //把可能有间断的文件内容复制到一块儿连续的内存中去,这样就可以直接到这块儿内存进行连续的读取了 file_loadfile(finfo->clusterno, finfo->size, img_adr, fat, (char *)(0x003e00 + ADR_DISKIMG)); //为这个任务分配一个内存段 set_segmdesc(gdt + 1003, finfo->size - 1, (int)img_adr, AR_CODE32_ER); //跳转到这个hlt任务所在的内存开始执行 farcall(0, 1003 * 8); memmanage_free_4K(memmanage, (int)img_adr, finfo->size); } /*无法找到这个应用程序的情况*/ else { displayStrings_atLayer(console->layer, 8, console->cursor_y, COL8_FFFFFF, COL8_000000, "File not found!"); console_newline(console); } console_newline(console); }
struct _task *task_init(struct _memman *memman) { int i; struct _task *task; struct _segmdes *gdt = (struct _segmdes *) ADR_GDT; taskctl = (struct _taskctl *) memman_alloc_4k(memman, sizeof (struct _taskctl)); taskctl->now_lv = 0; taskctl->lv_change = 0; for (i = 0; i < MAX_TASKS; i++) { /* Register all task slots on segment descriptor table */ taskctl->tasks0[i].flags = TASK_UNUSED; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; /* Setup selector (GDT segment) number */ set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } /* Allocate new task for task_init caller */ task = task_alloc(); task->flags = TASK_RUNNING; /* Priority and level */ task->priority = 2; /* Timeslice = 10ms * pri */ task->level = 0; /* Highest Level */ /* Add task to level control */ task_add(task); /* Recalebrate Running Level */ task_switchsub(); /* Activate Current Task */ load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof(struct TASKCTL)); for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; task->priority = 2; task->level = 0; task_add(task); task_switchsub(); load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
void _benmain(void) { int i; int c = 0; int keybuf[128]={0}; struct FIFO32 fifo; struct TIMER *timer; fifo32_init(&fifo, 128, keybuf); struct TSS32 tss_a, tss_c; env_init(); /* keyboard setting */ init_kb(&fifo, 256); i=0; timer = timer_alloc(); timer_init(timer, &fifo, 1); timer_settime(timer, 50); tss_a.ldtr = 0; tss_a.iomap = 0x40000000; tss_c.ldtr = 0; tss_c.iomap = 0x40000000; set_segmdesc(gdt + 3, 103, (int) &tss_a, AR_TSS32); task_init(memman); /* Unfortunate try the switch back to 3*8 (_benmain) with farjmp but not working. * And the reason still unknown. * So that I use another thread_kb_io() to catch the keyboard interrupt. */ load_tr(3 * 8); // record current working task to tss_a task_create((int) &thread_kb_io, memman, "bshell"); /* strange issue encountered if run pci_init at the setup_hw() */ puts("pci scan bus\n"); pci_init(); for (;;) { asm_cli(); if (fifo32_status(&fifo) == 0) { asm_stihlt(); // wake while keyboard input // got a interrupt } else { /* scan_code input */ c=fifo32_get(&fifo); asm_sti(); if (c == 1) { farjmp(0, 4*8); } else { puts("disabled boot options.\n"); } } } puts("\nSystem Halted \n"); _syshalt(); }
//初始化GDT、IDT void init_gdtidt(void) { struct SEGMENT_DESCRIPTOR *gdt=(struct SEGMENT_DESCRIPTOR *)0x00270000; struct GATE_DESCRIPTOR *idt=(struct GATE_DESCRIPTOR *)0x0026f800; int i; /*GDT的初始化*/ for(i=0;i<8192;i++){ set_segmdesc(gdt+i,0,0,0); } set_segmdesc(gdt+1,0xffffffff,0x00000000,0x4092); set_segmdesc(gdt+2,0x0007ffff,0x00280000,0x409a); load_gdtr(0xffff,0x00270000); /*IDT的初始化*/ for(i=0;i<256;i++){ set_gatedesc(idt+i,0,0,0); } load_idtr(0x7ff,0x0026800); return ; }
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char name[18], *p; int i; /* 根据命令行生成文件名 */ for (i = 0; i < 13; i++) { if (cmdline[i] <= ' ') { break; } name[i] = cmdline[i]; } name[i] = 0; /* 暂且将文件名的后面置位0 */ /* 寻找文件 */ finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo == 0 && name[i - 1] != '.') { /* 由于找不到文件,故在文件名后面加上“.hrb”后重新寻找 */ name[i ] = '.'; name[i + 1] = 'F'; name[i + 2] = 'E'; name[i + 3] = 'X'; name[i + 4] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { /* 找到文件的情况 */ p = (char *) memman_alloc_4k(memman, finfo->size); *((int *) 0xfe8) = (int) p; file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER); // *.fex成功读入内存之后,将其注册为GDT的1003号。1-2号有dsctbl.c使用,3-1002号由mtask.c使用。 if (finfo->size >= 8 && strncmp(p + 4, "Hari", 4) == 0) { p[0] = 0xe8; p[1] = 0x16; p[2] = 0x00; p[3] = 0x00; p[4] = 0x00; p[5] = 0xcb; } farcall(0, 1003 * 8); memman_free_4k(memman, (int) p, finfo->size); cons_newline(cons); return 1; } /* 没有找到文件的情况 */ return 0; }
task_t* task_init(memman_t* memman) { int i; task_t *task, *idle; segment_descriptor* gdt = (segment_descriptor*)ADR_GDT; taskctl = (taskctl_t*)memman_alloc_4k(memman, sizeof(taskctl_t)); for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int)taskctl->tasks0[i].ldt, AR_LDT); } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02s */ task->level = 0; /* 最高等级 */ task_add(task); task_switchsub(); /* 设置等级 */ load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; idle->tss.eip = (int)&task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
TASK* task_init(MEMMAN* memman) { SEGMENT_DESCRIPTOR* gdt = (SEGMENT_DESCRIPTOR*)ADR_GDT; taskctl = (TASKCTL*)memman_alloc_4k(memman, sizeof(TASKCTL)); for (int i = 0; i < MAX_TASKS; ++i) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].tss.ldtr = (TASK_GDT0 + MAX_TASKS + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int)taskctl->tasks0[i].ldt, AR_LDT); } for (int i = 0; i < MAX_TASKLEVELS; ++i) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } TASK* task = task_alloc(); // Main task. task->flags = RUNNING; task->priority = 2; // 0.02 sec task->level = 0; // Max level. task_add(task); task_switchsub(); load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); TASK* idle = task_alloc(); idle->tss.esp = (int)memman_alloc_4k(memman, 256) + 256; idle->tss.eip = (int)&task_idle; idle->tss.es = idle->tss.ss = idle->tss.ds = idle->tss.fs = idle->tss.gs = 1 * 8; idle->tss.cs = 2 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); taskctl->task_fpu = NULL; return task; }
//任务管理主体的初始化(并为调用这个函数的那个程序分配一个任务状态段) TASK *task_init(MEMMANAGE *memman) { int i; TASK *task, *idle; SEGMENT_DESCRIPTOR *gdt = (SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (TASKCTL *) memmanage_alloc_4K(memman, sizeof (TASKCTL)); //对taskctl进行初始化 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks[i].flags = UNUSED; taskctl->tasks[i].selector = (TASK_GDT0 + i) * 8; //为这个任务分配任务状态段所在的GDT描述符 set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->task_level[i].running_number = 0; taskctl->task_level[i].task_now = 0; } /*为调用这个初始化函数的程序分配一个属于它的任务*/ /*为调用这个初始化函数的程序分配一个属于它的任务*/ task = task_alloc(); task->flags = RUNNING; //这个任务当前正在运行中 task->priority = 2; //任务的优先级默认的都是2,即可以占用CPU0.02秒 task->level = 0; //调用这个函数的任务默认设定为最高级0级 task_add(task); //自动根据task的level添加到相应等级任务队列中 level_switch(); //由于有新任务添加进来,所以需要改变当前的lv_now load_tr(task->selector); //改写TR寄存器,让它存储当前这个任务的段偏移值 task_timer = timer_alloc(); //分配一个用于任务切换的计时器 timer_set(task_timer, task->priority); //0.02秒切换一次任务 /*给整个操作系统一个最低级的任务,这样当没有任务且键盘鼠标等任务休眠的时候就可以转到这个任务里 **,这个任务永远存在 */ idle = task_alloc(); idle->tss.esp = memmanage_alloc_4K(memman, 64 * 1024) + 64 * 1024; idle->tss.eip = (int) &task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
/* init taskctl and allocate the first task to the thread that calls the init method we don't need to assign it a fifo because all it doesn't is to switch by calling farjmp() and doesn't need to put data to any buffer */ struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *)memman_alloc_4k(memman, sizeof(struct TASKCTL)); for(i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; taskctl->tasks0[i].flags = 0; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int)&taskctl->tasks0[i].tss, AR_TSS32); } /* initialize all levels */ for(i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } /* after initializaing all tasks in taskctl, we need to alloc the first task and assign it to the thread that calls init */ task = task_alloc(); task->flags = 2; /* running */ task->priority = 2; task->level = 0; /* the first task(for mouse/keyboard/timer interruption) should be in highest level */ task_add(task); task_switchsub(); /* update taskctl->now_lv */ /* set task register to current task */ load_tr(task->sel); idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8; idle->tss.eip = (int)&task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; /* the idle task will always be running at lowest level in case there's no when there's no active task to run and OS doesn't know where to jump */ task_run(idle, MAX_TASKLEVELS - 1, 1); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; }
/** * @description 初始化 * @param menman:内存地址 */ struct TASK *task_init(struct MEMMAN *memman){ int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); //TODO 初始化所有任务 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } //TODO 初始化所有优先级层 for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; // task->priority = 2; //0.02秒 task->level = 0; //最高级别 task_add(task); task_switchsub(); //切换 load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); //TODO 初始化空闲进程 idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; //X86的栈是向下增长的,所以需要+64*1024 idle->tss.eip = (int) &task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
/* 整个多任务系统的初始化初始化 */ struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); /* 初始化所有的任务的task结构 */ for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; /* 选择子初始化 */ /* 描述符初始化 */ set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } /* 初始化所有level结构 */ for (i = 0; i < MAX_TASKLEVELS; i++) { taskctl->level[i].running = 0; /* 没有正在运行的任务 */ taskctl->level[i].now = 0; } task = task_alloc(); task->flags = 2; /* 活动中标志 */ task->priority = 2; /* 0.02秒 */ task->level = 0; /* 最高LEVEL */ task_add(task); task_switchsub(); /* LEVEL设置 */ load_tr(task->sel); /* 修改tr寄存器 */ task_timer = timer_alloc(); /* 重头戏!!任务切换的定时器 */ timer_settime(task_timer, task->priority); /* 闲置任务的初始化 */ idle = task_alloc(); idle->tss.esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; idle->tss.eip = (int) &task_idle; idle->tss.es = 1 * 8; idle->tss.cs = 2 * 8; idle->tss.ss = 1 * 8; idle->tss.ds = 1 * 8; idle->tss.fs = 1 * 8; idle->tss.gs = 1 * 8; task_run(idle, MAX_TASKLEVELS - 1, 1); return task; }
int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char name[18], *p; int i; for (i = 0; i < 13; i++) { if (cmdline[i] <= ' ') { break; } name[i] = cmdline[i]; } name[i] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo == 0 && name[i-1] != '.') { /* * If the file cannot be found * Search <filename>.hrb instead */ name[i] = '.'; name[i + 1] = 'H'; name[i + 2] = 'R'; name[i + 3] = 'B'; name[i + 4] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { /* File is found */ p = (char *) memman_alloc_4k(memman, finfo->size); file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); /* Assign 1003 Segment */ set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER); farcall(0, 1003 * 8); memman_free_4k(memman, (int) p, finfo->size); cons_newline(cons); return 1; } return 0; }
void cmd_hlt(struct CONSOLE *cons, int *fat) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo = file_search("HLT.HRB", (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char *p; if (finfo != 0) { /* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo->size); file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER); farjmp(0, 1003 * 8); memman_free_4k(memman, (int) p, finfo->size); } else { /* ファイルが見つからなかった場合 */ putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cons_newline(cons); } cons_newline(cons); return; }
struct TASK *task_init(struct MEMMAN *memman) { int i; struct TASK *task; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].flags = 0; taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); } task = task_alloc(); task->flags = 2; /* 動作中マーク */ taskctl->running = 1; taskctl->now = 0; taskctl->tasks[0] = task; load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, 2); return task; }
int cmd_app(struct CONSOLE *cons, int *fat,char *cmdline) { struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo = file_search("HLT.HRB", (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; char *p,name[18]; int i; for(i=0;i <13; i++) { if(cmdline[i] <= ' ') break; name[i] = cmdline[i]; } name[i] = 0; finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); if (finfo == 0 && name[i - 1] != '.') { name[i] = '.'; name[i+1] = 'H'; name[i+2] = 'R'; name[i+3] = 'B'; name[i+4] = 0; // search the file again finfo = file_search(name, (struct FILEINFO *) (ADR_DISKIMG + 0x002600), 224); } if (finfo != 0) { // found file p = (char *) memman_alloc_4k(memman, finfo->size); *((int *) 0xfe8) = (int) p; file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER); farcall(0, 1003 * 8); // call memman_free_4k(memman, (int) p, finfo->size); cons_newline(cons); return 1; } return 0; }
//任务管理主体的初始化(并为调用这个函数的那个程序分配一个任务状态段) TASK *taskctl_init(MEMMANAGE *memman) { int i; TASK *task; SEGMENT_DESCRIPTOR *gdt = (SEGMENT_DESCRIPTOR *)ADR_GDT; taskctl = (TASKCTL *) memmanage_alloc_4K(memman, sizeof(TASKCTL)); //对taskctl进行初始化 for(i = 0;i < MAX_TASKS; i++) { taskctl->tasks[i].flags = UNUSED; taskctl->tasks[i].selector = (TASK_GDT + i) * 8; //为这个任务分配任务状态段所在的GDT描述符 set_segmdesc(gdt + TASK_GDT + i, 103, (int) &taskctl->tasks[i].tss, AR_TSS32); } task = task_alloc(); //为调用这个初始化函数的程序分配一个属于它的任务 task->flags = RUNNING; //这个任务当前正在运行中 taskctl->running_number = 1; //当前正在运行着的任务只有一个 taskctl->task_now = 0; //当前占用着CPU的任务是0号task taskctl->running_tasks[0] = task; //让第一个数组指针指向这个正在运行的task load_tr(task->selector); //改写TR寄存器,让它存储当前这个任务的段偏移值 task_timer = timer_alloc(); //分配一个用于任务切换的计时器 timer_set(task_timer, 2); //0.02秒切换一次任务 return task; }
/* 控制台任务 */ void console_task(struct SHEET *sheet, unsigned int memtotal) { struct TIMER *timer; struct TASK *task = task_now(); int i, fifobuf[128], cursor_x = 16, cursor_y = 28, cursor_c = -1; char s[30], cmdline[30], *p; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; int x, y; struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); int *fat = (int *) memman_alloc_4k(memman, 4 * 2880); struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; fifo32_init(&task->fifo, 128, fifobuf, task); timer = timer_alloc(); timer_init(timer, &task->fifo, 1); timer_settime(timer, 50); file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); /* 输出一个">" */ putfonts8_asc_sht(sheet, 8, 28, COL8_FFFFFF, COL8_000000, ">", 1); for (;;) { io_cli(); if (fifo32_status(&task->fifo) == 0) { /* 控制台任务自己的缓冲区中没有数据 */ task_sleep(task); /* 睡眠自己 */ io_sti(); } else { i = fifo32_get(&task->fifo); /* 读出数据 */ io_sti(); if (i <= 1) { /* 光标用定时器 */ if (i != 0) { timer_init(timer, &task->fifo, 0); /* 下面是设定0 */ if (cursor_c >= 0) { /* 如果需要显示光标 */ cursor_c = COL8_FFFFFF; } } else { timer_init(timer, &task->fifo, 1); /* 下面是设定1 */ if (cursor_c >= 0) { /* 如果需要显示光标 */ cursor_c = COL8_000000; } } timer_settime(timer, 50); /* 设置半秒 */ } if (i == 2) { /* 光标ON */ cursor_c = COL8_FFFFFF; } if (i == 3) { /* 光标OFF */ /* 直接用黑色将原来光标的位置消去 */ boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); cursor_c = -1; } if (256 <= i && i <= 511) { /* 任务A传送过来的键盘的数据 */ if (i == 8 + 256) { /* 注意!在任务A中已经将键值转换成字符的ASCII码了 */ /* 退格键 */ if (cursor_x > 16) { /* 用空格把光标消去之后 光标向左移8个像素点 */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x -= 8; } } else if (i == 10 + 256) { /* 如果是回车 (10是换行符的ASCII码) */ /* Enter */ /* 用空格将光标擦除 */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cmdline[cursor_x / 8 - 2] = 0; /* 计算前面有几个字符 在字符的后面加上'\0' */ /* 加'\0'是因为C语言中字符串都是以它结尾的 */ /* 减2是减去'\0'的位置还有一个回车的位置 所*/ /* 以最后'\0'是刚好在最后一个字符后面 */ cursor_y = cons_newline(cursor_y, sheet); /* 换行 */ /* 执行命令 */ if (strcmp(cmdline, "mem") == 0) { /* mem命令 */ /* 输出内存总大小和空闲内存大小 */ sprintf(s, "total %dMB", memtotal / (1024 * 1024)); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); /* 换行 */ sprintf(s, "free %dKB", memman_total(memman) / 1024); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); /* 换行 */ cursor_y = cons_newline(cursor_y, sheet); /* 换行 */ } else if (strcmp(cmdline, "cls") == 0) { /* cls命令 */ /* 最简单。。每个像素都设为黑色..... */ for (y = 28; y < 28 + 128; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = COL8_000000; } } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); cursor_y = 28; } else if (strcmp(cmdline, "dir") == 0) { /* dir命令 */ for (x = 0; x < 224; x++) { /* 遍历所有的根目录条目 */ /* 这个224是在ipl10中定义的 */ if (finfo[x].name[0] == 0x00) { /* 该条目不包含任何文件信息 */ break; } if (finfo[x].name[0] != 0xe5) { /* 该条目包含文件信息 */ if ((finfo[x].type & 0x18) == 0) { /* 该条目记录的不是目录 也不是非文件信息 */ sprintf(s, "filename.ext %7d", finfo[x].size); for (y = 0; y < 8; y++) { /* 设置文件名 */ s[y] = finfo[x].name[y]; } s[ 9] = finfo[x].ext[0]; /* 设置扩展名 */ s[10] = finfo[x].ext[1]; s[11] = finfo[x].ext[2]; putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); /* 换行 */ } } } cursor_y = cons_newline(cursor_y, sheet); /* 换行 */ } else if (strncmp(cmdline, "type ", 5) == 0) { /* type命令 */ /* 准备文件名 */ for (y = 0; y < 11; y++) { s[y] = ' '; } y = 0; for (x = 5; y < 11 && cmdline[x] != 0; x++) { if (cmdline[x] == '.' && y <= 8) { y = 8; } else { s[y] = cmdline[x]; if ('a' <= s[y] && s[y] <= 'z') { /* 将小写字母转换成大写字母 */ s[y] -= 0x20; } y++; } } /* 寻找文件 */ for (x = 0; x < 224; ) { if (finfo[x].name[0] == 0x00) { /* 该条目不包含任何文件信息 */ break; } if ((finfo[x].type & 0x18) == 0) { /* 该条目记录的不是目录 也不是非文件信息 */ for (y = 0; y < 11; y++) { if (finfo[x].name[y] != s[y]) { goto type_next_file; } } break; /* 找到文件就退出循环 */ } type_next_file: x++; } if (x < 224 && finfo[x].name[0] != 0x00) { /* 找到文件的情况 */ /* 分配内存 这块内存用于存放文件的内容 */ p = (char *) memman_alloc_4k(memman, finfo[x].size); /* 将软盘中该文件的内容复制到p指向的内存中 */ file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); cursor_x = 8; for (y = 0; y < finfo[x].size; y++) { /* 逐个输出文件中的内容 */ s[0] = p[y]; s[1] = 0; if (s[0] == 0x09) { /* 制表符 */ for (;;) { /* 这一小段就不注释了,偷下懒 书中解释的很详细 */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } if (((cursor_x - 8) & 0x1f) == 0) { break; /* 被32整除则break */ } } } else if (s[0] == 0x0a) { /* 换行 */ cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } else if (s[0] == 0x0d) { /* 回车 */ /* 忽略 */ } else { /* 一般字符 */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } } } /* 输出完毕 将刚申请的内存空间释放掉 */ memman_free_4k(memman, (int) p, finfo[x].size); } else { /* 文件没有找到 */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); } else if (strcmp(cmdline, "hlt") == 0) { /* 调用应用程序 */ for (y = 0; y < 11; y++) { s[y] = ' '; } /* 设置文件名 */ s[0] = 'H'; s[1] = 'L'; s[2] = 'T'; s[8] = 'H'; s[9] = 'R'; s[10] = 'B'; /* 查找文件 */ for (x = 0; x < 224; ) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y++) { if (finfo[x].name[y] != s[y]) { goto hlt_next_file; } } break; /* 找到文件 */ } hlt_next_file: x++; } if (x < 224 && finfo[x].name[0] != 0x00) { /* 找到文件的情况 */ /* 分配一块内存 文件将被加载到这个并执行 */ p = (char *) memman_alloc_4k(memman, finfo[x].size); /* 将文件的内容复制到p指向的缓冲区 */ file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); /* 为我们的应用程序创建一个描述符 */ set_segmdesc(gdt + 1003, finfo[x].size - 1, (int) p, AR_CODE32_ER); /* 跳转到应用程序执行 */ farjmp(0, 1003 * 8); /* 释放内存 */ memman_free_4k(memman, (int) p, finfo[x].size); } else { /* 文件没有找到 */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); } else if (cmdline[0] != 0) { /* 控制台有输入但不是上面的命令 */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "Bad command.", 12); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } /* 输出一个'>' */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); cursor_x = 16; } else { /* 一般字符 */ if (cursor_x < 240) { /* 显示一个字符后光标向右移8个像素点 */ s[0] = i - 256; s[1] = 0; cmdline[cursor_x / 8 - 2] = i - 256; putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; } } } /* 如果需要显示光标 */ if (cursor_c >= 0) { boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); } sheet_refresh(sheet, cursor_x, cursor_y, cursor_x + 8, cursor_y + 16); } } }
void HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; struct FIFO32 fifo; char s[40]; int fifobuf[128]; struct TIMER *timer, *timer2, *timer3; int mx, my, i, cursor_x, cursor_c, task_b_esp; unsigned int memtotal; struct MOUSE_DEC mdec; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct SHTCTL *shtctl; 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 TSS32 tss_a, tss_b; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; init_gdtidt(); init_pic(); io_sti(); fifo32_init(&fifo, 128, fifobuf); init_pit(); init_keyboard(&fifo, 256); enable_mouse(&fifo, 512, &mdec); io_out8(PIC0_IMR, 0xf8); io_out8(PIC1_IMR, 0xef); timer = timer_alloc(); timer_init(timer, &fifo, 10); timer_settime(timer, 1000); timer2 = timer_alloc(); timer_init(timer2, &fifo, 3); timer_settime(timer2, 300); timer3 = timer_alloc(); timer_init(timer3, &fifo, 1); timer_settime(timer3, 50); 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_screen8(buf_back, binfo->scrnx, binfo->scrny); init_mouse_cursor8(buf_mouse, 99); make_window8(buf_win, 160, 52, "window"); make_textbox8(sht_win, 8, 28, 144, 16, COL8_FFFFFF); cursor_x = 8; cursor_c = COL8_FFFFFF; sheet_slide(sht_back, 0, 0); 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); sprintf(s, "(%3d, %3d)", mx, my); putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10); sprintf(s, "memory %dMB free : %dKB" , memtotal / (1024 * 1024), memman_total(memman) / 1024); putfonts8_asc_sht(sht_back, 0, 32, COL8_FFFFFF, COL8_008484, s, 40); tss_a.ldtr = 0; tss_a.iomap = 0x40000000; tss_b.ldtr = 0; tss_b.iomap = 0x40000000; set_segmdesc(gdt + 3, 103, (int) &tss_a, AR_TSS32); set_segmdesc(gdt + 4, 103, (int) &tss_b, AR_TSS32); load_tr(3 * 8); task_b_esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024; tss_b.eip = (int) &task_b_main; tss_b.eflags = 0x00000202; tss_b.eax = 0; tss_b.ecx = 0; tss_b.edx = 0; tss_b.ebx = 0; tss_b.esp = task_b_esp; tss_b.ebp = 0; tss_b.esi = 0; tss_b.edi = 0; tss_b.es = 1 * 8; tss_b.cs = 2 * 8; tss_b.ss = 1 * 8; tss_b.ds = 1 * 8; tss_b.fs = 1 * 8; tss_b.gs = 1 * 8; for (;;) { io_cli(); if (fifo32_status(&fifo) == 0) { io_stihlt(); } else { i = fifo32_get(&fifo); io_sti(); if (256 <=i && i <= 511) { sprintf(s, "%02X", i - 256); putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2); if (i < 0x54 + 256) { 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 (i == 256 + 0x0e && 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 (512 <= i && i <= 767) { if (mouse_decode(&mdec, i - 512) != 0) { 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'; } putfonts8_asc_sht(sht_back, 32, 16, COL8_FFFFFF, COL8_008484, s, 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); putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10); sheet_slide(sht_mouse, mx, my); if ((mdec.btn & 0x01) != 0) { sheet_slide(sht_win, mx - 80, my - 8); } } } else if (i == 10) { putfonts8_asc_sht(sht_back, 0, 64, COL8_FFFFFF, COL8_008484, "10[sec]", 7); taskswitch4(); } else if (i == 3) { putfonts8_asc_sht(sht_back, 0, 80, COL8_FFFFFF, COL8_008484, "3[sec]", 6); } else if (i <= 1) { if (i != 0) { timer_init(timer3, &fifo, 0); cursor_c = COL8_000000; } else { timer_init(timer3, &fifo, 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 HariMain(void) { int i; struct BOOTINFO *binfo = (struct BOOTINFO *)0x0ff0; int xsize = (*binfo).scrnx; int ysize = (*binfo).scrny; char *vram = (*binfo).vram; char msg[40], mcursor[256]; int mx = xsize/2; int my = ysize/2; int fifobuf[128]; struct MOUSE_DEC mdec; unsigned char s[32]; unsigned int memtotal, count = 0; struct MEMMAN *memman = (struct MEMMAN *)MEMMAN_ADDR; int cursor_x, cursor_c; struct SHTCTL *shtctl; struct SHEET *sht_back, *sht_mouse, *sht_win; unsigned char *buf_back, buf_mouse[256], *buf_win; struct TIMER *timer1, *timer2, *timer3, *timer_ts; struct FIFO32 fifo; 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', '.' }; init_gdtidt (); init_pic (); io_sti (); fifo32_init(&fifo, 32, fifobuf); init_pit(); io_out8(PIC0_IMR, 0xf8); /* Allow PIT and Keyboard (11111000) */ io_out8(PIC1_IMR, 0xef); /* Allow Mouse (11101111) */ init_keyboard (&fifo, 256); enable_mouse (&fifo, 512, &mdec); timer1 = timer_alloc(); timer_init(timer1, &fifo, 10); timer_settime(timer1, 1000); timer2 = timer_alloc(); timer_init(timer2, &fifo, 3); timer_settime(timer2, 300); timer3 = timer_alloc(); timer_init(timer3, &fifo, 1); timer_settime(timer3, 50); memtotal = memtest(0x00400000, 0xbfffffff); memman_init (memman); memman_free (memman, 0x00001000, 0x009e000); /* 0x00001000 - 0x0009efff */ memman_free (memman, 0x00400000, memtotal - 0x00400000); init_pallete(); 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 (buf_back, xsize, ysize); init_mouse_cursor8 (buf_mouse, 99); make_window8(buf_win, 160, 52, "counter"); sprintf (s, "(%d, %d)", 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(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s); make_textbox8 (sht_win, 8, 28, 144, 16, COL8_FFFFFF); cursor_x = 8; cursor_c = COL8_FFFFFF; sheet_slide (sht_back, 0, 0); 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); sheet_refresh (sht_back, 0, 0, binfo->scrnx, 48); //===================== // Task Settings //===================== struct TSS32 tas_a, tas_b; tas_a.ldtr = 0; tas_a.iomap = 0x40000000; tas_b.ldtr = 0; tas_b.iomap = 0x40000000; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *)ADR_GDT; set_segmdesc (gdt + 3, 103, (int)&tas_a, AR_TSS32); set_segmdesc (gdt + 4, 103, (int)&tas_b, AR_TSS32); load_tr(3 * 8); int tas_b_esp; tas_b_esp = memman_alloc_4k (memman, 64 * 1024) + 64 * 1024; *((int *) (tas_b_esp + 4)) = (int) sht_back; tas_b.eip = (int)&task_b_main; tas_b.eflags = 0x00000202; tas_b.eax = 0; tas_b.ecx = 0; tas_b.edx = 0; tas_b.ebx = 0; tas_b.esp = tas_b_esp; tas_b.ebp = 0; tas_b.esi = 0; tas_b.edi = 0; tas_b.es = 1 * 8; tas_b.cs = 2 * 8; tas_b.ss = 1 * 8; tas_b.ds = 1 * 8; tas_b.fs = 1 * 8; tas_b.gs = 1 * 8; //======================= // Task Switch for 0.02s //======================= timer_ts = timer_alloc(); timer_init(timer_ts, &fifo, 2); timer_settime(timer_ts, 2); for (;;) { count ++; io_cli(); if (fifo32_status(&fifo) == 0) { io_sti(); } else { i = fifo32_get(&fifo); io_sti(); if (i == 2) { farjmp(0, 4 * 8); timer_settime(timer_ts, 2); } else if (256 <= i && i <= 511) { // Keyboard Data sprintf (s, "%x", i - 256); putfonts8_asc_sht (sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 2); if (i < 256 + 0x54) { if (keytable[i - 256] != 0) { 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 (i == 256 + 0x0e && cursor_x > 8) { // Backspace 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 (512 <= i && i <= 767) { // Mouse Data if (mouse_decode(&mdec, i-512) != 0) { sprintf (s, "[lcr %d %d]", 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'; } putfonts8_asc_sht (sht_back, 32, 16, COL8_FFFFFF, COL8_008484, s, 15); mx += mdec.x; my += mdec.y; if (mx < 0) { mx = 0; } if (mx > binfo->scrnx - 1) { mx = binfo->scrnx - 1; } if (my < 0) { my = 0; } if (my > binfo->scrny - 1) { my = binfo->scrny - 1; } sprintf(s, "(%d, %d)", mx, my); putfonts8_asc_sht (sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 10); sheet_slide (sht_mouse, mx, my); if ((mdec.btn & 0x01) != 0) { sheet_slide (sht_win, mx - 80, my - 8); } } } else if (i == 10) { putfonts8_asc_sht (sht_back, 0, 64, COL8_FFFFFF, COL8_008484, "10[sec]", 7); } else if (i == 3) { putfonts8_asc_sht (sht_back, 0, 80, COL8_FFFFFF, COL8_008484, "3[sec]", 6); count = 0; } else if (i <= 1) { if (i != 0) { timer_init(timer3, &fifo, 0); cursor_c = COL8_000000; } else { timer_init(timer3, &fifo, 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 console_task(struct SHEET *sheet, unsigned int memtotal) { struct TIMER *timer; struct TASK *task = task_now(); int i, fifobuf[128], cursor_x = 16, cursor_y = 28, cursor_c = -1; char s[30], cmdline[30], *p; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; int x, y; struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); int *fat = (int *) memman_alloc_4k(memman, 4 * 2880); struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; fifo32_init(&task->fifo, 128, fifobuf, task); timer = timer_alloc(); timer_init(timer, &task->fifo, 1); timer_settime(timer, 50); file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); /* プロンプト表示 */ putfonts8_asc_sht(sheet, 8, 28, COL8_FFFFFF, COL8_000000, ">", 1); for (;;) { io_cli(); if (fifo32_status(&task->fifo) == 0) { task_sleep(task); io_sti(); } else { i = fifo32_get(&task->fifo); io_sti(); if (i <= 1) { /* カーソル用タイマ */ if (i != 0) { timer_init(timer, &task->fifo, 0); /* 次は0を */ if (cursor_c >= 0) { cursor_c = COL8_FFFFFF; } } else { timer_init(timer, &task->fifo, 1); /* 次は1を */ if (cursor_c >= 0) { cursor_c = COL8_000000; } } timer_settime(timer, 50); } if (i == 2) { /* カーソルON */ cursor_c = COL8_FFFFFF; } if (i == 3) { /* カーソルOFF */ boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); cursor_c = -1; } if (256 <= i && i <= 511) { /* キーボードデータ(タスクA経由) */ if (i == 8 + 256) { /* バックスペース */ if (cursor_x > 16) { /* カーソルをスペースで消してから、カーソルを1つ戻す */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x -= 8; } } else if (i == 10 + 256) { /* Enter */ /* カーソルをスペースで消してから改行する */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cmdline[cursor_x / 8 - 2] = 0; cursor_y = cons_newline(cursor_y, sheet); /* コマンド実行 */ if (strcmp(cmdline, "mem") == 0) { /* memコマンド */ sprintf(s, "total %dMB", memtotal / (1024 * 1024)); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); sprintf(s, "free %dKB", memman_total(memman) / 1024); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } else if (strcmp(cmdline, "cls") == 0) { /* clsコマンド */ for (y = 28; y < 28 + 128; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = COL8_000000; } } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); cursor_y = 28; } else if (strcmp(cmdline, "dir") == 0) { /* dirコマンド */ for (x = 0; x < 224; x++) { if (finfo[x].name[0] == 0x00) { break; } if (finfo[x].name[0] != 0xe5) { if ((finfo[x].type & 0x18) == 0) { sprintf(s, "filename.ext %7d", finfo[x].size); for (y = 0; y < 8; y++) { s[y] = finfo[x].name[y]; } s[ 9] = finfo[x].ext[0]; s[10] = finfo[x].ext[1]; s[11] = finfo[x].ext[2]; putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); } } } cursor_y = cons_newline(cursor_y, sheet); } else if (strncmp(cmdline, "type ", 5) == 0) { /* typeコマンド */ /* ファイル名を準備する */ for (y = 0; y < 11; y++) { s[y] = ' '; } y = 0; for (x = 5; y < 11 && cmdline[x] != 0; x++) { if (cmdline[x] == '.' && y <= 8) { y = 8; } else { s[y] = cmdline[x]; if ('a' <= s[y] && s[y] <= 'z') { /* 小文字は大文字に直す */ s[y] -= 0x20; } y++; } } /* ファイルを探す */ for (x = 0; x < 224; ) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y++) { if (finfo[x].name[y] != s[y]) { goto type_next_file; } } break; /* ファイルが見つかった */ } type_next_file: x++; } if (x < 224 && finfo[x].name[0] != 0x00) { /* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo[x].size); file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); cursor_x = 8; for (y = 0; y < finfo[x].size; y++) { /* 1文字ずつ出力 */ s[0] = p[y]; s[1] = 0; if (s[0] == 0x09) { /* タブ */ for (;;) { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } if (((cursor_x - 8) & 0x1f) == 0) { break; /* 4で割り切れたらbreak */ } } } else if (s[0] == 0x0a) { /* 改行 */ cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } else if (s[0] == 0x0d) { /* 復帰 */ /* とりあえずなにもしない */ } else { /* 普通の文字 */ putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } } } memman_free_4k(memman, (int) p, finfo[x].size); } else { /* ファイルが見つからなかった場合 */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); } else if (strcmp(cmdline, "hlt") == 0) { /* hlt.hrbアプリケーションを起動 */ for (y = 0; y < 11; y++) { s[y] = ' '; } s[0] = 'H'; s[1] = 'L'; s[2] = 'T'; s[8] = 'H'; s[9] = 'R'; s[10] = 'B'; for (x = 0; x < 224; ) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y++) { if (finfo[x].name[y] != s[y]) { goto hlt_next_file; } } break; /* ファイルが見つかった */ } hlt_next_file: x++; } if (x < 224 && finfo[x].name[0] != 0x00) { /* ファイルが見つかった場合 */ p = (char *) memman_alloc_4k(memman, finfo[x].size); file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo[x].size - 1, (int) p, AR_CODE32_ER); farjmp(0, 1003 * 8); memman_free_4k(memman, (int) p, finfo[x].size); } else { /* ファイルが見つからなかった場合 */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); } else if (cmdline[0] != 0) { /* コマンドではなく、さらに空行でもない */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "Bad command.", 12); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } /* プロンプト表示 */ putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); cursor_x = 16; } else { /* 一般文字 */ if (cursor_x < 240) { /* 一文字表示してから、カーソルを1つ進める */ s[0] = i - 256; s[1] = 0; cmdline[cursor_x / 8 - 2] = i - 256; putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; } } } /* カーソル再表示 */ if (cursor_c >= 0) { boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); } sheet_refresh(sheet, cursor_x, cursor_y, cursor_x + 8, cursor_y + 16); } } }
void console_task(struct SHEET *sheet, unsigned int memtotal) { struct TIMER *timer; struct TASK *task = task_now(); int i, fifobuf[128], cursor_x = 16, cursor_y = 28, cursor_c = -1; char s[30], cmdline[30], *p; struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; int x, y; struct FILEINFO *finfo = (struct FILEINFO *) (ADR_DISKIMG + 0x002600); int *fat = (int *) memman_alloc_4k(memman, 4 * 2880); struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; fifo32_init(&task->fifo, 128, fifobuf, task); timer = timer_alloc(); timer_init(timer, &task->fifo, 1); timer_settime(timer, 50); file_readfat(fat, (unsigned char *) (ADR_DISKIMG + 0x000200)); putfonts8_asc_sht(sheet, 8, 28, COL8_FFFFFF, COL8_000000, ">", 1); for (;;) { io_cli(); if (fifo32_status(&task->fifo) == 0) { task_sleep(task); io_sti(); } else { i = fifo32_get(&task->fifo); io_sti(); if (i <= 1) { if (i != 0) { timer_init(timer, &task->fifo, 0); if (cursor_c >= 0) { cursor_c = COL8_FFFFFF; } } else { timer_init(timer, &task->fifo, 1); if (cursor_c >= 0) { cursor_c = COL8_000000; } } timer_settime(timer, 50); } if (i == 2) { cursor_c = COL8_FFFFFF; } if (i == 3) { boxfill8(sheet->buf, sheet->bxsize, COL8_000000, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); cursor_c = -1; } if (256 <= i && i <= 511) { if (i == 8 + 256) { if (cursor_x > 16) { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x -= 8; } } else if (i == 10 + 256) { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cmdline[cursor_x / 8 - 2] = 0; cursor_y = cons_newline(cursor_y, sheet); if (strcmp(cmdline, "mem") == 0) { sprintf(s, "total %dMB", memtotal / (1024 * 1024)); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); sprintf(s, "free %dKB", memman_total(memman) / 1024); putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } else if (strcmp(cmdline, "cls") == 0) { for (y = 28; y < 28 + 128; y++) { for (x = 8; x < 8 + 240; x++) { sheet->buf[x + y * sheet->bxsize] = COL8_000000; } } sheet_refresh(sheet, 8, 28, 8 + 240, 28 + 128); cursor_y = 28; } else if (strcmp(cmdline, "dir") == 0) { for (x = 0; x < 224; x++) { if (finfo[x].name[0] == 0x00) { break; } if (finfo[x].name[0] != 0xe5) { if ((finfo[x].type & 0x18) == 0) { sprintf(s, "filename.ext %7d", finfo[x].size); for (y = 0; y < 8; y++) { s[y] = finfo[x].name[y]; } s[ 9] = finfo[x].ext[0]; s[10] = finfo[x].ext[1]; s[11] = finfo[x].ext[2]; putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, s, 30); cursor_y = cons_newline(cursor_y, sheet); } } } cursor_y = cons_newline(cursor_y, sheet); } else if (strncmp(cmdline, "type ", 5) == 0) { for (y = 0; y < 11; y++) { s[y] = ' '; } y = 0; for (x = 5; y < 11 && cmdline[x] != 0; x++) { if (cmdline[x] == '.' && y <= 8) { y = 8; } else { s[y] = cmdline[x]; if ('a' <= s[y] && s[y] <= 'z') { s[y] -= 0x20; } y++; } } for (x = 0; x < 224; ) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y++) { if (finfo[x].name[y] != s[y]) { goto type_next_file; } } break; } type_next_file: x++; } if (x < 224 && finfo[x].name[0] != 0x00) { p = (char *) memman_alloc_4k(memman, finfo[x].size); file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); cursor_x = 8; for (y = 0; y < finfo[x].size; y++) { s[0] = p[y]; s[1] = 0; if (s[0] == 0x09) { for (;;) { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, " ", 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } if (((cursor_x - 8) & 0x1f) == 0) { break; } } } else if (s[0] == 0x0a) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } else if (s[0] == 0x0d) { } else { putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; if (cursor_x == 8 + 240) { cursor_x = 8; cursor_y = cons_newline(cursor_y, sheet); } } } memman_free_4k(memman, (int) p, finfo[x].size); } else { putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); } else if (strcmp(cmdline, "hlt") == 0) { for (y = 0; y < 11; y++) { s[y] = ' '; } s[0] = 'H'; s[1] = 'L'; s[2] = 'T'; s[8] = 'H'; s[9] = 'R'; s[10] = 'B'; for (x = 0; x < 224; ) { if (finfo[x].name[0] == 0x00) { break; } if ((finfo[x].type & 0x18) == 0) { for (y = 0; y < 11; y++) { if (finfo[x].name[y] != s[y]) { goto hlt_next_file; } } break; } hlt_next_file: x++; } if (x < 224 && finfo[x].name[0] != 0x00) { p = (char *) memman_alloc_4k(memman, finfo[x].size); file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo[x].size - 1, (int) p, AR_CODE32_ER); farjmp(0, 1003 * 8); memman_free_4k(memman, (int) p, finfo[x].size); } else { putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File not found.", 15); cursor_y = cons_newline(cursor_y, sheet); } cursor_y = cons_newline(cursor_y, sheet); } else if (cmdline[0] != 0) { putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "Bad command.", 12); cursor_y = cons_newline(cursor_y, sheet); cursor_y = cons_newline(cursor_y, sheet); } putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, ">", 1); cursor_x = 16; } else { if (cursor_x < 240) { s[0] = i - 256; s[1] = 0; cmdline[cursor_x / 8 - 2] = i - 256; putfonts8_asc_sht(sheet, cursor_x, cursor_y, COL8_FFFFFF, COL8_000000, s, 1); cursor_x += 8; } } } if (cursor_c >= 0) { boxfill8(sheet->buf, sheet->bxsize, cursor_c, cursor_x, cursor_y, cursor_x + 7, cursor_y + 15); } sheet_refresh(sheet, cursor_x, cursor_y, cursor_x + 8, cursor_y + 16); } } }
void HariMain(void) { /* **最初的这部分变量没有通过内存管理来分配,它们本身属于操作系统的一部分,存在于bootpack.hrb所在的那块儿内存空间中 */ BOOTINFO *binfo = (BOOTINFO *) ADR_BOOTINFO; MOUSE_DECODE mouse_dec; MEMMANAGE *memmanage = (MEMMANAGE *)MEMMANAGE_ADDR; LAYER_MANAGE *layer_manage; LAYER *layer_bg, *layer_mouse, *layer_window; TIMER *timer1, *timer2, *timer3; FIFO fifo_mutual; //缓冲区管理,所有中断公用的 TSS tss_a, tss_b; //用于切换的两个任务 int fifobuf[128]; //缓冲区 int cursor_x = 8, cursor_color = COL8_FFFFFF; //分别代表输入字符后的那个闪烁光标的横坐标和颜色 int mCursorX, mCursorY; //鼠标光标显示位置的横纵坐标 int task_b_esp; unsigned int memory_total, i; char buf_cursor[mCursorWidth * mCursorHeight]; unsigned char *buf_bg, *buf_window; //屏幕的大背景会在init_screen的时候画出来,这里只需要一个指向它的指针即可 unsigned char strings[40]; mCursorX = binfo->scrnx / 2; mCursorY = (binfo->scrny - 28)/ 2; //减去下方任务栏的高度 /*内存检查*/ i = memtest(0x00400000, 0xbfffffff) / (1024 * 1024); //i的单位是MB /*内存管理*/ memmanage_init(memmanage); memory_total = i * 1024 * 1024; memmanage_free_4K(memmanage, 0x00001000, 0x0009e000); memmanage_free_4K(memmanage, 0x00400000, memory_total - 0x00400000); /*初始化接收中断的缓冲区*/ init_fifo(&fifo_mutual, 128, fifobuf); //初始化mouseFIFO缓冲区 /*初始化GDT和IDT表以及PIC板的数据*/ init_GDTandIDT(); //初始化GDT和IDT表 init_pic(); //初始化PIC主从板数据,除了IRQ2禁止了全部中断 io_sti(); //开始接收中断 /*初始化PIT中断控制*/ init_PIT(); /*若要接收鼠标中断需要两个步骤,首先必须使鼠标控制电路(就是键盘控制电路的一部分)有效,然后要使鼠标本身有效*/ init_keyboard(&fifo_mutual, 256); //初始化键盘控制器电路 enable_mouse(&fifo_mutual, 512, &mouse_dec); //激活鼠标 /*开放各种中断*/ io_out8(PIC0_IMR, 0xf8); //PIC0开发IRQ(11111000),开放IRQ0、IRQ1和IRQ2,定时器、键盘中断和从PIC板 io_out8(PIC1_IMR, 0xef); //PIC1开放IRQ(11101111), 开放鼠标中断 /*初始化调色板,为图形界面做准备*/ init_palette(); //初始化调色板 /*初始化图层管理,并且初始化鼠标光标和背景的图层*/ layer_manage = layer_man_init(memmanage, binfo->vram, binfo->scrnx, binfo->scrny); layer_bg = layer_alloc(layer_manage); //为背景分配图层 layer_mouse = layer_alloc(layer_manage); //为鼠标分配图层 layer_window = layer_alloc(layer_manage); //为窗口分配图层 buf_bg = (unsigned char *)memmanage_alloc_4K(memmanage, binfo->scrnx * binfo->scrny); //为背景图形的内容分配内存 buf_window = (unsigned char *)memmanage_alloc_4K(memmanage, 160 * 52); //为窗口图形的内容分配内存 /*为各个图形的图层内容进行设定*/ layer_set(layer_bg, buf_bg, binfo->scrnx, binfo->scrny, -1); layer_set(layer_mouse, buf_cursor, 16, 16 ,99); layer_set(layer_window, buf_window, 160, 52, -1); /*初始化整个桌面背景*/ init_screen(buf_bg, binfo->scrnx, binfo->scrny); //这个时候的init_screen不再是直接画出背景,而是在mBg内存地址中填写好背景内容 layer_slide(layer_bg, 0, 0); //把背景图层从(0,0)坐标开始画 /*初始化鼠标图标*/ init_mouse_cursor(buf_cursor, 99); //初始化鼠标光标 layer_slide(layer_mouse, mCursorX, mCursorY); //现在显示图形不需要再用displayShape函数了,直接用这个图层管理的绘图函数就行 /*初始化窗口*/ create_window(buf_window, 160, 52, "window"); //制作窗口 layer_slide(layer_window, 80, 72); //在指定位置显示出窗口 create_textbox(layer_window, 8, 28, 144, 16, COL8_FFFFFF); //在这个窗口中创建一个输入框 /*设置好各个图层的高度*/ layer_switch(layer_bg, 0); //把背景图层调为最底层,高度为0 layer_switch(layer_window, 1); //窗口图层调节为第二层,高度为1 layer_switch(layer_mouse, 2); //鼠标图层调为最高层,高度为2 /*定时器的初始化及其设置*/ timer1 = timer_alloc(); timer_init(timer1, &fifo_mutual, 10); timer_set(timer1, 1000); timer2 = timer_alloc(); timer_init(timer2, &fifo_mutual, 3); timer_set(timer2, 300); timer3 = timer_alloc(); timer_init(timer3, &fifo_mutual, 1); timer_set(timer3, 50); /*在屏幕上显示一些内存、鼠标和键盘等信息*/ sprintf(strings, "Memory has %dMB", i); displayStrings_CS(buf_bg, binfo->scrnx, 0, 48, COL8_FFFFFF,strings); layer_refresh(layer_bg, 0, 48, binfo->scrnx, 80); sprintf(strings, "free memory:%dKB",memmanage_total(memmanage) / 1024); displayStrings_CS(buf_bg, binfo->scrnx, 120, 48, COL8_FFFFFF,strings); //用字体显示当前内存容量 layer_refresh(layer_bg, 120, 48, binfo->scrnx, 80); /*任务切换*/ SEGMENT_DESCRIPTOR *gdt = (SEGMENT_DESCRIPTOR *)ADR_GDT; tss_a.ldtr = 0; tss_a.iomap = 0x40000000; tss_b.ldtr = 0; tss_b.iomap = 0x40000000; set_segmdesc(gdt + 3, 103, (int) &tss_a, AR_TSS32); //任务a在第三个段中运行,段限是103字节 set_segmdesc(gdt + 4, 103, (int) &tss_b, AR_TSS32); load_tr(3 * 8); //代表当前在运行第三个段中的程序 task_b_esp = memmanage_alloc_4K(memmanage, 64 * 1024) + 64 * 1024; tss_b.eip = (int) &task_b_main; tss_b.eflags = 0x00000202; /* IF = 1; */ tss_b.eax = 0; tss_b.ecx = 0; tss_b.edx = 0; tss_b.ebx = 0; tss_b.esp = task_b_esp; tss_b.ebp = 0; tss_b.esi = 0; tss_b.edi = 0; tss_b.es = 1 * 8; tss_b.cs = 2 * 8; tss_b.ss = 1 * 8; tss_b.ds = 1 * 8; tss_b.fs = 1 * 8; tss_b.gs = 1 * 8; for(;;) { /*只有在从中断返回的缓冲区中读取数据的时候才需要禁止中断,因为如果这个时候来了中断而没有禁止的话, **有可能读脏数据,即把还没有读出的数据的给抹掉或换成别的数据 */ io_cli(); if(0 == fifo_status(&fifo_mutual)) //当前没有中断产生 { io_stihlt(); //当CPU执行hlt指令之后只有外部中断等之情况才会再次唤醒CPU继续工作 } else { i = fifo_get(&fifo_mutual); io_sti(); if((keyboard_offset <= i) && (i <= keyboard_offset + 255)) //键盘数据 { sprintf(strings, "%2X", i - keyboard_offset); displayStrings_atLayer(layer_bg, 0, 0, COL8_FFFFFF, COL8_008484, strings); //由于向背景图层中添加了新东西,需要重绘各个图层 if(i < keyboard_offset + 0x54) //判断按下的字符是否可打印 { if(0 != key_table[i - keyboard_offset] && cursor_x < 144) //0对应的字符无法打印出来 { strings[0] = key_table[i - keyboard_offset]; strings[1] = 0; displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, strings); cursor_x += 8; //光标的位置随着每一个字符的输入向后移动一个字符宽度的位置即8像素 } if((keyboard_offset + 0x0e == i) && cursor_x > 8) //按下了退格键的情况,退格键的号码是0x0e { cursor_x -= 8; /*本来退格键应该只填充一个空格就行的,但是这样的话没办法刷新光标所在的那块儿区域了, **会留下光标的黑色痕迹,所以直接填充两个空格,刷新之后就不会有痕迹了 */ displayStrings_atLayer(layer_window, cursor_x, 28, COL8_000000, COL8_FFFFFF, " "); } //由于光标坐标后退了,为了及时显示它,需要立即重绘光标 drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15); layer_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44); } } else if((mouse_offset <= i) && (i <= mouse_offset + 255)) //鼠标数据 { if(0 != mouse_decode(&mouse_dec, i - mouse_offset)) //只有返回值为1的时候才说明成功接收完成一次鼠标的中断 { /*显示鼠标的信息*/ sprintf(strings,"[lcr %3d,%3d]",mouse_dec.x, mouse_dec.y); if(0 != (mouse_dec.btn & 0x01)) //按下了左键 { strings[1] = 'L'; //layer_slide(layer_window, mCursorX - 80, mCursorY -8); //这行代码是移动窗口的 } if(0 != (mouse_dec.btn & 0x02)) //按下了右键 { strings[3] = 'R'; } if(0 != (mouse_dec.btn & 0x04)) //按下了中键 { strings[2] = 'C'; } displayStrings_atLayer(layer_bg, 0, 16, COL8_FFFFFF, COL8_008484, strings); /*鼠标的移动*/ //根据mouse_dec里存储的鼠标信息画出新的鼠标图像 mCursorX += mouse_dec.x; mCursorY += mouse_dec.y; //不能让鼠标移出画面 if(mCursorX < 0) { mCursorX = 0; } if(mCursorY < 0) { mCursorY = 0; } if(mCursorX > binfo->scrnx - 1) { mCursorX = binfo->scrnx - 1; } if(mCursorY > binfo->scrny - 1) { mCursorY = binfo->scrny - 1; } sprintf(strings, "(%3d,%3d)", mCursorX, mCursorY); displayStrings_atLayer(layer_bg, 40, 32, COL8_FFFFFF, COL8_008484, strings); layer_slide(layer_mouse, mCursorX, mCursorY); } } else if(10 == i) //10秒定时器 { displayStrings_atLayer(layer_bg, 0, 64, COL8_FFFFFF, COL8_008484, "10[sec]"); taskswitch4(); //执行任务切换 } else if(3 == i) //3秒定时器 { displayStrings_atLayer(layer_bg, 0, 80, COL8_FFFFFF, COL8_008484, "3[sec]"); } else if(1 == i || 0 == i) //光标闪烁定时器 { if(0 != i) //这个timer的数据为1的时候显示光标 { timer_init(timer3, &fifo_mutual, 0); cursor_color = COL8_000000; } else //这个timer的数据为0的时候不显示光标 { timer_init(timer3, &fifo_mutual, 1); cursor_color = COL8_FFFFFF; } timer_set(timer3, 50); drawRectangle(layer_window->buffer, layer_window->length, cursor_color, cursor_x, 28, 2, 15); layer_refresh(layer_window, cursor_x, 28, cursor_x + 8, 44); } } } }