1
0
mirror of https://github.com/prirun/p50em.git synced 2026-02-04 07:12:49 +00:00

address trap changes, trace format change, added warn(), FP fixes

This commit is contained in:
Jim
2005-09-12 00:00:00 -04:00
parent 34e057b7b7
commit e20a46e164
2 changed files with 202 additions and 132 deletions

176
em.c
View File

@@ -66,13 +66,6 @@ typedef unsigned int pa_t; /* physical address */
else if (*(int *)(crs+L) < 0) \
crs[KEYS] |= 0200;
#define SETCC_LE \
crs[KEYS] &= ~0300; \
if (*(int *)(crs+L) == 0 && *(int *)(crs+E) == 0) \
crs[KEYS] |= 0100; \
else if (*(int *)(crs+L) < 0) \
crs[KEYS] |= 0200;
/* NOTE: in previous versions, exponent must be zero for 0.0, but DIAG
test CPU.FLOAT.V considers a zero fraction and non-zero exponent to
also be 0.0 (this is a "dirty zero") */
@@ -130,16 +123,16 @@ typedef unsigned int pa_t; /* physical address */
print something when they're encountered */
unsigned short gen0tab[] = {
000503, /* EMCM */
000501, /* LMCM */
001304, /* MDEI */
001305, /* MDII */
001324, /* MDIW */
001306, /* MDRS */
001307, /* MDWC */
000021, /* RMC */
000311, /* VIFY */
001113}; /* XVFY */
000503, /* EMCM - enter machine check mode */
000501, /* LMCM - leave machine check mode */
001304, /* MDEI - memory diagnostic */
001305, /* MDII - memory diagnostic */
001324, /* MDIW - memory diagnostic */
001306, /* MDRS - memory diagnostic */
001307, /* MDWC - memory diagnostic */
000021, /* RMC - reset machine check */
000311, /* VIFY - ucode verify */
001113}; /* XVFY - extended ucode verify */
#define GEN0TABSIZE sizeof(gen0tab)/sizeof(unsigned short)
@@ -218,7 +211,7 @@ unsigned long instcount=0; /* global instruction count */
unsigned short inhcount = 0; /* number of instructions to stay inhibited */
unsigned int instpermsec = 2400; /* initial assumption for inst/msec */
unsigned int instpermsec = 2600; /* initial assumption for inst/msec */
jmp_buf jmpbuf; /* for longjumps to the fetch loop */
@@ -598,7 +591,7 @@ unsigned short get16r(ea_t ea, ea_t rpring) {
/* check for live register access */
if (ea & 0x80000000 || (!(crs[KEYS] & 010000) && (ea & 0xFFFF) < 040)) {
if (ea & 0x80000000) {
ea = ea & 0xFFFF;
if (ea < 7)
return crs[memtocrs[ea]];
@@ -623,7 +616,7 @@ unsigned int get32r(ea_t ea, ea_t rpring) {
/* check for live register access */
if (ea & 0x80000000)
fatal("Address trap in get32!");
warn("address trap in get32");
pa = mapva(ea, RACC, &access, rpring);
@@ -644,7 +637,7 @@ double get64r(ea_t ea, ea_t rpring) {
/* check for live register access */
if (ea & 0x80000000)
fatal("Address trap in get64!");
warn("address trap in get64");
pa = mapva(ea, RACC, &access, rpring);
if ((pa & 01777) <= 01774)
@@ -663,7 +656,7 @@ put16r(unsigned short value, ea_t ea, ea_t rpring) {
pa_t pa;
unsigned short access;
if (ea & 0x80000000 || (!(crs[KEYS] & 010000) && (ea & 0xFFFF) < 040)) {
if (ea & 0x80000000) {
ea = ea & 0xFFFF;
if (ea < 7)
crs[memtocrs[ea]] = value;
@@ -694,7 +687,7 @@ put32r(unsigned int value, ea_t ea, ea_t rpring) {
/* check for live register access */
if (ea & 0x80000000)
fatal("Address trap in put32!");
warn("address trap in put32");
pa = mapva(ea, WACC, &access, rpring);
if ((pa & 01777) <= 01776)
@@ -714,7 +707,7 @@ put64r(double value, ea_t ea, ea_t rpring) {
/* check for live register access */
if (ea & 0x80000000)
fatal("Address trap in put32!");
warn("address trap in put32");
pa = mapva(ea, WACC, &access, rpring);
if ((pa & 01777) <= 01774)
@@ -917,13 +910,16 @@ void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) {
fatal(char *msg) {
printf("Fatal error: instruction #%d at %o/%o: %o %o\n", instcount, prevpc >> 16, prevpc & 0xFFFF, get16(prevpc), get16(prevpc+1));
printf("Fatal error: instruction #%d at %o/%o %s: %o %o keys=%o, modals=%o\n", instcount, prevpc >> 16, prevpc & 0xFFFF, searchloadmap(prevpc,' '), get16(prevpc), get16(prevpc+1), crs[KEYS], crs[MODALS]);
if (msg)
printf("%s\n", msg);
printf("keys = %o, modals=%o\n", crs[KEYS], crs[MODALS]);
/* should do a register dump, RL dump, PCB dump, etc. here... */
exit(1);
}
warn(char *msg) {
printf("emulator warning:\n instruction #%d at %o/%o: %o %o keys=%o, modals=%o\n %s\n", instcount, prevpc >> 16, prevpc & 0xFFFF, get16(prevpc), get16(prevpc+1),crs[KEYS], crs[MODALS], msg);
}
/* I/O device map table, containing function pointers to handle device I/O */
@@ -955,9 +951,13 @@ unsigned short readshort () {
ea_t ea16s (unsigned short inst, short i, short x) {
unsigned short ea, m, rpl, amask;
unsigned short ea, m, rpl, amask, live;
ea_t va;
if (crs[MODALS] & 4) /* segmentation enabled? */
live = 010; /* yes, limit register traps */
else
live = 040;
amask = 037777;
rpl = prevpc;
if (inst & 001000)
@@ -969,8 +969,7 @@ ea_t ea16s (unsigned short inst, short i, short x) {
ea += crs[X];
if (!i) /* not indirect */
break;
/* NOTE: this test is already in get16... */
if (ea < 040)
if (ea < live)
m = get16(0x80000000|ea);
else
m = get16(MAKEVA(RPH,ea));
@@ -979,7 +978,7 @@ ea_t ea16s (unsigned short inst, short i, short x) {
ea = m & 037777; /* go indirect */
}
va = MAKEVA(RPH, ea);
if (ea < 040) /* flag live register ea */
if (ea < live) /* flag live register ea */
return va | 0x80000000;
return va;
}
@@ -989,9 +988,14 @@ ea_t ea16s (unsigned short inst, short i, short x) {
ea_t ea32s (unsigned short inst, short i, short x) {
unsigned short ea, m,rpl,amask;
unsigned short ea, m,rpl, amask, live;
ea_t va;
if (crs[MODALS] & 4) /* segmentation enabled? */
live = 010; /* yes, limit register traps */
else
live = 040;
amask = 077777;
rpl = prevpc;
if (inst & 001000)
ea = (rpl & 077000) | (inst & 0777); /* current sector */
@@ -1014,7 +1018,7 @@ ea_t ea32s (unsigned short inst, short i, short x) {
ea += crs[X];
ea &= amask;
va = MAKEVA(RPH, ea);
if (ea < 040) /* flag live register ea */
if (ea < live) /* flag live register ea */
return va | 0x80000000;
return va;
}
@@ -1026,10 +1030,16 @@ ea_t ea32s (unsigned short inst, short i, short x) {
ea_t ea32r64r (ea_t earp, unsigned short inst, short i, short x, unsigned short *opcode) {
short class;
unsigned short ea,m,rph,rpl;
unsigned short live, ea, m, rph, rpl, amask, class;
ea_t va;
if (crs[MODALS] & 4) /* segmentation enabled? */
live = 010; /* yes, limit register traps */
else
live = 040;
amask = 0177777;
if ((crs[KEYS] & 016000) == 06000) /* 32R mode? */
amask = 077777;
rpl = earp;
rph = (earp >> 16) & 0x7FFF; /* clear fault (live register) bit from RP */
if (T_EAR) fprintf(stderr," ea32r64r: i=%o, x=%o, amask=%o\n", i!= 0, x!=0, amask);
@@ -1051,7 +1061,7 @@ ea_t ea32r64r (ea_t earp, unsigned short inst, short i, short x, unsigned short
}
}
while (i) {
if (ea < 040)
if (ea < live)
m = get16(0x80000000|ea);
else
m = get16(MAKEVA(rph,ea));
@@ -1070,7 +1080,7 @@ ea_t ea32r64r (ea_t earp, unsigned short inst, short i, short x, unsigned short
}
ea &= amask;
va = MAKEVA(rph, ea);
if (ea < 040) /* flag live register ea */
if (ea < live) /* flag live register ea */
return va | 0x80000000;
return va;
@@ -1090,7 +1100,7 @@ special:
if (T_EAR) fprintf(stderr," Preindex, new ea=%o\n", ea);
}
while (i) {
if (ea < 040)
if (ea < live)
m = get16(0x80000000|ea);
else
m = get16(MAKEVA(rph,ea));
@@ -1105,12 +1115,12 @@ special:
} else if (i && x) { /* class 2/3, ix=11 */
if (T_EAR) fprintf(stderr," class 2/3, ix=11\n");
ea = get16(MAKEVA(rph,RPL++)); /* get A from next word */
ea = get16(MAKEVA(RPH,RPL++)); /* get A from next word */
if (T_EAR) fprintf(stderr," ea=%o\n", ea);
if (class == 3)
ea += (short) crs[S];
while (i) {
if (ea < 040)
if (ea < live)
m = get16(0x80000000|ea);
else
m = get16(MAKEVA(rph,ea));
@@ -1133,7 +1143,7 @@ special:
ea = --crs[S];
if (T_EAR) fprintf(stderr," Class 2/3, new ea=%o, new S=%o\n", ea, crs[S]);
if (x) {
if (ea < 040)
if (ea < live)
m = get16(0x80000000|ea);
else
m = get16(MAKEVA(rph,ea));
@@ -1142,7 +1152,7 @@ special:
ea = m & amask;
}
while (i) {
if (ea < 040)
if (ea < live)
m = get16(0x80000000|ea);
else
m = get16(MAKEVA(rph,ea));
@@ -1157,7 +1167,7 @@ special:
}
ea &= amask;
va = MAKEVA(rph, ea);
if (ea < 040) /* flag live register ea */
if (ea < live) /* flag live register ea */
return va | 0x80000000;
return va;
}
@@ -2751,7 +2761,7 @@ main (int argc, char **argv) {
traceflags = ~TB_MAP;
#endif
#if 0
#if 1
if (traceflags != 0)
savetraceflags = traceflags;
if (crs[OWNERL] == 0100100 && savetraceflags)
@@ -3463,6 +3473,7 @@ stfa:
stlb[utempa].valid = 0;
if (T_INST) fprintf(stderr," invalidated STLB index %d\n", utempa);
}
#if 0
/* HACK for DIAG to suppress ITLB loop in trace */
if (RP == 0106070)
if (*(int *)(crs+L) == 0) {
@@ -3473,6 +3484,7 @@ stfa:
fprintf(stderr," Restoring DIAG trace\n");
traceflags = savetraceflags;
}
#endif
continue;
case 000711:
@@ -3497,8 +3509,8 @@ stfa:
fault(UIIFAULT, RPL, RP);
continue;
/* I think this is an invalid opcode that Prime uses when unexpected
things happen, for example:
/* JW: I think this is an invalid opcode that Prime uses when
unexpected things happen, for example:
LDA modals get modals
SAS 1 interrupts enabled?
@@ -4391,13 +4403,16 @@ lcgt:
case 0140550:
if (T_FLOW) fprintf(stderr," FLOT\n");
templ = crs[A];
templ = *(short *)(crs+A);
templ = crs[B] | (templ<<15);
tempf = templ;
tempf1 = tempf;
ieeepr4(&tempf);
crs[FLTH] = (*(unsigned int *)&tempf) >> 16;
crs[FLTL] = (*(unsigned int *)&tempf) & 0xFF00;
crs[FEXP] = (*(unsigned int *)&tempf) & 0xFF;
crs[FLTD] = 0;
if (T_INST) fprintf(stderr," A|B=%d, conv=%f, FEXP=%d (dec), FLTH='%o, FLTL='%o\n", templ, tempf1, crs[FEXP], crs[FLTH], crs[FLTL]);
continue;
case 0140534:
@@ -4499,13 +4514,15 @@ lcgt:
tempda[2] = crs[FLTD];
tempda[3] = crs[FEXP];
prieee8(tempda);
if (T_INST) fprintf(stderr," DFAC value=%f, FEXP=%d (dec), FLTH='%o, FLTL='%o, fltd='%o\n", *(double *)tempda, crs[FEXP], crs[FLTH], crs[FLTL], crs[FLTD]);
templ = *(double *)tempda;
if (T_INST) fprintf(stderr," INT value=%d\n", templ);
crs[B] = templ & 0x7FFF;
crs[A] = templ >> 15;
if (*(double *)tempda > 1073741823.0 || *(double *)tempda < -1073741824.0)
mathexception('f', FC_DFP_OFLOW, ea);
else
CLEARC;
templ = *(double *)tempda;
crs[B] = templ & 0x7FFF;
crs[A] = templ >> 15;
continue;
case 0140531:
@@ -4519,7 +4536,7 @@ lcgt:
mathexception('f', FC_DFP_OFLOW, ea);
else
CLEARC;
tempa = *(double *)tempda;
*(short *)(crs+A) = *(double *)tempda;
continue;
case 0140532:
@@ -4529,6 +4546,7 @@ lcgt:
crs[FLTH] = (*(unsigned int *)&tempf) >> 16;
crs[FLTL] = (*(unsigned int *)&tempf) & 0xFF00;
crs[FEXP] = (*(unsigned int *)&tempf) & 0xFF;
crs[FLTD] = 0;
continue;
case 0140533:
@@ -4542,7 +4560,7 @@ lcgt:
mathexception('f', FC_DFP_OFLOW, ea);
else
CLEARC;
templ = *(double *)tempda;
*(int *)(crs+L) = *(double *)tempda;
continue;
case 0140535:
@@ -4552,6 +4570,7 @@ lcgt:
crs[FLTH] = (*(unsigned int *)&tempf) >> 16;
crs[FLTL] = (*(unsigned int *)&tempf) & 0xFF00;
crs[FEXP] = (*(unsigned int *)&tempf) & 0xFF;
crs[FLTD] = 0;
continue;
case 0141711:
@@ -4563,7 +4582,7 @@ lcgt:
continue;
#if 0
case 0141602: /* same opcode as BCNE */
case 0141602: /* same opcode as BCEQ */
if (T_FLOW) fprintf(stderr," BMEQ\n");
goto bceq;
@@ -4581,11 +4600,6 @@ lcgt:
#endif
case 0141710:
#if 0
/* this is good for tracing the failure if cpuid is set to 15 in
Primos boot. Weird memory maps for 9950 16MB? */
traceflags = -1;
#endif
if (T_FLOW) fprintf(stderr," BMGT\n");
if (crs[KEYS] & 020000)
goto bcne;
@@ -4908,7 +4922,7 @@ lcgt:
break;
default:
printf("WARNING: unrecognized shift instruction %o at %o/%o\n", inst, RPH, RPL);
printf("emulator warning: unrecognized shift instruction %o at %o/%o\n", inst, RPH, RPL);
if (T_INST) fprintf(stderr," unrecognized shift instruction!: %o\n", inst);
}
continue;
@@ -5128,7 +5142,8 @@ keys = 14200, modals=100177
break;
case 4: /* 32I */
ea = ea32i(earp, inst, i, x);
fatal("32I not supported");
warn("32I mode not supported");
fault(RESTRICTFAULT, 0, 0);
break;
case 6: /* 64V */
ea = ea64v(earp, inst, i, x, &opcode, &eabit);
@@ -5208,7 +5223,7 @@ keys = 14200, modals=100177
crs[A] = utempl;
if (utempl & 0x10000) /* set L-bit if carry */
crs[KEYS] |= 020000;
/* NOTE: the EQ test prevents use from reusing the ADD code :( */
/* NOTE: this EQ test prevents reusing the ADD code :( */
if (*(int *)(crs+L) == 0) /* set EQ? */
crs[KEYS] |= 0100;
if (((~utempa ^ m) & (utempa ^ crs[A])) & 0x8000) {
@@ -5285,9 +5300,11 @@ keys = 14200, modals=100177
case 01000:
if (T_FLOW) fprintf(stderr," JST\n");
#if 0
ea = MAKEVA(RPH, ea & 0xFFFF);
#endif
/* NOTE: amask should be recomputed here if in R/S mode, so it
can be removed as a global variable. Flaky errors occur if
keys are changed w/o calling newkeys(), because amask would
be wrong (see dispatcher comment) */
if (amask == 0177777)
m = RPL;
else
@@ -5298,8 +5315,6 @@ keys = 14200, modals=100177
inhcount = 1;
continue;
/* this should set the C and L bits like subtract */
case 01100:
m = get16(ea);
if (T_FLOW) fprintf(stderr," CAS ='%o/%d\n", m, *(short *)&m);
@@ -5622,17 +5637,19 @@ keys = 14200, modals=100177
case 00601:
if (T_FLOW) fprintf(stderr," FAD\n");
if (T_INST) fprintf(stderr," FEXP=%d (dec), FLTH='%o, FLTL='%o\n", crs[FEXP], crs[FLTH], crs[FLTL]);
//if (T_INST) fprintf(stderr," ea EXP=%d (dec), ea H='%o, ea L='%o\n", (mem[ea+1] & 0xFF), mem[ea], (mem[ea+1] & 0xFF00));
*(int *)&tempf = (crs[FLTH]<<16) | (crs[FLTL] & 0xFF00) | (crs[FEXP] & 0xFF);
prieee4(&tempf);
if (T_INST) fprintf(stderr," FAC value=%f, FEXP=%d (dec), FLTH='%o, FLTL='%o\n", tempf, crs[FEXP], crs[FLTH], crs[FLTL]);
*(int *)&tempf1 = get32(ea);
prieee4(&tempf1);
if (T_INST) fprintf(stderr," ea value=%f, EXP=%d (dec), ea H='%o, ea L='%o\n", tempf1, get16(ea+1) & 0xFF, get16(ea), get16(ea+1) & 0xFF00);
tempf += tempf1;
tempf1 = tempf;
ieeepr4(&tempf);
crs[FLTH] = (*(unsigned int *)&tempf) >> 16;
crs[FLTL] = (*(unsigned int *)&tempf) & 0xFF00;
crs[FEXP] = (*(unsigned int *)&tempf) & 0xFF;
if (T_INST) fprintf(stderr," FAC value=%f, FEXP=%d (dec), FLTH='%o, FLTL='%o\n", tempf1, crs[FEXP], crs[FLTH], crs[FLTL]);
XEXPC(0);
continue;
@@ -5640,12 +5657,12 @@ keys = 14200, modals=100177
case 01101:
if (T_FLOW) fprintf(stderr," FCS\n");
if (T_INST) fprintf(stderr," FEXP=%d (dec), FLTH='%o, FLTL='%o\n", crs[FEXP], crs[FLTH], crs[FLTL]);
//if (T_INST) fprintf(stderr," ea EXP=%d (dec), ea H='%o, ea L='%o\n", (mem[ea+1] & 0xFF), mem[ea], (mem[ea+1] & 0xFF00));
*(int *)&tempf = (crs[FLTH]<<16) | (crs[FLTL] & 0xFF00) | (crs[FEXP] & 0xFF);
prieee4(&tempf);
if (T_INST) fprintf(stderr," FAC value=%f, FEXP=%d (dec), FLTH='%o, FLTL='%o\n", tempf, crs[FEXP], crs[FLTH], crs[FLTL]);
*(int *)&tempf1 = get32(ea);
prieee4(&tempf1);
if (T_INST) fprintf(stderr," ea value=%f, EXP=%d (dec), ea H='%o, ea L='%o\n", tempf1, get16(ea+1) & 0xFF, get16(ea), get16(ea+1) & 0xFF00);
crs[KEYS] &= ~0300;
if (tempf == tempf1) {
RPL++;
@@ -5674,10 +5691,12 @@ keys = 14200, modals=100177
case 0201:
if (T_FLOW) fprintf(stderr," FLD\n");
crs[FLTH] = get16(ea);
m = get16(ea+1);
crs[FLTL] = m & 0xFF00;
crs[FEXP] = m & 0xFF;
utempl = get32(ea);
crs[FLTH] = utempl >> 16;
crs[FLTL] = utempl & 0xFF00;
crs[FEXP] = utempl & 0xFF;
crs[FLTD] = 0;
if (T_INST) fprintf(stderr," FEXP=%d (dec), FLTH='%o, FLTL='%o\n", crs[FEXP], crs[FLTH], crs[FLTL]);
continue;
case 01601:
@@ -5714,6 +5733,7 @@ keys = 14200, modals=100177
case 0401:
if (T_FLOW) fprintf(stderr," FST\n");
if (T_INST) fprintf(stderr," FEXP=%d (dec), FLTH='%o, FLTL='%o\n", crs[FEXP], crs[FLTH], crs[FLTL]);
if (crs[FEXP] & 0xFF00)
mathexception('f', FC_SFP_STORE, ea);
put16(crs[FLTH],ea);
@@ -5929,14 +5949,6 @@ keys = 14200, modals=100177
continue;
default:
#if 0
if (mem[066] != 0) {
if (T_FLOW) fprintf(stderr," JST* '66 [%o]\n", mem[066]);
mem[mem[066]] = RPL;
RPL = mem[066]+1;
continue;
}
#endif
printf("Unknown memory reference opcode: %o\n", opcode);
fatal(NULL);
}
@@ -6232,7 +6244,7 @@ svc() {
/* if location '65 is set, do indirect JST to handle svc */
/* if the svc fault vector is zero, interpret the svc here. This
allows the emulator to run r-mode programs directly */
allows the emulator to run R-mode programs directly */
if ((crs[MODALS] & 010) || get16(065) != 0) {
fault(SVCFAULT, 0, 0);

158
emdev.h
View File

@@ -57,6 +57,7 @@
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>
#include <termios.h>
/* this macro is used when I/O is successful. In VI modes, it sets
the EQ condition code bit. In SR modes, it does a skip */
@@ -68,16 +69,20 @@
RPL++
/* macro to detect if an I/O instruction is followed by JMP *-1 (SR modes)
or BCNE *-2 (VI modes) */
or BCNE *-2 (VI modes). If process exchange is enabled, I/O can never
block. */
#if 1
#define BLOCKIO \
(get16(RP) == 03776 || (get16(RP) == 0141603 && get16(RP+1) == RPL-2))
(!(crs[MODALS] & 010) && (get16(RP) == 03776 || (get16(RP) == 0141603 && get16(RP+1) == RPL-2)))
#else
#define BLOCKIO 0
#endif
/* this is a template for device handlers */
void devnull (short class, short func, short device) {
switch (class) {
@@ -128,8 +133,8 @@ void devnull (short class, short func, short device) {
/* Device '4: system console
NOTES:
- needs to set -icanon -icrnl on system console tty
- only works with ASRATE 3410 - not 7672 (19,200 bps)
- needs to reset tty attributes when emulator shuts down
- Primos only handles ASRATE 110 (10cps), 1010 (30cps), 3410 (960 cps)
- input ID is wrong, causes OCP '0477 on clock interrupt
- instruction counters on output are bogus, need to intercept TNOUA instead
@@ -187,6 +192,7 @@ void devnull (short class, short func, short device) {
*/
void devasr (short class, short func, short device) {
static int ttydev;
@@ -194,7 +200,8 @@ void devasr (short class, short func, short device) {
static int needflush; /* true if data has been written but not flushed */
static int atbol=1; /* true if cursor is at bol */
static int atnewl=1; /* true if cursor is on a blank line */
fd_set readfds;
static struct termios terminfo;
static fd_set fds;
struct timeval timeout;
unsigned char ch;
int newflags;
@@ -213,8 +220,19 @@ void devasr (short class, short func, short device) {
perror(" unable to get tty flags");
fatal(NULL);
}
FD_ZERO(&readfds);
FD_SET(ttydev, &readfds);
FD_ZERO(&fds);
if (tcgetattr(ttydev, &terminfo) == -1) {
perror(" unable to get tty attributes");
fatal(NULL);
}
terminfo.c_iflag &= ~(INLCR | ICRNL);
terminfo.c_lflag &= ~(ECHOCTL | ICANON);
terminfo.c_cc[VMIN] = 0;
terminfo.c_cc[VTIME] = 0;
if (tcsetattr(ttydev, TCSANOW, &terminfo) == -1) {
perror(" unable to set tty attributes");
fatal(NULL);
}
break;
case 0:
@@ -223,27 +241,46 @@ void devasr (short class, short func, short device) {
case 1:
if (T_INST) fprintf(stderr," SKS '%02o%02o\n", func, device);
if (func == 7) { /* skip if received a char */
timeout.tv_sec = 0;
if (func == 6) { /* skip if room for a character */
#if 0
timeout.tv_usec = 100000;
#else
timeout.tv_usec = 1;
timeout.tv_sec = 0;
timeout.tv_usec = 0;
#endif
if (select(1, &readfds, NULL, NULL, &timeout) == 1)
FD_SET(ttydev, &fds);
n = select(ttydev+1, NULL, &fds, NULL, &timeout);
if (n == -1) {
perror(" unable to do write select on ttydev");
fatal(NULL);
}
if (n) {
IOSKIP;
}
#else
IOSKIP; /* assume there is room under Unix */
#endif
} else if (func == 7) { /* skip if received a char */
if (crs[MODALS] & 010) /* PX enabled? */
timeout.tv_sec = 0; /* yes, can't delay */
else
timeout.tv_sec = 1;
timeout.tv_usec = 0;
FD_SET(ttydev, &fds);
n = select(ttydev+1, &fds, NULL, NULL, &timeout);
if (n == -1) {
perror(" unable to do select on tty");
fatal(NULL);
}
if (n) {
IOSKIP;
}
} else if (func <= 014)
IOSKIP; /* assume it's always ready */
break;
case 2:
if (T_INST) fprintf(stderr," INA '%02o%02o\n", func, device);
if (needflush) {
fflush(stdout);
needflush = 0;
devpoll[device] = 0;
}
if (func == 0 || func == 010) {
if (BLOCKIO)
newflags = ttyflags & ~O_NONBLOCK;
@@ -254,6 +291,11 @@ void devasr (short class, short func, short device) {
fatal(NULL);
}
ttyflags = newflags;
if (needflush && BLOCKIO) {
fflush(stdout);
needflush = 0;
devpoll[device] = 0;
}
readasr:
n = read(ttydev, &ch, 1);
if (n < 0) {
@@ -263,16 +305,19 @@ readasr:
}
} else if (n == 1) {
if (ch == '') {
traceflags = -1;
traceflags = ~TB_MAP;
fprintf(stderr,"\nTRACE ENABLED:\n\n");
memdump(0, 0xFFFF);
traceflags = ~traceflags;
traceflags &= ~TB_MAP;
if (traceflags == 0)
fprintf(stderr,"\nTRACE DISABLED:\n\n");
else
fprintf(stderr,"\nTRACE ENABLED:\n\n");
//memdump(0, 0xFFFF);
goto readasr;
}
if (func >= 010)
crs[A] = 0;
crs[A] = crs[A] | ch;
if (T_INST) fprintf(stderr," character read=%o: %c\n", crs[A], crs[A]);
if (T_INST) fprintf(stderr," character read=%o: %c\n", crs[A], crs[A] & 0x7f);
IOSKIP;
} else if (n != 0) {
printf("Unexpected error reading from tty, n=%d", n);
@@ -301,24 +346,39 @@ readasr:
if (func == 0) {
ch = crs[A] & 0x7f;
if (T_INST) fprintf(stderr," char to write=%o: %c\n", crs[A], ch);
if (ch > 0) {
#if 0
if (atbol && atnewl)
printf("%10d| ", instcount);
#endif
putchar(ch);
if (ch == 015)
atbol = 1;
else if (ch == 012)
atnewl = 1;
else {
atbol = 0;
atnewl = 0;
}
needflush = 1;
devpoll[device] = instpermsec*100;
if (ch == 0 || ch == 0x7f) {
IOSKIP;
return;
}
IOSKIP; /* OTA '0004 always works on Unix */
#if 0
timeout.tv_sec = 0;
timeout.tv_usec = 0;
FD_SET(2, &fds);
n = select(2+1, NULL, &fds, NULL, &timeout);
if (n == -1) {
perror(" unable to do write select on stdout");
fatal(NULL);
}
if (!n)
return;
#endif
#if 0
if (atbol && atnewl)
printf("%10d| ", instcount);
#endif
putchar(ch);
if (ch == 015)
atbol = 1;
else if (ch == 012)
atnewl = 1;
else {
atbol = 0;
atnewl = 0;
}
needflush = 1;
if (devpoll[device] == 0)
devpoll[device] = instpermsec*100;
IOSKIP;
} else if (func == 1) { /* write control word */
IOSKIP;
} else if (04 <= func && func <= 07) { /* write control register 1/2 */
@@ -336,10 +396,13 @@ readasr:
break;
case 4:
/* since the tty device is in non-blocking mode under Primos, keep
flushing output every .1 seconds for smoothest and fastest
output */
if (needflush) {
fflush(stdout);
needflush = 0;
devpoll[device] = 0;
needflush = 1;
devpoll[device] = instpermsec*100;
}
}
}
@@ -655,11 +718,6 @@ void devdisk (short class, short func, short device) {
if (func == 01) /* read device id, clear A first */
crs[A] = CID4005 + device;
#if 0
/* this happens when the clock poll rate is set to 100000 (?) */
else if (func == 06) /* don't know what this is... */
return;
#endif
else if (func == 011) /* read device id, don't clear A */
crs[A] |= (CID4005 + device);
else if (func == 017) { /* read OAR */
@@ -727,7 +785,7 @@ void devdisk (short class, short func, short device) {
dc[device].status = 0100001;
} else if (order == 2) {
if (T_INST || T_DIO) fprintf(stderr," Format order\n");
fatal("DFORMAT channel order not implemented");
//fatal("DFORMAT channel order not implemented");
} else { /* order = 5 (read) or 6 (write) */
/* translate head/track/sector to drive record address */
@@ -799,7 +857,7 @@ void devdisk (short class, short func, short device) {
case 7: /* DSTALL = Stall */
if (T_INST || T_DIO) fprintf(stderr," stall\n");
#if 1
#if 0
devpoll[device] = instpermsec/5; /* 200 microseconds, sb 210 */
return;
#else