PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] Console-entwickeln



Crash-Override
19.04.2005, 16:12
Nein, will keinen Terminal-Emulator bauen :p

Um genau zu sein entwickle ich mit C ein Betriebssystem. Bin im Protected Mode etc, aber das ist für dieses Problem wenig relevant. Da es sich um ein algemeines C-Problem handelt stell ich die Frage mal hier:

Also, ich habe einen Keyboard-Treiber der mir je anch Taste n' Integer Wert übergibt. Nun die Funktion dies auswerten soll:



int main()
{
[... Titel Ausgeben, PIC remapen, IDT aufsetzen, IRQs verknüpfen, CMOS checken, Floppys untersuchen, Color-Test durchführen ...]
char console[80];
int pos = 0;
int last;
int now;
int i = 1;
while (i > 80)
{
console[i] = '\0';
i++;
}
pos=0;
while (1==1)
{
now = getkeycode();
if (now != last) // Das MUSS so sein, sonst gibt er bei a drücken aaaaaaaaa[......] aus. Man muss halt 2x drücken für doppelbuchstaben.
{
pos++;
switch (now)
{
case 1: console[pos] = 'q'; break;
case 2: console[pos] = 'w'; break;
case 3: console[pos] = 'e'; break;
case 4: console[pos] = 'r'; break;
case 5: console[pos] = 't'; break;
case 6: console[pos] = 'y'; break;
case 7: console[pos] = 'u'; break;
case 8: console[pos] = 'i'; break;
case 9: console[pos] = 'o'; break;
case 10: console[pos] = 'p'; break;
case 11: console[pos] = 'a'; break;
case 12: console[pos] = 's'; break;
case 13: console[pos] = 'd'; break;
case 14: console[pos] = 'f'; break;
case 15: console[pos] = 'g'; break;
case 16: console[pos] = 'h'; break;
case 17: console[pos] = 'j'; break;
case 18: console[pos] = 'k'; break;
case 19: console[pos] = 'l'; break;
case 20: console[pos] = 'z'; break;
case 21: console[pos] = 'x'; break;
case 22: console[pos] = 'c'; break;
case 23: console[pos] = 'v'; break;
case 24: console[pos] = 'b'; break;
case 25: console[pos] = 'n'; break;
case 26: console[pos] = 'm'; break;
case 27: console[pos] = ' '; break;
};
last = now;
};

printf(console);
printf("\r");
asm volatile ("nop"); // Nicht weiter wichtig zum verständniss...
};
};


Allerdings funktioniert die Ausgabe nicht.
Ich bekomme das angezeigt:

$è@

Tipp ich auf ne Taste, dann wird @ mit dem Buchstaben ersetzt der zuerst gedrückt wurde. also ich tippe e
dann steht da: $èe.

Wenn ich weitertipp bleicht es so.

Weiß irgendjemand warum das nicht funktioniert?

raian
19.04.2005, 16:31
ich kann nur Mutmaßen wie das in C ist, aber könnte es sein das das Der Code (in Maschienensprach oder wie die heißt^^) für z.B. e ist? Wie gesagt, ich bn mir nicht sicher...

Crash-Override
19.04.2005, 16:44
Nein, das glaube ich nicht, denn wenn nix drücke steht da $è@ und wenn ich was drücke wird @ dadurch ersetzt.

