PDP11, VAX: Fix SET RPn BADBLOCK behavior and auto sizing.
BAD144 info was written correctly if the user answered Y when the disk image was created, but would not work if SET RPn BADBLOCK was entered later. Auto sizing would be potentially wrong if a disk had been created without writing the BAD144 data. Now, if the disk contains a file system that information along with the physical container's size is used to properly auto size the disk.
This commit is contained in:
parent
f46c048bb6
commit
76dda8a01e
3 changed files with 41 additions and 54 deletions
|
@ -921,44 +921,9 @@ return SCPE_OK;
|
||||||
sta = status code
|
sta = status code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "sim_disk.h"
|
||||||
|
|
||||||
t_stat pdp11_bad_block (UNIT *uptr, int32 sec, int32 wds)
|
t_stat pdp11_bad_block (UNIT *uptr, int32 sec, int32 wds)
|
||||||
{
|
{
|
||||||
int32 i;
|
return sim_disk_pdp11_bad_block (uptr, sec, wds);
|
||||||
t_addr da;
|
|
||||||
uint16 *buf;
|
|
||||||
char *namebuf, *c;
|
|
||||||
uint32 packid;
|
|
||||||
|
|
||||||
if ((sec < 2) || (wds < 16))
|
|
||||||
return SCPE_ARG;
|
|
||||||
if ((uptr->flags & UNIT_ATT) == 0)
|
|
||||||
return SCPE_UNATT;
|
|
||||||
if (uptr->flags & UNIT_RO)
|
|
||||||
return SCPE_RO;
|
|
||||||
if (!get_yn ("Overwrite last track? [N]", FALSE))
|
|
||||||
return SCPE_OK;
|
|
||||||
da = (uptr->capac - (sec * wds)) * sizeof (uint16);
|
|
||||||
if (sim_fseek (uptr->fileref, da, SEEK_SET))
|
|
||||||
return SCPE_IOERR;
|
|
||||||
if ((buf = (uint16 *) malloc (wds * sizeof (uint16))) == NULL)
|
|
||||||
return SCPE_MEM;
|
|
||||||
namebuf = uptr->filename;
|
|
||||||
if ((c = strrchr (namebuf, '/')))
|
|
||||||
namebuf = c+1;
|
|
||||||
if ((c = strrchr (namebuf, '\\')))
|
|
||||||
namebuf = c+1;
|
|
||||||
if ((c = strrchr (namebuf, ']')))
|
|
||||||
namebuf = c+1;
|
|
||||||
packid = eth_crc32(0, namebuf, strlen (namebuf));
|
|
||||||
buf[0] = (uint16)packid;
|
|
||||||
buf[1] = (uint16)(packid >> 16) & 0x7FFF; /* Make sure MSB is clear */
|
|
||||||
buf[2] = buf[3] = 0;
|
|
||||||
for (i = 4; i < wds; i++)
|
|
||||||
buf[i] = 0177777u;
|
|
||||||
for (i = 0; (i < sec) && (i < 10); i++)
|
|
||||||
sim_fwrite (buf, sizeof (uint16), wds, uptr->fileref);
|
|
||||||
free (buf);
|
|
||||||
if (ferror (uptr->fileref))
|
|
||||||
return SCPE_IOERR;
|
|
||||||
return SCPE_OK;
|
|
||||||
}
|
}
|
||||||
|
|
53
sim_disk.c
53
sim_disk.c
|
@ -286,9 +286,9 @@ static t_bool sim_os_disk_isavailable_raw (FILE *f);
|
||||||
static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects);
|
static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects);
|
||||||
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects);
|
static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects);
|
||||||
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable);
|
static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable);
|
||||||
static t_stat sim_disk_pdp11_bad_block (UNIT *uptr, int32 sec);
|
|
||||||
static char *HostPathToVhdPath (const char *szHostPath, char *szVhdPath, size_t VhdPathSize);
|
static char *HostPathToVhdPath (const char *szHostPath, char *szVhdPath, size_t VhdPathSize);
|
||||||
static char *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize);
|
static char *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize);
|
||||||
|
static t_offset get_filesystem_size (UNIT *uptr);
|
||||||
|
|
||||||
struct sim_disk_fmt {
|
struct sim_disk_fmt {
|
||||||
const char *name; /* name */
|
const char *name; /* name */
|
||||||
|
@ -422,18 +422,28 @@ return (uptr->flags & DKUF_WRP)? TRUE: FALSE;
|
||||||
|
|
||||||
t_offset sim_disk_size (UNIT *uptr)
|
t_offset sim_disk_size (UNIT *uptr)
|
||||||
{
|
{
|
||||||
|
t_offset physical_size, filesystem_size;
|
||||||
|
t_bool saved_quiet = sim_quiet;
|
||||||
|
|
||||||
switch (DK_GET_FMT (uptr)) { /* case on format */
|
switch (DK_GET_FMT (uptr)) { /* case on format */
|
||||||
case DKUF_F_STD: /* SIMH format */
|
case DKUF_F_STD: /* SIMH format */
|
||||||
return sim_fsize_ex (uptr->fileref);
|
physical_size = sim_fsize_ex (uptr->fileref);
|
||||||
case DKUF_F_VHD: /* VHD format */
|
case DKUF_F_VHD: /* VHD format */
|
||||||
return sim_vhd_disk_size (uptr->fileref);
|
physical_size = sim_vhd_disk_size (uptr->fileref);
|
||||||
break;
|
break;
|
||||||
case DKUF_F_RAW: /* Raw Physical Disk Access */
|
case DKUF_F_RAW: /* Raw Physical Disk Access */
|
||||||
return sim_os_disk_size_raw (uptr->fileref);
|
physical_size = sim_os_disk_size_raw (uptr->fileref);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (t_offset)-1;
|
return (t_offset)-1;
|
||||||
}
|
}
|
||||||
|
sim_quiet = TRUE;
|
||||||
|
filesystem_size = get_filesystem_size (uptr);
|
||||||
|
sim_quiet = saved_quiet;
|
||||||
|
if ((filesystem_size == (t_offset)-1) ||
|
||||||
|
(filesystem_size < physical_size))
|
||||||
|
return physical_size;
|
||||||
|
return filesystem_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable asynchronous operation */
|
/* Enable asynchronous operation */
|
||||||
|
@ -1579,7 +1589,7 @@ if (storage_function)
|
||||||
|
|
||||||
if ((created) && (!copied)) {
|
if ((created) && (!copied)) {
|
||||||
t_stat r = SCPE_OK;
|
t_stat r = SCPE_OK;
|
||||||
uint8 *secbuf = (uint8 *)calloc (1, ctx->sector_size); /* alloc temp sector buf */
|
uint8 *secbuf = (uint8 *)calloc (128, ctx->sector_size); /* alloc temp sector buf */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
On a newly created disk, we write a zero sector to the last and the
|
On a newly created disk, we write a zero sector to the last and the
|
||||||
|
@ -1594,11 +1604,19 @@ if ((created) && (!copied)) {
|
||||||
*/
|
*/
|
||||||
if (secbuf == NULL)
|
if (secbuf == NULL)
|
||||||
r = SCPE_MEM;
|
r = SCPE_MEM;
|
||||||
if (r == SCPE_OK)
|
if (r == SCPE_OK) { /* Write all blocks */
|
||||||
r = sim_disk_wrsect (uptr, (t_lba)(((((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)) - ctx->sector_size)/ctx->sector_size), secbuf, NULL, 1); /* Write Last Sector */
|
t_lba lba;
|
||||||
if (r == SCPE_OK)
|
t_lba total_lbas = (t_lba)((((t_offset)uptr->capac)*ctx->capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1))/ctx->sector_size);
|
||||||
r = sim_disk_wrsect (uptr, (t_lba)(0), secbuf, NULL, 1); /* Write First Sector */
|
|
||||||
|
for (lba = 0; (r == SCPE_OK) && (lba < total_lbas); lba += 128) {
|
||||||
|
t_seccnt sectors = ((lba + 128) <= total_lbas) ? 128 : total_lbas - lba;
|
||||||
|
|
||||||
|
r = sim_disk_wrsect (uptr, lba, secbuf, NULL, sectors);
|
||||||
|
}
|
||||||
|
}
|
||||||
free (secbuf);
|
free (secbuf);
|
||||||
|
if (r == SCPE_OK)
|
||||||
|
uptr->io_flush (uptr);
|
||||||
if (r != SCPE_OK) {
|
if (r != SCPE_OK) {
|
||||||
sim_disk_detach (uptr); /* report error now */
|
sim_disk_detach (uptr); /* report error now */
|
||||||
remove (cptr); /* remove the create file */
|
remove (cptr); /* remove the create file */
|
||||||
|
@ -1640,7 +1658,7 @@ if ((created) && (!copied)) {
|
||||||
sim_printf ("%s%d: Initialized To Sector Address %dMB. 100%% complete.\n", sim_dname (dptr), (int)(uptr-dptr->units), (int)((((float)lba)*sector_size)/1000000));
|
sim_printf ("%s%d: Initialized To Sector Address %dMB. 100%% complete.\n", sim_dname (dptr), (int)(uptr-dptr->units), (int)((((float)lba)*sector_size)/1000000));
|
||||||
}
|
}
|
||||||
if (pdp11tracksize)
|
if (pdp11tracksize)
|
||||||
sim_disk_pdp11_bad_block (uptr, pdp11tracksize);
|
sim_disk_pdp11_bad_block (uptr, pdp11tracksize, sector_size/sizeof(uint16));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sim_switches & SWMASK ('K')) {
|
if (sim_switches & SWMASK ('K')) {
|
||||||
|
@ -1989,20 +2007,21 @@ return SCPE_OK;
|
||||||
Inputs:
|
Inputs:
|
||||||
uptr = pointer to unit
|
uptr = pointer to unit
|
||||||
sec = number of sectors per surface
|
sec = number of sectors per surface
|
||||||
|
wds = number of words per sector
|
||||||
Outputs:
|
Outputs:
|
||||||
sta = status code
|
sta = status code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static t_stat sim_disk_pdp11_bad_block (UNIT *uptr, int32 sec)
|
t_stat sim_disk_pdp11_bad_block (UNIT *uptr, int32 sec, int32 wds)
|
||||||
{
|
{
|
||||||
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
int32 i;
|
int32 i;
|
||||||
t_addr da;
|
t_addr da;
|
||||||
int32 wds = ctx->sector_size/sizeof (uint16);
|
|
||||||
uint16 *buf;
|
uint16 *buf;
|
||||||
DEVICE *dptr;
|
DEVICE *dptr;
|
||||||
char *namebuf, *c;
|
char *namebuf, *c;
|
||||||
uint32 packid;
|
uint32 packid;
|
||||||
|
t_stat stat = SCPE_OK;
|
||||||
|
|
||||||
if ((sec < 2) || (wds < 16))
|
if ((sec < 2) || (wds < 16))
|
||||||
return SCPE_ARG;
|
return SCPE_ARG;
|
||||||
|
@ -2033,12 +2052,14 @@ for (i = 4; i < wds; i++)
|
||||||
buf[i] = 0177777u;
|
buf[i] = 0177777u;
|
||||||
da = (uptr->capac*((dptr->flags & DEV_SECTORS) ? 512 : 1)) - (sec * wds);
|
da = (uptr->capac*((dptr->flags & DEV_SECTORS) ? 512 : 1)) - (sec * wds);
|
||||||
for (i = 0; (i < sec) && (i < 10); i++, da += wds)
|
for (i = 0; (i < sec) && (i < 10); i++, da += wds)
|
||||||
if (sim_disk_wrsect (uptr, (t_lba)(da/wds), (uint8 *)buf, NULL, 1)) {
|
if (ctx)
|
||||||
free (buf);
|
stat = sim_disk_wrsect (uptr, (t_lba)(da/wds), (uint8 *)buf, NULL, 1);
|
||||||
return SCPE_IOERR;
|
else {
|
||||||
|
if (wds != sim_fwrite (buf, sizeof (uint16), wds, uptr->fileref))
|
||||||
|
stat = SCPE_IOERR;
|
||||||
}
|
}
|
||||||
free (buf);
|
free (buf);
|
||||||
return SCPE_OK;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sim_disk_data_trace(UNIT *uptr, const uint8 *data, size_t lba, size_t len, const char* txt, int detail, uint32 reason)
|
void sim_disk_data_trace(UNIT *uptr, const uint8 *data, size_t lba, size_t len, const char* txt, int detail, uint32 reason)
|
||||||
|
|
|
@ -89,6 +89,7 @@ t_stat sim_disk_clearerr (UNIT *uptr);
|
||||||
t_bool sim_disk_isavailable (UNIT *uptr);
|
t_bool sim_disk_isavailable (UNIT *uptr);
|
||||||
t_bool sim_disk_isavailable_a (UNIT *uptr, DISK_PCALLBACK callback);
|
t_bool sim_disk_isavailable_a (UNIT *uptr, DISK_PCALLBACK callback);
|
||||||
t_bool sim_disk_wrp (UNIT *uptr);
|
t_bool sim_disk_wrp (UNIT *uptr);
|
||||||
|
t_stat sim_disk_pdp11_bad_block (UNIT *uptr, int32 sec, int32 wds);
|
||||||
t_offset sim_disk_size (UNIT *uptr);
|
t_offset sim_disk_size (UNIT *uptr);
|
||||||
t_bool sim_disk_vhd_support (void);
|
t_bool sim_disk_vhd_support (void);
|
||||||
t_bool sim_disk_raw_support (void);
|
t_bool sim_disk_raw_support (void);
|
||||||
|
|
Loading…
Add table
Reference in a new issue