151 lines
4.6 KiB
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;
|
|
}
|