/****************************************************
 * USEFUL LINKS
 * http://sos.enix.org [FR
 * http://webster.cs.ucr.edu/AoA/DOS/ch23/CH23-1.html [UK/US
 * http://geezer [UK/US]
 ****************************************************

#include <python2.3/Python.h
#include <string.h

#define SCREEN_START 0xB8000	/* Video RAM starting adress *
#define SCREEN_PAGE_SIZE 0xFA0 	/* 4000 bytes or 4 Ko : the size of a page *
#define SCREEN_PAGE_LIMIT (SCREEN_START + SCREEN_PAGE_SIZE) /* = 0xB8FA0 *

#define LINES 2
#define COLUMNS 8

/* Normal and Dark/Light foreground color *
#define FG_BLACK           
#define FG_BLUE            
#define FG_GREEN           
#define FG_CYAN            
#define FG_RED             
#define FG_MAGENTA         
#define FG_BROWN           
#define FG_WHITE           
#define FG_DARK_GRAY       
#define FG_BRIGHT_BLUE     
#define FG_BRIGHT_GREEN    1
#define FG_BRIGHT_CYAN     1
#define FG_PINK            1
#define FG_BRIGHT_MAGENTA  1
#define FG_YELLOW          1
#define FG_BRIGHT_WHITE    1

/* Background color *
#define BG_BLACK     (FG_BLACK	<< 4
#define BG_BLUE      (FG_BLUE 	<< 4
#define BG_GREEN     (FG_GREEN 	<< 4
#define BG_CYAN      (FG_CYAN 	<< 4
#define BG_RED       (FG_RED 	<< 4
#define BG_MAGENTA   (FG_MAGENTA << 4
#define BG_BROWN     (FG_BROWN 	<< 4
#define BG_LTGRAY    (FG_WHITE 	<< 4

/* Blinking *
#define FG_BLINKING  (1 << 7

static int cursor_x
static int cursor_y

/***  __scroll_up()  ***
/***********************

void __scroll_up(unsigned int lines_to_scroll_up

	unsigned char *video, *tmp

	for (video = (unsigned char*)SCREEN_START; video < (unsigned char*)SCREEN_PAGE_LIMIT; video++
	
		tmp = (unsigned char*)(video+lines_to_scroll_up*COLUMNS*2)

		if (tmp < (unsigned char*)SCREEN_PAGE_LIMIT
			*video = *tmp
		els
			*video = 0
	
	cursor_y = cursor_y - lines_to_scroll_up

	if ( cursor_y < 0 
		cursor_y = 0


/***  __scroll_down()  ***
/*************************

void __scroll_down(unsigned int lines_to_scroll_down





/***  __display_character()  ***
/*******************************

void __display_character(char character, char attributes, int cursor_x, int cursor_y

	unsigned char* video, *tmp

	video = (unsigned char*)(SCREEN_START + 2 * (cursor_x-1) + COLUMNS * 2 * (cursor_y - 1) )
	*video = (int)character
	*(video+1) = attributes

/*
	cursor_x++

	if ( cursor_x > (COLUMNS - 1) 
	
		cursor_x = 0
		cursor_y++
	

	if( cursor_y > (LINES - 1) 
		__scroll_up(cursor_y -(LINES - 1))
		**


/*****************
**  scroll_up()  *
******************

static PyObject *scroll_up(PyObject *self, PyObject *args

  int lines_to_scroll_up

  if (!PyArg_ParseTuple(args, "i", &lines_to_scroll_up)
    return NULL

  __scroll_up(lines_to_scroll_up)

  Py_INCREF( Py_None )
  return Py_None


/*******************
**  scroll_down()  *
********************

static PyObject *scroll_down(PyObject *self, PyObject *args

  int lines_to_scroll_down

  if (!PyArg_ParseTuple(args, "i", &lines_to_scroll_down)
    return NULL

  __scroll_down(lines_to_scroll_down)

  Py_INCREF( Py_None )
  return Py_None


/*************
** display() *
**************

static PyObject *display(PyObject *self, PyObject *args


	char *ptr_string_to_print;	/* a *
	char *fg_color;         	/* r *
	char *bg_color;         	/* g *
	unsigned int blinking;  	/* s *
	unsigned int x;         	/*   *
	unsigned int y;         	/*   *

	char attributes_mask = 0

	if (!PyArg_ParseTuple(args, "sssiii", &ptr_string_to_print, &fg_color, &bg_color, &blinking, &x, &y) 
		return NULL

	/* FOREGROUND COLORS *

	if ( strstr(fg_color,"black") 
		attributes_mask = attributes_mask | FG_BLACK

	if ( strstr(fg_color,"dark_grey" ) 
		attributes_mask = attributes_mask | FG_DARK_GRAY

	if ( strstr(fg_color,"blue" ) 
		attributes_mask = attributes_mask | FG_BLUE

	if ( strstr(fg_color,"bright_blue" ) 
		attributes_mask = attributes_mask | FG_BRIGHT_BLUE

	if ( strstr(fg_color,"green" ) 
		attributes_mask = attributes_mask | FG_GREEN

	if ( strstr(fg_color,"bright_green" ) 
		attributes_mask = attributes_mask | FG_BRIGHT_GREEN

	if ( strstr(fg_color,"cyan" ) 
		attributes_mask = attributes_mask | FG_CYAN

	if ( strstr(fg_color,"bright_cyan" ) 
		attributes_mask = attributes_mask | FG_BRIGHT_CYAN

	if ( strstr(fg_color,"red" ) 
		attributes_mask = attributes_mask | FG_RED

	if ( strstr(fg_color,"pink" ) 
		attributes_mask = attributes_mask | FG_PINK

	if ( strstr(fg_color,"magenta" ) 
		attributes_mask = attributes_mask | FG_MAGENTA

	if ( strstr(fg_color,"bright_magenta" ) 
		attributes_mask = attributes_mask | FG_BRIGHT_MAGENTA

	if ( strstr(fg_color,"brown" ) 
		attributes_mask = attributes_mask | FG_BROWN

	if ( strstr(fg_color,"yellow" ) 
		attributes_mask = attributes_mask | FG_YELLOW

	if ( strstr(fg_color,"white" ) 
		attributes_mask = attributes_mask | FG_WHITE

	if ( strstr(fg_color,"bright_white" ) 
		attributes_mask = attributes_mask | FG_BRIGHT_WHITE

	/* BACKGROUND COLORS *

	if ( strstr(bg_color,"black" ) 
		attributes_mask = attributes_mask | BG_BLACK

	if ( strstr(bg_color,"blue" ) 
		attributes_mask = attributes_mask | BG_BLUE

	if ( strstr(bg_color,"green" ) 
		attributes_mask = attributes_mask | BG_GREEN

	if ( strstr(bg_color,"cyan" ) 
		attributes_mask = attributes_mask | BG_CYAN

	if ( strstr(bg_color,"red" ) 
		attributes_mask = attributes_mask | BG_RED

	if ( strstr(bg_color,"magenta" ) 
		attributes_mask = attributes_mask | BG_MAGENTA

	if ( strstr(bg_color,"brown" ) 
		attributes_mask = attributes_mask | BG_BROWN

	if ( strstr(bg_color,"grey" ) 
		attributes_mask = attributes_mask | BG_LTGRAY

	/* BLINKING *

	if ( blinking == 1
		attributes_mask = attributes_mask | FG_BLINKING

	/* While we aren't at the end of the string, we print it. *
	while(*ptr_string_to_print != 0)
	
		__display_character(*ptr_string_to_print, attributes_mask, x++, y)
		ptr_string_to_print++
	

	Py_INCREF( Py_None )
	return Py_None


/****************
**   clear()   **
*****************

static PyObject *clear(PyObject *self, PyObject *args

	unsigned char *video

	for (video = (unsigned char*)SCREEN_START; video <= (unsigned char*)SCREEN_PAGE_LIMIT; video = video + 2
	
		*video = 0
		*(video + 1) = 0x00; /* Set with a black background/foreground *
	

	Py_INCREF( Py_None )
	return Py_None


/***************************
**   move_cursor_left()   **
****************************

static PyObject *move_cursor_left(PyObject *self, PyObject *args

  cursor_x--

  Py_INCREF( Py_None )
  return Py_None


/***************************
**   move_cursor_right()   **
****************************

static PyObject *move_cursor_right(PyObject *self, PyObject *args

  cursor_x++

  Py_INCREF( Py_None )
  return Py_None


/***************************
**   move_cursor_up()   **
****************************

static PyObject *move_cursor_up(PyObject *self, PyObject *args

  cursor_y++

  Py_INCREF( Py_None )
  return Py_None


/***************************
**   move_cursor_down()   **
****************************

static PyObject *move_cursor_down(PyObject *self, PyObject *args

  cursor_y--

  Py_INCREF( Py_None )
  return Py_None


/********************
** About the module *
*********************

static PyMethodDef ScreenMethods[] = 
  {"scroll_up", scroll_up, METH_VARARGS, "Scroll up the screen"}
  {"scroll_down", scroll_up, METH_VARARGS, "Scroll up the screen"}
  {"clear", clear, METH_VARARGS, "Clear the screen"}
  {"display", display, METH_VARARGS, "Display a string on the screen"}
  {"move_cursor_left", move_cursor_left, METH_VARARGS, "Move the cursor left"}
  {"move_cursor_right", move_cursor_right, METH_VARARGS, "Move the cursor right"}
  {"move_cursor_up", move_cursor_up, METH_VARARGS, "Move the cursor up"}
  {"move_cursor_down", move_cursor_down, METH_VARARGS, "Move teh cursor down"}
  {NULL, NULL, 0, NULL
}

void init_screenmodule() 
  Py_InitModule( "screen", ScreenMethods )


