mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-01-13 15:17:43 +00:00
Minimig hardfile(filesys) fix
This commit is contained in:
parent
89f9d710dd
commit
a60a369362
593
hdd.c
593
hdd.c
@ -42,220 +42,221 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// hardfile structure
|
// hardfile structure
|
||||||
hdfTYPE hdf[2];
|
hdfTYPE hdf[2];
|
||||||
|
|
||||||
static void RDBChecksum(unsigned long *p)
|
static void RDBChecksum(unsigned long *p) {
|
||||||
{
|
unsigned long count=p[1];
|
||||||
unsigned long count=p[1];
|
unsigned long c2;
|
||||||
unsigned long c2;
|
long result=0;
|
||||||
long result=0;
|
p[2]=0;
|
||||||
p[2]=0;
|
for(c2=0;c2<count;++c2)
|
||||||
for(c2=0;c2<count;++c2)
|
result+=p[c2];
|
||||||
result+=p[c2];
|
p[2]=(unsigned long)-result;
|
||||||
p[2]=(unsigned long)-result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SWAP(a) ((((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24))
|
||||||
|
|
||||||
// If the hardfile doesn't have a RigidDiskBlock,
|
// If the hardfile doesn't have a RigidDiskBlock,
|
||||||
// we synthesize one.
|
// we synthesize one.
|
||||||
static void FakeRDB(int unit,int block)
|
static void FakeRDB(int unit,int block) {
|
||||||
{
|
int i;
|
||||||
int i;
|
// Start by clearing the sector buffer
|
||||||
// Start by clearing the sector buffer
|
memset(sector_buffer, 0, 512);
|
||||||
for(i=0;i<512;++i)
|
|
||||||
sector_buffer[i]=0;
|
|
||||||
|
|
||||||
// If we're asked for LBA 0 we create an RDSK block, and if LBA 1, a PART block.
|
// If we're asked for LBA 0 we create an RDSK block, and if LBA 1, a PART block.
|
||||||
switch(block)
|
switch(block) {
|
||||||
{
|
case 0: { // RDB
|
||||||
case 0: // RDB
|
hdd_debugf("FAKE: RDB");
|
||||||
{
|
|
||||||
struct RigidDiskBlock *rdb=(struct RigidDiskBlock *)sector_buffer;
|
|
||||||
rdb->rdb_ID = 'R'<<24 | 'D' << 16 | 'S' << 8 | 'K';
|
|
||||||
|
|
||||||
rdb->rdb_Summedlongs=0x40;
|
|
||||||
rdb->rdb_HostID=0x07;
|
|
||||||
rdb->rdb_BlockBytes=0x200;
|
|
||||||
rdb->rdb_Flags=0x12; // (Disk ID valid, no LUNs after this one)
|
|
||||||
rdb->rdb_BadBlockList=0xffffffff; // We don't provide a bad block list
|
|
||||||
rdb->rdb_PartitionList=1;
|
|
||||||
rdb->rdb_FileSysHeaderList=0xffffffff;
|
|
||||||
rdb->rdb_DriveInit=0xffffffff;
|
|
||||||
rdb->rdb_Reserved1[0]=0xffffffff;
|
|
||||||
rdb->rdb_Reserved1[1]=0xffffffff;
|
|
||||||
rdb->rdb_Reserved1[2]=0xffffffff;
|
|
||||||
rdb->rdb_Reserved1[3]=0xffffffff;
|
|
||||||
rdb->rdb_Reserved1[4]=0xffffffff;
|
|
||||||
rdb->rdb_Reserved1[5]=0xffffffff;
|
|
||||||
rdb->rdb_Cylinders=hdf[unit].cylinders;
|
|
||||||
rdb->rdb_Sectors=hdf[unit].sectors;
|
|
||||||
rdb->rdb_Heads=hdf[unit].heads;
|
|
||||||
rdb->rdb_Interleave=1;
|
|
||||||
rdb->rdb_Park=rdb->rdb_Cylinders;
|
|
||||||
rdb->rdb_WritePreComp=rdb->rdb_Cylinders;
|
|
||||||
rdb->rdb_ReducedWrite=rdb->rdb_Cylinders;
|
|
||||||
rdb->rdb_StepRate=3;
|
|
||||||
rdb->rdb_RDBBlocksLo=0;
|
|
||||||
rdb->rdb_RDBBlocksHi=1;
|
|
||||||
rdb->rdb_LoCylinder=1;
|
|
||||||
rdb->rdb_HiCylinder=rdb->rdb_Cylinders-1;
|
|
||||||
rdb->rdb_CylBlocks=rdb->rdb_Heads * rdb->rdb_Sectors;
|
|
||||||
rdb->rdb_AutoParkSeconds=0;
|
|
||||||
rdb->rdb_HighRDSKBlock=1;
|
|
||||||
strcpy(rdb->rdb_DiskVendor,"Do not ");
|
|
||||||
strcpy(rdb->rdb_DiskProduct, "repartition!");
|
|
||||||
|
|
||||||
RDBChecksum((unsigned long *)rdb);
|
struct RigidDiskBlock *rdb=(struct RigidDiskBlock *)sector_buffer;
|
||||||
}
|
rdb->rdb_ID = 'R'<<24 | 'D' << 16 | 'S' << 8 | 'K';
|
||||||
break;
|
|
||||||
case 1: // Partition
|
rdb->rdb_Summedlongs=0x40;
|
||||||
{
|
rdb->rdb_HostID=0x07;
|
||||||
struct PartitionBlock *pb=(struct PartitionBlock *)sector_buffer;
|
rdb->rdb_BlockBytes=0x200;
|
||||||
pb->pb_ID = 'P'<<24 | 'A' << 16 | 'R' << 8 | 'T';
|
rdb->rdb_Flags=0x12; // (Disk ID valid, no LUNs after this one)
|
||||||
|
rdb->rdb_BadBlockList=0xffffffff; // We don't provide a bad block list
|
||||||
pb->pb_Summedlongs=0x40;
|
rdb->rdb_PartitionList=1;
|
||||||
pb->pb_HostID=0x07;
|
rdb->rdb_FileSysHeaderList=0xffffffff;
|
||||||
pb->pb_Next=0xffffffff;
|
rdb->rdb_DriveInit=0xffffffff;
|
||||||
pb->pb_Flags=0x1; // Bootable
|
rdb->rdb_Reserved1[0]=0xffffffff;
|
||||||
pb->pb_DevFlags=0;
|
rdb->rdb_Reserved1[1]=0xffffffff;
|
||||||
strcpy(pb->pb_DriveName," DH0");
|
rdb->rdb_Reserved1[2]=0xffffffff;
|
||||||
pb->pb_DriveName[0]=3; // BCPL string
|
rdb->rdb_Reserved1[3]=0xffffffff;
|
||||||
|
rdb->rdb_Reserved1[4]=0xffffffff;
|
||||||
|
rdb->rdb_Reserved1[5]=0xffffffff;
|
||||||
|
rdb->rdb_Cylinders=hdf[unit].cylinders;
|
||||||
|
rdb->rdb_Sectors=hdf[unit].sectors;
|
||||||
|
rdb->rdb_Heads=hdf[unit].heads;
|
||||||
|
rdb->rdb_Interleave=1;
|
||||||
|
rdb->rdb_Park=rdb->rdb_Cylinders;
|
||||||
|
rdb->rdb_WritePreComp=rdb->rdb_Cylinders;
|
||||||
|
rdb->rdb_ReducedWrite=rdb->rdb_Cylinders;
|
||||||
|
rdb->rdb_StepRate=3;
|
||||||
|
rdb->rdb_RDBBlocksLo=0;
|
||||||
|
rdb->rdb_RDBBlocksHi=1;
|
||||||
|
rdb->rdb_LoCylinder=1;
|
||||||
|
rdb->rdb_HiCylinder=rdb->rdb_Cylinders-1;
|
||||||
|
rdb->rdb_CylBlocks=rdb->rdb_Heads * rdb->rdb_Sectors;
|
||||||
|
rdb->rdb_AutoParkSeconds=0;
|
||||||
|
rdb->rdb_HighRDSKBlock=1;
|
||||||
|
strcpy(rdb->rdb_DiskVendor,"Do not ");
|
||||||
|
strcpy(rdb->rdb_DiskProduct, "repartition!");
|
||||||
|
|
||||||
|
// swap byte order of strings to be able to "unswap" them after checksum
|
||||||
|
unsigned long *p = (unsigned long*)rdb;
|
||||||
|
for(i=0;i<(8+16)/4;i++) p[40+i] = SWAP(p[40+i]);
|
||||||
|
|
||||||
pb->pb_Environment.de_TableSize=0x10;
|
RDBChecksum((unsigned long *)rdb);
|
||||||
pb->pb_Environment.de_SizeBlock=0x80;
|
|
||||||
pb->pb_Environment.de_Surfaces=hdf[unit].heads;
|
|
||||||
pb->pb_Environment.de_SectorPerBlock=1;
|
|
||||||
pb->pb_Environment.de_BlocksPerTrack=hdf[unit].sectors;
|
|
||||||
pb->pb_Environment.de_Reserved=2;
|
|
||||||
pb->pb_Environment.de_LowCyl=1;
|
|
||||||
pb->pb_Environment.de_HighCyl=hdf[unit].cylinders-1;
|
|
||||||
pb->pb_Environment.de_NumBuffers=30;
|
|
||||||
pb->pb_Environment.de_MaxTransfer=0xffffff;
|
|
||||||
pb->pb_Environment.de_Mask=0x7ffffffe;
|
|
||||||
pb->pb_Environment.de_DosType=0x444f5301;
|
|
||||||
|
|
||||||
RDBChecksum((unsigned long *)pb);
|
// swap byte order of first 0x40 long values
|
||||||
}
|
for(i=0;i<0x40;i++) p[i] = SWAP(p[i]);
|
||||||
break;
|
|
||||||
break;
|
} break;
|
||||||
default:
|
|
||||||
break;
|
case 1: { // Partition
|
||||||
}
|
hdd_debugf("FAKE: Partition");
|
||||||
|
|
||||||
|
struct PartitionBlock *pb=(struct PartitionBlock *)sector_buffer;
|
||||||
|
pb->pb_ID = 'P'<<24 | 'A' << 16 | 'R' << 8 | 'T';
|
||||||
|
|
||||||
|
pb->pb_Summedlongs=0x40;
|
||||||
|
pb->pb_HostID=0x07;
|
||||||
|
pb->pb_Next=0xffffffff;
|
||||||
|
pb->pb_Flags=0x1; // Bootable
|
||||||
|
pb->pb_DevFlags=0;
|
||||||
|
strcpy(pb->pb_DriveName,unit?"1HD\003":"0HD\003"); // "DH0"/"DH1" BCPL string
|
||||||
|
|
||||||
|
pb->pb_Environment.de_TableSize=0x10;
|
||||||
|
pb->pb_Environment.de_SizeBlock=0x80;
|
||||||
|
pb->pb_Environment.de_Surfaces=hdf[unit].heads;
|
||||||
|
pb->pb_Environment.de_SectorPerBlock=1;
|
||||||
|
pb->pb_Environment.de_BlocksPerTrack=hdf[unit].sectors;
|
||||||
|
pb->pb_Environment.de_Reserved=2;
|
||||||
|
pb->pb_Environment.de_LowCyl=1;
|
||||||
|
pb->pb_Environment.de_HighCyl=hdf[unit].cylinders-1;
|
||||||
|
pb->pb_Environment.de_NumBuffers=30;
|
||||||
|
pb->pb_Environment.de_MaxTransfer=0xffffff;
|
||||||
|
pb->pb_Environment.de_Mask=0x7ffffffe;
|
||||||
|
pb->pb_Environment.de_DosType=0x444f5301;
|
||||||
|
|
||||||
|
RDBChecksum((unsigned long *)pb);
|
||||||
|
|
||||||
|
// swap byte order of first 0x40 entries
|
||||||
|
unsigned long *p = (unsigned long*)pb;
|
||||||
|
for(i=0;i<0x40;i++) p[i] = SWAP(p[i]);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IdentifyDevice(unsigned short *pBuffer, unsigned char unit)
|
void IdentifyDevice(unsigned short *pBuffer, unsigned char unit) { // builds Identify Device struct
|
||||||
{ // builds Identify Device struct
|
char *p, i, x;
|
||||||
char *p, i, x;
|
unsigned long total_sectors = hdf[unit].cylinders * hdf[unit].heads * hdf[unit].sectors;
|
||||||
unsigned long total_sectors = hdf[unit].cylinders * hdf[unit].heads * hdf[unit].sectors;
|
|
||||||
|
|
||||||
memset(pBuffer, 0, 512);
|
memset(pBuffer, 0, 512);
|
||||||
|
|
||||||
|
switch(hdf[unit].type) {
|
||||||
|
case HDF_FILE | HDF_SYNTHRDB:
|
||||||
|
case HDF_FILE:
|
||||||
|
pBuffer[0] = 1 << 6; // hard disk
|
||||||
|
pBuffer[1] = hdf[unit].cylinders; // cyl count
|
||||||
|
pBuffer[3] = hdf[unit].heads; // head count
|
||||||
|
pBuffer[6] = hdf[unit].sectors; // sectors per track
|
||||||
|
// FIXME - can get serial no from card itself.
|
||||||
|
memcpy((char*)&pBuffer[10], "MiSTMiniMigHardfile ", 20); // serial number - byte swapped
|
||||||
|
memcpy((char*)&pBuffer[23], ".100 ", 8); // firmware version - byte swapped
|
||||||
|
p = (char*)&pBuffer[27];
|
||||||
|
// FIXME - likewise the model name can be fetched from the card.
|
||||||
|
if(hdf[unit].type & HDF_SYNTHRDB) {
|
||||||
|
memcpy(p, "DON'T ", 40);
|
||||||
|
p += 8;
|
||||||
|
memcpy(p, "REPARTITION! ", 16);
|
||||||
|
} else {
|
||||||
|
memcpy(p, "YAQUBE ", 40); // model name - byte swapped
|
||||||
|
p += 8;
|
||||||
|
if (config.hardfile[unit].long_name[0]) {
|
||||||
|
for (i = 0; (x = config.hardfile[unit].long_name[i]) && i < 16; i++) // copy file name as model name
|
||||||
|
p[i] = x;
|
||||||
|
} else {
|
||||||
|
memcpy(p, config.hardfile[unit].name, 8); // copy file name as model name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SwapBytes((char*)&pBuffer[27], 40); //not for 68000
|
||||||
|
break;
|
||||||
|
|
||||||
switch(hdf[unit].type)
|
case HDF_CARD:
|
||||||
{
|
case HDF_CARDPART0:
|
||||||
case HDF_FILE | HDF_SYNTHRDB:
|
case HDF_CARDPART1:
|
||||||
case HDF_FILE:
|
case HDF_CARDPART2:
|
||||||
pBuffer[0] = 1 << 6; // hard disk
|
case HDF_CARDPART3:
|
||||||
pBuffer[1] = hdf[unit].cylinders; // cyl count
|
pBuffer[0] = 1 << 6; // hard disk
|
||||||
pBuffer[3] = hdf[unit].heads; // head count
|
pBuffer[1] = hdf[unit].cylinders; // cyl count
|
||||||
pBuffer[6] = hdf[unit].sectors; // sectors per track
|
pBuffer[3] = hdf[unit].heads; // head count
|
||||||
// FIXME - can get serial no from card itself.
|
pBuffer[6] = hdf[unit].sectors; // sectors per track
|
||||||
memcpy((char*)&pBuffer[10], "1234567890ABCDEFGHIJ", 20); // serial number - byte swapped
|
// FIXME - can get serial no from card itself.
|
||||||
memcpy((char*)&pBuffer[23], ".100 ", 8); // firmware version - byte swapped
|
memcpy((char*)&pBuffer[10], "MiSTMiniMigSD0 ", 20); // serial number - byte swapped
|
||||||
p = (char*)&pBuffer[27];
|
pBuffer[23]+=hdf[unit].type-HDF_CARD;
|
||||||
// FIXME - likewise the model name can be fetched from the card.
|
memcpy((char*)&pBuffer[23], ".100 ", 8); // firmware version - byte swapped
|
||||||
if(hdf[unit].type & HDF_SYNTHRDB)
|
p = (char*)&pBuffer[27];
|
||||||
{
|
// FIXME - likewise the model name can be fetched from the card.
|
||||||
memcpy(p, "DON'T ", 40);
|
memcpy(p, "YAQUBE ", 40); // model name - byte swapped
|
||||||
p += 8;
|
p += 8;
|
||||||
memcpy(p, "REPARTITION! ", 16);
|
if(hdf[unit].type==HDF_CARD)
|
||||||
}
|
memcpy(p, "SD/MMC Card", 11); // copy file name as model name
|
||||||
else
|
else {
|
||||||
{
|
memcpy(p, "Card Part 1", 11); // copy file name as model name
|
||||||
memcpy(p, "YAQUBE ", 40); // model name - byte swapped
|
p[10]+=hdf[unit].partition;
|
||||||
p += 8;
|
}
|
||||||
if (config.hardfile[unit].long_name[0])
|
// SwapBytes((char*)&pBuffer[27], 40); //not for 68000
|
||||||
{
|
break;
|
||||||
for (i = 0; (x = config.hardfile[unit].long_name[i]) && i < 16; i++) // copy file name as model name
|
}
|
||||||
p[i] = x;
|
|
||||||
}
|
pBuffer[47] = 0x8010; //maximum sectors per block in Read/Write Multiple command
|
||||||
else
|
pBuffer[53] = 1;
|
||||||
{
|
pBuffer[54] = hdf[unit].cylinders;
|
||||||
memcpy(p, config.hardfile[unit].name, 8); // copy file name as model name
|
pBuffer[55] = hdf[unit].heads;
|
||||||
}
|
pBuffer[56] = hdf[unit].sectors;
|
||||||
}
|
pBuffer[57] = (unsigned short)total_sectors;
|
||||||
// SwapBytes((char*)&pBuffer[27], 40); //not for 68000
|
pBuffer[58] = (unsigned short)(total_sectors >> 16);
|
||||||
break;
|
|
||||||
case HDF_CARD:
|
|
||||||
case HDF_CARDPART0:
|
|
||||||
case HDF_CARDPART1:
|
|
||||||
case HDF_CARDPART2:
|
|
||||||
case HDF_CARDPART3:
|
|
||||||
pBuffer[0] = 1 << 6; // hard disk
|
|
||||||
pBuffer[1] = hdf[unit].cylinders; // cyl count
|
|
||||||
pBuffer[3] = hdf[unit].heads; // head count
|
|
||||||
pBuffer[6] = hdf[unit].sectors; // sectors per track
|
|
||||||
// FIXME - can get serial no from card itself.
|
|
||||||
memcpy((char*)&pBuffer[10], "TC64MiniMigSD0 ", 20); // serial number - byte swapped
|
|
||||||
pBuffer[23]+=hdf[unit].type-HDF_CARD;
|
|
||||||
memcpy((char*)&pBuffer[23], ".100 ", 8); // firmware version - byte swapped
|
|
||||||
p = (char*)&pBuffer[27];
|
|
||||||
// FIXME - likewise the model name can be fetched from the card.
|
|
||||||
memcpy(p, "YAQUBE ", 40); // model name - byte swapped
|
|
||||||
p += 8;
|
|
||||||
if(hdf[unit].type==HDF_CARD)
|
|
||||||
memcpy(p, "SD/MMC Card", 11); // copy file name as model name
|
|
||||||
else
|
|
||||||
{
|
|
||||||
memcpy(p, "Card Part 1", 11); // copy file name as model name
|
|
||||||
p[10]+=hdf[unit].partition;
|
|
||||||
}
|
|
||||||
// SwapBytes((char*)&pBuffer[27], 40); //not for 68000
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pBuffer[47] = 0x8010; //maximum sectors per block in Read/Write Multiple command
|
|
||||||
pBuffer[53] = 1;
|
|
||||||
pBuffer[54] = hdf[unit].cylinders;
|
|
||||||
pBuffer[55] = hdf[unit].heads;
|
|
||||||
pBuffer[56] = hdf[unit].sectors;
|
|
||||||
pBuffer[57] = (unsigned short)total_sectors;
|
|
||||||
pBuffer[58] = (unsigned short)(total_sectors >> 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long chs2lba(unsigned short cylinder, unsigned char head, unsigned short sector, unsigned char unit)
|
unsigned long chs2lba(unsigned short cylinder, unsigned char head, unsigned short sector, unsigned char unit) {
|
||||||
{
|
return(cylinder * hdf[unit].heads + head) * hdf[unit].sectors + sector - 1;
|
||||||
return(cylinder * hdf[unit].heads + head) * hdf[unit].sectors + sector - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteTaskFile(unsigned char error, unsigned char sector_count, unsigned char sector_number, unsigned char cylinder_low, unsigned char cylinder_high, unsigned char drive_head)
|
void WriteTaskFile(unsigned char error, unsigned char sector_count,
|
||||||
{
|
unsigned char sector_number, unsigned char cylinder_low,
|
||||||
EnableFpga();
|
unsigned char cylinder_high, unsigned char drive_head) {
|
||||||
|
EnableFpga();
|
||||||
SPI(CMD_IDE_REGS_WR); // write task file registers command
|
|
||||||
SPI(0x00);
|
SPI(CMD_IDE_REGS_WR); // write task file registers command
|
||||||
SPI(0x00); // dummy
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(0x00); // dummy
|
||||||
SPI(0x00); // dummy
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(0x00); // dummy
|
||||||
|
SPI(0x00);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SPI(0x00); // dummy
|
||||||
SPI(0x00); // dummy
|
|
||||||
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(error); // error
|
||||||
SPI(error); // error
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(sector_count); // sector count
|
||||||
SPI(sector_count); // sector count
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(sector_number); // sector number
|
||||||
SPI(sector_number); //sector number
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(cylinder_low); // cylinder low
|
||||||
SPI(cylinder_low); // cylinder low
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(cylinder_high); // cylinder high
|
||||||
SPI(cylinder_high); // cylinder high
|
SPI(0x00);
|
||||||
SPI(0x00);
|
SPI(drive_head); // drive/head
|
||||||
SPI(drive_head); // drive/head
|
|
||||||
|
DisableFpga();
|
||||||
DisableFpga();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteStatus(unsigned char status)
|
void WriteStatus(unsigned char status)
|
||||||
@ -303,22 +304,19 @@ void HandleHDD(unsigned char c1, unsigned char c2)
|
|||||||
|
|
||||||
unit = tfr[6] & 0x10 ? 1 : 0; // master/slave selection
|
unit = tfr[6] & 0x10 ? 1 : 0; // master/slave selection
|
||||||
|
|
||||||
if (0)
|
if (0) {
|
||||||
{
|
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||||
hdd_debugf("IDE:");
|
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||||
for (i = 1; i < 7; i++)
|
|
||||||
hdd_debugf("%02X.",tfr[i]);
|
|
||||||
hdd_debugf("%02X\r", tfr[7]);
|
|
||||||
}
|
}
|
||||||
if ((tfr[7] & 0xF0) == ACMD_RECALIBRATE) // Recalibrate 0x10-0x1F (class 3 command: no data)
|
if ((tfr[7] & 0xF0) == ACMD_RECALIBRATE) // Recalibrate 0x10-0x1F (class 3 command: no data)
|
||||||
{
|
{
|
||||||
hdd_debugf("Recalibrate\r");
|
hdd_debugf("IDE%d: Recalibrate", unit);
|
||||||
WriteTaskFile(0, 0, 1, 0, 0, tfr[6] & 0xF0);
|
WriteTaskFile(0, 0, 1, 0, 0, tfr[6] & 0xF0);
|
||||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
||||||
}
|
}
|
||||||
else if (tfr[7] == ACMD_IDENTIFY_DEVICE) // Identify Device
|
else if (tfr[7] == ACMD_IDENTIFY_DEVICE) // Identify Device
|
||||||
{
|
{
|
||||||
hdd_debugf("Identify Device\r");
|
hdd_debugf("IDE%d: Identify Device", unit);
|
||||||
IdentifyDevice(id, unit);
|
IdentifyDevice(id, unit);
|
||||||
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
||||||
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
||||||
@ -339,110 +337,102 @@ void HandleHDD(unsigned char c1, unsigned char c2)
|
|||||||
}
|
}
|
||||||
else if (tfr[7] == ACMD_INITIALIZE_DEVICE_PARAMETERS) // Initiallize Device Parameters
|
else if (tfr[7] == ACMD_INITIALIZE_DEVICE_PARAMETERS) // Initiallize Device Parameters
|
||||||
{
|
{
|
||||||
hdd_debugf("Initialize Device Parameters\r");
|
hdd_debugf("Initialize Device Parameters");
|
||||||
hdd_debugf("IDE:");
|
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||||
for (i = 1; i < 7; i++)
|
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||||
hdd_debugf("%02X.", tfr[i]);
|
|
||||||
hdd_debugf("%02X\r", tfr[7]);
|
|
||||||
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
||||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
||||||
}
|
}
|
||||||
else if (tfr[7] == ACMD_READ_SECTORS) // Read Sectors
|
else if (tfr[7] == ACMD_READ_SECTORS) // Read Sectors
|
||||||
{
|
{
|
||||||
long lba;
|
long lba;
|
||||||
|
|
||||||
sector = tfr[3];
|
sector = tfr[3];
|
||||||
cylinder = tfr[4] | (tfr[5] << 8);
|
cylinder = tfr[4] | (tfr[5] << 8);
|
||||||
head = tfr[6] & 0x0F;
|
head = tfr[6] & 0x0F;
|
||||||
sector_count = tfr[2];
|
sector_count = tfr[2];
|
||||||
|
|
||||||
|
hdd_debugf("IDE%d: read %d.%d.%d, %d", unit,cylinder, head, sector, sector_count);
|
||||||
|
|
||||||
if (sector_count == 0)
|
if (sector_count == 0)
|
||||||
sector_count = 0x100;
|
sector_count = 0x100;
|
||||||
|
|
||||||
switch(hdf[unit].type)
|
switch(hdf[unit].type) {
|
||||||
|
case HDF_FILE | HDF_SYNTHRDB:
|
||||||
|
case HDF_FILE:
|
||||||
|
lba=chs2lba(cylinder, head, sector, unit);
|
||||||
|
if (hdf[unit].file.size)
|
||||||
|
HardFileSeek(&hdf[unit], (lba+hdf[unit].offset) < 0 ? 0 : lba+hdf[unit].offset);
|
||||||
|
|
||||||
|
while (sector_count) {
|
||||||
|
// decrease sector count
|
||||||
|
if(sector_count!=1) {
|
||||||
|
if (sector == hdf[unit].sectors) {
|
||||||
|
sector = 1;
|
||||||
|
head++;
|
||||||
|
if (head == hdf[unit].heads) {
|
||||||
|
head = 0;
|
||||||
|
cylinder++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sector++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((lba+hdf[unit].offset)<0) {
|
||||||
|
FakeRDB(unit,lba);
|
||||||
|
|
||||||
|
WriteTaskFile(0, tfr[2], sector, (unsigned char)cylinder,
|
||||||
|
(unsigned char)(cylinder >> 8), (tfr[6] & 0xF0) | head);
|
||||||
|
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
||||||
|
|
||||||
|
EnableFpga();
|
||||||
|
SPI(CMD_IDE_DATA_WR); // write data command
|
||||||
|
SPI(0x00);
|
||||||
|
SPI(0x00);
|
||||||
|
SPI(0x00);
|
||||||
|
SPI(0x00);
|
||||||
|
SPI(0x00);
|
||||||
|
spi_block_write(sector_buffer);
|
||||||
|
DisableFpga();
|
||||||
|
|
||||||
|
WriteStatus(sector_count==1 ? IDE_STATUS_IRQ|IDE_STATUS_END : IDE_STATUS_IRQ);
|
||||||
|
} else {
|
||||||
|
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
||||||
|
WriteTaskFile(0, tfr[2], sector, (unsigned char)cylinder,
|
||||||
|
(unsigned char)(cylinder >> 8), (tfr[6] & 0xF0) | head);
|
||||||
|
|
||||||
|
while (!(GetFPGAStatus() & CMD_IDECMD)); // wait for empty sector buffer
|
||||||
|
|
||||||
|
WriteStatus(IDE_STATUS_IRQ);
|
||||||
|
|
||||||
|
if (hdf[unit].file.size) {
|
||||||
|
// FileRead(&hdf[unit].file, NULL);
|
||||||
|
FileRead(&hdf[unit].file, 0);
|
||||||
|
FileSeek(&hdf[unit].file, 1, SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lba++;
|
||||||
|
sector_count--; // decrease sector count
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HDF_CARD:
|
||||||
|
case HDF_CARDPART0:
|
||||||
|
case HDF_CARDPART1:
|
||||||
|
case HDF_CARDPART2:
|
||||||
|
case HDF_CARDPART3:
|
||||||
|
{
|
||||||
|
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
||||||
|
lba=chs2lba(cylinder, head, sector, unit)+hdf[unit].offset;
|
||||||
|
while (sector_count) {
|
||||||
|
// decrease sector count
|
||||||
|
if(sector_count!=1) {
|
||||||
|
if (sector == hdf[unit].sectors)
|
||||||
{
|
{
|
||||||
case HDF_FILE | HDF_SYNTHRDB:
|
sector = 1;
|
||||||
case HDF_FILE:
|
head++;
|
||||||
lba=chs2lba(cylinder, head, sector, unit);
|
if (head == hdf[unit].heads)
|
||||||
if (hdf[unit].file.size)
|
|
||||||
HardFileSeek(&hdf[unit], (lba+hdf[unit].offset) < 0 ? 0 : lba+hdf[unit].offset);
|
|
||||||
|
|
||||||
while (sector_count)
|
|
||||||
{
|
|
||||||
// decrease sector count
|
|
||||||
if(sector_count!=1)
|
|
||||||
{
|
|
||||||
if (sector == hdf[unit].sectors)
|
|
||||||
{
|
|
||||||
sector = 1;
|
|
||||||
head++;
|
|
||||||
if (head == hdf[unit].heads)
|
|
||||||
{
|
|
||||||
head = 0;
|
|
||||||
cylinder++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sector++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((lba+hdf[unit].offset)<0)
|
|
||||||
{
|
|
||||||
FakeRDB(unit,lba);
|
|
||||||
|
|
||||||
WriteTaskFile(0, tfr[2], sector, (unsigned char)cylinder, (unsigned char)(cylinder >> 8), (tfr[6] & 0xF0) | head);
|
|
||||||
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
|
||||||
EnableFpga();
|
|
||||||
SPI(CMD_IDE_DATA_WR); // write data command
|
|
||||||
SPI(0x00);
|
|
||||||
SPI(0x00);
|
|
||||||
SPI(0x00);
|
|
||||||
SPI(0x00);
|
|
||||||
SPI(0x00);
|
|
||||||
for (i = 0; i < 512; i++)
|
|
||||||
{
|
|
||||||
SPI(sector_buffer[i]);
|
|
||||||
}
|
|
||||||
DisableFpga();
|
|
||||||
WriteStatus(sector_count==1 ? IDE_STATUS_IRQ|IDE_STATUS_END : IDE_STATUS_IRQ);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
|
||||||
WriteTaskFile(0, tfr[2], sector, (unsigned char)cylinder, (unsigned char)(cylinder >> 8), (tfr[6] & 0xF0) | head);
|
|
||||||
|
|
||||||
while (!(GetFPGAStatus() & CMD_IDECMD)); // wait for empty sector buffer
|
|
||||||
|
|
||||||
WriteStatus(IDE_STATUS_IRQ);
|
|
||||||
|
|
||||||
if (hdf[unit].file.size)
|
|
||||||
{
|
|
||||||
// FileRead(&hdf[unit].file, NULL);
|
|
||||||
FileRead(&hdf[unit].file, 0);
|
|
||||||
FileSeek(&hdf[unit].file, 1, SEEK_CUR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lba++;
|
|
||||||
sector_count--; // decrease sector count
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case HDF_CARD:
|
|
||||||
case HDF_CARDPART0:
|
|
||||||
case HDF_CARDPART1:
|
|
||||||
case HDF_CARDPART2:
|
|
||||||
case HDF_CARDPART3:
|
|
||||||
{
|
|
||||||
WriteStatus(IDE_STATUS_RDY); // pio in (class 1) command type
|
|
||||||
lba=chs2lba(cylinder, head, sector, unit)+hdf[unit].offset;
|
|
||||||
while (sector_count)
|
|
||||||
{
|
|
||||||
// decrease sector count
|
|
||||||
if(sector_count!=1)
|
|
||||||
{
|
|
||||||
if (sector == hdf[unit].sectors)
|
|
||||||
{
|
|
||||||
sector = 1;
|
|
||||||
head++;
|
|
||||||
if (head == hdf[unit].heads)
|
|
||||||
{
|
{
|
||||||
head = 0;
|
head = 0;
|
||||||
cylinder++;
|
cylinder++;
|
||||||
@ -468,11 +458,9 @@ void HandleHDD(unsigned char c1, unsigned char c2)
|
|||||||
{
|
{
|
||||||
hdf[unit].sectors_per_block = tfr[2];
|
hdf[unit].sectors_per_block = tfr[2];
|
||||||
|
|
||||||
hdd_debugf("Set Multiple Mode\r");
|
hdd_debugf("Set Multiple Mode");
|
||||||
hdd_debugf("IDE:");
|
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||||
for (i = 1; i < 7; i++)
|
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||||
hdd_debugf("%02X.", tfr[i]);
|
|
||||||
hdd_debugf("%02X\r", tfr[7]);
|
|
||||||
|
|
||||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
||||||
}
|
}
|
||||||
@ -754,12 +742,9 @@ void HandleHDD(unsigned char c1, unsigned char c2)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hdd_debugf("Unknown ATA command\r");
|
hdd_debugf("Unknown ATA command");
|
||||||
|
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||||
hdd_debugf("IDE:");
|
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||||
for (i = 1; i < 7; i++)
|
|
||||||
hdd_debugf("%02X.", tfr[i]);
|
|
||||||
hdd_debugf("%02X\r", tfr[7]);
|
|
||||||
WriteTaskFile(0x04, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
WriteTaskFile(0x04, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
||||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ | IDE_STATUS_ERR);
|
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ | IDE_STATUS_ERR);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,14 +35,14 @@ struct RigidDiskBlock {
|
|||||||
unsigned long rdb_AutoParkSeconds; // zero
|
unsigned long rdb_AutoParkSeconds; // zero
|
||||||
unsigned long rdb_HighRDSKBlock; // 1
|
unsigned long rdb_HighRDSKBlock; // 1
|
||||||
unsigned long rdb_Reserved4;
|
unsigned long rdb_Reserved4;
|
||||||
char rdb_DiskVendor[8]; // "Don't"
|
char rdb_DiskVendor[8]; // "Don't"
|
||||||
char rdb_DiskProduct[16]; // " repartition!"
|
char rdb_DiskProduct[16]; // " repartition!"
|
||||||
char rdb_DiskRevision[4];
|
char rdb_DiskRevision[4];
|
||||||
char rdb_ControllerVendor[8];
|
char rdb_ControllerVendor[8];
|
||||||
char rdb_ControllerProduct[16];
|
char rdb_ControllerProduct[16];
|
||||||
char rdb_ControllerRevision[4];
|
char rdb_ControllerRevision[4];
|
||||||
unsigned long rdb_Reserved5[10];
|
unsigned long rdb_Reserved5[10];
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct DosEnvec {
|
struct DosEnvec {
|
||||||
unsigned long de_TableSize; // Size of Environment vector - 0x10
|
unsigned long de_TableSize; // Size of Environment vector - 0x10
|
||||||
@ -66,7 +66,7 @@ struct DosEnvec {
|
|||||||
unsigned long de_Baud;
|
unsigned long de_Baud;
|
||||||
unsigned long de_Control;
|
unsigned long de_Control;
|
||||||
unsigned long de_BootBlocks;
|
unsigned long de_BootBlocks;
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
struct PartitionBlock {
|
struct PartitionBlock {
|
||||||
@ -82,7 +82,7 @@ struct PartitionBlock {
|
|||||||
unsigned long pb_Reserved2[15];
|
unsigned long pb_Reserved2[15];
|
||||||
struct DosEnvec pb_Environment;
|
struct DosEnvec pb_Environment;
|
||||||
unsigned long pb_EReserved[12]; /* reserved for future environment vector */
|
unsigned long pb_EReserved[12]; /* reserved for future environment vector */
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
#endif /* HDD_INTERNAL_H */
|
#endif /* HDD_INTERNAL_H */
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user