mirror of
https://github.com/holub/mame
synced 2025-04-16 21:44:32 +03:00
Refactored Seta sound, adding preliminary ST0032 sound support. (#7800)
* Renamed sound/nile.cpp to sound/setapcm.cpp. * Added preliminary support for 16-voice ST0032 variant. * jclub2.cpp: Hooked up ST0032 sound. * jclub2.cpp, srmp6.cpp: Derive sound clocks from crystal frequencies.
This commit is contained in:
parent
e6caf6fb9c
commit
0a2caa105d
@ -853,7 +853,7 @@ end
|
|||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
-- Seta custom sound chips
|
-- Seta custom sound chips
|
||||||
--@src/devices/sound/st0016.h,SOUNDS["ST0016"] = true
|
--@src/devices/sound/st0016.h,SOUNDS["ST0016"] = true
|
||||||
--@src/devices/sound/nile.h,SOUNDS["NILE"] = true
|
--@src/devices/sound/setapcm.h,SOUNDS["SETAPCM"] = true
|
||||||
--@src/devices/sound/x1_010.h,SOUNDS["X1_010"] = true
|
--@src/devices/sound/x1_010.h,SOUNDS["X1_010"] = true
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
|
|
||||||
@ -864,10 +864,10 @@ if (SOUNDS["ST0016"]~=null) then
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
if (SOUNDS["NILE"]~=null) then
|
if (SOUNDS["SETAPCM"]~=null) then
|
||||||
files {
|
files {
|
||||||
MAME_DIR .. "src/devices/sound/nile.cpp",
|
MAME_DIR .. "src/devices/sound/setapcm.cpp",
|
||||||
MAME_DIR .. "src/devices/sound/nile.h",
|
MAME_DIR .. "src/devices/sound/setapcm.h",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ SOUNDS["CDDA"] = true
|
|||||||
SOUNDS["ICS2115"] = true
|
SOUNDS["ICS2115"] = true
|
||||||
SOUNDS["I5000_SND"] = true
|
SOUNDS["I5000_SND"] = true
|
||||||
SOUNDS["ST0016"] = true
|
SOUNDS["ST0016"] = true
|
||||||
SOUNDS["NILE"] = true
|
SOUNDS["SETAPCM"] = true
|
||||||
SOUNDS["X1_010"] = true
|
SOUNDS["X1_010"] = true
|
||||||
SOUNDS["VRENDER0"] = true
|
SOUNDS["VRENDER0"] = true
|
||||||
SOUNDS["VOTRAX"] = true
|
SOUNDS["VOTRAX"] = true
|
||||||
|
@ -259,7 +259,7 @@ SOUNDS["CDDA"] = true
|
|||||||
--SOUNDS["ICS2115"] = true
|
--SOUNDS["ICS2115"] = true
|
||||||
--SOUNDS["I5000_SND"] = true
|
--SOUNDS["I5000_SND"] = true
|
||||||
--SOUNDS["ST0016"] = true
|
--SOUNDS["ST0016"] = true
|
||||||
--SOUNDS["NILE"] = true
|
--SOUNDS["SETAPCM"] = true
|
||||||
--SOUNDS["X1_010"] = true
|
--SOUNDS["X1_010"] = true
|
||||||
--SOUNDS["VRENDER0"] = true
|
--SOUNDS["VRENDER0"] = true
|
||||||
SOUNDS["VOTRAX"] = true
|
SOUNDS["VOTRAX"] = true
|
||||||
|
@ -1,233 +0,0 @@
|
|||||||
// license:BSD-3-Clause
|
|
||||||
// copyright-holders:Tomasz Slanina
|
|
||||||
/************************************
|
|
||||||
Seta custom Nile ST-0026 chip
|
|
||||||
sound emulation by Tomasz Slanina
|
|
||||||
based on ST-0016 emulation
|
|
||||||
|
|
||||||
8 voices, 16 words of config data for each:
|
|
||||||
|
|
||||||
00
|
|
||||||
01 - sptr ?? (always 0)
|
|
||||||
02 - sptr LO
|
|
||||||
03 - sptr HI
|
|
||||||
04
|
|
||||||
05 - flags? 00000000 0000?L0? - bit 0 loops, other bits appear to be not used by the chip
|
|
||||||
06 - freq
|
|
||||||
07 - lsptr LO
|
|
||||||
08
|
|
||||||
09 - lsptr HI
|
|
||||||
0a - leptr LO
|
|
||||||
0b - leptr HI
|
|
||||||
0c - eptr LO
|
|
||||||
0d - eptr HI
|
|
||||||
0e - vol R
|
|
||||||
0f - vol L
|
|
||||||
|
|
||||||
************************************/
|
|
||||||
|
|
||||||
#include "emu.h"
|
|
||||||
#include "nile.h"
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
NILE_REG_UNK0=0,
|
|
||||||
NILE_REG_SPTR_TOP,
|
|
||||||
NILE_REG_SPTR_LO,
|
|
||||||
NILE_REG_SPTR_HI,
|
|
||||||
NILE_REG_UNK_4,
|
|
||||||
NILE_REG_FLAGS,
|
|
||||||
NILE_REG_FREQ,
|
|
||||||
NILE_REG_LSPTR_LO,
|
|
||||||
MILE_REG_UNK_8,
|
|
||||||
NILE_REG_LSPTR_HI,
|
|
||||||
NILE_REG_LEPTR_LO,
|
|
||||||
NILE_REG_LEPTR_HI,
|
|
||||||
NILE_REG_EPTR_LO,
|
|
||||||
NILE_REG_EPTR_HI,
|
|
||||||
NILE_REG_VOL_R,
|
|
||||||
NILE_REG_VOL_L
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
DEFINE_DEVICE_TYPE(NILE, nile_device, "nile", "Seta ST-0026 NiLe")
|
|
||||||
|
|
||||||
nile_device::nile_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
|
||||||
: device_t(mconfig, NILE, tag, owner, clock),
|
|
||||||
device_sound_interface(mconfig, *this),
|
|
||||||
m_stream(nullptr),
|
|
||||||
m_sound_ram(*this, DEVICE_SELF),
|
|
||||||
m_ctrl(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// device_start - device-specific startup
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void nile_device::device_start()
|
|
||||||
{
|
|
||||||
m_stream = stream_alloc(0, 2, 44100);
|
|
||||||
save_item(NAME(m_sound_regs));
|
|
||||||
save_item(NAME(m_vpos));
|
|
||||||
save_item(NAME(m_frac));
|
|
||||||
save_item(NAME(m_lponce));
|
|
||||||
save_item(NAME(m_ctrl));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// sound_stream_update - handle update requests
|
|
||||||
// for our sound stream
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
void nile_device::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
|
||||||
{
|
|
||||||
uint8_t *sound_ram = &m_sound_ram[0];
|
|
||||||
int v, i, snum;
|
|
||||||
uint16_t *slot;
|
|
||||||
int32_t mix[4800*2];
|
|
||||||
int32_t *mixp;
|
|
||||||
int16_t sample;
|
|
||||||
int sptr, eptr, freq, lsptr, leptr;
|
|
||||||
|
|
||||||
lsptr=leptr=0;
|
|
||||||
|
|
||||||
sound_assert(outputs[0].samples() * 2 < std::size(mix));
|
|
||||||
std::fill_n(&mix[0], outputs[0].samples()*2, 0);
|
|
||||||
|
|
||||||
for (v = 0; v < NILE_VOICES; v++)
|
|
||||||
{
|
|
||||||
slot = &m_sound_regs[v * 16];
|
|
||||||
|
|
||||||
if (m_ctrl&(1<<v))
|
|
||||||
{
|
|
||||||
mixp = &mix[0];
|
|
||||||
|
|
||||||
sptr = slot[NILE_REG_SPTR_HI]<<16 | slot[NILE_REG_SPTR_LO];
|
|
||||||
eptr = slot[NILE_REG_EPTR_HI]<<16 | slot[NILE_REG_EPTR_LO];
|
|
||||||
|
|
||||||
freq=slot[NILE_REG_FREQ]*14;
|
|
||||||
lsptr = slot[NILE_REG_LSPTR_HI]<<16 | slot[NILE_REG_LSPTR_LO];
|
|
||||||
leptr = slot[NILE_REG_LEPTR_HI]<<16 | slot[NILE_REG_LEPTR_LO];
|
|
||||||
|
|
||||||
for (snum = 0; snum < outputs[0].samples(); snum++)
|
|
||||||
{
|
|
||||||
sample = sound_ram[sptr + m_vpos[v]]<<8;
|
|
||||||
|
|
||||||
*mixp++ += (sample * (int32_t)slot[NILE_REG_VOL_R]) >> 16;
|
|
||||||
*mixp++ += (sample * (int32_t)slot[NILE_REG_VOL_L]) >> 16;
|
|
||||||
|
|
||||||
m_frac[v] += freq;
|
|
||||||
m_vpos[v] += m_frac[v]>>16;
|
|
||||||
m_frac[v] &= 0xffff;
|
|
||||||
|
|
||||||
// stop if we're at the end
|
|
||||||
if (m_lponce[v])
|
|
||||||
{
|
|
||||||
// we've looped once, check loop end rather than sample end
|
|
||||||
if ((m_vpos[v] + sptr) >= leptr)
|
|
||||||
{
|
|
||||||
m_vpos[v] = (lsptr - sptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not looped yet, check sample end
|
|
||||||
if ((m_vpos[v] + sptr) >= eptr)
|
|
||||||
{
|
|
||||||
// code at 11d8c:
|
|
||||||
// if bit 2 (0x4) is set, check if loop start = loop end.
|
|
||||||
// if they are equal, clear bit 0 and don't set the loop start/end
|
|
||||||
// registers in the NiLe. if they aren't, set bit 0 and set
|
|
||||||
// the loop start/end registers in the NiLe.
|
|
||||||
if ((slot[NILE_REG_FLAGS] & 0x5) == 0x5)
|
|
||||||
{
|
|
||||||
m_vpos[v] = (lsptr - sptr);
|
|
||||||
m_lponce[v] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_ctrl &= ~(1<<v);
|
|
||||||
m_vpos[v] = (eptr - sptr);
|
|
||||||
m_frac[v] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mixp = &mix[0];
|
|
||||||
for (i = 0; i < outputs[0].samples(); i++)
|
|
||||||
{
|
|
||||||
outputs[0].put_int(i, *mixp++, 32768 * 16);
|
|
||||||
outputs[1].put_int(i, *mixp++, 32768 * 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nile_device::nile_sndctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
|
||||||
{
|
|
||||||
uint16_t ctrl=m_ctrl;
|
|
||||||
|
|
||||||
m_stream->update();
|
|
||||||
|
|
||||||
COMBINE_DATA(&m_ctrl);
|
|
||||||
|
|
||||||
// logerror("CTRL: %04x -> %04x %s\n", ctrl, m_ctrl, machine().describe_context());
|
|
||||||
|
|
||||||
ctrl^=m_ctrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t nile_device::nile_sndctrl_r()
|
|
||||||
{
|
|
||||||
m_stream->update();
|
|
||||||
return m_ctrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint16_t nile_device::nile_snd_r(offs_t offset)
|
|
||||||
{
|
|
||||||
int reg=offset&0xf;
|
|
||||||
|
|
||||||
m_stream->update();
|
|
||||||
|
|
||||||
if(reg==2 || reg==3)
|
|
||||||
{
|
|
||||||
int slot=offset/16;
|
|
||||||
int sptr = ((m_sound_regs[slot*16+3]<<16)|m_sound_regs[slot*16+2])+m_vpos[slot];
|
|
||||||
|
|
||||||
if(reg==2)
|
|
||||||
{
|
|
||||||
return sptr&0xffff;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sptr>>16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m_sound_regs[offset];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void nile_device::nile_snd_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
|
||||||
{
|
|
||||||
int v, r;
|
|
||||||
|
|
||||||
m_stream->update();
|
|
||||||
|
|
||||||
COMBINE_DATA(&m_sound_regs[offset]);
|
|
||||||
|
|
||||||
v = offset / 16;
|
|
||||||
r = offset % 16;
|
|
||||||
|
|
||||||
if ((r == 2) || (r == 3))
|
|
||||||
{
|
|
||||||
m_vpos[v] = m_frac[v] = m_lponce[v] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//logerror("v%02d: %04x to reg %02d (PC=%x)\n", v, m_sound_regs[offset], r, machine().describe_context());
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
// license:BSD-3-Clause
|
|
||||||
// copyright-holders:Tomasz Slanina
|
|
||||||
#ifndef MAME_SOUND_NILE_H
|
|
||||||
#define MAME_SOUND_NILE_H
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// TYPE DEFINITIONS
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
// ======================> nile_device
|
|
||||||
|
|
||||||
class nile_device : public device_t,
|
|
||||||
public device_sound_interface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
nile_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// device-level overrides
|
|
||||||
virtual void device_start() override;
|
|
||||||
|
|
||||||
// sound stream update overrides
|
|
||||||
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void nile_snd_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
|
||||||
uint16_t nile_snd_r(offs_t offset);
|
|
||||||
void nile_sndctrl_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
|
|
||||||
uint16_t nile_sndctrl_r();
|
|
||||||
|
|
||||||
private:
|
|
||||||
static constexpr unsigned NILE_VOICES = 8;
|
|
||||||
|
|
||||||
sound_stream *m_stream;
|
|
||||||
required_region_ptr<uint8_t> m_sound_ram;
|
|
||||||
uint16_t m_sound_regs[0x80];
|
|
||||||
int m_vpos[NILE_VOICES];
|
|
||||||
int m_frac[NILE_VOICES];
|
|
||||||
int m_lponce[NILE_VOICES];
|
|
||||||
uint16_t m_ctrl;
|
|
||||||
};
|
|
||||||
|
|
||||||
DECLARE_DEVICE_TYPE(NILE, nile_device)
|
|
||||||
|
|
||||||
#endif // MAME_SOUND_NILE_H
|
|
429
src/devices/sound/setapcm.cpp
Normal file
429
src/devices/sound/setapcm.cpp
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Tomasz Slanina,cam900
|
||||||
|
/************************************
|
||||||
|
Seta PCM emulation
|
||||||
|
sound emulation by Tomasz Slanina
|
||||||
|
based on ST-0016 emulation
|
||||||
|
|
||||||
|
used by
|
||||||
|
- ST-0026 NiLe (srmp6, 8 voices)
|
||||||
|
- ST-0032 (jclub2, 16 voices)
|
||||||
|
- Capcom CPS3 sound hardware has similarity?
|
||||||
|
|
||||||
|
Register Format (32 byte per voices)
|
||||||
|
|
||||||
|
00-1f: Voice 0
|
||||||
|
Offset Bit Description
|
||||||
|
fedcba98 76543210
|
||||||
|
04 xxxxxxxx xxxxxxxx Start position LSB
|
||||||
|
06 xxxxxxxx xxxxxxxx Start position MSB
|
||||||
|
0a -------- ----xxx- Used but unknown
|
||||||
|
-------- -----x-- See below for NiLe specific? notes
|
||||||
|
-------- -------x Loop enable
|
||||||
|
0c xxxxxxxx xxxxxxxx Frequency
|
||||||
|
0e xxxxxxxx xxxxxxxx Loop Start position LSB
|
||||||
|
12 xxxxxxxx xxxxxxxx Loop Start position MSB
|
||||||
|
14 xxxxxxxx xxxxxxxx Loop End position LSB
|
||||||
|
16 xxxxxxxx xxxxxxxx Loop End position MSB
|
||||||
|
18 xxxxxxxx xxxxxxxx End position LSB
|
||||||
|
1a xxxxxxxx xxxxxxxx End position MSB
|
||||||
|
1c xxxxxxxx xxxxxxxx Right Volume
|
||||||
|
1e xxxxxxxx xxxxxxxx Left Volume
|
||||||
|
|
||||||
|
20-3f: Voice 1
|
||||||
|
...
|
||||||
|
e0-ff: Voice 7
|
||||||
|
|
||||||
|
100: Keyon/off, Bit 0-7 means Voice 0-7
|
||||||
|
110: Used but unknown
|
||||||
|
|
||||||
|
below for 16 voice configurations:
|
||||||
|
100-11f: Voice 8
|
||||||
|
120-13f: Voice 9
|
||||||
|
...
|
||||||
|
1e0-1ff: Voice 15
|
||||||
|
|
||||||
|
200: Keyon/off, Bit 0-15 means Voice 0-15
|
||||||
|
210: Used but unknown
|
||||||
|
|
||||||
|
Other registers are unknown/unused
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
- Verify loop and flag bit behavior from real hardware
|
||||||
|
|
||||||
|
************************************/
|
||||||
|
|
||||||
|
#include "emu.h"
|
||||||
|
#include "setapcm.h"
|
||||||
|
|
||||||
|
// constants
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
constexpr unsigned setapcm_device<MaxVoices, Divider>::MAX_VOICES;
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
constexpr unsigned setapcm_device<MaxVoices, Divider>::CLOCK_DIVIDER;
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
DEFINE_DEVICE_TYPE(NILE_SOUND, nile_sound_device, "nile_sound", "Seta ST-0026 NiLe (Sound)")
|
||||||
|
DEFINE_DEVICE_TYPE(ST0032_SOUND, st0032_sound_device, "st0032_sound", "Seta ST-0032 (Sound)")
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// LIVE DEVICE
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// setapcm_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
setapcm_device<MaxVoices, Divider>::setapcm_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: device_t(mconfig, type, tag, owner, clock)
|
||||||
|
, device_sound_interface(mconfig, *this)
|
||||||
|
, device_rom_interface(mconfig, *this)
|
||||||
|
, m_stream(nullptr)
|
||||||
|
, m_keyctrl(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nile_sound_device::nile_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: setapcm_device<8, 160>(mconfig, NILE_SOUND, tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
st0032_sound_device::st0032_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||||
|
: setapcm_device<16, 384>(mconfig, ST0032_SOUND, tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_start - device-specific startup
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::device_start()
|
||||||
|
{
|
||||||
|
// allocate stream
|
||||||
|
m_stream = stream_alloc(0, 2, clock() / CLOCK_DIVIDER);
|
||||||
|
|
||||||
|
// set host device to each voices
|
||||||
|
for (auto & elem : m_voice)
|
||||||
|
elem.m_host = this;
|
||||||
|
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_start));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_flags));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_freq));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_lpstart));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_lpend));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_end));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_vol_r));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_vol_l));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_pos));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_frac));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_lponce));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_keyon));
|
||||||
|
save_item(STRUCT_MEMBER(m_voice, m_out));
|
||||||
|
|
||||||
|
save_item(NAME(m_keyctrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// device_clock_changed - called if the clock
|
||||||
|
// changes
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::device_clock_changed()
|
||||||
|
{
|
||||||
|
m_stream->set_sample_rate(clock() / CLOCK_DIVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// sound_stream_update - handle update requests
|
||||||
|
// for our sound stream
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs)
|
||||||
|
{
|
||||||
|
outputs[0].fill(0);
|
||||||
|
outputs[1].fill(0);
|
||||||
|
|
||||||
|
for (int sampleind = 0; sampleind < outputs[0].samples(); sampleind++)
|
||||||
|
{
|
||||||
|
for (int v = 0; v < MAX_VOICES; v++)
|
||||||
|
{
|
||||||
|
// check if voice is activated
|
||||||
|
if (m_voice[v].update())
|
||||||
|
{
|
||||||
|
outputs[0].add_int(sampleind, (m_voice[v].m_out * m_voice[v].m_vol_l) >> 16, 32768 * MAX_VOICES);
|
||||||
|
outputs[1].add_int(sampleind, (m_voice[v].m_out * m_voice[v].m_vol_r) >> 16, 32768 * MAX_VOICES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// rom_bank_updated - the rom bank has changed
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::rom_bank_updated()
|
||||||
|
{
|
||||||
|
m_stream->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// update - update single voice
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
bool setapcm_device<MaxVoices, Divider>::voice_t::update()
|
||||||
|
{
|
||||||
|
if (m_keyon)
|
||||||
|
{
|
||||||
|
// fetch sample
|
||||||
|
m_out = s16(s8(m_host->read_byte(m_pos))) << 8;
|
||||||
|
|
||||||
|
// advance
|
||||||
|
m_frac += m_freq;
|
||||||
|
m_pos += m_frac >> 12;
|
||||||
|
m_frac &= 0xfff;
|
||||||
|
|
||||||
|
// stop if we're at the end
|
||||||
|
if (m_lponce)
|
||||||
|
{
|
||||||
|
// we've looped once, check loop end rather than sample end
|
||||||
|
if (m_pos >= m_lpend)
|
||||||
|
{
|
||||||
|
m_pos = m_lpstart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not looped yet, check sample end
|
||||||
|
if (m_pos >= m_end)
|
||||||
|
{
|
||||||
|
// code at 11d8c:
|
||||||
|
// if bit 2 (0x4) is set, check if loop start = loop end.
|
||||||
|
// if they are equal, clear bit 0 and don't set the loop start/end
|
||||||
|
// registers in the NiLe. if they aren't, set bit 0 and set
|
||||||
|
// the loop start/end registers in the NiLe.
|
||||||
|
// TODO: ST-0032 has same behavior?
|
||||||
|
if (BIT(m_flags, 0))
|
||||||
|
{
|
||||||
|
m_pos = m_lpstart;
|
||||||
|
m_lponce = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_keyon = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// clear output
|
||||||
|
m_out = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// keyon - set keyon flag for single voice
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::voice_t::keyon()
|
||||||
|
{
|
||||||
|
m_keyon = true;
|
||||||
|
m_pos = m_start;
|
||||||
|
m_frac = 0;
|
||||||
|
m_lponce = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// keyoff - set keyoff flag for single voice
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::voice_t::keyoff()
|
||||||
|
{
|
||||||
|
m_keyon = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// reg_r - read single voice registers
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
u16 setapcm_device<MaxVoices, Divider>::voice_t::reg_r(offs_t reg)
|
||||||
|
{
|
||||||
|
u16 ret = 0;
|
||||||
|
switch (reg & 0xf)
|
||||||
|
{
|
||||||
|
case 0x02: // Current position LSB
|
||||||
|
ret = m_pos & 0xffff;
|
||||||
|
break;
|
||||||
|
case 0x03: // Current position MSB
|
||||||
|
ret = m_pos >> 16;
|
||||||
|
break;
|
||||||
|
case 0x05: // Flags
|
||||||
|
ret = m_flags;
|
||||||
|
break;
|
||||||
|
case 0x06: // Frequency
|
||||||
|
ret = m_freq;
|
||||||
|
break;
|
||||||
|
case 0x07: // Loop start position LSB
|
||||||
|
ret = m_lpstart & 0xffff;
|
||||||
|
break;
|
||||||
|
case 0x09: // Loop start position MSB
|
||||||
|
ret = m_lpstart >> 16;
|
||||||
|
break;
|
||||||
|
case 0x0a: // Loop end position LSB
|
||||||
|
ret = m_lpend & 0xffff;
|
||||||
|
break;
|
||||||
|
case 0x0b: // Loop end position MSB
|
||||||
|
ret = m_lpend >> 16;
|
||||||
|
break;
|
||||||
|
case 0x0c: // End position LSB
|
||||||
|
ret = m_end & 0xffff;
|
||||||
|
break;
|
||||||
|
case 0x0d: // End position MSB
|
||||||
|
ret = m_end >> 16;
|
||||||
|
break;
|
||||||
|
case 0x0e: // Right volume
|
||||||
|
ret = m_vol_r;
|
||||||
|
break;
|
||||||
|
case 0x0f: // Left volume
|
||||||
|
ret = m_vol_l;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// reg_w - write single voice registers
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::voice_t::reg_w(offs_t reg, u16 data, u16 mem_mask)
|
||||||
|
{
|
||||||
|
switch (reg & 0xf)
|
||||||
|
{
|
||||||
|
case 0x02: // Start position LSB, also affected current position?
|
||||||
|
m_start = m_pos = (m_start & ~mem_mask) | (data & mem_mask);
|
||||||
|
break;
|
||||||
|
case 0x03: // Start position MSB
|
||||||
|
m_start = m_pos = (m_start & ~(u32(mem_mask) << 16)) | (u32(data & mem_mask) << 16);
|
||||||
|
break;
|
||||||
|
case 0x05: // Flags
|
||||||
|
COMBINE_DATA(&m_flags);
|
||||||
|
break;
|
||||||
|
case 0x06: // Frequency
|
||||||
|
COMBINE_DATA(&m_freq);
|
||||||
|
break;
|
||||||
|
case 0x07: // Loop start position LSB
|
||||||
|
m_lpstart = (m_lpstart & ~mem_mask) | (data & mem_mask);
|
||||||
|
break;
|
||||||
|
case 0x09: // Loop start position MSB
|
||||||
|
m_lpstart = (m_lpstart & ~(u32(mem_mask) << 16)) | (u32(data & mem_mask) << 16);
|
||||||
|
break;
|
||||||
|
case 0x0a: // Loop end position LSB
|
||||||
|
m_lpend = (m_lpend & ~mem_mask) | (data & mem_mask);
|
||||||
|
break;
|
||||||
|
case 0x0b: // Loop end position MSB
|
||||||
|
m_lpend = (m_lpend & ~(u32(mem_mask) << 16)) | (u32(data & mem_mask) << 16);
|
||||||
|
break;
|
||||||
|
case 0x0c: // End position LSB
|
||||||
|
m_end = (m_end & ~mem_mask) | (data & mem_mask);
|
||||||
|
break;
|
||||||
|
case 0x0d: // End position MSB
|
||||||
|
m_end = (m_end & ~(u32(mem_mask) << 16)) | (u32(data & mem_mask) << 16);
|
||||||
|
break;
|
||||||
|
case 0x0e: // Right volume
|
||||||
|
COMBINE_DATA(&m_vol_r);
|
||||||
|
break;
|
||||||
|
case 0x0f: // Left volume
|
||||||
|
COMBINE_DATA(&m_vol_l);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// snd_w - write each voice registers
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::snd_w(offs_t offset, u16 data, u16 mem_mask)
|
||||||
|
{
|
||||||
|
m_stream->update();
|
||||||
|
|
||||||
|
const int v = (offset >> 4);
|
||||||
|
|
||||||
|
if (v >= MAX_VOICES)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_voice[v].reg_w(offset & 0xf, data, mem_mask);
|
||||||
|
//logerror("v%02d: %04x & %04x to reg %02d (PC=%x)\n", v, data, mem_mask, r, machine().describe_context());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// snd_r - read each voice registers
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
u16 setapcm_device<MaxVoices, Divider>::snd_r(offs_t offset)
|
||||||
|
{
|
||||||
|
const int v = (offset >> 4);
|
||||||
|
|
||||||
|
if (v >= MAX_VOICES)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
m_stream->update();
|
||||||
|
|
||||||
|
return m_voice[v].reg_r(offset & 0xf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// key_w - set keyon/off flags for each voices
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
void setapcm_device<MaxVoices, Divider>::key_w(offs_t offset, u16 data, u16 mem_mask)
|
||||||
|
{
|
||||||
|
const u16 prev = m_keyctrl;
|
||||||
|
|
||||||
|
m_stream->update();
|
||||||
|
|
||||||
|
COMBINE_DATA(&m_keyctrl);
|
||||||
|
|
||||||
|
//logerror("KEYCTRL: %04x -> %04x %s\n", prev, m_keyctrl, machine().describe_context());
|
||||||
|
|
||||||
|
for (int v = 0; v < MAX_VOICES; v++)
|
||||||
|
{
|
||||||
|
if (BIT(m_keyctrl, v) && (!(BIT(prev, v)))) // keyon
|
||||||
|
{
|
||||||
|
m_voice[v].keyon();
|
||||||
|
}
|
||||||
|
else if ((!(BIT(m_keyctrl, v))) && BIT(prev, v)) // keyoff
|
||||||
|
{
|
||||||
|
m_voice[v].keyoff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// key_r - get keyon/off status from each voices
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
u16 setapcm_device<MaxVoices, Divider>::key_r()
|
||||||
|
{
|
||||||
|
m_stream->update();
|
||||||
|
return m_keyctrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// template class definition
|
||||||
|
template class setapcm_device<8, 160>;
|
||||||
|
template class setapcm_device<16, 384>;
|
103
src/devices/sound/setapcm.h
Normal file
103
src/devices/sound/setapcm.h
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// license:BSD-3-Clause
|
||||||
|
// copyright-holders:Tomasz Slanina,cam900
|
||||||
|
#ifndef MAME_SOUND_SETAPCM_H
|
||||||
|
#define MAME_SOUND_SETAPCM_H
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dirom.h"
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// TYPE DEFINITIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
// device type definition
|
||||||
|
DECLARE_DEVICE_TYPE(NILE_SOUND, nile_sound_device)
|
||||||
|
DECLARE_DEVICE_TYPE(ST0032_SOUND, st0032_sound_device)
|
||||||
|
|
||||||
|
// ======================> setapcm_device
|
||||||
|
|
||||||
|
// TODO: unknown address bus width
|
||||||
|
template<unsigned MaxVoices, unsigned Divider>
|
||||||
|
class setapcm_device : public device_t,
|
||||||
|
public device_sound_interface,
|
||||||
|
public device_rom_interface<32>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void snd_w(offs_t offset, u16 data, u16 mem_mask = ~0);
|
||||||
|
u16 snd_r(offs_t offset);
|
||||||
|
|
||||||
|
void key_w(offs_t offset, u16 data, u16 mem_mask = ~0);
|
||||||
|
u16 key_r();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
setapcm_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||||
|
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_clock_changed() override;
|
||||||
|
|
||||||
|
// sound stream update overrides
|
||||||
|
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs) override;
|
||||||
|
|
||||||
|
// device_rom_interface implementation
|
||||||
|
virtual void rom_bank_updated() override;
|
||||||
|
|
||||||
|
static constexpr unsigned MAX_VOICES = MaxVoices; // max voices
|
||||||
|
static constexpr unsigned CLOCK_DIVIDER = Divider; // clock divider for generate output rate
|
||||||
|
private:
|
||||||
|
struct voice_t
|
||||||
|
{
|
||||||
|
bool update();
|
||||||
|
void keyon();
|
||||||
|
void keyoff();
|
||||||
|
|
||||||
|
u16 reg_r(offs_t reg);
|
||||||
|
void reg_w(offs_t reg, u16 data, u16 mem_mask = ~0);
|
||||||
|
|
||||||
|
device_rom_interface<32> *m_host; // host device
|
||||||
|
u32 m_start = 0; // Start position
|
||||||
|
u16 m_flags = 0; // Flags (Bit 0 = loop)
|
||||||
|
u16 m_freq = 0; // Frequency (4.12 fixed point)
|
||||||
|
u32 m_lpstart = 0; // Loop start position
|
||||||
|
u32 m_lpend = 0; // Loop end position
|
||||||
|
u32 m_end = 0; // End position
|
||||||
|
s32 m_vol_r = 0; // Right volume
|
||||||
|
s32 m_vol_l = 0; // Left volume
|
||||||
|
u32 m_pos = 0; // Current position
|
||||||
|
u32 m_frac = 0; // Position fraction
|
||||||
|
bool m_lponce = false; // Is looped once?
|
||||||
|
bool m_keyon = false; // Keyon status
|
||||||
|
s32 m_out = 0; // output value
|
||||||
|
};
|
||||||
|
|
||||||
|
sound_stream *m_stream;
|
||||||
|
|
||||||
|
voice_t m_voice[MaxVoices]; // 8 or 16 Voice engines
|
||||||
|
u16 m_keyctrl; // Key on/off control bit
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> nile_sound_device
|
||||||
|
|
||||||
|
class nile_sound_device : public setapcm_device<8, 160>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nile_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> st0032_sound_device
|
||||||
|
|
||||||
|
class st0032_sound_device : public setapcm_device<16, 384>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
st0032_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||||
|
};
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// EXTERNAL TEMPLATE INSTANTIATIONS
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
extern template class setapcm_device<8, 160>;
|
||||||
|
extern template class setapcm_device<16, 384>;
|
||||||
|
|
||||||
|
#endif // MAME_SOUND_SETAPCM_H
|
@ -105,6 +105,7 @@
|
|||||||
#include "machine/ticket.h"
|
#include "machine/ticket.h"
|
||||||
#include "machine/timer.h"
|
#include "machine/timer.h"
|
||||||
#include "machine/watchdog.h"
|
#include "machine/watchdog.h"
|
||||||
|
#include "sound/setapcm.h"
|
||||||
#include "sound/okim6295.h"
|
#include "sound/okim6295.h"
|
||||||
#include "video/st0020.h"
|
#include "video/st0020.h"
|
||||||
#include "emupal.h"
|
#include "emupal.h"
|
||||||
@ -751,9 +752,9 @@ void jclub2_state::jclub2_map(address_map &map)
|
|||||||
map(0x880000, 0x89ffff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
|
map(0x880000, 0x89ffff).ram().w(m_palette, FUNC(palette_device::write32)).share("palette");
|
||||||
map(0x8a0000, 0x8bffff).ram(); // this should still be palette ram!
|
map(0x8a0000, 0x8bffff).ram(); // this should still be palette ram!
|
||||||
map(0x8c0000, 0x8c00ff).rw(m_st0020, FUNC(st0020_device::regs_r), FUNC(st0020_device::regs_w));
|
map(0x8c0000, 0x8c00ff).rw(m_st0020, FUNC(st0020_device::regs_r), FUNC(st0020_device::regs_w));
|
||||||
map(0x8e0000, 0x8e01ff).ram(); // sound?
|
map(0x8e0000, 0x8e01ff).rw("st0032_snd", FUNC(st0032_sound_device::snd_r), FUNC(st0032_sound_device::snd_w));
|
||||||
map(0x8e0200, 0x8e0203).ram();
|
map(0x8e0200, 0x8e0201).rw("st0032_snd", FUNC(st0032_sound_device::key_r), FUNC(st0032_sound_device::key_w));
|
||||||
map(0x8e0210, 0x8e0213).ram();
|
map(0x8e0210, 0x8e0213).ram(); // sound?
|
||||||
map(0x900000, 0x9fffff).rw(m_st0020, FUNC(st0020_device::gfxram_r), FUNC(st0020_device::gfxram_w));
|
map(0x900000, 0x9fffff).rw(m_st0020, FUNC(st0020_device::gfxram_r), FUNC(st0020_device::gfxram_w));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1212,6 +1213,15 @@ void jclub2_state::jclub2(machine_config &config)
|
|||||||
|
|
||||||
// layout
|
// layout
|
||||||
config.set_default_layout(layout_jclub2o);
|
config.set_default_layout(layout_jclub2o);
|
||||||
|
|
||||||
|
// sound hardware
|
||||||
|
// TODO: Mono?
|
||||||
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
|
|
||||||
|
st0032_sound_device &st0032_snd(ST0032_SOUND(config, "st0032_snd", XTAL(42'954'545) / 3)); // 14.318181MHz (42.954545MHz / 3)
|
||||||
|
st0032_snd.add_route(ALL_OUTPUTS, "lspeaker", 1.0);
|
||||||
|
st0032_snd.add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1387,7 +1397,7 @@ Provided to you by Belgium Dump Team Gerald (COY) on 18/01/2007.
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#define JCLUB2_OTHER_ROMS \
|
#define JCLUB2_OTHER_ROMS \
|
||||||
ROM_REGION( 0x100000, "samples", 0 ) \
|
ROM_REGION( 0x100000, "st0032_snd", 0 ) \
|
||||||
ROM_LOAD( "m88-02.u6", 0x00000, 0x100000, CRC(0dd3436a) SHA1(809d3b7a26d36f71da04036fd8ab5d0c5089392a) ) \
|
ROM_LOAD( "m88-02.u6", 0x00000, 0x100000, CRC(0dd3436a) SHA1(809d3b7a26d36f71da04036fd8ab5d0c5089392a) ) \
|
||||||
\
|
\
|
||||||
ROM_REGION( 0x117, "pld", 0 ) \
|
ROM_REGION( 0x117, "pld", 0 ) \
|
||||||
@ -1548,10 +1558,10 @@ GAME( 1996, jclub2v110, jclub2v112, jclub2o, jclub2v100, jclub2o_state, init_j
|
|||||||
GAME( 1996, jclub2v112, 0, jclub2o, jclub2v112, jclub2o_state, init_jclub2o, ROT0, "Seta", "Jockey Club II (v1.12X, older hardware)", MACHINE_IMPERFECT_GRAPHICS )
|
GAME( 1996, jclub2v112, 0, jclub2o, jclub2v112, jclub2o_state, init_jclub2o, ROT0, "Seta", "Jockey Club II (v1.12X, older hardware)", MACHINE_IMPERFECT_GRAPHICS )
|
||||||
GAME( 1997, jclub2v203, jclub2v112, jclub2o, jclub2v112, jclub2o_state, init_jclub2o, ROT0, "Seta", "Jockey Club II (v2.03X RC, older hardware, prototype)", MACHINE_IMPERFECT_GRAPHICS )
|
GAME( 1997, jclub2v203, jclub2v112, jclub2o, jclub2v112, jclub2o_state, init_jclub2o, ROT0, "Seta", "Jockey Club II (v2.03X RC, older hardware, prototype)", MACHINE_IMPERFECT_GRAPHICS )
|
||||||
// Newer hardware (ST-0032)
|
// Newer hardware (ST-0032)
|
||||||
GAME( 1996, jclub2v200, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.00, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
|
GAME( 1996, jclub2v200, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.00, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
|
||||||
GAME( 1996, jclub2v201, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.01X, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
|
GAME( 1996, jclub2v201, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.01X, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
|
||||||
GAME( 1997, jclub2v204, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.04, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
|
GAME( 1997, jclub2v204, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.04, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
|
||||||
GAME( 1997, jclub2v205, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.05, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
|
GAME( 1997, jclub2v205, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.05, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
|
||||||
GAME( 1998, jclub2v220, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.20X, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_NO_SOUND )
|
GAME( 1998, jclub2v220, jclub2v112, jclub2, jclub2v112, jclub2_state, empty_init, ROT0, "Seta", "Jockey Club II (v2.20X, newer hardware)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
|
||||||
// Bootleg hardware
|
// Bootleg hardware
|
||||||
GAME( 2001, darkhors, jclub2v112, darkhors, darkhors, darkhors_state, init_darkhors, ROT0, "bootleg", "Dark Horse (USA v4.00, bootleg of Jockey Club II)", MACHINE_IMPERFECT_GRAPHICS )
|
GAME( 2001, darkhors, jclub2v112, darkhors, darkhors, darkhors_state, init_darkhors, ROT0, "bootleg", "Dark Horse (USA v4.00, bootleg of Jockey Club II)", MACHINE_IMPERFECT_GRAPHICS )
|
||||||
|
@ -73,7 +73,7 @@ Dumped 06/15/2000
|
|||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "cpu/m68000/m68000.h"
|
#include "cpu/m68000/m68000.h"
|
||||||
#include "video/bufsprite.h"
|
#include "video/bufsprite.h"
|
||||||
#include "sound/nile.h"
|
#include "sound/setapcm.h"
|
||||||
#include "emupal.h"
|
#include "emupal.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
@ -568,8 +568,8 @@ void srmp6_state::srmp6_map(address_map &map)
|
|||||||
|
|
||||||
map(0x4c0000, 0x4c006f).rw(FUNC(srmp6_state::video_regs_r), FUNC(srmp6_state::video_regs_w)).share(m_video_regs); // ? gfx regs ST-0026 NiLe
|
map(0x4c0000, 0x4c006f).rw(FUNC(srmp6_state::video_regs_r), FUNC(srmp6_state::video_regs_w)).share(m_video_regs); // ? gfx regs ST-0026 NiLe
|
||||||
map(0x4d0000, 0x4d0001).r(FUNC(srmp6_state::irq_ack_r));
|
map(0x4d0000, 0x4d0001).r(FUNC(srmp6_state::irq_ack_r));
|
||||||
map(0x4e0000, 0x4e00ff).rw("nile", FUNC(nile_device::nile_snd_r), FUNC(nile_device::nile_snd_w));
|
map(0x4e0000, 0x4e00ff).rw("nile", FUNC(nile_sound_device::snd_r), FUNC(nile_sound_device::snd_w));
|
||||||
map(0x4e0100, 0x4e0101).rw("nile", FUNC(nile_device::nile_sndctrl_r), FUNC(nile_device::nile_sndctrl_w));
|
map(0x4e0100, 0x4e0101).rw("nile", FUNC(nile_sound_device::key_r), FUNC(nile_sound_device::key_w));
|
||||||
//map(0x4e0110, 0x4e0111).noprw(); // ? accessed once ($268dc, written $b.w)
|
//map(0x4e0110, 0x4e0111).noprw(); // ? accessed once ($268dc, written $b.w)
|
||||||
|
|
||||||
// CHR RAM: checked [$500000-$5fffff]
|
// CHR RAM: checked [$500000-$5fffff]
|
||||||
@ -704,7 +704,8 @@ void srmp6_state::srmp6(machine_config &config)
|
|||||||
SPEAKER(config, "lspeaker").front_left();
|
SPEAKER(config, "lspeaker").front_left();
|
||||||
SPEAKER(config, "rspeaker").front_right();
|
SPEAKER(config, "rspeaker").front_right();
|
||||||
|
|
||||||
nile_device &nile(NILE(config, "nile", 0));
|
// matches video, needs to verified; playback rate: (42.9545Mhz / 7) / 160 or (42.9545Mhz / 5) / 224 or (42.9545Mhz / 4) / 280?
|
||||||
|
nile_sound_device &nile(NILE_SOUND(config, "nile", XTAL(42'954'545) / 7));
|
||||||
nile.add_route(0, "lspeaker", 1.0);
|
nile.add_route(0, "lspeaker", 1.0);
|
||||||
nile.add_route(1, "rspeaker", 1.0);
|
nile.add_route(1, "rspeaker", 1.0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user