SVGA Programmierung

Super VGA Programmierung

Vorteile der SVGA-Grafikkarten gegenüber normalen VGA-Karten :
•	mehr Farben in allen Grafikmodi
•	höhere Auflösungen (bis 1600x1280 mit 16 Millionen Farben)
•	Hardware Zooming
•	Hardware-Cursor im Grafikmodus
•	Neue Textmodi mit mehr Spalten und Zeilen

Nachteile der SVGA-Programmierung:
•	Keine einheitliche Numerierung der Grafikmodi
•	Keine Standards für Textmodi

Der VESA Standard

Der VESA Standard wurde von der Video Electronics Standard Association im Jahr 1990 ins Leben gerufen. Dem VESA-Komitee gehören die wichtigsten Grafikkartenhertstellern (wie z.B. VideoSeven, S3, Orchid, Genoa, Intel, ...) an. Dieser Standard wurde als BIOS-Erweiterung in die neuen Grafikkarten integriert. Ältere Grafikkarten konnte man mit TSR - Programmen VESA-Tauglich machen.

Grafikmodi des VESA Standards:

Modus	Modusnummer	
		
80x60		 (Textmodus)	108h	
132x25	109h	
132x43	10Ah	
132x50	10Bh	
132x60	10Ch	
		
640x400x256	(Grafikmodus)	100h	
640x480x256	101h	
800x600x16	102h	
800x600x256	103h	
1024x768x16	104h	
1024x768x256	105h	
1280x1024x16	106h	
1280x1024x256	107h	
320x200x32K	10Dh	
320x200x64K	10Eh	
320x200x16M	10Fh	
640x480x32K	110h	
640x480x64K	111h	
640x480x16M	112h	
800x600x32K	113h	
800x600x64K	114h	
800x600x16M	115h	
1024x767x32K	116h	
1024x767x64K	117h	
1024x767x16M	118h	
1280x1024x32K	119h	
1280x1024x64K	11Ah	
1280x1024x16M	11Bh	
Tabelle 1

Aufruf der Funktionen des VESA BIOS:

Die VESA Funktionen sind genau so wie die Standard-VGA Funktionen über den Grafikinterrupt 10h zu erreichen. Das Register AH ist mit 4Fh zu laden, die Funktionsnummer wird im AL Register übergeben.
War der Aufruf erfolgreich, steht nach der Ausführung des Interrupts im AL Register 4Fh und im AH Register 00h.

Die VESA Funktionen:

AL	Funktion	
		
00h	SVGA-Informationen 
Eingabe 	:	ES:DI 		(Zeiger auf einen 256 Bytes großen Speicherbereich)
Ausgabe		:	
01h	SVGA-Modusinformationen
Eingabe		:	ES:DI 		(Zeiger auf einen 29 Bytes großen Speicherbereich)
			CX 		Modusnummer
Ausgabe		:	-	
02h	VESA-Modus setzen
Eingabe		:	BX		Modusnummer
Ausgabe		:	-	
03h	VESA-Modus ermitteln
Eingabe		:	-
Ausgabe		:	BX		Aktueller Grafikmodus (auch normale VGA-Modes)	
04h	Zustand der Grafikkarte sichern / laden
Eingabe		:	ES:BX	(Zeiger auf einen Speicherbereich)
			DL
				Wert	Funktion
				0	Nötigen Speicherplatz ermitteln
				1	Zustand sichern
				2	Zustand laden
			CX
				Bit	Funktion
				0	Hardwarezustand
				1	BIOS-Datenbereich
				2	DAC-Zustand
				3 	SVGA-Zustand
Ausgabe		:	-	
05h	Position des Speicherfensters ermitteln / verschieben
Eingabe		:	BL
				Wert	Funktion
				00	Fenster A
				01	Fenster B
			BH				
				0	Fenster an neue Position verschieben
				1	Fensterposition ermitteln
			DX		Neue Hauptspeicherposition
Ausgabe		:	DX		Hauptspeicherposition (Bei BH = 1)	
06h	Länge der Punktzeile lesen /setzen
Eingabe		:	BL
				0	Länge neu setzen
				1	Länge ermitteln
			CX		Neue Länge (In Punkten)
Ausgabe		:	CX		Länge in Punkten (Bei BL = 1)
			BX		Speicher in Bytes, den eine Zeile belegt	

