1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-26 16:53:58 +00:00

KA10: Dectapes only write back if modified.

This commit is contained in:
Richard Cornwell
2020-02-22 21:36:32 -05:00
parent af93029da2
commit 3479d2988e
2 changed files with 238 additions and 201 deletions

View File

@@ -169,6 +169,7 @@
#define DTC_FWDRV 0200000 /* Move unit forward */
#define DTC_STSTOP 0400000 /* Stop unit */
#define CMD u3
/* Flags in lower bits of u3 */
#define DTC_FNC_STOP 001 /* Unit stopping */
#define DTC_FNC_START 002 /* Start unit motion */
@@ -252,6 +253,8 @@
#define DT_WRDTIM 10000
#define WRITTEN u6 /* Set when tape modified */
int32 dtsa = 0; /* status A */
uint64 dtsb = 0; /* status B */
uint64 dtdb = 0; /* data buffer */
@@ -262,6 +265,7 @@ t_stat dt_svc (UNIT *uptr);
t_stat dt_boot(int32 unit_num, DEVICE * dptr);
t_stat dt_reset (DEVICE *dptr);
t_stat dt_attach (UNIT *uptr, CONST char *cptr);
void dt_flush (UNIT *uptr);
t_stat dt_detach (UNIT *uptr);
#if MPX_DEV
t_stat dt_set_mpx (UNIT *uptr, int32 val, CONST char *cptr, void *desc) ;
@@ -369,7 +373,7 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
/* Stop all drives and clear drive unit */
dtsa &= 0770777;
for (i = 0; i < DT_NUMDR; i++) {
dt_unit[i].u3 &= ~0700;
dt_unit[i].CMD &= ~0700;
}
if ((*data & DTC_SEL) == 0)
break;
@@ -426,14 +430,14 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
}
if (*data & DTC_STSTOP) {
if ((dt_unit[i].DSTATE & (DTC_MOT)) != 0) {
dt_unit[i].u3 |= DTC_FNC_STOP;
dt_unit[i].CMD |= DTC_FNC_STOP;
}
dtsa &=~ (DTC_FWDRV|DTC_RVDRV);
} else {
/* Start the unit if not already running */
dt_unit[i].u3 &= ~DTC_FNC_STOP;
dt_unit[i].CMD &= ~DTC_FNC_STOP;
if ((dt_unit[i].DSTATE & (DTC_MOT)) == 0) {
dt_unit[i].u3 |= DTC_FNC_START;
dt_unit[i].CMD |= DTC_FNC_START;
dtsb |= DTB_DLY;
if (!sim_is_active(&dt_unit[i]))
sim_activate(&dt_unit[i], 10000);
@@ -442,20 +446,20 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
switch(*data & (DTC_FWDRV|DTC_RVDRV)) {
case DTC_FWDRV:
if (dt_unit[i].DSTATE & DTC_REV) {
dt_unit[i].u3 |= DTC_FNC_REV;
dt_unit[i].CMD |= DTC_FNC_REV;
dtsa |= (DTC_RVDRV);
} else
dtsa |= (DTC_FWDRV);
break;
case DTC_RVDRV:
if ((dt_unit[i].DSTATE & DTC_REV) == 0) {
dt_unit[i].u3 |= DTC_FNC_REV;
dt_unit[i].CMD |= DTC_FNC_REV;
dtsa |= (DTC_RVDRV);
} else
dtsa |= (DTC_FWDRV);
break;
case DTC_FWDRV|DTC_RVDRV:
dt_unit[i].u3 |= DTC_FNC_REV;
dt_unit[i].CMD |= DTC_FNC_REV;
if ((dt_unit[i].DSTATE & DTC_REV) == 0)
dtsa |= (DTC_RVDRV);
else
@@ -500,7 +504,7 @@ t_stat dt_devio(uint32 dev, uint64 *data) {
for (i = 0; i < DT_NUMDR; i++) {
if (i != DTC_GETUNI(dtsa) &&
(dt_unit[i].DSTATE & DTC_MOT) != 0)
dt_unit[i].u3 |= DTC_FNC_STOP;
dt_unit[i].CMD |= DTC_FNC_STOP;
}
}
dtsb = (uint64)((*data & (DTS_PAR_ERR|DTS_DATA_MISS|DTS_JOB_DONE| \
@@ -569,11 +573,11 @@ t_stat dt_svc (UNIT *uptr)
*/
if (uptr->DSTATE & DTC_MOT) {
/* Check if stoping */
if (uptr->u3 & DTC_FNC_STOP) {
if (uptr->CMD & DTC_FNC_STOP) {
/* Stop delay */
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o stopping\n", u);
sim_activate(uptr, DT_WRDTIM*10);
uptr->u3 &= ~DTC_FNC_STOP;
uptr->CMD &= ~DTC_FNC_STOP;
uptr->DSTATE &= ~(DTC_MOT);
blk = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
uptr->DSTATE = (0100 << DTC_V_WORD) | DTC_BLOCK | (DTC_MOTMASK & uptr->DSTATE);
@@ -591,10 +595,10 @@ if (uptr->DSTATE & DTC_MOT) {
uptr->DSTATE |= (blk << DTC_V_BLK);
return SCPE_OK;
}
if (uptr->u3 & DTC_FNC_REV) {
if (uptr->CMD & DTC_FNC_REV) {
sim_activate(uptr, DT_WRDTIM*10);
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reversing\n", u);
uptr->u3 &= ~DTC_FNC_REV;
uptr->CMD &= ~DTC_FNC_REV;
uptr->DSTATE ^= DTC_REV;
return SCPE_OK;
}
@@ -614,7 +618,7 @@ if (uptr->DSTATE & DTC_MOT) {
case DTC_FEND: /* Tape in endzone */
/* Set stop */
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev forward end\n", u);
uptr->u3 |= DTC_FNC_STOP;
uptr->CMD |= DTC_FNC_STOP;
uptr->u6 = 0;
dtsb |= DTB_END;
dtsb &= ~DTB_IDL;
@@ -636,7 +640,7 @@ if (uptr->DSTATE & DTC_MOT) {
if (dtsb & DTB_STOP)
dtsa &= ~0700; /* Clear command */
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev forward block\n", u);
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_MOVE:
case FNC_SRCH:
case FNC_WBLK:
@@ -647,7 +651,7 @@ if (uptr->DSTATE & DTC_MOT) {
case FNC_RALL:
case FNC_WRIT:
case FNC_READ:
uptr->u3 &= 077077;
uptr->CMD &= 077077;
dtsb |= DTB_DONE;
if (dtsb & DTB_JOBENB)
set_interrupt(DT_DEVNUM, dtsa);
@@ -661,11 +665,11 @@ if (uptr->DSTATE & DTC_MOT) {
break;
}
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
uptr->u3 |= DTC_FNC_STOP;
uptr->CMD |= DTC_FNC_STOP;
}
if (DTC_GETUNI(dtsa) == u) {
uptr->u3 &= 077077;
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD &= 077077;
uptr->CMD |= dtsa & 0700; /* Copy command */
}
if (word <= 0) {
uptr->DSTATE = DTC_FEND | (DTC_MOTMASK & uptr->DSTATE);
@@ -698,7 +702,7 @@ if (uptr->DSTATE & DTC_MOT) {
uptr->DSTATE |= (word - 1) << DTC_V_WORD;
}
uptr->u6-=2;
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_MOVE:
case FNC_SRCH:
case FNC_WBLK:
@@ -724,6 +728,7 @@ if (uptr->DSTATE & DTC_MOT) {
data = dtdb;
fbuf[off] = (data >> 18) & RMASK;
fbuf[off+1] = data & RMASK;
uptr->WRITTEN = 1;
uptr->hwmark = uptr->capac;
break;
}
@@ -740,15 +745,16 @@ if (uptr->DSTATE & DTC_MOT) {
sim_activate(uptr,DT_WRDTIM*2);
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev reverse check\n", u);
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
uptr->DSTATE = DTC_BLOCK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) | (DTC_MOTMASK & uptr->DSTATE);
uptr->DSTATE = DTC_BLOCK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) |
(DTC_MOTMASK & uptr->DSTATE);
if (dtsb & DTB_STOP)
dtsa &= ~0700; /* Clear command */
if (DTC_GETUNI(dtsa) == u) {
uptr->u3 &= 077077;
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD &= 077077;
uptr->CMD |= dtsa & 0700; /* Copy command */
}
dtsb &= ~DTB_BLKRD;
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_WRIT:
case FNC_WALL:
dtsb |= DTB_DATREQ;
@@ -772,7 +778,7 @@ if (uptr->DSTATE & DTC_MOT) {
break;
}
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
uptr->u3 |= DTC_FNC_STOP;
uptr->CMD |= DTC_FNC_STOP;
}
break;
@@ -780,15 +786,16 @@ if (uptr->DSTATE & DTC_MOT) {
sim_activate(uptr,DT_WRDTIM*2);
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
data = (uint64)word;
uptr->DSTATE = DTC_RCHK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) | (DTC_MOTMASK & uptr->DSTATE);
uptr->DSTATE = DTC_RCHK|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) |
(DTC_MOTMASK & uptr->DSTATE);
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o rev reverse block %04o\n", u, word);
dtsb &= ~DTB_END;
dtsb |= DTB_BLKRD;
if (DTC_GETUNI(dtsa) == u) {
uptr->u3 &= 077077;
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD &= 077077;
uptr->CMD |= dtsa & 0700; /* Copy command */
}
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_MOVE:
case FNC_READ:
case FNC_WMRK:
@@ -825,7 +832,7 @@ if (uptr->DSTATE & DTC_MOT) {
case DTC_FEND: /* Tape in endzone */
sim_activate(uptr, DT_WRDTIM*10);
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o forward end\n", u);
uptr->DSTATE = DTC_FBLK | (DTC_MOTMASK & uptr->DSTATE); /* Move to first block */
uptr->DSTATE = DTC_FBLK | (DTC_MOTMASK & uptr->DSTATE); /* Move to first block */
uptr->u6 = 0;
dtsb &= ~DTB_IDL;
break;
@@ -839,10 +846,10 @@ if (uptr->DSTATE & DTC_MOT) {
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o forward block %04o\n", u, word);
data = (uint64)word;
if (DTC_GETUNI(dtsa) == u) {
uptr->u3 &= 077077;
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD &= 077077;
uptr->CMD |= dtsa & 0700; /* Copy command */
}
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_RALL:
case FNC_SRCH:
dt_putword(&data);
@@ -872,10 +879,10 @@ if (uptr->DSTATE & DTC_MOT) {
if (dtsb & DTB_STOP)
dtsa &= ~0700; /* Clear command */
if (DTC_GETUNI(dtsa) == u) {
uptr->u3 &= 077077;
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD &= 077077;
uptr->CMD |= dtsa & 0700; /* Copy command */
}
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_WRIT:
case FNC_WALL:
dtsb |= DTB_DATREQ;
@@ -899,7 +906,7 @@ if (uptr->DSTATE & DTC_MOT) {
break;
}
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
uptr->u3 |= DTC_FNC_STOP;
uptr->CMD |= DTC_FNC_STOP;
}
break;
@@ -918,7 +925,7 @@ if (uptr->DSTATE & DTC_MOT) {
uptr->DSTATE &= ~(DTC_M_WORD << DTC_V_WORD);
uptr->DSTATE |= (word + 1) << DTC_V_WORD;
}
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_MOVE:
case FNC_SRCH:
case FNC_WALL:
@@ -931,17 +938,18 @@ if (uptr->DSTATE & DTC_MOT) {
if ((dtsb & DTB_STOP) == 0)
dt_putword(&data);
else
uptr->u3 &= 077077;
uptr->CMD &= 077077;
break;
case FNC_WRIT:
if ((dtsb & DTB_STOP) == 0)
dt_getword(&data, (word != DTC_M_WORD));
else {
uptr->u3 &= 077077;
uptr->CMD &= 077077;
data = dtdb;
}
fbuf[off] = (data >> 18) & RMASK;
fbuf[off+1] = data & RMASK;
uptr->WRITTEN = 1;
uptr->hwmark = uptr->capac;
break;
case FNC_WMRK:
@@ -972,20 +980,21 @@ if (uptr->DSTATE & DTC_MOT) {
dtsb &= ~(DTB_CHK);
dtsb |= DTB_IDL;
if (DTC_GETUNI(dtsa) == u) {
uptr->u3 &= 077077;
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD &= 077077;
uptr->CMD |= dtsa & 0700; /* Copy command */
}
word = (uptr->DSTATE >> DTC_V_BLK) & DTC_M_BLK;
word++;
if (word > 01101) {
uptr->DSTATE = DTC_REND|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) | (DTC_MOTMASK & uptr->DSTATE);
uptr->DSTATE = DTC_REND|(word << DTC_V_BLK)|(DTC_M_WORD << DTC_V_WORD) |
(DTC_MOTMASK & uptr->DSTATE);
} else {
uptr->DSTATE = DTC_FBLK|(word << DTC_V_BLK) | (DTC_MOTMASK & uptr->DSTATE);
}
if (dtsb & DTB_STOP)
dtsa &= ~0700; /* Clear command */
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reverse block %o\n", u, word);
switch (DTC_GETFNC(uptr->u3)) {
switch (DTC_GETFNC(uptr->CMD)) {
case FNC_MOVE:
case FNC_WBLK:
case FNC_SRCH:
@@ -997,7 +1006,7 @@ if (uptr->DSTATE & DTC_MOT) {
case FNC_WRIT:
case FNC_READ:
case FNC_WMRK:
uptr->u3 &= 077077;
uptr->CMD &= 077077;
dtsb |= DTB_DONE;
if (dtsb & DTB_JOBENB)
set_interrupt(DT_DEVNUM, dtsa);
@@ -1006,13 +1015,13 @@ if (uptr->DSTATE & DTC_MOT) {
break;
}
if (dtsb & (DTB_PAR|DTB_MIS|DTB_ILL|DTB_END|DTB_INCBLK|DTB_MRKERR)) {
uptr->u3 |= DTC_FNC_STOP;
uptr->CMD |= DTC_FNC_STOP;
}
break;
case DTC_REND: /* In final endzone */
/* Set stop */
uptr->u3 |= DTC_FNC_STOP;
uptr->CMD |= DTC_FNC_STOP;
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o reverse end\n", u);
dtsb &= ~DTB_IDL;
dtsb |= DTB_END;
@@ -1023,18 +1032,18 @@ if (uptr->DSTATE & DTC_MOT) {
}
}
/* Check if starting */
} else if (uptr->u3 & DTC_FNC_START) {
} else if (uptr->CMD & DTC_FNC_START) {
/* Start up delay */
sim_activate(uptr, DT_WRDTIM*10);
uptr->u3 &= ~(0700 | DTC_FNC_START);
uptr->CMD &= ~(0700 | DTC_FNC_START);
if (DTC_GETUNI(dtsa) == u)
uptr->u3 |= dtsa & 0700; /* Copy command */
uptr->CMD |= dtsa & 0700; /* Copy command */
uptr->DSTATE |= DTC_MOT;
if (uptr->u3 & DTC_FNC_REV) {
uptr->u3 &= ~DTC_FNC_REV;
if (uptr->CMD & DTC_FNC_REV) {
uptr->CMD &= ~DTC_FNC_REV;
uptr->DSTATE ^= DTC_REV;
}
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o start %06o\n", u, uptr->u3);
sim_debug(DEBUG_DETAIL, &dt_dev, "DTA %o start %06o\n", u, uptr->CMD);
return SCPE_OK;
}
return SCPE_OK;
@@ -1111,7 +1120,7 @@ t_stat dt_reset (DEVICE *dptr)
dtsb = dtsa = 0; /* clear status */
for (i = 0; i < DT_NUMDR; i++) {
if ((dt_unit[i].DSTATE & DTC_MOT) != 0)
dt_unit[i].u3 |= DTC_FNC_STOP;
dt_unit[i].CMD |= DTC_FNC_STOP;
}
clr_interrupt(DT_DEVNUM);
clr_interrupt(DT_DEVNUM|4);
@@ -1129,77 +1138,126 @@ t_stat dt_reset (DEVICE *dptr)
t_stat dt_attach (UNIT *uptr, CONST char *cptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, sz, k, *fbuf;
int32 u = uptr - dt_dev.units;
t_stat r;
r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) /* error? */
return r;
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
if (sim_switches & SWMASK ('T')) /* att 12b? */
uptr->flags = uptr->flags | UNIT_8FMT;
else if (sim_switches & SWMASK ('S')) /* att 16b? */
uptr->flags = uptr->flags | UNIT_11FMT;
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
(sz = sim_fsize (uptr->fileref))) {
if (sz == D8_FILSIZ)
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, sz, k, *fbuf;
int32 u = uptr - dt_dev.units;
t_stat r;
r = attach_unit (uptr, cptr); /* attach */
if (r != SCPE_OK) /* error? */
return r;
if ((sim_switches & SIM_SW_REST) == 0) { /* not from rest? */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default 18b */
if (sim_switches & SWMASK ('T')) /* att 12b? */
uptr->flags = uptr->flags | UNIT_8FMT;
else if (sz == D11_FILSIZ)
else if (sim_switches & SWMASK ('S')) /* att 16b? */
uptr->flags = uptr->flags | UNIT_11FMT;
else if (!(sim_switches & SWMASK ('A')) && /* autosize? */
(sz = sim_fsize (uptr->fileref))) {
if (sz == D8_FILSIZ)
uptr->flags = uptr->flags | UNIT_8FMT;
else if (sz == D11_FILSIZ)
uptr->flags = uptr->flags | UNIT_11FMT;
}
}
uptr->capac = DTU_CAPAC (uptr); /* set capacity */
uptr->filebuf = calloc (uptr->capac, sizeof (uint32));
if (uptr->filebuf == NULL) { /* can't alloc? */
detach_unit (uptr);
return SCPE_MEM;
uptr->capac = DTU_CAPAC (uptr); /* set capacity */
uptr->filebuf = calloc (uptr->capac, sizeof (uint32));
if (uptr->filebuf == NULL) { /* can't alloc? */
detach_unit (uptr);
return SCPE_MEM;
}
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
printf ("%s%d: ", sim_dname (&dt_dev), u);
if (uptr->flags & UNIT_8FMT)
printf ("12b format");
else if (uptr->flags & UNIT_11FMT)
printf ("16b format");
else printf ("18b/36b format");
printf (", buffering file in memory\n");
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
if (k == 0)
break;
for ( ; k < D8_NBSIZE; k++)
pdp8b[k] = 0;
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
fbuf[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
((uint32) (pdp8b[k + 1] >> 6) & 077);
fbuf[ba + 1] = ((uint32) (pdp8b[k + 1] & 077) << 12) |
((uint32) pdp8b[k + 2] & 07777);
ba = ba + 2; /* end blk loop */
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
sim_printf ("%s%d: ", sim_dname (&dt_dev), u);
if (uptr->flags & UNIT_8FMT)
sim_printf ("12b format");
else if (uptr->flags & UNIT_11FMT)
sim_printf ("16b format");
else sim_printf ("18b/36b format");
sim_printf (", buffering file in memory\n");
uptr->io_flush = dt_flush;
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
if (k == 0)
break;
for ( ; k < D8_NBSIZE; k++)
pdp8b[k] = 0;
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop thru blk */
fbuf[ba] = ((uint32) (pdp8b[k] & 07777) << 6) |
((uint32) (pdp8b[k + 1] >> 6) & 077);
fbuf[ba + 1] = ((uint32) (pdp8b[k + 1] & 077) << 12) |
((uint32) pdp8b[k + 2] & 07777);
ba = ba + 2; /* end blk loop */
}
} /* end file loop */
uptr->hwmark = ba;
} /* end if */
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
if (k == 0)
break;
for ( ; k < D18_BSIZE; k++)
pdp11b[k] = 0;
for (k = 0; k < D18_BSIZE; k++)
fbuf[ba++] = pdp11b[k];
} /* end file loop */
uptr->hwmark = ba;
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
if (k == 0)
break;
for ( ; k < D18_BSIZE; k++)
pdp11b[k] = 0;
for (k = 0; k < D18_BSIZE; k++)
fbuf[ba++] = pdp11b[k];
}
uptr->hwmark = ba;
} /* end elif */
else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
uptr->capac, uptr->fileref);
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
uptr->pos = DT_EZLIN; /* beyond leader */
return SCPE_OK;
} else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
uptr->capac, uptr->fileref);
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
uptr->pos = DT_EZLIN; /* beyond leader */
uptr->WRITTEN = 0;
return SCPE_OK;
}
/* Flush tape image to disk
Cancel in progress operation
If 12b, convert 18b buffer to 12b and write to file
If 16b, convert 18b buffer to 16b and write to file
If 18b/36b, write buffer to file
Deallocate buffer
*/
void dt_flush (UNIT* uptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, k, *fbuf;
int32 u = uptr - dt_dev.units;
if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
rewind (uptr->fileref); /* start of file */
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop blk */
pdp8b[k] = (fbuf[ba] >> 6) & 07777;
pdp8b[k + 1] = ((fbuf[ba] & 077) << 6) |
((fbuf[ba + 1] >> 12) & 077);
pdp8b[k + 2] = fbuf[ba + 1] & 07777;
ba = ba + 2;
} /* end loop blk */
fxwrite (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
if (ferror (uptr->fileref))
break;
} /* end loop file */
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
pdp11b[k] = fbuf[ba++] & 0177777;
fxwrite (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
if (ferror (uptr->fileref))
break;
} /* end loop file */
} /* end if 16b */
else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
uptr->hwmark, uptr->fileref);
if (ferror (uptr->fileref))
sim_perror ("I/O error");
} /* end if hwmark */
uptr->WRITTEN = 0;
}
/* Detach routine
@@ -1213,54 +1271,23 @@ return SCPE_OK;
t_stat dt_detach (UNIT* uptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, k, *fbuf;
int32 u = uptr - dt_dev.units;
int32 u = uptr - dt_dev.units;
if (!(uptr->flags & UNIT_ATT))
return SCPE_OK;
if (sim_is_active (uptr)) {
sim_cancel (uptr);
uptr->u3 = uptr->pos = 0;
if (!(uptr->flags & UNIT_ATT))
return SCPE_OK;
if (sim_is_active (uptr)) {
sim_cancel (uptr);
uptr->CMD = uptr->pos = 0;
}
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
rewind (uptr->fileref); /* start of file */
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D8_NBSIZE; k = k + 3) { /* loop blk */
pdp8b[k] = (fbuf[ba] >> 6) & 07777;
pdp8b[k + 1] = ((fbuf[ba] & 077) << 6) |
((fbuf[ba + 1] >> 12) & 077);
pdp8b[k + 2] = fbuf[ba + 1] & 07777;
ba = ba + 2;
} /* end loop blk */
fxwrite (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
if (ferror (uptr->fileref))
break;
} /* end loop file */
} /* end if 12b */
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
pdp11b[k] = fbuf[ba++] & 0177777;
fxwrite (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
if (ferror (uptr->fileref))
break;
} /* end loop file */
} /* end if 16b */
else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
uptr->hwmark, uptr->fileref);
if (ferror (uptr->fileref))
perror ("I/O error");
} /* end if hwmark */
free (uptr->filebuf); /* release buf */
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
uptr->filebuf = NULL; /* clear buf ptr */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default fmt */
uptr->capac = DT_CAPAC; /* default size */
return detach_unit (uptr);
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
sim_printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
dt_flush(uptr);
} /* end if hwmark */
free (uptr->filebuf); /* release buf */
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
uptr->filebuf = NULL; /* clear buf ptr */
uptr->flags = uptr->flags & ~(UNIT_8FMT | UNIT_11FMT); /* default fmt */
uptr->capac = DT_CAPAC; /* default size */
return detach_unit (uptr);
}
#endif

