(MESS) megadriv.c: backing up preliminary work on SVP as slot device. disabled by default.

also reorganization of megadriv.xml, part 1. nw.
This commit is contained in:
Fabio Priuli 2013-03-21 15:53:22 +00:00
parent 28f8897275
commit f1283d262c
7 changed files with 2397 additions and 1724 deletions

2
.gitattributes vendored
View File

@ -7314,6 +7314,8 @@ src/mess/machine/md_slot.c svneol=native#text/plain
src/mess/machine/md_slot.h svneol=native#text/plain
src/mess/machine/md_stm95.c svneol=native#text/plain
src/mess/machine/md_stm95.h svneol=native#text/plain
src/mess/machine/md_svp.c svneol=native#text/plain
src/mess/machine/md_svp.h svneol=native#text/plain
src/mess/machine/megasvp.c svneol=native#text/plain
src/mess/machine/mface2.c svneol=native#text/plain
src/mess/machine/mface2.h svneol=native#text/plain

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
#include "includes/md.h"
#include "machine/md_slot.h"
#include "machine/md_rom.h"
//#include "machine/md_svp.h"
#include "machine/md_svp.h"
#include "machine/md_sk.h"
#include "machine/md_eeprom.h"
#include "machine/md_jcart.h"
@ -296,8 +296,7 @@ static MACHINE_RESET( ms_megadriv )
static SLOT_INTERFACE_START(md_cart)
SLOT_INTERFACE_INTERNAL("rom", MD_STD_ROM)
SLOT_INTERFACE_INTERNAL("rom_svp", MD_STD_ROM)
// SLOT_INTERFACE_INTERNAL("rom_svp", MD_ROM_SVP) // not ready yet...
SLOT_INTERFACE_INTERNAL("rom_svp", MD_ROM_SVP) // in progress...
SLOT_INTERFACE_INTERNAL("rom_sk", MD_ROM_SK)
// NVRAM handling
SLOT_INTERFACE_INTERNAL("rom_sram", MD_ROM_SRAM)

View File

