Grafikreegister



  • Hallo,
    ich arbeite im PMode und würde gerne Auflösung und Farbtiefe ändern, ohne in den RealMode zurückschalten zu müssen. So weit ich weiß, gibt es ja keine Möglichkeit dies über Vesa zu tun (falls doch, lasse ich mich gerne belehren). Nun habe ich gelesen, dass es auch an die 100 Grafikregister gibt, die sich über OUT ansteuern lassen und das ganze auch noch wesentlich schneller ist als VESA. Wo finde ich eine Liste dieser Register und evt. ein paar Beispiel? Vieln vielen Dank im voraus!



  • Hi

    für VGA gibts nen quasi standard, an den sich fast alle gehalten haben, alles was darüber hinaus geht SVGA und so ist kartenabhängig. Darum gibts ja auch ein VESA BIOS um zumindest eine gemeinsame software schnitstelle zu haben. Diese ist zumindest bei den neueren karten auch über PM ereichbar. VESA 3.0 glaub ich war das. War doch früher schon so, das mansche spiele nur mit ganz bestimmten karten funktioniert haben, auf anderen wars dan tirisch langsam.

    gruss Termite



  • Naja um ein Bild anzuzeigen wäre VESA ja noch schnell genug. Nur kann mir einer hier vielleicht einfach erklären, wie ich z.b. die Auflösung auf 1024x768x32 setzen kann mit VESA im PMode? Danke! Denn soweit ich das in der VBE 3.0 verstanden habe, gibt es lediglich 3 Funktionen um PMode die man nutzen kann, und eine solche zählt nicht dazu 😞



  • Moin sevobal,

    natürlich ist es möglich einen Grafikmodus mit dem PM-Interface einzuschalten. Welche Vorbereitungen man genau treffen muss, um die PM-Funktionen zu nutzen, ist in der offiziellen VBE-Spezifikation beschrieben und die gibt es unter

    http://www.vesa.org/public/VBE/

    Die Datei der Wahl heißt vbe3.pdf(271 KB). Die Beschreibung für den Protected-Mode-Entrypoint findest Du ab Seite 21.

    Ciao...



  • hm....hat das konkret auch schon mal einer geschaft? Im netz findet man da ja nichts zu. Denn ich bracuhe eine Hinweis. Wo muss ich diesen PMInfoBlock eintragen? in die GDT? Und wo oder in welches Register (wenn überhaupt) bekomme ich dann den Pointer um die PM Routinen aufzurufen? Wenn ich das richtig verstanden habe sind die Befehle ja identisch zum Auflösung setzen, nur das anstatt mit int 10 mit dem Pointer aufgerufen wird oder? 😕



  • Hi.

    sevobal schrieb:

    hat das konkret auch schon mal einer geschaft?

    Oehm... Ja. 😉

    sevobal schrieb:

    Wo muss ich diesen PMInfoBlock eintragen? in die GDT?

    Was du mit dem PMInfoBlock machen musst/kannst steht doch alles detailiert in den VBE3 Docs ab Seite 21 und auf Seite 22 folgt nochmal eine schoene Zusammenfassung. 🙄
    Ob GDT oder LDT verwendet wird, solltest du in deinem OS schon selbst wissen...
    Verwendest du Funktionen eines anderen OS (zB. DPMI), braucht dich das nicht kuemmern.

    ...Da du absolut keinen Durchblick zu haben scheinst, traegt es vielleicht zum besseren Verstaendnis bei, wenn ich dir og. Zusammenfassung auf Deutsch abschreibe:

    1. Reserviere einen mindestens 32KByte grossen Speicherbereich

    2. Kopiere das BIOS-Image von C0000h dort hin.

    3. Durchsuche das BIOS-Image nach dem PMInfoBlock (nach "PMID" suchen) und pruefe die Checksum. (Schritt 3 ist IMHO sinnvoller an erster Stelle, aber egal)

    4. Reserviere einen mindestens 600Byte grossen mit 0en gefuellten Speicherbereich fuer die BIOS-Daten. Erzeuge einen neuen Descriptor fuer diesen Datenbereich und trage den zugehoerigen Selector in das Feld "BIOSDataSel" im PMInfoBlock ein.

    5. Erzeuge jeweils Daten-Descriptoren, die auf A0000h, B0000h und B8000h zeigen und ein Limit von 64, 64 und 32KByte haben. Trage die dazugehoerigen Selectoren in die Felder A0000Sel, B0000Sel und B8000Sel im PMInfoBlock ein.

    6.Erzeuge einen Descriptor mit Lese-/Schreibrechten, der auf das kopierte BIOS-Image zeigt und trage den entsprechenden Selector in das Feld CodeSegSel im PMInfoBlock ein.

    7.Setze das Feld InProtectMode im PMInfoBlock 1 ein.

    8.Erzeuge einen 16Bit-CodeSeg-Descriptor mit Leserechten, der auf den Anfang des kopierten BIOS-Image zeigt. Der dazugehoerige Selector und der Wert beim PMInitialize-Feld ergeben ein 16:16, bzw 16:32 (bei 32Bit-OS muss auf 32Bit erweitert werden) Selector:Offset-paar. Mit diesem Selector:Offset-paar kannst du die Initialisierungsroutine des VESA-BIOS aufrufen. Diese muss ausgefuehrt werden, bevor andere Funktionen im PM verwendet werden koennen.

    9.Reserviere mindestens 1024Byte Speicher und erzeuge einen 16Bit-Daten-Descriptor, der auf diesen Speicherbereich zeigt. Dieser Puffer sollte als 16Bit-Stack fuer das BIOS benutzt werden. In diesem Fall muss vor dem Aufrufen einer BIOS-Funktion SS mit dem entsprechenden Selector geladen und SP auf 0 gesetzt werden.

    10.Mit dem in Schritt 8 erzeugten Selector und dem Wert im Feld EntryPoint hast du nun einen 16:16 (bzw. 16:32) far-Pointer. Mit diesem kannst du die VESA-Funktionen im PM via far-call aufrufen. Beachte, dass der Stack auf jeden Fall mindestens 1024Byte frei haben und 16Bit sein muss (ggF. in Schritt 9 erzeugten Stack benutzen).

    Weiter unten steht dann noch, dass alle Pointer, die BIOS-Funktionen uebergeben werden, 16:16 sein muessen (16Bit Offsets). 32Bit-Offsets muessen uU. mittels neuem Selector zu 16:16 konvertiert werden.

    So... Ist doch einleuchtend, oder? 😕
    Nun wuerde mich mal interessieren, wo genau eigentlich dein Problem liegt... Alle genannten Informationen standen ja wie gesagt auch so in etwa in den Docs.

    sevobal schrieb:

    Wenn ich das richtig verstanden habe sind die Befehle ja identisch zum Auflösung setzen, nur das anstatt mit int 10 mit dem Pointer aufgerufen wird oder?

    Jo, in der Tat, das hast du richtig verstanden.



  • danke, du hast recht, das klingt soweit einleuchtend...Danke! Nur wie kopiere ich eine Bios Image an eine Adresse und durchsuche es (mag ne blöde Frage sein 😕 ?



  • Moin sevobal,

    wenn ich Deine bisherigen Fragen richtig interpretiere, dann bist Du dabei ein OS zu programmieren. Ich möchte Dir nicht zu nahe treten, aber kennst Du überhaupt schon die wichtigsten Befehle der Intel( und kompatiblen) Prozessoren?

    Es gibt beispielsweise die hübschen, sogenannten, Stringfunktionen. Die dienen dazu komplette Speicherbereiche quasi mit einem Befehl zu kopieren.

    Quelle: ds:(e)si
    Ziel: es:(e)di

    Die Register (e)si und (e)di werden dabei automatisch erhöht oder erniedrigt.

    mov    (e)si, AdresseDesBIOSImage
            mov    (e)di, AdresseDesZielSpeicherbereichs
    
            ; Direction-Flag löschen, damit (e)si und (e)di inkrementiert werden
            cld
    
            mov    (e)cx, 8192  ; 8192 DWORDs kopieren
            rep movsd
    
            oder
    
            mov    (e)cx, 16384  ; 16384 WORDs kopieren
            rep movsw
    
            oder
    
            mov    (e)cx, 32768  ; 32768 BYTEs kopieren
            rep movsb
    

    Ciao...



  • Und zum Suchen nach "PMID" kannst du die scas-Instruktion benutzen.
    Die vergleicht den Inhalt von (e)ax, bzw. al mit dem Wert bei es:(e)di und veraendert (e)di dem direction-flag entsprechend - wie die uebrigen String-Befehle auch.

    Also Hier 2 Vorschlaege:
    1. Moeglichkeit:
    Du suchst mittels scasb erstmal nach "P" und pruefst dann, ob dort wirklich "PMID" steht - zB. mittels

    cmp [dword ptr es:edi - 01h], 'DIMP' ;TASM liest solche Strings falsch herum...
    

    2. Moeglichkeit:
    Du suchst mittels scasd nach "PMID" und ziehst jedesmal, wenn der String nicht stimmt, wieder 3 von edi ab, damit in Byte-Schritten nach dem String gesucht wird.



  • okay. Danke für eure Hilfe, jetzt sollte es kein Problem mehr sein!


Anmelden zum Antworten