#include "clip.h"

#define M6800_CLOCK	894886	/* NTSCカラーサブキャリア周波数(=3579545)の4分周 */
#define AY38910_CLOCK	M6800_CLOCK

unsigned char m6800_read (M6800* m6800, unsigned short addr);
         void m6800_write(M6800* m6800, unsigned short addr, unsigned char data);

typedef struct _DRIVER {
	M6800 m6800;
	unsigned char mem[0x10000];
	AY38910 ay1;
	AY38910 ay2;
} DRIVER;
DRIVER g_driver;

typedef struct _ROM {
	const char* name;
	unsigned short base;
	unsigned short size;
} ROM;
ROM roms[] = {
	{ "lr2-a-3e", 0xa000, 0x2000 },
	{ "lr2-a-3f", 0xc000, 0x2000 },
	{ "lr2-a-3h", 0xe000, 0x2000 },
};

void
rom_load()
{
	unsigned char* mem = g_driver.mem;
	char buf[100];
	int retval, i;
	ROM* rom;
	FILE* fp;

	for(i = 0; i < sizeof roms / sizeof *roms; i++) {
		rom = &roms[i];
		strcpy(buf, "ldrun2/");
		strcat(buf, rom->name);
		fp = fopen(buf, "rb");
		assert(fp);
		retval = fread(mem + rom->base, 1, rom->size, fp);
		assert(retval == rom->size);
	}
}

int
main(int argc, char* argv[])
{
	M6800* m6800 = &g_driver.m6800;
	unsigned char* mem = g_driver.mem;
	AY38910* ay1 = &g_driver.ay1;
	AY38910* ay2 = &g_driver.ay2;
//	short wbuff[320];

	rom_load();
	mem[0x02] = 0xff;

	m6800_reset(m6800, m6800_read, m6800_write);
	ay38910_reset(ay1, AY38910_CLOCK, NULL, NULL);
	ay38910_reset(ay2, AY38910_CLOCK, NULL, NULL);

//	mem[0xfb43] = 0x3e;	/* WAI */
//	mem[0xfb44] = 0x01;	/* NOP */
//	mem[0xfb45] = 0x01;	/* NOP */
//	mem[0xfb46] = 0x01;	/* NOP */

	mem[2] = 0x26;
	m6800_irq(m6800);

	for(;;) {
		m6800_run(m6800, M6800_CLOCK / 4000);
		m6800_nmi(m6800);
//		mem[0xbd]++;
//		mem[0xbf]++;
//		if(!(mem[0xbf] & 0xf)) {
//			mem[0xc0]++;
//			if(mem[0xc0]) m6800->wait = 0;
//		}
//		ay38910_mix(ay1, wbuff, 320);
	}

	return 0;
}

unsigned char
m6800_read(M6800* m6800, unsigned short addr)
{	
	DRIVER* driver = (DRIVER*)m6800;
	unsigned char* mem = driver->mem;

	if(addr >= 0x02 && addr <= 0x03) {
//		printf("%04x READ  %04x\n", m6800->pc, addr);
	}

	return mem[addr];
}

void
m6800_write(M6800* m6800, unsigned short addr, unsigned char data)
{
	DRIVER* driver = (DRIVER*)m6800;
	unsigned char* mem = driver->mem;
	AY38910* ay1 = &driver->ay1;
	AY38910* ay2 = &driver->ay2;

	static int port1;
	static int port2;

	switch(addr) {
	case 2:
		port1 = data;
		return;
	case 3:
		if((port2 & 1) && !(data & 1)) {
			if(port2 & 0x04) {
				if(port2 & 0x08) ay38910_address(ay1, port1 & 15);
				if(port2 & 0x10) ay38910_address(ay2, port1 & 15);
			} else {
				if(port2 & 0x08) {
if(ay1->address <= 13) TRACE("PSG1: %02x %02x\n", ay1->address, (unsigned char)port1);
					ay38910_write(ay1, (unsigned char)port1);
				}
				if(port2 & 0x10) {
if(ay2->address <= 13) TRACE("PSG2: %02x %02x\n", ay2->address, (unsigned char)port1);
					ay38910_write(ay2, (unsigned char)port1);
				}
			}
		}
		port2 = data;
		return;
	}

	mem[addr] = data;
}

