Files
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

184 lines
4.3 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* This program formats a 5 1/4 inch floppy disk in drive 0 or drive 1
* of the Olivetti M20. The format is ECMA standard for the headers.
* The data fields are filled with 0xE5, which CP/M thinks is a new
* IBM disk. This gives the disk the appearance of having an empty
* directory as far as CP/M is concerned.
*/
#include "stdio.h"
/* densities */
#define SINGLE 0
#define DOUBLE 1
#define BADTRACK -1
#define MAXBAD 2
#define NTRACKS 40
/* Space for humongous buffer */
#define TRACKSIZ 10000
char trakbuf[TRACKSIZ];
int track,
sector,
side,
density,
drive;
int intrlv[16] = { 9, 1, 10, 2,
11, 3, 12, 4,
13, 5, 14, 6,
15, 7, 16, 8};
extern long map_adr();
long physaddr; /* Segmented address of trakbuf */
main(argc,argv)
int argc;
char *argv[];
{
register char c, *p;
physaddr = map_adr((long)trakbuf,0); /* get seg addr */
while(--argc) {
p = *++argv;
if (strcmp(p,"a:") == 0) {
drive = 0;
warn(p);
format(p);
}
else if (strcmp(p,"b:") == 0) {
drive = 1;
warn(p);
format(p);
}
else printf("Unknown drive: %s\n",p);
}
}
/* Routine to format a disk in a given drive */
format(p)
char *p;
{
register int i,j,k;
int badtracks;
badtracks = 0;
/* Start with track 0; this track is special. */
printf("Formatting track %2d",0);
track = 0;
density = SINGLE;
if ( (j = make_zero()) == BADTRACK) {
printf("Can't format track zero; bad diskette\n");
return(-1);
}
/* Now do the other tracks */
density = DOUBLE;
for(track = 1; track<=40; track++) {
printf("%2d",track);
if( (j = dotrack(track)) == BADTRACK) badtracks++;
if (badtracks > MAXBAD) {
printf("%d bad tracks; too many.\n",badtracks);
return(-1);
}
}
printf("\nFormatting of disk in drive %s complete.\n\n",p);
return(badtracks);
}
/* Routine to do one track */
dotrack(track)
{
register int j;
if( (j = doside(0,track)) == BADTRACK) return(BADTRACK);
if( (j = doside(1,track)) == BADTRACK) return(BADTRACK);
return(track);
}
/* Routine to do one double density side */
doside(side,track)
int side,track;
{ register int j,sector;
char *p;
p = trakbuf;
for(j = 0; j < 32; j++) *p++ = 0x4e; /* Index Gap: 32 hx 4E's */
for(sector = 0; sector < 16; sector++) {
for(j = 0; j < 12; j++) *p++ = '\0';
for(j = 0; j < 3; j++) *p++ = 0xf5;
*p++ = 0xfe;
*p++ = track;
*p++ = side;
*p++ = intrlv[sector]; /* use interleave table */
*p++ = (char)DOUBLE;
*p++ = 0xf7; /* Puts two CRC bytes out */
for(j = 0; j < 22; j++) *p++ = 0x4e;
for(j = 0; j < 12; j++) *p++ = '\0';
for(j = 0; j < 3; j++) *p++ = 0xf5;
*p++ = 0xfb;
/* Magic with the data buffer: fill it with hex E5's, and CP/M will think */
/* that it has an empty directory! */
for(j = 0; j < 256; j++) *p++ = 0xe5;
*p++ = 0xf7; /* More CRC's */
for(j = 0; j < 50; j++) *p++ = 0x4e; /* sector gap */
}
/* Now do the end of track gap: 400 hex 4E's */
for(j = 0; j < 400; j++) *p++ = 0x4e;
/* Finally, use assembler magic to write the track image. */
return(writ_im(drive,track,side,physaddr));
}
/* Routine to make track zero, which is special. It's single-density
* on side zero, and double density on side one. Each of these has a
* different header encoding standard.
*/
make_zero()
{
register int j,sector;
char *p;
p = trakbuf;
for( j = 0; j < 16; j++) *p++ = 0xff; /* Index Gap */
for(sector = 0; sector < 16; sector++) {
for(j = 0; j < 6; j++) *p++ = '\0';
*p++ = 0xfe;
*p++ = 0; /* Track # */
*p++ = 0; /* Side # */
*p++ = intrlv[sector];
*p++ = '\0';
*p++ = 0xf7; /* CRC */
for(j = 0; j < 11; j++) *p++ = 0xff;
for(j = 0; j < 6; j++) *p++ = '\0';
*p++ = 0xfb;
for(j = 0; j < 128; j++) *p++ = 0xe5; /* Magic data */
*p++ = 0xf7; /* CRC */
for(j = 0; j < 24; j++) *p++ = 0xff; /* Sector Gap */
}
for(j = 0; j < 200; j++) *p++ = 0xff; /* End-of-track Gap */
j = writ_im(drive,0,0,physaddr); /* Write side 0 special */
if(j == BADTRACK) return(j);
return(doside(1,0)); /* Write side 1 normal */
}
warn(p)
char *p;
{
register int c,cc;
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");
printf("Warning: This will destroy all files on disk %s!\n\n",p);
printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");
printf("Do you wish to continue? ");
c = getchar();
if(c == '\n') exit(1);
else while( (cc = getchar()) != '\n') ;
if(c != 'y' && c != 'Y') exit(1);
return(0);
}