#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <stdarg.h>

#include <stdtypes.h>
#define die(x) { perror(x); exit(1); }
#define warn(x) { perror(x);  }

#include <x86emu/x86emu.h>
#include <console/console.h>
#include "helper_exec.h"
#include "testbios.h"
#include "pci-userspace.h"
int X86EMU_set_debug(int debug);
unsigned short get_device(char *arg_val);

extern int teststart, testend;

_ptr p;
ptr current = 0;
unsigned char biosmem[1024 * 1024];

int verbose = 0;


/* Interrupt multiplexer */

static void do_int(int num)
{
	int ret = 0;

	printf("int%x vector at %x\n", num, getIntVect(num));

	/* This is a pInt leftover */
	current->num = num;

	switch (num) {
#ifndef _PC
	case 0x10:
	case 0x42:
	case 0x6D:

		if (getIntVect(num) == 0xFF065) {
			ret = int42_handler();
		}
		break;
#endif
	case 0x15:
		ret = int15_handler();
		break;
	case 0x16:
		ret = int16_handler();
		break;
	case 0x1A:
		ret = int1A_handler();
		break;
	case 0xe6:
		ret = intE6_handler();
		break;
	default:
		break;
	}

	if (!ret)
		ret = run_bios_int(num);

	if (!ret) {
		printf("\nint%x: not implemented\n", num);
		//x86emu_dump_xregs();
	}
}

static unsigned char *mapitin(char *file, off_t where, size_t size)
{
	void *z;

	int fd = open(file, O_RDWR, 0);

	if (fd < 0)
		die(file);
	z = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, where);
	if (z == (void *) -1)
		die("mmap");
	close(fd);

	return z;

}

X86EMU_pioFuncs myfuncs = {
	x_inb, x_inw, x_inl,
	x_outb, x_outw, x_outl
};


static void usage(char *name)
{
	printf
	    ("Usage: %s [-c codesegment] [-s size] [-b base] [-i ip] [-t] <filename> ... \n",
	     name);
}

