Mouse driver services
---------------------

Functions implemented in CTMOUSE:

INT 33/0000 - MS MOUSE - RESET DRIVER AND READ STATUS
INT 33/0001 - MS MOUSE v1.0+ - SHOW MOUSE CURSOR
INT 33/0002 - MS MOUSE v1.0+ - HIDE MOUSE CURSOR
INT 33/0003 - MS MOUSE v1.0+ - GET CURSOR POSITION AND BUTTONS STATUS
INT 33/0004 - MS MOUSE v1.0+ - POSITION MOUSE CURSOR
INT 33/0005 - MS MOUSE v1.0+ - GET BUTTON PRESS DATA
INT 33/0006 - MS MOUSE v1.0+ - GET BUTTON RELEASE DATA
INT 33/0007 - MS MOUSE v1.0+ - SET HORIZONTAL CURSOR RANGE
INT 33/0008 - MS MOUSE v1.0+ - SET VERTICAL CURSOR RANGE
INT 33/0009 - MS MOUSE v3.0+ - DEFINE GRAPHICS CURSOR
INT 33/000A - MS MOUSE v3.0+ - DEFINE TEXT CURSOR
INT 33/000B - MS MOUSE v1.0+ - GET MOTION COUNTERS
INT 33/000C - MS MOUSE v1.0+ - DEFINE USER INTERRUPT ROUTINE
INT 33/000F - MS MOUSE v1.0+ - SET MICKEYS/PIXELS RATIOS
INT 33/0010 - MS MOUSE v1.0+ - DEFINE SCREEN REGION FOR UPDATING
INT 33/0014 - MS MOUSE v3.0+ - EXCHANGE USER INTERRUPT ROUTINES
INT 33/0015 - MS MOUSE v6.0+ - GET DRIVER STORAGE REQUIREMENTS
INT 33/0016 - MS MOUSE v6.0+ - SAVE DRIVER STATE
INT 33/0017 - MS MOUSE v6.0+ - RESTORE DRIVER STATE
INT 33/001A - MS MOUSE v6.0+ - SET MOUSE SENSITIVITY
INT 33/001B - MS MOUSE v6.0+ - GET MOUSE SENSITIVITY
INT 33/001E - MS MOUSE v6.0+ - GET DISPLAY PAGE
INT 33/001F - MS MOUSE v6.0+ - DISABLE MOUSE DRIVER
INT 33/0020 - MS MOUSE v6.0+ - ENABLE MOUSE DRIVER
INT 33/0021 - MS MOUSE v6.0+ - SOFTWARE RESET
INT 33/0023 - MS MOUSE v6.0+ - GET LANGUAGE FOR MESSAGES
INT 33/0024 - MS MOUSE v6.26+ - GET SOFTWARE VERSION, MOUSE TYPE AND IRQ
INT 33/0026 - MS MOUSE v6.26+ - GET MAXIMUM VIRTUAL SCREEN COORDINATES
INT 33/0027 - MS MOUSE v7.01+ - GET SCREEN/CURSOR MASKS AND MICKEY COUNTS
INT 33/002A - MS MOUSE v7.02+ - GET CURSOR HOT SPOT
INT 33/0032 - MS MOUSE v7.05+ - GET ACTIVE ADVANCED FUNCTIONS
INT 33/004D - MS MOUSE - GET POINTER TO COPYRIGHT STRING
INT 33/006D - MS MOUSE - GET POINTER TO VERSION

Video functions implemented in CTMOUSE:

INT 10/F0 - EGA Register Interface Library - READ ONE REGISTER
INT 10/F1 - EGA Register Interface Library - WRITE ONE REGISTER
INT 10/F2 - EGA Register Interface Library - READ REGISTER RANGE
INT 10/F3 - EGA Register Interface Library - WRITE REGISTER RANGE
INT 10/F4 - EGA Register Interface Library - READ REGISTER SET
INT 10/F5 - EGA Register Interface Library - WRITE REGISTER SET
INT 10/F6 - EGA Register Interface Library - REVERT REGISTERS TO DEFAULT
INT 10/F7 - EGA Register Interface Library - DEFINE REGISTERS DEFAULT
INT 10/FA - EGA Register Interface Library - INTERROGATE DRIVER

The following functions are not implemented but they don't return
anything and can be counted as implemented:

INT 33/000D - MS MOUSE v1.0+ - LIGHT PEN EMULATION ON
INT 33/000E - MS MOUSE v1.0+ - LIGHT PEN EMULATION OFF
INT 33/0013 - MS MOUSE v5.0+ - DEFINE DOUBLE-SPEED THRESHOLD
INT 33/001C - MS MOUSE v6.0+ - SET INTERRUPT RATE
INT 33/001D - MS MOUSE v6.0+ - SET DISPLAY PAGE
INT 33/0022 - MS MOUSE v6.0+ - SET LANGUAGE FOR MESSAGES

