openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

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