580
/* CPU modifier table.
582
The 21MX monikers are deprecated in favor of the 1000 designations. See the
583
"HP 1000 Series Naming History" on the back inside cover of the Technical
584
Reference Handbook. */
509
586
MTAB cpu_mod[] = {
510
{ UNIT_SYSTEM, UNIT_SYS_2116, NULL, "2116", &cpu_set_opt, NULL,
511
(void *) TYPE_211X },
512
{ UNIT_SYSTEM, UNIT_SYS_2100, NULL, "2100", &cpu_set_opt, NULL,
513
(void *) TYPE_2100 },
514
{ UNIT_SYSTEM, UNIT_SYS_21MX_E, NULL, "21MX-E", &cpu_set_opt, NULL,
515
(void *) TYPE_21MX },
516
{ UNIT_SYSTEM, UNIT_SYS_21MX_M, NULL, "21MX-M", &cpu_set_opt, NULL,
517
(void *) TYPE_21MX },
519
{ UNIT_CPU_MASK, UNIT_2116, "2116", NULL, NULL },
520
{ UNIT_CPU_MASK, UNIT_2100, "2100", NULL, NULL },
521
{ UNIT_CPU_MASK, UNIT_21MX_E, "21MX-E", NULL, NULL },
522
{ UNIT_CPU_MASK, UNIT_21MX_M, "21MX-M", NULL, NULL },
524
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt, NULL,
526
{ UNIT_EAU, 0, "no EAU", "NOEAU", &cpu_set_opt, NULL,
528
{ UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt, NULL,
530
{ UNIT_FP, 0, "no FP", "NOFP", &cpu_set_opt, NULL,
532
{ UNIT_IOP, UNIT_IOP, "IOP", "IOP", &cpu_set_opt, NULL,
534
{ UNIT_IOP, 0, "no IOP", "NOIOP", &cpu_set_opt, NULL,
536
{ UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt, NULL,
538
{ UNIT_DMS, 0, "no DMS", "NODMS", &cpu_set_opt, NULL,
540
{ UNIT_FFP, UNIT_FFP, "FFP", "FFP", &cpu_set_opt, NULL,
542
{ UNIT_FFP, 0, "no FFP", "NOFFP", &cpu_set_opt, NULL,
544
{ MTAB_XTD | MTAB_VDV, 4096, NULL, "4K", &cpu_set_size },
545
{ MTAB_XTD | MTAB_VDV, 8192, NULL, "8K", &cpu_set_size },
546
{ MTAB_XTD | MTAB_VDV, 16384, NULL, "16K", &cpu_set_size },
547
{ MTAB_XTD | MTAB_VDV, 32768, NULL, "32K", &cpu_set_size },
548
{ MTAB_XTD | MTAB_VDV, 65536, NULL, "64K", &cpu_set_size },
549
{ MTAB_XTD | MTAB_VDV, 131072, NULL, "128K", &cpu_set_size },
550
{ MTAB_XTD | MTAB_VDV, 262144, NULL, "256K", &cpu_set_size },
551
{ MTAB_XTD | MTAB_VDV, 524288, NULL, "512K", &cpu_set_size },
552
{ MTAB_XTD | MTAB_VDV, 1048576, NULL, "1024K", &cpu_set_size },
587
{ UNIT_MODEL_MASK, UNIT_2116, "", "2116", &cpu_set_model, &cpu_show_model, "2116" },
588
{ UNIT_MODEL_MASK, UNIT_2115, "", "2115", &cpu_set_model, &cpu_show_model, "2115" },
589
{ UNIT_MODEL_MASK, UNIT_2114, "", "2114", &cpu_set_model, &cpu_show_model, "2114" },
590
{ UNIT_MODEL_MASK, UNIT_2100, "", "2100", &cpu_set_model, &cpu_show_model, "2100" },
591
{ UNIT_MODEL_MASK, UNIT_1000_E, "", "1000-E", &cpu_set_model, &cpu_show_model, "1000-E" },
592
{ UNIT_MODEL_MASK, UNIT_1000_E, NULL, "21MX-E", &cpu_set_model, &cpu_show_model, "1000-E" },
593
{ UNIT_MODEL_MASK, UNIT_1000_M, "", "1000-M", &cpu_set_model, &cpu_show_model, "1000-M" },
594
{ UNIT_MODEL_MASK, UNIT_1000_M, NULL, "21MX-M", &cpu_set_model, &cpu_show_model, "1000-M" },
596
#if defined (HAVE_INT64)
597
{ UNIT_MODEL_MASK, UNIT_1000_F, "", "1000-F", &cpu_set_model, &cpu_show_model, "1000-F" },
600
{ MTAB_XTD | MTAB_VDV, 1, NULL, "LOADERENABLE", &cpu_set_ldr, NULL, NULL },
601
{ MTAB_XTD | MTAB_VDV, 0, NULL, "LOADERDISABLE", &cpu_set_ldr, NULL, NULL },
603
{ UNIT_EAU, UNIT_EAU, "EAU", "EAU", &cpu_set_opt, NULL, NULL },
604
{ UNIT_EAU, 0, "no EAU", NULL, NULL, NULL, NULL },
605
{ MTAB_XTD | MTAB_VDV, UNIT_EAU, NULL, "NOEAU", &cpu_clr_opt, NULL, NULL },
607
{ UNIT_FP, UNIT_FP, "FP", "FP", &cpu_set_opt, NULL, NULL },
608
{ UNIT_FP, 0, "no FP", NULL, NULL, NULL, NULL },
609
{ MTAB_XTD | MTAB_VDV, UNIT_FP, NULL, "NOFP", &cpu_clr_opt, NULL, NULL },
611
{ UNIT_IOP, UNIT_IOP, "IOP", "IOP", &cpu_set_opt, NULL, NULL },
612
{ UNIT_IOP, 0, "no IOP", NULL, NULL, NULL, NULL },
613
{ MTAB_XTD | MTAB_VDV, UNIT_IOP, NULL, "NOIOP", &cpu_clr_opt, NULL, NULL },
615
{ UNIT_DMS, UNIT_DMS, "DMS", "DMS", &cpu_set_opt, NULL, NULL },
616
{ UNIT_DMS, 0, "no DMS", NULL, NULL, NULL, NULL },
617
{ MTAB_XTD | MTAB_VDV, UNIT_DMS, NULL, "NODMS", &cpu_clr_opt, NULL, NULL },
619
{ UNIT_FFP, UNIT_FFP, "FFP", "FFP", &cpu_set_opt, NULL, NULL },
620
{ UNIT_FFP, 0, "no FFP", NULL, NULL, NULL, NULL },
621
{ MTAB_XTD | MTAB_VDV, UNIT_FFP, NULL, "NOFFP", &cpu_clr_opt, NULL, NULL },
623
{ UNIT_DBI, UNIT_DBI, "DBI", "DBI", &cpu_set_opt, NULL, NULL },
624
{ UNIT_DBI, 0, "no DBI", NULL, NULL, NULL, NULL },
625
{ MTAB_XTD | MTAB_VDV, UNIT_DBI, NULL, "NODBI", &cpu_clr_opt, NULL, NULL },
627
/* Future microcode support.
628
{ UNIT_EMA_VMA, UNIT_EMA, "EMA", "EMA", &cpu_set_opt, NULL, NULL },
629
{ MTAB_XTD | MTAB_VDV, UNIT_EMA, NULL, "NOEMA", &cpu_clr_opt, NULL, NULL },
631
{ UNIT_EMA_VMA, UNIT_VMAOS, "VMA", "VMA", &cpu_set_opt, NULL, NULL },
632
{ MTAB_XTD | MTAB_VDV, UNIT_VMAOS, NULL, "NOVMA", &cpu_clr_opt, NULL, NULL },
634
{ UNIT_EMA_VMA, 0, "no EMA/VMA", NULL, &cpu_set_opt, NULL, NULL },
636
{ UNIT_VIS, UNIT_VIS, "VIS", "VIS", &cpu_set_opt, NULL, NULL },
637
{ UNIT_VIS, 0, "no VIS", NULL, NULL, NULL, NULL },
638
{ MTAB_XTD | MTAB_VDV, UNIT_VIS, NULL, "NOVIS", &cpu_clr_opt, NULL, NULL },
640
{ UNIT_DS, UNIT_DS, "DS", "DS", &cpu_set_opt, NULL, NULL },
641
{ UNIT_DS, 0, "no DS", NULL, NULL, NULL, NULL },
642
{ MTAB_XTD | MTAB_VDV, UNIT_DS, NULL, "NODS", &cpu_clr_opt, NULL, NULL },
644
{ UNIT_SIGNAL, UNIT_SIGNAL,"SIGNAL", "SIGNAL", &cpu_set_opt, NULL, NULL },
645
{ UNIT_SIGNAL, 0, "no SIGNAL", NULL, NULL, NULL, NULL },
646
{ MTAB_XTD | MTAB_VDV, UNIT_SIGNAL, NULL, "NOSIGNAL", &cpu_clr_opt, NULL, NULL },
649
{ MTAB_XTD | MTAB_VDV, 4096, NULL, "4K", &cpu_set_size, NULL, NULL },
650
{ MTAB_XTD | MTAB_VDV, 8192, NULL, "8K", &cpu_set_size, NULL, NULL },
651
{ MTAB_XTD | MTAB_VDV, 12288, NULL, "12K", &cpu_set_size, NULL, NULL },
652
{ MTAB_XTD | MTAB_VDV, 16384, NULL, "16K", &cpu_set_size, NULL, NULL },
653
{ MTAB_XTD | MTAB_VDV, 24576, NULL, "24K", &cpu_set_size, NULL, NULL },
654
{ MTAB_XTD | MTAB_VDV, 32768, NULL, "32K", &cpu_set_size, NULL, NULL },
655
{ MTAB_XTD | MTAB_VDV, 65536, NULL, "64K", &cpu_set_size, NULL, NULL },
656
{ MTAB_XTD | MTAB_VDV, 131072, NULL, "128K", &cpu_set_size, NULL, NULL },
657
{ MTAB_XTD | MTAB_VDV, 262144, NULL, "256K", &cpu_set_size, NULL, NULL },
658
{ MTAB_XTD | MTAB_VDV, 524288, NULL, "512K", &cpu_set_size, NULL, NULL },
659
{ MTAB_XTD | MTAB_VDV, 1048576, NULL, "1024K", &cpu_set_size, NULL, NULL },
2095
2353
return is_conflict;
2098
/* Configuration validation
2100
- Checks that the current CPU type supports the option selected.
2101
- Ensures that FP/FFP and IOP are mutually exclusive if CPU is 2100.
2102
- Disables memory protect if 2116 is selected.
2103
- Enables memory protect if 2100 or 21MX or DMS is selected.
2104
- Enables DMA if 2116 or 2100 or 21MX is selected.
2105
- Memory is trimmed to 32K if 2116 or 2100 is selected. */
2107
t_bool cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
2109
int32 opt = (int32) desc;
2356
/* Change CPU memory size.
2358
On a 21xx, move the current loader to the top of the new memory size. Then
2359
clear "non-existent memory" so that reads return zero, per spec.
2362
- New size <= maximum size for current CPU.
2363
- New size a positive multiple of 4K (progamming error if not).
2364
- If new size < old size, truncation accepted.
2367
t_stat cpu_set_size (UNIT *uptr, int32 new_size, char *cptr, void *desc)
2371
uint32 model = CPU_MODEL_INDEX; /* current CPU model index */
2372
uint32 old_size = MEMSIZE; /* current memory size */
2374
if ((uint32) new_size > cpu_features[model].maxmem)
2375
return SCPE_NOFNC; /* mem size unsupported */
2377
if ((new_size <= 0) || (new_size > PASIZE) || ((new_size & 07777) != 0))
2378
return SCPE_NXM; /* invalid size (prog err) */
2380
if (!(sim_switches & SWMASK ('F'))) { /* force truncation? */
2381
for (i = new_size; i < MEMSIZE; i++) mc = mc | M[i];
2382
if ((mc != 0) && (!get_yn ("Really truncate memory [N]?", FALSE)))
2386
if (UNIT_CPU_FAMILY == UNIT_FAMILY_21XX) { /* 21xx CPU? */
2387
cpu_set_ldr (uptr, FALSE, NULL, NULL); /* save loader to shadow RAM */
2388
MEMSIZE = new_size; /* set new memory size */
2389
fwanxm = MEMSIZE - IBL_LNT; /* reserve memory for loader */
2391
else /* loader unsupported */
2392
fwanxm = MEMSIZE = new_size; /* set new memory size */
2394
for (i = fwanxm; i < old_size; i++) M[i] = 0; /* zero non-existent memory */
2398
/* Change CPU models.
2400
For convenience, MP and DMA are typically enabled if available; they may be
2401
disabled subsequently if desired. Note that the 2114 supports only one DMA
2402
channel (channel 0). All other models support two channels.
2405
- Sets standard equipment and convenience features.
2406
- Changes DMA device name to DCPC if 1000 is selected.
2407
- Enforces maximum memory allowed (doesn't change otherwise).
2408
- Disables loader on 21xx machines.
2411
t_stat cpu_set_model (UNIT *uptr, int32 new_model, char *cptr, void *desc)
2413
uint32 old_family = UNIT_CPU_FAMILY; /* current CPU type */
2414
uint32 new_family = new_model & UNIT_FAMILY_MASK; /* new CPU family */
2415
uint32 new_index = new_model >> UNIT_V_CPU; /* new CPU model index */
2419
cpu_unit.flags = cpu_unit.flags & ~UNIT_OPTS | /* set typical features */
2420
cpu_features[new_index].typ & UNIT_OPTS; /* mask pseudo-opts */
2423
if (cpu_features[new_index].typ & UNIT_MP) /* MP in typ config? */
2424
mp_dev.flags = mp_dev.flags & ~DEV_DIS; /* enable it */
2426
mp_dev.flags = mp_dev.flags | DEV_DIS; /* disable it */
2428
if (cpu_features[new_index].opt & UNIT_MP) /* MP an option? */
2429
mp_dev.flags = mp_dev.flags | DEV_DISABLE; /* make it alterable */
2431
mp_dev.flags = mp_dev.flags & ~DEV_DISABLE; /* make it unalterable */
2434
if (cpu_features[new_index].typ & UNIT_DMA) { /* DMA in typ config? */
2435
dma0_dev.flags = dma0_dev.flags & ~DEV_DIS; /* enable DMA channel 0 */
2437
if (new_model == UNIT_2114) /* 2114 has only one channel */
2438
dma1_dev.flags = dma1_dev.flags | DEV_DIS; /* disable channel 1 */
2439
else /* all others have two channels */
2440
dma1_dev.flags = dma1_dev.flags & ~DEV_DIS; /* enable it */
2443
dma0_dev.flags = dma0_dev.flags | DEV_DIS; /* disable channel 0 */
2444
dma1_dev.flags = dma1_dev.flags | DEV_DIS; /* disable channel 1 */
2447
if (cpu_features[new_index].opt & UNIT_DMA) { /* DMA an option? */
2448
dma0_dev.flags = dma0_dev.flags | DEV_DISABLE; /* make it alterable */
2450
if (new_model == UNIT_2114) /* 2114 has only one channel */
2451
dma1_dev.flags = dma1_dev.flags & ~DEV_DISABLE; /* make it unalterable */
2452
else /* all others have two channels */
2453
dma1_dev.flags = dma1_dev.flags | DEV_DISABLE; /* make it alterable */
2456
dma0_dev.flags = dma0_dev.flags & ~DEV_DISABLE; /* make it unalterable */
2457
dma1_dev.flags = dma1_dev.flags & ~DEV_DISABLE; /* make it unalterable */
2461
if ((old_family == UNIT_FAMILY_1000) && /* if current family is 1000 */
2462
(new_family == UNIT_FAMILY_21XX)) { /* and new family is 21xx */
2463
deassign_device (&dma0_dev); /* delete DCPC names */
2464
deassign_device (&dma1_dev);
2466
else if ((old_family == UNIT_FAMILY_21XX) && /* if current family is 21xx */
2467
(new_family == UNIT_FAMILY_1000)) { /* and new family is 1000 */
2468
assign_device (&dma0_dev, "DCPC0"); /* change DMA device name */
2469
assign_device (&dma1_dev, "DCPC1"); /* to DCPC for familiarity */
2472
if ((MEMSIZE == 0) || /* current mem size not set? */
2473
(MEMSIZE > cpu_features[new_index].maxmem)) /* current mem size too large? */
2474
new_memsize = cpu_features[new_index].maxmem; /* set it to max supported */
2476
new_memsize = MEMSIZE; /* or leave it unchanged */
2478
result = cpu_set_size (uptr, new_memsize, NULL, NULL); /* set memory size */
2480
if (result == SCPE_OK) /* memory change OK? */
2481
if (new_family == UNIT_FAMILY_21XX) /* 21xx CPU? */
2482
fwanxm = MEMSIZE - IBL_LNT; /* reserve memory for loader */
2484
fwanxm = MEMSIZE; /* loader reserved only for 21xx */
2489
/* Display the CPU model and optional loader status.
2491
Loader status is displayed for 21xx models and suppressed for 1000 models.
2494
t_stat cpu_show_model (FILE *st, UNIT *uptr, int32 val, void *desc)
2496
fputs ((char *) desc, st); /* write model name */
2498
if (UNIT_CPU_FAMILY == UNIT_FAMILY_21XX) /* valid only for 21xx */
2499
if (fwanxm < MEMSIZE) /* loader area non-existent? */
2500
fputs (", loader disabled", st); /* yes, so access disabled */
2502
fputs (", loader enabled", st); /* no, so access enabled */
2506
/* Set a CPU option.
2509
- Checks that the current CPU model supports the option selected.
2510
- If CPU is 2100, ensures that FP/FFP and IOP are mutually exclusive.
2511
- If CPU is 2100, ensures that FP is enabled if FFP enabled
2512
(FP is required for FFP installation).
2515
t_stat cpu_set_opt (UNIT *uptr, int32 option, char *cptr, void *desc)
2517
uint32 model = CPU_MODEL_INDEX; /* current CPU model index */
2519
if ((cpu_features[model].opt & option) == 0) /* option supported? */
2520
return SCPE_NOFNC; /* no */
2522
if (UNIT_CPU_TYPE == UNIT_TYPE_2100) {
2523
if ((option == UNIT_FP) || (option == UNIT_FFP)) /* 2100 IOP and FP/FFP options */
2524
uptr->flags = uptr->flags & ~UNIT_IOP; /* are mutually exclusive */
2525
else if (option == UNIT_IOP)
2526
uptr->flags = uptr->flags & ~(UNIT_FP | UNIT_FFP);
2528
if (option == UNIT_FFP) /* 2100 FFP option requires FP */
2529
uptr->flags = uptr->flags | UNIT_FP;
2535
/* Clear a CPU option.
2538
- Checks that the current CPU model supports the option selected.
2539
- Clears flag from unit structure (we are processing MTAB_XTD entries).
2540
- If CPU is 2100, ensures that FFP is disabled if FP disabled
2541
(FP is required for FFP installation).
2544
t_bool cpu_clr_opt (UNIT *uptr, int32 option, char *cptr, void *desc)
2546
uint32 model = CPU_MODEL_INDEX; /* current CPU model index */
2548
if ((cpu_features[model].opt & option) == 0) /* option supported? */
2549
return SCPE_NOFNC; /* no */
2551
uptr->flags = uptr->flags & ~option; /* disable option */
2553
if ((UNIT_CPU_TYPE == UNIT_TYPE_2100) && /* disabling 2100 FP? */
2554
(option == UNIT_FP))
2555
uptr->flags = uptr->flags & ~UNIT_FFP; /* yes, so disable FFP too */
2560
/* 21xx loader enable/disable function.
2562
The 21xx CPUs store their initial binary loaders in the last 64 words of
2563
available memory. This memory is protected by a LOADER ENABLE switch on the
2564
front panel. When the switch is off (disabled), main memory effectively ends
2565
64 locations earlier, i.e., the loader area is treated as non-existent.
2566
Because these are core machines, the loader is retained when system power is
2569
1000 CPUs do not have a protected loader feature. Instead, loaders are
2570
stored in PROMs and are copied into main memory for execution by the IBL
2573
Under simulation, we keep both a total configured memory size (MEMSIZE) and a
2574
current configured memory size (fwanxm = "first word address of non-existent
2575
memory). When the two are equal, the loader is enabled. When the current
2576
size is less than the total size, the loader is disabled.
2578
Disabling the loader copies the last 64 words to a shadow array, zeros the
2579
corresponding memory, and decreases the last word of addressable memory by
2580
64. Enabling the loader reverses this process.
2582
Disabling may be done manually by user command or automatically when a halt
2583
instruction is executed. Enabling occurs only by user command. This differs
2584
slightly from actual machine operation, which additionally disables the
2585
loader when a manual halt is performed. We do not do this to allow
2586
breakpoints within and single-stepping through the loaders.
2589
t_stat cpu_set_ldr (UNIT *uptr, int32 enable, char *cptr, void *desc)
2591
static uint16 loader[IBL_LNT];
2114
for (i = 0; opt_val[i].cpuf != 0; i++) {
2115
if ((opt == opt_val[i].optf) && (mod & opt_val[i].cpuf)) {
2116
if (mod == MOD_2100)
2117
if ((opt == UNIT_FP) || (opt == UNIT_FFP))
2118
uptr->flags = uptr->flags & ~UNIT_IOP;
2119
else if (opt == UNIT_IOP)
2120
uptr->flags = uptr->flags & ~(UNIT_FP | UNIT_FFP);
2121
if (opt == TYPE_211X)
2122
mp_dev.flags = mp_dev.flags | DEV_DIS;
2123
else if ((opt == UNIT_DMS) || (opt == TYPE_2100) || (opt == TYPE_21MX))
2124
mp_dev.flags = mp_dev.flags & ~DEV_DIS;
2125
if ((opt == TYPE_211X) || (opt == TYPE_2100) || (opt == TYPE_21MX)) {
2126
dma0_dev.flags = dma0_dev.flags & ~DEV_DIS;
2127
dma1_dev.flags = dma1_dev.flags & ~DEV_DIS;
2129
if (((opt == TYPE_211X) || (opt == TYPE_2100)) && (MEMSIZE > VASIZE))
2130
return cpu_set_size (uptr, VASIZE, cptr, desc);
2593
t_bool is_enabled = (fwanxm == MEMSIZE);
2595
if ((UNIT_CPU_FAMILY != UNIT_FAMILY_21XX) || /* valid only for 21xx */
2596
(MEMSIZE == 0)) /* and for initialized memory */
2599
if (is_enabled && (enable == 0)) { /* disable loader? */
2600
fwanxm = MEMSIZE - IBL_LNT; /* decrease available memory */
2601
for (i = 0; i < IBL_LNT; i++) { /* copy loader */
2602
loader[i] = M[fwanxm + i]; /* from memory */
2603
M[fwanxm + i] = 0; /* and zero location */
2607
else if ((!is_enabled) && (enable == 1)) { /* enable loader? */
2608
for (i = 0; i < IBL_LNT; i++) /* copy loader */
2609
M[fwanxm + i] = loader[i]; /* to memory */
2610
fwanxm = MEMSIZE; /* increase available memory */
2137
2616
/* IBL routine (CPU boot) */