Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Scorpion am 06. March 2005, 18:08
-
Hi Leute,
ich habe mir das super Tutorial über den VGA-Modus durchgelesen und bin begeistert. Ich kann jetzt in den Vesa-Mode schalten, sowohl in Windows als auch in meinem (ASM-)Kernel. Leider bleiben noch folgende Fragen offen:
- wie kann ich einzelne Pixel "anmalen"
- wie schreibe ich Text?
- wie portiere ich folgenden (nach dem Vesa-Tutorail erstellten) Asm-Code in C / C++?
VbeInfoBlock:
VbeSignature db 'VBE2' ; 4 Bytes
VbeVersion db 0, 0
VbeOEMStringPtr db 0, 0, 0, 0
VbeCapabilities db 0, 0, 0, 0
VbeVideoModePtr db 0, 0, 0, 0
VbeTotalMemory db 0, 0
VbeOEMSoftwareRev db 0, 0
VbeOEMVendorNamePtr db 0, 0, 0, 0
VbeOEMProductNamePtr db 0, 0, 0, 0
VbeOEMProductRevPtr db 0, 0, 0, 0
VbeReserved times 222 db 0
VbeOEMData times 256 db 0
VbeModeInfoBlock:
VbeModeModeAttributes db 0, 0
VbeModeWinAAttributes db 0
VbeModeWinBAttributes db 0
VbeModeWinGranularity db 0, 0
VbeModeWinSize db 0, 0
VbeModeWinASegment db 0, 0
VbeModeWinBSegment db 0, 0
VbeModeWinFuncPtr db 0, 0, 0, 0
VbeModeBytesPerScanLine db 0, 0
VbeModeXResolution db 0, 0
VbeModeYResolution db 0, 0
VbeModeXCharSize db 0
VbeModeYCharSize db 0
VbeModeNumberOfPlanes db 0
VbeModeBitsPerPixel db 0
VbeModeNumberOfBanks db 0
VbeModeMemoryModel db 0
VbeModeBankSize db 0
VbeModeNumberOfImagePages db 0
VbeModeReserved_page db 0
VbeModeRedMaskSize db 0
VbeModeRedMaskPos db 0
VbeModeGreenMaskSize db 0
VbeModeGreenMaskPos db 0
VbeModeBlueMaskSize db 0
VbeModeBlueMaskPos db 0
VbeModeReservedMaskSize db 0
VbeModeReservedMaskPos db 0
VbeModeDirectColorModeInfo db 0
VbeModePhysBasePtr db 0, 0, 0, 0
VbeModeOffScreenMemOffset db 0, 0, 0, 0
VbeModeOffScreenMemSize db 0, 0
VbeModeLinBytesPerScanLine db 0, 0
VbeModeBnkNumberOfPages db 0
VbeModeLinNumberOfPages db 0
VbeModeLinRedMaskSize db 0
VbeModeLinRedFieldPos db 0
VbeModeLinGreenMaskSize db 0
VbeModeLinGreenFieldPos db 0
VbeModeLinBlueMaskSize db 0
VbeModeLinBlueFieldPos db 0
VbeModeLinRsvdMaskSize db 0
VbeModeLinRsvdFieldPos db 0
VbeModeMaxPixelClock db 0, 0, 0, 0
VbeModeReserved db 0 times 190 db 0
mov ax, 0x4F00
mov di, VbeInfoBlock
int 0x10
mov ax, 0x4F01
mov di, VbeModeInfoBlock
mov cx, 0x4105
and cx, 0xFFF
int 0x10
mov ax, 0x4F02
mov bx, 0x4101
int 0x10
mov edi, [VbeModePhysBasePtr]
mov ecx, 640 * 480
mov eax, 0xCC
rep stosd
Danke im Voraus.
MfG, Scorpion!
-
hi,
um einzelne Pixel "anzumalen" musst du den LFB (Linear Frame Buffer) benutzen !
die Startadresse vom LFB steht in VbeModePhysBasePtr !
Bei 8-Bit Frabtiefe ist jeder Pixel 1 Byte lang (bei 16-Bit ist er 2 Byte,...)
Adresse: Pixelposition (von rechts oben aus gesehen)
[VbeModePhysBasePtr] = X: 0 Y: 0
[VbeModePhysBasePtr]+1 = X: 1 Y: 0
... usw ...
[VbeModePhysBasePtr]+640 = X: 0 Y: 1
...
Text kannst du nicht direkt draufzeichnen ! du musst die Pixel halt so zeichnen! normalerweise wird das über Fonts gemacht !
cu,
stefan2005
-
hätte dazu jemand mal ein beispiel, denn ich blick da leider kaum durch!
MfG, Scorpion!
-
die formeln lauten so:
ZielAdresse = PhysBasePtr + ((X + Y*PixelProZeile)*BitsPerPixel)/8
so, und das formst du nun entweder in C mit den passenden variablen um, oder aber du baust dir den dazu passenden ASM-Code. dann musste nurnoch an die adresse in ZielAdresse den Farbwert schreiben und schon is der Punkt angemalt. davor kannst/musste noch checken, ob der ausgewählte bereich inerhalb des anzeigebereichs is, sonst könnte jemand das ausnutzen (bufferoverflow!). und darauf kannste dann das zeichensetzen bauen, da brauchste ne font, die dir zeigt, weile pixel für z.B. ein A gesetzt werden müssen und eine passende routine, die die einzellnen werte abtastet und die punkte setzt, wenns angegeben is.
mfg
J!N
-
ich dachte links oben sei x: 0 y: 0...?
@scorpion:
ich mach das so. ich schreibe die beiden blöcke (VbeModeInfo... ) linear an irgend eine unbenutzte adresse und schalte in den modues. später im pm und in c greife ich so drauf zu:
unsigned long *VbeModeInfoBlock = (unsigned long *) 0x7e00;
unsigned char *VideoMem;
unsigned long ScrWidth, ScrHeight;
unsigned long BGColor = 0x02A8C6;
void SetupVideo()
{
ScrWidth = VbeModeInfoBlock[4] & 0xFFFF; //extract high word from double
ScrHeight= VbeModeInfoBlock[4] >> 0xF; //extract low word from double
VideoMem = (unsigned char *)(VbeModeInfoBlock[10]);
ClearScreen();
};
void ClearScreen ()
{
unsigned char BGR = (BGColor & 0xFF0000) >> 16;
unsigned char BGG = (BGColor & 0x00FF00) >> 8;
unsigned char BGB = (BGColor & 0x0000FF);
unsigned long i = 2;
for (;i < (ScrWidth * ScrHeight)*3; i++)
{
VideoMem[i] = BGR;
i++;
VideoMem[i] = BGG;
i++;
VideoMem[i] = BGB;
};
};
leider stimmt aber die farbe nicht mit der überein die ich eigendlich beabsichtigt habe...
aber villeicht hilft dir das was..
-
dein problem ist, dass du nicht auf die anzahl der bits per pixel achtest, zacK!
ich inite das zeug im bootloader, dazu check ich die modi 0x118 und 0x115 mit LFB und setze erstgenannten, falls es geht, sonst den 2. und wenn der net geht keinen. die werte übergebe ich meinem kernel, der berechnet daraus die passenden werte (maxX, maxY, LFBSize) und speichert die. und beim zeichenen checkt die routine dann auf maxX usw und auf bitsperpixel und setzt dann entsprechend die werte. und es geht :) alles in asm gemacht.
-
ich kapiere das nicht ganz. eigendlich schalte ich in den 1024*768*32. aber die farben muss ich anscheinend gleich ich 24 bit speichern... :(
bei meinem echten pc komt viollet heraus. und bei bochs ist es ein grün. eigendlich wollte ich ein helles blau... :(
-
eben. bochs benutzt 24bit pro pixel, was man auch braucht. real benutzt oft (aber leider nicht immer, sondern eher 50:50) 32bit, weil schnellerer speicherzugriff durch 1 dword als durch 1 word + 1 byte erfolgt. deshalb musst du das mit einbeziehen, also wenn du 24bit hast das X+Y*PixelProZeile nur mal 3, bei 32bit mal 4 multiplizieren, um an die adresse zu kommen...
-
In der Regeln reichen auch 16 Bit aus, da duerftest du die Sorgen nicht haben, vermute ich mal.
16 Bit ist schon sehr viel, damit ist auch Fotobearbeitung gut möglich. 32 Bit ist bei manchen Treibern, die direkt arbeiten, schon ein Geschwindigkeitsverlust... hab ich gehört (kann es selbst nicht beurteilen; messen muesstet ihr selbst)
Mvh Svenska
-
16Bit ist aber wieder komplizierter zu zerlegen, bei 32/24 kann man einfach die Bytes nehmen, bei 16 müsste man etwas komplizierter mit shift & and arbeiten wenn man die einzelnen Farben extrahieren will. Naja aber so wirklich viel ist 16 Bit nich, "nur" 65k Farben im Gegensatz zu 16Millionen, das macht schon einen Unterschied, nur ist dummerweise das menschliche Auge zu dumm den zu bemerken^^
-
Also ... hab Praktikerfahrung gleich null. Aber sind 16 Bit nicht gleich 2 Byte? Duerfte doch theoretisch ganz einfach sein, da ran zu kommen, Wert nach EAX und AX auslesen.
Mir gefällt immernoch die Angabe von 48 Bit Farbtiefe bei Scannern, weil das ist definitiv ueber dem Vermögen des Auges. Ich glaube, das Auge schafft nur 12-16 Bit und bei begabten Leuten sinds dann schonmal 20 Bit ... oder?
Ich fände es glaube ich einfacher, 16 Bit zu schreiben anstatt immer zu ueberlegen "nehm ich jetzt 24 oder 32 Bit?" ... aber wie gesagt, bei mir läuft eh noch nix. Ich schaffe es nichteinmal, ein Stringvariable in C in eine andere zu kopieren... :(
-
Also ... hab Praktikerfahrung gleich null. Aber sind 16 Bit nicht gleich 2 Byte? Duerfte doch theoretisch ganz einfach sein, da ran zu kommen, Wert nach EAX und AX auslesen.
Mir gefällt immernoch die Angabe von 48 Bit Farbtiefe bei Scannern, weil das ist definitiv ueber dem Vermögen des Auges. Ich glaube, das Auge schafft nur 12-16 Bit und bei begabten Leuten sinds dann schonmal 20 Bit ... oder?
Ich fände es glaube ich einfacher, 16 Bit zu schreiben anstatt immer zu ueberlegen "nehm ich jetzt 24 oder 32 Bit?" ... aber wie gesagt, bei mir läuft eh noch nix. Ich schaffe es nichteinmal, ein Stringvariable in C in eine andere zu kopieren... :(
ja, aber diese 3 farbwerte (RGB) in 16 bits zu bekommen is schwer, weil das net aufgeht. (16%3!=0) deswegen muss man das dann zerlegen. während bei 32 oder 24bit ist das einfach nur 1 byte für jedes (24bit) oder aber 1 nullbyte und dann die RGBs...
-
ich habe da auch ein problem....
mein vesa treiber spuckt die falschen farben aus...
aus 0x123456 gibt bochs die farbe 0x005634 aus...
und mein real-pc gibt wieder andere farben aus...
ausserdem fehlt beim echten pc in der mitte ein grosser streiffen der einfach schwarz ist... bochs färb alles ein...
hat das problem schon jemand gehabt?
-
ja, ich. du scheinst einen zahlendreher zu haben. wie ich dir in meiner email schon geschrieben habe, rate ich dir, einfach mal ein bisschen mit der reihenfolge auszuprobieren. und was den echten PC angeht: der wird wohl 32bit haben und deine routine hat nen fehler, dass sie da net geht, ich denke da an den zahlendreher.
-
ne, auch wenn ich die zahlen fest einschreiben also gleich
VideoMem[pos_für_rot] = 0x20 // angenommen VideoMem ist unsigned char *
auch dann ist rot 0x00... :(
und wenn ich die zahlen für die farbe ändere dann ändert sich das bild so wie ich es möchte in bochs, aber im realpc nicht...
-
hier mein code:
/*
;
;---------------------------------------------------------------+
; .__ __ ¦
;______ |__|___________ _/ |_ ____ ______ ¦
;\____ \| \_ __ \__ \\ __\ ______ / _ \/ ___/ ¦
;| |_> > || | \// __ \| | /_____/ ( <_> )___ \ ¦
;| __/|__||__| (____ /__| \____/____ > ¦
;|__| \/ \/ ¦
;---------------------------------------------------------------+
;
;[1] Informations
;
; Last Modified: 25. Januar 2005
; Begin: 15. Juni 2004
; Version: 0.000
; Coder: z4ck
;
;
;[2] Tasks
;
; Task Done Coder
;----------------------------------------------------------------
; - [ 0%] z4ck
;----------------------------------------------------------------
; TOTAL [ 0%] z4ck
;================================================================
*/
#include <video.h>
#define VesaMode 0x118
unsigned long *VbeModeInfoBlock = (unsigned long *) 0x7e00; // This one ist set in kernel16.asm @ setvesa...
unsigned char *VideoMem; // saved in the VbeModeInfoBlock
/********************************************/
/* Screen Settings */
/********************************************/
unsigned long ScrWidth, ScrHeight;
unsigned char BitsPerPixel;
/********************************************/
/* COLORS */
/********************************************/
unsigned long BGColor = 0x0011A8C6;
unsigned long FontColor = 0x00FFFFFF;
unsigned long FontShadowColor = 0x00EEEEEE;
/********************************************/
/********************************************/
/* Init the video */
/********************************************/
void SetupVideo()
{
ScrWidth = VbeModeInfoBlock[4] & 0xFFFF; //extract high word from double
ScrHeight = VbeModeInfoBlock[4] >> 0x10; //extract low word from double
BitsPerPixel = (VbeModeInfoBlock[6] & 0xFF00) >> 0x8;
VideoMem = (unsigned char *)(VbeModeInfoBlock[10]);
ClearScreen(); //Result: Color 0x00c6a8
DrawPixel(0, 0, 0x202020); //Result: Color 0x002020
VideoMem[(1*BitsPerPixel/8)]=0x11; //Result: COlor 0xc6a811
VideoMem[(1*BitsPerPixel/8)+1]=0xA8;
VideoMem[(1*BitsPerPixel/8)+2]=0xc6;
};
/********************************************/
/* Clear Screen whit BGColor */
/********************************************/
void ClearScreen ()
{
unsigned long i = 0;
for (;i < ScrHeight; i++)
{
unsigned long u = 0;
for (; u < ScrWidth; u++)
DrawPixel(u, i, BGColor);
};
};
void printf (char *_string, long _color)
{
};
void printc (char _character, long _color)
{
};
void Num2String(int _number)
{
};
/********************************************/
/* Draw a Pixel */
/********************************************/
void DrawPixel (unsigned long _x, unsigned long _y, unsigned long _RGB)
{
unsigned char A = _RGB >> 0x18; //Alpha
unsigned char R = (_RGB & 0x00FF0000) >> 0x10; //Red
unsigned char G = (_RGB & 0x0000FF00) >> 0x08; //Green
unsigned char B = (_RGB & 0x000000FF); //Blue
unsigned long pos = ((_y*ScrWidth)+_x)*(BitsPerPixel/8);
if (pos > (ScrWidth*ScrHeight*BitsPerPixel/8)) return;
switch(BitsPerPixel)
{
case 8:
case 16:
break;
case 24:
VideoMem[pos] = R;
VideoMem[pos++] = G;
VideoMem[pos++] = B;
break;
case 32:
VideoMem[pos] = A;
VideoMem[pos++] = R;
VideoMem[pos++] = G;
VideoMem[pos++] = B;
break;
};
};
/*
void DrawBMP (File *_file, int _x, int _y)
{
};
*/
-
danke, das hilft mir schon mehr weiter!
MfG, Scorpion!
-
@zacK: eben, das meine ich. vll. stimmt die position nicht richtig, oder aber C und soweiter bekommt was mit fett und schmalspur endian nicht gebacken oder so. ändere einfach mal die reihenfolge ein bisschen und schau, wann das richtige byte an der richigen stelle ist. dann ändere die anderen noch und fertig... (und ergebniss bitte posten, interessiert mich, warums net ging!)
-
wenn ich die position verändere, dann stimmt es vll in bochs, aber beim echten pc nicht mehr. ausser dem bleibt der rot-anteil immer auf 0x00 ausser ich schreibe es mit :
VideoMem[(1*BitsPerPixel/8)]=0x11;
also habe ich da noch ein bug...
:(
könnte es sein das die position der einzelnen farbwerte im ram irgendwie noch z.B von VbeModeLinRedFieldPos abhängt (sprich irgend einem eintrag im VbeModeInfoBlock)?
-
ja, aber es ist zu 99,999 % standardisiert (RGB oder ARGB), deswegen beachte ich das nichtmehr...
-
ja, aber es ist zu 99,999 % standardisiert (RGB oder ARGB), deswegen beachte ich das nichtmehr...
warum sagst du mir dann ich soll es ändern wenn es zu 99.999% so ist ?! :wink:
dann wird bochs wahrscheindlich das nicht anders haben (also das vga bios)
welches vgabios benutzt du?
könnte es auch sein das zb. alle rotwerte an 0xSoundso kommen und alle grünwerte 0xSoundso+1024 und alle blau werte an 0xSoundso+2048. also alle farben getrennt... (als beispiel)?
-
1. ich sage net, du sollst es ändern, weil es zu 0,001 % anderst sein kann, sondern, wegen Big und sonstwas Endian.
2. Ich benutz "VGABIOS-elpin-2.40"...
3. nein, so ist es nicht, nur die anordnung in den 24bits oder 32bits könnte anderst sein.
4. geh mal bei ICQ on, da kann man besser schreiben :D
J!N
-
was ist den big oder endian... sorry no plan...
ich habe mal das VGABIOS-elpin-2.40 getestet, und da sagt mein kernel "Vesa 2.0 not supportetd"
vielleicht hab ich da ein fehler beim setzen vom vesa modus.
hier ma der code:
;===============================================================
;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;--------------------Set Vesa-----------------------------------
SetVesaMode:
.0:
pusha
push es
mov ax, 0x7c0 ; Vesa Info Block @ 0x7c00
mov es, ax
xor di, di
mov DWORD [es:di], 'VBE2'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Test if Vesa 2 is supported;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.1:
mov ax, 0x4F00 ; Get Vesa Informations
mov di, 0
int 0x10
cmp ax,0x004F ; ah: 00 -> Successfuly al: 01 -> Function supported
je .2 ;
mov si, msg_VesaErrVer ;
call VesaError
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Get Mode Info;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.2:
mov ax, 0x4F01
mov cx, 0x118
mov bx, 0x7e0 ; Vesa Mode Info Block @ 0x7e00
mov es, bx
mov di, 0
int 0x10
cmp ax,0x004F
je .3
mov si, msg_VesaErrInfo
call VesaError
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Enable Vesa Mode;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.3:
mov ax, 0x4F02
mov bx, 0x4118
int 0x10
cmp ax,0x004F
je .4
mov si, msg_VesaErrSet
call VesaError
.4:
pop es
popa
ret
;===============================================================
;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
;--------------------Set Vesa-----------------------------------
VesaError:
.0:
call PrintString
cli
hlt
-
big und little endian sind die formate, wie der computer bytes im speicher vertauscht, wenn er z.B. ein dword oder ein word ablegt. der legt die net fein normal ab, sondern vermischt die:
word besteht aus 2 bytes, 1 und 2:
das normalerweise so aufgebaute word: 12 wird zu dem hier (soweit ich weiß): 21
und bei dwords ist es ja normalerweise 1234, das wird aber zu 4321 oder so gemacht... nicht gerade logisch, ka, wer sich das ausgedacht hat und wozu. und das musste eben beachten, wenn du mit bytes statt words oder dwords arbeitest, also mit nem anderen datentyp ließt als geschrieben hast.
-
ah so, nun versteh ich das. z.b schreibt ich byteweise 0x11 0x22 0x33, das in einem dword so aussehen würde 0x00112233 und dann nimmt bochs z.b 0x001122 weil er dachte das ich das dword im 1234 format abgespeichert habe (als beispiel)...
was meinst du zu meinem vga-bios problem?
-
nein, ich meine, wenn du ein dword (0x11223344) in den ram schreibst mit stosd und dann in bytes ausließt bekommste 0x44, 0x33, 0x22 und 0x11...
EDIT: und wenn du dann ein byte schreibst, und bochs das in dwords ausließt, bzw das vga-bios, dann werden die verkehrt...
-
ja schon aber ich schreibe es byte für byte ein und und wie es bochs oder was auch immer dann ausliesst weis ich nicht...
-
Wenn wir schon einen aktiven VESA-Thread haben, erlaube ich mir zu fragen, wie man im PM in die verschiedenen VGA/VESA/XGA-Modi schalten kann. Ich möchte nicht auf eine einmalige Grafikmoduswahl noch im RM beschränkt sein.
-
es gibt da verschiedene möglichkeiten (aber net sehr viele):
1. Vesa 3.0
2. Zurück zum RM und Int
3. V68
gibt glaube ich noch mehr, hab die aber vergessen ^^
-
Wie schafft es dann das BIOS?
Ist das ein riesiges Verfahren, das nicht neugeschrieben werden kann? Gibt es da für jede Graka unterschiedliche Initialisierungsverfahren für VGA?
-
@elfish_rider: k.A. frag joachim_neu ^^
@all:
ich habe nun mein treiber soweit, dass ich rechtecke malen kann etc. sogar mit den richtigen farben ^^
hier meine video.c:
/*
;
;---------------------------------------------------------------+
; .__ __ ¦
;______ |__|___________ _/ |_ ____ ______ ¦
;\____ \| \_ __ \__ \\ __\ ______ / _ \/ ___/ ¦
;| |_> > || | \// __ \| | /_____/ ( <_> )___ \ ¦
;| __/|__||__| (____ /__| \____/____ > ¦
;|__| \/ \/ ¦
;---------------------------------------------------------------+
;
;[1] Informations
;
; Last Modified: 25. Januar 2005
; Begin: 15. Juni 2004
; Version: 0.000
; Coder: z4ck
;
;
;[2] Tasks
;
; Task Done Coder
;----------------------------------------------------------------
; - [ 0%] z4ck
;----------------------------------------------------------------
; TOTAL [ 0%] z4ck
;================================================================
*/
#include <video.h>
#define VesaMode 0x118
/********************************************/
/* VbeModeInfoBlock Struktur */
/********************************************/
typedef struct {
unsigned short VbeModeModeAttributes;
unsigned char VbeModeWinAAttributes;
unsigned char VbeModeWinBAttributes;
unsigned short VbeModeWinGranularity;
unsigned short VbeModeWinSize;
unsigned short VbeModeWinASegment;
unsigned short VbeModeWinBSegment;
unsigned long VbeModeWinFuncPtr;
unsigned short VbeModeBytesPerScanLine;
unsigned short VbeModeXResolution;
unsigned short VbeModeYResolution;
unsigned char VbeModeXCharSize;
unsigned char VbeModeYCharSize;
unsigned char VbeModeNumberOfPlanes;
unsigned char VbeModeBitsPerPixel;
unsigned char VbeModeNumberOfBanks;
unsigned char VbeModeMemoryModel;
unsigned char VbeModeBankSize;
unsigned char VbeModeNumberOfImagePages;
unsigned char VbeModeReserved_page;
unsigned char VbeModeRedMaskSize;
unsigned char VbeModeRedMaskPos;
unsigned char VbeModeGreenMaskSize;
unsigned char VbeModeGreenMaskPos;
unsigned char VbeModeBlueMaskSize;
unsigned char VbeModeBlueMaskPos;
unsigned char VbeModeReservedMaskSize;
unsigned char VbeModeReservedMaskPos;
unsigned char VbeModeDirectColorModeInfo;
unsigned long VbeModePhysBasePtr;
unsigned long VbeModeOffScreenMemOffset;
unsigned short VbeModeOffScreenMemSize;
unsigned short VbeModeLinBytesPerScanLine;
unsigned char VbeModeBnkNumberOfPages;
unsigned char VbeModeLinNumberOfPages;
unsigned char VbeModeLinRedMaskSize;
unsigned char VbeModeLinRedFieldPos;
unsigned char VbeModeLinGreenMaskSize;
unsigned char VbeModeLinGreenFieldPos;
unsigned char VbeModeLinBlueMaskSize;
unsigned char VbeModeLinBlueFieldPos;
unsigned char VbeModeLinRsvdMaskSize;
unsigned char VbeModeLinRsvdFieldPos;
unsigned char VbeModeMaxPixelClock;
unsigned char VbeModeReserved[190];
} __attribute__ ((packed)) VbeModeInfoBlock;
/********************************************/
/* Global Vars */
/********************************************/
VbeModeInfoBlock *VbeMIB = (VbeModeInfoBlock *) 0x7e00; // This one ist set in kernel16.asm @ setvesa...
unsigned char *VideoMem; // saved in the VbeModeInfoBlock
/********************************************/
/* Screen Settings */
/********************************************/
unsigned long ScrWidth, ScrHeight;
unsigned char BitsPerPixel;
/********************************************/
/* COLORS */
/********************************************/
unsigned long BGColor = 0x0011A8C6;
unsigned long FontColor = 0x00FFFFFF;
unsigned long FontShadowColor = 0x00EEEEEE;
/********************************************/
/* Init the video */
/********************************************/
void SetupVideo()
{
ScrWidth = VbeMIB->VbeModeXResolution;
ScrHeight = VbeMIB->VbeModeYResolution;
BitsPerPixel = VbeMIB->VbeModeBitsPerPixel;
VideoMem = (unsigned char *)(VbeMIB->VbeModePhysBasePtr);
ClearScreen();
DrawRectangle(50, 50, 500, 300, 0x00FFFFFF, 0x00000000);
DrawRectangle(100, 100, 300, 500, 0x00FFFFFF, 0x00000000);
};
/********************************************/
/* Clear Screen whit BGColor */
/********************************************/
void ClearScreen ()
{
unsigned long i = 0;
for (;i < ScrHeight; i++)
{
unsigned long u = 0;
for (; u < ScrWidth; u++)
DrawPixel(u, i, BGColor);
};
};
void printf (char *_string, long _color)
{
};
void printc (char _character, long _color)
{
};
void Num2String(int _number)
{
};
/********************************************/
/* Draw a Pixel */
/********************************************/
void DrawPixel (unsigned long _x, unsigned long _y, unsigned long _RGB)
{
unsigned char A = _RGB >> 0x18; //Alpha
unsigned char R = (_RGB & 0x00FF0000) >> 0x10; //Red
unsigned char G = (_RGB & 0x0000FF00) >> 0x08; //Green
unsigned char B = (_RGB & 0x000000FF); //Blue
unsigned long pos = ((_y*ScrWidth)+_x)*(BitsPerPixel/8);
if (pos > (ScrWidth*ScrHeight*BitsPerPixel/8)) return;
switch(BitsPerPixel)
{
case 8:
case 16:
break;
case 24:
VideoMem[pos] = B;
VideoMem[++pos] = G;
VideoMem[++pos] = R;
break;
case 32:
VideoMem[pos] = A;
VideoMem[++pos] = B;
VideoMem[++pos] = G;
VideoMem[++pos] = R;
break;
};
};
void DrawLine (unsigned long _x1, unsigned long _y1, unsigned long _x2, unsigned long _y2, unsigned long _RGB)
{
unsigned long tmpWidth = (_x2 > _x1)?(_x2 - _x1):(_x1 - _x2);
unsigned long tmpHeight = (_y2 > _y1)?(_y2 - _y1):(_y1 - _y2);
unsigned long i = 0;
if (tmpHeight == 0)
{
for (;i<=tmpWidth; i++)
{
DrawPixel(_x1+i, _y1, _RGB);
}
return;
}
if (tmpWidth == 0)
{
for (;i<=tmpHeight; i++)
{
DrawPixel(_x1, _y1+i, _RGB);
}
return;
}
};
void DrawRectangle (unsigned long _x1, unsigned long _y1, unsigned long _x2, unsigned long _y2, unsigned long _LineRGB, unsigned long _FillRGB)
{
DrawLine(_x1, _y1, _x2, _y1, _LineRGB); //left to right; up
DrawLine(_x1, _y2, _x2, _y2, _LineRGB); //left to right; down
DrawLine(_x1, _y1, _x1, _y2, _LineRGB); //up to down; left
DrawLine(_x2, _y1, _x2, _y2, _LineRGB); //up to down; right
unsigned tmpHeight = _y2-_y1;
unsigned tmpWidth = _x2-_x1;
unsigned i = 1, u = 1;
for (;i < tmpHeight; i++)
{
for (u = 1; u < tmpWidth; u++)
{
DrawPixel (_x1+u, _y1+i, _FillRGB);
}
}
};
hoffe es hilft jemandem...
-
Wie schafft es dann das BIOS?
Ist das ein riesiges Verfahren, das nicht neugeschrieben werden kann? Gibt es da für jede Graka unterschiedliche Initialisierungsverfahren für VGA?
Wenn du es schaffst, an die technischen Daten aller Grafikkarten ranzukommen, duerftest du auch Treiber dafuer schreiben können. Aber da das nicht möglich ist ... wirst du wohl oder uebel das Vesabios benutzen muessen.
Jede Grafikkarte hat andere Register, andere Initialisierungs- und Rueckgabewerte sowie auch andere Fähigkeiten.
Was glaubst du, warum Linux immernoch keinen gebrauchbaren Hardwaretreiber fuer nVidia/ATI-Karten hat? Weil diese Daten Rueckschluesse auf den Aufbau der Karten fuehren könnten. Was wiederum der Konkurrenz grosse Vorteile geben wuerde etc.pp.
Einzigste Variante - irgendwo (frag nicht, wo :D) gab es mal die technischen Daten von einigen alten ISA-Grafikkarten (z.B. Trident etc) die noch kein Vesabios hatten. Wenn du diese ausreizen können willst (Stichwort 486er) dann musst du dafuer Treiber schreiben - oder dich mit Standard-VGA zufriedengeben.
Mvh Svenska
-
Selbst wenn man die Dokus der Grakas hat braucht man noch die SPezi's für PCI und AGP die kosten auch Geld, denn irgendwelche dokus dazu gibt es defacto nicht
-
ein kleiner nachtrag zu big und little endian:
damit ist die ausrichtung der bits in einem speicherteil gemeint. littleendian meint, dass das unwichtigste bit vorne ist, bei bigendian ist das wichtigste bit, also dass, bei dessen veränderung man die größte zahlenveränderung hat vorne ist, so, wie wir auch zahlen schreiben. in dezimal könnte man sich das so vorstellen, als würde man in einer zweistelligen zahl einfach einer und zehnerstelle vertauschen. das währe dann littleendian, die unwichtigste stelle (die einer) zuerst. bigendian ist, wie wir es machen würden, also die wichtigste stelle zuerst (die zehner).
-
Wie schafft es dann das BIOS?
Ist das ein riesiges Verfahren, das nicht neugeschrieben werden kann? Gibt es da für jede Graka unterschiedliche Initialisierungsverfahren für VGA?
Wenn du es schaffst, an die technischen Daten aller Grafikkarten ranzukommen, duerftest du auch Treiber dafuer schreiben können. Aber da das nicht möglich ist ... wirst du wohl oder uebel das Vesabios benutzen muessen.
Jede Grafikkarte hat andere Register, andere Initialisierungs- und Rueckgabewerte sowie auch andere Fähigkeiten.
Was glaubst du, warum Linux immernoch keinen gebrauchbaren Hardwaretreiber fuer nVidia/ATI-Karten hat? Weil diese Daten Rueckschluesse auf den Aufbau der Karten fuehren könnten. Was wiederum der Konkurrenz grosse Vorteile geben wuerde etc.pp.
Einzigste Variante - irgendwo (frag nicht, wo :D) gab es mal die technischen Daten von einigen alten ISA-Grafikkarten (z.B. Trident etc) die noch kein Vesabios hatten. Wenn du diese ausreizen können willst (Stichwort 486er) dann musst du dafuer Treiber schreiben - oder dich mit Standard-VGA zufriedengeben.
Mvh Svenska
Und nur das VESA-3-BIOS kann über den PM angesteuert werden? Jetzt regt mich diese RM-Kompatibilität auch langsam auf.
-
Selbst wenn man die Dokus der Grakas hat braucht man noch die SPezi's für PCI und AGP die kosten auch Geld, denn irgendwelche dokus dazu gibt es defacto nicht
Im PC-Hardwarebuch wird die PCI-Schnittstelle ganz gut erklärt, wenn ich mich nicht irre... und AGP ist ja auch nur eine "erweiterte" PCI-Schnittstelle. D.h. wenn du PCI eingebaut hast, kannst du auch AGP ansprechen (mit Einbußen allerdings).
Korrekt?
Svenska
-
[schild=1]Immer weiter so....[/schild]
Ich habe dadurch immer mehr gelernt! Danke!
MfG, Scorpion!
-
Tja, bei mir funzt das Mode-Switchen ohne Probs aber pixeln geht mit Bochs nicht (auf dem real PC schon!) ...Modus ist 0x101 und gepixelt sollte so werden:
mov edi, [VbeModePhysBasePtr]
mov ecx, 640*480
mov eax, 0xCC
rep stosb
-
Tja, bei mir funzt das Mode-Switchen ohne Probs aber pixeln geht mit Bochs nicht (auf dem real PC schon!) ...Modus ist 0x101 und gepixelt sollte so werden:
mov edi, [VbeModePhysBasePtr]
mov ecx, 640*480
mov eax, 0xCC
rep stosb
welche graka in real?
-
NVidia Geforce MX 2 440 aber da funzts ja...
-
mit der ists ein wunderwerk ;)
die hab ich in beiden rechnern (test und arbeit) und bei dem einen kackt mein os wegen Vesa da ab (arbeit) und bei dem anderen gehts, mit exakt der gleichen karte :D
-
der code von zacK oben (piratOS) sieht gut aus, ich habe ihn zwar noch nicht getestet, aber wie kann ich die printf fnktion einbauen? ich möchte ja auch text einbauen!
MfG, Scorpion!
-
da brauchst du zuerst eine art font.... du musst festhalten für welchen buchstaben welche pixel gemalt werden... sobald du ein grafik-modus gewählt hast, kannst du nicht mehr so einfach buchstaben ins videoram schreiben.. das sind dann alles pixel die du für jeden buchstaben mahlen musst..