mirror of
https://github.com/simh/simh.git
synced 2026-01-25 19:56:25 +00:00
Merge branch 'FastAsynchIO' into simhv38-2-rc2
Conflicts: PDP11/pdp11_tq.c PDP11/pdp11_ts.c PDP11/pdp11_xq.h VAX/vax780_sbi.c VAX/vax_cpu.c makefile scp.c sim_defs.h sim_ether.c sim_timer.c
This commit is contained in:
@@ -84,6 +84,7 @@
|
||||
#define MD_ACL 0x0002 /* t avl: all class NI */
|
||||
#define MD_NXU 0x0001 /* b gus: next unit */
|
||||
#define MD_RIP 0x0001 /* d onl: allow rip NI */
|
||||
#define MD_SPD 0x0001 /* d avl: spin-down */
|
||||
|
||||
/* End flags */
|
||||
|
||||
|
||||
242
PDP11/pdp11_rp.c
242
PDP11/pdp11_rp.c
@@ -25,6 +25,10 @@
|
||||
|
||||
rp RH/RP/RM moving head disks
|
||||
|
||||
06-Mar-11 MP Converted to using sim_disk library and refactored
|
||||
for Asynch I/O.
|
||||
Set STIME value to default of 26 which allows VMS V4.x
|
||||
to boot.
|
||||
17-May-07 RMS CS1 DVA resides in device, not MBA
|
||||
21-Nov-05 RMS Enable/disable device also enables/disables Massbus adapter
|
||||
12-Nov-05 RMS Fixed DriveClear, does not clear disk address
|
||||
@@ -65,6 +69,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include "sim_disk.h"
|
||||
#include <math.h>
|
||||
|
||||
#define RP_CTRL 0 /* ctrl is RP */
|
||||
@@ -93,6 +98,9 @@
|
||||
/* Parameters in the unit descriptor */
|
||||
|
||||
#define CYL u3 /* current cylinder */
|
||||
#define sectsread u4 /* sectors read */
|
||||
#define io_status u5 /* io status from callback */
|
||||
#define io_complete u6 /* io completion flag */
|
||||
|
||||
/* RPCS1, RMCS1 - control/status 1 - offset 0 */
|
||||
|
||||
@@ -319,19 +327,20 @@ struct drvtyp {
|
||||
int32 size; /* #blocks */
|
||||
int32 devtype; /* device type */
|
||||
int32 ctrl; /* ctrl type */
|
||||
char *name; /* device type name */
|
||||
};
|
||||
|
||||
static struct drvtyp drv_tab[] = {
|
||||
{ RM03_SECT, RM03_SURF, RM03_CYL, RM03_SIZE, RM03_DEV, RM_CTRL },
|
||||
{ RP04_SECT, RP04_SURF, RP04_CYL, RP04_SIZE, RP04_DEV, RP_CTRL },
|
||||
{ RM80_SECT, RM80_SURF, RM80_CYL, RM80_SIZE, RM80_DEV, RM_CTRL },
|
||||
{ RP06_SECT, RP06_SURF, RP06_CYL, RP06_SIZE, RP06_DEV, RP_CTRL },
|
||||
{ RM05_SECT, RM05_SURF, RM05_CYL, RM05_SIZE, RM05_DEV, RM_CTRL },
|
||||
{ RP07_SECT, RP07_SURF, RP07_CYL, RP07_SIZE, RP07_DEV, RM_CTRL },
|
||||
{ RM03_SECT, RM03_SURF, RM03_CYL, RM03_SIZE, RM03_DEV, RM_CTRL, "RM03" },
|
||||
{ RP04_SECT, RP04_SURF, RP04_CYL, RP04_SIZE, RP04_DEV, RP_CTRL, "RP04" },
|
||||
{ RM80_SECT, RM80_SURF, RM80_CYL, RM80_SIZE, RM80_DEV, RM_CTRL, "RM80" },
|
||||
{ RP06_SECT, RP06_SURF, RP06_CYL, RP06_SIZE, RP06_DEV, RP_CTRL, "RP06" },
|
||||
{ RM05_SECT, RM05_SURF, RM05_CYL, RM05_SIZE, RM05_DEV, RM_CTRL, "RM05" },
|
||||
{ RP07_SECT, RP07_SURF, RP07_CYL, RP07_SIZE, RP07_DEV, RM_CTRL, "RP07" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
uint16 *rpxb = NULL; /* xfer buffer */
|
||||
uint16 *rpxb[RP_NUMDR] = { 0 }; /* xfer buffer */
|
||||
uint16 rpcs1[RP_NUMDR] = { 0 }; /* control/status 1 */
|
||||
uint16 rpda[RP_NUMDR] = { 0 }; /* track/sector */
|
||||
uint16 rpds[RP_NUMDR] = { 0 }; /* drive status */
|
||||
@@ -346,7 +355,7 @@ 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 rp_stopioe = 1; /* stop on error */
|
||||
int32 rp_swait = 10; /* seek time */
|
||||
int32 rp_swait = 26; /* seek time */
|
||||
int32 rp_rwait = 10; /* rotate time */
|
||||
static const char *rp_fname[CS1_N_FNC] = {
|
||||
"NOP", "UNLD", "SEEK", "RECAL", "DCLR", "RLS", "OFFS", "RETN",
|
||||
@@ -767,6 +776,15 @@ int32 rp_abort (void)
|
||||
return rp_reset (&rp_dev);
|
||||
}
|
||||
|
||||
/* I/O completion callback */
|
||||
|
||||
void rp_io_complete (UNIT *uptr, t_stat status)
|
||||
{
|
||||
uptr->io_status = status;
|
||||
uptr->io_complete = 1;
|
||||
sim_activate (uptr, 0);
|
||||
}
|
||||
|
||||
/* Service unit timeout
|
||||
|
||||
Complete movement or data transfer command
|
||||
@@ -791,96 +809,127 @@ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
rp_update_ds (DS_ATA, drv); /* set attn */
|
||||
return (rp_stopioe? SCPE_UNATT: SCPE_OK);
|
||||
}
|
||||
rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY; /* change drive status */
|
||||
|
||||
switch (fnc) { /* case on function */
|
||||
if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
case FNC_OFFSET: /* offset */
|
||||
rp_update_ds (DS_OFM | DS_ATA, drv);
|
||||
break;
|
||||
case FNC_OFFSET: /* offset */
|
||||
rp_update_ds (DS_OFM | DS_ATA, drv);
|
||||
break;
|
||||
|
||||
case FNC_RETURN: /* return to centerline */
|
||||
rpds[drv] = rpds[drv] & ~DS_OFM; /* clear offset, set attn */
|
||||
rp_update_ds (DS_ATA, drv);
|
||||
break;
|
||||
case FNC_RETURN: /* return to centerline */
|
||||
rpds[drv] = rpds[drv] & ~DS_OFM; /* clear offset, set attn */
|
||||
rp_update_ds (DS_ATA, drv);
|
||||
break;
|
||||
|
||||
case FNC_UNLOAD: /* unload */
|
||||
rp_detach (uptr); /* detach unit */
|
||||
break;
|
||||
case FNC_UNLOAD: /* unload */
|
||||
rp_detach (uptr); /* detach unit */
|
||||
break;
|
||||
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
case FNC_SEARCH: /* search */
|
||||
case FNC_SEEK: /* seek */
|
||||
rp_update_ds (DS_ATA, drv);
|
||||
break;
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
case FNC_SEARCH: /* search */
|
||||
case FNC_SEEK: /* seek */
|
||||
rp_update_ds (DS_ATA, drv);
|
||||
break;
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
if (uptr->flags & UNIT_WPRT) { /* write locked? */
|
||||
rp_set_er (ER1_WLE, drv); /* set drive error */
|
||||
mba_set_exc (rp_dib.ba); /* set exception */
|
||||
rp_update_ds (DS_ATA, drv); /* set attn */
|
||||
return SCPE_OK;
|
||||
}
|
||||
case FNC_WCHK: /* write check */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read headers */
|
||||
err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET);
|
||||
mbc = mba_get_bc (rp_dib.ba); /* get byte count */
|
||||
wc = (mbc + 1) >> 1; /* convert to words */
|
||||
if ((da + wc) > drv_tab[dtype].size) { /* disk overrun? */
|
||||
rp_set_er (ER1_AOE, drv); /* set err */
|
||||
wc = drv_tab[dtype].size - da; /* trim xfer */
|
||||
mbc = wc << 1; /* trim mb count */
|
||||
if (da >= drv_tab[dtype].size) { /* none left? */
|
||||
case FNC_WRITE: /* write */
|
||||
if (uptr->flags & UNIT_WPRT) { /* write locked? */
|
||||
rp_set_er (ER1_WLE, drv); /* set drive error */
|
||||
mba_set_exc (rp_dib.ba); /* set exception */
|
||||
rp_update_ds (DS_ATA, drv); /* set attn */
|
||||
break;
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
if (fnc == FNC_WRITE) { /* write? */
|
||||
abc = mba_rdbufW (rp_dib.ba, mbc, rpxb); /* get buffer */
|
||||
wc = (abc + 1) >> 1; /* actual # wds */
|
||||
awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
|
||||
for (i = wc; i < awc; i++) /* fill buf */
|
||||
rpxb[i] = 0;
|
||||
if (wc && !err) { /* write buf */
|
||||
fxwrite (rpxb, sizeof (uint16), awc, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
case FNC_WCHK: /* write check */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read headers */
|
||||
mbc = mba_get_bc (rp_dib.ba); /* get byte count */
|
||||
wc = (mbc + 1) >> 1; /* convert to words */
|
||||
if ((da + wc) > drv_tab[dtype].size) { /* disk overrun? */
|
||||
rp_set_er (ER1_AOE, drv); /* set err */
|
||||
wc = drv_tab[dtype].size - da; /* trim xfer */
|
||||
mbc = wc << 1; /* trim mb count */
|
||||
if (da >= drv_tab[dtype].size) { /* none left? */
|
||||
mba_set_exc (rp_dib.ba); /* set exception */
|
||||
rp_update_ds (DS_ATA, drv); /* set attn */
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* end if wr */
|
||||
else { /* read or wchk */
|
||||
awc = fxread (rpxb, sizeof (uint16), wc, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
for (i = awc; i < wc; i++) /* fill buf */
|
||||
rpxb[i] = 0;
|
||||
if (fnc == FNC_WCHK) /* write check? */
|
||||
mba_chbufW (rp_dib.ba, mbc, rpxb); /* check vs mem */
|
||||
else mba_wrbufW (rp_dib.ba, mbc, rpxb); /* store in mem */
|
||||
} /* end if read */
|
||||
da = da + wc + (RP_NUMWD - 1);
|
||||
if (da >= drv_tab[dtype].size)
|
||||
rpds[drv] = rpds[drv] | DS_LST;
|
||||
da = da / RP_NUMWD;
|
||||
rpda[drv] = da % drv_tab[dtype].sect;
|
||||
da = da / drv_tab[dtype].sect;
|
||||
rpda[drv] = rpda[drv] | ((da % drv_tab[dtype].surf) << DA_V_SF);
|
||||
rpdc[drv] = da / drv_tab[dtype].surf;
|
||||
uptr->CYL = rpdc[drv];
|
||||
if (fnc == FNC_WRITE) { /* write? */
|
||||
abc = mba_rdbufW (rp_dib.ba, mbc, rpxb[drv]);/* get buffer */
|
||||
wc = (abc + 1) >> 1; /* actual # wds */
|
||||
awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
|
||||
for (i = wc; i < awc; i++) /* fill buf */
|
||||
rpxb[drv][i] = 0;
|
||||
sim_disk_wrsect_a (uptr, da/RP_NUMWD, (void *)rpxb[drv], NULL, awc/RP_NUMWD, rp_io_complete);
|
||||
return SCPE_OK;
|
||||
} /* end if wr */
|
||||
else { /* read or wchk */
|
||||
awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
|
||||
sim_disk_rdsect_a (uptr, da/RP_NUMWD, (void *)rpxb[drv], (t_seccnt*)&uptr->sectsread, awc/RP_NUMWD, rp_io_complete);
|
||||
return SCPE_OK;
|
||||
} /* end if read */
|
||||
|
||||
if (err != 0) { /* error? */
|
||||
rp_set_er (ER1_PAR, drv); /* set drive error */
|
||||
mba_set_exc (rp_dib.ba); /* set exception */
|
||||
rp_update_ds (DS_ATA, drv);
|
||||
perror ("RP I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
case FNC_WRITEH: /* write headers stub */
|
||||
mba_set_don (rp_dib.ba); /* set done */
|
||||
rp_update_ds (0, drv); /* update ds */
|
||||
break;
|
||||
} /* end case func */
|
||||
}
|
||||
else { /* Bottom End (After I/O processing) */
|
||||
uptr->io_complete = 0;
|
||||
err = uptr->io_status;
|
||||
|
||||
case FNC_WRITEH: /* write headers stub */
|
||||
mba_set_don (rp_dib.ba); /* set done */
|
||||
rp_update_ds (0, drv); /* update ds */
|
||||
break;
|
||||
} /* end case func */
|
||||
switch (fnc) { /* case on function */
|
||||
|
||||
case FNC_OFFSET: /* offset */
|
||||
case FNC_RETURN: /* return to centerline */
|
||||
case FNC_UNLOAD: /* unload */
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
case FNC_SEARCH: /* search */
|
||||
case FNC_SEEK: /* seek */
|
||||
case FNC_WRITEH: /* write headers stub */
|
||||
break;
|
||||
|
||||
case FNC_WRITE: /* write */
|
||||
case FNC_WCHK: /* write check */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read headers */
|
||||
mbc = mba_get_bc (rp_dib.ba); /* get byte count */
|
||||
wc = (mbc + 1) >> 1; /* convert to words */
|
||||
if (fnc == FNC_WRITE) { /* write? */
|
||||
} /* end if wr */
|
||||
else { /* read or wchk */
|
||||
awc = uptr->sectsread * RP_NUMWD;
|
||||
for (i = awc; i < wc; i++) /* fill buf */
|
||||
rpxb[drv][i] = 0;
|
||||
if (fnc == FNC_WCHK) /* write check? */
|
||||
mba_chbufW (rp_dib.ba, mbc, rpxb[drv]); /* check vs mem */
|
||||
else mba_wrbufW (rp_dib.ba, mbc, rpxb[drv]);/* store in mem */
|
||||
} /* end if read */
|
||||
da = da + wc + (RP_NUMWD - 1);
|
||||
if (da >= drv_tab[dtype].size)
|
||||
rpds[drv] = rpds[drv] | DS_LST;
|
||||
da = da / RP_NUMWD;
|
||||
rpda[drv] = da % drv_tab[dtype].sect;
|
||||
da = da / drv_tab[dtype].sect;
|
||||
rpda[drv] = rpda[drv] | ((da % drv_tab[dtype].surf) << DA_V_SF);
|
||||
rpdc[drv] = da / drv_tab[dtype].surf;
|
||||
uptr->CYL = rpdc[drv];
|
||||
|
||||
if (err != 0) { /* error? */
|
||||
rp_set_er (ER1_PAR, drv); /* set drive error */
|
||||
mba_set_exc (rp_dib.ba); /* set exception */
|
||||
rp_update_ds (DS_ATA, drv);
|
||||
perror ("RP I/O error");
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
|
||||
mba_set_don (rp_dib.ba); /* set done */
|
||||
rp_update_ds (0, drv); /* update ds */
|
||||
break;
|
||||
} /* end case func */
|
||||
}
|
||||
rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY; /* change drive status */
|
||||
|
||||
if (DEBUG_PRS (rp_dev))
|
||||
fprintf (sim_deb, ">>RP%d DONE: fnc=%s, ds=%o, cyl=%o, da=%o, er=%d\n",
|
||||
@@ -963,11 +1012,11 @@ for (i = 0; i < RP_NUMDR; i++) {
|
||||
rpec2[i] = 0;
|
||||
rmmr2[i] = 0;
|
||||
rmhr[i] = 0;
|
||||
if (rpxb[i] == NULL)
|
||||
rpxb[i] = (uint16 *) calloc (RP_MAXFR, sizeof (uint16));
|
||||
if (rpxb[i] == NULL)
|
||||
return SCPE_MEM;
|
||||
}
|
||||
if (rpxb == NULL)
|
||||
rpxb = (uint16 *) calloc (RP_MAXFR, sizeof (uint16));
|
||||
if (rpxb == NULL)
|
||||
return SCPE_MEM;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -979,7 +1028,9 @@ int32 drv, i, p;
|
||||
t_stat r;
|
||||
|
||||
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
|
||||
r = attach_unit (uptr, cptr); /* attach unit */
|
||||
r = sim_disk_attach (uptr, cptr, RP_NUMWD * sizeof (uint16),
|
||||
sizeof (uint16), TRUE, 0,
|
||||
drv_tab[GET_DTYPE (uptr->flags)].name, drv_tab[GET_DTYPE (uptr->flags)].sect);
|
||||
if (r != SCPE_OK) /* error? */
|
||||
return r;
|
||||
drv = (int32) (uptr - rp_dev.units); /* get drv number */
|
||||
@@ -988,14 +1039,9 @@ rpds[drv] = DS_MOL | DS_RDY | DS_DPR | /* upd drv status */
|
||||
rper1[drv] = 0;
|
||||
rp_update_ds (DS_ATA, drv); /* upd ctlr status */
|
||||
|
||||
if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */
|
||||
if (uptr->flags & UNIT_RO)
|
||||
return SCPE_OK;
|
||||
return pdp11_bad_block (uptr,
|
||||
drv_tab[GET_DTYPE (uptr->flags)].sect, RP_NUMWD);
|
||||
}
|
||||
if ((uptr->flags & UNIT_AUTO) == 0) /* autosize? */
|
||||
return SCPE_OK;
|
||||
p = (int32)sim_disk_size (uptr);
|
||||
for (i = 0; drv_tab[i].sect != 0; i++) {
|
||||
if (p <= (drv_tab[i].size * (int) sizeof (int16))) {
|
||||
uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE);
|
||||
@@ -1017,7 +1063,7 @@ if (!(uptr->flags & UNIT_ATT)) /* attached? */
|
||||
drv = (int32) (uptr - rp_dev.units); /* get drv number */
|
||||
rpds[drv] = rpds[drv] & ~(DS_MOL | DS_RDY | DS_WRL | DS_VV | DS_OFM);
|
||||
rp_update_ds (DS_ATA, drv); /* request intr */
|
||||
return detach_unit (uptr);
|
||||
return sim_disk_detach (uptr);
|
||||
}
|
||||
|
||||
/* Set size command validation routine */
|
||||
|
||||
367
PDP11/pdp11_rq.c
367
PDP11/pdp11_rq.c
@@ -26,6 +26,19 @@
|
||||
|
||||
rq RQDX3 disk controller
|
||||
|
||||
07-Mar-11 MP Added working behaviors for removable device types.
|
||||
This allows physical CDROM's to come online and be
|
||||
ejected.
|
||||
02-Mar-11 MP Fixed missing information from save/restore which
|
||||
caused operations to not complete correctly after
|
||||
a restore until the OS reset the controller.
|
||||
02-Feb-11 MP Added Autosize support to rq_attach
|
||||
28-Jan-11 MP Adopted use of sim_disk disk I/O library
|
||||
- added support for the multiple formats sim_disk
|
||||
provides (SimH, RAW, and VHD)
|
||||
- adjusted to potentially leverage asynch I/O when
|
||||
available
|
||||
- Added differing detailed debug output via sim_debug
|
||||
14-Jan-09 JH Added support for RD32 disc drive
|
||||
18-Jun-07 RMS Added UNIT_IDLE flag to timer thread
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
@@ -97,6 +110,7 @@ extern int32 cpu_opt;
|
||||
|
||||
#include "pdp11_uqssp.h"
|
||||
#include "pdp11_mscp.h"
|
||||
#include "sim_disk.h"
|
||||
|
||||
#define UF_MSK (UF_CMR|UF_CMW) /* settable flags */
|
||||
|
||||
@@ -129,20 +143,25 @@ extern int32 cpu_opt;
|
||||
#define UNIT_V_ATP (UNIT_V_UF + 2) /* attn pending */
|
||||
#define UNIT_V_DTYPE (UNIT_V_UF + 3) /* drive type */
|
||||
#define UNIT_M_DTYPE 0x1F
|
||||
#define UNIT_V_NOAUTO (UNIT_V_UF + 8) /* noautosize */
|
||||
#define UNIT_ONL (1 << UNIT_V_ONL)
|
||||
#define UNIT_WLK (1 << UNIT_V_WLK)
|
||||
#define UNIT_ATP (1 << UNIT_V_ATP)
|
||||
#define UNIT_NOAUTO (1 << UNIT_V_NOAUTO)
|
||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||
#define cpkt u3 /* current packet */
|
||||
#define pktq u4 /* packet queue */
|
||||
#define uf buf /* settable unit flags */
|
||||
#define cnum wait /* controller index */
|
||||
#define io_status u5 /* io status from callback */
|
||||
#define io_complete u6 /* io completion flag */
|
||||
#define rqxb filebuf /* xfer buffer */
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write prot */
|
||||
#define RQ_RMV(u) ((drv_tab[GET_DTYPE (u->flags)].flgs & RQDF_RMV)? \
|
||||
UF_RMV: 0)
|
||||
#define RQ_WPH(u) (((drv_tab[GET_DTYPE (u->flags)].flgs & RQDF_RO) || \
|
||||
(u->flags & UNIT_WPRT))? UF_WPH: 0)
|
||||
(u->flags & UNIT_WPRT) || sim_disk_wrp (u))? UF_WPH: 0)
|
||||
|
||||
#define CST_S1 0 /* init stage 1 */
|
||||
#define CST_S1_WR 1 /* stage 1 wrap */
|
||||
@@ -567,7 +586,6 @@ extern FILE *sim_deb;
|
||||
extern uint32 sim_taddr_64;
|
||||
extern int32 sim_switches;
|
||||
|
||||
uint16 *rqxb = NULL; /* xfer buffer */
|
||||
int32 rq_itime = 200; /* init time, except */
|
||||
int32 rq_itime4 = 10; /* stage 4 */
|
||||
int32 rq_qtime = RQ_QTIME; /* queue time */
|
||||
@@ -597,7 +615,56 @@ typedef struct {
|
||||
struct rqpkt pak[RQ_NPKTS]; /* packet queue */
|
||||
} MSC;
|
||||
|
||||
DEVICE rq_dev, rqb_dev, rqc_dev,rqd_dev;
|
||||
/* debugging bitmaps */
|
||||
#define DBG_TRC 0x0001 /* trace routine calls */
|
||||
#define DBG_INI 0x0002 /* display setup/init sequence info */
|
||||
#define DBG_REG 0x0004 /* trace read/write registers */
|
||||
#define DBG_REQ 0x0008 /* display transfer requests */
|
||||
#define DBG_DSK 0x0010 /* display sim_disk activities */
|
||||
#define DBG_DAT 0x0020 /* display transfer data */
|
||||
|
||||
DEBTAB rq_debug[] = {
|
||||
{"TRACE", DBG_TRC},
|
||||
{"INIT", DBG_INI},
|
||||
{"REG", DBG_REG},
|
||||
{"REQ", DBG_REQ},
|
||||
{"DISK", DBG_DSK},
|
||||
{"DATA", DBG_DAT},
|
||||
{0}
|
||||
};
|
||||
|
||||
static char *rq_cmdname[] = {
|
||||
"", /* 0 */
|
||||
"ABO", /* 1 b: abort */
|
||||
"GCS", /* 2 b: get command status */
|
||||
"GUS", /* 3 b: get unit status */
|
||||
"SCC", /* 4 b: set controller char */
|
||||
"","","", /* 5-7 */
|
||||
"AVL", /* 8 b: available */
|
||||
"ONL", /* 9 b: online */
|
||||
"SUC", /* 10 b: set unit char */
|
||||
"DAP", /* 11 b: det acc paths - nop */
|
||||
"","","","", /* 12-15 */
|
||||
"ACC", /* 16 b: access */
|
||||
"CCD", /* 17 d: compare - nop */
|
||||
"ERS", /* 18 b: erase */
|
||||
"FLU", /* 19 d: flush - nop */
|
||||
"","", /* 20-21 */
|
||||
"ERG", /* 22 t: erase gap */
|
||||
"","","","","","","","","", /* 23-31 */
|
||||
"CMP", /* 32 b: compare */
|
||||
"RD", /* 33 b: read */
|
||||
"WR", /* 34 b: write */
|
||||
"", /* 35 */
|
||||
"WTM", /* 36 t: write tape mark */
|
||||
"POS", /* 37 t: reposition */
|
||||
"","","","","","","","","", /* 38-46 */
|
||||
"FMT", /* 47 d: format */
|
||||
"","","","","","","","","","","","","","","","", /* 48-63 */
|
||||
"AVA", /* 64 b: unit now avail */
|
||||
};
|
||||
|
||||
DEVICE rq_dev, rqb_dev, rqc_dev, rqd_dev;
|
||||
|
||||
t_stat rq_rd (int32 *data, int32 PA, int32 access);
|
||||
t_stat rq_wr (int32 data, int32 PA, int32 access);
|
||||
@@ -686,9 +753,11 @@ REG rq_reg[] = {
|
||||
{ GRDATA (SAW, rq_ctx.saw, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (S1DAT, rq_ctx.s1dat, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (COMM, rq_ctx.comm, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQIOFF, rq_ctx.cq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (CQBA, rq_ctx.cq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQLNT, rq_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (CQIDX, rq_ctx.cq.idx, DEV_RDX, 8, 2) },
|
||||
{ GRDATA (RQIOFF, rq_ctx.rq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (RQBA, rq_ctx.rq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (RQLNT, rq_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (RQIDX, rq_ctx.rq.idx, DEV_RDX, 8, 2) },
|
||||
@@ -774,6 +843,10 @@ MTAB rq_mod[] = {
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, 0, "TYPE", NULL,
|
||||
NULL, &rq_show_type, NULL },
|
||||
{ UNIT_NOAUTO, UNIT_NOAUTO, "noautosize", "NOAUTOSIZE", NULL },
|
||||
{ UNIT_NOAUTO, 0, "autosize", "AUTOSIZE", NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT",
|
||||
&sim_disk_set_fmt, &sim_disk_show_fmt, NULL },
|
||||
#if defined (VM_PDP11)
|
||||
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
|
||||
&set_addr, &show_addr, NULL },
|
||||
@@ -793,7 +866,8 @@ DEVICE rq_dev = {
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rq_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
&rq_dib, DEV_FLTA | DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG,
|
||||
0, rq_debug
|
||||
};
|
||||
|
||||
/* RQB data structures
|
||||
@@ -829,9 +903,11 @@ REG rqb_reg[] = {
|
||||
{ GRDATA (SAW, rqb_ctx.saw, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (S1DAT, rqb_ctx.s1dat, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (COMM, rqb_ctx.comm, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQIOFF, rqb_ctx.cq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (CQBA, rqb_ctx.cq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQLNT, rqb_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (CQIDX, rqb_ctx.cq.idx, DEV_RDX, 8, 2) },
|
||||
{ GRDATA (RQIOFF, rqb_ctx.rq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (RQBA, rqb_ctx.rq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (RQLNT, rqb_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (RQIDX, rqb_ctx.rq.idx, DEV_RDX, 8, 2) },
|
||||
@@ -851,7 +927,7 @@ REG rqb_reg[] = {
|
||||
{ URDATA (CPKT, rqb_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rqb_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rqb_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (CAPAC, rqb_unit[0].capac, 10, 31, 0, RQ_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ URDATA (CAPAC, rqb_unit[0].capac, 10, T_ADDR_W, 0, RQ_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ GRDATA (DEVADDR, rqb_dib.ba, DEV_RDX, 32, 0), REG_HRO },
|
||||
{ GRDATA (DEVVEC, rqb_dib.vec, DEV_RDX, 16, 0), REG_HRO },
|
||||
{ NULL }
|
||||
@@ -862,7 +938,8 @@ DEVICE rqb_dev = {
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rqb_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
&rqb_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG,
|
||||
0, rq_debug
|
||||
};
|
||||
|
||||
/* RQC data structures
|
||||
@@ -898,9 +975,11 @@ REG rqc_reg[] = {
|
||||
{ GRDATA (SAW, rqc_ctx.saw, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (S1DAT, rqc_ctx.s1dat, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (COMM, rqc_ctx.comm, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQIOFF, rqc_ctx.cq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (CQBA, rqc_ctx.cq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQLNT, rqc_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (CQIDX, rqc_ctx.cq.idx, DEV_RDX, 8, 2) },
|
||||
{ GRDATA (RQIOFF, rqc_ctx.rq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (RQBA, rqc_ctx.rq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (RQLNT, rqc_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (RQIDX, rqc_ctx.rq.idx, DEV_RDX, 8, 2) },
|
||||
@@ -920,7 +999,7 @@ REG rqc_reg[] = {
|
||||
{ URDATA (CPKT, rqc_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rqc_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rqc_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (CAPAC, rqc_unit[0].capac, 10, 31, 0, RQ_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ URDATA (CAPAC, rqc_unit[0].capac, 10, T_ADDR_W, 0, RQ_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ GRDATA (DEVADDR, rqc_dib.ba, DEV_RDX, 32, 0), REG_HRO },
|
||||
{ GRDATA (DEVVEC, rqc_dib.vec, DEV_RDX, 16, 0), REG_HRO },
|
||||
{ NULL }
|
||||
@@ -931,7 +1010,8 @@ DEVICE rqc_dev = {
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rqc_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
&rqc_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG,
|
||||
0, rq_debug
|
||||
};
|
||||
|
||||
/* RQD data structures
|
||||
@@ -967,9 +1047,11 @@ REG rqd_reg[] = {
|
||||
{ GRDATA (SAW, rqd_ctx.saw, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (S1DAT, rqd_ctx.s1dat, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (COMM, rqd_ctx.comm, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQIOFF, rqd_ctx.cq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (CQBA, rqd_ctx.cq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQLNT, rqd_ctx.cq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (CQIDX, rqd_ctx.cq.idx, DEV_RDX, 8, 2) },
|
||||
{ GRDATA (RQIOFF, rqd_ctx.rq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (RQBA, rqd_ctx.rq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (RQLNT, rqd_ctx.rq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (RQIDX, rqd_ctx.rq.idx, DEV_RDX, 8, 2) },
|
||||
@@ -989,7 +1071,7 @@ REG rqd_reg[] = {
|
||||
{ URDATA (CPKT, rqd_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rqd_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rqd_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (CAPAC, rqd_unit[0].capac, 10, 31, 0, RQ_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ URDATA (CAPAC, rqd_unit[0].capac, 10, T_ADDR_W, 0, RQ_NUMDR, PV_LEFT | REG_HRO) },
|
||||
{ GRDATA (DEVADDR, rqd_dib.ba, DEV_RDX, 32, 0), REG_HRO },
|
||||
{ GRDATA (DEVVEC, rqd_dib.vec, DEV_RDX, 16, 0), REG_HRO },
|
||||
{ NULL }
|
||||
@@ -1000,7 +1082,8 @@ DEVICE rqd_dev = {
|
||||
RQ_NUMDR + 2, DEV_RDX, T_ADDR_W, 2, DEV_RDX, 16,
|
||||
NULL, NULL, &rq_reset,
|
||||
&rq_boot, &rq_attach, &rq_detach,
|
||||
&rqd_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
&rqd_dib, DEV_FLTA | DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_QBUS | DEV_DEBUG,
|
||||
0, rq_debug
|
||||
};
|
||||
|
||||
static DEVICE *rq_devmap[RQ_NUMCT] = {
|
||||
@@ -1023,6 +1106,8 @@ int32 cidx = rq_map_pa ((uint32) PA);
|
||||
MSC *cp = rq_ctxmap[cidx];
|
||||
DEVICE *dptr = rq_devmap[cidx];
|
||||
|
||||
sim_debug(DBG_REG, dptr, "rq_rd(PA=0x%08X [%s], access=%d)\n", PA, ((PA >> 1) & 01) ? "IP" : "SA", access);
|
||||
|
||||
if (cidx < 0)
|
||||
return SCPE_IERR;
|
||||
switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
@@ -1032,9 +1117,7 @@ switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
if (cp->csta == CST_S3_PPB) /* waiting for poll? */
|
||||
rq_step4 (cp);
|
||||
else if (cp->csta == CST_UP) { /* if up */
|
||||
if (DEBUG_PRD (dptr))
|
||||
fprintf (sim_deb, ">>RQ%c: poll started, PC=%X\n",
|
||||
'A' + cp->cnum, OLDPC);
|
||||
sim_debug (DBG_REQ, dptr, "poll started, PC=%X\n", OLDPC);
|
||||
cp->pip = 1; /* poll host */
|
||||
sim_activate (dptr->units + RQ_QUEUE, rq_qtime);
|
||||
}
|
||||
@@ -1044,7 +1127,6 @@ switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
*data = cp->sa;
|
||||
break;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1056,13 +1138,14 @@ DEVICE *dptr = rq_devmap[cidx];
|
||||
|
||||
if (cidx < 0)
|
||||
return SCPE_IERR;
|
||||
|
||||
sim_debug(DBG_REG, dptr, "rq_wr(PA=0x%08X [%s], access=%d)\n", PA, ((PA >> 1) & 01) ? "IP" : "SA", access);
|
||||
|
||||
switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
|
||||
case 0: /* IP */
|
||||
rq_reset (rq_devmap[cidx]); /* init device */
|
||||
if (DEBUG_PRD (dptr))
|
||||
fprintf (sim_deb, ">>RQ%c: initialization started\n",
|
||||
'A' + cp->cnum);
|
||||
sim_debug (DBG_REQ, dptr, "initialization started\n");
|
||||
break;
|
||||
|
||||
case 1: /* SA */
|
||||
@@ -1147,7 +1230,12 @@ MSC *cp = rq_ctxmap[uptr->cnum];
|
||||
DEVICE *dptr = rq_devmap[uptr->cnum];
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_quesvc\n");
|
||||
|
||||
if (cp->csta < CST_UP) { /* still init? */
|
||||
|
||||
sim_debug(DBG_INI, dptr, "CSTA=%d, SAW=0x%X\n", cp->csta, cp->saw);
|
||||
|
||||
switch (cp->csta) { /* controller state? */
|
||||
|
||||
case CST_S1: /* need S1 reply */
|
||||
@@ -1197,8 +1285,7 @@ if (cp->csta < CST_UP) { /* still init? */
|
||||
|
||||
case CST_S4: /* need S4 reply */
|
||||
if (cp->saw & SA_S4H_GO) { /* go set? */
|
||||
if (DEBUG_PRD (dptr))
|
||||
fprintf (sim_deb, ">>RQ%c: initialization complete\n", 'A' + cp->cnum);
|
||||
sim_debug (DBG_REQ, dptr, "initialization complete\n");
|
||||
cp->csta = CST_UP; /* we're up */
|
||||
cp->sa = 0; /* clear SA */
|
||||
sim_activate (dptr->units + RQ_TIMER, tmr_poll * clk_tps);
|
||||
@@ -1224,15 +1311,12 @@ if ((pkt == 0) && cp->pip) { /* polling? */
|
||||
if (!rq_getpkt (cp, &pkt)) /* get host pkt */
|
||||
return SCPE_OK;
|
||||
if (pkt) { /* got one? */
|
||||
if (DEBUG_PRD (dptr)) {
|
||||
fprintf (sim_deb, ">>RQ%c: cmd=%04X, mod=%04X, unit=%d, ",
|
||||
'A' + cp->cnum, cp->pak[pkt].d[CMD_OPC],
|
||||
cp->pak[pkt].d[CMD_MOD], cp->pak[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, "bc=%04X%04X, ma=%04X%04X, lbn=%04X%04X\n",
|
||||
sim_debug (DBG_REQ, dptr, "cmd=%04X(%3s), mod=%04X, unit=%d, bc=%04X%04X, ma=%04X%04X, lbn=%04X%04X\n",
|
||||
cp->pak[pkt].d[CMD_OPC], rq_cmdname[cp->pak[pkt].d[CMD_OPC]&0x3f],
|
||||
cp->pak[pkt].d[CMD_MOD], cp->pak[pkt].d[CMD_UN],
|
||||
cp->pak[pkt].d[RW_BCH], cp->pak[pkt].d[RW_BCL],
|
||||
cp->pak[pkt].d[RW_BAH], cp->pak[pkt].d[RW_BAL],
|
||||
cp->pak[pkt].d[RW_LBNH], cp->pak[pkt].d[RW_LBNL]);
|
||||
}
|
||||
if (GETP (pkt, UQ_HCTC, TYP) != UQ_TYP_SEQ) /* seq packet? */
|
||||
return rq_fatal (cp, PE_PIE); /* no, term thread */
|
||||
cnid = GETP (pkt, UQ_HCTC, CID); /* get conn ID */
|
||||
@@ -1253,6 +1337,7 @@ if (cp->rspq) { /* resp q? */
|
||||
pkt = rq_deqh (cp, &cp->rspq); /* get top of q */
|
||||
if (!rq_putpkt (cp, pkt, FALSE)) /* send to host */
|
||||
return SCPE_OK;
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_quesvc - rq_putpkt failed - 1\n");
|
||||
} /* end if resp q */
|
||||
if (pkt) /* more to do? */
|
||||
sim_activate (uptr, rq_qtime);
|
||||
@@ -1268,6 +1353,7 @@ UNIT *nuptr;
|
||||
MSC *cp = rq_ctxmap[uptr->cnum];
|
||||
DEVICE *dptr = rq_devmap[uptr->cnum];
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_tmrsvc\n");
|
||||
sim_activate (uptr, tmr_poll * clk_tps); /* reactivate */
|
||||
for (i = 0; i < RQ_NUMDR; i++) { /* poll */
|
||||
nuptr = dptr->units + i;
|
||||
@@ -1290,6 +1376,8 @@ t_bool rq_mscp (MSC *cp, int32 pkt, t_bool q)
|
||||
{
|
||||
uint32 sts, cmd = GETP (pkt, CMD_OPC, OPC);
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_mscp - %s\n", q? "Queue" : "No Queue");
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case OP_ABO: /* abort */
|
||||
@@ -1351,6 +1439,8 @@ int32 tpkt, prv;
|
||||
UNIT *uptr;
|
||||
DEVICE *dptr = rq_devmap[cp->cnum];
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_abo\n");
|
||||
|
||||
tpkt = 0; /* set no mtch */
|
||||
if (uptr = rq_getucb (cp, lu)) { /* get unit */
|
||||
if (uptr->cpkt && /* curr pkt? */
|
||||
@@ -1390,15 +1480,20 @@ t_bool rq_avl (MSC *cp, int32 pkt, t_bool q)
|
||||
{
|
||||
uint32 lu = cp->pak[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 mdf = cp->pak[pkt].d[CMD_MOD]; /* modifier */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_avl\n");
|
||||
|
||||
if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
if (q && uptr->cpkt) { /* need to queue? */
|
||||
rq_enqt (cp, &uptr->pktq, pkt); /* do later */
|
||||
return OK;
|
||||
}
|
||||
uptr->flags = uptr->flags & ~UNIT_ONL; /* not online */
|
||||
if ((mdf & MD_SPD) && RQ_RMV (uptr)) /* unload of removable device */
|
||||
sim_disk_unload (uptr);
|
||||
uptr->uf = 0; /* clr flags */
|
||||
sts = ST_SUC; /* success */
|
||||
}
|
||||
@@ -1417,6 +1512,8 @@ uint32 ref = GETP32 (pkt, GCS_REFL); /* ref # */
|
||||
int32 tpkt;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_gcs\n");
|
||||
|
||||
if ((uptr = rq_getucb (cp, lu)) && /* valid lu? */
|
||||
(tpkt = uptr->cpkt) && /* queued pkt? */
|
||||
(GETP32 (tpkt, CMD_REFL) == ref) && /* match ref? */
|
||||
@@ -1441,6 +1538,8 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 dtyp, sts, rbpar;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_gus\n");
|
||||
|
||||
if (cp->pak[pkt].d[CMD_MOD] & MD_NXU) { /* next unit? */
|
||||
if (lu >= (cp->ubase + RQ_NUMDR)) { /* end of range? */
|
||||
lu = 0; /* reset to 0 */
|
||||
@@ -1482,6 +1581,8 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_onl\n");
|
||||
|
||||
if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
if (q && uptr->cpkt) { /* need to queue? */
|
||||
rq_enqt (cp, &uptr->pktq, pkt); /* do later */
|
||||
@@ -1491,11 +1592,14 @@ if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
sts = ST_OFL | SB_OFL_NV; /* offl no vol */
|
||||
else if (uptr->flags & UNIT_ONL) /* already online? */
|
||||
sts = ST_SUC | SB_SUC_ON;
|
||||
else { /* mark online */
|
||||
else if (sim_disk_isavailable (uptr))
|
||||
{ /* mark online */
|
||||
sts = ST_SUC;
|
||||
uptr->flags = uptr->flags | UNIT_ONL;
|
||||
rq_setf_unit (cp, pkt, uptr); /* hack flags */
|
||||
}
|
||||
else
|
||||
sts = ST_OFL | SB_OFL_NV; /* offl no vol */
|
||||
rq_putr_unit (cp, pkt, uptr, lu, TRUE); /* set fields */
|
||||
}
|
||||
else sts = ST_OFL; /* offline */
|
||||
@@ -1511,6 +1615,8 @@ t_bool rq_scc (MSC *cp, int32 pkt, t_bool q)
|
||||
{
|
||||
int32 sts, cmd;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_scc\n");
|
||||
|
||||
if (cp->pak[pkt].d[SCC_MSV]) { /* MSCP ver = 0? */
|
||||
sts = ST_CMD | I_VRSN; /* no, lose */
|
||||
cmd = 0;
|
||||
@@ -1547,6 +1653,8 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_suc\n");
|
||||
|
||||
if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
if (q && uptr->cpkt) { /* need to queue? */
|
||||
rq_enqt (cp, &uptr->pktq, pkt); /* do later */
|
||||
@@ -1576,6 +1684,8 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_fmt\n");
|
||||
|
||||
if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
if (q && uptr->cpkt) { /* need to queue? */
|
||||
rq_enqt (cp, &uptr->pktq, pkt); /* do later */
|
||||
@@ -1610,8 +1720,11 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_rw(lu=%d, pkt=%d, queue=%s)\n", lu, pkt, q?"yes" : "no");
|
||||
|
||||
if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
if (q && uptr->cpkt) { /* need to queue? */
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_rw - queued\n");
|
||||
rq_enqt (cp, &uptr->pktq, pkt); /* do later */
|
||||
return OK;
|
||||
}
|
||||
@@ -1624,7 +1737,9 @@ if (uptr = rq_getucb (cp, lu)) { /* unit exist? */
|
||||
cp->pak[pkt].d[RW_WBCH] = cp->pak[pkt].d[RW_BCH];
|
||||
cp->pak[pkt].d[RW_WBLL] = cp->pak[pkt].d[RW_LBNL];
|
||||
cp->pak[pkt].d[RW_WBLH] = cp->pak[pkt].d[RW_LBNH];
|
||||
sim_activate (uptr, rq_xtime); /* activate */
|
||||
uptr->iostarttime = sim_grtime();
|
||||
sim_activate (uptr, 0); /* activate */
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_rw - started\n");
|
||||
return OK; /* done */
|
||||
}
|
||||
}
|
||||
@@ -1674,12 +1789,28 @@ if ((cmd == OP_WR) || (cmd == OP_ERS)) { /* write op? */
|
||||
return 0; /* success! */
|
||||
}
|
||||
|
||||
/* I/O completion callback */
|
||||
|
||||
void rq_io_complete (UNIT *uptr, t_stat status)
|
||||
{
|
||||
MSC *cp = rq_ctxmap[uptr->cnum];
|
||||
int32 elapsed = sim_grtime()-uptr->iostarttime;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_io_complete(status=%d)\n", status);
|
||||
|
||||
uptr->io_status = status;
|
||||
uptr->io_complete = 1;
|
||||
if (elapsed > rq_xtime)
|
||||
sim_activate (uptr, 0);
|
||||
else
|
||||
sim_activate (uptr, rq_xtime-elapsed);
|
||||
}
|
||||
|
||||
/* Unit service for data transfer commands */
|
||||
|
||||
t_stat rq_svc (UNIT *uptr)
|
||||
{
|
||||
MSC *cp = rq_ctxmap[uptr->cnum];
|
||||
|
||||
uint32 i, t, tbc, abc, wwc;
|
||||
uint32 err = 0;
|
||||
int32 pkt = uptr->cpkt; /* get packet */
|
||||
@@ -1687,7 +1818,10 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* get cmd */
|
||||
uint32 ba = GETP32 (pkt, RW_WBAL); /* buf addr */
|
||||
uint32 bc = GETP32 (pkt, RW_WBCL); /* byte count */
|
||||
uint32 bl = GETP32 (pkt, RW_WBLL); /* block addr */
|
||||
t_addr da = ((t_addr) bl) * RQ_NUMBY; /* disk addr */
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_svc(unit=%d, pkt=%d, cmd=%s, lbn=%0X, bc=%0x, phase=%s)\n",
|
||||
uptr-rq_devmap[cp->cnum]->units, pkt, rq_cmdname[cp->pak[pkt].d[CMD_OPC]&0x3f], bl, bc,
|
||||
uptr->io_complete ? "bottom" : "top");
|
||||
|
||||
if ((cp == NULL) || (pkt == 0)) /* what??? */
|
||||
return STOP_RQ;
|
||||
@@ -1713,77 +1847,85 @@ if ((cmd == OP_ERS) || (cmd == OP_WR)) { /* write op? */
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == OP_ERS) { /* erase? */
|
||||
wwc = ((tbc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1;
|
||||
for (i = 0; i < wwc; i++) /* clr buf */
|
||||
rqxb[i] = 0;
|
||||
err = sim_fseek (uptr->fileref, da, SEEK_SET); /* set pos */
|
||||
if (!err)
|
||||
sim_fwrite (rqxb, sizeof (int16), wwc, uptr->fileref);
|
||||
err = ferror (uptr->fileref); /* end if erase */
|
||||
}
|
||||
if (!uptr->io_complete) { /* Top End (I/O Initiation) Processing */
|
||||
if (cmd == OP_ERS) { /* erase? */
|
||||
wwc = ((tbc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1;
|
||||
memset (uptr->rqxb, 0, wwc * sizeof(uint16)); /* clr buf */
|
||||
sim_disk_data_trace(uptr, uptr->rqxb, bl, wwc << 1, "sim_disk_wrsect-ERS", DBG_DAT & rq_devmap[cp->cnum]->dctrl, DBG_REQ);
|
||||
err = sim_disk_wrsect_a (uptr, bl, uptr->rqxb, NULL, (wwc << 1) / RQ_NUMBY, rq_io_complete);
|
||||
}
|
||||
|
||||
else if (cmd == OP_WR) { /* write? */
|
||||
t = Map_ReadW (ba, tbc, rqxb); /* fetch buffer */
|
||||
if (abc = tbc - t) { /* any xfer? */
|
||||
wwc = ((abc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1;
|
||||
for (i = (abc >> 1); i < wwc; i++)
|
||||
rqxb[i] = 0;
|
||||
err = sim_fseek (uptr->fileref, da, SEEK_SET);
|
||||
if (!err)
|
||||
sim_fwrite (rqxb, sizeof (int16), wwc, uptr->fileref);
|
||||
err = ferror (uptr->fileref);
|
||||
}
|
||||
if (t) { /* nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - abc); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, ba + abc); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM);
|
||||
return SCPE_OK; /* end else wr */
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
err = sim_fseek (uptr->fileref, da, SEEK_SET); /* set pos */
|
||||
if (!err) {
|
||||
i = sim_fread (rqxb, sizeof (int16), tbc >> 1, uptr->fileref);
|
||||
for ( ; i < (tbc >> 1); i++) /* fill */
|
||||
rqxb[i] = 0;
|
||||
err = ferror (uptr->fileref);
|
||||
}
|
||||
if ((cmd == OP_RD) && !err) { /* read? */
|
||||
if (t = Map_WriteW (ba, tbc, rqxb)) { /* store, nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - (tbc - t)); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, ba + (tbc - t)); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM);
|
||||
return SCPE_OK;
|
||||
else if (cmd == OP_WR) { /* write? */
|
||||
t = Map_ReadW (ba, tbc, uptr->rqxb); /* fetch buffer */
|
||||
if (abc = tbc - t) { /* any xfer? */
|
||||
wwc = ((abc + (RQ_NUMBY - 1)) & ~(RQ_NUMBY - 1)) >> 1;
|
||||
for (i = (abc >> 1); i < wwc; i++)
|
||||
((uint16 *)(uptr->rqxb))[i] = 0;
|
||||
sim_disk_data_trace(uptr, uptr->rqxb, bl, wwc << 1, "sim_disk_wrsect-WR", DBG_DAT & rq_devmap[cp->cnum]->dctrl, DBG_REQ);
|
||||
err = sim_disk_wrsect_a (uptr, bl, uptr->rqxb, NULL, (wwc << 1) / RQ_NUMBY, rq_io_complete);
|
||||
}
|
||||
}
|
||||
else if ((cmd == OP_CMP) && !err) { /* compare? */
|
||||
uint8 dby, mby;
|
||||
for (i = 0; i < tbc; i++) { /* loop */
|
||||
if (Map_ReadB (ba + i, 1, &mby)) { /* fetch, nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - i); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, bc - i); /* adj ba */
|
||||
|
||||
else { /* OP_RD & OP_CMP */
|
||||
err = sim_disk_rdsect_a (uptr, bl, uptr->rqxb, NULL, (tbc + RQ_NUMBY - 1) / RQ_NUMBY, rq_io_complete);
|
||||
} /* end else read */
|
||||
return SCPE_OK; /* done for now until callback */
|
||||
}
|
||||
else { /* Bottom End (After I/O processing) */
|
||||
uptr->io_complete = 0;
|
||||
err = uptr->io_status;
|
||||
if (cmd == OP_ERS) { /* erase? */
|
||||
}
|
||||
|
||||
else if (cmd == OP_WR) { /* write? */
|
||||
t = Map_ReadW (ba, tbc, uptr->rqxb); /* fetch buffer */
|
||||
abc = tbc - t; /* any xfer? */
|
||||
if (t) { /* nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - abc); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, ba + abc); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM);
|
||||
return SCPE_OK; /* end else wr */
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
sim_disk_data_trace(uptr, uptr->rqxb, bl, tbc, "sim_disk_rdsect", DBG_DAT & rq_devmap[cp->cnum]->dctrl, DBG_REQ);
|
||||
if ((cmd == OP_RD) && !err) { /* read? */
|
||||
if (t = Map_WriteW (ba, tbc, uptr->rqxb)) { /* store, nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - (tbc - t)); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, ba + (tbc - t)); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM);
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM);
|
||||
return SCPE_OK;
|
||||
}
|
||||
dby = (rqxb[i >> 1] >> ((i & 1)? 8: 0)) & 0xFF;
|
||||
if (mby != dby) { /* cmp err? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - i); /* adj bc */
|
||||
rq_rw_end (cp, uptr, 0, ST_CMP); /* done */
|
||||
return SCPE_OK; /* exit */
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
} /* end else if */
|
||||
} /* end else read */
|
||||
}
|
||||
else if ((cmd == OP_CMP) && !err) { /* compare? */
|
||||
uint8 dby, mby;
|
||||
for (i = 0; i < tbc; i++) { /* loop */
|
||||
if (Map_ReadB (ba + i, 1, &mby)) { /* fetch, nxm? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - i); /* adj bc */
|
||||
PUTP32 (pkt, RW_WBAL, bc - i); /* adj ba */
|
||||
if (rq_hbe (cp, uptr)) /* post err log */
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_HST | SB_HST_NXM);
|
||||
return SCPE_OK;
|
||||
}
|
||||
dby = (((uint16 *)(uptr->rqxb))[i >> 1] >> ((i & 1)? 8: 0)) & 0xFF;
|
||||
if (mby != dby) { /* cmp err? */
|
||||
PUTP32 (pkt, RW_WBCL, bc - i); /* adj bc */
|
||||
rq_rw_end (cp, uptr, 0, ST_CMP); /* done */
|
||||
return SCPE_OK; /* exit */
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
} /* end else if */
|
||||
} /* end else read */
|
||||
} /* end else bottom end */
|
||||
if (err != 0) { /* error? */
|
||||
if (rq_dte (cp, uptr, ST_DRV)) /* post err log */
|
||||
rq_rw_end (cp, uptr, EF_LOG, ST_DRV); /* if ok, report err */
|
||||
perror ("RQ I/O error");
|
||||
clearerr (uptr->fileref);
|
||||
if (!(uptr->flags | UNIT_RAW))
|
||||
clearerr (uptr->fileref);
|
||||
return SCPE_IOERR;
|
||||
}
|
||||
ba = ba + tbc; /* incr bus addr */
|
||||
@@ -1793,7 +1935,7 @@ PUTP32 (pkt, RW_WBAL, ba); /* update pkt */
|
||||
PUTP32 (pkt, RW_WBCL, bc);
|
||||
PUTP32 (pkt, RW_WBLL, bl);
|
||||
if (bc) /* more? resched */
|
||||
sim_activate (uptr, rq_xtime);
|
||||
sim_activate (uptr, 0);
|
||||
else rq_rw_end (cp, uptr, 0, ST_SUC); /* done! */
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -1808,6 +1950,8 @@ uint32 bc = GETP32 (pkt, RW_BCL); /* init bc */
|
||||
uint32 wbc = GETP32 (pkt, RW_WBCL); /* work bc */
|
||||
DEVICE *dptr = rq_devmap[uptr->cnum];
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_rw_end\n");
|
||||
|
||||
uptr->cpkt = 0; /* done */
|
||||
PUTP32 (pkt, RW_BCL, bc - wbc); /* bytes processed */
|
||||
cp->pak[pkt].d[RW_WBAL] = 0; /* clear temps */
|
||||
@@ -1831,6 +1975,8 @@ t_bool rq_dte (MSC *cp, UNIT *uptr, uint32 err)
|
||||
int32 pkt, tpkt;
|
||||
uint32 lu, dtyp, lbn, ccyl, csurf, csect, t;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_dte\n");
|
||||
|
||||
if ((cp->cflgs & CF_THS) == 0) /* logging? */
|
||||
return OK;
|
||||
if (!rq_deqf (cp, &pkt)) /* get log pkt */
|
||||
@@ -1883,6 +2029,8 @@ t_bool rq_hbe (MSC *cp, UNIT *uptr)
|
||||
{
|
||||
int32 pkt, tpkt;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_hbe\n");
|
||||
|
||||
if ((cp->cflgs & CF_THS) == 0) /* logging? */
|
||||
return OK;
|
||||
if (!rq_deqf (cp, &pkt)) /* get log pkt */
|
||||
@@ -1912,6 +2060,8 @@ t_bool rq_plf (MSC *cp, uint32 err)
|
||||
{
|
||||
int32 pkt;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_plf\n");
|
||||
|
||||
if (!rq_deqf (cp, &pkt)) /* get log pkt */
|
||||
return ERR;
|
||||
cp->pak[pkt].d[ELP_REFL] = 0; /* ref = 0 */
|
||||
@@ -1933,12 +2083,13 @@ return rq_putpkt (cp, pkt, TRUE);
|
||||
|
||||
/* Unit now available attention packet */
|
||||
|
||||
int32 rq_una (MSC *cp, int32 un)
|
||||
t_bool rq_una (MSC *cp, int32 un)
|
||||
{
|
||||
int32 pkt;
|
||||
uint32 lu = cp->ubase + un;
|
||||
UNIT *uptr = rq_getucb (cp, lu);
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_una (Unit=%d)\n", lu);
|
||||
if (uptr == NULL) /* huh? */
|
||||
return OK;
|
||||
if (!rq_deqf (cp, &pkt)) /* get log pkt */
|
||||
@@ -2039,9 +2190,8 @@ DEVICE *dptr = rq_devmap[cp->cnum];
|
||||
|
||||
if (pkt == 0) /* any packet? */
|
||||
return OK;
|
||||
if (DEBUG_PRD (dptr))
|
||||
fprintf (sim_deb, ">>RQ%c: rsp=%04X, sts=%04X\n", 'A' + cp->cnum,
|
||||
cp->pak[pkt].d[RSP_OPF], cp->pak[pkt].d[RSP_STS]);
|
||||
sim_debug (DBG_REQ, dptr, "rsp=%04X, sts=%04X\n",
|
||||
cp->pak[pkt].d[RSP_OPF], cp->pak[pkt].d[RSP_STS]);
|
||||
if (!rq_getdesc (cp, &cp->rq, &desc)) /* get rsp desc */
|
||||
return ERR;
|
||||
if ((desc & UQ_DESC_OWN) == 0) { /* not valid? */
|
||||
@@ -2146,6 +2296,8 @@ void rq_putr_unit (MSC *cp, int32 pkt, UNIT *uptr, uint32 lu, t_bool all)
|
||||
uint32 dtyp = GET_DTYPE (uptr->flags); /* get drive type */
|
||||
uint32 maxlbn = (uint32) (uptr->capac / RQ_NUMBY); /* get max lbn */
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_putr_unit\n");
|
||||
|
||||
cp->pak[pkt].d[ONL_MLUN] = lu; /* unit */
|
||||
cp->pak[pkt].d[ONL_UFL] = uptr->uf | UF_RPL | RQ_WPH (uptr) | RQ_RMV (uptr);
|
||||
cp->pak[pkt].d[ONL_RSVL] = 0; /* reserved */
|
||||
@@ -2205,6 +2357,8 @@ return;
|
||||
|
||||
void rq_setint (MSC *cp)
|
||||
{
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_setint\n");
|
||||
|
||||
cp->irq = 1; /* set ctrl int */
|
||||
SET_INT (RQ); /* set master int */
|
||||
return;
|
||||
@@ -2217,6 +2371,8 @@ void rq_clrint (MSC *cp)
|
||||
int32 i;
|
||||
MSC *ncp;
|
||||
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_clrint\n");
|
||||
|
||||
cp->irq = 0; /* clr ctrl int */
|
||||
for (i = 0; i < RQ_NUMCT; i++) { /* loop thru ctrls */
|
||||
ncp = rq_ctxmap[i]; /* get context */
|
||||
@@ -2256,8 +2412,9 @@ t_bool rq_fatal (MSC *cp, uint32 err)
|
||||
{
|
||||
DEVICE *dptr = rq_devmap[cp->cnum];
|
||||
|
||||
if (DEBUG_PRD (dptr))
|
||||
fprintf (sim_deb, ">>RQ%c: fatal err=%X\n", 'A' + cp->cnum, err);
|
||||
sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_fatal\n");
|
||||
|
||||
sim_debug (DBG_REQ, dptr, "fatal err=%X\n", err);
|
||||
rq_reset (rq_devmap[cp->cnum]); /* reset device */
|
||||
cp->sa = SA_ER | err; /* SA = dead code */
|
||||
cp->csta = CST_DEAD; /* state = dead */
|
||||
@@ -2330,10 +2487,11 @@ t_stat rq_attach (UNIT *uptr, char *cptr)
|
||||
MSC *cp = rq_ctxmap[uptr->cnum];
|
||||
t_stat r;
|
||||
|
||||
r = attach_unit (uptr, cptr);
|
||||
r = sim_disk_attach (uptr, cptr, RQ_NUMBY, sizeof (uint16), (uptr->flags & UNIT_NOAUTO), DBG_DSK, drv_tab[GET_DTYPE (uptr->flags)].name, 0);
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
if (cp->csta == CST_UP)
|
||||
|
||||
if ((cp->csta == CST_UP) && sim_disk_isavailable (uptr))
|
||||
uptr->flags = uptr->flags | UNIT_ATP;
|
||||
return SCPE_OK;
|
||||
}
|
||||
@@ -2344,7 +2502,7 @@ t_stat rq_detach (UNIT *uptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
r = detach_unit (uptr); /* detach unit */
|
||||
r = sim_disk_detach (uptr); /* detach unit */
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
uptr->flags = uptr->flags & ~(UNIT_ONL | UNIT_ATP); /* clr onl, atn pend */
|
||||
@@ -2361,6 +2519,8 @@ UNIT *uptr;
|
||||
MSC *cp;
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
|
||||
sim_debug (DBG_TRC, dptr, "rq_reset\n");
|
||||
|
||||
for (i = 0, cidx = -1; i < RQ_NUMCT; i++) { /* find ctrl num */
|
||||
if (rq_devmap[i] == dptr)
|
||||
cidx = i;
|
||||
@@ -2408,11 +2568,10 @@ for (i = 0; i < (RQ_NUMDR + 2); i++) { /* init units */
|
||||
uptr->flags = uptr->flags & ~(UNIT_ONL | UNIT_ATP);
|
||||
uptr->uf = 0; /* clr unit flags */
|
||||
uptr->cpkt = uptr->pktq = 0; /* clr pkt q's */
|
||||
uptr->rqxb = (uint16 *) realloc (uptr->rqxb, (RQ_MAXFR >> 1) * sizeof (uint16));
|
||||
if (uptr->rqxb == NULL)
|
||||
return SCPE_MEM;
|
||||
}
|
||||
if (rqxb == NULL)
|
||||
rqxb = (uint16 *) calloc (RQ_MAXFR >> 1, sizeof (uint16));
|
||||
if (rqxb == NULL)
|
||||
return SCPE_MEM;
|
||||
return auto_config (0, 0); /* run autoconfig */
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ t_stat rx_wr (int32 data, int32 PA, int32 access);
|
||||
t_stat rx_svc (UNIT *uptr);
|
||||
t_stat rx_reset (DEVICE *dptr);
|
||||
t_stat rx_boot (int32 unitno, DEVICE *dptr);
|
||||
void rx_done (int esr_flags, int new_ecode);
|
||||
void rx_done (int32 esr_flags, int32 new_ecode);
|
||||
|
||||
/* RX11 data structures
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ t_stat ry_wr (int32 data, int32 PA, int32 access);
|
||||
t_stat ry_svc (UNIT *uptr);
|
||||
t_stat ry_reset (DEVICE *dptr);
|
||||
t_stat ry_boot (int32 unitno, DEVICE *dptr);
|
||||
void ry_done (int esr_flags, int new_ecode);
|
||||
void ry_done (int32 esr_flags, int32 new_ecode);
|
||||
t_stat ry_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
|
||||
t_stat ry_attach (UNIT *uptr, char *cptr);
|
||||
|
||||
|
||||
470
PDP11/pdp11_tq.c
470
PDP11/pdp11_tq.c
@@ -25,20 +25,23 @@
|
||||
|
||||
tq TQK50 tape controller
|
||||
|
||||
05-Mar-11 MP Added missing state for proper save/restore
|
||||
01-Mar-11 MP - Migrated complex physical tape activities to sim_tape
|
||||
- adopted use of asynch I/O interfaces from sim_tape
|
||||
- Added differing detailed debug output via sim_debug
|
||||
14-Jan-11 MP Various fixes discovered while exploring Ultrix issue:
|
||||
- Set UNIT_SXC flag when a tape mark is encountered
|
||||
during forward motion read operations
|
||||
during forward motion read operations.
|
||||
- Fixed logic which clears UNIT_SXC to check command
|
||||
modifier
|
||||
- Added CMF_WR flag to tq_cmf entry for OP_WTM
|
||||
- Made non-immediate rewind positioning operations
|
||||
take 2 seconds
|
||||
- Added UNIT_IDLE flag to tq units
|
||||
modifier.
|
||||
- Added CMF_WR flag to tq_cmf entry for OP_WTM.
|
||||
- Made Non-immediate rewind positioning operations
|
||||
take 2 seconds.
|
||||
- Added UNIT_IDLE flag to tq units.
|
||||
- Fixed debug output of tape file positions when they
|
||||
are 64b
|
||||
- Added more debug output after positioning operations.
|
||||
- Added textual display of the command being performed
|
||||
23-Dec-10 RMS Fixed comments about register addresses
|
||||
are 64b. Added more debug output after positioning
|
||||
operations. Also, added textual display of the
|
||||
command being performed (GUS,POS,RD,WR,etc…)
|
||||
18-Jun-07 RMS Added UNIT_IDLE flag to timer thread
|
||||
16-Feb-06 RMS Revised for new magtape capacity checking
|
||||
31-Oct-05 RMS Fixed address width for large files
|
||||
@@ -115,7 +118,10 @@ extern int32 cpu_opt;
|
||||
#define pktq u4 /* packet queue */
|
||||
#define uf buf /* settable unit flags */
|
||||
#define objp wait /* object position */
|
||||
#define io_status u5 /* io status from callback */
|
||||
#define io_complete u6 /* io completion flag */
|
||||
#define TQ_WPH(u) ((sim_tape_wrp (u))? UF_WPH: 0)
|
||||
#define results up7 /* xfer buffer & results */
|
||||
|
||||
#define CST_S1 0 /* init stage 1 */
|
||||
#define CST_S1_WR 1 /* stage 1 wrap */
|
||||
@@ -240,7 +246,6 @@ extern int32 tmr_poll, clk_tps;
|
||||
extern FILE *sim_deb;
|
||||
extern uint32 sim_taddr_64;
|
||||
|
||||
uint8 *tqxb = NULL; /* xfer buffer */
|
||||
uint32 tq_sa = 0; /* status, addr */
|
||||
uint32 tq_saw = 0; /* written data */
|
||||
uint32 tq_s1dat = 0; /* S1 data */
|
||||
@@ -340,7 +345,7 @@ DEVICE tq_dev;
|
||||
|
||||
t_stat tq_rd (int32 *data, int32 PA, int32 access);
|
||||
t_stat tq_wr (int32 data, int32 PA, int32 access);
|
||||
t_stat tq_inta (void);
|
||||
int32 tq_inta (void);
|
||||
t_stat tq_svc (UNIT *uptr);
|
||||
t_stat tq_tmrsvc (UNIT *uptr);
|
||||
t_stat tq_quesvc (UNIT *uptr);
|
||||
@@ -374,12 +379,10 @@ t_bool tq_dte (UNIT *uptr, uint32 err);
|
||||
t_bool tq_hbe (UNIT *uptr, uint32 ba);
|
||||
t_bool tq_una (UNIT *uptr);
|
||||
uint32 tq_map_status (UNIT *uptr, t_stat st);
|
||||
uint32 tq_spacef (UNIT *uptr, uint32 cnt, uint32 *skipped, t_bool qrec);
|
||||
uint32 tq_skipff (UNIT *uptr, uint32 cnt, uint32 *skipped);
|
||||
uint32 tq_rdbuff (UNIT *uptr, t_mtrlnt *tbc);
|
||||
uint32 tq_spacer (UNIT *uptr, uint32 cnt, uint32 *skipped, t_bool qrec);
|
||||
uint32 tq_skipfr (UNIT *uptr, uint32 cnt, uint32 *skipped);
|
||||
uint32 tq_rdbufr (UNIT *uptr, t_mtrlnt *tbc);
|
||||
void tq_rdbuff_top (UNIT *uptr, t_mtrlnt *tbc);
|
||||
uint32 tq_rdbuff_bottom (UNIT *uptr, t_mtrlnt *tbc);
|
||||
void tq_rdbufr_top (UNIT *uptr, t_mtrlnt *tbc);
|
||||
uint32 tq_rdbufr_bottom (UNIT *uptr, t_mtrlnt *tbc);
|
||||
t_bool tq_deqf (int32 *pkt);
|
||||
int32 tq_deqh (int32 *lh);
|
||||
void tq_enqh (int32 *lh, int32 pkt);
|
||||
@@ -429,9 +432,11 @@ REG tq_reg[] = {
|
||||
{ GRDATA (SA, tq_sa, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (SAW, tq_saw, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (S1DAT, tq_s1dat, DEV_RDX, 16, 0) },
|
||||
{ GRDATA (CQIOFF, tq_cq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (CQBA, tq_cq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (CQLNT, tq_cq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (CQIDX, tq_cq.idx, DEV_RDX, 8, 2) },
|
||||
{ GRDATA (TQIOFF, tq_rq.ioff, DEV_RDX, 32, 0) },
|
||||
{ GRDATA (TQBA, tq_rq.ba, DEV_RDX, 22, 0) },
|
||||
{ GRDATA (TQLNT, tq_rq.lnt, DEV_RDX, 8, 2), REG_NZ },
|
||||
{ GRDATA (TQIDX, tq_rq.idx, DEV_RDX, 8, 2) },
|
||||
@@ -504,12 +509,44 @@ MTAB tq_mod[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* debugging bitmaps */
|
||||
#define DBG_TRC 0x0001 /* trace routine calls */
|
||||
#define DBG_INI 0x0002 /* display setup/init sequence info */
|
||||
#define DBG_REG 0x0004 /* trace read/write registers */
|
||||
#define DBG_REQ 0x0008 /* display transfer requests */
|
||||
#define DBG_TAP 0x0010 /* display sim_tape activities */
|
||||
#define DBG_DAT 0x0020 /* display transfer data */
|
||||
|
||||
DEBTAB tq_debug[] = {
|
||||
{"TRACE", DBG_TRC},
|
||||
{"INIT", DBG_INI},
|
||||
{"REG", DBG_REG},
|
||||
{"REQ", DBG_REQ},
|
||||
{"TAPE", DBG_TAP},
|
||||
{"DATA", DBG_DAT},
|
||||
{0}
|
||||
};
|
||||
|
||||
DEVICE tq_dev = {
|
||||
"TQ", tq_unit, tq_reg, tq_mod,
|
||||
TQ_NUMDR + 2, 10, T_ADDR_W, 1, DEV_RDX, 8,
|
||||
NULL, NULL, &tq_reset,
|
||||
&tq_boot, &tq_attach, &tq_detach,
|
||||
&tq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG
|
||||
&tq_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG,
|
||||
0, tq_debug
|
||||
};
|
||||
|
||||
|
||||
struct tq_req_results { /* intermediate State during tape motion commands */
|
||||
t_stat io_status;
|
||||
int32 io_complete;
|
||||
int rewind_done;
|
||||
uint32 sts;
|
||||
uint32 sktmk;
|
||||
uint32 skrec;
|
||||
t_mtrlnt tbc;
|
||||
int32 objupd;
|
||||
uint8 tqxb[TQ_MAXFR];
|
||||
};
|
||||
|
||||
/* I/O dispatch routines, I/O addresses 17774500 - 17774502
|
||||
@@ -520,6 +557,8 @@ DEVICE tq_dev = {
|
||||
|
||||
t_stat tq_rd (int32 *data, int32 PA, int32 access)
|
||||
{
|
||||
sim_debug(DBG_REG, &tq_dev, "tq_rd(PA=0x%08X [%s], access=%d)\n", PA, ((PA >> 1) & 01) ? "IP" : "SA", access);
|
||||
|
||||
switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
case 0: /* IP */
|
||||
*data = 0; /* reads zero */
|
||||
@@ -541,13 +580,13 @@ return SCPE_OK;
|
||||
|
||||
t_stat tq_wr (int32 data, int32 PA, int32 access)
|
||||
{
|
||||
sim_debug(DBG_REG, &tq_dev, "tq_wr(PA=0x%08X [%s], access=%d)\n", PA, ((PA >> 1) & 01) ? "IP" : "SA", access);
|
||||
|
||||
switch ((PA >> 1) & 01) { /* decode PA<1> */
|
||||
|
||||
case 0: /* IP */
|
||||
tq_reset (&tq_dev); /* init device */
|
||||
if (DEBUG_PRS (tq_dev))
|
||||
fprintf (sim_deb, ">>TQ: initialization started, time=%.0f\n",
|
||||
sim_gtime ());
|
||||
sim_debug (DBG_REQ, &tq_dev, "initialization started\n");
|
||||
break;
|
||||
|
||||
case 1: /* SA */
|
||||
@@ -611,9 +650,12 @@ int32 i, cnid;
|
||||
int32 pkt = 0;
|
||||
UNIT *nuptr;
|
||||
|
||||
if (tq_csta < CST_UP) { /* still init? */
|
||||
switch (tq_csta) { /* controller state? */
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_quesvc\n");
|
||||
|
||||
if (tq_csta < CST_UP) { /* still init? */
|
||||
sim_debug(DBG_INI, &tq_dev, "CSTA=%d, SAW=0x%X\n", tq_csta, tq_saw);
|
||||
|
||||
switch (tq_csta) { /* controller state? */
|
||||
case CST_S1: /* need S1 reply */
|
||||
if (tq_saw & SA_S1H_VL) { /* valid? */
|
||||
if (tq_saw & SA_S1H_WR) { /* wrap? */
|
||||
@@ -661,8 +703,7 @@ if (tq_csta < CST_UP) { /* still init? */
|
||||
|
||||
case CST_S4: /* need S4 reply */
|
||||
if (tq_saw & SA_S4H_GO) { /* go set? */
|
||||
if (DEBUG_PRS (tq_dev))
|
||||
fprintf (sim_deb, ">>TQ: initialization complete\n");
|
||||
sim_debug (DBG_REQ, &tq_dev, "initialization complete\n");
|
||||
tq_csta = CST_UP; /* we're up */
|
||||
tq_sa = 0; /* clear SA */
|
||||
sim_activate (&tq_unit[TQ_TIMER], tmr_poll * clk_tps);
|
||||
@@ -687,21 +728,22 @@ if ((pkt == 0) && tq_pip) { /* polling? */
|
||||
if (!tq_getpkt (&pkt)) /* get host pkt */
|
||||
return SCPE_OK;
|
||||
if (pkt) { /* got one? */
|
||||
if (DEBUG_PRS (tq_dev)) {
|
||||
UNIT *up = tq_getucb (tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, ">>TQ: cmd=%04X(%3s), mod=%04X, unit=%d, ",
|
||||
tq_pkt[pkt].d[CMD_OPC], tq_cmdname[tq_pkt[pkt].d[CMD_OPC]&0x3f], tq_pkt[pkt].d[CMD_MOD], tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, "bc=%04X%04X, ma=%04X%04X",
|
||||
tq_pkt[pkt].d[RW_BCH], tq_pkt[pkt].d[RW_BCL],
|
||||
tq_pkt[pkt].d[RW_BAH], tq_pkt[pkt].d[RW_BAL]);
|
||||
if (up) {
|
||||
fprintf (sim_deb, ", pos=");
|
||||
fprint_val (sim_deb, up->pos, 10, T_ADDR_W, PV_LEFT);
|
||||
fprintf (sim_deb, ", obj=%d\n", up->objp);
|
||||
}
|
||||
else fprintf (sim_deb, "\n");
|
||||
fflush (sim_deb);
|
||||
}
|
||||
UNIT *up = tq_getucb (tq_pkt[pkt].d[CMD_UN]);
|
||||
|
||||
if (up)
|
||||
sim_debug (DBG_REQ, &tq_dev, "cmd=%04X(%3s), mod=%04X, unit=%d, bc=%04X%04X, ma=%04X%04X, obj=%d, pos=0x%X\n",
|
||||
tq_pkt[pkt].d[CMD_OPC], tq_cmdname[tq_pkt[pkt].d[CMD_OPC]&0x3f],
|
||||
tq_pkt[pkt].d[CMD_MOD], tq_pkt[pkt].d[CMD_UN],
|
||||
tq_pkt[pkt].d[RW_BCH], tq_pkt[pkt].d[RW_BCL],
|
||||
tq_pkt[pkt].d[RW_BAH], tq_pkt[pkt].d[RW_BAL],
|
||||
up->objp, up->pos);
|
||||
else
|
||||
sim_debug (DBG_REQ, &tq_dev, "cmd=%04X(%3s), mod=%04X, unit=%d, bc=%04X%04X, ma=%04X%04X\n",
|
||||
tq_pkt[pkt].d[CMD_OPC], tq_cmdname[tq_pkt[pkt].d[CMD_OPC]&0x3f],
|
||||
tq_pkt[pkt].d[CMD_MOD], tq_pkt[pkt].d[CMD_UN],
|
||||
tq_pkt[pkt].d[RW_BCH], tq_pkt[pkt].d[RW_BCL],
|
||||
tq_pkt[pkt].d[RW_BAH], tq_pkt[pkt].d[RW_BAL]);
|
||||
|
||||
if (GETP (pkt, UQ_HCTC, TYP) != UQ_TYP_SEQ) /* seq packet? */
|
||||
return tq_fatal (PE_PIE); /* no, term thread */
|
||||
cnid = GETP (pkt, UQ_HCTC, CID); /* get conn ID */
|
||||
@@ -735,6 +777,8 @@ t_stat tq_tmrsvc (UNIT *uptr)
|
||||
int32 i;
|
||||
UNIT *nuptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_tmrsvc\n");
|
||||
|
||||
sim_activate (uptr, tmr_poll * clk_tps); /* reactivate */
|
||||
for (i = 0; i < TQ_NUMDR; i++) { /* poll */
|
||||
nuptr = tq_dev.units + i;
|
||||
@@ -762,6 +806,8 @@ uint32 mdf = tq_pkt[pkt].d[CMD_MOD]; /* modifier */
|
||||
uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_mscp\n");
|
||||
|
||||
if ((cmd >= 64) || (tq_cmf[cmd] == 0)) { /* invalid cmd? */
|
||||
cmd = OP_END; /* set end op */
|
||||
sts = ST_CMD | I_OPCD; /* ill op */
|
||||
@@ -785,6 +831,7 @@ else { /* valid cmd */
|
||||
/* uptr->flags = uptr->flags & ~UNIT_CDL; */
|
||||
if ((mdf & MD_CSE) && (uptr->flags & UNIT_SXC)) /* clr ser exc? */
|
||||
uptr->flags = uptr->flags & ~UNIT_SXC;
|
||||
memset (uptr->results, 0, sizeof (struct tq_req_results)); /* init request state */
|
||||
}
|
||||
switch (cmd) {
|
||||
|
||||
@@ -852,6 +899,8 @@ uint32 ref = GETP32 (pkt, ABO_REFL); /* cmd ref # */
|
||||
int32 tpkt, prv;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_abo\n");
|
||||
|
||||
tpkt = 0; /* set no mtch */
|
||||
if (uptr = tq_getucb (lu)) { /* get unit */
|
||||
if (uptr->cpkt && /* curr pkt? */
|
||||
@@ -895,6 +944,8 @@ uint32 mdf = tq_pkt[pkt].d[CMD_MOD]; /* modifiers */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_avl\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
if (uptr->flags & UNIT_SXC) /* ser exc pending? */
|
||||
sts = ST_SXC;
|
||||
@@ -924,6 +975,8 @@ uint32 ref = GETP32 (pkt, GCS_REFL); /* ref # */
|
||||
int32 tpkt;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_gcs\n");
|
||||
|
||||
if ((uptr = tq_getucb (lu)) && /* valid lu? */
|
||||
(tpkt = uptr->cpkt) && /* queued pkt? */
|
||||
(GETP32 (tpkt, CMD_REFL) == ref) && /* match ref? */
|
||||
@@ -944,6 +997,8 @@ uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_gus\n");
|
||||
|
||||
if (tq_pkt[pkt].d[CMD_MOD] & MD_NXU) { /* next unit? */
|
||||
if (lu >= TQ_NUMDR) { /* end of range? */
|
||||
lu = 0; /* reset to 0 */
|
||||
@@ -975,6 +1030,8 @@ uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_onl\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||
sts = ST_OFL | SB_OFL_NV; /* offl no vol */
|
||||
@@ -999,6 +1056,8 @@ return tq_putpkt (pkt, TRUE);
|
||||
|
||||
t_bool tq_scc (int32 pkt)
|
||||
{
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_scc\n");
|
||||
|
||||
if (tq_pkt[pkt].d[SCC_MSV]) /* MSCP ver = 0? */
|
||||
tq_putr (pkt, 0, 0, ST_CMD | I_VRSN, SCC_LNT, UQ_TYP_SEQ);
|
||||
else {
|
||||
@@ -1028,6 +1087,8 @@ uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_suc\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||
sts = ST_OFL | SB_OFL_NV; /* offl no vol */
|
||||
@@ -1050,6 +1111,8 @@ uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_flu\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) /* unit exist? */
|
||||
sts = tq_mot_valid (uptr, OP_FLU); /* validate req */
|
||||
else sts = ST_OFL; /* offline */
|
||||
@@ -1066,11 +1129,14 @@ uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* opcode */
|
||||
uint32 sts;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_erase\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
sts = tq_mot_valid (uptr, cmd); /* validity checks */
|
||||
if (sts == ST_SUC) { /* ok? */
|
||||
uptr->cpkt = pkt; /* op in progress */
|
||||
sim_activate (uptr, tq_xtime); /* activate */
|
||||
uptr->iostarttime = sim_grtime();
|
||||
sim_activate (uptr, 0); /* activate */
|
||||
return OK; /* done */
|
||||
}
|
||||
}
|
||||
@@ -1087,12 +1153,15 @@ uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 sts, objp = 0;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_wtm\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
objp = uptr->objp; /* position op */
|
||||
sts = tq_mot_valid (uptr, OP_WTM); /* validity checks */
|
||||
if (sts == ST_SUC) { /* ok? */
|
||||
uptr->cpkt = pkt; /* op in progress */
|
||||
sim_activate (uptr, tq_xtime); /* activate */
|
||||
uptr->iostarttime = sim_grtime();
|
||||
sim_activate (uptr, 0); /* activate */
|
||||
return OK; /* done */
|
||||
}
|
||||
}
|
||||
@@ -1110,6 +1179,8 @@ uint32 lu = tq_pkt[pkt].d[CMD_UN]; /* unit # */
|
||||
uint32 sts, objp = 0;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_pos\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
objp = uptr->objp; /* position op */
|
||||
sts = tq_mot_valid (uptr, OP_POS); /* validity checks */
|
||||
@@ -1119,8 +1190,10 @@ if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
if ((tq_pkt[pkt].d[CMD_MOD] & MD_RWD) && /* rewind? */
|
||||
(!(tq_pkt[pkt].d[CMD_MOD] & MD_IMM))) /* !immediate? */
|
||||
sim_activate (uptr, tq_rwtime); /* use 2 sec rewind execute time */
|
||||
else /* otherwise */
|
||||
sim_activate (uptr, tq_xtime); /* use normal execute time */
|
||||
else { /* otherwise */
|
||||
uptr->iostarttime = sim_grtime();
|
||||
sim_activate (uptr, 0); /* use normal execute time */
|
||||
}
|
||||
return OK; /* done */
|
||||
}
|
||||
}
|
||||
@@ -1142,6 +1215,8 @@ uint32 bc = GETP32 (pkt, RW_BCL); /* byte count */
|
||||
uint32 sts, objp = 0;
|
||||
UNIT *uptr;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_rw\n");
|
||||
|
||||
if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
objp = uptr->objp; /* position op */
|
||||
sts = tq_mot_valid (uptr, cmd); /* validity checks */
|
||||
@@ -1152,7 +1227,8 @@ if (uptr = tq_getucb (lu)) { /* unit exist? */
|
||||
}
|
||||
else {
|
||||
uptr->cpkt = pkt; /* op in progress */
|
||||
sim_activate (uptr, tq_xtime); /* activate */
|
||||
uptr->iostarttime = sim_grtime();
|
||||
sim_activate (uptr, 0); /* activate */
|
||||
return OK; /* done */
|
||||
}
|
||||
}
|
||||
@@ -1169,6 +1245,8 @@ return tq_putpkt (pkt, TRUE);
|
||||
|
||||
int32 tq_mot_valid (UNIT *uptr, uint32 cmd)
|
||||
{
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_mot_valid\n");
|
||||
|
||||
if (uptr->flags & UNIT_SXC) /* ser exc pend? */
|
||||
return ST_SXC;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||
@@ -1190,10 +1268,28 @@ return ST_SUC; /* success! */
|
||||
|
||||
/* Unit service for motion commands */
|
||||
|
||||
/* I/O completion callback */
|
||||
|
||||
void tq_io_complete (UNIT *uptr, t_stat status)
|
||||
{
|
||||
struct tq_req_results *res = (struct tq_req_results *)uptr->results;
|
||||
int32 elapsed = sim_grtime()-uptr->iostarttime;
|
||||
|
||||
sim_debug(DBG_TRC, &tq_dev, "tq_io_complete(status=%d)\n", status);
|
||||
|
||||
res->io_status = status;
|
||||
res->io_complete = 1;
|
||||
if (elapsed > tq_xtime)
|
||||
sim_activate (uptr, 0);
|
||||
else
|
||||
sim_activate (uptr, tq_xtime-elapsed);
|
||||
}
|
||||
|
||||
|
||||
t_stat tq_svc (UNIT *uptr)
|
||||
{
|
||||
uint32 t, sts, sktmk, skrec;
|
||||
t_mtrlnt i, tbc, wbc;
|
||||
uint32 t;
|
||||
t_mtrlnt wbc;
|
||||
int32 pkt = uptr->cpkt; /* get packet */
|
||||
uint32 cmd = GETP (pkt, CMD_OPC, OPC); /* get cmd */
|
||||
uint32 mdf = tq_pkt[pkt].d[CMD_MOD]; /* modifier */
|
||||
@@ -1201,7 +1297,14 @@ uint32 ba = GETP32 (pkt, RW_BAL); /* buf addr */
|
||||
t_mtrlnt bc = GETP32 (pkt, RW_BCL); /* byte count */
|
||||
uint32 nrec = GETP32 (pkt, POS_RCL); /* #rec to skip */
|
||||
uint32 ntmk = GETP32 (pkt, POS_TMCL); /* #tmk to skp */
|
||||
struct tq_req_results *res = (struct tq_req_results *)uptr->results;
|
||||
int32 io_complete = res->io_complete;
|
||||
|
||||
sim_debug (DBG_TRC, &tq_dev, "tq_svc(unit=%d, pkt=%d, cmd=%s, mdf=0x%0X, bc=0x%0x, phase=%s)\n",
|
||||
uptr-tq_dev.units, pkt, tq_cmdname[tq_pkt[pkt].d[CMD_OPC]&0x3f], mdf, bc,
|
||||
uptr->io_complete ? "bottom" : "top");
|
||||
|
||||
res->io_complete = 0;
|
||||
if (pkt == 0) /* what??? */
|
||||
return SCPE_IERR;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
|
||||
@@ -1221,60 +1324,71 @@ if (tq_cmf[cmd] & CMF_WR) { /* write op? */
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
sts = ST_SUC; /* assume success */
|
||||
tbc = 0; /* assume zero rec */
|
||||
if (!io_complete) {
|
||||
res->sts = ST_SUC; /* assume success */
|
||||
res->tbc = 0; /* assume zero rec */
|
||||
}
|
||||
switch (cmd) { /* case on command */
|
||||
|
||||
case OP_RD:case OP_ACC:case OP_CMP: /* read-like op */
|
||||
if (mdf & MD_REV) /* read record */
|
||||
sts = tq_rdbufr (uptr, &tbc);
|
||||
else sts = tq_rdbuff (uptr, &tbc);
|
||||
if (sts == ST_DRV) { /* read error? */
|
||||
PUTP32 (pkt, RW_BCL, 0); /* no bytes processed */
|
||||
return tq_mot_err (uptr, tbc); /* log, done */
|
||||
if (!io_complete) {
|
||||
if (mdf & MD_REV) /* read record */
|
||||
tq_rdbufr_top (uptr, &res->tbc);
|
||||
else
|
||||
tq_rdbuff_top (uptr, &res->tbc);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if ((sts != ST_SUC) || (cmd == OP_ACC)) { /* error or access? */
|
||||
if (sts == ST_TMK)
|
||||
if (mdf & MD_REV) /* read record */
|
||||
res->sts = tq_rdbufr_bottom (uptr, &res->tbc);
|
||||
else
|
||||
res->sts = tq_rdbuff_bottom (uptr, &res->tbc);
|
||||
if (res->sts == ST_DRV) { /* read error? */
|
||||
PUTP32 (pkt, RW_BCL, 0); /* no bytes processed */
|
||||
return tq_mot_err (uptr, res->tbc); /* log, done */
|
||||
}
|
||||
if ((res->sts != ST_SUC) || (cmd == OP_ACC)) { /* error or access? */
|
||||
if (res->sts == ST_TMK)
|
||||
uptr->flags = uptr->flags | UNIT_SXC; /* set ser exc */
|
||||
PUTP32 (pkt, RW_BCL, 0); /* no bytes processed */
|
||||
break;
|
||||
}
|
||||
if (tbc > bc) { /* tape rec > buf? */
|
||||
if (res->tbc > bc) { /* tape rec > buf? */
|
||||
uptr->flags = uptr->flags | UNIT_SXC; /* serious exc */
|
||||
sts = ST_RDT; /* data truncated */
|
||||
res->sts = ST_RDT; /* data truncated */
|
||||
wbc = bc; /* set working bc */
|
||||
}
|
||||
else wbc = tbc;
|
||||
else wbc = res->tbc;
|
||||
if (cmd == OP_RD) { /* read? */
|
||||
if (t = Map_WriteB (ba, wbc, tqxb)) { /* store, nxm? */
|
||||
if (t = Map_WriteB (ba, wbc, res->tqxb)) { /* store, nxm? */
|
||||
PUTP32 (pkt, RW_BCL, wbc - t); /* adj bc */
|
||||
if (tq_hbe (uptr, ba + wbc - t)) /* post err log */
|
||||
tq_mot_end (uptr, EF_LOG, ST_HST | SB_HST_NXM, tbc);
|
||||
tq_mot_end (uptr, EF_LOG, ST_HST | SB_HST_NXM, res->tbc);
|
||||
return SCPE_OK; /* end if nxm */
|
||||
}
|
||||
} /* end if read */
|
||||
else { /* compare */
|
||||
uint8 mby, dby;
|
||||
uint32 mba;
|
||||
t_mtrlnt i;
|
||||
for (i = 0; i < wbc; i++) { /* loop */
|
||||
if (mdf & MD_REV) { /* reverse? */
|
||||
mba = ba + bc - 1 - i; /* mem addr */
|
||||
dby = tqxb[tbc - 1 - i]; /* byte */
|
||||
dby = ((uint8 *)res->tqxb)[res->tbc - 1 - i]; /* byte */
|
||||
}
|
||||
else {
|
||||
mba = ba + i;
|
||||
dby = tqxb[i];
|
||||
dby = ((uint8 *)res->tqxb)[i];
|
||||
}
|
||||
if (Map_ReadB (mba, 1, &mby)) { /* fetch, nxm? */
|
||||
PUTP32 (pkt, RW_BCL, i); /* adj bc */
|
||||
if (tq_hbe (uptr, mba)) /* post err log */
|
||||
tq_mot_end (uptr, EF_LOG, ST_HST | SB_HST_NXM, tbc);
|
||||
tq_mot_end (uptr, EF_LOG, ST_HST | SB_HST_NXM, res->tbc);
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (mby != dby) { /* cmp err? */
|
||||
uptr->flags = uptr->flags | UNIT_SXC; /* ser exc */
|
||||
PUTP32 (pkt, RW_BCL, i); /* adj bc */
|
||||
tq_mot_end (uptr, 0, ST_CMP, tbc);
|
||||
tq_mot_end (uptr, 0, ST_CMP, res->tbc);
|
||||
return SCPE_OK; /* exit */
|
||||
}
|
||||
} /* end for */
|
||||
@@ -1283,23 +1397,31 @@ switch (cmd) { /* case on command */
|
||||
break;
|
||||
|
||||
case OP_WR: /* write */
|
||||
if (t = Map_ReadB (ba, bc, tqxb)) { /* fetch buf, nxm? */
|
||||
PUTP32 (pkt, RW_BCL, 0); /* no bytes xfer'd */
|
||||
if (tq_hbe (uptr, ba + bc - t)) /* post err log */
|
||||
tq_mot_end (uptr, EF_LOG, ST_HST | SB_HST_NXM, bc);
|
||||
return SCPE_OK; /* end else wr */
|
||||
}
|
||||
if (sim_tape_wrrecf (uptr, tqxb, bc)) /* write rec fwd, err? */
|
||||
if (!io_complete) { /* Top half processing */
|
||||
if (t = Map_ReadB (ba, bc, res->tqxb)) { /* fetch buf, nxm? */
|
||||
PUTP32 (pkt, RW_BCL, 0); /* no bytes xfer'd */
|
||||
if (tq_hbe (uptr, ba + bc - t)) /* post err log */
|
||||
tq_mot_end (uptr, EF_LOG, ST_HST | SB_HST_NXM, bc);
|
||||
return SCPE_OK; /* end else wr */
|
||||
}
|
||||
sim_tape_wrrecf_a (uptr, res->tqxb, bc, tq_io_complete); /* write rec fwd */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (res->io_status)
|
||||
return tq_mot_err (uptr, bc); /* log, end */
|
||||
uptr->objp = uptr->objp + 1; /* upd obj pos */
|
||||
if (TEST_EOT (uptr)) /* EOT on write? */
|
||||
uptr->flags = uptr->flags | UNIT_SXC;
|
||||
uptr->flags = uptr->flags & ~UNIT_TMK; /* disable LEOT */
|
||||
tbc = bc; /* RW_BC is ok */
|
||||
res->tbc = bc; /* RW_BC is ok */
|
||||
break;
|
||||
|
||||
case OP_WTM: /* write tape mark */
|
||||
if (sim_tape_wrtmk (uptr)) /* write tmk, err? */
|
||||
if (!io_complete) { /* Top half processing */
|
||||
sim_tape_wrtmk_a (uptr, tq_io_complete); /* write tmk, err? */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (res->io_status)
|
||||
return tq_mot_err (uptr, 0); /* log, end */
|
||||
uptr->objp = uptr->objp + 1; /* incr obj cnt */
|
||||
case OP_ERG: /* erase gap */
|
||||
@@ -1309,51 +1431,47 @@ switch (cmd) { /* case on command */
|
||||
break;
|
||||
|
||||
case OP_ERS: /* erase */
|
||||
if (sim_tape_wreom (uptr)) /* write eom, err? */
|
||||
if (!io_complete) { /* Top half processing */
|
||||
sim_tape_wreomrw_a (uptr, tq_io_complete); /* write eom, err? */
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (res->io_status)
|
||||
return tq_mot_err (uptr, 0); /* log, end */
|
||||
sim_tape_rewind (uptr); /* rewind */
|
||||
uptr->objp = 0;
|
||||
uptr->flags = uptr->flags & ~(UNIT_TMK | UNIT_POL);
|
||||
break;
|
||||
|
||||
case OP_POS: /* position */
|
||||
sktmk = skrec = 0; /* clr skipped */
|
||||
if (mdf & MD_RWD) { /* rewind? */
|
||||
sim_tape_rewind (uptr);
|
||||
uptr->objp = 0; /* clr flags */
|
||||
uptr->flags = uptr->flags & ~(UNIT_TMK | UNIT_POL);
|
||||
}
|
||||
if (mdf & MD_OBC) { /* skip obj? */
|
||||
if (mdf & MD_REV) /* reverse? */
|
||||
sts = tq_spacer (uptr, nrec, &skrec, FALSE);
|
||||
else sts = tq_spacef (uptr, nrec, &skrec, FALSE);
|
||||
}
|
||||
else { /* skip tmk, rec */
|
||||
if (mdf & MD_REV)
|
||||
sts = tq_skipfr (uptr, ntmk, &sktmk);
|
||||
else sts = tq_skipff (uptr, ntmk, &sktmk);
|
||||
if (sts == ST_SUC) { /* tmk succeed? */
|
||||
if (mdf & MD_REV) /* reverse? */
|
||||
sts = tq_spacer (uptr, nrec, &skrec, TRUE);
|
||||
else sts = tq_spacef (uptr, nrec, &skrec, TRUE);
|
||||
if (sts == ST_TMK)
|
||||
sktmk = sktmk + 1;
|
||||
if (!io_complete) { /* Top half processing */
|
||||
res->sktmk = res->skrec = 0; /* clr skipped */
|
||||
if (mdf & MD_RWD) { /* rewind? */
|
||||
uptr->objp = 0; /* clr flags */
|
||||
uptr->flags = uptr->flags & ~(UNIT_TMK | UNIT_POL);
|
||||
}
|
||||
sim_tape_position_a (uptr,
|
||||
((mdf & MD_RWD) ? MTPOS_M_REW : 0) |
|
||||
((mdf & MD_REV) ? MTPOS_M_REV : 0) |
|
||||
((mdf & MD_OBC) ? MTPOS_M_OBJ : 0) ,
|
||||
nrec, &res->skrec, ntmk, &res->sktmk, (uint32 *)&res->objupd, tq_io_complete);
|
||||
return SCPE_OK;
|
||||
}
|
||||
PUTP32 (pkt, POS_RCL, skrec); /* #rec skipped */
|
||||
PUTP32 (pkt, POS_TMCL, sktmk); /* #tmk skipped */
|
||||
if (DEBUG_PRS (tq_dev)) {
|
||||
fprintf (sim_deb, ">>TQ: Position Done: mdf=%04X, nrec=%04X, ntmk=%04X, skrec=%04X, sktmk=%04X\n",
|
||||
mdf, nrec, ntmk, skrec, sktmk);
|
||||
fflush (sim_deb);
|
||||
}
|
||||
if (res->io_status)
|
||||
return tq_mot_err (uptr, 0); /* log, end */
|
||||
sim_debug (DBG_REQ, &tq_dev, "Position Done: mdf=0x%04X, nrec=%d, ntmk=%d, skrec=%d, sktmk=%d, skobj=%d\n",
|
||||
mdf, nrec, ntmk, res->skrec, res->sktmk, res->objupd);
|
||||
if (mdf & MD_REV)
|
||||
uptr->objp = uptr->objp - res->objupd;
|
||||
else
|
||||
uptr->objp = uptr->objp + res->objupd;
|
||||
PUTP32 (pkt, POS_RCL, res->skrec); /* #rec skipped */
|
||||
PUTP32 (pkt, POS_TMCL, res->sktmk); /* #tmk skipped */
|
||||
break;
|
||||
|
||||
default:
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
tq_mot_end (uptr, 0, sts, tbc); /* done */
|
||||
tq_mot_end (uptr, 0, res->sts, res->tbc); /* done */
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@@ -1445,90 +1563,21 @@ switch (st) {
|
||||
return ST_SUC;
|
||||
}
|
||||
|
||||
uint32 tq_spacef (UNIT *uptr, uint32 cnt, uint32 *skipped, t_bool qrec)
|
||||
{
|
||||
t_stat st;
|
||||
t_mtrlnt tbc;
|
||||
|
||||
*skipped = 0;
|
||||
while (*skipped < cnt) { /* loop */
|
||||
st = sim_tape_sprecf (uptr, &tbc); /* space rec fwd */
|
||||
if ((st != MTSE_OK) && (st != MTSE_TMK)) /* real error? */
|
||||
return tq_map_status (uptr, st); /* map status */
|
||||
uptr->objp = uptr->objp + 1; /* upd obj cnt */
|
||||
if (st == MTSE_TMK) { /* tape mark? */
|
||||
int32 pkt = uptr->cpkt; /* get pkt */
|
||||
if ((tq_pkt[pkt].d[CMD_MOD] & MD_DLE) && /* LEOT? */
|
||||
(uptr->flags & UNIT_TMK)) {
|
||||
sim_tape_sprecr (uptr, &tbc); /* rev over tmk */
|
||||
uptr->flags = uptr->flags | UNIT_SXC; /* serious exc */
|
||||
return ST_LED;
|
||||
}
|
||||
uptr->flags = uptr->flags | UNIT_TMK; /* set TM seen */
|
||||
if (qrec) /* rec spc? stop */
|
||||
return ST_TMK;
|
||||
}
|
||||
else uptr->flags = uptr->flags & ~UNIT_TMK; /* clr TM seen */
|
||||
*skipped = *skipped + 1; /* # obj skipped */
|
||||
}
|
||||
return ST_SUC;
|
||||
}
|
||||
|
||||
uint32 tq_skipff (UNIT *uptr, uint32 cnt, uint32 *skipped)
|
||||
{
|
||||
uint32 st, skrec;
|
||||
|
||||
*skipped = 0;
|
||||
while (*skipped < cnt) { /* loop */
|
||||
st = tq_spacef (uptr, 0x7FFFFFFF, &skrec, TRUE); /* rec spc fwd */
|
||||
if (st == ST_TMK) /* count files */
|
||||
*skipped = *skipped + 1;
|
||||
else if (st != ST_SUC)
|
||||
return st;
|
||||
}
|
||||
return ST_SUC;
|
||||
}
|
||||
|
||||
uint32 tq_spacer (UNIT *uptr, uint32 cnt, uint32 *skipped, t_bool qrec)
|
||||
{
|
||||
t_stat st;
|
||||
t_mtrlnt tbc;
|
||||
|
||||
*skipped = 0;
|
||||
while (*skipped < cnt) { /* loop */
|
||||
st = sim_tape_sprecr (uptr, &tbc); /* spc rec rev */
|
||||
if ((st != MTSE_OK) && (st != MTSE_TMK)) /* real error? */
|
||||
return tq_map_status (uptr, st); /* map status */
|
||||
uptr->objp = uptr->objp - 1; /* upd obj cnt */
|
||||
if ((st == MTSE_TMK) && qrec) /* tape mark, stop? */
|
||||
return ST_TMK;
|
||||
*skipped = *skipped + 1; /* # obj skipped */
|
||||
}
|
||||
return ST_SUC;
|
||||
}
|
||||
|
||||
uint32 tq_skipfr (UNIT *uptr, uint32 cnt, uint32 *skipped)
|
||||
{
|
||||
uint32 st, skrec;
|
||||
|
||||
*skipped = 0;
|
||||
while (*skipped < cnt) { /* loopo */
|
||||
st = tq_spacer (uptr, 0x7FFFFFFF, &skrec, TRUE); /* rec spc rev */
|
||||
if (st == ST_TMK) /* tape mark? */
|
||||
*skipped = *skipped + 1;
|
||||
else if (st != 0) /* error? */
|
||||
return st;
|
||||
}
|
||||
return ST_SUC;
|
||||
}
|
||||
|
||||
/* Read buffer - can return ST_TMK, ST_FMT, or ST_DRV */
|
||||
|
||||
uint32 tq_rdbuff (UNIT *uptr, t_mtrlnt *tbc)
|
||||
void tq_rdbuff_top (UNIT *uptr, t_mtrlnt *tbc)
|
||||
{
|
||||
struct tq_req_results *res = (struct tq_req_results *)uptr->results;
|
||||
|
||||
sim_tape_rdrecf_a (uptr, res->tqxb, tbc, MT_MAXFR, tq_io_complete);/* read rec fwd */
|
||||
}
|
||||
|
||||
uint32 tq_rdbuff_bottom (UNIT *uptr, t_mtrlnt *tbc)
|
||||
{
|
||||
t_stat st;
|
||||
struct tq_req_results *res = (struct tq_req_results *)uptr->results;
|
||||
|
||||
st = sim_tape_rdrecf (uptr, tqxb, tbc, MT_MAXFR); /* read rec fwd */
|
||||
st = res->io_status; /* read rec fwd io status */
|
||||
if (st == MTSE_TMK) { /* tape mark? */
|
||||
uptr->flags = uptr->flags | UNIT_SXC | UNIT_TMK; /* serious exc */
|
||||
uptr->objp = uptr->objp + 1; /* update obj cnt */
|
||||
@@ -1541,11 +1590,19 @@ uptr->objp = uptr->objp + 1; /* upd obj cnt */
|
||||
return ST_SUC;
|
||||
}
|
||||
|
||||
uint32 tq_rdbufr (UNIT *uptr, t_mtrlnt *tbc)
|
||||
void tq_rdbufr_top (UNIT *uptr, t_mtrlnt *tbc)
|
||||
{
|
||||
struct tq_req_results *res = (struct tq_req_results *)uptr->results;
|
||||
|
||||
sim_tape_rdrecr_a (uptr, res->tqxb, tbc, MT_MAXFR, tq_io_complete); /* read rec rev */
|
||||
}
|
||||
|
||||
uint32 tq_rdbufr_bottom (UNIT *uptr, t_mtrlnt *tbc)
|
||||
{
|
||||
t_stat st;
|
||||
struct tq_req_results *res = (struct tq_req_results *)uptr->results;
|
||||
|
||||
st = sim_tape_rdrecr (uptr, tqxb, tbc, MT_MAXFR); /* read rec rev */
|
||||
st = res->io_status; /* read rec rev io status */
|
||||
if (st == MTSE_TMK) { /* tape mark? */
|
||||
uptr->flags = uptr->flags | UNIT_SXC; /* serious exc */
|
||||
uptr->objp = uptr->objp - 1; /* update obj cnt */
|
||||
@@ -1645,7 +1702,7 @@ return tq_putpkt (pkt, TRUE);
|
||||
|
||||
/* Unit now available attention packet */
|
||||
|
||||
int32 tq_una (UNIT *uptr)
|
||||
t_bool tq_una (UNIT *uptr)
|
||||
{
|
||||
int32 pkt;
|
||||
uint32 lu;
|
||||
@@ -1744,21 +1801,17 @@ return tq_putdesc (&tq_cq, desc); /* release desc */
|
||||
t_bool tq_putpkt (int32 pkt, t_bool qt)
|
||||
{
|
||||
uint32 addr, desc, lnt, cr;
|
||||
UNIT *up = tq_getucb (tq_pkt[pkt].d[CMD_UN]);
|
||||
|
||||
if (pkt == 0) /* any packet? */
|
||||
return OK;
|
||||
if (DEBUG_PRS (tq_dev)) {
|
||||
UNIT *up = tq_getucb (tq_pkt[pkt].d[CMD_UN]);
|
||||
fprintf (sim_deb, ">>TQ: rsp=%04X, sts=%04X",
|
||||
tq_pkt[pkt].d[RSP_OPF], tq_pkt[pkt].d[RSP_STS]);
|
||||
if (up) {
|
||||
fprintf (sim_deb, ", pos=");
|
||||
fprint_val (sim_deb, up->pos, 10, T_ADDR_W, PV_LEFT);
|
||||
fprintf (sim_deb, ", obj=%d\n", up->objp);
|
||||
}
|
||||
else fprintf (sim_deb, "\n");
|
||||
fflush (sim_deb);
|
||||
}
|
||||
if (up)
|
||||
sim_debug (DBG_REQ, &tq_dev, "rsp=%04X, sts=%04X, rszl=%04X, obj=%d, pos=%d\n",
|
||||
tq_pkt[pkt].d[RSP_OPF], tq_pkt[pkt].d[RSP_STS], tq_pkt[pkt].d[RW_RSZL],
|
||||
up->objp, up->pos);
|
||||
else
|
||||
sim_debug (DBG_REQ, &tq_dev, "rsp=%04X, sts=%04X\n",
|
||||
tq_pkt[pkt].d[RSP_OPF], tq_pkt[pkt].d[RSP_STS]);
|
||||
if (!tq_getdesc (&tq_rq, &desc)) /* get rsp desc */
|
||||
return ERR;
|
||||
if ((desc & UQ_DESC_OWN) == 0) { /* not valid? */
|
||||
@@ -1944,8 +1997,9 @@ return tq_dib.vec; /* prog vector */
|
||||
|
||||
t_bool tq_fatal (uint32 err)
|
||||
{
|
||||
if (DEBUG_PRS (tq_dev))
|
||||
fprintf (sim_deb, ">>TQ: fatal err=%X\n", err);
|
||||
sim_debug (DBG_TRC, &tq_dev, "tq_fatal\n");
|
||||
|
||||
sim_debug (DBG_REQ, &tq_dev, "fatal err=%X\n", err);
|
||||
tq_reset (&tq_dev); /* reset device */
|
||||
tq_sa = SA_ER | err; /* SA = dead code */
|
||||
tq_csta = CST_DEAD; /* state = dead */
|
||||
@@ -1959,7 +2013,7 @@ t_stat tq_attach (UNIT *uptr, char *cptr)
|
||||
{
|
||||
t_stat r;
|
||||
|
||||
r = sim_tape_attach (uptr, cptr);
|
||||
r = sim_tape_attach_ex (uptr, cptr, DBG_TAP);
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
if (tq_csta == CST_UP)
|
||||
@@ -2020,11 +2074,11 @@ for (i = 0; i < TQ_NUMDR + 2; i++) { /* init units */
|
||||
~(UNIT_ONL|UNIT_ATP|UNIT_SXC|UNIT_POL|UNIT_TMK);
|
||||
uptr->uf = 0; /* clr unit flags */
|
||||
uptr->cpkt = uptr->pktq = 0; /* clr pkt q's */
|
||||
if (uptr->results == NULL)
|
||||
uptr->results = calloc (1, sizeof (struct tq_req_results));
|
||||
if (uptr->results == NULL)
|
||||
return SCPE_MEM;
|
||||
}
|
||||
if (tqxb == NULL)
|
||||
tqxb = (uint8 *) calloc (TQ_MAXFR, sizeof (uint8));
|
||||
if (tqxb == NULL)
|
||||
return SCPE_MEM;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -598,7 +598,7 @@ return MBE_GOE;
|
||||
|
||||
/* Abort transfer */
|
||||
|
||||
t_stat tu_abort (void)
|
||||
int32 tu_abort (void)
|
||||
{
|
||||
return tu_reset (&tu_dev);
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ struct xq_device {
|
||||
ETH_PACK read_buffer;
|
||||
ETH_PACK write_buffer;
|
||||
ETH_QUE ReadQ;
|
||||
uint32 idtmr; /* countdown for ID Timer */
|
||||
int32 idtmr; /* countdown for ID Timer */
|
||||
uint32 must_poll; /* receiver must poll instead of counting on asynch polls */
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user