aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--int15ps2.h13
-rw-r--r--int2fwin.h2
-rw-r--r--mousetsr.c78
-rw-r--r--mousetsr.h8
-rw-r--r--mousmain.c2
5 files changed, 80 insertions, 23 deletions
diff --git a/int15ps2.h b/int15ps2.h
index 95bedf7..438dfd8 100644
--- a/int15ps2.h
+++ b/int15ps2.h
@@ -31,10 +31,10 @@
typedef uint8_t ps2m_err;
enum ps2m_errors {
PS2M_ERR_INVALID_FUNCTION = 1,
- PSM2_ERR_INVALID_INPUT = 2,
- PSM2_ERR_INTERFACE_ERROR = 3,
- PSM2_ERR_RESEND = 4,
- PSM2_ERR_NO_CALLBACK = 5,
+ PS2M_ERR_INVALID_INPUT = 2,
+ PS2M_ERR_INTERFACE_ERROR = 3,
+ PS2M_ERR_RESEND = 4,
+ PS2M_ERR_NO_CALLBACK = 5,
};
enum ps2m_status {
@@ -48,8 +48,9 @@ enum ps2m_status {
};
enum ps2m_packet_size {
- PS2M_PACKET_SIZE_PLAIN = 3,
- PS2M_PACKET_SIZE_EXT = 4,
+ PS2M_PACKET_SIZE_STREAMING = 1,
+ PS2M_PACKET_SIZE_PLAIN = 3,
+ PS2M_PACKET_SIZE_EXT = 4,
};
enum ps2m_device_ids {
diff --git a/int2fwin.h b/int2fwin.h
index 255cdd7..abd5f2e 100644
--- a/int2fwin.h
+++ b/int2fwin.h
@@ -45,6 +45,8 @@ enum int2f_functions
{
/** Notification sent when Windows386 is starting up. */
INT2F_NOTIFY_WIN386_STARTUP = 0x1605,
+ /** Notification sent when Windows386 is terminating. */
+ INT2F_NOTIFY_WIN386_SHUTDOWN = 0x1606,
/** Notification sent by a VxD that wants to invoke a function in a real-mode driver. */
INT2F_NOTIFY_DEVICE_CALLOUT = 0x1607,
diff --git a/mousetsr.c b/mousetsr.c
index 406727b..3acbda1 100644
--- a/mousetsr.c
+++ b/mousetsr.c
@@ -846,19 +846,34 @@ static void handle_ps2_packet(void)
/** PS/2 BIOS calls this routine to notify mouse events.
* In our case, each time we receive a byte from the mouse. */
-static void ps2_mouse_handler(unsigned byte)
+static void ps2_mouse_handler(uint16_t word0, uint16_t word1, uint16_t word2, uint16_t word3)
{
-#pragma aux ps2_mouse_handler "*" parm caller [ax] modify [ax bx cx dx si di es fs gs]
+#pragma aux ps2_mouse_handler "*" parm caller [ax] [bx] [cx] [dx] modify [ax bx cx dx si di es fs gs]
uint16_t ticks = bda_get_tick_count_lo();
+ // Are we using the BIOS in 3-packet mode directly?
+ if (data.bios_packet_size == PS2M_PACKET_SIZE_PLAIN) {
+ // Just forward it to the full packet handler.
+ data.ps2_packet[0] = word0;
+ data.ps2_packet[1] = word1;
+ data.ps2_packet[2] = word2;
+ (void) word3;
+ handle_ps2_packet();
+ return;
+ }
+
+ // Otherwise we are using the BIOS in 1-packet size mode,
+ // receiving one byte at a time.
+ // We have to compute synchronization ourselves.
+
#if TRACE_EVENTS
dlog_print("ps2 callback byte ");
dlog_printd(1 + data.cur_packet_bytes);
dlog_putc('/');
dlog_printd(data.packet_size);
dlog_putc('=');
- dlog_printx(byte & 0xFF);
+ dlog_printx(word0 & 0xFF);
dlog_endline();
#endif /* TRACE_EVENTS */
@@ -876,10 +891,10 @@ static void ps2_mouse_handler(unsigned byte)
data.cur_packet_ticks = ticks;
}
- data.ps2_packet[data.cur_packet_bytes] = byte;
+ data.ps2_packet[data.cur_packet_bytes] = word0;
data.cur_packet_bytes++;
- if (data.cur_packet_bytes == data.packet_size) {
+ if (data.cur_packet_bytes >= data.packet_size) {
handle_ps2_packet();
data.cur_packet_bytes = 0;
}
@@ -904,9 +919,9 @@ void __declspec(naked) __far ps2_mouse_callback()
pop ds
mov ax,[bp+28+6] ; Status
- ; mov bx,[bp+28+4] ; X
- ; mov cx,[bp+28+2] ; Y
- ; mov dx,[bp+28+0] ; Z
+ mov bx,[bp+28+4] ; X
+ mov cx,[bp+28+2] ; Y
+ mov dx,[bp+28+0] ; Z
call ps2_mouse_handler
@@ -959,24 +974,53 @@ static void set_absolute(bool enable)
static void reset_mouse_hardware()
{
+ int err;
+
// Stop receiving bytes...
ps2m_enable(false);
- // Let the BIOS know we want every packet separately
- // This also resets the mouse
- ps2m_init(1);
-
+ data.bios_packet_size = PS2M_PACKET_SIZE_STREAMING; // Default to use the BIOS in streaming mode
data.packet_size = PS2M_PACKET_SIZE_PLAIN;
data.cur_packet_bytes = 0;
data.cur_packet_ticks = 0;
+#if USE_WIN386
+ if (data.haswin386) {
+ uint8_t device_id;
+ // Normally, win386 does not support anything except PS2M_PACKET_SIZE_PLAIN
+ // However, if we detect our special wheelvkd driver is running...
+ err = ps2m_get_device_id(&device_id);
+ if (err || device_id != PS2M_DEVICE_ID_IMPS2) {
+ // Our special driver is not running...
+ dlog_puts("Windows running, using plain packet size");
+ data.bios_packet_size = PS2M_PACKET_SIZE_PLAIN;
+ }
+ }
+#endif
+
+ // Try to init PS/2 BIOS with desired packet size / streaming mode
+ err = ps2m_init(data.bios_packet_size);
+
+ if (err && data.bios_packet_size != PS2M_PACKET_SIZE_PLAIN) {
+ // However, if there is an error, drop down to plain packet size
+ // Emulators like DOSBox don't support anything but plain packet size
+ dlog_puts("BIOS didn't support streaming mode, using plain packet size");
+ data.bios_packet_size = PS2M_PACKET_SIZE_PLAIN;
+ err = ps2m_init(data.bios_packet_size);
+ }
+ if (err) {
+ dlog_puts("error on ps2m_init during reset, ignoring");
+ }
+
#if USE_WHEEL
- if (data.usewheel && ps2m_detect_wheel()) {
+ if (data.usewheel
+ && data.bios_packet_size == PS2M_PACKET_SIZE_STREAMING
+ && ps2m_detect_wheel()) {
dlog_puts("PS/2 wheel detected");
data.haswheel = true;
data.packet_size = PS2M_PACKET_SIZE_EXT;
} else {
- dlog_puts("PS/2 wheel NOT detected");
+ if (data.usewheel) dlog_puts("PS/2 wheel NOT detected");
data.haswheel = false;
}
#endif
@@ -1422,6 +1466,12 @@ static void int2f_handler(union INTPACK r)
data.w386_instance[1].size = 0;
r.x.es = FP_SEG(&data.w386_startup);
r.x.bx = FP_OFF(&data.w386_startup);
+ data.haswin386 = true;
+ break;
+ case INT2F_NOTIFY_WIN386_SHUTDOWN:
+ dlog_puts("Windows is stopping");
+ data.haswin386 = false;
+ data.w386cursor = false;
break;
case INT2F_NOTIFY_DEVICE_CALLOUT:
switch (r.x.bx) {
diff --git a/mousetsr.h b/mousetsr.h
index 5e10afa..68377ab 100644
--- a/mousetsr.h
+++ b/mousetsr.h
@@ -110,9 +110,11 @@ typedef struct tsrdata {
/** Whether the current mouse has a wheel (and support is enabled). */
bool haswheel;
#endif
- /** Packet size that we are currently using. */
+ /** Packet size that the BIOS is currently using. Either 1 (streaming) or 3 (plain). */
+ uint8_t bios_packet_size;
+ /** Packet size that we are currently expecting internally. Usually 3 (plain) or 4 (with wheel). */
uint8_t packet_size;
- /** Number of bytes received so far (< packet_size). */
+ /** For streaming mode: number of bytes received so far (< packet_size). */
uint8_t cur_packet_bytes;
/** Stores the bytes received so far (cur_bytes). */
uint8_t ps2_packet[MAX_PS2_PACKET_SIZE];
@@ -195,6 +197,8 @@ typedef struct tsrdata {
/** Information that we pass to Windows 386 on startup. */
win386_startup_info w386_startup;
win386_instance_item w386_instance[2];
+ /** Whether Windows 386 is running. */
+ bool haswin386 : 1;
/** Whether Windows 386 is rendering the cursor for us,
* and therefore we should hide our own. */
bool w386cursor : 1;
diff --git a/mousmain.c b/mousmain.c
index 72b5b09..90e5e5c 100644
--- a/mousmain.c
+++ b/mousmain.c
@@ -246,7 +246,7 @@ static int configure_driver(LPTSRDATA data)
dlog_init();
// Check for PS/2 mouse BIOS availability
- if ((err = ps2m_init(1))) {
+ if ((err = ps2m_init(PS2M_PACKET_SIZE_PLAIN))) {
fprintf(stderr, "Cannot init PS/2 mouse BIOS, err=%d\n", err);
// Can't do anything without PS/2
return err;