ref: e8cac1e4c4a0005abbb15ecc7324e2751822386f
dir: /mem.c/
#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;
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] = (b << 16) | (g << 8) | r;
// printf("cramwrite %x %x\n", a, v);
// for(int i=0;i<64;i++)
// printf("%x ", cram[i]);
// printf("\n");
}
void
mapperinit(void)
{
slotaddr[0] = 0;
slotaddr[1] = 0x4000;
slotaddr[2] = (nbank - 1) * 0x4000;
ram_bank = 0;
ram_enabled = 0;
}
u8int
z80read(u16int a)
{
// printf("z80read %x\n", 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{
// print("== page 2 %x %x %x\n", a, (a - 0x8000) + slotaddr[2], slotaddr[2]);
// print("== rom[(a - 0x8000) + slotaddr[2]] %x\n", rom[(a - 0x8000) + slotaddr[2]]);
return rom[(a - 0x8000) + slotaddr[2]];
}
}else
return mem[a];
}
void
z80write(u16int a, u8int v)
{
// print("z80write %x %x\n", a, 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
{
// print("z80write > 0xE000 %x %x", a, v);
mem[a] = v;
mem[a - 0x2000] = v;
switch (a)
{
case 0xFFFC:
ram_bank = (v & (1 << 2)) != 0 ? 0x4000 : 0;
// print("RAM bank %x", ram_bank);
ram_enabled = (v & (1 << 3)) != 0 ? 1 : 0;
// print("RAM enabled %x", ram_enabled);
break;
case 0xFFFD:
// print("Switch mapper slot 0 to %d", (v & nbank-1));
slotaddr[0] = (v & nbank-1) * 0x4000;
break;
case 0xFFFE:
// print("switch mapper slot 1 to %d", (v & nbank-1));
slotaddr[1] = (v & nbank-1) * 0x4000;
break;
case 0xFFFF:
// print("switch mapper slot 2 to %d", (v & nbank-1));
slotaddr[2] = (v & nbank-1) * 0x4000;
break;
}
}
}
u8int portDC = 0x00;
u8int portDD = 0xff;
u8int port3E = 0x00;
u8int port3F = 0x00;
u8int port3FHC = 0x00;
u8int
z80in(u8int port)
{
// print("z80in %x", 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)
{
// print("z80out %x %x", port, v);
if (port < 0x40){
// print(" write to control register");
if ((port & 0x01) == 0x00)
port3E = v;
else{
port3FHC = v & 0x05;
port3F = ((v & 0x80) | (v & 0x20) << 1) & 0xC0;
}
}else if ((port >= 0x40) && (port < 0x80)){
// print(" write to SN76489 PSG");
psgwrite(v);
}else if ((port >= 0x80) && (port < 0xC0)){
// print(" write to VDP");
if ((port & 0x01) == 0x00)
vdpdata(v);
else
vdpctrl(v);
}else
print(" write with no effect");
}