PS/2 Mouse help (thread crapping epidemic, do not respond)

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
BenLunt
Member
Member
Posts: 941
Joined: Sat Nov 22, 2014 6:33 pm
Location: USA
Contact:

Re: PS/2 Mouse help

Post by BenLunt »

Sik wrote:Um, the bit you're talking about is the sign bit... that's essentially the 9th bit of the value (mouse motion is 9-bit, not 8-bit). The range is actually -255 to +255. (EDIT: oh and in case somebody wonders why not -256... mouses that return -0 are a thing sadly and you should be aware of them)
I did a little testing and I did get it a little wrong. Thanks for the correction. Take the sign bit (Xs or Ys) and or it to the 9th bit, bit 8, and sign extend to the width of the integer used.

For example, if the Xs bit is set and you have an 8-bit value of 0x01, this will be converted to a 32-bit integer as 0xFFFFFF01.

Therefore, you do have a range of -255 to +255.

Code: Select all

  int delta;
  if (Xs)
    delta = 0xFFFFFF00 | Xd;
  else
    delta = 0x00000000 | Xd;
Thank you for the correction.

Ben
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PS/2 Mouse help

Post by Brendan »

Hi,
BenLunt wrote:
Sik wrote:Um, the bit you're talking about is the sign bit... that's essentially the 9th bit of the value (mouse motion is 9-bit, not 8-bit). The range is actually -255 to +255. (EDIT: oh and in case somebody wonders why not -256... mouses that return -0 are a thing sadly and you should be aware of them)
I did a little testing and I did get it a little wrong. Thanks for the correction. Take the sign bit (Xs or Ys) and or it to the 9th bit, bit 8, and sign extend to the width of the integer used.
I'm wondering if you'd mind doing a little more testing for me...

My theory is that it may make more sense to use the overflow bit as the 9th bit, and the sign bit as the 10th, 11th, ... bits. This would give multiple possibilities depending on how the mouse handles overflow conditions (e.g. if the sign flag still works for overflow, if the other 8 movement bits are still valid, if the mouse clamps to the representable range, etc). The ideal case would be that you end up with a range from -512 to +511 with no problems at all (e.g. where "faster than +511" is just reported as +511).

More specifically, I think different mice might handle overflow in different ways, and that by treating it as "signed 11-bit integer" it'd be easier to handle each possibility (if you know the mouse's behaviour) and easier to "auto-guess" the mouse's behaviour when you don't know the mouse's behaviour (e.g. using some sort of "probability based on acceleration" logic).

Note that you might need to move the mouse quite fast to get overflow to occur. This depends on the resolution and sample rate. For example:
  • "resolution = 1 count/mm, 10 samples per second" (slowest case): you'd need to move the mouse at over 4.6 Km/h to achieve overflow (and over 9.2 Km/h to test values outside the -512 to +511 range)
  • "resolution = 1 count/mm, 200 samples per second": you'd need to move the mouse at over 25.6 Km/h to achieve overflow
  • "resolution = 8 count/mm, 200 samples per second" (fastest case): you'd need to move the mouse at over 737 Km/h to achieve overflow
For this reason I'd want to configure the mouse for "resolution = 1 count/mm, 10 samples per second" for testing the true behaviour of overflow.

The other thing I'm wondering is if the overflow flag is sticky. For example, if you move the mouse right for 1234 counts then left for 1233 counts in between samples, does the mouse report "overflowed at some point during this period" or does it report "moved right 1 count".

Sadly; I haven't been able to find any information that adequately describes the behaviour on overflow. :(


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 Mouse help

Post by Ycep »

You all seem to be ignoring me and go offtopic. Stop responding to this thread, please.
You anyways just debate about sign bit while currently I could not get a damn packet right.
I don't want somebody else to run into this thread and not realize there's a mistak
maybe you should repair your sentence:
I don't want somebody to run into their thread and not realize there's a mistak
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: PS/2 Mouse help

Post by Octacone »

