summaryrefslogtreecommitdiff
path: root/os/pc/devmouse.c
diff options
context:
space:
mode:
authorKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
committerKonstantin Kirik (snegovick) <snegovick@uprojects.org>2025-12-28 12:27:31 +0300
commit78ee7d5717807e6ac779293d0d3c78341de6130a (patch)
treea43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/pc/devmouse.c
parentbdaf46cf45bbb59261da245d548a179d95a42768 (diff)
Move existing boards into subdits split per arch
Diffstat (limited to 'os/pc/devmouse.c')
-rw-r--r--os/pc/devmouse.c672
1 files changed, 0 insertions, 672 deletions
diff --git a/os/pc/devmouse.c b/os/pc/devmouse.c
deleted file mode 100644
index 1b3c55c6..00000000
--- a/os/pc/devmouse.c
+++ /dev/null
@@ -1,672 +0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "io.h"
-#include "../port/error.h"
-
-/*
- * TODO
- * - shift key should modify right button with non-serial mice
- * + intellimouse implementation
- * - acceleration for all mouse types
- * + spurious interrupt 7 after probing for ps2 mouse for the first time...?
- * - test with ms busmouse
- * - test with logitech serial mouse
- */
-
-/*
- * mouse types
- */
-enum
-{
- Mouseother,
- Mouseserial,
- MousePS2,
- Mousebus,
- Mouseintelli,
- Mousemsbus,
-};
-
-static int mousetype;
-static int mouseswap;
-static int mouseport; /* port for serial mice, irq for bus mice */
-static int mousesubtype;
-static int accelerated;
-static QLock mouselock;
-
-static int msbusmousedetect(void);
-static int busmousedetect(void);
-static void mousectl(char *buf);
-static void mouseprobe(char *buf, int len);
-static void mousestatus(char *buf, int len);
-
-enum{
- Qdir,
- Qmousectl,
- Qmouseprobe,
-};
-
-static
-Dirtab mousetab[]={
- "mousectl", {Qmousectl, 0}, 0, 0600,
- "mouseprobe", {Qmouseprobe, 0}, 0, 0400,
-};
-
-static Chan*
-mouseattach(char* spec)
-{
- return devattach('m', spec);
-}
-
-static int
-mousewalk(Chan* c, char* name)
-{
- return devwalk(c, name, mousetab, nelem(mousetab), devgen);
-}
-
-static void
-mousestat(Chan* c, char* db)
-{
- devstat(c, db, mousetab, nelem(mousetab), devgen);
-}
-
-static Chan*
-mouseopen(Chan* c, int omode)
-{
- return devopen(c, omode, mousetab, nelem(mousetab), devgen);
-}
-
-static void
-mouseclose(Chan* c)
-{
- USED(c);
-}
-
-static long
-mouseread(Chan* c, void* a, long n, vlong offset)
-{
- char buf[64];
- USED(offset);
-
- switch(c->qid.path & ~CHDIR){
- case Qdir:
- return devdirread(c, a, n, mousetab, nelem(mousetab), devgen);
- case Qmousectl:
- qlock(&mouselock);
- mousestatus(buf, sizeof(buf));
- qunlock(&mouselock);
- n = readstr(offset, a, n, buf);
- break;
- case Qmouseprobe:
- if (mousetype)
- error(Emouseset);
- mouseprobe(buf, sizeof(buf));
- n = readstr(offset, a, n, buf);
- break;
- default:
- n=0;
- break;
- }
- return n;
-}
-
-static long
-mousewrite(Chan* c, void *a, long n, vlong)
-{
- char buf[64];
- if ((c->qid.path & ~CHDIR) != Qmousectl)
- error(Ebadusefd);
- if (n >= sizeof(buf))
- n = sizeof(buf) - 1;
- strncpy(buf, a, n);
- buf[n] = 0;
-
- qlock(&mouselock);
- if (waserror()) {
- qunlock(&mouselock);
- nexterror();
- }
- mousectl(buf);
- poperror();
- qunlock(&mouselock);
- return n;
-}
-
-static void
-track(int b, int dx, int dy)
-{
- static uchar map[8] = {0,4,2,6,1,5,3,7};
- if (mouseswap)
- b = map[b&7];
- mousetrack(b, dx, dy);
-}
-
-static void
-setintellimouse(void)
-{
- i8042auxcmd(0xF3); /* set sample */
- i8042auxcmd(0xC8);
- i8042auxcmd(0xF3); /* set sample */
- i8042auxcmd(0x64);
- i8042auxcmd(0xF3); /* set sample */
- i8042auxcmd(0x50);
-}
-
-/*
- * check for an Intellimouse.
- * this is only used when we know there's an 8042 aux device
- */
-static int
-intellimousedetect(void)
-{
- int id;
- setintellimouse();
- /* check whether the mouse is now in extended mode */
- id = i8042auxcmdval(0xf2); /* identify device */
- if (id != 3) {
- /*
- * set back to standard sample rate (100 per sec)
- */
- i8042auxcmd(0xf3);
- i8042auxcmd(0x64);
- return 0;
- }
- return 1;
-}
-
-static void
-mouseprobe(char *buf, int len)
-{
- USED(len);
- /*
- * bus mice are easiest, so probe them first
- */
- if (busmousedetect())
- sprint(buf, "bus\n");
- else if (msbusmousedetect())
- sprint(buf, "msbus\n");
- else if (i8042auxdetect()) {
- if (intellimousedetect())
- sprint(buf, "ps2intellimouse\n");
- else
- sprint(buf, "ps2\n");
- }
- else
- *buf = 0;
-}
-
-
-static void
-mousestatus(char *buf, int len)
-{
- char *s;
- USED(len);
- s = buf;
- switch (mousetype) {
- case Mouseserial:
- if (mousesubtype)
- s += sprint(s, "serial %d %c\n", mouseport, mousesubtype);
- else
- s += sprint(s, "serial %d\n", mouseport);
- break;
- case MousePS2:
- s += sprint(s, "ps2\n");
- break;
- case Mousebus:
- s += sprint(s, "bus %d\n", mouseport);
- break;
- case Mouseintelli:
- s += sprint(s, "intelli\n");
- break;
- case Mousemsbus:
- s += sprint(s, "msbus %d\n", mouseport);
- break;
- default:
- case Mouseother:
- s += sprint(s, "unknown\n");
- break;
- }
- if (accelerated)
- s += sprint(s, "accelerated\n");
- if (mouseswap)
- sprint(s, "swap\n");
-}
-
-/*
- * Logitech 5 byte packed binary mouse format, 8 bit bytes
- *
- * shift & right button is the same as middle button (for 2 button mice)
- */
-static int
-logitechmouseputc(Queue *q, int c)
-{
- static short msg[5];
- static int nb;
- static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7};
- int dx, dy, newbuttons;
- int mouseshifted;
-
- USED(q);
- if((c&0xF0) == 0x80)
- nb=0;
- msg[nb] = c;
- if(c & 0x80)
- msg[nb] |= ~0xFF; /* sign extend */
- if(++nb == 5){
- mouseshifted = 0; /* XXX should be from keyboard shift key */
- newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)];
- dx = msg[1]+msg[3];
- dy = -(msg[2]+msg[4]);
- track(newbuttons, dx, dy);
- nb = 0;
- }
- return 0;
-}
-
-/*
- * microsoft 3 button, 7 bit bytes
- *
- * byte 0 - 1 L R Y7 Y6 X7 X6
- * byte 1 - 0 X5 X4 X3 X2 X1 X0
- * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0
- * byte 3 - 0 M x x x x x (optional)
- *
- * shift & right button is the same as middle button (for 2 button mice)
- */
-static int
-m3mouseputc(Queue*, int c)
-{
- static uchar msg[3];
- static int nb;
- static int middle;
- static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 };
- short x;
- int dx, dy, buttons;
-
- /*
- * check bit 6 for consistency
- */
- if(nb==0){
- if((c&0x40) == 0){
- /* an extra byte gets sent for the middle button */
- if(c & 0x1c)
- return 0;
- middle = (c&0x20) ? 2 : 0;
- buttons = (mouse.b & ~2) | middle;
- track(buttons, 0, 0);
- return 0;
- }
- }
- msg[nb] = c&0x3f;
- if(++nb == 3){
- nb = 0;
- buttons = middle | b[(msg[0]>>4)&3];
- x = (msg[0]&0x3)<<14;
- dx = (x>>8) | msg[1];
- x = (msg[0]&0xc)<<12;
- dy = (x>>8) | msg[2];
- track(buttons, dx, dy);
- }
- return 0;
-}
-
-static void
-serialmouse(int port, char *type, int setspeed)
-{
- int (*putc)(Queue *, int) = 0;
- char pn[KNAMELEN];
-
- if(mousetype)
- error(Emouseset);
-
- if(port >= 2 || port < 0)
- error(Ebadarg);
-
- if (type == 0)
- putc = logitechmouseputc;
- else if (*type == 'M')
- putc = m3mouseputc;
- else
- error(Ebadarg);
- snprint(pn, sizeof(pn), "%d", port);
- i8250mouse(pn, putc, setspeed);
- mousetype = Mouseserial;
- mouseport = port;
- mousesubtype = (type && *type == 'M') ? 'M' : 0;
-}
-
-/*
- * ps/2 mouse message is three bytes
- *
- * byte 0 - 0 0 SDY SDX 1 M R L
- * byte 1 - DX
- * byte 2 - DY
- *
- * shift & left button is the same as middle button
- */
-static void
-ps2mouseputc(int c, int shift)
-{
- static short msg[3];
- static int nb;
- static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 };
- int buttons, dx, dy;
-
- /*
- * check byte 0 for consistency
- */
- if(nb==0 && (c&0xc8)!=0x08)
- return;
-
- msg[nb] = c;
- if(++nb == 3){
- nb = 0;
- if(msg[0] & 0x10)
- msg[1] |= 0xFF00;
- if(msg[0] & 0x20)
- msg[2] |= 0xFF00;
-
- buttons = b[(msg[0]&7) | (shift ? 8 : 0)];
- dx = msg[1];
- dy = -msg[2];
- track(buttons, dx, dy);
- }
- return;
-}
-
-/*
- * set up a ps2 mouse
- */
-static void
-ps2mouse(void)
-{
- if(mousetype)
- error(Emouseset);
-
- i8042auxenable(ps2mouseputc);
- /* make mouse streaming, enabled */
- i8042auxcmd(0xEA);
- i8042auxcmd(0xF4);
-
- mousetype = MousePS2;
-}
-
-/* logitech bus mouse ports and commands */
-enum {
- /* ports */
- BMdatap = 0x23c,
- BMsigp = 0x23d,
- BMctlp = 0x23e,
- BMintrp = 0x23e,
- BMconfigp = 0x23f,
-
- /* commands */
- BMintron = 0x0,
- BMintroff = 0x10,
- BMrxlo = 0x80,
- BMrxhi = 0xa0,
- BMrylo = 0xc0,
- BMryhi = 0xe0,
-
- BMconfig = 0x91,
- BMdefault = 0x90,
-
- BMsigval = 0xa5
-};
-
-static void
-busmouseintr(Ureg *, void *)
-{
- char dx, dy;
- uchar b;
- static uchar oldb;
- static Lock intrlock;
- ilock(&intrlock);
- outb(BMintrp, BMintroff);
- outb(BMctlp, BMrxlo);
- dx = inb(BMdatap) & 0xf;
- outb(BMctlp, BMrxhi);
- dx |= (inb(BMdatap) & 0xf) << 4;
- outb(BMctlp, BMrylo);
- dy = inb(BMdatap) & 0xf;
- outb(BMctlp, BMryhi);
- b = inb(BMdatap);
- dy |= (b & 0xf) << 4;
- b = ~(b >> 5) & 7;
- if (dx || dy || b != oldb) {
- oldb = b;
- track((b>>2)|(b&0x02)|((b&0x01)<<2), dx, dy);
- }
- iunlock(&intrlock);
- outb(BMintrp, BMintron);
-}
-
-static int
-busmousedetect(void)
-{
- outb(BMconfigp, BMconfig);
- outb(BMsigp, BMsigval);
- delay(2);
- if (inb(BMsigp) != BMsigval)
- return 0;
- outb(BMconfigp, BMdefault);
- return 1;
-}
-
-/*
- * set up a logitech bus mouse
- */
-static void
-busmouse(int irq)
-{
- if (mousetype)
- error(Emouseset);
- if (!busmousedetect())
- error(Enodev);
-
- intrenable(irq >= 0 ? irq+VectorPIC : VectorBUSMOUSE, busmouseintr, 0, BUSUNKNOWN);
- outb(BMintrp, BMintron);
- mousetype = Mousebus;
- mouseport = irq >= 0 ? irq : VectorBUSMOUSE-VectorPIC;
-}
-
-/* microsoft bus mouse ports and commands */
-enum {
- MBMdatap= 0x23d,
- MBMsigp= 0x23e,
- MBMctlp= 0x23c,
- MBMconfigp= 0x23f,
-
- MBMintron= 0x11,
- MBMintroff= 0x10,
- MBMrbuttons= 0x00,
- MBMrx= 0x01,
- MBMry= 0x02,
- MBMstart= 0x80,
- MBMcmd= 0x07,
-};
-
-static void
-msbusmouseintr(Ureg *, void *)
-{
- char dx, dy;
- uchar b;
- static uchar oldb;
- static Lock intrlock;
- ilock(&intrlock);
- outb(MBMctlp, MBMcmd);
- outb(MBMdatap, inb(MBMdatap)|0x20);
-
- outb(MBMctlp, MBMrx);
- dx = inb(MBMdatap);
-
- outb(MBMctlp, MBMry);
- dy = inb(MBMdatap);
-
- outb(MBMctlp, MBMrbuttons);
- b = inb(MBMdatap) & 0x7;
-
- outb(MBMctlp, MBMcmd);
- outb(MBMdatap, inb(MBMdatap)&0xdf);
-
- if (dx != 0 || dy != 0 || b != oldb) {
- oldb = b;
- /* XXX this is almost certainly wrong */
- track((b>>2)|(b&0x02)|((b&0x01)<<2), dx, dy);
- }
- iunlock(&intrlock);
-}
-
-static int
-msbusmousedetect(void)
-{
- if (inb(MBMsigp) == 0xde) {
- int v, i;
- delay(1);
- v = inb(MBMsigp);
- delay(1);
- for (i = 0; i < 4; i++) {
- if (inb(MBMsigp) != 0xde)
- break;
- delay(1);
- if (inb(MBMsigp) != v)
- break;
- delay(1);
- }
- if (i == 4) {
- outb(MBMctlp, MBMcmd);
- return 1;
- }
- }
- return 0;
-}
-
-static void
-msbusmouse(int irq)
-{
- if (mousetype)
- error(Emouseset);
- if (!msbusmousedetect())
- error(Enodev);
- mousetype = Mousemsbus;
- mouseport = irq >= 0 ? irq : VectorBUSMOUSE-VectorPIC;
- intrenable(irq >= 0 ? irq+VectorPIC : VectorBUSMOUSE, msbusmouseintr, 0, BUSUNKNOWN);
- outb(MBMdatap, MBMintron);
-}
-
-static void
-mousectl(char *buf)
-{
- int nf, x;
- char *field[10];
- nf = getfields(buf, field, 10, 1, " \t\n");
- if (nf < 1)
- return;
- if(strncmp(field[0], "serial", 6) == 0){
- switch(nf){
- /* the difference between these two cases is intriguing - wrtp */
- case 1:
- serialmouse(atoi(field[0]+6), 0, 1);
- break;
- case 2:
- serialmouse(atoi(field[1]), 0, 0);
- break;
- case 3:
- default:
- serialmouse(atoi(field[1]), field[2], 0);
- break;
- }
- } else if(strcmp(field[0], "ps2") == 0){
- ps2mouse();
- } else if (strcmp(field[0], "ps2intellimouse") == 0) {
- ps2mouse();
- setintellimouse();
- } else if (strncmp(field[0], "bus", 3) == 0 || strncmp(field[0], "msbus", 5) == 0) {
- int irq, isms;
-
- isms = (field[0][0] == 'm');
- if (nf == 1)
- irq = atoi(field[0] + (isms ? 5 : 3));
- else
- irq = atoi(field[1]);
- if (irq < 1)
- irq = -1;
- if (isms)
- msbusmouse(irq);
- else
- busmouse(irq);
- } else if(strcmp(field[0], "accelerated") == 0){
- switch(mousetype){
- case MousePS2:
- x = splhi();
- i8042auxcmd(0xE7);
- splx(x);
- accelerated = 1;
- break;
- }
- } else if(strcmp(field[0], "linear") == 0){
- switch(mousetype){
- case MousePS2:
- x = splhi();
- i8042auxcmd(0xE6);
- splx(x);
- accelerated = 0;
- break;
- }
- } else if(strcmp(field[0], "res") == 0){
- int n,m;
- switch(nf){
- default:
- n = 0x02;
- m = 0x23;
- break;
- case 2:
- n = atoi(field[1])&0x3;
- m = 0x7;
- break;
- case 3:
- n = atoi(field[1])&0x3;
- m = atoi(field[2])&0x7;
- break;
- }
-
- switch(mousetype){
- case MousePS2:
- x = splhi();
- i8042auxcmd(0xE8);
- i8042auxcmd(n);
- i8042auxcmd(0x5A);
- i8042auxcmd(0x30|m);
- i8042auxcmd(0x5A);
- i8042auxcmd(0x20|(m>>1));
- splx(x);
- break;
- }
- } else if(strcmp(field[0], "swap") == 0)
- mouseswap ^= 1;
-}
-
-Dev mousedevtab = { /* defaults in dev.c */
- 'm',
- "mouse",
-
- devreset, /* devreset */
- devinit, /* devinit */
- mouseattach,
- devdetach,
- devclone, /* devclone */
- mousewalk,
- mousestat,
- mouseopen,
- devcreate, /* devcreate */
- mouseclose,
- mouseread,
- devbread, /* devbread */
- mousewrite,
- devbwrite, /* devbwrite */
- devremove, /* devremove */
- devwstat, /* devwstat */
-};
-