Notes For V3.2-1

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

1. New Features in 3.2-1

1.1 SCP and libraries

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

1.2 HP2100 (new features from Dave Bryan)

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

1.3 PDP-11 and VAX

- Added DHQ11 support (from John Dundas)

2. Bugs Fixed in 3.2-1

2.1 HP2100 (most fixes from Dave Bryan)

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

2.2 All DEC console devices

- Removed SET TTI CTRL-C option.

2.3 PDP-11/VAX peripherals

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

2.4 VAX

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

View file

@ -1,103 +1,64 @@
Notes For V3.2-0 Notes For V3.2-1
RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT
enable this feature for normal operations. enable this feature for normal operations.
WARNING: The core simulator files (scp.c, sim_*.c) have been 1. New Features in 3.2-1
reorganized. Unzip V3.2-0 to an empty directory before attempting
to compile the source.
IMPORTANT: If you are compiling for UNIX, please read the notes
for Ethernet very carefully. You may need to download a new
version of the pcap library, or make changes to the makefile,
to get Ethernet support to work.
1. New Features in 3.2-0
1.1 SCP and libraries 1.1 SCP and libraries
- Added SHOW <device> RADIX command. - Added SET CONSOLE subhierarchy.
- Added SHOW <device> MODIFIERS command. - Added SHOW CONSOLE subhierarchy.
- Added SHOW <device> NAMES command. - Added limited keyboard mapping capability.
- Added SET/SHOW <device> DEBUG command.
- Added sim_vm_parse_addr and sim_vm_fprint_addr optional interfaces.
- Added REG_VMAD flag.
- Split SCP into separate libraries for easier modification.
- Added more room to the device and unit flag fields.
- Changed terminal multiplexor library to support unlimited.
number of async lines.
1.2 All DECtapes 1.2 HP2100 (new features from Dave Bryan)
- Added STOP_EOR flag to enable end-of-reel error stop - Added instruction printout to HALT message.
- Added device debug support. - Added M and T internal registers.
- Added N, S, and U breakpoints.
1.3 Nova and Eclipse 1.3 PDP-11 and VAX
- Added QTY and ALM multiplexors (Bruce Ray). - Added DHQ11 support (from John Dundas)
1.4 LGP-30 2. Bugs Fixed in 3.2-1
- Added LGP-30/LGP-21 simulator. 2.1 HP2100 (most fixes from Dave Bryan)
1.5 PDP-11 - 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.
- Added format, address increment inhibit, transfer overrun 2.2 All DEC console devices
detection to RK.
- Added device debug support to HK, RP, TM, TQ, TS.
- Added DEUNA/DELUA (XU) support (Dave Hittner).
- Add DZ per-line logging.
1.6 18b PDP's - Removed SET TTI CTRL-C option.
- Added support for 1-4 (PDP-9)/1-16 (PDP-15) additional 2.3 PDP-11/VAX peripherals
terminals.
1.7 PDP-10 - 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).
- Added DEUNA/DELUA (XU) support (Dave Hittner). 2.4 VAX
1.8 VAX
- Added extended memory to 512MB (Mark Pizzolato).
- Added RXV21 support.
2. Bugs Fixed in 3.2-0
2.1 SCP
- Fixed double logging of SHOW BREAK (found by Mark Pizzolato).
- Fixed implementation of REG_VMIO.
2.2 Nova and Eclipse
- Fixed device enable/disable support (found by Bruce Ray).
2.3 PDP-1
- Fixed bug in LOAD (found by Mark Crispin).
2.4 PDP-10
- Fixed bug in floating point unpack.
- Fixed bug in FIXR (found by Phil Stone, fixed by Chris Smith).
2.6 PDP-11
- Fixed bug in RQ interrupt control (found by Tom Evans).
2.6 PDP-18B
- Fixed bug in PDP-15 XVM g_mode implementation.
- Fixed bug in PDP-15 indexed address calculation.
- Fixed bug in PDP-15 autoindexed address calculation.
- Fixed bugs in FPP-15 instruction decode.
- Fixed clock response to CAF.
- Fixed bug in hardware read-in mode bootstrap.
- Fixed PDP-15 XVM instruction decoding errors.
2.7 VAX
- Fixed PC read fault in EXTxV.
- Fixed PC write fault in INSV.
- Fixed bug in DIVBx and DIVWx (reported by Peter Trimmel).

View file

@ -23,6 +23,23 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from 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 12-Mar-03 RMS Added logical name support
02-Feb-03 RMS Fixed last cycle bug in DMA output (found by Mike Gemeny) 02-Feb-03 RMS Fixed last cycle bug in DMA output (found by Mike Gemeny)
22-Nov-02 RMS Added 21MX IOP support 22-Nov-02 RMS Added 21MX IOP support
@ -55,6 +72,8 @@
BR<15:0> B register - addressable as location 1 BR<15:0> B register - addressable as location 1
PC<14:0> P register (program counter) PC<14:0> P register (program counter)
SR<15:0> S register SR<15:0> S register
MR<14:0> M register - memory address
TR<15:0> T register - memory data
E extend flag (carry out) E extend flag (carry out)
O overflow flag O overflow flag
@ -232,12 +251,13 @@
unknown I/O device and stop_dev flag set unknown I/O device and stop_dev flag set
I/O error in I/O simulator 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 commands as bit array dev_cmd[2][31..0]
device flags as bit array dev_flg[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 flag buffers as bit array dev_fbf[2][31..0]
device controls as bit array dev_ctl[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,. The HP 2100 interrupt structure is based on flag, flag buffer,.
and control. If a device flag is set, the flag buffer is set, and control. If a device flag is set, the flag buffer is set,
@ -252,6 +272,8 @@
by CLC; it is also cleared when the device flag is set. Simple by CLC; it is also cleared when the device flag is set. Simple
devices don't need to track command separately from control. 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 3. Non-existent memory. On the HP 2100, reads to non-existent memory
return zero, and writes are ignored. In the simulator, the return zero, and writes are ignored. In the simulator, the
largest possible memory is instantiated and initialized to zero. largest possible memory is instantiated and initialized to zero.
@ -308,11 +330,15 @@
#define DMAR0 1 #define DMAR0 1
#define DMAR1 2 #define DMAR1 2
#define ALL_BKPTS (SWMASK('E')|SWMASK('N')|SWMASK('S')|SWMASK('U'))
uint16 *M = NULL; /* memory */ uint16 *M = NULL; /* memory */
uint32 saved_AR = 0; /* A register */ uint32 saved_AR = 0; /* A register */
uint32 saved_BR = 0; /* B register */ uint32 saved_BR = 0; /* B register */
uint32 PC = 0; /* P register */ uint32 PC = 0; /* P register */
uint32 SR = 0; /* S register */ uint32 SR = 0; /* S register */
uint32 MR = 0; /* M register */
uint32 TR = 0; /* T register */
uint32 XR = 0; /* X register */ uint32 XR = 0; /* X register */
uint32 YR = 0; /* Y register */ uint32 YR = 0; /* Y register */
uint32 E = 0; /* E 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_ctl[2] = { 0 }; /* device control */
uint32 dev_flg[2] = { 0 }; /* device flags */ uint32 dev_flg[2] = { 0 }; /* device flags */
uint32 dev_fbf[2] = { 0 }; /* device flag bufs */ uint32 dev_fbf[2] = { 0 }; /* device flag bufs */
uint32 dev_srq[2] = { 0 }; /* device svc reqs */
struct DMA dmac[2] = { { 0 }, { 0 } }; /* DMA channels */ struct DMA dmac[2] = { { 0 }, { 0 } }; /* DMA channels */
uint32 ion = 0; /* interrupt enable */ uint32 ion = 0; /* interrupt enable */
uint32 ion_defer = 0; /* interrupt defer */ 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_ump = 0; /* dms user map */
uint32 dms_sr = 0; /* dms status reg */ uint32 dms_sr = 0; /* dms status reg */
uint32 dms_vr = 0; /* dms violation 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 iop_sp = 0; /* iop stack */
uint32 ind_max = 16; /* iadr nest limit */ uint32 ind_max = 16; /* iadr nest limit */
uint32 stop_inst = 1; /* stop on ill inst */ 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 int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */
extern FILE *sim_log; extern FILE *sim_log;
extern DEVICE *sim_devices[]; extern DEVICE *sim_devices[];
extern char halt_msg[];
t_stat Ea (uint32 IR, uint32 *addr, uint32 irq); t_stat Ea (uint32 IR, uint32 *addr, uint32 irq);
t_stat Ea1 (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_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_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_reset (DEVICE *dptr); t_stat cpu_reset (DEVICE *dptr);
t_stat cpu_boot (int32 unitno, DEVICE *dptr);
t_stat dma0_reset (DEVICE *dptr); t_stat dma0_reset (DEVICE *dptr);
t_stat dma1_reset (DEVICE *dptr); t_stat dma1_reset (DEVICE *dptr);
t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); 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 (P, PC, 15) },
{ ORDATA (A, saved_AR, 16) }, { ORDATA (A, saved_AR, 16) },
{ ORDATA (B, saved_BR, 16) }, { ORDATA (B, saved_BR, 16) },
{ ORDATA (M, MR, 15) },
{ ORDATA (T, TR, 16), REG_RO },
{ ORDATA (X, XR, 16) }, { ORDATA (X, XR, 16) },
{ ORDATA (Y, YR, 16) }, { ORDATA (Y, YR, 16) },
{ ORDATA (S, SR, 16) }, { ORDATA (S, SR, 16) },
{ ORDATA (F, mp_fence, 15) },
{ FLDATA (E, E, 0) }, { FLDATA (E, E, 0) },
{ FLDATA (O, O, 0) }, { FLDATA (O, O, 0) },
{ FLDATA (ION, ion, 0) }, { FLDATA (ION, ion, 0) },
{ FLDATA (ION_DEFER, ion_defer, 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 (MPCTL, dev_ctl[PRO/32], INT_V (PRO)) },
{ FLDATA (MPFLG, dev_flg[PRO/32], INT_V (PRO)) }, { FLDATA (MPFLG, dev_flg[PRO/32], INT_V (PRO)) },
{ FLDATA (MPFBF, dev_fbf[PRO/32], INT_V (PRO)) }, { FLDATA (MPFBF, dev_fbf[PRO/32], INT_V (PRO)) },
{ ORDATA (MPFR, mp_fence, 15) },
{ ORDATA (MPVR, mp_viol, 16) }, { ORDATA (MPVR, mp_viol, 16) },
{ FLDATA (MPMEV, mp_mevff, 0) }, { FLDATA (MPMEV, mp_mevff, 0) },
{ FLDATA (MPEVR, mp_evrff, 0) }, { FLDATA (MPEVR, mp_evrff, 0) },
@ -436,7 +467,7 @@ REG cpu_reg[] = {
{ FLDATA (DMSCUR, dms_ump, VA_N_PAG) }, { FLDATA (DMSCUR, dms_ump, VA_N_PAG) },
{ ORDATA (DMSSR, dms_sr, 16) }, { ORDATA (DMSSR, dms_sr, 16) },
{ ORDATA (DMSVR, dms_vr, 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) }, { ORDATA (IOPSP, iop_sp, 16) },
{ FLDATA (STOP_INST, stop_inst, 0) }, { FLDATA (STOP_INST, stop_inst, 0) },
{ FLDATA (STOP_DEV, stop_dev, 1) }, { FLDATA (STOP_DEV, stop_dev, 1) },
@ -452,6 +483,8 @@ REG cpu_reg[] = {
{ ORDATA (LFLG, dev_flg[1], 32), REG_HRO }, { ORDATA (LFLG, dev_flg[1], 32), REG_HRO },
{ ORDATA (HFBF, dev_fbf[0], 32), REG_HRO }, { ORDATA (HFBF, dev_fbf[0], 32), REG_HRO },
{ ORDATA (LFBF, dev_fbf[1], 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 } }; { NULL } };
MTAB cpu_mod[] = { MTAB cpu_mod[] = {
@ -499,9 +532,9 @@ MTAB cpu_mod[] = {
DEVICE cpu_dev = { DEVICE cpu_dev = {
"CPU", &cpu_unit, cpu_reg, cpu_mod, "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, &cpu_ex, &cpu_dep, &cpu_reset,
NULL, NULL, NULL }; &cpu_boot, NULL, NULL };
/* DMA controller data structures /* DMA controller data structures
@ -663,6 +696,7 @@ int32 (*dtab[64])() = {
t_stat sim_instr (void) t_stat sim_instr (void)
{ {
uint32 intrq, dmarq; /* set after setjmp */ uint32 intrq, dmarq; /* set after setjmp */
uint32 iotrap = 0; /* set after setjmp */
t_stat reason; /* set after setjmp */ t_stat reason; /* set after setjmp */
int32 i, dev; /* temp */ int32 i, dev; /* temp */
DEVICE *dptr; /* 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_ctl[0] = dev_ctl[0] & M_FXDEV;
dev_flg[0] = dev_flg[0] & M_FXDEV; dev_flg[0] = dev_flg[0] & M_FXDEV;
dev_fbf[0] = dev_fbf[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; dev_cmd[1] = dev_ctl[1] = dev_flg[1] = dev_fbf[1] = 0;
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */ 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 */ if (dibp->flg) { setFLG (dev); } /* restore flg */
clrFBF (dev); /* also sets fbf */ clrFBF (dev); /* also sets fbf */
if (dibp->fbf) { setFBF (dev); } /* restore fbf */ if (dibp->fbf) { setFBF (dev); } /* restore fbf */
if (dibp->srq) { setSRQ (dev); } /* restore srq */
dtab[dev] = dibp->iot; } } /* set I/O dispatch */ dtab[dev] = dibp->iot; } } /* set I/O dispatch */
sim_rtc_init (clk_delay (0)); /* recalibrate clock */ 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 IR, MA, M1, absel, v1, v2, t;
uint32 fop, eop, etype, eflag; uint32 fop, eop, etype, eflag;
uint32 skip, mapi, mapj, qs, rs; uint32 skip, mapi, mapj, qs, rs;
uint32 awc, sc, wc, hp, tp, iotrap; uint32 awc, sc, wc, hp, tp;
int32 sop1, sop2; int32 sop1, sop2;
if (sim_interval <= 0) { /* check clock queue */ if (sim_interval <= 0) { /* check clock queue */
@ -733,9 +769,21 @@ if (dmarq) {
dmarq = calc_dma (); /* recalc DMA reqs */ dmarq = calc_dma (); /* recalc DMA reqs */
intrq = calc_int (); } /* recalc interrupts */ 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? */ if (intrq && ((intrq <= PRO) || !ion_defer)) { /* interrupt request? */
iotrap = 1; /* I/O trap cell instr */ iotrap = 1; /* I/O trap cell instr */
clrFBF (intrq); /* clear flag buffer */ clrFBF (intrq); /* clear flag buffer */
if (intrq == PRO) clrFLG (PRO); /* MP flag follows flag buffer */
intaddr = intrq; /* save int addr */ intaddr = intrq; /* save int addr */
if (dms_enb) dms_sr = dms_sr | MST_ENBI; /* dms enabled? */ if (dms_enb) dms_sr = dms_sr | MST_ENBI; /* dms enabled? */
else dms_sr = dms_sr & ~MST_ENBI; else dms_sr = dms_sr & ~MST_ENBI;
@ -752,8 +800,12 @@ if (intrq && ((intrq <= PRO) || !ion_defer)) { /* interrupt request? */
else { iotrap = 0; /* normal instruction */ else { iotrap = 0; /* normal instruction */
err_PC = PC; /* save PC for error */ err_PC = PC; /* save PC for error */
if (sim_brk_summ && if (sim_brk_summ && /* any breakpoints? */
sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */ 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 */ reason = STOP_IBKPT; /* stop simulation */
break; } break; }
if (mp_evrff) mp_viol = PC; /* if ok, upd mp_viol */ if (mp_evrff) mp_viol = PC; /* if ok, upd mp_viol */
@ -1200,19 +1252,23 @@ case 0203:case 0213: /* MAC1 ext */
break; break;
case 0221: /* IOP PRFIO (I_NO) */ case 0221: /* IOP PRFIO (I_NO) */
case 0473: /* IOPX PFRIO (I_NO) */ case 0473: /* IOPX PFRIO (I_NO) */
IR = ReadW (PC); /* get IO instr */ t = ReadW (PC); /* get IO instr */
PC = (PC + 1) & VAMASK; PC = (PC + 1) & VAMASK;
WriteW (PC, 1); /* set flag */ WriteW (PC, 1); /* set flag */
PC = (PC + 1) & VAMASK; 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; break;
case 0222: /* IOP PRFEI (I_NO) */ case 0222: /* IOP PRFEI (I_NO) */
case 0471: /* IOPX PFREI (I_NO) */ case 0471: /* IOPX PFREI (I_NO) */
IR = ReadW (PC); /* get IO instr */ t = ReadW (PC); /* get IO instr */
PC = (PC + 1) & VAMASK; PC = (PC + 1) & VAMASK;
WriteW (PC, 1); /* set flag */ WriteW (PC, 1); /* set flag */
PC = (PC + 1) & VAMASK; 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 */ /* fall through */
case 0223: /* IOP PRFEX (I_NO) */ case 0223: /* IOP PRFEX (I_NO) */
case 0472: /* IOPX PFREX (I_NO) */ case 0472: /* IOPX PFREX (I_NO) */
@ -1655,6 +1711,7 @@ case 0203:case 0213: /* MAC1 ext */
break; break;
case 0764: /* SBT (E_NO) */ case 0764: /* SBT (E_NO) */
WriteB (BR, AR); /* store byte */ WriteB (BR, AR); /* store byte */
BR = (BR + 1) & DMASK; /* incr ptr */
break; break;
IOP_MBYTE: /* IOP MBYTE (I_AZ) */ IOP_MBYTE: /* IOP MBYTE (I_AZ) */
if (wc & SIGN) break; /* must be positive */ if (wc & SIGN) break; /* must be positive */
@ -1763,8 +1820,12 @@ if (reason == STOP_INDINT) { /* indirect intr? */
/* Simulation halted */ /* 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_AR = AR & DMASK;
saved_BR = BR & DMASK; saved_BR = BR & DMASK;
dms_upd_sr (); /* update dms_sr */
for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */ dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp) { /* exist? */ if (dibp) { /* exist? */
@ -1772,7 +1833,8 @@ for (i = 0; dptr = sim_devices[i]; i++) { /* loop thru dev */
dibp->cmd = CMD (dev); dibp->cmd = CMD (dev);
dibp->ctl = CTL (dev); dibp->ctl = CTL (dev);
dibp->flg = FLG (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 */ pcq_r->qptr = pcq_p; /* update pc q ptr */
return reason; return reason;
} }
@ -1865,7 +1927,10 @@ iodata = devdisp (dev, sop, ir, ABREG[ab]); /* process I/O */
ion_defer = defer_tab[sop]; /* set defer */ ion_defer = defer_tab[sop]; /* set defer */
if ((sop == ioMIX) || (sop == ioLIX)) /* store ret data */ if ((sop == ioMIX) || (sop == ioLIX)) /* store ret data */
ABREG[ab] = iodata & DMASK; 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 */ return (iodata >> IOT_V_REASON); /* return status */
} }
@ -1883,9 +1948,9 @@ uint32 calc_dma (void)
{ {
uint32 r = 0; 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; 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; r = r | DMAR1;
return r; return r;
} }
@ -1994,7 +2059,14 @@ else pa = va;
return M[pa]; 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)) #define MP_TEST(x) (CTL (PRO) && ((x) > 1) && ((x) < mp_fence))
@ -2003,8 +2075,8 @@ void WriteB (uint32 va, uint32 dat)
uint32 pa; uint32 pa;
if (dms_enb) pa = dms (va >> 1, dms_ump, WR); if (dms_enb) pa = dms (va >> 1, dms_ump, WR);
else { if (MP_TEST (va >> 1)) ABORT (ABORT_PRO); else pa = va >> 1;
pa = va >> 1; } if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) { if (MEM_ADDR_OK (pa)) {
if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377); if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377);
else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); } else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); }
@ -2018,8 +2090,8 @@ uint32 pa;
if (dms_enb) { if (dms_enb) {
dms_viol (va >> 1, MVI_WPR); /* viol if prot */ dms_viol (va >> 1, MVI_WPR); /* viol if prot */
pa = dms (va >> 1, dms_ump ^ MAP_LNT, WR); } pa = dms (va >> 1, dms_ump ^ MAP_LNT, WR); }
else { if (MP_TEST (va >> 1)) ABORT (ABORT_PRO); else pa = va >> 1;
pa = va >> 1; } if (MP_TEST (va >> 1)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) { if (MEM_ADDR_OK (pa)) {
if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377); if (va & 1) M[pa] = (M[pa] & 0177400) | (dat & 0377);
else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); } else M[pa] = (M[pa] & 0377) | ((dat & 0377) << 8); }
@ -2031,8 +2103,8 @@ void WriteW (uint32 va, uint32 dat)
uint32 pa; uint32 pa;
if (dms_enb) pa = dms (va, dms_ump, WR); if (dms_enb) pa = dms (va, dms_ump, WR);
else { if (MP_TEST (va)) ABORT (ABORT_PRO); else pa = va;
pa = va; } if (MP_TEST (va)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) M[pa] = dat; if (MEM_ADDR_OK (pa)) M[pa] = dat;
return; return;
} }
@ -2044,8 +2116,8 @@ int32 pa;
if (dms_enb) { if (dms_enb) {
dms_viol (va, MVI_WPR); /* viol if prot */ dms_viol (va, MVI_WPR); /* viol if prot */
pa = dms (va, dms_ump ^ MAP_LNT, WR); } pa = dms (va, dms_ump ^ MAP_LNT, WR); }
else { if (MP_TEST (va)) ABORT (ABORT_PRO); else pa = va;
pa = va; } if (MP_TEST (va)) ABORT (ABORT_PRO);
if (MEM_ADDR_OK (pa)) M[pa] = dat; if (MEM_ADDR_OK (pa)) M[pa] = dat;
return; return;
} }
@ -2076,8 +2148,8 @@ if (pgn == 0) { /* base page? */
if (prot == WR) dms_viol (va, MVI_BPG); /* if W, viol */ if (prot == WR) dms_viol (va, MVI_BPG); /* if W, viol */
return va; } } /* no mapping */ return va; } } /* no mapping */
mpr = dms_map[map + pgn]; /* get map reg */ mpr = dms_map[map + pgn]; /* get map reg */
if (mpr & prot) dms_viol (va, prot << (MVI_V_WPR - MAPA_V_WPR)); if (mpr & prot) dms_viol (va, prot); /* prot violation? */
return (PA_GETPAG (mpr) | VA_GETOFF (va)); return (MAP_GETPAG (mpr) | VA_GETOFF (va));
} }
/* DMS relocation for IO access */ /* DMS relocation for IO access */
@ -2095,19 +2167,24 @@ if (pgn == 0) { /* base page? */
(va < dms_fence)) { /* 0B10: < fence */ (va < dms_fence)) { /* 0B10: < fence */
return va; } } /* no mapping */ return va; } } /* no mapping */
mpr = dms_map[map + pgn]; /* get map reg */ 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 */ /* DMS relocation for console access */
uint32 dms_cons (uint32 va, int32 sw) uint32 dms_cons (uint32 va, int32 sw)
{ {
if (sw & SWMASK ("V")) return dms_io (va, dms_ump); uint32 map_sel;
if (sw & SWMASK ("S")) return dms_io (va, SMAP);
if (sw & SWMASK ("U")) return dms_io (va, UMAP); if (sw & SWMASK ('V')) map_sel = dms_ump; /* switch? select map */
if (sw & SWMASK ("P")) return dms_io (va, PAMAP); else if (sw & SWMASK ('S')) map_sel = SMAP;
if (sw & SWMASK ("Q")) return dms_io (va, PBMAP); else if (sw & SWMASK ('U')) map_sel = UMAP;
return va; 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 */ /* Mem protect and DMS validation for jumps */
@ -2131,19 +2208,14 @@ return;
uint16 dms_rmap (uint32 mapi) uint16 dms_rmap (uint32 mapi)
{ {
int32 t;
mapi = mapi & MAP_MASK; mapi = mapi & MAP_MASK;
t = (((dms_map[mapi] >> VA_N_OFF) & PA_M_PAG) | return (dms_map[mapi] & ~MAP_MBZ);
((dms_map[mapi] & (RD | WR)) << (MAPM_V_WPR - MAPA_V_WPR)));
return (uint16) t;
} }
void dms_wmap (uint32 mapi, uint32 dat) void dms_wmap (uint32 mapi, uint32 dat)
{ {
mapi = mapi & MAP_MASK; mapi = mapi & MAP_MASK;
dms_map[mapi] = ((dat & PA_M_PAG) << VA_N_OFF) | dms_map[mapi] = (uint16) (dat & ~MAP_MBZ);
((dat >> (MAPM_V_WPR - MAPA_V_WPR)) & (RD | WR));
return; return;
} }
@ -2172,7 +2244,24 @@ if (CTL (PRO)) dms_sr = dms_sr | MST_PRO;
return dms_sr; 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) int32 cpuio (int32 inst, int32 IR, int32 dat)
{ {
@ -2184,10 +2273,10 @@ case ioFLG: /* flag */
return dat; return dat;
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (!ion) PC = (PC + 1) & VAMASK; if (!ion) PC = (PC + 1) & VAMASK;
return dat; break;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (ion) PC = (PC + 1) & VAMASK; if (ion) PC = (PC + 1) & VAMASK;
return dat; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = 0; /* returns 0 */ dat = 0; /* returns 0 */
break; break;
@ -2249,7 +2338,11 @@ default:
return dat; 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) 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 */ return nulio (inst, IR, dat); /* non-existent dev */
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (FLG (PRO) && !mp_mevff) /* skip if mem prot */ if (!mp_mevff) PC = (PC + 1) & VAMASK; /* skip if mem prot */
PC = (PC + 1) & VAMASK; break;
return dat;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (FLG (PRO) && mp_mevff) /* skip if DMS */ if (mp_mevff) PC = (PC + 1) & VAMASK; /* skip if DMS */
PC = (PC + 1) & VAMASK; break;
return dat;
case ioMIX: /* merge */ case ioMIX: /* merge */
dat = dat | mp_viol; dat = dat | mp_viol;
break; break;
@ -2329,10 +2420,10 @@ case ioFLG: /* flag */
break; break;
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (FLG (DMA0 + ch) == 0) PC = (PC + 1) & VAMASK; if (FLG (DMA0 + ch) == 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (FLG (DMA0 + ch) != 0) PC = (PC + 1) & VAMASK; if (FLG (DMA0 + ch) != 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioMIX: case ioLIX: /* load, merge */ case ioMIX: case ioLIX: /* load, merge */
dat = DMASK; dat = DMASK;
break; break;
@ -2358,9 +2449,10 @@ return dat;
- CLC requested: issue CLC - CLC requested: issue CLC
Output cases: Output cases:
- neither STC nor CLC requested: issue CLF - neither STC nor CLC requested: issue CLF
- CLC requested but not STC: issue CLC,C
- STC requested but not CLC: issue STC,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) 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].cw3) { /* more to do? */
if (dmac[ch].cw1 & DMA1_STC) /* if STC flag, */ if (dmac[ch].cw1 & DMA1_STC) /* if STC flag, */
devdisp (dev, ioCTL, I_HC + dev, 0); /* do STC,C dev */ 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? */ else { if (inp) { /* last cycle, input? */
if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */ if (dmac[ch].cw1 & DMA1_CLC) /* CLC at end? */
devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */ devdisp (dev, ioCTL, I_CTL + dev, 0); /* yes */
} /* end input */ } /* end input */
else { /* output */ 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, */ 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? */ 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 */ } /* end output */
setFLG (DMA0 + ch); /* set DMA flg */ 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; return;
} }
@ -2428,6 +2524,7 @@ clrCMD (PRO);
clrCTL (PRO); clrCTL (PRO);
clrFLG (PRO); clrFLG (PRO);
clrFBF (PRO); clrFBF (PRO);
dev_srq[0] = dev_srq[0] & ~M_FXDEV;
mp_fence = 0; /* init mprot */ mp_fence = 0; /* init mprot */
mp_viol = 0; mp_viol = 0;
mp_mevff = 0; mp_mevff = 0;
@ -2436,7 +2533,8 @@ dms_enb = dms_ump = 0; /* init DMS */
dms_sr = 0; dms_sr = 0;
dms_vr = 0; dms_vr = 0;
pcq_r = find_reg ("PCQ", NULL, dptr); 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) M = calloc (PASIZE, sizeof (unsigned int16));
if (M == NULL) return SCPE_MEM; if (M == NULL) return SCPE_MEM;
if (pcq_r) pcq_r->qptr = 0; if (pcq_r) pcq_r->qptr = 0;
@ -2449,6 +2547,7 @@ t_stat dma0_reset (DEVICE *tptr)
clrCMD (DMA0); clrCMD (DMA0);
clrCTL (DMA0); clrCTL (DMA0);
setFLG (DMA0); setFLG (DMA0);
clrSRQ (DMA0);
dmac[0].cw1 = dmac[0].cw2 = dmac[0].cw3 = 0; dmac[0].cw1 = dmac[0].cw2 = dmac[0].cw3 = 0;
return SCPE_OK; return SCPE_OK;
} }
@ -2458,6 +2557,7 @@ t_stat dma1_reset (DEVICE *tptr)
clrCMD (DMA1); clrCMD (DMA1);
clrCTL (DMA1); clrCTL (DMA1);
setFLG (DMA1); setFLG (DMA1);
clrSRQ (DMA1);
dmac[1].cw1 = dmac[1].cw2 = dmac[1].cw3 = 0; dmac[1].cw1 = dmac[1].cw2 = dmac[1].cw3 = 0;
return SCPE_OK; return SCPE_OK;
} }
@ -2468,8 +2568,8 @@ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
{ {
int32 d; int32 d;
if (addr >= MEMSIZE) return SCPE_NXM;
addr = dms_cons (addr, sw); addr = dms_cons (addr, sw);
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr == 0) d = saved_AR; if (addr == 0) d = saved_AR;
else if (addr == 1) d = saved_BR; else if (addr == 1) d = saved_BR;
else d = M[addr]; 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) 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); addr = dms_cons (addr, sw);
if (addr >= MEMSIZE) return SCPE_NXM;
if (addr == 0) saved_AR = val & DMASK; if (addr == 0) saved_AR = val & DMASK;
else if (addr == 1) saved_BR = val & DMASK; else if (addr == 1) saved_BR = val & DMASK;
else M[addr] = val & DMASK; else M[addr] = val & DMASK;
@ -2558,7 +2658,7 @@ t_bool dev_conflict (void)
{ {
DEVICE *dptr, *cdptr; DEVICE *dptr, *cdptr;
DIB *dibp, *chkp; DIB *dibp, *chkp;
int32 i, j, dno; uint32 i, j, dno;
for (i = 0; cdptr = sim_devices[i]; i++) { for (i = 0; cdptr = sim_devices[i]; i++) {
chkp = (DIB *) cdptr->ctxt; chkp = (DIB *) cdptr->ctxt;
@ -2599,4 +2699,59 @@ for (i = 0; opt_val[i].optf != 0; i++) {
return SCPE_OK; } } return SCPE_OK; } }
return SCPE_NOFNC; return SCPE_NOFNC;
} }
/* IBL routine (CPU boot) */
t_stat cpu_boot (int32 unitno, DEVICE *dptr)
{
extern const uint16 ptr_rom[IBL_LNT], dq_rom[IBL_LNT], ms_rom[IBL_LNT];
int32 dev = (SR >> IBL_V_DEV) & I_DEVMASK;
int32 sel = (SR >> IBL_V_SEL) & IBL_M_SEL;
if (dev < 010) return SCPE_NOFNC;
switch (sel) {
case 0: /* PTR boot */
ibl_copy (ptr_rom, dev);
break;
case 1: /* DP/DQ boot */
ibl_copy (dq_rom, dev);
break;
case 2: /* MS boot */
ibl_copy (ms_rom, dev);
break;
default:
return SCPE_NOFNC; }
return SCPE_OK;
}
/* IBL boot ROM copy
- Use memory size to set the initial PC and base of the boot area
- Copy boot ROM to memory, updating I/O instructions
- Place 2's complement of boot base in last location
Notes:
- SR settings are done by the caller
- Boot ROM's must be assembled with a device code of 10 (10 and 11 for
devices requiring two codes)
*/
t_stat ibl_copy (const uint16 pboot[IBL_LNT], int32 dev)
{
int32 i;
uint16 wd;
if (dev < 010) return SCPE_ARG; /* valid device? */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */
for (i = 0; i < IBL_LNT; i++) { /* copy bootstrap */
wd = pboot[i]; /* get word */
if (((wd & I_NMRMASK) == I_IO) && /* IO instruction? */
((wd & I_DEVMASK) >= 010) && /* dev >= 10? */
(I_GETIOOP (wd) != ioHLT)) /* not a HALT? */
M[PC + i] = (wd + (dev - 010)) & DMASK; /* change dev code */
else M[PC + i] = wd; } /* leave unchanged */
M[PC + IBL_DPC] = (M[PC + IBL_DPC] + (dev - 010)) & DMASK; /* patch DMA ctrl */
M[PC + IBL_END] = (~PC + 1) & DMASK; /* fill in start of boot */
return SCPE_OK;
}

View file

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