AL	Funktion	
07h	Beginn des sichtbaren Bereichs lesen/setzen
Eingabe		:	BX
				0	Beginn neu setzen
				1	Aktuellen Beginn abfragen
			CX		Punktspalte
			DX		Zeile
Ausgabe		:	CX		Spalte (Bei BX = 1)
			DX		Zeile ( Bei BX  = 1)				
08h	Farbtiefe der Palette
Eingabe		:	BL
				0	Farbtiefe setzen
				1	Aktuelle Farbtiefe ermitteln
			BH		Anzahl der Bits (Bei BL = 0)
Ausgabe		:	BH		Aktuelle Anzahl der Bits (Bei BL = 1)	
Tabelle 2

Genaue Beschreibung der Funktionen

Funktion 00h								SVGA Informationen abfragen

Vinfo ist ein 256 Byte großer Far-Pointer
Regs ist eine Variable vom Typ Registers

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $00;			{ VESA Funktion 00h		}
Regs.ES := Seg(Vinfo);		{ Segment des FAR-Pointers	}
Regs.DI := Ofs(Vinfo); 		{ Offset des FAR-Pointers		}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Aufbau des Datenblocks

Offset	Inhalt	Länge	
			
00h	“VESA“ (Signatur)	4 Byte	
04h	VESA Version (Major)	1 Byte	
05h	VESA Version (Minor)	1 Byte	
06h	FAR Pointer auf einen ASCII2 String mit dem Namen des Kartenherstellers	1 DWord	
0Ah	ungenutzt (0000h)	1 DWord	
0Eh	FAR Pointer auf Liste mit den Codenummern der unterstützten Grafikmodi *	1 DWord
	
Tabelle 3

* Diese Liste (0Eh) enthält einzelne Words, die die jeweiligen Funktionsnummern beinhalten. Die Kartenspezifischen Modi sind kleiner als 100h, die VESA Modi sind größer als 100h (s. Tabelle 1).
Das Ende dieser Liste wird mit FFFFh gekennzeichnet.

Funktion 01h						SVGA Modusinformationen abfragen

Minfo ist ein  FAR-Pointer zu einem 29 Byte großen Speicherbereich
Regs ist eine Variable vom Typ Registers

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $01;			{ VESA Funktion 01h		}
Regs.ES := Seg(Minfo);		{ Segment des FAR-Pointers	}
Regs.DI := Ofs(Minfo); 		{ Offset des FAR-Pointers		}
Regs.CX := $107;			{ Gewünschter Grafikmodus	}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Aufbau des Datenblocks

Offset	Inhalt	Länge	
			
00h	Modus-Flag  (s. Tabelle 3)	1 Word	
02h	Flag fürs 1. Fenster  (s. Tabelle 6)	1 Byte	
03h	Flag fürs 2. Fenster  (s. Tabelle 6)	1 Byte	
04h	Anzahl der KBytes die im Fenster verschoben werden können	1 Word	
06h	Größe der Fenster in Kbytes	1 Word	
08h	Segmentadresse des 1. Fensters	1 Word	
0Ah	Segmentadresse des 2. Fensters	1 Word	
0Ch	FAR-Pointer auf Routine zum Verschieben des Fensters	1 DWord	
10h	Anzahl der Bytes pro Punktzeile	1 Word	
12h	X Auflösung in Punkten	1 Word	
14h	Y Auflösung in Punkten	1 Word	
16h	Breite der Zeichenmatrix in Punkten	1 Byte	
17h	Höhe der Zeichenmatrix in Punkten	1 Byte	
18h	Anzahl der Bit-Planes	1 Byte	
19h	Anzahl der Bits pro Bildschirmpunkt	1 Byte	
1Ah	Anzahl der Speicherblöcke	1 Byte	
1Bh	Speichermodell  (s. Tabelle 7)	1 Byte	
1Ch	Größe der Speicherblöcke	1 Byte	
Tabelle 4

Struktur des Modus-Flag

Bit	Inhalt	
		
0	Kann Modus mit Bildschirm verwendet werden ?
0 = Nein	1 = Ja	
1	Wurden optionale Informationen geliefert ?
0 = Nein	1 = Ja	
2	Werden BIOS-Textfunktionen unterstützt ?
0 = Nein	1 = Ja	
3	0 = monochromer Modus		1 = Farbmodus	
4	0 = Textmodus			1 = Grafikmodus	
5 -15 	nicht belegt	
Tabelle 5

Aufbau der beiden Flags für die Fenster (02h und 03h):

