Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BIOS: disk lesen

5 views
Skip to first unread message

Urs Thuermann

unread,
Jul 16, 2006, 4:33:27 AM7/16/06
to
Nach langer Zeit habe ich eben mal wieder was mit dem BIOS und
real-mode gemacht und stolpere gerade über ein Problem mit dem BIOS.

Ich will eine Diskette track-weise mit int 0x13 einlesen an die
Adresse 1000:0000. Es ist %es:%bx mit 1000:0000 initialisiert. Ich
lese immer 18 Sektoren und erhöhe dann %es um 0x240, %bx ist immer 0.
Das geht aber schief, sobald ich über die Adresse 0x1FFFF hinauskomme:

Loading...
ax cx dx es bx
0212 0001 0000 1000 0000
0212 0001 0100 1240 0000
0212 0101 0000 1480 0000
0212 0101 0100 16C0 0000
0212 0201 0000 1900 0000
0212 0201 0100 1B40 0000
0212 0301 0000 1D80 0000
0212 0301 0100 1FC0 0000 Error 09


Im Fehlerfall rufe ich int 0x13 also auf mit

%ah = 2 read
%al = 0x12 18 sectors
%ch = 3 track 3
%cl = 1 sector 1
%dh = 1 head 1
%dl = 0 drive 0
%es:%bx = 0x1FC0:0000 destination

Der int 0x13 kommt mit %ah = 9 zurück, also Segmentüberschreitung.
Das finde ich merkwürdig, denn ich lese in das Segment 0x1FC0 ab dem
Offset 0x0000 von der Diskette 18 Sektoren, also 0x2400 Bytes ein,
also von 0x1FC0:0000 bis 0x1FC0:2400. Da wird doch keine
Segmetgerenze überschritten. Das Problem scheint zu sein, daß der
Zugriff nicht innerhalb eines 64k-aligned Segments liegt. Ist das
BIOS also so blöd, daß es hier von 0x1000:FC00 bis 0x2000:2000 lesen
will, was natürlich eine Segmentgrenze überschreit?

urs

Spiro Trikaliotis

unread,
Jul 16, 2006, 5:25:40 AM7/16/06
to
Hallo Urs,

Urs Thuermann <u...@isnogud.escape.de> schrieb:

> Ich will eine Diskette track-weise mit int 0x13 einlesen an die
> Adresse 1000:0000. Es ist %es:%bx mit 1000:0000 initialisiert. Ich
> lese immer 18 Sektoren und erhöhe dann %es um 0x240, %bx ist immer 0.

Hm... Das habe ich auch mal gehabt, an das von dir geschilderte Problem
kann ich mich aber nicht erinnern. Trotzdem:

> Ist das BIOS also so blöd, daß es hier von 0x1000:FC00 bis 0x2000:2000
> lesen will, was natürlich eine Segmentgrenze überschreit?

Meine Antwort mag vollkommen blöde sein, dennoch ein kleiner Hinweis:
Der Zugriff auf die Diskette erfolgt über den DMA-Baustein 8253/8254
(bzw. über ein Äquivalent davon in moderneren Rechnern). Obwohl ich den
selbst nie programmiert habe kann ich mir gut vorstellen, dass er von
den Segment des 8086 nichts wissen will, so dass die
Segmentüberschreitung durch ihn verursacht wird.

Da könnte dann das BIOS nichts gegen machen.

So könnte ich mir dieses Verhalten jedenfalls aus dem Stegreif erklären.

HTH,
Spiro.

--
Spiro R. Trikaliotis http://opencbm.sf.net/
http://www.trikaliotis.net/ http://www.viceteam.org/

Spiro Trikaliotis

unread,
Jul 16, 2006, 6:10:30 AM7/16/06
to
Hallo,

Spiro Trikaliotis <news-...@trikaliotis.net> schrieb:

> Meine Antwort mag vollkommen blöde sein, dennoch ein kleiner Hinweis:
> Der Zugriff auf die Diskette erfolgt über den DMA-Baustein 8253/8254

Ich meine natürlich den DMA-Baustein 8237. Eine kleine Verwirrung
meinerseits. ;)

Gruß,

Andreas Grögel

