Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
309 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, ®s, REGS_MAIN, REGS_NONE); | ||
} | ||
|
||
|
||
void TerminateWithDosError(byte errorCode) | ||
{ | ||
regs.Bytes.B = errorCode; | ||
DosCall(_TERM, ®s, REGS_MAIN, REGS_NONE); | ||
} | ||
|
||
|
||
void CheckDosVersion() | ||
{ | ||
regs.Bytes.B = 0x5A; | ||
regs.Words.HL = 0x1234; | ||
regs.UWords.DE = 0xABCD; | ||
regs.Words.IX = 0; | ||
DosCall(_DOSVER, ®s, 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)®s2; | ||
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, ®s, 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" |