tried to make ps/2 mouse work in "remote mode" (polling), but it doesn't
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 12 May 2018 01:21:21 +0000 (04:21 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 12 May 2018 01:21:21 +0000 (04:21 +0300)
work. For now only interrupt (stream mode) works.
Also added ser_printf

src/contty.h
src/kbregs.h
src/keyb.c
src/libc/stdio.c
src/libc/stdio.h
src/psaux.c
src/psaux.h

index 66d9fb5..bbd2775 100644 (file)
@@ -27,5 +27,6 @@ void con_clear(void);
 void con_putchar(int c);
 
 void con_putchar_scr(int x, int y, int c);
+void con_printf(int x, int y, const char *fmt, ...);
 
 #endif /* CONTTY_H_ */
index abf6524..5c56c48 100644 (file)
@@ -55,6 +55,9 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #define KB_CCB_KB_XLAT                 0x40
 
 /* psaux commands (use with d4 prefix) */
+#define AUX_CMD_STREAM_MODE            0xea
+#define AUX_CMD_READ_MOUSE             0xeb
+#define AUX_CMD_REMOTE_MODE            0xf0
 #define AUX_CMD_ENABLE                 0xf4
 #define AUX_CMD_DEFAULTS               0xf6
 
index 0b61871..3e86f43 100644 (file)
@@ -22,6 +22,11 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include "asmops.h"
 #include "kbregs.h"
 
+#define delay7us() \
+       do { \
+               iodelay(); iodelay(); iodelay(); iodelay(); \
+               iodelay(); iodelay(); iodelay(); \
+       } while(0)
 
 /* table with rough translations from set 1 scancodes to ASCII-ish */
 static int scantbl[] = {
@@ -156,6 +161,7 @@ void kb_send_data(unsigned char data)
 unsigned char kb_read_data(void)
 {
        kb_wait_read();
+       delay7us();
        return inb(KB_DATA_PORT);
 }
 
index 449a5aa..1f2bb13 100644 (file)
@@ -19,11 +19,19 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include <string.h>
 #include <ctype.h>
 #include "contty.h"
+#include "serial.h"
+
+enum {
+       OUT_DEF,
+       OUT_BUF,
+       OUT_SCR,
+       OUT_SER
+};
 
 extern void pcboot_putchar(int c);
 
-static void bwrite(char *buf, size_t buf_sz, char *str, int sz);
-static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap);
+static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz);
+static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap);
 
 int putchar(int c)
 {
@@ -52,14 +60,14 @@ int printf(const char *fmt, ...)
        va_list ap;
 
        va_start(ap, fmt);
-       res = intern_printf(0, 0, fmt, ap);
+       res = intern_printf(OUT_DEF, 0, 0, fmt, ap);
        va_end(ap);
        return res;
 }
 
 int vprintf(const char *fmt, va_list ap)
 {
-       return intern_printf(0, 0, fmt, ap);
+       return intern_printf(OUT_DEF, 0, 0, fmt, ap);
 }
 
 int sprintf(char *buf, const char *fmt, ...)
@@ -68,14 +76,14 @@ int sprintf(char *buf, const char *fmt, ...)
        va_list ap;
 
        va_start(ap, fmt);
-       res = intern_printf(buf, 0, fmt, ap);
+       res = intern_printf(OUT_BUF, buf, 0, fmt, ap);
        va_end(ap);
        return res;
 }
 
 int vsprintf(char *buf, const char *fmt, va_list ap)
 {
-       return intern_printf(buf, 0, fmt, ap);
+       return intern_printf(OUT_BUF, buf, 0, fmt, ap);
 }
 
 int snprintf(char *buf, size_t sz, const char *fmt, ...)
@@ -84,16 +92,31 @@ int snprintf(char *buf, size_t sz, const char *fmt, ...)
        va_list ap;
 
        va_start(ap, fmt);
-       res = intern_printf(buf, sz, fmt, ap);
+       res = intern_printf(OUT_BUF, buf, sz, fmt, ap);
        va_end(ap);
        return res;
 }
 
 int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap)
 {
-       return intern_printf(buf, sz, fmt, ap);
+       return intern_printf(OUT_BUF, buf, sz, fmt, ap);
 }
 
