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

📄 kernel.x

📁 一个用自己写的编译器编译的操作系统内核. 有包含中断和不包含中断两个版本. 还有简单的用户应用程序。 因为该代码原目的是下载到硬件上使用
💻 X
📖 第 1 页 / 共 2 页
字号:
//*******************************************************************
//output
void sys_putchar(char c)
{
	while (((*(int *)0x6001) & 1) == 0);
	*(int *)0x6000 = (int )c;
}

void sys_puts(char *s)
{
	int i;
	for (i=0;*(s+i)!=0;i++)
		sys_putchar(s[i]);
}

void sys_puthex(int num)
{
	int i,j;
	for (i=0;i<4;i++)
	{
		j = ((num & 0xF000) >> 12);
		num = (num << 4);
		if (j < 10)
			sys_putchar((char)(j+48));
		else sys_putchar((char)(j+55));
	}
}

//*******************************************************************
//input
char sys_getchar()
{
	char ch;
	while (((*(int *)0x6001) & 2) == 0);
	ch = (char)((*(int *)0x6000) & 0xFF);
	if (ch == (char)10)
		sys_putchar(ch);
	return ch;
}

char sys_get8bit()
{
	char ch;
	while (((*(int *)0x6001) & 2) == 0);
	ch = (char)((*(int *)0x6000) & 0xFF);
	return ch;
}

int sys_gethex()
{
	int num;
	char ch;
	ch = sys_get8bit();
	num = (ch << 8);
	ch = sys_get8bit();
	num = (num | ch);
	return num;
}

//*******************************************************************
//decode

int *const_asm;
const int asm_total = 48;
const int clock_inter = 0x20;
const int hard_inter  = 0x10;
const int OS_func_inter = 0x3;
const int OS_debug_inter = 0x5;
struct TASM
{
	char [6]name;
	int code;
	int x,y,z;
};


struct Tf
{
	int t;
	int hi;
	int lo;
	int sp;
	int ra;
	int [8]regs;
	int intno;
	int pc;
};

struct Env
{
	struct Tf tf;
	int env_id;
	int first_run;
};

const int env_limit = 2;
struct Env *curenv;
struct Env [2]envs;
int curenv_id;
int total_env;
void* trap_entry_addr, interrupt_handler_addr;
int recovery_addr, recovery_data, recovery_addr_jump, recovery_data_jump;
int debug_mode;

//sys_command
void sys_command();
int del_env(int id);
void uasm(int code);
void sys_yield();

void env_run(struct Env *env)
{
	curenv = env;

	if (!(*curenv).first_run)
	{
		int sp; sp = (*curenv).tf.sp;
		* (struct Tf *)(sp - 15) = (*curenv).tf;
		int pc;
		%asm{
			%writereg("r0", trap_entry_addr);
			%asm("LI", "r1", "0x80");
			%asm("SLL", "r1", "r1", "0");
			%asm("OR", "r0", "r1");
			%asm("MTIH", "r0");
			%writereg("r0", sp);
			%asm("MTSP", "r0");
			%asm("LI", "r0", "0");
			%asm("LW-SP", "r1", "-15");
			%asm("SLT", "r0", "r1");
			%asm("LW-SP", "r0", "-10");
			%asm("LW-SP", "r1", "-9");
			%asm("LW-SP", "r2", "-8");
			%asm("LW-SP", "r3", "-7");
			%asm("LW-SP", "r4", "-6");
			%asm("LW-SP", "r5", "-5");
			%asm("LW-SP", "r6", "-4");
			%asm("LW-SP", "r7", "-3");
			%asm("SW-SP", "r0", "-2");
			%asm("LW-SP", "r0", "-1");
			%asm("JR", "r0");
			%asm("LW-SP", "r0", "-2");
		};
	}
	else
	{
		(*curenv).first_run = 0;
		int pc; pc = (*curenv).tf.pc;
		%asm {
			%writereg("r0", trap_entry_addr);
			%asm("LI", "r1", "0x80");
			%asm("SLL", "r1", "r1", "0");
			%asm("OR", "r0", "r1");
			%asm("MTIH", "r0");
			%writereg("r0", pc);
			%asm("JR", "r0");
			%asm("NOP");
		};
	}
}

