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:
committed by
Mark Pizzolato
parent
15919a2dd7
commit
53d02f7fa7
@@ -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 ();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user