From 9358438bef42dbbcd1492a52d9010899a9756d2c Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 12 May 2018 04:21:21 +0300 Subject: [PATCH] tried to make ps/2 mouse work in "remote mode" (polling), but it doesn't work. For now only interrupt (stream mode) works. Also added ser_printf --- src/contty.h | 1 + src/kbregs.h | 3 ++ src/keyb.c | 6 +++ src/libc/stdio.c | 84 +++++++++++++++++++++++--------- src/libc/stdio.h | 4 ++ src/psaux.c | 140 ++++++++++++++++++++++++++++++++++++++---------------- src/psaux.h | 2 + 7 files changed, 177 insertions(+), 63 deletions(-) diff --git a/src/contty.h b/src/contty.h index 66d9fb5..bbd2775 100644 --- a/src/contty.h +++ b/src/contty.h @@ -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_ */ diff --git a/src/kbregs.h b/src/kbregs.h index abf6524..5c56c48 100644 --- a/src/kbregs.h +++ b/src/kbregs.h @@ -55,6 +55,9 @@ along with this program. If not, see . #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 diff --git a/src/keyb.c b/src/keyb.c index 0b61871..3e86f43 100644 --- a/src/keyb.c +++ b/src/keyb.c @@ -22,6 +22,11 @@ along with this program. If not, see . #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); } diff --git a/src/libc/stdio.c b/src/libc/stdio.c index 449a5aa..1f2bb13 100644 --- a/src/libc/stdio.c +++ b/src/libc/stdio.c @@ -19,11 +19,19 @@ along with this program. If not, see . #include #include #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. #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); } } diff --git a/src/psaux.h b/src/psaux.h index bbaf96e..7acc3f6 100644 --- a/src/psaux.h +++ b/src/psaux.h @@ -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_ */ -- 1.7.10.4