console.c (8961B)
1 /* $Id: //depot/blt/srv/console2/console.c#15 $ 2 ** 3 ** Copyright 1998 Brian J. Swetland 4 ** All rights reserved. 5 ** Copyright 1999 Sidney Cammeresi 6 ** All rights reserved. 7 ** 8 ** Redistribution and use in source and binary forms, with or without 9 ** modification, are permitted provided that the following conditions 10 ** are met: 11 ** 1. Redistributions of source code must retain the above copyright 12 ** notice, this list of conditions, and the following disclaimer. 13 ** 2. Redistributions in binary form must reproduce the above copyright 14 ** notice, this list of conditions, and the following disclaimer in the 15 ** documentation and/or other materials provided with the distribution. 16 ** 3. The name of the author may not be used to endorse or promote products 17 ** derived from this software without specific prior written permission. 18 ** 19 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <blt/syscall.h> 32 #include <blt/error.h> 33 #include <blt/namer.h> 34 #include <blt/conio.h> 35 #include <blt/qsem.h> 36 #include <i386/io.h> 37 #include <string.h> 38 39 #include "vt100.h" 40 41 int console_port = -1; 42 int send_port = -1; 43 int remote_port = -1; 44 45 volatile int ready = 0; 46 47 #define CLEAR "\033[2J" 48 #define FG_BLACK "\033[30m" 49 #define FG_BLUE "\033[31m" 50 #define FG_GREEN "\033[32m" 51 #define FG_CYAN "\033[33m" 52 #define FG_RED "\033[34m" 53 #define FG_PURPLE "\033[35m" 54 #define FG_BROWN "\033[36m" 55 #define FG_WHITE "\033[37m" 56 57 #define BG_BLACK "\033[40m" 58 #define BG_BLUE "\033[41m" 59 #define BG_GREEN "\033[42m" 60 #define BG_CYAN "\033[43m" 61 #define BG_RED "\033[44m" 62 #define BG_PURPLE "\033[45m" 63 #define BG_BROWN "\033[46m" 64 #define BG_WHITE "\033[47m" 65 66 67 #define MONOx 68 69 #ifdef MONO 70 #define SCREEN 0xB0000 71 #else 72 #define SCREEN 0xB8000 73 #endif 74 void *screen = (void *) SCREEN; 75 76 void movecursor (int x, int y) 77 { 78 int offset; 79 80 offset = 80 * y + x; 81 outb (0xe, 0x3d4); 82 outb (offset / 256, 0x3d5); 83 outb (0xf, 0x3d4); 84 outb (offset % 256, 0x3d5); 85 } 86 87 struct virtscreen con[10]; 88 struct virtscreen statbar; 89 struct virtscreen *active; 90 91 void move_cursor(struct virtscreen *cur) 92 { 93 if(cur == active) movecursor(cur->xpos,cur->ypos); 94 } 95 96 void vprintf(struct virtscreen *vscr, char *fmt, ...); 97 void printf(char *fmt, ...); 98 99 void keypress(int key) 100 { 101 char c; 102 103 sem_acquire(active->lock); 104 char_to_virtscreen(active, key); 105 sem_release(active->lock); 106 if(remote_port > 0) { 107 c = key; 108 port_send(send_port, remote_port, &c, 1, 0); 109 } 110 } 111 112 void vputs(struct virtscreen *vscr, char *s) 113 { 114 sem_acquire(vscr->lock); 115 while(*s) { 116 char_to_virtscreen(vscr, *s); 117 if(*s == '\n') char_to_virtscreen(vscr, '\r'); 118 s++; 119 } 120 sem_release(vscr->lock); 121 } 122 123 124 void printf(char *fmt, ...) 125 { 126 static char line[128]; 127 va_list pvar; 128 va_start(pvar,fmt); 129 va_snprintf(line,128,fmt,pvar); 130 line[127]=0; 131 va_end(pvar); 132 vputs(active,line); 133 } 134 135 void vprintf(struct virtscreen *vscr, char *fmt, ...) 136 { 137 static char line[128]; 138 va_list pvar; 139 va_start(pvar,fmt); 140 va_snprintf(line,128,fmt,pvar); 141 line[127]=0; 142 va_end(pvar); 143 vputs(vscr,line); 144 } 145 146 void status(int n) 147 { 148 vprintf(&statbar,FG_WHITE BG_BLUE CLEAR "### OpenBLT Console mkII ### VC %d",n); 149 } 150 151 #define ESC 27 152 #define BS 8 153 #define TAB 9 154 #define CR 13 155 #define LF 10 156 157 char ScanTable [] = {' ', ESC, '1', '2', '3', '4', '5', '6', '7', '8', 158 '9', '0', '-', '=', BS, TAB, 'q', 'w', 'e', 'r', 159 't', 'y', 'u', 'i', 'o', 'p', '[', ']', LF, ' ', 160 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 161 '\'', '`', ' ', '\\', 'z', 'x', 'c', 'v', 'b', 'n', 162 'm', ',', '.', '/', ' ', ' ', ' ', ' ', ' '}; 163 char ShiftTable [] = {' ', ESC, '!', '@', '#', '$', '%', '^', '&', '*', 164 '(', ')', '_', '+', ' ', ' ', 'Q', 'W', 'E', 'R', 165 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', LF, ' ', 166 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', 167 '\"', '~', ' ', '|', 'Z', 'X', 'C', 'V', 'B', 'N', 168 'M', '<', '>', '?', ' ', ' ', ' ', ' ', ' '}; 169 #define LSHIFT 42 170 #define RSHIFT 54 171 #define CONTROL 0x1d 172 #define ALT 0x38 173 174 #define F1 0x3b 175 #define F2 0x3c 176 #define F3 0x3d 177 #define F4 0x3e 178 #define F5 0x3f 179 #define F6 0x40 180 #define F7 0x41 181 #define F8 0x42 182 #define F9 0x43 183 #define F10 0x44 184 185 void movecursor (int x, int y); 186 void keypress(int key); 187 188 void save(struct virtscreen *vscr) 189 { 190 sem_acquire(vscr->lock); 191 if(vscr->data != vscr->back) { 192 memcpy(vscr->back,vscr->data,vscr->num_bytes); 193 vscr->data = vscr->back; 194 } 195 sem_release(vscr->lock); 196 } 197 198 void load(struct virtscreen *vscr) 199 { 200 sem_acquire(vscr->lock); 201 if(vscr->data == vscr->back) { 202 vscr->data = screen; 203 memcpy(vscr->data,vscr->back,vscr->num_bytes); 204 } 205 active = vscr; 206 movecursor(vscr->xpos,vscr->ypos); 207 sem_release(vscr->lock); 208 status(vscr - con); 209 } 210 211 void function(int number) 212 { 213 save(active); 214 active = &con[number]; 215 load(active); 216 } 217 218 void keyboard_irq_thread(void) 219 { 220 int shift = 0; 221 int control = 0; 222 int alt = 0; 223 224 int key; 225 226 os_handle_irq(1); 227 228 for(;;) { 229 os_sleep_irq(); 230 #ifdef MULTI 231 while(inb(0x64) & 0x01) { 232 #endif 233 key = inb(0x60); 234 if(alt && (key == 1)) { 235 save(active); 236 os_debug(); 237 load(active); 238 alt = 0; 239 continue; 240 } 241 242 switch(key){ 243 case F1: 244 case F2: 245 case F3: 246 case F4: 247 case F5: 248 case F6: 249 case F7: 250 case F8: 251 case F9: 252 case F10: 253 function(key - F1); 254 break; 255 256 case ALT: 257 alt = 1; 258 break; 259 case ALT | 0x80: 260 alt = 0; 261 break; 262 case CONTROL: 263 control = 1; 264 break; 265 case CONTROL | 0x80: 266 control = 0; 267 break; 268 case LSHIFT: 269 case RSHIFT: 270 shift = 1; 271 break; 272 case LSHIFT | 0x80: 273 case RSHIFT | 0x80: 274 shift = 0; 275 break; 276 default: 277 if(key & 0x80){ 278 /* break */ 279 } else { 280 if(key < 59){ 281 if(control){ 282 key = ScanTable[key]; 283 if(key >= 'a' && key <= 'z'){ 284 keypress(key - 'a' + 1); 285 } 286 } else { 287 key = shift ? ShiftTable[key] : ScanTable[key]; 288 keypress(key); 289 } 290 } 291 } 292 } 293 #ifdef MULTI 294 } 295 #endif 296 } 297 298 } 299 300 void console_thread(void) 301 { 302 int l, src; 303 uint32 code; 304 char data[257]; 305 306 #ifdef CONSOLE_DEBUG 307 vprintf(active, "console: " FG_GREEN "listener ready" FG_WHITE " (port %d)\n",console_port); 308 #endif 309 310 while((l = port_recv(console_port, &src, data, 256, &code)) >= 0){ 311 if(code == 0) { 312 remote_port = src; 313 } else { 314 data[l] = 0; 315 vputs(active, data); 316 } 317 } 318 vprintf(active, "console: output listener has left the building (%d)\n",l); 319 os_terminate(0); 320 } 321 322 int console_main(void) 323 { 324 int err,i; 325 area_create(0x2000, 0, &screen, AREA_PHYSMAP); 326 327 console_port = port_create(0,"console_listen_port"); 328 send_port = port_create(0,"console_send_port"); 329 port_option(send_port, PORT_OPT_NOWAIT, 1); 330 331 err = namer_register(console_port,"console"); 332 333 init_virtscreen(&statbar, 1, 80); 334 statbar.back = statbar.data; 335 statbar.data = (unsigned short *) (((uint32) screen) + 80*24*2); 336 statbar.lock = sem_create(1,"statbar_lock"); 337 338 for(i=0;i<10;i++){ 339 init_virtscreen(&con[i], 24, 80); 340 con[i].back = con[i].data; 341 con[i].lock = sem_create(1,"vscr_lock"); 342 vputs(&con[i],CLEAR); 343 } 344 load(&con[0]); 345 346 status(0); 347 if(err) vprintf(active,"console: the namer hates us\n"); 348 else 349 #ifdef CONSOLE_DEBUG 350 vprintf(active,"console: " FG_GREEN "online." FG_WHITE "\n"); 351 #else 352 ; 353 #endif 354 355 thr_create(keyboard_irq_thread, NULL, "console:kbd"); 356 ready = 1; 357 console_thread(); 358 359 return 0; 360 } 361 362 int main(void) 363 { 364 thr_create(console_main, NULL, "console:main"); 365 while(!ready) ; 366 return 0; 367 } 368