Device-fied PRO-CT0

for protection, aka ALPHA-8921(in Some later 80s alpha denshi PCBs) or SNK-9201
prot_fatfury2.cpp: Convert protection into alpha_8921.cpp device
This commit is contained in:
cam900 2020-09-13 17:45:42 +09:00 committed by Vas Crabb
parent 59ff79f394
commit 612bf6546f
7 changed files with 337 additions and 60 deletions

View File

@ -4535,3 +4535,14 @@ if (MACHINES["SWIM3"]~=null) then
MAME_DIR .. "src/devices/machine/swim3.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/alpha_8921.h,MACHINES["ALPHA_8921"] = true
---------------------------------------------------
if (MACHINES["ALPHA_8921"]~=null) then
files {
MAME_DIR .. "src/devices/machine/alpha_8921.cpp",
MAME_DIR .. "src/devices/machine/alpha_8921.h",
}
end

View File

@ -388,6 +388,7 @@ VIDEOS["VRENDER0"] = true
MACHINES["ACORN_VIDC"] = true
MACHINES["AKIKO"] = true
MACHINES["ALPHA_8921"] = true
--MACHINES["AM2901B"] = true
MACHINES["ARM_IOMD"] = true
MACHINES["AUTOCONFIG"] = true

View File

@ -426,6 +426,7 @@ VIDEOS["BT431"] = true
--------------------------------------------------
MACHINES["AKIKO"] = true
MACHINES["ALPHA_8921"] = true
MACHINES["AM2901B"] = true
MACHINES["AUTOCONFIG"] = true
MACHINES["BUSMOUSE"] = true

View File

@ -11,14 +11,18 @@ DEFINE_DEVICE_TYPE(NG_FATFURY2_PROT, fatfury2_prot_device, "ng_fatfury_prot", "N
fatfury2_prot_device::fatfury2_prot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, NG_FATFURY2_PROT, tag, owner, clock),
m_prot_data(0)
m_pro_ct0(*this, "pro_ct0")
{
}
void fatfury2_prot_device::device_add_mconfig(machine_config &config)
{
ALPHA_8921(config, m_pro_ct0, 0); // PRO-CT0 or SNK-9201
}
void fatfury2_prot_device::device_start()
{
save_item(NAME(m_prot_data));
}
void fatfury2_prot_device::device_reset()
@ -33,69 +37,27 @@ void fatfury2_prot_device::device_reset()
/* 0x2xxxxx range. There are several checks all around the code. */
uint16_t fatfury2_prot_device::protection_r(offs_t offset)
{
uint16_t res = m_prot_data >> 24;
switch (offset)
{
case 0x55550/2:
case 0xffff0/2:
case 0x00000/2:
case 0xff000/2:
case 0x36000/2:
case 0x36008/2:
return res;
case 0x36004/2:
case 0x3600c/2:
return ((res & 0xf0) >> 4) | ((res & 0x0f) << 4);
default:
logerror("unknown protection read at %s, offset %08x\n", machine().describe_context(), offset << 1);
return 0;
}
m_pro_ct0->even_w(BIT(offset, 1));
m_pro_ct0->h_w(BIT(offset, 2));
u8 gad = m_pro_ct0->gad_r();
u8 gbd = m_pro_ct0->gbd_r();
return (BIT(gbd, 0, 2) << 6) | (BIT(gbd, 2, 2) << 4) | (BIT(gad, 0, 2) << 6) | (BIT(gad, 2, 2) << 4);
}
void fatfury2_prot_device::protection_w(offs_t offset, uint16_t data)
{
switch (offset)
{
case 0x11112/2: /* data == 0x1111; expects 0xff000000 back */
m_prot_data = 0xff000000;
break;
// /PORTOEL connected into PRO-CT0 CLK pin
m_pro_ct0->clk_w(true);
case 0x33332/2: /* data == 0x3333; expects 0x0000ffff back */
m_prot_data = 0x0000ffff;
break;
m_pro_ct0->load_w(BIT(offset, 0)); // A1
m_pro_ct0->even_w(BIT(offset, 1)); // A2
m_pro_ct0->h_w(BIT(offset, 2)); // A3
case 0x44442/2: /* data == 0x4444; expects 0x00ff0000 back */
m_prot_data = 0x00ff0000;
break;
// C16-31 = A4-A19, C0-C15 = D0-D15
m_pro_ct0->c_w((u32(bitswap<16>(BIT(offset, 3, 16), 15, 13, 11, 9, 14, 12, 10, 8, 7, 5, 3, 1, 6, 4, 2, 0)) << 16) |
bitswap<16>(data, 15, 13, 11, 9, 14, 12, 10, 8, 7, 5, 3, 1, 6, 4, 2, 0));
case 0x55552/2: /* data == 0x5555; read back from 55550, ffff0, 00000, ff000 */
m_prot_data = 0xff00ff00;
break;
case 0x56782/2: /* data == 0x1234; read back from 36000 *or* 36004 */
m_prot_data = 0xf05a3601;
break;
case 0x42812/2: /* data == 0x1824; read back from 36008 *or* 3600c */
m_prot_data = 0x81422418;
break;
case 0x55550/2:
case 0xffff0/2:
case 0xff000/2:
case 0x36000/2:
case 0x36004/2:
case 0x36008/2:
case 0x3600c/2:
m_prot_data <<= 8;
break;
default:
logerror("unknown protection write at %s, offset %08x, data %02x\n", machine().describe_context(), offset, data);
break;
}
// release /PORTOEL
m_pro_ct0->clk_w(false);
}

