mirror of
https://github.com/simh/simh.git
synced 2026-04-16 00:21:35 +00:00
HP2100: HP 2100 release 26
See HP2100/hp2100_release.txt for details of the release
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
HP 2100 SIMULATOR FIXES
|
HP 2100 SIMULATOR FIX ARCHIVE
|
||||||
=======================
|
=============================
|
||||||
Last update: 2016-08-05
|
Final update: 2016-08-05
|
||||||
|
|
||||||
|
See the "SIMH/HP 2100 Release Notes" file for bug fixes implemented after the
|
||||||
|
date above.
|
||||||
|
|
||||||
|
|
||||||
1. PROBLEM: Booting from magnetic tape reports "HALT instruction, P: 77756
|
1. PROBLEM: Booting from magnetic tape reports "HALT instruction, P: 77756
|
||||||
|
|||||||
@@ -1,30 +1,33 @@
|
|||||||
/* hp2100_cpu1.c: HP 2100/1000 EAU simulator and UIG dispatcher
|
/* hp2100_cpu1.c: HP 2100/1000 EAU simulator and UIG dispatcher
|
||||||
|
|
||||||
Copyright (c) 2005-2016, Robert M. Supnik
|
Copyright (c) 2005-2016, Robert M. Supnik
|
||||||
|
Copyright (c) 2017 J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
copy of this software and associated documentation files (the "Software"),
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
to deal in the Software without restriction, including without limitation
|
in the Software without restriction, including without limitation the rights
|
||||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
and/or sell copies of the Software, and to permit persons to whom the
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
Software is furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
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
|
Except as contained in this notice, the names of the authors shall not be
|
||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from the authors.
|
||||||
|
|
||||||
CPU1 Extended arithmetic and optional microcode dispatchers
|
CPU1 Extended arithmetic and optional microcode dispatchers
|
||||||
|
|
||||||
|
22-Apr-17 JDB Improved the EAU shift/rotate instructions
|
||||||
|
21-Mar-17 JDB Fixed UIG 1 comment regarding 2000 IOP and F-Series
|
||||||
05-Aug-16 JDB Renamed the P register from "PC" to "PR"
|
05-Aug-16 JDB Renamed the P register from "PC" to "PR"
|
||||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||||
05-Apr-14 JDB Corrected typo in comments for cpu_ops
|
05-Apr-14 JDB Corrected typo in comments for cpu_ops
|
||||||
@@ -172,173 +175,249 @@
|
|||||||
EXECUTE (100120), is also described but was never implemented, and the
|
EXECUTE (100120), is also described but was never implemented, and the
|
||||||
E/F-series microcode execute a NOP for this instruction code.
|
E/F-series microcode execute a NOP for this instruction code.
|
||||||
|
|
||||||
Notes:
|
|
||||||
|
|
||||||
1. Under simulation, TIMER, DIAG, and EXECUTE cause undefined instruction
|
Implementation notes:
|
||||||
stops if the CPU is set to 21xx. DIAG and EXECUTE also cause stops on
|
|
||||||
the 1000-M. TIMER does not, because it is used by several HP programs
|
|
||||||
to differentiate between M- and E/F-series machines.
|
|
||||||
|
|
||||||
2. DIAG is not implemented under simulation. On the E/F, it performs a
|
1. Under simulation, TIMER, DIAG, and EXECUTE cause undefined instruction
|
||||||
destructive test of all installed memory. Because of this, it is only
|
stops if the CPU is set to 21xx. DIAG and EXECUTE also cause stops on
|
||||||
functional if the machine is halted, i.e., if the instruction is
|
the 1000-M. TIMER does not, because it is used by several HP programs
|
||||||
executed with the INSTR STEP button. If it is executed in a program,
|
to differentiate between M- and E/F-series machines.
|
||||||
the result is NOP.
|
|
||||||
|
|
||||||
3. RRR is permitted and executed as NOP if the CPU is a 2114, as the
|
2. DIAG is not implemented under simulation. On the E/F, it performs a
|
||||||
presence of the EAU is tested by the diagnostic configurator to
|
destructive test of all installed memory. Because of this, it is only
|
||||||
differentiate between 2114 and 2100/1000 CPUs.
|
functional if the machine is halted, i.e., if the instruction is
|
||||||
|
executed with the INSTR STEP button. If it is executed in a program,
|
||||||
|
the result is NOP.
|
||||||
|
|
||||||
|
3. RRR is permitted and executed as NOP if the CPU is a 2114, as the
|
||||||
|
presence of the EAU is tested by the diagnostic configurator to
|
||||||
|
differentiate between 2114 and 2100/1000 CPUs.
|
||||||
|
|
||||||
|
4. The shift count is calculated unconditionally, as six of the ten
|
||||||
|
instructions will be using the value.
|
||||||
|
|
||||||
|
5. An arithmetic left shift must be handled as a special case because the
|
||||||
|
shifted operand bits "skip over" the sign bit. That is, the bits are
|
||||||
|
lost from the next-most-significant bit while preserving the MSB. For
|
||||||
|
all other shifts, including the arithmetic right shift, the operand may
|
||||||
|
be shifted and then merged with the appropriate fill bits.
|
||||||
|
|
||||||
|
6. The C standard specifies that the results of bitwise shifts with negative
|
||||||
|
signed operands are undefined (for left shifts) or implementation-defined
|
||||||
|
(for right shifts). Therefore, we must use unsigned operands and handle
|
||||||
|
arithmetic shifts explicitly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
t_stat cpu_eau (uint32 IR, uint32 intrq)
|
t_stat cpu_eau (uint32 IR, uint32 intrq)
|
||||||
{
|
{
|
||||||
t_stat reason = SCPE_OK;
|
t_stat reason = SCPE_OK;
|
||||||
OPS op;
|
OPS op;
|
||||||
uint32 rs, qs, sc, v1, v2, t;
|
uint32 rs, qs, v1, v2, operand, fill, mask, shift;
|
||||||
int32 sop1, sop2;
|
int32 sop1, sop2;
|
||||||
|
|
||||||
if ((cpu_unit.flags & UNIT_EAU) == 0) /* option installed? */
|
if ((cpu_unit.flags & UNIT_EAU) == 0) /* option installed? */
|
||||||
if ((UNIT_CPU_MODEL == UNIT_2114) && (IR == 0101100)) /* 2114 and RRR 16? */
|
if (UNIT_CPU_MODEL == UNIT_2114 && IR == 0101100) /* 2114 and RRR 16? */
|
||||||
return SCPE_OK; /* allowed as NOP */
|
return SCPE_OK; /* allowed as NOP */
|
||||||
else
|
else
|
||||||
return stop_inst; /* fail */
|
return stop_inst; /* fail */
|
||||||
|
|
||||||
|
if (IR & 017) /* if the shift count is 1-15 */
|
||||||
|
shift = IR & 017; /* then use it verbatim */
|
||||||
|
else /* otherwise the count iz zero */
|
||||||
|
shift = 16; /* so use a shift count of 16 */
|
||||||
|
|
||||||
switch ((IR >> 8) & 0377) { /* decode IR<15:8> */
|
switch ((IR >> 8) & 0377) { /* decode IR<15:8> */
|
||||||
|
|
||||||
case 0200: /* EAU group 0 */
|
case 0200: /* EAU group 0 */
|
||||||
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
|
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
|
||||||
|
|
||||||
case 000: /* DIAG 100000 */
|
case 000: /* DIAG 100000 */
|
||||||
if ((UNIT_CPU_MODEL != UNIT_1000_E) && /* must be 1000 E-series */
|
if ((UNIT_CPU_MODEL != UNIT_1000_E) && /* must be 1000 E-series */
|
||||||
(UNIT_CPU_MODEL != UNIT_1000_F)) /* or 1000 F-series */
|
(UNIT_CPU_MODEL != UNIT_1000_F)) /* or 1000 F-series */
|
||||||
return stop_inst; /* trap if not */
|
return stop_inst; /* trap if not */
|
||||||
break; /* DIAG is NOP unless halted */
|
break; /* DIAG is NOP unless halted */
|
||||||
|
|
||||||
case 001: /* ASL 100020-100037 */
|
|
||||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
|
||||||
O = 0; /* clear ovflo */
|
|
||||||
while (sc-- != 0) { /* bit by bit */
|
|
||||||
t = BR << 1; /* shift B */
|
|
||||||
BR = (BR & SIGN) | (t & 077777) | (AR >> 15);
|
|
||||||
AR = (AR << 1) & DMASK;
|
|
||||||
if ((BR ^ t) & SIGN) O = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 002: /* LSL 100040-100057 */
|
case 001: /* ASL 100020-100037 */
|
||||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
operand = TO_DWORD (BR, AR); /* form the double-word operand */
|
||||||
BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK;
|
|
||||||
AR = (AR << sc) & DMASK; /* BR'AR lsh left */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 003: /* TIMER 100060 */
|
mask = D32_UMAX << 31 - shift; /* form a mask for the bits that will be lost */
|
||||||
if (UNIT_CPU_TYPE != UNIT_TYPE_1000) /* must be 1000 */
|
|
||||||
return stop_inst; /* trap if not */
|
|
||||||
if (UNIT_CPU_MODEL == UNIT_1000_M) /* 1000 M-series? */
|
|
||||||
goto MPY; /* decode as MPY */
|
|
||||||
BR = (BR + 1) & DMASK; /* increment B */
|
|
||||||
if (BR) PR = err_PC; /* if !=0, repeat */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 004: /* RRL 100100-100117 */
|
if (operand & D32_SIGN) /* if the operand is negative */
|
||||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
O = (~operand & mask & D32_MASK) != 0; /* then set overflow if any of the lost bits are zeros */
|
||||||
t = BR; /* BR'AR rot left */
|
else /* otherwise it's positive */
|
||||||
BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK;
|
O = (operand & mask & D32_MASK) != 0; /* so set overflow if any of the lost bits are ones */
|
||||||
AR = ((AR << sc) | (t >> (16 - sc))) & DMASK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 010: /* MPY 100200 (OP_K) */
|
operand = operand << shift & D32_SMAX /* shift the operand left */
|
||||||
MPY:
|
| operand & D32_SIGN; /* while keeping the original sign bit */
|
||||||
reason = cpu_ops (OP_K, op, intrq); /* get operand */
|
|
||||||
if (reason == SCPE_OK) { /* successful eval? */
|
|
||||||
sop1 = SEXT (AR); /* sext AR */
|
|
||||||
sop2 = SEXT (op[0].word); /* sext mem */
|
|
||||||
sop1 = sop1 * sop2; /* signed mpy */
|
|
||||||
BR = (sop1 >> 16) & DMASK; /* to BR'AR */
|
|
||||||
AR = sop1 & DMASK;
|
|
||||||
O = 0; /* no overflow */
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* others undefined */
|
BR = UPPER_WORD (operand); /* split the operand */
|
||||||
return stop_inst;
|
AR = LOWER_WORD (operand); /* into its constituent parts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 002: /* LSL 100040-100057 */
|
||||||
|
operand = TO_DWORD (BR, AR) << shift; /* shift the double-word operand left */
|
||||||
|
|
||||||
|
BR = UPPER_WORD (operand); /* split the operand */
|
||||||
|
AR = LOWER_WORD (operand); /* into its constituent parts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 004: /* RRL 100100-100117 */
|
||||||
|
operand = TO_DWORD (BR, AR); /* form the double-word operand */
|
||||||
|
fill = operand; /* and fill with operand bits */
|
||||||
|
|
||||||
|
operand = operand << shift /* rotate the operand left */
|
||||||
|
| fill >> 32 - shift; /* while filling in on the right */
|
||||||
|
|
||||||
|
BR = UPPER_WORD (operand); /* split the operand */
|
||||||
|
AR = LOWER_WORD (operand); /* into its constituent parts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 003: /* TIMER 100060 */
|
||||||
|
if (UNIT_CPU_TYPE != UNIT_TYPE_1000) /* must be 1000 */
|
||||||
|
return stop_inst; /* trap if not */
|
||||||
|
|
||||||
|
if (UNIT_CPU_MODEL != UNIT_1000_M) { /* 1000 E/F-series? */
|
||||||
|
BR = (BR + 1) & DMASK; /* increment B */
|
||||||
|
|
||||||
|
if (BR) /* if !=0, repeat */
|
||||||
|
PR = err_PC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fall into the MPY case if 1000 M-Series */
|
||||||
|
|
||||||
|
case 010: /* MPY 100200 (OP_K) */
|
||||||
|
reason = cpu_ops (OP_K, op, intrq); /* get operand */
|
||||||
|
|
||||||
|
if (reason == SCPE_OK) { /* successful eval? */
|
||||||
|
sop1 = SEXT (AR); /* sext AR */
|
||||||
|
sop2 = SEXT (op[0].word); /* sext mem */
|
||||||
|
sop1 = sop1 * sop2; /* signed mpy */
|
||||||
|
BR = UPPER_WORD (sop1); /* to BR'AR */
|
||||||
|
AR = LOWER_WORD (sop1);
|
||||||
|
O = 0; /* no overflow */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default: /* others undefined */
|
||||||
|
return stop_inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0201: /* DIV 100400 (OP_K) */
|
case 0201: /* DIV 100400 (OP_K) */
|
||||||
reason = cpu_ops (OP_K, op, intrq); /* get operand */
|
reason = cpu_ops (OP_K, op, intrq); /* get operand */
|
||||||
|
|
||||||
if (reason != SCPE_OK) /* eval failed? */
|
if (reason != SCPE_OK) /* eval failed? */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
rs = qs = BR & SIGN; /* save divd sign */
|
rs = qs = BR & SIGN; /* save divd sign */
|
||||||
|
|
||||||
if (rs) { /* neg? */
|
if (rs) { /* neg? */
|
||||||
AR = (~AR + 1) & DMASK; /* make B'A pos */
|
AR = (~AR + 1) & DMASK; /* make B'A pos */
|
||||||
BR = (~BR + (AR == 0)) & DMASK; /* make divd pos */
|
BR = (~BR + (AR == 0)) & DMASK; /* make divd pos */
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 = op[0].word; /* divr = mem */
|
v2 = op[0].word; /* divr = mem */
|
||||||
|
|
||||||
if (v2 & SIGN) { /* neg? */
|
if (v2 & SIGN) { /* neg? */
|
||||||
v2 = (~v2 + 1) & DMASK; /* make divr pos */
|
v2 = (~v2 + 1) & DMASK; /* make divr pos */
|
||||||
qs = qs ^ SIGN; /* sign of quotient */
|
qs = qs ^ SIGN; /* sign of quotient */
|
||||||
}
|
}
|
||||||
if (BR >= v2) O = 1; /* divide work? */
|
|
||||||
|
if (BR >= v2) /* if the divisor is too small */
|
||||||
|
O = 1; /* then set overflow */
|
||||||
|
|
||||||
else { /* maybe... */
|
else { /* maybe... */
|
||||||
O = 0; /* assume ok */
|
O = 0; /* assume ok */
|
||||||
v1 = (BR << 16) | AR; /* 32b divd */
|
v1 = (BR << 16) | AR; /* 32b divd */
|
||||||
AR = (v1 / v2) & DMASK; /* quotient */
|
AR = (v1 / v2) & DMASK; /* quotient */
|
||||||
BR = (v1 % v2) & DMASK; /* remainder */
|
BR = (v1 % v2) & DMASK; /* remainder */
|
||||||
|
|
||||||
if (AR) { /* quotient > 0? */
|
if (AR) { /* quotient > 0? */
|
||||||
if (qs) AR = (~AR + 1) & DMASK; /* apply quo sign */
|
if (qs) /* apply quo sign */
|
||||||
if ((AR ^ qs) & SIGN) O = 1; /* still wrong? ovflo */
|
AR = NEG16 (AR);
|
||||||
|
|
||||||
|
if ((AR ^ qs) & SIGN) /* still wrong? ovflo */
|
||||||
|
O = 1;
|
||||||
}
|
}
|
||||||
if (rs) BR = (~BR + 1) & DMASK; /* apply rem sign */
|
|
||||||
|
if (rs)
|
||||||
|
BR = NEG16 (BR); /* apply rem sign */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0202: /* EAU group 2 */
|
case 0202: /* EAU group 2 */
|
||||||
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
|
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
|
||||||
|
|
||||||
case 001: /* ASR 101020-101037 */
|
case 001: /* ASR 101020-101037 */
|
||||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
O = 0; /* clear ovflo */
|
||||||
AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK;
|
|
||||||
BR = (SEXT (BR) >> sc) & DMASK; /* BR'AR ash right */
|
|
||||||
O = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 002: /* LSR 101040-101057 */
|
operand = TO_DWORD (BR, AR); /* form the double-word operand */
|
||||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
fill = (operand & D32_SIGN ? ~0 : 0); /* and fill with copies of the sign bit */
|
||||||
AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK;
|
|
||||||
BR = BR >> sc; /* BR'AR log right */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 004: /* RRR 101100-101117 */
|
operand = operand >> shift /* shift the operand right */
|
||||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
| fill << 32 - shift; /* while filling in with sign bits */
|
||||||
t = AR; /* BR'AR rot right */
|
|
||||||
AR = ((AR >> sc) | (BR << (16 - sc))) & DMASK;
|
|
||||||
BR = ((BR >> sc) | (t << (16 - sc))) & DMASK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* others undefined */
|
BR = UPPER_WORD (operand); /* split the operand */
|
||||||
return stop_inst;
|
AR = LOWER_WORD (operand); /* into its constituent parts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 002: /* LSR 101040-101057 */
|
||||||
|
operand = TO_DWORD (BR, AR) >> shift; /* shift the double-word operand right */
|
||||||
|
|
||||||
|
BR = UPPER_WORD (operand); /* split the operand */
|
||||||
|
AR = LOWER_WORD (operand); /* into its constituent parts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case 004: /* RRR 101100-101117 */
|
||||||
|
operand = TO_DWORD (BR, AR); /* form the double-word operand */
|
||||||
|
fill = operand; /* and fill with operand bits */
|
||||||
|
|
||||||
|
operand = operand >> shift /* rotate the operand right */
|
||||||
|
| fill << 32 - shift; /* while filling in on the left */
|
||||||
|
|
||||||
|
BR = UPPER_WORD (operand); /* split the operand */
|
||||||
|
AR = LOWER_WORD (operand); /* into its constituent parts */
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
default: /* others undefined */
|
||||||
|
return stop_inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0210: /* DLD 104200 (OP_D) */
|
case 0210: /* DLD 104200 (OP_D) */
|
||||||
reason = cpu_ops (OP_D, op, intrq); /* get operand */
|
reason = cpu_ops (OP_D, op, intrq); /* get operand */
|
||||||
|
|
||||||
if (reason == SCPE_OK) { /* successful eval? */
|
if (reason == SCPE_OK) { /* successful eval? */
|
||||||
AR = (op[0].dword >> 16) & DMASK; /* load AR */
|
AR = UPPER_WORD (op[0].dword); /* load AR */
|
||||||
BR = op[0].dword & DMASK; /* load BR */
|
BR = LOWER_WORD (op[0].dword); /* load BR */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 0211: /* DST 104400 (OP_A) */
|
case 0211: /* DST 104400 (OP_A) */
|
||||||
reason = cpu_ops (OP_A, op, intrq); /* get operand */
|
reason = cpu_ops (OP_A, op, intrq); /* get operand */
|
||||||
|
|
||||||
if (reason == SCPE_OK) { /* successful eval? */
|
if (reason == SCPE_OK) { /* successful eval? */
|
||||||
WriteW (op[0].word, AR); /* store AR */
|
WriteW (op[0].word, AR); /* store AR */
|
||||||
WriteW ((op[0].word + 1) & VAMASK, BR); /* store BR */
|
WriteW ((op[0].word + 1) & VAMASK, BR); /* store BR */
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default: /* should never get here */
|
default: /* should never get here */
|
||||||
return SCPE_IERR; /* bad call from cpu_instr */
|
return SCPE_IERR; /* bad call from cpu_instr */
|
||||||
}
|
}
|
||||||
@@ -521,8 +600,8 @@ return cpu_user (IR, intrq); /* try user microcode */
|
|||||||
|
|
||||||
Instructions Option Name 1000-M 1000-E 1000-F
|
Instructions Option Name 1000-M 1000-E 1000-F
|
||||||
------------- ---------------------------- ------ ------ ------
|
------------- ---------------------------- ------ ------ ------
|
||||||
10x400-10x437 2000 IOP opt opt opt
|
10x400-10x437 2000 IOP opt opt -
|
||||||
10x460-10x477 2000 IOP opt opt opt
|
10x460-10x477 2000 IOP opt opt -
|
||||||
10x460-10x477 Vector Instruction Set - - opt
|
10x460-10x477 Vector Instruction Set - - opt
|
||||||
10x520-10x537 Distributed System opt - -
|
10x520-10x537 Distributed System opt - -
|
||||||
10x600-10x617 SIGNAL/1000 Instruction Set - - opt
|
10x600-10x617 SIGNAL/1000 Instruction Set - - opt
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* hp2100_defs.h: HP 2100 simulator definitions
|
/* hp2100_defs.h: HP 2100 System architectural declarations
|
||||||
|
|
||||||
Copyright (c) 1993-2016, Robert M. Supnik
|
Copyright (c) 1993-2016, Robert M. Supnik
|
||||||
|
Copyright (c) 2017 J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -23,6 +24,7 @@
|
|||||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
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.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
10-Jan-17 JDB Added architectural constants
|
||||||
05-Aug-16 JDB Removed PC_Global renaming; P register is now "PR"
|
05-Aug-16 JDB Removed PC_Global renaming; P register is now "PR"
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
19-Jun-15 JDB Conditionally use PC_Global for PC for version 4.0 and on
|
19-Jun-15 JDB Conditionally use PC_Global for PC for version 4.0 and on
|
||||||
@@ -71,9 +73,80 @@
|
|||||||
15-Oct-00 RMS Added dynamic device numbers
|
15-Oct-00 RMS Added dynamic device numbers
|
||||||
14-Apr-99 RMS Changed t_addr to unsigned
|
14-Apr-99 RMS Changed t_addr to unsigned
|
||||||
|
|
||||||
The author gratefully acknowledges the help of Jeff Moffat in answering
|
The [original] author gratefully acknowledges the help of Jeff Moffat in
|
||||||
questions about the HP2100; and of Dave Bryan in adding features and
|
answering questions about the HP2100; and of Dave Bryan in adding features
|
||||||
correcting errors throughout the simulator.
|
and correcting errors throughout the simulator.
|
||||||
|
|
||||||
|
|
||||||
|
This file provides the general declarations used throughout the HP 2100
|
||||||
|
simulator. It is required by all modules.
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------
|
||||||
|
Implementation Note -- Compiling the Simulator as C++
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
Although simulators are written in C, the SIMH project encourages developers
|
||||||
|
to compile them with a C++ compiler to obtain the more careful type checking
|
||||||
|
provided. To obtain successful compilations, the simulator must be written
|
||||||
|
in the subset of C that is also valid C++. Using valid C features beyond
|
||||||
|
that subset, as the HP 2100 simulator does, will produce C++ compiler errors.
|
||||||
|
|
||||||
|
The standard C features used by the simulator that prevent error-free C++
|
||||||
|
compilation are:
|
||||||
|
|
||||||
|
1. Incomplete types.
|
||||||
|
|
||||||
|
In C, mutually recursive type definitions are allowed by the use of
|
||||||
|
incomplete type declarations, such as "DEVICE ms_dev;" followed later by
|
||||||
|
"DEVICE ms_dev {...};". Several HP device simulators use this feature to
|
||||||
|
place a pointer to the device structure in the "desc" field of an MTAB
|
||||||
|
array element, typically when the associated validation or display
|
||||||
|
routine handles multiple devices. As the DEVICE contains a pointer to
|
||||||
|
the MTAB array, and an MTAB array element contains a pointer to the
|
||||||
|
DEVICE, the definitions are mutually recursive, and incomplete types are
|
||||||
|
employed. C++ does not permit incomplete types.
|
||||||
|
|
||||||
|
2. Implicit conversion of ints to enums.
|
||||||
|
|
||||||
|
In C, enumeration types are compatible with integer types, and its
|
||||||
|
members are constants having type "int". As such, they are semantically
|
||||||
|
equivalent to and may be used interchangeably with integers. For the
|
||||||
|
developer, though, C enumerations have some advantages. In particular,
|
||||||
|
the compiler may check a "switch" statement to ensure that all of the
|
||||||
|
enumeration cases are covered. Also, a mathematical set may be modeled
|
||||||
|
by an enumeration type with disjoint enumerator values, with the bitwise
|
||||||
|
integer OR and AND operators modeling the set union and intersection
|
||||||
|
operations. The latter has direct support in the "gdb" debugger, which
|
||||||
|
will display an enumerated type value as a union of the various
|
||||||
|
enumerators. The HP simulator makes extensive use of both features to
|
||||||
|
model hardware signal buses (e.g., INBOUND_SET, OUTBOUND_SET) and so
|
||||||
|
performs bitwise integer operations on the enumerations to model signal
|
||||||
|
assertion and denial. In C++, implicit conversion from enumerations to
|
||||||
|
integers is allowed, but conversion from integers to enumerations is
|
||||||
|
illegal without explicit casts. Therefore, the idiom employed by the
|
||||||
|
simulator to assert a signal (e.g., "outbound_signals |= INTREQ") is
|
||||||
|
rejected by the C++ compiler.
|
||||||
|
|
||||||
|
3. Implicit increment operations on enums.
|
||||||
|
|
||||||
|
Because enums are compatible with integers in C, no special enumerator
|
||||||
|
increment operator is provided. To cycle through the range of an
|
||||||
|
enumeration type, e.g. in a "for" statement, the standard integer
|
||||||
|
increment operator, "++", is used. In C++, the "++" operator must be
|
||||||
|
overloaded with a version specific to the enumeration type; applying the
|
||||||
|
integer "++" to an enumeration is illegal.
|
||||||
|
|
||||||
|
4. Use of C++ keywords as variable names.
|
||||||
|
|
||||||
|
C++ reserves a number of additional keywords beyond those reserved by C.
|
||||||
|
Use of any of these keywords as a variable or type name is legal C but
|
||||||
|
illegal C++. The HP simulator uses variables named "class" and
|
||||||
|
"operator", which are keywords in C++.
|
||||||
|
|
||||||
|
The HP simulator is written in ISO standard C and will compile cleanly with a
|
||||||
|
compiler implementing the 1999 C standard. Compilation as C++ is not a goal
|
||||||
|
of the simulator and cannot work, given the incompatibilities listed above.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -86,18 +159,32 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The following pragmas quell clang warnings that are on by default but should
|
/* The following pragmas quell clang and Microsoft Visual C++ warnings that are
|
||||||
not be, in my opinion. They warn about the use of perfectly valid code and
|
on by default but should not be, in my opinion. They warn about the use of
|
||||||
require the addition of redundant parentheses and braces to silence them.
|
perfectly valid code and require the addition of redundant parentheses and
|
||||||
Rather than clutter up the code with scores of extra symbols that, in my
|
braces to silence them. Rather than clutter up the code with scores of extra
|
||||||
view, make the code harder to read and maintain, I elect to suppress these
|
symbols that, in my view, make the code harder to read and maintain, I elect
|
||||||
warnings.
|
to suppress these warnings.
|
||||||
|
|
||||||
|
VC++ 2008 warning descriptions:
|
||||||
|
|
||||||
|
- 4114: "same type qualifier used more than once" [legal per C99]
|
||||||
|
|
||||||
|
- 4554: "check operator precedence for possible error; use parentheses to
|
||||||
|
clarify precedence"
|
||||||
|
|
||||||
|
- 4996: "function was declared deprecated"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined (__clang__)
|
#if defined (__clang__)
|
||||||
#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
|
#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
|
||||||
#pragma clang diagnostic ignored "-Wbitwise-op-parentheses"
|
#pragma clang diagnostic ignored "-Wbitwise-op-parentheses"
|
||||||
#pragma clang diagnostic ignored "-Wdangling-else"
|
#pragma clang diagnostic ignored "-Wshift-op-parentheses"
|
||||||
|
#pragma clang diagnostic ignored "-Wdangling-else"
|
||||||
|
|
||||||
|
#elif defined (_MSC_VER)
|
||||||
|
#pragma warning (disable: 4114 4554 4996)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -114,6 +201,181 @@
|
|||||||
#define STOP_PWROFF 9 /* device powered off */
|
#define STOP_PWROFF 9 /* device powered off */
|
||||||
#define NOTE_IOG 10 /* I/O instr executed */
|
#define NOTE_IOG 10 /* I/O instr executed */
|
||||||
|
|
||||||
|
|
||||||
|
/* Modifier validation identifiers */
|
||||||
|
|
||||||
|
#define MTAB_XDV (MTAB_XTD | MTAB_VDV)
|
||||||
|
#define MTAB_XUN (MTAB_XTD | MTAB_VUN)
|
||||||
|
|
||||||
|
|
||||||
|
/* Architectural constants.
|
||||||
|
|
||||||
|
These macros specify the width, sign location, value mask, and minimum and
|
||||||
|
maximum signed and unsigned values for the data sizes supported by the
|
||||||
|
simulator. In addition, masks for 16-bit and 32-bit overflow are defined (an
|
||||||
|
overflow is indicated if the masked bits are not all ones or all zeros).
|
||||||
|
|
||||||
|
The HP_WORD type is used to declare variables that represent 16-bit registers
|
||||||
|
or buses in hardware.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef uint16 HP_WORD; /* HP 16-bit data word representation */
|
||||||
|
|
||||||
|
#define R_MASK 0177777u /* 16-bit register mask */
|
||||||
|
|
||||||
|
#define D4_WIDTH 4 /* 4-bit data bit width */
|
||||||
|
#define D4_MASK 0017u /* 4-bit data mask */
|
||||||
|
|
||||||
|
#define D8_WIDTH 8 /* 8-bit data bit width */
|
||||||
|
#define D8_MASK 0377u /* 8-bit data mask */
|
||||||
|
#define D8_UMAX 0377u /* 8-bit unsigned maximum value */
|
||||||
|
#define D8_SMAX 0177u /* 8-bit signed maximum value */
|
||||||
|
#define D8_SMIN 0200u /* 8-bit signed minimum value */
|
||||||
|
#define D8_SIGN 0200u /* 8-bit sign */
|
||||||
|
|
||||||
|
#define D16_WIDTH 16 /* 16-bit data bit width */
|
||||||
|
#define D16_MASK 0177777u /* 16-bit data mask */
|
||||||
|
#define D16_UMAX 0177777u /* 16-bit unsigned maximum value */
|
||||||
|
#define D16_SMAX 0077777u /* 16-bit signed maximum value */
|
||||||
|
#define D16_SMIN 0100000u /* 16-bit signed minimum value */
|
||||||
|
#define D16_SIGN 0100000u /* 16-bit sign */
|
||||||
|
|
||||||
|
#define D32_WIDTH 32 /* 32-bit data bit width */
|
||||||
|
#define D32_MASK 037777777777u /* 32-bit data mask */
|
||||||
|
#define D32_UMAX 037777777777u /* 32-bit unsigned maximum value */
|
||||||
|
#define D32_SMAX 017777777777u /* 32-bit signed maximum value */
|
||||||
|
#define D32_SMIN 020000000000u /* 32-bit signed minimum value */
|
||||||
|
#define D32_SIGN 020000000000u /* 32-bit sign */
|
||||||
|
|
||||||
|
#define D48_WIDTH 48 /* 48-bit data bit width */
|
||||||
|
#define D48_MASK 07777777777777777uL /* 48-bit data mask */
|
||||||
|
#define D48_UMAX 07777777777777777uL /* 48-bit unsigned maximum value */
|
||||||
|
#define D48_SMAX 03777777777777777uL /* 48-bit signed maximum value */
|
||||||
|
#define D48_SMIN 04000000000000000uL /* 48-bit signed minimum value */
|
||||||
|
#define D48_SIGN 04000000000000000uL /* 48-bit sign */
|
||||||
|
|
||||||
|
#define D64_WIDTH 64 /* 64-bit data bit width */
|
||||||
|
#define D64_MASK 01777777777777777777777uL /* 64-bit data mask */
|
||||||
|
#define D64_UMAX 01777777777777777777777uL /* 64-bit unsigned maximum value */
|
||||||
|
#define D64_SMAX 00777777777777777777777uL /* 64-bit signed maximum value */
|
||||||
|
#define D64_SMIN 01000000000000000000000uL /* 64-bit signed minimum value */
|
||||||
|
#define D64_SIGN 01000000000000000000000uL /* 64-bit sign */
|
||||||
|
|
||||||
|
#define S16_OVFL_MASK ((uint32) D16_UMAX << D16_WIDTH | \
|
||||||
|
D16_SIGN) /* 16-bit signed overflow mask */
|
||||||
|
|
||||||
|
#define S32_OVFL_MASK ((t_uint64) D32_UMAX << D32_WIDTH | \
|
||||||
|
D32_SIGN) /* 32-bit signed overflow mask */
|
||||||
|
|
||||||
|
|
||||||
|
/* Memory constants */
|
||||||
|
|
||||||
|
#define OF_WIDTH 10 /* offset bit width */
|
||||||
|
#define OF_MASK ((1u << OF_WIDTH) - 1) /* offset mask (2 ** 10 - 1) */
|
||||||
|
#define OF_MAX ((1u << OF_WIDTH) - 1) /* offset maximum (2 ** 10 - 1) */
|
||||||
|
|
||||||
|
#define PG_WIDTH 10 /* page bit width */
|
||||||
|
#define PG_MASK ((1u << PG_WIDTH) - 1) /* page mask (2 ** 10 - 1) */
|
||||||
|
#define PG_MAX ((1u << PG_WIDTH) - 1) /* page maximum (2 ** 10 - 1) */
|
||||||
|
|
||||||
|
#define LA_WIDTH 15 /* logical address bit width */
|
||||||
|
#define LA_MASK ((1u << LA_WIDTH) - 1) /* logical address mask (2 ** 15 - 1) */
|
||||||
|
#define LA_MAX ((1u << LA_WIDTH) - 1) /* logical address maximum (2 ** 15 - 1) */
|
||||||
|
|
||||||
|
#define PA_WIDTH 20 /* physical address bit width */
|
||||||
|
#define PA_MASK ((1u << PA_WIDTH) - 1) /* physical address mask (2 ** 20 - 1) */
|
||||||
|
#define PA_MAX ((1u << PA_WIDTH) - 1) /* physical address maximum (2 ** 20 - 1) */
|
||||||
|
|
||||||
|
#define DV_WIDTH 16 /* data value bit width */
|
||||||
|
#define DV_MASK ((1u << DV_WIDTH) - 1) /* data value mask (2 ** 16 - 1) */
|
||||||
|
#define DV_SIGN ( 1u << (DV_WIDTH - 1)) /* data value sign (2 ** 15) */
|
||||||
|
#define DV_UMAX ((1u << DV_WIDTH) - 1) /* data value unsigned maximum (2 ** 16 - 1) */
|
||||||
|
#define DV_SMAX ((1u << (DV_WIDTH - 1)) - 1) /* data value signed maximum (2 ** 15 - 1) */
|
||||||
|
|
||||||
|
|
||||||
|
/* Portable conversions.
|
||||||
|
|
||||||
|
SIMH is written with the assumption that the defined-size types (e.g.,
|
||||||
|
uint16) are at least the required number of bits but may be larger.
|
||||||
|
Conversions that otherwise would make inherent size assumptions must instead
|
||||||
|
be coded explicitly. For example, doing:
|
||||||
|
|
||||||
|
negative_value_32 = (int32) negative_value_16;
|
||||||
|
|
||||||
|
...will not guarantee that bits 0-15 of "negative_value_32" are ones, whereas
|
||||||
|
the supplied sign-extension macro will.
|
||||||
|
|
||||||
|
The conversions available are:
|
||||||
|
|
||||||
|
- SEXT8 -- int8 sign-extended to int32
|
||||||
|
- SEXT16 -- int16 sign-extended to int32
|
||||||
|
- NEG16 -- int8 negated
|
||||||
|
- NEG16 -- int16 negated
|
||||||
|
- NEG32 -- int32 negated
|
||||||
|
- INT16 -- uint16 to int16
|
||||||
|
- INT32 -- uint32 to int32
|
||||||
|
|
||||||
|
|
||||||
|
Implementation notes:
|
||||||
|
|
||||||
|
1. The routines assume that 16-bit values are masked to exactly 16 bits
|
||||||
|
before invoking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SEXT8(x) (int32) ((x) & D8_SIGN ? (x) | ~D8_MASK : (x))
|
||||||
|
#define SEXT16(x) (int32) ((x) & D16_SIGN ? (x) | ~D16_MASK : (x))
|
||||||
|
|
||||||
|
#define NEG8(x) ((~(x) + 1) & D8_MASK)
|
||||||
|
#define NEG16(x) ((~(x) + 1) & D16_MASK)
|
||||||
|
#define NEG32(x) ((~(x) + 1) & D32_MASK)
|
||||||
|
|
||||||
|
#define INT16(u) ((u) > D16_SMAX ? (-(int16) (D16_UMAX - (u)) - 1) : (int16) (u))
|
||||||
|
#define INT32(u) ((u) > D32_SMAX ? (-(int32) (D32_UMAX - (u)) - 1) : (int32) (u))
|
||||||
|
|
||||||
|
|
||||||
|
/* Byte accessors.
|
||||||
|
|
||||||
|
These macros extract the upper and lower bytes from a word and form a word
|
||||||
|
from upper and lower bytes. Replacement of a byte within a word is also
|
||||||
|
provided, as is an enumeration type that defines byte selection.
|
||||||
|
|
||||||
|
The accessors are:
|
||||||
|
|
||||||
|
- UPPER_BYTE -- return the byte from the upper position of a word value
|
||||||
|
- LOWER_BYTE -- return the byte from the lower position of a word value
|
||||||
|
- TO_WORD -- return a word with the specified upper and lower bytes
|
||||||
|
|
||||||
|
- REPLACE_UPPER -- replace the upper byte of the word value
|
||||||
|
- REPLACE_LOWER -- replace the lower byte of the word value
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
upper, /* upper byte selected */
|
||||||
|
lower /* lower byte selected */
|
||||||
|
} BYTE_SELECTOR;
|
||||||
|
|
||||||
|
#define UPPER_BYTE(w) (uint8) ((w) >> D8_WIDTH & D8_MASK)
|
||||||
|
#define LOWER_BYTE(w) (uint8) ((w) & D8_MASK)
|
||||||
|
#define TO_WORD(u,l) (HP_WORD) (((u) & D8_MASK) << D8_WIDTH | (l) & D8_MASK)
|
||||||
|
|
||||||
|
#define REPLACE_UPPER(w,b) ((w) & D8_MASK | ((b) & D8_MASK) << D8_WIDTH)
|
||||||
|
#define REPLACE_LOWER(w,b) ((w) & D8_MASK << D8_WIDTH | (b) & D8_MASK)
|
||||||
|
|
||||||
|
|
||||||
|
/* Double-word accessors */
|
||||||
|
|
||||||
|
#define UPPER_WORD(d) (HP_WORD) ((d) >> D16_WIDTH & D16_MASK)
|
||||||
|
#define LOWER_WORD(d) (HP_WORD) ((d) & D16_MASK)
|
||||||
|
|
||||||
|
#define TO_DWORD(u,l) ((uint32) (u) << D16_WIDTH | (l))
|
||||||
|
|
||||||
|
|
||||||
|
/* Portable conversions (sign-extension, unsigned-to-signed) */
|
||||||
|
|
||||||
|
#define SEXT(x) ((int32) (((x) & SIGN)? ((x) | ~DMASK): ((x) & DMASK)))
|
||||||
|
|
||||||
|
|
||||||
/* Memory */
|
/* Memory */
|
||||||
|
|
||||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||||
@@ -134,13 +396,6 @@
|
|||||||
#define DMAX 0077777 /* 16b maximum signed value */
|
#define DMAX 0077777 /* 16b maximum signed value */
|
||||||
#define DMASK8 0377 /* 8b data mask/maximum value */
|
#define DMASK8 0377 /* 8b data mask/maximum value */
|
||||||
|
|
||||||
/* Portable conversions (sign-extension, unsigned-to-signed) */
|
|
||||||
|
|
||||||
#define SEXT(x) ((int32) (((x) & SIGN)? ((x) | ~DMASK): ((x) & DMASK)))
|
|
||||||
|
|
||||||
#define INT16(u) ((u) > DMAX ? (-(int16) (DMASK - (u)) - 1) : (int16) (u))
|
|
||||||
#define INT32(u) ((u) > DMAX32 ? (-(int32) (DMASK32 - (u)) - 1) : (int32) (u))
|
|
||||||
|
|
||||||
/* Timers */
|
/* Timers */
|
||||||
|
|
||||||
#define TMR_CLK 0 /* clock */
|
#define TMR_CLK 0 /* clock */
|
||||||
@@ -332,9 +587,19 @@ typedef uint32 IOCYCLE; /* a set of signals form
|
|||||||
ioCRS | ioPOPIO | ioPON) /* signals that may affect interrupt state */
|
ioCRS | ioPOPIO | ioPON) /* signals that may affect interrupt state */
|
||||||
|
|
||||||
|
|
||||||
/* I/O structures */
|
/* Flip-flops */
|
||||||
|
|
||||||
typedef enum { CLEAR, SET } FLIP_FLOP; /* flip-flop type and values */
|
typedef enum {
|
||||||
|
CLEAR = 0, /* the flip-flop is clear */
|
||||||
|
SET = 1 /* the flip-flop is set */
|
||||||
|
} FLIP_FLOP;
|
||||||
|
|
||||||
|
#define TOGGLE(ff) ff = (FLIP_FLOP) (ff ^ 1) /* toggle a flip-flop variable */
|
||||||
|
|
||||||
|
#define D_FF(b) (FLIP_FLOP) ((b) != 0) /* use a Boolean expression for a D flip-flop */
|
||||||
|
|
||||||
|
|
||||||
|
/* I/O structures */
|
||||||
|
|
||||||
typedef struct dib DIB; /* incomplete definition */
|
typedef struct dib DIB; /* incomplete definition */
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* hp2100_di.c: HP 12821A HP-IB Disc Interface simulator
|
/* hp2100_di.c: HP 12821A HP-IB Disc Interface simulator
|
||||||
|
|
||||||
Copyright (c) 2010-2016, J. David Bryan
|
Copyright (c) 2010-2017, J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
DI 12821A Disc Interface
|
DI 12821A Disc Interface
|
||||||
|
|
||||||
|
17-Jan-17 JDB Changed to use new byte accessors in hp2100_defs.h
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||||
Removed redundant global declarations
|
Removed redundant global declarations
|
||||||
@@ -33,10 +34,10 @@
|
|||||||
09-Oct-10 JDB Created DI simulation
|
09-Oct-10 JDB Created DI simulation
|
||||||
|
|
||||||
References:
|
References:
|
||||||
- HP 12821A Disc Interface Installation and Service Manual (12821-90006,
|
- HP 12821A Disc Interface Installation and Service Manual
|
||||||
Feb-1985)
|
(12821-90006, February 1985)
|
||||||
- IEEE Standard Digital Interface for Programmable Instrumentation
|
- IEEE Standard Digital Interface for Programmable Instrumentation
|
||||||
(IEEE-488A-1980, Sep-1979)
|
(IEEE-488A-1980, September 1979)
|
||||||
|
|
||||||
|
|
||||||
The 12821A was a high-speed implementation of the Hewlett-Packard Interface
|
The 12821A was a high-speed implementation of the Hewlett-Packard Interface
|
||||||
@@ -1609,7 +1610,7 @@ if (di_card->cntl_register & CNTL_LSTN) { /* is the card receiving
|
|||||||
if ((di_card->cntl_register & CNTL_EOI /* EOI detection is enabled, */
|
if ((di_card->cntl_register & CNTL_EOI /* EOI detection is enabled, */
|
||||||
&& di_card->bus_cntl & BUS_EOI) /* and data was tagged with EOI? */
|
&& di_card->bus_cntl & BUS_EOI) /* and data was tagged with EOI? */
|
||||||
|| (di_card->cntl_register & CNTL_LF /* or LF detection is enabled, */
|
|| (di_card->cntl_register & CNTL_LF /* or LF detection is enabled, */
|
||||||
&& GET_LOWER (data) == LF)) { /* and the byte is a line feed? */
|
&& LOWER_BYTE (data) == LF)) { /* and the byte is a line feed? */
|
||||||
tag = tag | TAG_LBR; /* tag as the last byte received */
|
tag = tag | TAG_LBR; /* tag as the last byte received */
|
||||||
di_card->status_register |= STAT_LBI; /* set the last byte in status */
|
di_card->status_register |= STAT_LBI; /* set the last byte in status */
|
||||||
}
|
}
|
||||||
@@ -1633,10 +1634,10 @@ if (access == bus_access) { /* is this a bus access
|
|||||||
|
|
||||||
if (tag & TAG_LBR) /* is this the last byte? */
|
if (tag & TAG_LBR) /* is this the last byte? */
|
||||||
di_card->fifo [index] = /* copy to both bytes of the FIFO */
|
di_card->fifo [index] = /* copy to both bytes of the FIFO */
|
||||||
tag | SET_BOTH (data); /* and store with the tag */
|
tag | TO_WORD (data, data); /* and store with the tag */
|
||||||
else { /* more bytes are expected */
|
else { /* more bytes are expected */
|
||||||
di_card->fifo [index] = /* so position this byte */
|
di_card->fifo [index] = /* so position this byte */
|
||||||
tag | SET_UPPER (data); /* and store it with the tag */
|
tag | TO_WORD (data, 0); /* and store it with the tag */
|
||||||
add_word = FALSE; /* wait for the second byte before adding */
|
add_word = FALSE; /* wait for the second byte before adding */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1646,18 +1647,18 @@ if (access == bus_access) { /* is this a bus access
|
|||||||
di_card->ibp = upper; /* set the upper byte as next */
|
di_card->ibp = upper; /* set the upper byte as next */
|
||||||
|
|
||||||
di_card->fifo [index] = /* merge the data and tag values */
|
di_card->fifo [index] = /* merge the data and tag values */
|
||||||
tag | di_card->fifo [index] | SET_LOWER (data);
|
tag | di_card->fifo [index] | TO_WORD (0, data);
|
||||||
}
|
}
|
||||||
else /* the card is in unpacked mode */
|
else /* the card is in unpacked mode */
|
||||||
di_card->fifo [index] = /* position this byte */
|
di_card->fifo [index] = /* position this byte */
|
||||||
tag | SET_LOWER (data); /* and store with the tag */
|
tag | TO_WORD (0, data); /* and store with the tag */
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (access == cpu_access) /* is this a cpu access? */
|
else if (access == cpu_access) /* is this a cpu access? */
|
||||||
di_card->fifo [index] = tag | data; /* store the tag and full word in the FIFO */
|
di_card->fifo [index] = tag | data; /* store the tag and full word in the FIFO */
|
||||||
|
|
||||||
else { /* must be diagnostic access */
|
else { /* must be diagnostic access */
|
||||||
data = SET_BOTH (GET_LOWER (data)); /* copy the lower byte to the upper byte */
|
data = TO_WORD (data, data); /* copy the lower byte to the upper byte */
|
||||||
di_card->fifo [index] = tag | data; /* and store the tag and full word in the FIFO */
|
di_card->fifo [index] = tag | data; /* and store the tag and full word in the FIFO */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1814,19 +1815,19 @@ if (access == cpu_access) { /* is this a cpu access?
|
|||||||
else if (access == bus_access) /* is this a bus access? */
|
else if (access == bus_access) /* is this a bus access? */
|
||||||
if (di_card->obp == upper) { /* is this the upper byte? */
|
if (di_card->obp == upper) { /* is this the upper byte? */
|
||||||
di_card->obp = lower; /* set the lower byte as next */
|
di_card->obp = lower; /* set the lower byte as next */
|
||||||
data = GET_UPPER (data); /* mask and position the upper byte in the data word */
|
data = UPPER_BYTE (data); /* mask and position the upper byte in the data word */
|
||||||
remove_word = FALSE; /* do not unload the FIFO until the next byte */
|
remove_word = FALSE; /* do not unload the FIFO until the next byte */
|
||||||
}
|
}
|
||||||
|
|
||||||
else { /* this is the lower byte */
|
else { /* this is the lower byte */
|
||||||
data = GET_LOWER (data); /* mask and position it in the data word */
|
data = LOWER_BYTE (data); /* mask and position it in the data word */
|
||||||
|
|
||||||
if (di_card->cntl_register & CNTL_PACK) /* is the card in the packed mode? */
|
if (di_card->cntl_register & CNTL_PACK) /* is the card in the packed mode? */
|
||||||
di_card->obp = upper; /* set the upper byte as next */
|
di_card->obp = upper; /* set the upper byte as next */
|
||||||
}
|
}
|
||||||
|
|
||||||
else /* must be a diagnostic access */
|
else /* must be a diagnostic access */
|
||||||
data = GET_LOWER (data); /* access is to the lower byte only */
|
data = LOWER_BYTE (data); /* access is to the lower byte only */
|
||||||
|
|
||||||
|
|
||||||
if (remove_word) { /* remove the word from the FIFO? */
|
if (remove_word) { /* remove the word from the FIFO? */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* hp2100_di.h: HP 12821A HP-IB Disc Interface simulator definitions
|
/* hp2100_di.h: HP 12821A HP-IB Disc Interface simulator declarations
|
||||||
|
|
||||||
Copyright (c) 2010-2016, J. David Bryan
|
Copyright (c) 2010-2017, J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
DI 12821A Disc Interface
|
DI 12821A Disc Interface
|
||||||
|
|
||||||
|
10-Jan-17 JDB Moved byte accessors to hp2100_defs.h
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
14-Feb-12 JDB First release
|
14-Feb-12 JDB First release
|
||||||
16-Nov-10 JDB Created DI common definitions file
|
16-Nov-10 JDB Created DI common definitions file
|
||||||
@@ -136,36 +137,17 @@ typedef enum {
|
|||||||
#define PPR(a) (uint8) (1 << (7 - (a))) /* parallel poll response */
|
#define PPR(a) (uint8) (1 << (7 - (a))) /* parallel poll response */
|
||||||
|
|
||||||
|
|
||||||
/* Byte accessors */
|
|
||||||
|
|
||||||
#define BYTE_SHIFT 8 /* byte shift count */
|
|
||||||
#define UPPER_BYTE 0177400 /* high-order byte mask */
|
|
||||||
#define LOWER_BYTE 0000377 /* low-order byte mask */
|
|
||||||
|
|
||||||
#define GET_UPPER(w) (uint8) (((w) & UPPER_BYTE) >> BYTE_SHIFT)
|
|
||||||
#define GET_LOWER(w) (uint8) ((w) & LOWER_BYTE)
|
|
||||||
|
|
||||||
#define SET_UPPER(b) (uint16) ((b) << BYTE_SHIFT)
|
|
||||||
#define SET_LOWER(b) (uint16) (b)
|
|
||||||
#define SET_BOTH(b) (SET_UPPER (b) | SET_LOWER (b))
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
upper, /* upper byte selected */
|
|
||||||
lower /* lower byte selected */
|
|
||||||
} SELECTOR;
|
|
||||||
|
|
||||||
|
|
||||||
/* Per-card state variables */
|
/* Per-card state variables */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FLIP_FLOP control; /* control flip-flop */
|
FLIP_FLOP control; /* control flip-flop */
|
||||||
FLIP_FLOP flag; /* flag flip-flop */
|
FLIP_FLOP flag; /* flag flip-flop */
|
||||||
FLIP_FLOP flagbuf; /* flag buffer flip-flop */
|
FLIP_FLOP flagbuf; /* flag buffer flip-flop */
|
||||||
FLIP_FLOP srq; /* SRQ flip-flop */
|
FLIP_FLOP srq; /* SRQ flip-flop */
|
||||||
FLIP_FLOP edt; /* EDT flip-flop */
|
FLIP_FLOP edt; /* EDT flip-flop */
|
||||||
FLIP_FLOP eor; /* EOR flip-flop */
|
FLIP_FLOP eor; /* EOR flip-flop */
|
||||||
SELECTOR ibp; /* input byte pointer selector */
|
BYTE_SELECTOR ibp; /* input byte pointer selector */
|
||||||
SELECTOR obp; /* output byte pointer selector */
|
BYTE_SELECTOR obp; /* output byte pointer selector */
|
||||||
|
|
||||||
uint16 cntl_register; /* control word register */
|
uint16 cntl_register; /* control word register */
|
||||||
uint16 status_register; /* status word register */
|
uint16 status_register; /* status word register */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* hp2100_di_da.c: HP 12821A HP-IB Disc Interface simulator for Amigo disc drives
|
/* hp2100_di_da.c: HP 12821A HP-IB Disc Interface simulator for Amigo disc drives
|
||||||
|
|
||||||
Copyright (c) 2011-2016, J. David Bryan
|
Copyright (c) 2011-2017, J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
DA 12821A Disc Interface with Amigo disc drives
|
DA 12821A Disc Interface with Amigo disc drives
|
||||||
|
|
||||||
|
17-Jan-17 JDB Changed to use new byte accessors in hp2100_defs.h
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
04-Mar-16 JDB Name changed to "hp2100_disclib" until HP 3000 integration
|
04-Mar-16 JDB Name changed to "hp2100_disclib" until HP 3000 integration
|
||||||
30-Dec-14 JDB Added S-register parameters to ibl_copy
|
30-Dec-14 JDB Added S-register parameters to ibl_copy
|
||||||
@@ -36,16 +37,20 @@
|
|||||||
04-Nov-11 JDB Created DA device
|
04-Nov-11 JDB Created DA device
|
||||||
|
|
||||||
References:
|
References:
|
||||||
- HP 13365 Integrated Controller Programming Guide (13365-90901, Feb-1980)
|
- HP 13365 Integrated Controller Programming Guide
|
||||||
- HP 7910 Disc Drive Service Manual (07910-90903, Apr-1981)
|
(13365-90901, February 1980)
|
||||||
- 12745D Disc Controller (13037) to HP-IB Adapter Kit Installation and
|
- HP 7910 Disc Drive Service Manual
|
||||||
Service Manual (12745-90911, Sep-1983)
|
(07910-90903, April 1981)
|
||||||
- HP's 5 1/4-Inch Winchester Disc Drive Service Documentation
|
- 12745D Disc Controller (13037) to HP-IB Adapter Kit Installation and Service Manual
|
||||||
(09134-90032, Aug-1983)
|
(12745-90911, September 1983)
|
||||||
- HP 12992 Loader ROMs Installation Manual (12992-90001, Apr-1986)
|
- HP's 5 1/4-Inch Winchester Disc Drive Service Documentation
|
||||||
- RTE Driver DVA32 Source (92084-18708, revision 2540)
|
(09134-90032, August 1983)
|
||||||
- IEEE Standard Digital Interface for Programmable Instrumentation
|
- HP 12992 Loader ROMs Installation Manual
|
||||||
(IEEE-488A-1980, Sep-1979)
|
(12992-90001, April 1986)
|
||||||
|
- RTE Driver DVA32 Source
|
||||||
|
(92084-18708, revision 2540)
|
||||||
|
- IEEE Standard Digital Interface for Programmable Instrumentation
|
||||||
|
(IEEE-488A-1980, September 1979)
|
||||||
|
|
||||||
|
|
||||||
The HP 7906H, 7920H, and 7925H Integrated Controller Disc (ICD) drives were
|
The HP 7906H, 7920H, and 7925H Integrated Controller Disc (ICD) drives were
|
||||||
@@ -1713,7 +1718,7 @@ else { /* it is bus data (A
|
|||||||
if (DEBUG_PRI (da_dev, DEB_XFER))
|
if (DEBUG_PRI (da_dev, DEB_XFER))
|
||||||
sprintf (action, "opcode %02XH", data & DL_OPCODE_MASK);
|
sprintf (action, "opcode %02XH", data & DL_OPCODE_MASK);
|
||||||
|
|
||||||
buffer [0] = SET_UPPER (data); /* set the opcode into the buffer */
|
buffer [0] = TO_WORD (data, 0); /* set the opcode into the buffer */
|
||||||
|
|
||||||
if (dl_prepare_command (&icd_cntlr [unit], /* is the command valid? */
|
if (dl_prepare_command (&icd_cntlr [unit], /* is the command valid? */
|
||||||
da_unit, unit)) {
|
da_unit, unit)) {
|
||||||
@@ -2081,9 +2086,9 @@ static uint8 get_buffer_byte (CVPTR cvptr)
|
|||||||
cvptr->length = cvptr->length - 1; /* count the byte */
|
cvptr->length = cvptr->length - 1; /* count the byte */
|
||||||
|
|
||||||
if (cvptr->length & 1) /* is the upper byte next? */
|
if (cvptr->length & 1) /* is the upper byte next? */
|
||||||
return GET_UPPER (buffer [cvptr->index]); /* return the byte */
|
return UPPER_BYTE (buffer [cvptr->index]); /* return the byte */
|
||||||
else /* the lower byte is next */
|
else /* the lower byte is next */
|
||||||
return GET_LOWER (buffer [cvptr->index++]); /* return the byte and bump the word index */
|
return LOWER_BYTE (buffer [cvptr->index++]); /* return the byte and bump the word index */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2103,9 +2108,9 @@ static void put_buffer_byte (CVPTR cvptr, uint8 data)
|
|||||||
cvptr->length = cvptr->length - 1; /* count the byte */
|
cvptr->length = cvptr->length - 1; /* count the byte */
|
||||||
|
|
||||||
if (cvptr->length & 1) /* is the upper byte next? */
|
if (cvptr->length & 1) /* is the upper byte next? */
|
||||||
buffer [cvptr->index] = SET_UPPER (data); /* save the byte */
|
buffer [cvptr->index] = TO_WORD (data, 0); /* save the byte */
|
||||||
else /* the lower byte is next */
|
else /* the lower byte is next */
|
||||||
buffer [cvptr->index++] |= SET_LOWER (data); /* merge the byte and bump the word index */
|
buffer [cvptr->index++] |= TO_WORD (0, data); /* merge the byte and bump the word index */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* hp2100_disclib.c: HP MAC/ICD disc controller simulator library
|
/* hp2100_disclib.c: HP MAC/ICD disc controller simulator library
|
||||||
|
|
||||||
Copyright (c) 2011-2016, J. David Bryan
|
Copyright (c) 2011-2017, J. David Bryan
|
||||||
Copyright (c) 2004-2011, Robert M. Supnik
|
Copyright (c) 2004-2011, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@@ -24,6 +24,9 @@
|
|||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from the authors.
|
in this Software without prior written authorization from the authors.
|
||||||
|
|
||||||
|
22-Apr-17 JDB A failed sim_fseek call now causes a drive fault
|
||||||
|
09-Mar-17 JDB Added the simulator name to the "perror" message.
|
||||||
|
17-Jan-17 JDB Moved "hp2100_defs.h" inclusion to "hp2100_disclib.c"
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
04-Mar-16 JDB Name changed to "hp2100_disclib" until HP 3000 integration
|
04-Mar-16 JDB Name changed to "hp2100_disclib" until HP 3000 integration
|
||||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||||
@@ -256,6 +259,7 @@
|
|||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "hp2100_defs.h" /* this must reflect the machine used */
|
||||||
#include "hp2100_disclib.h"
|
#include "hp2100_disclib.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -552,7 +556,7 @@ static void start_write (CVPTR cvptr, UNIT *uptr);
|
|||||||
static t_stat end_write (CVPTR cvptr, UNIT *uptr);
|
static t_stat end_write (CVPTR cvptr, UNIT *uptr);
|
||||||
static t_bool position_sector (CVPTR cvptr, UNIT *uptr, t_bool verify);
|
static t_bool position_sector (CVPTR cvptr, UNIT *uptr, t_bool verify);
|
||||||
static void next_sector (CVPTR cvptr, UNIT *uptr);
|
static void next_sector (CVPTR cvptr, UNIT *uptr);
|
||||||
static t_stat io_error (CVPTR cvptr, UNIT *uptr);
|
static t_stat io_error (CVPTR cvptr, UNIT *uptr, CNTLR_STATUS status);
|
||||||
|
|
||||||
/* Disc library local utility routines */
|
/* Disc library local utility routines */
|
||||||
|
|
||||||
@@ -1808,8 +1812,8 @@ count = sim_fread (cvptr->buffer + offset, /* read the sector from
|
|||||||
for (count = count + offset; count < cvptr->length; count++) /* pad the sector as needed */
|
for (count = count + offset; count < cvptr->length; count++) /* pad the sector as needed */
|
||||||
cvptr->buffer [count] = 0; /* e.g., if reading from a new file */
|
cvptr->buffer [count] = 0; /* e.g., if reading from a new file */
|
||||||
|
|
||||||
if (ferror (uptr->fileref)) /* did a host file system error occur? */
|
if (ferror (uptr->fileref)) /* did a host file system error occur? */
|
||||||
return io_error (cvptr, uptr); /* set up the data error status and stop the simulation */
|
return io_error (cvptr, uptr, uncorrectable_data_error); /* set up the data error status and stop the simulation */
|
||||||
|
|
||||||
next_sector (cvptr, uptr); /* address the next sector */
|
next_sector (cvptr, uptr); /* address the next sector */
|
||||||
|
|
||||||
@@ -1985,8 +1989,8 @@ if (cvptr->index < DL_WPSEC + offset) { /* was a partial sector
|
|||||||
sim_fwrite (cvptr->buffer + offset, sizeof (uint16), /* write the sector to the file */
|
sim_fwrite (cvptr->buffer + offset, sizeof (uint16), /* write the sector to the file */
|
||||||
DL_WPSEC, uptr->fileref);
|
DL_WPSEC, uptr->fileref);
|
||||||
|
|
||||||
if (ferror (uptr->fileref)) /* did a host file system error occur? */
|
if (ferror (uptr->fileref)) /* did a host file system error occur? */
|
||||||
return io_error (cvptr, uptr); /* set up the data error status and stop the simulation */
|
return io_error (cvptr, uptr, uncorrectable_data_error); /* set up the data error status and stop the simulation */
|
||||||
|
|
||||||
next_sector (cvptr, uptr); /* address the next sector */
|
next_sector (cvptr, uptr); /* address the next sector */
|
||||||
|
|
||||||
@@ -2036,10 +2040,13 @@ return SCPE_OK;
|
|||||||
error.
|
error.
|
||||||
|
|
||||||
If the addresses are valid, the drive is checked to ensure that it is ready
|
If the addresses are valid, the drive is checked to ensure that it is ready
|
||||||
for positioning. If it is, the the byte offset in the image file is
|
for positioning. If it is, the file is positioned to a byte offset in the
|
||||||
calculated from the CHS address, and the file is positioned. The disc
|
image file that is calculated from the CHS address. If positioning succeeds,
|
||||||
service is scheduled to begin the data transfer, and the routine returns TRUE
|
the disc service is scheduled to begin the data transfer, and the routine
|
||||||
to indicate that the file position was set.
|
returns TRUE to indicate that the file position is set. If positioning fails
|
||||||
|
with a host file system error, it is reported to the simulation console, and
|
||||||
|
the routine returns FALSE to indicate that an AGC (drive positioner) fault
|
||||||
|
occurred.
|
||||||
|
|
||||||
|
|
||||||
Implementation notes:
|
Implementation notes:
|
||||||
@@ -2100,10 +2107,18 @@ else { /* we are ready to posit
|
|||||||
cvptr->sector, model); /* (for inspection only) */
|
cvptr->sector, model); /* (for inspection only) */
|
||||||
uptr->pos = TO_OFFSET (block); /* and then convert to a byte offset */
|
uptr->pos = TO_OFFSET (block); /* and then convert to a byte offset */
|
||||||
|
|
||||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set the image file position */
|
if (sim_fseek (uptr->fileref, uptr->pos, SEEK_SET)) { /* set the image file position; if it failed */
|
||||||
|
io_error (cvptr, uptr, status_2_error); /* then report it to the simulation console */
|
||||||
|
|
||||||
uptr->wait = cvptr->data_time; /* delay for the data access time */
|
dl_load_unload (cvptr, uptr, FALSE); /* unload the heads */
|
||||||
return TRUE; /* and report that positioning was accomplished */
|
uptr->STAT |= DL_S2FAULT; /* and set Fault status */
|
||||||
|
}
|
||||||
|
|
||||||
|
else { /* otherwise the seek succeeded */
|
||||||
|
uptr->wait = cvptr->data_time; /* so delay for the data access time */
|
||||||
|
|
||||||
|
return TRUE; /* report that positioning was accomplished */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE; /* report that positioning failed or was deferred */
|
return FALSE; /* report that positioning failed or was deferred */
|
||||||
@@ -2252,19 +2267,19 @@ return TRUE; /* and report that t
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Report an I/O error.
|
/* Report a stream I/O error.
|
||||||
|
|
||||||
Errors indicated by the host file system are reported to the console, and
|
Errors indicated by the host file system are reported to the console, and
|
||||||
simulation is stopped with an "I/O error" message. If the simulation is
|
simulation is stopped with an "I/O error" message. If the simulation is
|
||||||
continued, the CPU will receive an Uncorrectable Data Error indication from
|
continued, the CPU will receive the supplied status indication from the
|
||||||
the controller.
|
controller.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static t_stat io_error (CVPTR cvptr, UNIT *uptr)
|
static t_stat io_error (CVPTR cvptr, UNIT *uptr, CNTLR_STATUS status)
|
||||||
{
|
{
|
||||||
dl_end_command (cvptr, uncorrectable_data_error); /* terminate the command with an error */
|
dl_end_command (cvptr, status); /* terminate the command with an error */
|
||||||
|
|
||||||
perror ("DiscLib I/O error"); /* report the error to the console */
|
perror ("HP 2100 simulator disc library I/O error"); /* report the error to the console */
|
||||||
clearerr (uptr->fileref); /* and clear the error in case we resume */
|
clearerr (uptr->fileref); /* and clear the error in case we resume */
|
||||||
|
|
||||||
return SCPE_IOERR; /* return an I/O error to stop the simulator */
|
return SCPE_IOERR; /* return an I/O error to stop the simulator */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* hp_disclib.h: HP MAC/ICD disc controller simulator library definitions
|
/* hp_disclib.h: HP MAC/ICD disc controller simulator library declarations
|
||||||
|
|
||||||
Copyright (c) 2011-2016, J. David Bryan
|
Copyright (c) 2011-2017, J. David Bryan
|
||||||
Copyright (c) 2004-2011, Robert M. Supnik
|
Copyright (c) 2004-2011, Robert M. Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from the authors.
|
in this Software without prior written authorization from the authors.
|
||||||
|
|
||||||
|
17-Jan-17 JDB Moved "hp2100_defs.h" inclusion to "hp2100_disclib.c"
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
24-Oct-12 JDB Changed CNTLR_OPCODE to title case to avoid name clash
|
24-Oct-12 JDB Changed CNTLR_OPCODE to title case to avoid name clash
|
||||||
07-May-12 JDB Added end-of-track delay time as a controller variable
|
07-May-12 JDB Added end-of-track delay time as a controller variable
|
||||||
@@ -38,10 +39,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "hp2100_defs.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Program limits */
|
/* Program limits */
|
||||||
|
|
||||||
#define DL_MAXDRIVE 7 /* last valid drive number */
|
#define DL_MAXDRIVE 7 /* last valid drive number */
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/* hp2100_dp.c: HP 2100 12557A/13210A disk simulator
|
/* hp2100_dp.c: HP 2100 12557A/13210A disk simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2016, Robert M. Supnik
|
Copyright (c) 1993-2016, Robert M. Supnik
|
||||||
|
Copyright (c) 2017 J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -26,6 +27,7 @@
|
|||||||
DP 12557A 2870 disk subsystem
|
DP 12557A 2870 disk subsystem
|
||||||
13210A 7900 disk subsystem
|
13210A 7900 disk subsystem
|
||||||
|
|
||||||
|
22-Apr-17 JDB Added fall-through comment for FNC_STA case in dpcio
|
||||||
09-Nov-16 JDB Corrected disk subsystem model number from 2871 to 2870
|
09-Nov-16 JDB Corrected disk subsystem model number from 2871 to 2870
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
30-Dec-14 JDB Added S-register parameters to ibl_copy
|
30-Dec-14 JDB Added S-register parameters to ibl_copy
|
||||||
@@ -647,6 +649,8 @@ while (working_set) {
|
|||||||
if (dp_ctype == A13210) /* 13210? clr dch flag */
|
if (dp_ctype == A13210) /* 13210? clr dch flag */
|
||||||
dpdio (&dpd_dib, ioCLF, 0);
|
dpdio (&dpd_dib, ioCLF, 0);
|
||||||
|
|
||||||
|
/* fall into FNC_CHK and FNC_AR cases */
|
||||||
|
|
||||||
case FNC_CHK: /* check */
|
case FNC_CHK: /* check */
|
||||||
case FNC_AR: /* addr rec */
|
case FNC_AR: /* addr rec */
|
||||||
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
|
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* hp2100_mpx.c: HP 12792C eight-channel asynchronous multiplexer simulator
|
/* hp2100_mpx.c: HP 12792C eight-channel asynchronous multiplexer simulator
|
||||||
|
|
||||||
Copyright (c) 2008-2016, J. David Bryan
|
Copyright (c) 2008-2017, J. David Bryan
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
MPX 12792C 8-channel multiplexer card
|
MPX 12792C 8-channel multiplexer card
|
||||||
|
|
||||||
|
22-Apr-17 JDB Corrected missing compound statements
|
||||||
02-Aug-16 JDB Burst-fill only the first receive buffer in fast mode
|
02-Aug-16 JDB Burst-fill only the first receive buffer in fast mode
|
||||||
28-Jul-16 JDB Fixed buffer ready check at read completion
|
28-Jul-16 JDB Fixed buffer ready check at read completion
|
||||||
Fixed terminate on character counts > 254
|
Fixed terminate on character counts > 254
|
||||||
@@ -1136,7 +1137,7 @@ switch (mpx_cmd) {
|
|||||||
case CMD_CANCEL: /* cancel first read buffer */
|
case CMD_CANCEL: /* cancel first read buffer */
|
||||||
port = key_to_port (mpx_portkey); /* get port */
|
port = key_to_port (mpx_portkey); /* get port */
|
||||||
|
|
||||||
if (port >= 0) /* port defined? */
|
if (port >= 0) { /* port defined? */
|
||||||
buf_cancel (ioread, port, get); /* cancel get buffer */
|
buf_cancel (ioread, port, get); /* cancel get buffer */
|
||||||
|
|
||||||
if (buf_avail (ioread, port) == 2) /* if all buffers are now clear */
|
if (buf_avail (ioread, port) == 2) /* if all buffers are now clear */
|
||||||
@@ -1144,6 +1145,7 @@ switch (mpx_cmd) {
|
|||||||
|
|
||||||
else if (!(mpx_flags [port] & FL_RDFILL)) /* otherwise if the other buffer is not filling */
|
else if (!(mpx_flags [port] & FL_RDFILL)) /* otherwise if the other buffer is not filling */
|
||||||
mpx_flags [port] |= FL_HAVEBUF; /* then indicate buffer availability */
|
mpx_flags [port] |= FL_HAVEBUF; /* then indicate buffer availability */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
@@ -1233,11 +1235,12 @@ switch (mpx_cmd) {
|
|||||||
case CMD_SET_FLOW: /* set flow control */
|
case CMD_SET_FLOW: /* set flow control */
|
||||||
port = key_to_port (mpx_portkey); /* get port */
|
port = key_to_port (mpx_portkey); /* get port */
|
||||||
|
|
||||||
if (port >= 0) /* port defined? */
|
if (port >= 0) { /* port defined? */
|
||||||
mpx_flowcntl [port] = mpx_param & FC_XONXOFF; /* save port flow control */
|
mpx_flowcntl [port] = mpx_param & FC_XONXOFF; /* save port flow control */
|
||||||
|
|
||||||
if (mpx_param & FC_FORCE_XON) /* force XON? */
|
if (mpx_param & FC_FORCE_XON) /* force XON? */
|
||||||
mpx_flags [port] &= ~FL_XOFF; /* resume transmission if suspended */
|
mpx_flags [port] &= ~FL_XOFF; /* resume transmission if suspended */
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
SIMH/HP 2100 RELEASE NOTES
|
SIMH/HP 2100 RELEASE NOTES
|
||||||
==========================
|
==========================
|
||||||
Last update: 2017-01-11
|
Last update: 2017-05-01
|
||||||
|
|
||||||
|
|
||||||
This file documents the release history of the simulator for the Hewlett-Packard
|
This file documents the release history of the simulator for the Hewlett-Packard
|
||||||
@@ -12,7 +12,7 @@ simulator code base is available at:
|
|||||||
https://github.com/simh/simh
|
https://github.com/simh/simh
|
||||||
|
|
||||||
...and may be downloaded at any time. A code snapshot is identified by the "git
|
...and may be downloaded at any time. A code snapshot is identified by the "git
|
||||||
commit ID" that is displayed by the simulator welcome banner.
|
commit ID" that is displayed in the simulator welcome banner.
|
||||||
|
|
||||||
Therefore, HP 2100 releases are simply documentation checkpoints that describe
|
Therefore, HP 2100 releases are simply documentation checkpoints that describe
|
||||||
the changes that have occurred since the last checkpoint. Generally, a release
|
the changes that have occurred since the last checkpoint. Generally, a release
|
||||||
@@ -22,6 +22,25 @@ of the next release document.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
===============================
|
||||||
|
Reporting Bugs in the Simulator
|
||||||
|
===============================
|
||||||
|
|
||||||
|
If you find a bug in the HP 2100 simulator, please report it either to the SIMH
|
||||||
|
issue tracker on github at:
|
||||||
|
|
||||||
|
https://github.com/simh/simh/issues
|
||||||
|
|
||||||
|
...or to the SIMH mailing list; see:
|
||||||
|
|
||||||
|
http://mailman.trailing-edge.com/mailman/listinfo/simh
|
||||||
|
|
||||||
|
...for subscribing information. In either case, please include a console log
|
||||||
|
that contains a reproducible test case that illustrates the problem. See the
|
||||||
|
"Recording Simulator Activities" section of the "SIMH User's Guide" for details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
===================
|
===================
|
||||||
General Information
|
General Information
|
||||||
===================
|
===================
|
||||||
@@ -35,11 +54,13 @@ diagnostic tests. See the accompanying "hp2100_diag.txt" file for details.
|
|||||||
|
|
||||||
The simulator has been tested with the following operating systems:
|
The simulator has been tested with the following operating systems:
|
||||||
|
|
||||||
|
- SIO, BCS, and MTS.
|
||||||
|
|
||||||
- 2000E, 2000F, and 2000/Access Time-Shared BASIC.
|
- 2000E, 2000F, and 2000/Access Time-Shared BASIC.
|
||||||
|
|
||||||
- DOS, DOS-M, and DOS-III.
|
- DOS, DOS-M, and DOS-III.
|
||||||
|
|
||||||
- RTE-II, RTE-III, RTE-IVB, and RTE-6/VM.
|
- RTE, RTE-B, RTE-C, RTE-II, RTE-III, RTE-IV, RTE-IVB, and RTE-6/VM.
|
||||||
|
|
||||||
The user's manual for the simulator is provided in Microsoft Word format in the
|
The user's manual for the simulator is provided in Microsoft Word format in the
|
||||||
"doc" subdirectory of the code base snapshot downloaded from the github site. A
|
"doc" subdirectory of the code base snapshot downloaded from the github site. A
|
||||||
@@ -136,6 +157,148 @@ Revision 5010:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
======================
|
||||||
|
Release 26, 2017-05-01
|
||||||
|
======================
|
||||||
|
|
||||||
|
This release of the HP 2100 simulator does not add any new features.
|
||||||
|
|
||||||
|
|
||||||
|
--------------------
|
||||||
|
Implementation Notes
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
- Starting with the next release, the LOAD command will be rewritten to load
|
||||||
|
files containing absolute binary loaders into the protected address space of
|
||||||
|
the 21xx machines and configure the I/O instructions. The LOAD command is
|
||||||
|
not designed for general loading of absolute binary files, as it does not
|
||||||
|
initialize the A and B registers as some HP software expects. It is intended
|
||||||
|
only to install bootstrap loaders. The BOOT PTR command is the proper
|
||||||
|
simulation of the hardware absolute paper tape loader.
|
||||||
|
|
||||||
|
|
||||||
|
----------
|
||||||
|
Bugs Fixed
|
||||||
|
----------
|
||||||
|
|
||||||
|
1. PROBLEM: The RWCS debug option shown in the user's guide does not exist.
|
||||||
|
|
||||||
|
VERSION: Release 25.
|
||||||
|
|
||||||
|
OBSERVATION: The "HP2100 Simulator User's Guide" says that the RWCS debug
|
||||||
|
option may be specified for the DS and DA devices to trace "disk read/
|
||||||
|
write/control/status commands." However, entering a SET DS DEBUG=RWCS
|
||||||
|
command gives an "Invalid argument" error.
|
||||||
|
|
||||||
|
CAUSE: The option name is misspelled; the correct option is RWSC.
|
||||||
|
|
||||||
|
RESOLUTION: Modify "hp2100_doc.doc" to list the correct option name.
|
||||||
|
|
||||||
|
STATUS: Fixed in Release 26.
|
||||||
|
|
||||||
|
|
||||||
|
2. PROBLEM: Halt opcodes 1060xx and 1070xx do not display in mnemonic form.
|
||||||
|
|
||||||
|
VERSION: Release 25.
|
||||||
|
|
||||||
|
OBSERVATION: Halt instructions 106000-106077 and 107000-107077 are not
|
||||||
|
displayed in mnemonic form, either directly with an EXAMINE -M command
|
||||||
|
or in the message displayed for a programmed halt. These instruction
|
||||||
|
ranges are displayed in octal only.
|
||||||
|
|
||||||
|
CAUSE: Section 3.20, "Input/Output Instructions," of the "HP 1000
|
||||||
|
M/E/F-Series Computers Technical Reference Handbook" (HP 5955-0282, March
|
||||||
|
1980) says, in part, "Bit 11, where relevant, specifies the A- or
|
||||||
|
B-register or distinguishes between set control and clear control;
|
||||||
|
otherwise, bit 11 may be a logic 0 or a logic 1 without affecting the
|
||||||
|
instruction (although the assembler will assign zeros in this case)." The
|
||||||
|
HLT instruction does not specify the A/B register, so the valid opcodes are
|
||||||
|
102000-102077, 103000-103777, 106000-106077, and 107000-107077. However,
|
||||||
|
the latter two ranges are omitted from the "opcode" and "opc_val" tables
|
||||||
|
used for decoding.
|
||||||
|
|
||||||
|
RESOLUTION: Add the 1060xx/107xx range to the "opc_val" table and a second
|
||||||
|
"HLT" string to the "opcode" table (hp2100_sys.c) to permit mnemonic
|
||||||
|
display of this instruction range.
|
||||||
|
|
||||||
|
STATUS: Fixed in Release 26.
|
||||||
|
|
||||||
|
|
||||||
|
3. PROBLEM: The SFB (scan for byte) opcode displays as SBT (store byte).
|
||||||
|
|
||||||
|
VERSION: Release 25.
|
||||||
|
|
||||||
|
OBSERVATION: Entering the "EVAL -M 105767" command should display the
|
||||||
|
"SFB" mnemonic. Instead, it displays "SBT".
|
||||||
|
|
||||||
|
CAUSE: The entry in the opcode mnemonic table corresponding to the 105767
|
||||||
|
value is "SBT", which is incorrect. It should be "SFB" (SBT is 105764).
|
||||||
|
|
||||||
|
RESOLUTION: Modify the "opcode" table (hp2100_sys.c) to use the correct
|
||||||
|
mnemonic for the SFB instruction.
|
||||||
|
|
||||||
|
STATUS: Fixed in Release 26.
|
||||||
|
|
||||||
|
|
||||||
|
4. PROBLEM: Host file system seek errors are not caught.
|
||||||
|
|
||||||
|
VERSION: Release 25.
|
||||||
|
|
||||||
|
OBSERVATION: The MAC/ICD disc library checks for host file system read or
|
||||||
|
write errors and returns Uncorrectable Data Error status if an error is
|
||||||
|
indicated. However, host file system seeks are simply assumed to succeed;
|
||||||
|
no indication of an error is given if a call fails. A failed seek should
|
||||||
|
be detected, and a Drive Fault (positioner error) should be returned.
|
||||||
|
|
||||||
|
CAUSE: Oversight.
|
||||||
|
|
||||||
|
RESOLUTION: Modify "position_sector" (hp2100_disclib.c) to test the
|
||||||
|
"sim_fseek" call for error status and to simulate a Drive Fault (AGC error)
|
||||||
|
if the call fails.
|
||||||
|
|
||||||
|
STATUS: Fixed in Release 26.
|
||||||
|
|
||||||
|
|
||||||
|
5. PROBLEM: Set Flow Control and Cancel commands fail if port key is not set.
|
||||||
|
|
||||||
|
VERSION: Release 25.
|
||||||
|
|
||||||
|
OBSERVATION: HP 8-channel multiplexer commands that refer to ports do so
|
||||||
|
indirectly by passing a port key, rather than a port number. The
|
||||||
|
key-to-port translation is established by the "Set Port Key" command, which
|
||||||
|
must be executed before any port-specific commands. If a port key has not
|
||||||
|
been established, then all port-specific commands should be ignored.
|
||||||
|
However, the "Cancel first receive buffer" and "Set flow control" commands
|
||||||
|
cause program corruption if the key has not been set.
|
||||||
|
|
||||||
|
CAUSE: The test for key validity is improperly applied for these commands.
|
||||||
|
|
||||||
|
RESOLUTION: Modify "exec_command" (hp2100_mpx.c) to ignore these commands
|
||||||
|
if the port key has not been set.
|
||||||
|
|
||||||
|
STATUS: Fixed in Release 26.
|
||||||
|
|
||||||
|
|
||||||
|
6. ENHANCEMENT: Improve the EAU shift and rotate instruction simulations.
|
||||||
|
|
||||||
|
VERSION: Release 25.
|
||||||
|
|
||||||
|
OBSERVATION: The shift and rotate instructions (ASL, ASR, LSL, LSR, RRL,
|
||||||
|
and RRR) perform 32-bit operations on the combined B and A registers. The
|
||||||
|
original implementation treated the 16-bit registers independently.
|
||||||
|
However, it is faster and smaller to form a 32-bit operand, apply the
|
||||||
|
operation, and then split the operand back into the B and A registers.
|
||||||
|
Modern compilers, such as gcc, recognize the shifting and masking patterns
|
||||||
|
necessary for a rotation and generate a single rotate-left or rotate-right
|
||||||
|
machine instruction.
|
||||||
|
|
||||||
|
RESOLUTION: Modify "cpu_eau" (hp2100_cpu1.c) to reimplement the shift and
|
||||||
|
rotate instructions as 32-bit operations.
|
||||||
|
|
||||||
|
STATUS: Fixed in Release 26.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
======================
|
======================
|
||||||
Release 25, 2017-01-11
|
Release 25, 2017-01-11
|
||||||
======================
|
======================
|
||||||
@@ -144,42 +307,42 @@ This is the initial checkpoint release of the HP 2100 simulator, corresponding
|
|||||||
to the 25th set of changes to the 4.0 code base. The following devices are
|
to the 25th set of changes to the 4.0 code base. The following devices are
|
||||||
currently simulated:
|
currently simulated:
|
||||||
|
|
||||||
- 2114C CPU with up to 16 KW of memory
|
- 2114C CPU with up to 16 KW of memory
|
||||||
- 2115A CPU with up to 8 KW of memory
|
- 2115A CPU with up to 8 KW of memory
|
||||||
- 2116C CPU with up to 32 KW of memory
|
- 2116C CPU with up to 32 KW of memory
|
||||||
- 2100A CPU with up to 32 KW of memory
|
- 2100A CPU with up to 32 KW of memory
|
||||||
- 1000 M/E/F-Series CPU with up to 1024 KW of memory
|
- 1000 M/E/F-Series CPU with up to 1024 KW of memory
|
||||||
- EAU, FP, IOP, DMS, FFP, DBI, VIS, and SIGNAL microcode extensions
|
- EAU, FP, IOP, DMS, FFP, DBI, VIS, and SIGNAL microcode extensions
|
||||||
- RTE-IV EMA or RTE-6/VM OS and VMA microcode extensions
|
- RTE-IV EMA or RTE-6/VM OS and VMA microcode extensions
|
||||||
- 12531C Buffered Teleprinter Interface with one 2752 Teleprinter
|
- 12531C Buffered Teleprinter Interface with one 2752 Teleprinter
|
||||||
- 12539C Time Base Generator
|
- 12539C Time Base Generator
|
||||||
- 12557A Disc Controller with four 2870 drives
|
- 12557A Disc Controller with four 2870 drives
|
||||||
- 12559C Magnetic Tape Controller with one 3030 drive
|
- 12559C Magnetic Tape Controller with one 3030 drive
|
||||||
- 12565A Disc Controller with two 2883 drives
|
- 12565A Disc Controller with two 2883 drives
|
||||||
- 12566B Microcircuit Interface with a loopback connector
|
- 12566B Microcircuit Interface with a loopback connector
|
||||||
- 12578A Direct Memory Access Controller
|
- 12578A Direct Memory Access Controller
|
||||||
- 12581A Memory Protect
|
- 12581A Memory Protect
|
||||||
- 12597A Duplex Register Interface with one 2748 Paper Tape Reader
|
- 12597A Duplex Register Interface with one 2748 Paper Tape Reader
|
||||||
- 12597A Duplex Register Interface with one 2895 Paper Tape Punch
|
- 12597A Duplex Register Interface with one 2895 Paper Tape Punch
|
||||||
- 12606B Fixed Head Disc Controller with one 2770/2771 drive
|
- 12606B Fixed Head Disc Controller with one 2770/2771 drive
|
||||||
- 12607B Direct Memory Access Controller
|
- 12607B Direct Memory Access Controller
|
||||||
- 12610B Drum Controller with one 2773/2774/2775 drive
|
- 12610B Drum Controller with one 2773/2774/2775 drive
|
||||||
- 12620A Privileged Interrupt Fence
|
- 12620A Privileged Interrupt Fence
|
||||||
- 12653A Printer Controller with one 2767 Line Printer
|
- 12653A Printer Controller with one 2767 Line Printer
|
||||||
- 12792C 8-Channel Asynchronous Multiplexer
|
- 12792C 8-Channel Asynchronous Multiplexer
|
||||||
- 12821A Disc Interface with four 7906H/7920H/7925H drives
|
- 12821A Disc Interface with four 7906H/7920H/7925H drives
|
||||||
- 12845B Printer Controller with one 2607 Line Printer
|
- 12845B Printer Controller with one 2607 Line Printer
|
||||||
- 12875A Interprocessor Link
|
- 12875A Interprocessor Link
|
||||||
- 12892B Memory Protect
|
- 12892B Memory Protect
|
||||||
- 12895A Direct Memory Access Controller
|
- 12895A Direct Memory Access Controller
|
||||||
- 12897B Dual-Channel Port Controller
|
- 12897B Dual-Channel Port Controller
|
||||||
- 12920A 16-Channel Terminal Multiplexer
|
- 12920A 16-Channel Terminal Multiplexer
|
||||||
- 12936A Privileged Interrupt Fence
|
- 12936A Privileged Interrupt Fence
|
||||||
- 12966A Buffered Asynchronous Communications Interface
|
- 12966A Buffered Asynchronous Communications Interface
|
||||||
- 13037D Disc Controller with eight 7905/7906/7920/7925 drives
|
- 13037D Disc Controller with eight 7905/7906/7920/7925 drives
|
||||||
- 13181A Magnetic Tape Controller with four 7970B drives
|
- 13181A Magnetic Tape Controller with four 7970B drives
|
||||||
- 13183A Magnetic Tape Controller with four 7970E drives
|
- 13183A Magnetic Tape Controller with four 7970E drives
|
||||||
- 13210A Disc Controller with four 7900 drives
|
- 13210A Disc Controller with four 7900 drives
|
||||||
|
|
||||||
The "HP 2100 Simulator User's Guide" manual describes the configuration and
|
The "HP 2100 Simulator User's Guide" manual describes the configuration and
|
||||||
operation of each of these devices in detail.
|
operation of each of these devices in detail.
|
||||||
@@ -194,12 +357,11 @@ Implementation Notes
|
|||||||
|
|
||||||
- Starting with the next release, the LOAD command will restrict its operation
|
- Starting with the next release, the LOAD command will restrict its operation
|
||||||
to the addresses occupied by the bootstrap loaders, i.e., the last 64
|
to the addresses occupied by the bootstrap loaders, i.e., the last 64
|
||||||
locations in memory (up to 32K), unless forced by the addition of the "-F"
|
locations in memory (up to 32K). The LOAD command is not designed for
|
||||||
switch. The LOAD command is not designed for general loading of absolute
|
general loading of absolute binary files, as it does not initialize the A and
|
||||||
binary files, as it does not initialize the A and B registers as some HP
|
B registers as some HP software expects. It is intended only to install
|
||||||
software expects. It is intended only to install bootstrap loaders. The
|
bootstrap loaders. The BOOT PTR command is the proper simulation of the
|
||||||
BOOT PTR command is the proper simulation of the hardware absolute paper tape
|
hardware absolute paper tape loader.
|
||||||
loader.
|
|
||||||
|
|
||||||
|
|
||||||
----------
|
----------
|
||||||
|
|||||||
@@ -24,6 +24,8 @@
|
|||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
in this Software without prior written authorization from Robert M Supnik.
|
||||||
|
|
||||||
|
15-Jan-17 JDB Corrected HLT decoding to add the 1060xx and 1070xx ranges
|
||||||
|
Corrected SFB decoding
|
||||||
14-Jan-17 JDB Removed use of Fprintf functions for version 4.x and on
|
14-Jan-17 JDB Removed use of Fprintf functions for version 4.x and on
|
||||||
30-Dec-16 JDB Corrected parsing of memory reference instructions
|
30-Dec-16 JDB Corrected parsing of memory reference instructions
|
||||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||||
@@ -294,7 +296,7 @@ static const char *opcode[] = {
|
|||||||
"FAD", "FSB", "FMP", "FDV",
|
"FAD", "FSB", "FMP", "FDV",
|
||||||
"FIX", "FLT",
|
"FIX", "FLT",
|
||||||
"STO", "CLO", "SOC", "SOS",
|
"STO", "CLO", "SOC", "SOS",
|
||||||
"HLT", "STF", "CLF",
|
"HLT", "HLT", "STF", "CLF", /* 2nd HLT is 1060xx and 1070xx ranges */
|
||||||
"SFC", "SFS", "MIA", "MIB",
|
"SFC", "SFS", "MIA", "MIB",
|
||||||
"LIA", "LIB", "OTA", "OTB",
|
"LIA", "LIB", "OTA", "OTB",
|
||||||
"STC", "CLC",
|
"STC", "CLC",
|
||||||
@@ -319,7 +321,7 @@ static const char *opcode[] = {
|
|||||||
"CYA", "CYB", "LDY",
|
"CYA", "CYB", "LDY",
|
||||||
"ADY", "XAY", "XBY",
|
"ADY", "XAY", "XBY",
|
||||||
"ISX", "DSX", "JLY", "LBT",
|
"ISX", "DSX", "JLY", "LBT",
|
||||||
"SBT", "MBT", "CBT", "SBT",
|
"SBT", "MBT", "CBT", "SFB",
|
||||||
"ISY", "DSY", "JPY", "SBS",
|
"ISY", "DSY", "JPY", "SBS",
|
||||||
"CBS", "TBS", "CMW", "MVW",
|
"CBS", "TBS", "CMW", "MVW",
|
||||||
NULL, /* decode only */
|
NULL, /* decode only */
|
||||||
@@ -353,7 +355,7 @@ static const int32 opc_val[] = {
|
|||||||
0105000+I_EMR, 0105020+I_EMR, 0105040+I_EMR, 0105060+I_EMR,
|
0105000+I_EMR, 0105020+I_EMR, 0105040+I_EMR, 0105060+I_EMR,
|
||||||
0105100+I_NPN, 0105120+I_NPN,
|
0105100+I_NPN, 0105120+I_NPN,
|
||||||
0102101+I_NPN, 0103101+I_NPN, 0102201+I_NPC, 0102301+I_NPC,
|
0102101+I_NPN, 0103101+I_NPN, 0102201+I_NPC, 0102301+I_NPC,
|
||||||
0102000+I_IO1, 0102100+I_IO2, 0103100+I_IO2,
|
0102000+I_IO1, 0106000+I_IO1, 0102100+I_IO2, 0103100+I_IO2,
|
||||||
0102200+I_IO1, 0102300+I_IO1, 0102400+I_IO1, 0106400+I_IO1,
|
0102200+I_IO1, 0102300+I_IO1, 0102400+I_IO1, 0106400+I_IO1,
|
||||||
0102500+I_IO1, 0106500+I_IO1, 0102600+I_IO1, 0106600+I_IO1,
|
0102500+I_IO1, 0106500+I_IO1, 0102600+I_IO1, 0106600+I_IO1,
|
||||||
0102700+I_IO1, 0106700+I_IO1,
|
0102700+I_IO1, 0106700+I_IO1,
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user