Home Memoirs of a Gamer Movies I watched Guidebook Links
Initialization of the mouse really breaks down to 4 steps:
Fortunately there are software interrupts provided by BIOS that can help us perform these tasks!
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
xor ax, ax int 0x33 |
union REGS regs; regs.x.ax = 0; int86(0x33, ®s, ®s); |
union REGS regs; regs.x.ax = 0; int386(0x33, ®s, ®s); |
After executing int 33, whether our mouse is detected will be stored in AX (0 for no, -1 for yes) and the number of buttons detected will be stored in BX. Keep in mind that in the DOS days only 2 buttons were thought of as standard. Middle mouse button was fit into the spec but it wasn't common place until well into the Windows era. Sadly no scroll wheel was available in DOS.
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
mov ax, 4 mov cx, 160 mov dx, 100 int 0x33 |
union REGS regs; regs.x.ax = 4; regs.x.cx = 160; regs.x.dx = 100; int86(0x33, ®s, ®s); |
union REGS regs; regs.x.ax = 4; regs.x.cx = 160; regs.x.dx = 100; int386(0x33, ®s, ®s); |
So let's move the mouse pointer to the center of the screen. We'll assume that we're using 320x200 as our screen resolution so we want our X coordinate to be 160 and our Y coordinate to be 100.
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
mov ax, 7 mov cx, 0 mov dx, 319 int 0x33 |
union REGS regs; regs.x.ax = 7; regs.x.cx = 0; regs.x.dx = 319; int86(0x33, ®s, ®s); |
union REGS regs; regs.x.ax = 7; regs.x.cx = 0; regs.x.dx = 319; int386(0x33, ®s, ®s); |
Now we have the BIOS driver aware of how wide the screen should be in virtual pixels.
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
mov ax, 8 mov cx, 0 mov dx, 199 int 0x33 |
union REGS regs; regs.x.ax = 8; regs.x.cx = 0; regs.x.dx = 199; int86(0x33, ®s, ®s); |
union REGS regs; regs.x.ax = 8; regs.x.cx = 0; regs.x.dx = 199; int386(0x33, ®s, ®s); |
And finally we've set how tall our screen is in virtual pixels. Now we should be ready to use our mouse!
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
mouse_init: push bx push cx xor ax, ax int 0x33 mov mouse_button_count, bx cmp ax, -1 jnz error mov ax, 4 mov cx, 160 mov dx, 100 int 0x33 mov ax, 7 mov cx, 0 mov dx, 319 int 0x33 mov ax, 8 mov cx, 0 mov dx, 199 int 0x33 pop cx pop bx xor ax, ax ret error: pop cx pop bx mov ax, -1 ret |
union REGS regs; regs.x.ax = 0; int86(0x33, ®s, ®s); if (regs.x.ax==-1) return -1; mouse.buttoncount = regs.x.bx; regs.x.ax = 4; regs.x.cx = 160; regs.x.dx = 100; int86(0x33, ®s, ®s); regs.x.ax = 7; regs.x.cx = 0; regs.x.dx = 319; int86(0x33, ®s, ®s); regs.x.ax = 8; regs.x.cx = 0; regs.x.dx = 199; int86(0x33, ®s, ®s); return 0; |
union REGS regs; regs.x.ax = 0; int386(0x33, ®s, ®s); if (regs.x.ax==-1) return -1; mouse.buttoncount = regs.x.bx; regs.x.ax = 4; regs.x.cx = 160; regs.x.dx = 100; int386(0x33, ®s, ®s); regs.x.ax = 7; regs.x.cx = 0; regs.x.dx = 319; int386(0x33, ®s, ®s); regs.x.ax = 8; regs.x.cx = 0; regs.x.dx = 199; int386(0x33, ®s, ®s); return 0; |
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
mov ax, 3 int 0x33 mov mouse_x, cx mov mouse_y, dx mov mouse_buttons, bx |
union REGS regs; regs.x.ax = 3; int86(0x33, ®s, ®s); mouse.x = regs.x.cx; mouse.y = regs.x.dx; mouse.buttons = regs.x.bx |
union REGS regs; regs.x.ax = 3; int386(0x33, ®s, ®s); mouse.x = regs.x.cx; mouse.y = regs.x.dx; mouse.buttons = regs.x.bx |
One strange quirk you may want to keep in mind when integrating mouse support is the BIOS routine usually doesn't track the least significant bit on the X coordinate. What this means is that you'll see your cursor skip every odd X coordinate. This can be remedied by setting the horizontal spacing to twice your resolution - 1, and then bit shift the resulting mouse X coordinate read by 1 (divide by 2).
Assembly | Borland Turbo C++ / Open Watcom 16bit |
Open Watcom 32bit |
xor ax, ax int 0x33 |
union REGS regs; regs.x.ax = 0; int86(0x33, ®s, ®s); |
union REGS regs; regs.x.ax = 0; int386(0x33, ®s, ®s); |