Lowlevel

Lowlevel => Lowlevel-Coding => Thema gestartet von: bitmaster am 11. October 2005, 22:54

Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 11. October 2005, 22:54
Hallo. Ich programmiere seit einiger Zeit ein eigenes OS. Schaut euch es mal auf meiner Webseite unter http://www.osm-page.de an. Wie ihr dort seht ist es erst in der Alpha-Version. Aber die Beta-Version ist so gut wie fertig. Also könnte ich sie auf meiner Webseite setzten. Würde mir nicht der Maustreiber den ich unbedingt haben will ein Problem bereiten. Ich möchte nämlich einen Maustreiber für Seriell und PS/2 schreiben. Aber mein Problem ist das ich so gut wie keine Daten über die Maustreiber-entwicklung habe. Ich weis dass der IRQ für COM1 vier, für COM2 drei und für PS/2 zwölf ist. Ich habe auch herausgefunden, dass der IRQ12 der int 74h ist. Wenn ich jetzt den int 74h meinen eigenen Code zuweise müsste dieser doch ausgeführt werden sobald ich etwas mit der PS/2-Maus mache (sie z.B. bewege). Tut er aber nicht. Dann habe ich herausgefunden dass ich die PS/2-Maus erst aktivieren muss. Aber meine Frage ist wie. Wie muss ich die PS/2-Maus aktivieren. Wenn ich dies getan habe führt sie dann automatisch den IRQ12 also int 74h aus? Welche Ports muss ich für den Datenaustausch (Daten der Maus empfangen und durch z.B. drücken senden) ansprechen? Die PS/2 nutzt doch auch den Tastaturcontroller oder? Aber wie weise ich der Maus meinen IRQ-Handler zu? Was muss in den IRQ-Handler rein und wie teste ich ob es sich um eine PS/2-Maus oder einer seriellen handelt. Ich finde einfach keine Infos darüber. Hoffentlich könnt Ihr mir helfen. Ich bitte so um Hilfe.

Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: Kyoko12 am 12. October 2005, 15:43
Wießt du das Beta test version und Alpha endgültige version heißt??????

mfg,
Kyoko12
Titel: Maustreiber schreiben.
Beitrag von: stultus am 12. October 2005, 15:52
Öhm Kyoko, wo haste denn den stuss her? Alpha kommt grundsätzlich vor Beta...  und ist damit definitiv keine fertige Version
Titel: Maustreiber schreiben.
Beitrag von: DarkThing am 12. October 2005, 16:31
@Topic:
Es gab mal das OS StormOS (Wird im nächsten Lowlevel vorgestellt), wo es auch einen Maustreiber gab. Da die Website inzwischen verschwunden ist, poste ich einfach mal den kompletten Code (inkl. russischer Kommentare). Interssant sind hier erstmal die Funktionen CheckPS2 und InitMouse.

typedef struct {
unsigned char LButton;
unsigned char RButton;

short X;
short Y;

unsigned char Moved;
unsigned char Pressed;
} TMouse;

TMouse Mouse;

#define KEYB_CTRL 0x64
#define KEYB_BUF 0x60

// naudojami ekrano dydio nustatymai, kad nereik� kviesti ekrano objekto
unsigned short sWidth, sHeight;

/**
 * �ungiama PS2 pel�
 * @param Width  ekrano ilgis
 * @param Height ekrano auk�is
 */
void InitMouse(unsigned short Width, unsigned short Height) {
CheckPS2();
outportb(KEYB_CTRL, 0xA8); //�ungiame PS2 pel� bendravim�

CheckPS2();
outportb(KEYB_CTRL, 0xD4);

CheckPS2();
outportb(KEYB_BUF, 0xF4); // �ungiame duomen siuntim�
CheckPS2();

sWidth = Width;
sHeight = Height;

// nustatome koordinates ties ekrano viduriu
Mouse.X = sWidth / 2;
Mouse.Y = sHeight / 2;

Mouse.Moved = 0;
Mouse.Pressed = 0;
}

/**
 * I�augomas ekrano buferis pelei ir nupie�ama pati pel�
 */
void InitMouseGFX() {
GetMouseBuffer(Mouse.X, Mouse.Y);
DrawMouse(Mouse.X, Mouse.Y);
}

/**
 * Patikriname Input Buffer Flag, Output Buffer Flag ir MOBF
 */
void CheckPS2() {
unsigned long i = 0xFFFF;

while((inportb(KEYB_CTRL) & 0x3) && i) {
inportb(KEYB_BUF);
i--;
}
}