Hier:
[Bild] Start ohne gedrückt (http://pic2006.milten.lima-city.de/Bilder//PNG/PNG23.PNG)
[Bild] Nach drück auf g (http://pic2006.milten.lima-city.de/Bilder//PNG/PNG24.PNG)

Dingsi
19.04.2005, 17:19
while (i > 80) << Sollte es nicht while i < 80 heißen? ;) i müsste am Anfang auch 0 und nicht 1 sein.

Ich würde außerdem now und last initialisieren.

BTW: Der Keyboard-Treiber würde mich interessieren..

Crash-Override
19.04.2005, 17:23
jap, sollte es -.-".

Leider kommt hierdurch das nächste Problem.

Nun lautet die Ausgabe schlicht "$" .Egal was ich drück, es rührt nix. :eek:

2.Edit:
Hab das mit der 1 und der 0 übersehen was du sagtest. Das heißt er zeigt gar nichts an. Auch nicht bei Tastendruck.

Edit:
BTW: Der Keyboard-Treiber würde mich interessieren..
Im Grunde ist es recht einfach. Es gibt einen Interrupt Detection (?) Table kurz IDT. Ich kann den *alten* aus dem Real-Mode nicht mitnehmen (und will es auch nicht) und kann so keine Standart BIOS-Ints mehr im Protected Mode nutzen. Also lege ich mir selbst einen an. Nun trage ich da ein das beim Tastendruck die Funktion IRQ_1 ausgeführt wird (IRQ 1 ist der Keyboard-Int ^^)

Mein Treiber ist zwar nicht alzu besonders, aber hier ist mal ne Version:



void irq_1(void) // Keyboard
{
int key = 0;
int i = 0;
out(0x20,0x20);
out(0xA0,0x20);
key = in(0x60);

if (key == 0x10) // Taste q
i=1;

if (key == 0x39)
i=27; // Leertaste
if (key == 0x3A)
i=28; // Groß-Schreib
if (key == 0x2A)
i=29; // Klein-Schreib links
if (key == 0x0E)
i=30; // Backspace

keycode = i;
};

int getkeycode()
{
return keycode;
keycode = 0;
};


Das anlegen des IDT ist hier etwas komplizierter. Wenn dich das interressiert, dann kannst du ja mal den Code von mir ansehen (http://crashoverride22.cr.funpic.de/OSDEV/). Zum kompilen brauchst du djgpp (nicht die System-Varis vergessen) und nasm (beides kostenlos). Auserdem rawwrite ums auf eine Diskette zu schreiben und evt. Bochs ums zu Emulieren. Allerdings funktioniert das Teil noch nicht besonders auf manchen PC's (z.B. i686er Architekturen)
warum weiß ich nicht, wird sich noch ändern -.-!

Wem das zuviel ist kanns ja unter Linux kompilen. GCC ist unter Linux schon bald standart. Nasm (zumindest bei Fedora nicht, aber man kannst ja downloaden).

Unter Linux müsst ihr euch halt die Befehle aus der Compile.bat ziehen und dann in ne Make schreiben.



Allerding muss ich sagen es liegt nicht am "Treiber". Wenn amn statt den

case x: console[pos] = 'x'; break;

ein case x: printf("x"); break;

einfügt klappt es.

Edit 3:
Mhm... wenn ich statt dem \0 bei der Schleife einfach nur 0 eingebe und dann hallo eingebe bekomme ich das angezeigt:

00h0a0l0l0o0000[...]00 4xwirres Zeichen(verschiedene)

Edit4 *seuftz*:

Jetzt läuft es :D


char console[80];
int pos = 0;
int last;
int now;
int i = 0;
while (i < 80)
{
console[i] = '\0';
i++;
}
pos=-1;
while (1==1)
{
now = getkeycode();
if (now != last)
{
switch (now)
{
case 1: pos++; console[pos] = 'q'; break;
case 2: pos++; console[pos] = 'w'; break;
case 3: pos++; console[pos] = 'e'; break;
case 4: pos++; console[pos] = 'r'; break;
case 5: pos++; console[pos] = 't'; break;
case 6: pos++; console[pos] = 'y'; break;
case 7: pos++; console[pos] = 'u'; break;
case 8: pos++; console[pos] = 'i'; break;
case 9: pos++; console[pos] = 'o'; break;
case 10: pos++; console[pos] = 'p'; break;
case 11: pos++; console[pos] = 'a'; break;
case 12: pos++; console[pos] = 's'; break;
case 13: pos++; console[pos] = 'd'; break;
case 14: pos++; console[pos] = 'f'; break;
case 15: pos++; console[pos] = 'g'; break;
case 16: pos++; console[pos] = 'h'; break;
case 17: pos++; console[pos] = 'j'; break;
case 18: pos++; console[pos] = 'k'; break;
case 19: pos++; console[pos] = 'l'; break;
case 20: pos++; console[pos] = 'z'; break;
case 21: pos++; console[pos] = 'x'; break;
case 22: pos++; console[pos] = 'c'; break;
case 23: pos++; console[pos] = 'v'; break;
case 24: pos++; console[pos] = 'b'; break;
case 25: pos++; console[pos] = 'n'; break;
case 26: pos++; console[pos] = 'm'; break;
case 27: pos++;console[pos] = ' '; break;
};
last = now;
}

printf(console);
printf("\r");
asm volatile ("nop");
};
};


Der Fehler war 1. Das das 1. Zeichen ein \0 war und deshalb nix ausgegeben wurde. Das mit dem h0a ist so zu erklären. Wenn kein Zeichen kommt wird pos +1 gemacht, aber in Console wird nix geändert. Das heißt in Console steht dann
h\0a was natürlich keine Ausgabe erzeugt ;)

