Files
RFS/tools/MZFD/MZFDTool.c.original

630 lines
13 KiB
Plaintext
Executable File
Vendored

#define VERSION "1.01"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <mem.h>
#include <dos.h>
union REGS regs;
struct SREGS sregs;
struct MZ700BootStruct
{
unsigned char Type;
char Signature[6];
char Name[11];
unsigned short StartAddress;
unsigned short FileSize;
unsigned char Dummy[8];
unsigned short SectorAddress;
};
struct MZ700DirectoryStruct
{
unsigned char FileType; // 0x00 -> 1
char FileName[17]; // 0x01 ... 0x11 -> 17
unsigned char LockFlag; // 0x12 -> 1
unsigned char DummyFlag; // 0x13 -> 1
unsigned short FileSize; // 0x14 ... 0x15 -> 2
unsigned short LoadAddress; // 0x16 ... 0x17 -> 2
unsigned short ExecAddress; // 0x18 ... 0x19 -> 2
char Dummy[4]; // 0x1A ... 0x1D -> 4
unsigned short SectorAddress; // 0x1E ... 0x1F -> 2
};
struct CMTHeader
{
unsigned char Attribute;
char Name[17];
unsigned short Size;
unsigned short LoadAddress;
unsigned short ExecAddress;
char Comment[104];
};
char FileTypes[][4] = {
"???",
"OBJ",
"BTX",
"BSD",
"BRD",
"RB ",
"???",
"LIB",
"???",
"???",
"SYS",
"GR "
};
unsigned char DiskParameters[11] =
{0xDF, 0x02, 0x25, 0x01, 16, 0x4E, 0xFF, 0x6C, 0xE5, 100, 8};
// {0xDF, 0x02, 0x25, 0x02, 18, 0x1B, 0xFF, 0x6C, 0xF6, 100, 8}; /* 1.44MB */
char *ErrorMsg[] =
{
"success",
"invalid function",
"address mark not found",
"disk write-protected",
"sector not found / read error",
"reset faild",
"data did not verify correctly",
"disk changed",
"drive parameter activity failed",
"DMA overrun",
"data boundary error",
"bad sector detected",
"bad track detected",
"unsupported track or invalid media",
"invalid number of sectors",
"control data address mark detected",
"DMA arbitration level out of range",
"uncorrectable CRC or ECCerror",
"data ECC corrected"
};
unsigned char SectorBuffer[1024];
unsigned char Drive;
unsigned char Cylinder;
unsigned char Head;
unsigned char Sector;
unsigned int OrgInt1EOffset;
unsigned int OrgInt1ESegment;
void Error(unsigned char Index)
{
printf("Error: %02X - ", Index);
if(Index < 0x12) printf("%s\n", ErrorMsg[Index]);
if(Index == 0x80) puts("No disc in drive!");
exit(1);
}
void ShowSectorBuffer(void)
{
unsigned char ByteCounter;
unsigned char LineCounter;
int Counter;
Counter = 0;
for(LineCounter = 0; LineCounter < 16; LineCounter++)
{
printf("\n%04X : ", Counter);
for(ByteCounter = 0; ByteCounter < 16; ByteCounter++)
{
printf("%02X ", SectorBuffer[Counter + ByteCounter]);
}
printf(" ");
for(ByteCounter = 0; ByteCounter < 16; ByteCounter++)
{
printf("%c", iscntrl(SectorBuffer[Counter]) ? ' ' : SectorBuffer[Counter]);
Counter++;
}
}
puts("");
}
int ResetFloppy(char Drive)
{
regs.h.ah = 0;
regs.h.dl = Drive;
int86(0x13, &regs, &regs);
return(regs.h.ah);
}
int ReadSector(char Drive, char Cylinder, char Head, char Sector)
{
int Counter;
if(Head == 0) Head = 1;
else Head = 0;
regs.h.ah = 0x02;
Counter = 3;
while((regs.h.ah != 0) && (Counter != 0))
{
regs.h.ah = 0x02;
regs.h.al = 1;
regs.h.ch = Cylinder;
regs.h.cl = Sector;
regs.h.dh = Head;
regs.h.dl = Drive;
sregs.es = FP_SEG(SectorBuffer);
regs.x.bx = FP_OFF(SectorBuffer);
int86x(0x13, &regs, &regs, &sregs);
Counter--;
}
for(Counter = 0; Counter < sizeof(SectorBuffer); Counter++)
SectorBuffer[Counter] = ~SectorBuffer[Counter];
return(regs.x.ax);
}
void SaveInt1E(void)
{
OrgInt1EOffset = peek(0x0000, 0x1E * 4);
OrgInt1ESegment = peek(0x0000, 0x1E * 4 + 2);
}
void SetInt1E(unsigned char Type)
{
Type++;
asm cli;
poke(0x0000, 0x1E * 4, FP_OFF(DiskParameters));
poke(0x0000, 0x1E * 4 + 2, FP_SEG(DiskParameters));
asm sti;
}
void ResetInt1E(void)
{
asm cli;
poke(0x0000, 0x1E * 4, OrgInt1EOffset);
poke(0x0000, 0x1E * 4 + 2, OrgInt1ESegment);
asm sti;
}
void ShowDirectory(void)
{
unsigned char SectorCounter;
unsigned char Counter;
unsigned char C, H, S;
struct MZ700BootStruct *Boot;
struct MZ700DirectoryStruct *Entry;
char FileName[18];
unsigned int Result;
// unsigned short LastUsedSector;
puts("");
Result = ReadSector(Drive, 0, 0, 1);
Result = Result >> 8;
if(Result != 0) Error(Result);
Boot = (struct MZ700BootStruct *) SectorBuffer;
memcpy(FileName, Boot->Signature, 6);
FileName[6] = '\0';
if((Boot->Type == 3) && (strcmp(FileName, "IPLPRO") == 0))
{
puts("Floppy is bootable:");
puts("");
memcpy(FileName, Boot->Name, 11);
if(strchr(FileName, 0x0D) != NULL) *strchr(FileName, 0x0D) = '\0';
else FileName[11] = '\0';
printf(" %-17s OBJ %5u ", FileName, Boot->FileSize);
S = Boot->SectorAddress % 16 + 1;
H = (Boot->SectorAddress / 16) % 2;
C = Boot->SectorAddress / 16 / 2;
printf(" %4u (%2u %u %2u)\n", Boot->SectorAddress, C, H, S);
}
else
{
puts("Floppy is not bootable.");
}
puts("");
puts("Directory:");
puts("");
puts(" Name Type Size Lock Load Exec Pos ( C H S)");
puts("");
for(SectorCounter = 1; SectorCounter < 17; SectorCounter++)
{
ReadSector(Drive, 0, 1, SectorCounter);
for(Counter = 0; Counter < 256 / 32; Counter++)
{
Entry = (struct MZ700DirectoryStruct *) &SectorBuffer[Counter * sizeof(struct MZ700DirectoryStruct)];
// if((SectorCounter == 1) && (Counter == 0)) LastUsedSector = Entry->SectorAddress;
if((Entry->FileType > 0) && (Entry->FileType < 0x80))
{
memcpy(FileName, Entry->FileName, 17);
if(strchr(FileName, 0x0D) != NULL) *strchr(FileName, 0x0D) = '\0';
else FileName[17] = '\0';
printf(" %-17s %s %5u %c %04X %04X", FileName, FileTypes[Entry->FileType], Entry->FileSize, Entry->LockFlag ? 'X' : ' ', Entry->LoadAddress, Entry->ExecAddress);
S = Entry->SectorAddress % 16 + 1;
H = (Entry->SectorAddress / 16) % 2;
C = Entry->SectorAddress / 16 / 2;
printf(" %4u (%2u %u %2u)\n", Entry->SectorAddress, C, H, S);
}
}
}
// printf("\nLast used Sector: %u\n\n", LastUsedSector);
}
void CopyFDToMZF(char *FileName)
{
char MZFFileName[13];
char EntryFileName[18];
unsigned char SectorCounter, Counter;
FILE *MZFFile;
struct MZ700DirectoryStruct *Entry;
struct CMTHeader MZFHeader;
unsigned char C, H, S;
unsigned short WriteSize;
unsigned int Result;
S = 0;
Result = ReadSector(Drive, 0, 0, 1); // BootSector
Result = Result >> 8;
if(Result != 0) Error(Result);
SectorBuffer[33] = '\0'; // emergency stop
if(strstr(SectorBuffer, FileName) != NULL)
{
Entry = (struct MZ700DirectoryStruct *) SectorBuffer;
S = Entry->SectorAddress % 16 + 1;
H = (Entry->SectorAddress / 16) % 2;
C = Entry->SectorAddress / 16 / 2;
Entry->FileType = 1;
}
else
{
for(SectorCounter = 1; (SectorCounter < 17) && (S == 0); SectorCounter++)
{
ReadSector(Drive, 0, 1, SectorCounter);
for(Counter = 0; (Counter < 256 / 32) && (S == 0); Counter++)
{
Entry = (struct MZ700DirectoryStruct *) &SectorBuffer[Counter * sizeof(struct MZ700DirectoryStruct)];
if((Entry->FileType > 0) && (Entry->FileType < 0x80))
{
memcpy(EntryFileName, Entry->FileName, 17);
if(strchr(EntryFileName, 0x0D) != NULL) *strchr(EntryFileName, 0x0D) = '\0';
else EntryFileName[17] = '\0';
if(strcmp(FileName, EntryFileName) == 0)
{
S = Entry->SectorAddress % 16 + 1;
H = (Entry->SectorAddress / 16) % 2;
C = Entry->SectorAddress / 16 / 2;
}
}
}
}
}
if(S != 0)
{
memset(MZFFileName, 0, sizeof(MZFFileName));
strncpy(MZFFileName, FileName, 8);
strcat(MZFFileName, ".MZF");
printf("%s found save it as %s\n", FileName, MZFFileName);
MZFFile = fopen(MZFFileName , "wb");
memset(&MZFHeader, 0, sizeof(MZFHeader));
if(Entry->FileType == 0x02) MZFHeader.Attribute = 0x05;
else MZFHeader.Attribute = Entry->FileType;
memcpy(MZFHeader.Name, Entry->FileName, 17);
MZFHeader.Size = Entry->FileSize;
strcat(MZFHeader.Comment, "by MZFDTool");
if((Entry->FileType == 0x01) && (Entry->LoadAddress == 0x0000))
{
MZFHeader.Comment[24] = 0x21;
MZFHeader.Comment[25] = 0x30;
MZFHeader.Comment[26] = 0x11;
MZFHeader.Comment[27] = 0x01;
MZFHeader.Comment[28] = 0x10;
MZFHeader.Comment[29] = 0x00;
MZFHeader.Comment[30] = 0x11;
MZFHeader.Comment[31] = 0xF0;
MZFHeader.Comment[32] = 0xCF;
MZFHeader.Comment[33] = 0xED;
MZFHeader.Comment[34] = 0xB0;
MZFHeader.Comment[35] = 0xC3;
MZFHeader.Comment[36] = 0xF0;
MZFHeader.Comment[37] = 0xCF;
MZFHeader.Comment[40] = 0x21;
MZFHeader.Comment[41] = 0x00;
MZFHeader.Comment[42] = 0x12;
MZFHeader.Comment[43] = 0x01;
MZFHeader.Comment[44] = (unsigned char) Entry->FileSize & 0xFF;
MZFHeader.Comment[45] = Entry->FileSize >> 8;
MZFHeader.Comment[46] = 0x11;
MZFHeader.Comment[47] = 0x00;
MZFHeader.Comment[48] = 0x00;
MZFHeader.Comment[49] = 0xD3;
MZFHeader.Comment[50] = 0xE0;
MZFHeader.Comment[51] = 0xED;
MZFHeader.Comment[52] = 0xB0;
MZFHeader.Comment[53] = 0xC3;
MZFHeader.Comment[54] = 0x00;
MZFHeader.Comment[55] = 0x00;
MZFHeader.LoadAddress = 0x1200;
MZFHeader.ExecAddress = 0x1120;
}
else
{
MZFHeader.LoadAddress = Entry->LoadAddress;
MZFHeader.ExecAddress = Entry->ExecAddress;
}
fwrite(&MZFHeader, sizeof(MZFHeader), 1, MZFFile);
while(MZFHeader.Size != 0)
{
WriteSize = 256;
if(MZFHeader.Size < WriteSize) WriteSize = MZFHeader.Size;
MZFHeader.Size = MZFHeader.Size - WriteSize;
ReadSector(Drive, C, H, S);
fwrite(SectorBuffer, WriteSize, 1, MZFFile);
S++;
if(S == 17)
{
S = 1;
if(H == 0) H = 1;
else
{
C++;
H = 0;
}
}
}
fclose(MZFFile);
}
else
{
puts("");
printf("%s not found!\n", FileName);
puts("");
puts("Remember that capital letters are differenced!");
}
}
void CopyMZFToFD(char *FileName)
{
printf("Not implemented yet (%s)\n", FileName);
}
void Copy(char *FileName)
{
if((strstr(FileName, ".MZF") == NULL) && (strstr(FileName, ".mzf") == NULL)) CopyFDToMZF(FileName);
else CopyMZFToFD(FileName);
}
void ShowMap(void)
{
unsigned short UsedSectors;
unsigned short Counter;
unsigned char BitCounter;
// unsigned char BitMask;
unsigned short BitMask;
unsigned short *SectorsPerTrack;
unsigned char StartTrack;
unsigned int Result;
puts("");
Result = ReadSector(Drive, 0, 0, 16);
Result = Result >> 8;
if(Result != 0) Error(Result);
UsedSectors = SectorBuffer[3] * 256 + SectorBuffer[4];
StartTrack = SectorBuffer[5];
printf("Volume: %c%c%c Used Sectors: %4u\n\n", SectorBuffer[0], SectorBuffer[1], SectorBuffer[2], UsedSectors);
puts("");
puts(" 1111111");
puts("Track ( C H S) 1234567890123456");
puts("");
for(Counter = StartTrack; Counter <= 80; Counter++)
{
printf(" %3d (%2d %s 1) ", Counter, (Counter - 1) / 2, (Counter - 1) % 2 ? "1" : "0");
BitMask = 0x0001;
SectorsPerTrack = (unsigned short *) &SectorBuffer[6 + 2 * (Counter - StartTrack)];
for(BitCounter = 0; BitCounter < 16; BitCounter++)
{
if(*SectorsPerTrack & BitMask) printf("X");
else printf("-");
BitMask = BitMask << 1;
}
puts("");
}
puts("");
}
void Init(void)
{
memset(SectorBuffer, 0, sizeof(SectorBuffer));
Drive = 0;
Cylinder = 0;
Head = 0;
Sector = 1;
}
void Usage(void)
{
puts("usage: mzfdtool dir [DRIVE:]");
puts(" map [DRIVE:]");
puts(" copy [DRIVE:] FILENAME");
puts(" DRIVE: C H S");
puts("");
exit(1);
}
int main(int argc, char *argv[])
{
unsigned int Result;
printf("\nMZFDTool V %s (c) 2002 by BKK\n\n", VERSION);
if(argc == 1) Usage();
Init();
SetInt1E(0);
ResetFloppy(Drive);
if(strcmp(argv[1], "dir") == 0)
{
if(argc == 3)
if(toupper(argv[2][0]) == 'B') Drive = 1;
ShowDirectory();
}
else
{
if(strcmp(argv[1], "copy") == 0)
{
if(argc == 4)
{
if(toupper(argv[2][0]) == 'B') Drive = 1;
Copy(argv[3]);
}
else Copy(argv[2]);
}
else
{
if(strcmp(argv[1], "map") == 0)
{
if(argc == 3)
if(toupper(argv[2][0]) == 'B') Drive = 1;
ShowMap();
}
else
{
if(argc < 3) exit(1);
if(toupper(argv[1][0]) == 'B') Drive = 1;
Cylinder = atoi(argv[2]);
Head = atoi(argv[3]);
Sector = atoi(argv[4]);
printf("Drive: %c CHS: %u %u %u\n", Drive ? 'B' : 'A', Cylinder, Head, Sector);
// Set_Floppy_Medis_Type();
Result = ReadSector(Drive, Cylinder, Head, Sector);
Result = Result >> 8;
if(Result == 0) ShowSectorBuffer();
else Error(Result);
}
}
}
ResetInt1E();
ResetFloppy(Drive);
return(0);
}