Notes For V3.2-3

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

1. New Features in 3.2-3

1.1 SCP

- Added ECHO command (from Dave Bryan)

2. Bugs Fixed in 3.2-2

2.1 SCP

- Qualified RESTORE detach with SIM_SW_REST
- Fixed OS/2 issues in sim_console.c and sim_sock.h

2.2 HP2100 (all from Dave Bryan)

- Changed CPU error stops to report PC not PC + 1

- Fixed CLC to DR to stop operation in progress

- Functional and timing fixes to DP
  > controller sets ATN for all commands except read status
  > controller resumes polling for ATN interrupts after read status
  > check status on unattached drive set busy and not ready
  > check status tests wrong unit for write protect status
  > drive on line sets ATN, will set FLG if polling

- Functional and timing fixes to MS
  > fixed erroneous execution of rejected command
  > fixed erroneous execution of select-only command
  > fixed erroneous execution of clear command
  > fixed odd byte handling for read
  > fixed spurious odd byte status on 13183A EOF
  > modified handling of end of medium
  > added detailed timing, with fast and realistic modes
  > added reel sizes to simulate end of tape
  > added debug printouts

- Modified MT handling of end of medium

- Added tab to TTY control char set

2.3 VAX

- VAX RQ controllers start LUNs at 0 (from Andreas Cejna)
- Added compatibility mode definitions
- Fixed EMODD, EMODG to probe second longword of quadword destination
This commit is contained in:
Bob Supnik 2004-09-03 15:31:00 -07:00 committed by Mark Pizzolato
parent 2688f2d26e
commit 2e00e1122f
26 changed files with 1701 additions and 368 deletions

View file

@ -1,32 +1,53 @@
Notes For V3.2-2
Notes For V3.2-3
RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT
enable this feature for normal operations.
RESTRICTION: The HP DS disk is not debugged. DO NOT enable this
feature under any circumstances.
feature for normal operations.
1. New Features in 3.2-2
1. New Features in 3.2-3
None
1.1 SCP
- Added ECHO command (from Dave Bryan)
2. Bugs Fixed in 3.2-2
2.1 SCP
- Fixed problem ATTACHing to read-only files (found by John Dundas)
- Fixed problems in Windows terminal code (found by Dave Bryan)
- Fixed problem in big-endian reads (reported by Scott Bailey)
- Qualified RESTORE detach with SIM_SW_REST
- Fixed OS/2 issues in sim_console.c and sim_sock.h
2.2 GRI-909
2.2 HP2100 (all from Dave Bryan)
- Updated MSR to include SOV
- Updated EAO to include additional functions
- Changed CPU error stops to report PC not PC + 1
2.2 HP2100 (from Dave Bryan)
- Fixed CLC to DR to stop operation in progress
- Generalized control character handling for console terminal
- Functional and timing fixes to DP
> controller sets ATN for all commands except read status
> controller resumes polling for ATN interrupts after read status
> check status on unattached drive set busy and not ready
> check status tests wrong unit for write protect status
> drive on line sets ATN, will set FLG if polling
- Functional and timing fixes to MS
> fixed erroneous execution of rejected command
> fixed erroneous execution of select-only command
> fixed erroneous execution of clear command
> fixed odd byte handling for read
> fixed spurious odd byte status on 13183A EOF
> modified handling of end of medium
> added detailed timing, with fast and realistic modes
> added reel sizes to simulate end of tape
> added debug printouts
- Modified MT handling of end of medium
- Added tab to TTY control char set
2.3 VAX
- Fixed bad block initialization routine
- VAX RQ controllers start LUNs at 0 (from Andreas Cejna)
- Added compatibility mode definitions
- Fixed EMODD, EMODG to probe second longword of quadword destination

View file

