-igs/igs027a.cpp: Started encapsulating IGS 027A onboard peripherals.

-igs/igs_m027.cpp: Improved I/O:
* Hooked up inputs, hopper and counters for mgcs3.
* Hooked up mahjong keyboard for lhzb4.
* Added more RAM for extradrw.

-Bumped GitHub CI to three simuataneous jobs for Windows and Linux -
 this should be OK with 16GB RAM.

-Added out-of-line destructors to various device classes that aren't
 templates and aren't in anonymous namespaces.
This commit is contained in:
Vas Crabb 2024-09-13 06:30:17 +10:00
parent 98d6cb788e
commit 21a89d5bbd
29 changed files with 394 additions and 224 deletions

View file

@ -58,7 +58,7 @@ jobs:
ARCHOPTS: ${{ matrix.archopts }}
SUBTARGET: ${{ matrix.subtarget }}
TOOLS: 1
run: make -j2
run: make -j3
- name: Validate
run: ./${{ matrix.executable }} -validate
- name: Reconcile driver list

View file

@ -56,7 +56,7 @@ jobs:
ARCHOPTS: "-fuse-ld=lld"
SUBTARGET: ${{ matrix.subtarget }}
TOOLS: 1
run: make -j2
run: make -j3
- name: Validate
run: ./${{ matrix.executable }}.exe -validate
- uses: actions/upload-artifact@master

View file

@ -83,9 +83,17 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, const char *tag,
{
}
arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness)
arm7_cpu_device::arm7_cpu_device(
const machine_config &mconfig,
device_type type,
const char *tag, device_t *owner,
uint32_t clock,
uint8_t archRev,
uint32_t archFlags,
endianness_t endianness,
address_map_constructor internal_map)
: cpu_device(mconfig, type, tag, owner, clock)
, m_program_config("program", endianness, 32, 32, 0)
, m_program_config("program", endianness, 32, 32, 0, internal_map)
, m_prefetch_word0_shift(endianness == ENDIANNESS_LITTLE ? 0 : 16)
, m_prefetch_word1_shift(endianness == ENDIANNESS_LITTLE ? 16 : 0)
, m_endian(endianness)
@ -113,6 +121,10 @@ arm7_cpu_device::arm7_cpu_device(const machine_config &mconfig, device_type type
m_actual_log = 0;
}
arm7_cpu_device::~arm7_cpu_device()
{
}
arm7_be_cpu_device::arm7_be_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: arm7_cpu_device(mconfig, ARM7_BE, tag, owner, clock, 4, ARCHFLAG_T, ENDIANNESS_BIG)

View file

@ -52,6 +52,7 @@ class arm7_cpu_device : public cpu_device, public arm7_disassembler::config
public:
// construction/destruction
arm7_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~arm7_cpu_device();
void set_high_vectors() { m_vectorbase = 0xffff0000; }
@ -113,7 +114,16 @@ protected:
ARM9_COPRO_ID_MFR_INTEL = 0x69 << 24
};
arm7_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t archRev, uint32_t archFlags, endianness_t endianness);
arm7_cpu_device(
const machine_config &mconfig,
device_type type,
const char *tag,
device_t *owner,
uint32_t clock,
uint8_t archRev,
uint32_t archFlags,
endianness_t endianness,
address_map_constructor internal_map = address_map_constructor());
void postload();

View file

@ -45,6 +45,10 @@ fifo2812_device::fifo2812_device(machine_config const &mconfig, char const *tag,
std::fill(std::begin(m_data), std::end(m_data), 0U);
}
fifo2812_device::~fifo2812_device()
{
}
void fifo2812_device::mr_w(int state)
{

View file

@ -33,6 +33,7 @@ class fifo2812_device : public device_t
public:
// standard constructor
fifo2812_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0);
virtual ~fifo2812_device();
// callbacks
auto q_cb() { return m_q_cb.bind(); }

View file

