Changes

Kempston Mouse

332 bytes added, 14 January
/* Get mouse position on screen */
This mouse is supported by [[The OCP Art Studio]], [[The Advanced OCP Art Studio]] and [[Carrier Command]].
 
It is emulated in [[Arnold (Emulator)|Arnold]] and [http://ace.cpcscene.net/en:downloads ACE].
== Pictures ==
The schematics and PCB are 90% the same as the Spectrum's. They differ in the port decoding.
Port decoding NOTE: * Counters are reset to be confirmed0 at power on.* Counters are NOT reset to 0 when using bus reset (reset switch)
FBEE is xxxx x0x1 xxx0 xxx0FBEF is xxxx x0x1 xxx0 xxx1FAEF is xxxx x0x0 xxx0 xxxx=== I/O decoding ===
In Spectrum interface A10 chooses Decoding seems to be (some testing to confirm this):  I/O port for X,position is decoded as xxxx x0x1 xxx0 xxx0 (FBEE is normally used) I/O port for Y. On CPC interface position is decoded as xxxx x0x1 xxx0 xxx1 (FBEF is normally used) I/O port for Buttons is decoded as xxxx x0x0 xxx0 xxxx (FAEF is normally used) Confirmed connected:A10, A0 chooses X,Y.In Spectrum interface A4, A8 chooses buttons or directions. On CPC interface A8 alsochooses this.==== Movement ====
Position:
Port FBEEh READ: Kempston Mouse 8 bit X position (left: -ve, right: +ve)
Port FBEFh READ: Kempston Mouse 8 bit Y position (up: +ve, down: -ve)
NOTE:
* Movement is accumulated so you only need to read the mouse status when you want e.g. once per frame.* Speed is 1 for slow movement of the mouse and 12 for very fast movement.* The position values aren't are not reset after reading.* The position values do not change if the mouse doesn't move in that is not moving * Position values wrap around e.g. when moving left with movement speed of 1, 0 wraps around to ff (0-1 -> ff)and when moving right with movement speed of 1, ff wraps around to 0 (ff+1->0) * To calculated the distance moved since last read subtract the new value read from the previous value read and AND with ff. The value is the amount of movement.
0 means no movement. -ve means moving left/down, +ve means right/up.
dist=-01h..-80h moved left/down
==== Buttons:==== 
Port FAEFh READ: Kempston Mouse Buttons
bit 0: Right Button (active low)
Here is the algorithm in pseudo-code:
// # initMouse initializes variables and centers the mouse pointer on screen function def initMouse() {: maxX = 639; maxY = 399; // # centering the mouse pointer on the screen virtualX = maxX >> 1; // virtualX = # maxX/2 virtualY = maxY >> 1; // virtualY = # maxY/2 // # store raw mouse values oldX = inp(&FBEE); oldY = inp(&FBEF); // # get mouse pointer position refreshMouse();  }def refreshMouse(): # get raw mouse values rawX = inp(&FBEE) rawY = inp(&FBEF) # get the relative mouse displacement since last call deltaX = rawX - oldX deltaY = rawY - oldY # store raw mouse values oldX = rawX oldY = rawY # calculate new unclipped virtual position virtualX = virtualX + deltaX virtualY = virtualY - deltaY # Kempston mouse Y-axis is inverted compared to screen coordinates! # perform clipping if virtualX < 0: virtualX = 0 elif virtualX > maxX: virtualX = maxX if virtualY < 0: virtualY = 0 elif virtualY > maxY: virtualY = maxY # now we translate position from the virtual screen to the current CPC screen mode mouseX = virtualX if graphicsMode == 2 else (virtualX >> 1 if graphicsMode == 1 else virtualX >> 2) mouseY = virtualY >> 1 # virtualY/2 == Manual == * Any manual exists?  == Downloads == * Any kempston example or driver software exists?
// refreshMouse has to be called before you redraw the mouse pointer (and ideally on every frame)
function refreshMouse() {
// get raw mouse values
rawX = inp(&FBEE);
rawY = inp(&FBEF);
// get the relative mouse displacement since last call
deltaX = rawX - oldX;
deltaY = rawY - oldY;
// store raw mouse values
oldX = rawX;
oldY = rawY;
// calculate new unclipped virtual position
virtualX = virtualX + deltaX;
virtualY = virtualY - deltaY; // Kempston mouse Y-axis is inverted compared to screen coordinates!
// perform clipping
if (virtualX < 0) then virtualX = 0;
else if (virtualX > maxX) then virtualX = maxX;
if (virtualY < 0) then virtualY = 0;
else if (virtualY > maxY) then virtualY = maxY;
// now we translate position from the virtual screen to the current CPC screen mode
mouseY = virtualY >> 1; // mouseY = virtualY/2
if (mode2) then mouseX = virtualX;
else if (mode1) then mouseX = virtualX >> 1; // mouseX = virtualX/2
else if (mode0) then mouseX = virtualX >> 2; // mouseX = virtualX/4
}
[[Category:Peripherals]][[Category:Input Device]]
4,605
edits