diff --git a/hash/supracan.xml b/hash/supracan.xml
index d31d96d350b..6a21c6c2cd3 100644
--- a/hash/supracan.xml
+++ b/hash/supracan.xml
@@ -10,12 +10,12 @@ license:CC0-1.0
AV Artisan Corp.
-
+
@@ -27,14 +27,13 @@ license:CC0-1.0
1995
Panda Entertainment Technology
-
+
@@ -50,14 +49,17 @@ Uses [video] blending during attract and title screen
Wrong [video] ROZ paging for title screen
Broken [video] during intro, uses bitmap mode
[video] uses per-tile priority during gameplay
+[sound] BGM during intro releases few keys too early (TODO: pinpoint which)
]]>
-
-
+
+
+
+
@@ -68,11 +70,13 @@ Broken [video] during intro, uses bitmap mode
-
+
@@ -84,15 +88,19 @@ Broken [video] during intro, uses bitmap mode
1995
C&E Soft
-
-
+
+
+
+
@@ -101,11 +109,11 @@ Broken [video] during intro, uses bitmap mode
1995
Funtech
-
+
@@ -122,12 +130,15 @@ Can potentially hang, [maincpu] tight loops for $e80300 bit 7 high
]]>
-
-
+
+
+
+
+
@@ -137,11 +148,14 @@ Can potentially hang, [maincpu] tight loops for $e80300 bit 7 high
Panda Entertainment Technology
-
-
+
+
+
+
+
@@ -150,16 +164,21 @@ Can potentially hang, [maincpu] tight loops for $e80300 bit 7 high
1996
Funtech
-
+
+
+
+
+
+
@@ -168,14 +187,14 @@ Erratic gameplay speed, controls [irq 3] as FRC, can potentially hang
1996
Funtech
-
+
@@ -192,7 +211,7 @@ Uses [video] clipping for layer 1 during intro
-
+
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index c6d4b7f1cb5..6ca699992a0 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2010,6 +2010,8 @@ if (BUSES["MSX_SLOT"]~=null) then
MAME_DIR .. "src/devices/bus/msx/slot/music.h",
MAME_DIR .. "src/devices/bus/msx/slot/panasonic08.cpp",
MAME_DIR .. "src/devices/bus/msx/slot/panasonic08.h",
+ MAME_DIR .. "src/devices/bus/msx/slot/panasonic08r.cpp",
+ MAME_DIR .. "src/devices/bus/msx/slot/panasonic08r.h",
MAME_DIR .. "src/devices/bus/msx/slot/rom.cpp",
MAME_DIR .. "src/devices/bus/msx/slot/rom.h",
MAME_DIR .. "src/devices/bus/msx/slot/ram.cpp",
@@ -2576,6 +2578,20 @@ if (BUSES["SS50"]~=null) then
}
end
+---------------------------------------------------
+--
+--@src/devices/bus/supracan/slot.h,BUSES["SUPRACAN"] = true
+---------------------------------------------------
+
+if (BUSES["SUPRACAN"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/bus/supracan/slot.cpp",
+ MAME_DIR .. "src/devices/bus/supracan/slot.h",
+ MAME_DIR .. "src/devices/bus/supracan/rom.cpp",
+ MAME_DIR .. "src/devices/bus/supracan/rom.h",
+ }
+end
+
---------------------------------------------------
--
diff --git a/src/devices/bus/msx/slot/fs4600.cpp b/src/devices/bus/msx/slot/fs4600.cpp
index 7f947b5b7fd..abb599d4c42 100644
--- a/src/devices/bus/msx/slot/fs4600.cpp
+++ b/src/devices/bus/msx/slot/fs4600.cpp
@@ -36,10 +36,11 @@ void msx_slot_fs4600_device::device_start()
fatalerror("Memory region '%s' is too small for the FS4600 firmware\n", m_rom_region.finder_tag());
}
- m_sram.resize(SRAM_SIZE);
- m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+ m_sram = std::make_unique(SRAM_SIZE);
+ m_nvram->set_base(&m_sram[0], SRAM_SIZE);
save_item(NAME(m_sram_address));
+ save_pointer(NAME(m_sram), SRAM_SIZE);
for (int i = 0; i < 3; i++)
m_rombank[i]->configure_entries(0, 0x40, m_rom_region->base() + m_region_offset, 0x4000);
diff --git a/src/devices/bus/msx/slot/fs4600.h b/src/devices/bus/msx/slot/fs4600.h
index 5061e9186bf..dacf5be14c2 100644
--- a/src/devices/bus/msx/slot/fs4600.h
+++ b/src/devices/bus/msx/slot/fs4600.h
@@ -41,7 +41,7 @@ class msx_slot_fs4600_device : public device_t, public msx_internal_slot_interfa
memory_view m_view[3];
u32 m_region_offset;
u32 m_sram_address;
- std::vector m_sram;
+ std::unique_ptr m_sram;
};
diff --git a/src/devices/bus/msx/slot/fsa1fm.cpp b/src/devices/bus/msx/slot/fsa1fm.cpp
index 93e55d5b78d..6b59c516bbe 100644
--- a/src/devices/bus/msx/slot/fsa1fm.cpp
+++ b/src/devices/bus/msx/slot/fsa1fm.cpp
@@ -32,15 +32,15 @@ void msx_slot_fsa1fm2_device::device_start()
fatalerror("Memory region '%s' is not the correct size for the FS-A1FM firmware\n", m_rom_region.finder_tag());
}
- m_ram.resize(RAM_SIZE);
- m_empty_bank.resize(8 * 1024);
+ m_ram = std::make_unique(RAM_SIZE);
+ m_empty_bank = std::make_unique(8 * 1024);
for (int i = 0; i < 8 * 1024; i++)
m_empty_bank[i] = 0xff;
save_item(NAME(m_selected_bank));
save_item(NAME(m_control));
save_item(NAME(m_ram_active));
- save_pointer(m_ram.data(), "ram", RAM_SIZE);
+ save_pointer(NAME(m_ram), m_size);
for (int i = 0; i < 6; i++)
{
@@ -48,10 +48,10 @@ void msx_slot_fsa1fm2_device::device_start()
m_bank[i]->configure_entries(0x80, 0x80, m_rom_region->base() + m_region_offset, 0x2000);
for (int j = 0; j < 4; j++)
{
- m_bank[i]->configure_entry(0x80 + j, m_empty_bank.data()); // 0x80-0x83 empty
- m_bank[i]->configure_entry(0x84 + j, m_ram.data()); // 0x84-0x87 ram
- m_bank[i]->configure_entry(0x88 + j, m_empty_bank.data()); // 0x88-0x8b empty
- m_bank[i]->configure_entry(0x8c + j, m_ram.data()); // 0x8c-0x8f ram
+ m_bank[i]->configure_entry(0x80 + j, &m_empty_bank[0]); // 0x80-0x83 empty
+ m_bank[i]->configure_entry(0x84 + j, &m_ram[0]); // 0x84-0x87 ram
+ m_bank[i]->configure_entry(0x88 + j, &m_empty_bank[0]); // 0x88-0x8b empty
+ m_bank[i]->configure_entry(0x8c + j, &m_ram[0]); // 0x8c-0x8f ram
}
}
@@ -182,14 +182,16 @@ void msx_slot_fsa1fm_device::device_start()
fatalerror("Memory region '%s' is not the correct size for the FS-A1FM firmware\n", m_rom_region.finder_tag());
}
- m_sram.resize(SRAM_SIZE);
- m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+ m_sram = std::make_unique(SRAM_SIZE);
+ m_nvram->set_base(&m_sram[0], SRAM_SIZE);
+
+ save_pointer(NAME(m_sram), SRAM_SIZE);
m_rombank->configure_entries(0, 16, m_rom_region->base(), 0x2000);
page(1)->install_read_bank(0x4000, 0x5fff, m_rombank);
// SRAM is always visible?
- page(1)->install_ram(0x6000, 0x7fff, m_sram.data());
+ page(1)->install_ram(0x6000, 0x7fff, &m_sram[0]);
page(1)->install_write_handler(0x7fc0, 0x7fc0, emu::rw_delegate(*m_i8251, FUNC(i8251_device::data_w)));
page(1)->install_read_handler(0x7fc0, 0x7fc0, emu::rw_delegate(*m_i8251, FUNC(i8251_device::data_r)));
page(1)->install_write_handler(0x7fc1, 0x7fc1, emu::rw_delegate(*m_i8251, FUNC(i8251_device::control_w)));
diff --git a/src/devices/bus/msx/slot/fsa1fm.h b/src/devices/bus/msx/slot/fsa1fm.h
index 660baa43e99..e0d2bac0bcd 100644
--- a/src/devices/bus/msx/slot/fsa1fm.h
+++ b/src/devices/bus/msx/slot/fsa1fm.h
@@ -42,8 +42,8 @@ class msx_slot_fsa1fm2_device : public device_t, public msx_internal_slot_interf
uint8_t m_selected_bank[6];
bool m_ram_active[6];
uint8_t m_control;
- std::vector m_ram;
- std::vector m_empty_bank;
+ std::unique_ptr m_ram;
+ std::unique_ptr m_empty_bank;
};
@@ -76,7 +76,7 @@ class msx_slot_fsa1fm_device : public device_t, public msx_internal_slot_interfa
required_memory_region m_rom_region;
memory_bank_creator m_rombank;
u32 m_region_offset;
- std::vector m_sram;
+ std::unique_ptr m_sram;
};
diff --git a/src/devices/bus/msx/slot/msx_rs232.cpp b/src/devices/bus/msx/slot/msx_rs232.cpp
index 0750abf7c9a..3848b8e5ff4 100644
--- a/src/devices/bus/msx/slot/msx_rs232.cpp
+++ b/src/devices/bus/msx/slot/msx_rs232.cpp
@@ -255,21 +255,21 @@ void msx_slot_rs232_sony_device::device_start()
{
msx_slot_rs232_base_device::device_start();
- m_ram.resize(RAM_SIZE);
- save_item(NAME(m_ram));
+ m_ram = std::make_unique(RAM_SIZE);
+ save_pointer(NAME(m_ram), RAM_SIZE);
// TODO unmap rom from page 0
- page(0)->install_ram(0x2000, 0x27ff, m_ram.data());
+ page(0)->install_ram(0x2000, 0x27ff, &m_ram[0]);
page(1)->install_rom(0x4000, 0x5fff, m_rom_region->base() + m_region_offset);
- page(1)->install_ram(0x6000, 0x67ff, m_ram.data());
- page(2)->install_ram(0xa000, 0xa7ff, m_ram.data());
+ page(1)->install_ram(0x6000, 0x67ff, &m_ram[0]);
+ page(2)->install_ram(0xa000, 0xa7ff, &m_ram[0]);
page(2)->install_read_handler(0xbff8, 0xbff9, emu::rw_delegate(*m_i8251, FUNC(i8251_device::read)));
page(2)->install_write_handler(0xbff8, 0xbff9, emu::rw_delegate(*m_i8251, FUNC(i8251_device::write)));
page(2)->install_read_handler(0xbffa, 0xbffa, emu::rw_delegate(*this, FUNC(msx_slot_rs232_sony_device::status_r)));
page(2)->install_write_handler(0xbffa, 0xbffa, emu::rw_delegate(*this, FUNC(msx_slot_rs232_sony_device::irq_mask_w)));
page(2)->install_read_handler(0xbffc, 0xbfff, emu::rw_delegate(*m_i8253, FUNC(pit8253_device::read)));
page(2)->install_write_handler(0xbffc, 0xbfff, emu::rw_delegate(*m_i8253, FUNC(pit8253_device::write)));
- page(3)->install_ram(0xe000, 0xe7ff, m_ram.data());
+ page(3)->install_ram(0xe000, 0xe7ff, &m_ram[0]);
}
u8 msx_slot_rs232_sony_device::status_r(offs_t offset)
@@ -454,10 +454,11 @@ void msx_slot_rs232_toshiba_hx3x_device::device_start()
io_space().install_readwrite_handler(0x82, 0x82, emu::rw_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::status_r)), emu::rw_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::irq_mask_w)));
io_space().install_readwrite_handler(0x84, 0x87, emu::rw_delegate(*m_i8253, FUNC(pit8253_device::read)), emu::rw_delegate(*m_i8253, FUNC(pit8253_device::write)));
- m_sram.resize(SRAM_SIZE);
- m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+ m_sram = std::make_unique(SRAM_SIZE);
+ m_nvram->set_base(&m_sram[0], SRAM_SIZE);
save_item(NAME(m_bank_reg));
+ save_pointer(NAME(m_sram), SRAM_SIZE);
m_rombank->configure_entries(0, 4, m_rom_region->base() + m_region_offset + 0x4000, 0x4000);
@@ -465,7 +466,7 @@ void msx_slot_rs232_toshiba_hx3x_device::device_start()
page(1)->install_read_handler(0x7fff, 0x7fff, emu::rw_delegate(*this, FUNC(msx_slot_rs232_toshiba_hx3x_device::bank_r)));
page(2)->install_view(0x8000, 0xbfff, m_view);
m_view[0].install_read_bank(0x8000, 0xbfff, m_rombank);
- m_view[1].install_ram(0x8000, 0x87ff, 0x3800, m_sram.data());
+ m_view[1].install_ram(0x8000, 0x87ff, 0x3800, &m_sram[0]);
}
void msx_slot_rs232_toshiba_hx3x_device::device_reset()
diff --git a/src/devices/bus/msx/slot/msx_rs232.h b/src/devices/bus/msx/slot/msx_rs232.h
index 6aa6ba52ffa..e22221bbe9b 100644
--- a/src/devices/bus/msx/slot/msx_rs232.h
+++ b/src/devices/bus/msx/slot/msx_rs232.h
@@ -95,7 +95,7 @@ class msx_slot_rs232_sony_device : public msx_slot_rs232_base_device
static constexpr size_t RAM_SIZE = 0x800;
required_ioport m_switch_port;
- std::vector m_ram;
+ std::unique_ptr m_ram;
};
@@ -152,7 +152,7 @@ class msx_slot_rs232_toshiba_hx3x_device : public msx_slot_rs232_base_device
required_device m_nvram;
memory_bank_creator m_rombank;
memory_view m_view;
- std::vector m_sram;
+ std::unique_ptr m_sram;
u8 m_bank_reg;
};
diff --git a/src/devices/bus/msx/slot/panasonic08.cpp b/src/devices/bus/msx/slot/panasonic08.cpp
index 5de4c1d1913..a0a644c46a9 100644
--- a/src/devices/bus/msx/slot/panasonic08.cpp
+++ b/src/devices/bus/msx/slot/panasonic08.cpp
@@ -41,20 +41,21 @@ void msx_slot_panasonic08_device::device_start()
fatalerror("Memory region '%s' is too small for the panasonic08 firmware\n", m_rom_region.finder_tag());
}
- m_sram.resize(SRAM_SIZE);
+ m_sram = std::make_unique(SRAM_SIZE);
m_nvram->set_base(&m_sram[0], SRAM_SIZE);
save_item(NAME(m_selected_bank));
save_item(NAME(m_control));
+ save_pointer(NAME(m_sram), SRAM_SIZE);
for (int i = 0; i < 6; i++)
{
m_bank[i]->configure_entries(0, 0x100, m_rom_region->base() + m_region_offset, 0x2000);
- m_bank[i]->configure_entry(0x80, m_sram.data());
- m_bank[i]->configure_entry(0x81, m_sram.data() + 0x2000);
- m_bank[i]->configure_entry(0x82, m_sram.data());
- m_bank[i]->configure_entry(0x83, m_sram.data() + 0x2000);
+ m_bank[i]->configure_entry(0x80, &m_sram[0]);
+ m_bank[i]->configure_entry(0x81, &m_sram[0x2000]);
+ m_bank[i]->configure_entry(0x82, &m_sram[0]);
+ m_bank[i]->configure_entry(0x83, &m_sram[0x2000]);
}
page(0)->install_view(0x0000, 0x1fff, m_view[0]);
diff --git a/src/devices/bus/msx/slot/panasonic08.h b/src/devices/bus/msx/slot/panasonic08.h
index 6fd7ace83f4..5602dfd20dd 100644
--- a/src/devices/bus/msx/slot/panasonic08.h
+++ b/src/devices/bus/msx/slot/panasonic08.h
@@ -41,7 +41,7 @@ class msx_slot_panasonic08_device : public device_t, public msx_internal_slot_in
u32 m_region_offset;
u8 m_selected_bank[6];
u8 m_control;
- std::vector m_sram;
+ std::unique_ptr m_sram;
};
diff --git a/src/devices/bus/msx/slot/panasonic08r.cpp b/src/devices/bus/msx/slot/panasonic08r.cpp
new file mode 100644
index 00000000000..c274cf951f4
--- /dev/null
+++ b/src/devices/bus/msx/slot/panasonic08r.cpp
@@ -0,0 +1,166 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/*
+
+ Emulation of the firmware mapper as found in Panasonic FS-A1ST and FS-A1GT Turbo-R machines.
+
+
+*/
+
+#include "emu.h"
+#include "panasonic08r.h"
+
+
+DEFINE_DEVICE_TYPE(MSX_SLOT_PANASONIC08R, msx_slot_panasonic08r_device, "msx_slot_panasonic08r", "MSX Internal Panasonic08r")
+
+
+msx_slot_panasonic08r_device::msx_slot_panasonic08r_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, MSX_SLOT_PANASONIC08R, tag, owner, clock)
+ , msx_internal_slot_interface(mconfig, *this)
+ , m_sram_size(0)
+ , m_nvram(*this, "nvram")
+ , m_rom_region(*this, finder_base::DUMMY_TAG)
+ , m_bank(*this, "bank%u", 0U)
+ , m_view{
+ {*this, "view0"}, {*this, "view1"}, {*this, "view2"}, {*this, "view3"},
+ {*this, "view4"}, {*this, "view5"}, {*this, "view6"}, {*this, "view7"}
+ }
+ , m_mm(*this, finder_base::DUMMY_TAG)
+ , m_region_offset(0)
+ , m_control(0)
+{
+}
+
+
+void msx_slot_panasonic08r_device::device_add_mconfig(machine_config &config)
+{
+ NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0);
+}
+
+
+void msx_slot_panasonic08r_device::device_start()
+{
+ // Sanity checks
+ if (m_rom_region->bytes() < m_region_offset + 0x400000)
+ fatalerror("Memory region '%s' is too small for the panasonic08r firmware\n", m_rom_region.finder_tag());
+ if (m_sram_size != 0x4000 && m_sram_size != 0x8000)
+ fatalerror("Invalid SRAM size for the panasonic08r firmware\n");
+
+ m_sram = std::make_unique(m_sram_size);
+ m_nvram->set_base(&m_sram[0], m_sram_size);
+
+ save_item(NAME(m_selected_bank));
+ save_item(NAME(m_control));
+ save_item(NAME(m_bank9));
+ save_pointer(NAME(m_sram), m_sram_size);
+
+ for (int i = 0; i < 8; i++)
+ {
+ m_bank[i]->configure_entries(0, 0x200, m_rom_region->base() + m_region_offset, 0x2000);
+ m_bank[i]->configure_entry(0x80, &m_sram[0]);
+ m_bank[i]->configure_entry(0x81, &m_sram[0x2000]);
+ if (m_sram_size >= 0x8000)
+ {
+ m_bank[i]->configure_entry(0x82, &m_sram[0x4000]);
+ m_bank[i]->configure_entry(0x83, &m_sram[0x6000]);
+ }
+
+ // Assuming smaller internal RAM is mirrored.
+ int internal_ram_banks = m_mm->get_ram_size() / 0x2000;
+ int start_bank = 0x180;
+ do {
+ int nr_banks = internal_ram_banks;
+ if (start_bank + nr_banks > 0x200)
+ nr_banks = 0x200 - start_bank;
+ m_bank[i]->configure_entries(start_bank, nr_banks, m_mm->get_ram_base(), 0x2000);
+ start_bank += internal_ram_banks;
+ }
+ while (start_bank < 0x200);
+ }
+
+ for (int i = 0; i < 8; i++)
+ {
+ const u16 start = 0x2000 * i;
+ const u16 end = start + 0x1fff;
+
+ page(i/2)->install_view(start, end, m_view[i]);
+ m_view[i][0].install_read_bank(start, end, m_bank[i]);
+ m_view[i][1].install_readwrite_bank(start, end, m_bank[i]);
+ }
+
+ m_view[3][2].install_read_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view[3][2].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, [this] (offs_t offset) { return m_selected_bank[offset] & 0xff; }, "bank_r"));
+ m_view[3][3].install_readwrite_bank(0x6000, 0x7fff, m_bank[3]);
+ m_view[3][3].install_read_handler(0x7ff0, 0x7ff7, read8sm_delegate(*this, [this] (offs_t offset) { return m_selected_bank[offset] & 0xff; }, "bank_r"));
+ page(1)->install_write_handler(0x6000, 0x6000, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<0>)));
+ page(1)->install_write_handler(0x6400, 0x6400, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<1>)));
+ page(1)->install_write_handler(0x6800, 0x6800, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<2>)));
+ page(1)->install_write_handler(0x6c00, 0x6c00, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<3>)));
+ page(1)->install_write_handler(0x7000, 0x7000, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<4>)));
+ page(1)->install_write_handler(0x7400, 0x7400, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<6>)));
+ page(1)->install_write_handler(0x7800, 0x7800, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<5>)));
+ page(1)->install_write_handler(0x7c00, 0x7c00, emu::rw_delegate(*this, FUNC(msx_slot_panasonic08r_device::bank_w<7>)));
+ page(1)->install_readwrite_handler(0x7ff8, 0x7ff8,
+ read8smo_delegate(*this, [this] () { return m_bank9; }, "bank9_r"),
+ write8smo_delegate(*this, [this] (u8 data)
+ {
+ m_bank9 = data;
+ select_banks();
+ }, "bank9_w"));
+ page(1)->install_write_handler(0x7ff9, 0x7ff9, write8smo_delegate(*this, [this] (u8 data)
+ {
+ m_control = data;
+ select_banks();
+ }, "control_w"
+ ));
+}
+
+
+void msx_slot_panasonic08r_device::device_reset()
+{
+ m_control = 0;
+ m_bank9 = 0;
+ for (int i = 0 ; i < 8; i++)
+ {
+ m_selected_bank[i] = 0;
+ m_bank[i]->set_entry(0);
+ m_view[i].select(0);
+ }
+}
+
+
+template
+void msx_slot_panasonic08r_device::set_view()
+{
+ const bool sram_active = (m_selected_bank[Bank] >= 0x80 && m_selected_bank[Bank] < 0x84);
+ const bool ram_active = (m_selected_bank[Bank] >= 0x180);
+ const int view = ((sram_active || ram_active) ? 1 : 0) | ((Bank == 3 && BIT(m_control, 2)) ? 2 : 0);
+
+ m_view[Bank].select(view);
+}
+
+
+template
+void msx_slot_panasonic08r_device::bank_w(u8 data)
+{
+ u16 bank = data;
+
+ if (BIT(m_control, 4))
+ bank |= (BIT(m_bank9, Bank) << 8);
+ m_selected_bank[Bank] = bank;
+ m_bank[Bank]->set_entry(bank);
+ set_view();
+}
+
+
+void msx_slot_panasonic08r_device::select_banks()
+{
+ bank_w<0>(m_selected_bank[0]);
+ bank_w<1>(m_selected_bank[1]);
+ bank_w<2>(m_selected_bank[2]);
+ bank_w<3>(m_selected_bank[3]);
+ bank_w<4>(m_selected_bank[4]);
+ bank_w<5>(m_selected_bank[5]);
+ bank_w<6>(m_selected_bank[6]);
+ bank_w<7>(m_selected_bank[7]);
+}
diff --git a/src/devices/bus/msx/slot/panasonic08r.h b/src/devices/bus/msx/slot/panasonic08r.h
new file mode 100644
index 00000000000..c7efcf6e27a
--- /dev/null
+++ b/src/devices/bus/msx/slot/panasonic08r.h
@@ -0,0 +1,52 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+#ifndef MAME_BUS_MSX_SLOT_PANASONIC08R_H
+#define MAME_BUS_MSX_SLOT_PANASONIC08R_H
+
+#pragma once
+
+#include "ram_mm.h"
+#include "slot.h"
+#include "machine/nvram.h"
+
+
+DECLARE_DEVICE_TYPE(MSX_SLOT_PANASONIC08R, msx_slot_panasonic08r_device)
+
+
+class msx_slot_panasonic08r_device : public device_t, public msx_internal_slot_interface
+{
+public:
+ msx_slot_panasonic08r_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ template msx_slot_panasonic08r_device &set_mm_tag(T &&tag) { m_mm.set_tag(std::forward(tag)); return *this; }
+ void set_rom_start(const char *region, u32 offset) { m_rom_region.set_tag(region); m_region_offset = offset; }
+ msx_slot_panasonic08r_device &set_sram_size(u16 size) { m_sram_size = size; return *this; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ template void set_view();
+ template void bank_w(u8 data);
+
+ void select_banks();
+
+ u16 m_sram_size;
+ required_device m_nvram;
+ required_memory_region m_rom_region;
+ memory_bank_array_creator<8> m_bank;
+ memory_view m_view[8];
+ required_device m_mm;
+ u32 m_region_offset;
+ u16 m_selected_bank[8];
+ u8 m_control;
+ u8 m_bank9;
+ std::unique_ptr m_sram;
+};
+
+
+#endif // MAME_BUS_MSX_SLOT_PANASONIC08R_H
diff --git a/src/devices/bus/msx/slot/ram.cpp b/src/devices/bus/msx/slot/ram.cpp
index 92f9a57929d..03219dbf824 100644
--- a/src/devices/bus/msx/slot/ram.cpp
+++ b/src/devices/bus/msx/slot/ram.cpp
@@ -14,10 +14,13 @@ msx_slot_ram_device::msx_slot_ram_device(const machine_config &mconfig, const ch
void msx_slot_ram_device::device_start()
{
- m_ram.resize(m_size);
- save_item(NAME(m_ram));
+ if (m_size < m_end_address - m_start_address)
+ fatalerror("Invalid size %04x for address range %004x - %04x\n", m_start_address, m_end_address);
- u8 *ram = m_ram.data();
+ m_ram = std::make_unique(m_size);
+ save_pointer(NAME(m_ram), m_size);
+
+ u8 *ram = &m_ram[0];
u32 start_address = m_start_address;
for (int i = m_start_address >> 14; i < 4 && i * 0x4000 < m_end_address; i++)
{
diff --git a/src/devices/bus/msx/slot/ram.h b/src/devices/bus/msx/slot/ram.h
index 9e8f08bc373..c1a5e78e9e8 100644
--- a/src/devices/bus/msx/slot/ram.h
+++ b/src/devices/bus/msx/slot/ram.h
@@ -20,7 +20,7 @@ class msx_slot_ram_device : public device_t,
virtual void device_start() override;
private:
- std::vector m_ram;
+ std::unique_ptr m_ram;
};
diff --git a/src/devices/bus/msx/slot/ram_mm.cpp b/src/devices/bus/msx/slot/ram_mm.cpp
index b32264a02eb..bd0de812474 100644
--- a/src/devices/bus/msx/slot/ram_mm.cpp
+++ b/src/devices/bus/msx/slot/ram_mm.cpp
@@ -30,9 +30,8 @@ void msx_slot_ram_mm_device::device_start()
default: fatalerror("Invalid memory mapper size specified\n");
}
- m_ram.resize(m_total_size);
-
- save_item(NAME(m_ram));
+ m_ram = std::make_unique(m_total_size);
+ save_pointer(NAME(m_ram), m_total_size);
// Install IO read/write handlers using taps to prevent overwriting taps
// installed by other (external) memory mapper devices.
@@ -41,7 +40,7 @@ void msx_slot_ram_mm_device::device_start()
for (int i = 0; i < 4; i++)
{
- m_rambank[i]->configure_entries(0, u32(m_bank_mask) + 1, m_ram.data(), 0x4000);
+ m_rambank[i]->configure_entries(0, u32(m_bank_mask) + 1, &m_ram[0], 0x4000);
page(i)->install_readwrite_bank(0x4000 * i, (0x4000 * i) + 0x3fff, m_rambank[i]);
}
}
diff --git a/src/devices/bus/msx/slot/ram_mm.h b/src/devices/bus/msx/slot/ram_mm.h
index 69ce5f41053..8c4c1426264 100644
--- a/src/devices/bus/msx/slot/ram_mm.h
+++ b/src/devices/bus/msx/slot/ram_mm.h
@@ -15,6 +15,10 @@ class msx_slot_ram_mm_device : public device_t, public msx_internal_slot_interfa
msx_slot_ram_mm_device &set_total_size(u32 total_size) { m_total_size = total_size; return *this; }
msx_slot_ram_mm_device &set_unused_bits(u8 unused_bits) { m_unused_bits = unused_bits; return *this; }
+ // Backdoor for the Turbo-R firmware/internal mapper to access internal RAM.
+ u32 get_ram_size() { return m_total_size; }
+ u8 *get_ram_base() { return &m_ram[0]; }
+
protected:
virtual void device_start() override;
@@ -22,7 +26,7 @@ class msx_slot_ram_mm_device : public device_t, public msx_internal_slot_interfa
u8 read_mapper_bank(offs_t offset);
void write_mapper_bank(offs_t offset, u8 data);
- std::vector m_ram;
+ std::unique_ptr m_ram;
u32 m_total_size;
u8 m_bank_mask;
u8 m_unused_bits;
diff --git a/src/devices/bus/msx/slot/sony08.cpp b/src/devices/bus/msx/slot/sony08.cpp
index bf13f091ee1..29fd07cca93 100644
--- a/src/devices/bus/msx/slot/sony08.cpp
+++ b/src/devices/bus/msx/slot/sony08.cpp
@@ -38,8 +38,10 @@ void msx_slot_sony08_device::device_start()
fatalerror("Memory region '%s' is too small for the SONY08 firmware\n", m_rom_region.finder_tag());
}
- m_sram.resize(SRAM_SIZE);
- m_nvram->set_base(m_sram.data(), SRAM_SIZE);
+ m_sram= std::make_unique(SRAM_SIZE);
+ m_nvram->set_base(&m_sram[0], SRAM_SIZE);
+
+ save_pointer(NAME(m_sram), SRAM_SIZE);
for (int i = 0; i < 4; i++)
m_rombank[i]->configure_entries(0, 0x80, m_rom_region->base() + m_region_offset, 0x2000);
@@ -48,7 +50,7 @@ void msx_slot_sony08_device::device_start()
page(0)->install_view(0x0000, 0x3fff, m_view[0]);
m_view[0][0];
- m_view[0][1].install_ram(0x0000, 0x3fff, m_sram.data());
+ m_view[0][1].install_ram(0x0000, 0x3fff, &m_sram[0]);
page(1)->install_read_bank(0x4000, 0x5fff, m_rombank[0]);
page(1)->install_write_handler(0x4fff, 0x4fff, emu::rw_delegate(*this, FUNC(msx_slot_sony08_device::bank_w<0>)));
diff --git a/src/devices/bus/msx/slot/sony08.h b/src/devices/bus/msx/slot/sony08.h
index 2fa9d9e89ca..c8e364612d0 100644
--- a/src/devices/bus/msx/slot/sony08.h
+++ b/src/devices/bus/msx/slot/sony08.h
@@ -36,7 +36,7 @@ class msx_slot_sony08_device : public device_t, public msx_internal_slot_interfa
memory_bank_array_creator<6> m_rombank;
memory_view m_view[2];
u32 m_region_offset;
- std::vector m_sram;
+ std::unique_ptr m_sram;
};
diff --git a/src/devices/bus/supracan/rom.cpp b/src/devices/bus/supracan/rom.cpp
new file mode 100644
index 00000000000..ca3be333df6
--- /dev/null
+++ b/src/devices/bus/supracan/rom.cpp
@@ -0,0 +1,96 @@
+// license:BSD-3-Clause
+// copyright-holders:
+
+#include "emu.h"
+#include "rom.h"
+
+
+//-------------------------------------------------
+// superacan_rom_device - constructor
+//-------------------------------------------------
+
+DEFINE_DEVICE_TYPE(SUPERACAN_ROM_STD, superacan_rom_device, "superacan_rom", "Super A'Can Standard Cart")
+
+
+superacan_rom_device::superacan_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock), device_superacan_cart_interface(mconfig, *this)
+ , m_rom_base(nullptr)
+ , m_nvram_base(nullptr)
+ , m_rom_size(0)
+ , m_nvram_size(0)
+{
+}
+
+superacan_rom_device::superacan_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : superacan_rom_device(mconfig, SUPERACAN_ROM_STD, tag, owner, clock)
+{
+}
+
+
+void superacan_rom_device::device_start()
+{
+}
+
+void superacan_rom_device::device_add_mconfig(machine_config &config)
+{
+ // TODO: move UM6650 from funtech folder
+}
+
+std::error_condition superacan_rom_device::load()
+{
+ memory_region *const romregion = memregion("^rom");
+ m_rom_base = reinterpret_cast(romregion->base());
+ m_rom_size = romregion->bytes() / 2;
+
+// if (m_rom_size > 0x40'0000)
+// return std::make_pair(image_error::INVALIDLENGTH, "Unsupported cartridge size (must be no larger than 4M)");
+
+ memory_region *const nvramregion = memregion("^nvram");
+ if (nvramregion)
+ {
+ m_nvram_base = reinterpret_cast(nvramregion->base());
+ m_nvram_size = nvramregion->bytes();
+
+ if (m_nvram_size & (m_nvram_size - 1))
+ return image_error::BADSOFTWARE;
+
+ save_pointer(NAME(m_nvram_base), m_nvram_size);
+ battery_load(m_nvram_base, m_nvram_size, 0xff);
+ }
+
+ return std::error_condition();
+}
+
+
+void superacan_rom_device::unload()
+{
+ if (m_nvram_base)
+ battery_save(m_nvram_base, m_nvram_size);
+}
+
+
+/*-------------------------------------------------
+ read/write
+ -------------------------------------------------*/
+
+u16 superacan_rom_device::rom_r(offs_t offset)
+{
+ if (offset < m_rom_size)
+ return m_rom_base[offset];
+ else
+ return 0xffff;
+}
+
+u8 superacan_rom_device::nvram_r(offs_t offset)
+{
+ if (m_nvram_base)
+ return m_nvram_base[offset & (m_nvram_size - 1)];
+ else
+ return 0xff;
+}
+
+void superacan_rom_device::nvram_w(offs_t offset, u8 data)
+{
+ if (m_nvram_base)
+ m_nvram_base[offset & (m_nvram_size - 1)] = data;
+}
diff --git a/src/devices/bus/supracan/rom.h b/src/devices/bus/supracan/rom.h
new file mode 100644
index 00000000000..a75cb26fa66
--- /dev/null
+++ b/src/devices/bus/supracan/rom.h
@@ -0,0 +1,46 @@
+// license:BSD-3-Clause
+// copyright-holders:
+#ifndef MAME_BUS_SUPERACAN_ROM_H
+#define MAME_BUS_SUPERACAN_ROM_H
+
+#pragma once
+
+#include "slot.h"
+
+
+// ======================> superacan_rom_device
+
+class superacan_rom_device : public device_t,
+ public device_superacan_cart_interface
+{
+public:
+ // construction/destruction
+ superacan_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // load/unload
+ virtual std::error_condition load() override;
+ virtual void unload() override;
+
+ // read/write
+ virtual u16 rom_r(offs_t offset) override;
+ virtual u8 nvram_r(offs_t offset) override;
+ virtual void nvram_w(offs_t offset, u8 data) override;
+
+protected:
+ superacan_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ virtual void device_start() override;
+
+ virtual void device_add_mconfig(machine_config &config) override;
+
+private:
+ const u16 *m_rom_base;
+ u8 *m_nvram_base;
+ u32 m_rom_size;
+ u32 m_nvram_size;
+};
+
+
+DECLARE_DEVICE_TYPE(SUPERACAN_ROM_STD, superacan_rom_device)
+
+#endif // MAME_BUS_SUPERACAN_ROM_H
diff --git a/src/devices/bus/supracan/slot.cpp b/src/devices/bus/supracan/slot.cpp
new file mode 100644
index 00000000000..19f10c449f6
--- /dev/null
+++ b/src/devices/bus/supracan/slot.cpp
@@ -0,0 +1,116 @@
+// license:BSD-3-Clause
+// copyright-holders:
+
+#include "emu.h"
+#include "slot.h"
+
+
+DEFINE_DEVICE_TYPE(SUPERACAN_CART_SLOT, superacan_cart_slot_device, "superacan_cart_slot", "Super A'Can Cartridge Slot")
+
+
+device_superacan_cart_interface::device_superacan_cart_interface(const machine_config &mconfig, device_t &device)
+ : device_interface(device, "superacan_cart")
+ , m_slot(dynamic_cast(device.owner()))
+{
+}
+
+
+device_superacan_cart_interface::~device_superacan_cart_interface()
+{
+}
+
+
+void device_superacan_cart_interface::battery_load(void *buffer, int length, int fill)
+{
+ assert(m_slot);
+ m_slot->battery_load(buffer, length, fill);
+}
+
+void device_superacan_cart_interface::battery_load(void *buffer, int length, void *def_buffer)
+{
+ assert(m_slot);
+ m_slot->battery_load(buffer, length, def_buffer);
+}
+
+void device_superacan_cart_interface::battery_save(const void *buffer, int length)
+{
+ assert(m_slot);
+ m_slot->battery_save(buffer, length);
+}
+
+
+superacan_cart_slot_device::superacan_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SUPERACAN_CART_SLOT, tag, owner, clock),
+ device_cartrom_image_interface(mconfig, *this),
+ device_single_card_slot_interface(mconfig, *this),
+ m_cart(nullptr)
+{
+}
+
+
+//-------------------------------------------------
+// superacan_cart_slot_device - destructor
+//-------------------------------------------------
+
+superacan_cart_slot_device::~superacan_cart_slot_device()
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void superacan_cart_slot_device::device_start()
+{
+ m_cart = get_card_device();
+}
+
+
+
+/*-------------------------------------------------
+ call load
+ -------------------------------------------------*/
+
+std::pair superacan_cart_slot_device::call_load()
+{
+ if (!m_cart)
+ return std::make_pair(std::error_condition(), std::string());
+
+ memory_region *romregion = loaded_through_softlist() ? memregion("rom") : nullptr;
+ if (loaded_through_softlist() && !romregion)
+ return std::make_pair(image_error::INVALIDLENGTH, "Software list item has no 'rom' data area");
+
+ const u32 len = loaded_through_softlist() ? romregion->bytes() : length();
+
+ if (!loaded_through_softlist())
+ {
+ romregion = machine().memory().region_alloc(subtag("rom"), len, 2, ENDIANNESS_BIG);
+ u16 *const rombase = reinterpret_cast(romregion->base());
+ const u32 cnt = fread(rombase, len);
+ if (cnt != len)
+ return std::make_pair(std::errc::io_error, "Error reading cartridge file");
+ }
+
+ return std::make_pair(m_cart->load(), std::string());
+}
+
+
+/*-------------------------------------------------
+ call unload
+ -------------------------------------------------*/
+
+void superacan_cart_slot_device::call_unload()
+{
+ if (m_cart)
+ m_cart->unload();
+}
+
+
+/*-------------------------------------------------
+ get default card software
+ -------------------------------------------------*/
+
+std::string superacan_cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const
+{
+ return software_get_default_slot("std");
+}
diff --git a/src/devices/bus/supracan/slot.h b/src/devices/bus/supracan/slot.h
new file mode 100644
index 00000000000..2c285377807
--- /dev/null
+++ b/src/devices/bus/supracan/slot.h
@@ -0,0 +1,90 @@
+// license:BSD-3-Clause
+// copyright-holders:
+
+#ifndef MAME_BUS_SUPERACAN_SLOT_H
+#define MAME_BUS_SUPERACAN_SLOT_H
+
+#include "imagedev/cartrom.h"
+
+#include
+#include
+
+
+/***************************************************************************
+ TYPE DEFINITIONS
+ ***************************************************************************/
+
+class superacan_cart_slot_device;
+
+
+class device_superacan_cart_interface : public device_interface
+{
+public:
+ virtual ~device_superacan_cart_interface();
+
+ // load/unload
+ virtual std::error_condition load() = 0;
+ virtual void unload() = 0;
+
+ // read/write
+ virtual u16 rom_r(offs_t offset) = 0;
+ virtual u8 nvram_r(offs_t offset) = 0;
+ virtual void nvram_w(offs_t offset, u8 data) = 0;
+
+protected:
+ // construction/destruction
+ device_superacan_cart_interface(const machine_config &mconfig, device_t &device);
+
+ // helpers for slot stuff
+ void battery_load(void *buffer, int length, int fill);
+ void battery_load(void *buffer, int length, void *def_buffer);
+ void battery_save(const void *buffer, int length);
+
+private:
+ superacan_cart_slot_device *const m_slot;
+};
+
+
+class superacan_cart_slot_device : public device_t,
+ public device_cartrom_image_interface,
+ public device_single_card_slot_interface
+{
+public:
+ // construction/destruction
+ template
+ superacan_cart_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock, T &&opts, char const *dflt)
+ : superacan_cart_slot_device(mconfig, tag, owner, clock)
+ {
+ option_reset();
+ opts(*this);
+ set_default_option(dflt);
+ set_fixed(false);
+ }
+ superacan_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ virtual ~superacan_cart_slot_device();
+
+ // device_image_interface implementation
+ virtual std::pair call_load() override;
+ virtual void call_unload() override;
+
+ virtual bool is_reset_on_load() const noexcept override { return true; }
+ virtual const char *image_interface() const noexcept override { return "superacan_cart"; }
+ virtual const char *file_extensions() const noexcept override { return "bin"; }
+
+ virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override;
+
+ // reading and writing
+ u16 rom_r(offs_t offset) { return m_cart ? m_cart->rom_r(offset) : 0xffff; }
+ u8 nvram_r(offs_t offset) { return m_cart ? m_cart->nvram_r(offset) : 0xff; }
+ void nvram_w(offs_t offset, u8 data) { if (m_cart) m_cart->nvram_w(offset, data); }
+
+protected:
+ // device_t implementation
+ virtual void device_start() override;
+
+ device_superacan_cart_interface *m_cart;
+};
+
+DECLARE_DEVICE_TYPE(SUPERACAN_CART_SLOT, superacan_cart_slot_device)
+
+#endif // MAME_BUS_SUPERACAN_SLOT_H
diff --git a/src/devices/cpu/tlcs900/tlcs900.cpp b/src/devices/cpu/tlcs900/tlcs900.cpp
index 166a07db6e8..0dcceeb0153 100644
--- a/src/devices/cpu/tlcs900/tlcs900.cpp
+++ b/src/devices/cpu/tlcs900/tlcs900.cpp
@@ -70,13 +70,12 @@ std::unique_ptr tlcs900_device::create_disassembler()
}
-/* Flag defines */
-#define FLAG_CF 0x01
-#define FLAG_NF 0x02
-#define FLAG_VF 0x04
-#define FLAG_HF 0x10
-#define FLAG_ZF 0x40
-#define FLAG_SF 0x80
+static constexpr u8 FLAG_CF = 0x01;
+static constexpr u8 FLAG_NF = 0x02;
+static constexpr u8 FLAG_VF = 0x04;
+static constexpr u8 FLAG_HF = 0x10;
+static constexpr u8 FLAG_ZF = 0x40;
+static constexpr u8 FLAG_SF = 0x80;
inline uint8_t tlcs900_device::RDOP()
diff --git a/src/devices/cpu/tlcs900/tmp95c061.cpp b/src/devices/cpu/tlcs900/tmp95c061.cpp
index d74d7baa0a1..6c126be5cb6 100644
--- a/src/devices/cpu/tlcs900/tmp95c061.cpp
+++ b/src/devices/cpu/tlcs900/tmp95c061.cpp
@@ -257,50 +257,52 @@ void tmp95c061_device::device_reset()
}
}
+enum
+{
+ INTE0AD,
+ INTE45,
+ INTE67,
+ INTET10,
+ INTET32,
+ INTET54,
+ INTET76,
+ INTES0,
+ INTES1,
+ INTETC10,
+ INTETC32
+};
-#define TMP95C061_INTE0AD 0x0
-#define TMP95C061_INTE45 0x1
-#define TMP95C061_INTE67 0x2
-#define TMP95C061_INTET10 0x3
-#define TMP95C061_INTET32 0x4
-#define TMP95C061_INTET54 0x5
-#define TMP95C061_INTET76 0x6
-#define TMP95C061_INTES0 0x7
-#define TMP95C061_INTES1 0x8
-#define TMP95C061_INTETC10 0x9
-#define TMP95C061_INTETC32 0xa
-
-#define TMP95C061_NUM_MASKABLE_IRQS 22
static const struct {
uint8_t reg;
uint8_t iff;
uint8_t vector;
-} tmp95c061_irq_vector_map[TMP95C061_NUM_MASKABLE_IRQS] =
-{
- { TMP95C061_INTETC32, 0x80, 0x80 }, /* INTTC3 */
- { TMP95C061_INTETC32, 0x08, 0x7c }, /* INTTC2 */
- { TMP95C061_INTETC10, 0x80, 0x78 }, /* INTTC1 */
- { TMP95C061_INTETC10, 0x08, 0x74 }, /* INTTC0 */
- { TMP95C061_INTE0AD, 0x80, 0x70 }, /* INTAD */
- { TMP95C061_INTES1, 0x80, 0x6c }, /* INTTX1 */
- { TMP95C061_INTES1, 0x08, 0x68 }, /* INTRX1 */
- { TMP95C061_INTES0, 0x80, 0x64 }, /* INTTX0 */
- { TMP95C061_INTES0, 0x08, 0x60 }, /* INTRX0 */
- { TMP95C061_INTET76, 0x80, 0x5c }, /* INTTR7 */
- { TMP95C061_INTET76, 0x08, 0x58 }, /* INTTR6 */
- { TMP95C061_INTET54, 0x80, 0x54 }, /* INTTR5 */
- { TMP95C061_INTET54, 0x08, 0x50 }, /* INTTR4 */
- { TMP95C061_INTET32, 0x80, 0x4c }, /* INTT3 */
- { TMP95C061_INTET32, 0x08, 0x48 }, /* INTT2 */
- { TMP95C061_INTET10, 0x80, 0x44 }, /* INTT1 */
- { TMP95C061_INTET10, 0x08, 0x40 }, /* INTT0 */
- /* 0x3c - reserved */
- { TMP95C061_INTE67, 0x80, 0x38 }, /* INT7 */
- { TMP95C061_INTE67, 0x08, 0x34 }, /* INT6 */
- { TMP95C061_INTE45, 0x80, 0x30 }, /* INT5 */
- { TMP95C061_INTE45, 0x08, 0x2c }, /* INT4 */
- { TMP95C061_INTE0AD, 0x08, 0x28 } /* INT0 */
+} tmp95c061_irq_vector_map[] =
+{
+ { INTETC32, 0x80, 0x80 }, // INTTC3
+ { INTETC32, 0x08, 0x7c }, // INTTC2
+ { INTETC10, 0x80, 0x78 }, // INTTC1
+ { INTETC10, 0x08, 0x74 }, // INTTC0
+ { INTE0AD, 0x80, 0x70 }, // INTAD
+ { INTES1, 0x80, 0x6c }, // INTTX1
+ { INTES1, 0x08, 0x68 }, // INTRX1
+ { INTES0, 0x80, 0x64 }, // INTTX0
+ { INTES0, 0x08, 0x60 }, // INTRX0
+ { INTET76, 0x80, 0x5c }, // INTTR7
+ { INTET76, 0x08, 0x58 }, // INTTR6
+ { INTET54, 0x80, 0x54 }, // INTTR5
+ { INTET54, 0x08, 0x50 }, // INTTR4
+ { INTET32, 0x80, 0x4c }, // INTT3
+ { INTET32, 0x08, 0x48 }, // INTT2
+ { INTET10, 0x80, 0x44 }, // INTT1
+ { INTET10, 0x08, 0x40 }, // INTT0
+ // 0x3c - reserved
+ { INTE67, 0x80, 0x38 }, // INT7
+ { INTE67, 0x08, 0x34 }, // INT6
+ { INTE45, 0x80, 0x30 }, // INT5
+ { INTE45, 0x08, 0x2c }, // INT4
+ { INTE0AD, 0x08, 0x28 } // INT0
};
+static constexpr u8 NUM_MASKABLE_IRQS = sizeof(tmp95c061_irq_vector_map) / 3;
int tmp95c061_device::tlcs900_process_hdma( int channel )
@@ -312,11 +314,11 @@ int tmp95c061_device::tlcs900_process_hdma( int channel )
{
int irq = 0;
- while( irq < TMP95C061_NUM_MASKABLE_IRQS && tmp95c061_irq_vector_map[irq].vector != vector )
+ while( irq < NUM_MASKABLE_IRQS && tmp95c061_irq_vector_map[irq].vector != vector )
irq++;
/* Check if our interrupt flip-flop is set */
- if ( irq < TMP95C061_NUM_MASKABLE_IRQS && m_int_reg[tmp95c061_irq_vector_map[irq].reg] & tmp95c061_irq_vector_map[irq].iff )
+ if ( irq < NUM_MASKABLE_IRQS && m_int_reg[tmp95c061_irq_vector_map[irq].reg] & tmp95c061_irq_vector_map[irq].iff )
{
switch( m_dmam[channel].b.l & 0x1f )
{
@@ -406,16 +408,16 @@ int tmp95c061_device::tlcs900_process_hdma( int channel )
switch( channel )
{
case 0:
- m_int_reg[TMP95C061_INTETC10] |= 0x08;
+ m_int_reg[INTETC10] |= 0x08;
break;
case 1:
- m_int_reg[TMP95C061_INTETC10] |= 0x80;
+ m_int_reg[INTETC10] |= 0x80;
break;
case 2:
- m_int_reg[TMP95C061_INTETC32] |= 0x08;
+ m_int_reg[INTETC32] |= 0x08;
break;
case 3:
- m_int_reg[TMP95C061_INTETC32] |= 0x80;
+ m_int_reg[INTETC32] |= 0x80;
break;
}
}
@@ -475,7 +477,7 @@ void tmp95c061_device::tlcs900_check_irqs()
}
/* Check regular irqs */
- for( i = 0; i < TMP95C061_NUM_MASKABLE_IRQS; i++ )
+ for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
{
if ( m_int_reg[tmp95c061_irq_vector_map[i].reg] & tmp95c061_irq_vector_map[i].iff )
{
@@ -563,7 +565,7 @@ void tmp95c061_device::tlcs900_handle_ad()
m_ad_mode &= ~ 0x40;
m_ad_mode |= 0x80;
- m_int_reg[TMP95C061_INTE0AD] |= 0x80;
+ m_int_reg[INTE0AD] |= 0x80;
m_check_irqs = 1;
/* AD repeat mode */
@@ -661,7 +663,7 @@ void tmp95c061_device::tlcs900_handle_timers()
if ( ( m_t8_mode[0] & 0xc0 ) != 0x40 )
{
m_timer[0] = 0;
- m_int_reg[TMP95C061_INTET10] |= 0x08;
+ m_int_reg[INTET10] |= 0x08;
}
}
}
@@ -691,7 +693,7 @@ void tmp95c061_device::tlcs900_handle_timers()
if ( m_timer[1] == m_t8_reg[1] )
{
m_timer[1] = 0;
- m_int_reg[TMP95C061_INTET10] |= 0x80;
+ m_int_reg[INTET10] |= 0x80;
if ( m_t8_invert & 0x02 )
{
@@ -738,7 +740,7 @@ void tmp95c061_device::tlcs900_handle_timers()
if ( ( m_t8_mode[1] & 0xc0 ) != 0x40 )
{
m_timer[2] = 0;
- m_int_reg[TMP95C061_INTET32] |= 0x08;
+ m_int_reg[INTET32] |= 0x08;
}
}
}
@@ -768,7 +770,7 @@ void tmp95c061_device::tlcs900_handle_timers()
if ( m_timer[3] == m_t8_reg[3] )
{
m_timer[3] = 0;
- m_int_reg[TMP95C061_INTET32] |= 0x80;
+ m_int_reg[INTET32] |= 0x80;
if ( m_t8_invert & 0x20 )
{
@@ -815,16 +817,16 @@ void tmp95c061_device::execute_set_input(int input, int level)
{
/* Leave HALT state */
m_halted = 0;
- m_int_reg[TMP95C061_INTE0AD] |= 0x08;
+ m_int_reg[INTE0AD] |= 0x08;
}
}
else
{
/* Level detect */
if ( level == ASSERT_LINE )
- m_int_reg[TMP95C061_INTE0AD] |= 0x08;
+ m_int_reg[INTE0AD] |= 0x08;
else
- m_int_reg[TMP95C061_INTE0AD] &= ~ 0x08;
+ m_int_reg[INTE0AD] &= ~ 0x08;
}
}
m_level[TLCS900_INT0] = level;
@@ -835,7 +837,7 @@ void tmp95c061_device::execute_set_input(int input, int level)
{
if ( m_level[TLCS900_INT4] == CLEAR_LINE && level == ASSERT_LINE )
{
- m_int_reg[TMP95C061_INTE45] |= 0x08;
+ m_int_reg[INTE45] |= 0x08;
}
}
m_level[TLCS900_INT4] = level;
@@ -846,7 +848,7 @@ void tmp95c061_device::execute_set_input(int input, int level)
{
if ( m_level[TLCS900_INT5] == CLEAR_LINE && level == ASSERT_LINE )
{
- m_int_reg[TMP95C061_INTE45] |= 0x80;
+ m_int_reg[INTE45] |= 0x80;
}
}
m_level[TLCS900_INT5] = level;
@@ -1262,7 +1264,7 @@ uint8_t tmp95c061_device::sc0buf_r()
void tmp95c061_device::sc0buf_w(uint8_t data)
{
// Fake finish sending data
- m_int_reg[TMP95C061_INTES0] |= 0x80;
+ m_int_reg[INTES0] |= 0x80;
m_check_irqs = 1;
}
@@ -1307,7 +1309,7 @@ uint8_t tmp95c061_device::sc1buf_r()
void tmp95c061_device::sc1buf_w(uint8_t data)
{
// Fake finish sending data
- m_int_reg[TMP95C061_INTES1] |= 0x80;
+ m_int_reg[INTES1] |= 0x80;
m_check_irqs = 1;
}
@@ -1364,7 +1366,7 @@ uint8_t tmp95c061_device::adreg_r(offs_t offset)
return m_ad_result[offset >> 1] >> 2;
// Reading data from the upper 8 bits clears INTE0AD IADC
- m_int_reg[TMP95C061_INTE0AD] &= ~0x80;
+ m_int_reg[INTE0AD] &= ~0x80;
return m_ad_result[offset >> 1] << 6 | 0x3f;
}
diff --git a/src/devices/cpu/tlcs900/tmp95c063.cpp b/src/devices/cpu/tlcs900/tmp95c063.cpp
index c70a19e85cc..7de78938de9 100644
--- a/src/devices/cpu/tlcs900/tmp95c063.cpp
+++ b/src/devices/cpu/tlcs900/tmp95c063.cpp
@@ -176,64 +176,64 @@ void tmp95c063_device::device_config_complete()
}
}
+enum
+{
+ INTE0AD,
+ INTE12,
+ INTE34,
+ INTE56,
+ INTE78,
+ INTET01,
+ INTET23,
+ INTET45,
+ INTET67,
+ INTET89,
+ INTETAB,
+ INTES0,
+ INTES1,
+ INTETC01,
+ INTETC23
+};
-
-#define TMP95C063_INTE0AD 0x0
-#define TMP95C063_INTE12 0x1
-#define TMP95C063_INTE34 0x2
-#define TMP95C063_INTE56 0x3
-#define TMP95C063_INTE78 0x4
-#define TMP95C063_INTET01 0x5
-#define TMP95C063_INTET23 0x6
-#define TMP95C063_INTET45 0x7
-#define TMP95C063_INTET67 0x8
-#define TMP95C063_INTET89 0x9
-#define TMP95C063_INTETAB 0xa
-#define TMP95C063_INTES0 0xb
-#define TMP95C063_INTES1 0xc
-#define TMP95C063_INTETC01 0xd
-#define TMP95C063_INTETC23 0xe
-
-
-#define TMP95C063_NUM_MASKABLE_IRQS 30
static const struct {
uint8_t reg;
uint8_t iff;
uint8_t vector;
-} tmp95c063_irq_vector_map[TMP95C063_NUM_MASKABLE_IRQS] =
-{
- { TMP95C063_INTETC23, 0x80, 0xa0 }, /* INTTC3 */
- { TMP95C063_INTETC23, 0x08, 0x9c }, /* INTTC2 */
- { TMP95C063_INTETC01, 0x80, 0x98 }, /* INTTC1 */
- { TMP95C063_INTETC01, 0x08, 0x94 }, /* INTTC0 */
- { TMP95C063_INTE0AD, 0x80, 0x90 }, /* INTAD */
- { TMP95C063_INTES1, 0x80, 0x8c }, /* INTTX1 */
- { TMP95C063_INTES1, 0x08, 0x88 }, /* INTRX1 */
- { TMP95C063_INTES0, 0x80, 0x84 }, /* INTTX0 */
- { TMP95C063_INTES0, 0x08, 0x80 }, /* INTRX0 */
- { TMP95C063_INTETAB, 0x80, 0x7c }, /* INTTRB */
- { TMP95C063_INTETAB, 0x08, 0x78 }, /* INTTRA */
- { TMP95C063_INTET89, 0x80, 0x74 }, /* INTTR9 */
- { TMP95C063_INTET89, 0x80, 0x70 }, /* INTTR8 */
- { TMP95C063_INTET67, 0x80, 0x6c }, /* INTT7 */
- { TMP95C063_INTET67, 0x08, 0x68 }, /* INTT6 */
- { TMP95C063_INTET45, 0x80, 0x64 }, /* INTT5 */
- { TMP95C063_INTET45, 0x08, 0x60 }, /* INTT4 */
- { TMP95C063_INTET23, 0x80, 0x5c }, /* INTT3 */
- { TMP95C063_INTET23, 0x08, 0x58 }, /* INTT2 */
- { TMP95C063_INTET01, 0x80, 0x54 }, /* INTT1 */
- { TMP95C063_INTET01, 0x08, 0x50 }, /* INTT0 */
- { TMP95C063_INTE78, 0x80, 0x4c }, /* int8_t */
- { TMP95C063_INTE78, 0x08, 0x48 }, /* INT7 */
- { TMP95C063_INTE56, 0x80, 0x44 }, /* INT6 */
- { TMP95C063_INTE56, 0x08, 0x40 }, /* INT5 */
- /* 0x3c - reserved */
- { TMP95C063_INTE34, 0x80, 0x38 }, /* INT4 */
- { TMP95C063_INTE34, 0x08, 0x34 }, /* INT3 */
- { TMP95C063_INTE12, 0x80, 0x30 }, /* INT2 */
- { TMP95C063_INTE12, 0x08, 0x2c }, /* INT1 */
- { TMP95C063_INTE0AD, 0x08, 0x28 } /* INT0 */
+} tmp95c063_irq_vector_map[] =
+{
+ { INTETC23, 0x80, 0xa0 }, // INTTC3
+ { INTETC23, 0x08, 0x9c }, // INTTC2
+ { INTETC01, 0x80, 0x98 }, // INTTC1
+ { INTETC01, 0x08, 0x94 }, // INTTC0
+ { INTE0AD, 0x80, 0x90 }, // INTAD
+ { INTES1, 0x80, 0x8c }, // INTTX1
+ { INTES1, 0x08, 0x88 }, // INTRX1
+ { INTES0, 0x80, 0x84 }, // INTTX0
+ { INTES0, 0x08, 0x80 }, // INTRX0
+ { INTETAB, 0x80, 0x7c }, // INTTRB
+ { INTETAB, 0x08, 0x78 }, // INTTRA
+ { INTET89, 0x80, 0x74 }, // INTTR9
+ { INTET89, 0x80, 0x70 }, // INTTR8
+ { INTET67, 0x80, 0x6c }, // INTT7
+ { INTET67, 0x08, 0x68 }, // INTT6
+ { INTET45, 0x80, 0x64 }, // INTT5
+ { INTET45, 0x08, 0x60 }, // INTT4
+ { INTET23, 0x80, 0x5c }, // INTT3
+ { INTET23, 0x08, 0x58 }, // INTT2
+ { INTET01, 0x80, 0x54 }, // INTT1
+ { INTET01, 0x08, 0x50 }, // INTT0
+ { INTE78, 0x80, 0x4c }, // INT8
+ { INTE78, 0x08, 0x48 }, // INT7
+ { INTE56, 0x80, 0x44 }, // INT6
+ { INTE56, 0x08, 0x40 }, // INT5
+ // 0x3c - reserved
+ { INTE34, 0x80, 0x38 }, // INT4
+ { INTE34, 0x08, 0x34 }, // INT3
+ { INTE12, 0x80, 0x30 }, // INT2
+ { INTE12, 0x08, 0x2c }, // INT1
+ { INTE0AD, 0x08, 0x28 } // INT0
};
+static constexpr u8 NUM_MASKABLE_IRQS = sizeof(tmp95c063_irq_vector_map) / 3;
void tmp95c063_device::tlcs900_handle_timers()
{
@@ -277,7 +277,7 @@ void tmp95c063_device::tlcs900_handle_timers()
if ( ( m_t8_mode[0] & 0xc0 ) != 0x40 )
{
m_timer[0] = 0;
- m_int_reg[TMP95C063_INTET01] |= 0x08;
+ m_int_reg[INTET01] |= 0x08;
}
}
}
@@ -307,7 +307,7 @@ void tmp95c063_device::tlcs900_handle_timers()
if ( m_timer[1] == m_t8_reg[1] )
{
m_timer[1] = 0;
- m_int_reg[TMP95C063_INTET01] |= 0x80;
+ m_int_reg[INTET01] |= 0x80;
if ( m_t8_invert[0] & 0x02 )
{
@@ -354,7 +354,7 @@ void tmp95c063_device::tlcs900_handle_timers()
if ( ( m_t8_mode[1] & 0xc0 ) != 0x40 )
{
m_timer[2] = 0;
- m_int_reg[TMP95C063_INTET23] |= 0x08;
+ m_int_reg[INTET23] |= 0x08;
}
}
}
@@ -384,7 +384,7 @@ void tmp95c063_device::tlcs900_handle_timers()
if ( m_timer[3] == m_t8_reg[3] )
{
m_timer[3] = 0;
- m_int_reg[TMP95C063_INTET23] |= 0x80;
+ m_int_reg[INTET23] |= 0x80;
if ( m_t8_invert[1] & 0x20 )
{
@@ -434,7 +434,7 @@ void tmp95c063_device::tlcs900_check_irqs()
}
/* Check regular irqs */
- for( i = 0; i < TMP95C063_NUM_MASKABLE_IRQS; i++ )
+ for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
{
if ( m_int_reg[tmp95c063_irq_vector_map[i].reg] & tmp95c063_irq_vector_map[i].iff )
{
@@ -544,7 +544,7 @@ void tmp95c063_device::tlcs900_handle_ad()
m_ad_mode1 &= ~ 0x40;
m_ad_mode1 |= 0x80;
- m_int_reg[TMP95C063_INTE0AD] |= 0x80;
+ m_int_reg[INTE0AD] |= 0x80;
m_check_irqs = 1;
}
}
@@ -1225,7 +1225,7 @@ uint8_t tmp95c063_device::sc0buf_r()
void tmp95c063_device::sc0buf_w(uint8_t data)
{
// Fake finish sending data
- m_int_reg[TMP95C063_INTES0] |= 0x80;
+ m_int_reg[INTES0] |= 0x80;
m_check_irqs = 1;
}
@@ -1270,7 +1270,7 @@ uint8_t tmp95c063_device::sc1buf_r()
void tmp95c063_device::sc1buf_w(uint8_t data)
{
// Fake finish sending data
- m_int_reg[TMP95C063_INTES1] |= 0x80;
+ m_int_reg[INTES1] |= 0x80;
m_check_irqs = 1;
}
@@ -1503,16 +1503,16 @@ void tmp95c063_device::execute_set_input(int input, int level)
{
/* Leave HALT state */
m_halted = 0;
- m_int_reg[TMP95C063_INTE0AD] |= 0x08;
+ m_int_reg[INTE0AD] |= 0x08;
}
}
else
{
/* Level detect */
if (level == ASSERT_LINE)
- m_int_reg[TMP95C063_INTE0AD] |= 0x08;
+ m_int_reg[INTE0AD] |= 0x08;
else
- m_int_reg[TMP95C063_INTE0AD] &= ~ 0x08;
+ m_int_reg[INTE0AD] &= ~ 0x08;
}
}
m_level[TLCS900_INT0] = level;
@@ -1521,11 +1521,11 @@ void tmp95c063_device::execute_set_input(int input, int level)
case TLCS900_INT1:
if (m_level[TLCS900_INT1] == CLEAR_LINE && level == ASSERT_LINE)
{
- m_int_reg[TMP95C063_INTE12] |= 0x08;
+ m_int_reg[INTE12] |= 0x08;
}
else if (m_level[TLCS900_INT1] == ASSERT_LINE && level == CLEAR_LINE)
{
- m_int_reg[TMP95C063_INTE12] &= ~0x08;
+ m_int_reg[INTE12] &= ~0x08;
}
m_level[TLCS900_INT1] = level;
break;
@@ -1533,11 +1533,11 @@ void tmp95c063_device::execute_set_input(int input, int level)
case TLCS900_INT2:
if (m_level[TLCS900_INT2] == CLEAR_LINE && level == ASSERT_LINE)
{
- m_int_reg[TMP95C063_INTE12] |= 0x80;
+ m_int_reg[INTE12] |= 0x80;
}
else if (m_level[TLCS900_INT2] == ASSERT_LINE && level == CLEAR_LINE)
{
- m_int_reg[TMP95C063_INTE12] &= ~0x80;
+ m_int_reg[INTE12] &= ~0x80;
}
m_level[TLCS900_INT2] = level;
break;
@@ -1545,11 +1545,11 @@ void tmp95c063_device::execute_set_input(int input, int level)
case TLCS900_INT3:
if (m_level[TLCS900_INT3] == CLEAR_LINE && level == ASSERT_LINE)
{
- m_int_reg[TMP95C063_INTE34] |= 0x08;
+ m_int_reg[INTE34] |= 0x08;
}
else if (m_level[TLCS900_INT3] == ASSERT_LINE && level == CLEAR_LINE)
{
- m_int_reg[TMP95C063_INTE34] &= ~0x08;
+ m_int_reg[INTE34] &= ~0x08;
}
m_level[TLCS900_INT3] = level;
break;
@@ -1559,7 +1559,7 @@ void tmp95c063_device::execute_set_input(int input, int level)
{
if ( m_level[TLCS900_INT4] == CLEAR_LINE && level == ASSERT_LINE )
{
- m_int_reg[TMP95C063_INTE34] |= 0x80;
+ m_int_reg[INTE34] |= 0x80;
}
}
m_level[TLCS900_INT4] = level;
@@ -1570,7 +1570,7 @@ void tmp95c063_device::execute_set_input(int input, int level)
{
if ( m_level[TLCS900_INT5] == CLEAR_LINE && level == ASSERT_LINE )
{
- m_int_reg[TMP95C063_INTE56] |= 0x08;
+ m_int_reg[INTE56] |= 0x08;
}
}
m_level[TLCS900_INT5] = level;
@@ -1579,11 +1579,11 @@ void tmp95c063_device::execute_set_input(int input, int level)
case TLCS900_INT6:
if (m_level[TLCS900_INT6] == CLEAR_LINE && level == ASSERT_LINE)
{
- m_int_reg[TMP95C063_INTE56] |= 0x80;
+ m_int_reg[INTE56] |= 0x80;
}
else if (m_level[TLCS900_INT6] == ASSERT_LINE && level == CLEAR_LINE)
{
- m_int_reg[TMP95C063_INTE56] &= ~0x80;
+ m_int_reg[INTE56] &= ~0x80;
}
m_level[TLCS900_INT6] = level;
break;
diff --git a/src/mame/funtech/supracan.cpp b/src/mame/funtech/supracan.cpp
index b72028b0561..04a17f8d451 100644
--- a/src/mame/funtech/supracan.cpp
+++ b/src/mame/funtech/supracan.cpp
@@ -65,8 +65,8 @@ Super A'Can (c) 1995 Funtech
#include "emu.h"
-#include "bus/generic/slot.h"
-#include "bus/generic/carts.h"
+#include "bus/supracan/rom.h"
+#include "bus/supracan/slot.h"
#include "cpu/m68000/m68000.h"
#include "cpu/m6502/m65c02.h"
@@ -179,7 +179,7 @@ class supracan_state : public driver_device
required_device m_maincpu;
required_device m_soundcpu;
- required_device m_cart;
+ required_device m_cart;
required_device m_lockout;
required_region_ptr m_internal68;
memory_view m_main_loview;
@@ -227,6 +227,12 @@ class supracan_state : public driver_device
uint16_t m_tilemap_flags[3]{};
uint16_t m_tilemap_mode[3]{};
uint16_t m_tilemap_tile_mode[3]{};
+ uint16_t m_tilemap_linescrollx_addr[3]{};
+
+ uint16_t m_window_control[2]{};
+ uint16_t m_window_start_addr[2]{};
+ uint16_t m_window_scrollx[2]{};
+ uint16_t m_window_scrolly[2]{};
uint32_t m_roz_base_addr = 0;
uint16_t m_roz_mode = 0;
@@ -242,7 +248,6 @@ class supracan_state : public driver_device
uint16_t m_roz_coeffc = 0;
uint16_t m_roz_coeffd = 0;
int32_t m_roz_changed = 0;
- uint16_t m_unk_1d0 = 0;
u8 m_pixel_mode = 0;
u8 m_gfx_mode = 0;
@@ -265,7 +270,6 @@ class supracan_state : public driver_device
TIMER_CALLBACK_MEMBER(line_on_cb);
TIMER_CALLBACK_MEMBER(line_off_cb);
TIMER_CALLBACK_MEMBER(scanline_cb);
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
int get_tilemap_region(int layer);
void get_tilemap_info_common(int layer, tile_data &tileinfo, int count);
void get_roz_tilemap_info(int layer, tile_data &tileinfo, int count);
@@ -308,7 +312,7 @@ int supracan_state::get_tilemap_region(int layer)
}
// TODO: 4th layer at $f00160 (gfx mode 0 only, ignored for everything else)
- throw new emu_fatalerror("Error: layer = %d not defined", layer);
+ throw emu_fatalerror("Error: layer = %d not defined", layer);
}
void supracan_state::get_tilemap_info_common(int layer, tile_data &tileinfo, int count)
@@ -1015,7 +1019,6 @@ uint32_t supracan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
// mix screen
int xsize = 0, ysize = 0;
// int tilemap_num;
- int priority = 0;
for (int pri = 7; pri >= 0; pri--)
{
@@ -1023,6 +1026,7 @@ uint32_t supracan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
for (int layer = 0; layer < ROZ_LAYER_NUMBER + 1; layer ++)
{
int enabled = 0;
+ int layer_priority = 0;
// ROZ
if (layer == ROZ_LAYER_NUMBER)
@@ -1030,17 +1034,17 @@ uint32_t supracan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
enabled = BIT(m_video_flags, 2);
if (!enabled)
continue;
- priority = ((m_roz_mode >> 13) & 7);
+ layer_priority = ((m_roz_mode >> 13) & 7);
}
else
{
enabled = BIT(m_video_flags, 7 - layer);
if (!enabled)
continue;
- priority = ((m_tilemap_flags[layer] >> 13) & 7);
+ layer_priority = ((m_tilemap_flags[layer] >> 13) & 7);
}
- if (priority == pri)
+ if (layer_priority == pri)
{
int which_tilemap_size = get_tilemap_dimensions(xsize, ysize, layer);
bitmap_ind16 &src_bitmap = m_tilemap_sizes[layer][which_tilemap_size]->pixmap();
@@ -1094,22 +1098,30 @@ uint32_t supracan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
uint16_t *src = &src_bitmap.pix(realy & ((ysize * 8) - 1));
uint8_t *priop = &m_prio_bitmap.pix(y);
+ int line_scroll_x = scrollx;
+
+ // formduel main menu
+ if (BIT(m_tilemap_tile_mode[layer], 14))
+ {
+ int16_t linescrollx = (int16_t)m_vram[((m_tilemap_linescrollx_addr[layer] << 1) + y) & 0xffff];
+ line_scroll_x += linescrollx;
+ }
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
int actualx = x & mosaic_mask;
- int realx = actualx + scrollx;
+ int realx = actualx + line_scroll_x;
if (!wrap)
- if (scrollx + x < 0 || scrollx + x > ((xsize * 8) - 1))
+ if (line_scroll_x + x < 0 || line_scroll_x + x > ((xsize * 8) - 1))
continue;
uint16_t srcpix = src[realx & ((xsize * 8) - 1)];
- if ((srcpix & transmask) != 0 && priority < (priop[x] >> 4))
+ if ((srcpix & transmask) != 0 && layer_priority < (priop[x] >> 4))
{
screen[x] = srcpix;
- priop[x] = (priop[x] & 0x0f) | (priority << 4);
+ priop[x] = (priop[x] & 0x0f) | (layer_priority << 4);
}
}
}
@@ -1178,6 +1190,49 @@ uint32_t supracan_state::screen_update(screen_device &screen, bitmap_ind16 &bitm
}
}
+
+ // TODO: secondary window control at $1d8-$1df (no SW sets it up so far)
+ if (BIT(m_video_flags, 1))
+ {
+ // bit 15: enabled by magipool at circular intro, will show sprites above it if checked with.
+ int layer_priority = ((m_window_control[0] >> 13) & 3);
+ if (pri != layer_priority)
+ continue;
+ const u8 reverse_clip = BIT(m_window_control[0], 11);
+ // magipool enables this on title screen
+ // (for the white "overlay", revealing Funtech copyright progressively)
+ // TODO: confirm implementation
+ int window_scrollx = m_window_scrollx[0] & 0x3ff;
+ // TODO: window_scrolly
+
+ if (window_scrollx & 0x200)
+ window_scrollx -= 0x400;
+
+ const u8 window_pen = m_window_control[0] & 0xff;
+
+ for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
+ {
+ // bit 8 is unset by sangofgt, where it uses only two entries of the table on transitions.
+ const int ybase = BIT(m_window_control[0], 8) ? (y * 2) : 0;
+ const u32 clip_base = ((m_window_start_addr[0] << 1) + ybase) & 0xffff;
+
+ const int16_t clip_min_x = (m_vram[clip_base + 0] + window_scrollx);
+ const int16_t clip_max_x = (m_vram[clip_base + 1] + window_scrollx);
+ uint8_t *priop = &m_prio_bitmap.pix(y);
+
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
+ {
+ if (layer_priority >= (priop[x] >> 4))
+ continue;
+
+ if ((x >= clip_min_x && x < clip_max_x) ^ reverse_clip)
+ {
+ bitmap.pix(y, x) = window_pen;
+ priop[x] = (priop[x] & 0x0f) | (layer_priority << 4);
+ }
+ }
+ }
+ }
}
@@ -1349,9 +1404,9 @@ void supracan_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
void supracan_state::main_map(address_map &map)
{
map(0x000000, 0x3fffff).view(m_main_loview);
- m_main_loview[0](0x000000, 0x3fffff).r(m_cart, FUNC(generic_slot_device::read16_rom));
+ m_main_loview[0](0x000000, 0x3fffff).r(m_cart, FUNC(superacan_cart_slot_device::rom_r)),
m_main_loview[0](0x000000, 0x000fff).rom().region(m_internal68, 0);
- m_main_loview[1](0x000000, 0x3fffff).r(m_cart, FUNC(generic_slot_device::read16_rom));
+ m_main_loview[1](0x000000, 0x3fffff).r(m_cart, FUNC(superacan_cart_slot_device::rom_r));
map(0xe80000, 0xe8ffff).rw(FUNC(supracan_state::_68k_soundram_r), FUNC(supracan_state::_68k_soundram_w));
map(0xe90000, 0xe9001f).m(*this, FUNC(supracan_state::host_um6619_map));
map(0xe90020, 0xe9002f).w(FUNC(supracan_state::dma_w<0>));
@@ -1361,15 +1416,15 @@ void supracan_state::main_map(address_map &map)
map(0xeb0d00, 0xeb0d03).rw(m_lockout, FUNC(umc6650_device::read), FUNC(umc6650_device::write)).umask16(0x00ff);
-// map(0xec0000, 0xec*fff) Cart NVRAM, 8-bit interface
+ map(0xec0000, 0xecffff).rw(m_cart, FUNC(superacan_cart_slot_device::nvram_r), FUNC(superacan_cart_slot_device::nvram_w)).umask16(0x00ff);
map(0xf00000, 0xf001ff).rw(FUNC(supracan_state::video_r), FUNC(supracan_state::video_w));
map(0xf00200, 0xf003ff).ram().w("palette", FUNC(palette_device::write16)).share("palette");
map(0xf40000, 0xf5ffff).ram().w(FUNC(supracan_state::vram_w)).share("vram");
map(0xf80000, 0xfbffff).view(m_main_hiview);
- m_main_hiview[0](0xf80000, 0xfbffff).r(m_cart, FUNC(generic_slot_device::read16_rom));
+ m_main_hiview[0](0xf80000, 0xfbffff).r(m_cart, FUNC(superacan_cart_slot_device::rom_r));
m_main_hiview[0](0xf80000, 0xf80fff).rom().region(m_internal68, 0);
- m_main_hiview[1](0xf80000, 0xfbffff).r(m_cart, FUNC(generic_slot_device::read16_rom));
+ m_main_hiview[1](0xf80000, 0xfbffff).r(m_cart, FUNC(superacan_cart_slot_device::rom_r));
map(0xfc0000, 0xfcffff).mirror(0x30000).ram(); /* System work ram */
}
@@ -1830,6 +1885,12 @@ TIMER_CALLBACK_MEMBER(supracan_state::scanline_cb)
m_soundcpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
break;
+ default:
+ // Effectively used by sangofgt only for clipping effects
+ // gamblord, monopoly, magipool also enables this but service is rte for all.
+ if (vpos < 240 && BIT(m_irq_mask, 4))
+ m_maincpu->set_input_line(4, HOLD_LINE);
+ break;
}
m_video_timer->adjust(m_screen->time_until_pos((vpos + 1) % 262, 0));
@@ -1944,6 +2005,7 @@ void supracan_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
visarea.set(0, (h320_mode ? 320 : 256) - 1, 8, 232 - 1);
m_screen->configure(htotal, 262, visarea, attotime::from_ticks(htotal * 262, U13_CLOCK / divider).as_attoseconds());
+ //m_screen->reset_origin(0, 0);
}
m_video_flags = data;
@@ -1992,6 +2054,7 @@ void supracan_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
case 0x106/2: m_tilemap_scrolly[0] = data; LOGMASKED(LOG_TILEMAP0, "tilemap_scrolly[0] = %04x\n", data); break;
case 0x108/2: m_tilemap_base_addr[0] = data << 1; LOGMASKED(LOG_TILEMAP0, "tilemap_base_addr[0] = %05x\n", data << 2); break;
case 0x10a/2: m_tilemap_mode[0] = data; LOGMASKED(LOG_TILEMAP0, "tilemap_mode[0] = %04x\n", data); break;
+ case 0x10c/2: m_tilemap_linescrollx_addr[0] = data; break;
/* Tilemap 1 */
case 0x120/2: {
@@ -2005,6 +2068,7 @@ void supracan_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
case 0x126/2: m_tilemap_scrolly[1] = data; LOGMASKED(LOG_TILEMAP1, "tilemap_scrolly[1] = %04x\n", data); break;
case 0x128/2: m_tilemap_base_addr[1] = data << 1; LOGMASKED(LOG_TILEMAP1, "tilemap_base_addr[1] = %05x\n", data << 2); break;
case 0x12a/2: m_tilemap_mode[1] = data; LOGMASKED(LOG_TILEMAP1, "tilemap_mode[1] = %04x\n", data); break;
+ case 0x12c/2: m_tilemap_linescrollx_addr[1] = data; break;
/* Tilemap 2 */
case 0x140/2: {
@@ -2018,6 +2082,7 @@ void supracan_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
case 0x146/2: m_tilemap_scrolly[2] = data; LOGMASKED(LOG_TILEMAP2, "tilemap_scrolly[2] = %04x\n", data); break;
case 0x148/2: m_tilemap_base_addr[2] = data << 1; LOGMASKED(LOG_TILEMAP2, "tilemap_base_addr[2] = %05x\n", data << 2); break;
case 0x14a/2: m_tilemap_mode[2] = data; LOGMASKED(LOG_TILEMAP2, "tilemap_mode[2] = %04x\n", data); break;
+ case 0x14c/2: m_tilemap_linescrollx_addr[2] = data; break;
/* ROZ */
case 0x180/2: {
@@ -2042,7 +2107,14 @@ void supracan_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
case 0x19e/2: m_roz_unk_base2 = data << 2; LOGMASKED(LOG_ROZ, "roz_unk_base2 = %05x\n", data << 2); break;
// color mixing stuff goes here
- case 0x1d0/2: m_unk_1d0 = data; LOGMASKED(LOG_UNKNOWNS, "unk_1d0 = %04x\n", data); break;
+ case 0x1d0/2: COMBINE_DATA(&m_window_control[0]); break;
+ case 0x1d2/2: COMBINE_DATA(&m_window_start_addr[0]); break;
+ case 0x1d4/2: COMBINE_DATA(&m_window_scrollx[0]); break;
+ case 0x1d6/2: COMBINE_DATA(&m_window_scrolly[0]); break;
+ case 0x1d8/2: COMBINE_DATA(&m_window_control[1]); break;
+ case 0x1da/2: COMBINE_DATA(&m_window_start_addr[1]); break;
+ case 0x1dc/2: COMBINE_DATA(&m_window_scrollx[1]); break;
+ case 0x1de/2: COMBINE_DATA(&m_window_scrolly[1]); break;
case 0x1f0/2:
m_pixel_mode = data & 0x18;
@@ -2060,20 +2132,6 @@ void supracan_state::video_w(offs_t offset, uint16_t data, uint16_t mem_mask)
// m_video_regs[offset] = data;
}
-
-DEVICE_IMAGE_LOAD_MEMBER(supracan_state::cart_load)
-{
- uint32_t size = m_cart->common_get_size("rom");
-
- if (size > 0x40'0000)
- return std::make_pair(image_error::INVALIDLENGTH, "Unsupported cartridge size (must be no larger than 4M)");
-
- m_cart->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG);
- m_cart->common_load_rom(m_cart->get_rom_base(), size, "rom");
-
- return std::make_pair(std::error_condition(), std::string());
-}
-
static INPUT_PORTS_START( supracan )
PORT_START("P1")
PORT_BIT(0x000f, IP_ACTIVE_LOW, IPT_UNUSED)
@@ -2155,7 +2213,10 @@ void supracan_state::machine_start()
save_item(NAME(m_roz_coeffc));
save_item(NAME(m_roz_coeffd));
save_item(NAME(m_roz_changed));
- save_item(NAME(m_unk_1d0));
+ save_item(NAME(m_window_control));
+ save_item(NAME(m_window_start_addr));
+ save_item(NAME(m_window_scrollx));
+ save_item(NAME(m_window_scrolly));
save_item(NAME(m_video_regs));
@@ -2275,6 +2336,12 @@ static GFXDECODE_START( gfx_supracan )
GFXDECODE_RAM( "vram", 0, supracan_gfx1bpp_alt, 0, 0x80 )
GFXDECODE_END
+static void superacan_cart_types(device_slot_interface &device)
+{
+ device.option_add_internal("std", SUPERACAN_ROM_STD);
+}
+
+
void supracan_state::supracan(machine_config &config)
{
// M68000P10
@@ -2311,11 +2378,8 @@ void supracan_state::supracan(machine_config &config)
m_sound->add_route(0, "lspeaker", 1.0);
m_sound->add_route(1, "rspeaker", 1.0);
- generic_cartslot_device &cartslot(GENERIC_CARTSLOT(config, "cartslot", generic_plain_slot, "supracan_cart"));
- cartslot.set_must_be_loaded(true);
- cartslot.set_width(GENERIC_ROM16_WIDTH);
- cartslot.set_endian(ENDIANNESS_BIG);
- cartslot.set_device_load(FUNC(supracan_state::cart_load));
+ // TODO: clock for cart is (again) unconfirmed
+ SUPERACAN_CART_SLOT(config, m_cart, U13_CLOCK / 6, superacan_cart_types, nullptr).set_must_be_loaded(true);
SOFTWARE_LIST(config, "cart_list").set_original("supracan");
}
diff --git a/src/mame/funtech/umc6619_sound.cpp b/src/mame/funtech/umc6619_sound.cpp
index bf847eb12c7..40e08237e9c 100644
--- a/src/mame/funtech/umc6619_sound.cpp
+++ b/src/mame/funtech/umc6619_sound.cpp
@@ -14,6 +14,8 @@
#define VERBOSE (0)
#include "logmacro.h"
+#define LIVE_AUDIO_VIEW 0
+
// device type definition
DEFINE_DEVICE_TYPE(UMC6619_SOUND, umc6619_sound_device, "umc6619_sound", "UMC UM6619 Sound Engine")
@@ -53,6 +55,7 @@ void umc6619_sound_device::device_start()
save_item(STRUCT_MEMBER(m_channels, volume_l));
save_item(STRUCT_MEMBER(m_channels, volume_r));
save_item(STRUCT_MEMBER(m_channels, one_shot));
+ save_item(STRUCT_MEMBER(m_channels, unk_upper_05));
save_item(NAME(m_regs));
}
@@ -64,7 +67,20 @@ void umc6619_sound_device::device_reset()
for (auto &channel : m_channels)
{
+ channel.pitch = 0;
+ channel.length = 0;
+ channel.start_addr = 0;
+ channel.curr_addr = 0;
+ channel.end_addr = 0;
+ channel.addr_increment = 0;
+ channel.frac = 0;
channel.register9 = 0;
+ std::fill(std::begin(channel.envelope), std::end(channel.envelope), 0);
+ channel.volume = 0;
+ channel.volume_l = 0;
+ channel.volume_r = 0;
+ channel.one_shot = false;
+ channel.unk_upper_05 = 0;
}
m_timer->reset();
@@ -84,10 +100,45 @@ TIMER_CALLBACK_MEMBER(umc6619_sound_device::channel_irq)
}
}
+std::string umc6619_sound_device::print_audio_state()
+{
+ std::ostringstream outbuffer;
+
+ util::stream_format(outbuffer, "channel | address | length | pitch | one? | vol | DMA? | (unk09) |\n");
+
+ for (int i = 0; i < 16; i++)
+ {
+ acan_channel &channel = m_channels[i];
+
+ util::stream_format(outbuffer, "%02d: %01d | %04x (%04x-%04x) | %04x | %04x | %d (%02x)| %02x | %02x | %02x %02x %02x %02x|\n"
+ , i
+ , BIT(m_active_channels, i)
+ , channel.curr_addr
+ , (channel.start_addr << 6) & 0xffff
+ , channel.end_addr
+ , channel.length
+ , channel.pitch
+ , channel.one_shot
+ , channel.unk_upper_05
+ , channel.volume
+ , channel.register9
+ , channel.envelope[0]
+ , channel.envelope[1]
+ , channel.envelope[2]
+ , channel.envelope[3]
+ );
+ }
+
+ return outbuffer.str();
+}
+
void umc6619_sound_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs)
{
std::fill_n(&m_mix[0], outputs[0].samples() * 2, 0);
+ if (LIVE_AUDIO_VIEW)
+ popmessage(print_audio_state());
+
for (int i = 0; i < 16 && m_active_channels != 0; i++)
{
if (BIT(m_active_channels, i))
@@ -244,6 +295,7 @@ void umc6619_sound_device::write(offs_t offset, uint8_t data)
acan_channel &channel = m_channels[lower];
channel.length = 0x40 << ((data & 0x0e) >> 1);
channel.one_shot = BIT(data, 0);
+ channel.unk_upper_05 = data & 0xf0;
LOG("%s: Waveform length and attributes (voice %02x): %02x\n", machine().describe_context(), lower, data);
break;
}
diff --git a/src/mame/funtech/umc6619_sound.h b/src/mame/funtech/umc6619_sound.h
index d607735c7c9..17dff54dc46 100644
--- a/src/mame/funtech/umc6619_sound.h
+++ b/src/mame/funtech/umc6619_sound.h
@@ -49,6 +49,7 @@ class umc6619_sound_device : public device_t, public device_sound_interface
uint8_t volume_l;
uint8_t volume_r;
bool one_shot;
+ uint8_t unk_upper_05;
};
void keyon_voice(uint8_t voice);
@@ -63,6 +64,8 @@ class umc6619_sound_device : public device_t, public device_sound_interface
acan_channel m_channels[16];
uint8_t m_regs[256];
std::unique_ptr m_mix;
+
+ std::string print_audio_state();
};
DECLARE_DEVICE_TYPE(UMC6619_SOUND, umc6619_sound_device)
diff --git a/src/mame/igs/igs_m027.cpp b/src/mame/igs/igs_m027.cpp
index def2669e40f..65a40c5e319 100644
--- a/src/mame/igs/igs_m027.cpp
+++ b/src/mame/igs/igs_m027.cpp
@@ -141,6 +141,7 @@ class igs_m027_state : public driver_device
template void lamps_w(u8 data);
void mahjong_output_w(u8 data);
+ void lhzb4_output_w(u8 data);
void jking02_output_w(u8 data);
void oceanpar_output_w(u8 data);
@@ -154,8 +155,8 @@ class igs_m027_state : public driver_device
void igs_mahjong_map(address_map &map) ATTR_COLD;
void igs_mahjong_xor_map(address_map &map) ATTR_COLD;
- void jking02_xor_map(address_map &map) ATTR_COLD;
void lhdmg_xor_map(address_map &map) ATTR_COLD;
+ void jking02_xor_map(address_map &map) ATTR_COLD;
void extradraw_map(address_map &map) ATTR_COLD;
};
@@ -211,18 +212,18 @@ void igs_m027_state::igs_mahjong_xor_map(address_map &map)
map(0x08000000, 0x0807ffff).r(FUNC(igs_m027_state::external_rom_r)); // Game ROM
}
-void igs_m027_state::jking02_xor_map(address_map &map)
+void igs_m027_state::lhdmg_xor_map(address_map &map)
{
igs_mahjong_xor_map(map);
- map(0x4000000c, 0x4000000f).portr("PLAYER");
+ map(0x4000000c, 0x4000000f).r(FUNC(igs_m027_state::lhdmg_unk2_r));
}
-void igs_m027_state::lhdmg_xor_map(address_map &map)
+void igs_m027_state::jking02_xor_map(address_map &map)
{
igs_mahjong_xor_map(map);
- map(0x4000000c, 0x4000000f).r(FUNC(igs_m027_state::lhdmg_unk2_r));
+ map(0x4000000c, 0x4000000f).portr("PLAYER");
}
void igs_m027_state::extradraw_map(address_map &map)
@@ -322,22 +323,25 @@ INPUT_PORTS_START( base )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
-INPUT_PORTS_START( mahjong )
- PORT_INCLUDE(igs_mahjong_matrix)
-
+INPUT_PORTS_START( mahjong_test )
PORT_START("TEST")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_TILT ) // 哈巴
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_NAME("Clear") // 清除
- 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_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) // TODO: default assignment clashes with mahjong I
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_TILT ) PORT_NAME("Hopper Switch") // 哈巴
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MEMORY_RESET ) PORT_NAME("Clear") // 清除
+ 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_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_PAYOUT ) // 退币 TODO: default assignment clashes with mahjong I
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
-INPUT_PORTS_START( mahjong_joy )
- PORT_INCLUDE(mahjong)
+INPUT_PORTS_START( mahjong_kbd )
+ PORT_INCLUDE(mahjong_test)
+ PORT_INCLUDE(igs_mahjong_matrix)
+INPUT_PORTS_END
+
+INPUT_PORTS_START( mahjong_kbd_joy )
+ PORT_INCLUDE(mahjong_kbd)
PORT_MODIFY("TEST")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
@@ -388,6 +392,56 @@ INPUT_PORTS_START( three_reel )
PORT_BIT( 0xfffe0000, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
+INPUT_PORTS_START( slqz3_dip_switches )
+ PORT_START("DSW1")
+ PORT_DIPNAME( 0x03, 0x03, DEF_STR(Coin_A) ) PORT_DIPLOCATION("SW1:1,2") // 投币比率
+ PORT_DIPSETTING( 0x03, DEF_STR(1C_1C) )
+ PORT_DIPSETTING( 0x02, DEF_STR(1C_2C) )
+ PORT_DIPSETTING( 0x01, DEF_STR(1C_3C) )
+ PORT_DIPSETTING( 0x00, DEF_STR(1C_5C) )
+ PORT_DIPNAME( 0x0c, 0x0c, "Key-In Rate" ) PORT_DIPLOCATION("SW1:3,4") // 开分比率
+ PORT_DIPSETTING( 0x0c, "10" )
+ PORT_DIPSETTING( 0x08, "20" )
+ PORT_DIPSETTING( 0x04, "50" )
+ PORT_DIPSETTING( 0x00, "100" )
+ PORT_DIPNAME( 0x10, 0x10, "Credit Limit" ) PORT_DIPLOCATION("SW1:5") // 进分上限
+ PORT_DIPSETTING( 0x10, "1000" )
+ PORT_DIPSETTING( 0x00, "2000" )
+ PORT_DIPNAME( 0x20, 0x20, "Credit Mode" ) PORT_DIPLOCATION("SW1:6") // 进分方式 (sets coin input function)
+ PORT_DIPSETTING( 0x20, "Coin Acceptor" ) // 投币 (uses coin A rate)
+ PORT_DIPSETTING( 0x00, "Key-In" ) // 开分 (uses key-in rate)
+ PORT_DIPNAME( 0x40, 0x40, "Payout Mode" ) PORT_DIPLOCATION("SW1:7") // 退分方式
+ PORT_DIPSETTING( 0x40, "Return Coins" ) // 退币 (uses hopper to pay out credits)
+ PORT_DIPSETTING( 0x00, "Key-Out" ) // 洗分 (just clears credits)
+ PORT_DIPNAME( 0x80, 0x80, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW1:8") // 示范音乐
+ PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 无
+ PORT_DIPSETTING( 0x80, DEF_STR(On) ) // 有
+
+ PORT_START("DSW2")
+ PORT_DIPNAME( 0x03, 0x03, "Double Up Jackpot" ) PORT_DIPLOCATION("SW2:1,2") // 比倍爆机
+ PORT_DIPSETTING( 0x03, "500" )
+ PORT_DIPSETTING( 0x02, "1000" )
+ PORT_DIPSETTING( 0x01, "1500" )
+ PORT_DIPSETTING( 0x00, "2000" )
+ PORT_DIPNAME( 0x0c, 0x0c, "Minimum Bet" ) PORT_DIPLOCATION("SW2:3,4") // 最小押注 (all settings show 1 in service mode and function identically)
+ PORT_DIPSETTING( 0x0c, "1" )
+ PORT_DIPSETTING( 0x08, "1" )
+ PORT_DIPSETTING( 0x04, "1" )
+ PORT_DIPSETTING( 0x00, "1" )
+ PORT_DIPNAME( 0x10, 0x10, "Double Up Game" ) PORT_DIPLOCATION("SW2:5") // 比倍游戏
+ PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 无
+ PORT_DIPSETTING( 0x10, DEF_STR(On) ) // 有
+ PORT_DIPNAME( 0x20, 0x20, "Double Up/Continue Play" ) PORT_DIPLOCATION("SW2:6") // 比倍续玩
+ PORT_DIPSETTING( 0x20, "Double Up" ) // 比倍
+ PORT_DIPSETTING( 0x00, "Continue Play" ) // 续玩
+ PORT_DIPNAME( 0x40, 0x40, "Number Type" ) PORT_DIPLOCATION("SW2:7") // 数字型态 (affects credit and bet display)
+ PORT_DIPSETTING( 0x40, "Numbers" ) // 数字 (text and digits)
+ PORT_DIPSETTING( 0x00, "Blocks" ) // 方块 (pigs for credit, apples for bet, mahjong tong tiles for numbers)
+ PORT_DIPNAME( 0x80, 0x80, "Hidden Function" ) PORT_DIPLOCATION("SW2:8") // 隐分功能 (hides credits and bets, game plays normally)
+ PORT_DIPSETTING( 0x80, DEF_STR(Off) ) // 无
+ PORT_DIPSETTING( 0x00, DEF_STR(On) ) // 有
+INPUT_PORTS_END
+
INPUT_PORTS_START( jking02 )
PORT_START("DSW1")
PORT_DIPNAME( 0x1f, 0x1f, "ID Number") PORT_DIPLOCATION("SW1:1,2,3,4,5")
@@ -517,6 +571,26 @@ INPUT_PORTS_START( jking02 )
PORT_BIT( 0xfff00000, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
+INPUT_PORTS_START( slqz3 )
+ PORT_INCLUDE(mahjong_test)
+ PORT_INCLUDE(slqz3_dip_switches)
+
+ PORT_MODIFY("TEST")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // 哈巴
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 ) // 功能
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) // 押注
+
+ PORT_START("JOY")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START1 ) // 开始
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // 上
+ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // 下
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // 左
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // 右
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) // 摸/舍
+INPUT_PORTS_END
+
INPUT_PORTS_START( qlgs )
PORT_INCLUDE(base)
@@ -527,58 +601,11 @@ INPUT_PORTS_START( qlgs )
INPUT_PORTS_END
INPUT_PORTS_START( lhdmg )
- PORT_INCLUDE(mahjong)
+ PORT_INCLUDE(mahjong_kbd)
+ PORT_INCLUDE(slqz3_dip_switches)
PORT_MODIFY("TEST")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // 哈巴
-
- PORT_START("DSW1")
- PORT_DIPNAME( 0x03, 0x03, DEF_STR(Coin_A) ) PORT_DIPLOCATION("SW1:1,2") // 投币比率
- PORT_DIPSETTING( 0x03, DEF_STR(1C_1C) )
- PORT_DIPSETTING( 0x02, DEF_STR(1C_2C) )
- PORT_DIPSETTING( 0x01, DEF_STR(1C_3C) )
- PORT_DIPSETTING( 0x00, DEF_STR(1C_5C) )
- PORT_DIPNAME( 0x0c, 0x0c, "Key-In Rate" ) PORT_DIPLOCATION("SW1:3,4") // 开分比率
- PORT_DIPSETTING( 0x0c, "10" )
- PORT_DIPSETTING( 0x08, "20" )
- PORT_DIPSETTING( 0x04, "50" )
- PORT_DIPSETTING( 0x00, "100" )
- PORT_DIPNAME( 0x10, 0x10, "Credit Limit" ) PORT_DIPLOCATION("SW1:5") // 进分上限
- PORT_DIPSETTING( 0x10, "1000" )
- PORT_DIPSETTING( 0x00, "2000" )
- PORT_DIPNAME( 0x20, 0x20, "Credit Mode" ) PORT_DIPLOCATION("SW1:6") // 进分上方式 (sets coin input function)
- PORT_DIPSETTING( 0x20, "Coin Acceptor" ) // 投币 (uses coin A rate)
- PORT_DIPSETTING( 0x00, "Key-In" ) // 开分 (uses key-in rate)
- PORT_DIPNAME( 0x40, 0x40, "Payout Mode" ) PORT_DIPLOCATION("SW1:7") // 退分上方式
- PORT_DIPSETTING( 0x40, "Return Coins" ) // 退币 (uses hopper to pay out credits)
- PORT_DIPSETTING( 0x00, "Key-Out" ) // 洗分 (just clears credits)
- PORT_DIPNAME( 0x80, 0x80, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW1:8") // 示范音乐
- PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 无
- PORT_DIPSETTING( 0x80, DEF_STR(On) ) // 有
-
- PORT_START("DSW2")
- PORT_DIPNAME( 0x03, 0x03, "Double Up Jackpot" ) PORT_DIPLOCATION("SW2:1,2") // 比倍爆机
- PORT_DIPSETTING( 0x03, "500" )
- PORT_DIPSETTING( 0x02, "1000" )
- PORT_DIPSETTING( 0x01, "1500" )
- PORT_DIPSETTING( 0x00, "2000" )
- PORT_DIPNAME( 0x0c, 0x0c, "Minimum Bet" ) PORT_DIPLOCATION("SW2:3,4") // 最小押注 (all settings show 1 in service mode and function identically)
- PORT_DIPSETTING( 0x0c, "1" )
- PORT_DIPSETTING( 0x08, "1" )
- PORT_DIPSETTING( 0x04, "1" )
- PORT_DIPSETTING( 0x00, "1" )
- PORT_DIPNAME( 0x10, 0x10, "Double Up Game" ) PORT_DIPLOCATION("SW2:5") // 比倍游戏
- PORT_DIPSETTING( 0x00, DEF_STR(Off) ) // 无
- PORT_DIPSETTING( 0x10, DEF_STR(On) ) // 有
- PORT_DIPNAME( 0x20, 0x20, "Double Up/Continue Play" ) PORT_DIPLOCATION("SW2:6") // 比倍续玩
- PORT_DIPSETTING( 0x20, "Double Up" ) // 比倍
- PORT_DIPSETTING( 0x00, "Continue Play" ) // 续玩
- PORT_DIPNAME( 0x40, 0x40, "Number Type" ) PORT_DIPLOCATION("SW2:7") // 数字型态 (affects credit and bet display)
- PORT_DIPSETTING( 0x40, "Numbers" ) // 数字 (text and digits)
- PORT_DIPSETTING( 0x00, "Blocks" ) // 方块 (pigs for credit, apples for bet, mahjong tong tiles for numbers)
- PORT_DIPNAME( 0x80, 0x80, "Hidden Function" ) PORT_DIPLOCATION("SW2:8") // 隐分功能 (hides credits and bets, game plays normally)
- PORT_DIPSETTING( 0x80, DEF_STR(Off) ) // 无
- PORT_DIPSETTING( 0x00, DEF_STR(On) ) // 有
INPUT_PORTS_END
INPUT_PORTS_START( lhzb3 )
@@ -592,29 +619,46 @@ INPUT_PORTS_START( lhzb3 )
INPUT_PORTS_END
INPUT_PORTS_START( lhzb4 )
- // TODO: this is very preliminary, mahjong inputs aren't hooked up
+ // TODO: this is very preliminary, mahjong keyboard inputs aren't hooked up
- PORT_INCLUDE(mahjong)
-
- PORT_MODIFY("TEST")
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN )
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT )
+ 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_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_START("JOY")
- PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON3 )
- PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 )
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 )
- PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("HP") // TODO: what is this?
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT )
+ 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( 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_START("PLAYER")
+ PORT_BIT( 0x000001ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
+ 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 )
+ 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, 0x01, "Control Panel" ) PORT_DIPLOCATION("SW1:1")
PORT_DIPSETTING( 0x01, "JAMMA" )
- PORT_DIPSETTING( 0x01, "Keyboard" )
+ PORT_DIPSETTING( 0x00, "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" )
@@ -645,7 +689,7 @@ INPUT_PORTS_START( lhzb4 )
INPUT_PORTS_END
INPUT_PORTS_START( lthy )
- PORT_INCLUDE(mahjong_joy)
+ PORT_INCLUDE(mahjong_kbd_joy)
PORT_MODIFY("TEST")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_GAMBLE_KEYOUT )
@@ -708,7 +752,7 @@ INPUT_PORTS_START( lthy )
INPUT_PORTS_END
INPUT_PORTS_START( zhongguo )
- PORT_INCLUDE(mahjong_joy)
+ PORT_INCLUDE(mahjong_kbd_joy)
PORT_MODIFY("TEST")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_READ_LINE_DEVICE_MEMBER("hopper", hopper_device, line_r) // 哈巴
@@ -764,7 +808,7 @@ INPUT_PORTS_START( zhongguo )
INPUT_PORTS_END
INPUT_PORTS_START( mgzz )
- PORT_INCLUDE(mahjong_joy)
+ PORT_INCLUDE(mahjong_kbd_joy)
// TODO: missing HP input shown in test mode for joystick mode
@@ -817,14 +861,14 @@ INPUT_PORTS_START( mgzz )
INPUT_PORTS_END
INPUT_PORTS_START( mgzza )
- PORT_INCLUDE( mgzz )
+ PORT_INCLUDE(mgzz)
PORT_MODIFY("DSW2")
PORT_DIPUNKNOWN_DIPLOC( 0x04, 0x04, "SW2:3" ) // not shown in test mode
INPUT_PORTS_END
INPUT_PORTS_START( oceanpara )
- PORT_INCLUDE( three_reel )
+ PORT_INCLUDE(three_reel)
PORT_START("DSW1")
PORT_DIPNAME( 0x01, 0x01, DEF_STR(Demo_Sounds) ) PORT_DIPLOCATION("SW1:1")
@@ -875,7 +919,7 @@ INPUT_PORTS_START( oceanpara )
INPUT_PORTS_END
INPUT_PORTS_START( oceanpar )
- PORT_INCLUDE( oceanpara )
+ PORT_INCLUDE(oceanpara)
PORT_MODIFY("DSW2")
PORT_DIPNAME( 0x06, 0x06, "Score Box" ) PORT_DIPLOCATION("SW2:2,3")
@@ -889,7 +933,7 @@ INPUT_PORTS_START( oceanpar )
INPUT_PORTS_END
INPUT_PORTS_START( fruitpara )
- PORT_INCLUDE( oceanpara )
+ PORT_INCLUDE(oceanpara)
PORT_MODIFY("DSW2")
PORT_DIPNAME( 0x02, 0x02, "Score Box" ) PORT_DIPLOCATION("SW2:2")
@@ -1068,11 +1112,17 @@ void igs_m027_state::mahjong_output_w(u8 data)
m_hopper->motor_w(BIT(data, 2));
}
+void igs_m027_state::lhzb4_output_w(u8 data)
+{
+ machine().bookkeeping().coin_counter_w(1, BIT(data, 6)); // one pulse per key-out
+ machine().bookkeeping().coin_counter_w(0, BIT(data, 7)); // one pulse per key-in accepted
+}
+
void igs_m027_state::jking02_output_w(u8 data)
{
machine().bookkeeping().coin_counter_w(0, BIT(data, 0)); // one pulse per coin 1 accepted (36+10)
- machine().bookkeeping().coin_counter_w(2, BIT(data, 1)); // one pulse per key-in accepted (36+10
- machine().bookkeeping().coin_counter_w(1, BIT(data, 3)); // one pulse per key-in accepted (36+10)
+ machine().bookkeeping().coin_counter_w(2, BIT(data, 1)); // one pulse per key-in accepted (36+10)
+ machine().bookkeeping().coin_counter_w(1, BIT(data, 3)); // one pulse per coin 2 accepted (36+10)
machine().bookkeeping().coin_counter_w(3, BIT(data, 4)); // one pulse per key-out (36+10)
machine().bookkeeping().coin_counter_w(4, BIT(data, 5)); // one pulse per coin accepted (28-pin)
machine().bookkeeping().coin_counter_w(5, BIT(data, 6)); // one pulse per key-out (28-pin)
@@ -1160,18 +1210,15 @@ void igs_m027_state::slqz3_xor(machine_config &config)
{
m027_xor(config);
- // TODO: PPI port A = input, port B = input, port C = output
-}
-
-void igs_m027_state::jking02_xor(machine_config &config)
-{
- m027_xor(config);
+ m_ppi->in_pa_callback().set_ioport("TEST");
+ m_ppi->in_pb_callback().set_ioport("JOY");
+ m_ppi->out_pc_callback().set(FUNC(igs_m027_state::mahjong_output_w));
- m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_state::jking02_xor_map);
+ m_igs017_igs031->in_pa_callback().set_ioport("DSW1");
+ m_igs017_igs031->in_pb_callback().set_ioport("DSW2");
+ m_igs017_igs031->in_pc_callback().set_constant(0xff);
- m_ppi->out_pa_callback().set(FUNC(igs_m027_state::lamps_w<8>));
- m_ppi->out_pb_callback().set(FUNC(igs_m027_state::jking02_output_w));
- m_ppi->out_pc_callback().set(FUNC(igs_m027_state::lamps_w<0>));
+ HOPPER(config, m_hopper, attotime::from_msec(50));
}
void igs_m027_state::lhdmg_xor(machine_config &config)
@@ -1195,13 +1242,18 @@ void igs_m027_state::lhzb4_xor(machine_config &config)
{
m027_xor(config);
+ m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_state::jking02_xor_map);
+
//m_ppi->out_pa_callback().set(...);
- //m_ppi->out_pb_callback().set(...);
+ m_ppi->out_pb_callback().set(FUNC(igs_m027_state::lhzb4_output_w));
m_ppi->out_pc_callback().set(FUNC(igs_m027_state::io_select_w<0>));
+ m_ppi->out_pc_callback().append(m_hopper, FUNC(hopper_device::motor_w)).bit(7);
m_igs017_igs031->in_pa_callback().set(NAME((&igs_m027_state::dsw_r<1, 0>)));
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::lthy_xor(machine_config &config)
@@ -1224,6 +1276,17 @@ void igs_m027_state::zhongguo_xor(machine_config &config)
HOPPER(config, m_hopper, attotime::from_msec(50));
}
+void igs_m027_state::jking02_xor(machine_config &config)
+{
+ m027_xor(config);
+
+ m_maincpu->set_addrmap(AS_PROGRAM, &igs_m027_state::jking02_xor_map);
+
+ m_ppi->out_pa_callback().set(FUNC(igs_m027_state::lamps_w<8>));
+ m_ppi->out_pb_callback().set(FUNC(igs_m027_state::jking02_output_w));
+ m_ppi->out_pc_callback().set(FUNC(igs_m027_state::lamps_w<0>));
+}
+
void igs_m027_state::mgzz_xor(machine_config &config)
{
m027_xor(config);
@@ -2343,7 +2406,7 @@ void igs_m027_state::init_lhdmg()
***************************************************************************/
// Complete dumps
-GAME( 1999, slqz3, 0, slqz3_xor, base, igs_m027_state, init_slqz3, ROT0, "IGS", "Mahjong Shuang Long Qiang Zhu 3 (China, VS107C)", MACHINE_NOT_WORKING )
+GAME( 1999, slqz3, 0, slqz3_xor, slqz3, igs_m027_state, init_slqz3, ROT0, "IGS", "Mahjong Shuang Long Qiang Zhu 3 (China, VS107C)", MACHINE_NOT_WORKING ) // 双龙抢珠Ⅲ
GAME( 1999, qlgs, 0, m027_xor, qlgs, igs_m027_state, init_qlgs, ROT0, "IGS", "Que Long Gao Shou", MACHINE_NOT_WORKING )
GAME( 1999, lhdmg, 0, lhdmg_xor, lhdmg, igs_m027_state, init_lhdmg, ROT0, "IGS", "Long Hu Da Manguan", MACHINE_NOT_WORKING ) // 龙虎大满贯
GAME( 1999, lhdmgp, lhdmg, lhdmg_xor, lhdmg, igs_m027_state, init_lhdmg, ROT0, "IGS", "Long Hu Da Manguan Plus", MACHINE_NOT_WORKING ) // 龙虎大满贯
diff --git a/src/mame/sony/smc777.cpp b/src/mame/sony/smc777.cpp
index dd06ae9f80b..8d338056b5f 100644
--- a/src/mame/sony/smc777.cpp
+++ b/src/mame/sony/smc777.cpp
@@ -21,20 +21,20 @@
#include "emu.h"
-#include "cpu/z80/z80.h"
#include "cpu/mcs48/mcs48.h"
+#include "cpu/z80/z80.h"
#include "imagedev/floppy.h"
#include "imagedev/snapquik.h"
#include "machine/74259.h"
#include "machine/timer.h"
#include "machine/wd_fdc.h"
-#include "softlist_dev.h"
#include "sound/beep.h"
#include "sound/sn76496.h"
#include "video/mc6845.h"
#include "emupal.h"
#include "screen.h"
+#include "softlist_dev.h"
#include "speaker.h"
diff --git a/src/mame/taito/taito_f2.cpp b/src/mame/taito/taito_f2.cpp
index a71ee071162..69416419c91 100644
--- a/src/mame/taito/taito_f2.cpp
+++ b/src/mame/taito/taito_f2.cpp
@@ -5021,6 +5021,7 @@ ROM_START( qzquest ) /* Quiz Quest */
/* no Delta-T samples */
ROM_END
+// Dual PCB version (main and sound program ROMs cannot be used on the single PCB version)
ROM_START( pulirula )
ROM_REGION( 0xc0000, "maincpu", 0 ) /* 768k for 68000 code */
ROM_LOAD16_BYTE( "c98-12.rom", 0x00000, 0x40000, CRC(816d6cde) SHA1(cac583440cca9aa57373f4a6c9a68c5442a5258b) )
@@ -5073,6 +5074,7 @@ ROM_START( pulirulaj )
/* no Delta-T samples */
ROM_END
+// Single PCB version (main and sound program ROMs cannot be used on the dual PCB version)
ROM_START( pulirulaa ) // dumped from an original PCB without original ROM labels. The maincpu and audiocpu ROMs differ from the parent.
ROM_REGION( 0xc0000, "maincpu", 0 ) /* 768k for 68000 code */
ROM_LOAD16_BYTE( "ic46.bin", 0x00000, 0x40000, CRC(584ae599) SHA1(c114442d93080aaf0641c1a9204569f0017af000) )
@@ -5618,7 +5620,7 @@ GAME( 1990, mjnquestb, mjnquest, mjnquest, mjnquest, taitof2_state, init_mjn
GAME( 1990, footchmp, 0, footchmp, footchmp, taitof2_state, empty_init, ROT0, "Taito Corporation Japan", "Football Champ / Euro Football Champ (World)", MACHINE_SUPPORTS_SAVE ) // title depends on dipswitch
GAME( 1990, htherou, footchmp, footchmp, htherou, taitof2_state, empty_init, ROT0, "Taito Corporation", "Hat Trick Hero (US)", MACHINE_SUPPORTS_SAVE ) // Single PCB
-GAME( 1990, htheroj, footchmp, hthero, htheroj, taitof2_state, empty_init, ROT0, "Taito Corporation", "Hat Trick Hero (Japan)", MACHINE_SUPPORTS_SAVE ) // Double PCB
+GAME( 1990, htheroj, footchmp, hthero, htheroj, taitof2_state, empty_init, ROT0, "Taito Corporation", "Hat Trick Hero (Japan)", MACHINE_SUPPORTS_SAVE ) // Dual PCB
GAME( 1992, footchmpbl, footchmp, footchmpbl,footchmpbl, taitof2_state, empty_init, ROT0, "bootleg", "Football Champ / Euro Football Champ (World) (bootleg)", MACHINE_SUPPORTS_SAVE | MACHINE_NOT_WORKING ) // very different hw register etc.
GAME( 1992, euroch92, 0, footchmp, footchmp, taitof2_state, empty_init, ROT0, "Taito Corporation Japan", "Euro Champ '92 (World)", MACHINE_SUPPORTS_SAVE )
@@ -5636,8 +5638,8 @@ GAME( 1991, solfigtr, 0, solfigtr, solfigtr, taitof2_state, empty_in
GAME( 1991, qzquest, 0, qzquest , qzquest, taitof2_state, empty_init, ROT0, "Taito Corporation", "Quiz Quest - Hime to Yuusha no Monogatari (Japan)", MACHINE_SUPPORTS_SAVE )
-GAME( 1991, pulirula, 0, pulirula, pulirula, taitof2_state, empty_init, ROT0, "Taito Corporation Japan", "PuLiRuLa (World)", MACHINE_SUPPORTS_SAVE )
-GAME( 1991, pulirulaa, pulirula, pulirula, pulirulaj, taitof2_state, empty_init, ROT0, "Taito Corporation", "PuLiRuLa (World, earlier?)", MACHINE_SUPPORTS_SAVE )
+GAME( 1991, pulirula, 0, pulirula, pulirula, taitof2_state, empty_init, ROT0, "Taito Corporation Japan", "PuLiRuLa (World, dual PCB)", MACHINE_SUPPORTS_SAVE )
+GAME( 1991, pulirulaa, pulirula, pulirula, pulirulaj, taitof2_state, empty_init, ROT0, "Taito Corporation", "PuLiRuLa (World, single PCB)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, pulirulaj, pulirula, pulirula, pulirulaj, taitof2_state, empty_init, ROT0, "Taito Corporation", "PuLiRuLa (Japan)", MACHINE_SUPPORTS_SAVE )
GAME( 1991, metalb, 0, metalb, metalb, taitof2_state, empty_init, ROT0, "Taito Corporation Japan", "Metal Black (World)", MACHINE_SUPPORTS_SAVE )