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 RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT
enable this feature for normal operations. enable this feature for normal operations.
RESTRICTION: The HP DS disk is not debugged. DO NOT enable this 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. Bugs Fixed in 3.2-2
2.1 SCP 2.1 SCP
- Fixed problem ATTACHing to read-only files (found by John Dundas) - Qualified RESTORE detach with SIM_SW_REST
- Fixed problems in Windows terminal code (found by Dave Bryan) - Fixed OS/2 issues in sim_console.c and sim_sock.h
- Fixed problem in big-endian reads (reported by Scott Bailey)
2.2 GRI-909 2.2 HP2100 (all from Dave Bryan)
- Updated MSR to include SOV - Changed CPU error stops to report PC not PC + 1
- Updated EAO to include additional functions
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 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 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 17-Jul-04 RMS Revised MSR, EAO based on additional documentation
14-Mar-03 RMS Fixed bug in SC queue tracking 14-Mar-03 RMS Fixed bug in SC queue tracking
@ -381,7 +382,7 @@ extern UNIT rtc_unit;
SC = SC & AMASK; /* load local PC */ SC = SC & AMASK; /* load local PC */
reason = 0; reason = 0;
AO = ao_update (); /* update AO */ ao_update (); /* update AO */
sim_rtc_init (rtc_unit.wait); /* init calibration */ sim_rtc_init (rtc_unit.wait); /* init calibration */
/* Main instruction fetch/decode loop */ /* Main instruction fetch/decode loop */
@ -517,7 +518,7 @@ else { SC = (SC + 1) & AMASK; /* incr SC */
/* Simulation halted */ /* Simulation halted */
AO = ao_update (); /* update AO */ ao_update (); /* update AO */
scq_r->qptr = scq_p; /* update sc q ptr */ scq_r->qptr = scq_p; /* update sc q ptr */
return reason; return reason;
} }
@ -700,12 +701,12 @@ return SWR;
uint32 msr_rd (uint32 src) uint32 msr_rd (uint32 src)
{ {
return MSR; return MSR & MSR_RW;
} }
t_stat msr_wr (uint32 src, uint32 dat) t_stat msr_wr (uint32 src, uint32 dat)
{ {
MSR = dat; /* new MSR */ MSR = dat & MSR_RW; /* new MSR */
ao_update (); /* update AOV */ ao_update (); /* update AOV */
return SCPE_OK; return SCPE_OK;
} }
@ -714,28 +715,27 @@ return SCPE_OK;
uint32 ao_update (void) uint32 ao_update (void)
{ {
int32 t; uint32 af = MSR_GET_FOA (MSR);
int32 af = MSR_GET_FOA (MSR);
switch (af) { switch (af) {
case AO_ADD: case AO_ADD:
t = (AX + AY) & DMASK; /* add */ AO = (AX + AY) & DMASK; /* add */
break; break;
case AO_AND: case AO_AND:
t = AX & AY; /* and */ AO = AX & AY; /* and */
break; break;
case AO_XOR: /* xor */ case AO_XOR: /* xor */
t = AX ^ AY; AO = AX ^ AY;
break; break;
case AO_IOR: case AO_IOR:
t = AX | AY; /* or */ AO = AX | AY; /* or */
break; } break; }
if ((AX + AY) & CBIT) MSR = MSR | MSR_AOV; /* always calc AOV */ if ((AX + AY) & CBIT) MSR = MSR | MSR_AOV; /* always calc AOV */
else MSR = MSR & ~MSR_AOV; else MSR = MSR & ~MSR_AOV;
if (SIGN & ((AX ^ (AX + AY)) & (~AX ^ AY))) /* always calc SOV */ if (SIGN & ((AX ^ (AX + AY)) & (~AX ^ AY))) /* always calc SOV */
MSR = MSR | MSR_SOV; MSR = MSR | MSR_SOV;
else MSR = MSR & ~MSR_SOV; else MSR = MSR & ~MSR_SOV;
return t; return AO;
} }
uint32 ax_rd (uint32 src) uint32 ax_rd (uint32 src)
@ -746,6 +746,7 @@ return AX;
t_stat ax_wr (uint32 dst, uint32 dat) t_stat ax_wr (uint32 dst, uint32 dat)
{ {
AX = dat; AX = dat;
ao_update ();
return SCPE_OK; return SCPE_OK;
} }
@ -757,18 +758,19 @@ return AY;
t_stat ay_wr (uint32 dst, uint32 dat) t_stat ay_wr (uint32 dst, uint32 dat)
{ {
AY = dat; AY = dat;
ao_update ();
return SCPE_OK; return SCPE_OK;
} }
uint32 ao_rd (uint32 src) uint32 ao_rd (uint32 src)
{ {
AO = ao_update (); return ao_update ();
return AO;
} }
t_stat ao_fo (uint32 op) t_stat ao_fo (uint32 op)
{ {
uint32 t = OP_GET_FOA (op); /* get func */ uint32 t = OP_GET_FOA (op); /* get func */
MSR = MSR_PUT_FOA (MSR, t); /* store in MSR */ MSR = MSR_PUT_FOA (MSR, t); /* store in MSR */
ao_update (); /* update AOV */ ao_update (); /* update AOV */
return SCPE_OK; return SCPE_OK;

View file

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

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.
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 14-May-04 RMS Fixed bugs and added features from Dave Bryan
- SBT increments B after store - SBT increments B after store
- DMS console map must check dms_enb - DMS console map must check dms_enb
@ -801,11 +803,9 @@ 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 && /* any breakpoints? */ if (sim_brk_summ && /* any breakpoints? */
sim_brk_test (PC, ALL_BKPTS) && /* at this location? */ sim_brk_test (PC, SWMASK ('E') | /* unconditional or */
(sim_brk_test (PC, SWMASK ('E')) || /* unconditional? */ (dms_enb? (dms_ump? SWMASK ('U'): SWMASK ('S')):
sim_brk_test (PC, dms_enb? /* or right type for DMS? */ SWMASK ('N')))) { /* 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 */
@ -1823,6 +1823,8 @@ if (reason == STOP_INDINT) { /* indirect intr? */
if (iotrap && (reason == STOP_HALT)) MR = intaddr; /* HLT in trap cell? */ if (iotrap && (reason == STOP_HALT)) MR = intaddr; /* HLT in trap cell? */
else MR = (PC - 1) & VAMASK; /* no, M = P - 1 */ else MR = (PC - 1) & VAMASK; /* no, M = P - 1 */
TR = ReadIO (MR, dms_ump); /* last word fetched */ 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_AR = AR & DMASK;
saved_BR = BR & DMASK; saved_BR = BR & DMASK;
dms_upd_sr (); /* update dms_sr */ dms_upd_sr (); /* update dms_sr */

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: HP2100 Simulator Usage Subj: HP2100 Simulator Usage
Date: 30-Jun-2004 Date: 20-Aug-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -256,11 +256,11 @@ when started.
In addition, most devices can be enabled or disabled. To enable a In addition, most devices can be enabled or disabled. To enable a
device, use the SET <dev> ENABLED command: 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: 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 For devices with more than one device number, disabling or enabling any
device in the set disables all the devices. 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, 12557A, supporting 2.5MB drives, or a 13210A, supporting 5MB drives,
with the commands: with the commands:
SET DP 12557A 2.5MB drives SET DPC 12557A 2.5MB drives
SET DP 13210A 5.0MB drives SET DPC 13210A 5.0MB drives
Drive types cannot be intermixed; the controller is configured for Drive types cannot be intermixed; the controller is configured for
one type or the other. The 13210A (for 7900/7901 disks) is selected 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 name size comments
OBUF 16 output buffer 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 CNT 5 check record count
CMD 1 controller enable CMD 1 controller enable
CTL 1 interrupt enable CTL 1 interrupt enable
@ -696,6 +696,7 @@ The device controller implements these registers:
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request SRQ 1 controller DMA service request
EOC 1 end of cylinder pending EOC 1 end of cylinder pending
POLL 1 attention polling enabled
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
RARS[0:3] 4 record address register sector, 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 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 The 12565A disk controller has two separate devices, a data channel and
a device controller. The data channel includes a 128-word (one sector) 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 write locked, and the ability to select the 13181A (800 bpi) controller
or the 13183A (1600 bpi) controller. or the 13183A (1600 bpi) controller.
SET MTn LOCKED set unit n write locked SET MSCn LOCKED set unit n write locked
SET MTn WRITEENABLED set unit n write enabled SET MSCn WRITEENABLED set unit n write enabled
SET MT 13181A set controller to 13181A SET MSC 13181A set controller to 13181A
SET MT 13183A set controller to 13183A 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 The 13181A/13183A mag tape drive has two separate devices, a data channel
and a device controller. The data channel includes a maximum record and a device controller. The data channel includes a maximum record
sized buffer for reads and writes. The device controller includes the sized buffer for reads and writes. The device controller includes the
tape units. 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 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 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:
@ -947,7 +955,11 @@ The device controller implements these registers:
FBF 1 controller ready buffer FBF 1 controller ready buffer
SRQ 1 controller DMA service request SRQ 1 controller DMA service request
POS[0:3] 32 magtape position POS[0:3] 32 magtape position
BTIME 24 BOT start delay time
CTIME 24 command 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 XTIME 24 interword transfer delay time
STOP_IOE 1 stop on I/O error STOP_IOE 1 stop on I/O error

View file

@ -26,6 +26,14 @@
dp 12557A 2871 disk subsystem dp 12557A 2871 disk subsystem
13210A 7900 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) 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 26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Fixed SR setting in IBL Fixed SR setting in IBL
@ -42,6 +50,29 @@
07-Sep-01 RMS Moved function prototypes 07-Sep-01 RMS Moved function prototypes
29-Nov-00 RMS Made variable names unique 29-Nov-00 RMS Made variable names unique
21-Nov-00 RMS Fixed flag, buffer power up state 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" #include "hp2100_defs.h"
@ -78,9 +109,9 @@
#define FNC_AR 013 /* address */ #define FNC_AR 013 /* address */
#define FNC_SEEK1 020 /* fake - seek1 */ #define FNC_SEEK1 020 /* fake - seek1 */
#define FNC_SEEK2 021 /* fake - seek2 */ #define FNC_SEEK2 021 /* fake - seek2 */
#define FNC_SEEK3 022 /* fake - seek3 */
#define FNC_CHK1 023 /* fake - check1 */ #define FNC_CHK1 023 /* fake - check1 */
#define FNC_AR1 024 /* fake - arec1 */ #define FNC_AR1 024 /* fake - arec1 */
#define FNC_STA1 025 /* fake - sta1 */
#define CW_V_DRV 0 /* drive */ #define CW_V_DRV 0 /* drive */
#define CW_M_DRV 03 #define CW_M_DRV 03
#define CW_GETDRV(x) (((x) >> CW_V_DRV) & CW_M_DRV) #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 dp_ctype = 1; /* ctrl type */
int32 dpc_busy = 0; /* cch unit */ int32 dpc_busy = 0; /* cch unit */
int32 dpc_poll = 0; /* cch poll enable */
int32 dpc_cnt = 0; /* check count */ int32 dpc_cnt = 0; /* check count */
int32 dpc_eoc = 0; /* end of cyl */ int32 dpc_eoc = 0; /* end of cyl */
int32 dpc_stime = 100; /* seek time */ int32 dpc_stime = 100; /* seek time */
@ -228,7 +260,7 @@ UNIT dpc_unit[] = {
REG dpc_reg[] = { REG dpc_reg[] = {
{ ORDATA (OBUF, dpc_obuf, 16) }, { ORDATA (OBUF, dpc_obuf, 16) },
{ ORDATA (BUSY, dpc_busy, 3), REG_RO }, { ORDATA (BUSY, dpc_busy, 4), REG_RO },
{ ORDATA (CNT, dpc_cnt, 5) }, { ORDATA (CNT, dpc_cnt, 5) },
{ FLDATA (CMD, dpc_dib.cmd, 0) }, { FLDATA (CMD, dpc_dib.cmd, 0) },
{ FLDATA (CTL, dpc_dib.ctl, 0) }, { FLDATA (CTL, dpc_dib.ctl, 0) },
@ -236,6 +268,7 @@ REG dpc_reg[] = {
{ FLDATA (FBF, dpc_dib.fbf, 0) }, { FLDATA (FBF, dpc_dib.fbf, 0) },
{ FLDATA (SRQ, dpc_dib.srq, 0) }, { FLDATA (SRQ, dpc_dib.srq, 0) },
{ FLDATA (EOC, dpc_eoc, 0) }, { FLDATA (EOC, dpc_eoc, 0) },
{ FLDATA (POLL, dpc_poll, 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) },
{ BRDATA (RARS, dpc_rars, 8, 4, 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]); if (dpc_busy) sim_cancel (&dpc_unit[dpc_busy - 1]);
sim_cancel (&dpd_unit); /* cancel dch */ sim_cancel (&dpd_unit); /* cancel dch */
dpd_xfer = 0; /* clr dch xfer */ 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 */ else { /* STC */
setCTL (devc); /* set ctl */ setCTL (devc); /* set ctl */
if (!CMD (devc)) { /* is cmd clr? */ if (!CMD (devc)) { /* is cmd clr? */
@ -358,9 +392,13 @@ case ioCTL: /* control clear/set */
drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */ drv = CW_GETDRV (dpc_obuf); /* get fnc, drv */
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_SEEK: /* seek */
dpc_poll = 1; /* enable polling */
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
break;
case FNC_STA: /* rd sta */ case FNC_STA: /* rd sta */
if (dp_ctype) { clrFSR (devd); } /* 13210? clr dch flag */ 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 */ case FNC_AR: /* addr rec */
dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */ dp_god (fnc, drv, dpc_dtime); /* sched dch xfr */
break; break;
@ -391,15 +429,18 @@ return;
void dp_goc (int32 fnc, int32 drv, int32 time) 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 */ sim_cancel (&dpc_unit[drv]); /* stop seek */
dpc_sta[drv] = dpc_sta[drv] & ~STA_BSY; /* clear busy */ 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 */ dp_ptr = 0; /* init buf ptr */
dpc_eoc = 0; /* clear end cyl */ dpc_eoc = 0; /* clear end cyl */
dpc_busy = drv + 1; /* set busy */ dpc_busy = drv + 1; /* set busy */
dpd_xfer = 1; /* xfer in prog */ dpd_xfer = 1; /* xfer in prog */
dpc_unit[drv].FNC = fnc; /* save function */ 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 */ sim_activate (&dpc_unit[drv], time); /* activate unit */
return; return;
} }
@ -425,7 +466,7 @@ return;
t_stat dpd_svc (UNIT *uptr) t_stat dpd_svc (UNIT *uptr)
{ {
int32 drv, devc, devd, st; int32 i, drv, devc, devd, st;
drv = uptr->CYL; /* get drive no */ drv = uptr->CYL; /* get drive no */
devc = dpc_dib.devno; /* get cch devno */ devc = dpc_dib.devno; /* get cch devno */
@ -478,7 +519,8 @@ case FNC_AR1: /* arec, need hd/sec */
setFSR (devc); /* set cch flg */ setFSR (devc); /* set cch flg */
clrCMD (devc); /* clr cch cmd */ clrCMD (devc); /* clr cch cmd */
setFSR (devd); /* set dch flg */ 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 */ else sim_activate (uptr, dpc_xtime); /* no, wait more */
break; break;
@ -488,8 +530,8 @@ case FNC_STA: /* read status */
dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */ dpd_ibuf = dpc_sta[drv] & ~STA_ERR; /* clear err */
if (dp_ctype) dpd_ibuf = /* 13210? */ if (dp_ctype) dpd_ibuf = /* 13210? */
(dpd_ibuf & ~(STA_MBZ13 | STA_PROT)) | (dpd_ibuf & ~(STA_MBZ13 | STA_PROT)) |
(uptr->flags & UNIT_WPRT? STA_PROT: 0); } (dpc_unit[drv].flags & UNIT_WPRT? STA_PROT: 0); }
else dpd_ibuf = STA_NRDY; /* not ready */ else dpd_ibuf = STA_NRDY|STA_BSY; /* 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;
setFSR (devd); /* set dch flg */ setFSR (devd); /* set dch flg */
@ -498,8 +540,16 @@ case FNC_STA: /* read status */
dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */ dpc_sta[drv] = dpc_sta[drv] & /* clr sta flags */
~(STA_ATN | STA_1ST | STA_OVR | ~(STA_ATN | STA_1ST | STA_OVR |
STA_RWU | STA_ACU | STA_EOC | STA_RWU | STA_ACU | STA_EOC |
STA_AER | STA_FLG | STA_DTE); } STA_AER | STA_FLG | STA_DTE);
else sim_activate (uptr, dpc_xtime); /* wait more */ 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; break;
case FNC_CHK: /* check, need cnt */ case FNC_CHK: /* check, need cnt */
@ -547,7 +597,9 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
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 */
dpd_xfer = dpd_wval = 0; dpc_poll = 0; /* polling disabled */
dpd_xfer = 0;
dpd_wval = 0;
return SCPE_OK; } return SCPE_OK; }
switch (uptr->FNC) { /* case function */ switch (uptr->FNC) { /* case function */
@ -556,11 +608,7 @@ case FNC_SEEK2: /* seek done */
if (uptr->CYL >= DP_NUMCY) { /* invalid cyl? */ if (uptr->CYL >= DP_NUMCY) { /* invalid cyl? */
dpc_sta[drv] = dpc_sta[drv] | STA_SKE; dpc_sta[drv] = dpc_sta[drv] | STA_SKE;
uptr->CYL = DP_NUMCY - 1; } uptr->CYL = DP_NUMCY - 1; }
case FNC_SEEK3: /* waiting for flag */ if (dpc_poll) { /* polling enabled? */
if (dpc_busy || FLG (devc)) { /* ctrl busy? wait */
uptr->FNC = FNC_SEEK3; /* next state */
sim_activate (uptr, dpc_xtime); }
else {
setFSR (devc); /* set cch flg */ setFSR (devc); /* set cch flg */
clrCMD (devc); } /* clear cmd */ clrCMD (devc); } /* clear cmd */
return SCPE_OK; return SCPE_OK;
@ -639,7 +687,7 @@ case FNC_WD: /* write */
default: 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 */ dpc_sta[drv] = dpc_sta[drv] | STA_ATN; /* set ATN */
setFSR (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 */
@ -661,6 +709,7 @@ hp_enbdis_pair (&dpc_dev, &dpd_dev); /* make pair cons */
dpd_ibuf = dpd_obuf = 0; /* clear buffers */ dpd_ibuf = dpd_obuf = 0; /* clear buffers */
dpc_busy = dpc_obuf = 0; dpc_busy = dpc_obuf = 0;
dpc_eoc = 0; dpc_eoc = 0;
dpc_poll = 0;
dpd_xfer = dpd_wval = 0; dpd_xfer = dpd_wval = 0;
dp_ptr = 0; dp_ptr = 0;
dpc_dib.cmd = dpd_dib.cmd = 0; /* clear cmd */ dpc_dib.cmd = dpd_dib.cmd = 0; /* clear cmd */
@ -690,7 +739,11 @@ t_stat r;
drv = uptr - dpc_dev.units; /* get drive no */ drv = uptr - dpc_dev.units; /* get drive no */
r = attach_unit (uptr, cptr); /* attach unit */ r = attach_unit (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; 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; return r;
} }

View file

@ -315,8 +315,8 @@ case ioCTL: /* control clear/set */
setCTL (devc); /* set ctl */ setCTL (devc); /* set ctl */
if (!CMD (devc)) { /* cmd clr? */ if (!CMD (devc)) { /* cmd clr? */
setCMD (devc); /* set cmd, ctl */ setCMD (devc); /* set cmd, ctl */
drv = CW_GETDRV (dqc_obuf); /* get fnc, drv */ drv = CW_GETDRV (dqc_obuf); /* get fnc, drv */
fnc = CW_GETFNC (dqc_obuf); /* from cmd word */ fnc = CW_GETFNC (dqc_obuf); /* from cmd word */
switch (fnc) { /* case on fnc */ switch (fnc) { /* case on fnc */
case FNC_SEEK: case FNC_RCL: /* seek, recal */ case FNC_SEEK: case FNC_RCL: /* seek, recal */
case FNC_CHK: /* check */ case FNC_CHK: /* check */
@ -352,9 +352,11 @@ return;
void dq_goc (int32 fnc, int32 drv, int32 time) 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 */ sim_cancel (&dqc_unit[drv]); /* cancel */
time = time + dqc_stime; } /* take longer */ time = time + t; } /* include seek time */
dqc_sta[drv] = 0; /* clear status */ dqc_sta[drv] = 0; /* clear status */
dq_ptr = 0; /* init buf ptr */ dq_ptr = 0; /* init buf ptr */
dqc_busy = drv + 1; /* set busy */ dqc_busy = drv + 1; /* set busy */
@ -456,7 +458,7 @@ case FNC_STA: /* read status */
if (CMD (devd)) { /* dch active? */ if (CMD (devd)) { /* dch active? */
if (dqc_unit[drv].flags & UNIT_ATT) /* attached? */ if (dqc_unit[drv].flags & UNIT_ATT) /* attached? */
dqd_ibuf = dqc_sta[drv] & ~STA_DID; 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; if (drv) dqd_ibuf = dqd_ibuf | STA_DID;
setFSR (devd); /* set dch flg */ setFSR (devd); /* set dch flg */
clrCMD (devd); /* clr dch cmd */ clrCMD (devd); /* clr dch cmd */

View file

@ -35,6 +35,7 @@
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-Aug-04 RMS Fixed CLC to stop operation (from Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C 26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Revised boot rom to use IBL algorithm Revised boot rom to use IBL algorithm
Implemented DMA SRQ (follows FLG) Implemented DMA SRQ (follows FLG)
@ -248,6 +249,7 @@ case ioCTL: /* control clear/set */
if (IR & I_AB) { /* CLC */ if (IR & I_AB) { /* CLC */
clrCMD (devd); /* clr "ctl" */ clrCMD (devd); /* clr "ctl" */
clrFSR (devd); /* clr flg */ clrFSR (devd); /* clr flg */
sim_cancel (&drc_unit); /* cancel curr op */
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" */

View file

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

View file

@ -26,6 +26,16 @@
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
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) 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 26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Fixed SR setting in IBL Fixed SR setting in IBL
@ -53,9 +63,6 @@
If the byte count is odd, the record is padded with an extra byte 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. 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" #include "hp2100_defs.h"
@ -66,6 +73,9 @@
#define DBSIZE (1 << DB_N_SIZE) /* max data cmd */ #define DBSIZE (1 << DB_N_SIZE) /* max data cmd */
#define FNC u3 /* function */ #define FNC u3 /* function */
#define UST u4 /* unit status */ #define UST u4 /* unit status */
#define REEL u5 /* tape reel size */
#define TCAP (300 * 12 * 800) /* 300 ft capacity at 800bpi */
/* Command - msc_fnc */ /* Command - msc_fnc */
@ -82,6 +92,7 @@
#define FNC_RWS 00105 /* rewind and offline */ #define FNC_RWS 00105 /* rewind and offline */
#define FNC_WFM 00211 /* write file mark */ #define FNC_WFM 00211 /* write file mark */
#define FNC_RFF 00223 /* "read file fwd" */ #define FNC_RFF 00223 /* "read file fwd" */
#define FNC_CMPL 00400 /* completion state */
#define FNC_V_SEL 9 /* select */ #define FNC_V_SEL 9 /* select */
#define FNC_M_SEL 017 #define FNC_M_SEL 017
#define FNC_GETSEL(x) (((x) >> FNC_V_SEL) & FNC_M_SEL) #define FNC_GETSEL(x) (((x) >> FNC_V_SEL) & FNC_M_SEL)
@ -93,6 +104,8 @@
#define FNF_RWD 00100 /* rewind */ #define FNF_RWD 00100 /* rewind */
#define FNF_CHS 00400 /* change select */ #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) */ /* Status - stored in msc_sta, unit.UST (u), or dynamic (d) */
#define STA_PE 0100000 /* 1600 bpi (d) */ #define STA_PE 0100000 /* 1600 bpi (d) */
@ -105,7 +118,7 @@
#define STA_BUSY 0000400 /* ctrl busy */ #define STA_BUSY 0000400 /* ctrl busy */
#define STA_EOF 0000200 /* end of file */ #define STA_EOF 0000200 /* end of file */
#define STA_BOT 0000100 /* beg of tape (u) */ #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_TIM 0000020 /* timing error */
#define STA_REJ 0000010 /* programming error */ #define STA_REJ 0000010 /* programming error */
#define STA_WLK 0000004 /* write locked (d) */ #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 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;
extern FILE *sim_deb;
int32 ms_ctype = 0; /* ctrl type */ int32 ms_ctype = 0; /* ctrl type */
int32 ms_timing = 1; /* timing type */
int32 msc_sta = 0; /* status */ int32 msc_sta = 0; /* status */
int32 msc_buf = 0; /* buffer */ int32 msc_buf = 0; /* buffer */
int32 msc_usl = 0; /* unit select */ int32 msc_usl = 0; /* unit select */
int32 msc_1st = 0; 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 msc_stopioe = 1; /* stop on error */
int32 msd_buf = 0; /* data buffer */ int32 msd_buf = 0; /* data buffer */
uint8 msxb[DBSIZE] = { 0 }; /* data buffer */ uint8 msxb[DBSIZE] = { 0 }; /* data buffer */
t_mtrlnt ms_ptr = 0, ms_max = 0; /* buffer ptrs */ 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; DEVICE msd_dev, msc_dev;
int32 msdio (int32 inst, int32 IR, int32 dat); int32 msdio (int32 inst, int32 IR, int32 dat);
int32 mscio (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_map_err (UNIT *uptr, t_stat st);
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc); 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_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 /* 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 (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) },
{ 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 (CTIME, msc_ctime, 24), REG_NZ + PV_LEFT },
{ DRDATA (GTIME, msc_gtime, 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 (RTIME, msc_rtime, 24), REG_NZ + PV_LEFT },
{ DRDATA (XTIME, msc_xtime, 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 (STOP_IOE, msc_stopioe, 0) },
{ FLDATA (CTYPE, ms_ctype, 0), REG_HRO }, { FLDATA (CTYPE, ms_ctype, 0), REG_HRO },
{ ORDATA (DEVNO, msc_dib.devno, 6), REG_HRO }, { ORDATA (DEVNO, msc_dib.devno, 6), REG_HRO },
@ -225,6 +278,8 @@ REG msc_reg[] = {
MTAB msc_mod[] = { MTAB msc_mod[] = {
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", 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", { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, &sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ MTAB_XTD | MTAB_VDV, 0, NULL, "13181A", { MTAB_XTD | MTAB_VDV, 0, NULL, "13181A",
@ -233,6 +288,12 @@ MTAB msc_mod[] = {
&ms_settype, NULL, NULL }, &ms_settype, NULL, NULL },
{ MTAB_XTD | MTAB_VDV, 0, "TYPE", NULL, { MTAB_XTD | MTAB_VDV, 0, "TYPE", NULL,
NULL, &ms_showtype, 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", { MTAB_XTD | MTAB_VDV, 1, "DEVNO", "DEVNO",
&hp_setdev, &hp_showdev, &msd_dev }, &hp_setdev, &hp_showdev, &msd_dev },
{ 0 } }; { 0 } };
@ -242,7 +303,7 @@ DEVICE msc_dev = {
MS_NUMDR, 10, 31, 1, 8, 8, MS_NUMDR, 10, 31, 1, 8, 8,
NULL, NULL, &msc_reset, NULL, NULL, &msc_reset,
&msc_boot, &msc_attach, &msc_detach, &msc_boot, &msc_attach, &msc_detach,
&msc_dib, DEV_DISABLE }; &msc_dib, DEV_DISABLE | DEV_DEBUG };
/* IOT routines */ /* IOT routines */
@ -289,7 +350,7 @@ return dat;
int32 mscio (int32 inst, int32 IR, int32 dat) int32 mscio (int32 inst, int32 IR, int32 dat)
{ {
int32 i, devc, devd; int32 i, devc, devd, sched_time;
t_stat st; t_stat st;
UNIT *uptr = msc_dev.units + msc_usl; UNIT *uptr = msc_dev.units + msc_usl;
static const uint8 map_sel[16] = { static const uint8 map_sel[16] = {
@ -309,6 +370,8 @@ case ioSFS: /* skip flag set */
if (FLG (devc) != 0) PC = (PC + 1) & VAMASK; if (FLG (devc) != 0) PC = (PC + 1) & VAMASK;
break; break;
case ioOTX: /* output */ case ioOTX: /* output */
if (DEBUG_PRS (msc_dev))
fprintf (sim_deb, ">>MSC OTx: Command = %06o\n", dat);
msc_buf = dat; msc_buf = dat;
msc_sta = msc_sta & ~STA_REJ; /* clear reject */ msc_sta = msc_sta & ~STA_REJ; /* clear reject */
if ((dat & 0377) == FNC_CLR) break; /* clear always ok */ if ((dat & 0377) == FNC_CLR) break; /* clear always ok */
@ -326,19 +389,26 @@ case ioOTX: /* output */
case ioLIX: /* load */ case ioLIX: /* load */
dat = 0; dat = 0;
case ioMIX: /* merge */ 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 (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; dat = dat | STA_TBSY;
if (sim_tape_wrp (uptr)) /* write prot? */ 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; else dat = dat | STA_TBSY | STA_LOCAL;
if (ms_ctype) dat = dat | STA_PE | /* 13183A? */ if (ms_ctype) dat = dat | STA_PE | /* 13183A? */
(msc_usl << STA_V_SEL); (msc_usl << STA_V_SEL);
if (DEBUG_PRS (msc_dev))
fprintf (sim_deb, ">>MSC LIx: Status = %06o\n", dat);
break; break;
case ioCTL: /* control clear/set */ case ioCTL: /* control clear/set */
if (IR & I_CTL) { clrCTL (devc); } /* CLC */ 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? */ if ((msc_buf & 0377) == FNC_CLR) { /* clear? */
for (i = 0; i < MS_NUMDR; i++) { /* loop thru units */ for (i = 0; i < MS_NUMDR; i++) { /* loop thru units */
if (sim_is_active (&msc_unit[i]) && /* write in prog? */ 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)) if (st = sim_tape_wrrecf (uptr, msxb, ms_ptr | MTR_ERF))
ms_map_err (uptr, st); } ms_map_err (uptr, st); }
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 not rew */
clrCTL (devc); /* init device */ setCTL (devc); /* set CTL for STC */
setFSR (devc); setFSR (devc); /* set FLG for completion */
clrCTL (devd); msc_sta = msc_1st = 0; /* clr ctlr status */
setFSR (devd); if (DEBUG_PRS (msc_dev))
msc_sta = msd_buf = msc_buf = msc_1st = 0; fputs (">>MSC STC: Controller cleared\n", sim_deb);
return SCPE_OK; } return SCPE_OK; }
uptr->FNC = msc_buf & 0377; /* save function */ uptr->FNC = msc_buf & 0377; /* save function */
if (uptr->FNC & FNF_RWD) /* rewind? */ if (uptr->FNC & FNF_RWD) { /* rewind? */
sim_activate (uptr, msc_rtime); /* fast response */ if (!(uptr->UST & STA_BOT)) /* not at BOT? */
else sim_activate (uptr, msc_ctime); /* schedule op */ uptr->UST = STA_REW; /* set rewinding */
uptr->UST = 0; /* clear status */ 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_sta = STA_BUSY; /* ctrl is busy */
msc_1st = 1; msc_1st = 1;
setCTL (devc); } /* go */ setCTL (devc); } /* go */
@ -381,29 +468,34 @@ return dat;
t_stat msc_svc (UNIT *uptr) t_stat msc_svc (UNIT *uptr)
{ {
int32 devc, devd; int32 devc, devd, unum, cap;
t_mtrlnt tbc; t_mtrlnt tbc;
t_stat st, r = SCPE_OK; t_stat st, r = SCPE_OK;
devc = msc_dib.devno; /* get device nos */ devc = msc_dib.devno; /* get device nos */
devd = msd_dib.devno; 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 */ msc_sta = (msc_sta | STA_REJ) & ~STA_BUSY; /* reject */
setFSR (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 */
case FNC_REW: /* rewind */
case FNC_RWS: /* rewind offline */ 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? */ if (uptr->UST & STA_REW) { /* rewind in prog? */
sim_tape_rewind (uptr); /* done */ uptr->FNC |= FNC_CMPL; /* set compl state */
uptr->UST = STA_BOT; /* set BOT status */ sim_activate (uptr, msc_ctime); } /* sched completion */
if (uptr->FNC & FNF_OFL) detach_unit (uptr); break; /* anyway, ctrl done */
return SCPE_OK; }
uptr->UST = STA_REW; /* set rewinding */ case FNC_REW | FNC_CMPL: /* complete rewind */
sim_activate (uptr, msc_ctime); /* sched completion */ sim_tape_rewind (uptr); /* rewind tape */
break; /* "done" */ uptr->UST = STA_BOT; /* set BOT status */
return SCPE_OK; /* drive is free */
case FNC_GFM: /* gap file mark */ case FNC_GFM: /* gap file mark */
case FNC_WFM: /* write file mark */ case FNC_WFM: /* write file mark */
@ -430,17 +522,16 @@ case FNC_BSR:
break; break;
case FNC_FSF: case FNC_FSF:
while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ; cap = (TCAP << uptr->REEL) << ms_ctype;
if (st == MTSE_TMK) /* stopped by tmk? */ while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) {
msc_sta = msc_sta | STA_EOF | STA_ODD; /* normal status */ if (uptr->REEL && sim_tape_eot (uptr, cap))
else r = ms_map_err (uptr, st); /* map error */ break; } /* EOT stops */
r = ms_map_err (uptr, st); /* map error */
break; break;
case FNC_BSF: case FNC_BSF:
while ((st = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ; while ((st = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ;
if (st == MTSE_TMK) /* stopped by tmk? */ r = ms_map_err (uptr, st); /* map error */
msc_sta = msc_sta | STA_EOF | STA_ODD; /* normal status */
else r = ms_map_err (uptr, st); /* map error */
break; break;
/* Unit service, continued */ /* Unit service, continued */
@ -454,21 +545,27 @@ case FNC_RC: /* read */
else if (st != MTSE_OK) { /* other error? */ else if (st != MTSE_OK) { /* other error? */
r = ms_map_err (uptr, st); /* map error */ r = ms_map_err (uptr, st); /* map error */
if (r == SCPE_OK) { /* recoverable? */ if (r == SCPE_OK) { /* recoverable? */
sim_activate (uptr, msc_gtime); /* sched IRG */ sim_activate (uptr, msc_itime); /* sched IRG */
uptr->FNC = 0; /* NOP func */ uptr->FNC |= FNC_CMPL; /* set completion */
return SCPE_OK; } return SCPE_OK; }
break; } /* err, done */ 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 (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) |
((ms_ptr + 1 == ms_max) ? 0 : msxb[ms_ptr + 1]);
ms_ptr = ms_ptr + 2; ms_ptr = ms_ptr + 2;
setFSR (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 */ 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? */ 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; return SCPE_OK;
case FNC_WC: /* write */ case FNC_WC: /* write */
@ -485,11 +582,13 @@ case FNC_WC: /* write */
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 */
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? */ if (st = sim_tape_wrrecf (uptr, msxb, ms_ptr)) { /* write, err? */
r = ms_map_err (uptr, st); /* map error */ r = ms_map_err (uptr, st); /* map error */
break; } } break; } }
sim_activate (uptr, msc_gtime); /* sched IRG */ sim_activate (uptr, msc_itime); /* sched IRG */
uptr->FNC = 0; /* NOP func */ uptr->FNC |= FNC_CMPL; /* set completion */
return SCPE_OK; return SCPE_OK;
default: /* unknown */ default: /* unknown */
@ -497,22 +596,30 @@ default: /* unknown */
setFSR (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; 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 */ /* Map tape error status */
t_stat ms_map_err (UNIT *uptr, t_stat st) 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) { switch (st) {
case MTSE_FMT: /* illegal fmt */ case MTSE_FMT: /* illegal fmt */
case MTSE_UNATT: /* unattached */ case MTSE_UNATT: /* unattached */
msc_sta = msc_sta | STA_REJ; /* reject */ msc_sta = msc_sta | STA_REJ; /* reject */
case MTSE_OK: /* no error */ case MTSE_OK: /* no error */
return SCPE_IERR; /* never get here! */ return SCPE_IERR; /* never get here! */
case MTSE_EOM: /* end of medium */
case MTSE_TMK: /* end of file */ case MTSE_TMK: /* end of file */
msc_sta = msc_sta | STA_EOF | STA_ODD; /* eof (also sets odd) */ msc_sta = msc_sta | STA_EOF | (ms_ctype ? 0 : STA_ODD);
break; break; /* EOF also sets ODD for 13181A */
case MTSE_INVRL: /* invalid rec lnt */ case MTSE_INVRL: /* invalid rec lnt */
msc_sta = msc_sta | STA_PAR; msc_sta = msc_sta | STA_PAR;
return SCPE_MTRLNT; return SCPE_MTRLNT;
@ -521,11 +628,10 @@ case MTSE_IOERR: /* IO error */
if (msc_stopioe) return SCPE_IOERR; if (msc_stopioe) return SCPE_IOERR;
break; break;
case MTSE_RECE: /* record in error */ case MTSE_RECE: /* record in error */
case MTSE_EOM: /* end of medium */
msc_sta = msc_sta | STA_PAR; /* error */ msc_sta = msc_sta | STA_PAR; /* error */
break; break;
case MTSE_BOT: /* reverse into BOT */ case MTSE_BOT: /* reverse into BOT */
uptr->UST = STA_BOT; /* set status */ msc_sta = msc_sta | STA_BOT; /* set BOT status */
break; break;
case MTSE_WRP: /* write protect */ case MTSE_WRP: /* write protect */
msc_sta = msc_sta | STA_REJ; /* reject */ msc_sta = msc_sta | STA_REJ; /* reject */
@ -553,7 +659,10 @@ 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);
sim_cancel (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; return SCPE_OK;
} }
@ -564,8 +673,7 @@ t_stat msc_attach (UNIT *uptr, char *cptr)
t_stat r; t_stat r;
r = sim_tape_attach (uptr, cptr); /* attach unit */ r = sim_tape_attach (uptr, cptr); /* attach unit */
if (r != SCPE_OK) return r; /* update status */ if (r == SCPE_OK) uptr->UST = STA_BOT; /* tape starts at BOT */
uptr->UST = STA_BOT;
return r; return r;
} }
@ -577,6 +685,36 @@ uptr->UST = 0; /* update status */
return sim_tape_detach (uptr); /* detach unit */ 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 */ /* Set controller type */
t_stat ms_settype (UNIT *uptr, int32 val, char *cptr, void *desc) 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++) { for (i = 0; i < MS_NUMDR; i++) {
if (msc_unit[i].flags & UNIT_ATT) return SCPE_ALATT; } if (msc_unit[i].flags & UNIT_ATT) return SCPE_ALATT; }
ms_ctype = val; ms_ctype = val;
ms_config_timing (); /* update for new type */
return SCPE_OK; return SCPE_OK;
} }
@ -599,6 +738,43 @@ else fprintf (st, "13181A");
return SCPE_OK; 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) */ /* 7970B/7970E bootstrap routine (HP 12992D ROM) */
const uint16 ms_rom[IBL_LNT] = { 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? */ if ((sim_switches & SWMASK ('S')) && AR) SR = SR | 1; /* skip? */
return SCPE_OK; return SCPE_OK;
} }

View file

@ -25,6 +25,7 @@
mt 12559A 3030 nine track magnetic tape 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) 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 26-Apr-04 RMS Fixed SFS x,C and SFC x,C
Implemented DMA SRQ (follows FLG) Implemented DMA SRQ (follows FLG)
@ -408,7 +409,7 @@ default: /* unknown */
setFSR (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 r;
} }
/* Map tape error status */ /* Map tape error status */
@ -421,6 +422,7 @@ case MTSE_UNATT: /* unattached */
mtc_sta = mtc_sta | STA_REJ; /* reject */ mtc_sta = mtc_sta | STA_REJ; /* reject */
case MTSE_OK: /* no error */ case MTSE_OK: /* no error */
return SCPE_IERR; /* never get here! */ return SCPE_IERR; /* never get here! */
case MTSE_EOM: /* end of medium */
case MTSE_TMK: /* end of file */ case MTSE_TMK: /* end of file */
mtc_sta = mtc_sta | STA_EOF; /* eof */ mtc_sta = mtc_sta | STA_EOF; /* eof */
break; break;
@ -432,7 +434,6 @@ case MTSE_INVRL: /* invalid rec lnt */
mtc_sta = mtc_sta | STA_PAR; mtc_sta = mtc_sta | STA_PAR;
return SCPE_MTRLNT; return SCPE_MTRLNT;
case MTSE_RECE: /* record in error */ case MTSE_RECE: /* record in error */
case MTSE_EOM: /* end of medium */
mtc_sta = mtc_sta | STA_PAR; /* error */ mtc_sta = mtc_sta | STA_PAR; /* error */
break; break;
case MTSE_BOT: /* reverse into BOT */ case MTSE_BOT: /* reverse into BOT */

View file

@ -28,6 +28,7 @@
tty 12531C buffered teleprinter interface tty 12531C buffered teleprinter interface
clk 12539C time base generator 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 14-Jul-04 RMS Generalized handling of control char echoing
(from Dave Bryan) (from Dave Bryan)
26-Apr-04 RMS Fixed SFS x,C and SFC x,C 26-Apr-04 RMS Fixed SFS x,C and SFC x,C
@ -76,9 +77,10 @@
#define BS_FLAG CHAR_FLAG('\b') #define BS_FLAG CHAR_FLAG('\b')
#define LF_FLAG CHAR_FLAG('\n') #define LF_FLAG CHAR_FLAG('\n')
#define CR_FLAG CHAR_FLAG('\r') #define CR_FLAG CHAR_FLAG('\r')
#define HT_FLAG CHAR_FLAG('\t')
#define FULL_SET 0xFFFFFFFF #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_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 */

View file

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

View file

@ -26,6 +26,7 @@
rq RQDX3 disk controller 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 05-Feb-04 RMS Revised for file I/O library
25-Jan-04 RMS Revised for device debug support 25-Jan-04 RMS Revised for device debug support
12-Jan-04 RMS Fixed bug in interrupt control (found by Tom Evans) 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??? */ if (cidx < 0) return SCPE_IERR; /* not found??? */
cp = rq_ctxmap[cidx]; /* get context */ cp = rq_ctxmap[cidx]; /* get context */
cp->cnum = cidx; /* init index */ 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 */ cp->ubase = cidx * RQ_NUMDR; /* init unit base */
#endif
cp->csta = CST_S1; /* init stage 1 */ cp->csta = CST_S1; /* init stage 1 */
cp->s1dat = 0; /* no S1 data */ cp->s1dat = 0; /* no S1 data */
dibp->vec = 0; /* no vector */ dibp->vec = 0; /* no vector */

View file

@ -25,6 +25,7 @@
cpu CVAX central processor 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) 28-Jun-04 RMS Fixed bug in DIVBx, DIVWx (reported by Peter Trimmel)
18-Apr-04 RMS Added octaword macros 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
@ -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_polyf (int32 *opnd, int32 acc);
extern void op_polyd (int32 *opnd, int32 acc); extern void op_polyd (int32 *opnd, int32 acc);
extern void op_polyg (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 intexc (int32 vec, int32 cc, int32 ipl, int ei);
extern int32 Read (uint32 va, int32 lnt, int32 acc); extern int32 Read (uint32 va, int32 lnt, int32 acc);
extern void Write (uint32 va, int32 val, 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 */ temp = fault_PC - PC; /* delta PC if needed */
SETPC (fault_PC); /* restore PC */ SETPC (fault_PC); /* restore PC */
switch (-abortval) { /* case on abort code */ 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 */ if (in_ie) ABORT (STOP_INIE); /* in exc? panic */
cc = intexc (-abortval, cc, 0, IE_EXC); /* take exception */ cc = intexc (-abortval, cc, 0, IE_EXC); /* take exception */
GET_CUR; /* PSL<cur> changed */ GET_CUR; /* PSL<cur> changed */
break; break;
case SCB_CMODE: /* comp mode fault */
case SCB_ARITH: /* arithmetic fault */ case SCB_ARITH: /* arithmetic fault */
if (in_ie) ABORT (STOP_INIE); /* in exc? panic */ if (in_ie) ABORT (STOP_INIE); /* in exc? panic */
cc = intexc (-abortval, cc, 0, IE_EXC); /* take exception */ 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; SP = SP - 4;
in_ie = 0; in_ie = 0;
break; 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 (in_ie) { /* in exception? */
if (PSL & PSL_IS) ABORT (STOP_INIE); /* on is? panic */ if (PSL & PSL_IS) ABORT (STOP_INIE); /* on is? panic */
cc = intexc (SCB_KSNV, cc, 0, IE_SVE); /* ksnv */ 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].PSL = PSL | cc;
hst[hst_p].opc = opc; hst[hst_p].opc = opc;
hst[hst_p].brdest = brdisp + PC; 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[hst_p].opnd[i] = opnd[i];
hst_p = hst_p + 1; hst_p = hst_p + 1;
if (hst_p >= hst_lnt) hst_p = 0; if (hst_p >= hst_lnt) hst_p = 0;
@ -2197,7 +2202,9 @@ case EMODF:
case EMODD: case EMODD:
r = op_emodd (opnd, &rh, &temp, &flg); 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; if (op5 >= 0) R[op5] = temp;
else Write (op6, temp, L_LONG, WA); else Write (op6, temp, L_LONG, WA);
WRITE_Q (r, rh); WRITE_Q (r, rh);
@ -2207,7 +2214,9 @@ case EMODD:
case EMODG: case EMODG:
r = op_emodg (opnd, &rh, &temp, &flg); 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; if (op5 >= 0) R[op5] = temp;
else Write (op6, temp, L_LONG, WA); else Write (op6, temp, L_LONG, WA);
WRITE_Q (r, rh); WRITE_Q (r, rh);
@ -2263,16 +2272,15 @@ case MFPR:
CC_IIZP_L (r); CC_IIZP_L (r);
break; break;
/* Emulated instructions */ /* Emulated CIS instructions */
case CVTPL: case CVTPL:
opnd[2] = (opnd[2] >= 0)? ~opnd[2]: opnd[3];
case MOVP: case CMPP3: case CMPP4: case CVTLP: case MOVP: case CMPP3: case CMPP4: case CVTLP:
case CVTPS: case CVTSP: case CVTTP: case CVTPT: case CVTPS: case CVTSP: case CVTTP: case CVTPT:
case ADDP4: case ADDP6: case SUBP4: case SUBP6: case ADDP4: case ADDP6: case SUBP4: case SUBP6:
case MULP: case DIVP: case ASHP: case CRC: case MULP: case DIVP: case ASHP: case CRC:
case MOVTC: case MOVTUC: case MATCHC: case EDITPC: case MOVTC: case MOVTUC: case MATCHC: case EDITPC:
cc = op_emulate (opnd, cc, opc, acc); cc = op_cis (opnd, cc, opc, acc);
break; break;
default: default:
RSVD_INST_FAULT; RSVD_INST_FAULT;

View file

@ -1446,7 +1446,7 @@ default: /* others */
return val; return val;
} }
/* Emulated instructions /* Emulated CIS instructions
opnd[0:5] = six operands to be pushed (if PSL<fpd> = 0) opnd[0:5] = six operands to be pushed (if PSL<fpd> = 0)
cc = condition codes cc = condition codes
@ -1458,7 +1458,7 @@ return val;
In both cases, the exception occurs in the current mode. 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; int32 vec;
@ -1468,7 +1468,9 @@ if (PSL & PSL_FPD) { /* FPD set? */
Write (SP - 4, PSL | cc, L_LONG, WA); /* push PSL */ Write (SP - 4, PSL | cc, L_LONG, WA); /* push PSL */
SP = SP - 8; /* decr stk ptr */ SP = SP - 8; /* decr stk ptr */
vec = ReadLP ((SCBB + SCB_EMULFPD) & PAMASK); } 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 - 48, opc, L_LONG, WA); /* push opcode */
Write (SP - 44, fault_PC, L_LONG, WA); /* push old PC */ Write (SP - 44, fault_PC, L_LONG, WA); /* push old PC */
Write (SP - 40, opnd[0], L_LONG, WA); /* push operands */ 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 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
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 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
@ -60,7 +62,8 @@
#define ABORT_MCHK (-SCB_MCHK) /* machine check */ #define ABORT_MCHK (-SCB_MCHK) /* machine check */
#define ABORT_RESIN (-SCB_RESIN) /* rsvd instruction */ #define ABORT_RESIN (-SCB_RESIN) /* rsvd instruction */
#define ABORT_RESAD (-SCB_RESAD) /* rsvd addr mode */ #define ABORT_RESAD (-SCB_RESAD) /* rsvd addr mode */
#define ABORT_RESOP (-SCB_RESOP) /* rsvd operand */ #define ABORT_RESOP (-SCB_RESOP) /* rsvd operand */
#define ABORT_CMODE (-SCB_CMODE) /* comp mode fault */
#define ABORT_ARITH (-SCB_ARITH) /* arithmetic trap */ #define ABORT_ARITH (-SCB_ARITH) /* arithmetic trap */
#define ABORT_ACV (-SCB_ACV) /* access violation */ #define ABORT_ACV (-SCB_ACV) /* access violation */
#define ABORT_TNV (-SCB_TNV) /* transl not vaid */ #define ABORT_TNV (-SCB_TNV) /* transl not vaid */
@ -71,6 +74,7 @@
#define FLT_OVFL_FAULT p1 = FLT_OVRFLO, ABORT (ABORT_ARITH) #define FLT_OVFL_FAULT p1 = FLT_OVRFLO, ABORT (ABORT_ARITH)
#define FLT_DZRO_FAULT p1 = FLT_DIVZRO, ABORT (ABORT_ARITH) #define FLT_DZRO_FAULT p1 = FLT_DIVZRO, ABORT (ABORT_ARITH)
#define FLT_UNFL_FAULT p1 = FLT_UNDFLO, 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) #define MACH_CHECK(cd) p1 = (cd), ABORT (ABORT_MCHK)
/* Address space */ /* Address space */
@ -150,6 +154,8 @@
/* PSL, PSW, and condition codes */ /* 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_V_TP 30 /* trace pending */
#define PSL_TP (1 << PSL_V_TP) #define PSL_TP (1 << PSL_V_TP)
#define PSL_V_FPD 27 /* first part done */ #define PSL_V_FPD 27 /* first part done */
@ -239,6 +245,10 @@
#define TIR_TRAP (TIR_M_TRAP << TIR_V_TRAP) #define TIR_TRAP (TIR_M_TRAP << TIR_V_TRAP)
#define TRAP_INTOV (1 << TIR_V_TRAP) /* integer overflow */ #define TRAP_INTOV (1 << TIR_V_TRAP) /* integer overflow */
#define TRAP_DIVZRO (2 << TIR_V_TRAP) /* divide by zero */ #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 TRAP_SUBSCR (7 << TIR_V_TRAP) /* subscript range */
#define SET_TRAP(x) trpirq = (trpirq & PSL_M_IPL) | (x) #define SET_TRAP(x) trpirq = (trpirq & PSL_M_IPL) | (x)
#define CLR_TRAPS trpirq = trpirq & ~TIR_TRAP #define CLR_TRAPS trpirq = trpirq & ~TIR_TRAP
@ -252,6 +262,50 @@
#define FLT_DIVZRO 0x9 /* flt div by zero */ #define FLT_DIVZRO 0x9 /* flt div by zero */
#define FLT_UNDFLO 0xA /* flt underflow */ #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 */ /* SCB offsets */
#define SCB_MCHK 0x04 /* machine chk */ #define SCB_MCHK 0x04 /* machine chk */
@ -265,6 +319,7 @@
#define SCB_TNV 0x24 /* TNV */ #define SCB_TNV 0x24 /* TNV */
#define SCB_TP 0x28 /* trace pending */ #define SCB_TP 0x28 /* trace pending */
#define SCB_BPT 0x2C /* BPT instr */ #define SCB_BPT 0x2C /* BPT instr */
#define SCB_CMODE 0x30 /* comp mode fault */
#define SCB_ARITH 0x34 /* arith fault */ #define SCB_ARITH 0x34 /* arith fault */
#define SCB_CHMK 0x40 /* CHMK */ #define SCB_CHMK 0x40 /* CHMK */
#define SCB_CHME 0x44 /* CHME */ #define SCB_CHME 0x44 /* CHME */
@ -458,10 +513,16 @@ enum opcodes {
BBS, BBC, BBSS, BBCS, BBSC, BBCC, BBSSI, BBCCI, BBS, BBC, BBSS, BBCS, BBSC, BBCC, BBSSI, BBCCI,
BLBS, BLBC, FFS, FFC, CMPV, CMPZV, EXTV, EXTZV, BLBS, BLBC, FFS, FFC, CMPV, CMPZV, EXTV, EXTZV,
INSV, ACBL, AOBLSS, AOBLEQ, SOBGEQ, SOBGTR, CVTLB, CVTLW, INSV, ACBL, AOBLSS, AOBLEQ, SOBGEQ, SOBGTR, CVTLB, CVTLW,
ASHP, CVTLP, CALLG, CALLS, XFC, CVTGF = 0x133, ASHP, CVTLP, CALLG, CALLS, XFC, CVTDH = 0x132, CVTGF = 0x133,
ADDG2= 0x140, ADDG3, SUBG2, SUBG3, MULG2, MULG3, DIVG2, DIVG3, ADDG2 = 0x140, ADDG3, SUBG2, SUBG3, MULG2, MULG3, DIVG2, DIVG3,
CVTGB, CVTGW, CVTGL, CVTRGL, CVTBG, CVTWG, CVTLG, ACBG, 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 */ /* Repeated operations */
@ -482,6 +543,7 @@ enum opcodes {
#define BRANCHB(d) PCQ_ENTRY, PC = PC + SXTB (d), FLUSH_ISTR #define BRANCHB(d) PCQ_ENTRY, PC = PC + SXTB (d), FLUSH_ISTR
#define BRANCHW(d) PCQ_ENTRY, PC = PC + SXTW (d), FLUSH_ISTR #define BRANCHW(d) PCQ_ENTRY, PC = PC + SXTW (d), FLUSH_ISTR
#define JUMP(d) PCQ_ENTRY, PC = (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 SETPC(d) PC = (d), FLUSH_ISTR
#define FLUSH_ISTR ibcnt = 0, ppc = -1 #define FLUSH_ISTR ibcnt = 0, ppc = -1

View file

@ -13,7 +13,7 @@ endif
CC = gcc -std=c99 -O2 -g -lm $(OS_CCDEFS) -I . CC = gcc -std=c99 -O2 -g -lm $(OS_CCDEFS) -I .
ifeq ($(USE_NETWORK),) ifeq ($(USE_NETWORK),)
else 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 endif
else else
#Win32 Environments #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 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.
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 12-Jul-04 RMS Fixed problem ATTACHing to read only files
(found by John Dundas) (found by John Dundas)
28-May-04 RMS Added SET/SHOW CONSOLE 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 do_cmd (int32 flag, char *ptr);
t_stat help_cmd (int32 flag, char *ptr); t_stat help_cmd (int32 flag, char *ptr);
t_stat spawn_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 */ /* Set and show command processors */
@ -521,6 +524,8 @@ static CTAB cmd_table[] = {
"sh{ow} <unit> {arg,...} show unit parameters\n" }, "sh{ow} <unit> {arg,...} show unit parameters\n" },
{ "DO", &do_cmd, 0, { "DO", &do_cmd, 0,
"do <file> {arg,arg...} process command file\n" }, "do <file> {arg,arg...} process command file\n" },
{ "ECHO", &echo_cmd, 0,
"echo <string> display <string>\n" },
{ "HELP", &help_cmd, 0, { "HELP", &help_cmd, 0,
"h{elp} type this message\n" "h{elp} type this message\n"
"h{elp} <command> type help for command\n" }, "h{elp} <command> type help for command\n" },
@ -699,6 +704,15 @@ system (cptr);
printf ("\n"); printf ("\n");
#endif #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; 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 == NULL) break; /* exit on eof */
if (*cptr == 0) continue; /* ignore blank */ if (*cptr == 0) continue; /* ignore blank */
if (echo) printf("do> %s\n", cptr); /* echo if -v */ 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 */ cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */
sim_switches = 0; /* init switches */ sim_switches = 0; /* init switches */
if (strcmp (gbuf, "DO") == 0) { /* don't recurse */ 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 */ if (!(dptr->flags & DEV_NET) || /* if not net dev or */
!(uptr->flags & UNIT_ATT) || /* not currently att */ !(uptr->flags & UNIT_ATT) || /* not currently att */
(buf[0] == 0)) { /* or will not be 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 */ r = scp_detach_unit (dptr, uptr); /* detach old */
if (r != SCPE_OK) return r; if (r != SCPE_OK) return r;
if (buf[0] != 0) { /* any file? */ if (buf[0] != 0) { /* any file? */
uptr->flags = uptr->flags & ~UNIT_DIS; uptr->flags = uptr->flags & ~UNIT_DIS;
sim_switches = SIM_SW_REST; /* attach/rest */
if (flg & UNIT_RO) /* [V2.10+] saved flgs & RO? */ if (flg & UNIT_RO) /* [V2.10+] saved flgs & RO? */
sim_switches |= SWMASK ('R'); /* RO attach */ sim_switches |= SWMASK ('R'); /* RO attach */
r = scp_attach_unit (dptr, uptr, buf); 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 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.
20-Aug-04 RMS Added OS/2 EMX fixes (from Holger Veit)
14-Jul-04 RMS Revised Windows console code (from Dave Bryan) 14-Jul-04 RMS Revised Windows console code (from Dave Bryan)
28-May-04 RMS Added SET/SHOW CONSOLE 28-May-04 RMS Added SET/SHOW CONSOLE
RMS Added break, delete character maps RMS Added break, delete character maps
@ -471,7 +472,6 @@ return SCPE_OK;
#include <fcntl.h> #include <fcntl.h>
#include <io.h> #include <io.h>
#include <windows.h> #include <windows.h>
#include <signal.h>
#define RAW_MODE 0 #define RAW_MODE 0
static HANDLE std_input; static HANDLE std_input;
static DWORD saved_mode; static DWORD saved_mode;
@ -490,7 +490,7 @@ if (!GetConsoleMode(std_input, &saved_mode) ||
!SetConsoleMode(std_input, RAW_MODE)) return SCPE_TTYERR; !SetConsoleMode(std_input, RAW_MODE)) return SCPE_TTYERR;
if (sim_log) { if (sim_log) {
fflush (sim_log); fflush (sim_log);
setmode (_fileno (sim_log), _O_BINARY); } _setmode (_fileno (sim_log), _O_BINARY); }
SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
return SCPE_OK; return SCPE_OK;
} }
@ -528,7 +528,7 @@ if (c != 0177) _putch (c);
return SCPE_OK; return SCPE_OK;
} }
/* OS/2 routines, from Bruce Ray */ /* OS/2 routines, from Bruce Ray and Holger Veit */
#elif defined (__OS2__) #elif defined (__OS2__)
@ -558,8 +558,19 @@ t_stat sim_os_poll_kbd (void)
{ {
int c; 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; if (!kbhit ()) return SCPE_OK;
c = getch(); c = getch();
#endif
if ((c & 0177) == sim_del_char) 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; 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) t_stat sim_os_putchar (int32 c)
{ {
if (c != 0177) { if (c != 0177) {
#if defined (__EMX__)
putchar (c);
#else
putch (c); putch (c);
#endif
fflush (stdout); } fflush (stdout); }
return SCPE_OK; return SCPE_OK;
} }

View file

@ -29,12 +29,51 @@
#define SIM_MAJOR 3 #define SIM_MAJOR 3
#define SIM_MINOR 2 #define SIM_MINOR 2
#define SIM_PATCH 2 #define SIM_PATCH 3
/* V3.2 revision history /* V3.2 revision history
patch date module(s) and fix(es) 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 2 17-Jul-04 scp.c: fixed problem ATTACHing to read only files
(found by John Dundas) (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 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 - SBT increments B after store
- DMS console map must check dms_enb - DMS console map must check dms_enb
- SFS x,C and SFC x,C work - 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 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.
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 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 avoid a conflict if sim_sock.h and sim_ether.h get
included by the same module. included by the same module.
@ -65,6 +66,11 @@
#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 #define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0
#endif #endif
#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_master_sock (int32 port);
SOCKET sim_connect_sock (int32 ip, 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, Ultimately, this will be a place to hide processing of various tape formats,
as well as OS-specific direct hardware access. 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 05-Jan-04 RMS Revised for file I/O library
25-Apr-03 RMS Added extended file support 25-Apr-03 RMS Added extended file support
28-Mar-03 RMS Added E11 and TPC format support 28-Mar-03 RMS Added E11 and TPC format support
@ -364,8 +366,8 @@ t_mtrlnt sbc;
MT_CLR_PNU (uptr); MT_CLR_PNU (uptr);
if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */ if ((uptr->flags & UNIT_ATT) == 0) return MTSE_UNATT; /* not attached? */
if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */ if (sim_tape_wrp (uptr)) return MTSE_WRP; /* write prot? */
if (f == MTUF_F_STD) sbc = (bc + 1) & ~1; if (f == MTUF_F_STD) sbc = MTR_L ((bc + 1) & ~1);
else sbc = bc; else sbc = MTR_L (bc);
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */ sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* set pos */
sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref); sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref);
sim_fwrite (buf, sizeof (uint8), sbc, uptr->fileref); sim_fwrite (buf, sizeof (uint8), sbc, uptr->fileref);
@ -427,7 +429,7 @@ t_stat st;
if (MT_TST_PNU (uptr)) { if (MT_TST_PNU (uptr)) {
MT_CLR_PNU (uptr); MT_CLR_PNU (uptr);
*bc = 0; *bc = 0;
return SCPE_OK; } return MTSE_OK; }
st = sim_tape_rdlntr (uptr, bc); /* get record length */ st = sim_tape_rdlntr (uptr, bc); /* get record length */
*bc = MTR_L (*bc); *bc = MTR_L (*bc);
return st; return st;
@ -479,7 +481,7 @@ t_stat sim_tape_ioerr (UNIT *uptr)
{ {
perror ("Magtape library I/O error"); perror ("Magtape library I/O error");
clearerr (uptr->fileref); clearerr (uptr->fileref);
return SCPE_IOERR; return MTSE_IOERR;
} }
/* Set tape format */ /* Set tape format */

View file

@ -1,7 +1,7 @@
To: Users To: Users
From: Bob Supnik From: Bob Supnik
Subj: Simulator Usage, V3.2-1 Subj: Simulator Usage, V3.2-3
Date: 15-Jun-2004 Date: 20-Aug-2004
COPYRIGHT NOTICE COPYRIGHT NOTICE
@ -705,6 +705,11 @@ quotation marks.
If the switch -V is specified, the commands in the file are echoed If the switch -V is specified, the commands in the file are echoed
before they are executed. 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 3.13 Executing System Commands
The simulator can execute operating system commands with the ! (spawn) The simulator can execute operating system commands with the ! (spawn)