@ -291,6 +291,10 @@ at_kbc_device_base::at_kbc_device_base(machine_config const &mconfig, device_typ
{
}
at_kbc_device_base::~at_kbc_device_base()
{
}
void at_kbc_device_base::device_start()
{
save_item(NAME(m_hot_res));
@ -376,6 +380,10 @@ at_keyboard_controller_device::at_keyboard_controller_device(machine_config cons
{
}
at_keyboard_controller_device::~at_keyboard_controller_device()
{
}
tiny_rom_entry const *at_keyboard_controller_device::device_rom_region() const
{
return ROM_NAME(at_kbc);
@ -452,6 +460,10 @@ ps2_keyboard_controller_device::ps2_keyboard_controller_device(machine_config co
{
}
ps2_keyboard_controller_device::~ps2_keyboard_controller_device()
{
}
tiny_rom_entry const *ps2_keyboard_controller_device::device_rom_region() const
{
return ROM_NAME(ps2_kbc);

View file

@ -20,6 +20,8 @@
class at_kbc_device_base : public device_t
{
public:
virtual ~at_kbc_device_base();
// outputs to host
auto hot_res() { return m_hot_res_cb.bind(); }
auto gate_a20() { return m_gate_a20_cb.bind(); }
@ -83,6 +85,7 @@ class at_keyboard_controller_device : public at_kbc_device_base
public:
// standard constructor
at_keyboard_controller_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
virtual ~at_keyboard_controller_device();
protected:
// device_t implementation
@ -120,6 +123,7 @@ public:
// standard constructor
ps2_keyboard_controller_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
virtual ~ps2_keyboard_controller_device();
protected:
// device_t implementation

View file

@ -19,6 +19,8 @@
class input_merger_device : public device_t
{
public:
virtual ~input_merger_device() override;
// configuration
auto output_handler() { return m_output_handler.bind(); }
@ -38,7 +40,6 @@ protected:
u32 initval,
u32 xorval,
int active);
virtual ~input_merger_device() override;
// device-level overrides
virtual void device_start() override;

View file

@ -261,6 +261,10 @@ generic_keyboard_device::generic_keyboard_device(
{
}
generic_keyboard_device::~generic_keyboard_device()
{
}
generic_keyboard_device::generic_keyboard_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: generic_keyboard_device(mconfig, GENERIC_KEYBOARD, tag, owner, clock)

View file

@ -78,6 +78,7 @@ public:
const char *tag,
device_t *owner,
u32 clock);
virtual ~generic_keyboard_device();
template <typename... T>
void set_keyboard_callback(T &&... args)

View file

@ -168,6 +168,10 @@ micom_xe_1a_device::micom_xe_1a_device(
{
}
micom_xe_1a_device::~micom_xe_1a_device()
{
}
u8 micom_xe_1a_device::out_r()
{

View file

@ -15,6 +15,7 @@ class micom_xe_1a_device : public device_t
{
public:
micom_xe_1a_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0) ATTR_COLD;
virtual ~micom_xe_1a_device();
auto buttons_handler() { return m_buttons_callback.bind(); }
auto analog_handler() { return m_analog_callback.bind(); }

View file

@ -145,6 +145,10 @@ s2350_device::s2350_device(const machine_config &mconfig, const char *tag, devic
{
}
s2350_device::~s2350_device()
{
}
void s2350_device::device_start()
{
save_item(NAME(m_transmit_buffer_empty));

View file

@ -21,6 +21,7 @@ class s2350_device : public device_t
{
public:
s2350_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
virtual ~s2350_device();
// transmit bits
auto tx_handler() { return m_tx_cb.bind(); }

View file

@ -180,6 +180,10 @@ s2636_device::s2636_device(const machine_config &mconfig, const char *tag, devic
for (auto &elem : m_obj_dup) elem = false;
}
s2636_device::~s2636_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------

View file

@ -28,6 +28,7 @@ class s2636_device : public device_t,
{
public:
s2636_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~s2636_device();
void set_offsets(int y_offset, int x_offset) { m_x_offset = x_offset; m_y_offset = y_offset; }

View file

@ -37,6 +37,10 @@ device_sdlc_consumer_interface::device_sdlc_consumer_interface(machine_config co
{
}
device_sdlc_consumer_interface::~device_sdlc_consumer_interface()
{
}
void device_sdlc_consumer_interface::interface_post_start()
{
device().save_item(NAME(m_line_active));
@ -139,6 +143,10 @@ sdlc_logger_device::sdlc_logger_device(machine_config const &mconfig, char const
{
}
sdlc_logger_device::~sdlc_logger_device()
{
}
void sdlc_logger_device::clock_w(int state)
{
if (bool(state) != bool(m_current_clock))

View file

@ -23,6 +23,7 @@ public:
protected:
device_sdlc_consumer_interface(machine_config const &mconfig, device_t &device);
virtual ~device_sdlc_consumer_interface();
virtual void interface_post_start() override;
@ -55,6 +56,7 @@ class sdlc_logger_device : public device_t, public device_sdlc_consumer_interfac
{
public:
sdlc_logger_device(machine_config const &mconfig, char const *tag, device_t *owner, std::uint32_t clock);
virtual ~sdlc_logger_device();
// input signals
void data_w(int state) { m_current_data = state ? 1U : 0U; }

View file

@ -139,6 +139,10 @@ qsound_device::qsound_device(machine_config const &mconfig, char const *tag, dev
{
}
qsound_device::~qsound_device()
{
}
void qsound_device::qsound_w(offs_t offset, u8 data)
{

View file

@ -19,6 +19,7 @@ class qsound_device : public device_t, public device_sound_interface, public dev
public:
// default 60MHz clock (divided by 2 for DSP core clock, and then by 1248 for sample rate)
qsound_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 60'000'000);
virtual ~qsound_device();
void qsound_w(offs_t offset, u8 data);
u8 qsound_r();

View file

@ -194,6 +194,10 @@ dl1414_device::dl1414_device(
{
}
dl1414_device::~dl1414_device()
{
}
dl1416_device::dl1416_device(
machine_config const &mconfig,
device_type type,
@ -208,6 +212,10 @@ dl1416_device::dl1416_device(
{
}
dl1416_device::~dl1416_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------

View file

@ -33,6 +33,8 @@ DECLARE_DEVICE_TYPE(DL1416T, dl1416_device)
class dl1414_device : public device_t
{
public:
virtual ~dl1414_device();
auto update() { return m_update_cb.bind(); }
// signal-level interface
@ -51,7 +53,7 @@ protected:
device_t *owner,
u32 clock);
// device-level overrides
// device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
@ -76,6 +78,8 @@ private:
class dl1416_device : public dl1414_device
{
public:
virtual ~dl1416_device();
virtual void wr_w(int state) override;
void ce_w(int state); // chip enable (active low)
void cu_w(int state); // cursor enable (active low)

108
src/mame/igs/igs027a.cpp Normal file
View file

@ -0,0 +1,108 @@
// license:BSD-3-Clause
// copyright-holders:XingXing, Vas Crabb
#include "emu.h"
#include "igs027a.h"
#include "cpu/arm7/arm7core.h"
DEFINE_DEVICE_TYPE(IGS027A, igs027a_cpu_device, "igs027a", "IGS 027A ARM CPU (little)")
igs027a_cpu_device::igs027a_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
arm7_cpu_device(
mconfig,
IGS027A,
tag,
owner,
clock,
4,
ARCHFLAG_T,
ENDIANNESS_LITTLE,
address_map_constructor(FUNC(igs027a_cpu_device::onboard_peripherals), this)),
m_irq_timers{ nullptr, nullptr },
m_irq_enable(0xff),
m_irq_pending(0xff)
{
}
igs027a_cpu_device::~igs027a_cpu_device()
{
}
void igs027a_cpu_device::trigger_irq(unsigned num)
{
if (!BIT(m_irq_enable, num))
{
m_irq_pending &= ~(u8(1) << num);
pulse_input_line(ARM7_IRQ_LINE, minimum_quantum_time());
}
}
void igs027a_cpu_device::device_start()
{
arm7_cpu_device::device_start();
m_irq_timers[0] = timer_alloc(FUNC(igs027a_cpu_device::timer_irq<0>), this);
m_irq_timers[1] = timer_alloc(FUNC(igs027a_cpu_device::timer_irq<1>), this);
save_item(NAME(m_irq_enable));
save_item(NAME(m_irq_pending));
}
void igs027a_cpu_device::device_reset()
{
arm7_cpu_device::device_reset();
m_irq_enable = 0xff;
m_irq_pending = 0xff;
}
void igs027a_cpu_device::onboard_peripherals(address_map &map)
{
map(0x0000'0000, 0x0000'3fff).rom().region(DEVICE_SELF, 0);
map(0x7000'0100, 0x7000'0103).umask32(0x0000'00ff).w(FUNC(igs027a_cpu_device::timer_rate_w<0>));
map(0x7000'0104, 0x7000'0107).umask32(0x0000'00ff).w(FUNC(igs027a_cpu_device::timer_rate_w<1>));
map(0x7000'0200, 0x7000'0203).umask32(0x0000'00ff).rw(FUNC(igs027a_cpu_device::irq_pending_r), FUNC(igs027a_cpu_device::irq_enable_w));
map(0xf000'0008, 0xf000'000b).umask32(0x0000'00ff).w(FUNC(igs027a_cpu_device::bus_sizing_w));
}
template <unsigned N>
void igs027a_cpu_device::timer_rate_w(u8 data)
{
// TODO: determine how timer intervals are derived from clocks
m_irq_timers[N]->adjust(attotime::from_hz(data / 2), 0, attotime::from_hz(data / 2));
}
u8 igs027a_cpu_device::irq_pending_r()
{
u8 const result = m_irq_pending;
if (!machine().side_effects_disabled())
m_irq_pending = 0xff;
return result;
}
void igs027a_cpu_device::irq_enable_w(u8 data)
{
m_irq_enable = data;
}
void igs027a_cpu_device::bus_sizing_w(u8 data)
{
logerror("Bus sizing configuration: 0x%02x\n", data);
}
template <unsigned N>
TIMER_CALLBACK_MEMBER(igs027a_cpu_device::timer_irq)
{
trigger_irq(N);
}

43
src/mame/igs/igs027a.h Normal file
View file

@ -0,0 +1,43 @@
// license:BSD-3-Clause
// copyright-holders:XingXing, Vas Crabb
#ifndef MAME_IGS_IGS027A_H
#define MAME_IGS_IGS027A_H
#pragma once
#include "cpu/arm7/arm7.h"
class igs027a_cpu_device : public arm7_cpu_device
{
public:
igs027a_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
virtual ~igs027a_cpu_device();
void trigger_irq(unsigned num);
protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
private:
void onboard_peripherals(address_map &map) ATTR_COLD;
template <unsigned N> void timer_rate_w(u8 data);
u8 irq_pending_r();
void irq_enable_w(u8 data);
void bus_sizing_w(u8 data);
template <unsigned N> TIMER_CALLBACK_MEMBER(timer_irq);
emu_timer *m_irq_timers[2];
u8 m_irq_enable;
u8 m_irq_pending;
};
DECLARE_DEVICE_TYPE(IGS027A, igs027a_cpu_device)
#endif // MAME_IGS_IGS027A_H

View file

@ -7,9 +7,9 @@
#include "emu.h"
#include "igs027a.h"
#include "pgmcrypt.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "cpu/xa/xa.h"
#include "machine/nvram.h"
@ -79,14 +79,6 @@ private:
u32 igs027_gpio_r(offs_t offset, u32 mem_mask);
void igs027_gpio_w(offs_t offset, u32 data, u32 mem_mask);
TIMER_CALLBACK_MEMBER(igs027_timer0);
TIMER_CALLBACK_MEMBER(igs027_timer1);
void igs027_periph_init(void);
void igs027_trigger_irq(int num);
u32 igs027_periph_r(offs_t offset, u32 mem_mask);
void igs027_periph_w(offs_t offset, u32 data, u32 mem_mask);
u32 xa_r(offs_t offset, u32 mem_mask);
void xa_w(offs_t offset, u32 data, u32 mem_mask);
void cpld_w(offs_t offset, u32 data, u32 mem_mask);
@ -107,7 +99,7 @@ private:
required_shared_ptr<uint32_t> m_sram;
required_shared_ptr<u32> m_videoram;
required_device<cpu_device> m_maincpu;
required_device<igs027a_cpu_device> m_maincpu;
required_device<mx10exa_cpu_device> m_xa;
required_device<ics2115_device> m_ics;
required_device<screen_device> m_screen;
@ -118,17 +110,12 @@ private:
required_ioport_array<2> m_io_dsw;
optional_ioport_array<2> m_io_trackball;
emu_timer *m_timer0;
emu_timer *m_timer1;
u32 m_xor_table[0x100];
u8 m_port2_latch;
u8 m_port0_latch;
u32 m_gpio_o;
u32 m_irq_enable;
u32 m_irq_pending;
u32 m_xa_cmd;
u32 m_xa_ret0;
@ -147,7 +134,6 @@ private:
void igs_fear_state::video_start()
{
igs027_periph_init();
}
void igs_fear_state::machine_start()
@ -160,8 +146,6 @@ void igs_fear_state::machine_start()
save_item(NAME(m_port0_latch));
save_item(NAME(m_gpio_o));
save_item(NAME(m_irq_enable));
save_item(NAME(m_irq_pending));
save_item(NAME(m_xa_cmd));
save_item(NAME(m_xa_ret0));
@ -180,8 +164,6 @@ void igs_fear_state::machine_reset()
m_port0_latch = 0;
m_gpio_o = 0;
m_irq_enable = 0;
m_irq_pending = 0;
m_xa_cmd = 0;
m_xa_ret0 = 0;
@ -255,7 +237,6 @@ u32 igs_fear_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
void igs_fear_state::main_map(address_map &map)
{
map(0x00000000, 0x00003fff).rom(); // Internal ROM
map(0x08000000, 0x0807ffff).rom().region("user1", 0); // Game ROM
map(0x10000000, 0x100003ff).ram().share("iram");
map(0x18000000, 0x1800ffff).ram().share(m_sram);
@ -273,8 +254,6 @@ void igs_fear_state::main_map(address_map &map)
map(0x58100000, 0x58100003).portr("IN1");
map(0x68000000, 0x6800000f).w(FUNC(igs_fear_state::cpld_w));
map(0x70000000, 0x700003ff).rw(FUNC(igs_fear_state::igs027_periph_r), FUNC(igs_fear_state::igs027_periph_w));
}
void igs_fear_state::main_xor_map(address_map &map)
@ -482,74 +461,6 @@ void igs_fear_state::igs027_gpio_w(offs_t offset, u32 data, u32 mem_mask)
}
}
void igs_fear_state::igs027_periph_init()
{
m_irq_enable = 0xff;
m_irq_pending = 0xff;
m_timer0 = timer_alloc(FUNC(igs_fear_state::igs027_timer0), this);
m_timer1 = timer_alloc(FUNC(igs_fear_state::igs027_timer1), this);
}
void igs_fear_state::igs027_trigger_irq(int num)
{
if (!BIT(m_irq_enable, num))
{
m_irq_pending &= ~(u32(1) << num);
m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time());
}
}
TIMER_CALLBACK_MEMBER(igs_fear_state::igs027_timer0)
{
igs027_trigger_irq(0);
}
TIMER_CALLBACK_MEMBER(igs_fear_state::igs027_timer1)
{
igs027_trigger_irq(1);
}
void igs_fear_state::igs027_periph_w(offs_t offset, u32 data, u32 mem_mask)
{
switch (offset * 4)
{
case 0x100:
// TODO: verify the timer interval
m_timer0->adjust(attotime::from_hz(data / 2), 0, attotime::from_hz(data / 2));
break;
case 0x104:
m_timer1->adjust(attotime::from_hz(data / 2), 0, attotime::from_hz(data / 2));
break;
case 0x200:
m_irq_enable = data;
break;
default:
LOGMASKED(LOG_DEBUG, "%s: unhandled igs027_periph_w %04x %08x (%08x)\n", machine().describe_context(), offset * 4, data, mem_mask);
break;
}
}
u32 igs_fear_state::igs027_periph_r(offs_t offset, u32 mem_mask)
{
u32 data = ~u32(0);
switch (offset * 4)
{
case 0x200:
data = m_irq_pending;
m_irq_pending = 0xff;
break;
default:
LOGMASKED(LOG_DEBUG, "%s: unhandled igs027_periph_r %04x (%08x)\n", machine().describe_context(), offset * 4, mem_mask);
break;
}
return data;
}
// TODO: trackball support in XA
u32 igs_fear_state::xa_r(offs_t offset, u32 mem_mask)
{
@ -694,7 +605,7 @@ void igs_fear_state::mcu_p1_w(uint8_t data)
if (posedge(olddata, m_port1_dat, 3))
{
igs027_trigger_irq(3);
m_maincpu->trigger_irq(3);
}
}
@ -753,10 +664,10 @@ void igs_fear_state::mcu_p3_w(uint8_t data)
void igs_fear_state::igs_fear(machine_config &config)
{
ARM7(config, m_maincpu, 50000000/2);
IGS027A(config, m_maincpu, 50'000'000/2);
m_maincpu->set_addrmap(AS_PROGRAM, &igs_fear_state::main_map);
MX10EXA(config, m_xa, 50000000/3); // MX10EXAQC (Philips 80C51 XA)
MX10EXA(config, m_xa, 50'000'000/3); // MX10EXAQC (Philips 80C51 XA)
m_xa->port_in_cb<0>().set(FUNC(igs_fear_state::mcu_p0_r));
m_xa->port_in_cb<1>().set(FUNC(igs_fear_state::mcu_p1_r));
m_xa->port_in_cb<2>().set(FUNC(igs_fear_state::mcu_p2_r));

View file

@ -26,10 +26,10 @@
#include "emu.h"
#include "igs017_igs031.h"
#include "igs027a.h"
#include "mahjong.h"
#include "pgmcrypt.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "machine/i8255.h"
@ -83,6 +83,7 @@ public:
void lthy_xor(machine_config &config) ATTR_COLD;
void zhongguo_xor(machine_config &config) ATTR_COLD;
void mgzz_xor(machine_config &config) ATTR_COLD;
void mgcs3_xor(machine_config &config) ATTR_COLD;
void oceanpar_xor(machine_config &config) ATTR_COLD;
void extradraw(machine_config &config) ATTR_COLD;
@ -116,7 +117,7 @@ private:
required_region_ptr<u32> m_external_rom;
optional_shared_ptr<u32> m_igs_mainram;
required_device<cpu_device> m_maincpu;
required_device<igs027a_cpu_device> m_maincpu;
required_device<i8255_device> m_ppi;
required_device<igs017_igs031_device> m_igs017_igs031;
required_device<screen_device> m_screen;
@ -148,6 +149,8 @@ private:
void jking02_output_w(u8 data);
void oceanpar_output_w(u8 data);
void mgcs3_ppi_pc_w(u8 data);
u32 unk2_r();
u32 lhdmg_unk2_r();
void unk2_w(u32 data);
@ -190,7 +193,6 @@ void igs_m027_state::video_start()
void igs_m027_state::igs_mahjong_map(address_map &map)
{
map(0x00000000, 0x00003fff).rom(); // Internal ROM
map(0x08000000, 0x0807ffff).rom().region("user1", 0); // Game ROM
map(0x10000000, 0x100003ff).ram().share("igs_mainram"); // main RAM for ASIC?
map(0x18000000, 0x18007fff).ram();
@ -204,8 +206,6 @@ void igs_m027_state::igs_mahjong_map(address_map &map)
map(0x40000018, 0x4000001b).umask32(0x000000ff).w(FUNC(igs_m027_state::io_select_w<1>));
map(0x50000000, 0x500003ff).umask32(0x000000ff).w(FUNC(igs_m027_state::xor_table_w)); // uploads XOR table to external ROM here
map(0x70000200, 0x70000203).ram(); // ??????????????
map(0xf0000000, 0xf000000f).nopw(); // magic registers
}
void igs_m027_state::igs_mahjong_xor_map(address_map &map)
@ -233,7 +233,7 @@ void igs_m027_state::extradraw_map(address_map &map)
{
igs_mahjong_map(map);
map(0x18088000, 0x1808ffff).ram(); // Extra Draw needs RAM here, maybe just a mirror, maybe due to PCB difference
map(0x18080000, 0x1808ffff).ram(); // Extra Draw needs RAM here, maybe just a mirror, maybe due to PCB difference
}
/***************************************************************************
@ -671,9 +671,9 @@ INPUT_PORTS_START( qlgs )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x01, "Control Mode" ) PORT_DIPLOCATION("SW2:1") // 操作方式
PORT_DIPNAME( 0x01, 0x01, "Control Panel" ) PORT_DIPLOCATION("SW2:1") // 操作方式
PORT_DIPSETTING( 0x01, "Mahjong" ) // 麻將
PORT_DIPSETTING( 0x00, "Joystick" ) // 搖桿
PORT_DIPSETTING( 0x00, DEF_STR(Joystick) ) // 搖桿
PORT_DIPNAME( 0x02, 0x02, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW2:2") // 示範音樂
PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 無
PORT_DIPSETTING( 0x02, DEF_STR(On) ) // 有
@ -708,33 +708,33 @@ INPUT_PORTS_START( lhzb3 )
INPUT_PORTS_END
INPUT_PORTS_START( lhzb4 )
// TODO: this is very preliminary, mahjong keyboard inputs aren't hooked up
PORT_INCLUDE( igs_mahjong_matrix )
PORT_START("TEST")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // 下
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // 下
PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) // 测试
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) // 查帐
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // 投币
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // 上
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // 左
PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // 上
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // 左
PORT_START("JOY")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // S3
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // S2
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // S1
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // 开始
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) // S3
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) // S2
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) // S1
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) // 开始
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // HP
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 ) // 右
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 ) // 投币
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // 右
PORT_START("PLAYER")
PORT_BIT( 0x000001ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000007, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x000001f8, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(igs_m027_state, kbd_ioport_r)
PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x01 )
PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW1", 0x01, EQUALS, 0x00 ) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // HP
PORT_BIT( 0x00000400, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -746,8 +746,8 @@ INPUT_PORTS_START( lhzb4 )
PORT_START("DSW1")
PORT_DIPNAME( 0x01, 0x01, "Control Panel" ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x01, "JAMMA" )
PORT_DIPSETTING( 0x00, "Keyboard" )
PORT_DIPSETTING( 0x01, DEF_STR(Joystick) ) // called JAMMA
PORT_DIPSETTING( 0x00, "Mahjong" ) // called Keyboard
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" ) // remaining DIP switches not shown in test mode
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW1:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW1:4" )
@ -822,9 +822,9 @@ INPUT_PORTS_START( lthy )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x01, "Control Mode" ) PORT_DIPLOCATION("SW2:1") // 操作模式
PORT_DIPSETTING( 0x01, "Buttons" ) // 按键
PORT_DIPSETTING( 0x00, "Joystick" ) // 揺杆
PORT_DIPNAME( 0x01, 0x01, "Control Panel" ) PORT_DIPLOCATION("SW2:1") // 操作模式
PORT_DIPSETTING( 0x01, "Mahjong" ) // 按键
PORT_DIPSETTING( 0x00, DEF_STR(Joystick) ) // 揺杆
PORT_DIPNAME( 0x02, 0x02, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW2:2") // 示范音乐
PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 无
PORT_DIPSETTING( 0x02, DEF_STR(On) ) // 有
@ -871,9 +871,9 @@ INPUT_PORTS_START( zhongguo )
PORT_DIPSETTING( 0x80, DEF_STR(On) ) // 有
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x01, "Control Mode" ) PORT_DIPLOCATION("SW2:1") // 操作模式
PORT_DIPSETTING( 0x01, "Buttons" ) // 按键
PORT_DIPSETTING( 0x00, "Joystick" ) // 搖杆
PORT_DIPNAME( 0x01, 0x01, "Control Panel" ) PORT_DIPLOCATION("SW2:1") // 操作模式
PORT_DIPSETTING( 0x01, "Mahjong" ) // 按键
PORT_DIPSETTING( 0x00, DEF_STR(Joystick) ) // 搖杆
PORT_DIPNAME( 0x06, 0x06, "Card Display" ) PORT_DIPLOCATION("SW2:2,3") // 扑克画面
PORT_DIPSETTING( 0x06, "Small Cards" ) // 小扑克
PORT_DIPSETTING( 0x04, "Cards" ) // 扑克
@ -913,9 +913,9 @@ INPUT_PORTS_START( mgzz )
PORT_DIPNAME( 0x01, 0x01, DEF_STR(Allow_Continue) ) PORT_DIPLOCATION("SW1:1") // 續玩遊戲
PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 無
PORT_DIPSETTING( 0x01, DEF_STR(On) ) // 有
PORT_DIPNAME( 0x02, 0x02, "Control Mode" ) PORT_DIPLOCATION("SW1:2") // 操作方式
PORT_DIPSETTING( 0x02, "Buttons" ) // 按鍵 (called "MAHJONG" in input test)
PORT_DIPSETTING( 0x00, "Joystick" ) // 搖桿 (called "JAMMA" in input test)
PORT_DIPNAME( 0x02, 0x02, "Control Panel" ) PORT_DIPLOCATION("SW1:2") // 操作方式
PORT_DIPSETTING( 0x02, "Mahjong" ) // 按鍵 (called "MAHJONG" in input test)
PORT_DIPSETTING( 0x00, DEF_STR(Joystick) ) // 搖桿 (called "JAMMA" in input test)
PORT_DIPNAME( 0x04, 0x04, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW1:3") // 示範音樂
PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 無
PORT_DIPSETTING( 0x04, DEF_STR(On) ) // 有
@ -956,6 +956,79 @@ INPUT_PORTS_START( mgzza )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW2:3" ) // not shown in test mode
INPUT_PORTS_END
INPUT_PORTS_START( mgcs3 )
PORT_INCLUDE(igs_mahjong_matrix)
PORT_START("TEST")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // 下
PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) // 测试
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) // 査帐
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) // 投币
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // 上
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // 左
PORT_START("JOY")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 ) // S3
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) // S2
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) // S1
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 ) // 开始
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // HP
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00)
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) // 投币
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // 右
PORT_START("PLAYER")
PORT_BIT( 0x00000007, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x000001f8, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_CUSTOM_MEMBER(igs_m027_state, kbd_ioport_r)
PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x01)
PORT_BIT( 0x00000200, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_CONDITION("DSW2", 0x01, EQUALS, 0x00) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // HP
PORT_BIT( 0x00000400, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000800, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN ) // 开分
PORT_BIT( 0x0007f000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) // 退币
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT ) // 洗分
PORT_BIT( 0xffe00000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("DSW1")
PORT_DIPNAME( 0x01, 0x00, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW1:1") // 示范音乐
PORT_DIPSETTING( 0x01, DEF_STR(Off) ) // 无
PORT_DIPSETTING( 0x00, DEF_STR(On) ) // 有
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW1:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW1:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW1:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW1:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW1:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW1:7" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW1:8" )
PORT_START("DSW2")
PORT_DIPNAME( 0x01, 0x01, "Control Panel" ) PORT_DIPLOCATION("SW2:1") // 配线方式
PORT_DIPSETTING( 0x01, DEF_STR(Joystick) ) // 娱乐
PORT_DIPSETTING( 0x00, "Mahjong" ) // 麻将
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW2:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW2:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW2:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW2:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW2:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW2:7" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW2:8" )
PORT_START("DSW3")
PORT_DIPUNKNOWN_DIPLOC( 0x01, 0x01, "SW3:1" )
PORT_DIPUNKNOWN_DIPLOC( 0x02, 0x02, "SW3:2" )
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW3:3" )
PORT_DIPUNKNOWN_DIPLOC( 0x08, 0x08, "SW3:4" )
PORT_DIPUNKNOWN_DIPLOC( 0x10, 0x10, "SW3:5" )
PORT_DIPUNKNOWN_DIPLOC( 0x20, 0x20, "SW3:6" )
PORT_DIPUNKNOWN_DIPLOC( 0x40, 0x40, "SW3:7" )
PORT_DIPUNKNOWN_DIPLOC( 0x80, 0x80, "SW3:8" )
INPUT_PORTS_END
INPUT_PORTS_START( oceanpara )
PORT_INCLUDE(three_reel)
@ -1110,7 +1183,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(igs_m027_state::interrupt)
int scanline = param;
if (scanline == 240 && m_igs017_igs031->get_irq_enable())
m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time()); // source?
m_maincpu->trigger_irq(3); // source?
if (scanline == 0 && m_igs017_igs031->get_nmi_enable())
m_maincpu->pulse_input_line(ARM7_FIRQ_LINE, m_maincpu->minimum_quantum_time()); // vbl?
@ -1227,6 +1300,13 @@ void igs_m027_state::oceanpar_output_w(u8 data)
m_hopper->motor_w(BIT(data, 7));
}
void igs_m027_state::mgcs3_ppi_pc_w(u8 data)
{
io_select_w<0>(data & 0x1f);
machine().bookkeeping().coin_counter_w(0, BIT(data, 5)); // one pulse per coin or key-in accepted
machine().bookkeeping().coin_counter_w(1, BIT(data, 6)); // one pulse per key-out
}
u32 igs_m027_state::unk2_r()
{
logerror("%s: unk2_r\n", machine().describe_context());
@ -1263,7 +1343,7 @@ CUSTOM_INPUT_MEMBER(igs_m027_state::kbd_ioport_r)
void igs_m027_state::m027(machine_config &config)
{
ARM7(config, m_maincpu, 22000000); // Jungle King 2002 has a 22Mhz Xtal, what about the others?
IGS027A(config, m_maincpu, 22'000'000); // Jungle King 2002 has a 22Mhz Xtal, what about the others?
m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_state::igs_mahjong_map);
// NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
@ -1409,6 +1489,21 @@ void igs_m027_state::mgzz_xor(machine_config &config)
HOPPER(config, m_hopper, attotime::from_msec(50));
}
void igs_m027_state::mgcs3_xor(machine_config &config)
{
m027_xor(config);
m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_state::jking02_xor_map);
m_ppi->out_pb_callback().set(m_hopper, FUNC(hopper_device::motor_w)).bit(4);
m_ppi->out_pc_callback().set(FUNC(igs_m027_state::mgcs3_ppi_pc_w));
m_igs017_igs031->in_pb_callback().set_ioport("TEST");
m_igs017_igs031->in_pc_callback().set_ioport("JOY");
HOPPER(config, m_hopper, attotime::from_msec(50));
}
void igs_m027_state::oceanpar_xor(machine_config &config)
{
m027_xor(config);
@ -2524,7 +2619,7 @@ GAME( 2000, zhongguo, 0, zhongguo_xor, zhongguo, igs_m027_state, init_z
GAMEL( 200?, jking02, 0, jking02_xor, jking02, igs_m027_state, init_jking02, ROT0, "IGS", "Jungle King 2002 (V209US)", MACHINE_NOT_WORKING, layout_jking02 )
GAME( 2003, mgzz, 0, mgzz_xor, mgzz, igs_m027_state, init_mgzz, ROT0, "IGS", "Man Guan Zhi Zun (V101CN)", MACHINE_NOT_WORKING )
GAME( 2000, mgzza, mgzz, mgzz_xor, mgzza, igs_m027_state, init_mgzz, ROT0, "IGS", "Man Guan Zhi Zun (V100CN)", MACHINE_NOT_WORKING )
GAME( 2007, mgcs3, 0, m027_xor, base, igs_m027_state, init_mgcs3, ROT0, "IGS", "Man Guan Caishen 3 (V101CN)", MACHINE_NOT_WORKING )
GAME( 2007, mgcs3, 0, mgcs3_xor, mgcs3, igs_m027_state, init_mgcs3, ROT0, "IGS", "Man Guan Caishen 3 (V101CN)", MACHINE_NOT_WORKING )
GAMEL( 1999, oceanpar, 0, oceanpar_xor, oceanpar, igs_m027_state, init_oceanpar, ROT0, "IGS", "Ocean Paradise (V105US)", MACHINE_NOT_WORKING, layout_oceanpar ) // 1999 copyright in ROM
GAMEL( 1999, oceanpara, oceanpar, oceanpar_xor, oceanpara,igs_m027_state, init_oceanpar, ROT0, "IGS", "Ocean Paradise (V101US)", MACHINE_NOT_WORKING, layout_oceanpar ) // 1999 copyright in ROM
GAMEL( 1999, fruitpar, 0, oceanpar_xor, oceanpar, igs_m027_state, init_fruitpar, ROT0, "IGS", "Fruit Paradise (V214)", MACHINE_NOT_WORKING, layout_oceanpar )

View file

@ -11,9 +11,9 @@ These games use the IGS027A processor.
#include "emu.h"
#include "igs017_igs031.h"
#include "igs027a.h"
#include "pgmcrypt.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "cpu/xa/xa.h"
@ -66,7 +66,7 @@ protected:
private:
optional_shared_ptr<u32> m_igs_mainram;
required_device<cpu_device> m_maincpu;
required_device<igs027a_cpu_device> m_maincpu;
required_device<mx10exa_cpu_device> m_xa;
required_device<i8255_device> m_ppi;
required_device<igs017_igs031_device> m_igs017_igs031;
@ -77,16 +77,11 @@ private:
optional_ioport_array<3> m_io_test;
optional_ioport_array<3> m_io_dsw;
emu_timer *m_timer0;
emu_timer *m_timer1;
u32 m_xor_table[0x100];
u8 m_io_select[2];
u8 m_port2_latch;
u8 m_port0_latch;
u32 m_irq_enable; // m_irq_enable and m_irq_pending are not currently hooked up
u32 m_irq_pending; // it appears they will be needed to differentiate between IRQs from the XA and elsewhere though
u32 m_xa_cmd;
u32 m_xa_ret0;
bool m_irq_from_igs031;
@ -105,8 +100,6 @@ private:
void main_map(address_map &map);
void main_xor_map(address_map &map);
void igs027_trigger_irq(int num);
u32 external_rom_r(offs_t offset);
void xor_table_w(offs_t offset, u8 data);
@ -125,12 +118,6 @@ private:
void mcu_p2_w(uint8_t data);
void mcu_p3_w(uint8_t data);
u32 igs027_periph_r(offs_t offset, u32 mem_mask);
void igs027_periph_w(offs_t offset, u32 data, u32 mem_mask);
template <unsigned N>
TIMER_CALLBACK_MEMBER(igs027_timer_irq);
u32 gpio_r();
void oki_bank_w(offs_t offset, u8 data);
template <unsigned Select, unsigned First> u8 dsw_r();
@ -142,8 +129,6 @@ void igs_m027xa_state::machine_reset()
{
m_port2_latch = 0;
m_port0_latch = 0;
m_irq_enable = 0xff;
m_irq_pending = 0xff;
m_xa_cmd = 0;
m_xa_ret0 = 0;
m_irq_from_igs031 = false;
@ -166,8 +151,6 @@ void igs_m027xa_state::machine_start()
save_item(NAME(m_port2_latch));
save_item(NAME(m_port0_latch));
save_item(NAME(m_irq_enable));
save_item(NAME(m_irq_pending));
save_item(NAME(m_xa_cmd));
save_item(NAME(m_xa_ret0));
save_item(NAME(m_irq_from_igs031));
@ -179,9 +162,6 @@ void igs_m027xa_state::machine_start()
save_item(NAME(m_port3_dat));
save_item(NAME(m_igs_40000014));
m_timer0 = timer_alloc(FUNC(igs_m027xa_state::igs027_timer_irq<0>), this);
m_timer1 = timer_alloc(FUNC(igs_m027xa_state::igs027_timer_irq<1>), this);
}
void igs_m027xa_state::video_start()
@ -189,50 +169,6 @@ void igs_m027xa_state::video_start()
m_igs017_igs031->video_start();
}
template <unsigned N>
TIMER_CALLBACK_MEMBER(igs_m027xa_state::igs027_timer_irq)
{
igs027_trigger_irq(N);
}
void igs_m027xa_state::igs027_periph_w(offs_t offset, u32 data, u32 mem_mask)
{
switch (offset * 4)
{
case 0x100:
// TODO: verify the timer interval
m_timer0->adjust(attotime::from_hz(data / 2), 0, attotime::from_hz(data / 2));
break;
case 0x104:
m_timer1->adjust(attotime::from_hz(data / 2), 0, attotime::from_hz(data / 2));
break;
case 0x200:
m_irq_enable = data;
break;
default:
LOGMASKED(LOG_DEBUG, "%s: unhandled igs027_periph_w %04x %08x (%08x)\n", machine().describe_context(), offset * 4, data, mem_mask);
}
}
u32 igs_m027xa_state::igs027_periph_r(offs_t offset, u32 mem_mask)
{
u32 data = ~u32(0);
switch (offset * 4)
{
case 0x200:
data = m_irq_pending;
m_irq_pending = 0xff;
break;
default:
LOGMASKED(LOG_DEBUG, "%s: unhandled igs027_periph_r %04x (%08x)\n", machine().describe_context(), offset * 4, mem_mask);
}
return data;
}
/***************************************************************************
Memory Maps
@ -241,7 +177,6 @@ u32 igs_m027xa_state::igs027_periph_r(offs_t offset, u32 mem_mask)
void igs_m027xa_state::main_map(address_map &map)
{
map(0x00000000, 0x00003fff).rom(); // Internal ROM
map(0x08000000, 0x0807ffff).rom().region("user1", 0); // Game ROM
map(0x10000000, 0x100003ff).ram().share("igs_mainram"); // main RAM for ASIC?
map(0x18000000, 0x18007fff).ram();
@ -254,13 +189,9 @@ void igs_m027xa_state::main_map(address_map &map)
map(0x40000014, 0x40000017).w(FUNC(igs_m027xa_state::igs_40000014_w));
map(0x40000018, 0x4000001b).umask32(0x000000ff).w(FUNC(igs_m027xa_state::io_select_w<1>));
map(0x58000000, 0x580000ff).rw(FUNC(igs_m027xa_state::xa_r), FUNC(igs_m027xa_state::xa_w));
map(0x70000000, 0x700003ff).rw(FUNC(igs_m027xa_state::igs027_periph_r), FUNC(igs_m027xa_state::igs027_periph_w));
map(0x50000000, 0x500003ff).umask32(0x000000ff).w(FUNC(igs_m027xa_state::xor_table_w));
map(0xf0000000, 0xf000000f).nopw(); // magic registers
map(0x58000000, 0x580000ff).rw(FUNC(igs_m027xa_state::xa_r), FUNC(igs_m027xa_state::xa_w));
}
void igs_m027xa_state::main_xor_map(address_map &map)
@ -355,15 +286,6 @@ static INPUT_PORTS_START( base )
INPUT_PORTS_END
void igs_m027xa_state::igs027_trigger_irq(int num)
{
if (!BIT(m_irq_enable, num))
{
m_irq_pending &= ~(u32(1) << num);
m_maincpu->pulse_input_line(ARM7_IRQ_LINE, m_maincpu->minimum_quantum_time());
}
}
u16 igs_m027xa_state::xa_r(offs_t offset, u16 mem_mask)
{
u32 data = ~u32(0);
@ -508,7 +430,7 @@ void igs_m027xa_state::mcu_p3_w(uint8_t data)
if (posedge(oldport3, m_port3_dat, 5))
{
m_irq_from_xa = true;
igs027_trigger_irq(3);
m_maincpu->trigger_irq(3);
}
// high->low transition on bit 0x80 must read into latches!
if (negedge(oldport3, m_port3_dat, 7))
@ -543,12 +465,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(igs_m027xa_state::interrupt)
{
int scanline = param;
// should be using igs027_trigger_irq with more compelx interrupt logic?
// should be using m_maincpu->trigger_irq with more compelx interrupt logic?
if (scanline == 240 && m_igs017_igs031->get_irq_enable())
{
m_irq_from_igs031 = true;
igs027_trigger_irq(3);
m_maincpu->trigger_irq(3);
}
if (scanline == 0 && (m_igs_40000014 & 1))
m_maincpu->pulse_input_line(ARM7_FIRQ_LINE, m_maincpu->minimum_quantum_time()); // vbl?
@ -557,7 +479,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(igs_m027xa_state::interrupt)
void igs_m027xa_state::igs_mahjong_xa(machine_config &config)
{
ARM7(config, m_maincpu, 22'000'000); // Crazy Bugs has a 22MHz crystal, what about the others?
IGS027A(config, m_maincpu, 22'000'000); // Crazy Bugs has a 22MHz crystal, what about the others?
m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027xa_state::main_map);
// NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);

View file

@ -131,7 +131,7 @@ void pgm_arm_type2_state::_55857F_arm7_map(address_map &map)
map(0x18000000, 0x1800ffff).ram().share("arm_ram");
map(0x38000000, 0x38000003).rw(FUNC(pgm_arm_type2_state::arm7_latch_arm_r), FUNC(pgm_arm_type2_state::arm7_latch_arm_w)); /* 68k Latch */
map(0x48000000, 0x4800ffff).rw(FUNC(pgm_arm_type2_state::arm7_shareram_r), FUNC(pgm_arm_type2_state::arm7_shareram_w)).share("arm7_shareram");
map(0x50000000, 0x500003ff).ram().umask32(0x000000ff).w(FUNC(pgm_arm_type2_state::xor_table_w));
map(0x50000000, 0x500003ff).ram().umask32(0x000000ff).w(FUNC(pgm_arm_type2_state::xor_table_w));
}
/******* ARM 55857F *******/