#include #include #include #include #include #include #include #include #define nil NULL void panic(char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); va_end(ap); exit(1); } FILE* mustopen(const char *name, const char *mode) { FILE *f; if(f = fopen(name, mode), f == nil) panic("couldn't open file: %s", name); return f; } int hasinput(int fd) { fd_set fds; struct timeval timeout; if(fd < 0) return 0; timeout.tv_sec = 0; timeout.tv_usec = 0; FD_ZERO(&fds); FD_SET(fd, &fds); return select(fd+1, &fds, NULL, NULL, &timeout) > 0; } typedef struct Flexowriter Flexowriter; struct Flexowriter { int in, out; }; void putfl(Flexowriter *fl, int c) { char cc; cc = c & 077; write(fl->out, &cc, 1); } int getfl(Flexowriter *fl) { char c; read(fl->in, &c, 1); return c; } typedef uint32_t word; typedef struct TX0 TX0; #define MEMSZ 0200000 #define AMSK 0177777 struct TX0 { int ss; int ios; int pbs; int dev; int c; word ac; word lr; word mbr; word mar; word pc, prevpc; word ir; word core[MEMSZ]; word tbr; word tac; Flexowriter *fl; }; static void pstate(TX0 *tx) { printf("%06o: AC/%06o LR/%06o PC/%06o\n", tx->prevpc, tx->ac, tx->lr, tx->pc); printf(" 01/%06o 02/%06o rsp/%06o psp/%06o\n", tx->core[01], tx->core[02], tx->core[057], tx->core[0117]); /* printf(" 10/%06o 11/%06o 12/%06o 13/%06o\n", tx->core[010], tx->core[011], tx->core[012], tx->core[013]); */ } static word readcore(TX0 *tx) { tx->mbr = tx->core[tx->mar] & 0777777; return tx->mbr; } static void writecore(TX0 *tx) { tx->core[tx->mar] = tx->mbr & 0777777; } static void step(TX0 *tx) { word mbr_t; tx->mbr = 0; if(tx->c == 0){ tx->prevpc = tx->mar; readcore(tx); tx->pc = 0; tx->ir = tx->mbr>>16; tx->pc = tx->mar+1 & AMSK; tx->mar = tx->mbr & AMSK; switch(tx->ir){ case 0: case 1: tx->c = 1; break; case 2: if((tx->ac & 0400000) == 0) tx->c = 1; break; case 3: // opr // 0.8 if(tx->mar & 0100000) tx->ac &= 0000777; if(tx->mar & 0040000) tx->ac &= 0777000; if((tx->mar & 0030000) == 0020000){ // IO stop tx->ss = 0; tx->ios = 0; tx->dev = tx->mar>>9 & 7; } tx->c = 1; break; } }else{ switch(tx->ir){ case 0: // sto tx->mbr = tx->ac; writecore(tx); break; case 1: // add readcore(tx); tx->ac ^= tx->mbr; tx->ac += (~tx->ac & tx->mbr)<<1; if(tx->ac & 01000000) tx->ac += 1; tx->ac &= 0777777; break; case 2: // trn - branch not taken break; case 3: // opr // 1.1 if((tx->mar & 0104) == 0004) tx->ac |= tx->tac; if((tx->mar & 0104) == 0100) ; // TODO: pen // 1.2 if(tx->mar & 1) tx->mbr |= tx->mar & 2 ? tx->tbr : tx->ac; if(tx->mar & 040) tx->ac = ~tx->ac & 0777777; // 1.3 mbr_t = tx->mbr; if((tx->mar & 3) == 2) tx->mbr = tx->lr; if((tx->mar & 0600) == 0200) tx->lr = mbr_t; // 1.4 if(tx->mar & 020) tx->ac ^= tx->mbr; else if((tx->mar & 0600) == 0400) tx->ac = tx->ac>>1 | tx->ac&0400000; else if((tx->mar & 0600) == 0600) tx->ac = (tx->ac>>1 | tx->ac<<17) & 0777777; // 1.6 if((tx->mar & 0030000) == 0030000) tx->pbs = 0; // halt // 1.7 if(tx->mar & 010){ tx->ac += (~tx->ac & tx->mbr)<<1; if(tx->ac & 01000000) tx->ac += 1; tx->ac &= 0777777; } break; } tx->mar = tx->pc; tx->c = 0; // pstate(tx); } if(tx->pbs == 0) tx->ss = 0; // handle IO if(tx->ss == 0){ if(tx->ios == 0){ int c; switch(tx->dev){ case 0: break; case 1: case 2: case 3: case 4: // pnt c = 0; if(tx->ac & 0000001) c |= 1; if(tx->ac & 0000010) c |= 2; if(tx->ac & 0000100) c |= 4; if(tx->ac & 0001000) c |= 010; if(tx->ac & 0010000) c |= 020; if(tx->ac & 0100000) c |= 040; putfl(tx->fl, c); tx->ios = 1; break; case 5: case 6: case 7: break; } if(tx->pbs == 0) tx->ss = 0; }else tx->ss = tx->pbs; } // sleep(1); } void readmem(TX0 *tx, FILE *f) { char buf[100], *s; word a, w; a = 0; while(s = fgets(buf, 100, f)){ while(*s){ if(*s == ';') break; else if('0' <= *s && *s <= '7'){ w = strtol(s, &s, 8); if(*s == ':'){ a = w; s++; }else if(a < MEMSZ) tx->core[a++] = w & 0777777; }else s++; } } } void printmem(TX0 *tx) { word a; for(a = 0; a < MEMSZ; a++) if(tx->core[a]) printf("%06o/%06o\n", a, tx->core[a]); } TX0 tx0; Flexowriter fl; int main() { FILE *mf; memset(&fl, 0, sizeof(fl)); fl.in = open("/tmp/fl", O_RDWR); if(fl.in < 0) panic("can't open /tmp/fl"); fl.out = fl.in; memset(&tx0, 0, sizeof(tx0)); tx0.pbs = 1; tx0.fl = &fl; tx0.mar = tx0.pc = 040; mf = mustopen("out.mem", "r"); readmem(&tx0, mf); fclose(mf); printmem(&tx0); printf("\n\n"); tx0.ss = 1; while(tx0.ss){ step(&tx0); if(hasinput(tx0.fl->in)){ int c; c = getfl(tx0.fl); tx0.lr = 0400000; if(c & 001) tx0.lr |= 0000001; if(c & 002) tx0.lr |= 0000010; if(c & 004) tx0.lr |= 0000100; if(c & 010) tx0.lr |= 0001000; if(c & 020) tx0.lr |= 0010000; if(c & 040) tx0.lr |= 0100000; } } printmem(&tx0); pstate(&tx0); return 0; }