The following functions are not implemented at all:

INT 10/04 - VIDEO - GET LIGHT PEN POSITION (except VGA)
INT 33/0011 - Genius Mouse 9.06 - GET NUMBER OF BUTTONS
INT 33/0012 - MS MOUSE - SET LARGE GRAPHICS CURSOR BLOCK
INT 33/0018 - MS MOUSE v6.0+ - SET ALTERNATE USER INTERRUPT HANDLER
INT 33/0019 - MS MOUSE v6.0+ - GET ALTERNATE USER INTERRUPT HANDLER
INT 33/0025 - MS MOUSE v6.26+ - GET GENERAL DRIVER INFORMATION
INT 33/0028 - MS MOUSE v7.0+ - SET VIDEO MODE
INT 33/0029 - MS MOUSE v7.0+ - ENUMERATE VIDEO MODES
INT 33/002B - MS MOUSE v7.0+ - LOAD ACCELERATION PROFILES
INT 33/002C - MS MOUSE v7.0+ - GET ACCELERATION PROFILES
INT 33/002D - MS MOUSE v7.0+ - SELECT ACCELERATION PROFILE
INT 33/002E - MS MOUSE v8.10+ - SET ACCELERATION PROFILE NAMES
INT 33/002F - MS MOUSE v7.02+ - MOUSE HARDWARE RESET
INT 33/0030 - MS MOUSE v7.04+ - GET/SET BallPoint INFORMATION
INT 33/0031 - MS MOUSE v7.05+ - GET CURRENT MINIMUM/MAXIMUM VIRTUAL COORDINATES
INT 33/0033 - MS MOUSE v7.05+ - GET SWITCH SETTINGS AND ACCELERATION PROFILE DATA
INT 33/0034 - MS MOUSE v8.0+ - GET INITIALIZATION FILE
INT 33/0035 - MS MOUSE v8.10+ - LCD SCREEN LARGE POINTER SUPPORT


Details of driver operation
---------------------------

CTMOUSE displays cursor only in standard video modes of CGA, EGA and VGA;
  Hercules Graphics/InColor Card or SVGA/VESA extended video modes are not
  supported but the cursor can always be displayed manually: remove INT
  33/0001 (Show cursor) calls, set cursor movement area (INT 33/0007 and
  INT 33/0008) and setup user interrupt routine (INT 33/000C), which will
  redraw cursor when mouse moves.
Some applications call INT 33/0001 (Show cursor), INT 33/0009 (Define
  graphics cursor) and INT 33/000A (Define text cursor) in loops; to
  prevent cursor flickering INT 33/0001 redraws cursor only if it was
  hidden before and INT 33/0004 (Position cursor), INT 33/0009 and
  INT 33/000A redraw cursor only if its position or pattern changed.
Unlike many other mouse drivers CTMOUSE doesn't require call INT 33/0002
  (Hide cursor) before writing to the screen in text mode because screen
  under cursor isn't restored if cursor is overwritten; note: if character
  is written at cursor position without an attribute - through INT 21 or
  through INT 10/0E (Teletype output) - then it gets cursor's attribute.
Unlike Microsoft's specification, CTMOUSE always displays cursor on the
  active video page and doesn't require call INT 33/001D (Set display
  page) at all; this function is, anyway, a dummy.

Below is a table of virtual screen size, cursor movement granularity,
  minimum and maximum cursor size in positions (actual for INT 33/0010)
  for each video mode:
				 min	 max
	mode	 screen  cell	shape	shape
	 *0	640x200  16x8	16x8	16x8
	 *1	640x200  16x8	16x8	16x8
	 *2	640x200   8x8	 8x8	 8x8
	 *3	640x200   8x8	 8x8	 8x8
	  4	640x200   2x1	16x16	24x16
	  5	640x200   2x1	16x16	24x16
	  6	640x200   1x1	16x16	24x16
	 *7	640x200   8x8	 8x8	 8x8
	 0Dh	640x200   2x1	32x16	48x16
	 0Eh	640x200   1x1	16x16	24x16
	 0Fh	640x350   1x1	16x16	24x16
	 10h	640x350   1x1	16x16	24x16
	 11h	640x480   1x1	16x16	24x16
	 12h	640x480   1x1	16x16	24x16
	 13h	640x200   2x1	32x16	32x16
	nonstd	640x200   1x1	  -	  -

  * for text modes virtual screen size given for standard screen sizes
  40x25 and 80x25; for nonstandard screen sizes virtual screen size is
  changed accordingly.
