mirror of
https://github.com/open-simh/simh.git
synced 2026-04-29 05:15:30 +00:00
Notes For V3.4-0
The memory layout for the Interdata simulators has been changed. Do not use Interdata SAVE files from prior revisions with V3.4. 1. New Features in 3.4 1.1 SCP and Libraries - Revised interpretation of fprint_sym, fparse_sym returns - Revised syntax for SET DEBUG - DO command nesting allowed to ten levels 1.2 Interdata - Revised memory model to be 16b instead of 8b 1.3 HP2100 - Added Fast FORTRAN Processor instructions - Added SET OFFLINE/ONLINE and SET UNLOAD/LOAD commands to tapes and disks 2. Bugs Fixed in 3.4-0 2.1 Interdata - Fixed bug in show history routine (from Mark Hittinger) - Fixed bug in initial memory allocation 2.2 PDP-10 - Fixed TU bug, ERASE and WREOF should not clear done (reported by Rich Alderson) - Fixed TU error reporting 2.3 PDP-11 - Fixed TU error reporting
This commit is contained in:
committed by
Mark Pizzolato
parent
098200a126
commit
ec60bbf329
@@ -27,6 +27,7 @@
|
||||
MP 12892B memory protect
|
||||
DMA0,DMA1 12895A/12897B direct memory access/dual channel port controller
|
||||
|
||||
21-Jan-05 JDB Reorganized CPU option flags
|
||||
15-Jan-05 RMS Split out EAU and MAC instructions
|
||||
26-Dec-04 RMS DMA reset doesn't clear alternate CTL flop (from Dave Bryan)
|
||||
DMA reset shouldn't clear control words (from Dave Bryan)
|
||||
@@ -340,9 +341,16 @@
|
||||
#define UNIT_MP_INT (1 << UNIT_V_MP_INT)
|
||||
#define UNIT_MP_SEL1 (1 << UNIT_V_MP_SEL1)
|
||||
|
||||
#define MOD_2116 1
|
||||
#define MOD_2100 2
|
||||
#define MOD_21MX 4
|
||||
#define MOD_211X (1 << TYPE_211X)
|
||||
#define MOD_2100 (1 << TYPE_2100)
|
||||
#define MOD_21MX (1 << TYPE_21MX)
|
||||
#define MOD_CURRENT (1 << CPU_TYPE)
|
||||
|
||||
#define UNIT_SYSTEM (UNIT_CPU_MASK | UNIT_OPTS)
|
||||
#define UNIT_SYS_2116 (UNIT_2116)
|
||||
#define UNIT_SYS_2100 (UNIT_2100 | UNIT_EAU)
|
||||
#define UNIT_SYS_21MX_M (UNIT_21MX_M | UNIT_EAU | UNIT_FP | UNIT_DMS)
|
||||
#define UNIT_SYS_21MX_E (UNIT_21MX_E | UNIT_EAU | UNIT_FP | UNIT_DMS)
|
||||
|
||||
#define ABORT(val) longjmp (save_env, (val))
|
||||
|
||||
@@ -396,13 +404,14 @@ struct opt_table { /* options table */
|
||||
int32 cpuf; };
|
||||
|
||||
static struct opt_table opt_val[] = {
|
||||
{ UNIT_EAU, MOD_2116 },
|
||||
{ UNIT_EAU, MOD_211X },
|
||||
{ UNIT_FP, MOD_2100 },
|
||||
{ UNIT_DMS, MOD_21MX },
|
||||
{ UNIT_IOP, MOD_2100 | MOD_21MX },
|
||||
{ UNIT_2116, MOD_2116 | MOD_2100 | MOD_21MX },
|
||||
{ UNIT_2100, MOD_2116 | MOD_2100 | MOD_21MX },
|
||||
{ UNIT_21MX, MOD_2116 | MOD_2100 | MOD_21MX },
|
||||
{ UNIT_FFP, MOD_2100 | MOD_21MX },
|
||||
{ TYPE_211X, MOD_211X | MOD_2100 | MOD_21MX },
|
||||
{ TYPE_2100, MOD_211X | MOD_2100 | MOD_21MX },
|
||||
{ TYPE_21MX, MOD_211X | MOD_2100 | MOD_21MX },
|
||||
{ 0, 0 } };
|
||||
|
||||
extern int32 sim_interval;
|
||||
@@ -415,7 +424,7 @@ extern DEVICE *sim_devices[];
|
||||
extern int32 sim_switches;
|
||||
extern char halt_msg[];
|
||||
|
||||
t_stat Ea1 (uint32 *addr, uint32 irq);
|
||||
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq);
|
||||
uint16 ReadIO (uint32 addr, uint32 map);
|
||||
uint16 ReadPW (uint32 addr);
|
||||
uint16 ReadTAB (uint32 addr);
|
||||
@@ -440,7 +449,8 @@ t_bool dev_conflict (void);
|
||||
void hp_post_cmd (t_bool from_scp);
|
||||
|
||||
extern t_stat cpu_eau (uint32 IR, uint32 intrq);
|
||||
extern t_stat cpu_mac (uint32 IR, uint32 intrq);
|
||||
extern t_stat cpu_uig_0 (uint32 IR, uint32 intrq);
|
||||
extern t_stat cpu_uig_1 (uint32 IR, uint32 intrq);
|
||||
extern int32 clk_delay (int32 flg);
|
||||
extern void (*sim_vm_post) (t_bool from_scp);
|
||||
|
||||
@@ -495,49 +505,50 @@ REG cpu_reg[] = {
|
||||
{ NULL } };
|
||||
|
||||
MTAB cpu_mod[] = {
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
||||
UNIT_2116, NULL, "2116", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_2116 },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
||||
UNIT_2100+UNIT_EAU, NULL, "2100", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_2100 },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
||||
UNIT_21MX+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-E", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_21MX },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS+UNIT_IOP+UNIT_IOPX,
|
||||
UNIT_21MX+UNIT_MXM+UNIT_EAU+UNIT_FP+UNIT_DMS, NULL, "21MX-M", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_21MX },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2116, "2116", NULL, NULL },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX, UNIT_2100, "2100", NULL, NULL },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX, "21MX-E", NULL, NULL },
|
||||
{ UNIT_2116+UNIT_2100+UNIT_21MX+UNIT_MXM, UNIT_21MX+UNIT_MXM, "21MX-M", NULL, NULL },
|
||||
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_EAU },
|
||||
{ UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_EAU },
|
||||
{ UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_FP },
|
||||
{ UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_FP },
|
||||
{ UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_DMS },
|
||||
{ UNIT_DMS, 0, "no DMS", "NODMS", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_DMS },
|
||||
{ UNIT_MSIZE, 2, NULL, "IOP", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_IOP },
|
||||
{ UNIT_IOP+UNIT_IOPX, UNIT_IOP, "IOP", NULL, NULL },
|
||||
{ UNIT_IOP+UNIT_IOPX, UNIT_IOPX,"IOP", NULL, NULL },
|
||||
{ UNIT_IOP+UNIT_IOPX, 0, "no IOP", "NOIOP", &cpu_set_opt,
|
||||
NULL, (void *) UNIT_IOP },
|
||||
{ UNIT_MSIZE, 4096, NULL, "4K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 65536, NULL, "64K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 131072, NULL, "128K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 262144, NULL, "256K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 524288, NULL, "512K", &cpu_set_size },
|
||||
{ UNIT_MSIZE, 1048576, NULL, "1024K", &cpu_set_size },
|
||||
{ UNIT_SYSTEM, UNIT_SYS_2116, NULL, "2116", &cpu_set_opt, NULL,
|
||||
(void *) TYPE_211X },
|
||||
{ UNIT_SYSTEM, UNIT_SYS_2100, NULL, "2100", &cpu_set_opt, NULL,
|
||||
(void *) TYPE_2100 },
|
||||
{ UNIT_SYSTEM, UNIT_SYS_21MX_E, NULL, "21MX-E", &cpu_set_opt, NULL,
|
||||
(void *) TYPE_21MX },
|
||||
{ UNIT_SYSTEM, UNIT_SYS_21MX_M, NULL, "21MX-M", &cpu_set_opt, NULL,
|
||||
(void *) TYPE_21MX },
|
||||
|
||||
{ UNIT_CPU_MASK, UNIT_2116, "2116", NULL, NULL },
|
||||
{ UNIT_CPU_MASK, UNIT_2100, "2100", NULL, NULL },
|
||||
{ UNIT_CPU_MASK, UNIT_21MX_E, "21MX-E", NULL, NULL },
|
||||
{ UNIT_CPU_MASK, UNIT_21MX_M, "21MX-M", NULL, NULL },
|
||||
|
||||
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_EAU },
|
||||
{ UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_EAU },
|
||||
{ UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_FP },
|
||||
{ UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_FP },
|
||||
{ UNIT_IOP, UNIT_IOP, "IOP", "IOP", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_IOP },
|
||||
{ UNIT_IOP, 0, "no IOP", "NOIOP", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_IOP },
|
||||
{ UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_DMS },
|
||||
{ UNIT_DMS, 0, "no DMS", "NODMS", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_DMS },
|
||||
{ UNIT_FFP, UNIT_FFP, "FFP", "FFP", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_FFP },
|
||||
{ UNIT_FFP, 0, "no FFP", "NOFFP", &cpu_set_opt, NULL,
|
||||
(void *) UNIT_FFP },
|
||||
|
||||
{ MTAB_XTD | MTAB_VDV, 4096, NULL, "4K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 8192, NULL, "8K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 16384, NULL, "16K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 32768, NULL, "32K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 65536, NULL, "64K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 131072, NULL, "128K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 262144, NULL, "256K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 524288, NULL, "512K", &cpu_set_size },
|
||||
{ MTAB_XTD | MTAB_VDV, 1048576, NULL, "1024K", &cpu_set_size },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE cpu_dev = {
|
||||
@@ -1006,10 +1017,15 @@ case 0211: /* DST */
|
||||
|
||||
/* Extended instructions */
|
||||
|
||||
case 0212: /* MAC0 ext */
|
||||
case 0203: /* MAC1 ext */
|
||||
case 0212: /* UIG 0 extension */
|
||||
reason = cpu_uig_0 (IR, intrq); /* extended opcode */
|
||||
dmarq = calc_dma (); /* recalc DMA masks */
|
||||
intrq = calc_int (); /* recalc interrupts */
|
||||
break;
|
||||
|
||||
case 0203: /* UIG 1 extension */
|
||||
case 0213:
|
||||
reason = cpu_mac (IR, intrq); /* extended opcode */
|
||||
reason = cpu_uig_1 (IR, intrq); /* extended opcode */
|
||||
dmarq = calc_dma (); /* recalc DMA masks */
|
||||
intrq = calc_int (); /* recalc interrupts */
|
||||
break; } /* end case IR */
|
||||
@@ -1043,14 +1059,12 @@ pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||
return reason;
|
||||
}
|
||||
|
||||
/* Effective address calculation */
|
||||
/* Resolve indirect addresses */
|
||||
|
||||
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq)
|
||||
t_stat resolve (uint32 MA, uint32 *addr, uint32 irq)
|
||||
{
|
||||
uint32 i, MA;
|
||||
uint32 i;
|
||||
|
||||
MA = IR & (I_IA | I_DISP); /* ind + disp */
|
||||
if (IR & I_CP) MA = ((PC - 1) & I_PAGENO) | MA; /* current page? */
|
||||
for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */
|
||||
if (irq && /* int req? */
|
||||
((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */
|
||||
@@ -1062,23 +1076,15 @@ if (i >= ind_max) return STOP_IND; /* indirect loop? */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Effective address, two words */
|
||||
/* Get effective address from IR */
|
||||
|
||||
t_stat Ea1 (uint32 *addr, uint32 irq)
|
||||
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq)
|
||||
{
|
||||
uint32 i, MA;
|
||||
uint32 MA;
|
||||
|
||||
MA = ReadW (PC); /* get next address */
|
||||
PC = (PC + 1) & VAMASK;
|
||||
for (i = 0; (i < ind_max) && (MA & I_IA); i++) { /* resolve multilevel */
|
||||
if (irq && /* int req? */
|
||||
((i >= 2) || (mp_unit.flags & UNIT_MP_INT)) && /* ind > 3 or W6 out? */
|
||||
!(mp_unit.flags & DEV_DIS)) /* MP installed? */
|
||||
return STOP_INDINT; /* break out */
|
||||
MA = ReadW (MA & VAMASK); }
|
||||
if (i >= ind_max) return STOP_IND; /* indirect loop? */
|
||||
*addr = MA;
|
||||
return SCPE_OK;
|
||||
MA = IR & (I_IA | I_DISP); /* ind + disp */
|
||||
if (IR & I_CP) MA = ((PC - 1) & I_PAGENO) | MA; /* current page? */
|
||||
return resolve (MA, addr, irq); /* resolve indirects */
|
||||
}
|
||||
|
||||
/* Shift micro operation */
|
||||
@@ -1181,7 +1187,7 @@ return r;
|
||||
to request an interrupt. This is the masked under the
|
||||
result from #1 to determine the highest priority interrupt,
|
||||
if any.
|
||||
*/
|
||||
*/
|
||||
|
||||
uint32 calc_int (void)
|
||||
{
|
||||
@@ -1550,7 +1556,7 @@ case ioLIX: /* load */
|
||||
dat = SR;
|
||||
break;
|
||||
case ioOTX: /* output */
|
||||
if (cpu_unit.flags & (UNIT_2100 | UNIT_21MX)) SR = dat;
|
||||
if (UNIT_CPU_TYPE != UNIT_TYPE_211X) SR = dat;
|
||||
break;
|
||||
default:
|
||||
break; }
|
||||
@@ -1663,7 +1669,7 @@ case ioSFS: /* skip flag set */
|
||||
case ioLIX: /* load */
|
||||
dat = 0;
|
||||
case ioMIX: /* merge */
|
||||
if (cpu_unit.flags & UNIT_21MX) dat = DMASK;
|
||||
if (UNIT_CPU_TYPE == UNIT_TYPE_21MX) dat = DMASK;
|
||||
break;
|
||||
case ioOTX: /* output */
|
||||
dmac[ch].cw1 = dat;
|
||||
@@ -1748,7 +1754,8 @@ case ioSFC: /* skip flag clear */
|
||||
case ioLIX: /* load */
|
||||
dat = 0;
|
||||
case ioMIX: /* merge */
|
||||
if ((devd < VARDEV) && (cpu_unit.flags & UNIT_21MX)) dat = DMASK;
|
||||
if ((devd < VARDEV) && (UNIT_CPU_TYPE == UNIT_TYPE_21MX))
|
||||
dat = DMASK;
|
||||
break;
|
||||
default:
|
||||
break; }
|
||||
@@ -1854,7 +1861,7 @@ int32 mc = 0;
|
||||
uint32 i;
|
||||
|
||||
if ((val <= 0) || (val > PASIZE) || ((val & 07777) != 0) ||
|
||||
(!(uptr->flags & UNIT_21MX) && (val > VASIZE)))
|
||||
((UNIT_CPU_TYPE != UNIT_TYPE_21MX) && (val > VASIZE)))
|
||||
return SCPE_ARG;
|
||||
if (!(sim_switches & SWMASK ('F'))) { /* force truncation? */
|
||||
for (i = val; i < MEMSIZE; i++) mc = mc | M[i];
|
||||
@@ -1947,33 +1954,35 @@ return FALSE;
|
||||
|
||||
/* Configuration validation
|
||||
|
||||
Memory is trimmed to 32K if 2116 or 2100 is selected.
|
||||
Memory protect is enabled if 2100 or 21MX or DMS is selected.
|
||||
DMA is enabled if 2116 or 2100 or 21MX is selected. */
|
||||
- Checks that the current CPU type supports the option selected.
|
||||
- Ensures that FP/FFP and IOP are mutually exclusive if CPU is 2100.
|
||||
- Disables memory protect if 2116 is selected.
|
||||
- Enables memory protect if 2100 or 21MX or DMS is selected.
|
||||
- Enables DMA if 2116 or 2100 or 21MX is selected.
|
||||
- Memory is trimmed to 32K if 2116 or 2100 is selected. */
|
||||
|
||||
t_bool cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 opt = (int32) desc;
|
||||
int32 mod, i;
|
||||
int32 i;
|
||||
uint32 mod;
|
||||
|
||||
mod = MOD_2116;
|
||||
if (uptr->flags & UNIT_2100) mod = MOD_2100;
|
||||
else if (uptr->flags & UNIT_21MX) mod = MOD_21MX;
|
||||
mod = MOD_CURRENT;
|
||||
for (i = 0; opt_val[i].cpuf != 0; i++) {
|
||||
if ((opt == opt_val[i].optf) && (mod & opt_val[i].cpuf)) {
|
||||
if ((mod == MOD_2100) && (val == UNIT_FP))
|
||||
uptr->flags = uptr->flags & ~UNIT_IOP;
|
||||
if ((opt == UNIT_IOP) && val) {
|
||||
if (mod == MOD_2100)
|
||||
uptr->flags = (uptr->flags & ~UNIT_FP) | UNIT_IOP;
|
||||
if (mod == MOD_21MX) uptr->flags |= UNIT_IOPX; }
|
||||
if (opt == UNIT_2116) mp_dev.flags = mp_dev.flags | DEV_DIS;
|
||||
else if ((val == UNIT_DMS) || (opt == UNIT_2100) || (opt == UNIT_21MX))
|
||||
if (mod == MOD_2100)
|
||||
if ((opt == UNIT_FP) || (opt == UNIT_FFP))
|
||||
uptr->flags = uptr->flags & ~UNIT_IOP;
|
||||
else if (opt == UNIT_IOP)
|
||||
uptr->flags = uptr->flags & ~(UNIT_FP | UNIT_FFP);
|
||||
if (opt == TYPE_211X)
|
||||
mp_dev.flags = mp_dev.flags | DEV_DIS;
|
||||
else if ((opt == UNIT_DMS) || (opt == TYPE_2100) || (opt == TYPE_21MX))
|
||||
mp_dev.flags = mp_dev.flags & ~DEV_DIS;
|
||||
if ((opt == UNIT_2116) || (opt == UNIT_2100) || (opt == UNIT_21MX)) {
|
||||
if ((opt == TYPE_211X) || (opt == TYPE_2100) || (opt == TYPE_21MX)) {
|
||||
dma0_dev.flags = dma0_dev.flags & ~DEV_DIS;
|
||||
dma1_dev.flags = dma1_dev.flags & ~DEV_DIS; }
|
||||
if (((opt == UNIT_2116) || (opt == UNIT_2100)) && (MEMSIZE > VASIZE))
|
||||
if (((opt == TYPE_211X) || (opt == TYPE_2100)) && (MEMSIZE > VASIZE))
|
||||
return cpu_set_size (uptr, VASIZE, cptr, desc);
|
||||
return SCPE_OK; } }
|
||||
return SCPE_NOFNC;
|
||||
|
||||
@@ -23,37 +23,67 @@
|
||||
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.
|
||||
|
||||
21-Jan-05 JDB Reorganized CPU option flags
|
||||
14-Jan-05 RMS Cloned from hp2100_cpu.c
|
||||
|
||||
CPU models are broken down into type and series to facilitate option
|
||||
validation. Bits 3:2 encode the type, and bits 1:0 encode the series
|
||||
within the type.
|
||||
*/
|
||||
|
||||
#ifndef _HP2100_CPU_H_
|
||||
#define _HP2100_CPU_H_ 0
|
||||
|
||||
#define CPU_V_SERIES 0
|
||||
#define CPU_V_TYPE 2
|
||||
|
||||
#define TYPE_211X 0 /* 2114, 2115, 2116 */
|
||||
#define TYPE_2100 1 /* 2100A, 2100S */
|
||||
#define TYPE_21MX 2 /* 21MX-M, 21MX-E, 21MX-F */
|
||||
#define TYPE_1000A 3 /* A600, A700, A900, A990 */
|
||||
|
||||
#define CPU_2116 (TYPE_211X << CPU_V_TYPE | 0)
|
||||
#define CPU_2100 (TYPE_2100 << CPU_V_TYPE | 0)
|
||||
#define CPU_21MX_M (TYPE_21MX << CPU_V_TYPE | 0)
|
||||
#define CPU_21MX_E (TYPE_21MX << CPU_V_TYPE | 1)
|
||||
|
||||
#define UNIT_V_CPU (UNIT_V_UF + 0) /* CPU model bits 0-3 */
|
||||
#define UNIT_M_CPU 017 /* CPU model mask */
|
||||
#define UNIT_M_TYPE 014 /* CPU type mask */
|
||||
#define UNIT_V_EAU (UNIT_V_UF + 4) /* EAU installed */
|
||||
#define UNIT_V_FP (UNIT_V_UF + 5) /* FP installed */
|
||||
#define UNIT_V_IOP (UNIT_V_UF + 6) /* IOP installed */
|
||||
#define UNIT_V_DMS (UNIT_V_UF + 7) /* DMS installed */
|
||||
#define UNIT_V_FFP (UNIT_V_UF + 8) /* FFP installed */
|
||||
|
||||
#define UNIT_CPU_MASK (UNIT_M_CPU << UNIT_V_CPU)
|
||||
#define UNIT_2116 (CPU_2116 << UNIT_V_CPU)
|
||||
#define UNIT_2100 (CPU_2100 << UNIT_V_CPU)
|
||||
#define UNIT_21MX_M (CPU_21MX_M << UNIT_V_CPU)
|
||||
#define UNIT_21MX_E (CPU_21MX_E << UNIT_V_CPU)
|
||||
|
||||
#define UNIT_TYPE_MASK (UNIT_M_TYPE << UNIT_V_CPU)
|
||||
#define UNIT_TYPE_211X ((TYPE_211X << CPU_V_TYPE) << UNIT_V_CPU)
|
||||
#define UNIT_TYPE_2100 ((TYPE_2100 << CPU_V_TYPE) << UNIT_V_CPU)
|
||||
#define UNIT_TYPE_21MX ((TYPE_21MX << CPU_V_TYPE) << UNIT_V_CPU)
|
||||
|
||||
#define UNIT_CPU_MODEL (cpu_unit.flags & UNIT_CPU_MASK)
|
||||
#define UNIT_CPU_TYPE (cpu_unit.flags & UNIT_TYPE_MASK)
|
||||
#define CPU_TYPE (UNIT_CPU_TYPE >> (UNIT_V_CPU + CPU_V_TYPE))
|
||||
|
||||
#define UNIT_EAU (1 << UNIT_V_EAU)
|
||||
#define UNIT_FP (1 << UNIT_V_FP)
|
||||
#define UNIT_IOP (1 << UNIT_V_IOP)
|
||||
#define UNIT_DMS (1 << UNIT_V_DMS)
|
||||
#define UNIT_FFP (1 << UNIT_V_FFP)
|
||||
|
||||
#define UNIT_OPTS (UNIT_EAU | UNIT_FP | UNIT_IOP | UNIT_DMS | UNIT_FFP)
|
||||
|
||||
#define PCQ_SIZE 64 /* must be 2**n */
|
||||
#define PCQ_MASK (PCQ_SIZE - 1)
|
||||
#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = err_PC
|
||||
|
||||
#define UNIT_V_2100 (UNIT_V_UF + 0) /* 2100 */
|
||||
#define UNIT_V_21MX (UNIT_V_UF + 1) /* 21MX-E or 21MX-M */
|
||||
#define UNIT_V_EAU (UNIT_V_UF + 2) /* EAU */
|
||||
#define UNIT_V_FP (UNIT_V_UF + 3) /* FP */
|
||||
#define UNIT_V_DMS (UNIT_V_UF + 4) /* DMS */
|
||||
#define UNIT_V_IOP (UNIT_V_UF + 5) /* 2100 IOP */
|
||||
#define UNIT_V_IOPX (UNIT_V_UF + 6) /* 21MX IOP */
|
||||
#define UNIT_V_MSIZE (UNIT_V_UF + 7) /* dummy mask */
|
||||
#define UNIT_V_MXM (UNIT_V_UF + 8) /* 21MX is M-series */
|
||||
#define UNIT_2116 (0)
|
||||
#define UNIT_2100 (1 << UNIT_V_2100)
|
||||
#define UNIT_21MX (1 << UNIT_V_21MX)
|
||||
#define UNIT_EAU (1 << UNIT_V_EAU)
|
||||
#define UNIT_FP (1 << UNIT_V_FP)
|
||||
#define UNIT_DMS (1 << UNIT_V_DMS)
|
||||
#define UNIT_IOP (1 << UNIT_V_IOP)
|
||||
#define UNIT_IOPX (1 << UNIT_V_IOPX)
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
#define UNIT_MXM (1 << UNIT_V_MXM)
|
||||
|
||||
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq);
|
||||
t_stat resolve (uint32 MA, uint32 *addr, uint32 irq);
|
||||
uint8 ReadB (uint32 addr);
|
||||
uint8 ReadBA (uint32 addr);
|
||||
uint16 ReadW (uint32 addr);
|
||||
|
||||
2550
HP2100/hp2100_cpu1.c
2550
HP2100/hp2100_cpu1.c
File diff suppressed because it is too large
Load Diff
@@ -63,7 +63,7 @@
|
||||
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
|
||||
#define VA_N_SIZE 15 /* virtual addr size */
|
||||
#define VASIZE (1 << VA_N_SIZE)
|
||||
#define VAMASK (VASIZE - 1) /* virt addr mask */
|
||||
#define VAMASK 077777 /* virt addr mask */
|
||||
#define PA_N_SIZE 20 /* phys addr size */
|
||||
#define PASIZE (1 << PA_N_SIZE)
|
||||
#define PAMASK (PASIZE - 1) /* phys addr mask */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SIMH/HP 21XX DIAGNOSTICS PERFORMANCE
|
||||
====================================
|
||||
Last update: 2004-12-29
|
||||
Last update: 2005-03-22
|
||||
|
||||
|
||||
The HP 24396 diagnostic suite has been run against the SIMH HP 21xx simulation.
|
||||
@@ -12,7 +12,7 @@ The test system configuration is the default SIMH configuration with these
|
||||
alterations (except where noted in the individual diagnostic reports):
|
||||
|
||||
* All I/O devices are enabled.
|
||||
* The CPU is configured as a 21MX with 128KW of memory.
|
||||
* The CPU is configured as a 21MX-E with 128KW of memory.
|
||||
|
||||
Detailed diagnostic configuration, operation, and results are given after the
|
||||
summary table. These may be used to duplicate the diagnostic results.
|
||||
@@ -42,9 +42,9 @@ The results of the diagnostic runs are summarized below:
|
||||
|
||||
101011 Extended Instruction Group (Index) 1432 3.2-3 Passed
|
||||
101112 Extended Instruction Group (Word, Byte) 1728 3.2-3 Passed
|
||||
101110 2100 Fast FORTRAN Package 1632 - No simulation
|
||||
101213 M/E-Series Fast FORTRAN Package 1 1822 - No simulation
|
||||
101115 M/E-Series Fast FORTRAN Package 2 1632 - No simulation
|
||||
101110 2100 Fast FORTRAN Package 1632 3.4-0 Partial
|
||||
101213 M/E-Series Fast FORTRAN Package 1 1822 3.4-0 Passed
|
||||
101114 M/E-Series Fast FORTRAN Package 2 1632 3.4-0 Passed
|
||||
101121 F-Series FPP/SIS/FFP 1926 - No simulation
|
||||
|
||||
102103 Memory Expansion Unit 1830 3.2-3 Passed
|
||||
@@ -492,7 +492,7 @@ TEST RESULT: Passed.
|
||||
DSN 101011 - Extended Instruction Group (Index)
|
||||
-----------------------------------------------
|
||||
|
||||
TESTED DEVICE: CPU (hp2100_cpu.c)
|
||||
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||
|
||||
CONFIGURATION: sim> deposit S 000000
|
||||
sim> reset
|
||||
@@ -511,7 +511,7 @@ TEST RESULT: Passed.
|
||||
DSN 101112 - Extended Instruction Group (Word, Byte, Bit)
|
||||
---------------------------------------------------------
|
||||
|
||||
TESTED DEVICE: CPU (hp2100_cpu.c)
|
||||
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||
|
||||
CONFIGURATION: sim> set LPS diag
|
||||
sim> deposit S 000014
|
||||
@@ -533,6 +533,148 @@ TEST RESULT: Passed.
|
||||
|
||||
|
||||
|
||||
--------------------------------------
|
||||
DSN 101110 - 2100 Fast FORTRAN Package
|
||||
--------------------------------------
|
||||
|
||||
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||
|
||||
CONFIGURATION: sim> set CPU 2100
|
||||
sim> set CPU 32K
|
||||
sim> set CPU FFP
|
||||
|
||||
sim> deposit S 000013
|
||||
sim> reset
|
||||
sim> go 100
|
||||
|
||||
HALT instruction 102074
|
||||
|
||||
sim> deposit S 000000
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
TEST REPORT: START 2100A-S FFP DIAGNOSTIC
|
||||
H030 .GOTO TEST
|
||||
H050 .ENTR TEST
|
||||
H060 .ENTP TEST
|
||||
H100 .SETP TEST
|
||||
H110 ..MAP TEST
|
||||
H120 SNGL TEST
|
||||
H130 DBLE TEST
|
||||
H140 .XADD TEST
|
||||
|
||||
TEST 07
|
||||
E142 NOT INTERRUPTIBLE
|
||||
|
||||
HALT instruction 106042
|
||||
|
||||
sim> go
|
||||
|
||||
H150 .XSUB TEST
|
||||
H160 .XMPY TEST
|
||||
|
||||
TEST 11
|
||||
E162 NOT INTERRUPTIBLE
|
||||
|
||||
HALT instruction 106062
|
||||
|
||||
sim> go
|
||||
|
||||
H200 .XDIV TEST
|
||||
H210 .DFER TEST
|
||||
H220 .XFER TEST
|
||||
PASS 000001
|
||||
|
||||
HALT instruction 102077
|
||||
|
||||
TEST RESULT: Partially passed.
|
||||
|
||||
TEST NOTES: Tests 07 and 11 test the interruptibility of the .XADD and .XMPY
|
||||
instructions. These features are not simulated.
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
DSN 101213 - M/E-Series Fast FORTRAN Package 1
|
||||
----------------------------------------------
|
||||
|
||||
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||
|
||||
CONFIGURATION: sim> set CPU FFP
|
||||
sim> set LPS diag
|
||||
|
||||
sim> deposit S 000014
|
||||
sim> reset
|
||||
sim> go 100
|
||||
|
||||
HALT instruction 102074
|
||||
|
||||
sim> deposit S 000000
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
TEST REPORT: START 21MX FFP DIAGNOSTIC 1
|
||||
H110 ..MAP TEST
|
||||
H120 SNGL TEST
|
||||
H130 DBLE TEST
|
||||
H210 .DFER TEST
|
||||
H220 .XFER TEST
|
||||
H230 PWR2 TEST
|
||||
H240 .PACK TEST
|
||||
H250 FLUN TEST
|
||||
H260 .XPAK TEST
|
||||
H300 .XCOM TEST
|
||||
H310 ..DCM TEST
|
||||
H320 DDINT TEST
|
||||
H330 .CFER TEST
|
||||
PASS 000001
|
||||
|
||||
HALT instruction 102077
|
||||
|
||||
TEST RESULT: Passed.
|
||||
|
||||
|
||||
|
||||
----------------------------------------------
|
||||
DSN 101115 - M/E-Series Fast FORTRAN Package 2
|
||||
----------------------------------------------
|
||||
|
||||
TESTED DEVICE: CPU (hp2100_cpu1.c)
|
||||
|
||||
CONFIGURATION: sim> set CPU FFP
|
||||
sim> set LPS diag
|
||||
|
||||
sim> deposit S 000014
|
||||
sim> reset
|
||||
sim> go 100
|
||||
|
||||
HALT instruction 102074
|
||||
|
||||
sim> deposit S 000000
|
||||
sim> reset
|
||||
sim> go
|
||||
|
||||
TEST REPORT: START 21MX FFP DIAGNOSTIC 2
|
||||
H030 .GOTO TEST
|
||||
H050 .ENTR TEST
|
||||
H060 .ENTP TEST
|
||||
H100 .SETP TEST
|
||||
H115 XADD TEST
|
||||
H125 XSUB TEST
|
||||
H135 XMPY TEST
|
||||
H140 .XADD TEST
|
||||
H150 .XSUB TEST
|
||||
H160 .XMPY TEST
|
||||
H200 .XDIV TEST
|
||||
H215 XDIV TEST
|
||||
PASS 000001
|
||||
|
||||
HALT instruction 102077
|
||||
|
||||
TEST RESULT: Passed.
|
||||
|
||||
|
||||
|
||||
----------------------------------
|
||||
DSN 102103 - Memory Expansion Unit
|
||||
----------------------------------
|
||||
@@ -933,7 +1075,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> detach DPC0
|
||||
sim> set DPC0 unloaded
|
||||
sim> go
|
||||
|
||||
H40 PROTECT U/D THEN READY UNIT 0
|
||||
@@ -942,7 +1084,7 @@ TEST REPORT: H0 7900/7901 CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||
Simulation stopped
|
||||
|
||||
sim> set DPC0 locked
|
||||
sim> attach DPC0 scratch.U0.7900.disc
|
||||
sim> set DPC0 loaded
|
||||
sim> go
|
||||
|
||||
H41 CLEAR U/D PROTECT,LOAD,PUSH RUN
|
||||
@@ -1113,7 +1255,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DS0 FORMAT
|
||||
sim> set DS0 format
|
||||
sim> go
|
||||
|
||||
H46 READ IN STEP 04
|
||||
@@ -1142,7 +1284,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DS0 NOFORMAT
|
||||
sim> set DS0 noformat
|
||||
sim> go
|
||||
|
||||
H46 READ IN STEP 07
|
||||
@@ -1171,7 +1313,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DS0 FORMAT
|
||||
sim> set DS0 format
|
||||
sim> go
|
||||
|
||||
H45 WRITE IN STEP 10
|
||||
@@ -1189,7 +1331,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> detach DS0
|
||||
sim> set DS0 unloaded
|
||||
sim> go
|
||||
|
||||
H107 READY UNIT 0
|
||||
@@ -1197,21 +1339,21 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
[CTRL+E]
|
||||
Simulation stopped
|
||||
|
||||
sim> attach DS0 scratch.U0.7905.disc
|
||||
sim> set DS0 loaded
|
||||
sim> go
|
||||
|
||||
H142 PROTECT U/D,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DS0 LOCKED
|
||||
sim> set DS0 locked
|
||||
sim> go
|
||||
|
||||
H143 CLEAR U/D PROTECT,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DS0 WRITEENABLED
|
||||
sim> set DS0 writeenabled
|
||||
sim> go
|
||||
|
||||
H110 PRESS PRESET(S),PRESS RUN
|
||||
@@ -1323,12 +1465,14 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
sim> go
|
||||
|
||||
H46 READ IN STEP 43
|
||||
E47 DATA WORD 0000 IS 156164 SHOULD BE 144300
|
||||
E47 DATA WORD 0001 IS 023302 SHOULD BE 117306
|
||||
E47 DATA WORD 0002 IS 114642 SHOULD BE 045322
|
||||
H135 S P D TSTAT XXXX UNIT / E DRTYPE X A P F DF FS SC NR B
|
||||
E64 STATUS IS 0 0 0 00111 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
|
||||
E64 STATUS IS 0 0 0 00000 0000 0000 / 0 000010 0 0 0 1 0 0 0 0 0
|
||||
SHOULD BE 1 0 0 00000 XXXX XXXX / 0 000010 0 0 0 X 0 0 0 0 0
|
||||
H137 TERMINATION STATUS IS "CYL CMP ERROR " SHOULD BE "NORMAL COMPLET"
|
||||
E13 0000 WORDS TRANSFERRED 0128 EXPECTED
|
||||
START 0016/00/33-LAST 0016/00/33 WORD COUNT 00128,OLD CYL 0016,UNIT 00
|
||||
H137 TERMINATION STATUS IS "NORMAL COMPLET"
|
||||
START 0016/00/33-LAST 0016/00/34 WORD COUNT 00128,OLD CYL 0016,UNIT 00
|
||||
|
||||
HALT instruction 102001
|
||||
|
||||
@@ -1462,28 +1606,28 @@ TEST REPORT: 7970-13181 DIAG.
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC0 scratch.U0.7970.tape
|
||||
sim> set MSC0 online
|
||||
sim> go
|
||||
|
||||
H137 PUT TAPE UNIT ON-LINE
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC1 scratch.U1.7970.tape
|
||||
sim> set MSC1 online
|
||||
sim> go
|
||||
|
||||
H137 PUT TAPE UNIT ON-LINE
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC2 scratch.U2.7970.tape
|
||||
sim> set MSC2 online
|
||||
sim> go
|
||||
|
||||
H137 PUT TAPE UNIT ON-LINE
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC3 scratch.U3.7970.tape
|
||||
sim> set MSC3 online
|
||||
sim> go
|
||||
|
||||
PASS 000001
|
||||
@@ -1599,28 +1743,28 @@ TEST REPORT: 7970-13183 DIAG.
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC0 scratch.U0.7970.tape
|
||||
sim> set MSC0 online
|
||||
sim> go
|
||||
|
||||
H137 PUT TAPE UNIT ON-LINE
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC1 scratch.U1.7970.tape
|
||||
sim> set MSC1 online
|
||||
sim> go
|
||||
|
||||
H137 PUT TAPE UNIT ON-LINE
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC2 scratch.U2.7970.tape
|
||||
sim> set MSC2 online
|
||||
sim> go
|
||||
|
||||
H137 PUT TAPE UNIT ON-LINE
|
||||
|
||||
HALT instruction 106037
|
||||
|
||||
sim> attach MSC3 scratch.U3.7970.tape
|
||||
sim> set MSC3 online
|
||||
sim> go
|
||||
|
||||
PASS 000001
|
||||
@@ -2257,7 +2401,7 @@ TEST REPORT: H0 HP2100A CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> detach DPC0
|
||||
sim> set DPC0 unloaded
|
||||
sim> go
|
||||
|
||||
H40 READY UNIT 0
|
||||
@@ -2265,7 +2409,7 @@ TEST REPORT: H0 HP2100A CARTRIDGE DISC MEMORY DIAGNOSTIC
|
||||
[CTRL+E]
|
||||
Simulation stopped
|
||||
|
||||
sim> attach DPC0 scratch.U0.2871.disc
|
||||
sim> set DPC0 loaded
|
||||
sim> go
|
||||
|
||||
H71 PRESS PRESET THEN PRESS RUN
|
||||
@@ -2446,7 +2590,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> detach DQC0
|
||||
sim> set DQC0 unloaded
|
||||
sim> go
|
||||
|
||||
H40 ENABLE UNIT 0
|
||||
@@ -2454,7 +2598,7 @@ TEST REPORT: H66 SET FORMAT SWITCH ON UNIT 0,PUSH RUN
|
||||
[CTRL+E]
|
||||
Simulation stopped
|
||||
|
||||
sim> attach DQC0 scratch.U0.2883.disc
|
||||
sim> set DQC0 loaded
|
||||
sim> go
|
||||
|
||||
H71 PRESS PRESET THEN PRESS RUN
|
||||
@@ -2497,7 +2641,7 @@ CONFIGURATION: sim> reset
|
||||
HALT instruction 107001
|
||||
|
||||
sim> set DRC 180K
|
||||
sim> set DRC TRACKPROT=8
|
||||
sim> set DRC trackprot=8
|
||||
sim> attach DRC0 scratch.U0.2770.disc
|
||||
sim> deposit S 002611
|
||||
sim> go
|
||||
@@ -2516,14 +2660,14 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC PROTECTED
|
||||
sim> set DRC protected
|
||||
sim> go
|
||||
|
||||
H14 DEVICE HAS 0032 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||
@@ -2532,7 +2676,7 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H36 PASS 0001
|
||||
@@ -2560,7 +2704,7 @@ CONFIGURATION: sim> reset
|
||||
HALT instruction 107001
|
||||
|
||||
sim> set DRC 720K
|
||||
sim> set DRC TRACKPROT=32
|
||||
sim> set DRC trackprot=32
|
||||
sim> attach DRC0 scratch.U0.2771.disc
|
||||
sim> deposit S 002611
|
||||
sim> go
|
||||
@@ -2579,14 +2723,14 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC PROTECTED
|
||||
sim> set DRC protected
|
||||
sim> go
|
||||
|
||||
H14 DEVICE HAS 0128 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||
@@ -2595,7 +2739,7 @@ TEST REPORT: H12 DEVICE HAS 90 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H36 PASS 0001
|
||||
@@ -2623,7 +2767,7 @@ CONFIGURATION: sim> reset
|
||||
HALT instruction 107001
|
||||
|
||||
sim> set DRC 384K
|
||||
sim> set DRC TRACKPROT=16
|
||||
sim> set DRC trackprot=16
|
||||
sim> attach DRC0 scratch.U0.2773.disc
|
||||
sim> deposit S 002611
|
||||
sim> go
|
||||
@@ -2642,14 +2786,14 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC PROTECTED
|
||||
sim> set DRC protected
|
||||
sim> go
|
||||
|
||||
H14 DEVICE HAS 0192 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||
@@ -2658,7 +2802,7 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H36 PASS 0001
|
||||
@@ -2686,7 +2830,7 @@ CONFIGURATION: sim> reset
|
||||
HALT instruction 107001
|
||||
|
||||
sim> set DRC 1536K
|
||||
sim> set DRC TRACKPROT=64
|
||||
sim> set DRC trackprot=64
|
||||
sim> attach DRC0 scratch.U0.2775.disc
|
||||
sim> deposit S 002611
|
||||
sim> go
|
||||
@@ -2705,14 +2849,14 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H10 SET TRACK PROTECT SWITCH TO PROTECTED,PRESS RUN
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC PROTECTED
|
||||
sim> set DRC protected
|
||||
sim> go
|
||||
|
||||
H14 DEVICE HAS 0768 TRACKS,THE FOLLOWING ARE PROTECTED:
|
||||
@@ -2721,7 +2865,7 @@ TEST REPORT: H12 DEVICE HAS 32 SECTORS
|
||||
|
||||
HALT instruction 102002
|
||||
|
||||
sim> set DRC UNPROTECTED
|
||||
sim> set DRC unprotected
|
||||
sim> go
|
||||
|
||||
H36 PASS 0001
|
||||
|
||||
@@ -55,9 +55,11 @@ sim/ scp.h
|
||||
|
||||
sim/hp2100/ hp2100_cpu.h
|
||||
hp2100_defs.h
|
||||
hp2100_fp1.h
|
||||
hp2100_cpu.c
|
||||
hp2100_cpu1.c
|
||||
hp2100_fp.c
|
||||
hp2100_fp1.c
|
||||
hp2100_dp.c
|
||||
hp2100_dq.c
|
||||
hp2100_dr.c
|
||||
@@ -78,9 +80,10 @@ The HP2100 simulator is configured as follows:
|
||||
device simulates
|
||||
name(s)
|
||||
|
||||
CPU 2116 CPU with 32KW memory
|
||||
2100 CPU with 32KW memory, FP or IOP instructions
|
||||
21MX-M/E CPU with 1024KW memory, FP, DMS, and/or IOP instructions
|
||||
CPU 2116 CPU with up to 32KW of memory
|
||||
2100 CPU with up to 32KW of memory
|
||||
21MX-M or -E CPU with up to 1024KW of memory
|
||||
EAU, FP, FFP, IOP, and/or DMS microcode extensions
|
||||
MP 12892B memory protect
|
||||
DMA0, DMA1 12895A/12897B direct memory access/dual channel port controller
|
||||
PTR 12597A duplex register interface with 2748 paper tape reader
|
||||
@@ -110,13 +113,21 @@ The HP2100 simulator implements several unique stop conditions:
|
||||
- more than INDMAX indirect references are detected during
|
||||
memory reference address decoding
|
||||
|
||||
The HP2100 loader supports standard absolute binary format. The DUMP
|
||||
The HP2100 LOAD command supports standard absolute binary format. The DUMP
|
||||
command is not implemented.
|
||||
|
||||
2.1 CPU
|
||||
|
||||
CPU options include choice of instruction set and memory size. The
|
||||
general command form is:
|
||||
CPU options include choice of model, memory size, and instruction sets.
|
||||
Several microcode options are simulated:
|
||||
|
||||
EAU Extended Arithmetic Unit
|
||||
FP Single-Precision Floating Point
|
||||
FFP Fast FORTRAN Processor
|
||||
IOP 2000/Access I/O Processor
|
||||
DMS Dynamic Mapping System
|
||||
|
||||
The general command form is:
|
||||
|
||||
SET {-F} CPU <option>
|
||||
|
||||
@@ -132,6 +143,8 @@ Options that may be specified are:
|
||||
SET CPU NOFP no FP instructions (2100 only)
|
||||
SET CPU IOP IOP instructions (2100, 21MX only)
|
||||
SET CPU NOIOP no IOP instructions (2100, 21MX only)
|
||||
SET CPU FFP FFP instructions (2100, 21MX only)
|
||||
SET CPU NOFFP no FFP instructions (2100, 21MX only)
|
||||
SET CPU DMS DMS instructions (21MX only)
|
||||
SET CPU NODMS no DMS instructions (21MX only)
|
||||
SET CPU 4K set memory size = 4K
|
||||
@@ -144,11 +157,10 @@ Options that may be specified are:
|
||||
SET CPU 512K set memory size = 512K (21MX only)
|
||||
SET CPU 1024K set memory size = 1024K (21MX only)
|
||||
|
||||
On the 2100, EAU is standard, and the FP and IOP options are mutually
|
||||
exclusive. On the 21MX, EAU and FP are standard. The 21MX optionally
|
||||
includes DMS (dynamic mapping system) and IOP instructions. The 21MX-E
|
||||
supports the TIMER instruction; on the 21MX-M, this instruction decodes
|
||||
as MPY.
|
||||
On the 2100, EAU is standard, and the FP or FFP and IOP options are mutually
|
||||
exclusive. On the 21MX, EAU and FP are standard. The DMS, FFP, and IOP
|
||||
instructions are optional. The 21MX-E supports the TIMER instruction; on
|
||||
the 21MX-M, this instruction decodes as MPY.
|
||||
|
||||
Setting the CPU type to 2116, 2100, or 21MX establishes a consistent set
|
||||
of common options. Additional SET CPU commands may follow to fine-tune
|
||||
@@ -813,6 +825,14 @@ Separate protection for the upper and lower platters of the 7900 drive
|
||||
is not supported. Also, the drive Protect/Override switch is not
|
||||
supported; drive protection is permanently overridden.
|
||||
|
||||
Drives may also have their heads unloaded and loaded:
|
||||
|
||||
SET DPCn UNLOADED unload heads on unit n
|
||||
SET DPCn LOADED load heads on unit n
|
||||
|
||||
This provides a convenient method of setting a drive "down" without
|
||||
detaching the associated disk image file.
|
||||
|
||||
The 12557A/13210A supports the BOOT command. BOOT DPC copies the IBL
|
||||
for 7900 class disks into memory and starts it running. BOOT -R DPC
|
||||
boots from the removable platter (head 0). The switch register (S) is
|
||||
@@ -869,7 +889,7 @@ Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached disk not ready (drive unloaded)
|
||||
not attached disk not ready (heads unloaded)
|
||||
|
||||
end of file assume rest of disk is zero
|
||||
|
||||
@@ -887,6 +907,14 @@ Individual drives may be protected against writing:
|
||||
SET DQCn LOCKED set unit n write locked
|
||||
SET DQCn WRITEENABLED set unit n write enabled
|
||||
|
||||
Drives may also have their heads unloaded and loaded:
|
||||
|
||||
SET DQCn UNLOADED unload heads on unit n
|
||||
SET DQCn LOADED load heads on unit n
|
||||
|
||||
This provides a convenient method of setting a drive "down" without
|
||||
detaching the associated disk image file.
|
||||
|
||||
The 12565A supports the BOOT command. BOOT DQC copies the IBL for 2883
|
||||
class disks into memory and starts it running. The switch register (S)
|
||||
is set automatically to the value expected by the IBL loader:
|
||||
@@ -939,7 +967,7 @@ Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached disk not ready
|
||||
not attached disk not ready (heads unloaded)
|
||||
|
||||
end of file assume rest of disk is zero
|
||||
|
||||
@@ -1052,6 +1080,14 @@ Separate protection for the upper and lower platters of the 7905 and
|
||||
7906 drives is not supported. Protecting a 7905 or 7906 drive behaves
|
||||
as though both of the Disc Protect switches were on.
|
||||
|
||||
Drives may also have their heads unloaded and loaded:
|
||||
|
||||
SET DSn UNLOADED unload heads on unit n
|
||||
SET DSn LOADED load heads on unit n
|
||||
|
||||
This provides a convenient method of setting a drive "down" without
|
||||
detaching the associated disk image file.
|
||||
|
||||
The setting of the drive Format switch may be changed with:
|
||||
|
||||
SET DSn FORMAT set format enabled
|
||||
@@ -1105,7 +1141,7 @@ Error handling is as follows:
|
||||
|
||||
error processed as
|
||||
|
||||
not attached disk not ready
|
||||
not attached disk not ready (heads unloaded)
|
||||
|
||||
end of file assume rest of disk is zero
|
||||
|
||||
@@ -1171,10 +1207,12 @@ Error handling is as follows:
|
||||
2.7.2 13181A Magnetic Tape Controller (MSC, MSD) with Four 7970B Drives
|
||||
18183A Magnetic Tape Controller (MSC, MSD) with Four 7970E Drives
|
||||
|
||||
Magnetic tape options include the ability to make the unit write enabled
|
||||
or write locked, and the ability to select the 13181A (800 bpi) controller
|
||||
or the 13183A (1600 bpi) controller.
|
||||
Magnetic tape options include the ability to set a drive offline and
|
||||
online, write enabled or write locked, and the ability to select the
|
||||
13181A (800 bpi) controller or the 13183A (1600 bpi) controller.
|
||||
|
||||
SET MSCn OFFLINE set unit n offline
|
||||
SET MSCn ONLINE set unit n online
|
||||
SET MSCn LOCKED set unit n write locked
|
||||
SET MSCn WRITEENABLED set unit n write enabled
|
||||
SET MSC 13181A set controller to 13181A
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
dp 12557A 2871 disk subsystem
|
||||
13210A 7900 disk subsystem
|
||||
|
||||
01-Mar-05 JDB Added SET UNLOAD/LOAD
|
||||
07-Oct-04 JDB Fixed enable/disable from either device
|
||||
Fixed ANY ERROR status for 12557A interface
|
||||
Fixed unattached drive status for 12557A interface
|
||||
@@ -113,7 +114,9 @@
|
||||
#include "hp2100_defs.h"
|
||||
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_V_UNLOAD (UNIT_V_UF + 1) /* heads unloaded */
|
||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||
#define UNIT_UNLOAD (1 << UNIT_V_UNLOAD)
|
||||
#define FNC u3 /* saved function */
|
||||
#define DRV u4 /* drive number (DC) */
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
||||
@@ -231,11 +234,12 @@ int32 dpcio (int32 inst, int32 IR, int32 dat);
|
||||
t_stat dpc_svc (UNIT *uptr);
|
||||
t_stat dpd_svc (UNIT *uptr);
|
||||
t_stat dpc_reset (DEVICE *dptr);
|
||||
t_stat dpc_vlock (UNIT *uptr, int32 val);
|
||||
t_stat dpc_attach (UNIT *uptr, char *cptr);
|
||||
t_stat dpc_detach (UNIT* uptr);
|
||||
t_stat dpc_boot (int32 unitno, DEVICE *dptr);
|
||||
void dp_god (int32 fnc, int32 drv, int32 time);
|
||||
void dp_goc (int32 fnc, int32 drv, int32 time);
|
||||
t_stat dpc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
t_stat dp_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat dp_showtype (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
@@ -291,14 +295,14 @@ DEVICE dpd_dev = {
|
||||
*/
|
||||
|
||||
UNIT dpc_unit[] = {
|
||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DP_SIZE3) },
|
||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DP_SIZE3) },
|
||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DP_SIZE3) },
|
||||
{ UDATA (&dpc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DP_SIZE3) } };
|
||||
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) },
|
||||
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) },
|
||||
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) },
|
||||
{ UDATA (&dpc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, DP_SIZE3) } };
|
||||
|
||||
REG dpc_reg[] = {
|
||||
{ ORDATA (OBUF, dpc_obuf, 16) },
|
||||
@@ -329,6 +333,8 @@ REG dpc_reg[] = {
|
||||
{ NULL } };
|
||||
|
||||
MTAB dpc_mod[] = {
|
||||
{ UNIT_UNLOAD, UNIT_UNLOAD, "heads unloaded", "UNLOADED", dpc_load_unload },
|
||||
{ UNIT_UNLOAD, 0, "heads loaded", "LOADED", dpc_load_unload },
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 1, NULL, "13210A",
|
||||
@@ -345,7 +351,7 @@ DEVICE dpc_dev = {
|
||||
"DPC", dpc_unit, dpc_reg, dpc_mod,
|
||||
DP_NUMDRV, 8, 24, 1, 8, 16,
|
||||
NULL, NULL, &dpc_reset,
|
||||
&dpc_boot, &dpc_attach, NULL,
|
||||
&dpc_boot, &dpc_attach, &dpc_detach,
|
||||
&dpc_dib, DEV_DISABLE };
|
||||
|
||||
/* IOT routines */
|
||||
@@ -561,7 +567,7 @@ case FNC_SEEK1: /* seek, need hd/sec */
|
||||
|
||||
case FNC_STA: /* read status */
|
||||
if (CMD (devd) || dp_ctype) { /* dch act or 13210? */
|
||||
if (dpc_unit[drv].flags & UNIT_ATT) { /* attached? */
|
||||
if ((dpc_unit[drv].flags & UNIT_UNLOAD) == 0) { /* drive up? */
|
||||
dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */
|
||||
if (dp_ctype) dpd_ibuf = /* 13210? */
|
||||
(dpd_ibuf & ~(STA_MBZ13 | STA_PROT)) |
|
||||
@@ -621,7 +627,7 @@ err = 0; /* assume no err */
|
||||
drv = uptr - dpc_dev.units; /* get drive no */
|
||||
devc = dpc_dib.devno; /* get cch devno */
|
||||
devd = dpd_dib.devno; /* get dch devno */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
if (uptr->flags & UNIT_UNLOAD) { /* drive down? */
|
||||
setFSR (devc); /* set cch flg */
|
||||
clrCMD (devc); /* clr cch cmd */
|
||||
dpc_sta[drv] = 0; /* clr status */
|
||||
@@ -760,20 +766,42 @@ return SCPE_OK;
|
||||
|
||||
t_stat dpc_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
int32 drv;
|
||||
t_stat r;
|
||||
|
||||
drv = uptr - dpc_dev.units; /* get drive no */
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r;
|
||||
dpc_sta[drv] = dpc_sta[drv] | STA_ATN | STA_1ST; /* update status */
|
||||
if (dpc_poll) { /* polling enabled? */
|
||||
dpc_dib.fbf = 1; /* set fbf */
|
||||
dpc_dib.flg = 1; /* set flg */
|
||||
dpc_dib.srq = 1; } /* srq follows flg */
|
||||
if (r == SCPE_OK) dpc_load_unload (uptr, 0, NULL, NULL);/* if OK, load heads */
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Detach routine */
|
||||
|
||||
t_stat dpc_detach (UNIT* uptr)
|
||||
{
|
||||
dpc_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */
|
||||
return detach_unit (uptr); /* detach unit */
|
||||
}
|
||||
|
||||
/* Load and unload heads */
|
||||
|
||||
t_stat dpc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
uint32 drv;
|
||||
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* must be attached to load */
|
||||
|
||||
if (value == UNIT_UNLOAD) /* unload heads? */
|
||||
uptr->flags = uptr->flags | UNIT_UNLOAD; /* indicate unload */
|
||||
else { /* load heads */
|
||||
uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */
|
||||
drv = uptr - dpc_dev.units; /* get drive no */
|
||||
dpc_sta[drv] = dpc_sta[drv] | STA_ATN | STA_1ST;/* update status */
|
||||
if (dpc_poll) { /* polling enabled? */
|
||||
dpc_dib.fbf = 1; /* set fbf */
|
||||
dpc_dib.flg = 1; /* set flg */
|
||||
dpc_dib.srq = 1; } } /* srq follows flg */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Set controller type */
|
||||
|
||||
t_stat dp_settype (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
dq 12565A 2883 disk system
|
||||
|
||||
01-Mar-05 JDB Added SET UNLOAD/LOAD
|
||||
07-Oct-04 JDB Fixed enable/disable from either device
|
||||
Shortened xtime from 5 to 3 (drive avg 156KW/second)
|
||||
Fixed not ready/any error status
|
||||
@@ -71,7 +72,9 @@
|
||||
#include "hp2100_defs.h"
|
||||
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_V_UNLOAD (UNIT_V_UF + 1) /* heads unloaded */
|
||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||
#define UNIT_UNLOAD (1 << UNIT_V_UNLOAD)
|
||||
#define FNC u3 /* saved function */
|
||||
#define DRV u4 /* drive number (DC) */
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
||||
@@ -166,6 +169,9 @@ int32 dqcio (int32 inst, int32 IR, int32 dat);
|
||||
t_stat dqc_svc (UNIT *uptr);
|
||||
t_stat dqd_svc (UNIT *uptr);
|
||||
t_stat dqc_reset (DEVICE *dptr);
|
||||
t_stat dqc_attach (UNIT *uptr, char *cptr);
|
||||
t_stat dqc_detach (UNIT* uptr);
|
||||
t_stat dqc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
t_stat dqc_boot (int32 unitno, DEVICE *dptr);
|
||||
void dq_god (int32 fnc, int32 drv, int32 time);
|
||||
void dq_goc (int32 fnc, int32 drv, int32 time);
|
||||
@@ -222,10 +228,10 @@ DEVICE dqd_dev = {
|
||||
*/
|
||||
|
||||
UNIT dqc_unit[] = {
|
||||
{ UDATA (&dqc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DQ_SIZE) },
|
||||
{ UDATA (&dqc_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DQ_SIZE) } };
|
||||
{ UDATA (&dqc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, DQ_SIZE) },
|
||||
{ UDATA (&dqc_svc, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, DQ_SIZE) } };
|
||||
|
||||
REG dqc_reg[] = {
|
||||
{ ORDATA (OBUF, dqc_obuf, 16) },
|
||||
@@ -252,6 +258,8 @@ REG dqc_reg[] = {
|
||||
{ NULL } };
|
||||
|
||||
MTAB dqc_mod[] = {
|
||||
{ UNIT_UNLOAD, UNIT_UNLOAD, "heads unloaded", "UNLOADED", dqc_load_unload },
|
||||
{ UNIT_UNLOAD, 0, "heads loaded", "LOADED", dqc_load_unload },
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
|
||||
@@ -262,7 +270,7 @@ DEVICE dqc_dev = {
|
||||
"DQC", dqc_unit, dqc_reg, dqc_mod,
|
||||
DQ_NUMDRV, 8, 24, 1, 8, 16,
|
||||
NULL, NULL, &dqc_reset,
|
||||
&dqc_boot, NULL, NULL,
|
||||
&dqc_boot, &dqc_attach, &dqc_detach,
|
||||
&dqc_dib, DEV_DISABLE };
|
||||
|
||||
/* IOT routines */
|
||||
@@ -472,7 +480,7 @@ case FNC_RCL: /* recalibrate */
|
||||
|
||||
case FNC_STA: /* read status */
|
||||
if (CMD (devd)) { /* dch active? */
|
||||
if (dqc_unit[drv].flags & UNIT_ATT) /* attached? */
|
||||
if ((dqc_unit[drv].flags & UNIT_UNLOAD) == 0) /* drive up? */
|
||||
dqd_ibuf = dqc_sta[drv] & ~STA_DID;
|
||||
else dqd_ibuf = STA_NRDY;
|
||||
if (dqd_ibuf & STA_ANYERR) /* errors? set flg */
|
||||
@@ -527,7 +535,7 @@ err = 0; /* assume no err */
|
||||
drv = uptr - dqc_dev.units; /* get drive no */
|
||||
devc = dqc_dib.devno; /* get cch devno */
|
||||
devd = dqd_dib.devno; /* get dch devno */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
if (uptr->flags & UNIT_UNLOAD) { /* drive down? */
|
||||
setFSR (devc); /* set cch flg */
|
||||
clrCMD (devc); /* clr cch cmd */
|
||||
dqc_sta[drv] = 0; /* clr status */
|
||||
@@ -671,11 +679,33 @@ for (drv = 0; drv < DQ_NUMDRV; drv++) { /* loop thru drives */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Write lock/enable routine */
|
||||
/* Attach routine */
|
||||
|
||||
t_stat dqc_vlock (UNIT *uptr, int32 val)
|
||||
t_stat dqc_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
if (uptr->flags & UNIT_ATT) return SCPE_ARG;
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r == SCPE_OK) dqc_load_unload (uptr, 0, NULL, NULL);/* if OK, load heads */
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Detach routine */
|
||||
|
||||
t_stat dqc_detach (UNIT* uptr)
|
||||
{
|
||||
dqc_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */
|
||||
return detach_unit (uptr); /* detach unit */
|
||||
}
|
||||
|
||||
/* Load and unload heads */
|
||||
|
||||
t_stat dqc_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* must be attached to load */
|
||||
if (value == UNIT_UNLOAD) /* unload heads? */
|
||||
uptr->flags = uptr->flags | UNIT_UNLOAD; /* indicate unload */
|
||||
else uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* hp2100_ds.c: HP 2100 13037 disk controller simulator
|
||||
|
||||
Copyright (c) 2004, Robert M. Supnik
|
||||
Copyright (c) 2004-2005, Robert M. Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
ds 13037 disk controller
|
||||
|
||||
18-Mar-05 RMS Added attached test to detach routine
|
||||
01-Mar-05 JDB Added SET UNLOAD/LOAD
|
||||
|
||||
States of the controller: the controller uP runs all the time, but most of
|
||||
the time it is waiting for an event. The simulator only 'runs' the controller
|
||||
when there's an event to process: change in CPU interface state, change in
|
||||
@@ -77,14 +80,16 @@
|
||||
/* Flags in the unit flags word */
|
||||
|
||||
#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
|
||||
#define UNIT_V_FMT (UNIT_V_UF + 1) /* format enabled */
|
||||
#define UNIT_V_UNLOAD (UNIT_V_UF + 1) /* heads unloaded */
|
||||
#define UNIT_V_DTYPE (UNIT_V_UF + 2) /* disk type */
|
||||
#define UNIT_M_DTYPE 3
|
||||
#define UNIT_V_AUTO (UNIT_V_UF + 4) /* autosize */
|
||||
#define UNIT_V_FMT (UNIT_V_UF + 5) /* format enabled */
|
||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||
#define UNIT_FMT (1 << UNIT_V_FMT)
|
||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||
#define UNIT_AUTO (1 << UNIT_V_AUTO)
|
||||
#define UNIT_UNLOAD (1 << UNIT_V_UNLOAD)
|
||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||
#define UNIT_WPR (UNIT_WLK | UNIT_RO) /* write prot */
|
||||
|
||||
@@ -406,6 +411,7 @@ t_stat ds_reset (DEVICE *dptr);
|
||||
t_stat ds_attach (UNIT *uptr, char *cptr);
|
||||
t_stat ds_detach (UNIT *uptr);
|
||||
t_stat ds_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat ds_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
t_stat ds_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
void ds_poll (void);
|
||||
void ds_docmd (uint32 cmd);
|
||||
@@ -443,22 +449,22 @@ void ds_fifo_reset (void);
|
||||
DIB ds_dib = { DS, 0, 0, 0, 0, 0, &dsio };
|
||||
|
||||
UNIT ds_unit[] = {
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_u, UNIT_FIX | UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_UNLOAD, D7905_SIZE) },
|
||||
{ UDATA (&ds_svc_c, UNIT_DIS, 0) },
|
||||
{ UDATA (&ds_svc_t, UNIT_DIS, 0) } };
|
||||
|
||||
@@ -504,6 +510,8 @@ REG ds_reg[] = {
|
||||
{ NULL } };
|
||||
|
||||
MTAB ds_mod[] = {
|
||||
{ UNIT_UNLOAD, UNIT_UNLOAD, "heads unloaded", "UNLOADED", ds_load_unload },
|
||||
{ UNIT_UNLOAD, 0, "heads loaded", "LOADED", ds_load_unload },
|
||||
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
|
||||
{ UNIT_FMT, 0, "format disabled", "NOFORMAT", NULL },
|
||||
@@ -850,7 +858,7 @@ switch (op) { /* case on function */
|
||||
/* Seek and recalibrate */
|
||||
|
||||
case DSC_RECAL: /* recalibrate */
|
||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
||||
if ((uptr->flags & UNIT_UNLOAD) == 0) { /* drive up? */
|
||||
ds_start_seek (uptr, 0, DSC_RECAL|DSC_2ND); /* set up seek */
|
||||
ds_set_idle (); /* ctrl is idle */
|
||||
}
|
||||
@@ -873,7 +881,7 @@ case DSC_SEEK | DSC_2ND: /* waiting for word 1 */
|
||||
case DSC_SEEK | DSC_3RD: /* waiting for word 2 */
|
||||
if (!DS_FIFO_EMPTY) { /* OTA ds? */
|
||||
ds_hs = ds_fifo_read (); /* save head/sector */
|
||||
if (uptr->flags & UNIT_ATT) { /* attached? */
|
||||
if ((uptr->flags & UNIT_UNLOAD) == 0) { /* drive up? */
|
||||
ds_start_seek (uptr, ds_cyl, DSC_SEEK|DSC_4TH); /* set up seek */
|
||||
ds_set_idle (); /* ctrl is idle */
|
||||
}
|
||||
@@ -900,7 +908,7 @@ case DSC_ROFF | DSC_2ND: /* poll done */
|
||||
break;
|
||||
|
||||
case DSC_COLD: /* cold load read */
|
||||
if (uptr->flags & UNIT_ATT) /* attached? */
|
||||
if ((uptr->flags & UNIT_UNLOAD) == 0) /* drive up? */
|
||||
ds_start_seek (uptr, 0, DSC_READ); /* set up seek */
|
||||
else ds_cmd_done (1, DS1_S2ERR); /* no, not ready error */
|
||||
break;
|
||||
@@ -1065,7 +1073,7 @@ sta = drv_tab[dtyp].id | /* form status */
|
||||
uptr->STA | /* static bits */
|
||||
((uptr->flags & UNIT_WPR)? DS2_RO: 0) | /* dynamic bits */
|
||||
((uptr->flags & UNIT_FMT)? DS2_FRM: 0) |
|
||||
((uptr->flags & UNIT_ATT)? 0: DS2_NR | DS2_BS) |
|
||||
((uptr->flags & UNIT_UNLOAD)? DS2_NR | DS2_BS: 0) |
|
||||
(sim_is_active (uptr)? DS2_BS: 0);
|
||||
if (sta & DS2_ALLERR) sta = sta | DS2_ERR; /* set error */
|
||||
return sta;
|
||||
@@ -1133,7 +1141,7 @@ uint32 dtyp = GET_DTYPE (uptr->flags);
|
||||
|
||||
ds_eod = 0; /* init eod */
|
||||
ds_ptr = 0; /* init buffer ptr */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
if (uptr->flags & UNIT_UNLOAD) { /* drive down? */
|
||||
ds_cmd_done (1, DS1_S2ERR);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1410,7 +1418,7 @@ t_stat r;
|
||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
if (r != SCPE_OK) return r; /* error? */
|
||||
uptr->STA = DS2_ATN | DS2_FS; /* update drive status */
|
||||
ds_load_unload (uptr, 0, NULL, NULL); /* if OK, load heads */
|
||||
ds_sched_atn (uptr); /* schedule attention */
|
||||
if (((uptr->flags & UNIT_AUTO) == 0) || /* static size? */
|
||||
((p = sim_fsize (uptr->fileref)) == 0)) return SCPE_OK; /* new file? */
|
||||
@@ -1428,11 +1436,26 @@ return SCPE_OK;
|
||||
|
||||
t_stat ds_detach (UNIT *uptr)
|
||||
{
|
||||
uptr->STA = DS2_ATN; /* update drive status */
|
||||
ds_sched_atn (uptr); /* schedule attention */
|
||||
if (!(uptr->flags & UNIT_ATT)) return SCPE_OK; /* attached? */
|
||||
ds_load_unload (uptr, UNIT_UNLOAD, NULL, NULL); /* unload heads */
|
||||
return detach_unit (uptr);
|
||||
}
|
||||
|
||||
/* Load and unload heads */
|
||||
|
||||
t_stat ds_load_unload (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* must be attached to [un]load */
|
||||
if (value == UNIT_UNLOAD) { /* unload heads? */
|
||||
uptr->flags = uptr->flags | UNIT_UNLOAD; /* indicate unload */
|
||||
uptr->STA = DS2_ATN; /* update drive status */
|
||||
ds_sched_atn (uptr); } /* schedule attention */
|
||||
else { /* load heads */
|
||||
uptr->flags = uptr->flags & ~UNIT_UNLOAD; /* indicate load */
|
||||
uptr->STA = DS2_ATN | DS2_FS; } /* update drive status */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Schedule attention interrupt if CTL set, not restore, and controller idle */
|
||||
|
||||
void ds_sched_atn (UNIT *uptr)
|
||||
|
||||
@@ -23,6 +23,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.
|
||||
|
||||
25-Feb-05 JDB Added FFP helpers f_pack, f_unpack, f_pwr2
|
||||
11-Feb-05 JDB Fixed missing negative overflow renorm in StoreFP
|
||||
26-Dec-04 RMS Separated A/B from M[0/1] for DMA IO (from Dave Bryan)
|
||||
15-Jul-03 RMS Fixed signed/unsigned warning
|
||||
@@ -105,6 +106,7 @@ struct ufp { /* unpacked fp */
|
||||
#define FR_NEG(v) ((~(v) + 1) & DMASK32)
|
||||
|
||||
extern uint16 ABREG[2];
|
||||
|
||||
uint32 UnpackFP (struct ufp *fop, uint32 opnd);
|
||||
void NegFP (struct ufp *fop);
|
||||
void NormFP (struct ufp *fop);
|
||||
@@ -260,6 +262,46 @@ if (fop1.fr) { /* dvd != 0? */
|
||||
return StoreFP (&quo); /* store result */
|
||||
}
|
||||
|
||||
/* Fast FORTRAN Processor helpers. */
|
||||
|
||||
/* Pack mantissa in A/B and exponent and return fp in A/B */
|
||||
|
||||
uint32 f_pack (int32 expon)
|
||||
{
|
||||
struct ufp fop;
|
||||
|
||||
fop.fr = FPAB;
|
||||
fop.exp = expon;
|
||||
return StoreFP (&fop);
|
||||
}
|
||||
|
||||
/* Unpack fp number in A/B into A (exponent) and B (lower mantissa) */
|
||||
|
||||
void f_unpack (void)
|
||||
{
|
||||
AR = FP_GETEXP (BR); /* get exponent */
|
||||
if (FP_GETEXPS (BR)) AR = (AR | ~FP_M_EXP) & DMASK; /* < 0? sext */
|
||||
BR = BR & (uint16) ~(FP_EXP | FP_EXPS); /* clear exp */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Multiply fp number in A/B by 2**n and return in A/B.
|
||||
Exponent overflow or underflow wraps around. */
|
||||
|
||||
void f_pwr2 (int32 n)
|
||||
{
|
||||
uint32 save_a;
|
||||
|
||||
if (AR | BR) { /* microcode test */
|
||||
save_a = AR;
|
||||
f_unpack (); /* unpack exponent */
|
||||
AR = AR + n; /* multiply */
|
||||
BR = BR | ((AR & FP_M_EXP) << FP_V_EXP) | /* merge exponent */
|
||||
((AR & SIGN)? (1 << FP_V_EXPS): 0); /* and exponent sign */
|
||||
AR = save_a; }
|
||||
return;
|
||||
}
|
||||
|
||||
/* Utility routines */
|
||||
|
||||
/* Unpack operand */
|
||||
|
||||
508
HP2100/hp2100_fp1.c
Normal file
508
HP2100/hp2100_fp1.c
Normal file
@@ -0,0 +1,508 @@
|
||||
/* hp2100_fp1.c: HP 2100/21MX extended-precision floating point routines
|
||||
|
||||
Copyright (c) 2005, 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:
|
||||
|
||||
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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from the author.
|
||||
|
||||
Primary references:
|
||||
- HP 1000 M/E/F-Series Computers Technical Reference Handbook
|
||||
(5955-0282, Mar-1980)
|
||||
- DOS/RTE Relocatable Library Reference Manual
|
||||
(24998-90001, Oct-1981)
|
||||
|
||||
The extended-precision floating-point format is a 48-bit extension of the
|
||||
32-bit format used for single precision. A packed "XP" number consists of a
|
||||
40-bit twos-complement mantissa and an 8-bit twos-complement exponent. The
|
||||
exponent is rotated left so that the sign is in the LSB. Pictorially, an XP
|
||||
number appears in memory as follows:
|
||||
|
||||
15 14 0
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
|S | mantissa high | : M
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| mantissa middle | : M + 1
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
| mantissa low | exponent |XS| : M + 2
|
||||
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
||||
15 8 7 1 0
|
||||
|
||||
In a normalized value, the sign and MSB of the mantissa differ. Zero is
|
||||
represented by all three words = 0.
|
||||
|
||||
Internally, an unpacked XP number is contained in a structure having a signed
|
||||
64-bit mantissa and a signed 32-bit exponent. The mantissa is masked to 48
|
||||
bits and left-justified, while the exponent is right-justified.
|
||||
*/
|
||||
|
||||
#include "hp2100_defs.h"
|
||||
#include "hp2100_cpu.h"
|
||||
#include "hp2100_fp1.h"
|
||||
|
||||
#if defined (HAVE_INT64) /* we need int64 support */
|
||||
|
||||
/* packed starting bit numbers */
|
||||
|
||||
#define XP_PAD 16 /* padding LSBs */
|
||||
|
||||
#define XP_V_MSIGN (47 + XP_PAD) /* mantissa sign */
|
||||
#define XP_V_MANT ( 8 + XP_PAD) /* mantissa */
|
||||
#define XP_V_EXP ( 1 + XP_PAD) /* exponent */
|
||||
#define XP_V_ESIGN ( 0 + XP_PAD) /* exponent sign */
|
||||
|
||||
/* packed bit widths */
|
||||
|
||||
#define XP_W_MSIGN 1 /* mantissa sign */
|
||||
#define XP_W_MANT 39 /* mantissa */
|
||||
#define XP_W_EXP 7 /* exponent */
|
||||
#define XP_W_ESIGN 1 /* exponent sign */
|
||||
|
||||
/* packed bit masks */
|
||||
|
||||
#define XP_M_MSIGN (((t_uint64) 1 << XP_W_MSIGN) - 1) /* mantissa sign */
|
||||
#define XP_M_MANT (((t_uint64) 1 << XP_W_MANT) - 1) /* mantissa */
|
||||
#define XP_M_EXP (((t_uint64) 1 << XP_W_EXP) - 1) /* exponent */
|
||||
#define XP_M_ESIGN (((t_uint64) 1 << XP_W_ESIGN) - 1) /* exponent sign */
|
||||
|
||||
/* packed field masks */
|
||||
|
||||
#define XP_MSIGN (XP_M_MSIGN << XP_V_MSIGN) /* mantissa sign */
|
||||
#define XP_MANT (XP_M_MANT << XP_V_MANT) /* mantissa */
|
||||
#define XP_SMANT (XP_MSIGN | XP_MANT) /* signed mantissa */
|
||||
|
||||
/* unpacked starting bit numbers */
|
||||
|
||||
#define XP_V_UMANT (0 + XP_PAD) /* signed mantissa */
|
||||
|
||||
/* unpacked bit widths */
|
||||
|
||||
#define XP_W_USMANT 48 /* signed mantissa */
|
||||
|
||||
/* unpacked bit masks */
|
||||
|
||||
#define XP_M_USMANT (((t_uint64) 1 << XP_W_USMANT) - 1) /* mantissa */
|
||||
|
||||
/* unpacked field masks */
|
||||
|
||||
#define XP_USMANT (XP_M_USMANT << XP_V_UMANT) /* signed mantissa */
|
||||
|
||||
/* values */
|
||||
|
||||
#define XP_ONEHALF ((t_int64) 1 << (XP_V_MSIGN - 1)) /* mantissa = 0.5 */
|
||||
#define XP_HALSBPOS ((t_int64) 1 << (XP_V_MANT - 1)) /* + 1/2 LSB */
|
||||
#define XP_HALSBNEG ((t_int64) XP_HALSBPOS - 1) /* - 1/2 LSB */
|
||||
#define XP_MAXPOS ((t_int64) XP_MANT) /* maximum pos mantissa */
|
||||
#define XP_MAXNEG ((t_int64) XP_MSIGN) /* maximum neg mantissa */
|
||||
#define XP_MAXEXP ((t_int64) XP_M_EXP) /* maximum pos exponent */
|
||||
|
||||
/* helpers */
|
||||
|
||||
#define DENORM(x) ((((x) ^ (x) << 1) & XP_MSIGN) == 0)
|
||||
|
||||
#define TO_INT64(xpn) ((t_int64) ((t_uint64) (xpn).high << 32 | (xpn).low))
|
||||
|
||||
/* internal unpacked extended-precision representation */
|
||||
|
||||
typedef struct { t_int64 mantissa;
|
||||
int32 exponent; } XPU;
|
||||
|
||||
/* Private routines */
|
||||
|
||||
|
||||
/* Pack an unpacked mantissa and exponent */
|
||||
|
||||
static XPN to_xpn (t_uint64 m, int32 e)
|
||||
{
|
||||
XPN packed;
|
||||
|
||||
packed.high = (uint32) (m >> 32);
|
||||
packed.low = (uint32) (m | ((e & XP_M_EXP) << XP_V_EXP) | ((e < 0) << XP_V_ESIGN));
|
||||
return packed;
|
||||
}
|
||||
|
||||
|
||||
/* Unpack a packed number */
|
||||
|
||||
static XPU unpack (XPN packed)
|
||||
{
|
||||
XPU unpacked;
|
||||
|
||||
unpacked.mantissa = TO_INT64 (packed) & XP_SMANT; /* left-justify mantissa */
|
||||
unpacked.exponent = (int8) ((packed.low >> XP_V_EXP & XP_M_EXP) | /* sign-extend exponent */
|
||||
packed.low >> (XP_V_ESIGN - XP_W_EXP));
|
||||
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
|
||||
/* Normalize an unpacked number */
|
||||
|
||||
static void normalize (XPU *unpacked)
|
||||
{
|
||||
if (unpacked->mantissa) { /* non-zero? */
|
||||
while (DENORM (unpacked->mantissa)) { /* normal form? */
|
||||
unpacked->exponent = unpacked->exponent - 1; /* no, so shift */
|
||||
unpacked->mantissa = unpacked->mantissa << 1; } }
|
||||
else unpacked->exponent = 0; /* clean for zero */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Round and pack an unpacked number */
|
||||
|
||||
static uint32 pack (XPN *packed, XPU unpacked)
|
||||
{
|
||||
int32 sign, overflow = 0;
|
||||
|
||||
normalize (&unpacked); /* normalize */
|
||||
sign = (unpacked.mantissa < 0); /* save sign */
|
||||
unpacked.mantissa = (unpacked.mantissa + /* round the number */
|
||||
(sign? XP_HALSBNEG: XP_HALSBPOS)) & XP_SMANT; /* mask off rounding bits */
|
||||
if (sign != (unpacked.mantissa < 0)) { /* pos overflow? */
|
||||
unpacked.mantissa = /* renormalize */
|
||||
(t_uint64) unpacked.mantissa >> 1 & XP_SMANT; /* and remask */
|
||||
unpacked.exponent = unpacked.exponent + 1; }
|
||||
else normalize (&unpacked); /* neg overflow? renorm */
|
||||
unpacked.mantissa = unpacked.mantissa & XP_SMANT;
|
||||
if (unpacked.mantissa == 0) /* result 0? */
|
||||
packed->high = packed->low = 0; /* return 0 */
|
||||
else if (unpacked.exponent < -(XP_MAXEXP + 1)) { /* underflow? */
|
||||
packed->high = packed->low = 0; /* return 0 */
|
||||
overflow = 1; } /* and set overflow */
|
||||
else if (unpacked.exponent > XP_MAXEXP) { /* overflow? */
|
||||
if (sign) *packed = to_xpn (XP_MAXNEG, XP_MAXEXP); /* return neg infinity */
|
||||
else *packed = to_xpn (XP_MAXPOS, XP_MAXEXP); /* or pos infinity */
|
||||
overflow = 1; } /* with overflow */
|
||||
else *packed = to_xpn (unpacked.mantissa, unpacked.exponent);
|
||||
return overflow;
|
||||
}
|
||||
|
||||
|
||||
/* Complement an unpacked number */
|
||||
|
||||
static void complement (XPU *result)
|
||||
{
|
||||
result->mantissa = -result->mantissa; /* negate mantissa */
|
||||
if (result->mantissa == XP_MAXNEG) { /* maximum negative? */
|
||||
result->mantissa = (t_uint64) result->mantissa >> 1; /* renormalize to pos */
|
||||
result->exponent = result->exponent + 1; } /* correct exponent */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Add two unpacked numbers
|
||||
|
||||
The mantissas are first aligned (if necessary) by scaling the smaller of the
|
||||
two operands. If the magnitude of the difference between the exponents is
|
||||
greater than the number of significant bits, then the smaller number has been
|
||||
scaled to zero, and so the sum is simply the larger operand. Otherwise, the
|
||||
sum is computed and checked for overflow, which has occured if the signs of
|
||||
the operands are the same but differ from that of the result. Scaling and
|
||||
renormalization is perfomed if overflow occurred. */
|
||||
|
||||
static void add (XPU *sum, XPU augend, XPU addend)
|
||||
{
|
||||
int32 magn;
|
||||
|
||||
if (augend.mantissa == 0) *sum = addend; /* x + 0 = x */
|
||||
else if (addend.mantissa == 0) *sum = augend; /* 0 + x = x */
|
||||
else {
|
||||
magn = augend.exponent - addend.exponent; /* difference exponents */
|
||||
if (magn > 0) { /* addend smaller? */
|
||||
*sum = augend; /* preset augend */
|
||||
addend.mantissa = addend.mantissa >> magn; } /* align addend */
|
||||
else { /* augend smaller? */
|
||||
*sum = addend; /* preset addend */
|
||||
magn = -magn; /* make difference positive */
|
||||
augend.mantissa = augend.mantissa >> magn; } /* align augend */
|
||||
if (magn <= XP_W_MANT + 1) { /* check mangitude */
|
||||
sum->mantissa = addend.mantissa + augend.mantissa; /* add mantissas */
|
||||
if (((addend.mantissa < 0) == (augend.mantissa < 0)) && /* chk overflow */
|
||||
((addend.mantissa < 0) != (sum->mantissa < 0))) {
|
||||
sum->mantissa = (addend.mantissa & XP_MSIGN) | /* restore sign */
|
||||
(t_uint64) sum->mantissa >> 1; /* renormalize */
|
||||
sum->exponent = sum->exponent + 1; } } } /* adjust exponent */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Multiply two unpacked numbers
|
||||
|
||||
The firmware first negates the operands as necessary so that the values are
|
||||
positive. Then it performs six of the nine 16-bit x 16-bit = 32-bit unsigned
|
||||
multiplications required for a full 96-bit product. Given a 48-bit
|
||||
multiplicand "a1a2a3" and a 48-bit multiplier "b1b2b3", the firmware performs
|
||||
these calculations to develop a 48-bit product:
|
||||
|
||||
a1 a2 a3
|
||||
+-------+-------+-------+
|
||||
b1 b2 b3
|
||||
+-------+-------+-------+
|
||||
_________________________
|
||||
|
||||
a1 * b3 [m1]
|
||||
+-------+-------+
|
||||
a2 * b2 [m2]
|
||||
+-------+-------+
|
||||
a1 * b2 [m3]
|
||||
+-------+-------+
|
||||
a3 * b1 [m4]
|
||||
+-------+-------+
|
||||
a2 * b1 [m5]
|
||||
+-------+-------+
|
||||
a1 * b1 [m6]
|
||||
+-------+-------+
|
||||
_________________________________
|
||||
|
||||
product
|
||||
+-------+-------+-------+
|
||||
|
||||
The least-significant words of intermediate multiplications [m1], [m2], and
|
||||
[m4] are used only to develop a carry bit into the 48-bit sum. The product
|
||||
is complemented if necessary to restore the sign.
|
||||
|
||||
Instead of implementing this algorithm directly, it is more efficient under
|
||||
simulation to use 32 x 32 = 64-bit multiplications, thereby reducing the
|
||||
number required from six to four. */
|
||||
|
||||
static void multiply (XPU *product, XPU multiplicand, XPU multiplier)
|
||||
{
|
||||
uint32 ah, al, bh, bl, carry, sign = 0;
|
||||
t_uint64 hi, m1, m2, m3;
|
||||
|
||||
if ((multiplicand.mantissa == 0) || (multiplier.mantissa == 0)) /* x * 0 = 0 */
|
||||
product->mantissa = product->exponent = 0;
|
||||
else {
|
||||
if (multiplicand.mantissa < 0) { /* negative? */
|
||||
complement (&multiplicand); /* complement operand */
|
||||
sign = ~sign; } /* track sign */
|
||||
if (multiplier.mantissa < 0) { /* negative? */
|
||||
complement (&multiplier); /* complement operand */
|
||||
sign = ~sign; } /* track sign */
|
||||
|
||||
product->exponent = multiplicand.exponent + /* compute exponent */
|
||||
multiplier.exponent + 1;
|
||||
|
||||
ah = (uint32) (multiplicand.mantissa >> 32); /* split multiplicand */
|
||||
al = (uint32) multiplicand.mantissa; /* into high and low parts */
|
||||
bh = (uint32) (multiplier.mantissa >> 32); /* split multiplier */
|
||||
bl = (uint32) multiplier.mantissa; /* into high and low parts */
|
||||
|
||||
hi = ((t_uint64) ah * bh); /* form four cross products */
|
||||
m1 = ((t_uint64) ah * bl); /* using 32 x 32 = 64-bit */
|
||||
m2 = ((t_uint64) al * bh); /* hardware multiplies */
|
||||
m3 = ((t_uint64) al * bl);
|
||||
|
||||
carry = ((uint32) m1 + (uint32) m2 + /* form a carry bit */
|
||||
(uint32) (m3 >> 32)) >> (31 - XP_V_UMANT); /* and align to LSB - 1 */
|
||||
|
||||
product->mantissa = (hi + (m1 >> 32) + /* align, sum, and mask */
|
||||
(m2 >> 32) + carry) & XP_USMANT;
|
||||
if (sign) complement (product); } /* negate if required */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Divide two unpacked numbers
|
||||
|
||||
The firmware performs division by calculating (1.0 / divisor) and then
|
||||
multiplying by the dividend. The simulator uses 64-bit division and uses a
|
||||
"divide-and-correct" algorithm similar to the one employed by the base set
|
||||
single-precision floating-point division routine. */
|
||||
|
||||
static void divide (XPU *quotient, XPU dividend, XPU divisor)
|
||||
{
|
||||
t_int64 bh, bl, m1, m2, m3, m4;
|
||||
|
||||
if (divisor.mantissa == 0) { /* division by zero? */
|
||||
if (dividend.mantissa < 0)
|
||||
quotient->mantissa = XP_MSIGN; /* return minus infinity */
|
||||
else quotient->mantissa = XP_MANT; /* or plus infinity */
|
||||
quotient->exponent = XP_MAXEXP + 1; }
|
||||
else if (dividend.mantissa == 0) /* dividend zero? */
|
||||
quotient->mantissa = quotient->exponent = 0; /* yes; result is zero */
|
||||
else {
|
||||
quotient->exponent = dividend.exponent - /* division subtracts exponents */
|
||||
divisor.exponent + 1;
|
||||
|
||||
bh = divisor.mantissa >> 32; /* split divisor */
|
||||
bl = divisor.mantissa & 0xFFFFFFFF;
|
||||
|
||||
m1 = (dividend.mantissa >> 2) / bh; /* form 1st partial quotient */
|
||||
m2 = (dividend.mantissa >> 2) % bh; /* obtain remainder */
|
||||
m3 = bl * m1; /* calculate correction */
|
||||
m4 = ((m2 - (m3 >> 32)) << 32) / bh; /* form 2nd partial quotient */
|
||||
|
||||
quotient->mantissa = (m1 << 32) + m4; /* merge quotients */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Global routines */
|
||||
|
||||
/* Extended-precision memory read */
|
||||
|
||||
XPN ReadX (uint32 va)
|
||||
{
|
||||
XPN packed;
|
||||
|
||||
packed.high = ReadW (va) << 16 | ReadW ((va + 1) & VAMASK);
|
||||
packed.low = ReadW ((va + 2) & VAMASK) << 16; /* read and pack */
|
||||
return packed;
|
||||
}
|
||||
|
||||
|
||||
/* Extended-precision memory write */
|
||||
|
||||
void WriteX (uint32 va, XPN packed)
|
||||
{
|
||||
WriteW (va, (packed.high >> 16) & DMASK); /* write high word */
|
||||
WriteW ((va + 1) & VAMASK, packed.high & DMASK); /* write middle word */
|
||||
WriteW ((va + 2) & VAMASK, (packed.low >> 16) & DMASK); /* write low word */
|
||||
}
|
||||
|
||||
|
||||
#if defined (HAVE_INT64)
|
||||
|
||||
/* Extended-precision add */
|
||||
|
||||
uint32 x_add (XPN *sum, XPN augend, XPN addend)
|
||||
{
|
||||
XPU usum, uaddend, uaugend;
|
||||
|
||||
uaugend = unpack (augend); /* unpack augend */
|
||||
uaddend = unpack (addend); /* unpack addend */
|
||||
add (&usum, uaugend, uaddend); /* calculate sum */
|
||||
return pack (sum, usum); /* pack sum */
|
||||
}
|
||||
|
||||
|
||||
/* Extended-precision subtract */
|
||||
|
||||
uint32 x_sub (XPN *difference, XPN minuend, XPN subtrahend)
|
||||
{
|
||||
XPU udifference, uminuend, usubtrahend;
|
||||
|
||||
uminuend = unpack (minuend); /* unpack minuend */
|
||||
usubtrahend = unpack (subtrahend); /* unpack subtrahend */
|
||||
complement (&usubtrahend); /* calculate difference */
|
||||
add (&udifference, uminuend, usubtrahend); /* pack difference */
|
||||
return pack (difference, udifference);
|
||||
}
|
||||
|
||||
|
||||
/* Extended-precision multiply */
|
||||
|
||||
uint32 x_mpy (XPN *product, XPN multiplicand, XPN multiplier)
|
||||
{
|
||||
XPU uproduct, umultiplicand, umultiplier;
|
||||
|
||||
umultiplicand = unpack (multiplicand); /* unpack multiplicand */
|
||||
umultiplier = unpack (multiplier); /* unpack multiplier */
|
||||
multiply (&uproduct, umultiplicand, umultiplier); /* calculate product */
|
||||
return pack (product, uproduct); /* pack product */
|
||||
}
|
||||
|
||||
|
||||
/* Extended-precision divide */
|
||||
|
||||
uint32 x_div (XPN *quotient, XPN dividend, XPN divisor)
|
||||
{
|
||||
XPU uquotient, udividend, udivisor;
|
||||
|
||||
udividend = unpack (dividend); /* unpack dividend */
|
||||
udivisor = unpack (divisor); /* unpack divisor */
|
||||
divide (&uquotient, udividend, udivisor); /* calculate quotient */
|
||||
return pack (quotient, uquotient); /* pack quotient */
|
||||
}
|
||||
|
||||
|
||||
/* Pack an extended-precision number
|
||||
|
||||
An unpacked mantissa is passed as a "packed" number with an unused exponent.
|
||||
*/
|
||||
uint32 x_pak (XPN *result, XPN mantissa, int32 exponent)
|
||||
{
|
||||
XPU unpacked;
|
||||
|
||||
unpacked.mantissa = TO_INT64 (mantissa); /* retrieve mantissa */
|
||||
unpacked.exponent = exponent; /* and exponent */
|
||||
return pack (result, unpacked); /* pack them */
|
||||
}
|
||||
|
||||
|
||||
/* Complement an extended-precision mantissa
|
||||
|
||||
An unpacked mantissa is passed as a "packed" number with an unused exponent.
|
||||
We return the exponent increment, i.e., either zero or one, depending on
|
||||
whether a renormalization was required. */
|
||||
|
||||
uint32 x_com (XPN *mantissa)
|
||||
{
|
||||
XPU unpacked;
|
||||
|
||||
unpacked.mantissa = TO_INT64 (*mantissa); /* retrieve mantissa */
|
||||
unpacked.exponent = 0; /* exponent is irrelevant */
|
||||
complement (&unpacked); /* negate it */
|
||||
*mantissa = to_xpn (unpacked.mantissa, 0); /* replace mantissa */
|
||||
return (uint32) unpacked.exponent; /* return exponent increment */
|
||||
}
|
||||
|
||||
|
||||
/* Complement an extended-precision number */
|
||||
|
||||
uint32 x_dcm (XPN *packed)
|
||||
{
|
||||
XPU unpacked;
|
||||
|
||||
unpacked = unpack (*packed); /* unpack the number */
|
||||
complement (&unpacked); /* negate it */
|
||||
return pack (packed, unpacked); /* and repack */
|
||||
}
|
||||
|
||||
|
||||
/* Truncate an extended-precision number */
|
||||
|
||||
void x_trun (XPN *result, XPN source)
|
||||
{
|
||||
t_uint64 mask;
|
||||
uint32 bitslost;
|
||||
XPU unpacked;
|
||||
const XPU one = { XP_ONEHALF, 1 }; /* 0.5 * 2 ** 1 = 1.0 */
|
||||
|
||||
unpacked = unpack (source);
|
||||
if (unpacked.exponent < 0) /* number < 0.5? */
|
||||
result->high = result->low = 0; /* return 0 */
|
||||
else if (unpacked.exponent > XP_W_MANT) /* no fractional bits? */
|
||||
*result = source; /* already integer */
|
||||
else {
|
||||
mask = (XP_MANT >> unpacked.exponent) & XP_MANT;/* mask fractional bits */
|
||||
bitslost = (uint32) (unpacked.mantissa & mask); /* flag if bits lost */
|
||||
unpacked.mantissa = unpacked.mantissa & ~mask; /* mask off fraction */
|
||||
if ((unpacked.mantissa < 0) && bitslost) /* negative? */
|
||||
add (&unpacked, unpacked, one); /* truncate toward zero */
|
||||
pack (result, unpacked); } /* (overflow cannot occur) */
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* defined (HAVE_INT64) */
|
||||
52
HP2100/hp2100_fp1.h
Normal file
52
HP2100/hp2100_fp1.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* hp2100_fp1.h: HP 2100/21MX extended-precision floating point definitions
|
||||
|
||||
Copyright (c) 2005, 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:
|
||||
|
||||
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.
|
||||
|
||||
Except as contained in this notice, the name of the author shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from the author.
|
||||
*/
|
||||
|
||||
#ifndef _HP2100_FP1_H_
|
||||
#define _HP2100_FP1_H_ 0
|
||||
|
||||
|
||||
/* HP memory representation of an extended-precision number */
|
||||
|
||||
typedef struct { uint32 high;
|
||||
uint32 low; } XPN;
|
||||
|
||||
|
||||
#define AS_XPN(x) (*(XPN *) &(x)) /* view as XPN */
|
||||
|
||||
|
||||
XPN ReadX (uint32 va);
|
||||
void WriteX (uint32 va, XPN packed);
|
||||
|
||||
uint32 x_add (XPN *sum, XPN augend, XPN addend);
|
||||
uint32 x_sub (XPN *difference, XPN minuend, XPN subtrahend);
|
||||
uint32 x_mpy (XPN *product, XPN multiplicand, XPN multiplier);
|
||||
uint32 x_div (XPN *quotient, XPN dividend, XPN divisor);
|
||||
uint32 x_pak (XPN *result, XPN mantissa, int32 exponent);
|
||||
uint32 x_com (XPN *mantissa);
|
||||
uint32 x_dcm (XPN *packed);
|
||||
void x_trun (XPN *result, XPN source);
|
||||
|
||||
#endif
|
||||
@@ -26,6 +26,7 @@
|
||||
ms 13181A 7970B 800bpi nine track magnetic tape
|
||||
13183A 7970E 1600bpi nine track magnetic tape
|
||||
|
||||
01-Mar-05 JDB Added SET OFFLINE; rewind/offline now does not detach
|
||||
07-Oct-04 JDB Fixed enable/disable from either device
|
||||
14-Aug-04 JDB Fixed many functional and timing problems (from Dave Bryan)
|
||||
- fixed erroneous execution of rejected command
|
||||
@@ -75,6 +76,9 @@
|
||||
#include "hp2100_defs.h"
|
||||
#include "sim_tape.h"
|
||||
|
||||
#define UNIT_V_OFFLINE (MTUF_V_UF + 0) /* unit offline */
|
||||
#define UNIT_OFFLINE (1 << UNIT_V_OFFLINE)
|
||||
|
||||
#define MS_NUMDR 4 /* number of drives */
|
||||
#define DB_N_SIZE 16 /* max data buf */
|
||||
#define DBSIZE (1 << DB_N_SIZE) /* max data cmd */
|
||||
@@ -190,6 +194,7 @@ t_stat msc_svc (UNIT *uptr);
|
||||
t_stat msc_reset (DEVICE *dptr);
|
||||
t_stat msc_attach (UNIT *uptr, char *cptr);
|
||||
t_stat msc_detach (UNIT *uptr);
|
||||
t_stat msc_online (UNIT *uptr, int32 value, char *cptr, void *desc);
|
||||
t_stat msc_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat ms_map_err (UNIT *uptr, t_stat st);
|
||||
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
@@ -250,10 +255,14 @@ DEVICE msd_dev = {
|
||||
*/
|
||||
|
||||
UNIT msc_unit[] = {
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) },
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE + UNIT_ROABLE + UNIT_DISABLE, 0) } };
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_OFFLINE, 0) },
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_OFFLINE, 0) },
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_OFFLINE, 0) },
|
||||
{ UDATA (&msc_svc, UNIT_ATTABLE | UNIT_ROABLE |
|
||||
UNIT_DISABLE | UNIT_OFFLINE, 0) } };
|
||||
|
||||
REG msc_reg[] = {
|
||||
{ ORDATA (STA, msc_sta, 12) },
|
||||
@@ -282,6 +291,8 @@ REG msc_reg[] = {
|
||||
{ NULL } };
|
||||
|
||||
MTAB msc_mod[] = {
|
||||
{ UNIT_OFFLINE, UNIT_OFFLINE, "offline", "OFFLINE", NULL },
|
||||
{ UNIT_OFFLINE, 0, "online", "ONLINE", msc_online },
|
||||
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
|
||||
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
|
||||
{ MTAB_XTD|MTAB_VUN, 0, "REEL", "REEL",
|
||||
@@ -396,7 +407,7 @@ case ioLIX: /* load */
|
||||
dat = 0;
|
||||
case ioMIX: /* merge */
|
||||
dat = dat | (msc_sta & ~STA_DYN); /* get card status */
|
||||
if (uptr->flags & UNIT_ATT) { /* online? */
|
||||
if ((uptr->flags & UNIT_OFFLINE) == 0) { /* online? */
|
||||
dat = dat | uptr->UST; /* add unit status */
|
||||
if (sim_is_active (uptr) && /* TBSY unless RWD at BOT */
|
||||
!((uptr->FNC & FNF_RWD) && (uptr->UST & STA_BOT)))
|
||||
@@ -482,14 +493,17 @@ devc = msc_dib.devno; /* get device nos */
|
||||
devd = msd_dib.devno;
|
||||
unum = uptr - msc_dev.units; /* get unit number */
|
||||
|
||||
if ((uptr->FNC != FNC_RWS) && !(uptr->flags & UNIT_ATT)) { /* offline? */
|
||||
if ((uptr->FNC != FNC_RWS) && (uptr->flags & UNIT_OFFLINE)) { /* offline? */
|
||||
msc_sta = (msc_sta | STA_REJ) & ~STA_BUSY; /* reject */
|
||||
setFSR (devc); /* set cch flg */
|
||||
return IORETURN (msc_stopioe, SCPE_UNATT); }
|
||||
|
||||
switch (uptr->FNC) { /* case on function */
|
||||
|
||||
case FNC_RWS: /* rewind offline */
|
||||
detach_unit (uptr); /* detach == offline */
|
||||
sim_tape_rewind (uptr); /* rewind tape */
|
||||
uptr->flags = uptr->flags | UNIT_OFFLINE; /* set offline */
|
||||
uptr->UST = STA_BOT; /* BOT when online again */
|
||||
break; /* we're done */
|
||||
|
||||
case FNC_REW: /* rewind */
|
||||
@@ -680,7 +694,9 @@ t_stat msc_attach (UNIT *uptr, char *cptr)
|
||||
t_stat r;
|
||||
|
||||
r = sim_tape_attach (uptr, cptr); /* attach unit */
|
||||
if (r == SCPE_OK) uptr->UST = STA_BOT; /* tape starts at BOT */
|
||||
if (r == SCPE_OK) {
|
||||
uptr->flags = uptr->flags & ~UNIT_OFFLINE; /* set online */
|
||||
uptr->UST = STA_BOT; } /* tape starts at BOT */
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -689,9 +705,18 @@ return r;
|
||||
t_stat msc_detach (UNIT* uptr)
|
||||
{
|
||||
uptr->UST = 0; /* update status */
|
||||
uptr->flags = uptr->flags | UNIT_OFFLINE; /* set offline */
|
||||
return sim_tape_detach (uptr); /* detach unit */
|
||||
}
|
||||
|
||||
/* Online routine */
|
||||
|
||||
t_stat msc_online (UNIT *uptr, int32 value, char *cptr, void *desc)
|
||||
{
|
||||
if (uptr->flags & UNIT_ATT) return SCPE_OK;
|
||||
else return SCPE_UNATT;
|
||||
}
|
||||
|
||||
/* Configure timing */
|
||||
|
||||
void ms_config_timing (void)
|
||||
|
||||
Reference in New Issue
Block a user