From 5e14f8a76fabe83c4c9359afdd1158555d6ea6c4 Mon Sep 17 00:00:00 2001 From: ValleyBell Date: Fri, 8 Nov 2019 05:33:38 +0100 Subject: add Roland CM-32P driver (#5876) * add (non-working) CM-32P driver * CM-32P: make booting test mode sort of work (nw) * CM-32P: fix initialization, working test mode (nw) - test mode now boots properly and shows error report - test mode can be enabled/disabled - RCC-CPU check passes - PCM ROM check passes, PCM card check fails (requires SN-U110-04 card) * CM-32P: add research notes (nw) --- scripts/target/mame/mess.lua | 1 + src/mame/drivers/rcm32p.cpp | 562 +++++++++++++++++++++++++++++++++++++++++++ src/mame/drivers/rmt32.cpp | 4 +- src/mame/mame.lst | 3 + src/mame/mess.flt | 1 + 5 files changed, 569 insertions(+), 2 deletions(-) create mode 100644 src/mame/drivers/rcm32p.cpp diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 973999ad3d8..bbfef8126bd 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3122,6 +3122,7 @@ files { createMESSProjects(_target, _subtarget, "roland") files { MAME_DIR .. "src/mame/drivers/rmt32.cpp", + MAME_DIR .. "src/mame/drivers/rcm32p.cpp", MAME_DIR .. "src/mame/drivers/rd110.cpp", MAME_DIR .. "src/mame/drivers/rsc55.cpp", MAME_DIR .. "src/mame/drivers/tb303.cpp", diff --git a/src/mame/drivers/rcm32p.cpp b/src/mame/drivers/rcm32p.cpp new file mode 100644 index 00000000000..806f4df0b72 --- /dev/null +++ b/src/mame/drivers/rcm32p.cpp @@ -0,0 +1,562 @@ +// license:BSD-3-Clause +// copyright-holders:Valley Bell +/************************************************************************************************* + + Roland CM-32P driver + + Driver by Valley Bell + + Thanks to KitsuWhooa for the PCB layout diagram and part list. + + +Notes: +- When booting, it does a basic check by writing values 0..0xFF to 0x108A. + It then expects (value & 0x03) to be read back from 0x1080 and (value) to be read back from 0x1081/0x1082. + The routine for doing the check begins at 0x4686. + Succeeding means it ends up at 0x4801. +- When in test mode, the firmware gets stuck in the loop at 0xBB06, waiting for Interrupt #5 (calls 0x4014) to fire. + It gets there by calling function 0xBBBB, which writes text (address w@0x40, num characters b@0x43) to the LCD screen. + This can be worked around by setting b@BB2D = 03. +- The firmware gets also stuck in the loop at 0x7D70, waiting for Interrupt #8 (calls 0x4020). + This might be related to finding the best free voice? + You can exit the loop by setting b@7D80 = 00. +- Test Mode shows the results of 4 checks: + 1. SRAM check + 2. MIDI IN/OUT check + 3. PCM ROM and card check + 4. RCC-CPU check + Errors in check 2 and 3 are "not abnormal". + In order to make check 2 pass successfully, you need to connect MIDI Out with MIDI In, creating a loopback. + Check 3 requires the SN-U110-04 PCM card ("Electric Grand & Clavi") to be inserted in order to succeed. +- In order to access the built-in PCM ROM (IC18), the CPU asks the sound chip to read offsets 0x000000 .. 0x07FFFF. + The PCM card is accessed via offsets 0x080000 .. 0x0FFFFF. + The additional PCM ROMs are mapped to 0x100000 .. 0x17FFFF (IC19) and 0x200000 .. 0x27FFFF according to the sample table in IC18. +- The sound chip has 32 voices. Voice 0 is reserved by the firmware for reading data from the PCM ROM. + The firmware allocates voices from back to front, i.e. voice 31 first. + + +TODO: +- actual sound emulation +- add PCM card support + + +PCB Layout +---------- + +PCM BOARD CM-32P ASSY 79554310 00 + +| OUTPUT | PHONES | INPUT (MT-32) | MIDI IN | MIDI THROUGH | DC 9V | +|----------------------------------------------------------------------| +| JK2 JK4 JK3 JKLI JKRI CN4 JK1I JK1T JK5 | +| | +| SW1 | +| || IC2 IC1 | +| IC35 IC33 IC34 || IC31 IC30 CN0 | +| CN3 ||<--IC32 | +| |----| |----| |----| | +| | | | | | | | +| IC22 || IC24 |IC10| |IC9 | | | | +| || IC25 IC4 | | | | | | | +| ||<--IC23 |SRAM| |ROM | | | | +| |----| |----| |IC3 | X1 | +| |----| | | | +| | IC | |------| | | | +| | 17 | | IC16 | IC12 | | | +| |----| |------| X2 |----| | +| |------| IC13 | +| IC6 |----||----||----| | IC15 | | +| |-||-| | || || | |------| IC14 |------| | +| | || | |IC20||IC19||IC18| | IC8 | | +| |-||-| | || || | |------| | +| IC7 |SMPL||SMPL||SMPL| |------------------| | +| |ROM ||ROM ||ROM | | CN5 | | +| |----||----||----| | | CN1 | +|------------------------------|------------------|--------------------| + | | + +Parts: + +(All parts THT unless otherwise noted.) +|-----------------------------------------------------------------------| +| JK1I, JK1T | DIN 5 | +| JK2, JK4, JKRI, JKLI | 1/4 Mono Jack | +| JK3 | 1/4 Stereo Jack | +| JK5 | DC Barrel Jack (Centre Negative) | +| SW1 | SW PCB DPDT | +| IC1 | 74HC04AP | +| IC2 | TLP552 | +| IC3 | P8098 (CPU) | +| IC4 | M51953AL | +| IC6, IC7 | M5M4464AP-12 | +| IC8 | Roland R15239111 / M60012-0141FP (QFP) | +| IC9 | AM27C512-150DC | +| IC10 | TC5564APL-15 | +| IC12 | 74HC00AP | +| IC13 | 74HC02AP | +| IC14 | 74HC32AP | +| IC15 | Roland R15229894 / MB87419 (QFP) | +| IC16 | Roland R15229895 / MB87420 (QFP) | +| IC17 | Roland P15239126 / 23140-007 (QFP) | +| IC18 | Roland R15179970 / MB834000A-20 3B1 | +| IC19 | Roland R15179971 / MB834000A-20 3B2 | +| IC20 | Roland R15179972 / HN62304BPE98 | +| IC22 | PCM56P | +| IC23 | M5238L | +| IC24 | HD14052BP | +| IC25 | NJM2082D | +| IC30, IC31, IC33, IC34, IC35 | NJM4565DD | +| IC32 | M5207L01 | +| CN0 | 7805A | +| CN1 | LED PCB | +| CN3 | Volume Control PCB | +| CN4 | unpopulated | +| CN5 | PCM Card Slot | +| X1 | Crystal 12MHz | +| X2 | Crystal 32.768KHz | +|-----------------------------------------------------------------------| + + +PCM ROM Tables +-------------- +Sample Table (address: 0x00100) +------------ +Pos Len Description +00 02 start offset, bits 0-15 (Little Endian) +02 01 start offset, bits 16-18 (bits 0-2) + PCM card select (bit 3): set for sounds on PCM cards + ROM bank (bits 4-5): + 0 = IC18 + 1 = IC19 + 2 = IC20 + loop mode (bits 6-7): + 0 = normal loop + 1 = no loop + 2 = ping-pong (forwards, backwards, forwards, backwards, ...) +03 02 last sample (sample length = last sample + 1) +05 02 loop length (loop start = sample length - loop length) +07 01 ?? +08 01 reference note (when played back at 32000 Hz) +09 01 ?? +-> 0Ah bytes per entry + +Tone List (address: 0x01000) +--------- +Pos Len Description +00 0A sample name +0A 01 tone type + 00 - single + 01 - dual + 02 - detune + 03 - velocity mix + 04 - velocity switch + 05..07 - invalid + 08..0F/10..17/.../78..7F - same as 00..07 + 80..FF - rhythm? +0B 01 ?? +0C 02 ?? +0E 01 ?? +0F 01 ?? +10 0B some note IDs (padded with FF) +1B 0C sample IDs (always one more than number of note IDs, padded with FF) +27 09 ?? +30 0B some note IDs (padded with FF) +3B 0C sample IDs (always one more than number of note IDs, padded with FF) +47 09 ?? +-> 50h bytes per entry + +Note: Section 30..4F is only used with tone types 01, 03, 04 + + +CM-32P Firmware Work RAM Layout +------------------------------- +2100..22FF - MIDI data receive buffer + +2344..23C1 - Part 1..6 "Patch temporary area" (see manual page 21, 0x15 bytes per partial) +23C4..23D4 - "System area" settings (see manual page 22, master volume, reverb setting, channel assignments) + 23CE-23D3 - Part 1..6 MIDI channel +23D6..25B5 - Part 1..6 instrument data (0x50 bytes per partial, from PCM ROM at 0x1000/0x1050/0x10A0/...) +25B8..2B57 - Part 1..6 sample table data (0xF0 bytes per partial, from PCM ROM at 0x0100/0x010A/0x0114/...) + +34DC..34E1 - Part 1..6 Modulation (CC #1, initialized with 0) +34E2..34E7 - Part 1..6 Pitch Bend LSB (initialized with 0) +34E8..34ED - Part 1..6 Pitch Bend MSB (initialized with 64) +34EE..34F3 - Part 1..6 Expression setting (CC #11, initialized with 100) +34F4..34F9 - Part 1..6 Sustain setting (CC #64, initialized with 0) +34FA..34FF - Part 1..6 unused (initialized with 0) +3500..3505 - Part 1..6 RPN LSB (CC #98, initialized with 0xFF) +3506..350B - Part 1..6 RPN MSB (CC #99, initialized with 0xFF) +350C..3511 - Part 1..6 NRPN received (initialized with 0xFF, set to 0 when RPN LSB/MSB is received, set to 0xFF when NRPN is received) +3512..3517 - Part 1..6 ?? (initialized with 0) +3518..351D - Part 1..6 Instrument setting +351E - Reverb Mode +351F - Reverb Time +3521 - ?? (initialized with 1) +352A..3889 - voice memory (32 bytes per block) + 35AA..35C9 - some jump table index for interrupt #8 +38DE..394D - more voice memory (32 bytes per block) + +397E..3??? - state of playing notes + 3986 - current panning volume, left speaker (00..1F) + 39A6 - current panning volume, right speaker (00..1F) + 39C6 - target panning volume, left speaker (00..1F) + 39E6 - target panning volume, right speaker (00..1F) + +3D7C..3E84 - SysEx receive data buffer + +Some routine locations +---------------------- +0x4014 LCD related interrupt handler +0x401C serial input (MIDI data) interrupt handler +0x4020 some interrupt handler required while playing notes +0x45CB Initialization (memory clear + checks), external memory is checked from 0x4679 on +0x5024 decide whether or not Test Mode is entered (normal boot == jump to 0x502A) +0x50F5 MIDI handling code +0x65E8 PCM ROM instrument check +0x6650 PCM card instrument check (Note: assumes that the SN-U110-04 PCM card is inserted) +0x6EA4 play a note (parameters: 0040 - part, 0041 = note pitch, 0042 - velocity) +0xB027 load instrument data from PCM ROM (writes to 23D6 + 50*i) +0xB12B load instrument sample data from PCM ROM (reads sample IDs from 23D6+1B + 50*i, writes to 25B8 + F0*i) +0xB1A0 load secondary instrument sample data from PCM ROM (reads sample IDs from 23D6+3B + 50h*i, writes to 25B8+50 + F0*i) +0xB1E8 load 1 sample table entry from PCM ROM +0xB316 PCM ROM signature check +0xBBBB write text to LCD + +*/ + +#include "emu.h" +#include "cpu/mcs96/i8x9x.h" +#include "machine/ram.h" +#include "machine/timer.h" +#include "video/msm6222b.h" +#include "emupal.h" +#include "screen.h" + + +// unscramble address: ROM dump offset -> proper (descrambled) offset +#define UNSCRAMBLE_ADDRESS(_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) \ + bitswap<19>(_offset,18,17,14,16,15, 9,13,12, 8,10, 7,11, 3, 1, 2, 6, 5, 4, 0) + +#define UNSCRAMBLE_DATA(_data) \ + bitswap<8>(_data,1,2,7,3,5,0,4,6) + + +static INPUT_PORTS_START( cm32p ) + PORT_START("A7") + PORT_BIT(0x03ff, 0x0000, IPT_DIAL) PORT_NAME("Knob") PORT_SENSITIVITY(50) PORT_KEYDELTA(8) PORT_CODE_DEC(KEYCODE_DOWN) PORT_CODE_INC(KEYCODE_UP) + + 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_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 + PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: THD Check") PORT_CODE(KEYCODE_2) // SW 2 + PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: PCM Out: String 1") PORT_CODE(KEYCODE_3) // SW 3 + PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: PCM Out: Sax 1") PORT_CODE(KEYCODE_4) // SW 4 + PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: PCM + Long Reverb") PORT_CODE(KEYCODE_5) // SW 5 + PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: PCM + Short Reverb") PORT_CODE(KEYCODE_6) // SW 6 + PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: VCA Down Check") PORT_CODE(KEYCODE_7) // SW 7 + PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Test: VCA Up Check") PORT_CODE(KEYCODE_8) // SW 8 +INPUT_PORTS_END + +class cm32p_state : public driver_device +{ +public: + cm32p_state(const machine_config &mconfig, device_type type, const char *tag); + + void cm32p(machine_config &config); + +protected: + virtual void machine_start() override; + virtual void machine_reset() override; + +private: + required_device cpu; + required_device lcd; + required_device midi_timer; + required_device some_ram; + required_ioport test_sw; + required_ioport service_port; + + void mt32_palette(palette_device &palette) const; + + uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + DECLARE_WRITE16_MEMBER(midi_w); + + DECLARE_READ8_MEMBER(lcd_ctrl_r); + DECLARE_WRITE8_MEMBER(lcd_ctrl_w); + DECLARE_WRITE8_MEMBER(lcd_data_w); + DECLARE_READ16_MEMBER(port0_r); + DECLARE_READ8_MEMBER(pcmrom_r); + DECLARE_READ8_MEMBER(dsp_io_r); + DECLARE_WRITE8_MEMBER(dsp_io_w); + DECLARE_READ8_MEMBER(snd_io_r); + DECLARE_WRITE8_MEMBER(snd_io_w); + DECLARE_READ8_MEMBER(test_sw_r); + + TIMER_DEVICE_CALLBACK_MEMBER(midi_timer_cb); + TIMER_DEVICE_CALLBACK_MEMBER(samples_timer_cb); + + void cm32p_map(address_map &map); + + u8 midi; + int midi_pos; + u8 port0; + u8 sound_io_buffer[0x100]; + u8 dsp_io_buffer[0x80]; +}; + +cm32p_state::cm32p_state(const machine_config &mconfig, device_type type, const char *tag) + : driver_device(mconfig, type, tag) + , cpu(*this, "maincpu") + , lcd(*this, "lcd") + , midi_timer(*this, "midi_timer") + , some_ram(*this, "some_ram") + , test_sw(*this, "SW") + , service_port(*this, "SERVICE") +{ +} + + +// screen update function from Roland D-110 +uint32_t cm32p_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + uint8_t y,ra,gfx; + uint16_t sy=0,x; + const uint8_t *data = lcd->render(); + bitmap.fill(0); + + for (y = 0; y < 2; y++) + { + for (ra = 0; ra < 9; ra++) + { + uint16_t *p = &bitmap.pix16(sy++); + + for (x = 0; x < 16; x++) + { + gfx = 0; + if (ra < 8) + gfx = data[x*16 + y*640 + ra]; + + *p++ = BIT(gfx, 4); + *p++ = BIT(gfx, 3); + *p++ = BIT(gfx, 2); + *p++ = BIT(gfx, 1); + *p++ = BIT(gfx, 0); + *p++ = 0; + } + } + } + return 0; +} + +void cm32p_state::machine_start() +{ + u8 *rom = memregion("maincpu")->base(); + + // TODO: The IC8 gate array has an "LCD INT" line that needs to be emulated. Then, the hack can be removed. + // Note: The hack is not necessary when *not* using test mode. + rom[0xBB2D] = 0x03; // hack to make test mode not freeze when displaying the LCD text + + // TODO: remove this hack + rom[0x7D80] = 0x00; // hack to exit some loop waiting for interrupt #8 +} + +void cm32p_state::machine_reset() +{ + midi_timer->adjust(attotime::from_hz(1)); + midi_pos = 0; + port0 = 0; +} + +WRITE8_MEMBER(cm32p_state::lcd_ctrl_w) +{ + lcd->control_w(data); +} + +READ8_MEMBER(cm32p_state::lcd_ctrl_r) +{ + // The CM-64 service manual lists "D-110 LCD UNIT" for using PCM test mode, so I assume it works like that. + // However, the CM-32P firmware doesn't seem to ever read the status. + return lcd->control_r() >> 7; +} + +WRITE8_MEMBER(cm32p_state::lcd_data_w) +{ + lcd->data_w(data); +} + +WRITE16_MEMBER(cm32p_state::midi_w) +{ + logerror("midi_out %02x\n", data); + midi = data; +} + +TIMER_DEVICE_CALLBACK_MEMBER(cm32p_state::midi_timer_cb) +{ + const static uint8_t midi_data[3] = { 0x9a, 0x40, 0x7f }; + midi = midi_data[midi_pos++]; + logerror("midi_in %02x\n", midi); + cpu->serial_w(midi); + if(midi_pos < sizeof(midi_data)) + midi_timer->adjust(attotime::from_hz(1250)); +} + +READ16_MEMBER(cm32p_state::port0_r) +{ + return port0 | service_port->read(); +} + +READ8_MEMBER(cm32p_state::pcmrom_r) +{ + offs_t romOfs = SCRAMBLE_ADDRESS(offset); + const u8* pcm_rom = memregion("pcm32")->base(); + return UNSCRAMBLE_DATA(pcm_rom[romOfs]); +} + +READ8_MEMBER(cm32p_state::dsp_io_r) +{ + return dsp_io_buffer[offset]; +} + +WRITE8_MEMBER(cm32p_state::dsp_io_w) +{ + dsp_io_buffer[offset] = data; + // do read/write to some external memory, makes the RCC-CPU check pass. (routine at 0x4679) + switch(offset) + { + case 0x04: + // write to partials?? (written in loop at 0x4375) + break; + case 0x06: + { + u8* ram = some_ram->pointer(); + offs_t ofs = data; + ram[0x000 | ofs] = dsp_io_buffer[0x00] & 0x03; + ram[0x100 | ofs] = dsp_io_buffer[0x01]; + ram[0x200 | ofs] = dsp_io_buffer[0x02]; + } + break; + case 0x0A: + { + const u8* ram = some_ram->pointer(); + offs_t ofs = data; + dsp_io_buffer[0x00] = ram[0x000 | ofs]; + dsp_io_buffer[0x01] = ram[0x100 | ofs]; + dsp_io_buffer[0x02] = ram[0x200 | ofs]; + } + break; + } +} + +READ8_MEMBER(cm32p_state::snd_io_r) +{ + if (offset == 0x01) + { + // code for reading from the PCM sample table is at 0xB027 + // The code at 0xB0AC writes to 1411/1F (??), then 1403/02 (bank), then 1409/08/0B/0A (address). + // It waits a few cycles and at 0xB0F7 it reads the resulting data from 1401. + offs_t bank = sound_io_buffer[0x03]; + offs_t addr = (sound_io_buffer[0x09] << 0) | (sound_io_buffer[0x0A] << 8) | (sound_io_buffer[0x0B] << 16); + addr = ((addr >> 6) + 2) & 0x3FFFF; + addr |= (bank << 16); + // write actual ROM address to 1440..1443 for debugging + sound_io_buffer[0x43] = (addr >> 0) & 0xFF; + sound_io_buffer[0x42] = (addr >> 8) & 0xFF; + sound_io_buffer[0x41] = (addr >> 16) & 0xFF; + sound_io_buffer[0x40] = (addr >> 24) & 0xFF; + return pcmrom_r(space, addr, 0xFF); + } + return sound_io_buffer[offset]; +} + +WRITE8_MEMBER(cm32p_state::snd_io_w) +{ + // register map + // ------------ + // Note: 16-bit words are Little Endian, the firmware writes the odd byte is first + // 00/01 - ?? + // 02/03 - ROM bank (only bits 11-13 are used, bit 11 = PCM card, bits 12-13 select between IC18/19/20) + // 04/05 - frequency (2.14 fixed point, 0x4000 = 32000 Hz) + // 06/07 - volume + // 08/09 - sample start address, fraction (2.14 fixed point, i.e. 1 byte = 0x4000) + // 0A/0B - sample start address (high word, i.e. address bits 2..17) + // 0C/0D - sample end address (high word) + // 0E/0F - sample loop address (high word) + // 11/13/15/17 - voice enable mask (11 = least significant 8 bits, 17 = most significant 8 bits) + // 1A - ?? + // 1F - voice select + sound_io_buffer[offset] = data; +} + +READ8_MEMBER(cm32p_state::test_sw_r) +{ + return test_sw->read(); +} + +TIMER_DEVICE_CALLBACK_MEMBER(cm32p_state::samples_timer_cb) +{ + port0 ^= 0x10; +} + +void cm32p_state::mt32_palette(palette_device &palette) const +{ + palette.set_pen_color(0, rgb_t(0, 0, 0)); + palette.set_pen_color(1, rgb_t(0, 255, 0)); +} + +void cm32p_state::cm32p_map(address_map &map) +{ + map(0x1080, 0x10ff).rw(FUNC(cm32p_state::dsp_io_r), FUNC(cm32p_state::dsp_io_w)); // DSP area (writes to 1080..82/86/8C/8D) + map(0x1100, 0x1100).rw(FUNC(cm32p_state::lcd_ctrl_r), FUNC(cm32p_state::lcd_ctrl_w)); + map(0x1102, 0x1102).w(FUNC(cm32p_state::lcd_data_w)); + map(0x1300, 0x1300).r(FUNC(cm32p_state::test_sw_r)); // test switch state + map(0x1400, 0x14ff).rw(FUNC(cm32p_state::snd_io_r), FUNC(cm32p_state::snd_io_w)); // sound chip area + map(0x2000, 0x20ff).rom().region("maincpu", 0x2000); // init vector @ 2080 + map(0x2100, 0x3fff).ram(); // main RAM + map(0x4000, 0xbfff).rom().region("maincpu", 0x4000); + map(0xc000, 0xffff).r(FUNC(cm32p_state::pcmrom_r)); // show descrambled PCM ROM (for debugging) +} + +void cm32p_state::cm32p(machine_config &config) +{ + i8x9x_device &maincpu(P8098(config, cpu, 12_MHz_XTAL)); + maincpu.set_addrmap(AS_PROGRAM, &cm32p_state::cm32p_map); + maincpu.ach7_cb().set_ioport("A7"); + maincpu.serial_tx_cb().set(FUNC(cm32p_state::midi_w)); + maincpu.in_p0_cb().set(FUNC(cm32p_state::port0_r)); + + RAM(config, some_ram).set_default_size("8K"); + + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD)); + screen.set_refresh_hz(50); + screen.set_screen_update(FUNC(cm32p_state::screen_update)); + 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); + + 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)); +} + +ROM_START( cm32p ) + ROM_REGION( 0x10000, "maincpu", 0 ) + ROM_LOAD( "cm-32p-ic9.bin", 0x000000, 0x10000, CRC(6f2f6dfd) SHA1(689f77c1d56f923ef1dab7d993a124c47736bc56) ) + + ROM_REGION( 0x400000, "pcm32", 0 ) + ROM_LOAD( "cm-32p-ic18.bin", 0x000000, 0x80000, CRC(8e53b2a3) SHA1(4872530870d5079776e80e477febe425dc0ec1df) ) + // 0x080000 .. 0x0FFFFF is reserved for the PCM card + ROM_LOAD( "cm-32p-ic19.bin", 0x100000, 0x80000, CRC(c8220761) SHA1(49e55fa672020f95fd9c858ceaae94d6db93df7d) ) + ROM_LOAD( "cm-32p-ic20.bin", 0x200000, 0x80000, CRC(733c4054) SHA1(9b6b59ab74e5bf838702abb087c408aaa85b7b1f) ) +ROM_END + +CONS( 1989, cm32p, 0, 0, cm32p, cm32p, cm32p_state, empty_init, "Roland", "CM-32P", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/drivers/rmt32.cpp b/src/mame/drivers/rmt32.cpp index 3e93698e165..2f6c0be316f 100644 --- a/src/mame/drivers/rmt32.cpp +++ b/src/mame/drivers/rmt32.cpp @@ -437,5 +437,5 @@ ROM_START( cm32l ) ROM_LOAD( "r15179917.ic19.bin", 0, 0x8000, CRC(236c87a6) SHA1(e1c03905c46e962d1deb15eeed92eb61b42bba4a) ) ROM_END -CONS( 1987, mt32, 0, 0, mt32, mt32, mt32_state, empty_init, "Roland", "MT32", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) -CONS( 1989, cm32l, 0, 0, mt32, mt32, mt32_state, empty_init, "Roland", "CM32L", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +CONS( 1987, mt32, 0, 0, mt32, mt32, mt32_state, empty_init, "Roland", "MT-32", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) +CONS( 1989, cm32l, 0, 0, mt32, mt32, mt32_state, empty_init, "Roland", "CM-32L", MACHINE_NOT_WORKING | MACHINE_NO_SOUND ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 645c0ded537..a63306aefde 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -34045,6 +34045,9 @@ nimbus // RM Nimbus 186 cm32l // mt32 // +@source:rcm32p.cpp +cm32p // + @source:rockrage.cpp rockrage // GX620 (c) 1986 (World?) rockragea // GX620 (c) 1986 (Prototype?) diff --git a/src/mame/mess.flt b/src/mame/mess.flt index 17980311e2a..7987752ea3e 100644 --- a/src/mame/mess.flt +++ b/src/mame/mess.flt @@ -697,6 +697,7 @@ rambo.cpp ravens.cpp rc702.cpp rc759.cpp +rcm32p.cpp rd100.cpp rd110.cpp replicator.cpp -- cgit v1.2.3