Being newly retired, I've spent some time in a return to my CP/M roots.
It's been fun to see the work done by Peter Schorn for the Altair SIMH
simulator. First rate.
Your question tweaked my curiosity. It turns out, as Dennis Boone
suggested elsewhere, that the format for the 1 meg pseudo-floppy is 137
bytes per sector. At least in this implementation, each sector has 3
bytes of E5 prefix, followed by what seems to be a regular 128 byte
sector, followed in turn by a suffix of 6 bytes of E5. Thinking that an
adjusted version of the pseudo-floppy could be created with a little
manipulation, I wrote the following short C code, compiled on Linux with
gcc. On a different system, some minor changes might be needed. Sorry
about putting it into this post, but it's short, and I don't have any web
site to post it. Also note that it reads the whole pseudo-floppy in one
big chunk. On a machine with very limited memory, it may need to be
chopped into more manageable reads.
I named it altair.adjust.c but you can call it whatever you like. You
might need to edit it again after my cutting and pasting.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <string.h>
void usage(void)
{
printf("altair.adjust infile outfile\n");
printf(" where infile is a 1 meg SIMH Altair dsk file and
outfile receives\n");
printf(" the adjusted sectors accessible to cpmtools\n");
}
int main(int argc, char *argv[])
{
int fdread, fdwrite;
int tracks, sectors_per_track, sector_size, track_size;
int c;
char infile[PATH_MAX], outfile[PATH_MAX];
char *data, *cp;
int bytes;
int ret;
if (argc != 3){
usage();
exit(1);
}
strcpy(infile,argv[1]);
strcpy(outfile,argv[2]);
tracks = 254;
sectors_per_track = 32;
sector_size = 137;
if ((fdwrite = open(outfile, O_RDONLY)) != -1){
printf("%s already exists! Continue? (y/n) ", outfile);
c = getchar();
if (c != 'Y' && c != 'y'){
close(fdwrite);
printf("Stopping\n");
exit(1);
}
}
close(fdwrite);
if ((fdwrite = open(outfile, O_CREAT | O_TRUNC | O_WRONLY,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH))
== -1){
printf("Unable to open %s for writing\n", outfile);
exit(1);
}
if ((fdread = open(infile, O_RDONLY)) == -1){
close(fdwrite);
printf("Unable to open %s for reading\n", infile);
exit(1);
}
track_size = sectors_per_track * sector_size;
bytes = tracks * track_size;
if ((data = malloc(bytes)) == NULL){
close(fdwrite);
close(fdread);
printf("Unable to allocate memory!\n");
exit(1);
}
ret = read(fdread,(void *) data, bytes);
if (ret == -1 || ret == 0){
close(fdwrite);
close(fdread);
printf("Unable to read from %s\n",infile);
exit(1);
}
if (ret < bytes)
printf("Expected %d, read %d bytes from %s
\n",bytes,ret,infile);
for (cp = data; cp < data + bytes; cp += sector_size){
write(fdwrite, (const void *) (cp + 3), 128);
}
close(fdread);
close(fdwrite);
free(data);
exit(0);
}
Usage of the compiled executable is "altair.adjust infile outfile", where
the infile is an Altair SIMH 1 meg pseudo-floppy, and outfile is the file
where the prefix and suffix E5's are removed. For example "altair.adjust
cpm2.dsk cpm2adj.dsk".
The adjusted disk can then be accessed by cpmtools if the following is
added to the cpmtools diskdef file.
diskdef altair.adj
seclen 128
tracks 254
sectrk 32
blocksize 2048
maxdir 256
skew 17
boottrk 6
os 2.2
end
As an experiment, I copied 65 files into a blank pseudo-floppy using the
simlulator read utility (r), created an adjusted dsk file, ran "cpmls -f
altair.adj adjusted.dsk" and saw all files listed in the directory. I
used cpmcp to pull the files back out, and all but 1 were identical. The
outlier had 128 bytes of null appended, and truncating them rendered it
identical to the original. I suspect that this reflects some artifact,
but can't say whether its pseudo-disk storage allocation or cpmtools
which contributes.
I thought I'd put this out so others can check my work, comment, and
improve.
I don't know whether anyone has looked at the 8 meg Altair SIMH pseudo-
hardisk with cpmtools yet, but the following cpmtools diskdef seemed to
work OK for me.
diskdef 8megAltairSIMH
seclen 128
tracks 2048
sectrk 32
blocksize 4096
maxdir 1024
skew 0
boottrack 6
os 2.2
end