diff options
| author | Javier <dev.git@javispedro.com> | 2026-08-30 03:39:32 +0200 |
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2026-08-30 03:39:32 +0200 |
| commit | 9104ab9ab59c5b23e12a174368062b4bc166359f (patch) | |
| tree | cd8579255230aa7d53bda82faac69bfa4538920c /mousmain.c | |
| parent | b1e5bd8d67179f24f3603fad22ea928357f6b164 (diff) | |
| download | vbados-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.c | 201 |
1 files changed, 129 insertions, 72 deletions
@@ -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; |
