// chybi: ...jake vid_copy? (pry ho ma kernel...) /*===========================================================================* * Terminal Task * *===========================================================================* * Written by : Vit Condak =P * * Last update: 27-05-1997 * *===========================================================================*/ /*===========================================================================* * scrolling and such a thingies * *===========================================================================*/ /* hardware depending part of tty-output */ /* tento soubor obsahuje hardwarove zavisle casti vystupni casti konzole ehm, tedy funkce pro vystup na obrazovku pouziva se standardni textova pamet (b800:0000) a sluzby CGA, ktere slouzi k posunu kurzoru a pocatku viditelne casti videobufferu (tato sluzba se pouziva pro hardwarovy scrolling. az se dojde na konec videobufferu [vyuzivame zhruba 16kB], zkopiruje se obrazovka zase na zacatek videobufferu a jede se znova) aby to bylo 'ciste', mela by se asi na zasahy do videopameti pouzit funkce (k)vid_copy(), kterou by mel dodat kernel Ceka se na to, az knihovnici udelaji funkci _fmemcpy() .... zatim neni k dispozici a proto je volani funkce v podminenem prekaldu ... */ #define LO(value) (unsigned char)((unsigned int)(value)&0x00ff) //dolni byte #define HI(value) (unsigned char)((unsigned int)(value)>>8) //horni byte #define TEXTMEM (unsigned int far *) 0xb8000000L //zacatek videopameti textovych rezimu #define MAXX 80 //pocet znaku na radek #define MAXY 25 //pocet radku na obrazovku #define SPEAKER_PORT 0x61 //port pro speaker =) (co jineho?) #define CGA_OUT(reg, val) \ { \ asm mov al, (reg) ;\ asm mov dx, 0x3d4 ;\ asm out dx, al ;\ asm mov al, (val) ;\ asm mov dx, 0x3d5 ;\ asm out dx, al ;\ } PRIVATE int ScreenPage=0; // Se kterou video strankou prave // pracujeme (0,1,2,...) - zatim // MUSI byt 0. - jinak nefunguje ! // Slouci znak s atributem // Vysledkem je integer = lobyte:znak, hibyte:atribut #define char_att(ch, attrib) \ ((unsigned int)(((unsigned int)(attrib)<<8) | (unsigned char)(ch))) // s~i'l(e)ne' pomocne funkce pro kopirovani na obrazovku // sx a sy jsou souradnice obrazovky (zleva dole od 1,1)) // chat je znak s atributem // ze souradnic kurzoru vypocte ofset do videopameti // (ale polovicni, videoram se pak chape jako pole integeru) int count_offs(int sx, int sy) { return sx-1+(ScreenPage*MAXY+MAXY-sy)*MAXX; } /* sx-1+ScreenPage*MAXX*MAXY+(MAXY-sy)*MAXX; */ // Zapise od pozice sx,sy na obrazovce blok znaku 'chat' dlouhy 'len' void write_block(int sx, int sy, int chat, int len) { int l; unsigned far * ptr = TEXTMEM; ptr += count_offs(sx,sy); for (l=0; l> 12) + MAXX*2, ( (DWord) ptr) >> 12 ,MAXX*(MAXY-1)*2); #endif // Naplni dolni radek obrazovky mezerami write_block(1,1,char_att(' ',attrib),MAXX); } void scroll_down(void) { #ifdef DEBUG _fmemcpy(TEXTMEM+MAXX,TEXTMEM,MAXX*(MAXY-1)*2); #else unsigned int far * ptr = TEXTMEM; k_phys_copy ( ((DWord) ptr) << CLICK_SHIFT,(((DWord) ptr) << CLICK_SHIFT)+MAXX*2,MAXX*(MAXY-1)*2); #endif // Naplni horni radek obrazovky mezerami s atributem 7 // (mozna bude vhodne jine cislo nez 7 - bila na cernem podkladu) write_block(1,24,char_att(' ',7),MAXX); } void scroll_up(void) { new_line(' '); } // Nastavi pozici kurzoru (x,y jsou obrazovkove souradnice) void move_to(int x, int y) { unsigned int off = count_offs(x,y); unsigned char lo = LO(off); unsigned char ho = HI(off); CGA_OUT(14, ho); CGA_OUT(15, lo); } /* Proste piiipne speaker funguje tak, ze se pripoji k nejakemu casovaci a ten ho prubezne zapina a vypina, a tak vznika zvuk pokud chce clovek ziskat konkretni frekvenci, musi si casovac vhodne nastavit, ale protoze moc nechci zasahovat do systemu, proste spoleham na to, ze je nastaveny na nejakou 'slusnou' hodnotu ze stejneho duvodu je delay reseny jednoduchym cyklenim */ void beep(void) { int a,b; //pripoji speaker k casovaci a=inportb(SPEAKER_PORT); a=a|3; outportb(SPEAKER_PORT,a); //delay =) no nic moc... for (a=1; a!=0; a++) { for (b=1; b<50; b++) {b=--b+1;} } //odpoji od casovace a=inportb(SPEAKER_PORT); a=a&0xfc; outportb(SPEAKER_PORT,a); } PRIVATE void flush(struct tty_struct * tp) /* flush() kopiruje na obrazovku obsah bufferu (outqueue) mozna by bylo dobre pripsat cekani na retrace, ale neni pouzito, protoze se terminal nebude pouzivat pro animace, a tak by to melo stacit pozice kurzoru se meni az tady (pri flakani pismenek do videopameti) */ { int i; i = tp->tty_outcaller; // tom prubnu to vyvolat funkci v tp->dev_start, ale jen pro COM port // if (tp->tty_outcaller == 0x07) { // out_char(tp, c); tp->tty_devstart(tp); // flush(tp); // exit(); // } /* tom vykomentuji a prsunu vypis znaku do console.inc while (tp->tty_outcount) //t.j. dokud outtail nedozene outhead { //vypis pismenka i s atributem do videopameti write_char(tp->tty_column,tp->tty_row,*tp->tty_outtail); tp->tty_outtail++; //posune ptr na konec dat v bufferu if (tp->tty_outtail==tp->tty_outqueue+TTY_OUT_BYTES) //pokud je treba zacit zase od zacatku 'outqueue' tp->tty_outtail=tp->tty_outqueue; // tu bylo neco blbe tp->tty_outcount--; //pozice kurzoru tp->tty_column++; if (tp->tty_column>MAXX) //presel na novy radek? { tp->tty_column=1; if (tp->tty_row>1) //je to jeste na obrazovce? ... { tp->tty_row--; //staci posunout kurzor } else //...nebo je uz treba scrollovat? (newline!) { //pozice kurzoru uz je spravne nastavena na x=1, y=1 // asi ne scroll_screen(); ale new_line(tp->tty_attribute); } } } //aktualizovat pozici kurzoru (vykresleni) move_to(tp->tty_column, tp->tty_row); */ }