mirror of
https://github.com/aap/pdp6.git
synced 2026-03-04 18:54:41 +00:00
emu: improved cli
This commit is contained in:
66
emu/apr.c
66
emu/apr.c
@@ -1,10 +1,53 @@
|
||||
#include "pdp6.h"
|
||||
#include <unistd.h>
|
||||
|
||||
enum Opcode {
|
||||
FSC = 0132,
|
||||
IBP = 0133,
|
||||
CAO = 0133,
|
||||
LDCI = 0134,
|
||||
LDC = 0135,
|
||||
DPCI = 0136,
|
||||
DPC = 0137,
|
||||
ASH = 0240,
|
||||
ROT = 0241,
|
||||
LSH = 0242,
|
||||
ASHC = 0244,
|
||||
ROTC = 0245,
|
||||
LSHC = 0246,
|
||||
EXCH = 0250,
|
||||
BLT = 0251,
|
||||
AOBJP = 0252,
|
||||
AOBJN = 0253,
|
||||
JRST = 0254,
|
||||
JFCL = 0255,
|
||||
XCT = 0256,
|
||||
PUSHJ = 0260,
|
||||
PUSH = 0261,
|
||||
POP = 0262,
|
||||
POPJ = 0263,
|
||||
JSR = 0264,
|
||||
JSP = 0265,
|
||||
JSA = 0266,
|
||||
JRA = 0267,
|
||||
|
||||
BLKI = 0700000,
|
||||
DATAI = 0700040,
|
||||
BLKO = 0700100,
|
||||
DATAO = 0700140,
|
||||
CONO = 0700200,
|
||||
CONI = 0700240,
|
||||
CONSZ = 0700300,
|
||||
CONSO = 0700340
|
||||
|
||||
};
|
||||
|
||||
static void aprcycle(void *p);
|
||||
static void wake_cpa(void *dev);
|
||||
static void wake_pi(void *dev);
|
||||
|
||||
char *apr_ident = APR_IDENT;
|
||||
|
||||
void
|
||||
curpulse(Apr *apr, Pulse *p)
|
||||
{
|
||||
@@ -25,21 +68,28 @@ nextpulse(Apr *apr, Pulse *p)
|
||||
apr->nlist[apr->nnextpulses++] = p;
|
||||
}
|
||||
|
||||
Apr*
|
||||
makeapr(void)
|
||||
Device*
|
||||
makeapr(int argc, char *argv[])
|
||||
{
|
||||
Apr *apr;
|
||||
Thread th;
|
||||
|
||||
apr = malloc(sizeof(Apr));
|
||||
memset(apr, 0, sizeof(Apr));
|
||||
|
||||
apr->dev.type = apr_ident;
|
||||
apr->dev.name = "";
|
||||
apr->dev.attach = nil;
|
||||
apr->dev.ioconnect = nil;
|
||||
apr->dev.next = nil;
|
||||
|
||||
apr->iobus.dev[CPA] = (Busdev){ apr, wake_cpa, 0 };
|
||||
apr->iobus.dev[PI] = (Busdev){ apr, wake_pi, 0 };
|
||||
|
||||
th = (Thread){ nil, aprcycle, apr, 1, 0 };
|
||||
addthread(th);
|
||||
|
||||
return apr;
|
||||
return &apr->dev;
|
||||
}
|
||||
|
||||
|
||||
@@ -367,10 +417,12 @@ void
|
||||
setreq(IOBus *bus, int dev, u8 pia)
|
||||
{
|
||||
u8 req;
|
||||
req = (0200>>pia) & 0177;
|
||||
if(bus->dev[dev].req != req){
|
||||
bus->dev[dev].req = req;
|
||||
recalc_req(bus);
|
||||
if(bus){
|
||||
req = (0200>>pia) & 0177;
|
||||
if(bus->dev[dev].req != req){
|
||||
bus->dev[dev].req = req;
|
||||
recalc_req(bus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
extern char *argv0;
|
||||
#define USED(x) ((void)x)
|
||||
#define SET(x) ((x)=0)
|
||||
|
||||
|
||||
217
emu/cmd.c
217
emu/cmd.c
@@ -197,6 +197,126 @@ dep(word addr, int fastmem, word w)
|
||||
|
||||
/* Commands */
|
||||
|
||||
typedef struct DevDef DevDef;
|
||||
struct DevDef
|
||||
{
|
||||
char *type;
|
||||
Device *(*make)(int argc, char *argv[]);
|
||||
};
|
||||
DevDef definitions[] = {
|
||||
{ FMEM_IDENT, makefmem },
|
||||
{ CMEM_IDENT, makecmem },
|
||||
{ APR_IDENT, makeapr },
|
||||
{ TTY_IDENT, maketty },
|
||||
{ PTR_IDENT, makeptr },
|
||||
{ PTP_IDENT, makeptp },
|
||||
{ nil, nil }
|
||||
};
|
||||
|
||||
static void
|
||||
c_mkdev(int argc, char *argv[])
|
||||
{
|
||||
Device *dev;
|
||||
DevDef *def;
|
||||
|
||||
if(argc < 3){
|
||||
printf("Not enough arguments\n");
|
||||
return;
|
||||
}
|
||||
for(def = definitions; def->type; def++)
|
||||
if(strcmp(def->type, argv[2]) == 0){
|
||||
dev = def->make(argc-3, argv+3);
|
||||
goto found;
|
||||
}
|
||||
printf("No such device type: %s\n", argv[2]);
|
||||
return;
|
||||
found:
|
||||
dev->name = strdup(argv[1]);
|
||||
adddevice(dev);
|
||||
}
|
||||
|
||||
static void
|
||||
c_attach(int argc, char *argv[])
|
||||
{
|
||||
Device *dev;
|
||||
|
||||
if(argc < 3){
|
||||
printf("Not enough arguments\n");
|
||||
return;
|
||||
}
|
||||
dev = getdevice(argv[1]);
|
||||
if(dev == nil){
|
||||
printf("No device: %s\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if(dev->attach == nil){
|
||||
printf("No attach for device type %s\n", dev->type);
|
||||
return;
|
||||
}
|
||||
dev->attach(dev, argv[2]);
|
||||
}
|
||||
|
||||
/* ioconnect dev busdev */
|
||||
static void
|
||||
c_ioconnect(int argc, char *argv[])
|
||||
{
|
||||
Device *dev, *busdev;
|
||||
|
||||
if(argc < 3){
|
||||
printf("Not enough arguments\n");
|
||||
return;
|
||||
}
|
||||
dev = getdevice(argv[1]);
|
||||
if(dev == nil){
|
||||
printf("No device: %s\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
busdev = getdevice(argv[2]);
|
||||
if(busdev == nil){
|
||||
printf("No device: %s\n", argv[2]);
|
||||
return;
|
||||
}
|
||||
if(busdev->type != apr_ident){
|
||||
printf("No bus device: %s\n", busdev->type);
|
||||
return;
|
||||
}
|
||||
if(dev->ioconnect == nil){
|
||||
printf("No ioconnect for device type %s\n", dev->type);
|
||||
return;
|
||||
}
|
||||
dev->ioconnect(dev, &((Apr*)busdev)->iobus);
|
||||
}
|
||||
|
||||
/* memconnect dev proc busdev addr */
|
||||
static void
|
||||
c_memconnect(int argc, char *argv[])
|
||||
{
|
||||
int proc, addr;
|
||||
Device *dev, *busdev;
|
||||
|
||||
if(argc < 5){
|
||||
printf("Not enough arguments\n");
|
||||
return;
|
||||
}
|
||||
dev = getdevice(argv[1]);
|
||||
if(dev == nil){
|
||||
printf("No device: %s\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
proc = atoi(argv[2]);
|
||||
busdev = getdevice(argv[3]);
|
||||
if(busdev == nil){
|
||||
printf("No device: %s\n", argv[3]);
|
||||
return;
|
||||
}
|
||||
if(busdev->type != apr_ident){
|
||||
printf("No bus device: %s\n", argv[3]);
|
||||
return;
|
||||
}
|
||||
addr = strtol(argv[4], nil, 8);
|
||||
attachmem((Mem*)dev, proc, &((Apr*)busdev)->membus, addr);
|
||||
}
|
||||
|
||||
static void
|
||||
c_ex(int argc, char *argv[])
|
||||
{
|
||||
@@ -316,6 +436,10 @@ struct {
|
||||
char *cmd;
|
||||
void (*f)(int, char **);
|
||||
} cmdtab[] = {
|
||||
{ "mkdev", c_mkdev },
|
||||
{ "attach", c_attach },
|
||||
{ "ioconnect", c_ioconnect },
|
||||
{ "memconnect", c_memconnect },
|
||||
{ "examine", c_ex },
|
||||
{ "deposit", c_dep },
|
||||
{ "load", c_load },
|
||||
@@ -324,55 +448,72 @@ struct {
|
||||
{ "", nil}
|
||||
};
|
||||
|
||||
void*
|
||||
cmdthread(void *p)
|
||||
void
|
||||
commandline(char *line)
|
||||
{
|
||||
size_t len, l;
|
||||
char *line, *cmd;
|
||||
int i, n;
|
||||
int nfound;
|
||||
size_t l;
|
||||
char *cmd;
|
||||
|
||||
lp = line;
|
||||
splitops();
|
||||
|
||||
if(numops && ops[0][0] != '#'){
|
||||
nfound = 0;
|
||||
for(i = 0; cmdtab[i].cmd[0]; i++){
|
||||
cmd = cmdtab[i].cmd;
|
||||
l = strlen(ops[0]);
|
||||
if(strncmp(ops[0], cmd, l) == 0){
|
||||
n = i;
|
||||
nfound++;
|
||||
}
|
||||
}
|
||||
if(nfound == 0)
|
||||
printf("%s: not found\n", ops[0]);
|
||||
else if(nfound == 1)
|
||||
cmdtab[n].f(numops, ops);
|
||||
else{
|
||||
printf("Ambiguous command: %s\n", ops[0]);
|
||||
for(i = 0; cmdtab[i].cmd[0]; i++){
|
||||
cmd = cmdtab[i].cmd;
|
||||
l = strlen(ops[0]);
|
||||
if(strncmp(ops[0], cmd, l) == 0)
|
||||
printf(" %s\n", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cli(FILE *in)
|
||||
{
|
||||
Device *dev;
|
||||
size_t len;
|
||||
char *line;
|
||||
|
||||
apr = nil;
|
||||
for(i = 0; i < 4; i++)
|
||||
if(aprs[i]){
|
||||
apr = aprs[i];
|
||||
for(dev = devlist; dev; dev = dev->next)
|
||||
if(dev->type == apr_ident){
|
||||
apr = (Apr*)dev;
|
||||
break;
|
||||
}
|
||||
for(;;){
|
||||
line = nil;
|
||||
len = 0;
|
||||
printf("> ");
|
||||
if(getline(&line, &len, stdin) < 0)
|
||||
quit(0);
|
||||
|
||||
lp = line;
|
||||
splitops();
|
||||
|
||||
if(numops){
|
||||
nfound = 0;
|
||||
for(i = 0; cmdtab[i].cmd[0]; i++){
|
||||
cmd = cmdtab[i].cmd;
|
||||
l = strlen(ops[0]);
|
||||
if(strncmp(ops[0], cmd, l) == 0){
|
||||
n = i;
|
||||
nfound++;
|
||||
}
|
||||
}
|
||||
if(nfound == 0)
|
||||
printf("%s: not found\n", ops[0]);
|
||||
else if(nfound == 1)
|
||||
cmdtab[n].f(numops, ops);
|
||||
else{
|
||||
printf("Ambiguous command: %s\n", ops[0]);
|
||||
for(i = 0; cmdtab[i].cmd[0]; i++){
|
||||
cmd = cmdtab[i].cmd;
|
||||
l = strlen(ops[0]);
|
||||
if(strncmp(ops[0], cmd, l) == 0)
|
||||
printf(" %s\n", cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(in == stdin)
|
||||
printf("> ");
|
||||
if(getline(&line, &len, in) < 0)
|
||||
return;
|
||||
commandline(line);
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
cmdthread(void *p)
|
||||
{
|
||||
cli(stdin);
|
||||
quit(0);
|
||||
return nil;
|
||||
}
|
||||
|
||||
23
emu/init.ini
Normal file
23
emu/init.ini
Normal file
@@ -0,0 +1,23 @@
|
||||
# apr, tty, ptr and ptp names are needed by the emulator
|
||||
mkdev apr apr166
|
||||
mkdev tty tty626
|
||||
mkdev ptr ptr760
|
||||
mkdev ptp ptp761
|
||||
mkdev fmem fmem162 0
|
||||
mkdev cmem0 cmem161C mem_0
|
||||
mkdev cmem1 cmem161C mem_1
|
||||
mkdev cmem2 cmem161C mem_2
|
||||
mkdev cmem3 cmem161C mem_3
|
||||
|
||||
ioconnect tty apr
|
||||
ioconnect ptr apr
|
||||
ioconnect ptp apr
|
||||
memconnect fmem 0 apr -1
|
||||
memconnect cmem0 0 apr 0
|
||||
memconnect cmem1 0 apr 1
|
||||
memconnect cmem2 0 apr 2
|
||||
memconnect cmem3 0 apr 3
|
||||
|
||||
attach tty /tmp/6tty
|
||||
attach ptr ../code/test.rim
|
||||
attach ptp ../code/ptp.out
|
||||
124
emu/main.c
124
emu/main.c
@@ -168,6 +168,8 @@ updateapr(Apr *apr, Ptr *ptr)
|
||||
{
|
||||
Apr oldapr;
|
||||
|
||||
if(apr == nil)
|
||||
return;
|
||||
oldapr = *apr;
|
||||
setlights(apr->ir, ir_l, 18);
|
||||
setlights(apr->mi, mi_l, 36);
|
||||
@@ -352,30 +354,36 @@ updateapr(Apr *apr, Ptr *ptr)
|
||||
void
|
||||
updatetty(Tty *tty)
|
||||
{
|
||||
tty_l[0].state = tty->tti_busy;
|
||||
tty_l[1].state = tty->tti_flag;
|
||||
tty_l[2].state = tty->tto_busy;
|
||||
tty_l[3].state = tty->tto_flag;
|
||||
setlights(tty->pia, &tty_l[4], 3);
|
||||
setlights(tty->tti, ttibuf_l, 8);
|
||||
if(tty){
|
||||
tty_l[0].state = tty->tti_busy;
|
||||
tty_l[1].state = tty->tti_flag;
|
||||
tty_l[2].state = tty->tto_busy;
|
||||
tty_l[3].state = tty->tto_flag;
|
||||
setlights(tty->pia, &tty_l[4], 3);
|
||||
setlights(tty->tti, ttibuf_l, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
updatept(Ptp *ptp, Ptr *ptr)
|
||||
{
|
||||
ptp_l[0].state = ptp->b;
|
||||
ptp_l[1].state = ptp->busy;
|
||||
ptp_l[2].state = ptp->flag;
|
||||
setlights(ptp->pia, &ptp_l[3], 3);
|
||||
setlights(ptp->ptp, ptpbuf_l, 8);
|
||||
if(ptp){
|
||||
ptp_l[0].state = ptp->b;
|
||||
ptp_l[1].state = ptp->busy;
|
||||
ptp_l[2].state = ptp->flag;
|
||||
setlights(ptp->pia, &ptp_l[3], 3);
|
||||
setlights(ptp->ptp, ptpbuf_l, 8);
|
||||
}
|
||||
|
||||
ptr_l[0].state = ptr->b;
|
||||
ptr_l[1].state = ptr->busy;
|
||||
ptr_l[2].state = ptr->flag;
|
||||
setlights(ptr->pia, &ptr_l[3], 3);
|
||||
setlights(ptr->ptr, ptrbuf_l, 36);
|
||||
if(ptr){
|
||||
ptr_l[0].state = ptr->b;
|
||||
ptr_l[1].state = ptr->busy;
|
||||
ptr_l[2].state = ptr->flag;
|
||||
setlights(ptr->pia, &ptr_l[3], 3);
|
||||
setlights(ptr->ptr, ptrbuf_l, 36);
|
||||
|
||||
extra_l[0].state = ptr->motor_on;
|
||||
extra_l[0].state = ptr->motor_on;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -569,6 +577,45 @@ simthread(void *p)
|
||||
return nil;
|
||||
}
|
||||
|
||||
Device *devlist;
|
||||
|
||||
void
|
||||
adddevice(Device *dev)
|
||||
{
|
||||
dev->next = devlist;
|
||||
devlist = dev;
|
||||
};
|
||||
|
||||
Device*
|
||||
getdevice(const char *name)
|
||||
{
|
||||
Device *dev;
|
||||
for(dev = devlist; dev; dev = dev->next)
|
||||
if(strcmp(dev->name, name) == 0)
|
||||
return dev;
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
printdevices(void)
|
||||
{
|
||||
Device *dev;
|
||||
for(dev = devlist; dev; dev = dev->next)
|
||||
printf("%s %s\n", dev->name, dev->type);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dofile(const char *path)
|
||||
{
|
||||
FILE *f;
|
||||
if(f = fopen(path, "r"), f == nil){
|
||||
printf("Couldn't open file %s\n", path);
|
||||
return;
|
||||
}
|
||||
cli(f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void
|
||||
quit(int code)
|
||||
@@ -581,12 +628,10 @@ quit(int code)
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-t] [-d debugfile] [-c ttyfile]\n", argv0);
|
||||
fprintf(stderr, "usage: %s [-t] [-d debugfile]\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Apr *aprs[4];
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@@ -598,17 +643,15 @@ main(int argc, char *argv[])
|
||||
int i;
|
||||
int w, h;
|
||||
pthread_t cmd_thread, sim_thread;
|
||||
const char *outfile, *ttyfile;
|
||||
const char *outfile;
|
||||
|
||||
Apr *apr;
|
||||
Ptr *ptr;
|
||||
Ptp *ptp;
|
||||
Tty *tty;
|
||||
Mem *coremems[4];
|
||||
Mem *fastmem;
|
||||
Mem *mem;
|
||||
|
||||
outfile = "/dev/null";
|
||||
ttyfile = "/tmp/6tty";
|
||||
ARGBEGIN{
|
||||
case 't':
|
||||
dotrace = 1;
|
||||
@@ -616,9 +659,6 @@ main(int argc, char *argv[])
|
||||
case 'd':
|
||||
outfile = EARGF(usage());
|
||||
break;
|
||||
case 'c':
|
||||
ttyfile = EARGF(usage());
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND;
|
||||
@@ -716,31 +756,13 @@ main(int argc, char *argv[])
|
||||
|
||||
extra_l = e; e += 1;
|
||||
|
||||
fastmem = makefastmem(0);
|
||||
coremems[0] = makecoremem("mem_0");
|
||||
coremems[1] = makecoremem("mem_1");
|
||||
coremems[2] = makecoremem("mem_2");
|
||||
coremems[3] = makecoremem("mem_3");
|
||||
dofile("init.ini");
|
||||
apr = (Apr*)getdevice("apr");
|
||||
tty = (Tty*)getdevice("tty");
|
||||
ptr = (Ptr*)getdevice("ptr");
|
||||
ptp = (Ptp*)getdevice("ptp");
|
||||
|
||||
aprs[0] = apr = makeapr();
|
||||
attachmem(fastmem, 0, &apr->membus, -1);
|
||||
attachmem(coremems[0], 0, &apr->membus, 0);
|
||||
attachmem(coremems[1], 0, &apr->membus, 1);
|
||||
attachmem(coremems[2], 0, &apr->membus, 2);
|
||||
attachmem(coremems[3], 0, &apr->membus, 3);
|
||||
tty = maketty(&apr->iobus);
|
||||
ptr = makeptr(&apr->iobus);
|
||||
ptp = makeptp(&apr->iobus);
|
||||
if(ttyfile)
|
||||
attachdevtty(tty, ttyfile);
|
||||
|
||||
/* Power on memory */
|
||||
// TODO: maybe do that somewhere else?
|
||||
fastmem->poweron(fastmem);
|
||||
coremems[0]->poweron(coremems[0]);
|
||||
coremems[1]->poweron(coremems[1]);
|
||||
coremems[2]->poweron(coremems[2]);
|
||||
coremems[3]->poweron(coremems[3]);
|
||||
printdevices();
|
||||
|
||||
pthread_create(&sim_thread, nil, simthread, apr);
|
||||
pthread_create(&cmd_thread, nil, cmdthread, nil);
|
||||
|
||||
45
emu/mem.c
45
emu/mem.c
@@ -1,5 +1,8 @@
|
||||
#include "pdp6.h"
|
||||
|
||||
char *fmem_ident = FMEM_IDENT;
|
||||
char *cmem_ident = CMEM_IDENT;
|
||||
|
||||
Membus memterm;
|
||||
|
||||
void
|
||||
@@ -242,6 +245,12 @@ makecoremem(const char *file)
|
||||
core->filename = file;
|
||||
|
||||
mem = malloc(sizeof(Mem));
|
||||
mem->dev.type = cmem_ident;
|
||||
mem->dev.name = "";
|
||||
mem->dev.attach = nil;
|
||||
mem->dev.ioconnect = nil;
|
||||
mem->dev.next = nil;
|
||||
|
||||
mem->module = core;
|
||||
mem->bus[0] = &memterm;
|
||||
mem->bus[1] = &memterm;
|
||||
@@ -261,9 +270,16 @@ makefastmem(int p)
|
||||
|
||||
ff = malloc(sizeof(FMem));
|
||||
memset(ff, 0, sizeof(FMem));
|
||||
|
||||
ff->fmc_p_sel = p;
|
||||
|
||||
mem = malloc(sizeof(Mem));
|
||||
mem->dev.type = fmem_ident;
|
||||
mem->dev.name = "";
|
||||
mem->dev.attach = nil;
|
||||
mem->dev.ioconnect = nil;
|
||||
mem->dev.next = nil;
|
||||
|
||||
mem->module = ff;
|
||||
mem->bus[0] = &memterm;
|
||||
mem->bus[1] = &memterm;
|
||||
@@ -275,6 +291,35 @@ makefastmem(int p)
|
||||
return mem;
|
||||
}
|
||||
|
||||
Device*
|
||||
makefmem(int argc, char *argv[])
|
||||
{
|
||||
Mem *m;
|
||||
int p;
|
||||
|
||||
if(argc > 0)
|
||||
p = atoi(argv[0]);
|
||||
else
|
||||
p = 0;
|
||||
m = makefastmem(p);
|
||||
m->poweron(m);
|
||||
return &m->dev;
|
||||
}
|
||||
|
||||
Device*
|
||||
makecmem(int argc, char *argv[])
|
||||
{
|
||||
Mem *m;
|
||||
char *path;
|
||||
if(argc > 0)
|
||||
path = argv[0];
|
||||
else
|
||||
path = "/dev/null";
|
||||
m = makecoremem(path);
|
||||
m->poweron(m);
|
||||
return &m->dev;
|
||||
}
|
||||
|
||||
/* Attach mem to bus for processor p.
|
||||
* If n < 0, it is attached as fast memory,
|
||||
* else at addresses starting at n<<14. */
|
||||
|
||||
146
emu/pdp6.h
146
emu/pdp6.h
@@ -28,6 +28,7 @@ u32 getms(void);
|
||||
int hasinput(int fd);
|
||||
|
||||
void quit(int code);
|
||||
void cli(FILE *f);
|
||||
void *cmdthread(void *);
|
||||
|
||||
enum {
|
||||
@@ -67,6 +68,15 @@ enum FullwordBits {
|
||||
F33 = 0000000000004, F34 = 0000000000002, F35 = 0000000000001
|
||||
};
|
||||
|
||||
typedef struct Mem Mem;
|
||||
typedef struct Membus Membus;
|
||||
typedef struct FMem FMem;
|
||||
typedef struct CMem CMem;
|
||||
typedef struct Busdev Busdev;
|
||||
typedef struct IOBus IOBus;
|
||||
typedef struct Apr Apr;
|
||||
|
||||
|
||||
typedef struct Thread Thread;
|
||||
struct Thread
|
||||
{
|
||||
@@ -80,62 +90,22 @@ struct Thread
|
||||
extern Thread *threads;
|
||||
void addthread(Thread th);
|
||||
|
||||
|
||||
/* external pulses, bits of Apr.extpulse */
|
||||
enum Extpulse {
|
||||
EXT_KEY_MANUAL = 1,
|
||||
EXT_KEY_INST_STOP = 2,
|
||||
EXT_NONEXIT_MEM = 4
|
||||
/* not used yet */
|
||||
typedef struct Device Device;
|
||||
struct Device
|
||||
{
|
||||
Device *next;
|
||||
char *type;
|
||||
char *name;
|
||||
/* attach file to device */
|
||||
void (*attach)(Device *dev, const char *path);
|
||||
/* connect device to iobus */
|
||||
void (*ioconnect)(Device *dev, IOBus *bus);
|
||||
};
|
||||
|
||||
enum Opcode {
|
||||
FSC = 0132,
|
||||
IBP = 0133,
|
||||
CAO = 0133,
|
||||
LDCI = 0134,
|
||||
LDC = 0135,
|
||||
DPCI = 0136,
|
||||
DPC = 0137,
|
||||
ASH = 0240,
|
||||
ROT = 0241,
|
||||
LSH = 0242,
|
||||
ASHC = 0244,
|
||||
ROTC = 0245,
|
||||
LSHC = 0246,
|
||||
EXCH = 0250,
|
||||
BLT = 0251,
|
||||
AOBJP = 0252,
|
||||
AOBJN = 0253,
|
||||
JRST = 0254,
|
||||
JFCL = 0255,
|
||||
XCT = 0256,
|
||||
PUSHJ = 0260,
|
||||
PUSH = 0261,
|
||||
POP = 0262,
|
||||
POPJ = 0263,
|
||||
JSR = 0264,
|
||||
JSP = 0265,
|
||||
JSA = 0266,
|
||||
JRA = 0267,
|
||||
|
||||
BLKI = 0700000,
|
||||
DATAI = 0700040,
|
||||
BLKO = 0700100,
|
||||
DATAO = 0700140,
|
||||
CONO = 0700200,
|
||||
CONI = 0700240,
|
||||
CONSZ = 0700300,
|
||||
CONSO = 0700340
|
||||
|
||||
};
|
||||
|
||||
typedef struct Mem Mem;
|
||||
typedef struct Membus Membus;
|
||||
typedef struct FMem FMem;
|
||||
typedef struct CMem CMem;
|
||||
typedef struct Busdev Busdev;
|
||||
typedef struct IOBus IOBus;
|
||||
typedef struct Apr Apr;
|
||||
extern Device *devlist;
|
||||
void adddevice(Device *dev);
|
||||
Device *getdevice(const char *name);
|
||||
|
||||
|
||||
/*
|
||||
@@ -168,6 +138,7 @@ enum {
|
||||
/* A memory module connected to up to 4 Membuses */
|
||||
struct Mem
|
||||
{
|
||||
Device dev;
|
||||
void *module;
|
||||
Membus *bus[4];
|
||||
int (*wake)(Mem *mem, Membus *bus);
|
||||
@@ -181,8 +152,6 @@ struct Membus
|
||||
* and c??_pulse is used to detect leading edges. */
|
||||
word c12, c12_prev, c12_pulse;
|
||||
word c34, c34_prev, c34_pulse;
|
||||
/* cycle counter to implement NXM timeout */
|
||||
int numcyc;
|
||||
|
||||
Mem *fmem; /* fast memory */
|
||||
Mem *cmem[16]; /* 16 16k core modules */
|
||||
@@ -198,7 +167,10 @@ struct FMem
|
||||
bool fmc_act;
|
||||
bool fmc_wr;
|
||||
};
|
||||
#define FMEM_IDENT "fmem162"
|
||||
extern char *fmem_ident;
|
||||
Mem *makefastmem(int p);
|
||||
Device *makefmem(int argc, char *argv[]);
|
||||
|
||||
/* Core memory 161C, 16k words */
|
||||
struct CMem
|
||||
@@ -214,7 +186,10 @@ struct CMem
|
||||
u8 cmc_last_proc;
|
||||
bool cmc_pse_sync;
|
||||
};
|
||||
#define CMEM_IDENT "cmem161C"
|
||||
extern char *cmem_ident;
|
||||
Mem *makecoremem(const char *file);
|
||||
Device *makecmem(int argc, char *argv[]);
|
||||
|
||||
void attachmem(Mem *mem, int p, Membus *bus, int n);
|
||||
void readmem(const char *file, word *mem, word size);
|
||||
@@ -300,11 +275,19 @@ void setreq(IOBus *bus, int dev, u8 pia);
|
||||
#define CPA (0000>>2)
|
||||
#define PI (0004>>2)
|
||||
|
||||
/* external pulses, bits of Apr.extpulse */
|
||||
enum Extpulse {
|
||||
EXT_KEY_MANUAL = 1,
|
||||
EXT_KEY_INST_STOP = 2,
|
||||
EXT_NONEXIT_MEM = 4
|
||||
};
|
||||
|
||||
typedef void Pulse(Apr *apr);
|
||||
#define pulse(p) static void p(Apr *apr)
|
||||
|
||||
struct Apr
|
||||
{
|
||||
Device dev;
|
||||
IOBus iobus;
|
||||
Membus membus;
|
||||
int powered;
|
||||
@@ -414,24 +397,9 @@ struct Apr
|
||||
Pulse **clist, **nlist;
|
||||
int ncurpulses, nnextpulses;
|
||||
};
|
||||
extern Apr *aprs[4];
|
||||
Apr *makeapr(void);
|
||||
|
||||
|
||||
/* Paper tape punch 761 */
|
||||
#define PTP (0100>>2)
|
||||
typedef struct Ptp Ptp;
|
||||
struct Ptp
|
||||
{
|
||||
IOBus *bus;
|
||||
uchar ptp;
|
||||
bool busy, flag, b;
|
||||
int pia;
|
||||
|
||||
int fd;
|
||||
int waitdatao;
|
||||
};
|
||||
Ptp *makeptp(IOBus *bus);
|
||||
#define APR_IDENT "apr166"
|
||||
extern char *apr_ident;
|
||||
Device *makeapr(int argc, char *argv[]);
|
||||
|
||||
|
||||
/* Paper tape reader 760 */
|
||||
@@ -439,6 +407,7 @@ Ptp *makeptp(IOBus *bus);
|
||||
typedef struct Ptr Ptr;
|
||||
struct Ptr
|
||||
{
|
||||
Device dev;
|
||||
IOBus *bus;
|
||||
int motor_on;
|
||||
word sr;
|
||||
@@ -448,15 +417,37 @@ struct Ptr
|
||||
|
||||
int fd;
|
||||
};
|
||||
Ptr *makeptr(IOBus *bus);
|
||||
#define PTR_IDENT "ptr760"
|
||||
extern char *ptr_ident;
|
||||
Device *makeptr(int argc, char *argv[]);
|
||||
void ptr_setmotor(Ptr *ptr, int m);
|
||||
|
||||
|
||||
/* Paper tape punch 761 */
|
||||
#define PTP (0100>>2)
|
||||
typedef struct Ptp Ptp;
|
||||
struct Ptp
|
||||
{
|
||||
Device dev;
|
||||
IOBus *bus;
|
||||
uchar ptp;
|
||||
bool busy, flag, b;
|
||||
int pia;
|
||||
|
||||
int fd;
|
||||
int waitdatao;
|
||||
};
|
||||
#define PTP_IDENT "ptp761"
|
||||
extern char *ptp_ident;
|
||||
Device *makeptp(int argc, char *argv[]);
|
||||
|
||||
|
||||
/* Teletype 626 */
|
||||
#define TTY (0120>>2)
|
||||
typedef struct Tty Tty;
|
||||
struct Tty
|
||||
{
|
||||
Device dev;
|
||||
IOBus *bus;
|
||||
uchar tto, tti;
|
||||
bool tto_busy, tto_flag;
|
||||
@@ -464,5 +455,6 @@ struct Tty
|
||||
int pia;
|
||||
int fd;
|
||||
};
|
||||
Tty *maketty(IOBus *bus);
|
||||
void attachdevtty(Tty *tty, const char *path);
|
||||
#define TTY_IDENT "tty626"
|
||||
extern char *tty_ident;
|
||||
Device *maketty(int argc, char *argv[]);
|
||||
|
||||
87
emu/pt.c
87
emu/pt.c
@@ -9,6 +9,9 @@
|
||||
|
||||
/* TODO? implement motor delays */
|
||||
|
||||
char *ptr_ident = PTR_IDENT;
|
||||
char *ptp_ident = PTP_IDENT;
|
||||
|
||||
static void
|
||||
recalc_ptp_req(Ptp *ptp)
|
||||
{
|
||||
@@ -185,38 +188,94 @@ ptr_setmotor(Ptr *ptr, int m)
|
||||
recalc_ptr_req(ptr);
|
||||
}
|
||||
|
||||
Ptp*
|
||||
makeptp(IOBus *bus)
|
||||
static void
|
||||
ptpattach(Device *dev, const char *path)
|
||||
{
|
||||
Ptp *ptp;
|
||||
int fd;
|
||||
|
||||
ptp = (Ptp*)dev;
|
||||
fd = ptp->fd;
|
||||
if(fd >= 0){
|
||||
ptp->fd = -1;
|
||||
close(fd);
|
||||
}
|
||||
ptp->fd = open(path, O_WRONLY | O_CREAT, 0666);
|
||||
if(ptp->fd < 0)
|
||||
fprintf(stderr, "couldn't open file %s\n", path);
|
||||
}
|
||||
|
||||
static void
|
||||
ptrattach(Device *dev, const char *path)
|
||||
{
|
||||
Ptr *ptr;
|
||||
int fd;
|
||||
|
||||
ptr = (Ptr*)dev;
|
||||
fd = ptr->fd;
|
||||
if(fd >= 0){
|
||||
ptr->fd = -1;
|
||||
close(fd);
|
||||
}
|
||||
ptr->fd = open(path, O_RDONLY);
|
||||
if(ptr->fd < 0)
|
||||
fprintf(stderr, "couldn't open file %s\n", path);
|
||||
}
|
||||
|
||||
static void
|
||||
ptrioconnect(Device *dev, IOBus *bus)
|
||||
{
|
||||
Ptr *ptr;
|
||||
ptr = (Ptr*)dev;
|
||||
ptr->bus = bus;
|
||||
bus->dev[PTR] = (Busdev){ ptr, wake_ptr, 0 };
|
||||
}
|
||||
|
||||
static void
|
||||
ptpioconnect(Device *dev, IOBus *bus)
|
||||
{
|
||||
Ptp *ptp;
|
||||
ptp = (Ptp*)dev;
|
||||
ptp->bus = bus;
|
||||
bus->dev[PTP] = (Busdev){ ptp, wake_ptp, 0 };
|
||||
}
|
||||
|
||||
Device*
|
||||
makeptp(int argc, char *argv[])
|
||||
{
|
||||
Ptp *ptp;
|
||||
Thread th;
|
||||
|
||||
ptp = malloc(sizeof(Ptp));
|
||||
memset(ptp, 0, sizeof(Ptp));
|
||||
ptp->bus = bus;
|
||||
bus->dev[PTP] = (Busdev){ ptp, wake_ptp, 0 };
|
||||
|
||||
ptp->dev.type = ptp_ident;
|
||||
ptp->dev.name = "";
|
||||
ptp->dev.attach = ptpattach;
|
||||
ptp->dev.ioconnect = ptpioconnect;
|
||||
ptp->fd = -1;
|
||||
|
||||
th = (Thread){ nil, ptpcycle, ptp, 1, 0 };
|
||||
addthread(th);
|
||||
|
||||
ptp->fd = open("../code/ptp.out", O_WRONLY | O_CREAT, 0666);
|
||||
return ptp;
|
||||
return &ptp->dev;
|
||||
}
|
||||
|
||||
Ptr*
|
||||
makeptr(IOBus *bus)
|
||||
Device*
|
||||
makeptr(int argc, char *argv[])
|
||||
{
|
||||
Ptr *ptr;
|
||||
Thread th;
|
||||
|
||||
ptr = malloc(sizeof(Ptr));
|
||||
memset(ptr, 0, sizeof(Ptr));
|
||||
ptr->bus = bus;
|
||||
bus->dev[PTR] = (Busdev){ ptr, wake_ptr, 0 };
|
||||
|
||||
ptr->dev.type = ptr_ident;
|
||||
ptr->dev.name = "";
|
||||
ptr->dev.attach = ptrattach;
|
||||
ptr->dev.ioconnect = ptrioconnect;
|
||||
ptr->fd = -1;
|
||||
|
||||
th = (Thread){ nil, ptrcycle, ptr, 1, 0 };
|
||||
addthread(th);
|
||||
|
||||
ptr->fd = open("../code/test.rim", O_RDONLY);
|
||||
return ptr;
|
||||
return &ptr->dev;
|
||||
}
|
||||
|
||||
33
emu/tty.c
33
emu/tty.c
@@ -4,6 +4,8 @@
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
|
||||
char *tty_ident = TTY_IDENT;
|
||||
|
||||
static void
|
||||
recalc_tty_req(Tty *tty)
|
||||
{
|
||||
@@ -91,12 +93,14 @@ wake_tty(void *dev)
|
||||
recalc_tty_req(tty);
|
||||
}
|
||||
|
||||
void
|
||||
attachdevtty(Tty *tty, const char *path)
|
||||
static void
|
||||
ttyattach(Device *dev, const char *path)
|
||||
{
|
||||
Tty *tty;
|
||||
int fd;
|
||||
struct termios tio;
|
||||
|
||||
tty = (Tty*)dev;
|
||||
fd = tty->fd;
|
||||
if(fd >= 0){
|
||||
tty->fd = -1;
|
||||
@@ -116,23 +120,36 @@ attachdevtty(Tty *tty, const char *path)
|
||||
|
||||
fail:
|
||||
if(fd >= 0) close(fd);
|
||||
fprintf(stderr, "couldn't open tty %s\n", path);
|
||||
fprintf(stderr, "couldn't open file %s\n", path);
|
||||
}
|
||||
|
||||
Tty*
|
||||
maketty(IOBus *bus)
|
||||
static void
|
||||
ttyioconnect(Device *dev, IOBus *bus)
|
||||
{
|
||||
Tty *tty;
|
||||
tty = (Tty*)dev;
|
||||
tty->bus = bus;
|
||||
bus->dev[TTY] = (Busdev){ tty, wake_tty, 0 };
|
||||
}
|
||||
|
||||
Device*
|
||||
maketty(int argc, char *argv[])
|
||||
{
|
||||
Tty *tty;
|
||||
Thread th;
|
||||
|
||||
tty = malloc(sizeof(Tty));
|
||||
memset(tty, 0, sizeof(Tty));
|
||||
|
||||
tty->dev.type = tty_ident;
|
||||
tty->dev.name = "";
|
||||
tty->dev.attach = ttyattach;
|
||||
tty->dev.ioconnect = ttyioconnect;
|
||||
|
||||
tty->fd = -1;
|
||||
tty->bus = bus;
|
||||
bus->dev[TTY] = (Busdev){ tty, wake_tty, 0 };
|
||||
|
||||
th = (Thread){ nil, ttycycle, tty, 1, 0 };
|
||||
addthread(th);
|
||||
|
||||
return tty;
|
||||
return &tty->dev;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user