/**
 * Klaviatros jungties skaitymas
 * @return pel� "Scan" kodas
 */
char ReadMouse() {
unsigned long i;
char Status, Byte = 0;

for(i = 0; i < 0xFFFF; i++) {
Status = inportb(KEYB_CTRL);

if(Status & 0x01) {
Byte = inportb(KEYB_BUF);

if(!(Status & 0xC0))
return Byte;
}
}
return Byte;
}


void IRQ12() {
Mouse.Pressed = 0;
Mouse.Moved = 0;

char Buf[3];
// skaitome tris pel� siun�amus baitus
Buf[0] = ReadMouse();
Buf[1] = ReadMouse();
Buf[2] = ReadMouse();

// ar buvo paspaustas pel�, kuris nors vienas mygtukas
// �a�me tada status�
if(Buf[0] & 1) {
Mouse.LButton = 1;
Mouse.Pressed = 1;
}

if((Buf[0] & 2) >> 1) {
Mouse.RButton = 1;
Mouse.Pressed = 1;
}


if(Buf[1] + Buf[2]) {
PutMouseBuffer(Mouse.X, Mouse.Y);

Mouse.X += Buf[1];
Mouse.Y -= Buf[2];

Mouse.Moved = 1;
// tikriname ar po naujo pel� pajudinimo nebuvo perengtos ekrano ribos
// X a�je
if(Mouse.X >= sWidth)
Mouse.X = sWidth - 1;
if(Mouse.X < 0)
Mouse.X = 0;

// Y a�je
if(Mouse.Y >= sHeight) Mouse.Y = sHeight - 1;
if(Mouse.Y < 0) Mouse.Y = 0;

GetMouseBuffer(Mouse.X, Mouse.Y);
DrawMouse(Mouse.X, Mouse.Y);
}
}
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 12. October 2005, 18:51
Kyoko12: Stuss

N00B: genau

DarkThing: Danke, aber ich kann kein russisch. Kannst du den Code erkähren? C ist auch nicht so meine Stärke. Wäre schön wenn das Assembler wäre. Aber ich versuche es mal in Assembler zu übersetzen. Vielen Dank!
Titel: Maustreiber schreiben.
Beitrag von: Roshl am 12. October 2005, 19:04
Das ist allerdings auch kein Russisch^^ Russisch wird zu allermeist in Kyrillischen Buchstaben geschrieben. Und selbst wenn man es in Lateinischen Buchstaben umschreibt ist Russisch anders
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 12. October 2005, 19:08
InitMouse proc near
call CheckPS2
mov al,0A8h
out 64h,al
call CheckPS2
mov al,0D4h
out 64h,al
call CheckPS2
mov al,0F4h
out 60h,al
call CheckPS2
?
InitMouse endp


So, den rest habe ich nicht verstanden bzw. kann ich nicht übersetzten. Kannst du (könnt ihr) mir helfen? Hast du (habt ihr) eine Doku wo erklährt wird was z.B. A8h, D4h und F4h bewirken? Ich wäre sehr dankbar. Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: DarkThing am 13. October 2005, 13:36
Die Funktion ReadMouse liefert (denk ich) ein Byte Daten von der Maus - Ähnlich wie beim Keyboardtreiber "in 0x60". Die Funktion IRQ12 ist einfach der IRQ-Handler, der in der IDT eingetragen werden muss. Dort werden 3 Bytes mit Hilfe von ReadMouse geholt und die neue Position errechnet.

Ansonsten gibts noch hier ein paar Tuts über Maustreiber:
http://www.nondot.org/sabre/os/articles/HumanInterfaceDevices/
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 13. October 2005, 19:06
Danke. Aber jetzt weis ich auch nicht mehr wie vorher. In dem Link wird nur der int 33h beschrieben. Der ist aber kein Treiber sondern ein int der den vorhandenen Treiber nutzt. Ich muss so einen aber selber schreiben. Also meine Frage ist erst einmal: Wie bringe ich die Maus dazu (wenn ich sie z.B. bewege, drücke) den IRQ12-Handler (int 74h) anzuspringen? Mehr möchte ich erst mal gar nicht wissen. Wie aktiviere ich die Maus und mache ihr klar das sie den int 74h anspringen soll? Dann könnte ich ja einfach eine Adresse den IRQ12 (int 74h) zuweise die z.B. eine Meldung ausgibt und den EOI (end of interrupt) also mov al,20h out A0,al out 20,al sendet. Dann würde ich doch immer wenn ich die Maus benutze eine Meldung bekommen. Somit könnte ich erst einmal testen ob das bis dahin funktioniert und dann später die richtigen Sachen den IRQ12 zuweisen. Kann doch so gemacht werden oder? Also wie bringe ich die Maus dazu den IRQ12 anzuspringen? Danke!!!

