VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've implemented an UART clock (as documented), which is further divided with 1 start bit, 5-8 data bits and 1 or 2 stop bits to get the rate at which data is received(and checked if available) from the (in this case) connected serial mouse.

Most of the interface is unchanged, only the receive timing is now timed according to the start/data/stop bits(in whole packets receiving a byte of data).

UART code: https://bitbucket.org/superfury/unipcemu/src/ … art.c?at=master
Serial mouse plugged in to the first UART (COM) port: https://bitbucket.org/superfury/unipcemu/src/ … use.c?at=master

For some reason the mouse drivers aren't recognizing the serial mouse anymore. Also Windows 3.0 crashes when it receives mouse events from it(before the latest two commits)?

Anyone can see what's going wrong? Jepael? Reenigne?

Last edited by superfury on 2016-09-25, 17:41. Edited 1 time in total.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 7, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

Usually the mouse responds with a single 'M' letter after it is reset (don't remember if RTS or DTR resets it), not several. One should be enough.

T the calculation of data bits per frame is somewhat off.

First of all, the stop bits calculation is weird. The stop bit selection is either 0 or 1, and it means 1 or 2 stop bits. Shifting it left gives you 0 or 2 stop bits, no stop bits can't be right. OK, there is a very obscure case where with 5 data bits there is 1.5 stop bits instead of two, but who would use it.

You also don't calculate whether parity bit is sent or not.

Fortunately MS mice use 1200 bit rate, with 1 start, 7 data, no parity, 1 stop, I think, so there's 9 bit times between received bytes. So it can send 133 bytes per second, or up to 44 three byte packets, if they are sent back-to-back. I recall that sometimes mice send with 2 stop bits, so that bytes are not completely back-to-back, and it does not matter if PC receives with one stop bit (7N1) or two stop bits (7N2 or 8N1 where MSB is ignored), and that will make 10 bit times per byte or 120 bytes per second or 40 packets per second.

Edit: Other than that, the timings seem to be as expected. The crystal runs at 115200*16 Hz which means the max bit rate is 115200. I also think divisor of 0 does not mean 65536, it is something undefined, based on warnings about not loading with 0.

Reply 2 of 7, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've found this article: https://courses.cit.cornell.edu/ee476/FinalPr … 476finalweb.htm

So DTR and RTS are toggled both to receive a 'M' character when both raised. Will it start streaming immediately? Or does this require other lines to be set? It says microsoft toggles RTS to make it send the M character, but it also says it toggles both RTS and DTR to make it do that? But if so, how does the chip(connected serial mouse) know it can start sending packets? Also, does it send M on both RTS&DTR or just RTS being raised? What does the DTR line do on a real Microsoft serial mouse?

Also: http://www.cpcwiki.eu/index.php/Serial_RS232_Mouse (with the same RTS&DTR issue highlighted).

Looking at some other documentation: http://simmiyy.altervista.org/files/Serial.Port.pdf

That says it needs DTR&RTS to function correctly, while toggling RTS off and on makes it send that 'M' detection byte?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 7, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

I think mice are different. You need to just cope with that or see how MS driver detects MS mouse or 3-button driver detects 3-button mice so you can emulate a specific mouse if you like.

For what I can tell about my experience, which I recall was not manufactured by MS, the RTS is either power or reset to the mouse controller chip, so when it goes into powered-on/not-reset state the mouse controller boots up and sends the 'M' letter.

DTR does not affect the mouse controller chip, but might be used to power the rotary encoder LEDs, I recall the mouse was succesfully detected but it was not able to detect movement.

TXD to mouse may also be used for power.

Mouse does not know when it can send packets, when it has power it will send the 'M' and if there is movement it sends packets. There is no continuous stream of packets, if there is no movement, there is no packets.

Reply 4 of 7, by superfury

User metadata
Rank l33t++
Rank
l33t++

Ok. So the RTS bit being set makes it power on and send a M byte. It needs DTR to detect movement, but button presses will still work. Packets are sent while RTS=1.

What happens to partially sent packets when RTS becomes 0? Are they discarded(chip powers off)?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 7, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

What happens to partially sent packets when RTS becomes 0? Are they discarded(chip powers off)?

It's the same as unplugging the mouse. The mouse chip loses power or goes into reset.

Reply 6 of 7, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've tried rewriting the mouse movement emulation and increasing the range to it's full 8-bits instead of it's old 7-bits, as well as applying clipping to prevent invalid movements.

https://bitbucket.org/superfury/unipcemu/src/ … use.c?at=master

For some reason mouse movement acts a bit strange (in Windows 3.0)? It moves in strange ways?

Can anyone see what goes wrong in the new mouse packet movement data? Maybe a sign or movement data conversion error? The movement data supplied to the handler is 8-bits movement data(and used for both PS/2 and Serial Mouse input, which is toggable in the settings menu of UniPCemu).

Jepael?

This is my current coordinate conversion and buffering routine:

byte buttons = 0;
SERMouse.buttons = packet->buttons; //Save last button status!
//Convert buttons (packet=1=left, 2=right, 4=middle) to output (1=right, 2=left)!
buttons = packet->buttons; //Left/right/middle mouse button!
buttons &= 3; //Only left&right mouse buttons!
buttons = (buttons >> 1) | ((buttons & 1) << 1); //Left mouse button and right mouse buttons are switched in the packet vs our mouse handler packet!
byte highbits;
byte xmove, ymove;
//Translate our movement to valid values if needed!
xmove = ((packet->xmove)<0)?((MAX(packet->xmove,-0x80)&0x7F)|0x80):(MIN(packet->xmove,0x7F)&0x7F); //X movement data!
ymove = ((packet->ymove)<0)?((MAX(packet->ymove,-0x80)&0x7F)|0x80):(MIN(packet->ymove,0x7F)&0x7F); //Y movement data!

if (SERMouse.movement==0) //Not gotten movement masked?
{
xmove = ymove = 0; //No movement!
}
//Bits 0-1 are X6&X7. Bits 2-3 are Y6&Y7. They're signed values.
highbits = ((xmove >> 6) & 0x3); //X6&X7 to bits 0-1!
highbits |= ((ymove >> 4) & 0xC); //Y6&7 to bits 2-3!
writefifobuffer(SERMouse.buffer, 0x40 | (buttons << 4) | highbits); //Give info and buttons!
writefifobuffer(SERMouse.buffer, (xmove&0x3F)); //X movement!
writefifobuffer(SERMouse.buffer, (ymove&0x3F)); //Y movement!

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 7 of 7, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've fixed the emulator. Now Windows 3.0 runs properly again:)

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io