1
0
mirror of https://github.com/aap/pdp6.git synced 2026-03-23 01:16:30 +00:00

lua interface for new pdp6 emulator

This commit is contained in:
aap
2026-03-19 16:50:15 +01:00
parent 7534d72963
commit 2645ed907d
11 changed files with 672 additions and 71 deletions

View File

@@ -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

View File

@@ -15,6 +15,8 @@
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <poll.h>
#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 <poll.h>
struct FDmsg
{
int msg;

View File

@@ -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);

View File

@@ -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;
}
}

44
newemu/init.lua Normal file
View File

@@ -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()

268
newemu/lua.c Normal file
View File

@@ -0,0 +1,268 @@
#include "common.h"
#include "pdp6.h"
#include <unistd.h>
#include <fcntl.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
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;
}
}

View File

@@ -5,6 +5,9 @@
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <pthread.h>
#include <sys/socket.h>
#include <signal.h>
@@ -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

View File

@@ -4,7 +4,6 @@
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);
}