Turbocharge mouse movement
.. by storing directly into the vars used by the mac plus ROM, rather than working through the IRQ & I/O subsystems.
This commit is contained in:
parent
d7d30c5608
commit
d86ebf1bb8
1 changed files with 14 additions and 77 deletions
91
src/main.c
91
src/main.c
|
|
@ -615,94 +615,32 @@ void umac_opt_disassemble(int enable)
|
||||||
disassemble = enable;
|
disassemble = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MOUSE_MAX_PENDING_PIX 30
|
|
||||||
|
|
||||||
static int pending_mouse_deltax = 0;
|
|
||||||
static int pending_mouse_deltay = 0;
|
|
||||||
|
|
||||||
/* Provide mouse input (movement, button) data.
|
/* Provide mouse input (movement, button) data.
|
||||||
*
|
*
|
||||||
* X is positive going right; Y is positive going upwards.
|
* X is positive going right; Y is positive going upwards.
|
||||||
*/
|
*/
|
||||||
void umac_mouse(int deltax, int deltay, int button)
|
void umac_mouse(int deltax, int deltay, int button)
|
||||||
{
|
{
|
||||||
pending_mouse_deltax += deltax;
|
#define MTemp_h 0x82a
|
||||||
pending_mouse_deltay += deltay;
|
#define MTemp_v 0x828
|
||||||
|
#define CrsrNew 0x8ce
|
||||||
|
#define CrsrCouple 0x8cf
|
||||||
|
|
||||||
/* Clamp if the UI has flooded with lots and lots of steps!
|
if(deltax) {
|
||||||
*/
|
int16_t temp_h = RAM_RD16(MTemp_h) + deltax;
|
||||||
if (pending_mouse_deltax > MOUSE_MAX_PENDING_PIX)
|
RAM_WR16(MTemp_h, temp_h);
|
||||||
pending_mouse_deltax = MOUSE_MAX_PENDING_PIX;
|
|
||||||
if (pending_mouse_deltax < -MOUSE_MAX_PENDING_PIX)
|
|
||||||
pending_mouse_deltax = -MOUSE_MAX_PENDING_PIX;
|
|
||||||
if (pending_mouse_deltay > MOUSE_MAX_PENDING_PIX)
|
|
||||||
pending_mouse_deltay = MOUSE_MAX_PENDING_PIX;
|
|
||||||
if (pending_mouse_deltay < -MOUSE_MAX_PENDING_PIX)
|
|
||||||
pending_mouse_deltay = -MOUSE_MAX_PENDING_PIX;
|
|
||||||
|
|
||||||
/* FIXME: The movement might take a little time, but this
|
|
||||||
* posts the button status immediately. Probably OK, but the
|
|
||||||
* mismatch might be perceptible.
|
|
||||||
*/
|
|
||||||
via_mouse_pressed = button;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void mouse_tick(void)
|
|
||||||
{
|
|
||||||
/* Periodically, check if the mouse X/Y deltas are non-zero.
|
|
||||||
* If a movement is required, encode one step in X and/or Y
|
|
||||||
* and deduct from the pending delta.
|
|
||||||
*
|
|
||||||
* The step ultimately posts an SCC IRQ, so we _don't_ try to
|
|
||||||
* make any more steps while an IRQ is currently pending.
|
|
||||||
* (Currently, that means a previous step's DCD IRQ event
|
|
||||||
* hasn't yet been consumed by the OS handler. In future, if
|
|
||||||
* SCC is extended with other IRQ types, then just checking
|
|
||||||
* the IRQ status is technically too crude, but should still
|
|
||||||
* be fine given the timeframes.)
|
|
||||||
*/
|
|
||||||
if (pending_mouse_deltax == 0 && pending_mouse_deltay == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (scc_irq_state == 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
static int old_dcd_a = 0;
|
|
||||||
static int old_dcd_b = 0;
|
|
||||||
|
|
||||||
/* Mouse X/Y quadrature signals are wired to:
|
|
||||||
* VIA Port B[4] & SCC DCD_A for X
|
|
||||||
* VIA Port B[5] & SCC DCD_B for Y
|
|
||||||
*
|
|
||||||
* As VIA mouse signals aren't sampled until IRQ, can do this
|
|
||||||
* in one step, toggling existing DCD states and setting VIA
|
|
||||||
* either equal or opposite to DCD:
|
|
||||||
*/
|
|
||||||
int dcd_a = old_dcd_a;
|
|
||||||
int dcd_b = old_dcd_b;
|
|
||||||
int deltax = pending_mouse_deltax;
|
|
||||||
int deltay = pending_mouse_deltay;
|
|
||||||
uint8_t qb = via_quadbits;
|
|
||||||
|
|
||||||
if (deltax) {
|
|
||||||
dcd_a = !dcd_a;
|
|
||||||
qb = (qb & ~0x10) | ((deltax < 0) == dcd_a ? 0x10 : 0);
|
|
||||||
pending_mouse_deltax += (deltax > 0) ? -1 : 1;
|
|
||||||
MDBG(" px %d, oldpx %d", pending_mouse_deltax, deltax);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deltay) {
|
if (deltay) {
|
||||||
dcd_b = !dcd_b;
|
int16_t temp_v = RAM_RD16(MTemp_v) - deltay;
|
||||||
qb = (qb & ~0x20) | ((deltay < 0) == dcd_b ? 0x20 : 0);
|
RAM_WR16(MTemp_v, temp_v);
|
||||||
pending_mouse_deltay += (deltay > 0) ? -1 : 1;
|
|
||||||
MDBG(" py %d, oldpy %d", pending_mouse_deltay, deltay);
|
|
||||||
}
|
}
|
||||||
MDBG("\n");
|
|
||||||
|
|
||||||
via_quadbits = qb;
|
if(deltax || deltay) {
|
||||||
old_dcd_a = dcd_a;
|
RAM_WR8(CrsrNew, RAM_RD8(CrsrCouple));
|
||||||
old_dcd_b = dcd_b;
|
}
|
||||||
scc_set_dcd(dcd_a, dcd_b);
|
|
||||||
|
via_mouse_pressed = button;
|
||||||
}
|
}
|
||||||
|
|
||||||
void umac_reset(void)
|
void umac_reset(void)
|
||||||
|
|
@ -734,7 +672,6 @@ int umac_loop(void)
|
||||||
|
|
||||||
// Device polling
|
// Device polling
|
||||||
via_tick(global_time_us);
|
via_tick(global_time_us);
|
||||||
mouse_tick();
|
|
||||||
disc_tick();
|
disc_tick();
|
||||||
kbd_check_work();
|
kbd_check_work();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue