PS2 Mouse Wheel Support (#657)

This commit is contained in:
pixelsuft‮ 2022-05-21 03:26:57 +07:00 committed by GitHub
parent 77a1cc47cf
commit 56b741466a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -66,6 +66,15 @@ function PS2(cpu, bus)
/** @type {number} */
this.sample_rate = 100;
/** @type {number} */
this.intellimouse_activation_counter = 0;
/** @type {number} */
this.mouse_id = 0x00;
/** @type {number} */
this.wheel_movement = 0;
/** @type {number} */
this.resolution = 4;
@ -106,8 +115,10 @@ function PS2(cpu, bus)
this.bus.register("mouse-wheel", function(data)
{
// TODO: Mouse Wheel
// http://www.computer-engineering.org/ps2mouse/
this.wheel_movement -= data[0];
this.wheel_movement -= data[1] * 2; // X Wheel Movement
this.wheel_movement = Math.min(7, Math.max(-8, this.wheel_movement));
this.send_mouse_packet(0, 0);
}, this);
this.command_register = 1 | 4;
@ -153,6 +164,8 @@ PS2.prototype.get_state = function()
state[22] = this.read_command_register;
state[23] = this.controller_output_port;
state[24] = this.read_controller_output_port;
state[25] = this.mouse_id;
state[26] = this.intellimouse_activation_counter;
return state;
};
@ -184,6 +197,8 @@ PS2.prototype.set_state = function(state)
this.read_command_register = state[22];
this.controller_output_port = state[23];
this.read_controller_output_port = state[24];
this.mouse_id = state[25] || 0;
this.intellimouse_activation_counter = state[26] || 0;
this.next_byte_is_ready = false;
this.next_byte_is_aux = false;
@ -332,6 +347,21 @@ PS2.prototype.send_mouse_packet = function(dx, dy)
this.mouse_buffer.push(delta_x);
this.mouse_buffer.push(delta_y);
if(this.mouse_id === 0x04)
{
this.mouse_buffer.push(
0 << 5 | // TODO: 5th button
0 << 4 | // TODO: 4th button
this.wheel_movement & 0xF
);
this.wheel_movement = 0;
}
else if(this.mouse_id === 0x03)
{
this.mouse_buffer.push(this.wheel_movement); // Byte 4 - Z Movement
this.wheel_movement = 0;
}
if(PS2_LOG_VERBOSE)
{
dbg_log("adding mouse packets: " + [info_byte, dx, dy], LOG_PS2);
@ -447,7 +477,31 @@ PS2.prototype.port60_write = function(write_byte)
this.mouse_buffer.push(0xFA);
this.sample_rate = write_byte;
dbg_log("mouse sample rate: " + h(write_byte), LOG_PS2);
if(this.mouse_id === 0x03)
{
if(this.intellimouse_activation_counter === 0 && this.sample_rate === 200) this.intellimouse_activation_counter = 1;
else if(this.intellimouse_activation_counter === 1 && this.sample_rate === 200) this.intellimouse_activation_counter = 2;
else if(this.intellimouse_activation_counter === 2 && this.sample_rate === 80) {
// Host sends sample rate 200->200->80 to activate Intellimouse 4th, 5th buttons
this.intellimouse_activation_counter = 0;
this.mouse_id = 0x04;
}
else this.intellimouse_activation_counter = 0;
}
else if(this.mouse_id === 0x00)
{
if(this.intellimouse_activation_counter === 0 && this.sample_rate === 200)
this.intellimouse_activation_counter = 1;
else if(this.intellimouse_activation_counter === 1 && this.sample_rate === 100)
this.intellimouse_activation_counter = 2;
else if(this.intellimouse_activation_counter === 2 && this.sample_rate === 80) {
// Host sends sample rate 200->100->80 to activate Intellimouse wheel
this.intellimouse_activation_counter = 0;
this.mouse_id = 0x03;
}
else this.intellimouse_activation_counter = 0;
}
dbg_log("mouse sample rate: " + h(write_byte) + ", mouse id: " + h(this.mouse_id), LOG_PS2);
if(!this.sample_rate)
{
dbg_log("invalid sample rate, reset to 100", LOG_PS2);
@ -545,10 +599,13 @@ PS2.prototype.port60_write = function(write_byte)
break;
case 0xF2:
// MouseID Byte
this.mouse_buffer.push(0);
this.mouse_buffer.push(0);
dbg_log("required id: " + h(this.mouse_id), LOG_PS2);
this.mouse_buffer.push(this.mouse_id);
// this.mouse_buffer.push(this.mouse_id);
this.mouse_clicks = this.mouse_delta_x = this.mouse_delta_y = 0;
// this.send_mouse_packet(0, 0);
this.raise_irq();
break;
case 0xF3:
// sample rate
@ -572,6 +629,9 @@ PS2.prototype.port60_write = function(write_byte)
this.sample_rate = 100;
this.scaling2 = false;
this.resolution = 4;
this.intellimouse_activation_counter = 0;
this.mouse_id = 0x00;
this.wheel_movement = 0;
break;
case 0xFF:
// reset, send completion code
@ -587,6 +647,10 @@ PS2.prototype.port60_write = function(write_byte)
this.scaling2 = false;
this.resolution = 4;
this.intellimouse_activation_counter = 0;
this.mouse_id = 0x00;
this.wheel_movement = 0;
this.mouse_clicks = this.mouse_delta_x = this.mouse_delta_y = 0;
break;
@ -596,11 +660,11 @@ PS2.prototype.port60_write = function(write_byte)
this.mouse_irq();
}
else if (this.read_controller_output_port)
else if(this.read_controller_output_port)
{
this.read_controller_output_port = false;
this.controller_output_port = write_byte;
// If we ever want to implement A20 masking, here is where
// If we ever want to implement A20 masking, here is where
// we should turn the masking off if the second bit is on
}
else