1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 11:46:37 +00:00

Notes For V3.7-0

1. New Features

1.1 3.7-0

1.1.1 SCP

- Added SET THROTTLE and SET NOTHROTTLE commands to regulate simulator
  execution rate and host resource utilization.
- Added idle support (based on work by Mark Pizzolato).
- Added -e to control error processing in nested DO commands (from
  Dave Bryan).

1.1.2 HP2100

- Added Double Integer instructions, 1000-F CPU, and Floating Point
  Processor (from Dave Bryan).
- Added 2114 and 2115 CPUs, 12607B and 12578A DMA controllers, and
  21xx binary loader protection (from Dave Bryan).

1.1.3 Interdata

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state.

1.1.4 PDP-11

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (WAIT instruction executed).
- Added TA11/TU60 cassette support.

1.1.5 PDP-8

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (keyboard poll loop or jump-to-self).
- Added TA8E/TU60 cassette support.

1.1.6 PDP-1

- Added support for 16-channel sequence break system.
- Added support for PDP-1D extended features and timesharing clock.
- Added support for Type 630 data communications subsystem.

1.1.6 PDP-4/7/9/15

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (keyboard poll loop or jump-to-self).

1.1.7 VAX, VAX780

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (more than 200 cycles at IPL's 0, 1, or 3 in kernel mode).

1.1.8 PDP-10

- Added SET IDLE and SET NOIDLE commands to idle the simulator in wait
  state (operating system dependent).
- Added CD20 (CD11) support.

2. Bugs Fixed

Please see the revision history on http://simh.trailing-edge.com or
in the source module sim_rev.h.
This commit is contained in:
Bob Supnik
2007-02-03 14:59:00 -08:00
committed by Mark Pizzolato
parent 15919a2dd7
commit 53d02f7fa7
161 changed files with 18604 additions and 6903 deletions

View File

@@ -136,8 +136,6 @@
#define PCQ_SIZE 64 /* must be 2**n */
#define PCQ_MASK (PCQ_SIZE - 1)
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = PC
#define UNIT_V_MSIZE (UNIT_V_T20V41 + 1) /* dummy mask */
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
#define HIST_PC 0x40000000
#define HIST_MIN 64
@@ -188,6 +186,7 @@ int32 stop_op0 = 0; /* stop on 0 */
int32 rlog = 0; /* extend fixup log */
int32 ind_max = 32; /* nested ind limit */
int32 xct_max = 32; /* nested XCT limit */
int32 t20_idlelock = 0; /* TOPS-20 idle lock */
a10 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
int32 pcq_p = 0; /* PC queue ptr */
REG *pcq_r = NULL; /* PC queue reg ptr */
@@ -321,6 +320,7 @@ extern t_bool wrpcst (a10 ea, int32 prv);
extern t_bool spm (a10 ea, int32 prv);
extern t_bool lpmr (a10 ea, int32 prv);
extern int32 pi_ub_vec (int32 lvl, int32 *uba);
extern t_stat tim_set_mod (UNIT *uptr, int32 val, char *cptr, void *desc);
/* CPU data structures
@@ -390,9 +390,14 @@ REG cpu_reg[] = {
};
MTAB cpu_mod[] = {
{ UNIT_ITS+UNIT_T20V41, 0, "Standard microcode", "STANDARD", NULL },
{ UNIT_ITS+UNIT_T20V41, UNIT_T20V41, "TOPS-20 V4.1", "TOPS20V41", NULL },
{ UNIT_ITS+UNIT_T20V41, UNIT_ITS, "ITS microcode", "ITS", NULL },
{ UNIT_KLAD+UNIT_ITS+UNIT_T20, 0, "TOPS-10", "TOPS-10", &tim_set_mod },
{ UNIT_KLAD+UNIT_ITS+UNIT_T20, 0, NULL , "TOPS10", &tim_set_mod },
{ UNIT_KLAD+UNIT_ITS+UNIT_T20, UNIT_T20, "TOPS-20", "TOPS-20", &tim_set_mod },
{ UNIT_KLAD+UNIT_ITS+UNIT_T20, UNIT_T20, NULL, "TOPS20", &tim_set_mod },
{ UNIT_KLAD+UNIT_ITS+UNIT_T20, UNIT_ITS, "ITS", "ITS", &tim_set_mod },
{ UNIT_KLAD+UNIT_ITS+UNIT_T20, UNIT_KLAD, "diagnostic mode", "KLAD", &tim_set_mod },
{ MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
NULL, &show_iospace },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
@@ -593,11 +598,11 @@ static t_stat jrst_tab[16] = {
#define T__N if ((AC(ac) & mb) != 0) INCPC
#define T__A INCPC
#define IOC if (TSTF (F_USR) && !TSTF (F_UIO)) goto MUUO;
#define IO7(x,y) IOC; fptr = ((ITS)? x[ac]: y[ac]); \
#define IO7(x,y) IOC; fptr = ((Q_ITS)? x[ac]: y[ac]); \
if (fptr == NULL) goto MUUO; \
if (fptr (ea, MM_OPND)) INCPC; break;
#define IOA IOC; if (!ITS) ea = calc_ioea (inst, pflgs)
#define IOAM IOC; ea = ((ITS)? ((a10) Read (ea, MM_OPND)): \
#define IOA IOC; if (!Q_ITS) ea = calc_ioea (inst, pflgs)
#define IOAM IOC; ea = ((Q_ITS)? ((a10) Read (ea, MM_OPND)): \
calc_ioea (inst, pflgs))
/* Flag tests */
@@ -629,7 +634,8 @@ pager_pi = FALSE; /* not in pi sequence */
rlog = 0; /* not in extend */
pi_eval (); /* eval pi system */
sim_rtc_init (tim_unit.wait); /* init calibration */
if (!ITS) its_1pr = 0; /* ~ITS, clr 1-proc */
if (!Q_ITS) its_1pr = 0; /* ~ITS, clr 1-proc */
t20_idlelock = 0; /* clr T20 idle lock */
/* Abort handling
@@ -656,7 +662,7 @@ else if (abortval == PAGE_FAIL) { /* page fail */
if (rlog) xtcln (rlog); /* clean up extend */
rlog = 0; /* clear log */
if (pager_tc) flags = pager_flags; /* trap? get flags */
if (T20) { /* TOPS-20 */
if (T20PAG) { /* TOPS-20 paging? */
WriteP (upta + UPT_T20_PFL, pager_word); /* write page fail wd */
WriteP (upta + UPT_T20_OFL, XWD (flags, 0));
WriteP (upta + UPT_T20_OPC, pager_PC);
@@ -664,7 +670,7 @@ else if (abortval == PAGE_FAIL) { /* page fail */
}
else {
a10 ea; /* TOPS-10 or ITS */
if (ITS) { /* ITS? */
if (Q_ITS) { /* ITS? */
ea = epta + EPT_ITS_PAG + (pi_m2lvl[pi_act] * 3);
if (its_1pr) flags = flags | F_1PR; /* store 1-proc */
its_1pr = 0; /* clear 1-proc */
@@ -715,7 +721,7 @@ if (qintr) {
else inst = ReadP (epta + EPT_PIIT + (2 * qintr));
op = GET_OP (inst); /* get opcode */
ac = GET_AC (inst); /* get ac */
if (its_1pr && ITS) { /* 1-proc set? */
if (its_1pr && Q_ITS) { /* 1-proc set? */
flags = flags | F_1PR; /* store 1-proc */
its_1pr = 0; /* clear 1-proc */
}
@@ -846,12 +852,12 @@ case 0037: Write (040, UUOWORD, MM_CUR); /* store op, ac, ea */
/* case 0100: MUUO /* UJEN */
/* case 0101: MUUO /* unassigned */
case 0102: if (ITS && !TSTF (F_USR)) { /* GFAD (KL), XCTRI (ITS) */
case 0102: if (Q_ITS && !TSTF (F_USR)) { /* GFAD (KL), XCTRI (ITS) */
inst = Read (ea, MM_OPND);
pflgs = pflgs | ac; goto XCT;
}
goto MUUO;
case 0103: if (ITS && !TSTF (F_USR)) { /* GFSB (KL), XCTR (ITS) */
case 0103: if (Q_ITS && !TSTF (F_USR)) { /* GFSB (KL), XCTR (ITS) */
inst = Read (ea, MM_OPND);
pflgs = pflgs | ac; goto XCT;
}
@@ -977,7 +983,7 @@ case 0243: AC(P1) = jffo (AC(ac)); /* JFFO */
case 0244: ashc (ac, ea); break; /* ASHC */
case 0245: rotc (ac, ea); break; /* ROTC */
case 0246: lshc (ac, ea); break; /* LSHC */
case 0247: if (ITS) circ (ac, ea); break; /* (ITS) CIRC */
case 0247: if (Q_ITS) circ (ac, ea); break; /* (ITS) CIRC */
case 0250: RM; WRAC; AC(ac) = mb; break; /* EXCH */
case 0251: blt (ac, ea, pflgs); break; /* BLT */
case 0252: AOBAC; if (TGE (AC(ac))) JUMP (ea); break; /* AOBJP */
@@ -991,9 +997,10 @@ case 0255: if (flags & (ac << 14)) { /* JFCL */
case 0256: if (xct_cnt++ >= xct_max) /* XCT */
ABORT (STOP_XCT);
inst = Read (ea, MM_OPND);
if (ac && !TSTF (F_USR) && !ITS) pflgs = pflgs | ac;
if (ac && !TSTF (F_USR) && !Q_ITS)
pflgs = pflgs | ac;
goto XCT;
case 0257: if (ITS) goto MUUO; /* MAP */
case 0257: if (Q_ITS) goto MUUO; /* MAP */
AC(ac) = map (ea, MM_OPND); break;
case 0260: WRP (FLPC); AOBAC; /* PUSHJ */
SUBJ (ea); PUSHF; break;
@@ -1054,7 +1061,12 @@ case 0340: AOJ; break; /* AOJ */
case 0341: AOJ; if (TL (AC(ac))) JUMP (ea); break; /* AOJL */
case 0342: AOJ; if (TE (AC(ac))) JUMP (ea); break; /* AOJE */
case 0343: AOJ; if (TLE (AC(ac))) JUMP (ea); break; /* AOJLE */
case 0344: AOJ; JUMP(ea); break; /* AOJA */
case 0344: AOJ; JUMP(ea); /* AOJA */
if (Q_ITS && Q_IDLE && /* ITS idle? */
TSTF (F_USR) && (pager_PC == 017) && /* user mode, loc 17? */
(ac == 0) && (ea == 017)) /* AOJA 0,17? */
sim_idle (0, FALSE);
break;
case 0345: AOJ; if (TGE (AC(ac))) JUMP (ea); break; /* AOJGE */
case 0346: AOJ; if (TN (AC(ac))) JUMP (ea); break; /* AOJN */
case 0347: AOJ; if (TG (AC(ac))) JUMP (ea); break; /* AOJG */
@@ -1073,7 +1085,22 @@ case 0363: SOJ; if (TLE (AC(ac))) JUMP (ea); break; /* SOJLE */
case 0364: SOJ; JUMP(ea); break; /* SOJA */
case 0365: SOJ; if (TGE (AC(ac))) JUMP (ea); break; /* SOJGE */
case 0366: SOJ; if (TN (AC(ac))) JUMP (ea); break; /* SOJN */
case 0367: SOJ; if (TG (AC(ac))) JUMP (ea); break; /* SOJG */
case 0367: SOJ; if (TG (AC(ac))) JUMP (ea); /* SOJG */
if ((ea == pager_PC) && Q_IDLE) { /* to self, idle enab? */
extern int32 tmr_poll;
if ((ac == 6) && (ea == 1) && /* SOJG 6,1? */
TSTF (F_USR) && Q_T10) /* T10, user mode? */
sim_idle (0, FALSE);
else if (!t20_idlelock && /* interlock off? */
(ac == 2) && (ea == 3) && /* SOJG 2,3? */
!TSTF (F_USR) && Q_T20 && /* T20, mon mode? */
(sim_interval > (tmr_poll >> 1))) { /* >= half clock? */
t20_idlelock = 1; /* set interlock */
if (sim_os_ms_sleep (1)) /* sleep 1ms */
sim_interval = 0; /* if ok, sched event */
}
}
break;
case 0370: SOS; break; /* SOS */
case 0371: SOS; if (TL (mb)) INCPC; break; /* SOSL */
case 0372: SOS; if (TE (mb)) INCPC; break; /* SOSE */
@@ -1331,7 +1358,7 @@ case 0725: IOA; io725 (AC(ac), ea); break; /* BCIOB, IOWRBQ */
default:
MUUO:
its_2pr = 0; /* clear trap */
if (T20) { /* TOPS20? */
if (T20PAG) { /* TOPS20 paging? */
int32 tf = (op << (INST_V_OP - 18)) | (ac << (INST_V_AC - 18));
WriteP (upta + UPT_MUUO, XWD ( /* store flags,,op+ac */
flags & ~(F_T2 | F_T1), tf)); /* traps clear */
@@ -1425,7 +1452,7 @@ case 0254: /* JRST */
break;
case 015: /* JRST 15 = XJRST */
if (!T20) goto MUUO; /* only in TOPS20 */
if (!T20PAG) goto MUUO; /* only in TOPS20 paging */
JUMP (Read (ea, MM_OPND)); /* jump to M[ea] */
break;
} /* end case subop */
@@ -1434,14 +1461,14 @@ case 0254: /* JRST */
if (its_2pr) { /* 1-proc trap? */
its_1pr = its_2pr = 0; /* clear trap */
if (ITS) { /* better be ITS */
if (Q_ITS) { /* better be ITS */
WriteP (upta + UPT_1PO, FLPC); /* wr old flgs, PC */
mb = ReadP (upta + UPT_1PN); /* rd new flgs, PC */
JUMP (mb); /* set PC */
set_newflags (mb, TRUE); /* set new flags */
}
} /* end if 2-proc */
} /* end for */
} /* end for */
/* Should never get here */
@@ -2017,7 +2044,7 @@ return;
t_bool aprid (a10 ea, int32 prv)
{
Write (ea, (ITS)? UC_AIDITS: UC_AIDDEC, prv);
Write (ea, (Q_ITS)? UC_AIDITS: UC_AIDDEC, prv);
return FALSE;
}
@@ -2069,7 +2096,7 @@ if (jrst && TSTF (F_USR)) { /* if in user now */
fl = fl | F_USR; /* can't clear user */
if (!TSTF (F_UIO)) fl = fl & ~F_UIO; /* if !UIO, can't set */
}
if (ITS && (fl & F_1PR)) { /* ITS 1-proceed? */
if (Q_ITS && (fl & F_1PR)) { /* ITS 1-proceed? */
its_1pr = 1; /* set flag */
fl = fl & ~F_1PR; /* vanish bit */
}
@@ -2177,7 +2204,7 @@ pi_enb = pi_act = pi_prq = 0; /* clear PI */
apr_enb = apr_flg = apr_lvl = 0; /* clear APR */
pcst = 0; /* clear PC samp */
rlog = 0; /* clear reg log */
hsb = (ITS)? UC_HSBITS: UC_HSBDEC; /* set HSB */
hsb = (Q_ITS)? UC_HSBITS: UC_HSBDEC; /* set HSB */
set_dyn_ptrs ();
set_ac_display (ac_cur);
pi_eval ();

View File

@@ -1,6 +1,6 @@
/* pdp10_defs.h: PDP-10 simulator definitions
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,8 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
01-Feb-07 RMS Added CD support
29-Oct-06 RMS Added clock coscheduling function
29-Dec-03 RMS Added Q18 definition for PDP11 compatibility
19-May-03 RMS Revised for new conditional compilation scheme
09-Jan-03 RMS Added DEUNA/DELUA support
@@ -122,10 +124,16 @@ typedef t_int64 d10; /* PDP-10 data (36b) */
/* Operating system flags, kept in cpu_unit.flags */
#define UNIT_V_ITS (UNIT_V_UF) /* ITS */
#define UNIT_V_T20 (UNIT_V_UF + 1) /* TOPS-20 */
#define UNIT_V_KLAD (UNIT_V_UF + 2) /* diagnostics */
#define UNIT_ITS (1 << UNIT_V_ITS)
#define UNIT_V_T20V41 (UNIT_V_UF + 1) /* TOPS-20 V4.1 */
#define UNIT_T20V41 (1 << UNIT_V_T20V41)
#define ITS (cpu_unit.flags & UNIT_ITS)
#define UNIT_T20 (1 << UNIT_V_T20)
#define UNIT_KLAD (1 << UNIT_V_KLAD)
#define Q_T10 ((cpu_unit.flags & (UNIT_ITS|UNIT_T20|UNIT_KLAD)) == 0)
#define Q_ITS (cpu_unit.flags & UNIT_ITS)
#define Q_T20 (cpu_unit.flags & UNIT_T20)
#define Q_KLAD (cpu_unit.flags & UNIT_KLAD)
#define Q_IDLE (sim_idle_enab)
/* Architectural constants */
@@ -384,7 +392,7 @@ typedef t_int64 d10; /* PDP-10 data (36b) */
#define EBR_MASK (EBR_T20P | EBR_PGON | (EBR_M_EBR << EBR_V_EBR))
#define EBR_GETEBR(x) ((int32) (((x) >> EBR_V_EBR) & PAG_M_PPN))
#define PAGING (ebr & EBR_PGON)
#define T20 (ebr & EBR_T20P)
#define T20PAG (ebr & EBR_T20P)
/* AC and mapping contexts
@@ -647,6 +655,8 @@ typedef struct pdp_dib DIB;
#define IOLN_UBMNT3 001
#define IOBA_XU (IO_UBA3 + 0774510) /* DEUNA/DELUA */
#define IOLN_XU 010
#define IOBA_CR (IO_UBA3 + 0777160) /* CD/CR/CM */
#define IOLN_CR 010
#define IOBA_RY (IO_UBA3 + 0777170) /* RX211 */
#define IOLN_RY 004
#define IOBA_TU (IO_UBA3 + 0772440) /* RH11/tape */
@@ -689,6 +699,7 @@ typedef struct pdp_dib DIB;
#define INT_V_PTR 24 /* PC11 */
#define INT_V_PTP 25
#define INT_V_LP20 26 /* LPT20 */
#define INT_V_CR 27 /* CD20 (CD11) */
#define INT_RP (1u << INT_V_RP)
#define INT_TU (1u << INT_V_TU)
@@ -699,6 +710,7 @@ typedef struct pdp_dib DIB;
#define INT_PTR (1u << INT_V_PTR)
#define INT_PTP (1u << INT_V_PTP)
#define INT_LP20 (1u << INT_V_LP20)
#define INT_CR (1u << INT_V_CR)
#define IPL_RP 6 /* int levels */
#define IPL_TU 6
@@ -709,6 +721,7 @@ typedef struct pdp_dib DIB;
#define IPL_PTR 4
#define IPL_PTP 4
#define IPL_LP20 4
#define IPL_CR 4
#define INT_UB1 INT_RP /* on Unibus 1 */
#define INT_UB3 (0xFFFFFFFFu & ~INT_UB1) /* on Unibus 3 */
@@ -723,6 +736,7 @@ typedef struct pdp_dib DIB;
#define VEC_PTP 0074
#define VEC_XU 0120
#define VEC_TU 0224
#define VEC_CR 0230
#define VEC_RP 0254
#define VEC_RY 0264
#define VEC_DZRX 0340
@@ -748,4 +762,10 @@ t_stat set_vec (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat show_vec (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat auto_config (char *name, int32 num);
int32 clk_cosched (int32 wait);
/* Global data */
extern t_bool sim_idle_enab;
#endif

View File

@@ -1,6 +1,6 @@
/* pdp10_fe.c: PDP-10 front end (console terminal) simulator
Copyright (c) 1993-2004, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,7 @@
fe KS10 console front end
17-Oct-06 RMS Synced keyboard to clock for idling
28-May-04 RMS Removed SET FE CTRL-C
29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support
@@ -40,6 +41,7 @@
extern d10 *M;
extern int32 apr_flg;
extern int32 tmxr_poll;
t_stat fei_svc (UNIT *uptr);
t_stat feo_svc (UNIT *uptr);
t_stat fe_reset (DEVICE *dptr);
@@ -56,14 +58,14 @@ t_stat fe_stop_os (UNIT *uptr, int32 val, char *cptr, void *desc);
#define feo_unit fe_unit[1]
UNIT fe_unit[] = {
{ UDATA (&fei_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&fei_svc, 0, 0), 0 },
{ UDATA (&feo_svc, 0, 0), SERIAL_OUT_WAIT }
};
REG fe_reg[] = {
{ ORDATA (IBUF, fei_unit.buf, 8) },
{ DRDATA (ICOUNT, fei_unit.pos, T_ADDR_W), REG_RO + PV_LEFT },
{ DRDATA (ITIME, fei_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (ITIME, fei_unit.wait, 24), PV_LEFT },
{ ORDATA (OBUF, feo_unit.buf, 8) },
{ DRDATA (OCOUNT, feo_unit.pos, T_ADDR_W), REG_RO + PV_LEFT },
{ DRDATA (OTIME, feo_unit.wait, 24), REG_NZ + PV_LEFT },
@@ -139,12 +141,12 @@ t_stat fei_svc (UNIT *uptr)
{
int32 temp;
sim_activate (&fei_unit, fei_unit.wait); /* continue poll */
sim_activate (uptr, KBD_WAIT (uptr->wait, tmxr_poll)); /* continue poll */
if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */
if (temp & SCPE_BREAK) return SCPE_OK; /* ignore break */
fei_unit.buf = temp & 0177;
fei_unit.pos = fei_unit.pos + 1;
M[FE_CTYIN] = fei_unit.buf | FE_CVALID; /* put char in mem */
uptr->buf = temp & 0177;
uptr->pos = uptr->pos + 1;
M[FE_CTYIN] = uptr->buf | FE_CVALID; /* put char in mem */
apr_flg = apr_flg | APRF_CON; /* interrupt KS10 */
return SCPE_OK;
}
@@ -156,7 +158,7 @@ t_stat fe_reset (DEVICE *dptr)
fei_unit.buf = feo_unit.buf = 0;
M[FE_CTYIN] = M[FE_CTYOUT] = 0;
apr_flg = apr_flg & ~(APRF_ITC | APRF_CON);
sim_activate (&fei_unit, fei_unit.wait); /* start input poll */
sim_activate_abs (&fei_unit, KBD_WAIT (fei_unit.wait, tmxr_poll));
return SCPE_OK;
}

View File

@@ -188,14 +188,14 @@ DIB *std_dib[] = { /* standard DIBs */
/* IO 710 (DEC) TIOE - test I/O word, skip if zero
(ITS) IORDI - read word from Unibus 3
returns TRUE if skip, FALSE otherwise
returns TRUE if skip, FALSE otherwise
*/
t_bool io710 (int32 ac, a10 ea)
{
d10 val;
if (ITS) AC(ac) = ReadIO (IO_UBA3 | ea); /* IORDI */
if (Q_ITS) AC(ac) = ReadIO (IO_UBA3 | ea); /* IORDI */
else { /* TIOE */
val = ReadIO (ea); /* read word */
if ((AC(ac) & val) == 0) return TRUE;
@@ -205,14 +205,14 @@ return FALSE;
/* IO 711 (DEC) TION - test I/O word, skip if non-zero
(ITS) IORDQ - read word from Unibus 1
returns TRUE if skip, FALSE otherwise
returns TRUE if skip, FALSE otherwise
*/
t_bool io711 (int32 ac, a10 ea)
{
d10 val;
if (ITS) AC(ac) = ReadIO (IO_UBA1 | ea); /* IORDQ */
if (Q_ITS) AC(ac) = ReadIO (IO_UBA1 | ea); /* IORDQ */
else { /* TION */
val = ReadIO (ea); /* read word */
if ((AC(ac) & val) != 0) return TRUE;
@@ -248,7 +248,7 @@ void io714 (d10 val, a10 ea)
d10 temp;
val = val & 0177777;
if (ITS) WriteIO (IO_UBA3 | ea, val, WRITE); /* IOWRI */
if (Q_ITS) WriteIO (IO_UBA3 | ea, val, WRITE); /* IOWRI */
else {
temp = ReadIO (ea); /* BSIO */
temp = temp | val;
@@ -266,7 +266,7 @@ void io715 (d10 val, a10 ea)
d10 temp;
val = val & 0177777;
if (ITS) WriteIO (IO_UBA1 | ea, val, WRITE); /* IOWRQ */
if (Q_ITS) WriteIO (IO_UBA1 | ea, val, WRITE); /* IOWRQ */
else {
temp = ReadIO (ea); /* BCIO */
temp = temp & ~val;
@@ -277,14 +277,14 @@ return;
/* IO 720 (DEC) TIOEB - test I/O byte, skip if zero
(ITS) IORDBI - read byte from Unibus 3
returns TRUE if skip, FALSE otherwise
returns TRUE if skip, FALSE otherwise
*/
t_bool io720 (int32 ac, a10 ea)
{
d10 val;
if (ITS) { /* IORDBI */
if (Q_ITS) { /* IORDBI */
val = ReadIO (IO_UBA3 | eaRB);
AC(ac) = GETBYTE (ea, val);
}
@@ -298,14 +298,14 @@ return FALSE;
/* IO 721 (DEC) TIONB - test I/O word, skip if non-zero
(ITS) IORDBQ - read word from Unibus 1
returns TRUE if skip, FALSE otherwise
returns TRUE if skip, FALSE otherwise
*/
t_bool io721 (int32 ac, a10 ea)
{
d10 val;
if (ITS) { /* IORDBQ */
if (Q_ITS) { /* IORDBQ */
val = ReadIO (IO_UBA1 | eaRB);
AC(ac) = GETBYTE (ea, val);
}
@@ -348,7 +348,7 @@ void io724 (d10 val, a10 ea)
d10 temp;
val = val & 0377;
if (ITS) WriteIO (IO_UBA3 | ea, val, WRITEB); /* IOWRBI */
if (Q_ITS) WriteIO (IO_UBA3 | ea, val, WRITEB); /* IOWRBI */
else {
temp = ReadIO (eaRB); /* BSIOB */
temp = GETBYTE (ea, temp);
@@ -367,7 +367,7 @@ void io725 (d10 val, a10 ea)
d10 temp;
val = val & 0377;
if (ITS) WriteIO (IO_UBA1 | ea, val, WRITEB); /* IOWRBQ */
if (Q_ITS) WriteIO (IO_UBA1 | ea, val, WRITEB); /* IOWRBQ */
else {
temp = ReadIO (eaRB); /* BCIOB */
temp = GETBYTE (ea, temp);

View File

@@ -312,7 +312,7 @@ int32 ptbl_fill (a10 ea, int32 *tbl, int32 mode)
ITS has no MAP instruction, therefore, physical NXM traps are ok.
*/
if (ITS) { /* ITS paging */
if (Q_ITS) { /* ITS paging */
int32 acc, decvpn, pte, vpn, ptead, xpte;
d10 ptewd;
@@ -349,7 +349,7 @@ if (ITS) { /* ITS paging */
user process tables.
*/
else if (!T20) { /* TOPS-10 paging */
else if (!T20PAG) { /* TOPS-10 paging */
int32 pte, vpn, ptead, xpte;
d10 ptewd;
@@ -377,7 +377,7 @@ else if (!T20) { /* TOPS-10 paging */
PAGE_FAIL_TRAP;
} /* end TOPS10 paging */
/* TOPS-20 paging - checked against KS10 ucode.
/* TOPS-20 paging - checked against KS10 microcode
TOPS-20 paging has three phases:
@@ -549,7 +549,7 @@ else {
}
t = EBR_GETEBR (ebr);
epta = t << PAG_V_PN;
if (ITS) upta = (int32) ubr & PAMASK;
if (Q_ITS) upta = (int32) ubr & PAMASK;
else {
t = UBR_GETUBR (ubr);
upta = t << PAG_V_PN;
@@ -601,7 +601,7 @@ t_bool clrpt (a10 ea, int32 prv)
{
int32 vpn = PAG_GETVPN (ea); /* get page num */
if (ITS) { /* ITS? */
if (Q_ITS) { /* ITS? */
uptbl[vpn & ~1] = 0; /* clear double size */
uptbl[vpn | 1] = 0; /* entries in */
eptbl[vpn & ~1] = 0; /* both page tables */
@@ -631,7 +631,7 @@ return FALSE;
t_bool wrubr (a10 ea, int32 prv)
{
d10 val = Read (ea, prv);
d10 ubr_mask = (ITS)? PAMASK: UBR_UBRMASK; /* ITS: ubr is wd addr */
d10 ubr_mask = (Q_ITS)? PAMASK: UBR_UBRMASK; /* ITS: ubr is wd addr */
if (val & UBR_SETACB) ubr = ubr & ~UBR_ACBMASK; /* set AC's? */
else val = val & ~UBR_ACBMASK; /* no, keep old val */
@@ -647,7 +647,7 @@ return FALSE;
t_bool rdubr (a10 ea, int32 prv)
{
ubr = ubr & (UBR_ACBMASK | (ITS? PAMASK: UBR_UBRMASK));
ubr = ubr & (UBR_ACBMASK | (Q_ITS? PAMASK: UBR_UBRMASK));
Write (ea, UBRWORD, prv);
return FALSE;
}
@@ -705,7 +705,7 @@ return FALSE;
t_bool wrcstm (a10 ea, int32 prv)
{
cstm = Read (ea, prv);
if ((cpu_unit.flags & UNIT_T20V41) && (ea == 040127))
if ((cpu_unit.flags & UNIT_T20) && (ea == 040127))
cstm = 0770000000000;
return FALSE;
}

View File

@@ -803,8 +803,8 @@ switch (fnc) { /* case on function */
break;
}
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
(GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
(GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
(GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
(GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
set_rper (ER1_IAE, drv);
break;
}
@@ -827,8 +827,8 @@ switch (fnc) { /* case on function */
rpcs2 = rpcs2 & ~CS2_ERR; /* clear errors */
rpcs1 = rpcs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
(GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
(GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
(GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
(GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
set_rper (ER1_IAE, drv);
break;
}
@@ -909,7 +909,7 @@ switch (uptr->FUNC) { /* case on function */
case FNC_READH: /* read headers */
ba = GET_UAE (rpcs1) | rpba; /* get byte addr */
wc10 = (0200000 - rpwc) >> 1; /* get PDP-10 wc */
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD; /* get disk addr */
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD; /* get disk addr */
if ((da + wc10) > drv_tab[dtype].size) { /* disk overrun? */
set_rper (ER1_AOE, drv);
if (wc10 > (drv_tab[dtype].size - da))
@@ -1256,7 +1256,7 @@ extern a10 saved_PC;
M[FE_UNIT] = unitno & CS2_M_UNIT;
for (i = 0; i < BOOT_LEN; i++)
M[BOOT_START + i] = ITS? boot_rom_its[i]: boot_rom_dec[i];
M[BOOT_START + i] = Q_ITS? boot_rom_its[i]: boot_rom_dec[i];
saved_PC = BOOT_START;
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* pdp10_sys.c: PDP-10 simulator interface
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2007, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -23,6 +23,7 @@
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
01-Feb-07 RMS Added CD support
22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn)
09-Jan-03 RMS Added DEUNA/DELUA support
12-Sep-02 RMS Added RX211 support
@@ -40,11 +41,18 @@
#include "pdp10_defs.h"
#include <ctype.h>
extern DEVICE cpu_dev, pag_dev;
extern DEVICE tim_dev, fe_dev, uba_dev;
extern DEVICE ptr_dev, ptp_dev;
extern DEVICE rp_dev, tu_dev;
extern DEVICE dz_dev, ry_dev;
extern DEVICE cpu_dev;
extern DEVICE pag_dev;
extern DEVICE tim_dev;
extern DEVICE fe_dev;
extern DEVICE uba_dev;
extern DEVICE ptr_dev;
extern DEVICE ptp_dev;
extern DEVICE rp_dev;
extern DEVICE tu_dev;
extern DEVICE dz_dev;
extern DEVICE ry_dev;
extern DEVICE cr_dev;
extern DEVICE lp20_dev;
extern DEVICE xu_dev;
extern UNIT cpu_unit;
@@ -78,6 +86,7 @@ DEVICE *sim_devices[] = {
&ptp_dev,
&ry_dev,
&lp20_dev,
&cr_dev,
&rp_dev,
&tu_dev,
&dz_dev,
@@ -693,7 +702,7 @@ dev = GET_DEV (inst);
for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
j = (int32) ((opc_val[i] >> I_V_FL) & I_M_FL); /* get class */
if (((opc_val[i] & DMASK) == (inst & masks[j])) && /* match? */
(((opc_val[i] & I_ITS) == 0) || ITS)) {
(((opc_val[i] & I_ITS) == 0) || Q_ITS)) {
fprintf (of, "%s ", opcode[i]); /* opcode */
switch (j) { /* case on class */

View File

@@ -1,6 +1,6 @@
/* pdp10_tim.c: PDP-10 tim subsystem simulator
Copyright (c) 1993-2005, Robert M Supnik
Copyright (c) 1993-2006, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -25,6 +25,8 @@
tim timer subsystem
03-Nov-06 RMS Rewritten to support idling
29-Oct-06 RMS Added clock coscheduling function
02-Feb-04 RMS Exported variables needed by Ethernet simulator
29-Jan-02 RMS New data structures
06-Jan-02 RMS Added enable/disable support
@@ -37,41 +39,61 @@
#include "pdp10_defs.h"
#include <time.h>
#define TIM_N_HWRE 12 /* hwre bits */
#define TIM_HWRE 0000000010000 /* hwre incr */
#define TIM_DELAY 500
#define TIM_TPS 1001 /* ticks per sec */
#define DZ_MULT (TIM_TPS / 60) /* DZ poll multiplier */
#define TB_MASK 037777777777777777777; /* 71 - 12 bits */
#define UNIT_V_Y2K (UNIT_V_UF) /* Y2K compliant OS */
/* Invariants */
#define TIM_HW_FREQ 4100000 /* 4.1Mhz */
#define TIM_HWRE_MASK 07777
#define UNIT_V_Y2K (UNIT_V_UF + 0) /* Y2K compliant OS */
#define UNIT_Y2K (1u << UNIT_V_Y2K)
/* Clock mode TOPS-10/ITS */
#define TIM_TPS_T10 60
#define TIM_WAIT_T10 8000
#define TIM_MULT_T10 1
#define TIM_ITS_QUANT (TIM_HW_FREQ / TIM_TPS_T10)
/* Clock mode TOPS-20/KLAD */
#define TIM_TPS_T20 1001
#define TIM_WAIT_T20 500
#define TIM_MULT_T20 16
/* Probability function for TOPS-20 idlelock */
#define PROB(x) (((rand() * 100) / RAND_MAX) >= (x))
d10 tim_base[2] = { 0, 0 }; /* 71b timebase */
d10 tim_ttg = 0; /* time to go */
d10 tim_period = 0; /* period */
d10 quant = 0; /* ITS quantum */
int32 tim_mult = TIM_MULT_T10; /* tmxr poll mult */
int32 tim_t20_prob = 33; /* TOPS-20 prob */
/* Exported variables */
int32 clk_tps = TIM_TPS_T10; /* clock ticks/sec */
int32 tmr_poll = TIM_WAIT_T10; /* clock poll */
int32 tmxr_poll = TIM_WAIT_T10 * TIM_MULT_T10; /* term mux poll */
extern int32 apr_flg, pi_act;
extern UNIT cpu_unit;
extern d10 pcst;
extern a10 pager_PC;
t_int64 timebase = 0; /* 71b timebase */
d10 ttg = 0; /* time to go */
d10 period = 0; /* period */
d10 quant = 0; /* ITS quantum */
int32 diagflg = 0; /* diagnostics? */
int32 tmxr_poll = TIM_DELAY * DZ_MULT; /* term mux poll */
/* Exported variables */
int32 clk_tps = TIM_TPS; /* clock ticks/sec */
int32 tmr_poll = TIM_DELAY; /* clock poll */
extern int32 t20_idlelock;
DEVICE tim_dev;
t_stat tcu_rd (int32 *data, int32 PA, int32 access);
extern t_stat wr_nop (int32 data, int32 PA, int32 access);
t_stat tim_svc (UNIT *uptr);
t_stat tim_reset (DEVICE *dptr);
void tim_incr_base (d10 *base, d10 incr);
extern d10 Read (a10 ea, int32 prv);
extern d10 ReadM (a10 ea, int32 prv);
extern void Write (a10 ea, d10 val, int32 prv);
extern void WriteP (a10 ea, d10 val);
extern int32 pi_eval (void);
extern t_stat wr_nop (int32 data, int32 PA, int32 access);
/* TIM data structures
@@ -82,16 +104,19 @@ extern int32 pi_eval (void);
DIB tcu_dib = { IOBA_TCU, IOLN_TCU, &tcu_rd, &wr_nop, 0 };
UNIT tim_unit = { UDATA (&tim_svc, 0, 0), TIM_DELAY };
UNIT tim_unit = { UDATA (&tim_svc, 0, 0), TIM_WAIT_T10 };
REG tim_reg[] = {
{ ORDATA (TIMEBASE, timebase, 71 - TIM_N_HWRE) },
{ ORDATA (TTG, ttg, 36) },
{ ORDATA (PERIOD, period, 36) },
{ BRDATA (TIMEBASE, tim_base, 8, 36, 2) },
{ ORDATA (TTG, tim_ttg, 36) },
{ ORDATA (PERIOD, tim_period, 36) },
{ ORDATA (QUANT, quant, 36) },
{ DRDATA (TIME, tim_unit.wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (DIAG, diagflg, 0) },
{ FLDATA (Y2K, tim_unit.flags, UNIT_V_Y2K), REG_HRO },
{ DRDATA (PROB, tim_t20_prob, 6), REG_NZ + PV_LEFT + REG_HIDDEN },
{ DRDATA (POLL, tmr_poll, 32), REG_HRO + PV_LEFT },
{ DRDATA (MUXPOLL, tmxr_poll, 32), REG_HRO + PV_LEFT },
{ DRDATA (MULT, tim_mult, 6), REG_HRO + PV_LEFT },
{ DRDATA (TPS, clk_tps, 12), REG_HRO + PV_LEFT },
{ NULL }
};
@@ -108,79 +133,135 @@ DEVICE tim_dev = {
1, 0, 0, 0, 0, 0,
NULL, NULL, &tim_reset,
NULL, NULL, NULL,
&tcu_dib, DEV_DISABLE | DEV_UBUS
&tcu_dib, DEV_UBUS
};
/* Timer instructions */
/* Timer - if the timer is running at less than hardware frequency,
need to interpolate the value by calculating how much of the current
clock tick has elapsed, and what that equates to in msec. */
t_bool rdtim (a10 ea, int32 prv)
{
ReadM (INCA (ea), prv);
Write (ea, (timebase >> (35 - TIM_N_HWRE)) & DMASK, prv);
Write (INCA(ea), (timebase << TIM_N_HWRE) & MMASK, prv);
d10 tempbase[2];
ReadM (INCA (ea), prv); /* check 2nd word */
tempbase[0] = tim_base[0]; /* copy time base */
tempbase[1] = tim_base[1];
if (tim_mult != TIM_MULT_T20) { /* interpolate? */
int32 used;
d10 incr;
used = tmr_poll - (sim_is_active (&tim_unit) - 1);
incr = (d10) (((double) used * TIM_HW_FREQ) /
((double) tmr_poll * (double) clk_tps));
tim_incr_base (tempbase, incr);
}
tempbase[0] = tempbase[0] & ~((d10) TIM_HWRE_MASK); /* clear low 12b */
Write (ea, tempbase[0], prv);
Write (INCA(ea), tempbase[1], prv);
return FALSE;
}
t_bool wrtim (a10 ea, int32 prv)
{
timebase = (Read (ea, prv) << (35 - TIM_N_HWRE)) |
(CLRS (Read (INCA (ea), prv)) >> TIM_N_HWRE);
tim_base[0] = Read (ea, prv);
tim_base[1] = CLRS (Read (INCA (ea), prv));
return FALSE;
}
t_bool rdint (a10 ea, int32 prv)
{
Write (ea, period, prv);
Write (ea, tim_period, prv);
return FALSE;
}
t_bool wrint (a10 ea, int32 prv)
{
period = Read (ea, prv);
ttg = period;
tim_period = Read (ea, prv);
tim_ttg = tim_period;
return FALSE;
}
/* Timer routines
tim_svc process event (timer tick)
tim_reset process reset
*/
/* Timer service - the timer is only serviced when the 'ttg' register
has reached 0 based on the expected frequency of clock interrupts. */
t_stat tim_svc (UNIT *uptr)
{
int32 t;
t = diagflg? tim_unit.wait: sim_rtc_calb (TIM_TPS); /* calibrate clock */
sim_activate (&tim_unit, t); /* reactivate unit */
tmr_poll = t; /* set timer poll */
tmxr_poll = t * DZ_MULT; /* set mux poll */
timebase = (timebase + 1) & TB_MASK; /* increment timebase */
ttg = ttg - TIM_HWRE; /* decrement timer */
if (ttg <= 0) { /* timeout? */
ttg = period; /* reload */
apr_flg = apr_flg | APRF_TIM; /* request interrupt */
}
if (ITS) { /* ITS? */
if (pi_act == 0) quant = (quant + TIM_HWRE) & DMASK;
if (cpu_unit.flags & UNIT_KLAD) /* diags? */
tmr_poll = uptr->wait; /* fixed clock */
else tmr_poll = sim_rtc_calb (clk_tps); /* else calibrate */
sim_activate (uptr, tmr_poll); /* reactivate unit */
tmxr_poll = tmr_poll * tim_mult; /* set mux poll */
tim_incr_base (tim_base, tim_period); /* incr time base */
tim_ttg = tim_period; /* reload */
apr_flg = apr_flg | APRF_TIM; /* request interrupt */
if (Q_ITS) { /* ITS? */
if (pi_act == 0)
quant = (quant + TIM_ITS_QUANT) & DMASK;
if (TSTS (pcst)) { /* PC sampling? */
WriteP ((a10) pcst & AMASK, pager_PC); /* store sample */
pcst = AOB (pcst); /* add 1,,1 */
}
} /* end ITS */
else if (t20_idlelock && PROB (100 - tim_t20_prob))
t20_idlelock = 0;
return SCPE_OK;
}
t_stat tim_reset (DEVICE *dptr)
/* Clock coscheduling routine */
int32 clk_cosched (int32 wait)
{
int32 t;
period = ttg = 0; /* clear timer */
if (tim_mult == TIM_MULT_T20) return wait;
t = sim_is_active (&tim_unit);
return (t? t - 1: wait);
}
void tim_incr_base (d10 *base, d10 incr)
{
base[1] = base[1] + incr; /* add on incr */
base[0] = base[0] + (base[1] >> 35); /* carry to high */
base[0] = base[0] & DMASK; /* mask high */
base[1] = base[1] & MMASK; /* mask low */
return;
}
/* Timer reset */
t_stat tim_reset (DEVICE *dptr)
{
tim_period = 0; /* clear timer */
tim_ttg = 0;
apr_flg = apr_flg & ~APRF_TIM; /* clear interrupt */
t = sim_rtc_init (tim_unit.wait); /* init timer */
sim_activate (&tim_unit, t); /* activate unit */
tmr_poll = t; /* set timer poll */
tmxr_poll = t * DZ_MULT; /* set mux poll */
tmr_poll = sim_rtc_init (tim_unit.wait); /* init timer */
sim_activate_abs (&tim_unit, tmr_poll); /* activate unit */
tmxr_poll = tmr_poll * tim_mult; /* set mux poll */
return SCPE_OK;
}
/* Set timer parameters from CPU model */
t_stat tim_set_mod (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (val & (UNIT_T20|UNIT_KLAD)) {
clk_tps = TIM_TPS_T20;
uptr->wait = TIM_WAIT_T20;
tmr_poll = TIM_WAIT_T20;
tim_mult = TIM_MULT_T20;
uptr->flags = uptr->flags | UNIT_Y2K;
}
else {
clk_tps = TIM_TPS_T10;
uptr->wait = TIM_WAIT_T10;
tmr_poll = TIM_WAIT_T10;
tim_mult = TIM_MULT_T10;
if (Q_ITS) uptr->flags = uptr->flags | UNIT_Y2K;
else uptr->flags = uptr->flags & ~UNIT_Y2K;
}
tmxr_poll = tmr_poll * tim_mult;
return SCPE_OK;
}

View File

@@ -839,7 +839,7 @@ switch (fnc) { /* case on function */
tufs = tufs | FS_ATA;
break;
case FNC_WREOF: /* write end of file */
case FNC_WREOF: /* write end of file */
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
r = tu_map_err (uptr, st, 0); /* map error */
tufs = tufs | FS_ATA;
@@ -1225,7 +1225,7 @@ M[FE_UNIT] = 0;
M[FE_MTFMT] = (unitno & TC_M_UNIT) | (TC_1600 << TC_V_DEN) | (TC_10C << TC_V_FMT);
tu_unit[unitno].pos = 0;
for (i = 0; i < BOOT_LEN; i++)
M[BOOT_START + i] = ITS? boot_rom_its[i]: boot_rom_dec[i];
M[BOOT_START + i] = Q_ITS? boot_rom_its[i]: boot_rom_dec[i];
saved_PC = BOOT_START;
return SCPE_OK;
}