mirror of
https://github.com/simh/simh.git
synced 2026-01-11 23:52:58 +00:00
HP2100: HP 2100 release 26
See HP2100/hp2100_release.txt for details of the release
This commit is contained in:
parent
af54a5c8fd
commit
90e9c2f4a0
@ -1,6 +1,9 @@
|
||||
HP 2100 SIMULATOR FIXES
|
||||
=======================
|
||||
Last update: 2016-08-05
|
||||
HP 2100 SIMULATOR FIX ARCHIVE
|
||||
=============================
|
||||
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,30 +1,33 @@
|
||||
/* hp2100_cpu1.c: HP 2100/1000 EAU simulator and UIG dispatcher
|
||||
|
||||
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
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
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
|
||||
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
|
||||
|
||||
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"
|
||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||
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
|
||||
E/F-series microcode execute a NOP for this instruction code.
|
||||
|
||||
Notes:
|
||||
|
||||
1. Under simulation, TIMER, DIAG, and EXECUTE cause undefined instruction
|
||||
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.
|
||||
Implementation notes:
|
||||
|
||||
2. DIAG is not implemented under simulation. On the E/F, it performs a
|
||||
destructive test of all installed memory. Because of this, it is only
|
||||
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.
|
||||
1. Under simulation, TIMER, DIAG, and EXECUTE cause undefined instruction
|
||||
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.
|
||||
|
||||
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.
|
||||
2. DIAG is not implemented under simulation. On the E/F, it performs a
|
||||
destructive test of all installed memory. Because of this, it is only
|
||||
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 reason = SCPE_OK;
|
||||
OPS op;
|
||||
uint32 rs, qs, sc, v1, v2, t;
|
||||
uint32 rs, qs, v1, v2, operand, fill, mask, shift;
|
||||
int32 sop1, sop2;
|
||||
|
||||
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 */
|
||||
else
|
||||
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> */
|
||||
|
||||
case 0200: /* EAU group 0 */
|
||||
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
|
||||
|
||||
case 000: /* DIAG 100000 */
|
||||
if ((UNIT_CPU_MODEL != UNIT_1000_E) && /* must be 1000 E-series */
|
||||
(UNIT_CPU_MODEL != UNIT_1000_F)) /* or 1000 F-series */
|
||||
return stop_inst; /* trap if not */
|
||||
break; /* DIAG is NOP unless halted */
|
||||
case 000: /* DIAG 100000 */
|
||||
if ((UNIT_CPU_MODEL != UNIT_1000_E) && /* must be 1000 E-series */
|
||||
(UNIT_CPU_MODEL != UNIT_1000_F)) /* or 1000 F-series */
|
||||
return stop_inst; /* trap if not */
|
||||
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 */
|
||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
||||
BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK;
|
||||
AR = (AR << sc) & DMASK; /* BR'AR lsh left */
|
||||
break;
|
||||
case 001: /* ASL 100020-100037 */
|
||||
operand = TO_DWORD (BR, AR); /* form the double-word operand */
|
||||
|
||||
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 M-series? */
|
||||
goto MPY; /* decode as MPY */
|
||||
BR = (BR + 1) & DMASK; /* increment B */
|
||||
if (BR) PR = err_PC; /* if !=0, repeat */
|
||||
break;
|
||||
mask = D32_UMAX << 31 - shift; /* form a mask for the bits that will be lost */
|
||||
|
||||
case 004: /* RRL 100100-100117 */
|
||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
||||
t = BR; /* BR'AR rot left */
|
||||
BR = ((BR << sc) | (AR >> (16 - sc))) & DMASK;
|
||||
AR = ((AR << sc) | (t >> (16 - sc))) & DMASK;
|
||||
break;
|
||||
if (operand & D32_SIGN) /* if the operand is negative */
|
||||
O = (~operand & mask & D32_MASK) != 0; /* then set overflow if any of the lost bits are zeros */
|
||||
else /* otherwise it's positive */
|
||||
O = (operand & mask & D32_MASK) != 0; /* so set overflow if any of the lost bits are ones */
|
||||
|
||||
case 010: /* MPY 100200 (OP_K) */
|
||||
MPY:
|
||||
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;
|
||||
operand = operand << shift & D32_SMAX /* shift the operand left */
|
||||
| operand & D32_SIGN; /* while keeping the original sign bit */
|
||||
|
||||
default: /* others undefined */
|
||||
return stop_inst;
|
||||
BR = UPPER_WORD (operand); /* split the operand */
|
||||
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;
|
||||
|
||||
|
||||
case 0201: /* DIV 100400 (OP_K) */
|
||||
reason = cpu_ops (OP_K, op, intrq); /* get operand */
|
||||
|
||||
if (reason != SCPE_OK) /* eval failed? */
|
||||
break;
|
||||
|
||||
rs = qs = BR & SIGN; /* save divd sign */
|
||||
|
||||
if (rs) { /* neg? */
|
||||
AR = (~AR + 1) & DMASK; /* make B'A pos */
|
||||
BR = (~BR + (AR == 0)) & DMASK; /* make divd pos */
|
||||
}
|
||||
|
||||
v2 = op[0].word; /* divr = mem */
|
||||
|
||||
if (v2 & SIGN) { /* neg? */
|
||||
v2 = (~v2 + 1) & DMASK; /* make divr pos */
|
||||
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... */
|
||||
O = 0; /* assume ok */
|
||||
v1 = (BR << 16) | AR; /* 32b divd */
|
||||
AR = (v1 / v2) & DMASK; /* quotient */
|
||||
BR = (v1 % v2) & DMASK; /* remainder */
|
||||
|
||||
if (AR) { /* quotient > 0? */
|
||||
if (qs) AR = (~AR + 1) & DMASK; /* apply quo sign */
|
||||
if ((AR ^ qs) & SIGN) O = 1; /* still wrong? ovflo */
|
||||
if (qs) /* apply quo sign */
|
||||
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;
|
||||
|
||||
|
||||
case 0202: /* EAU group 2 */
|
||||
switch ((IR >> 4) & 017) { /* decode IR<7:4> */
|
||||
|
||||
case 001: /* ASR 101020-101037 */
|
||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
||||
AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK;
|
||||
BR = (SEXT (BR) >> sc) & DMASK; /* BR'AR ash right */
|
||||
O = 0;
|
||||
break;
|
||||
case 001: /* ASR 101020-101037 */
|
||||
O = 0; /* clear ovflo */
|
||||
|
||||
case 002: /* LSR 101040-101057 */
|
||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
||||
AR = ((BR << (16 - sc)) | (AR >> sc)) & DMASK;
|
||||
BR = BR >> sc; /* BR'AR log right */
|
||||
break;
|
||||
operand = TO_DWORD (BR, AR); /* form the double-word operand */
|
||||
fill = (operand & D32_SIGN ? ~0 : 0); /* and fill with copies of the sign bit */
|
||||
|
||||
case 004: /* RRR 101100-101117 */
|
||||
sc = (IR & 017)? (IR & 017): 16; /* get sc */
|
||||
t = AR; /* BR'AR rot right */
|
||||
AR = ((AR >> sc) | (BR << (16 - sc))) & DMASK;
|
||||
BR = ((BR >> sc) | (t << (16 - sc))) & DMASK;
|
||||
break;
|
||||
operand = operand >> shift /* shift the operand right */
|
||||
| fill << 32 - shift; /* while filling in with sign bits */
|
||||
|
||||
default: /* others undefined */
|
||||
return stop_inst;
|
||||
BR = UPPER_WORD (operand); /* split the operand */
|
||||
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;
|
||||
|
||||
|
||||
case 0210: /* DLD 104200 (OP_D) */
|
||||
reason = cpu_ops (OP_D, op, intrq); /* get operand */
|
||||
|
||||
if (reason == SCPE_OK) { /* successful eval? */
|
||||
AR = (op[0].dword >> 16) & DMASK; /* load AR */
|
||||
BR = op[0].dword & DMASK; /* load BR */
|
||||
AR = UPPER_WORD (op[0].dword); /* load AR */
|
||||
BR = LOWER_WORD (op[0].dword); /* load BR */
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case 0211: /* DST 104400 (OP_A) */
|
||||
reason = cpu_ops (OP_A, op, intrq); /* get operand */
|
||||
|
||||
if (reason == SCPE_OK) { /* successful eval? */
|
||||
WriteW (op[0].word, AR); /* store AR */
|
||||
WriteW ((op[0].word + 1) & VAMASK, BR); /* store BR */
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default: /* should never get here */
|
||||
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
|
||||
------------- ---------------------------- ------ ------ ------
|
||||
10x400-10x437 2000 IOP opt opt opt
|
||||
10x460-10x477 2000 IOP opt opt opt
|
||||
10x400-10x437 2000 IOP opt opt -
|
||||
10x460-10x477 2000 IOP opt opt -
|
||||
10x460-10x477 Vector Instruction Set - - opt
|
||||
10x520-10x537 Distributed System 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) 2017 J. David Bryan
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
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
|
||||
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"
|
||||
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
|
||||
@ -71,9 +73,80 @@
|
||||
15-Oct-00 RMS Added dynamic device numbers
|
||||
14-Apr-99 RMS Changed t_addr to unsigned
|
||||
|
||||
The author gratefully acknowledges the help of Jeff Moffat in answering
|
||||
questions about the HP2100; and of Dave Bryan in adding features and
|
||||
correcting errors throughout the simulator.
|
||||
The [original] author gratefully acknowledges the help of Jeff Moffat in
|
||||
answering questions about the HP2100; and of Dave Bryan in adding features
|
||||
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
|
||||
not be, in my opinion. They warn about the use of perfectly valid code and
|
||||
require the addition of redundant parentheses and braces to silence them.
|
||||
Rather than clutter up the code with scores of extra symbols that, in my
|
||||
view, make the code harder to read and maintain, I elect to suppress these
|
||||
warnings.
|
||||
/* The following pragmas quell clang and Microsoft Visual C++ warnings that are
|
||||
on by default but should not be, in my opinion. They warn about the use of
|
||||
perfectly valid code and require the addition of redundant parentheses and
|
||||
braces to silence them. Rather than clutter up the code with scores of extra
|
||||
symbols that, in my view, make the code harder to read and maintain, I elect
|
||||
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__)
|
||||
#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
|
||||
#pragma clang diagnostic ignored "-Wbitwise-op-parentheses"
|
||||
#pragma clang diagnostic ignored "-Wdangling-else"
|
||||
#pragma clang diagnostic ignored "-Wlogical-op-parentheses"
|
||||
#pragma clang diagnostic ignored "-Wbitwise-op-parentheses"
|
||||
#pragma clang diagnostic ignored "-Wshift-op-parentheses"
|
||||
#pragma clang diagnostic ignored "-Wdangling-else"
|
||||
|
||||
#elif defined (_MSC_VER)
|
||||
#pragma warning (disable: 4114 4554 4996)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -114,6 +201,181 @@
|
||||
#define STOP_PWROFF 9 /* device powered off */
|
||||
#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 */
|
||||
|
||||
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
|
||||
@ -134,13 +396,6 @@
|
||||
#define DMAX 0077777 /* 16b maximum signed 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 */
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
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
|
||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||
Removed redundant global declarations
|
||||
@ -33,10 +34,10 @@
|
||||
09-Oct-10 JDB Created DI simulation
|
||||
|
||||
References:
|
||||
- HP 12821A Disc Interface Installation and Service Manual (12821-90006,
|
||||
Feb-1985)
|
||||
- IEEE Standard Digital Interface for Programmable Instrumentation
|
||||
(IEEE-488A-1980, Sep-1979)
|
||||
- HP 12821A Disc Interface Installation and Service Manual
|
||||
(12821-90006, February 1985)
|
||||
- IEEE Standard Digital Interface for Programmable Instrumentation
|
||||
(IEEE-488A-1980, September 1979)
|
||||
|
||||
|
||||
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, */
|
||||
&& di_card->bus_cntl & BUS_EOI) /* and data was tagged with EOI? */
|
||||
|| (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 */
|
||||
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? */
|
||||
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 */
|
||||
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 */
|
||||
}
|
||||
}
|
||||
@ -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->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 */
|
||||
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? */
|
||||
di_card->fifo [index] = tag | data; /* store the tag and full word in the FIFO */
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
@ -1814,19 +1815,19 @@ if (access == cpu_access) { /* is this a cpu access?
|
||||
else if (access == bus_access) /* is this a bus access? */
|
||||
if (di_card->obp == upper) { /* is this the upper byte? */
|
||||
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 */
|
||||
}
|
||||
|
||||
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? */
|
||||
di_card->obp = upper; /* set the upper byte as next */
|
||||
}
|
||||
|
||||
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? */
|
||||
|
||||
@ -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
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
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
|
||||
14-Feb-12 JDB First release
|
||||
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 */
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
||||
typedef struct {
|
||||
FLIP_FLOP control; /* control flip-flop */
|
||||
FLIP_FLOP flag; /* flag flip-flop */
|
||||
FLIP_FLOP flagbuf; /* flag buffer flip-flop */
|
||||
FLIP_FLOP srq; /* SRQ flip-flop */
|
||||
FLIP_FLOP edt; /* EDT flip-flop */
|
||||
FLIP_FLOP eor; /* EOR flip-flop */
|
||||
SELECTOR ibp; /* input byte pointer selector */
|
||||
SELECTOR obp; /* output byte pointer selector */
|
||||
FLIP_FLOP control; /* control flip-flop */
|
||||
FLIP_FLOP flag; /* flag flip-flop */
|
||||
FLIP_FLOP flagbuf; /* flag buffer flip-flop */
|
||||
FLIP_FLOP srq; /* SRQ flip-flop */
|
||||
FLIP_FLOP edt; /* EDT flip-flop */
|
||||
FLIP_FLOP eor; /* EOR flip-flop */
|
||||
BYTE_SELECTOR ibp; /* input byte pointer selector */
|
||||
BYTE_SELECTOR obp; /* output byte pointer selector */
|
||||
|
||||
uint16 cntl_register; /* control 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
|
||||
|
||||
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
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
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
|
||||
04-Mar-16 JDB Name changed to "hp2100_disclib" until HP 3000 integration
|
||||
30-Dec-14 JDB Added S-register parameters to ibl_copy
|
||||
@ -36,16 +37,20 @@
|
||||
04-Nov-11 JDB Created DA device
|
||||
|
||||
References:
|
||||
- HP 13365 Integrated Controller Programming Guide (13365-90901, Feb-1980)
|
||||
- HP 7910 Disc Drive Service Manual (07910-90903, Apr-1981)
|
||||
- 12745D Disc Controller (13037) to HP-IB Adapter Kit Installation and
|
||||
Service Manual (12745-90911, Sep-1983)
|
||||
- HP's 5 1/4-Inch Winchester Disc Drive Service Documentation
|
||||
(09134-90032, Aug-1983)
|
||||
- HP 12992 Loader ROMs Installation Manual (12992-90001, Apr-1986)
|
||||
- RTE Driver DVA32 Source (92084-18708, revision 2540)
|
||||
- IEEE Standard Digital Interface for Programmable Instrumentation
|
||||
(IEEE-488A-1980, Sep-1979)
|
||||
- HP 13365 Integrated Controller Programming Guide
|
||||
(13365-90901, February 1980)
|
||||
- HP 7910 Disc Drive Service Manual
|
||||
(07910-90903, April 1981)
|
||||
- 12745D Disc Controller (13037) to HP-IB Adapter Kit Installation and Service Manual
|
||||
(12745-90911, September 1983)
|
||||
- HP's 5 1/4-Inch Winchester Disc Drive Service Documentation
|
||||
(09134-90032, August 1983)
|
||||
- HP 12992 Loader ROMs Installation Manual
|
||||
(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
|
||||
@ -1713,7 +1718,7 @@ else { /* it is bus data (A
|
||||
if (DEBUG_PRI (da_dev, DEB_XFER))
|
||||
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? */
|
||||
da_unit, unit)) {
|
||||
@ -2081,9 +2086,9 @@ static uint8 get_buffer_byte (CVPTR cvptr)
|
||||
cvptr->length = cvptr->length - 1; /* count the byte */
|
||||
|
||||
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 */
|
||||
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 */
|
||||
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
|
||||
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
|
||||
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
|
||||
04-Mar-16 JDB Name changed to "hp2100_disclib" until HP 3000 integration
|
||||
24-Dec-14 JDB Added casts for explicit downward conversions
|
||||
@ -256,6 +259,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "hp2100_defs.h" /* this must reflect the machine used */
|
||||
#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_bool position_sector (CVPTR cvptr, UNIT *uptr, t_bool verify);
|
||||
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 */
|
||||
|
||||
@ -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 */
|
||||
cvptr->buffer [count] = 0; /* e.g., if reading from a new file */
|
||||
|
||||
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 */
|
||||
if (ferror (uptr->fileref)) /* did a host file system error occur? */
|
||||
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 */
|
||||
|
||||
@ -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 */
|
||||
DL_WPSEC, uptr->fileref);
|
||||
|
||||
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 */
|
||||
if (ferror (uptr->fileref)) /* did a host file system error occur? */
|
||||
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 */
|
||||
|
||||
@ -2036,10 +2040,13 @@ return SCPE_OK;
|
||||
error.
|
||||
|
||||
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
|
||||
calculated from the CHS address, and the file is positioned. The disc
|
||||
service is scheduled to begin the data transfer, and the routine returns TRUE
|
||||
to indicate that the file position was set.
|
||||
for positioning. If it is, the file is positioned to a byte offset in the
|
||||
image file that is calculated from the CHS address. If positioning succeeds,
|
||||
the disc service is scheduled to begin the data transfer, and the routine
|
||||
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:
|
||||
@ -2100,10 +2107,18 @@ else { /* we are ready to posit
|
||||
cvptr->sector, model); /* (for inspection only) */
|
||||
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 */
|
||||
return TRUE; /* and report that positioning was accomplished */
|
||||
dl_load_unload (cvptr, uptr, FALSE); /* unload the heads */
|
||||
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 */
|
||||
@ -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
|
||||
simulation is stopped with an "I/O error" message. If the simulation is
|
||||
continued, the CPU will receive an Uncorrectable Data Error indication from
|
||||
the controller.
|
||||
continued, the CPU will receive the supplied status indication from the
|
||||
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 */
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
@ -38,10 +39,6 @@
|
||||
|
||||
|
||||
|
||||
#include "hp2100_defs.h"
|
||||
|
||||
|
||||
|
||||
/* Program limits */
|
||||
|
||||
#define DL_MAXDRIVE 7 /* last valid drive number */
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* hp2100_dp.c: HP 2100 12557A/13210A disk simulator
|
||||
|
||||
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
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -26,6 +27,7 @@
|
||||
DP 12557A 2870 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
|
||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||
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 */
|
||||
dpdio (&dpd_dib, ioCLF, 0);
|
||||
|
||||
/* fall into FNC_CHK and FNC_AR cases */
|
||||
|
||||
case FNC_CHK: /* check */
|
||||
case FNC_AR: /* addr rec */
|
||||
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* 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
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
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
|
||||
28-Jul-16 JDB Fixed buffer ready check at read completion
|
||||
Fixed terminate on character counts > 254
|
||||
@ -1136,7 +1137,7 @@ switch (mpx_cmd) {
|
||||
case CMD_CANCEL: /* cancel first read buffer */
|
||||
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 */
|
||||
|
||||
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 */
|
||||
mpx_flags [port] |= FL_HAVEBUF; /* then indicate buffer availability */
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@ -1233,11 +1235,12 @@ switch (mpx_cmd) {
|
||||
case CMD_SET_FLOW: /* set flow control */
|
||||
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 */
|
||||
|
||||
if (mpx_param & FC_FORCE_XON) /* force XON? */
|
||||
mpx_flags [port] &= ~FL_XOFF; /* resume transmission if suspended */
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
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
|
||||
@ -12,7 +12,7 @@ simulator code base is available at:
|
||||
https://github.com/simh/simh
|
||||
|
||||
...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
|
||||
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
|
||||
===================
|
||||
@ -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:
|
||||
|
||||
- SIO, BCS, and MTS.
|
||||
|
||||
- 2000E, 2000F, and 2000/Access Time-Shared BASIC.
|
||||
|
||||
- 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
|
||||
"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
|
||||
======================
|
||||
@ -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
|
||||
currently simulated:
|
||||
|
||||
- 2114C CPU with up to 16 KW of memory
|
||||
- 2115A CPU with up to 8 KW of memory
|
||||
- 2116C 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
|
||||
- EAU, FP, IOP, DMS, FFP, DBI, VIS, and SIGNAL microcode extensions
|
||||
- RTE-IV EMA or RTE-6/VM OS and VMA microcode extensions
|
||||
- 12531C Buffered Teleprinter Interface with one 2752 Teleprinter
|
||||
- 12539C Time Base Generator
|
||||
- 12557A Disc Controller with four 2870 drives
|
||||
- 12559C Magnetic Tape Controller with one 3030 drive
|
||||
- 12565A Disc Controller with two 2883 drives
|
||||
- 12566B Microcircuit Interface with a loopback connector
|
||||
- 12578A Direct Memory Access Controller
|
||||
- 12581A Memory Protect
|
||||
- 12597A Duplex Register Interface with one 2748 Paper Tape Reader
|
||||
- 12597A Duplex Register Interface with one 2895 Paper Tape Punch
|
||||
- 12606B Fixed Head Disc Controller with one 2770/2771 drive
|
||||
- 12607B Direct Memory Access Controller
|
||||
- 12610B Drum Controller with one 2773/2774/2775 drive
|
||||
- 12620A Privileged Interrupt Fence
|
||||
- 12653A Printer Controller with one 2767 Line Printer
|
||||
- 12792C 8-Channel Asynchronous Multiplexer
|
||||
- 12821A Disc Interface with four 7906H/7920H/7925H drives
|
||||
- 12845B Printer Controller with one 2607 Line Printer
|
||||
- 12875A Interprocessor Link
|
||||
- 12892B Memory Protect
|
||||
- 12895A Direct Memory Access Controller
|
||||
- 12897B Dual-Channel Port Controller
|
||||
- 12920A 16-Channel Terminal Multiplexer
|
||||
- 12936A Privileged Interrupt Fence
|
||||
- 12966A Buffered Asynchronous Communications Interface
|
||||
- 13037D Disc Controller with eight 7905/7906/7920/7925 drives
|
||||
- 13181A Magnetic Tape Controller with four 7970B drives
|
||||
- 13183A Magnetic Tape Controller with four 7970E drives
|
||||
- 13210A Disc Controller with four 7900 drives
|
||||
- 2114C CPU with up to 16 KW of memory
|
||||
- 2115A CPU with up to 8 KW of memory
|
||||
- 2116C 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
|
||||
- EAU, FP, IOP, DMS, FFP, DBI, VIS, and SIGNAL microcode extensions
|
||||
- RTE-IV EMA or RTE-6/VM OS and VMA microcode extensions
|
||||
- 12531C Buffered Teleprinter Interface with one 2752 Teleprinter
|
||||
- 12539C Time Base Generator
|
||||
- 12557A Disc Controller with four 2870 drives
|
||||
- 12559C Magnetic Tape Controller with one 3030 drive
|
||||
- 12565A Disc Controller with two 2883 drives
|
||||
- 12566B Microcircuit Interface with a loopback connector
|
||||
- 12578A Direct Memory Access Controller
|
||||
- 12581A Memory Protect
|
||||
- 12597A Duplex Register Interface with one 2748 Paper Tape Reader
|
||||
- 12597A Duplex Register Interface with one 2895 Paper Tape Punch
|
||||
- 12606B Fixed Head Disc Controller with one 2770/2771 drive
|
||||
- 12607B Direct Memory Access Controller
|
||||
- 12610B Drum Controller with one 2773/2774/2775 drive
|
||||
- 12620A Privileged Interrupt Fence
|
||||
- 12653A Printer Controller with one 2767 Line Printer
|
||||
- 12792C 8-Channel Asynchronous Multiplexer
|
||||
- 12821A Disc Interface with four 7906H/7920H/7925H drives
|
||||
- 12845B Printer Controller with one 2607 Line Printer
|
||||
- 12875A Interprocessor Link
|
||||
- 12892B Memory Protect
|
||||
- 12895A Direct Memory Access Controller
|
||||
- 12897B Dual-Channel Port Controller
|
||||
- 12920A 16-Channel Terminal Multiplexer
|
||||
- 12936A Privileged Interrupt Fence
|
||||
- 12966A Buffered Asynchronous Communications Interface
|
||||
- 13037D Disc Controller with eight 7905/7906/7920/7925 drives
|
||||
- 13181A Magnetic Tape Controller with four 7970B drives
|
||||
- 13183A Magnetic Tape Controller with four 7970E drives
|
||||
- 13210A Disc Controller with four 7900 drives
|
||||
|
||||
The "HP 2100 Simulator User's Guide" manual describes the configuration and
|
||||
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
|
||||
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"
|
||||
switch. 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.
|
||||
locations in memory (up to 32K). 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.
|
||||
|
||||
|
||||
----------
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
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
|
||||
30-Dec-16 JDB Corrected parsing of memory reference instructions
|
||||
13-May-16 JDB Modified for revised SCP API function parameter types
|
||||
@ -294,7 +296,7 @@ static const char *opcode[] = {
|
||||
"FAD", "FSB", "FMP", "FDV",
|
||||
"FIX", "FLT",
|
||||
"STO", "CLO", "SOC", "SOS",
|
||||
"HLT", "STF", "CLF",
|
||||
"HLT", "HLT", "STF", "CLF", /* 2nd HLT is 1060xx and 1070xx ranges */
|
||||
"SFC", "SFS", "MIA", "MIB",
|
||||
"LIA", "LIB", "OTA", "OTB",
|
||||
"STC", "CLC",
|
||||
@ -319,7 +321,7 @@ static const char *opcode[] = {
|
||||
"CYA", "CYB", "LDY",
|
||||
"ADY", "XAY", "XBY",
|
||||
"ISX", "DSX", "JLY", "LBT",
|
||||
"SBT", "MBT", "CBT", "SBT",
|
||||
"SBT", "MBT", "CBT", "SFB",
|
||||
"ISY", "DSY", "JPY", "SBS",
|
||||
"CBS", "TBS", "CMW", "MVW",
|
||||
NULL, /* decode only */
|
||||
@ -353,7 +355,7 @@ static const int32 opc_val[] = {
|
||||
0105000+I_EMR, 0105020+I_EMR, 0105040+I_EMR, 0105060+I_EMR,
|
||||
0105100+I_NPN, 0105120+I_NPN,
|
||||
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,
|
||||
0102500+I_IO1, 0106500+I_IO1, 0102600+I_IO1, 0106600+I_IO1,
|
||||
0102700+I_IO1, 0106700+I_IO1,
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user