View file

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

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: HP2100 Simulator Usage Subj: HP2100 Simulator Usage
Date: 15-Feb-2004 Date: 30-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -80,7 +80,7 @@ CPU 2116 CPU with 32KW memory
21MX CPU with 1024KW memory, FP or DMS instructions 21MX CPU with 1024KW memory, FP or DMS instructions
DMA0, DMA1 dual channel DMA controller DMA0, DMA1 dual channel DMA controller
PTR,PTP 12597A paper tape reader/punch PTR,PTP 12597A paper tape reader/punch
TTY 12631C buffered terminal controller TTY 12531C buffered terminal controller
LPS 12653A printer controller with 2767 printer LPS 12653A printer controller with 2767 printer
12566B microcircuit interface for diagnostics 12566B microcircuit interface for diagnostics
LPT 12845A printer controller with 2607 printer 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: 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 - reference to an undefined I/O device, and STOP_DEV is set
- more than INDMAX indirect references are detected during - more than INDMAX indirect references are detected during
memory reference address decoding 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 -p if DMS enabled, force port A map
-q if DMS enabled, force port B 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 CPU registers include the visible state of the processor as well as the
control registers for the interrupt system. control registers for the interrupt system.
@ -157,18 +164,20 @@ control registers for the interrupt system.
P all 15 program counter P all 15 program counter
A all 16 A register A all 16 A register
B all 16 B 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 X 21MX 16 X index register
Y 21MX 16 Y index register Y 21MX 16 Y index register
S all 16 switch/display register S all 16 switch/display register
F 2100,21MX 15 memory protection fence
E all 1 extend flag E all 1 extend flag
O all 1 overflow flag O all 1 overflow flag
ION all 1 interrupt enable flag ION all 1 interrupt enable flag
ION_DEFER all 1 interrupt defer 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 MPCTL 2100,21MX 1 memory protection enable
MPFLG 2100,21MX 1 memory protection flag MPFLG 2100,21MX 1 memory protection flag
MPFBF 2100,21MX 1 memory protection flag buffer MPFBF 2100,21MX 1 memory protection flag buffer
MPFR 2100,21MX 15 memory protection fence
MPVR 2100,21MX 16 memory protection violation reg MPVR 2100,21MX 16 memory protection violation reg
MPEVR 2100,21MX 1 memory protection freeze flag MPEVR 2100,21MX 1 memory protection freeze flag
MPMEV 2100,21MX 1 memory protection DMS error 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 DMSCUR 21MX 1 DMS current mode
DMSSR 21MX 16 DMS status register DMSSR 21MX 16 DMS status register
DMSVR 21MX 16 DMS violation 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_INST all 1 stop on undefined instruction
STOP_DEV all 1 stop on undefined device STOP_DEV all 1 stop on undefined device
INDMAX all 16 indirect address limit INDMAX all 16 indirect address limit
@ -184,6 +193,24 @@ control registers for the interrupt system.
most recent P change first most recent P change first
WRU all 8 interrupt character 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 2.2 DMA Controllers
The HP2100 includes two DMA channel controllers (DMA0 and DMA1). Each 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. Thus, by changing POS, the user can backspace or advance the reader.
The paper tape reader supports the BOOT command. BOOT PTR copies the 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: The paper tape reader implements these registers:
@ -254,6 +287,9 @@ The paper tape reader implements these registers:
CTL 1 device/interrupt enable CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer 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 POS 32 position in the input file
TIME 24 time from I/O initiation to interrupt TIME 24 time from I/O initiation to interrupt
STOP_IOE 1 stop on I/O error STOP_IOE 1 stop on I/O error
@ -285,6 +321,7 @@ The paper tape punch implements these registers:
CTL 1 device/interrupt enable CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
POS 32 position in the output file POS 32 position in the output file
TIME 24 time from I/O initiation to interrupt TIME 24 time from I/O initiation to interrupt
STOP_IOE 1 stop on I/O error 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 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 The console terminal has three units: keyboard (unit 0), printer
(unit 1), and punch (unit 2). The keyboard reads from the console (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, 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 lower case input and output characters are automatically converted to
upper case. In 7B mode, input and output characters are masked to 7 upper case. In 7B mode, input and output characters are masked to 7
bits. In 8B mode, characters are not modified. Changing the mode bits. In 8B mode, characters are not modified. In UC and 7B mode,
of either unit changes both. The default mode is UC. 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: The console teleprinter implements these registers:
@ -319,6 +368,7 @@ The console teleprinter implements these registers:
CTL 1 device/interrupt enable CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
KPOS 32 number of characters input KPOS 32 number of characters input
KTIME 24 keyboard polling interval KTIME 24 keyboard polling interval
TPOS 32 number of characters printed TPOS 32 number of characters printed
@ -363,6 +413,7 @@ The 12653A implements these registers:
CTL 1 device/interrupt enable CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
POS 32 position in the output file POS 32 position in the output file
CTIME 24 time between characters CTIME 24 time between characters
PTIME 24 time for a print operation PTIME 24 time for a print operation
@ -395,6 +446,7 @@ The line printer implements these registers:
CTL 1 device/interrupt enable CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
LCNT 7 line count within page LCNT 7 line count within page
POS 32 position in the output file POS 32 position in the output file
CTIME 24 time between characters CTIME 24 time between characters
@ -497,6 +549,7 @@ The lines (MUXL) implements these registers:
CTL 1 device/interrupt enable CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
STA[0:20] 16 line status, lines 0-20 STA[0:20] 16 line status, lines 0-20
RPAR[0:20] 16 receive parameters, lines 0-20 RPAR[0:20] 16 receive parameters, lines 0-20
XPAR[0:15] 16 transmit parameters, lines 0-15 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 CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
SCAN 1 scan enabled SCAN 1 scan enabled
CHAN 4 current line CHAN 4 current line
DSO[0:15] 6 C2,C1,ES2,ES1,SS2,SS1, lines 0-15 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 CTL 1 device/interrupt enable
FLG 1 device ready FLG 1 device ready
FBF 1 device ready buffer FBF 1 device ready buffer
SRQ 1 device DMA service request
TIME 24 polling interval for input TIME 24 polling interval for input
STOP_IOE 1 stop on I/O error 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 buffer for reads and writes. The device controller includes the four
disk drives. Disk drives can be set ONLINE or OFFLINE. disk drives. Disk drives can be set ONLINE or OFFLINE.
The 12557A/13210A supports the BOOT command. BOOT DP loads the IBL The 12557A/13210A supports the BOOT command. BOOT DPC copies the IBL
for 7900 class disks into memory and starts it running. BOOT -F DP for 7900 class disks into memory and starts it running. BOOT -R DP
boots from the fixed platter (head 2). The switch register (S) is boots from the removable platter (head 2). The switch register (S) is
set automatically to the value expected by the IBL loader: set automatically to the value expected by the IBL loader:
<15:14> = 01 <15:14> = 01
<13:12> = 00 <13:12> = 00
<11:6> = data channel device code <11:6> = data channel device code
<5:1> = 00000 <5:3> = unchanged
<0> = 1 if booting from the fixed platter <2:1> = 00
<0> = 1 if booting from the removable platter
The data channel implements these registers: The data channel implements these registers:
@ -619,6 +675,7 @@ The data channel implements these registers:
CTL 1 interrupt enable CTL 1 interrupt enable
FLG 1 channel ready FLG 1 channel ready
FBF 1 channel ready buffer FBF 1 channel ready buffer
SRQ 1 channel DMA service request
XFER 1 transfer in progress flag XFER 1 transfer in progress flag
WVAL 1 write data valid flag WVAL 1 write data valid flag
@ -633,6 +690,7 @@ The device controller implements these registers:
CTL 1 interrupt enable CTL 1 interrupt enable
FLG 1 controller ready FLG 1 controller ready
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request
EOC 1 end of cylinder pending EOC 1 end of cylinder pending
RARC[0:3] 8 record address register cylinder, drives 0-3 RARC[0:3] 8 record address register cylinder, drives 0-3
RARH[0:3] 2 record address register head, 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 buffer for reads and writes. The device controller includes the two
disk drives. Disk drives can be set ONLINE or OFFLINE. 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) class disks into memory and starts it running. The switch register (S)
is set automatically to the value expected by the IBL loader: is set automatically to the value expected by the IBL loader:
<15:14> = 01 <15:12> = 0110
<13:12> = 10
<11:6> = data channel device code <11:6> = data channel device code
<5:0> = 00000 <5:3> = unchanged
<2:0> = 000
The data channel implements these registers: The data channel implements these registers:
@ -681,6 +739,7 @@ The data channel implements these registers:
CTL 1 interrupt enable CTL 1 interrupt enable
FLG 1 channel ready FLG 1 channel ready
FBF 1 channel ready buffer FBF 1 channel ready buffer
SRQ 1 channel DMA service request
XFER 1 transfer in progress flag XFER 1 transfer in progress flag
WVAL 1 write data valid flag WVAL 1 write data valid flag
@ -695,6 +754,7 @@ The device controller implements these registers:
CTL 1 interrupt enable CTL 1 interrupt enable
FLG 1 controller ready FLG 1 controller ready
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request
RARC[0:1] 8 record address register cylinder, drives 0-1 RARC[0:1] 8 record address register cylinder, drives 0-1
RARH[0:1] 5 record address register head, 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 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 CTL 1 interrupt enable
FLG 1 channel ready FLG 1 channel ready
FBF 1 channel ready buffer FBF 1 channel ready buffer
SRQ 1 channel DMA service request
BPTR 6 sector buffer pointer BPTR 6 sector buffer pointer
The device controller implements these registers: The device controller implements these registers:
@ -759,6 +820,7 @@ The device controller implements these registers:
CTL 1 interrupt enable CTL 1 interrupt enable
FLG 1 controller ready FLG 1 controller ready
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request
TIME 24 interword transfer time TIME 24 interword transfer time
STOP_IOE 1 stop on I/O error STOP_IOE 1 stop on I/O error
@ -793,6 +855,7 @@ The data channel implements these registers:
name size comments name size comments
FLG 1 channel ready FLG 1 channel ready
SRQ 1 channel DMA service request
DBUF[0:65535] 8 transfer buffer DBUF[0:65535] 8 transfer buffer
BPTR 16 buffer pointer (reads and writes) BPTR 16 buffer pointer (reads and writes)
BMAX 16 buffer size (writes) BMAX 16 buffer size (writes)
@ -807,6 +870,7 @@ The device controller implements these registers:
CTL 1 interrupt enabled CTL 1 interrupt enabled
FLG 1 controller ready FLG 1 controller ready
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request
DTF 1 data transfer flop DTF 1 data transfer flop
FSVC 1 first service flop FSVC 1 first service flop
POS 32 magtape position 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 the A register before starting to load data. The switch register (S) is
set automatically to the value expected by the IBL loader: set automatically to the value expected by the IBL loader:
<15:14> = 10 <15:12> = 1000
<13:12> = 00
<11:6> = data channel device code <11:6> = data channel device code
<5:1> = 00000 <5:3> = unchanged
<2:0> = 00
<0> = 1 if space forward before loading <0> = 1 if space forward before loading
The data channel implements these registers: The data channel implements these registers:
@ -861,6 +925,7 @@ The data channel implements these registers:
CTL 1 interrupt enabled CTL 1 interrupt enabled
FLG 1 channel ready FLG 1 channel ready
FBF 1 channel ready buffer FBF 1 channel ready buffer
SRQ 1 channel DMA service request
DBUF[0:65535] 8 transfer buffer DBUF[0:65535] 8 transfer buffer
BPTR 17 buffer pointer (reads and writes) BPTR 17 buffer pointer (reads and writes)
BMAX 17 buffer size (writes) BMAX 17 buffer size (writes)
@ -876,6 +941,7 @@ The device controller implements these registers:
CTL 1 interrupt enabled CTL 1 interrupt enabled
FLG 1 controller ready FLG 1 controller ready
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request
POS[0:3] 32 magtape position POS[0:3] 32 magtape position
CTIME 24 command delay time CTIME 24 command delay time
XTIME 24 interword transfer delay time XTIME 24 interword transfer delay time

View file

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

View file

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

View file

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

1398
HP2100/hp2100_ds.c Normal file

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -28,6 +28,11 @@
tty 12531C buffered teleprinter interface tty 12531C buffered teleprinter interface
clk 12539C time base generator 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 29-Mar-03 RMS Added support for console backpressure
25-Apr-03 RMS Added extended file support 25-Apr-03 RMS Added extended file support
22-Dec-02 RMS Added break support 22-Dec-02 RMS Added break support
@ -62,12 +67,15 @@
#include "hp2100_defs.h" #include "hp2100_defs.h"
#include <ctype.h> #include <ctype.h>
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */ #define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_V_UC (UNIT_V_UF + 1) /* UC only */ #define UNIT_V_UC (UNIT_V_UF + 1) /* UC only */
#define UNIT_V_DIAG (UNIT_V_UF + 2) /* diag mode */ #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_8B (1 << UNIT_V_8B)
#define UNIT_UC (1 << UNIT_V_UC) #define UNIT_UC (1 << UNIT_V_UC)
#define UNIT_DIAG (1 << UNIT_V_DIAG) #define UNIT_DIAG (1 << UNIT_V_DIAG)
#define UNIT_AUTOLF (1 << UNIT_V_AUTOLF)
#define PTP_LOW 0000040 /* low tape */ #define PTP_LOW 0000040 /* low tape */
#define TM_MODE 0100000 /* mode change */ #define TM_MODE 0100000 /* mode change */
@ -81,12 +89,18 @@
extern uint16 *M; extern uint16 *M;
extern uint32 PC, SR; 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; 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 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_select = 0; /* clock time select */
int32 clk_error = 0; /* clock error */ int32 clk_error = 0; /* clock error */
int32 clk_ctr = 0; /* clock counter */ 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; DEVICE ptr_dev, ptp_dev, tty_dev, clk_dev;
int32 ptrio (int32 inst, int32 IR, int32 dat); int32 ptrio (int32 inst, int32 IR, int32 dat);
t_stat ptr_svc (UNIT *uptr); t_stat ptr_svc (UNIT *uptr);
t_stat ptr_attach (UNIT *uptr, char *cptr);
t_stat ptr_reset (DEVICE *dptr); t_stat ptr_reset (DEVICE *dptr);
t_stat ptr_boot (int32 unitno, DEVICE *dptr); t_stat ptr_boot (int32 unitno, DEVICE *dptr);
int32 ptpio (int32 inst, int32 IR, int32 dat); 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 tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr); t_stat tto_svc (UNIT *uptr);
t_stat tty_reset (DEVICE *dptr); 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); int32 clkio (int32 inst, int32 IR, int32 dat);
t_stat clk_svc (UNIT *uptr); t_stat clk_svc (UNIT *uptr);
t_stat clk_reset (DEVICE *dptr); t_stat clk_reset (DEVICE *dptr);
int32 clk_delay (int32 flg); int32 clk_delay (int32 flg);
t_stat tto_out (int32 c);
t_stat ttp_out (int32 c);
/* PTR data structures /* PTR data structures
@ -123,7 +140,7 @@ int32 clk_delay (int32 flg);
ptr_reg PTR register list 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 = { UNIT ptr_unit = {
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0),
@ -135,6 +152,9 @@ REG ptr_reg[] = {
{ FLDATA (CTL, ptr_dib.ctl, 0) }, { FLDATA (CTL, ptr_dib.ctl, 0) },
{ FLDATA (FLG, ptr_dib.flg, 0) }, { FLDATA (FLG, ptr_dib.flg, 0) },
{ FLDATA (FBF, ptr_dib.fbf, 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 (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptr_stopioe, 0) }, { FLDATA (STOP_IOE, ptr_stopioe, 0) },
@ -150,7 +170,7 @@ DEVICE ptr_dev = {
"PTR", &ptr_unit, ptr_reg, ptr_mod, "PTR", &ptr_unit, ptr_reg, ptr_mod,
1, 10, 31, 1, 8, 8, 1, 10, 31, 1, 8, 8,
NULL, NULL, &ptr_reset, NULL, NULL, &ptr_reset,
&ptr_boot, NULL, NULL, &ptr_boot, &ptr_attach, NULL,
&ptr_dib, DEV_DISABLE }; &ptr_dib, DEV_DISABLE };
/* PTP data structures /* PTP data structures
@ -161,7 +181,7 @@ DEVICE ptr_dev = {
ptp_reg PTP register list 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 = { UNIT ptp_unit = {
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; 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 (CTL, ptp_dib.ctl, 0) },
{ FLDATA (FLG, ptp_dib.flg, 0) }, { FLDATA (FLG, ptp_dib.flg, 0) },
{ FLDATA (FBF, ptp_dib.fbf, 0) }, { FLDATA (FBF, ptp_dib.fbf, 0) },
{ FLDATA (SRQ, ptp_dib.srq, 0) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, ptp_stopioe, 0) }, { FLDATA (STOP_IOE, ptp_stopioe, 0) },
@ -202,7 +223,7 @@ DEVICE ptp_dev = {
#define TTO 1 #define TTO 1
#define TTP 2 #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[] = { UNIT tty_unit[] = {
{ UDATA (&tti_svc, UNIT_UC, 0), KBD_POLL_WAIT }, { UDATA (&tti_svc, UNIT_UC, 0), KBD_POLL_WAIT },
@ -212,10 +233,13 @@ UNIT tty_unit[] = {
REG tty_reg[] = { REG tty_reg[] = {
{ ORDATA (BUF, tty_buf, 8) }, { ORDATA (BUF, tty_buf, 8) },
{ ORDATA (MODE, tty_mode, 16) }, { ORDATA (MODE, tty_mode, 16) },
{ ORDATA (SHIN, tty_shin, 8), REG_HRO },
{ FLDATA (CMD, tty_dib.cmd, 0), REG_HRO }, { FLDATA (CMD, tty_dib.cmd, 0), REG_HRO },
{ FLDATA (CTL, tty_dib.ctl, 0) }, { FLDATA (CTL, tty_dib.ctl, 0) },
{ FLDATA (FLG, tty_dib.flg, 0) }, { FLDATA (FLG, tty_dib.flg, 0) },
{ FLDATA (FBF, tty_dib.fbf, 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 (KPOS, tty_unit[TTI].pos, T_ADDR_W), PV_LEFT },
{ DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT }, { DRDATA (KTIME, tty_unit[TTI].wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT }, { DRDATA (TPOS, tty_unit[TTO].pos, T_ADDR_W), PV_LEFT },
@ -226,9 +250,16 @@ REG tty_reg[] = {
{ NULL } }; { NULL } };
MTAB tty_mod[] = { MTAB tty_mod[] = {
{ UNIT_UC+UNIT_8B, UNIT_UC, "UC", "UC", &tty_set_mode }, { UNIT_UC+UNIT_8B, UNIT_UC, "UC", "UC", &tty_set_opt,
{ UNIT_UC+UNIT_8B, 0 , "7b", "7B", &tty_set_mode }, NULL, ((void *) (UNIT_UC + UNIT_8B)) },
{ UNIT_UC+UNIT_8B, UNIT_8B, "8b", "8B", &tty_set_mode }, { 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", { MTAB_XTD | MTAB_VDV, 0, "DEVNO", "DEVNO",
&hp_setdev, &hp_showdev, &tty_dev }, &hp_setdev, &hp_showdev, &tty_dev },
{ 0 } }; { 0 } };
@ -248,7 +279,7 @@ DEVICE tty_dev = {
clk_reg CLK register list 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 = { UNIT clk_unit = {
UDATA (&clk_svc, 0, 0) }; UDATA (&clk_svc, 0, 0) };
@ -260,6 +291,7 @@ REG clk_reg[] = {
{ FLDATA (CTL, clk_dib.ctl, 0) }, { FLDATA (CTL, clk_dib.ctl, 0) },
{ FLDATA (FLG, clk_dib.flg, 0) }, { FLDATA (FLG, clk_dib.flg, 0) },
{ FLDATA (FBF, clk_dib.fbf, 0) }, { FLDATA (FBF, clk_dib.fbf, 0) },
{ FLDATA (SRQ, clk_dib.srq, 0) },
{ FLDATA (ERR, clk_error, CLK_V_ERROR) }, { FLDATA (ERR, clk_error, CLK_V_ERROR) },
{ BRDATA (TIME, clk_time, 10, 24, 8) }, { BRDATA (TIME, clk_time, 10, 24, 8) },
{ ORDATA (DEVNO, clk_dib.devno, 6), REG_HRO }, { ORDATA (DEVNO, clk_dib.devno, 6), REG_HRO },
@ -288,14 +320,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */ dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */ case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */ if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break; break;
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK; if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK; if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioMIX: /* merge */ case ioMIX: /* merge */
dat = dat | ptr_unit.buf; dat = dat | ptr_unit.buf;
break; break;
@ -313,7 +345,7 @@ case ioCTL: /* control clear/set */
break; break;
default: default:
break; } break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */ if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat; return dat;
} }
@ -327,25 +359,40 @@ dev = ptr_dib.devno; /* get device no */
clrCMD (dev); /* clear cmd */ clrCMD (dev); /* clear cmd */
if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */ if ((ptr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptr_stopioe, SCPE_UNATT); return IORETURN (ptr_stopioe, SCPE_UNATT);
if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read byte */ if ((temp = getc (ptr_unit.fileref)) == EOF) { /* read byte, error? */
if (feof (ptr_unit.fileref)) { if (feof (ptr_unit.fileref)) { /* end of file? */
if (ptr_stopioe) printf ("PTR end of file\n"); if (ptr_trlcnt >= ptr_trllim) { /* added all trailer? */
else return SCPE_OK; } if (ptr_stopioe) { /* stop on error? */
else perror ("PTR I/O error"); printf ("PTR end of file\n");
clearerr (ptr_unit.fileref); return SCPE_IOERR; }
return SCPE_IOERR; } else return SCPE_OK; } /* no, just hang */
setFLG (dev); /* set flag */ 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.buf = temp & 0377; /* put byte in buf */
ptr_unit.pos = ftell (ptr_unit.fileref); ptr_unit.pos = ftell (ptr_unit.fileref);
return SCPE_OK; 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 */ /* Reset routine - called from SCP, flags in DIB's */
t_stat ptr_reset (DEVICE *dptr) t_stat ptr_reset (DEVICE *dptr)
{ {
ptr_dib.cmd = ptr_dib.ctl = 0; /* clear cmd, ctl */ 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; ptr_unit.buf = 0;
sim_cancel (&ptr_unit); /* deactivate unit */ sim_cancel (&ptr_unit); /* deactivate unit */
return SCPE_OK; return SCPE_OK;
@ -353,10 +400,7 @@ return SCPE_OK;
/* Paper tape reader bootstrap routine (HP 12992K ROM) */ /* Paper tape reader bootstrap routine (HP 12992K ROM) */
#define LDR_BASE 077 const uint16 ptr_rom[IBL_LNT] = {
#define CHANGE_DEV (1 << 24)
static const int32 pboot[IBL_LNT] = {
0107700, /*ST CLC 0,C ; intr off */ 0107700, /*ST CLC 0,C ; intr off */
0002401, /* CLA,RSS ; skip in */ 0002401, /* CLA,RSS ; skip in */
0063756, /*CN LDA M11 ; feed frame */ 0063756, /*CN LDA M11 ; feed frame */
@ -393,10 +437,10 @@ static const int32 pboot[IBL_LNT] = {
0027700, /* JMP ST ; next */ 0027700, /* JMP ST ; next */
0000000, /*RD 0 */ 0000000, /*RD 0 */
0006600, /* CLB,CME ; E reg byte ptr */ 0006600, /* CLB,CME ; E reg byte ptr */
0103700+CHANGE_DEV, /* STC RDR,C ; start reader */ 0103710, /* STC RDR,C ; start reader */
0102300+CHANGE_DEV, /* SFS RDR ; wait */ 0102310, /* SFS RDR ; wait */
0027745, /* JMP *-1 */ 0027745, /* JMP *-1 */
0106400+CHANGE_DEV, /* MIB RDR ; get byte */ 0106410, /* MIB RDR ; get byte */
0002041, /* SEZ,RSS ; E set? */ 0002041, /* SEZ,RSS ; E set? */
0127742, /* JMP RD,I ; no, done */ 0127742, /* JMP RD,I ; no, done */
0005767, /* BLF,CLE,BLF ; shift byte */ 0005767, /* BLF,CLE,BLF ; shift byte */
@ -410,16 +454,11 @@ static const int32 pboot[IBL_LNT] = {
t_stat ptr_boot (int32 unitno, DEVICE *dptr) t_stat ptr_boot (int32 unitno, DEVICE *dptr)
{ {
int32 i, dev; int32 dev;
dev = ptr_dib.devno; /* get device no */ dev = ptr_dib.devno; /* get device no */
PC = ((MEMSIZE - 1) & ~IBL_MASK) & VAMASK; /* start at mem top */ if (ibl_copy (ptr_rom, dev)) return SCPE_IERR; /* copy boot to memory */
SR = IBL_PTR + (dev << IBL_V_DEV); /* set SR */ SR = (SR & IBL_OPT) | 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;
return SCPE_OK; return SCPE_OK;
} }
@ -432,14 +471,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */ dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */ case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */ if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break; break;
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK; if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK; if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = 0; dat = 0;
case ioMIX: /* merge */ case ioMIX: /* merge */
@ -460,7 +499,7 @@ case ioCTL: /* control clear/set */
break; break;
default: default:
break; } break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */ if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat; return dat;
} }
@ -472,7 +511,7 @@ int32 dev;
dev = ptp_dib.devno; /* get device no */ dev = ptp_dib.devno; /* get device no */
clrCMD (dev); /* clear cmd */ clrCMD (dev); /* clear cmd */
setFLG (dev); /* set flag */ setFSR (dev); /* set flag */
if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */ if ((ptp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (ptp_stopioe, SCPE_UNATT); return IORETURN (ptp_stopioe, SCPE_UNATT);
if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { /* output byte */ if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) { /* output byte */
@ -488,7 +527,7 @@ return SCPE_OK;
t_stat ptp_reset (DEVICE *dptr) t_stat ptp_reset (DEVICE *dptr)
{ {
ptp_dib.cmd = ptp_dib.ctl = 0; /* clear cmd, ctl */ 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; ptp_unit.buf = 0;
sim_cancel (&ptp_unit); /* deactivate unit */ sim_cancel (&ptp_unit); /* deactivate unit */
return SCPE_OK; return SCPE_OK;
@ -503,14 +542,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */ dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */ case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */ if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break; break;
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK; if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK; if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioLIX: /* load */ case ioLIX: /* load */
dat = 0; dat = 0;
case ioMIX: /* merge */ case ioMIX: /* merge */
@ -531,11 +570,79 @@ case ioCTL: /* control clear/set */
break; break;
default: default:
break; } break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */ if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat; 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) t_stat tto_out (int32 c)
{ {
@ -546,8 +653,10 @@ if (tty_mode & TM_PRI) { /* printing? */
c = c & 0177; c = c & 0177;
if (islower (c)) c = toupper (c); } if (islower (c)) c = toupper (c); }
else c = c & ((tty_unit[TTO].flags & UNIT_8B)? 0377: 0177); else c = c & ((tty_unit[TTO].flags & UNIT_8B)? 0377: 0177);
if (r = sim_putchar_s (c)) return r; /* output char */ if (c || (tty_unit[TTO].flags & UNIT_8B)) { /* !null or 8b? */
tty_unit[TTO].pos = tty_unit[TTO].pos + 1; } if (r = sim_putchar_s (c)) return r; /* output char */
tty_unit[TTO].pos = tty_unit[TTO].pos + 1; }
}
return SCPE_OK; return SCPE_OK;
} }
@ -564,63 +673,29 @@ if (tty_mode & TM_PUN) { /* punching? */
return SCPE_OK; 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 */ /* Reset routine */
t_stat tty_reset (DEVICE *dptr) t_stat tty_reset (DEVICE *dptr)
{ {
tty_dib.cmd = tty_dib.ctl = 0; /* clear cmd, ctl */ 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_mode = TM_KBD; /* enable input */
tty_buf = 0; 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_activate (&tty_unit[TTI], tty_unit[TTI].wait); /* activate poll */
sim_cancel (&tty_unit[TTO]); /* cancel output */ sim_cancel (&tty_unit[TTO]); /* cancel output */
return SCPE_OK; 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 u = uptr - tty_dev.units;
int32 mask = (int32) desc;
if (u > 1) return SCPE_NOFNC; if (u > 1) return SCPE_NOFNC;
tty_unit[TTI].flags = (tty_unit[TTI].flags & ~(UNIT_UC | UNIT_8B)) | val; tty_unit[TTI].flags = (tty_unit[TTI].flags & ~mask) | val;
tty_unit[TTO].flags = (tty_unit[TTO].flags & ~(UNIT_UC | UNIT_8B)) | val; tty_unit[TTO].flags = (tty_unit[TTO].flags & ~mask) | val;
return SCPE_OK; return SCPE_OK;
} }
@ -633,14 +708,14 @@ int32 dev;
dev = IR & I_DEVMASK; /* get device no */ dev = IR & I_DEVMASK; /* get device no */
switch (inst) { /* case on opcode */ switch (inst) { /* case on opcode */
case ioFLG: /* flag clear/set */ case ioFLG: /* flag clear/set */
if ((IR & I_HC) == 0) { setFLG (dev); } /* STF */ if ((IR & I_HC) == 0) { setFSR (dev); } /* STF */
break; break;
case ioSFC: /* skip flag clear */ case ioSFC: /* skip flag clear */
if (FLG (dev) == 0) PC = (PC + 1) & VAMASK; if (FLG (dev) == 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioSFS: /* skip flag set */ case ioSFS: /* skip flag set */
if (FLG (dev) != 0) PC = (PC + 1) & VAMASK; if (FLG (dev) != 0) PC = (PC + 1) & VAMASK;
return dat; break;
case ioMIX: /* merge */ case ioMIX: /* merge */
dat = dat | clk_error; dat = dat | clk_error;
break; break;
@ -666,7 +741,7 @@ case ioCTL: /* control clear/set */
break; break;
default: default:
break; } break; }
if (IR & I_HC) { clrFLG (dev); } /* H/C option */ if (IR & I_HC) { clrFSR (dev); } /* H/C option */
return dat; return dat;
} }
@ -686,7 +761,7 @@ clk_ctr = clk_ctr - 1; /* decrement counter */
if (clk_ctr <= 0) { /* end of interval? */ if (clk_ctr <= 0) { /* end of interval? */
tim = FLG (dev); tim = FLG (dev);
if (FLG (dev)) clk_error = CLK_ERROR; /* overrun? error */ 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 */ clk_ctr = clk_delay (1); } /* reset counter */
return SCPE_OK; return SCPE_OK;
} }
@ -696,7 +771,7 @@ return SCPE_OK;
t_stat clk_reset (DEVICE *dptr) t_stat clk_reset (DEVICE *dptr)
{ {
clk_dib.cmd = clk_dib.ctl = 0; /* clear cmd, ctl */ 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_error = 0; /* clear error */
clk_select = 0; /* clear select */ clk_select = 0; /* clear select */
clk_ctr = 0; /* clear counter */ clk_ctr = 0; /* clear counter */

View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from 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 22-Mar-02 RMS Revised for dynamically allocated memory
14-Feb-02 RMS Added DMS instructions 14-Feb-02 RMS Added DMS instructions
04-Feb-02 RMS Fixed bugs in alter/skip display and parsing 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 dpd_dev, dpc_dev;
extern DEVICE dqd_dev, dqc_dev; extern DEVICE dqd_dev, dqc_dev;
extern DEVICE drd_dev, drc_dev; extern DEVICE drd_dev, drc_dev;
extern DEVICE ds_dev;
extern DEVICE muxl_dev, muxu_dev, muxc_dev; extern DEVICE muxl_dev, muxu_dev, muxc_dev;
extern DEVICE ipli_dev, iplo_dev; extern DEVICE ipli_dev, iplo_dev;
extern REG cpu_reg[]; extern REG cpu_reg[];
@ -67,6 +70,8 @@ extern uint16 *M;
char sim_name[] = "HP 2100"; char sim_name[] = "HP 2100";
char halt_msg[] = "HALT instruction xxxxxx";
REG *sim_PC = &cpu_reg[0]; REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 3; int32 sim_emax = 3;
@ -84,6 +89,7 @@ DEVICE *sim_devices[] = {
&dpd_dev, &dpc_dev, &dpd_dev, &dpc_dev,
&dqd_dev, &dqc_dev, &dqd_dev, &dqc_dev,
&drd_dev, &drc_dev, &drd_dev, &drc_dev,
&ds_dev,
&mtd_dev, &mtc_dev, &mtd_dev, &mtc_dev,
&msd_dev, &msc_dev, &msd_dev, &msc_dev,
&muxl_dev, &muxu_dev, &muxc_dev, &muxl_dev, &muxu_dev, &muxc_dev,
@ -94,7 +100,7 @@ const char *sim_stop_messages[] = {
"Unknown error", "Unknown error",
"Unimplemented instruction", "Unimplemented instruction",
"Non-existent I/O device", "Non-existent I/O device",
"HALT instruction", halt_msg,
"Breakpoint", "Breakpoint",
"Indirect address loop", "Indirect address loop",
"Indirect address interrupt (should not happen!)", "Indirect address interrupt (should not happen!)",
@ -231,7 +237,7 @@ static const int32 opc_val[] = {
0105100+I_NPN, 0105120+I_NPN, 0105100+I_NPN, 0105120+I_NPN,
0102101+I_NPN, 0103101+I_NPN, 0102201+I_NPC, 0102301+I_NPC, 0102101+I_NPN, 0103101+I_NPN, 0102201+I_NPC, 0102301+I_NPC,
0102000+I_IO1, 0102100+I_IO2, 0103100+I_IO2, 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, 0102500+I_IO1, 0106500+I_IO1, 0102600+I_IO1, 0106600+I_IO1,
0102700+I_IO1, 0106700+I_IO1, 0102700+I_IO1, 0106700+I_IO1,
0101710+I_NPN, 0101711+I_NPN, 0101712+I_NPN, 0101713+I_NPN, 0101710+I_NPN, 0101711+I_NPN, 0101712+I_NPN, 0101713+I_NPN,

View file

@ -70,10 +70,12 @@ BSC32_SBRS= \
$(INTDIR)/ibm1130_gui.sbr \ $(INTDIR)/ibm1130_gui.sbr \
$(INTDIR)/ibm1130_prt.sbr \ $(INTDIR)/ibm1130_prt.sbr \
$(INTDIR)/scp.sbr \ $(INTDIR)/scp.sbr \
$(INTDIR)/scp_tty.sbr \
$(INTDIR)/sim_tmxr.sbr \ $(INTDIR)/sim_tmxr.sbr \
$(INTDIR)/sim_sock.sbr \ $(INTDIR)/sim_sock.sbr \
$(INTDIR)/ibm1130_fmt.sbr $(INTDIR)/ibm1130_fmt.sbr \
$(INTDIR)/sim_console.sbr \
$(INTDIR)/sim_fio.sbr \
$(INTDIR)/sim_timer.sbr
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS) $(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<< $(BSC32) @<<
@ -98,10 +100,12 @@ LINK32_OBJS= \
$(INTDIR)/ibm1130_gui.obj \ $(INTDIR)/ibm1130_gui.obj \
$(INTDIR)/ibm1130_prt.obj \ $(INTDIR)/ibm1130_prt.obj \
$(INTDIR)/scp.obj \ $(INTDIR)/scp.obj \
$(INTDIR)/scp_tty.obj \
$(INTDIR)/sim_tmxr.obj \ $(INTDIR)/sim_tmxr.obj \
$(INTDIR)/sim_sock.obj \ $(INTDIR)/sim_sock.obj \
$(INTDIR)/ibm1130_fmt.obj $(INTDIR)/ibm1130_fmt.obj \
$(INTDIR)/sim_console.obj \
$(INTDIR)/sim_fio.obj \
$(INTDIR)/sim_timer.obj
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) $(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<< $(LINK32) @<<
@ -149,10 +153,12 @@ BSC32_SBRS= \
$(INTDIR)/ibm1130_gui.sbr \ $(INTDIR)/ibm1130_gui.sbr \
$(INTDIR)/ibm1130_prt.sbr \ $(INTDIR)/ibm1130_prt.sbr \
$(INTDIR)/scp.sbr \ $(INTDIR)/scp.sbr \
$(INTDIR)/scp_tty.sbr \
$(INTDIR)/sim_tmxr.sbr \ $(INTDIR)/sim_tmxr.sbr \
$(INTDIR)/sim_sock.sbr \ $(INTDIR)/sim_sock.sbr \
$(INTDIR)/ibm1130_fmt.sbr $(INTDIR)/ibm1130_fmt.sbr \
$(INTDIR)/sim_console.sbr \
$(INTDIR)/sim_fio.sbr \
$(INTDIR)/sim_timer.sbr
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS) $(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<< $(BSC32) @<<
@ -178,10 +184,12 @@ LINK32_OBJS= \
$(INTDIR)/ibm1130_gui.obj \ $(INTDIR)/ibm1130_gui.obj \
$(INTDIR)/ibm1130_prt.obj \ $(INTDIR)/ibm1130_prt.obj \
$(INTDIR)/scp.obj \ $(INTDIR)/scp.obj \
$(INTDIR)/scp_tty.obj \
$(INTDIR)/sim_tmxr.obj \ $(INTDIR)/sim_tmxr.obj \
$(INTDIR)/sim_sock.obj \ $(INTDIR)/sim_sock.obj \
$(INTDIR)/ibm1130_fmt.obj $(INTDIR)/ibm1130_fmt.obj \
$(INTDIR)/sim_console.obj \
$(INTDIR)/sim_fio.obj \
$(INTDIR)/sim_timer.obj
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) $(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<< $(LINK32) @<<
@ -325,17 +333,6 @@ $(INTDIR)/scp.obj : $(SOURCE) $(DEP_SCP_C) $(INTDIR)
################################################################################ ################################################################################
# Begin Source File # Begin Source File
SOURCE=..\scp_tty.c
DEP_SCP_T=\
..\sim_defs.h
$(INTDIR)/scp_tty.obj : $(SOURCE) $(DEP_SCP_T) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\pdp11\supnik\sim_tmxr.c SOURCE=\pdp11\supnik\sim_tmxr.c
DEP_SIM_T=\ DEP_SIM_T=\
..\sim_defs.h\ ..\sim_defs.h\
@ -367,6 +364,59 @@ SOURCE=.\ibm1130_fmt.c
$(INTDIR)/ibm1130_fmt.obj : $(SOURCE) $(INTDIR) $(INTDIR)/ibm1130_fmt.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=\pdp11\supnik\sim_console.c
DEP_SIM_C=\
..\sim_defs.h\
\pdp11\supnik\sim_sock.h\
\pdp11\supnik\sim_tmxr.h\
\pdp11\supnik\scp.h\
\pdp11\supnik\sim_console.h\
\pdp11\supnik\sim_timer.h\
\pdp11\supnik\sim_fio.h\
d:\progra~1\micros~1\include\winsock2.h\
\MSVC20\INCLUDE\sys\TYPES.H\
d:\progra~1\micros~1\include\qos.h\
d:\winddk\2600\inc\wxp\guiddef.h
$(INTDIR)/sim_console.obj : $(SOURCE) $(DEP_SIM_C) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\pdp11\supnik\sim_fio.c
DEP_SIM_F=\
..\sim_defs.h\
d:\progra~1\micros~1\include\BASETSD.H\
\pdp11\supnik\scp.h\
\pdp11\supnik\sim_console.h\
\pdp11\supnik\sim_timer.h\
\pdp11\supnik\sim_fio.h
$(INTDIR)/sim_fio.obj : $(SOURCE) $(DEP_SIM_F) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=\pdp11\supnik\sim_timer.c
DEP_SIM_TI=\
..\sim_defs.h\
d:\progra~1\micros~1\include\BASETSD.H\
\pdp11\supnik\scp.h\
\pdp11\supnik\sim_console.h\
\pdp11\supnik\sim_timer.h\
\pdp11\supnik\sim_fio.h
$(INTDIR)/sim_timer.obj : $(SOURCE) $(DEP_SIM_TI) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File # End Source File
# End Group # End Group
# End Project # End Project

View file

@ -45,21 +45,20 @@ END
// Bitmap // Bitmap
// //
IDB_CONSOLE BITMAP "1130consoleblank.bmp" IDB_CONSOLE BITMAP MOVEABLE PURE "1130consoleblank.bmp"
FULL_1442 BITMAP "1442full.bmp" FULL_1442 BITMAP MOVEABLE PURE "1442full.bmp"
EOF_1442 BITMAP "1442eof.bmp" EOF_1442 BITMAP MOVEABLE PURE "1442eof.bmp"
EMPTY_1442 BITMAP "1442empty.bmp" EMPTY_1442 BITMAP MOVEABLE PURE "1442empty.bmp"
MIDDLE_1442 BITMAP "1442middle.bmp" MIDDLE_1442 BITMAP MOVEABLE PURE "1442middle.bmp"
FULL_1132 BITMAP "1132full.bmp" FULL_1132 BITMAP MOVEABLE PURE "1132full.bmp"
EMPTY_1132 BITMAP "1132empty.bmp" EMPTY_1132 BITMAP MOVEABLE PURE "1132empty.bmp"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Cursor // Cursor
// //
IDC_HAND CURSOR "HAND.CUR" IDC_MYHAND CURSOR DISCARDABLE "HAND.CUR"
#ifndef APSTUDIO_INVOKED #ifndef APSTUDIO_INVOKED
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -18,6 +18,9 @@
* This is not a supported product, but I welcome bug reports and fixes. * This is not a supported product, but I welcome bug reports and fixes.
* Mail to simh@ibm1130.org * Mail to simh@ibm1130.org
* Update 2004-04-12: Changed ascii field of CPCODE to unsigned char, caught a couple
other potential problems with signed characters used as subscript indexes.
* Update 2003-11-25: Physical card reader support working, may not be perfect. * Update 2003-11-25: Physical card reader support working, may not be perfect.
Changed magic filename for stdin to "(stdin)". Changed magic filename for stdin to "(stdin)".
@ -454,7 +457,7 @@ DEVICE cp_dev = {
typedef struct { typedef struct {
uint16 hollerith; uint16 hollerith;
char ascii; unsigned char ascii;
} CPCODE; } CPCODE;
static CPCODE cardcode_029[] = static CPCODE cardcode_029[] =
@ -505,7 +508,7 @@ static CPCODE cardcode_029[] =
0x0120, '\'', 0x0120, '\'',
0x00A0, '=', 0x00A0, '=',
0x0060, '"', 0x0060, '"',
0x8820, '\xA2', // cent, in MS-DOS encoding (this is in guess_cr_code as well) 0x8820, (unsigned char) '\xA2', // cent, in MS-DOS encoding (this is in guess_cr_code as well)
0x8420, '.', 0x8420, '.',
0x8220, '<', // ) in 026 Fortran 0x8220, '<', // ) in 026 Fortran
0x8120, '(', 0x8120, '(',
@ -516,7 +519,7 @@ static CPCODE cardcode_029[] =
0x4220, '*', 0x4220, '*',
0x4120, ')', 0x4120, ')',
0x40A0, ';', 0x40A0, ';',
0x4060, '\xAC', // not, in MS-DOS encoding (this is in guess_cr_code as well) 0x4060, (unsigned char) '\xAC', // not, in MS-DOS encoding (this is in guess_cr_code as well)
0x2420, ',', 0x2420, ',',
0x2220, '%', // ( in 026 Fortran 0x2220, '%', // ( in 026 Fortran
0x2120, '_', 0x2120, '_',
@ -947,7 +950,7 @@ char card_to_ascii (uint16 hol)
for (i = 0; i < ncardcode; i++) for (i = 0; i < ncardcode; i++)
if (cardcode[i].hollerith == hol) if (cardcode[i].hollerith == hol)
return cardcode[i].ascii; return (char) cardcode[i].ascii;
return '?'; return '?';
} }
@ -960,7 +963,7 @@ char hollerith_to_ascii (uint16 hol)
for (i = 0; i < ncardcode; i++) for (i = 0; i < ncardcode; i++)
if (cardcode_029[i].hollerith == hol) if (cardcode_029[i].hollerith == hol)
return cardcode[i].ascii; return (char) cardcode[i].ascii;
return ' '; return ' ';
} }
@ -1074,7 +1077,7 @@ again: /* jump here if we've loaded a new deck after emptying the previous one
result = buf; result = buf;
for (i = 0; i < nread; i++) /* convert ascii to punch code */ for (i = 0; i < nread; i++) /* convert ascii to punch code */
readstation[i] = ascii_to_card[result[i]]; readstation[i] = ascii_to_card[(unsigned char) result[i]];
nread = 80; /* even if line was blank consider it present */ nread = 80; /* even if line was blank consider it present */
} }

View file

@ -13,6 +13,8 @@
*/ */
#include "sim_defs.h" /* main SIMH defns (include path should include .., or make a copy) */ #include "sim_defs.h" /* main SIMH defns (include path should include .., or make a copy) */
#include "sim_console.h" /* more SIMH defns (include path should include .., or make a copy) */
#include <setjmp.h> #include <setjmp.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>

View file

@ -11,6 +11,8 @@
* This is not a supported product, but I welcome bug reports and fixes. * This is not a supported product, but I welcome bug reports and fixes.
* Mail to simh@ibm1130.org * Mail to simh@ibm1130.org
* *
* 09-Apr-04 BLK Changed code to use stock windows cursor IDC_HAND if available
*
* 02-Dec-02 BLK Changed display, added printer and card reader icons * 02-Dec-02 BLK Changed display, added printer and card reader icons
* Added drag and drop support for scripts and card decks * Added drag and drop support for scripts and card decks
* Added support for physical card reader and printer (hides icons) * Added support for physical card reader and printer (hides icons)
@ -768,7 +770,13 @@ static DWORD WINAPI Pump (LPVOID arg)
hDkGreyPen = CreatePen(PS_SOLID, 1, RGB(64,64,64)); hDkGreyPen = CreatePen(PS_SOLID, 1, RGB(64,64,64));
hcArrow = LoadCursor(NULL, IDC_ARROW); hcArrow = LoadCursor(NULL, IDC_ARROW);
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_HAND)); #ifdef IDC_HAND
hcHand = LoadCursor(NULL, IDC_HAND); // use stock object provided by Windows
if (hcHand == NULL)
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_MYHAND));
#else
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_MYHAND));
#endif
if (hBitmap == NULL) if (hBitmap == NULL)
hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CONSOLE)); hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CONSOLE));

