1
0
mirror of https://github.com/simh/simh.git synced 2026-01-26 12:02:14 +00:00

Notes For V3.2-1

RESTRICTION: The PDP-15 FPP is only partially debugged.  Do NOT
enable this feature for normal operations.

1. New Features in 3.2-1

1.1 SCP and libraries

- Added SET CONSOLE subhierarchy.
- Added SHOW CONSOLE subhierarchy.
- Added limited keyboard mapping capability.

1.2 HP2100 (new features from Dave Bryan)

- Added instruction printout to HALT message.
- Added M and T internal registers.
- Added N, S, and U breakpoints.

1.3 PDP-11 and VAX

- Added DHQ11 support (from John Dundas)

2. Bugs Fixed in 3.2-1

2.1 HP2100 (most fixes from Dave Bryan)

- SBT increments B after store.
- DMS console map must check dms_enb.
- SFS x,C and SFC x,C work.
- MP violation clears automatically on interrupt.
- SFS/SFC 5 is not gated by protection enabled.
- DMS enable does not disable mem prot checks.
- DMS status inconsistent at simulator halt.
- Examine/deposit are checking wrong addresses.
- Physical addresses are 20b not 15b.
- Revised DMS to use memory rather than internal format.
- Revised IBL facility to conform to microcode.
- Added DMA EDT I/O pseudo-opcode.
- Separated DMA SRQ (service request) from FLG.
- Revised peripherals to make SFS x,C and SFC x,C work.
- Revised boot ROMs to use IBL facility.
- Revised IBL treatment of SR to preserve SR<5:3>.
- Fixed LPS, LPT timing.
- Fixed DP boot interpretation of SR<0>.
- Revised DR boot code to use IBL algorithm.
- Fixed TTY input behavior during typeout for RTE-IV.
- Suppressed nulls on TTY output for RTE-IV.
- Added SFS x,C and SFC x,C to print/parse routines.
- Fixed spurious timing error in magtape reads.

2.2 All DEC console devices

- Removed SET TTI CTRL-C option.

2.3 PDP-11/VAX peripherals

- Fixed bug in TQ reporting write protect status (reported by Lyle Bickley).
- Fixed TK70 model number and media ID (found by Robert Schaffrath).
- Fixed bug in autoconfigure (found by John Dundas).

2.4 VAX

- Fixed bug in DIVBx and DIVWx (reported by Peter Trimmel).
This commit is contained in:
Bob Supnik
2004-07-10 06:13:00 -07:00
committed by Mark Pizzolato
parent 26aa6de663
commit e2ba672610
75 changed files with 14174 additions and 2343 deletions

View File

@@ -23,6 +23,23 @@
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.
14-May-04 RMS Fixed bugs and added features from Dave Bryan
- SBT increments B after store
- DMS console map must check dms_enb
- SFS x,C and SFC x,C work
- MP violation clears automatically on interrupt
- SFS/SFC 5 is not gated by protection enabled
- DMS enable does not disable mem prot checks
- DMS status inconsistent at simulator halt
- Examine/deposit are checking wrong addresses
- Physical addresses are 20b not 15b
- Revised DMS to use memory rather than internal format
- Added instruction printout to HALT message
- Added M and T internal registers
- Added N, S, and U breakpoints
Revised IBL facility to conform to microcode
Added DMA EDT I/O pseudo-opcode
Separated DMA SRQ (service request) from FLG
12-Mar-03 RMS Added logical name support
02-Feb-03 RMS Fixed last cycle bug in DMA output (found by Mike Gemeny)
22-Nov-02 RMS Added 21MX IOP support
@@ -55,6 +72,8 @@
BR<15:0> B register - addressable as location 1
PC<14:0> P register (program counter)
SR<15:0> S register
MR<14:0> M register - memory address
TR<15:0> T register - memory data
E extend flag (carry out)
O overflow flag
@@ -232,12 +251,13 @@
unknown I/O device and stop_dev flag set
I/O error in I/O simulator
2. Interrupts. I/O devices are modelled as four parallel arrays:
2. Interrupts. I/O devices are modelled as five parallel arrays:
device commands as bit array dev_cmd[2][31..0]
device flags as bit array dev_flg[2][31..0]
device flag buffers as bit array dev_fbf[2][31..0]
device controls as bit array dev_ctl[2][31..0]
device service requests as bit array dev_srq[3][31..0]
The HP 2100 interrupt structure is based on flag, flag buffer,.
and control. If a device flag is set, the flag buffer is set,
@@ -251,6 +271,8 @@
tells whether a device is active. It is set by STC and cleared
by CLC; it is also cleared when the device flag is set. Simple
devices don't need to track command separately from control.
Service requests are used to trigger the DMA service logic.
3. Non-existent memory. On the HP 2100, reads to non-existent memory
return zero, and writes are ignored. In the simulator, the
@@ -308,11 +330,15 @@
#define DMAR0 1
#define DMAR1 2
#define ALL_BKPTS (SWMASK('E')|SWMASK('N')|SWMASK('S')|SWMASK('U'))
uint16 *M = NULL; /* memory */
uint32 saved_AR = 0; /* A register */
uint32 saved_BR = 0; /* B register */
uint32 PC = 0; /* P register */
uint32 SR = 0; /* S register */
uint32 MR = 0; /* M register */
uint32 TR = 0; /* T register */
uint32 XR = 0; /* X register */
uint32 YR = 0; /* Y register */
uint32 E = 0; /* E register */
@@ -321,6 +347,7 @@ uint32 dev_cmd[2] = { 0 }; /* device command */
uint32 dev_ctl[2] = { 0 }; /* device control */
uint32 dev_flg[2] = { 0 }; /* device flags */
uint32 dev_fbf[2] = { 0 }; /* device flag bufs */
uint32 dev_srq[2] = { 0 }; /* device svc reqs */
struct DMA dmac[2] = { { 0 }, { 0 } }; /* DMA channels */
uint32 ion = 0; /* interrupt enable */
uint32 ion_defer = 0; /* interrupt defer */
@@ -334,7 +361,7 @@ uint32 dms_enb = 0; /* dms enable */
uint32 dms_ump = 0; /* dms user map */
uint32 dms_sr = 0; /* dms status reg */
uint32 dms_vr = 0; /* dms violation reg */
uint32 dms_map[MAP_NUM * MAP_LNT] = { 0 }; /* dms maps */
uint16 dms_map[MAP_NUM * MAP_LNT] = { 0 }; /* dms maps */
uint32 iop_sp = 0; /* iop stack */
uint32 ind_max = 16; /* iadr nest limit */
uint32 stop_inst = 1; /* stop on ill inst */
@@ -361,6 +388,7 @@ extern int32 sim_int_char;
extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern FILE *sim_log;
extern DEVICE *sim_devices[];
extern char halt_msg[];
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq);
t_stat Ea1 (uint32 *addr, uint32 irq);
@@ -390,6 +418,7 @@ void dma_cycle (uint32 chan, uint32 map);
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_reset (DEVICE *dptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
t_stat dma0_reset (DEVICE *dptr);
t_stat dma1_reset (DEVICE *dptr);
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
@@ -417,18 +446,20 @@ REG cpu_reg[] = {
{ ORDATA (P, PC, 15) },
{ ORDATA (A, saved_AR, 16) },
{ ORDATA (B, saved_BR, 16) },
{ ORDATA (M, MR, 15) },
{ ORDATA (T, TR, 16), REG_RO },
{ ORDATA (X, XR, 16) },
{ ORDATA (Y, YR, 16) },
{ ORDATA (S, SR, 16) },
{ ORDATA (F, mp_fence, 15) },
{ FLDATA (E, E, 0) },
{ FLDATA (O, O, 0) },
{ FLDATA (ION, ion, 0) },
{ FLDATA (ION_DEFER, ion_defer, 0) },
{ ORDATA (IADDR, intaddr, 6) },
{ ORDATA (CIR, intaddr, 6) },
{ FLDATA (MPCTL, dev_ctl[PRO/32], INT_V (PRO)) },
{ FLDATA (MPFLG, dev_flg[PRO/32], INT_V (PRO)) },
{ FLDATA (MPFBF, dev_fbf[PRO/32], INT_V (PRO)) },
{ ORDATA (MPFR, mp_fence, 15) },
{ ORDATA (MPVR, mp_viol, 16) },
{ FLDATA (MPMEV, mp_mevff, 0) },
{ FLDATA (MPEVR, mp_evrff, 0) },
@@ -436,7 +467,7 @@ REG cpu_reg[] = {
{ FLDATA (DMSCUR, dms_ump, VA_N_PAG) },
{ ORDATA (DMSSR, dms_sr, 16) },
{ ORDATA (DMSVR, dms_vr, 16) },
{ BRDATA (DMSMAP, dms_map, 8, PA_N_SIZE, MAP_NUM * MAP_LNT) },
{ BRDATA (DMSMAP, dms_map, 8, 16, MAP_NUM * MAP_LNT) },
{ ORDATA (IOPSP, iop_sp, 16) },
{ FLDATA (STOP_INST, stop_inst, 0) },
{ FLDATA (STOP_DEV, stop_dev, 1) },
@@ -452,6 +483,8 @@ REG cpu_reg[] = {
{ ORDATA (LFLG, dev_flg[1], 32), REG_HRO },
{ ORDATA (HFBF, dev_fbf[0], 32), REG_HRO },
{ ORDATA (LFBF, dev_fbf[1], 32), REG_HRO },
{ ORDATA (HSRQ, dev_srq[0], 32), REG_HRO },
{ ORDATA (LSRQ, dev_srq[1], 32), REG_HRO },
{ NULL } };
MTAB cpu_mod[] = {
@@ -499,9 +532,9 @@ MTAB cpu_mod[] = {
DEVICE cpu_dev = {
"CPU", &cpu_unit, cpu_reg, cpu_mod,
1, 8, 15, 1, 8, 16,
1, 8, PA_N_SIZE, 1, 8, 16,
&cpu_ex, &cpu_dep, &cpu_reset,
NULL, NULL, NULL };
&cpu_boot, NULL, NULL };
/* DMA controller data structures
@@ -663,6 +696,7 @@ int32 (*dtab[64])() = {
t_stat sim_instr (void)
{
uint32 intrq, dmarq; /* set after setjmp */
uint32 iotrap = 0; /* set after setjmp */
t_stat reason; /* set after setjmp */
int32 i, dev; /* temp */
DEVICE *dptr; /* temp */
@@ -684,6 +718,7 @@ dev_cmd[0] = dev_cmd[0] & M_FXDEV; /* clear dynamic info */
dev_ctl[0] = dev_ctl[0] & M_FXDEV;
dev_flg[0] = dev_flg[0] & M_FXDEV;
dev_fbf[0] = dev_fbf[0] & M_FXDEV;
dev_srq[0] = dev_srq[1] = 0; /* init svc requests */
dev_cmd[1] = dev_ctl[1] = dev_flg[1] = dev_fbf[1] = 0;
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
@@ -694,6 +729,7 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
if (dibp->flg) { setFLG (dev); } /* restore flg */
clrFBF (dev); /* also sets fbf */
if (dibp->fbf) { setFBF (dev); } /* restore fbf */
if (dibp->srq) { setSRQ (dev); } /* restore srq */
dtab[dev] = dibp->iot; } } /* set I/O dispatch */
sim_rtc_init (clk_delay (0)); /* recalibrate clock */
@@ -719,7 +755,7 @@ while (reason == 0) { /* loop until halted */
uint32 IR, MA, M1, absel, v1, v2, t;
uint32 fop, eop, etype, eflag;
uint32 skip, mapi, mapj, qs, rs;
uint32 awc, sc, wc, hp, tp, iotrap;
uint32 awc, sc, wc, hp, tp;
int32 sop1, sop2;
if (sim_interval <= 0) { /* check clock queue */
@@ -733,9 +769,21 @@ if (dmarq) {
dmarq = calc_dma (); /* recalc DMA reqs */
intrq = calc_int (); } /* recalc interrupts */
/* (From Dave Bryan)
Unlike most other I/O devices, the MP flag flip-flop is cleared
automatically when the interrupt is acknowledged and not by a programmed
instruction (CLF and STF affect the parity error enable FF instead).
Section 4.4.3 "Memory Protect and I/O Interrupt Generation" of the "HP 1000
M/E/F-Series Computers Engineering and Reference Documentation" (HP
92851-90001) says:
"When IAK occurs and IRQ5 is asserted, the FLAGBFF is cleared, FLAGFF
clocked off at next T2, and IRQ5 will no longer occur." */
if (intrq && ((intrq <= PRO) || !ion_defer)) { /* interrupt request? */
iotrap = 1; /* I/O trap cell instr */
clrFBF (intrq); /* clear flag buffer */
if (intrq == PRO) clrFLG (PRO); /* MP flag follows flag buffer */
intaddr = intrq; /* save int addr */
if (dms_enb) dms_sr = dms_sr | MST_ENBI; /* dms enabled? */
else dms_sr = dms_sr & ~MST_ENBI;
@@ -752,8 +800,12 @@ if (intrq && ((intrq <= PRO) || !ion_defer)) { /* interrupt request? */
else { iotrap = 0; /* normal instruction */
err_PC = PC; /* save PC for error */
if (sim_brk_summ &&
sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */
if (sim_brk_summ && /* any breakpoints? */
sim_brk_test (PC, ALL_BKPTS) && /* at this location? */
(sim_brk_test (PC, SWMASK ('E')) || /* unconditional? */
sim_brk_test (PC, dms_enb? /* or right type for DMS? */
(dms_ump? SWMASK ('U'): SWMASK ('S')):
SWMASK ('N')))) {
reason = STOP_IBKPT; /* stop simulation */
break; }
if (mp_evrff) mp_viol = PC; /* if ok, upd mp_viol */
@@ -1200,19 +1252,23 @@ case 0203:case 0213: /* MAC1 ext */
break;
case 0221: /* IOP PRFIO (I_NO) */
case 0473: /* IOPX PFRIO (I_NO) */
IR = ReadW (PC); /* get IO instr */
t = ReadW (PC); /* get IO instr */
PC = (PC + 1) & VAMASK;
WriteW (PC, 1); /* set flag */
PC = (PC + 1) & VAMASK;
reason = iogrp (IR, 0); /* execute instr */
reason = iogrp (t, 0); /* execute instr */
dmarq = calc_dma (); /* recalc DMA */
intrq = calc_int (); /* recalc interrupts */
break;
case 0222: /* IOP PRFEI (I_NO) */
case 0471: /* IOPX PFREI (I_NO) */
IR = ReadW (PC); /* get IO instr */
t = ReadW (PC); /* get IO instr */
PC = (PC + 1) & VAMASK;
WriteW (PC, 1); /* set flag */
PC = (PC + 1) & VAMASK;
reason = iogrp (IR, 0); /* execute instr */
reason = iogrp (t, 0); /* execute instr */
dmarq = calc_dma (); /* recalc DMA */
intrq = calc_int (); /* recalc interrupts */
/* fall through */
case 0223: /* IOP PRFEX (I_NO) */
case 0472: /* IOPX PFREX (I_NO) */
@@ -1655,6 +1711,7 @@ case 0203:case 0213: /* MAC1 ext */
break;
case 0764: /* SBT (E_NO) */
WriteB (BR, AR); /* store byte */
BR = (BR + 1) & DMASK; /* incr ptr */
break;
IOP_MBYTE: /* IOP MBYTE (I_AZ) */
if (wc & SIGN) break; /* must be positive */
@@ -1763,8 +1820,12 @@ if (reason == STOP_INDINT) { /* indirect intr? */
/* Simulation halted */
if (iotrap && (reason == STOP_HALT)) MR = intaddr; /* HLT in trap cell? */
else MR = (PC - 1) & VAMASK; /* no, M = P - 1 */
TR = ReadIO (MR, dms_ump); /* last word fetched */
saved_AR = AR & DMASK;
saved_BR = BR & DMASK;
dms_upd_sr (); /* update dms_sr */
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp) { /* exist? */
@@ -1772,7 +1833,8 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp->cmd = CMD (dev);
dibp->ctl = CTL (dev);
dibp->flg = FLG (dev);
dibp->fbf = FBF (dev); } }
dibp->fbf = FBF (dev);
dibp->srq = SRQ (dev); } }
pcq_r->qptr = pcq_p; /* update pc q ptr */
return reason;
}
@@ -1865,7 +1927,10 @@ iodata = devdisp (dev, sop, ir, ABREG[ab]); /* process I/O */
ion_defer = defer_tab[sop]; /* set defer */
if ((sop == ioMIX) || (sop == ioLIX)) /* store ret data */
ABREG[ab] = iodata & DMASK;
if (sop == ioHLT) return STOP_HALT; /* halt? */
if (sop == ioHLT) { /* halt? */
int32 len = strlen (halt_msg); /* find end msg */
sprintf (&halt_msg[len - 6], "%06o", ir); /* add the halt */
return STOP_HALT; }
return (iodata >> IOT_V_REASON); /* return status */
}
@@ -1883,9 +1948,9 @@ uint32 calc_dma (void)
{
uint32 r = 0;
if (CMD (DMA0) && FLG (dmac[0].cw1 & I_DEVMASK)) /* check DMA0 cycle */
if (CMD (DMA0) && SRQ (dmac[0].cw1 & I_DEVMASK)) /* check DMA0 cycle */
r = r | DMAR0;
if (CMD (DMA1) && FLG (dmac[1].cw1 & I_DEVMASK)) /* check DMA1 cycle */
if (CMD (DMA1) && SRQ (dmac[1].cw1 & I_DEVMASK)) /* check DMA1 cycle */
r = r | DMAR1;
return r;
}
@@ -1994,7 +2059,14 @@ else pa = va;
return M[pa];
}
/* Memory protection test for writes */
/* Memory protection test for writes
From Dave Bryan: The problem is that memory writes aren't being checked for
an MP violation if DMS is enabled, i.e., if DMS is enabled, and the page is
writable, then whether the target is below the MP fence is not checked. [The
simulator must] do MP check on all writes after DMS translation and violation
checks are done (so, to pass, the page must be writable AND the target must
be above the MP fence). */
#define MP_TEST(x) (CTL (PRO) && ((x) > 1) && ((x) < mp_fence))
@@ -2003,8 +2075,8 @@ void WriteB (uint32 va, uint32 dat)
uint32 pa;
if (dms_enb) pa = dms (va >> 1, dms_ump, WR);
else { if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
pa = va >> 1; }
else pa = va >> 1;
if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) {
if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377);
else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); }
@@ -2018,8 +2090,8 @@ uint32 pa;
if (dms_enb) {
dms_viol (va >> 1, MVI_WPR); /* viol if prot */
pa = dms (va >> 1, dms_ump ^ MAP_LNT, WR); }
else { if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
pa = va >> 1; }
else pa = va >> 1;
if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) {
if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377);
else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); }
@@ -2031,8 +2103,8 @@ void WriteW (uint32 va, uint32 dat)
uint32 pa;
if (dms_enb) pa = dms (va, dms_ump, WR);
else { if (MP_TEST (va)) ABORT (ABORT_PRO);
pa = va; }
else pa = va;
if (MP_TEST (va)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) M[pa] = dat;
return;
}
@@ -2044,8 +2116,8 @@ int32 pa;
if (dms_enb) {
dms_viol (va, MVI_WPR); /* viol if prot */
pa = dms (va, dms_ump ^ MAP_LNT, WR); }
else { if (MP_TEST (va)) ABORT (ABORT_PRO);
pa = va; }
else pa = va;
if (MP_TEST (va)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) M[pa] = dat;
return;
}
@@ -2076,8 +2148,8 @@ if (pgn == 0) { /* base page? */
if (prot == WR) dms_viol (va, MVI_BPG); /* if W, viol */
return va; } } /* no mapping */
mpr = dms_map[map + pgn]; /* get map reg */
if (mpr & prot) dms_viol (va, prot << (MVI_V_WPR - MAPA_V_WPR));
return (PA_GETPAG (mpr) | VA_GETOFF (va));
if (mpr & prot) dms_viol (va, prot); /* prot violation? */
return (MAP_GETPAG (mpr) | VA_GETOFF (va));
}
/* DMS relocation for IO access */
@@ -2095,19 +2167,24 @@ if (pgn == 0) { /* base page? */
(va < dms_fence)) { /* 0B10: < fence */
return va; } } /* no mapping */
mpr = dms_map[map + pgn]; /* get map reg */
return (PA_GETPAG (mpr) | VA_GETOFF (va));
return (MAP_GETPAG (mpr) | VA_GETOFF (va));
}
/* DMS relocation for console access */
uint32 dms_cons (uint32 va, int32 sw)
{
if (sw & SWMASK ("V")) return dms_io (va, dms_ump);
if (sw & SWMASK ("S")) return dms_io (va, SMAP);
if (sw & SWMASK ("U")) return dms_io (va, UMAP);
if (sw & SWMASK ("P")) return dms_io (va, PAMAP);
if (sw & SWMASK ("Q")) return dms_io (va, PBMAP);
return va;
uint32 map_sel;
if (sw & SWMASK ('V')) map_sel = dms_ump; /* switch? select map */
else if (sw & SWMASK ('S')) map_sel = SMAP;
else if (sw & SWMASK ('U')) map_sel = UMAP;
else if (sw & SWMASK ('P')) map_sel = PAMAP;
else if (sw & SWMASK ('Q')) map_sel = PBMAP;
else return va; /* no switch, physical */
if (va >= VASIZE) return MEMSIZE; /* virtual, must be 15b */
else if (dms_enb) return dms_io (va, map_sel); /* DMS on? go thru map */
else return va; /* else return virtual */
}
/* Mem protect and DMS validation for jumps */
@@ -2131,19 +2208,14 @@ return;
uint16 dms_rmap (uint32 mapi)
{
int32 t;
mapi = mapi & MAP_MASK;
t = (((dms_map[mapi] >> VA_N_OFF) & PA_M_PAG) |
((dms_map[mapi] & (RD | WR)) << (MAPM_V_WPR - MAPA_V_WPR)));
return (uint16) t;
return (dms_map[mapi] & ~MAP_MBZ);
}
void dms_wmap (uint32 mapi, uint32 dat)
{
mapi = mapi & MAP_MASK;
dms_map[mapi] = ((dat & PA_M_PAG) << VA_N_OFF) |
((dat >> (MAPM_V_WPR - MAPA_V_WPR)) & (RD | WR));
dms_map[mapi] = (uint16) (dat & ~MAP_MBZ);
return;
}
@@ -2172,7 +2244,24 @@ if (CTL (PRO)) dms_sr = dms_sr | MST_PRO;
return dms_sr;
}
/* Device 0 (CPU) I/O routine */
/* Device 0 (CPU) I/O routine
From Dave Bryan: RTE uses the undocumented instruction "SFS 0,C" to both test
and turn off the interrupt system. This is confirmed in the "RTE-6/VM
Technical Specifications" manual (HP 92084-90015), section 2.3.1 "Process
the Interrupt", subsection "A.1 $CIC":
"Test to see if the interrupt system is on or off. This is done with the
SFS 0,C instruction. In either case, turn it off (the ,C does it)."
...and in section 5.8, "Parity Error Detection":
"Because parity error interrupts can occur even when the interrupt system
is off, the code at $CIC must be able to save the complete system status.
The major hole in being able to save the complete state is in saving the
interrupt system state. In order to do this in both the 21MX and the 21XE
the instruction 103300 was used to both test the interrupt system and
turn it off." */
int32 cpuio (int32 inst, int32 IR, int32 dat)
{
@@ -2184,10 +2273,10 @@ case ioFLG: /* flag */
return dat;
case ioSFC: /* skip flag clear */
if (!ion) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (ion) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioLIX: /* load */
dat = 0; /* returns 0 */
break;
@@ -2249,7 +2338,11 @@ default:
return dat;
}
/* Device 5 (memory protect) I/O routine */
/* Device 5 (memory protect) I/O routine
From Dave Bryan: Examination of the schematics for the MP card in the
engineering documentation shows that the SFS and SFC I/O backplane signals
gate the output of the MEVFF onto the SKF line unconditionally. */
int32 proio (int32 inst, int32 IR, int32 dat)
{
@@ -2257,13 +2350,11 @@ if ((cpu_unit.flags & UNIT_MPR) == 0) /* not installed? */
return nulio (inst, IR, dat); /* non-existent dev */
switch (inst) { /* case on opcode */
case ioSFC: /* skip flag clear */
if (FLG (PRO) && !mp_mevff) /* skip if mem prot */
PC = (PC + 1) & VAMASK;
return dat;
if (!mp_mevff) PC = (PC + 1) & VAMASK; /* skip if mem prot */
break;
case ioSFS: /* skip flag set */
if (FLG (PRO) && mp_mevff) /* skip if DMS */
PC = (PC + 1) & VAMASK;
return dat;
if (mp_mevff) PC = (PC + 1) & VAMASK; /* skip if DMS */
break;
case ioMIX: /* merge */
dat = dat | mp_viol;
break;
@@ -2329,10 +2420,10 @@ case ioFLG: /* flag */
break;
case ioSFC: /* skip flag clear */
if (FLG (DMA0 + ch) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (DMA0 + ch) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioMIX: case ioLIX: /* load, merge */
dat = DMASK;
break;
@@ -2358,9 +2449,10 @@ return dat;
- CLC requested: issue CLC
Output cases:
- neither STC nor CLC requested: issue CLF
- CLC requested but not STC: issue CLC,C
- STC requested but not CLC: issue STC,C
- STC and CLC both requested: issue STC,C and CLC,C
- CLC requested but not STC: issue CLC,C
- STC and CLC both requested: issue STC,C and CLC,C, in that order
Either: issue EDT
*/
void dma_cycle (uint32 ch, uint32 map)
@@ -2380,20 +2472,24 @@ dmac[ch].cw3 = (dmac[ch].cw3 + 1) & DMASK; /* incr wcount */
if (dmac[ch].cw3) { /* more to do? */
if (dmac[ch].cw1 & DMA1_STC) /* if STC flag, */
devdisp (dev, ioCTL, I_HC + dev, 0); /* do STC,C dev */
else devdisp (dev, ioFLG, I_HC + dev, 0); } /* else CLF dev */
else devdisp (dev, ioFLG, I_HC + dev, 0); /* else CLF dev */
}
else { if (inp) { /* last cycle, input? */
if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */
devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */
} /* end input */
else { /* output */
devdisp (dev, ioFLG, I_HC + dev, 0); /* clear flag */
if ((dmac[ch].cw1 & (DMA1_STC | DMA1_CLC)) == 0)
devdisp (dev, ioFLG, I_HC + dev, 0); /* clear flag */
if (dmac[ch].cw1 & DMA1_STC) /* if STC flag, */
devdisp (dev, ioCTL, dev, 0); /* do STC dev */
devdisp (dev, ioCTL, I_HC + dev, 0); /* do STC,C dev */
if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */
devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */
devdisp (dev, ioCTL, I_HC + I_CTL + dev, 0); /* yes */
} /* end output */
setFLG (DMA0 + ch); /* set DMA flg */
clrCMD (DMA0 + ch); } /* clr DMA cmd */
clrCMD (DMA0 + ch); /* clr DMA cmd */
devdisp (dev, ioEDT, dev, 0); /* do EDT */
}
return;
}
@@ -2428,6 +2524,7 @@ clrCMD (PRO);
clrCTL (PRO);
clrFLG (PRO);
clrFBF (PRO);
dev_srq[0] = dev_srq[0] & ~M_FXDEV;
mp_fence = 0; /* init mprot */
mp_viol = 0;
mp_mevff = 0;
@@ -2436,7 +2533,8 @@ dms_enb = dms_ump = 0; /* init DMS */
dms_sr = 0;
dms_vr = 0;
pcq_r = find_reg ("PCQ", NULL, dptr);
sim_brk_types = sim_brk_dflt = SWMASK ('E');
sim_brk_types = ALL_BKPTS;
sim_brk_dflt = SWMASK ('E');
if (M == NULL) M = calloc (PASIZE, sizeof (unsigned int16));
if (M == NULL) return SCPE_MEM;
if (pcq_r) pcq_r->qptr = 0;
@@ -2449,6 +2547,7 @@ t_stat dma0_reset (DEVICE *tptr)
clrCMD (DMA0);
clrCTL (DMA0);
setFLG (DMA0);
clrSRQ (DMA0);
dmac[0].cw1 = dmac[0].cw2 = dmac[0].cw3 = 0;
return SCPE_OK;
}
@@ -2458,6 +2557,7 @@ t_stat dma1_reset (DEVICE *tptr)
clrCMD (DMA1);
clrCTL (DMA1);
setFLG (DMA1);
clrSRQ (DMA1);
dmac[1].cw1 = dmac[1].cw2 = dmac[1].cw3 = 0;
return SCPE_OK;
}
@@ -2468,8 +2568,8 @@ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
{
int32 d;
if (addr >= MEMSIZE) return SCPE_NXM;
addr = dms_cons (addr, sw);
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr == 0) d = saved_AR;
else if (addr == 1) d = saved_BR;
else d = M[addr];
@@ -2481,8 +2581,8 @@ return SCPE_OK;
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw)
{
if (addr >= MEMSIZE) return SCPE_NXM;
addr = dms_cons (addr, sw);
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr == 0) saved_AR = val & DMASK;
else if (addr == 1) saved_BR = val & DMASK;
else M[addr] = val & DMASK;
@@ -2558,7 +2658,7 @@ t_bool dev_conflict (void)
{
DEVICE *dptr, *cdptr;
DIB *dibp, *chkp;
int32 i, j, dno;
uint32 i, j, dno;
for (i = 0; cdptr = sim_devices[i]; i++) {
chkp = (DIB *) cdptr->ctxt;
@@ -2599,4 +2699,59 @@ for (i = 0; opt_val[i].optf != 0; i++) {
return SCPE_OK; } }
return SCPE_NOFNC;
}
/* IBL routine (CPU boot) */
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
extern const uint16 ptr_rom[IBL_LNT], dq_rom[IBL_LNT], ms_rom[IBL_LNT];
int32 dev = (SR >> IBL_V_DEV) & I_DEVMASK;
int32 sel = (SR >> IBL_V_SEL) & IBL_M_SEL;
if (dev < 010) return SCPE_NOFNC;
switch (sel) {
case 0: /* PTR boot */
ibl_copy (ptr_rom, dev);
break;
case 1: /* DP/DQ boot */
ibl_copy (dq_rom, dev);
break;
case 2: /* MS boot */
ibl_copy (ms_rom, dev);
break;
default:
return SCPE_NOFNC; }
return SCPE_OK;
}
/* IBL boot ROM copy
- Use memory size to set the initial PC and base of the boot area
- Copy boot ROM to memory, updating I/O instructions
- Place 2's complement of boot base in last location
Notes:
- SR settings are done by the caller
- Boot ROM's must be assembled with a device code of 10 (10 and 11 for
devices requiring two codes)
*/
t_stat ibl_copy (const uint16 pboot[IBL_LNT], int32 dev)
{
int32 i;
uint16 wd;
if (dev < 010) return SCPE_ARG; /* valid device? */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */
wd = pboot[i]; /* get word */
if (((wd & I_NMRMASK) == I_IO) && /* IO instruction? */
((wd & I_DEVMASK) >= 010) && /* dev >= 10? */
(I_GETIOOP (wd) != ioHLT)) /* not a HALT? */
M[PC + i] = (wd + (dev - 010)) & DMASK; /* change dev code */
else M[PC + i] = wd; } /* leave unchanged */
M[PC + IBL_DPC] = (M[PC + IBL_DPC] + (dev - 010)) & DMASK; /* patch DMA ctrl */
M[PC + IBL_END] = (~PC + 1) & DMASK; /* fill in start of boot */
return SCPE_OK;
}