View File

@@ -228,6 +228,8 @@
#define DT_WRDTIM 15000
#define WRITTEN u6
int32 dtc_dtsa = 0; /* status A */
int32 dtc_dtsb = 0; /* status B */
int dtc_dct = 0;
@@ -239,6 +241,7 @@ t_stat dtc_set_dct (UNIT *, int32, CONST char *, void *);
t_stat dtc_show_dct (FILE *, UNIT *, int32, CONST void *);
t_stat dtc_reset (DEVICE *dptr);
t_stat dtc_attach (UNIT *uptr, CONST char *cptr);
void dtc_flush (UNIT *uptr);
t_stat dtc_detach (UNIT *uptr);
/* DT data structures
@@ -495,7 +498,6 @@ dtc_svc (UNIT *uptr)
case DTC_FEND: /* Tape in endzone */
/* Set stop */
sim_debug(DEBUG_DETAIL, &dtc_dev, "DTC %o rev forward end\n", u);
uptr->u6 = 0;
dtc_dtsb |= DTB_EOT|DTB_NULL;
dtc_dtsb &= ~(DTB_REQ|DTB_ACT);
if (uptr->CMD & DTC_ETF)
@@ -607,7 +609,6 @@ dtc_svc (UNIT *uptr)
uptr->DSTATE &= ~(DTC_M_WORD << DTC_V_WORD);
uptr->DSTATE |= (word - 1) << DTC_V_WORD;
}
uptr->u6-=2;
if ((dtc_dtsb & DTB_DLY) || (dtc_dtsb & DTB_ACT) == 0)
break;
switch (DTC_GETFNC(uptr->CMD)) {
@@ -636,6 +637,7 @@ dtc_svc (UNIT *uptr)
}
fbuf[off] = (data >> 18) & RMASK;
fbuf[off+1] = data & RMASK;
uptr->WRITTEN = 1;
uptr->hwmark = uptr->capac;
break;
}
@@ -749,7 +751,6 @@ dtc_svc (UNIT *uptr)
sim_debug(DEBUG_DETAIL, &dtc_dev, "DTC %o forward end\n", u);
/* Move to first block */
uptr->DSTATE = DTC_FBLK | (uptr->DSTATE & DTC_MOTMASK);
uptr->u6 = 0;
break;
case DTC_FBLK: /* In forward block number */
@@ -887,6 +888,7 @@ dtc_svc (UNIT *uptr)
dtc_dtsb |= DTB_DONE;
fbuf[off] = (data >> 18) & RMASK;
fbuf[off+1] = data & RMASK;
uptr->WRITTEN = 1;
uptr->hwmark = uptr->capac;
break;
case FNC_WMRK:
@@ -1169,22 +1171,24 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
uptr->flags = uptr->flags | UNIT_8FMT;
else if (sz == D11_FILSIZ)
uptr->flags = uptr->flags | UNIT_11FMT;
}
}
}
uptr->capac = DTU_CAPAC (uptr); /* set capacity */
uptr->filebuf = calloc (uptr->capac, sizeof (uint32));
if (uptr->filebuf == NULL) { /* can't alloc? */
detach_unit (uptr);
return SCPE_MEM;
}
}
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
printf ("%s%d: ", sim_dname (&dtc_dev), u);
sim_printf ("%s%d: ", sim_dname (&dtc_dev), u);
if (uptr->flags & UNIT_8FMT)
printf ("12b format");
sim_printf ("12b format");
else if (uptr->flags & UNIT_11FMT)
printf ("16b format");
else printf ("18b/36b format");
printf (", buffering file in memory\n");
sim_printf ("16b format");
else sim_printf ("18b/36b format");
sim_printf (", buffering file in memory\n");
uptr->WRITTEN = 0;
uptr->io_flush = dtc_flush;
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
k = fxread (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
@@ -1198,11 +1202,10 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
fbuf[ba + 1] = ((uint32) (pdp8b[k + 1] & 077) << 12) |
((uint32) pdp8b[k + 2] & 07777);
ba = ba + 2; /* end blk loop */
}
} /* end file loop */
}
} /* end file loop */
uptr->hwmark = ba;
} /* end if */
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->capac; ) { /* loop thru file */
k = fxread (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
if (k == 0)
@@ -1211,10 +1214,9 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
pdp11b[k] = 0;
for (k = 0; k < D18_BSIZE; k++)
fbuf[ba++] = pdp11b[k];
}
}
uptr->hwmark = ba;
} /* end elif */
else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
} else uptr->hwmark = fxread (uptr->filebuf, sizeof (uint32),
uptr->capac, uptr->fileref);
uptr->flags = uptr->flags | UNIT_BUF; /* set buf flag */
uptr->pos = DT_EZLIN; /* beyond leader */
@@ -1230,23 +1232,15 @@ dtc_attach (UNIT *uptr, CONST char *cptr)
Deallocate buffer
*/
t_stat
dtc_detach (UNIT* uptr)
void
dtc_flush (UNIT* uptr)
{
uint16 pdp8b[D8_NBSIZE];
uint16 pdp11b[D18_BSIZE];
uint32 ba, k, *fbuf;
int32 u = uptr - dtc_dev.units;
if (!(uptr->flags & UNIT_ATT))
return SCPE_OK;
if (sim_is_active (uptr)) {
sim_cancel (uptr);
uptr->CMD = uptr->pos = 0;
}
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
printf ("%s%d: writing buffer to file\n", sim_dname (&dtc_dev), u);
if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
fbuf = (uint32 *) uptr->filebuf; /* file buffer */
rewind (uptr->fileref); /* start of file */
if (uptr->flags & UNIT_8FMT) { /* 12b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
@@ -1256,26 +1250,42 @@ dtc_detach (UNIT* uptr)
((fbuf[ba + 1] >> 12) & 077);
pdp8b[k + 2] = fbuf[ba + 1] & 07777;
ba = ba + 2;
} /* end loop blk */
} /* end loop blk */
fxwrite (pdp8b, sizeof (uint16), D8_NBSIZE, uptr->fileref);
if (ferror (uptr->fileref))
break;
} /* end loop file */
} /* end if 12b */
else if (uptr->flags & UNIT_11FMT) { /* 16b? */
} /* end loop file */
} else if (uptr->flags & UNIT_11FMT) { /* 16b? */
for (ba = 0; ba < uptr->hwmark; ) { /* loop thru file */
for (k = 0; k < D18_BSIZE; k++) /* loop blk */
pdp11b[k] = fbuf[ba++] & 0177777;
fxwrite (pdp11b, sizeof (uint16), D18_BSIZE, uptr->fileref);
if (ferror (uptr->fileref))
break;
} /* end loop file */
} /* end if 16b */
else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
} /* end loop file */
} else fxwrite (uptr->filebuf, sizeof (uint32), /* write file */
uptr->hwmark, uptr->fileref);
if (ferror (uptr->fileref))
perror ("I/O error");
} /* end if hwmark */
sim_perror ("I/O error");
uptr->WRITTEN = 0;
} /* end if hwmark */
}
t_stat
dtc_detach (UNIT* uptr)
{
int32 u = uptr - dtc_dev.units;
if (!(uptr->flags & UNIT_ATT))
return SCPE_OK;
if (sim_is_active (uptr)) {
sim_cancel (uptr);
uptr->CMD = uptr->pos = 0;
}
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) { /* any data? */
sim_printf ("%s%d: writing buffer to file\n", sim_dname (&dtc_dev), u);
dtc_flush (uptr);
} /* end if hwmark */
free (uptr->filebuf); /* release buf */
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
uptr->filebuf = NULL; /* clear buf ptr */