1
0
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:
Mark Pizzolato
2017-05-01 15:47:33 -07:00
parent af54a5c8fd
commit 90e9c2f4a0
13 changed files with 780 additions and 262 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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? */

View File

@@ -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 */

View File

@@ -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;
} }

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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;

View File

@@ -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.
---------- ----------

View File

@@ -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.