edit: Ach ja, alles in Assembler bitte. Danke
Titel: Maustreiber schreiben.
Beitrag von: DarkThing am 14. October 2005, 14:38
Du musst die Adresse des Handlers genau wie bei allen anderen Interrupt-Handlern (Exceptions, Timer, Keyboard, ...) an der richtigen Position in die IDT eintragen. Anschließend kannst du die Maus initialisieren (mit InitMouse). Das ist eigentlich schon alles.

Tutorials zur IDT gibts in Lowlevel, auf www.osdever.net , usw.
Titel: Maustreiber schreiben.
Beitrag von: SSJ7Gohan am 14. October 2005, 14:44
bitmasters OS arbeitet im Realmode, daher verwendet er keine IDT, sondern die IVT.
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 14. October 2005, 16:33
Ja genau ich arbeite im Real-Mode und nutze deswegen die IVT. Aber wenn ich die Maus mit initmouse initialisiere und in der IVT an Adresse 74h*4 meine routine schicke führt der PC sie nicht aus wenn ich die Maus beispielsweise bewege. Warum? Ist das initmouse überhaubt richtig wie ich das weiter oben in ASM übersetzt habe? Sagen wir mal es würde funktionieren, hat keine eine Doku die dies erklährt? Ich möchte auch wissen was das bedeutet und nicht einfach Code kopieren und sagen ja es funst. Bitte um Hilfe. Ich weis nicht mehr weiter.  :cry:
Titel: Maustreiber schreiben.
Beitrag von: matthieuriolo am 14. October 2005, 18:05
Ich wusste doch das ich was dazu schon mal gesehen habe

http://www.osdever.net/documents.php?cat=8&sort=1

vielleicht hilfts. Schickes os mal so am rande. In welchem Grafik Modus arbeitest du?
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 14. October 2005, 22:28
Zitat von: matthieuriolo
Ich wusste doch das ich was dazu schon mal gesehen habe

http://www.osdever.net/documents.php?cat=8&sort=1

vielleicht hilfts.
danke, aber dort wird nicht beschrieben wie ich die PS/2-Maus aktiviere und sie somit zum IRQ12 zwinge.
Zitat von: matthieuriolo
Schickes os mal so am rande. In welchem Grafik Modus arbeitest du?
Machst du dich lustig oder ist das ernst? Ich arbeite nicht im Grafikmodus sondern im Textmodus. Modus 3 heißt er.
Titel: Maustreiber schreiben.
Beitrag von: matthieuriolo am 15. October 2005, 13:40
Zitat von: bitmaster
Machst du dich lustig oder ist das ernst? Ich arbeite nicht im Grafikmodus sondern im Textmodus. Modus 3 heißt er.


Nein mach ich nicht, aber ich frage weil ich gerne wüsste wie du den Hintergrund färbst.
Titel: Maustreiber schreiben.
Beitrag von: SSJ7Gohan am 15. October 2005, 14:32
Zum Färben des Hintergrundes gibts ein paar Bits im Attribut Byte im Textmodus. Ich glaube das wird auch in einem Magazin hier auf der Seite erklärt.
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 15. October 2005, 22:27
Zitat von: matthieuriolo
Zitat von: bitmaster
Machst du dich lustig oder ist das ernst? Ich arbeite nicht im Grafikmodus sondern im Textmodus. Modus 3 heißt er.


Nein mach ich nicht, aber ich frage weil ich gerne wüsste wie du den Hintergrund färbst.
Mach ein neues Thema darüber auf und ich werde dir zeigen wie ich das mache. Hier möchte ich dir das nicht erklären, weil es dann vielleicht nur noch darum geht und nicht um die Maus. Bitte um Verständnis.
Titel: Maustreiber schreiben.
Beitrag von: Homix am 22. October 2005, 21:12
hi,
C++ ist zwar nicht mein Spezialgebiet (Pascal und asm sind besser  :D ), aber so ungefähr müsste es stimmen:


Loop:
  mov dx,KEYB_CTRL       ; wenn KEYB_CTRL ne Variable ist, dann [KEYB_CTRL] schreiben
  in al,dx
  and al,0x03
  and eax,[i]                    ; zwecks verständlichkeit drin, könnte man weglassen
  cmp eax,0                     ; könnte man ebenfalls weglassen
  jz Ende:
  mov dx,KEYB_BUF
  in al,dx
  dec [i]
  jmp Loop