View File

@@ -23,6 +23,8 @@
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-Apr-04 RMS Added additional IBL definitions
Added DMA EDT I/O pseudo-opcode
25-Apr-03 RMS Revised for extended file support
24-Oct-02 RMS Added indirect address interrupt
08-Feb-02 RMS Added DMS definitions
@@ -81,7 +83,7 @@
/* Other instructions */
#define I_NMRMASK 0102000 /* non-mrf opcode */
#define I_NMRMASK 0172000 /* non-mrf opcode */
#define I_SRG 0000000 /* shift */
#define I_ASKP 0002000 /* alter/skip */
#define I_EXTD 0100000 /* extend */
@@ -98,9 +100,9 @@
#define DMA2_OI 0100000 /* DMA - output/input */
struct DMA { /* DMA channel */
int32 cw1; /* device select */
int32 cw2; /* direction, address */
int32 cw3; /* word count */
uint32 cw1; /* device select */
uint32 cw2; /* direction, address */
uint32 cw3; /* word count */
};
/* Memory management */
@@ -123,18 +125,17 @@ struct DMA { /* DMA channel */
#define PAMAP (UMAP + MAP_LNT) /* port A map */
#define PBMAP (PAMAP + MAP_LNT) /* port B map */
/* Map entries are left shifted by VA_N_OFF, flags in lower 2b */
/* DMS map entries */
#define PA_N_PAG (PA_N_SIZE - VA_N_OFF) /* page width */
#define PA_V_PAG (VA_N_OFF)
#define PA_M_PAG ((1 << PA_N_PAG) - 1)
#define MAPM_V_RPR 15 /* in mem: read prot */
#define MAPM_V_WPR 14 /* write prot */
#define MAPA_V_RPR 1 /* in array: */
#define MAPA_V_WPR 0
#define PA_GETPAG(x) ((x) & (PA_M_PAG << VA_V_PAG))
#define RD (1 << MAPA_V_RPR)
#define WR (1 << MAPA_V_WPR)
#define MAP_V_RPR 15 /* read prot */
#define MAP_V_WPR 14 /* write prot */
#define RD (1 << MAP_V_RPR)
#define WR (1 << MAP_V_WPR)
#define MAP_MBZ 0036000 /* must be zero */
#define MAP_N_PAG (PA_N_SIZE - VA_N_OFF) /* page width */
#define MAP_V_PAG (VA_N_OFF)
#define MAP_M_PAG ((1 << MAP_N_PAG) - 1)
#define MAP_GETPAG(x) (((x) & MAP_M_PAG) << MAP_V_PAG)
/* Map status register */
@@ -148,8 +149,8 @@ struct DMA { /* DMA channel */
/* Map violation register */
#define MVI_V_RPR 15
#define MVI_V_WPR 14
#define MVI_V_RPR 15 /* must be same as */
#define MVI_V_WPR 14 /* MAP_V_xPR */
#define MVI_RPR (1 << MVI_V_RPR) /* rd viol */
#define MVI_WPR (1 << MVI_V_WPR) /* wr viol */
#define MVI_BPG 0020000 /* base page viol */
@@ -174,6 +175,7 @@ struct DMA { /* DMA channel */
#define ioLIX 5 /* load into A/B */
#define ioOTX 6 /* output from A/B */
#define ioCTL 7 /* set/clear control */
#define ioEDT 8 /* DMA: end data transfer */
/* I/O devices - fixed assignments */
@@ -211,31 +213,39 @@ struct DMA { /* DMA channel */
#define MSC 031 /* 13181A control */
#define IPLI 032 /* 12556B link in */
#define IPLO 033 /* 12556B link out */
#define DS 034 /* 13037 control */
#define MUXL 040 /* 12920A lower data */
#define MUXU 041 /* 12920A upper data */
#define MUXC 042 /* 12920A control */
/* IBL assignments */
#define IBL_V_SEL 14 /* ROM select */
#define IBL_M_SEL 03
#define IBL_PTR 0000000 /* PTR */
#define IBL_DP 0040000 /* DP */
#define IBL_DQ 0060000 /* DQ */
#define IBL_MS 0100000 /* MS */
#define IBL_TBD 0140000 /* tbd */
#define IBL_DP 0040000 /* disk: DP */
#define IBL_DQ 0060000 /* disk: DQ */
#define IBL_MS 0100000 /* option 0: MS */
#define IBL_DS 0140000 /* option 1: DS */
#define IBL_MAN 0010000 /* RPL/man boot */
#define IBL_V_DEV 6 /* dev in <11:6> */
#define IBL_FIX 0000001 /* DP fixed */
#define IBL_OPT 0000070 /* options in <5:3> */
#define IBL_DP_REM 0000001 /* DP removable */
#define IBL_LNT 64 /* boot length */
#define IBL_MASK (IBL_LNT - 1) /* boot length mask */
#define IBL_DPC (IBL_LNT - 2) /* DMA ctrl word */
#define IBL_END (IBL_LNT - 1) /* last location */
/* Dynamic device information table */
struct hp_dib {
int32 devno; /* device number */
int32 cmd; /* saved command */
int32 ctl; /* saved control */
int32 flg; /* saved flag */
int32 fbf; /* saved flag buf */
int32 (*iot)(); /* I/O routine */
uint32 devno; /* device number */
uint32 cmd; /* saved command */
uint32 ctl; /* saved control */
uint32 flg; /* saved flag */
uint32 fbf; /* saved flag buf */
uint32 srq; /* saved svc req */
int32 (*iot)(int32 op, int32 ir, int32 dat); /* I/O routine */
};
typedef struct hp_dib DIB;
@@ -254,16 +264,24 @@ typedef struct hp_dib DIB;
setFBF(D)
#define clrFLG(D) dev_flg[(D)/32] = dev_flg[(D)/32] & ~INT_M (D); \
clrFBF(D)
#define setFSR(D) dev_flg[(D)/32] = dev_flg[(D)/32] | INT_M (D); \
setFBF(D); setSRQ(D)
#define clrFSR(D) dev_flg[(D)/32] = dev_flg[(D)/32] & ~INT_M (D); \
clrFBF(D); clrSRQ(D)
#define setSRQ(D) dev_srq[(D)/32] = dev_srq[(D)/32] | INT_M ((D))
#define clrSRQ(D) dev_srq[(D)/32] = dev_srq[(D)/32] & ~INT_M (D)
#define CMD(D) ((dev_cmd[(D)/32] >> INT_V (D)) & 1)
#define CTL(D) ((dev_ctl[(D)/32] >> INT_V (D)) & 1)
#define FLG(D) ((dev_flg[(D)/32] >> INT_V (D)) & 1)
#define FBF(D) ((dev_fbf[(D)/32] >> INT_V (D)) & 1)
#define SRQ(D) ((dev_srq[(D)/32] >> INT_V (D)) & 1)
#define IOT_V_REASON 16
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
/* Function prototypes */
t_stat ibl_copy (const uint16 pboot[IBL_LNT], int32 dev);
t_stat hp_setdev (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat hp_showdev (FILE *st, UNIT *uptr, int32 val, void *desc);
void hp_enbdis_pair (DEVICE *ccp, DEVICE *dcp);

View File

@@ -169,3 +169,12 @@ Peripherals
- test 19 uses non-supported read rev
13183 7970E magtape not run in 21MX CE no
12920 multiplexor not run in 21MX CE no
Bug List (post-release)
1. SFS x,C and SFC x,C work for all devices, not just device 1.
2. DMS protection does not disable conventional memory protection.
3. Memory protect violation clears automatically when the interrupt is acknowledged.
4. SFS/SFC 5 is not gated by protection enabled.
3. SBT increments B after the byte store.

View File

@@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: HP2100 Simulator Usage
Date: 15-Feb-2004
Date: 30-Jun-2004
COPYRIGHT NOTICE
@@ -80,7 +80,7 @@ CPU 2116 CPU with 32KW memory
21MX CPU with 1024KW memory, FP or DMS instructions
DMA0, DMA1 dual channel DMA controller
PTR,PTP 12597A paper tape reader/punch
TTY 12631C buffered terminal controller
TTY 12531C buffered terminal controller
LPS 12653A printer controller with 2767 printer
12566B microcircuit interface for diagnostics
LPT 12845A printer controller with 2607 printer
@@ -99,7 +99,7 @@ IPLO 12556B interprocessor link, output side
The HP2100 simulator implements several unique stop conditions:
- decode of an undefined instruction, and STOP_INST is et
- decode of an undefined instruction, and STOP_INST is set
- reference to an undefined I/O device, and STOP_DEV is set
- more than INDMAX indirect references are detected during
memory reference address decoding
@@ -149,6 +149,13 @@ These switches are recognized when examining or depositing in CPU memory:
-p if DMS enabled, force port A map
-q if DMS enabled, force port B map
The CPU implements four different kinds of instruction breakpoints:
-e break unconditionally
-n break if DMS is disabled
-s break if DMS enabled and system map
-u break if DMS enabled and user map
CPU registers include the visible state of the processor as well as the
control registers for the interrupt system.
@@ -157,18 +164,20 @@ control registers for the interrupt system.
P all 15 program counter
A all 16 A register
B all 16 B register
M all 15 M (memory address) register
T all 16 T (memory data) register
X 21MX 16 X index register
Y 21MX 16 Y index register
S all 16 switch/display register
F 2100,21MX 15 memory protection fence
E all 1 extend flag
O all 1 overflow flag
ION all 1 interrupt enable flag
ION_DEFER all 1 interrupt defer flag
IADDR all 6 most recent interrupting device
CIR all 6 current interrupt register
MPCTL 2100,21MX 1 memory protection enable
MPFLG 2100,21MX 1 memory protection flag
MPFBF 2100,21MX 1 memory protection flag buffer
MPFR 2100,21MX 15 memory protection fence
MPVR 2100,21MX 16 memory protection violation reg
MPEVR 2100,21MX 1 memory protection freeze flag
MPMEV 2100,21MX 1 memory protection DMS error flag
@@ -176,7 +185,7 @@ control registers for the interrupt system.
DMSCUR 21MX 1 DMS current mode
DMSSR 21MX 16 DMS status register
DMSVR 21MX 16 DMS violation register
DMSMAP[4][32] 21MX 20 DMS maps
DMSMAP[4][16] 21MX 16 DMS maps
STOP_INST all 1 stop on undefined instruction
STOP_DEV all 1 stop on undefined device
INDMAX all 16 indirect address limit
@@ -184,6 +193,24 @@ control registers for the interrupt system.
most recent P change first
WRU all 8 interrupt character
BOOT CPU implements the 21MX IBL facility. IBL is controlled by the switch
register S. S<15:14> selects the device to boot:
00 paper-tape reader (12992K ROM)
01 7900A/2883 disk (12992A ROM)
10 7970B/E tape (12992D ROM)
11 undefined
For the 7900A/2883 only, S<13:12> specify the type of disk:
00 7900A
10 2883
S<11:6> contains the device address. If the device has two addresses, S<11:6>
specifies the lower address. S<5:3> are passed to the bootstrap program.
S<2:0> specify options for the boot loader. IBL will not report an error if
the device address in S<11:6> is incorrect.
2.2 DMA Controllers
The HP2100 includes two DMA channel controllers (DMA0 and DMA1). Each
@@ -243,7 +270,13 @@ register specifies the number of the next data item to be read.
Thus, by changing POS, the user can backspace or advance the reader.
The paper tape reader supports the BOOT command. BOOT PTR copies the
absolute binary loader into memory and starts it running.
IBL into memory and starts it running. The switch register (S) is
set automatically to the value expected by the IBL loader:
<15:12> = 0000
<11:6> = device code
<5:3> = unchanged
<2:0> = 000
The paper tape reader implements these registers:
@@ -254,6 +287,9 @@ The paper tape reader implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
TRLLIM 8 number of trailing nulls to append
after end-of-file is detected
POS 32 position in the input file
TIME 24 time from I/O initiation to interrupt
STOP_IOE 1 stop on I/O error
@@ -285,6 +321,7 @@ The paper tape punch implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
POS 32 position in the output file
TIME 24 time from I/O initiation to interrupt
STOP_IOE 1 stop on I/O error
@@ -298,7 +335,7 @@ Error handling is as follows:
OS I/O error x report error and stop
2.4.3 12631C Buffered Terminal (TTY)
2.4.3 12531C Buffered Terminal (TTY)
The console terminal has three units: keyboard (unit 0), printer
(unit 1), and punch (unit 2). The keyboard reads from the console
@@ -307,8 +344,20 @@ punch writes to a disk file. The keyboard and printer units (TTY0,
TTY1) can be set to one of three modes: UC, 7B, or 8B. In UC mode,
lower case input and output characters are automatically converted to
upper case. In 7B mode, input and output characters are masked to 7
bits. In 8B mode, characters are not modified. Changing the mode
of either unit changes both. The default mode is UC.
bits. In 8B mode, characters are not modified. In UC and 7B mode,
output of null characters is suppressed; in 8B mode, output of null
characters is permitted. Changing the mode of either the keyboard
or the printer changes both. The default mode is UC.
Some HP software systems expect the console terminal to transmit
line-feed automatically following carriage-return. This feature is
enabled with:
SET TTY AUTOLF
and disabled with:
SET TTY NOAUTOLF
The console teleprinter implements these registers:
@@ -319,6 +368,7 @@ The console teleprinter implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
KPOS 32 number of characters input
KTIME 24 keyboard polling interval
TPOS 32 number of characters printed
@@ -363,6 +413,7 @@ The 12653A implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
POS 32 position in the output file
CTIME 24 time between characters
PTIME 24 time for a print operation
@@ -395,6 +446,7 @@ The line printer implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
LCNT 7 line count within page
POS 32 position in the output file
CTIME 24 time between characters
@@ -497,6 +549,7 @@ The lines (MUXL) implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
STA[0:20] 16 line status, lines 0-20
RPAR[0:20] 16 receive parameters, lines 0-20
XPAR[0:15] 16 transmit parameters, lines 0-15
@@ -513,6 +566,7 @@ The modem control (MUXM) implements these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
SCAN 1 scan enabled
CHAN 4 current line
DSO[0:15] 6 C2,C1,ES2,ES1,SS2,SS1, lines 0-15
@@ -574,6 +628,7 @@ Both IPLI and IPLO implement these registers:
CTL 1 device/interrupt enable
FLG 1 device ready
FBF 1 device ready buffer
SRQ 1 device DMA service request
TIME 24 polling interval for input
STOP_IOE 1 stop on I/O error
@@ -596,16 +651,17 @@ a device controller. The data channel includes a 128-word (one sector)
buffer for reads and writes. The device controller includes the four
disk drives. Disk drives can be set ONLINE or OFFLINE.
The 12557A/13210A supports the BOOT command. BOOT DP loads the IBL
for 7900 class disks into memory and starts it running. BOOT -F DP
boots from the fixed platter (head 2). The switch register (S) is
The 12557A/13210A supports the BOOT command. BOOT DPC copies the IBL
for 7900 class disks into memory and starts it running. BOOT -R DP
boots from the removable platter (head 2). The switch register (S) is
set automatically to the value expected by the IBL loader:
<15:14> = 01
<13:12> = 00
<11:6> = data channel device code
<5:1> = 00000
<0> = 1 if booting from the fixed platter
<5:3> = unchanged
<2:1> = 00
<0> = 1 if booting from the removable platter
The data channel implements these registers:
@@ -619,6 +675,7 @@ The data channel implements these registers:
CTL 1 interrupt enable
FLG 1 channel ready
FBF 1 channel ready buffer
SRQ 1 channel DMA service request
XFER 1 transfer in progress flag
WVAL 1 write data valid flag
@@ -633,6 +690,7 @@ The device controller implements these registers:
CTL 1 interrupt enable
FLG 1 controller ready
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
EOC 1 end of cylinder pending
RARC[0:3] 8 record address register cylinder, drives 0-3
RARH[0:3] 2 record address register head, drives 0-3
@@ -660,14 +718,14 @@ a device controller. The data channel includes a 128-word (one sector)
buffer for reads and writes. The device controller includes the two
disk drives. Disk drives can be set ONLINE or OFFLINE.
The 12565A supports the BOOT command. BOOT DQ loads the IBL for 2883
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:
<15:14> = 01
<13:12> = 10
<15:12> = 0110
<11:6> = data channel device code
<5:0> = 00000
<5:3> = unchanged
<2:0> = 000
The data channel implements these registers:
@@ -681,6 +739,7 @@ The data channel implements these registers:
CTL 1 interrupt enable
FLG 1 channel ready
FBF 1 channel ready buffer
SRQ 1 channel DMA service request
XFER 1 transfer in progress flag
WVAL 1 write data valid flag
@@ -695,6 +754,7 @@ The device controller implements these registers:
CTL 1 interrupt enable
FLG 1 controller ready
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
RARC[0:1] 8 record address register cylinder, drives 0-1
RARH[0:1] 5 record address register head, drives 0-1
RARS[0:1] 5 record address register sector, drives 0-1
@@ -747,6 +807,7 @@ The data channel implements these registers:
CTL 1 interrupt enable
FLG 1 channel ready
FBF 1 channel ready buffer
SRQ 1 channel DMA service request
BPTR 6 sector buffer pointer
The device controller implements these registers:
@@ -759,6 +820,7 @@ The device controller implements these registers:
CTL 1 interrupt enable
FLG 1 controller ready
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
TIME 24 interword transfer time
STOP_IOE 1 stop on I/O error
@@ -793,6 +855,7 @@ The data channel implements these registers:
name size comments
FLG 1 channel ready
SRQ 1 channel DMA service request
DBUF[0:65535] 8 transfer buffer
BPTR 16 buffer pointer (reads and writes)
BMAX 16 buffer size (writes)
@@ -807,6 +870,7 @@ The device controller implements these registers:
CTL 1 interrupt enabled
FLG 1 controller ready
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
DTF 1 data transfer flop
FSVC 1 first service flop
POS 32 magtape position
@@ -847,10 +911,10 @@ MS causes the loader to space forward the number of files specified in
the A register before starting to load data. The switch register (S) is
set automatically to the value expected by the IBL loader:
<15:14> = 10
<13:12> = 00
<15:12> = 1000
<11:6> = data channel device code
<5:1> = 00000
<5:3> = unchanged
<2:0> = 00
<0> = 1 if space forward before loading
The data channel implements these registers:
@@ -861,6 +925,7 @@ The data channel implements these registers:
CTL 1 interrupt enabled
FLG 1 channel ready
FBF 1 channel ready buffer
SRQ 1 channel DMA service request
DBUF[0:65535] 8 transfer buffer
BPTR 17 buffer pointer (reads and writes)
BMAX 17 buffer size (writes)
@@ -876,6 +941,7 @@ The device controller implements these registers:
CTL 1 interrupt enabled
FLG 1 controller ready
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
POS[0:3] 32 magtape position
CTIME 24 command delay time
XTIME 24 interword transfer delay time

View File

@@ -26,6 +26,12 @@
dp 12557A 2871 disk subsystem
13210A 7900 disk subsystem
21-Apr-04 RMS Fixed typo in boot loader (found by Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Fixed SR setting in IBL
Fixed interpretation of SR<0>
Revised IBL loader
Implemented DMA SRQ (follows FLG)
25-Apr-03 RMS Revised for extended file support
Fixed bug(s) in boot (found by Terry Newton)
10-Nov-02 RMS Added BOOT command, fixed numerous bugs
@@ -122,7 +128,7 @@
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;
extern UNIT cpu_unit;
@@ -167,8 +173,8 @@ t_stat dp_showtype (FILE *st, UNIT *uptr, int32 val, void *desc);
*/
DIB dp_dib[] = {
{ DPD, 0, 0, 0, 0, &dpdio },
{ DPC, 0, 0, 0, 0, &dpcio } };
{ DPD, 0, 0, 0, 0, 0, &dpdio },
{ DPC, 0, 0, 0, 0, 0, &dpcio } };
#define dpd_dib dp_dib[0]
#define dpc_dib dp_dib[1]
@@ -182,6 +188,7 @@ REG dpd_reg[] = {
{ FLDATA (CTL, dpd_dib.ctl, 0) },
{ FLDATA (FLG, dpd_dib.flg, 0) },
{ FLDATA (FBF, dpd_dib.fbf, 0) },
{ FLDATA (SRQ, dpd_dib.srq, 0) },
{ FLDATA (XFER, dpd_xfer, 0) },
{ FLDATA (WVAL, dpd_wval, 0) },
{ BRDATA (DBUF, dpxb, 8, 16, DP_NUMWD) },
@@ -227,6 +234,7 @@ REG dpc_reg[] = {
{ FLDATA (CTL, dpc_dib.ctl, 0) },
{ FLDATA (FLG, dpc_dib.flg, 0) },
{ FLDATA (FBF, dpc_dib.fbf, 0) },
{ FLDATA (SRQ, dpc_dib.srq, 0) },
{ FLDATA (EOC, dpc_eoc, 0) },
{ BRDATA (RARC, dpc_rarc, 8, 8, DP_NUMDRV) },
{ BRDATA (RARH, dpc_rarh, 8, 2, DP_NUMDRV) },
@@ -275,14 +283,14 @@ int32 devd;
devd = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devd); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devd); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devd) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devd) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
dpd_obuf = dat;
if (!dpc_busy || dpd_xfer) dpd_wval = 1; /* if !overrun, valid */
@@ -306,7 +314,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devd); } /* H/C option */
if (IR & I_HC) { clrFSR (devd); } /* H/C option */
return dat;
}
@@ -318,14 +326,14 @@ int32 devd = dpd_dib.devno;
devc = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devc); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devc); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devc) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devc) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
dpc_obuf = dat;
break;
@@ -351,7 +359,7 @@ case ioCTL: /* control clear/set */
fnc = CW_GETFNC (dpc_obuf); /* from cmd word */
switch (fnc) { /* case on fnc */
case FNC_STA: /* rd sta */
if (dp_ctype) { clrFLG (devd); } /* 13210? clr dch flag */
if (dp_ctype) { clrFSR (devd); } /* 13210? clr dch flag */
case FNC_SEEK: case FNC_CHK: /* seek, check */
case FNC_AR: /* addr rec */
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
@@ -365,7 +373,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devc); } /* H/C option */
if (IR & I_HC) { clrFSR (devc); } /* H/C option */
return dat;
}
@@ -428,7 +436,7 @@ case FNC_SEEK: /* seek, need cyl */
if (CMD (devd)) { /* dch active? */
dpc_rarc[drv] = DA_GETCYL (dpd_obuf); /* take cyl word */
dpd_wval = 0; /* clr data valid */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
uptr->FNC = FNC_SEEK1; } /* advance state */
sim_activate (uptr, dpc_xtime); /* no, wait more */
@@ -438,7 +446,7 @@ case FNC_SEEK1: /* seek, need hd/sec */
dpc_rarh[drv] = DA_GETHD (dpd_obuf); /* get head */
dpc_rars[drv] = DA_GETSC (dpd_obuf); /* get sector */
dpd_wval = 0; /* clr data valid */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
if (sim_is_active (&dpc_unit[drv])) { /* if busy, */
dpc_sta[drv] = dpc_sta[drv] | STA_SKE;
@@ -457,7 +465,7 @@ case FNC_AR: /* arec, need cyl */
if (CMD (devd)) { /* dch active? */
dpc_rarc[drv] = DA_GETCYL (dpd_obuf); /* take cyl word */
dpd_wval = 0; /* clr data valid */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
uptr->FNC = FNC_AR1; } /* advance state */
sim_activate (uptr, dpc_xtime); /* no, wait more */
@@ -467,9 +475,9 @@ case FNC_AR1: /* arec, need hd/sec */
dpc_rarh[drv] = DA_GETHD (dpd_obuf); /* get head */
dpc_rars[drv] = DA_GETSC (dpd_obuf); /* get sector */
dpd_wval = 0; /* clr data valid */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); } /* clr dch cmd */
else sim_activate (uptr, dpc_xtime); /* no, wait more */
break;
@@ -484,7 +492,7 @@ case FNC_STA: /* read status */
else dpd_ibuf = STA_NRDY; /* not ready */
if (dpd_ibuf & STA_ALLERR) /* errors? set flg */
dpd_ibuf = dpd_ibuf | STA_ERR;
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
clrCMD (devc); /* clr cch cmd */
dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */
@@ -498,7 +506,7 @@ case FNC_CHK: /* check, need cnt */
if (CMD (devd)) { /* dch active? */
dpc_cnt = dpd_obuf & DA_CKMASK; /* get count */
dpd_wval = 0; /* clr data valid */
/* setFLG (devd); /* set dch flg */
/* setFSR (devd); /* set dch flg */
/* clrCMD (devd); /* clr dch cmd */
dp_goc (FNC_CHK1, drv, dpc_xtime); } /* sched drv */
else sim_activate (uptr, dpc_xtime); /* wait more */
@@ -535,7 +543,7 @@ 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? */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
dpc_sta[drv] = 0; /* clr status */
dpc_busy = 0; /* ctlr is free */
@@ -553,7 +561,7 @@ case FNC_SEEK3: /* waiting for flag */
uptr->FNC = FNC_SEEK3; /* next state */
sim_activate (uptr, dpc_xtime); }
else {
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); } /* clear cmd */
return SCPE_OK;
@@ -589,7 +597,7 @@ case FNC_CHK1: /* check */
if (dpc_cnt == 0) break; } /* stop at zero */
dp_ptr = 0; } /* wrap buf ptr */
if (CMD (devd) && dpd_xfer) { /* dch on, xfer? */
setFLG (devd); } /* set flag */
setFSR (devd); } /* set flag */
clrCMD (devd); /* clr dch cmd */
sim_activate (uptr, dpc_xtime); /* sched next word */
return SCPE_OK;
@@ -623,7 +631,7 @@ case FNC_WD: /* write */
if (err = ferror (uptr->fileref)) break; /* error? */
dp_ptr = 0; } /* next sector */
if (CMD (devd) && dpd_xfer) { /* dch on, xfer? */
setFLG (devd); } /* set flag */
setFSR (devd); } /* set flag */
clrCMD (devd); /* clr dch cmd */
sim_activate (uptr, dpc_xtime); /* sched next word */
return SCPE_OK;
@@ -632,7 +640,7 @@ default:
return SCPE_IERR; } /* end case fnc */
if (!dp_ctype) dpc_sta[drv] = dpc_sta[drv] | STA_ATN; /* 12559 sets ATN */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
dpc_busy = 0; /* ctlr is free */
dpd_xfer = dpd_wval = 0;
@@ -659,6 +667,7 @@ dpc_dib.cmd = dpd_dib.cmd = 0; /* clear cmd */
dpc_dib.ctl = dpd_dib.ctl = 0; /* clear ctl */
dpc_dib.fbf = dpd_dib.fbf = 1; /* set fbf */
dpc_dib.flg = dpd_dib.flg = 1; /* set flg */
dpc_dib.srq = dpd_dib.flg = 1; /* srq follows flg */
sim_cancel (&dpd_unit); /* cancel dch */
for (i = 0; i < DP_NUMDRV; i++) { /* loop thru drives */
sim_cancel (&dpc_unit[i]); /* cancel activity */
@@ -711,27 +720,24 @@ return SCPE_OK;
/* 7900/7901 bootstrap routine (HP 12992F ROM) */
#define LDR_BASE 077
#define CHANGE_DEV (1 << 24)
static const int32 dboot[IBL_LNT] = {
0106700+CHANGE_DEV, /*ST CLC DC ; clr dch */
0106701+CHANGE_DEV, /* CLC CC ; clr cch */
const uint16 dp_rom[IBL_LNT] = {
0106710, /*ST CLC DC ; clr dch */
0106711, /* CLC CC ; clr cch */
0017757, /* JSB STAT ; get status */
0067746, /*SK LDB SKCMD ; seek cmd */
0106600+CHANGE_DEV, /* OTB DC ; cyl # */
0103700+CHANGE_DEV, /* STC DC,C ; to dch */
0106601+CHANGE_DEV, /* OTB CC ; seek cmd */
0103701+CHANGE_DEV, /* STC CC,C ; to cch */
0102300+CHANGE_DEV, /* SFS DC ; addr wd ok? */
0106610, /* OTB DC ; cyl # */
0103710, /* STC DC,C ; to dch */
0106611, /* OTB CC ; seek cmd */
0103711, /* STC CC,C ; to cch */
0102310, /* SFS DC ; addr wd ok? */
0027710, /* JMP *-1 ; no, wait */
0006400, /* CLB */
0102501, /* LIA 1 ; read switches */
0002011, /* SLA,RSS ; <0> set? */
0047747, /* ADB BIT9 ; head 2 = fixed */
0106600+CHANGE_DEV, /* OTB DC ; head/sector */
0103700+CHANGE_DEV, /* STC DC,C ; to dch */
0102301+CHANGE_DEV, /* SFS CC ; seek done? */
0047747, /* ADB BIT9 ; head 2 = removable */
0106610, /* OTB DC ; head/sector */
0103710, /* STC DC,C ; to dch */
0102311, /* SFS CC ; seek done? */
0027720, /* JMP *-1 ; no, wait */
0017757, /* JSB STAT ; get status */
0067776, /* LDB DMACW ; DMA control */
@@ -742,11 +748,11 @@ static const int32 dboot[IBL_LNT] = {
0067752, /* LDB CNT ; word count */
0106602, /* OTB 2 */
0063745, /* LDB RDCMD ; read cmd */
0102601+CHANGE_DEV, /* OTA CC ; to cch */
0103700+CHANGE_DEV, /* STC DC,C ; start dch */
0103606, /* STC 6,C ; start DMA */
0103701+CHANGE_DEV, /* STC CC,C ; start cch */
0102301+CHANGE_DEV, /* SFS CC ; done? */
0102611, /* OTA CC ; to cch */
0103710, /* STC DC,C ; start dch */
0103706, /* STC 6,C ; start DMA */
0103711, /* STC CC,C ; start cch */
0102311, /* SFS CC ; done? */
0027737, /* JMP *-1 ; no, wait */
0017757, /* JSB STAT ; get status */
0027775, /* JMP XT ; done */
@@ -761,11 +767,11 @@ static const int32 dboot[IBL_LNT] = {
0, 0, 0, 0, /* unused */
0000000, /*STAT 0 */
0002400, /* CLA ; status request */
0102601+CHANGE_DEV, /* OTC CC ; to cch */
0103701+CHANGE_DEV, /* STC CC,C ; start cch */
0102300+CHANGE_DEV, /* SFS DC ; done? */
0102611, /* OTC CC ; to cch */
0103711, /* STC CC,C ; start cch */
0102310, /* SFS DC ; done? */
0027763, /* JMP *-1 */
0102500+CHANGE_DEV, /* LIA DC ; get status */
0102510, /* LIA DC ; get status */
0013743, /* AND FSMSK ; mask 15,14,3,0 */
0002003, /* SZA,RSS ; drive ready? */
0127757, /* JMP STAT,I ; yes */
@@ -774,23 +780,18 @@ static const int32 dboot[IBL_LNT] = {
0102030, /* HLT 30 ; yes */
0027700, /* JMP ST ; no, retry */
0117751, /*XT JSB ADDR2,I ; start program */
0120000+CHANGE_DEV, /*DMACW 120000+DC */
0120010, /*DMACW 120000+DC */
0000000 }; /* -ST */
t_stat dpc_boot (int32 unitno, DEVICE *dptr)
{
int32 i, dev;
int32 dev;
if (unitno != 0) return SCPE_NOFNC; /* only unit 0 */
dev = dpd_dib.devno; /* get data chan dev */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
SR = IBL_DP + (dev << IBL_V_DEV); /* set SR */
if (sim_switches & SWMASK ('F')) SR = SR | IBL_FIX; /* boot from fixed? */
for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */
if (dboot[i] & CHANGE_DEV) /* IO instr? */
M[PC + i] = (dboot[i] + dev) & DMASK;
else M[PC + i] = dboot[i]; }
M[PC + LDR_BASE] = (~PC + 1) & DMASK;
if (ibl_copy (dp_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = (SR & IBL_OPT) | IBL_DP | (dev << IBL_V_DEV); /* set SR */
if (sim_switches & SWMASK ('R')) SR = SR | IBL_DP_REM; /* boot from removable? */
return SCPE_OK;
}

View File

@@ -25,6 +25,11 @@
dq 12565A 2883 disk system
21-Apr-04 RMS Fixed typo in boot loader (found by Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Fixed SR setting in IBL
Revised IBL loader
Implemented DMA SRQ (follows FLG)
25-Apr-03 RMS Fixed bug in status check
10-Nov-02 RMS Added boot command, rebuilt like 12559/13210
09-Jan-02 WOM Copied dp driver and mods for 2883
@@ -106,7 +111,7 @@
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;
extern UNIT cpu_unit;
@@ -145,8 +150,8 @@ void dq_goc (int32 fnc, int32 drv, int32 time);
*/
DIB dq_dib[] = {
{ DQD, 0, 0, 0, 0, &dqdio },
{ DQC, 0, 0, 0, 0, &dqcio } };
{ DQD, 0, 0, 0, 0, 0, &dqdio },
{ DQC, 0, 0, 0, 0, 0, &dqcio } };
#define dqd_dib dq_dib[0]
#define dqc_dib dq_dib[1]
@@ -160,6 +165,7 @@ REG dqd_reg[] = {
{ FLDATA (CTL, dqd_dib.ctl, 0) },
{ FLDATA (FLG, dqd_dib.flg, 0) },
{ FLDATA (FBF, dqd_dib.fbf, 0) },
{ FLDATA (SRQ, dqd_dib.srq, 0) },
{ FLDATA (XFER, dqd_xfer, 0) },
{ FLDATA (WVAL, dqd_wval, 0) },
{ BRDATA (DBUF, dqxb, 8, 16, DQ_NUMWD) },
@@ -201,6 +207,7 @@ REG dqc_reg[] = {
{ FLDATA (CTL, dqc_dib.ctl, 0) },
{ FLDATA (FLG, dqc_dib.flg, 0) },
{ FLDATA (FBF, dqc_dib.fbf, 0) },
{ FLDATA (SRQ, dqc_dib.srq, 0) },
{ BRDATA (RARC, dqc_rarc, 8, 8, DQ_NUMDRV) },
{ BRDATA (RARH, dqc_rarh, 8, 5, DQ_NUMDRV) },
{ BRDATA (RARS, dqc_rars, 8, 5, DQ_NUMDRV) },
@@ -239,14 +246,14 @@ int32 devd;
devd = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devd); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devd); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devd) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devd) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
dqd_obuf = dat;
if (!dqc_busy || dqd_xfer) dqd_wval = 1; /* if !overrun, valid */
@@ -270,7 +277,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devd); } /* H/C option */
if (IR & I_HC) { clrFSR (devd); } /* H/C option */
return dat;
}
@@ -281,14 +288,14 @@ int32 devc, fnc, drv;
devc = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devc); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devc); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devc) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devc) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
dqc_obuf = dat;
break;
@@ -327,7 +334,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devc); } /* H/C option */
if (IR & I_HC) { clrFSR (devc); } /* H/C option */
return dat;
}
@@ -391,7 +398,7 @@ case FNC_SEEK: /* seek, need cyl */
if (CMD (devd)) { /* dch active? */
dqc_rarc[drv] = DA_GETCYL (dqd_obuf); /* take cyl word */
dqd_wval = 0; /* clr data valid */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
uptr->FNC = FNC_SEEK1; } /* advance state */
sim_activate (uptr, dqc_xtime); /* no, wait more */
@@ -401,7 +408,7 @@ case FNC_SEEK1: /* seek, need hd/sec */
dqc_rarh[drv] = DA_GETHD (dqd_obuf); /* get head */
dqc_rars[drv] = DA_GETSC (dqd_obuf); /* get sector */
dqd_wval = 0; /* clr data valid */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
if (sim_is_active (&dqc_unit[drv])) break; /* if busy */
st = abs (dqc_rarc[drv] - dqc_unit[drv].CYL) * dqc_stime;
@@ -428,7 +435,7 @@ case FNC_LA: /* arec, need cyl */
if (CMD (devd)) { /* dch active? */
dqc_rarc[drv] = DA_GETCYL (dqd_obuf); /* take cyl word */
dqd_wval = 0; /* clr data valid */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
uptr->FNC = FNC_LA1; } /* advance state */
sim_activate (uptr, dqc_xtime); /* no, wait more */
@@ -438,9 +445,9 @@ case FNC_LA1: /* arec, need hd/sec */
dqc_rarh[drv] = DA_GETHD (dqd_obuf); /* get head */
dqc_rars[drv] = DA_GETSC (dqd_obuf); /* get sector */
dqd_wval = 0; /* clr data valid */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); } /* clr dch cmd */
else sim_activate (uptr, dqc_xtime); /* no, wait more */
break;
@@ -451,7 +458,7 @@ case FNC_STA: /* read status */
dqd_ibuf = dqc_sta[drv] & ~STA_DID;
else dqd_ibuf = STA_NRDY;
if (drv) dqd_ibuf = dqd_ibuf | STA_DID;
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
clrCMD (devc); /* clr cch cmd */
dqc_sta[drv] = dqc_sta[drv] & /* clr sta flags */
@@ -464,7 +471,7 @@ case FNC_CHK: /* check, need cnt */
if (CMD (devd)) { /* dch active? */
dqc_cnt = dqd_obuf & DA_CKMASK; /* get count */
dqd_wval = 0; /* clr data valid */
/* setFLG (devd); /* set dch flg */
/* setFSR (devd); /* set dch flg */
/* clrCMD (devd); /* clr dch cmd */
dq_goc (FNC_CHK1, drv, dqc_ctime); } /* sched drv */
else sim_activate (uptr, dqc_xtime); /* wait more */
@@ -504,7 +511,7 @@ 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? */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
dqc_sta[drv] = 0; /* clr status */
dqc_busy = 0; /* ctlr is free */
@@ -522,7 +529,7 @@ case FNC_SEEK3:
uptr->FNC = FNC_SEEK3; /* next state */
sim_activate (uptr, dqc_xtime); } /* ctrl busy? wait */
else {
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); } /* clr cch cmd */
return SCPE_OK;
@@ -537,7 +544,7 @@ case FNC_RA: /* read addr */
dqc_rars[drv] = 0; }
else break;
dq_ptr = dq_ptr + 1;
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */
sim_activate (uptr, dqc_xtime); /* sched next word */
return SCPE_OK;
@@ -570,7 +577,7 @@ case FNC_CHK1: /* check */
if (dqc_cnt == 0) break; } /* if zero, done */
dq_ptr = 0; } /* wrap buf ptr */
if (CMD (devd) && dqd_xfer) { /* dch on, xfer? */
setFLG (devd); } /* set flag */
setFSR (devd); } /* set flag */
clrCMD (devd); /* clr dch cmd */
sim_activate (uptr, dqc_xtime); /* sched next word */
return SCPE_OK;
@@ -603,7 +610,7 @@ case FNC_WD: /* write */
if (err = ferror (uptr->fileref)) break;
dq_ptr = 0; }
if (CMD (devd) && dqd_xfer) { /* dch on, xfer? */
setFLG (devd); } /* set flag */
setFSR (devd); } /* set flag */
clrCMD (devd); /* clr dch cmd */
sim_activate (uptr, dqc_xtime); /* sched next word */
return SCPE_OK;
@@ -611,7 +618,7 @@ case FNC_WD: /* write */
default:
return SCPE_IERR; } /* end case fnc */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
dqc_busy = 0; /* ctlr is free */
dqd_xfer = dqd_wval = 0;
@@ -637,6 +644,7 @@ dqc_dib.cmd = dqd_dib.cmd = 0; /* clear cmd */
dqc_dib.ctl = dqd_dib.ctl = 0; /* clear ctl */
dqc_dib.fbf = dqd_dib.fbf = 1; /* set fbf */
dqc_dib.flg = dqd_dib.flg = 1; /* set flg */
dqc_dib.srq = dqd_dib.srq = 1; /* srq follows flg */
sim_cancel (&dqd_unit); /* cancel dch */
for (i = 0; i < DQ_NUMDRV; i++) { /* loop thru drives */
sim_cancel (&dqc_unit[i]); /* cancel activity */
@@ -655,66 +663,81 @@ if (uptr->flags & UNIT_ATT) return SCPE_ARG;
return SCPE_OK;
}
/* 2883/2884 bootstrap routine (subset HP 12992A ROM) */
/* 7900/7901/2883/2884 bootstrap routine (HP 12992A ROM) */
#define LDR_BASE 077
#define CHANGE_DEV (1 << 24)
static const int32 dboot[IBL_LNT] = {
0106700+CHANGE_DEV, /*ST CLC DC ; clr dch */
0106701+CHANGE_DEV, /* CLC CC ; clr cch */
0067771, /* LDA SKCMD ; seek cmd */
0106600+CHANGE_DEV, /* OTB DC ; cyl # */
0103700+CHANGE_DEV, /* STC DC,C ; to dch */
0106601+CHANGE_DEV, /* OTB CC ; seek cmd */
0103701+CHANGE_DEV, /* STC CC,C ; to cch */
0102300+CHANGE_DEV, /* SFS DC ; addr wd ok? */
0027707, /* JMP *-1 ; no, wait */
const uint16 dq_rom[IBL_LNT] = {
0102501, /*ST LIA 1 ; get switches */
0106501, /* LIB 1 */
0013765, /* AND D7 ; isolate hd */
0005750, /* BLF,CLE,SLB */
0027741, /* JMP RD */
0005335, /* RBR,SLB,ERB ; <13>->E, set = 2883 */
0027717, /* JMP IS */
0102611, /*LP OTA CC ; do 7900 status to */
0103711, /* STC CC,C ; clear first seek */
0102310, /* SFS DC */
0027711, /* JMP *-1 */
0002004, /* INA ; get next drive */
0053765, /* CPA D7 ; all cleared? */
0002001, /* RSS */
0027707, /* JMP LP */
0067761, /*IS LDB SEEKC ; get seek comnd */
0106610, /* OTB DC ; issue cyl addr (0) */
0103710, /* STC DC,C ; to dch */
0106611, /* OTB CC ; seek cmd */
0103711, /* STC CC,C ; to cch */
0102310, /* SFS DC ; addr wd ok? */
0027724, /* JMP *-1 ; no, wait */
0006400, /* CLB */
0106600+CHANGE_DEV, /* OTB DC ; head/sector */
0103700+CHANGE_DEV, /* STC DC,C ; to dch */
0102301+CHANGE_DEV, /* SFS CC ; seek done? */
0027714, /* JMP *-1 ; no, wait */
0063770, /* LDA RDCMD ; get read read */
0067776, /* LDB DMACW ; DMA control */
0102501, /* LIA 1 ; get switches */
0002051, /* SEZ,SLA,RSS ; subchan = 1 or ISS */
0047770, /* ADB BIT9 ; head 2 */
0106610, /* OTB DC ; head/sector */
0103710, /* STC DC,C ; to dch */
0102311, /* SFS CC ; seek done? */
0027734, /* JMP *-1 ; no, wait */
0063731, /* LDA ISSRD ; get read read */
0002341, /* SEZ,CCE,RSS ; iss disc? */
0001100, /* ARS ; no, make 7900 read */
0067776, /*RD LDB DMACW ; DMA control */
0106606, /* OTB 6 */
0067772, /* LDB ADDR1 ; memory addr */
0067762, /* LDB ADDR1 ; memory addr */
0077741, /* STB RD ; make non re-executable */
0106602, /* OTB 2 */
0102702, /* STC 2 ; flip DMA ctrl */
0067774, /* LDB CNT ; word count */
0067764, /* LDB COUNT ; word count */
0106602, /* OTB 2 */
0102601+CHANGE_DEV, /* OTA CC ; to cch */
0103700+CHANGE_DEV, /* STC DC,C ; start dch */
0103606, /* STC 6,C ; start DMA */
0103701+CHANGE_DEV, /* STC CC,C ; start cch */
0102301+CHANGE_DEV, /* SFS CC ; done? */
0027732, /* JMP *-1 ; no, wait */
0027775, /* JMP XT ; done */
0, 0, 0, /* unused */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0020000, /*RDCMD 020000 ; read cmd */
0030000, /*SKCMD 030000 ; seek cmd */
0002041, /* SEZ,RSS */
0027766, /* JMP NW */
0102611, /* OTA CC ; to cch */
0103710, /* STC DC,C ; start dch */
0103706, /* STC 6,C ; start DMA */
0103711, /* STC CC,C ; start cch */
0037773, /* ISZ SK */
0027773, /* JMP SK */
0030000, /*SEEKC 030000 */
0102011, /*ADDR1 102011 */
0102055, /*ADDR2 102055 */
0164000, /*CNT -6144. */
0117773, /*XT JSB ADDR2,I ; start program */
0120000+CHANGE_DEV, /*DMACW 120000+DC */
0164000, /*COUNT -6144. */
0000007, /*D7 7 */
0106710, /*NW CLC DC ; set 'next wd is cmd' flag */
0001720, /* ALF,ALF ; move to head number loc */
0001000, /*BIT9 ALS */
0103610, /* OTA DC,C ; output cold load cmd */
0103706, /* STC 6,C ; start DMA */
0102310, /* SFS DC ; done? */
0027773, /* JMP *-1 ; no, wait */
0117763, /*XT JSB ADDR2,I ; start program */
0120010, /*DMACW 120000+DC */
0000000 }; /* -ST */
t_stat dqc_boot (int32 unitno, DEVICE *dptr)
{
int32 i, dev;
int32 dev;
if (unitno != 0) return SCPE_NOFNC; /* only unit 0 */
dev = dqd_dib.devno; /* get data chan dev */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
SR = IBL_DQ + (dev << IBL_V_DEV); /* set SR */
for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */
if (dboot[i] & CHANGE_DEV) /* IO instr? */
M[PC + i] = (dboot[i] + dev) & DMASK;
else M[PC + i] = dboot[i]; }
M[PC + LDR_BASE] = (~PC + 1) & DMASK;
if (ibl_copy (dq_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = (SR & IBL_OPT) | IBL_DQ | (dev << IBL_V_DEV); /* set SR */
return SCPE_OK;
}

View File

@@ -35,6 +35,9 @@
The drum control channel does not have any of the traditional flip-flops.
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Revised boot rom to use IBL algorithm
Implemented DMA SRQ (follows FLG)
27-Jul-03 RMS Fixed drum sizes
Fixed variable capacity interaction with SAVE/RESTORE
10-Nov-02 RMS Added BOOT command
@@ -110,7 +113,7 @@
extern UNIT cpu_unit;
extern uint16 *M;
extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
int32 drc_cw = 0; /* fnc, addr */
int32 drc_sta = 0; /* status */
@@ -142,8 +145,8 @@ t_stat dr_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
*/
DIB dr_dib[] = {
{ DRD, 0, 0, 0, 0, &drdio },
{ DRC, 0, 0, 0, 0, &drcio } };
{ DRD, 0, 0, 0, 0, 0, &drdio },
{ DRC, 0, 0, 0, 0, 0, &drcio } };
#define drd_dib dr_dib[0]
#define drc_dib dr_dib[1]
@@ -157,6 +160,7 @@ REG drd_reg[] = {
{ FLDATA (CTL, drd_dib.ctl, 0) },
{ FLDATA (FLG, drd_dib.flg, 0) },
{ FLDATA (FBF, drd_dib.fbf, 0) },
{ FLDATA (SRQ, drd_dib.srq, 0) },
{ ORDATA (BPTR, drd_ptr, 6) },
{ ORDATA (DEVNO, drd_dib.devno, 6), REG_HRO },
{ NULL } };
@@ -192,6 +196,7 @@ REG drc_reg[] = {
{ FLDATA (CTL, drc_dib.ctl, 0) },
{ FLDATA (FLG, drc_dib.flg, 0) },
{ FLDATA (FBF, drc_dib.fbf, 0) },
{ FLDATA (SRQ, drc_dib.srq, 0) },
{ DRDATA (TIME, dr_time, 24), REG_NZ + PV_LEFT },
{ FLDATA (STOP_IOE, dr_stopioe, 0) },
{ ORDATA (DEVNO, drc_dib.devno, 6), REG_HRO },
@@ -242,11 +247,11 @@ case ioLIX: /* load */
case ioCTL: /* control clear/set */
if (IR & I_AB) { /* CLC */
clrCMD (devd); /* clr "ctl" */
clrFLG (devd); /* clr flg */
clrFSR (devd); /* clr flg */
drc_sta = drc_sta & ~DRS_SAC; } /* clear SAC flag */
else if (!CMD (devd)) { /* STC, not set? */
setCMD (devd); /* set "ctl" */
if (drc_cw & CW_WR) { setFLG (devd); } /* prime DMA */
if (drc_cw & CW_WR) { setFSR (devd); } /* prime DMA */
drc_sta = 0; /* clear errors */
drd_ptr = 0; /* clear sec ptr */
sim_cancel (&drc_unit); /* cancel curr op */
@@ -256,7 +261,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devd); } /* H/C option */
if (IR & I_HC) { clrFSR (devd); } /* H/C option */
return dat;
}
@@ -267,7 +272,7 @@ int32 st;
switch (inst) { /* case on opcode */
case ioSFC: /* skip flag clear */
PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
drc_cw = dat;
break;
@@ -310,7 +315,7 @@ if (drc_cw & CW_WR) { /* write? */
uptr->hwmark = da + drd_ptr + 1; }
drd_ptr = dr_incda (trk, sec, drd_ptr); /* inc disk addr */
if (CMD (devd)) { /* dch active? */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
sim_activate (uptr, dr_time); } /* sched next word */
else if (drd_ptr) { /* done, need to fill? */
for ( ; drd_ptr < DR_NUMWD; drd_ptr++)
@@ -321,7 +326,7 @@ else { /* read */
if ((da >= uptr->capac) || (sec >= DR_NUMSC)) drd_ibuf = 0;
else drd_ibuf = bptr[da + drd_ptr];
drd_ptr = dr_incda (trk, sec, drd_ptr);
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
sim_activate (uptr, dr_time); } /* sched next word */
}
return SCPE_OK;
@@ -354,6 +359,7 @@ drc_dib.cmd = drd_dib.cmd = 0; /* clear cmd */
drc_dib.ctl = drd_dib.ctl = 0; /* clear ctl */
drc_dib.fbf = drd_dib.fbf = 0; /* clear fbf */
drc_dib.flg = drd_dib.flg = 0; /* clear flg */
drc_dib.srq = drd_dib.srq = 0; /* srq follows flg */
sim_cancel (&drc_unit);
return SCPE_OK;
}
@@ -384,18 +390,17 @@ return SCPE_OK;
/* Fixed head disk/drum bootstrap routine (disc subset of disc/paper tape loader) */
#define CHANGE_DEV (1 << 24)
#define BOOT_BASE 056
#define BOOT_START 060
static const int32 dboot[IBL_LNT - BOOT_BASE] = {
0020000+CHANGE_DEV, /*DMA 20000+DC */
static const uint16 dr_rom[IBL_LNT - BOOT_BASE] = {
0020010, /*DMA 20000+DC */
0000000, /* 0 */
0107700, /* CLC 0,C */
0063756, /* LDA DMA ; DMA ctrl */
0102606, /* OTA 6 */
0002700, /* CLA,CCE */
0102601+CHANGE_DEV, /* OTA CC ; trk = sec = 0 */
0102611, /* OTA CC ; trk = sec = 0 */
0001500, /* ERA ; A = 100000 */
0102602, /* OTA 2 ; DMA in, addr */
0063777, /* LDA M64 */
@@ -404,21 +409,25 @@ static const int32 dboot[IBL_LNT - BOOT_BASE] = {
0103706, /* STC 6,C ; start DMA */
0067776, /* LDB JSF ; get JMP . */
0074077, /* STB 77 ; in base page */
0102700+CHANGE_DEV, /* STC DC ; start disc */
0102710, /* STC DC ; start disc */
0024077, /*JSF JMP 77 ; go wait */
0177700 }; /*M64 -100 */
t_stat drc_boot (int32 unitno, DEVICE *dptr)
{
int32 i, dev, ad;
uint16 wd;
if (unitno != 0) return SCPE_NOFNC; /* only unit 0 */
dev = drd_dib.devno; /* get data chan dev */
ad = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
for (i = 0; i < (IBL_LNT - BOOT_BASE); i++) { /* copy bootstrap */
if (dboot[i] & CHANGE_DEV) /* IO instr? */
M[ad + BOOT_BASE + i] = (dboot[i] + dev) & DMASK;
else M[ad + BOOT_BASE + i] = dboot[i]; }
for (i = BOOT_BASE; i < IBL_LNT; i++) { /* copy bootstrap */
wd = dr_rom[i - BOOT_BASE]; /* get word */
if (((wd & I_NMRMASK) == I_IO) && /* IO instruction? */
((wd & I_DEVMASK) >= 010) && /* dev >= 10? */
(I_GETIOOP (wd) != ioHLT)) /* not a HALT? */
M[ad + i] = (wd + (dev - 010)) & DMASK;
else M[ad + i] = wd; }
PC = ad + BOOT_START;
return SCPE_OK;
}

1398
HP2100/hp2100_ds.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,8 @@
ipli, iplo 12556B interprocessor link pair
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Implemented DMA SRQ (follows FLG)
21-Dec-03 RMS Adjusted ipl_ptime for TSB (from Mike Gemeny)
09-May-03 RMS Added network device flag
31-Jan-03 RMS Links are full duplex (found by Mike Gemeny)
@@ -48,7 +50,7 @@
#define LSOCKET u4 /* listening socket */
extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern FILE *sim_log;
int32 ipl_ptime = 31; /* polling interval */
int32 ipl_stopioe = 0; /* stop on error */
@@ -75,8 +77,8 @@ t_bool ipl_check_conn (UNIT *uptr);
*/
DIB ipl_dib[] = {
{ IPLI, 0, 0, 0, 0, &ipliio },
{ IPLO, 0, 0, 0, 0, &iploio } };
{ IPLI, 0, 0, 0, 0, 0, &ipliio },
{ IPLO, 0, 0, 0, 0, 0, &iploio } };
#define ipli_dib ipl_dib[0]
#define iplo_dib ipl_dib[1]
@@ -95,6 +97,7 @@ REG ipli_reg[] = {
{ FLDATA (CTL, ipli_dib.ctl, 0) },
{ FLDATA (FLG, ipli_dib.flg, 0) },
{ FLDATA (FBF, ipli_dib.fbf, 0) },
{ FLDATA (SRQ, ipli_dib.srq, 0) },
{ ORDATA (HOLD, ipl_hold[0], 8) },
{ DRDATA (TIME, ipl_ptime, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ipl_stopioe, 0) },
@@ -131,6 +134,7 @@ REG iplo_reg[] = {
{ FLDATA (CTL, iplo_dib.ctl, 0) },
{ FLDATA (FLG, iplo_dib.flg, 0) },
{ FLDATA (FBF, iplo_dib.fbf, 0) },
{ FLDATA (SRQ, iplo_dib.srq, 0) },
{ ORDATA (HOLD, ipl_hold[1], 8) },
{ DRDATA (TIME, ipl_ptime, 24), PV_LEFT },
{ ORDATA (DEVNO, iplo_dib.devno, 6), REG_HRO },
@@ -164,14 +168,14 @@ int8 msg[2];
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
uptr->OBUF = dat;
break;
@@ -204,12 +208,12 @@ case ioCTL: /* control clear/set */
u = (uptr - ipl_unit) ^ 1; /* find other device */
ipl_unit[u].IBUF = uptr->OBUF; /* output to other */
odev = ipl_dib[u].devno; /* other device no */
setFLG (odev); } /* set other flag */
setFSR (odev); } /* set other flag */
else return SCPE_UNATT; } /* lose */
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
@@ -241,7 +245,7 @@ else uptr->IBUF = ((((int32) msg[0]) & 0377) << 8) |
(((int32) msg[1]) & 0377);
dev = ipl_dib[u].devno; /* get device number */
clrCMD (dev); /* clr cmd, set flag */
setFLG (dev);
setFSR (dev);
return SCPE_OK;
}
@@ -268,7 +272,7 @@ UNIT *uptr = dptr->units;
hp_enbdis_pair (&ipli_dev, &iplo_dev); /* make pair cons */
dibp->cmd = dibp->ctl = 0; /* clear cmd, ctl */
dibp->flg = dibp->fbf = 1; /* set flg, fbf */
dibp->flg = dibp->fbf = dibp->srq = 1; /* set flg, fbf, srq */
uptr->IBUF = uptr->OBUF = 0; /* clr buffers */
if (uptr->flags & UNIT_ATT) sim_activate (uptr, ipl_ptime);
else sim_cancel (uptr); /* deactivate unit */
@@ -381,13 +385,13 @@ return SCPE_OK;
/* Interprocessor link bootstrap routine (HP Access Manual) */
#define LDR_BASE 073
#define MAX_BASE 073
#define IPL_PNTR 074
#define PTR_PNTR 075
#define IPL_DEVA 076
#define PTR_DEVA 077
static const int32 pboot[IBL_LNT] = {
static const uint32 pboot[IBL_LNT] = {
0163774, /*BBL LDA ICK,I ; IPL sel code */
0027751, /* JMP CFG ; go configure */
0107700, /*ST CLC 0,C ; intr off */
@@ -467,7 +471,7 @@ devp = ptr_dib.devno;
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
SR = (devi << IBL_V_DEV) | devp; /* set SR */
for (i = 0; i < IBL_LNT; i++) M[PC + i] = pboot[i]; /* copy bootstrap */
M[PC + LDR_BASE] = (~PC + 1) & DMASK; /* fix ups */
M[PC + MAX_BASE] = (~PC + 1) & DMASK; /* fix ups */
M[PC + IPL_PNTR] = M[PC + IPL_PNTR] | PC;
M[PC + PTR_PNTR] = M[PC + PTR_PNTR] | PC;
M[PC + IPL_DEVA] = devi;

View File

@@ -26,6 +26,9 @@
lps 12653A 2767 line printer
(based on 12556B microcircuit interface)
03-Jun-04 RMS Fixed timing (found by Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Implemented DMA SRQ (follows FLG)
25-Apr-03 RMS Revised for extended file support
24-Oct-02 RMS Added microcircuit test features
30-May-02 RMS Widened POS to 32b
@@ -44,8 +47,9 @@
#define UNIT_DIAG (1 << UNIT_V_DIAG)
extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
int32 lps_ctime = 1000; /* char time */
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
int32 lps_ctime = 4; /* char time */
int32 lps_ptime = 10000; /* print time */
int32 lps_stopioe = 0; /* stop on error */
int32 lps_sta = 0;
@@ -61,10 +65,10 @@ t_stat lps_reset (DEVICE *dptr);
lps_reg LPS register list
*/
DIB lps_dib = { LPS, 0, 0, 0, 0, &lpsio };
DIB lps_dib = { LPS, 0, 0, 0, 0, 0, &lpsio };
UNIT lps_unit = {
UDATA (&lps_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
UDATA (&lps_svc, UNIT_SEQ+UNIT_ATTABLE, 0) };
REG lps_reg[] = {
{ ORDATA (BUF, lps_unit.buf, 16) },
@@ -73,9 +77,10 @@ REG lps_reg[] = {
{ FLDATA (CTL, lps_dib.ctl, 0) },
{ FLDATA (FLG, lps_dib.flg, 0) },
{ FLDATA (FBF, lps_dib.fbf, 0) },
{ FLDATA (SRQ, lps_dib.srq, 0) },
{ DRDATA (POS, lps_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (CTIME, lps_ctime, 31), PV_LEFT },
{ DRDATA (PTIME, lps_unit.wait, 24), PV_LEFT },
{ DRDATA (PTIME, lps_ptime, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lps_stopioe, 0) },
{ ORDATA (DEVNO, lps_dib.devno, 6), REG_HRO },
{ NULL } };
@@ -103,14 +108,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
lps_unit.buf = dat;
break;
@@ -135,11 +140,11 @@ case ioCTL: /* control clear/set */
if (lps_unit.flags & UNIT_DIAG) /* diagnostic? */
sim_activate (&lps_unit, 1); /* loop back */
else sim_activate (&lps_unit, /* real lpt, sched */
(lps_unit.buf < 040)? lps_unit.wait: lps_ctime); }
(lps_unit.buf < 040)? lps_ptime: lps_ctime); }
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
@@ -150,7 +155,7 @@ int32 c = lps_unit.buf & 0177;
dev = lps_dib.devno; /* get dev no */
clrCMD (dev); /* clear cmd */
setFLG (dev); /* set flag, fbf */
setFSR (dev); /* set flag, fbf */
if (lps_unit.flags & UNIT_DIAG) { /* diagnostic? */
lps_sta = lps_unit.buf; /* loop back */
return SCPE_OK; } /* done */
@@ -169,7 +174,7 @@ return SCPE_OK;
t_stat lps_reset (DEVICE *dptr)
{
lps_dib.cmd = lps_dib.ctl = 0; /* clear cmd, ctl */
lps_dib.flg = lps_dib.fbf = 1; /* set flg, fbf */
lps_dib.flg = lps_dib.fbf = lps_dib.srq = 1; /* set flg, fbf, srq */
lps_sta = lps_unit.buf = 0;
sim_cancel (&lps_unit); /* deactivate unit */
return SCPE_OK;

View File

@@ -25,6 +25,9 @@
lpt 12845A line printer
03-Jun-04 RMS Fixed timing (found by Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Implemented DMA SRQ (follows FLG)
25-Apr-03 RMS Revised for extended file support
24-Oct-02 RMS Cloned from 12653A
*/
@@ -43,8 +46,10 @@
#define LPT_CHANM 0000007 /* channel mask */
extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
int32 lpt_ctime = 1000; /* char time */
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
int32 lpt_ctime = 4; /* char time */
int32 lpt_ptime = 10000; /* print time */
int32 lpt_stopioe = 0; /* stop on error */
int32 lpt_lcnt = 0; /* line count */
static int32 lpt_cct[8] = {
@@ -63,10 +68,10 @@ t_stat lpt_attach (UNIT *uptr, char *cptr);
lpt_reg LPT register list
*/
DIB lpt_dib = { LPT, 0, 0, 0, 0, &lptio };
DIB lpt_dib = { LPT, 0, 0, 0, 0, 0, &lptio };
UNIT lpt_unit = {
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0) };
REG lpt_reg[] = {
{ ORDATA (BUF, lpt_unit.buf, 7) },
@@ -74,10 +79,11 @@ REG lpt_reg[] = {
{ FLDATA (CTL, lpt_dib.ctl, 0) },
{ FLDATA (FLG, lpt_dib.flg, 0) },
{ FLDATA (FBF, lpt_dib.fbf, 0) },
{ FLDATA (SRQ, lpt_dib.srq, 0) },
{ DRDATA (LCNT, lpt_lcnt, 7) },
{ DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (CTIME, lpt_ctime, 31), PV_LEFT },
{ DRDATA (PTIME, lpt_unit.wait, 24), PV_LEFT },
{ DRDATA (PTIME, lpt_ptime, 24), PV_LEFT },
{ FLDATA (STOP_IOE, lpt_stopioe, 0) },
{ ORDATA (DEVNO, lpt_dib.devno, 6), REG_HRO },
{ NULL } };
@@ -103,14 +109,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
lpt_unit.buf = dat & (LPT_CTL | 0177);
break;
@@ -131,11 +137,11 @@ case ioCTL: /* control clear/set */
setCMD (dev); /* set ctl, cmd */
setCTL (dev);
sim_activate (&lpt_unit, /* schedule op */
(lpt_unit.buf & LPT_CTL)? lpt_unit.wait: lpt_ctime); }
(lpt_unit.buf & LPT_CTL)? lpt_ptime: lpt_ctime); }
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
@@ -147,7 +153,7 @@ dev = lpt_dib.devno; /* get dev no */
clrCMD (dev); /* clear cmd */
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (lpt_stopioe, SCPE_UNATT);
setFLG (dev); /* set flag, fbf */
setFSR (dev); /* set flag, fbf */
if (uptr->buf & LPT_CTL) { /* control word? */
if (uptr->buf & LPT_CHAN) {
chan = uptr->buf & LPT_CHANM;
@@ -179,7 +185,7 @@ return SCPE_OK;
t_stat lpt_reset (DEVICE *dptr)
{
lpt_dib.cmd = lpt_dib.ctl = 0; /* clear cmd, ctl */
lpt_dib.flg = lpt_dib.fbf = 1; /* set flg, fbf */
lpt_dib.flg = lpt_dib.fbf = lpt_dib.srq = 1; /* set flg, fbf, srq */
lpt_unit.buf = 0;
sim_cancel (&lpt_unit); /* deactivate unit */
return SCPE_OK;

View File

@@ -26,6 +26,11 @@
ms 13181A 7970B 800bpi nine track magnetic tape
13183A 7970E 1600bpi nine track magnetic tape
06-Jul-04 RMS Fixed spurious timing error after CLC (found by Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Fixed SR setting in IBL
Revised IBL loader
Implemented DMA SRQ (follows FLG)
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
28-Feb-03 RMS Revised for magtape library
@@ -110,7 +115,7 @@
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;
extern UNIT cpu_unit;
@@ -148,8 +153,8 @@ t_stat ms_showtype (FILE *st, UNIT *uptr, int32 val, void *desc);
*/
DIB ms_dib[] = {
{ MSD, 0, 0, 0, 0, &msdio },
{ MSC, 0, 0, 0, 0, &mscio } };
{ MSD, 0, 0, 0, 0, 0, &msdio },
{ MSC, 0, 0, 0, 0, 0, &mscio } };
#define msd_dib ms_dib[0]
#define msc_dib ms_dib[1]
@@ -162,6 +167,7 @@ REG msd_reg[] = {
{ FLDATA (CTL, msd_dib.ctl, 0) },
{ FLDATA (FLG, msd_dib.flg, 0) },
{ FLDATA (FBF, msd_dib.fbf, 0) },
{ FLDATA (SRQ, msd_dib.srq, 0) },
{ BRDATA (DBUF, msxb, 8, 8, DBSIZE) },
{ DRDATA (BPTR, ms_ptr, DB_N_SIZE + 1) },
{ DRDATA (BMAX, ms_max, DB_N_SIZE + 1) },
@@ -203,6 +209,7 @@ REG msc_reg[] = {
{ FLDATA (CTL, msc_dib.ctl, 0) },
{ FLDATA (FLG, msc_dib.flg, 0) },
{ FLDATA (FBF, msc_dib.fbf, 0) },
{ FLDATA (SRQ, msc_dib.srq, 0) },
{ URDATA (POS, msc_unit[0].pos, 10, T_ADDR_W, 0, MS_NUMDR, PV_LEFT) },
{ URDATA (FNC, msc_unit[0].FNC, 8, 8, 0, MS_NUMDR, REG_HRO) },
{ URDATA (UST, msc_unit[0].UST, 8, 12, 0, MS_NUMDR, REG_HRO) },
@@ -246,14 +253,14 @@ int32 devd;
devd = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devd); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devd); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devd) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devd) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
msd_buf = dat; /* store data */
break;
@@ -271,9 +278,12 @@ case ioCTL: /* control clear/set */
setCTL (devd); /* set ctl, cmd */
setCMD (devd); }
break;
case ioEDT: /* DMA end */
clrFSR (devd); /* same as CLF */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devd); } /* H/C option */
if (IR & I_HC) { clrFSR (devd); } /* H/C option */
return dat;
}
@@ -290,14 +300,14 @@ devc = IR & I_DEVMASK; /* get device no */
devd = devc - 1;
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devc); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devc); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devc) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devc) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
msc_buf = dat;
msc_sta = msc_sta & ~STA_REJ; /* clear reject */
@@ -338,9 +348,9 @@ case ioCTL: /* control clear/set */
if ((msc_unit[i].UST & STA_REW) == 0)
sim_cancel (&msc_unit[i]); } /* stop if now rew */
clrCTL (devc); /* init device */
setFLG (devc);
setFSR (devc);
clrCTL (devd);
setFLG (devd);
setFSR (devd);
msc_sta = msd_buf = msc_buf = msc_1st = 0;
return SCPE_OK; }
uptr->FNC = msc_buf & 0377; /* save function */
@@ -352,9 +362,12 @@ case ioCTL: /* control clear/set */
msc_1st = 1;
setCTL (devc); } /* go */
break;
case ioEDT: /* DMA end */
clrFSR (devc); /* same as CLF */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devc); } /* H/C option */
if (IR & I_HC) { clrFSR (devc); } /* H/C option */
return dat;
}
@@ -377,7 +390,7 @@ devd = msd_dib.devno;
if ((uptr->flags & UNIT_ATT) == 0) { /* offline? */
msc_sta = (msc_sta | STA_REJ) & ~STA_BUSY; /* reject */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
return IORETURN (msc_stopioe, SCPE_UNATT); }
switch (uptr->FNC) { /* case on function */
@@ -446,11 +459,11 @@ case FNC_RC: /* read */
return SCPE_OK; }
break; } /* err, done */
}
if (ms_ptr < ms_max) { /* more chars? */
if (CTL (devd) && (ms_ptr < ms_max)) { /* DCH on, more data? */
if (FLG (devd)) msc_sta = msc_sta | STA_TIM | STA_PAR;
msd_buf = ((uint16) msxb[ms_ptr] << 8) | msxb[ms_ptr + 1];
ms_ptr = ms_ptr + 2;
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
sim_activate (uptr, msc_xtime); /* re-activate */
return SCPE_OK; }
sim_activate (uptr, msc_gtime); /* sched IRG */
@@ -468,7 +481,7 @@ case FNC_WC: /* write */
uptr->UST = 0; }
else msc_sta = msc_sta | STA_PAR; }
if (CTL (devd)) { /* xfer flop set? */
setFLG (devd); /* set dch flag */
setFSR (devd); /* set dch flag */
sim_activate (uptr, msc_xtime); /* re-activate */
return SCPE_OK; }
if (ms_ptr) { /* any data? write */
@@ -482,7 +495,7 @@ case FNC_WC: /* write */
default: /* unknown */
break; }
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
msc_sta = msc_sta & ~STA_BUSY; /* update status */
return SCPE_OK;
}
@@ -535,6 +548,7 @@ msc_dib.cmd = msd_dib.cmd = 0; /* clear cmd */
msc_dib.ctl = msd_dib.ctl = 0; /* clear ctl */
msc_dib.flg = msd_dib.flg = 1; /* set flg */
msc_dib.fbf = msd_dib.fbf = 1; /* set fbf */
msc_dib.srq = msd_dib.srq = 1; /* srq follows flg */
for (i = 0; i < MS_NUMDR; i++) {
uptr = msc_dev.units + i;
sim_tape_reset (uptr);
@@ -587,9 +601,7 @@ return SCPE_OK;
/* 7970B/7970E bootstrap routine (HP 12992D ROM) */
#define CHANGE_DEV (1 << 24)
static const int32 mboot[IBL_LNT] = {
const uint16 ms_rom[IBL_LNT] = {
0106501, /*ST LIB 1 ; read sw */
0006011, /* SLB,RSS ; bit 0 set? */
0027714, /* JMP RD ; no read */
@@ -597,42 +609,42 @@ static const int32 mboot[IBL_LNT] = {
0073775, /* STA WC ; save */
0067772, /* LDA SL0RW ; sel 0, rew */
0017762, /*FF JSB CMD ; do cmd */
0102301+CHANGE_DEV, /* SFS CC ; done? */
0102311, /* SFS CC ; done? */
0027707, /* JMP *-1 ; wait */
0067774, /* LDB FFC ; get file fwd */
0037775, /* ISZ WC ; done files? */
0027706, /* JMP FF ; no */
0067773, /*RD LDB RDCMD ; read cmd */
0017762, /* JSB CMD ; do cmd */
0103700+CHANGE_DEV, /* STC DC,C ; start dch */
0102201+CHANGE_DEV, /* SFC CC ; read done? */
0103710, /* STC DC,C ; start dch */
0102211, /* SFC CC ; read done? */
0027752, /* JMP STAT ; no, get stat */
0102300+CHANGE_DEV, /* SFS DC ; any data? */
0102310, /* SFS DC ; any data? */
0027717, /* JMP *-3 ; wait */
0107500+CHANGE_DEV, /* LIB DC,C ; get rec cnt */
0107510, /* LIB DC,C ; get rec cnt */
0005727, /* BLF,BLF ; move to lower */
0007000, /* CMB ; make neg */
0077775, /* STA WC ; save */
0102201+CHANGE_DEV, /* SFC CC ; read done? */
0102211, /* SFC CC ; read done? */
0027752, /* JMP STAT ; no, get stat */
0102300+CHANGE_DEV, /* SFS DC ; any data? */
0102310, /* SFS DC ; any data? */
0027727, /* JMP *-3 ; wait */
0107500+CHANGE_DEV, /* LIB DC,C ; get load addr */
0107510, /* LIB DC,C ; get load addr */
0074000, /* STB 0 ; start csum */
0077762, /* STA CMD ; save address */
0027742, /* JMP *+4 */
0177762, /*NW STB CMD,I ; store data */
0040001, /* ADA 1 ; add to csum */
0037762, /* ISZ CMD ; adv addr ptr */
0102300+CHANGE_DEV, /* SFS DC ; any data? */
0102310, /* SFS DC ; any data? */
0027742, /* JMP *-1 ; wait */
0107500+CHANGE_DEV, /* LIB DC,C ; get word */
0107510, /* LIB DC,C ; get word */
0037775, /* ISZ WC ; done? */
0027737, /* JMP NW ; no */
0054000, /* CPB 0 ; csum ok? */
0027717, /* JMP RD+3 ; yes, cont */
0102011, /* HLT 11 ; no, halt */
0102501+CHANGE_DEV, /*ST LIA CC ; get status */
0102511, /*ST LIA CC ; get status */
0001727, /* ALF,ALF ; get eof bit */
0002020, /* SSA ; set? */
0102077, /* HLT 77 ; done */
@@ -641,12 +653,12 @@ static const int32 mboot[IBL_LNT] = {
0102000, /* HLT 0 ; no */
0027714, /* JMP RD ; read next */
0000000, /*CMD 0 */
0106601+CHANGE_DEV, /* OTB CC ; output cmd */
0102501+CHANGE_DEV, /* LIA CC ; check for reject */
0106611, /* OTB CC ; output cmd */
0102511, /* LIA CC ; check for reject */
0001323, /* RAR,RAR */
0001310, /* RAR,SLA */
0027763, /* JMP CMD+1 ; try again */
0103701+CHANGE_DEV, /* STC CC,C ; start command */
0103711, /* STC CC,C ; start command */
0127762, /* JMP CMD,I ; exit */
0001501, /*SL0RW 001501 ; select 0, rewind */
0001423, /*RDCMD 001423 ; read record */
@@ -657,16 +669,12 @@ static const int32 mboot[IBL_LNT] = {
t_stat msc_boot (int32 unitno, DEVICE *dptr)
{
int32 i, dev;
int32 dev;
if (unitno != 0) return SCPE_NOFNC; /* only unit 0 */
dev = msd_dib.devno; /* get data chan dev */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
SR = IBL_MS + (dev << IBL_V_DEV); /* set SR */
if (ibl_copy (ms_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = (SR & IBL_OPT) | IBL_MS | (dev << IBL_V_DEV); /* set SR */
if ((sim_switches & SWMASK ('S')) && AR) SR = SR | 1; /* skip? */
for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */
if (mboot[i] & CHANGE_DEV) /* IO instr? */
M[PC + i] = (mboot[i] + dev) & DMASK;
else M[PC + i] = mboot[i]; }
return SCPE_OK;
}

View File

@@ -25,6 +25,9 @@
mt 12559A 3030 nine track magnetic tape
06-Jul-04 RMS Fixed spurious timing error after CLC (found by Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Implemented DMA SRQ (follows FLG)
21-Dec-03 RMS Adjusted msc_ctime for TSB (from Mike Gemeny)
25-Apr-03 RMS Revised for extended file support
28-Mar-03 RMS Added multiformat support
@@ -88,7 +91,8 @@
#define STA_BUSY 0001 /* busy (d) */
extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
int32 mtc_fnc = 0; /* function */
int32 mtc_sta = 0; /* status register */
int32 mtc_dtf = 0; /* data xfer flop */
@@ -119,8 +123,8 @@ t_stat mt_map_err (UNIT *uptr, t_stat st);
*/
DIB mt_dib[] = {
{ MTD, 0, 0, 0, 0, &mtdio },
{ MTC, 0, 0, 0, 0, &mtcio } };
{ MTD, 0, 0, 0, 0, 0, &mtdio },
{ MTC, 0, 0, 0, 0, 0, &mtcio } };
#define mtd_dib mt_dib[0]
#define mtc_dib mt_dib[1]
@@ -131,7 +135,8 @@ REG mtd_reg[] = {
{ FLDATA (CMD, mtd_dib.cmd, 0), REG_HRO },
{ FLDATA (CTL, mtd_dib.ctl, 0), REG_HRO },
{ FLDATA (FLG, mtd_dib.flg, 0) },
{ FLDATA (FBF, mtd_dib.fbf, 0), REG_HRO },
{ FLDATA (FBF, mtd_dib.fbf, 0) },
{ FLDATA (SRQ, mtd_dib.srq, 0) },
{ BRDATA (DBUF, mtxb, 8, 8, DBSIZE) },
{ DRDATA (BPTR, mt_ptr, DB_V_SIZE + 1) },
{ DRDATA (BMAX, mt_max, DB_V_SIZE + 1) },
@@ -172,6 +177,7 @@ REG mtc_reg[] = {
{ FLDATA (CTL, mtc_dib.ctl, 0) },
{ FLDATA (FLG, mtc_dib.flg, 0) },
{ FLDATA (FBF, mtc_dib.fbf, 0) },
{ FLDATA (SRQ, mtc_dib.srq, 0) },
{ FLDATA (DTF, mtc_dtf, 0) },
{ FLDATA (FSVC, mtc_1st, 0) },
{ DRDATA (POS, mtc_unit.pos, T_ADDR_W), PV_LEFT },
@@ -203,14 +209,14 @@ int32 devd;
devd = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devd); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devd); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devd) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devd) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
mtc_unit.buf = dat & 0377; /* store data */
break;
@@ -225,7 +231,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devd); } /* H/C option */
if (IR & I_HC) { clrFSR (devd); } /* H/C option */
return dat;
}
@@ -238,14 +244,14 @@ devc = IR & I_DEVMASK; /* get device no */
devd = devc - 1;
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (devc); } /* STF */
if ((IR & I_HC) == 0) { setFSR (devc); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (devc) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (devc) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
dat = dat & 0377;
mtc_sta = mtc_sta & ~STA_REJ; /* clear reject */
@@ -259,9 +265,9 @@ case ioOTX: /* output */
mtc_1st = mtc_dtf = 0;
mtc_sta = mtc_sta & STA_BOT;
clrCTL (devc); /* init device */
clrFLG (devc);
clrFSR (devc);
clrCTL (devd);
clrFLG (devd);
clrFSR (devd);
return SCPE_OK; }
for (i = valid = 0; i < sizeof (mtc_cmd); i++) /* is fnc valid? */
if (dat == mtc_cmd[i]) valid = 1;
@@ -275,8 +281,8 @@ case ioOTX: /* output */
mtc_fnc = dat; /* save function */
mtc_sta = STA_BUSY; /* unit busy */
mt_ptr = 0; /* init buffer ptr */
clrFLG (devc); /* clear flags */
clrFLG (devd);
clrFSR (devc); /* clear flags */
clrFSR (devd);
mtc_1st = 1; /* set 1st flop */
mtc_dtf = 1; } /* set xfer flop */
break;
@@ -295,7 +301,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (devc); } /* H/C option */
if (IR & I_HC) { clrFSR (devc); } /* H/C option */
return dat;
}
@@ -317,7 +323,7 @@ devc = mtc_dib.devno; /* get device nos */
devd = mtd_dib.devno;
if ((mtc_unit.flags & UNIT_ATT) == 0) { /* offline? */
mtc_sta = STA_LOCAL | STA_REJ; /* rejected */
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
return IORETURN (mtc_stopioe, SCPE_UNATT); }
switch (mtc_fnc) { /* case on function */
@@ -368,10 +374,10 @@ case FNC_RC: /* read */
mtc_sta = mtc_sta | STA_PAR; /* set flag */
break; }
}
if (mt_ptr < mt_max) { /* more chars? */
if (mtc_dtf && (mt_ptr < mt_max)) { /* more chars? */
if (FLG (devd)) mtc_sta = mtc_sta | STA_TIM;
mtc_unit.buf = mtxb[mt_ptr++]; /* fetch next */
setFLG (devd); /* set dch flg */
setFSR (devd); /* set dch flg */
sim_activate (uptr, mtc_xtime); /* re-activate */
return SCPE_OK; }
sim_activate (uptr, mtc_gtime); /* schedule gap */
@@ -386,7 +392,7 @@ case FNC_WC: /* write */
mtc_sta = mtc_sta & ~STA_BOT; } /* clear BOT */
else mtc_sta = mtc_sta | STA_PAR; }
if (mtc_dtf) { /* xfer flop set? */
setFLG (devd); /* set dch flag */
setFSR (devd); /* set dch flag */
sim_activate (uptr, mtc_xtime); /* re-activate */
return SCPE_OK; }
if (mt_ptr) { /* write buffer */
@@ -400,7 +406,7 @@ case FNC_WC: /* write */
default: /* unknown */
break; }
setFLG (devc); /* set cch flg */
setFSR (devc); /* set cch flg */
mtc_sta = mtc_sta & ~STA_BUSY; /* not busy */
return SCPE_OK;
}
@@ -449,6 +455,7 @@ mtc_dib.cmd = mtd_dib.cmd = 0; /* clear cmd */
mtc_dib.ctl = mtd_dib.ctl = 0; /* clear ctl */
mtc_dib.flg = mtd_dib.flg = 0; /* clear flg */
mtc_dib.fbf = mtd_dib.fbf = 0; /* clear fbf */
mtc_dib.srq = mtd_dib.srq = 0; /* srq follows flg */
sim_cancel (&mtc_unit); /* cancel activity */
sim_tape_reset (&mtc_unit);
if (mtc_unit.flags & UNIT_ATT) mtc_sta =