Lukand wrote:You all seem to be ignoring me and go offtopic. Stop responding to this thread, please.
You anyways just debate about sign bit while currently I could not get a damn packet right.
I don't want somebody else to run into this thread and not realize there's a mistak
maybe you should repair your sentence:
I don't want somebody to run into their thread and not realize there's a mistak
Let me fix both of you:
I don't want somebody else to run into this thread and not realize there's a mistake
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 Mouse help

Post by Octocontrabass »

Lukand wrote:Waiting always times out.
Are you waiting for data from the PS/2 controller, or data from the mouse?
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: PS/2 Mouse help

Post by Octacone »

Lukand wrote:Waiting always times out.
Try my code:
When reading data:

Code: Select all

uint32_t timeout = 100000;
while(timeout--)
{
	if((Inportb(0x64) & 0x01) == 1)
	{
		return;
	}
}
When writing data:

Code: Select all

uint32_t timeout = 100000;
while(timeout--)
{
	if((Inportb(0x64) & 0x02) == 0)
	{
		return;
	}
}
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
Octocontrabass
Member
Member
Posts: 5587
Joined: Mon Mar 25, 2013 7:01 pm

Re: PS/2 Mouse help

Post by Octocontrabass »

octacone wrote:Try my code:
Your code is not better than Lukand's.
User avatar
Octacone
Member
Member
Posts: 1138
Joined: Fri Aug 07, 2015 6:13 am

Re: PS/2 Mouse help

Post by Octacone »

Octocontrabass wrote:
octacone wrote:Try my code:
Your code is not better than Lukand's.
It works so I guess it is fine. :P
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: PS/2 Mouse help

Post by BrightLight »

octacone wrote:
Octocontrabass wrote:Your code is not better than Lukand's.
It works so I guess it is fine. :P
Works != good.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
User avatar
Ycep
Member
Member
Posts: 401
Joined: Mon Dec 28, 2015 11:11 am

Re: PS/2 Mouse help

Post by Ycep »

Now only the ones that notice any problem with this code should respond.
It seems clear that problem is not in function itself, but in something else...
Through if it gives any help, there is whole new updated mouse code:

Code: Select all

void WaitSignal()//Function for waiting PS/2 semaphores
{
	uint tmo=40;
	while(tmo--)
    {
		if((inb(0x64)&2)==0)
		{
			return;
		}
		sleep(1);
    }
    return;
}
void WaitData()//Function for waiting PS/2 semaphores
{
	uint tmo=40;
	while(tmo--)
    {
		if((inb(0x64)&1)==1)
		{
			return;
		}
		sleep(1);
	}
    return;
}
void MouseSend(uint8 no, uint8* e) //Get single packet function
{
	WaitSignal();
	outb(0x64, 0xD4);
	WaitSignal();
	outb(0x60, 0xEB);//Send command
	inb(0x60);//Get ACK
	for(uint8 i=0;i<no;i++)
	{
		WaitData();
		e[i]=inb(0x60);//Take one byte
	}
}
_declspec(naked) void EmptyInterrupt()
{
	__asm
	{
		mov dx, 0x20
		mov al, 0x20
		out dx, al
		iretd
	}
}
bool InitMouse()
{
	setvect(0x2C,EmptyInterrupt); //Empty interrupt to avoid warning messages
	WaitSignal();
	outb(0x64, 0xA8); //Enable aux port
	inb(0x60);
	WaitSignal();
	outb(0x64, 0x20); //Get status byte
	WaitData();
	uint8 stat=(inb(0x60)|2)^0x20;
	WaitSignal();
	outb(0x64, 0x60);
	WaitSignal();
	outb(0x60, stat);
	return 1;
}
I will try some tests and debugging to make timing out stop.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: PS/2 Mouse help

Post by gerryg400 »

Lukand, what does 'sleep(1)' do ?
If a trainstation is where trains stop, what is a workstation ?
hannah
Member
Member
Posts: 34
Joined: Wed Oct 12, 2016 11:32 am
Location: At my PC

Re: PS/2 Mouse help

Post by hannah »

