ref: 000040ac39bcca98a50c39ca04964ec338f112fd
dir: /5552e.c/
/* 5552 cpu emulator */
#include "5552.h"
struct mach
{
word reg[REGS];
/* both are nibbles currently, but for convience */
word op;
word mode;
word arg1;
word arg2;
byte mem[MMAX];
};
/*
int
btoi(int b[], int len)
{
char arr[10];
int res = 0, i = 0, j = len;
while (i <= len)
{
arr[i] = b[j] ? '1' : '0';
i++;
j--;
}
sscanf(arr, "%d", &res);
return res;
}
*/
int
mach_drd(word dev, word src, word dst)
{
switch(dev)
{
case REG:
regs[dst] = regs[src];
break;
case MEM:
regs[dst] = mem[src];
break;
case GPIO:
switch(src)
{
case SERIAL:
read(0, regs+dst, sizeof(Word));
break;
default:
break;
}
default:
break;
}
}
int
mach_dwr(word dev, word src, word dst)
{
switch(dev)
{
case REG:
regs[src] = regs[dst];
break;
case MEM:
regs[src] = mem[dst];
break;
case GPIO:
switch(dst)
{
case SERIAL:
write(0, regs+src, sizeof(Word));
break;
default:
break;
}
default:
break;
}
}
int
mach_dwr(word dev, word src, word dst)
{
switch(dev)
{
case REG:
regs[src] = regs[dst];
break;
case MEM:
regs[src] = mem[dst];
break;
case GPIO:
switch(dst)
{
case SERIAL:
write(0, regs+src, sizeof(Word));
break;
default:
break;
}
default:
break;
}
}
int
mach_not(word mode, word arg1, word arg2)
{
switch(mode)
{
case REG:
regs[RES] = ~regs[arg1];
break;
case INLINE:
regs[RES] = ~((arg1 << (sizeof Word) * 8) & arg2);
break;
case DIRECT:
default:
break;
}
}
int
mach_and(Word mode, Word arg1, Word arg2)
{
switch(mode)
{
case REG:
regs[RES] = regs[arg1] & regs[arg2];
break;
case INLINE:
regs[RES] = arg1 & arg2;
break;
case DIRECT:
regs[RES] = regs[arg1] & arg2;
break;
default:
break;
}
}
int
mach_nor(Word mode, Word arg1, Word arg2)
{
switch(mode)
{
case REG:
regs[RES] = !(regs[arg1] | regs[arg2]);
break;
case INLINE:
regs[RES] = !(arg1 | arg2);
break;
case DIRECT:
regs[RES] = !(regs[arg1] & arg2);
break;
default:
break;
}
}
int
mach_xor(Word mode, Word arg1, Word arg2)
{
switch(mode)
{
case REG:
regs[RES] = regs[arg1] ^ regs[arg2];
break;
case INLINE:
regs[RES] = arg1 ^ arg2;
break;
case DIRECT:
regs[RES] = regs[arg1] ^ arg2;
break;
default:
break;
}
}
int
mach_add(Word mode, Word arg1, Word arg2)
{
int result;
switch(mode)
{
case REG:
result = (int)regs[arg1] + (int)regs[arg2];
break;
case INLINE:
result = (int)arg1 + (int)arg2;
break;
case DIRECT:
result = (int)regs[arg1] + (int)arg2;
break;
default:
break;
}
if(intsize(result) > sizeof Word)
regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
regs[RES] = (Word)result;
}
int
mach_sub(Word mode, Word arg1, Word arg2)
{
int result;
switch(mode)
{
case REG:
result = (int)regs[arg1] - (int)regs[arg2];
break;
case INLINE:
result = (int)arg1 - (int)arg2;
break;
case DIRECT:
result = (int)regs[arg1] - (int)arg2;
break;
default:
break;
}
if(intsize(result) > sizeof Word * 8)
regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
regs[RES] = (Word)result;
}
int
mach_mul(Word mode, Word arg1, Word arg2)
{
int result;
switch(mode)
{
case REG:
result = (int)regs[arg1] * (int)regs[arg2];
break;
case INLINE:
result = (int)arg1 * (int)arg2;
break;
case DIRECT:
result = (int)regs[arg1] * (int)arg2;
break;
default:
break;
}
if(intsize(result) > sizeof Word * 8)
regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
regs[RES] = (Word)result;
}
int
mach_div(Word mode, Word arg1, Word arg2)
{
int result;
switch(mode)
{
case REG:
result = (int)regs[arg1] / (int)regs[arg2];
break;
case INLINE:
result = (int)arg1 / (int)arg2;
break;
case DIRECT:
result = (int)regs[arg1] / (int)arg2;
break;
default:
break;
}
regs[RES] = (Word)result;
}
int
mach_mul(Word mode, Word arg1, Word arg2)
{
int result;
switch(mode)
{
case REG:
result = (int)regs[arg1] * (int)regs[arg2];
break;
case INLINE:
result = (int)arg1 * (int)arg2;
break;
case DIRECT:
result = (int)regs[arg1] * (int)arg2;
break;
default:
break;
}
if(intsize(result) > sizeof Word * 8)
regs[CRR] = (Word)(result % 2 << (sizeof Word * 8));
regs[RES] = (Word)result;
}
void
main(void)
{
char *input;
void *buf;
int arg, prev;
input = malloc(OPLEN);
if(input < 0)
panic("Not enough memory\n");
mach.reg[STATE] = ON;
while(mach.state == ON)
{
if(read(1, buf, 3) < 3)
{
panic("EOF?\n");
}
mach.op = buf[0] >> 4;
mach.mode = buf[0] & (1 << 4) - 1;
mach.arg1 = buf[1];
mach.arg2 = buf[2];
for(int i = 0; i < sizeof(optab) ; i++)
{
if(mach.op == operators[i].op)
{
operators[i].exec(mach.mode, mach.arg1, mach.arg2);
break;
}
}
}
}
int
main(void)
{
char string[16];
r.flags[ON] = 1;
r.flags[NSIGN] = false;
unsigned int op, a, b, c, ind = 0;
bool barr[10];
/* there is no space between op and args
since some can have no args */
while(r.flags[ON] && scanf("%u %[^\n]", &op, string))
{
sscanf(string, "%u %u %u", &a, &b, &c);
switch(op)
{
case DIE:
r.flags[ON] = 0;
break;
case OUT:
/* just in case output is "manfi" */
if(r.flags[NSIGN])
printf("-%u\n", r.regs[a]);
else
printf("%u\n", r.regs[a]);
break;
case NOT:
r.regs[b] = !a;
break;
case AND:
r.regs[c] = a & b;
break;
case NOR:
r.regs[c] = !(a | b);
break;
case XOR:
r.regs[c] = a ^ b;
break;
case SUB:
b = ~b;
r.regs[CARRY] = 1;
r.flags[NSIGN] = (a < b);
r.regs[c] = r.flags[NSIGN] ? b - a : a - b;
case ADD:
r.flags[NSIGN] = false;
r.regs[c] = a + b;
break;
r.flags[NSIGN] = false;
r.regs[b] = a + 1;
break;
case DEC:
r.regs[b] = a - 1;
r.flags[NSIGN] = (r.regs[b] < 0);
break;
case SHR:
r.regs[c] = a >> b;
break;
case SHL:
r.regs[c] = a << b;
break;
case PUT:
memory[b] = a;
case MOV:
memory[b] = r.regs[a];
break;
case LDM:
r.regs[b] = memory[a];
break;
case NTH:
r.regs[c] = a >> b;
break;
default:
fprintf(stderr, "unknown op\n");
return 1;
}
/* clear them */
a = 0;
b = 0;
op = 0;
string[0] = '\0';
}
return 0;
}