View file

@ -3,7 +3,7 @@
// Used by ibm1130.rc // Used by ibm1130.rc
// //
#define IDB_CONSOLE 101 #define IDB_CONSOLE 101
#define IDC_HAND 102 #define IDC_MYHAND 102
// Next default values for new objects // Next default values for new objects
// //

74
Ibm1130/makefile Normal file
View file

@ -0,0 +1,74 @@
# (This makefile is for operating systems other than Windows,
# or compilers other than Microsoft's. For MS builds, use the
# .mak files found in this directory and the utils directory).
#
# If you are building the emulator and utilities as part of
# the SIMH package, please:
#
# Be sure that you there are NO copies of scp.c, scp_tty.c,
# sim_sock.c, sim_tmxr.c, sim_rev.h, sim_defs.h, sim_sock.h and
# sim_tmxr.h in the ibm1130 subdirectory. Delete them if there
# are.
#
# Do not use this makefile with "make all" or "make ibm1130".
# Use the SIMH build files instead.
#
# If and when you download updates for this simulator from
# www.ibm1130.org, get ibm1130code.zip and ibm1130software.zip
# separately.
#
# If you have downloaded the emulator independently of SIMH (e.g, from
# www.ibm1130.org), please:
#
# Be sure that you DO have copies of scp.c, scp_tty.c, sim_sock.c,
# sim_tmxr.c, sim_rev.h, sim_defs.h, sim_sock.h and sim_tmxr.h
# in this folder.
#
# Use this file to make the emulator.
#
# If and when you download updates for this simulator from
# www.ibm1130.org, get ibm1130.zip. When you expand it,
# also expand ibm1130sofware.zip, which is inside.
#
# In either case, if you want to build DMS or work with assembly
# language programs outside of DMS, you'll want to make the utilities
# by cd'ing to the utils directory and running make there.
# CC Command
#
# Note: -O2 is sometimes broken in GCC when setjump/longjump is being
# used. Try -O2 only with released simulators.
#
CC = gcc -O0 -lm -I .
#CC = gcc -O2 -g -lm -I .
#
# Common Libraries
#
BIN =
SIM = scp.c sim_console.c sim_fio.c sim_sock.c sim_timer.c sim_tmxr.c scp_tty.c
SIM_INC = scp.h sim_console.h sim_defs.h sim_fio.h sim_rev.h sim_sock.h sim_timer.h sim_tmxr.h
#
# Emulator source files and compile time options
#
ibm1130D = ./
ibm1130 = ${ibm1130D}ibm1130_sys.c ${ibm1130D}ibm1130_cpu.c \
${ibm1130D}ibm1130_cr.c ${ibm1130D}ibm1130_disk.c \
${ibm1130D}ibm1130_stddev.c ${ibm1130D}ibm1130_gdu.c \
${ibm1130D}ibm1130_gui.c ${ibm1130D}ibm1130_prt.c \
${ibm1130D}ibm1130_fmt.c
ibm1130_INC = ibm1130res.h ibm1130_conin.h ibm1130_conout.h \
ibm1130_defs.h ibm1130_prtwheel.h ibm1130_fmt.h \
dmsr2v12phases.h dmsr2v12slet.h
#
# Build the emulator
#
${BIN}ibm1130 : ${ibm1130} ${SIM} ${ibm1130_INC} ${SIM_INC}
${CC} ${ibm1130} ${SIM} -o $@

4503
Ibm1130/utils/asm1130.c Normal file

File diff suppressed because it is too large Load diff

175
Ibm1130/utils/asm1130.mak Normal file
View file

@ -0,0 +1,175 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "asm1130.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/asm1130.exe $(OUTDIR)/asm1130.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"asm1130.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"asm1130.bsc"
BSC32_SBRS= \
$(INTDIR)/asm1130.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/asm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:no /PDB:$(OUTDIR)/"asm1130.pdb" /MACHINE:I386\
/OUT:$(OUTDIR)/"asm1130.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/asm1130.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/asm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/asm1130.exe $(OUTDIR)/asm1130.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"asm1130.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"asm1130.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"asm1130.bsc"
BSC32_SBRS= \
$(INTDIR)/asm1130.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/asm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:yes /PDB:$(OUTDIR)/"asm1130.pdb" /DEBUG /MACHINE:I386\
/OUT:$(OUTDIR)/"asm1130.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/asm1130.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/asm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\asm1130.c
$(INTDIR)/asm1130.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

755
Ibm1130/utils/bindump.c Normal file
View file

