INT 33h is not part of the BIOS or of DOS. It belongs to the mouse driver, a program loaded at boot (MOUSE.COM, or MOUSE.SYS in CONFIG.SYS) that talks to the mouse hardware on a serial port or the PS/2 port, keeps track of where the pointer is, draws it on the screen and answers questions through this vector. Microsoft defined the interface in 1983 and every later driver copied it. DOSBox-X has a driver built in, active from the start.
Unlike most services the function number is the whole of AX, not AH: MOV AX, 0003h, not MOV AH, 03h. Results come back in AX, BX, CX and DX.
| AX | Service |
|---|---|
| 0000h | reset the driver; AX = FFFFh if a mouse is there, BX = buttons |
| 0001h / 0002h | show / hide the pointer (a counter, not a switch) |
| 0003h | position (CX, DX) and buttons (BX) |
| 0004h | move the pointer |
| 0005h / 0006h | button press / release counts and positions since the last call |
| 0007h / 0008h | horizontal / vertical range |
| 000Bh | motion counters in mickeys since the last call |
| 000Ch | install an event handler |
| 000Fh | mickeys per 8 pixels |
| 0021h | software reset (no hardware reset) |
Is there a driver?
Calling INT 33h when nothing is installed is a gamble. On DOS 2 the vector may be 0000:0000 and the call jumps into the interrupt table; later DOS versions point it at an IRET, so the call returns with AX unchanged. A careful program reads the vector first with INT 21h AH=35h, checks that it is not zero and does not point at an IRET (CFh), then calls INT 33h AX=0000h and checks for AX = FFFFh.
MOV AX, 3533h ; DOS: get the INT 33h vectorINT 21h ; ES:BX = the handlerMOV AX, ESOR AX, BX ; 0000:0000: nothing installedJZ NONE1CMP BYTE PTR ES:[BX], 0CFh ; only an IRET there?JE NONE1XOR AX, AX ; mouse: reset and detectINT 33h ; AX = FFFFh if a mouse is there, BX = buttonsCMP AX, 0FFFFhJNE NONE1MOV DX, OFFSET FOUND1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hMOV AX, BXCALL PDEC ; the button countMOV DX, OFFSET BUTTONS1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hJMP DONE1NONE1:MOV DX, OFFSET NOMOUSE1MOV AH, 09h ; DOS: print the $-string at DS:DXINT 21hDONE1:FOUND1 DB "mouse driver found, $"BUTTONS1 DB " buttons", 13, 10, "$"NOMOUSE1 DB "no mouse driver", 13, 10, "$"PDEC PROC NEAR ; print AX in decimal; keeps every registerPUSH AXPUSH BXPUSH CXPUSH DXMOV BX, 10XOR CX, CX ; digits on the stackDECD1:XOR DX, DXDIV BX ; AX = AX / 10, DX = the last digitPUSH DXINC CXTEST AX, AXJNZ DECD1DECD2:POP DX ; the digits come back first to lastADD DL, "0"MOV AH, 02hINT 21hLOOP DECD2POP DXPOP CXPOP BXPOP AXRETPDEC ENDP
Coordinates
The driver reports the position in pixels of a virtual screen, whatever the video mode. In graphics modes that is the real resolution (640×480 in mode 12h; in mode 13h the driver still counts 0..639 across, so divide x by 2). In text mode the virtual screen is 640×200 for 80×25: every character cell is 8 × 8, so column = x / 8 and row = y / 8, and the driver only ever reports multiples of 8. The pointer in text mode is a cell drawn with inverted colours, not an arrow.
Mickeys
The mouse itself sends movement counts, mickeys, about 1/200 inch each. The driver turns them into pixels with a ratio, by default 8 mickeys per 8 pixels across and 16 per 8 pixels down, changeable with AX=000Fh, and applies acceleration when the mouse moves fast. AX=000Bh returns the raw mickeys since the last call, which is what a game uses for mouse-look, unaffected by the screen edges.
The cursor counter
Visibility is a counter: 0 means shown, anything below hidden. Reset sets it to −1 (hidden), INT 33h AX=0001h adds 1 but never goes above 0, INT 33h AX=0002h subtracts 1. So nested hides need as many shows, which lets a drawing routine hide and show without knowing whether its caller had the pointer visible.
In DOSBox-X
The built-in driver supports the Microsoft functions up to version 7 or so, including AX=002Ah (read the cursor counter). It integrates with the host pointer, so in a window the DOS pointer follows yours. The configuration setting int33=false turns the driver off, for programs that bring their own; then the vector check above reports no mouse.