//sys_command
void sys_command();
int del_env(int id);
void uasm(int code);
void sys_putregs(struct Env* env);

void sys_yield()
{
	if (total_env == 0)
	{
		sys_puts("\nBack to kernel monitor.\n");
		sys_command();
	}
	else if (total_env == 1)
	{
		env_run(curenv);
	}
	else
	{
		if (curenv == &envs[0]) env_run(&envs[1]);
		else env_run(&envs[0]);
	}
}

void trap_entry()
{
	%asm {
		%asm("MTSP", "r7");
		%asm("ADDIU", "r7", "3");
		%asm("ADDSP", "-12");
		%asm("SW-SP", "r6", "11");
		%asm("SW-SP", "r5", "10");
		%asm("SW-SP", "r4", "9");
		%asm("SW-SP", "r3", "8");
		%asm("SW-SP", "r2", "7");
		%asm("SW-SP", "r1", "6");
		%asm("SW-SP", "r0", "5");
		%asm("LI", "r0", "0");
		%asm("MTIH", "r0");
		%asm("BTEQZ", "2");
		%asm("NOP");
		%asm("LI", "r0", "1");
		%asm("SW-SP", "r0", "0");
		%asm("SW-SP", "r7", "3");

		%writereg("r3", interrupt_handler_addr);
		%asm("ADDSP3", "r0", "0");
		%asm("MOVE", "r1", "r2");
		%asm("SRL", "r2", "r1", "0");
		%asm("SLTUI", "r2", "29");
		%asm("BTEQZ", "7");
		%asm("NOP");
		%asm("LI", "r1", "0x27");
		%asm("SLL", "r1", "r1", "0");
		%asm("B", "2");
		%asm("NOP");
		%asm("ADDIU", "r1", "-30");
		%asm("MTSP", "r1");
		%asm("LW", "r0", "r1", "0");
		%asm("SW-SP", "r1", "0");
		%asm("LW", "r0", "r1", "1");
		%asm("SW-SP", "r1", "1");
		%asm("LW", "r0", "r1", "2");
		%asm("SW-SP", "r1", "2");
		%asm("LW", "r0", "r1", "3");
		%asm("SW-SP", "r1", "3");
		%asm("LW", "r0", "r1", "4");
		%asm("SW-SP", "r1", "4");
		%asm("LW", "r0", "r1", "5");
		%asm("SW-SP", "r1", "5");
		%asm("LW", "r0", "r1", "6");
		%asm("SW-SP", "r1", "6");
		%asm("LW", "r0", "r1", "7");
		%asm("SW-SP", "r1", "7");
		%asm("LW", "r0", "r1", "8");
		%asm("SW-SP", "r1", "8");
		%asm("LW", "r0", "r1", "9");
		%asm("SW-SP", "r1", "9");
		%asm("LW", "r0", "r1", "10");
		%asm("SW-SP", "r1", "10");
		%asm("LW", "r0", "r1", "11");
		%asm("SW-SP", "r1", "11");
		%asm("LW", "r0", "r1", "12");
		%asm("SW-SP", "r1", "12");
		%asm("LW", "r0", "r1", "13");
		%asm("SW-SP", "r1", "13");
		%asm("LW", "r0", "r1", "14");
		%asm("SW-SP", "r1", "14");

		%asm("ADDSP", "-2");

		%asm("JR", "r3");
		%asm("NOP");
	};
}

