add directory Minix
This commit is contained in:
281
Minix/CD-ROM-2.0/FDVOL.C
Normal file
281
Minix/CD-ROM-2.0/FDVOL.C
Normal file
@@ -0,0 +1,281 @@
|
||||
/* fdvol.c - A stripped down version of the MINIX vol program. It takes
|
||||
* a file and breaks into into floppy-sized chunks, writing each one raw
|
||||
* to a floppy.
|
||||
*
|
||||
* Usage: fdvol file drive KB [slow]
|
||||
*
|
||||
* Examples: fdvol 1440 a: foo.taz # 1.4 MB floppy a:
|
||||
* fdvol 1200 b: foo.taz # 1.2 MB floppy b:
|
||||
* fdvol slow 360 a: foo.taz # old machine
|
||||
* fdvol 1440 a: foo bar # concatenate
|
||||
*
|
||||
* The optional 'slow' parameter forces the program to write in units of 3
|
||||
* sectors. Folk tradition has it that this works around some buggy BIOSes.
|
||||
*
|
||||
* This code borrows heavily from Mark Becker's RaWrite program.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define TEST 0
|
||||
|
||||
#if !TEST
|
||||
#include <alloc.h>
|
||||
#include <bios.h>
|
||||
#include <dir.h>
|
||||
#include <dos.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE (!FALSE)
|
||||
|
||||
#define SECTORSIZE 512
|
||||
|
||||
#define RESET 0
|
||||
#define LAST 1
|
||||
#define READ 2
|
||||
#define WRITE 3
|
||||
#define VERIFY 4
|
||||
#define FORMAT 5
|
||||
|
||||
int done;
|
||||
char buffer[18*SECTORSIZE]; /* do I/O in units of up to 18 sectors */
|
||||
char testbuf[SECTORSIZE]; /* to do a test read of the first sector */
|
||||
|
||||
|
||||
int handler(void)
|
||||
{
|
||||
/* Catch CTRL-C and CTRL-Break. */
|
||||
|
||||
done = 1;
|
||||
return(0);
|
||||
}
|
||||
|
||||
void msg(char (*s))
|
||||
{
|
||||
/* Print an error message and quit. */
|
||||
|
||||
fprintf(stderr, "%s\n", s);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
void Error(int status, int cyl, int head, int sector)
|
||||
{
|
||||
/* Identify the error code with a real error message. */
|
||||
|
||||
|
||||
fprintf(stderr, "\nError occured while writing cyl %d, head=%d, sector=%d\n", cyl,head,sector+1);
|
||||
switch (status) {
|
||||
case 0x00: msg("Operation Successful"); break;
|
||||
case 0x01: msg("Bad command"); break;
|
||||
case 0x02: msg("Address mark not found"); break;
|
||||
case 0x03: msg("Attempt to write on write-protected disk"); break;
|
||||
case 0x04: msg("Sector not found"); break;
|
||||
case 0x05: msg("Reset failed (hard disk)"); break;
|
||||
case 0x06: msg("Disk changed since last operation"); break;
|
||||
case 0x07: msg("Drive parameter activity failed"); break;
|
||||
case 0x08: msg("DMA overrun"); break;
|
||||
case 0x09: msg("Attempt to DMA across 64K boundary"); break;
|
||||
case 0x0A: msg("Bad sector detected"); break;
|
||||
case 0x0B: msg("Bad track detected"); break;
|
||||
case 0x0C: msg("Unsupported track"); break;
|
||||
case 0x10: msg("Bad CRC/ECC on disk read"); break;
|
||||
case 0x11: msg("CRC/ECC corrected data error"); break;
|
||||
case 0x20: msg("Controller has failed"); break;
|
||||
case 0x40: msg("Seek operation failed"); break;
|
||||
case 0x80: msg("Attachment failed to respond"); break;
|
||||
case 0xAA: msg("Drive not ready (hard disk only"); break;
|
||||
case 0xBB: msg("Undefined error occurred (hard disk only)"); break;
|
||||
case 0xCC: msg("Write fault occurred"); break;
|
||||
case 0xE0: msg("Status error"); break;
|
||||
case 0xFF: msg("Sense operation failed"); break;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
void main(int argc, char *argv[])
|
||||
{
|
||||
int disknr = 1, fdin, count, drive, head, cyl, status, sector;
|
||||
int max_cyl, chunk, nsectors, ct;
|
||||
long offset, drive_size, r, cyl_size;
|
||||
char *p, c;
|
||||
int slow;
|
||||
int kbsize;
|
||||
char **files;
|
||||
int nfiles, i;
|
||||
|
||||
#if !TEST
|
||||
/* Catch breaks. */
|
||||
ctrlbrk(handler);
|
||||
#endif
|
||||
|
||||
#if 0 /* Do we have to clear the screen? */
|
||||
fprintf(stderr, "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
|
||||
#endif
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "slow") == 0) { /* Lousy BIOS? */
|
||||
slow = 1;
|
||||
argc--;
|
||||
argv++;
|
||||
} else {
|
||||
slow = 0;
|
||||
}
|
||||
|
||||
/* Check the arguments for validity. */
|
||||
if (argc < 4)
|
||||
msg("Usage: fdvol [slow] #kilobytes drive-letter file1 [file2 ...]");
|
||||
|
||||
kbsize = atoi(argv[1]);
|
||||
|
||||
p = argv[2];
|
||||
c = *p;
|
||||
if (c == 'a' || c == 'A')
|
||||
drive = 0;
|
||||
else if (c == 'b' || c == 'B')
|
||||
drive = 1;
|
||||
else
|
||||
msg("fdvol: Second parameter must be drive, either a: or b:");
|
||||
|
||||
files = argv + 3;
|
||||
nfiles = argc - 3;
|
||||
|
||||
switch(kbsize) {
|
||||
case 360:
|
||||
cyl_size = 9*2*SECTORSIZE; /* bytes/cylinder */
|
||||
max_cyl = 39; /* zero-based counting */
|
||||
drive_size = cyl_size * (max_cyl+1);
|
||||
chunk = (!slow ? 9 * SECTORSIZE : 3 * SECTORSIZE);
|
||||
nsectors = chunk/SECTORSIZE;
|
||||
break;
|
||||
|
||||
case 720:
|
||||
cyl_size = 9*2*SECTORSIZE; /* bytes/cylinder */
|
||||
max_cyl = 79; /* zero-based counting */
|
||||
drive_size = cyl_size * (max_cyl+1);
|
||||
chunk = (!slow ? 9 * SECTORSIZE : 3 * SECTORSIZE);
|
||||
nsectors = chunk/SECTORSIZE;
|
||||
break;
|
||||
|
||||
case 1200:
|
||||
cyl_size = 15*2*SECTORSIZE; /* bytes/cylinder */
|
||||
max_cyl = 79; /* zero-based counting */
|
||||
drive_size = cyl_size * (max_cyl+1);
|
||||
chunk = (!slow ? 15 * SECTORSIZE : 3 * SECTORSIZE);
|
||||
nsectors = chunk/SECTORSIZE;
|
||||
break;
|
||||
|
||||
case 1440:
|
||||
cyl_size = 18*2*SECTORSIZE; /* bytes/cylinder */
|
||||
max_cyl = 79; /* zero-based counting */
|
||||
drive_size = cyl_size * (max_cyl+1);
|
||||
chunk = (!slow ? 18 * SECTORSIZE : 3 * SECTORSIZE);
|
||||
nsectors = chunk/SECTORSIZE;
|
||||
break;
|
||||
|
||||
default:
|
||||
msg("fdvol: First parameter must be one of: 360, 720, 1200, or 1440");
|
||||
}
|
||||
|
||||
#if !TEST
|
||||
biosdisk(RESET, drive, 0, 0, 0, 0, testbuf);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start writing data to diskette until there is no more data to write.
|
||||
* Optionally read and write in units of 3 sectors. Folk tradition says
|
||||
* that this makes fewer buggy BIOSes unhappy than doing a whole track at a
|
||||
* time.
|
||||
*/
|
||||
offset = 0;
|
||||
i = 0;
|
||||
fdin = -1;
|
||||
|
||||
while(1) {
|
||||
if (done > 0) {
|
||||
if (done == 1) msg("User abort");
|
||||
#if !TEST
|
||||
biosdisk(READ, drive, 0, 0, 1, 1, testbuf); /* Retract head */
|
||||
#endif
|
||||
fprintf(stderr, "Done. \n");
|
||||
exit(done == 1 ? 1 : 0);
|
||||
}
|
||||
|
||||
/* Until a chunk is read. */
|
||||
count = 0;
|
||||
while (count < chunk) {
|
||||
if (fdin == -1) { /* open next file */
|
||||
#if !TEST
|
||||
_fmode = O_BINARY;
|
||||
#endif
|
||||
fdin = open(files[i], O_RDONLY);
|
||||
if (fdin < 0) {
|
||||
perror(files[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* read from file */
|
||||
ct = read(fdin, buffer + count, chunk - count);
|
||||
if (ct < 0) {
|
||||
perror(files[i]);
|
||||
exit(1);
|
||||
}
|
||||
if (ct == 0) { /* end of file */
|
||||
close(fdin);
|
||||
fdin = -1;
|
||||
|
||||
/* choose next file */
|
||||
if (++i >= nfiles) break; /* no more files */
|
||||
}
|
||||
count += ct;
|
||||
}
|
||||
|
||||
if (count == 0) { /* absolute EOF */
|
||||
done = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count < chunk) { /* pad last track */
|
||||
/* Pad out buffer with zeroes. */
|
||||
p = &buffer[count];
|
||||
while (p < &buffer[chunk]) *p++ = 0;
|
||||
done = 2;
|
||||
}
|
||||
|
||||
r = offset % drive_size;
|
||||
if (r == 0) {
|
||||
/* An integral number of diskettes have been filled. Prompt. */
|
||||
fprintf(stderr, "Please insert formatted diskette #%d in drive %c, then hit Enter%c\n", disknr, c, 7);
|
||||
disknr++;
|
||||
#if !TEST
|
||||
while(bioskey(1) == 0) ; /* wait for input */
|
||||
if ((bioskey(0) & 0x7F) == 3) exit(1); /* CTRL-C */
|
||||
biosdisk(READ, drive, 0, 0, 1, 1, testbuf); /* get it going */
|
||||
#endif
|
||||
|
||||
}
|
||||
/* Compute cyl, head, sector. */
|
||||
cyl = r/cyl_size;
|
||||
r -= cyl * cyl_size;
|
||||
head = (r < cyl_size/2 ? 0 : 1);
|
||||
r -= head * cyl_size/2;
|
||||
sector = r/SECTORSIZE;
|
||||
|
||||
fprintf(stderr, "Track: %2d Head: %d Sector: %2d File offset: %ld\r",
|
||||
cyl, head, sector+1,offset);
|
||||
#if !TEST
|
||||
status = biosdisk(WRITE, drive, head, cyl, sector+1, nsectors, buffer);
|
||||
if (status != 0) Error(status, cyl, head, sector);
|
||||
#else
|
||||
write(1, buffer, chunk);
|
||||
#endif
|
||||
offset += chunk;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user