added PS/2 mouse code
[bootcensus] / src / test / vbetest.c
1 #include <stdio.h>
2 #include <string.h>
3 #include "video.h"
4 #include "asmops.h"
5 #include "keyb.h"
6 #include "psaux.h"
7 #include "contty.h"
8
9 static void draw_cursor(int x, int y, uint16_t col);
10
11 static uint16_t *framebuf;
12
13 #define CURSOR_XSZ      12
14 #define CURSOR_YSZ      16
15 static uint16_t cursor[] = {
16         0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
17         0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
18         0xffff, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
19         0xffff, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
20         0xffff, 0x0001, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
21         0xffff, 0x0001, 0x0001, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
22         0xffff, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
23         0xffff, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000,
24         0xffff, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000,
25         0xffff, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000,
26         0xffff, 0x0001, 0x0001, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
27         0xffff, 0x0001, 0x0001, 0xffff, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
28         0xffff, 0x0001, 0xffff, 0xffff, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
29         0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000,
30         0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0001, 0x0001, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000,
31         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
32 };
33
34 int vbetest(void)
35 {
36         int i, j, nmodes, mx, my;
37         unsigned int st;
38         struct video_mode vi;
39         uint16_t *fbptr;
40
41         nmodes = video_mode_count();
42         printf("%d video modes found:\n", nmodes);
43         for(i=0; i<nmodes; i++) {
44                 if(video_mode_info(i, &vi) == -1) {
45                         continue;
46                 }
47                 printf(" %04x: %dx%d %d bpp", vi.mode, vi.width, vi.height, vi.bpp);
48                 if(vi.bpp > 8) {
49                         printf(" (%d%d%d)\n", vi.rbits, vi.gbits, vi.bbits);
50                 } else {
51                         putchar('\n');
52                 }
53         }
54
55         if(!(framebuf = set_video_mode(find_video_mode(640, 480, 16)))) {
56                 return -1;
57         }
58         get_color_bits(&vi.rbits, &vi.gbits, &vi.bbits);
59         get_color_shift(&vi.rshift, &vi.gshift, &vi.bshift);
60         get_color_mask(&vi.rmask, &vi.gmask, &vi.bmask);
61
62         fbptr = framebuf;
63         for(i=0; i<480; i++) {
64                 for(j=0; j<640; j++) {
65                         int xor = i^j;
66                         uint16_t r = xor & 0xff;
67                         uint16_t g = (xor << 1) & 0xff;
68                         uint16_t b = (xor << 2) & 0xff;
69
70                         r >>= 8 - vi.rbits;
71                         g >>= 8 - vi.gbits;
72                         b >>= 8 - vi.bbits;
73
74                         *fbptr++ = ((r << vi.rshift) & vi.rmask) | ((g << vi.gshift) & vi.gmask) |
75                                 ((b << vi.bshift) & vi.bmask);
76                 }
77         }
78
79         set_mouse_bounds(0, 0, 639, 479);
80
81         /* empty the kb queue */
82         while(kb_getkey() != -1);
83
84         for(;;) {
85                 if(kb_getkey() != -1) {
86                         break;
87                 }
88
89                 st = mouse_state(&mx, &my);
90                 draw_cursor(mx, my, st & 1 ? 0xf800 : (st & 2 ? 0x7e0 : (st & 4 ? 0x00ff : 0)));
91
92                 halt_cpu();
93         }
94
95         set_vga_mode(3);
96         con_clear();
97         return 0;
98 }
99
100 static void draw_cursor(int x, int y, uint16_t col)
101 {
102         static uint16_t saved[CURSOR_XSZ * CURSOR_YSZ];
103         static int saved_x = -1, saved_y, saved_w, saved_h;
104
105         int i, j, w, h;
106         uint16_t *dest, *src, *savp;
107
108         if(saved_x >= 0) {
109                 dest = framebuf + saved_y * 640 + saved_x;
110                 src = saved;
111
112                 for(i=0; i<saved_h; i++) {
113                         for(j=0; j<saved_w; j++) {
114                                 *dest++ = *src++;
115                         }
116                         src += CURSOR_XSZ - saved_w;
117                         dest += 640 - saved_w;
118                 }
119         }
120
121         dest = framebuf + y * 640 + x;
122         src = cursor;
123         savp = saved;
124
125         w = 640 - x;
126         if(w > CURSOR_XSZ) w = CURSOR_XSZ;
127         h = 480 - y;
128         if(h > CURSOR_YSZ) h = CURSOR_YSZ;
129
130         saved_x = x;
131         saved_y = y;
132         saved_w = w;
133         saved_h = h;
134
135         for(i=0; i<h; i++) {
136                 for(j=0; j<w; j++) {
137                         uint16_t c = *src++;
138                         *savp++ = *dest;
139                         if(c) {
140                                 if(c == 1) c = col;
141                                 *dest = c;
142                         }
143                         dest++;
144                 }
145                 src += CURSOR_XSZ - w;
146                 dest += 640 - w;
147                 savp += CURSOR_XSZ - w;
148         }
149 }