@ -25,6 +25,7 @@
cpu GRI-909 CPU
18-Jul-04 RMS Fixed missing ao_update calls in AX, AY write
17-Jul-04 RMS Revised MSR, EAO based on additional documentation
14-Mar-03 RMS Fixed bug in SC queue tracking
@ -381,7 +382,7 @@ extern UNIT rtc_unit;
SC = SC & AMASK; /* load local PC */
reason = 0;
AO = ao_update (); /* update AO */
ao_update (); /* update AO */
sim_rtc_init (rtc_unit.wait); /* init calibration */
/* Main instruction fetch/decode loop */
@ -517,7 +518,7 @@ else { SC = (SC + 1) & AMASK; /* incr SC */
/* Simulation halted */
AO = ao_update (); /* update AO */
ao_update (); /* update AO */
scq_r->qptr = scq_p; /* update sc q ptr */
return reason;
}
@ -700,12 +701,12 @@ return SWR;
uint32 msr_rd (uint32 src)
{
return MSR;
return MSR & MSR_RW;
}
t_stat msr_wr (uint32 src, uint32 dat)
{
MSR = dat; /* new MSR */
MSR = dat & MSR_RW; /* new MSR */
ao_update (); /* update AOV */
return SCPE_OK;
}
@ -714,28 +715,27 @@ return SCPE_OK;
uint32 ao_update (void)
{
int32 t;
int32 af = MSR_GET_FOA (MSR);
uint32 af = MSR_GET_FOA (MSR);
switch (af) {
case AO_ADD:
t = (AX + AY) & DMASK; /* add */
AO = (AX + AY) & DMASK; /* add */
break;
case AO_AND:
t = AX & AY; /* and */
AO = AX & AY; /* and */
break;
case AO_XOR: /* xor */
t = AX ^ AY;
AO = AX ^ AY;
break;
case AO_IOR:
t = AX | AY; /* or */
AO = AX | AY; /* or */
break; }
if ((AX + AY) & CBIT) MSR = MSR | MSR_AOV; /* always calc AOV */
else MSR = MSR & ~MSR_AOV;
if (SIGN & ((AX ^ (AX + AY)) & (~AX ^ AY))) /* always calc SOV */
MSR = MSR | MSR_SOV;
else MSR = MSR & ~MSR_SOV;
return t;
return AO;
}
uint32 ax_rd (uint32 src)
@ -746,6 +746,7 @@ return AX;
t_stat ax_wr (uint32 dst, uint32 dat)
{
AX = dat;
ao_update ();
return SCPE_OK;
}
@ -757,18 +758,19 @@ return AY;
t_stat ay_wr (uint32 dst, uint32 dat)
{
AY = dat;
ao_update ();
return SCPE_OK;
}
uint32 ao_rd (uint32 src)
{
AO = ao_update ();
return AO;
return ao_update ();
}
t_stat ao_fo (uint32 op)
{
uint32 t = OP_GET_FOA (op); /* get func */
MSR = MSR_PUT_FOA (MSR, t); /* store in MSR */
ao_update (); /* update AOV */
return SCPE_OK;

View file

@ -43,13 +43,10 @@
overflow is handled. Answer: EAO is a package of ROM subroutines
with just four functions: multiply, divide, arithmetic right shift,
and normalize.
Outstanding issues:
1. Is there any interaction between the byte swapper and the byte packer?
2. Is SOV testable even if the FOA is not ADD?
3. How does the EAO handle divide overflow? Answer: set link.
4. What are the other EAO functions beside multiply and divide?
4. Is SOV testable even if the FOA is not ADD? Answer: AOV and SOV are
calculated regardless of the function.
5. How does the EAO handle divide overflow? Answer: set link.
6. What are the other EAO functions beside multiply and divide?
Answer: arithmetic right shift, normalize.
*/
@ -172,11 +169,13 @@ struct gdev {
#define MSR_V_AOV 0 /* arith carry */
#define MSR_BOV (1u << MSR_V_BOV)
#define MSR_L (1u << MSR_V_L)
#define MSR_FOA (MSR_M_FOA << MSR_V_FOA)
#define MSR_SOV (1u << MSR_V_SOV)
#define MSR_AOV (1u << MSR_V_AOV)
#define MSR_GET_FOA(x) (((x) >> MSR_V_FOA) & MSR_M_FOA)
#define MSR_PUT_FOA(x,n) (((x) & ~(MSR_M_FOA << MSR_V_FOA)) | \
(((n) & MSR_M_FOA) << MSR_V_FOA))
#define MSR_RW (MSR_BOV|MSR_L|MSR_FOA|MSR_SOV|MSR_AOV)
/* Real time clock */

View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
20-Jul-04 RMS Fixed bug in breakpoint test (reported by Dave Bryan)
Back up PC on instruction errors (from Dave Bryan)
14-May-04 RMS Fixed bugs and added features from Dave Bryan
- SBT increments B after store
- DMS console map must check dms_enb
@ -801,11 +803,9 @@ if (intrq && ((intrq <= PRO) || !ion_defer)) { /* interrupt request? */
else { iotrap = 0; /* normal instruction */
err_PC = PC; /* save PC for error */
if (sim_brk_summ && /* any breakpoints? */
sim_brk_test (PC, ALL_BKPTS) && /* at this location? */
(sim_brk_test (PC, SWMASK ('E')) || /* unconditional? */
sim_brk_test (PC, dms_enb? /* or right type for DMS? */
(dms_ump? SWMASK ('U'): SWMASK ('S')):
SWMASK ('N')))) {
sim_brk_test (PC, SWMASK ('E') | /* unconditional or */
(dms_enb? (dms_ump? SWMASK ('U'): SWMASK ('S')):
SWMASK ('N')))) { /* or right type for DMS? */
reason = STOP_IBKPT; /* stop simulation */
break; }
if (mp_evrff) mp_viol = PC; /* if ok, upd mp_viol */
@ -1823,6 +1823,8 @@ if (reason == STOP_INDINT) { /* indirect intr? */
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 */
if ((reason == STOP_RSRV) || (reason == STOP_IODV) || /* instr error? */
(reason == STOP_IND)) PC = err_PC; /* back up PC */
saved_AR = AR & DMASK;
saved_BR = BR & DMASK;
dms_upd_sr (); /* update dms_sr */

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: HP2100 Simulator Usage
Date: 30-Jun-2004
Date: 20-Aug-2004
COPYRIGHT NOTICE
@ -256,11 +256,11 @@ when started.
In addition, most devices can be enabled or disabled. To enable a
device, use the SET <dev> ENABLED command:
sim> SET DP ENABLED
sim> SET DPC ENABLED
To disable a device, use the SET <dev> DISABLED command:
sim> SET DP DISABLED
sim> SET DPC DISABLED
For devices with more than one device number, disabling or enabling any
device in the set disables all the devices.
@ -643,8 +643,8 @@ The 12557A/13210A disk controller can be configured as either a
12557A, supporting 2.5MB drives, or a 13210A, supporting 5MB drives,
with the commands:
SET DP 12557A 2.5MB drives
SET DP 13210A 5.0MB drives
SET DPC 12557A 2.5MB drives
SET DPC 13210A 5.0MB drives
Drive types cannot be intermixed; the controller is configured for
one type or the other. The 13210A (for 7900/7901 disks) is selected
@ -688,7 +688,7 @@ The device controller implements these registers:
name size comments
OBUF 16 output buffer
BUSY 3 busy (unit #, + 1, of active unit)
BUSY 4 busy (unit #, + 1, of active unit)
CNT 5 check record count
CMD 1 controller enable
CTL 1 interrupt enable
@ -696,6 +696,7 @@ The device controller implements these registers:
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
EOC 1 end of cylinder pending
POLL 1 attention polling enabled
RARC[0:3] 8 record address register cylinder, drives 0-3
RARH[0:3] 2 record address register head, drives 0-3
RARS[0:3] 4 record address register sector, drives 0-3
@ -715,7 +716,7 @@ Error handling is as follows:
OS I/O error report error and stop
2.6 12565A Disk Controller (DQC, DRC) with 2883 Drives
2.6 12565A Disk Controller (DQC, DQD) with 2883 Drives
The 12565A disk controller has two separate devices, a data channel and
a device controller. The data channel includes a 128-word (one sector)
@ -899,19 +900,26 @@ Magnetic tape options include the ability to make the unit write enabled
or write locked, and the ability to select the 13181A (800 bpi) controller
or the 13183A (1600 bpi) controller.
SET MTn LOCKED set unit n write locked
SET MTn WRITEENABLED set unit n write enabled
SET MT 13181A set controller to 13181A
SET MT 13183A set controller to 13183A
SET MSCn LOCKED set unit n write locked
SET MSCn WRITEENABLED set unit n write enabled
SET MSC 13181A set controller to 13181A
SET MSC 13183A set controller to 13183A
SET MSC REALTIME set controller to actual timing
SET MSC FASTIME set controller to optimized timing (default)
SET MSCn REEL=length set unit tape reel size
0 = unlimited (default)
600 = 600 feet
1200 = 1200 feet
2400 = 2400 feet
The 13181A/13183A mag tape drive has two separate devices, a data channel
and a device controller. The data channel includes a maximum record
sized buffer for reads and writes. The device controller includes the
tape units.
The 13181A/13183A supports the BOOT command. BOOT MS loads the IBL for
The 13181A/13183A supports the BOOT command. BOOT MSC loads the IBL for
7970B/E magnetic tape drives into memory and starts it running. BOOT -S
MS causes the loader to space forward the number of files specified in
MSC causes the loader to space forward the number of files specified in
the A register before starting to load data. The switch register (S) is
set automatically to the value expected by the IBL loader:
@ -947,7 +955,11 @@ The device controller implements these registers:
FBF 1 controller ready buffer
SRQ 1 controller DMA service request
POS[0:3] 32 magtape position
BTIME 24 BOT start delay time
CTIME 24 command delay time
GTIME 24 gap traversal time
ITIME 24 IRG traversal time
RTIME 24 rewind initiation time
XTIME 24 interword transfer delay time
STOP_IOE 1 stop on I/O error

View file

@ -26,6 +26,14 @@
dp 12557A 2871 disk subsystem
13210A 7900 disk subsystem
20-Aug-04 JDB Fixes from Dave Bryan
- Check status on unattached drive set busy and not ready
- Check status tests wrong unit for write protect status
- Drive on line sets ATN, will set FLG if polling
15-Aug-04 RMS Controller resumes polling for ATN interrupts after
read status (found by Dave Bryan)
22-Jul-04 RMS Controller sets ATN for all commands except
read status (found by Dave Bryan)
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
@ -42,6 +50,29 @@
07-Sep-01 RMS Moved function prototypes
29-Nov-00 RMS Made variable names unique
21-Nov-00 RMS Fixed flag, buffer power up state
The simulator uses a number of state variables:
dpc_busy set to drive number + 1 when the controller is busy
of the unit in use
dpd_xfer set to 1 if the data channel is executing a data transfer
dpd_wval set to 1 by OTx if either !dpc_busy or dpd_xfer
dpc_poll set to 1 if attention polling is enabled
dpc_busy and dpd_xfer are set together at the start of a read, write, refine,
or init. When data transfers are complete (CLC DC), dpd_xfer is cleared, but the
operation is not necessarily over. When the operation is complete, dpc_busy
is cleared and the command channel flag is set.
dpc_busy && !dpd_xfer && STC DC (controller is busy, data channel transfer has
been terminated by CLC DC, but a word has been placed in the data channel buffer)
indicates data overrun.
dpd_wval is used in write operations to fill out the sector buffer with 0's
if only a partial sector has been transferred.
dpc_poll indicates whether seek completion polling can occur. It is cleared
by reset and CLC CC and set by issuance of a seek or completion of check status.
*/
#include "hp2100_defs.h"
@ -78,9 +109,9 @@
#define FNC_AR 013 /* address */
#define FNC_SEEK1 020 /* fake - seek1 */
#define FNC_SEEK2 021 /* fake - seek2 */
#define FNC_SEEK3 022 /* fake - seek3 */
#define FNC_CHK1 023 /* fake - check1 */
#define FNC_AR1 024 /* fake - arec1 */
#define FNC_STA1 025 /* fake - sta1 */
#define CW_V_DRV 0 /* drive */
#define CW_M_DRV 03
#define CW_GETDRV(x) (((x) >> CW_V_DRV) & CW_M_DRV)
@ -134,6 +165,7 @@ extern UNIT cpu_unit;
int32 dp_ctype = 1; /* ctrl type */
int32 dpc_busy = 0; /* cch unit */
int32 dpc_poll = 0; /* cch poll enable */
int32 dpc_cnt = 0; /* check count */
int32 dpc_eoc = 0; /* end of cyl */
int32 dpc_stime = 100; /* seek time */
@ -228,7 +260,7 @@ UNIT dpc_unit[] = {
REG dpc_reg[] = {
{ ORDATA (OBUF, dpc_obuf, 16) },
{ ORDATA (BUSY, dpc_busy, 3), REG_RO },
{ ORDATA (BUSY, dpc_busy, 4), REG_RO },
{ ORDATA (CNT, dpc_cnt, 5) },
{ FLDATA (CMD, dpc_dib.cmd, 0) },
{ FLDATA (CTL, dpc_dib.ctl, 0) },
@ -236,6 +268,7 @@ REG dpc_reg[] = {
{ FLDATA (FBF, dpc_dib.fbf, 0) },
{ FLDATA (SRQ, dpc_dib.srq, 0) },
{ FLDATA (EOC, dpc_eoc, 0) },
{ FLDATA (POLL, dpc_poll, 0) },
{ BRDATA (RARC, dpc_rarc, 8, 8, DP_NUMDRV) },
{ BRDATA (RARH, dpc_rarh, 8, 2, DP_NUMDRV) },
{ BRDATA (RARS, dpc_rars, 8, 4, DP_NUMDRV) },
@ -350,7 +383,8 @@ case ioCTL: /* control clear/set */
if (dpc_busy) sim_cancel (&dpc_unit[dpc_busy - 1]);
sim_cancel (&dpd_unit); /* cancel dch */
dpd_xfer = 0; /* clr dch xfer */
dpc_busy = 0; } /* clr cch busy */
dpc_busy = 0; /* clr cch busy */
dpc_poll = 0; } /* clr cch poll */
else { /* STC */
setCTL (devc); /* set ctl */
if (!CMD (devc)) { /* is cmd clr? */
@ -358,9 +392,13 @@ case ioCTL: /* control clear/set */
drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */
fnc = CW_GETFNC (dpc_obuf); /* from cmd word */
switch (fnc) { /* case on fnc */
case FNC_SEEK: /* seek */
dpc_poll = 1; /* enable polling */
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
break;
case FNC_STA: /* rd sta */
if (dp_ctype) { clrFSR (devd); } /* 13210? clr dch flag */
case FNC_SEEK: case FNC_CHK: /* seek, check */
case FNC_CHK: /* check */
case FNC_AR: /* addr rec */
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
break;
@ -391,15 +429,18 @@ return;
void dp_goc (int32 fnc, int32 drv, int32 time)
{
if (sim_is_active (&dpc_unit[drv])) { /* still seeking? */
int32 t;
if (t = sim_is_active (&dpc_unit[drv])) { /* still seeking? */
sim_cancel (&dpc_unit[drv]); /* stop seek */
dpc_sta[drv] = dpc_sta[drv] & ~STA_BSY; /* clear busy */
time = time + dpc_stime; } /* take longer */
time = time + t; } /* include seek time */
dp_ptr = 0; /* init buf ptr */
dpc_eoc = 0; /* clear end cyl */
dpc_busy = drv + 1; /* set busy */
dpd_xfer = 1; /* xfer in prog */
dpc_unit[drv].FNC = fnc; /* save function */
dpc_sta[drv] = dpc_sta[drv] & ~STA_ATN; /* clear ATN */
sim_activate (&dpc_unit[drv], time); /* activate unit */
return;
}
@ -425,7 +466,7 @@ return;
t_stat dpd_svc (UNIT *uptr)
{
int32 drv, devc, devd, st;
int32 i, drv, devc, devd, st;
drv = uptr->CYL; /* get drive no */
devc = dpc_dib.devno; /* get cch devno */
@ -478,7 +519,8 @@ case FNC_AR1: /* arec, need hd/sec */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
setFSR (devd); /* set dch flg */
clrCMD (devd); } /* clr dch cmd */
clrCMD (devd); /* clr dch cmd */
dpc_sta[drv] = dpc_sta[drv] | STA_ATN; } /* set drv attn */
else sim_activate (uptr, dpc_xtime); /* no, wait more */
break;
@ -488,8 +530,8 @@ case FNC_STA: /* read status */
dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */
if (dp_ctype) dpd_ibuf = /* 13210? */
(dpd_ibuf & ~(STA_MBZ13 | STA_PROT)) |
(uptr->flags & UNIT_WPRT? STA_PROT: 0); }
else dpd_ibuf = STA_NRDY; /* not ready */
(dpc_unit[drv].flags & UNIT_WPRT? STA_PROT: 0); }
else dpd_ibuf = STA_NRDY|STA_BSY; /* not ready */
if (dpd_ibuf & STA_ALLERR) /* errors? set flg */
dpd_ibuf = dpd_ibuf | STA_ERR;
setFSR (devd); /* set dch flg */
@ -498,8 +540,16 @@ case FNC_STA: /* read status */
dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */
~(STA_ATN | STA_1ST | STA_OVR |
STA_RWU | STA_ACU | STA_EOC |
STA_AER | STA_FLG | STA_DTE); }
else sim_activate (uptr, dpc_xtime); /* wait more */
STA_AER | STA_FLG | STA_DTE);
uptr->FNC = FNC_STA1; } /* advance state */
sim_activate (uptr, dpc_xtime); /* no, wait more */
break;
case FNC_STA1: /* read sta, poll */
dpc_poll = 1; /* enable polling */
for (i = 0; i < DP_NUMDRV; i++) { /* loop thru drives */
if (dpc_sta[i] & STA_ATN) { /* any ATN set? */
setFSR (devc); /* set cch flg */
break; } }
break;
case FNC_CHK: /* check, need cnt */
@ -547,7 +597,9 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
clrCMD (devc); /* clr cch cmd */
dpc_sta[drv] = 0; /* clr status */
dpc_busy = 0; /* ctlr is free */
dpd_xfer = dpd_wval = 0;
dpc_poll = 0; /* polling disabled */
dpd_xfer = 0;
dpd_wval = 0;
return SCPE_OK; }
switch (uptr->FNC) { /* case function */
@ -556,11 +608,7 @@ case FNC_SEEK2: /* seek done */
if (uptr->CYL >= DP_NUMCY) { /* invalid cyl? */
dpc_sta[drv] = dpc_sta[drv] | STA_SKE;
uptr->CYL = DP_NUMCY - 1; }
case FNC_SEEK3: /* waiting for flag */
if (dpc_busy || FLG (devc)) { /* ctrl busy? wait */
uptr->FNC = FNC_SEEK3; /* next state */
sim_activate (uptr, dpc_xtime); }
else {
if (dpc_poll) { /* polling enabled? */
setFSR (devc); /* set cch flg */
clrCMD (devc); } /* clear cmd */
return SCPE_OK;
@ -639,7 +687,7 @@ case FNC_WD: /* write */
default:
return SCPE_IERR; } /* end case fnc */
if (!dp_ctype) dpc_sta[drv] = dpc_sta[drv] | STA_ATN; /* 12559 sets ATN */
dpc_sta[drv] = dpc_sta[drv] | STA_ATN; /* set ATN */
setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */
dpc_busy = 0; /* ctlr is free */
@ -661,6 +709,7 @@ hp_enbdis_pair (&dpc_dev, &dpd_dev); /* make pair cons */
dpd_ibuf = dpd_obuf = 0; /* clear buffers */
dpc_busy = dpc_obuf = 0;
dpc_eoc = 0;
dpc_poll = 0;
dpd_xfer = dpd_wval = 0;
dp_ptr = 0;
dpc_dib.cmd = dpd_dib.cmd = 0; /* clear cmd */
@ -690,7 +739,11 @@ t_stat r;
drv = uptr - dpc_dev.units; /* get drive no */
r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r;
dpc_sta[drv] = dpc_sta[drv] | STA_1ST; /* update status */
dpc_sta[drv] = dpc_sta[drv] | STA_ATN | STA_1ST; /* update status */
if (dpc_poll) { /* polling enabled? */
dpc_dib.fbf = 1; /* set fbf */
dpc_dib.flg = 1; /* set flg */
dpc_dib.srq = 1; } /* srq follows flg */
return r;
}

View file

@ -352,9 +352,11 @@ return;
void dq_goc (int32 fnc, int32 drv, int32 time)
{
if (sim_is_active (&dqc_unit[drv])) { /* still seeking? */
int32 t;
if (t = sim_is_active (&dqc_unit[drv])) { /* still seeking? */
sim_cancel (&dqc_unit[drv]); /* cancel */
time = time + dqc_stime; } /* take longer */
time = time + t; } /* include seek time */
dqc_sta[drv] = 0; /* clear status */
dq_ptr = 0; /* init buf ptr */
dqc_busy = drv + 1; /* set busy */
@ -456,7 +458,7 @@ case FNC_STA: /* read status */
if (CMD (devd)) { /* dch active? */
if (dqc_unit[drv].flags & UNIT_ATT) /* attached? */
dqd_ibuf = dqc_sta[drv] & ~STA_DID;
else dqd_ibuf = STA_NRDY;
else dqd_ibuf = STA_NRDY|STA_BSY;
if (drv) dqd_ibuf = dqd_ibuf | STA_DID;
setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */

View file

@ -35,6 +35,7 @@
The drum control channel does not have any of the traditional flip-flops.
26-Aug-04 RMS Fixed CLC to stop operation (from Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Revised boot rom to use IBL algorithm
Implemented DMA SRQ (follows FLG)
@ -248,6 +249,7 @@ case ioCTL: /* control clear/set */
if (IR & I_AB) { /* CLC */
clrCMD (devd); /* clr "ctl" */
clrFSR (devd); /* clr flg */
sim_cancel (&drc_unit); /* cancel curr op */
drc_sta = drc_sta & ~DRS_SAC; } /* clear SAC flag */
else if (!CMD (devd)) { /* STC, not set? */
setCMD (devd); /* set "ctl" */

View file

@ -53,9 +53,9 @@
#define DS_NUMDR 8 /* max drives */
#define DS_DRMASK (DS_NUMDR - 1)
#define DS_NUMWD 128 /* words/sector */
#define DS_NUMWDF 138 /* words/full sec */
#define DS_FSYNC 0 /* full offsets */
#define DS_NUMWD 128 /* data words/sec */
#define DS_NUMWDF 138 /* total words/sec */
#define DS_FSYNC 0 /* sector offsets */
#define DS_FCYL 1
#define DS_FHS 2
#define DS_FDATA 3
@ -190,7 +190,7 @@
#define DS1_CYLCE (007 << DS1_V_STAT) /* cyl compare err */
#define DS1_UNCOR (010 << DS1_V_STAT) /* uncor data err */
#define DS1_HSCE (011 << DS1_V_STAT) /* h/s compare err */
#define DS1_IOPE (012 << DS1_V_STAT) /* IO operation err - na */
#define DS1_IOPE (012 << DS1_V_STAT) /* IO oper err - na */
#define DS1_EOCYL (014 << DS1_V_STAT) /* end cylinder */
#define DS1_OVRUN (016 << DS1_V_STAT) /* overrun */
#define DS1_CORDE (017 << DS1_V_STAT) /* correctible - na */
@ -332,6 +332,10 @@ static const uint32 ds_opflags[32] = { /* flags for ops */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_CLRS|CMF_UNIT|CMF_UIDLE, /* read no verify */
CMF_CLRS, /* write TIO */
CMF_CLRS, /* read disk addr */
CMF_CLRS, /* end */
CMF_CLRS, /* wake */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
@ -340,10 +344,7 @@ static const uint32 ds_opflags[32] = { /* flags for ops */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS, /* undefined */
CMF_UNDF|CMF_CLRS }; /* undefined */
CMF_UNDF|CMF_CLRS, }; /* undefined */
DEVICE ds_dev;
int32 dsio (int32 inst, int32 IR, int32 dat);
@ -418,7 +419,7 @@ REG ds_reg[] = {
{ ORDATA (UNIT, ds_u, 4) },
{ ORDATA (FMASK, ds_fmask, 8) },
{ ORDATA (CYL, ds_cyl, 16) },
{ ORDATA (HS, ds_hs, 12) },
{ ORDATA (HS, ds_hs, 16) },
{ ORDATA (STATE, ds_state, 2), REG_RO },
{ ORDATA (LASTA, ds_lastatn, 3) },
{ DRDATA (FIP, ds_fifo_ip, 4) },
@ -492,7 +493,7 @@ DEVICE ds_dev = {
DS_NUMDR + 2, 8, 27, 1, 8, 16,
NULL, NULL, &ds_reset,
&ds_boot, &ds_attach, &ds_detach,
&ds_dib, DEV_DISABLE };
&ds_dib, DEV_DISABLE | DEV_DIS };
/* IO instructions */
@ -526,6 +527,7 @@ case ioLIX: /* load */
break;
case ioCTL: /* control clear/set */
if (IR & I_CTL) { /* CLC */
clrCTL (dev); /* clear control */
ds_cmdf = 1; /* expecting command */
ds_cmdp = 0; /* none pending */
ds_fifo_reset (); } /* clear fifo */
@ -551,9 +553,9 @@ return dat;
void ds_poll (void)
{
uint32 i;
uint32 dev = ds_dib.devno;
uint32 i, dev;
dev = ds_dib.devno; /* device num */
if (ds_state == DS_BUSY) return; /* ctrl busy? */
if (ds_cmdp) ds_docmd (ds_cmd); /* cmd pending? */
if ((ds_state != DS_IDLE) || !CTL (dev)) return; /* waiting for cmd or */
@ -579,10 +581,10 @@ return;
void ds_docmd (uint32 cmd)
{
uint32 op = DSC_GETOP (cmd); /* operation */
uint32 f = ds_opflags[op]; /* flags */
uint32 dtyp;
uint32 op, f, dtyp;
op = DSC_GETOP (cmd); /* operation */
f = ds_opflags[op]; /* flags */
if (op == DSC_COLD) ds_u = 0; /* boot force unit 0 */
else ds_u = DSC_GETUNIT (cmd); /* get unit */
if ((f & CMF_UIDLE) && (ds_u < DS_NUMDR) && /* idle required */
@ -672,9 +674,10 @@ return;
t_stat ds_svc_c (UNIT *uptr)
{
uint32 op = uptr->FNC;
uint32 dev = ds_dib.devno;
uint32 op, dev;
op = uptr->FNC;
dev = ds_dib.devno;
switch (op) {
case DSC_AREC: /* address record */
@ -760,11 +763,12 @@ return SCPE_OK;
t_stat ds_svc_u (UNIT *uptr)
{
uint32 op = uptr->FNC;
uint32 dev = ds_dib.devno;
uint32 dtyp = GET_DTYPE (uptr->flags);
uint32 op, dev, dtyp;
t_stat r;
op = uptr->FNC;
dev = ds_dib.devno;
dtyp = GET_DTYPE (uptr->flags);
switch (op) { /* case on function */
/* Seek and recalibrate */
@ -830,11 +834,11 @@ case DSC_READ | DSC_3RD: /* end of sector */
break;
case DSC_RFULL: /* read full */
if (r = ds_start_rd (uptr, DS_FDATA, 0)) /* new sector; error? */
return r;
dsxb[DS_FSYNC] = 0100376; /* fill in header */
dsxb[DS_FCYL] = uptr->CYL;
dsxb[DS_FHS] = ds_hs;
dsxb[DS_FHS] = ds_hs; /* before h/s update */
if (r = ds_start_rd (uptr, DS_FDATA, 0)) /* new sector; error? */
return r;
break;
case DSC_RFULL | DSC_2ND: /* word transfer */
ds_cont_rd (uptr, DS_NUMWDF); /* xfr wd, check end */
@ -994,13 +998,13 @@ int32 t;
uint32 dtyp = GET_DTYPE (uptr->flags);
uptr->FNC = newst; /* set new state */
uptr->STA = uptr->STA & ~DS2_SC; /* clear seek check */
if (cyl >= drv_tab[dtyp].cyl) { /* out of bounds? */
uptr->CYL = t = drv_tab[dtyp].cyl; /* put off edge */
uptr->STA = uptr->STA | DS2_SC; } /* set seek check */
else { /* seek in range */
t = abs (uptr->CYL - cyl); /* delta cylinders */
uptr->CYL = cyl; } /* put on cylinder */
uptr->CYL = cyl; /* put on cylinder */
uptr->STA = uptr->STA & ~DS2_SC; } /* clear seek check */
sim_activate (uptr, ds_stime * (t + 1)); /* schedule */
return;
}
@ -1017,6 +1021,7 @@ t_bool ds_start_rw (UNIT *uptr, int32 tm, t_bool vfy)
uint32 da, hd, sc;
uint32 dtyp = GET_DTYPE (uptr->flags);
ds_eod = 0; /* clear eod */
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
ds_cmd_done (1, DS1_S2ERR);
return TRUE; }
@ -1037,7 +1042,7 @@ if ((hd >= drv_tab[dtyp].hd) || /* valid head, sector? */
ds_cmd_done (1, DS1_HSCE); /* no, error */
return TRUE; }
da = GET_DA (uptr->CYL, hd, sc, dtyp); /* position in file */
fseek (uptr->fileref, da * sizeof (uint16), SEEK_SET); /* set up I/O oper */
sim_fseek (uptr->fileref, da * sizeof (uint16), SEEK_SET); /* set file pos */
ds_ptr = 0; /* init buffer ptr */
uptr->FNC += DSC_NEXT; /* next state */
sim_activate (uptr, tm); /* activate unit */
@ -1060,7 +1065,7 @@ uint32 t;
if (ds_start_rw (uptr, ds_rtime, vfy)) /* new sector; error? */
return SCPE_OK; /* nothing scheduled */
t = sim_fread (dsxb + off, sizeof (uint16), DS_NUMWD, uptr->fileref);
for ( ; t < (DS_NUMWDF - off); t++) dsxb[t] = 0; /* fill sector */
for (t = t + off ; t < DS_NUMWDF; t++) dsxb[t] = 0; /* fill sector */
if (ferror (uptr->fileref)) /* error? */
return ds_set_uncorr (uptr); /* say uncorrectable */
ds_next_sec (uptr); /* increment hd, sc */
@ -1077,9 +1082,9 @@ return SCPE_OK;
void ds_start_wr (UNIT *uptr, t_bool vfy)
{
uint32 i;
uint32 dev = ds_dib.devno;
uint32 i, dev;
dev = ds_dib.devno;
if ((uptr->flags & UNIT_WPR) || /* write protected? */
(!vfy && ((uptr->flags & UNIT_FMT) == 0))) { /* format, not enbl? */
ds_cmd_done (1, DS1_S2ERR); /* error */
@ -1095,15 +1100,13 @@ return;
void ds_next_sec (UNIT *uptr)
{
uint32 dtyp = GET_DTYPE (uptr->flags);
uint32 hd = DSHS_GETHD (ds_hs);
uint32 sc = DSHS_GETSC (ds_hs);
ds_hs = ds_hs + 1; /* increment sector */
if (sc < drv_tab[dtyp].sc) return; /* end of track? */
if (DSHS_GETSC (ds_hs) < drv_tab[dtyp].sc) return; /* end of track? */
ds_hs = ds_hs & ~DSHS_SC; /* yes, wrap sector */
if (ds_fmask & DSC_CYLM) { /* cylinder mode? */
ds_hs = ds_hs + (1 << DSHS_V_HD); /* increment head */
if (hd < drv_tab[dtyp].hd) return; /* end of cyl? */
if (DSHS_GETHD (ds_hs) < drv_tab[dtyp].hd) return; /* end of cyl? */
ds_hs = ds_hs & ~DSHS_HD; } /* 0 head */
ds_eoc = 1; /* flag end cylinder */
return;
@ -1180,7 +1183,7 @@ void ds_end_rw (UNIT *uptr, uint32 newst)
{
uptr->FNC = newst; /* new state */
if (ds_eod) ds_cmd_done (1, DS1_OK); /* done? */
else if (ds_eoc) ds_next_cyl (uptr); /* end cyl? seek if auto */
else if (ds_eoc) ds_next_cyl (uptr); /* end cyl? seek */
else sim_activate (uptr, ds_rtime); /* normal transfer */
return;
}
@ -1275,9 +1278,9 @@ uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */
uptr->STA = DS2_ATN | DS2_FS; /* update drive status */
if (ds_dib.ctl) ds_sched_attn (uptr); /* if CTL, sched ATTN */
if (((p = sim_fsize (uptr->fileref)) == 0) || /* new disk image? */
((uptr->flags & UNIT_AUTO) == 0)) return SCPE_OK; /* static size? */
ds_sched_attn (uptr); /* schedule attention */
if (((uptr->flags & UNIT_AUTO) == 0) || /* static size? */
((p = sim_fsize (uptr->fileref)) == 0)) return SCPE_OK; /* new file? */
for (i = 0; drv_tab[i].sc != 0; i++) { /* find best fit */
if (p <= (drv_tab[i].size * sizeof (uint16))) {
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
@ -1291,16 +1294,17 @@ return SCPE_OK;
t_stat ds_detach (UNIT *uptr)
{
uptr->STA = DS2_ATN; /* update drive status */
if (ds_dib.ctl) ds_sched_attn (uptr); /* if CTL, sched ATTN */
ds_sched_attn (uptr); /* schedule attention */
return detach_unit (uptr);
}
/* Schedule attention interrupt if controller idle */
/* Schedule attention interrupt if CTL set, not restore, and controller idle */
void ds_sched_attn (UNIT *uptr)
{
int32 i;
if (!ds_dib.ctl || (sim_switches & SIM_SW_REST)) return;
for (i = 0; i < (DS_NUMDR + 1); i++) { /* check units, ctrl */
if (sim_is_active (ds_dev.units + i)) return; }
uptr->FNC = DSC_ATTN; /* pseudo operation */

View file

@ -26,6 +26,16 @@
ms 13181A 7970B 800bpi nine track magnetic tape
13183A 7970E 1600bpi nine track magnetic tape
14-Aug-04 JDB Fixed many functional and timing problems (from Dave Bryan)
- fixed erroneous execution of rejected command
- fixed erroneous execution of select-only command
- fixed erroneous execution of clear command
- fixed odd byte handling for read
- fixed spurious odd byte status on 13183A EOF
- modified handling of end of medium
- added detailed timing, with fast and realistic modes
- added reel sizes to simulate end of tape
- added debug printouts
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
@ -53,9 +63,6 @@
If the byte count is odd, the record is padded with an extra byte
of junk. File marks are represented by a byte count of 0.
Unusually among HP peripherals, the 12559 does not have a command flop,
and its flag and flag buffer power up as clear rather than set.
*/
#include "hp2100_defs.h"
@ -66,6 +73,9 @@
#define DBSIZE (1 << DB_N_SIZE) /* max data cmd */
#define FNC u3 /* function */
#define UST u4 /* unit status */
#define REEL u5 /* tape reel size */
#define TCAP (300 * 12 * 800) /* 300 ft capacity at 800bpi */
/* Command - msc_fnc */
@ -82,6 +92,7 @@
#define FNC_RWS 00105 /* rewind and offline */
#define FNC_WFM 00211 /* write file mark */
#define FNC_RFF 00223 /* "read file fwd" */
#define FNC_CMPL 00400 /* completion state */
#define FNC_V_SEL 9 /* select */
#define FNC_M_SEL 017
#define FNC_GETSEL(x) (((x) >> FNC_V_SEL) & FNC_M_SEL)
@ -93,6 +104,8 @@
#define FNF_RWD 00100 /* rewind */
#define FNF_CHS 00400 /* change select */
#define FNC_SEL ((FNC_M_SEL << FNC_V_SEL) | FNF_CHS)
/* Status - stored in msc_sta, unit.UST (u), or dynamic (d) */
#define STA_PE 0100000 /* 1600 bpi (d) */
@ -105,7 +118,7 @@
#define STA_BUSY 0000400 /* ctrl busy */
#define STA_EOF 0000200 /* end of file */
#define STA_BOT 0000100 /* beg of tape (u) */
#define STA_EOT 0000040 /* end of tape (u) */
#define STA_EOT 0000040 /* end of tape (d) */
#define STA_TIM 0000020 /* timing error */
#define STA_REJ 0000010 /* programming error */
#define STA_WLK 0000004 /* write locked (d) */
@ -118,21 +131,52 @@ extern uint32 PC, SR;
extern uint32 dev_cmd[2], dev_ctl[2], dev_flg[2], dev_fbf[2], dev_srq[2];
extern int32 sim_switches;
extern UNIT cpu_unit;
extern FILE *sim_deb;
int32 ms_ctype = 0; /* ctrl type */
int32 ms_timing = 1; /* timing type */
int32 msc_sta = 0; /* status */
int32 msc_buf = 0; /* buffer */
int32 msc_usl = 0; /* unit select */
int32 msc_1st = 0;
int32 msc_ctime = 1000; /* command wait */
int32 msc_gtime = 1000; /* gap stop time */
int32 msc_rtime = 1000; /* rewind wait */
int32 msc_xtime = 15; /* data xfer time */
int32 msc_stopioe = 1; /* stop on error */
int32 msd_buf = 0; /* data buffer */
uint8 msxb[DBSIZE] = { 0 }; /* data buffer */
t_mtrlnt ms_ptr = 0, ms_max = 0; /* buffer ptrs */
/* Hardware timing at 45 IPS 13181 13183
(based on 1580 instr/msec) instr msec SCP instr msec SCP
-------------------- --------------------
- BOT start delay : btime = 161512 102.22 184 252800 160.00 288
- motion cmd start delay : ctime = 14044 8.89 16 17556 11.11 20
- GAP traversal time : gtime = 175553 111.11 200 105333 66.67 120
- IRG traversal time : itime = 24885 15.75 - 27387 17.33 -
- rewind initiation time : rtime = 878 0.56 1 878 0.56 1
- data xfer time / word : xtime = 88 55.56us - 44 27.78us -
NOTE: The 13181-60001 Rev. 1629 tape diagnostic fails test 17B subtest 6 with
"E116 BYTE TIME SHORT" if the correct data transfer time is used for
13181A interface. Set "xtime" to 115 (instructions) to pass that
diagnostic. Rev. 2040 of the tape diagnostic fixes this problem and
passes with the correct data transfer time.
*/
int32 msc_btime = 0; /* BOT start delay */
int32 msc_ctime = 0; /* motion cmd start delay */
int32 msc_gtime = 0; /* GAP traversal time */
int32 msc_itime = 0; /* IRG traversal time */
int32 msc_rtime = 0; /* rewind initiation time */
int32 msc_xtime = 0; /* data xfer time / word */
typedef int32 TIMESET[6]; /* set of controller times */
int32 *const timers[] = { &msc_btime, &msc_ctime, &msc_gtime,
&msc_itime, &msc_rtime, &msc_xtime };
const TIMESET times[3] = { { 161512, 14044, 175553, 24885, 878, 88 }, /* 13181A */
{ 252800, 17556, 105333, 27387, 878, 44 }, /* 13183A */
{ 1, 1000, 1, 1, 100, 10 } };/* FAST */
DEVICE msd_dev, msc_dev;
int32 msdio (int32 inst, int32 IR, int32 dat);
int32 mscio (int32 inst, int32 IR, int32 dat);
@ -144,6 +188,11 @@ t_stat msc_boot (int32 unitno, DEVICE *dptr);
t_stat ms_map_err (UNIT *uptr, t_stat st);
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ms_showtype (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat ms_set_timing (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ms_show_timing (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat ms_set_reelsize (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat ms_show_reelsize (FILE *st, UNIT *uptr, int32 val, void *desc);
void ms_config_timing (void);
/* MSD data structures
@ -213,10 +262,14 @@ REG msc_reg[] = {
{ URDATA (POS, msc_unit[0].pos, 10, T_ADDR_W, 0, MS_NUMDR, PV_LEFT) },
{ URDATA (FNC, msc_unit[0].FNC, 8, 8, 0, MS_NUMDR, REG_HRO) },
{ URDATA (UST, msc_unit[0].UST, 8, 12, 0, MS_NUMDR, REG_HRO) },
{ URDATA (REEL, msc_unit[0].REEL, 10, 2, 0, MS_NUMDR, REG_HRO) },
{ DRDATA (BTIME, msc_btime, 24), REG_NZ + PV_LEFT },
{ DRDATA (CTIME, msc_ctime, 24), REG_NZ + PV_LEFT },
{ DRDATA (GTIME, msc_gtime, 24), REG_NZ + PV_LEFT },
{ DRDATA (ITIME, msc_itime, 24), REG_NZ + PV_LEFT },
{ DRDATA (RTIME, msc_rtime, 24), REG_NZ + PV_LEFT },
{ DRDATA (XTIME, msc_xtime, 24), REG_NZ + PV_LEFT },
{ FLDATA (TIMING, ms_timing, 0), REG_HRO },
{ FLDATA (STOP_IOE, msc_stopioe, 0) },
{ FLDATA (CTYPE, ms_ctype, 0), REG_HRO },
{ ORDATA (DEVNO, msc_dib.devno, 6), REG_HRO },
@ -225,6 +278,8 @@ REG msc_reg[] = {
MTAB msc_mod[] = {
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
{ MTAB_XTD|MTAB_VUN, 0, "REEL", "REEL",
&ms_set_reelsize, &ms_show_reelsize, NULL },
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "13181A",
@ -233,6 +288,12 @@ MTAB msc_mod[] = {
&ms_settype, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, 0, "TYPE", NULL,
NULL, &ms_showtype, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "REALTIME",
&ms_set_timing, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, 1, NULL, "FASTTIME",
&ms_set_timing, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, 0, "TIMING", NULL,
NULL, &ms_show_timing, NULL },
{ MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
&hp_setdev, &hp_showdev, &msd_dev },
{ 0 } };
@ -242,7 +303,7 @@ DEVICE msc_dev = {
MS_NUMDR, 10, 31, 1, 8, 8,
NULL, NULL, &msc_reset,
&msc_boot, &msc_attach, &msc_detach,
&msc_dib, DEV_DISABLE };
&msc_dib, DEV_DISABLE | DEV_DEBUG };
/* IOT routines */
@ -289,7 +350,7 @@ return dat;
int32 mscio (int32 inst, int32 IR, int32 dat)
{
int32 i, devc, devd;
int32 i, devc, devd, sched_time;
t_stat st;
UNIT *uptr = msc_dev.units + msc_usl;
static const uint8 map_sel[16] = {
@ -309,6 +370,8 @@ case ioSFS: /* skip flag set */
if (FLG (devc) != 0) PC = (PC + 1) & VAMASK;
break;
case ioOTX: /* output */
if (DEBUG_PRS (msc_dev))
fprintf (sim_deb, ">>MSC OTx: Command = %06o\n", dat);
msc_buf = dat;
msc_sta = msc_sta & ~STA_REJ; /* clear reject */
if ((dat & 0377) == FNC_CLR) break; /* clear always ok */
@ -326,19 +389,26 @@ case ioOTX: /* output */
case ioLIX: /* load */
dat = 0;
case ioMIX: /* merge */
dat = dat | ((msc_sta | uptr->UST) & ~STA_DYN);
dat = dat | (msc_sta & ~STA_DYN); /* get card status */
if (uptr->flags & UNIT_ATT) { /* online? */
if (sim_is_active (uptr)) /* busy */
dat = dat | uptr->UST; /* add unit status */
if (sim_is_active (uptr) && /* TBSY unless RWD at BOT */
!((uptr->FNC & FNF_RWD) && (uptr->UST & STA_BOT)))
dat = dat | STA_TBSY;
if (sim_tape_wrp (uptr)) /* write prot? */
dat = dat | STA_WLK; }
dat = dat | STA_WLK;
if (uptr->REEL &&
sim_tape_eot (uptr, (TCAP << uptr->REEL) << ms_ctype))
dat = dat | STA_EOT; }
else dat = dat | STA_TBSY | STA_LOCAL;
if (ms_ctype) dat = dat | STA_PE | /* 13183A? */
(msc_usl << STA_V_SEL);
if (DEBUG_PRS (msc_dev))
fprintf (sim_deb, ">>MSC LIx: Status = %06o\n", dat);
break;
case ioCTL: /* control clear/set */
if (IR & I_CTL) { clrCTL (devc); } /* CLC */
else { /* STC */
else if (!(msc_sta & STA_REJ)) { /* STC, last cmd rejected? */
if ((msc_buf & 0377) == FNC_CLR) { /* clear? */
for (i = 0; i < MS_NUMDR; i++) { /* loop thru units */
if (sim_is_active (&msc_unit[i]) && /* write in prog? */
@ -346,18 +416,35 @@ case ioCTL: /* control clear/set */
if (st = sim_tape_wrrecf (uptr, msxb, ms_ptr | MTR_ERF))
ms_map_err (uptr, st); }
if ((msc_unit[i].UST & STA_REW) == 0)
sim_cancel (&msc_unit[i]); } /* stop if now rew */
clrCTL (devc); /* init device */
setFSR (devc);
clrCTL (devd);
setFSR (devd);
msc_sta = msd_buf = msc_buf = msc_1st = 0;
sim_cancel (&msc_unit[i]); } /* stop if not rew */
setCTL (devc); /* set CTL for STC */
setFSR (devc); /* set FLG for completion */
msc_sta = msc_1st = 0; /* clr ctlr status */
if (DEBUG_PRS (msc_dev))
fputs (">>MSC STC: Controller cleared\n", sim_deb);
return SCPE_OK; }
uptr->FNC = msc_buf & 0377; /* save function */
if (uptr->FNC & FNF_RWD) /* rewind? */
sim_activate (uptr, msc_rtime); /* fast response */
else sim_activate (uptr, msc_ctime); /* schedule op */
uptr->UST = 0; /* clear status */
if (uptr->FNC & FNF_RWD) { /* rewind? */
if (!(uptr->UST & STA_BOT)) /* not at BOT? */
uptr->UST = STA_REW; /* set rewinding */
sched_time = msc_rtime; } /* set response time */
else {
if (uptr-> UST & STA_BOT) /* at BOT? */
sched_time = msc_btime; /* use BOT start time */
else if ((uptr->FNC == FNC_GAP) || (uptr->FNC == FNC_GFM))
sched_time = msc_gtime; /* use gap traversal time */
else sched_time = 0;
if (uptr->FNC != FNC_GAP)
sched_time += msc_ctime; /* add base command time */
if (uptr->FNC & FNF_MOT) /* motion command? */
uptr->UST = 0; } /* clear BOT status */
if (msc_buf & ~FNC_SEL) { /* NOP for unit sel alone */
sim_activate (uptr, sched_time); /* else schedule op */
if (DEBUG_PRS (msc_dev)) fprintf (sim_deb,
">>MSC STC: Unit %d command %03o scheduled, time = %d\n",
msc_usl, uptr->FNC, sched_time); }
else if (DEBUG_PRS (msc_dev))
fputs (">>MSC STC: Unit select (NOP)\n", sim_deb);
msc_sta = STA_BUSY; /* ctrl is busy */
msc_1st = 1;
setCTL (devc); } /* go */
@ -381,29 +468,34 @@ return dat;
t_stat msc_svc (UNIT *uptr)
{
int32 devc, devd;
int32 devc, devd, unum, cap;
t_mtrlnt tbc;
t_stat st, r = SCPE_OK;
devc = msc_dib.devno; /* get device nos */
devd = msd_dib.devno;
unum = uptr - msc_dev.units; /* get unit number */
if ((uptr->flags & UNIT_ATT) == 0) { /* offline? */
if ((uptr->FNC != FNC_RWS) && !(uptr->flags & UNIT_ATT)) { /* offline? */
msc_sta = (msc_sta | STA_REJ) & ~STA_BUSY; /* reject */
setFSR (devc); /* set cch flg */
return IORETURN (msc_stopioe, SCPE_UNATT); }
switch (uptr->FNC) { /* case on function */
case FNC_REW: /* rewind */
case FNC_RWS: /* rewind offline */
detach_unit (uptr); /* detach == offline */
break; /* we're done */
case FNC_REW: /* rewind */
if (uptr->UST & STA_REW) { /* rewind in prog? */
sim_tape_rewind (uptr); /* done */
uptr->FNC |= FNC_CMPL; /* set compl state */
sim_activate (uptr, msc_ctime); } /* sched completion */
break; /* anyway, ctrl done */
case FNC_REW | FNC_CMPL: /* complete rewind */
sim_tape_rewind (uptr); /* rewind tape */
uptr->UST = STA_BOT; /* set BOT status */
if (uptr->FNC & FNF_OFL) detach_unit (uptr);
return SCPE_OK; }
uptr->UST = STA_REW; /* set rewinding */
sim_activate (uptr, msc_ctime); /* sched completion */
break; /* "done" */
return SCPE_OK; /* drive is free */
case FNC_GFM: /* gap file mark */
case FNC_WFM: /* write file mark */
@ -430,17 +522,16 @@ case FNC_BSR:
break;
case FNC_FSF:
while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ;
if (st == MTSE_TMK) /* stopped by tmk? */
msc_sta = msc_sta | STA_EOF | STA_ODD; /* normal status */
else r = ms_map_err (uptr, st); /* map error */
cap = (TCAP << uptr->REEL) << ms_ctype;
while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) {
if (uptr->REEL && sim_tape_eot (uptr, cap))
break; } /* EOT stops */
r = ms_map_err (uptr, st); /* map error */
break;
case FNC_BSF:
while ((st = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ;
if (st == MTSE_TMK) /* stopped by tmk? */
msc_sta = msc_sta | STA_EOF | STA_ODD; /* normal status */
else r = ms_map_err (uptr, st); /* map error */
r = ms_map_err (uptr, st); /* map error */
break;
/* Unit service, continued */
@ -454,21 +545,27 @@ case FNC_RC: /* read */
else if (st != MTSE_OK) { /* other error? */
r = ms_map_err (uptr, st); /* map error */
if (r == SCPE_OK) { /* recoverable? */
sim_activate (uptr, msc_gtime); /* sched IRG */
uptr->FNC = 0; /* NOP func */
sim_activate (uptr, msc_itime); /* sched IRG */
uptr->FNC |= FNC_CMPL; /* set completion */
return SCPE_OK; }
break; } /* err, done */
if (ms_ctype) msc_sta = msc_sta | STA_ODD; /* set ODD for 13183A */
if (DEBUG_PRS (msc_dev)) fprintf (sim_deb,
">>MSC svc: Unit %d read %d word record\n", unum, ms_max / 2);
}
if (CTL (devd) && (ms_ptr < ms_max)) { /* DCH on, more data? */
if (FLG (devd)) msc_sta = msc_sta | STA_TIM | STA_PAR;
msd_buf = ((uint16) msxb[ms_ptr] << 8) | msxb[ms_ptr + 1];
msd_buf = ((uint16) msxb[ms_ptr] << 8) |
((ms_ptr + 1 == ms_max) ? 0 : msxb[ms_ptr + 1]);
ms_ptr = ms_ptr + 2;
setFSR (devd); /* set dch flg */
sim_activate (uptr, msc_xtime); /* re-activate */
return SCPE_OK; }
sim_activate (uptr, msc_gtime); /* sched IRG */
if (ms_max & 1) msc_sta = msc_sta | STA_ODD; /* set ODD by rec len */
else msc_sta = msc_sta & ~STA_ODD;
sim_activate (uptr, msc_itime); /* sched IRG */
if (uptr->FNC == FNC_RFF) msc_1st = 1; /* diagnostic? */
else uptr->FNC = 0; /* NOP func */
else uptr->FNC |= FNC_CMPL; /* set completion */
return SCPE_OK;
case FNC_WC: /* write */
@ -485,11 +582,13 @@ case FNC_WC: /* write */
sim_activate (uptr, msc_xtime); /* re-activate */
return SCPE_OK; }
if (ms_ptr) { /* any data? write */
if (DEBUG_PRS (msc_dev)) fprintf (sim_deb,
">>MSC svc: Unit %d wrote %d word record\n", unum, ms_ptr / 2);
if (st = sim_tape_wrrecf (uptr, msxb, ms_ptr)) { /* write, err? */
r = ms_map_err (uptr, st); /* map error */
break; } }
sim_activate (uptr, msc_gtime); /* sched IRG */
uptr->FNC = 0; /* NOP func */
sim_activate (uptr, msc_itime); /* sched IRG */
uptr->FNC |= FNC_CMPL; /* set completion */
return SCPE_OK;
default: /* unknown */
@ -497,22 +596,30 @@ default: /* unknown */
setFSR (devc); /* set cch flg */
msc_sta = msc_sta & ~STA_BUSY; /* update status */
return SCPE_OK;
if (DEBUG_PRS (msc_dev)) fprintf (sim_deb,
">>MSC svc: Unit %d command %03o complete\n", unum, uptr->FNC & 0377);
return r;
}
/* Map tape error status */
t_stat ms_map_err (UNIT *uptr, t_stat st)
{
int32 unum = uptr - msc_dev.units; /* get unit number */
if (DEBUG_PRS (msc_dev)) fprintf (sim_deb,
">>MSC err: Unit %d tape library status = %d\n", unum, st);
switch (st) {
case MTSE_FMT: /* illegal fmt */
case MTSE_UNATT: /* unattached */
msc_sta = msc_sta | STA_REJ; /* reject */
case MTSE_OK: /* no error */
return SCPE_IERR; /* never get here! */
case MTSE_EOM: /* end of medium */
case MTSE_TMK: /* end of file */
msc_sta = msc_sta | STA_EOF | STA_ODD; /* eof (also sets odd) */
break;
msc_sta = msc_sta | STA_EOF | (ms_ctype ? 0 : STA_ODD);
break; /* EOF also sets ODD for 13181A */
case MTSE_INVRL: /* invalid rec lnt */
msc_sta = msc_sta | STA_PAR;
return SCPE_MTRLNT;
@ -521,11 +628,10 @@ case MTSE_IOERR: /* IO error */
if (msc_stopioe) return SCPE_IOERR;
break;
case MTSE_RECE: /* record in error */
case MTSE_EOM: /* end of medium */
msc_sta = msc_sta | STA_PAR; /* error */
break;
case MTSE_BOT: /* reverse into BOT */
uptr->UST = STA_BOT; /* set status */
msc_sta = msc_sta | STA_BOT; /* set BOT status */
break;
case MTSE_WRP: /* write protect */
msc_sta = msc_sta | STA_REJ; /* reject */
@ -553,7 +659,10 @@ for (i = 0; i < MS_NUMDR; i++) {
uptr = msc_dev.units + i;
sim_tape_reset (uptr);
sim_cancel (uptr);
uptr->UST = 0; }
if ((uptr->flags & UNIT_ATT) && sim_tape_bot (uptr))
uptr->UST = STA_BOT;
else uptr->UST = 0; }
ms_config_timing ();
return SCPE_OK;
}
@ -564,8 +673,7 @@ t_stat msc_attach (UNIT *uptr, char *cptr)
t_stat r;
r = sim_tape_attach (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* update status */
uptr->UST = STA_BOT;
if (r == SCPE_OK) uptr->UST = STA_BOT; /* tape starts at BOT */
return r;
}
@ -577,6 +685,36 @@ uptr->UST = 0; /* update status */
return sim_tape_detach (uptr); /* detach unit */
}
/* Configure timing */
void ms_config_timing (void)
{
int32 i, tset;
tset = (ms_timing << 1) | (ms_timing? 0 : ms_ctype); /* select timing set */
for (i = 0; i < (sizeof (timers) / sizeof (timers[0])); i++)
*timers[i] = times[tset][i]; /* assign times */
}
/* Set controller timing */
t_stat ms_set_timing (UNIT *uptr, int32 val, char *cptr, void *desc)
{
if ((val < 0) || (val > 1) || (cptr != NULL)) return SCPE_ARG;
ms_timing = val;
ms_config_timing ();
return SCPE_OK;
}
/* Show controller timing */
t_stat ms_show_timing (FILE *st, UNIT *uptr, int32 val, void *desc)
{
if (ms_timing) fputs ("fast timing", st);
else fputs ("realistic timing", st);
return SCPE_OK;
}
/* Set controller type */
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc)
@ -587,6 +725,7 @@ if ((val < 0) || (val > 1) || (cptr != NULL)) return SCPE_ARG;
for (i = 0; i < MS_NUMDR; i++) {
if (msc_unit[i].flags & UNIT_ATT) return SCPE_ALATT; }
ms_ctype = val;
ms_config_timing (); /* update for new type */
return SCPE_OK;
}
@ -599,6 +738,43 @@ else fprintf (st, "13181A");
return SCPE_OK;
}
/* Set unit reel size */
t_stat ms_set_reelsize (UNIT *uptr, int32 val, char *cptr, void *desc)
{
int32 reel;
t_stat status;
if (cptr == NULL) return SCPE_ARG;
reel = (int32) get_uint (cptr, 10, 2400, &status);
if (status != SCPE_OK) return status;
else switch (reel) {
case 0:
uptr->REEL = 0; /* type 0 = unlimited */
break;
case 600:
uptr->REEL = 1; /* type 1 = 600 foot */
break;
case 1200:
uptr->REEL = 2; /* type 2 = 1200 foot */
break;
case 2400:
uptr->REEL = 3; /* type 3 = 2400 foot */
break;
default:
return SCPE_ARG; }
return SCPE_OK;
}
/* Show unit reel size */
t_stat ms_show_reelsize (FILE *st, UNIT *uptr, int32 val, void *desc)
{
if (uptr->REEL == 0) fputs ("unlimited size", st);
else fprintf (st, "%4d foot reel", 300 << uptr->REEL);
return SCPE_OK;
}
/* 7970B/7970E bootstrap routine (HP 12992D ROM) */
const uint16 ms_rom[IBL_LNT] = {
@ -678,3 +854,4 @@ SR = (SR & IBL_OPT) | IBL_MS | (dev << IBL_V_DEV); /* set SR */
if ((sim_switches & SWMASK ('S')) && AR) SR = SR | 1; /* skip? */
return SCPE_OK;
}

View file

@ -25,6 +25,7 @@
mt 12559A 3030 nine track magnetic tape
14-Aug-04 RMS Modified handling of end of medium (suggested by Dave Bryan)
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)
@ -408,7 +409,7 @@ default: /* unknown */
setFSR (devc); /* set cch flg */
mtc_sta = mtc_sta & ~STA_BUSY; /* not busy */
return SCPE_OK;
return r;
}
/* Map tape error status */
@ -421,6 +422,7 @@ case MTSE_UNATT: /* unattached */
mtc_sta = mtc_sta | STA_REJ; /* reject */
case MTSE_OK: /* no error */
return SCPE_IERR; /* never get here! */
case MTSE_EOM: /* end of medium */
case MTSE_TMK: /* end of file */
mtc_sta = mtc_sta | STA_EOF; /* eof */
break;
@ -432,7 +434,6 @@ case MTSE_INVRL: /* invalid rec lnt */
mtc_sta = mtc_sta | STA_PAR;
return SCPE_MTRLNT;
case MTSE_RECE: /* record in error */
case MTSE_EOM: /* end of medium */
mtc_sta = mtc_sta | STA_PAR; /* error */
break;
case MTSE_BOT: /* reverse into BOT */

View file

@ -28,6 +28,7 @@
tty 12531C buffered teleprinter interface
clk 12539C time base generator
15-Aug-04 RMS Added tab to control char set (from Dave Bryan)
14-Jul-04 RMS Generalized handling of control char echoing
(from Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C
@ -76,9 +77,10 @@
#define BS_FLAG CHAR_FLAG('\b')
#define LF_FLAG CHAR_FLAG('\n')
#define CR_FLAG CHAR_FLAG('\r')
#define HT_FLAG CHAR_FLAG('\t')
#define FULL_SET 0xFFFFFFFF
#define CNTL_SET (BEL_FLAG | BS_FLAG | LF_FLAG | CR_FLAG)
#define CNTL_SET (BEL_FLAG | BS_FLAG | HT_FLAG | LF_FLAG | CR_FLAG)
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_V_UC (UNIT_V_UF + 1) /* UC only */

View file

@ -517,7 +517,6 @@ r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */
uptr->CYL = 0;
if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
for (i = 0; drv_tab[i].surf != 0; i++) {
if (p <= drv_tab[i].size) {

View file

@ -673,7 +673,6 @@ r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* error? */
uptr->CYL = 0;
if ((uptr->flags & UNIT_AUTO) == 0) return SCPE_OK; /* autosize? */
if (fseek (uptr->fileref, 0, SEEK_END)) return SCPE_OK;
if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK;
for (i = 0; drv_tab[i].surf != 0; i++) {
if (p <= drv_tab[i].size) {

View file

@ -26,6 +26,7 @@
rq RQDX3 disk controller
24-Jul-04 RMS VAX controllers luns start with 0 (from Andreas Cejna)
05-Feb-04 RMS Revised for file I/O library
25-Jan-04 RMS Revised for device debug support
12-Jan-04 RMS Fixed bug in interrupt control (found by Tom Evans)
@ -2077,7 +2078,13 @@ for (i = 0, cidx = -1; i < RQ_NUMCT; i++) { /* find ctrl num */
if (cidx < 0) return SCPE_IERR; /* not found??? */
cp = rq_ctxmap[cidx]; /* get context */
cp->cnum = cidx; /* init index */
#if defined (VM_VAX) /* VAX */
cp->ubase = 0; /* unit base = 0 */
#else /* PDP-11 */
cp->ubase = cidx * RQ_NUMDR; /* init unit base */
#endif
cp->csta = CST_S1; /* init stage 1 */
cp->s1dat = 0; /* no S1 data */
dibp->vec = 0; /* no vector */

View file

@ -25,6 +25,7 @@
cpu CVAX central processor
02-Sep-04 RMS Fixed bug in EMODD/G, second word of quad dst not probed
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
@ -333,7 +334,7 @@ extern int32 op_emodg (int32 *opnd, int32 *rh, int32 *intgr, int32 *flg);
extern void op_polyf (int32 *opnd, int32 acc);
extern void op_polyd (int32 *opnd, int32 acc);
extern void op_polyg (int32 *opnd, int32 acc);
extern int32 op_emulate (int32 *opnd, int32 cc, int32 opc, int32 acc);
extern int32 op_cis (int32 *opnd, int32 cc, int32 opc, int32 acc);
extern int32 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 Read (uint32 va, int32 lnt, int32 acc);
extern void Write (uint32 va, int32 val, int32 lnt, int32 acc);
@ -497,11 +498,14 @@ else if (abortval < 0) { /* mm or rsrv or int */
temp = fault_PC - PC; /* delta PC if needed */
SETPC (fault_PC); /* restore PC */
switch (-abortval) { /* case on abort code */
case SCB_RESIN: case SCB_RESAD: case SCB_RESOP: /* reserved fault */
case SCB_RESIN: /* rsrv inst fault */
case SCB_RESAD: /* rsrv addr fault */
case SCB_RESOP: /* rsrv opnd fault */
if (in_ie) ABORT (STOP_INIE); /* in exc? panic */
cc = intexc (-abortval, cc, 0, IE_EXC); /* take exception */
GET_CUR; /* PSL<cur> changed */
break;
case SCB_CMODE: /* comp mode fault */
case SCB_ARITH: /* arithmetic fault */
if (in_ie) ABORT (STOP_INIE); /* in exc? panic */
cc = intexc (-abortval, cc, 0, IE_EXC); /* take exception */
@ -511,7 +515,8 @@ else if (abortval < 0) { /* mm or rsrv or int */
SP = SP - 4;
in_ie = 0;
break;
case SCB_ACV: case SCB_TNV: /* mem management */
case SCB_ACV: /* ACV fault */
case SCB_TNV: /* TNV fault */
if (in_ie) { /* in exception? */
if (PSL & PSL_IS) ABORT (STOP_INIE); /* on is? panic */
cc = intexc (SCB_KSNV, cc, 0, IE_SVE); /* ksnv */
@ -1049,7 +1054,7 @@ if (hst_lnt) {
hst[hst_p].PSL = PSL | cc;
hst[hst_p].opc = opc;
hst[hst_p].brdest = brdisp + PC;
for (i = 0; i < (numspec & DR_NSPMASK); i++)
for (i = 0; i < OPND_SIZE; i++)
hst[hst_p].opnd[i] = opnd[i];
hst_p = hst_p + 1;
if (hst_p >= hst_lnt) hst_p = 0;
@ -2197,7 +2202,9 @@ case EMODF:
case EMODD:
r = op_emodd (opnd, &rh, &temp, &flg);
if (op7 < 0) Read (op8, L_LONG, WA);
if (op7 < 0) {
Read (op8, L_BYTE, WA);
Read ((op8 + 7) & LMASK, L_BYTE, WA); }
if (op5 >= 0) R[op5] = temp;
else Write (op6, temp, L_LONG, WA);
WRITE_Q (r, rh);
@ -2207,7 +2214,9 @@ case EMODD:
case EMODG:
r = op_emodg (opnd, &rh, &temp, &flg);
if (op7 < 0) Read (op8, L_LONG, WA);
if (op7 < 0) {
Read (op8, L_BYTE, WA);
Read ((op8 + 7) & LMASK, L_BYTE, WA); }
if (op5 >= 0) R[op5] = temp;
else Write (op6, temp, L_LONG, WA);
WRITE_Q (r, rh);
@ -2263,16 +2272,15 @@ case MFPR:
CC_IIZP_L (r);
break;
/* Emulated instructions */
/* Emulated CIS instructions */
case CVTPL:
opnd[2] = (opnd[2] >= 0)? ~opnd[2]: opnd[3];
case MOVP: case CMPP3: case CMPP4: case CVTLP:
case CVTPS: case CVTSP: case CVTTP: case CVTPT:
case ADDP4: case ADDP6: case SUBP4: case SUBP6:
case MULP: case DIVP: case ASHP: case CRC:
case MOVTC: case MOVTUC: case MATCHC: case EDITPC:
cc = op_emulate (opnd, cc, opc, acc);
cc = op_cis (opnd, cc, opc, acc);
break;
default:
RSVD_INST_FAULT;

View file

@ -1446,7 +1446,7 @@ default: /* others */
return val;
}
/* Emulated instructions
/* Emulated CIS instructions
opnd[0:5] = six operands to be pushed (if PSL<fpd> = 0)
cc = condition codes
@ -1458,7 +1458,7 @@ return val;
In both cases, the exception occurs in the current mode.
*/
int32 op_emulate (int32 *opnd, int32 cc, int32 opc, int32 acc)
int32 op_cis (int32 *opnd, int32 cc, int32 opc, int32 acc)
{
int32 vec;
@ -1468,7 +1468,9 @@ if (PSL & PSL_FPD) { /* FPD set? */
Write (SP - 4, PSL | cc, L_LONG, WA); /* push PSL */
SP = SP - 8; /* decr stk ptr */
vec = ReadLP ((SCBB + SCB_EMULFPD) & PAMASK); }
else { Read (SP - 1, L_BYTE, WA); /* wchk stack */
else { if (opc == CVTPL) /* CVTPL? handle .wl */
opnd[2] = (opnd[2] >= 0)? ~opnd[2]: opnd[3];
Read (SP - 1, L_BYTE, WA); /* wchk stack */
Write (SP - 48, opc, L_LONG, WA); /* push opcode */
Write (SP - 44, fault_PC, L_LONG, WA); /* push old PC */
Write (SP - 40, opnd[0], L_LONG, WA); /* push operands */

View file

@ -26,6 +26,8 @@
The author gratefully acknowledges the help of Stephen Shirron, Antonio
Carlini, and Kevin Peterson in providing specifications for the Qbus VAX's
30-Aug-04 RMS Added octa, h_floating instructin definitions
24-Aug-04 RMS Added compatibility mode definitions
18-Apr-04 RMS Added octa, fp, string definitions
19-May-03 RMS Revised for new conditional compilation scheme
14-Jul-02 RMS Added infinite loop message
@ -61,6 +63,7 @@
#define ABORT_RESIN (-SCB_RESIN) /* rsvd instruction */
#define ABORT_RESAD (-SCB_RESAD) /* rsvd addr mode */
#define ABORT_RESOP (-SCB_RESOP) /* rsvd operand */
#define ABORT_CMODE (-SCB_CMODE) /* comp mode fault */
#define ABORT_ARITH (-SCB_ARITH) /* arithmetic trap */
#define ABORT_ACV (-SCB_ACV) /* access violation */
#define ABORT_TNV (-SCB_TNV) /* transl not vaid */
@ -71,6 +74,7 @@
#define FLT_OVFL_FAULT p1 = FLT_OVRFLO, ABORT (ABORT_ARITH)
#define FLT_DZRO_FAULT p1 = FLT_DIVZRO, ABORT (ABORT_ARITH)
#define FLT_UNFL_FAULT p1 = FLT_UNDFLO, ABORT (ABORT_ARITH)
#define CMODE_FAULT(cd) p1 = (cd), ABORT (ABORT_CMODE)
#define MACH_CHECK(cd) p1 = (cd), ABORT (ABORT_MCHK)
/* Address space */
@ -150,6 +154,8 @@
/* PSL, PSW, and condition codes */
#define PSL_V_CM 31 /* compatibility mode */
#define PSL_CM (1 << PSL_V_CM)
#define PSL_V_TP 30 /* trace pending */
#define PSL_TP (1 << PSL_V_TP)
#define PSL_V_FPD 27 /* first part done */
@ -239,6 +245,10 @@
#define TIR_TRAP (TIR_M_TRAP << TIR_V_TRAP)
#define TRAP_INTOV (1 << TIR_V_TRAP) /* integer overflow */
#define TRAP_DIVZRO (2 << TIR_V_TRAP) /* divide by zero */
#define TRAP_FLTOVF (3 << TIR_V_TRAP) /* flt overflow */
#define TRAP_FLTDIV (4 << TIR_V_TRAP) /* flt/dec div by zero */
#define TRAP_FLTUND (5 << TIR_V_TRAP) /* flt underflow */
#define TRAP_DECOVF (6 << TIR_V_TRAP) /* decimal overflow */
#define TRAP_SUBSCR (7 << TIR_V_TRAP) /* subscript range */
#define SET_TRAP(x) trpirq = (trpirq & PSL_M_IPL) | (x)
#define CLR_TRAPS trpirq = trpirq & ~TIR_TRAP
@ -252,6 +262,50 @@
#define FLT_DIVZRO 0x9 /* flt div by zero */
#define FLT_UNDFLO 0xA /* flt underflow */
/* Compatability mode fault parameters */
#define CMODE_RSVI 0x0 /* reserved instr */
#define CMODE_BPT 0x1 /* BPT */
#define CMODE_IOT 0x2 /* IOT */
#define CMODE_EMT 0x3 /* EMT */
#define CMODE_TRAP 0x4 /* TRAP */
#define CMODE_ILLI 0x5 /* illegal instr */
#define CMODE_ODD 0x6 /* odd address */
/* EDITPC suboperators */
#define EO_END 0x00 /* end */
#define EO_END_FLOAT 0x01 /* end float */
#define EO_CLR_SIGNIF 0x02 /* clear signif */
#define EO_SET_SIGNIF 0x03 /* set signif */
#define EO_STORE_SIGN 0x04 /* store sign */
#define EO_LOAD_FILL 0x40 /* load fill */
#define EO_LOAD_SIGN 0x41 /* load sign */
#define EO_LOAD_PLUS 0x42 /* load sign if + */
#define EO_LOAD_MINUS 0x43 /* load sign if - */
#define EO_INSERT 0x44 /* insert */
#define EO_BLANK_ZERO 0x45 /* blank zero */
#define EO_REPL_SIGN 0x46 /* replace sign */
#define EO_ADJUST_LNT 0x47 /* adjust length */
#define EO_FILL 0x80 /* fill */
#define EO_MOVE 0x90 /* move */
#define EO_FLOAT 0xA0 /* float */
#define EO_RPT_MASK 0x0F /* rpt mask */
#define EO_RPT_FLAG 0x80 /* rpt flag */
/* EDITPC R2 packup parameters */
#define ED_V_SIGN 8 /* sign */
#define ED_M_SIGN 0xFF
#define ED_SIGN (ED_M_SIGN << ED_V_SIGN)
#define ED_V_FILL 0 /* fill */
#define ED_M_FILL 0xFF
#define ED_FILL (ED_M_FILL << ED_V_FILL)
#define ED_GETSIGN(x) (((x) >> ED_V_SIGN) & ED_M_SIGN)
#define ED_GETFILL(x) (((x) >> ED_V_FILL) & ED_M_FILL)
#define ED_PUTSIGN(r,x) (((r) & ~ED_SIGN) | (((x) << ED_V_SIGN) & ED_SIGN))
#define ED_PUTFILL(r,x) (((r) & ~ED_FILL) | (((x) << ED_V_FILL) & ED_FILL))
/* SCB offsets */
#define SCB_MCHK 0x04 /* machine chk */
@ -265,6 +319,7 @@
#define SCB_TNV 0x24 /* TNV */
#define SCB_TP 0x28 /* trace pending */
#define SCB_BPT 0x2C /* BPT instr */
#define SCB_CMODE 0x30 /* comp mode fault */
#define SCB_ARITH 0x34 /* arith fault */
#define SCB_CHMK 0x40 /* CHMK */
#define SCB_CHME 0x44 /* CHME */
@ -458,10 +513,16 @@ enum opcodes {
BBS, BBC, BBSS, BBCS, BBSC, BBCC, BBSSI, BBCCI,
BLBS, BLBC, FFS, FFC, CMPV, CMPZV, EXTV, EXTZV,
INSV, ACBL, AOBLSS, AOBLEQ, SOBGEQ, SOBGTR, CVTLB, CVTLW,
ASHP, CVTLP, CALLG, CALLS, XFC, CVTGF = 0x133,
ADDG2= 0x140, ADDG3, SUBG2, SUBG3, MULG2, MULG3, DIVG2, DIVG3,
ASHP, CVTLP, CALLG, CALLS, XFC, CVTDH = 0x132, CVTGF = 0x133,
ADDG2 = 0x140, ADDG3, SUBG2, SUBG3, MULG2, MULG3, DIVG2, DIVG3,
CVTGB, CVTGW, CVTGL, CVTRGL, CVTBG, CVTWG, CVTLG, ACBG,
MOVG, CMPG, MNEGG, TSTG, EMODG, POLYG, CVTFG = 0x199 };
MOVG, CMPG, MNEGG, TSTG, EMODG, POLYG, CVTGH,
ADDH2 = 0x160, ADDH3, SUBH2, SUBH3, MULH2, MULH3, DIVH2, DIVH3,
CVTHB, CVTHW, CVTHL, CVTRHL, CVTBH, CVTWH, CVTLH, ACBH,
MOVH, CMPH, MNEGH, TSTH, EMODH, POLYH, CVTHG,
CLRO = 0x176, MOVO, MOVAO, PUSHAO,
CVTFH = 0x198, CVTFG = 0x199,
CVTHF = 0x1F6, CVTHD = 0x1F7 };
/* Repeated operations */
@ -482,6 +543,7 @@ enum opcodes {
#define BRANCHB(d) PCQ_ENTRY, PC = PC + SXTB (d), FLUSH_ISTR
#define BRANCHW(d) PCQ_ENTRY, PC = PC + SXTW (d), FLUSH_ISTR
#define JUMP(d) PCQ_ENTRY, PC = (d), FLUSH_ISTR
#define CMODE_JUMP(d) PCQ_ENTRY, PC = (d)
#define SETPC(d) PC = (d), FLUSH_ISTR
#define FLUSH_ISTR ibcnt = 0, ppc = -1

View file

@ -13,7 +13,7 @@ endif
CC = gcc -std=c99 -O2 -g -lm $(OS_CCDEFS) -I .
ifeq ($(USE_NETWORK),)
else
NETWORK_OPT = -DUSE_NETWORK -lpcap -isystem /usr/local/include -L /usr/local/lib
NETWORK_OPT = -DUSE_NETWORK -isystem /usr/local/include /usr/local/lib/libpcap.a
endif
else
#Win32 Environments

18
scp.c
View file

@ -23,6 +23,8 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
13-Aug-04 RMS Qualified RESTORE detach with SIM_SW_REST
17-Jul-04 RMS Added ECHO command (from Dave Bryan)
12-Jul-04 RMS Fixed problem ATTACHing to read only files
(found by John Dundas)
28-May-04 RMS Added SET/SHOW CONSOLE
@ -247,6 +249,7 @@ t_stat brk_cmd (int32 flag, char *ptr);
t_stat do_cmd (int32 flag, char *ptr);
t_stat help_cmd (int32 flag, char *ptr);
t_stat spawn_cmd (int32 flag, char *ptr);
t_stat echo_cmd (int32 flag, char *ptr);
/* Set and show command processors */
@ -521,6 +524,8 @@ static CTAB cmd_table[] = {
"sh{ow} <unit> {arg,...} show unit parameters\n" },
{ "DO", &do_cmd, 0,
"do <file> {arg,arg...} process command file\n" },
{ "ECHO", &echo_cmd, 0,
"echo <string> display <string>\n" },
{ "HELP", &help_cmd, 0,
"h{elp} type this message\n"
"h{elp} <command> type help for command\n" },
@ -699,6 +704,15 @@ system (cptr);
printf ("\n");
#endif
return SCPE_OK;
}
/* Echo command */
t_stat echo_cmd (int32 flag, char *cptr)
{
puts (cptr);
if (sim_log) fprintf (sim_log, "%s\n", cptr);
return SCPE_OK;
}
@ -734,7 +748,7 @@ do { cptr = read_line (cbuf, CBUFSIZE, fpin); /* get cmd line */
if (cptr == NULL) break; /* exit on eof */
if (*cptr == 0) continue; /* ignore blank */
if (echo) printf("do> %s\n", cptr); /* echo if -v */
if (sim_log) fprintf (sim_log, "do> %s\n", cptr);
if (echo && sim_log) fprintf (sim_log, "do> %s\n", cptr);
cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
sim_switches = 0; /* init switches */
if (strcmp (gbuf, "DO") == 0) { /* don't recurse */
@ -1937,11 +1951,11 @@ for ( ;; ) { /* device loop */
if (!(dptr->flags & DEV_NET) || /* if not net dev or */
!(uptr->flags & UNIT_ATT) || /* not currently att */
(buf[0] == 0)) { /* or will not be att */
sim_switches = SIM_SW_REST; /* att-det/rest */
r = scp_detach_unit (dptr, uptr); /* detach old */
if (r != SCPE_OK) return r;
if (buf[0] != 0) { /* any file? */
uptr->flags = uptr->flags & ~UNIT_DIS;
sim_switches = SIM_SW_REST; /* attach/rest */
if (flg & UNIT_RO) /* [V2.10+] saved flgs & RO? */
sim_switches |= SWMASK ('R'); /* RO attach */
r = scp_attach_unit (dptr, uptr, buf);

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
20-Aug-04 RMS Added OS/2 EMX fixes (from Holger Veit)
14-Jul-04 RMS Revised Windows console code (from Dave Bryan)
28-May-04 RMS Added SET/SHOW CONSOLE
RMS Added break, delete character maps
@ -471,7 +472,6 @@ return SCPE_OK;
#include <fcntl.h>
#include <io.h>
#include <windows.h>
#include <signal.h>
#define RAW_MODE 0
static HANDLE std_input;
static DWORD saved_mode;
@ -490,7 +490,7 @@ if (!GetConsoleMode(std_input, &saved_mode) ||
!SetConsoleMode(std_input, RAW_MODE)) return SCPE_TTYERR;
if (sim_log) {
fflush (sim_log);
setmode (_fileno (sim_log), _O_BINARY); }
_setmode (_fileno (sim_log), _O_BINARY); }
SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
return SCPE_OK;
}
@ -528,7 +528,7 @@ if (c != 0177) _putch (c);
return SCPE_OK;
}
/* OS/2 routines, from Bruce Ray */
/* OS/2 routines, from Bruce Ray and Holger Veit */
#elif defined (__OS2__)
@ -558,8 +558,19 @@ t_stat sim_os_poll_kbd (void)
{
int c;
#if defined (__EMX__)
switch (c = _read_kbd(0,0,0)) { /* EMX has _read_kbd */
case -1: /* no char*/
return SCPE_OK;
case 0: /* char pending */
c = _read_kbd(0,1,0);
break;
default: /* got char */
break; }
#else
if (!kbhit ()) return SCPE_OK;
c = getch();
#endif
if ((c & 0177) == sim_del_char) c = 0177;
if ((c & 0177) == sim_int_char) return SCPE_STOP;
if (sim_brk_char && ((c & 0177) == sim_brk_char)) return SCPE_BREAK;
@ -569,7 +580,11 @@ return c | SCPE_KFLAG;
t_stat sim_os_putchar (int32 c)
{
if (c != 0177) {
#if defined (__EMX__)
putchar (c);
#else
putch (c);
#endif
fflush (stdout); }
return SCPE_OK;
}

View file

@ -29,12 +29,51 @@
#define SIM_MAJOR 3
#define SIM_MINOR 2
#define SIM_PATCH 2
#define SIM_PATCH 3
/* V3.2 revision history
patch date module(s) and fix(es)
3 03-Sep-04 scp.c:
- added ECHO command (from Dave Bryan)
- qualified RESTORE detach with SIM_SW_REST
sim_console: added OS/2 EMX fixes (from Holger Veit)
sim_sock.h: added missing definition for OS/2 (from Holger Veit)
hp2100_cpu.c: changed error stops to report PC not PC + 1
(from Dave Bryan)
hp2100_dp.c: functional and timing fixes (from Dave Bryan)
- controller sets ATN for all commands except read status
- controller resumes polling for ATN interrupts after read status
- check status on unattached drive set busy and not ready
- check status tests wrong unit for write protect status
- drive on line sets ATN, will set FLG if polling
hp2100_dr.c: fixed CLC to stop operation (from Dave Bryan)
hp2100_ms.c: functional and timing fixes (from Dave Bryan)
- fixed erroneous execution of rejected command
- fixed erroneous execution of select-only command
- fixed erroneous execution of clear command
- fixed odd byte handling for read
- fixed spurious odd byte status on 13183A EOF
- modified handling of end of medium
- added detailed timing, with fast and realistic modes
- added reel sizes to simulate end of tape
- added debug printouts
hp2100_mt.c: modified handling of end of medium (from Dave Bryan)
hp2100_stddev.c: added tab to control char set (from Dave Bryan)
pdp11_rq.c: VAX controllers luns start at 0 (from Andreas Cejna)
vax_cpu.c: fixed bug in EMODD/G, second word of quad dst not probed
2 17-Jul-04 scp.c: fixed problem ATTACHing to read only files
(found by John Dundas)
@ -52,7 +91,7 @@ patch date module(s) and fix(es)
1 10-Jul-04 scp.c: added SET/SHOW CONSOLE subhierarchy
hp2100_cpu.c: fixed bugs and added features from Dave Bryan
hp2100_cpu.c: fixes 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

View file

@ -23,6 +23,7 @@
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
20-Aug-04 HV Added missing definition for OS/2 (from Holger Veit)
22-Oct-03 MP Changed WIN32 winsock include to use winsock2.h to
avoid a conflict if sim_sock.h and sim_ether.h get
included by the same module.
@ -65,6 +66,11 @@
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif
#endif
#if defined(__EMX__) /* OS/2 unique */
#if !defined (timerclear)
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif
#endif
SOCKET sim_master_sock (int32 port);
SOCKET sim_connect_sock (int32 ip, int32 port);

View file

@ -26,6 +26,8 @@
Ultimately, this will be a place to hide processing of various tape formats,
as well as OS-specific direct hardware access.
28-Jul-04 RMS Fixed bug in writing error records (found by Dave Bryan)
RMS Fixed incorrect error codes (found by Dave Bryan)
05-Jan-04 RMS Revised for file I/O library
25-Apr-03 RMS Added extended file support
28-Mar-03 RMS Added E11 and TPC format support
@ -364,8 +366,8 @@ t_mtrlnt sbc;
MT_CLR_PNU (uptr);
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */
if (f == MTUF_F_STD) sbc = (bc + 1) & ~1;
else sbc = bc;
if (f == MTUF_F_STD) sbc = MTR_L ((bc + 1) & ~1);
else sbc = MTR_L (bc);
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */
sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref);
sim_fwrite (buf, sizeof (uint8), sbc, uptr->fileref);
@ -427,7 +429,7 @@ t_stat st;
if (MT_TST_PNU (uptr)) {
MT_CLR_PNU (uptr);
*bc = 0;
return SCPE_OK; }
return MTSE_OK; }
st = sim_tape_rdlntr (uptr, bc); /* get record length */
*bc = MTR_L (*bc);
return st;
@ -479,7 +481,7 @@ t_stat sim_tape_ioerr (UNIT *uptr)
{
perror ("Magtape library I/O error");
clearerr (uptr->fileref);
return SCPE_IOERR;
return MTSE_IOERR;
}
/* Set tape format */

View file

@ -1,7 +1,7 @@
To: Users
From: Bob Supnik
Subj: Simulator Usage, V3.2-1
Date: 15-Jun-2004
Subj: Simulator Usage, V3.2-3
Date: 20-Aug-2004
COPYRIGHT NOTICE
@ -705,6 +705,11 @@ quotation marks.
If the switch -V is specified, the commands in the file are echoed
before they are executed.
The ECHO command is a useful way of annotating command files. ECHO
prints out its argument on the console:
sim> ECHO <string> -- output string to console
3.13 Executing System Commands
The simulator can execute operating system commands with the ! (spawn)