@ -0,0 +1,755 @@
/*
* (C) Copyright 2002, Brian Knittel.
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
* usual yada-yada. Please keep this notice and the copyright in any distributions
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
*/
// ---------------------------------------------------------------------------------
// BINDUMP - dumps card deck files in assembler object format
//
// Usage:
/// bindump deckfile lists object header info & sector break cards
// bindump -v deckfile lists object data records as well
// bindump -p deckfile for system program, lists phase IDs in the deck
// bindump -s deckfile >outfile for system program, sorts the phases & writes to stdout
#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
# include <windows.h>
# include <io.h>
# include <fcntl.h>
#endif
#include "util_io.h"
#ifndef TRUE
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif
typedef enum {R_ABSOLUTE = 0, R_RELATIVE = 1, R_LIBF = 2, R_CALL = 3} RELOC;
BOOL verbose = FALSE;
BOOL phid = FALSE;
BOOL sort = FALSE;
unsigned short card[80], buf[54], cardtype;
// bindump - dump a binary (card format) deck to verify sbrks, etc
void bail (char *msg);
void dump (char *fname);
void dump_data (char *fname);
void dump_phids (char *fname);
char *getname (unsigned short *ptr);
char *getseq (void);
int hollerith_to_ascii (unsigned short h);
void process (char *fname);
void show_raw (char *name);
void show_data (void);
void show_core (void);
void show_endc (void);
void show_81 (void);
void show_main (void);
void show_sub (void);
void show_ils (void);
void show_iss (void);
void show_end (void);
void sort_phases (char *fname);
void trim (char *s);
void unpack (unsigned short *card, unsigned short *buf);
void verify_checksum(unsigned short *buf);
int main (int argc, char **argv)
{
char *arg;
static char usestr[] = "Usage: bindump [-psv] filename...";
int i;
for (i = 1; i < argc; i++) {
arg = argv[i];
if (*arg == '-') {
arg++;
while (*arg) {
switch (*arg++) {
case 'v':
verbose = TRUE;
break;
case 'p':
phid = TRUE; // print only phase ID's
break;
case 's':
sort = TRUE; // sort deck by phases, writing to stdout
break;
default:
bail(usestr);
}
}
}
}
for (i = 1; i < argc; i++) {
arg = argv[i];
if (*arg != '-')
process(arg);
}
return 0;
}
void process (char *nm)
{
#ifdef _WIN32
WIN32_FIND_DATA fd;
HANDLE hFind;
char *c, buf[256];
if (strchr(nm, '*') == NULL && strchr(nm, '?') == NULL)
dump(nm);
else if ((hFind = FindFirstFile(nm, &fd)) == INVALID_HANDLE_VALUE)
fprintf(stderr, "No files matching '%s'\n", nm);
else {
if ((c = strrchr(nm, '\\')) == NULL)
c = strrchr(nm, ':');
do {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
if (c == NULL)
dump(fd.cFileName);
else {
strcpy(buf, nm);
strcpy(buf + (c-nm+1), fd.cFileName);
dump(buf);
}
} while (FindNextFile(hFind, &fd));
FindClose(hFind);
}
#else
dump(nm); // on unices, sh globs for us
#endif
}
void dump (char *fname)
{
if (sort)
sort_phases(fname);
else if (phid)
dump_phids(fname);
else
dump_data(fname);
}
struct tag_card {
int phid, seq;
unsigned short card[80];
};
int cardcomp (const void *a, const void *b)
{
short diff;
diff = ((struct tag_card *) a)->phid - ((struct tag_card *) b)->phid;
return diff ? diff : (((struct tag_card *) a)->seq - ((struct tag_card *) b)->seq);
}
void sort_phases (char *fname)
{
int i, ncards, cardtype, len, seq = 0, phid;
struct tag_card *deck;
FILE *fd;
BOOL saw_sbrk = TRUE;
if ((fd = fopen(fname, "rb")) == NULL) {
perror(fname);
return;
}
fseek(fd, 0, SEEK_END);
len = ftell(fd); // get length of file
fseek(fd, 0, SEEK_SET);
if (len <= 0 || (len % 160) != 0) {
fprintf(stderr, "%s is not a binard deck image\n");
fclose(fd);
return;
}
ncards = len / 160;
if ((deck = (struct tag_card *) malloc(ncards*sizeof(struct tag_card))) == NULL) {
fprintf(stderr, "%s: can't sort, insufficient memory\n");
fclose(fd);
return;
}
phid = 0;
for (i = 0; i < ncards; i++) {
if (fxread(deck[i].card, sizeof(card[0]), 80, fd) != 80) {
free(deck);
fprintf(stderr, "%s: error reading deck\n");
fclose(fd);
return;
}
unpack(deck[i].card, buf);
deck[i].seq = seq++;
deck[i].phid = phid;
verify_checksum(buf);
cardtype = (buf[2] >> 8) & 0xFF;
if (cardtype == 1 || cardtype == 2) { // start of deck is same as sector break
saw_sbrk = TRUE;
}
else if (cardtype == 0) {
fprintf(stderr, "%s is a core image deck\n");
free(deck);
fclose(fd);
return;
}
else if (cardtype == 0x0A && saw_sbrk) {
phid = (int) (signed short) buf[10];
if (phid < 0)
phid = -phid;
deck[i].phid = phid; // this belongs to the new phase
deck[i-1].phid = phid; // as does previous card
saw_sbrk = FALSE;
}
}
fclose(fd);
qsort(deck, ncards, sizeof(struct tag_card), cardcomp); // sort the deck
#ifdef _WIN32
_setmode(_fileno(stdout), _O_BINARY); // set standard output to binary mode
#endif
for (i = 0; i < ncards; i++) // write to stdout
fxwrite(deck[i].card, sizeof(card[0]), 80, stdout);
free(deck);
}
void dump_phids (char *fname)
{
FILE *fp;
BOOL first = TRUE;
BOOL saw_sbrk = TRUE, neg;
short id;
if ((fp = fopen(fname, "rb")) == NULL) {
perror(fname);
return;
}
printf("\n%s:\n", fname);
while (fxread(card, sizeof(card[0]), 80, fp) > 0) {
unpack(card, buf);
verify_checksum(buf);
cardtype = (buf[2] >> 8) & 0xFF;
if (cardtype == 1 && ! first) { // sector break
saw_sbrk = TRUE;
continue;
}
else {
switch (cardtype) {
case 0x00:
printf(" This is a core image deck\n");
goto done;
break;
case 0x01:
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x0F:
break;
case 0x0A:
if (saw_sbrk) {
id = buf[10];
if (id < 0)
id = -id, neg = TRUE;
else
neg = FALSE;
printf(" : %3d / %02x%s\n", id, id, neg ? " (neg)" : "");
saw_sbrk = FALSE;
}
break;
default:
show_raw("??? ");
}
}
done:
first = FALSE;
}
fclose(fp);
}
void dump_data (char *fname)
{
FILE *fp;
BOOL first = TRUE;
char str[80];
int i;
if ((fp = fopen(fname, "rb")) == NULL) {
perror(fname);
return;
}
printf("\n%s:\n", fname);
while (fxread(card, sizeof(card[0]), 80, fp) > 0) {
unpack(card, buf);
verify_checksum(buf);
cardtype = (buf[2] >> 8) & 0xFF;
if (cardtype == 1 && ! first) { // sector break
for (i = 4; i < 72; i++)
str[i] = hollerith_to_ascii(card[i]);
str[i] = '\0';
trim(str+4);
printf("*SBRK %s\n", str+4);
continue;
}
else {
switch (cardtype) {
case 0x00:
if (first)
show_raw("CORE");
if (verbose)
show_core();
break;
case 0x01:
show_raw("ABS ");
show_main();
break;
case 0x02:
show_raw("REL ");
show_main();
break;
case 0x03:
show_raw("LIB ");
show_sub();
break;
case 0x04:
show_raw("SUB ");
show_sub();
break;
case 0x05:
show_raw("ISSL");
show_iss();
break;
case 0x06:
show_raw("ISSC");
show_iss();
break;
case 0x07:
show_raw("ILS ");
show_ils();
break;
case 0x0F:
show_raw("END ");
show_end();
break;
case 0x80:
show_raw("ENDC");
show_endc();
break;
case 0x81:
show_raw("81 ");
show_81();
break;
case 0x0A:
if (verbose)
show_data();
break;
default:
show_raw("??? ");
}
}
first = FALSE;
}
fclose(fp);
}
void show_data (void)
{
int i, n, jrel, rflag, nout, ch, reloc;
BOOL first = TRUE;
n = buf[2] & 0x00FF;
printf("%04x: ", buf[0]);
jrel = 3;
nout = 0;
rflag = buf[jrel++];
for (i = 0; i < n; i++) {
if (nout >= 8) {
rflag = buf[jrel++];
if (first) {
printf(" %s", getseq());
first = FALSE;
}
printf("\n ");
nout = 0;
}
reloc = (rflag >> 14) & 0x03;
ch = (reloc == R_ABSOLUTE) ? ' ' :
(reloc == R_RELATIVE) ? 'R' :
(reloc == R_LIBF) ? 'L' : '@';
printf("%04x%c ", buf[9+i], ch);
rflag <<= 2;
nout++;
}
putchar('\n');
}
void show_core (void)
{
int i, n, nout;
BOOL first = TRUE;
n = buf[2] & 0x00FF;
printf("%04x: ", buf[0]);
nout = 0;
for (i = 0; i < n; i++) {
if (nout >= 8) {
if (first) {
printf(" %s", getseq());
first = FALSE;
}
printf("\n ");
nout = 0;
}
printf("%04x ", buf[9+i]);
nout++;
}
putchar('\n');
}
void info (int i, char *nm, char type)
{
if (nm)
printf("%s ", nm);
switch (type) {
case 'd':
printf("%d ", buf[i]);
break;
case 'x':
printf("%04x ", buf[i]);
break;
case 'b':
printf("%02x ", buf[i] & 0xFF);
break;
case 'n':
printf("%s ", getname(buf+i));
break;
default:
bail("BAD TYPE");
}
}
void show_main (void)
{
printf(" ");
info(2, "prec", 'b');
info(4, "common", 'd');
info(6, "work", 'd');
info(8, "files", 'd');
info(9, "name", 'n');
info(11, "pta", 'x');
putchar('\n');
}
void show_sub (void)
{
int i, n;
printf(" ");
info( 2, "prec", 'b');
n = buf[5] / 3;
for (i = 0; i < n; i++) {
info( 9+3*i, "ent", 'n');
info(11+3*i, NULL, 'x');
}
putchar('\n');
}
void show_iss (void)
{
printf(" ");
info(12, "level", 'd');
putchar('\n');
}
void show_ils (void)
{
printf(" ");
info( 2, "prec", 'b');
info( 5, "nint6", 'd');
info( 9, "ent", 'n');
info(11, NULL, 'x');
info(14, "nint", 'd');
info(15, "il1", 'd');
info(16, "il2", 'd');
putchar('\n');
}
void show_end (void)
{
printf(" ");
info(0, "size", 'd');
info(3, "pta", 'x');
putchar('\n');
}
void show_endc(void)
{
printf(" ");
info(52, "IX3", 'x');
info(53, "pta", 'x');
putchar('\n');
}
void show_81(void)
{
}
void show_raw (char *name)
{
int i;
printf("*%s", name);
for (i = 0; i < 12; i++)
printf(" %04x", buf[i]);
printf(" %s\n", getseq());
}
char * getseq (void)
{
static char seq[10];
int i;
for (i = 0; i < 8; i++)
seq[i] = hollerith_to_ascii(card[72+i]);
seq[i] = '\0';
return seq;
}
void bail (char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
void unpack (unsigned short *icard, unsigned short *obuf)
{
int i, j;
unsigned short wd1, wd2, wd3, wd4;
for (i = j = 0; i < 54; i += 3, j += 4) {
wd1 = icard[j];
wd2 = icard[j+1];
wd3 = icard[j+2];
wd4 = icard[j+3];
obuf[i ] = (wd1 & 0xFFF0) | ((wd2 >> 12) & 0x000F);
obuf[i+1] = ((wd2 << 4) & 0xFF00) | ((wd3 >> 8) & 0x00FF);
obuf[i+2] = ((wd3 << 8) & 0xF000) | ((wd4 >> 4) & 0x0FFF);
}
}
void verify_checksum (unsigned short *obuf)
{
// unsigned short sum;
if (obuf[1] == 0) // no checksum
return;
// if (sum != card[1])
// printf("Checksum %04x doesn't match card %04x\n", sum, card[1]);
}
typedef struct {
unsigned short hollerith;
char ascii;
} CPCODE;
static CPCODE cardcode_029[] =
{
0x0000, ' ',
0x8000, '&', // + in 026 Fortran
0x4000, '-',
0x2000, '0',
0x1000, '1',
0x0800, '2',
0x0400, '3',
0x0200, '4',
0x0100, '5',
0x0080, '6',
0x0040, '7',
0x0020, '8',
0x0010, '9',
0x9000, 'A',
0x8800, 'B',
0x8400, 'C',
0x8200, 'D',
0x8100, 'E',
0x8080, 'F',
0x8040, 'G',
0x8020, 'H',
0x8010, 'I',
0x5000, 'J',
0x4800, 'K',
0x4400, 'L',
0x4200, 'M',
0x4100, 'N',
0x4080, 'O',
0x4040, 'P',
0x4020, 'Q',
0x4010, 'R',
0x3000, '/',
0x2800, 'S',
0x2400, 'T',
0x2200, 'U',
0x2100, 'V',
0x2080, 'W',
0x2040, 'X',
0x2020, 'Y',
0x2010, 'Z',
0x0820, ':',
0x0420, '#', // = in 026 Fortran
0x0220, '@', // ' in 026 Fortran
0x0120, '\'',
0x00A0, '=',
0x0060, '"',
0x8820, 'c', // cent
0x8420, '.',
0x8220, '<', // ) in 026 Fortran
0x8120, '(',
0x80A0, '+',
0x8060, '|',
0x4820, '!',
0x4420, '$',
0x4220, '*',
0x4120, ')',
0x40A0, ';',
0x4060, 'n', // not
0x2820, 'x', // what?
0x2420, ',',
0x2220, '%', // ( in 026 Fortran
0x2120, '_',
0x20A0, '>',
0x2060, '>',
};
int hollerith_to_ascii (unsigned short h)
{
int i;
h &= 0xFFF0;
for (i = 0; i < sizeof(cardcode_029) / sizeof(CPCODE); i++)
if (cardcode_029[i].hollerith == h)
return cardcode_029[i].ascii;
return '?';
}
// ---------------------------------------------------------------------------------
// trim - remove trailing whitespace from string s
// ---------------------------------------------------------------------------------
void trim (char *s)
{
char *nb;
for (nb = s-1; *s; s++)
if (*s > ' ')
nb = s;
nb[1] = '\0';
}
int ascii_to_ebcdic_table[128] =
{
0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,
0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, 0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,
0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,
0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,
0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d,
0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,
0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,
};
char *getname (unsigned short *ptr)
{
static char str[6];
int i, j, ch;
long v;
v = (ptr[0] << 16L) | ptr[1];
for (i = 0; i < 5; i++) {
ch = ((v >> 24) & 0x3F) | 0xC0; // recover those lost two bits
v <<= 6;
str[i] = ' ';
for (j = 0; j < (sizeof(ascii_to_ebcdic_table)/sizeof(ascii_to_ebcdic_table[0])); j++) {
if (ascii_to_ebcdic_table[j] == ch) {
str[i] = j;
break;
}
}
}
str[5] = '\0';
return str;
}

175
Ibm1130/utils/bindump.mak Normal file
View file

@ -0,0 +1,175 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "bindump.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/bindump.exe $(OUTDIR)/bindump.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"bindump.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"bindump.bsc"
BSC32_SBRS= \
$(INTDIR)/bindump.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/bindump.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
/NOLOGO /SUBSYSTEM:console /INCREMENTAL:no /PDB:$(OUTDIR)/"bindump.pdb"\
/MACHINE:I386 /OUT:$(OUTDIR)/"bindump.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/bindump.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/bindump.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/bindump.exe $(OUTDIR)/bindump.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"bindump.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"bindump.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"bindump.bsc"
BSC32_SBRS= \
$(INTDIR)/bindump.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/bindump.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
/NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes /PDB:$(OUTDIR)/"bindump.pdb" /DEBUG\
/MACHINE:I386 /OUT:$(OUTDIR)/"bindump.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/bindump.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/bindump.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\bindump.c
$(INTDIR)/bindump.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

262
Ibm1130/utils/checkdisk.c Normal file
View file

@ -0,0 +1,262 @@
/*
* (C) Copyright 2002, Brian Knittel.
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
* usual yada-yada. Please keep this notice and the copyright in any distributions
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
*/
// checkdisk - validates and optionally dumps an IBM1130 DMS2 disk image file
//
// Usage:
// checkdisk [-f] [-d cyl.sec|abssec] [-n count] filename
//
// Examples:
// checkdisk file.dsk
// report any misnumbered sectors in file.dsk
//
// checkdisk -f file.dsk
// report and fix any misnumbered sectors
//
// checkdisk -d 198.0 file.dsk
// dump cylinder 198 sector 0
//
// checkdisk -d 0 file.dsk
// dump absolute sector 0
//
// checkdisk -d 198.0 -n 4 file.dsk
// dump 4 sectors starting at m.n
// -----------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util_io.h"
#ifdef _WIN32
# include <io.h>
#else
long filelength (int fno);
# include <sys/types.h>
# include <sys/stat.h>
#endif
#ifndef TRUE
# define BOOL int
# define TRUE 1
# define FALSE 0
#endif
#define DSK_NUMWD 321 /* words/sector */
#define DSK_NUMSC 4 /* sectors/surface */
#define DSK_NUMSF 2 /* surfaces/cylinder */
#define DSK_NUMCY 203 /* cylinders/drive */
#define DSK_NUMDR 5 /* drives/controller */
#define DSK_SIZE (DSK_NUMCY * DSK_NUMSF * DSK_NUMSC * DSK_NUMWD) /* words/drive */
char *usestr = "Usage: checkdisk [-f] [-d cyl.sec|abssec] [-n count] diskfile";
char *baddisk = "Cannot fix this";
void bail (char *msg);
char *lowcase (char *str);
int main (int argc, char **argv)
{
FILE *fp;
char *fname = NULL, *arg, *argval;
int i, j, cyl, sec, pos, asec, retry, nbad = 0, nfixed = 0, nline;
BOOL fixit = FALSE, dump = FALSE;
int dsec, nsec = 1;
unsigned short wd, buf[DSK_NUMWD];
for (i = 1; i < argc;) {
arg = argv[i++];
if (*arg == '-') {
arg++;
lowcase(arg);
while (*arg) {
switch (*arg++) {
case 'f':
fixit = TRUE;
break;
case 'd':
dump = TRUE;
if (i >= argc)
bail(usestr);
argval = argv[i++];
if (strchr(argval, '.') != NULL) {
if (sscanf(argval, "%d.%d", &cyl, &sec) != 2)
bail(usestr);
dsec = cyl*(DSK_NUMSF*DSK_NUMSC) + sec;
}
else if (sscanf(argval, "%d", &dsec) != 1)
bail(usestr);
if (dsec < 0 || dsec >= (DSK_NUMCY*DSK_NUMSF*DSK_NUMSC))
bail("No such sector");
break;
case 'n':
if (i >= argc)
bail(usestr);
argval = argv[i++];
if (sscanf(argval, "%d", &nsec) != 1)
bail(usestr);
if (nsec <= 0)
bail(usestr);
break;
default:
bail(usestr);
}
}
}
else if (fname == NULL)
fname = arg;
else
bail(usestr);
}
if (fname == NULL)
bail(usestr);
if ((fp = fopen(fname, "rb+")) == NULL) {
perror(fname);
return 1;
}
if (filelength(fileno(fp)) != 2*DSK_SIZE) {
fprintf(stderr, "File is wrong length, expected %d\n", DSK_SIZE);
bail(baddisk);
}
for (cyl = 0; cyl < DSK_NUMCY; cyl++) {
for (sec = 0; sec < (DSK_NUMSF*DSK_NUMSC); sec++) {
retry = 1;
again:
asec = cyl*(DSK_NUMSF*DSK_NUMSC) + sec;
pos = asec*2*DSK_NUMWD;
if (fseek(fp, pos, SEEK_SET) != 0) {
fprintf(stderr, "Error seeking to pos %x\n", pos);
bail(baddisk);
}
if (fxread(&wd, sizeof(wd), 1, fp) != 1) {
fprintf(stderr, "Error reading word at abs sec %x, cyl %x, sec %x at offset %x\n", asec, cyl, sec, pos);
bail(baddisk);
}
if (wd != asec) {
fprintf(stderr, "Bad sector #%x at abs sec %x, cyl %x, sec %x at offset %x\n", wd, asec, cyl, sec, pos);
nbad++;
if (fixit) {
if (fseek(fp, pos, SEEK_SET) != 0) {
fprintf(stderr, "Error seeking to pos %x\n", pos);
bail(baddisk);
}
if (fxwrite(&asec, sizeof(wd), 1, fp) != 1) {
fprintf(stderr, "Error writing sector # to abs sec %x, cyl %x, sec %x at offset %x\n", asec, cyl, sec, pos);
bail(baddisk);
}
if (retry) {
retry = 0;
nfixed++;
goto again;
}
fprintf(stderr, "Failed after retry\n");
bail(baddisk);
}
}
}
}
if (nbad)
printf("%d bad sector mark%s %s\n", nbad, (nbad == 1) ? "" : "s", fixit ? "fixed" : "found");
else if (! dump)
printf("All sector marks OK\n");
if (! dump)
return 0;
pos = dsec*2*DSK_NUMWD;
if (fseek(fp, pos, SEEK_SET) != 0) {
fprintf(stderr, "Error seeking to pos %x\n", pos);
bail(baddisk);
}
for (i = 0; i < nsec; i++) {
cyl = dsec / (DSK_NUMSF*DSK_NUMSC);
sec = dsec - cyl*(DSK_NUMSF*DSK_NUMSC);
if (fxread(&buf, sizeof(buf[0]), DSK_NUMWD, fp) != DSK_NUMWD) {
fprintf(stderr, "Error reading abs sec %x, cyl %x, sec %x at offset %x\n", dsec, cyl, sec, pos);
bail(baddisk);
}
printf("\nSector %d.%d - %d - /%04x label %04x\n", cyl, sec, dsec, dsec, buf[0]);
for (nline = 0, j = 1; j < DSK_NUMWD; j++) {
printf("%04x", buf[j]);
if (++nline == 16) {
putchar('\n');
nline = 0;
}
else
putchar(' ');
}
dsec++;
}
return 0;
}
void bail (char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
/* ------------------------------------------------------------------------
* lowcase - force a string to lower case (ASCII)
* ------------------------------------------------------------------------ */
char *lowcase (char *str)
{
char *s;
for (s = str; *s; s++) {
if (*s >= 'A' && *s <= 'Z')
*s += 32;
}
return str;
}
#ifndef _WIN32
long filelength (int fno)
{
struct stat sb;
if (fstat(fno, &sb) != 0)
return 0;
return (long) sb.st_size;
}
#endif

177
Ibm1130/utils/checkdisk.mak Normal file
View file

@ -0,0 +1,177 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "checkdisk.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Release"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/checkdisk.exe $(OUTDIR)/checkdisk.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"checkdisk.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"checkdisk.bsc"
BSC32_SBRS= \
$(INTDIR)/checkdisk.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/checkdisk.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib /NOLOGO\
/SUBSYSTEM:console /INCREMENTAL:no /PDB:$(OUTDIR)/"checkdisk.pdb" /MACHINE:I386\
/OUT:$(OUTDIR)/"checkdisk.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/checkdisk.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/checkdisk.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/checkdisk.exe $(OUTDIR)/checkdisk.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"checkdisk.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"checkdisk.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"checkdisk.bsc"
BSC32_SBRS= \
$(INTDIR)/checkdisk.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/checkdisk.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib /NOLOGO\
/SUBSYSTEM:console /INCREMENTAL:yes /PDB:$(OUTDIR)/"checkdisk.pdb" /DEBUG\
/MACHINE:I386 /OUT:$(OUTDIR)/"checkdisk.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/checkdisk.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/checkdisk.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\checkdisk.c
DEP_CHECK=\
.\util_io.h\
\MSVC20\INCLUDE\sys\types.h\
\MSVC20\INCLUDE\sys\stat.h
$(INTDIR)/checkdisk.obj : $(SOURCE) $(DEP_CHECK) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
$(INTDIR)/util_io.obj : $(SOURCE) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

612
Ibm1130/utils/diskview.c Normal file
View file

@ -0,0 +1,612 @@
/*
* (C) Copyright 2002, Brian Knittel.
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
* usual yada-yada. Please keep this notice and the copyright in any distributions
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
*/
// DISKVIEW - lists contents of an 1130 system disk image file. Not finished yet.
// needs LET/SLET listing routine.
//
// usage:
// diskview -v diskfile
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "util_io.h"
#define BETWEEN(v,a,b) (((v) >= (a)) && ((v) <= (b)))
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
#ifndef TRUE
# define TRUE 1
# define FALSE 0
# define BOOL int
#endif
#define NOT_DEF 0x0658 // defective cylinder table entry means no defect
#define DSK_NUMWD 321 /* words/sector */
#define DSK_NUMCY 203 /* cylinders/drive */
#define DSK_SECCYL 8 /* sectors per cylinder */
#define SECLEN 320 /* data words per sector */
#define SLETLEN ((3*SECLEN)/4) /* length of slet in records */
typedef unsigned short WORD;
FILE *fp;
WORD buf[DSK_NUMWD];
WORD dcom[DSK_NUMWD];
#pragma pack(2)
struct tag_slet {
WORD phid;
WORD addr;
WORD nwords;
WORD sector;
} slet[SLETLEN];
#pragma pack()
WORD dcyl[3];
BOOL verbose = FALSE;
void checksectors (void);
void dump_id (void);
void dump_dcom (void);
void dump_resmon (void);
void dump_slet (void);
void dump_hdng (void);
void dump_scra (void);
void dump_let (void);
void dump_flet (void);
void dump_cib (void);
void getsector (int sec, WORD *sbuf);
void getdcyl (void);
char *lowcase (char *str);
void bail(char *fmt, ...);
char *trim (char *s);
int main (int argc, char **argv)
{
char *fname = NULL, *arg;
static char usestr[] = "Usage: diskview [-v] filename";
int i;
for (i = 1; i < argc;) {
arg = argv[i++];
if (*arg == '-') {
arg++;
lowcase(arg);
while (*arg) {
switch (*arg++) {
case 'v':
verbose = TRUE;
break;
default:
bail(usestr);
}
}
}
else if (fname == NULL)
fname = arg;
else
bail(usestr);
}
if (fname == NULL)
bail(usestr);
if ((fp = fopen(fname, "rb")) == NULL) {
perror(fname);
return 2;
}
printf("%s:\n", fname);
checksectors();
getdcyl();
dump_id(); // ID & coldstart
dump_dcom(); // DCOM
dump_resmon(); // resident image
dump_slet(); // SLET
dump_hdng(); // heading sector
dump_scra();
dump_flet();
dump_cib();
dump_let();
fclose(fp);
return 0;
}
// checksectors - verify that all sectors are properly numbered
void checksectors ()
{
WORD sec = 0;
fseek(fp, 0, SEEK_SET);
for (sec = 0; sec < DSK_NUMCY*DSK_SECCYL; sec++) {
if (fxread(buf, sizeof(WORD), DSK_NUMWD, fp) != DSK_NUMWD)
bail("File read error or not a disk image file");
if (buf[0] != sec)
bail("Sector /%x is misnumbered, run checkdisk [-f]", sec);
}
}
// get defective cylinder list
void getdcyl (void)
{
fseek(fp, sizeof(WORD), SEEK_SET); // skip sector count
if (fxread(dcyl, sizeof(WORD), 3, fp) != 3)
bail("Unable to read defective cylinder table");
}
// getsector - read specified absolute sector
void getsector (int sec, WORD *sbuf)
{
int i, cyl, ssec;
sec &= 0x7FF; // mask of drive bits, if any
cyl = sec / DSK_SECCYL; // get cylinder
ssec = sec & ~(DSK_SECCYL-1); // mask to get starting sector of cylinder
for (i = 0; i < 3; i++) { // map through defective cylinder table
if (dcyl[i] == ssec) {
sec &= (DSK_SECCYL-1); // mask to get base sector
cyl = DSK_NUMCY-3+i; // replacements are last three on disk
sec += cyl*DSK_SECCYL; // add new cylinder offset
break;
}
}
// read the sector
if (fseek(fp, (sec*DSK_NUMWD+1)*sizeof(WORD), SEEK_SET) != 0)
bail("File seek failed");
if (fxread(sbuf, sizeof(WORD), DSK_NUMWD, fp) != DSK_NUMWD)
bail("File read error or not a disk image file");
}
void dump (int nwords)
{
int i, nline = 0;
for (i = 0; i < nwords; i++) {
if (nline == 16) {
putchar('\n');
nline = 0;
}
printf("%04x", buf[i]);
nline++;
}
putchar('\n');
}
void showmajor (char *label)
{
int i;
printf("\n--- %s ", label);
for (i = strlen(label); i < 40; i++)
putchar('-');
putchar('\n');
putchar('\n');
}
void name (char *label)
{
printf("%-32.32s ", label);
}
void pbf (char *label, WORD *buf, int nwords)
{
int i, nout;
name(label);
for (i = nout = 0; i < nwords; i++, nout++) {
if (nout == 8) {
putchar('\n');
name("");
nout = 0;
}
printf(" %04x", buf[i]);
}
putchar('\n');
}
void prt (char *label, char *fmt, ...)
{
va_list args;
name(label);
putchar(' ');
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
putchar('\n');
}
void dump_id (void)
{
showmajor("Sector 0 - ID & coldstart");
getsector(0, buf);
pbf("DCYL def cyl table", buf+ 0, 3);
pbf("CIDN cart id", buf+ 3, 1);
pbf(" copy code", buf+ 4, 1);
pbf("DTYP disk type", buf+ 7, 1);
pbf(" diskz copy", buf+ 30, 8);
pbf(" cold start pgm",buf+270, 8);
}
// EQUIVALENCES FOR DCOM PARAMETERS
#define NAME 4 // NAME OF PROGRAM/CORE LOAD
#define DBCT 6 // BLOCK CT OF PROGRAM/CORE LOAD
#define FCNT 7 // FILES SWITCH
#define SYSC 8 // SYSTEM/NON-SYSTEM CARTRIDGE INDR
#define JBSW 9 // JOBT SWITCH
#define CBSW 10 // CLB-RETURN SWITCH
#define LCNT 11 // NO. OF LOCALS
#define MPSW 12 // CORE MAP SWITCH
#define MDF1 13 // NO. DUP CTRL RECORDS (MODIF)
#define MDF2 14 // ADDR OF MODIF BUFFER
#define NCNT 15 // NO. OF NOCALS
#define ENTY 16 // RLTV ENTRY ADDR OF PROGRAM
#define RP67 17 // 1442-5 SWITCH
#define TODR 18 // OBJECT WORK STORAGE DRIVE CODE
#define FHOL 20 // ADDR LARGEST HOLE IN FIXED AREA
#define FSZE 21 // BLK CNT LARGEST HOLE IN FXA
#define UHOL 22 // ADDR LAST HOLE IN USER AREA 2-10
#define USZE 23 // BLK CNT LAST HOLE IN UA 2-10
#define DCSW 24 // DUP CALL SWITCH
#define PIOD 25 // PRINCIPAL I/O DEVICE INDICATOR
#define PPTR 26 // PRINCIPAL PRINT DEVICE INDICATOR
#define CIAD 27 // RLTV ADDR IN @STRT OF CIL ADDR
#define ACIN 28 // AVAILABLE CARTRIDGE INDICATOR
#define GRPH 29 // 2250 INDICATOR 2G2
#define GCNT 30 // NO. G2250 RECORDS 2G2
#define LOSW 31 // LOCAL-CALLS-LOCAL SWITCH 2-2
#define X3SW 32 // SPECIAL ILS SWITCH 2-2
#define ECNT 33 // NO. OF *EQUAT RCDS 2-4
#define ANDU 35 // 1+BLK ADDR END OF UA (ADJUSTED)
#define BNDU 40 // 1+BLK ADDR END OF UA (BASE)
#define FPAD 45 // FILE PROTECT ADDR
#define PCID 50 // CARTRIDGE ID, PHYSICAL DRIVE
#define CIDN 55 // CARTRIDGE ID, LOGICAL DRIVE
#define CIBA 60 // SCTR ADDR OF CIB
#define SCRA 65 // SCTR ADDR OF SCRA
#define FMAT 70 // FORMAT OF PROG IN WORKING STG
#define FLET 75 // SCTR ADDR 1ST SCTR OF FLET
#define ULET 80 // SCTR ADDR 1ST SCTR OF LET
#define WSCT 85 // BLK CNT OF PROG IN WORKING STG
#define CSHN 90 // NO. SCTRS IN CUSHION AREA
struct tag_dcominfo {
char *nm;
int offset;
char *descr;
} dcominfo[] = {
"NAME", 4, "NAME OF PROGRAM/CORE LOAD",
"DBCT", 6, "BLOCK CT OF PROGRAM/CORE LOAD",
"FCNT", 7, "FILES SWITCH",
"SYSC", 8, "SYSTEM/NON-SYSTEM CARTRIDGE INDR",
"JBSW", 9, "JOBT SWITCH",
"CBSW", 10, "CLB-RETURN SWITCH",
"LCNT", 11, "NO. OF LOCALS",
"MPSW", 12, "CORE MAP SWITCH",
"MDF1", 13, "NO. DUP CTRL RECORDS (MODIF)",
"MDF2", 14, "ADDR OF MODIF BUFFER",
"NCNT", 15, "NO. OF NOCALS",
"ENTY", 16, "RLTV ENTRY ADDR OF PROGRAM",
"RP67", 17, "1442-5 SWITCH",
"TODR", 18, "OBJECT WORK STORAGE DRIVE CODE",
"FHOL", 20, "ADDR LARGEST HOLE IN FIXED AREA",
"FSZE", 21, "BLK CNT LARGEST HOLE IN FXA",
"UHOL", 22, "ADDR LAST HOLE IN USER AREA",
"USZE", 23, "BLK CNT LAST HOLE IN UA",
"DCSW", 24, "DUP CALL SWITCH",
"PIOD", 25, "PRINCIPAL I/O DEVICE INDICATOR",
"PPTR", 26, "PRINCIPAL PRINT DEVICE INDICATOR",
"CIAD", 27, "RLTV ADDR IN @STRT OF CIL ADDR",
"ACIN", 28, "AVAILABLE CARTRIDGE INDICATOR",
"GRPH", 29, "2250 INDICATOR",
"GCNT", 30, "NO. G2250 RECORDS",
"LOSW", 31, "LOCAL-CALLS-LOCAL SWITCH",
"X3SW", 32, "SPECIAL ILS SWITCH",
"ECNT", 33, "NO. OF *EQUAT RCDS",
"ANDU", 35, "1+BLK ADDR END OF UA (ADJUSTED)",
"BNDU", 40, "1+BLK ADDR END OF UA (BASE)",
"FPAD", 45, "FILE PROTECT ADDR",
"PCID", 50, "CARTRIDGE ID, PHYSICAL DRIVE",
"CIDN", 55, "CARTRIDGE ID, LOGICAL DRIVE",
"CIBA", 60, "SCTR ADDR OF CIB",
"SCRA", 65, "SCTR ADDR OF SCRA",
"FMAT", 70, "FORMAT OF PROG IN WORKING STG",
"FLET", 75, "SCTR ADDR 1ST SCTR OF FLET",
"ULET", 80, "SCTR ADDR 1ST SCTR OF LET",
"WSCT", 85, "BLK CNT OF PROG IN WORKING STG",
"CSHN", 90, "NO. SCTRS IN CUSHION AREA",
NULL
};
void dump_dcom (void)
{
struct tag_dcominfo *d;
char txt[50];
showmajor("Sector 1 - DCOM");
getsector(1, dcom);
for (d = dcominfo; d->nm != NULL; d++) {
sprintf(txt, "%-4.4s %s", d->nm, d->descr);
pbf(txt, dcom+d->offset, 1);
}
}
void dump_resmon (void)
{
showmajor("Sector 2 - Resident Image");
getsector(2, buf);
dump(verbose ? SECLEN : 32);
}
struct {
int pfrom, pto;
int printed;
char *name;
} sletinfo[] = {
0x01, 0x12, FALSE, "DUP",
0x1F, 0x39, FALSE, "Fortran",
0x51, 0x5C, FALSE, "Cobol",
0x6E, 0x74, FALSE, "Supervisor",
0x78, 0x84, FALSE, "Core Load Builder",
0x8C, 0x8C, FALSE, "Sys 1403 prt",
0x8D, 0x8D, FALSE, "Sys 1132 prt",
0x8E, 0x8E, FALSE, "Sys console prt",
0x8F, 0x8F, FALSE, "Sys 2501 rdr",
0x90, 0x90, FALSE, "Sys 1442 rdr/pun",
0x91, 0x91, FALSE, "Sys 1134 paper tape",
0x92, 0x92, FALSE, "Sys kbd",
0x93, 0x93, FALSE, "Sys 2501/1442 conv",
0x94, 0x94, FALSE, "Sys 1134 conv",
0x95, 0x95, FALSE, "Sys kbd conv",
0x96, 0x96, FALSE, "Sys diskz",
0x97, 0x97, FALSE, "Sys disk1",
0x98, 0x98, FALSE, "Sys diskn",
0x99, 0x99, FALSE, "(primary print)",
0x9A, 0x9A, FALSE, "(primary input)",
0x9B, 0x9B, FALSE, "(primary input excl kbd)",
0x9C, 0x9C, FALSE, "(primary sys conv)",
0x9D, 0x9D, FALSE, "(primary conv excl kbd)",
0xA0, 0xA1, FALSE, "Core Image Loader",
0xB0, 0xCC, FALSE, "RPG",
0xCD, 0xCE, FALSE, "Dup Part 2",
0xCF, 0xF6, FALSE, "Macro Assembler",
0
};
void dump_slet (void)
{
int i, j, iphase, nsecs, sec, max_sec = 0;
char sstr[16], *smark;
showmajor("Sectors 3-5 - SLET");
for (i = 0; i < 3; i++) {
getsector(3+i, buf);
memmove(((WORD *) slet)+SECLEN*i, buf, SECLEN*sizeof(WORD));
}
printf("# PHID Addr Len Sector Secs\n");
printf("------------------------------------------\n");
for (i = 0; i < SLETLEN; i++) {
if (slet[i].phid == 0)
break;
sec = slet[i].sector;
iphase = (int) (signed short) slet[i].phid;
nsecs = (slet[i].nwords + SECLEN-1)/SECLEN;
if (sec & 0xF800) {
smark = "*";
sec &= 0x7FF;
}
else
smark = " ";
for (j = 0; sletinfo[j].pfrom != 0; j++)
if (sletinfo[j].pfrom <= iphase && sletinfo[j].pto >= iphase)
break;
sprintf(sstr, "(%d.%d)", sec / DSK_SECCYL, slet[i].sector % DSK_SECCYL);
printf("%3d %04x %4d %04x %04x %04x %s %-7s %3x",
i, slet[i].phid, iphase, slet[i].addr, slet[i].nwords, slet[i].sector, smark, sstr, nsecs);
if (iphase < 0)
iphase = -iphase;
if (sletinfo[j].pfrom == 0)
printf(" ???");
else if (! sletinfo[j].printed) {
printf(" %s", sletinfo[j].name);
sletinfo[j].printed = TRUE;
}
for (j = 0; j < i; j++) {
if (sec == (slet[j].sector & 0x7FF)) {
printf(" (same as %04x)", slet[j].phid);
break;
}
}
max_sec = MAX(max_sec, sec+nsecs-1); // find last sector used
putchar('\n');
if (i >= 15 && ! verbose) {
printf("...\n");
break;
}
}
}
int ascii_to_ebcdic_table[128] =
{
0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,
0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, 0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,
0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,
0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,
0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d,
0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,
0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,
};
int ebcdic_to_ascii (int ch)
{
int j;
for (j = 32; j < 128; j++)
if (ascii_to_ebcdic_table[j] == ch)
return j;
return '?';
}
#define HDR_LEN 120
void dump_hdng(void)
{
int i;
char str[HDR_LEN+1], *p = str;
showmajor("Sector 7 - Heading");
getsector(7, buf);
for (i = 0; i < (HDR_LEN/2); i++) {
*p++ = ebcdic_to_ascii((buf[i] >> 8) & 0xFF);
*p++ = ebcdic_to_ascii( buf[i] & 0xFF);
}
*p = '\0';
trim(str);
printf("%s\n", str);
}
BOOL mget (int offset, char *name)
{
char title[80];
if (dcom[offset] == 0)
return FALSE;
getsector(dcom[offset], buf);
sprintf(title, "Sector %x - %s", dcom[offset], name);
showmajor(title);
return TRUE;
}
void dump_scra (void)
{
if (! mget(SCRA, "SCRA"))
return;
dump(verbose ? SECLEN : 32);
}
void dump_let (void)
{
if (! mget(ULET, "LET"))
return;
}
void dump_flet (void)
{
if (! mget(FLET, "FLET"))
return;
}
void dump_cib (void)
{
if (! mget(CIBA, "CIB"))
return;
dump(verbose ? SECLEN : 32);
}
#define LFHD 5 // WORD COUNT OF LET/FLET HEADER PMN09970
#define LFEN 3 // NO OF WDS PER LET/FLET ENTRY PMN09980
#define SCTN 0 // RLTY ADDR OF LET/FLET SCTR NO. PMN09990
#define UAFX 1 // RLTV ADDR OF SCTR ADDR OF UA/FXA PMN10000
#define WDSA 3 // RLTV ADDR OF WDS AVAIL IN SCTR PMN10010
#define NEXT 4 // RLTV ADDR OF ADDR NEXT SCTR PMN10020
#define LFNM 0 // RLTV ADDR OF LET/FLET ENTRY NAME PMN10030
#define BLCT 2 // RLTV ADDR OF LET/FLET ENTRY DBCT PMN10040
void bail (char *fmt, ...)
{
va_list args;
va_start(args, fmt);
fprintf(stderr, fmt, args);
va_end(args);
putchar('\n');
exit(1);
}
// ---------------------------------------------------------------------------------
// trim - remove trailing whitespace from string s
// ---------------------------------------------------------------------------------
char *trim (char *s)
{
char *os = s, *nb;
for (nb = s-1; *s; s++)
if (*s > ' ')
nb = s;
nb[1] = '\0';
return os;
}
/* ------------------------------------------------------------------------
* lowcase - force a string to lowercase (ASCII)
* ------------------------------------------------------------------------ */
char *lowcase (char *str)
{
char *s;
for (s = str; *s; s++) {
if (*s >= 'A' && *s <= 'Z')
*s += 32;
}
return str;
}

175
Ibm1130/utils/diskview.mak Normal file
View file

@ -0,0 +1,175 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "diskview.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/diskview.exe $(OUTDIR)/diskview.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"diskview.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"diskview.bsc"
BSC32_SBRS= \
$(INTDIR)/diskview.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/diskview.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:no /PDB:$(OUTDIR)/"diskview.pdb" /MACHINE:I386\
/OUT:$(OUTDIR)/"diskview.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/diskview.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/diskview.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/diskview.exe $(OUTDIR)/diskview.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"diskview.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"diskview.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"diskview.bsc"
BSC32_SBRS= \
$(INTDIR)/diskview.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/diskview.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:yes /PDB:$(OUTDIR)/"diskview.pdb" /DEBUG /MACHINE:I386\
/OUT:$(OUTDIR)/"diskview.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/diskview.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/diskview.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\diskview.c
$(INTDIR)/diskview.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

47
Ibm1130/utils/makefile Normal file
View file

@ -0,0 +1,47 @@
# (This makefile is for operating systems other than Windows,
# or compilers other than Microsoft's. For MS builds, use the
# .mak files).
#
# CC Command
#
# Note: -O2 is sometimes broken in GCC when setjump/longjump is being
# used. Try -O2 only with released simulators.
#
CC = gcc -O0 -lm -I .
#CC = gcc -O2 -g -lm -I .
BIN =
IOLIB_DEP = util_io.c util_io.h
IOLIB_SRC = util_io.c
#
# Build everything
#
all : ${BIN}asm1130 ${BIN}bindump ${BIN}checkdisk \
${BIN}diskview ${BIN}mkboot ${BIN}viewdeck
#
# Individual builds
#
${BIN}asm1130 : asm1130.c ${IOLIB_DEP}
${CC} asm1130.c ${IOLIB_SRC} -o $@
${BIN}bindump : bindump.c ${IOLIB_DEP}
${CC} bindump.c ${IOLIB_SRC} -o $@
${BIN}checkdisk : checkdisk.c ${IOLIB_DEP}
${CC} checkdisk.c ${IOLIB_SRC} -o $@
${BIN}diskview : diskview.c ${IOLIB_DEP}
${CC} diskview.c ${IOLIB_SRC} -o $@
${BIN}mkboot : mkboot.c ${IOLIB_DEP}
${CC} mkboot.c ${IOLIB_SRC} -o $@
${BIN}viewdeck : viewdeck.c ${IOLIB_DEP}
${CC} viewdeck.c ${IOLIB_SRC} -o $@

706
Ibm1130/utils/mkboot.c Normal file
View file

@ -0,0 +1,706 @@
/*
* (C) Copyright 2002, Brian Knittel.
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
* usual yada-yada. Please keep this notice and the copyright in any distributions
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
*/
// ---------------------------------------------------------------------------------
// MKBOOT - reads card loader format cards and produces an absolute core image that
// can then be dumped out in 1130 IPL, 1800 IPL or Core Image loader formats.
//
// Usage: mkboot [-v] binfile outfile [1130|1800|core [loaddr [hiaddr [ident]]]]"
//
// Arguments:
// binfile - name of assembler output file (card loader format, absolute output)
// outfile - name of output file to create
// mode - output mode, default is 1130 IPL format
// loaddr - low address to dump. Default is lowest address loaded from binfile
// hiaddr - high address to dump. Defult is highest address loaded from binfile
// ident - ident string to write in last 8 columns. Omit when when writing an
// 1130 IPL card that requires all 80 columns of data.
//
// Examples:
// mkboot somefile.bin somefile.ipl 1130
//
// loads somefile.bin, writes object in 1130 IPL format to somefile.ipl
// Up to 80 columns will be written depending on what the object actually uses
//
// mkboot somefile.bin somefile.ipl 1130 0 48 SOMEF
//
// loads somefile.bin. Writes 72 columns (hex 48), with ident columns 73-80 = SOMEF001
//
// mkboot somefile.bin somefile.dat core 0 0 SOMEF001
//
// loads somefile.bin and writes a core image format deck with ident SOMEF001, SOMEF002, etc
//
// For other examples of usage, see MKDMS.BAT
//
// 1.00 - 2002Apr18 - first release. Tested only under Win32. The core image
// loader format is almost certainly wrong. Cannot handle
// relocatable input decks, but it works well enough to
// load DSYSLDR1 which is what we are after here.
// ---------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "util_io.h"
#ifndef TRUE
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif
#ifndef _WIN32
int strnicmp (char *a, char *b, int n);
int strcmpi (char *a, char *b);
#endif
#define BETWEEN(v,a,b) (((v) >= (a)) && ((v) <= (b)))
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
#define MAXADDR 4096
typedef enum {R_ABSOLUTE = 0, R_RELATIVE = 1, R_LIBF = 2, R_CALL = 3} RELOC;
typedef enum {B_1130, B_1800, B_CORE} BOOTMODE;
BOOL verbose = FALSE;
char *infile = NULL, *outfile = NULL;
BOOTMODE mode = B_1130;
int addr_from = 0, addr_to = 79;
int outcols = 0; // columns written in using card output
int maxiplcols = 80;
char cardid[9]; // characters used for IPL card ID
int pta = 0;
int load_low = 0x7FFFFFF;
int load_high = 0;
unsigned short mem[MAXADDR]; // small core!
// mkboot - load a binary object deck into core and dump requested bytes as a boot card
void bail (char *msg);
void verify_checksum(unsigned short *card);
char *upcase (char *str);
void unpack (unsigned short *card, unsigned short *buf);
void dump (char *fname);
void loaddata (char *fname);
void write_1130 (void);
void write_1800 (void);
void write_core (void);
void flushcard(void);
int ascii_to_hollerith (int ch);
void corecard_init (void);
void corecard_writecard (char *sbrk_text);
void corecard_writedata (void);
void corecard_flush (void);
void corecard_setorg (int neworg);
void corecard_writew (int word, RELOC relative);
void corecard_endcard (void);
char *fname = NULL;
FILE *fout;
int main (int argc, char **argv)
{
char *arg;
static char usestr[] = "Usage: mkboot [-v] binfile outfile [1130|1800|core [loaddr [hiaddr [ident]]]]";
int i, ano = 0, ok;
for (i = 1; i < argc; i++) {
arg = argv[i];
if (*arg == '-') {
arg++;
while (*arg) {
switch (*arg++) {
case 'v':
verbose = TRUE;
break;
default:
bail(usestr);
}
}
}
else {
switch (ano++) {
case 0:
infile = arg;
break;
case 1:
outfile = arg;
break;
case 2:
if (strcmp(arg, "1130") == 0) mode = B_1130;
else if (strcmp(arg, "1800") == 0) mode = B_1800;
else if (strcmpi(arg, "core") == 0) mode = B_CORE;
else bail(usestr);
break;
case 3:
if (strnicmp(arg, "0x", 2) == 0) ok = sscanf(arg+2, "%x", &addr_from);
else if (arg[0] == '/') ok = sscanf(arg+1, "%x", &addr_from);
else ok = sscanf(arg, "%d", &addr_from);
if (ok != 1) bail(usestr);
break;
case 4:
if (strnicmp(arg, "0x", 2) == 0) ok = sscanf(arg+2, "%x", &addr_to);
else if (arg[0] == '/') ok = sscanf(arg+1, "%x", &addr_to);
else ok = sscanf(arg, "%d", &addr_to);
if (ok != 1) bail(usestr);
break;
case 5:
strncpy(cardid, arg, 9);
cardid[8] = '\0';
upcase(cardid);
break;
default:
bail(usestr);
}
}
}
if (*cardid == '\0')
maxiplcols = (mode == B_1130) ? 80 : 72;
else {
while (strlen(cardid) < 8)
strcat(cardid, "0");
maxiplcols = 72;
}
loaddata(infile);
if (mode == B_1800)
write_1800();
else if (mode == B_CORE)
write_core();
else
write_1130();
return 0;
}
void write_1130 (void)
{
int addr;
unsigned short word;
if ((fout = fopen(outfile, "wb")) == NULL) {
perror(outfile);
exit(1);
}
for (addr = addr_from; addr <= addr_to; addr++) {
if (outcols >= maxiplcols)
flushcard();
word = mem[addr];
// if F or L bits are set, or if high 2 bits of displacement are unequal, it's bad
if ((word & 0x0700) || ! (((word & 0x00C0) == 0) || ((word & 0x00C0) == 0x00C0)))
printf("Warning: word %04x @ %04x may not IPL properly\n", word & 0xFFFF, addr);
word = ((word & 0xF800) >> 4) | (word & 0x7F); // convert to 1130 IPL format
putc((word & 0x000F) << 4, fout); // write the 12 bits in little-endian binary AABBCC00 as CC00 AABB
putc((word & 0x0FF0) >> 4, fout);
outcols++;
}
flushcard();
fclose(fout);
}
void write_1800 (void)
{
int addr;
unsigned short word;
if ((fout = fopen(outfile, "wb")) == NULL) {
perror(outfile);
exit(1);
}
for (addr = addr_from; addr <= addr_to; addr++) {
word = mem[addr];
if (outcols >= maxiplcols)
flushcard();
putc(0, fout);
putc(word & 0xFF, fout); // write the low 8 bits in little-endian binary
outcols++;
putc(0, fout);
putc((word >> 8) & 0xFF, fout); // write the high 8 bits in little-endian binary
outcols++;
}
flushcard();
fclose(fout);
}
void write_core (void)
{
int addr;
if ((fout = fopen(outfile, "wb")) == NULL) {
perror(outfile);
exit(1);
}
addr_from = load_low;
addr_to = load_high;
maxiplcols = 72;
corecard_init();
corecard_setorg(addr_from);
for (addr = addr_from; addr <= addr_to; addr++) {
corecard_writew(mem[addr], 0);
}
corecard_flush();
corecard_endcard();
fclose(fout);
}
void flushcard (void)
{
int i, hol, ndig;
char fmt[20], newdig[20];
if (outcols <= 0)
return; // nothing to flush
while (outcols < maxiplcols) { // pad to required number of columns with blanks (no punches)
putc(0, fout);
putc(0, fout);
outcols++;
}
if (*cardid) { // add label
for (i = 0; i < 8; i++) { // write label as specified
hol = ascii_to_hollerith(cardid[i] & 0x7F);
putc(hol & 0xFF, fout);
putc((hol >> 8) & 0xFF, fout);
}
ndig = 0; // count trailing digits in the label
for (i = 8; --i >= 0; ndig++)
if (! isdigit(cardid[i]))
break;
i++; // index of first digit in trailing sequence
if (ndig > 0) { // if any, increment them
sprintf(fmt, "%%0%dd", ndig); // make, e.g. %03d
sprintf(newdig, fmt, atoi(cardid+i)+1);
newdig[ndig] = '\0'; // clip if necessary
strcpy(cardid+i, newdig); // replace for next card's sequence number
}
}
outcols = 0;
}
void show_data (unsigned short *buf)
{
int i, n, jrel, rflag, nout, ch, reloc;
n = buf[2] & 0x00FF;
printf("%04x: ", buf[0]);
jrel = 3;
nout = 0;
rflag = buf[jrel++];
for (i = 0; i < n; i++) {
if (nout >= 8) {
rflag = buf[jrel++];
putchar('\n');
printf(" ");
nout = 0;
}
reloc = (rflag >> 14) & 0x03;
ch = (reloc == R_ABSOLUTE) ? ' ' :
(reloc == R_RELATIVE) ? 'R' :
(reloc == R_LIBF) ? 'L' : '@';
printf("%04x%c ", buf[9+i], ch);
rflag <<= 2;
nout++;
}
putchar('\n');
}
void loadcard (unsigned short *buf)
{
int addr, n, i;
addr = buf[0];
n = buf[2] & 0x00FF;
for (i = 0; i < n; i++) {
if (addr >= MAXADDR)
bail("Program doesn't fit into 4K");
mem[addr] = buf[9+i];
load_low = MIN(addr, load_low);
load_high = MAX(addr, load_high);
addr++;
}
}
void loaddata (char *fname)
{
FILE *fp;
BOOL first = TRUE;
unsigned short card[80], buf[54], cardtype;
if ((fp = fopen(fname, "rb")) == NULL) {
perror(fname);
exit(1);
}
if (verbose)
printf("\n%s:\n", fname);
while (fxread(card, sizeof(card[0]), 80, fp) > 0) {
unpack(card, buf);
verify_checksum(card);
cardtype = (buf[2] >> 8) & 0xFF;
if (cardtype == 1 && ! first) { // sector break
if (verbose)
printf("*SBRK\n");
continue;
}
else {
switch (cardtype) {
case 0x01:
if (verbose)
printf("*ABS\n");
break;
case 0x02:
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
bail("Data must be in absolute format");
break;
case 0x0F:
pta = buf[3]; // save program transfer address
if (verbose)
printf("*END\n");
break;
case 0x0A:
if (verbose)
show_data(buf);
loadcard(buf);
break;
default:
bail("Unexpected card type");
}
}
first = FALSE;
}
fclose(fp);
}
void bail (char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}
void unpack (unsigned short *card, unsigned short *buf)
{
int i, j;
unsigned short wd1, wd2, wd3, wd4;
for (i = j = 0; i < 54; i += 3, j += 4) {
wd1 = card[j];
wd2 = card[j+1];
wd3 = card[j+2];
wd4 = card[j+3];
buf[i ] = (wd1 & 0xFFF0) | ((wd2 >> 12) & 0x000F);
buf[i+1] = ((wd2 << 4) & 0xFF00) | ((wd3 >> 8) & 0x00FF);
buf[i+2] = ((wd3 << 8) & 0xF000) | ((wd4 >> 4) & 0x0FFF);
}
}
void verify_checksum (unsigned short *card)
{
// unsigned short sum;
if (card[1] == 0) // no checksum
return;
// if (sum != card[1])
// printf("Checksum %04x doesn't match card %04x\n", sum, card[1]);
}
typedef struct {
int hollerith;
char ascii;
} CPCODE;
static CPCODE cardcode_029[] =
{
0x0000, ' ',
0x8000, '&', // + in 026 Fortran
0x4000, '-',
0x2000, '0',
0x1000, '1',
0x0800, '2',
0x0400, '3',
0x0200, '4',
0x0100, '5',
0x0080, '6',
0x0040, '7',
0x0020, '8',
0x0010, '9',
0x9000, 'A',
0x8800, 'B',
0x8400, 'C',
0x8200, 'D',
0x8100, 'E',
0x8080, 'F',
0x8040, 'G',
0x8020, 'H',
0x8010, 'I',
0x5000, 'J',
0x4800, 'K',
0x4400, 'L',
0x4200, 'M',
0x4100, 'N',
0x4080, 'O',
0x4040, 'P',
0x4020, 'Q',
0x4010, 'R',
0x3000, '/',
0x2800, 'S',
0x2400, 'T',
0x2200, 'U',
0x2100, 'V',
0x2080, 'W',
0x2040, 'X',
0x2020, 'Y',
0x2010, 'Z',
0x0820, ':',
0x0420, '#', // = in 026 Fortran
0x0220, '@', // ' in 026 Fortran
0x0120, '\'',
0x00A0, '=',
0x0060, '"',
0x8820, 'c', // cent
0x8420, '.',
0x8220, '<', // ) in 026 Fortran
0x8120, '(',
0x80A0, '+',
0x8060, '|',
0x4820, '!',
0x4420, '$',
0x4220, '*',
0x4120, ')',
0x40A0, ';',
0x4060, 'n', // not
0x2820, 'x', // what?
0x2420, ',',
0x2220, '%', // ( in 026 Fortran
0x2120, '_',
0x20A0, '>',
0x2060, '>',
};
int ascii_to_hollerith (int ch)
{
int i;
for (i = 0; i < sizeof(cardcode_029) / sizeof(CPCODE); i++)
if (cardcode_029[i].ascii == ch)
return cardcode_029[i].hollerith;
return 0;
}
// ---------------------------------------------------------------------------------
// corecard - routines to write IBM 1130 Card object format
// ---------------------------------------------------------------------------------
unsigned short corecard[54]; // the 54 data words that can fit on a binary format card
int corecard_n = 0; // number of object words stored in corecard (0-45)
int corecard_seq = 1; // card output sequence number
int corecard_org = 0; // origin of current card-full
int corecard_maxaddr = 0;
BOOL corecard_first = TRUE; // TRUE when we're to write the program type card
// corecard_init - prepare a new object data output card
void corecard_init (void)
{
memset(corecard, 0, sizeof(corecard)); // clear card data
corecard_n = 0; // no data
corecard[0] = corecard_org; // store load address
corecard_maxaddr = MAX(corecard_maxaddr, corecard_org-1); // save highest address written-to (this may be a BSS)
}
// binard_writecard - emit a card. sbrk_text = NULL for normal data cards, points to comment text for sbrk card
void corecard_writecard (char *sbrk_text)
{
unsigned short binout[80];
int i, j;
for (i = j = 0; i < 54; i += 3, j += 4) {
binout[j ] = ( corecard[i] & 0xFFF0);
binout[j+1] = ((corecard[i] << 12) & 0xF000) | ((corecard[i+1] >> 4) & 0x0FF0);
binout[j+2] = ((corecard[i+1] << 8) & 0xFF00) | ((corecard[i+2] >> 8) & 0x00F0);
binout[j+3] = ((corecard[i+2] << 4) & 0xFFF0);
}
for (i = 0; i < 72; i++) {
putc(binout[i] & 0xFF, fout);
putc((binout[i] >> 8) & 0xFF, fout);
}
outcols = 72; // add the ident
flushcard();
}
// binard_writedata - emit an object data card
void corecard_writedata (void)
{
corecard[1] = 0; // checksum
corecard[2] = 0x0000 | corecard_n; // data card type + word count
corecard_writecard(FALSE); // emit the card
}
// corecard_flush - flush any pending binary data
void corecard_flush (void)
{
if (corecard_n > 0)
corecard_writedata();
corecard_init();
}
// corecard_setorg - set the origin
void corecard_setorg (int neworg)
{
corecard_org = neworg; // set origin for next card
corecard_flush(); // flush any current data & store origin
}
// corecard_writew - write a word to the current output card.
void corecard_writew (int word, RELOC relative)
{
if (corecard_n >= 50) // flush full card buffer (must be even)
corecard_flush();
corecard[3+corecard_n++] = word;
corecard_org++;
}
// corecard_endcard - write end of program card
void corecard_endcard (void)
{
corecard_flush();
corecard[0] = 0; // effective length: add 1 to max origin, then 1 more to round up
corecard[1] = 0;
corecard[2] = 0x8000; // they look for negative bit but all else must be zero
corecard[52] = 0xabcd; // index register 3 value, this is for fun
corecard[53] = pta; // hmmm
corecard_writecard(NULL);
}
/* ------------------------------------------------------------------------
* upcase - force a string to uppercase (ASCII)
* ------------------------------------------------------------------------ */
char *upcase (char *str)
{
char *s;
for (s = str; *s; s++) {
if (*s >= 'a' && *s <= 'z')
*s -= 32;
}
return str;
}
#ifndef _WIN32
int strnicmp (char *a, char *b, int n)
{
int ca, cb;
for (;;) {
if (--n < 0) // still equal after n characters? quit now
return 0;
if ((ca = *a) == 0) // get character, stop on null terminator
return *b ? -1 : 0;
if (ca >= 'a' && ca <= 'z') // fold lowercase to uppercase
ca -= 32;
cb = *b;
if (cb >= 'a' && cb <= 'z')
cb -= 32;
if ((ca -= cb) != 0) // if different, return comparison
return ca;
a++, b++;
}
}
int strcmpi (char *a, char *b)
{
int ca, cb;
for (;;) {
if ((ca = *a) == 0) // get character, stop on null terminator
return *b ? -1 : 0;
if (ca >= 'a' && ca <= 'z') // fold lowercase to uppercase
ca -= 32;
cb = *b;
if (cb >= 'a' && cb <= 'z')
cb -= 32;
if ((ca -= cb) != 0) // if different, return comparison
return ca;
a++, b++;
}
}
#endif

175
Ibm1130/utils/mkboot.mak Normal file
View file

@ -0,0 +1,175 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "mkboot.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/mkboot.exe $(OUTDIR)/mkboot.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"mkboot.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"mkboot.bsc"
BSC32_SBRS= \
$(INTDIR)/mkboot.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/mkboot.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:no /PDB:$(OUTDIR)/"mkboot.pdb" /MACHINE:I386\
/OUT:$(OUTDIR)/"mkboot.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/mkboot.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/mkboot.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/mkboot.exe $(OUTDIR)/mkboot.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"mkboot.pch" /Fo$(INTDIR)/ /Fd$(OUTDIR)/"mkboot.pdb"\
/c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"mkboot.bsc"
BSC32_SBRS= \
$(INTDIR)/mkboot.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/mkboot.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib /NOLOGO /SUBSYSTEM:console\
/INCREMENTAL:yes /PDB:$(OUTDIR)/"mkboot.pdb" /DEBUG /MACHINE:I386\
/OUT:$(OUTDIR)/"mkboot.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/mkboot.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/mkboot.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\mkboot.c
$(INTDIR)/mkboot.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

243
Ibm1130/utils/viewdeck.c Normal file
View file

@ -0,0 +1,243 @@
/* Simple program to display a binary card-image file in ASCII.
* We assume the deck was written with one card per 16-bit word, left-justified,
* and written in PC little-endian order
*
* (C) Copyright 2002, Brian Knittel.
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
* usual yada-yada. Please keep this notice and the copyright in any distributions
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
*/
#include <stdio.h>
#include <stdlib.h>
#include "util_io.h"
#define TRUE 1
#define FALSE 0
typedef int BOOL;
int hollerith_to_ascii (unsigned short h);
void bail (char *msg);
void format_coldstart (unsigned short *buf);
int main (int argc, char **argv)
{
FILE *fd;
char *fname = NULL, line[82], *arg;
BOOL coldstart = FALSE;
unsigned short buf[80];
int i, lastnb;
static char usestr[] =
"Usage: viewdeck [-c] deckfile\n"
"\n"
"-c: convert cold start card to 16-bit format as a C array initializer\n";
for (i = 1; i < argc; i++) { // process command line arguments
arg = argv[i];
if (*arg == '-') {
arg++;
while (*arg) {
switch (*arg++) {
case 'c':
coldstart = TRUE;
break;
default:
bail(usestr);
}
}
}
else if (fname == NULL) // first non-switch arg is file name
fname = arg;
else
bail(usestr); // there can be only one name
}
if (fname == NULL) // there must be a name
bail(usestr);
if ((fd = fopen(fname, "rb")) == NULL) {
perror(fname);
return 1;
}
while (fxread(buf, sizeof(short), 80, fd) == 80) {
if (coldstart) {
format_coldstart(buf);
break;
}
lastnb = -1;
for (i = 0; i < 80; i++) {
line[i] = hollerith_to_ascii(buf[i]);
if (line[i] > ' ')
lastnb = i;
}
line[++lastnb] = '\n';
line[++lastnb] = '\0';
fputs(line, stdout);
}
if (coldstart) {
if (fxread(buf, sizeof(short), 1, fd) == 1)
bail("Coldstart deck has more than one card");
}
fclose(fd);
return 0;
}
void format_coldstart (unsigned short *buf)
{
int i, nout = 0;
unsigned short word;
for (i = 0; i < 80; i++) {
word = buf[i]; // expand 12-bit card data to 16-bit instruction
word = (word & 0xF800) | ((word & 0x0400) ? 0x00C0 : 0x0000) | ((word & 0x03F0) >> 4);
if (nout >= 8) {
fputs(",\n", stdout);
nout = 0;
}
else if (i > 0)
fputs(", ", stdout);
printf("0x%04x", word);
nout++;
}
putchar('\n');
}
typedef struct {
unsigned short hollerith;
char ascii;
} CPCODE;
static CPCODE cardcode_029[] =
{
0x0000, ' ',
0x8000, '&', // + in 026 Fortran
0x4000, '-',
0x2000, '0',
0x1000, '1',
0x0800, '2',
0x0400, '3',
0x0200, '4',
0x0100, '5',
0x0080, '6',
0x0040, '7',
0x0020, '8',
0x0010, '9',
0x9000, 'A',
0x8800, 'B',
0x8400, 'C',
0x8200, 'D',
0x8100, 'E',
0x8080, 'F',
0x8040, 'G',
0x8020, 'H',
0x8010, 'I',
0x5000, 'J',
0x4800, 'K',
0x4400, 'L',
0x4200, 'M',
0x4100, 'N',
0x4080, 'O',
0x4040, 'P',
0x4020, 'Q',
0x4010, 'R',
0x3000, '/',
0x2800, 'S',
0x2400, 'T',
0x2200, 'U',
0x2100, 'V',
0x2080, 'W',
0x2040, 'X',
0x2020, 'Y',
0x2010, 'Z',
0x0820, ':',
0x0420, '#', // = in 026 Fortran
0x0220, '@', // ' in 026 Fortran
0x0120, '\'',
0x00A0, '=',
0x0060, '"',
0x8820, '\xA2', // cent, in MS-DOS encoding
0x8420, '.',
0x8220, '<', // ) in 026 Fortran
0x8120, '(',
0x80A0, '+',
0x8060, '|',
0x4820, '!',
0x4420, '$',
0x4220, '*',
0x4120, ')',
0x40A0, ';',
0x4060, '\xAC', // not, in MS-DOS encoding
0x2420, ',',
0x2220, '%', // ( in 026 Fortran
0x2120, '_',
0x20A0, '>',
0xB000, 'a',
0xA800, 'b',
0xA400, 'c',
0xA200, 'd',
0xA100, 'e',
0xA080, 'f',
0xA040, 'g',
0xA020, 'h',
0xA010, 'i',
0xD000, 'j',
0xC800, 'k',
0xC400, 'l',
0xC200, 'm',
0xC100, 'n',
0xC080, 'o',
0xC040, 'p',
0xC020, 'q',
0xC010, 'r',
0x6800, 's',
0x6400, 't',
0x6200, 'u',
0x6100, 'v',
0x6080, 'w',
0x6040, 'x',
0x6020, 'y',
0x6010, 'z', // these odd punch codes are used by APL:
0x1010, '\001', // no corresponding ASCII using ^A
0x0810, '\002', // SYN using ^B
0x0410, '\003', // no corresponding ASCII using ^C
0x0210, '\004', // PUNCH ON using ^D
0x0110, '\005', // READER STOP using ^E
0x0090, '\006', // UPPER CASE using ^F
0x0050, '\013', // EOT using ^K
0x0030, '\016', // no corresponding ASCII using ^N
0x1030, '\017', // no corresponding ASCII using ^O
0x0830, '\020', // no corresponding ASCII using ^P
};
int hollerith_to_ascii (unsigned short h)
{
int i;
h &= 0xFFF0;
for (i = 0; i < sizeof(cardcode_029) / sizeof(CPCODE); i++)
if (cardcode_029[i].hollerith == h)
return cardcode_029[i].ascii;
return '?';
}
void bail (char *msg)
{
fprintf(stderr, "%s\n", msg);
exit(1);
}

176
Ibm1130/utils/viewdeck.mak Normal file
View file

@ -0,0 +1,176 @@
# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
!IF "$(CFG)" == ""
CFG=Win32 Debug
!MESSAGE No configuration specified. Defaulting to Win32 Debug.
!ENDIF
!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE on this makefile
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "viewdeck.mak" CFG="Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF
################################################################################
# Begin Project
# PROP Target_Last_Scanned "Win32 Debug"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "WinRel"
# PROP BASE Intermediate_Dir "WinRel"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "WinRel"
# PROP Intermediate_Dir "WinRel"
OUTDIR=.\WinRel
INTDIR=.\WinRel
ALL : $(OUTDIR)/viewdeck.exe $(OUTDIR)/viewdeck.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"viewdeck.pch" /Fo$(INTDIR)/ /c
CPP_OBJS=.\WinRel/
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"viewdeck.bsc"
BSC32_SBRS= \
$(INTDIR)/viewdeck.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/viewdeck.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no\
/PDB:$(OUTDIR)/"viewdeck.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"viewdeck.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/viewdeck.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/viewdeck.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ELSEIF "$(CFG)" == "Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "WinDebug"
# PROP BASE Intermediate_Dir "WinDebug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "WinDebug"
# PROP Intermediate_Dir "WinDebug"
OUTDIR=.\WinDebug
INTDIR=.\WinDebug
ALL : $(OUTDIR)/viewdeck.exe $(OUTDIR)/viewdeck.bsc
$(OUTDIR) :
if not exist $(OUTDIR)/nul mkdir $(OUTDIR)
# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
# ADD CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c
CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE"\
/FR$(INTDIR)/ /Fp$(OUTDIR)/"viewdeck.pch" /Fo$(INTDIR)/\
/Fd$(OUTDIR)/"viewdeck.pdb" /c
CPP_OBJS=.\WinDebug/
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
BSC32_FLAGS=/nologo /o$(OUTDIR)/"viewdeck.bsc"
BSC32_SBRS= \
$(INTDIR)/viewdeck.sbr \
$(INTDIR)/util_io.sbr
$(OUTDIR)/viewdeck.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
$(BSC32_FLAGS) $(BSC32_SBRS)
<<
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386
LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes\
/PDB:$(OUTDIR)/"viewdeck.pdb" /DEBUG /MACHINE:I386\
/OUT:$(OUTDIR)/"viewdeck.exe"
DEF_FILE=
LINK32_OBJS= \
$(INTDIR)/viewdeck.obj \
$(INTDIR)/util_io.obj
$(OUTDIR)/viewdeck.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
$(LINK32_FLAGS) $(LINK32_OBJS)
<<
!ENDIF
.c{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cpp{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
.cxx{$(CPP_OBJS)}.obj:
$(CPP) $(CPP_PROJ) $<
################################################################################
# Begin Group "Source Files"
################################################################################
# Begin Source File
SOURCE=.\viewdeck.c
$(INTDIR)/viewdeck.obj : $(SOURCE) $(INTDIR)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\util_io.c
DEP_UTIL_=\
.\util_io.h
$(INTDIR)/util_io.obj : $(SOURCE) $(DEP_UTIL_) $(INTDIR)
# End Source File
# End Group
# End Project
################################################################################

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
02-Jul-04 RMS Fixed missing type in declaration
15-Jul-03 RMS Fixed signed/unsigned bug in get_imm 15-Jul-03 RMS Fixed signed/unsigned bug in get_imm
27-Feb-03 RMS Added relative addressing support 27-Feb-03 RMS Added relative addressing support
23-Dec-01 RMS Cloned from ID4 sources 23-Dec-01 RMS Cloned from ID4 sources
@ -50,7 +51,7 @@ extern uint32 *M;
t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf); t_stat fprint_sym_m (FILE *of, t_addr addr, t_value *val, t_bool cf);
t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf); t_stat parse_sym_m (char *cptr, t_addr addr, t_value *val, t_bool cf);
extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam); extern t_stat lp_load (FILE *fileref, char *cptr, char *fnam);
extern pt_dump (FILE *of, char *cptr, char *fnam); extern t_stat pt_dump (FILE *of, char *cptr, char *fnam);
/* SCP data structures and interface routines /* SCP data structures and interface routines

View file

@ -23,3 +23,4 @@ Bugs Found
15. UBA initialization reset the UBA itself 15. UBA initialization reset the UBA itself
16. RHCS1: writing IE cannot trigger an interrupt 16. RHCS1: writing IE cannot trigger an interrupt
17. Tape bootstrap was set to 800bpi instead of 1600bpi 17. Tape bootstrap was set to 800bpi instead of 1600bpi
18. FIXR off by 1 in testing for lower limit to process

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: PDP-10 Simulator Usage Subj: PDP-10 Simulator Usage
Date: 04-Apr-2004 Date: 15-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -208,10 +208,9 @@ The Unibus adapter has the following registers:
2.4 Front End (FE) 2.4 Front End (FE)
The front end is the system console. The keyboard input is unit 0, The front end is the system console. The keyboard input is unit 0,
the console output is unit 1. It supports two options: the console output is unit 1. It supports one option:
SET FE STOP halts the PDP-10 operating system SET FE STOP halts the PDP-10 operating system
SET FE CTLC simulates typing ^C
The front end has the following registers: The front end has the following registers:

View file

@ -25,6 +25,7 @@
fe KS10 console front end fe KS10 console front end
28-May-04 RMS Removed SET FE CTRL-C
29-Dec-03 RMS Added console backpressure support 29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
22-Dec-02 RMS Added break support 22-Dec-02 RMS Added break support
@ -43,7 +44,6 @@ t_stat fei_svc (UNIT *uptr);
t_stat feo_svc (UNIT *uptr); t_stat feo_svc (UNIT *uptr);
t_stat fe_reset (DEVICE *dptr); t_stat fe_reset (DEVICE *dptr);
t_stat fe_stop_os (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat fe_stop_os (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat fe_ctrl_c (UNIT *uptr, int32 val, char *cptr, void *desc);
/* FE data structures /* FE data structures
@ -70,7 +70,6 @@ REG fe_reg[] = {
MTAB fe_mod[] = { MTAB fe_mod[] = {
{ UNIT_DUMMY, 0, NULL, "STOP", &fe_stop_os }, { UNIT_DUMMY, 0, NULL, "STOP", &fe_stop_os },
{ UNIT_DUMMY, 0, NULL, "CTRL-C", &fe_ctrl_c },
{ 0 } }; { 0 } };
DEVICE fe_dev = { DEVICE fe_dev = {
@ -161,13 +160,3 @@ t_stat fe_stop_os (UNIT *uptr, int32 val, char *cptr, void *desc)
M[FE_SWITCH] = IOBA_RP; /* tell OS to stop */ M[FE_SWITCH] = IOBA_RP; /* tell OS to stop */
return SCPE_OK; return SCPE_OK;
} }
/* Enter control-C for Windoze */
t_stat fe_ctrl_c (UNIT *uptr, int32 val, char *cptr, void *desc)
{
fei_unit.buf = 003; /* control-C */
M[FE_CTYIN] = fei_unit.buf | FE_CVALID; /* put char in mem */
apr_flg = apr_flg | APRF_CON; /* interrupt KS10 */
return SCPE_OK;
}

