Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: MrTom3715 am 10. November 2012, 21:51

Titel: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 10. November 2012, 21:51
Hallo Liebe Community,

ich habe jetzt geschafft Hello World zu schreiben nur ich weiß nicht wie ich "\n" implementieren soll.
Ich hoffe ihr könnt mir helfen.


MrTom3715
Titel: Re: kprintf - Steuerzeichen
Beitrag von: Jidder am 10. November 2012, 22:11
Hi und willkommen an Board!

Ich nehme mal an, dass du zwei Variablen x und y hast, die die Position des Cursors speichern. Mal angenommen du hast gerade "Hello World" in die erste Zeile geschrieben, dann ist y = 0 und x = 11. Bei einem \n musst du nun die Zeichen in der Zeile y im Bereich von 11 (= x) bis 79 mit Leerzeichen überschreiben. Manche lassen das am Anfang weg, aber dann schauts doof aus, wenn noch was auf dem Bildschirm steht. Anschließend musst du noch y um 1 erhöhen und x auf 0 setzen. Dann bist du in der nächsten Zeile.

Allerdings musst du einen Spezialfall betrachten: Wenn du in der letzten Zeile bist (d.h. y = 24), dann musst du den Bildschirm um eine Zeile hochscrollen. Dazu kannst du einfach prüfen, ob y den Wert 25 hat, nachdem du es eben gerade erhöht hast. Wenn ja, musst du y wieder um 1 verringern, und alle Zeilen von y = 0 bis y = 23 um ein Zeile nach oben kopieren. Das kannst du entweder manuell mit Schleifen machen oder mit memcpy:
unsigned short *video = (unsigned short *)0xb8000; // so eine Variable hast du hoffentlich irgendwo
memcpy(video, (void *)(((uintptr_t)video) + 2 * 80), 24 * 80);

und anschließend die letzte Zeile (24) leeren, z.B. auch manuell oder mit memset.memset((void *)(((uintptr_t)video) + 24 * 80 * 2), 0, 160);
Die ganzen Casts solltest du vielleicht noch etwas vereinfachen, je nachdem wie video bei dir tatsächlich deklariert ist.
Titel: Re: kprintf - Steuerzeichen
Beitrag von: Svenska am 10. November 2012, 23:54
Hallo,

sehr schöne Erklärung. Du solltest neben '\n' auch gleich '\r' und eventuell '\t' mit implementieren (sind auch nur Cursor-Verschiebungen), da sich diese für Fortschrittsanzeigen und einfache Tabellen sehr gut eignen.

Statt den Bildschirm hochzuscrollen, kannst du den Cursor auch einfach in die obere linke Ecke setzen, wenn er unter die letzte Zeile gesetzt werden sollte. Ist etwas gewöhnungsbedürftig, funktioniert aber prima (und erspart einem, jedes Byte im Bildschirmspeicher anzufassen). Wurde in 80er-Jahre-Heimcomputern gemacht, weil das Scrolling zu langsam war.

Gruß,
Svenska
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 11. November 2012, 12:23
Vielen Dank für die ausführliche Erklärung Jidder.
Ich habe kein x und kein y. Ich werde es aber damit versuchen.

MrTom3715 :-)
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 11. November 2012, 19:19
Bei mir fängt eine neue Zeile mit
video[(zeile * 160) + i * 2] = hw[i];an. Ist das normal?

MrTom3715
Titel: Re: kprintf - Steuerzeichen
Beitrag von: Jidder am 11. November 2012, 19:23
Ich hoffe zu deiner Lösung gehört, dass du = durch == in if(hw[i] = '\n') ersetzt hast.

Du solltest die Position im String (i) von der Position auf dem Bildschirm (x) entkoppeln. Wenn du das nicht tust, kriegst du ziemliche Probleme, wenn du %d, etc implementieren willst. Dazu solltest du eine kputc-Funktion schreiben, die ich kürzlich hier beschrieben habe: http://forum.lowlevel.eu/index.php?topic=3127.msg36187#msg36187
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 11. November 2012, 19:57
Mein Code sieht jetzt so aus:
void kprintf(char * hw, ...)
{
char* video = (char*) 0xb8000;
int i;
int n;
int x;
int y;
int zeile;

for (i = 0; hw[i] != '\0'; i++)
{
y = i;
if(hw[i] == '\n')
{
zeile++;
n == 79 - i;
if(i == 3999)
{
memcpy(video, (void *)(((uintptr_t)video) + 2 * 80), 24 * 80);
memset((void *)(((uintptr_t)video) + 24 * 80 * 2), 0, 160);
zeile = 24;
}
else
{
for(x = i; x < n; x++)
video[x] = 0;
}
}
else
{
video[(zeile * 160) + y * 2] = hw[i];
        video[(zeile * 160) + y * 2 + 1] = 0x07;
}
    }

}