gerryg400 wrote:Lukand, what does 'sleep(1)' do ?

Code: Select all

void sleep(int16 ms)
{
	uint need=ms+ticks;
	while(need>ticks)
	{
		//nextTask(), or whatever it needs to be in future
	}
}
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: PS/2 Mouse help

Post by Schol-R-LEA »

@Hannah: Is this Lukand's sleep() function, then? I wasn't able to locate it or anything else regarding scheduling in the Nutoak Github repo, but that doesn't appear to have been updated in the past two months, so I don't know if he's moved the repo somewhere else, or hasn't used it for some other reason.

Before I comment further, let me say that I don't have enough information to say if this actually might having anything to do with the problem at hand - I am following gerryg400's lead in this, and at this point only Lukand could say whether this is a relevant topic or not.

Now, to continue: if this is the sleep() function in question, it presents a significant problem, as it seems to be designed to busy-wait on the timer ticks. The comment seems to indicate that the process is meant to cede the CPU to the scheduler inside the loop at the point which is currently commented out, but in the absence of anything else, it will simply spin in place, modulo the timer interrupts, until the ticks variable (which is presumably a global variable in the kernel which is being updated by the timer interrupt handler) exceeds the computed amount of time (saved in a local variable in the function).

I don't want to say too much about this, given that we don't know about the implementation of the scheduler or the interrupt handlers. However, I will refine gerryg400's question by asking: a) will one tick (which seems to be equated to one millisecond) be sufficient time for the wait on this operation, b) what are the time resolutions of the scheduler and the timer interrupt handler, c) approximately how many clock cycles does the timer interrupt handler use in computing each tick, and d) how do you reconcile any RTC drift this might cause in the ticks variable?

Admittedly, I don't even know if these questions make sense in your current design, but they seem to be relevant from what I have seen so far.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
hannah
Member
Member
Posts: 34
Joined: Wed Oct 12, 2016 11:32 am
Location: At my PC

Re: PS/2 Mouse help

Post by hannah »

Schol-R-LEA wrote:@Hannah: Is this Lukand's sleep() function, then? I wasn't able to locate it or anything else regarding scheduling in the Nutoak Github repo, but that doesn't appear to have been updated in the past two months, so I don't know if he's moved the repo somewhere else, or hasn't used it for some other reason.

Before I comment further, let me say that I don't have enough information to say if this actually might having anything to do with the problem at hand - I am following gerryg400's lead in this, and at this point only Lukand could say whether this is a relevant topic or not.

Now, to continue: if this is the sleep() function in question, it presents a significant problem, as it seems to be designed to busy-wait on the timer ticks. The comment seems to indicate that the process is meant to cede the CPU to the scheduler inside the loop at the point which is currently commented out, but in the absence of anything else, it will simply spin in place, modulo the timer interrupts, until the ticks variable (which is presumably a global variable in the kernel which is being updated by the timer interrupt handler) exceeds the computed amount of time (saved in a local variable in the function).

I don't want to say too much about this, given that we don't know about the implementation of the scheduler or the interrupt handlers. However, I will refine gerryg400's question by asking: a) will one tick (which seems to be equated to one millisecond) be sufficient time for the wait on this operation, b) what are the time resolutions of the scheduler and the timer interrupt handler, c) approximately how many clock cycles does the timer interrupt handler use in computing each tick, and d) how do you reconcile any RTC drift this might cause in the ticks variable?

Admittedly, I don't even know if these questions make sense in your current design, but they seem to be relevant from what I have seen so far.
https://github.com/lukaandjelkovic/Nuto ... /conio.cpp
User avatar
Schol-R-LEA
Member
Member
Posts: 1925
Joined: Fri Oct 27, 2006 9:42 am
Location: Athens, GA, USA

Re: PS/2 Mouse help

Post by Schol-R-LEA »

facepalm Yeah, that is where I would expect to find that, sure.

OK, I will admit that I didn't look there, because... well, I assumed it would be in with the scheduling stuff, and I never found any. I need to make fewer assumptions of that sort, it seems.
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.
Locked