⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kernel.x

📁 一个用自己写的编译器编译的操作系统内核. 有包含中断和不包含中断两个版本. 还有简单的用户应用程序。 因为该代码原目的是下载到硬件上使用
💻 X
📖 第 1 页 / 共 2 页
字号:
		else if (ch<='f' && ch>='a')
			value = (value | (ch-'W'));
		else if (ch<='F' && ch>='A')
			value = (value | (ch-'7'));
		else
		{
			*error = 1;
			return 0xFFFF;
		}
	}
	return value;
}

int strlen(char *s)
{
	int len;
	len = 0;
	while (s[len] != 0) len ++;
	return len;
}

int asm(int argc,char **argv)
{
	int i, j, k, code, len, value, error;
	struct TASM *p;
	char *s;
	value = get_value(argv[0],&error);
	if (error == 0)
	{
		if (strlen(argv[0]) > 4)
			return 0xFFFF;
		return value;
	}
	p = (struct TASM *)const_asm;
	for (i=0;i<asm_total;i++)
	{
		s = (*p).name;
		k = 0;
		while (k < 6 && s[k] != 0) k ++;
		if (k == strlen(argv[0]))
		{
			for (j=0;j<k;j++)
			{
				if (s[j] != argv[0][j] && (s[j]+32) != argv[0][j])
					break;
			}
			if (j == k)
				break ;
		}
		p ++;
	}
	if ((code = i) == asm_total)
		return 0xFFFF;
	code = (*p).code;
	int [3]regs;
	regs[0] = ~(*p).x;
	regs[1] = ~(*p).y;
	regs[2] = ~(*p).z;
	int reg;
	for (i=0;i<3;i++)
	{
		reg = regs[i];
		if (reg != 0)
		{
			if (argc <= i)
				return 0xFFFF;
			else s = argv[i+1];
			k = (reg & code);
			if (k == reg)
			{
				if (s[0] != 'R' && s[0] != 'r')
					return 0xFFFF;
				s ++;
			}
			if ((value = get_value(s,&error)) == 0xFFFF)
				return value;
			while ((reg & 1) == 0)
			{
				if ((value & 0x8000) != 0)
					return 0xFFFF;
				reg = (reg >> 1);
				value = (value << 1);
			}
			reg = ~regs[i];
			if ((reg & value) != 0)
				return 0xFFFF;
			code = ((code & reg) | value);
		}
		else if (argc != i+1)
			return 0xFFFF;
		else break;
	}
	return code;
}

int parse(char *buffer,char **argv)
{
	char ch;
	int i, j, argc;
	i = 0;
	while ((ch = sys_getchar()) != '\n' && i < 31)
	{
		if (ch == 8)
		{
			if (i != 0)
			{
				i --;
				sys_putchar((char)8);
				sys_putchar(' ');
				sys_putchar((char)8);
			}
		}
		else
		{
			sys_putchar(ch);
			buffer[i++] = ch;
		}
	}
	if (i == 31)
		return 0x10;			//输入过长
	argc = j = 0;
	buffer[i] = '\0';
	for (i=0;buffer[i] != '\0';i++)
	{
		if (buffer[i] != ' ')
		{
			if (j == 0)
			{
				if (argc == 8)
					return 0x20;//分段过多
				argv[argc++] = &buffer[i];
			}
			j = 1;
		}
		else
		{
			j = 0;
			buffer[i] = '\0';
		}
	}
	return argc;
}

void sys_putregs(struct Env* env)
{
	sys_puts("  env_id = ");
	sys_putchar((char)((*env).env_id+48));
	if ((*env).first_run) sys_puts("   "); else sys_puts("  R");
	if (env == curenv) sys_puts("  *"); else sys_puts("  ");
	sys_putchar('\n');
	sys_puts("  ");
	int i;
	for (i=0;i<8;i++)
	{
		sys_putchar('R');
		sys_putchar((char)(i+48));
		sys_puts(" = ");
		sys_puthex((*env).tf.regs[i]);
		sys_puts("   ");
		if (i == 3)
		{
			sys_putchar('\n');
			sys_puts("  ");
		}
	}
	sys_puts("\n  PC = ");
	sys_puthex((*env).tf.pc);
	sys_puts("   SP = ");
	sys_puthex((*env).tf.sp);
	sys_puts("   T  = ");
	sys_puthex((*env).tf.t);
	sys_putchar('\n');
}