@ -228,8 +228,7 @@ struct md_slot
static const md_slot slot_list[] =
{
{ SEGA_SK, "rom_sk" },
{ SEGA_STD, "rom_svp"},
// { SEGA_SVP, "rom_svp"}, // not ready yet...
{ SEGA_SVP, "rom_svp"},
{ SEGA_SRAM, "rom_sram" },
{ SEGA_FRAM, "rom_fram" },

440
src/mess/machine/md_svp.c Normal file
View File

@ -0,0 +1,440 @@
/****************************************** SVP related *****************************************/
/*
* Emulator of memory controller in SVP chip
*
* Copyright 2008, Grazvydas Ignotas
* based on RE work by Tasco Deluxe
*
* SSP1601 EXT registers are mapped as I/O ports due to their function
* (they are interfaced through external bus), and are named as follows
* (these are unofficial names, official ones are unknown):
* EXT0: PM0 - programmable register 0
* EXT1: PM1 - ... 1
* EXT2: PM2 - ... 2
* EXT3: XST - external status. Can also act as PM.
* EXT4: PM4 - ... 4
* EXT5: (unused)
* EXT6: PMC - programmable memory register control (PMAC).
* EXT7: AL - although internal to SSP1601, it still causes bus access
*
* Depending on GPO bits in status register, PM0, PM1, PM2 and XST can act as
* external status registers, os as programmable memory registers. PM4 always
* acts as PM register (independent on GPO bits).
*/
#include "emu.h"
#include "machine/md_svp.h"
//-------------------------------------------------
// md_rom_device - constructor
//-------------------------------------------------
const device_type MD_ROM_SVP = &device_creator<md_rom_svp_device>;
md_rom_svp_device::md_rom_svp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, type, name, tag, owner, clock),
device_md_cart_interface( mconfig, *this ),
m_svp(*this, "svp"),
m_test_ipt(*this, "MEMORY_TEST")
{
}
md_rom_svp_device::md_rom_svp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MD_ROM_SVP, "MD Virtua Racing", tag, owner, clock),
device_md_cart_interface( mconfig, *this ),
m_svp(*this, "svp"),
m_test_ipt(*this, "MEMORY_TEST")
{
}
#define SSP_PMC_HAVE_ADDR 1 // address written to PMAC, waiting for mode
#define SSP_PMC_SET 2 // PMAC is set, PMx can be programmed
#define MASTER_CLOCK_NTSC 53693175
// HELPERS
INLINE int get_inc(int mode)
{
int inc = (mode >> 11) & 7;
if (inc != 0) {
if (inc != 7) inc--;
inc = 1 << inc; // 0 1 2 4 8 16 32 128
if (mode & 0x8000) inc = -inc; // decrement mode
}
return inc;
}
INLINE void overwrite_write(UINT16 *dst, UINT16 d)
{
if (d & 0xf000) { *dst &= ~0xf000; *dst |= d & 0xf000; }
if (d & 0x0f00) { *dst &= ~0x0f00; *dst |= d & 0x0f00; }
if (d & 0x00f0) { *dst &= ~0x00f0; *dst |= d & 0x00f0; }
if (d & 0x000f) { *dst &= ~0x000f; *dst |= d & 0x000f; }
}
UINT32 md_rom_svp_device::pm_io(int reg, int write, UINT32 d)
{
if (m_emu_status & SSP_PMC_SET)
{
m_pmac_read[write ? reg + 6 : reg] = m_pmc.d;
m_emu_status &= ~SSP_PMC_SET;
return 0;
}
// just in case
if (m_emu_status & SSP_PMC_HAVE_ADDR)
m_emu_status &= ~SSP_PMC_HAVE_ADDR;
if (reg == 4 || (m_svp->state().state_int(SSP_ST) & 0x60))
{
#define CADDR ((((mode<<16)&0x7f0000)|addr)<<1)
UINT16 *dram = (UINT16 *)m_dram;
if (write)
{
int mode = m_pmac_write[reg] >> 16;
int addr = m_pmac_write[reg] & 0xffff;
if ((mode & 0x43ff) == 0x0018) // DRAM
{
int inc = get_inc(mode);
if (mode & 0x0400)
overwrite_write(&dram[addr], d);
else
dram[addr] = d;
m_pmac_write[reg] += inc;
}
else if ((mode & 0xfbff) == 0x4018) // DRAM, cell inc
{
if (mode & 0x0400)
overwrite_write(&dram[addr], d);
else
dram[addr] = d;
m_pmac_write[reg] += (addr & 1) ? 31 : 1;
}
else if ((mode & 0x47ff) == 0x001c) // IRAM
{
int inc = get_inc(mode);
((UINT16 *)m_iram)[addr & 0x3ff] = d;
m_pmac_write[reg] += inc;
}
else
{
logerror("ssp FIXME: PM%i unhandled write mode %04x, [%06x] %04x\n",
reg, mode, CADDR, d);
}
}
else
{
int mode = m_pmac_read[reg] >> 16;
int addr = m_pmac_read[reg] & 0xffff;
if ((mode & 0xfff0) == 0x0800) // ROM, inc 1, verified to be correct
{
UINT16 *ROM = (UINT16 *)get_rom_base();
m_pmac_read[reg] += 1;
d = ROM[addr | ((mode & 0xf) << 16)];
}
else if ((mode & 0x47ff) == 0x0018) // DRAM
{
int inc = get_inc(mode);
d = dram[addr];
m_pmac_read[reg] += inc;
}
else
{
logerror("ssp FIXME: PM%i unhandled read mode %04x, [%06x]\n",
reg, mode, CADDR);
d = 0;
}
}
// PMC value corresponds to last PMR accessed (not sure).
m_pmc.d = m_pmac_read[write ? reg + 6 : reg];
return d;
}
return (UINT32)-1;
}
READ16_MEMBER( md_rom_svp_device::read_pm0 )
{
UINT32 d = pm_io(0, 0, 0);
if (d != (UINT32)-1)
return d;
d = m_xst2;
m_xst2 &= ~2; // ?
return d;
}
WRITE16_MEMBER( md_rom_svp_device::write_pm0 )
{
UINT32 r = pm_io(0, 1, data);
if (r != (UINT32)-1)
return;
m_xst2 = data; // ?
}
READ16_MEMBER( md_rom_svp_device::read_pm1 )
{
UINT32 r = pm_io(1, 0, 0);
if (r != (UINT32)-1)
return r;
logerror("svp: PM1 acces in non PM mode?\n");
return 0;
}
WRITE16_MEMBER( md_rom_svp_device::write_pm1 )
{
UINT32 r = pm_io(1, 1, data);
if (r != (UINT32)-1)
return;
logerror("svp: PM1 acces in non PM mode?\n");
}
READ16_MEMBER( md_rom_svp_device::read_pm2 )
{
UINT32 r = pm_io(2, 0, 0);
if (r != (UINT32)-1)
return r;
logerror("svp: PM2 acces in non PM mode?\n");
return 0;
}
WRITE16_MEMBER( md_rom_svp_device::write_pm2 )
{
UINT32 r = pm_io(2, 1, data);
if (r != (UINT32)-1)
return;
logerror("svp: PM2 acces in non PM mode?\n");
}
READ16_MEMBER( md_rom_svp_device::read_xst )
{
UINT32 d = pm_io(3, 0, 0);
if (d != (UINT32)-1)
return d;
return m_xst;
}
WRITE16_MEMBER( md_rom_svp_device::write_xst )
{
UINT32 r = pm_io(3, 1, data);
if (r != (UINT32)-1)
return;
m_xst2 |= 1;
m_xst = data;
}
READ16_MEMBER( md_rom_svp_device::read_pm4 )
{
return pm_io(4, 0, 0);
}
WRITE16_MEMBER( md_rom_svp_device::write_pm4 )
{
pm_io(4, 1, data);
}
READ16_MEMBER( md_rom_svp_device::read_pmc )
{
if (m_emu_status & SSP_PMC_HAVE_ADDR)
{
m_emu_status |= SSP_PMC_SET;
m_emu_status &= ~SSP_PMC_HAVE_ADDR;
return ((m_pmc.w.l << 4) & 0xfff0) | ((m_pmc.w.l >> 4) & 0xf);
}
else
{
m_emu_status |= SSP_PMC_HAVE_ADDR;
return m_pmc.w.l;
}
}
WRITE16_MEMBER( md_rom_svp_device::write_pmc )
{
if (m_emu_status & SSP_PMC_HAVE_ADDR)
{
m_emu_status |= SSP_PMC_SET;
m_emu_status &= ~SSP_PMC_HAVE_ADDR;
m_pmc.w.h = data;
}
else
{
m_emu_status |= SSP_PMC_HAVE_ADDR;
m_pmc.w.l = data;
}
}
READ16_MEMBER( md_rom_svp_device::read_al )
{
m_emu_status &= ~(SSP_PMC_SET | SSP_PMC_HAVE_ADDR);
return 0;
}
WRITE16_MEMBER( md_rom_svp_device::write_al )
{
}
READ16_MEMBER( md_rom_svp_device::rom_read1 )
{
UINT16 *IRAM = (UINT16 *)m_iram;
return IRAM[offset];
}
READ16_MEMBER( md_rom_svp_device::rom_read2 )
{
return m_rom[offset + 0x800/2];
}
static INPUT_PORTS_START( md_svp )
PORT_START("MEMORY_TEST") /* special memtest mode */
PORT_DIPNAME( 0x01, 0x00, DEF_STR( Test ) )
PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
PORT_DIPSETTING( 0x01, DEF_STR( On ) )
INPUT_PORTS_END
//-------------------------------------------------
// ADDRESS_MAP( svp_ssp_map )
//-------------------------------------------------
ADDRESS_MAP_START( md_svp_ssp_map, AS_PROGRAM, 16, md_rom_svp_device )
AM_RANGE(0x0000, 0x03ff) AM_READ(rom_read1)
AM_RANGE(0x0400, 0xffff) AM_READ(rom_read2)
// AM_RANGE(0x0000, 0x03ff) AM_ROMBANK("bank3")
// AM_RANGE(0x0400, 0xffff) AM_ROMBANK("bank4")
ADDRESS_MAP_END
//-------------------------------------------------
// ADDRESS_MAP( svp_ext_map )
//-------------------------------------------------
ADDRESS_MAP_START( md_svp_ext_map, AS_IO, 16, md_rom_svp_device )
ADDRESS_MAP_GLOBAL_MASK(0xf)
AM_RANGE(0*2, 0*2+1) AM_READWRITE(read_pm0, write_pm0)
AM_RANGE(1*2, 1*2+1) AM_READWRITE(read_pm1, write_pm1)
AM_RANGE(2*2, 2*2+1) AM_READWRITE(read_pm2, write_pm2)
AM_RANGE(3*2, 3*2+1) AM_READWRITE(read_xst, write_xst)
AM_RANGE(4*2, 4*2+1) AM_READWRITE(read_pm4, write_pm4)
AM_RANGE(6*2, 6*2+1) AM_READWRITE(read_pmc, write_pmc)
AM_RANGE(7*2, 7*2+1) AM_READWRITE(read_al, write_al)
ADDRESS_MAP_END
//-------------------------------------------------
// MACHINE_DRIVER( md_svp )
//-------------------------------------------------
static MACHINE_CONFIG_FRAGMENT( md_svp )
MCFG_CPU_ADD("svp", SSP1601, MASTER_CLOCK_NTSC / 7 * 3) /* ~23 MHz (guessed) */
MCFG_CPU_PROGRAM_MAP(md_svp_ssp_map)
MCFG_CPU_IO_MAP(md_svp_ext_map)
MACHINE_CONFIG_END
//-------------------------------------------------
// machine_config_additions - device-specific
// machine configurations
//-------------------------------------------------
machine_config_constructor md_rom_svp_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( md_svp );
}
ioport_constructor md_rom_svp_device::device_input_ports() const
{
return INPUT_PORTS_NAME( md_svp );
}
void md_rom_svp_device::device_start()
{
memset(m_pmac_read, 0, ARRAY_LENGTH(m_pmac_read));
memset(m_pmac_write, 0, ARRAY_LENGTH(m_pmac_write));
m_pmc.d = 0;
m_pmc.w.l = 0;
m_pmc.w.h = 0;
m_emu_status = 0;
m_xst = 0;
m_xst2 = 0;
/* SVP stuff */
m_dram = auto_alloc_array(machine(), UINT8, 0x20000);
m_iram = auto_alloc_array(machine(), UINT8, 0x800);
}
READ16_MEMBER(md_rom_svp_device::read)
{
UINT16 *DRAM = (UINT16 *)m_dram;
if (offset >= 0x300000/2 && offset < 0x320000/2)
{
return DRAM[offset - 0x300000/2];
}
else if (offset >= 0x390000/2 && offset < 0x3a0000/2)
{
// this is rewritten 68k test code
UINT32 a1 = offset - 0x390000/2;
a1 = (a1 & 0x7001) | ((a1 & 0x3e) << 6) | ((a1 & 0xfc0) >> 5);
return DRAM[a1];
}
else if (offset >= 0x3a0000/2 && offset < 0x3b0000/2)
{
// this is rewritten 68k test code
UINT32 a1 = offset - 0x3a0000/2;
a1 = (a1 & 0x7801) | ((a1 & 0x1e) << 6) | ((a1 & 0x7e0) >> 4);
return DRAM[a1];
}
if (offset < 0x200000/2)
return m_rom[offset];
else
{
printf("read out of bound\n");
return 0xffff;
}
}
WRITE16_MEMBER(md_rom_svp_device::write)
{
if (offset >= 0x300000/2 && offset < 0x320000/2)
{
UINT32 a1 = offset - 0x300000/2;
UINT16 *DRAM = (UINT16 *)m_dram;
DRAM[a1] = data;
}
}
READ16_MEMBER(md_rom_svp_device::read_a15)
{
UINT32 d;
switch (offset)
{
// 0xa15000, 0xa15002
case 0:
case 1: return m_xst;
// 0xa15004
case 2: d = m_xst2; m_xst2 &= ~1; return d;
default: logerror("unhandled SVP reg read @ %x\n", offset << 1);
}
return 0;
}
WRITE16_MEMBER(md_rom_svp_device::write_a15)
{
switch (offset)
{
// 0xa15000, 0xa15002
case 0:
case 1: m_xst = data; m_xst2 |= 2; break;
// 0xa15006
case 3: break; // possibly halts SSP1601
default: logerror("unhandled SVP reg write %04x @ %x\n", data, offset << 1);
}
}

