Autor Thema: kprintf - Steuerzeichen  (Gelesen 2260 mal)

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« 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

Jidder

  • Administrator
  • Beiträge: 1 623
    • Profil anzeigen
Gespeichert
« Antwort #1 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.
« Letzte Änderung: 10. November 2012, 22:14 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

Svenska

  • Beiträge: 1 784
    • Profil anzeigen
Gespeichert
« Antwort #2 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

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #3 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 :-)
« Letzte Änderung: 11. November 2012, 12:24 von MrTom3715 »

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #4 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
« Letzte Änderung: 11. November 2012, 19:50 von MrTom3715 »

Jidder

  • Administrator
  • Beiträge: 1 623
    • Profil anzeigen
Gespeichert
« Antwort #5 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
« Letzte Änderung: 11. November 2012, 19:34 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #6 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

chris12

  • Beiträge: 134
    • Profil anzeigen
Gespeichert
« Antwort #7 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 ....
OS? Pah! Zuerst die CPU, dann die Plattform und _dann_ das OS!

Svenska

  • Beiträge: 1 784
    • Profil anzeigen
Gespeichert
« Antwort #8 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
« Letzte Änderung: 11. November 2012, 23:07 von Svenska »

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #9 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

Jidder

  • Administrator
  • Beiträge: 1 623
    • Profil anzeigen
Gespeichert
« Antwort #10 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.
« Letzte Änderung: 12. November 2012, 18:57 von Jidder »
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 12. November 2012, 19:01 »
Stimmt die Schleife ist unnötig werde es gleich mal ausprobieren.
Danke.

MrTom3715

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #12 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

Jidder

  • Administrator
  • Beiträge: 1 623
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 12. November 2012, 19:20 »
scrolldown sollte cursor_y um times verringern.
Dieser Text wird unter jedem Beitrag angezeigt.

MrTom3715

  • Beiträge: 38
    • Profil anzeigen
Gespeichert
« Antwort #14 am: 12. November 2012, 20:14 »
Klappt Super!
Dankeschön!

MrTom3715

 

Einloggen