Edit x [sind schon zu viele...]:

Hab das ganze nun mal in ner billig-Konsole umgesetzt:
[Bild] (http://pic2006.milten.lima-city.de/Bilder//PNG/PNG25.PNG)

Neuster Source-Code:
[HIER] (http://crashoverride22.cr.funpic.de/OSDEV/)

Die Codes sind so benannt:

[Tag]-[Monat]-[Jahr]-[Stunde]-[Minute].rar

also neustes ist im Moment:
19-04-05-18-03.rar

Ineluki
20.04.2005, 02:41
Passt zwar nicht ganz zum threadthema, aber was solls ...

Weiss einer, wie man bootfaehige CDs fuer eigene Betriebssysteme erstellt ?
Also sowas wie rawwrite fuer CDs ? Dieweil ich hab kein Diskettenlaufwerk -__-

Gruss Luki

GSandSDS
20.04.2005, 08:48
Soweit ich weiß hat z.B. Nero (bzw. Nero Express) die Option bootfähige CDs zu erstellen. Genaueres kann ich leider nicht sagen, da ich dieses Feature noch nie verwendet habe.

Crash-Override
20.04.2005, 16:31
Passt zwar nicht ganz zum threadthema, aber was solls ...

Weiss einer, wie man bootfaehige CDs fuer eigene Betriebssysteme erstellt ?
Also sowas wie rawwrite fuer CDs ? Dieweil ich hab kein Diskettenlaufwerk -__-

Gruss Luki

Hatte ich auch nicht... ahbs von nem Freund bekommen und musste mir nur noch das total überteuerte Kabel kaufen [Das Flachband].

Naja, wenns nur drum geht etwas zu testen kannst du ja mit Bochs n' PC emulieren und's darauf laufen lassen:

http://lowlevel.brainsware.org/index.php?pagename=tutorials&showtut_id=28

btw: hab wieder geupt. Jetzt hab ich die Befehle info und exit zur Konsole hinzugefügt ;)
Auserdem hab ich mir n' paar Ansätze für n' Floppy-Treiber überlegt. [Der wird dringend nötig sein und in Verbindung mit dem Datentreiber (Das ist dann das Teil was "weiß" wie Fat aufgebaut ist und es an den Floppy-Treiber leitet) die Grundlage fürs ausführen von Programmen sein.

DFYX
20.04.2005, 18:57
Ich habs leider nicht auf die Reihe gebracht, das unter Windows mit gcc (Nicht djgpp) zu compilieren. Wär nett, wenn du entweder alle benötigten Downloadlinks und/oder eine fertig compilierte Version liefern könntest.

Crash-Override
20.04.2005, 19:10
Compilte Version liegt bei ;) also, zuerst MUSST du den Bootloader auf ne Diskette kopieren. Das heißt: Ins Bootloader Verzeichniss gehen und Bootf.bat ausführen. Dafür benötigst du den Freeware Assembler nasm und das Programm PartCopy. NASM Homepage (http://nasm.sourceforge.net/wakka.php?wakka=HomePage).
Partcopy (http://my.execpc.com/~geezer/johnfine/pcopy02.zip)
Die Datei nasmw.exe in nasm.exe umbenennen (ich machs so, weil in Linux heißt sie nur nasm) und ins Windows verzeichniss oder ins Bootloader Verzeichniss damit (Partcopy auch). Dann kopierst du aus dem Out Verzeichniss die Kernel.bin auf die Diskette (du kannst sie ganz normal mit Windows reinkopieren da ich Fat12 als Filesystem ahb =).


Edit:
Ich hab nun alles etwas aktuallisiert: http://crashoverride22.cr.funpic.de/OSDEV/

Ich hab ein Binary hochgeladen (einfach über Rawwrite auf ne Diskette schreiben und fertig).
Dann hab ich noch einige Tools geupt für Faule -.-".

Also:
DJGPP-Packet
Bochs
Nasm
Partcopy
Notepad2 [Nicht benötigt, aber super zum anschauen der Codes (mit Highlighting für x Sprachen)]

Beachtet die Readme.txt im Tools Verzeichnis.

Edit2:

Bei der Bochs-Run.bat nehmt statt bochs -d bochs -q...

Tippfehler...

Crash-Override
26.04.2005, 15:28
sry für den Doppelpost, aber sonst würde wohl niemand mehr in den Thread reinsehen, oder? ;)

Also, neues Problem. Ich will meine Konsole nun auf Großbuchstaben erweitern...

Hier der relevante Keyboard-Treiber abschnitt:



int keycode = 0;

unsigned char keyboard[128] =
{
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
'9', '0', '-', '=', -1, /* Backspace */
' ', /* Tab */
'q', 'w', 'e', 'r', /* 19 */
't', 'y', 'u', 'i', 'o', 'p', '[', ']', -2, /* Enter key */
0, /* 29 - Control */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
'\'', '`', -3, /* Left shift */
'\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 49 */
'm', ',', '.', '/', -3, /* Right shift */
'*',
0, /* Alt */
' ', /* Space bar */
-4, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
-1, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};

unsigned char up_keyboard[128] =
{
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', /* 9 */
'(', ')', '_', '+', -1, /* Backspace */
' ', /* Tab */
'Q', 'W', 'E', 'R', /* 19 */
'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', -2, /* Enter key */
0, /* 29 - Control */
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 39 */
'\'', '"', -3, /* Left shift */
'|', 'Z', 'Y', 'C', 'V', 'B', 'N', /* 49 */
'M', '<', '>', '?', -3, /* Right shift */
'*',
0, /* Alt */
' ', /* Space bar */
-4, /* Caps lock */
0, /* 59 - F1 key ... > */
0, 0, 0, 0, 0, 0, 0, 0,
0, /* < ... F10 */
0, /* 69 - Num lock*/
0, /* Scroll Lock */
0, /* Home key */
0, /* Up Arrow */
0, /* Page Up */
'-',
0, /* Left Arrow */
0,
0, /* Right Arrow */
'+',
0, /* 79 - End key*/
0, /* Down Arrow */
0, /* Page Down */
0, /* Insert Key */
-1, /* Delete Key */
0, 0, 0,
0, /* F11 Key */
0, /* F12 Key */
0, /* All other keys are undefined */
};

int caps = 1;
char keyi;

char getkeycode()
{
if (caps == 1)
{
keyi = keyboard[keycode];
}
else
{
keyi = up_keyboard[keycode];
}
keycode = 0;

if (keyi == -3)
{
caps = 1;
return 0;
}
else if (keyi == -4)
{
caps = 2;
return 0;
}
else
{
return keyi;
}
};


(Am Konsolen-Code liegts nicht, denn der gibt einfach aus was er zurückbekommt.)
Das Problem ist folgendes: Wenn ich Caps an hab dann schreibt er einwandfrei große-Buchstaben, wenn ich allerdings Caps aus ist, dann gibt er sobald die Taste gedrückt wird die Taste als kleinbuchstaben aus, wenn ich die Taste loslasse, dann gibt er die selbe Taste als Großbuchstabe aus. KA woran das liegt.

Ach ja: Ich werde Fat12 (weil es eben DAS Disketten-Format ist) als mein 1. Filesystem verwenden. Das heißt man kann nur DOS-Datei-namen im 8:3 Format verwenden. Ich dachte mir man könnte es ja wie bei Linux machne und Dateien am Header erkennen lassen. Das hieße dann das ich bis zu 11-Zeichen Dateinamen nutzen kann. Das hieße auf Dateiendungen weitgehend zu verzichten. Was haltet ihr davon?