mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-01-13 07:09:44 +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
|
||||
hdfTYPE hdf[2];
|
||||
|
||||
static void RDBChecksum(unsigned long *p)
|
||||
{
|
||||
unsigned long count=p[1];
|
||||
unsigned long c2;
|
||||
long result=0;
|
||||
p[2]=0;
|
||||
for(c2=0;c2<count;++c2)
|
||||
result+=p[c2];
|
||||
p[2]=(unsigned long)-result;
|
||||
static void RDBChecksum(unsigned long *p) {
|
||||
unsigned long count=p[1];
|
||||
unsigned long c2;
|
||||
long result=0;
|
||||
p[2]=0;
|
||||
for(c2=0;c2<count;++c2)
|
||||
result+=p[c2];
|
||||
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,
|
||||
// we synthesize one.
|
||||
static void FakeRDB(int unit,int block)
|
||||
{
|
||||
int i;
|
||||
// Start by clearing the sector buffer
|
||||
for(i=0;i<512;++i)
|
||||
sector_buffer[i]=0;
|
||||
static void FakeRDB(int unit,int block) {
|
||||
int i;
|
||||
// Start by clearing the sector buffer
|
||||
memset(sector_buffer, 0, 512);
|
||||
|
||||
// If we're asked for LBA 0 we create an RDSK block, and if LBA 1, a PART block.
|
||||
switch(block)
|
||||
{
|
||||
case 0: // 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!");
|
||||
// If we're asked for LBA 0 we create an RDSK block, and if LBA 1, a PART block.
|
||||
switch(block) {
|
||||
case 0: { // RDB
|
||||
hdd_debugf("FAKE: RDB");
|
||||
|
||||
RDBChecksum((unsigned long *)rdb);
|
||||
}
|
||||
break;
|
||||
case 1: // 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," DH0");
|
||||
pb->pb_DriveName[0]=3; // BCPL string
|
||||
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!");
|
||||
|
||||
// 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;
|
||||
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 *)rdb);
|
||||
|
||||
RDBChecksum((unsigned long *)pb);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// swap byte order of first 0x40 long values
|
||||
for(i=0;i<0x40;i++) p[i] = SWAP(p[i]);
|
||||
|
||||
} 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)
|
||||
{ // builds Identify Device struct
|
||||
char *p, i, x;
|
||||
unsigned long total_sectors = hdf[unit].cylinders * hdf[unit].heads * hdf[unit].sectors;
|
||||
void IdentifyDevice(unsigned short *pBuffer, unsigned char unit) { // builds Identify Device struct
|
||||
char *p, i, x;
|
||||
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_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], "1234567890ABCDEFGHIJ", 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;
|
||||
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);
|
||||
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], "MiSTMiniMigSD0 ", 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)
|
||||
{
|
||||
return(cylinder * hdf[unit].heads + head) * hdf[unit].sectors + sector - 1;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
EnableFpga();
|
||||
|
||||
SPI(CMD_IDE_REGS_WR); // write task file registers command
|
||||
SPI(0x00);
|
||||
SPI(0x00); // dummy
|
||||
SPI(0x00);
|
||||
SPI(0x00); // dummy
|
||||
SPI(0x00);
|
||||
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) {
|
||||
EnableFpga();
|
||||
|
||||
SPI(CMD_IDE_REGS_WR); // write task file registers command
|
||||
SPI(0x00);
|
||||
SPI(0x00); // dummy
|
||||
SPI(0x00);
|
||||
SPI(0x00); // dummy
|
||||
SPI(0x00);
|
||||
|
||||
|
||||
|
||||
|
||||
SPI(0x00); // dummy
|
||||
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(error); // error
|
||||
SPI(0x00);
|
||||
SPI(sector_count); // sector count
|
||||
SPI(0x00);
|
||||
SPI(sector_number); //sector number
|
||||
SPI(0x00);
|
||||
SPI(cylinder_low); // cylinder low
|
||||
SPI(0x00);
|
||||
SPI(cylinder_high); // cylinder high
|
||||
SPI(0x00);
|
||||
SPI(drive_head); // drive/head
|
||||
|
||||
DisableFpga();
|
||||
SPI(0x00); // dummy
|
||||
|
||||
SPI(0x00);
|
||||
SPI(0x00);
|
||||
SPI(error); // error
|
||||
SPI(0x00);
|
||||
SPI(sector_count); // sector count
|
||||
SPI(0x00);
|
||||
SPI(sector_number); // sector number
|
||||
SPI(0x00);
|
||||
SPI(cylinder_low); // cylinder low
|
||||
SPI(0x00);
|
||||
SPI(cylinder_high); // cylinder high
|
||||
SPI(0x00);
|
||||
SPI(drive_head); // drive/head
|
||||
|
||||
DisableFpga();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if (0)
|
||||
{
|
||||
hdd_debugf("IDE:");
|
||||
for (i = 1; i < 7; i++)
|
||||
hdd_debugf("%02X.",tfr[i]);
|
||||
hdd_debugf("%02X\r", tfr[7]);
|
||||
if (0) {
|
||||
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||
}
|
||||
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);
|
||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
||||
}
|
||||
else if (tfr[7] == ACMD_IDENTIFY_DEVICE) // Identify Device
|
||||
{
|
||||
hdd_debugf("Identify Device\r");
|
||||
hdd_debugf("IDE%d: Identify Device", unit);
|
||||
IdentifyDevice(id, unit);
|
||||
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
||||
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
|
||||
{
|
||||
hdd_debugf("Initialize Device Parameters\r");
|
||||
hdd_debugf("IDE:");
|
||||
for (i = 1; i < 7; i++)
|
||||
hdd_debugf("%02X.", tfr[i]);
|
||||
hdd_debugf("%02X\r", tfr[7]);
|
||||
hdd_debugf("Initialize Device Parameters");
|
||||
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||
WriteTaskFile(0, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
||||
}
|
||||
else if (tfr[7] == ACMD_READ_SECTORS) // Read Sectors
|
||||
{
|
||||
long lba;
|
||||
long lba;
|
||||
|
||||
sector = tfr[3];
|
||||
cylinder = tfr[4] | (tfr[5] << 8);
|
||||
head = tfr[6] & 0x0F;
|
||||
sector_count = tfr[2];
|
||||
|
||||
hdd_debugf("IDE%d: read %d.%d.%d, %d", unit,cylinder, head, sector, sector_count);
|
||||
|
||||
if (sector_count == 0)
|
||||
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:
|
||||
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);
|
||||
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)
|
||||
sector = 1;
|
||||
head++;
|
||||
if (head == hdf[unit].heads)
|
||||
{
|
||||
head = 0;
|
||||
cylinder++;
|
||||
@ -468,11 +458,9 @@ void HandleHDD(unsigned char c1, unsigned char c2)
|
||||
{
|
||||
hdf[unit].sectors_per_block = tfr[2];
|
||||
|
||||
hdd_debugf("Set Multiple Mode\r");
|
||||
hdd_debugf("IDE:");
|
||||
for (i = 1; i < 7; i++)
|
||||
hdd_debugf("%02X.", tfr[i]);
|
||||
hdd_debugf("%02X\r", tfr[7]);
|
||||
hdd_debugf("Set Multiple Mode");
|
||||
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||
|
||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ);
|
||||
}
|
||||
@ -754,12 +742,9 @@ void HandleHDD(unsigned char c1, unsigned char c2)
|
||||
}
|
||||
else
|
||||
{
|
||||
hdd_debugf("Unknown ATA command\r");
|
||||
|
||||
hdd_debugf("IDE:");
|
||||
for (i = 1; i < 7; i++)
|
||||
hdd_debugf("%02X.", tfr[i]);
|
||||
hdd_debugf("%02X\r", tfr[7]);
|
||||
hdd_debugf("Unknown ATA command");
|
||||
hdd_debugf("IDE%d: %02X.%02X.%02X.%02X.%02X.%02X.%02X.%02X", unit,
|
||||
tfr[0], tfr[1], tfr[2], tfr[3], tfr[4], tfr[5], tfr[6], tfr[7]);
|
||||
WriteTaskFile(0x04, tfr[2], tfr[3], tfr[4], tfr[5], tfr[6]);
|
||||
WriteStatus(IDE_STATUS_END | IDE_STATUS_IRQ | IDE_STATUS_ERR);
|
||||
}
|
||||
|
||||
@ -35,14 +35,14 @@ struct RigidDiskBlock {
|
||||
unsigned long rdb_AutoParkSeconds; // zero
|
||||
unsigned long rdb_HighRDSKBlock; // 1
|
||||
unsigned long rdb_Reserved4;
|
||||
char rdb_DiskVendor[8]; // "Don't"
|
||||
char rdb_DiskVendor[8]; // "Don't"
|
||||
char rdb_DiskProduct[16]; // " repartition!"
|
||||
char rdb_DiskRevision[4];
|
||||
char rdb_ControllerVendor[8];
|
||||
char rdb_ControllerProduct[16];
|
||||
char rdb_ControllerRevision[4];
|
||||
unsigned long rdb_Reserved5[10];
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct DosEnvec {
|
||||
unsigned long de_TableSize; // Size of Environment vector - 0x10
|
||||
@ -66,7 +66,7 @@ struct DosEnvec {
|
||||
unsigned long de_Baud;
|
||||
unsigned long de_Control;
|
||||
unsigned long de_BootBlocks;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct PartitionBlock {
|
||||
@ -82,7 +82,7 @@ struct PartitionBlock {
|
||||
unsigned long pb_Reserved2[15];
|
||||
struct DosEnvec pb_Environment;
|
||||
unsigned long pb_EReserved[12]; /* reserved for future environment vector */
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* HDD_INTERNAL_H */
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user