2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY, without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
25 static void init_mouse(void);
26 static void proc_mouse_data(unsigned char *data);
27 static void psaux_intr();
30 static unsigned int bnstate;
37 interrupt(IRQ_TO_INTR(12), psaux_intr);
40 set_mouse_bounds(0, 0, 319, 199);
43 static void init_mouse(void)
47 kb_send_cmd(KB_CMD_AUX_ENABLE);
50 printf("aux enable: %02x\n", (unsigned int)val);
54 kb_send_cmd(KB_CMD_PSAUX);
55 kb_send_data(AUX_CMD_REMOTE_MODE);
59 kb_send_cmd(KB_CMD_GET_CMDBYTE);
61 val &= ~KB_CCB_AUX_DISABLE;
62 val |= KB_CCB_AUX_INTREN;
63 kb_send_cmd(KB_CMD_SET_CMDBYTE);
68 printf("set cmdbyte: %02x\n", (unsigned int)val);
72 kb_send_cmd(KB_CMD_PSAUX);
73 kb_send_data(AUX_CMD_DEFAULTS);
76 kb_send_cmd(KB_CMD_PSAUX);
77 kb_send_data(AUX_CMD_ENABLE);
80 present = (val == KB_ACK) ? 1 : 0;
81 printf("init_mouse: %spresent\n", present ? "" : "not ");
89 void set_mouse_bounds(int x0, int y0, int x1, int y1)
97 unsigned int mouse_state(int *xp, int *yp)
108 /* TODO: poll_mouse doesn't work (enable remote mode and disable interrupt on init to test) */
109 #define STAT_AUX_PENDING (KB_STAT_OUTBUF_FULL | KB_STAT_AUX)
110 static inline int aux_pending(void)
112 return (inp(KB_STATUS_PORT) & STAT_AUX_PENDING) == STAT_AUX_PENDING ? 1 : 0;
115 void poll_mouse(void)
117 static int poll_state;
118 static unsigned char pkt[3];
121 ser_printf("poll_mouse(%d)\n", poll_state);
124 case 0: /* send read mouse command */
125 kb_send_cmd(KB_CMD_PSAUX);
126 kb_send_data(AUX_CMD_READ_MOUSE);
130 case 1: /* wait for ACK */
131 if(kb_wait_read()) {// && aux_pending()) {
132 if((rd = kb_read_data()) == KB_ACK) {
135 ser_printf("poll_mouse state 1: expected ack: %02x\n", (unsigned int)rd);
140 case 2: /* read packet data */
143 if(kb_wait_read() && aux_pending()) {
144 int i = poll_state++ - 2;
145 pkt[i] = kb_read_data();
147 if(poll_state == 5) {
148 ser_printf("proc_mouse_data(%02x %02x %02x)\n", (unsigned int)pkt[0],
149 (unsigned int)pkt[1], (unsigned int)pkt[2]);
150 proc_mouse_data(pkt);
156 ser_printf("poll_mouse reached state: %d\n", poll_state);
160 static void proc_mouse_data(unsigned char *data)
164 if(data[0] & AUX_PKT0_OVF_BITS) {
165 /* consensus seems to be that if overflow bits are set, something is
166 * fucked, and it's best to re-initialize the mouse
170 bnstate = data[0] & AUX_PKT0_BUTTON_BITS;
174 if(data[0] & AUX_PKT0_XSIGN) {
177 if(data[0] & AUX_PKT0_YSIGN) {
184 if(mx < bounds[0]) mx = bounds[0];
185 if(mx > bounds[2]) mx = bounds[2];
186 if(my < bounds[1]) my = bounds[1];
187 if(my > bounds[3]) my = bounds[3];
191 static void psaux_intr()
193 static unsigned char data[3];
196 if(!(inp(KB_STATUS_PORT) & KB_STAT_AUX)) {
197 /* no mouse data pending, ignore interrupt */
201 data[idx] = kb_read_data();
205 proc_mouse_data(data);