int main(int argc, char **argv)
{
	char *absegname = 0;
	void *abseg = 0;
	int i, c, trace = 0;
	unsigned char *cp;
	char *filename;
	ssize_t size = 0;
	int base = 0;
	int have_size = 0, have_base = 0, have_ip = 0, have_cs = 0;
	int have_devfn = 0;
	int parse_rom = 0;
	char *fsegname = 0;
	unsigned char *fsegptr;
	unsigned short initialip = 0, initialcs = 0, devfn = 0;
	X86EMU_intrFuncs intFuncs[256];
	int debugflag = 0;

	const char *optstring = "vh?b:i:c:s:tpd:";
	while (1) {
		int option_index = 0;
		static struct option long_options[] = {
			{"verbose", 0, 0, 'v'},
			{"help", 0, 0, 'h'},
			{"trace", 0, 0, 't'},
			{"base", 1, 0, 'b'},
			{"fseg", 1, 0, 'f'},
			{"instructionpointer", 1, 0, 'i'},
			{"codesegment", 1, 0, 'c'},
			{"absegment", 1, 0, 'a'},
			{"size", 1, 0, 's'},
			{"parserom", 0, 0, 'p'},
			{"device", 1, 0, 'd'},
			{"debug", 1, 0, 'D'},
			{0, 0, 0, 0}
		};
		c = getopt_long(argc, argv, optstring, long_options, &option_index);
		if (c == -1)
			break;
		switch (c) {
		case 'v':
			verbose = 1;
			break;
		case 'h':
		case '?':
			usage(argv[0]);
			return 0;
		case 't':
			trace = 1;
			break;
		case 'b':
			base = strtol(optarg, 0, 0);
			have_base = 1;
			break;
		case 'i':
			initialip = strtol(optarg, 0, 0);
			have_ip = 1;
			break;
		case 'c':
			initialcs = strtol(optarg, 0, 0);
			have_cs = 1;
			break;
		case 's':
			size = strtol(optarg, 0, 0);
			have_size = 1;
			break;
		case 'p':
			parse_rom = 1;
			break;
		case 'f':
			fsegname = optarg;
			break;
		case 'a':
			absegname = optarg;
			break;
		case 'd':
			devfn = get_device(optarg);
			have_devfn = 1;
			break;
		case 'D':
			debugflag = strtol(optarg, 0, 0);
			break;
		default:
			printf("Unknown option \n");
			usage(argv[0]);
			return 1;
		}
	}

	if (optind >= argc) {
		printf("Filename missing.\n");
		usage(argv[0]);
		return 1;
	}

	while (optind < argc) {
		printf("running file %s\n", argv[optind]);
		filename = argv[optind];
		optind++;
		/* normally we would do continue, but for
		 * now only one filename is supported.
		 */
		/* continue; */
		break;
	}

	if (!have_size) {
		printf("No size specified. defaulting to 32k\n");
		size = 32 * 1024;
	}
	if (!have_base) {
		printf("No base specified. defaulting to 0xc0000\n");
		base = 0xc0000;
	}
	if (!have_cs) {
		printf("No initial code segment specified. defaulting to 0xc000\n");
		initialcs = 0xc000;
	}
	if (!have_ip) {
		printf
		    ("No initial instruction pointer specified. defaulting to 0x0003\n");
		initialip = 0x0003;
	}

	if (parse_rom)
		printf("Parsing rom images not implemented.\n");

	//printf("Point 1 int%x vector at %x\n", 0x42, getIntVect(0x42));

	if (initialip == 0x0003) {
		if ((devfn == 0) || (have_devfn == 0)) {
			printf("WARNING! It appears you are trying to run an option ROM.\n");
			printf("  (initial ip = 0x0003)\n");
			if (have_devfn) {
				printf("  However, the device you have specified is 0x00\n");
				printf("  It is very unlikely that your device is at this address\n");
				printf("  Please check your -d option\n");
			}
			else {
				printf("  Please specify a device with -d\n");
				printf("  The default is not likely to work\n");
			}
		}
	}

	if (absegname) {
		abseg = mapitin(absegname, (off_t) 0xa0000, 0x20000);
		if (!abseg)
			die(absegname);
	}

	current = &p;
	X86EMU_setMemBase(biosmem, sizeof(biosmem));
	M.abseg = (unsigned long)abseg;
	X86EMU_setupPioFuncs(&myfuncs);
	ioperm(0, 0x400, 1);

	if (iopl(3) < 0) {
		warn("iopl failed, continuing anyway");
	}

	/* Emergency sync ;-) */
	sync();
	sync();

	/* Setting up interrupt environment.
	 * basically this means initializing PCI and
	 * intXX handlers.
	 */
	pciInit();

	for (i = 0; i < 256; i++)
		intFuncs[i] = do_int;
	X86EMU_setupIntrFuncs(intFuncs);
	cp = mapitin(filename, (off_t) 0, size);

	if (devfn) {
		printf("Loading ax with BusDevFn = %x\n",devfn);
	}

	current->ax = devfn   ? devfn : 0xff;
	current->dx = 0x80;
	//      current->ip = 0;
	for (i = 0; i < size; i++)
		wrb(base + i, cp[i]);

	if (fsegname) {
		fsegptr = mapitin(fsegname, (off_t) 0, 0x10000);
		for (i = 0; i < 0x10000; i++)
			wrb(0xf0000 + i, fsegptr[i]);
	} else {
		const char *date = "01/01/99";
		for (i = i; date[i]; i++)
			wrb(0xffff5 + i, date[i]);
		wrb(0xffff7, '/');
		wrb(0xffffa, '/');
	}
	/* cpu setup */
	X86_AX = devfn ? devfn : 0xff;
	X86_DX = 0x80;
	X86_EIP = initialip;
	X86_CS = initialcs;

	/* Initialize stack and data segment */
	X86_SS = 0x0030;
	X86_DS = 0x0040;
	X86_SP = 0xfffe;
	/* We need a sane way to return from bios
	 * execution. A hlt instruction and a pointer
	 * to it, both kept on the stack, will do.
	 */
	pushw(0xf4f4);		/* hlt; hlt */
	pushw(X86_SS);
	pushw(X86_SP + 2);

	X86_ES = 0x0000;

	if (trace) {
		printf("Switching to single step mode.\n");
		//X86EMU_trace_on();
	}
	if (debugflag) {
		//X86EMU_set_debug(debugflag);
	}
	X86EMU_exec();
	/* Cleaning up */
	pciExit();

	return 0;
}

unsigned short get_device(char *arg_val)
{
	unsigned short devfn=0;
	long bus=0,dev=0,fn=0,need_pack=0;
	char *tok;

	tok = strsep(&arg_val,":");
	if (arg_val != NULL) {
		bus = strtol(tok,0,16);
		need_pack = 1;
	}
	else {
		arg_val = tok;
	}

	tok = strsep(&arg_val,".");
	if (arg_val != NULL) {
		dev = strtol(tok,0,16);
		fn  = strtol(arg_val,0,16);
		need_pack = 1;
	}
	else {
		if (need_pack ==1 && (strlen(tok))) {
			dev = strtol(tok,0,16);
		}
	}

	if ( need_pack == 1) {
		devfn = bus<<8 | (dev<<3) | fn;
	}
	else {
		devfn = strtol(tok, 0, 0);
	}


	return devfn;
}

int printk(int msg_level, const char *fmt, ...)
{
	va_list args;
	int i;

	printf ("<%d> ", msg_level);
	va_start(args, fmt);
	i = vprintf(fmt, args);
	va_end(args);

	return i;
}
