/* Copyright (C) 2005 David Decotigny This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include /** * @file banner.c * * Basic tests demonstrating how to create multithreaded processes */ static char *str1 = " _ _ _ _ ___ _ _ _ _ _ " " | | | | ___ | | | | ___ |_ _| __ _ _ __ ___ | |_ | |__ _ __ ___ __ _ __| | / | | |" " | |_| | / _ \\ | | | | / _ \\ | | / _` | | '_ ` _ \\ | __| | '_ \\ | '__| / _ \\ / _` | / _` | | | | |" " | _ | | __/ | | | | | (_) | _ | | | (_| | | | | | | | | |_ | | | | | | | __/ | (_| | | (_| | | | |_|" " |_| |_| \\___| |_| |_| \\___/ ( ) |___| \\__,_| |_| |_| |_| \\__| |_| |_| |_| \\___| \\__,_| \\__,_| |_| (_)" " |/ "; static char *str2 = " _ _ _ _ ___ _ _ _ ____ _ " " | | | | ___ | | | | ___ |_ _| __ _ _ __ ___ | |_ | |__ _ __ ___ __ _ __| | |___ \\ | |" " | |_| | / _ \\ | | | | / _ \\ | | / _` | | '_ ` _ \\ | __| | '_ \\ | '__| / _ \\ / _` | / _` | __) | | |" " | _ | | __/ | | | | | (_) | _ | | | (_| | | | | | | | | |_ | | | | | | | __/ | (_| | | (_| | / __/ |_|" " |_| |_| \\___| |_| |_| \\___/ ( ) |___| \\__,_| |_| |_| |_| \\__| |_| |_| |_| \\___| \\__,_| \\__,_| |_____| (_)" " |/ "; /** * Structure of a character in the x86 video memory mapping (text mode) */ static struct x86_videomem_char { unsigned char character; unsigned char attribute; } * video; static void print(int line, int col, char c, unsigned char attr) { video[line*80 + col].character = c; video[line*80 + col].attribute = attr; } /** * Helper function that scrolls the given string on the screen */ static void print_banner(int top_line, const char * str, int nlines, unsigned char attr, unsigned pause_ms, int direction) { int nbcols = strnlen(str, 16384) / nlines; int base_char = 0; while (1) { int col; for (col = 0 ; col < 80 ; col ++) { int col_in_str = (col + base_char) % (nbcols + 20); int line; for (line = 0 ; line < nlines ; line ++) if (col_in_str < nbcols) print(top_line + line, col, str[line*nbcols + col_in_str], attr); else print(top_line + line, col, ' ', attr); } _sos_nanosleep(0, pause_ms * 1000000); if (direction > 0) base_char ++; else base_char --; if (base_char < 0) base_char = nbcols + 20 - 1; } } struct thread_param { int top_line; const char * str; int nlines; unsigned char attr; unsigned int pause_ms; int direction; }; static void banner_thread(const struct thread_param *p) { print_banner(p->top_line, p->str, p->nlines, p->attr, p->pause_ms, p->direction); } static struct thread_param p1, p2; int main(void) { int fd; /* Map the x86 text-mode framebuffer in user space */ fd = open("/dev/mem", O_RDWR); video = mmap(0, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xb8000); close(fd); p1.top_line = 3; p1.str = str1; p1.nlines = 6; p1.attr = 14 | (7 << 4); p1.pause_ms = 10; p1.direction = 1; _sos_new_thread((sos_thread_func_t*)banner_thread, (void*) & p1, 8192); p2.top_line = 10; p2.str = str2; p2.nlines = 6; p2.attr = (4 << 4) | (7 << 4); p2.pause_ms = 20; p2.direction = -1; _sos_new_thread((sos_thread_func_t*)banner_thread, (void*) & p2, 8192); return 0; }