Annotation of prex-old/dev/arm/gba/console.c, Revision 1.1.1.1
1.1 nbrk 1: /*-
2: * Copyright (c) 2005-2007, Kohsuke Ohtani
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. Neither the name of the author nor the names of any co-contributors
14: * may be used to endorse or promote products derived from this software
15: * without specific prior written permission.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * console.c - GBA console driver
32: */
33:
34: #include <driver.h>
35: #include <sys/tty.h>
36: #include "lcd.h"
37: #include "font.h"
38:
39: static int console_init(void);
40: static int console_read(device_t, char *, size_t *, int);
41: static int console_write(device_t, char *, size_t *, int);
42: static int console_ioctl(device_t, int, u_long);
43:
44: /*
45: * Driver structure
46: */
47: struct driver console_drv = {
48: /* name */ "GBA Console",
49: /* order */ 4,
50: /* init */ console_init,
51: };
52:
53: static struct devio console_io = {
54: /* open */ NULL,
55: /* close */ NULL,
56: /* read */ console_read,
57: /* write */ console_write,
58: /* ioctl */ console_ioctl,
59: /* event */ NULL,
60: };
61:
62: static device_t console_dev;
63: static struct tty console_tty;
64:
65: static uint16_t *vram = CONSOLE_MAP;
66: static int pos_x;
67: static int pos_y;
68: static u_short attrib;
69:
70: static int esc_index;
71: static int esc_arg1;
72: static int esc_arg2;
73: static int esc_argc;
74: static int esc_saved_x;
75: static int esc_saved_y;
76:
77: static u_short ansi_colors[] = {0, 4, 2, 6, 1, 5, 3, 7};
78:
79: static void
80: scroll_up(void)
81: {
82: int i;
83:
84: for (i = 0; i < VSCR_COLS * (SCR_ROWS - 1); i++)
85: vram[i] = vram[i + VSCR_COLS];
86: for (i = 0; i < VSCR_COLS; i++)
87: vram[VSCR_COLS * (SCR_ROWS - 1) + i] = ' ';
88: }
89:
90: static void
91: move_cursor(void)
92: {
93: }
94:
95:
96: static void
97: new_line(void)
98: {
99:
100: pos_x = 0;
101: pos_y++;
102: if (pos_y >= SCR_ROWS) {
103: pos_y = SCR_ROWS - 1;
104: scroll_up();
105: }
106: }
107:
108: static void
109: clear_screen(void)
110: {
111: int i;
112:
113: for (i = 0; i < VSCR_COLS * SCR_ROWS; i++)
114: vram[i] = ' ';
115:
116: pos_x = 0;
117: pos_y = 0;
118: move_cursor();
119: }
120:
121: /*
122: * Check for escape code sequence.
123: * Return true if escape
124: *
125: * <Support list>
126: * ESC[#;#H or : moves cursor to line #, column #
127: * ESC[#;#f
128: * ESC[#A : moves cursor up # lines
129: * ESC[#B : moves cursor down # lines
130: * ESC[#C : moves cursor right # spaces
131: * ESC[#D : moves cursor left # spaces
132: * ESC[#;#R : reports current cursor line & column
133: * ESC[s : save cursor position for recall later
134: * ESC[u : return to saved cursor position
135: * ESC[2J : clear screen and home cursor
136: * ESC[K : clear to end of line
137: *
138: * <Not support>
139: * ESC[#m : attribute (0=attribure off, 4=underline, 5=blink)
140: */
141: static int
142: check_escape(char c)
143: {
144: int move = 0;
145: int val;
146: u_short color;
147:
148: if (c == 033) {
149: esc_index = 1;
150: esc_argc = 0;
151: return 1;
152: }
153: if (esc_index == 0)
154: return 0;
155:
156: if (c >= '0' && c <= '9') {
157: val = c - '0';
158: switch (esc_argc) {
159: case 0:
160: esc_arg1 = val;
161: esc_index++;
162: break;
163: case 1:
164: esc_arg1 = esc_arg1 * 10 + val;
165: break;
166: case 2:
167: esc_arg2 = val;
168: esc_index++;
169: break;
170: case 3:
171: esc_arg2 = esc_arg2 * 10 + val;
172: break;
173: default:
174: goto reset;
175: }
176: esc_argc++;
177: return 1;
178: }
179:
180: esc_index++;
181:
182: switch (esc_index) {
183: case 2:
184: if (c != '[')
185: goto reset;
186: return 1;
187: case 3:
188: switch (c) {
189: case 's': /* Save cursor position */
190: esc_saved_x = pos_x;
191: esc_saved_y = pos_y;
192: break;
193: case 'u': /* Return to saved cursor position */
194: pos_x = esc_saved_x;
195: pos_y = esc_saved_y;
196: move_cursor();
197: break;
198: case 'K': /* Clear to end of line */
199: break;
200: }
201: goto reset;
202: case 4:
203: switch (c) {
204: case 'A': /* Move cursor up # lines */
205: pos_y -= esc_arg1;
206: if (pos_y < 0)
207: pos_y = 0;
208: move = 1;
209: break;
210: case 'B': /* Move cursor down # lines */
211: pos_y += esc_arg1;
212: if (pos_y >= SCR_ROWS)
213: pos_y = SCR_ROWS - 1;
214: move = 1;
215: break;
216: case 'C': /* Move cursor forward # spaces */
217: pos_x += esc_arg1;
218: if (pos_x >= SCR_COLS)
219: pos_x = SCR_COLS - 1;
220: move = 1;
221: break;
222: case 'D': /* Move cursor back # spaces */
223: pos_x -= esc_arg1;
224: if (pos_x < 0)
225: pos_x = 0;
226: move = 1;
227: break;
228: case ';':
229: if (esc_argc == 1)
230: esc_argc = 2;
231: return 1;
232: case 'J':
233: if (esc_arg1 == 2) /* Clear screen */
234: clear_screen();
235: break;
236: case 'm': /* Change attribute */
237: switch (esc_arg1) {
238: case 0: /* reset */
239: attrib = 0x0F;
240: break;
241: case 1: /* bold */
242: attrib = 0x0F;
243: break;
244: case 4: /* under line */
245: break;
246: case 5: /* blink */
247: attrib |= 0x80;
248: break;
249: case 30: case 31: case 32: case 33:
250: case 34: case 35: case 36: case 37:
251: color = ansi_colors[esc_arg1 - 30];
252: attrib = (attrib & 0xf0) | color;
253: break;
254: case 40: case 41: case 42: case 43:
255: case 44: case 45: case 46: case 47:
256: color = ansi_colors[esc_arg1 - 40];
257: attrib = (attrib & 0x0f) | (color << 4);
258: break;
259: }
260: break;
261:
262: }
263: if (move)
264: move_cursor();
265: goto reset;
266: case 6:
267: switch (c) {
268: case 'H':
269: case 'f':
270: pos_y = esc_arg1;
271: pos_x = esc_arg2;
272: if (pos_y >= SCR_ROWS)
273: pos_y = SCR_ROWS - 1;
274: if (pos_x >= SCR_COLS)
275: pos_x = SCR_COLS - 1;
276: move_cursor();
277: break;
278: case 'R':
279: /* XXX */
280: break;
281: }
282: goto reset;
283: default:
284: goto reset;
285: }
286: return 1;
287: reset:
288: esc_index = 0;
289: esc_argc = 0;
290: return 1;
291: }
292:
293: static void
294: put_char(char c)
295: {
296:
297: if (check_escape(c))
298: return;
299:
300: switch (c) {
301: case '\n':
302: new_line();
303: return;
304: case '\r':
305: pos_x = 0;
306: return;
307: case '\b':
308: if (pos_x == 0)
309: return;
310: pos_x--;
311: return;
312: }
313:
314: vram[pos_y * VSCR_COLS + pos_x] = c;
315: pos_x++;
316: if (pos_x >= SCR_COLS) {
317: pos_x = 0;
318: pos_y++;
319: if (pos_y >= SCR_ROWS) {
320: pos_y = SCR_ROWS - 1;
321: scroll_up();
322: }
323: }
324: }
325:
326: static void
327: console_output(struct tty *tp)
328: {
329: int c;
330:
331: sched_lock();
332: while ((c = ttyq_getc(&tp->t_outq)) >= 0)
333: put_char(c);
334: move_cursor();
335: esc_index = 0;
336: sched_unlock();
337: }
338:
339: #if defined(DEBUG) && defined(CONFIG_DIAG_VBA)
340: /*
341: * Debug print handler
342: */
343: static void
344: diag_print(char *str)
345: {
346: size_t count;
347: char c;
348:
349: sched_lock();
350: for (count = 0; count < 128; count++) {
351: c = *str;
352: if (c == '\0')
353: break;
354: put_char(c);
355: str++;
356: }
357: move_cursor();
358: esc_index = 0;
359: sched_unlock();
360: }
361: #endif
362:
363: /*
364: * Read
365: */
366: static int
367: console_read(device_t dev, char *buf, size_t *nbyte, int blkno)
368: {
369:
370: return tty_read(&console_tty, buf, nbyte);
371: }
372:
373: /*
374: * Write
375: */
376: static int
377: console_write(device_t dev, char *buf, size_t *nbyte, int blkno)
378: {
379:
380: return tty_write(&console_tty, buf, nbyte);
381: }
382:
383: /*
384: * I/O control
385: */
386: static int
387: console_ioctl(device_t dev, int cmd, u_long arg)
388: {
389:
390: return tty_ioctl(&console_tty, cmd, (void *)arg);
391: }
392:
393: /*
394: * Attach input device.
395: */
396: void
397: console_attach(struct tty **tpp)
398: {
399:
400: *tpp = &console_tty;
401: }
402:
403: /*
404: * Init font
405: */
406: static void
407: init_font(void)
408: {
409: int i, row, col, bit, val = 0;
410: uint16_t *tile = CONSOLE_TILE;
411:
412: for (i = 0; i < 128; i++) {
413: for (row = 0; row < 8; row++) {
414: for (col = 7; col >= 0; col--) {
415: bit = (font_bitmap[i][row] & (1 << col)) ? 2 : 1;
416: if (col % 2)
417: val = bit;
418: else
419: tile[(i * 32) + (row * 4) + ((7 - col) / 2)] =
420: val + (bit << 8);
421: }
422: }
423: }
424: }
425:
426: /*
427: * Init screen
428: */
429: static void
430: init_screen(void)
431: {
432: uint16_t *pal = BG_PALETTE;
433:
434: /* Initialize palette */
435: pal[0] = 0; /* Transparent */
436: pal[1] = RGB(0,0,0); /* Black */
437: pal[2] = RGB(31,31,31); /* White */
438:
439: /* Setup video */
440: REG_BG3CNT = 0x1080; /* Size0, 256color, priority0 */
441: REG_DISPCNT = 0x0800; /* Mode0, BG3 */
442: }
443:
444: /*
445: * Init
446: */
447: static int
448: console_init(void)
449: {
450:
451: esc_index = 0;
452: pos_x = 0;
453: pos_y = 19;
454: console_dev = device_create(&console_io, "console", DF_CHR);
455: init_font();
456: init_screen();
457: #if defined(DEBUG) && defined(CONFIG_DIAG_VBA)
458: debug_attach(diag_print);
459: #endif
460: tty_register(&console_io, &console_tty, console_output);
461: console_tty.t_winsize.ws_row = SCR_ROWS;
462: console_tty.t_winsize.ws_col = SCR_COLS;
463: return 0;
464: }
CVSweb