-
Windows und die Treiber
- Struktur der Windows Registrierung
Nun, die Windows Registrierung ist relativ einfach aufgebaut.
Man darf sich das ganze als eine Art Baum vorstellen, mit Astgabeln und Blättern.
Windows speichert in der Registrierung eine Liste aller im System verfügbaren Grafiktreibern.
Diese Liste findet man unter HKEY_LOCAL_MACHINE \ HARDWARE \ DEVICEMAP \ VIDEO
Dort gibt es zum einen den Schlüssel "MaxObjectNumber" welcher die höchste Nummer der aktiven Grafiktreiber enthält.
Es ist zu beachten das die erste Grafikkarte die Nummer 0 hat.
Für jeden Grafiktreiber findet man nun im Schlüssel "Video#", wobei # für eine Zahl ab 0 steht, eine Art Wegbeschreibung durch die Registrierung wo denn der Treiber zu finden ist.
Die Angabe "\Registry\Machine" kann man übrigends außer Acht lassen, da diese nur aussagt, das man in der Windows Registrierung im Stammschlüssel HKEY_LOCAL_MACHINE suchen muss.
Den Namen einer Grafikkarte kann, sofern vorhanden, am Schlüssel "Device Description" ablesen.
Ansonsten steht einem noch der Name des Grafiktreibers zur Verfügung, welchen man im Schlüssel "InstalledDisplayDrivers" findet.
- Erkennungsmerkmale
Man erkennt spezielle Treiber am besten an Markenten Schlüsseln.
Eine genaue Erläuterung der verwendeten Schlüssel zu jedem Treiber folgt weiter unten.
- NVidia Treiber
Einen NVidia ForceWare Treiber erkennt man am einfachsten an dem Schlüssel "NV_Modes".
- ATI Treiber
Einen ATI Catalyst Treiber erkennt man am einfachsten an dem Schlüssel "Catalyst_Version".
- Matrox Treiber
Einen Matrox Treiber erkennt man am einfachsten an dem Schlüssel "Mga.SingleResolutions".
- 3Dfx Treiber
Einen 3Dfx Treiber erkennt man am einfachsten an dem Schlüssel "GlideGammaTable".
- Intel GMA Treiber
Einen Intel GMA Treiber erkennt man am einfachsten an dem Schlüssel "TotalDTDCount".
-
NVidia Treiber
- NVidia Treiber
Der NVidia Treiber ist mir persönlich einer der liebsten.
Er verfügt über eine Liste mit allen Auflösungen, welche im Schlüssel "NV_Modes" zu finden ist, sowie einen Schlüssel namens "CUST_MODE" in dem jede Auflösung genau definiert werden kann, jedoch nicht muss.
- NV_Modes
Der Schlüssel "NV_Modes" enthält kleine Listen mit Auflösungen und den zugehörigen Grafikkarten.
Diese Listen werden mit Strichpunkten (;) getrennt und wiefolgt Aufgeschlüsselt:
{<ID>}<OPTION> <AUFLÖSUNGEN>=<REFRESHCODE>;
ID stell hierbei die Hardware-ID einer Grafikkarte dar, der diese Liste zugeordnet ist. Ein Stern * bedeutet das diese Liste für alle Grafikkarten gilt.
OPTION gibt Informationen zu den Auflösungen. S bedeutet das die Auflösungen für einen Bildschirm gedacht sind, H bzw. V bedeuten, das die Auflösungen für Mehr-Bildschirm-Betrieb gedacht sind.
AUFLÖSUNGEN führt alle Auflösungen in dieser Liste auf.
REFRESHCODE schließlich gibt Aufschluss darüber welche Bildwiederholraten erlaubt sind. Eine genaue Auflösung dieses Codes gibt es in der Dokumentation weiter unten.
Eine genaue Beschreibung des "NV_Modes" Schlüssels kann man im Compressed Modes UserGuide von NVidia nachlesen.
- CUST_MODE
Der Schlüssel "CUST_MODE" enthält kleine Datenblöcke mit Informationen zu speziellen Auflösungen.
Jeder dieser Datenblöcke ist genau 92 Byte lang.
Angemerkt sei auch das diese Datenblöcke in Big-Endian Format gespeichert sind.
Achtung! Es gibt einen Bug in der ForceWare, der verhindert das "CUST_MODE" richtig ausgelesen wird, wenn man mehr als 31 Datenblöcke einfügt. Dieser Bug wurde NVidia gemeldet, aber bisher gibt es noch kein Update.
Ein solcher Datenblock setzt sich aus 4 Komponenten zusammen.
- Kopf
Der Kopf ist 20 Byte lang und setzt sich wiefolgt zusammen:
Code:
Name Länge Wert Hex
NOT_USED 8 * 04 00 00 00 00 00 00 00
HEAD 4 3 03 00 00 00 <- 1 = VGA1, 2 = VGA2, 3 = VGA1 & VGA2, 16 = TV1 etc.
H_AKTIV 2 640 08 02 <- Aktive Pixel in der Breite (Windows!)
V_AKTIV 2 480 E0 01 <- Aktive Pixel in der Höhe (Windows!)
NOT_USED 2 * 00 00 <- Vermutlich Farbtiefe
V_RATE 2 60 3C 00 <- Bildwiederholrate (Windows!)
Hierbei handelt es sich AUSDRÜCKLICH um die Angaben die für Windows gelten, nicht was die Grafikkarte tatsächlich ausgibt.
- Data 1
Ein Datenblock ist 32 Byte lang und setzt sich wiefolgt zusammen:
Code:
Name Länge Wert Hex
NOT_USED 4 * 00 00 00 00
H_AKTIV 2 640 80 02
V_AKTIV 2 240 F0 00
H_TOTAL 2 776 08 03
H_FRONT 2 16 10 00 <- H_START - H_AKTIV
H_SYNC 2 56 38 00 <- H_ENDE - H_START
V_TOTAL 2 262 06 01
V_FRONT 2 3 03 00 <- V_START - V_AKTIV
V_SYNC 2 3 03 00 <- V_ENDE - V_START
NOT_USED 4 * 00 00 00 00
H_NEGSYNC 1 1 01
V_NEGSYNC 1 1 01
INTERLACE 1 1 01
DOUBLESCAN 1 0 00
V_FREQ 4 59940 24 EA 00 00 <- Bildwiederholrate in Hz
Achtung! Bei Interlace Auflösungen die Vertikal Werte durch 2 Teilen.
Bei Doublescan Auflösungen die Vertikal Werte (Außer V_AKTIV!) verdoppeln.
- Data 2
Auch dieser Datenblock ist 32 Byte lang.
Data 2 wird nur verwendet wenn zwei Bildschirme angesteuert werden, ansonsten ist der Datenblock komplett mit 0en gefüllt.
- Fuß
Der Fuß ist 8 Byte lang, jedoch komplett mit 0en gefüllt.
Anmerkung: Soft-15KHz fügt in Windows alle Auflösungen mit 60Hz hinzu.
-
ATI Treiber
- ATI Treiber
Die ATI Treiber sind die bisher aufwendigsten.
Es gibt eine "weisse" Liste mit allen Auflösungen die wir explizit wünschen.
Es gibt eine "schwarze" Liste mit allen Auflösungen die wir explizit nicht wünschen.
Und es gibt eine "graue" Liste mit Standard Auflösungen, die man allerdings nicht bearbeiten kann.
Man muss nun, wenn man nur ein paar spezielle Auflösungen haben will, diese in die "weisse" Liste eintragen, und dann alle Auflösungen aus der "grauen" Liste die man NICHT möchte in der "schwarzen" Liste hinzufügen.
Zudem muss man jede Auflösung unter 640x480 Pixel zusätzlich explizit "erlauben".
- Die "weisse" Liste
Die "weisse" Liste findet man im Schlüssel "DALNonStandardModesBCD".
Jeder Eintrag in dieser Liste ist genau 8 Byte lang.
Die Daten werden im "ATI-Style" gespeichert.
Ein Eintrag für 640x480 Pixel bei 60Hz sieht in Hex wiefolgt aus:
Code:
Name Länge Wert Hex
H_AKTIV 2 640 06 40
V_AKTIV 2 480 04 80
NOT_USED 2 * 00 00
V_FREQ 2 60 00 60
Wenn man V_FREQ leer, bzw. 0 lässt, werden alle standard Bildwiederholraten aktiv.
Ebenso kann diese Liste nur 16 Einträge beinhalten, weitere Einträge müssen dann in den Schlüssel "DALNonStandardModesBCD1", "DALNonStandardModesBCD2" u.s.w. eingetragen werden
- Die "schwarze" Liste
Die "schwarze" Liste findet man im Schlüssel "DALRestrictedModesBCD".
Jeder Eintrag in dieser Liste ist genau 8 Byte lang.
Die Daten werden im "ATI-Style" gespeichert.
Ein Eintrag für 640x480 Pixel bei 60Hz sieht in Hex wiefolgt aus:
Code:
Name Länge Wert Hex
H_AKTIV 2 640 06 40
V_AKTIV 2 480 04 80
NOT_USED 2 * 00 00
V_FREQ 2 60 00 60
Wenn man V_FREQ leer, bzw. 0 lässt, werden alle Bildwiederholraten gesperrt (außer die auf der "weissen" Liste).
- Eine Auflösung explizit erlauben/verbieten
Man muss eine Auflösung unter 640x480 Pixel explizit erlauben.
Hierfür gibt es für jede Auflösung einen Schlüssel namens "DALRULE_RESTRICT<H_AKTIV>x<V_AKTIV>MODE".
Hat dieser den Wert 0 ist eine Auflösung erlaubt, ist dieser Wert 1 ist sie verboten.
In unserem Beispiel ist das DALRULE_RESTRICT640x480MODE.
- Eine Auflösung konfigurieren
Um nun eine Auflösung im speziellen zu konfigurieren gibt es zwei Schlüssel.
- Polarität der Syncronisation festlegen
Die Polarität legt man im Schlüssel "DALR6 CRT<H_AKTIV>x<V_AKTIV>x0x<V_FREQ>" fest.
In unserem Beispiel ist das DALR6 CRT640x480x0x60.
Je nach Version des Catalyst Treibers sieht dieser Schlüssel etwas anders aus.
- Versionen vor 3.0
In Versionen vor 3.0 ist der Datenblock 24 Byte lang.
Code:
Name Länge Wert Hex
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 8 * 00 00 00 00 00 00 00 00
H_NEGSYNC 1 1 01 <- 1 = Negativ, 0 = Positiv
NOT_USED 3 * 00 00 00
V_NEGSYNC 1 1 01 <- 1 = Negativ, 0 = Positiv
NOT_USED 3 * 00 00 00
- Versionen 3.x und 4.x
In den Versionen 3.x und 4.x ist der Datenblock 28 Byte lang.
Code:
Name Länge Wert Hex
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 4 * 00 00 00 00
H_NEGSYNC 1 1 01 <- 1 = Negativ, 0 = Positiv
NOT_USED 3 * 00 00 00
V_NEGSYNC 1 1 01 <- 1 = Negativ, 0 = Positiv
NOT_USED 3 * 00 00 00
- Versionen 5.x und 6.x
In den Versionen 5.x und 5.x ist der Datenblock 32 Byte lang.
Code:
Name Länge Wert Hex
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 4 * 00 00 00 00
H_NEGSYNC 1 1 01 <- 1 = Negativ, 0 = Positiv
NOT_USED 3 * 00 00 00
V_NEGSYNC 1 1 01 <- 1 = Negativ, 0 = Positiv
NOT_USED 3 * 00 00 00
NOT_USED 4 * 00 00 00 00
- Die Auflösung selbst konfigurieren
Die Auflösungen selbst legt man im Schlüssel "DALDTMCRTBCD<H_AKTIV>x<V_AKTIV>x0x<V_FREQ>" fest.
In unserem Beispiel ist das DALDTMCRTBCD640x480x0x60.
Die Daten werden im "ATI-Style" gespeichert.
Dieser Datenblock ist 68 Byte lang und setzt sich wiefolgt zusammen:
Code:
Name Länge Wert Hex
NOT_USED 3 * 00 00 00
SCAN_OPTION 1 2 02 <- 1 = doublescan, 2 = interlace
NOT_USED 2 * 00 00
H_TOTAL 2 776 07 76
NOT_USED 2 * 00 00
H_AKTIV 2 640 06 40
NOT_USED 2 * 00 00
H_START 2 656 06 56
NOT_USED 2 * * 00 00
H_SYNC 2 56 00 56 <- H_ENDE - H_START
NOT_USED 2 * 00 00
V_TOTAL 2 525 05 25
NOT_USED 2 * 00 00
V_AKTIV 2 480 04 80
NOT_USED 2 * 00 00
V_START 2 486 04 86
NOT_USED 2 * 00 00
V_SYNC 2 6 00 06 <- V_ENDE - V_START
NOT_USED 2 * 00 00
PIX_FREQ 2 1221 12 21
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 8 * 00 00 00 00 00 00 00 00
NOT_USED 2 * 00 00
CHECKSUM 2 60687 ED 0F <- 65535 - 4848 = 60687
Die Prüfsumme errechnet man in dem man alle anderen Werte zusammen addiert und dann von 65535 abzieht.
-
Matrox Treiber
- Matrox Treiber
Matrox macht schöne Treiber, muss man ihnen lassen.
Der Matrox Treiber hat eine Liste mit allen Auflösungen, die sich im Schlüssel "Mga.SingleResolutions" findet.
Zudem gibt es für jede Auflösung eine Liste mit möglichen Anzeigemodi.
Diese Schlüssel haben den Namen "Graphic.<H_AKTIV>.<V_AKTIV>".
In unserem Beispiel wäre das Graphic.640.480.
- Mga.SingleResolutions
Jeder Eintrag in der Liste ist 4 Byte lang.
Daten werden in Big-Endian gespeichert.
Jeder Eintrag schlüsselt sich wie folgt auf:
Code:
Name Länge Wert Hex
H_AKTIV 2 640 80 02
V_AKTIV 2 480 E0 01
Anmerkung: Matrox Treiber mögen nur Auflösungen deren Breite ein Vielfaches von 8, und deren Höhe ein Vielfaches von 4 ist.
- Graphic.<H_AKTIV>.<V_AKTIV>
Wir verwenden für unser Beispiel den Schlüssel Graphic.640.480.
Der Schlüssel enthält eine Liste mit möglichen Bildwiederholraten für diese Auflösung.
Jeder Datenblock ist 24 Bytes lang und schlüsselt wiefolgt auf:
Code:
Name Länge Wert Hex
V_FREQ 2 60 3C 00
H_FREQ 2 16 10 00
PIX_FREQ 2 12210 B2 2F
NOT_USED 2 * 00 00
H_FRONT 2 16 10 00 <- H_START - H_AKTIV
H_SYNC 2 62 40 00 <- H_ENDE - H_START
H_BACK 2 56 38 00 <- H_TOTAL - H_ENDE
V_FRONT 2 3 03 00 <- V_START - V_AKTIV
V_SYNC 2 3 03 00 <- V_ENDE - V_START
V_BACK 2 16 10 00 <- V_TOTAL - V_ENDE
SYNC_OPT 2 1 01 00 <- 1 = interlace, 4 = +hsync, 8 = +vsync
NOT_USED 2 * 00 00
Achtung! Bei Interlace Auflösungen die Vertikal Werte durch 2 Teilen :)
-
3Dfx Treiber
- 3Dfx Treiber
Der 3Dfx Treiber ist logisch aufgebaut, bereitet mir dennoch einiges an Kopfzerbrechen.
Es gibt eine Schlüsselgruppe "TIMINGS", in der sich wiederrum für jede Auflösung eine Untergruppe "<H_AKTIV>,<V_AKTIV>" befindet.
In diesen Untergruppen gibt es für jede Bildwiederholrate eine weitere Schlüsselgruppe "<V_FREQ>Hz".
Anmerkung: Die Windows-Auflösung muss in der Breite durch 8 Teilbar sein, ansonsten gibt die Karte ziemlichen Pixelmüll aus.
In dieser Gruppe gibt es nun den Standardschlüssel, sowie einen Schlüssel "Supported".
- Standardschlüssel
Es gibt zwei möglichkeiten den Standardschlüssel zu befüllen.
Die erste ist der Wert "GTF", und bedeutet das die Karte selbst einen Modus entsprechend der Windows Vorgaben erstellt.
Die Zweite Möglichkeit ist eine durch Kommas getrennte Zahlenfolge die sich wiefolgt aufschlüsselt:
<H_TOTAL>,<H_START>,<H_ENDE>,<V_TOTAL>,<V_START>,< V_ENDE>,<OPTIONS>,<PIX_FREQ>,<V_FREQ>,8,<CHECKSUM>
H_TOTAL ist die Anzahl realer Pixel in der Breite.
H_START ist der Beginn der Synchronisation in der Breite.
H_ENDE ist das Ende der Synchronisation in der Breite.
V_TOTAL ist die Anzahl realer Zeilen in der Höhe.
V_START ist der Beginn der Synchronisation in der Höhe.
V_ENDE ist das Ende der Synchronisation in der Höhe.
OPTIONS steht für einige Optionen.
- 1 steht für das Zeilendoppelverfahren, das die Anzahl der sichtbaren Zeilen effektiv verdoppelt indem es jede Zeile doppelt darstellt.
- 4 steht für negative Horizontal-Synchronisation.
- 8 steht für negative Vertikal-Synchronisation.
PIX_FREQ ist die Pixelfrequenz.
V_FREQ ist die Bildwiederholrate.
8 ist bisher unbekannt und hat IMMER den Wert 8.
CHECKSUM ist eine Prüfsumme alle anderer Zahlenwerte.
- Supported
Der Schlüssel "Supported ist eine durch Kommas getrennte Wortfolge.
Einige der Werte im Detail:
BPP+8+16+32 bedeutet das die Farbtiefen von 8, 16 und 32 Bit erlaubt sind.
DDRAW bedeutet das der Modus in DirectX genutzt werden kann.
DFP_DESK sowie DFP_DDRAW bedeuten das der Modus in Verbindung mit einem Flachbildschirm als Desktop und in DirectX genutzt werden kann.
Anmerkung: Eigentlich witzig, denn keine 3Dfx Karte für den PC verfügt über einen DVI Ausgang. Diese waren den Macintosh Versionen vorbehalten.
TVO_DESK sowie TVO_DDRAW bedeuten das der Modus in Verbindung mit einem Fernseher als Desktop und in DirectX genutzt werden kann.
NTSC und PAL bedeuten das der Modus in Verbindung mit einem Fernseher in eben NTSC oder PAL genutzt werden kann.
-
Intel GMA Treiber
- Intel GMA Treiber
Die neueren Intel GMA Treiber lassen sich mit mehr oder weniger Aufwand erweitern.
- Statische Liste
Dem Intel GMA Treiber kann eine statische Liste verfügbarer Auflösungen zugewiesen werden, deren Größe im Schlüssel "TotalStaticModes" definiert ist.
Für jede Auflösung in dieser statischen Liste gibt es einen Eintrag mit dem Namen "STATIC_MODE_#", wobei # einer Zahl zwischen 1 und dem Wert von "TotalStaticModes" entspricht.
- STATIC_MODE_#
Der Aufbau eines Eintrags sieht wiefolgt aus.
Code:
Name Byte Note
---- ---- ----
XRes 2 Pixelbreite der Auflösung
YRes 2 Pixelhöhe der Auflösung
RMask 2 Refresh-Maske (Bit 0 = 60Hz, Bit 1 = 70Hz, Bit 2 = 72Hz, Bit 3 = 75Hz, 4 = 85Hz, 5 = 100Hz, 6 = 120Hz, 7-15 unbekannt)
BMask 1 Bit-Maske (Bit 0 = 256 Farben, Bit 1 = 16Bit, Bit 2 = 32Bit, 3-7 unbekannt)
Unkn 1 Unbekannt (immer 0x0F bzw. 15)
- Definitionsliste
Der Intel GMA Treiber hat eine Definitionsliste für "spezielle" Auflösungen, deren Anzahl im Schlüssel "TotalDTDCount" zu finden ist.
Zudem gibt es dann für jede Auflösung einen Datenblock mit dem Namen "DTD_#", wobei # einer Zahl zwischen 1 und dem Wert von "TotalDTDCount" entspricht.
In unserem Beispiel wäre das DTD_1.
- DTD_#
Der Aufbau eines Datenblocks sieht wiefolgt aus.
Achtung! Ich konnte das noch nicht am laufenden Gerät testen, alle Angaben also ohne Gewähr :)
Code:
Name Bits Note
---- ---- ----
PCLOCK 16 Pixel Clock
lHACT 8 Lower 8 Bits of Horizontal Active
lHBLK 8 Lower 8 Bits of Horizontal Blanking
uHACT 4 Upper 4 Bits of Horizontal Active
uHBLK 4 Upper 4 Bits of Horizontal Blanking
lVACT 8 Lower 8 Bits of Vertical Active
lVBLK 8 Lower 8 Bits of Vertical Blanking
uVACT 4 Upper 4 Bits of Vertical Active
uVBLK 4 Upper 4 Bits of Vertical Blanking
lHOFF 8 Lower 8 Bits of Horizontal Offset
lHPUL 8 Lower 8 Bits of Horizontal Pulse
lVOFF 4 Lower 4 Bits of Vertical Offset
lVPUL 4 Lower 4 Bits of Vertical Pulse,
uHOFF 2 Upper 2 Bits of Horizontal Offset
uHPUL 2 Upper 2 Bits of Horizontal Pulse
uVOFF 2 Upper 2 Bits of Vertical Offset
uVPUL 2 Upper 2 Bits of Vertical Pulse
lHI 8 Lower 8 Bits of Horinzontal Image Size (unused)
lVI 8 Lower 8 Bits of Vertical Image Size (unused)
uHI 4 Upper 4 Bits of Horizontal Image Size
uVI 4 Upper 4 Bits of Vertical Image Size
HO 8 Horizontal Border
VO 8 Vertical Border
bILACE 1 Interlace-Flag (0 off, 1 on)
S3DFLG 2 Stereo3D Flags (00 = off)
SEPSYN 2 Seperate Sync (11 = H- and V-Sync)
VSPOL 1 Vertical Polarity (0 - negative, 1 - positive)
HSPOL 1 Horizontal Polarity (0 - negative, 1 - positive)
S3DMOD 1 Stereo Mode (0 - off, 1 - on)
INTEL 16 Intel Flags (don't know right now, use 27,00 or 37,01)