From 8c42a3436c531776db37faaa62ab96434cc30976 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 29 Dec 2020 11:14:34 -0800 Subject: [PATCH] VAXen with SCSI: Allow some cross controller read only drive access --- VAX/vax4xx_rz80.c | 31 +++++++++++++++++++++++++++++-- VAX/vax4xx_rz94.c | 29 ++++++++++++++++++++++++++++- sim_disk.c | 31 +++++++++++++++++++------------ sim_scsi.c | 9 +++++++-- sim_scsi.h | 1 + 5 files changed, 84 insertions(+), 17 deletions(-) diff --git a/VAX/vax4xx_rz80.c b/VAX/vax4xx_rz80.c index 46669e72..0e99bfd6 100644 --- a/VAX/vax4xx_rz80.c +++ b/VAX/vax4xx_rz80.c @@ -142,6 +142,7 @@ typedef struct { t_stat rz_svc (UNIT *uptr); t_stat rz_isvc (UNIT *uptr); t_stat rz_reset (DEVICE *dptr); +t_stat rz_attach (UNIT *uptr, CONST char *cptr); t_stat rz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat rz_set_type (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat rz_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc); @@ -250,11 +251,32 @@ MTAB rz_mod[] = { { 0 } }; +static const char *drv_types[] = { + "RZ23", + "RZ23L", + "RZ24", + "RZ24L", + "RZ25", + "RZ25L", + "RZ26", + "RZ26L", + "RZ55", + "CDROM", + "RRD40", + "RRD42", + "RRW11", + "CDW900", + "XR1001", + "TZK50", + "TZ30", + "RZUSER" + }; + DEVICE rz_dev = { "RZ", rz_unit, rz_reg, rz_mod, RZ_NUMDR + 1, DEV_RDX, 31, 1, DEV_RDX, 8, NULL, NULL, &rz_reset, - NULL, &scsi_attach, &scsi_detach, + NULL, &rz_attach, &scsi_detach, NULL, DEV_DEBUG | DEV_DISK | DEV_SECTORS | RZ_FLAGS, 0, rz_debug, NULL, NULL, &rz_help, NULL, NULL, &rz_description @@ -302,7 +324,7 @@ DEVICE rzb_dev = { "RZB", rzb_unit, rzb_reg, rz_mod, RZ_NUMDR + 1, DEV_RDX, 31, 1, DEV_RDX, 8, NULL, NULL, &rz_reset, - NULL, &scsi_attach, &scsi_detach, + NULL, &rz_attach, &scsi_detach, &rzb_dib, DEV_DEBUG | DEV_DISK | DEV_SECTORS | RZB_FLAGS, 0, rz_debug, NULL, NULL, &rz_help, NULL /* help and attach_help routines */ @@ -860,6 +882,11 @@ scsi_help (st, dptr, uptr, flag, cptr); return SCPE_OK; } +t_stat rz_attach (UNIT *uptr, CONST char *cptr) +{ +return scsi_attach_ex (uptr, cptr, drv_types); +} + const char *rz_description (DEVICE *dptr) { return "NCR 5380 SCSI controller"; diff --git a/VAX/vax4xx_rz94.c b/VAX/vax4xx_rz94.c index f499e13b..ae83b214 100644 --- a/VAX/vax4xx_rz94.c +++ b/VAX/vax4xx_rz94.c @@ -111,6 +111,7 @@ DEBTAB rz_debug[] = { t_stat rz_svc (UNIT *uptr); t_stat rz_reset (DEVICE *dptr); +t_stat rz_attach (UNIT *uptr, CONST char *cptr); void rz_sw_reset (void); t_stat rz_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); void rz_cmd (uint32 cmd); @@ -203,11 +204,32 @@ MTAB rz_mod[] = { { 0 } }; +static const char *drv_types[] = { + "RZ23", + "RZ23L", + "RZ24", + "RZ24L", + "RZ25", + "RZ25L", + "RZ26", + "RZ26L", + "RZ55", + "CDROM", + "RRD40", + "RRD42", + "RRW11", + "CDW900", + "XR1001", + "TZK50", + "TZ30", + "RZUSER" + }; + DEVICE rz_dev = { "RZ", rz_unit, rz_reg, rz_mod, 9, DEV_RDX, 8, 1, DEV_RDX, 8, NULL, NULL, &rz_reset, - NULL, &scsi_attach, &scsi_detach, + NULL, &rz_attach, &scsi_detach, NULL, DEV_DISABLE | DEV_DEBUG | DEV_DISK | DEV_SECTORS, 0, rz_debug, NULL, NULL, &rz_help, NULL, NULL, &rz_description @@ -866,6 +888,11 @@ scsi_help (st, dptr, uptr, flag, cptr); return SCPE_OK; } +t_stat rz_attach (UNIT *uptr, CONST char *cptr) +{ +return scsi_attach_ex (uptr, cptr, drv_types); +} + const char *rz_description (DEVICE *dptr) { return "NCR 53C94 SCSI controller"; diff --git a/sim_disk.c b/sim_disk.c index 5f5fb116..fd6b5fa0 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -2043,6 +2043,8 @@ for (i = 0; checks[i] != NULL; i++) { return ret_val; } +static t_stat store_disk_footer (UNIT *uptr, const char *dtype); + static t_stat get_disk_footer (UNIT *uptr) { struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; @@ -2109,6 +2111,13 @@ if (f) { f = NULL; } else { + /* We've got a valid footer, but it may need to be corrected */ + if ((NtoHl (f->TransferElementSize) == 1) && + (0 == memcmp (f->DriveType, "RZ", 2))) { + f->TransferElementSize = NtoHl (2); + f->Checksum = NtoHl (eth_crc32 (0, f, sizeof (*f) - sizeof (f->Checksum))); + store_disk_footer (uptr, (char *)f->DriveType); + } free (ctx->footer); ctx->footer = f; container_size -= sizeof (*f); @@ -2161,8 +2170,10 @@ free (ctx->footer); ctx->footer = f; switch (f->AccessFormat) { case DKUF_F_STD: /* SIMH format */ - if (sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET) == 0) + if (sim_fseeko ((FILE *)uptr->fileref, total_sectors * ctx->sector_size, SEEK_SET) == 0) { sim_fwrite (f, sizeof (*f), 1, (FILE *)uptr->fileref); + fflush ((FILE *)uptr->fileref); + } break; case DKUF_F_VHD: /* VHD format */ break; @@ -2189,7 +2200,6 @@ DEVICE *dptr; char tbuf[4*CBUFSIZE]; FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen; FILE *(*create_function)(const char *filename, t_offset desiredsize) = NULL; -t_offset (*size_function)(FILE *file); t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) = NULL; t_bool created = FALSE, copied = FALSE; t_bool auto_format = FALSE; @@ -2416,7 +2426,6 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ sim_vhd_disk_close (uptr->fileref); /* close vhd file*/ uptr->fileref = NULL; open_function = sim_vhd_disk_open; - size_function = sim_vhd_disk_size; break; } while (tmp_size < sector_size) @@ -2426,7 +2435,6 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ sim_disk_set_fmt (uptr, 0, "RAW", NULL); /* set file format to RAW */ sim_os_disk_close_raw (uptr->fileref); /* close raw file*/ open_function = sim_os_disk_open_raw; - size_function = sim_os_disk_size_raw; storage_function = sim_os_disk_info_raw; uptr->fileref = NULL; break; @@ -2434,7 +2442,6 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ } sim_disk_set_fmt (uptr, 0, "SIMH", NULL); /* set file format to SIMH */ open_function = sim_fopen; - size_function = sim_fsize_ex; break; case DKUF_F_STD: /* SIMH format */ if (NULL != (uptr->fileref = sim_vhd_disk_open (cptr, "rb"))) { /* Try VHD first */ @@ -2442,17 +2449,14 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ sim_vhd_disk_close (uptr->fileref); /* close vhd file*/ uptr->fileref = NULL; open_function = sim_vhd_disk_open; - size_function = sim_vhd_disk_size; auto_format = TRUE; break; } open_function = sim_fopen; - size_function = sim_fsize_ex; break; case DKUF_F_VHD: /* VHD format */ open_function = sim_vhd_disk_open; create_function = sim_vhd_disk_create; - size_function = sim_vhd_disk_size; storage_function = sim_os_disk_info_raw; break; case DKUF_F_RAW: /* Raw Physical Disk Access */ @@ -2461,12 +2465,10 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ sim_vhd_disk_close (uptr->fileref); /* close vhd file*/ uptr->fileref = NULL; open_function = sim_vhd_disk_open; - size_function = sim_vhd_disk_size; auto_format = TRUE; break; } open_function = sim_os_disk_open_raw; - size_function = sim_os_disk_size_raw; storage_function = sim_os_disk_info_raw; break; default: @@ -2552,8 +2554,13 @@ if ((DK_GET_FMT (uptr) == DKUF_F_VHD) || (ctx->footer)) { cmd[sizeof (cmd) - 1] = '\0'; snprintf (cmd, sizeof (cmd) - 1, "%s %s", sim_uname (uptr), container_dtype); r = set_cmd (0, cmd); - if (r != SCPE_OK) - r = sim_messagef (r, "Can't set %s to drive type %s\n", sim_uname (uptr), container_dtype); + if (r != SCPE_OK) { + r = sim_messagef (r, "%s: Can't set to drive type %s\n", sim_uname (uptr), container_dtype); + if ((uptr->flags & UNIT_RO) != 0) /* Not Opening read only? */ + r = sim_messagef (SCPE_OK, "%s: Read Only access to inconsistent drive type allowed\n", sim_uname (uptr)); + else + sim_messagef (SCPE_OK, "'%s' can only be attached Read Only to %s\n", cptr, sim_uname (uptr)); + } } } } diff --git a/sim_scsi.c b/sim_scsi.c index eed91b00..c4289593 100644 --- a/sim_scsi.c +++ b/sim_scsi.c @@ -1689,7 +1689,7 @@ return SCPE_OK; /* Attach device */ -t_stat scsi_attach (UNIT *uptr, CONST char *cptr) +t_stat scsi_attach_ex (UNIT *uptr, CONST char *cptr, const char **drivetypes) { SCSI_DEV *dev = (SCSI_DEV *)uptr->up7; @@ -1700,7 +1700,7 @@ switch (dev->devtype) { case SCSI_DISK: case SCSI_WORM: case SCSI_CDROM: - return sim_disk_attach (uptr, cptr, dev->block_size, sizeof (uint8), (uptr->flags & SCSI_NOAUTO), SCSI_DBG_DSK, dev->name, 0, 0); + return sim_disk_attach_ex (uptr, cptr, dev->block_size, sizeof (uint16), (uptr->flags & SCSI_NOAUTO), SCSI_DBG_DSK, dev->name, 0, 0, drivetypes); case SCSI_TAPE: return sim_tape_attach (uptr, cptr); default: @@ -1708,6 +1708,11 @@ switch (dev->devtype) { } } +t_stat scsi_attach (UNIT *uptr, CONST char *cptr) +{ +return scsi_attach_ex (uptr, cptr, NULL); +} + /* Dettach device */ t_stat scsi_detach (UNIT *uptr) diff --git a/sim_scsi.h b/sim_scsi.h index f7a884e3..d0f56c62 100644 --- a/sim_scsi.h +++ b/sim_scsi.h @@ -129,6 +129,7 @@ t_stat scsi_set_wlk (UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat scsi_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat scsi_show_wlk (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat scsi_attach (UNIT *uptr, CONST char *cptr); +t_stat scsi_attach_ex (UNIT *uptr, CONST char *cptr, const char **drivetypes); t_stat scsi_detach (UNIT *uptr); t_stat scsi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);