DISK: Added disk auto size detection for DEC ODS1 structured disks

This commit is contained in:
Mark Pizzolato 2017-02-06 00:04:53 -08:00
parent f006aaa398
commit 7050a1aef5

View file

@ -839,7 +839,40 @@ return stat;
}
#pragma pack(push,1)
typedef struct _ODS2_HomeBlock
typedef struct _ODS1_HomeBlock
{
uint16 hm1_w_ibmapsize;
uint32 hm1_l_ibmaplbn;
uint16 hm1_w_maxfiles;
uint16 hm1_w_cluster;
uint16 hm1_w_devtype;
uint16 hm1_w_structlev;
#define HM1_C_LEVEL1 0401
#define HM1_C_LEVEL2 0402
uint8 hm1_t_volname[12];
uint8 hm1_b_fill_1[4];
uint16 hm1_w_volowner;
uint16 hm1_w_protect;
uint16 hm1_w_volchar;
uint16 hm1_w_fileprot;
uint8 hm1_b_fill_2[6];
uint8 hm1_b_window;
uint8 hm1_b_extend;
uint8 hm1_b_lru_lim;
uint8 hm1_b_fill_3[11];
uint16 hm1_w_checksum1;
uint8 hm1_t_credate[14];
uint8 hm1_b_fill_4[382];
uint32 hm1_l_serialnum;
uint8 hm1_b_fill_5[12];
uint8 hm1_t_volname2[12];
uint8 hm1_t_ownername[12];
uint8 hm1_t_format[12];
uint8 hm1_t_fill_6[2];
uint16 hm1_w_checksum2;
} ODS1_HomeBlock;
typedef struct _ODS2_HomeBlock
{
uint32 hm2_l_homelbn;
uint32 hm2_l_alhomelbn;
@ -884,6 +917,21 @@ typedef struct _ODS2_HomeBlock
uint16 hm2_w_checksum2;
} ODS2_HomeBlock;
typedef struct _ODS1_FileHeader
{
uint8 fh1_b_idoffset;
uint8 fh1_b_mpoffset;
uint16 fh1_w_fid_num;
uint16 fh1_w_fid_seq;
uint16 fh1_w_struclev;
uint16 fh1_w_fileowner;
uint16 fh1_w_fileprot;
uint16 fh1_w_filechar;
uint16 fh1_w_recattr;
uint8 fh1_b_fill_1[494];
uint16 fh1_w_checksum;
} ODS1_FileHeader;
typedef struct _ODS2_FileHeader
{
uint8 fh2_b_idoffset;
@ -944,6 +992,41 @@ typedef union _ODS2_Retreval
} fm2_r_map_bits3;
} ODS2_Retreval;
typedef struct _ODS1_Retreval
{
uint8 fm1_b_ex_segnum;
uint8 fm1_b_ex_rvn;
uint16 fm1_w_ex_filnum;
uint16 fm1_w_ex_filseq;
uint8 fm1_b_countsize;
uint8 fm1_b_lbnsize;
uint8 fm1_b_inuse;
uint8 fm1_b_avail;
union {
struct {
uint8 fm1_b_highlbn;
uint8 fm1_b_count;
uint16 fm1_w_lowlbn;
} fm1_s_fm1def1;
struct {
uint8 fm1_b_highlbn;
uint8 fm1_b_count;
uint16 fm1_w_lowlbn;
} fm1_s_fm1def2;
} fm1_pointers[4];
} ODS1_Retreval;
typedef struct _ODS1_StorageControlBlock
{
uint8 scb_b_unused[3];
uint8 scb_b_bitmapblks;
struct _bitmapblk {
uint16 scb_w_freeblks;
uint16 scb_w_freeptr;
} scb_r_blocks[1];
} ODS1_SCB;
typedef struct _ODS2_StorageControlBlock
{
uint8 scb_b_strucver; /* 1 */
@ -967,7 +1050,7 @@ typedef struct _ODS2_StorageControlBlock
#pragma pack(pop)
static uint16
ODS2Checksum (void *Buffer, uint16 WordCount)
ODSChecksum (void *Buffer, uint16 WordCount)
{
int i;
uint16 Sum = 0;
@ -980,7 +1063,7 @@ ODS2Checksum (void *Buffer, uint16 WordCount)
}
static t_offset get_ods_filesystem_size (UNIT *uptr)
static t_offset get_ods2_filesystem_size (UNIT *uptr)
{
DEVICE *dptr;
t_addr saved_capac;
@ -1001,8 +1084,8 @@ saved_capac = uptr->capac;
uptr->capac = (t_addr)(temp_capac/(capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)));
if (sim_disk_rdsect (uptr, 1, (uint8 *)&Home, NULL, 1))
goto Return_Cleanup;
CheckSum1 = ODS2Checksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum1)-((char *)&Home.hm2_l_homelbn))/2));
CheckSum2 = ODS2Checksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum2)-((char *)&Home.hm2_l_homelbn))/2));
CheckSum1 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum1)-((char *)&Home.hm2_l_homelbn))/2));
CheckSum2 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm2_w_checksum2)-((char *)&Home.hm2_l_homelbn))/2));
if ((Home.hm2_l_homelbn == 0) ||
(Home.hm2_l_alhomelbn == 0) ||
(Home.hm2_l_altidxlbn == 0) ||
@ -1021,7 +1104,7 @@ if ((Home.hm2_l_homelbn == 0) ||
goto Return_Cleanup;
if (sim_disk_rdsect (uptr, Home.hm2_l_ibmaplbn+Home.hm2_w_ibmapsize+1, (uint8 *)&Header, NULL, 1))
goto Return_Cleanup;
CheckSum1 = ODS2Checksum (&Header, 255);
CheckSum1 = ODSChecksum (&Header, 255);
if (CheckSum1 != *(((uint16 *)&Header)+255)) /* Verify Checksum on BITMAP.SYS file header */
goto Return_Cleanup;
Retr = (ODS2_Retreval *)(((uint16*)(&Header))+Header.fh2_b_mpoffset);
@ -1043,7 +1126,7 @@ switch (Retr->fm2_r_word0_bits.fm2_v_format)
Retr = (ODS2_Retreval *)(((uint16 *)Retr)+Retr->fm2_r_word0_bits.fm2_v_format+1);
if (sim_disk_rdsect (uptr, ScbLbn, (uint8 *)&Scb, NULL, 1))
goto Return_Cleanup;
CheckSum1 = ODS2Checksum (&Scb, 255);
CheckSum1 = ODSChecksum (&Scb, 255);
if (CheckSum1 != *(((uint16 *)&Scb)+255)) /* Verify Checksum on Storage Control Block */
goto Return_Cleanup;
if ((Scb.scb_w_cluster != Home.hm2_w_cluster) ||
@ -1051,7 +1134,7 @@ if ((Scb.scb_w_cluster != Home.hm2_w_cluster) ||
(Scb.scb_b_struclev != Home.hm2_b_struclev))
goto Return_Cleanup;
if (!sim_quiet) {
sim_printf ("%s%d: '%s' Contains ODS%d File system:\n", sim_dname (dptr), (int)(uptr-dptr->units), uptr->filename, Home.hm2_b_struclev);
sim_printf ("%s%d: '%s' Contains ODS%d File system\n", sim_dname (dptr), (int)(uptr-dptr->units), uptr->filename, Home.hm2_b_struclev);
sim_printf ("%s%d: Volume Name: %12.12s ", sim_dname (dptr), (int)(uptr-dptr->units), Home.hm2_t_volname);
sim_printf ("Format: %12.12s ", Home.hm2_t_format);
sim_printf ("Sectors In Volume: %u\n", Scb.scb_l_volsize);
@ -1063,6 +1146,65 @@ uptr->capac = saved_capac;
return ret_val;
}
static t_offset get_ods1_filesystem_size (UNIT *uptr)
{
DEVICE *dptr;
t_addr saved_capac;
t_offset temp_capac = 512 * (t_offset)0xFFFFFFFFu; /* Make sure we can access the largest sector */
uint32 capac_factor;
ODS1_HomeBlock Home;
ODS1_FileHeader Header;
ODS1_Retreval *Retr;
uint8 scb_buf[512];
ODS1_SCB *Scb = (ODS1_SCB *)scb_buf;
uint16 CheckSum1, CheckSum2;
uint32 ScbLbn;
t_offset ret_val = (t_offset)-1;
if ((dptr = find_dev_from_unit (uptr)) == NULL)
return ret_val;
capac_factor = ((dptr->dwidth / dptr->aincr) == 16) ? 2 : 1; /* save capacity units (word: 2, byte: 1) */
saved_capac = uptr->capac;
uptr->capac = (t_addr)(temp_capac/(capac_factor*((dptr->flags & DEV_SECTORS) ? 512 : 1)));
if (sim_disk_rdsect (uptr, 1, (uint8 *)&Home, NULL, 1))
goto Return_Cleanup;
CheckSum1 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm1_w_checksum1)-((char *)&Home.hm1_w_ibmapsize))/2));
CheckSum2 = ODSChecksum (&Home, (uint16)((((char *)&Home.hm1_w_checksum2)-((char *)&Home.hm1_w_ibmapsize))/2));
if ((Home.hm1_w_ibmapsize == 0) ||
(Home.hm1_l_ibmaplbn == 0) ||
(Home.hm1_w_maxfiles == 0) ||
(Home.hm1_w_cluster != 1) ||
((Home.hm1_w_structlev != HM1_C_LEVEL1) && (Home.hm1_w_structlev != HM1_C_LEVEL2)) ||
(Home.hm1_l_ibmaplbn == 0) ||
(Home.hm1_w_checksum1 != CheckSum1) ||
(Home.hm1_w_checksum2 != CheckSum2))
goto Return_Cleanup;
if (sim_disk_rdsect (uptr, ((Home.hm1_l_ibmaplbn << 16) + ((Home.hm1_l_ibmaplbn >> 16) & 0xFFFF)) + Home.hm1_w_ibmapsize + 1, (uint8 *)&Header, NULL, 1))
goto Return_Cleanup;
CheckSum1 = ODSChecksum (&Header, 255);
if (CheckSum1 != *(((uint16 *)&Header)+255)) /* Verify Checksum on BITMAP.SYS file header */
goto Return_Cleanup;
Retr = (ODS1_Retreval *)(((uint16*)(&Header))+Header.fh1_b_mpoffset);
ScbLbn = (Retr->fm1_pointers[0].fm1_s_fm1def1.fm1_b_highlbn<<16)+Retr->fm1_pointers[0].fm1_s_fm1def1.fm1_w_lowlbn;
if (sim_disk_rdsect (uptr, ScbLbn, (uint8 *)Scb, NULL, 1))
goto Return_Cleanup;
if (Scb->scb_b_bitmapblks < 127)
ret_val = (((t_offset)Scb->scb_r_blocks[Scb->scb_b_bitmapblks].scb_w_freeblks << 16) + Scb->scb_r_blocks[Scb->scb_b_bitmapblks].scb_w_freeptr) * 512;
else
ret_val = (((t_offset)Scb->scb_r_blocks[0].scb_w_freeblks << 16) + Scb->scb_r_blocks[0].scb_w_freeptr) * 512;
if (!sim_quiet) {
sim_printf ("%s%d: '%s' Contains an ODS1 File system\n", sim_dname (dptr), (int)(uptr-dptr->units), uptr->filename);
sim_printf ("%s%d: Volume Name: %12.12s ", sim_dname (dptr), (int)(uptr-dptr->units), Home.hm1_t_volname);
sim_printf ("Format: %12.12s ", Home.hm1_t_format);
sim_printf ("Sectors In Volume: %u\n", (uint32)(ret_val / 512));
}
Return_Cleanup:
uptr->capac = saved_capac;
return ret_val;
}
typedef struct ultrix_disklabel {
uint32 pt_magic; /* magic no. indicating part. info exits */
uint32 pt_valid; /* set by driver if pt is current */
@ -1122,7 +1264,8 @@ typedef t_offset (*FILESYSTEM_CHECK)(UNIT *uptr);
static t_offset get_filesystem_size (UNIT *uptr)
{
static FILESYSTEM_CHECK checks[] = {
&get_ods_filesystem_size,
&get_ods2_filesystem_size,
&get_ods1_filesystem_size,
&get_ultrix_filesystem_size,
NULL
};