Ende:
  ...

i dd 0


Aber ich bin mir nicht sicher, wie man einmal das "&" und dann das "&&" übersetzt, in meinen Augen ist in diesem Fall das beides ein AND (wobei ich && bei Vergleichen kenne).
probiers einfach mal aus.

cu,
stefan2005
Titel: Maustreiber schreiben.
Beitrag von: SSJ7Gohan am 22. October 2005, 21:13
EDIT: Argh, hatte einen kleinen Fehler

[global checkPS2]
checkPS2:
push ecx
push edx

mov ecx, 0xFFFF
mov dx, KEYB_CTRL

check:
in al, dx
and al, 0x3
cmp al, 0
jnz check_ok
loop check

jmp check_failed

check_ok:
mov dx, KEYB_BUF
in al, dx

check_failed:
pop edx
pop ecx
ret


Ich habe den Code nicht getestet, sollte aber funktionieren.
Kompilier doch einfach den Code mit "gcc -S -o ps2.asm ps2.c" und sieh dir das Ergebniss an^^
Titel: Maustreiber schreiben.
Beitrag von: DarkThing am 23. October 2005, 13:22
Zitat von: stefan2005
Aber ich bin mir nicht sicher, wie man einmal das "&" und dann das "&&" übersetzt, in meinen Augen ist in diesem Fall das beides ein AND (wobei ich && bei Vergleichen kenne).

Ein && ist ein boolesches and. Das heißt, dass es nur true liefert wenn zwei Variablen/Werte auch true sind.
Ein normales & bedeutet bitweises and. Da werden also die zwei Werte/Vars binär geandet.
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 23. October 2005, 15:15
Also ich habe jetzt die maus so aktiviert:

;gebe IRQ12 also int 74h eine Adresse
;für einen Code der eine Meldung ausgibt
;und mit iret zurückspringt
call InitMouse ;rufe die Funktion auf
;beende

InitMouse proc near
call CheckPS2
mov al,0A8h
out 64h,al
call CheckPS2
mov al,0D4h
out 64h,al
call CheckPS2
mov al,0F4h
out 60h,al
call CheckPS2
ret
InitMouse endp

CheckPS2 proc near

mov dx,0FFFFh
next:
in al,64h
and al,03h
jz done
or dx,dx
jz done
in al,60h
dec dx
jmp next
done:
ret
CheckPS2 endp


Also ich übergebe dem IRQ12 (int 74h) die Adresse meines Codes der  folgenes macht:

Alle Register auf den Stack schreibt. Dann das ds zum cs macht und eine Meldung ausgiebt. Nun den EOI (end of interrupt) mit folgendem Code sendet:

mov al,20h
out 0A0h,al
out 20h,al


jetzt holt er alle Register vom Stack und springt mit iret zurück.

Dann aktiviere ich die Maus mit dem Code den ich gepostet habe und ende. Wenn ich jetzt unter einem Real-Mode OS (z.B. DOS oder meins) die Schose laufen lasse passiert erstmal nicht solange bis das Programm endet. Dann mache ich nicht und er gibt die meldung aus die er eigentlich erst ausgeben soll wenn ich etwas mit der Maus mache sie z.B. bewege. Und nun bleibt das OS hängen. Das verstehe ich nicht. Er führt also den IRQ12 aus und tut dann garnichts mehr. Warum? Normalerweise sollte er mir immer die Meldung ausgeben (also den IRQ12 ausführen) wenn ich die Maus bewege und drücke. Das soll  nämlich nur ein Test sein ob er auch den IRQ12 ausführt wenn ich es will. Später könnte ich dann ja immer noch den Code für die Meldung mit dem richtigen Code für die Maus (Daten lesen etc.) ersetzten. Aber wie ich sehe funktioniert nicht einmal dies. Könnt Ihr mir weiterhelfen?

Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 24. October 2005, 22:35
Hat keiner von euch ne Ahnung? Dann poste ich mal meinen Code:

mouse.asm => mouse.filexor ah,ah
mov si,offset filename
int 60h
mov ah,05h
mov si,offset filename
mov bx,1000h
mov dx,2000h
int 60h
mov ax,2000h
mov ds,ax
mov es,ax
push 2000h
push 1000h
retf

filename db "mouse.sys",00h


mouse2.asm -> mouse.sys
org 1000h
xor ah,ah
mov si,offset msg
int 60h
mov ax,2174h
mov dx,cs
mov bx,offset MouseOffset
int 60h
call InitMouse
mov ah,04h
int 60h

