diff options
| author | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
|---|---|---|
| committer | Konstantin Kirik (snegovick) <snegovick@uprojects.org> | 2025-12-28 12:27:31 +0300 |
| commit | 78ee7d5717807e6ac779293d0d3c78341de6130a (patch) | |
| tree | a43e3b0f61318ac45e6d907c7cc5bad2c6d7f497 /os/pc/devmouse.c | |
| parent | bdaf46cf45bbb59261da245d548a179d95a42768 (diff) | |
Move existing boards into subdits split per arch
Diffstat (limited to 'os/pc/devmouse.c')
| -rw-r--r-- | os/pc/devmouse.c | 672 |
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 */ -}; - |