71
src/mess/machine/md_svp.h Normal file
View File

@ -0,0 +1,71 @@
#ifndef __MD_SVP_H
#define __MD_SVP_H
#include "machine/md_slot.h"
#include "cpu/ssp1601/ssp1601.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> md_rom_svp_device
class md_rom_svp_device : public device_t,
public device_md_cart_interface
{
public:
// construction/destruction
md_rom_svp_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
md_rom_svp_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
//protected:
// device-level overrides
virtual void device_start();
virtual void device_config_complete() { m_shortname = "md_rom_svp"; }
virtual machine_config_constructor device_mconfig_additions() const;
virtual ioport_constructor device_input_ports() const;
required_device<device_t> m_svp;
required_ioport m_test_ipt;
// reading and writing
virtual DECLARE_READ16_MEMBER(read);
virtual DECLARE_WRITE16_MEMBER(write);
virtual DECLARE_READ16_MEMBER(read_a15);
virtual DECLARE_WRITE16_MEMBER(write_a15);
virtual DECLARE_READ16_MEMBER(rom_read1);
virtual DECLARE_READ16_MEMBER(rom_read2);
virtual DECLARE_READ16_MEMBER(read_pm0);
virtual DECLARE_READ16_MEMBER(read_pm1);
virtual DECLARE_READ16_MEMBER(read_pm2);
virtual DECLARE_READ16_MEMBER(read_pm4);
virtual DECLARE_READ16_MEMBER(read_xst);
virtual DECLARE_READ16_MEMBER(read_pmc);
virtual DECLARE_READ16_MEMBER(read_al);
virtual DECLARE_WRITE16_MEMBER(write_pm0);
virtual DECLARE_WRITE16_MEMBER(write_pm1);
virtual DECLARE_WRITE16_MEMBER(write_pm2);
virtual DECLARE_WRITE16_MEMBER(write_pm4);
virtual DECLARE_WRITE16_MEMBER(write_xst);
virtual DECLARE_WRITE16_MEMBER(write_pmc);
virtual DECLARE_WRITE16_MEMBER(write_al);
UINT32 pm_io(int reg, int write, UINT32 d);
UINT8 *m_iram; // IRAM (0-0x7ff)
UINT8 *m_dram; // [0x20000];
UINT32 m_pmac_read[6]; // read modes/addrs for PM0-PM5
UINT32 m_pmac_write[6]; // write ...
PAIR m_pmc;
UINT32 m_emu_status;
UINT16 m_xst; // external status, mapped at a15000 and a15002 on 68k side.
UINT16 m_xst2; // status of XST (bit1 set when 68k writes to XST)
};
// device type definition
extern const device_type MD_ROM_SVP;
#endif

View File

@ -1629,6 +1629,7 @@ $(MESSOBJ)/sega.a: \
$(MESS_MACHINE)/md_eeprom.o \
$(MESS_MACHINE)/md_jcart.o \
$(MESS_MACHINE)/md_stm95.o \
$(MESS_MACHINE)/md_svp.o \
$(MESS_MACHINE)/megasvp.o \
$(MESS_DRIVERS)/megadriv.o \
$(MESS_DRIVERS)/dccons.o \