Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ CARGO_FLAGS_SAFE=\
CARGO_FLAGS=$(CARGO_FLAGS_SAFE) -C target-feature=+bulk-memory -C target-feature=+multivalue -C target-feature=+simd128

CORE_FILES=cjs.js const.js io.js main.js lib.js buffer.js ide.js pci.js floppy.js \
dma.js pit.js vga.js ps2.js rtc.js uart.js \
dma.js pit.js vga.js ps2.js rtc.js uart.js vmware.js \
acpi.js iso9660.js \
state.js ne2k.js sb16.js virtio.js virtio_console.js virtio_net.js virtio_balloon.js \
bus.js log.js cpu.js \
Expand Down
12 changes: 12 additions & 0 deletions docs/windows-9x.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ The default VGA display driver only supports 640x480x4 video mode, to fix this,
5. Select "VESA ISA" adapter and press "OK".
6. After installing, restart Windows.

## Enabling absolute mouse positioning (VBMOUSE)

v86 emulates the VMware absolute pointing device. With an absolute mouse driver installed in the guest, the guest cursor follows the host cursor directly, without having to lock the mouse.

[VBADOS](https://git.javispedro.com/cgit/vbados.git/about/) provides VBMOUSE, an open-source DOS mouse driver with VMware mouse support, together with a 16-bit Windows mouse driver on top of it that Windows 9x can use.

1. Download [vbados.flp](https://depot.javispedro.com/vbox/vbados/vbados.flp) and mount it as a floppy image (or copy its contents into the guest in some other way).
2. Copy `VBMOUSE.EXE` from the floppy to the hard disk (for example to `C:\VBADOS`) and `VBMOUSE.DRV` to `C:\WINDOWS\SYSTEM`.
3. Add `C:\VBADOS\VBMOUSE.EXE` to `C:\AUTOEXEC.BAT`, so the DOS part of the driver is loaded before Windows starts.
4. In `C:\WINDOWS\SYSTEM.INI`, change the `mouse.drv` line in the `[boot]` section to `mouse.drv=vbmouse.drv`.
5. Restart Windows.

## CPU idling on Windows 95
See about [installing AmnHLT](cpu-idling.md#windows-9x-using-amnhlt).

Expand Down
12 changes: 11 additions & 1 deletion src/browser/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2681,6 +2681,7 @@ function init_ui(profile, settings, emulator)
var last_instr_counter = 0;
var interval = null;
var os_uses_mouse = false;
var os_uses_absolute_mouse = false;
var total_instructions = 0;

function update_info()
Expand Down Expand Up @@ -2828,6 +2829,11 @@ function init_ui(profile, settings, emulator)
$("info_mouse_enabled").textContent = is_enabled ? "Yes" : "No";
});

emulator.add_listener("vmware-absolute-mouse", function(is_enabled)
{
os_uses_absolute_mouse = is_enabled;
});

emulator.add_listener("screen-set-size", function(args)
{
const [w, h, bpp] = args;
Expand Down Expand Up @@ -3216,7 +3222,11 @@ function init_ui(profile, settings, emulator)
emulator.speaker_adapter.audio_context.resume();
}

if(mouse_is_enabled && os_uses_mouse)
// No need to lock the mouse if the guest tracks the host cursor
// through the absolute pointing device. The "Lock mouse" button can
// still be used, e.g. for games (movement is then sent as relative
// deltas).
if(mouse_is_enabled && os_uses_mouse && !os_uses_absolute_mouse)
{
emulator.lock_mouse();
}
Expand Down
11 changes: 10 additions & 1 deletion src/browser/mouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export function MouseAdapter(bus, screen_container)
window.removeEventListener("mousedown", mousedown_handler, false);
window.removeEventListener("mouseup", mouseup_handler, false);
window.removeEventListener("wheel", mousewheel_handler, { passive: false });
document.removeEventListener("pointerlockchange", pointerlockchange_handler, false);
};

this.init = function()
Expand All @@ -75,9 +76,15 @@ export function MouseAdapter(bus, screen_container)
window.addEventListener("mousedown", mousedown_handler, false);
window.addEventListener("mouseup", mouseup_handler, false);
window.addEventListener("wheel", mousewheel_handler, { passive: false });
document.addEventListener("pointerlockchange", pointerlockchange_handler, false);
};
this.init();

function pointerlockchange_handler()
{
mouse.bus.send("mouse-pointer-lock", !!document.pointerLockElement);
}

function is_child(child, parent)
{
while(child.parentNode)
Expand Down Expand Up @@ -225,7 +232,9 @@ export function MouseAdapter(bus, screen_container)

mouse.bus.send("mouse-delta", [delta_x, delta_y]);

if(screen_container)
// Under pointer lock the page coordinates don't change, so no
// meaningful absolute position can be reported
if(screen_container && !document.pointerLockElement)
{
const absolute_x = e.pageX - screen_container.offsetLeft;
const absolute_y = e.pageY - screen_container.offsetTop;
Expand Down
14 changes: 14 additions & 0 deletions src/browser/starter.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,20 @@ V86.prototype.continue_init = async function(emulator, options)
this.mouse_adapter = new MouseAdapter(this.bus, screen_options.container);
}

// Pointer lock is not needed while the guest uses absolute pointer
// positions (the guest cursor follows the host cursor), so release it
// when the guest driver enables absolute positioning
this.absolute_pointer_enabled = false;
this.bus.register("vmware-absolute-mouse", function(enabled)
{
if(enabled && !this.absolute_pointer_enabled &&
typeof document !== "undefined" && document.pointerLockElement)
{
document.exitPointerLock();
}
this.absolute_pointer_enabled = enabled;
}, this);

if(screen_options.container)
{
this.screen_adapter = new ScreenAdapter(screen_options, () => this.v86.cpu.devices.vga && this.v86.cpu.devices.vga.screen_fill_buffer());
Expand Down
4 changes: 4 additions & 0 deletions src/cpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { IO } from "./io.js";
import { VirtioConsole } from "./virtio_console.js";
import { PCI } from "./pci.js";
import { PS2 } from "./ps2.js";
import { VMwareMouse } from "./vmware.js";
import { read_elf } from "./elf.js";

import { FloppyController } from "./floppy.js";
Expand Down Expand Up @@ -570,6 +571,7 @@ CPU.prototype.get_state = function()
state[86] = this.last_result;
state[87] = this.fpu_status_word;
state[88] = this.mxcsr;
state[89] = this.devices.vmware;

return state;
};
Expand Down Expand Up @@ -738,6 +740,7 @@ CPU.prototype.set_state = function(state)
this.devices.virtio_console && this.devices.virtio_console.set_state(state[82]);
this.devices.virtio_net && this.devices.virtio_net.set_state(state[83]);
this.devices.virtio_balloon && this.devices.virtio_balloon.set_state(state[84]);
this.devices.vmware && state[89] && this.devices.vmware.set_state(state[89]);

this.fw_value = state[62];

Expand Down Expand Up @@ -1176,6 +1179,7 @@ CPU.prototype.init = function(settings, device_bus)
this.devices.vga = new VGAScreen(this, device_bus, settings.screen, settings.vga_memory_size || 8 * 1024 * 1024);

this.devices.ps2 = new PS2(this, device_bus);
this.devices.vmware = new VMwareMouse(this, device_bus);

this.devices.uart0 = new UART(this, 0x3F8, device_bus);

Expand Down
Loading
Loading