mirror of
https://github.com/simh/simh.git
synced 2026-05-02 06:15:23 +00:00
Notes For V3.3
RESTRICTION: The HP DS disk is not debugged. DO NOT enable this feature for normal operations. WARNING: Massive changes in the PDP-11 make all previous SAVEd file obsolete. Do not attempt to use a PDP-11 SAVE file from a prior release with V3.3! 1. New Features in 3.3 1.1 SCP - Added -p (powerup) qualifier to RESET - Changed SET <unit> ONLINE/OFFLINE to SET <unit> ENABLED/DISABLED - Moved SET DEBUG under SET CONSOLE hierarchy - Added optional parameter value to SHOW command - Added output file option to SHOW command 1.2 PDP-11 - Separated RH Massbus adapter from RP controller - Added TU tape support - Added model emulation framework - Added model details 1.3 VAX - Separated out CVAX-specific features from core instruction simulator - Implemented capability for CIS, octaword, compatibility mode instructions - Added instruction display and parse for compatibility mode - Changed SET CPU VIRTUAL=n to SHOW CPU VIRTUAL=n - Added =n optional parameter to SHOW CPU HISTORY 1.4 Unibus/Qbus simulators (PDP-11, VAX, PDP-10) - Simplified DMA API's - Modified DMA peripherals to use simplified API's 1.5 HP2100 (all changes from Dave Bryan) CPU - moved MP into its own device; added MP option jumpers - modified DMA to allow disabling - modified SET CPU 2100/2116 to truncate memory > 32K - added -F switch to SET CPU to force memory truncation - modified WRU to be REG_HRO - added BRK and DEL to save console settings DR - provided protected tracks and "Writing Enabled" status bit - added "parity error" status return on writes for 12606 - added track origin test for 12606 - added SCP test for 12606 - added "Sector Flag" status bit - added "Read Inhibit" status bit for 12606 - added TRACKPROT modifier LPS - added SET OFFLINE/ONLINE, POWEROFF/POWERON - added fast/realistic timing - added debug printouts LPT - added SET OFFLINE/ONLINE, POWEROFF/POWERON PTR - added paper tape loop mode, DIAG/READER modifiers to PTR - added PV_LEFT to PTR TRLLIM register CLK - modified CLK to permit disable 1.6 IBM 1401, IBM 1620, Interdata 16b, SDS 940, PDP-10 - Added instruction history 1.7 H316, PDP-15, PDP-8 - Added =n optional value to SHOW CPU HISTORY 2. Bugs Fixed in 3.3 2.1 SCP - Fixed comma-separated SET options (from Dave Bryan) - Fixed duplicate HELP displays with user-specified commands 2.2 PDP-10 - Replicated RP register state per drive - Fixed TU to set FCE on short record - Fixed TU to return bit<15> in drive type - Fixed TU format specification, 1:0 are don't cares - Fixed TU handling of TMK status - Fixed TU handling of DONE, ATA at end of operation - Implemented TU write check 2.3 PDP-11 - Replicated RP register state per drive - Fixed RQ, TQ to report correct controller type and stage 1 configuration flags on a Unibus system - Fixed HK CS2<output_ready> flag 2.4 VAX - Fixed parsing of indirect displacement modes in instruction input 2.5 HP2100 (all fixes from Dave Bryan) CPU - fixed S-register behavior on 2116 - fixed LIx/MIx behavior for DMA on 2116 and 2100 - fixed LIx/MIx behavior for empty I/O card slots DP - fixed enable/disable from either device - fixed ANY ERROR status for 12557A interface - fixed unattached drive status for 12557A interface - status cmd without prior STC DC now completes (12557A) - OTA/OTB CC on 13210A interface also does CLC CC - fixed RAR model - fixed seek check on 13210 if sector out of range DQ - fixed enable/disable from either device - shortened xtime from 5 to 3 (drive avg 156KW/second) - fixed not ready/any error status - fixed RAR model DR - fixed enable/disable from either device - fixed sector return in status word - fixed DMA last word write, incomplete sector fill value - fixed 12610 SFC operation - fixed current-sector determination IPL - fixed enable/disable from either device LPS - fixed status returns for error conditions - fixed handling of non-printing characters - fixed handling of characters after column 80 - improved timing model accuracy for RTE LPT - fixed status returns for error conditions - fixed TOF handling so form remains on line 0 SYS - fixed display of CCA/CCB/CCE instructions 2.5 PDP-15 FPP - fixed URFST to mask low 9b of fraction - fixed exception PC setting
This commit is contained in:
committed by
Mark Pizzolato
parent
2e00e1122f
commit
b6393b36b4
@@ -25,6 +25,7 @@
|
||||
|
||||
cpu KS10 central processor
|
||||
|
||||
10-Nov-04 RMS Added instruction history
|
||||
08-Oct-02 RMS Revised to build dib_tab dynamically
|
||||
Added SHOW IOSPACE
|
||||
30-Dec-01 RMS Added old PC queue
|
||||
@@ -136,6 +137,15 @@
|
||||
#define UNIT_V_MSIZE (UNIT_V_T20V41 + 1) /* dummy mask */
|
||||
#define UNIT_MSIZE (1 << UNIT_V_MSIZE)
|
||||
|
||||
#define HIST_PC 0x40000000
|
||||
#define HIST_MIN 64
|
||||
#define HIST_MAX 65536
|
||||
struct InstHistory {
|
||||
a10 pc;
|
||||
a10 ea;
|
||||
d10 ir;
|
||||
d10 ac; };
|
||||
|
||||
d10 *M = NULL; /* memory */
|
||||
d10 acs[AC_NBLK * AC_NUM] = { 0 }; /* AC blocks */
|
||||
d10 *ac_cur, *ac_prv; /* AC cur, prv (dyn) */
|
||||
@@ -178,6 +188,9 @@ a10 pcq[PCQ_SIZE] = { 0 }; /* PC queue */
|
||||
int32 pcq_p = 0; /* PC queue ptr */
|
||||
REG *pcq_r = NULL; /* PC queue reg ptr */
|
||||
jmp_buf save_env;
|
||||
int32 hst_p = 0; /* history pointer */
|
||||
int32 hst_lnt = 0; /* history length */
|
||||
struct InstHistory *hst = NULL; /* instruction history */
|
||||
|
||||
extern int32 sim_int_char;
|
||||
extern int32 sim_interval;
|
||||
@@ -189,6 +202,8 @@ extern UNIT tim_unit;
|
||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
|
||||
t_stat cpu_reset (DEVICE *dptr);
|
||||
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
d10 adjsp (d10 val, a10 ea);
|
||||
void ibp (a10 ea, int32 pflgs);
|
||||
d10 ldb (a10 ea, int32 pflgs);
|
||||
@@ -375,6 +390,8 @@ MTAB cpu_mod[] = {
|
||||
{ UNIT_ITS+UNIT_T20V41, UNIT_ITS, "ITS microcode", "ITS", NULL },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "IOSPACE", NULL,
|
||||
NULL, &show_iospace },
|
||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY",
|
||||
&cpu_set_hist, &cpu_show_hist },
|
||||
{ 0 } };
|
||||
|
||||
DEVICE cpu_dev = {
|
||||
@@ -742,7 +759,14 @@ for (indrct = inst, i = 0; i < ind_max; i++) { /* calc eff addr */
|
||||
if (TST_IND (indrct)) indrct = Read (ea, MM_EA);
|
||||
else break; }
|
||||
if (i >= ind_max)
|
||||
ABORT (STOP_IND); /* too many ind? stop */
|
||||
ABORT (STOP_IND); /* too many ind? stop */
|
||||
if (hst_lnt) { /* history enabled? */
|
||||
hst_p = (hst_p + 1); /* next entry */
|
||||
if (hst_p >= hst_lnt) hst_p = 0;
|
||||
hst[hst_p].pc = pager_PC | HIST_PC;
|
||||
hst[hst_p].ea = ea;
|
||||
hst[hst_p].ir = inst;
|
||||
hst[hst_p].ac = AC(ac); }
|
||||
switch (op) { /* case on opcode */
|
||||
|
||||
/* UUO's (0000 - 0077) - checked against KS10 ucode */
|
||||
@@ -2100,3 +2124,63 @@ if (rptr == NULL) return;
|
||||
for (i = 0; i < AC_NUM; i++, rptr++) rptr->loc = (void *) (acbase + i);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set history */
|
||||
|
||||
t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 i, lnt;
|
||||
t_stat r;
|
||||
|
||||
if (cptr == NULL) {
|
||||
for (i = 0; i < hst_lnt; i++) hst[i].pc = 0;
|
||||
hst_p = 0;
|
||||
return SCPE_OK; }
|
||||
lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
|
||||
if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) return SCPE_ARG;
|
||||
hst_p = 0;
|
||||
if (hst_lnt) {
|
||||
free (hst);
|
||||
hst_lnt = 0;
|
||||
hst = NULL; }
|
||||
if (lnt) {
|
||||
hst = calloc (sizeof (struct InstHistory), lnt);
|
||||
if (hst == NULL) return SCPE_MEM;
|
||||
hst_lnt = lnt; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Show history */
|
||||
|
||||
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc)
|
||||
{
|
||||
int32 k, di, lnt;
|
||||
char *cptr = (char *) desc;
|
||||
t_stat r;
|
||||
t_value sim_eval;
|
||||
struct InstHistory *h;
|
||||
extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val,
|
||||
UNIT *uptr, int32 sw);
|
||||
|
||||
if (hst_lnt == 0) return SCPE_NOFNC; /* enabled? */
|
||||
if (cptr) {
|
||||
lnt = (int32) get_uint (cptr, 10, hst_lnt, &r);
|
||||
if ((r != SCPE_OK) || (lnt == 0)) return SCPE_ARG; }
|
||||
else lnt = hst_lnt;
|
||||
di = hst_p - lnt; /* work forward */
|
||||
if (di < 0) di = di + hst_lnt;
|
||||
fprintf (st, "PC AC EA IR\n\n");
|
||||
for (k = 0; k < lnt; k++) { /* print specified */
|
||||
h = &hst[(++di) % hst_lnt]; /* entry pointer */
|
||||
if (h->pc & HIST_PC) { /* instruction? */
|
||||
fprintf (st, "%06o ", h->pc & AMASK);
|
||||
fprintf (st, "%012o ", h->ac);
|
||||
fprintf (st, "%06o ", h->ea);
|
||||
sim_eval = h->ir;
|
||||
if ((fprint_sym (st, h->pc & AMASK, &sim_eval, &cpu_unit, SWMASK ('M'))) > 0)
|
||||
fprintf (st, "(undefined) %012o", h->ir);
|
||||
fputc ('\n', st); /* end line */
|
||||
} /* end else instruction */
|
||||
} /* end for */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -619,9 +619,6 @@ typedef struct pdp_dib DIB;
|
||||
|
||||
#define UNIBUS TRUE /* 18b only */
|
||||
|
||||
#define FST 0 /* Unibus 1 */
|
||||
#define MAP 1 /* Unibus 3 */
|
||||
|
||||
#define DEV_RDX 8 /* default device radix */
|
||||
|
||||
/* I/O page layout */
|
||||
@@ -739,10 +736,11 @@ typedef struct pdp_dib DIB;
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf, t_bool ub);
|
||||
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf, t_bool ub);
|
||||
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf, t_bool ub);
|
||||
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf, t_bool ub);
|
||||
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf);
|
||||
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf);
|
||||
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf);
|
||||
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf);
|
||||
|
||||
t_stat set_addr (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat set_addr_flt (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat show_addr (FILE *st, UNIT *uptr, int32 val, void *desc);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
To: Users
|
||||
From: Bob Supnik
|
||||
Subj: PDP-10 Simulator Usage
|
||||
Date: 15-Jun-2004
|
||||
Date: 15-Nov-2004
|
||||
|
||||
COPYRIGHT NOTICE
|
||||
|
||||
@@ -174,6 +174,17 @@ control registers for the interrupt system.
|
||||
WRU 8 interrupt character
|
||||
REG[0:127] 36 fast memory blocks
|
||||
|
||||
The CPU can maintain a history of the most recently executed instructions.
|
||||
This is controlled by the SET CPU HISTORY and SHOW CPU HISTORY commands:
|
||||
|
||||
SET CPU HISTORY clear history buffer
|
||||
SET CPU HISTORY=0 disable history
|
||||
SET CPU HISTORY=n enable history, length = n
|
||||
SHOW CPU HISTORY print CPU history
|
||||
SHOW CPU HISTORY=n print first n entries of CPU history
|
||||
|
||||
The maximum length for the history is 65536 entries.
|
||||
|
||||
2.2 Pager
|
||||
|
||||
The pager contains the page maps for executive and user mode. The
|
||||
@@ -417,7 +428,7 @@ to set the drive type to one of six disk types, or autosize:
|
||||
The type options can be used only when a unit is not attached to a file.
|
||||
Note that TOPS-10 V7.03 supported only the RP06 and RM03; V7.04 added
|
||||
support for the RP07. TOPS-20 V4.1 also supported only the RP06 and
|
||||
RM03. Units can be set ONLINE or OFFLINE.
|
||||
RM03. Units can be set ENABLED or DISABLED.
|
||||
|
||||
The RP controller implements these registers:
|
||||
|
||||
@@ -467,7 +478,7 @@ the ability to make units write enabled or locked.
|
||||
SET TUn LOCKED set unit n write locked
|
||||
SET TUn WRITEENABLED set unit n write enabled
|
||||
|
||||
Units can also be set ONLINE or OFFLINE.
|
||||
Units can also be set ENABLED or DISABLED.
|
||||
|
||||
The magnetic tape controller implements these registers:
|
||||
|
||||
|
||||
@@ -394,7 +394,7 @@ for (i = 0; dibp = dib_tab[i]; i++ ) {
|
||||
UBNXM_FAIL (pa, mode);
|
||||
}
|
||||
|
||||
/* Mapped read and write routines - used by word-oriented Unibus devices */
|
||||
/* Mapped read and write routines - used by standard Unibus devices on Unibus 1 */
|
||||
|
||||
a10 Map_Addr10 (a10 ba, int32 ub)
|
||||
{
|
||||
@@ -407,23 +407,23 @@ pa10 = (ubmap[ub][vpn] + PAG_GETOFF (ba >> 2)) & PAMASK;
|
||||
return pa10;
|
||||
}
|
||||
|
||||
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf, t_bool ub)
|
||||
int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf)
|
||||
{
|
||||
uint32 lim;
|
||||
a10 pa10;
|
||||
|
||||
lim = ba + bc;
|
||||
for ( ; ba < lim; ba++) { /* by bytes */
|
||||
pa10 = Map_Addr10 (ba, ub); /* map addr */
|
||||
pa10 = Map_Addr10 (ba, 1); /* map addr */
|
||||
if ((pa10 < 0) || MEM_ADDR_NXM (pa10)) { /* inv map or NXM? */
|
||||
ubcs[ub] = ubcs[ub] | UBCS_TMO; /* UBA times out */
|
||||
ubcs[1] = ubcs[1] | UBCS_TMO; /* UBA times out */
|
||||
return (lim - ba); } /* return bc */
|
||||
*buf++ = (uint8) ((M[pa10] >> ubashf[ba & 3]) & 0377);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf, t_bool ub)
|
||||
int32 Map_ReadW (uint32 ba, int32 bc, uint16 *buf)
|
||||
{
|
||||
uint32 lim;
|
||||
a10 pa10;
|
||||
@@ -431,16 +431,16 @@ a10 pa10;
|
||||
ba = ba & ~01; /* align start */
|
||||
lim = ba + (bc & ~01);
|
||||
for ( ; ba < lim; ba = ba + 2) { /* by words */
|
||||
pa10 = Map_Addr10 (ba, ub); /* map addr */
|
||||
pa10 = Map_Addr10 (ba, 1); /* map addr */
|
||||
if ((pa10 < 0) || MEM_ADDR_NXM (pa10)) { /* inv map or NXM? */
|
||||
ubcs[ub] = ubcs[ub] | UBCS_TMO; /* UBA times out */
|
||||
ubcs[1] = ubcs[1] | UBCS_TMO; /* UBA times out */
|
||||
return (lim - ba); } /* return bc */
|
||||
*buf++ = (uint16) ((M[pa10] >> ((ba & 2)? 0: 18)) & 0177777);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf, t_bool ub)
|
||||
int32 Map_WriteB (uint32 ba, int32 bc, uint8 *buf)
|
||||
{
|
||||
uint32 lim;
|
||||
a10 pa10;
|
||||
@@ -448,16 +448,16 @@ static d10 mask = 0377;
|
||||
|
||||
lim = ba + bc;
|
||||
for ( ; ba < lim; ba++) { /* by bytes */
|
||||
pa10 = Map_Addr10 (ba, ub); /* map addr */
|
||||
pa10 = Map_Addr10 (ba, 1); /* map addr */
|
||||
if ((pa10 < 0) || MEM_ADDR_NXM (pa10)) { /* inv map or NXM? */
|
||||
ubcs[ub] = ubcs[ub] | UBCS_TMO; /* UBA times out */
|
||||
ubcs[1] = ubcs[1] | UBCS_TMO; /* UBA times out */
|
||||
return (lim - ba); } /* return bc */
|
||||
M[pa10] = (M[pa10] & ~(mask << ubashf[ba & 3])) |
|
||||
(((d10) *buf++) << ubashf[ba & 3]); }
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf, t_bool ub)
|
||||
int32 Map_WriteW (uint32 ba, int32 bc, uint16 *buf)
|
||||
{
|
||||
uint32 lim;
|
||||
a10 pa10;
|
||||
@@ -466,9 +466,9 @@ d10 val;
|
||||
ba = ba & ~01; /* align start */
|
||||
lim = ba + (bc & ~01);
|
||||
for ( ; ba < lim; ba++) { /* by bytes */
|
||||
pa10 = Map_Addr10 (ba, ub); /* map addr */
|
||||
pa10 = Map_Addr10 (ba, 1); /* map addr */
|
||||
if ((pa10 < 0) || MEM_ADDR_NXM (pa10)) { /* inv map or NXM? */
|
||||
ubcs[ub] = ubcs[ub] | UBCS_TMO; /* UBA times out */
|
||||
ubcs[1] = ubcs[1] | UBCS_TMO; /* UBA times out */
|
||||
return (lim - ba); } /* return bc */
|
||||
val = *buf++; /* get data */
|
||||
if (ba & 2) M[pa10] = (M[pa10] & 0777777600000) | val;
|
||||
|
||||
@@ -373,7 +373,7 @@ if ((fnc == FNC_PR) && (dvlnt == 0)) {
|
||||
return SCPE_OK; }
|
||||
|
||||
for (i = 0, cont = TRUE; (i < tbc) && cont; ba++, i++) {
|
||||
if (Map_ReadW (ba, 2, &wd10, MAP)) { /* get word, err? */
|
||||
if (Map_ReadW (ba, 2, &wd10)) { /* get word, err? */
|
||||
lpcsb = lpcsb | CSB_MTE; /* set NXM error */
|
||||
update_lpcs (CSA_ERR); /* set done */
|
||||
break; }
|
||||
|
||||
219
PDP10/pdp10_rp.c
219
PDP10/pdp10_rp.c
@@ -25,6 +25,7 @@
|
||||
|
||||
rp RH/RP/RM moving head disks
|
||||
|
||||
20-Sep-04 RMS Fixed bugs in replicated state, RP vs RM accuracy
|
||||
04-Jan-04 RMS Changed sim_fsize calling sequence
|
||||
23-Jul-03 RMS Fixed bug in read header stub
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
@@ -72,6 +73,8 @@
|
||||
#define RP_MAXFR 32768 /* max transfer */
|
||||
#define GET_SECTOR(x,d) ((int) fmod (sim_gtime() / ((double) (x)), \
|
||||
((double) drv_tab[d].sect)))
|
||||
#define MBA_RP_CTRL 0 /* RP drive */
|
||||
#define MBA_RM_CTRL 1 /* RM drive */
|
||||
|
||||
/* Flags in the unit flags word */
|
||||
|
||||
@@ -255,6 +258,8 @@
|
||||
In theory, each drive can be a different type. The size field in
|
||||
each unit selects the drive capacity for each drive and thus the
|
||||
drive type. DISKS MUST BE DECLARED IN ASCENDING SIZE.
|
||||
|
||||
The RP07, despite its name, uses an RM-style controller.
|
||||
*/
|
||||
|
||||
#define RM03_DTYPE 0
|
||||
@@ -300,20 +305,21 @@
|
||||
#define RP07_SIZE (RP07_SECT * RP07_SURF * RP07_CYL * RP_NUMWD)
|
||||
|
||||
struct drvtyp {
|
||||
int sect; /* sectors */
|
||||
int surf; /* surfaces */
|
||||
int cyl; /* cylinders */
|
||||
int size; /* #blocks */
|
||||
int devtype; /* device type */
|
||||
int32 sect; /* sectors */
|
||||
int32 surf; /* surfaces */
|
||||
int32 cyl; /* cylinders */
|
||||
int32 size; /* #blocks */
|
||||
int32 devtype; /* device type */
|
||||
int32 ctrl; /* ctrl type */
|
||||
};
|
||||
|
||||
struct drvtyp drv_tab[] = {
|
||||
{ RM03_SECT, RM03_SURF, RM03_CYL, RM03_SIZE, RM03_DEV },
|
||||
{ RP04_SECT, RP04_SURF, RP04_CYL, RP04_SIZE, RP04_DEV },
|
||||
{ RM80_SECT, RM80_SURF, RM80_CYL, RM80_SIZE, RM80_DEV },
|
||||
{ RP06_SECT, RP06_SURF, RP06_CYL, RP06_SIZE, RP06_DEV },
|
||||
{ RM05_SECT, RM05_SURF, RM05_CYL, RM05_SIZE, RM05_DEV },
|
||||
{ RP07_SECT, RP07_SURF, RP07_CYL, RP07_SIZE, RP07_DEV },
|
||||
{ RM03_SECT, RM03_SURF, RM03_CYL, RM03_SIZE, RM03_DEV, MBA_RM_CTRL },
|
||||
{ RP04_SECT, RP04_SURF, RP04_CYL, RP04_SIZE, RP04_DEV, MBA_RP_CTRL },
|
||||
{ RM80_SECT, RM80_SURF, RM80_CYL, RM80_SIZE, RM80_DEV, MBA_RM_CTRL },
|
||||
{ RP06_SECT, RP06_SURF, RP06_CYL, RP06_SIZE, RP06_DEV, MBA_RP_CTRL },
|
||||
{ RM05_SECT, RM05_SURF, RM05_CYL, RM05_SIZE, RM05_DEV, MBA_RM_CTRL },
|
||||
{ RP07_SECT, RP07_SURF, RP07_CYL, RP07_SIZE, RP07_DEV, MBA_RM_CTRL },
|
||||
{ 0 } };
|
||||
|
||||
extern d10 *M; /* memory */
|
||||
@@ -326,18 +332,20 @@ extern UNIT cpu_unit;
|
||||
int32 rpcs1 = 0; /* control/status 1 */
|
||||
int32 rpwc = 0; /* word count */
|
||||
int32 rpba = 0; /* bus address */
|
||||
int32 rpda = 0; /* track/sector */
|
||||
int32 rpcs2 = 0; /* control/status 2 */
|
||||
int32 rpds[RP_NUMDR] = { 0 }; /* drive status */
|
||||
int32 rper1[RP_NUMDR] = { 0 }; /* error status 1 */
|
||||
int32 rpdb = 0; /* data buffer */
|
||||
int32 rpmr = 0; /* maint register */
|
||||
int32 rpof = 0; /* offset */
|
||||
int32 rpdc = 0; /* cylinder */
|
||||
int32 rper2 = 0; /* error status 2 */
|
||||
int32 rper3 = 0; /* error status 3 */
|
||||
int32 rpec1 = 0; /* ECC correction 1 */
|
||||
int32 rpec2 = 0; /* ECC correction 2 */
|
||||
uint16 rpda[RP_NUMDR] = { 0 }; /* track/sector */
|
||||
uint16 rpds[RP_NUMDR] = { 0 }; /* drive status */
|
||||
uint16 rper1[RP_NUMDR] = { 0 }; /* error status 1 */
|
||||
uint16 rmhr[RP_NUMDR] = { 0 }; /* holding reg */
|
||||
uint16 rpmr[RP_NUMDR] = { 0 }; /* maint reg */
|
||||
uint16 rmmr2[RP_NUMDR] = { 0 }; /* maint reg 2 */
|
||||
uint16 rpof[RP_NUMDR] = { 0 }; /* offset */
|
||||
uint16 rpdc[RP_NUMDR] = { 0 }; /* cylinder */
|
||||
uint16 rper2[RP_NUMDR] = { 0 }; /* error status 2 */
|
||||
uint16 rper3[RP_NUMDR] = { 0 }; /* error status 3 */
|
||||
uint16 rpec1[RP_NUMDR] = { 0 }; /* ECC correction 1 */
|
||||
uint16 rpec2[RP_NUMDR] = { 0 }; /* ECC correction 2 */
|
||||
int32 rpiff = 0; /* INTR flip/flop */
|
||||
int32 rp_stopioe = 1; /* stop on error */
|
||||
int32 rp_swait = 10; /* seek time */
|
||||
@@ -345,6 +353,7 @@ int32 rp_rwait = 10; /* rotate time */
|
||||
static int32 reg_in_drive[32] = {
|
||||
0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
static char *rp_mapnam[MBA_RM_CTRL + 1] = { "RP", "RM" };
|
||||
|
||||
t_stat rp_rd (int32 *data, int32 PA, int32 access);
|
||||
t_stat rp_wr (int32 data, int32 PA, int32 access);
|
||||
@@ -354,6 +363,7 @@ t_stat rp_reset (DEVICE *dptr);
|
||||
t_stat rp_boot (int32 unitno, DEVICE *dptr);
|
||||
t_stat rp_attach (UNIT *uptr, char *cptr);
|
||||
t_stat rp_detach (UNIT *uptr);
|
||||
void set_rper (int32 flag, int32 drv);
|
||||
void update_rpcs (int32 flags, int32 drv);
|
||||
void rp_go (int32 drv, int32 fnc);
|
||||
t_stat rp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
@@ -391,18 +401,20 @@ REG rp_reg[] = {
|
||||
{ ORDATA (RPCS1, rpcs1, 16) },
|
||||
{ ORDATA (RPWC, rpwc, 16) },
|
||||
{ ORDATA (RPBA, rpba, 16) },
|
||||
{ ORDATA (RPDA, rpda, 16) },
|
||||
{ ORDATA (RPCS2, rpcs2, 16) },
|
||||
{ ORDATA (RPDB, rpdb, 16) },
|
||||
{ BRDATA (RPDA, rpda, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPDS, rpds, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPER1, rper1, 8, 16, RP_NUMDR) },
|
||||
{ ORDATA (RPOF, rpof, 16) },
|
||||
{ ORDATA (RPDC, rpdc, 16) },
|
||||
{ ORDATA (RPER2, rper2, 16) },
|
||||
{ ORDATA (RPER3, rper3, 16) },
|
||||
{ ORDATA (RPEC1, rpec1, 16) },
|
||||
{ ORDATA (RPEC2, rpec2, 16) },
|
||||
{ ORDATA (RPMR, rpmr, 16) },
|
||||
{ ORDATA (RPDB, rpdb, 16) },
|
||||
{ BRDATA (RPHR, rmhr, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPOF, rpof, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPDC, rpdc, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPER2, rper2, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPER3, rper3, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPEC1, rpec1, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RPEC2, rpec2, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RMMR, rpmr, 8, 16, RP_NUMDR) },
|
||||
{ BRDATA (RMMR2, rmmr2, 8, 16, RP_NUMDR) },
|
||||
{ FLDATA (IFF, rpiff, 0) },
|
||||
{ FLDATA (INT, int_req, INT_V_RP) },
|
||||
{ FLDATA (SC, rpcs1, CSR_V_ERR) },
|
||||
@@ -497,7 +509,7 @@ case 002: /* RPBA */
|
||||
*data = rpba = rpba & ~BA_MBZ;
|
||||
break;
|
||||
case 003: /* RPDA */
|
||||
*data = rpda = rpda & ~DA_MBZ;
|
||||
*data = rpda[drv] = rpda[drv] & ~DA_MBZ;
|
||||
break;
|
||||
case 004: /* RPCS2 */
|
||||
*data = rpcs2 = (rpcs2 & ~CS2_MBZ) | CS2_IR | CS2_OR;
|
||||
@@ -520,7 +532,7 @@ case 011: /* RPDB */
|
||||
*data = rpdb;
|
||||
break;
|
||||
case 012: /* RPMR */
|
||||
*data = rpmr;
|
||||
*data = rpmr[drv];
|
||||
break;
|
||||
case 013: /* RPDT */
|
||||
*data = drv_tab[dtype].devtype;
|
||||
@@ -529,28 +541,34 @@ case 014: /* RPSN */
|
||||
*data = 020 | (drv + 1);
|
||||
break;
|
||||
case 015: /* RPOF */
|
||||
*data = rpof = rpof & ~OF_MBZ;
|
||||
*data = rpof[drv] = rpof[drv] & ~OF_MBZ;
|
||||
break;
|
||||
case 016: /* RPDC */
|
||||
*data = rpdc = rpdc & ~DC_MBZ;
|
||||
*data = rpdc[drv] = rpdc[drv] & ~DC_MBZ;
|
||||
break;
|
||||
case 017: /* RPCC, RMHR */
|
||||
*data = rp_unit[drv].CYL;
|
||||
if (drv_tab[dtype].ctrl == MBA_RP_CTRL) /* RP is CC */
|
||||
*data = rp_unit[drv].CYL;
|
||||
else *data = rmhr[drv] ^ 0177777; /* RM is HR */
|
||||
break;
|
||||
case 020: /* RPER2, RMMR2 */
|
||||
*data = rper2;
|
||||
if (drv_tab[dtype].ctrl == MBA_RP_CTRL) /* RP is ER2 */
|
||||
*data = rper2[drv];
|
||||
else *data = rmmr2[drv]; /* RM is MR2 */
|
||||
break;
|
||||
case 021: /* RPER3, RMER2 */
|
||||
*data = rper3;
|
||||
if (drv_tab[dtype].ctrl == MBA_RP_CTRL) /* RP is ER3 */
|
||||
*data = rper3[drv];
|
||||
else *data = rper2[drv]; /* RM is ER2 */
|
||||
break;
|
||||
case 022: /* RPEC1 */
|
||||
*data = rpec1;
|
||||
*data = rpec1[drv];
|
||||
break;
|
||||
case 023: /* RPEC2 */
|
||||
*data = rpec2;
|
||||
*data = rpec2[drv];
|
||||
break;
|
||||
default: /* all others */
|
||||
rper1[drv] = rper1[drv] | ER1_ILR;
|
||||
set_rper (ER1_ILR, drv);
|
||||
update_rpcs (0, drv);
|
||||
break; }
|
||||
return SCPE_OK;
|
||||
@@ -558,11 +576,12 @@ return SCPE_OK;
|
||||
|
||||
t_stat rp_wr (int32 data, int32 PA, int32 access)
|
||||
{
|
||||
int32 cs1f, drv, i, j;
|
||||
int32 cs1f, drv, dtype, i, j;
|
||||
UNIT *uptr;
|
||||
|
||||
cs1f = 0; /* no int on cs1 upd */
|
||||
drv = GET_UNIT (rpcs2); /* get current unit */
|
||||
dtype = GET_DTYPE (rp_unit[drv].flags); /* get drive type */
|
||||
uptr = rp_dev.units + drv; /* get unit */
|
||||
j = (PA >> 1) & 037; /* get reg offset */
|
||||
if (reg_in_drive[j] && (rp_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
||||
@@ -570,9 +589,10 @@ if (reg_in_drive[j] && (rp_unit[drv].flags & UNIT_DIS)) { /* nx disk */
|
||||
update_rpcs (CS1_SC, drv); /* request intr */
|
||||
return SCPE_OK; }
|
||||
if (reg_in_drive[j] && sim_is_active (&rp_unit[drv])) { /* unit busy? */
|
||||
rper1[drv] = rper1[drv] | ER1_RMR; /* won't write */
|
||||
set_rper (ER1_RMR, drv); /* won't write */
|
||||
update_rpcs (0, drv);
|
||||
return SCPE_OK; }
|
||||
rmhr[drv] = data;
|
||||
|
||||
switch (j) { /* decode PA<5:1> */
|
||||
case 000: /* RPCS1 */
|
||||
@@ -591,7 +611,7 @@ case 000: /* RPCS1 */
|
||||
rpcs2 = rpcs2 | CS2_NED; /* set error flag */
|
||||
cs1f = CS1_SC; } /* req interrupt */
|
||||
else if (sim_is_active (uptr))
|
||||
rper1[drv] = rper1[drv] | ER1_RMR; /* won't write */
|
||||
set_rper (ER1_RMR, drv); /* won't write */
|
||||
else if (data & CS1_GO) { /* start op */
|
||||
uptr->FUNC = GET_FNC (data); /* set func */
|
||||
if ((uptr->FUNC >= FNC_XFER) && /* data xfer and */
|
||||
@@ -610,9 +630,8 @@ case 002: /* RPBA */
|
||||
rpba = data & ~BA_MBZ;
|
||||
break;
|
||||
case 003: /* RPDA */
|
||||
if (access == WRITEB) data = (PA & 1)?
|
||||
(rpda & 0377) | (data << 8): (rpda & ~0377) | data;
|
||||
rpda = data & ~DA_MBZ;
|
||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||
rpda[drv] = data & ~DA_MBZ;
|
||||
break;
|
||||
case 004: /* RPCS2 */
|
||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||
@@ -626,8 +645,8 @@ case 004: /* RPCS2 */
|
||||
drv = GET_UNIT (rpcs2);
|
||||
break;
|
||||
case 006: /* RPER1 */
|
||||
if (access == WRITEB) break;
|
||||
rper1[drv] = rper1[drv] & data;
|
||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||
rper1[drv] = data;
|
||||
break;
|
||||
case 007: /* RPAS */
|
||||
if ((access == WRITEB) && (PA & 1)) break;
|
||||
@@ -640,32 +659,28 @@ case 011: /* RPDB */
|
||||
rpdb = data;
|
||||
break;
|
||||
case 012: /* RPMR */
|
||||
if (access == WRITEB) data = (PA & 1)?
|
||||
(rpmr & 0377) | (data << 8): (rpmr & ~0377) | data;
|
||||
rpmr = data;
|
||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||
rpmr[drv] = data;
|
||||
break;
|
||||
case 015: /* RPOF */
|
||||
if (access == WRITEB) data = (PA & 1)?
|
||||
(rpof & 0377) | (data << 8): (rpof & ~0377) | data;
|
||||
rpof = data & ~OF_MBZ;
|
||||
rpof[drv] = data & ~OF_MBZ;
|
||||
break;
|
||||
case 016: /* RPDC */
|
||||
if (access == WRITEB) data = (PA & 1)?
|
||||
(rpdc & 0377) | (data << 8): (rpdc & ~0377) | data;
|
||||
rpdc = data & ~DC_MBZ;
|
||||
if ((access == WRITEB) && (PA & 1)) data = data << 8;
|
||||
rpdc[drv] = data & ~DC_MBZ;
|
||||
break;
|
||||
case 005: /* RPDS */
|
||||
case 010: /* RPLA */
|
||||
case 013: /* RPDT */
|
||||
case 014: /* RPSN */
|
||||
case 017: /* RPDC, RMHR */
|
||||
case 020: /* RPER2, RMMN2 */
|
||||
case 017: /* RPCC, RMHR */
|
||||
case 020: /* RPER2, RMMR2 */
|
||||
case 021: /* RPER3, RMER2 */
|
||||
case 022: /* RPEC1 */
|
||||
case 023: /* RPEC2 */
|
||||
break; /* read only */
|
||||
default: /* all others */
|
||||
rper1[drv] = rper1[drv] | ER1_ILR;
|
||||
set_rper (ER1_ILR, drv);
|
||||
break; } /* end switch */
|
||||
update_rpcs (cs1f, drv); /* update status */
|
||||
return SCPE_OK;
|
||||
@@ -684,26 +699,25 @@ if (uptr->flags & UNIT_DIS) { /* nx unit? */
|
||||
update_rpcs (CS1_SC, drv); /* request intr */
|
||||
return; }
|
||||
if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */
|
||||
rper1[drv] = rper1[drv] | ER1_ILF; /* not allowed */
|
||||
rpds[drv] = rpds[drv] | DS_ATA; /* set attention */
|
||||
set_rper (ER1_ILF, drv); /* set err, ATN */
|
||||
update_rpcs (CS1_SC, drv); /* request intr */
|
||||
return; }
|
||||
dtype = GET_DTYPE (uptr->flags); /* get drive type */
|
||||
rpds[drv] = rpds[drv] & ~DS_ATA; /* clear attention */
|
||||
dc = rpdc; /* assume seek, sch */
|
||||
dc = rpdc[drv]; /* assume seek, sch */
|
||||
|
||||
switch (fnc) { /* case on function */
|
||||
case FNC_DCLR: /* drive clear */
|
||||
rpda = 0; /* clear disk addr */
|
||||
rper1[drv] = rper2 = rper3 = 0; /* clear errors */
|
||||
rpda[drv] = 0; /* clear disk addr */
|
||||
rper1[drv] = rper2[drv] = rper3[drv] = 0; /* clear errors */
|
||||
case FNC_NOP: /* no operation */
|
||||
case FNC_RELEASE: /* port release */
|
||||
return;
|
||||
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
rpdc = 0; /* clear disk addr */
|
||||
rpda = 0;
|
||||
rpof = 0; /* clear offset */
|
||||
rpdc[drv] = 0; /* clear disk addr */
|
||||
rpda[drv] = 0;
|
||||
rpof[drv] = 0; /* clear offset */
|
||||
case FNC_PACK: /* pack acknowledge */
|
||||
rpds[drv] = rpds[drv] | DS_VV; /* set volume valid */
|
||||
return;
|
||||
@@ -711,7 +725,7 @@ case FNC_PACK: /* pack acknowledge */
|
||||
case FNC_OFFSET: /* offset mode */
|
||||
case FNC_RETURN:
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||
set_rper (ER1_UNS, drv); /* unsafe */
|
||||
break; }
|
||||
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
||||
sim_activate (uptr, rp_swait); /* time operation */
|
||||
@@ -723,12 +737,12 @@ case FNC_RECAL: /* recalibrate */
|
||||
case FNC_SEEK: /* seek */
|
||||
case FNC_SEARCH: /* search */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||
set_rper (ER1_UNS, drv); /* unsafe */
|
||||
break; }
|
||||
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
||||
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||
rper1[drv] = rper1[drv] | ER1_IAE;
|
||||
(GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
|
||||
(GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||
set_rper (ER1_IAE, drv);
|
||||
break; }
|
||||
rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */
|
||||
t = abs (dc - uptr->CYL); /* cyl diff */
|
||||
@@ -743,14 +757,14 @@ case FNC_WCHK: /* write check */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read headers */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
rper1[drv] = rper1[drv] | ER1_UNS; /* unsafe */
|
||||
set_rper (ER1_UNS, drv); /* unsafe */
|
||||
break; }
|
||||
rpcs2 = rpcs2 & ~CS2_ERR; /* clear errors */
|
||||
rpcs1 = rpcs1 & ~(CS1_TRE | CS1_MCPE | CS1_DONE);
|
||||
if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */
|
||||
(GET_SF (rpda) >= drv_tab[dtype].surf) || /* bad surface */
|
||||
(GET_SC (rpda) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||
rper1[drv] = rper1[drv] | ER1_IAE;
|
||||
(GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
|
||||
(GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
|
||||
set_rper (ER1_IAE, drv);
|
||||
break; }
|
||||
rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */
|
||||
sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr->CYL)));
|
||||
@@ -758,9 +772,8 @@ case FNC_READH: /* read headers */
|
||||
return;
|
||||
|
||||
default: /* all others */
|
||||
rper1[drv] = rper1[drv] | ER1_ILF; /* not supported */
|
||||
set_rper (ER1_ILF, drv); /* not supported */
|
||||
break; }
|
||||
rpds[drv] = rpds[drv] | DS_ATA; /* error, set attn */
|
||||
update_rpcs (CS1_SC, drv); /* req intr */
|
||||
return;
|
||||
}
|
||||
@@ -815,7 +828,7 @@ case FNC_SEEK: /* seek */
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
if (uptr->flags & UNIT_WPRT) { /* write locked? */
|
||||
rper1[drv] = rper1[drv] | ER1_WLE; /* set drive error */
|
||||
set_rper (ER1_WLE, drv); /* set drive error */
|
||||
update_rpcs (CS1_DONE | CS1_TRE, drv); /* set done, err */
|
||||
break; }
|
||||
case FNC_WCHK: /* write check */
|
||||
@@ -823,9 +836,9 @@ case FNC_READ: /* read */
|
||||
case FNC_READH: /* read headers */
|
||||
ba = GET_UAE (rpcs1) | rpba; /* get byte addr */
|
||||
wc10 = (0200000 - rpwc) >> 1; /* get PDP-10 wc */
|
||||
da = GET_DA (rpdc, rpda, dtype) * RP_NUMWD; /* get disk addr */
|
||||
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD; /* get disk addr */
|
||||
if ((da + wc10) > drv_tab[dtype].size) { /* disk overrun? */
|
||||
rper1[drv] = rper1[drv] | ER1_AOE;
|
||||
set_rper (ER1_AOE, drv);
|
||||
if (wc10 > (drv_tab[dtype].size - da))
|
||||
wc10 = drv_tab[dtype].size - da; }
|
||||
|
||||
@@ -884,13 +897,13 @@ case FNC_READH: /* read headers */
|
||||
da = da + twc10 + (RP_NUMWD - 1);
|
||||
if (da >= drv_tab[dtype].size) rpds[drv] = rpds[drv] | DS_LST;
|
||||
da = da / RP_NUMWD;
|
||||
rpda = da % drv_tab[dtype].sect;
|
||||
rpda[drv] = da % drv_tab[dtype].sect;
|
||||
da = da / drv_tab[dtype].sect;
|
||||
rpda = rpda | ((da % drv_tab[dtype].surf) << DA_V_SF);
|
||||
rpdc = da / drv_tab[dtype].surf;
|
||||
rpda[drv] = rpda[drv] | ((da % drv_tab[dtype].surf) << DA_V_SF);
|
||||
rpdc[drv] = da / drv_tab[dtype].surf;
|
||||
|
||||
if (err != 0) { /* error? */
|
||||
rper1[drv] = rper1[drv] | ER1_PAR; /* set drive error */
|
||||
set_rper (ER1_PAR, drv); /* set drive error */
|
||||
update_rpcs (CS1_DONE | CS1_TRE, drv); /* set done, err */
|
||||
perror ("RP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
@@ -901,6 +914,16 @@ case FNC_WRITEH: /* write headers stub */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Set drive error */
|
||||
|
||||
void set_rper (int32 flag, int32 drv)
|
||||
{
|
||||
rper1[drv] = rper1[drv] | flag;
|
||||
rpds[drv] = rpds[drv] | DS_ATA;
|
||||
rpcs1 = rpcs1 | CS1_SC;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Controller status update
|
||||
|
||||
Check for done transition
|
||||
@@ -921,7 +944,8 @@ if (rp_unit[drv].flags & UNIT_DIS) rpds[drv] = rper1[drv] = 0;
|
||||
else rpds[drv] = (rpds[drv] | DS_DPR) & ~DS_PGM;
|
||||
if (rp_unit[drv].flags & UNIT_ATT) rpds[drv] = rpds[drv] | DS_MOL;
|
||||
else rpds[drv] = rpds[drv] & ~(DS_MOL | DS_VV | DS_RDY);
|
||||
if (rper1[drv] | rper2 | rper3) rpds[drv] = rpds[drv] | DS_ERR | DS_ATA;
|
||||
if (rper1[drv] | rper2[drv] | rper3[drv])
|
||||
rpds[drv] = rpds[drv] | DS_ERR;
|
||||
else rpds[drv] = rpds[drv] & ~DS_ERR;
|
||||
|
||||
rpcs1 = (rpcs1 & ~(CS1_SC | CS1_MCPE | CS1_MBZ | CS1_DRV)) | CS1_DVA | flag;
|
||||
@@ -955,10 +979,7 @@ UNIT *uptr;
|
||||
|
||||
rpcs1 = CS1_DVA | CS1_DONE;
|
||||
rpcs2 = CS2_IR | CS2_OR;
|
||||
rpba = rpda = 0;
|
||||
rpof = rpdc = 0;
|
||||
rper2 = rper3 = 0;
|
||||
rpec1 = rpec2 = 0;
|
||||
rpba = rpwc = 0;
|
||||
rpiff = 0; /* clear CSTB INTR */
|
||||
int_req = int_req & ~INT_RP; /* clear intr req */
|
||||
for (i = 0; i < RP_NUMDR; i++) {
|
||||
@@ -969,7 +990,17 @@ for (i = 0; i < RP_NUMDR; i++) {
|
||||
DS_DPR | DS_RDY | DS_MOL | ((uptr->flags & UNIT_WPRT)? DS_WRL: 0);
|
||||
else if (uptr->flags & UNIT_DIS) rpds[i] = 0;
|
||||
else rpds[i] = DS_DPR;
|
||||
rper1[i] = 0; }
|
||||
rper1[i] = 0;
|
||||
rper2[i] = 0;
|
||||
rper3[i] = 0;
|
||||
rpda[i] = 0;
|
||||
rpdc[i] = 0;
|
||||
rpmr[i] = 0;
|
||||
rpof[i] = 0;
|
||||
rpec1[i] = 0;
|
||||
rpec2[i] = 0;
|
||||
rmmr2[i] = 0;
|
||||
rmhr[i] = 0; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1021,8 +1052,10 @@ return detach_unit (uptr);
|
||||
|
||||
t_stat rp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc)
|
||||
{
|
||||
int32 dtype = GET_DTYPE (val);
|
||||
|
||||
if (uptr->flags & UNIT_ATT) return SCPE_ALATT;
|
||||
uptr->capac = drv_tab[GET_DTYPE (val)].size;
|
||||
uptr->capac = drv_tab[dtype].size;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
136
PDP10/pdp10_tu.c
136
PDP10/pdp10_tu.c
@@ -25,6 +25,12 @@
|
||||
|
||||
tu RH11/TM03/TU45 magtape
|
||||
|
||||
23-Oct-04 RMS Fixed setting done on non data transfers
|
||||
01-Oct-04 RMS Modified to set FCE on read short record, eof
|
||||
Implemented write check
|
||||
TM03 uses only den<2> for validity test
|
||||
TMK is cleared by new motion command, not DCLR
|
||||
14-Sep-04 RMS Fixed RIP value
|
||||
25-Apr-03 RMS Revised for extended file support
|
||||
28-Mar-03 RMS Added multiformat support
|
||||
28-Feb-03 RMS Revised for magtape library
|
||||
@@ -85,13 +91,14 @@
|
||||
#define USTAT u3 /* unit status */
|
||||
#define UDENS u4 /* unit density */
|
||||
#define UD_UNK 0 /* unknown */
|
||||
#define MT_MAXFR (1 << 16) /* max data buf */
|
||||
#define MT_MAXFR (1 << 16) /* max data buf */
|
||||
|
||||
/* MTCS1 - 172440 - control/status 1 */
|
||||
|
||||
#define CS1_GO CSR_GO /* go */
|
||||
#define CS1_V_FNC 1 /* function pos */
|
||||
#define CS1_M_FNC 037 /* function mask */
|
||||
#define CS1_N_FNC (CS1_M_FNC + 1)
|
||||
#define CS1_FNC (CS1_M_FNC << CS1_V_FNC)
|
||||
#define FNC_NOP 000 /* no operation */
|
||||
#define FNC_UNLOAD 001 /* unload */
|
||||
@@ -146,7 +153,7 @@
|
||||
#define CS2_NEM 0004000 /* nx mem err */
|
||||
#define CS2_NEF 0010000 /* nx fmter err */
|
||||
#define CS2_PE 0020000 /* parity err NI */
|
||||
#define CS2_WCE 0040000 /* write chk err NI */
|
||||
#define CS2_WCE 0040000 /* write chk err */
|
||||
#define CS2_DLT 0100000 /* data late NI */
|
||||
#define CS2_MBZ (CS2_CLR | CS2_WCE)
|
||||
#define CS2_RW (CS2_FMTR | CS2_UAI | CS2_PAT | CS2_MXF | CS2_PE)
|
||||
@@ -214,6 +221,7 @@
|
||||
|
||||
/* MTDT - 172466 - drive type */
|
||||
|
||||
#define DT_NSA 0100000 /* not sect addr */
|
||||
#define DT_TAPE 0040000 /* tape */
|
||||
#define DT_PRES 0002000 /* slave present */
|
||||
#define DT_TM03 0000040 /* TM03 formatter */
|
||||
@@ -243,6 +251,7 @@
|
||||
#define TC_ACC 0100000 /* accelerating NI */
|
||||
#define TC_RW 0013777
|
||||
#define TC_MBZ 0004000
|
||||
#define TC_RIP ((TC_800 << TC_V_DEN) || (TC_10C << TC_V_FMT))
|
||||
#define GET_DEN(x) (((x) >> TC_V_DEN) & TC_M_DEN)
|
||||
#define GET_FMT(x) (((x) >> TC_V_FMT) & TC_M_FMT)
|
||||
#define GET_DRV(x) (((x) >> TC_V_UNIT) & TC_M_UNIT)
|
||||
@@ -280,6 +289,8 @@ extern int32 int_vec[32];
|
||||
extern int32 ubmap[UBANUM][UMAP_MEMSIZE]; /* Unibus map */
|
||||
extern int32 ubcs[UBANUM];
|
||||
extern UNIT cpu_unit;
|
||||
extern int32 sim_switches;
|
||||
extern FILE *sim_deb;
|
||||
|
||||
int32 tucs1 = 0; /* control/status 1 */
|
||||
int32 tuwc = 0; /* word count */
|
||||
@@ -304,8 +315,11 @@ int32 reg_in_fmtr1[32] = { /* rmr if write + go */
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
|
||||
int32 fmt_test[16] = { /* fmt bytes/10 wd */
|
||||
5, 0, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int32 den_test[8] = { /* valid densities */
|
||||
0, 0, 0, 1, 1, 0, 0, 0 };
|
||||
static char *tu_fname[CS1_N_FNC] = {
|
||||
"NOP", "UNLD", "2", "REW", "FCLR", "5", "6", "7",
|
||||
"RIP", "11", "ERASE", "WREOF", "SPCF", "SPCR", "16", "17",
|
||||
"20", "21", "22", "23", "WRCHKF", "25", "26", "WRCHKR",
|
||||
"WRITE", "31", "32", "33", "READF", "35", "36" "READR" };
|
||||
static uint8 *xbuf = NULL; /* xfer buffer */
|
||||
|
||||
t_stat tu_rd (int32 *data, int32 PA, int32 access);
|
||||
@@ -317,6 +331,7 @@ t_stat tu_attach (UNIT *uptr, char *cptr);
|
||||
t_stat tu_detach (UNIT *uptr);
|
||||
t_stat tu_boot (int32 unitno, DEVICE *dptr);
|
||||
void tu_go (int32 drv);
|
||||
void set_tuer (int32 flag);
|
||||
void update_tucs (int32 flag, int32 drv);
|
||||
t_stat tu_map_err (UNIT *uptr, t_stat st);
|
||||
|
||||
@@ -381,7 +396,7 @@ DEVICE tu_dev = {
|
||||
TU_NUMDR, 10, 31, 1, 8, 8,
|
||||
NULL, NULL, &tu_reset,
|
||||
&tu_boot, &tu_attach, &tu_detach,
|
||||
&tu_dib, DEV_UBUS };
|
||||
&tu_dib, DEV_UBUS | DEV_DEBUG };
|
||||
|
||||
/* I/O dispatch routine, I/O addresses 17772440 - 17772472 */
|
||||
|
||||
@@ -435,8 +450,8 @@ case 012: /* MTMR */
|
||||
*data = tumr;
|
||||
break;
|
||||
case 013: /* MTDT */
|
||||
*data = DT_TAPE | DT_TM03 | ((tu_unit[drv].flags & UNIT_DIS)?
|
||||
DT_OFF: (DT_PRES | DT_TU45));
|
||||
*data = DT_NSA | DT_TAPE | DT_TM03 |
|
||||
((tu_unit[drv].flags & UNIT_DIS)? DT_OFF: (DT_PRES | DT_TU45));
|
||||
break;
|
||||
case 014: /* MTSN */
|
||||
*data = (tu_unit[drv].flags & UNIT_DIS)? 0: 040 | (drv + 1);
|
||||
@@ -445,7 +460,7 @@ case 015: /* MTTC */
|
||||
*data = tutc = tutc & ~TC_MBZ;
|
||||
break;
|
||||
default: /* all others */
|
||||
tuer = tuer | ER_ILR;
|
||||
set_tuer (ER_ILR);
|
||||
update_tucs (0, drv);
|
||||
break; }
|
||||
return SCPE_OK;
|
||||
@@ -464,7 +479,7 @@ if (reg_in_fmtr[j] && (fmtr != 0)) { /* nx formatter */
|
||||
update_tucs (CS1_SC, drv); /* request intr */
|
||||
return SCPE_OK; }
|
||||
if (reg_in_fmtr1[j] && ((tucs1 & CS1_DONE) == 0)) { /* formatter busy? */
|
||||
tuer = tuer | ER_RMR; /* won't write */
|
||||
set_tuer (ER_RMR); /* won't write */
|
||||
update_tucs (0, drv);
|
||||
return SCPE_OK; }
|
||||
|
||||
@@ -485,7 +500,7 @@ case 000: /* MTCS1 */
|
||||
tucs2 = tucs2 | CS2_NEF; /* set error flag */
|
||||
cs1f = CS1_SC; } /* req interrupt */
|
||||
else if (tucs1 & CS1_GO) { /* busy? */
|
||||
if (tucs1 & CS1_DONE) tuer = tuer | ER_RMR;
|
||||
if (tucs1 & CS1_DONE) set_tuer (ER_RMR);
|
||||
else tucs2 = tucs2 | CS2_PGE; }
|
||||
else {
|
||||
tucs1 = (tucs1 & ~CS1_DRV) | (data & CS1_DRV);
|
||||
@@ -544,7 +559,7 @@ case 013: /* MTDT */
|
||||
case 014: /* MTSN */
|
||||
break; /* read only */
|
||||
default: /* all others */
|
||||
tuer = tuer | ER_ILR;
|
||||
set_tuer (ER_ILR);
|
||||
break; } /* end switch */
|
||||
update_tucs (cs1f, drv); /* update status */
|
||||
return SCPE_OK;
|
||||
@@ -560,10 +575,12 @@ UNIT *uptr;
|
||||
fnc = GET_FNC (tucs1); /* get function */
|
||||
den = GET_DEN (tutc); /* get density */
|
||||
uptr = tu_dev.units + drv; /* get unit */
|
||||
if (DEBUG_PRS (tu_dev)) fprintf (sim_deb,
|
||||
">>TU%d STRT: fnc=%s, cs1=%06o, cs2=%06o, ba=%06o, wc=%06o, fc=%06o, fs=%06o, er=%06o, pos=%d\n",
|
||||
drv, tu_fname[fnc], tucs1, tucs2, tuba, tuwc, tufc, tufs, tuer, uptr->pos);
|
||||
if ((fnc != FNC_FCLR) && /* not clear & err */
|
||||
((tufs & FS_ERR) || sim_is_active (uptr))) { /* or in motion? */
|
||||
tuer = tuer | ER_ILF; /* set error flag */
|
||||
tufs = tufs | FS_ATA; /* exception */
|
||||
set_tuer (ER_ILF); /* set err, ATN */
|
||||
tucs1 = tucs1 & ~CS1_GO; /* clear go */
|
||||
update_tucs (CS1_SC, drv); /* request intr */
|
||||
return; }
|
||||
@@ -574,45 +591,48 @@ switch (fnc) { /* case on function */
|
||||
case FNC_FCLR: /* drive clear */
|
||||
tuer = 0; /* clear errors */
|
||||
tutc = tutc & ~TC_FCS; /* clear fc status */
|
||||
tufs = tufs & ~(FS_SAT | FS_SSC | FS_ID | FS_TMK | FS_ERR);
|
||||
tufs = tufs & ~(FS_SAT | FS_SSC | FS_ID | FS_ERR);
|
||||
sim_cancel (uptr); /* reset drive */
|
||||
uptr->USTAT = 0;
|
||||
case FNC_NOP:
|
||||
tucs1 = tucs1 & ~CS1_GO; /* no operation */
|
||||
return;
|
||||
case FNC_RIP: /* read-in preset */
|
||||
tutc = TC_800; /* density = 800 */
|
||||
tutc = TC_RIP; /* density = 800 */
|
||||
sim_tape_rewind (&tu_unit[0]); /* rewind unit 0 */
|
||||
tu_unit[0].USTAT = 0;
|
||||
tucs1 = tucs1 & ~CS1_GO;
|
||||
tufs = tufs & ~FS_TMK;
|
||||
return;
|
||||
|
||||
case FNC_UNLOAD: /* unload */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
tuer = tuer | ER_UNS;
|
||||
set_tuer (ER_UNS);
|
||||
break; }
|
||||
detach_unit (uptr);
|
||||
uptr->USTAT = FS_REW;
|
||||
sim_activate (uptr, tu_time);
|
||||
tucs1 = tucs1 & ~CS1_GO;
|
||||
tufs = tufs & ~FS_TMK;
|
||||
return;
|
||||
case FNC_REWIND:
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
tuer = tuer | ER_UNS;
|
||||
set_tuer (ER_UNS);
|
||||
break; }
|
||||
uptr->USTAT = FS_PIP | FS_REW;
|
||||
sim_activate (uptr, tu_time);
|
||||
tucs1 = tucs1 & ~CS1_GO;
|
||||
tufs = tufs & ~FS_TMK;
|
||||
return;
|
||||
|
||||
case FNC_SPACEF:
|
||||
space_test = FS_EOT;
|
||||
case FNC_SPACER:
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
tuer = tuer | ER_UNS;
|
||||
set_tuer (ER_UNS);
|
||||
break; }
|
||||
if ((tufs & space_test) || ((tutc & TC_FCS) == 0)) {
|
||||
tuer = tuer | ER_NXF;
|
||||
set_tuer (ER_NXF);
|
||||
break; }
|
||||
uptr->USTAT = FS_PIP;
|
||||
goto GO_XFER;
|
||||
@@ -620,36 +640,30 @@ case FNC_SPACER:
|
||||
case FNC_WCHKR: /* wchk = read */
|
||||
case FNC_READR: /* read rev */
|
||||
if (tufs & FS_BOT) { /* beginning of tape? */
|
||||
tuer = tuer | ER_NXF;
|
||||
set_tuer (ER_NXF);
|
||||
break; }
|
||||
goto DATA_XFER;
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
if (((tutc & TC_FCS) == 0) || /* frame cnt = 0? */
|
||||
((den == TC_800) && (tufc > 0777765))) { /* NRZI, fc < 13? */
|
||||
tuer = tuer | ER_NXF;
|
||||
set_tuer (ER_NXF);
|
||||
break; }
|
||||
case FNC_WREOF: /* write tape mark */
|
||||
case FNC_ERASE: /* erase */
|
||||
if (sim_tape_wrp (uptr)) { /* write locked? */
|
||||
tuer = tuer | ER_NXF;
|
||||
set_tuer (ER_NXF);
|
||||
break; }
|
||||
case FNC_WCHKF: /* wchk = read */
|
||||
case FNC_READF: /* read */
|
||||
DATA_XFER:
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* unattached? */
|
||||
tuer = tuer | ER_UNS;
|
||||
set_tuer (ER_UNS);
|
||||
break; }
|
||||
if (fmt_test[GET_FMT (tutc)] == 0) { /* invalid format? */
|
||||
tuer = tuer | ER_FER;
|
||||
break; }
|
||||
if (den_test[den] == 0) { /* invalid density? */
|
||||
tuer = tuer | ER_NXF;
|
||||
set_tuer (ER_FER);
|
||||
break; }
|
||||
if (uptr->UDENS == UD_UNK) uptr->UDENS = den; /* set dens */
|
||||
/* else if (uptr->UDENS != den) { /* density mismatch? */
|
||||
/* tuer = tuer | ER_NXF;
|
||||
/* break; } */
|
||||
uptr->USTAT = 0;
|
||||
tucs1 = tucs1 & ~CS1_DONE; /* clear done */
|
||||
GO_XFER:
|
||||
@@ -660,10 +674,9 @@ GO_XFER:
|
||||
return;
|
||||
|
||||
default: /* all others */
|
||||
tuer = tuer | ER_ILF; /* not supported */
|
||||
set_tuer (ER_ILF); /* not supported */
|
||||
break; } /* end case function */
|
||||
tucs1 = tucs1 & ~CS1_GO; /* clear go */
|
||||
tufs = tufs | FS_ATA; /* set attn */
|
||||
update_tucs (CS1_SC, drv); /* set intr */
|
||||
return;
|
||||
}
|
||||
@@ -677,7 +690,7 @@ return;
|
||||
|
||||
t_stat tu_svc (UNIT *uptr)
|
||||
{
|
||||
int32 f, fmt, i, j, k, wc10, ba10;
|
||||
int32 fnc, fmt, i, j, k, wc10, ba10;
|
||||
int32 ba, fc, wc, drv, mpa10, vpn;
|
||||
d10 val, v[4];
|
||||
t_mtrlnt tbc;
|
||||
@@ -691,7 +704,7 @@ if (uptr->USTAT & FS_REW) { /* rewind or unload? */
|
||||
update_tucs (CS1_SC, drv); /* update status */
|
||||
return SCPE_OK; }
|
||||
|
||||
f = GET_FNC (tucs1); /* get command */
|
||||
fnc = GET_FNC (tucs1); /* get command */
|
||||
fmt = GET_FMT (tutc); /* get format */
|
||||
ba = GET_UAE (tucs1) | tuba; /* get bus address */
|
||||
wc = 0200000 - tuwc; /* get word count */
|
||||
@@ -700,7 +713,7 @@ wc10 = wc >> 1; /* 10 word count */
|
||||
ba10 = ba >> 2; /* 10 word addr */
|
||||
uptr->USTAT = 0; /* clear status */
|
||||
|
||||
switch (f) { /* case on function */
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
/* Unit service - non-data transfer commands - set ATA when done */
|
||||
|
||||
@@ -712,7 +725,7 @@ case FNC_SPACEF: /* space forward */
|
||||
break; }
|
||||
}
|
||||
while (tufc != 0);
|
||||
if (tufc) tuer = tuer | ER_FCE;
|
||||
if (tufc) set_tuer (ER_FCE);
|
||||
else tutc = tutc & ~TC_FCS;
|
||||
tufs = tufs | FS_ATA;
|
||||
break;
|
||||
@@ -725,7 +738,7 @@ case FNC_SPACER: /* space reverse */
|
||||
break; }
|
||||
}
|
||||
while (tufc != 0);
|
||||
if (tufc) tuer = tuer | ER_FCE;
|
||||
if (tufc) set_tuer (ER_FCE);
|
||||
else tutc = tutc & ~TC_FCS;
|
||||
tufs = tufs | FS_ATA;
|
||||
break;
|
||||
@@ -770,11 +783,15 @@ case FNC_WCHKF: /* wcheck = read */
|
||||
for (k = 0; k < 4; k++) v[k] = xbuf[j++];
|
||||
val = (v[0] << 28) | (v[1] << 20) | (v[2] << 12) | (v[3] << 4);
|
||||
if (fmt == TC_10C) val = val | ((d10) xbuf[j++] & 017);
|
||||
if (f == FNC_READF) M[mpa10] = val;
|
||||
if (fnc == FNC_READF) M[mpa10] = val; /* read? store */
|
||||
else if (M[mpa10] != val) { /* wchk, mismatch? */
|
||||
tucs2 = tucs2 | CS2_WCE; /* flag, stop */
|
||||
break; }
|
||||
mpa10 = mpa10 + 1; } /* end for */
|
||||
tufc = tbc & 0177777;
|
||||
tuwc = (tuwc + (i << 1)) & 0177777;
|
||||
ba = ba + (i << 2);
|
||||
if (tuwc) set_tuer (ER_FCE); /* short record? */
|
||||
break;
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
@@ -813,20 +830,38 @@ case FNC_WCHKR: /* wcheck = read */
|
||||
val = ((fmt == TC_10C)? (((d10) xbuf [--j]) & 017): 0);
|
||||
for (k = 0; k < 4; i++) v[k] = xbuf[--j];
|
||||
val = val | (v[0] << 4) | (v[1] << 12) | (v[2] << 20) | (v[3] << 28);
|
||||
if (f == FNC_READR) M[mpa10] = val;
|
||||
if (fnc == FNC_READR) M[mpa10] = val; /* read? store */
|
||||
else if (M[mpa10] != val) { /* wchk, mismatch? */
|
||||
tucs2 = tucs2 | CS2_WCE; /* flag, stop */
|
||||
break; }
|
||||
mpa10 = mpa10 - 1; } /* end for */
|
||||
tufc = tbc & 0177777;
|
||||
tuwc = (tuwc + (i << 1)) & 0177777;
|
||||
ba = ba - (i << 2);
|
||||
if (tuwc) set_tuer (ER_FCE); /* short record? */
|
||||
break; } /* end case */
|
||||
|
||||
tucs1 = (tucs1 & ~CS1_UAE) | ((ba >> (16 - CS1_V_UAE)) & CS1_UAE);
|
||||
tuba = ba & 0177777; /* update mem addr */
|
||||
tucs1 = tucs1 & ~CS1_GO; /* clear go */
|
||||
update_tucs (CS1_DONE, drv);
|
||||
if (fnc >= FNC_XFER) update_tucs (CS1_DONE, drv); /* data xfer? */
|
||||
else update_tucs (CS1_SC, drv); /* no, set attn */
|
||||
if (DEBUG_PRS (tu_dev)) fprintf (sim_deb,
|
||||
">>TU%d DONE: fnc=%s, cs1=%06o, cs2=%06o, ba=%06o, wc=%06o, fc=%06o, fs=%06o, er=%06o, pos=%d\n",
|
||||
drv, tu_fname[fnc], tucs1, tucs2, tuba, tuwc, tufc, tufs, tuer, uptr->pos);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Formatter error */
|
||||
|
||||
void set_tuer (int32 flag)
|
||||
{
|
||||
tuer = tuer | flag;
|
||||
tufs = tufs | FS_ATA;
|
||||
tucs1 = tucs1 | CS1_SC;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Controller status update
|
||||
|
||||
Check for done transition
|
||||
@@ -877,29 +912,30 @@ t_stat tu_map_err (UNIT *uptr, t_stat st)
|
||||
switch (st) {
|
||||
case MTSE_FMT: /* illegal fmt */
|
||||
case MTSE_UNATT: /* not attached */
|
||||
tuer = tuer | ER_NXF; /* can't execute */
|
||||
set_tuer (ER_NXF); /* can't execute */
|
||||
case MTSE_OK: /* no error */
|
||||
return SCPE_IERR;
|
||||
case MTSE_TMK: /* end of file */
|
||||
tufs = tufs | FS_TMK;
|
||||
set_tuer (ER_FCE); /* also sets FCE */
|
||||
break;
|
||||
case MTSE_IOERR: /* IO error */
|
||||
tuer = tuer | ER_VPE; /* flag error */
|
||||
set_tuer (ER_VPE); /* flag error */
|
||||
if (tu_stopioe) return SCPE_IOERR;
|
||||
break;
|
||||
case MTSE_INVRL: /* invalid rec lnt */
|
||||
tuer = tuer | ER_VPE; /* flag error */
|
||||
set_tuer (ER_VPE); /* flag error */
|
||||
return SCPE_MTRLNT;
|
||||
case MTSE_RECE: /* record in error */
|
||||
tuer = tuer | ER_CRC; /* set crc err */
|
||||
set_tuer (ER_CRC); /* set crc err */
|
||||
break;
|
||||
case MTSE_EOM: /* end of medium */
|
||||
tuer = tuer | ER_OPI; /* incomplete */
|
||||
set_tuer (ER_OPI); /* incomplete */
|
||||
break;
|
||||
case MTSE_BOT: /* reverse into BOT */
|
||||
break;
|
||||
case MTSE_WRP: /* write protect */
|
||||
tuer = tuer | ER_NXF; /* can't execute */
|
||||
set_tuer (ER_NXF); /* can't execute */
|
||||
break; }
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -913,9 +949,13 @@ UNIT *uptr;
|
||||
|
||||
tucs1 = CS1_DVA | CS1_DONE;
|
||||
tucs2 = CS2_IR | CS2_OR;
|
||||
tuba = tufc = 0;
|
||||
tutc = tuer = 0;
|
||||
tuba = 0;
|
||||
tuwc = 0;
|
||||
tufc = 0;
|
||||
tuer = 0;
|
||||
tufs = FS_FPR | FS_RDY;
|
||||
if (sim_switches & SWMASK ('P')) tutc = 0; /* powerup? clr TC */
|
||||
else tutc = tutc & ~TC_FCS; /* no, clr <fcs> */
|
||||
tuiff = 0; /* clear CSTB INTR */
|
||||
int_req = int_req & ~INT_TU; /* clear interrupt */
|
||||
for (u = 0; u < TU_NUMDR; u++) { /* loop thru units */
|
||||
|
||||
Reference in New Issue
Block a user