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(); }
task_t* task_init(mem_mgr_t* mem_mgr) { int i; task_t* task; segment_descriptor_t* gdt = (segment_descriptor_t*)ADR_GDT; g_taskctrl = (task_ctrl_t*)mem_mgr_alloc_4k(mem_mgr, sizeof(task_ctrl_t)); for (i = 0; i < MAX_TASKS; ++i) { g_taskctrl->tasks[i].flags = 0; g_taskctrl->tasks[i].sel = (TASK_GDT0 + i) * 8; set_segment_descriptor(gdt + TASK_GDT0 + i, 103, (int)&g_taskctrl->tasks[i].tss, AR_TSS32); } task = task_alloc(); task->flags = 2; /* flags about activity */ g_taskctrl->running = 1; g_taskctrl->now = 0; g_taskctrl->tasks_map[0] = task; load_tr(task->sel); g_task_timer = timer_alloc(); timer_settimer(g_task_timer, 2); return task; }
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(); }
Task* TaskControll::Initialize(){ Task* task,*idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR*) ADR_GDT; //とりあえず全部のタスクを初期化 for(int i=0; i<MAX_TASKS; i++){ TaskControll::tasks0[i].flags = 0; TaskControll::tasks0[i].sel = (TASK_GDT0 + i)*8; Descriptor::set_segmdesc(gdt+TASK_GDT0+i,103,(int) &TaskControll::tasks0[i].tss,AR_TSS32); } //すべてのレベルのタスク数を0にする for(int i=0; i<MAX_TASKLEVELS; i++){ TaskControll::level[i].running = 0; TaskControll::level[i].now = 0; } //現在のタスクを作る task = TaskControll::alloc(); task->flags = 2; //動作中 task->priority = 2; //優先度2 task->level = 0; //最高レベルにおく task->title = (unsigned char*)Memory::alloc_4k( strlen("Main") +4); //タスクに名前を付ける strcpy((char*)task->title,"main"); TaskControll::task_add(task); //タスクを追加 TaskControll::task_switchsub();//レベルを切り替える load_tr(task->sel); //アイドルタスクを作る idle = TaskControll::alloc(); idle->tss.esp = Memory::alloc_4k(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; idle->title = (unsigned char*)Memory::alloc_4k( strlen("Idle") +4); //タスクに名前を付ける strcpy((char*)idle->title,"Idle"); idle->run(MAX_TASKLEVELS-1,1); //タスクタイマーを作る TaskControll::timer = TimerControl::alloc(); TaskControll::timer->settime(task->priority); 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; }
/* 1st task_init */ void task_init(struct MEMMAN *memman, struct SHEET *sht_back) { /* init tss_a */ task_a_esp = (int) memman_alloc_4k(memman, 4096); memset(&tss_a, 0, sizeof(struct TSS32)); tss_a.ldtr = 0; tss_a.iomap = 0x40000000; #if 0 tss_a.eip = (int)&task_a_main; tss_a.eflags = 0x00000202; /**/ tss_a.esp = task_a_esp; tss_a.es = 1 * 8; tss_a.cs = 2 * 8; tss_a.ss = 1 * 8; tss_a.ds = 1 * 8; tss_a.fs = 1 * 8; tss_a.gs = 1 * 8; #endif /* init tss_b */ task_b_esp = (int) memman_alloc_4k(memman, 4096) + 4096 - 8; memset(&tss_b, 0, sizeof(struct TSS32)); tss_b.ldtr = 0; tss_b.iomap = 0x40000000; tss_b.eip = (int)&task_b_main; tss_b.eflags = 0x00000202; /**/ tss_b.esp = task_b_esp; 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; load_tr(3 * 8); *((int *) (task_b_esp + 4)) = (int) sht_back; mt_timer = timer_alloc(); timer_settime(mt_timer, 200); mt_tr = 3 * 8; }
/* 整个多任务系统的初始化初始化 */ 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; }
/** * @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; }
task_t* task_init(mem_mgr_t* mem_mgr) { int i; task_t* task; task_t* idle; segment_descriptor_t* gdt = (segment_descriptor_t*)ADR_GDT; g_taskctrl = (task_ctrl_t*)mem_mgr_alloc_4k(mem_mgr, sizeof(task_ctrl_t)); for (i = 0; i < MAX_TASKS; ++i) { g_taskctrl->tasks[i].flags = 0; g_taskctrl->tasks[i].sel = (TASK_GDT0 + i) * 8; set_segment_descriptor(gdt + TASK_GDT0 + i, 103, (int)&g_taskctrl->tasks[i].tss, AR_TSS32); } for (i = 0; i < MAX_TASKLEVELS; ++i) { g_taskctrl->levels[i].running = 0; g_taskctrl->levels[i].now = 0; } task = task_alloc(); task->flags = 2; /* flags about activity */ task->level = 0; /* top task level */ task->priority = 2; /* 0.02 s */ task_add(task); task_switch_sub(); /* setting level */ load_tr(task->sel); g_task_timer = timer_alloc(); timer_settimer(g_task_timer, task->priority); idle = task_alloc(); idle->tss.esp = mem_mgr_alloc_4k(mem_mgr, 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; }
static void tss_gdt_desc_init() { void * gdt = get_gdt_ptr(); const virt_t tss_addr = (virt_t) &tss; const size_t tss_size_desc = (sizeof(tss_strct)) - 1; tss_desc desc = { .base_0 = SPLICE(tss_addr, 0, 16), .base_1 = SPLICE(tss_addr, 16, 24), .base_2 = SPLICE(tss_addr, 24, 32), .base_3 = SPLICE(tss_addr, 32, 64), .limit_0 = SPLICE(tss_size_desc, 0, 16), .limit_1 = SPLICE(tss_size_desc, 16, 20), .type = (TSS_DESC_TYPE) | (TSS_DPL << 5) | (TSS_PRESENT << 7), }; *(tss_desc *)(((uint64_t* )gdt) + TSS_TI) = desc; } static void tss_selector_load() { load_tr(TSS_SELECTOR); }
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; }
//任务管理主体的初始化(并为调用这个函数的那个程序分配一个任务状态段) 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; }
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; }
void ap_task_init() { struct thread *t_idle; tss_t *tss; uint16_t selektor; // IDLE-Thread fuer den AP erzeugen... t_idle = get_current_thread(); t_idle->cr3 = kernel_cr3; t_idle->esp0 = ((uint32_t) t_idle) + PAGE_SIZE;; t_idle->state = THREAD_IDLE; t_idle->priority = 0; disable_interrupts(); t_idle->counter = t_idle->priority; t_idle->need_reschedule = 0; enable_interrupts(); // IDLE-Thread in die Thread-Liste aufnehmen... add_thread(t_idle); // TSS initialiesieren und laden... tss = (tss_t *) (t_idle + 1); selektor = TSS_SELEKTOR(get_apic_id()); memset(tss, 0, sizeof(tss_t)); tss->esp0 = t_idle->esp0; tss->ss0 = KERNEL_DATA_SELEKTOR; set_tss_deskriptor(BSP_TSS_SELEKTOR, tss); load_tr(BSP_TSS_SELEKTOR); t_idle->tss = tss; return; }
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; }
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 HariMain(void) { struct BOOTINFO *binfo = (struct BOOTINFO *) ADR_BOOTINFO; g_binfo = binfo; struct FIFO32 fifo; char s[40]; int fifobuf[128]; struct TIMER *timer, *timer2, *timer3; int mx, my, i; int cursor_x, cursor_c; 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; int task_b_esp; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR*)ADR_GDT; init_gdtidt(); init_pic(); io_sti(); /* GDT,IDT,PIC*/ fifo32_init(&fifo, 128, fifobuf); // timer init_pit(); 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); io_out8(PIC0_IMR, 0xf8); // 11111001,PIC1和IRQ1, io_out8(PIC1_IMR, 0xef); // 11101111, IRQ12 init_keyboard(&fifo, 256); enable_mouse(&fifo, 512, &mdec); 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, "counter"); 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, "(0x%x, 0x%x)", mx, my); putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); sprintf(s, "memory 0x%xMB, free : 0x%xKB", memtotal / (1024 * 1024), memman_total(memman) / 1024); putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s); sheet_refresh(sht_back, 0, 0, binfo->scrnx, 48); 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 - 8; *((int *) (task_b_esp + 4)) = (int) sht_back; tss_b.eip = (int)&task_b_main - ADR_BOTPAK; 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; mt_init(); for(;;) { io_cli(); if(0 == fifo32_status(&fifo)) { io_sti(); }else{ i = fifo32_get(&fifo); io_sti(); if (256 <= i && i <= 511) { sprintf(s, "0x%x", i - 256); putfonts8_asc_sht(sht_back, 0, 16, COL8_FFFFFF, COL8_008484, s, 8); if (i < 256 + 0x54) { if (0 != keytable[i - 256] && cursor_x < 144) { s[0] = keytable[i - 256]; s[1] = 0; putfonts8_asc_sht(sht_win, cursor_x, 28, COL8_000000, COL8_C6C6C6, 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); } // if key status else if (512 <= i && i <= 767) { if (0 != mouse_decode(&mdec, i - 512)) { sprintf(s, "[lcr 0x%x 0x%x 0x%x]", mdec.buf[0], mdec.buf[1], mdec.buf[2]); if (0 != (mdec.btn & 0x01)) { s[1] = 'L'; } if (0 != (mdec.btn & 0x02)) { s[3] = 'R'; } if (0 != (mdec.btn & 0x04)) { s[2] = 'C'; } putfonts8_asc_sht(sht_back, 64, 16, COL8_FFFFFF, COL8_008484, s, 24); 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, "(0x%x, 0x%x)", mx, my); putfonts8_asc_sht(sht_back, 0, 0, COL8_FFFFFF, COL8_008484, s, 16); sheet_slide(sht_mouse, mx, my); /* 显示鼠标 */ // if ((mdec.btn & 0x01) != 0) { sheet_slide(sht_win, mx - 80, my - 8); } } // if mouse decode } // if 512 767 else if (10 == i) { putfonts8_asc_sht(sht_back, 0, 64, COL8_FFFFFF, COL8_008484, "10[sec]", 7); } else if (3 == i) { putfonts8_asc_sht(sht_back, 0, 80, COL8_FFFFFF, COL8_008484, "3[sec]", 6); } else if (i <= 1) { if (0 != i) { timer_init(timer3, &fifo, 0); // set to 0 cursor_c = COL8_000000; } else { timer_init(timer3, &fifo, 1); cursor_c = COL8_FFFFFF; } boxfill8(sht_win->buf, sht_win->bxsize, cursor_c, cursor_x, 28, cursor_x + 7, 43); timer_settime(timer3, 50); sheet_refresh(sht_back, 8, 96, 16, 112); } } // else 0 == getstatus fifo } // for return; }
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); } } } }
////初始化进程管理器 //返回:内核进程task_a struct TASK *task_init(struct MEMMAN *memman) { int i,j; struct TASK *task, *idle; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); //事先将全部的TASK结构的TSS和LDT、文件描述符都设置好 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[i].pid = -1; taskctl->tasks0[i].forked = 0; strcpy(taskctl->tasks0[i].name,"anony"); taskctl->tasks0[i].flags = 0; //标志未使用 taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8; //设置TSS的seletor, 当进行任务切换的时候,是跳转到这个段上的。 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); //TSS段 set_segmdesc(gdt + TASK_GDT0 + MAX_TASKS + i, 15, (int) taskctl->tasks0[i].ldt, AR_LDT); //LDT段 //设置任务的文件描述符 for(j=0; j<NR_FILES; j++){ taskctl->tasks0[i].filp[j] = 0; } /* TODO: 初始化进程的键盘输入缓冲,这里的内存可能没有被释放*/ int bufCount = 100; int *fifobuf = (int *)memman_alloc(memman,sizeof(int)*bufCount); taskctl->tasks0[i].ch_buf.task = &taskctl->tasks0[i]; fifo32_init(&taskctl->tasks0[i].ch_buf, bufCount, fifobuf, 0); } 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); 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; strcpy(idle->name,"idle"); task_run(idle, MAX_TASKLEVELS - 1, 1); //默认情况下,所有进程的父进程都是idle,包括task_a和idle自己。 for (i = 0; i < MAX_TASKS; i++) { taskctl->tasks0[0].parent_pid = idle->pid; } return task; }
int emu_0f(unsigned char *lina) { unsigned char *orig_lina = lina; switch (lina[1]) { case 0x00: /* lldt, ltr */ { switch (REG_OPCODE(lina[2])) { case 2: /* 0F 00 /2 LLDT r/m16 Load segment selector r/m16 into LDTR */ { u_int addr, is_addr, reg, selector; trace("lldt\n"); if (!opa.pe) { set_guest_exc(EXC_UD, 0); goto exc; } if (opa.cpl != 0) { set_guest_exc(EXC_GP, 0); goto exc; } lina += 2; /* move up to RM byte */ decode_rm16(&addr, &is_addr, ®, &lina); if (emu_get(is_addr, addr, &selector, 2)) goto exc; if (load_ldtr(selector)) goto exc; break; } case 3: /* 0F 00 /3 LTR r/m16 Load r/m16 into TR */ { u_int addr, is_addr, reg; Bit32u dtr; trace("ltr\n"); if (!opa.pe) { set_guest_exc(EXC_UD, 0); goto exc; } if (opa.cpl != 0) { set_guest_exc(EXC_GP, 0); goto exc; } lina += 2; /* move up to RM byte */ decode_rm16(&addr, &is_addr, ®, &lina); if (emu_get(is_addr, addr, &dtr, 2)) goto exc; if (load_tr(dtr)) goto exc; break; } default: unknown(lina); } break; } case 0x01: /* invlpg, lgdt, lidt, lmsw */ { int reg_op = REG_OPCODE(lina[2]); switch (reg_op) { case 2: /* lgdt */ case 3: /* lidt */ { u_int addr, is_addr, reg, limit, base; lina += 2; /* move up to RM byte */ decode_rm(&addr, &is_addr, ®, &lina); ASSERT(is_addr); /* addr now points to the m16&32; lina is at next instr */ if (get_memory(opa.seg, addr, &limit, 2) != 0 || get_memory(opa.seg, addr+2, &base, opa.opb==4 ? 4 : 3) != 0) goto exc; /* by definition of lgdt/lidt, base is a linear address already. */ if (reg_op == 2) { set_gdt(base, limit); } else { set_idt(base, limit); } debug_mem("loaded %cdt from 0x%08x\n", reg_op==2 ? 'g' : 'i', base); break; } case 6: /* 0F 01 /6 LMSW r/m16 Loads r/m16 in msw of CR0 */ { u_int addr, is_addr, reg, val; trace("lmsw\n"); if (opa.pe && opa.cpl!=0) { set_guest_exc(13, 0); goto exc; } lina += 2; /* move up to RM byte */ decode_rm16(&addr, &is_addr, ®, &lina); if (emu_get(is_addr, addr, &val, 2)) goto exc; if (vmstate.cr[0] & 1 && !(val & 1)) val |= 1; /* can't clear PE with lmsw */ mov_to_cr(0, val, 0x0000000f); /* only PE, MP, EM, and TS can be affected */ break; } case 7: /* invlpg */ { Bit32u ptr; debug("invlpg\n"); lina += 2; /* move up to memory operand */ if (opa.opb==4) { ptr = *(Bit32u*)lina; } else { ptr = *(Bit16u*)lina; } lina += opa.opb; if (vmstate.cr[0]&PG_MASK) { /* Modify a pte with itself. This should have the desired side effect of flushing that TLB entry. */ sys_self_mod_pte_range(0, 0, /* add no flag bits */ 0, /* remove no flag bits */ ptr, 1); } break; } default: unknown(lina); } break; } case 0x06: /* clts 0F 06 */ { if (opa.cpl!=0) { set_guest_exc(13, 0); goto exc; } else { vmstate.cr[0] &= ~TS_MASK; lina += 2; } break; } case 0x08: /* invd 0F 08 */ case 0x09: /* wbinvd 0F 09 */ { if (opa.cpl!=0) { set_guest_exc(13, 0); goto exc; } else { /* will not implement */ lina += 2; } break; } case 0x0b: /* UD2 */ { set_guest_exc(6, 0); goto exc; } case 0x20: /* MOV r <- CRx */ { int cr = REG_OPCODE(lina[2]); int reg = RM(lina[2]); ASSERT(cr<5); set_reg(reg, vmstate.cr[cr], 4); lina += 3; break; } case 0x21: /* MOV r <- DRx */ { int dr = REG_OPCODE(lina[2]); int reg = RM(lina[2]); set_reg(reg, vmstate.dr[dr], 4); lina += 3; break; } case 0x22: /* MOV CRx <- r */ { int cr = REG_OPCODE(lina[2]); ASSERT(cr<5); if (opa.pe && opa.cpl!=0) { set_guest_exc(13, 0); goto exc; } mov_to_cr(cr, get_reg(RM(lina[2]), 4), 0xffffffff); lina += 3; break; } case 0x23: /* MOV DRx <- r */ { int dr = REG_OPCODE(lina[2]); debug("mov dr%d <- r%d\n", dr, RM(lina[2])); if (opa.pe && opa.cpl!=0) { set_guest_exc(13, 0); goto exc; } vmstate.dr[dr] = get_reg(RM(lina[2]), 4); lina += 3; break; } case 0x30: /* wrmsr */ { int ctr = 0; if (REG(ecx) == P6MSR_CTRSEL0) ctr = 0; else if (REG(ecx) == P6MSR_CTRSEL1) ctr = 1; else unknown(lina); /* only performance counters are implemented */ sys_pctr(ctr==0 ? PCIOCS0 : PCIOCS1, 0, ®(eax)); lina += 2; break; } case 0x32: /* rdmsr */ { struct pctrst p; int ctr = 0; if (REG(ecx) == P6MSR_CTR0) ctr = 0; else if (REG(ecx) == P6MSR_CTR1) ctr = 1; else unknown(lina); /* only performance counters are implemented */ sys_pctr(PCIOCRD, 0, &p); REG(eax) = p.pctr_hwc[ctr]; REG(edx) = p.pctr_hwc[ctr] >> 32; lina += 2; break; } #if 0 case 0x33: /* rdpmc */ { struct pctrst p; /* or cpl!=0 and cr4 ... */ if (REG(ecx)>1) { set_guest_exc(EXC_GP, 0); goto exc; } sys_pctr(PCIOCRD, 0, &p); REG(eax) = p.pctr_hwc[REG(ecx)]; REG(edx) = p.pctr_hwc[REG(ecx)] >> 32; lina += 2; break; } #endif case 0xa2: /* cpuid */ { /* cpuid may trap on a Cyrix. I don't care. */ leaveemu(ERR_UNIMPL); break; } case 0xb2: /* lss */ case 0xb4: /* lfs */ case 0xb5: /* lgs */ { int seg; if (lina[1]==0xb2) { seg = REGNO_SS; } else if (lina[1]==0xb4) { seg = REGNO_FS; } else seg = REGNO_GS; if (load_far_pointer(&lina, seg)) goto exc; break; } case 0x31: /* rdtsc ... should be enabled in xok */ case 0xc8: /* bswap should not trap */ default: unknown(lina); } REG(eip) += lina-orig_lina; return 0; exc: return -1; }
void task_init() { struct thread *t_kernel; struct thread *t_idle; uint32_t *stack; tss_t *tss; // Kernel-Thread initialiesieren... t_kernel = &kernel_stack; t_kernel->cr3 = kernel_cr3; t_kernel->esp0 = ((uint32_t) t_kernel) + PAGE_SIZE;; t_kernel->state = THREAD_READY; t_kernel->priority = MAX_PRIORITY; disable_interrupts(); t_kernel->counter = t_kernel->priority; t_kernel->need_reschedule = 0; enable_interrupts(); // Kernel-Thread in die Thread-Liste // aufnehmen und die Run-Queue // initialiesieren... t_kernel->next = t_kernel; t_kernel->prev = t_kernel; first_thread = t_kernel; last_thread = t_kernel; t_kernel->q_next = NULL; queue_first = NULL; queue_last = NULL; // IDLE-Thread fuer den BSP erzeugen... t_idle = &idle_stack; t_idle->cr3 = kernel_cr3; t_idle->esp0 = ((uint32_t) t_idle) + PAGE_SIZE; t_idle->esp = t_idle->esp0 - (6 * sizeof(uint32_t)); t_idle->state = THREAD_IDLE; t_idle->priority = 0; t_idle->counter = t_idle->priority; t_idle->need_reschedule = 0; stack = (uint32_t *) t_idle->esp; stack[0] = 0; /* ebx */ stack[1] = 0; /* edi */ stack[2] = 0; /* esi */ stack[3] = 0; /* ebp */ stack[4] = EF_IF; /* eflags */ stack[5] = (uint32_t) idle; /* eip */ // IDLE-Thread in die Thread- und IDLE- // Liste aufnehmen... add_thread(t_idle); t_idle->q_next = NULL; idle_first = t_idle; // TSS initialiesieren und laden... tss = &bsp_tss; memset(tss, 0, sizeof(tss_t)); tss->esp0 = t_kernel->esp0; tss->ss0 = KERNEL_DATA_SELEKTOR; set_tss_deskriptor(BSP_TSS_SELEKTOR, tss); load_tr(BSP_TSS_SELEKTOR); t_kernel->tss = tss; return; }
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) { boot_info_t* binfo = (boot_info_t*)ADR_BOOTINFO; fifo32_t fifo; int fifobuf[128]; char debug_info[64]; timer_t* timer1; timer_t* timer2; timer_t* timer3; int mouse_x, mouse_y, cursor_x, cursor_c, task_b_esp; int data; mouse_dec_t mdec; unsigned int memory_total; mem_mgr_t* mem_mgr = (mem_mgr_t*)MEMMGR_ADDR; layer_mgr_t* layer_mgr; layer_t* back_layer; layer_t* mouse_layer; layer_t* win_layer; unsigned char* back_buf; unsigned char mouse_buf[256]; unsigned char* win_buf; static char s_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, '\\','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', '.' }; tss32_t tss_a, tss_b; segment_descriptor_t* gdt = (segment_descriptor_t*)ADR_GDT; init_gdt_idt(); init_pic(); io_sti(); /* after initialize IDT/PIC, allow all CPU's interruptors */ fifo_init(&fifo, fifobuf, 128); init_pit(); /* initialize programmable interval timer */ init_keyboard(&fifo, 256); enable_mouse(&fifo, 512, &mdec); io_out8(PIC0_IMR, 0xf8); /* set PIT/PIC1/keyboard permission 11111000 */ io_out8(PIC1_IMR, 0xef); /* set mouse permission 11101111 */ set490(&fifo, 1); timer1 = timer_alloc(); timer_init(timer1, &fifo, 10); timer_settimer(timer1, 1000); timer2 = timer_alloc(); timer_init(timer2, &fifo, 3); timer_settimer(timer2, 300); timer3 = timer_alloc(); timer_init(timer3, &fifo, 1); timer_settimer(timer3, 50); memory_total = memory_test(0x00400000, 0xbfffffff); mem_mgr_init(mem_mgr); mem_mgr_free(mem_mgr, 0x00001000, 0x0009e000); /*0x00001000~0x0009e000*/ mem_mgr_free(mem_mgr, 0x00400000, memory_total - 0x00400000); init_palette(); layer_mgr = layer_mgr_init(mem_mgr, binfo->vram, binfo->screen_x, binfo->screen_y); back_layer = layer_alloc(layer_mgr); mouse_layer = layer_alloc(layer_mgr); win_layer = layer_alloc(layer_mgr); back_buf = (unsigned char*)mem_mgr_alloc_4k(mem_mgr, binfo->screen_x * binfo->screen_y); win_buf = (unsigned char*)mem_mgr_alloc_4k(mem_mgr, 160 * 52); layer_setbuf(back_layer, back_buf, binfo->screen_x, binfo->screen_y, -1); layer_setbuf(mouse_layer, mouse_buf, 16, 16, 99); layer_setbuf(win_layer, win_buf, 160, 52, -1); init_screen(back_buf, binfo->screen_x, binfo->screen_y); init_mouse_cursor8(mouse_buf, 99); make_window8(win_buf, 160, 52, "Window"); make_text8(win_layer, 8, 28, 144, 16, COLOR8_FFFFFF); cursor_x = 8; cursor_c = COLOR8_FFFFFF; layer_slide(back_layer, 0, 0); mouse_x = (binfo->screen_x - 16) / 2; mouse_y = (binfo->screen_y - 28 - 16) / 2; layer_slide(mouse_layer, mouse_x, mouse_y); layer_slide(win_layer, 80, 72); layer_updown(back_layer, 0); layer_updown(win_layer, 1); layer_updown(mouse_layer, 2); sprintf(debug_info, "(%3d, %3d)", mouse_x, mouse_y); drawstring_and_refresh(back_layer, 0, 0, COLOR8_FFFFFF, COLOR8_848484, debug_info, 10); sprintf(debug_info, "memory total: %dMB, free space: %dKB", memory_total / (1024 * 1024), mem_mgr_total(mem_mgr) / 1024); drawstring_and_refresh(back_layer, 0, 32, COLOR8_FFFFFF, COLOR8_848484, debug_info, 40); tss_a.ldtr = 0; tss_a.iomap = 0x40000000; tss_b.ldtr = 0; tss_b.iomap = 0x40000000; set_segment_descriptor(gdt + 3, 103, (int)&tss_a, AR_TSS32); set_segment_descriptor(gdt + 4, 103, (int)&tss_b, AR_TSS32); load_tr(3 * 8); task_b_esp = mem_mgr_alloc_4k(mem_mgr, 64 * 1024) + 64 * 1024 - 8; 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; *((int*)(task_b_esp + 4)) = (int)back_layer; mt_init(); for ( ; ; ) { io_cli(); if (0 == fifo_size(&fifo)) io_stihlt(); else { data = fifo_get(&fifo); io_sti(); if (256 <= data && data <= 511) { sprintf(debug_info, "%02X", data - 256); drawstring_and_refresh(back_layer, 0, 16, COLOR8_FFFFFF, COLOR8_848484, debug_info, 2); if (data < (256 + 0x54)) { if (0 != s_keytable[data - 256] && cursor_x < 144) { /* normal character, show 1 character, move cursor 1 time */ debug_info[0] = s_keytable[data - 256]; debug_info[1] = 0; drawstring_and_refresh(win_layer, cursor_x, 28, COLOR8_000000, COLOR8_FFFFFF, debug_info, 1); cursor_x += 8; } } if ((256 + 0x0e) == data && cursor_x > 8) { /* backspace, recover cursor by sapce, move back cursor 1 time */ drawstring_and_refresh(win_layer, cursor_x, 28, COLOR8_000000, COLOR8_FFFFFF, " ", 1); cursor_x -= 8; } /* show cursor again */ fill_box8(win_layer->buf, win_layer->w_size, cursor_c, cursor_x, 28, cursor_x + 7, 43); layers_refresh(win_layer, cursor_x, 28, cursor_x + 8, 44); } else if (512 <= data && data <= 767) { if (0 != mouse_decode(&mdec, data - 512)) { /* show all mouse bytes code */ sprintf(debug_info, "[lcr %4d %4d]", mdec.x, mdec.y); if (0 != (mdec.state & 0x01)) debug_info[1] = 'L'; if (0 != (mdec.state & 0x02)) debug_info[3] = 'R'; if (0 != (mdec.state & 0x04)) debug_info[2] = 'C'; drawstring_and_refresh(back_layer, 32, 16, COLOR8_FFFFFF, COLOR8_848484, debug_info, 15); mouse_x += mdec.x; mouse_y += mdec.y; if (mouse_x < 0) mouse_x = 0; if (mouse_y < 0) mouse_y = 0; if (mouse_x > binfo->screen_x - 1) mouse_x = binfo->screen_x - 1; if (mouse_y > binfo->screen_y - 1) mouse_y = binfo->screen_y - 1; sprintf(debug_info, "(%3d, %3d)", mouse_x, mouse_y); drawstring_and_refresh(back_layer, 0, 0, COLOR8_FFFFFF, COLOR8_848484, debug_info, 10); layer_slide(mouse_layer, mouse_x, mouse_y); if (0 != (mdec.state & 0x01)) { /* down left click, move window */ layer_slide(win_layer, mouse_x - 80, mouse_y - 8); } } } else if (10 == data) { drawstring_and_refresh(back_layer, 0, 64, COLOR8_FFFFFF, COLOR8_848484, "10[sec]", 7); } else if (3 == data) { drawstring_and_refresh(back_layer, 0, 80, COLOR8_FFFFFF, COLOR8_848484, "03[sec]", 7); } else if (data <= 1) { /* timer by cursor */ if (0 != data) { timer_init(timer3, &fifo, 0); cursor_c = COLOR8_000000; } else { timer_init(timer3, &fifo, 1); cursor_c = COLOR8_FFFFFF; } timer_settimer(timer3, 50); fill_box8(win_layer->buf, win_layer->w_size, cursor_c, cursor_x, 28, cursor_x + 7, 43); layers_refresh(win_layer, cursor_x, 28, cursor_x + 8, 44); } } } }