diff --git a/hash/supracan.xml b/hash/supracan.xml
index e8b8f71f579..fdcd19cbee1 100644
--- a/hash/supracan.xml
+++ b/hash/supracan.xml
@@ -134,7 +134,7 @@ Black screen at security BIOS time, cfr. PC=f8061a
1996
Funtech
diff --git a/src/mame/funtech/acan.cpp b/src/mame/funtech/acan.cpp
index 589f93972d5..e92928695bc 100644
--- a/src/mame/funtech/acan.cpp
+++ b/src/mame/funtech/acan.cpp
@@ -11,7 +11,7 @@
#include "emu.h"
#include "acan.h"
-#define VERBOSE (1)
+#define VERBOSE (0)
#include "logmacro.h"
// device type definition
diff --git a/src/mame/funtech/supracan.cpp b/src/mame/funtech/supracan.cpp
index ada6d66c12e..759411c87ec 100644
--- a/src/mame/funtech/supracan.cpp
+++ b/src/mame/funtech/supracan.cpp
@@ -2,12 +2,7 @@
// copyright-holders:Angelo Salese,Ryan Holtz
/***************************************************************************
-
- Funtech Super A'Can
- -------------------
-
- Preliminary driver by Angelo Salese
- Improvements by Ryan Holtz
+Super A'Can (c) 1995 Funtech
References:
- https://gist.github.com/evadot/66cfdb8891544b41b4c9
@@ -89,6 +84,7 @@ DEBUG TRICKS:
#include "softlist_dev.h"
#include "speaker.h"
#include "tilemap.h"
+#include "umc6650.h"
#define LOG_UNKNOWNS (1U << 1)
#define LOG_DMA (1U << 2)
@@ -108,7 +104,7 @@ DEBUG TRICKS:
#define LOG_ALL (LOG_UNKNOWNS | LOG_HFUNKNOWNS | LOG_DMA | LOG_VIDEO | LOG_HFVIDEO | LOG_IRQS | LOG_SOUND | LOG_68K_SOUND | LOG_CONTROLS)
#define LOG_DEFAULT (LOG_ALL & ~(LOG_HFVIDEO | LOG_HFUNKNOWNS))
-#define VERBOSE (LOG_UNKNOWNS | LOG_SOUND | LOG_DMA)
+#define VERBOSE (LOG_UNKNOWNS | LOG_DMA)
#include "logmacro.h"
@@ -129,10 +125,10 @@ public:
, m_maincpu(*this, "maincpu")
, m_soundcpu(*this, "soundcpu")
, m_cart(*this, "cartslot")
+ , m_lockout(*this, "lockout")
, m_internal68(*this, "internal68")
, m_internal68_view(*this, "internal68")
, m_internal68_view_hi(*this, "internal68_hi")
- , m_umc6650key(*this, "umc6650key")
, m_vram(*this, "vram")
, m_soundram(*this, "soundram")
, m_sound(*this, "acansnd")
@@ -168,10 +164,6 @@ private:
void video_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
- void umc6650_addr_w(uint8_t data);
- uint8_t umc6650_data_r();
- void umc6650_data_w(uint8_t data);
-
uint8_t sound_ram_read(offs_t offset);
struct dma_regs_t
@@ -195,10 +187,10 @@ private:
required_device m_maincpu;
required_device m_soundcpu;
required_device m_cart;
+ required_device m_lockout;
required_region_ptr m_internal68;
memory_view m_internal68_view;
memory_view m_internal68_view_hi;
- required_region_ptr m_umc6650key;
required_shared_ptr m_vram;
required_shared_ptr m_soundram;
@@ -1335,23 +1327,6 @@ void supracan_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
m_gfxdecode->gfx(4)->mark_dirty((offset * 2) / 8);
}
-void supracan_state::umc6650_addr_w(uint8_t data)
-{
- m_umc6650_addr = data & 0x7f;
-}
-
-uint8_t supracan_state::umc6650_data_r()
-{
- if (m_umc6650_addr >= 0x20 && m_umc6650_addr < 0x2f)
- return m_umc6650key[m_umc6650_addr & 0xf];
- return m_umc6650_data[m_umc6650_addr];
-}
-
-void supracan_state::umc6650_data_w(uint8_t data)
-{
- m_umc6650_data[m_umc6650_addr] = data;
-}
-
void supracan_state::supracan_mem(address_map &map)
{
// 0x000000..0x3fffff is mapped by the cartslot
@@ -1360,8 +1335,9 @@ void supracan_state::supracan_mem(address_map &map)
map(0xe90020, 0xe9002f).w(FUNC(supracan_state::dma_channel0_w));
map(0xe90030, 0xe9003f).w(FUNC(supracan_state::dma_channel1_w));
- map(0xeb0d00, 0xeb0d01).rw(FUNC(supracan_state::umc6650_data_r), FUNC(supracan_state::umc6650_data_w)).umask16(0x00ff);
- map(0xeb0d02, 0xeb0d03).w(FUNC(supracan_state::umc6650_addr_w)).umask16(0x00ff);
+ map(0xe90b3c, 0xe90b3d).noprw(); // noisy during lockout checks
+
+ map(0xeb0d00, 0xeb0d03).rw(m_lockout, FUNC(umc6650_device::read), FUNC(umc6650_device::write)).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");
@@ -2177,11 +2153,14 @@ void supracan_state::supracan(machine_config &config)
M68000(config, m_maincpu, XTAL(10'738'635)); /* Correct frequency unknown */
m_maincpu->set_addrmap(AS_PROGRAM, &supracan_state::supracan_mem);
- M6502(config, m_soundcpu, XTAL(3'579'545)); /* TODO: Verify actual clock */
+ // TODO: Verify actual clock
+ M6502(config, m_soundcpu, XTAL(3'579'545));
m_soundcpu->set_addrmap(AS_PROGRAM, &supracan_state::supracan_sound_mem);
config.set_perfect_quantum(m_soundcpu);
+ UMC6650(config, m_lockout, 0);
+
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(XTAL(10'738'635)/2, 348, 0, 256, 256, 0, 240); /* No idea if this is correct */
m_screen->set_screen_update(FUNC(supracan_state::screen_update));
@@ -2215,10 +2194,6 @@ ROM_START( supracan )
// 68k internal ROM (security related)
ROM_LOAD16_WORD_SWAP( "internal_68k.bin", 0x0000, 0x1000, CRC(8d575662) SHA1(a8e75633662978d0a885f16a4ed0f898f278a10a) )
- ROM_REGION(0x10, "umc6650key", ROMREGION_ERASEFF)
- // 68k internal ROM (security related)
- ROM_LOAD( "umc6650.bin", 0x00, 0x10, CRC(0ba78597) SHA1(f94805457976d60b91e8df18f9f49cccec77be78) )
-
ROM_REGION(0x2000, "internal6502", ROMREGION_ERASEFF)
// 2 additional blocks of ROM(?) can be seen next to the 68k ROM on a die shot from Furrtek
ROM_LOAD( "internal_6502_1.bin", 0x0000, 0x1000, NO_DUMP )
diff --git a/src/mame/funtech/umc6650.cpp b/src/mame/funtech/umc6650.cpp
new file mode 100644
index 00000000000..a3b0a3baa3f
--- /dev/null
+++ b/src/mame/funtech/umc6650.cpp
@@ -0,0 +1,78 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+/*************************************************************************************************
+
+[Super A'Can] UMC 6650 lockout chip
+
+TODO:
+- signal to cart B26 & B27 (from register $09?).
+- Does the effective lockout resolution input merges with $1c signal from UMC6619 host space?
+- /WR for optional cart save RAM
+
+**************************************************************************************************/
+
+#include "emu.h"
+#include "umc6650.h"
+
+#define VERBOSE (1)
+#include "logmacro.h"
+
+DEFINE_DEVICE_TYPE(UMC6650, umc6650_device, "umc6650", "UMC 6650 lockout chip")
+
+umc6650_device::umc6650_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, UMC6650, tag, owner, clock)
+ , device_memory_interface(mconfig, *this)
+ , m_romkey(*this, "romkey")
+ , m_space_io_config("io", ENDIANNESS_LITTLE, 8, 7, 0, address_map_constructor(FUNC(umc6650_device::internal_map), this))
+{
+}
+
+ROM_START( umc6650 )
+ ROM_REGION(0x10, "romkey", ROMREGION_ERASEFF)
+ // 68k internal ROM (security related)
+ ROM_LOAD( "umc6650.bin", 0x00, 0x10, CRC(0ba78597) SHA1(f94805457976d60b91e8df18f9f49cccec77be78) )
+ROM_END
+
+const tiny_rom_entry *umc6650_device::device_rom_region() const
+{
+ return ROM_NAME( umc6650 );
+}
+
+device_memory_interface::space_config_vector umc6650_device::memory_space_config() const
+{
+ return space_config_vector{
+ std::make_pair(AS_IO, &m_space_io_config)
+ };
+}
+
+void umc6650_device::device_start()
+{
+ m_space_io = &space(AS_IO);
+ save_item(NAME(m_address));
+}
+
+void umc6650_device::device_reset()
+{
+ m_address = 0x7f;
+}
+
+u8 umc6650_device::read(offs_t offset)
+{
+ return offset == 1 ? m_address : m_space_io->read_byte(m_address);
+}
+
+void umc6650_device::write(offs_t offset, u8 data)
+{
+ if (offset == 1)
+ m_address = data & 0x7f;
+ else
+ m_space_io->write_byte(m_address, data);
+}
+
+void umc6650_device::internal_map(address_map &map)
+{
+// map(0x09, 0x09)
+// map(0x0c, 0x0c)
+ map(0x20, 0x2f).rom().region(m_romkey, 0);
+ map(0x40, 0x5f).ram();
+}
diff --git a/src/mame/funtech/umc6650.h b/src/mame/funtech/umc6650.h
new file mode 100644
index 00000000000..e3ae9557e50
--- /dev/null
+++ b/src/mame/funtech/umc6650.h
@@ -0,0 +1,33 @@
+// license:BSD-3-Clause
+// copyright-holders:Angelo Salese
+
+#ifndef MAME_FUNTECH_UMC6650_H
+#define MAME_FUNTECH_UMC6650_H
+
+#pragma once
+
+class umc6650_device : public device_t, public device_memory_interface
+{
+public:
+ umc6650_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ u8 read(offs_t offset);
+ void write(offs_t offset, u8 data);
+
+private:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual space_config_vector memory_space_config() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ required_memory_region m_romkey;
+ address_space_config m_space_io_config;
+
+ void internal_map(address_map &map);
+ address_space *m_space_io;
+ u8 m_address;
+};
+
+DECLARE_DEVICE_TYPE(UMC6650, umc6650_device)
+
+#endif // MAME_FUNTECH_UMC6650_H