From 6def163aa0a11996d2f990fb18690a83b5e605a6 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 2 Jun 2024 20:54:46 +0200 Subject: add new moustest program for testing --- dlog.h | 3 + int33.h | 33 ++++++ makefile | 13 ++- moustest.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 382 insertions(+), 2 deletions(-) create mode 100644 moustest.c diff --git a/dlog.h b/dlog.h index ebeb01c..112254e 100644 --- a/dlog.h +++ b/dlog.h @@ -280,6 +280,9 @@ static void dprintf(const char *fmt, ...) : va_arg(va, const char *), precision); break; + case 'c': + dputc(va_arg(va, char)); + break; case '%': dputc('%'); break; diff --git a/int33.h b/int33.h index f7a469d..2755379 100644 --- a/int33.h +++ b/int33.h @@ -214,6 +214,29 @@ static uint16_t int33_reset(void); __value [ax] \ __modify [ax bx] +static bool int33_reset_get_buttons(uint16_t *num_buttons); +#pragma aux int33_reset_get_buttons = \ + "mov ax, 0x0" \ + "int 0x33" \ + "mov [di], bx" \ + "cmp ax, 0xFFFF" \ + "sete ah" \ + __parm [di] \ + __value [ah] \ + __modify [ax bx] + +static void int33_show_cursor(void); +#pragma aux int33_show_cursor = \ + "mov ax, 0x1" \ + "int 0x33" \ + __modify [ax] + +static void int33_hide_cursor(void); +#pragma aux int33_hide_cursor = \ + "mov ax, 0x2" \ + "int 0x33" \ + __modify [ax] + static void int33_set_horizontal_window(int16_t min, int16_t max); #pragma aux int33_set_horizontal_window = \ "mov ax, 0x7" \ @@ -309,4 +332,14 @@ static uint16_t int33_get_capabilities(void); __value [cx] \ __modify [ax bx cx] +static const char __far * int33_get_version_string(void); +#pragma aux int33_get_version_string = \ + "xor ax, ax" \ + "mov di, ax" \ + "mov es, ax" \ + "mov ax, 0x6d" \ + "int 0x33" \ + __value [es di] \ + __modify [ax] + #endif /* INT33_H */ diff --git a/makefile b/makefile index 907a8e5..c6dc7e5 100644 --- a/makefile +++ b/makefile @@ -2,7 +2,7 @@ # Assuming you have sourced `owsetenv` beforehand. # All binaries to build -bins = vbmouse.exe vbsf.exe vbmouse.drv +bins = vbmouse.exe vbsf.exe vbmouse.drv moustest.exe # Inf files infs = oemsetup.inf @@ -16,7 +16,7 @@ sfdos_objs = sftsr.obj sfmain.obj kitten.obj vbox.obj # Compiler arguments for DOS dos_cflags = -bt=dos -ms -6 -osi -w3 -wcd=202 -# -ms to use small memory model (though sometimes ss != ds...) +# -ms to use small memory model (this assumes ss == ds) # -osi to optimize for size, put intrinsics inline (to avoid runtime calls) # -w3 enables warnings # -wcd=202 disables the unreferenced function warning (e.g., for inline functions in headers) @@ -78,6 +78,15 @@ vbox.obj: vbox.c .AUTODEPEND kitten.obj: kitten.c .AUTODEPEND $(compile_dos) +# Test programs +moustest_objs = moustest.obj + +moustest.exe: moustest.obj + *wlink system dos name $@ file { $(moustest_objs) } + +moustest.obj: moustest.c .AUTODEPEND + $(compile_dos) -mc -zu + # Other targets clean: .SYMBOLIC rm -f vbmouse.exe vbmouse.drv vbsf.exe vbados.flp *.obj *.map diff --git a/moustest.c b/moustest.c new file mode 100644 index 0000000..97e554b --- /dev/null +++ b/moustest.c @@ -0,0 +1,335 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include "int33.h" +#include "utils.h" +#include "dlog.h" + +#define DPREFIX "moustest: " + +bool exiting = false; + +uint16_t driver_caps; +uint16_t num_buttons; +uint16_t num_wheels; + +struct videoconfig vidconf; + +short ctexttop, ctextbot, ctextleft, ctextright; +struct rccoord ctextpos; +const short ctextcolor = 7; +const long ctextbg = _BLACK; + +void gui_printf(const char *format, ...) +{ + va_list arglist; + char buffer[120]; + + va_start(arglist, format); + vsprintf(buffer, format, arglist); + va_end(arglist); + + _outtext(buffer); +} + +void gui_draw_textwindow(int top, int left, int bottom, int right, grcolor fg, long bg) +{ + _settextwindow(top, left, bottom, right); + _setbkcolor(bg); + _settextcolor(fg); + _clearscreen(_GWINDOW); +} + +void gui_draw_title() +{ + const int cols = vidconf.numtextcols; + + gui_draw_textwindow(1, 1, 1, cols, 0, _WHITE); + _outtext("MOUSTEST ESC to exit, 'r' reset, 's' show, 'h' hide"); +} + +void gui_draw_status() +{ + const int statusrow = vidconf.numtextrows; + const int cols = vidconf.numtextcols; + + gui_draw_textwindow(statusrow, 1, statusrow, cols, 0, _WHITE); +} + +void gui_draw_console() +{ + const int rows = vidconf.numtextrows, cols = vidconf.numtextcols; + ctexttop = 3; + ctextbot = rows - 2; + ctextleft = 1; + ctextright = cols; + gui_draw_textwindow(ctexttop, ctextleft, ctextbot, ctextright, + ctextcolor, ctextbg); +} + +void gui_init() +{ + _setbkcolor(_BLACK); + _clearscreen(_GCLEARSCREEN); + + gui_draw_title(); + + gui_draw_status(); + + gui_draw_console(); +} + +void console_enter() +{ + _settextwindow(ctexttop, ctextleft, ctextbot, ctextright); + _settextposition(ctextpos.row, ctextpos.col); + _setbkcolor(ctextbg); + _settextcolor(ctextcolor); +} + +void console_leave() +{ + ctextpos = _gettextposition(); +} + +void console_print(char __far *str) +{ + _disable(); + int33_hide_cursor(); + console_enter(); + _outtext(str); + console_leave(); + int33_show_cursor(); + _enable(); +} + +void console_printf(const char *format, ...) +{ + va_list arglist; + char buffer[120]; + + va_start(arglist, format); + vsprintf(buffer, format, arglist); + va_end(arglist); + + console_print(buffer); +} + +/** Called by the int33 mouse driver. */ +void __far mouse_callback(uint16_t events, uint16_t buttons, int16_t x, int16_t y, int16_t delta_x, int16_t delta_y) +#pragma aux (INT33_CB) mouse_callback +{ + int8_t z = buttons >> 8; + +#if 1 + dprintf(DPREFIX "mouse_callback events=0x%x buttons=0x%x x=%d y=%d dx=%d dy=%d\n", + events, buttons, x, y, delta_x, delta_y); +#endif + + // Update the status bar + _disable(); + gui_draw_status(); + + gui_printf(" %3s %4u , %4u |", + events & INT33_EVENT_MASK_ABSOLUTE ? "ABS" : "REL", x, y); + + if (num_buttons <= 2) { + gui_printf(" [%5s] [%5s] ", + buttons & INT33_BUTTON_MASK_LEFT ? "LEFT" : "", + buttons & INT33_BUTTON_MASK_RIGHT ? "RIGHT" : ""); + } else { + gui_printf(" [%5s] [%5s] [%5s] ", + buttons & INT33_BUTTON_MASK_LEFT ? "LEFT" : "", + buttons & INT33_BUTTON_MASK_CENTER ? "MID " : "", + buttons & INT33_BUTTON_MASK_RIGHT ? "RIGHT" : ""); + if (num_buttons > 3) { + gui_printf(" [%3s] [%3s] ", + buttons & INT33_BUTTON_MASK_4TH ? "4TH" : "", + buttons & INT33_BUTTON_MASK_5TH ? "5TH" : ""); + } + } + + if (num_wheels > 0) { + char c = ' '; + if (events & INT33_EVENT_MASK_WHEEL_MOVEMENT) { + c = z > 0 ? 0x19 : 0x18; + } else if (events & INT33_EVENT_MASK_HORIZ_WHEEL_MOVEMENT) { + c = z > 0 ? 0x1A : 0x1B; + } + gui_printf("| %c", c); + } + + _settextposition(1, 1); + _enable(); + + // Log the events + if (events & INT33_EVENT_MASK_LEFT_BUTTON_PRESSED) { + console_printf("Left button pressed\n"); + } + if (events & INT33_EVENT_MASK_LEFT_BUTTON_RELEASED) { + console_printf("Left button released\n"); + } + if (events & INT33_EVENT_MASK_CENTER_BUTTON_PRESSED) { + console_printf("Middle button pressed\n"); + } + if (events & INT33_EVENT_MASK_CENTER_BUTTON_RELEASED) { + console_printf("Middle button released\n"); + } + if (events & INT33_EVENT_MASK_RIGHT_BUTTON_PRESSED) { + console_printf("Right button pressed\n"); + } + if (events & INT33_EVENT_MASK_RIGHT_BUTTON_RELEASED) { + console_printf("Right button released\n"); + } + if (events & INT33_EVENT_MASK_4TH_BUTTON_PRESSED) { + console_printf("4th button pressed\n"); + } + if (events & INT33_EVENT_MASK_4TH_BUTTON_RELEASED) { + console_printf("4th button released\n"); + } + if (events & INT33_EVENT_MASK_5TH_BUTTON_PRESSED) { + console_printf("5th button pressed\n"); + } + if (events & INT33_EVENT_MASK_5TH_BUTTON_RELEASED) { + console_printf("5th button released\n"); + } + + if (events & INT33_EVENT_MASK_WHEEL_MOVEMENT) { + console_printf("Wheel %s %d\n", z > 0 ? "down" : "up", z); + } + if (events & INT33_EVENT_MASK_HORIZ_WHEEL_MOVEMENT) { + console_printf("Wheel %s %d\n", z > 0 ? "right" : "left", z); + } +} + +bool mouse_reset() +{ + if (!int33_reset_get_buttons(&num_buttons)) { + puts("Mouse not installed"); + return false; + } + + driver_caps = int33_get_capabilities(); + num_wheels = 0; + if (driver_caps & INT33_CAPABILITY_WHEEL_API) { + num_wheels = 1; + } + if (driver_caps & INT33_CAPABILITY_WHEEL2_API) { + num_wheels = 2; + } + + int33_set_event_handler(INT33_EVENT_MASK_ALL, mouse_callback); + + return true; +} + +void mouse_report() +{ + const char __far *fstr; + + if (driver_caps != 0) { + console_printf("Driver capabilities bits: 0x%x %s %s\n", driver_caps, + driver_caps & INT33_CAPABILITY_WHEEL_API ? "" : "", + driver_caps & INT33_CAPABILITY_WHEEL2_API ? "" : ""); + } + + fstr = int33_get_version_string(); + if (fstr) { + console_printf("Driver version string: %Fs\n", fstr); + } + + console_printf("Number of buttons: %u\n", num_buttons); + console_printf("Number of wheels: %u\n", num_wheels); + +} + +void mouse_quit() +{ + int33_reset(); +} + +void mouse_debug() +{ + // TODO ? + union REGS in, out; + in.x.ax = INT33_GET_MOUSE_POSITION; + in.x.bx = 0x4567; + in.x.cx = 0x7845; + in.x.dx = 0x9AAC; + in.x.si = 0xAAAA; + in.x.di = 0xBBBB; + + int86(0x33, &in, &out); + + console_printf("IN ax 0x%04x bx 0x%04x cx 0x%04x dx 0x%04x si 0x%04x di 0x%04x\n", + in.x.ax, in.x.bx, in.x.cx, in.x.dx, in.x.si, in.x.di); + console_printf("OUT ax 0x%04x bx 0x%04x cx 0x%04x dx 0x%04x si 0x%04x di 0x%04x\n", + out.x.ax, out.x.bx, out.x.cx, out.x.dx, out.x.si, out.x.di); +} + +int main(int argc, const char *argv[]) +{ + int c; + + (void)argc; + (void)argv; + + if (!mouse_reset()) { + return EXIT_FAILURE; + } + + _setvideomode(_TEXTC80); + _getvideoconfig(&vidconf); + + gui_init(); + + mouse_report(); + + int33_show_cursor(); + + while (!exiting) { + int c; + + c = getch(); + + dprintf(DPREFIX "getch returns %d\n", c); + + if (c == 0) { + // Extended key + c = getch(); + console_printf("Keyboard extended key %d\n", c); + } else { + console_printf("Keyboard key %d '%c'\n", c, c); + switch (c) { + case 27: // Escape + exiting = true; + break; + case 'r': + console_printf("Reset mouse driver\n"); + mouse_reset(); + mouse_report(); + break; + case 's': + int33_show_cursor(); + break; + case 'h': + int33_hide_cursor(); + break; + case 'd': + mouse_debug(); + break; + } + } + } + + mouse_quit(); + _setvideomode(_DEFAULTMODE); + + return EXIT_SUCCESS; +} -- cgit v1.2.3