In standard text modes CTMOUSE supports any screen size beside 40x25 and
  80x25 and sets virtual screen size as (screen width in characters)*8 by
  (screen height in characters)*8 (except video modes 0-1, when width is
  multiplied by 16) each time when INT 33/0000 (Reset driver), INT 33/0020
  (Enable driver) or INT 33/0021 (Software reset) is called or the video
  mode is changed.
If screen size in text mode is changed, then INT 33/0000 (Reset driver),
  INT 33/0020 (Enable driver) or INT 33/0021 (Software reset) must be
  called to renew virtual screen size; after INT 33/0020 also INT 33/0007
  (Set horizontal range) and INT 33/0008 (Set vertical range) with
  minrange=0 and maxrange=8*screen width-1/8*screen height-1 must be
  called to enable the complete screen for cursor movement.
CTMOUSE intercepts only INT 10/0 (Set video mode) video function and no
  other function, such as 4Fh (VESA/SVGA functions), 1Ch (VGA state
  save/restore) or 11h (EGA/VGA character generation functions), so INT
  33/0000 (Reset driver), INT 33/0021 (Software reset) or INT 33/0020
  (Enable driver) must be called after these video functions.

INT 33/0007 (Set horizontal range) and INT 33/0008 (Set vertical range)
  calls setup cursor movement area, but cursor will be seen on the screen
  only in standard video modes and when cursor shape intersects with
  virtual screen coordinates.
All driver's coordinates (ranges, cursor positions, regions) interpreted
  as signed values, also as cursor hot spot or mickey counts.


Notes for mouse driver services
-------------------------------

INT 33/0004 (Position cursor) call also clears mickey counts.
When bit 0 (call if mouse moves) is set in the call mask passed to INT
  33/000C (Define user interrupt routine) then user routine is called when
  any mickey count is changed; note: cursor position usually changes less
  often than mickey counts because mickeys/pixels ratios can reduce
  mickeys change to zero and cursor position change can be hidden by
  granulation (in text modes cursor positions are always factor of 8 or
  16, in some graphics modes X cursor positions are always factor of two).
User interrupt routine installed via INT 33/000C must use far RET, not
  IRET for return and it is not required to save any register in routine.
Mouse interrupt handler will not redraw cursor on the screen if mouse
  events change cursor position until called user interrupt routine
  returns back to mouse interrupt handler.
For bitmapped graphics modes 4-6 and 0Dh-12h a peculiarity of INT 33/0010
  (Define region for updating) function should be noted: horizontal cursor
  position is always aligned by modulo 8 or 16 and cursor occupies 24 or
  48 positions, unlike mode 13h, where start position is unchanged and
  cursor occupies 32 positions; i.e. for left limit L and right limit R in
  modes 4-6, 0Eh-12h cursor will be hidden between (L-L%8)-16 and
  [R/8+1]*8-1 positions, in mode 0Dh cursor will be hidden between
  (L-L%16)-32 and [R/16+1]*16-1 positions and in mode 13h cursor will be
  hidden between L-32 and R positions.
To set update region via INT 33/0010 in terms of character positions you
  must compute arguments as CX=left*W, DX=top*8, SI=(right+1)*W-1 and
  DI=(bottom+1)*W-1, where W=16 for modes 0-1, 4-5, 0Dh and 13h and W=8
  for all other modes.
Size of buffer, required to save driver state by INT 33/0016, in CTMOUSE
  is less than 180 bytes; exact buffer size is returned by INT 33/0015
  (Get driver storage requirements).
When the video mode is changed (through INT 10/0) CTMOUSE hides cursor
  (so that it can be shown by next INT 33/0001), recalculates screen
  sizes, sets cursor ranges to screen sizes, centers cursor and clears
  mickey counts.
For INT 33/0000 (Reset driver) and INT 33/0021 (Software reset) calls
  CTMOUSE hides cursor (so that it can be shown by next INT 33/0001),
  recalculates screen sizes, sets cursor ranges to screen sizes, centers
  cursor and clears mickey counts, user interrupt routine call mask,
  buttons status and press/release data; also horizontal mickeys per 8
  pixels ratio is set to 8, vertical mickeys per 8 pixels ratio is set to
  16, software text mode cursor is set with reverse video shape (screen
  mask 77FFh, cursor mask 7700h) and graphics mode cursor shape is set to
  arrow with zero hot spot.
