diff --git a/emu/Makefile b/emu/Makefile index ad732d9..23da7ad 100644 --- a/emu/Makefile +++ b/emu/Makefile @@ -1,4 +1,4 @@ -SRC=main.c cmd.c apr.c mem.c tty.c pt.c ../tools/pdp6common.c +SRC=main.c cmd.c apr.c mem.c tty.c pt.c dc.c ../tools/pdp6common.c H=pdp6.h ../tools/pdp6common.h # clang #CFLAGS= -Wno-shift-op-parentheses -Wno-logical-op-parentheses \ diff --git a/emu/cmd.c b/emu/cmd.c index c154809..75b0023 100644 --- a/emu/cmd.c +++ b/emu/cmd.c @@ -210,6 +210,7 @@ DevDef definitions[] = { { TTY_IDENT, maketty }, { PTR_IDENT, makeptr }, { PTP_IDENT, makeptp }, + { DC_IDENT, makedc }, { nil, nil } }; diff --git a/emu/dc.c b/emu/dc.c new file mode 100644 index 0000000..ef36b14 --- /dev/null +++ b/emu/dc.c @@ -0,0 +1,238 @@ +#include "pdp6.h" + +char *dc_ident = DC_IDENT; + +/* table from DC1: + * bits per char ch mode shifts per char chars per word + * 6 0 0 0 6 + * 12 1 0 2 3 + * 18 1 1 3 2 + * 36 0 1 0 1 + */ +#define NSHIFT ((0x70 >> (dc->ch_mode*2)) & 03) +#define NCHARS ((02316 >> (dc->ch_mode*3)) & 07) +#define DC_SCT_DONE (dc->sct == NSHIFT) +#define DC_CCT_DONE (dc->cct == NCHARS-1) +//#define DC_CCT_CONT (DC_SCT_DONE && !(DC_CCT_DONE)) +//#define DC_SCT_CONT (!(DC_SCT_DONE) && !(DC_CCT_DONE)) + +static void +recalc_dc_req(Dc136 *dc) +{ + setreq(dc->bus, DC, dc->db_rq ? dc->pia : 0); +} + +static void +dbdamove(Dc136 *dc) +{ + dc->da_rq = 0; + dc->dbda_move = 0; + dc->db_rq = 1; + + if(dc->inout) + dc->da = dc->db; // out + else{ + dc->db = dc->da; // in + dc->da = 0; + } +} + +static void +dash_cp0(Dc136 *dc) +{ +cp0: + // DASH CP0 + if(dc->da_rq) + dc->data_clbd = 1; + + // DASH CP1 + if(DC_CCT_DONE){ + dc->cct = 0; + if(dc->da_rq == 0){ + dc->da_rq = 1; + if(dc->dbda_move) + dbdamove(dc); + }else + dc->da_rq = 1; + }else{ + if(DC_SCT_DONE){ + // CCT CONT + dc->cct++; + // this shouldn't be under the !CCT_DONE branch + // but the flow diagram FD1 does it too + dc->sct = 0; + }else{ + // SCT CONT + dc->sct++; + + // DASH LT + dc->da <<= 6; + goto cp0; + } + } +} + +void +dcgv(Dc136 *dc, word c, int n, int rev) +{ + switch(n){ + case 1: case 2: + if(rev) + dc->da = (dc->da >> 6 | (c&077)<<30) & FW; + else + dc->da = (dc->da << 6 | c&077) & FW; + break; + case 3: case 4: + dc->da = (dc->da << 6 | c&077) & FW; + break; + case 5: case 6: + dc->da |= c & FW; + break; + default: + return; + } + dash_cp0(dc); + recalc_dc_req(dc); +} + +word +dctk(Dc136 *dc, int n, int rev) +{ + word c; + switch(n){ + case 1: case 2: + if(rev){ + c = dc->da & 077; + dc->da = (dc->da >> 6) & FW; + }else{ + c = (dc->da >> 30) & 077; + dc->da = (dc->da << 6) & FW; + } + break; + case 3: case 4: + c = (dc->da >> 30) & 077; + dc->da = (dc->da << 6) & FW; + break; + case 5: case 6: + c = dc->da & FW; + break; + default: + return 0; + } + dash_cp0(dc); + recalc_dc_req(dc); + return c; +} + +static void +wake_dc(void *dev) +{ + Dc136 *dc; + IOBus *bus; + int dbda_move_old, da_rq_old; + + dc = dev; + bus = dc->bus; + + if(IOB_RESET){ + dc->db = 0; + dc->da = 0; + + dc->cct = 0; + dc->sct = 0; + dc->data_clbd = 0; + dc->dbda_move = 0; + dc->da_rq = 0; + dc->db_rq = 0; + dc->inout = 0; + dc->ch_mode = 0; + dc->device = 0; + dc->pia = 0; + } + + if(bus->devcode == DC){ + dbda_move_old = dc->dbda_move; + da_rq_old = dc->da_rq; + + if(IOB_STATUS){ + bus->c12 |= (dc->cct&7) << 13; + if(dc->data_clbd) bus->c12 |= F23; + if(dc->dbda_move) bus->c12 |= F24; + if(dc->da_rq) bus->c12 |= F25; + if(dc->db_rq) bus->c12 |= F26; + if(dc->inout) bus->c12 |= F27; + bus->c12 |= (dc->ch_mode & 3) << 6; + bus->c12 |= (dc->device & 7) << 3; + bus->c12 |= dc->pia & 7; + } + if(IOB_DATAI){ + bus->c12 |= dc->db; + dc->db_rq = 0; + dc->dbda_move = 1; + } + if(IOB_CONO_CLEAR){ + dc->db = dc->da; + dc->da = 0; + + dc->cct = 0; + dc->sct = 0; + dc->data_clbd = 0; + dc->dbda_move = 0; + dc->da_rq = 0; + dc->db_rq = 0; + dc->inout = 0; + dc->ch_mode = 0; + dc->device = 0; + dc->pia = 0; + } + if(IOB_CONO_SET){ + if(bus->c12 & F23) dc->data_clbd = 1; + if(bus->c12 & F24) dc->dbda_move = 1; + if(bus->c12 & F25) dc->da_rq = 1; + if(bus->c12 & F26) dc->db_rq = 1; + if(bus->c12 & F27) dc->inout = 1; + dc->ch_mode |= bus->c12>>6 & 03; + dc->device |= bus->c12>>3 & 07; + dc->pia |= bus->c12 & 07; + } + if(IOB_DATAO_CLEAR){ + dc->db = 0; + dc->db_rq = 0; + } + if(IOB_DATAO_SET){ + dc->db |= bus->c12; + dc->dbda_move = 1; + } + + if(dc->dbda_move && dc->da_rq && + !(dbda_move_old && da_rq_old)) + dbdamove(dc); + + recalc_dc_req(dc); + } +} + +static void +dcioconnect(Device *dev, IOBus *bus) +{ + Dc136 *dc; + dc = (Dc136*)dev; + dc->bus = bus; + bus->dev[DC] = (Busdev){ dc, wake_dc, 0 }; +} + +Device* +makedc(int argc, char *argv[]) +{ + Dc136 *dc; + + dc = malloc(sizeof(Dc136)); + memset(dc, 0, sizeof(Dc136)); + + dc->dev.type = dc_ident; + dc->dev.name = ""; + dc->dev.attach = nil; + dc->dev.ioconnect = dcioconnect; + + return &dc->dev; +} diff --git a/emu/init.ini b/emu/init.ini index 5bfed46..a54bdea 100644 --- a/emu/init.ini +++ b/emu/init.ini @@ -3,6 +3,7 @@ mkdev apr apr166 mkdev tty tty626 mkdev ptr ptr760 mkdev ptp ptp761 +mkdev dc dc136 mkdev fmem fmem162 0 mkdev cmem0 cmem161C mem_0 mkdev cmem1 cmem161C mem_1 @@ -12,6 +13,7 @@ mkdev cmem3 cmem161C mem_3 ioconnect tty apr ioconnect ptr apr ioconnect ptp apr +ioconnect dc apr memconnect fmem 0 apr -1 memconnect cmem0 0 apr 0 memconnect cmem1 0 apr 1 diff --git a/emu/pdp6.h b/emu/pdp6.h index 9e7fb28..cd3fbf6 100644 --- a/emu/pdp6.h +++ b/emu/pdp6.h @@ -458,3 +458,40 @@ struct Tty #define TTY_IDENT "tty626" extern char *tty_ident; Device *maketty(int argc, char *argv[]); + +/* Data Control 136 */ +#define DC (0200>>2) +typedef struct Dc136 Dc136; +struct Dc136 +{ + Device dev; + IOBus *bus; + int pia; + int device; + int ch_mode; + void *devp[8]; + + word da; + word db; + int cct; + int sct; + + int data_clbd; /* data clobbered */ + int dbda_move; + int da_rq; + int db_rq; + int inout; + + /* lines between dc and devices 1/2: + * tk/gv rt + * tk/gv lt + * clr cct 1 + * darq(1) + * sel 1 + */ +}; +#define DC_IDENT "dc136" +extern char *dc_ident; +Device *makedc(int argc, char *argv[]); +void dcgv(Dc136 *dc, word c, int n, int rev); +word dctk(Dc136 *dc, int n, int rev); diff --git a/emu/pt.c b/emu/pt.c index 1b29b2e..e561455 100644 --- a/emu/pt.c +++ b/emu/pt.c @@ -1,11 +1,7 @@ #include "pdp6.h" #include -#include #include -#include -#include -#include -#include +#include /* TODO? implement motor delays */ diff --git a/misc/mkpty.c b/misc/mkpty.c index 015a625..4cc1281 100644 --- a/misc/mkpty.c +++ b/misc/mkpty.c @@ -38,6 +38,9 @@ reset(int fd) struct timespec slp = { 0, 1000*1000*1000 / BAUD }; +//#define SLEEP nanosleep(&slp, NULL) +#define SLEEP + void readwrite(int ttyin, int ttyout, int ptyin, int ptyout) { @@ -63,7 +66,7 @@ readwrite(int ttyin, int ttyout, int ptyin, int ptyout) return; else{ write(ttyout, &c, 1); - nanosleep(&slp, NULL); + SLEEP; } } /* read from tty, write to pty */ @@ -74,7 +77,7 @@ readwrite(int ttyin, int ttyout, int ptyin, int ptyout) if(c == 035) return; write(ptyout, &c, 1); - nanosleep(&slp, NULL); + SLEEP; } } }