1
0
mirror of https://github.com/prirun/p50em.git synced 2026-04-05 04:33:23 +00:00

virtual address translation, fault handling code +

tracing for address translation, disk I/O, and PCL
field address, field length, and load/store character instructions
queue instructions
more work on setting C & L bits correctly
This commit is contained in:
Jim
2005-06-07 00:00:00 -04:00
parent c2c3e8f650
commit 22f4c22f8f
4 changed files with 1205 additions and 261 deletions

1269
em.c

File diff suppressed because it is too large Load Diff

152
emdev.h
View File

@@ -83,7 +83,7 @@ void devnull (short class, short func, short device) {
;
} else {
if (T_INST) fprintf(stderr," unimplemented OCP device '%02o function\n", device);
exit(1);
fatal(NULL);
}
break;
@@ -93,7 +93,7 @@ void devnull (short class, short func, short device) {
IOSKIP; /* assume it's always ready */
else {
if (T_INST) fprintf(stderr," unimplemented SKS device '%02o function\n", device);
exit(1);
fatal(NULL);
}
break;
@@ -103,7 +103,7 @@ void devnull (short class, short func, short device) {
;
} else {
if (T_INST) fprintf(stderr," unimplemented INA device '%02o function\n", device);
exit(1);
fatal(NULL);
}
break;
@@ -113,7 +113,7 @@ void devnull (short class, short func, short device) {
IOSKIP; /* OTA '0004 always works on Unix */
} else {
if (T_INST) fprintf(stderr," unimplemented OTA device '%02o function\n", device);
exit(1);
fatal(NULL);
}
break;
}
@@ -190,11 +190,11 @@ void devasr (short class, short func, short device) {
ttydev = open("/dev/tty", O_RDWR, 0);
if (ttydev < 0) {
perror(" error opening /dev/tty");
exit(1);
fatal(NULL);
}
if (fcntl(ttydev, F_GETFL, ttyflags) == -1) {
perror(" unable to get tty flags");
exit(1);
fatal(NULL);
}
FD_ZERO(&readfds);
FD_SET(ttydev, &readfds);
@@ -208,14 +208,13 @@ void devasr (short class, short func, short device) {
case 1:
if (T_INST) fprintf(stderr," SKS '%02o%02o\n", func, device);
if (func < 7)
IOSKIP; /* assume it's always ready */
else if (func == 7) { /* skip if received a char */
if (func == 7) { /* skip if received a char */
timeout.tv_sec = 0;
timeout.tv_usec = 100000;
if (select(1, &readfds, NULL, NULL, &timeout) == 1)
IOSKIP;
}
} else if (func <= 014)
IOSKIP; /* assume it's always ready */
break;
case 2:
@@ -227,7 +226,7 @@ void devasr (short class, short func, short device) {
newflags = ttyflags | O_NONBLOCK;
if (newflags != ttyflags && fcntl(ttydev, F_SETFL, newflags) == -1) {
perror(" unable to set tty flags");
exit(1);
fatal(NULL);
}
ttyflags = newflags;
readasr:
@@ -235,7 +234,7 @@ readasr:
if (n < 0) {
if (errno != EAGAIN) {
perror(" error reading from tty");
exit(1);
fatal(NULL);
}
} else if (n == 1) {
if (ch == '') {
@@ -249,7 +248,7 @@ readasr:
IOSKIP;
} else if (n != 0) {
if (T_INST) fprintf(stderr," unexpected error reading from tty, n=%d", n);
exit(1);
fatal(NULL);
}
} else if (func == 011) { /* read device id? */
crs[A] = 4;
@@ -259,7 +258,7 @@ readasr:
IOSKIP;
} else {
if (T_INST) fprintf(stderr," unimplemented INA '04 function\n");
exit(1);
fatal(NULL);
}
break;
@@ -277,7 +276,7 @@ readasr:
IOSKIP;
} else {
if (T_INST) fprintf(stderr," unimplemented OTA '04 function\n");
exit(1);
fatal(NULL);
}
break;
}
@@ -305,7 +304,7 @@ void devmt (short class, short func, short device) {
if (T_INST) fprintf(stderr," INA '%02o%02o\n", func, device);
if (BLOCKIO) {
if (T_INST) fprintf(stderr," Device not supported, so I/O hangs\n");
exit(1);
fatal(NULL);
}
break;
@@ -313,7 +312,7 @@ void devmt (short class, short func, short device) {
if (T_INST) fprintf(stderr," OTA '%02o%02o\n", func, device);
if (BLOCKIO) {
if (T_INST) fprintf(stderr," Device not supported, so I/O hangs\n");
exit(1);
fatal(NULL);
}
break;
}
@@ -334,22 +333,24 @@ void devcp (short class, short func, short device) {
case 0:
if (T_INST) fprintf(stderr," OCP '%02o%02o\n", func, device);
if (T_INST) fprintf(stderr," unimplemented OCP device '%02o function\n", device);
exit(1);
fatal(NULL);
break;
case 1:
if (T_INST) fprintf(stderr," SKS '%02o%02o\n", func, device);
if (T_INST) fprintf(stderr," unimplemented SKS device '%02o function\n", device);
exit(1);
fatal(NULL);
break;
case 2:
if (T_INST) fprintf(stderr," INA '%02o%02o\n", func, device);
if (func == 016) {
crs[A] = sswitch;
} else if (func == 017) { /* read switches in momentary down position */
crs[A] = 0;
} else {
if (T_INST) fprintf(stderr," unimplemented INA device '%02o function\n", device);
exit(1);
fatal(NULL);
}
break;
@@ -359,7 +360,7 @@ void devcp (short class, short func, short device) {
IOSKIP;
} else {
if (T_INST) fprintf(stderr," unimplemented OTA device '%02o function\n", device);
exit(1);
fatal(NULL);
}
break;
}
@@ -396,26 +397,30 @@ void devdisk (short class, short func, short device) {
short halt;
short unit;
short head, track, rec, recsize, nwords;
unsigned short dmachan, dmanch, dmaaddr, dmareg;
short dmanw;
unsigned short dmachan, dmaaddr, dmareg;
short dmanw, dmanch;
char ordertext[8];
char devfile[8];
char devopened[8]; /* device file that is open on devfd */
static int devfd=-1; /* device file descriptor */
int theads, spt, phyra;
static int readnum=0; /* increments on each read */
int rtfd; /* read trace file descriptor */
char rtfile[16]; /* read trace file name */
int rtnw; /* total number of words read (all channels) */
switch (class) {
case 0:
if (T_INST) fprintf(stderr," OCP '%2o%2o\n", func, device);
if (T_INST || T_DIO) fprintf(stderr," OCP '%2o%2o\n", func, device);
break;
case 1:
if (T_INST) fprintf(stderr," SKS '%2o%2o\n", func, device);
if (T_INST || T_DIO) fprintf(stderr," SKS '%2o%2o\n", func, device);
break;
case 2:
if (T_INST) fprintf(stderr," INA '%2o%2o\n", func, device);
if (T_INST || T_DIO) fprintf(stderr," INA '%2o%2o\n", func, device);
if (func == 01) /* read device id, clear A first */
crs[A] = device;
else if (func == 011) /* read device id, don't clear A */
@@ -423,14 +428,14 @@ void devdisk (short class, short func, short device) {
else if (func == 017) /* read status */
crs[A] = 0100000;
else {
if (T_INST) fprintf(stderr," unimplemented INA device '%02o function\n", device);
exit(1);
if (T_INST || T_DIO) fprintf(stderr," unimplemented INA device '%02o function\n", device);
fatal(NULL);
}
IOSKIP;
break;
case 3:
if (T_INST) fprintf(stderr," OTA '%02o%02o\n", func, device);
if (T_INST || T_DIO) fprintf(stderr," OTA '%02o%02o\n", func, device);
if (func == 017) { /* set OAR (order address register) */
oar = crs[A];
halt = 0;
@@ -438,7 +443,7 @@ void devdisk (short class, short func, short device) {
unit = -1;
while (!halt) {
order = mem[oar]>>12;
if (T_INST) fprintf(stderr,"\n %o: %o %o %o\n", oar, mem[oar], mem[oar+1], mem[oar+2]);
if (T_INST || T_DIO) fprintf(stderr,"\n %o: %o %o %o\n", oar, mem[oar], mem[oar+1], mem[oar+2]);
if (mem[oar] & 04000) { /* "execute if ..." */
if (order == 2 || order == 5 || order == 6)
oar += 3;
@@ -449,7 +454,7 @@ void devdisk (short class, short func, short device) {
switch (order) {
case 0: /* DHLT = Halt */
halt = 1;
if (T_INST) fprintf(stderr," channel program halt at '%o\n", oar);
if (T_INST || T_DIO) fprintf(stderr," channel program halt at '%o\n", oar);
break;
case 2: /* SFORM = Format */
case 5: /* SREAD = Read */
@@ -464,17 +469,12 @@ void devdisk (short class, short func, short device) {
strcpy(ordertext,"Read");
else if (order == 6)
strcpy(ordertext,"Write");
if (T_INST) fprintf(stderr," %s, head=%d, track=%d, rec=%d, recsize=%d\n", ordertext, head, track, rec, recsize);
dmareg = ((dmachan & 036) << 1) | (dmachan & 1);
dmanw = regs.sym.regdmx[dmareg];
dmanw = -(dmanw>>4);
dmaaddr = regs.sym.regdmx[dmareg+1];
if (T_INST) fprintf(stderr, " DMA channels: nch-1=%d, ['%o]='%o, ['%o]='%o, nwords=%d\n", dmanch, dmachan, regs.sym.regdmx[dmareg], dmachan+1, dmaaddr, dmanw);
if (T_INST || T_DIO) fprintf(stderr," %s, head=%d, track=%d, rec=%d, recsize=%d\n", ordertext, head, track, rec, recsize);
if (devfd == -1) {
if (T_INST) fprintf(stderr," Unit not selected or not ready\n");
if (T_INST || T_DIO) fprintf(stderr," Unit not selected or not ready\n");
status = 0100001;
} else if (order == 2) {
if (T_INST) fprintf(stderr," Format order not implemented\n");
if (T_INST || T_DIO) fprintf(stderr," Format order not implemented\n");
} else if (order == 5) {
/* translate head/track/sector to drive record address */
@@ -482,33 +482,65 @@ void devdisk (short class, short func, short device) {
theads = 40; /* should get total heads from a config file */
spt = 9; /* and sectors per track too */
phyra = (track*theads*spt) + head*9 + rec;
if (T_INST) fprintf(stderr, " phyra=%d, byte offset=%d\n", phyra, phyra*2080);
#if 0
if (phyra == 106987) traceflags = -1;
#endif
if (T_INST || T_DIO) fprintf(stderr, " phyra=%d, byte offset=%d\n", phyra, phyra*2080);
if (lseek(devfd, phyra*2080, SEEK_SET) == -1) {
perror("Unable to seek drive file");
exit(1);
fatal(NULL);
}
if (read(devfd, mem+dmaaddr, dmanw*2) != dmanw*2) {
perror("Unable to read drive file");
exit(1);
readnum++;
rtnw = 0;
while (dmanch >= 0) {
dmareg = ((dmachan & 036) << 1) | (dmachan & 1);
dmanw = regs.sym.regdmx[dmareg];
dmanw = -(dmanw>>4);
dmaaddr = regs.sym.regdmx[dmareg+1];
if (T_INST || T_DIO) fprintf(stderr, " DMA channels: nch-1=%d, ['%o]='%o, ['%o]='%o, nwords=%d\n", dmanch, dmachan, regs.sym.regdmx[dmareg], dmachan+1, dmaaddr, dmanw);
if (read(devfd, mem+dmaaddr, dmanw*2) != dmanw*2) {
perror("Unable to read drive file");
fatal(NULL);
}
if (T_DIO) {
fprintf(stderr, "\nRT: Read #%d.%d, RA=%d, numwords=%d, memaddr=%o, Unix pos=%d\n", readnum, dmanch, phyra, dmanw, dmaaddr, phyra*2080+rtnw*2);
snprintf(rtfile,sizeof(rtfile),"rt/rt%d.%d", readnum, dmanch);
if ((rtfd = open(rtfile, O_WRONLY+O_CREAT, 0777)) == -1) {
printf("Read trace filename: %s\n", rtfile);
perror("Read trace file open");
fatal(NULL);
}
if (write(rtfd, mem+dmaaddr, dmanw*2) != dmanw*2) {
perror("Unable to write read trace file");
fatal(NULL);
}
close(rtfd);
rtnw += dmanw;
if (dmanw == 16)
fprintf(stderr, "RT: cra=%d, bra=%d, cnt=%d, type=%d, next=%d, prev=%d\n", *(int *)(mem+dmaaddr), *(int *)(mem+dmaaddr+2), mem[dmaaddr+4], mem[dmaaddr+5], *(int *)(mem+dmaaddr+6), *(int *)(mem+dmaaddr+8));
}
regs.sym.regdmx[dmareg] = 0;
regs.sym.regdmx[dmareg+1] += dmanw;
dmachan += 2;
dmanch--;
}
regs.sym.regdmx[dmareg] = 0;
regs.sym.regdmx[dmareg+1] += dmanw;
} else if (order == 6) {
if (T_INST) fprintf(stderr," Write order not implemented\n");
printf(" Write order not implemented\n");
exit(1);
}
oar += 3;
break;
case 3: /* SSEEK = Seek */
track = mem[oar+1] & 01777;
if (T_INST) fprintf(stderr," seek track %d, restore=%d, clear=%d\n", track, (mem[oar+1] & 0100000) != 0, (mem[oar+1] & 040000) != 0);
if (T_INST || T_DIO) fprintf(stderr," seek track %d, restore=%d, clear=%d\n", track, (mem[oar+1] & 0100000) != 0, (mem[oar+1] & 040000) != 0);
oar += 2;
break;
case 4: /* DSEL = Select unit */
unit = (mem[oar+1] & 017) >> 1; /* unit = 0/1/2/4 */
if (unit == 4) unit = 3; /* unit = 0/1/2/3 */
snprintf(devfile,sizeof(devfile),"dev%ou%d", device, unit);
if (T_INST) fprintf(stderr," select unit %d, filename %s\n", unit, devfile);
if (T_INST || T_DIO) fprintf(stderr," select unit %d, filename %s\n", unit, devfile);
if (strcmp(devfile,devopened) != 0 || devfd == -1) {
if (devfd != -1) {
close(devfd);
@@ -522,46 +554,46 @@ void devdisk (short class, short func, short device) {
oar += 2;
break;
case 7: /* DSTALL = Stall */
if (T_INST) fprintf(stderr," stall\n");
if (T_INST || T_DIO) fprintf(stderr," stall\n");
oar += 2;
break;
case 9: /* DSTAT = Store status to memory */
memaddr = mem[oar+1];
if (T_INST) fprintf(stderr, " store status='%o to '%o\n", status, memaddr);
if (T_INST || T_DIO) fprintf(stderr, " store status='%o to '%o\n", status, memaddr);
mem[memaddr] = status;
oar += 2;
break;
case 11: /* DOAR = Store OAR to memory (2 words) */
memaddr = mem[oar+1];
if (T_INST) fprintf(stderr, " store OAR='%o to '%o\n", oar, memaddr);
if (T_INST || T_DIO) fprintf(stderr, " store OAR='%o to '%o\n", oar, memaddr);
mem[memaddr] = oar;
oar += 2;
break;
case 13: /* SDMA = select DMA channel(s) to use */
dmanch = mem[oar] & 017;
dmachan = mem[oar+1];
if (T_INST) fprintf(stderr, " set DMA channels, nch-1=%d, channel='%o\n", dmanch, dmachan);
if (T_INST || T_DIO) fprintf(stderr, " set DMA channels, nch-1=%d, channel='%o\n", dmanch, dmachan);
oar += 2;
break;
case 14: /* DINT = generate interrupt through vector address */
memaddr = mem[oar+1];
if (T_INST) fprintf(stderr, " interrupt through '%o\n", memaddr);
exit(1);
if (T_INST || T_DIO) fprintf(stderr, " interrupt through '%o\n", memaddr);
fatal(NULL);
oar += 2;
break;
case 15: /* DTRAN = channel program jump */
oar = mem[oar+1];
if (T_INST) fprintf(stderr, " jump to '%o\n", oar);
if (T_INST || T_DIO) fprintf(stderr, " jump to '%o\n", oar);
break;
default:
if (T_INST) fprintf(stderr, " unrecognized channel order = %d\n", order);
exit(1);
if (T_INST || T_DIO) fprintf(stderr, " unrecognized channel order = %d\n", order);
fatal(NULL);
}
}
IOSKIP;
} else {
if (T_INST) fprintf(stderr," unimplemented OTA device '%02o function\n", device);
exit(1);
if (T_INST || T_DIO) fprintf(stderr," unimplemented OTA device '%02o function\n", device);
fatal(NULL);
}
break;
}

5
os.c
View File

@@ -157,8 +157,13 @@ os_timdat(short *userbuf, short *n) {
tod = time(NULL);
localtime_r(&tod, &tms);
strncpy(timbuf.mmddyy,"042105",6);
#if 0
timbuf.timemins = tms.tm_hour*60 + tms.tm_min;
timbuf.timesecs = tms.tm_sec;
#else
timbuf.timemins = 0;
timbuf.timesecs = 0;
#endif
timbuf.timeticks = 0;
timbuf.cpusecs = timbuf.cputicks = timbuf.iosecs = timbuf.ioticks = 0;
timbuf.tickspersec = 330;

40
regs.h
View File

@@ -1,23 +1,15 @@
#define REGSETS 8
/* these are offsets from into crs (current register set) */
/* these are 16-bit offsets into crs (current register set) */
#define A 4
#define B 5
#define L 4
#define E 6
#if 1
#define S 10
#define Y 10
#define X 14
#else
#define S 11
#define Y 11
#define X 15
#endif
/* XXX: is the floating pt register really split like this? */
#define S 10
#define Y 10
#define X 14
#define FLTH 20
#define FLTL 21
@@ -53,9 +45,28 @@
#define OWNERH 42
#define OWNERL 43
#define FCODE 44
#define FADDR 47
#define FADDR 46
#define TIMER 48
/* these are 32-bit offsets into crsl (current register set long) */
#define GR0 0
#define GR1 1
#define GR2 2
#define GR3 3
#define GR4 4
#define GR5 5
#define GR6 6
#define GR7 7
#define FAR0 8
#define FLR0 9
#define FAR1 10
#define FLR1 11
#define FAC0H 8
#define FAC0L 9
#define FAC1H 10
#define FAC1L 11
union {
int rs[REGSETS][32];
@@ -91,6 +102,7 @@
} regs;
unsigned short *crs;
unsigned int *crsl;
/* define mapping between memory addresses and the current register set */
@@ -105,7 +117,7 @@ unsigned short memtocrs[] = {
-1, /* 7 = PC (this is in the microcode scratch register set - TR7) */
32, /* 10 = unnamed */
FCODE, /* 11 = FCODE */
FADDR, /* 12 = FADDR */
FADDR+1,/* 12 = FADDR (word) */
16, /* 13 = unnamed */
SBH, /* 14 = unnamed (SB seg) */
SBL, /* 15 = unnamed (SB word) */