Use the PS/2 Mouse

From F256 Foenix
Jump to navigationJump to search

PS/2 Port Registers

Address R/W Name 7 6 5 4 3 2 1 0
0xD640 R/W PS2_CTRL - - MCLR KCLR M_WR - K_WR -
0xD641 R/W PS2_OUT Data to send to keyboard
0xD642 R KBD_IN Data from the keyboard input FIFO
0xD643 R MS_IN Data from the mouse input FIFO
0xD644 R PS2_STAT K_AK K_NK M_AK M_NK - - MEMP KEMP

K_WR set to 1 then 0 to send a byte written on PS2_OUT to the keyboard

M_WR set to 1 then 0 to send a byte written on PS2_OUT to the mouse

KCLR set to 1 then 0 to clear the keyboard input FIFO queue.

MCLR set to 1 then 0 to clear the mouse input FIFO queue.

K_AK when 1, the code sent to the keyboard has been acknowledged

K_NK when 1, the code sent to the keyboard has resulted in an error

M_AK when 1, the code sent to the mouse has been acknowledged

M_NK when 1, the code sent to the mouse has resulted in an error

KEMP when 1, the keyboard input FIFO is empty

MEMP when 1, the mouse input FIFO is empty

Mouse Pointer Registers

The mouse pointer bitmap graphic is a grayscale 16x16 "sprite" that is not part of the regular 64 sprites provided by the TinyVicky, but can be thought of as a "special 65th" sprite that can be directly controlled by these registers.

The bitmap data is stored at address range 0xCC00-0xCFFF (256 bytes).

The F256Jr manual reports that:

The position of the mouse pointer is controlled in one of two ways. In the default approach (MODE = 0), the system software will monitor mouse movements, determine the mouse position programmatically, and set the TinyVicky mouse position registers directly. In the legacy approach (MODE = 1), the system software will receive the three byte PS/2 mouse data packet and set the TinyVicky mouse PS2_BYTE registers. In this legacy mode, TinyVicky will interpret the mouse packets and track the mouse position for the system. This approach is less work for the system software, but is less flexible.

The italic bold part is proven to be untrue. You are responsible to set the mouse position yourself by keeping a local copy of its X and Y coordinates and set the appropriate registers below yourself.

Address R/W 7 6 5 4 3 2 1 0
0xD6E0 W - - - - - - MODE EN
0xD6E2 RW X7 X6 X5 X4 X3 X2 X1 X0
0xD6E3 RW X15 X14 X13 X12 X11 X10 X9 X8
0xD6E4 RW Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
0xD6E5 RW Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8
0xD6E6 W PS2_BYTE_0
0xD6E7 W PS2_BYTE_1
0xD6E8 W PS2_BYTE_2

EN if set (1), the mouse pointer is displayed. If clear (0), the mouse pointer is not displayed

MODE if clear (0), the mouse position is specified by setting the X and Y registers. If set (1), the

program must pass along the 3 byte PS/2 mouse packet to the packet registers (this is a

legacy mode).

X this is the X coordinate of the mouse and both readable and writable if MODE is clear (0)

Y this is the Y coordinate of the mouse and both readable and writable if MODE is clear (0)

PS2_BYTE_0 the first byte of the PS/2 mouse message packet. Only used if MODE is set (1).

PS2_BYTE_1 the second byte of the PS/2 mouse message packet. Only used if MODE is set (1).

PS2_BYTE_2 the third byte of the PS/2 mouse message packet. Only used if MODE is set (1).

Common easy usage

  1. Send 0x01 to 0xD6E0 in order to enable the mouse and set it to MODE 0, by far the easiest.
  2. Send 0x0100 as a 16-bit value to both 0xD6E2 and 0xD6E4 to set the mouse at a relatively central position on the screen
  3. In your device detection loop, look for a MicroKernel event of type mouse.DELTA which will trigger for both movement and also button clicks or mouse wheel movement
  4. PEEK the current x and y positions as 16-bit values from 0xD6E2-0xD6E5 and add to them the signed 8-bit values of mouse.delta.x and mouse.delta.y. Keep in mind that this delta can be negative (left or up) or positive (right, or down).
  5. IMPORTANT NOTE: Under a bitmap graphic resolution under 60Hz of 320x240 pixels, the mouse position resolution is instead 640x480, so plan accordingly if you want to interface where the mouse is and where graphics are influenced or interacted with.
  6. SECOND IMPORTANT NOTE: In a situation where you'll want to test if the mouse is in the right coordinates compared to a sprite location that could act as a button, remember that the visible top left coordinate of the screen for sprites is at (32,32) by default, because of the border.

Example C code can be found here: https://github.com/Mu0n/F256KsimpleCdoodles/blob/main/mousing/src/mousing.c