PE> No, I'll beat you to getting Tobruk working on the Amiga
PE> though (with messagebase capabilities).
FA> Most likely:)
FA> I don't even know what Tobruk does, is,
It's a mailprocessor. Just like squish. Remember I was recommending
Binkley/Squish/Msged? Well I use Binkley/Tobruk/Msged.
FA> and why it's called Tobruk ??
FA> Didn't we lose a battle there once ? :)
Not unless you're German. First time in WWII the Germans were unable to
take a place.
PE> A simple "Released to the Public Domain" is all you need,
FA> Yes boss, i'll do so in future, it just seems a bit strange for a simple
FA> thing like that.
Several hours of work is not something simple. It's something worth $160
at standard contract rates ($40/hour). If I can get a $160
program for free, I am happy.
FA> I really hate that,i should've declared it "void ShowMedia( void )"
FA> I always thought void func() would assume void for parameters, but it
FA> keeps happening of late so i guess not.
Actually void func() is sort of equivalent to void func(...), ie a variable
number (possibly 0) of parameters, of unknown type. You definitely don't
want that!
FA> I will repost it on the weekend or early next week as a reader/saver
I'll post the one I've currently got ready to go in OZPD...
/*
** Fat saver.. Written by Frank Adam and released to the public domain.
** This will NOT work on an older compiler if you have a modern
** large drive because they (EG. TC2) seem to use the old INT25 absread()
** function, which can not read LBA drives. Compiled in BC4, but
** should port with little pain.
** Only one truely non portable part in this, absread(), there are
** replacements for that out there, but i didn't really want to bother.
** Could replace it with INT25 AX=ffffh, i think.
** Compile in large memory model.
*/
#include
#include /* for memcpy */
#include /* for toupper */
#include
#include
#define BYTE char
#define WORD unsigned int
#define DWORD unsigned long
struct DriveParamBlock /* from Ralph Brown's excellent Interrupt
List */
{
BYTE Driveno; /* drive number (00h = A:, 01h = B:, etc) */
BYTE DevUnit; /* unit number within device driver */
WORD Bpersec; /* bytes per sector */
BYTE Hysect; /* highest sector number within a cluster */
BYTE Shft; /* shift count to convert clusters into
sectors */
WORD ResSecs; /* number of reserved sectors at beginning
of drive */
BYTE NumFats; /* number of FATs */
WORD NumRoot; /* number of root directory entries */
WORD UserFsc; /* number of first sector containing user
data */
WORD MaxClust; /* highest cluster number (number of data
clusters + 1) */
/* 16-bit FAT if greater than 0FF6h, else 12-bit FAT */
WORD SecPerFat; /* number of sectors per FAT */
WORD DirStart; /* sector number of first directory sector */
DWORD DevHead; /* address of device driver header */
BYTE MediaId; /* media ID byte (see #0669) */
BYTE AccessB; /* 00h if disk accessed, FFh if not */
DWORD NextDbp; /* pointer to next DPB */
WORD NextClus; /* cluster at which to start search for
free space */
/* when writing, usually the last cluster allocated */
WORD FreeClus; /* number of free clusters on drive, FFFFh
= unknown */
};
struct BackupData /* this could hold the "where to put it
back" info */
{
int drive;
short fss; /* fat start sector. Always 1(i think) */
int bps; /* bytes per sector 512 on my drives */
int spf; /* sectors per fat 251-2 on my drives */
short fats; /* number of fats (normally 2, 0 here is
not good at all:)) */
/* the two fats are contigous and the same, so one is enough /* to
save, image.exe does the same. */
}
bupdat; /* not yet in use */
char fname[80];
struct DriveParamBlock dpb;
int GetDpb(int drive)
{
union REGS inregs, outregs;
struct SREGS sregs;
char far *p;
inregs.h.ah = 0x32;
inregs.h.dl = drive; /* 0 default drv,1 = A, 2 = B, etc.. */
intdosx(&inregs, &outregs, &sregs);
if (outregs.x.cflag)
return 0;
if (outregs.h.al)
return 0;
p = (char far *)MK_FP((unsigned)sregs.ds, (unsigned)outregs.x.bx);
printf("\nDBP Address = %p\n", p);
memcpy(&dpb, p, sizeof(struct DriveParamBlock));
return 1;
};
int GetFat(int drive)
{
char *fat;
int startsector = 1, j, p = 0;
FILE *out;
int i;
sprintf(fname, "testfat%c.dat\0", (dpb.Driveno + 'A'));
fat = (char *)calloc(dpb.Bpersec, sizeof(unsigned char));
if (NULL == fat)
{
printf("\nNot enough memory");
return 0;
}
out = fopen(fname, "wb");
if (out == NULL)
{
perror("\nError opening file");
return 0;
}
printf("\n\n");
for (i = 0; i < (dpb.SecPerFat); i++)
{
if (absread(drive, 1, i + startsector, fat) != 0)
{
perror("Disk read error");
return 0;
}
printf("\rSector %02d Read OK....", i);
for (j = 0; j < dpb.Bpersec; j++)
p += fwrite(&fat[j], 1, 1, out);
printf("Written %03d items OK", i, p);
p = 0;
}
free(fat);
fclose(out);
return 1; /* phew */
};
void ShowMedia(void) /* just a bit of show off :o) */
{
printf("\n Drive %c media type = ", toupper(dpb.Driveno + 'A'));
switch ((int)dpb.MediaId)
{
case 0xfff0:
if (dpb.SecPerFat > 4 && dpb.SecPerFat < 10)
printf("Probably 1.44M 3.5 floppy");
else
printf("Unrecognized device or CD-ROM drive.");
break;
case 0xfff8:
printf("Hard drive");
break;
case 0xfff9:
printf("DS 1.2M 5.25 floppy");
break;
case 0xfffa:
printf("HP ROM device");
break;
case 0xfffc:
printf("SS 9S/T 180K floppy");
break;
case 0xfffd:
printf("DS 9S/T 360K floppy");
break;
case 0xfffe:
printf("SS 8S/T 160K floppy");
break;
case 0xffff:
printf("DS 8S/T 320K floppy");
break;
default:
printf("Unrecognized device");
break;
}
printf("\nSectors per fat = %d", dpb.SecPerFat);
printf("\nBytes per sector = %d", dpb.Bpersec);
printf("\nNumber of fats = %d", dpb.NumFats);
};
/* Note: i found, a 1.4M can return 0xfff9 if disk/x-copied from a 1.2M */
int main(void)
{
int drive = 1; /*
** try 'A' first, but works fine here
on all my drives ** except the
CD-ROM */
if (GetDpb(drive))
printf("DBP Operation OK..");
else
{
printf("DBP Operation Failed ! ");
return 0;
}
ShowMedia(); /* looking good if we got here */
printf("\n\nProceed with reading FAT ?");
if (toupper(fgetc(stdin)) == 'N')
return 0;
if (GetFat(drive - 1) != 0)
printf("\nFat saved OK to %s.", fname);
return 0;
}
@EOT:
---
* Origin: X (3:711/934.9)
|