InitMouse proc near
call CheckPS2
mov al,0A8h
out 64h,al
call CheckPS2
mov al,0D4h
out 64h,al
call CheckPS2
mov al,0F4h
out 60h,al
call CheckPS2
ret
InitMouse endp

CheckPS2 proc near

mov dx,0FFFFh
next:
in al,64h
and al,03h
jz done
or dx,dx
jz done
in al,60h
dec dx
jmp next
done:
ret
CheckPS2 endp

MouseOffset:
push ax
push si
push ds
mov ax,cs
mov ds,ax
xor ah,ah
mov si,offset msg
int 60h
mov al,20h
out 0A0h,al
out 20h,al
pop ds
pop si
pop ax
iret

msg db 0Dh,0Ah,"mouse",00h
Warum funst der Code nicht? Er soll bei jeder bewegung der Mouse die Meldung mouse ausgeben. Hilfe!!!

Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 25. October 2005, 20:14
Also ich verstehe das nicht. Einige von euch haben doch ein OS mit Mausfunktion. Kann mir nicht jemand Helfen. Mein OS ist bereit für die Beta-Version abgesehen von dem Maustreiber. Ich würde meine Beta-Version gerne fertig bekommen aber mit Maustreiber. Kann denn keiner von euch mir helfen? Folgendes Dokument habe ich auf meiner Festplatte: http://www.prakinf.tu-ilmenau.de/~albrecht/alfred/f0157.htm Dort wird gesagt wenn ich A8h an den Port 64h sende wird die Zusatzeinheit (das müsste die Maus sein) aktiviert. Aber ich verstehe immer noch nicht wie ich die Maus dazu bringe den IRQ12 (int 74h) anzuspringen wenn ich sie gebrauche. Könnt ihr mir nicht helfen?

Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 25. October 2005, 20:43
Ich habs ich habs ich haaaaabs. Es funst. Jetzt ruft er entlich den IRQ12 auf wenn ich die maus benutze. Ich hatte vergessen (und wusste nicht das ich das muss) in al,60h in der IRQ12 Routine zu schreiben. Erst dann kann er weiter machen. Ich bin so froh. Aber ich bin ja noch nicht am Ziel. Jetzt muss ich noch die meldung im IRQ12 mit den richtigen Funktionen ersetzten. Woher weis ich wann die linke/rechte/das Rad gedrückt wurde und die maus in welcher Richtung?

Danke!!!

PS: Ich bin so froh ;-)
Titel: Maustreiber schreiben.
Beitrag von: Homix am 25. October 2005, 21:18
hi,
wenn der IRQ12 aufgerufen wird, dann musst du mittels IN 3 mal ein Byte vom Port einlesen.
Das erste Byte enthält Informationen über die Maustasten (Bit 1 = linke Maustaste, Bit 2 = rechte, Bit 3 = mittlere, glaub ich, notfalls durch ausprobieren rauskriegen :), wenn Bit gesetzt, dann ist die Maustaste gedrückt )
Das zweite Byte gibt als signed int 8 die Veränderung auf der X-Achse
und das dritte die veränderung auf der y-Achse an.

(hab vor paar minuten selbst erst meinen Maustreiber vollendet :D)

mfg,
Stefan2005
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 25. October 2005, 22:17
Zitat von: stefan2005
(hab vor paar minuten selbst erst meinen Maustreiber vollendet :D)
Das ist ja cool. Vielen dank ich werde das morgen ausprobieren, weil ich jetzt schlafen gehe.

PS: nochmals vielen dank
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 26. October 2005, 07:30
Habe herrausgefunden das mein Programm nicht auf allen PCs funktioniert. Ich weis aber nicht warum. Ich habe gelesen das es im Kontroller-Register 2 Bits gibt die dafür zuständig sind IRQs aufzurufen. Meine Fragen sind: Sind die vielleicht bei der Maus nicht bei allen PCs standartmäßig gesetzt? Und wie setze ich diese? Folgendes habe ich nämlich im Internet gefunden:

Kontroll-Register:

- XLAT _EN2 _EN - SYS INT2 INT


INT
bei neuen Daten von der Tastatur wird Interrupt 1 ausgelöst
INT2
bei neuen Daten von der Maus wird Interrupt 12 ausgelöst


Schonmal danke!!!
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 26. October 2005, 20:44
Also irgendwie funst die Schose nicht so richtig. Beim VMware läufts ganz gut, unter Bochs gar nicht, 1. PC läuft auch nicht und beim 2. PC läuft es aber nicht so wie bei vmware. Das heißt unter VMware läufts noch am besten. Aber was mache ich falsch? Hier mein Code:


