mirror of
https://github.com/holub/mame
synced 2025-04-19 15:11:37 +03:00
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.
This commit is contained in:
parent
ec8e3a038f
commit
cc537e30db
@ -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
|
||||
|
@ -278,6 +278,7 @@ SOUNDS["DAVE"] = true
|
||||
--SOUNDS["LC7535"] = true
|
||||
SOUNDS["UPD934G"] = true
|
||||
SOUNDS["IOPSPU"] = true
|
||||
SOUNDS["SWP30"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available video cores
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
463
src/devices/sound/swp30.cpp
Normal file
463
src/devices/sound/swp30.cpp
Normal file
@ -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; r5<r0b; r5++) {
|
||||
r6 = er1[r5].w; // 89 8a 8b
|
||||
e5 = (r6 % 6) + 0x21;
|
||||
r0 = r6 / 6;
|
||||
write_reg(r6/6, (r6 % 6)*2 + 0x21, g214cc2[r6].w);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
DEFINE_DEVICE_TYPE(SWP30, swp30_device, "swp30", "Yamaha SWP30 sound chip")
|
||||
|
||||
swp30_device::swp30_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SWP30, tag, owner, clock),
|
||||
device_sound_interface(mconfig, *this),
|
||||
device_rom_interface(mconfig, *this, 25+2, ENDIANNESS_LITTLE, 32)
|
||||
{
|
||||
}
|
||||
|
||||
void swp30_device::device_start()
|
||||
{
|
||||
m_stream = stream_alloc(0, 2, 44100);
|
||||
|
||||
// Attenuantion for panning is logarithmic on one byte where 0x10
|
||||
// means divide by two. It means 0 to -96dB with steps of
|
||||
// 0.375dB. Since it's a nice scale, we assume it's the same for
|
||||
// other attenuation values.
|
||||
for(int i=0; i<256; i++)
|
||||
m_linear_attenuation[i] = 65536.0/pow(2, i/16.0);
|
||||
|
||||
// Relative playback frequency of a sample is encoded on signed 14
|
||||
// bits. The scale is logarithmic, with 0x400 = 1 octave (e.g. *2
|
||||
// or /2).
|
||||
for(int i=-0x20000; i<0x2000; i++)
|
||||
m_sample_increment[i & 0x3fff] = 256 * pow(2, i/1024.0);
|
||||
|
||||
// Log to linear 8-bits sample decompression. Statistics say
|
||||
// that's what it should look like. Note that 0 can be encoded
|
||||
// both as 0x00 and 0x80, and as it happens 0x80 is never used in
|
||||
// these samples.
|
||||
|
||||
// Rescale so that it's roughly 16 bits. Range ends up being +/- 78c0.
|
||||
|
||||
for(int i=0; i<32; i++) {
|
||||
m_sample_log8[ i] = i << 0;
|
||||
m_sample_log8[0x20|i] = (i << 1) + 0x21;
|
||||
m_sample_log8[0x40|i] = (i << 2) + 0x62;
|
||||
m_sample_log8[0x60|i] = (i << 3) + 0xe3;
|
||||
}
|
||||
for(int i=0; i<128; i++) {
|
||||
m_sample_log8[i] = m_sample_log8[i] << 6;
|
||||
m_sample_log8[i | 0x80] = -m_sample_log8[i];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void swp30_device::device_reset()
|
||||
{
|
||||
memset(m_pre_size, 0, sizeof(m_pre_size));
|
||||
memset(m_post_size, 0, sizeof(m_post_size));
|
||||
memset(m_address, 0, sizeof(m_address));
|
||||
memset(m_volume, 0, sizeof(m_volume));
|
||||
memset(m_freq, 0, sizeof(m_freq));
|
||||
memset(m_pan, 0, sizeof(m_pan));
|
||||
|
||||
m_keyon_mask = 0;
|
||||
m_active_mask = 0;
|
||||
}
|
||||
|
||||
void swp30_device::rom_bank_updated()
|
||||
{
|
||||
m_stream->update();
|
||||
}
|
||||
|
||||
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<int sel> u16 swp30_device::keyon_mask_r()
|
||||
{
|
||||
return m_keyon_mask >> (16*sel);
|
||||
}
|
||||
|
||||
template<int sel> 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++;
|
||||
}
|
||||
}
|
61
src/devices/sound/swp30.h
Normal file
61
src/devices/sound/swp30.h
Normal file
@ -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<int sel> u16 keyon_mask_r();
|
||||
template<int sel> 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
|
@ -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];
|
||||
|
||||
|
@ -39,19 +39,19 @@ public:
|
||||
typedef device_delegate<void (bitmap_ind16 &bitmap, uint8_t line, uint8_t pos, uint8_t y, uint8_t x, int state)> 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 <typename... T> void set_pixel_update_cb(T &&... args) { m_pixel_update_cb = pixel_update_delegate(std::forward<T>(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);
|
||||
|
@ -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 )
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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<h8_sci_device>("maincpu:sci0")->force(val);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual DECLARE_READ16_MEMBER(adc7_r);
|
||||
virtual u16 adc7_r();
|
||||
|
||||
private:
|
||||
enum {
|
||||
@ -172,39 +299,38 @@ private:
|
||||
};
|
||||
|
||||
required_device<h8s2655_device> m_maincpu;
|
||||
required_device<swp30_device> m_swp30;
|
||||
required_device<hd44780_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);
|
||||
u16 adc0_r();
|
||||
u16 adc2_r();
|
||||
u16 adc4_r();
|
||||
u16 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);
|
||||
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);
|
||||
|
||||
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);
|
||||
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<uint32_t *>(bitmap.raw_pixptr(y));
|
||||
u32 *pix = reinterpret_cast<u32 *>(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<uint32_t *>(bitmap.raw_pixptr(y+yy)) + (x-dx);
|
||||
u32 *pix = reinterpret_cast<u32 *>(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));
|
||||
map(0x400000, 0x401fff).m(m_swp30, FUNC(swp30_device::map));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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...
|
||||
}
|
||||
|
||||
MCFG_HD44780_ADD("lcd")
|
||||
MCFG_HD44780_LCD_SIZE(4, 20)
|
||||
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_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)
|
||||
HD44780(config, m_lcd);
|
||||
m_lcd->set_lcd_size(4, 20);
|
||||
|
||||
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<h8_sci_device>("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 )
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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 )
|
||||
|
Loading…
Reference in New Issue
Block a user