mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
184 lines
4.3 KiB
C
184 lines
4.3 KiB
C
/*
|
||
* 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);
|
||
}
|