// license:BSD-3-Clause // copyright-holders:Mathis Rosenhauer /************************************************************************* Exidy Vertigo hardware *************************************************************************/ #include "emu.h" #include "includes/vertigo.h" /************************************* * * IRQ handling. The priority encoder * has to be emulated. Otherwise * interrupts are lost. * *************************************/ void vertigo_state::update_irq(uint8_t data) { if (m_irq_state < 7) m_maincpu->set_input_line(m_irq_state ^ 7, CLEAR_LINE); m_irq_state = data; if (m_irq_state < 7) m_maincpu->set_input_line(m_irq_state ^ 7, ASSERT_LINE); } void vertigo_state::update_irq_encoder(int line, int state) { m_ttl74148->input_line_w(line, !state); m_ttl74148->update(); } WRITE_LINE_MEMBER(vertigo_state::v_irq4_w) { update_irq_encoder(INPUT_LINE_IRQ4, state); vertigo_vproc(m_maincpu->attotime_to_cycles(machine().time() - m_irq4_time), state); m_irq4_time = machine().time(); } WRITE_LINE_MEMBER(vertigo_state::v_irq3_w) { m_custom->sound_interrupt_w(state); update_irq_encoder(INPUT_LINE_IRQ3, state); } /************************************* * * ADC (ADC0808) and coin handlers * *************************************/ WRITE_LINE_MEMBER( vertigo_state::adc_eoc_w ) { update_irq_encoder(INPUT_LINE_IRQ2, state ? ASSERT_LINE : CLEAR_LINE); } uint16_t vertigo_state::vertigo_io_convert(offs_t offset) { m_adc->address_offset_start_w(offset, 0); return 0; } uint16_t vertigo_state::vertigo_coin_r() { update_irq_encoder(INPUT_LINE_IRQ6, CLEAR_LINE); return (ioport("COIN")->read()); } INTERRUPT_GEN_MEMBER(vertigo_state::vertigo_interrupt) { /* Coin inputs cause IRQ6 */ if ((ioport("COIN")->read() & 0x7) < 0x7) update_irq_encoder(INPUT_LINE_IRQ6, ASSERT_LINE); } /************************************* * * Sound board interface * *************************************/ void vertigo_state::vertigo_wsot_w(uint16_t data) { /* Reset sound cpu */ if ((data & 2) == 0) m_custom->sound_reset_w(ASSERT_LINE); else m_custom->sound_reset_w(CLEAR_LINE); } TIMER_CALLBACK_MEMBER(vertigo_state::sound_command_w) { m_custom->exidy440_sound_command(param); /* It is important that the sound cpu ACKs the sound command quickly. Otherwise the main CPU gives up with sound. Boosting the interleave for a while helps. */ machine().scheduler().boost_interleave(attotime::zero, attotime::from_usec(100)); } void vertigo_state::vertigo_audio_w(offs_t offset, uint16_t data, uint16_t mem_mask) { if (ACCESSING_BITS_0_7) machine().scheduler().synchronize(timer_expired_delegate(FUNC(vertigo_state::sound_command_w),this), data & 0xff); } uint16_t vertigo_state::vertigo_sio_r() { return m_custom->exidy440_sound_command_ack() ? 0xfc : 0xfd; } /************************************* * * Machine initialization * *************************************/ void vertigo_state::machine_start() { save_item(NAME(m_irq_state)); save_item(NAME(m_irq4_time)); vertigo_vproc_init(); } void vertigo_state::machine_reset() { int i; m_ttl74148->enable_input_w(0); for (i = 0; i < 8; i++) m_ttl74148->input_line_w(i, 1); m_ttl74148->update(); vertigo_vproc_reset(); m_irq4_time = machine().time(); m_irq_state = 7; } /************************************* * * Motor controller interface * *************************************/ void vertigo_state::vertigo_motor_w(uint16_t data) { /* Motor controller interface. Not emulated. */ }