int strcmp(char *s1,char *s2,int choose)
{
	if (strlen(s1) != strlen(s2))
		return 1;
	int i;
	for (i=0;*(s1+i)!=0;i++)
	{
		if (s1[i] != s2[i])
		{
			if (choose == 1)
			{
				if ((char)(s1[i]-32) != s2[i] && s1[i] != (char)(s2[i]-32))
					return 1;
			}
			else return 1;
		}
	}
	return 0;
}

int load_env()
{
	sys_puts("Waiting for binary code...\n");

	int code_range, code_size, begin;
	code_range = sys_gethex();
	code_size = sys_gethex();

	if (used[0] == 0)
	{
		if (env0_end-ram_begin < code_size)
		{
			while (code_size != 0)
			{
				sys_gethex();
				code_size --;
			}
			return 1;
		}
		used[0] = 1;
		env1_begin = ram_begin + code_size;
		begin = ram_begin;
		curenv = &envs[0];
		(*curenv).env_id = 0;
	}
	else
	{
		if (ram_end-env1_begin < code_size)
		{
			while (code_size != 0)
			{
				sys_gethex();
				code_size --;
			}
			return 1;
		}
		used[1] = 1;
		env0_end = ram_end - code_size;
		begin = ram_end - code_size;
		curenv = &envs[1];
		(*curenv).env_id = 1;
	}
	(*curenv).tf.pc = begin;
	(*curenv).first_run = 1;

	int i, code, regs, offset , addr, hi, lo;
	i = 0;
	addr = begin;
	while (i<code_range)
	{
		code = sys_gethex();
		if (code == 0xFFFF)
		{
			regs = sys_gethex();
			regs = (regs << 8);
			offset = sys_gethex();
			code = begin+offset;
			hi = (code >> 8);
			lo = (code & 0xFF);
			if ((lo & 0x80) != 0)
				hi ++;
			*(int *)addr = (hi | 0x6800 | regs);
			addr ++;		
			*(int *)addr = (regs | (regs >> 3) | 0x3000);
			addr ++;
			*(int *)addr = (lo | 0x4800 | regs);
			i = i+2;
		}
		else *(int *)addr = code;
		addr ++;
		i ++;
	}
	while (i<code_size)
	{
		code = sys_gethex();
		*(int *)addr = code;
		addr ++;
		i ++;
	}
	
	total_env ++;

	sys_puts("\nenv id   : "); sys_puthex((*curenv).env_id);
	sys_puts("\n");

	return 0;
}

int del_env(int id)
{
	if (id > 1 || used[id] == 0)
	{
		return 0;
	}
	total_env --;
	used[id] = 0;
	if (total_env == 0)
	{
		env0_end = ram_end;
		env1_begin = ram_begin;
		curenv = null;
	}
	else
	{
		if (id == 0) 
		{
			env1_begin = ram_begin;
			curenv = &envs[1];
		}
		else 
		{
			env0_end = ram_end;
			curenv = &envs[0];
		}
	}
	return 1;
}