+int ser_printf(const char *fmt, ...)
+{
+       int res;
+       va_list ap;
+
+       va_start(ap, fmt);
+       res = intern_printf(OUT_SER, 0, 0, fmt, ap);
+       va_end(ap);
+       return res;
+}
+
+int ser_vprintf(const char *fmt, va_list ap)
+{
+       return intern_printf(OUT_SER, 0, 0, fmt, ap);
+}
 
 /* intern_printf provides all the functionality needed by all the printf
  * variants.
@@ -108,7 +131,7 @@ int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap)
 #define BUF(x) ((x) ? (x) + cnum : (x))
 #define SZ(x)  ((x) ? (x) - cnum : (x))
 
-static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
+static int intern_printf(int out, char *buf, size_t sz, const char *fmt, va_list ap)
 {
        char conv_buf[32];
        char *str;
@@ -143,7 +166,7 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
                                        base = 16;
 
                                        if(alt) {
-                                               bwrite(BUF(buf), SZ(sz), "0x", 2);
+                                               bwrite(out, BUF(buf), SZ(sz), "0x", 2);
                                        }
 
                                case 'u':
@@ -154,7 +177,7 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
                                                base = 8;
 
                                                if(alt) {
-                                                       bwrite(BUF(buf), SZ(sz), "0", 1);
+                                                       bwrite(out, BUF(buf), SZ(sz), "0", 1);
                                                }
                                        }
 
@@ -173,18 +196,18 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
 
                                        slen = strlen(conv_buf);
                                        for(i=slen; i<fwidth; i++) {
-                                               bwrite(BUF(buf), SZ(sz), (char*)&padc, 1);
+                                               bwrite(out, BUF(buf), SZ(sz), (char*)&padc, 1);
                                                cnum++;
                                        }
 
-                                       bwrite(BUF(buf), SZ(sz), conv_buf, strlen(conv_buf));
+                                       bwrite(out, BUF(buf), SZ(sz), conv_buf, strlen(conv_buf));
                                        cnum += slen;
                                        break;
 
                                case 'c':
                                        {
                                                char c = va_arg(ap, int);
-                                               bwrite(BUF(buf), SZ(sz), &c, 1);
+                                               bwrite(out, BUF(buf), SZ(sz), &c, 1);
                                                cnum++;
                                        }
                                        break;
@@ -194,10 +217,10 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
                                        slen = strlen(str);
 
                                        for(i=slen; i<fwidth; i++) {
-                                               bwrite(BUF(buf), SZ(sz), (char*)&padc, 1);
+                                               bwrite(out, BUF(buf), SZ(sz), (char*)&padc, 1);
                                                cnum++;
                                        }
-                                       bwrite(BUF(buf), SZ(sz), str, slen);
+                                       bwrite(out, BUF(buf), SZ(sz), str, slen);
                                        cnum += slen;
                                        break;
 
@@ -252,7 +275,7 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
                                fmt++;
                        }
                } else {
-                       bwrite(BUF(buf), SZ(sz), (char*)fmt++, 1);
+                       bwrite(out, BUF(buf), SZ(sz), (char*)fmt++, 1);
                        cnum++;
                }
        }
@@ -262,19 +285,34 @@ static int intern_printf(char *buf, size_t sz, const char *fmt, va_list ap)
 
 
 /* bwrite is called by intern_printf to transparently handle writing into a
- * buffer (if buf is non-null) or to the terminal (if buf is null).
+ * buffer or to the terminal
  */