View file

@ -26,6 +26,7 @@
The author gratefully acknowledges the help of Max Burnet, Megan Gentry, The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
and John Wilson in resolving questions about the PDP-11 and John Wilson in resolving questions about the PDP-11
28-May-04 RMS Added DHQ support
25-Jan-04 RMS Removed local debug logging support 25-Jan-04 RMS Removed local debug logging support
22-Dec-03 RMS Added second DEUNA/DELUA support 22-Dec-03 RMS Added second DEUNA/DELUA support
18-Oct-03 RMS Added DECtape off reel message 18-Oct-03 RMS Added DECtape off reel message
@ -74,6 +75,8 @@
#define UNIMEMSIZE 001000000 /* 2**18 */ #define UNIMEMSIZE 001000000 /* 2**18 */
#define UNIMASK (UNIMEMSIZE - 1) /* 2**18 - 1 */ #define UNIMASK (UNIMEMSIZE - 1) /* 2**18 - 1 */
#define IOPAGEBASE 017760000 /* 2**22 - 2**13 */ #define IOPAGEBASE 017760000 /* 2**22 - 2**13 */
#define IOPAGESIZE 000020000 /* 2**13 */
#define IOPAGEMASK (IOPAGESIZE - 1) /* 2**13 - 1 */
#define MAXMEMSIZE 020000000 /* 2**22 */ #define MAXMEMSIZE 020000000 /* 2**22 */
#define PAMASK (MAXMEMSIZE - 1) /* 2**22 - 1 */ #define PAMASK (MAXMEMSIZE - 1) /* 2**22 - 1 */
#define MEMSIZE (cpu_unit.capac) #define MEMSIZE (cpu_unit.capac)
@ -308,8 +311,9 @@ typedef struct fpac fpac_t;
/* IO parameters */ /* IO parameters */
#define DZ_MUXES 4 /* max # of muxes */ #define DZ_MUXES 4 /* max # of DZ muxes */
#define DZ_LINES 8 /* lines per mux */ #define DZ_LINES 8 /* lines per DZ mux */
#define VH_MUXES 4 /* max # of VH muxes */
#define MT_MAXFR (1 << 16) /* magtape max rec */ #define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */ #define AUTO_LNT 34 /* autoconfig ranks */
#define DIB_MAX 100 /* max DIBs */ #define DIB_MAX 100 /* max DIBs */
@ -359,6 +363,8 @@ typedef struct pdp_dib DIB;
#define IOLN_RQC 004 #define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC) #define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004 #define IOLN_RQD 004
#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */
#define IOLN_VH 020
#define IOBA_UBM (IOPAGEBASE + 010200) /* Unibus map */ #define IOBA_UBM (IOPAGEBASE + 010200) /* Unibus map */
#define IOLN_UBM (UBM_LNT_LW * sizeof (int32)) #define IOLN_UBM (UBM_LNT_LW * sizeof (int32))
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */ #define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
@ -446,7 +452,9 @@ typedef struct pdp_dib DIB;
#define INT_V_PTR 2 #define INT_V_PTR 2
#define INT_V_PTP 3 #define INT_V_PTP 3
#define INT_V_LPT 4 #define INT_V_LPT 4
#define INT_V_PIR4 5 #define INT_V_VHRX 5
#define INT_V_VHTX 6
#define INT_V_PIR4 7
#define INT_V_PIR3 0 /* BR3 */ #define INT_V_PIR3 0 /* BR3 */
#define INT_V_PIR2 0 /* BR2 */ #define INT_V_PIR2 0 /* BR2 */
@ -477,6 +485,8 @@ typedef struct pdp_dib DIB;
#define INT_TTI (1u << INT_V_TTI) #define INT_TTI (1u << INT_V_TTI)
#define INT_TTO (1u << INT_V_TTO) #define INT_TTO (1u << INT_V_TTO)
#define INT_LPT (1u << INT_V_LPT) #define INT_LPT (1u << INT_V_LPT)
#define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define INT_PIR4 (1u << INT_V_PIR4) #define INT_PIR4 (1u << INT_V_PIR4)
#define INT_PIR3 (1u << INT_V_PIR3) #define INT_PIR3 (1u << INT_V_PIR3)
#define INT_PIR2 (1u << INT_V_PIR2) #define INT_PIR2 (1u << INT_V_PIR2)
@ -504,6 +514,8 @@ typedef struct pdp_dib DIB;
#define IPL_TTI 4 #define IPL_TTI 4
#define IPL_TTO 4 #define IPL_TTO 4
#define IPL_LPT 4 #define IPL_LPT 4
#define IPL_VHRX 4
#define IPL_VHTX 4
#define IPL_PIR7 7 #define IPL_PIR7 7
#define IPL_PIR6 6 #define IPL_PIR6 6
@ -539,6 +551,8 @@ typedef struct pdp_dib DIB;
#define VEC_RY 0264 #define VEC_RY 0264
#define VEC_DZRX 0300 #define VEC_DZRX 0300
#define VEC_DZTX 0304 #define VEC_DZTX 0304
#define VEC_VHRX 0310
#define VEC_VHTX 0314
/* Autoconfigure ranks */ /* Autoconfigure ranks */
@ -548,6 +562,7 @@ typedef struct pdp_dib DIB;
#define RANK_XU 25 #define RANK_XU 25
#define RANK_RQ 26 #define RANK_RQ 26
#define RANK_TQ 30 #define RANK_TQ 30
#define RANK_VH 32
/* Interrupt macros */ /* Interrupt macros */

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: PDP-11 Simulator Usage Subj: PDP-11 Simulator Usage
Date: 04-Apr-2004 Date: 15-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -84,6 +84,7 @@ sim/pdp11/ pdp11_defs.h
pdp11_tc.c pdp11_tc.c
pdp11_tm.c pdp11_tm.c
pdp11_ts.c pdp11_ts.c
pdp11_vh.c
pdp11_xq.c pdp11_xq.c
pdp11_xu.c pdp11_xu.c
@ -103,6 +104,7 @@ LPT LP11 line printer
CLK line frequency clock CLK line frequency clock
PCLK KW11P programmable clock PCLK KW11P programmable clock
DZ DZ11 8-line terminal multiplexor (up to 4) DZ DZ11 8-line terminal multiplexor (up to 4)
VH DHQ11 8-line terminal multiplexor (up to 4)
RK RK11/RK05 cartridge disk controller with eight drives RK RK11/RK05 cartridge disk controller with eight drives
HK RK611/RK06(7) cartridge disk controller with eight drives HK RK611/RK06(7) cartridge disk controller with eight drives
RL RLV12/RL01(2) cartridge disk controller with four drives RL RLV12/RL01(2) cartridge disk controller with four drives
@ -144,12 +146,12 @@ The CPU options include CPU mapping configuration (18b Unibus, 22b Unibus
with RH70-style controllers, 22b Unibus with RH11 style controllers, and with RH70-style controllers, 22b Unibus with RH11 style controllers, and
22b Qbus), the CIS instruction set, and the size of main memory. 22b Qbus), the CIS instruction set, and the size of main memory.
SET CPU 18B 18b addressing, no I/O map SET CPU U18 Unibus, no I/O map, 18b addressing
SET CPU URH11 22b addresssing, Unibus I/O map, SET CPU URH11 Unibus, I/O map with 22b addressing,
18b mapped RH11 controller 18b mapped RH11 controller
SET CPU URH70 22b addressing, Unibus I/O map, SET CPU URH70 Unibus, I/O map with 22b addressing,
22b unmapped RH70 controller 22b unmapped RH70 controller
SET CPU 22B 22b addressing, no I/O map (Qbus) SET CPU Q22 Qbus, no I/O map, 22b addressing
SET CPU NOCIS disable CIS instructions (default) SET CPU NOCIS disable CIS instructions (default)
SET CPU CIS enable CIS instructions SET CPU CIS enable CIS instructions
SET CPU 16K set memory size = 16KB SET CPU 16K set memory size = 16KB
@ -395,12 +397,6 @@ implements these registers:
POS 32 number of characters input POS 32 number of characters input
TIME 24 keyboard polling interval TIME 24 keyboard polling interval
If the simulator is compiled under Windows Visual C++, typing ^C to the
terminal input causes a fatal run-time error. Use the following command
to simulate typing ^C:
SET TTI CTRL-C
2.3.4 DL11 Terminal Output (TTO) 2.3.4 DL11 Terminal Output (TTO)
The terminal output (TTO) writes to the simulator console window. It The terminal output (TTO) writes to the simulator console window. It
@ -499,81 +495,6 @@ up or down so that the clock tracks actual elapsed time. Operation at
the highest clock rate (100Khz) is not recommended. The programmable the highest clock rate (100Khz) is not recommended. The programmable
clock is disabled by default. clock is disabled by default.
2.3.8 DZ11 Terminal Multiplexor (DZ)
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
are supported. The number of lines can be changed with the command
SET DZ LINES=n set line count to n
The line count must be a multiple of 8, with a maximum of 32.
The DZ11 supports 8-bit input and output of characters. 8-bit output
may be incompatible with certain operating systems. The command
SET DZ 7B
forces output characters (only) to be masked to 7 bits.
The DZ11 supports logging on a per-line basis. The command
SET DZ LOG=line=filename
enables logging for the specified line to the indicated file. The
command
SET DZ NOLOG=line
disables logging for the specified line and closes any open log file.
Finally, the command
SHOW DZ LOG
displays logging information for all DZ lines.
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH {-am} DZ <port> set up listening port
where port is a decimal number between 1 and 65535 that is not being used
for other TCP/IP activities. The optional switch -m turns on the DZ11's
modem controls; the optional switch -a turns on active disconnects
(disconnect session if computer clears Data Terminal Ready). Without
modem control, the DZ behaves as though terminals were directly connected;
disconnecting the Telnet session does not cause any operating system-
visible change in line status.
Once the DZ is attached and the simulator is running, the DZ will listen
for connections on the specified port. It assumes that the incoming
connections are Telnet connections. The connection remains open until
disconnected by the simulated program, the Telnet client, a SET DZ
DISCONNECT command, or a DETACH DZ command.
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
The SHOW DZ STATISTICS command displays statistics for active connections.
The SET DZ DISCONNECT=linenumber disconnects the specified line.
The DZ11 implements these registers:
name size comments
CSR[0:3] 16 control/status register, boards 0..3
RBUF[0:3] 16 receive buffer, boards 0..3
LPR[0:3] 16 line parameter register, boards 0..3
TCR[0:3] 16 transmission control register, boards 0..3
MSR[0:3] 16 modem status register, boards 0..3
TDR[0:3] 16 transmit data register, boards 0..3
SAENB[0:3] 1 silo alarm enabled, boards 0..3
RXINT 4 receive interrupts, boards 3..0
TXINT 4 transmit interrupts, boards 3..0
MDMTCL 1 modem control enabled
AUTODS 1 autodisconnect enabled
The DZ11 does not support save and restore. All open connections are
lost when the simulator shuts down or the DZ is detached.
2.4 Floppy Disk Drives 2.4 Floppy Disk Drives
2.4.1 RX11/RX01 Floppy Disk (RX) 2.4.1 RX11/RX01 Floppy Disk (RX)
@ -1217,7 +1138,166 @@ Error handling is as follows:
OS I/O error fatal tape error OS I/O error fatal tape error
2.10 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB) 2.10 Communications Devices
2.10.1 DZ11 Terminal Multiplexor (DZ)
The DZ11 is an 8-line terminal multiplexor. Up to 4 DZ11's (32 lines)
are supported. The number of lines can be changed with the command
SET DZ LINES=n set line count to n
The line count must be a multiple of 8, with a maximum of 32.
The DZ11 supports 8-bit input and output of characters. 8-bit output
may be incompatible with certain operating systems. The command
SET DZ 7B
forces output characters (only) to be masked to 7 bits.
The DZ11 supports logging on a per-line basis. The command
SET DZ LOG=line=filename
enables logging for the specified line to the indicated file. The
command
SET DZ NOLOG=line
disables logging for the specified line and closes any open log file.
Finally, the command
SHOW DZ LOG
displays logging information for all DZ lines.
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH {-am} DZ <port> set up listening port
where port is a decimal number between 1 and 65535 that is not being used
for other TCP/IP activities. The optional switch -m turns on the DZ11's
modem controls; the optional switch -a turns on active disconnects
(disconnect session if computer clears Data Terminal Ready). Without
modem control, the DZ behaves as though terminals were directly connected;
disconnecting the Telnet session does not cause any operating system-
visible change in line status.
Once the DZ is attached and the simulator is running, the DZ will listen
for connections on the specified port. It assumes that the incoming
connections are Telnet connections. The connection remains open until
disconnected by the simulated program, the Telnet client, a SET DZ
DISCONNECT command, or a DETACH DZ command.
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
The SHOW DZ STATISTICS command displays statistics for active connections.
The SET DZ DISCONNECT=linenumber disconnects the specified line.
The DZ11 implements these registers:
name size comments
CSR[0:3] 16 control/status register, boards 0..3
RBUF[0:3] 16 receive buffer, boards 0..3
LPR[0:3] 16 line parameter register, boards 0..3
TCR[0:3] 16 transmission control register, boards 0..3
MSR[0:3] 16 modem status register, boards 0..3
TDR[0:3] 16 transmit data register, boards 0..3
SAENB[0:3] 1 silo alarm enabled, boards 0..3
RXINT 4 receive interrupts, boards 3..0
TXINT 4 transmit interrupts, boards 3..0
MDMTCL 1 modem control enabled
AUTODS 1 autodisconnect enabled
The DZ11 does not support save and restore. All open connections are
lost when the simulator shuts down or the DZ is detached.
2.10.2 DHQ11 Terminal Multiplexor (VH)
The DHQ11 is an 8-line terminal multiplexor for Qbus systems. Up
to 4 DHQ11's are supported.
The DHQ11 is a programmable asynchronous terminal multiplexor. It
has two programming modes: DHV11 and DHU11. The register sets are
compatible with these devices. For transmission, the DHQ11 can be
used in either DMA or programmed I/O mode. For reception, there
is a 256-entry FIFO for received characters, dataset status changes,
and diagnostic information, and a programmable input interrupt
timer (in DHU mode). The device supports 16-, 18-, and 22-bit
addressing. The DHQ11 can be programmed to filter and/or handle
XON/XOFF characters independently of the processor. The DHQ11
supports programmable bit width (between 5 and 8) for the input
and output of characters.
The DHQ11 has a rocker switch for determining the programming mode.
By default, the DHV11 mode is selected, though DHU11 mode is
recommended for applications that can support it. The VH controller
may be adjusted on a per controller basis as follows:
SET VHn DHU use the DHU programming mode and registers
SET VHn DHV use the DHV programming mode and registers
DMA output is supported. In a real DHQ11, DMA is not initiated
immediately upon receipt of TX.DMA.START but is dependent upon some
internal processes. The VH controller mimics this behavior by default.
It may be desirable to alter this and start immediately, though
this may not be compatible with all operating systems and diagnostics.
You can change the behavior of the VH controller as follows:
SET VHn NORMAL use normal DMA procedures
SET VHn FASTDMA set DMA to initiate immediately
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH VH <port> set up listening port
DETACH VH
where port is a decimal number between 1 and 65535 that is not
being used for other TCP/IP activities. This port is the point of
entry for al lines on all VH controllers.
Modem and auto-disconnect support may be set on an individual
controller basis. The SET MODEM command directs the controller to
report modem status changes to the computer. The SET HANGUP command
turns on active disconnects (disconnect session if computer clears
Data Terminal Ready).
SET VHn [NO]MODEM disable/enable modem control
SET VHn [NO]HANGUP disable/enable disconnect on DTR drop
Once the VH is attached and the simulator is running, the VH will
listen for connections on the specified port. It assumes that the
incoming connections are Telnet connections. The connection remains
open until disconnected by the simulated program, the Telnet client,
a SET VH DISCONNECT command, or a DETACH VH command.
The SHOW VH CONNECTIONS command displays the current connections to the VH.
The SHOW VH STATISTICS command displays statistics for active connections.
The SET VH DISCONNECT=linenumber disconnects the specified line.
The DHQ11 implements these registers, though not all can be examined
from SCP:
name size comments
CSR[0:3] 16 control/status register, boards 0..3
RBUF[0:3] 16 receive buffer, boards 0..3
LPR[0:3] 16 line parameter register, boards 0..3
RXINT 4 receive interrupts, boards 3..0
TXINT 4 transmit interrupts, boards 3..0
[more to be described...]
The DHQ11 does not support save and restore. All open connections
are lost when the simulator shuts down or the VH is detached.
2.11 Ethernet Controllers
2.11.1 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB)
The simulator implements two DELQA/DEQNA Qbus Ethernet controllers (XQ, The simulator implements two DELQA/DEQNA Qbus Ethernet controllers (XQ,
XQB). Initially, XQ is enabled, and XQB is disabled. Options allow XQB). Initially, XQ is enabled, and XQB is disabled. Options allow
@ -1301,10 +1381,10 @@ not limited to the ~1.5Mbit/sec of the real DEQNA/DELQA controllers,
nor the 10Mbit/sec of a standard Ethernet. Attach it to a Fast Ethernet nor the 10Mbit/sec of a standard Ethernet. Attach it to a Fast Ethernet
(100 Mbit/sec) card, and "Feel the Power!" :-) (100 Mbit/sec) card, and "Feel the Power!" :-)
2.11 DEUNA/DELUA Unibus Ethernet Controller (XU) 2.11.2 DEUNA/DELUA Unibus Ethernet Controller (XU)
XU simulates the DEUNA/DELUA Unibus Ethernet controller. THe current XU simulates the DEUNA/DELUA Unibus Ethernet controller. Its operation
implementation is a stub and is permanently disabled. is analagous to the DELQA/DEQNA controller.
2.12 Symbolic Display and Input 2.12 Symbolic Display and Input

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
28-May-04 RMS Revised I/O dispatching (from John Dundas)
25-Jan-04 RMS Removed local debug logging support 25-Jan-04 RMS Removed local debug logging support
21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls 21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls
21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner) 21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner)
@ -42,13 +43,13 @@
extern uint16 *M; extern uint16 *M;
extern int32 int_req[IPL_HLVL]; extern int32 int_req[IPL_HLVL];
extern int32 ub_map[UBM_LNT_LW]; extern int32 ub_map[UBM_LNT_LW];
extern UNIT cpu_unit;
extern int32 cpu_bme, cpu_18b, cpu_ubm; extern int32 cpu_bme, cpu_18b, cpu_ubm;
extern int32 trap_req, ipl; extern int32 trap_req, ipl;
extern int32 cpu_log; extern int32 cpu_log;
extern int32 autcon_enb; extern int32 autcon_enb;
extern FILE *sim_log; extern FILE *sim_log;
extern DEVICE *sim_devices[]; extern DEVICE *sim_devices[], cpu_dev;
extern UNIT cpu_unit;
int32 calc_ints (int32 nipl, int32 trq); int32 calc_ints (int32 nipl, int32 trq);
@ -57,7 +58,9 @@ extern DIB cpu3_dib, cpu4_dib, ubm_dib;
/* I/O data structures */ /* I/O data structures */
DIB *dib_tab[DIB_MAX]; /* run time DIBs */ static t_stat (*iodispR[IOPAGESIZE >> 1])(int32 *dat, int32 ad, int32 md);
static t_stat (*iodispW[IOPAGESIZE >> 1])(int32 dat, int32 ad, int32 md);
static DIB *iodibp[IOPAGESIZE >> 1];
int32 int_vec[IPL_HLVL][32]; /* int req to vector */ int32 int_vec[IPL_HLVL][32]; /* int req to vector */
@ -71,9 +74,9 @@ static DIB *std_dib[] = { /* standard DIBs */
&cpu4_dib, &cpu4_dib,
NULL }; NULL };
static int32 pirq_vloc[7] = { static const int32 pirq_bit[7] = {
IVCL (PIR7), IVCL (PIR6), IVCL (PIR5), IVCL (PIR4), INT_V_PIR1, INT_V_PIR2, INT_V_PIR3, INT_V_PIR4,
IVCL (PIR3), IVCL (PIR2), IVCL (PIR1) }; INT_V_PIR5, INT_V_PIR6, INT_V_PIR7 };
/* I/O page lookup and linkage routines /* I/O page lookup and linkage routines
@ -88,31 +91,27 @@ static int32 pirq_vloc[7] = {
t_stat iopageR (int32 *data, uint32 pa, int32 access) t_stat iopageR (int32 *data, uint32 pa, int32 access)
{ {
int32 i; int32 idx;
DIB *dibp;
t_stat stat; t_stat stat;
for (i = 0; dibp = dib_tab[i]; i++ ) { idx = (pa & IOPAGEMASK) >> 1;
if ((pa >= dibp->ba) && if (iodispR[idx]) {
(pa < (dibp->ba + dibp->lnt))) { stat = iodispR[idx] (data, pa, access);
stat = dibp->rd (data, pa, access); trap_req = calc_ints (ipl, trap_req);
trap_req = calc_ints (ipl, trap_req); return stat; }
return stat; } }
return SCPE_NXM; return SCPE_NXM;
} }
t_stat iopageW (int32 data, uint32 pa, int32 access) t_stat iopageW (int32 data, uint32 pa, int32 access)
{ {
int32 i; int32 idx;
DIB *dibp;
t_stat stat; t_stat stat;
for (i = 0; dibp = dib_tab[i]; i++ ) { idx = (pa & IOPAGEMASK) >> 1;
if ((pa >= dibp->ba) && if (iodispW[idx]) {
(pa < (dibp->ba + dibp->lnt))) { stat = iodispW[idx] (data, pa, access);
stat = dibp->wr (data, pa, access); trap_req = calc_ints (ipl, trap_req);
trap_req = calc_ints (ipl, trap_req); return stat; }
return stat; } }
return SCPE_NXM; return SCPE_NXM;
} }
@ -422,123 +421,126 @@ else { fprintf (st, "vector=%o", vec);
return SCPE_OK; return SCPE_OK;
} }
/* Test for conflict in device addresses */ /* Build dispatch tables */
t_bool dev_conflict (DIB *curr) t_stat build_dsp_tab (DEVICE *dptr, DIB *dibp)
{ {
uint32 i, end; uint32 i, idx;
DEVICE *dptr;
DIB *dibp;
end = curr->ba + curr->lnt - 1; /* get end */ if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ for (i = 0; i < dibp->lnt; i = i + 2) { /* create entries */
dibp = (DIB *) dptr->ctxt; /* get DIB */ idx = ((dibp->ba + i) & IOPAGEMASK) >> 1; /* index into disp */
if ((dibp == NULL) || (dibp == curr) || if ((iodispR[idx] && dibp->rd && /* conflict? */
(dptr->flags & DEV_DIS)) continue; (iodispR[idx] != dibp->rd)) ||
if (((curr->ba >= dibp->ba) && /* overlap start? */ (iodispW[idx] && dibp->wr &&
(curr->ba < (dibp->ba + dibp->lnt))) || (iodispW[idx] != dibp->wr))) {
((end >= dibp->ba) && /* overlap end? */ printf ("Device %s address conflict at %08o\n",
(end < (dibp->ba + dibp->lnt)))) { sim_dname (dptr), dibp->ba);
printf ("Device %s address conflict at %08o\n", if (sim_log) fprintf (sim_log,
sim_dname (dptr), dibp->ba); "Device %s address conflict at %08o\n",
if (sim_log) fprintf (sim_log, sim_dname (dptr), dibp->ba);
"Device %s address conflict at %08o\n", return SCPE_STOP;
sim_dname (dptr), dibp->ba); }
return TRUE; } } if (dibp->rd) iodispR[idx] = dibp->rd; /* set rd dispatch */
return FALSE; if (dibp->wr) iodispW[idx] = dibp->wr; /* set wr dispatch */
iodibp[idx] = dibp; /* remember DIB */
}
return SCPE_OK;
} }
/* Build interrupt tables */ /* Build interrupt tables */
t_bool build_int_vec (int32 vloc, int32 ivec, int32 (*iack)(void) ) t_stat build_int_vec (DEVICE *dptr, DIB *dibp)
{ {
int32 ilvl = vloc / 32; int32 i, idx, vec, ilvl, ibit;
int32 ibit = vloc % 32;
if (iack != NULL) { if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
if (int_ack[ilvl][ibit] && if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR;
(int_ack[ilvl][ibit] != iack)) return TRUE; for (i = 0; i < dibp->vnum; i++) { /* loop thru vec */
int_ack[ilvl][ibit] = iack; } idx = dibp->vloc + i; /* vector index */
else if (ivec != 0) { vec = dibp->vec? (dibp->vec + (i * 4)): 0; /* vector addr */
if (int_vec[ilvl][ibit] && ilvl = idx / 32;
(int_vec[ilvl][ibit] != ivec)) return TRUE; ibit = idx % 32;
int_vec[ilvl][ibit] = ivec; } if ((int_ack[ilvl][ibit] && dibp->ack[i] && /* conflict? */
return FALSE; (int_ack[ilvl][ibit] != dibp->ack[i])) ||
} (int_vec[ilvl][ibit] && vec &&
(int_vec[ilvl][ibit] != vec))) {
/* Build dib_tab from device list */ printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
t_stat build_dib_tab (int32 ubm) if (sim_log) fprintf (sim_log,
{ "Device %s interrupt slot conflict at %d\n",
int32 i, j, k; sim_dname (dptr), idx);
DEVICE *dptr; return SCPE_STOP;
DIB *dibp; }
if (dibp->ack[i]) int_ack[ilvl][ibit] = dibp->ack[i];
for (i = 0; i < IPL_HLVL; i++) { /* clear int tables */ else if (vec) int_vec[ilvl][ibit] = vec;
for (j = 0; j < 32; j++) { }
int_vec[i][j] = 0;
int_ack[i][j] = NULL; } }
for (i = j = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR;
for (k = 0; k < dibp->vnum; k++) { /* loop thru vec */
if (build_int_vec (dibp->vloc + k, /* add vector */
dibp->vec + (k * 4), dibp->ack[k])) {
printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), dibp->vloc + k);
if (sim_log) fprintf (sim_log,
"Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), dibp->vloc + k);
return SCPE_IERR; } }
if (dibp->lnt != 0) { /* I/O addresses? */
dib_tab[j++] = dibp; /* add DIB to dib_tab */
if (j >= DIB_MAX) return SCPE_IERR; } /* too many? */
} /* end if enabled */
} /* end for */
for (i = 0; (dibp = std_dib[i]) != NULL; i++) { /* loop thru std */
dib_tab[j++] = dibp; /* add to dib_tab */
if (j >= DIB_MAX) return SCPE_IERR; } /* too many? */
if (ubm) { /* Unibus map? */
dib_tab[j++] = &ubm_dib; /* add to dib_tab */
if (j >= DIB_MAX) return SCPE_IERR; } /* too many? */
dib_tab[j] = NULL; /* end with NULL */
for (i = 0; i < 7; i++) /* add PIRQ intr */
build_int_vec (pirq_vloc[i], VEC_PIRQ, NULL);
for (i = 0; (dibp = dib_tab[i]) != NULL; i++) { /* test built dib_tab */
if (dev_conflict (dibp)) {
return SCPE_STOP; } } /* for conflicts */
return SCPE_OK; return SCPE_OK;
} }
/* Show dib_tab */ /* Build tables from device list */
t_stat build_dib_tab (int32 ubm)
{
int32 i, j;
DEVICE *dptr;
DIB *dibp;
t_stat r;
for (i = 0; i < IPL_HLVL; i++) { /* clear intr tab */
for (j = 0; j < 32; j++) {
int_vec[i][j] = 0;
int_ack[i][j] = NULL; } }
for (i = 0; i < (IOPAGESIZE >> 1); i++) { /* clear dispatch tab */
iodispR[i] = NULL;
iodispW[i] = NULL;
iodibp[i] = NULL; }
for (i = 0; i < 7; i++) /* seed PIRQ intr */
int_vec[i + 1][pirq_bit[i]] = VEC_PIRQ;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (r = build_int_vec (dptr, dibp)) /* add to intr tab */
return r;
if (r = build_dsp_tab (dptr, dibp)) /* add to dispatch tab */
return r;
} /* end if enabled */
} /* end for */
for (i = 0; std_dib[i] != NULL; i++) { /* loop thru std */
if (r = build_dsp_tab (&cpu_dev, std_dib[i])) /* add to dispatch tab */
return r;
}
if (ubm) { /* Unibus map? */
if (r = build_dsp_tab (&cpu_dev, &ubm_dib)) /* add to dispatch tab */
return r;
}
return SCPE_OK;
}
/* Show IO space */
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc) t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc)
{ {
int32 i, j, done = 0; uint32 i, j;
DEVICE *dptr; DEVICE *dptr;
DIB *dibt; DIB *dibp;
build_dib_tab (cpu_ubm); /* build table */ if (build_dib_tab (cpu_ubm)) return SCPE_OK; /* build IO page */
while (done == 0) { /* sort ascending */ for (i = 0, dibp = NULL; i < (IOPAGESIZE >> 1); i++) { /* loop thru entries */
done = 1; /* assume done */ if (iodibp[i] && (iodibp[i] != dibp)) { /* new block? */
for (i = 0; dib_tab[i + 1] != NULL; i++) { /* check table */ dibp = iodibp[i]; /* DIB for block */
if (dib_tab[i]->ba > dib_tab[i + 1]->ba) { /* out of order? */ for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) {
dibt = dib_tab[i]; /* interchange */ if (((DIB*) sim_devices[j]->ctxt) == dibp) {
dib_tab[i] = dib_tab[i + 1]; dptr = sim_devices[j]; /* locate device */
dib_tab[i + 1] = dibt; break;
done = 0; } } /* not done */ } /* end if */
} /* end while */ } /* end for j */
for (i = 0; dib_tab[i] != NULL; i++) { /* print table */ fprintf (st, "%08o - %08o%c\t%s\n", /* print block entry */
for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) { dibp->ba, dibp->ba + dibp->lnt - 1,
if (((DIB*) sim_devices[j]->ctxt) == dib_tab[i]) {
dptr = sim_devices[j];
break; } }
fprintf (st, "%08o - %08o%c\t%s\n", dib_tab[i]->ba,
dib_tab[i]->ba + dib_tab[i]->lnt - 1,
(dptr && (dptr->flags & DEV_FLTA))? '*': ' ', (dptr && (dptr->flags & DEV_FLTA))? '*': ' ',
dptr? sim_dname (dptr): "CPU"); dptr? sim_dname (dptr): "CPU");
} } /* end if */
} /* end for i */
return SCPE_OK; return SCPE_OK;
} }
@ -593,7 +595,7 @@ struct auto_con auto_tab[AUTO_LNT + 1] = {
{ 0xf, 0x3 }, /* VS100 */ { 0xf, 0x3 }, /* VS100 */
{ 0x3, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_TQ, { "TQ", "TQB" } }, { 0x3, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_TQ, { "TQ", "TQB" } },
{ 0xf, 0x7 }, /* KMV11 */ { 0xf, 0x7 }, /* KMV11 */
{ 0xf, 0x7 }, /* DHU11/DHQ11 */ { 0x1f, 0x7, AUTO_VEC, VH_MUXES, 0, { "VH" } }, /* DHU11/DHQ11 */
{ 0x1f, 0x7 }, /* DMZ32 */ { 0x1f, 0x7 }, /* DMZ32 */
{ 0x1f, 0x7 }, /* CP132 */ { 0x1f, 0x7 }, /* CP132 */

View file

@ -26,6 +26,7 @@
tti,tto DL11 terminal input/output tti,tto DL11 terminal input/output
clk KW11L line frequency clock clk KW11L line frequency clock
28-May-04 RMS Removed SET TTI CTRL-C
29-Dec-03 RMS Added console backpressure support 29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
01-Mar-03 RMS Added SET/SHOW CLOCK FREQ, SET TTI CTRL-C 01-Mar-03 RMS Added SET/SHOW CLOCK FREQ, SET TTI CTRL-C
@ -80,7 +81,6 @@ t_stat tto_rd (int32 *data, int32 PA, int32 access);
t_stat tto_wr (int32 data, int32 PA, int32 access); t_stat tto_wr (int32 data, int32 PA, int32 access);
t_stat tto_svc (UNIT *uptr); t_stat tto_svc (UNIT *uptr);
t_stat tto_reset (DEVICE *dptr); t_stat tto_reset (DEVICE *dptr);
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat clk_rd (int32 *data, int32 PA, int32 access); t_stat clk_rd (int32 *data, int32 PA, int32 access);
t_stat clk_wr (int32 data, int32 PA, int32 access); t_stat clk_wr (int32 data, int32 PA, int32 access);
@ -115,8 +115,6 @@ REG tti_reg[] = {
MTAB tti_mod[] = { MTAB tti_mod[] = {
{ UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode }, { UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode }, { UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ MTAB_XTD|MTAB_VDV|MTAB_VUN, 0, NULL, "CTRL-C",
&tti_set_ctrlc, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, { MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL }, NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
@ -267,18 +265,6 @@ CLR_INT (TTI);
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */ sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} }
/* Set control-C */
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr) return SCPE_ARG;
uptr->buf = 003;
uptr->pos = uptr->pos + 1;
tti_csr = tti_csr | CSR_DONE;
if (tti_csr & CSR_IE) SET_INT (TTI);
return SCPE_OK;
}
/* Terminal output address routines */ /* Terminal output address routines */

View file

@ -57,6 +57,7 @@ extern DEVICE tti_dev, tto_dev;
extern DEVICE lpt_dev; extern DEVICE lpt_dev;
extern DEVICE clk_dev, pclk_dev; extern DEVICE clk_dev, pclk_dev;
extern DEVICE dz_dev; extern DEVICE dz_dev;
extern DEVICE vh_dev;
extern DEVICE rk_dev, rl_dev; extern DEVICE rk_dev, rl_dev;
extern DEVICE hk_dev; extern DEVICE hk_dev;
extern DEVICE rx_dev, ry_dev; extern DEVICE rx_dev, ry_dev;
@ -98,6 +99,7 @@ DEVICE *sim_devices[] = {
&clk_dev, &clk_dev,
&pclk_dev, &pclk_dev,
&dz_dev, &dz_dev,
&vh_dev,
&rk_dev, &rk_dev,
&rl_dev, &rl_dev,
&hk_dev, &hk_dev,

View file

@ -25,6 +25,8 @@
tq TQK50 tape controller tq TQK50 tape controller
12-Jun-04 RMS Fixed bug in reporting write protect (reported by Lyle Bickley)
18-Apr-04 RMS Fixed TQK70 media ID and model byte (found by Robert Schaffrath)
26-Mar-04 RMS Fixed warnings with -std=c99 26-Mar-04 RMS Fixed warnings with -std=c99
25-Jan-04 RMS Revised for device debug support 25-Jan-04 RMS Revised for device debug support
19-May-03 RMS Revised for new conditional compilation scheme 19-May-03 RMS Revised for new conditional compilation scheme
@ -87,7 +89,7 @@ extern int32 cpu_18b, cpu_ubm;
#define pktq u4 /* packet queue */ #define pktq u4 /* packet queue */
#define uf buf /* settable unit flags */ #define uf buf /* settable unit flags */
#define objp wait /* object position */ #define objp wait /* object position */
#define TQ_WPH(u) (sim_tape_wrp (u)) #define TQ_WPH(u) ((sim_tape_wrp (u))? UF_WPH: 0)
#define CST_S1 0 /* init stage 1 */ #define CST_S1 0 /* init stage 1 */
#define CST_S1_WR 1 /* stage 1 wrap */ #define CST_S1_WR 1 /* stage 1 wrap */
@ -144,8 +146,8 @@ struct tqpkt {
#define TQ7_TYPE 1 /* TK70 */ #define TQ7_TYPE 1 /* TK70 */
#define TQ7_UQPM 14 /* UQ port ID */ #define TQ7_UQPM 14 /* UQ port ID */
#define TQ7_CMOD 14 /* ctrl ID */ #define TQ7_CMOD 14 /* ctrl ID */
#define TQ7_UMOD 11 /* unit ID */ #define TQ7_UMOD 14 /* unit ID */
#define TQ7_MED 0x6A68B046 /* media ID */ #define TQ7_MED 0x6D68B046 /* media ID */
#define TQ7_CREV ((1 << 8) | 5) /* ctrl revs */ #define TQ7_CREV ((1 << 8) | 5) /* ctrl revs */
#define TQ7_FREV 0 /* formatter revs */ #define TQ7_FREV 0 /* formatter revs */
#define TQ7_UREV 0 /* unit revs */ #define TQ7_UREV 0 /* unit revs */

1367
PDP11/pdp11_vh.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: 18b PDP Simulator Usage Subj: 18b PDP Simulator Usage
Date: 4-Apr-2004 Date: 15-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -416,12 +416,6 @@ implements these registers:
POS 32 number of characters input POS 32 number of characters input
TIME 24 keyboard polling interval TIME 24 keyboard polling interval
If the simulator is debugged under Windows Visual C++, typing ^C to the
terminal input causes a fatal run-time error. Use the following command
to simulate typing ^C:
SET TTI CTRL-C
2.3.4 Terminal Output (TTO) 2.3.4 Terminal Output (TTO)
The terminal output (TTO) writes to the simulator console window. It The terminal output (TTO) writes to the simulator console window. It

View file

@ -25,6 +25,8 @@
fpp PDP-15 floating point processor fpp PDP-15 floating point processor
10-Apr-04 RMS JEA is 15b not 18b
The FP15 instruction format is: The FP15 instruction format is:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
@ -168,7 +170,6 @@ void dp_swap (UFP *a, UFP *b);
extern t_stat Read (int32 ma, int32 *dat, int32 cyc); extern t_stat Read (int32 ma, int32 *dat, int32 cyc);
extern t_stat Write (int32 ma, int32 dat, int32 cyc); extern t_stat Write (int32 ma, int32 dat, int32 cyc);
extern t_stat Ia (int32 ma, int32 *ea, t_bool jmp);
extern int32 Incr_addr (int32 addr); extern int32 Incr_addr (int32 addr);
extern int32 Jms_word (int32 t); extern int32 Jms_word (int32 t);
@ -195,7 +196,7 @@ REG fpp_reg[] = {
{ FLDATA (FGUARD, fguard, 0) }, { FLDATA (FGUARD, fguard, 0) },
{ ORDATA (FMQH, fmq.hi, 17) }, { ORDATA (FMQH, fmq.hi, 17) },
{ ORDATA (FMQL, fmq.lo, 18) }, { ORDATA (FMQL, fmq.lo, 18) },
{ ORDATA (JEA, jea, 18) }, { ORDATA (JEA, jea, 15) },
{ FLDATA (STOP_FPP, stop_fpp, 0) }, { FLDATA (STOP_FPP, stop_fpp, 0) },
{ NULL } }; { NULL } };
@ -314,7 +315,7 @@ case FOP_JEA: /* JEA */
else { /* no, load */ else { /* no, load */
if (sta = Read (ar, &dat, RD)) break; if (sta = Read (ar, &dat, RD)) break;
fguard = (dat >> JEA_V_GUARD) & 1; fguard = (dat >> JEA_V_GUARD) & 1;
jea = dat; } jea = dat & JEA_EAMASK; }
break; break;
case FOP_ADD: /* add */ case FOP_ADD: /* add */

View file

@ -29,6 +29,7 @@
tto teleprinter tto teleprinter
clk clock clk clock
28-May-04 RMS Removed SET TTI CTRL-C
16-Feb-04 RMS Fixed bug in hardware read-in mode bootstrap 16-Feb-04 RMS Fixed bug in hardware read-in mode bootstrap
14-Jan-04 RMS Revised IO device call interface 14-Jan-04 RMS Revised IO device call interface
CAF does not turn off the clock CAF does not turn off the clock
@ -37,7 +38,7 @@
Added hardware read-in mode support for PDP-7/9/15 Added hardware read-in mode support for PDP-7/9/15
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
14-Mar-03 RMS Clean up flags on detach 14-Mar-03 RMS Clean up flags on detach
01-Mar-03 RMS Added SET/SHOW CLK FREQ support, SET TTI CTRL-C support 01-Mar-03 RMS Added SET/SHOW CLK freq, SET TTI CTRL-C
22-Dec-02 RMS Added break support 22-Dec-02 RMS Added break support
01-Nov-02 RMS Added 7B/8B support to terminal 01-Nov-02 RMS Added 7B/8B support to terminal
05-Oct-02 RMS Added DIBs, device number support, IORS call 05-Oct-02 RMS Added DIBs, device number support, IORS call
@ -106,7 +107,6 @@ t_stat ptr_detach (UNIT *uptr);
t_stat ptp_detach (UNIT *uptr); t_stat ptp_detach (UNIT *uptr);
t_stat ptr_boot (int32 unitno, DEVICE *dptr); t_stat ptr_boot (int32 unitno, DEVICE *dptr);
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat clk_set_freq (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat clk_set_freq (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat clk_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat clk_show_freq (FILE *st, UNIT *uptr, int32 val, void *desc);
@ -292,7 +292,6 @@ MTAB tti_mod[] = {
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode }, { UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ UNIT_HDX, 0 , "full duplex", "FDX", NULL }, { UNIT_HDX, 0 , "full duplex", "FDX", NULL },
{ UNIT_HDX, UNIT_HDX, "half duplex", "HDX", NULL }, { UNIT_HDX, UNIT_HDX, "half duplex", "HDX", NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VUN, 0, NULL, "CTRL-C", &tti_set_ctrlc, NULL, NULL },
#endif #endif
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_devno, NULL }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_devno, NULL },
{ 0 } }; { 0 } };

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: PDP-8 Simulator Usage Subj: PDP-8 Simulator Usage
Date: 15-Feb-2004 Date: 15-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -305,12 +305,6 @@ implements these registers:
POS 32 number of characters input POS 32 number of characters input
TIME 24 keyboard polling interval TIME 24 keyboard polling interval
If the simulator is compiled under Windows Visual C++, typing ^C to the
terminal input causes a fatal run-time error. Use the following command
to simulate typing ^C:
SET TTI CTRL-C
2.3.4 KL8E Terminal Output (TTO) 2.3.4 KL8E Terminal Output (TTO)
The terminal output (TTO) writes to the simulator console window. It The terminal output (TTO) writes to the simulator console window. It