call CheckPS2
;hiermit aktiviere ich die Maus, fehlt da was?
;dies befindet sich außerhalb der IRQ12 Routine
;wird also nur einmal aufgerufen, ist das richtig?
mov al,0A8h
out 64h,al
call CheckPS2
mov al,0D4h
out 64h,al
call CheckPS2
mov al,0F4h
out 60h,al
call CheckPS2
;ende
CheckPS2:
mov dx,0FFFFh
next:
in al,64h
and al,03h
jz done
or dx,dx
jz done
in al,60h
dec dx
jmp next
done:
ret
;folgender Code ist in der IRQ12 Routine
push ax ;Register sichern
push si
push ds
push es
mov ax,cs ;für meldung muss ds gleich cs sein
mov ds,ax
mov es,ax
in al,64h
test al,20h
jz exit ;wenn nicht für Maus dann ende
in al,60h
test al,00000001b ;linke taste gedrückt?
jz nicht_linke
xor ah,ah
mov si,offset linke
int 60h ;dies gibt einfach nur die meldung linke aus (int 60h von mein os)
jmp weiter
nicht_linke:
test al,00000010b ;rechte taste gedrückt?
jz nicht_rechte
xor ah,ah
mov si,offset rechte ;meldung rechte
int 60h
jmp weiter
nicht_rechte:
test al,00000100b ;mittlere taste gedrückt?
jz weiter
xor ah,ah
mov si,offset mitte ;meldung mitte
int 60h
weiter: ;der rest x und y bewegung der maus, für später
in al,60h
in al,60h
;
xor ah,ah
mov si,offset msg ;eine meldung ausgeben, wenn nur diese
int 60h ;ausgegeben wird dann wurde keine taste gedrückt
;
exit:
mov al,20h ;sende EOI (end of interrupt)
out 0A0h,al ;schalte slave frei
out 20h,al ;schalte master frei
pop es
pop ds
pop si
pop ax
iret ;zurück