-static void bwrite(char *buf, size_t buf_sz, char *str, int sz)
+static void bwrite(int out, char *buf, size_t buf_sz, char *str, int sz)
 {
-       if(buf) {
+       int i;
+
+       if(out == OUT_BUF) {
                if(buf_sz && buf_sz <= sz) sz = buf_sz - 1;
                memcpy(buf, str, sz);
 
                buf[sz] = 0;
        } else {
-               int i;
-               for(i=0; i<sz; i++) {
-                       putchar(*str++);
+               switch(out) {
+               case OUT_DEF:
+                       for(i=0; i<sz; i++) {
+                               putchar(*str++);
+                       }
+                       break;
+
+               case OUT_SER:
+                       for(i=0; i<sz; i++) {
+                               ser_putchar(*str++);
+                       }
+                       break;
+
+               default:
+                       /* TODO: OUT_SCR */
+                       break;
                }
        }
 }
index e968172..fbc79b7 100644 (file)
@@ -33,4 +33,8 @@ int vsprintf(char *buf, const char *fmt, va_list ap);
 int snprintf(char *buf, size_t sz, const char *fmt, ...);
 int vsnprintf(char *buf, size_t sz, const char *fmt, va_list ap);
 
+/* printf to the serial port */
+int ser_printf(const char *fmt, ...);
+int ser_vprintf(const char *fmt, va_list ap);
+
 #endif /* STDIO_H_ */
index d6d5f2e..bd5a8be 100644 (file)
@@ -22,24 +22,25 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include "keyb.h"
 #include "kbregs.h"
 
-static void init_mouse();
+static void init_mouse(void);
+static void proc_mouse_data(unsigned char *data);
 static void psaux_intr();
 
 static int mx, my;
 static unsigned int bnstate;
 static int present;
 static int bounds[4];
+static int intr_mode;
 
 void init_psaux(void)
 {
        interrupt(IRQ_TO_INTR(12), psaux_intr);
 
-       set_mouse_bounds(0, 0, 319, 199);
-
        init_mouse();
+       set_mouse_bounds(0, 0, 319, 199);
 }
 
-static void init_mouse()
+static void init_mouse(void)
 {
        unsigned char val;
 
@@ -49,6 +50,12 @@ static void init_mouse()
                printf("aux enable: %02x\n", (unsigned int)val);
        }
 
+       /*
+       kb_send_cmd(KB_CMD_PSAUX);
+       kb_send_data(AUX_CMD_REMOTE_MODE);
+       val = kb_read_data();
+       */
+
        kb_send_cmd(KB_CMD_GET_CMDBYTE);
        val = kb_read_data();
        val &= ~KB_CCB_AUX_DISABLE;
@@ -60,6 +67,7 @@ static void init_mouse()
                val = kb_read_data();
                printf("set cmdbyte: %02x\n", (unsigned int)val);
        }
+       intr_mode = 1;
 
        kb_send_cmd(KB_CMD_PSAUX);
        kb_send_data(AUX_CMD_DEFAULTS);
@@ -88,16 +96,102 @@ void set_mouse_bounds(int x0, int y0, int x1, int y1)
 
 unsigned int mouse_state(int *xp, int *yp)
 {
+       if(!intr_mode) {
+               poll_mouse();
+       }
+
        *xp = mx;
        *yp = my;
        return bnstate;
 }
 
+/* TODO: poll_mouse doesn't work (enable remote mode and disable interrupt on init to test) */
+#define STAT_AUX_PENDING               (KB_STAT_OUTBUF_FULL | KB_STAT_AUX)
+static inline int aux_pending(void)
+{
+       return (inb(KB_STATUS_PORT) & STAT_AUX_PENDING) == STAT_AUX_PENDING ? 1 : 0;
+}
+
+void poll_mouse(void)
+{
+       static int poll_state;
+       static unsigned char pkt[3];
+       unsigned char rd;
+
+       ser_printf("poll_mouse(%d)\n", poll_state);
+
+       switch(poll_state) {
+       case 0: /* send read mouse command */
+               kb_send_cmd(KB_CMD_PSAUX);
+               kb_send_data(AUX_CMD_READ_MOUSE);
+               ++poll_state;
+               break;
+
+       case 1: /* wait for ACK */
+               if(kb_wait_read()) {// && aux_pending()) {
+                       if((rd = kb_read_data()) == KB_ACK) {
+                               ++poll_state;
+                       } else {
+                               ser_printf("poll_mouse state 1: expected ack: %02x\n", (unsigned int)rd);
+                       }
+               }
+               break;
+
+       case 2: /* read packet data */
+       case 3:
+       case 4:
+               if(kb_wait_read() && aux_pending()) {
+                       int i = poll_state++ - 2;
+                       pkt[i] = kb_read_data();
+               }
+               if(poll_state == 5) {
+                       ser_printf("proc_mouse_data(%02x %02x %02x)\n", (unsigned int)pkt[0],
+                                       (unsigned int)pkt[1], (unsigned int)pkt[2]);
+                       proc_mouse_data(pkt);
+                       poll_state = 0;
+               }
+               break;
+
+       default:
+               ser_printf("poll_mouse reached state: %d\n", poll_state);
+       }
+}
+
+static void proc_mouse_data(unsigned char *data)
+{
+       int dx, dy;
+
+       if(data[0] & AUX_PKT0_OVF_BITS) {
+               /* consensus seems to be that if overflow bits are set, something is
+                * fucked, and it's best to re-initialize the mouse
+                */
+               /*init_mouse();*/
+       } else {
+               bnstate = data[0] & AUX_PKT0_BUTTON_BITS;
+               dx = data[1];
+               dy = data[2];
+
+               if(data[0] & AUX_PKT0_XSIGN) {
+                       dx |= 0xffffff00;
+               }
+               if(data[0] & AUX_PKT0_YSIGN) {
+                       dy |= 0xffffff00;
+               }
+
+               mx += dx;
+               my -= dy;
+
+               if(mx < bounds[0]) mx = bounds[0];
+               if(mx > bounds[2]) mx = bounds[2];
+               if(my < bounds[1]) my = bounds[1];
+               if(my > bounds[3]) my = bounds[3];
+       }
+}
+
 static void psaux_intr()
 {
        static unsigned char data[3];
        static int idx;
-       int dx, dy;
 
        if(!(inb(KB_STATUS_PORT) & KB_STAT_AUX)) {
                /* no mouse data pending, ignore interrupt */
@@ -108,40 +202,6 @@ static void psaux_intr()
        if(++idx >= 3) {
                idx = 0;
 
-               if(data[0] & AUX_PKT0_OVF_BITS) {
-                       /* consensus seems to be that if overflow bits are set, something is
-                        * fucked, and it's best to re-initialize the mouse
-                        */
-                       init_mouse();
-               } else {
-                       /*
-                       printf("psaux data packet: %02x %02x %02x\n", (unsigned int)data[0],
-                                       (unsigned int)data[1], (unsigned int)data[2]);
-                       */
-
-                       bnstate = data[0] & AUX_PKT0_BUTTON_BITS;
-                       dx = data[1];
-                       dy = data[2];
-
-                       if(data[0] & AUX_PKT0_XSIGN) {
-                               dx |= 0xffffff00;
-                       }
-                       if(data[0] & AUX_PKT0_YSIGN) {
-                               dy |= 0xffffff00;
-                       }
-
-                       mx += dx;
-                       my -= dy;
-
-                       if(mx < bounds[0]) mx = bounds[0];
-                       if(mx > bounds[2]) mx = bounds[2];
-                       if(my < bounds[1]) my = bounds[1];
-                       if(my > bounds[3]) my = bounds[3];
-
-                       /*
-                       printf("mouse: %d,%d [%c%c%c]\n", mx, my, bnstate & AUX_PKT0_LEFTBN ? '1' : '0',
-                                       bnstate & AUX_PKT0_MIDDLEBN ? '1' : '0', bnstate & AUX_PKT0_RIGHTBN ? '1' : '0');
-                       */
-               }
+               proc_mouse_data(data);
        }
 }
index bbaf96e..7acc3f6 100644 (file)
@@ -29,4 +29,6 @@ int have_mouse(void);
 void set_mouse_bounds(int x0, int y0, int x1, int y1);
 unsigned int mouse_state(int *xp, int *yp);
 
+void poll_mouse(void);
+
 #endif /* PSAUX_H_ */