View File

@@ -25,6 +25,8 @@
mux,muxl,muxc 12920A terminal multiplexor
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Implemented DMA SRQ (follows FLG)
05-Jan-04 RMS Revised for tmxr library changes
21-Dec-03 RMS Added invalid character screening for TSB (from Mike Gemeny)
09-May-03 RMS Added network device flag
@@ -133,7 +135,7 @@
<< LIC_V_I)
extern uint32 PC;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
uint16 mux_sta[MUX_LINES]; /* line status */
uint16 mux_rpar[MUX_LINES + MUX_ILINES]; /* rcv param */
@@ -191,8 +193,8 @@ static uint8 odd_par[256] = {
#define RCV_PAR(x) (odd_par[(x) & 0377]? LIL_PAR: 0)
DIB mux_dib[] = {
{ MUXL, 0, 0, 0, 0, &muxlio },
{ MUXU, 0, 0, 0, 0, &muxuio } };
{ MUXL, 0, 0, 0, 0, 0, &muxlio },
{ MUXU, 0, 0, 0, 0, 0, &muxuio } };
#define muxl_dib mux_dib[0]
#define muxu_dib mux_dib[1]
@@ -214,6 +216,7 @@ REG muxu_reg[] = {
{ FLDATA (CTL, muxu_dib.ctl, 0), REG_HRO },
{ FLDATA (FLG, muxu_dib.flg, 0), REG_HRO },
{ FLDATA (FBF, muxu_dib.fbf, 0), REG_HRO },
{ FLDATA (SRQ, muxu_dib.srq, 0), REG_HRO },
{ ORDATA (DEVNO, muxu_dib.devno, 6), REG_HRO },
{ NULL } };
@@ -282,6 +285,7 @@ REG muxl_reg[] = {
{ FLDATA (CTL, muxl_dib.ctl, 0) },
{ FLDATA (FLG, muxl_dib.flg, 0) },
{ FLDATA (FBF, muxl_dib.fbf, 0) },
{ FLDATA (SRQ, muxl_dib.srq, 0) },
{ BRDATA (STA, mux_sta, 8, 16, MUX_LINES) },
{ BRDATA (RPAR, mux_rpar, 8, 16, MUX_LINES + MUX_ILINES) },
{ BRDATA (XPAR, mux_xpar, 8, 16, MUX_LINES) },
@@ -309,7 +313,7 @@ DEVICE muxl_dev = {
muxc_mod MUXM modifiers list
*/
DIB muxc_dib = { MUXC, 0, 0, 0, 0, &muxcio };
DIB muxc_dib = { MUXC, 0, 0, 0, 0, 0, &muxcio };
UNIT muxc_unit = { UDATA (NULL, 0, 0) };
@@ -318,6 +322,7 @@ REG muxc_reg[] = {
{ FLDATA (CTL, muxc_dib.ctl, 0) },
{ FLDATA (FLG, muxc_dib.flg, 0) },
{ FLDATA (FBF, muxc_dib.fbf, 0) },
{ FLDATA (SRQ, muxc_dib.srq, 0) },
{ FLDATA (SCAN, muxc_scan, 0) },
{ ORDATA (CHAN, muxc_chan, 4) },
{ BRDATA (DSO, muxc_ota, 8, 6, MUX_LINES) },
@@ -346,14 +351,14 @@ int32 dev, ln;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
muxl_obuf = dat; /* store data */
break;
@@ -385,7 +390,7 @@ case ioCTL: /* control clear/set */
default:
break; }
if (IR & I_HC) { /* H/C option */
clrFLG (dev); /* clear flag */
clrFSR (dev); /* clear flag */
mux_data_int (); } /* look for new int */
return dat;
}
@@ -416,14 +421,14 @@ int32 dev, ln, t, old;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioOTX: /* output */
if (dat & OTC_SCAN) muxc_scan = 1; /* set scan flag */
else muxc_scan = 0;
@@ -460,7 +465,7 @@ case ioCTL: /* ctrl clear/set */
default:
break; }
if (IR & I_HC) { /* H/C option */
clrFLG (dev); /* clear flag */
clrFSR (dev); /* clear flag */
mux_ctrl_int (); } /* look for new int */
return dat;
}
@@ -558,14 +563,14 @@ for (i = 0; i < MUX_LINES; i++) { /* rcv lines */
muxu_ibuf = PUT_CCH (i) | mux_sta[i]; /* hi buf = stat */
mux_rchp[i] = 0; /* clr char, stat */
mux_sta[i] = 0;
setFLG (muxl_dib.devno); /* interrupt */
setFSR (muxl_dib.devno); /* interrupt */
return; } }
for (i = 0; i < MUX_LINES; i++) { /* xmt lines */
if ((mux_xpar[i] & OTL_ENB) && mux_xdon[i]) { /* enabled, done? */
muxu_ibuf = PUT_CCH (i) | mux_sta[i] | LIU_TR; /* hi buf = stat */
mux_xdon[i] = 0; /* clr done, stat */
mux_sta[i] = 0;
setFLG (muxl_dib.devno); /* interrupt */
setFSR (muxl_dib.devno); /* interrupt */
return; } }
for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
if ((mux_rpar[i] & OTL_ENB) && mux_rchp[i]) { /* enabled, char? */
@@ -574,7 +579,7 @@ for (i = MUX_LINES; i < (MUX_LINES + MUX_ILINES); i++) { /* diag lines */
muxu_ibuf = PUT_CCH (i) | mux_sta[i] | LIU_DG; /* hi buf = stat */
mux_rchp[i] = 0; /* clr char, stat */
mux_sta[i] = 0;
setFLG (muxl_dib.devno);
setFSR (muxl_dib.devno);
return; } }
return;
}
@@ -589,7 +594,7 @@ if (muxc_scan == 0) return;
for (i = 0; i < MUX_LINES; i++) {
muxc_chan = (muxc_chan + 1) & LIC_M_CHAN; /* step channel */
if (LIC_TSTI (muxc_chan)) { /* status change? */
setFLG (muxc_dib.devno); /* set flag */
setFSR (muxc_dib.devno); /* set flag */
break; } }
return;
}
@@ -639,11 +644,11 @@ if (muxu_dev.flags & DEV_DIS) { /* enb/dis dev */
else { muxl_dev.flags = muxl_dev.flags & ~DEV_DIS;
muxc_dev.flags = muxc_dev.flags & ~DEV_DIS; }
muxl_dib.cmd = muxl_dib.ctl = 0; /* init lower */
muxl_dib.flg = muxl_dib.fbf = 1;
muxl_dib.flg = muxl_dib.fbf = muxl_dib.srq = 1;
muxu_dib.cmd = muxu_dib.ctl = 0; /* upper not */
muxu_dib.flg = muxu_dib.fbf = 0; /* implemented */
muxu_dib.flg = muxu_dib.fbf = muxu_dib.srq = 0; /* implemented */
muxc_dib.cmd = muxc_dib.ctl = 0; /* init ctrl */
muxc_dib.flg = muxc_dib.fbf = 1;
muxc_dib.flg = muxc_dib.fbf = muxc_dib.srq = 1;
muxc_chan = muxc_scan = 0; /* init modem scan */
if (muxu_unit.flags & UNIT_ATT) { /* master att? */
if (!sim_is_active (&muxu_unit)) {

View File

@@ -28,6 +28,11 @@
tty 12531C buffered teleprinter interface
clk 12539C time base generator
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Fixed SR setting in IBL
Fixed input behavior during typeout for RTE-IV
Suppressed nulls on TTY output for RTE-IV
Implemented DMA SRQ (follows FLG)
29-Mar-03 RMS Added support for console backpressure
25-Apr-03 RMS Added extended file support
22-Dec-02 RMS Added break support
@@ -62,12 +67,15 @@
#include "hp2100_defs.h"
#include <ctype.h>
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_V_UC (UNIT_V_UF + 1) /* UC only */
#define UNIT_V_DIAG (UNIT_V_UF + 2) /* diag mode */
#define UNIT_V_AUTOLF (UNIT_V_UF + 3) /* auto linefeed */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_UC (1 << UNIT_V_UC)
#define UNIT_DIAG (1 << UNIT_V_DIAG)
#define UNIT_AUTOLF (1 << UNIT_V_AUTOLF)
#define PTP_LOW 0000040 /* low tape */
#define TM_MODE 0100000 /* mode change */
@@ -81,12 +89,18 @@
extern uint16 *M;
extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2];
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern UNIT cpu_unit;
int32 ptr_stopioe = 0, ptp_stopioe = 0; /* stop on error */
int32 ptr_stopioe = 0; /* stop on error */
int32 ptr_trlcnt = 0; /* trailer counter */
int32 ptr_trllim = 40; /* trailer to add */
int32 ptp_stopioe = 0;
int32 ttp_stopioe = 0;
int32 tty_buf = 0, tty_mode = 0; /* tty buffer, mode */
int32 tty_buf = 0; /* tty buffer */
int32 tty_mode = 0; /* tty mode */
int32 tty_shin = 0377; /* tty shift in */
int32 tty_lf = 0; /* lf flag */
int32 clk_select = 0; /* clock time select */
int32 clk_error = 0; /* clock error */
int32 clk_ctr = 0; /* clock counter */
@@ -100,6 +114,7 @@ int32 clk_rpt[8] = /* number of repeats */
DEVICE ptr_dev, ptp_dev, tty_dev, clk_dev;
int32 ptrio (int32 inst, int32 IR, int32 dat);
t_stat ptr_svc (UNIT *uptr);
t_stat ptr_attach (UNIT *uptr, char *cptr);
t_stat ptr_reset (DEVICE *dptr);
t_stat ptr_boot (int32 unitno, DEVICE *dptr);
int32 ptpio (int32 inst, int32 IR, int32 dat);
@@ -109,11 +124,13 @@ int32 ttyio (int32 inst, int32 IR, int32 dat);
t_stat tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr);
t_stat tty_reset (DEVICE *dptr);
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat tty_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc);
int32 clkio (int32 inst, int32 IR, int32 dat);
t_stat clk_svc (UNIT *uptr);
t_stat clk_reset (DEVICE *dptr);
int32 clk_delay (int32 flg);
t_stat tto_out (int32 c);
t_stat ttp_out (int32 c);
/* PTR data structures
@@ -123,7 +140,7 @@ int32 clk_delay (int32 flg);
ptr_reg PTR register list
*/
DIB ptr_dib = { PTR, 0, 0, 0, 0, &ptrio };
DIB ptr_dib = { PTR, 0, 0, 0, 0, 0, &ptrio };
UNIT ptr_unit = {
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
@@ -135,6 +152,9 @@ REG ptr_reg[] = {
{ FLDATA (CTL, ptr_dib.ctl, 0) },
{ FLDATA (FLG, ptr_dib.flg, 0) },
{ FLDATA (FBF, ptr_dib.fbf, 0) },
{ FLDATA (SRQ, ptr_dib.srq, 0) },
{ DRDATA (TRLCTR, ptr_trlcnt, 8), REG_HRO },
{ DRDATA (TRLLIM, ptr_trllim, 8) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) },
@@ -150,7 +170,7 @@ DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, ptr_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset,
&ptr_boot, NULL, NULL,
&ptr_boot, &ptr_attach, NULL,
&ptr_dib, DEV_DISABLE };
/* PTP data structures
@@ -161,7 +181,7 @@ DEVICE ptr_dev = {
ptp_reg PTP register list
*/
DIB ptp_dib = { PTP, 0, 0, 0, 0, &ptpio };
DIB ptp_dib = { PTP, 0, 0, 0, 0, 0, &ptpio };
UNIT ptp_unit = {
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
@@ -172,6 +192,7 @@ REG ptp_reg[] = {
{ FLDATA (CTL, ptp_dib.ctl, 0) },
{ FLDATA (FLG, ptp_dib.flg, 0) },
{ FLDATA (FBF, ptp_dib.fbf, 0) },
{ FLDATA (SRQ, ptp_dib.srq, 0) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) },
@@ -202,7 +223,7 @@ DEVICE ptp_dev = {
#define TTO 1
#define TTP 2
DIB tty_dib = { TTY, 0, 0, 0, 0, &ttyio };
DIB tty_dib = { TTY, 0, 0, 0, 0, 0, &ttyio };
UNIT tty_unit[] = {
{ UDATA (&tti_svc, UNIT_UC, 0), KBD_POLL_WAIT },
@@ -212,10 +233,13 @@ UNIT tty_unit[] = {
REG tty_reg[] = {
{ ORDATA (BUF, tty_buf, 8) },
{ ORDATA (MODE, tty_mode, 16) },
{ ORDATA (SHIN, tty_shin, 8), REG_HRO },
{ FLDATA (CMD, tty_dib.cmd, 0), REG_HRO },
{ FLDATA (CTL, tty_dib.ctl, 0) },
{ FLDATA (FLG, tty_dib.flg, 0) },
{ FLDATA (FBF, tty_dib.fbf, 0) },
{ FLDATA (SRQ, tty_dib.srq, 0) },
{ FLDATA (KLFP, tty_lf, 0), REG_HRO },
{ DRDATA (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
{ DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT },
@@ -226,9 +250,16 @@ REG tty_reg[] = {
{ NULL } };
MTAB tty_mod[] = {
{ UNIT_UC+UNIT_8B, UNIT_UC, "UC", "UC", &tty_set_mode },
{ UNIT_UC+UNIT_8B, 0 , "7b", "7B", &tty_set_mode },
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", &tty_set_mode },
{ UNIT_UC+UNIT_8B, UNIT_UC, "UC", "UC", &tty_set_opt,
NULL, ((void *) (UNIT_UC + UNIT_8B)) },
{ UNIT_UC+UNIT_8B, 0 , "7b", "7B", &tty_set_opt,
NULL, ((void *) (UNIT_UC + UNIT_8B)) },
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", &tty_set_opt,
NULL, ((void *) (UNIT_UC + UNIT_8B)) },
{ UNIT_AUTOLF, UNIT_AUTOLF, "autolf", "AUTOLF", &tty_set_opt,
NULL, ((void *) UNIT_AUTOLF) },
{ UNIT_AUTOLF, 0 , NULL, "NOAUTOLF", &tty_set_opt,
NULL, ((void *) UNIT_AUTOLF) },
{ MTAB_XTD | MTAB_VDV, 0, "DEVNO", "DEVNO",
&hp_setdev, &hp_showdev, &tty_dev },
{ 0 } };
@@ -248,7 +279,7 @@ DEVICE tty_dev = {
clk_reg CLK register list
*/
DIB clk_dib = { CLK, 0, 0, 0, 0, &clkio };
DIB clk_dib = { CLK, 0, 0, 0, 0, 0, &clkio };
UNIT clk_unit = {
UDATA (&clk_svc, 0, 0) };
@@ -260,6 +291,7 @@ REG clk_reg[] = {
{ FLDATA (CTL, clk_dib.ctl, 0) },
{ FLDATA (FLG, clk_dib.flg, 0) },
{ FLDATA (FBF, clk_dib.fbf, 0) },
{ FLDATA (SRQ, clk_dib.srq, 0) },
{ FLDATA (ERR, clk_error, CLK_V_ERROR) },
{ BRDATA (TIME, clk_time, 10, 24, 8) },
{ ORDATA (DEVNO, clk_dib.devno, 6), REG_HRO },
@@ -288,14 +320,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioMIX: /* merge */
dat = dat | ptr_unit.buf;
break;
@@ -313,7 +345,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
@@ -327,25 +359,40 @@ dev = ptr_dib.devno; /* get device no */
clrCMD (dev); /* clear cmd */
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read byte */
if (feof (ptr_unit.fileref)) {
if (ptr_stopioe) printf ("PTR end of file\n");
else return SCPE_OK; }
else perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
return SCPE_IOERR; }
setFLG (dev); /* set flag */
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read byte, error? */
if (feof (ptr_unit.fileref)) { /* end of file? */
if (ptr_trlcnt >= ptr_trllim) { /* added all trailer? */
if (ptr_stopioe) { /* stop on error? */
printf ("PTR end of file\n");
return SCPE_IOERR; }
else return SCPE_OK; } /* no, just hang */
ptr_trlcnt++; /* count trailer */
temp = 0; } /* read a zero */
else { /* no, real error */
perror ("PTR I/O error");
clearerr (ptr_unit.fileref);
return SCPE_IOERR; }
}
setFSR (dev); /* set flag */
ptr_unit.buf = temp & 0377; /* put byte in buf */
ptr_unit.pos = ftell (ptr_unit.fileref);
return SCPE_OK;
}
/* Attach routine - clear the trailer counter */
t_stat ptr_attach (UNIT *uptr, char *cptr)
{
ptr_trlcnt = 0;
return attach_unit (uptr, cptr);
}
/* Reset routine - called from SCP, flags in DIB's */
t_stat ptr_reset (DEVICE *dptr)
{
ptr_dib.cmd = ptr_dib.ctl = 0; /* clear cmd, ctl */
ptr_dib.flg = ptr_dib.fbf = 1; /* set flg, fbf */
ptr_dib.flg = ptr_dib.fbf = ptr_dib.srq = 1; /* set flg, fbf, srq */
ptr_unit.buf = 0;
sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK;
@@ -353,10 +400,7 @@ return SCPE_OK;
/* Paper tape reader bootstrap routine (HP 12992K ROM) */
#define LDR_BASE 077
#define CHANGE_DEV (1 << 24)
static const int32 pboot[IBL_LNT] = {
const uint16 ptr_rom[IBL_LNT] = {
0107700, /*ST CLC 0,C ; intr off */
0002401, /* CLA,RSS ; skip in */
0063756, /*CN LDA M11 ; feed frame */
@@ -393,10 +437,10 @@ static const int32 pboot[IBL_LNT] = {
0027700, /* JMP ST ; next */
0000000, /*RD 0 */
0006600, /* CLB,CME ; E reg byte ptr */
0103700+CHANGE_DEV, /* STC RDR,C ; start reader */
0102300+CHANGE_DEV, /* SFS RDR ; wait */
0103710, /* STC RDR,C ; start reader */
0102310, /* SFS RDR ; wait */
0027745, /* JMP *-1 */
0106400+CHANGE_DEV, /* MIB RDR ; get byte */
0106410, /* MIB RDR ; get byte */
0002041, /* SEZ,RSS ; E set? */
0127742, /* JMP RD,I ; no, done */
0005767, /* BLF,CLE,BLF ; shift byte */
@@ -410,16 +454,11 @@ static const int32 pboot[IBL_LNT] = {
t_stat ptr_boot (int32 unitno, DEVICE *dptr)
{
int32 i, dev;
int32 dev;
dev = ptr_dib.devno; /* get device no */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
SR = IBL_PTR + (dev << IBL_V_DEV); /* set SR */
for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */
if (pboot[i] & CHANGE_DEV) /* IO instr? */
M[PC + i] = (pboot[i] + dev) & DMASK;
else M[PC + i] = pboot[i]; }
M[PC + LDR_BASE] = (~PC + 1) & DMASK;
if (ibl_copy (ptr_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = (SR & IBL_OPT) | IBL_PTR | (dev << IBL_V_DEV); /* set SR */
return SCPE_OK;
}
@@ -432,14 +471,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioLIX: /* load */
dat = 0;
case ioMIX: /* merge */
@@ -460,7 +499,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
@@ -472,7 +511,7 @@ int32 dev;
dev = ptp_dib.devno; /* get device no */
clrCMD (dev); /* clear cmd */
setFLG (dev); /* set flag */
setFSR (dev); /* set flag */
if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { /* output byte */
@@ -488,7 +527,7 @@ return SCPE_OK;
t_stat ptp_reset (DEVICE *dptr)
{
ptp_dib.cmd = ptp_dib.ctl = 0; /* clear cmd, ctl */
ptp_dib.flg = ptp_dib.fbf = 1; /* set flg, fbf */
ptp_dib.flg = ptp_dib.fbf = ptp_dib.srq = 1; /* set flg, fbf, srq */
ptp_unit.buf = 0;
sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK;
@@ -503,14 +542,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioLIX: /* load */
dat = 0;
case ioMIX: /* merge */
@@ -531,11 +570,79 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
/* Unit service routines */
/* Unit service routines. Note from Dave Bryan:
Referring to the 12531C schematic, the terminal input enters on pin X
("DATA FROM EIA COMPATIBLE DEVICE"). The signal passes through four
transistor inversions (Q8, Q1, Q2, and Q3) to appear on pin 12 of NAND gate
U104C. If the flag flip-flop is not set, the terminal input passes to the
(inverted) output of U104C and thence to the D input of the first of the
flip-flops forming the data register.
In the idle condition (no key pressed), the terminal input line is marking
(voltage negative), so in passing through a total of five inversions, a
logic one is presented at the serial input of the data register. During an
output operation, the register is parallel loaded and serially shifted,
sending the output data through the register to the device and -- this is
the crux -- filling the register with logic ones from U104C.
At the end of the output operation, the card flag is set, an interrupt
occurs, and the RTE driver is entered. The driver then does an LIA SC to
read the contents of the data register. If no key has been pressed during
the output operation, the register will read as all ones (octal 377). If,
however, any key was struck, at least one zero bit will be present. If the
register value doesn't equal 377, the driver sets the system "operator
attention" flag, which will cause RTE to output the asterisk and initiate a
terminal read when the current output line is completed. */
t_stat tti_svc (UNIT *uptr)
{
int32 c, dev;
dev = tty_dib.devno; /* get device no */
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* continue poll */
tty_shin = 0377; /* assume inactive */
if (tty_lf) { /* auto lf pending? */
c = 012; /* force lf */
tty_lf = 0; }
else { if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) c = 0; /* break? */
else if (tty_unit[TTI].flags & UNIT_UC) { /* UC only? */
c = c & 0177;
if (islower (c)) c = toupper (c); }
else c = c & ((tty_unit[TTI].flags & UNIT_8B)? 0377: 0177);
tty_lf = ((c & 0177) == 015) && (uptr->flags & UNIT_AUTOLF);
}
if (tty_mode & TM_KBD) { /* keyboard enabled? */
tty_buf = c; /* put char in buf */
tty_unit[TTI].pos = tty_unit[TTI].pos + 1;
setFSR (dev); /* set flag */
if (c) {
tto_out (c); /* echo? */
return ttp_out (c); } } /* punch? */
else tty_shin = c; /* no, char shifts in */
return SCPE_OK;
}
t_stat tto_svc (UNIT *uptr)
{
int32 c, dev;
t_stat r;
c = tty_buf; /* get char */
tty_buf = tty_shin; /* shift in */
tty_shin = 0377; /* line inactive */
if ((r = tto_out (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
dev = tty_dib.devno; /* get device no */
setFSR (dev); /* set done flag */
return ttp_out (c); /* punch if enabled */
}
t_stat tto_out (int32 c)
{
@@ -546,8 +653,10 @@ if (tty_mode & TM_PRI) { /* printing? */
c = c & 0177;
if (islower (c)) c = toupper (c); }
else c = c & ((tty_unit[TTO].flags & UNIT_8B)? 0377: 0177);
if (r = sim_putchar_s (c)) return r; /* output char */
tty_unit[TTO].pos = tty_unit[TTO].pos + 1; }
if (c || (tty_unit[TTO].flags & UNIT_8B)) { /* !null or 8b? */
if (r = sim_putchar_s (c)) return r; /* output char */
tty_unit[TTO].pos = tty_unit[TTO].pos + 1; }
}
return SCPE_OK;
}
@@ -564,63 +673,29 @@ if (tty_mode & TM_PUN) { /* punching? */
return SCPE_OK;
}
t_stat tti_svc (UNIT *uptr)
{
int32 c, dev;
dev = tty_dib.devno; /* get device no */
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) c = 0; /* break? */
else if (tty_unit[TTI].flags & UNIT_UC) { /* UC only? */
c = c & 0177;
if (islower (c)) c = toupper (c); }
else c = c & ((tty_unit[TTI].flags & UNIT_8B)? 0377: 0177);
if (tty_mode & TM_KBD) { /* keyboard enabled? */
tty_buf = c; /* put char in buf */
tty_unit[TTI].pos = tty_unit[TTI].pos + 1;
setFLG (dev); /* set flag */
if (c) {
tto_out (c); /* echo? */
return ttp_out (c); } } /* punch? */
return SCPE_OK;
}
t_stat tto_svc (UNIT *uptr)
{
int32 c, dev;
t_stat r;
c = tty_buf; /* get char */
tty_buf = 0377; /* defang buf */
if ((r = tto_out (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* retry */
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
dev = tty_dib.devno; /* get device no */
setFLG (dev); /* set done flag */
return ttp_out (c); /* punch if enabled */
}
/* Reset routine */
t_stat tty_reset (DEVICE *dptr)
{
tty_dib.cmd = tty_dib.ctl = 0; /* clear cmd, ctl */
tty_dib.flg = tty_dib.fbf = 1; /* set flg, fbf */
tty_dib.flg = tty_dib.fbf = tty_dib.srq = 1; /* set flg, fbf, srq */
tty_mode = TM_KBD; /* enable input */
tty_buf = 0;
tty_shin = 0377; /* input inactive */
tty_lf = 0; /* no lf pending */
sim_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate poll */
sim_cancel (&tty_unit[TTO]); /* cancel output */
return SCPE_OK;
}
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc)
t_stat tty_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 u = uptr - tty_dev.units;
int32 mask = (int32) desc;
if (u > 1) return SCPE_NOFNC;
tty_unit[TTI].flags = (tty_unit[TTI].flags & ~(UNIT_UC | UNIT_8B)) | val;
tty_unit[TTO].flags = (tty_unit[TTO].flags & ~(UNIT_UC | UNIT_8B)) | val;
tty_unit[TTI].flags = (tty_unit[TTI].flags & ~mask) | val;
tty_unit[TTO].flags = (tty_unit[TTO].flags & ~mask) | val;
return SCPE_OK;
}
@@ -633,14 +708,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */
if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break;
case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat;
break;
case ioMIX: /* merge */
dat = dat | clk_error;
break;
@@ -666,7 +741,7 @@ case ioCTL: /* control clear/set */
break;
default:
break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */
if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat;
}
@@ -686,7 +761,7 @@ clk_ctr = clk_ctr - 1; /* decrement counter */
if (clk_ctr <= 0) { /* end of interval? */
tim = FLG (dev);
if (FLG (dev)) clk_error = CLK_ERROR; /* overrun? error */
else { setFLG (dev); } /* else set flag */
else { setFSR (dev); } /* else set flag */
clk_ctr = clk_delay (1); } /* reset counter */
return SCPE_OK;
}
@@ -696,7 +771,7 @@ return SCPE_OK;
t_stat clk_reset (DEVICE *dptr)
{
clk_dib.cmd = clk_dib.ctl = 0; /* clear cmd, ctl */
clk_dib.flg = clk_dib.fbf = 1; /* set flg, fbf */
clk_dib.flg = clk_dib.fbf = clk_dib.srq = 1; /* set flg, fbf, srq */
clk_error = 0; /* clear error */
clk_select = 0; /* clear select */
clk_ctr = 0; /* clear counter */

View File

@@ -23,6 +23,8 @@
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.
01-Jun-04 RMS Added latent 13037 support
19-Apr-04 RMS Recognize SFS x,C and SFC x,C
22-Mar-02 RMS Revised for dynamically allocated memory
14-Feb-02 RMS Added DMS instructions
04-Feb-02 RMS Fixed bugs in alter/skip display and parsing
@@ -50,6 +52,7 @@ extern DEVICE msd_dev, msc_dev;
extern DEVICE dpd_dev, dpc_dev;
extern DEVICE dqd_dev, dqc_dev;
extern DEVICE drd_dev, drc_dev;
extern DEVICE ds_dev;
extern DEVICE muxl_dev, muxu_dev, muxc_dev;
extern DEVICE ipli_dev, iplo_dev;
extern REG cpu_reg[];
@@ -67,6 +70,8 @@ extern uint16 *M;
char sim_name[] = "HP 2100";
char halt_msg[] = "HALT instruction xxxxxx";
REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 3;
@@ -84,6 +89,7 @@ DEVICE *sim_devices[] = {
&dpd_dev, &dpc_dev,
&dqd_dev, &dqc_dev,
&drd_dev, &drc_dev,
&ds_dev,
&mtd_dev, &mtc_dev,
&msd_dev, &msc_dev,
&muxl_dev, &muxu_dev, &muxc_dev,
@@ -94,7 +100,7 @@ const char *sim_stop_messages[] = {
"Unknown error",
"Unimplemented instruction",
"Non-existent I/O device",
"HALT instruction",
halt_msg,
"Breakpoint",
"Indirect address loop",
"Indirect address interrupt (should not happen!)",
@@ -231,7 +237,7 @@ static const int32 opc_val[] = {
0105100+I_NPN, 0105120+I_NPN,
0102101+I_NPN, 0103101+I_NPN, 0102201+I_NPC, 0102301+I_NPC,
0102000+I_IO1, 0102100+I_IO2, 0103100+I_IO2,
0102200+I_IO2, 0102300+I_IO2, 0102400+I_IO1, 0106400+I_IO1,
0102200+I_IO1, 0102300+I_IO1, 0102400+I_IO1, 0106400+I_IO1,
0102500+I_IO1, 0106500+I_IO1, 0102600+I_IO1, 0106600+I_IO1,
0102700+I_IO1, 0106700+I_IO1,
0101710+I_NPN, 0101711+I_NPN, 0101712+I_NPN, 0101713+I_NPN,