diff options
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 |
commit | 9814692d0686e8c1481ac7561d42a2f52eaad46d (patch) | |
tree | ed5fbd0b71a30f52458bb80935c2986711fa1014 | |
parent | 5d05eb44277e395b18229c880458ede43c1968ba (diff) | |
parent | 6f576131989b64ceb09c6ccee5f4122f29d5c84c (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.xml | 199 | ||||
-rw-r--r-- | src/mame/drivers/roland_cm32p.cpp | 104 |
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 & 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 & 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 & 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 & 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 & 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 |