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 unsigned int mouse_state(int *xp, int *yp)
109 /* TODO: poll_mouse doesn't work (enable remote mode and disable interrupt on init to test) */
110 #define STAT_AUX_PENDING (KB_STAT_OUTBUF_FULL | KB_STAT_AUX)
111 static inline int aux_pending(void)
113 return (inp(KB_STATUS_PORT) & STAT_AUX_PENDING) == STAT_AUX_PENDING ? 1 : 0;
116 void poll_mouse(void)
118 static int poll_state;
119 static unsigned char pkt[3];
122 ser_printf("poll_mouse(%d)\n", poll_state);
125 case 0: /* send read mouse command */
126 kb_send_cmd(KB_CMD_PSAUX);
127 kb_send_data(AUX_CMD_READ_MOUSE);
131 case 1: /* wait for ACK */
132 if(kb_wait_read()) {// && aux_pending()) {
133 if((rd = kb_read_data()) == KB_ACK) {
136 ser_printf("poll_mouse state 1: expected ack: %02x\n", (unsigned int)rd);
141 case 2: /* read packet data */
144 if(kb_wait_read() && aux_pending()) {
145 int i = poll_state++ - 2;
146 pkt[i] = kb_read_data();
148 if(poll_state == 5) {
149 ser_printf("proc_mouse_data(%02x %02x %02x)\n", (unsigned int)pkt[0],
150 (unsigned int)pkt[1], (unsigned int)pkt[2]);
151 proc_mouse_data(pkt);
157 ser_printf("poll_mouse reached state: %d\n", poll_state);
161 static void proc_mouse_data(unsigned char *data)
165 if(data[0] & AUX_PKT0_OVF_BITS) {
166 /* consensus seems to be that if overflow bits are set, something is
167 * fucked, and it's best to re-initialize the mouse
171 bnstate = data[0] & AUX_PKT0_BUTTON_BITS;
175 if(data[0] & AUX_PKT0_XSIGN) {
178 if(data[0] & AUX_PKT0_YSIGN) {
185 if(mx < bounds[0]) mx = bounds[0];
186 if(mx > bounds[2]) mx = bounds[2];
187 if(my < bounds[1]) my = bounds[1];
188 if(my > bounds[3]) my = bounds[3];
192 static void psaux_intr()
194 static unsigned char data[3];
197 if(!(inp(KB_STATUS_PORT) & KB_STAT_AUX)) {
198 /* no mouse data pending, ignore interrupt */
202 data[idx] = kb_read_data();
206 proc_mouse_data(data);