View file

@ -25,6 +25,7 @@
tti,tto KL8E terminal input/output tti,tto KL8E terminal input/output
28-May-04 RMS Removed SET TTI CTRL-C
29-Dec-03 RMS Added console output backpressure support 29-Dec-03 RMS Added console output backpressure support
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
02-Mar-02 RMS Added SET TTI CTRL-C 02-Mar-02 RMS Added SET TTI CTRL-C
@ -51,7 +52,6 @@ t_stat tti_svc (UNIT *uptr);
t_stat tto_svc (UNIT *uptr); t_stat tto_svc (UNIT *uptr);
t_stat tti_reset (DEVICE *dptr); t_stat tti_reset (DEVICE *dptr);
t_stat tto_reset (DEVICE *dptr); t_stat tto_reset (DEVICE *dptr);
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat tty_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc);
/* TTI data structures /* TTI data structures
@ -80,7 +80,6 @@ MTAB tti_mod[] = {
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode }, { UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode }, { UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode }, { UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ MTAB_XTD|MTAB_VDV|MTAB_VUN, 0, NULL, "CTRL-C", &tti_set_ctrlc, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_dev, NULL }, { MTAB_XTD|MTAB_VDV, 0, "DEVNO", NULL, NULL, &show_dev, NULL },
{ 0 } }; { 0 } };
@ -186,18 +185,6 @@ int_enable = int_enable | INT_TTI; /* set enable */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */ sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} }
/* Set control-C */
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr) return SCPE_ARG;
uptr->buf = (uptr->flags & UNIT_KSR)? 0203: 0003;
uptr->pos = uptr->pos + 1;
dev_done = dev_done | INT_TTI; /* set done */
int_req = INT_UPDATE; /* update interrupts */
return SCPE_OK;
}
/* Terminal output: IOT routine */ /* Terminal output: IOT routine */

View file

