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);
41 set_mouse_bounds(0, 0, 319, 199);
44 static void init_mouse(void)
48 kb_send_cmd(KB_CMD_AUX_ENABLE);
51 printf("aux enable: %02x\n", (unsigned int)val);
55 kb_send_cmd(KB_CMD_PSAUX);
56 kb_send_data(AUX_CMD_REMOTE_MODE);
60 kb_send_cmd(KB_CMD_GET_CMDBYTE);
62 val &= ~KB_CCB_AUX_DISABLE;
63 val |= KB_CCB_AUX_INTREN;
64 kb_send_cmd(KB_CMD_SET_CMDBYTE);
69 printf("set cmdbyte: %02x\n", (unsigned int)val);
73 kb_send_cmd(KB_CMD_PSAUX);
74 kb_send_data(AUX_CMD_DEFAULTS);
77 kb_send_cmd(KB_CMD_PSAUX);
78 kb_send_data(AUX_CMD_ENABLE);
81 present = (val == KB_ACK) ? 1 : 0;
82 printf("init_mouse: %spresent\n", present ? "" : "not ");
90 void set_mouse_bounds(int x0, int y0, int x1, int y1)
98 void set_mouse_pos(int x, int y)
104 unsigned int mouse_state(int *xp, int *yp)
115 /* TODO: poll_mouse doesn't work (enable remote mode and disable interrupt on init to test) */
116 #define STAT_AUX_PENDING (KB_STAT_OUTBUF_FULL | KB_STAT_AUX)
117 static inline int aux_pending(void)
119 return (inp(KB_STATUS_PORT) & STAT_AUX_PENDING) == STAT_AUX_PENDING ? 1 : 0;
122 void poll_mouse(void)
124 static int poll_state;
125 static unsigned char pkt[3];
128 ser_printf("poll_mouse(%d)\n", poll_state);
131 case 0: /* send read mouse command */
132 kb_send_cmd(KB_CMD_PSAUX);
133 kb_send_data(AUX_CMD_READ_MOUSE);
137 case 1: /* wait for ACK */
138 if(kb_wait_read()) {// && aux_pending()) {
139 if((rd = kb_read_data()) == KB_ACK) {
142 ser_printf("poll_mouse state 1: expected ack: %02x\n", (unsigned int)rd);
147 case 2: /* read packet data */
150 if(kb_wait_read() && aux_pending()) {
151 int i = poll_state++ - 2;
152 pkt[i] = kb_read_data();
154 if(poll_state == 5) {
155 ser_printf("proc_mouse_data(%02x %02x %02x)\n", (unsigned int)pkt[0],
156 (unsigned int)pkt[1], (unsigned int)pkt[2]);
157 proc_mouse_data(pkt);
163 ser_printf("poll_mouse reached state: %d\n", poll_state);
167 static void proc_mouse_data(unsigned char *data)
171 if(data[0] & AUX_PKT0_OVF_BITS) {
172 /* consensus seems to be that if overflow bits are set, something is
173 * fucked, and it's best to re-initialize the mouse
177 bnstate = data[0] & AUX_PKT0_BUTTON_BITS;
181 if(data[0] & AUX_PKT0_XSIGN) {
184 if(data[0] & AUX_PKT0_YSIGN) {
191 if(mx < bounds[0]) mx = bounds[0];
192 if(mx > bounds[2]) mx = bounds[2];
193 if(my < bounds[1]) my = bounds[1];
194 if(my > bounds[3]) my = bounds[3];
198 static void psaux_intr()
200 static unsigned char data[3];
203 if(!(inp(KB_STATUS_PORT) & KB_STAT_AUX)) {
204 /* no mouse data pending, ignore interrupt */
208 data[idx] = kb_read_data();
212 proc_mouse_data(data);