Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Konamiman committed Oct 29, 2023
1 parent fd5631e commit b66ac3f
Show file tree
Hide file tree
Showing 2 changed files with 309 additions and 0 deletions.
7 changes: 7 additions & 0 deletions source/tools/C/buildeptcft
@@ -0,0 +1,7 @@
#!/bin/bash
set -e
sdcc --code-loc 0x180 --data-loc 0 -mz80 --disable-warning 85 --disable-warning 196 --no-std-crt0 crt0_msxdos_advanced.rel eptcft.c
objcopy -I ihex -O binary eptcft.ihx eptcft.com
sudo mount -o loop,uid=konamiman,gid=konamiman /mnt/d/Dropbox/Dropbox/MSX/msxdos/discosa.dsk ~/floppy
cp eptcft.com ~/floppy
sudo umount ~/floppy
302 changes: 302 additions & 0 deletions source/tools/C/eptcft.c
@@ -0,0 +1,302 @@
/* Extended partition type code fix tool v1.0
By Konamiman 11/2023
Compilation command line:
sdcc --code-loc 0x180 --data-loc 0 -mz80 --disable-warning 196
--no-std-crt0 crt0_msxdos_advanced.rel
eptcft.c
hex2bin -e com eptcft.ihx
*/

/* Includes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "strcmpi.h"
#include "asmcall.h"
#include "types.h"
#include "dos.h"
#include "partit.h"

/* Defines */

#define PTYPE_EXTENDED_CHS 5
#define PTYPE_EXTENDED_LBA 15

/* Strings */

const char* strTitle=
"Extended Partition Type Code Fix Tool v1.0\r\n"
"By Konamiman, 5/2014\r\n"
"\r\n";

const char* strUsage=
"Usage: eptcft <drive>:|<device>[-<LUN>] <slot> [fix|unfix] \r\n"
"\r\n"
"This tool checks the partition type code used by extended partitions\r\n"
"existing on a given device controlled by a Nextor driver.\r\n"
"If a drive letter is specified, the device the drive is mapped to is used.\r\n"
"\r\n"
"Since Nextor 2.1.2 FDISK creates extended partitions with code 15\r\n"
"(extended LBA), in older Nextor versions FDISK uses code 5 (extended CHS)\r\n"
"for new extended partitions, which is incorrect.\r\n"
"\r\n"
"Adding \"fix\" will change the extended partitions that have code 5 to 15\r\n"
"in the device, adding \"unfix\" will do the opposite (might be needed for\r\n"
"old partition handling tools that assume code 5 for extended partitions).\r\n";

const char* strInvParam = "Invalid parameter";
const char* strCRLF = "\r\n";


/* Global variables */

byte ASMRUT[4];
byte OUT_FLAGS;
Z80_registers regs;
Z80_registers regs2;
bool isNextor;
masterBootRecord* mbrBuffer = (masterBootRecord*)0x8000;
driveLetterInfo* dliBuffer = (driveLetterInfo*)0x8200;
driverInfo* driverInfoBuffer = (driverInfo*)0x8200;
char* stringBuffer = (char*)0x8000;
int driveNumber; //-1=No drive specified, 0=A:, etc
byte deviceNumber;
byte lunNumber;
byte slotNumber;
bool doFix;
bool doUnfix;


/* Some handy code defines */

#define PrintNewLine() printf(strCRLF)
#define StringIs(a, b) (strcmpi(a,b)==0)


/* Function prototypes */

void Terminate(const char* errorMessage);
void TerminateWithDosError(byte errorCode);
void CheckDosVersion();
void ExtractParameters(char** argv, int argc);
void ProcessParameters();
void DoDosCall(byte functionCode);

void print(char* s);


/* MAIN */

int main(char** argv, int argc)
{
ASMRUT[0] = 0xC3;
print(strTitle);

if(argc == 0) {
print(strUsage);
Terminate(null);
}

CheckDosVersion();
ExtractParameters(argv, argc);
ProcessParameters();

//WIP: Scan partitions

Terminate(null);
return 0;
}


/* Functions */

void Terminate(const char* errorMessage)
{
if(errorMessage != NULL) {
printf("\r\x1BK*** %s\r\n", errorMessage);
}

regs.Bytes.B = (errorMessage == NULL ? 0 : 1);
DosCall(_TERM, &regs, REGS_MAIN, REGS_NONE);
}


void TerminateWithDosError(byte errorCode)
{
regs.Bytes.B = errorCode;
DosCall(_TERM, &regs, REGS_MAIN, REGS_NONE);
}