@ -25,6 +25,8 @@
cpu CVAX central processor cpu CVAX central processor
28-Jun-04 RMS Fixed bug in DIVBx, DIVWx (reported by Peter Trimmel)
18-Apr-04 RMS Added octaword macros
25-Jan-04 RMS Removed local debug logging support 25-Jan-04 RMS Removed local debug logging support
RMS,MP Added extended physical memory support RMS,MP Added extended physical memory support
31-Dec-03 RMS Fixed bug in set_cpu_hist 31-Dec-03 RMS Fixed bug in set_cpu_hist
@ -155,7 +157,7 @@
#define UNIT_MSIZE (1u << UNIT_V_MSIZE) #define UNIT_MSIZE (1u << UNIT_V_MSIZE)
#define GET_CUR acc = ACC_MASK (PSL_GETCUR (PSL)) #define GET_CUR acc = ACC_MASK (PSL_GETCUR (PSL))
#define OPND_SIZE 10 #define OPND_SIZE 20
#define op0 opnd[0] #define op0 opnd[0]
#define op1 opnd[1] #define op1 opnd[1]
#define op2 opnd[2] #define op2 opnd[2]
@ -167,6 +169,7 @@
#define op8 opnd[8] #define op8 opnd[8]
#define CHECK_FOR_PC if (rn == nPC) RSVD_ADDR_FAULT #define CHECK_FOR_PC if (rn == nPC) RSVD_ADDR_FAULT
#define CHECK_FOR_SP if (rn >= nSP) RSVD_ADDR_FAULT #define CHECK_FOR_SP if (rn >= nSP) RSVD_ADDR_FAULT
#define CHECK_FOR_AP if (rn >= nAP) RSVD_ADDR_FAULT
#define RECW(l) ((l) << 4) | rn #define RECW(l) ((l) << 4) | rn
#define WRITE_B(r) if (spec > (GRN | nPC)) Write (va, r, L_BYTE, WA); \ #define WRITE_B(r) if (spec > (GRN | nPC)) Write (va, r, L_BYTE, WA); \
else R[rn] = (R[rn] & ~BMASK) | ((r) & BMASK) else R[rn] = (R[rn] & ~BMASK) | ((r) & BMASK)
@ -174,11 +177,24 @@
else R[rn] = (R[rn] & ~WMASK) | ((r) & WMASK) else R[rn] = (R[rn] & ~WMASK) | ((r) & WMASK)
#define WRITE_L(r) if (spec > (GRN | nPC)) Write (va, r, L_LONG, WA); \ #define WRITE_L(r) if (spec > (GRN | nPC)) Write (va, r, L_LONG, WA); \
else R[rn] = (r) else R[rn] = (r)
#define WRITE_Q(rl,rh) if (spec > (GRN | nPC)) { \ #define WRITE_Q(rl,rh) if (spec > (GRN | nPC)) { \
if (Test (va + 7, WA, &mstat) >= 0) \ if (Test (va + 7, WA, &mstat) >= 0) \
Write (va, rl, L_LONG, WA); \ Write (va, rl, L_LONG, WA); \
Write (va + 4, rh, L_LONG, WA); } \ Write (va + 4, rh, L_LONG, WA); } \
else { R[rn] = rl; R[rnplus1] = rh; } else { \
R[rn] = rl; \
R[rnplus1] = rh; }
#define WRITE_O(rl,rm2,rm1,rh) if (spec > (GRN | nPC)) { \
if (Test (va + 15, WA, &mstat) >= 0) \
Write (va, rl, L_LONG, WA); \
Write (va + 4, rm2, L_LONG, WA); \
Write (va + 8, rm1, L_LONG, WA); \
Write (va + 12, rh, L_LONG, WA); } \
else { \
R[rn] = rl; \
R[(rn + 1) & 0xF] = rm2; \
R[(rn + 2) & 0xF] = rm1; \
R[(rn + 3) & 0xF] = rh; }
#define HIST_MIN 128 #define HIST_MIN 128
#define HIST_MAX 65536 #define HIST_MAX 65536
@ -1343,6 +1359,7 @@ case DIVB2: case DIVB3:
else { else {
r = SXTB (op1) / SXTB (op0); /* ok, divide */ r = SXTB (op1) / SXTB (op0); /* ok, divide */
temp = 0; } temp = 0; }
r = r & BMASK; /* mask to result */
WRITE_B (r); /* write result */ WRITE_B (r); /* write result */
CC_IIZZ_B (r); /* set cc's */ CC_IIZZ_B (r); /* set cc's */
cc = cc | temp; /* error? set V */ cc = cc | temp; /* error? set V */
@ -1359,6 +1376,7 @@ case DIVW2: case DIVW3:
else { else {
r = SXTW (op1) / SXTW (op0); /* ok, divide */ r = SXTW (op1) / SXTW (op0); /* ok, divide */
temp = 0; } temp = 0; }
r = r & WMASK; /* mask to result */
WRITE_W (r); /* write result */ WRITE_W (r); /* write result */
CC_IIZZ_W (r); /* set cc's */ CC_IIZZ_W (r); /* set cc's */
cc = cc | temp; /* error? set V */ cc = cc | temp; /* error? set V */
@ -1375,6 +1393,7 @@ case DIVL2: case DIVL3:
else { else {
r = op1 / op0; /* ok, divide */ r = op1 / op0; /* ok, divide */
temp = 0; } temp = 0; }
r = r & LMASK; /* mask to result */
WRITE_L (r); /* write result */ WRITE_L (r); /* write result */
CC_IIZZ_L (r); /* set cc's */ CC_IIZZ_L (r); /* set cc's */
cc = cc | temp; /* error? set V */ cc = cc | temp; /* error? set V */
@ -1460,7 +1479,7 @@ case ROTL:
case ASHL: case ASHL:
if (op0 & BSIGN) { /* right shift? */ if (op0 & BSIGN) { /* right shift? */
temp = 0x100 - op0; /* get |shift| */ temp = 0x100 - op0; /* get |shift| */
if (temp > 31) r = (op1 & LSIGN)? -1: 0; /* sc > 31? */ if (temp > 31) r = (op1 & LSIGN)? LMASK: 0; /* sc > 31? */
else r = op1 >> temp; /* shift */ else r = op1 >> temp; /* shift */
WRITE_L (r); /* store result */ WRITE_L (r); /* store result */
CC_IIZZ_L (r); /* set cc's */ CC_IIZZ_L (r); /* set cc's */
@ -1468,7 +1487,7 @@ case ASHL:
else { else {
if (op0 > 31) r = temp = 0; /* sc > 31? */ if (op0 > 31) r = temp = 0; /* sc > 31? */
else { else {
r = ((uint32) op1) << op0; /* shift */ r = (((uint32) op1) << op0) & LMASK; /* shift */
temp = r >> op0; } /* shift back */ temp = r >> op0; } /* shift back */
WRITE_L (r); /* store result */ WRITE_L (r); /* store result */
CC_IIZZ_L (r); /* set cc's */ CC_IIZZ_L (r); /* set cc's */

View file

@ -730,15 +730,6 @@ return 0; /* q can't be empty */
#define MVC_FILL 3 /* must be 3 */ #define MVC_FILL 3 /* must be 3 */
#define MVC_M_STATE 3 #define MVC_M_STATE 3
#define MVC_V_CC 2 #define MVC_V_CC 2
#define STR_V_DPC 24
#define STR_M_DPC 0xFF
#define STR_V_CHR 16
#define STR_M_CHR 0xFF
#define STR_LNMASK 0xFFFF
#define STR_GETDPC(x) (((x) >> STR_V_DPC) & STR_M_DPC)
#define STR_GETCHR(x) (((x) >> STR_V_CHR) & STR_M_CHR)
#define STR_PACK(m,x) ((((PC - fault_PC) & STR_M_DPC) << STR_V_DPC) | \
(((m) & STR_M_CHR) << STR_V_CHR) | ((x) & STR_LNMASK))
/* MOVC3, MOVC5 /* MOVC3, MOVC5

View file

@ -26,6 +26,7 @@
The author gratefully acknowledges the help of Stephen Shirron, Antonio The author gratefully acknowledges the help of Stephen Shirron, Antonio
Carlini, and Kevin Peterson in providing specifications for the Qbus VAX's Carlini, and Kevin Peterson in providing specifications for the Qbus VAX's
18-Apr-04 RMS Added octa, fp, string definitions
19-May-03 RMS Revised for new conditional compilation scheme 19-May-03 RMS Revised for new conditional compilation scheme
14-Jul-02 RMS Added infinite loop message 14-Jul-02 RMS Added infinite loop message
30-Apr-02 RMS Added CLR_TRAPS macro 30-Apr-02 RMS Added CLR_TRAPS macro
@ -96,6 +97,32 @@
#define NUM_INST 512 /* one byte+two byte */ #define NUM_INST 512 /* one byte+two byte */
#define MAX_SPEC 6 /* max spec/instr */ #define MAX_SPEC 6 /* max spec/instr */
/* Floating point formats */
#define FD_V_EXP 7 /* f/d exponent */
#define FD_M_EXP 0xFF
#define FD_BIAS 0x80 /* f/d bias */
#define FD_EXP (FD_M_EXP << FD_V_EXP)
#define FD_HB (1 << FD_V_EXP) /* f/d hidden bit */
#define FD_GUARD (15 - FD_V_EXP) /* # guard bits */
#define FD_GETEXP(x) (((x) >> FD_V_EXP) & FD_M_EXP)
#define G_V_EXP 4 /* g exponent */
#define G_M_EXP 0x7FF
#define G_BIAS 0x400 /* g bias */
#define G_EXP (G_M_EXP << G_V_EXP)
#define G_HB (1 << G_V_EXP) /* g hidden bit */
#define G_GUARD (15 - G_V_EXP) /* # guard bits */
#define G_GETEXP(x) (((x) >> G_V_EXP) & G_M_EXP)
#define H_V_EXP 0 /* h exponent */
#define H_M_EXP 0x7FFF
#define H_BIAS 0x4000 /* h bias */
#define H_EXP (H_M_EXP << H_V_EXP)
#define H_HB (1 << H_V_EXP) /* h hidden bit */
#define H_GUARD (15 - H_V_EXP) /* # guard bits */
#define H_GETEXP(x) (((x) >> H_V_EXP) & H_M_EXP)
/* Memory management modes */ /* Memory management modes */
#define KERN 0 #define KERN 0
@ -458,6 +485,18 @@ enum opcodes {
#define SETPC(d) PC = (d), FLUSH_ISTR #define SETPC(d) PC = (d), FLUSH_ISTR
#define FLUSH_ISTR ibcnt = 0, ppc = -1 #define FLUSH_ISTR ibcnt = 0, ppc = -1
/* Character string instructions */
#define STR_V_DPC 24 /* delta PC */
#define STR_M_DPC 0xFF
#define STR_V_CHR 16 /* char argument */
#define STR_M_CHR 0xFF
#define STR_LNMASK 0xFFFF /* string length */
#define STR_GETDPC(x) (((x) >> STR_V_DPC) & STR_M_DPC)
#define STR_GETCHR(x) (((x) >> STR_V_CHR) & STR_M_CHR)
#define STR_PACK(m,x) ((((PC - fault_PC) & STR_M_DPC) << STR_V_DPC) | \
(((m) & STR_M_CHR) << STR_V_CHR) | ((x) & STR_LNMASK))
/* Read and write */ /* Read and write */
#define RA (acc) #define RA (acc)
@ -488,6 +527,10 @@ enum opcodes {
if ((rh) & LSIGN) cc = CC_N; \ if ((rh) & LSIGN) cc = CC_N; \
else if (((rl) | (rh)) == 0) cc = CC_Z; \ else if (((rl) | (rh)) == 0) cc = CC_Z; \
else cc = 0 else cc = 0
#define CC_IIZZ_O(rl,rm2,rm1,rh) \
if ((rh) & LSIGN) cc = CC_N; \
else if (((rl) | (rm2) | (rm1) | (rh)) == 0) cc = CC_Z; \
else cc = 0
#define CC_IIZZ_FP CC_IIZZ_W #define CC_IIZZ_FP CC_IIZZ_W
#define CC_IIZP_B(r) \ #define CC_IIZP_B(r) \
@ -506,6 +549,10 @@ enum opcodes {
if ((rh) & LSIGN) cc = CC_N | (cc & CC_C); \ if ((rh) & LSIGN) cc = CC_N | (cc & CC_C); \
else if (((rl) | (rh)) == 0) cc = CC_Z | (cc & CC_C); \ else if (((rl) | (rh)) == 0) cc = CC_Z | (cc & CC_C); \
else cc = cc & CC_C else cc = cc & CC_C
#define CC_IIZP_O(rl,rm2,rm1,rh) \
if ((rh) & LSIGN) cc = CC_N | (cc & CC_C); \
else if (((rl) | (rm2) | (rm1) | (rh)) == 0) cc = CC_Z | (cc & CC_C); \
else cc = cc & CC_C
#define CC_IIZP_FP CC_IIZP_W #define CC_IIZP_FP CC_IIZP_W
#define V_ADD_B(r,s1,s2) \ #define V_ADD_B(r,s1,s2) \

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: VAX Simulator Usage Subj: VAX Simulator Usage
Date: 04-Apr-2004 Date: 15-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -82,7 +82,8 @@ sim/pdp11/ pdp11_mscp.h
pdp11_rq.c pdp11_rq.c
pdp11_tq.c pdp11_tq.c
pdp11_ts.c pdp11_ts.c
pdp11_xp.c pdp11_vh.c
pdp11_xq.c
Additional files are: Additional files are:
@ -108,6 +109,7 @@ TTI,TTO console terminal
LPT LPV11 line printer LPT LPV11 line printer
CLK real-time clock CLK real-time clock
DZ DZV11 4-line terminal multiplexor (up to 4) DZ DZV11 4-line terminal multiplexor (up to 4)
VH DHQ11 8-line terminal multiplexor (up to 4)
RL RLV12/RL01(2) cartridge disk controller with four drives RL RLV12/RL01(2) cartridge disk controller with four drives
RQ RQDX3 MSCP controller with four drives RQ RQDX3 MSCP controller with four drives
RQB second RQDX3 MSCP controller with four drives RQB second RQDX3 MSCP controller with four drives
@ -476,12 +478,6 @@ implements these registers:
POS 32 number of characters input POS 32 number of characters input
TIME 24 keyboard polling interval TIME 24 keyboard polling interval
If the simulator is compiled under Windows Visual C++, typing ^C to the
terminal input causes a fatal run-time error. Use the following command
to simulate typing ^C:
SET TTI CTRL-C
2.3.4 Terminal Output (TTO) 2.3.4 Terminal Output (TTO)
The terminal output (TTO) writes to the simulator console window. It The terminal output (TTO) writes to the simulator console window. It
@ -544,81 +540,6 @@ The clock (CLK) implements these registers:
The real-time clock autocalibrates; the clock interval is adjusted up or The real-time clock autocalibrates; the clock interval is adjusted up or
down so that the clock tracks actual elapsed time. down so that the clock tracks actual elapsed time.
2.3.7 DZV11 Terminal Multiplexor (DZ)
The DZV11 is an 4-line terminal multiplexor. Up to 4 DZ11's (16 lines)
are supported. The number of lines can be changed with the command
SET DZ LINES=n set line count to n
The line count must be a multiple of 4, with a maximum of 16.
The DZV11 supports 8-bit input and output of characters. 8-bit output
may be incompatible with certain operating systems. The command
SET DZ 7B
forces output characters to be masked to 7 bits.
The DZ11 supports logging on a per-line basis. The command
SET DZ LOG=line=filename
enables logging for the specified line to the indicated file. The
command
SET DZ NOLOG=line
disables logging for the specified line and closes any open log file.
Finally, the command
SHOW DZ LOG
displays logging information for all DZ lines.
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH {-am} DZ <port> set up listening port
where port is a decimal number between 1 and 65535 that is not being used
for other TCP/IP activities. The optional switch -m turns on the DZV11's
modem controls; the optional switch -a turns on active disconnects
(disconnect session if computer clears Data Terminal Ready). Without
modem control, the DZ behaves as though terminals were directly connected;
disconnecting the Telnet session does not cause any operating system-
visible change in line status.
Once the DZ is attached and the simulator is running, the DZ will listen
for connections on the specified port. It assumes that the incoming
connections are Telnet connections. The connection remains open until
disconnected by the simulated program, the Telnet client, a SET DZ
DISCONNECT command, or a DETACH DZ command.
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
The SHOW DZ STATISTICS command displays statistics for active connections.
The SET DZ DISCONNECT=linenumber disconnects the specified line.
The DZV11 implements these registers:
name size comments
CSR[0:3] 16 control/status register, boards 0-3
RBUF[0:3] 16 receive buffer, boards 0-3
LPR[0:3] 16 line parameter register, boards 0-3
TCR[0:3] 16 transmission control register, boards 0-3
MSR[0:3] 16 modem status register, boards 0-3
TDR[0:3] 16 transmit data register, boards 0-3
SAENB[0:3] 1 silo alarm enabled, boards 0-3
RXINT 4 receive interrupts, boards 3..0
TXINT 4 transmit interrupts, boards 3..0
MDMTCL 1 modem control enabled
AUTODS 1 autodisconnect enabled
The DZV11 does not support save and restore. All open connections are
lost when the simulator shuts down or the DZ is detached.
2.4 RLV12/RL01,RL02 Cartridge Disk (RL) 2.4 RLV12/RL01,RL02 Cartridge Disk (RL)
RLV12 options include the ability to set units write enabled or write locked, RLV12 options include the ability to set units write enabled or write locked,
@ -685,13 +606,12 @@ of many disk types:
SET RQn RA72 set type to RA72 SET RQn RA72 set type to RA72
SET RQn RA90 set type to RA90 SET RQn RA90 set type to RA90
SET RQn RA92 set type to RA92 SET RQn RA92 set type to RA92
SET RQn RAUSER{=n} set type to RA81 with n LBN's SET RQn RAUSER{=n} set type to RA81 with n MB's
The type options can be used only when a unit is not attached to a file. The type options can be used only when a unit is not attached to a file.
RAUSER is a "user specified" disk; the user can specify the size of the RAUSER is a "user specified" disk; the user can specify the size of the
disk in logical block numbers (LBN's, 512 bytes each). The minimum size disk in megabytes. The minimum size is 50MB. The maximum size is 2GB if
is 50MB. The maximum size is 2GB if the simulator is compiled without the simulator is compiled without 64b addressing, 1000GB with 64b addressing.
64b addressing, 1000GB with 64b addressing.
Units can also be set ONLINE or OFFLINE. Units can also be set ONLINE or OFFLINE.
@ -912,6 +832,163 @@ Error handling is as follows:
OS I/O error report error and stop OS I/O error report error and stop
2.8 Communications Devices
2.8.1 DZV11 Terminal Multiplexor (DZ)
The DZV11 is an 4-line terminal multiplexor. Up to 4 DZ11's (16 lines)
are supported. The number of lines can be changed with the command
SET DZ LINES=n set line count to n
The line count must be a multiple of 4, with a maximum of 16.
The DZV11 supports 8-bit input and output of characters. 8-bit output
may be incompatible with certain operating systems. The command
SET DZ 7B
forces output characters to be masked to 7 bits.
The DZ11 supports logging on a per-line basis. The command
SET DZ LOG=line=filename
enables logging for the specified line to the indicated file. The
command
SET DZ NOLOG=line
disables logging for the specified line and closes any open log file.
Finally, the command
SHOW DZ LOG
displays logging information for all DZ lines.
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH {-am} DZ <port> set up listening port
where port is a decimal number between 1 and 65535 that is not being used
for other TCP/IP activities. The optional switch -m turns on the DZV11's
modem controls; the optional switch -a turns on active disconnects
(disconnect session if computer clears Data Terminal Ready). Without
modem control, the DZ behaves as though terminals were directly connected;
disconnecting the Telnet session does not cause any operating system-
visible change in line status.
Once the DZ is attached and the simulator is running, the DZ will listen
for connections on the specified port. It assumes that the incoming
connections are Telnet connections. The connection remains open until
disconnected by the simulated program, the Telnet client, a SET DZ
DISCONNECT command, or a DETACH DZ command.
The SHOW DZ CONNECTIONS command displays the current connections to the DZ.
The SHOW DZ STATISTICS command displays statistics for active connections.
The SET DZ DISCONNECT=linenumber disconnects the specified line.
The DZV11 implements these registers:
name size comments
CSR[0:3] 16 control/status register, boards 0-3
RBUF[0:3] 16 receive buffer, boards 0-3
LPR[0:3] 16 line parameter register, boards 0-3
TCR[0:3] 16 transmission control register, boards 0-3
MSR[0:3] 16 modem status register, boards 0-3
TDR[0:3] 16 transmit data register, boards 0-3
SAENB[0:3] 1 silo alarm enabled, boards 0-3
RXINT 4 receive interrupts, boards 3..0
TXINT 4 transmit interrupts, boards 3..0
MDMTCL 1 modem control enabled
AUTODS 1 autodisconnect enabled
The DZV11 does not support save and restore. All open connections are
lost when the simulator shuts down or the DZ is detached.
2.8.2 DHQ11 Terminal Multiplexor (VH)
The DHQ11 is an 8-line terminal multiplexor for Qbus systems. Up
to 4 DHQ11's are supported.
The DHQ11 is a programmable asynchronous terminal multiplexor. It
has two programming modes: DHV11 and DHU11. The register sets are
compatible with these devices. For transmission, the DHQ11 can be
used in either DMA or programmed I/O mode. For reception, there
is a 256-entry FIFO for received characters, dataset status changes,
and diagnostic information, and a programmable input interrupt
timer (in DHU mode). The device supports 16-, 18-, and 22-bit
addressing. The DHQ11 can be programmed to filter and/or handle
XON/XOFF characters independently of the processor. The DHQ11
supports programmable bit width (between 5 and 8) for the input
and output of characters.
The DHQ11 has a rocker switch for determining the programming mode.
By default, the DHV11 mode is selected, though DHU11 mode is
recommended for applications that can support it. The VH controller
may be adjusted on a per controller basis as follows:
SET VHn DHU use the DHU programming mode and registers
SET VHn DHV use the DHV programming mode and registers
DMA output is supported. In a real DHQ11, DMA is not initiated
immediately upon receipt of TX.DMA.START but is dependent upon some
internal processes. The VH controller mimics this behavior by default.
It may be desirable to alter this and start immediately, though
this may not be compatible with all operating systems and diagnostics.
You can change the behavior of the VH controller as follows:
SET VHn NORMAL use normal DMA procedures
SET VHn FASTDMA set DMA to initiate immediately
The terminal lines perform input and output through Telnet sessions
connected to a user-specified port. The ATTACH command specifies
the port to be used:
ATTACH VH <port> set up listening port
DETACH VH
where port is a decimal number between 1 and 65535 that is not
being used for other TCP/IP activities. This port is the point of
entry for al lines on all VH controllers.
Modem and auto-disconnect support may be set on an individual
controller basis. The SET MODEM command directs the controller to
report modem status changes to the computer. The SET HANGUP command
turns on active disconnects (disconnect session if computer clears
Data Terminal Ready).
SET VHn [NO]MODEM disable/enable modem control
SET VHn [NO]HANGUP disable/enable disconnect on DTR drop
Once the VH is attached and the simulator is running, the VH will
listen for connections on the specified port. It assumes that the
incoming connections are Telnet connections. The connection remains
open until disconnected by the simulated program, the Telnet client,
a SET VH DISCONNECT command, or a DETACH VH command.
The SHOW VH CONNECTIONS command displays the current connections to the VH.
The SHOW VH STATISTICS command displays statistics for active connections.
The SET VH DISCONNECT=linenumber disconnects the specified line.
The DHQ11 implements these registers, though not all can be examined
from SCP:
name size comments
CSR[0:3] 16 control/status register, boards 0..3
RBUF[0:3] 16 receive buffer, boards 0..3
LPR[0:3] 16 line parameter register, boards 0..3
RXINT 4 receive interrupts, boards 3..0
TXINT 4 transmit interrupts, boards 3..0
[more to be described...]
The DHQ11 does not support save and restore. All open connections
are lost when the simulator shuts down or the VH is detached.
2.9 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB) 2.9 DELQA/DEQNA Qbus Ethernet Controllers (XQ, XQB)
The simulator implements two DELQA/DEQNA Qbus Ethernet controllers (XQ, The simulator implements two DELQA/DEQNA Qbus Ethernet controllers (XQ,

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
18-Apr-04 RMS Moved format definitions to vax_defs.h
19-Jun-03 RMS Simplified add algorithm 19-Jun-03 RMS Simplified add algorithm
16-May-03 RMS Fixed bug in floating to integer convert overflow 16-May-03 RMS Fixed bug in floating to integer convert overflow
Fixed multiple bugs in EMODx Fixed multiple bugs in EMODx
@ -43,22 +44,6 @@
#define M32 0xFFFFFFFF /* 32b */ #define M32 0xFFFFFFFF /* 32b */
#define M16 0x0000FFFF #define M16 0x0000FFFF
#define FD_V_EXP 7 /* f/d exponent */
#define FD_M_EXP 0xFF
#define FD_BIAS 0x80 /* f/d bias */
#define FD_EXP (FD_M_EXP << FD_V_EXP)
#define FD_HB (1 << FD_V_EXP) /* f/d hidden bit */
#define FD_GUARD (15 - FD_V_EXP) /* # guard bits */
#define FD_GETEXP(x) (((x) >> FD_V_EXP) & FD_M_EXP)
#define G_V_EXP 4 /* g exponent */
#define G_M_EXP 0x7FF
#define G_BIAS 0x400 /* g bias */
#define G_EXP (G_M_EXP << G_V_EXP)
#define G_HB (1 << G_V_EXP) /* g hidden bit */
#define G_GUARD (15 - G_V_EXP) /* # guard bits */
#define G_GETEXP(x) (((x) >> G_V_EXP) & G_M_EXP)
extern int32 R[16]; extern int32 R[16];
extern int32 PSL; extern int32 PSL;
extern int32 p1; extern int32 p1;

View file

@ -25,6 +25,7 @@
qba Qbus adapter qba Qbus adapter
28-May-04 RMS Revised I/O dispatching (from John Dundas)
21-Mar-04 RMS Added RXV21 support 21-Mar-04 RMS Added RXV21 support
21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls 21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls
21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner) 21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner)
@ -154,9 +155,11 @@ DEVICE qba_dev = {
NULL, NULL, NULL, NULL, NULL, NULL,
&qba_dib, DEV_QBUS }; &qba_dib, DEV_QBUS };
/* IO page addresses */ /* IO page dispatches */
DIB *dib_tab[DIB_MAX]; /* DIB table */ static t_stat (*iodispR[IOPAGESIZE >> 1])(int32 *dat, int32 ad, int32 md);
static t_stat (*iodispW[IOPAGESIZE >> 1])(int32 dat, int32 ad, int32 md);
static DIB *iodibp[IOPAGESIZE >> 1];
/* Interrupt request to interrupt action map */ /* Interrupt request to interrupt action map */
@ -174,14 +177,12 @@ int32 int_vec[IPL_HLVL][32]; /* int req to vector */
int32 ReadQb (uint32 pa) int32 ReadQb (uint32 pa)
{ {
int32 i, val; int32 idx, val;
DIB *dibp;
for (i = 0; dibp = dib_tab[i]; i++ ) { idx = (pa & IOPAGEMASK) >> 1;
if ((pa >= dibp->ba) && if (iodispR[idx]) {
(pa < (dibp->ba + dibp->lnt))) { iodispR[idx] (&val, pa, READ);
dibp->rd (&val, pa, READ); return val; }
return val; } }
cq_merr (pa); cq_merr (pa);
MACH_CHECK (MCHK_READ); MACH_CHECK (MCHK_READ);
return 0; return 0;
@ -189,14 +190,12 @@ return 0;
void WriteQb (uint32 pa, int32 val, int32 mode) void WriteQb (uint32 pa, int32 val, int32 mode)
{ {
int32 i; int32 idx;
DIB *dibp;
for (i = 0; dibp = dib_tab[i]; i++ ) { idx = (pa & IOPAGEMASK) >> 1;
if ((pa >= dibp->ba) && if (iodispW[idx]) {
(pa < (dibp->ba + dibp->lnt))) { iodispW[idx] (val, pa, mode);
dibp->wr (val, pa, mode); return; }
return; } }
cq_merr (pa); cq_merr (pa);
mem_err = 1; mem_err = 1;
return; return;
@ -781,114 +780,117 @@ else { fprintf (st, "vector=%X", vec);
return SCPE_OK; return SCPE_OK;
} }
/* Test for conflict in device addresses */ /* Build dispatch tables */
t_bool dev_conflict (DIB *curr) t_stat build_dsp_tab (DEVICE *dptr, DIB *dibp)
{ {
uint32 i, end; uint32 i, idx;
DEVICE *dptr;
DIB *dibp;
end = curr->ba + curr->lnt - 1; /* get end */ if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ for (i = 0; i < dibp->lnt; i = i + 2) { /* create entries */
dibp = (DIB *) dptr->ctxt; /* get DIB */ idx = ((dibp->ba + i) & IOPAGEMASK) >> 1; /* index into disp */
if ((dibp == NULL) || (dibp == curr) || if ((iodispR[idx] && dibp->rd && /* conflict? */
(dptr->flags & DEV_DIS)) continue; (iodispR[idx] != dibp->rd)) ||
if (((curr->ba >= dibp->ba) && /* overlap start? */ (iodispW[idx] && dibp->wr &&
(curr->ba < (dibp->ba + dibp->lnt))) || (iodispW[idx] != dibp->wr))) {
((end >= dibp->ba) && /* overlap end? */ printf ("Device %s address conflict at %08o\n",
(end < (dibp->ba + dibp->lnt)))) { sim_dname (dptr), dibp->ba);
printf ("Device %s address conflict at %08X\n", if (sim_log) fprintf (sim_log,
sim_dname (dptr), dibp->ba); "Device %s address conflict at %08o\n",
if (sim_log) fprintf (sim_log, sim_dname (dptr), dibp->ba);
"Device %s address conflict at %08X\n", return SCPE_STOP;
sim_dname (dptr), dibp->ba); }
return TRUE; } } if (dibp->rd) iodispR[idx] = dibp->rd; /* set rd dispatch */
return FALSE; if (dibp->wr) iodispW[idx] = dibp->wr; /* set wr dispatch */
iodibp[idx] = dibp; /* remember DIB */
}
return SCPE_OK;
} }
/* Build interrupt tables */ /* Build interrupt tables */
t_bool build_int_vec (int32 vloc, int32 ivec, int32 (*iack)(void) ) t_stat build_int_vec (DEVICE *dptr, DIB *dibp)
{ {
int32 ilvl = vloc / 32; int32 i, idx, vec, ilvl, ibit;
int32 ibit = vloc % 32;
if (iack != NULL) { if ((dptr == NULL) || (dibp == NULL)) return SCPE_IERR; /* validate args */
if (int_ack[ilvl][ibit] && if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR;
(int_ack[ilvl][ibit] != iack)) return TRUE; for (i = 0; i < dibp->vnum; i++) { /* loop thru vec */
int_ack[ilvl][ibit] = iack; } idx = dibp->vloc + i; /* vector index */
else if (ivec != 0) { vec = dibp->vec? (dibp->vec + (i * 4)): 0; /* vector addr */
if (int_vec[ilvl][ibit] && ilvl = idx / 32;
(int_vec[ilvl][ibit] != ivec)) return TRUE; ibit = idx % 32;
int_vec[ilvl][ibit] = ivec; } if ((int_ack[ilvl][ibit] && dibp->ack[i] && /* conflict? */
return FALSE; (int_ack[ilvl][ibit] != dibp->ack[i])) ||
(int_vec[ilvl][ibit] && vec &&
(int_vec[ilvl][ibit] != vec))) {
printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
if (sim_log) fprintf (sim_log,
"Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), idx);
return SCPE_STOP;
}
if (dibp->ack[i]) int_ack[ilvl][ibit] = dibp->ack[i];
else if (vec) int_vec[ilvl][ibit] = vec;
}
return SCPE_OK;
} }
/* Build dib_tab from device list */ /* Build dib_tab from device list */
t_stat build_dib_tab (void) t_stat build_dib_tab (void)
{ {
int32 i, j, k; int32 i, j;
DEVICE *dptr; DEVICE *dptr;
DIB *dibp; DIB *dibp;
t_stat r;
for (i = 0; i < IPL_HLVL; i++) { /* clear int tables */ for (i = 0; i < IPL_HLVL; i++) { /* clear int tables */
for (j = 0; j < 32; j++) { for (j = 0; j < 32; j++) {
int_vec[i][j] = 0; int_vec[i][j] = 0;
int_ack[i][j] = NULL; } } int_ack[i][j] = NULL; } }
for (i = j = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */ for (i = 0; i < (IOPAGESIZE >> 1); i++) { /* clear dispatch tab */
iodispR[i] = NULL;
iodispW[i] = NULL;
iodibp[i] = NULL; }
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* loop thru dev */
dibp = (DIB *) dptr->ctxt; /* get DIB */ dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */ if (dibp && !(dptr->flags & DEV_DIS)) { /* defined, enabled? */
if (dibp->vnum > VEC_DEVMAX) return SCPE_IERR; if (r = build_int_vec (dptr, dibp)) /* add to intr tab */
for (k = 0; k < dibp->vnum; k++) { /* loop thru vec */ return r;
if (build_int_vec (dibp->vloc + k, /* add vector */ if (r = build_dsp_tab (dptr, dibp)) /* add to dispatch tab */
dibp->vec + (k * 4), dibp->ack[k])) { return r;
printf ("Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), dibp->vloc + k);
if (sim_log) fprintf (sim_log,
"Device %s interrupt slot conflict at %d\n",
sim_dname (dptr), dibp->vloc + k);
return SCPE_IERR; } }
if (dibp->lnt != 0) { /* I/O addresses? */
dib_tab[j++] = dibp; /* add DIB to dib_tab */
if (j >= DIB_MAX) return SCPE_IERR; } /* too many? */
} /* end if enabled */ } /* end if enabled */
} /* end for */ } /* end for */
dib_tab[j] = NULL; /* end with NULL */ return SCPE_OK;
for (i = 0; (dibp = dib_tab[i]) != NULL; i++) { /* test built dib_tab */
if (dev_conflict (dibp)) return SCPE_STOP; } /* for conflicts */
return FALSE;
} }
/* Show dib_tab */ /* Show IO space */
t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc) t_stat show_iospace (FILE *st, UNIT *uptr, int32 val, void *desc)
{ {
int32 i, j, done = 0; uint32 i, j;
DEVICE *dptr; DEVICE *dptr;
DIB *dibt; DIB *dibp;
build_dib_tab (); /* build table */ if (build_dib_tab ()) return SCPE_OK; /* build IO page */
while (done == 0) { /* sort ascending */ for (i = 0, dibp = NULL; i < (IOPAGESIZE >> 1); i++) { /* loop thru entries */
done = 1; /* assume done */ if (iodibp[i] && (iodibp[i] != dibp)) { /* new block? */
for (i = 0; dib_tab[i + 1] != NULL; i++) { /* check table */ dibp = iodibp[i]; /* DIB for block */
if (dib_tab[i]->ba > dib_tab[i + 1]->ba) { /* out of order? */ for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) {
dibt = dib_tab[i]; /* interchange */ if (((DIB*) sim_devices[j]->ctxt) == dibp) {
dib_tab[i] = dib_tab[i + 1]; dptr = sim_devices[j]; /* locate device */
dib_tab[i + 1] = dibt; break;
done = 0; } } /* not done */ } /* end if */
} /* end while */ } /* end for j */
for (i = 0; dib_tab[i] != NULL; i++) { /* print table */ fprintf (st, "%08X - %08X%c\t%s\n", dibp->ba,
for (j = 0, dptr = NULL; sim_devices[j] != NULL; j++) { dibp->ba + dibp->lnt - 1,
if (((DIB*) sim_devices[j]->ctxt) == dib_tab[i]) {
dptr = sim_devices[j];
break; } }
fprintf (st, "%08X - %08X%c\t%s\n", dib_tab[i]->ba,
dib_tab[i]->ba + dib_tab[i]->lnt - 1,
(dptr && (dptr->flags & DEV_FLTA))? '*': ' ', (dptr && (dptr->flags & DEV_FLTA))? '*': ' ',
dptr? sim_dname (dptr): "CPU"); dptr? sim_dname (dptr): "CPU");
} } /* end if */
} /* end for i */
return SCPE_OK; return SCPE_OK;
} }
@ -943,7 +945,7 @@ struct auto_con auto_tab[AUTO_LNT + 1] = {
{ 0xf, 0x3 }, /* VS100 */ { 0xf, 0x3 }, /* VS100 */
{ 0x3, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_TQ, { "TQ", "TQB" } }, { 0x3, 0x3, AUTO_DYN|AUTO_VEC, 0, IOBA_TQ, { "TQ", "TQB" } },
{ 0xf, 0x7 }, /* KMV11 */ { 0xf, 0x7 }, /* KMV11 */
{ 0xf, 0x7 }, /* DHU11/DHQ11 */ { 0x1f, 0x7, AUTO_VEC, VH_MUXES, 0, { "VH" } }, /* DHU11/DHQ11 */
{ 0x1f, 0x7 }, /* DMZ32 */ { 0x1f, 0x7 }, /* DMZ32 */
{ 0x1f, 0x7 }, /* CP132 */ { 0x1f, 0x7 }, /* CP132 */

View file

@ -194,7 +194,7 @@ if (lnt >= L_LONG) { /* lw unaligned? */
sc = bo << 3; sc = bo << 3;
wl = ReadL (pa); /* read both lw */ wl = ReadL (pa); /* read both lw */
wh = ReadL (pa1); /* extract */ wh = ReadL (pa1); /* extract */
return (((wl >> sc) & align[bo]) | (wh << (32 - sc))); } return ((((wl >> sc) & align[bo]) | (wh << (32 - sc))) & LMASK); }
else if (bo == 1) return ((ReadL (pa) >> 8) & WMASK); else if (bo == 1) return ((ReadL (pa) >> 8) & WMASK);
else { wl = ReadL (pa); /* word cross lw */ else { wl = ReadL (pa); /* word cross lw */
wh = ReadL (pa1); /* read, extract */ wh = ReadL (pa1); /* read, extract */
@ -248,7 +248,7 @@ wl = ReadL (pa);
if (lnt >= L_LONG) { if (lnt >= L_LONG) {
sc = bo << 3; sc = bo << 3;
wh = ReadL (pa1); wh = ReadL (pa1);
wl = (wl & insert[bo]) | (val << sc); wl = (wl & insert[bo]) | ((val << sc) & LMASK);
wh = (wh & ~insert[bo]) | ((val >> (32 - sc)) & insert[bo]); wh = (wh & ~insert[bo]) | ((val >> (32 - sc)) & insert[bo]);
WriteL (pa, wl); WriteL (pa, wl);
WriteL (pa1, wh); } WriteL (pa1, wh); }
@ -256,7 +256,7 @@ else if (bo == 1) {
wl = (wl & 0xFF0000FF) | (val << 8); wl = (wl & 0xFF0000FF) | (val << 8);
WriteL (pa, wl); } WriteL (pa, wl); }
else { wh = ReadL (pa1); else { wh = ReadL (pa1);
wl = (wl & 0x00FFFFFF) | (val << 24); wl = (wl & 0x00FFFFFF) | ((val & 0xFF) << 24);
wh = (wh & 0xFFFFFF00) | ((val >> 8) & 0xFF); wh = (wh & 0xFFFFFF00) | ((val >> 8) & 0xFF);
WriteL (pa, wl); WriteL (pa, wl);
WriteL (pa1, wh); } WriteL (pa1, wh); }

View file

@ -27,6 +27,7 @@
tto terminal output tto terminal output
clk 100Hz and TODR clock clk 100Hz and TODR clock
28-May-04 RMS Removed SET TTI CTRL-C
29-Dec-03 RMS Added console backpressure support 29-Dec-03 RMS Added console backpressure support
25-Apr-03 RMS Revised for extended file support 25-Apr-03 RMS Revised for extended file support
02-Mar-02 RMS Added SET TTI CTRL-C 02-Mar-02 RMS Added SET TTI CTRL-C
@ -74,7 +75,6 @@ t_stat clk_svc (UNIT *uptr);
t_stat tti_reset (DEVICE *dptr); t_stat tti_reset (DEVICE *dptr);
t_stat tto_reset (DEVICE *dptr); t_stat tto_reset (DEVICE *dptr);
t_stat clk_reset (DEVICE *dptr); t_stat clk_reset (DEVICE *dptr);
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc);
extern int32 sysd_hlt_enb (void); extern int32 sysd_hlt_enb (void);
@ -102,8 +102,6 @@ REG tti_reg[] = {
MTAB tti_mod[] = { MTAB tti_mod[] = {
{ UNIT_8B, UNIT_8B, "8b", "8B", NULL }, { UNIT_8B, UNIT_8B, "8b", "8B", NULL },
{ UNIT_8B, 0 , "7b", "7B", NULL }, { UNIT_8B, 0 , "7b", "7B", NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VUN, 0, NULL, "CTRL-C",
&tti_set_ctrlc, NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL, { MTAB_XTD|MTAB_VDV, 0, "VECTOR", NULL,
NULL, &show_vec, NULL }, NULL, &show_vec, NULL },
{ 0 } }; { 0 } };
@ -292,18 +290,6 @@ CLR_INT (TTI);
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */ sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK; return SCPE_OK;
} }
/* Set control-C */
t_stat tti_set_ctrlc (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if (cptr) return SCPE_ARG;
uptr->buf = 003;
uptr->pos = uptr->pos + 1;
tti_csr = tti_csr | CSR_DONE;
if (tti_csr & CSR_IE) SET_INT (TTI);
return SCPE_OK;
}
/* Terminal output routines /* Terminal output routines

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
16-Jun-04 RMS Added DHQ11 support
21-Mar-04 RMS Added RXV21 support 21-Mar-04 RMS Added RXV21 support
06-May-03 RMS Added support for second DELQA 06-May-03 RMS Added support for second DELQA
12-Oct-02 RMS Added multiple RQ controller support 12-Oct-02 RMS Added multiple RQ controller support
@ -52,6 +53,7 @@ extern DEVICE ry_dev;
extern DEVICE ts_dev; extern DEVICE ts_dev;
extern DEVICE tq_dev; extern DEVICE tq_dev;
extern DEVICE dz_dev; extern DEVICE dz_dev;
extern DEVICE vh_dev;
extern DEVICE xq_dev, xqb_dev; extern DEVICE xq_dev, xqb_dev;
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern REG cpu_reg[]; extern REG cpu_reg[];
@ -104,6 +106,7 @@ DEVICE *sim_devices[] = {
&ptp_dev, &ptp_dev,
&lpt_dev, &lpt_dev,
&dz_dev, &dz_dev,
&vh_dev,
&rl_dev, &rl_dev,
&rq_dev, &rq_dev,
&rqb_dev, &rqb_dev,

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
16-Jun-04 RMS Added DHQ11 support
21-Mar-04 RMS Added RXV21 support 21-Mar-04 RMS Added RXV21 support
25-Jan-04 RMS Removed local debug logging support 25-Jan-04 RMS Removed local debug logging support
RMS,MP Added "KA655X" support RMS,MP Added "KA655X" support
@ -204,8 +205,9 @@
/* I/O system definitions */ /* I/O system definitions */
#define DZ_MUXES 4 /* max # of muxes */ #define DZ_MUXES 4 /* max # of DZV muxes */
#define DZ_LINES 4 /* (DZV) lines per mux */ #define DZ_LINES 4 /* lines per DZV mux */
#define VH_MUXES 4 /* max # of DHQ muxes */
#define MT_MAXFR (1 << 16) /* magtape max rec */ #define MT_MAXFR (1 << 16) /* magtape max rec */
#define AUTO_LNT 34 /* autoconfig ranks */ #define AUTO_LNT 34 /* autoconfig ranks */
#define DIB_MAX 100 /* max DIBs */ #define DIB_MAX 100 /* max DIBs */
@ -250,6 +252,8 @@ typedef struct pdp_dib DIB;
#define IOLN_RQC 004 #define IOLN_RQC 004
#define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC) #define IOBA_RQD (IOPAGEBASE + IOBA_RQC + IOLN_RQC)
#define IOLN_RQD 004 #define IOLN_RQD 004
#define IOBA_VH (IOPAGEBASE + 000440) /* DHQ11 */
#define IOLN_VH 020
#define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */ #define IOBA_RQ (IOPAGEBASE + 012150) /* RQDX3 */
#define IOLN_RQ 004 #define IOLN_RQ 004
#define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */ #define IOBA_TS (IOPAGEBASE + 012520) /* TS11 */
@ -297,6 +301,7 @@ typedef struct pdp_dib DIB;
#define INT_V_TS 5 /* TS11/TSV05 */ #define INT_V_TS 5 /* TS11/TSV05 */
#define INT_V_TQ 6 /* TMSCP */ #define INT_V_TQ 6 /* TMSCP */
#define INT_V_XQ 7 /* DEQNA/DELQA */ #define INT_V_XQ 7 /* DEQNA/DELQA */
#define INT_V_RY 8 /* RXV21 */
/* IPL 14 */ /* IPL 14 */
@ -309,7 +314,8 @@ typedef struct pdp_dib DIB;
#define INT_V_CSO 6 #define INT_V_CSO 6
#define INT_V_TMR0 7 /* SSC timers */ #define INT_V_TMR0 7 /* SSC timers */
#define INT_V_TMR1 8 #define INT_V_TMR1 8
#define INT_V_RY 9 /* RXV21 */ #define INT_V_VHRX 9 /* DHQ11 */
#define INT_V_VHTX 10
#define INT_CLK (1u << INT_V_CLK) #define INT_CLK (1u << INT_V_CLK)
#define INT_RQ (1u << INT_V_RQ) #define INT_RQ (1u << INT_V_RQ)
@ -320,6 +326,7 @@ typedef struct pdp_dib DIB;
#define INT_TS (1u << INT_V_TS) #define INT_TS (1u << INT_V_TS)
#define INT_TQ (1u << INT_V_TQ) #define INT_TQ (1u << INT_V_TQ)
#define INT_XQ (1u << INT_V_XQ) #define INT_XQ (1u << INT_V_XQ)
#define INT_RY (1u << INT_V_RY)
#define INT_TTI (1u << INT_V_TTI) #define INT_TTI (1u << INT_V_TTI)
#define INT_TTO (1u << INT_V_TTO) #define INT_TTO (1u << INT_V_TTO)
#define INT_PTR (1u << INT_V_PTR) #define INT_PTR (1u << INT_V_PTR)
@ -329,7 +336,8 @@ typedef struct pdp_dib DIB;
#define INT_CSO (1u << INT_V_CSO) #define INT_CSO (1u << INT_V_CSO)
#define INT_TMR0 (1u << INT_V_TMR0) #define INT_TMR0 (1u << INT_V_TMR0)
#define INT_TMR1 (1u << INT_V_TMR1) #define INT_TMR1 (1u << INT_V_TMR1)
#define INT_RY (1u << INT_V_RY) #define INT_VHRX (1u << INT_V_VHRX)
#define INT_VHTX (1u << INT_V_VHTX)
#define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */ #define IPL_CLK (0x16 - IPL_HMIN) /* relative IPL */
#define IPL_RQ (0x15 - IPL_HMIN) #define IPL_RQ (0x15 - IPL_HMIN)
@ -350,6 +358,8 @@ typedef struct pdp_dib DIB;
#define IPL_CSO (0x14 - IPL_HMIN) #define IPL_CSO (0x14 - IPL_HMIN)
#define IPL_TMR0 (0x14 - IPL_HMIN) #define IPL_TMR0 (0x14 - IPL_HMIN)
#define IPL_TMR1 (0x14 - IPL_HMIN) #define IPL_TMR1 (0x14 - IPL_HMIN)
#define IPL_VHRX (0x14 - IPL_HMIN)
#define IPL_VHTX (0x14 - IPL_HMIN)
#define IPL_HMAX 0x17 /* highest hwre level */ #define IPL_HMAX 0x17 /* highest hwre level */
#define IPL_HMIN 0x14 /* lowest hwre level */ #define IPL_HMIN 0x14 /* lowest hwre level */
@ -371,6 +381,8 @@ typedef struct pdp_dib DIB;
#define VEC_RY (VEC_Q + 0264) #define VEC_RY (VEC_Q + 0264)
#define VEC_DZRX (VEC_Q + 0300) #define VEC_DZRX (VEC_Q + 0300)
#define VEC_DZTX (VEC_Q + 0304) #define VEC_DZTX (VEC_Q + 0304)
#define VEC_VHRX (VEC_Q + 0310)
#define VEC_VHTX (VEC_Q + 0314)
/* Autoconfigure ranks */ /* Autoconfigure ranks */
@ -379,6 +391,7 @@ typedef struct pdp_dib DIB;
#define RANK_RX 18 #define RANK_RX 18
#define RANK_RQ 26 #define RANK_RQ 26
#define RANK_TQ 30 #define RANK_TQ 30
#define RANK_VH 32
/* Interrupt macros */ /* Interrupt macros */

View file

@ -362,7 +362,8 @@ PDP11_SOURCE1 = $(PDP11_DIR)PDP11_FP.C,$(PDP11_DIR)PDP11_CPU.C,\
$(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_RK.C,\ $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_RK.C,\
$(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\ $(PDP11_DIR)PDP11_RL.C,$(PDP11_DIR)PDP11_RP.C,\
$(PDP11_DIR)PDP11_RX.C,$(PDP11_DIR)PDP11_STDDEV.C,\ $(PDP11_DIR)PDP11_RX.C,$(PDP11_DIR)PDP11_STDDEV.C,\
$(PDP11_DIR)PDP11_SYS.C,$(PDP11_DIR)PDP11_TC.C $(PDP11_DIR)PDP11_SYS.C,$(PDP11_DIR)PDP11_TC.C, \
$(PDP11_DIR)PDP11_VH.C
PDP11_LIB2 = $(LIB_DIR)PDP11L2-$(ARCH).OLB PDP11_LIB2 = $(LIB_DIR)PDP11L2-$(ARCH).OLB
PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\ PDP11_SOURCE2 = $(PDP11_DIR)PDP11_TM.C,$(PDP11_DIR)PDP11_TS.C,\
$(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\ $(PDP11_DIR)PDP11_IO.C,$(PDP11_DIR)PDP11_RQ.C,\
@ -422,7 +423,7 @@ VAX_SOURCE = $(VAX_DIR)VAX_CPU1.C,$(VAX_DIR)VAX_CPU.C,\
$(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\ $(PDP11_DIR)PDP11_TS.C,$(PDP11_DIR)PDP11_DZ.C,\
$(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TQ.C,\ $(PDP11_DIR)PDP11_LP.C,$(PDP11_DIR)PDP11_TQ.C,\
$(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_XQ.C,\ $(PDP11_DIR)PDP11_PT.C,$(PDP11_DIR)PDP11_XQ.C,\
$(PDP11_DIR)PDP11_RY.C $(PDP11_DIR)PDP11_RY.C,$(PDP11_DIR)PDP11_VH.C
VAX_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR)$(PCAP_INC))\ VAX_OPTIONS = /INCLUDE=($(SIMH_DIR),$(VAX_DIR),$(PDP11_DIR)$(PCAP_INC))\
/DEFINE=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS)) /DEFINE=($(CC_DEFS),"VM_VAX=1"$(PCAP_DEFS))

View file

@ -81,7 +81,7 @@ PDP11 = ${PDP11D}pdp11_fp.c ${PDP11D}pdp11_cpu.c ${PDP11D}pdp11_dz.c \
${PDP11D}pdp11_tm.c ${PDP11D}pdp11_ts.c ${PDP11D}pdp11_io.c \ ${PDP11D}pdp11_tm.c ${PDP11D}pdp11_ts.c ${PDP11D}pdp11_io.c \
${PDP11D}pdp11_rq.c ${PDP11D}pdp11_tq.c ${PDP11D}pdp11_pclk.c \ ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_tq.c ${PDP11D}pdp11_pclk.c \
${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_hk.c \ ${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_hk.c \
${PDP11D}pdp11_xq.c ${PDP11D}pdp11_xu.c ${PDP11D}pdp11_xq.c ${PDP11D}pdp11_xu.c ${PDP11D}pdp11_vh.c
PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT} PDP11_OPT = -DVM_PDP11 -I ${PDP11D} ${NETWORK_OPT}
@ -92,7 +92,8 @@ VAX = ${VAXD}vax_cpu1.c ${VAXD}vax_cpu.c ${VAXD}vax_fpa.c ${VAXD}vax_io.c \
${VAXD}vax_sysdev.c \ ${VAXD}vax_sysdev.c \
${PDP11D}pdp11_rl.c ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_ts.c \ ${PDP11D}pdp11_rl.c ${PDP11D}pdp11_rq.c ${PDP11D}pdp11_ts.c \
${PDP11D}pdp11_dz.c ${PDP11D}pdp11_lp.c ${PDP11D}pdp11_tq.c \ ${PDP11D}pdp11_dz.c ${PDP11D}pdp11_lp.c ${PDP11D}pdp11_tq.c \
${PDP11D}pdp11_pt.c ${PDP11D}pdp11_xq.c ${PDP11D}pdp11_ry.c ${PDP11D}pdp11_pt.c ${PDP11D}pdp11_xq.c ${PDP11D}pdp11_ry.c \
${PDP11D}pdp11_vh.c
VAX_OPT = -DVM_VAX -DUSE_INT64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT} VAX_OPT = -DVM_VAX -DUSE_INT64 -I ${VAXD} -I ${PDP11D} ${NETWORK_OPT}
@ -131,7 +132,7 @@ HP2100 = ${HP2100D}hp2100_stddev.c ${HP2100D}hp2100_dp.c ${HP2100D}hp2100_dq.c \
${HP2100D}hp2100_dr.c ${HP2100D}hp2100_lps.c ${HP2100D}hp2100_ms.c \ ${HP2100D}hp2100_dr.c ${HP2100D}hp2100_lps.c ${HP2100D}hp2100_ms.c \
${HP2100D}hp2100_mt.c ${HP2100D}hp2100_mux.c ${HP2100D}hp2100_cpu.c \ ${HP2100D}hp2100_mt.c ${HP2100D}hp2100_mux.c ${HP2100D}hp2100_cpu.c \
${HP2100D}hp2100_fp.c ${HP2100D}hp2100_sys.c ${HP2100D}hp2100_lpt.c \ ${HP2100D}hp2100_fp.c ${HP2100D}hp2100_sys.c ${HP2100D}hp2100_lpt.c \
${HP2100D}hp2100_ipl.c ${HP2100D}hp2100_ipl.c ${HP2100D}hp2100_ds.c
HP2100_OPT = -I ${HP2100D} HP2100_OPT = -I ${HP2100D}

71
scp.c
View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
28-May-04 RMS Added SET/SHOW CONSOLE
14-Feb-04 RMS Updated SAVE/RESTORE (V3.2) 14-Feb-04 RMS Updated SAVE/RESTORE (V3.2)
RMS Added debug print routines (from Dave Hittner) RMS Added debug print routines (from Dave Hittner)
RMS Added sim_vm_parse_addr and sim_vm_fprint_addr RMS Added sim_vm_parse_addr and sim_vm_fprint_addr
@ -247,8 +248,6 @@ t_stat spawn_cmd (int32 flag, char *ptr);
/* Set and show command processors */ /* Set and show command processors */
t_stat set_logon (int32 flag, char *cptr);
t_stat set_logoff (int32 flag, char *cptr);
t_stat set_debon (int32 flag, char *cptr); t_stat set_debon (int32 flag, char *cptr);
t_stat set_deboff (int32 flag, char *cptr); t_stat set_deboff (int32 flag, char *cptr);
t_stat set_dev_radix (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat set_dev_radix (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
@ -261,7 +260,6 @@ t_stat show_queue (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_time (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_time (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_mod_names (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_mod_names (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_log_names (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_log_names (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_dev_radix (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_dev_radix (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat show_dev_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_dev_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
@ -305,10 +303,7 @@ void fprint_help (FILE *st);
void fprint_stopped (FILE *st, t_stat r); void fprint_stopped (FILE *st, t_stat r);
void fprint_capac (FILE *st, DEVICE *dptr, UNIT *uptr); void fprint_capac (FILE *st, DEVICE *dptr, UNIT *uptr);
char *read_line (char *ptr, int32 size, FILE *stream); char *read_line (char *ptr, int32 size, FILE *stream);
CTAB *find_ctab (CTAB *tab, char *gbuf);
C1TAB *find_c1tab (C1TAB *tab, char *gbuf);
CTAB *find_cmd (char *gbuf); CTAB *find_cmd (char *gbuf);
SHTAB *find_shtab (SHTAB *tab, char *gbuf);
DEVICE *find_dev (char *ptr); DEVICE *find_dev (char *ptr);
DEVICE *find_unit (char *ptr, UNIT **uptr); DEVICE *find_unit (char *ptr, UNIT **uptr);
REG *find_reg_glob (char *ptr, char **optr, DEVICE **gdptr); REG *find_reg_glob (char *ptr, char **optr, DEVICE **gdptr);
@ -492,10 +487,7 @@ static CTAB cmd_table[] = {
{ "QUIT", &exit_cmd, 0, NULL }, { "QUIT", &exit_cmd, 0, NULL },
{ "BYE", &exit_cmd, 0, NULL }, { "BYE", &exit_cmd, 0, NULL },
{ "SET", &set_cmd, 0, { "SET", &set_cmd, 0,
"set log <file> enable logging to file\n" "set console arg{,arg...} set console options\n"
"set nolog disable logging\n"
"set telnet <port> enable Telnet port for console\n"
"set notelnet disable Telnet for console\n"
"set debug <file> enable debug output to file\n" "set debug <file> enable debug output to file\n"
"set nodebug disable debug output\n" "set nodebug disable debug output\n"
"set <dev> OCT|DEC|HEX set device display radix\n" "set <dev> OCT|DEC|HEX set device display radix\n"
@ -510,14 +502,13 @@ static CTAB cmd_table[] = {
}, },
{ "SHOW", &show_cmd, 0, { "SHOW", &show_cmd, 0,
"sh{ow} br{eak} <list> show breakpoints on address list\n" "sh{ow} br{eak} <list> show breakpoints on address list\n"
"sh{ow} c{onfiguration} show configuration\n" "sh{ow} con{figuration} show configuration\n"
"sh{ow} cons{ole} {arg} show console options\n"
"sh{ow} deb{ug} show debugging output\n" "sh{ow} deb{ug} show debugging output\n"
"sh{ow} dev{ices} show devices\n" "sh{ow} dev{ices} show devices\n"
"sh{ow} l{og} show log\n"
"sh{ow} m{odifiers} show modifiers\n" "sh{ow} m{odifiers} show modifiers\n"
"sh{ow} n{ames} show logical names\n" "sh{ow} n{ames} show logical names\n"
"sh{ow} q{ueue} show event queue\n" "sh{ow} q{ueue} show event queue\n"
"sh{ow} te{lnet} show console Telnet status\n"
"sh{ow} ti{me} show simulated time\n" "sh{ow} ti{me} show simulated time\n"
"sh{ow} ve{rsion} show simulator version\n" "sh{ow} ve{rsion} show simulator version\n"
"sh{ow} <dev> RADIX show device display radix\n" "sh{ow} <dev> RADIX show device display radix\n"
@ -634,8 +625,8 @@ while (stat != SCPE_EXIT) { /* in case exit */
} /* end while */ } /* end while */
detach_all (0, TRUE); /* close files */ detach_all (0, TRUE); /* close files */
set_logoff (0, NULL); /* close log */
set_deboff (0, NULL); /* close debug */ set_deboff (0, NULL); /* close debug */
sim_set_logoff (0, NULL); /* close log */
sim_set_notelnet (0, NULL); /* close Telnet */ sim_set_notelnet (0, NULL); /* close Telnet */
sim_ttclose (); /* close console */ sim_ttclose (); /* close console */
return 0; return 0;
@ -802,10 +793,11 @@ CTAB *gcmdp;
C1TAB *ctbr, *glbr; C1TAB *ctbr, *glbr;
static CTAB set_glob_tab[] = { static CTAB set_glob_tab[] = {
{ "TELNET", &sim_set_telnet, 0 }, { "CONSOLE", &sim_set_console, 0 },
{ "NOTELNET", &sim_set_notelnet, 0 }, { "TELNET", &sim_set_telnet, 0 }, /* deprecated */
{ "LOG", &set_logon, 0 }, { "NOTELNET", &sim_set_notelnet, 0 }, /* deprecated */
{ "NOLOG", &set_logoff, 0 }, { "LOG", &sim_set_logon, 0 }, /* deprecated */
{ "NOLOG", &sim_set_logoff, 0 }, /* deprecated */
{ "BREAK", &brk_cmd, SSH_ST }, { "BREAK", &brk_cmd, SSH_ST },
{ "DEBUG", &set_debon, 0 }, { "DEBUG", &set_debon, 0 },
{ "NODEBUG", &set_deboff, 0 }, { "NODEBUG", &set_deboff, 0 },
@ -905,36 +897,6 @@ for (; tab->name != NULL; tab++) {
return NULL; return NULL;
} }
/* Log on routine */
t_stat set_logon (int32 flag, char *cptr)
{
char gbuf[CBUFSIZE];
if (*cptr == 0) return SCPE_2FARG; /* need arg */
cptr = get_glyph_nc (cptr, gbuf, 0); /* get file name */
if (*cptr != 0) return SCPE_2MARG; /* now eol? */
set_logoff (0, NULL); /* close cur log */
sim_log = sim_fopen (gbuf, "a"); /* open log */
if (sim_log == NULL) return SCPE_OPENERR; /* error? */
if (!sim_quiet) printf ("Logging to file \"%s\"\n", gbuf);
fprintf (sim_log, "Logging to file \"%s\"\n", gbuf); /* start of log */
return SCPE_OK;
}
/* Log off routine */
t_stat set_logoff (int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) return SCPE_2MARG; /* now eol? */
if (sim_log == NULL) return SCPE_OK; /* no log? */
if (!sim_quiet) printf ("Log file closed\n");
fprintf (sim_log, "Log file closed\n"); /* close log */
fclose (sim_log);
sim_log = NULL;
return SCPE_OK;
}
/* Set device data radix routine */ /* Set device data radix routine */
t_stat set_dev_radix (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr) t_stat set_dev_radix (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
@ -1064,8 +1026,9 @@ static SHTAB show_glob_tab[] = {
{ "MODIFIERS", &show_mod_names, 0 }, { "MODIFIERS", &show_mod_names, 0 },
{ "NAMES", &show_log_names, 0 }, { "NAMES", &show_log_names, 0 },
{ "VERSION", &show_version, 0 }, { "VERSION", &show_version, 0 },
{ "LOG", &show_log, 0 }, { "CONSOLE", &sim_show_console, 0 },
{ "TELNET", &sim_show_telnet, 0 }, { "LOG", &sim_show_log, 0 }, /* deprecated */
{ "TELNET", &sim_show_telnet, 0 }, /* deprecated */
{ "BREAK", &show_break, 0 }, { "BREAK", &show_break, 0 },
{ "DEBUG", &show_debug, 0 }, { "DEBUG", &show_debug, 0 },
{ NULL, NULL, 0 } }; { NULL, NULL, 0 } };
@ -1283,14 +1246,6 @@ fprintf (st, "Time: %.0f\n", sim_time);
return SCPE_OK; return SCPE_OK;
} }
t_stat show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) return SCPE_2MARG;
if (sim_log) fputs ("Logging enabled\n", st);
else fputs ("Logging disabled\n", st);
return SCPE_OK;
}
t_stat show_break (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr) t_stat show_break (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{ {
t_stat r; t_stat r;

5
scp.h
View file

@ -1,4 +1,4 @@
/* sim_timer.h: simulator timer library headers /* scp.h: simulator control program headers
Copyright (c) 1993-2004, Robert M Supnik Copyright (c) 1993-2004, Robert M Supnik
@ -52,6 +52,9 @@ t_value strtotv (char *cptr, char **endptr, uint32 radix);
t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt); t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt);
DEVICE *find_dev_from_unit (UNIT *uptr); DEVICE *find_dev_from_unit (UNIT *uptr);
REG *find_reg (char *ptr, char **optr, DEVICE *dptr); REG *find_reg (char *ptr, char **optr, DEVICE *dptr);
CTAB *find_ctab (CTAB *tab, char *gbuf);
C1TAB *find_c1tab (C1TAB *tab, char *gbuf);
SHTAB *find_shtab (SHTAB *tab, char *gbuf);
BRKTAB *sim_brk_fnd (t_addr loc); BRKTAB *sim_brk_fnd (t_addr loc);
t_bool sim_brk_test (t_addr bloc, int32 btyp); t_bool sim_brk_test (t_addr bloc, int32 btyp);
char *match_ext (char *fnam, char *ext); char *match_ext (char *fnam, char *ext);

View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
28-May-04 RMS Added SET/SHOW CONSOLE
RMS Added break, delete character maps
02-Jan-04 RMS Removed timer routines, added Telnet console routines 02-Jan-04 RMS Removed timer routines, added Telnet console routines
RMS Moved console logging to OS-independent code RMS Moved console logging to OS-independent code
25-Apr-03 RMS Added long seek support from Mark Pizzolato 25-Apr-03 RMS Added long seek support from Mark Pizzolato
@ -50,9 +52,8 @@
sim_poll_kbd - poll for keyboard input sim_poll_kbd - poll for keyboard input
sim_putchar - output character to console sim_putchar - output character to console
sim_putchar_s - output character to console, stall if congested sim_putchar_s - output character to console, stall if congested
sim_set_telnet - set console to Telnet port sim_set_console - set console parameters
sim_set_notelnet - close console Telnet port sim_show_console - show console parameters
sim_show_telnet - show console status
sim_ttinit - called once to get initial terminal state sim_ttinit - called once to get initial terminal state
sim_ttrun - called to put terminal into run state sim_ttrun - called to put terminal into run state
@ -62,18 +63,63 @@
sim_os_putchar - output character to console sim_os_putchar - output character to console
The first group is OS-independent; the second group is OS-dependent. The first group is OS-independent; the second group is OS-dependent.
The following routines are exposed but deprecated:
sim_set_telnet - set console to Telnet port
sim_set_notelnet - close console Telnet port
sim_show_telnet - show console status
*/ */
#include "sim_defs.h" #include "sim_defs.h"
#include "sim_sock.h" #include "sim_sock.h"
#include "sim_tmxr.h" #include "sim_tmxr.h"
#define KMAP_WRU 0
#define KMAP_BRK 1
#define KMAP_DEL 2
#define KMAP_MASK 0377
#define KMAP_NZ 0400
int32 sim_int_char = 005; /* interrupt character */ int32 sim_int_char = 005; /* interrupt character */
int32 sim_brk_char = 000; /* break character */
#if defined (_WIN32) || defined (__OS2__) || (defined (__MWERKS__) && defined (macintosh))
int32 sim_del_char = '\b'; /* delete character */
#else
int32 sim_del_char = 0177;
#endif
TMLN sim_con_ldsc = { 0 }; /* console line descr */ TMLN sim_con_ldsc = { 0 }; /* console line descr */
TMXR sim_con_tmxr = { 1, 0, 0, &sim_con_ldsc }; /* console line mux */ TMXR sim_con_tmxr = { 1, 0, 0, &sim_con_ldsc }; /* console line mux */
extern volatile int32 stop_cpu; extern volatile int32 stop_cpu;
extern int32 sim_quiet;
extern FILE *sim_log; extern FILE *sim_log;
extern DEVICE *sim_devices[];
/* Set/show data structures */
static CTAB set_con_tab[] = {
{ "WRU", &sim_set_kmap, KMAP_WRU | KMAP_NZ },
{ "BRK", &sim_set_kmap, KMAP_BRK },
{ "DEL", &sim_set_kmap, KMAP_DEL |KMAP_NZ },
{ "TELNET", &sim_set_telnet, 0 },
{ "NOTELNET", &sim_set_notelnet, 0 },
{ "LOG", &sim_set_logon, 0 },
{ "NOLOG", &sim_set_logoff, 0 },
{ NULL, NULL, 0 } };
static SHTAB show_con_tab[] = {
{ "WRU", &sim_show_kmap, KMAP_WRU },
{ "BRK", &sim_show_kmap, KMAP_BRK },
{ "DEL", &sim_show_kmap, KMAP_DEL },
{ "LOG", &sim_show_log, 0 },
{ "TELNET", &sim_show_telnet, 0 },
{ NULL, NULL, 0 } };
static int32 *cons_kmap[] = {
&sim_int_char,
&sim_brk_char,
&sim_del_char };
/* Console I/O package. /* Console I/O package.
@ -83,11 +129,126 @@ extern FILE *sim_log;
sim_con_tmxr and internal terminal line description sim_con_ldsc. sim_con_tmxr and internal terminal line description sim_con_ldsc.
*/ */
/* SET CONSOLE command */
t_stat sim_set_console (int32 flag, char *cptr)
{
char *cvptr, gbuf[CBUFSIZE];
CTAB *ctptr;
t_stat r;
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG;
while (*cptr != 0) { /* do all mods */
cptr = get_glyph_nc (cptr, gbuf, 0); /* get modifier */
if (cvptr = strchr (gbuf, '=')) *cvptr++ = 0; /* = value? */
get_glyph (gbuf, gbuf, 0); /* modifier to UC */
if (ctptr = find_ctab (set_con_tab, gbuf)) { /* match? */
r = ctptr->action (ctptr->arg, cvptr); /* do the rest */
if (r != SCPE_OK) return r; }
else return SCPE_NOPARAM;
}
return SCPE_OK;
}
/* SHOW CONSOLE command */
t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
char gbuf[CBUFSIZE];
SHTAB *shptr;
int32 i;
if (*cptr == 0) { /* show all */
for (i = 0; show_con_tab[i].name; i++)
show_con_tab[i].action (st, dptr, uptr, show_con_tab[i].arg, cptr);
return SCPE_OK;
}
while (*cptr != 0) {
cptr = get_glyph (cptr, gbuf, ','); /* get modifier */
if (shptr = find_shtab (show_con_tab, gbuf))
shptr->action (st, dptr, uptr, shptr->arg, cptr);
else return SCPE_NOPARAM;
}
return SCPE_OK;
}
/* Set keyboard map */
t_stat sim_set_kmap (int32 flag, char *cptr)
{
DEVICE *dptr = sim_devices[0];
int32 val, rdx;
t_stat r;
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG;
if (dptr->dradix == 16) rdx = 16;
else rdx = 8;
val = (int32) get_uint (cptr, rdx, 0177, &r);
if ((r != SCPE_OK) ||
((val == 0) && (flag & KMAP_NZ))) return SCPE_ARG;
*(cons_kmap[flag & KMAP_MASK]) = val;
return SCPE_OK;
}
/* Show keyboard map */
t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
int32 rdx = 8;
dptr = sim_devices[0];
if (dptr->dradix == 16) rdx = 16;
fprintf (st, "%s = ", show_con_tab[flag].name);
fprint_val (st, *(cons_kmap[flag & KMAP_MASK]), rdx, 7, 0);
fprintf (st, "\n");
return SCPE_OK;
}
/* Set log routine */
t_stat sim_set_logon (int32 flag, char *cptr)
{
char gbuf[CBUFSIZE];
if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG; /* need arg */
cptr = get_glyph_nc (cptr, gbuf, 0); /* get file name */
if (*cptr != 0) return SCPE_2MARG; /* now eol? */
sim_set_logoff (0, NULL); /* close cur log */
sim_log = sim_fopen (gbuf, "a"); /* open log */
if (sim_log == NULL) return SCPE_OPENERR; /* error? */
if (!sim_quiet) printf ("Logging to file \"%s\"\n", gbuf);
fprintf (sim_log, "Logging to file \"%s\"\n", gbuf); /* start of log */
return SCPE_OK;
}
/* Set nolog routine */
t_stat sim_set_logoff (int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) return SCPE_2MARG; /* now eol? */
if (sim_log == NULL) return SCPE_OK; /* no log? */
if (!sim_quiet) printf ("Log file closed\n");
fprintf (sim_log, "Log file closed\n"); /* close log */
fclose (sim_log);
sim_log = NULL;
return SCPE_OK;
}
/* Show log status */
t_stat sim_show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
if (cptr && (*cptr != 0)) return SCPE_2MARG;
if (sim_log) fputs ("Logging enabled\n", st);
else fputs ("Logging disabled\n", st);
return SCPE_OK;
}
/* Set console to Telnet port */ /* Set console to Telnet port */
t_stat sim_set_telnet (int32 flg, char *cptr) t_stat sim_set_telnet (int32 flg, char *cptr)
{ {
if (*cptr == 0) return SCPE_2FARG; /* too few arguments? */ if ((cptr == NULL) || (*cptr == 0)) return SCPE_2FARG; /* too few arguments? */
if (sim_con_tmxr.master) return SCPE_ALATT; /* already open? */ if (sim_con_tmxr.master) return SCPE_ALATT; /* already open? */
return tmxr_open_master (&sim_con_tmxr, cptr); /* open master socket */ return tmxr_open_master (&sim_con_tmxr, cptr); /* open master socket */
} }
@ -284,6 +445,7 @@ status = sys$qiow (EFN, tty_chan,
&iosb, 0, 0, buf, 1, 0, term, 0, 0); &iosb, 0, 0, buf, 1, 0, term, 0, 0);
if ((status != SS$_NORMAL) || (iosb.status != SS$_NORMAL)) return SCPE_OK; if ((status != SS$_NORMAL) || (iosb.status != SS$_NORMAL)) return SCPE_OK;
if (buf[0] == sim_int_char) return SCPE_STOP; if (buf[0] == sim_int_char) return SCPE_STOP;
if (sim_brk_char && (buf[0] == sim_brk_char)) return SCPE_BREAK;
return (buf[0] | SCPE_KFLAG); return (buf[0] | SCPE_KFLAG);
} }
@ -349,8 +511,9 @@ if (sim_win_ctlc) {
return 003 | SCPE_KFLAG; } return 003 | SCPE_KFLAG; }
if (!_kbhit ()) return SCPE_OK; if (!_kbhit ()) return SCPE_OK;
c = _getch (); c = _getch ();
if ((c & 0177) == '\b') c = 0177; if ((c & 0177) == sim_del_char) c = 0177;
if ((c & 0177) == sim_int_char) return SCPE_STOP; if ((c & 0177) == sim_int_char) return SCPE_STOP;
if (sim_brk_char && ((c & 0177) == sim_brk_char)) return SCPE_BREAK;
return c | SCPE_KFLAG; return c | SCPE_KFLAG;
} }
@ -392,8 +555,9 @@ int c;
if (!kbhit ()) return SCPE_OK; if (!kbhit ()) return SCPE_OK;
c = getch(); c = getch();
if ((c & 0177) == '\b') c = 0177; if ((c & 0177) == sim_del_char) c = 0177;
if ((c & 0177) == sim_int_char) return SCPE_STOP; if ((c & 0177) == sim_int_char) return SCPE_STOP;
if (sim_brk_char && ((c & 0177) == sim_brk_char)) return SCPE_BREAK;
return c | SCPE_KFLAG; return c | SCPE_KFLAG;
} }
@ -561,8 +725,9 @@ int c;
if (!ps_kbhit ()) return SCPE_OK; if (!ps_kbhit ()) return SCPE_OK;
c = ps_getch(); c = ps_getch();
if ((c & 0177) == '\b') c = 0177; if ((c & 0177) == sim_del_char) c = 0177;
if ((c & 0177) == sim_int_char) return SCPE_STOP; if ((c & 0177) == sim_int_char) return SCPE_STOP;
if (sim_brk_char && ((c & 0177) == sim_brk_char)) return SCPE_BREAK;
return c | SCPE_KFLAG; return c | SCPE_KFLAG;
} }
@ -644,6 +809,7 @@ unsigned char buf[1];
status = read (0, buf, 1); status = read (0, buf, 1);
if (status != 1) return SCPE_OK; if (status != 1) return SCPE_OK;
if (sim_brk_char && (buf[0] == sim_brk_char)) return SCPE_BREAK;
else return (buf[0] | SCPE_KFLAG); else return (buf[0] | SCPE_KFLAG);
} }
@ -741,6 +907,7 @@ unsigned char buf[1];
status = read (0, buf, 1); status = read (0, buf, 1);
if (status != 1) return SCPE_OK; if (status != 1) return SCPE_OK;
if (sim_brk_char && (buf[0] == sim_brk_char)) return SCPE_BREAK;
else return (buf[0] | SCPE_KFLAG); else return (buf[0] | SCPE_KFLAG);
} }

