#include "clip.h"

#define CPU_CLOCK	(640*480*60/ 12)
#define WSG_CLOCK	(640*480*60/768)

typedef struct _DRIVER {
	M6809 m6809;
	unsigned char mem[0x10000];
	//
	WSG wsg;
	unsigned char wavetable[0x100];
} DRIVER;
DRIVER driver;
M6809* m6809 = &driver.m6809;
unsigned char* mem = driver.mem;
WSG* wsg = &driver.wsg;
unsigned char* wavetable = driver.wavetable;

short wbuff[WSGBUFLEN];

//unsigned short access[0x10000];

unsigned char
m6809_read(M6809* m6809, unsigned short addr)
{
	DRIVER* driver = (DRIVER*)m6809;
	unsigned char* mem = driver->mem;

	if(addr <= 0x03ff) {
		if(addr == 0xa1) goto L10; /* GlobalCounter */
		if(addr >= 0x80 && addr <= 0x9f) goto L10; /* SoundRegister prepare */
		if(addr >= 0x3f0) goto L10; /* Stack (maybe) */
		if(m6809->pc <= 0xe073) goto L10; /* Init */
		if(m6809->pc >= 0xe55a) goto L10; /* IRQ isr */
//		if(access[addr] == m6809->pc) goto L10;
//		access[addr] = m6809->pc;
//		printf("%04x: READ %04x\n", m6809->pc, addr);
	}
L10:

	return mem[addr];
}

void
m6809_write(M6809* m6809, unsigned short addr, unsigned char data)
{
	DRIVER* driver = (DRIVER*)m6809;
	unsigned char* mem = driver->mem;

	if(addr >= 0x0080 && addr <= 0x009f && m6809->pc != 0xe584) {
//		printf("%04x: WRITE %04x %02x\n", m6809->pc, addr, data);
	}

	if(addr <= 0x3f) {
printf("%02x: %02x\n", addr, data);
		wsg_write(wsg, addr, data);
		return;
	}

	mem[addr] = data;
}

void
init()
{
	FILE* fp;

	fp = fopen("todruaga/td1_4.1k", "rb");
	if(!fp) DIE();
	fread(&mem[0xe000], 1, 0x2000, fp);
	fclose(fp);

	fp = fopen("todruaga/td1-3.3m", "rb");
	if(!fp) DIE();
	fread(wavetable, 1, 0x100, fp);
	fclose(fp);

	/* IRQ待ちループをCWAIに変更 */
	mem[0xe431+0] = 0x3c;	//CWAI #$FF
	mem[0xe431+1] = 0xff;
	mem[0xe431+2] = 0x12;	//NOP
	mem[0xe431+3] = 0x12;	//NOP

	m6809_reset(m6809, m6809_read, m6809_write);
	wsg_reset(wsg, WSG_CLOCK, wavetable);
}

int
main(int argc, char* argv[])
{
	init();

	do {
		m6809_run(m6809, CPU_CLOCK / 60);
	} while(!m6809->wait);

	mem[0x40 + 0x00] = 1;

	for(;;) {
		m6809_run(m6809, CPU_CLOCK / 60);
		m6809_irq(m6809);
		wsg_mix(wsg, wbuff, WSGBUFLEN);
	}
}

