Lowlevel
Lowlevel => Lowlevel-Coding => Thema gestartet von: Tbex am 09. March 2016, 11:16
-
Zuerst mal Danke für die Aktivierung meines Accounts in diesem Forum :)
wie im Titel schon beschrieben möchte ich ein bit in einem Byte maskieren.
Ich möchte nämlich den vga modus 12 benuzten, der im Planar modus ist.
Ich schaff es den Modus zu ändern wie auch den ganzen Bildschirm schon mit einer Farbe zu füllen.
Wenn ich aber ein Pixel ändere möchte, muss ich 4 bits ändern die alle auf der gleichen Adresse liegen. mit outportw kann ich in diesen Planes switchen.
Hier der Code:
void int32_setpixel_0x12(int x, int y, char farbe)
{
char Plane0[2];
char Plane1[2];
char Plane2[2];
char Plane3[2];
int getPosPixel = (y*640) + x;//wieviele pixel von oben links gesehen
int BytePos = getPosPixel /8;//welches byte anwählen
int modulo = getPosPixel % 8;//welches bit im byte anwählen
char* vidmem = (char*) 0xA0000;
//holle byte das verändert werden muss(4x wegen planes)
outportw(0x3CE,0x0005);//setup plane masking
outportw(0x3c4,0x0102);//plane 0
k_memcpy(Plane0,(vidmem + BytePos), 1);
outportw(0x3c4,0x0202);//plane 1
k_memcpy(Plane1,(vidmem + BytePos), 1);
outportw(0x3c4,0x0402);//plane 2
k_memcpy(Plane2,(vidmem + BytePos), 1);
outportw(0x3c4,0x0802);//plane 3
k_memcpy(Plane3,(vidmem + BytePos), 1);
outportw(0x3c4,0x0F02);//restore normal plane mask
//ändere bits
switch(modulo)
{
case(0):
{
if((farbe & 0x1) == 0x1){Plane0[0] |= 0x80;}//1000'0000
else{Plane0[0] &= 0x7F;}//0111'1111
if((farbe & 0x2) == 0x2){Plane1[0] |= 0x80;}
else{Plane1[0] &= 0x7F;}
if((farbe & 0x4) == 0x4){Plane2[0] |= 0x80;}
else{Plane2[0] &= 0x7F;}
if((farbe & 0x8) == 0x8){Plane3[0] |= 0x80;}
else{Plane3[0] &= 0x7F;}
break;
}
}
//byte zurück in video speicher
outportw(0x3CE,0x0005);//setup plane masking
outportw(0x3c4,0x0102);//plane 0
k_memset((vidmem + BytePos), Plane0[0], 1);
outportw(0x3c4,0x0202);//plane 1
k_memset((vidmem + BytePos), Plane1[0], 1);
outportw(0x3c4,0x0402);//plane 2
k_memset((vidmem + BytePos), Plane2[0], 1);
outportw(0x3c4,0x0802);//plane 3
k_memset((vidmem + BytePos), Plane3[0], 1);
outportw(0x3c4,0x0F02);//restore normal plane mask
}
Irgendwie kann aber k_memcpy das Byte nicht aus dem speicher lesen und in den string schreiben....
Kann mir jemand helfen oder zeigen wie ich das machen kann?
Vielen Dank im voraus
-
Auch hier nochmal herzlich willkommen im Forum, falls du die PN noch nicht gelesen hast. ;)
Wenn du sagst, dass k_memcpy() die Daten nicht richtig liest, heißt das, dass du das Zwischenergebnis nach dem Holen der Bytes ausgegeben hast und schon das nicht stimmt? Dann müssen wir uns den Rest nämlich gar nicht erst anschauen.
Theoretisch denkbar ist, dass dein k_memcpy() nicht richtig funktioniert, kannst du es mal posten? Ansonsten wäre es wahrscheinlich, dass VGA doch nicht so funktioniert wie du denkst. Wie das genau geht, weiß ich aber auch nicht auswendig und müsste es erstmal nachlesen.
Und dann wäre natürlich noch die Frage, wieso du dir überhaupt Modus 12 antust, wenn es heute vernünftige Auflösungen mit genug Farben gibt. :D
-
wenn ich im standart textmodus diesen code benutzte:
USHORT* vidmem = (USHORT*) 0xb8000;
char Ausgabe[10];
set_cursor(0,0);
save_cursor();
k_clear_screen();
printformat("hallo");
k_memcpy(Ausgabe,vidmem, 10);
printformat("\n%s",Ausgabe);
sleepSeconds(100);
kommt auch beim 2. printformat das Hallo, davon gehe ich aus, dass die funktion geht.
hier k_memcpy:
void* k_memcpy(void* dest, const void* src, size_t count)
{
const char *sp = (const char *)src;
char *dp = (char *)dest;
for(; count != 0; count--) *dp++ = *sp++;
return dest;
}
mir geht es nicht darum den besten Farbmodus zu haben, ich möchte nur meine Programmierfähigkeiten verbessern und dazulernen.
hier das einzige gute dokument was ich zu den vga modis gefunden habe:
http://webpages.charter.net/danrollins/techhelp/0089.HTM
-
Hier gibt es ein bisschen mehr Doku: http://www.osdever.net/FreeVGA/vga/vga.htm
Bist du dir sicher, dass es eine gute Idee ist, Adress- und Datenregister gleichzeitig mit einem outw zu setzen statt erst die Adresse und dann die Daten jeweils mit outb?
(k_memcpy sieht okay aus. Nur das Textmodus-Testprogramm ist strenggenommen kaputt, weil Ausgabe nicht nullterminiert ist.)
-
wie meinst du das: "Adress- und Datenregister gleichzeitig mit einem outw zu setzen"?
wenn es mit:
void int32_clear_screen_0x12(char farbe)
{
char Plane0, Plane1, Plane2, Plane3;
if((farbe & 0x1) == 0x1){Plane0 = 0xFF;}
else{Plane0 = 0x00;}
if((farbe & 0x2) == 0x2){Plane1 = 0xFF;}
else{Plane1 = 0x00;}
if((farbe & 0x4) == 0x4){Plane2 = 0xFF;}
else{Plane2 = 0x00;}
if((farbe & 0x8) == 0x8){Plane3 = 0xFF;}
else{Plane3 = 0x00;}
outportw(0x3CE,0x0005);//setup plane masking
outportw(0x3c4,0x0102);//plane 0
k_memset((char*) 0xA0000,Plane0,38400);
outportw(0x3c4,0x0202);//plane 1
k_memset((char*) 0xA0000,Plane1,38400);
outportw(0x3c4,0x0402);//plane 2
k_memset((char*) 0xA0000,Plane2,38400);
outportw(0x3c4,0x0802);//plane 3
k_memset((char*) 0xA0000,Plane3,38400);
outportw(0x3c4,0x0F02);//restore normal plane mask
}
geht, sollte es ja auch mit einem byte gehen^^
-
wie meinst du das: "Adress- und Datenregister gleichzeitig mit einem outw zu setzen"?
Das hier:
outportw(0x3c4,0x0102);//plane 0
Ich hätte da eher sowas erwartet:
outportb(0x3c4,0x02); // Adressregister auf Index von Map Mask Register setzen
outportb(0x3c5,0x01); // Mit Datenregister den Wert des MMR setzen
wenn es mit: [...] geht, sollte es ja auch mit einem byte gehen^^
Du meinst, dein int32_clear_screen_0x12() funktioniert? Das hattest du bisher nicht erwähnt. :)
-
ja diese Funktion geht einwandfrei :)
ich habe auch schon mit dieser Funktion den Bildschirm Komplet Weiß eingefärbt(alle byte mit 0xFF) und dann wieder in Textmodus gewechselt um dann wie vorher den Speicher abgefragt.
Leider ohne erfolg :/
ob ich outportb oder outportw benutzte macht auch kein unterschied....
Ich frage morgen in der Schule mal mein H&S Lehrer, auch wenn ich nicht viel von ihm erwarte kann^^
-
Was für eine Ausgabe erwartest du denn? Wenn die ersten beiden Pixel schwarz sind, (Wert 0x00) dann enthält der String Ausgabe ja gleich ein Nullterminierungzeichen und somit wird nichts ausgegeben. Vielleicht solltest du den Wert noch in einen String umwandeln?
-
Wie meinst du was ich als Ausgabe erwarte? ich erwarte beim Auslesen des Speichers ein 0xFF, weil der Bildschirm weiss ist/war.
Mein Lehrer weiss auch nichts wie erwartet.... :?
ich setzt mich heut Abend mal hin und mach ne asm Funktion die den Speicher auslesen soll.
-
ob ich outportb oder outportw benutzte macht auch kein unterschied....
Das kann reale Hardware deutlich anders sehen als ein Emulator.
-
Das kann reale Hardware deutlich anders sehen als ein Emulator.
da geb ich dir recht aber das ist nicht mein problem^^
Irgendwie will k_memcpy den speicher nicht ausslesen und ich seh den fehler nicht :/
-
Wenn du gar nicht weiterkommst, kannst du mal deinen kompletten Code irgendwo online stellen, dass man das im Komplettzusammenhang sehen und evtl. auch damit spielen kann. Ich bin mir noch nicht sicher, ob ich Zeit habe, das für dich zu debuggen, aber vielleicht springt ja jemand anderes ein.
-
https://www.dropbox.com/sh/8b08pga11m3ms9n/AABXrYM34vN_rKN5cLq6ZDhLa?dl=0 (https://www.dropbox.com/sh/8b08pga11m3ms9n/AABXrYM34vN_rKN5cLq6ZDhLa?dl=0)
viel spass, sollte recht gut auskommentiert sein :)
die funktion die aufgeruffen wird heisst: int32_setpixel_0x12(320,320,GREEN); in ckernel.c zeile 112
die funktion ist ausgeschrieben in int32.c zeile 61