Bit	Inhalt	
		
0	Ist das Fenster verfügbar ?
0 = Nein	1 = Ja	
1	Lesezugriffe auf Video-RAM über Fenster möglich ?
0 = Nein	1 = Ja	
2	Schreibzugriffe auf Video-RAM über Fenster möglich ?
0 = Nein	1 = Ja	
3-7	nicht belegt	
Tabelle 6

Kodierung des Speichermodells (Offset 1Bh)

Nummer	Aufgabe	
		
00h	Textmodus	
01h	CGA - Format mit 2 oder 4 Speicherblöcken	
02h	Hercules - Format mit 4 Speicherblöcken	
03h	normales EGA/VGA Format für 16 Farben Grafikmodi	
04h	gepacktes Format mit 2 Punkten  = 4 Bit pro Byte	
05h	normales EGA/VGA Format für 256 Farben Grafikmodi	
06h - 0Fh	reserviert	
10h - FFh	Hersteller-spezifische Codes (bislang ungenutzt)	
Tabelle 7

Funktion 02h									   VESA Modus setzen

Um einen neuen VESA Modus zu setzen, muss in CX der gewünschte Modus übergeben werden.
Soll der Grafikspeicher beim Einschalten des Modus nicht gelöscht werden, muß das 15. Bit gesetzt werden.

Regs ist eine Variable vom Typ Registers

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $02;			{ VESA Funktion 02h		}
Regs.CX := $107;			{ Gewünschter Grafikmodus	}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Funktion 03h						                       Aktuellen Grafikmodus ermitteln

Bei der Ermittlung des aktuellen Modus steht nach Ausführung des Interrupts im Register BX der Modus.
Werte unter 100h bedeuten, daß es sich um einen Standard VGA Modus handelt, Werte über 100h bedeuten, daß es sich um einen VESA-Modus handelt.

Regs ist eine Variable vom Typ Registers
ActMode ist eine Variable vom Typ Word

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $03;			{ VESA Funktion 03h		}
Intr($10, Regs);			{ Grafikinterrupt 10h		}
Actmode := Regs.BX;		{ Aktueller Grafikmodus in BX	}

Funktion 04h						         Zustand der Grafikkarte sichern / laden 
Unterfunktion 00h						       Benötigten Speicherplatz feststellen

Das DL Register muß mit 00h geladen werden. Im CX Register müssen je nach Anforderung folgende Bits gesetzt werden:

Bit	Funktion	
		
0	Hardwarezustand sichern	
1	BIOS Datenbereich sichern	
2	DAC-Zustand sichern	
3	SVGA-Zustand sichern	
Tabelle 8

Nach Ausführung des Interrupts liefert das BX Register die Anzahl der benötigten 64 Byte Blöcke zurück.
Der Puffer muss also eine Größe von 64 * BX haben.

Regs ist eine Variable vom Typ Registers
NeedSpace ist eine Variable vom Typ Word;

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $04;			{ VESA Funktion 04h		}
Regs.DL := $00;			{ Unterfunktion 00h		}
Regs.CL := 15;			{ Alle Komponenten sichern	}
Intr($10, Regs);			{ Grafikinterrupt 10h		}
NeedSpace := Regs.BX * 64;	{ Benötigter Speicher in Bytes	}

Unterfunktion 01h						     		            Zustand sichern 

Das DL Register muss mit 01h geladen werden. Im CX Register müssen die Bits wie bei Unterfunktion 00h gesetzt werden (s. Tabelle 8).  Segment und Offset des Puffers werden in ES:BX übergeben.

Regs ist eine Variable vom Typ Registers
Buffer ist ein Pointer mit der benötigten Größe

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $04;			{ VESA Funktion 04h		}
Regs.DL := $01;			{ Unterfunktion 01h		}
Regs.CL := 15;			{ Alle Komponenten sichern	}
Regs.ES := Seg(Buffer);		{ Segment des Puffers		}
Regs.BX := Ofs(Buffer);		{ Offset des Puffers		}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Unterfunktion 02h						     		               Zustand laden 

Das DL Register muss mit 02h geladen werden. Im CX Register müssen die gleichen Bits wie bei der Unterfunktion 00h gesetzt werden (s. Tabelle 8). Segment und Offset des Puffers werden in ES:BX übergeben.

