mirror of
https://github.com/0ldsk00l/smsplus.git
synced 2025-04-02 10:32:07 -04:00
348 lines
7 KiB
C
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;
|
|
}
|
|
|