/*
 *  arch/arm/mach-rpc/include/mach/uncompress.h
 *
 *  Copyright (C) 1996 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#define VIDMEM ((char *)SCREEN_START)
 
#include <linux/io.h>
#include <mach/hardware.h>
#include <asm/setup.h>
#include <asm/page.h>

int video_size_row;
unsigned char bytes_per_char_h;
extern unsigned long con_charconvtable[256];

struct param_struct {
	unsigned long page_size;
	unsigned long nr_pages;
	unsigned long ramdisk_size;
	unsigned long mountrootrdonly;
	unsigned long rootdev;
	unsigned long video_num_cols;
	unsigned long video_num_rows;
	unsigned long video_x;
	unsigned long video_y;
	unsigned long memc_control_reg;
	unsigned char sounddefault;
	unsigned char adfsdrives;
	unsigned char bytes_per_char_h;
	unsigned char bytes_per_char_v;
	unsigned long unused[256/4-11];
};

static const unsigned long palette_4[16] = {
	0x00000000,
	0x000000cc,
	0x0000cc00,             /* Green   */
	0x0000cccc,             /* Yellow  */
	0x00cc0000,             /* Blue    */
	0x00cc00cc,             /* Magenta */
	0x00cccc00,             /* Cyan    */
	0x00cccccc,             /* White   */
	0x00000000,
	0x000000ff,
	0x0000ff00,
	0x0000ffff,
	0x00ff0000,
	0x00ff00ff,
	0x00ffff00,
	0x00ffffff
};

#define palette_setpixel(p)	*(unsigned long *)(IO_START+0x00400000) = 0x10000000|((p) & 255)
#define palette_write(v)	*(unsigned long *)(IO_START+0x00400000) = 0x00000000|((v) & 0x00ffffff)

/*
 * params_phys is a linker defined symbol - see
 * arch/arm/boot/compressed/Makefile
 */
extern __attribute__((pure)) struct param_struct *params(void);
#define params (params())

#ifndef STANDALONE_DEBUG 
unsigned long video_num_cols;
unsigned long video_num_rows;
unsigned long video_x;
unsigned long video_y;
unsigned char bytes_per_char_v;
int white;

/*
 * This does not append a newline
 */
static inline void putc(int c)
{
	extern void ll_write_char(char *, char c, char white);
	int x,y;
	char *ptr;

	x = video_x;
	y = video_y;

	if (c == '\n') {
		if (++y >= video_num_rows)
			y--;
	} else if (c == '\r') {
		x = 0;
	} else {
		ptr = VIDMEM + ((y*video_num_cols*bytes_per_char_v+x)*bytes_per_char_h);
		ll_write_char(ptr, c, white);
		if (++x >= video_num_cols) {
			x = 0;
			if ( ++y >= video_num_rows ) {
				y--;
			}
		}
	}

	video_x = x;
	video_y = y;
}

static inline void flush(void)
{
}

/*
 * Setup for decompression
 */
static void arch_decomp_setup(void)
{
	int i;
	struct tag *t = (struct tag *)params;
	unsigned int nr_pages = 0, page_size = PAGE_SIZE;

	if (t->hdr.tag == ATAG_CORE)
	{
		for (; t->hdr.size; t = tag_next(t))
		{
			if (t->hdr.tag == ATAG_VIDEOTEXT)
			{
				video_num_rows = t->u.videotext.video_lines;
				video_num_cols = t->u.videotext.video_cols;
				bytes_per_char_h = t->u.videotext.video_points;
				bytes_per_char_v = t->u.videotext.video_points;
				video_x = t->u.videotext.x;
				video_y = t->u.videotext.y;
			}

			if (t->hdr.tag == ATAG_MEM)
			{
				page_size = PAGE_SIZE;
				nr_pages += (t->u.mem.size / PAGE_SIZE);
			}
		}
	}
	else
	{
		nr_pages = params->nr_pages;
		page_size = params->page_size;
		video_num_rows = params->video_num_rows;
		video_num_cols = params->video_num_cols;
		video_x = params->video_x;
		video_y = params->video_y;
		bytes_per_char_h = params->bytes_per_char_h;
		bytes_per_char_v = params->bytes_per_char_v;
	}

	video_size_row = video_num_cols * bytes_per_char_h;
	
	if (bytes_per_char_h == 4)
		for (i = 0; i < 256; i++)
			con_charconvtable[i] =
				(i & 128 ? 1 << 0  : 0) |
				(i & 64  ? 1 << 4  : 0) |
				(i & 32  ? 1 << 8  : 0) |
				(i & 16  ? 1 << 12 : 0) |
				(i & 8   ? 1 << 16 : 0) |
				(i & 4   ? 1 << 20 : 0) |
				(i & 2   ? 1 << 24 : 0) |
				(i & 1   ? 1 << 28 : 0);
	else
		for (i = 0; i < 16; i++)
			con_charconvtable[i] =
				(i & 8   ? 1 << 0  : 0) |
				(i & 4   ? 1 << 8  : 0) |
				(i & 2   ? 1 << 16 : 0) |
				(i & 1   ? 1 << 24 : 0);


	palette_setpixel(0);
	if (bytes_per_char_h == 1) {
		palette_write (0);
		palette_write (0x00ffffff);
		for (i = 2; i < 256; i++)
			palette_write (0);
		white = 1;
	} else {
		for (i = 0; i < 256; i++)
			palette_write (i < 16 ? palette_4[i] : 0);
		white = 7;
	}

	if (nr_pages * page_size < 4096*1024) error("<4M of mem\n");
}
#endif
