Autor Thema: FDC-Probleme  (Gelesen 7472 mal)

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« am: 02. January 2006, 11:19 »
Ich habe einige Probleme mit der Programmierung des FDC. Zum Testen will ich den Bootsektor einlesen.

Schon ganz am Anfang komme ich nicht weiter. Ich mache einen Reset des FDC, danach starte ich den Motor des ersten Laufwerks. Ich warte dann, bis der FDC bereit ist, Befehle entgegenzunehmen. Ist er aber nie...

Out8Bit(0x0C, 0x03F2);      /* Reset */
Out8Bit(0x18, 0x03F2);      /* Motor starten */
while(In8Bit(0x03F4) != 0x80);


Das Auslesen von Port 0x03F4 gibt immer folgendes Resultat: Bit 7 nicht gesetzt (Datenregister nicht bereit) und Bit 4 gesetzt (FDC beschäftigt).

Homix

  • Beiträge: 138
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 02. January 2006, 14:42 »
hi,
beim Senden des Bytes zum Starten des Motors hast du wohl ein Bit vergessen.
Es sollte 0x1C statt 0x18 heißen.

mfg,
stefan

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 02. January 2006, 15:23 »
Ich dachte, Bit 2 stünde für den Reset.
_verwirrung_
Also kann ich beides in einem Befehl machen?

bitmaster

  • Troll
  • Beiträge: 1 138
    • Profil anzeigen
    • OS-64 = 64 Bit Operating System
Gespeichert
« Antwort #3 am: 02. January 2006, 16:02 »
Zitat von: elfish_rider
Ich dachte, Bit 2 stünde für den Reset.
_verwirrung_
Also kann ich beides in einem Befehl machen?
Wenn du Reset auf Null setzt, dann wird ein Reset durchgeführt ansonsten nicht.
In the Future everyone will need OS-64!!!

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 02. January 2006, 23:27 »
Wenn ich mehrere Sektoren nacheinander einlesen will, geht das nicht. Einer allein geht.

Bochs meldet, dass ein Befehl noch Pending ist, obwohl ich vor dem Schreiben ins Datenregister immer überprüfe, ob es bereit ist.

In anderen Treibern habe ich gesehen, dass nach vielen Befehlen (Motor an, Motor aus) ein Delay kommt. Muss man dieses unelegantes Zeugs auch einbauen?

Hier der Code:

volatile BYTE operationDone = 0;

BYTE ReadSectors(WORD startSector, WORD count, void* target)
{
BYTE cylinder, head, sector;
WORD i;

for(i = 0; i < count; i++, target += 512)
{
while(InByte(0x03F4) & 0x80 == 0);
OutByte(0x1C, 0x03F2);      /* Motor starten */

LBAToCHS(startSector + i, &cylinder, &head, &sector);

PrepareDMAWrite(2, target, 512);
/*
while(InByte(0x03F4) & 0x80 == 0);
OutByte(0x0F, 0x03F5);
while(InByte(0x03F4) & 0x80 == 0);
OutByte(head, 0x03F5);
while(InByte(0x03F4) & 0x80 == 0);
OutByte(cylinder, 0x03F5);
*/
while(InByte(0x03F4) & 0x80 == 0);
OutByte(0x46, 0x03F5);      /* Sektor lesen */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(head << 2, 0x03F5); /* Head */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(cylinder, 0x03F5);  /* Cylinder */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(head, 0x03F5);      /* Head */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(sector, 0x03F5);    /* Sector */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(2, 0x03F5);         /* Sektorengrösse */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(18, 0x03F5);        /* Sektoren pro Spur */
while(InByte(0x03F4) & 0x80 == 0);
OutByte(0x1B, 0x03F5);
while(InByte(0x03F4) & 0x80 == 0);
OutByte(0xFF, 0x03F5);

WaitForFloppy();

while(InByte(0x03F4) & 0x80 == 0);
OutByte(0x00, 0x03F2);
PrintChar('!');
}

return ERROR_NO;
}

void WaitForFloppy()
{
while(operationDone == 0);
operationDone = 0;
}

elfish_rider

  • Beiträge: 293
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 03. January 2006, 14:01 »
Also, ich vermute, dass das Problem daran liegt, dass ein Befehl (Seek, ReadSector) noch am abarbeiten ist, während ich schon den nächsten schicke. Sollte doch aber nicht?! Ich warte ja auf den Interrupt. Ist zum Zeitpunkt von dessen Auslösung die Operation noch nicht beendet?

volatile BYTE operationDone = 0;

BYTE ReadSectors(WORD startSector, WORD count, void* target)
{
BYTE cylinder, head, sector;
WORD i;

for(i = 0; i < count; i++, target += 512)
{
OutByte(0x1C, 0x03F2);      /* Motor starten */

LBAToCHS(startSector + i, &cylinder, &head, &sector);

PrepareDMAWrite(2, target, 512);

FloppyOutByte(0x0F);
FloppyOutByte(head);
FloppyOutByte(cylinder);

WaitForFloppy();

FloppyOutByte(0x46);      /* Sektor lesen */
FloppyOutByte(head << 2); /* Head */
FloppyOutByte(cylinder);  /* Cylinder */
FloppyOutByte(head);      /* Head */
FloppyOutByte(sector);    /* Sector */
FloppyOutByte(2);         /* Sektorengrösse */
FloppyOutByte(18);        /* Sektoren pro Spur */
FloppyOutByte(0x1B);
FloppyOutByte(0xFF);

WaitForFloppy();

OutByte(0x04, 0x03F2);

PrintChar('!');
}

return ERROR_NO;
}

void FloppyOutByte(BYTE value)
{
while(1)
{
if(InByte(0x3F4) & 0x80 == 0)
InByte(0x80);
else
{
OutByte(value, 0x03F5);
return;
}
}
}

void WaitForFloppy()
{
while(operationDone == 0);
operationDone = 0;
}

 

Einloggen