Add device emulation of Dallas DS2430A 1-Wire EEPROM

- crazyfgt, lastfght, all games in subsino2.cpp: Hook up DS2430A device, add handcrafted EEPROM data to satisfy serial protection checks and remove ROM patches that forced them to pass
- crazyfgt: Hook up coin counter
- queenbeei, queenbeesa, qbeebing, treamary: Add RTE-to-RTS ROM patches that were missing
- treamary: Change configuration to one that allows booting into title screen rather than getting stuck on initial tests
This commit is contained in:
AJR 2023-04-11 21:26:26 -04:00
parent f2ce9a832c
commit c3c625c8f3
7 changed files with 1094 additions and 222 deletions

View File

@ -1287,6 +1287,18 @@ if (MACHINES["DS2404"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/ds2430a.h,MACHINES["DS2430A"] = true
---------------------------------------------------
if (MACHINES["DS2430A"]~=null) then
files {
MAME_DIR .. "src/devices/machine/ds2430a.cpp",
MAME_DIR .. "src/devices/machine/ds2430a.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/ds6417.h,MACHINES["DS6417"] = true

View File

@ -0,0 +1,685 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Dallas Semiconductor DS2430A 256-Bit 1-Wire EEPROM
The EEPROM is organized as 32 bytes of storage, backed by a
volatile scratchpad of identical size. The EEPROM itself is not
addressible, but may be copied to the scratchpad quickly in its
entirety by the "read memory" command. Copying the scratchpad to
EEPROM is also a bulk operation but of course takes longer.
The other addressable memory type in the DS2430A is a 64-bit
(i.e. 8-byte) "application" register. This can only be programmed
once, at which time two bits in the status register are zeroed
permanently. It is likewise backed by a scratchpad area, which
ceases to be readable once the register has been locked. (This
register seems to be rarely used and is currently not fully
emulated.)
As with most Dallas 1-Wire devices (but not the original DS2430,
which otherwise had the same organization but used a completely
incompatible command set), each DS2430A also contains a factory-
lasered ROM whose contents are an 8-bit device code (14h for this
type), a unique 48-bit serial number and an 8-bit CRC of the
preceding 56 bits.
Unlike most other 1-Wire EEPROMs, the DS2430A memory commands use
an 8-bit rather than 16-bit address for the EEPROM scratchpad and
the application register. The addresses wrap continuously from
1Fh or 07h to 00h for both read and write operations.
DS1971 contains the same chip as DS2430A, but comes in a small
round MicroCan package.
**********************************************************************/
#include "emu.h"
#include "ds2430a.h"
#include <algorithm>
#define LOG_PULSE (1U << 1)
#define LOG_BITS (1U << 2)
#define LOG_STATE (1U << 3)
#define LOG_DATA (1U << 4)
#define LOG_COMMAND (1U << 5)
#define VERBOSE (LOG_PULSE | LOG_BITS | LOG_STATE | LOG_DATA | LOG_COMMAND)
#include "logmacro.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// device type definitions
DEFINE_DEVICE_TYPE(DS2430A, ds2430a_device, "ds2430a", "Dallas DS2430A 1-Wire EEPROM")
DEFINE_DEVICE_TYPE(DS1971, ds1971_device, "ds1971", "Dallas DS1971 EEPROM iButton")
//**************************************************************************
// 1-WIRE PROTOCOL IMPLEMENTATION
//**************************************************************************
// timing constants
static constexpr attoseconds_t tRSTL = 480 * ATTOSECONDS_PER_MICROSECOND; // 480 μs ≤ t < ∞
static constexpr attoseconds_t tRSTH = 480 * ATTOSECONDS_PER_MICROSECOND; // 480 μs ≤ t < ∞
static constexpr attoseconds_t tPDL = 15 * ATTOSECONDS_PER_MICROSECOND; // 15 μs ≤ t < 60 μs
static constexpr attoseconds_t tPDH = 120 * ATTOSECONDS_PER_MICROSECOND; // 60 μs ≤ t < 240 μs
static constexpr attoseconds_t tSLOT = 60 * ATTOSECONDS_PER_MICROSECOND; // 60 μs ≤ t < 120 μs
static constexpr attoseconds_t tREC = 1 * ATTOSECONDS_PER_MICROSECOND; // 1 μs ≤ t < ∞
static constexpr attoseconds_t tLOW0 = 60 * ATTOSECONDS_PER_MICROSECOND; // 60 μs ≤ t < 120 μs
static constexpr attoseconds_t tLOW1 = 15 * ATTOSECONDS_PER_MICROSECOND; // 1 μs ≤ t < 15 μs
static constexpr attoseconds_t tRELEASE = 30 * ATTOSECONDS_PER_MICROSECOND; // 1 μs ≤ t < 45 μs
static constexpr attoseconds_t tCOPY = 10 * ATTOSECONDS_PER_MILLISECOND;
static constexpr attoseconds_t tRDV = 15 * ATTOSECONDS_PER_MICROSECOND;
static constexpr attoseconds_t tSLOT_read = tRDV + tRELEASE + tREC; // timing loops may be tighter for reads than for writes?
static const char *const c_state_desc[] =
{
"presence",
"ROM command",
"ROM read",
"ROM match",
"ROM search bit",
"ROM search /bit",
"ROM search write",
"memory command",
"memory read",
"memory write",
"memory copy",
"done"
};
ALLOW_SAVE_TYPE(ds1wire_device::state)
//-------------------------------------------------
// ds1wire_device - constructor
//-------------------------------------------------
ds1wire_device::ds1wire_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, m_timing_scale(1.0)
, m_slot_timer(nullptr)
, m_data_in(true) // idle state is high
, m_data_out(true)
, m_shift_data(0)
, m_command(0)
, m_bit_count(0)
, m_pulse_start_time(attotime::zero)
, m_current_state(state::DONE)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void ds1wire_device::device_start()
{
m_slot_timer = timer_alloc(FUNC(ds1wire_device::update_state), this);
// save state
save_item(NAME(m_data_in));
save_item(NAME(m_data_out));
save_item(NAME(m_shift_data));
save_item(NAME(m_command));
save_item(NAME(m_bit_count));
save_item(NAME(m_pulse_start_time));
save_item(NAME(m_current_state));
}
//-------------------------------------------------
// data_r - read signal on data line
//-------------------------------------------------
READ_LINE_MEMBER(ds1wire_device::data_r)
{
// Open drain output produces wired-AND signal
return m_data_in && m_data_out;
}
//-------------------------------------------------
// data_w - write bit to data line
//-------------------------------------------------
WRITE_LINE_MEMBER(ds1wire_device::data_w)
{
// Look for transitions
if (m_data_in && !state)
{
m_data_in = false;
pulse_start(machine().time());
}
else if (!m_data_in && state)
{
m_data_in = true;
pulse_end(machine().time());
}
}
//-------------------------------------------------
// set_state - handle internal state changes
//-------------------------------------------------
bool ds1wire_device::set_state(ds1wire_device::state new_state)
{
if (m_current_state != new_state)
{
LOGMASKED(LOG_STATE, "New state: %s\n", c_state_desc[int(new_state)]);
m_current_state = new_state;
m_bit_count = 0;
return true;
}
return false;
}
//-------------------------------------------------
// pulse_start - handle falling edge on data line
//-------------------------------------------------
void ds1wire_device::pulse_start(attotime time)
{
if (m_pulse_start_time <= time)
{
m_pulse_start_time = time;
LOGMASKED(LOG_PULSE, "Pulse started at %s\n", time.to_string());
switch (m_current_state)
{
case state::MEMORY_READ:
case state::ROM_READ:
case state::ROM_SEARCH:
if ((m_bit_count & 7) == 0)
{
if (m_current_state == state::MEMORY_READ)
{
m_shift_data = ds1wire_read_memory(m_command, m_bit_count >> 3);
LOGMASKED(LOG_DATA, "%s: Master Rx byte %d = %02Xh (memory command %02Xh)\n", machine().describe_context(), m_bit_count >> 3, m_shift_data, m_command);
}
else
{
m_shift_data = ds1wire_read_rom(m_bit_count >> 3);
LOGMASKED(LOG_DATA, "%s: Master Rx ROM byte %d = %02Xh\n", machine().describe_context(), m_bit_count >> 3, m_shift_data);
}
}
LOGMASKED(LOG_BITS, "%s: Master Rx bit %d = %d\n", machine().describe_context(), m_bit_count & 7, BIT(m_shift_data, 0));
if (!BIT(m_shift_data, 0))
{
m_data_out = false;
m_slot_timer->adjust(scaled_time(tRELEASE));
}
break;
case state::ROM_MATCH:
if ((m_bit_count & 7) == 0)
m_shift_data = ds1wire_read_rom(m_bit_count >> 3);
break;
case state::ROM_SEARCH_COMPLEMENT:
LOGMASKED(LOG_BITS, "%s: Master Rx /bit %d = %d\n", machine().describe_context(), m_bit_count & 7, !BIT(m_shift_data, 0));
if (BIT(m_shift_data, 0))
{
m_data_out = false;
m_slot_timer->adjust(scaled_time(tRELEASE));
}
break;
case state::MEMORY_COPY:
logerror("Copy interrupted at %s\n", time.to_string());
(void)set_state(state::DONE);
break;
case state::PRESENCE:
case state::ROM_COMMAND:
case state::MEMORY_COMMAND:
case state::MEMORY_WRITE:
case state::ROM_SEARCH_WRITE:
case state::DONE:
// Only compilers care about cases that do nothing
break;
}
}
else
LOGMASKED(LOG_PULSE, "Pulse started too early at %s\n", time.to_string());
}
//-------------------------------------------------
// pulse_end - handle rising edge on data line
//-------------------------------------------------
void ds1wire_device::pulse_end(attotime time)
{
if (m_pulse_start_time < time)
{
// Measure pulse width
attotime pulse_width = time - m_pulse_start_time;
LOGMASKED(LOG_PULSE, "Pulse ended at %s (%d us measured width)\n", time.to_string(), int(pulse_width.as_double() * 1.0E6));
pulse_width = attotime::from_double(pulse_width.as_double() / m_timing_scale);
if (pulse_width >= attotime(0, tRSTL))
{
LOGMASKED(LOG_BITS, "%s: Master reset\n", machine().describe_context());
(void)set_state(state::PRESENCE);
m_slot_timer->adjust(scaled_time(tPDH));
m_pulse_start_time = time + scaled_time(tRSTH);
}
else if (pulse_width < attotime(0, tREC))
LOGMASKED(LOG_PULSE, "Pulse ended too early at %s\n", time.to_string());
else switch (m_current_state)
{
case state::ROM_COMMAND:
case state::MEMORY_COMMAND:
case state::MEMORY_WRITE:
m_shift_data >>= 1;
if (pulse_width < attotime(0, tLOW0))
m_shift_data |= 0x80;
LOGMASKED(LOG_BITS, "%s: Master Tx bit %d = %d\n", machine().describe_context(), m_bit_count & 7, BIT(m_shift_data, 7));
if ((m_bit_count & 7) == 7)
{
if ((m_bit_count >> 3) == 0 && (m_current_state == state::ROM_COMMAND || m_current_state == state::MEMORY_COMMAND))
{
LOGMASKED(LOG_COMMAND, "%s: Master Tx %s command = %02Xh\n", machine().describe_context(), m_current_state == state::ROM_COMMAND ? "ROM" : "memory", m_shift_data);
m_command = m_shift_data;
}
else
LOGMASKED(LOG_DATA, "%s: Master Tx byte %d = %02Xh\n", machine().describe_context(), m_bit_count >> 3, m_shift_data);
state next_state = ds1wire_next_state(m_current_state, m_command, m_bit_count >> 3, m_shift_data);
if (set_state(next_state))
{
if (next_state == state::MEMORY_COPY)
{
m_slot_timer->adjust(scaled_time(tCOPY));
break;
}
}
else
++m_bit_count;
}
else
++m_bit_count;
m_pulse_start_time += scaled_time(tSLOT);
break;
case state::MEMORY_READ:
case state::ROM_READ:
m_shift_data >>= 1;
if ((m_bit_count & 7) != 7 || !set_state(ds1wire_next_state(m_current_state, m_command, m_bit_count >> 3, 0)))
++m_bit_count;
m_pulse_start_time += scaled_time(tSLOT_read);
break;
case state::ROM_SEARCH:
m_current_state = state::ROM_SEARCH_COMPLEMENT;
m_pulse_start_time += scaled_time(tSLOT_read);
break;
case state::ROM_SEARCH_COMPLEMENT:
m_current_state = state::ROM_SEARCH_WRITE;
m_pulse_start_time += scaled_time(tSLOT_read);
break;
case state::ROM_MATCH:
case state::ROM_SEARCH_WRITE:
if ((pulse_width >= attotime(0, tLOW0)) == BIT(m_shift_data, 0))
{
LOGMASKED(LOG_BITS, "%s: Master Tx bit %d not matched; device deselected\n", machine().describe_context(), m_bit_count & 7);
(void)set_state(state::DONE);
}
else
{
LOGMASKED(LOG_BITS, "%s: Master Tx bit %d = %d (matched)\n", machine().describe_context(), m_bit_count & 7, BIT(m_shift_data, 0));
m_shift_data >>= 1;
if ((m_bit_count & 7) != 7 || !set_state(ds1wire_next_state(m_current_state, m_command, m_bit_count >> 3, 0)))
{
++m_bit_count;
if (m_current_state == state::ROM_SEARCH_WRITE)
m_current_state = state::ROM_SEARCH;
}
}
m_pulse_start_time += scaled_time(tSLOT);
break;
case state::PRESENCE:
case state::MEMORY_COPY:
case state::DONE:
// Only compilers care about cases that do nothing
break;
}
}
}
//-------------------------------------------------
// update_state - generate timed responses to bus
// transactions
//-------------------------------------------------
TIMER_CALLBACK_MEMBER(ds1wire_device::update_state)
{
switch (m_current_state)
{
case state::PRESENCE:
m_data_out = !m_data_out;
LOGMASKED(LOG_PULSE, "Presence pulse %sactive\n", m_data_out ? "in" : "");
if (m_data_out)
(void)set_state(state::ROM_COMMAND);
else
m_slot_timer->adjust(scaled_time(tPDL));
break;
case state::MEMORY_READ:
case state::ROM_READ:
case state::ROM_SEARCH:
case state::ROM_SEARCH_COMPLEMENT:
m_data_out = true;
break;
case state::MEMORY_COPY:
ds1wire_memory_copy(m_command);
m_current_state = state::DONE;
break;
case state::ROM_COMMAND:
case state::ROM_MATCH:
case state::MEMORY_COMMAND:
case state::MEMORY_WRITE:
case state::ROM_SEARCH_WRITE:
case state::DONE:
// Only compilers care about cases that do nothing
break;
}
}
//**************************************************************************
// DEVICE EMULATION
//**************************************************************************
//-------------------------------------------------
// ds2430a_device - constructor
//-------------------------------------------------
ds2430a_device::ds2430a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: ds1wire_device(mconfig, type, tag, owner, clock)
, device_nvram_interface(mconfig, *this)
, m_default_data(*this, DEVICE_SELF)
, m_start_address(0)
{
std::fill(std::begin(m_scratchpad), std::end(m_scratchpad), 0);
std::fill(std::begin(m_app_scratchpad), std::end(m_app_scratchpad), 0);
}
ds2430a_device::ds2430a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: ds2430a_device(mconfig, DS2430A, tag, owner, clock)
{
}
//-------------------------------------------------
// ds1971_device - constructor
//-------------------------------------------------
ds1971_device::ds1971_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: ds2430a_device(mconfig, DS1971, tag, owner, clock)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void ds2430a_device::device_start()
{
ds1wire_device::device_start();
save_item(NAME(m_eeprom));
save_item(NAME(m_scratchpad));
save_item(NAME(m_app_scratchpad));
save_item(NAME(m_start_address));
}
//-------------------------------------------------
// nvram_read - called to read NVRAM from the
// specified file
//-------------------------------------------------
bool ds2430a_device::nvram_read(util::read_stream &file)
{
size_t actual;
if (file.read(&m_eeprom[0], 0x20, actual) || actual != 0x20)
return false;
if (file.read(&m_rom[0], 8, actual) || actual != 8)
return false;
if (m_rom[0] != 0x14)
osd_printf_error("Incorrect ROM family code (expected 14h, found %02Xh in saved data)\n", m_rom[0]);
u8 crc = std::accumulate(std::begin(m_rom), std::end(m_rom) - 1, u8(0), &ds1wire_crc);
if (m_rom[7] != crc)
osd_printf_error("Incorrect ROM CRC (expected %02Xh, found %02Xh in saved data)\n", crc, m_rom[7]);
return true;
}
//-------------------------------------------------
// nvram_write - called to write NVRAM to the
// specified file
//-------------------------------------------------
bool ds2430a_device::nvram_write(util::write_stream &file)
{
size_t actual;
if (file.write(&m_eeprom[0], 0x20, actual) || actual != 0x20)
return false;
if (file.write(&m_rom[0], 8, actual) || actual != 8)
return false;
return true;
}
//-------------------------------------------------
// nvram_default - called to initialize NVRAM to
// its default state
//-------------------------------------------------
void ds2430a_device::nvram_default()
{
if (m_default_data.found())
{
std::copy_n(&m_default_data[0], 0x20, &m_eeprom[0]);
std::copy_n(&m_default_data[0x20], 8, &m_rom[0]);
if (m_rom[0] != 0x14)
osd_printf_error("Incorrect ROM family code (expected 14h, found %02Xh in default data)\n", m_rom[0]);
u8 crc = std::accumulate(std::begin(m_rom), std::end(m_rom) - 1, u8(0), &ds1wire_crc);
if (m_rom[7] != crc)
osd_printf_error("Incorrect ROM CRC (expected %02Xh, found %02Xh in default data)\n", crc, m_rom[7]);
}
else
{
// Erase EEPROM to ones
std::fill(std::begin(m_eeprom), std::end(m_eeprom), 0xff);
// Make up a fake ID (shh, nobody alert the authorities)
m_rom[0] = 0x14;
m_rom[1] = 0x11;
m_rom[2] = 0x22;
m_rom[3] = 0x33;
m_rom[4] = 0x44;
m_rom[5] = 0x55;
m_rom[6] = 0x66;
m_rom[7] = std::accumulate(std::begin(m_rom), std::end(m_rom) - 1, u8(0), &ds1wire_crc);
}
}
//-------------------------------------------------
// ds1wire_next_state - handle memory byte writes
// and state changes
//-------------------------------------------------
ds1wire_device::state ds2430a_device::ds1wire_next_state(ds1wire_device::state prev_state, u8 command, u16 index, u8 data)
{
if (prev_state == state::ROM_COMMAND)
{
switch (command)
{
case 0x33: // Read ROM
return state::ROM_READ;
case 0x55: // Match ROM
return state::ROM_MATCH;
case 0xcc: // Skip ROM
return state::MEMORY_COMMAND;
case 0xf0: // Search ROM
return state::ROM_SEARCH;
default:
return state::DONE;
}
}
else if (prev_state == state::ROM_READ && index == 7)
return state::DONE;
else if ((prev_state == state::ROM_MATCH || prev_state == state::ROM_SEARCH_WRITE) && index == 7)
return state::MEMORY_COMMAND;
else if (prev_state == state::MEMORY_COMMAND)
{
switch (command)
{
case 0x0f: // Write Scratchpad
case 0x99: // Write Application Register
if (index == 1)
{
m_start_address = data;
return state::MEMORY_READ;
}
else
return state::MEMORY_COMMAND;
case 0x55: // Copy Scratchpad
case 0x5a: // Copy & Lock Application Register
if (index == 1)
{
// Validation key is A5h
if (data == 0xa5)
return state::MEMORY_COPY;
else
return state::DONE;
}
else
return state::MEMORY_COMMAND;
case 0x66: // Read Status Register
if (index == 1)
{
// Validation key is 00h
if (data == 0x00)
return state::MEMORY_READ;
else
return state::DONE;
}
else
return state::MEMORY_COMMAND;
case 0xf0: // Read Memory
if (index == 0)
std::copy(std::begin(m_eeprom), std::end(m_eeprom), std::begin(m_scratchpad));
[[fallthrough]];
case 0xaa: // Read Scratchpad
case 0xc3: // Read Application Register
if (index == 1)
{
m_start_address = data;
return state::MEMORY_READ;
}
else
return state::MEMORY_COMMAND;
default:
logerror("Unrecognized memory command %02Xh\n", command);
return state::DONE;
}
}
else if (prev_state == state::MEMORY_READ && command == 0x66)
{
// Status register does not wrap around
return state::DONE;
}
else
{
if (prev_state == state::MEMORY_WRITE)
{
if (command == 0x0f)
m_scratchpad[(m_start_address + index) & 0x1f] = data;
else if (command == 0x99)
m_app_scratchpad[(m_start_address + index) & 0x07] = data;
}
return prev_state;
}
}
//-------------------------------------------------
// ds1wire_read_rom - fetch one byte from ROM
//-------------------------------------------------
u8 ds2430a_device::ds1wire_read_rom(u16 index) const
{
assert(index <= 7);
return m_rom[index];
}
//-------------------------------------------------
// ds1wire_read_memory - fetch one byte from the
// selected memory area
//-------------------------------------------------
u8 ds2430a_device::ds1wire_read_memory(u8 command, u16 index) const
{
switch (command)
{
case 0x66: // Read Status Register
return 0xff; // TODO (only low 2 bits may be zero)
case 0xaa: // Read Scratchpad
case 0xf0: // Read Memory
return m_scratchpad[(m_start_address + index) & 0x1f];
case 0xc3: // Read Application Register
return m_app_scratchpad[(m_start_address + index) & 0x07];
default:
return 0xff;
}
}
//-------------------------------------------------
// ds1wire_memory_copy - execute copy command
// after a delay
//-------------------------------------------------
void ds2430a_device::ds1wire_memory_copy(u8 command)
{
if (command == 0x55)
std::copy(std::begin(m_scratchpad), std::end(m_scratchpad), std::begin(m_eeprom));
else if (command == 0x5a)
logerror("Copy scratchpad to application register (not supported)\n");
}

View File

@ -0,0 +1,145 @@
// license:BSD-3-Clause
// copyright-holders:AJR
/**********************************************************************
Dallas Semiconductor DS2430A 256-Bit 1-Wire EEPROM
**********************************************************************/
#ifndef MAME_MACHINE_DS2430A_H
#define MAME_MACHINE_DS2430A_H
#pragma once
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
// ======================> ds1wire_device
class ds1wire_device : public device_t
{
protected:
enum class state : u8
{
PRESENCE = 0,
ROM_COMMAND,
ROM_READ,
ROM_MATCH,
ROM_SEARCH,
ROM_SEARCH_COMPLEMENT,
ROM_SEARCH_WRITE,
MEMORY_COMMAND,
MEMORY_READ,
MEMORY_WRITE,
MEMORY_COPY,
DONE
};
ds1wire_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// Dallas 1-Wire CRC algorithm (use with std::accumulate)
static u8 ds1wire_crc(u8 crc, u8 data) noexcept
{
for (int i = 8; i > 0; --i)
{
crc = (crc >> 1) ^ (BIT(data ^ crc, 0) ? 0x8c : 0);
data >>= 1;
}
return crc;
}
public:
void set_timing_scale(double scale) { m_timing_scale = scale; }
// serial data line handlers
DECLARE_READ_LINE_MEMBER(data_r);
DECLARE_WRITE_LINE_MEMBER(data_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual state ds1wire_next_state(state prev_state, u8 command, u16 index, u8 data) = 0;
virtual u8 ds1wire_read_rom(u16 index) const = 0;
virtual u8 ds1wire_read_memory(u8 command, u16 index) const = 0;
virtual void ds1wire_memory_copy(u8 command) = 0;
private:
// internal helpers
attotime scaled_time(attoseconds_t tconst) const { return attotime(0, tconst * m_timing_scale); }
bool set_state(state new_state);
void pulse_start(attotime time);
void pulse_end(attotime time);
TIMER_CALLBACK_MEMBER(update_state);
// misc. configuration
double m_timing_scale;
// timer object
emu_timer *m_slot_timer;
// line state
bool m_data_in;
bool m_data_out;
// internal state
u8 m_shift_data;
u8 m_command;
u32 m_bit_count;
attotime m_pulse_start_time;
state m_current_state;
};
// ======================> ds2430a_device
class ds2430a_device : public ds1wire_device, public device_nvram_interface
{
public:
// device type constructor
ds2430a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
protected:
ds2430a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device-level overrides
virtual void device_start() override;
// device_nvram_interface overrides
virtual bool nvram_read(util::read_stream &file) override;
virtual bool nvram_write(util::write_stream &file) override;
virtual void nvram_default() override;
// ds1wire_device overrides
virtual state ds1wire_next_state(state prev_state, u8 command, u16 index, u8 data) override;
virtual u8 ds1wire_read_rom(u16 index) const override;
virtual u8 ds1wire_read_memory(u8 command, u16 index) const override;
virtual void ds1wire_memory_copy(u8 command) override;
private:
optional_region_ptr<u8> m_default_data;
u8 m_rom[8];
u8 m_eeprom[0x20];
u8 m_scratchpad[0x20];
u8 m_app_scratchpad[8];
u8 m_start_address;
};
// ======================> ds1971_device
class ds1971_device : public ds2430a_device
{
public:
// device type constructor
ds1971_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
};
// device type declarations
DECLARE_DEVICE_TYPE(DS2430A, ds2430a_device)
DECLARE_DEVICE_TYPE(DS1971, ds1971_device)
#endif // MAME_MACHINE_DS2430A_H

View File

@ -3259,7 +3259,18 @@ void pairlove_state::machine_start()
Crazy Fight
***************************************************************************/
void seta_state::crazyfgt_map(address_map &map)
void crazyfgt_state::coin_counter_w(u8 data)
{
machine().bookkeeping().coin_counter_w(0, BIT(data, 0));
}
void crazyfgt_state::outputs_w(u8 data)
{
// TODO: lower bits also used (for palette banking effect???)
m_eeprom->data_w(!BIT(data, 5));
}
void crazyfgt_state::crazyfgt_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x400000, 0x40ffff).ram();
@ -3267,8 +3278,9 @@ void seta_state::crazyfgt_map(address_map &map)
map(0x610002, 0x610003).portr("UNK");
map(0x610004, 0x610005).portr("INPUT");
map(0x610006, 0x610007).nopw();
map(0x620000, 0x620003).nopw(); // protection
map(0x630000, 0x630003).r(FUNC(seta_state::seta_dsw_r));
map(0x620001, 0x620001).w(FUNC(crazyfgt_state::coin_counter_w));
map(0x620003, 0x620003).w(FUNC(crazyfgt_state::outputs_w));
map(0x630000, 0x630003).r(FUNC(crazyfgt_state::seta_dsw_r));
map(0x640400, 0x640fff).writeonly().share("paletteram1"); // Palette
map(0x650000, 0x650003).w("ymsnd", FUNC(ym3812_device::write)).umask16(0x00ff);
map(0x658001, 0x658001).w("oki", FUNC(okim6295_device::write));
@ -7126,7 +7138,7 @@ static INPUT_PORTS_START( crazyfgt )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_CUSTOM ) // protection
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r)
PORT_START("UNK") //? - $610002.w
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -9833,15 +9845,17 @@ void pairlove_state::pairlove(machine_config &config)
Crazy Fight
***************************************************************************/
void seta_state::crazyfgt(machine_config &config)
void crazyfgt_state::crazyfgt(machine_config &config)
{
/* basic machine hardware */
M68000(config, m_maincpu, 16_MHz_XTAL);
m_maincpu->set_addrmap(AS_PROGRAM, &seta_state::crazyfgt_map);
m_maincpu->set_vblank_int("screen", FUNC(seta_state::irq1_line_hold));
m_maincpu->set_addrmap(AS_PROGRAM, &crazyfgt_state::crazyfgt_map);
m_maincpu->set_vblank_int("screen", FUNC(crazyfgt_state::irq1_line_hold));
DS2430A(config, m_eeprom);
X1_001(config, m_spritegen, 16_MHz_XTAL, m_palette, gfx_sprites);
m_spritegen->set_gfxbank_callback(FUNC(seta_state::setac_gfxbank_callback));
m_spritegen->set_gfxbank_callback(FUNC(crazyfgt_state::setac_gfxbank_callback));
// position kludges
m_spritegen->set_fg_xoffsets(0, 0); // wrong (empty background column in title screen, but aligned sprites in screen select)
m_spritegen->set_fg_yoffsets(-0x12, 0x0e);
@ -9853,14 +9867,14 @@ void seta_state::crazyfgt(machine_config &config)
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
screen.set_size(64*8, 32*8);
screen.set_visarea(0*8, 48*8-1, 2*8, 30*8-1);
screen.set_screen_update(FUNC(seta_state::screen_update_seta));
screen.set_screen_update(FUNC(crazyfgt_state::screen_update_seta));
screen.set_palette(m_palette);
X1_012(config, m_layers[0], m_palette, gfx_blandia_layer1).set_xoffsets(0, -2);
m_layers[0]->set_screen(m_screen);
X1_012(config, m_layers[1], m_palette, gfx_blandia_layer2).set_xoffsets(0, -2);
m_layers[1]->set_screen(m_screen);
PALETTE(config, m_palette, FUNC(seta_state::gundhara_palette), 16*32 + 64*32*4, 0x600); // sprites, layer2, layer1 - layers are 6 planes deep (seta_state,but have only 4 palettes)
PALETTE(config, m_palette, FUNC(crazyfgt_state::gundhara_palette), 16*32 + 64*32*4, 0x600); // sprites, layer2, layer1 - layers are 6 planes deep (seta_state,but have only 4 palettes)
/* sound hardware */
SPEAKER(config, "mono").front_center();
@ -11877,6 +11891,9 @@ ROM_START( crazyfgt )
ROM_REGION( 0x40000, "oki", 0 ) /* OKI samples */
ROM_LOAD( "rom.u85", 0x00000, 0x40000, CRC(7b95d0bb) SHA1(f16dfd639eed6856e3ab93704caef592a07ba367) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(3b5ea5d2) SHA1(bbaad9a879834d1510f20321b97de558d9759ec7) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
ROM_START( jockeyc )
@ -12396,16 +12413,6 @@ void seta_state::init_wiggie()
}
}
void seta_state::init_crazyfgt()
{
u16 *RAM = (u16 *) memregion("maincpu")->base();
// protection check at boot
RAM[0x1078/2] = 0x4e71;
// fixed priorities?
}
void jockeyc_state::init_inttoote()
{
// code patches due to unemulated protection (to be removed...)
@ -12540,4 +12547,4 @@ GAME( 1995, zombraid, 0, zombraid, zombraid, zombraid_state, init_zomb
GAME( 1995, zombraidp, zombraid, zombraid, zombraid, zombraid_state, init_zombraid, ROT0, "American Sammy", "Zombie Raid (9/28/95, US, prototype PCB)", MACHINE_NO_COCKTAIL ) // actual code is same as the released version
GAME( 1995, zombraidpj,zombraid, zombraid, zombraid, zombraid_state, init_zombraid, ROT0, "Sammy Industries Co.,Ltd.", "Zombie Raid (9/28/95, Japan, prototype PCB)", MACHINE_NO_COCKTAIL ) // just 3 bytes different from above
GAME( 1996, crazyfgt, 0, crazyfgt, crazyfgt, seta_state, init_crazyfgt, ROT0, "Subsino", "Crazy Fight", MACHINE_UNEMULATED_PROTECTION | MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, crazyfgt, 0, crazyfgt, crazyfgt, crazyfgt_state, empty_init, ROT0, "Subsino", "Crazy Fight", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )

View File

@ -13,6 +13,7 @@
#include "machine/74157.h"
#include "machine/adc083x.h"
#include "machine/ds2430a.h"
#include "machine/gen_latch.h"
#include "machine/ticket.h"
#include "machine/timer.h"
@ -79,7 +80,6 @@ public:
void blockcarb(machine_config &config);
void wrofaero(machine_config &config);
void blockcar(machine_config &config);
void crazyfgt(machine_config &config);
void drgnunit(machine_config &config);
void stg(machine_config &config);
void qzkklogy(machine_config &config);
@ -95,7 +95,6 @@ public:
void rezon(machine_config &config);
void init_rezon();
void init_crazyfgt();
void init_wiggie();
void init_bankx1();
void init_eightfrc();
@ -185,7 +184,6 @@ protected:
void blockcarb_map(address_map &map);
void blockcarb_sound_map(address_map &map);
void blockcarb_sound_portmap(address_map &map);
void crazyfgt_map(address_map &map);
void daioh_map(address_map &map);
void daiohp_map(address_map &map);
void drgnunit_map(address_map &map);
@ -536,6 +534,26 @@ protected:
std::unique_ptr<u16 []> m_protram_old;
};
class crazyfgt_state : public seta_state
{
public:
crazyfgt_state(const machine_config &mconfig, device_type type, const char *tag)
: seta_state(mconfig, type, tag)
, m_eeprom(*this, "eeprom")
{
}
void crazyfgt(machine_config &config);
private:
void coin_counter_w(u8 data);
void outputs_w(u8 data);
void crazyfgt_map(address_map &map);
required_device<ds2430a_device> m_eeprom;
};
class jockeyc_state : public seta_state
{
public:

View File

@ -65,15 +65,20 @@ Notes:
TODO:
- Game speed seems to be completely wrong, timers and player movement too fast?
The EEPROM protection method is the same as in the subsino2.cpp games.
*********************************************************************************************************************/
#include "emu.h"
#include "cpu/h8/h83048.h"
#include "machine/ds2430a.h"
#include "machine/nvram.h"
#include "video/ramdac.h"
#include "emupal.h"
#include "screen.h"
#define DEBUG_GFX 0
namespace {
@ -83,8 +88,10 @@ public:
lastfght_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_maincpu(*this,"maincpu"),
m_eeprom(*this, "eeprom"),
m_screen(*this, "screen"),
m_palette(*this, "palette")
m_palette(*this, "palette"),
m_inputs(*this, "IN%u", 0U)
{ }
void lastfght(machine_config &config);
@ -136,7 +143,7 @@ private:
int m_y = 0;
int m_w = 0;
int m_h = 0;
#ifdef MAME_DEBUG
#if DEBUG_GFX
unsigned m_base = 0;
int m_view_roms = 0;
#endif
@ -146,8 +153,10 @@ private:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<ds2430a_device> m_eeprom;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_ioport_array<3> m_inputs;
};
@ -168,8 +177,7 @@ void lastfght_state::video_start()
uint32_t lastfght_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
#ifdef MAME_DEBUG
#if 1
#if DEBUG_GFX
// gfx roms viewer (toggle with enter, use pgup/down to browse)
uint8_t const *const gfxdata = memregion("gfx1")->base();
@ -195,7 +203,6 @@ uint32_t lastfght_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
popmessage("%x", m_base);
return 0;
}
#endif
#endif
copybitmap(bitmap, m_bitmap[m_dest ^ 1], 0, 0, 0, 0, cliprect);
@ -372,12 +379,12 @@ uint16_t lastfght_state::c00002_r()
{
// high byte:
// mask 0x1c: from sound?
return (machine().rand() & 0x1c00) | ioport("IN0")->read();
return (machine().rand() & 0x1c00) | m_inputs[0]->read();
}
uint16_t lastfght_state::c00004_r()
{
return ioport("IN1")->read();
return m_inputs[1]->read();
}
uint16_t lastfght_state::c00006_r()
@ -385,13 +392,15 @@ uint16_t lastfght_state::c00006_r()
// low byte:
// bit 7 = protection?
// bit 5 = blitter?
return ioport("IN2")->read();
return (m_c00006 & 0x005f) | (m_inputs[2]->read() & 0xffa0);
}
void lastfght_state::c00006_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
COMBINE_DATA(&m_c00006);
// popmessage("%04x", m_c00006);
m_eeprom->data_w(!BIT(m_c00006, 6));
}
uint16_t lastfght_state::sound_r()
@ -494,14 +503,9 @@ static INPUT_PORTS_START( lastfght )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_START("IN2") /* IN2 - c00006&7 */
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x005f, IP_ACTIVE_HIGH, IPT_UNUSED ) // outputs
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r)
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
@ -565,6 +569,8 @@ void lastfght_state::lastfght(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
DS2430A(config, m_eeprom).set_timing_scale(0.16);
/* video hardware */
PALETTE(config, m_palette).set_entries(256);
@ -596,15 +602,15 @@ ROM_START( lastfght )
ROM_REGION( 0x100000, "samples", 0 ) // Samples
ROM_LOAD( "v100.u7", 0x000000, 0x100000, CRC(c134378c) SHA1(999c75f3a7890421cfd904a926ca377ee43a6825) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(622a8862) SHA1(fae60a326e6905aefc36275d505147e1860a71d0) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void lastfght_state::init_lastfght()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// pass initial check (protection ? hw?)
rom[0x00354 / 2] = 0x403e;
// rts -> rte
rom[0x01b86 / 2] = 0x5670;
}

View File

@ -31,7 +31,6 @@ Year Game CPU Sound Custom
To do:
- Implement serial communication, remove patches (used for protection).
- Add sound to SS9804/SS9904 games.
- ptrain: missing scroll in race screens.
- humlan: empty reels when bonus image should scroll in via L0 scroll. The image (crown/fruits) is at y > 0x100 in the tilemap.
@ -40,6 +39,19 @@ To do:
- mtrain: implement hopper.
- xplan: starts with 4 credits, no controls to move the aircraft
Protection seems to work the same way on every game in this driver, using a bitbanged Dallas 1-Wire EEPROM. First a Read ROM
command is issued, and only the first 8 bits returned are examined to determine whether they match the expected device code (0x14).
If this test passes, the EEPROM contents are recalled and the first 64 bits are read out. These 64 bits are then unscrambled using
a permutation table common to all games. The second and final protection check compares byte 6 in the unscrambled data buffer
against a game-specific ID code. This byte is composed of EEPROM bits 22 (MSB), 27, 52, 50, 42, 9, 38 and 35 (LSB).
It is unknown where this protection EEPROM exists on any Subsino PCB (if it isn't an external dongle), though the IC package is
known to be quite small.
Timings in the Z180-based and H8-based games consistently fail to meet 1-Wire specifications. In the case of the H8-based games,
this likely has to do with CPU clocks and emulated cycle timings being both too fast. There may also be wait states programmed
by the otherwise seemingly unnecessary internal ROMs.
************************************************************************************************************/
#include "emu.h"
@ -48,6 +60,7 @@ To do:
#include "cpu/h8/h83048.h"
#include "cpu/i86/i186.h"
#include "cpu/z180/z180.h"
#include "machine/ds2430a.h"
#include "machine/nvram.h"
#include "machine/ticket.h"
#include "sound/okim6295.h"
@ -103,6 +116,7 @@ public:
, m_palette(*this, "palette")
, m_hopper(*this, "hopper")
, m_ticket(*this, "ticket")
, m_eeprom(*this, "eeprom")
, m_keyb(*this, "KEYB_%u", 0U)
, m_dsw(*this, "DSW%u", 1U)
, m_system(*this, "SYSTEM")
@ -123,21 +137,16 @@ public:
void init_new2001();
void init_queenbee();
void init_queenbeeb();
void init_queenbeei();
void init_humlan();
void init_squeenb();
void init_qbeebing();
void init_treamary();
void init_xtrain();
void init_expcard();
void init_wtrnymph();
void init_mtrain();
void init_strain();
void init_tbonusal();
void init_saklove();
void init_xplan();
void init_ptrain();
void init_treacity();
void init_treacity202();
CUSTOM_INPUT_MEMBER(output_d_r) { return m_outputs[3] & 0x47; }
protected:
virtual void video_start() override;
@ -178,7 +187,8 @@ private:
uint8_t dsw_r();
uint8_t vblank_bit2_r();
uint8_t vblank_bit6_r();
void bishjan_sound_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint8_t bishjan_sound_r();
void bishjan_sound_w(uint8_t data);
uint16_t bishjan_serial_r();
void bishjan_input_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
uint16_t bishjan_input_r();
@ -239,6 +249,7 @@ private:
required_device<palette_device> m_palette;
optional_device<ticket_dispenser_device> m_hopper;
optional_device<ticket_dispenser_device> m_ticket;
required_device<ds2430a_device> m_eeprom;
optional_ioport_array<5> m_keyb;
optional_ioport_array<4> m_dsw;
optional_ioport m_system;
@ -901,21 +912,36 @@ void subsino2_state::oki_bank_bit4_w(uint8_t data)
Bishou Jan
***************************************************************************/
void subsino2_state::bishjan_sound_w(offs_t offset, uint16_t data, uint16_t mem_mask)
uint8_t subsino2_state::bishjan_sound_r()
{
return 0;
}
void subsino2_state::bishjan_sound_w(uint8_t data)
{
/*
sound writes in service mode:
01 88 04 00 (coin in)
02 89 04 0v (v = voice = 0..3)
*/
if (ACCESSING_BITS_8_15)
m_bishjan_sound = data >> 8;
switch (data)
{
case 0x10:
m_eeprom->data_w(1);
break;
case 0x13:
m_eeprom->data_w(0);
break;
}
m_bishjan_sound = data;
}
uint16_t subsino2_state::bishjan_serial_r()
{
return
(machine().rand() & 0x9800) | // bit 7 - serial communication
(m_eeprom->data_r() ? 0x8000 : 0) | // bit 7 - serial communication
(machine().rand() & 0x1800) |
(((m_bishjan_sound == 0x12) ? 0x40:0x00) << 8) | // bit 6 - sound communication
// (machine().rand() & 0xff);
// (((m_screen->frame_number()%60)==0)?0x18:0x00);
@ -992,7 +1018,7 @@ void subsino2_state::bishjan_map(address_map &map)
map(0x436000, 0x436fff).w(FUNC(subsino2_state::ss9601_reelram_hi_lo_w));
map(0x437000, 0x4371ff).w(FUNC(subsino2_state::ss9601_scrollram_0_hi_lo_w));
map(0x600000, 0x600001).nopr().w(FUNC(subsino2_state::bishjan_sound_w));
map(0x600000, 0x600000).rw(FUNC(subsino2_state::bishjan_sound_r), FUNC(subsino2_state::bishjan_sound_w));
map(0x600040, 0x600040).w(FUNC(subsino2_state::ss9601_scrollctrl_w));
map(0x600060, 0x600060).w("ramdac", FUNC(ramdac_device::index_w));
map(0x600061, 0x600061).w("ramdac", FUNC(ramdac_device::pal_w));
@ -1086,7 +1112,7 @@ void subsino2_state::new2001_base_map(address_map &map)
map(0x436000, 0x436fff).w(FUNC(subsino2_state::ss9601_reelram_hi_lo_w));
map(0x437000, 0x4371ff).w(FUNC(subsino2_state::ss9601_scrollram_0_hi_lo_w));
map(0x600000, 0x600001).nopr().w(FUNC(subsino2_state::bishjan_sound_w));
map(0x600000, 0x600000).rw(FUNC(subsino2_state::bishjan_sound_r), FUNC(subsino2_state::bishjan_sound_w));
map(0x600020, 0x600020).w(FUNC(subsino2_state::ss9601_byte_lo2_w));
map(0x600040, 0x600040).w(FUNC(subsino2_state::ss9601_scrollctrl_w));
map(0x600060, 0x600060).w("ramdac", FUNC(ramdac_device::index_w));
@ -1158,7 +1184,7 @@ void subsino2_state::expcard_outputs_w(offs_t offset, uint8_t data)
switch (offset)
{
case 0: // D
// 0x40 = serial out ? (at boot)
m_eeprom->data_w(!BIT(data, 6));
break;
case 1: // C
@ -1212,6 +1238,7 @@ void subsino2_state::mtrain_outputs_w(offs_t offset, uint8_t data)
break;
case 3:
m_eeprom->data_w(!BIT(data, 6));
break;
}
@ -1298,7 +1325,7 @@ void subsino2_state::mtrain_map(address_map &map)
map(0x0912f, 0x0912f).w(FUNC(subsino2_state::ss9601_byte_lo_w));
map(0x09140, 0x09142).w(FUNC(subsino2_state::mtrain_outputs_w)).share("outputs");
map(0x09140, 0x09143).w(FUNC(subsino2_state::mtrain_outputs_w)).share("outputs");
map(0x09143, 0x09143).portr("IN-D"); // (not shown in system test) 0x40 serial out, 0x80 serial in
map(0x09144, 0x09144).portr("IN-A"); // A
map(0x09145, 0x09145).portr("IN-B"); // B
@ -1349,6 +1376,7 @@ void subsino2_state::saklove_outputs_w(offs_t offset, uint8_t data)
case 3:
// 1, 2, 4
m_eeprom->data_w(!BIT(data, 6));
break;
}
@ -1421,7 +1449,7 @@ void subsino2_state::xplan_outputs_w(offs_t offset, uint8_t data)
switch (offset)
{
case 0:
// 0x40 = serial out ? (at boot)
m_eeprom->data_w(!BIT(data, 6));
break;
case 1:
@ -1531,7 +1559,7 @@ void subsino2_state::xtrain_outputs_w(offs_t offset, uint8_t data)
{
case 0: // D
m_hopper->motor_w(BIT(data, 2));
// 0x40 = serial out ? (at boot)
m_eeprom->data_w(!BIT(data, 6));
break;
case 1: // C
@ -1880,8 +1908,8 @@ static INPUT_PORTS_START( expcard )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1) // reset
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) // serial in?
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) // serial out
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r)
INPUT_PORTS_END
/***************************************************************************
@ -2021,14 +2049,11 @@ static INPUT_PORTS_START( mtrain )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN-D") // not shown in test mode
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) // serial in?
PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(subsino2_state, output_d_r)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
/***************************************************************************
@ -2171,14 +2196,11 @@ static INPUT_PORTS_START( strain ) // inputs need verifying
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN-D") // not shown in test mode
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) // serial in?
PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(subsino2_state, output_d_r)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
/***************************************************************************
@ -2321,14 +2343,11 @@ static INPUT_PORTS_START( tbonusal ) // inputs need verifying
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN-D") // not shown in test mode
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) // serial in?
PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(subsino2_state, output_d_r)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
/***************************************************************************
@ -2458,8 +2477,8 @@ static INPUT_PORTS_START( saklove )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // used?
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) // serial out
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
/***************************************************************************
@ -2608,8 +2627,8 @@ static INPUT_PORTS_START( treacity )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // used?
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) // serial out
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
/***************************************************************************
@ -2676,8 +2695,8 @@ static INPUT_PORTS_START( xplan )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // used?
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) // serial in?
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_OTHER ) // serial out
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
/***************************************************************************
@ -2742,8 +2761,8 @@ static INPUT_PORTS_START( xtrain )
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_CUSTOM) PORT_READ_LINE_DEVICE_MEMBER("hopper", ticket_dispenser_device, line_r)
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_UNKNOWN)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_UNKNOWN)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_CUSTOM) // serial in?
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_OTHER) // serial out
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_CUSTOM) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
static INPUT_PORTS_START( ptrain )
@ -2891,14 +2910,11 @@ static INPUT_PORTS_START( wtrnymph )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Play Tetris") PORT_CODE(KEYCODE_T) // T |__ play Tetris game
PORT_START("IN-D") // not shown in test mode
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) // serial in?
PORT_BIT( 0x47, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(subsino2_state, output_d_r)
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Reset") PORT_CODE(KEYCODE_F1)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("eeprom", ds2430a_device, data_r) // serial in
INPUT_PORTS_END
@ -2918,6 +2934,8 @@ void subsino2_state::bishjan(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
TICKET_DISPENSER(config, m_hopper, attotime::from_msec(200), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH);
DS2430A(config, m_eeprom).set_timing_scale(0.12);
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_size(512, 256);
@ -2952,6 +2970,8 @@ void subsino2_state::humlan(machine_config &config)
H83044(config.replace(), m_maincpu, XTAL(48'000'000) / 3);
m_maincpu->set_addrmap(AS_PROGRAM, &subsino2_state::humlan_map);
m_eeprom->set_timing_scale(0.16);
// sound hardware
// SS9804
}
@ -2966,6 +2986,8 @@ void subsino2_state::mtrain(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &subsino2_state::mtrain_map);
m_maincpu->set_addrmap(AS_IO, &subsino2_state::mtrain_io);
DS2430A(config, m_eeprom).set_timing_scale(0.73);
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
// video hardware
@ -3002,6 +3024,8 @@ void subsino2_state::saklove(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
DS2430A(config, m_eeprom);
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_size(512, 256);
@ -3037,6 +3061,8 @@ void subsino2_state::xplan(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
DS2430A(config, m_eeprom);
// video hardware
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_size(512, 256);
@ -3143,15 +3169,15 @@ ROM_START( bishjan )
ROM_REGION( 0x100000, "samples", 0 ) // SS9904
ROM_LOAD( "2-v201.u9", 0x000000, 0x100000, CRC(ea42764d) SHA1(13fe1cd30e474f4b092949c440068e9ddca79976) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(e248ebfa) SHA1(b75e5be0a0a6b32e6cc372fc3da01009f3cca7e2) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_bishjan()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (it always enters test mode on boot otherwise)
rom[0x042EA/2] = 0x4008;
// rts -> rte
rom[0x33386/2] = 0x5670; // IRQ 0
rom[0x0CC5C/2] = 0x5670; // IRQ 8
@ -3213,15 +3239,15 @@ ROM_START( new2001 )
ROM_REGION( 0x80000, "samples", 0 ) // SS9904
ROM_LOAD( "new_2001_italy_2_v200.u9", 0x00000, 0x80000, CRC(9d522d04) SHA1(68f314b077a62598f3de8ef753bdedc93d6eca71) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(71281d72) SHA1(1661181a5a5331083d649b10a7d3a36062e617c0) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_new2001()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (ERROR 041920 otherwise)
rom[0x19A2/2] = 0x4066;
// rts -> rte
rom[0x45E8/2] = 0x5670; // IRQ 8
rom[0x471C/2] = 0x5670; // IRQ 0
@ -3249,15 +3275,15 @@ ROM_START( queenbee )
ROM_REGION( 0x80000, "samples", 0 )
ROM_LOAD( "27c4001 u9.bin", 0x000000, 0x80000, CRC(c7cda990) SHA1(193144fe0c31fc8342bd44aa4899bf15f0bc399d) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(f64b92e5) SHA1(fbef61b1046c6559d5ac71e665e822f9a6704461) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_queenbee()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (ERROR 093099 otherwise)
rom[0x1cc6/2] = 0x4066;
// rts -> rte
rom[0x3e6a/2] = 0x5670; // IRQ 8
rom[0x3fbe/2] = 0x5670; // IRQ 0
@ -3278,15 +3304,15 @@ ROM_START( queenbeeb )
ROM_REGION( 0x40000, "samples", 0 )
ROM_LOAD( "u9", 0x000000, 0x40000, NO_DUMP )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(b6d57e98) SHA1(6bbed2613c667369e74c417917c1c36d36f03739) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_queenbeeb()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (ERROR 093099 otherwise)
rom[0x1826/2] = 0x4066;
// rts -> rte
rom[0x3902/2] = 0x5670; // IRQ 8
rom[0x3a56/2] = 0x5670; // IRQ 0
@ -3303,8 +3329,20 @@ ROM_START( queenbeei )
ROM_REGION( 0x80000, "samples", 0 )
ROM_LOAD( "u9", 0x000000, 0x80000, NO_DUMP )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(25d37d36) SHA1(9d7130328be80c1b9376ac6923300122ee1b9399) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_queenbeei()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// rts -> rte
rom[0x3abc/2] = 0x5670; // IRQ 8
rom[0x3bca/2] = 0x5670; // IRQ 0
}
ROM_START( queenbeesa )
ROM_REGION( 0x80000, "maincpu", 0 ) // H8/3044
ROM_LOAD( "00b0 u21 1v101", 0x00000, 0x40000, CRC(19e31fd7) SHA1(01cf507958b0411d21dd660280f45668d7c5b9d9) )
@ -3315,8 +3353,10 @@ ROM_START( queenbeesa )
ROM_REGION( 0x80000, "samples", 0 )
ROM_LOAD( "u9", 0x000000, 0x80000, NO_DUMP )
ROM_END
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(a084e2c9) SHA1(18ba0577ab61d89816b157ee24532c4a3f8d0b6f) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
@ -3347,15 +3387,15 @@ ROM_START( humlan )
ROM_REGION( 0x40000, "samples", 0 ) // SS9804
// clearly samples, might be different from the SS9904 case
ROM_LOAD( "subsino__qb-v1.u9", 0x000000, 0x40000, CRC(c5dfed44) SHA1(3f5effb85de10c0804efee9bce769d916268bfc9) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(281eb16b) SHA1(db62a7004e2bc9a052d6f154cb4c6d645d00f768) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_humlan()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (ERROR 093099 otherwise)
rom[0x170A/2] = 0x4066;
// rts -> rte
rom[0x38B4/2] = 0x5670; // IRQ 8
rom[0x3A08/2] = 0x5670; // IRQ 0
@ -3383,15 +3423,15 @@ ROM_START( squeenb )
ROM_REGION( 0x80000, "samples", 0 )
ROM_LOAD( "u9", 0x000000, 0x80000, CRC(c7cda990) SHA1(193144fe0c31fc8342bd44aa4899bf15f0bc399d) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(c861db4a) SHA1(3109031239328a167f80082ec70b62630f8316ab) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_squeenb()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (ERROR 093099 otherwise)
rom[0x1814/2] = 0x4066;
// rts -> rte
rom[0x399a/2] = 0x5670; // IRQ 8
rom[0x3aa8/2] = 0x5670; // IRQ 0
@ -3406,16 +3446,18 @@ ROM_START( qbeebing )
ROM_LOAD16_BYTE( "rom 3 27c160 08d7h", 0x000000, 0x200000, CRC(1fdf0fcb) SHA1(ed54172521f8d05bad37b670548106e4c4deb8af) )
ROM_REGION( 0x80000, "samples", ROMREGION_ERASE00 ) // no samples, missing?
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(0d8db9ef) SHA1(eef0c8debbb2cb20af180c5c6a8ba998104fa24e) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_qbeebing()
{
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// patch serial protection test (ERROR 093099 otherwise)
rom[0x25b6/2] = 0x4066;
// other patches?
// rts -> rte
rom[0x4714/2] = 0x5670; // IRQ 8
rom[0x49a0/2] = 0x5670; // IRQ 0
}
ROM_START( treamary )
@ -3430,14 +3472,20 @@ ROM_START( treamary )
ROM_REGION( 0x80000, "samples", 0 )
ROM_LOAD( "27c040_u9.bin", 0x000000, 0x80000, CRC(5345ca39) SHA1(2b8f1dfeebb93a1d99c06912d89b268c642163df) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(0c068400) SHA1(7892443b04a987da944e36d6a528e1fdfbc68a39) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_treamary()
{
// other patches?
uint16_t *rom = (uint16_t*)memregion("maincpu")->base();
// gets stuck on CHIP1 test, enters test mode if bypassed
// rts -> rte
rom[0x5804/2] = 0x5670; // IRQ 0
// other patches?
}
@ -3491,16 +3539,11 @@ ROM_START( expcard )
ROM_REGION( 0x80000, "oki", 0 )
ROM_LOAD( "top_card-ve1.u7", 0x00000, 0x80000, CRC(0ca9bd18) SHA1(af791c78ae321104afa738564bc23f520f37e7d5) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(622a8862) SHA1(fae60a326e6905aefc36275d505147e1860a71d0) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_expcard()
{
uint8_t *rom = memregion("maincpu")->base();
// patch protection test (it always enters test mode on boot otherwise)
rom[0xed4dc-0xc0000] = 0xeb;
}
/***************************************************************************
Magic Train
@ -3569,6 +3612,9 @@ ROM_START( mtrain )
ROM_LOAD( "gal16v8d.u19", 0x000, 0x117, NO_DUMP )
ROM_LOAD( "gal16v8d.u26", 0x000, 0x117, NO_DUMP )
ROM_LOAD( "gal16v8d.u31", 0x000, 0x117, NO_DUMP )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(a73211f7) SHA1(ebe175b9b8ea3fffcc9dd03ea51ccef36b016eb8) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
ROM_START( strain )
@ -3589,6 +3635,9 @@ ROM_START( strain )
ROM_REGION( 0x117, "plds", ROMREGION_ERASE00 )
// TODO: list these
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(133705eb) SHA1(974b7fd5f7eaa84c4ba2a5ba9e014ac459fa7d23) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
@ -3612,20 +3661,6 @@ ROM_END
void subsino2_state::init_mtrain()
{
subsino_decrypt(machine(), crsbingo_bitswaps, crsbingo_xors, 0x8000);
// patch serial protection test (it always enters test mode on boot otherwise)
uint8_t *rom = memregion("maincpu")->base();
rom[0x0cec] = 0x18;
rom[0xb037] = 0x18;
}
void subsino2_state::init_strain()
{
subsino_decrypt(machine(), crsbingo_bitswaps, crsbingo_xors, 0x8000);
// patch 'version error' (not sure this is correct, there's no title logo?)
uint8_t *rom = memregion("maincpu")->base();
rom[0x141c] = 0x20;
}
@ -3653,16 +3688,14 @@ ROM_START( tbonusal )
ROM_REGION( 0x117, "plds", ROMREGION_ERASEFF )
// TODO list of GALs
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(7c832409) SHA1(fe16074490fe4edab2be2de5fa83941dac9969b0) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_tbonusal()
{
subsino_decrypt(machine(), sharkpy_bitswaps, sharkpy_xors, 0x8000);
// patch serial protection test (it always enters test mode on boot otherwise)
uint8_t *rom = memregion("maincpu")->base();
rom[0x0ea7] = 0x18;
rom[0xbbbf] = 0x18;
}
/***************************************************************************
@ -3709,16 +3742,11 @@ ROM_START( saklove )
ROM_REGION( 0x80000, "oki", 0 )
ROM_LOAD( "2.u10", 0x00000, 0x80000, CRC(4f70125c) SHA1(edd5e6bd47b9a4fa3c4057cb4a85544241fe483d) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(0ed01bd7) SHA1(62546003443845552e6adc4ca26375f93824d662) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_saklove()
{
uint8_t *rom = memregion("maincpu")->base();
// patch serial protection test (it always enters test mode on boot otherwise)
rom[0x0e029] = 0xeb;
}
/***************************************************************************
X-Plan
@ -3769,16 +3797,11 @@ ROM_START( xplan )
ROM_REGION( 0x80000, "oki", 0 )
ROM_LOAD( "x-plan_rom_2_v100.u7", 0x00000, 0x80000, CRC(c742b5c8) SHA1(646960508be738824bfc578c1b21355c17e05010) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(ac70474d) SHA1(120362665af4ab361197795c6be51c8fed5a3506) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_xplan()
{
uint8_t *rom = memregion("maincpu")->base();
// patch protection test (it always enters test mode on boot otherwise)
rom[0xeded9-0xc0000] = 0xeb;
}
/***************************************************************************
X-Train
@ -3829,16 +3852,11 @@ ROM_START( xtrain )
ROM_REGION( 0x80000, "oki", 0 )
ROM_LOAD( "x-train_rom_2_v1.2.u7", 0x00000, 0x80000, CRC(aae563ff) SHA1(97db845d7e3d343bd70352371cb27b16faacca7f) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(9c5973b7) SHA1(ba79b2971cfa5d0183b1be5d54c5e7f13f0e8243) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_xtrain()
{
uint8_t *rom = memregion("maincpu")->base();
// patch protection test (it always enters test mode on boot otherwise)
rom[0xe190f-0xc0000] = 0xeb;
}
/***************************************************************************
Panda Train (Novamatic 1.7)
@ -3892,16 +3910,11 @@ ROM_START( ptrain )
ROM_REGION( 0x80000, "oki", 0 )
ROM_LOAD( "panda-novam_2-v1.4.u7", 0x00000, 0x80000, CRC(d1debec8) SHA1(9086975e5bef2066a688ab3c1df3b384f59e507d) )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(a19d7b78) SHA1(e32a33a953d2523a558c395debbf85ee1df8965b) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_ptrain()
{
uint8_t *rom = memregion("maincpu")->base();
// patch protection test (it always enters test mode on boot otherwise)
rom[0xe1b08-0xc0000] = 0xeb;
}
/***************************************************************************
Treasure City
@ -3920,16 +3933,11 @@ ROM_START( treacity )
ROM_LOAD32_BYTE( "alpha 207_27c4001_u10.bin", 0x00003, 0x80000, CRC(338370f9) SHA1(0e06ed1b71fb44bfd617f4d5112f6d34f0b759bc) )
ROM_REGION( 0x80000, "oki", ROMREGION_ERASE00 ) // samples, missing or not used / other hardware here?
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(8c9906fd) SHA1(8afaaf80dbaf5d9763da5fa0c6f95d20887bc336) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_treacity()
{
uint8_t *rom = memregion("maincpu")->base();
// patch protection test (it always enters test mode on boot otherwise)
rom[0xaff9] = 0x75;
}
ROM_START( treacity202 )
ROM_REGION( 0x20000, "maincpu", 0 )
ROM_LOAD( "alpha 202_27c1001_u33.bin", 0x00000, 0x20000, CRC(1a698c3d) SHA1(c2107b67d86783b04d1ebdf78d1f358916c51219) )
@ -3941,16 +3949,11 @@ ROM_START( treacity202 )
ROM_LOAD32_BYTE( "alpha 142_27c4001_u10.bin", 0x00003, 0x80000, CRC(8545e8cd) SHA1(0d122a532df81fe2150c1eaf49b5a4e35c8134eb) )
ROM_REGION( 0x80000, "oki", ROMREGION_ERASE00 ) // samples, missing or not used / other hardware here?
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(8c9906fd) SHA1(8afaaf80dbaf5d9763da5fa0c6f95d20887bc336) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_treacity202()
{
uint8_t *rom = memregion("maincpu")->base();
// patch protection test (it always enters test mode on boot otherwise)
rom[0xae30] = 0x75;
}
@ -3986,49 +3989,45 @@ ROM_START( wtrnymph )
ROM_LOAD( "gal16v8d.u19", 0x000, 0x117, NO_DUMP )
ROM_LOAD( "gal16v8d.u26", 0x000, 0x117, NO_DUMP )
ROM_LOAD( "gal16v8d.u31", 0x000, 0x117, NO_DUMP )
ROM_REGION( 0x28, "eeprom", 0 )
ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(1b585f27) SHA1(ee89dfc731d867507c15009910e9f743c652a399) BAD_DUMP ) // handcrafted to pass protection check
ROM_END
void subsino2_state::init_wtrnymph()
{
subsino_decrypt(machine(), victor5_bitswaps, victor5_xors, 0x8000);
// patch serial protection test (it always enters test mode on boot otherwise)
uint8_t *rom = memregion("maincpu")->base();
rom[0x0d79] = 0x18;
rom[0xc1cf] = 0x18;
rom[0xc2a9] = 0x18;
rom[0xc2d7] = 0x18;
}
GAME( 1996, mtrain, 0, mtrain, mtrain, subsino2_state, init_mtrain, ROT0, "Subsino", "Magic Train (Ver. 1.31)", 0 )
GAME( 1996, strain, 0, mtrain, strain, subsino2_state, init_strain, ROT0, "Subsino", "Super Train (Ver. 1.9)", MACHINE_NOT_WORKING )
GAME( 1996, strain, 0, mtrain, strain, subsino2_state, init_mtrain, ROT0, "Subsino", "Super Train (Ver. 1.9)", MACHINE_NOT_WORKING )
GAME( 1995, tbonusal, 0, mtrain, tbonusal, subsino2_state, init_tbonusal, ROT0, "Subsino (American Alpha license)", "Treasure Bonus (American Alpha, Ver. 1.6)", MACHINE_NOT_WORKING )
GAME( 1996, wtrnymph, 0, mtrain, wtrnymph, subsino2_state, init_wtrnymph, ROT0, "Subsino", "Water-Nymph (Ver. 1.4)", 0 )
GAME( 1998, expcard, 0, expcard, expcard, subsino2_state, init_expcard, ROT0, "Subsino (American Alpha license)", "Express Card / Top Card (Ver. 1.5)", 0 )
GAME( 1998, expcard, 0, expcard, expcard, subsino2_state, empty_init, ROT0, "Subsino (American Alpha license)", "Express Card / Top Card (Ver. 1.5)", 0 )
GAME( 1998, saklove, 0, saklove, saklove, subsino2_state, init_saklove, ROT0, "Subsino", "Ying Hua Lian 2.0 (China, Ver. 1.02)", 0 )
GAME( 1998, saklove, 0, saklove, saklove, subsino2_state, empty_init, ROT0, "Subsino", "Ying Hua Lian 2.0 (China, Ver. 1.02)", 0 )
GAME( 1999, xtrain, 0, xtrain, xtrain, subsino2_state, init_xtrain, ROT0, "Subsino", "X-Train (Ver. 1.3)", 0 )
GAME( 1999, xtrain, 0, xtrain, xtrain, subsino2_state, empty_init, ROT0, "Subsino", "X-Train (Ver. 1.3)", 0 )
GAME( 1999, ptrain, 0, ptrain, ptrain, subsino2_state, init_ptrain, ROT0, "Subsino", "Panda Train (Novamatic 1.7)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1999, ptrain, 0, ptrain, ptrain, subsino2_state, empty_init, ROT0, "Subsino", "Panda Train (Novamatic 1.7)", MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, treacity, 0, saklove, treacity, subsino2_state, init_treacity, ROT0, "Subsino (American Alpha license)", "Treasure City (Ver. 208)", MACHINE_NOT_WORKING )
GAME( 1997, treacity202, treacity,saklove, treacity, subsino2_state, init_treacity202, ROT0, "Subsino (American Alpha license)", "Treasure City (Ver. 202)", MACHINE_NOT_WORKING )
GAME( 1997, treacity, 0, saklove, treacity, subsino2_state, empty_init, ROT0, "Subsino (American Alpha license)", "Treasure City (Ver. 208)", MACHINE_NOT_WORKING )
GAME( 1997, treacity202, treacity,saklove, treacity, subsino2_state, empty_init, ROT0, "Subsino (American Alpha license)", "Treasure City (Ver. 202)", MACHINE_NOT_WORKING )
GAME( 1999, bishjan, 0, bishjan, bishjan, subsino2_state, init_bishjan, ROT0, "Subsino", "Bishou Jan (Japan, Ver. 203)", MACHINE_NO_SOUND )
GAME( 2000, new2001, 0, new2001, new2001, subsino2_state, init_new2001, ROT0, "Subsino", "New 2001 (Italy, Ver. 200N)", MACHINE_NO_SOUND )
GAME( 2006, xplan, 0, xplan, xplan, subsino2_state, init_xplan, ROT0, "Subsino", "X-Plan (Ver. 101)", MACHINE_NOT_WORKING )
GAME( 2006, xplan, 0, xplan, xplan, subsino2_state, empty_init, ROT0, "Subsino", "X-Plan (Ver. 101)", MACHINE_NOT_WORKING )
GAME( 2001, queenbee, 0, humlan, queenbee, subsino2_state, init_queenbee, ROT0, "Subsino (American Alpha license)", "Queen Bee (Ver. 114)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues
GAME( 2001, queenbeeb,queenbee, humlan, queenbee, subsino2_state, init_queenbeeb,ROT0, "Subsino", "Queen Bee (Brazil, Ver. 202)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues, only program ROM available
GAME( 2001, queenbeei,queenbee, humlan, queenbee, subsino2_state, empty_init, ROT0, "Subsino", "Queen Bee (Israel, Ver. 100)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues, only program ROM available
GAME( 2001, queenbeesa,queenbee,humlan, queenbee, subsino2_state, empty_init, ROT0, "Subsino", "Queen Bee (SA-101-HARD)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues, only program ROM available
GAME( 2001, queenbeei,queenbee, humlan, queenbee, subsino2_state, init_queenbeei,ROT0, "Subsino", "Queen Bee (Israel, Ver. 100)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues, only program ROM available
GAME( 2001, queenbeesa,queenbee,humlan, queenbee, subsino2_state, init_queenbeeb,ROT0, "Subsino", "Queen Bee (SA-101-HARD)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues, only program ROM available
GAME( 2001, humlan, queenbee, humlan, humlan, subsino2_state, init_humlan, ROT0, "Subsino (Truemax license)", "Humlan's Lyckohjul (Sweden, Ver. 402)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS ) // severe timing issues
@ -4036,4 +4035,4 @@ GAME( 2002, squeenb, 0, humlan, humlan, subsino2_state, init_squeenb
GAME( 2003, qbeebing, 0, humlan, humlan, subsino2_state, init_qbeebing, ROT0, "Subsino", "Queen Bee Bingo", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 200?, treamary, 0, humlan, humlan, subsino2_state, init_treamary, ROT0, "Subsino", "Treasure Mary", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 200?, treamary, 0, bishjan, bishjan, subsino2_state, init_treamary, ROT0, "Subsino", "Treasure Mary", MACHINE_NOT_WORKING | MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS )