Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: MeisterProppa am 23. June 2004, 23:38
-
Hallo, ich bins wieder...
Von dem Anfangsstadium bei meiner ersten Frage habe ich mich schon etwas entfernt. Ich habe inzwischen einen keyboard-Treiber mitsamt scan-Funktion für den Input, dann habe ich ein einfaches Paging-System eingebaut und versuche mich mal darin den Floppycontroller anzusprechen.
Ich starte also den Motor und schicke ein ReadSector Command ab. Das Laufwerk reagiert und sendet einen Interrupt #6 zurück...
Und hier setzt mein Problem an: Trotz Googlen habe ich keine Ahnung, in welchen Ports jetzt welche Daten stehen, die mein ReadSector zurückgegeben hat.
Kennt jemand da eine gute Übersicht oder ein Tutorial, in dem das beschrieben ist?
-
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 :)
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
-
Danke, ich werde mir den Code gleich mal näher ansehen und einbauen ;)
-
Bliebe noch eine Frage.. Was machst du in deinem Interrupt #6 Handler? Du musst ja zumindest irgendwie FloppyReady setzen, da sich das Programm sonst in einer Endlosschleife verfängt. Außerdem muss man einen 0x08 auf Port 0x3F5 schicken und dann zweimal diesen Port lesen.. Gibt es sonst noch was?
-
Hiho,
SetInterrupt(6,FloppyInterrupt); installiert den asm Interrupt handler, der wiederrum FloppyHandler() auf. Der Interrupt ist ja nur dazu da, zu signalisierne das etwas beendet worden ist. Und FloppyHandler() setzt iFloppyReady auf true.
Und
while(!iFloppyReady);
iFloppyReady=0;
in WaitFloppy() wartet nun auf den Interrupt. Was mir grad einfällt:
iFloppyReady=0;
while(!iFloppyReady);
wäre besser :)
Das mit dem 0x08 an 0x3F5... Du meinst das "sense interrupt state" command, wa?
Guckst du hier:
if(iSense)
{
fd_sendbyte(8);
fd_getbyte();
fd_getbyte();
}
*gg
MfG GhostCoder