Regs ist eine Variable vom Typ Registers
Buffer ist ein Pointer mit der benötigten Größe

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $04;			{ VESA Funktion 04h		}
Regs.DL := $02;			{ Unterfunktion 02h		}
Regs.CL := 15;			{ Alle Komponenten laden	}
Regs.ES := Seg(Buffer);		{ Segment des Puffers		}
Regs.BX := Ofs(Buffer);		{ Offset des Puffers		}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Funktion 05h	     				                       Position des Speicherfensters verschieben

Da bei zeitkritischen Anwendungen ein Interruptaufruf sehr lange dauert, und da die Speicherfenster relativ
oft verschoben werden müssen, wurde eine Far-Call Funktion direkt in das VESA-Bios integriert. Die Adresse steht im Datenblock der Funktion 01h zurückliefert bei Offset 0Ch (s. Tabelle 4).
Im DX Register wird angegeben, wie weit das Speicherfenster verschoben werden soll. Liegt die Granularität z.B. bei 1 kByte, bewirkt der Wert, das das Speicherfenster um 256 kBytes verschorben wird.
Im BX Register wird die Nummer des Zugriffsfensters angegeben. (0 oder 1).

Regs ist eine Variable vom Typ Registers

Regs.AH := $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL := $05;			{ VESA Funktion 05h		}
Regs.BH  := $00;			{ Unterfunktion 0		}
Regs.BL  := $00;			{ Speicherfenster 0		}
Regs.DX := $FF;			{ um 256 kBytes verschieben	}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Funktion 06h						                     Länge der Punktzeile lesen/setzten

Diese Funktion dient zum lesen/setzten der Länge der Punktzeile  im Speicher (nicht der dargestellten Länge der Zeile). Um den aktuellen Wert zu bekommen, muss BL auf 01h gesetzt werden, um einen neuen Wert zu setzten, muss BL auf 00h gesetzt werden. Bei BL = 00h muss in CX die gewünschte, neue Länge in Pixeln angegeben werden. Zurückgeliefert wird in beiden Fällen die Länge der Zeile in CX, die Anzahl der im Speicher benötigten Bytes in BX und die maximale Anzahl von Zeilen im Speicher in DX

Regs ist eine Variable vom Typ Registers

Regs.AH 	:= $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL 	:= $06;			{ VESA Funktion 06h		}
Regs.BL  	:= $00;			{ Unterfunktion 0 (Länge setzten)  }
Regs.CX  	:= $280;			{ Zeilenlänge : 640 Pixel		}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Funktion 07h					           Beginn des sichtbaren Bereichs setzten/ermitteln

Mit Hilfe dieser Funktion wird bestimmt, ab welcher Speicherposition die gespeicherten Daten auf dem Bildschirm ausgegeben werden. Mit BX=0 wird ein neuer Wert gesetzt, mit BX=01h wird der aktuelle Wert ermittelt. Bei BX=00h muss in CX die Spalte, und in DX die Zeile übergeben werden, ab der die Daten sichtbar werden sollen. Bei BX=01h wird die aktuelle Spalte in CX, die aktuelle Zeile in DX zurückgeliefert.

Regs ist eine Variable vom Typ Registers

Regs.AH 	:= $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL 	:= $07;			{ VESA Funktion 07h		}
Regs.BX  	:= $00;			{ Unterfunktion 0 		}
Regs.CX  	:= $64;			{ Spalte : 100 Pixel		}
Regs.DX 	:= $32;			{ Zeile : 50 Pixel			}
Intr($10, Regs);			{ Grafikinterrupt 10h		}

Funktion 08h 						                Farbtiefe der Palette setzen/ermitteln

Diese Funktion ist für das ändern der Farbtiefe in der Farbpalette zuständig. Mit BL=00h wird ein neuer Wert gesetzt, mit BL=01h wird der aktuelle Wert eingelesen. Bei BL=00h muss in BH die Anzahl der Bits übergeben werden. Bei BL=01h wird in BH die aktuelle Anzahl der Bits zurückgeliefert.

Regs ist eine Variable vom Typ Registers
AnzBits ist eine Variable vom Typ Byte

Regs.AH 	:= $4F;			{ Aufruf der VESA Funktionen 	}
Regs.AL 	:= $08;			{ VESA Funktion 08h		}
Regs.BL  	:= $01;			{ Unterfunktion 1		}
Intr($10, Regs);			{ Grafikinterrupt 10h		}
AnzBits 	:= Regs.BH;		{ Aktuelle Anzahl Bits lesen	}

Copyright ©1997 by Christian Link