181
Lowlevel-Coding / Diskettencontroller
« am: 24. June 2004, 10:14 »
Hiho,
ReadSector nutzt dma. Man kann das zwar ausstellen, aber dann geht es bei mir auch nicht. Btw, du musst vorher auch noch andere Commands an den Controller senden. Hier ist ein alter Code für meinen Floppy Treiber, der ist aber glaub ich nen bissle buggy
MfG GhostCoder
ReadSector nutzt dma. Man kann das zwar ausstellen, aber dann geht es bei mir auch nicht. Btw, du musst vorher auch noch andere Commands an den Controller senden. Hier ist ein alter Code für meinen Floppy Treiber, der ist aber glaub ich nen bissle buggy
Code: [Auswählen]
extern void FloppyInterrupt();
int iFloppyReady;
int iFloppy;
void FloppyHandler()
{
iFloppyReady=1;
}
/* fd_sendbyte() routine from intel manual */
void fd_sendbyte(int byte)
{
volatile int msr;
int tmo;
for (tmo=0; tmo<100; tmo++)
{
msr = InByte(0x3F4);
if( (msr & 0xc0)==0x80 )
{
OutByte(0x3F5,byte);
return;
}
InByte(0x80); /* delay */
}
}
/* fd_getbyte() routine from intel manual */
int fd_getbyte()
{
volatile int msr;
int tmo;
for (tmo=0; tmo<100; tmo++)
{
msr = InByte(0x3F4);
if ((msr & 0xd0) == 0xd0)
{
return InByte(0x3F5);
}
InByte(0x80); /* delay */
}
return -1; /* read timeout */
}
void SetFloppy(int iDriveNum)
{
iFloppy=iDriveNum;
}
void WaitFloppy(int iSense)
{
if(iSense)
{
while(!iFloppyReady);
iFloppyReady=0;
}
// Read command results
while(InByte(0x3F4) & 16) fd_getbyte();
if(iSense)
{
fd_sendbyte(8);
fd_getbyte();
fd_getbyte();
}
}
void FloppyMotorOn()
{
int i;
OutByte(0x3F2,0x1C | iFloppy);
for(i=0;i<100000;i++);
}
void FloppyMotorOff()
{
int i;
OutByte(0x3F2,0x0C | iFloppy);
for(i=0;i<100000;i++);
}
int FloppySeek(int iTrack)
{
int i;
FloppyMotorOn();
fd_sendbyte(0x0F);
fd_sendbyte(0);
fd_sendbyte(iTrack);
for(i=0;i<1000000;i++);
WaitFloppy(1);
FloppyMotorOff();
return 1;
}
int ReadFloppy(int iSector,void *pvBuffer)
{
int head,track,sector;
// Compute chs address
sector=(iSector%18)+1;
track=(iSector/18)/2;
head=(iSector/18)%2;
// Enable dma channel
asm("cli");
OutByte(12,0x46);
OutByte(11,0x46);
OutByte(4,(DWORD)pvBuffer & 0xFF); //OFFSET LSB
OutByte(4,((DWORD)pvBuffer >> 8) & 0xFF); //OFFSET MSB
OutByte(0x81,(DWORD)pvBuffer >> 16); //PAGE
OutByte(5,511 & 0xFF); //SIZE-1 LSB
OutByte(5,511 >> 8); //SIZE-1 MSB
OutByte(10,2);
asm("sti");
FloppySeek(track);
FloppyMotorOn();
// Send read command
fd_sendbyte(0x66);
fd_sendbyte(head << 2);
fd_sendbyte(track);
fd_sendbyte(head);
fd_sendbyte(sector);
fd_sendbyte(2); // bytes per sector
fd_sendbyte(18); // Sectors per track
fd_sendbyte(0x1B);
fd_sendbyte(0xFF);
WaitFloppy(0);
int i;
for(i=0;i<10000;i++);
FloppyMotorOff();
return 1;
}
void InitFloppy()
{
int i;
SetFloppy(0);
iFloppyReady=0;
SetInterrupt(6,FloppyInterrupt);
// Reset controller
OutByte(0x3F2,0);
// Set datarate
OutByte(0x3F7,0);
// Enable controller
OutByte(0x3F2,0x0C | iFloppy);
for(i=0;i<1000000;i++);
WaitFloppy(1);
// Specifiy
fd_sendbyte(3);
fd_sendbyte(0xDF);
fd_sendbyte(2);
// Seek
FloppySeek(1);
// Recalibrate
FloppyMotorOn();
fd_sendbyte(7);
fd_sendbyte(0);
iFloppyReady=1;
WaitFloppy(1);
FloppyMotorOff();
}
MfG GhostCoder