View file

@ -23,15 +23,23 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
28-May-04 RMS Added SET/SHOW CONSOLE
02-Jan-04 RMS Removed timer routines, added Telnet console routines 02-Jan-04 RMS Removed timer routines, added Telnet console routines
*/ */
#ifndef _SIM_CONSOLE_H_ #ifndef _SIM_CONSOLE_H_
#define _SIM_CONSOLE_H_ 0 #define _SIM_CONSOLE_H_ 0
t_stat sim_set_telnet (int32 flg, char *cptr); t_stat sim_set_console (int32 flag, char *cptr);
t_stat sim_set_kmap (int32 flag, char *cptr);
t_stat sim_set_telnet (int32 flag, char *cptr);
t_stat sim_set_notelnet (int32 flag, char *cptr); t_stat sim_set_notelnet (int32 flag, char *cptr);
t_stat sim_set_logon (int32 flag, char *cptr);
t_stat sim_set_logoff (int32 flag, char *cptr);
t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_telnet (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat sim_show_telnet (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
t_stat sim_check_console (int32 sec); t_stat sim_check_console (int32 sec);
t_stat sim_poll_kbd (void); t_stat sim_poll_kbd (void);
t_stat sim_putchar (int32 c); t_stat sim_putchar (int32 c);

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik. in this Software without prior written authorization from Robert M Supnik.
26-May-04 RMS Optimized sim_fread (suggested by John Dundas)
02-Jan-04 RMS Split out from SCP 02-Jan-04 RMS Split out from SCP
This library includes: This library includes:
@ -57,8 +58,8 @@ int32 sim_end = 1; /* 1 = little */
These routines are analogs of the standard C runtime routines These routines are analogs of the standard C runtime routines
fread and fwrite. If the host is little endian, or the data items fread and fwrite. If the host is little endian, or the data items
are size char, then the calls are passed directly to fread or are size char, then the calls are passed directly to fread or
fwrite. Otherwise, these routines perform the necessary byte swaps fwrite. Otherwise, these routines perform the necessary byte swaps.
using an intermediate buffer. Sim_fread swaps in place, sim_fwrite uses an intermediate buffer.
*/ */
int32 sim_finit (void) int32 sim_finit (void)
@ -72,28 +73,21 @@ return sim_end;
size_t sim_fread (void *bptr, size_t size, size_t count, FILE *fptr) size_t sim_fread (void *bptr, size_t size, size_t count, FILE *fptr)
{ {
size_t c, j, nelem, nbuf, lcnt, total; size_t c, j;
int32 i, k; int32 k;
unsigned char *sptr, *dptr; unsigned char by, *sptr, *dptr;
if (sim_end || (size == sizeof (char))) if ((size == 0) || (count == 0)) return 0; /* check arguments */
return fread (bptr, size, count, fptr); c = fread (bptr, size, count, fptr); /* read buffer */
if ((size == 0) || (count == 0)) return 0; if (sim_end || (size == sizeof (char)) || (c == 0)) /* le, byte, or err? */
nelem = FLIP_SIZE / size; /* elements in buffer */ return c; /* done */
nbuf = count / nelem; /* number buffers */ for (j = 0, dptr = sptr = bptr; j < c; j++) { /* loop on items */
lcnt = count % nelem; /* count in last buf */ for (k = size - 1; k >= 0; k--) { /* loop on bytes/item */
if (lcnt) nbuf = nbuf + 1; by = *sptr; /* swap end-for-end */
else lcnt = nelem; *sptr++ = *(dptr + k);
total = 0; *(dptr + k) = by; }
dptr = bptr; /* init output ptr */ dptr = dptr + size; } /* next item */
for (i = nbuf; i > 0; i--) { return c;
c = fread (sim_flip, size, (i == 1? lcnt: nelem), fptr);
if (c == 0) return total;
total = total + c;
for (j = 0, sptr = sim_flip; j < c; j++) {
for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++;
dptr = dptr + size; } }
return total;
} }
size_t sim_fwrite (void *bptr, size_t size, size_t count, FILE *fptr) size_t sim_fwrite (void *bptr, size_t size, size_t count, FILE *fptr)
@ -102,9 +96,9 @@ size_t c, j, nelem, nbuf, lcnt, total;
int32 i, k; int32 i, k;
unsigned char *sptr, *dptr; unsigned char *sptr, *dptr;
if (sim_end || (size == sizeof (char))) if ((size == 0) || (count == 0)) return 0; /* check arguments */
return fwrite (bptr, size, count, fptr); if (sim_end || (size == sizeof (char))) /* le or byte? */
if ((size == 0) || (count == 0)) return 0; return fwrite (bptr, size, count, fptr); /* done */
nelem = FLIP_SIZE / size; /* elements in buffer */ nelem = FLIP_SIZE / size; /* elements in buffer */
nbuf = count / nelem; /* number buffers */ nbuf = count / nelem; /* number buffers */
lcnt = count % nelem; /* count in last buf */ lcnt = count % nelem; /* count in last buf */
@ -112,9 +106,9 @@ if (lcnt) nbuf = nbuf + 1;
else lcnt = nelem; else lcnt = nelem;
total = 0; total = 0;
sptr = bptr; /* init input ptr */ sptr = bptr; /* init input ptr */
for (i = nbuf; i > 0; i--) { for (i = nbuf; i > 0; i--) { /* loop on buffers */
c = (i == 1)? lcnt: nelem; c = (i == 1)? lcnt: nelem;
for (j = 0, dptr = sim_flip; j < c; j++) { for (j = 0, dptr = sim_flip; j < c; j++) { /* loop on items */
for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++; for (k = size - 1; k >= 0; k--) *(dptr + k) = *sptr++;
dptr = dptr + size; } dptr = dptr + size; }
c = fwrite (sim_flip, size, c, fptr); c = fwrite (sim_flip, size, c, fptr);
@ -146,6 +140,8 @@ FILE *sim_fopen (char *file, char *mode)
#if defined (VMS) #if defined (VMS)
return fopen (file, mode, "ALQ=32", "DEQ=4096", return fopen (file, mode, "ALQ=32", "DEQ=4096",
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm"); "MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
#elif defined (USE_INT64) && defined (USE_ADDR64) && defined (linux)
return fopen64 (file, mode);
#else #else
return fopen (file, mode); return fopen (file, mode);
#endif #endif
@ -250,6 +246,18 @@ return fsetpos (st, &fileaddr);
#endif /* end Windows */ #endif /* end Windows */
/* Linux */
#if defined (linux)
#define _SIM_IO_FSEEK_EXT_ 1
int sim_fseek (FILE *st, t_addr xpos, int origin)
{
return fseeko64 (st, xpos, origin);
}
#endif /* end Linux with LFS */
#endif /* end 64b seek defs */ #endif /* end 64b seek defs */
/* Default: no OS-specific routine has been defined */ /* Default: no OS-specific routine has been defined */

644
sim_rev.h

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: Simulator Usage, V3.2 Subj: Simulator Usage, V3.2-1
Date: 4-Apr-2004 Date: 15-Jun-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -527,8 +527,8 @@ These simulator-detected conditions stop simulation:
3.7.2 User Specified Stop Conditions 3.7.2 User Specified Stop Conditions
Typing the interrupt character stops simulation. The interrupt character Typing the interrupt character stops simulation. The interrupt character
is defined by the WRU (where are you) register and is initially set to is defined by the WRU (where are you) console option and is initially set
005 (^E). to 005 (^E).
3.7.3 Breakpoints 3.7.3 Breakpoints
@ -632,16 +632,6 @@ Most multi-unit devices allow units to be placed online or offline:
When a unit is offline, it will not be displayed by SHOW DEVICE. When a unit is offline, it will not be displayed by SHOW DEVICE.
The console terminal normally runs in the controlling window.
Optionally, the console terminal can be connected to a Telnet port.
This allows systems to emulate a VT100 using the built-in terminal
emulation of the Telnet client.
sim> SET TELNET <port> -- listen for console
Telnet connection on port
sim> SET NOTELNET -- disable console Telnet
sim> SHOW TELNET -- show console Telnet status
The standard device names can be supplemented with logical names. The standard device names can be supplemented with logical names.
Logical names must be unique within a simulator (that is, they cannot Logical names must be unique within a simulator (that is, they cannot
be the same as an existing device name). To assign a logical name be the same as an existing device name). To assign a logical name
@ -661,18 +651,43 @@ To show all logical names:
sim> SHOW NAMES sim> SHOW NAMES
3.11 Logging Console Output 3.11 Console Options
Output to the console can be logged simultaneously to a file. Logging Console options are controlled by the SET CONSOLE command.
is enabled by the LOG command:
sim> SET LOG <filename> -- log console output to file The console terminal normally runs in the controlling window.
Optionally, the console terminal can be connected to a Telnet port.
This allows systems to emulate a VT100 using the built-in terminal
emulation of the Telnet client.
Logging is disabled by the NOLOG command: sim> SET CONSOLE TELNET=<port> -- connect console terminal
to Telnet session on port
sim> SET CONSOLE NOTELNET -- disable console Telnet
sim> SET NOLOG -- disable logging Output to the console can be logged simultaneously to a file:
SHOW LOG displays whether logging is enabled or disabled. sim> SET CONSOLE LOG=<filename> -- log console output to file
sim> SET CONSOLE NOLOG -- disable logging
The console provides a limited key remapping capability:
sim> SET CONSOLE WRU=<value> -- interpret ASCII code
value as WRU
sim> SET CONSOLE BRK=<value> -- interpret ASCII code
value as BREAK (0 disables)
sim> SET CONSOLE DEL=<value> -- interpret ASCII code
value as DELETE
Values are hexadecimal on hex CPU's, octal on all others.
The SHOW CONSOLE command displays the current state of console options:
sim> SHOW CONSOLE -- show all console options
sim> SHOW CONSOLE TELNET -- show console Telnet state
sim> SHOW CONSOLE LOG -- show console logging state
sim> SHOW CONSOLE WRU -- show value assigned to WRU
sim> SHOW CONSOLE BRK -- show value assigned to BREAK
sim> SHOW CONSOLE DEL -- show value assigned to DELETE
3.12 Executing Command Files 3.12 Executing Command Files
@ -859,9 +874,9 @@ line printer y y y h y
clock - y y h y clock - y y h y
extra terminal - y y - y extra terminal - y y - y
hard disk h y y - y hard disk h y y - y
fixed disk - n - h - fixed disk - h - h -
floppy disk - - h - - floppy disk - - h - -
drum - n - - - drum - h - - -
DECtape - - - - - DECtape - - - - -
mag tape y y y h y mag tape y y y h y

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: Sample Software Packages Subj: Sample Software Packages
Date: 15-Jan-2004 Date: 06-Apr-2004
This memorandum documents the sample software packages available to run This memorandum documents the sample software packages available to run
with the SIMH simulators. Many of these packages are available under with the SIMH simulators. Many of these packages are available under
@ -176,7 +176,7 @@ the license.
UNIX V5 is contained on a single RK05 disk image. To boot UNIX: UNIX V5 is contained on a single RK05 disk image. To boot UNIX:
sim> set cpu 18b sim> set cpu u18
sim> att rk0 unix_v5_rk.dsk sim> att rk0 unix_v5_rk.dsk
sim> boot rk sim> boot rk
@unix @unix
@ -187,7 +187,7 @@ UNIX V5 is contained on a single RK05 disk image. To boot UNIX:
UNIX V6 is contained on four RK05 disk images. To boot UNIX: UNIX V6 is contained on four RK05 disk images. To boot UNIX:
sim> set cpu 18b sim> set cpu u18
sim> att rk0 unix0_v6_rk.dsk sim> att rk0 unix0_v6_rk.dsk
sim> att rk1 unix1_v6_rk.dsk sim> att rk1 unix1_v6_rk.dsk
sim> att rk2 unix2_v6_rk.dsk sim> att rk2 unix2_v6_rk.dsk
@ -201,7 +201,7 @@ UNIX V6 is contained on four RK05 disk images. To boot UNIX:
UNIX V7 is contained on a single RL02 disk image. To boot UNIX: UNIX V7 is contained on a single RL02 disk image. To boot UNIX:
sim> set cpu 18b sim> set cpu u18
sim> set rl0 RL02 sim> set rl0 RL02
sim> att rl0 unix_v7_rl.dsk sim> att rl0 unix_v7_rl.dsk
sim> boot rl0 sim> boot rl0
@ -212,7 +212,7 @@ UNIX V7 is contained on a single RL02 disk image. To boot UNIX:
A smaller image is contained on a single RK05 disk image. To boot UNIX: A smaller image is contained on a single RK05 disk image. To boot UNIX:
sim> set cpu 18b sim> set cpu u18
sim> att rk0 unix_v7_rk.dsk sim> att rk0 unix_v7_rk.dsk
sim> boot rk0 sim> boot rk0
@boot @boot