DISK: Add RT11 file system disk size detection
This commit is contained in:
parent
39f36f273b
commit
e47a7e9ef7
2 changed files with 205 additions and 0 deletions
|
@ -225,6 +225,8 @@ Host platforms which have libSDL available can leverage this functionality.
|
||||||
#### Disk Extensions
|
#### Disk Extensions
|
||||||
RAW Disk Access (including CDROM)
|
RAW Disk Access (including CDROM)
|
||||||
Virtual Disk Container files, including differencing disks
|
Virtual Disk Container files, including differencing disks
|
||||||
|
File System type detection to accurately autosize disks.
|
||||||
|
Recognized file systems are: DEC ODS1, DEC ODS2, DEC RT11, Ultrix Partitions
|
||||||
|
|
||||||
#### Tape Extensions
|
#### Tape Extensions
|
||||||
AWS format tape support
|
AWS format tape support
|
||||||
|
|
203
sim_disk.c
203
sim_disk.c
|
@ -1304,6 +1304,204 @@ uptr->capac = saved_capac;
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
typedef struct _RT11_HomeBlock {
|
||||||
|
uint8 hb_b_bbtable[130];
|
||||||
|
uint8 hb_b_unused1[2];
|
||||||
|
uint8 hb_b_initrestore[38];
|
||||||
|
uint8 hb_b_bup[18];
|
||||||
|
uint8 hb_b_unused2[260];
|
||||||
|
uint16 hb_w_reserved1;
|
||||||
|
uint16 hb_w_reserved2;
|
||||||
|
uint8 hb_b_unused3[14];
|
||||||
|
uint16 hb_w_clustersize;
|
||||||
|
uint16 hb_w_firstdir;
|
||||||
|
uint16 hb_w_sysver;
|
||||||
|
#define HB_C_SYSVER_V3A 36521
|
||||||
|
#define HB_C_SYSVER_V04 36434
|
||||||
|
#define HB_C_SYSVER_V05 36435
|
||||||
|
uint8 hb_b_volid[12];
|
||||||
|
uint8 hb_b_owner[12];
|
||||||
|
uint8 hb_b_sysid[12];
|
||||||
|
#define HB_C_SYSID "DECRT11A "
|
||||||
|
uint8 hb_b_unused4[2];
|
||||||
|
uint16 hb_w_checksum;
|
||||||
|
} RT11_HomeBlock;
|
||||||
|
|
||||||
|
typedef struct _RT11_DirHeader {
|
||||||
|
uint16 dh_w_count;
|
||||||
|
uint16 dh_w_next;
|
||||||
|
uint16 dh_w_highest;
|
||||||
|
#define DH_C_MAXSEG 31
|
||||||
|
uint16 dh_w_extra;
|
||||||
|
uint16 dh_w_start;
|
||||||
|
} RT11_DirHeader;
|
||||||
|
|
||||||
|
typedef struct _RT11_DirEntry {
|
||||||
|
uint16 de_w_status;
|
||||||
|
#define DE_C_PRE 0000020
|
||||||
|
#define DE_C_TENT 0000400
|
||||||
|
#define DE_C_EMPTY 0001000
|
||||||
|
#define DE_C_PERM 0002000
|
||||||
|
#define DE_C_EOS 0004000
|
||||||
|
#define DE_C_READ 0040000
|
||||||
|
#define DE_C_PROT 0100000
|
||||||
|
uint16 de_w_fname1;
|
||||||
|
uint16 de_w_fname2;
|
||||||
|
uint16 de_w_ftype;
|
||||||
|
uint16 de_w_length;
|
||||||
|
uint16 de_w_jobchannel;
|
||||||
|
uint16 de_w_creationdate;
|
||||||
|
} RT11_DirEntry;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#define RT11_MAXPARTITIONS 256 /* Max partitions supported */
|
||||||
|
#define RT11_HOME 1 /* Home block # */
|
||||||
|
|
||||||
|
#define RT11_NOPART 0
|
||||||
|
#define RT11_SINGLEPART 1
|
||||||
|
#define RT11_MULTIPART 2
|
||||||
|
|
||||||
|
static int rt11_get_partition_type(RT11_HomeBlock *home, int part)
|
||||||
|
{
|
||||||
|
if (strncmp((char *)&home->hb_b_sysid, HB_C_SYSID, strlen(HB_C_SYSID)) == 0) {
|
||||||
|
uint16 type = home->hb_w_sysver;
|
||||||
|
|
||||||
|
if (part == 0) {
|
||||||
|
if ((type == HB_C_SYSVER_V3A) || (type == HB_C_SYSVER_V04))
|
||||||
|
return RT11_SINGLEPART;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == HB_C_SYSVER_V05)
|
||||||
|
return RT11_MULTIPART;
|
||||||
|
}
|
||||||
|
return RT11_NOPART;
|
||||||
|
}
|
||||||
|
|
||||||
|
static t_offset get_rt11_filesystem_size (UNIT *uptr)
|
||||||
|
{
|
||||||
|
DEVICE *dptr;
|
||||||
|
t_addr saved_capac;
|
||||||
|
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
|
||||||
|
t_offset temp_capac = 512 * (t_offset)0xFFFFFFFFu;
|
||||||
|
uint32 capac_factor;
|
||||||
|
uint8 sector_buf[1024];
|
||||||
|
RT11_HomeBlock Home;
|
||||||
|
RT11_DirHeader *dir_hdr = (RT11_DirHeader *)sector_buf;
|
||||||
|
int partitions = 0;
|
||||||
|
int part;
|
||||||
|
uint32 base;
|
||||||
|
uint32 dir_sec;
|
||||||
|
uint16 dir_seg;
|
||||||
|
uint16 version;
|
||||||
|
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;
|
||||||
|
saved_capac = uptr->capac;
|
||||||
|
uptr->capac = (t_addr)(temp_capac / (capac_factor * ((dptr->flags & DEV_SECTORS) ? 512 : 1)));
|
||||||
|
|
||||||
|
for (part = 0; part < RT11_MAXPARTITIONS; part++) {
|
||||||
|
uint16 seg_highest;
|
||||||
|
int type;
|
||||||
|
|
||||||
|
base = part << 16;
|
||||||
|
|
||||||
|
if (sim_disk_rdsect(uptr, (base + RT11_HOME) * (512 / ctx->sector_size), (uint8 *)&Home, NULL, 512 / ctx->sector_size))
|
||||||
|
goto Return_Cleanup;
|
||||||
|
|
||||||
|
type = rt11_get_partition_type(&Home, part);
|
||||||
|
|
||||||
|
if (type != RT11_NOPART) {
|
||||||
|
uint16 highest = 0;
|
||||||
|
uint8 seg_seen[DH_C_MAXSEG + 1];
|
||||||
|
|
||||||
|
memset(seg_seen, 0, sizeof(seg_seen));
|
||||||
|
|
||||||
|
partitions++;
|
||||||
|
|
||||||
|
dir_seg = 1;
|
||||||
|
do {
|
||||||
|
int offset = sizeof(RT11_DirHeader);
|
||||||
|
int dir_size = sizeof(RT11_DirEntry);
|
||||||
|
uint16 cur_blk;
|
||||||
|
|
||||||
|
if (seg_seen[dir_seg]++ != 0)
|
||||||
|
goto Next_Partition;
|
||||||
|
|
||||||
|
dir_sec = Home.hb_w_firstdir + ((dir_seg - 1) * 2);
|
||||||
|
|
||||||
|
if (sim_disk_rdsect(uptr, (base + dir_sec) * (512 / ctx->sector_size), sector_buf, NULL, 1024 / ctx->sector_size))
|
||||||
|
goto Return_Cleanup;
|
||||||
|
|
||||||
|
if (dir_seg == 1) {
|
||||||
|
seg_highest = dir_hdr->dh_w_highest;
|
||||||
|
if (seg_highest > DH_C_MAXSEG)
|
||||||
|
goto Next_Partition;
|
||||||
|
}
|
||||||
|
dir_size += dir_hdr->dh_w_extra;
|
||||||
|
cur_blk = dir_hdr->dh_w_start;
|
||||||
|
|
||||||
|
while ((1024 - offset) >= dir_size) {
|
||||||
|
RT11_DirEntry *dir_entry = (RT11_DirEntry *)§or_buf[offset];
|
||||||
|
|
||||||
|
if (dir_entry->de_w_status & DE_C_EOS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Within each directory segment the bas address should never
|
||||||
|
* decrease.
|
||||||
|
*/
|
||||||
|
if (((cur_blk + dir_entry->de_w_length) & 0xFFFF) < cur_blk)
|
||||||
|
goto Next_Partition;
|
||||||
|
|
||||||
|
cur_blk += dir_entry->de_w_length;
|
||||||
|
offset += dir_size;
|
||||||
|
}
|
||||||
|
if (cur_blk > highest)
|
||||||
|
highest = cur_blk;
|
||||||
|
dir_seg = dir_hdr->dh_w_next;
|
||||||
|
|
||||||
|
if (dir_seg > seg_highest)
|
||||||
|
goto Next_Partition;
|
||||||
|
} while (dir_seg != 0);
|
||||||
|
|
||||||
|
ret_val = (t_offset)((base + highest) * 512);
|
||||||
|
version = Home.hb_w_sysver;
|
||||||
|
|
||||||
|
if (type == RT11_SINGLEPART)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Next_Partition:
|
||||||
|
}
|
||||||
|
|
||||||
|
Return_Cleanup:
|
||||||
|
if (partitions) {
|
||||||
|
if (!sim_quiet) {
|
||||||
|
char *parttype = "???";
|
||||||
|
|
||||||
|
switch (version) {
|
||||||
|
case HB_C_SYSVER_V3A:
|
||||||
|
parttype = "V3A";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HB_C_SYSVER_V04:
|
||||||
|
parttype = "V04";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HB_C_SYSVER_V05:
|
||||||
|
parttype = "V05";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sim_printf ("%s%d: '%s' Contains RT11 partitions\n", sim_dname (dptr), (int)(uptr-dptr->units), uptr->filename);
|
||||||
|
sim_printf ("%d valid partition%s, Type: %s, Sectors On Disk: %u\n", partitions, partitions == 1 ? "" : "s", parttype, (uint32)(ret_val / 512));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uptr->capac = saved_capac;
|
||||||
|
return ret_val;
|
||||||
|
};
|
||||||
|
|
||||||
typedef t_offset (*FILESYSTEM_CHECK)(UNIT *uptr);
|
typedef t_offset (*FILESYSTEM_CHECK)(UNIT *uptr);
|
||||||
|
|
||||||
static t_offset get_filesystem_size (UNIT *uptr)
|
static t_offset get_filesystem_size (UNIT *uptr)
|
||||||
|
@ -1312,6 +1510,11 @@ static FILESYSTEM_CHECK checks[] = {
|
||||||
&get_ods2_filesystem_size,
|
&get_ods2_filesystem_size,
|
||||||
&get_ods1_filesystem_size,
|
&get_ods1_filesystem_size,
|
||||||
&get_ultrix_filesystem_size,
|
&get_ultrix_filesystem_size,
|
||||||
|
&get_rt11_filesystem_size, /* This should be the last entry
|
||||||
|
in the table to reduce the
|
||||||
|
possibility of matching an RT-11
|
||||||
|
container file stored in another
|
||||||
|
filesystem */
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
t_offset ret_val;
|
t_offset ret_val;
|
||||||
|
|
Loading…
Add table
Reference in a new issue