[BACK]Return to console.c CVS log [TXT][DIR] Up to [local] / prex / dev / arm / gba

Annotation of prex/dev/arm/gba/console.c, Revision 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, u_long, void *);
        !            43: void console_attach(struct tty **);
        !            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:
        !           340: #if defined(DEBUG) && defined(CONFIG_DIAG_SCREEN)
        !           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
        !           388: console_ioctl(device_t dev, u_long cmd, void *arg)
        !           389: {
        !           390:
        !           391:        return tty_ioctl(&console_tty, cmd, arg);
        !           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();
        !           458: #if defined(DEBUG) && defined(CONFIG_DIAG_SCREEN)
        !           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