void interrupt_handler(struct Tf tf)
{
//	sys_puts("get in: ");
//	sys_puthex(tf.sp);
//	sys_puts("\n");
	(*curenv).tf = tf;
//	sys_puthex((*curenv).tf.pc);
//	sys_puts("\n");
	if (debug_mode)
	{
		sys_puts("Trap frame:\n");
		sys_putregs(curenv);
		sys_puts("NO  = "); sys_puthex(tf.intno); 
		sys_puts("\n"); 
	}
	if (tf.intno == clock_inter) sys_yield();
	else if (tf.intno == hard_inter)
	{
		sys_puts("\nBack to kernel monitor.\n");
		sys_command();
	}
	else if (tf.intno == OS_func_inter)
	{
		int port;
		port = (*curenv).env_id << 1;
		if (tf.regs[0] == 0)
		{
			sys_puts("env "); sys_puthex((*curenv).env_id); sys_puts(" exited with code 0x"); sys_puthex(tf.regs[2]);
			del_env((*curenv).env_id);
			sys_yield();
		}
		else if (tf.regs[0] <= 2)
		{
			if (tf.regs[0] == 1)
			{
				if ((*(int *)(0x6001 + port)) & 1)
				{
					*(int *)(0x6000 + port) = tf.regs[2];
					(*curenv).tf.regs[1] = 0;
					sys_yield();
				}
			}
			else
			{
				if ((*(int *)(0x6001 + port)) & 2)
				{
					(*curenv).tf.regs[2] = (*(int *)(0x6000 + port) & 0xff);
					(*curenv).tf.regs[1] = 0;
					sys_yield();
				}
			}
			(*curenv).tf.regs[1] = 1;
			sys_yield();
		}
	}
	else if (tf.intno == OS_debug_inter)
	{
		tf.pc --;
		(*curenv).tf.pc --;
		* (int *) recovery_addr = recovery_data;
		if (recovery_addr_jump) * (int *) recovery_addr_jump = recovery_data_jump;
		sys_puts("  ["); sys_puthex(tf.pc); sys_puts("] ");
		uasm(*(int *)tf.pc);
		sys_command();
	}
	else 
	{
		sys_puts("\nUnknown interrupt: "); sys_puthex(tf.intno); sys_puts("\n");
		sys_command();
	}
}

const int ram_begin = 0x4000;
const int ram_end = 0x6000;
int [2]used;
int env0_end;
int env1_begin;


void init()
{
	%asm {
		%asm("LI", "r0", "0");
		%asm("MTIH", "r0");
	};
	curenv = null;
	total_env = 0;
	envs[0].env_id = envs[1].env_id = 0;
	const_asm = <			65,68,68,83,80,51,1793,63743,65280,65535,
							66,0,0,0,0,0,4096,63488,65535,65535,
							66,69,81,90,0,0,9984,63743,65280,65535,
							66,78,69,90,0,0,12032,63743,65280,65535,
							83,76,76,0,0,0,14308,63743,65311,65507,
							83,82,76,0,0,0,14310,63743,65311,65507,
							83,82,65,0,0,0,14311,63743,65311,65507,
							65,68,68,73,85,51,18400,63743,65311,65520,
							65,68,68,73,85,0,20224,63743,65280,65535,
							83,76,84,73,0,0,22272,63743,65280,65535,
							83,76,84,85,73,0,24321,63743,65280,65535,
							66,84,69,81,90,0,24576,65280,65535,65535,
							66,84,78,69,90,0,24832,65280,65535,65535,
							83,87,45,82,83,0,25089,65280,65535,65535,
							65,68,68,83,80,0,25344,65280,65535,65535,
							77,84,83,80,0,0,25824,65311,65535,65535,
							77,79,86,69,0,0,26599,65311,65528,65535,
							76,73,0,0,0,0,28417,63743,65280,65535,
							67,77,80,73,0,0,30465,63743,65280,65535,
							76,87,45,83,80,0,38657,63743,65280,65535,
							76,87,0,0,0,0,40929,63743,65311,65504,
							83,87,45,83,80,0,55041,63743,65280,65535,
							83,87,0,0,0,0,57313,63743,65311,65504,
							65,68,68,85,0,0,59389,63743,65311,65507,
							83,85,66,85,0,0,59391,63743,65311,65507,
							74,82,0,0,0,0,61184,63743,65535,65535,
							77,70,72,73,0,0,61200,63743,65535,65535,
							77,70,76,79,0,0,61202,63743,65535,65535,
							77,70,80,67,0,0,61248,63743,65535,65535,
							83,76,84,0,0,0,61410,63743,65311,65535,
							83,76,84,85,0,0,61411,63743,65311,65535,
							83,76,76,86,0,0,61412,63743,65311,65535,
							83,82,76,86,0,0,61414,63743,65311,65535,
							83,82,65,86,0,0,61415,63743,65311,65535,
							67,77,80,0,0,0,61418,63743,65311,65535,
							78,69,71,0,0,0,61419,63743,65311,65535,
							65,78,68,0,0,0,61420,63743,65311,65535,
							79,82,0,0,0,0,61421,63743,65311,65535,
							88,79,82,0,0,0,61422,63743,65311,65535,
							78,79,84,0,0,0,61423,63743,65311,65535,
							77,85,76,84,0,0,61432,63743,65311,65535,
							77,85,76,84,85,0,61433,63743,65311,65535,
							68,73,86,0,0,0,61434,63743,65311,65535,
							68,73,86,85,0,0,61435,63743,65311,65535,
							78,79,80,0,0,0,2048,65535,65535,65535,
							73,78,84,0,0,0,63489,65520,65535,65535,
							77,70,73,72,0,0,63232,63743,65535,65535,
							77,84,73,72,0,0,63233,63743,65535,65535
		>;

		used[0] = 0;
		used[1] = 0;
		env0_end = ram_end;
		env1_begin = ram_end;
		trap_entry_addr = (void *) trap_entry;
		interrupt_handler_addr = (void *) interrupt_handler;
}

