📄 kernel.x
字号:
//*******************************************************************
//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 + -