diff --git a/emu/Makefile b/emu/Makefile index 2445267..eac4f5c 100644 --- a/emu/Makefile +++ b/emu/Makefile @@ -3,12 +3,14 @@ H=pdp6.h ../tools/pdp6common.h # clang #CFLAGS= -Wno-shift-op-parentheses -Wno-logical-op-parentheses \ # -Wno-bitwise-op-parentheses -CFLAGS= -g -Wall -Wno-parentheses -fno-diagnostics-show-caret \ - `sdl-config --cflags` `pkg-config SDL_image --cflags` +CFLAGS= -g -Wall -Wno-parentheses -fno-diagnostics-show-caret +SDLFLAGS=`sdl-config --cflags` `pkg-config SDL_image --cflags` -LIBS= `sdl-config --libs` `pkg-config SDL_image --libs` -lpthread +LIBS=`sdl-config --libs` `pkg-config SDL_image --libs` -lpthread pdp6: $(SRC) $(H) - $(CC) $(CFLAGS) $(SRC) $(LIBS) -o pdp6 + $(CC) -o $@ $(CFLAGS) $(SDLFLAGS) $(SRC) $(LIBS) +test_dc: test_dc.c dc.c $(H) + $(CC) -o $@ $(CFLAGS) test_dc.c dc.c diff --git a/emu/dc.c b/emu/dc.c index a25e9d3..4350fd7 100644 --- a/emu/dc.c +++ b/emu/dc.c @@ -9,13 +9,17 @@ char *dc_ident = DC_IDENT; * 18 1 1 3 2 * 36 0 1 0 1 */ -#define NSHIFT ((0x70 >> (dc->ch_mode*2)) & 03) +#define NSHIFT ((0xE0 >> (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)) +#define DB_JM_DA (dc->db = dc->da), dc->da = 0 +#define DA_JM_DB (dc->da = dc->db) +#define DB_CLR dc->db = dc->db_rq = 0 + static void recalc_dc_req(Dc136 *dc) { @@ -23,18 +27,38 @@ recalc_dc_req(Dc136 *dc) } static void -dbdamove(Dc136 *dc) +db_da_swap(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; - } + DA_JM_DB; // out + else + DB_JM_DA; // in +} + +/* TODO: maybe make these two a bit nicer?? */ +static void +set_da_rq(Dc136 *dc) +{ + int prev; + + prev = dc->da_rq && dc->dbda_move; + dc->da_rq = 1; + if(!prev && dc->da_rq && dc->dbda_move) + db_da_swap(dc); +} +static void +set_dbda_move(Dc136 *dc) +{ + int prev; + + prev = dc->da_rq && dc->dbda_move; + dc->dbda_move = 1; + if(!prev && dc->da_rq && dc->dbda_move) + db_da_swap(dc); } static void @@ -45,39 +69,37 @@ cp0: if(dc->da_rq) dc->data_clbd = 1; + // 1ms delay + // DASH CP1 if(DC_CCT_DONE){ //printf("Full DA: %012lo\n", dc->da); dc->cct = 0; - if(dc->da_rq == 0){ - dc->da_rq = 1; - if(dc->dbda_move) - dbdamove(dc); - }else - dc->da_rq = 1; + set_da_rq(dc); + }else if(DC_SCT_DONE){ + // CCT CONT + dc->sct = 0; + dc->cct = (dc->cct+1) & 7; }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++; + // SCT CONT + dc->sct = (dc->sct+1) & 3; - // DASH LT - dc->da <<= 6; - goto cp0; - } + // DASH LT + dc->da = (dc->da << 6) & FW; + goto cp0; } } +/* Give TO DC, this is the TK signal in the DC. + * NB: for dev 5/6 give only the lower N bits. */ void dcgv(Dc136 *dc, int n, word c, int rev) { //printf("DC Taking %06lo from dev %d\n", c, n); - switch(n){ + + if(n != dc->device) + return; + switch(dc->device){ case 1: case 2: if(rev) dc->da = (dc->da >> 6 | (c&077)<<30) & FW; @@ -97,11 +119,16 @@ dcgv(Dc136 *dc, int n, word c, int rev) recalc_dc_req(dc); } +/* Take FROM DC, this is the GV signal in the DC. + * NB: for dev 5/6 read only the upper N bits. */ word dctk(Dc136 *dc, int n, int rev) { word c; - switch(n){ + + if(n != dc->device) + return 0; + switch(dc->device){ case 1: case 2: if(rev){ c = dc->da & 077; @@ -127,36 +154,38 @@ dctk(Dc136 *dc, int n, int rev) return c; } +static void +ic_clr(Dc136 *dc) +{ + DB_JM_DA; + + 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; +} + 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; + ic_clr(dc); + DB_CLR; } 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; @@ -171,46 +200,27 @@ wake_dc(void *dev) 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; + set_dbda_move(dc); } + if(IOB_CONO_CLEAR) + ic_clr(dc); 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 & F24) set_dbda_move(dc); + if(bus->c12 & F25) set_da_rq(dc); 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_CLEAR) + DB_CLR; if(IOB_DATAO_SET){ dc->db |= bus->c12; - dc->dbda_move = 1; + set_dbda_move(dc); } - if(dc->dbda_move && dc->da_rq && - !(dbda_move_old && da_rq_old)) - dbdamove(dc); - recalc_dc_req(dc); } } diff --git a/emu/init.ini b/emu/init.ini index c4fdae2..243443d 100644 --- a/emu/init.ini +++ b/emu/init.ini @@ -12,6 +12,7 @@ mkdev cmem1 cmem161C mem_1 mkdev cmem2 cmem161C mem_2 mkdev cmem3 cmem161C mem_3 #mkdev netmem netmem its.pdp10.se 10006 +mkdev netmem netmem localhost 10006 connectdev dc dt0 connectdev dt0 dx0 8 diff --git a/emu/netmem.c b/emu/netmem.c index 29f0d1c..c251fd2 100644 --- a/emu/netmem.c +++ b/emu/netmem.c @@ -120,6 +120,7 @@ makenetmem(int argc, char *argv[]) nm->fd = dial(host, port); if(nm->fd < 0) printf("couldn't connect\n"); + printf("netmem fd: %d\n", nm->fd); th = (Thread){ nil, netmemcycle, nm, 50, 0 }; addthread(th); diff --git a/emu/test_dc.c b/emu/test_dc.c new file mode 100644 index 0000000..1ae65fd --- /dev/null +++ b/emu/test_dc.c @@ -0,0 +1,234 @@ +#include "pdp6.h" + +Dc136 *dc; +IOBus iobus; +IOBus *bus = &iobus; +int pireq; + +void +setreq(IOBus *bus, int dev, u8 pia) +{ + pireq = pia; +} + +void +wakedev(IOBus *bus, int d) +{ + Busdev *dev; + bus->devcode = d; + dev = &bus->dev[d]; + if(dev->wake) + dev->wake(dev->dev); +} + +void +bus_reset(IOBus *bus) +{ + int d; + bus->c34 |= IOBUS_IOB_RESET; + for(d = 0; d < 128; d++) + wakedev(bus, d); + bus->c34 &= ~IOBUS_IOB_RESET; +} + +void +cono(IOBus *bus, int d, hword w) +{ + bus->c34 |= IOBUS_CONO_CLEAR; + wakedev(bus, d); + bus->c34 &= ~IOBUS_CONO_CLEAR; + + bus->c34 |= IOBUS_CONO_SET; + bus->c12 = w; + wakedev(bus, d); + bus->c34 &= ~IOBUS_CONO_SET; + bus->c12 = 0; +} + +void +datao(IOBus *bus, int d, word w) +{ + bus->c34 |= IOBUS_DATAO_CLEAR; + wakedev(bus, d); + bus->c34 &= ~IOBUS_DATAO_CLEAR; + + bus->c34 |= IOBUS_DATAO_SET; + bus->c12 = w; + wakedev(bus, d); + bus->c34 &= ~IOBUS_DATAO_SET; + bus->c12 = 0; +} + +word +coni(IOBus *bus, int d) +{ + word w; + bus->c34 |= IOBUS_IOB_STATUS; + wakedev(bus, d); + bus->c34 &= ~IOBUS_IOB_STATUS; + w = bus->c12; + bus->c12 = 0; + return w; +} + +word +datai(IOBus *bus, int d) +{ + word w; + bus->c34 |= IOBUS_IOB_DATAI; + wakedev(bus, d); + bus->c34 &= ~IOBUS_IOB_DATAI; + w = bus->c12; + bus->c12 = 0; + return w; +} + +void +printdc(Dc136 *dc) +{ + printf("DB/%012lo DA/%012lo CCT/%o SCT/%o CHMOD/%o\n", + dc->db, dc->da, dc->cct, dc->sct, dc->ch_mode); + printf(" CLBD/%o DBDAMOVE/%o DARQ/%o DBRQ/%o INOUT/%o DEV/%o PIA/%o\n", + dc->data_clbd, dc->dbda_move, dc->da_rq, dc->db_rq, + dc->inout, dc->device, dc->pia); +} + +enum { + CLBD = 010000, + + DBDAMOVE = 04000, + DARQ = 02000, + DBRQ = 01000, + + IN = 0000, + OUT = 0400, + + CHMOD_6 = 0000, + CHMOD_36 = 0100, + CHMOD_12 = 0200, + CHMOD_18 = 0300, + + DEV1 = 010, + DEV2 = 020, + DEV3 = 030, + DEV4 = 040, + DEV5 = 050, + DEV6 = 060, +}; + +/* + * output: + * DARQ: DA empty, need new data + * DBRQ: DB empty, need new data + * DBDA MOVE: DB waiting to send data to DA + * input: + * DARQ: DA full, need to empty + * DBRQ: DB full, need to empty + * DBDA MOVE: DB waiting to get data from DA + */ + +int +main() +{ + dc = (Dc136*)makedc(0, nil); + dc->dev.ioconnect((Device*)dc, bus); + + bus_reset(bus); + assert(coni(bus, DC) == 0); + + // output test + cono(bus, DC, DARQ|DBRQ|OUT|CHMOD_6|DEV1|7); // 3417 + assert(pireq == 7); + printdc(dc); + datao(bus, DC, 0123456000001); + assert(pireq == 7); + printdc(dc); + datao(bus, DC, 0123456000002); + assert(pireq == 0); + printdc(dc); + assert(dctk(dc, 1, 0) == 012); + assert(pireq == 0); + printdc(dc); + assert(dctk(dc, 1, 0) == 034); + assert(pireq == 0); + printdc(dc); + assert(dctk(dc, 1, 0) == 056); + assert(pireq == 0); + printdc(dc); + assert(dctk(dc, 1, 0) == 000); + assert(pireq == 0); + printdc(dc); + assert(dctk(dc, 1, 0) == 000); + assert(pireq == 0); + printdc(dc); + assert(dctk(dc, 1, 0) == 001); + assert(pireq == 7); + printdc(dc); + + printf("\n\n"); + + cono(bus, DC, DARQ|DBRQ|OUT|CHMOD_12|DEV5|7); // 3657 + assert(pireq == 7); + printdc(dc); + datao(bus, DC, 0123456112233); + assert(pireq == 7); + printdc(dc); + datao(bus, DC, 0123456445566); + assert(pireq == 0); + printdc(dc); + assert((dctk(dc, 5, 0)&0777700000000) == 0123400000000); + assert(pireq == 0); + printdc(dc); + assert((dctk(dc, 5, 0)&0777700000000) == 0561100000000); + assert(pireq == 0); + printdc(dc); + assert((dctk(dc, 5, 0)&0777700000000) == 0223300000000); + assert(pireq == 7); + printdc(dc); + + printf("\n\n"); + + // input test + cono(bus, DC, DBDAMOVE|IN|CHMOD_6|DEV1|7); // 4017 + assert(pireq == 0); + printdc(dc); + dcgv(dc, 1, 012, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 1, 034, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 1, 056, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 1, 011, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 1, 022, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 1, 033, 0); + assert(pireq == 7); + printdc(dc); + assert(datai(bus, DC) == 0123456112233); + printdc(dc); + + + printf("\n\n"); + + + cono(bus, DC, DBDAMOVE|IN|CHMOD_12|DEV5|7); // 4017 + assert(pireq == 0); + printdc(dc); + dcgv(dc, 5, 01234, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 5, 05611, 0); + assert(pireq == 0); + printdc(dc); + dcgv(dc, 5, 02233, 0); + assert(pireq == 7); + printdc(dc); + + return 0; +}