mirror of
https://github.com/aap/pdp6.git
synced 2026-02-27 01:10:14 +00:00
newemu: shared memory implemented. two new message types to make caching possible
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
159
newemu/netmem.c
Normal file
159
newemu/netmem.c
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "common.h"
|
||||
#include "pdp6.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user