mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
simpsons, k053260: Fix the pan, fix the interrupts, fix the general volume [O. Galibert, P. Bennett]
This commit is contained in:
parent
a97d097b3b
commit
8720db13ca
@ -59,12 +59,28 @@
|
||||
|
||||
#define LOG 0
|
||||
|
||||
static constexpr int CLOCKS_PER_SAMPLE = 32;
|
||||
static constexpr int CLOCKS_PER_SAMPLE = 64;
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(K053260, k053260_device, "k053260", "K053260 KDSC")
|
||||
;
|
||||
|
||||
|
||||
// Pan multipliers. Set according to integer angles in degrees, amusingly.
|
||||
// Exact precision hard to know, the floating point-ish output format makes
|
||||
// comparisons iffy. So we used a 1.16 format.
|
||||
const int k053260_device::pan_mul[8][2] = {
|
||||
{ 0, 0 }, // No sound for pan 0
|
||||
{ 65536, 0 }, // 0 degrees
|
||||
{ 59870, 26656 }, // 24 degrees
|
||||
{ 53684, 37950 }, // 35 degrees
|
||||
{ 46341, 46341 }, // 45 degrees
|
||||
{ 37950, 53684 }, // 55 degrees
|
||||
{ 26656, 59870 }, // 66 degrees
|
||||
{ 0, 65536 } // 90 degrees
|
||||
};
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -79,7 +95,10 @@ k053260_device::k053260_device(const machine_config &mconfig, const char *tag, d
|
||||
: device_t(mconfig, K053260, tag, owner, clock)
|
||||
, device_sound_interface(mconfig, *this)
|
||||
, device_rom_interface(mconfig, *this, 21)
|
||||
, m_sh1_cb(*this)
|
||||
, m_sh2_cb(*this)
|
||||
, m_stream(nullptr)
|
||||
, m_timer(nullptr)
|
||||
, m_keyon(0)
|
||||
, m_mode(0)
|
||||
, m_voice{ { *this }, { *this }, { *this }, { *this } }
|
||||
@ -94,15 +113,21 @@ k053260_device::k053260_device(const machine_config &mconfig, const char *tag, d
|
||||
|
||||
void k053260_device::device_start()
|
||||
{
|
||||
m_sh1_cb.resolve_safe();
|
||||
m_sh2_cb.resolve_safe();
|
||||
|
||||
m_stream = stream_alloc( 0, 2, clock() / CLOCKS_PER_SAMPLE );
|
||||
|
||||
/* register with the save state system */
|
||||
save_item(NAME(m_portdata));
|
||||
save_item(NAME(m_keyon));
|
||||
save_item(NAME(m_mode));
|
||||
save_item(NAME(m_timer_state));
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_voice[i].voice_start(i);
|
||||
|
||||
m_timer = timer_alloc(0);
|
||||
}
|
||||
|
||||
|
||||
@ -113,6 +138,7 @@ void k053260_device::device_start()
|
||||
void k053260_device::device_clock_changed()
|
||||
{
|
||||
m_stream->set_sample_rate(clock() / CLOCKS_PER_SAMPLE);
|
||||
m_timer->adjust(attotime::from_ticks(16, clock()), 0, attotime::from_ticks(16, clock()));
|
||||
}
|
||||
|
||||
|
||||
@ -122,6 +148,8 @@ void k053260_device::device_clock_changed()
|
||||
|
||||
void k053260_device::device_reset()
|
||||
{
|
||||
m_timer->adjust(attotime::from_ticks(16, clock()), 0, attotime::from_ticks(16, clock()));
|
||||
|
||||
for (auto & elem : m_voice)
|
||||
elem.voice_reset();
|
||||
}
|
||||
@ -137,6 +165,17 @@ void k053260_device::rom_bank_updated()
|
||||
}
|
||||
|
||||
|
||||
void k053260_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch(m_timer_state) {
|
||||
case 0: m_sh1_cb(ASSERT_LINE); break;
|
||||
case 1: m_sh1_cb(CLEAR_LINE); break;
|
||||
case 2: m_sh2_cb(ASSERT_LINE); break;
|
||||
case 3: m_sh2_cb(CLEAR_LINE); break;
|
||||
}
|
||||
m_timer_state = (m_timer_state+1) & 3;
|
||||
}
|
||||
|
||||
u8 k053260_device::main_read(offs_t offset)
|
||||
{
|
||||
// sub-to-main ports
|
||||
@ -289,8 +328,8 @@ void k053260_device::sound_stream_update(sound_stream &stream, stream_sample_t *
|
||||
voice.play(buffer);
|
||||
}
|
||||
|
||||
outputs[0][j] = limit( buffer[0] >> 1, MAXOUT, MINOUT );
|
||||
outputs[1][j] = limit( buffer[1] >> 1, MAXOUT, MINOUT );
|
||||
outputs[0][j] = limit( buffer[0], MAXOUT, MINOUT );
|
||||
outputs[1][j] = limit( buffer[1], MAXOUT, MINOUT );
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -384,8 +423,8 @@ void k053260_device::KDSC_Voice::set_pan(u8 data)
|
||||
|
||||
void k053260_device::KDSC_Voice::update_pan_volume()
|
||||
{
|
||||
m_pan_volume[0] = m_volume * (8 - m_pan);
|
||||
m_pan_volume[1] = m_volume * m_pan;
|
||||
m_pan_volume[0] = m_volume * pan_mul[m_pan][0];
|
||||
m_pan_volume[1] = m_volume * pan_mul[m_pan][1];
|
||||
}
|
||||
|
||||
void k053260_device::KDSC_Voice::key_on()
|
||||
@ -394,8 +433,8 @@ void k053260_device::KDSC_Voice::key_on()
|
||||
m_counter = 0x1000 - CLOCKS_PER_SAMPLE; // force update on next sound_stream_update
|
||||
m_output = 0;
|
||||
m_playing = true;
|
||||
if (LOG) m_device.logerror("K053260: start = %06x, length = %06x, pitch = %04x, vol = %02x, loop = %s, %s\n",
|
||||
m_start, m_length, m_pitch, m_volume, m_loop ? "yes" : "no", m_kadpcm ? "KADPCM" : "PCM" );
|
||||
if (LOG) m_device.logerror("K053260: start = %06x, length = %06x, pitch = %04x, vol = %02x:%x, loop = %s, %s\n",
|
||||
m_start, m_length, m_pitch, m_volume, m_pan, m_loop ? "yes" : "no", m_kadpcm ? "KADPCM" : "PCM" );
|
||||
}
|
||||
|
||||
void k053260_device::KDSC_Voice::key_off()
|
||||
@ -451,8 +490,8 @@ void k053260_device::KDSC_Voice::play(stream_sample_t *outputs)
|
||||
}
|
||||
}
|
||||
|
||||
outputs[0] += m_output * m_pan_volume[0];
|
||||
outputs[1] += m_output * m_pan_volume[1];
|
||||
outputs[0] += (m_output * m_pan_volume[0]) >> 15;
|
||||
outputs[1] += (m_output * m_pan_volume[1]) >> 15;
|
||||
}
|
||||
|
||||
u8 k053260_device::KDSC_Voice::read_rom()
|
||||
|
@ -29,11 +29,15 @@ public:
|
||||
u8 read(offs_t offset);
|
||||
void write(offs_t offset, u8 data);
|
||||
|
||||
auto sh1_cb() { return m_sh1_cb.bind(); }
|
||||
auto sh2_cb() { return m_sh2_cb.bind(); }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_clock_changed() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
// sound stream update overrides
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
@ -42,13 +46,22 @@ protected:
|
||||
virtual void rom_bank_updated() override;
|
||||
|
||||
private:
|
||||
// Pan multipliers
|
||||
static const int pan_mul[8][2];
|
||||
|
||||
// Sample hold lines callbacks (often used for interrupts)
|
||||
devcb_write_line m_sh1_cb;
|
||||
devcb_write_line m_sh2_cb;
|
||||
|
||||
// configuration
|
||||
sound_stream * m_stream;
|
||||
emu_timer *m_timer;
|
||||
|
||||
// live state
|
||||
u8 m_portdata[4];
|
||||
u8 m_keyon;
|
||||
u8 m_mode;
|
||||
int m_timer_state;
|
||||
|
||||
// per voice state
|
||||
class KDSC_Voice
|
||||
@ -74,7 +87,7 @@ private:
|
||||
|
||||
// live state
|
||||
u32 m_position = 0;
|
||||
u16 m_pan_volume[2];
|
||||
int m_pan_volume[2];
|
||||
u16 m_counter = 0;
|
||||
s8 m_output = 0;
|
||||
bool m_playing = false;
|
||||
|
@ -157,22 +157,11 @@ WRITE8_MEMBER(simpsons_state::z80_bankswitch_w)
|
||||
membank("bank2")->set_entry(data & 7);
|
||||
}
|
||||
|
||||
#if 0
|
||||
void simpsons_state::sound_nmi_callback( int param )
|
||||
{
|
||||
m_audiocpu->set_input_line(INPUT_LINE_NMI, (m_nmi_enabled) ? CLEAR_LINE : ASSERT_LINE );
|
||||
m_nmi_enabled = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void simpsons_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_NMI:
|
||||
m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
break;
|
||||
case TIMER_DMASTART:
|
||||
if (m_firq_enabled)
|
||||
m_maincpu->set_input_line(KONAMI_FIRQ_LINE, ASSERT_LINE);
|
||||
@ -189,7 +178,17 @@ void simpsons_state::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
WRITE8_MEMBER(simpsons_state::z80_arm_nmi_w)
|
||||
{
|
||||
m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
timer_set(attotime::from_usec(25), TIMER_NMI); /* kludge until the K053260 is emulated correctly */
|
||||
m_nmi_enabled = machine().time().as_ticks(m_audiocpu->clock());
|
||||
}
|
||||
|
||||
void simpsons_state::z80_nmi_w(int state)
|
||||
{
|
||||
if(state && m_nmi_enabled && machine().time().as_ticks(m_audiocpu->clock()) > m_nmi_enabled + 1) {
|
||||
m_nmi_enabled = 0;
|
||||
m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
|
||||
} else
|
||||
m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
}
|
||||
|
||||
void simpsons_state::z80_map(address_map &map)
|
||||
@ -338,9 +337,6 @@ void simpsons_state::simpsons(machine_config &config)
|
||||
EEPROM_ER5911_8BIT(config, "eeprom");
|
||||
|
||||
WATCHDOG_TIMER(config, "watchdog");
|
||||
//So, the horizontal timing of simpsons is 16/32/16/320
|
||||
//6MHz dot clock
|
||||
//Vertical is 16/8/16/224
|
||||
|
||||
/* video hardware */
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
|
||||
@ -382,8 +378,9 @@ void simpsons_state::simpsons(machine_config &config)
|
||||
ymsnd.add_route(1, "rspeaker", 0.0);
|
||||
|
||||
k053260_device &k053260(K053260(config, "k053260", XTAL(3'579'545))); /* verified on pcb */
|
||||
k053260.add_route(0, "lspeaker", 0.75);
|
||||
k053260.add_route(1, "rspeaker", 0.75);
|
||||
k053260.add_route(0, "lspeaker", 1.00);
|
||||
k053260.add_route(1, "rspeaker", 1.00);
|
||||
k053260.sh2_cb().set(FUNC(simpsons_state::z80_nmi_w));
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
private:
|
||||
enum
|
||||
{
|
||||
TIMER_NMI,
|
||||
TIMER_DMASTART,
|
||||
TIMER_DMAEND
|
||||
};
|
||||
@ -46,7 +45,7 @@ private:
|
||||
|
||||
/* misc */
|
||||
int m_firq_enabled;
|
||||
//int m_nmi_enabled;
|
||||
u64 m_nmi_enabled;
|
||||
|
||||
/* devices */
|
||||
required_device<konami_cpu_device> m_maincpu;
|
||||
@ -71,6 +70,7 @@ private:
|
||||
INTERRUPT_GEN_MEMBER(simpsons_irq);
|
||||
void simpsons_video_banking(int bank);
|
||||
void simpsons_objdma();
|
||||
void z80_nmi_w(int state);
|
||||
K052109_CB_MEMBER(tile_callback);
|
||||
DECLARE_WRITE8_MEMBER(banking_callback);
|
||||
K053246_CB_MEMBER(sprite_callback);
|
||||
|
@ -73,6 +73,7 @@ void simpsons_state::machine_start()
|
||||
membank("bank2")->configure_entries(2, 6, memregion("audiocpu")->base() + 0x10000, 0x4000);
|
||||
|
||||
save_item(NAME(m_firq_enabled));
|
||||
save_item(NAME(m_nmi_enabled));
|
||||
save_item(NAME(m_sprite_colorbase));
|
||||
save_item(NAME(m_layer_colorbase));
|
||||
save_item(NAME(m_layerpri));
|
||||
@ -89,6 +90,7 @@ void simpsons_state::machine_reset()
|
||||
|
||||
m_sprite_colorbase = 0;
|
||||
m_firq_enabled = 0;
|
||||
m_nmi_enabled = 0;
|
||||
|
||||
/* init the default banks */
|
||||
membank("bank1")->set_entry(0);
|
||||
|
Loading…
Reference in New Issue
Block a user