init.c:
for(i = 0; i< 24; i++)
kprintf("Hello World!\n");

kprintf("Ich bin eine neue Zeile\n");
kprintf("Und das ist mein Zwilling\n");

"Und das ist mein Zwilling" wird nicht angezeigt.
Was ist falsch?

MrTom3715
Titel: Re: kprintf - Steuerzeichen
Beitrag von: chris12 am 11. November 2012, 20:04
mir kommt es etwas spanisch vor, dass du die variablen x, y, sowie video mit in deiner funktion hast ....
Titel: Re: kprintf - Steuerzeichen
Beitrag von: Svenska am 11. November 2012, 23:01
Hallo,

die Variablen x und y müssen ihren Zustand über mehrere Aufrufe von kprintf() beibehalten (sonst überschreibt jedes kprintf das, was das letzte kprintf da hingeschrieben hat). Entweder, du machst globale Variablen draus oder du markierst sie als static. Normalerweise (vgl. Mathematik) bezeichnet man mit X die Spalte und mit Y die Zeile des Cursors. Du nennst sie Y und Zeile, was etwas irritiert.

Baue erstmal eine Funktion kputc() o.ä., die nur ein einzelnes Zeichen an die aktuelle Cursorposition schreibt und sich um die Bewegung des Cursors kümmert. Dein kprintf() nutzt die dann.

Ich habe bei mir den Videospeicher übrigens als uint16_t deklariert, da jedes Zeichen im Textmodus 16 Bit belegt. Am Ende ist das aber nur Geschmackssache.

Gruß,
Svenska
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 12. November 2012, 18:50
Hallo,

ich habe x und y jetzt umbenannt und kputc(char c) erstellt:
void kputc(char c)
{
cursor_x++;
if(c == '\n')
{
cursor_y++;
cursor_x = -1;
if(cursor_y == 25)
{
scrolldown(1);
}
}
else
{
video[(cursor_y * 160) + cursor_x * 2] = c;
video[(cursor_y * 160) + cursor_x * 2 + 1] = 0x07;
}
}


void scrolldown(int times)
{
int n;
int i;
int p;
for (p = 0; p < times; p++)
{for (i = 0; i < 4000; i++)
{
for (n = 0; n < 160; n++)
video[n] = 0;
for (n = 0; n < 3840; n++)
video[n] = video[n + 160];
for (n = 3841; n < 4000; n++)
video[n] = 0;
}
}
}

Ich möchte den Text gerne manuell verschieben.
for (n = 0; n < 3840; n++)
video[n] = video[n + 160];
funktioniert aber nicht was ist falsch?

MrTom3715
Titel: Re: kprintf - Steuerzeichen
Beitrag von: Jidder am 12. November 2012, 18:55
for (n = 3841; n < 4000; n++)
Das muss 3840 sein, nicht 3841. Die Schleife davor läuft ja auch nur bis n=3839 wegen der Bedingung n < 3840.

for (i = 0; i < 4000; i++)
Warum hast du diese Schleife drin? Die enthält ja die anderen Schleifen.

Wenn das nicht hilft, musst du genauer beschreiben, was "funktioniert nicht" bedeutet.
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 12. November 2012, 19:01
Stimmt die Schleife ist unnötig werde es gleich mal ausprobieren.
Danke.

MrTom3715
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 12. November 2012, 19:06
So die letzte Zeile ist frei, aber "Und das ist mein Zwilling" ist nicht da.
Ich habe die eine Schleife gelöscht und die andere geändert.


MrTom3715
Titel: Re: kprintf - Steuerzeichen
Beitrag von: Jidder am 12. November 2012, 19:20
scrolldown sollte cursor_y um times verringern.
Titel: Re: kprintf - Steuerzeichen
Beitrag von: MrTom3715 am 12. November 2012, 20:14
Klappt Super!
Dankeschön!

MrTom3715