home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
354.lha
/
MSH_v1.5
/
src
/
messyfmt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-12
|
9KB
|
343 lines
/*
* MESSYFMT.C
*
* Formats a disk. Low-level formatting can also be done by mounting a file
* system and using the AmigaDOS format command.
*
* This code is (C) Copyright 1989,1990 by Olaf Seibert. All rights reserved.
* May not be used or copied without a licence.
*/
#include <stdio.h>
#include "han.h"
extern int Enable_Abort;
ulong BootBlock[] = {
0xEB349049, 0x424D2020, 0x332E3200, 0x02020100, /* ...IBM 3.2..... */
0x027000A0, 0x05F90300, 0x09000200, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x0000000F,
0x00000000, 0x0100FA33, 0xC08ED0BC, 0x007C1607,
0xBB780036, 0xC5371E56, 0x1653BF2B, 0x7CB90B00,
0xFCAC2680, 0x3D007403, 0x268A05AA, 0x8AC4E2F1,
0x061F8947, 0x02C7072B, 0x7CFBCD13, 0x7267A010,
0x7C98F726, 0x167C0306, 0x1C7C0306, 0x0E7CA33F,
0x7CA3377C, 0xB82000F7, 0x26117C8B, 0x1E0B7C03,
0xC348F7F3, 0x0106377C, 0xBB0005A1, 0x3F7CE896,
0x00B80102, 0xE8AA0072, 0x198BFBB9, 0x0B00BECD,
0x7DF3A675, 0x0D8D7F20, 0xBED87DB9, 0x0B00F3A6,
0x7418BE6E, 0x7DE86100, 0x32E4CD16, 0x5E1F8F04,
0x8F4402CD, 0x19BEB77D, 0xEBEBA11C, 0x0533D2F7,
0x360B7CFE, 0xC0A23C7C, 0xA1377CA3, 0x3D7CBB00,
0x07A1377C, 0xE84000A1, 0x187C2A06, 0x3B7C4050,
0xE84E0058, 0x72CF2806, 0x3C7C760C, 0x0106377C,
0xF7260B7C, 0x03D8EBD9, 0x8A2E157C, 0x8A16FD7D,
0x8B1E3D7C, 0xEA000070, 0x00AC0AC0, 0x7422B40E,
0xBB0700CD, 0x10EBF233, 0xD2F73618, 0x7CFEC288,
0x163B7C33, 0xD2F7361A, 0x7C88162A, 0x7CA3397C,
0xC3B4028B, 0x16397CB1, 0x06D2E60A, 0x363B7C8B,
0xCA86E98A, 0x16FD7D8A, 0x362A7CCD, 0x13C30D0A,
0x4E6F6E2D, 0x53797374, 0x656D2064, 0x69736B20, /* Non-System disk */
0x6F722064, 0x69736B20, 0x6572726F, 0x720D0A52, /* or disk error..R */
0x65706C61, 0x63652061, 0x6E642073, 0x7472696B, /* eplace and strik */
0x6520616E, 0x79206B65, 0x79207768, 0x656E2072, /* e any key when r */
0x65616479, 0x0D0A000D, 0x0A446973, 0x6B20426F, /* eady.....Disk Bo */
0x6F742066, 0x61696C75, 0x72650D0A, 0x0049424D, /* ot failure...IBM */
0x42494F20, 0x20434F4D, 0x49424D44, 0x4F532020, /* BIO COMIBMDOS */
0x434F4D00, 0x00000000, 0x00000000, 0x00000000, /* COM............. */
0x00000000, 0x00000000, 0x00000000, 0x000055AA,
};
byte *DiskTrack;
long TrackSize;
int Track;
int LowTrack;
word nsides;
struct IOExtTD *TDReq,
*CreateExtIO();
char *Device;
int
todigit(c)
register char c;
{
if ((c -= '0') < 0 || c > ('F' - '0'))
return 42;
if (c >= ('A' - '0')) {
c -= 'A' - '9' - 1;
}
return c;
}
long
ntoi(str)
register char *str;
{
register long total = 0;
register long value;
register int digit;
register int base;
/* First determine the base */
number:
if (*str == '0') {
if (*++str == 'x') { /* 0x means hexadecimal */
base = 16;
str++;
} else {
base = 8; /* Otherwise, 0 means octal */
}
} else {
base = 10; /* and any other digit means decimal */
}
value = 0;
while ((digit = todigit(*str)) < base) {
value *= base;
value += digit;
str++;
}
suffix:
switch (*str++) {
case 'm': /* scale with megabytes */
value *= 1024L * 1024;
goto suffix;
case 'k': /* scale with kilobytes */
value *= 1024;
goto suffix;
case 's': /* scale with sectors */
value *= TD_SECTOR; /* or maybe even kilosectors! */
goto suffix;
case 'b': /* scale with bytes */
goto suffix;
}
str--;
total += value;
if (*str >= '0' && *str <= '9')
goto number; /* Allow 10k512, recursion eliminated */
return total;
}
word
input(question, defval)
char *question;
word defval;
{
char buf[80];
printf("%s? [%d] ", question, defval);
fflush(stdout);
if (fgets(buf, sizeof (buf) - 1, stdin)) {
if (buf[0] && buf[0] != '\n')
defval = ntoi(buf);
}
return defval;
}
void
PutWord(address, value)
register byte *address;
register word value;
{
address[0] = value;
address[1] = value >> 8;
}
word
SetWord(address, question, value)
byte *address;
char *question;
word value;
{
value = input(question, value);
PutWord(address, value);
return value;
}
byte
SetByte(address, question, value)
byte *address;
char *question;
word value;
{
value = input(question, value);
return *address = value;
}
byte *
MaybeWrite(block)
byte *block;
{
while (block >= (DiskTrack + TrackSize)) {
int t,
s;
t = Track / nsides;
s = Track % nsides;
printf(" Writing cylinder %3d side %d...\r", t, s);
fflush(stdout);
TDReq->iotd_Req.io_Command = TD_FORMAT;
TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
TDReq->iotd_Req.io_Length = TrackSize;
TDReq->iotd_Req.io_Offset = TrackSize * Track;
DoIO(TDReq);
if (TDReq->iotd_Req.io_Error) {
printf(" Write error %d on cylinder %d side %d.\n",
TDReq->iotd_Req.io_Error, t, s);
}
TDReq->iotd_Req.io_Command = CMD_UPDATE;
DoIO(TDReq);
if (TDReq->iotd_Req.io_Error) {
printf("Update error %d on cylinder %d side %d.\n",
TDReq->iotd_Req.io_Error, t, s);
}
TDReq->iotd_Req.io_Command = CMD_CLEAR;
DoIO(TDReq);
printf(" Read\r");
fflush(stdout);
TDReq->iotd_Req.io_Command = CMD_READ;
TDReq->iotd_Req.io_Data = (APTR) DiskTrack;
TDReq->iotd_Req.io_Length = TrackSize;
TDReq->iotd_Req.io_Offset = TrackSize * Track;
DoIO(TDReq);
if (TDReq->iotd_Req.io_Error) {
printf(" Read error %d on cylinder %d side %d.\n",
TDReq->iotd_Req.io_Error, t, s);
}
setmem(DiskTrack, (int) TrackSize, 0);
Track++;
if ((block -= TrackSize) < DiskTrack)
block = DiskTrack;
}
return block;
}
main(argc, argv)
int argc;
char **argv;
{
struct MsgPort *port,
*CreatePort();
byte *diskBlock;
long unitNr;
int i;
word bps = MS_BPS,
spt = MS_SPT;
word res,
nfats,
spf,
nsects,
ncylinders,
ndirs,
wholeDisk,
endtrack;
if (argc < 2) {
printf("Usage: %s <unitnr> <device>\n"
"Formats a messydos volume in any desired shape.\n",
argv[0]);
exit(1);
}
Enable_Abort = 0;
unitNr = ntoi(argv[1]);
if (argc > 2)
Device = argv[2];
else
Device = "messydisk.device";
if (!(port = CreatePort(NULL, 0L))) {
puts("No memory for replyport");
goto abort1;
}
if (!(TDReq = CreateExtIO(port, (long) sizeof (*TDReq)))) {
puts("No memory for I/O request");
goto abort2;
}
if (OpenDevice(Device, unitNr, TDReq, 0L)) {
printf("Cannot OpenDevice %s\n", Device);
goto abort3;
}
bps = input("Bytes per sector", bps);
spt = input("Sectors per track", spt);
TrackSize = bps * spt;
nsides = input("Number of sides", MS_NSIDES);
Track = input("Starting cylinder", 0);
Track *= nsides;
ncylinders = input("Number of cylinders", 80);
endtrack = Track + nsides * ncylinders;
if ((DiskTrack = AllocMem(TrackSize,
MEMF_PUBLIC | MEMF_CHIP | MEMF_CLEAR)) == NULL) {
puts("No memory for track buffer");
goto abort4;
}
CopyMem(BootBlock, DiskTrack, (long) sizeof (BootBlock));
PutWord(DiskTrack + 0x0b, bps);
SetByte(DiskTrack + 0x0d, "Sectors per cluster", MS_SPC);
res = SetWord(DiskTrack + 0x0e, "Bootsectors", MS_RES);
nfats = SetByte(DiskTrack + 0x10, "Number of FAT copies", MS_NFATS);
ndirs = SetWord(DiskTrack + 0x11, "Root directory entries", MS_NDIRS);
nsects = SetWord(DiskTrack + 0x13, "Total number of sectors", spt * ncylinders * nsides);
SetByte(DiskTrack + 0x15, "Media byte", 0xF9);
spf = SetWord(DiskTrack + 0x16, "Sectors per FAT", MS_SPF);
PutWord(DiskTrack + 0x18, spt);
PutWord(DiskTrack + 0x1a, nsides);
SetWord(DiskTrack + 0x1c, "Number of hidden sectors", 0);
wholeDisk = input("Format whole disk (enter 1)", 0);
if (input("Are you sure? (enter 42)", 0) != 42)
goto abort5;
if (Chk_Abort())
goto abort5;
/* Go to first FAT */
diskBlock = MaybeWrite(DiskTrack + bps * res);
for (i = 0; i < nfats; i++) {
diskBlock[0] = 0xF9;
diskBlock[1] = 0xFF;
diskBlock[2] = 0xFF;
diskBlock = MaybeWrite(diskBlock + bps * spf); /* Next FAT */
}
/* Clear entire directory */
diskBlock = MaybeWrite(diskBlock + ndirs * MS_DIRENTSIZE);
MaybeWrite(DiskTrack + TrackSize); /* Force a write */
ncylinders *= nsides;
if (wholeDisk) {
while (Track < ncylinders) {
MaybeWrite(DiskTrack + TrackSize); /* Write an empty track */
if (Chk_Abort())
break;
}
}
TDReq->iotd_Req.io_Command = TD_MOTOR;
TDReq->iotd_Req.io_Length = 0;
DoIO(TDReq);
printf("\n\nNow remove the disk from the drive (or use DiskChange).\n");
abort5:
FreeMem(DiskTrack, TrackSize);
abort4:
CloseDevice(TDReq);
abort3:
DeleteExtIO(TDReq);
abort2:
DeletePort(port);
abort1:;
}
_wb_parse()
{
}