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:
committed by
Mark Pizzolato
parent
26aa6de663
commit
e2ba672610
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
1398
HP2100/hp2100_ds.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user