/*
 * linux/arch/m68k/console/txtcon.c -- Low level text mode based console driver
 *
 *    Copyright (C) 1995 Geert Uytterhoeven
 *
 *
 * This file is currently only a skeleton, since all Amigas and Ataris have
 * bitmapped graphics.
 *
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file README.legal in the main directory of this archive
 * for more details.
 */


#include <linux/types.h>
#include <linux/console.h>


   /*
    *    Interface used by the world
    */

static u_long txtcon_startup(u_long kmem_start, char **display_desc);
static void txtcon_init(struct vc_data *conp);
static int txtcon_deinit(struct vc_data *conp);
static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
                        int width);
static int txtcon_putc(struct vc_data *conp, int c, int y, int x);
static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
                        int x);
static int txtcon_cursor(struct vc_data *conp, int mode);
static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count);
static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
                        int height, int width);
static int txtcon_switch(struct vc_data *conp);
static int txtcon_blank(int blank);
static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data);



static u_long txtcon_startup(u_long kmem_start, char **display_desc)
{
   *display_desc = "Not yet implemented";
   return(kmem_start);
}


static void txtcon_init(struct vc_data *conp)
{
}


static int txtcon_deinit(struct vc_data *conp)
{
   return(0);
}


/* ====================================================================== */

/* txtcon_XXX routines - interface used by the world */


static int txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
                        int width)
{
   return(0);
}


static int txtcon_putc(struct vc_data *conp, int c, int y, int x)
{
   return(0);
}


static int txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
                        int x)
{
   return(0);
}


static int txtcon_cursor(struct vc_data *conp, int mode)
{
   return(0);
}


static int txtcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
{
   return(0);
}


static int txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
                        int height, int width)
{
   return(0);
}


static int txtcon_switch(struct vc_data *conp)
{
   return(0);
}


static int txtcon_blank(int blank)
{
   return(0);
}


/*
 * PIO_FONT support.
 *
 * The font loading code goes back to the codepage package by
 * Joel Hoffman (joel@wam.umd.edu). (He reports that the original
 * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
 * Video Systems_ by Richard Wilton. 1987.  Microsoft Press".)
 *
 * Change for certain monochrome monitors by Yury Shevchuck
 * (sizif@botik.yaroslavl.su).
 */

#define colourmap ((char *)0xa0000)
/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
   should use 0xA0000 for the bwmap as well.. */
#define blackwmap ((char *)0xa0000)
#define cmapsz 8192
#define seq_port_reg (0x3c4)
#define seq_port_val (0x3c5)
#define gr_port_reg (0x3ce)
#define gr_port_val (0x3cf)

static int set_get_font(char * arg, int set)
{
#ifdef CAN_LOAD_EGA_FONTS
	int i;
	char *charmap;
	int beg;

	/* no use to "load" CGA... */

	if (video_type == VIDEO_TYPE_EGAC) {
		charmap = colourmap;
		beg = 0x0e;
	} else if (video_type == VIDEO_TYPE_EGAM) {
		charmap = blackwmap;
		beg = 0x0a;
	} else
		return -EINVAL;

	i = verify_area(set ? VERIFY_READ : VERIFY_WRITE, (void *)arg, cmapsz);
	if (i)
	        return i;

	cli();
	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
	outb_p( 0x02, seq_port_reg );
	outb_p( 0x04, seq_port_val );   /* CPU writes only to map 2 */
	outb_p( 0x04, seq_port_reg );
	outb_p( 0x07, seq_port_val );   /* Sequential addressing */
	outb_p( 0x00, seq_port_reg );
	outb_p( 0x03, seq_port_val );   /* Clear synchronous reset */

	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
	outb_p( 0x02, gr_port_val );    /* select map 2 */
	outb_p( 0x05, gr_port_reg );
	outb_p( 0x00, gr_port_val );    /* disable odd-even addressing */
	outb_p( 0x06, gr_port_reg );
	outb_p( 0x00, gr_port_val );    /* map start at A000:0000 */
	sti();

	if (set)
		memcpy_fromfs (charmap, arg, cmapsz);
	else
		memcpy_tofs (arg, charmap, cmapsz);

	cli();
	outb_p( 0x00, seq_port_reg );   /* First, the sequencer */
	outb_p( 0x01, seq_port_val );   /* Synchronous reset */
	outb_p( 0x02, seq_port_reg );
	outb_p( 0x03, seq_port_val );   /* CPU writes to maps 0 and 1 */
	outb_p( 0x04, seq_port_reg );
	outb_p( 0x03, seq_port_val );   /* odd-even addressing */
	outb_p( 0x00, seq_port_reg );
	outb_p( 0x03, seq_port_val );   /* clear synchronous reset */

	outb_p( 0x04, gr_port_reg );    /* Now, the graphics controller */
	outb_p( 0x00, gr_port_val );    /* select map 0 for CPU */
	outb_p( 0x05, gr_port_reg );
	outb_p( 0x10, gr_port_val );    /* enable even-odd addressing */
	outb_p( 0x06, gr_port_reg );
	outb_p( beg, gr_port_val );     /* map starts at b800:0 or b000:0 */
	sti();

	return 0;
#else
	return -EINVAL;
#endif
}

static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
{
	int i;
	
	i = get_set_font( data, 0 );
	if (i)
		return i;
	*w = 8;
	*h = 32;  /* This is incorrect! How to determine the real size? */
	return 0;
}


static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data)
{
	if (w != 8 || !h)
		/* no predefined fonts (?) and must be width 8 */
		return -ENXIO;
	return get_set_font( data, 1 );
}


/* ====================================================================== */

   /*
    *    The console `switch' structure for the text mode based console
    */

struct consw txt_con = {
   txtcon_startup, txtcon_init, txtcon_deinit, txtcon_clear, txtcon_putc,
   txtcon_putcs, txtcon_cursor, txtcon_scroll, txtcon_bmove, txtcon_switch,
   txtcon_blank, txtcon_get_font, txtcon_set_font
};