//*******************************************************************
//uasm
void uasm(int code)
{
	struct TASM *p;
	p = (struct TASM *)const_asm;
	int i, j, k;
	for (i=0;i<asm_total;i++)
	{
		j = ((*p).code & (*p).x & (*p).y & (*p).z); 
		k = (code & (*p).x & (*p).y & (*p).z);
		if (j == k)
			break;
		p ++;
	}
	sys_puts("  <");
	sys_puthex(code);
	sys_puts("> ");
	if (i == asm_total)
	{
		sys_puts(" --- UNKNOWN ---\n");
		return ;
	}
	char *name;
	name = (*p).name;
	for (i=0;i<6 && name[i]!=0;i++)
		sys_putchar(name[i]);
	int [3]regs;
	int num;
	regs[0] = ~(*p).x;
	regs[1] = ~(*p).y;
	regs[2] = ~(*p).z;
	for (i=0;i<3;i++)
	{
		if (regs[i] != 0)
		{
			k = (regs[i] & (*p).code);
			num = (regs[i] & code);
			if (regs[i] == k)
			{
				sys_puts(" R");
				while ((regs[i] & 1) == 0)
				{
					num = (num >> 1);
					regs[i] = (regs[i] >> 1);
				}
				sys_putchar((char)(num+48));
			}
			else if (k == 0)
			{
				sys_putchar(' ');
				while ((regs[i] & 1) == 0)
				{
					num = (num >> 1);
					regs[i] = (regs[i] >> 1);
				}
				j = ~regs[i];
				if ((num & (j >> 1)) != 0)
					num = (num | j);
				sys_puthex(num);
			}
			else
			{
				sys_putchar(' ');
				while ((regs[i] & 1) == 0)
				{
					num = (num >> 1);
					regs[i] = (regs[i] >> 1);
				}
				sys_puthex(num);
			}
		}
	}
	sys_putchar('\n');
}

int get_value(char *s,int *error)
{
	if (s[0] == 0)
	{
		*error = 1;
		return 0xFFFF;
	}
	int i, value;
	value = 0;
	char ch;
	*error = 0;
	for (i=0;*(s+i)!=0;i++)
	{
		ch = s[i];
		value = (value << 4);
		if (ch<='9' && ch>='0')
			value = (value | (ch-'0'));

⌨️ 快捷键说明

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