aboutsummaryrefslogtreecommitdiff
path: root/mousmain.c
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2026-08-30 03:39:32 +0200
committerJavier <dev.git@javispedro.com>2026-08-30 03:39:32 +0200
commit9104ab9ab59c5b23e12a174368062b4bc166359f (patch)
treecd8579255230aa7d53bda82faac69bfa4538920c /mousmain.c
parentb1e5bd8d67179f24f3603fad22ea928357f6b164 (diff)
downloadvbados-9104ab9ab59c5b23e12a174368062b4bc166359f.tar.gz
vbados-9104ab9ab59c5b23e12a174368062b4bc166359f.zip
allow for 'vbados reconf' command to re-search for mouse and reconfigure driver
Diffstat (limited to 'mousmain.c')
-rw-r--r--mousmain.c201
1 files changed, 129 insertions, 72 deletions
diff --git a/mousmain.c b/mousmain.c
index 23dd2e3..2b6a2ab 100644
--- a/mousmain.c
+++ b/mousmain.c
@@ -424,22 +424,22 @@ static int configure_driver(LPTSRDATA data, unsigned num_ports, int ports[])
{
int errs[MAX_PORTS+1] = {0};
unsigned portidx;
+ bool found_mouse = false;
// Configure the debug logging port
dlog_init();
+ // Search for a mouse
for (portidx = 0; portidx < num_ports; portidx++) {
int port = ports[portidx];
if (port == 0) {
// PS/2
int err = configure_driver_ps2(data);
if (!err) {
- unsigned num_wheels = 0;
-#if USE_WHEEL
- num_wheels = data->num_wheels;
-#endif
- printf(_(1, 0, "Found PS/2 mouse with %u buttons, %u wheels\n"), data->num_buttons, num_wheels);
- return 0;
+ printf(_(1, 0, "Found PS/2 mouse with %u buttons, %u wheels\n"),
+ data->num_buttons, data->num_wheels);
+ found_mouse = true;
+ break;
} else {
// Remember error to print out later only if no mouse was found
errs[portidx] = err;
@@ -448,12 +448,10 @@ static int configure_driver(LPTSRDATA data, unsigned num_ports, int ports[])
#if USE_SERIAL
int err = configure_driver_serial(data, port, serial_get_iobase(port));
if (!err) {
- unsigned num_wheels = 0;
-#if USE_WHEEL
- num_wheels = data->num_wheels;
-#endif
- printf(_(1, 22, "Found serial mouse on COM%u with %u buttons, %u wheels\n"), port, data->num_buttons, num_wheels);
- return 0;
+ printf(_(1, 22, "Found serial mouse on COM%u with %u buttons, %u wheels\n"),
+ port, data->num_buttons, data->num_wheels);
+ found_mouse = true;
+ break;
} else {
errs[portidx] = err;
}
@@ -461,24 +459,43 @@ static int configure_driver(LPTSRDATA data, unsigned num_ports, int ports[])
}
}
- // If we are here, we have neither serial nor PS/2.
- // Print all error messages now.
- for (portidx = 0; portidx < num_ports; portidx++) {
- int port = ports[portidx];
- int err = errs[portidx];
-
- if (err) {
- if (port == 0) {
- fprintf(stderr, _(3, 8, "Cannot init PS/2 mouse BIOS, err=%d\n"), err);
- } else {
- fprintf(stderr, _(3, 15, "Cannot find mouse in COM%u, err=%d\n"), port, err);
+ if (!found_mouse) {
+ // If we are here, we have neither serial nor PS/2.
+ // Print all error messages now.
+ for (portidx = 0; portidx < num_ports; portidx++) {
+ int port = ports[portidx];
+ int err = errs[portidx];
+
+ if (err) {
+ if (port == 0) {
+ fprintf(stderr, _(3, 8, "Cannot init PS/2 mouse BIOS, err=%d\n"), err);
+ } else {
+ fprintf(stderr, _(3, 15, "Cannot find mouse in COM%u, err=%d\n"), port, err);
+ }
}
}
+
+ fprintf(stderr, _(3, 14, "No mouse found\n"));
+ return -1;
}
- fprintf(stderr, _(3, 14, "No mouse found\n"));
+ // Otherwise, we found a mouse, go ahead with installation
- return -1;
+ // No more interruptions from now on and until we TSR.
+ // Inserting ourselves in the interrupt chain should be atomic.
+ _disable();
+
+ // Hook hardware interrupts. Which interrupts depends on which mouse was found.
+ data->prev_irq3_4_handler = 0;
+#if USE_SERIAL
+ if (data->port_irq) {
+ dprintf("Hooking irq%hu (int%x) for serial\n", data->port_irq, 0x8 + data->port_irq);
+ data->prev_irq3_4_handler = _dos_getvect(0x8 + data->port_irq);
+ _dos_setvect(0x8 + data->port_irq, data:>irq3_4_isr);
+ }
+#endif
+
+ return 0;
}
static int move_driver_to_umb(LPTSRDATA __far * data)
@@ -499,26 +516,17 @@ static __declspec(aborts) int install_driver(LPTSRDATA data, bool high)
{
const unsigned int resident_size = DOS_PSP_SIZE + get_resident_size();
- // No more interruptions from now on and until we TSR.
- // Inserting ourselves in the interrupt chain should be atomic.
_disable();
+ // Hook main interrupts
data->prev_int33_handler = _dos_getvect(0x33);
_dos_setvect(0x33, data:>int33_isr);
- data->prev_irq3_4_handler = 0;
-#if USE_SERIAL
- if (data->port_irq) {
- dprintf("Hooking irq%hu (int%x) for serial\n", data->port_irq, 0x8 + data->port_irq);
- data->prev_irq3_4_handler = _dos_getvect(0x8 + data->port_irq);
- _dos_setvect(0x8 + data->port_irq, data:>irq3_4_isr);
- }
-#endif
-
- data->prev_int2f_handler = 0;
#if USE_WIN386
data->prev_int2f_handler = _dos_getvect(0x2f);
_dos_setvect(0x2f, data:>int2f_isr);
+#else
+ data->prev_int2f_handler = 0;
#endif
printf(_(1, 17, "Driver installed\n"));
@@ -538,17 +546,18 @@ static __declspec(aborts) int install_driver(LPTSRDATA data, bool high)
static bool check_if_driver_uninstallable(LPTSRDATA data)
{
- void (__interrupt __far *cur_int33_handler)() = _dos_getvect(0x33);
-
// Compare the segment of the installed handler to see if its ours
// or someone else's
- if (FP_SEG(cur_int33_handler) != FP_SEG(data)) {
- fprintf(stderr, _(3, 9, "INT%X has been hooked by someone else, cannot safely remove\n"), 0x33);
- return false;
+ if (data->prev_int33_handler) {
+ void (__interrupt __far *cur_int33_handler)() = _dos_getvect(0x33);
+
+ if (FP_SEG(cur_int33_handler) != FP_SEG(data)) {
+ fprintf(stderr, _(3, 9, "INT%X has been hooked by someone else, cannot safely remove\n"), 0x33);
+ return false;
+ }
}
-#if USE_SERIAL
- if (data->port_irq) {
+ if (data->port_irq && data->prev_irq3_4_handler) {
void (__interrupt __far *cur_irq3_4_handler)() = _dos_getvect(0x8 + data->port_irq);
if (FP_SEG(cur_irq3_4_handler) != FP_SEG(data)) {
@@ -556,10 +565,8 @@ static bool check_if_driver_uninstallable(LPTSRDATA data)
return false;
}
}
-#endif
-#if USE_WIN386
- {
+ if (data->prev_int2f_handler) {
void (__interrupt __far *cur_int2f_handler)() = _dos_getvect(0x2f);
if (FP_SEG(cur_int2f_handler) != FP_SEG(data)) {
@@ -567,12 +574,11 @@ static bool check_if_driver_uninstallable(LPTSRDATA data)
return false;
}
}
-#endif
return true;
}
-static int unconfigure_driver(LPTSRDATA data)
+static void unconfigure_driver(LPTSRDATA data)
{
if (data->port == 0) {
// PS/2 mode
@@ -597,30 +603,38 @@ static int unconfigure_driver(LPTSRDATA data)
#endif
}
- return 0;
+ // Unhook only configured hardware-related interrupts
+ _disable();
+ if (data->port_irq && data->prev_irq3_4_handler) {
+ _dos_setvect(0x8 + data->port_irq, data->prev_irq3_4_handler);
+ data->prev_irq3_4_handler = 0;
+ }
+ _enable();
}
-static int uninstall_driver(LPTSRDATA data)
+static void uninstall_driver(LPTSRDATA data)
{
- _dos_setvect(0x33, data->prev_int33_handler);
-
-#if USE_SERIAL
- if (data->port_irq) {
+ // Unhook all interrupts
+ _disable();
+ if (data->prev_int33_handler) {
+ _dos_setvect(0x33, data->prev_int33_handler);
+ data->prev_int33_handler = 0;
+ }
+ if (data->port_irq && data->prev_irq3_4_handler) {
_dos_setvect(0x8 + data->port_irq, data->prev_irq3_4_handler);
+ data->prev_irq3_4_handler = 0;
}
-#endif
-
-#if USE_WIN386
- _dos_setvect(0x2f, data->prev_int2f_handler);
-#endif
+ if (data->prev_int2f_handler) {
+ _dos_setvect(0x2f, data->prev_int2f_handler);
+ data->prev_int2f_handler = 0;
+ }
+ _enable();
// Find and deallocate the PSP (including the entire program),
// it is always 256 bytes (16 paragraphs) before the TSR segment
dos_free(FP_SEG(data) - (DOS_PSP_SIZE/16));
printf(_(1, 18, "Driver uninstalled\n"));
-
- return 0;
}
static int driver_reset(void)
@@ -708,6 +722,18 @@ static int parse_port(const char *s)
}
}
+static int default_port_order(int ports[])
+{
+ const unsigned num_com_ports = MIN(serial_num_ports(), MAX_PORTS);
+ unsigned portidx = 0, port;
+ if (ps2m_installed()) ports[portidx++] = 0; // 1st. PS2
+ // 2nd. COMn in order
+ for (port = 1; port <= num_com_ports; port++) {
+ ports[portidx++] = port;
+ }
+ return portidx;
+}
+
int main(int argc, const char *argv[])
{
LPTSRDATA data = get_tsr_data(true);
@@ -719,12 +745,13 @@ int main(int argc, const char *argv[])
if (argi >= argc || stricmp(argv[argi], "install") == 0) {
bool high = true;
- int portidx = 0, port;
+ int portidx = 0;
// Default search order (PS2, COM1, COM2, COM3...)
int ports[1+MAX_PORTS] = {-1};
argi++;
for (; argi < argc; argi++) {
+ int port;
if (stricmp(argv[argi], "low") == 0) {
high = false;
} else if (stricmp(argv[argi], "high") == 0) {
@@ -737,15 +764,9 @@ int main(int argc, const char *argv[])
return invalid_arg(argv[argi]);
}
}
-
if (!portidx) {
// User has not specified custom search order, so init with default
- const unsigned num_com_ports = MIN(serial_num_ports(), MAX_PORTS);
- if (ps2m_installed()) ports[portidx++] = 0; // 1st. PS2
- // 2nd. COMn in order
- for (port = 1; port <= num_com_ports; port++) {
- ports[portidx++] = port;
- }
+ portidx = default_port_order(ports);
}
if (data) {
@@ -766,17 +787,53 @@ int main(int argc, const char *argv[])
if (high) cancel_reallocation(FP_SEG(data));
return EXIT_FAILURE;
}
+
return install_driver(data, high);
} else if (stricmp(argv[argi], "uninstall") == 0) {
if (!data) return driver_not_found();
if (!check_if_driver_uninstallable(data)) {
return EXIT_FAILURE;
}
- err = unconfigure_driver(data);
+ unconfigure_driver(data);
+ uninstall_driver(data);
+ return EXIT_SUCCESS;
+ } else if (stricmp(argv[argi], "reconf") == 0) {
+ int portidx = 0, port;
+ // Default search order (PS2, COM1, COM2, COM3...)
+ int ports[1+MAX_PORTS] = {-1};
+
+ argi++;
+ for (; argi < argc; argi++) {
+ int port;
+ if ((port = parse_port(argv[argi])) >= 0) {
+ if (portidx > MAX_PORTS) return invalid_arg(argv[argi]);
+ if (port < 0 || port > MAX_PORTS) return invalid_arg(argv[argi]);
+ ports[portidx++] = port;
+ } else {
+ return invalid_arg(argv[argi]);
+ }
+ }
+ if (!portidx) {
+ portidx = default_port_order(ports);
+ }
+
+ // Unhook the driver
+ if (!data) return driver_not_found();
+ if (!check_if_driver_uninstallable(data)) {
+ return EXIT_FAILURE;
+ }
+ unconfigure_driver(data);
+
+ // Configure the driver again
+ err = configure_driver(data, portidx, ports);
if (err) {
return EXIT_FAILURE;
}
- return uninstall_driver(data);
+
+ // Force a reset of the driver
+ driver_reset();
+
+ return EXIT_SUCCESS;
#if USE_WHEEL
} else if (stricmp(argv[argi], "wheel") == 0) {
bool enable = true;