sos-code-article10/userland/banner.c

151 lines
4.6 KiB
C

/* 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 <crt.h>
#include <libc.h>
#include <string.h>
#include <stdarg.h>
#include <debug.h>
/**
* @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;
}