View File

@ -6,6 +6,8 @@
#pragma once
#include "machine/alpha_8921.h"
DECLARE_DEVICE_TYPE(NG_FATFURY2_PROT, fatfury2_prot_device)
@ -19,10 +21,12 @@ public:
void protection_w(offs_t offset, uint16_t data);
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override;
virtual void device_reset() override;
uint32_t m_prot_data;
private:
required_device<alpha_8921_device> m_pro_ct0; // PRO-CT0 or SNK-9201
};
#endif // MAME_BUS_NEOGEO_PROT_FATFURY2_H

View File

@ -0,0 +1,213 @@
// license:BSD-3-Clause
// copyright-holders:cam900
/***************************************************************************
Alpha denshi ALPHA-8921 emulation
Also known as
SNK PRO-CT0
SNK-9201
This chip is sprite ROM data serializer, or optional security device.
used in some later 80s Alpha Denshi hardware(ex: Gang Wars),
Some early Neogeo MVS motherboards, AES cartridges.
also integrated in NEO-ZMC2, NEO-CMC.
reference: https://wiki.neogeodev.org/index.php?title=PRO-CT0
***************************************************************************/
#include "emu.h"
#include "alpha_8921.h"
#include <algorithm>
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definition
DEFINE_DEVICE_TYPE(ALPHA_8921, alpha_8921_device, "alpha_8921", "Alpha denshi ALPHA-8921")
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// alpha_8921_device - constructor
//-------------------------------------------------
alpha_8921_device::alpha_8921_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ALPHA_8921, tag, owner, clock)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void alpha_8921_device::device_start()
{
// save states
save_item(NAME(m_clk));
save_item(NAME(m_load));
save_item(NAME(m_even));
save_item(NAME(m_h));
save_item(NAME(m_c));
save_item(NAME(m_gad));
save_item(NAME(m_gbd));
save_item(NAME(m_dota));
save_item(NAME(m_dotb));
save_item(NAME(m_sr));
save_item(NAME(m_old_sr));
save_item(NAME(m_old_even));
save_item(NAME(m_old_h));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void alpha_8921_device::device_reset()
{
// force update outputs
m_old_sr = ~m_sr;
m_old_even = !m_even;
m_old_h = !m_h;
update_output();
}
//**************************************************************************
// READ/WRITE HANDLERS
//**************************************************************************
//-------------------------------------------------
// clk_w - Change clock pin status
//-------------------------------------------------
WRITE_LINE_MEMBER(alpha_8921_device::clk_w)
{
if (m_clk != state)
{
m_clk = state;
if (!m_clk) // falling edge
{
if (m_load)
m_sr = m_c;
else if (m_h)
m_sr = (BIT(m_sr, 24, 6) << 26) | (BIT(m_sr, 16, 6) << 18) | (BIT(m_sr, 8, 6) << 10) | (BIT(m_sr, 0, 6) << 2);
else
m_sr = ((BIT(m_sr, 26, 6)) << 24) | ((BIT(m_sr, 18, 6)) << 16) | ((BIT(m_sr, 10, 6)) << 8) | (BIT(m_sr, 2, 6));
}
}
}
//-------------------------------------------------
// load_w - Change LOAD pin status
//-------------------------------------------------
WRITE_LINE_MEMBER(alpha_8921_device::load_w)
{
m_load = state;
}
//-------------------------------------------------
// even_w - Change EVEN pin status
//-------------------------------------------------
WRITE_LINE_MEMBER(alpha_8921_device::even_w)
{
m_even = state;
}
//-------------------------------------------------
// h_w - Change H pin status
//-------------------------------------------------
WRITE_LINE_MEMBER(alpha_8921_device::h_w)
{
m_h = state;
}
//-------------------------------------------------
// c_w - Change C data
//-------------------------------------------------
void alpha_8921_device::c_w(u32 data)
{
m_c = data;
}
//-------------------------------------------------
// update_output - Update output results
//-------------------------------------------------
void alpha_8921_device::update_output()
{
if ((m_old_sr != m_sr) || (m_old_even != m_even) || (m_old_h != m_h))
{
switch (m_h)
{
case 1:
m_gbd = bitswap<4>(m_sr, 30, 22, 14, 6);
m_gad = bitswap<4>(m_sr, 31, 23, 15, 7);
break;
case 0:
m_gbd = bitswap<4>(m_sr, 25, 17, 9, 1);
m_gad = bitswap<4>(m_sr, 24, 16, 8, 0);
break;
}
if (m_even)
std::swap<u8>(m_gad, m_gbd);
m_dota = m_gad ? true : false;
m_dotb = m_gbd ? true : false;
m_old_sr = m_sr;
m_old_even = m_even;
m_old_h = m_h;
}
}
//-------------------------------------------------
// gad_r - Read GAD data
//-------------------------------------------------
u8 alpha_8921_device::gad_r()
{
update_output();
return m_gad & 0xf;
}
//-------------------------------------------------
// gbd_r - Read GBD data
//-------------------------------------------------
u8 alpha_8921_device::gbd_r()
{
update_output();
return m_gbd & 0xf;
}
//-------------------------------------------------
// dota_r - Read DOTA pin data (GAD isn't 0)
//-------------------------------------------------
READ_LINE_MEMBER(alpha_8921_device::dota_r)
{
update_output();
return m_dota;
}
//-------------------------------------------------
// dotb_r - Read DOTB pin data (GBD isn't 0)
//-------------------------------------------------
READ_LINE_MEMBER(alpha_8921_device::dotb_r)
{
update_output();
return m_dotb;
}

View File

@ -0,0 +1,85 @@
// license:BSD-3-Clause
// copyright-holders:cam900
/***************************************************************************
Alpha denshi ALPHA-8921 emulation
***************************************************************************/
#ifndef MAME_MACHINE_ALPHA_8921_H
#define MAME_MACHINE_ALPHA_8921_H
#pragma once
//**************************************************************************
// INTERFACE CONFIGURATION MACROS
//**************************************************************************
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> alpha_8921_device
class alpha_8921_device : public device_t
{
public:
// construction/destruction
alpha_8921_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// inputs
DECLARE_WRITE_LINE_MEMBER(clk_w);
DECLARE_WRITE_LINE_MEMBER(load_w);
DECLARE_WRITE_LINE_MEMBER(even_w);
DECLARE_WRITE_LINE_MEMBER(h_w);
void c_w(u32 data);
// outputs
u8 gad_r();
u8 gbd_r();
DECLARE_READ_LINE_MEMBER(dota_r);
DECLARE_READ_LINE_MEMBER(dotb_r);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
private:
// inputs
bool m_clk = false; // CLK pin
bool m_load = false; // LOAD pin
bool m_even = false; // EVEN pin
bool m_h = false; // H pin
u32 m_c = 0; // C data (32 bit)
// outputs
u8 m_gad = 0; // GAD data (4 bit)
u8 m_gbd = 0; // GBD data (4 bit)
bool m_dota = false; // DOTA pin
bool m_dotb = false; // DOTB pin
// internal status
u32 m_sr = 0;
u32 m_old_sr = ~0;
bool m_old_even = true;
bool m_old_h = true;
void update_output();
};
// device type definition
DECLARE_DEVICE_TYPE(ALPHA_8921, alpha_8921_device)
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
#endif // MAME_MACHINE_ALPHA_8921_H