1
0
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:
Mark Pizzolato 2014-02-12 21:08:18 -08:00
parent f1a10a7ff9
commit 59d0602b0d
6 changed files with 82 additions and 67 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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
View File

@ -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);
}
}
}
}

View File

@ -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 */