unread,
Jul 17, 2006, 3:52:52 AM7/17/06
to
Spiro Trikaliotis wrote:
> Meine Antwort mag vollkommen blöde sein, dennoch ein kleiner Hinweis:
> Der Zugriff auf die Diskette erfolgt über den DMA-Baustein 8253/8254
> (bzw. über ein Äquivalent davon in moderneren Rechnern). Obwohl ich den
> selbst nie programmiert habe kann ich mir gut vorstellen, dass er von
> den Segment des 8086 nichts wissen will, so dass die
> Segmentüberschreitung durch ihn verursacht wird.

Ist nicht blöde :) - woher sollte ein externer DMA-Baustein denn
überhaupt was von den Segmentregistern der CPU wissen? DMA arbeitet
immer mit physikalischen, unsegmentierten Adressen, und ist im Falle
dieses "antiken" ISA-DMA auf 64k-Alignment beschränkt. Und
erfahrungsgemäß überlassen es tatsächlich viele BIOSe dem Aufrufer,
die Floppy-Zugriffe entsprechend auszurichten.

--
Grüße,
Andreas

Urs Thuermann

unread,
Jul 22, 2006, 10:37:45 AM7/22/06
to
Andreas Grögel <ju...@ag1.de> writes:

> Ist nicht blöde :) - woher sollte ein externer DMA-Baustein denn
> überhaupt was von den Segmentregistern der CPU wissen? DMA arbeitet
> immer mit physikalischen, unsegmentierten Adressen,

Genau deswegen hätte ich ja erwartet, daß ich nicht auf die von der
CPU herrührende Segmentierung beschränkt bin. Ich habe angenommen,
daß der DMA controller mit 20 bit breiten physikalischen Adressen
arbeitet und daß ich problemlos über eine Adresse hinweg
lesen/schreiben kann, die ein Vielfaches von 64K ist.

> und ist im Falle dieses "antiken" ISA-DMA auf 64k-Alignment
> beschränkt.

Heißt das, man kann nicht einen track (18 Sektoren) von der floppy mit
einem BIOS-Aufruf beispielsweise an die Adresse 0x1FE00 lesen? Ich
muß also entweder mit einem BIOS-Aufruf von 0x1FE00 bis 0x1FFFF und
mit einem zweiten von 0x20000 bis 0x22200 lesen oder erst in einen
anderen Buffer lesen und dann an die Zieladresse verschieben?

Und wenn die Zieladresse z.B. 0x1FF00 sein soll, habe ich nur noch die
zweite Möglichkeit, weil ich schon einen Sektor nicht in den
Adreßbereich 0x1FF00 bis 0x200FF lesen kann?

Oh mann, ich staune immer wieder, wie krank diese ganze PC-Architektur
ist.

> Und erfahrungsgemäß überlassen es tatsächlich viele BIOSe dem
> Aufrufer, die Floppy-Zugriffe entsprechend auszurichten.

Ich habe erwartet, daß das BIOS die segmentierte Adresse in eine
20-Bit-Adresse umrechnet und dem Controller übergibt.

urs

Spiro Trikaliotis

unread,
Jul 23, 2006, 7:16:27 AM7/23/06
to
Hallo Urs,

Urs Thuermann <u...@isnogud.escape.de> schrieb:

> Ich habe erwartet, daß das BIOS die segmentierte Adresse in eine


> 20-Bit-Adresse umrechnet und dem Controller übergibt.

Das Problem hier: Der 8237 kann gar keine 20-Bit-Adressen. Er ist
nämlich eigentlich ein Baustein für den 8080/8085, der nur
16-Bit-Adressen konnte.

Für die zusätzlichen Bits werden sogenannte "DMA Page register" als
zusätzliche Latches ergänzt; da diese aber vom DMA-Chip getrennt sind,
kann kein Übertrag vom DMA-Baustein in diese Latches erfolgen, so dass
es eine "harte" 64KB-Grenze gibt.

Siehe z.B. "9.1.2 DMA Page Registers and 16Meg address space
limitations" unter
http://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/dma.html

oder auch http://www.cast-inc.com/cores/c8237/index.shtml

Gruß,

0 new messages