mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
(MESS) snes: added skeleton SA-1 support. nw.
This commit is contained in:
parent
af0b9c5bf5
commit
5d05f2ff14
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -7755,6 +7755,8 @@ src/mess/machine/sns_rom.c svneol=native#text/plain
|
||||
src/mess/machine/sns_rom.h svneol=native#text/plain
|
||||
src/mess/machine/sns_rom21.c svneol=native#text/plain
|
||||
src/mess/machine/sns_rom21.h svneol=native#text/plain
|
||||
src/mess/machine/sns_sa1.c svneol=native#text/plain
|
||||
src/mess/machine/sns_sa1.h svneol=native#text/plain
|
||||
src/mess/machine/sns_sdd1.c svneol=native#text/plain
|
||||
src/mess/machine/sns_sdd1.h svneol=native#text/plain
|
||||
src/mess/machine/sns_sfx.c svneol=native#text/plain
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "machine/sns_rom.h"
|
||||
#include "machine/sns_rom21.h"
|
||||
#include "machine/sns_bsx.h"
|
||||
#include "machine/sns_sa1.h"
|
||||
#include "machine/sns_sdd1.h"
|
||||
#include "machine/sns_sfx.h"
|
||||
#include "machine/sns_spc7110.h"
|
||||
@ -70,6 +71,10 @@ public:
|
||||
DECLARE_READ8_MEMBER( snessfx_lo_r );
|
||||
DECLARE_WRITE8_MEMBER( snessfx_hi_w );
|
||||
DECLARE_WRITE8_MEMBER( snessfx_lo_w );
|
||||
DECLARE_READ8_MEMBER( snessa1_hi_r );
|
||||
DECLARE_READ8_MEMBER( snessa1_lo_r );
|
||||
DECLARE_WRITE8_MEMBER( snessa1_hi_w );
|
||||
DECLARE_WRITE8_MEMBER( snessa1_lo_w );
|
||||
DECLARE_READ8_MEMBER( snes7110_hi_r );
|
||||
DECLARE_READ8_MEMBER( snes7110_lo_r );
|
||||
DECLARE_WRITE8_MEMBER( snes7110_hi_w );
|
||||
@ -514,6 +519,93 @@ WRITE8_MEMBER( snes_console_state::snessfx_lo_w )
|
||||
snessfx_hi_w(space, offset, data, 0xff);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// LoROM + SA-1
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
READ8_MEMBER( snes_console_state::snessa1_hi_r )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
else if (address < 0x6000)
|
||||
{
|
||||
if (address >= 0x2200 && address < 0x2400)
|
||||
return m_cartslot->chip_read(space, offset); // SA-1 Regs
|
||||
else if (address >= 0x3000 && address < 0x3800)
|
||||
return m_cartslot->chip_read(space, offset); // Internal SA-1 RAM (2K)
|
||||
else
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
else if (address < 0x8000)
|
||||
return m_cartslot->chip_read(space, offset); // SA-1 BWRAM
|
||||
else
|
||||
return m_cartslot->read_h(space, offset);
|
||||
}
|
||||
else
|
||||
return m_cartslot->read_h(space, offset);
|
||||
}
|
||||
|
||||
READ8_MEMBER( snes_console_state::snessa1_lo_r )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
return space.read_byte(0x7e0000 + address);
|
||||
else if (address < 0x6000)
|
||||
{
|
||||
if (address >= 0x2200 && address < 0x2400)
|
||||
return m_cartslot->chip_read(space, offset); // SA-1 Regs
|
||||
else if (address >= 0x3000 && address < 0x3800)
|
||||
return m_cartslot->chip_read(space, offset); // Internal SA-1 RAM (2K)
|
||||
else
|
||||
return snes_r_io(space, address);
|
||||
}
|
||||
else if (address < 0x8000)
|
||||
return m_cartslot->chip_read(space, offset); // SA-1 BWRAM
|
||||
else
|
||||
return m_cartslot->read_l(space, offset);
|
||||
}
|
||||
else if (offset < 0x500000)
|
||||
return m_cartslot->chip_read(space, offset); // SA-1 BWRAM (not mirrored above!)
|
||||
else
|
||||
return snes_r_io(space, address); // nothing mapped here!
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( snes_console_state::snessa1_hi_w )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x2000)
|
||||
space.write_byte(0x7e0000 + address, data);
|
||||
else if (address < 0x6000)
|
||||
{
|
||||
if (address >= 0x2200 && address < 0x2400)
|
||||
m_cartslot->chip_write(space, offset, data); // SA-1 Regs
|
||||
else if (address >= 0x3000 && address < 0x3800)
|
||||
m_cartslot->chip_write(space, offset, data); // Internal SA-1 RAM (2K)
|
||||
else
|
||||
snes_w_io(space, address, data);
|
||||
}
|
||||
else if (address < 0x8000)
|
||||
m_cartslot->chip_write(space, offset, data); // SA-1 BWRAM
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( snes_console_state::snessa1_lo_w )
|
||||
{
|
||||
if (offset >= 0x400000 && offset < 0x500000)
|
||||
m_cartslot->chip_write(space, offset, data); // SA-1 BWRAM (not mirrored above!)
|
||||
else
|
||||
snessfx_hi_w(space, offset, data, 0xff);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// HiROM + SPC-7110
|
||||
//---------------------------------------------------------------------------------
|
||||
@ -1484,7 +1576,7 @@ static SLOT_INTERFACE_START(snes_cart)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_dsp", SNS_LOROM_NECDSP)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_dsp4", SNS_LOROM_NECDSP)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_obc1", SNS_LOROM_OBC1)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sa1", SNS_LOROM) // Cart + SA1 - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sa1", SNS_LOROM_SA1) // Cart + SA1 - unsupported
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sdd1", SNS_LOROM_SDD1)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sfx", SNS_LOROM_SUPERFX)
|
||||
SLOT_INTERFACE_INTERNAL("lorom_sgb", SNS_LOROM) // SuperGB base cart - unsupported
|
||||
@ -1535,10 +1627,14 @@ void snes_console_state::machine_start()
|
||||
case SNES_CX4: // this still uses the old simulation instead of emulating the CPU
|
||||
case SNES_ST010: // this requires two diff kinds of chip access, so we handle it in snes20_lo/hi_r/w
|
||||
case SNES_ST011: // this requires two diff kinds of chip access, so we handle it in snes20_lo/hi_r/w
|
||||
case SNES_SA1: // still unemulated
|
||||
case SNES_ST018: // still unemulated
|
||||
case SNES_Z80GB: // still unemulated
|
||||
break;
|
||||
case SNES_SA1: // skeleton support
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x000000, 0x7dffff, read8_delegate(FUNC(snes_console_state::snessa1_lo_r),this), write8_delegate(FUNC(snes_console_state::snessa1_lo_w),this));
|
||||
m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x800000, 0xffffff, read8_delegate(FUNC(snes_console_state::snessa1_hi_r),this), write8_delegate(FUNC(snes_console_state::snessa1_hi_w),this));
|
||||
set_5a22_map(m_maincpu);
|
||||
break;
|
||||
case SNES_DSP:
|
||||
m_maincpu->space(AS_PROGRAM).install_read_handler(0x208000, 0x20ffff, 0, 0x9f0000, read8_delegate(FUNC(base_sns_cart_slot_device::chip_read),(base_sns_cart_slot_device*)m_cartslot));
|
||||
m_maincpu->space(AS_PROGRAM).install_write_handler(0x208000, 0x20ffff, 0, 0x9f0000, write8_delegate(FUNC(base_sns_cart_slot_device::chip_write),(base_sns_cart_slot_device*)m_cartslot));
|
||||
|
628
src/mess/machine/sns_sa1.c
Normal file
628
src/mess/machine/sns_sa1.c
Normal file
@ -0,0 +1,628 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
SA-1 add-on chip emulation (for SNES/SFC)
|
||||
|
||||
Copyright MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
Note:
|
||||
- SA-1 register description below is based on no$cash docs.
|
||||
- about bankswitch handling: no matter what is ROM size, at loading the ROM is mirrored up to 8MB and a
|
||||
rom_bank_map[0x100] array is built as a lookup table for 256x32KB banks filling the 8MB accessible ROM
|
||||
area; this allows to handle any 0-7 value written to CXB/DXB/EXB/FXB SA-1 registers without any masking!
|
||||
- about BWRAM "bitmap mode": in 2bits mode
|
||||
600000h.Bit0-1 mirrors to 400000h.Bit0-1
|
||||
600001h.Bit0-1 mirrors to 400000h.Bit2-3
|
||||
600002h.Bit0-1 mirrors to 400000h.Bit4-5
|
||||
600003h.Bit0-1 mirrors to 400000h.Bit6-7
|
||||
...
|
||||
in 4bits mode
|
||||
600000h.Bit0-3 mirrors to 400000h.Bit0-3
|
||||
600001h.Bit0-3 mirrors to 400000h.Bit4-7
|
||||
600002h.Bit0-3 mirrors to 400001h.Bit0-3
|
||||
600003h.Bit0-3 mirrors to 400001h.Bit4-7
|
||||
...
|
||||
to handle the separate modes, bitmap accesses go to offset + 0x100000
|
||||
|
||||
TODO:
|
||||
- test case for BWRAM & IRAM write protect (bsnes does not seem to ever protect either, so it's not implemented
|
||||
for the moment)
|
||||
- almost everything CPU related!
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/sns_sa1.h"
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type SNS_LOROM_SA1 = &device_creator<sns_sa1_device>;
|
||||
|
||||
|
||||
sns_sa1_device::sns_sa1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SNS_LOROM_SA1, "SNES Cart + SA-1", tag, owner, clock, "sns_rom_sa1", __FILE__),
|
||||
device_sns_cart_interface( mconfig, *this ),
|
||||
m_sa1(*this, "sa1cpu")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void sns_sa1_device::device_start()
|
||||
{
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------
|
||||
RAM / SRAM / Registers
|
||||
-------------------------------------------------*/
|
||||
|
||||
UINT8 sns_sa1_device::read_regs(UINT32 offset)
|
||||
{
|
||||
UINT8 value = 0xff;
|
||||
offset &= 0x1ff; // $2200 + offset gives the reg value to compare with docs
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x100:
|
||||
// SNES SFR SNES CPU Flag Read (R)
|
||||
break;
|
||||
case 0x101:
|
||||
// SA-1 CFR SA-1 CPU Flag Read (R)
|
||||
break;
|
||||
case 0x102:
|
||||
// SA-1 HCR H-Count Read Lsb / Do Latching (R)
|
||||
break;
|
||||
case 0x103:
|
||||
// SA-1 HCR H-Count Read Msb (R)
|
||||
break;
|
||||
case 0x104:
|
||||
// SA-1 VCR V-Count Read Lsb (R)
|
||||
break;
|
||||
case 0x105:
|
||||
// SA-1 VCR V-Count Read Msb (R)
|
||||
break;
|
||||
case 0x106:
|
||||
// SA-1 MR Arithmetic Result, bit0-7 (Sum/Product/Quotient) (R)
|
||||
break;
|
||||
case 0x107:
|
||||
// SA-1 MR Arithmetic Result, bit8-15 (Sum/Product/Quotient) (R)
|
||||
break;
|
||||
case 0x108:
|
||||
// SA-1 MR Arithmetic Result, bit16-23 (Sum/Product/Remainder) (R)
|
||||
break;
|
||||
case 0x109:
|
||||
// SA-1 MR Arithmetic Result, bit24-31 (Sum/Product/Remainder) (R)
|
||||
break;
|
||||
case 0x10a:
|
||||
// SA-1 MR Arithmetic Result, bit32-39 (Sum) (R)
|
||||
break;
|
||||
case 0x10b:
|
||||
// SA-1 OF Arithmetic Overflow Flag (R)
|
||||
break;
|
||||
case 0x10c:
|
||||
// SA-1 VDP Variable-Length Data Read Port Lsb (R)
|
||||
break;
|
||||
case 0x10d:
|
||||
// SA-1 VDP Variable-Length Data Read Port Msb (R)
|
||||
break;
|
||||
case 0x10e:
|
||||
// SNES VC Version Code Register (R)
|
||||
break;
|
||||
default:
|
||||
logerror("SA-1 Read access to an unmapped reg (%x)", offset);
|
||||
break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void sns_sa1_device::write_regs(UINT32 offset, UINT8 data)
|
||||
{
|
||||
offset &= 0x1ff; // $2200 + offset gives the reg value to compare with docs
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x000:
|
||||
// SNES CCNT 20h SA-1 CPU Control (W)
|
||||
break;
|
||||
case 0x001:
|
||||
// SNES SIE 00h SNES CPU Int Enable (W)
|
||||
break;
|
||||
case 0x002:
|
||||
// SNES SIC 00h SNES CPU Int Clear (W)
|
||||
break;
|
||||
case 0x003:
|
||||
// SNES CRV - SA-1 CPU Reset Vector Lsb (W)
|
||||
break;
|
||||
case 0x004:
|
||||
// SNES CRV - SA-1 CPU Reset Vector Msb (W)
|
||||
break;
|
||||
case 0x005:
|
||||
// SNES CNV - SA-1 CPU NMI Vector Lsb (W)
|
||||
break;
|
||||
case 0x006:
|
||||
// SNES CNV - SA-1 CPU NMI Vector Msb (W)
|
||||
break;
|
||||
case 0x007:
|
||||
// SNES CIV - SA-1 CPU IRQ Vector Lsb (W)
|
||||
break;
|
||||
case 0x008:
|
||||
// SNES CIV - SA-1 CPU IRQ Vector Msb (W)
|
||||
break;
|
||||
case 0x009:
|
||||
// SA-1 SCNT 00h SNES CPU Control (W)
|
||||
break;
|
||||
case 0x00a:
|
||||
// SA-1 CIE 00h SA-1 CPU Int Enable (W)
|
||||
break;
|
||||
case 0x00b:
|
||||
// SA-1 CIC 00h SA-1 CPU Int Clear (W)
|
||||
break;
|
||||
case 0x00c:
|
||||
// SA-1 SNV - SNES CPU NMI Vector Lsb (W)
|
||||
break;
|
||||
case 0x00d:
|
||||
// SA-1 SNV - SNES CPU NMI Vector Msb (W)
|
||||
break;
|
||||
case 0x00e:
|
||||
// SA-1 SIV - SNES CPU IRQ Vector Lsb (W)
|
||||
break;
|
||||
case 0x00f:
|
||||
// SA-1 SIV - SNES CPU IRQ Vector Msb (W)
|
||||
break;
|
||||
case 0x010:
|
||||
// SA-1 TMC 00h H/V Timer Control (W)
|
||||
break;
|
||||
case 0x011:
|
||||
// SA-1 CTR - SA-1 CPU Timer Restart (W)
|
||||
break;
|
||||
case 0x012:
|
||||
// SA-1 HCNT - Set H-Count Lsb (W)
|
||||
break;
|
||||
case 0x013:
|
||||
// SA-1 HCNT - Set H-Count Msb (W)
|
||||
break;
|
||||
case 0x014:
|
||||
// SA-1 VCNT - Set V-Count Lsb (W)
|
||||
break;
|
||||
case 0x015:
|
||||
// SA-1 VCNT - Set V-Count Msb (W)
|
||||
break;
|
||||
case 0x020:
|
||||
// ROM 1MB bank for [c0-cf]
|
||||
m_bank_c_hi = BIT(data, 7);
|
||||
m_bank_c_rom = data & 0x07;
|
||||
break;
|
||||
case 0x021:
|
||||
// ROM 1MB bank for [d0-df]
|
||||
m_bank_d_hi = BIT(data, 7);
|
||||
m_bank_d_rom = data & 0x07;
|
||||
break;
|
||||
case 0x022:
|
||||
// ROM 1MB bank for [e0-ef]
|
||||
m_bank_e_hi = BIT(data, 7);
|
||||
m_bank_e_rom = data & 0x07;
|
||||
break;
|
||||
case 0x023:
|
||||
// ROM 1MB bank for [f0-ff]
|
||||
m_bank_f_hi = BIT(data, 7);
|
||||
m_bank_f_rom = data & 0x07;
|
||||
break;
|
||||
case 0x024:
|
||||
// BWRAM bank from SNES side
|
||||
m_bwram_snes = data & 0x1f; // max 32x8K banks
|
||||
break;
|
||||
case 0x025:
|
||||
// BWRAM bank & type from SA-1 side
|
||||
m_bwram_sa1_source = BIT(data, 7); // 0 = normal, 1 = bitmap?
|
||||
m_bwram_sa1 = data & 0x7f; // up to 128x8K banks here?
|
||||
break;
|
||||
case 0x026:
|
||||
// enable writing to BWRAM from SNES
|
||||
m_bwram_write_snes = BIT(data, 7);
|
||||
break;
|
||||
case 0x027:
|
||||
// enable writing to BWRAM from SA-1
|
||||
m_bwram_write_sa1 = BIT(data, 7);
|
||||
break;
|
||||
case 0x028:
|
||||
// write protected area at bottom of BWRAM
|
||||
m_bwpa_sa1 = 0x100 * (data & 0x0f);
|
||||
break;
|
||||
case 0x029:
|
||||
// enable writing to IRAM from SNES (1 bit for each 0x100 chunk)
|
||||
m_iram_write_snes = data;
|
||||
break;
|
||||
case 0x02a:
|
||||
// enable writing to IRAM from SA-1 (1 bit for each 0x100 chunk)
|
||||
m_iram_write_sa1 = data;
|
||||
break;
|
||||
case 0x030:
|
||||
// SA-1 DCNT 00h DMA Control (W)
|
||||
break;
|
||||
case 0x031:
|
||||
// Both CDMA 00h Character Conversion DMA Parameters (W)
|
||||
break;
|
||||
case 0x032:
|
||||
// Both SDA - DMA Source Device Start Address Lsb (W)
|
||||
break;
|
||||
case 0x033:
|
||||
// Both SDA - DMA Source Device Start Address Mid (W)
|
||||
break;
|
||||
case 0x034:
|
||||
// Both SDA - DMA Source Device Start Address Msb (W)
|
||||
break;
|
||||
case 0x035:
|
||||
// Both DDA - DMA Dest Device Start Address Lsb (W)
|
||||
break;
|
||||
case 0x036:
|
||||
// Both DDA - DMA Dest Device Start Address Mid (Start/I-RAM) (W)
|
||||
break;
|
||||
case 0x037:
|
||||
// Both DDA - DMA Dest Device Start Address Msb (Start/BW-RAM)(W)
|
||||
break;
|
||||
case 0x038:
|
||||
// SA-1 DTC - DMA Terminal Counter Lsb (W)
|
||||
break;
|
||||
case 0x039:
|
||||
// SA-1 DTC - DMA Terminal Counter Msb (W)
|
||||
break;
|
||||
case 0x03f:
|
||||
// Format for BWRAM when mapped to bitmap
|
||||
m_bwram_sa1_format = BIT(data, 7); // 0 = 4bit, 1 = 2bit
|
||||
break;
|
||||
case 0x040:
|
||||
case 0x041:
|
||||
case 0x042:
|
||||
case 0x043:
|
||||
case 0x044:
|
||||
case 0x045:
|
||||
case 0x046:
|
||||
case 0x047:
|
||||
case 0x048:
|
||||
case 0x049:
|
||||
case 0x04a:
|
||||
case 0x04b:
|
||||
case 0x04c:
|
||||
case 0x04d:
|
||||
case 0x04e:
|
||||
case 0x04f:
|
||||
// SA-1 BRF - Bit Map Register File (2240h..224Fh) (W)
|
||||
break;
|
||||
case 0x050:
|
||||
// SA-1 MCNT 00h Arithmetic Control (W)
|
||||
break;
|
||||
case 0x051:
|
||||
// SA-1 MA - Arithmetic Param A Lsb (Multiplicand/Dividend) (W)
|
||||
break;
|
||||
case 0x052:
|
||||
// SA-1 MA - Arithmetic Param A Msb (Multiplicand/Dividend) (W)
|
||||
break;
|
||||
case 0x053:
|
||||
// SA-1 MB - Arithmetic Param B Lsb (Multiplier/Divisor) (W)
|
||||
break;
|
||||
case 0x054:
|
||||
// SA-1 MB - Arithmetic Param B Msb (Multiplier/Divisor)/Start (W)
|
||||
break;
|
||||
case 0x058:
|
||||
// SA-1 VBD - Variable-Length Bit Processing (W)
|
||||
break;
|
||||
case 0x059:
|
||||
// SA-1 VDA - Var-Length Bit Game Pak ROM Start Address Lsb (W)
|
||||
break;
|
||||
case 0x05a:
|
||||
// SA-1 VDA - Var-Length Bit Game Pak ROM Start Address Mid (W)
|
||||
break;
|
||||
case 0x05b:
|
||||
// SA-1 VDA - Var-Length Bit Game Pak ROM Start Address Msb & Kick
|
||||
break;
|
||||
default:
|
||||
logerror("SA-1 Write access to an unmapped reg (%x) with data %x", offset, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 sns_sa1_device::read_iram(UINT32 offset)
|
||||
{
|
||||
return m_internal_ram[offset & 0x7ff];
|
||||
}
|
||||
|
||||
void sns_sa1_device::write_iram(UINT32 offset, UINT8 data)
|
||||
{
|
||||
m_internal_ram[offset & 0x7ff] = data;
|
||||
}
|
||||
|
||||
UINT8 sns_sa1_device::read_bwram(UINT32 offset)
|
||||
{
|
||||
int shift = 0;
|
||||
UINT8 mask = 0xff;
|
||||
|
||||
if (!m_nvram)
|
||||
return 0xff; // this should probably never happen, or are there SA-1 games with no BWRAM?
|
||||
|
||||
if (offset < 0x100000)
|
||||
return m_nvram[offset & (m_nvram_size - 1)];
|
||||
|
||||
// Bitmap BWRAM
|
||||
if (m_bwram_sa1_format)
|
||||
{
|
||||
// 2bits mode
|
||||
offset /= 4;
|
||||
shift = ((offset % 4) * 2);
|
||||
mask = 0x03;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4bits mode
|
||||
offset /= 2;
|
||||
shift = ((offset % 2) * 4);
|
||||
mask = 0x0f;
|
||||
}
|
||||
|
||||
// only return the correct bits
|
||||
return (m_nvram[offset & (m_nvram_size - 1)] >> shift) & mask;
|
||||
}
|
||||
|
||||
void sns_sa1_device::write_bwram(UINT32 offset, UINT8 data)
|
||||
{
|
||||
UINT8 mask = 0xff;
|
||||
|
||||
if (!m_nvram)
|
||||
return; // this should probably never happen, or are there SA-1 games with no BWRAM?
|
||||
|
||||
if (offset < 0x100000)
|
||||
{
|
||||
m_nvram[offset & (m_nvram_size - 1)] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
// Bitmap BWRAM
|
||||
if (m_bwram_sa1_format)
|
||||
{
|
||||
// 2bits mode
|
||||
offset /= 4;
|
||||
data = (data & 0x03) << ((offset % 4) * 2);
|
||||
mask = 0x03 << ((offset % 4) * 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 4bits mode
|
||||
offset /= 2;
|
||||
data = (data & 0x0f) << ((offset % 2) * 4);
|
||||
mask = 0x0f << ((offset % 2) * 4);
|
||||
}
|
||||
|
||||
// only change the correct bits, keeping the rest untouched
|
||||
m_nvram[offset & (m_nvram_size - 1)] = (m_nvram[offset & (m_nvram_size - 1)] & ~mask) | data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
Accesses from SNES CPU
|
||||
-------------------------------------------------*/
|
||||
|
||||
|
||||
READ8_MEMBER(sns_sa1_device::read_l)
|
||||
{
|
||||
int bank = 0;
|
||||
|
||||
// ROM is mapped to [00-3f][8000-ffff] only here
|
||||
if (offset < 0x200000)
|
||||
{
|
||||
if (!m_bank_c_hi) // when HiROM mapping is disabled, we always access first 1MB here
|
||||
bank = (offset / 0x10000) + 0x00;
|
||||
else // when HiROM mapping is enabled, we mirror [c0-cf][0000-ffff] bank
|
||||
bank = (offset / 0x10000) + (m_bank_c_rom * 0x20);
|
||||
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else if (offset < 0x400000)
|
||||
{
|
||||
offset -= 0x200000;
|
||||
if (!m_bank_d_hi) // when HiROM mapping is disabled, we always access second 1MB here
|
||||
bank = (offset / 0x10000) + 0x20;
|
||||
else // when HiROM mapping is enabled, we mirror [d0-df][0000-ffff] bank
|
||||
bank = (offset / 0x10000) + (m_bank_d_rom * 0x20);
|
||||
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else
|
||||
return 0; // this should not happen (the driver should only call read_l in the above case)
|
||||
}
|
||||
|
||||
READ8_MEMBER(sns_sa1_device::read_h)
|
||||
{
|
||||
int bank = 0;
|
||||
|
||||
// ROM is mapped to [80-bf][8000-ffff] & [c0-ff][0000-ffff]
|
||||
if (offset < 0x200000)
|
||||
{
|
||||
if (!m_bank_e_hi) // when HiROM mapping is disabled, we always access third 1MB here
|
||||
bank = (offset / 0x10000) + 0x40;
|
||||
else // when HiROM mapping is enabled, we mirror [e0-ef][0000-ffff] bank
|
||||
bank = (offset / 0x10000) + (m_bank_e_rom * 0x20);
|
||||
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else if (offset < 0x400000)
|
||||
{
|
||||
offset -= 0x200000;
|
||||
if (!m_bank_f_hi) // when HiROM mapping is disabled, we always access fourth 1MB here
|
||||
bank = (offset / 0x10000) + 0x60;
|
||||
else // when HiROM mapping is enabled, we mirror [f0-ff][0000-ffff] bank
|
||||
bank = (offset / 0x10000) + (m_bank_f_rom * 0x20);
|
||||
|
||||
return m_rom[rom_bank_map[bank] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
else if (offset < 0x500000)
|
||||
return m_rom[rom_bank_map[(m_bank_c_rom * 0x20) + (offset / 0x8000)] * 0x8000 + (offset & 0x7fff)];
|
||||
else if (offset < 0x600000)
|
||||
return m_rom[rom_bank_map[(m_bank_d_rom * 0x20) + (offset / 0x8000)] * 0x8000 + (offset & 0x7fff)];
|
||||
else if (offset < 0x700000)
|
||||
return m_rom[rom_bank_map[(m_bank_e_rom * 0x20) + (offset / 0x8000)] * 0x8000 + (offset & 0x7fff)];
|
||||
else
|
||||
return m_rom[rom_bank_map[(m_bank_f_rom * 0x20) + (offset / 0x8000)] * 0x8000 + (offset & 0x7fff)];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_sa1_device::write_l)
|
||||
{
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(sns_sa1_device::write_h)
|
||||
{
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_sa1_device::chip_read )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000 && address >= 0x2200 && address < 0x2400)
|
||||
return read_regs(address & 0x1ff); // SA-1 Regs
|
||||
|
||||
if (offset < 0x400000 && address >= 0x3000 && address < 0x3800)
|
||||
return read_iram(address & 0x7ff); // Internal SA-1 RAM (2K)
|
||||
|
||||
if (offset < 0x400000 && address >= 0x6000 && address < 0x8000)
|
||||
return read_bwram((m_bwram_snes * 0x2000) + (offset & 0x1fff)); // SA-1 BWRAM
|
||||
|
||||
if (offset >= 0x400000 && offset < 0x500000)
|
||||
return read_bwram(offset); // SA-1 BWRAM again (but not called for the [c0-cf] range, because it's not mirrored)
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sns_sa1_device::chip_write )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000 && address >= 0x2200 && address < 0x2400)
|
||||
write_regs(address & 0x1ff, data); // SA-1 Regs
|
||||
|
||||
if (offset < 0x400000 && address >= 0x3000 && address < 0x3800)
|
||||
write_iram(address & 0x7ff, data); // Internal SA-1 RAM (2K)
|
||||
|
||||
if (offset < 0x400000 && address >= 0x6000 && address < 0x8000)
|
||||
write_bwram((m_bwram_snes * 0x2000) + (offset & 0x1fff), data); // SA-1 BWRAM
|
||||
|
||||
if (offset >= 0x400000 && offset < 0x500000)
|
||||
write_bwram(offset, data); // SA-1 BWRAM again (but not called for the [c0-cf] range, because it's not mirrored)
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
Accesses from SA-1 CPU
|
||||
-------------------------------------------------*/
|
||||
|
||||
// These handlers basically match the SNES CPU ones, but there is no access to internal
|
||||
// I/O regs or WRAM, and there are a few additional accesses to IRAM (in [00-3f][0000-07ff])
|
||||
// and to BWRAM (in [60-6f][0000-ffff], so-called bitmap mode)
|
||||
|
||||
READ8_MEMBER( sns_sa1_device::sa1_hi_r )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x6000)
|
||||
{
|
||||
if (address < 0x0800)
|
||||
return read_iram(offset); // Internal SA-1 RAM (2K)
|
||||
else if (address >= 0x2200 && address < 0x2400)
|
||||
return read_regs(offset & 0x1ff); // SA-1 Regs
|
||||
else if (address >= 0x3000 && address < 0x3800)
|
||||
return read_iram(offset); // Internal SA-1 RAM (2K)
|
||||
}
|
||||
else if (address < 0x8000)
|
||||
return read_bwram((m_bwram_sa1 * 0x2000) + (offset & 0x1fff) + (m_bwram_sa1_source * 0x100000)); // SA-1 BWRAM
|
||||
else
|
||||
return read_h(space, offset); // ROM
|
||||
|
||||
return 0xff; // maybe open bus? same as the main system one or diff? (currently not accessible from carts anyway...)
|
||||
}
|
||||
else
|
||||
return read_h(space, offset); // ROM
|
||||
}
|
||||
|
||||
READ8_MEMBER( sns_sa1_device::sa1_lo_r )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x6000)
|
||||
{
|
||||
if (address < 0x0800)
|
||||
return read_iram(offset); // Internal SA-1 RAM (2K)
|
||||
else if (address >= 0x2200 && address < 0x2400)
|
||||
return read_regs(offset & 0x1ff); // SA-1 Regs
|
||||
else if (address >= 0x3000 && address < 0x3800)
|
||||
return read_iram(offset); // Internal SA-1 RAM (2K)
|
||||
}
|
||||
else if (address < 0x8000)
|
||||
return read_bwram((m_bwram_sa1 * 0x2000) + (offset & 0x1fff) + (m_bwram_sa1_source * 0x100000)); // SA-1 BWRAM
|
||||
else
|
||||
return read_l(space, offset); // ROM
|
||||
|
||||
return 0xff; // maybe open bus? same as the main system one or diff? (currently not accessible from carts anyway...)
|
||||
}
|
||||
else if (offset < 0x500000)
|
||||
return read_bwram(offset); // SA-1 BWRAM (not mirrored above!)
|
||||
else if (offset >= 0x600000 && offset < 0x700000)
|
||||
return read_bwram((offset & 0xfffff) + 0x100000); // SA-1 BWRAM Bitmap mode
|
||||
else
|
||||
return 0xff; // nothing should be mapped here, so maybe open bus?
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_sa1_device::sa1_hi_w )
|
||||
{
|
||||
UINT16 address = offset & 0xffff;
|
||||
if (offset < 0x400000)
|
||||
{
|
||||
if (address < 0x6000)
|
||||
{
|
||||
if (address < 0x0800)
|
||||
write_iram(offset, data); // Internal SA-1 RAM (2K)
|
||||
else if (address >= 0x2200 && address < 0x2400)
|
||||
write_regs(offset & 0x1ff, data); // SA-1 Regs
|
||||
else if (address >= 0x3000 && address < 0x3800)
|
||||
write_iram(offset, data); // Internal SA-1 RAM (2K)
|
||||
}
|
||||
else if (address < 0x8000)
|
||||
write_bwram((m_bwram_sa1 * 0x2000) + (offset & 0x1fff) + (m_bwram_sa1_source * 0x100000), data); // SA-1 BWRAM
|
||||
}
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( sns_sa1_device::sa1_lo_w )
|
||||
{
|
||||
if (offset >= 0x400000 && offset < 0x500000)
|
||||
write_bwram(offset & 0xfffff, data); // SA-1 BWRAM (not mirrored above!)
|
||||
else if (offset >= 0x600000 && offset < 0x700000)
|
||||
write_bwram((offset & 0xfffff) + 0x100000, data); // SA-1 BWRAM Bitmap mode
|
||||
else
|
||||
sa1_hi_w(space, offset, data);
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( sa1_map, AS_PROGRAM, 8, sns_sa1_device )
|
||||
AM_RANGE(0x000000, 0x7dffff) AM_READWRITE(sa1_lo_r, sa1_lo_w)
|
||||
AM_RANGE(0x7e0000, 0x7fffff) AM_NOP
|
||||
AM_RANGE(0x800000, 0xffffff) AM_READWRITE(sa1_hi_r, sa1_hi_w)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( snes_sa1 )
|
||||
MCFG_CPU_ADD("sa1cpu", _5A22, 10000000)
|
||||
MCFG_CPU_PROGRAM_MAP(sa1_map)
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
machine_config_constructor sns_sa1_device::device_mconfig_additions() const
|
||||
{
|
||||
return MACHINE_CONFIG_NAME( snes_sa1 );
|
||||
}
|
70
src/mess/machine/sns_sa1.h
Normal file
70
src/mess/machine/sns_sa1.h
Normal file
@ -0,0 +1,70 @@
|
||||
#ifndef __SNS_SA1_H
|
||||
#define __SNS_SA1_H
|
||||
|
||||
#include "machine/sns_slot.h"
|
||||
#include "cpu/g65816/g65816.h"
|
||||
|
||||
|
||||
// ======================> sns_sa1_device
|
||||
|
||||
class sns_sa1_device : public device_t,
|
||||
public device_sns_cart_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
sns_sa1_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual machine_config_constructor device_mconfig_additions() const;
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_l);
|
||||
virtual DECLARE_READ8_MEMBER(read_h);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_l);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_h);
|
||||
|
||||
// additional reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(chip_read);
|
||||
virtual DECLARE_WRITE8_MEMBER(chip_write);
|
||||
|
||||
DECLARE_READ8_MEMBER(sa1_lo_r);
|
||||
DECLARE_READ8_MEMBER(sa1_hi_r);
|
||||
DECLARE_WRITE8_MEMBER(sa1_lo_w);
|
||||
DECLARE_WRITE8_MEMBER(sa1_hi_w);
|
||||
|
||||
private:
|
||||
|
||||
UINT8 read_regs(UINT32 offset);
|
||||
UINT8 read_iram(UINT32 offset);
|
||||
UINT8 read_bwram(UINT32 offset);
|
||||
void write_regs(UINT32 offset, UINT8 data);
|
||||
void write_iram(UINT32 offset, UINT8 data);
|
||||
void write_bwram(UINT32 offset, UINT8 data);
|
||||
|
||||
required_device<_5a22_device> m_sa1;
|
||||
|
||||
UINT8 m_internal_ram[0x800];
|
||||
|
||||
// register related
|
||||
// $2220-$2223
|
||||
int m_bank_c_hi, m_bank_c_rom;
|
||||
int m_bank_d_hi, m_bank_d_rom;
|
||||
int m_bank_e_hi, m_bank_e_rom;
|
||||
int m_bank_f_hi, m_bank_f_rom;
|
||||
// $2224-$2225 & $223f
|
||||
UINT8 m_bwram_snes, m_bwram_sa1;
|
||||
int m_bwram_sa1_source, m_bwram_sa1_format;
|
||||
// $2226-$2227
|
||||
int m_bwram_write_snes, m_bwram_write_sa1;
|
||||
// $2228
|
||||
UINT32 m_bwpa_sa1;
|
||||
// $2229-$222a
|
||||
UINT8 m_iram_write_snes, m_iram_write_sa1;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type SNS_LOROM_SA1;
|
||||
|
||||
#endif
|
@ -1677,6 +1677,7 @@ $(MESSOBJ)/nintendo.a: \
|
||||
$(MESS_MACHINE)/sns_rom.o \
|
||||
$(MESS_MACHINE)/sns_rom21.o \
|
||||
$(MESS_MACHINE)/sns_bsx.o \
|
||||
$(MESS_MACHINE)/sns_sa1.o \
|
||||
$(MESS_MACHINE)/sns_sdd1.o \
|
||||
$(MESS_MACHINE)/sns_sfx.o \
|
||||
$(MESS_MACHINE)/sns_spc7110.o \
|
||||
|
Loading…
Reference in New Issue
Block a user