smsplus/memz80.c
2016-09-21 19:54:51 -04:00

348 lines
7 KiB
C

/*
memz80.c --
Z80 port handlers.
*/
#include "shared.h"
/* Pull-up resistors on data bus */
uint8 data_bus_pullup = 0x00;
uint8 data_bus_pulldown = 0x00;
/* Read unmapped memory */
uint8 z80_read_unmapped(void)
{
int pc = z80_get_reg(Z80_PC);
uint8 data;
pc = (pc - 1) & 0xFFFF;
data = cpu_readmap[pc >> 13][pc & 0x03FF];
return ((data | data_bus_pullup) & ~data_bus_pulldown);
}
void memctrl_w(uint8 data)
{
sms.memctrl = data;
}
/*--------------------------------------------------------------------------*/
/* Sega Master System port handlers */
/*--------------------------------------------------------------------------*/
void sms_port_w(uint16 port, uint8 data)
{
switch(port & 0xC1)
{
case 0x00:
memctrl_w(data);
return;
case 0x01:
ioctrl_w(data);
return;
case 0x40:
case 0x41:
psg_write(data);
return;
case 0x80:
case 0x81:
vdp_write(port, data);
return;
case 0xC0:
case 0xC1:
return;
}
}
uint8 sms_port_r(uint16 port)
{
switch(port & 0xC0)
{
case 0x00:
return z80_read_unmapped();
case 0x40:
return vdp_counter_r(port);
case 0x80:
return vdp_read(port);
case 0xC0:
return input_r(port);
}
/* Just to please the compiler */
return -1;
}
/*--------------------------------------------------------------------------*/
/* Sega Master System (J) port handlers */
/*--------------------------------------------------------------------------*/
void smsj_port_w(uint16 port, uint8 data)
{
port &= 0xFF;
if(port >= 0xF0)
{
switch(port)
{
case 0xF0:
fmunit_write(0, data);
return;
case 0xF1:
fmunit_write(1, data);
return;
case 0xF2:
fmunit_detect_w(data);
return;
}
}
switch(port & 0xC1)
{
case 0x00:
memctrl_w(data);
return;
case 0x01:
ioctrl_w(data);
return;
case 0x40:
case 0x41:
psg_write(data);
return;
case 0x80:
case 0x81:
vdp_write(port, data);
return;
case 0xC0:
case 0xC1:
return;
}
}
uint8 smsj_port_r(uint16 port)
{
port &= 0xFF;
if(port == 0xF2 && !(sms.memctrl & 4))
return fmunit_detect_r();
switch(port & 0xC0)
{
case 0x00:
return z80_read_unmapped();
case 0x40:
return vdp_counter_r(port);
case 0x80:
return vdp_read(port);
case 0xC0:
return input_r(port);
}
/* Just to please the compiler */
return -1;
}
/*--------------------------------------------------------------------------*/
/* Game Gear port handlers */
/*--------------------------------------------------------------------------*/
void gg_port_w(uint16 port, uint8 data)
{
port &= 0xFF;
if(port <= 0x06) {
sio_w(port, data);
return;
}
switch(port & 0xC1)
{
case 0x00:
memctrl_w(data);
return;
case 0x01:
ioctrl_w(data);
return;
case 0x40:
case 0x41:
psg_write(data);
return;
case 0x80:
case 0x81:
gg_vdp_write(port, data);
return;
}
}
uint8 gg_port_r(uint16 port)
{
port &= 0xFF;
if(port <= 0x06)
return sio_r(port);
switch(port & 0xC0)
{
case 0x00:
return z80_read_unmapped();
case 0x40:
return vdp_counter_r(port);
case 0x80:
return vdp_read(port);
case 0xC0:
switch(port)
{
case 0xC0:
case 0xC1:
case 0xDC:
case 0xDD:
return input_r(port);
}
return z80_read_unmapped();
}
/* Just to please the compiler */
return -1;
}
/*--------------------------------------------------------------------------*/
/* Game Gear (MS) port handlers */
/*--------------------------------------------------------------------------*/
void ggms_port_w(uint16 port, uint8 data)
{
port &= 0xFF;
switch(port & 0xC1)
{
case 0x00:
memctrl_w(data);
return;
case 0x01:
ioctrl_w(data);
return;
case 0x40:
case 0x41:
psg_write(data);
return;
case 0x80:
case 0x81:
gg_vdp_write(port, data);
return;
}
}
uint8 ggms_port_r(uint16 port)
{
port &= 0xFF;
switch(port & 0xC0)
{
case 0x00:
return z80_read_unmapped();
case 0x40:
return vdp_counter_r(port);
case 0x80:
return vdp_read(port);
case 0xC0:
switch(port)
{
case 0xC0:
case 0xC1:
case 0xDC:
case 0xDD:
return input_r(port);
}
return z80_read_unmapped();
}
/* Just to please the compiler */
return -1;
}
/*--------------------------------------------------------------------------*/
/* MegaDrive / Genesis port handlers */
/*--------------------------------------------------------------------------*/
void md_port_w(uint16 port, uint8 data)
{
switch(port & 0xC1)
{
case 0x00:
/* No memory control register */
return;
case 0x01:
ioctrl_w(data);
return;
case 0x40:
case 0x41:
psg_write(data);
return;
case 0x80:
case 0x81:
md_vdp_write(port, data);
return;
}
}
uint8 md_port_r(uint16 port)
{
switch(port & 0xC0)
{
case 0x00:
return z80_read_unmapped();
case 0x40:
return vdp_counter_r(port);
case 0x80:
return vdp_read(port);
case 0xC0:
switch(port)
{
case 0xC0:
case 0xC1:
case 0xDC:
case 0xDD:
return input_r(port);
}
return z80_read_unmapped();
}
/* Just to please the compiler */
return -1;
}