From 88875b87ce1dfd458e2ba5f15f65b745a18d19f9 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 7 Feb 2018 01:37:09 +0100 Subject: [PATCH] committing old stuff --- code/Makefile | 11 +- code/bootstrap.txt | 65 +++++ code/dtboot.s | 23 ++ code/main.s | 16 ++ code/tty.s | 23 ++ emu/Makefile | 2 +- emu/cmd.c | 43 ++++ emu/cmds.txt | 18 ++ emu/dc.c | 5 +- emu/dt.c | 577 +++++++++++++++++++++++++++++++++++++++++++++ emu/init.ini | 6 + emu/main.c | 4 +- emu/mem.c | 3 +- emu/mem_0 | 24 ++ emu/pdp6.h | 97 +++++++- misc/mkpty.c | 3 + tools/ld6.c | 18 +- 17 files changed, 920 insertions(+), 18 deletions(-) create mode 100644 code/bootstrap.txt create mode 100644 code/dtboot.s create mode 100644 emu/cmds.txt create mode 100644 emu/dt.c create mode 100644 emu/mem_0 diff --git a/code/Makefile b/code/Makefile index 9ccddcc..060babc 100644 --- a/code/Makefile +++ b/code/Makefile @@ -1,8 +1,11 @@ -test.rim: main.rel tty.rel pt.rel - ld6 -o test.rim main.rel tty.rel pt.rel +test.rim: main.rel tty.rel pt.rel dt.rel + ld6 -o test.rim main.rel tty.rel pt.rel dt.rel -test.sav: main.rel tty.rel pt.rel - ld6 -f sav -o test.sav main.rel tty.rel pt.rel +test.sav: main.rel tty.rel pt.rel dt.rel + ld6 -f sav -o test.sav main.rel tty.rel pt.rel dt.rel + +dtboot.rim: dtboot.rel + ld6 -o dtboot.rim dtboot.rel %.rel: %.s as6 -o $@ $< diff --git a/code/bootstrap.txt b/code/bootstrap.txt new file mode 100644 index 0000000..4db86a2 --- /dev/null +++ b/code/bootstrap.txt @@ -0,0 +1,65 @@ +PAPER TAPE RIM LOADER (AT 20): + + LOC 20 + CONO PTR,60 ; 710600 000060 +A: CONSO PTR,10 ; 710740 000010 + JRST .-1 ; 254000 000021 + DATAI PTR,B ; 710440 000026 + CONSO PTR,10 ; 710740 000010 + JRST .-1 ; 254000 000024 +B: 0 ; 000000 000000 + JRST A ; 254000 000021 + +DECTAPE RIM LOADER AT 0 (SHADOW) 014 INSTRUCTIONS + +MY DECTAPE LOADER: + CONO DC,4010 ; 720200 004010 + CONO UTC,220300 ; 721200 220300 + MOVE 17,12 ; 200740 000012 + CONSO DC,1000 ; 720340 001000 + JRST .-1 ; 254000 000003 + BLKI DC,17 ; 720000 000017 + JRST DONE ; 254000 000010 + JRST .-1 ; 254000 000003 +DONE: CONO DC,0 ; 720200 000000 + HALT 300 ; 254200 000300 + 777600000277 ; 777600 000277 + + +PDP-10 RIM10 LOADER: + +003110' R1BLDR: +000000 PHASE 0 +003110' 777762 000000 IOWD $ADR,$ST +003111' 710600 000060 $ST: CONO PTR,60 +003112' 541400 000004 HRRI $A,$RD+1 +003113' 710740 000010 $RD: CONSO PTR,10 +003114' 254000 000003 JRST .-1 +003115' 710470 000007 DATAI PTR,@$TBL1-$RD+1($A) +003116' 256010 000007 XCT $TBL1-$RD+1($A) +003117' 256010 000012 XCT $TBL2-$RD+1($A) +003120' 364400 000000 $A: SOJA $A, +003121' 312740 000016 $TBL1: CAME $CKSM,$ADR +003122' 270756 000001 ADD $CKSM,1($ADR) +003123' 331740 000016 SKIPL $CKSM,$ADR +003124' 254200 000001 $TBL2: JRST 4,$ST +003125' 253700 000003 AOBJN $ADR,$RD +003126' 254000 000002 $ADR: JRST $ST+1 +000017 $CKSM: +003127' DEPHASE + + +MAC DECtape RIM loader: +000000 JFCL +000001 MOVSI (JFCL) +000002 CONO 635550 +000003 CONO PI,11577 +000004 CONO UTC,223110 +000005 CONO DC,4010 +000006 CONSO DC,1000 +000007 JRST 6 +000010 DATAI DC,13 +000011 AOJGE 13,6 +000012 TRNE 13,-1 +000013 . +000014 JRST 6 diff --git a/code/dtboot.s b/code/dtboot.s new file mode 100644 index 0000000..b5efae2 --- /dev/null +++ b/code/dtboot.s @@ -0,0 +1,23 @@ +DC==200 +UTC==210 +UTS==214 + +DACI==04010 + +SL==220000 +RD==300 + +LOC 0 +ENTRY: + CONO DC,DACI + CONO UTC,SL+RD + MOVE 17,[ IOWD 200,300 ] + CONSO DC,1000 + JRST .-1 + BLKI DC,17 + JRST DONE + JRST .-4 +DONE: CONO DC,0 + HALT 300 + +END ENTRY diff --git a/code/main.s b/code/main.s index 79de70b..2453ee8 100644 --- a/code/main.s +++ b/code/main.s @@ -10,7 +10,9 @@ PTP==100 EXTERN PUTC,PUTS EXTERN GETCH,GETC +EXTERN PUTN EXTERN PTPUT +EXTERN DTTEST ENTRY: JRST START @@ -19,16 +21,30 @@ SP: XWD -100,PDL-1 START: MOVE PDP,SP + ;; NUMBER TEST +; MOVE AC1,[-1234] +; PUSHJ PDP,PUTN +; MOVE AC1,[1234] +; PUSHJ PDP,PUTN + + ;; DECTAPE TEST + JRST DTTEST + + ;; UUO TEST ; UUO1 123 + ;; ENABLE CLOCK PI ON CHANNEL 1 ; CONO CPA,2001 + ;; ENABLE PI ON CHANNEL 1 ; CONO PRS,2300 ; JRST . + ;; WRITE MESSAGE TO TTY MOVSI AC2,440700 HRRI AC2,MSG PUSHJ PDP,PUTS + ;; WRITE FROM TTY TO PTP PUSHJ PDP,GETC ; CONO PTP,20 PUSHJ PDP,PTPUT diff --git a/code/tty.s b/code/tty.s index f17123f..ceb7e22 100644 --- a/code/tty.s +++ b/code/tty.s @@ -7,6 +7,7 @@ PDP==17 INTERNAL PUTC,PUTS +; PRINT CHAR IN AC1 ON TTY PUTC: CONSZ TTY,20 ; wait until not busy JRST .-1 @@ -31,6 +32,7 @@ PUTS: INTERNAL GETCH,GETC +; READ CHAR FROM TTY INTO AC1 GETCH: CONSO TTY,40 ; wait for flag JRST .-1 @@ -42,3 +44,24 @@ GETC: PUSHJ PDP,GETCH PUSHJ PDP,PUTC POPJ PDP, + +BASE: 10 +DIGITS: EXP "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" +; PRINT NUMBER IN AC! +INTERNAL PUTN +PUTN: + JUMPGE AC1,UPUTN + PUSH PDP,AC1 + MOVEI AC1, "-" + PUSHJ PDP,PUTC + POP PDP,AC1 + MOVM AC1,AC1 +UPUTN: + IDIV AC1,BASE + JUMPE AC1,UPR1 + PUSH PDP,AC2 + PUSHJ PDP,UPUTN + POP PDP,AC2 +UPR1: + MOVE AC1,DIGITS(AC2) + JRST PUTC diff --git a/emu/Makefile b/emu/Makefile index 23da7ad..930c186 100644 --- a/emu/Makefile +++ b/emu/Makefile @@ -1,4 +1,4 @@ -SRC=main.c cmd.c apr.c mem.c tty.c pt.c dc.c ../tools/pdp6common.c +SRC=main.c cmd.c apr.c mem.c tty.c pt.c dc.c dt.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 75b0023..be5a406 100644 --- a/emu/cmd.c +++ b/emu/cmd.c @@ -211,6 +211,8 @@ DevDef definitions[] = { { PTR_IDENT, makeptr }, { PTP_IDENT, makeptp }, { DC_IDENT, makedc }, + { DT_IDENT, makedt }, + { DX_IDENT, makedx }, { nil, nil } }; @@ -318,6 +320,44 @@ c_memconnect(int argc, char *argv[]) attachmem((Mem*)dev, proc, &((Apr*)busdev)->membus, addr); } +/* devconnect dev1 dev2 */ +// TODO: not quite sure this is the right way to do it +static void +c_devconnect(int argc, char *argv[]) +{ + Device *dev1, *dev2; + + if(argc < 3){ +args: + printf("Not enough arguments\n"); + return; + } + dev1 = getdevice(argv[1]); + if(dev1 == nil){ + printf("No device: %s\n", argv[1]); + return; + } + dev2 = getdevice(argv[2]); + if(dev2 == nil){ + printf("No device: %s\n", argv[2]); + return; + } + if(dev1->type == dc_ident && dev2->type == dt_ident) + dtconn((Dc136*)dev1, (Dt551*)dev2); + else if(dev1->type == dt_ident && dev2->type == dx_ident){ + int n; + if(argc < 4) + goto args; + n = atoi(argv[3]); + if(n < 1 || n > 8){ + printf("Invalid device number %d\n", n); + return; + } + dxconn((Dt551*)dev1, (Dx555*)dev2, n); + }else + printf("Cannot connect %s to %s\n", dev2->type, dev1->type); +} + static void c_ex(int argc, char *argv[]) { @@ -423,6 +463,8 @@ c_load(int argc, char *argv[]) static void c_show(int argc, char *argv[]) { + printf("Devices:\n"); + showdevices(); printf("Memory:\n"); showmem(&apr->membus); } @@ -441,6 +483,7 @@ struct { { "attach", c_attach }, { "ioconnect", c_ioconnect }, { "memconnect", c_memconnect }, + { "devconnect", c_devconnect }, { "examine", c_ex }, { "deposit", c_dep }, { "load", c_load }, diff --git a/emu/cmds.txt b/emu/cmds.txt new file mode 100644 index 0000000..08860ed --- /dev/null +++ b/emu/cmds.txt @@ -0,0 +1,18 @@ +mkdev name type + creates a device and gives it a name +attach name path + attaches a file to a device +ioconnect name busdevname + connects a device to the IO bus of a processor +memconnect name procnum busdevname addr + connects a memory module to the memory bus of a processor +examine [-sm] address(range) + examines memory (s: shadow mode, m: mnemonic) +deposit [-sm] address(range) word + deposits word into memory (s: shadow mode, m: mnemonic) +load filename + loads file into memory (see source for which format) +show + shows device configuration +quit + take a guess diff --git a/emu/dc.c b/emu/dc.c index ef36b14..a25e9d3 100644 --- a/emu/dc.c +++ b/emu/dc.c @@ -47,6 +47,7 @@ cp0: // 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; @@ -73,8 +74,9 @@ cp0: } void -dcgv(Dc136 *dc, word c, int n, int rev) +dcgv(Dc136 *dc, int n, word c, int rev) { +//printf("DC Taking %06lo from dev %d\n", c, n); switch(n){ case 1: case 2: if(rev) @@ -121,6 +123,7 @@ dctk(Dc136 *dc, int n, int rev) } dash_cp0(dc); recalc_dc_req(dc); +//printf("DC Giving %06lo to dev %d\n", c, n); return c; } diff --git a/emu/dt.c b/emu/dt.c new file mode 100644 index 0000000..9df883c --- /dev/null +++ b/emu/dt.c @@ -0,0 +1,577 @@ +#include "pdp6.h" +#include +#include + +char *dt_ident = DT_IDENT; +char *dx_ident = DX_IDENT; + +// TODO: find out how this should be controlled +#define DEVNO 1 + +enum +{ + DTSIZE = 922512 +}; + +/* Transport */ + +static uchar +dxread(Dx555 *dx) +{ + if(dx->dt->ut_rev) + return *dx->cur ^ 010; + else + return *dx->cur; +} + +static void +dxwrite(Dx555 *dx, uchar d) +{ + if(dx->dt->ut_rev) + *dx->cur = d ^ 010; + else + *dx->cur = d; +} + +static void +dxmove(Dx555 *dx) +{ + // At end of tape read the last word forever + if(dx->dt->ut_rev){ + dx->cur--; + if(dx->cur < dx->start) + dx->cur = dx->start+5; + }else{ + dx->cur++; + if(dx->cur >= dx->end) + dx->cur = dx->end-6; + } +} + +static void +dxattach(Device *dev, const char *path) +{ + Dx555 *dx; + int fd; + + dx = (Dx555*)dev; + fd = dx->fd; + if(fd >= 0){ + dx->fd = -1; + close(dx->fd); + } + memset(dx->start, 0, DTSIZE); + dx->fd = open(path, O_RDWR | O_CREAT, 0666); + if(dx->fd < 0) + fprintf(stderr, "couldn't open file %s\n", path); + else + read(dx->fd, dx->start, DTSIZE); +} + +/* Connect a transport to a control */ +void +dxconn(Dt551 *dt, Dx555 *dx, int n) +{ + dt->dx[n%8] = dx; + dx->dt = dt; + dx->unit = n; +} + +Device* +makedx(int argc, char *argv[]) +{ + Dx555 *dx; + + dx = malloc(sizeof(Dx555)); + memset(dx, 0, sizeof(Dx555)); + + dx->dev.type = dx_ident; + dx->dev.name = ""; + dx->dev.attach = dxattach; + dx->dev.ioconnect = nil; + + dx->start = malloc(DTSIZE); + dx->cur = dx->start; + dx->end = dx->start + DTSIZE; + memset(dx->start, 0, DTSIZE); + + return &dx->dev; +} + +/* Control */ + +enum +{ + TapeEndF = 022, + TapeEndR = 055, + + BlockSpace = 025, + + BlockEndF = 026, + BlockEndR = 045, + + DataSync = 032, /* rev guard */ + BlockSync = 051, /* guard */ + + DataEndF = 073, /* pre-final, final, ck, rev lock */ + DataEndR = 010, /* lock, rev ck, rev final, rev pre-final */ + + Data = 070, + + + RW_NULL = 0, + RW_RQ = 1, + RW_ACTIVE = 2, +}; + +#define DATA_SYNC (dt->tmk == (0600|DataSync)) +#define END_ZONE (dt->tmk == (0600|TapeEndF)) +#define BM_SPACE (dt->tmk == (0400|BlockSpace) ||\ + dt->tmk == (0500|BlockSpace) ||\ + dt->tmk == (0600|BlockSpace) ||\ + dt->tmk == (0700|BlockSpace)) +#define BM_END (dt->tmk == (0500|BlockEndF)) +#define DATA_SYNC (dt->tmk == (0600|DataSync)) +#define BM_SYNC (dt->tmk == (0700|BlockSync)) +#define FWD_DATA_END (dt->tmk == (0400|DataEndF) ||\ + dt->tmk == (0700|DataEndF)) +#define REV_DATA_END (dt->tmk == (0400|DataEndR) ||\ + dt->tmk == (0600|DataEndR)) +#define DATA (dt->tmk == (0400|Data)) + +#define STOP (dt->tdata == 0 || dt->tdata == 1) +#define SYNC (dt->tdata == 0200) +#define REV_CKS (dt->tdata == 0100) +#define BLOCK (dt->tdata == 040 || dt->tdata == 020 || dt->tdata == 010) +#define PRE_FINAL (dt->tdata == 004) +#define FWD_CKS (dt->tdata == 002) + +#define UT_WRITE ((dt->ut_fcn & 04) == 04) +#define UT_READ ((dt->ut_fcn & 04) == 0) +#define UT_ALL ((dt->ut_fcn & 03) == 01) +#define UT_BM ((dt->ut_fcn & 03) == 02) +#define UT_DATA ((dt->ut_fcn & 03) == 03) +#define UT_DN (dt->ut_fcn == 0) +#define UT_WRTM (dt->ut_fcn == 04) + +#define DC_SELECT1 (dt->dc->devp[dt->dc->device] == dt) +#define UTE_DC_DISCONNECT (!(DC_SELECT1 && !dt->dc->da_rq)) +#define UT_WRITE_PREVENT (dt->seldx->wrlock) +#define UT_WREN_DATA (UT_WRITE && dt->ut_wren && !UT_WRITE_PREVENT) +#define RW_ODD (!dt->tct && dt->rw_state == RW_ACTIVE) +#define RW_BM_DONE (UT_BM && BM_END) +#define RW_DATA_CONT (DC_SELECT1 && !dt->dc->da_rq && UT_DATA && dt->rw_state == RW_ACTIVE) +#define RW_DATA_STOP (UTE_DC_DISCONNECT && UT_DATA && dt->rw_state == RW_ACTIVE) + +#define TBM0 (dt->tbm == 10) +#define TBM3 (dt->tbm == 1) + +// all but block space +#define UTE_MK (DATA_SYNC || END_ZONE || BM_END ||\ + DATA_SYNC || BM_SYNC || FWD_DATA_END || REV_DATA_END || DATA) +#define UTE_ERROR (dt->uteck && (dt->utek == 040) != UTE_MK) +// not sure if BM SYNC || DATA SYNC is correct +#define UTE_ACTIVE_ERROR (!UT_ALL && dt->rw_state == RW_ACTIVE && (BM_SYNC || DATA_SYNC)) + + + +#define PRINT1 \ + printf("%c%02o(%o,%02o,%d)", dt->rw_state == RW_ACTIVE ? '+' : dt->rw_state == RW_RQ ? '-' : ' ', \ + dt->tmk&077, l&07, dt->rwb, dt->tct); \ + putchar(' '); \ + if(STOP) \ + printf(" [STOP] "); \ + else if(SYNC) \ + printf(" [SYNC] "); \ + else if(REV_CKS) \ + printf(" [REV_CKS] "); \ + else if(BLOCK) \ + printf(" [BLOCK] "); \ + else if(PRE_FINAL) \ + printf(" [PRE FINAL] "); \ + else if(FWD_CKS) \ + printf(" [FWD CKS %02o] ", dt->lb); + +#define PRINT2 \ + if(END_ZONE) \ + printf("TapeEndF "); \ + else if(BM_SPACE) \ + printf("BlockSpace %o ", dt->tbm); \ + else if(BM_END) \ + printf("BlockEndF "); \ + else if(DATA_SYNC) \ + printf("DataSync "); \ + else if(BM_SYNC) \ + printf("BlockSync "); \ + else if(FWD_DATA_END) \ + printf("DataEndF "); \ + else if(REV_DATA_END) \ + printf("DataEndR "); \ + else if(DATA) \ + printf("Data "); + +static void +recalc_dt_req(Dt551 *dt) +{ + int req; + if(dt->ut_jb_done_flag && dt->ut_jb_done_enable || + dt->ut_tape_end_flag && dt->ut_tape_end_enable || + dt->time_flag && dt->time_enable || + dt->ut_info_error || + dt->ut_illegal_op) + req = dt->ut_pia; + else + req = 0; + setreq(dt->bus, UTC, req); +} + +static void +dtcycle(void *p) +{ + Dt551 *dt; + dt = (Dt551*)p; + uchar l, wb; + int data1edge, data7edge; + int bm0edge, bm3edge; + + // TODO: maybe do something else here? + if(dt->seldx == nil) + return; + + if(!dt->ut_go) + return; + + + if(dt->rw_state != RW_ACTIVE) + dt->tct = 0; + l = dxread(dt->seldx); + +/* TP0 */ + + if(dt->rw_state == RW_ACTIVE) + dt->ut_wren = 1; + + if(UT_WRITE){ + if(UT_WRITE_PREVENT) + dt->ut_illegal_op = 1; + if(dt->tct) + wb = l&010 | dt->rwb&07; + else + wb = l&010 | dt->rwb>>3 & 07; + } + if(UT_WREN_DATA) + dxwrite(dt->seldx, wb); + +/* TP1 */ + +//**/ PRINT1 +//**/ PRINT2 + + dt->tmk = ((dt->tmk << 1) | !!(l&010)) & 0377 | + dt->tmk&0400 | (dt->tmk<<1)&0400; + if(UT_READ){ + if(dt->tct != dt->ut_rev) + dt->rwb |= l&07; + else + dt->rwb |= (l&07) << 3; + } + +/* TP2 */ +///**/ printf("%2o%c%c%c ", dt->utek, UTE_MK ? 'M' : ' ', UTE_ERROR ? 'E' : ' ', dt->uteck ? 'C' : ' '); + + if(UTE_ERROR || UTE_ACTIVE_ERROR) +printf("UT INFO ERROR\n"), + dt->ut_info_error = 1; + + if(!BM_SPACE){ + if(dt->utek == 1) + dt->utek = 040; + else + dt->utek >>= 1; + } + + if(dt->tct) + dt->lb ^= ~dt->rwb & 077; + +//**/ if(dt->rw_state == RW_ACTIVE && dt->tct) +//**/ printf("(%02o, %02o) ", dt->rwb, dt->lb); + + if(UT_READ && dt->rw_state == RW_ACTIVE && dt->tct){ + // before tct complement + if(!(UT_DATA && dt->tdata & 0102)){ + dcgv(dt->dc, DEVNO, dt->rwb, dt->ut_rev); + if(UTE_DC_DISCONNECT) + dt->ut_incomp_block = 1; + } + } + + + if(END_ZONE){ + dt->ut_tape_end_flag = 1; + dt->ut_go = 0; + } + + bm0edge = 0; + bm3edge = 0; + if(BM_SYNC) + dt->tbm |= 020; // shifted to 010 (TBM0) now + if(BM_SPACE || BM_SYNC){ + dt->tbm >>= 1; + if(TBM0) + bm0edge = 1; + else if(TBM3) + bm3edge = 1; + } + + data1edge = 0; // goes up before rev checksum is expected + data7edge = 0; // goes up when checksum is seen + if(DATA_SYNC) + dt->tdata |= 0400; // shifted to 0200 now + if(FWD_DATA_END || REV_DATA_END || DATA_SYNC){ + dt->tdata >>= 1; + if(dt->tdata == 0100) + data1edge = 1; + else if(dt->tdata == 1) + data7edge = 1; + } + + if(data1edge) + dt->lb = 0; + + // TODO: not sure about rw_active + if(data7edge && dt->rw_state == RW_ACTIVE) + if(dt->lb != 077) +printf("UT INFO ERROR\n"), + dt->ut_info_error = 1; + + // before active is set below + if(dt->rw_state == RW_ACTIVE) + dt->tct = !dt->tct; + + // manual mentions tdata6(0) going to 0??? + if(dt->rw_state == RW_ACTIVE){ + if(data7edge && RW_DATA_STOP || + RW_BM_DONE){ +printf("FINISHING JOB\n"); + dt->ut_jb_done_flag = 1; + dt->rw_state = RW_NULL; + } + if(UTE_ACTIVE_ERROR) + dt->rw_state = RW_NULL; + if(data7edge && RW_DATA_CONT) + dt->rw_state = RW_RQ; + }else if(dt->rw_state == RW_RQ){ + if(UT_BM && bm3edge || + UT_DATA && data1edge || + UT_ALL && bm0edge) + dt->rw_state = RW_ACTIVE; + } + +/* TP3 */ + + if(RW_ODD) + dt->rwb = 0; + + if(TBM3 && BM_SPACE) + dt->utek = 040; + if(BM_SYNC) + dt->uteck = 0; + if(TBM3 && !BM_SPACE) + dt->uteck = 1; + +/* TP4 */ + + if(UT_WRITE && RW_ODD){ + /* Take checksum data from LB */ + if(UT_DATA && dt->tdata & 0102) + dt->rwb = dt->lb; + else{ + dt->rwb |= dctk(dt->dc, DEVNO, dt->ut_rev); + if(UTE_DC_DISCONNECT) + dt->ut_incomp_block = 1; + } + if(dt->ut_rev) + dt->rwb = dt->rwb>>3 & 07 | dt->rwb<<3 & 070; + } + if(dt->rw_state == RW_ACTIVE) + dt->ut_wren = 0; + +//**/ printf("\n"); + + dxmove(dt->seldx); + + recalc_dt_req(dt); +} + +static void +wake_dt(void *dev) +{ + Dt551 *dt; + IOBus *bus; + + dt = (Dt551*)dev; + bus = dt->bus; + if(IOB_RESET){ + dt->ut_incomp_block = 0; + + dt->ut_pia = 0; + dt->ut_units = 0; + dt->ut_units_select = 0; + dt->ut_fcn = 0; + dt->ut_time = 0; + dt->ut_wren = 0; + dt->ut_go = 0; + dt->ut_rev = 0; + dt->ut_tape_end_flag = 0; + dt->ut_tape_end_enable = 0; + dt->ut_jb_done_flag = 0; + dt->ut_jb_done_enable = 0; + dt->time_enable = 0; + dt->time_flag = 0; + dt->ut_illegal_op = 0; + dt->ut_info_error = 0; + + dt->tmk = 0; + dt->rwb = 0; + dt->tbm = 0; + dt->tdata = 0; + dt->utek = 0; + dt->uteck = 0; + + dt->rw_state = RW_NULL; + } + + if(bus->devcode == UTS){ + if(IOB_STATUS){ +//printf("UTS STATUS\n"); + // we have no delays (yet?) F25 + if(dt->rw_state == RW_RQ) bus->c12 |= F26; + if(dt->rw_state == RW_ACTIVE) bus->c12 |= F27; + if(dt->rw_state == RW_NULL) bus->c12 |= F28; + if(dt->ut_incomp_block) bus->c12 |= F29; + if(dt->ut_wren) bus->c12 |= F30; + if(dt->time_flag) bus->c12 |= F31; + if(dt->ut_info_error) bus->c12 |= F32; + if(dt->ut_illegal_op) bus->c12 |= F33; + if(dt->ut_tape_end_flag) bus->c12 |= F34; + if(dt->ut_jb_done_flag) bus->c12 |= F35; + } + } + if(bus->devcode == UTC){ + if(IOB_STATUS){ +//printf("UTC STATUS\n"); + if(dt->ut_units_select) bus->c12 |= F19; + if(dt->ut_tape_end_enable) bus->c12 |= F20; + if(dt->ut_jb_done_enable) bus->c12 |= F21; + if(dt->ut_go) bus->c12 |= F22; + if(dt->ut_rev) bus->c12 |= F23; + if(dt->time_enable) bus->c12 |= F24; + bus->c12 |= (dt->ut_time & 03) << 9; + bus->c12 |= (dt->ut_fcn & 07) << 6; + bus->c12 |= (dt->ut_units & 07) << 3; + bus->c12 |= dt->ut_pia & 07; + } + if(IOB_CONO_CLEAR){ +//printf("UTC CONO CLEAR\n"); + dt->ut_incomp_block = 0; + dt->ut_wren = 0; + dt->time_flag = 0; + dt->ut_info_error = 0; + dt->ut_illegal_op = 0; + dt->ut_tape_end_flag = 0; + dt->ut_jb_done_flag = 0; + + dt->rw_state = RW_NULL; + } + if(IOB_CONO_SET){ +//printf("UTC CONO SET\n"); + int i, n, nunits; + + dt->ut_pia = bus->c12 & 07; + dt->ut_units = bus->c12>>3 & 07; + dt->ut_fcn = bus->c12>>6 & 07; + dt->ut_time = bus->c12>>9 & 03; + dt->time_enable = bus->c12>>11 & 1; + dt->ut_rev = bus->c12>>12 & 1; + dt->ut_go = bus->c12>>13 & 1; + dt->ut_jb_done_enable = bus->c12>>14 & 1; + dt->ut_tape_end_enable = bus->c12>>15 & 1; + dt->ut_units_select = bus->c12>>16 & 1; + + // UT CONO SET LONG + // triggers UT START level until end of delay + + // find selected transport unit + n = dt->ut_units == 0 ? 8 : dt->ut_units; + dt->seldx = nil; + nunits = 0; + if(dt->ut_units_select) + for(i = 0; i < 8; i++) + if(dt->dx[i] && dt->dx[i]->unit == n){ + dt->seldx = dt->dx[i]; + nunits++; + } + if(dt->ut_time){ + // wait delay + dt->time_flag = 1; + dt->uteck = 0; + + if(nunits != 1){ + dt->ut_go = 0; + dt->ut_illegal_op = 1; + goto ret; + } + if(dt->ut_btm_switch != UT_WRTM) + dt->ut_illegal_op = 1; + } + + if(!UT_DN){ + if(UT_WRTM) + dt->rw_state = RW_ACTIVE; + else + dt->rw_state = RW_RQ; + } + } + } +ret: + recalc_dt_req(dt); +} + +static void +dtioconnect(Device *dev, IOBus *bus) +{ + Dt551 *dt; + dt = (Dt551*)dev; + dt->bus = bus; + bus->dev[UTC] = (Busdev){ dt, wake_dt, 0 }; + bus->dev[UTS] = (Busdev){ dt, wake_dt, 0 }; +} + +/* Connect a dt control to a data control */ +void +dtconn(Dc136 *dc, Dt551 *dt) +{ + dt->dc = dc; + dc->devp[DEVNO] = dt; +} + +Device* +makedt(int argc, char *argv[]) +{ + Dt551 *dt; + Thread th; + + dt = malloc(sizeof(Dt551)); + memset(dt, 0, sizeof(Dt551)); + + dt->dev.type = dt_ident; + dt->dev.name = ""; + dt->dev.attach = nil; + dt->dev.ioconnect = dtioconnect; + + // should have 30000 cycles per second + th = (Thread){ nil, dtcycle, dt, 1000, 0 }; + addthread(th); + + return &dt->dev; +} diff --git a/emu/init.ini b/emu/init.ini index a54bdea..1fa53d2 100644 --- a/emu/init.ini +++ b/emu/init.ini @@ -4,16 +4,21 @@ mkdev tty tty626 mkdev ptr ptr760 mkdev ptp ptp761 mkdev dc dc136 +mkdev dt0 dt551 +mkdev dx0 dx555 mkdev fmem fmem162 0 mkdev cmem0 cmem161C mem_0 mkdev cmem1 cmem161C mem_1 mkdev cmem2 cmem161C mem_2 mkdev cmem3 cmem161C mem_3 +devconnect dc dt0 +devconnect dt0 dx0 8 ioconnect tty apr ioconnect ptr apr ioconnect ptp apr ioconnect dc apr +ioconnect dt0 apr memconnect fmem 0 apr -1 memconnect cmem0 0 apr 0 memconnect cmem1 0 apr 1 @@ -23,3 +28,4 @@ memconnect cmem3 0 apr 3 attach tty /tmp/6tty attach ptr ../code/test.rim attach ptp ../code/ptp.out +attach dx0 ../test/out.dt6 diff --git a/emu/main.c b/emu/main.c index 1295599..70c8cac 100644 --- a/emu/main.c +++ b/emu/main.c @@ -597,7 +597,7 @@ getdevice(const char *name) } void -printdevices(void) +showdevices(void) { Device *dev; for(dev = devlist; dev; dev = dev->next) @@ -762,8 +762,6 @@ main(int argc, char *argv[]) ptr = (Ptr*)getdevice("ptr"); ptp = (Ptp*)getdevice("ptp"); - printdevices(); - pthread_create(&sim_thread, nil, simthread, apr); pthread_create(&cmd_thread, nil, cmdthread, nil); diff --git a/emu/mem.c b/emu/mem.c index e88058d..7063040 100644 --- a/emu/mem.c +++ b/emu/mem.c @@ -242,8 +242,7 @@ makecoremem(const char *file) core = malloc(sizeof(CMem)); memset(core, 0, sizeof(CMem)); - core->filename = file; - + core->filename = strdup(file); mem = malloc(sizeof(Mem)); mem->dev.type = cmem_ident; mem->dev.name = ""; diff --git a/emu/mem_0 b/emu/mem_0 new file mode 100644 index 0000000..3083bc9 --- /dev/null +++ b/emu/mem_0 @@ -0,0 +1,24 @@ +720200004010 +721200220300 +200740000012 +720340001000 +254000000003 +720000000017 +254000000010 +254000000003 +720200000000 +254200000300 +777600000277 +0 +0 +0 +0 +0 +710600000060 +710740000010 +254000000021 +710440000026 +710740000010 +254000000024 +0 +254000000021 diff --git a/emu/pdp6.h b/emu/pdp6.h index cd3fbf6..77f15fe 100644 --- a/emu/pdp6.h +++ b/emu/pdp6.h @@ -90,7 +90,6 @@ struct Thread extern Thread *threads; void addthread(Thread th); -/* not used yet */ typedef struct Device Device; struct Device { @@ -106,6 +105,7 @@ struct Device extern Device *devlist; void adddevice(Device *dev); Device *getdevice(const char *name); +void showdevices(void); /* @@ -493,5 +493,98 @@ struct Dc136 #define DC_IDENT "dc136" extern char *dc_ident; Device *makedc(int argc, char *argv[]); -void dcgv(Dc136 *dc, word c, int n, int rev); +void dcgv(Dc136 *dc, int n, word c, int rev); word dctk(Dc136 *dc, int n, int rev); + +/* Microtape/DECtape */ + +/* 555 has: + * move tape fwd, rev, auto + * unit selection (1-8) + * motor off, write lock on/off +*/ + +typedef struct Dx555 Dx555; +typedef struct Dt551 Dt551; + +/* Transport 555, + * a half of it really */ +struct Dx555 +{ + Device dev; + + Dt551 *dt; + + int unit; + int wrlock; + + int fd; + uchar *start; + uchar *cur; + uchar *end; +}; +#define DX_IDENT "dx555" +extern char *dx_ident; +Device *makedx(int argc, char *argv[]); +void dxconn(Dt551 *dt, Dx555 *dx, int n); +/* +void dxatt(Dx555 *dx, uchar *buf, int size); +void dxff(Dx555 *dx); +void dxrew(Dx555 *dx); +*/ + +/* Control 551 */ +#define UTC (0210>>2) +#define UTS (0214>>2) +struct Dt551 +{ + Device dev; + IOBus *bus; + + Dc136 *dc; + Dx555 *dx[8]; + Dx555 *seldx; + + /* enable time and mark track writing */ + int ut_btm_switch; + + int ut_pia; + int ut_units; + int ut_units_select; + int ut_fcn; + int ut_time; + int ut_wren; + int ut_go; + int ut_rev; + int ut_tape_end_flag; + int ut_tape_end_enable; + int ut_jb_done_flag; + int ut_jb_done_enable; + int time_enable; + int time_flag; + int ut_illegal_op; + int ut_info_error; + int ut_incomp_block; + + int tmk; /* 9 bits */ + int rwb; /* 6 bits */ + int lb; /* 6 bits */ + int tbm; /* 4 bits */ + int tdata; /* 8 bits */ + int tct; /* 1 bit */ + int utek; /* 6 bits */ + int uteck; + + int rw_state; /* null, rq, active */ + + +// int req; +}; +#define DT_IDENT "dt551" +extern char *dt_ident; +Device *makedt(int argc, char *argv[]); +void dtconn(Dc136 *dc, Dt551 *dt); +/* +void dtcono(Dt551 *dt, word iob); +void dtcycle(Dt551 *dt); +*/ diff --git a/misc/mkpty.c b/misc/mkpty.c index 4cc1281..7c98239 100644 --- a/misc/mkpty.c +++ b/misc/mkpty.c @@ -37,6 +37,7 @@ reset(int fd) #define BAUD 30 struct timespec slp = { 0, 1000*1000*1000 / BAUD }; +struct timespec hupslp = { 0, 100*1000*1000 }; //#define SLEEP nanosleep(&slp, NULL) #define SLEEP @@ -60,6 +61,8 @@ readwrite(int ttyin, int ttyout, int ptyin, int ptyout) } if(n == 0) return; + if(pfd[0].revents & POLLHUP) + nanosleep(&hupslp, NULL); /* read from pty, write to tty */ if(pfd[0].revents & POLLIN){ if(n = read(ptyin, &c, 1), n <= 0) diff --git a/tools/ld6.c b/tools/ld6.c index 9ebb390..7ad5609 100644 --- a/tools/ld6.c +++ b/tools/ld6.c @@ -179,9 +179,13 @@ fixadd(void) continue; } if(a->l) - mem[a->addr] += fw(right(s[1]), 0); + mem[a->addr] = fw( + left(mem[a->addr]) + right(s[1]), + right(mem[a->addr])); else - mem[a->addr] += fw(0, right(s[1])); + mem[a->addr] = fw( + left(mem[a->addr]), + right(mem[a->addr]) + right(s[1])); } } @@ -299,9 +303,13 @@ readblock(int doreloc) reloc <<= 2; if(doreloc){ if(bits & 1) - block[i] += fw(0, rel); + block[i] = fw( + left(block[i]), + right(block[i]) + rel); if(bits & 2) - block[i] += fw(rel, 0); + block[i] = fw( + left(block[i]) + rel, + right(block[i])); } } } @@ -570,7 +578,7 @@ main(int argc, char *argv[]) } fixadd(); -// dumpsym(); + dumpsym(); checkundef(); if(error)