summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author ajrhacker <ajrhacker@users.noreply.github.com>2021-04-18 18:36:10 -0400
committer GitHub <noreply@github.com>2021-04-18 18:36:10 -0400
commit9814692d0686e8c1481ac7561d42a2f52eaad46d (patch)
treeed5fbd0b71a30f52458bb80935c2986711fa1014
parent5d05eb44277e395b18229c880458ede43c1968ba (diff)
parent6f576131989b64ceb09c6ccee5f4122f29d5c84c (diff)
Merge pull request #7968 from ValleyBell/cm32p-pcm-cards
CM-32P: support PCM cards, add U-110 card softlist
-rw-r--r--hash/u110_card.xml199
-rw-r--r--src/mame/drivers/roland_cm32p.cpp104
2 files changed, 288 insertions, 15 deletions
diff --git a/hash/u110_card.xml b/hash/u110_card.xml
new file mode 100644
index 00000000000..ac8651dd5a1
--- /dev/null
+++ b/hash/u110_card.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0"?>
+<!DOCTYPE softwarelist SYSTEM "softwarelist.dtd">
+<!--
+license:CC0
+
+Undumped cards:
+- all Rhodes SN-U01-xxR cards
+- Roland SN-SPLA-01/03
+- Musitronics 2 Voices (U-22)
+- Musitronics 5 Eldek (U-21)
+- Musitronics 6 Analog Synthesizer (U-20)
+ -> see https://www.playkeyboardnow.com/Roland_D70_Soundbanks/page63/index.html
+
+Release dates were taken from http://www.rolandmuseum.de/z_syn_wc.php
+-->
+
+<softwarelist name="u110_card" description="Roland U-110 PCM memory cards">
+ <software name="mus1-akk">
+ <description>Musitronics 1 Akkordeon (U-25)</description>
+ <year>199x</year>
+ <publisher>musitronics GmbH</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <!-- Note: The current dump is an overdump due to how address scrambling works. The internal ROM appears to be only 64K. -->
+ <rom name="musitronics_akkordeon.bin" size="0x20000" crc="69e41a1b" sha1="2931181ad60372461e82491a014cb118c68605d8"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-mv30-01">
+ <description>SN-MV30-01 Rhythm Section (U-31)</description>
+ <year>1991</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-mv30-01.bin" size="0x80000" crc="9b571919" sha1="873afbac7b1fcd45128952152dc090de48b765c6"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-mv30-02">
+ <description>SN-MV30-02 Orchestral (U-30)</description>
+ <year>1991</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-mv30-02.bin" size="0x80000" crc="596254dc" sha1="1081973aad7ad5941329d3ab8a20db654c063a2e"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-01">
+ <description>SN-U110-01 Pipe Organ &amp; Harpsichord</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-01.bin" size="0x80000" crc="71fec2e0" sha1="42440bcf0e025dad9182de0a3231f0e00c3a149d"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-02">
+ <description>SN-U110-02 Latin &amp; F.X. Percussions</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-02.bin" size="0x80000" crc="335a67cb" sha1="3e1c2fd64c59474426aa8717eb03240bb8b69730"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-03">
+ <description>SN-U110-03 Ethnic</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-03.bin" size="0x80000" crc="20a010db" sha1="2d33603fe3217d44d28aec284216581e581a9981"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-04">
+ <description>SN-U110-04 Electric Grand &amp; Clavi</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-04.bin" size="0x80000" crc="2653ac2b" sha1="e856625e9efac8ee4026696f46aad4015fb3c097"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-05">
+ <description>SN-U110-05 Orchestral Strings</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-05.bin" size="0x80000" crc="712aa669" sha1="9d67bd73848c1b6c4a9543b8f4abb5794ac2f951"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-06">
+ <description>SN-U110-06 Orchestral Winds</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-06.bin" size="0x80000" crc="5725360d" sha1="d5a8beece04b6da27c6a6b3bddc808c757168a28"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-07">
+ <description>SN-U110-07 Electric Guitar</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-07.bin" size="0x80000" crc="7a6319c2" sha1="fdcb923b986805e3671fb0962804315d8287cba5"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-08">
+ <description>SN-U110-08 Synthesizer</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-08.bin" size="0x80000" crc="fef365d2" sha1="ad3ea185cac7d938a9f7fe17d80cab32881e05d7"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-09">
+ <description>SN-U110-09 Guitar &amp; Keyboards</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-09.bin" size="0x80000" crc="28b03851" sha1="54d07e1b49eedd0f5339999dc0f4690134849f31"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-10">
+ <description>SN-U110-10 Rock Drums</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-10.bin" size="0x80000" crc="7611196a" sha1="056344e4908c2fbde98f77b4d1f5c198c62333e7"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-11">
+ <description>SN-U110-11 Sound Effects</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-11.bin" size="0x80000" crc="57e50aa1" sha1="c15071da567204c84d1a0ae35961caa84ebfa2fc"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-12">
+ <description>SN-U110-12 Sax &amp; Trombone</description>
+ <year>1989</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-12.bin" size="0x80000" crc="4f925426" sha1="c36fb83e720c3bd55d21959927fa616c92105bbc"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-13">
+ <description>SN-U110-13 Super Strings</description>
+ <year>1992</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-13.bin" size="0x80000" crc="b26fd0b4" sha1="e332d1dd5f0ebf5284501540fdbcc1488e8ef828"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-14">
+ <description>SN-U110-14 Super Ac Guitar</description>
+ <year>1992</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-14.bin" size="0x80000" crc="7143045d" sha1="b540bd0db7eb2c0914c7cfb5e98ac8c85bd868aa"/>
+ </dataarea>
+ </part>
+ </software>
+ <software name="sn-u110-15">
+ <description>SN-U110-15 Super Brass</description>
+ <year>1992</year>
+ <publisher>Roland</publisher>
+ <part name="card" interface="u110_card">
+ <dataarea name="rom" size="0x80000">
+ <rom name="sn-u110-15.bin" size="0x80000" crc="4e215a4d" sha1="10ad202551632118c5e3bdfb06e6613079217ce9"/>
+ </dataarea>
+ </part>
+ </software>
+</softwarelist>
diff --git a/src/mame/drivers/roland_cm32p.cpp b/src/mame/drivers/roland_cm32p.cpp
index 2c3da094385..295c44b54f2 100644
--- a/src/mame/drivers/roland_cm32p.cpp
+++ b/src/mame/drivers/roland_cm32p.cpp
@@ -39,7 +39,6 @@ Notes:
TODO:
- figure out how "freeing a voice" works - right now the firmware gets stuck when playing the 32th note.
-- add PCM card support
PCB Layout
@@ -231,18 +230,24 @@ Some routine locations
#include "machine/timer.h"
#include "sound/rolandpcm.h"
#include "video/msm6222b.h"
+#include "bus/generic/slot.h"
+#include "bus/generic/carts.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
// unscramble address: ROM dump offset -> proper (descrambled) offset
-#define UNSCRAMBLE_ADDRESS(_offset) \
+#define UNSCRAMBLE_ADDR_INT(_offset) \
bitswap<19>(_offset,18,17,15,14,16,12,11, 7, 9,13,10, 8, 3, 2, 1, 6, 4, 5, 0)
// scramble address: proper offset -> ROM dump offset
-#define SCRAMBLE_ADDRESS(_offset) \
+#define SCRAMBLE_ADDR_INT(_offset) \
bitswap<19>(_offset,18,17,14,16,15, 9,13,12, 8,10, 7,11, 3, 1, 2, 6, 5, 4, 0)
+// PCM cards use a different address line scrambling
+#define UNSCRAMBLE_ADDR_EXT(_offset) \
+ bitswap<19>(_offset,18,17, 8, 9,16,11,12, 7,14,10,13,15, 3, 2, 1, 6, 4, 5, 0)
+
#define UNSCRAMBLE_DATA(_data) \
bitswap<8>(_data,1,2,7,3,5,0,4,6)
@@ -254,7 +259,7 @@ static INPUT_PORTS_START( cm32p )
PORT_START("SERVICE") // connected to Port 0 of the P8098 CPU.
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test Switch") PORT_TOGGLE PORT_CODE(KEYCODE_F2) // SW A (checked during boot)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: Check/Tune") PORT_CODE(KEYCODE_B) // SW B
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("PCM card inserted") PORT_TOGGLE PORT_CODE(KEYCODE_C)
+ //PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("PCM card inserted") PORT_TOGGLE PORT_CODE(KEYCODE_C)
PORT_START("SW") // test switches, accessed by reading from address 0x1300
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: MSB Adj.") PORT_CODE(KEYCODE_1) // SW 1
@@ -283,6 +288,7 @@ protected:
private:
required_device<i8x9x_device> cpu;
required_device<mb87419_mb87420_device> pcm;
+ required_device<generic_slot_device> pcmcard;
required_device<msm6222b_device> lcd;
required_device<timer_device> midi_timer;
required_device<ram_device> some_ram;
@@ -309,8 +315,15 @@ private:
TIMER_DEVICE_CALLBACK_MEMBER(midi_timer_cb);
TIMER_DEVICE_CALLBACK_MEMBER(samples_timer_cb);
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(card_load);
+ DECLARE_DEVICE_IMAGE_UNLOAD_MEMBER(card_unload);
+
void cm32p_map(address_map &map);
+ void descramble_rom_internal(u8* dst, const u8* src);
+ void descramble_rom_external(u8* dst, const u8* src);
+
+ bool pcmard_loaded;
u8 midi;
int midi_pos;
u8 sound_io_buffer[0x100];
@@ -321,6 +334,7 @@ cm32p_state::cm32p_state(const machine_config &mconfig, device_type type, const
: driver_device(mconfig, type, tag)
, cpu(*this, "maincpu")
, pcm(*this, "pcm")
+ , pcmcard(*this, "cardslot")
, lcd(*this, "lcd")
, midi_timer(*this, "midi_timer")
, some_ram(*this, "some_ram")
@@ -379,6 +393,46 @@ void cm32p_state::machine_reset()
midi_pos = 0;
}
+DEVICE_IMAGE_LOAD_MEMBER(cm32p_state::card_load)
+{
+ uint32_t size = pcmcard->common_get_size("rom");
+ if (size > 0x080000)
+ {
+ image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only up to 512K is supported");
+ return image_init_result::FAIL;
+ }
+
+ pcmcard->rom_alloc(0x080000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); // cards are up to 512K
+ pcmcard->common_load_rom(pcmcard->get_rom_base(), size, "rom");
+ u8* base = pcmcard->get_rom_base();
+ if (size < 0x080000)
+ {
+ uint32_t mirror = (1 << (31 - count_leading_zeros(size)));
+ if (mirror < 0x020000) // due to how address descrambling works, we can currently only do mirroring for 128K pages
+ mirror = 0x020000;
+ for (uint32_t ofs = mirror; ofs < 0x080000; ofs += mirror)
+ memcpy(base + ofs, base, mirror);
+ }
+
+ u8* src = static_cast<u8*>(memregion("pcmorg")->base());
+ u8* dst = static_cast<u8*>(memregion("pcm")->base());
+ memcpy(&src[0x080000], base, 0x080000);
+ // descramble PCM card ROM
+ descramble_rom_external(&dst[0x080000], &src[0x080000]);
+ pcmard_loaded = true;
+
+ return image_init_result::PASS;
+}
+
+DEVICE_IMAGE_UNLOAD_MEMBER(cm32p_state::card_unload)
+{
+ u8* src = static_cast<u8*>(memregion("pcmorg")->base());
+ u8* dst = static_cast<u8*>(memregion("pcm")->base());
+ memset(&src[0x080000], 0xFF, 0x080000);
+ memset(&dst[0x080000], 0xFF, 0x080000);
+ pcmard_loaded = false;
+}
+
void cm32p_state::lcd_ctrl_w(u8 data)
{
lcd->control_w(data);
@@ -414,7 +468,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(cm32p_state::midi_timer_cb)
u16 cm32p_state::port0_r()
{
- return service_port->read();
+ return service_port->read() | (pcmard_loaded ? 0x10 : 0x00);
}
u8 cm32p_state::pcmrom_r(offs_t offset)
@@ -565,11 +619,14 @@ void cm32p_state::cm32p(machine_config &config)
screen.set_size(16*6-1, (16*6-1)*3/4);
screen.set_visarea(0, 16*6-2, 0, (16*6-1)*3/4-1);
screen.set_palette("palette");
-
PALETTE(config, "palette", FUNC(cm32p_state::mt32_palette), 2);
-
MSM6222B_01(config, lcd, 0);
+ generic_cartslot_device &cardslot(GENERIC_CARTSLOT(config, "cardslot", generic_romram_plain_slot, "u110_card", "bin"));
+ cardslot.set_device_load(FUNC(cm32p_state::card_load));
+ cardslot.set_device_unload(FUNC(cm32p_state::card_unload));
+ SOFTWARE_LIST(config, "card_list").set_original("u110_card");
+
TIMER(config, midi_timer).configure_generic(FUNC(cm32p_state::midi_timer_cb));
TIMER(config, "samples_timer").configure_periodic(FUNC(cm32p_state::samples_timer_cb), attotime::from_hz(32000*2));
@@ -578,20 +635,37 @@ void cm32p_state::cm32p(machine_config &config)
void cm32p_state::init_cm32p()
{
// Roland did a fair amount of scrambling on the address and data lines.
- // Only the first 0x20 bytes of the ROMs are readable text in a raw dump.
+ // Only the first 0x80 bytes of the ROMs are readable text in a raw dump.
+ // The CM-32P actually checks some of these header bytes, but it uses post-scrambling variants of offsets/values.
u8* src = static_cast<u8*>(memregion("pcmorg")->base());
u8* dst = static_cast<u8*>(memregion("pcm")->base());
- for (offs_t bank_ofs = 0x00; bank_ofs < 0x400000; bank_ofs += 0x080000)
+ // descramble internal ROMs
+ descramble_rom_internal(&dst[0x000000], &src[0x000000]);
+ descramble_rom_internal(&dst[0x100000], &src[0x100000]);
+ descramble_rom_internal(&dst[0x200000], &src[0x200000]);
+ // descramble PCM card ROM
+ descramble_rom_external(&dst[0x080000], &src[0x080000]);
+}
+
+void cm32p_state::descramble_rom_internal(u8* dst, const u8* src)
+{
+ for (offs_t srcpos = 0x00; srcpos < 0x80000; srcpos ++)
{
- offs_t dstpos;
- for (offs_t srcpos = 0x00; srcpos < 0x80000; srcpos ++)
- {
- dstpos = UNSCRAMBLE_ADDRESS(srcpos);
- dst[bank_ofs + dstpos] = UNSCRAMBLE_DATA(src[bank_ofs + srcpos]);
- }
+ offs_t dstpos = UNSCRAMBLE_ADDR_INT(srcpos);
+ dst[dstpos] = UNSCRAMBLE_DATA(src[srcpos]);
+ }
+}
+
+void cm32p_state::descramble_rom_external(u8* dst, const u8* src)
+{
+ for (offs_t srcpos = 0x00; srcpos < 0x80000; srcpos ++)
+ {
+ offs_t dstpos = UNSCRAMBLE_ADDR_EXT(srcpos);
+ dst[dstpos] = UNSCRAMBLE_DATA(src[srcpos]);
}
}
+
ROM_START( cm32p )
ROM_REGION( 0x10000, "maincpu", 0 )
ROM_LOAD( "cm-32_p__1.0.0.am27c512.7d.ic9", 0x000000, 0x10000, CRC(6f2f6dfd) SHA1(689f77c1d56f923ef1dab7d993a124c47736bc56) ) // "CM-32 P // 1 0 0 <filled bubbles in red marker>" sticker on an AM27C512-150DC eprom @ IC9