#include "mapper_direct.h"

struct mapper_direct_t
{
	int* memory;
};

void mapper_direct_init(mapper_direct_t** mapper_direct, int* memory, mapper_funcs_t* mapper_funcs)
{
	mapper_direct_t* pThis = NULL;

	(*mapper_direct) = (mapper_direct_t*)malloc(sizeof(mapper_direct_t));
	assert((*mapper_direct));
	pThis = (*mapper_direct);
	
	pThis->memory = memory;
	
	mapper_funcs->read = &mapper_direct_read;
	mapper_funcs->write = &mapper_direct_write;
	mapper_funcs->kill = &mapper_direct_kill;
}

void mapper_direct_kill(void* mapper_data)
{
	mapper_direct_t* pThis = (mapper_direct_t*)mapper_data;
	
	assert(pThis);
	
	free(pThis);
}

int mapper_direct_read(void* mapper_data, int address)
{
	mapper_direct_t* pThis = (mapper_direct_t*)mapper_data;
	
	assert(pThis);

	address &= 0xFFFF;
	if (address > 0x4017) {
		/* SaveRAM */
		return pThis->memory[address];
	}
	else if (address >= 0x2000) {
		/* TODO: IO Ports */
		return 0x0;
	}
	else {
		/* RAM (mirrored) */
		return pThis->memory[address & 0x7FF];
	}
}

void mapper_direct_write(void* mapper_data, int address, int value)
{
	mapper_direct_t* pThis = (mapper_direct_t*)mapper_data;
	
	assert(pThis);
	
	if (address > 0x4017) {
		pThis->memory[address] = value;
		if (address >= 0x6000 && address < 0x8000) {
			/* TODO: Write to SaveRAM, store in file. */
		}
	}
	else if (address > 0x2007 && address < 0x4000) {
		/* TODO: Write to registers, offset */
	}
	else if (address < 0x2000) {
		/* RAM (mirrored) */
		pThis->memory[address & 0x7FF] = value;
	}
	else {
		/* TODO: Write to registers */
	}
}