diff --git a/newemu/Makefile b/newemu/Makefile index 6ff5c22..ac9db37 100644 --- a/newemu/Makefile +++ b/newemu/Makefile @@ -1,10 +1,10 @@ -INC= -LIBS=-lpthread -lm -lSDL2 +INC=`pkg-config lua --cflags` +LIBS=-lpthread -lm -lSDL2 `pkg-config lua --libs` #CFLAGS=-Wall -Wextra -g -O3 #CFLAGS=-g -O3 -mcpu=cortex-a53 -mtune=cortex-a53 CFLAGS=-g -Wall -Wno-parentheses -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 +pdp6: main.c panel6.c pdp6.c netmem.c tty.c pt.c dis340.c dc.c ut.c ge.c audio.c ttytelnet.c common.c lua.c cc $(CFLAGS) -o $@ $^ $(INC) $(LIBS) run: pdp6 diff --git a/newemu/common.c b/newemu/common.c index d3dea97..56fd5de 100644 --- a/newemu/common.c +++ b/newemu/common.c @@ -15,6 +15,8 @@ #include #include #include +#include + #include "common.h" @@ -58,6 +60,35 @@ readn(int fd, void *data, int n) return 0; } +int +socketlisten(int port) +{ + int x; + struct sockaddr_in server; + int fd; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if(fd < 0) { + perror("error: socket"); + return -1; + } + + x = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *)&x, sizeof x); + + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons(port); + if(bind(fd, (struct sockaddr*)&server, sizeof(server)) < 0) { + close(fd); + perror("error: bind"); + return -1; + } + listen(fd, 1); + return fd; +} + int dial(const char *host, int port) { @@ -97,27 +128,12 @@ serve1(int port) { int sockfd, confd; socklen_t len; - struct sockaddr_in server, client; - int x; + struct sockaddr_in client; - sockfd = socket(AF_INET, SOCK_STREAM, 0); - if(sockfd < 0){ - perror("error: socket"); + sockfd = socketlisten(port); + if(sockfd < 0) return -1; - } - x = 1; - setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&x, sizeof x); - - memset(&server, 0, sizeof(server)); - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; - server.sin_port = htons(port); - if(bind(sockfd, (struct sockaddr*)&server, sizeof(server)) < 0){ - perror("error: bind"); - return -1; - } - listen(sockfd, 5); len = sizeof(client); confd = accept(sockfd, (struct sockaddr*)&client, &len); close(sockfd); @@ -126,6 +142,50 @@ serve1(int port) perror("error: accept"); return -1; } + +// listen on multiple ports +void +serveN(struct PortHandler *ports, int nports, void *arg) +{ + int i; + int confd; + struct pollfd pfds[100]; + struct sockaddr_in client; + socklen_t len; + + // create and listen on sockets for the given ports + for(i = 0; i < nports; i++) { + pfds[i].revents = 0; + pfds[i].events = 0; + pfds[i].fd = socketlisten(ports[i].port); + if(pfds[i].fd >= 0) + pfds[i].events = POLLIN; + } + + // now poll to accept connections and hand off to handle function + for(;;) { + int ret = poll(pfds, nports, -1); + if(ret < 0) + break; + if(ret == 0) + continue; + + for(i = 0; i < nports; i++) { + if(pfds[i].revents & POLLIN) { + len = sizeof(client); + confd = accept(pfds[i].fd, (struct sockaddr*)&client, &len); + if(confd >= 0) + ports[i].handle(confd, arg); + } else if(pfds[i].revents) { + printf("weird stuff on port %d\n", ports[i].port); + } + } + } + + for(i = 0; i < nports; i++) + close(pfds[i].fd); +} + void nodelay(int fd) { @@ -255,8 +315,6 @@ split(char *line, int *pargc) } -#include - struct FDmsg { int msg; diff --git a/newemu/common.h b/newemu/common.h index 6c26b09..a076d73 100644 --- a/newemu/common.h +++ b/newemu/common.h @@ -22,6 +22,12 @@ int hasinput(int fd); int readn(int fd, void *data, int n); int dial(const char *host, int port); int serve1(int port); +struct PortHandler { + int port; + void (*handle)(int fd, void *arg); +}; +void serveN(struct PortHandler *ports, int nports, void *arg); + void nodelay(int fd); void *createseg(const char *name, size_t sz); diff --git a/newemu/dis340.c b/newemu/dis340.c index 6739adf..e540e02 100644 --- a/newemu/dis340.c +++ b/newemu/dis340.c @@ -63,6 +63,7 @@ struct Dis340 int pnt; u32 cmdbuf[128]; u32 ncmds; + u32 agetime; }; #define LDB(p, s, w) ((w)>>(p) & (1<<(s))-1) @@ -71,54 +72,67 @@ static void calc_dis_req(PDP6 *pdp, Dis340 *dis); static void -addcmd(Dis340 *dis, u32 cmd) +flushdis(Dis340 *d) { - dis->cmdbuf[dis->ncmds++] = cmd; - if(dis->ncmds == nelem(dis->cmdbuf)) { - int n = write(dis->fd.fd, dis->cmdbuf, sizeof(dis->cmdbuf)); - dis->ncmds = 0; - if(n < (int)sizeof(dis->cmdbuf)) { -// TODO: close fd - dis->fd.fd = -1; - } - } + int sz = d->ncmds*sizeof(d->cmdbuf[0]); + int n = write(d->fd.fd, d->cmdbuf, sz); + d->ncmds = 0; + if(n < sz) + closefd(&d->fd); } static void -agedisplay(Dis340 *dis) +discmd(Dis340 *d, u32 cmd) { - if(dis->fd.fd < 0) + d->cmdbuf[d->ncmds++] = cmd; + if(d->ncmds == nelem(d->cmdbuf)) + flushdis(d); +} + +static void +agedisplay(Dis340 *d) +{ + if(d->fd.fd < 0) return; - u32 cmd = 510<<23; - assert(dis->lasttime <= dis->simtime); - u64 dt = (dis->simtime - dis->lasttime)/1000; - while(dt >= 510) { - dis->lasttime += 510*1000; - addcmd(dis, cmd); - dt = (dis->simtime - dis->lasttime)/1000; + int ival = d->agetime; + assert(d->lasttime <= d->simtime); + u64 dt = (d->simtime - d->lasttime)/1000; + if(dt >= ival) { + discmd(d, 511<<23); + discmd(d, dt); + d->lasttime = d->simtime; + flushdis(d); + if(d->agetime < 1000*1000) + d->agetime += d->agetime/10; } } static void intensify(Dis340 *dis) { + // need to make sure dt field doesn't overflow cmd + dis->agetime = 510; + agedisplay(dis); + // reset age interval for every point shown + dis->agetime = 50*1000; + if(dis->fd.fd < 0) + return; + if(dis->pen && dis->lp_enable) { int dx = dis->penx - dis->x; int dy = dis->peny - dis->y; if(dx*dx + dy*dy <= 4) dis->lp_find = 1; } - if(dis->fd.fd >= 0){ - agedisplay(dis); - u32 cmd; - cmd = dis->x; - cmd |= dis->y<<10; - cmd |= dis->i<<20; - int dt = (dis->simtime - dis->lasttime)/1000; - cmd |= dt<<23; - dis->lasttime = dis->simtime; - addcmd(dis, cmd); - } + + int dt = (dis->simtime - dis->lasttime)/1000; + u32 cmd; + cmd = dis->x; + cmd |= dis->y<<10; + cmd |= dis->i<<20; + cmd |= dt<<23; + dis->lasttime = dis->simtime; + discmd(dis, cmd); } enum { @@ -646,6 +660,12 @@ dis_connect(Dis340 *dis, int fd) { if(dis->fd.fd >= 0) closefd(&dis->fd); - dis->fd.fd = fd; - waitfd(&dis->fd); + else { + nodelay(fd); + dis->fd.fd = fd; + dis->fd.id = -1; + waitfd(&dis->fd); + dis->lasttime = dis->simtime; + dis->agetime = 50*1000; + } } diff --git a/newemu/init.lua b/newemu/init.lua new file mode 100644 index 0000000..354d536 --- /dev/null +++ b/newemu/init.lua @@ -0,0 +1,44 @@ +function o(n) + return tonumber(tostring(n), 8) +end +function fw(w) + local l = (w >> 18) & o(777777) + local r = w & o(777777) + return oct(l,6) .. ",," .. oct(r,6) +end + +--uxmount(1, "t/system.dtr"); +uxmount(1, "t/systemdis.dtr"); +uxmount(2, "t/its138.dtr"); +uxmount(3, "t/music.dtr"); + + +-- MACDMP RIM loader +d(o(00), o(255000000000), 0) +d(o(01), o(205000255000), 0) +d(o(02), o(700200635550), 0) +d(o(03), o(700600011577), 0) +d(o(04), o(721200223110), 0) +d(o(05), o(720200004010), 0) +d(o(06), o(720340001000), 0) +d(o(07), o(254000000006), 0) +d(o(10), o(720040000013), 0) +d(o(11), o(345540000006), 0) +d(o(12), o(602540777777), 0) +d(o(13), o(000000000013), 0) +d(o(14), o(254000000006), 0) + +-- PTR RIM loader +d(o(20), o(710600000060)) +d(o(21), o(710740000010)) +d(o(22), o(254000000021)) +d(o(23), o(710440000026)) +d(o(24), o(710740000010)) +d(o(25), o(254000000024)) +d(o(27), o(254000000021)) + +--setpc(readmemory("t/ddt.16k.oct")) + +ptrmount("t/hello.rim") +ptpmount("out.ptp") +ttycon() diff --git a/newemu/lua.c b/newemu/lua.c new file mode 100644 index 0000000..8b98b1d --- /dev/null +++ b/newemu/lua.c @@ -0,0 +1,268 @@ +#include "common.h" +#include "pdp6.h" + +#include +#include + +#include +#include +#include + +lua_State *L; + +// initdevs(pdp); +// attach_ptp(pdp); +// attach_ptr(pdp); +// attach_tty(pdp); +// dis = attach_dis(pdp); +// Dc136 *dc = attach_dc(pdp); +// Ut551 *ut = attach_ut(pdp, dc); +// ux1 = attach_ux(ut, 1); +// ux2 = attach_ux(ut, 2); +// ux3 = attach_ux(ut, 3); +// ux4 = attach_ux(ut, 4); +// // stub for ITS +// attach_ge(pdp); + + +// this is not ideal... +extern Word memory[01000000]; +extern Word fmem[020]; +extern Dis340 *dis; +extern Ux555 *ux1; +extern Ux555 *ux2; +extern Ux555 *ux3; +extern Ux555 *ux4; + +static PDP6 *pdp; + +// things we would like to be able to do: + +// pdp->netmem_fd.fd = dial("maya", 20006); +// if(pdp->netmem_fd.fd >= 0) +// printf("netmem connected\n"); +// waitfd(&pdp->netmem_fd); + + +// fix the language a bit +static int +L_oct(lua_State *L) +{ + lua_Integer n = luaL_checkinteger(L, 1); + int pad = luaL_optinteger(L, 2, -1); + char buf[100]; + if(pad < 0) + snprintf(buf, sizeof(buf), "%0llo", (unsigned long long)n); + else + snprintf(buf, sizeof(buf), "%0*llo", pad, (unsigned long long)n); + lua_pushstring(L, buf); + return 1; +} + +static int +L_examine(lua_State *L) +{ + lua_Integer addr = luaL_checkinteger(L, 1); + int fast = luaL_optinteger(L, 2, 1); + if(addr >= 0) { + if(addr < 020 && fast) + lua_pushinteger(L, fmem[addr]); + else if(addr < 01000000) + lua_pushinteger(L, memory[addr]); + else + lua_pushinteger(L, 0); + } else + lua_pushinteger(L, 0); + return 1; +} + +static int +L_deposit(lua_State *L) +{ + lua_Integer addr = luaL_checkinteger(L, 1); + lua_Integer word = luaL_checkinteger(L, 2); + int fast = luaL_optinteger(L, 3, 1); + if(addr >= 0) { + if(addr < 020 && fast) + fmem[addr] = word; + else if(addr < 01000000) + memory[addr] = word; + } + return 0; +} + +Hword readmemory(const char *path); + +static int +L_readmemory(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + int start = readmemory(path); + lua_pushinteger(L, start); + return 1; +} + +static int +L_setpc(lua_State *L) +{ + int pc = luaL_checkinteger(L, 1); + pdp->pc = pc & 0777777; + return 0; +} + +static int +L_ttycon(lua_State *L) +{ + const char *path = luaL_optstring(L, 1, "/tmp/tty"); + if(pdp->tty_fd.fd >= 0) + closefd(&pdp->tty_fd); + if((pdp->tty_fd.fd = open(path, O_RDWR)) < 0) + printf("couldn't open %s\n", path); + waitfd(&pdp->tty_fd); + return 0; +} + +static int +L_ptrmount(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + int fd = open(path, O_RDONLY); + if(fd < 0) + printf("couldn't open %s\n", path); + else + ptrmount(pdp, fd); + return 0; +} + +static int +L_ptrunmount(lua_State *L) +{ + ptrunmount(pdp); + return 0; +} + +static int +L_ptpmount(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + int fd = open(path, O_CREAT|O_WRONLY|O_TRUNC, 0644); + if(fd < 0) + printf("couldn't open %s\n", path); + else + ptpmount(pdp, fd); + return 0; +} + +static int +L_ptpunmount(lua_State *L) +{ + ptpunmount(pdp); + return 0; +} + +static int +L_uxmount(lua_State *L) +{ + int unit = luaL_checkinteger(L, 1); + const char *path = luaL_checkstring(L, 2); + + Ux555 *ux[] = { ux1, ux2, ux3, ux4 }; + if(0 < unit && unit <= 4) + uxmount(ux[unit-1], path); + return 0; +} + +static int +L_uxunmount(lua_State *L) +{ + int unit = luaL_checkinteger(L, 1); + + Ux555 *ux[] = { ux1, ux2, ux3, ux4 }; + if(0 < unit && unit <= 4) + uxunmount(ux[unit-1]); + return 0; +} + +static int +L_discon(lua_State *L) +{ + const char *host = luaL_optstring(L, 1, "localhost"); + int port = luaL_optinteger(L, 2, 3400); + int dis_fd = dial(host, port); + if(dis_fd < 0) + printf("can't open display\n"); + dis_connect(dis, dis_fd); + return 0; +} + +void +doline(char *line) +{ + char *retline = nil; + asprintf(&retline, "return %s", line); + + int status = luaL_loadstring(L, retline); + free(retline); + + if(status != LUA_OK) { + lua_pop(L, 1); + status = luaL_loadstring(L, line); + } + if(status != LUA_OK) { + fprintf(stderr, "error: %s\n", lua_tostring(L, -1)); + return; + } + status = lua_pcall(L, 0, LUA_MULTRET, 0); + + const char *s; + int n = lua_gettop(L); + for(int i = 1; i <= n; i++) { + if(lua_type(L, i) == LUA_TNUMBER) { + lua_getglobal(L, "pnum"); + lua_pushvalue(L, i); + lua_pcall(L, 1, 1, 0); + s = lua_tostring(L, -1); + printf("%s%s", i > 1 ? "\t" : "", s); + lua_pop(L, 1); + } else { + s = luaL_tolstring(L, i, nil); + printf("%s%s", i > 1 ? "\t" : "", s); + lua_pop(L, 1); + } + } + if (n > 0) { + lua_pushvalue(L, n); + lua_setglobal(L, "_"); + printf("\n"); + } + lua_settop(L, 0); +} + +void +initlua(PDP6 *apdp) +{ + L = luaL_newstate(); + luaL_openlibs(L); + + pdp = apdp; + lua_register(L, "oct", L_oct); + lua_register(L, "pnum", L_oct); + lua_register(L, "e", L_examine); + lua_register(L, "d", L_deposit); + lua_register(L, "readmemory", L_readmemory); + lua_register(L, "setpc", L_setpc); + lua_register(L, "ttycon", L_ttycon); + lua_register(L, "ptrmount", L_ptrmount); + lua_register(L, "ptrunmount", L_ptrunmount); + lua_register(L, "ptpmount", L_ptpmount); + lua_register(L, "ptpunmount", L_ptpunmount); + lua_register(L, "uxmount", L_uxmount); + lua_register(L, "uxunmount", L_uxunmount); + lua_register(L, "discon", L_discon); + + if(luaL_dofile(L, "init.lua") != LUA_OK) { + fprintf(stderr, "error: %s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + return; + } +} diff --git a/newemu/main.c b/newemu/main.c index c43bfd8..fea19eb 100644 --- a/newemu/main.c +++ b/newemu/main.c @@ -5,6 +5,9 @@ #include #include #include +#include + +#include #include @@ -46,7 +49,7 @@ readmemory(const char *path) FILE *f; f = fopen(path, "r"); - if(f == NULL) { + if(f == nil) { printf("couldn't open file %s\n", path); return 0; } @@ -68,7 +71,54 @@ readmemory(const char *path) return pc; } -const bool throttle = 1; +void +readmem(const char *file, Word *mem, Hword size) +{ + FILE *f; + char buf[100], *s; + Hword a; + Word w; + if(f = fopen(file, "r"), f == nil) + return; + a = 0; + while(s = fgets(buf, 100, f)){ + while(*s){ + if(*s == ';') + break; + else if('0' <= *s && *s <= '7'){ + w = strtoull(s, &s, 8); + if(*s == ':' || *s == '/'){ + a = w; + s++; + }else if(a < size) + mem[a++] = w; + else + fprintf(stderr, "Address out of range: %o\n", a++); + }else + s++; + } + } + fclose(f); +} + +void +dumpmem(const char *file, Word *mem, Hword size) +{ + FILE *f; + Hword a; + + if(f = fopen("coremem", "w"), f == nil) + return; + + for(a = 0; a < size; a++) + if(mem[a] != 0){ + fprintf(f, "%06o/ ", a); + fprintf(f, "%012llo\n", mem[a]); + } + fclose(f); +} + +const bool dothrottle = 1; // TODO: this sucks Dis340 *dis; @@ -80,8 +130,8 @@ Ux555 *ux4; void configmachine(PDP6 *pdp) { - uxmount(ux1, "t/systemdis.dtr"); -// uxmount(ux1, "t/system.dtr"); +// uxmount(ux1, "t/systemdis.dtr"); + uxmount(ux1, "t/system.dtr"); // uxmount(ux2, "t/syseng.dtr"); uxmount(ux2, "t/its138.dtr"); // uxmount(ux3, "t/foo.dtr"); @@ -117,8 +167,8 @@ configmachine(PDP6 *pdp) // assumes reader motor will be off // memory[0101] |= I(0, 1, 0, 0, 0); // disable device tests in part3 // part4: start with 1 in switches, flip back to 0 at some point -// pdp->pc = readmemory("t/ddt.16k.oct"); - pdp->pc = readmemory("t/ddt.d16k.oct"); // needs moby + pdp->pc = readmemory("t/ddt.16k.oct"); +// pdp->pc = readmemory("t/ddt.d16k.oct"); // needs moby // pdp->pc = readmemory("t/nts.lisp.u16k.oct"); // pdp->pc = readmemory("t/nts.teco6.u256k.oct"); // pdp->pc = readmemory("t/spcwar.oct"); @@ -151,13 +201,44 @@ initemu(PDP6 *pdp) attach_ge(pdp); - srand(time(NULL)); + srand(time(nil)); pwrclr(pdp); cycle_io(pdp, 0); if(domusic) initmusic(); } + +void prompt(void) { printf("> "); fflush(stdout); } +void +cli(PDP6 *pdp, FD *fd) +{ + char line[1024]; + int n; + + n = read(fd->fd, line, sizeof(line)); + if(n <= 0) { + printf("\n"); + exit(0); + } + if(n > 0 && n < sizeof(line)) { + line[n] = '\0'; +void doline(char *line); + doline(line); + prompt(); + waitfd(fd); + } +} + +void +throttle(void) +{ + while(realtime < simtime) { + usleep(1000); + realtime = gettime(); + } +} + void emu(PDP6 *pdp, Panel *panel) { @@ -167,6 +248,12 @@ emu(PDP6 *pdp, Panel *panel) updateswitches(pdp, panel); + FD clifd; + clifd.id = -1; + clifd.fd = 0; + prompt(); + waitfd(&clifd); + inittime(); simtime = 0; //gettime(); pdp->clk_timer = 0; @@ -203,7 +290,8 @@ stopmusic(); cycle_io(pdp, 1); handlenetmem(pdp); - if(throttle) while(realtime < simtime) realtime = gettime(); + if(dothrottle) throttle(); +while(realtime < simtime) realtime = gettime(); } else { stopmusic(); if(power) @@ -211,17 +299,57 @@ stopmusic(); lightsoff(panel); - if(throttle) + if(dothrottle) simtime = gettime(); else simtime += 1500; cycle_io(pdp, 0); } -// cli(pdp); + if(clifd.ready) + cli(pdp, &clifd); } } +void +handledis(int fd, void *arg) +{ +// PDP6 *pdp = (PDP6*)arg; + nodelay(fd); + dis_connect(dis, fd); +} + +void +handleptr(int fd, void *arg) +{ + PDP6 *pdp = (PDP6*)arg; + nodelay(fd); + ptrmount(pdp, fd); +} + +void +handleptp(int fd, void *arg) +{ + PDP6 *pdp = (PDP6*)arg; + nodelay(fd); + ptpmount(pdp, fd); +} + +void* +netthread(void *arg) +{ + struct PortHandler ports[] = { +// { 1640, handlenetcmd }, +// // 1041 is teletype + { 1642, handleptr }, + { 1643, handleptp }, + { 3400, handledis }, + }; + serveN(ports, nelem(ports), arg); + return nil; +} + +/* char *argv0; void usage(void) @@ -229,6 +357,15 @@ usage(void) fprintf(stderr, "usage: %s [-h host] [-p port]\n", argv0); exit(1); } +*/ + +static void +cleanup(void *arg) +{ + Panel *panel = (Panel*)arg; + lightsoff(panel); + dumpmem("coremem", memory, 01000000); +} void inthandler(int sig) @@ -239,9 +376,11 @@ inthandler(int sig) int main(int argc, char *argv[]) { + pthread_t th; Panel *panel; PDP6 pdp6, *pdp = &pdp6; +/* const char *host; int port; @@ -257,6 +396,7 @@ main(int argc, char *argv[]) default: usage(); } ARGEND; +*/ panel = getpanel(); if(panel == nil) { @@ -268,36 +408,61 @@ main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); signal(SIGINT, inthandler); - addcleanup((void (*)(void*))lightsoff, panel); + addcleanup(cleanup, panel); initemu(pdp); - configmachine(pdp); + readmem("coremem", memory, 01000000); startpolling(); +// now in lua +// configmachine(pdp); + +/* int dis_fd = dial(host, port); if(dis_fd < 0) printf("can't open display\n"); nodelay(dis_fd); dis_connect(dis, dis_fd); +*/ +/* const char *tape = "t/hello.rim"; // const char *tape = "t/ptp_test.rim"; // const char *tape = "t/bla.txt"; pdp->ptr_fd.fd = open(tape, O_RDONLY); waitfd(&pdp->ptr_fd); - pdp->ptp_fd = open("out.ptp", O_CREAT|O_WRONLY|O_TRUNC, 0644); + pdp->ptp_fd = open("out.ptp", O_CREAT|O_WRONLY|O_TRUNC, 0644); +*/ + +/* pdp->tty_fd.fd = open("/tmp/tty", O_RDWR); if(pdp->tty_fd.fd < 0) 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); +*/ + +void initlua(PDP6 *pdp); + initlua(pdp); + + pthread_create(&th, nil, netthread, pdp); + int fd[2]; + socketpair(AF_UNIX, SOCK_STREAM, 0, fd); + pdp->tty_fd.fd = fd[0]; + waitfd(&pdp->tty_fd); +void ttytelnet(int port, int fd); + ttytelnet(1641, fd[1]); emu(pdp, panel); return 0; // can't happen diff --git a/newemu/pdp6.c b/newemu/pdp6.c index dfaf6ae..9df4a4b 100644 --- a/newemu/pdp6.c +++ b/newemu/pdp6.c @@ -4,7 +4,6 @@ #include #include -#include #include diff --git a/newemu/pdp6.h b/newemu/pdp6.h index 71faea4..893ef74 100644 --- a/newemu/pdp6.h +++ b/newemu/pdp6.h @@ -279,8 +279,12 @@ void cycle_io(PDP6 *pdp, int pwr); void setreq(PDP6 *pdp, IOdev *dev, u8 req); void attach_ptp(PDP6 *pdp); +void ptpunmount(PDP6 *pdp); +void ptpmount(PDP6 *pdp, int fd); void ptr_set_motor(PDP6 *pdp, int state); void attach_ptr(PDP6 *pdp); +void ptrunmount(PDP6 *pdp); +void ptrmount(PDP6 *pdp, int fd); void attach_tty(PDP6 *pdp); diff --git a/newemu/pt.c b/newemu/pt.c index c306521..2d24aeb 100644 --- a/newemu/pt.c +++ b/newemu/pt.c @@ -129,9 +129,25 @@ calc_ptp_req(PDP6 *pdp) void attach_ptp(PDP6 *pdp) { + pdp->ptp_fd = -1; installdev(pdp, &ptp_dev); } +void +ptpunmount(PDP6 *pdp) +{ + if(pdp->ptp_fd >= 0) + close(pdp->ptp_fd); + pdp->ptp_fd = -1; +} + +void +ptpmount(PDP6 *pdp, int fd) +{ + ptpunmount(pdp); + pdp->ptp_fd = fd; +} + /* PTR */ static void calc_ptr_req(PDP6 *pdp); @@ -223,8 +239,13 @@ cycle_ptr(PDP6 *pdp, IOdev *dev, int pwr) if(!pdp->ptr_fd.ready) return; - if(read(pdp->ptr_fd.fd, &c, 1) <= 0) + if(read(pdp->ptr_fd.fd, &c, 1) <= 0) { + closefd(&pdp->ptr_fd); return; + } + // write back in case this is over a socket + // and we need to synchronize + write(pdp->ptr_fd.fd, &c, 1); waitfd(&pdp->ptr_fd); if(pdp->ptr_busy && (c & 0200 || !pdp->ptr_b)) { // PTR STROBE @@ -265,3 +286,18 @@ attach_ptr(PDP6 *pdp) installdev(pdp, &ptr_dev); } + +void +ptrunmount(PDP6 *pdp) +{ + if(pdp->ptr_fd.fd >= 0) + closefd(&pdp->ptr_fd); +} + +void +ptrmount(PDP6 *pdp, int fd) +{ + ptrunmount(pdp); + pdp->ptr_fd.fd = fd; + waitfd(&pdp->ptr_fd); +} diff --git a/newemu/tty.c b/newemu/tty.c index 82499b5..5a51290 100644 --- a/newemu/tty.c +++ b/newemu/tty.c @@ -129,7 +129,8 @@ attach_tty(PDP6 *pdp) pdp->tty_fd.fd = -1; pdp->tty_fd.id = -1; - pdp->tty_baud = 110; +// pdp->tty_baud = 110; + pdp->tty_baud = 300; pdp->tty_dly = 1000000000 / pdp->tty_baud; installdev(pdp, &tty_dev); }