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
|
||||
RAW Disk Access (including CDROM)
|
||||
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
|
||||
AWS format tape support
|
||||
|
|
203
sim_disk.c
203
sim_disk.c
|
@ -1304,6 +1304,204 @@ uptr->capac = saved_capac;
|
|||
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);
|
||||
|
||||
static t_offset get_filesystem_size (UNIT *uptr)
|
||||
|
@ -1312,6 +1510,11 @@ static FILESYSTEM_CHECK checks[] = {
|
|||
&get_ods2_filesystem_size,
|
||||
&get_ods1_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
|
||||
};
|
||||
t_offset ret_val;
|
||||
|
|
Loading…
Add table
Reference in a new issue