mirror of
https://github.com/simh/simh.git
synced 2026-03-27 10:21:07 +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
@@ -700,7 +700,7 @@ switch (op) { /* case on opcode */
|
||||
fpd = 1; /* set FPD */
|
||||
R[4] = R[4] & 0377; /* mask fill */
|
||||
c = t = 0;
|
||||
for (i = 0; (R[0] || R[2]); ) { /* until cnts == 0 */
|
||||
for (i = 0; (R[0] || R[2]); ) { /* until cnts == 0 */
|
||||
if (R[0]) c = ReadB (R[1] | dsenable); /* get src1 or fill */
|
||||
else c = R[4];
|
||||
if (R[2]) t = ReadB (R[3] | dsenable); /* get src2 or fill */
|
||||
@@ -1192,15 +1192,18 @@ return TestDstr (src); /* clean -0 */
|
||||
dsrc = decimal string descriptor
|
||||
src = decimal string structure
|
||||
flag = numeric/packed flag
|
||||
|
||||
PSW.NZ are also set to their proper values
|
||||
PSW.V will be set on overflow; it must be initialized elsewhere
|
||||
(to allow for external overflow calculations)
|
||||
(to allow for external overflow calculations)
|
||||
|
||||
The rules for the stored sign and the PSW sign are:
|
||||
- Stored sign is negative if input is negative, string type
|
||||
is signed, and the result is non-zero or there was overflow
|
||||
- PSW sign is negative if input is negative, string type is
|
||||
signed, and the result is non-zero
|
||||
|
||||
- Stored sign is negative if input is negative, string type
|
||||
is signed, and the result is non-zero or there was overflow
|
||||
- PSW sign is negative if input is negative, string type is
|
||||
signed, and the result is non-zero
|
||||
|
||||
Thus, the stored sign and the PSW sign will differ in one case:
|
||||
a negative zero generated by overflow is stored with a negative
|
||||
sign, but PSW.N is clear
|
||||
@@ -1265,16 +1268,18 @@ return;
|
||||
cy = carry in
|
||||
Output = 1 if carry, 0 if no carry
|
||||
|
||||
This algorithm courtesy Anton Chernoff, circa 1992 or even earlier
|
||||
This algorithm courtesy Anton Chernoff, circa 1992 or even earlier.
|
||||
|
||||
We trace the history of a pair of adjacent digits to see how the
|
||||
carry is fixed; each parenthesized item is a 4b digit.
|
||||
|
||||
Assume we are adding:
|
||||
|
||||
(a)(b) I
|
||||
+ (x)(y) J
|
||||
|
||||
First compute I^J:
|
||||
|
||||
(a^x)(b^y) TMP
|
||||
|
||||
Note that the low bit of each digit is the same as the low bit of
|
||||
@@ -1283,6 +1288,7 @@ return;
|
||||
|
||||
Now compute I+J+66 to get decimal addition with carry forced left
|
||||
one digit:
|
||||
|
||||
(a+x+6+carry mod 16)(b+y+6 mod 16) SUM
|
||||
|
||||
Note that if there was a carry from b+y+6, then the low bit of the
|
||||
@@ -1357,6 +1363,7 @@ return 0;
|
||||
|
||||
Arguments:
|
||||
dsrc = decimal string structure
|
||||
|
||||
Returns the non-zero length of the string, in int32 units
|
||||
If the string is zero, the sign is cleared
|
||||
*/
|
||||
@@ -1395,8 +1402,8 @@ return ((nz - 1) * 8) + i;
|
||||
mtable[10] = array of decimal string structures
|
||||
|
||||
Note that dsrc has a high order zero nibble; this
|
||||
guarantees that the largest multiple won't overflow
|
||||
Also note that mtable[0] is not filled in
|
||||
guarantees that the largest multiple won't overflow.
|
||||
Also note that mtable[0] is not filled in.
|
||||
*/
|
||||
|
||||
void CreateTable (DSTR *dsrc, DSTR mtable[10])
|
||||
@@ -1560,7 +1567,7 @@ fpd = 0; /* instr done */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Test for CIS mid-instruction interrupt - stub for now */
|
||||
/* Test for CIS mid-instruction interrupt */
|
||||
|
||||
t_bool cis_int_test (int32 cycles, int32 oldpc, t_stat *st)
|
||||
{
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
cpu PDP-11 CPU
|
||||
|
||||
27-Oct-06 RMS Added idle support
|
||||
18-Oct-06 RMS Fixed bug in ASH -32 C value
|
||||
24-May-06 RMS Added instruction history
|
||||
03-May-06 RMS Fixed XOR operand fetch order for 11/70-style systems
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
@@ -220,8 +222,8 @@
|
||||
#define calc_is(md) ((md) << VA_V_MODE)
|
||||
#define calc_ds(md) (calc_is((md)) | ((MMR3 & dsmask[(md)])? VA_DS: 0))
|
||||
#define calc_MMR1(val) ((MMR1)? (((val) << 8) | MMR1): (val))
|
||||
#define GET_SIGN_W(v) ((v) >> 15)
|
||||
#define GET_SIGN_B(v) ((v) >> 7)
|
||||
#define GET_SIGN_W(v) (((v) >> 15) & 1)
|
||||
#define GET_SIGN_B(v) (((v) >> 7) & 1)
|
||||
#define GET_Z(v) ((v) == 0)
|
||||
#define JMP_PC(x) PCQ_ENTRY; PC = (x)
|
||||
#define BRANCH_F(x) PCQ_ENTRY; PC = (PC + (((x) + (x)) & 0377)) & 0177777
|
||||
@@ -300,6 +302,7 @@ extern UNIT clk_unit, pclk_unit;
|
||||
extern int32 sim_int_char;
|
||||
extern uint32 sim_switches;
|
||||
extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
|
||||
extern t_bool sim_idle_enab;
|
||||
extern DEVICE *sim_devices[];
|
||||
extern CPUTAB cpu_tab[];
|
||||
|
||||
@@ -376,7 +379,7 @@ int32 trap_clear[TRAP_V_MAX] = { /* trap clears */
|
||||
cpu_mod CPU modifier list
|
||||
*/
|
||||
|
||||
UNIT cpu_unit = { UDATA (NULL, UNIT_FIX + UNIT_BINK, INIMEMSIZE) };
|
||||
UNIT cpu_unit = { UDATA (NULL, UNIT_FIX|UNIT_BINK, INIMEMSIZE) };
|
||||
|
||||
REG cpu_reg[] = {
|
||||
{ ORDATA (PC, saved_PC, 16) },
|
||||
@@ -533,7 +536,7 @@ REG cpu_reg[] = {
|
||||
{ BRDATA (IREQ, int_req, 8, 32, IPL_HLVL), REG_RO },
|
||||
{ ORDATA (TRAPS, trap_req, TRAP_V_MAX) },
|
||||
{ FLDATA (WAIT, wait_state, 0) },
|
||||
{ FLDATA (WAIT_ENABLE, wait_enable, 0) },
|
||||
{ FLDATA (WAIT_ENABLE, wait_enable, 0), REG_HIDDEN },
|
||||
{ ORDATA (STOP_TRAPS, stop_trap, TRAP_V_MAX) },
|
||||
{ FLDATA (STOP_VECA, stop_vecabort, 0) },
|
||||
{ FLDATA (STOP_SPA, stop_spabort, 0) },
|
||||
@@ -583,6 +586,8 @@ MTAB cpu_mod[] = {
|
||||
{ MTAB_XTD|MTAB_VDV, OPT_CIS, NULL, "NOCIS", &cpu_clr_opt },
|
||||
{ MTAB_XTD|MTAB_VDV, OPT_MMU, NULL, "MMU", &cpu_set_opt },
|
||||
{ MTAB_XTD|MTAB_VDV, OPT_MMU, NULL, "NOMMU", &cpu_clr_opt },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "IDLE", "IDLE", &sim_set_idle, &sim_show_idle },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, NULL, "NOIDLE", &sim_clr_idle, NULL },
|
||||
{ UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size},
|
||||
{ UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size},
|
||||
{ UNIT_MSIZE, 49152, NULL, "48K", &cpu_set_size},
|
||||
@@ -786,8 +791,11 @@ while (reason == 0) {
|
||||
|
||||
if (tbit) setTRAP (TRAP_TRC);
|
||||
if (wait_state) { /* wait state? */
|
||||
if (sim_qcount () != 0) sim_interval = 0; /* force check */
|
||||
else reason = STOP_WAIT;
|
||||
if (sim_idle_enab) /* idle enabled? */
|
||||
sim_idle (TMR_CLK, TRUE);
|
||||
else if (wait_enable) /* old style idle? */
|
||||
sim_interval = 0; /* force check */
|
||||
else sim_interval = sim_interval - 1; /* count cycle */
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -846,7 +854,7 @@ while (reason == 0) {
|
||||
else setTRAP (TRAP_ILL); /* no, ill inst */
|
||||
break;
|
||||
case 1: /* WAIT */
|
||||
if (wait_enable) wait_state = 1;
|
||||
wait_state = 1;
|
||||
break;
|
||||
case 3: /* BPT */
|
||||
setTRAP (TRAP_BPT);
|
||||
@@ -1374,7 +1382,7 @@ while (reason == 0) {
|
||||
else PWriteW (dst, last_pa);
|
||||
break;
|
||||
|
||||
/* Opcode 07: EIS, FIS (not implemented), CIS
|
||||
/* Opcode 07: EIS, FIS, CIS
|
||||
|
||||
Notes:
|
||||
- The code assumes that the host int length is at least 32 bits.
|
||||
@@ -1471,7 +1479,8 @@ while (reason == 0) {
|
||||
}
|
||||
else if (src2 == 32) { /* [32] = -32 */
|
||||
dst = -sign;
|
||||
V = C = 0;
|
||||
V = 0;
|
||||
C = sign;
|
||||
}
|
||||
else { /* [33,63] = -31,-1 */
|
||||
dst = (src >> (64 - src2)) | (-sign << (src2 - 32));
|
||||
@@ -1505,7 +1514,7 @@ while (reason == 0) {
|
||||
else if (src2 == 32) { /* [32] = -32 */
|
||||
dst = -sign;
|
||||
V = 0;
|
||||
C = (src >> 31) & 1;
|
||||
C = sign;
|
||||
}
|
||||
else { /* [33,63] = -31,-1 */
|
||||
dst = (src >> (64 - src2)) | (-sign << (src2 - 32));
|
||||
@@ -2136,7 +2145,7 @@ if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
||||
}
|
||||
pa = relocR (va); /* relocate */
|
||||
if (ADDR_IS_MEM (pa)) return (M[pa >> 1]); /* memory address? */
|
||||
if ((pa < IOPAGEBASE) || /* I/O address */
|
||||
if ((pa < IOPAGEBASE) || /* not I/O address */
|
||||
(CPUT (CPUT_J) && (pa >= IOBA_CPU))) { /* or J11 int reg? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
@@ -2158,7 +2167,7 @@ if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
||||
}
|
||||
pa = relocR (va); /* relocate */
|
||||
if (ADDR_IS_MEM (pa)) return (M[pa >> 1]); /* memory address? */
|
||||
if (pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2175,7 +2184,7 @@ int32 pa, data;
|
||||
|
||||
pa = relocR (va); /* relocate */
|
||||
if (ADDR_IS_MEM (pa)) return (va & 1? M[pa >> 1] >> 8: M[pa >> 1]) & 0377;
|
||||
if (pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2196,7 +2205,7 @@ if ((va & 1) && CPUT (HAS_ODD)) { /* odd address? */
|
||||
}
|
||||
last_pa = relocW (va); /* reloc, wrt chk */
|
||||
if (ADDR_IS_MEM (last_pa)) return (M[last_pa >> 1]); /* memory address? */
|
||||
if (last_pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (last_pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2214,7 +2223,7 @@ int32 data;
|
||||
last_pa = relocW (va); /* reloc, wrt chk */
|
||||
if (ADDR_IS_MEM (last_pa))
|
||||
return (va & 1? M[last_pa >> 1] >> 8: M[last_pa >> 1]) & 0377;
|
||||
if (last_pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (last_pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2247,7 +2256,7 @@ if (ADDR_IS_MEM (pa)) { /* memory address? */
|
||||
M[pa >> 1] = data;
|
||||
return;
|
||||
}
|
||||
if (pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2268,7 +2277,7 @@ if (ADDR_IS_MEM (pa)) { /* memory address? */
|
||||
else M[pa >> 1] = (M[pa >> 1] & ~0377) | data;
|
||||
return;
|
||||
}
|
||||
if (pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2285,7 +2294,7 @@ if (ADDR_IS_MEM (pa)) { /* memory address? */
|
||||
M[pa >> 1] = data;
|
||||
return;
|
||||
}
|
||||
if (pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2303,7 +2312,7 @@ if (ADDR_IS_MEM (pa)) { /* memory address? */
|
||||
else M[pa >> 1] = (M[pa >> 1] & ~0377) | data;
|
||||
return;
|
||||
}
|
||||
if (pa < IOPAGEBASE) { /* I/O address? */
|
||||
if (pa < IOPAGEBASE) { /* not I/O address? */
|
||||
setCPUERR (CPUE_NXM);
|
||||
ABORT (TRAP_NXM);
|
||||
}
|
||||
@@ -2574,8 +2583,8 @@ switch ((pa >> 1) & 3) { /* decode pa<2:1> */
|
||||
case 3: /* MMR2 */
|
||||
*data = MMR2;
|
||||
break;
|
||||
}
|
||||
/* end switch pa */
|
||||
} /* end switch pa */
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1024,7 +1024,7 @@ t_stat r;
|
||||
for (i = 0; cnf_tab[i].dib != NULL; i++) { /* loop thru config tab */
|
||||
if (((cnf_tab[i].cpum == 0) || (cpu_type & cnf_tab[i].cpum)) &&
|
||||
((cnf_tab[i].optm == 0) || (cpu_opt & cnf_tab[i].optm))) {
|
||||
if (r = build_ubus_tab (&cpu_dev, cnf_tab[i].dib)) /* add to dispatch tab */
|
||||
if (r = build_ubus_tab (&cpu_dev, cnf_tab[i].dib)) /* add to dispatch tab */
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp11_cr.c: CR/CM/CD-11 card reader simulator
|
||||
|
||||
Copyright (c) 2005, John A. Dundas III
|
||||
Copyright (c) 2005-2007, John A. Dundas III
|
||||
Portions derived from work by Douglas W. Jones, jones@cs.uiowa.edu
|
||||
Portions derived from work by Robert M Supnik
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
http://www.cs.uiowa.edu/~jones/cards/
|
||||
Paul Mattes' x026 keypunch simulator
|
||||
http://x3270.bgp.nu/x026.html
|
||||
CDRSER.MAC - TOPS card reader driver source
|
||||
http://pdp-10.trailing-edge.com/custsupcuspmar86_bb-x130b-sb/02/cdrser.mac
|
||||
CD2SER.MAC - TOPS card reader driver source
|
||||
http://pdp-10.trailing-edge.com/custsupcuspmar86_bb-x130b-sb/02/cd2ser.mac
|
||||
|
||||
The Card Image format code and documentation is adapted from Prof.
|
||||
Jones's site, with his permission. Please see his site for additional
|
||||
@@ -66,14 +66,13 @@
|
||||
3. No testing under RSX; volunteers needed
|
||||
4. No testing under Ultrix or Unix for PDP-11; volunteers needed
|
||||
5. No testing under Ultrix or Unix for VAX; volunteers needed
|
||||
6. No PDP-10 support; volunteers needed
|
||||
7. The simulator implements a single controller/reader combination
|
||||
6. The simulator implements a single controller/reader combination
|
||||
|
||||
Operating System Notes
|
||||
|
||||
RT-11 (and CTS-300) support one CR11 or CM11, but no CD11.
|
||||
|
||||
VMS supports multiple CR11 controllers.
|
||||
VMS supports multiple CR11 controllers, but no CD11.
|
||||
|
||||
RSTS/E supports either the CR11/CM11 or CD11 but not both in
|
||||
the same SIL. It appears to support only one unit.
|
||||
@@ -84,12 +83,11 @@
|
||||
Don't have any information about Unix or Ultrix-11 yet. Same
|
||||
for VAX Unices.
|
||||
|
||||
TOPS: it appears that both the CD11 and CR11 were supported.
|
||||
I don't have any knowledge on how to make this work with the
|
||||
PDP-10 simulation, though.
|
||||
TOPS: only the CD11 is supported, under the name CD20.
|
||||
|
||||
Revision History:
|
||||
|
||||
01-Feb-07 RMS Added PDP-10 support
|
||||
12-May-06 JAD Modify the DEBUG code to use the SIMH DEBUG_x
|
||||
macros. Modify the UNIT structure to include
|
||||
the DEBUG bit.
|
||||
@@ -168,14 +166,23 @@
|
||||
#if defined (VM_PDP10) /* PDP10 version */
|
||||
#include "pdp10_defs.h"
|
||||
extern int32 int_req;
|
||||
#define DFLT_DIS (DEV_DIS)
|
||||
#define DFLT_CR11 (0) /* CD11 only */
|
||||
#define DFLT_CPM 1000
|
||||
|
||||
#elif defined (VM_VAX) /* VAX version */
|
||||
#include "vax_defs.h"
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
#define DFLT_DIS (0)
|
||||
#define DFLT_CR11 (UNIT_CR11)
|
||||
#define DFLT_CPM 285
|
||||
|
||||
#else /* PDP-11 version */
|
||||
#include "pdp11_defs.h"
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
#define DFLT_DIS (0)
|
||||
#define DFLT_CR11 (UNIT_CR11)
|
||||
#define DFLT_CPM 285
|
||||
#endif
|
||||
|
||||
extern FILE *sim_deb; /* sim_console.c */
|
||||
@@ -294,7 +301,7 @@ static int32 blowerState = BLOW_OFF; /* reader vacuum/blower
|
||||
static int32 spinUp = 3000; /* blower spin-up time: 3 seconds */
|
||||
static int32 spinDown = 2000; /* blower spin-down time: 2 seconds */
|
||||
static t_bool EOFcard = FALSE; /* played special card yet? */
|
||||
static int32 cpm = 285; /* reader rate: cards per minute */
|
||||
static int32 cpm = DFLT_CPM; /* reader rate: cards per minute */
|
||||
/* card image in various formats */
|
||||
static int16 hcard[82]; /* Hollerith format */
|
||||
static char ccard[82]; /* DEC compressed format */
|
||||
@@ -343,8 +350,8 @@ static DIB cr_dib = { IOBA_CR, IOLN_CR, &cr_rd, &cr_wr,
|
||||
static UNIT cr_unit = {
|
||||
UDATA (&cr_svc,
|
||||
UNIT_ATTABLE+UNIT_SEQ+UNIT_ROABLE+UNIT_DISABLE+
|
||||
UNIT_CR11+UNIT_AUTOEOF, 0),
|
||||
(60 * 1000) / 285 };
|
||||
DFLT_CR11+UNIT_AUTOEOF, 0),
|
||||
(60 * 1000) / DFLT_CPM };
|
||||
|
||||
static const REG cr_reg[] = {
|
||||
{ GRDATA (BUF, cr_unit.buf, DEV_RDX, 8, 0) },
|
||||
@@ -367,8 +374,13 @@ static const REG cr_reg[] = {
|
||||
{ NULL } };
|
||||
|
||||
static const MTAB cr_mod[] = {
|
||||
#if defined (VM_PDP11)
|
||||
{ UNIT_CR11, UNIT_CR11, "CR11", "CR11", &cr_set_type },
|
||||
{ UNIT_CR11, 0, "CD11", "CD11", &cr_set_type },
|
||||
#else
|
||||
{ UNIT_CR11, UNIT_CR11, "CR11", NULL },
|
||||
{ UNIT_CR11, 0, "CD11", NULL },
|
||||
#endif
|
||||
{ UNIT_AUTOEOF, UNIT_AUTOEOF, "auto EOF", "AUTOEOF", NULL },
|
||||
{ UNIT_AUTOEOF, 0, "no auto EOF", "NOAUTOEOF", NULL },
|
||||
/* card reader RESET switch */
|
||||
@@ -395,7 +407,7 @@ DEVICE cr_dev = {
|
||||
1, 10, 31, 1, DEV_RDX, 8,
|
||||
NULL, NULL, &cr_reset,
|
||||
NULL, &cr_attach, &cr_detach,
|
||||
&cr_dib, DEV_DISABLE | DEV_UBUS | DEV_DEBUG };
|
||||
&cr_dib, DEV_DISABLE | DFLT_DIS | DEV_UBUS | DEV_DEBUG };
|
||||
|
||||
/* Utility routines */
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
||||
and John Wilson in resolving questions about the PDP-11
|
||||
|
||||
16-Dec-06 RMS Added TA11 support
|
||||
29-Oct-06 RMS Added clock coscheduling
|
||||
06-Jul-06 RMS Added multiple KL11/DL11 support
|
||||
26-Jun-06 RMS Added RF11 support
|
||||
24-May-06 RMS Added 11/44 DR support (from CIS diagnostic)
|
||||
@@ -569,6 +571,8 @@ typedef struct pdp_dib DIB;
|
||||
#define IOLN_HK 040
|
||||
#define IOBA_RF (IOPAGEBASE + 017460) /* RF11 */
|
||||
#define IOLN_RF 020
|
||||
#define IOBA_TA (IOPAGEBASE + 017500) /* TA11 */
|
||||
#define IOLN_TA 004
|
||||
#define IOBA_LPT (IOPAGEBASE + 017514) /* LP11 */
|
||||
#define IOLN_LPT 004
|
||||
#define IOBA_CTL (IOPAGEBASE + 017520) /* board ctrl */
|
||||
@@ -613,7 +617,8 @@ typedef struct pdp_dib DIB;
|
||||
#define INT_V_CLK 0 /* BR6 */
|
||||
#define INT_V_PCLK 1
|
||||
#define INT_V_DTA 2
|
||||
#define INT_V_PIR6 3
|
||||
#define INT_V_TA 3
|
||||
#define INT_V_PIR6 4
|
||||
|
||||
#define INT_V_RK 0 /* BR5 */
|
||||
#define INT_V_RL 1
|
||||
@@ -653,6 +658,7 @@ typedef struct pdp_dib DIB;
|
||||
#define INT_CLK (1u << INT_V_CLK)
|
||||
#define INT_PCLK (1u << INT_V_PCLK)
|
||||
#define INT_DTA (1u << INT_V_DTA)
|
||||
#define INT_TA (1u << INT_V_TA)
|
||||
#define INT_PIR6 (1u << INT_V_PIR6)
|
||||
#define INT_RK (1u << INT_V_RK)
|
||||
#define INT_RL (1u << INT_V_RL)
|
||||
@@ -689,6 +695,7 @@ typedef struct pdp_dib DIB;
|
||||
#define IPL_CLK 6 /* int pri levels */
|
||||
#define IPL_PCLK 6
|
||||
#define IPL_DTA 6
|
||||
#define IPL_TA 6
|
||||
#define IPL_RK 5
|
||||
#define IPL_RL 5
|
||||
#define IPL_RX 5
|
||||
@@ -749,6 +756,7 @@ typedef struct pdp_dib DIB;
|
||||
#define VEC_CR 0230
|
||||
#define VEC_RP 0254
|
||||
#define VEC_TQ 0260
|
||||
#define VEC_TA 0260
|
||||
#define VEC_RX 0264
|
||||
#define VEC_RY 0264
|
||||
#define VEC_TTIX 0300
|
||||
@@ -810,4 +818,6 @@ void mba_set_don (uint32 mbus);
|
||||
void mba_set_enbdis (uint32 mb, t_bool dis);
|
||||
t_stat mba_show_num (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
int32 clk_cosched (int32 wait);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp11_dz.c: DZ11 terminal multiplexor simulator
|
||||
|
||||
Copyright (c) 2001-2005, Robert M Supnik
|
||||
Copyright (c) 2001-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 @@
|
||||
|
||||
dz DZ11 terminal multiplexor
|
||||
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
15-Jun-05 RMS Revised for new autoconfigure interface
|
||||
@@ -304,7 +305,8 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
|
||||
(dz_csr[dz] & 0377) | (data << 8):
|
||||
(dz_csr[dz] & ~0377) | data;
|
||||
if (data & CSR_CLR) dz_clear (dz, FALSE); /* clr? reset */
|
||||
if (data & CSR_MSE) sim_activate (&dz_unit, tmxr_poll);
|
||||
if (data & CSR_MSE) /* MSE? start poll */
|
||||
sim_activate (&dz_unit, clk_cosched (tmxr_poll));
|
||||
else dz_csr[dz] &= ~(CSR_SA | CSR_RDONE | CSR_TRDY);
|
||||
if ((data & CSR_RIE) == 0) dz_clr_rxint (dz); /* RIE = 0? */
|
||||
else if (((dz_csr[dz] & CSR_IE) == 0) && /* RIE 0->1? */
|
||||
|
||||
@@ -145,47 +145,55 @@
|
||||
|
||||
/* Double precision operations on 64b quantities */
|
||||
|
||||
#define F_LOAD(qd,ac,ds) ds.h = ac.h; ds.l = (qd)? ac.l: 0
|
||||
#define F_LOAD_P(qd,ac,ds) ds->h = ac.h; ds->l = (qd)? ac.l: 0
|
||||
#define F_LOAD_FRAC(qd,ac,ds) ds.h = (ac.h & FP_FRACH) | FP_HB; \
|
||||
ds.l = (qd)? ac.l: 0
|
||||
#define F_STORE(qd,sr,ac) ac.h = sr.h; if ((qd)) ac.l = sr.l
|
||||
#define F_STORE_P(qd,sr,ac) ac.h = sr->h; if ((qd)) ac.l = sr->l
|
||||
#define F_GET_FRAC_P(sr,ds) ds.l = sr->l; \
|
||||
ds.h = (sr->h & FP_FRACH) | FP_HB
|
||||
#define F_ADD(s2,s1,ds) ds.l = (s1.l + s2.l) & 0xFFFFFFFF; \
|
||||
ds.h = (s1.h + s2.h + (ds.l < s2.l)) & 0xFFFFFFFF
|
||||
#define F_SUB(s2,s1,ds) ds.h = (s1.h - s2.h - (s1.l < s2.l)) & 0xFFFFFFFF; \
|
||||
ds.l = (s1.l - s2.l) & 0xFFFFFFFF
|
||||
#define F_LT(x,y) ((x.h < y.h) || ((x.h == y.h) && (x.l < y.l)))
|
||||
#define F_LT_AP(x,y) (((x->h & ~FP_SIGN) < (y->h & ~FP_SIGN)) || \
|
||||
(((x->h & ~FP_SIGN) == (y->h & ~FP_SIGN)) && (x->l < y->l)))
|
||||
#define F_LOAD(qd,ac,ds) \
|
||||
ds.h = ac.h; ds.l = (qd)? ac.l: 0
|
||||
#define F_LOAD_P(qd,ac,ds) \
|
||||
ds->h = ac.h; ds->l = (qd)? ac.l: 0
|
||||
#define F_LOAD_FRAC(qd,ac,ds) \
|
||||
ds.h = (ac.h & FP_FRACH) | FP_HB; \
|
||||
ds.l = (qd)? ac.l: 0
|
||||
#define F_STORE(qd,sr,ac) \
|
||||
ac.h = sr.h; if ((qd)) ac.l = sr.l
|
||||
#define F_STORE_P(qd,sr,ac) \
|
||||
ac.h = sr->h; if ((qd)) ac.l = sr->l
|
||||
#define F_GET_FRAC_P(sr,ds) \
|
||||
ds.l = sr->l; \
|
||||
ds.h = (sr->h & FP_FRACH) | FP_HB
|
||||
#define F_ADD(s2,s1,ds) \
|
||||
ds.l = (s1.l + s2.l) & 0xFFFFFFFF; \
|
||||
ds.h = (s1.h + s2.h + (ds.l < s2.l)) & 0xFFFFFFFF
|
||||
#define F_SUB(s2,s1,ds) \
|
||||
ds.h = (s1.h - s2.h - (s1.l < s2.l)) & 0xFFFFFFFF; \
|
||||
ds.l = (s1.l - s2.l) & 0xFFFFFFFF
|
||||
#define F_LT(x,y) ((x.h < y.h) || ((x.h == y.h) && (x.l < y.l)))
|
||||
#define F_LT_AP(x,y) (((x->h & ~FP_SIGN) < (y->h & ~FP_SIGN)) || \
|
||||
(((x->h & ~FP_SIGN) == (y->h & ~FP_SIGN)) && (x->l < y->l)))
|
||||
#define F_LSH_V(sr,n,ds) \
|
||||
ds.h = (((n) >= 32)? (sr.l << ((n) - 32)): \
|
||||
(sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
|
||||
& 0xFFFFFFFF; \
|
||||
ds.l = ((n) >= 32)? 0: (sr.l << (n)) & 0xFFFFFFFF
|
||||
ds.h = (((n) >= 32)? (sr.l << ((n) - 32)): \
|
||||
(sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
|
||||
& 0xFFFFFFFF; \
|
||||
ds.l = ((n) >= 32)? 0: (sr.l << (n)) & 0xFFFFFFFF
|
||||
#define F_RSH_V(sr,n,ds) \
|
||||
ds.l = (((n) >= 32)? (sr.h >> ((n) - 32)) & and_mask[64 - (n)]: \
|
||||
((sr.l >> (n)) & and_mask[32 - (n)]) | \
|
||||
(sr.h << (32 - (n)))) & 0xFFFFFFFF; \
|
||||
ds.h = ((n) >= 32)? 0: \
|
||||
((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
|
||||
ds.l = (((n) >= 32)? (sr.h >> ((n) - 32)) & and_mask[64 - (n)]: \
|
||||
((sr.l >> (n)) & and_mask[32 - (n)]) | \
|
||||
(sr.h << (32 - (n)))) & 0xFFFFFFFF; \
|
||||
ds.h = ((n) >= 32)? 0: \
|
||||
((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
|
||||
|
||||
/* For the constant shift macro, arguments must in the range [2,31] */
|
||||
|
||||
#define F_LSH_1(ds) ds.h = ((ds.h << 1) | ((ds.l >> 31) & 1)) & 0xFFFFFFFF; \
|
||||
ds.l = (ds.l << 1) & 0xFFFFFFFF
|
||||
#define F_RSH_1(ds) ds.l = ((ds.l >> 1) & 0x7FFFFFFF) | ((ds.h & 1) << 31); \
|
||||
ds.h = ((ds.h >> 1) & 0x7FFFFFFF)
|
||||
#define F_LSH_1(ds) ds.h = ((ds.h << 1) | ((ds.l >> 31) & 1)) & 0xFFFFFFFF; \
|
||||
ds.l = (ds.l << 1) & 0xFFFFFFFF
|
||||
#define F_RSH_1(ds) ds.l = ((ds.l >> 1) & 0x7FFFFFFF) | ((ds.h & 1) << 31); \
|
||||
ds.h = ((ds.h >> 1) & 0x7FFFFFFF)
|
||||
#define F_LSH_K(sr,n,ds) \
|
||||
ds.h = ((sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
|
||||
& 0xFFFFFFFF; \
|
||||
ds.l = (sr.l << (n)) & 0xFFFFFFFF
|
||||
ds.h = ((sr.h << (n)) | ((sr.l >> (32 - (n))) & and_mask[n])) \
|
||||
& 0xFFFFFFFF; \
|
||||
ds.l = (sr.l << (n)) & 0xFFFFFFFF
|
||||
#define F_RSH_K(sr,n,ds) \
|
||||
ds.l = (((sr.l >> (n)) & and_mask[32 - (n)]) | \
|
||||
(sr.h << (32 - (n)))) & 0xFFFFFFFF; \
|
||||
ds.h = ((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
|
||||
ds.l = (((sr.l >> (n)) & and_mask[32 - (n)]) | \
|
||||
(sr.h << (32 - (n)))) & 0xFFFFFFFF; \
|
||||
ds.h = ((sr.h >> (n)) & and_mask[32 - (n)]) & 0xFFFFFFFF
|
||||
#define F_LSH_GUARD(ds) F_LSH_K(ds,FP_GUARD,ds)
|
||||
#define F_RSH_GUARD(ds) F_RSH_K(ds,FP_GUARD,ds)
|
||||
|
||||
@@ -252,7 +260,8 @@ int32 i, qdouble, lenf, leni;
|
||||
int32 newV, exp, sign;
|
||||
fpac_t fac, fsrc, modfrac;
|
||||
static const uint32 i_limit[2][2] = {
|
||||
{ 0x80000000, 0x80010000 }, { 0x80000000, 0x80000001 }
|
||||
{ 0x80000000, 0x80010000 },
|
||||
{ 0x80000000, 0x80000001 }
|
||||
};
|
||||
|
||||
backup_PC = PC; /* save PC for FEA */
|
||||
@@ -433,7 +442,7 @@ switch ((IR >> 8) & 017) { /* decode IR<11:8> */
|
||||
if (FPS & FPS_L) {
|
||||
leni = LONG;
|
||||
i = FP_BIAS + 32;
|
||||
}
|
||||
}
|
||||
else {
|
||||
leni = WORD;
|
||||
i = FP_BIAS + 16;
|
||||
@@ -602,7 +611,8 @@ return 0;
|
||||
uint32 ReadI (int32 VA, int32 spec, int32 len)
|
||||
{
|
||||
if ((len == WORD) || (spec == 027)) return (ReadW (VA) << 16);
|
||||
return ((ReadW (VA) << 16) | ReadW ((VA & ~0177777) | ((VA + 2) & 0177777)));
|
||||
return ((ReadW (VA) << 16) |
|
||||
ReadW ((VA & ~0177777) | ((VA + 2) & 0177777)));
|
||||
}
|
||||
|
||||
/* Read floating operand
|
||||
|
||||
@@ -469,7 +469,7 @@ int32 drv, i, j;
|
||||
|
||||
drv = GET_UNIT (hkcs2); /* get current unit */
|
||||
j = (PA >> 1) & 017; /* get reg offset */
|
||||
if (reg_in_drive[j] && (hk_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
||||
if (reg_in_drive[j] && (hk_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
||||
hkcs2 = hkcs2 | CS2_NED; /* set error flag */
|
||||
update_hkcs (0, drv);
|
||||
*data = 0;
|
||||
@@ -705,6 +705,7 @@ switch (fnc) { /* case on function */
|
||||
case FNC_NOP: /* no operation */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
break;
|
||||
|
||||
case FNC_PACK: /* pack acknowledge */
|
||||
hkds[drv] = hkds[drv] | DS_VV; /* set volume valid */
|
||||
update_hkcs (CS1_DONE, drv); /* done */
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
rf RF11 fixed head disk
|
||||
|
||||
25-Dec-06 RMS Fixed bug in unit mask (found by John Dundas)
|
||||
26-Jun-06 RMS Cloned from RF08 simulator
|
||||
|
||||
The RF11 is a head-per-track disk. To minimize overhead, the entire RF11
|
||||
@@ -42,7 +43,7 @@
|
||||
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 0) /* autosize */
|
||||
#define UNIT_V_PLAT (UNIT_V_UF + 1) /* #platters - 1 */
|
||||
#define UNIT_M_PLAT 03
|
||||
#define UNIT_M_PLAT (RF_NUMDK - 1)
|
||||
#define UNIT_GETP(x) ((((x) >> UNIT_V_PLAT) & UNIT_M_PLAT) + 1)
|
||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||
#define UNIT_PLAT (UNIT_M_PLAT << UNIT_V_PLAT)
|
||||
|
||||
@@ -31,12 +31,15 @@
|
||||
WARNING: The interupt logic of the RH11/RH70 is unusual and must be
|
||||
simulated with great precision. The RH11 has an internal interrupt
|
||||
request flop, CSTB INTR, which is controlled as follows:
|
||||
|
||||
- Writing IE and DONE simultaneously sets CSTB INTR
|
||||
- Controller clear, INIT, and interrupt acknowledge clear CSTB INTR
|
||||
(and also clear IE)
|
||||
- A transition of DONE from 0 to 1 sets CSTB INTR from IE
|
||||
|
||||
The output of CSTB INTR is OR'd with the AND of RPCS1<SC,DONE,IE> to
|
||||
create the interrupt request signal. Thus,
|
||||
|
||||
- The DONE interrupt is edge sensitive, but the SC interrupt is
|
||||
level sensitive.
|
||||
- The DONE interrupt, once set, is not disabled if IE is cleared,
|
||||
|
||||
@@ -75,7 +75,8 @@
|
||||
#define RK_NUMTR (RK_NUMCY * RK_NUMSF) /* tracks/drive */
|
||||
#define RK_NUMDR 8 /* drives/controller */
|
||||
#define RK_M_NUMDR 07
|
||||
#define RK_SIZE (RK_NUMCY * RK_NUMSF * RK_NUMSC * RK_NUMWD) /* words/drive */
|
||||
#define RK_SIZE (RK_NUMCY * RK_NUMSF * RK_NUMSC * RK_NUMWD)
|
||||
/* words/drive */
|
||||
#define RK_CTLI 1 /* controller int */
|
||||
#define RK_SCPI(x) (2u << (x)) /* drive int */
|
||||
#define RK_MAXFR (1 << 16) /* max transfer */
|
||||
@@ -172,8 +173,8 @@
|
||||
|
||||
#define RKBA_IMP 0177776 /* implemented */
|
||||
|
||||
#define RK_MIN 10
|
||||
#define MAX(x,y) (((x) > (y))? (x): (y))
|
||||
#define RK_MIN 10
|
||||
#define MAX(x,y) (((x) > (y))? (x): (y))
|
||||
|
||||
extern uint16 *M; /* memory */
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
@@ -297,8 +298,10 @@ switch ((PA >> 1) & 07) { /* decode PA<3:1> */
|
||||
rkds = (rkds & RKDS_ID) | RKDS_RK05 | RKDS_SC_OK |
|
||||
(rand () % RK_NUMSC); /* random sector */
|
||||
uptr = rk_dev.units + GET_DRIVE (rkda); /* selected unit */
|
||||
if (uptr->flags & UNIT_ATT) rkds = rkds | RKDS_RDY; /* attached? */
|
||||
if (!sim_is_active (uptr)) rkds = rkds | RKDS_RWS; /* idle? */
|
||||
if (uptr->flags & UNIT_ATT) /* attached? */
|
||||
rkds = rkds | RKDS_RDY;
|
||||
if (!sim_is_active (uptr)) /* idle? */
|
||||
rkds = rkds | RKDS_RWS;
|
||||
if (uptr->flags & UNIT_WPRT) rkds = rkds | RKDS_WLK;
|
||||
if (GET_SECT (rkda) == (rkds & RKDS_SC)) rkds = rkds | RKDS_ON_SC;
|
||||
*data = rkds;
|
||||
@@ -356,7 +359,8 @@ switch ((PA >> 1) & 07) { /* decode PA<3:1> */
|
||||
SET_INT (RK); /* set int request */
|
||||
}
|
||||
rkcs = (rkcs & ~RKCS_RW) | (data & RKCS_RW);
|
||||
if ((rkcs & CSR_DONE) && (data & CSR_GO)) rk_go (); /* new function? */
|
||||
if ((rkcs & CSR_DONE) && (data & CSR_GO)) /* new function? */
|
||||
rk_go ();
|
||||
return SCPE_OK;
|
||||
|
||||
case 3: /* RKWC */
|
||||
@@ -410,8 +414,9 @@ if (uptr->flags & UNIT_DIS) { /* not present? */
|
||||
rk_set_done (RKER_NXD);
|
||||
return;
|
||||
}
|
||||
if (((uptr->flags & UNIT_ATT) == 0) || sim_is_active (uptr)) {
|
||||
rk_set_done (RKER_DRE); /* not att or busy */
|
||||
if (((uptr->flags & UNIT_ATT) == 0) || /* not att or busy? */
|
||||
sim_is_active (uptr)) {
|
||||
rk_set_done (RKER_DRE);
|
||||
return;
|
||||
}
|
||||
if ((rkcs & RKCS_FMT) && /* format and */
|
||||
@@ -419,8 +424,9 @@ if ((rkcs & RKCS_FMT) && /* format and */
|
||||
rk_set_done (RKER_PGE);
|
||||
return;
|
||||
}
|
||||
if ((func == RKCS_WRITE) && (uptr->flags & UNIT_WPRT)) {
|
||||
rk_set_done (RKER_WLK); /* write and locked? */
|
||||
if ((func == RKCS_WRITE) && /* write and locked? */
|
||||
(uptr->flags & UNIT_WPRT)) {
|
||||
rk_set_done (RKER_WLK);
|
||||
return;
|
||||
}
|
||||
if (func == RKCS_WLK) { /* write lock? */
|
||||
@@ -530,7 +536,7 @@ if (wc && (err == 0)) { /* seek ok? */
|
||||
for ( ; i < wc; i++) rkxb[i] = 0; /* fill buf */
|
||||
}
|
||||
if (rkcs & RKCS_INH) { /* incr inhibit? */
|
||||
if (t = Map_WriteW (ma, 2, &rkxb[wc - 1])) { /* store last */
|
||||
if (t = Map_WriteW (ma, 2, &rkxb[wc - 1])) { /* store last */
|
||||
rker = rker | RKER_NXM; /* NXM? set flag */
|
||||
wc = 0; /* no transfer */
|
||||
}
|
||||
@@ -558,7 +564,7 @@ if (wc && (err == 0)) { /* seek ok? */
|
||||
}
|
||||
}
|
||||
if (wc) { /* any xfer? */
|
||||
awc = (wc + (RK_NUMWD - 1)) & ~(RK_NUMWD - 1); /* clr to */
|
||||
awc = (wc + (RK_NUMWD - 1)) & ~(RK_NUMWD - 1); /* clr to */
|
||||
for (i = wc; i < awc; i++) rkxb[i] = 0; /* end of blk */
|
||||
fxwrite (rkxb, sizeof (int16), awc, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
#define RP_NUMWD 256 /* words/sector */
|
||||
#define RP_MAXFR (1 << 16) /* max transfer */
|
||||
#define GET_SECTOR(x,d) ((int) fmod (sim_gtime() / ((double) (x)), \
|
||||
((double) drv_tab[d].sect)))
|
||||
((double) drv_tab[d].sect)))
|
||||
#define RM_OF (MBA_RMASK + 1)
|
||||
|
||||
/* Flags in the unit flags word */
|
||||
|
||||
@@ -369,12 +369,12 @@ switch (rx_state) { /* case on state */
|
||||
break;
|
||||
}
|
||||
uptr->TRACK = rx_track; /* now on track */
|
||||
if ((rx_sector == 0) || (rx_sector > RX_NUMSC)) { /* bad sect? */
|
||||
if ((rx_sector == 0) || (rx_sector > RX_NUMSC)) { /* bad sect? */
|
||||
rx_done (0, 0070); /* done, error */
|
||||
break;
|
||||
}
|
||||
da = CALC_DA (rx_track, rx_sector); /* get disk address */
|
||||
if (func == RXCS_WRDEL) rx_esr = rx_esr | RXES_DD; /* del data? */
|
||||
if (func == RXCS_WRDEL) rx_esr = rx_esr | RXES_DD; /* del data? */
|
||||
if (func == RXCS_READ) { /* read? */
|
||||
for (i = 0; i < RX_NUMBY; i++)
|
||||
rx_buf[i] = fbuf[da + i];
|
||||
|
||||
@@ -427,7 +427,7 @@ switch (ry_state) { /* case on state */
|
||||
break;
|
||||
}
|
||||
uptr->TRACK = ry_track; /* now on track */
|
||||
if ((ry_sector == 0) || (ry_sector > RX_NUMSC)) { /* bad sect? */
|
||||
if ((ry_sector == 0) || (ry_sector > RX_NUMSC)) { /* bad sect? */
|
||||
ry_done (0, 0070); /* done, error */
|
||||
break;
|
||||
}
|
||||
@@ -437,7 +437,7 @@ switch (ry_state) { /* case on state */
|
||||
break;
|
||||
}
|
||||
da = CALC_DA (ry_track, ry_sector, bps); /* get disk address */
|
||||
if (func == RYCS_WRDEL) ry_esr = ry_esr | RYES_DD; /* del data? */
|
||||
if (func == RYCS_WRDEL) ry_esr = ry_esr | RYES_DD; /* del data? */
|
||||
if (func == RYCS_READ) { /* read? */
|
||||
for (i = 0; i < bps; i++)
|
||||
rx2xb[i] = fbuf[da + i];
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
tti,tto DL11 terminal input/output
|
||||
clk KW11L (and other) line frequency clock
|
||||
|
||||
29-Oct-06 RMS Synced keyboard and clock
|
||||
Added clock coscheduling support
|
||||
05-Jul-06 RMS Added UC only support for early DOS/RSTS
|
||||
22-Nov-05 RMS Revised for new terminal processing routines
|
||||
22-Sep-05 RMS Fixed declarations (from Sterling Garwood)
|
||||
@@ -107,7 +109,7 @@ DIB tti_dib = {
|
||||
1, IVCL (TTI), VEC_TTI, { NULL }
|
||||
};
|
||||
|
||||
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
|
||||
UNIT tti_unit = { UDATA (&tti_svc, 0, 0), 0 };
|
||||
|
||||
REG tti_reg[] = {
|
||||
{ ORDATA (BUF, tti_unit.buf, 8) },
|
||||
@@ -117,7 +119,7 @@ REG tti_reg[] = {
|
||||
{ FLDATA (DONE, tti_csr, CSR_V_DONE) },
|
||||
{ FLDATA (IE, tti_csr, CSR_V_IE) },
|
||||
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
|
||||
{ DRDATA (TIME, tti_unit.wait, 24), PV_LEFT },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -153,7 +155,7 @@ DIB tto_dib = {
|
||||
1, IVCL (TTO), VEC_TTO, { NULL }
|
||||
};
|
||||
|
||||
UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
|
||||
UNIT tto_unit = { UDATA (&tto_svc, TT_MODE_7P, 0), SERIAL_OUT_WAIT };
|
||||
|
||||
REG tto_reg[] = {
|
||||
{ ORDATA (BUF, tto_unit.buf, 8) },
|
||||
@@ -281,7 +283,7 @@ t_stat tti_svc (UNIT *uptr)
|
||||
{
|
||||
int32 c;
|
||||
|
||||
sim_activate (uptr, uptr->wait); /* continue poll */
|
||||
sim_activate (uptr, KBD_WAIT (uptr->wait, tmr_poll)); /* continue poll */
|
||||
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
|
||||
if (c & SCPE_BREAK) uptr->buf = 0; /* break? */
|
||||
else uptr->buf = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags));
|
||||
@@ -298,7 +300,7 @@ t_stat tti_reset (DEVICE *dptr)
|
||||
tti_unit.buf = 0;
|
||||
tti_csr = 0;
|
||||
CLR_INT (TTI);
|
||||
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
|
||||
sim_activate_abs (&tti_unit, KBD_WAIT (tti_unit.wait, tmr_poll));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -404,7 +406,7 @@ t_stat clk_wr (int32 data, int32 PA, int32 access)
|
||||
if (clk_fnxm) return SCPE_NXM; /* not there??? */
|
||||
if (PA & 1) return SCPE_OK;
|
||||
clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
|
||||
if (CPUT (HAS_LTCM) && ((data & CSR_DONE) == 0)) /* monitor bit? */
|
||||
if (CPUT (HAS_LTCM) && ((data & CSR_DONE) == 0)) /* monitor bit? */
|
||||
clk_csr = clk_csr & ~CSR_DONE; /* clr if zero */
|
||||
if ((((clk_csr & CSR_IE) == 0) && !clk_fie) || /* unless IE+DONE */
|
||||
((clk_csr & CSR_DONE) == 0)) CLR_INT (CLK); /* clr intr */
|
||||
@@ -434,6 +436,16 @@ if (CPUT (CPUT_24)) clk_csr = clk_csr & ~CSR_DONE;
|
||||
return clk_dib.vec;
|
||||
}
|
||||
|
||||
/* Clock coscheduling routine */
|
||||
|
||||
int32 clk_cosched (int32 wait)
|
||||
{
|
||||
int32 t;
|
||||
|
||||
t = sim_is_active (&clk_unit);
|
||||
return (t? t - 1: wait);
|
||||
}
|
||||
|
||||
/* Clock reset */
|
||||
|
||||
t_stat clk_reset (DEVICE *dptr)
|
||||
|
||||
@@ -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.
|
||||
|
||||
20-Dec-06 RMS Added TA11 support
|
||||
12-Nov-06 RMS Fixed operand order in EIS instructions (found by W.F.J. Mueller)
|
||||
14-Jul-06 RMS Reordered device list
|
||||
06-Jul-06 RMS Added multiple KL11/DL11 support
|
||||
26-Jun-06 RMS Added RF11 support
|
||||
@@ -85,6 +87,7 @@ extern DEVICE tm_dev;
|
||||
extern DEVICE tq_dev;
|
||||
extern DEVICE ts_dev;
|
||||
extern DEVICE tu_dev;
|
||||
extern DEVICE ta_dev;
|
||||
extern DEVICE xq_dev, xqb_dev;
|
||||
extern DEVICE xu_dev, xub_dev;
|
||||
extern UNIT cpu_unit;
|
||||
@@ -141,6 +144,7 @@ DEVICE *sim_devices[] = {
|
||||
&ts_dev,
|
||||
&tq_dev,
|
||||
&tu_dev,
|
||||
&ta_dev,
|
||||
&xq_dev,
|
||||
&xqb_dev,
|
||||
&xu_dev,
|
||||
@@ -311,7 +315,7 @@ return SCPE_OK;
|
||||
/* Warning: for literals, the class number MUST equal the field width!! */
|
||||
|
||||
#define I_V_CL 18 /* class bits */
|
||||
#define I_M_CL 017 /* class mask */
|
||||
#define I_M_CL 037 /* class mask */
|
||||
#define I_V_NPN 0 /* no operands */
|
||||
#define I_V_REG 1 /* reg */
|
||||
#define I_V_SOP 2 /* operand */
|
||||
@@ -328,6 +332,7 @@ return SCPE_OK;
|
||||
#define I_V_DOP 13 /* double operand */
|
||||
#define I_V_CCC 14 /* CC clear */
|
||||
#define I_V_CCS 15 /* CC set */
|
||||
#define I_V_SOPR 16 /* operand, reg */
|
||||
#define I_NPN (I_V_NPN << I_V_CL)
|
||||
#define I_REG (I_V_REG << I_V_CL)
|
||||
#define I_3B (I_V_3B << I_V_CL)
|
||||
@@ -344,12 +349,14 @@ return SCPE_OK;
|
||||
#define I_DOP (I_V_DOP << I_V_CL)
|
||||
#define I_CCC (I_V_CCC << I_V_CL)
|
||||
#define I_CCS (I_V_CCS << I_V_CL)
|
||||
#define I_SOPR (I_V_SOPR << I_V_CL)
|
||||
|
||||
static const int32 masks[] = {
|
||||
0177777, 0177770, 0177700, 0177770,
|
||||
0177700+I_D, 0177400+I_D, 0177700, 0177400,
|
||||
0177400, 0177000, 0177000, 0177400,
|
||||
0177400+I_D+I_L, 0170000, 0177777, 0177777
|
||||
0177400+I_D+I_L, 0170000, 0177777, 0177777,
|
||||
0177000
|
||||
};
|
||||
|
||||
static const char *opcode[] = {
|
||||
@@ -443,7 +450,7 @@ static const int32 opc_val[] = {
|
||||
0007000+I_SOP, 0007200+I_SOP, 0007300+I_SOP,
|
||||
0010000+I_DOP, 0020000+I_DOP, 0030000+I_DOP, 0040000+I_DOP,
|
||||
0050000+I_DOP, 0060000+I_DOP,
|
||||
0070000+I_RSOP, 0071000+I_RSOP, 0072000+I_RSOP, 0073000+I_RSOP,
|
||||
0070000+I_SOPR, 0071000+I_SOPR, 0072000+I_SOPR, 0073000+I_SOPR,
|
||||
0074000+I_RSOP,
|
||||
0075000+I_REG, 0075010+I_REG, 0075020+I_REG, 0075030+I_REG,
|
||||
0076020+I_REG,
|
||||
@@ -662,7 +669,7 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
||||
case I_V_BR: /* cond branch */
|
||||
fprintf (of, "%s ", opcode[i]);
|
||||
brdisp = (l8b + l8b + ((l8b & 0200)? 0177002: 2)) & 0177777;
|
||||
if (cflag) fprintf (of, "%-o", (addr + brdisp) & 0177777);
|
||||
if (cflag) fprintf (of, "%-o", (addr + brdisp) & 0177777);
|
||||
else if (brdisp < 01000) fprintf (of, ".+%-o", brdisp);
|
||||
else fprintf (of, ".-%-o", 0200000 - brdisp);
|
||||
break;
|
||||
@@ -684,6 +691,12 @@ for (i = 0; opc_val[i] >= 0; i++) { /* loop thru ops */
|
||||
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
||||
break;
|
||||
|
||||
case I_V_SOPR: /* sopr */
|
||||
fprintf (of, "%s ", opcode[i]);
|
||||
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
||||
fprintf (of, ",%s", rname[srcr]);
|
||||
break;
|
||||
|
||||
case I_V_ASOP: case I_V_ASMD: /* asop, asmd */
|
||||
fprintf (of, "%s %s,", opcode[i], fname[fac]);
|
||||
wd1 = fprint_spec (of, addr, dstm, val[1], cflag, TRUE);
|
||||
@@ -987,13 +1000,23 @@ switch (j) { /* case on class */
|
||||
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
|
||||
if ((reg = get_reg (gbuf, rname, 0)) < 0) return SCPE_ARG;
|
||||
val[0] = val[0] | (reg << 6); /* fall through */
|
||||
case I_V_SOP: /* sop */
|
||||
case I_V_SOP: /* sop */
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
|
||||
if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1], cflag, TRUE)) > 0)
|
||||
return SCPE_ARG;
|
||||
val[0] = val[0] | spec;
|
||||
break;
|
||||
|
||||
case I_V_SOPR: /* dop, reg */
|
||||
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
|
||||
if ((n1 = get_spec (gbuf, addr, 0, &spec, &val[1], cflag, TRUE)) > 0)
|
||||
return SCPE_ARG;
|
||||
val[0] = val[0] | spec;
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
|
||||
if ((reg = get_reg (gbuf, rname, 0)) < 0) return SCPE_ARG;
|
||||
val[0] = val[0] | (reg << 6);
|
||||
break;
|
||||
|
||||
case I_V_AFOP: case I_V_ASOP: case I_V_ASMD: /* fac, (s)fop */
|
||||
cptr = get_glyph (cptr, gbuf, ','); /* get glyph */
|
||||
if ((reg = get_reg (gbuf, fname, 0)) < 0) return SCPE_ARG;
|
||||
|
||||
584
PDP11/pdp11_ta.c
Normal file
584
PDP11/pdp11_ta.c
Normal file
@@ -0,0 +1,584 @@
|
||||
/* pdp11_ta.c: PDP-11 cassette tape simulator
|
||||
|
||||
Copyright (c) 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"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ATAION OF CONTRATA, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNETAION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of Robert M Supnik shall not be
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
ta TA11/TU60 cassette tape
|
||||
|
||||
Magnetic tapes are represented as a series of variable records
|
||||
of the form:
|
||||
|
||||
32b byte count
|
||||
byte 0
|
||||
byte 1
|
||||
:
|
||||
byte n-2
|
||||
byte n-1
|
||||
32b byte count
|
||||
|
||||
If the byte count is odd, the record is padded with an extra byte
|
||||
of junk. File marks are represented by a byte count of 0.
|
||||
|
||||
Cassette format differs in one very significant way: it has file gaps
|
||||
rather than file marks. If the controller spaces or reads into a file
|
||||
gap and then reverses direction, the file gap is not seen again. This
|
||||
is in contrast to magnetic tapes, where the file mark is a character
|
||||
sequence and is seen again if direction is reversed.
|
||||
*/
|
||||
|
||||
#include "pdp11_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
#define TA_NUMDR 2 /* #drives */
|
||||
#define FNC u3 /* unit function */
|
||||
#define UST u4 /* unit status */
|
||||
#define TA_SIZE 93000 /* chars/tape */
|
||||
#define TA_MAXFR (TA_SIZE) /* max record lnt */
|
||||
|
||||
/* Control/status - TACS */
|
||||
|
||||
#define TACS_ERR (1 << CSR_V_ERR) /* error */
|
||||
#define TACS_CRC 0040000 /* CRC */
|
||||
#define TACS_BEOT 0020000 /* BOT/EOT */
|
||||
#define TACS_WLK 0010000 /* write lock */
|
||||
#define TACS_EOF 0004000 /* end file */
|
||||
#define TACS_TIM 0002000 /* timing */
|
||||
#define TACS_EMP 0001000 /* empty */
|
||||
#define TACS_V_UNIT 8 /* unit */
|
||||
#define TACS_M_UNIT (TA_NUMDR - 1)
|
||||
#define TACS_UNIT (TACS_M_UNIT << TACS_V_UNIT)
|
||||
#define TACS_TR (1 << CSR_V_DONE) /* transfer req */
|
||||
#define TACS_IE (1 << CSR_V_IE) /* interrupt enable */
|
||||
#define TACS_RDY 0000040 /* ready */
|
||||
#define TACS_ILBS 0000020 /* start CRC */
|
||||
#define TACS_V_FNC 1 /* function */
|
||||
#define TACS_M_FNC 07
|
||||
#define TACS_WFG 00
|
||||
#define TACS_WRITE 01
|
||||
#define TACS_READ 02
|
||||
#define TACS_SRF 03
|
||||
#define TACS_SRB 04
|
||||
#define TACS_SFF 05
|
||||
#define TACS_SFB 06
|
||||
#define TACS_REW 07
|
||||
#define TACS_2ND 010
|
||||
#define TACS_3RD 030
|
||||
#define TACS_FNC (TACS_M_FNC << TACS_V_FNC)
|
||||
#define TACS_GO (1 << CSR_V_GO) /* go */
|
||||
#define TACS_W (TACS_UNIT|TACS_IE|TACS_ILBS|TACS_FNC)
|
||||
#define TACS_XFRERR (TACS_ERR|TACS_CRC|TACS_WLK|TACS_EOF|TACS_TIM)
|
||||
#define GET_UNIT(x) (((x) >> TACS_V_UNIT) & TACS_M_UNIT)
|
||||
#define GET_FNC(x) (((x) >> TACS_V_FNC) & TACS_M_FNC)
|
||||
|
||||
/* Function code flags */
|
||||
|
||||
#define OP_WRI 01 /* op is a write */
|
||||
#define OP_REV 02 /* op is rev motion */
|
||||
#define OP_FWD 04 /* op is fwd motion */
|
||||
|
||||
/* Unit status flags */
|
||||
|
||||
#define UST_REV (OP_REV) /* last op was rev */
|
||||
#define UST_GAP 01 /* last op hit gap */
|
||||
|
||||
extern int32 int_req[IPL_HLVL];
|
||||
extern FILE *sim_deb;
|
||||
|
||||
uint32 ta_cs = 0; /* control/status */
|
||||
uint32 ta_idb = 0; /* input data buf */
|
||||
uint32 ta_odb = 0; /* output data buf */
|
||||
uint32 ta_write = 0; /* TU60 write flag */
|
||||
uint32 ta_bptr = 0; /* buf ptr */
|
||||
uint32 ta_blnt = 0; /* buf length */
|
||||
int32 ta_stime = 1000; /* start time */
|
||||
int32 ta_ctime = 100; /* char latency */
|
||||
uint32 ta_stopioe = 1; /* stop on error */
|
||||
uint8 *ta_xb = NULL; /* transfer buffer */
|
||||
static uint8 ta_fnc_tab[TACS_M_FNC + 1] = {
|
||||
OP_WRI|OP_FWD, OP_WRI|OP_FWD, OP_FWD, OP_REV,
|
||||
OP_REV , OP_FWD, OP_FWD, 0
|
||||
};
|
||||
|
||||
DEVICE ta_dev;
|
||||
t_stat ta_rd (int32 *data, int32 PA, int32 access);
|
||||
t_stat ta_wr (int32 data, int32 PA, int32 access);
|
||||
t_stat ta_svc (UNIT *uptr);
|
||||
t_stat ta_reset (DEVICE *dptr);
|
||||
t_stat ta_attach (UNIT *uptr, char *cptr);
|
||||
t_stat ta_detach (UNIT *uptr);
|
||||
void ta_go (void);
|
||||
t_stat ta_map_err (UNIT *uptr, t_stat st);
|
||||
UNIT *ta_busy (void);
|
||||
void ta_set_tr (void);
|
||||
uint32 ta_updsta (UNIT *uptr);
|
||||
uint32 ta_crc (uint8 *buf, uint32 cnt);
|
||||
|
||||
/* TA data structures
|
||||
|
||||
ta_dev TA device descriptor
|
||||
ta_unit TA unit list
|
||||
ta_reg TA register list
|
||||
ta_mod TA modifier list
|
||||
*/
|
||||
|
||||
DIB ta_dib = {
|
||||
IOBA_TA, IOLN_TA, &ta_rd, &ta_wr,
|
||||
1, IVCL (TA), VEC_TA, { NULL }
|
||||
};
|
||||
|
||||
UNIT ta_unit[] = {
|
||||
{ UDATA (&ta_svc, UNIT_ATTABLE+UNIT_ROABLE, TA_SIZE) },
|
||||
{ UDATA (&ta_svc, UNIT_ATTABLE+UNIT_ROABLE, TA_SIZE) },
|
||||
};
|
||||
|
||||
REG ta_reg[] = {
|
||||
{ ORDATA (TACS, ta_cs, 16) },
|
||||
{ ORDATA (TAIDB, ta_idb, 8) },
|
||||
{ ORDATA (TAODB, ta_odb, 8) },
|
||||
{ FLDATA (WRITE, ta_write, 0) },
|
||||
{ FLDATA (INT, IREQ (TA), INT_V_TA) },
|
||||
{ FLDATA (ERR, ta_cs, CSR_V_ERR) },
|
||||
{ FLDATA (TR, ta_cs, CSR_V_DONE) },
|
||||
{ FLDATA (IE, ta_cs, CSR_V_IE) },
|
||||
{ DRDATA (BPTR, ta_bptr, 17) },
|
||||
{ DRDATA (BLNT, ta_blnt, 17) },
|
||||
{ DRDATA (STIME, ta_stime, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (CTIME, ta_ctime, 24), PV_LEFT + REG_NZ },
|
||||
{ FLDATA (STOP_IOE, ta_stopioe, 0) },
|
||||
{ URDATA (UFNC, ta_unit[0].FNC, 8, 5, 0, TA_NUMDR, 0), REG_HRO },
|
||||
{ URDATA (UST, ta_unit[0].UST, 8, 2, 0, TA_NUMDR, 0), REG_HRO },
|
||||
{ URDATA (POS, ta_unit[0].pos, 10, T_ADDR_W, 0,
|
||||
TA_NUMDR, PV_LEFT | REG_RO) },
|
||||
{ ORDATA (DEVADDR, ta_dib.ba, 32), REG_HRO },
|
||||
{ ORDATA (DEVVEC, ta_dib.vec, 16), REG_HRO },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
MTAB ta_mod[] = {
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
// { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
// &sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", NULL,
|
||||
NULL, &sim_tape_show_capac, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, IOLN_TA, "ADDRESS", "ADDRESS",
|
||||
&set_addr, &show_addr, NULL },
|
||||
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
|
||||
&set_vec, &show_vec, NULL },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
DEVICE ta_dev = {
|
||||
"TA", ta_unit, ta_reg, ta_mod,
|
||||
TA_NUMDR, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &ta_reset,
|
||||
NULL, &ta_attach, &ta_detach,
|
||||
&ta_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG
|
||||
};
|
||||
|
||||
/* I/O dispatch routines, I/O addresses 17777500 - 17777503
|
||||
|
||||
17777500 TACS read/write
|
||||
17777502 TADB read/write
|
||||
*/
|
||||
|
||||
t_stat ta_rd (int32 *data, int32 PA, int32 access)
|
||||
{
|
||||
switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
|
||||
case 0: /* TACSR */
|
||||
*data = ta_updsta (NULL); /* update status */
|
||||
break;
|
||||
|
||||
case 1: /* TADB */
|
||||
*data = ta_idb; /* return byte */
|
||||
ta_cs &= ~TACS_TR; /* clear tra req */
|
||||
ta_updsta (NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat ta_wr (int32 data, int32 PA, int32 access)
|
||||
{
|
||||
switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
|
||||
case 0: /* TACS */
|
||||
if (access == WRITEB) data = (PA & 1)? /* byte write? */
|
||||
(ta_cs & 0377) | (data << 8): /* merge old */
|
||||
(ta_cs & ~0377) | data;
|
||||
ta_cs = (ta_cs & ~TACS_W) | (data & TACS_W); /* merge new */
|
||||
if ((data & CSR_GO) && !ta_busy ()) /* go, not busy? */
|
||||
ta_go (); /* start operation */
|
||||
if (ta_cs & TACS_ILBS) ta_cs &= ~TACS_TR; /* ILBS inhibits TR */
|
||||
break;
|
||||
|
||||
case 1: /* TADB */
|
||||
if (PA & 1) break; /* ignore odd byte */
|
||||
ta_odb = data; /* return byte */
|
||||
ta_cs &= ~TACS_TR; /* clear tra req */
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
ta_updsta (NULL); /* update status */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Start a new operation - cassette is not busy */
|
||||
|
||||
void ta_go (void)
|
||||
{
|
||||
UNIT *uptr = ta_dev.units + GET_UNIT (ta_cs);
|
||||
uint32 fnc = GET_FNC (ta_cs);
|
||||
uint32 flg = ta_fnc_tab[fnc];
|
||||
uint32 old_ust = uptr->UST;
|
||||
|
||||
if (DEBUG_PRS (ta_dev)) fprintf (sim_deb,
|
||||
">>TA start: op=%o, old_sta = %o, pos=%d\n",
|
||||
fnc, uptr->UST, uptr->pos);
|
||||
ta_cs &= ~(TACS_XFRERR|TACS_EMP|TACS_TR|TACS_RDY); /* clr err, tr, rdy */
|
||||
ta_bptr = 0; /* init buffer */
|
||||
ta_blnt = 0;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) {
|
||||
ta_cs |= TACS_ERR|TACS_EMP|TACS_RDY;
|
||||
return;
|
||||
}
|
||||
if (flg & OP_WRI) { /* write op? */
|
||||
if (sim_tape_wrp (uptr)) { /* locked? */
|
||||
ta_cs |= TACS_ERR|TACS_WLK|TACS_RDY; /* don't start */
|
||||
return;
|
||||
}
|
||||
ta_odb = 0;
|
||||
ta_write = 1;
|
||||
}
|
||||
else {
|
||||
ta_idb = 0;
|
||||
ta_write = 0;
|
||||
}
|
||||
ta_cs &= ~TACS_BEOT; /* tape in motion */
|
||||
uptr->FNC = fnc; /* save function */
|
||||
if ((fnc != TACS_REW) && !(flg & OP_WRI)) { /* read cmd? */
|
||||
uptr->UST = flg & UST_REV; /* save direction */
|
||||
if ((old_ust ^ uptr->UST) == (UST_REV|UST_GAP)) { /* reverse in gap? */
|
||||
t_mtrlnt t; /* skip file mark */
|
||||
if (uptr->UST) sim_tape_rdrecr (uptr, ta_xb, &t, TA_MAXFR);
|
||||
else sim_tape_rdrecf (uptr, ta_xb, &t, TA_MAXFR);
|
||||
if (DEBUG_PRS (ta_dev)) fprintf (sim_deb,
|
||||
">>TA skip gap: op=%o, old_sta = %o, pos=%d\n",
|
||||
fnc, uptr->UST, uptr->pos);
|
||||
}
|
||||
}
|
||||
else uptr->UST = 0;
|
||||
sim_activate (uptr, ta_stime); /* schedule op */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Unit service */
|
||||
|
||||
t_stat ta_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 i, crc;
|
||||
uint32 flg = ta_fnc_tab[uptr->FNC & TACS_M_FNC];
|
||||
t_mtrlnt tbc;
|
||||
t_stat st, r;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
ta_cs |= TACS_ERR|TACS_EMP|TACS_RDY;
|
||||
ta_updsta (uptr); /* update status */
|
||||
return (ta_stopioe? SCPE_UNATT: SCPE_OK);
|
||||
}
|
||||
if (((flg & OP_FWD) && sim_tape_eot (uptr)) || /* illegal motion? */
|
||||
((flg & OP_REV) && sim_tape_bot (uptr))) {
|
||||
ta_cs |= TACS_ERR|TACS_BEOT|TACS_RDY; /* error */
|
||||
ta_updsta (uptr);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
r = SCPE_OK;
|
||||
switch (uptr->FNC) { /* case on function */
|
||||
|
||||
case TACS_READ: /* read start */
|
||||
st = sim_tape_rdrecf (uptr, ta_xb, &ta_blnt, TA_MAXFR); /* get rec */
|
||||
if (st == MTSE_RECE) ta_cs |= TACS_ERR|TACS_CRC; /* rec in err? */
|
||||
else if (st != MTSE_OK) { /* other error? */
|
||||
r = ta_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
}
|
||||
crc = ta_crc (ta_xb, ta_blnt); /* calculate CRC */
|
||||
ta_xb[ta_blnt++] = (crc >> 8) & 0377; /* append to buffer */
|
||||
ta_xb[ta_blnt++] = crc & 0377;
|
||||
uptr->FNC |= TACS_2ND; /* next state */
|
||||
sim_activate (uptr, ta_ctime); /* sched next char */
|
||||
return SCPE_OK;
|
||||
|
||||
case TACS_READ|TACS_2ND: /* read char */
|
||||
if (ta_bptr < ta_blnt) /* more chars? */
|
||||
ta_idb = ta_xb[ta_bptr++];
|
||||
else { /* no */
|
||||
ta_idb = 0;
|
||||
ta_cs |= TACS_ERR|TACS_CRC; /* overrun */
|
||||
break; /* tape stops */
|
||||
}
|
||||
if (ta_cs & TACS_ILBS) { /* CRC seq? */
|
||||
uptr->FNC |= TACS_3RD; /* next state */
|
||||
sim_activate (uptr, ta_stime); /* sched CRC chk */
|
||||
}
|
||||
else {
|
||||
ta_set_tr (); /* set tra req */
|
||||
sim_activate (uptr, ta_ctime); /* sched next char */
|
||||
}
|
||||
return SCPE_OK;
|
||||
|
||||
case TACS_READ|TACS_3RD: /* second read CRC */
|
||||
if (ta_bptr != ta_blnt) { /* partial read? */
|
||||
crc = ta_crc (ta_xb, ta_bptr + 2); /* actual CRC */
|
||||
if (crc != 0) ta_cs |= TACS_ERR|TACS_CRC; /* must be zero */
|
||||
}
|
||||
break; /* read done */
|
||||
|
||||
case TACS_WRITE: /* write start */
|
||||
for (i = 0; i < TA_MAXFR; i++) ta_xb[i] = 0; /* clear buffer */
|
||||
ta_set_tr (); /* set tra req */
|
||||
uptr->FNC |= TACS_2ND; /* next state */
|
||||
sim_activate (uptr, ta_ctime); /* sched next char */
|
||||
return SCPE_OK;
|
||||
|
||||
case TACS_WRITE|TACS_2ND: /* write char */
|
||||
if (ta_cs & TACS_ILBS) { /* CRC seq? */
|
||||
uptr->FNC |= TACS_3RD; /* next state */
|
||||
sim_activate (uptr, ta_stime); /* sched wri done */
|
||||
}
|
||||
else {
|
||||
if ((ta_bptr < TA_MAXFR) && /* room in buf? */
|
||||
((uptr->pos + ta_bptr) < uptr->capac)) /* room on tape? */
|
||||
ta_xb[ta_bptr++] = ta_odb; /* store char */
|
||||
ta_set_tr (); /* set tra req */
|
||||
sim_activate (uptr, ta_ctime); /* sched next char */
|
||||
}
|
||||
return SCPE_OK;
|
||||
|
||||
case TACS_WRITE|TACS_3RD: /* write CRC */
|
||||
if (ta_bptr) { /* anything to write? */
|
||||
if (st = sim_tape_wrrecf (uptr, ta_xb, ta_bptr)) /* write, err? */
|
||||
r = ta_map_err (uptr, st); /* map error */
|
||||
}
|
||||
break; /* op done */
|
||||
|
||||
case TACS_WFG: /* write file gap */
|
||||
if (st = sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||
r = ta_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
|
||||
case TACS_REW: /* rewind */
|
||||
sim_tape_rewind (uptr);
|
||||
ta_cs |= TACS_BEOT; /* bot, no error */
|
||||
break;
|
||||
|
||||
case TACS_SRB: /* space rev blk */
|
||||
if (st = sim_tape_sprecr (uptr, &tbc)) /* space rev, err? */
|
||||
r = ta_map_err (uptr, st); /* map error */
|
||||
break;
|
||||
|
||||
case TACS_SRF: /* space rev file */
|
||||
while ((st = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ;
|
||||
if (st == MTSE_TMK) /* if tape mark, */
|
||||
ta_cs |= TACS_EOF; /* set EOF, no err */
|
||||
else r = ta_map_err (uptr, st); /* else map error */
|
||||
break;
|
||||
|
||||
case TACS_SFB: /* space fwd blk */
|
||||
if (st = sim_tape_sprecf (uptr, &tbc)) /* space rev, err? */
|
||||
r = ta_map_err (uptr, st); /* map error */
|
||||
ta_cs |= TACS_CRC; /* CRC sets, no err */
|
||||
break;
|
||||
|
||||
case TACS_SFF: /* space fwd file */
|
||||
while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ;
|
||||
if (st == MTSE_TMK) /* if tape mark, */
|
||||
ta_cs |= TACS_EOF; /* set EOF, no err */
|
||||
else r = ta_map_err (uptr, st); /* else map error */
|
||||
break;
|
||||
|
||||
default: /* never get here! */
|
||||
return SCPE_IERR;
|
||||
} /* end case */
|
||||
|
||||
ta_cs |= TACS_RDY; /* set ready */
|
||||
ta_updsta (uptr); /* update status */
|
||||
if (DEBUG_PRS (ta_dev)) fprintf (sim_deb,
|
||||
">>TA done: op=%o, status = %o, pos=%d\n",
|
||||
uptr->FNC, ta_cs, uptr->pos);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Update controller status */
|
||||
|
||||
uint32 ta_updsta (UNIT *uptr)
|
||||
{
|
||||
if (uptr == NULL) { /* unit specified? */
|
||||
if ((uptr = ta_busy ()) == NULL) /* use busy */
|
||||
uptr = ta_dev.units + GET_UNIT (ta_cs); /* use sel unit */
|
||||
}
|
||||
else if (ta_cs & TACS_EOF) uptr->UST |= UST_GAP; /* save EOF */
|
||||
if (uptr->flags & UNIT_ATT) ta_cs &= ~TACS_EMP; /* attached? */
|
||||
else ta_cs |= TACS_EMP|TACS_RDY; /* no, empty, ready */
|
||||
if ((ta_cs & TACS_IE) && /* int enabled? */
|
||||
(ta_cs & (TACS_TR|TACS_RDY))) /* req or ready? */
|
||||
SET_INT (TA); /* set int req */
|
||||
else CLR_INT (TA); /* no, clr int req */
|
||||
return ta_cs;
|
||||
}
|
||||
|
||||
/* Set transfer request */
|
||||
|
||||
void ta_set_tr (void)
|
||||
{
|
||||
if (ta_cs & TACS_TR) ta_cs |= (TACS_ERR|TACS_TIM); /* flag still set? */
|
||||
else ta_cs |= TACS_TR; /* set xfr req */
|
||||
if (ta_cs & TACS_IE) SET_INT (TA); /* if ie, int req */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Test if controller busy */
|
||||
|
||||
UNIT *ta_busy (void)
|
||||
{
|
||||
uint32 u;
|
||||
UNIT *uptr;
|
||||
|
||||
for (u = 0; u < TA_NUMDR; u++) { /* loop thru units */
|
||||
uptr = ta_dev.units + u;
|
||||
if (sim_is_active (uptr)) return uptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Calculate CRC on buffer */
|
||||
|
||||
uint32 ta_crc (uint8 *buf, uint32 cnt)
|
||||
{
|
||||
uint32 crc, i, j;
|
||||
|
||||
crc = 0;
|
||||
for (i = 0; i < cnt; i++) {
|
||||
crc = crc ^ (((uint32) buf[i]) << 8);
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (crc & 1) crc = (crc >> 1) ^ 0xA001;
|
||||
else crc = crc >> 1;
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/* Map error status */
|
||||
|
||||
t_stat ta_map_err (UNIT *uptr, t_stat st)
|
||||
{
|
||||
switch (st) {
|
||||
|
||||
case MTSE_FMT: /* illegal fmt */
|
||||
case MTSE_UNATT: /* unattached */
|
||||
ta_cs |= TACS_ERR|TACS_CRC;
|
||||
case MTSE_OK: /* no error */
|
||||
return SCPE_IERR; /* never get here! */
|
||||
|
||||
case MTSE_TMK: /* end of file */
|
||||
ta_cs |= TACS_ERR|TACS_EOF;
|
||||
break;
|
||||
|
||||
case MTSE_IOERR: /* IO error */
|
||||
ta_cs |= TACS_ERR|TACS_CRC; /* set crc err */
|
||||
if (ta_stopioe) return SCPE_IOERR;
|
||||
break;
|
||||
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
ta_cs |= TACS_ERR|TACS_CRC; /* set crc err */
|
||||
return SCPE_MTRLNT;
|
||||
|
||||
case MTSE_RECE: /* record in error */
|
||||
case MTSE_EOM: /* end of medium */
|
||||
ta_cs |= TACS_ERR|TACS_CRC; /* set crc err */
|
||||
break;
|
||||
|
||||
case MTSE_BOT: /* reverse into BOT */
|
||||
ta_cs |= TACS_ERR|TACS_BEOT; /* set bot */
|
||||
break;
|
||||
|
||||
case MTSE_WRP: /* write protect */
|
||||
ta_cs |= TACS_ERR|TACS_WLK; /* set wlk err */
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Reset routine */
|
||||
|
||||
t_stat ta_reset (DEVICE *dptr)
|
||||
{
|
||||
uint32 u;
|
||||
UNIT *uptr;
|
||||
|
||||
ta_cs = 0;
|
||||
ta_idb = 0;
|
||||
ta_odb = 0;
|
||||
ta_write = 0;
|
||||
ta_bptr = 0;
|
||||
ta_blnt = 0;
|
||||
CLR_INT (TA); /* clear interrupt */
|
||||
for (u = 0; u < TA_NUMDR; u++) { /* loop thru units */
|
||||
uptr = ta_dev.units + u;
|
||||
sim_cancel (uptr); /* cancel activity */
|
||||
sim_tape_reset (uptr); /* reset tape */
|
||||
}
|
||||
if (ta_xb == NULL) ta_xb = (uint8 *) calloc (TA_MAXFR + 2, sizeof (uint8));
|
||||
if (ta_xb == NULL) return SCPE_MEM;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Attach routine */
|
||||
|
||||
t_stat ta_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
r = sim_tape_attach (uptr, cptr);
|
||||
if (r != SCPE_OK) return r;
|
||||
ta_updsta (NULL);
|
||||
uptr->UST = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Detach routine */
|
||||
|
||||
t_stat ta_detach (UNIT* uptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* check attached */
|
||||
r = sim_tape_detach (uptr);
|
||||
ta_updsta (NULL);
|
||||
uptr->UST = 0;
|
||||
return r;
|
||||
}
|
||||
@@ -640,7 +640,7 @@ switch (fnc) { /* case function */
|
||||
|
||||
case DTS_OFR: /* off reel */
|
||||
if (dir) newpos = -1000; /* rev? < start */
|
||||
else newpos = DTU_FWDEZ (uptr) + DT_EZLIN + 1000; /* fwd? > end */
|
||||
else newpos = DTU_FWDEZ (uptr) + DT_EZLIN + 1000; /* fwd? > end */
|
||||
break;
|
||||
|
||||
case FNC_SRCH: /* search */
|
||||
@@ -811,7 +811,7 @@ switch (mot) {
|
||||
return IORETURN (dt_stopoffr, STOP_DTOFF);
|
||||
uptr->STATE = DTS_NXTSTA (uptr->STATE); /* advance state */
|
||||
if (uptr->STATE) /* not stopped? */
|
||||
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* reversing */
|
||||
sim_activate (uptr, dt_dctime - (dt_dctime >> 2)); /* reversing */
|
||||
return SCPE_OK;
|
||||
|
||||
case DTS_ACCF: case DTS_ACCR: /* accelerating */
|
||||
@@ -1061,9 +1061,9 @@ int32 wrd = relpos / DT_WSIZE;
|
||||
|
||||
if (wrd == DT_BLKWD) return blk; /* fwd blknum */
|
||||
if (wrd == DT_CSMWD) return 077; /* rev csum */
|
||||
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
|
||||
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_CSMWD - 1)) /* fwd csum */
|
||||
return (dt_csum (uptr, blk) << 12);
|
||||
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_BLKWD - 1)) /* rev blkno */
|
||||
if (wrd == (2 * DT_HTWRD + DTU_BSIZE (uptr) - DT_BLKWD - 1)) /* rev blkno */
|
||||
return dt_comobv (blk);
|
||||
return 0; /* all others */
|
||||
}
|
||||
@@ -1107,43 +1107,43 @@ return SCPE_OK;
|
||||
#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16))
|
||||
|
||||
static const uint16 boot_rom[] = {
|
||||
0042124, /* "TD" */
|
||||
0012706, BOOT_START, /* MOV #boot_start, SP */
|
||||
0012700, 0000000, /* MOV #unit, R0 ; unit number */
|
||||
0010003, /* MOV R0, R3 */
|
||||
0000303, /* SWAB R3 */
|
||||
0012701, 0177342, /* MOV #TCCM, R1 ; csr */
|
||||
0012702, 0004003, /* RW: MOV #4003, R2 ; rev+rnum+go */
|
||||
0050302, /* BIS R3, R2 */
|
||||
0010211, /* MOV R2, (R1) ; load csr */
|
||||
0032711, 0100200, /* BIT #100200, (R1) ; wait */
|
||||
0001775, /* BEQ .-4 */
|
||||
0100370, /* BPL RW ; no err, cont */
|
||||
0005761, 0177776, /* TST -2(R1) ; end zone? */
|
||||
0100036, /* BPL ER ; no, err */
|
||||
0012702, 0000003, /* MOV #3, R2 ; rnum+go */
|
||||
0050302, /* BIS R3, R2 */
|
||||
0010211, /* MOV R2, (R1) ; load csr */
|
||||
0032711, 0100200, /* BIT #100200, (R1) ; wait */
|
||||
0001775, /* BEQ .-4 */
|
||||
0100426, /* BMI ER ; err, die */
|
||||
0005761, 0000006, /* TST 6(R1) ; blk 0? */
|
||||
0001023, /* BNE ER ; no, die */
|
||||
0012761, 0177000, 0000002, /* MOV #-256.*2, 2(R1) ; load wc */
|
||||
0005061, 0000004, /* CLR 4(R1) ; clear ba */
|
||||
0012702, 0000005, /* MOV #READ+GO, R2 ; read & go */
|
||||
0050302, /* BIS R3, R2 */
|
||||
0010211, /* MOV R2, (R1) ; load csr */
|
||||
0005002, /* CLR R2 */
|
||||
0005003, /* CLR R3 */
|
||||
0012704, BOOT_START+020, /* MOV #START+20, R4 */
|
||||
0005005, /* CLR R5 */
|
||||
0032711, 0100200, /* BIT #100200, (R1) ; wait */
|
||||
0001775, /* BEQ .-4 */
|
||||
0100401, /* BMI ER ; err, die */
|
||||
0005007, /* CLR PC */
|
||||
0012711, 0000001, /* ER: MOV #1, (R1) ; stop all */
|
||||
0000000 /* HALT */
|
||||
0042124, /* "TD" */
|
||||
0012706, BOOT_START, /* MOV #boot_start, SP */
|
||||
0012700, 0000000, /* MOV #unit, R0 ; unit number */
|
||||
0010003, /* MOV R0, R3 */
|
||||
0000303, /* SWAB R3 */
|
||||
0012701, 0177342, /* MOV #TCCM, R1 ; csr */
|
||||
0012702, 0004003, /* RW: MOV #4003, R2 ; rev+rnum+go */
|
||||
0050302, /* BIS R3, R2 */
|
||||
0010211, /* MOV R2, (R1) ; load csr */
|
||||
0032711, 0100200, /* BIT #100200, (R1) ; wait */
|
||||
0001775, /* BEQ .-4 */
|
||||
0100370, /* BPL RW ; no err, cont */
|
||||
0005761, 0177776, /* TST -2(R1) ; end zone? */
|
||||
0100036, /* BPL ER ; no, err */
|
||||
0012702, 0000003, /* MOV #3, R2 ; rnum+go */
|
||||
0050302, /* BIS R3, R2 */
|
||||
0010211, /* MOV R2, (R1) ; load csr */
|
||||
0032711, 0100200, /* BIT #100200, (R1) ; wait */
|
||||
0001775, /* BEQ .-4 */
|
||||
0100426, /* BMI ER ; err, die */
|
||||
0005761, 0000006, /* TST 6(R1) ; blk 0? */
|
||||
0001023, /* BNE ER ; no, die */
|
||||
0012761, 0177000, 0000002, /* MOV #-256.*2, 2(R1) ; load wc */
|
||||
0005061, 0000004, /* CLR 4(R1) ; clear ba */
|
||||
0012702, 0000005, /* MOV #READ+GO, R2 ; read & go */
|
||||
0050302, /* BIS R3, R2 */
|
||||
0010211, /* MOV R2, (R1) ; load csr */
|
||||
0005002, /* CLR R2 */
|
||||
0005003, /* CLR R3 */
|
||||
0012704, BOOT_START+020, /* MOV #START+20, R4 */
|
||||
0005005, /* CLR R5 */
|
||||
0032711, 0100200, /* BIT #100200, (R1) ; wait */
|
||||
0001775, /* BEQ .-4 */
|
||||
0100401, /* BMI ER ; err, die */
|
||||
0005007, /* CLR PC */
|
||||
0012711, 0000001, /* ER: MOV #1, (R1) ; stop all */
|
||||
0000000 /* HALT */
|
||||
};
|
||||
|
||||
t_stat dt_boot (int32 unitno, DEVICE *dptr)
|
||||
@@ -1179,7 +1179,7 @@ t_stat r;
|
||||
r = attach_unit (uptr, cptr); /* attach */
|
||||
if (r != SCPE_OK) return r; /* fail? */
|
||||
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
|
||||
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; /* default 16b */
|
||||
uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; /* default 16b */
|
||||
if (sim_switches & SWMASK ('T')) /* att 12b? */
|
||||
uptr->flags = (uptr->flags | UNIT_8FMT) & ~UNIT_11FMT;
|
||||
else if (sim_switches & SWMASK ('F')) /* att 18b? */
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
#define MTC_FNC (MTC_M_FNC << MTC_V_FNC)
|
||||
#define MTC_GO (1 << CSR_V_GO) /* go */
|
||||
#define MTC_RW (MTC_DEN | MTC_LPAR | MTC_UNIT | MTC_IE | \
|
||||
MTC_EMA | MTC_FNC)
|
||||
MTC_EMA | MTC_FNC)
|
||||
#define GET_EMA(x) (((x) & MTC_EMA) << (16 - MTC_V_EMA))
|
||||
#define GET_UNIT(x) (((x) >> MTC_V_UNIT) & MTC_M_UNIT)
|
||||
#define GET_FNC(x) (((x) >> MTC_V_FNC) & MTC_M_FNC)
|
||||
@@ -422,7 +422,7 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* if not attached */
|
||||
}
|
||||
|
||||
if (DEBUG_PRS (tm_dev)) fprintf (sim_deb,
|
||||
">>TM: op=%o, ma=%o, bc=%o, pos=%d\n", f, xma, cbc, uptr->pos);
|
||||
">>TM: op=%o, ma=%o, bc=%o, pos=%d\n", f, xma, tm_bc, uptr->pos);
|
||||
switch (f) { /* case on function */
|
||||
|
||||
case MTC_READ: /* read */
|
||||
@@ -488,7 +488,7 @@ tm_ca = xma & 0177777; /* update mem addr */
|
||||
tm_set_done (); /* set done */
|
||||
tm_updcsta (uptr); /* update status */
|
||||
if (DEBUG_PRS (tm_dev)) fprintf (sim_deb,
|
||||
">>TM: sta=%o, ma=%o, wc=%o, pos=%d\n",
|
||||
">>TM: sta=%o, ma=%o, bc=%o, pos=%d\n",
|
||||
tm_sta, tm_ca, tm_bc, uptr->pos);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ switch (fnc) { /* case on function */
|
||||
else tutc = tutc & ~TC_FCS;
|
||||
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 (drv, st, 0); /* map error */
|
||||
break;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* pdp11_vh.c: DHQ11 asynchronous terminal multiplexor simulator
|
||||
|
||||
Copyright (c) 2004-2005, John A. Dundas III
|
||||
Copyright (c) 2004-2006, John A. Dundas III
|
||||
Portions derived from work by Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
vh DHQ11 asynch multiplexor for SIMH
|
||||
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
07-Jul-05 RMS Removed extraneous externs
|
||||
15-Jun-05 RMS Revised for new autoconfigure interface
|
||||
Fixed bug in vector display routine
|
||||
@@ -382,7 +383,7 @@ DEVICE vh_dev = {
|
||||
&vh_attach, /* attach routine */
|
||||
&vh_detach, /* detach routine */
|
||||
(void *)&vh_dib, /* context */
|
||||
DEV_FLTA | DEV_DISABLE | DEV_NET | DEV_QBUS | DEV_UBUS, /* flags */
|
||||
DEV_FLTA | DEV_DISABLE | DEV_DIS |DEV_NET | DEV_QBUS | DEV_UBUS, /* flags */
|
||||
};
|
||||
|
||||
/* Interrupt routines */
|
||||
@@ -791,7 +792,7 @@ static t_stat vh_wr ( int32 data,
|
||||
if (data & CSR_MASTER_RESET) {
|
||||
if ((vh_unit[vh].flags & UNIT_MODEDHU) && (data & CSR_SKIP))
|
||||
data &= ~CSR_MASTER_RESET;
|
||||
sim_activate (&vh_unit[vh], tmxr_poll);
|
||||
sim_activate (&vh_unit[vh], clk_cosched (tmxr_poll));
|
||||
/* vh_mcount[vh] = 72; */ /* 1.2 seconds */
|
||||
vh_mcount[vh] = MS2SIMH (1200); /* 1.2 seconds */
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
27-Jan-06 RMS Fixed unaligned accesses in XQB (found by Doug Carman)
|
||||
07-Jan-06 RMS Fixed unaligned access bugs (found by Doug Carman)
|
||||
07-Sep-05 DTH Removed unused variable
|
||||
@@ -209,7 +210,7 @@
|
||||
#include "pdp11_xq.h"
|
||||
#include "pdp11_xq_bootrom.h"
|
||||
|
||||
extern int32 tmr_poll, clk_tps;
|
||||
extern int32 tmxr_poll;
|
||||
extern FILE* sim_deb;
|
||||
extern char* read_line (char *ptr, int32 size, FILE *stream);
|
||||
|
||||
@@ -1621,7 +1622,7 @@ t_stat xq_wr_csr(CTLR* xq, int32 data)
|
||||
/* start/stop receive timer when RE transitions */
|
||||
if ((xq->var->csr ^ data) & XQ_CSR_RE) {
|
||||
if (data & XQ_CSR_RE)
|
||||
sim_activate(&xq->unit[0], (clk_tps * tmr_poll)/xq->var->poll);
|
||||
sim_activate(&xq->unit[0], clock_cosched (tmxr_poll));
|
||||
else
|
||||
sim_cancel(&xq->unit[0]);
|
||||
}
|
||||
@@ -1682,8 +1683,6 @@ t_stat xq_reset(DEVICE* dptr)
|
||||
t_stat status;
|
||||
CTLR* xq = xq_dev2ctlr(dptr);
|
||||
const uint16 set_bits = XQ_CSR_RL | XQ_CSR_XL;
|
||||
/* must be recalculated each time since tmr_poll is a dynamic number */
|
||||
const int32 one_second = clk_tps * tmr_poll;
|
||||
|
||||
sim_debug(DBG_TRC, xq->dev, "xq_reset()\n");
|
||||
|
||||
@@ -1721,7 +1720,7 @@ t_stat xq_reset(DEVICE* dptr)
|
||||
xq_csr_set_clr(xq, XQ_CSR_OK, 0);
|
||||
|
||||
/* start service timer */
|
||||
sim_activate(&xq->unit[0], one_second/xq->var->poll);
|
||||
sim_activate_abs(&xq->unit[0], tmxr_poll);
|
||||
}
|
||||
|
||||
/* set hardware sanity controls */
|
||||
@@ -1826,9 +1825,6 @@ t_stat xq_svc(UNIT* uptr)
|
||||
{
|
||||
CTLR* xq = xq_unit2ctlr(uptr);
|
||||
|
||||
/* must be recalculated each time since tmr_poll is a dynamic number */
|
||||
const int32 one_second = clk_tps * tmr_poll;
|
||||
|
||||
/* if the receiver is enabled */
|
||||
if (xq->var->csr & XQ_CSR_RE) {
|
||||
t_stat status;
|
||||
@@ -1867,7 +1863,7 @@ t_stat xq_svc(UNIT* uptr)
|
||||
}
|
||||
|
||||
/* resubmit service timer */
|
||||
sim_activate(&xq->unit[0], one_second/xq->var->poll);
|
||||
sim_activate(&xq->unit[0], tmxr_poll);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* pdp11_xu.c: DEUNA/DELUA ethernet controller simulator
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2003-2005, David T. Hittner
|
||||
Copyright (c) 2003-2006, David T. Hittner
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -57,6 +57,7 @@
|
||||
|
||||
Modification history:
|
||||
|
||||
29-Oct-06 RMS Synced poll and clock
|
||||
08-Dec-05 DTH Implemented ancilliary functions 022/023/024/025
|
||||
18-Nov-05 DTH Corrected time between system ID packets
|
||||
07-Sep-05 DTH Corrected runt packet processing (found by Tim Chapman),
|
||||
@@ -83,7 +84,7 @@
|
||||
|
||||
#include "pdp11_xu.h"
|
||||
|
||||
extern int32 tmr_poll, clk_tps, cpu_astop;
|
||||
extern int32 tmxr_poll, tmr_poll, clk_tps, cpu_astop;
|
||||
extern FILE *sim_log;
|
||||
|
||||
t_stat xu_rd(int32* data, int32 PA, int32 access);
|
||||
@@ -449,8 +450,8 @@ t_stat xu_svc(UNIT* uptr)
|
||||
int queue_size;
|
||||
t_stat status;
|
||||
CTLR* xu = xu_unit2ctlr(uptr);
|
||||
const int one_second = clk_tps * tmr_poll; /* recalibrate timer */
|
||||
const ETH_MAC mop_multicast = {0xAB, 0x00, 0x00, 0x02, 0x00, 0x00};
|
||||
const int one_second = clk_tps * tmr_poll;
|
||||
|
||||
/* First pump any queued packets into the system */
|
||||
if ((xu->var->ReadQ.count > 0) && ((xu->var->pcsr1 & PCSR1_STATE) == STATE_RUNNING))
|
||||
@@ -486,7 +487,7 @@ t_stat xu_svc(UNIT* uptr)
|
||||
switch (xu->var->pcsr1 & PCSR1_STATE) {
|
||||
case STATE_READY:
|
||||
case STATE_RUNNING:
|
||||
sim_activate(&xu->unit[0], one_second/XU_SERVICE_INTERVAL);
|
||||
sim_activate(&xu->unit[0], tmxr_poll);
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -522,7 +523,6 @@ void xu_setclrint(CTLR* xu, int32 bits)
|
||||
t_stat xu_sw_reset (CTLR* xu)
|
||||
{
|
||||
t_stat status;
|
||||
const int one_second = clk_tps * tmr_poll; /* recalibrate timer */
|
||||
|
||||
sim_debug(DBG_TRC, xu->dev, "xu_sw_reset()\n");
|
||||
|
||||
@@ -564,10 +564,9 @@ t_stat xu_sw_reset (CTLR* xu)
|
||||
&xu->var->mac, xu->var->setup.multicast,
|
||||
xu->var->setup.promiscuous);
|
||||
|
||||
/* activate device if not disabled - cancel first, just in case */
|
||||
/* activate device if not disabled */
|
||||
if ((xu->dev->flags & DEV_DIS) == 0) {
|
||||
sim_cancel(&xu->unit[0]);
|
||||
sim_activate(&xu->unit[0], one_second/XU_SERVICE_INTERVAL);
|
||||
sim_activate_abs(&xu->unit[0], clk_cosched (tmxr_poll));
|
||||
}
|
||||
|
||||
/* clear load_server address */
|
||||
@@ -727,9 +726,9 @@ sim_debug(DBG_TRC, xu->dev, "FC_WAL: mtlen=%d\n", mtlen);
|
||||
xu->var->rrlen = xu->var->udb[5];
|
||||
xu->var->rxnext = 0;
|
||||
xu->var->txnext = 0;
|
||||
xu_dump_rxring(xu);
|
||||
xu_dump_txring(xu);
|
||||
/*cpu_astop=1;*/
|
||||
// xu_dump_rxring(xu);
|
||||
// xu_dump_txring(xu);
|
||||
|
||||
break;
|
||||
|
||||
case FC_RDCTR: /* read counters */
|
||||
@@ -1072,7 +1071,7 @@ void xu_process_receive(CTLR* xu)
|
||||
|
||||
/* set or clear interrupt, depending on what happened */
|
||||
xu_setclrint(xu, 0);
|
||||
xu_dump_rxring(xu); /* debug receive ring */
|
||||
// xu_dump_rxring(xu); /* debug receive ring */
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user