From cc537e30db7e3dc92c63e9eb74b43d0a9656d904 Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Wed, 31 Oct 2018 17:04:16 +0100 Subject: mu100: Make some noise [O. Galibert] Two sample roms are missing, sad. Volume is not taken into account yet (because the registers are not yet understood), pan is though. Don't even think about reverb or effects :-) Current code plays a scale in a loop. Comment the timer alloc in machine_reset to kill that. Demo song (missing lots of sounds, because roms): U then > until demo then ENTER ENTER. --- scripts/src/sound.lua | 12 + scripts/target/mame/mess.lua | 1 + src/devices/cpu/h8/h8_sci.cpp | 7 +- src/devices/cpu/h8/h8_sci.h | 2 + src/devices/sound/swp30.cpp | 463 ++++++++++++++++++++++++++++++++++++++ src/devices/sound/swp30.h | 61 +++++ src/devices/video/hd44780.cpp | 20 +- src/devices/video/hd44780.h | 14 +- src/mame/drivers/alesis.cpp | 2 +- src/mame/drivers/alphasma.cpp | 16 +- src/mame/drivers/cz101.cpp | 4 +- src/mame/drivers/novag6502.cpp | 2 +- src/mame/drivers/novag68k.cpp | 4 +- src/mame/drivers/pc2000.cpp | 8 +- src/mame/drivers/piggypas.cpp | 4 +- src/mame/drivers/psion.cpp | 4 +- src/mame/drivers/replicator.cpp | 4 +- src/mame/drivers/rz1.cpp | 4 +- src/mame/drivers/ymmu100.cpp | 477 +++++++++++++++++++++++++++++++--------- src/mame/machine/mmboard.cpp | 2 +- src/mame/machine/model1io2.cpp | 2 +- 21 files changed, 964 insertions(+), 149 deletions(-) create mode 100644 src/devices/sound/swp30.cpp create mode 100644 src/devices/sound/swp30.h diff --git a/scripts/src/sound.lua b/scripts/src/sound.lua index db5930d3801..f2d6c9b979d 100644 --- a/scripts/src/sound.lua +++ b/scripts/src/sound.lua @@ -1497,3 +1497,15 @@ if (SOUNDS["IOPSPU"]~=null) then MAME_DIR .. "src/devices/sound/iopspu.h", } end + +--------------------------------------------------- +-- +--@src/devices/sound/swp30.h,SOUNDS["SWP30"] = true +--------------------------------------------------- + +if (SOUNDS["SWP30"]~=null) then + files { + MAME_DIR .. "src/devices/sound/swp30.cpp", + MAME_DIR .. "src/devices/sound/swp30.h", + } +end diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 584f6ceae15..2685e740a94 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -278,6 +278,7 @@ SOUNDS["DAVE"] = true --SOUNDS["LC7535"] = true SOUNDS["UPD934G"] = true SOUNDS["IOPSPU"] = true +SOUNDS["SWP30"] = true -------------------------------------------------- -- specify available video cores diff --git a/src/devices/cpu/h8/h8_sci.cpp b/src/devices/cpu/h8/h8_sci.cpp index 6b708655256..c511ea664f9 100644 --- a/src/devices/cpu/h8/h8_sci.cpp +++ b/src/devices/cpu/h8/h8_sci.cpp @@ -141,17 +141,12 @@ READ8_MEMBER(h8_sci_device::tdr_r) WRITE8_MEMBER(h8_sci_device::ssr_w) { - cpu->synchronize(); - if(!(scr & SCR_TE)) { data |= SSR_TDRE; ssr |= SSR_TDRE; } if((ssr & SSR_TDRE) && !(data & SSR_TDRE)) - { ssr &= ~SSR_TEND; - scr &= ~SCR_TIE; - } ssr = ((ssr & ~SSR_MPBT) | (data & SSR_MPBT)) & (data | (SSR_TEND|SSR_MPB|SSR_MPBT)); if(V>=2) logerror("ssr_w %02x -> %02x (%06x)\n", data, ssr, cpu->pc()); @@ -611,7 +606,7 @@ void h8_sci_device::tx_dropped_edge() tx_bit = 0; clock_stop(CLK_TX); tx_cb(1); - ssr |= SSR_TEND|SSR_TDRE; + ssr |= SSR_TEND; if(scr & SCR_TEIE) intc->internal_interrupt(tei_int); break; diff --git a/src/devices/cpu/h8/h8_sci.h b/src/devices/cpu/h8/h8_sci.h index 065c5e4b305..9ce95a17f05 100644 --- a/src/devices/cpu/h8/h8_sci.h +++ b/src/devices/cpu/h8/h8_sci.h @@ -37,6 +37,8 @@ public: void set_info(const char *intc, int eri, int rxi, int txi, int tei); void set_external_clock_period(const attotime &_period); + void force(u8 data) { rdr = data; intc->internal_interrupt(rxi_int); } + DECLARE_WRITE8_MEMBER(smr_w); DECLARE_READ8_MEMBER(smr_r); DECLARE_WRITE8_MEMBER(brr_w); diff --git a/src/devices/sound/swp30.cpp b/src/devices/sound/swp30.cpp new file mode 100644 index 00000000000..e1107329d2e --- /dev/null +++ b/src/devices/sound/swp30.cpp @@ -0,0 +1,463 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Yamaha SWP30/30B, rompler/dsp combo + +#include "emu.h" +#include "swp30.h" + +/* + mode hall 1 reverb 0.3/2.0/2.1/30.0 + 5ab/b56: 1ff2 + 5e1/bc2: 1ff1 + 5e3/bc6, 521/a42, 527/a4e, 563/ac6, 56b/ad6, 5a7/b4e, 5e3/bc6: 1d + 529/a52: 1a21/13d2/134f/ 70c + 4e9/9d2, 4eb/9d6: 5/14d0/1585/1ec3 + 565/aca: 1a21/12cb/1247/ 684 + 523/a46, 525/a4a: 10/1631/16d4/1eef + 5a1/b42: 1a21/11c2/113d/ 606 + 561/ac2, 52b/ac2: a2/176f/1801/1f15 + 5a9/b5a: 1a20/10fb/1077/ 5ae + 567/ace, 569/ad2: 4d/1847/18cd/1f2e + 5e5/bca: 1a1f/ f74/ ef5/ 50b + 5a3/b46, 5a5/b46: d2/19c2/1a31/1f58 + 623/c46: 1a21/130d/1289/ 6a5 + 5ab/b56, 5e1/bc2: c/15dc/1683/1ee4 + + +72814: move e0 to reg r0 + +62fcc: compute stuff + +*/ +#if 0 +// 929a6: 00 2e 30 32 33 34 35 36 37 3a 3c + +void f_62fcc(e0, r0, e1, r1l, er5) // 8 (11/12) 1 6 84268 +{ + l8 = 929b1 + 6*e1; + r6 = r1l == 6 ? 0x15 : r1l == 4 ? 0xd : r1l == 3 ? 0x9 : e1; + f_64a34(0x01, 01, t929a6[e0].b << 8, 0x40, 0, er5 + 2*r6); // 0101 3700 40 0 84292 +} + +void write_regs(r0b, er1) // 728c0, r0=3, er1=84292 +{ + if(!g214c98) + return; + for(r5=0; r5update(); +} + +void swp30_device::map(address_map &map) +{ + map(0x0000, 0x1fff).rw(FUNC(swp30_device::snd_r), FUNC(swp30_device::snd_w)); + map(0x0012, 0x0013).select(0x1f80).rw(FUNC(swp30_device::volume_r), FUNC(swp30_device::volume_w)); + map(0x0022, 0x0023).select(0x1f80).rw(FUNC(swp30_device::freq_r), FUNC(swp30_device::freq_w)); + map(0x0024, 0x0027).select(0x1f80).rw(FUNC(swp30_device::pre_size_r), FUNC(swp30_device::pre_size_w)); + map(0x0028, 0x002b).select(0x1f80).rw(FUNC(swp30_device::post_size_r), FUNC(swp30_device::post_size_w)); + map(0x002c, 0x002f).select(0x1f80).rw(FUNC(swp30_device::address_r), FUNC(swp30_device::address_w)); + map(0x0064, 0x0065).select(0x1f80).rw(FUNC(swp30_device::pan_r), FUNC(swp30_device::pan_w)); + map(0x031c, 0x031d). rw(FUNC(swp30_device::keyon_mask_r<3>), FUNC(swp30_device::keyon_mask_w<3>)); + map(0x031e, 0x031f). rw(FUNC(swp30_device::keyon_mask_r<2>), FUNC(swp30_device::keyon_mask_w<2>)); + map(0x039c, 0x039d). rw(FUNC(swp30_device::keyon_mask_r<1>), FUNC(swp30_device::keyon_mask_w<1>)); + map(0x039e, 0x039f). rw(FUNC(swp30_device::keyon_mask_r<0>), FUNC(swp30_device::keyon_mask_w<0>)); + map(0x041c, 0x041d). rw(FUNC(swp30_device::keyon_r), FUNC(swp30_device::keyon_w)); +} + + +template u16 swp30_device::keyon_mask_r() +{ + return m_keyon_mask >> (16*sel); +} + +template void swp30_device::keyon_mask_w(u16 data) +{ + m_keyon_mask = (m_keyon_mask & ~(u64(0xffff) << (16*sel))) | (u64(data) << (16*sel)); +} + +u16 swp30_device::keyon_r() +{ + return 0; +} + +void swp30_device::keyon_w(u16) +{ + m_stream->update(); + static int count = 0; + for(int i=0; i<64; i++) { + u64 mask = u64(1) << i; + if((m_keyon_mask & mask) && !(m_active_mask & mask) && !(m_volume[i] & 0x8000)) { + m_sample_pos[i] = -s32(m_pre_size[i] << 8); + logerror("sample count %3d %02x %08x %08x %08x vol %04x pan %04x\n", count, i, m_pre_size[i], m_post_size[i], m_address[i], m_volume[i], m_pan[i]); + m_active_mask |= mask; + count++; + } + } + m_keyon_mask = 0; +} + +u16 swp30_device::volume_r(offs_t offset) +{ + int chan = offset >> 6; + return m_volume[chan]; +} + +void swp30_device::volume_w(offs_t offset, u16 data) +{ + m_stream->update(); + u8 chan = offset >> 6; + if(m_volume[chan] != data) + logerror("snd chan %02x volume %02x %02x\n", chan, data >> 8, data & 0xff); + m_volume[chan] = data; + if(data & 0x8000) + m_active_mask &= ~(u64(1) << chan); +} + + +u16 swp30_device::pan_r(offs_t offset) +{ + return m_pan[offset >> 6]; +} + +void swp30_device::pan_w(offs_t offset, u16 data) +{ + u8 chan = offset >> 6; + double p1 = pow(2, -(data >> 8)/16.0); + double p2 = pow(2, -(data & 0xff)/16.0); + if(m_pan[chan] != data) + logerror("snd chan %02x pan l %02x r %02x (%g %g %g)\n", chan, data >> 8, data & 0xff, p1, p2, sqrt(p1*p1+p2*p2)); + m_pan[chan] = data; +} + +u16 swp30_device::freq_r(offs_t offset) +{ + return m_freq[offset >> 6]; +} + +void swp30_device::freq_w(offs_t offset, u16 data) +{ + u8 chan = offset >> 6; + // delta is 4*256 per octave, positive means higher freq, e.g 4.10 format. + s16 v = data & 0x2000 ? data | 0xc000 : data; + if(m_freq[chan] != data) + logerror("snd chan %02x freq %c%c %d.%03x\n", chan, data & 0x8000 ? '#' : '.', data & 0x4000 ? '#' : '.', v / 1024, (v < 0 ? -v : v) & 0x3ff); + m_freq[chan] = data; +} + +u16 swp30_device::pre_size_r(offs_t offset) +{ + if(offset & 1) + return m_pre_size[offset >> 6]; + else + return m_pre_size[offset >> 6] >> 16; +} + +void swp30_device::pre_size_w(offs_t offset, u16 data) +{ + u8 chan = offset >> 6; + if(offset & 1) { + m_pre_size[chan] = (m_pre_size[chan] & 0xffff0000) | data; + logerror("snd chan %02x pre-size %02x %06x\n", chan, m_pre_size[chan] >> 24, m_pre_size[chan] & 0xffffff); + } else + m_pre_size[chan] = (m_pre_size[chan] & 0x0000ffff) | (data << 16); +} + +u16 swp30_device::post_size_r(offs_t offset) +{ + if(offset & 1) + return m_post_size[offset >> 6]; + else + return m_post_size[offset >> 6] >> 16; +} + +void swp30_device::post_size_w(offs_t offset, u16 data) +{ + u8 chan = offset >> 6; + if(offset & 1) { + m_post_size[chan] = (m_post_size[chan] & 0xffff0000) | data; + logerror("snd chan %02x post-size %02x %06x\n", chan, m_post_size[chan] >> 24, m_post_size[chan] & 0xffffff); + } else + m_post_size[chan] = (m_post_size[chan] & 0x0000ffff) | (data << 16); +} + +u16 swp30_device::address_r(offs_t offset) +{ + if(offset & 1) + return m_address[offset >> 6]; + else + return m_address[offset >> 6] >> 16; +} + +void swp30_device::address_w(offs_t offset, u16 data) +{ + u8 chan = offset >> 6; + if(offset & 1) { + // The address may be 25 bits + static const char *const formats[4] = { "l16", "l12", "l8", "x8" }; + m_address[chan] = (m_address[chan] & 0xffff0000) | data; + logerror("snd chan %02x format %s flags %02x address %06x\n", chan, formats[m_address[chan] >> 30], (m_address[chan] >> 24) & 0x3f, m_address[chan] & 0xffffff); + } else + m_address[chan] = (m_address[chan] & 0x0000ffff) | (data << 16); +} + +static u16 rr[0x40*0x40]; + +u16 swp30_device::snd_r(offs_t offset) +{ + if(0) { + int chan = (offset >> 6) & 0x3f; + int slot = offset & 0x3f; + std::string preg = "-"; + if(slot >= 0x21 && slot <= 0x2b && (slot & 1)) + preg = util::string_format("%03x", (slot-0x21)/2 + 6*chan); + logerror("snd_r [%04x %04x - %-4s] %02x.%02x %04x\n", offset, offset*2, preg, chan, slot, rr[offset]); + } + if(offset == 0x080f) + return rr[offset] & ~8; + // return chan == 0x20 && slot == 0xf ? 0 : 0xffff; + return rr[offset]; +} + +void swp30_device::snd_w(offs_t offset, u16 data) +{ + if(rr[offset] == data) + return; + if(offset == 0x4e && (data ^ rr[offset]) == 0x400) { + rr[offset] = data; + return; + } + rr[offset] = data; + int chan = (offset >> 6) & 0x3f; + int slot = offset & 0x3f; + std::string preg = "-"; + if(slot >= 0x21 && slot <= 0x2b && (slot & 1)) + preg = util::string_format("%03x", (slot-0x21)/2 + 6*chan); + logerror("snd_w [%04x %04x - %-4s] %02x.%02x, %04x\n", offset, offset*2, preg, chan, slot, data); +} + +/* +[:swp30] sample 00 46a86f [3] -5848 0180 00ff 3e06 +[:swp30] sample 01 4a2a69 [1] -5789 0400 001b 0122 +[:swp30] sample 02 42a89b [3] -4110 0100 00ff 0a3a +[:swp30] sample 03 46ce62 [3] -6727 0380 00ff 3e06 +[:swp30] sample 08 427193 [3] -4190 0540 00ff 0a3a +#[:swp30] sample 09 94ba25 [0] -11267 0000 0026 0830 +[:swp30] sample 0b 41b5c1 [3] +617 fe80 003c 0a3a +#[:swp30] sample 20 455235 [3] +19583 0580 002f 3e06 +#[:swp30] sample 24 4117b1 [3] +18465 fa80 0034 0a3a +#[:swp30] sample 2a 41f4bf [3] +19969 ff40 0039 0a3a +[:swp30] sample 2d 467938 [3] +7441 ff40 00ff 3e06 +[:swp30] sample 30 435fd3 [3] -5882 fdc0 0039 0a3a +[:swp30] sample 33 431a0a [3] +1960 0340 0043 0a3a +#[:swp30] sample 36 94ba25 [0] -2174 0000 0047 081c +[:swp30] sample 39 42e187 [3] +4221 ffc0 00ff 0a3a +[:swp30] sample 3a 46f798 [3] +2522 0000 00ff 3e06 + +[:swp30] sample id 1226729 085f 0402 + +[:swp30] sample 00 46a86f [3] -5847 00c0 00ff 3e06 +[:swp30] sample 01 4a2a69 [1] -5788 3010 001b 0122 +[:swp30] sample 02 42a89b [3] -4109 00c0 00ff 0a3a +[:swp30] sample 03 46ce62 [3] -6726 0000 00ff 3e06 +[:swp30] sample 08 427193 [3] -4189 03c0 00ff 0a3a +#[:swp30] sample 09 94ba25 [0] -11267 0000 0026 0830 +[:swp30] sample 0b 41b5c1 [3] +618 0180 003c 0a3a +#[:swp30] sample 20 455235 [3] +19583 0580 002f 3e06 +#[:swp30] sample 24 4117b1 [3] +18465 fa80 0034 0a3a +#[:swp30] sample 2a 41f4bf [3] +19970 fe40 0039 0a3a +[:swp30] sample 2d 467938 [3] +7442 ff00 00ff 3e06 +[:swp30] sample 30 435fd3 [3] -5882 fdc0 0039 0a3a +[:swp30] sample 33 431a0a [3] +1961 0040 0043 0a3a +#[:swp30] sample 36 94ba25 [0] -2173 0000 0047 081c +[:swp30] sample 39 42e187 [3] +4222 02c0 00ff 0a3a +[:swp30] sample 3a 46f798 [3] +2523 ff80 00ff 3e06 + +[:swp30] sample id 1226730 0ea3 2e06 +*/ + + //static int sid = 0; + +void swp30_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) +{ + // Loop first on the samples and not on the channels otherwise + // effects will be impossible to implement. + + for(int sample = 0; sample < samples; sample++) { + // Accumulate on 64 bits, shift/clamp at the end + s64 acc_left = 0, acc_right = 0; + + // Loop on channels + for(int channel = 0; channel < 64; channel++) + if(m_active_mask & (u64(1) << channel)) { + // First, read the sample + + // - Find the base sample index and base address + s32 spos = m_sample_pos[channel] >> 8; + offs_t base_address = (m_address[channel] & 0x1ffffff) << 2; + // - Read/decompress the sample + s16 samp = 0; + switch(m_address[channel] >> 30) { + case 0: { // 16-bits linear + offs_t adr = base_address + (spos << 1); + samp = read_word(adr); + break; + } + + case 1: { // 12-bits linear + offs_t adr = base_address + (spos >> 2)*6; + switch(spos & 3) { + case 0: { // .abc .... .... + u16 w0 = read_word(adr); + samp = (w0 & 0x0fff) << 4; + break; + } + case 1: { // C... ..AB .... + u16 w0 = read_word(adr); + u16 w1 = read_word(adr+2); + samp = ((w0 & 0xf000) >> 8) | ((w1 & 0x00ff) << 8); + break; + } + case 2: { // .... bc.. ...a + u16 w0 = read_word(adr+2); + u16 w1 = read_word(adr+4); + samp = ((w0 & 0xff00) >> 4) | ((w1 & 0x000f) << 12); + break; + } + case 3: { // .... .... ABC. + u16 w1 = read_word(adr+4); + samp = w1 & 0xfff0; + break; + } + } + break; + } + + case 2: // 8-bits linear + samp = read_byte(base_address + spos) << 8; + break; + + case 3: // 8-bits logarithmic + samp = m_sample_log8[read_byte(base_address + spos)]; + break; + } + + // logerror("sample %02x %06x [%d] %+5d %04x %04x %04x\n", channel, base_address >> 2, m_address[channel] >> 30, spos, samp & 0xffff, m_volume[channel], m_pan[channel]); + + // Second, step the sample pos, loop/deactivate as needed + m_sample_pos[channel] += m_sample_increment[m_freq[channel] & 0x3fff]; + s32 loop_size = m_post_size[channel] << 8; + if(m_sample_pos[channel] >= loop_size) { + // We reached the loop point, stop if loop size is zero, + // otherwise loop + if(!loop_size) + m_active_mask &= ~((u64(1) << channel)); + else + do + m_sample_pos[channel] -= loop_size; + while(m_sample_pos[channel] >= loop_size); + } + + // Third, filter the sample + + // - no idea what's needed there + + // Fourth, volume and pan, clamp the attenuation at -96dB + s32 sampl = samp * m_linear_attenuation[std::min(0xff, (m_volume[channel] & 0x00) + (m_pan[channel] >> 8))]; + s32 sampr = samp * m_linear_attenuation[std::min(0xff, (m_volume[channel] & 0x00) + (m_pan[channel] & 0xff))]; + + // Fifth, add to the accumulators + acc_left += sampl; + acc_right += sampr; + + // Missing: reverb, chorus, effects in general + } + + // Samples are 16 bits, there are up to 64 of them, and the accumulators are fixed-point signed 48.16 + acc_left >>= (16+6); + if(acc_left < -0x8000) + acc_left = -0x8000; + else if(acc_left > 0x7fff) + acc_left = 0x7fff; + outputs[0][sample] = acc_left; + + acc_right >>= (16+6); + if(acc_right < -0x8000) + acc_right = -0x8000; + else if(acc_right > 0x7fff) + acc_right = 0x7fff; + outputs[1][sample] = acc_right; + + // logerror("sample id %8d %04x %04x %016x [%08x]\n", sid, acc_right & 0xffff, acc_left & 0xffff, m_active_mask, m_address[4]); + // sid++; + } +} diff --git a/src/devices/sound/swp30.h b/src/devices/sound/swp30.h new file mode 100644 index 00000000000..ad6c39e1e5f --- /dev/null +++ b/src/devices/sound/swp30.h @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Yamaha SWP30/30B, rompler/dsp combo + +#ifndef DEVICES_SOUND_SWP30_H +#define DEVICES_SOUND_SWP30_H + +#pragma once + +class swp30_device : public device_t, public device_sound_interface, public device_rom_interface +{ +public: + swp30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); + + void map(address_map &map); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override; + virtual void rom_bank_updated() override; + +private: + sound_stream *m_stream; + + s32 m_sample_increment[0x4000]; + s32 m_linear_attenuation[0x100]; + s16 m_sample_log8[0x100]; + + u64 m_keyon_mask, m_active_mask; + u32 m_pre_size[0x40], m_post_size[0x40], m_address[0x40]; + + s32 m_sample_pos[64]; + + u16 m_volume[0x40], m_freq[0x40], m_pan[0x40]; + + u16 volume_r(offs_t offset); + void volume_w(offs_t offset, u16 data); + u16 freq_r(offs_t offset); + void freq_w(offs_t offset, u16 data); + u16 pre_size_r(offs_t offset); + void pre_size_w(offs_t offset, u16 data); + u16 post_size_r(offs_t offset); + void post_size_w(offs_t offset, u16 data); + u16 address_r(offs_t offset); + void address_w(offs_t offset, u16 data); + u16 pan_r(offs_t offset); + void pan_w(offs_t offset, u16 data); + template u16 keyon_mask_r(); + template void keyon_mask_w(u16 data); + u16 keyon_r(); + void keyon_w(u16); + + u16 snd_r(offs_t offset); + void snd_w(offs_t offset, u16 data); +}; + +DECLARE_DEVICE_TYPE(SWP30, swp30_device) + +#endif diff --git a/src/devices/video/hd44780.cpp b/src/devices/video/hd44780.cpp index a810e90b5f0..8a1a436befb 100644 --- a/src/devices/video/hd44780.cpp +++ b/src/devices/video/hd44780.cpp @@ -345,27 +345,27 @@ uint32_t hd44780_device::screen_update(screen_device &screen, bitmap_ind16 &bitm return 0; } -READ8_MEMBER(hd44780_device::read) +u8 hd44780_device::read(offs_t offset) { switch (offset & 0x01) { - case 0: return control_read(space, 0); - case 1: return data_read(space, 0); + case 0: return control_read(); + case 1: return data_read(); } return 0; } -WRITE8_MEMBER(hd44780_device::write) +void hd44780_device::write(offs_t offset, u8 data) { switch (offset & 0x01) { - case 0: control_write(space, 0, data); break; - case 1: data_write(space, 0, data); break; + case 0: control_write(data); break; + case 1: data_write(data); break; } } -WRITE8_MEMBER(hd44780_device::control_write) +void hd44780_device::control_write(u8 data) { if (m_data_len == 4) { @@ -485,7 +485,7 @@ WRITE8_MEMBER(hd44780_device::control_write) m_first_cmd = false; } -READ8_MEMBER(hd44780_device::control_read) +u8 hd44780_device::control_read() { if (m_data_len == 4) { @@ -503,7 +503,7 @@ READ8_MEMBER(hd44780_device::control_read) } } -WRITE8_MEMBER(hd44780_device::data_write) +void hd44780_device::data_write(u8 data) { if (m_busy_flag) { @@ -543,7 +543,7 @@ WRITE8_MEMBER(hd44780_device::data_write) set_busy_flag(41); } -READ8_MEMBER(hd44780_device::data_read) +u8 hd44780_device::data_read() { uint8_t data = (m_active_ram == DDRAM) ? m_ddram[m_ac] : m_cgram[m_ac]; diff --git a/src/devices/video/hd44780.h b/src/devices/video/hd44780.h index 45750c0475c..bcf5a683a88 100644 --- a/src/devices/video/hd44780.h +++ b/src/devices/video/hd44780.h @@ -39,19 +39,19 @@ public: typedef device_delegate pixel_update_delegate; // construction/destruction - hd44780_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + hd44780_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); // static configuration helpers void set_lcd_size(int lines, int chars) { m_lines = lines; m_chars = chars; } template void set_pixel_update_cb(T &&... args) { m_pixel_update_cb = pixel_update_delegate(std::forward(args)...); } // device interface - virtual DECLARE_WRITE8_MEMBER(write); - virtual DECLARE_READ8_MEMBER(read); - virtual DECLARE_WRITE8_MEMBER(control_write); - virtual DECLARE_READ8_MEMBER(control_read); - virtual DECLARE_WRITE8_MEMBER(data_write); - virtual DECLARE_READ8_MEMBER(data_read); + virtual void write(offs_t offset, u8 data); + virtual u8 read(offs_t offset); + virtual void control_write(u8 data); + virtual u8 control_read(); + virtual void data_write(u8 data); + virtual u8 data_read(); const uint8_t *render(); virtual uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); diff --git a/src/mame/drivers/alesis.cpp b/src/mame/drivers/alesis.cpp index f31f60fde61..eb9b72ac435 100644 --- a/src/mame/drivers/alesis.cpp +++ b/src/mame/drivers/alesis.cpp @@ -72,7 +72,7 @@ WRITE8_MEMBER( alesis_state::p3_w ) WRITE8_MEMBER( alesis_state::sr16_lcd_w ) { - m_lcdc->write(space, BIT(m_kb_matrix,7), data); + m_lcdc->write(BIT(m_kb_matrix,7), data); } WRITE8_MEMBER( alesis_state::mmt8_led_w ) diff --git a/src/mame/drivers/alphasma.cpp b/src/mame/drivers/alphasma.cpp index 8e9df198ad3..c6b6613d4a0 100644 --- a/src/mame/drivers/alphasma.cpp +++ b/src/mame/drivers/alphasma.cpp @@ -62,7 +62,7 @@ protected: virtual DECLARE_WRITE8_MEMBER(port_a_w); DECLARE_READ8_MEMBER(port_d_r); DECLARE_WRITE8_MEMBER(port_d_w); - void update_lcdc(address_space &space, bool lcdc0, bool lcdc1); + void update_lcdc(bool lcdc0, bool lcdc1); void alphasmart_io(address_map &map); void alphasmart_mem(address_map &map); @@ -128,17 +128,17 @@ READ8_MEMBER(alphasmart_state::port_a_r) return (m_port_a & 0xfd) | (m_battery_status->read() << 1); } -void alphasmart_state::update_lcdc(address_space &space, bool lcdc0, bool lcdc1) +void alphasmart_state::update_lcdc(bool lcdc0, bool lcdc1) { if (m_matrix[1] & 0x04) { uint8_t lcdc_data = 0; if (lcdc0) - lcdc_data |= m_lcdc0->read(space, BIT(m_matrix[1], 1)); + lcdc_data |= m_lcdc0->read(BIT(m_matrix[1], 1)); if (lcdc1) - lcdc_data |= m_lcdc1->read(space, BIT(m_matrix[1], 1)); + lcdc_data |= m_lcdc1->read(BIT(m_matrix[1], 1)); m_port_d = (m_port_d & 0xc3) | (lcdc_data>>2); } @@ -147,17 +147,17 @@ void alphasmart_state::update_lcdc(address_space &space, bool lcdc0, bool lcdc1) uint8_t lcdc_data = (m_port_d<<2) & 0xf0; if (lcdc0) - m_lcdc0->write(space, BIT(m_matrix[1], 1), lcdc_data); + m_lcdc0->write(BIT(m_matrix[1], 1), lcdc_data); if (lcdc1) - m_lcdc1->write(space, BIT(m_matrix[1], 1), lcdc_data); + m_lcdc1->write(BIT(m_matrix[1], 1), lcdc_data); } } WRITE8_MEMBER(alphasmart_state::port_a_w) { uint8_t changed = (m_port_a ^ data) & data; - update_lcdc(space, changed & 0x80, changed & 0x20); + update_lcdc(changed & 0x80, changed & 0x20); m_rambank->set_entry(((data>>3) & 0x01) | ((data>>4) & 0x02)); m_port_a = data; } @@ -207,7 +207,7 @@ WRITE8_MEMBER(asma2k_state::io_w) else if (offset == 0x4000) { uint8_t changed = (m_lcd_ctrl ^ data) & data; - update_lcdc(space, changed & 0x01, changed & 0x02); + update_lcdc(changed & 0x01, changed & 0x02); m_lcd_ctrl = data; } diff --git a/src/mame/drivers/cz101.cpp b/src/mame/drivers/cz101.cpp index aeb76c3c052..9854296ebf3 100644 --- a/src/mame/drivers/cz101.cpp +++ b/src/mame/drivers/cz101.cpp @@ -325,7 +325,7 @@ READ8_MEMBER( cz101_state::keys_r ) READ8_MEMBER( cz101_state::port_a_r ) { if ((BIT(m_port_c, 7) == 1) && (BIT(m_port_c, 6) == 1)) - return m_hd44780->read(space, BIT(m_port_c, 5)); + return m_hd44780->read(BIT(m_port_c, 5)); return 0xff; } @@ -333,7 +333,7 @@ READ8_MEMBER( cz101_state::port_a_r ) WRITE8_MEMBER( cz101_state::port_a_w ) { if ((BIT(m_port_c, 7) == 1) && (BIT(m_port_c, 6) == 0)) - m_hd44780->write(space, BIT(m_port_c, 5), data); + m_hd44780->write(BIT(m_port_c, 5), data); } // 7------- nmi output diff --git a/src/mame/drivers/novag6502.cpp b/src/mame/drivers/novag6502.cpp index d3f118b0750..edfb13e134d 100644 --- a/src/mame/drivers/novag6502.cpp +++ b/src/mame/drivers/novag6502.cpp @@ -410,7 +410,7 @@ WRITE8_MEMBER(novag6502_state::sexpert_lcd_control_w) // d1: HD44780 R/W // d2: HD44780 E if (m_lcd_control & ~data & 4 && ~data & 2) - m_lcd->write(space, m_lcd_control & 1, m_lcd_data); + m_lcd->write(m_lcd_control & 1, m_lcd_data); m_lcd_control = data & 7; } diff --git a/src/mame/drivers/novag68k.cpp b/src/mame/drivers/novag68k.cpp index 4ac9dbad1bb..6ae8b414bdd 100644 --- a/src/mame/drivers/novag68k.cpp +++ b/src/mame/drivers/novag68k.cpp @@ -82,7 +82,7 @@ WRITE8_MEMBER(novag68k_state::diablo68k_control_w) // d0: HD44780 E // d1: HD44780 RS if (m_lcd_control & ~data & 1) - m_lcd->write(space, m_lcd_control >> 1 & 1, m_lcd_data); + m_lcd->write(m_lcd_control >> 1 & 1, m_lcd_data); m_lcd_control = data & 3; // d7: enable beeper @@ -130,7 +130,7 @@ WRITE8_MEMBER(novag68k_state::scorpio68k_control_w) // d0: HD44780 E // d1: HD44780 RS if (m_lcd_control & ~data & 1) - m_lcd->write(space, m_lcd_control >> 1 & 1, m_lcd_data); + m_lcd->write(m_lcd_control >> 1 & 1, m_lcd_data); m_lcd_control = data & 3; // d7: enable beeper diff --git a/src/mame/drivers/pc2000.cpp b/src/mame/drivers/pc2000.cpp index b55ea95f587..d93948e7fb8 100644 --- a/src/mame/drivers/pc2000.cpp +++ b/src/mame/drivers/pc2000.cpp @@ -362,7 +362,7 @@ READ8_MEMBER( pc1000_state::kb_r ) READ8_MEMBER( pc1000_state::lcdc_data_r ) { //logerror("lcdc data r\n"); - return m_lcdc->data_read(space, 0) >> 4; + return m_lcdc->data_read() >> 4; } WRITE8_MEMBER( pc1000_state::lcdc_data_w ) @@ -370,19 +370,19 @@ WRITE8_MEMBER( pc1000_state::lcdc_data_w ) //popmessage("%s", (char*)m_maincpu->space(AS_PROGRAM).get_read_ptr(0x4290)); //logerror("lcdc data w %x\n", data); - m_lcdc->data_write(space, 0, data << 4); + m_lcdc->data_write(data << 4); } READ8_MEMBER( pc1000_state::lcdc_control_r ) { //logerror("lcdc control r\n"); - return m_lcdc->control_read(space, 0) >> 4; + return m_lcdc->control_read() >> 4; } WRITE8_MEMBER( pc1000_state::lcdc_control_w ) { //logerror("lcdc control w %x\n", data); - m_lcdc->control_write(space, 0, data<<4); + m_lcdc->control_write(data<<4); } HD44780_PIXEL_UPDATE(pc1000_state::pc1000_pixel_update) diff --git a/src/mame/drivers/piggypas.cpp b/src/mame/drivers/piggypas.cpp index 8583b8eb894..264a368357c 100644 --- a/src/mame/drivers/piggypas.cpp +++ b/src/mame/drivers/piggypas.cpp @@ -112,9 +112,9 @@ WRITE8_MEMBER(piggypas_state::lcd_control_w) if (BIT(data, 0)) { if (BIT(data, 2)) - m_lcd_latch = m_hd44780->read(space, BIT(data, 1)); + m_lcd_latch = m_hd44780->read(BIT(data, 1)); else - m_hd44780->write(space, BIT(data, 1), m_lcd_latch); + m_hd44780->write(BIT(data, 1), m_lcd_latch); } // T0 (P3.4) = output shift clock (serial data present at P1.0) diff --git a/src/mame/drivers/psion.cpp b/src/mame/drivers/psion.cpp index bc8209405b3..d7eb5777f8e 100644 --- a/src/mame/drivers/psion.cpp +++ b/src/mame/drivers/psion.cpp @@ -199,7 +199,7 @@ WRITE8_MEMBER( psion_state::io_w ) switch (offset & 0x0ffc0) { case 0x80: - m_lcdc->write(space, offset & 0x01, data); + m_lcdc->write(offset & 0x01, data); break; default: io_rw(space, offset); @@ -211,7 +211,7 @@ READ8_MEMBER( psion_state::io_r ) switch (offset & 0xffc0) { case 0x80: - return m_lcdc->read(space, offset & 0x01); + return m_lcdc->read(offset & 0x01); default: io_rw(space, offset); } diff --git a/src/mame/drivers/replicator.cpp b/src/mame/drivers/replicator.cpp index c54cef2f7ea..a4afebb03df 100644 --- a/src/mame/drivers/replicator.cpp +++ b/src/mame/drivers/replicator.cpp @@ -361,9 +361,9 @@ WRITE8_MEMBER(replicator_state::port_w) if (enable && RW==0){ if (RS==0){ - m_lcdc->control_write(space, 0, lcd_data); + m_lcdc->control_write(lcd_data); } else { - m_lcdc->data_write(space, 0, lcd_data); + m_lcdc->data_write(lcd_data); } } } diff --git a/src/mame/drivers/rz1.cpp b/src/mame/drivers/rz1.cpp index 0a2b445ebb6..1b36b2141b4 100644 --- a/src/mame/drivers/rz1.cpp +++ b/src/mame/drivers/rz1.cpp @@ -245,7 +245,7 @@ READ8_MEMBER( rz1_state::port_a_r ) if ((BIT(m_port_b, 7) == 0) && (BIT(m_port_b, 6) == 1)) { // Not clear why, but code expects to read busy flag from PA5 rather than PA7 - return bitswap<8>(m_hd44780->read(space, BIT(m_port_b, 5)), 5, 6, 7, 4, 3, 2, 1, 0); + return bitswap<8>(m_hd44780->read(BIT(m_port_b, 5)), 5, 6, 7, 4, 3, 2, 1, 0); } logerror("port_a_r (PB = %02x)\n", m_port_b); @@ -257,7 +257,7 @@ WRITE8_MEMBER( rz1_state::port_a_w ) m_port_a = data; if ((BIT(m_port_b, 7) == 0) && (BIT(m_port_b, 6) == 0)) - m_hd44780->write(space, BIT(m_port_b, 5), data); + m_hd44780->write(BIT(m_port_b, 5), data); } // 7------- lcd e diff --git a/src/mame/drivers/ymmu100.cpp b/src/mame/drivers/ymmu100.cpp index e810f5f9e0c..1e9139822de 100644 --- a/src/mame/drivers/ymmu100.cpp +++ b/src/mame/drivers/ymmu100.cpp @@ -120,6 +120,7 @@ #include "bus/midi/midioutport.h" #include "cpu/h8/h8s2655.h" #include "video/hd44780.h" +#include "sound/swp30.h" #include "debugger.h" #include "screen.h" @@ -148,12 +149,112 @@ static INPUT_PORTS_START( mu100 ) PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_UNUSED) INPUT_PORTS_END +/* 40 41 42 43 + +reads + .09 at 3e5a, tests & 0x8000 + .05 at 3e4a: read current to change bits (sets xaxx) + .0a at 4070: read current to change bits (keeps 14-15) + +01.0f at d320: put bits 6-13 in r0l inverted, bits 14-15 in r0h 6-7, does complex calcs from it + + + +[:] snd_w 00.09, f000 (0020a0) +[:] snd_w 00.10, 4000 (00d376) +[:] snd_w 00.00, 169b (00d3be) +[:] snd_w 00.01, e0ff (00d3d0) +[:] snd_w 00.02, 8000 (00d3f8) +[:] snd_w 00.03, 5010 (00d400) +[:] snd_w 00.04, 0000 (00d412) +[:] snd_w 00.05, fb00 (00d434) +[:] snd_w 00.20, e05d (00d43e) +[:] snd_w 00.22, 1fa3 (00d448) +[:] snd_w 00.24, 2000 (00d452) +[:] snd_w 00.26, 0257 (00d45c) +[:] snd_w 00.28, fda9 (00d466) +[:] snd_w 00.2a, 2000 (00d470) +[:] snd_w 00.06, 5d80 (00d48e) +[:] snd_w 00.07, 1414 (00d4ae) 1614 1614 1614 +[:] snd_w 00.08, 18fe (00d4ce) 1afe 1afe 1afe +[:] snd_w 00.0a, 5f00 (00d510) +[:] snd_w 00.0b, 0000 (00d530) +[:] snd_w 00.0b, 6f00 (00d53a) +[:] snd_w 00.11, be29 (00d54e) be7e bdd2 be27 +[:] snd_w 00.12, 0000 (00d56c) +[:] snd_w 00.13, 5c74 (00d570) 6f0b +[:] snd_w 00.14, 0000 (00d586) +[:] snd_w 00.15, 749d (00d58a) 749d 5951 5951 +[:] snd_w 00.16, ee42 (00d5d6) +[:] snd_w 00.17, a89b (00d5da) +[:] snd_w 00.32, 0808 (00d5ea) +[:] snd_w 00.33, 182b (00d5fa) +[:] snd_w 00.34, ff10 (00d60a) +[:] snd_w 00.35, 0d00 (00d614) +[:] snd_w 00.36, 0800 (00d61e) +[:] snd_w 00.37, 0400 (00d628) +[:] snd_w 00.09, 70e0 (00d634) +[:] snd_r 00.0b (00d638) +[:] snd_r 00.0b (00d63c) +[:] snd_r 00.09 (00d658) +[:] snd_r 00.09 (00d65c) + + e3 = (note - ->m1b) * 100 + s8(->m2b) + + compute freq adjustment in 1/100th of semitone (ex. 737) +clamp to +/- 9599 +(2d74) +div/rem by 300 -> e6 = 137, r6 = 2 +lookup d14c[rem].b (0-299 -> 00-ff, perfectly linear), tack div on top -> 274 +put sign back in, and with 3fff, -> g58 + + + + + + + 9 = attenuation? +11 = 52|58 -> 15 flag, 14 zero, 13-0 cents frequency adjustment +12-13 = pre-size + flags +14-15 = post-size + flags +16-17 = address + flags + loop size? +32 = 6a/6b = pan l/r +33 = 6c/6d = ? / reverb attenuation +34 = 6e/6f = chorus attenuation / ? +35 = 70 +36 = 72 +37 = 74 +3e = ? / chorus lfo frequency +3f = ? / chorus lfo frequency + +09 = 0x7000 + 4c +read 0b twice, store the second is 2114c7 + +d510: + r6 = ffec54 (0) + if(!0) { ... } + r5 = r6 + +0b = r5 + r5h = ffec50 + +0b = r5 + +11 = ffec58 | (ffec52 << 8) + +12, +13 = ffec5c.l | (ffec5a << 24) + +14, +15 = ffec60.l | (ffec64 << 24) + +50: 6f 40 80 00 00 00 00 00 3e 27 00 00 00 00 6f 0b +60: 00 00 59 51 00 ee 00 42 e1 87 08 08 18 2b ff 10 + +2e1c computes everything + +*/ + class mu100_state : public driver_device { public: mu100_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), + m_swp30(*this, "swp30"), m_lcd(*this, "lcd"), m_ioport_p7(*this, "P7"), m_ioport_p8(*this, "P8") @@ -161,8 +262,34 @@ public: void mu100(machine_config &config); + int seq; + + virtual void machine_reset() override { + timer_alloc()->adjust(attotime::from_double(5)); + seq = 0; + } + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override { + static u8 xnote[8] = { 60, 62, 64, 65, 67, 69, 71, 72 }; + static int note = 0; + switch(seq) { + case 0: push(0x90); logerror("swp30 midi keyon %d\n", note); timer.adjust(attotime::from_double(0.0005)); if(1) machine().debug_break(); break; + case 1: push(xnote[note]); timer.adjust(attotime::from_double(0.0005)); break; + case 2: push(0x7f); timer.adjust(attotime::from_double(0.5)); break; + case 3: push(0x80); logerror("swp30 midi keyoff\n"); timer.adjust(attotime::from_double(0.0005)); if(0) machine().debug_break(); break; + case 4: push(xnote[note]); timer.adjust(attotime::from_double(0.0005)); note++; if(note == 8) note = 0; break; + case 5: push(0x7f); timer.adjust(attotime::from_double(0.05)); seq=0; return; + } + seq ++; + } + + void push(u8 val) { + logerror("push %02x\n", val); + machine().root_device().subdevice("maincpu:sci0")->force(val); + } + protected: - virtual DECLARE_READ16_MEMBER(adc7_r); + virtual u16 adc7_r(); private: enum { @@ -172,39 +299,38 @@ private: }; required_device m_maincpu; + required_device m_swp30; required_device m_lcd; required_ioport m_ioport_p7; required_ioport m_ioport_p8; - uint8_t cur_p1, cur_p2, cur_p3, cur_p5, cur_p6, cur_pa, cur_pf, cur_pg; - uint8_t cur_ic32; + u8 cur_p1, cur_p2, cur_p3, cur_p5, cur_p6, cur_pa, cur_pf, cur_pg; + u8 cur_ic32; float contrast; - DECLARE_READ16_MEMBER(adc0_r); - DECLARE_READ16_MEMBER(adc2_r); - DECLARE_READ16_MEMBER(adc4_r); - DECLARE_READ16_MEMBER(adc6_r); - - DECLARE_WRITE16_MEMBER(p1_w); - DECLARE_READ16_MEMBER(p1_r); - DECLARE_WRITE16_MEMBER(p2_w); - DECLARE_WRITE16_MEMBER(p3_w); - DECLARE_WRITE16_MEMBER(p5_w); - DECLARE_WRITE16_MEMBER(p6_w); - DECLARE_READ16_MEMBER(p6_r); - DECLARE_WRITE16_MEMBER(pa_w); - DECLARE_READ16_MEMBER(pa_r); - DECLARE_WRITE16_MEMBER(pf_w); - DECLARE_WRITE16_MEMBER(pg_w); - - DECLARE_READ16_MEMBER(snd_r); - DECLARE_WRITE16_MEMBER(snd_w); - - float lightlevel(const uint8_t *src, const uint8_t *render); - uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + u16 adc0_r(); + u16 adc2_r(); + u16 adc4_r(); + u16 adc6_r(); + + void p1_w(u16 data); + u16 p1_r(); + void p2_w(u16 data); + void p3_w(u16 data); + void p5_w(u16 data); + void p6_w(u16 data); + u16 p6_r(); + void pa_w(u16 data); + u16 pa_r(); + void pf_w(u16 data); + void pg_w(u16 data); + + float lightlevel(const u8 *src, const u8 *render); + u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); virtual void machine_start() override; void mu100_iomap(address_map &map); void mu100_map(address_map &map); + void swp30_map(address_map &map); }; class mu100r_state : public mu100_state { @@ -214,20 +340,173 @@ public: { } private: - virtual DECLARE_READ16_MEMBER(adc7_r) override; + virtual u16 adc7_r() override; }; #include "../drivers/ymmu100.hxx" +struct v1 { + u32 m0; + u8 m4; + u8 m5; + u16 m6; + u8 m8; + u8 m9; + u16 ma; + u8 mc; + u8 md; + u16 me; +}; + +// g base = ffec00 + +// fcf30: 0010 27 1b 00 00b0f5 00 006bc4 ee 402c3e +// ... +// fcfd0: 0048 c9 45 00 006f0b 00 005951 ee 42e187 + +// 4772 616e 6450 2023 GrandP # +// f5b1e: 0225 007f 017f 58f0 8040 7000 4040 3c77 +// 3c3f 3f3f 3f40 4040 4040 0100 441f 3c54 +// 6c42 4042 45d7 093c 3f01 020d 404e 4640 +// 406c 183c 505c 4045 3e3b 9748 902f 0b0d +// 2075 0000 0000 0050 + +//20f03e: 000f5b1e 0020de54 00000000 0000fdd5 + +#if 0 +// samp2: +// 000000 - 00 20 27 1b 00 00b0f5 00 006bc4 ee 402c3e +// 004734 - 00 23 f9 1f 00 00bafd 00 007d3c ee 4075f0 +// 009544 - 00 28 2b 23 00 00cbc6 00 007d50 e4 40c832 +// 00e78b - 00 2b c7 28 00 00c0a6 00 007b70 e4 4117b1 +// 013691 - 00 32 29 2d 00 00bd5e 00 007c62 ee 4165e6 + + +// g34 = 0x43 = note + +// checksums +// 2.ef = (0/4000000) | (1 << n) +// 3.e = 0000 +// 3.f = 0001 +// 4.e = 8000 +// wait until 4.f.b != 0 +// read 5.ef and compare +// 4.e = 0000 + +// 0..13 for 32M, 0..12 for 16M + +// list of checksums at 58712/58766 +// ff49 ffa0 +// feb3 ff03 +// fd93 fdd7 +// fb76 fbb0 +// f79d f7e7 + +// f1e40 = select instrument +void f1e40() +{ + er3 = g04; // 20de54 + r5 = g29; // 7f - global volume? + r4 = er3->mcb; // 40 - global volume? + r5 = r4*r5 >> 6; // -> 7f + r5 += 2*(er3->md - 0x40); + r5 = clamp(r5, 1, 0x7f); + g29 = r5; + r5 = g20f034; // 01 + if(r5 & 1) { + r4 = er3->m1b; // 00 + r4 = lcb098[r4]; // byte, 00 + if(!r4) { + r4 = er3->m2b; + r6 = g20f031; + if(!r6) + r4 = lcb118[r4]; + else { + r6 = g20f034; + if(r6 == 3) + r4 = lcb118[r4]; + else + r4 = lcb218[r4]; + } + } else { + if(r4 != 0x48) + r4 = lcb198[er3->m2b]; + } + } else + r4 = lcb518[er3->m1b]; + + // r4 -> 55 + r4 = (r4 << 8) | (er3->m3b << 1); + r4 = cb710 + lb4898[r4 >> 1]; // dword 2a404 -> f5b14 005a GrandP # + g0c = r4 + 0xe; + + +} + +void f2ace(er4 *instrument) // f5b1e +{ + r6 = (er4->m0 << 7) | er4->m1; + if(r6 < 0x125) + r6 = lf692e + tfccde[r6].w; + else if(r6 < 0x147) + r6 = lfcf30 + tfdf80[r6 - 0x125].w; + else + r6 = lfdfc4 + t100c34[r6 - 0x147].w; + // r6 = fcf30 + while(r6->m3 & 0x7f <= g34) + r6 += 0x10; +} + +void f2d0a(...) +{ + // + f2f26(); // calc freq + + // ... + g3f = f6b14(); // r6h + f330a(); // sets 6a/6b + f2e1c(); // sets 5a/64/5c/66/60/65 + f3038(); // sets 38 + f31f8(er4); // sets 46 47 48 4a + f32a4(); // sets 40 + f3486(); // sets 90/92/94/96/98/9a + f309c(); +} + +void f2e1c(er4 **instrument) // 20f03e -> f5b1e +{ + v1 *xv1 = g18; // fcfd0 + g5a = xv1->m4; + g64 = xv1->m8; + er1 = (xv1->m5 << 16) | xv1->m6; + er2 = (xv1->md << 16) | xv1->me; + er3 = (xv1->m9 << 16) | xv1->ma; + er6 = *er4; + r0 = xv1->mc << 8; + r5 = (er6->m43 << 7) + er6->m44; + if(!(g64 & 0x80)) { + er1 = max(0, er1 - er5); + + } else { + // 2ae2 + } + // 2ef8 + g5c = er1; + g66 = er2; + g60 = er3; + g65 = r0 >> 8; +} +#endif + void mu100_state::machine_start() { cur_p1 = cur_p2 = cur_p3 = cur_p5 = cur_p6 = cur_pa = cur_pf = cur_pg = cur_ic32 = 0xff; contrast = 1.0; } -float mu100_state::lightlevel(const uint8_t *src, const uint8_t *render) +float mu100_state::lightlevel(const u8 *src, const u8 *render) { - uint8_t l = *src; + u8 l = *src; if(l == 0) return 1.0; int slot = (src[1] << 8) | src[2]; @@ -241,16 +520,16 @@ float mu100_state::lightlevel(const uint8_t *src, const uint8_t *render) return 0.95f; } -uint32_t mu100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +u32 mu100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - const uint8_t *render = m_lcd->render(); - const uint8_t *src = ymmu100_bkg + 15; + const u8 *render = m_lcd->render(); + const u8 *src = ymmu100_bkg + 15; for(int y=0; y<241; y++) { - uint32_t *pix = reinterpret_cast(bitmap.raw_pixptr(y)); + u32 *pix = reinterpret_cast(bitmap.raw_pixptr(y)); for(int x=0; x<800; x++) { float light = lightlevel(src, render); - uint32_t col = (int(0xef*light) << 16) | (int(0xf5*light) << 8); + u32 col = (int(0xef*light) << 16) | (int(0xf5*light) << 8); *pix++ = col; src += 3; } @@ -264,7 +543,7 @@ uint32_t mu100_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, int y = 55 + 65*(i >> 1); for(int yy=-9; yy <= 9; yy++) { int dx = int(sqrt((float)(99-yy*yy))); - uint32_t *pix = reinterpret_cast(bitmap.raw_pixptr(y+yy)) + (x-dx); + u32 *pix = reinterpret_cast(bitmap.raw_pixptr(y+yy)) + (x-dx); for(int xx=0; xx<2*dx+1; xx++) *pix++ = 0x00ff00; } @@ -276,79 +555,64 @@ void mu100_state::mu100_map(address_map &map) { map(0x000000, 0x1fffff).rom().region("maincpu", 0); map(0x200000, 0x21ffff).ram(); // 128K work RAM - map(0x400000, 0x401fff).rw(FUNC(mu100_state::snd_r), FUNC(mu100_state::snd_w)); -} - -READ16_MEMBER(mu100_state::snd_r) -{ - int chan = (offset >> 6) & 0x3f; - int slot = offset & 0x3f; - logerror("snd_r %02x.%02x (%06x)\n", chan, slot, m_maincpu->pc()); - return 0x0000; -} - -WRITE16_MEMBER(mu100_state::snd_w) -{ - int chan = (offset >> 6) & 0x3f; - int slot = offset & 0x3f; - logerror("snd_w %02x.%02x, %04x (%06x)\n", chan, slot, data, m_maincpu->pc()); + map(0x400000, 0x401fff).m(m_swp30, FUNC(swp30_device::map)); } -READ16_MEMBER(mu100_state::adc0_r) +u16 mu100_state::adc0_r() { logerror("adc0_r\n"); return 0; } -READ16_MEMBER(mu100_state::adc2_r) +u16 mu100_state::adc2_r() { logerror("adc2_r\n"); return 0; } // Put the host switch to pure midi -READ16_MEMBER(mu100_state::adc4_r) +u16 mu100_state::adc4_r() { return 0; } // Battery level -READ16_MEMBER(mu100_state::adc6_r) +u16 mu100_state::adc6_r() { logerror("adc6_r\n"); return 0x3ff; } // model detect. pulled to GND (0) on MU100, to 0.5Vcc on the card version, to Vcc on MU100R -READ16_MEMBER(mu100_state::adc7_r) +u16 mu100_state::adc7_r() { return 0; } -READ16_MEMBER(mu100r_state::adc7_r) +u16 mu100r_state::adc7_r() { return 0x3ff; } -WRITE16_MEMBER(mu100_state::p1_w) +void mu100_state::p1_w(u16 data) { cur_p1 = data; } -READ16_MEMBER(mu100_state::p1_r) +u16 mu100_state::p1_r() { if((cur_p2 & P2_LCD_ENABLE)) { if(cur_p2 & P2_LCD_RW) { if(cur_p2 & P2_LCD_RS) - return m_lcd->data_read(space, offset); + return m_lcd->data_read(); else - return m_lcd->control_read(space, offset); + return m_lcd->control_read(); } else return 0x00; } if(!(cur_pf & 0x02)) { - uint8_t val = 0xff; + u8 val = 0xff; if(!(cur_ic32 & 0x20)) val &= m_ioport_p7->read(); if(!(cur_ic32 & 0x40)) @@ -359,65 +623,65 @@ READ16_MEMBER(mu100_state::p1_r) return 0xff; } -WRITE16_MEMBER(mu100_state::p2_w) +void mu100_state::p2_w(u16 data) { // LCB enable edge if(!(cur_p2 & P2_LCD_ENABLE) && (data & P2_LCD_ENABLE)) { if(!(cur_p2 & P2_LCD_RW)) { if(cur_p2 & P2_LCD_RS) - m_lcd->data_write(space, offset, cur_p1); + m_lcd->data_write(cur_p1); else - m_lcd->control_write(space, offset, cur_p1); + m_lcd->control_write(cur_p1); } } contrast = (8 - ((cur_p2 >> 3) & 7))/8.0; cur_p2 = data; } -WRITE16_MEMBER(mu100_state::p3_w) +void mu100_state::p3_w(u16 data) { cur_p3 = data; logerror("A/D gain control %d\n", (data >> 4) & 3); } -WRITE16_MEMBER(mu100_state::p5_w) +void mu100_state::p5_w(u16 data) { cur_p5 = data; logerror("Rotary reset %d\n", (data >> 3) & 1); } -WRITE16_MEMBER(mu100_state::p6_w) +void mu100_state::p6_w(u16 data) { cur_p6 = data; logerror("pbsel %d pbreset %d soundreset %d\n", (data >> 2) & 3, (data >> 4) & 1, (data >> 5) & 1); } -READ16_MEMBER(mu100_state::p6_r) +u16 mu100_state::p6_r() { logerror("plug in detect read\n"); return 0x00; } -WRITE16_MEMBER(mu100_state::pa_w) +void mu100_state::pa_w(u16 data) { cur_pa = data; logerror("rotary encoder %d\n", (data >> 6) & 3); } -READ16_MEMBER(mu100_state::pa_r) +u16 mu100_state::pa_r() { logerror("offline detect read\n"); return 0x00; } -WRITE16_MEMBER(mu100_state::pf_w) +void mu100_state::pf_w(u16 data) { if(!(cur_pf & 0x01) && (data & 0x01)) cur_ic32 = cur_p1; cur_pf = data; } -WRITE16_MEMBER(mu100_state::pg_w) +void mu100_state::pg_w(u16 data) { cur_pg = data; logerror("pbsel3 %d\n", data & 1); @@ -440,31 +704,46 @@ void mu100_state::mu100_iomap(address_map &map) map(h8_device::ADC_7, h8_device::ADC_7).r(FUNC(mu100_state::adc7_r)); } -MACHINE_CONFIG_START(mu100_state::mu100) - MCFG_DEVICE_ADD( "maincpu", H8S2655, XTAL(16'000'000) ) - MCFG_DEVICE_PROGRAM_MAP( mu100_map ) - MCFG_DEVICE_IO_MAP( mu100_iomap ) +void mu100_state::swp30_map(address_map &map) +{ + map(0x000000*4, 0x200000*4-1).rom().region("swp30", 0).mirror(4*0x200000); + map(0x400000*4, 0x500000*4-1).rom().region("swp30", 0x800000).mirror(4*0x300000); + map(0x800000*4, 0xa00000*4-1).rom().region("swp30", 0x1000000).mirror(4*0x200000); // Missing roms... +} + +void mu100_state::mu100(machine_config &config) +{ + H8S2655(config, m_maincpu, 16_MHz_XTAL); + m_maincpu->set_addrmap(AS_PROGRAM, &mu100_state::mu100_map); + m_maincpu->set_addrmap(AS_IO, &mu100_state::mu100_iomap); - MCFG_HD44780_ADD("lcd") - MCFG_HD44780_LCD_SIZE(4, 20) + HD44780(config, m_lcd); + m_lcd->set_lcd_size(4, 20); - MCFG_SCREEN_ADD("screen", LCD) - MCFG_SCREEN_REFRESH_RATE(50) - MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate, asynchronous updating anyway */ - MCFG_SCREEN_UPDATE_DRIVER(mu100_state, screen_update) - MCFG_SCREEN_SIZE(900, 241) - MCFG_SCREEN_VISIBLE_AREA(0, 899, 0, 240) + auto &screen = SCREEN(config, "screen", SCREEN_TYPE_LCD); + screen.set_refresh_hz(50); + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate, asynchronous updating anyway */ + screen.set_screen_update(FUNC(mu100_state::screen_update)); + screen.set_size(900, 241); + screen.set_visarea(0, 899, 0, 240); SPEAKER(config, "lspeaker").front_left(); SPEAKER(config, "rspeaker").front_right(); - MCFG_MIDI_PORT_ADD("mdin", midiin_slot, "midiin") - MCFG_MIDI_RX_HANDLER(WRITELINE("maincpu:sci0", h8_sci_device, rx_w)) + SWP30(config, m_swp30); + m_swp30->set_addrmap(0, &mu100_state::swp30_map); + m_swp30->add_route(0, "lspeaker", 1.0); + m_swp30->add_route(1, "rspeaker", 1.0); - MCFG_MIDI_PORT_ADD("mdout", midiout_slot, "midiout") - MCFG_DEVICE_MODIFY("maincpu:sci0") - MCFG_H8_SCI_TX_CALLBACK(WRITELINE("mdout", midi_port_device, write_txd)) -MACHINE_CONFIG_END + auto &mdin(MIDI_PORT(config, "mdin")); + midiin_slot(mdin); + mdin.rxd_handler().set("maincpu:sci0", FUNC(h8_sci_device::rx_w)); + + auto &mdout(MIDI_PORT(config, "mdout")); + midiout_slot(mdout); + + m_maincpu->subdevice("sci0")->tx_handler().set(mdout, FUNC(midi_port_device::write_txd)); +} #define ROM_LOAD16_WORD_SWAP_BIOS(bios,name,offset,length,hash) \ ROMX_LOAD(name, offset, length, hash, ROM_GROUPWORD | ROM_REVERSE | ROM_BIOS(bios)) @@ -476,11 +755,12 @@ ROM_START( mu100 ) ROM_SYSTEM_BIOS( 1, "bios1", "xt71420 (v1.05, Sep. 19, 1997)" ) ROM_LOAD16_WORD_SWAP_BIOS( 1, "xt71420.ic11", 0x000000, 0x200000, CRC(0e5b3bae) SHA1(3148c5bd59a3d00809d3ab1921216215fe2582c5) ) - ROM_REGION( 0x2800000, "waverom", 0 ) + ROM_REGION( 0x1800000, "swp30", ROMREGION_ERASE00 ) ROM_LOAD32_WORD( "sx518b0.ic34", 0x000000, 0x400000, CRC(2550d44f) SHA1(fd3cce228c7d389a2fde25c808a5b26080588cba) ) ROM_LOAD32_WORD( "sx743b0.ic35", 0x000002, 0x400000, CRC(a9109a6c) SHA1(a67bb49378a38a2d809bd717d286e18bc6496db0) ) - ROM_LOAD32_WORD( "xt445a0-828.ic36", 0x800000, 0x1000000, CRC(d4483a43) SHA1(5bfd0762dea8598eda19db20251dac20e31fa02c) ) - ROM_LOAD32_WORD( "xt461a0-829.ic37", 0x800002, 0x1000000, CRC(c5af4501) SHA1(1c88de197c36382311053add8b19a5740802cb78) ) + ROM_LOAD32_WORD( "xt445a0-828.ic36", 0x800000, 0x200000, CRC(225c2280) SHA1(23b5e046fd2e2ac01af3e6dc6357c5c6547b286b) ) + ROM_LOAD32_WORD( "xt461a0-829.ic37", 0x800002, 0x200000, CRC(a1d138a3) SHA1(46a7a7225cd7e1818ba551325d2af5ac1bf5b2bf) ) + // Two missing roms at 100000+, ic38 and 39 ROM_REGION( 0x1000, "lcd", 0) // Hand made, 3 characters unused @@ -495,16 +775,17 @@ ROM_START( mu100r ) ROM_SYSTEM_BIOS( 1, "bios1", "xt71420 (v1.05, Sep. 19, 1997)" ) ROM_LOAD16_WORD_SWAP_BIOS( 1, "xt71420.ic11", 0x000000, 0x200000, CRC(0e5b3bae) SHA1(3148c5bd59a3d00809d3ab1921216215fe2582c5) ) - ROM_REGION( 0x2800000, "waverom", 0 ) + ROM_REGION( 0x1800000, "swp30", ROMREGION_ERASE00 ) ROM_LOAD32_WORD( "sx518b0.ic34", 0x000000, 0x400000, CRC(2550d44f) SHA1(fd3cce228c7d389a2fde25c808a5b26080588cba) ) ROM_LOAD32_WORD( "sx743b0.ic35", 0x000002, 0x400000, CRC(a9109a6c) SHA1(a67bb49378a38a2d809bd717d286e18bc6496db0) ) - ROM_LOAD32_WORD( "xt445a0-828.ic36", 0x800000, 0x1000000, CRC(d4483a43) SHA1(5bfd0762dea8598eda19db20251dac20e31fa02c) ) - ROM_LOAD32_WORD( "xt461a0-829.ic37", 0x800002, 0x1000000, CRC(c5af4501) SHA1(1c88de197c36382311053add8b19a5740802cb78) ) + ROM_LOAD32_WORD( "xt445a0-828.ic36", 0x800000, 0x200000, CRC(d4483a43) SHA1(5bfd0762dea8598eda19db20251dac20e31fa02c) ) + ROM_LOAD32_WORD( "xt461a0-829.ic37", 0x800002, 0x200000, CRC(c5af4501) SHA1(1c88de197c36382311053add8b19a5740802cb78) ) + // Two missing roms, ic38 and 39 ROM_REGION( 0x1000, "lcd", 0) // Hand made, 3 characters unused ROM_LOAD( "mu100-font.bin", 0x0000, 0x1000, BAD_DUMP CRC(a7d6c1d6) SHA1(9f0398d678bdf607cb34d83ee535f3b7fcc97c41) ) ROM_END -CONS( 1997, mu100, 0, 0, mu100, mu100, mu100_state, empty_init, "Yamaha", "MU100", MACHINE_NOT_WORKING ) -CONS( 1997, mu100r, mu100, 0, mu100, mu100, mu100r_state, empty_init, "Yamaha", "MU100 Rackable version", MACHINE_NOT_WORKING ) +CONS( 1997, mu100, 0, 0, mu100, mu100, mu100_state, empty_init, "Yamaha", "MU100", 0 ) +CONS( 1997, mu100r, mu100, 0, mu100, mu100, mu100r_state, empty_init, "Yamaha", "MU100 Rackable version", 0 ) diff --git a/src/mame/machine/mmboard.cpp b/src/mame/machine/mmboard.cpp index 55d237aff54..8484694f405 100644 --- a/src/mame/machine/mmboard.cpp +++ b/src/mame/machine/mmboard.cpp @@ -375,7 +375,7 @@ WRITE8_MEMBER(mephisto_display_modul_device::latch_w) WRITE8_MEMBER(mephisto_display_modul_device::io_w) { if (BIT(data, 1) && !BIT(m_ctrl, 1)) - m_lcdc->write(space, BIT(data, 0), m_latch); + m_lcdc->write(BIT(data, 0), m_latch); m_beeper->set_state(BIT(data, 2) | BIT(data, 3)); diff --git a/src/mame/machine/model1io2.cpp b/src/mame/machine/model1io2.cpp index 4c115d86bda..32ca0218772 100644 --- a/src/mame/machine/model1io2.cpp +++ b/src/mame/machine/model1io2.cpp @@ -355,7 +355,7 @@ WRITE8_MEMBER( model1io2_device::io_pf_w ) m_eeprom->cs_write(BIT(data, 4) ? ASSERT_LINE : CLEAR_LINE); if (BIT(data, 3) == 0 && BIT(data, 2) == 1 && BIT(data, 1) == 0) - m_lcd->write(space, BIT(data, 0), m_lcd_data); + m_lcd->write(BIT(data, 0), m_lcd_data); } WRITE8_MEMBER( model1io2_device::io_pg_w ) -- cgit v1.2.3