Der Code soll folgendes bewirken. Er soll die PS/2-Maus aktivieren (nur einmal also außerhalb von der IRQ12-Routine). In der Routine soll er prüfen welche taste gedrückt wurde und dann die jeweilige Meldung ausgeben + msg-Meldung. Wenn keine Taste gedrückt wurde dann soll er nur die msg-Meldung ausgeben. Die letzten beiden Parameter für x und y Achse (Verschiebung der maus) werden erst einmal nicht berücksichtigt. Zum Schluss der EOI und zurück. Der Code soll einfach nur ausgeben welche Taste gedrückt wurde (stört euch nicht an den int 60h das ist einfach der int von meinem os und ah = Null bedeutet Meldung ausgeben. Das alles funktioniert unter VMware genau so. Aber und Bochs funst nichts und unter einem PC von mir auch nicht. Der andere PC funktioniert damit fast er gibt nur beim verschieben auch die Meldungen für recht, links, mittel aus obwohl ich keine Taste drücke. Was ist an diesem Code falsch? Ist das aktivieren der Maus richtig? Was muss ich ändern?

Danke!!!

PS: stefan2005 du sagtest du hast deinen Maustreiber fertig könntest du mir vielleicht sagen wie du die Maus aktiviert hast und was du im IRQ12 stehen hast? Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: Homix am 27. October 2005, 16:39
hi,
klar, ist jedoch Delphi Code, sollte aber leicht zu verstehen sein, da viel Assembler drin vorkommt.


procedure InitMouse;
var InByte : Byte;
begin
  kbCmd($A8);
  kbRead;
  kbCmd($20);
  InByte := kbRead OR $3;
  kbCmd($60);
  If Inb($E9) = $E9 then kbWrite(InByte);   // Für Bochs
  kbCmd($D4);
  kbWrite($F4);
  kbRead;
end;

procedure kbWrite(Cmd: Byte);
asm
  @Init:
    pushad
    mov dl,al
    mov ecx,$ffff

  @kw_loop1:
    in al,$64
    test al,$20
    jz @kw_ok1
    loop @kw_loop1
    mov ah,1
    jmp @kw_exit
  @kw_ok1:
    in al,$60
    mov ecx,$ffff
  @kw_loop:
    in al,$64
    test al,2
    jz @kw_ok
    loop @kw_loop
    mov ah,1
    jmp @kw_exit
  @kw_ok:
    mov al,dl
    out $60,al
    mov ecx,$ffff
  @kw_loop3:
    in  al,$64
    test al,2
    jz  @kw_ok3
    loop @kw_loop3
    mov ah,1
    jmp @kw_exit
  @kw_ok3:
    mov ah,8
  @kw_loop4:
    mov ecx,$ffff
  @kw_loop5:
    in al,$64
    test al,1
    jnz @kw_ok4
    loop @kw_loop5
    dec ah
    jnz @kw_loop4
  @kw_ok4:
    xor ah,ah
  @kw_exit:
    popad
end;

function kbRead: Byte;
asm
  @Init:
    push ecx
    push edx
    mov ecx,$ffff
  @kr_loop:
    in al,$64
    test al,1
    jnz @kr_ready
    loop @kr_loop
    mov ah,1
    jmp @kr_exit
  @kr_ready:
    push ecx
    mov ecx,32
  @kr_delay:
    loop @kr_delay
    pop ecx
    in al,$60
    xor ah,ah
  @kr_exit:
    pop edx
    pop ecx
end;

procedure kbCmd(Cmd: Byte);
asm
  @Init:
    mov ecx,$ffff
    push eax
  @c_wait:
    in al,$64
    test al,2
    jz @c_send
    loop @c_wait
    jmp @c_error
  @c_send:
    pop eax
    out $64,al
    mov ecx,$ffff
  @c_accept:
    in al,$64
    test al,2
    jz @c_ok
    loop @c_accept
  @c_error:
    mov ah,1
    jmp @c_exit
  @c_ok:
    xor ah,ah
  @c_exit:
end;

procedure IRQ12_ASM; assembler;
asm
  pushad
  call IRQ12
  popad
  iretd
end;



mfg,
stefan
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 27. October 2005, 17:09
Habe ich gerade unter Bochs und VMware getestet. Dort funktioniert es. Auch wenn ich den Code nicht ganz verstehe. Werde gleich mal meine PCs testen. Aber der Code kommt mir so bekannt vor. Der hat ziemlich viel änlichkeit mit folgendem Code:

kb_read:

        push    ecx edx

        mov     ecx,0xffff
      kr_loop:
        in      al,0x64
        test    al,1
        jnz     kr_ready
        loop    kr_loop
        mov     ah,1
        jmp     kr_exit
      kr_ready:
        push    ecx
        mov     ecx,32
      kr_delay:
        loop    kr_delay
        pop     ecx
        in      al,0x60
        xor     ah,ah
      kr_exit:

        pop     edx ecx

        ret


kb_write:

        push    ecx edx

        mov     dl,al
        mov     ecx,0xffff
      kw_loop1:
        in      al,0x64
        test    al,0x20
        jz      kw_ok1
        loop    kw_loop1
        mov     ah,1
        jmp     kw_exit
      kw_ok1:
        in      al,0x60
        mov     ecx,0xffff
      kw_loop:
        in      al,0x64
        test    al,2
        jz      kw_ok
        loop    kw_loop
        mov     ah,1
        jmp     kw_exit
      kw_ok:
        mov     al,dl
        out     0x60,al
        mov     ecx,0xffff
      kw_loop3:
        in      al,0x64
        test    al,2
        jz      kw_ok3
        loop    kw_loop3
        mov     ah,1
        jmp     kw_exit
      kw_ok3:
        mov     ah,8
      kw_loop4:
        mov     ecx,0xffff
      kw_loop5:
        in      al,0x64
        test    al,1
        jnz     kw_ok4
        loop    kw_loop5
        dec     ah
        jnz     kw_loop4
      kw_ok4:
        xor     ah,ah
      kw_exit:

        pop     edx ecx

        ret


kb_cmd:

        mov     ecx,0xffff
      c_wait:
        in      al,0x64
        test    al,2
        jz      c_send
        loop    c_wait
        jmp     c_error
      c_send:
        mov     al,bl
        out     0x64,al
        mov     ecx,0xffff
      c_accept:
        in      al,0x64
        test    al,2
        jz      c_ok
        loop    c_accept
      c_error:
        mov     ah,1
        jmp     c_exit
      c_ok:
        xor     ah,ah
      c_exit:
        ret


setmouse:  ; set mousepicture -pointer
           ; ps2 mouse enable

     mov     [0xf200],dword mousepointer

     cli
     mov     bl,0xa8                 ; enable mouse cmd
     call    kb_cmd
     call    kb_read                 ; read status

     mov     bl,0x20                 ; get command byte
     call    kb_cmd
     call    kb_read
     or      al,3                    ; enable interrupt
     mov     bl,0x60                 ; write command
     push    eax
     call    kb_cmd
     pop     eax
     call    kb_write

     mov     bl,0xd4                 ; for mouse
     call    kb_cmd
     mov     al,0xf4                 ; enable mouse device
     call    kb_write
     call    kb_read           ; read status return


Was soll die Zeile in der "für Bochs" steht bedeuten? Brauch Bochs eine extra Einladung?
Titel: Maustreiber schreiben.
Beitrag von: Homix am 27. October 2005, 18:42
hi,
in der Tat, ich hab mir das initialisieren der Maus ein wenig einfacher gemacht  :)

