diff --git a/hash/msx1_cart.xml b/hash/msx1_cart.xml
index f4f70eb80b0..b2ccf98104d 100644
--- a/hash/msx1_cart.xml
+++ b/hash/msx1_cart.xml
@@ -7147,6 +7147,22 @@ kept for now until finding out what those bytes affect...
+
+ Keyboard Master (Prototype)
+ 1984
+ Konami
+
+
+
+
+
+
+
+
+
+
+
+
Kage no Densetsu - The Legend of Kage (Jpn)
1986
diff --git a/src/emu/bus/msx_cart/cartridge.c b/src/emu/bus/msx_cart/cartridge.c
index 20dc60f739e..4ef5d178c7c 100644
--- a/src/emu/bus/msx_cart/cartridge.c
+++ b/src/emu/bus/msx_cart/cartridge.c
@@ -44,6 +44,7 @@ SLOT_INTERFACE_START(msx_cart)
SLOT_INTERFACE_INTERNAL("msxaud_nms1205", MSX_CART_MSX_AUDIO_NMS1205)
SLOT_INTERFACE_INTERNAL("super_swangi", MSX_CART_SUPER_SWANGI)
SLOT_INTERFACE_INTERNAL("hfox", MSX_CART_HFOX)
+ SLOT_INTERFACE_INTERNAL("keyboard_master", MSX_CART_KEYBOARD_MASTER)
SLOT_INTERFACE_END
@@ -58,6 +59,11 @@ void msx_cart_interface::rom_alloc(UINT32 size)
m_rom.resize(size);
}
+void msx_cart_interface::rom_vlm5030_alloc(UINT32 size)
+{
+ m_rom_vlm5030.resize(size);
+}
+
void msx_cart_interface::ram_alloc(UINT32 size)
{
m_ram.resize(size);
diff --git a/src/emu/bus/msx_cart/cartridge.h b/src/emu/bus/msx_cart/cartridge.h
index 7df0dc662a4..ebaee3f6e56 100644
--- a/src/emu/bus/msx_cart/cartridge.h
+++ b/src/emu/bus/msx_cart/cartridge.h
@@ -26,18 +26,22 @@ public:
// Mainly used by the cartridge slot when loading images
void rom_alloc(UINT32 size);
void ram_alloc(UINT32 size);
+ void rom_vlm5030_alloc(UINT32 size);
void sram_alloc(UINT32 size);
UINT8* get_rom_base() { return m_rom; }
+ UINT8* get_rom_vlm5030_base() { return m_rom_vlm5030; }
UINT8* get_ram_base() { return m_ram; }
UINT8* get_sram_base() { return m_sram; }
UINT32 get_rom_size() { return m_rom.count(); }
+ UINT32 get_rom_vlm5030_size() { return m_rom_vlm5030.count(); }
UINT32 get_ram_size() { return m_ram.count(); }
UINT32 get_sram_size() { return m_sram.count(); }
protected:
dynamic_buffer m_rom;
dynamic_buffer m_ram;
+ dynamic_buffer m_rom_vlm5030;
dynamic_buffer m_sram;
devcb_write_line m_out_irq_cb;
};
diff --git a/src/emu/bus/msx_cart/konami.c b/src/emu/bus/msx_cart/konami.c
index d6ff7f8866b..55c217574f0 100644
--- a/src/emu/bus/msx_cart/konami.c
+++ b/src/emu/bus/msx_cart/konami.c
@@ -7,6 +7,7 @@ const device_type MSX_CART_GAMEMASTER2 = &device_creator;
const device_type MSX_CART_SYNTHESIZER = &device_creator;
const device_type MSX_CART_SOUND_SNATCHER = &device_creator;
const device_type MSX_CART_SOUND_SDSNATCHER = &device_creator;
+const device_type MSX_CART_KEYBOARD_MASTER = &device_creator;
msx_cart_konami::msx_cart_konami(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
@@ -866,3 +867,70 @@ void msx_cart_konami_sound_sdsnatcher::initialize_cartridge()
}
+
+
+msx_cart_keyboard_master::msx_cart_keyboard_master(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, MSX_CART_KEYBOARD_MASTER, "MSX Cartridge - Keyboard Master", tag, owner, clock, "msx_cart_keyboard_master", __FILE__)
+ , msx_cart_interface(mconfig, *this)
+ , m_vlm5030(*this, "vlm5030")
+{
+}
+
+
+static MACHINE_CONFIG_FRAGMENT( msx_cart_keyboard_master )
+ // This is actually incorrect. The sound output is passed back into the MSX machine where it is mixed internally and output through the system 'speaker'.
+ MCFG_SPEAKER_STANDARD_MONO("mono")
+ MCFG_SOUND_ADD("vlm5030", VLM5030, XTAL_3_579545MHz)
+ MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.40)
+MACHINE_CONFIG_END
+
+
+machine_config_constructor msx_cart_keyboard_master::device_mconfig_additions() const
+{
+ return MACHINE_CONFIG_NAME( msx_cart_keyboard_master );
+}
+
+
+void msx_cart_keyboard_master::device_start()
+{
+ // Install IO read/write handlers
+ address_space &space = machine().device("maincpu")->space(AS_IO);
+ space.install_write_handler(0x00, 0x00, write8_delegate(FUNC(vlm5030_device::data_w), m_vlm5030.target()));
+ space.install_write_handler(0x20, 0x20, write8_delegate(FUNC(msx_cart_keyboard_master::io_20_w), this));
+ space.install_read_handler(0x00, 0x00, read8_delegate(FUNC(msx_cart_keyboard_master::io_00_r), this));
+}
+
+
+void msx_cart_keyboard_master::initialize_cartridge()
+{
+ if (get_rom_size() != 0x4000)
+ {
+ fatalerror("keyboard_master: Invalid ROM size\n");
+ }
+ m_vlm5030->set_rom(m_rom_vlm5030);
+}
+
+
+READ8_MEMBER(msx_cart_keyboard_master::read_cart)
+{
+ if (offset >= 0x4000 && offset < 0x8000)
+ {
+ return m_rom[offset & 0x3fff];
+ }
+ return 0xff;
+}
+
+
+WRITE8_MEMBER(msx_cart_keyboard_master::io_20_w)
+{
+ m_vlm5030->rst((data & 0x01) ? 1 : 0);
+ m_vlm5030->vcu((data & 0x04) ? 1 : 0);
+ m_vlm5030->st((data & 0x02) ? 1 : 0);
+}
+
+
+READ8_MEMBER(msx_cart_keyboard_master::io_00_r)
+{
+ return m_vlm5030->bsy() ? 0x10 : 0x00;
+}
+
diff --git a/src/emu/bus/msx_cart/konami.h b/src/emu/bus/msx_cart/konami.h
index 5d1501cdaef..6f9b10bdf94 100644
--- a/src/emu/bus/msx_cart/konami.h
+++ b/src/emu/bus/msx_cart/konami.h
@@ -3,6 +3,7 @@
#include "bus/msx_cart/cartridge.h"
#include "sound/k051649.h"
+#include "sound/vlm5030.h"
#include "sound/dac.h"
@@ -12,6 +13,7 @@ extern const device_type MSX_CART_GAMEMASTER2;
extern const device_type MSX_CART_SYNTHESIZER;
extern const device_type MSX_CART_SOUND_SNATCHER;
extern const device_type MSX_CART_SOUND_SDSNATCHER;
+extern const device_type MSX_CART_KEYBOARD_MASTER;
class msx_cart_konami : public device_t
@@ -166,4 +168,28 @@ public:
};
+
+class msx_cart_keyboard_master : public device_t
+ , public msx_cart_interface
+{
+public:
+ msx_cart_keyboard_master(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
+
+ // device-level overrides
+ virtual machine_config_constructor device_mconfig_additions() const;
+ virtual void device_start();
+
+ virtual void initialize_cartridge();
+
+ virtual DECLARE_READ8_MEMBER(read_cart);
+
+ DECLARE_WRITE8_MEMBER(io_20_w);
+ DECLARE_READ8_MEMBER(io_00_r);
+
+private:
+ required_device m_vlm5030;
+};
+
+
+
#endif
diff --git a/src/emu/bus/msx_slot/cartridge.c b/src/emu/bus/msx_slot/cartridge.c
index c3eabedcb9d..b2d2f95a01e 100644
--- a/src/emu/bus/msx_slot/cartridge.c
+++ b/src/emu/bus/msx_slot/cartridge.c
@@ -106,12 +106,25 @@ bool msx_slot_cartridge_device::call_load()
{
if ( software_entry() )
{
- // Allocate and copy rom contents
- UINT32 length = get_software_region_length("rom");
+ UINT32 length;
+ // Allocate and copy rom contents
+ length = get_software_region_length("rom");
m_cartridge->rom_alloc( length );
- UINT8 *rom_base = m_cartridge->get_rom_base();
- memcpy(rom_base, get_software_region("rom"), length);
+ if (length > 0)
+ {
+ UINT8 *rom_base = m_cartridge->get_rom_base();
+ memcpy(rom_base, get_software_region("rom"), length);
+ }
+
+ // Allocate and copy vlm5030 rom contents
+ length = get_software_region_length("vlm5030");
+ m_cartridge->rom_vlm5030_alloc(length);
+ if (length > 0)
+ {
+ UINT8 *rom_base = m_cartridge->get_rom_vlm5030_base();
+ memcpy(rom_base, get_software_region("vlm5030"), length);
+ }
// Allocate ram
length = get_software_region_length("ram");