#include #include #include #include #include typedef uint32_t word; #define MEMSIZE (1 << 16) word memory [MEMSIZE]; #define IOAREA 0x01000000 word memr (word a) { if (a >= MEMSIZE) { switch (a) { case IOAREA + 0: return getchar () & 0xFf; default: abort (); } } else return memory [a]; } void memw (word a, word w) { if (a >= MEMSIZE) { switch (a) { case IOAREA + 0: putchar (w & 0xFF); fflush (stdout); // usleep (1000); break; default: abort (); } } else memory [a] = w; } #define dprintf (void) #define NPERTICK 2000 /* [kHz] */ /* Our simulator runs at circa 800MHz */ void sim (void) { word pc = 0; word a = 0; word b; word op; uint64_t s; int zf = 0, cf = 0; int ncycle = 0; for (;;) { op = memr (pc++); dprintf ("%.8x op %.8x\n", pc-1, op); b = memr (op & 0x0FFFFFFF); dprintf ("b %.8x\n", b); switch (op >> 28) { case 0x0: a = s = (uint64_t)a + (uint64_t)b; cf = (s >> 32) & 1; zf = (a == 0); break; case 0x1: a = s = (uint64_t)a + (uint64_t)b + (uint64_t)cf; cf = (s >> 32) & 1; zf = (a == 0); break; case 0x2: a = s = (uint64_t)a - (uint64_t)b; cf = (s >> 32) & 1; zf = (a == 0); break; case 0x3: a = s = (uint64_t)a - (uint64_t)b - (uint64_t)cf; cf = (s >> 32) & 1; zf = (a == 0); break; case 0x4: a = a & b; zf = (a == 0); break; case 0x5: a = a | b; zf = (a == 0); break; case 0x6: a = a ^ b; zf = (a == 0); break; case 0x7: a = a >> 1; zf = (a == 0); break; case 0x8: pc = b; break; case 0x9: if (!zf) pc = b; break; case 0xA: if (zf) pc = b; break; case 0xB: if (cf) pc = b; break; case 0xC: a = memr (b); dprintf ("R %.8x %.8x\n", b, a); break; case 0xD: memw (b, a); dprintf ("W %.8x %.8x\n", b, a); break; case 0xE: case 0xF: exit (0); } ncycle += 3; if (ncycle > NPERTICK) { ncycle = 0; pause (); } } } int dosim (void) { FILE *f; f = fopen ("core.bin", "r"); fread (memory, 1, sizeof (memory), f); sim (); return 0; } void handler (int sig) { // printf ("a"); fflush (stdout); } int main (void) { int i; signal (SIGALRM, handler); { struct itimerval val = { { 0, 1000}, {0, 1} }; setitimer (ITIMER_REAL, &val, 0); } dosim (); return 0; }