From cbcdd6ba2961d8d842ebf3160b696c69eb1198a7 Mon Sep 17 00:00:00 2001 From: aap Date: Tue, 23 Apr 2024 17:50:11 +0200 Subject: [PATCH] newemu: shared memory implemented. two new message types to make caching possible --- newemu/Makefile | 2 +- newemu/common.c | 15 +++++ newemu/common.h | 1 + newemu/dis340.c | 10 +++ newemu/main.c | 7 +++ newemu/netmem.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ newemu/pdp6.c | 7 +++ newemu/pdp6.h | 4 ++ 8 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 newemu/netmem.c diff --git a/newemu/Makefile b/newemu/Makefile index ec5576c..6ff5c22 100644 --- a/newemu/Makefile +++ b/newemu/Makefile @@ -4,7 +4,7 @@ LIBS=-lpthread -lm -lSDL2 #CFLAGS=-g -O3 -mcpu=cortex-a53 -mtune=cortex-a53 CFLAGS=-g -Wall -Wno-parentheses -pdp6: main.c panel6.c pdp6.c tty.c pt.c dis340.c dc.c ut.c ge.c audio.c common.c +pdp6: main.c panel6.c pdp6.c netmem.c tty.c pt.c dis340.c dc.c ut.c ge.c audio.c common.c cc $(CFLAGS) -o $@ $^ $(INC) $(LIBS) run: pdp6 diff --git a/newemu/common.c b/newemu/common.c index e7f6379..1389b64 100644 --- a/newemu/common.c +++ b/newemu/common.c @@ -43,6 +43,21 @@ hasinput(int fd) return select(fd+1, &fds, NULL, NULL, &timeout) > 0; } +int +readn(int fd, void *data, int n) +{ + int m; + + while(n > 0) { + m = read(fd, data, n); + if(m <= 0) + return -1; + data += m; + n -= m; + } + return 0; +} + int dial(const char *host, int port) { diff --git a/newemu/common.h b/newemu/common.h index dd88b0f..6c26b09 100644 --- a/newemu/common.h +++ b/newemu/common.h @@ -19,6 +19,7 @@ typedef int8_t i8; void panic(const char *fmt, ...); int hasinput(int fd); +int readn(int fd, void *data, int n); int dial(const char *host, int port); int serve1(int port); void nodelay(int fd); diff --git a/newemu/dis340.c b/newemu/dis340.c index d8a7419..b03c162 100644 --- a/newemu/dis340.c +++ b/newemu/dis340.c @@ -613,7 +613,16 @@ handle_joy(PDP6 *pdp, IOdev *dev, int cmd) break; } } +static void +handle_ojoy(PDP6 *pdp, IOdev *dev, int cmd) +{ + switch(cmd) { + case IOB_DATAI: + break; + } +} static IOdev joy_dev = { 0, 0420, nil, handle_joy, nil }; +static IOdev ojoy_dev = { 0, 0724, nil, handle_ojoy, nil }; Dis340* attach_dis(PDP6 *pdp) @@ -624,6 +633,7 @@ attach_dis(PDP6 *pdp) installdev(pdp, &dis_dev); installdev(pdp, &joy_dev); + installdev(pdp, &ojoy_dev); return &dis; } diff --git a/newemu/main.c b/newemu/main.c index 0d8d703..c43bfd8 100644 --- a/newemu/main.c +++ b/newemu/main.c @@ -201,6 +201,7 @@ stopmusic(); updatelights(pdp, panel); cycle_io(pdp, 1); + handlenetmem(pdp); if(throttle) while(realtime < simtime) realtime = gettime(); } else { @@ -292,6 +293,12 @@ main(int argc, char *argv[]) printf("can't open /tmp/tty\n"); waitfd(&pdp->tty_fd); +// pdp->netmem_fd.fd = dial("maya", 10006); + pdp->netmem_fd.fd = dial("maya", 20006); + if(pdp->netmem_fd.fd >= 0) + printf("netmem connected\n"); + waitfd(&pdp->netmem_fd); + emu(pdp, panel); return 0; // can't happen } diff --git a/newemu/netmem.c b/newemu/netmem.c new file mode 100644 index 0000000..89f0f37 --- /dev/null +++ b/newemu/netmem.c @@ -0,0 +1,159 @@ +#include "common.h" +#include "pdp6.h" + +#include + +extern Word memory[01000000]; + +static u8* +putu16(u8 *p, u16 n) +{ + *p++ = n>>8; + *p++ = n; + return p; +} + +static u8* +getu16(u8 *p, u16 *wp) +{ + u16 w; + w = p[0]; + w <<= 8; w |= p[1]; + *wp = w; + return p+2; +} + +static u8* +putword(u8 *p, u64 w) +{ + *p++ = w; + *p++ = w>>8; + *p++ = w>>16; + *p++ = w>>24; + *p++ = w>>32; + return p; +} + +static u8* +getword(u8 *p, u64 *wp) +{ + u64 w; + w = p[4]; + w <<= 8; w |= p[3]; + w <<= 8; w |= p[2]; + w <<= 8; w |= p[1]; + w <<= 8; w |= p[0]; + *wp = w & 0777777777777; + return p+5; +} + +static u8* +getaddr(u8 *p, u32 *wp) +{ + u32 w; + w = p[2]; + w <<= 8; w |= p[1]; + w <<= 8; w |= p[0]; + *wp = w & 0777777; + return p+3; +} + +#define log(...) + +void +handlenetmem(PDP6 *pdp) +{ + static u8 buf[6 + 512*5]; + u8 *p; + u16 len, n; + u32 a; + u64 d; + enum { + WRRQ = 1, + RDRQ, + ACK, + ERR, + RDNRQ, + WRNRQ, + }; + + if(pdp->mem_busy || pdp->netmem_fd.fd < 0 || !pdp->netmem_fd.ready) + return; + + if(readn(pdp->netmem_fd.fd, buf, 2)) + return; + getu16(buf, &len); + if(len > sizeof(buf)) { + printf("netmem botch, closing\n"); + closefd(&pdp->netmem_fd); + return; + } + + memset(buf, 0, sizeof(buf)); + readn(pdp->netmem_fd.fd, buf, len); + + p = getaddr(&buf[1], &a); + + switch(buf[0]) { + case WRRQ: + p = getword(p, &d); + memory[a] = d; + log("write %06o %012llo\n", a, d); + len = 1; + p = putu16(buf, len); + *p++ = ACK; + write(pdp->netmem_fd.fd, buf, len+2); + break; + + case RDRQ: + d = memory[a]; + log("read %06o %012llo\n", a, d); + len = 6; + p = putu16(buf, len); + *p++ = ACK; + p = putword(p, d); + write(pdp->netmem_fd.fd, buf, len+2); + break; + + case RDNRQ: + p = getu16(p, &n); + assert(n <= 512); + + log("read N %d %06o\n", n, a); + len = 1 + n*5; + p = putu16(buf, len); + *p++ = ACK; + while(n--) { + d = memory[a]; +// log("read %06o %012llo\n", a, d); + p = putword(p, d); + a = (a+1) & 0777777; + } + + write(pdp->netmem_fd.fd, buf, len+2); + break; + + case WRNRQ: + p = getu16(p, &n); + assert(n <= 512); + + log("write N %d %06o\n", n, a); + while(n--) { + p = getword(p, &d); + memory[a] = d; +// log("write %06o %012llo\n", a, d); + a = (a+1) & 0777777; + } + + len = 1; + p = putu16(buf, len); + *p++ = ACK; + write(pdp->netmem_fd.fd, buf, len+2); + break; + + default: + printf("unknown msg %d\n", buf[0]); + } + + waitfd(&pdp->netmem_fd); +} diff --git a/newemu/pdp6.c b/newemu/pdp6.c index f63d19c..dfaf6ae 100644 --- a/newemu/pdp6.c +++ b/newemu/pdp6.c @@ -405,6 +405,7 @@ trace("WR\t\t%06o %06o %d <- %012llo\n", MA, pdp->rla, pdp->key_rim_sbr, MB); void rdwrrq(PDP6 *pdp, int ret) { + pdp->mem_busy = 1; rdrq(pdp, ret); } @@ -412,6 +413,7 @@ void wrrs(PDP6 *pdp, int ret) { wrrq(pdp, ret); + pdp->mem_busy = 0; } @@ -429,6 +431,9 @@ initdevs(PDP6 *pdp) numdevs = 0; installdev(pdp, &cpa_dev); installdev(pdp, &pi_dev); + + pdp->netmem_fd.fd = -1; + pdp->netmem_fd.id = -1; } void @@ -463,6 +468,8 @@ pwrclr(PDP6 *pdp) pdp->run = 0; mr_start(pdp); mr_clr(pdp); + + pdp->mem_busy = 0; } void diff --git a/newemu/pdp6.h b/newemu/pdp6.h index 0e4623a..71faea4 100644 --- a/newemu/pdp6.h +++ b/newemu/pdp6.h @@ -164,6 +164,7 @@ struct PDP6 bool ex_ill_op; Hword pr, rlr, rla; + bool mem_busy; bool mc_rq, mc_rd, mc_wr; bool cpa_iot_user; @@ -230,6 +231,8 @@ struct PDP6 u64 tto_timer; + FD netmem_fd; + bool dotrace; u64 clk_timer; @@ -246,6 +249,7 @@ void pwrclr(PDP6 *pdp); void kt0(PDP6 *pdp); void cycle(PDP6 *pdp); void clr_run(PDP6 *pdp); +void handlenetmem(PDP6 *pdp); extern u64 simtime; extern u64 realtime;