From f0bceea10504e1b160305098157372e856c65120 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 11 Dec 2016 14:38:36 -0500 Subject: [PATCH 1/2] equites.cpp: Use 8155 device (nw) --- src/mame/drivers/equites.cpp | 84 +++++++++++++++--------------------- src/mame/includes/equites.h | 6 +-- 2 files changed, 38 insertions(+), 52 deletions(-) diff --git a/src/mame/drivers/equites.cpp b/src/mame/drivers/equites.cpp index cacf60c5d19..4c108332c09 100644 --- a/src/mame/drivers/equites.cpp +++ b/src/mame/drivers/equites.cpp @@ -169,8 +169,6 @@ TODO: - bassline imperfect. This is just the square wave output of the 5232 at the moment. It should go through analog stages. -- properly emulate the 8155 on the sound board. - - implement low-pass filters on the DAC output - the purpose of the sound PROM is unclear. From the schematics, it seems it @@ -365,6 +363,7 @@ D #include "cpu/alph8201/alph8201.h" #include "cpu/i8085/i8085.h" #include "cpu/m68000/m68000.h" +#include "machine/i8155.h" #include "machine/nvram.h" #include "machine/watchdog.h" #include "sound/ay8910.h" @@ -385,9 +384,10 @@ D /******************************************************************************/ // Sound -TIMER_CALLBACK_MEMBER(equites_state::equites_nmi_callback) +WRITE_LINE_MEMBER(equites_state::equites_8155_timer_pulse) { - m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); + if (!state) // active low + m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); } TIMER_CALLBACK_MEMBER(equites_state::equites_frq_adjuster_callback) @@ -518,12 +518,35 @@ WRITE8_MEMBER(equites_state::equites_dac_latch_w) equites_update_dac(); } +WRITE8_MEMBER(equites_state::equites_8155_porta_w) +{ + m_eq8155_port_a = data; + m_msm->set_output_gain(0, (data >> 4) / 15.0); /* group1 from msm5232 */ + m_msm->set_output_gain(1, (data >> 4) / 15.0); /* group1 from msm5232 */ + m_msm->set_output_gain(2, (data >> 4) / 15.0); /* group1 from msm5232 */ + m_msm->set_output_gain(3, (data >> 4) / 15.0); /* group1 from msm5232 */ + m_msm->set_output_gain(4, (data & 0x0f) / 15.0); /* group2 from msm5232 */ + m_msm->set_output_gain(5, (data & 0x0f) / 15.0); /* group2 from msm5232 */ + m_msm->set_output_gain(6, (data & 0x0f) / 15.0); /* group2 from msm5232 */ + m_msm->set_output_gain(7, (data & 0x0f) / 15.0); /* group2 from msm5232 */ +} + WRITE8_MEMBER(equites_state::equites_8155_portb_w) { m_eq8155_port_b = data; equites_update_dac(); } +WRITE8_MEMBER(equites_state::equites_8155_portc_w) +{ + m_eq8155_port_c = data; + m_msm->set_output_gain(8, (data & 0x0f) / 15.0); /* SOLO 8' from msm5232 */ + if (data & 0x20) + m_msm->set_output_gain(9, (data & 0x0f) / 15.0); /* SOLO 16' from msm5232 */ + else + m_msm->set_output_gain(9, 0); /* SOLO 16' from msm5232 */ +} + WRITE_LINE_MEMBER(equites_state::equites_msm5232_gate) { } @@ -555,47 +578,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(equites_state::splndrbt_scanline) m_maincpu->set_input_line(2, HOLD_LINE); } -WRITE8_MEMBER(equites_state::equites_8155_w) -{ - // FIXME proper 8155 emulation must be implemented - switch( offset ) - { - case 0: //logerror( "8155 Command register write %x, timer command = %x, interrupt enable = %x, ports = %x\n", data, (data >> 6) & 3, (data >> 4) & 3, data & 0xf ); - if (((data >> 6) & 3) == 3) - m_nmi_timer->adjust(attotime::from_hz(XTAL_6_144MHz/2 / m_timer_count), 0, attotime::from_hz(XTAL_6_144MHz/2 / m_timer_count)); - break; - case 1: //logerror( "8155 I/O Port A write %x\n", data ); - m_eq8155_port_a = data; - m_msm->set_output_gain(0, (data >> 4) / 15.0); /* group1 from msm5232 */ - m_msm->set_output_gain(1, (data >> 4) / 15.0); /* group1 from msm5232 */ - m_msm->set_output_gain(2, (data >> 4) / 15.0); /* group1 from msm5232 */ - m_msm->set_output_gain(3, (data >> 4) / 15.0); /* group1 from msm5232 */ - m_msm->set_output_gain(4, (data & 0x0f) / 15.0); /* group2 from msm5232 */ - m_msm->set_output_gain(5, (data & 0x0f) / 15.0); /* group2 from msm5232 */ - m_msm->set_output_gain(6, (data & 0x0f) / 15.0); /* group2 from msm5232 */ - m_msm->set_output_gain(7, (data & 0x0f) / 15.0); /* group2 from msm5232 */ - break; - case 2: //logerror( "8155 I/O Port B write %x\n", data ); - equites_8155_portb_w(space, 0, data); - break; - case 3: //logerror( "8155 I/O Port C (or control) write %x\n", data ); - m_eq8155_port_c = data; - m_msm->set_output_gain(8, (data & 0x0f) / 15.0); /* SOLO 8' from msm5232 */ - if (data & 0x20) - m_msm->set_output_gain(9, (data & 0x0f) / 15.0); /* SOLO 16' from msm5232 */ - else - m_msm->set_output_gain(9, 0); /* SOLO 16' from msm5232 */ - - break; - case 4: //logerror( "8155 Timer low 8 bits write %x\n", data ); - m_timer_count = (m_timer_count & 0xff00) | data; - break; - case 5: //logerror( "8155 Timer high 6 bits write %x, timer mode %x\n", data & 0x3f, (data >> 6) & 3); - m_timer_count = (m_timer_count & 0x00ff) | ((data & 0x3f) << 8); - break; - } -} - /******************************************************************************/ @@ -717,11 +699,11 @@ static ADDRESS_MAP_START( sound_map, AS_PROGRAM, 8, equites_state ) AM_RANGE(0xc0d0, 0xc0d0) AM_WRITE(equites_dac_latch_w) // followed by 1 (and usually 0) on 8155 port B AM_RANGE(0xc0e0, 0xc0e0) AM_WRITE(equites_dac_latch_w) // followed by 2 (and usually 0) on 8155 port B AM_RANGE(0xc0f8, 0xc0ff) AM_WRITE(equites_c0f8_w) - AM_RANGE(0xe000, 0xe0ff) AM_RAM + AM_RANGE(0xe000, 0xe0ff) AM_DEVREADWRITE("audio8155", i8155_device, memory_r, memory_w) ADDRESS_MAP_END static ADDRESS_MAP_START( sound_portmap, AS_IO, 8, equites_state ) - AM_RANGE(0x00e0, 0x00e5) AM_WRITE(equites_8155_w) + AM_RANGE(0x00e0, 0x00e7) AM_DEVREADWRITE("audio8155", i8155_device, io_r, io_w) ADDRESS_MAP_END @@ -1056,6 +1038,12 @@ static MACHINE_CONFIG_FRAGMENT( common_sound ) MCFG_CPU_PROGRAM_MAP(sound_map) MCFG_CPU_IO_MAP(sound_portmap) + MCFG_DEVICE_ADD("audio8155", I8155, XTAL_6_144MHz/2) + MCFG_I8155_OUT_PORTA_CB(WRITE8(equites_state, equites_8155_porta_w)) + MCFG_I8155_OUT_PORTB_CB(WRITE8(equites_state, equites_8155_portb_w)) + MCFG_I8155_OUT_PORTC_CB(WRITE8(equites_state, equites_8155_portc_w)) + MCFG_I8155_OUT_TIMEROUT_CB(WRITELINE(equites_state, equites_8155_timer_pulse)) + /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("speaker") @@ -1133,8 +1121,6 @@ void equites_state::machine_start() save_item(NAME(m_timer_count)); save_item(NAME(m_gekisou_unknown_bit)); - m_nmi_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(equites_state::equites_nmi_callback), this)); - m_adjuster_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(equites_state::equites_frq_adjuster_callback), this)); m_adjuster_timer->adjust(attotime::from_hz(60), 0, attotime::from_hz(60)); } diff --git a/src/mame/includes/equites.h b/src/mame/includes/equites.h index e30699f0317..5de0b388de1 100644 --- a/src/mame/includes/equites.h +++ b/src/mame/includes/equites.h @@ -60,7 +60,6 @@ public: uint8_t m_ay_port_a; uint8_t m_ay_port_b; uint8_t m_eq_cymbal_ctrl; - emu_timer *m_nmi_timer; emu_timer *m_adjuster_timer; float m_cymvol; float m_hihatvol; @@ -84,8 +83,9 @@ public: DECLARE_WRITE8_MEMBER(equites_c0f8_w); DECLARE_WRITE8_MEMBER(equites_cymbal_ctrl_w); DECLARE_WRITE8_MEMBER(equites_dac_latch_w); + DECLARE_WRITE8_MEMBER(equites_8155_porta_w); DECLARE_WRITE8_MEMBER(equites_8155_portb_w); - DECLARE_WRITE8_MEMBER(equites_8155_w); + DECLARE_WRITE8_MEMBER(equites_8155_portc_w); DECLARE_WRITE16_MEMBER(gekisou_unknown_bit_w); DECLARE_READ16_MEMBER(equites_spriteram_kludge_r); DECLARE_READ8_MEMBER(mcu_ram_r); @@ -117,7 +117,7 @@ public: DECLARE_PALETTE_INIT(splndrbt); uint32_t screen_update_equites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); uint32_t screen_update_splndrbt(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - TIMER_CALLBACK_MEMBER(equites_nmi_callback); + DECLARE_WRITE_LINE_MEMBER(equites_8155_timer_pulse); TIMER_CALLBACK_MEMBER(equites_frq_adjuster_callback); TIMER_DEVICE_CALLBACK_MEMBER(equites_scanline); TIMER_DEVICE_CALLBACK_MEMBER(splndrbt_scanline); From 95d24633de351373e95e656cd631c6dc28ab0289 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 11 Dec 2016 18:19:50 -0500 Subject: [PATCH 2/2] Attempt at fixing 8155 timer behavior so 8085 doesn't lose interrupts in equites --- src/devices/machine/i8155.cpp | 47 ++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/devices/machine/i8155.cpp b/src/devices/machine/i8155.cpp index 74989e51f81..aca33145518 100644 --- a/src/devices/machine/i8155.cpp +++ b/src/devices/machine/i8155.cpp @@ -294,18 +294,9 @@ void i8155_device::device_timer(emu_timer &timer, device_timer_id id, int param, { if (LOG) logerror("8155 Timer Count Reached\n"); - switch (m_command & COMMAND_TM_MASK) - { - case COMMAND_TM_STOP_AFTER_TC: - // stop timer - m_timer->enable(0); - - if (LOG) logerror("8155 Timer Stopped\n"); - break; - } - switch (get_timer_mode()) { + case TIMER_MODE_LOW: case TIMER_MODE_SQUARE_WAVE: // toggle timer output m_to = !m_to; @@ -313,15 +304,8 @@ void i8155_device::device_timer(emu_timer &timer, device_timer_id id, int param, break; case TIMER_MODE_SINGLE_PULSE: - // single pulse upon TC being reached - pulse_timer_output(); - - // clear timer mode setting - m_command &= ~COMMAND_TM_MASK; - break; - case TIMER_MODE_AUTOMATIC_RELOAD: - // automatic reload, i.e. single pulse every time TC is reached + // pulse upon TC being reached pulse_timer_output(); break; } @@ -329,8 +313,28 @@ void i8155_device::device_timer(emu_timer &timer, device_timer_id id, int param, // set timer flag m_status |= STATUS_TIMER; - // reload timer counter - m_counter = m_count_length & 0x3fff; + if ((m_command & COMMAND_TM_MASK) == COMMAND_TM_START) + { + // load new timer counter + m_counter = m_count_length & 0x3fff; + + if (LOG) logerror("8155 Timer New Start\n"); + } + else if ((m_command & COMMAND_TM_MASK) == COMMAND_TM_STOP_AFTER_TC || get_timer_mode() == TIMER_MODE_SINGLE_PULSE) + { + // stop timer + m_timer->enable(0); + + if (LOG) logerror("8155 Timer Stopped\n"); + } + else + { + // automatically reload the counter + m_counter = m_count_length & 0x3fff; + } + + // clear timer command + m_command &= ~COMMAND_TM_MASK; } } @@ -455,6 +459,9 @@ void i8155_device::register_w(int offset, uint8_t data) // load mode and CNT length and start immediately after loading (if timer is not running) m_counter = m_count_length & 0x3fff; m_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); + + // clear timer command so this won't execute twice + m_command &= ~COMMAND_TM_MASK; } break; }