#include #include #include int store[32768*6]; // each short cmpartment is one word, right justified int sc; // sequence control register, i.e. program counter int instr; // currently obeyed instruction int msa, lsa, msb, lsb; // most significant half of A, etc int creg, tagreg; int groupref = 0; // points to modifier group of current group (starts with group 0) i.e. T * 8 int msd, lsd, mse, lsed, msf, lsf; // internal registers, not seen by programmer - may not use int w4, w3, w2, w1; // 4 short cmps to receive results char buff[1000]; void illegal(char *s, int val); void negate(int n4, int n3, int n2, int n1) // negate the double length number in n4..n1 // also used to convert from sign and modulus // deliver the restul into w4..w1 { int c; // carry register if ( creg == 0 ) // using binary i.e. radix 16 { w1 = -n1; c = (w1>>20) & 1; w1 &= 03777777; w2 = -n2 - c; c = (w2>>20) & 1; w2 &= 03777777; w3 = -n3 - c; c = (w3>>20) & 1; w3 &= 03777777; w4 = -n4 - c; c = (w4>>20) & 1; w4 &= 03777777; } else illegal("Cannot do fancy radix yet"); } int add5(int a, int d) // add using radix in creg // carry digits are evaluated as the difference between addition and exclusive or { int aa = a + creg; // add in exces digits int r = aa + d; // raw addition int c = ((aa ^ d) ^ r) & 0x111111; // carry digits int mask = (c>>1) | (c>>2) | (c>>3) | (c>>4); // printf("\n a = %05X d = %05X\n", a, d); // printf("aa = %05X c = %05X m = %05X\n", aa, c, mask); // printf(" r = %05X\n", r); r -= creg - (creg&mask); // removes excess for those digits where there was no carry // printf("result = %05X\n", r); return r; // result is 21 bits with carry at the top } void illegal(char *s, int val) { printf("Illegal: %s [%d %o]\n", s, val, val); sc --; // back step to failing instruction printf("sc = %d instr = %d/%d/%d %d\n", sc, instr>>16, (instr>>15)&1, (instr>>13)&3, instr&017777); printf(" A = %05X %05X [%d %d]\n", msa, lsa, msa, lsa); printf(" B = %05X %05X [%d %d]\n", msb, lsb, msb, lsb); exit(1); } void notImplemented(char *s) { sprintf(buff, "Not implemented: %s", s); illegal(buff, instr>>13); } void interpret(int addr) { int a, d, m, f, n; sc = addr; while ( 1 == 1 ) { instr = store[sc++]; f = instr>>13; a = f>>3; d = (f&4) >> 2; m = f&3; // initially set the modifier number, but then then to modifier value when appropriate n = instr & 017777; printf("---> %d/%d/%d %d\n", a, d, m, n); switch (f) { *************************************************** } } } void loadprog(char *fn) { FILE *fin = fopen(fn, "r"); int sc = 160; // start loading code here printf("Loading program %s\n\n", fn); while ( fgets(buff, 999, fin) != NULL ) if ( strlen(buff) > 5 && *buff != ' ' ) { int f = atoi(buff); int n = f<<3; int i = 4; int a = 0; int m, d; while ( buff[++i] > ' ' ) ; m = atoi(buff+i-1); d = atoi(buff+i-3); n += d*4 + m; if ( buff[i] == ' ' && buff[++i] != ' ' ) // if there is an address part a = atoi(buff+i); printf("%4d %d/%d/%d %4d| %s", sc, f, d, m, a, buff); store[sc++] = (n<<13) + a; if ( m >= 4 || d >= 2 ) { printf("Error: %s", buff); exit(1); } } fclose(fin); } main(int argc, char **argv) { loadprog(argv[1]); interpret(160); }