Page 1 of 2
PS/2 mouse driver
Posted: Sun Oct 01, 2006 3:13 am
by inflater
Hi,
i want to write a PS/2 mouse driver... in PASCAL
... without MS-BOSS (DOS
)... for use to my OS
...
the problem is - that i never writed any driver, neither DOS nor Windows...
So, i dont know where to start
I was thinking of hooking the driver to CMOS real time clock (for "refreshing" the position of mouse) and to INT 33h.
I hope, that I dont corrupt CMOS with this operation
... but never mind, I have on my mainboard a CMOS Clear Jumper (everybody has
)
But, straight to this:
I've downloaded a pin scheme for PS/2:
1. Unused
2. +5 volts (to power the chip and LEDs)
3. Unused
4. Clock
5. Ground
6. Data
And what with that now?
PS/2 mouse is a bus mouse. Pheew, I cant handle that. I've searched, what kind of port uses PS/2 mouse. No such luck - only IRQ 12. What with it ??
Or let BIOS do hard work?
Can yo help me??
inflater
Posted: Sun Oct 01, 2006 7:51 am
by joke
are you programming real or protected mode? (or lmode ?)
anyways, i hope that'll help (it's pascal + asm
)
http://www.nondot.org/sabre/os/files/HCI/MOUSE1.TXT
Posted: Sun Oct 01, 2006 8:52 am
by inflater
I am programming real mode (i am not ready for pmode yet).
Thanx, but that is not a PS/2 driver...
How can I test it? I do not have serial mouse... only PS/2...
inflater
HERE IS, ONLY THING YOU NEED TO DO IS TO TRANSLATE TO PASCAL
Posted: Mon Oct 02, 2006 5:58 am
by digo_rp
inline void mouse_wait(byte a_type) { //unsigned char
dword _time_out=100000; //unsigned int
if(a_type==0) {
while(_time_out--) { //Data
if((inportb(0x64) & 1)==1) {
return;
}
}
return;
}
else
{
while(_time_out--) { //Signal
if((inportb(0x64) & 2)==0) {
return;
}
}
return;
}
}
inline void mouse_write(byte a_write) { //unsigned char
//Wait to be able to send a command
mouse_wait(1);
//Tell the mouse we are sending a command
outportb(0x64, 0xD4);
//Wait for the final part
mouse_wait(1);
//Finally write
outportb(0x60, a_write);
}
byte mouse_read() {
//Get's response from mouse
mouse_wait(0);
return inportb(0x60);
}
void mouse_install() {
byte _status; //unsigned char
S_MouseRESTORE.mbitmap = (int *)kalloc(25*25);
VideoMode = TEXT_Interface;
//Enable the auxiliary mouse device
mouse_wait(1);
outportb(0x64, 0xA8);
//Enable the interrupts
mouse_wait(1);
outportb(0x64, 0x20);
mouse_wait(0);
_status=(inportb(0x60) | 2);
mouse_wait(1);
outportb(0x64, 0x60);
mouse_wait(1);
outportb(0x60, _status);
//Tell the mouse to use default settings
mouse_write(0xF6);
mouse_read(); //Acknowledge
//Enable the mouse
mouse_write(0xF4);
mouse_read(); //Acknowledge
//Setup the mouse handler
irq_install(0x0C, (dword)ps2_irq12_handler);
irq_unlock(0x0C);
setup_ps2mouse(1);
}
Posted: Mon Oct 02, 2006 8:19 am
by inflater
Thanx digo rp, i try to convert it to pascal.
inflater
Posted: Mon Oct 02, 2006 8:51 am
by gaf
Hello inflater,
as I never stayed in real-mode for any longer than absolutly necessary I can't really tell you if todays BIOS actually support PS/2 mice. If you're however planning to eventually move on to pmode, you might aswell write a proper driver right aways. Both the PS/2 keyboard aswell as the mouse are handled by the same controller hardware and are relativly easy to program. Details about the chip's interface are available on Adam Chapweske's
site - which can be considered the standard resource for PS/2 programming - and some more information can be found
here.
regards,
gaf
Posted: Mon Oct 02, 2006 8:57 am
by inflater
digo_rp:
What did you mean
irq_install(0x0C, (dword)ps2_irq12_handler);
irq_unlock(0x0C);
setup_ps2mouse(1);
There is no such functions (I cant use GETINTVEC/SETINTVEC because this is IRQ, not INT)
Thanks,
inflater
Posted: Mon Oct 02, 2006 9:14 am
by digo_rp
those lines below you can forget about.
it just add new handler to IRQ12
irq_install(0x0C, (dword)ps2_irq12_handler);
and enable IRQ12
irq_unlock(0x0C);
that one aloc memory for mouse pointer. etc.
setup_ps2mouse(1);
Posted: Mon Oct 02, 2006 9:25 am
by inflater
Yep, but SETINTVEC sets ONLY INTERRUPTS, not INTERRUPT REQUESTS. Or should I use that SETINTVEC?
IRQ_INSTALL - Pascal does not have that function.
Anyway,
I tried to convert (myself) the code to Pascal.
Bochs 2.3 generated LAAARGE log - it contained mainly this:
00018005861i[CPU0 ] LOCK prefix unallowed (op1=0x53, attr=0x0, mod=0x0, nnn=0)
I tried to remove Alexei Frounzes memory managment, but still no luck.
For more info - down.
//EDIT:
When I moved the mouse a few, the bochsout.txt growed (size) with this error.
When I moved the mouse (a few) more, the bochsout.txt was 20 MB
And when I moved the mouse a lot more, the log was 100 MB
:lol:
Alexei Frounzes memory managment:
It will go into PMode, create a 4GB segment and returns back to real mode.
That 4GB segment can be used to access all PC memory (up to 4GB, of course).
inflater
Posted: Mon Oct 02, 2006 7:08 pm
by carbonBased
inflater wrote:Yep, but SETINTVEC sets ONLY INTERRUPTS, not INTERRUPT REQUESTS. Or should I use that SETINTVEC?
IRQ_INSTALL - Pascal does not have that function.
IRQs are interrupts.
irq_install(), et al are functions (or similar) that any OS will have. They install vectors into your IDT (if written correctly, the same functions can double to install vectors in your GDT).
--Jeff
Posted: Mon Oct 02, 2006 10:10 pm
by inflater
Still not working.
The whole functions in Pascal:
Code: Select all
var MouseHandler: procedure;
function inportb(port:byte): byte;
begin
asm
in al,offset port
mov al,@Result
end;
end;
procedure mouse_wait(a_type: byte);
var
time_out: longint;
begin
time_out := 100000;
if a_type = 0 then begin
repeat
Dec(time_out);
if (inportb($64) and 1) = 1 then Exit;
until (time_out = 0);
end;
Exit;
if a_type = 1 then begin
repeat
Dec(time_out);
if (inportb($64) and 2) = 0 then Exit;
until (time_out = 0);
end;
Exit;
end;
procedure mouse_write(a_write: byte);
begin
mouse_wait(1);
Port[$64] := $D4;
mouse_wait(1);
Port[$60] := a_write;
end;
function mouse_read: byte;
begin
mouse_wait(0);
Mouse_read := inportb($60);
end;
procedure mouse_install;
var _status: byte;
begin
mouse_wait(1);
Port[$64] := $A8;
mouse_wait(1);
Port[$64] := $20;
mouse_wait(0);
_status := (inportb(60) or 2);
mouse_wait(1);
Port[$64] := $60;
mouse_wait(1);
Port[$60] := _status;
mouse_write($F6);
mouse_read;
mouse_write($F4);
mouse_read;
GetIntVec($0C,@MouseHandler);
SetIntVec($0C,ADDR(mouse_install)); {What handler ??}
end;
inflater
Posted: Tue Oct 03, 2006 4:47 am
by digo_rp
maybe you should change
function inportb(port:byte): byte;
begin
asm
in al,offset port
mov al,@Result
end;
end;
to
function inportb(p:byte): byte;
begin
Result := Port[p];
end;
donĀ“t know the right sintax but you can go in that way.
Posted: Tue Oct 03, 2006 5:39 am
by gaf
carbonBased wrote:IRQs are interrupts.
In my opinion that's a bit misleading: IRQs are special interrupts that can be triggered by a hardware device. You'll have to remap the PIC to enable IRQs. I'm sorry in case that this was already obvious. From the way that inflater askes about IRQs it's just hard to tell if he has already done the required setup..
regards,
gaf
Posted: Tue Oct 03, 2006 8:41 am
by inflater
Reprogramming PIC?
Yep, it is working
Code: Select all
procedure mouse_install;
var IRQ12enable: byte;
...
...
asm
xor ax,ax
or al,4
mov IRQ12enable,al
end;
Port[$A0] := IRQ12Enable;
And result? Well, L.O.L.
But seriously,
BOCHS knew, that I'd like to write to the PIC, as said in the doc, to A0h.
How can I correct this? (and make mouse driver work
)
inflater
Posted: Wed Oct 04, 2006 10:46 am
by gaf
BOCHS knew, that I'd like to write to the PIC, as said in the doc, to A0h.
You actually have to use port 0xA1 to change the mask. Apart from that a set bit disables the corresponding interrupt, so that you should probably negate your bitmask before assigning it.
SetIntVec($0C,ADDR(mouse_install)); {What handler ??}
Mouse_install is not the handler but the initialization routine. You have to write your own ISR that gets the mouse scan-code from port 0x60 and converts it to an absolute coordinate. By default the PS/2 mouse sends 3 packages that each contain one of the dimensions {x, y, z}. The handler will be called as each package arrives and has to collect the data.
On a second though I actually think that you shouldn't remap the PIC at all: In real-mode the BIOS relies on the standard mapping (8-15 | 70-77). If you alter that mapping the BIOS won't get its interrupts any longer and may thus not work correctly.
To receive the mouse irq in real-mode you'll have to install a IVT handler for interrupt #74 (reads: number four on the second PIC). I'd also advise you to have a look at the links I provided in my first post as you'll need the information they contain to process the mouse data in your interrupt handler.
regards,
gaf