For INT 33/001F (Disable driver) call CTMOUSE hides cursor (so that it can
  be shown by next INT 33/0001), disables mouse interrupts, restores IRQ
  interrupt (if serial mouse is active) and returns in ES:BX old INT 33
  interrupt handler address; if INT 10 interrupt was not restored and both
  INT 33 and INT 10 interrupts is not intercepted by other program then on
  exit INT 10 interrupt handler will be restored else AX will contain -1.
For INT 33/0020 (Enable driver) call CTMOUSE installs IRQ handler (if
  serial mouse is active) and INT 10 handler (if it is not yet installed),
  enables mouse interrupts, recalculates screen sizes, sets cursor ranges
  to screen sizes, centers cursor and clears mickey counts.
CTMOUSE supports INT 33/0022 and 0023 (Set/get language for messages)
  functions, but only for English.
When you have to deal with RIL, keep in mind that RIL is unprotected from
  wrong user input - RIL functions should be called only in standard video
  modes and on EGA or later video adapters, and RIL doesn't check if group
  index, register number or count of registers are valid.


Used BIOS variables
-------------------

0:449h	bits 0-6 used to determine the current video mode (when driver
	enabled by INT 33/0020 or video mode changed)
0:44Ah	screen width in text columns (used to compute offset in video
	memory in text video modes)
0:44Eh	offset in video segment of active video memory page
0:462h	current video page (returned by INT 33/001E)
0:463h	used to compute CRTC base and Feature Control video ports addresses
	(when driver enabled by INT 33/0020 or video mode changed)
0:46Ch	timer used in mouse detection routine to make timing
0:487h	bits 5-6 used to determine RAM size on video adapter (when driver
	enabled by INT 33/0020 or video mode changed)
0:488h	bits 0-3 used to get video configuration switches (when driver
	enabled by INT 33/0020 or video mode changed)
0:4A8h	used to get default video registers values for RIL (when driver
	enabled by INT 33/0020 or video mode changed)


Used interrupts
---------------

INT 10/01	setup text-mode hardware cursor shape, when hardware
		cursor selected
INT 10/1A00	get DCC to check VGA presence
INT 15/C200	enable/disable PS/2 pointing device
INT 15/C203	set resolution of PS/2 pointing device [when PS/2 checking]
INT 15/C205	initialize PS/2 pointing device [when PS/2 checking]
INT 15/C207	set handler for PS/2 pointing device
INT 21/09	output all strings to standard output
INT 21/25	install interrupt handlers for INT 33, INT 10 and IRQ
		handler, also restore those interrupts
INT 21/26	create new PSP for driver image in the UMB [when trying	to
		install driver high]
INT 21/31	remain TSR when driver not copied to other UMB segment
INT 21/35	save old INT 33, INT 10 and IRQ handlers addresses
INT 21/48	allocate UMB memory [when trying to install driver high]
INT 21/49	free memory used by environment and by unloaded TSR
INT 21/4C	terminate program with nonzero errorlevel if some error
		found or with zero errorlevel when no errors
INT 21/58	modify memory allocation strategy [when trying to install
		driver high]
INT 2F/4310	get XMS driver entry [when trying to install driver high]
INT 33/001F	disable previous mouse driver, if one is present
INT 33/0020	enable previous mouse driver after unloading CuteMouse


Techniques used
---------------

1. Two writes to adjacent I/O ports are combined into one write "out dx,ax"
   (used for most video registers and divisor latch of COM port).
2. For interrupt handler's address comparision only segment of address is
   used, because usually different programs reside in different segments
   and no one program is pointed to by zero segment.
3. CuteMouse uses a lot of self-modifying code and many variables are
   placed in the code instructions; most of code modification is grouped
   in the setupdriver and setupvideo procedures.
4. To use free part of PSP and thus minimize memory footprint, CuteMouse
   source includes corresponding "ORG" statement before uninitialized
   variables, for which only offsets are computed and no data is generated.
   Note: in TASM, a structure instance with "DUP" modifier generates data,
   so buttpress and buttrelease arrays are defined without "DUP" as series
   of BUTTLASTSTATE structure insertions instead.
5. CuteMouse is written using TASM and makes use some of TASM features:
   for example, multiple "push" and "pop" in one line ("push ax bx") and
   shifts with an immediate value >1 ("shl ax,2"), which are converted
   into several opcodes valid for 8086/8088 CPUs (i.e. for shifts, TASM
   simply duplicates them - "shl ax,1/shl ax,1"), because there is no
   ".186" or higher statement.
6. Often instructions with shorter opcode but slightly different behavior
   than assumed instruction are used to minimize code; each such use is
   marked by "OPTIMIZE" comment. In addition, instructions for which
   functions are performed by previous code remain in the source as
   comments; this is done for greater readability and to ease code
   carrying.
