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