00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00025 
00026 
00027 
00028 #include "src/common/shared.hpp"
00029 #include "src/common/error.hpp"
00030 #include "src/common/io.hpp"
00031 #include "src/memory/align.hpp"
00032 #include "src/memory/memset.hpp"
00033 #include "src/memory/alloc4k.hpp"
00034 #include "src/memory/pager.hpp"
00035 #include "src/memory/heap.hpp"
00036 #include "src/common/string.hpp"
00037 #include "src/thread/scheduler.hpp"
00038 #include "src/tty/teletype.hpp"
00039 
00040 bool volatile TTYDisableLock=false;     
00041 
00042 teletype videoHW ((ChCol*) VIDEO_MEMORY + CONSOLE_XSIZE, CONSOLE_XSIZE, CONSOLE_YSIZE, CONSOLE_YSIZE, NULL, NULL, CONSOLE_COLOR);       
00043 teletype *active_console = &tty1;       
00044 
00045 teletype tty_panel ((ChCol*) VIDEO_MEMORY, CONSOLE_XSIZE, 1, 1, NULL, NULL, TTY_PANEL_COLOR);
00046 
00047 teletype tty1 (tty1_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00048 teletype tty2 (tty2_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00049 teletype tty3 (tty3_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00050 teletype tty4 (tty4_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00051 teletype tty5 (tty5_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00052 teletype tty6 (tty6_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00053 teletype tty7 (tty7_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00054 teletype tty8 (tty8_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00055 teletype tty9 (tty9_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00056 teletype tty0 (tty0_buf, CONSOLE_XSIZE, CONSOLE_YSIZE, VIRTCONS_LINES, &videoHW, &tui_kbd_handler, CONSOLE_COLOR);
00057 
00058 ChCol tty1_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00059 ChCol tty2_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00060 ChCol tty3_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00061 ChCol tty4_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00062 ChCol tty5_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00063 ChCol tty6_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00064 ChCol tty7_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00065 ChCol tty8_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00066 ChCol tty9_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00067 ChCol tty0_buf [VIRTCONS_LINES * CONSOLE_XSIZE] __attribute__ ((section (".bss.dontcare")));
00068 
00069 
00070 namespace Teletype {
00071 
00072 ChCol *vidmem;
00073 
00074 
00075 void init()
00076  {
00077 
00078 uint32 **pgd, *pgt;
00079         vidmem= (ChCol*) Memory::Physical::ballocate(4096, PAGE_ALIGN);
00080 
00081 
00082         asm volatile("mov %%cr3, %%eax" : "=a" (pgd));
00083         
00084         pgt= (uint32*)((uint32)pgd[(uint32)vidmem/PGT_WIDE]&0xfffff000);
00085         pgt[((uint32)vidmem&0x003fffff)/PAGE_SIZE]= video_memory|PTE_PRESENT|PTE_WRITEABLE;
00086         
00087 
00088 
00089         
00090         asm volatile("movl %cr3, %eax\nmovl %eax, %cr3");
00091 
00092         videoHW.video=vidmem+CONSOLE_XSIZE;
00093         tty_panel.video=vidmem;
00094  }
00095 
00096  };     
00097 
00098 
00099 teletype::teletype(ChCol *buffer, int _xsize, int _ysize, int _lines, teletype *vHW, int (*kbd_h)(), uint8 col)
00100  {
00101 
00102         sem_init(&sem_tty,1,"tty");
00103 
00104         video=(ChCol*) buffer;
00105 
00106         xsize=_xsize; ysize=_ysize; lines= _lines; yfocus=yoffset=0;
00107         color = col;
00108         start=0;lgth=0;
00109 
00110         HW = vHW;
00111         kbd_handler=kbd_h;
00112 
00113 
00114         clrscr();
00115  }
00116 
00117 
00118 void teletype::clrscr()
00119  {
00120 
00121         memset((void*) video, color * 0x01000100, sizeof (ChCol) * xsize * lines);
00122 
00123         yfocus=yoffset = 0;
00124         start=0;lgth=0;
00125         x=y=0;
00126         gotoxy(0, 0);
00127 
00128         if (HW)
00129         if (this == active_console)
00130                 HW->clrscr();
00131  }
00132 
00133 
00134 int teletype::line (int n)
00135  {
00136 int val = n + start;
00137 
00138         if (val < 0)
00139                 return -1;
00140         if (n >= lines)
00141                 return -1;
00142 
00143         if (val >= lines)
00144                 return val - lines;
00145 
00146         return val;
00147  }
00148 
00149 
00150 ChCol *teletype::lineptr (int n)
00151  {
00152 int l = line(n);
00153 ChCol *r;
00154 
00155         if (l == -1)
00156                 r= NULL; else
00157 
00158         r= video + l * xsize;
00159 
00160         if ((uint32)r<0x1000)
00161          { asm volatile("cli"); TTYDisableLock=true; say(const_cast<char*>("%x"),r);asm volatile ("cli\nhlt");}
00162         return r;
00163  }
00164 
00165 
00166 void teletype::movecurs(int n)
00167  {
00168 int k;
00169 int nl;
00170         x+=n;
00171         if (x >= xsize)
00172          {
00173                 k = x / xsize;
00174                 x = x % xsize;
00175                 y+=k;
00176         
00177                 nl=y+yfocus+k;
00178                 if (nl > lgth)
00179                         lgth=nl;
00180          }
00181         if (y >= ysize)
00182          {
00183                 yfocus += ysize - y + 1;
00184                 yoffset=yfocus;
00185                 y= ysize-1;
00186         
00187                 if (lgth>lines)
00188                         del_top(lgth-lines);
00189         
00190                 if (HW)
00191                 if (this == active_console)
00192                         HW->repaint(this);
00193          }
00194  }
00195 
00196 
00197 
00198 void teletype::llock() {
00199         _PF;
00200         if (TTYDisableLock)     
00201                 Preturn();
00202 
00203 
00204 int cnt=0xffff;
00205         while (cnt--)
00206                 if (sem_trywait(&sem_tty)==ESUCCESS)
00207                         Preturn();
00208         Preturn();
00209  }
00210 
00211 
00212 void teletype::lulock() {
00213 
00214         sem_post(&sem_tty);
00215  }
00216 
00217 
00218 void teletype::repaint(teletype *tty)
00219  { _Pf("tty'::repaint");
00220 int i;
00221 
00222         videoHW_toggle_cursor(tty->yfocus == tty->yoffset);
00223 
00224         for (i=0;i<ysize;i++)
00225                 memmove (lineptr(yoffset + i),
00226                         tty->lineptr(tty->yoffset+i),
00227                         160);
00228 
00229         preturn();
00230  }
00231 
00232 
00233 void teletype::del_top(int n)
00234  {
00235 
00236         memset((void*) lineptr(0), color * 0x01000100, n * sizeof(ChCol) * xsize);
00237 
00238         yoffset-=n; yfocus-=n;
00239         start+=n;if (start>=lines) start-=lines;
00240         lgth-=n;
00241  }
00242 
00243 
00244 void teletype::gotoxy(int px, int py)
00245  {
00246  
00247 
00248 
00249         x=px; y=py;
00250         if (this == active_console) 
00251                 videoHW_gotoxy(y * xsize + x + GOTOXY_ADDEND);
00252  return; 
00253 
00254 
00255         if (yoffset != yfocus) {
00256                 yoffset=yfocus;
00257                 if (HW)
00258                 if (this == active_console) HW->repaint(this); }
00259 
00260 
00261         return ;
00262 
00263         if ((px < 0) || (px >= xsize))  
00264                 return ;
00265         if (py + yfocus < 0)    
00266                 return ;
00267         if (py + yfocus > lines)        
00268                 sysfail("oy! teletype::gotoxy, error #1");
00269  }
00270 
00271 
00272 void teletype::showtop(int py)
00273  {
00274 
00275         if (py < 0)
00276                 py = 0;
00277         if (py + ysize > lines)
00278                 py = lines - ysize;
00279 
00280         yoffset = py;
00281         if (HW)
00282         if (this == active_console)
00283                 HW->repaint(this);
00284  }
00285 
00286 
00287 void teletype::put(char ch)
00288  {
00289         put(ch,color);
00290  }
00291 
00292 
00293 void teletype::put(char ch, uint8 col)
00294  { _Pf("Tty'::put");
00295 
00296 
00297         if (yoffset != yfocus) {
00298                 yoffset=yfocus;
00299                 if (HW) if (this == active_console) HW->repaint(this); }
00300 
00301         switch (ch)
00302          {
00303         case '\n':
00304                 movecurs(xsize-x);
00305                 break;
00306         case '\t':
00307                 tab(8);
00308 
00309 
00310 
00311 
00312 
00313 
00314 
00315                 break;
00316         case 13:
00317                 x=0;
00318                 break;
00319         case '\a':
00320                 break;
00321         case '\b':
00322                 poke (' ', x-1,y, color);
00323                 movecurs(-1);
00324                 break;
00325         default:
00326                 poke (ch, x,y, col);
00327                 movecurs(1);
00328                 break;
00329          }
00330 
00331 
00332         preturn();
00333  }
00334 
00335 
00336 void teletype::putch(char ch)
00337  {
00338         putch(ch,color);
00339  }
00340 
00341 
00342 void teletype::putch(char ch, uint8 col)
00343  {
00344         put(ch,col);
00345         gotoxy(x,y);
00346  }
00347 
00348 
00349 void teletype::poke_str(char *ch, int px, int py, uint8 col, uint32 limit)
00350  {
00351 uint32 oldx=x,oldy=y;
00352 uint32 cnt=0;
00353         gotoxy(px,py);
00354         while ( (*ch) && (cnt < limit) ) put(*(ch++),col);
00355         gotoxy(oldx,oldy);
00356  }
00357 
00358 
00359 void teletype::poke (char ch, int px, int py, uint8 col)
00360  {
00361 ChCol *l = lineptr(py + yfocus);
00362 
00363         if (l == NULL)
00364                 return ;
00365         if (px < 0)
00366                 return ;
00367         if (px >= xsize)
00368                 return ;
00369 
00370 
00371         l[px].ch=ch;
00372         l[px].col=col;
00373 
00374         if (HW)
00375         if (this == active_console)
00376                 HW->poke(ch,px,py,col);
00377  }
00378 
00379 int teletype::getx() {
00380         return x;
00381  }
00382 
00383 int teletype::gety() {
00384         return y;
00385  }
00386 
00387 int teletype::getxsize() {
00388         return xsize;
00389  }
00390 
00391 int teletype::getysize() {
00392         return ysize;
00393  }
00394 
00395 
00396 void teletype::setcol(uint8 col) {
00397         color = col;
00398  }
00399 
00400 
00401 void teletype::scroll(int i)
00402  {
00403 
00404 int newyoffset = yoffset + i * ysize / 2;
00405 
00406         if (newyoffset + ysize > lgth)
00407                 newyoffset = lgth - ysize;
00408 
00409         showtop(newyoffset);
00410  }
00411 
00412 
00413 void teletype::tab(int i)
00414  {
00415 int new_x= align_up(x+1, i);
00416         while (x < new_x)
00417          {
00418                 poke(' ', x,y, color);
00419                 x++;
00420          }
00421  }
00422 
00423 
00424 
00425 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 void coutnum(uint32 n, uint32 radix, uint32 n_pos, char first_letter)
00436  {
00437         coutnum(active_console,n,radix,n_pos,first_letter);
00438  }
00439 
00440 
00441 void coutnum(teletype *tty, uint32 n, uint32 radix, uint32 n_pos, char first_letter) {
00442         coutnum(tty,n,radix,n_pos,first_letter,'0');
00443  }
00444 
00445 
00446 void coutnum(teletype *tty, uint32 n, uint32 radix, uint32 n_pos, char first_letter, char EmptyLetter)
00447  {
00448 uint32 cipher;
00449 bool FirstCipherPut=false;
00450         tty->llock();
00451         while (n_pos)
00452          {
00453                 cipher = n / n_pos;
00454                 if (cipher <= 9) { if ((cipher==0)&&(n_pos/radix)&&(FirstCipherPut==false)) tty->put(EmptyLetter); else
00455                         { tty->put(cipher + (char) '0'); FirstCipherPut=true; } }
00456                         else tty->put(cipher + first_letter - 0xA);
00457 
00458                 n -= cipher * n_pos;
00459                 n_pos = n_pos / radix;
00460          }
00461         tty->gotoxy(tty->getx(),tty->gety());
00462         tty->lulock();
00463  }
00464 
00465 
00466 void coutnum(teletype *tty, uint32 n, uint32 radix, uint32 n_pos, char first_letter, uint8 col)
00467  {
00468         tty->llock();
00469 uint32 cipher;
00470         while (n_pos)
00471          {
00472                 cipher = n / n_pos;
00473                 if (cipher <= 9) tty->put(cipher + (char) '0',col);
00474                         else tty->put(cipher + first_letter - 0xA,col);
00475 
00476                 n -= cipher * n_pos;
00477                 n_pos = n_pos / radix;
00478          }
00479         tty->gotoxy(tty->getx(),tty->gety());
00480         tty->lulock();
00481  }
00482 
00483 
00484 void coutDec(uint32 i) {
00485    if (i == 0) {
00486       putch('0');
00487       return ;
00488    }
00489    for (uint32 rank=1000000000; rank; rank /= 10) {
00490       if (rank > i)
00491          continue;
00492       putch( '0'+(i / rank)%10 );
00493    }
00494 }
00495 
00496 
00497 void cout (const char *ch)
00498  {
00499 
00500 
00501         cout(active_console,const_cast<char*>(ch));
00502  }
00503 
00504 
00505 void cout(teletype *tty, char *ch)
00506  {
00507         tty->llock();
00508         while ( (*ch) ) tty->put(*(ch++));
00509         tty->gotoxy(tty->getx(),tty->gety());
00510         tty->lulock();
00511  }
00512 
00513 
00514 void cout (char *ch, uint8 color)
00515  {
00516         active_console->llock();
00517         while ( (*ch) ) active_console->put(*(ch++),color);
00518         active_console->gotoxy(active_console->getx(),active_console->gety());
00519         active_console->lulock();
00520  }
00521 
00522 
00523 void cout (uint32 i)
00524  {
00525         coutnum(i, 16, 0x10000000, 'A');
00526  }
00527 
00528 
00529 void cout (uint32 i,uint8 col)
00530  {
00531         coutnum(active_console, i, 16, 0x10000000, 'A', col);
00532  }
00533 
00534 
00535 void cout (teletype *tty, uint32 i)
00536  {
00537         coutnum(tty,i,16,0x10000000,'A');
00538  }
00539 
00540 
00541 void coutb(uint8 ch)
00542  {
00543         coutnum(ch, 0x10, 0x10, 'A');
00544  }
00545 
00546 
00547 void putch(char ch)
00548  {
00549         active_console->llock();
00550         active_console->putch(ch);
00551         active_console->lulock();
00552  }
00553 
00554 
00555 void writehere(char *ch, uint8 color, uint32 limit)
00556  {
00557         active_console->llock();
00558         active_console->poke_str(ch,color,active_console->getx(), active_console->gety(), limit);
00559         active_console->lulock();
00560  }
00561 
00562 
00563 void poke_char(char ch, uint8 color, int x, int y)
00564  {
00565         active_console->llock();
00566         active_console->poke(ch, x,y, color);
00567         active_console->lulock();
00568  }
00569 
00570 
00571 void poke_str(char *ch, uint8 color, int x, int y, uint32 limit)
00572  {
00573         active_console->llock();
00574         active_console->poke_str(ch, color, x,y, limit);
00575         active_console->lulock();
00576  }
00577 
00578 
00579 void kprintf(const char *text, ...) 
00580  {
00581 
00582 string formatted_text;
00583 
00584         formatted_text.inval();
00585         formatted_text.formatText(const_cast<char*>(text), (char*)((uint32)&text + 1));
00586 
00587         cout(formatted_text.v());
00588 
00589 
00590         formatted_text.done();
00591  }
00592 
00593 
00594 void ksnprintf(char *str, size_t size, char *format, ...)
00595   {
00596 string foo;
00597 uint32 len;
00598           foo.inval(); foo.formatText(format, (char*)((uint32)&format + 1));
00599           len= foo.length();
00600           len= (len<size?len:size-1);
00601           memmove(str, foo.v( ), len );
00602           str[len]='\0';
00603   }
00604 
00605 
00606 void kprintf_alert(char *text, ...)
00607  {
00608 
00609 string formatted_text;
00610 
00611         formatted_text.inval();
00612         formatted_text.formatText(text, (char*)((uint32)&text + 1));
00613 
00614         alert(formatted_text.v());
00615 
00616 
00617         formatted_text.done();
00618  }
00619 
00620 
00621 void kprintf(teletype *tty, char *text, ...)
00622  {
00623 
00624 string formatted_text;
00625 
00626         formatted_text.inval();
00627         formatted_text.formatText(text, (char*)((uint32)&text + 1));
00628 
00629         cout(tty, formatted_text.v());
00630 
00631 
00632         formatted_text.done();
00633  }
00634 
00635 
00636 
00637 void videoHW_gotoxy(int n)
00638  {
00639 union
00640  {
00641         uint32 u;
00642         uint8 c[2]; 
00643  } un;
00644         un.u = n;
00645 
00646 uint32 fl;
00647         asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00648    IOPorts::outb (0x3d4, 0xf);
00649    IOPorts::outb (0x3d5, un.c[0]);
00650         IOPorts::outb (0x3d4, 0xe);
00651    IOPorts::outb (0x3d5, un.c[1]);
00652         asm volatile("pushl %0\npopf"::"g"(fl));
00653  }
00654 
00655 
00656 void videoHW_toggle_cursor(bool on)
00657  {
00658 uint8 val;
00659 uint32 fl;
00660         asm volatile("pushf\npopl %0\ncli":"=g"(fl));
00661 
00662         IOPorts::outb(0x3d4, 0xa);
00663         val = IOPorts::inb(0x3d5);
00664 
00665         val &= 0xff - 0x20;
00666         val |= (!on) << 5;
00667 
00668         IOPorts::outb (0x3d4, 0xa);
00669         IOPorts::outb (0x3d5, val);
00670         asm volatile("pushl %0\npopf"::"g"(fl));
00671  }
00672 
00673 
00674 int tui_kbd_handler()
00675  {
00676         return 1;
00677 
00678 
00679 
00680 
00681 
00682 
00683 
00684 
00685 
00686 
00687 
00688 
00689 
00690 
00691 
00692 
00693 
00694 
00695 
00696 
00697 
00698 
00699 
00700 
00701 
00702 
00703 
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 
00712 
00713 
00714 
00715  }
00716 
00717 
00718 void tty_switch(teletype *tty, char *name)
00719  {
00720 
00721         active_console = tty;
00722 
00723         tty->HW->repaint(tty);
00724 
00725         tty->gotoxy(tty->getx(), tty->gety());
00726 
00727         tty_panel.poke_str(name, TTY_NO_X,0, TTY_PANEL_COLOR, 5);
00728  }
00729 
00730 
00731 
00732 
00733 
00734 
00735