PDP8: Add device buffer flush capability and keep track of data written state in the device buffer. Fixes #87
This commit is contained in:
parent
ffda4c1c41
commit
c9e8121c16
2 changed files with 45 additions and 32 deletions
|
@ -105,6 +105,7 @@
|
||||||
#define UNIT_11FMT (1 << UNIT_V_11FMT)
|
#define UNIT_11FMT (1 << UNIT_V_11FMT)
|
||||||
#define STATE u3 /* unit state */
|
#define STATE u3 /* unit state */
|
||||||
#define LASTT u4 /* last time update */
|
#define LASTT u4 /* last time update */
|
||||||
|
#define WRITTEN u5 /* device buffer is dirty and needs flushing */
|
||||||
#define DT_WC 07754 /* word count */
|
#define DT_WC 07754 /* word count */
|
||||||
#define DT_CA 07755 /* current addr */
|
#define DT_CA 07755 /* current addr */
|
||||||
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
|
||||||
|
@ -281,6 +282,7 @@ int32 dt77 (int32 IR, int32 AC);
|
||||||
t_stat dt_svc (UNIT *uptr);
|
t_stat dt_svc (UNIT *uptr);
|
||||||
t_stat dt_reset (DEVICE *dptr);
|
t_stat dt_reset (DEVICE *dptr);
|
||||||
t_stat dt_attach (UNIT *uptr, char *cptr);
|
t_stat dt_attach (UNIT *uptr, char *cptr);
|
||||||
|
t_stat dt_flush (UNIT *uptr);
|
||||||
t_stat dt_detach (UNIT *uptr);
|
t_stat dt_detach (UNIT *uptr);
|
||||||
t_stat dt_boot (int32 unitno, DEVICE *dptr);
|
t_stat dt_boot (int32 unitno, DEVICE *dptr);
|
||||||
void dt_deselect (int32 oldf);
|
void dt_deselect (int32 oldf);
|
||||||
|
@ -304,22 +306,22 @@ int32 dt_gethdr (UNIT *uptr, int32 blk, int32 relpos, int32 dir);
|
||||||
DIB dt_dib = { DEV_DTA, 2, { &dt76, &dt77 } };
|
DIB dt_dib = { DEV_DTA, 2, { &dt76, &dt77 } };
|
||||||
|
|
||||||
UNIT dt_unit[] = {
|
UNIT dt_unit[] = {
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) },
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) },
|
||||||
{ UDATA (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
{ UDATAFLUSH (&dt_svc, UNIT_8FMT+UNIT_FIX+UNIT_ATTABLE+
|
||||||
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC) }
|
UNIT_DISABLE+UNIT_ROABLE, DT_CAPAC, &dt_flush) }
|
||||||
};
|
};
|
||||||
|
|
||||||
REG dt_reg[] = {
|
REG dt_reg[] = {
|
||||||
|
@ -870,6 +872,7 @@ switch (fnc) { /* at speed, check fnc *
|
||||||
if (dir) /* rev? comp obv */
|
if (dir) /* rev? comp obv */
|
||||||
dat = dt_comobv (dat);
|
dat = dt_comobv (dat);
|
||||||
fbuf[ba] = dat; /* write word */
|
fbuf[ba] = dat; /* write word */
|
||||||
|
uptr->WRITTEN = TRUE;
|
||||||
if (ba >= uptr->hwmark)
|
if (ba >= uptr->hwmark)
|
||||||
uptr->hwmark = ba + 1;
|
uptr->hwmark = ba + 1;
|
||||||
if (M[DT_WC] == 0)
|
if (M[DT_WC] == 0)
|
||||||
|
@ -1275,29 +1278,16 @@ return SCPE_OK;
|
||||||
If 16b or 18b, convert 12b buffer to 16b or 18b and write to file
|
If 16b or 18b, convert 12b buffer to 16b or 18b and write to file
|
||||||
Deallocate buffer
|
Deallocate buffer
|
||||||
*/
|
*/
|
||||||
|
t_stat dt_flush (UNIT* uptr)
|
||||||
t_stat dt_detach (UNIT* uptr)
|
|
||||||
{
|
{
|
||||||
uint32 pdp18b[D18_NBSIZE];
|
uint32 pdp18b[D18_NBSIZE];
|
||||||
uint16 pdp11b[D18_NBSIZE], *fbuf;
|
uint16 pdp11b[D18_NBSIZE], *fbuf;
|
||||||
int32 i, k;
|
int32 i, k;
|
||||||
int32 u = uptr - dt_dev.units;
|
|
||||||
uint32 ba;
|
uint32 ba;
|
||||||
|
|
||||||
if (!(uptr->flags & UNIT_ATT)) /* attached? */
|
if (uptr->WRITTEN && uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||||
return SCPE_OK;
|
|
||||||
if (sim_is_active (uptr)) {
|
|
||||||
sim_cancel (uptr);
|
|
||||||
if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) {
|
|
||||||
dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF;
|
|
||||||
DT_UPDINT;
|
|
||||||
}
|
|
||||||
uptr->STATE = uptr->pos = 0;
|
|
||||||
}
|
|
||||||
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 (&dt_dev), u);
|
|
||||||
rewind (uptr->fileref); /* start of file */
|
rewind (uptr->fileref); /* start of file */
|
||||||
|
fbuf = (uint16 *) uptr->filebuf; /* file buffer */
|
||||||
if (uptr->flags & UNIT_8FMT) /* PDP8? */
|
if (uptr->flags & UNIT_8FMT) /* PDP8? */
|
||||||
fxwrite (uptr->filebuf, sizeof (uint16), /* write file */
|
fxwrite (uptr->filebuf, sizeof (uint16), /* write file */
|
||||||
uptr->hwmark, uptr->fileref);
|
uptr->hwmark, uptr->fileref);
|
||||||
|
@ -1322,6 +1312,28 @@ if (uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||||
} /* end else */
|
} /* end else */
|
||||||
if (ferror (uptr->fileref))
|
if (ferror (uptr->fileref))
|
||||||
perror ("I/O error");
|
perror ("I/O error");
|
||||||
|
}
|
||||||
|
uptr->WRITTEN = FALSE; /* no longer dirty */
|
||||||
|
return SCPE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_stat dt_detach (UNIT* uptr)
|
||||||
|
{
|
||||||
|
int u = (int)(uptr - dt_dev.units);
|
||||||
|
|
||||||
|
if (!(uptr->flags & UNIT_ATT)) /* attached? */
|
||||||
|
return SCPE_OK;
|
||||||
|
if (sim_is_active (uptr)) {
|
||||||
|
sim_cancel (uptr);
|
||||||
|
if ((u == DTA_GETUNIT (dtsa)) && (dtsa & DTA_STSTP)) {
|
||||||
|
dtsb = dtsb | DTB_ERF | DTB_SEL | DTB_DTF;
|
||||||
|
DT_UPDINT;
|
||||||
|
}
|
||||||
|
uptr->STATE = uptr->pos = 0;
|
||||||
|
}
|
||||||
|
if (uptr->hwmark && ((uptr->flags & UNIT_RO)== 0)) { /* any data? */
|
||||||
|
printf ("%s%d: writing buffer to file\n", sim_dname (&dt_dev), u);
|
||||||
|
dt_flush (uptr);
|
||||||
} /* end if hwmark */
|
} /* end if hwmark */
|
||||||
free (uptr->filebuf); /* release buf */
|
free (uptr->filebuf); /* release buf */
|
||||||
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
uptr->flags = uptr->flags & ~UNIT_BUF; /* clear buf flag */
|
||||||
|
|
|
@ -646,6 +646,7 @@ struct sim_fileref {
|
||||||
/* The following macros define structure contents */
|
/* 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 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)
|
#if defined (__STDC__) || defined (_WIN32)
|
||||||
/* Right Justified Octal Register Data */
|
/* Right Justified Octal Register Data */
|
||||||
|
|
Loading…
Add table
Reference in a new issue