diff --git a/PDP10/kx10_disk.c b/PDP10/kx10_disk.c
new file mode 100644
index 0000000..0d40405
--- /dev/null
+++ b/PDP10/kx10_disk.c
@@ -0,0 +1,289 @@
+/* kx10_disk.c: Disk translator.
+
+ Copyright (c) 2020, Richard Cornwell
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+#include "kx10_defs.h"
+#include "kx10_disk.h"
+
+/*
+ * SIMH format is number words per sector stored as a 64 bit word.
+ *
+ * DBD9 format is: 9 character per pair of words.
+ *
+ * 0 - B0 1 2 3 4 5 6 7
+ * 0 - 8 9 10 11 12 13 14 15
+ * 0 - 16 17 18 19 20 21 22 23
+ * 0 - 24 25 26 27 28 29 30 31
+ * 0 - 32 33 34 35 B0 1 2 3
+ * 1 - 4 5 6 7 8 9 10 11
+ * 1 - 12 13 14 15 16 17 18 19
+ * 1 - 20 21 22 23 24 25 26 27
+ * 1 - 28 29 30 31 32 33 34 35
+ *
+ *
+ * DLD9 format is: 9 character per pair of words.
+ *
+ * 0 - 28 29 30 31 32 33 34 35
+ * 0 - 20 21 22 23 24 25 26 27
+ * 0 - 12 13 14 15 16 17 18 19
+ * 0 - 4 5 6 7 8 9 10 11
+ * 0 - 32 33 34 35 B0 1 2 3
+ * 1 - 24 25 26 27 28 29 30 31
+ * 1 - 16 17 18 19 20 21 22 23
+ * 1 - 8 9 10 11 12 13 14 15
+ * 1 - B0 1 2 3 4 5 6 7
+ */
+
+
+struct disk_formats {
+ uint32 mode;
+ const char *name;
+};
+
+static struct disk_formats fmts[] = {
+ {SIMH, "SIMH"},
+ {DBD9, "DBD9"},
+ {DLD9, "DLD9"},
+ {0, 0},
+};
+
+t_stat
+disk_read(UNIT *uptr, uint64 *buffer, int sector, int wps)
+{
+ int da;
+ int wc;
+ int bc;
+ int wp;
+ uint64 temp;
+ uint8 conv_buff[2048];
+ switch(GET_FMT(uptr->flags)) {
+ case SIMH:
+ da = sector * wps;
+ (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
+ wc = sim_fread (buffer, sizeof(uint64), wps, uptr->fileref);
+ while (wc < wps)
+ buffer[wc++] = 0;
+ break;
+ case DBD9:
+ bc = (wps / 2) * 9;
+ da = sector * bc;
+ (void)sim_fseek(uptr->fileref, da, SEEK_SET);
+ wc = sim_fread (&conv_buff, 1, bc, uptr->fileref);
+ while (wc < bc)
+ conv_buff[wc++] = 0;
+ for (wp = wc = 0; wp < wps;) {
+ temp = ((uint64)conv_buff[wc++]) << 28;
+ temp |= ((uint64)conv_buff[wc++]) << 20;
+ temp |= ((uint64)conv_buff[wc++]) << 12;
+ temp |= ((uint64)conv_buff[wc++]) << 4;
+ temp |= ((uint64)conv_buff[wc]) >> 4;
+ buffer[wp++] = temp;
+ temp = ((uint64)conv_buff[wc++] & 0xf) << 32;
+ temp |= ((uint64)conv_buff[wc++]) << 24;
+ temp |= ((uint64)conv_buff[wc++]) << 16;
+ temp |= ((uint64)conv_buff[wc++]) << 8;
+ temp |= ((uint64)conv_buff[wc++]);
+ buffer[wp++] = temp;
+ }
+ break;
+
+ case DLD9:
+ bc = (wps / 2) * 9;
+ da = sector * bc;
+ (void)sim_fseek(uptr->fileref, da, SEEK_SET);
+ wc = sim_fread (&conv_buff, 1, bc, uptr->fileref);
+ while (wc < bc)
+ conv_buff[wc++] = 0;
+ for (wp = wc = 0; wp < wps;) {
+ temp = ((uint64)conv_buff[wc++]);
+ temp |= ((uint64)conv_buff[wc++]) << 8;
+ temp |= ((uint64)conv_buff[wc++]) << 16;
+ temp |= ((uint64)conv_buff[wc++]) << 24;
+ temp |= ((uint64)conv_buff[wc] & 0xf) << 32;
+ buffer[wp++] = temp;
+ temp = ((uint64)conv_buff[wc++] & 0xf0) >> 4;
+ temp |= ((uint64)conv_buff[wc++]) << 4;
+ temp |= ((uint64)conv_buff[wc++]) << 12;
+ temp |= ((uint64)conv_buff[wc++]) << 20;
+ temp |= ((uint64)conv_buff[wc++]) << 28;
+ buffer[wp++] = temp;
+ }
+ break;
+ }
+ return SCPE_OK;
+}
+
+t_stat
+disk_write(UNIT *uptr, uint64 *buffer, int sector, int wps)
+{
+ int da;
+ int wc;
+ int bc;
+ int wp;
+ uint64 temp;
+ uint8 conv_buff[2048];
+ switch(GET_FMT(uptr->flags)) {
+ case SIMH:
+ da = sector * wps;
+ (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
+ wc = sim_fwrite (buffer, sizeof(uint64), wps, uptr->fileref);
+ break;
+ case DBD9:
+ bc = (wps / 2) * 9;
+ for (wp = wc = 0; wp < wps;) {
+ temp = buffer[wp++];
+ conv_buff[wc++] = (uint8)((temp >> 28) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 20) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 12) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 4) & 0xff);
+ conv_buff[wc] = (uint8)((temp & 0xf) << 4);
+ temp = buffer[wp++];
+ conv_buff[wc++] |= (uint8)((temp >> 32) & 0xf);
+ conv_buff[wc++] = (uint8)((temp >> 24) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 16) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 8) & 0xff);
+ conv_buff[wc++] = (uint8)(temp & 0xff);
+ }
+ da = sector * bc;
+ (void)sim_fseek(uptr->fileref, da, SEEK_SET);
+ wc = sim_fwrite (&conv_buff, 1, bc, uptr->fileref);
+ return SCPE_OK;
+ case DLD9:
+ bc = (wps / 2) * 9;
+ for (wp = wc = 0; wp < wps;) {
+ temp = buffer[wp++];
+ conv_buff[wc++] = (uint8)(temp & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 8) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 16) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 24) & 0xff);
+ conv_buff[wc] = (uint8)((temp >> 32) & 0xf);
+ temp = buffer[wp++];
+ conv_buff[wc++] |= (uint8)((temp << 4) & 0xf0);
+ conv_buff[wc++] = (uint8)((temp >> 4) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 12) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 20) & 0xff);
+ conv_buff[wc++] = (uint8)((temp >> 28) & 0xff);
+ }
+ da = sector * bc;
+ (void)sim_fseek(uptr->fileref, da, SEEK_SET);
+ wc = sim_fwrite (&conv_buff, 1, bc, uptr->fileref);
+ return SCPE_OK;
+ }
+ return SCPE_OK;
+}
+
+
+/* Set disk format */
+t_stat disk_set_fmt (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
+{
+ int f;
+
+ if (uptr == NULL) return SCPE_IERR;
+ if (cptr == NULL) return SCPE_ARG;
+ for (f = 0; fmts[f].name != 0; f++) {
+ if (strcmp (cptr, fmts[f].name) == 0) {
+ uptr->flags &= ~UNIT_FMT;
+ uptr->flags |= SET_FMT(fmts[f].mode);
+ return SCPE_OK;
+ }
+ }
+ return SCPE_ARG;
+}
+
+/* Show disk format */
+
+t_stat disk_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
+{
+ int fmt = GET_FMT(uptr->flags);
+ int f;
+
+ for (f = 0; fmts[f].name != 0; f++) {
+ if (fmt == fmts[f].mode) {
+ fprintf (st, "%s format", fmts[f].name);
+ return SCPE_OK;
+ }
+ }
+ fprintf (st, "invalid format");
+ return SCPE_OK;
+}
+
+
+/* Device attach */
+t_stat disk_attach (UNIT *uptr, CONST char *cptr)
+{
+ t_stat r;
+ char gbuf[30];
+
+ /* Reset to SIMH format on attach */
+ uptr->flags &= ~UNIT_FMT;
+ /* Pickup optional format specifier during RESTORE */
+ cptr = get_sim_sw (cptr);
+ if (sim_switches & SWMASK ('F')) { /* format spec? */
+ cptr = get_glyph (cptr, gbuf, 0); /* get spec */
+ if (*cptr == 0) return SCPE_2FARG; /* must be more */
+ if (disk_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK)
+ return SCPE_ARG;
+ }
+
+ r = attach_unit (uptr, cptr);
+ if (r != SCPE_OK)
+ return r;
+ return SCPE_OK;
+}
+
+/* Device detach */
+
+t_stat disk_detach (UNIT *uptr)
+{
+ return detach_unit (uptr);
+}
+
+t_stat disk_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
+{
+ fprintf (st, "%s Disk Attach Help\n\n", dptr->name);
+
+ fprintf (st, "Disk container files can be one of 3 different types:\n\n");
+ fprintf (st, " SIMH A disk is an unstructured binary file of 64bit integers\n");
+ fprintf (st, " DBD9 Compatible with KLH10 is a packed big endian word\n");
+ fprintf (st, " DLD9 Compatible with KLH10 is a packed little endian word\n");
+
+ if (dptr->numunits > 1) {
+ uint32 i;
+
+ for (i=0; (i < dptr->numunits); ++i)
+ if ((dptr->units[i].flags & UNIT_ATTABLE) &&
+ !(dptr->units[i].flags & UNIT_DIS)) {
+ fprintf (st, " sim> ATTACH {switches} %s%d diskfile\n", dptr->name, i);
+ }
+ }
+ else
+ fprintf (st, " sim> ATTACH {switches} %s diskfile\n", dptr->name);
+ fprintf (st, "\n%s attach command switches\n", dptr->name);
+ fprintf (st, " -R Attach Read Only.\n");
+ fprintf (st, " -E Must Exist (if not specified an attempt to create the indicated\n");
+ fprintf (st, " disk container will be attempted).\n");
+ fprintf (st, " -F Open the indicated disk container in a specific format (default\n");
+ fprintf (st, " is SIMH), other options are DBD9 and DLD9\n");
+ fprintf (st, " -Y Answer Yes to prompt to overwrite last track (on disk create)\n");
+ fprintf (st, " -N Answer No to prompt to overwrite last track (on disk create)\n");
+ return SCPE_OK;
+}
diff --git a/PDP10/kx10_disk.h b/PDP10/kx10_disk.h
new file mode 100644
index 0000000..21bf9bc
--- /dev/null
+++ b/PDP10/kx10_disk.h
@@ -0,0 +1,81 @@
+/* kx10_disk.h: Disk translator.
+
+ Copyright (c) 2020, Richard Cornwell
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ RICHARD CORNWELL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+*/
+
+
+/* Flags in the unit flags word */
+
+#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
+#define UNIT_WLK (1 << UNIT_V_WLK)
+#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
+#define UNIT_V_FMT (UNIT_V_UF + 8)
+#define UNIT_M_FMT 7
+#define GET_FMT(x) (((x) >> UNIT_V_FMT) & UNIT_M_FMT)
+#define SET_FMT(x) (((x) & UNIT_M_FMT) << UNIT_V_FMT)
+#define UNIT_FMT (UNIT_M_FMT << UNIT_V_FMT)
+
+#define SIMH 0 /* Default raw uint64 word format */
+#define DBD9 1 /* KLH10 Disb Big End Double */
+#define DLD9 2 /* KLH10 Disb Little End Double */
+
+/*
+ * SIMH format is number words per sector stored as a 64 bit word.
+ *
+ * DBD9 format is: 9 character per pair of words.
+ *
+ * 0 - B0 1 2 3 4 5 6 7
+ * 0 - 8 9 10 11 12 13 14 15
+ * 0 - 16 17 18 19 20 21 22 23
+ * 0 - 24 25 26 27 28 29 30 31
+ * 0 - 32 33 34 35 B0 1 2 3
+ * 1 - 4 5 6 7 8 9 10 11
+ * 1 - 12 13 14 15 16 17 18 19
+ * 1 - 20 21 22 23 24 25 26 27
+ * 1 - 28 29 30 31 32 33 34 35
+ *
+ *
+ * DLD9 format is: 9 character per pair of words.
+ *
+ * 0 - 28 29 30 31 32 33 34 35
+ * 0 - 20 21 22 23 24 25 26 27
+ * 0 - 12 13 14 15 16 17 18 19
+ * 0 - 4 5 6 7 8 9 10 11
+ * 0 - 32 33 34 35 B0 1 2 3
+ * 1 - 24 25 26 27 28 29 30 31
+ * 1 - 16 17 18 19 20 21 22 23
+ * 1 - 8 9 10 11 12 13 14 15
+ * 1 - B0 1 2 3 4 5 6 7
+ */
+
+
+t_stat disk_read(UNIT *uptr, uint64 *buffer, int sector, int wps);
+t_stat disk_write(UNIT *uptr, uint64 *buffer, int sector, int wps);
+/* Set disk format */
+t_stat disk_set_fmt (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
+/* Show disk format */
+t_stat disk_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
+/* Device attach */
+t_stat disk_attach (UNIT *uptr, CONST char *cptr);
+/* Device detach */
+t_stat disk_detach (UNIT *uptr);
+/* Print attach help */
+t_stat disk_attach_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
diff --git a/PDP10/kx10_dp.c b/PDP10/kx10_dp.c
index e0df6ae..a7b38ea 100644
--- a/PDP10/kx10_dp.c
+++ b/PDP10/kx10_dp.c
@@ -22,6 +22,7 @@
*/
#include "kx10_defs.h"
+#include "kx10_disk.h"
#ifndef NUM_DEVS_DP
#define NUM_DEVS_DP 0
@@ -39,13 +40,10 @@
/* Flags in the unit flags word */
#define DEV_WHDR (1 << DEV_V_UF) /* Enable write headers */
-#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_V_DTYPE (UNIT_V_UF + 1) /* disk type */
#define UNIT_M_DTYPE 3
-#define UNIT_WLK (1 << UNIT_V_WLK)
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
-#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
/* Parameters in the unit descriptor */
@@ -271,6 +269,7 @@ MTAB dp_mod[] = {
{UNIT_DTYPE, (RP03_DTYPE << UNIT_V_DTYPE), "RP03", "RP03", &dp_set_type },
{UNIT_DTYPE, (RP02_DTYPE << UNIT_V_DTYPE), "RP02", "RP02", &dp_set_type },
{UNIT_DTYPE, (RP01_DTYPE << UNIT_V_DTYPE), "RP01", "RP01", &dp_set_type },
+ {MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", NULL, &disk_show_fmt },
{0},
};
@@ -602,7 +601,7 @@ t_stat dp_svc (UNIT *uptr)
int cyl = (uptr->UFLAGS >> 20) & 0777;
DEVICE *dptr = dp_devs[ctlr];
struct df10 *df10 = &dp_df10[ctlr];
- int diff, diffs, wc;
+ int diff, diffs;
int r;
sect &= 017;
@@ -646,12 +645,8 @@ t_stat dp_svc (UNIT *uptr)
if (cmd != WR) {
/* Read the block */
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
- * dp_drv_tab[dtype].sect + sect) * RP_NUMWD;
- (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
- wc = sim_fread (&dp_buf[ctlr][0], sizeof(uint64), RP_NUMWD,
- uptr->fileref);
- for (; wc < RP_NUMWD; wc++)
- dp_buf[ctlr][wc] = 0;
+ * dp_drv_tab[dtype].sect + sect);
+ (void)disk_read(uptr, &dp_buf[ctlr][0], da, RP_NUMWD);
uptr->hwmark = RP_NUMWD;
uptr->DATAPTR = 0;
sect = sect + 1;
@@ -694,13 +689,11 @@ t_stat dp_svc (UNIT *uptr)
if (uptr->DATAPTR >= RP_NUMWD || r == 0 ) {
if (cmd == WR) {
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
- * dp_drv_tab[dtype].sect + sect) * RP_NUMWD;
+ * dp_drv_tab[dtype].sect + sect);
/* write block the block */
for (; uptr->DATAPTR < RP_NUMWD; uptr->DATAPTR++)
dp_buf[ctlr][uptr->DATAPTR] = 0;
- (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
- wc = sim_fwrite(&dp_buf[ctlr][0],sizeof(uint64), RP_NUMWD,
- uptr->fileref);
+ (void)disk_write(uptr, &dp_buf[ctlr][0], da, RP_NUMWD);
uptr->STATUS |= SRC_DONE;
sect = sect + 1;
if (sect >= dp_drv_tab[dtype].sect) {
@@ -779,13 +772,11 @@ t_stat dp_svc (UNIT *uptr)
uptr->DATAPTR++;
if (uptr->DATAPTR >= RP_NUMWD || r == 0 ) {
int da = ((cyl * dp_drv_tab[dtype].surf + surf)
- * dp_drv_tab[dtype].sect + sect) * RP_NUMWD;
+ * dp_drv_tab[dtype].sect + sect);
/* write block the block */
for (; uptr->DATAPTR < RP_NUMWD; uptr->DATAPTR++)
dp_buf[ctlr][uptr->DATAPTR] = 0;
- (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
- wc = sim_fwrite(&dp_buf[ctlr][0],sizeof(uint64), RP_NUMWD,
- uptr->fileref);
+ (void)disk_write(uptr, &dp_buf[ctlr][0], da, RP_NUMWD);
uptr->STATUS |= SRC_DONE;
sect = sect + 1;
if (sect >= dp_drv_tab[dtype].sect) {
@@ -930,8 +921,7 @@ dp_boot(int32 unit_num, DEVICE * dptr)
addr = (MEMSIZE - 512) & RMASK;
for (sect = 4; sect <= 7; sect++) {
- (void)sim_fseek(uptr->fileref, (sect * RP_NUMWD) * sizeof(uint64), SEEK_SET);
- (void)sim_fread (&dp_buf[0][0], sizeof(uint64), RP_NUMWD, uptr->fileref);
+ (void)disk_read(uptr, &dp_buf[0][0], sect, RP_NUMWD);
ptr = 0;
for(wc = RP_NUMWD; wc > 0; wc--)
M[addr++] = dp_buf[0][ptr++];
@@ -949,10 +939,10 @@ t_stat dp_attach (UNIT *uptr, CONST char *cptr)
DIB *dib;
int ctlr;
- uptr->capac = dp_drv_tab[GET_DTYPE (uptr->flags)].size;
- r = attach_unit (uptr, cptr);
- if (r != SCPE_OK)
+ r = disk_attach (uptr, cptr);
+ if (r != SCPE_OK || (sim_switches & SIM_SW_REST) != 0)
return r;
+ uptr->capac = dp_drv_tab[GET_DTYPE (uptr->flags)].size;
dptr = find_dev_from_unit(uptr);
if (dptr == 0)
return SCPE_OK;
@@ -961,7 +951,7 @@ t_stat dp_attach (UNIT *uptr, CONST char *cptr)
uptr->CUR_CYL = 0;
uptr->UFLAGS = (NO << 3) | SEEK_DONE | (ctlr >> 2);
dp_df10[ctlr].status |= PI_ENABLE;
- set_interrupt(DP_DEVNUM + (ctlr), dp_df10[ctlr >> 2].status);
+ set_interrupt(DP_DEVNUM + (ctlr), dp_df10[ctlr].status);
return SCPE_OK;
}
@@ -973,7 +963,7 @@ t_stat dp_detach (UNIT *uptr)
return SCPE_OK;
if (sim_is_active (uptr)) /* unit active? */
sim_cancel (uptr); /* cancel operation */
- return detach_unit (uptr);
+ return disk_detach (uptr);
}
t_stat dp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
@@ -982,6 +972,7 @@ fprintf (st, "RP10 RP01/2/3 Disk Pack Drives (DP)\n\n");
fprintf (st, "The DP controller implements the RP10 disk drives. RP\n");
fprintf (st, "options include the ability to set units write enabled or write locked, to\n");
fprintf (st, "set the drive type to one of three disk types.\n");
+disk_attach_help(st, dptr, uptr, flag, cptr);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n");
diff --git a/PDP10/kx10_rp.c b/PDP10/kx10_rp.c
index 80b3552..166d58d 100644
--- a/PDP10/kx10_rp.c
+++ b/PDP10/kx10_rp.c
@@ -22,6 +22,7 @@
*/
#include "kx10_defs.h"
+#include "kx10_disk.h"
#ifndef NUM_DEVS_RP
#define NUM_DEVS_RP 0
@@ -36,14 +37,11 @@
/* Flags in the unit flags word */
-#define UNIT_V_WLK (UNIT_V_UF + 0) /* write locked */
#define UNIT_V_DTYPE (UNIT_V_UF + 1) /* disk type */
#define UNIT_M_DTYPE 7
-#define UNIT_WLK (1 << UNIT_V_WLK)
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
#define DTYPE(x) (((x) & UNIT_M_DTYPE) << UNIT_V_DTYPE)
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
-#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protect */
/* Parameters in the unit descriptor */
#define CMD u3
@@ -345,6 +343,7 @@ MTAB rp_mod[] = {
{UNIT_DTYPE, (RP07_DTYPE << UNIT_V_DTYPE), "RP07", "RP07", &rp_set_type },
{UNIT_DTYPE, (RP06_DTYPE << UNIT_V_DTYPE), "RP06", "RP06", &rp_set_type },
{UNIT_DTYPE, (RP04_DTYPE << UNIT_V_DTYPE), "RP04", "RP04", &rp_set_type },
+ {MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", NULL, &disk_show_fmt },
{0}
};
@@ -834,8 +833,6 @@ t_stat rp_svc (UNIT *uptr)
}
if (BUF_EMPTY(uptr)) {
- int wc;
-
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
uptr->CMD |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
@@ -846,12 +843,8 @@ t_stat rp_svc (UNIT *uptr)
}
sim_debug(DEBUG_DETAIL, dptr, "%s%o read (%d,%d,%d)\n", dptr->name, unit, cyl,
GET_SF(uptr->DA), GET_SC(uptr->DA));
- da = GET_DA(uptr->DA, dtype) * RP_NUMWD;
- (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
- wc = sim_fread (&rp_buf[ctlr][0], sizeof(uint64), RP_NUMWD,
- uptr->fileref);
- while (wc < RP_NUMWD)
- rp_buf[ctlr][wc++] = 0;
+ da = GET_DA(uptr->DA, dtype);
+ (void)disk_read(uptr, &rp_buf[ctlr][0], da, RP_NUMWD);
uptr->hwmark = RP_NUMWD;
uptr->DATAPTR = 0;
/* On read headers, transfer 2 words to start */
@@ -945,10 +938,8 @@ rd_end:
if (uptr->DATAPTR == RP_NUMWD) {
sim_debug(DEBUG_DETAIL, dptr, "%s%o write (%d,%d,%d)\n", dptr->name,
unit, cyl, GET_SF(uptr->DA), GET_SC(uptr->DA));
- da = GET_DA(uptr->DA, dtype) * RP_NUMWD;
- (void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
- (void)sim_fwrite (&rp_buf[ctlr][0], sizeof(uint64), RP_NUMWD,
- uptr->fileref);
+ da = GET_DA(uptr->DA, dtype);
+ (void)disk_write(uptr, &rp_buf[ctlr][0], da, RP_NUMWD);
uptr->DATAPTR = 0;
CLR_BUF(uptr);
if (sts) {
@@ -1023,11 +1014,10 @@ rp_boot(int32 unit_num, DEVICE * rptr)
#if KL
int sect;
/* KL does not support readin, so fake it by reading in sectors 4 to 7 */
- /* Possible in future fine boot loader in FE file system */
+ /* Possible in future find boot loader in FE file system */
addr = (MEMSIZE - 512) & RMASK;
for (sect = 4; sect <= 7; sect++) {
- (void)sim_fseek(uptr->fileref, (sect * RP_NUMWD) * sizeof(uint64), SEEK_SET);
- (void)sim_fread (&rp_buf[0][0], sizeof(uint64), RP_NUMWD, uptr->fileref);
+ disk_read(uptr, &rp_buf[0][0], sect, RP_NUMWD);
ptr = 0;
for(wc = RP_NUMWD; wc > 0; wc--) {
word = rp_buf[0][ptr++];
@@ -1036,8 +1026,7 @@ rp_boot(int32 unit_num, DEVICE * rptr)
}
word = (MEMSIZE - 512) & RMASK;
#else
- (void)sim_fseek(uptr->fileref, 0, SEEK_SET);
- (void)sim_fread (&rp_buf[0][0], sizeof(uint64), RP_NUMWD, uptr->fileref);
+ disk_read(uptr, &rp_buf[0][0], 0, RP_NUMWD);
addr = rp_buf[0][ptr] & RMASK;
wc = (rp_buf[0][ptr++] >> 18) & RMASK;
while (wc != 0) {
@@ -1071,7 +1060,7 @@ t_stat rp_attach (UNIT *uptr, CONST char *cptr)
int ctlr;
uptr->capac = rp_drv_tab[GET_DTYPE (uptr->flags)].size;
- r = attach_unit (uptr, cptr);
+ r = disk_attach (uptr, cptr);
if (r != SCPE_OK)
return r;
rptr = find_dev_from_unit(uptr);
@@ -1082,11 +1071,13 @@ t_stat rp_attach (UNIT *uptr, CONST char *cptr)
if (rh[ctlr].dev == rptr)
break;
}
+ if (uptr->flags & UNIT_WLK)
+ uptr->CMD |= DS_WRL;
+ if (sim_switches & SIM_SW_REST)
+ return SCPE_OK;
uptr->DA = 0;
uptr->CMD &= ~DS_VV;
uptr->CMD |= DS_DPR|DS_MOL|DS_DRY;
- if (uptr->flags & UNIT_WLK)
- uptr->CMD |= DS_WRL;
rp_rh[ctlr].status |= PI_ENABLE;
set_interrupt(dib->dev_num, rp_rh[ctlr].status);
return SCPE_OK;
@@ -1101,7 +1092,7 @@ t_stat rp_detach (UNIT *uptr)
if (sim_is_active (uptr)) /* unit active? */
sim_cancel (uptr); /* cancel operation */
uptr->CMD &= ~(DS_VV|DS_WRL|DS_DPR|DS_DRY);
- return detach_unit (uptr);
+ return disk_detach (uptr);
}
t_stat rp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
@@ -1111,6 +1102,7 @@ fprintf (st, "The RP controller implements the Massbus family of large disk driv
fprintf (st, "options include the ability to set units write enabled or write locked, to\n");
fprintf (st, "set the drive type to one of six disk types or autosize, and to write a DEC\n");
fprintf (st, "standard 044 compliant bad block table on the last track.\n\n");
+disk_attach_help(st, dptr, uptr, flag, cptr);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprintf (st, "\nThe type options can be used only when a unit is not attached to a file.\n");
diff --git a/Visual Studio Projects/PDP10-KA.vcproj b/Visual Studio Projects/PDP10-KA.vcproj
index 692fff6..dab7b7c 100644
--- a/Visual Studio Projects/PDP10-KA.vcproj
+++ b/Visual Studio Projects/PDP10-KA.vcproj
@@ -273,6 +273,10 @@
RelativePath="..\PDP10\kx10_dk.c"
>
+
+
@@ -621,6 +625,10 @@
RelativePath="..\PDP10\kx10_defs.h"
>
+
+
diff --git a/Visual Studio Projects/PDP10-KI.vcproj b/Visual Studio Projects/PDP10-KI.vcproj
index 90ad3c0..f3fcd50 100644
--- a/Visual Studio Projects/PDP10-KI.vcproj
+++ b/Visual Studio Projects/PDP10-KI.vcproj
@@ -221,6 +221,10 @@
RelativePath="..\PDP10\kx10_dk.c"
>
+
+
@@ -541,6 +545,10 @@
RelativePath="..\PDP10\kx10_defs.h"
>
+
+
diff --git a/Visual Studio Projects/PDP10-KL.vcproj b/Visual Studio Projects/PDP10-KL.vcproj
index c8cdec2..e4df28c 100644
--- a/Visual Studio Projects/PDP10-KL.vcproj
+++ b/Visual Studio Projects/PDP10-KL.vcproj
@@ -221,6 +221,10 @@
RelativePath="..\PDP10\kx10_df.c"
>
+
+
@@ -497,6 +501,10 @@
RelativePath="..\PDP10\kx10_defs.h"
>
+
+
diff --git a/Visual Studio Projects/PDP6.vcproj b/Visual Studio Projects/PDP6.vcproj
index 7e0891c..b11cd9c 100644
--- a/Visual Studio Projects/PDP6.vcproj
+++ b/Visual Studio Projects/PDP6.vcproj
@@ -245,6 +245,10 @@
RelativePath="..\PDP10\pdp6_mtc.c"
>
+
+
diff --git a/doc/ka10_doc.doc b/doc/ka10_doc.doc
index a3e39bf..8110df0 100644
Binary files a/doc/ka10_doc.doc and b/doc/ka10_doc.doc differ
diff --git a/doc/ki10_doc.doc b/doc/ki10_doc.doc
index c772f57..d202f9e 100644
Binary files a/doc/ki10_doc.doc and b/doc/ki10_doc.doc differ
diff --git a/doc/kl10_doc.doc b/doc/kl10_doc.doc
index e118495..9fe1eb6 100644
Binary files a/doc/kl10_doc.doc and b/doc/kl10_doc.doc differ
diff --git a/makefile b/makefile
index 6c3371a..1a4cd19 100644
--- a/makefile
+++ b/makefile
@@ -1978,11 +1978,11 @@ ifneq (,$(BESM6_BUILD))
endif
SEL32D = ${SIMHD}/SEL32
-SEL32 = ${SEL32D}/sel32_cpu.c ${SEL32D}/sel32_sys.c ${SEL32D}/sel32_defs.h \
- ${SEL32D}/sel32_chan.c ${SEL32D}/sel32_iop.c ${SEL32D}/sel32_com.c \
- ${SEL32D}/sel32_con.c ${SEL32D}/sel32_clk.c ${SEL32D}/sel32_mt.c \
- ${SEL32D}/sel32_lpr.c ${SEL32D}/sel32_scfi.c ${SEL32D}/sel32_fltpt.c \
- ${SEL32D}/sel32_disk.c ${SEL32D}/sel32_hsdp.c
+SEL32 = ${SEL32D}/sel32_cpu.c ${SEL32D}/sel32_sys.c ${SEL32D}/sel32_chan.c \
+ ${SEL32D}/sel32_iop.c ${SEL32D}/sel32_com.c ${SEL32D}/sel32_con.c \
+ ${SEL32D}/sel32_clk.c ${SEL32D}/sel32_mt.c ${SEL32D}/sel32_lpr.c \
+ ${SEL32D}/sel32_scfi.c ${SEL32D}/sel32_fltpt.c ${SEL32D}/sel32_disk.c \
+ ${SEL32D}/sel32_hsdp.c
SEL32_OPT = -I $(SEL32D) -DSEL32
#SEL32_OPT = -I $(SEL32D) -DUSE_INT64 -DSEL32
@@ -2012,7 +2012,8 @@ PDP6 = ${PDP6D}/kx10_cpu.c ${PDP6D}/kx10_sys.c ${PDP6D}/kx10_cty.c \
${PDP6D}/kx10_lp.c ${PDP6D}/kx10_pt.c ${PDP6D}/kx10_cr.c \
${PDP6D}/kx10_cp.c ${PDP6D}/pdp6_dct.c ${PDP6D}/pdp6_dtc.c \
${PDP6D}/pdp6_mtc.c ${PDP6D}/pdp6_dsk.c ${PDP6D}/pdp6_dcs.c \
- ${PDP6D}/kx10_dpy.c ${PDP6D}/pdp6_slave.c ${DISPLAYL} ${DISPLAY340}
+ ${PDP6D}/kx10_dpy.c ${PDP6D}/pdp6_slave.c ${PDP6D}/kx10_disk.c \
+ ${DISPLAYL} ${DISPLAY340}
PDP6_OPT = -DPDP6=1 -DUSE_INT64 -I ${PDP6D} -DUSE_SIM_CARD ${DISPLAY_OPT} ${PDP6_DISPLAY_OPT}
KA10D = ${SIMHD}/PDP10
@@ -2031,8 +2032,8 @@ KA10 = ${KA10D}/kx10_cpu.c ${KA10D}/kx10_sys.c ${KA10D}/kx10_df.c \
$(KA10D)/ka10_pmp.c ${KA10D}/ka10_dkb.c ${KA10D}/pdp6_dct.c \
${KA10D}/pdp6_dtc.c ${KA10D}/pdp6_mtc.c ${KA10D}/pdp6_dsk.c \
${KA10D}/pdp6_dcs.c ${KA10D}/ka10_dpk.c ${KA10D}/kx10_dpy.c \
- ${PDP10D}/ka10_ai.c ${KA10D}/ka10_iii.c ${DISPLAYL} ${DISPLAY340} \
- ${DISPLAYIII}
+ ${PDP10D}/ka10_ai.c ${KA10D}/ka10_iii.c ${KA10D}/kx10_disk.c \
+ ${DISPLAYL} ${DISPLAY340} ${DISPLAYIII}
KA10_OPT = -DKA=1 -DUSE_INT64 -I ${KA10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KA10_DISPLAY_OPT}
ifneq (${PANDA_LIGHTS},)
# ONLY for Panda display.
@@ -2051,7 +2052,8 @@ KI10 = ${KI10D}/kx10_cpu.c ${KI10D}/kx10_sys.c ${KI10D}/kx10_df.c \
${KI10D}/kx10_rh.c ${KI10D}/kx10_rp.c ${KI10D}/kx10_rc.c \
${KI10D}/kx10_dt.c ${KI10D}/kx10_dk.c ${KI10D}/kx10_cr.c \
${KI10D}/kx10_cp.c ${KI10D}/kx10_tu.c ${KI10D}/kx10_rs.c \
- ${KI10D}/kx10_imp.c ${KI10D}/kx10_dpy.c ${DISPLAYL} ${DISPLAY340}
+ ${KI10D}/kx10_imp.c ${KI10D}/kx10_dpy.c ${KI10D}/kx10_disk.c \
+ ${DISPLAYL} ${DISPLAY340}
KI10_OPT = -DKI=1 -DUSE_INT64 -I ${KI10D} -DUSE_SIM_CARD ${NETWORK_OPT} ${DISPLAY_OPT} ${KI10_DISPLAY_OPT}
ifneq (${PANDA_LIGHTS},)
# ONLY for Panda display.
@@ -2065,7 +2067,8 @@ KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \
${KL10D}/kx10_mt.c ${KL10D}/kx10_dc.c ${KL10D}/kx10_rh.c \
${KL10D}/kx10_rp.c ${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.c \
${KL10D}/kx10_imp.c ${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c \
- ${KL10D}/ka10_ch10.c ${KL10D}/kx10_lp.c ${KL10D}/kl10_nia.c
+ ${KL10D}/ka10_ch10.c ${KL10D}/kx10_lp.c ${KL10D}/kl10_nia.c \
+ ${KL10D}/kx10_disk.c
KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) -DUSE_SIM_CARD ${NETWORK_OPT}
ATT3B2D = ${SIMHD}/3B2
@@ -2142,7 +2145,7 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \
sigma uc15 pdp10-ka pdp10-ki pdp6
-ALL = b5500 i701 i704 i7010 i7070 i7080 i7090 pdp10-ka pdp10-ki pdp10-kl ibm360 ibm360_32 icl1900 pdp6 sel32
+ALL = b5500 i701 i704 i7010 i7070 i7080 i7090 pdp10-ka pdp10-ki pdp10-kl pdp6 ibm360 ibm360_32 icl1900 sel32
all : ${ALL}