Date : Fri, 02 Jun 2000 12:35:24 +0100
From : Tom Lees <tal26@...>
Subject: Re: Wave level tape encoding & adfs disk format
On Fri, Jun 02, 2000 at 04:02:27AM -0700, Thomas Harte wrote:
> The next targets for my emulator are to properly support tape files and
> possibly loading over the soundcard, and to finish the dfs2adfs (it actually
> does more than that, but no matter) converter such that all the bodged
> 'Electron' games on the 'net are loadable.
[...]
> As for the ADFS, I have checked every file on the BBC Documentation source
> which says 'disk' or 'dfs' anywhere in the title, but to no avail. The
> regulr DFS and Watford DFS62 formats are documented in a file principly
> about the Watford DFS62, but that is all I have found. Does anyone happen to
> know of a less obviously titled document, possibly on another topic, which
> happens to mention the format? I'm talking about at the level of what the
> Electron or BBC sees, I'm not so interested in the low level disk formatting
> and so on. Which is a shame because I have that information!
>
> Thanks in advance, and apologies if I am asking too much.
I can't help for tape, but here's a short C program I wrote to extract files
from an ADFS image. I got the structures from the Electron Plus 3 UG (which
is at home at the moment), but you should be able to find the appropriate
info from here:
/*
* Utility to extract stuff from ADFS images
*/
#include <stdio.h>
#include <string.h>
typedef unsigned char byte;
typedef unsigned int dword;
int map;
#pragma pack(1)
struct threebyte
{
byte lo, mid, hi;
};
#define DECODE_3B(x) (x.lo | (x.mid << 8) | (x.hi << 16))
struct fsmap
{
struct threebyte addr[82];
byte reserved[6];
struct threebyte total_sect;
byte checksum_sect0;
struct threebyte length[82];
byte reserved_1[5];
byte discid[2];
byte bootopt;
byte end_fslist;
byte checksum_sect1;
};
struct adfs_dir
{
byte msn;
byte hugo[4];
struct entry
{
byte name_access[10];
dword load;
dword exec;
dword len;
struct threebyte start_sect;
byte sequence;
} entries[47];
byte zero;
byte filename[10];
struct threebyte parent_ptr;
byte dirtitle[19];
byte reserved[14];
byte msn_copy;
byte hugo_2[4];
byte zero_2;
};
#pragma pack()
FILE *f;
struct fsmap fsm;
void read_sectors (void *ptr, int nsectors, int first)
{
int trk;
int i;
int sect;
int lsect;
if (map)
{
for (i = 0; i < nsectors; i++)
{
trk = (first+i)/10;
sect = (first+i)%10;
if (trk & 1)
lsect = ((80+(trk>>1))*10)+sect;
else
lsect = ((trk>>1)*10)+sect;
printf ("trk%d sect%d --> lsect%d\n", trk, sect, lsect);
fseek (f, lsect*256, SEEK_SET);
fread (ptr + (i*256), 256, 1, f);
}
}
else
{
fseek (f, first*256, SEEK_SET);
fread (ptr, nsectors, 256, f);
}
}
void do_dir (int sector)
{
struct adfs_dir dir;
char namebuf[20], namebuf2[20];
int i, j;
read_sectors (&dir, 5, sector);
if (strncmp (dir.hugo, "Hugo", 4))
printf ("Warning: first hugo mismatch\n");
if (strncmp (dir.hugo_2, "Hugo", 4))
printf ("Warning: second hugo mismatch\n");
for (i = 0; i < 10; i++)
{
namebuf[i] = dir.filename[i] & 0x7f;
if (namebuf[i] == 0xd)
namebuf[i] = 0;
}
for (i = 0; i < 19; i++)
{
namebuf2[i] = dir.dirtitle[i] & 0x7f;
if (namebuf2[i] == 0xd)
namebuf2[i] = 0;
}
namebuf[19] = 0;
printf ("\n%s '%s' (%d %d)\n", namebuf, namebuf2,
dir.msn, dir.msn_copy);
for (i = 0; i < 47; i++)
{
if (dir.entries[i].name_access[0] == 0)
break;
for (j = 0; j < 10; j++)
{
namebuf[j] = dir.entries[i].name_access[j] & 0x7f;
if (namebuf[j] == 0xd)
namebuf[j] = 0;
}
namebuf[10] = 0;
printf ("%.10s %c %c %c %c %08x %08x %d\n",
namebuf,
dir.entries[i].name_access[0] & 0x80 ? 'R' : 'r',
dir.entries[i].name_access[1] & 0x80 ? 'W' : 'w',
dir.entries[i].name_access[2] & 0x80 ? 'L' : 'l',
dir.entries[i].name_access[3] & 0x80 ? 'D' : 'd',
dir.entries[i].load,
dir.entries[i].exec,
dir.entries[i].len);
if (dir.entries[i].name_access[3] & 0x80)
do_dir (DECODE_3B (dir.entries[i].start_sect));
}
printf ("\n");
}
int main(int argc, char *argv[])
{
printf ("%d %d\n", sizeof (struct fsmap),
sizeof (struct adfs_dir));
if (argc >= 3)
map = 1;
else
map = 0;
f = fopen (argv[1], "r");
fread (&fsm, sizeof (fsm), 1, f);
do_dir (2);
}
/* End of file. */
--
Tom Lees <tal26@... > <tom@... > <tom@... >