das für Bochs heißt, dass diese zeile nur ausgeführt wird, wenn das OS auf Bochs läuft -> bei meiner Bochs Version würde es ohne dieser zeile nicht laufen. Mit dieser Zeile würde es zwar in Bochs laufen, aber nicht mehr auf nem echten PC  :D

mfg,
stefan2005
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 27. October 2005, 19:53
Also bei mir läuft es überall ohne diese Zeile, auch in Bochs. Ist Bochs 2.2.1, wie das bei anderen Versionen ist weis ich nicht. Aber ich lasse diese Zeile weck. Vielen dank noch. Ach ja wenn ich die drei in al,60h in der IRQ12 Routine laufen lasse muss ich etwas berücksichtigen? Vielleicht vorher irgendwie prüfen ob die Daten überhaupt schon da sind?

Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: SSJ7Gohan am 27. October 2005, 21:33
Ich kenn mich jetzt nich so mit der Maus aus, aber ich denke nicht, das du noch Abfragen musst, ob die Daten da sind, da der IRQ ja nur aufgerufen werden sollte, wenn welche da sind.
Titel: Maustreiber schreiben.
Beitrag von: Homix am 27. October 2005, 21:49
hi,
ja, wenn das erste Bit im Port $64 (KEYBOARD CONTROL) gesetzt ist, dann kann man vom port $60 das Byte einlesen.

mfg,
stefan
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 27. October 2005, 21:55
Zitat von: SSJ7Gohan
Ich kenn mich jetzt nich so mit der Maus aus, aber ich denke nicht, das du noch Abfragen musst, ob die Daten da sind, da der IRQ ja nur aufgerufen werden sollte, wenn welche da sind.
Ja, aber ich meine wenn ich mit in al,60h den ersten Parameter lade und da die CPU viel schneller ist als die Peripherie ob direkt schon der zweite da ist oder ob ich erst warten (prüfen) muss bis er da ist und diesen dann laden und danach den letzten.
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 27. October 2005, 21:56
Zitat von: stefan2005
hi,
ja, wenn das erste Bit im Port $64 (KEYBOARD CONTROL) gesetzt ist, dann kann man vom port $60 das Byte einlesen.

mfg,
stefan
OK.

Danke!!!

PS: Melde mich bald wieder. ;-)
Titel: Maustreiber schreiben.
Beitrag von: bitmaster am 28. October 2005, 23:42
So da bin ich wieder. Ich habe den Code zum aktivieren der PS/2-Maus noch etwas optimiert und in meinem OS integriert. Alles funktioniert wunderbar. Der erste Parameter der Maus gibt ja an welche Taste gedrückt oder nicht gedrückt wurde. Das funktioniert auch wunderbar. Jetzt habe ich aber eine Frage wie das mit dem zweiten und dritten Parameter funktioniert. Die sollen ja die Bewegung der Maus beinhalten (zweiter = x-Achse und dritter = y-Achse). Aber was genau beinhalten sie dann? Die zahlen gehen doch von -128 bis +128 oder? Ich habe mir die mal ausgeben lassen. Wenn ich die Maus ein ganz kleines Stück nach rechts bewege bekommt der zweite Parameter eine 1 und der dritte eine Null. Wenn ich die Maus ein ganz kleines Stück nach links bewege bekommt der zweite Parameter eine 255 (das müssten dann eine -1 sein oder?) und der dritte eine Null. Aber was sagt die 1 mir dann? Muss ich diese an meinen Video-Modus anpassen? Wie mache ich das am besten?

Danke!!!
Titel: Maustreiber schreiben.
Beitrag von: DarkThing am 29. October 2005, 13:10
Die beiden Parameter geben wohl an, wie weit/schnell die Maus bewegt wurde (und natürlich auch die Richtung). Du könntest erstmal die Werte direkt zu deiner Mauszeiger-Position addieren oder von ihr subtrahieren. Dann sollte man den Mauszeiger schon richtig bewegen können. Später kann man dann ja noch die Geschwindigkeit anpassen.