Example #1
0
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);
	    }
	}
     }
}
Example #2
0
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);
			}
		}
	}	
}