^1 ij ^1 Fonts zum Zweiten... ^1 by The Real Adok ^1 Tja, da haben LeidPen und ich wohl dieselbe Idee gehabt. Ich mchte euch in diesem Artikel aber vor allem das Auslesen der ROM-Fonts in C erklren. Das Ganze funktioniert ber eine Unterfunktion der Funktion 11h des Interrupts 10h. Leider ist diese Funktion nicht sehr gut dokumentiert, und sowohl im MicroCode als auch im PC-Intern ist sie FALSCH beschrieben! Es handelt sich um Ufo 30h. Mit ihr kann man u.a. die Zeichenstze aus dem ROM in ein Speichersegment laden. Von dort kann man dann den Zeichensatz auslesen und darstellen. Dabei mu als Parameter im BH-Register die Nummer des gewnschten Zeichensatzes bergeben werden. Es gibt Zeichenstze mit einer Hhe von 8, 14 oder 16 Punkten (Bytes). Der 8-Pnktchen-Satz hat die Nummer 3, 14 Punkte 2 und 16 Punkte 6. Letzterer bentigt jedoch eine VGA-Karte... aber die hat doch jeder, oder!? Also: ^0 MOV AX,1130h ^0 MOV BX,300h ; oder 200h fr 14 Punkte, 600h fr 16 Punkte ^0 INT 10h Damit wird der gewnschte ROM-Zeichensatz an eine Speicherstelle geladen, deren Segment in ES und Offset in BP zurckgegeben wird! Nun kann man den Zeichensatz auslesen, anzeigen, sich damit herumspielen und so weiter, wie man will! Das Ganze funktioniert so hnlich wie mit EGA.CPI: den ASCII-Code des Zeichens, das man auslesen will, mit der Zeichensatzgre (also 8, 14 oder 16) multiplizieren und den Anfangsoffset (das, was in BP zurckgegeben wird) dazu- addieren. Nun ist man beim Offset des Zeichens. Die nchsten 8/14/16 Bytes enthalten dann 'verschlsselt' die Matrix des Zeichens. Und zwar so, wie es dieses Beispiel zeigt... [scroll down] ^3 Ŀ ^3 Byte (Zeile) Bits in diesem Byte das Ganze ergibt ^3 ^3 1 11111110 ^3 2 11000110 ^3 3 00001100 ^3 4 00011000 ^3 5 00110010 ^3 6 01100110 ^3 7 11111110 ^3 8 00000000 ^3 Wenn man eine hardwarenahe Textausgaberoutine programmieren will, dann mu man also blo jedes Byte Bit fr Bit auslesen und einfach die Pixels setzen! Baby- leicht, stimmt's? :-) Genau das macht das C-Beispielprogramm am Ende dieses Artikels, mit dem ihr schn herumexperimentieren drft, denn es ist PD! Vorher mchte ich jedoch noch die anderen Mglichkeiten vorstellen, die der Interrupt 10h Fkt. 11h Ufo 30h zur Verfgung stellt. Ihr knnt BH auch mit folgenden Werten laden... - 0: Gibt in ES und BP Segment und Offset des Interrupts 1Fh zurck. - 1: Gibt in ES und BP Segment und Offset des Interrupts 43h zurck. - 4: ...der zweiten Hlfte des 8-Punkte Zeichensatzes... (nur VGA!) - 5: ...des 9x14-Zeichensatzes... (nur VGA!) - 7: ...des 9x16-Zeichensatzes... (nur VGA!) Auerdem werden in CX die Hhe der aktuellen Zeichenmatrix und in DL die Anzahl der Zeilen des Bildschirms minus eins zurckgegeben. Zu den Zeichenstzen 9x14- und 9x16-Zeichensatz sei gesagt: Ursprnglich wollten die Entwickler der VGA-Karte zwei Zeichenstze erstellen, die eine Breite von neun Punkten haben. Das wren aber neun Bits pro Zeile, und bekanntlich passen nur acht Bits in ein Byte. Somit hat man einfach gesagt: "Wir speichern ins VGA-ROM nur die ersten acht Bits pro Zeile. Das neunte Bit sollen sich einfach die Textausgaberoutinen selbst machen, indem sie einfach das achte Bit nocheinmal ausgeben." Das bedeutet schlicht und einfach, da die 9er-Zeichenstze im ROM mit den normalen Zeichenstzen identisch sind. Dies hat wenigstens den Vorteil, da man eine Sicherheitskopie in den Hnden hat, falls man mal einen eigenen Zeichensatz verwendet und dabei einen anderen Zeichensatz berschreibt. Nun mchte ich euch das Beispielprogramm nicht lnger vorenthalten! Hier eine Beschreibung der verwendeten Funktionen: 9- char13h: Eine "Komfortfunktion", die einen Text im Bildschirmmodus 13h in 9 viiiielen Varianten ausg[i/e]b[t/en sollte]. Als Parameter kommt zuerst mal 9 der Buchstabe oder sein ASCII-Code, dann der verwendete 8/14/16-Font, 9 Farbcode, X-Position, Y-Position (hier ist, im Gegensatz zu Standardroutys 9 wie printf oder Basic's PRINT jeder beliebige Pixel mglich!), Hhe 9 (1 = normal, 2 = etwas zusammengequetscht, 3 = noch mehr zusammengequetscht, 9 10000000=...), Breite (siehe oben und links, im Klartext: wie Hhe), Segment 9 und Offset des Zeichensatzes. Wird von text13h verwendet. Bentigt pset13h. 9- pset13h: Einen Punkt im Bildschirmmodus 13h mit den Koordinaten x und y in 9 der Farbe col setzen. Wird von char13h verwendet. 9- screen: Schaltet in den angegebenen Bildschirmmodus um. 9- text13h: Gibt einen ganzen String aus! Restliche Parameter wie char13h, das 9 von dieser Funktion verwendet wird und wiederum pset13h bentigt. Den 9 logischen letzten Satz, "bentigt char13h", kann ich mir also sparen (uff). Wichtig: Mit all dem lt sich der Zeichensatz nur auslesen, jedoch nicht neu definieren, also durch einen eigenen ersetzen. Wie man einen eigenen Zeichen- satz definiert, kann ich euch bei Interesse im nchsten Hugi zeigen. Nun also das Listing. Jeder kann damit experimentieren und versuchen, es auszubauen. Falls ihr eure Lsungen interessant findet, schickt sie an den Hugi! Das Proggy bekommt dann eine neue Versionsnummer und wird verffent- licht. Also, ihr habt die Chance, weltberhmt zu werden! ^4 Euer The Real Adok. ^2______________________________________________________________________________ ^0// DEMAGOG V1.1 ist PD (w) by The Real Adok ^0void char13h(unsigned int letter,unsigned char font,unsigned char col, ^0 unsigned int xpos,unsigned char ypos, ^0 unsigned char height,unsigned char width, ^0 unsigned int zseg,unsigned int zoff); ^0void pset13h(int x,int y,int col); ^0void screen (unsigned char nr); ^0void text13h(unsigned char text[],unsigned char font,unsigned char col, ^0 unsigned int xpos,unsigned char ypos, ^0 unsigned char height,unsigned char width, ^0 unsigned int zseg,unsigned int zoff); ^0// Ausgabe eines Zeichens ^0void char13h(unsigned int letter,unsigned char font,unsigned char col, ^0 unsigned int xpos,unsigned char ypos, ^0 unsigned char height,unsigned char width, ^0 unsigned int zseg,unsigned int zoff) ^0{ ^0 unsigned char temp,i; ^0 unsigned int y; ^0 letter=letter*font; ^0 for(y=0;y