shithub: sms

ref: e1dfe664672f3520ecfccefd0fe6a9c1a8d38c0f
dir: /mem.c/

View raw version
#include <u.h>
#include <libc.h>
#include <thread.h>
#include "../eui.h"
#include "dat.h"
#include "fns.h"

u16int ram[32768] = {0};
u8int vram[32768];
u8int cram[64], vsram[40];
u32int cramc[64];
u8int reg[16] = {
    0x36, 0x80, 0xff, 0xff,
    0xff, 0xff, 0xfb, 0x00,
    0x00, 0x00, 0xff, 0x00,
    0x00, 0x00, 0x00, 0x00,
};
u8int ctl[15];

u8int vdplatch;

u8int z80bus = 0;
u16int ram_bank;
u8int ram_enabled = 0;

int slotaddr[3] = {0, 0, 0};
int nbank = 1;

u8int portDC = 0x00;
u8int portDD = 0xff;
u8int port3E = 0x00;
u8int port3F = 0x00;
u8int port3FHC = 0x00;

void
cramwrite(u16int a, u8int v)
{
	cram[a & 0x1f] = v;

	u8int r = (v & 0x03) << 6;
	u8int g = (v & 0x0c) << 4;
	u8int b = (v & 0x30) << 2;

	cramc[a & 0x1f] = (r << 16) | (g << 8) | b;
}

void
mapperinit(void)
{
	slotaddr[0] = 0;
	slotaddr[1] = 0x4000;
	slotaddr[2] = (nbank - 1) * 0x4000;
	ram_bank = 0;
	ram_enabled = 0;
}

u8int
z80read(u16int a)
{
	if (a < 0x400)
		return rom[a];
	else if (a < 0x4000)
		return rom[a + slotaddr[0]];
	else if (a < 0x8000)
		return rom[(a - 0x4000) + slotaddr[1]];
	else if (a < 0xC000){
		if (ram_enabled)
			return ram[(a - 0x8000) + ram_bank];
		else
			return rom[(a - 0x8000) + slotaddr[2]];
	}else
		return mem[a];
}

void
z80write(u16int a, u8int v)
{
	if (a < 0x8000)
		print("wrong z80write page 0 or 1 %x %x", a, v);
	else if (a < 0xC000)
		if (ram_enabled)
			ram[(a - 0x8000) + ram_bank] = v;
		else
			print("wrong z80write page 2 %x %x", a, v);
	else if (a < 0xE000)
	{
		mem[a] = v;
		mem[a + 0x2000]  = v;
	}
	else
	{
		mem[a] = v;
		mem[a - 0x2000]  = v;

		switch (a)
		{
			case 0xFFFC:
				ram_bank = (v & (1 << 2)) != 0 ? 0x4000 : 0;
				ram_enabled = (v & (1 << 3)) != 0 ? 1 : 0;
				break;
			case 0xFFFD:
				slotaddr[0] = (v & nbank-1) * 0x4000;
				break;
			case 0xFFFE:
				slotaddr[1] = (v & nbank-1) * 0x4000;
				break;
			case 0xFFFF:
				slotaddr[2] = (v & nbank-1) * 0x4000;
				break;
		}
	}
}

u8int
z80in(u8int port)
{
	if (port < 0x40)
		return 0xff;
	else if (port >= 0x40 && port < 0x80)
		if ((port & 0x01) == 0x00)
			return vdpvcounter();
		else
			return vdphcounter();
	else if ((port >= 0x80) && (port < 0xC0))
		if ((port & 0x01) == 0x00)
			return vdpdataport();
		else
			return vdpstatus();
	else
		if ((port & 0x01) == 0x00)
			return portDC;
		else
			return (portDD & 0x3f) | (port3F & 0xc0);
}

void
z80out(u8int port, u8int v)
{
	if (port < 0x40){
		if ((port & 0x01) == 0x00)
			port3E = v;
		else{
			port3FHC = v & 0x05;
			port3F = ((v & 0x80) | (v & 0x20) << 1) & 0xC0;
		}
	}else if ((port >= 0x40) && (port < 0x80)){
		psgwrite(v);
	}else if ((port >= 0x80) && (port < 0xC0)){
		if ((port & 0x01) == 0x00)
			vdpdata(v);
		else
			vdpctrl(v);
	}
}