FAST GELÖST: Hilfe beim beim Sektorenlesen (DMA im P-Mode) - der 18. Sektor!
-
Ich nochmal,
nach langem experimentieren bin ich nervlich am Ende
Erstmal etwas zum Programm selbst:
Das Einlesen eines Sektors geschieht mit 4 Funktionen.
call setsektor ;Log. Sektor umwandeln call setdma ;DMA Einstellungen festlegen call dmaread ;DMA auf lesen stellen call read ;Sektor einlesen call fdd_ready ;Warten bis FDD bereit
Funktion "setsektor" wandelt den logischen Sektor in seine Bestandteile
Spur, Kopf und Sektornummer um:;wandelt den logischen in einen "echten" Sektor um (Kopf, Spur und Sektor) setsektor: ;Sektor berechnen und in Variablen eintragen pushad ;inc word [logsektor] ;nächsten logischen Sektor lesen movzx eax, word [logsektor] push eax xor edx, edx xor ebx, ebx mov bl, byte [sekzahl] div ebx mov eax, edx inc eax mov byte [aktsektor], al ;der aktuelle Sektor pop eax push eax xor edx, edx xor ebx, ebx mov bl, byte [sekzahl] div ebx and eax, 1d mov byte [aktkopf], al ;der aktuelle Kopf pop eax mov ecx, 36d xor edx, edx div ecx mov byte [aktspur], al ;die aktuelle Spur popad ret
Funktion "setdma" konfiguriert den DMA Controller mit der Adresse 0x300000 (3MB)
;setzt die DMA Einstellungen setdma: pushad mov al, 0x6 mov edx, 0xa out dx, al ;mask dma channel 2 mov al, 0xff mov edx, 0d8h out dx, al ;reset master flip-flop mov edx, 0x4 mov ebx, dword [address] mov al, bl out dx, al mov al, bh out dx, al ;Adresse festlegen von Buffer mov al, 0xff mov edx, 0xd8 out dx, al ;reset master flip-flop mov edx, 0x5 mov al, 0xFF out dx, al mov al, 0x1 ;0x1 nur für einen Sektor out dx, al ;511 = 512 Byte einlesen xor eax, eax mov ax, word [address +2] mov edx, 0x81 out dx, al ;Page Register laden ;DMA aktivieren mov al, 0x2 mov edx, 0xa out dx, al ;unmask dma channel 2 popad ret
Die Funktion "dmaread" stellt den DMA auf schreiben in den Speicher ein.
;Setzt DMA auf lesen (Gerät ----> Speicher) dmaread: pushad mov al, 0x6 mov edx, 0xa ;d4 out dx, al ;mask dma channel 2 mov edx, 0xb ;d6 mov al, 0x56 ;single transfer, address increment, autoinit, write, channel 2 out dx, al ; mov al, 0x2 mov edx, 0xa ;d4 out dx, al ;unmask dma channel 2 popad ret
Und zuletzt noch die Funktion "read", diese übergibt die Befehle zum
lesen eines Sektors an den FDD.;liest den gewählten logischen Sektor ein ;setdma muss immer aus die Größe einer ganzen Spur eingestellt werden ;sonst kann man immer nur einen Sektor lesen ;Bei der Befehlsübergabe (read) übergibt man die Anzahl der zu lesenden ;Sektoren (max. 17) und alles läuft :-) read: pushad mov edx, 0x3f2 mov al, 0x1c out dx, al ;Daten ins DOR schreiben = Aktivieren mov edx, 0xFFFF .warten: nop dec edx jnz .warten ;Warteschleife zum aktivieren des Motors im LW mov edx, 03f5h ;Datenregister mov al, 11100110b out dx, al xor eax, eax mov al, byte [aktkopf] shl ax, 2 and al, 11111100b out dx, al ;Kopf und Laufwerk Bit 0 - 2 xor eax, eax mov al, byte [aktspur] out dx, al ;Zylinder (Spur) xor eax, eax mov al, byte [aktkopf] out dx, al ;Kopf wie Befehl 2 mov al, byte [aktsektor] ;Sektornummer out dx, al mov al, 0x2 out dx, al ;Sektorgröße = 2 (512 Byte) mov al, byte [aktsektor] out dx, al ;Anzahl zu lesender Sektoren, sollte = Sektornummer sein ; damit nur ein Sektor gelesen wird mov al, 27d ;GAP Nummer = 27 (Standard) out dx, al mov al, 0xff out dx, al ;Länge der Daten (immer 0FFh) popad ret
Damit kann ich (fast) jeden Sektor, auch mehrere in einer Schleife einlesen.
Nun zu dem fast:
Den Aufruf jedes 18. Sektors quittiert mein Programm mit Stillstand
Alle anderen (Sektor 1 bis 17 auf jeder Spur) kann ich problemlos einlesen und auf dem Schirm anzeigen.Ich habe alle Funktionen zum lesen und schreiben der FAT fertig, jedoch kann
ich diese nicht richtig nutzen wenn ich nicht auf die ganze Disk zugreifen kann.Kann mir bitte jemand sagen was das Geheimnis des 18. Sektors ist?
Nicky
-
das selbe Problem (18. Sektor) ist bei einlesen einer ganzen Spur...
Nicky
-
Hallo,
Das Programm habe ich gestern abend auf einem "echten" PC getestet.
Läuft tadellos, ebenfalls erhalte ich ganz andere Ergebnisbytes nach der
Befehlsphase. Liegt wohl doch an der virtuellen Maschine.Nicky
-
des Rätsels Lösung war das Bit 4 im Modusregister des DMA Controllers.
Virtual PC kommt damit wohl nicht zurecht.Nicky