void sys_command()
{
	int code;
	char [32]buffer;
	char *[8]argv;
	int argc, addr, var, i, j, error;
	addr = 1;
	char ch;
	while (1)
	{
		sys_puts(">>");
		argc = parse(buffer,argv);
		if (argc != 0)
		{
			if (strlen(argv[0]) == 1)
			{
				ch = argv[0][0];
				if (ch <= 'z' && ch >= 'a')
					ch = (char)(ch-32);
				if (ch == 'S')
				{
					if (curenv != null)
					{
						if (argc >= 3)
						{
							var = get_value(argv[2],&error);
							if (error == 0)
							{
								if (argv[1][0] == 'R' || argv[1][0] == 'r')
								{
									if ((j = get_value(&argv[1][1],&error)) >= 8)
										sys_puts("  Unknown argument.\n");
									else (*curenv).tf.regs[j] = var;
								}
								else if (strcmp(argv[1],"sp",1) == 0)
									(*curenv).tf.sp = var;
								else if (strcmp(argv[1],"pc",1) == 0)
									(*curenv).tf.pc = var;
								else sys_puts("  Unknown argument.\n");
							}
							else sys_puts("  Unknown argument.\n");
						}
						else sys_puts("  Not enough arguments.\n");
					}
					else sys_puts("  curenv == null\n");					
				}
				else if (argc == 1 || (addr = get_value(argv[1],&error)) != 0xFFFF)
				{
					if (ch == 'A')
					{		
						while (argc != 0)
						{
							sys_puts("  [");
							sys_puthex(addr);
							sys_puts("] ");
							argc = parse(buffer,argv);
							if (argc != 0)
							{
								code = asm(argc,argv);
								if (code != 0xFFFF)
								{
									*(int *)addr = code;
									addr ++;
								}
							}
						}
						sys_putchar('\n');
					}				
					else if (ch == 'U')
					{
						if (argc <= 2 ||  (var = get_value(argv[2],&error)) < 10)
							var = 10;
						for (i=0;i<var;i++)
						{
							sys_puts("  [");
							sys_puthex(addr);
							sys_puts("] ");
							uasm(*(int *)addr);
							addr ++;
						}
					}
					else if (ch == 'G')
					{
						if (curenv != null) env_run(curenv);
						else sys_puts("  curenv == null\n");
					}
					else if (ch == 'R')
					{
						if (used[0]) sys_putregs(&envs[0]);
						if (used[1]) sys_putregs(&envs[1]);
						if (!used[0] && !used[1])
						{
							sys_puts("  no envs available.\n");
						}
					}
					else if (ch == 'D')
					{
						if (argc >= 2)
						{
							var = get_value(argv[1], &error);
							if (error == 0)
							{
								if (del_env(var)) sys_puts("  deletion operation successful.\n");
								else sys_puts("  env to delete does not exist.\n");
							}
							else sys_puts("  Unknown argument.\n");
						}
						else sys_puts("  Not enough arguments.\n");
					}
					else if (ch == 'T')
					{
						if (curenv == null) sys_puts("  curenv == null\n");
						else
						{
							recovery_addr_jump = 0; recovery_addr = (*curenv).tf.pc;
							code = * (int *) (recovery_addr ++);
							if ((code & 0xf800) == 0x1000)												// B
								if ((code & 0x7ff) <= 0x3ff) recovery_addr_jump = (code & 0x7ff) + recovery_addr;
								else recovery_addr_jump = (code & 0x7ff) + recovery_addr - 0x800;
							else if ((code & 0xfe00) == 0x6000 || (code & 0xf000) == 0x2000)			//	BTEQZ, BTNEZ, BEQZ, BNEZ
								if ((code & 0xff) <= 0x7f) recovery_addr_jump = (code & 0xff) + recovery_addr;
								else recovery_addr_jump = (code & 0xff) + recovery_addr - 0x100;
							else if ((code & 0xe8ff) == 0xe800)
								recovery_addr_jump = (*curenv).tf.regs[(code >> 8) & 7];
							if (recovery_addr_jump) 
							{
								recovery_addr ++;
								recovery_data_jump = * (int *) recovery_addr_jump;
								* (int *) recovery_addr_jump = (0xf800 | OS_debug_inter);				// INT : 111110000000XXXX
							}
							recovery_data = * (int *) recovery_addr;
							* (int *) recovery_addr = (0xf800 | OS_debug_inter);						// INT : 111110000000XXXX
							env_run(curenv);
						}
					}
					else if (ch == 'C')
					{
						if (total_env == 2) curenv = &envs[(*curenv).env_id ^ 1];
						if (used[0]) sys_putregs(&envs[0]);
						if (used[1]) sys_putregs(&envs[1]);
						if (!used[0] && !used[1])
						{
							sys_puts("  no envs available.\n");
						}
					}
					else sys_puts("  Unknown command.\n");
				}
			}
			else if (strcmp(argv[0],"load",1) == 0)
			{
				if (total_env == 2)
					sys_puts("  Too many envs.\n");
				else
				{
					if (load_env())
					{
						sys_puts("  Not enough memory.\n");
					}
				}
			}
			else sys_puts("  Unknown command.\n");
		}
	}
}

int main ()
{
	//串口初始化
	*(int *)0x6001 = 0x4E;
	*(int *)0x6001 = 0x37;
	*(int *)0x6003 = 0x4E;
	*(int *)0x6003 = 0x37;
	sys_puts("Welcome to Xaser kernel 0.5.0 [2008/6/1] designed for mips16e CPU.\n");
	sys_puts("Debug mode = ");
	if (sys_getchar() == '1') debug_mode = 1; else debug_mode = 0;
	sys_puthex(debug_mode);
	sys_putchar('\n');
	init();
	sys_command();
	while (1);
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -