1 /* 2 * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "console.h" 8 9 #include <SupportDefs.h> 10 #include <util/kernel_cpp.h> 11 #include <boot/stage2.h> 12 13 #include <string.h> 14 15 16 class Console : public ConsoleNode { 17 public: 18 Console(); 19 20 virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize); 21 virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize); 22 }; 23 24 static uint16 *sScreenBase = (uint16 *)0xb8000; 25 static uint32 sScreenWidth = 80; 26 static uint32 sScreenHeight = 25; 27 static uint32 sScreenOffset = 0; 28 static uint16 sColor = 0x0f00; 29 30 static Console sInput, sOutput; 31 FILE *stdin, *stdout, *stderr; 32 33 34 static void 35 scroll_up() 36 { 37 memcpy(sScreenBase, sScreenBase + sScreenWidth, 38 sScreenWidth * sScreenHeight * 2 - sScreenWidth * 2); 39 sScreenOffset = (sScreenHeight - 1) * sScreenWidth; 40 41 for (uint32 i = 0; i < sScreenWidth; i++) 42 sScreenBase[sScreenOffset + i] = sColor | ' '; 43 } 44 45 46 // #pragma mark - 47 48 49 Console::Console() 50 : ConsoleNode() 51 { 52 } 53 54 55 ssize_t 56 Console::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize) 57 { 58 // don't seek in character devices 59 // not implemented (and not yet? needed) 60 return B_ERROR; 61 } 62 63 64 ssize_t 65 Console::WriteAt(void *cookie, off_t /*pos*/, const void *buffer, size_t bufferSize) 66 { 67 const char *string = (const char *)buffer; 68 69 if (gKernelArgs.frame_buffer.enabled) 70 return bufferSize; 71 72 for (uint32 i = 0; i < bufferSize; i++) { 73 if (string[0] == '\n') 74 sScreenOffset += sScreenWidth - (sScreenOffset % sScreenWidth); 75 else 76 sScreenBase[sScreenOffset++] = sColor | string[0]; 77 78 if (sScreenOffset >= sScreenWidth * sScreenHeight) 79 scroll_up(); 80 81 string++; 82 } 83 return bufferSize; 84 } 85 86 87 // #pragma mark - 88 89 90 void 91 console_clear_screen(void) 92 { 93 if (gKernelArgs.frame_buffer.enabled) 94 return; 95 96 for (uint32 i = 0; i < sScreenWidth * sScreenHeight; i++) 97 sScreenBase[i] = sColor; 98 99 // reset cursor position as well 100 sScreenOffset = 0; 101 } 102 103 104 int32 105 console_width(void) 106 { 107 return sScreenWidth; 108 } 109 110 111 int32 112 console_height(void) 113 { 114 return sScreenHeight; 115 } 116 117 118 void 119 console_set_cursor(int32 x, int32 y) 120 { 121 if (y >= (int32)sScreenHeight) 122 y = sScreenHeight - 1; 123 else if (y < 0) 124 y = 0; 125 if (x >= (int32)sScreenWidth) 126 x = sScreenWidth - 1; 127 else if (x < 0) 128 x = 0; 129 130 sScreenOffset = x + y * sScreenWidth; 131 } 132 133 134 void 135 console_set_color(int32 foreground, int32 background) 136 { 137 sColor = (background & 0xf) << 12 | (foreground & 0xf) << 8; 138 } 139 140 141 status_t 142 console_init(void) 143 { 144 // ToDo: make screen size changeable via stage2_args 145 146 console_clear_screen(); 147 148 // enable stdio functionality 149 stdin = (FILE *)&sInput; 150 stdout = stderr = (FILE *)&sOutput; 151 152 return B_OK; 153 } 154 155 156