mirror of
https://github.com/prirun/p50em.git
synced 2026-01-19 09:08:33 +00:00
MPY, DIV, devasr, devamlc changes +
for R-mode MPY, do the math THEN generate the exception DIV exception handling was wrong, code was wrong too a few devasr changes changed devamlc to always turn off parity instead of flipping it
This commit is contained in:
parent
8f1833c843
commit
ec2ba390d0
4
ea64v.h
4
ea64v.h
@ -1,7 +1,7 @@
|
||||
/* this version is derived from the flowchart in the preliminary P400
|
||||
release notes */
|
||||
|
||||
ea_t ea64v (ea_t earp, unsigned short inst, short i, short x, unsigned short *opcode, unsigned short *bit) {
|
||||
inline ea_t ea64v (ea_t earp, unsigned short inst, short x, unsigned short *opcode, unsigned short *bit) {
|
||||
|
||||
ea_t ea; /* full seg/word va */
|
||||
unsigned short ea_s; /* eff address segno */
|
||||
@ -9,6 +9,7 @@ ea_t ea64v (ea_t earp, unsigned short inst, short i, short x, unsigned short *op
|
||||
unsigned short ea_w; /* eff address wordno */
|
||||
unsigned short br;
|
||||
unsigned short live; /* max live register addr */
|
||||
unsigned short i;
|
||||
unsigned short y;
|
||||
unsigned short xok;
|
||||
unsigned short a;
|
||||
@ -17,6 +18,7 @@ ea_t ea64v (ea_t earp, unsigned short inst, short i, short x, unsigned short *op
|
||||
unsigned short rph,rpl;
|
||||
|
||||
*bit = 0;
|
||||
i = inst & 0100000; /* indirect is bit 1 (left/MS bit) */
|
||||
|
||||
/* rph/rpl (and earp) are usually = RPH/RPL in the register file,
|
||||
except for the case of an XEC instruction; in that case, these
|
||||
|
||||
158
em.c
158
em.c
@ -28,7 +28,7 @@
|
||||
-------------
|
||||
Usage: to load SAM.SAVE from Unix FS and run diagnostics from pdev 2466
|
||||
|
||||
$ time ./em -cpuid 5 -ss 14114 -boot SAM.SAVE 2>err
|
||||
$ time ./em -cpuid 5 -ss 14114 -boot SAM.SAVE 2>err
|
||||
|
||||
[SAM Rev. 16.2, DTS Release: 0004.A, Copyright (c) 1990, Prime Computer, Inc.]
|
||||
Enter physical device = 2466
|
||||
@ -41,7 +41,7 @@ SAM>
|
||||
--------------
|
||||
Usage: to load initial boot from tape, then prompt for disk pdev
|
||||
|
||||
$ time ./em -boot 1005 -tport 8000 -cpuid 5
|
||||
$ time ./em -boot 1005 -tport 8000 -cpuid 5
|
||||
Boot file is dev14u0 <--- note tape drive boot
|
||||
Sense switches set to 1005 <--- these cause pdev prompt
|
||||
[BOOT Rev. 20.2.3 Copyright (c) 1987, Prime Computer, Inc.]
|
||||
@ -52,8 +52,25 @@ DISK ERROR, STATUS: 000001
|
||||
PHYSICAL DEVICE=
|
||||
|
||||
---------------
|
||||
Usage: to load .SAVE image from tape:
|
||||
|
||||
Instruction details are spewed to stderr depending on the trace flags.
|
||||
$ time ./em -boot 10005
|
||||
[BOOT Rev. 20.2.3 Copyright (c) 1987, Prime Computer, Inc.]
|
||||
|
||||
RUN FILE TREENAME=MFD>DOS>DOS.SAVE
|
||||
|
||||
BOOTING FROM MT0 MFD>DOS>DOS.SAVE
|
||||
|
||||
|
||||
PRIMOS II REV 20.0 03/15/85 (AT 170000)
|
||||
Copyright (c) Prime Computer, Inc. 1985.
|
||||
PRIMOS II is being phased out. To boot PRIMOS return to CP mode.
|
||||
("BOOT 14xxx" will autoboot PRIMOS.)
|
||||
|
||||
OK:
|
||||
---------------
|
||||
|
||||
Instruction details are spewed to trace.log depending on the trace flags.
|
||||
|
||||
IMPORTANT NOTE: this only runs on a big-endian machine, like the Prime.
|
||||
*/
|
||||
@ -250,7 +267,7 @@ int intvec=-1; /* currently raised interrupt (if >= zero)
|
||||
/* NOTE: Primos II gives "NOT FOUND" on startup 2460 if sense switches
|
||||
are set to 014114. But DIAGS like this sense switch setting. :( */
|
||||
|
||||
unsigned short sswitch = 0; /* sense switches, set with -ss & -boot*/
|
||||
unsigned short sswitch = 014114; /* sense switches, set with -ss & -boot*/
|
||||
|
||||
/* NOTE: the default cpuid is a 4150: 2 MIPS, 32MB of memory */
|
||||
|
||||
@ -331,11 +348,16 @@ unsigned int prevpc; /* backed program counter */
|
||||
unsigned short amask; /* address mask */
|
||||
|
||||
#define FAULTMASK32 0x80000000 /* fault bit */
|
||||
#define RINGMASK32 0x60000000 /* ring bits */
|
||||
#define EXTMASK32 0x10000000 /* E-bit */
|
||||
#define SEGMASK32 0x0FFF0000 /* segment number */
|
||||
#define RINGMASK16 0x6000 /* ring bits */
|
||||
#define EXTMASK16 0x1000 /* E-bit */
|
||||
#define RINGMASK32 0x60000000 /* ring bits */
|
||||
#define EXTMASK32 0x10000000 /* E-bit */
|
||||
#define SEGMASK32 0x0FFF0000 /* segment number */
|
||||
#define RINGMASK16 0x6000 /* ring bits */
|
||||
#define EXTMASK16 0x1000 /* E-bit */
|
||||
|
||||
#define DTAR(ea) (((ea)>>26) & 3)
|
||||
#define SEGNO(ea) (((ea)>>16) & 07777)
|
||||
#define PAGENO(ea) (((ea)>>10) & 077)
|
||||
|
||||
|
||||
/* Fault/interrupt vectors */
|
||||
|
||||
@ -491,7 +513,8 @@ char *searchloadmap(int addr, char type) {
|
||||
static char buf[MAXBUFIX][100];
|
||||
static int bufix=-1;
|
||||
|
||||
if ((ix = findsym(addr, type)) > 0) {
|
||||
if ((SEGNO(addr) <= 01777 | SEGNO(addr) >= 06000) &&
|
||||
(ix = findsym(addr, type)) > 0) {
|
||||
diff = addr - mapsym[ix].address;
|
||||
if (diff) {
|
||||
if (++bufix == MAXBUFIX)
|
||||
@ -505,10 +528,6 @@ char *searchloadmap(int addr, char type) {
|
||||
}
|
||||
|
||||
|
||||
#define DTAR(ea) (((ea)>>26) & 3)
|
||||
#define SEGNO(ea) (((ea)>>16) & 07777)
|
||||
#define PAGENO(ea) (((ea)>>10) & 077)
|
||||
|
||||
/* intended memory access types:
|
||||
1 = PCL (PACC)
|
||||
2 = read (RACC)
|
||||
@ -705,7 +724,7 @@ double get64r(ea_t ea, ea_t rpring) {
|
||||
Ring 0. I tried using get64 (with appropriate mask changes) and
|
||||
performance was much worse than not prefetching at all on a G4 */
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
inline unsigned short iget16(ea_t ea) {
|
||||
static ea_t eafirst = -1; /* ea of instruction buffer */
|
||||
static unsigned short insts[2]; /* instruction buffer */
|
||||
@ -1000,7 +1019,7 @@ void fault(unsigned short fvec, unsigned short fcode, ea_t faddr) {
|
||||
|
||||
/* I/O device map table, containing function pointers to handle device I/O */
|
||||
|
||||
long devpoll[64] = {0};
|
||||
int devpoll[64] = {0};
|
||||
|
||||
#include "emdev.h"
|
||||
|
||||
@ -1022,7 +1041,7 @@ int (*devmap[64])(short, short, short) = {
|
||||
|
||||
/* this is the "minimum system" controller configuration */
|
||||
|
||||
int (*devmap[64])(short, short, short) = {
|
||||
int (*devmap[64])(int, int, int) = {
|
||||
/* '0x */ 0,0,0,0,devasr,0,0,devpnc,
|
||||
#if 1
|
||||
/* '1x */ devnone,devnone,0,devnone,devmt,devnone, devnone, devnone,
|
||||
@ -1041,11 +1060,12 @@ int (*devmap[64])(short, short, short) = {
|
||||
|
||||
/* 16S Addressing Mode */
|
||||
|
||||
ea_t ea16s (unsigned short inst, short i, short x) {
|
||||
ea_t ea16s (unsigned short inst, short x) {
|
||||
|
||||
unsigned short ea, m, rpl, amask, live;
|
||||
unsigned short ea, m, rpl, amask, live, i;
|
||||
ea_t va;
|
||||
|
||||
i = inst & 0100000; /* indirect */
|
||||
if (crs[MODALS] & 4) /* segmentation enabled? */
|
||||
live = 010; /* yes, limit register traps */
|
||||
else
|
||||
@ -1078,11 +1098,12 @@ ea_t ea16s (unsigned short inst, short i, short x) {
|
||||
|
||||
/* 32S Addressing Mode */
|
||||
|
||||
ea_t ea32s (unsigned short inst, short i, short x) {
|
||||
ea_t ea32s (unsigned short inst, short x) {
|
||||
|
||||
unsigned short ea, m,rpl, amask, live;
|
||||
unsigned short ea, m,rpl, amask, live, i;
|
||||
ea_t va;
|
||||
|
||||
i = inst & 0100000; /* indirect */
|
||||
if (crs[MODALS] & 4) /* segmentation enabled? */
|
||||
live = 010; /* yes, limit register traps */
|
||||
else
|
||||
@ -1120,11 +1141,12 @@ ea_t ea32s (unsigned short inst, short i, short x) {
|
||||
bit, is that 32R indirect words have an indirect bit for multi-level
|
||||
indirects */
|
||||
|
||||
ea_t ea32r64r (ea_t earp, unsigned short inst, short i, short x, unsigned short *opcode) {
|
||||
ea_t ea32r64r (ea_t earp, unsigned short inst, short x, unsigned short *opcode) {
|
||||
|
||||
unsigned short live, ea, m, rph, rpl, amask, class;
|
||||
unsigned short live, ea, m, rph, rpl, amask, class, i;
|
||||
ea_t va;
|
||||
|
||||
i = inst & 0100000; /* indirect */
|
||||
if (crs[MODALS] & 4) /* segmentation enabled? */
|
||||
live = 010; /* yes, limit register traps */
|
||||
else
|
||||
@ -1266,7 +1288,7 @@ special:
|
||||
|
||||
#include "ea64v.h"
|
||||
|
||||
unsigned int ea32i (ea_t earp, unsigned short inst, short i, short x) {
|
||||
unsigned int ea32i (ea_t earp, unsigned short inst, short x) {
|
||||
TRACE(T_EAI, "Mode 32I not implemented\n");
|
||||
}
|
||||
|
||||
@ -2737,7 +2759,7 @@ main (int argc, char **argv) {
|
||||
short i,j,x;
|
||||
unsigned short savemask;
|
||||
unsigned short class;
|
||||
int nw;
|
||||
int nw,nw2;
|
||||
unsigned short rvec[9]; /* SA, EA, P, A, B, X, keys, dummy, dummy */
|
||||
unsigned short inst;
|
||||
unsigned short m,m1,m2;
|
||||
@ -2932,8 +2954,6 @@ main (int argc, char **argv) {
|
||||
Bits 11-12 are the unit number, 0-4
|
||||
*/
|
||||
|
||||
if (sswitch == 0)
|
||||
sswitch = 014114;
|
||||
bootunit = (sswitch>>7) & 3;
|
||||
rvec[2] = 01000; /* starting address */
|
||||
rvec[3] = rvec[4] = rvec[5] = rvec[6] = 0;
|
||||
@ -2941,15 +2961,17 @@ main (int argc, char **argv) {
|
||||
if ((sswitch & 0x7) == 4) { /* disk boot */
|
||||
bootctrl = bootdiskctrl[(sswitch>>4) & 3];
|
||||
rvec[0] = 0760; /* disk load starts at '760 */
|
||||
rvec[1] = 0760+1040-1; /* read 1 disk block */
|
||||
rvec[1] = rvec[0]+1040-1; /* read 1 disk block */
|
||||
/* setup DMA register '20 (address only) for the next boot record */
|
||||
regs.sym.regdmx[041] = 03000;
|
||||
|
||||
} else if ((sswitch & 0x7) == 5) { /* tape boot */
|
||||
bootctrl = 014;
|
||||
rvec[0] = 0200; /* tape load starts at '200 */
|
||||
rvec[1] = 3072-rvec[0]; /* read in at most 3 pages (6K) */
|
||||
rvec[1] = rvec[0]+2355-1; /* read in at most 3 pages (6K) */
|
||||
bootskip = 4; /* to skip .TAP header */
|
||||
/* setup DMA register '20 (address only) for the next boot record */
|
||||
regs.sym.regdmx[041] = 0200+2355;;
|
||||
|
||||
} else {
|
||||
printf("\
|
||||
@ -2996,7 +3018,7 @@ For disk boots, the last 3 digits can be:\n\
|
||||
/* read memory image from SA to EA inclusive */
|
||||
|
||||
nw = rvec[1]-rvec[0]+1;
|
||||
if ((i=read(bootfd, mem+rvec[0], nw*2)) == -1) {
|
||||
if ((nw2=read(bootfd, mem+rvec[0], nw*2)) == -1) {
|
||||
perror("Error reading memory image");
|
||||
fatal(NULL);
|
||||
}
|
||||
@ -3004,8 +3026,10 @@ For disk boots, the last 3 digits can be:\n\
|
||||
/* check we got it all, except for tape boots; the boot program size
|
||||
is unpredictable on tape */
|
||||
|
||||
if (i != nw*2 && (sswitch & 0x7) != 5)
|
||||
if (nw2 != nw*2 && ((sswitch & 0x7) == 4 || bootarg)) {
|
||||
printf("rvec[0]=%d, rvec[1]=%d, nw2=%d, nw=%d, nw*2=%d\n", rvec[0], rvec[1], nw2, nw, nw*2);
|
||||
fatal("Didn't read entire boot program");
|
||||
}
|
||||
|
||||
/* setup execution (registers, keys, address mask, etc.) from rvec */
|
||||
|
||||
@ -3056,7 +3080,7 @@ For disk boots, the last 3 digits can be:\n\
|
||||
savetraceflags = traceflags;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
if (traceflags != 0)
|
||||
savetraceflags = traceflags;
|
||||
if (crs[OWNERL] == 0100200 && savetraceflags)
|
||||
@ -4027,7 +4051,7 @@ irtn:
|
||||
|
||||
case 000003:
|
||||
TRACE(T_FLOW, " gen 3?\n");
|
||||
printf("#%d: %o/%o: Generic instruction 3?\n", instcount, RPH, RPL);
|
||||
TRACEA("#%d: %o/%o: Generic instruction 3?\n", instcount, RPH, RPL);
|
||||
continue;
|
||||
|
||||
default:
|
||||
@ -5423,13 +5447,13 @@ keys = 14200, modals=100177
|
||||
continue;
|
||||
}
|
||||
|
||||
/* get ix bits and adjust opcode so that PMA manual opcode
|
||||
/* get x bit and adjust opcode so that PMA manual opcode
|
||||
references can be used directly, ie, if the PMA manual says the
|
||||
opcode is '15 02, then 01502 can be used here. If the PMA
|
||||
manual says the opcode is '11, then use 01100 (the XX extended
|
||||
opcode bits are zero) */
|
||||
|
||||
i = inst & 0100000; /* indirect is bit 1 (left/MS bit) */
|
||||
i = inst & 0100000; /* (for trace) indirect is bit 1 */
|
||||
x = inst & 040000; /* indexed is bit 2 */
|
||||
opcode = (inst & 036000) >> 4; /* isolate opcode bits */
|
||||
|
||||
@ -5461,24 +5485,24 @@ keys = 14200, modals=100177
|
||||
|
||||
TRACE(T_INST, " opcode=%5#0o, i=%o, x=%o\n", opcode, i != 0, x != 0);
|
||||
|
||||
switch ((crs[KEYS] & 016000) >> 10) {
|
||||
switch (crs[KEYS] & 016000) {
|
||||
case 0: /* 16S */
|
||||
ea = ea16s(inst, i, x);
|
||||
ea = ea16s(inst, x);
|
||||
break;
|
||||
case 1: /* 32S */
|
||||
ea = ea32s(inst, i, x);
|
||||
case 1<<10: /* 32S */
|
||||
ea = ea32s(inst, x);
|
||||
break;
|
||||
case 2: /* 64R */
|
||||
case 3: /* 32R */
|
||||
ea = ea32r64r(earp, inst, i, x, &opcode);
|
||||
case 2<<10: /* 64R */
|
||||
case 3<<10: /* 32R */
|
||||
ea = ea32r64r(earp, inst, x, &opcode);
|
||||
break;
|
||||
case 4: /* 32I */
|
||||
ea = ea32i(earp, inst, i, x);
|
||||
case 4<<10: /* 32I */
|
||||
ea = ea32i(earp, inst, x);
|
||||
warn("32I mode not supported");
|
||||
fault(RESTRICTFAULT, 0, 0);
|
||||
break;
|
||||
case 6: /* 64V */
|
||||
ea = ea64v(earp, inst, i, x, &opcode, &eabit);
|
||||
case 6<<10: /* 64V */
|
||||
ea = ea64v(earp, inst, x, &opcode, &eabit);
|
||||
break;
|
||||
default:
|
||||
printf("Bad CPU mode in EA calculation, keys = %o\n", crs[KEYS]);
|
||||
@ -5716,6 +5740,9 @@ keys = 14200, modals=100177
|
||||
put16(crs[X],ea);
|
||||
continue;
|
||||
|
||||
/* MPY can't overflow in V-mode, but in R-mode (31 bits),
|
||||
-32768*-32768 can overflow and yields 0x8000/0x0000 */
|
||||
|
||||
case 01600:
|
||||
m = get16(ea);
|
||||
TRACE(T_FLOW, " MPY ='%o/%d\n", m, *(short *)&m);
|
||||
@ -5724,12 +5751,11 @@ keys = 14200, modals=100177
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
*(int *)(crs+L) = templ;
|
||||
} else { /* R/S mode */
|
||||
if (crs[A] == 0x8000 && m == 0x8000)
|
||||
utempa = crs[A];
|
||||
crs[A] = (templ >> 15);
|
||||
crs[B] = templ & 077777;
|
||||
if (utempa == 0x8000 && m == 0x8000)
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
else {
|
||||
crs[A] = (templ >> 15);
|
||||
crs[B] = templ & 077777;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
@ -5743,6 +5769,7 @@ keys = 14200, modals=100177
|
||||
|
||||
case 01700:
|
||||
m = get16(ea);
|
||||
//printf("L='%o/%d, DIV ='%o/%d\n", *(unsigned int *)(crs+L), *(int *)(crs+L), m, *(short *)&m);
|
||||
TRACE(T_FLOW, " DIV ='%o/%d\n", m, *(short *)&m);
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
templ = *(int *)(crs+A);
|
||||
@ -5751,17 +5778,26 @@ keys = 14200, modals=100177
|
||||
templ = (templ<<15) | (crs[B] & 0x7FFF);
|
||||
//printf("\nR-mode DIV: A='%o/%d, B='%o/%d, templ='%o/%d\n", crs[A], *(short *)(crs+A), crs[B], *(short *)(crs+B), templ, templ);
|
||||
}
|
||||
if (m != 0 && abs(*(short *)(crs+A)) < abs(*(short *)&m)) {
|
||||
crs[A] = templ / *(short *)&m;
|
||||
if (m == 0)
|
||||
mathexception('i', FC_INT_ZDIV, 0);
|
||||
else if (abs(*(short *)(crs+A)) < abs(*(short *)&m)) {
|
||||
templ2 = templ / *(short *)&m;
|
||||
crs[A] = templ2;
|
||||
crs[B] = templ % *(short *)&m;
|
||||
CLEARC;
|
||||
//printf("DIV results: m='%o/%d, A='%o/%d, B='%o/%d\n", m, *(short *)&m, crs[A], *(short *)(crs+A), crs[B], *(short *)(crs+B));
|
||||
if ((crs[A] & 0x8000) ^ (templ2 & 0x80000000)>>16)
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
else
|
||||
CLEARC;
|
||||
} else {
|
||||
SETC;
|
||||
mathexception('i', FC_INT_OFLOW, 0);
|
||||
//printf("DIV overflow\n");
|
||||
}
|
||||
continue;
|
||||
|
||||
/* NOTE: RESET QVFY, DVL runs okay with cpuid=5 (P750), but
|
||||
fails with default cpuid (P4450) */
|
||||
|
||||
case 01703:
|
||||
templ = get32(ea);
|
||||
TRACE(T_FLOW, " DVL ='%o/%d\n", templ, *(int *)&templ);
|
||||
@ -5771,7 +5807,7 @@ keys = 14200, modals=100177
|
||||
*(int *)(crs+E) = templl % templ;
|
||||
CLEARC;
|
||||
} else
|
||||
SETC;
|
||||
mathexception('i', FC_INT_ZDIV, 0);
|
||||
continue;
|
||||
|
||||
case 03500:
|
||||
@ -5791,8 +5827,8 @@ keys = 14200, modals=100177
|
||||
|
||||
case 00203:
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
TRACE(T_FLOW, " LDL\n");
|
||||
*(unsigned int *)(crs+L) = get32(ea);
|
||||
TRACE(T_FLOW, " LDL ='%o/%d\n", *(unsigned int *)(crs+A), *(int *)(crs+A));
|
||||
} else {
|
||||
TRACE(T_FLOW, " JEQ\n");
|
||||
if (*(short *)(crs+A) == 0)
|
||||
@ -5843,7 +5879,7 @@ keys = 14200, modals=100177
|
||||
case 00503:
|
||||
if (crs[KEYS] & 010000) { /* V/I mode */
|
||||
utempl = get32(ea);
|
||||
TRACE(T_FLOW, " ERL ='%o\n", utempl);
|
||||
TRACE(T_FLOW, " ERL ='%o/%d '%o/'%o %d/%d\n", utempl, *(int *)&utempl, utempl>>16, utempl&0xFFFF, utempl>>16, utempl&0xFFFF);
|
||||
*(unsigned int *)(crs+L) ^= utempl;
|
||||
} else {
|
||||
TRACE(T_FLOW, " JGT\n");
|
||||
@ -6922,9 +6958,9 @@ badsvc:
|
||||
*/
|
||||
|
||||
pio(unsigned int inst) {
|
||||
short class;
|
||||
short func;
|
||||
short device;
|
||||
int class;
|
||||
int func;
|
||||
int device;
|
||||
|
||||
RESTRICT();
|
||||
class = inst >> 14;
|
||||
|
||||
58
emdev.h
58
emdev.h
@ -103,7 +103,7 @@
|
||||
|
||||
/* this is a template for new device handlers */
|
||||
|
||||
int devnew (short class, short func, short device) {
|
||||
int devnew (int class, int func, int device) {
|
||||
|
||||
switch (class) {
|
||||
|
||||
@ -155,9 +155,9 @@ int devnew (short class, short func, short device) {
|
||||
|
||||
/* this is a template for null (not present) devices */
|
||||
|
||||
int devnone (short class, short func, short device) {
|
||||
int devnone (int class, int func, int device) {
|
||||
|
||||
static short lastdev=-1;
|
||||
static int seen[64] = {64*0};
|
||||
|
||||
switch (class) {
|
||||
|
||||
@ -180,9 +180,9 @@ int devnone (short class, short func, short device) {
|
||||
TRACE(T_INST, " OTA '%02o%02o\n", func, device);
|
||||
break;
|
||||
}
|
||||
if (device != lastdev)
|
||||
if (!seen[device])
|
||||
fprintf(stderr, " unimplemented device '%o\n", device);
|
||||
lastdev = device;
|
||||
seen[device] = 1;
|
||||
}
|
||||
|
||||
|
||||
@ -249,7 +249,7 @@ int devnone (short class, short func, short device) {
|
||||
*/
|
||||
|
||||
|
||||
int devasr (short class, short func, short device) {
|
||||
int devasr (int class, int func, int device) {
|
||||
|
||||
static FILE *conslog;
|
||||
static int ttydev;
|
||||
@ -283,8 +283,16 @@ int devasr (short class, short func, short device) {
|
||||
perror(" unable to get tty attributes");
|
||||
fatal(NULL);
|
||||
}
|
||||
|
||||
/* NOTE: some of these are not restored after the emulator
|
||||
is suspended (VSUSP) then restarted, eg, the VSUSP and
|
||||
VINTR characters */
|
||||
|
||||
terminfo.c_iflag &= ~(INLCR | ICRNL);
|
||||
terminfo.c_lflag &= ~(ECHOCTL | ICANON);
|
||||
terminfo.c_oflag &= ~(TOSTOP);
|
||||
terminfo.c_cc[VINTR] = _POSIX_VDISABLE; /* use ^\ instead */
|
||||
terminfo.c_cc[VSUSP] = '';
|
||||
terminfo.c_cc[VMIN] = 0;
|
||||
terminfo.c_cc[VTIME] = 0;
|
||||
if (tcsetattr(ttydev, TCSANOW, &terminfo) == -1) {
|
||||
@ -292,6 +300,10 @@ int devasr (short class, short func, short device) {
|
||||
fatal(NULL);
|
||||
}
|
||||
|
||||
/* ignore SIGTTIN in case the emulator is put in the background */
|
||||
|
||||
signal(SIGTTIN, SIG_IGN);
|
||||
|
||||
/* open console log file and set to line buffering */
|
||||
|
||||
if ((conslog = fopen("console.log", "w")) == NULL) {
|
||||
@ -341,6 +353,9 @@ int devasr (short class, short func, short device) {
|
||||
IOSKIP; /* assume it's always ready */
|
||||
break;
|
||||
|
||||
/* signal SIGTTIN is ignore during initialization, so if the
|
||||
emulator is put in the background, read() will return EIO */
|
||||
|
||||
case 2:
|
||||
TRACE(T_INST, " INA '%02o%02o\n", func, device);
|
||||
if (func == 0 || func == 010) {
|
||||
@ -363,7 +378,7 @@ int devasr (short class, short func, short device) {
|
||||
readasr:
|
||||
n = read(ttydev, &ch, 1);
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
if (errno != EAGAIN && errno != EIO) {
|
||||
perror(" error reading from tty");
|
||||
fatal(NULL);
|
||||
}
|
||||
@ -375,6 +390,7 @@ readasr:
|
||||
TRACEA("\nTRACE DISABLED:\n\n");
|
||||
else
|
||||
TRACEA("\nTRACE ENABLED:\n\n");
|
||||
fflush(tracefile);
|
||||
//memdump(0, 0xFFFF);
|
||||
goto readasr;
|
||||
}
|
||||
@ -419,6 +435,13 @@ readasr:
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
/* could do this here too, but Primos does it with SKS before
|
||||
doing the OTA for the console, so it isn't really necessary.
|
||||
Also, if done here, it might confused a program if SKS said
|
||||
the character could be output, then OTA said it couldn't.
|
||||
The program might stay in a tight OTA loop and hang the
|
||||
machine until sys console output clears */
|
||||
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
FD_SET(2, &fds);
|
||||
@ -705,7 +728,7 @@ int mtwrite (int fd, unsigned short *iobuf, int nw, int *mtstat) {
|
||||
*mtstat &= ~8; /* not at BOT now */
|
||||
}
|
||||
|
||||
int devmt (short class, short func, short device) {
|
||||
int devmt (int class, int func, int device) {
|
||||
|
||||
static unsigned short mtvec = 0114; /* interrupt vector */
|
||||
static unsigned short dmxchan = 0; /* dmx channel number */
|
||||
@ -1159,7 +1182,7 @@ initclock(datnowea) {
|
||||
}
|
||||
|
||||
|
||||
int devcp (short class, short func, short device) {
|
||||
int devcp (int class, int func, int device) {
|
||||
static short enabled = 0;
|
||||
static unsigned short clkvec;
|
||||
static short clkpic = 0;
|
||||
@ -1290,11 +1313,10 @@ int devcp (short class, short func, short device) {
|
||||
previnstcount = instcount;
|
||||
if (datnowea != 0)
|
||||
initclock(datnowea);
|
||||
printf("em: resetting real time clock\n");
|
||||
}
|
||||
elapsedms = (tv.tv_sec-start_tv.tv_sec-1)*1000 + (tv.tv_usec+1000000-start_tv.tv_usec)/1000;
|
||||
targetticks = elapsedms/(-clkpic*3.2/1000);
|
||||
#if 1
|
||||
#if 0
|
||||
absticks++;
|
||||
if (absticks%1000 == 0)
|
||||
printf("Clock check: target=%d, ticks=%d\n", targetticks, ticks);
|
||||
@ -1306,7 +1328,7 @@ int devcp (short class, short func, short device) {
|
||||
If datnowea is not available (no Primos maps), then we have
|
||||
to tick our way to the correct time */
|
||||
|
||||
if (abs(ticks-targetticks) > 1000 && datnowea != 0)
|
||||
if (abs(ticks-targetticks) > 5000 && datnowea != 0)
|
||||
ticks = -1;
|
||||
else if (ticks < targetticks)
|
||||
devpoll[device] = 100; /* behind, so catch-up */
|
||||
@ -1327,7 +1349,7 @@ int devcp (short class, short func, short device) {
|
||||
instpermsec = (instcount-previnstcount) /
|
||||
((tv.tv_sec-prev_tv.tv_sec-1)*1000 + (tv.tv_usec+1000000-prev_tv.tv_usec)/1000);
|
||||
//printf("instcount = %d, previnstcount = %d, diff=%d, instpermsec=%d\n", instcount, previnstcount, instcount-previnstcount, instpermsec);
|
||||
printf("instpermsec=%d\n", instpermsec);
|
||||
//printf("instpermsec=%d\n", instpermsec);
|
||||
previnstcount = instcount;
|
||||
prev_tv = tv;
|
||||
}
|
||||
@ -1371,7 +1393,7 @@ int devcp (short class, short func, short device) {
|
||||
|
||||
*/
|
||||
|
||||
int devdisk (short class, short func, short device) {
|
||||
int devdisk (int class, int func, int device) {
|
||||
|
||||
#define S_HALT 0
|
||||
#define S_RUN 1
|
||||
@ -1880,7 +1902,7 @@ int devdisk (short class, short func, short device) {
|
||||
- emulator stores in a structure
|
||||
*/
|
||||
|
||||
int devamlc (short class, short func, short device) {
|
||||
int devamlc (int class, int func, int device) {
|
||||
|
||||
#define MAXLINES 128
|
||||
#define MAXFD MAXLINES+20
|
||||
@ -2194,7 +2216,7 @@ conloop:
|
||||
while (n < sizeof(buf) && rtq(qcbea, &utempa, 0)) {
|
||||
if (utempa & 0x8000) { /* valid character */
|
||||
//printf("Device %o, line %d, entry=%o (%c)\n", device, lx, utempa, utempa & 0x7f);
|
||||
buf[n++] = utempa ^ 0x80;
|
||||
buf[n++] = utempa & 0x7F;
|
||||
}
|
||||
}
|
||||
} else { /* no line connected, just drain queue */
|
||||
@ -2206,7 +2228,7 @@ conloop:
|
||||
if (utempa != 0) {
|
||||
if ((utempa & 0x8000) && (dc[device].dss & bitmask16[lx+1])) {
|
||||
//printf("Device %o, line %d, entry=%o (%c)\n", device, lx, utempa, utempa & 0x7f);
|
||||
buf[n++] = utempa ^ 0x80;
|
||||
buf[n++] = utempa & 0x7F;
|
||||
}
|
||||
put16r(0, dc[device].baseaddr + lx, 0);
|
||||
}
|
||||
@ -2416,7 +2438,7 @@ conloop:
|
||||
|
||||
*/
|
||||
|
||||
int devpnc (short class, short func, short device) {
|
||||
int devpnc (int class, int func, int device) {
|
||||
|
||||
/* PNC controller status bits */
|
||||
#define PNCRCVINT 0x8000 /* bit 1 rcv interrupt (rcv complete) */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user