From c3c625c8f378ca1deb81524f62c94dd8d4b065e1 Mon Sep 17 00:00:00 2001 From: AJR Date: Tue, 11 Apr 2023 21:26:26 -0400 Subject: 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 --- scripts/src/machine.lua | 12 + src/devices/machine/ds2430a.cpp | 685 ++++++++++++++++++++++++++++++++++++++++ src/devices/machine/ds2430a.h | 145 +++++++++ src/mame/seta/seta.cpp | 49 +-- src/mame/seta/seta.h | 24 +- src/mame/subsino/lastfght.cpp | 42 +-- src/mame/subsino/subsino2.cpp | 359 +++++++++++---------- 7 files changed, 1094 insertions(+), 222 deletions(-) create mode 100644 src/devices/machine/ds2430a.cpp create mode 100644 src/devices/machine/ds2430a.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 9ae0f30f936..d79cf1f0ee3 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -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 diff --git a/src/devices/machine/ds2430a.cpp b/src/devices/machine/ds2430a.cpp new file mode 100644 index 00000000000..2a992ee2667 --- /dev/null +++ b/src/devices/machine/ds2430a.cpp @@ -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 + +#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"); +} diff --git a/src/devices/machine/ds2430a.h b/src/devices/machine/ds2430a.h new file mode 100644 index 00000000000..64d426c9b77 --- /dev/null +++ b/src/devices/machine/ds2430a.h @@ -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 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 diff --git a/src/mame/seta/seta.cpp b/src/mame/seta/seta.cpp index d080c0f6d8c..14af5808a95 100644 --- a/src/mame/seta/seta.cpp +++ b/src/mame/seta/seta.cpp @@ -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 ) diff --git a/src/mame/seta/seta.h b/src/mame/seta/seta.h index d69b130dc69..4453f42de68 100644 --- a/src/mame/seta/seta.h +++ b/src/mame/seta/seta.h @@ -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 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 m_eeprom; +}; + class jockeyc_state : public seta_state { public: diff --git a/src/mame/subsino/lastfght.cpp b/src/mame/subsino/lastfght.cpp index 62fe7527fa3..06aa1822744 100644 --- a/src/mame/subsino/lastfght.cpp +++ b/src/mame/subsino/lastfght.cpp @@ -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 m_maincpu; + required_device m_eeprom; required_device m_screen; required_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; } diff --git a/src/mame/subsino/subsino2.cpp b/src/mame/subsino/subsino2.cpp index 216c33f4927..489b07e4edf 100644 --- a/src/mame/subsino/subsino2.cpp +++ b/src/mame/subsino/subsino2.cpp @@ -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 m_palette; optional_device m_hopper; optional_device m_ticket; + required_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(); + + // rts -> rte + rom[0x5804/2] = 0x5670; // IRQ 0 - // gets stuck on CHIP1 test, enters test mode if bypassed + // other patches? } @@ -3491,15 +3539,10 @@ ROM_START( expcard ) ROM_REGION( 0x80000, "oki", 0 ) ROM_LOAD( "top_card-ve1.u7", 0x00000, 0x80000, CRC(0ca9bd18) SHA1(af791c78ae321104afa738564bc23f520f37e7d5) ) -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; -} + ROM_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(622a8862) SHA1(fae60a326e6905aefc36275d505147e1860a71d0) BAD_DUMP ) // handcrafted to pass protection check +ROM_END /*************************************************************************** @@ -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,15 +3742,10 @@ ROM_START( saklove ) ROM_REGION( 0x80000, "oki", 0 ) ROM_LOAD( "2.u10", 0x00000, 0x80000, CRC(4f70125c) SHA1(edd5e6bd47b9a4fa3c4057cb4a85544241fe483d) ) -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; -} + ROM_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(0ed01bd7) SHA1(62546003443845552e6adc4ca26375f93824d662) BAD_DUMP ) // handcrafted to pass protection check +ROM_END /*************************************************************************** @@ -3769,15 +3797,10 @@ ROM_START( xplan ) ROM_REGION( 0x80000, "oki", 0 ) ROM_LOAD( "x-plan_rom_2_v100.u7", 0x00000, 0x80000, CRC(c742b5c8) SHA1(646960508be738824bfc578c1b21355c17e05010) ) -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; -} + ROM_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(ac70474d) SHA1(120362665af4ab361197795c6be51c8fed5a3506) BAD_DUMP ) // handcrafted to pass protection check +ROM_END /*************************************************************************** @@ -3829,15 +3852,10 @@ ROM_START( xtrain ) ROM_REGION( 0x80000, "oki", 0 ) ROM_LOAD( "x-train_rom_2_v1.2.u7", 0x00000, 0x80000, CRC(aae563ff) SHA1(97db845d7e3d343bd70352371cb27b16faacca7f) ) -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; -} + ROM_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(9c5973b7) SHA1(ba79b2971cfa5d0183b1be5d54c5e7f13f0e8243) BAD_DUMP ) // handcrafted to pass protection check +ROM_END /*************************************************************************** @@ -3892,15 +3910,10 @@ ROM_START( ptrain ) ROM_REGION( 0x80000, "oki", 0 ) ROM_LOAD( "panda-novam_2-v1.4.u7", 0x00000, 0x80000, CRC(d1debec8) SHA1(9086975e5bef2066a688ab3c1df3b384f59e507d) ) -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; -} + ROM_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(a19d7b78) SHA1(e32a33a953d2523a558c395debbf85ee1df8965b) BAD_DUMP ) // handcrafted to pass protection check +ROM_END /*************************************************************************** @@ -3920,15 +3933,10 @@ 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_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_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(8c9906fd) SHA1(8afaaf80dbaf5d9763da5fa0c6f95d20887bc336) BAD_DUMP ) // handcrafted to pass protection check +ROM_END ROM_START( treacity202 ) ROM_REGION( 0x20000, "maincpu", 0 ) @@ -3941,15 +3949,10 @@ 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_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; -} + ROM_REGION( 0x28, "eeprom", 0 ) + ROM_LOAD( "ds2430a.bin", 0x00, 0x28, CRC(8c9906fd) SHA1(8afaaf80dbaf5d9763da5fa0c6f95d20887bc336) BAD_DUMP ) // handcrafted to pass protection check +ROM_END @@ -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 ) -- cgit v1.2.3