void CheckDosVersion()
{
regs.Bytes.B = 0x5A;
regs.Words.HL = 0x1234;
regs.UWords.DE = 0xABCD;
regs.Words.IX = 0;
DosCall(_DOSVER, &regs, REGS_ALL, REGS_ALL);

if(regs.Bytes.B < 2 || regs.Bytes.IXh != 1) {
Terminate("This program is for Nextor only.");
}
}


void ExtractParameters(char** argv, int argc)
{
int fixParamIndex;

if(argv[0][1] == ':') {
driveNumber = (argv[0][0] | 32) - 'a';
fixParamIndex = 1;
}
else {
if(argc < 2) {
Terminate(strInvParam);
}
driveNumber = -1;

deviceNumber = argv[0][0];
if(deviceNumber < '1' || deviceNumber > '7') {
Terminate(strInvParam);
}
deviceNumber -= '0';

if(argv[0][1] == '-') {
lunNumber = argv[0][2];
if(lunNumber < '0' || lunNumber > '7') {
Terminate(strInvParam);
}
lunNumber -= '0'; - '0';
}
else {
lunNumber = 0;
}

slotNumber = argv[1][0];
if(slotNumber < '0' || slotNumber > '3') {
Terminate(strInvParam);
}
slotNumber -= '0';

if(argv[1][1] == '-') {
if(argv[1][2] < '0' || argv[1][2] > '3') {
Terminate(strInvParam);
}
slotNumber += 0x80 + ((argv[1][2] - '0') << 2);
}

fixParamIndex = 2;
}

if(argc < fixParamIndex + 1) {
return;
}

if(strcmpi(argv[2], "fix") == 0) {
doFix = true;
}
else if(strcmpi(argv[2], "unfix") == 0) {
doUnfix = true;
}
else {
Terminate(strInvParam);
}
}


void ProcessParameters() {
int i;

if(driveNumber != -1) {
regs.Bytes.A = driveNumber;
regs.Words.HL = (int)dliBuffer;
DoDosCall(_GDLI);

switch(dliBuffer->driveStatus) {
case 0:
Terminate("The specified drive is unassigned");
break;
case 1:
break;
case 3:
Terminate("The specified drive is mapped to a mounted file");
break;
case 4:
Terminate("The specified drive is mapped to the RAM disk");
break;
default:
printf("The specified drive has unknown status: %i\r\n", dliBuffer->driveStatus);
TerminateWithDosError(1);
break;
}

slotNumber = dliBuffer->driverSlotNumber;
deviceNumber = dliBuffer->deviceIndex;
lunNumber = dliBuffer->logicalUnitNumber;

if(deviceNumber == 0) {
Terminate("The specified drive is mapped to a MSX-DOS controller");
}
}

regs.Bytes.A = 0;
regs.Bytes.D = slotNumber;
regs.Bytes.E = 0xFF;
regs.Words.HL = (int)driverInfoBuffer;
DoDosCall(_GDRVR);
for(int i=31; i>0; i--) {
if(driverInfoBuffer->driverName[i] != ' ') {
driverInfoBuffer->driverName[i+1] = '\0';
break;
}
}
printf("Driver: %s v%i.%i.%i in slot ", driverInfoBuffer->driverName, driverInfoBuffer->versionMain, driverInfoBuffer->versionSec, driverInfoBuffer->versionRev);
if(slotNumber & 0x80) {
printf("%i-%i\r\n", slotNumber & 3, (slotNumber >> 2) & 3);
}
else {
printf("%i\r\n", slotNumber);
}

regs.Bytes.A = slotNumber;
regs.Bytes.B = 0xFF;
regs.Words.DE = DEV_INFO;
regs.Words.HL = (int)&regs2;
regs2.Bytes.A = deviceNumber;
regs2.Bytes.B = 2; //Device name string
regs2.Words.HL = (int)stringBuffer;
DoDosCall(_CDRVR);
if(regs2.Bytes.IXh == 0) {
for(int i=31; i>0; i--) {
if(stringBuffer[i] != ' ') {
stringBuffer[i+1] = '\0';
break;
}
}
printf("Device %i, %s\r\n", deviceNumber, stringBuffer);
}
else {
printf("Device %i\r\n", deviceNumber);
}
}

void DoDosCall(byte functionCode)
{
DosCall(functionCode, &regs, REGS_ALL, REGS_ALL);
if(regs.Bytes.A != 0) {
TerminateWithDosError(regs.Bytes.A);
}
}


#define COM_FILE
#include "print_msxdos.c"
#include "printf.c"
#include "asmcall.c"
#include "strcmpi.c"

0 comments on commit b66ac3f

Please sign in to comment.