mirror of
https://github.com/simh/simh.git
synced 2026-01-11 23:52:58 +00:00
PDP8: Add device buffer flush capability and keep track of data written state in the device buffer. Fixes #87
Finishing the last DECtape device which was missed when this functionality was added to pdp11_dt, pdp18b_dt and pdp8_dt in commits: 2934112a7003bd31c135197a01b36d969e9c79ba and c9e8121c16ca7af2b79f45bba4b220e1c95983ba Cleaned up the pdp11, pdp18b and other pdp8 implementations to make backporting cleaner. Made sure that buffer flushing happens correctly when simulation returns to the sim> prompt.
This commit is contained in:
parent
f1a10a7ff9
commit
59d0602b0d
@ -328,22 +328,22 @@ DIB dt_dib = {
|
||||
};
|
||||
|
||||
UNIT dt_unit[] = {
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC, &dt_flush) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE+UNIT_11FMT, DT_CAPAC) },
|
||||
{ UDATA (&dt_svcdone, UNIT_DIS, 0) }
|
||||
};
|
||||
|
||||
@ -1249,6 +1249,7 @@ else if (uptr->flags & UNIT_11FMT)
|
||||
printf ("16b format");
|
||||
else printf ("18b/36b format");
|
||||
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 (int16), D8_NBSIZE, uptr->fileref);
|
||||
|
||||
@ -372,22 +372,22 @@ int32 dt_gethdr (UNIT *uptr, int32 blk, int32 relpos);
|
||||
DIB dt_dib = { DEV_DTA, 2, &dt_iors, { &dt75, &dt76 } };
|
||||
|
||||
UNIT dt_unit[] = {
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC, &dt_flush) }
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+
|
||||
UNIT_ROABLE, DT_CAPAC) }
|
||||
};
|
||||
|
||||
REG dt_reg[] = {
|
||||
@ -1443,6 +1443,7 @@ else if (uptr->flags & UNIT_11FMT)
|
||||
printf ("16b format");
|
||||
else printf ("18b/36b format");
|
||||
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);
|
||||
|
||||
@ -306,22 +306,22 @@ int32 dt_gethdr (UNIT *uptr, int32 blk, int32 relpos, int32 dir);
|
||||
DIB dt_dib = { DEV_DTA, 2, { &dt76, &dt77 } };
|
||||
|
||||
UNIT dt_unit[] = {
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) }
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) }
|
||||
};
|
||||
|
||||
REG dt_reg[] = {
|
||||
@ -1241,6 +1241,7 @@ else if (uptr->flags & UNIT_11FMT)
|
||||
printf ("16b format");
|
||||
else printf ("18b/36b format");
|
||||
printf (", buffering file in memory\n");
|
||||
uptr->io_flush = dt_flush;
|
||||
if (uptr->flags & UNIT_8FMT) /* 12b? */
|
||||
uptr->hwmark = fxread (uptr->filebuf, sizeof (uint16),
|
||||
uptr->capac, uptr->fileref);
|
||||
|
||||
@ -90,6 +90,7 @@
|
||||
#define UNIT_11FMT (1 << UNIT_V_11FMT)
|
||||
#define STATE u3 /* unit state */
|
||||
#define LASTT u4 /* last time update */
|
||||
#define WRITTEN u5 /* device buffer is dirty and needs flushing */
|
||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||
|
||||
/* System independent DECtape constants */
|
||||
@ -197,6 +198,7 @@ int32 td77 (int32 IR, int32 AC);
|
||||
t_stat td_svc (UNIT *uptr);
|
||||
t_stat td_reset (DEVICE *dptr);
|
||||
t_stat td_attach (UNIT *uptr, char *cptr);
|
||||
void td_flush (UNIT *uptr);
|
||||
t_stat td_detach (UNIT *uptr);
|
||||
t_stat td_boot (int32 unitno, DEVICE *dptr);
|
||||
t_bool td_newsa (int32 newf);
|
||||
@ -659,6 +661,7 @@ int32 nibp = 3 * (DT_WSIZE - 1 - (line % DT_WSIZE)); /* nibble pos */
|
||||
|
||||
ba = ba + (line / DT_WSIZE); /* block addr */
|
||||
fbuf[ba] = (fbuf[ba] & ~(07 << nibp)) | (dat << nibp); /* upd data nibble */
|
||||
uptr->WRITTEN = TRUE;
|
||||
if (ba >= uptr->hwmark) /* upd length */
|
||||
uptr->hwmark = ba + 1;
|
||||
return;
|
||||
@ -803,6 +806,7 @@ else if (uptr->flags & UNIT_11FMT)
|
||||
printf ("16b format");
|
||||
else printf ("18b/36b format");
|
||||
printf (", buffering file in memory\n");
|
||||
uptr->io_flush = td_flush;
|
||||
if (uptr->flags & UNIT_8FMT) /* 12b? */
|
||||
uptr->hwmark = fxread (uptr->filebuf, sizeof (uint16),
|
||||
uptr->capac, uptr->fileref);
|
||||
@ -856,20 +860,16 @@ return SCPE_OK;
|
||||
Deallocate buffer
|
||||
*/
|
||||
|
||||
t_stat td_detach (UNIT* uptr)
|
||||
void td_flush (UNIT* uptr)
|
||||
{
|
||||
uint32 pdp18b[D18_NBSIZE];
|
||||
uint16 pdp11b[D18_NBSIZE], *fbuf;
|
||||
int32 i, k;
|
||||
int32 u = uptr - td_dev.units;
|
||||
uint32 ba;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT))
|
||||
return SCPE_OK;
|
||||
fbuf = (uint16 *) uptr->filebuf; /* file buffer */
|
||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||
printf ("%s%d: writing buffer to file\n", sim_dname (&td_dev), u);
|
||||
if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||
rewind (uptr->fileref); /* start of file */
|
||||
fbuf = (uint16 *) uptr->filebuf; /* file buffer */
|
||||
if (uptr->flags & UNIT_8FMT) /* PDP8? */
|
||||
fxwrite (uptr->filebuf, sizeof (uint16), /* write file */
|
||||
uptr->hwmark, uptr->fileref);
|
||||
@ -892,7 +892,21 @@ if (uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||
D18_NBSIZE, uptr->fileref);
|
||||
} /* end loop buf */
|
||||
} /* end else */
|
||||
if (ferror (uptr->fileref)) perror ("I/O error");
|
||||
if (ferror (uptr->fileref))
|
||||
perror ("I/O error");
|
||||
}
|
||||
uptr->WRITTEN = FALSE; /* no longer dirty */
|
||||
}
|
||||
|
||||
t_stat td_detach (UNIT* uptr)
|
||||
{
|
||||
int u = (int)(uptr - td_dev.units);
|
||||
|
||||
if (!(uptr->flags & UNIT_ATT))
|
||||
return SCPE_OK;
|
||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||
printf ("%s%d: writing buffer to file\n", sim_dname (&td_dev), u);
|
||||
td_flush (uptr);
|
||||
} /* end if hwmark */
|
||||
free (uptr->filebuf); /* release buf */
|
||||
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
||||
|
||||
19
scp.c
19
scp.c
@ -3103,10 +3103,8 @@ if (1) {
|
||||
for (j = 0; j < dptr->numunits; j++) { /* if not buffered in mem */
|
||||
uptr = dptr->units + j;
|
||||
if ((uptr->flags & UNIT_ATT) && /* attached, */
|
||||
!(uptr->flags & UNIT_BUF) && /* not buffered, */
|
||||
(uptr->fileref)) /* real file, */
|
||||
if (uptr->io_flush) /* unit specific flush routine */
|
||||
uptr->io_flush (uptr);
|
||||
(uptr->io_flush)) /* unit specific flush routine */
|
||||
uptr->io_flush (uptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5429,15 +5427,16 @@ if (sim_deb) /* flush debug log */
|
||||
for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* flush attached files */
|
||||
for (j = 0; j < dptr->numunits; j++) { /* if not buffered in mem */
|
||||
uptr = dptr->units + j;
|
||||
if ((uptr->flags & UNIT_ATT) && /* attached, */
|
||||
!(uptr->flags & UNIT_BUF) && /* not buffered, */
|
||||
(uptr->fileref)) { /* real file, */
|
||||
if (uptr->flags & UNIT_ATT) { /* attached, */
|
||||
if (uptr->io_flush) /* unit specific flush routine */
|
||||
uptr->io_flush (uptr);
|
||||
else
|
||||
if (!(uptr->dynflags & UNIT_NO_FIO) && /* is FILE *, */
|
||||
uptr->io_flush (uptr); /* call it */
|
||||
else {
|
||||
if (!(uptr->flags & UNIT_BUF) && /* not buffered, */
|
||||
(uptr->fileref) && /* real file, */
|
||||
!(uptr->dynflags & UNIT_NO_FIO) && /* is FILE *, */
|
||||
!(uptr->flags & UNIT_RO)) /* not read only? */
|
||||
fflush (uptr->fileref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -646,7 +646,6 @@ struct sim_fileref {
|
||||
/* The following macros define structure contents */
|
||||
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,0,0,(fl),0,(cap),0,NULL,0,0
|
||||
#define UDATAFLUSH(act,fl,cap,flush) NULL,act,NULL,NULL,NULL,0,0,(fl),0,(cap),0,flush,0,0
|
||||
|
||||
#if defined (__STDC__) || defined (_WIN32)
|
||||
/* Right Justified Octal Register Data */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user