mirror of
https://github.com/holub/mame
synced 2025-07-04 17:38:08 +03:00
kl5c80a12, kl5c80a16: Added emulation of KP63(A) Timer/Counter unit. This improves timings in animalc, haekaka, pyenaget and tdoboon.
* animalc: Pile kludge upon kludge for poorly understood video timing register * gocowboy, itazuram: Increase frequency of one timer interrupt (and hopper timing in gocowboy) * kc82, kp69: Modernize state_add syntax
This commit is contained in:
parent
949da6a0b0
commit
7e121d68bb
@ -49,6 +49,14 @@ if (CPU_INCLUDE_DRC) then
|
|||||||
MAME_DIR .. "src/devices/cpu/drcbex86.h",
|
MAME_DIR .. "src/devices/cpu/drcbex86.h",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if _OPTIONS["targetos"]=="macosx" and _OPTIONS["gcc"]~=nil then
|
||||||
|
if string.find(_OPTIONS["gcc"], "clang") and (str_to_version(_OPTIONS["gcc_version"]) < 80000) then
|
||||||
|
defines {
|
||||||
|
"TARGET_OS_OSX=1",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
@ -2624,6 +2632,8 @@ if (CPUS["Z80"]~=null) then
|
|||||||
MAME_DIR .. "src/devices/cpu/z80/kl5c80a12.h",
|
MAME_DIR .. "src/devices/cpu/z80/kl5c80a12.h",
|
||||||
MAME_DIR .. "src/devices/cpu/z80/kl5c80a16.cpp",
|
MAME_DIR .. "src/devices/cpu/z80/kl5c80a16.cpp",
|
||||||
MAME_DIR .. "src/devices/cpu/z80/kl5c80a16.h",
|
MAME_DIR .. "src/devices/cpu/z80/kl5c80a16.h",
|
||||||
|
MAME_DIR .. "src/devices/cpu/z80/kp63.cpp",
|
||||||
|
MAME_DIR .. "src/devices/cpu/z80/kp63.h",
|
||||||
MAME_DIR .. "src/devices/cpu/z80/kp69.cpp",
|
MAME_DIR .. "src/devices/cpu/z80/kp69.cpp",
|
||||||
MAME_DIR .. "src/devices/cpu/z80/kp69.h",
|
MAME_DIR .. "src/devices/cpu/z80/kp69.h",
|
||||||
MAME_DIR .. "src/devices/cpu/z80/ky80.cpp",
|
MAME_DIR .. "src/devices/cpu/z80/ky80.cpp",
|
||||||
|
@ -64,13 +64,11 @@ void kc82_device::device_start()
|
|||||||
|
|
||||||
for (int n = 1; n <= 4; n++)
|
for (int n = 1; n <= 4; n++)
|
||||||
{
|
{
|
||||||
state_add<u8>(KC82_B1 + n - 1, string_format("B%d", n).c_str(),
|
state_add(KC82_B1 + n - 1, string_format("B%d", n).c_str(), m_mmu_b[n],
|
||||||
[this, n]() { return m_mmu_b[n]; },
|
|
||||||
[this, n](u8 data) { m_mmu_b[n] = data; mmu_remap_pages(); }
|
[this, n](u8 data) { m_mmu_b[n] = data; mmu_remap_pages(); }
|
||||||
).mask(0x3f);
|
).mask(0x3f);
|
||||||
if (n != 4)
|
if (n != 4)
|
||||||
state_add<u16>(KC82_A1 + n - 1, string_format("A%d", n).c_str(),
|
state_add(KC82_A1 + n - 1, string_format("A%d", n).c_str(), m_mmu_a[n],
|
||||||
[this, n]() { return m_mmu_a[n]; },
|
|
||||||
[this, n](u16 data) { m_mmu_a[n] = data; mmu_remap_pages(); }
|
[this, n](u16 data) { m_mmu_a[n] = data; mmu_remap_pages(); }
|
||||||
).mask(0x3ff);
|
).mask(0x3ff);
|
||||||
}
|
}
|
||||||
|
477
src/devices/cpu/z80/kp63.cpp
Normal file
477
src/devices/cpu/z80/kp63.cpp
Normal file
@ -0,0 +1,477 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:AJR
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
Kawasaki Steel (Kawatetsu) KP63(A) Timer/Counter
|
||||||
|
|
||||||
|
These macro cells provide 4 independent 16-bit down counters (reduced
|
||||||
|
to 3 in some versions) driven by an 8-bit prescaler attached to the
|
||||||
|
system clock. This prescaler is not fully emulated here, since its
|
||||||
|
operations are mostly transparent, though a divide-by-4 clock output
|
||||||
|
(SYNC) may be selected to appear on a port pin.
|
||||||
|
|
||||||
|
Each counter has a single and optional external input (GATEn), which
|
||||||
|
on the KP63 can only be used to gate a divide-by-4 count but can also
|
||||||
|
be configured as an input clock on the KP63A.
|
||||||
|
|
||||||
|
Two outputs are generated for each counter. The pulse or toggle output
|
||||||
|
(OUTPn) has configurable polarity and can be used for 8-bit PWM. The
|
||||||
|
strobe output (OUTSn) goes active high for 4 clock cycles when the
|
||||||
|
counter underflows and is connected to the interrupt controller.
|
||||||
|
|
||||||
|
Writing the initial count register (CR) and reading the current count
|
||||||
|
are two-step processes, effective at the second write or first read.
|
||||||
|
These must not be overlapped with each other since they share a
|
||||||
|
temporary register.
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "kp63.h"
|
||||||
|
|
||||||
|
#define VERBOSE 1
|
||||||
|
#include "logmacro.h"
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// GLOBAL VARIABLES
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// device type definitions
|
||||||
|
DEFINE_DEVICE_TYPE(KP63_3CHANNEL, kp63_3channel_device, "kp63_3channel", "Kawasaki Steel KP63 Timer/Counter (3 channels)")
|
||||||
|
DEFINE_DEVICE_TYPE(KP63A, kp63a_device, "kp63a", "Kawasaki Steel KP63A Timer/Counter")
|
||||||
|
|
||||||
|
const char *const kp63_device::s_count_modes[4] =
|
||||||
|
{
|
||||||
|
"one-shot",
|
||||||
|
"continuous count",
|
||||||
|
"WDT",
|
||||||
|
"PWM"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// KP63 DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// kp63_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
kp63_device::kp63_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 num_counters, u8 mode_mask)
|
||||||
|
: device_t(mconfig, type, tag, owner, clock)
|
||||||
|
, m_out_pulse_callback(*this)
|
||||||
|
, m_out_strobe_callback(*this)
|
||||||
|
, c_num_counters(num_counters)
|
||||||
|
, c_mode_mask(mode_mask)
|
||||||
|
, m_timer{0}
|
||||||
|
, m_strobe_timer{0}
|
||||||
|
, m_pwm_timer{0}
|
||||||
|
, m_cr{0}
|
||||||
|
, m_last_count{0}
|
||||||
|
, m_count_tmp{0}
|
||||||
|
, m_status{0}
|
||||||
|
, m_rw_seq(0)
|
||||||
|
, m_timer_started(0)
|
||||||
|
, m_gate_input(0xf)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// kp63_3channel_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
kp63_3channel_device::kp63_3channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: kp63_device(mconfig, KP63_3CHANNEL, tag, owner, clock, 3, 0x1f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// kp63a_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
kp63a_device::kp63a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: kp63_device(mconfig, KP63A, tag, owner, clock, 4, 0x3f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_resolve_objects - resolve objects that
|
||||||
|
// may be needed for other devices to set
|
||||||
|
// initial conditions at start time
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::device_resolve_objects()
|
||||||
|
{
|
||||||
|
// Resolve output callbacks
|
||||||
|
m_out_pulse_callback.resolve_all_safe();
|
||||||
|
m_out_strobe_callback.resolve_all_safe();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// timer_expired - handle timed count underflow
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
TIMER_CALLBACK_MEMBER(kp63_device::timer_expired)
|
||||||
|
{
|
||||||
|
timer_pulse(N);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// strobe_off - handle end of strobe output
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
TIMER_CALLBACK_MEMBER(kp63_device::strobe_off)
|
||||||
|
{
|
||||||
|
m_out_strobe_callback[N](0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// pwm_off - handle PWM phase change
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template <int N>
|
||||||
|
TIMER_CALLBACK_MEMBER(kp63_device::pwm_off)
|
||||||
|
{
|
||||||
|
m_status[N] &= 0x7f;
|
||||||
|
m_out_pulse_callback[N](BIT(m_status[N], 4) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::device_start()
|
||||||
|
{
|
||||||
|
// Setup timers
|
||||||
|
m_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<0>), this));
|
||||||
|
m_strobe_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<0>), this));
|
||||||
|
m_pwm_timer[0] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<0>), this));
|
||||||
|
m_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<1>), this));
|
||||||
|
m_strobe_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<1>), this));
|
||||||
|
m_pwm_timer[1] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<1>), this));
|
||||||
|
m_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<2>), this));
|
||||||
|
m_strobe_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<2>), this));
|
||||||
|
m_pwm_timer[2] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<2>), this));
|
||||||
|
if (c_num_counters > 3)
|
||||||
|
{
|
||||||
|
m_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::timer_expired<3>), this));
|
||||||
|
m_strobe_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::strobe_off<3>), this));
|
||||||
|
m_pwm_timer[3] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(kp63_device::pwm_off<3>), this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save state
|
||||||
|
save_item(NAME(m_cr));
|
||||||
|
save_item(NAME(m_last_count));
|
||||||
|
save_item(NAME(m_count_tmp));
|
||||||
|
save_item(NAME(m_status));
|
||||||
|
save_item(NAME(m_rw_seq));
|
||||||
|
save_item(NAME(m_timer_started));
|
||||||
|
save_item(NAME(m_gate_input));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_reset - device-specific reset
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::device_reset()
|
||||||
|
{
|
||||||
|
for (unsigned n = 0; n < c_num_counters; n++)
|
||||||
|
{
|
||||||
|
// Turn off timers
|
||||||
|
m_timer[n]->adjust(attotime::never);
|
||||||
|
m_strobe_timer[n]->adjust(attotime::never);
|
||||||
|
m_pwm_timer[n]->adjust(attotime::never);
|
||||||
|
|
||||||
|
// Reset status and count
|
||||||
|
m_status[n] = 0;
|
||||||
|
m_cr[n] = 0xffff;
|
||||||
|
m_last_count[n] = 0xffff;
|
||||||
|
|
||||||
|
// Clear outputs
|
||||||
|
m_out_pulse_callback[n](0);
|
||||||
|
m_out_strobe_callback[n](0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear read/write sequence for all counters
|
||||||
|
m_rw_seq = 0;
|
||||||
|
m_timer_started = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// timer_pulse - change outputs and stop or
|
||||||
|
// reload timer as count underflows
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::timer_pulse(unsigned n)
|
||||||
|
{
|
||||||
|
// Toggle pulse output
|
||||||
|
m_status[n] ^= 0x80;
|
||||||
|
m_out_pulse_callback[n](BIT(m_status[n], 7) != BIT(m_status[n], 4) ? 1 : 0);
|
||||||
|
|
||||||
|
// Begin strobe output
|
||||||
|
m_out_strobe_callback[n](1);
|
||||||
|
m_strobe_timer[n]->adjust(clocks_to_attotime(4));
|
||||||
|
|
||||||
|
// Reload timer in continuous count and PWM modes
|
||||||
|
if (BIT(m_status[n], 2))
|
||||||
|
timer_reload(n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Stop count at FFFF in one-shot and WDT modes
|
||||||
|
m_last_count[n] = 0xffff;
|
||||||
|
m_timer_started &= ~(1 << n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// timer_reload - reload timer from CR
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::timer_reload(unsigned n)
|
||||||
|
{
|
||||||
|
m_timer_started |= 1 << n;
|
||||||
|
|
||||||
|
if (BIT(m_status[n], 5) || ((m_status[n] & 0x03) == 0x03 && !BIT(m_gate_input, n)))
|
||||||
|
m_last_count[n] = m_cr[n];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned prescale = BIT(m_status[n], 1) ? 4 : BIT(m_status[n], 0) ? 16 : 256;
|
||||||
|
if ((m_status[n] & 0x0c) == 0x0c)
|
||||||
|
{
|
||||||
|
// PWM
|
||||||
|
m_timer[n]->adjust(clocks_to_attotime(prescale * ((m_cr[n] & 0x00ff) + 1)));
|
||||||
|
m_pwm_timer[n]->adjust(clocks_to_attotime(prescale * ((m_cr[n] >> 8) + 1)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_timer[n]->adjust(clocks_to_attotime(prescale * (u32(m_cr[n]) + 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// timer_resume_count - start counting again
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::timer_resume_count(unsigned n)
|
||||||
|
{
|
||||||
|
if (!BIT(m_status[n], 5) || ((m_status[n] & 0x03) != 0x03 || BIT(m_gate_input, n)))
|
||||||
|
{
|
||||||
|
unsigned prescale = BIT(m_status[n], 1) ? 4 : BIT(m_status[n], 0) ? 16 : 256;
|
||||||
|
if ((m_status[n] & 0x0c) == 0x0c)
|
||||||
|
{
|
||||||
|
// PWM
|
||||||
|
m_timer[n]->adjust(clocks_to_attotime(prescale * ((m_last_count[n] & 0x00ff) + 1)));
|
||||||
|
m_pwm_timer[n]->adjust(clocks_to_attotime(prescale * ((m_last_count[n] >> 8) + 1)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_timer[n]->adjust(clocks_to_attotime(prescale * (u32(m_last_count[n]) + 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// timer_get_count - obtain the instant count in
|
||||||
|
// case of a readout or pause
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
u16 kp63_device::timer_get_count(unsigned n) const
|
||||||
|
{
|
||||||
|
if (!BIT(m_timer_started, n) || BIT(m_status[n], 5) || ((m_status[n] & 0x03) == 0x03 && !BIT(m_gate_input, n)))
|
||||||
|
return m_last_count[n];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned prescale = BIT(m_status[n], 1) ? 4 : BIT(m_status[n], 0) ? 16 : 256;
|
||||||
|
if ((m_status[n] & 0x0c) == 0x0c)
|
||||||
|
{
|
||||||
|
// PWM
|
||||||
|
u8 ticks = attotime_to_clocks(m_timer[n]->remaining()) / prescale;
|
||||||
|
return ticks | ((m_cr[n] - (u16(ticks) << 8)) & 0xff00);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return attotime_to_clocks(m_timer[n]->remaining()) / prescale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// read - read count or status register
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
u8 kp63_device::read(offs_t offset)
|
||||||
|
{
|
||||||
|
const unsigned n = offset >> 1;
|
||||||
|
assert(n < c_num_counters);
|
||||||
|
|
||||||
|
if (BIT(offset, 0))
|
||||||
|
{
|
||||||
|
// Status read clears read/write sequence
|
||||||
|
if (!machine().side_effects_disabled())
|
||||||
|
m_rw_seq &= ~(1 << n);
|
||||||
|
return m_status[n];
|
||||||
|
}
|
||||||
|
else if (BIT(m_rw_seq, n))
|
||||||
|
{
|
||||||
|
// Second step of counter readout
|
||||||
|
if (!machine().side_effects_disabled())
|
||||||
|
m_rw_seq &= ~(1 << n);
|
||||||
|
return m_count_tmp[n];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// First step of counter readout
|
||||||
|
u16 count = timer_get_count(n);
|
||||||
|
if (!machine().side_effects_disabled())
|
||||||
|
{
|
||||||
|
// Latch high byte into TMP register
|
||||||
|
m_rw_seq |= 1 << n;
|
||||||
|
m_count_tmp[n] = count >> 8;
|
||||||
|
}
|
||||||
|
return count & 0x00ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// write - set CR or mode register
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::write(offs_t offset, u8 data)
|
||||||
|
{
|
||||||
|
const unsigned n = offset >> 1;
|
||||||
|
assert(n < c_num_counters);
|
||||||
|
|
||||||
|
if (BIT(offset, 0))
|
||||||
|
{
|
||||||
|
bool old_outp = BIT(m_status[n], 7) != BIT(m_status[n], 4);
|
||||||
|
|
||||||
|
// Stop count before setting mode
|
||||||
|
if (BIT(m_timer_started, n))
|
||||||
|
{
|
||||||
|
if (!BIT(m_status[n], 5) || ((m_status[n] & 0x03) != 0x03 || BIT(m_gate_input, n)))
|
||||||
|
{
|
||||||
|
m_last_count[n] = timer_get_count(n);
|
||||||
|
m_timer[n]->adjust(attotime::never);
|
||||||
|
m_pwm_timer[n]->adjust(attotime::never);
|
||||||
|
}
|
||||||
|
m_timer_started &= ~(1 << n);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BIT(data & c_mode_mask, 5))
|
||||||
|
LOG("%s: Timer #%d configured for %s mode, %s edges of GATE, initial output %c\n",
|
||||||
|
machine().describe_context(),
|
||||||
|
n,
|
||||||
|
s_count_modes[BIT(data, 2, 2)],
|
||||||
|
BIT(data, 1) ? "???" : BIT(data, 0) ? "falling" : "rising",
|
||||||
|
BIT(data, 4) ? 'H' : 'L');
|
||||||
|
else
|
||||||
|
LOG("%s: Timer #%d configured for %s mode, 1/%d system clock (GATE %s), initial output %c\n",
|
||||||
|
machine().describe_context(),
|
||||||
|
n,
|
||||||
|
s_count_modes[BIT(data, 2, 2)],
|
||||||
|
BIT(data, 1) ? 4 : BIT(data, 0) ? 16 : 256,
|
||||||
|
(data == 0x03) == 0x03 ? "effective" : "ignored",
|
||||||
|
BIT(data, 4) ? 'H' : 'L');
|
||||||
|
m_status[n] = data & c_mode_mask;
|
||||||
|
|
||||||
|
// Update OUTP
|
||||||
|
if (old_outp != BIT(data, 4))
|
||||||
|
m_out_pulse_callback[n](BIT(data, 4) ? 1 : 0);
|
||||||
|
}
|
||||||
|
else if ((m_status[n] & 0x0c) == 0x08)
|
||||||
|
{
|
||||||
|
// WDT retrigger (data ignored; initial count must be written using a different mode)
|
||||||
|
timer_reload(n);
|
||||||
|
}
|
||||||
|
else if (BIT(m_rw_seq, n))
|
||||||
|
{
|
||||||
|
// Second step of initial count write
|
||||||
|
m_rw_seq &= ~(1 << n);
|
||||||
|
m_cr[n] = u16(data) << 8 | m_count_tmp[n];
|
||||||
|
|
||||||
|
LOG("%s: Timer #%d initial count = %d\n", machine().describe_context(), n, (m_status[n] == 0x0c) ? m_cr[n] & 0x00ff : m_cr[n]);
|
||||||
|
|
||||||
|
// Automatic retrigger in one-shot and continuous modes
|
||||||
|
if (!BIT(m_status[n], 3) || !BIT(m_timer_started, n))
|
||||||
|
{
|
||||||
|
if (!BIT(m_status[n], 7))
|
||||||
|
{
|
||||||
|
// Toggle OUTP
|
||||||
|
m_status[n] |= 0x80;
|
||||||
|
m_out_pulse_callback[n](BIT(m_status[n], 4) ? 0 : 1);
|
||||||
|
}
|
||||||
|
timer_reload(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// First step of initial count write (held in TMP register)
|
||||||
|
m_rw_seq |= 1 << n;
|
||||||
|
m_count_tmp[n] = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// write_gate - handle gate inputs
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void kp63_device::write_gate(unsigned n, bool state)
|
||||||
|
{
|
||||||
|
assert(n < c_num_counters);
|
||||||
|
|
||||||
|
if (BIT(m_gate_input, n) != state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (state)
|
||||||
|
m_gate_input |= 1 << n;
|
||||||
|
else
|
||||||
|
m_gate_input &= ~(1 << n);
|
||||||
|
|
||||||
|
if (BIT(m_timer_started, n))
|
||||||
|
{
|
||||||
|
if ((m_status[n] & 0x23) == 0x03)
|
||||||
|
{
|
||||||
|
// Timer gated on or off
|
||||||
|
if (state)
|
||||||
|
timer_resume_count(n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_last_count[n] = timer_get_count(n);
|
||||||
|
m_timer[n]->adjust(attotime::never);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((m_status[n] & 0x23) == (state ? 0x21 : 0x20))
|
||||||
|
{
|
||||||
|
// Count edges of gate input
|
||||||
|
if ((m_status[n] & 0x0c) == 0x0c)
|
||||||
|
{
|
||||||
|
// PWM: count is in lower 8 bits
|
||||||
|
if ((m_last_count[n] & 0x00ff) == 0)
|
||||||
|
timer_pulse(n);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Decrement both halves and check for underflow in upper half
|
||||||
|
m_last_count[n] -= 0x0101;
|
||||||
|
if (m_last_count[n] >= 0xff00)
|
||||||
|
{
|
||||||
|
m_status[n] &= 0x7f;
|
||||||
|
m_out_pulse_callback[n](BIT(m_status[n], 4) ? 1 : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (m_last_count[n]-- == 0)
|
||||||
|
timer_pulse(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
98
src/devices/cpu/z80/kp63.h
Normal file
98
src/devices/cpu/z80/kp63.h
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:AJR
|
||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
Kawasaki Steel (Kawatetsu) KP63(A) Timer/Counter
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#ifndef MAME_CPU_Z80_KP63_H
|
||||||
|
#define MAME_CPU_Z80_KP63_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
class kp63_device : public device_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// callback configuration
|
||||||
|
template <int N> auto outp_callback() { return m_out_pulse_callback[N].bind(); }
|
||||||
|
template <int N> auto outs_callback() { return m_out_strobe_callback[N].bind(); }
|
||||||
|
|
||||||
|
// register interface
|
||||||
|
u8 read(offs_t offset);
|
||||||
|
void write(offs_t offset, u8 data);
|
||||||
|
|
||||||
|
// input line interface
|
||||||
|
template <int N> DECLARE_WRITE_LINE_MEMBER(gate_w) { write_gate(N, state); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// construction/destruction
|
||||||
|
kp63_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 num_counters, u8 mode_mask);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_resolve_objects() override;
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const char *const s_count_modes[4];
|
||||||
|
|
||||||
|
// timer callbacks
|
||||||
|
template <int N> TIMER_CALLBACK_MEMBER(timer_expired);
|
||||||
|
template <int N> TIMER_CALLBACK_MEMBER(strobe_off);
|
||||||
|
template <int N> TIMER_CALLBACK_MEMBER(pwm_off);
|
||||||
|
|
||||||
|
// internal helpers
|
||||||
|
void timer_pulse(unsigned n);
|
||||||
|
void timer_reload(unsigned n);
|
||||||
|
void timer_resume_count(unsigned n);
|
||||||
|
u16 timer_get_count(unsigned n) const;
|
||||||
|
void write_gate(unsigned n, bool state);
|
||||||
|
|
||||||
|
// callback objects
|
||||||
|
devcb_write_line::array<4> m_out_pulse_callback;
|
||||||
|
devcb_write_line::array<4> m_out_strobe_callback;
|
||||||
|
|
||||||
|
// constant parameters
|
||||||
|
const u8 c_num_counters;
|
||||||
|
const u8 c_mode_mask;
|
||||||
|
|
||||||
|
// internal timers
|
||||||
|
emu_timer *m_timer[4];
|
||||||
|
emu_timer *m_strobe_timer[4];
|
||||||
|
emu_timer *m_pwm_timer[4];
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
u16 m_cr[4];
|
||||||
|
u16 m_last_count[4];
|
||||||
|
u8 m_count_tmp[4];
|
||||||
|
u8 m_status[4];
|
||||||
|
u8 m_rw_seq;
|
||||||
|
u8 m_timer_started;
|
||||||
|
u8 m_gate_input;
|
||||||
|
};
|
||||||
|
|
||||||
|
class kp63_3channel_device : public kp63_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// device type constructor
|
||||||
|
kp63_3channel_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
class kp63a_device : public kp63_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// device type constructor
|
||||||
|
kp63a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
// device type declarations
|
||||||
|
DECLARE_DEVICE_TYPE(KP63_3CHANNEL, kp63_3channel_device)
|
||||||
|
DECLARE_DEVICE_TYPE(KP63A, kp63a_device)
|
||||||
|
|
||||||
|
#endif // MAME_CPU_Z80_KP63_H
|
@ -107,12 +107,12 @@ void kp69_device::device_start()
|
|||||||
|
|
||||||
void kp69_base_device::add_to_state(device_state_interface &state, int index)
|
void kp69_base_device::add_to_state(device_state_interface &state, int index)
|
||||||
{
|
{
|
||||||
state.state_add<u16>(index, "IRR", [this]() { return m_irr; }, [this](u16 data) { set_irr(data); });
|
state.state_add(index, "IRR", m_irr, [this](u16 data) { set_irr(data); });
|
||||||
state.state_add<u16>(index + 1, "ISR", [this]() { return m_isr; }, [this](u16 data) { set_isr(data); });
|
state.state_add(index + 1, "ISR", m_isr, [this](u16 data) { set_isr(data); });
|
||||||
state.state_add(index + 2, "IVR", m_ivr).mask(0xe0);
|
state.state_add(index + 2, "IVR", m_ivr).mask(0xe0);
|
||||||
state.state_add<u16>(index + 3, "LER", [this]() { return m_ler; }, [this](u16 data) { set_ler(data); });
|
state.state_add(index + 3, "LER", m_ler, [this](u16 data) { set_ler(data); });
|
||||||
state.state_add<u16>(index + 4, "PGR", [this]() { return m_pgr; }, [this](u16 data) { set_pgr(data); });
|
state.state_add(index + 4, "PGR", m_pgr, [this](u16 data) { set_pgr(data); });
|
||||||
state.state_add<u16>(index + 5, "IMR", [this]() { return m_imr; }, [this](u16 data) { set_imr(data); });
|
state.state_add(index + 5, "IMR", m_imr, [this](u16 data) { set_imr(data); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ To Do:
|
|||||||
to "coin" (it probably changes the number of reads from port $C0).
|
to "coin" (it probably changes the number of reads from port $C0).
|
||||||
I guess the reset_delay mechanism should be implemented with a timer in eeprom.c.
|
I guess the reset_delay mechanism should be implemented with a timer in eeprom.c.
|
||||||
- pyenaget intro: when the theater scrolls out to the left, the train should scroll in from the right,
|
- pyenaget intro: when the theater scrolls out to the left, the train should scroll in from the right,
|
||||||
with no visible gaps. It currently leaves the screen empty instead, for several seconds.
|
with no visible gaps. It currently leaves a small gap.
|
||||||
- tdoboon: no smoke from hit planes as shown in the video? Tiles are present (f60-125f) and used in demo mode.
|
- tdoboon: no smoke from hit planes as shown in the video? Tiles are present (f60-125f) and used in demo mode.
|
||||||
- dashhero does not acknowledge the button bashing correctly, it's very hard to win (a slower pace works better!)
|
- dashhero does not acknowledge the button bashing correctly, it's very hard to win (a slower pace works better!)
|
||||||
- dodghero and sushimar often write zeroes to 81XX1 and 00XX1 for some reason (maybe just sloppy coding?)
|
- dodghero and sushimar often write zeroes to 81XX1 and 00XX1 for some reason (maybe just sloppy coding?)
|
||||||
@ -283,6 +283,7 @@ public:
|
|||||||
sammymdl_state(const machine_config &mconfig, device_type type, const char *tag)
|
sammymdl_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||||
: sigmab98_base_state(mconfig, type, tag)
|
: sigmab98_base_state(mconfig, type, tag)
|
||||||
, m_maincpu(*this, "maincpu")
|
, m_maincpu(*this, "maincpu")
|
||||||
|
, m_kp69(*this, "maincpu:kp69")
|
||||||
, m_eeprom(*this, "eeprom")
|
, m_eeprom(*this, "eeprom")
|
||||||
, m_hopper(*this, "hopper")
|
, m_hopper(*this, "hopper")
|
||||||
, m_hopper_small(*this, "hopper_small")
|
, m_hopper_small(*this, "hopper_small")
|
||||||
@ -301,13 +302,13 @@ public:
|
|||||||
void init_itazuram();
|
void init_itazuram();
|
||||||
void init_animalc();
|
void init_animalc();
|
||||||
void init_haekaka();
|
void init_haekaka();
|
||||||
void init_gocowboy();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void machine_start() override { m_leds.resolve(); }
|
virtual void machine_start() override { m_leds.resolve(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TIMER_DEVICE_CALLBACK_MEMBER(sammymdl_irq);
|
TIMER_DEVICE_CALLBACK_MEMBER(gocowboy_int);
|
||||||
|
TIMER_DEVICE_CALLBACK_MEMBER(timer_1khz);
|
||||||
|
|
||||||
uint8_t coin_counter_r();
|
uint8_t coin_counter_r();
|
||||||
void coin_counter_w(uint8_t data);
|
void coin_counter_w(uint8_t data);
|
||||||
@ -339,6 +340,7 @@ private:
|
|||||||
|
|
||||||
// Required devices
|
// Required devices
|
||||||
required_device<kl5c80a12_device> m_maincpu;
|
required_device<kl5c80a12_device> m_maincpu;
|
||||||
|
required_device<kp69_device> m_kp69;
|
||||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||||
|
|
||||||
// Optional devices
|
// Optional devices
|
||||||
@ -348,10 +350,6 @@ private:
|
|||||||
|
|
||||||
output_finder<8> m_leds;
|
output_finder<8> m_leds;
|
||||||
|
|
||||||
uint8_t m_vblank_vector;
|
|
||||||
uint8_t m_timer0_vector;
|
|
||||||
uint8_t m_timer1_vector;
|
|
||||||
|
|
||||||
uint8_t m_out[3];
|
uint8_t m_out[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -946,7 +944,7 @@ uint8_t sigmab98_base_state::vblank_r()
|
|||||||
{
|
{
|
||||||
// mask 0x04 must be set before writing sprite list
|
// mask 0x04 must be set before writing sprite list
|
||||||
// mask 0x10 must be set or irq/00 hangs?
|
// mask 0x10 must be set or irq/00 hangs?
|
||||||
return m_vblank | 0x14;
|
return (m_vblank & ~0x01) | 0x14;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sigmab98_base_state::vblank_w(uint8_t data)
|
void sigmab98_base_state::vblank_w(uint8_t data)
|
||||||
@ -1632,23 +1630,29 @@ void lufykzku_state::lufykzku(machine_config &config)
|
|||||||
Sammy Medal Games
|
Sammy Medal Games
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
TIMER_DEVICE_CALLBACK_MEMBER(sammymdl_state::sammymdl_irq)
|
TIMER_DEVICE_CALLBACK_MEMBER(sammymdl_state::gocowboy_int)
|
||||||
{
|
{
|
||||||
int scanline = param;
|
int scanline = param;
|
||||||
uint16_t irqs = 0;
|
|
||||||
|
|
||||||
|
// TODO: what really triggers these?
|
||||||
if (scanline == 240)
|
if (scanline == 240)
|
||||||
irqs |= 1 << ((m_vblank_vector & 0x1e) >> 1);
|
{
|
||||||
|
m_kp69->ir_w<0>(1);
|
||||||
|
m_kp69->ir_w<0>(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (scanline == 128)
|
if (scanline == 128)
|
||||||
irqs |= 1 << ((m_timer0_vector & 0x1e) >> 1);
|
{
|
||||||
|
m_kp69->ir_w<1>(1);
|
||||||
|
m_kp69->ir_w<1>(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (scanline == 32)
|
TIMER_DEVICE_CALLBACK_MEMBER(sammymdl_state::timer_1khz)
|
||||||
irqs |= 1 << ((m_timer1_vector & 0x1e) >> 1);
|
{
|
||||||
|
// FIXME: this is an internally generated timer interrupt
|
||||||
// FIXME: this is not much less of a hack than HOLD_LINE
|
m_kp69->ir_w<11>(1);
|
||||||
if (irqs != 0)
|
m_kp69->ir_w<11>(0);
|
||||||
m_maincpu->set_state_int(kl5c80a12_device::KP69_IRR, m_maincpu->state_int(kl5c80a12_device::KP69_IRR) | irqs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sammymdl_state::sammymdl(machine_config &config)
|
void sammymdl_state::sammymdl(machine_config &config)
|
||||||
@ -1657,8 +1661,6 @@ void sammymdl_state::sammymdl(machine_config &config)
|
|||||||
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::animalc_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::animalc_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::animalc_io);
|
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::animalc_io);
|
||||||
|
|
||||||
TIMER(config, "scantimer").configure_scanline(FUNC(sammymdl_state::sammymdl_irq), "screen", 0, 1);
|
|
||||||
|
|
||||||
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // battery backed RAM
|
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0); // battery backed RAM
|
||||||
EEPROM_93C46_8BIT(config, "eeprom");
|
EEPROM_93C46_8BIT(config, "eeprom");
|
||||||
|
|
||||||
@ -1673,7 +1675,7 @@ void sammymdl_state::sammymdl(machine_config &config)
|
|||||||
m_screen->set_size(0x140, 0x100);
|
m_screen->set_size(0x140, 0x100);
|
||||||
m_screen->set_visarea(0, 0x140-1, 0, 0xf0-1);
|
m_screen->set_visarea(0, 0x140-1, 0, 0xf0-1);
|
||||||
m_screen->set_screen_update(FUNC(sammymdl_state::screen_update));
|
m_screen->set_screen_update(FUNC(sammymdl_state::screen_update));
|
||||||
m_screen->screen_vblank().set(FUNC(sammymdl_state::screen_vblank_sammymdl));
|
m_screen->screen_vblank().set(m_kp69, FUNC(kp69_device::ir_w<0>));
|
||||||
m_screen->set_palette(m_palette);
|
m_screen->set_palette(m_palette);
|
||||||
|
|
||||||
GFXDECODE(config, m_gfxdecode, m_palette, gfx_sigmab98);
|
GFXDECODE(config, m_gfxdecode, m_palette, gfx_sigmab98);
|
||||||
@ -1706,9 +1708,14 @@ void sammymdl_state::gocowboy(machine_config &config)
|
|||||||
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::gocowboy_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::gocowboy_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::gocowboy_io);
|
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::gocowboy_io);
|
||||||
|
|
||||||
|
TIMER(config, "scantimer").configure_scanline(FUNC(sammymdl_state::gocowboy_int), "screen", 0, 1);
|
||||||
|
TIMER(config, "1khztimer").configure_periodic(FUNC(sammymdl_state::timer_1khz), attotime::from_msec(1));
|
||||||
|
|
||||||
config.device_remove("hopper");
|
config.device_remove("hopper");
|
||||||
TICKET_DISPENSER(config, m_hopper_small, attotime::from_msec(1000), TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_LOW );
|
TICKET_DISPENSER(config, m_hopper_small, attotime::from_msec(200), TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_LOW );
|
||||||
TICKET_DISPENSER(config, m_hopper_large, attotime::from_msec(1000), TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_LOW );
|
TICKET_DISPENSER(config, m_hopper_large, attotime::from_msec(200), TICKET_MOTOR_ACTIVE_LOW, TICKET_STATUS_ACTIVE_LOW );
|
||||||
|
|
||||||
|
m_screen->screen_vblank().set_nop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sammymdl_state::haekaka(machine_config &config)
|
void sammymdl_state::haekaka(machine_config &config)
|
||||||
@ -1717,14 +1724,21 @@ void sammymdl_state::haekaka(machine_config &config)
|
|||||||
|
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::haekaka_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::haekaka_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::haekaka_io);
|
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::haekaka_io);
|
||||||
|
|
||||||
|
m_screen->screen_vblank().set(m_kp69, FUNC(kp69_device::ir_w<2>));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sammymdl_state::itazuram(machine_config &config)
|
void sammymdl_state::itazuram(machine_config &config)
|
||||||
{
|
{
|
||||||
sammymdl(config);
|
sammymdl(config);
|
||||||
|
|
||||||
|
TIMER(config, "scantimer").configure_scanline(FUNC(sammymdl_state::gocowboy_int), "screen", 0, 1);
|
||||||
|
TIMER(config, "1khztimer").configure_periodic(FUNC(sammymdl_state::timer_1khz), attotime::from_msec(1));
|
||||||
|
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::itazuram_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::itazuram_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::itazuram_io);
|
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::itazuram_io);
|
||||||
|
|
||||||
|
m_screen->screen_vblank().set_nop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sammymdl_state::pyenaget(machine_config &config)
|
void sammymdl_state::pyenaget(machine_config &config)
|
||||||
@ -1733,6 +1747,8 @@ void sammymdl_state::pyenaget(machine_config &config)
|
|||||||
|
|
||||||
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::haekaka_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::haekaka_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::pyenaget_io);
|
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::pyenaget_io);
|
||||||
|
|
||||||
|
m_screen->screen_vblank().set(m_kp69, FUNC(kp69_device::ir_w<2>));
|
||||||
}
|
}
|
||||||
|
|
||||||
void sammymdl_state::tdoboon(machine_config &config)
|
void sammymdl_state::tdoboon(machine_config &config)
|
||||||
@ -1742,6 +1758,7 @@ void sammymdl_state::tdoboon(machine_config &config)
|
|||||||
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::tdoboon_map);
|
m_maincpu->set_addrmap(AS_PROGRAM, &sammymdl_state::tdoboon_map);
|
||||||
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::tdoboon_io);
|
m_maincpu->set_addrmap(AS_IO, &sammymdl_state::tdoboon_io);
|
||||||
|
|
||||||
|
m_screen->screen_vblank().set(m_kp69, FUNC(kp69_device::ir_w<2>));
|
||||||
m_screen->set_visarea(0,0x140-1, 0+4,0xf0+4-1);
|
m_screen->set_visarea(0,0x140-1, 0+4,0xf0+4-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2184,10 +2201,6 @@ void sammymdl_state::init_animalc()
|
|||||||
|
|
||||||
// force jump out of BIOS loop
|
// force jump out of BIOS loop
|
||||||
rom[0x005ac] = 0xc3;
|
rom[0x005ac] = 0xc3;
|
||||||
|
|
||||||
m_vblank_vector = 0x00; // increment counter
|
|
||||||
m_timer0_vector = 0x1c; // read hopper state
|
|
||||||
m_timer1_vector = 0x1e; // drive hopper motor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -2225,13 +2238,6 @@ ROM_START( gocowboy )
|
|||||||
ROM_LOAD( "vm1212f01.u5.jed", 0x0000, 0x5cde, CRC(b86a1825) SHA1(cc2e633fb8a24cfc93291a778b0964089f6b8ac7) )
|
ROM_LOAD( "vm1212f01.u5.jed", 0x0000, 0x5cde, CRC(b86a1825) SHA1(cc2e633fb8a24cfc93291a778b0964089f6b8ac7) )
|
||||||
ROM_END
|
ROM_END
|
||||||
|
|
||||||
void sammymdl_state::init_gocowboy()
|
|
||||||
{
|
|
||||||
m_vblank_vector = 0x00;
|
|
||||||
m_timer0_vector = 0x02;
|
|
||||||
m_timer1_vector = 0x16;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
||||||
Itazura Monkey ( VX1902L02 ITZRMONKY 200011211639 SAMMY CORP. AM )
|
Itazura Monkey ( VX1902L02 ITZRMONKY 200011211639 SAMMY CORP. AM )
|
||||||
@ -2260,10 +2266,6 @@ void sammymdl_state::init_itazuram()
|
|||||||
|
|
||||||
// force jump out of BIOS loop
|
// force jump out of BIOS loop
|
||||||
rom[0x005ac] = 0xc3;
|
rom[0x005ac] = 0xc3;
|
||||||
|
|
||||||
m_vblank_vector = 0x00;
|
|
||||||
m_timer0_vector = 0x02;
|
|
||||||
m_timer1_vector = 0x16;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -2366,10 +2368,6 @@ void sammymdl_state::init_haekaka()
|
|||||||
|
|
||||||
// force jump out of BIOS loop
|
// force jump out of BIOS loop
|
||||||
rom[0x005ac] = 0xc3;
|
rom[0x005ac] = 0xc3;
|
||||||
|
|
||||||
m_vblank_vector = 0x04;
|
|
||||||
m_timer0_vector = 0x1a;
|
|
||||||
m_timer1_vector = 0x1c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -2396,4 +2394,4 @@ GAME( 2000, itazuram, sammymdl, itazuram, sammymdl, sammymdl_state, init_itazura
|
|||||||
GAME( 2000, pyenaget, sammymdl, pyenaget, sammymdl, sammymdl_state, init_haekaka, ROT0, "Sammy", "Pye-nage Taikai", 0 )
|
GAME( 2000, pyenaget, sammymdl, pyenaget, sammymdl, sammymdl_state, init_haekaka, ROT0, "Sammy", "Pye-nage Taikai", 0 )
|
||||||
GAME( 2000, tdoboon, sammymdl, tdoboon, haekaka, sammymdl_state, init_haekaka, ROT0, "Sammy", "Taihou de Doboon", 0 )
|
GAME( 2000, tdoboon, sammymdl, tdoboon, haekaka, sammymdl_state, init_haekaka, ROT0, "Sammy", "Taihou de Doboon", 0 )
|
||||||
GAME( 2001, haekaka, sammymdl, haekaka, haekaka, sammymdl_state, init_haekaka, ROT0, "Sammy", "Hae Hae Ka Ka Ka", 0 )
|
GAME( 2001, haekaka, sammymdl, haekaka, haekaka, sammymdl_state, init_haekaka, ROT0, "Sammy", "Hae Hae Ka Ka Ka", 0 )
|
||||||
GAME( 2003, gocowboy, 0, gocowboy, gocowboy, sammymdl_state, init_gocowboy, ROT0, "Sammy", "Go Go Cowboy (English, prize)", 0 )
|
GAME( 2003, gocowboy, 0, gocowboy, gocowboy, sammymdl_state, empty_init, ROT0, "Sammy", "Go Go Cowboy (English, prize)", 0 )
|
||||||
|
Loading…
Reference in New Issue
Block a user