1f33c8020SAxel Dörfler /* 2*173d0b2fSAxel Dörfler * Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3f33c8020SAxel Dörfler * Distributed under the terms of the MIT License. 4f33c8020SAxel Dörfler */ 5f33c8020SAxel Dörfler 6f33c8020SAxel Dörfler 7f33c8020SAxel Dörfler #include "blue_screen.h" 8f33c8020SAxel Dörfler 967f20716SAxel Dörfler #include <KernelExport.h> 10f33c8020SAxel Dörfler #include <frame_buffer_console.h> 11f33c8020SAxel Dörfler #include <console.h> 12f33c8020SAxel Dörfler #include <arch/debug_console.h> 13f33c8020SAxel Dörfler 14f33c8020SAxel Dörfler #include <string.h> 15f33c8020SAxel Dörfler #include <stdio.h> 16f33c8020SAxel Dörfler 17f33c8020SAxel Dörfler 18f33c8020SAxel Dörfler #define USE_SCROLLING 0 19f33c8020SAxel Dörfler #define NO_CLEAR 1 20f33c8020SAxel Dörfler 2167f20716SAxel Dörfler #define MAX_ARGS 8 2267f20716SAxel Dörfler 2367f20716SAxel Dörfler #define FMASK 0x0f 2467f20716SAxel Dörfler #define BMASK 0x70 2567f20716SAxel Dörfler 2667f20716SAxel Dörfler typedef enum { 2767f20716SAxel Dörfler CONSOLE_STATE_NORMAL = 0, 2867f20716SAxel Dörfler CONSOLE_STATE_GOT_ESCAPE, 2967f20716SAxel Dörfler CONSOLE_STATE_SEEN_BRACKET, 3067f20716SAxel Dörfler CONSOLE_STATE_NEW_ARG, 3167f20716SAxel Dörfler CONSOLE_STATE_PARSING_ARG, 3267f20716SAxel Dörfler } console_state; 3367f20716SAxel Dörfler 3470c3e1a4SAxel Dörfler typedef enum { 3570c3e1a4SAxel Dörfler LINE_ERASE_WHOLE, 3670c3e1a4SAxel Dörfler LINE_ERASE_LEFT, 3770c3e1a4SAxel Dörfler LINE_ERASE_RIGHT 3870c3e1a4SAxel Dörfler } erase_line_mode; 3970c3e1a4SAxel Dörfler 40f33c8020SAxel Dörfler struct screen_info { 41f33c8020SAxel Dörfler int32 columns; 42f33c8020SAxel Dörfler int32 rows; 43f33c8020SAxel Dörfler int32 x, y; 44f33c8020SAxel Dörfler uint8 attr; 4567f20716SAxel Dörfler bool bright_attr; 4667f20716SAxel Dörfler bool reverse_attr; 4767f20716SAxel Dörfler 4867f20716SAxel Dörfler // state machine 4967f20716SAxel Dörfler console_state state; 5067f20716SAxel Dörfler int32 arg_count; 5167f20716SAxel Dörfler int32 args[MAX_ARGS]; 52f33c8020SAxel Dörfler } sScreen; 53f33c8020SAxel Dörfler 54f33c8020SAxel Dörfler console_module_info *sModule; 55f33c8020SAxel Dörfler 56f33c8020SAxel Dörfler 57f33c8020SAxel Dörfler static inline void 58f33c8020SAxel Dörfler hide_cursor(void) 59f33c8020SAxel Dörfler { 60f33c8020SAxel Dörfler sModule->move_cursor(-1, -1); 61f33c8020SAxel Dörfler } 62f33c8020SAxel Dörfler 63f33c8020SAxel Dörfler 64f33c8020SAxel Dörfler static inline void 65f33c8020SAxel Dörfler update_cursor(int32 x, int32 y) 66f33c8020SAxel Dörfler { 67f33c8020SAxel Dörfler sModule->move_cursor(x, y); 68f33c8020SAxel Dörfler } 69f33c8020SAxel Dörfler 70f33c8020SAxel Dörfler 7167f20716SAxel Dörfler static inline void 7267f20716SAxel Dörfler move_cursor(int32 x, int32 y) 7367f20716SAxel Dörfler { 7467f20716SAxel Dörfler sScreen.x = x; 7567f20716SAxel Dörfler sScreen.y = y; 7667f20716SAxel Dörfler update_cursor(x, y); 7767f20716SAxel Dörfler } 7867f20716SAxel Dörfler 7967f20716SAxel Dörfler 80f33c8020SAxel Dörfler #if USE_SCROLLING 81f33c8020SAxel Dörfler 82f33c8020SAxel Dörfler /** scroll from the cursor line up to the top of the scroll region up one line */ 83f33c8020SAxel Dörfler 84f33c8020SAxel Dörfler static void 85f33c8020SAxel Dörfler scroll_up(void) 86f33c8020SAxel Dörfler { 87f33c8020SAxel Dörfler // move the screen up one 88f33c8020SAxel Dörfler sModule->blit(0, 1, sScreen.columns, sScreen.rows - 1, 0, 0); 89f33c8020SAxel Dörfler 90f33c8020SAxel Dörfler // clear the bottom line 91f33c8020SAxel Dörfler sModule->fill_glyph(0, 0, sScreen.columns, 1, ' ', sScreen.attr); 92f33c8020SAxel Dörfler } 93f33c8020SAxel Dörfler #endif 94f33c8020SAxel Dörfler 95f33c8020SAxel Dörfler 96f33c8020SAxel Dörfler static void 97f33c8020SAxel Dörfler next_line(void) 98f33c8020SAxel Dörfler { 99f33c8020SAxel Dörfler if (sScreen.y == sScreen.rows - 1) { 100f33c8020SAxel Dörfler #if USE_SCROLLING 101f33c8020SAxel Dörfler scroll_up(); 102f33c8020SAxel Dörfler #else 103f33c8020SAxel Dörfler sScreen.y = 0; 104f33c8020SAxel Dörfler #endif 105f33c8020SAxel Dörfler } else if (sScreen.y < sScreen.rows - 1) { 106f33c8020SAxel Dörfler sScreen.y++; 107f33c8020SAxel Dörfler } 108f33c8020SAxel Dörfler 109f33c8020SAxel Dörfler #if NO_CLEAR 1100160c6fbSAxel Dörfler sModule->fill_glyph(0, (sScreen.y + 2) % sScreen.rows, sScreen.columns, 1, ' ', sScreen.attr); 111f33c8020SAxel Dörfler #endif 112f33c8020SAxel Dörfler sScreen.x = 0; 113f33c8020SAxel Dörfler } 114f33c8020SAxel Dörfler 115f33c8020SAxel Dörfler 116f33c8020SAxel Dörfler static void 11770c3e1a4SAxel Dörfler erase_line(erase_line_mode mode) 11870c3e1a4SAxel Dörfler { 11970c3e1a4SAxel Dörfler switch (mode) { 12070c3e1a4SAxel Dörfler case LINE_ERASE_WHOLE: 12170c3e1a4SAxel Dörfler sModule->fill_glyph(0, sScreen.y, sScreen.columns, 1, ' ', sScreen.attr); 12270c3e1a4SAxel Dörfler break; 12370c3e1a4SAxel Dörfler case LINE_ERASE_LEFT: 12470c3e1a4SAxel Dörfler sModule->fill_glyph(0, sScreen.y, sScreen.x + 1, 1, ' ', sScreen.attr); 12570c3e1a4SAxel Dörfler break; 12670c3e1a4SAxel Dörfler case LINE_ERASE_RIGHT: 12770c3e1a4SAxel Dörfler sModule->fill_glyph(sScreen.x, sScreen.y, sScreen.columns - sScreen.x, 12870c3e1a4SAxel Dörfler 1, ' ', sScreen.attr); 12970c3e1a4SAxel Dörfler break; 13070c3e1a4SAxel Dörfler // default: 13170c3e1a4SAxel Dörfler } 13270c3e1a4SAxel Dörfler } 13370c3e1a4SAxel Dörfler 13470c3e1a4SAxel Dörfler 13570c3e1a4SAxel Dörfler static void 136f33c8020SAxel Dörfler back_space(void) 137f33c8020SAxel Dörfler { 138f33c8020SAxel Dörfler if (sScreen.x <= 0) 139f33c8020SAxel Dörfler return; 140f33c8020SAxel Dörfler 141f33c8020SAxel Dörfler sScreen.x--; 142f33c8020SAxel Dörfler sModule->put_glyph(sScreen.x, sScreen.y, ' ', sScreen.attr); 143f33c8020SAxel Dörfler } 144f33c8020SAxel Dörfler 145f33c8020SAxel Dörfler 146f33c8020SAxel Dörfler static void 147f33c8020SAxel Dörfler put_character(char c) 148f33c8020SAxel Dörfler { 149f33c8020SAxel Dörfler if (++sScreen.x >= sScreen.columns) { 150f33c8020SAxel Dörfler next_line(); 151f33c8020SAxel Dörfler sScreen.x++; 152f33c8020SAxel Dörfler } 153f33c8020SAxel Dörfler 154f33c8020SAxel Dörfler sModule->put_glyph(sScreen.x - 1, sScreen.y, c, sScreen.attr); 155f33c8020SAxel Dörfler } 156f33c8020SAxel Dörfler 157f33c8020SAxel Dörfler 158f33c8020SAxel Dörfler static void 15967f20716SAxel Dörfler set_vt100_attributes(int32 *args, int32 argCount) 16067f20716SAxel Dörfler { 16167f20716SAxel Dörfler if (argCount == 0) { 16267f20716SAxel Dörfler // that's the default (attributes off) 16367f20716SAxel Dörfler argCount++; 16467f20716SAxel Dörfler args[0] = 0; 16567f20716SAxel Dörfler } 16667f20716SAxel Dörfler 16767f20716SAxel Dörfler for (int32 i = 0; i < argCount; i++) { 16867f20716SAxel Dörfler switch (args[i]) { 16967f20716SAxel Dörfler case 0: // reset 17067f20716SAxel Dörfler sScreen.attr = 0x0f; 17167f20716SAxel Dörfler sScreen.bright_attr = true; 17267f20716SAxel Dörfler sScreen.reverse_attr = false; 17367f20716SAxel Dörfler break; 17467f20716SAxel Dörfler case 1: // bright 17567f20716SAxel Dörfler sScreen.bright_attr = true; 17667f20716SAxel Dörfler sScreen.attr |= 0x08; // set the bright bit 17767f20716SAxel Dörfler break; 17867f20716SAxel Dörfler case 2: // dim 17967f20716SAxel Dörfler sScreen.bright_attr = false; 18067f20716SAxel Dörfler sScreen.attr &= ~0x08; // unset the bright bit 18167f20716SAxel Dörfler break; 18267f20716SAxel Dörfler case 4: // underscore we can't do 18367f20716SAxel Dörfler break; 18467f20716SAxel Dörfler case 5: // blink 18567f20716SAxel Dörfler sScreen.attr |= 0x80; // set the blink bit 18667f20716SAxel Dörfler break; 18767f20716SAxel Dörfler case 7: // reverse 18867f20716SAxel Dörfler sScreen.reverse_attr = true; 18967f20716SAxel Dörfler sScreen.attr = ((sScreen.attr & BMASK) >> 4) | ((sScreen.attr & FMASK) << 4); 19067f20716SAxel Dörfler if (sScreen.bright_attr) 19167f20716SAxel Dörfler sScreen.attr |= 0x08; 19267f20716SAxel Dörfler break; 19367f20716SAxel Dörfler case 8: // hidden? 19467f20716SAxel Dörfler break; 19567f20716SAxel Dörfler 19667f20716SAxel Dörfler /* foreground colors */ 19767f20716SAxel Dörfler case 30: sScreen.attr = (sScreen.attr & ~FMASK) | 0 | (sScreen.bright_attr ? 0x08 : 0); break; // black 19867f20716SAxel Dörfler case 31: sScreen.attr = (sScreen.attr & ~FMASK) | 4 | (sScreen.bright_attr ? 0x08 : 0); break; // red 19967f20716SAxel Dörfler case 32: sScreen.attr = (sScreen.attr & ~FMASK) | 2 | (sScreen.bright_attr ? 0x08 : 0); break; // green 20067f20716SAxel Dörfler case 33: sScreen.attr = (sScreen.attr & ~FMASK) | 6 | (sScreen.bright_attr ? 0x08 : 0); break; // yellow 20167f20716SAxel Dörfler case 34: sScreen.attr = (sScreen.attr & ~FMASK) | 1 | (sScreen.bright_attr ? 0x08 : 0); break; // blue 20267f20716SAxel Dörfler case 35: sScreen.attr = (sScreen.attr & ~FMASK) | 5 | (sScreen.bright_attr ? 0x08 : 0); break; // magenta 20367f20716SAxel Dörfler case 36: sScreen.attr = (sScreen.attr & ~FMASK) | 3 | (sScreen.bright_attr ? 0x08 : 0); break; // cyan 20467f20716SAxel Dörfler case 37: sScreen.attr = (sScreen.attr & ~FMASK) | 7 | (sScreen.bright_attr ? 0x08 : 0); break; // white 20567f20716SAxel Dörfler 20667f20716SAxel Dörfler /* background colors */ 20767f20716SAxel Dörfler case 40: sScreen.attr = (sScreen.attr & ~BMASK) | (0 << 4); break; // black 20867f20716SAxel Dörfler case 41: sScreen.attr = (sScreen.attr & ~BMASK) | (4 << 4); break; // red 20967f20716SAxel Dörfler case 42: sScreen.attr = (sScreen.attr & ~BMASK) | (2 << 4); break; // green 21067f20716SAxel Dörfler case 43: sScreen.attr = (sScreen.attr & ~BMASK) | (6 << 4); break; // yellow 21167f20716SAxel Dörfler case 44: sScreen.attr = (sScreen.attr & ~BMASK) | (1 << 4); break; // blue 21267f20716SAxel Dörfler case 45: sScreen.attr = (sScreen.attr & ~BMASK) | (5 << 4); break; // magenta 21367f20716SAxel Dörfler case 46: sScreen.attr = (sScreen.attr & ~BMASK) | (3 << 4); break; // cyan 21467f20716SAxel Dörfler case 47: sScreen.attr = (sScreen.attr & ~BMASK) | (7 << 4); break; // white 21567f20716SAxel Dörfler } 21667f20716SAxel Dörfler } 21767f20716SAxel Dörfler } 21867f20716SAxel Dörfler 21967f20716SAxel Dörfler 22067f20716SAxel Dörfler static bool 22167f20716SAxel Dörfler process_vt100_command(const char c, bool seenBracket, int32 *args, int32 argCount) 22267f20716SAxel Dörfler { 22367f20716SAxel Dörfler bool ret = true; 22467f20716SAxel Dörfler 22567f20716SAxel Dörfler // kprintf("process_vt100_command: c '%c', argCount %ld, arg[0] %ld, arg[1] %ld, seenBracket %d\n", 22667f20716SAxel Dörfler // c, argCount, args[0], args[1], seenBracket); 22767f20716SAxel Dörfler 22867f20716SAxel Dörfler if (seenBracket) { 22967f20716SAxel Dörfler switch (c) { 23067f20716SAxel Dörfler case 'H': /* set cursor position */ 23167f20716SAxel Dörfler case 'f': { 23267f20716SAxel Dörfler int32 row = argCount > 0 ? args[0] : 1; 23367f20716SAxel Dörfler int32 col = argCount > 1 ? args[1] : 1; 23467f20716SAxel Dörfler if (row > 0) 23567f20716SAxel Dörfler row--; 23667f20716SAxel Dörfler if (col > 0) 23767f20716SAxel Dörfler col--; 23867f20716SAxel Dörfler move_cursor(col, row); 23967f20716SAxel Dörfler break; 24067f20716SAxel Dörfler } 24167f20716SAxel Dörfler case 'A': { /* move up */ 24267f20716SAxel Dörfler int32 deltay = argCount > 0 ? -args[0] : -1; 24367f20716SAxel Dörfler if (deltay == 0) 24467f20716SAxel Dörfler deltay = -1; 24567f20716SAxel Dörfler move_cursor(sScreen.x, sScreen.y + deltay); 24667f20716SAxel Dörfler break; 24767f20716SAxel Dörfler } 24867f20716SAxel Dörfler case 'e': 24967f20716SAxel Dörfler case 'B': { /* move down */ 25067f20716SAxel Dörfler int32 deltay = argCount > 0 ? args[0] : 1; 25167f20716SAxel Dörfler if (deltay == 0) 25267f20716SAxel Dörfler deltay = 1; 25367f20716SAxel Dörfler move_cursor(sScreen.x, sScreen.y + deltay); 25467f20716SAxel Dörfler break; 25567f20716SAxel Dörfler } 25667f20716SAxel Dörfler case 'D': { /* move left */ 25767f20716SAxel Dörfler int32 deltax = argCount > 0 ? -args[0] : -1; 25867f20716SAxel Dörfler if (deltax == 0) 25967f20716SAxel Dörfler deltax = -1; 26067f20716SAxel Dörfler move_cursor(sScreen.x + deltax, sScreen.y); 26167f20716SAxel Dörfler break; 26267f20716SAxel Dörfler } 26367f20716SAxel Dörfler case 'a': 26467f20716SAxel Dörfler case 'C': { /* move right */ 26567f20716SAxel Dörfler int32 deltax = argCount > 0 ? args[0] : 1; 26667f20716SAxel Dörfler if (deltax == 0) 26767f20716SAxel Dörfler deltax = 1; 26867f20716SAxel Dörfler move_cursor(sScreen.x + deltax, sScreen.y); 26967f20716SAxel Dörfler break; 27067f20716SAxel Dörfler } 27167f20716SAxel Dörfler case '`': 27267f20716SAxel Dörfler case 'G': { /* set X position */ 27367f20716SAxel Dörfler int32 newx = argCount > 0 ? args[0] : 1; 27467f20716SAxel Dörfler if (newx > 0) 27567f20716SAxel Dörfler newx--; 27667f20716SAxel Dörfler move_cursor(newx, sScreen.y); 27767f20716SAxel Dörfler break; 27867f20716SAxel Dörfler } 27967f20716SAxel Dörfler case 'd': { /* set y position */ 28067f20716SAxel Dörfler int32 newy = argCount > 0 ? args[0] : 1; 28167f20716SAxel Dörfler if (newy > 0) 28267f20716SAxel Dörfler newy--; 28367f20716SAxel Dörfler move_cursor(sScreen.x, newy); 28467f20716SAxel Dörfler break; 28567f20716SAxel Dörfler } 28667f20716SAxel Dörfler #if 0 28767f20716SAxel Dörfler case 's': /* save current cursor */ 28867f20716SAxel Dörfler save_cur(console, false); 28967f20716SAxel Dörfler break; 29067f20716SAxel Dörfler case 'u': /* restore cursor */ 29167f20716SAxel Dörfler restore_cur(console, false); 29267f20716SAxel Dörfler break; 29367f20716SAxel Dörfler case 'r': { /* set scroll region */ 29467f20716SAxel Dörfler int32 low = argCount > 0 ? args[0] : 1; 29567f20716SAxel Dörfler int32 high = argCount > 1 ? args[1] : sScreen.lines; 29667f20716SAxel Dörfler if (low <= high) 29767f20716SAxel Dörfler set_scroll_region(console, low - 1, high - 1); 29867f20716SAxel Dörfler break; 29967f20716SAxel Dörfler } 30067f20716SAxel Dörfler case 'L': { /* scroll virtual down at cursor */ 30167f20716SAxel Dörfler int32 lines = argCount > 0 ? args[0] : 1; 30267f20716SAxel Dörfler while (lines > 0) { 30367f20716SAxel Dörfler scrdown(console); 30467f20716SAxel Dörfler lines--; 30567f20716SAxel Dörfler } 30667f20716SAxel Dörfler break; 30767f20716SAxel Dörfler } 30867f20716SAxel Dörfler case 'M': { /* scroll virtual up at cursor */ 30967f20716SAxel Dörfler int32 lines = argCount > 0 ? args[0] : 1; 31067f20716SAxel Dörfler while (lines > 0) { 31167f20716SAxel Dörfler scrup(console); 31267f20716SAxel Dörfler lines--; 31367f20716SAxel Dörfler } 31467f20716SAxel Dörfler break; 31567f20716SAxel Dörfler } 31670c3e1a4SAxel Dörfler #endif 31767f20716SAxel Dörfler case 'K': 31867f20716SAxel Dörfler if (argCount == 0 || args[0] == 0) { 31967f20716SAxel Dörfler // erase to end of line 32070c3e1a4SAxel Dörfler erase_line(LINE_ERASE_RIGHT); 32167f20716SAxel Dörfler } else if (argCount > 0) { 32267f20716SAxel Dörfler if (args[0] == 1) 32370c3e1a4SAxel Dörfler erase_line(LINE_ERASE_LEFT); 32467f20716SAxel Dörfler else if (args[0] == 2) 32570c3e1a4SAxel Dörfler erase_line(LINE_ERASE_WHOLE); 32667f20716SAxel Dörfler } 32767f20716SAxel Dörfler break; 32870c3e1a4SAxel Dörfler #if 0 32967f20716SAxel Dörfler case 'J': 33067f20716SAxel Dörfler if (argCount == 0 || args[0] == 0) { 33167f20716SAxel Dörfler // erase to end of screen 33267f20716SAxel Dörfler erase_screen(console, SCREEN_ERASE_DOWN); 33367f20716SAxel Dörfler } else { 33467f20716SAxel Dörfler if (args[0] == 1) 33567f20716SAxel Dörfler erase_screen(console, SCREEN_ERASE_UP); 33667f20716SAxel Dörfler else if (args[0] == 2) 33767f20716SAxel Dörfler erase_screen(console, SCREEN_ERASE_WHOLE); 33867f20716SAxel Dörfler } 33967f20716SAxel Dörfler break; 34067f20716SAxel Dörfler #endif 34167f20716SAxel Dörfler case 'm': 34267f20716SAxel Dörfler if (argCount >= 0) 34367f20716SAxel Dörfler set_vt100_attributes(args, argCount); 34467f20716SAxel Dörfler break; 34567f20716SAxel Dörfler default: 34667f20716SAxel Dörfler ret = false; 34767f20716SAxel Dörfler } 34867f20716SAxel Dörfler } else { 34967f20716SAxel Dörfler switch (c) { 35067f20716SAxel Dörfler #if 0 35167f20716SAxel Dörfler case 'c': 35267f20716SAxel Dörfler reset_console(console); 35367f20716SAxel Dörfler break; 35467f20716SAxel Dörfler case 'D': 35567f20716SAxel Dörfler rlf(console); 35667f20716SAxel Dörfler break; 35767f20716SAxel Dörfler case 'M': 35867f20716SAxel Dörfler lf(console); 35967f20716SAxel Dörfler break; 36067f20716SAxel Dörfler case '7': 36167f20716SAxel Dörfler save_cur(console, true); 36267f20716SAxel Dörfler break; 36367f20716SAxel Dörfler case '8': 36467f20716SAxel Dörfler restore_cur(console, true); 36567f20716SAxel Dörfler break; 36667f20716SAxel Dörfler #endif 36767f20716SAxel Dörfler default: 36867f20716SAxel Dörfler ret = false; 36967f20716SAxel Dörfler } 37067f20716SAxel Dörfler } 37167f20716SAxel Dörfler 37267f20716SAxel Dörfler return ret; 37367f20716SAxel Dörfler } 37467f20716SAxel Dörfler 37567f20716SAxel Dörfler 37667f20716SAxel Dörfler static void 377f33c8020SAxel Dörfler parse_character(char c) 378f33c8020SAxel Dörfler { 37967f20716SAxel Dörfler switch (sScreen.state) { 38067f20716SAxel Dörfler case CONSOLE_STATE_NORMAL: 381f33c8020SAxel Dörfler // just output the stuff 382f33c8020SAxel Dörfler switch (c) { 383f33c8020SAxel Dörfler case '\n': 384f33c8020SAxel Dörfler next_line(); 385f33c8020SAxel Dörfler break; 386f33c8020SAxel Dörfler case 0x8: 387f33c8020SAxel Dörfler back_space(); 388f33c8020SAxel Dörfler break; 389f33c8020SAxel Dörfler case '\t': 39067f20716SAxel Dörfler // ToDo: real tab... 391f31dc4ddSAxel Dörfler sScreen.x = (sScreen.x + 8) & ~7; 392f31dc4ddSAxel Dörfler if (sScreen.x >= sScreen.columns) 393f31dc4ddSAxel Dörfler next_line(); 394f33c8020SAxel Dörfler break; 395f33c8020SAxel Dörfler 396f33c8020SAxel Dörfler case '\r': 397f33c8020SAxel Dörfler case '\0': 39867f20716SAxel Dörfler case '\a': // beep 399f33c8020SAxel Dörfler break; 400f33c8020SAxel Dörfler 40167f20716SAxel Dörfler case 0x1b: 40267f20716SAxel Dörfler // escape character 40367f20716SAxel Dörfler sScreen.arg_count = -1; 40467f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_GOT_ESCAPE; 40567f20716SAxel Dörfler break; 406f33c8020SAxel Dörfler default: 407f33c8020SAxel Dörfler put_character(c); 408f33c8020SAxel Dörfler } 40967f20716SAxel Dörfler break; 41067f20716SAxel Dörfler case CONSOLE_STATE_GOT_ESCAPE: 41167f20716SAxel Dörfler // look for either commands with no argument, or the '[' character 41267f20716SAxel Dörfler switch (c) { 41367f20716SAxel Dörfler case '[': 41467f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_SEEN_BRACKET; 41567f20716SAxel Dörfler break; 41667f20716SAxel Dörfler default: 41767f20716SAxel Dörfler sScreen.args[sScreen.arg_count] = 0; 41867f20716SAxel Dörfler process_vt100_command(c, false, sScreen.args, sScreen.arg_count + 1); 41967f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NORMAL; 42067f20716SAxel Dörfler } 42167f20716SAxel Dörfler break; 42267f20716SAxel Dörfler case CONSOLE_STATE_SEEN_BRACKET: 42367f20716SAxel Dörfler switch (c) { 42467f20716SAxel Dörfler case '0'...'9': 42567f20716SAxel Dörfler sScreen.arg_count = 0; 42667f20716SAxel Dörfler sScreen.args[sScreen.arg_count] = c - '0'; 42767f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_PARSING_ARG; 42867f20716SAxel Dörfler break; 42967f20716SAxel Dörfler case '?': 43067f20716SAxel Dörfler // private DEC mode parameter follows - we ignore those anyway 43167f20716SAxel Dörfler break; 43267f20716SAxel Dörfler default: 43367f20716SAxel Dörfler process_vt100_command(c, true, sScreen.args, sScreen.arg_count + 1); 43467f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NORMAL; 43567f20716SAxel Dörfler } 43667f20716SAxel Dörfler break; 43767f20716SAxel Dörfler case CONSOLE_STATE_NEW_ARG: 43867f20716SAxel Dörfler switch (c) { 43967f20716SAxel Dörfler case '0'...'9': 44067f20716SAxel Dörfler sScreen.arg_count++; 44167f20716SAxel Dörfler if (sScreen.arg_count == MAX_ARGS) { 44267f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NORMAL; 44367f20716SAxel Dörfler break; 44467f20716SAxel Dörfler } 44567f20716SAxel Dörfler sScreen.args[sScreen.arg_count] = c - '0'; 44667f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_PARSING_ARG; 44767f20716SAxel Dörfler break; 44867f20716SAxel Dörfler default: 44967f20716SAxel Dörfler process_vt100_command(c, true, sScreen.args, sScreen.arg_count + 1); 45067f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NORMAL; 45167f20716SAxel Dörfler } 45267f20716SAxel Dörfler break; 45367f20716SAxel Dörfler case CONSOLE_STATE_PARSING_ARG: 45467f20716SAxel Dörfler // parse args 45567f20716SAxel Dörfler switch (c) { 45667f20716SAxel Dörfler case '0'...'9': 45767f20716SAxel Dörfler sScreen.args[sScreen.arg_count] *= 10; 45867f20716SAxel Dörfler sScreen.args[sScreen.arg_count] += c - '0'; 45967f20716SAxel Dörfler break; 46067f20716SAxel Dörfler case ';': 46167f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NEW_ARG; 46267f20716SAxel Dörfler break; 46367f20716SAxel Dörfler default: 46467f20716SAxel Dörfler process_vt100_command(c, true, sScreen.args, sScreen.arg_count + 1); 46567f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NORMAL; 46667f20716SAxel Dörfler } 46767f20716SAxel Dörfler } 468f33c8020SAxel Dörfler } 469f33c8020SAxel Dörfler 470f33c8020SAxel Dörfler 471f33c8020SAxel Dörfler // #pragma mark - 472f33c8020SAxel Dörfler 473f33c8020SAxel Dörfler 474f33c8020SAxel Dörfler status_t 475f33c8020SAxel Dörfler blue_screen_init(void) 476f33c8020SAxel Dörfler { 477f33c8020SAxel Dörfler extern console_module_info gFrameBufferConsoleModule; 478f33c8020SAxel Dörfler 479f33c8020SAxel Dörfler // we can't use get_module() here, since it's too early in the boot process 480f33c8020SAxel Dörfler 481f33c8020SAxel Dörfler if (!frame_buffer_console_available()) 482f33c8020SAxel Dörfler return B_ERROR; 483f33c8020SAxel Dörfler 484f33c8020SAxel Dörfler sModule = &gFrameBufferConsoleModule; 485f33c8020SAxel Dörfler return B_OK; 486f33c8020SAxel Dörfler } 487f33c8020SAxel Dörfler 488f33c8020SAxel Dörfler 489*173d0b2fSAxel Dörfler status_t 49092447917SAxel Dörfler blue_screen_enter(bool debugOutput) 491f33c8020SAxel Dörfler { 49292447917SAxel Dörfler sScreen.attr = debugOutput ? 0xf0 : 0x0f; 49392447917SAxel Dörfler // black on white for KDL, white on black for debug output 494f33c8020SAxel Dörfler sScreen.x = sScreen.y = 0; 49567f20716SAxel Dörfler sScreen.state = CONSOLE_STATE_NORMAL; 496f33c8020SAxel Dörfler 497*173d0b2fSAxel Dörfler if (sModule == NULL) 498*173d0b2fSAxel Dörfler return B_NO_INIT; 499*173d0b2fSAxel Dörfler 500f33c8020SAxel Dörfler sModule->get_size(&sScreen.columns, &sScreen.rows); 501f33c8020SAxel Dörfler #if !NO_CLEAR 502f33c8020SAxel Dörfler sModule->clear(sScreen.attr); 503f33c8020SAxel Dörfler #else 504f33c8020SAxel Dörfler sModule->fill_glyph(0, sScreen.y, sScreen.columns, 3, ' ', sScreen.attr); 505f33c8020SAxel Dörfler #endif 506*173d0b2fSAxel Dörfler return B_OK; 507f33c8020SAxel Dörfler } 508f33c8020SAxel Dörfler 509f33c8020SAxel Dörfler 510f33c8020SAxel Dörfler char 511f33c8020SAxel Dörfler blue_screen_getchar(void) 512f33c8020SAxel Dörfler { 513f33c8020SAxel Dörfler return arch_debug_blue_screen_getchar(); 514f33c8020SAxel Dörfler } 515f33c8020SAxel Dörfler 516f33c8020SAxel Dörfler 517f33c8020SAxel Dörfler void 518f33c8020SAxel Dörfler blue_screen_putchar(char c) 519f33c8020SAxel Dörfler { 520f33c8020SAxel Dörfler hide_cursor(); 521f33c8020SAxel Dörfler 522f33c8020SAxel Dörfler parse_character(c); 523f33c8020SAxel Dörfler 524f33c8020SAxel Dörfler update_cursor(sScreen.x, sScreen.y); 525f33c8020SAxel Dörfler } 526f33c8020SAxel Dörfler 527f33c8020SAxel Dörfler 528f33c8020SAxel Dörfler void 529f33c8020SAxel Dörfler blue_screen_puts(const char *text) 530f33c8020SAxel Dörfler { 531f33c8020SAxel Dörfler hide_cursor(); 532f33c8020SAxel Dörfler 533f33c8020SAxel Dörfler while (text[0] != '\0') { 534f33c8020SAxel Dörfler parse_character(text[0]); 535f33c8020SAxel Dörfler text++; 536f33c8020SAxel Dörfler } 537f33c8020SAxel Dörfler 538f33c8020SAxel Dörfler update_cursor(sScreen.x, sScreen.y); 539f33c8020SAxel Dörfler } 540