mame
mame copied to clipboard
logitech_mouse breaks LMOUSE.DRV in Windows 3.1
By default, at386 plugs a logitech_mouse in the first serial port. When installing win31, this gets detected as "Logitech", and the LMOUSE.DRV driver is installed. When the setup then switches to Windows mode, it hangs forever. Changing the mouse type to "Microsoft" (or plugging microsoft_mouse into the serial port instead) mitigates this, which makes me suspect there's something wrong with the logitech implementation in hlemouse.cpp.
To repro this:
- run
at386 -hard1 win31(win31comes from from https://github.com/mamedev/mame/pull/7192) - go to Windows Setup - Options - Change System Settings, pick Logitech in the Mouse dropdown, confirm
- plug in the requested floppy from the
win31set and let it install the driver - restart Windows, notice it hangs forever now
This also repros with wfw311, and with at486 / ct486.
This has been reported before, and it confuses me. The Logitech mouse in MAME does work correctly with the CuteMouse driver for DOS and follows the description of the protocol in the Linux mouse(4) man page. There’s something going wrong somewhere, but I’m honestly at a loss to know what it is. The code provided the fourth report byte for the additional button state whenever the additional button is depressed and on the first report after it’s released, which is what CuteMouse and Linux expect. Is there any more detail on what Windows 3 wants or why it goes wrong?
Also quoting from https://www.kryslix.com/nsfaq/Q.12.html (it has a bad certificate):
Logitech extended the 2 button mouse protocol to support 3 button mice by adding a 4th byte when the middle button is pressed (and the first packet after it is released). If a 4th byte is encountered (i.e., an extra byte with D6 set to 0) then D5 of that byte (0x20) indicates the status of the middle mouse button.
I don't know whether this has anything to do with this issue, but there appears to be a copy-and-paste error in hle_msmouse_device_base::input_rts.
Ah yes, that does appear to be an error.
After fixing that, and adding some debug logging, it looks like the logitech driver sends some stuff over (maybe to negotiate speed / protocol?), and it likely expects a reply. Compare: microsoft driver:
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
logitech driver
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] received byte 00000044
[:board2:comat:serport0:logitech_mouse] received byte 00000073
[:board2:comat:serport0:logitech_mouse] received byte 00000070
[:board2:comat:serport0:logitech_mouse] received byte 00000075
[:board2:comat:serport0:logitech_mouse] received byte 0000007e
[:board2:comat:serport0:logitech_mouse] received byte 0000007d
[:board2:comat:serport0:logitech_mouse] received byte 0000007f
[:board2:comat:serport0:logitech_mouse] received byte 0000007f
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] dtr
[:board2:comat:serport0:logitech_mouse] rts
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] received byte 0000002a
and that was done with
diff --git a/src/devices/bus/rs232/hlemouse.cpp b/src/devices/bus/rs232/hlemouse.cpp
index a6452b9dcef..96d81523b94 100644
--- a/src/devices/bus/rs232/hlemouse.cpp
+++ b/src/devices/bus/rs232/hlemouse.cpp
@@ -66,6 +66,9 @@
#include "emu.h"
#include "hlemouse.h"
+#define VERBOSE 1
+#include "logmacro.h"
+
#include <cassert>
#include <cmath>
@@ -241,13 +244,15 @@ void hle_msmouse_device_base::device_start()
WRITE_LINE_MEMBER(hle_msmouse_device_base::input_dtr)
{
+ LOG("dtr\n");
m_dtr = state ? 1U : 0U;
check_enable();
}
WRITE_LINE_MEMBER(hle_msmouse_device_base::input_rts)
{
- m_dtr = state ? 1U : 0U;
+ LOG("rts\n");
+ m_rts = state ? 1U : 0U;
check_enable();
}
@@ -260,6 +265,7 @@ void hle_msmouse_device_base::tra_complete()
void hle_msmouse_device_base::received_byte(u8 byte)
{
+ LOG("received byte %08x\n", byte);
}
@@ -355,6 +361,7 @@ ioport_constructor hle_logitech_mouse_device::device_input_ports() const
void hle_logitech_mouse_device::reset_and_identify()
{
+ LOG("logitech reset\n");
// assume ASCII host system
transmit_byte('M');
transmit_byte('3');
If I hardcode the baudrate to 2400 it doesn't hang anymore, but the mouse doesn't work at all. The data the driver sends over is a bit different:
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] received byte 00000060
[:board2:comat:serport0:logitech_mouse] received byte 0000007e
[:board2:comat:serport0:logitech_mouse] received byte 0000001e
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000044
[:board2:comat:serport0:logitech_mouse] received byte 00000073
[:board2:comat:serport0:logitech_mouse] received byte 00000070
[:board2:comat:serport0:logitech_mouse] received byte 00000075
[:board2:comat:serport0:logitech_mouse] received byte 0000007e
[:board2:comat:serport0:logitech_mouse] received byte 0000007d
Same for 4800, where I get
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000060
[:board2:comat:serport0:logitech_mouse] received byte 0000007e
[:board2:comat:serport0:logitech_mouse] received byte 0000001e
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000044
[:board2:comat:serport0:logitech_mouse] received byte 00000073
[:board2:comat:serport0:logitech_mouse] received byte 00000070
[:board2:comat:serport0:logitech_mouse] received byte 00000075
and 9600
[:board2:comat:serport0:logitech_mouse] logitech reset
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000000
[:board2:comat:serport0:logitech_mouse] received byte 00000060
[:board2:comat:serport0:logitech_mouse] received byte 0000007e
[:board2:comat:serport0:logitech_mouse] received byte 0000001e
[:board2:comat:serport0:logitech_mouse] received byte 00000078
[:board2:comat:serport0:logitech_mouse] received byte 00000044
[:board2:comat:serport0:logitech_mouse] received byte 00000073
Some (possibly) helpful information in https://github.com/FreeBSDDesktop/freebsd-base/blob/master/usr.sbin/moused/moused.c#L1591
Apparently it works fine in 86Box. Here's the code that emulates the Logitech serial mouse in 86Box. https://github.com/86Box/86Box/blob/master/src/device/mouse_serial.c
Ok, the actual protocol is described here (specifically, section 14.10): http://www.bitsavers.org/pdf/logitech/Logitech_Logimouse_C7_Firmware_Rev_3.0_Jan86.pdf
Specifically, it looks like the driver attempts to enable prompt mode (44), request status (73) and set speed to 4800 baud (70).
Since changing hosts, Bitsavers is now black-holing traffic from at least half the world. This document doesn’t appear to be on a mirror I just checked.
I put it up here: https://drive.google.com/file/d/15vZMlrFveS21FaWmOQFWBL9ohxK-aIDP/view?usp=sharing and the whole folder at https://drive.google.com/file/d/19RCe08yLYAUqWv9vxdNJUrFQqsodm7UM/view?usp=sharing
Note that this isn't quite the complete story, as there's a few extra commands (like the mode selection stuff like *X mentioned in the freebsd source I linked above) that were likely added later and aren't covered there. Bitsavers also has an actual ROM of this C7 mouse (also in the folder), but I don't know how easy that would be to get running (it's marked as a LSC82406P / MC1146805F2, and I couldn't find an equivalent in MAME, nor a datasheet).
Just thought I'd add that I just ran into this problem a day or two ago with the latest release of MAME (0.258). The workaround of switching away from the default Logitech mouse to the Microsoft mouse allowed the Windows 3.1 Setup program to complete it's switch to Windows mode.