balsente.cpp: Use ACIA devices for sound communication

This commit is contained in:
AJR 2018-06-14 17:20:16 -04:00
parent 810da767b7
commit 3acfb25aaf
3 changed files with 41 additions and 235 deletions

View File

@ -231,6 +231,7 @@ DIP locations verified for:
#include "cpu/z80/z80.h"
#include "cpu/m6809/m6809.h"
#include "cpu/m68000/m68000.h"
#include "machine/clock.h"
#include "machine/watchdog.h"
#include "sound/cem3394.h"
#include "speaker.h"
@ -265,7 +266,7 @@ void balsente_state::cpu1_base_map(address_map &map)
map(0x9902, 0x9902).portr("IN0");
map(0x9903, 0x9903).portr("IN1").nopw();
map(0x9a00, 0x9a03).r(FUNC(balsente_state::random_num_r));
map(0x9a04, 0x9a05).rw(FUNC(balsente_state::m6850_r), FUNC(balsente_state::m6850_w));
map(0x9a04, 0x9a05).rw("acia", FUNC(acia6850_device::read), FUNC(acia6850_device::write));
map(0xa000, 0xbfff).bankr("bank1");
map(0xc000, 0xffff).bankr("bank2");
}
@ -295,8 +296,8 @@ void balsente_state::cpu2_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x2000, 0x5fff).ram();
map(0x6000, 0x7fff).w(FUNC(balsente_state::m6850_sound_w));
map(0xe000, 0xffff).r(FUNC(balsente_state::m6850_sound_r));
map(0x6000, 0x6001).mirror(0x1ffe).w("audiouart", FUNC(acia6850_device::write));
map(0xe000, 0xe001).mirror(0x1ffe).r("audiouart", FUNC(acia6850_device::read));
}
@ -1314,7 +1315,20 @@ MACHINE_CONFIG_START(balsente_state::balsente)
MCFG_DEVICE_PROGRAM_MAP(cpu2_map)
MCFG_DEVICE_IO_MAP(cpu2_io_map)
MCFG_QUANTUM_TIME(attotime::from_hz(600))
MCFG_DEVICE_ADD("acia", ACIA6850, 0)
MCFG_ACIA6850_TXD_HANDLER(WRITELINE("audiouart", acia6850_device, write_rxd))
MCFG_ACIA6850_IRQ_HANDLER(INPUTLINE("maincpu", M6809_FIRQ_LINE))
MCFG_DEVICE_ADD("audiouart", ACIA6850, 0)
MCFG_ACIA6850_TXD_HANDLER(WRITELINE("acia", acia6850_device, write_rxd))
MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(*this, balsente_state, uint_w))
MCFG_DEVICE_ADD("uartclock", CLOCK, 8_MHz_XTAL / 16) // 500 kHz
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(*this, balsente_state, uint_propagate_w))
MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("audiouart", acia6850_device, write_txc))
MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("audiouart", acia6850_device, write_rxc))
MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("acia", acia6850_device, write_txc)) MCFG_DEVCB_INVERT
MCFG_DEVCB_CHAIN_OUTPUT(WRITELINE("acia", acia6850_device, write_rxc)) MCFG_DEVCB_INVERT
MCFG_X2212_ADD_AUTOSAVE("nov0") // system NOVRAM
MCFG_X2212_ADD_AUTOSAVE("nov1") // cart NOVRAM

View File

@ -8,6 +8,7 @@
***************************************************************************/
#include "machine/6850acia.h"
#include "machine/pit8253.h"
#include "machine/timer.h"
#include "machine/x2212.h"
@ -54,6 +55,8 @@ public:
, m_palette(*this, "palette")
, m_outlatch(*this, "outlatch")
, m_novram(*this, "nov%u", 0U)
, m_acia(*this, "acia")
, m_audiouart(*this, "audiouart")
, m_generic_paletteram_8(*this, "paletteram")
{ }
@ -101,10 +104,8 @@ private:
DECLARE_WRITE_LINE_MEMBER(nvrecall_w);
DECLARE_READ8_MEMBER(novram_8bit_r);
DECLARE_WRITE8_MEMBER(novram_8bit_w);
DECLARE_READ8_MEMBER(m6850_r);
DECLARE_WRITE8_MEMBER(m6850_w);
DECLARE_READ8_MEMBER(m6850_sound_r);
DECLARE_WRITE8_MEMBER(m6850_sound_w);
DECLARE_WRITE_LINE_MEMBER(uint_w);
DECLARE_WRITE_LINE_MEMBER(uint_propagate_w);
DECLARE_READ8_MEMBER(adc_data_r);
DECLARE_WRITE8_MEMBER(adc_select_w);
DECLARE_READ8_MEMBER(counter_state_r);
@ -135,14 +136,11 @@ private:
uint32_t screen_update_balsente(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(update_analog_inputs);
TIMER_CALLBACK_MEMBER(irq_off);
TIMER_CALLBACK_MEMBER(m6850_data_ready_callback);
TIMER_CALLBACK_MEMBER(m6850_w_callback);
TIMER_CALLBACK_MEMBER(adc_finished);
TIMER_DEVICE_CALLBACK_MEMBER(interrupt_timer);
TIMER_DEVICE_CALLBACK_MEMBER(clock_counter_0_ff);
void draw_one_sprite(bitmap_ind16 &bitmap, const rectangle &cliprect, uint8_t *sprite);
void poly17_init();
void m6850_update_io();
DECLARE_WRITE_LINE_MEMBER(set_counter_0_ff);
void update_grudge_steering();
void expand_roms(uint8_t cd_rom_mask);
@ -191,18 +189,8 @@ private:
uint8_t m_dac_register;
uint8_t m_chip_select;
/* main CPU 6850 states */
uint8_t m_m6850_status;
uint8_t m_m6850_control;
uint8_t m_m6850_input;
uint8_t m_m6850_output;
uint8_t m_m6850_data_ready;
/* sound CPU 6850 states */
uint8_t m_m6850_sound_status;
uint8_t m_m6850_sound_control;
uint8_t m_m6850_sound_input;
uint8_t m_m6850_sound_output;
bool m_uint;
/* noise generator states */
uint32_t m_noise_position[6];
@ -236,6 +224,8 @@ private:
required_device<palette_device> m_palette;
required_device<ls259_device> m_outlatch;
required_device_array<x2212_device, 2> m_novram;
required_device<acia6850_device> m_acia;
required_device<acia6850_device> m_audiouart;
required_shared_ptr<uint8_t> m_generic_paletteram_8;
};

View File

@ -72,6 +72,11 @@ void balsente_state::machine_start()
/* create the polynomial tables */
poly17_init();
m_acia->write_cts(0);
m_acia->write_dcd(0);
m_audiouart->write_cts(0);
m_audiouart->write_dcd(0);
save_item(NAME(m_counter_control));
save_item(NAME(m_counter_0_ff));
save_item(NAME(m_counter_0_out));
@ -84,16 +89,7 @@ void balsente_state::machine_start()
save_item(NAME(m_dac_register));
save_item(NAME(m_chip_select));
save_item(NAME(m_m6850_status));
save_item(NAME(m_m6850_control));
save_item(NAME(m_m6850_input));
save_item(NAME(m_m6850_output));
save_item(NAME(m_m6850_data_ready));
save_item(NAME(m_m6850_sound_status));
save_item(NAME(m_m6850_sound_control));
save_item(NAME(m_m6850_sound_input));
save_item(NAME(m_m6850_sound_output));
save_item(NAME(m_uint));
save_item(NAME(m_noise_position));
@ -108,7 +104,6 @@ void balsente_state::machine_start()
void balsente_state::machine_reset()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
int numbanks;
/* reset the manual counter 0 clock */
@ -116,6 +111,7 @@ void balsente_state::machine_reset()
m_counter_0_ff = false;
m_counter_0_out = false;
m_counter_0_timer_active = false;
m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
/* reset the ADC states */
m_adc_value = 0;
@ -128,10 +124,6 @@ void balsente_state::machine_reset()
/* reset game-specific states */
m_grudge_steering_result = 0;
/* reset the 6850 chips */
m6850_w(space, 0, 3);
m6850_sound_w(space, 0, 3);
/* reset the noise generator */
memset(m_noise_position, 0, sizeof(m_noise_position));
@ -335,206 +327,15 @@ WRITE8_MEMBER(balsente_state::novram_8bit_w)
*
*************************************/
void balsente_state::m6850_update_io()
WRITE_LINE_MEMBER(balsente_state::uint_w)
{
uint8_t new_state;
/* sound -> main CPU communications */
if (!(m_m6850_sound_status & 0x02))
{
/* set the overrun bit if the data in the destination hasn't been read yet */
if (m_m6850_status & 0x01)
m_m6850_status |= 0x20;
/* copy the sound's output to our input */
m_m6850_input = m_m6850_sound_output;
/* set the receive register full bit */
m_m6850_status |= 0x01;
/* set the sound's trasmitter register empty bit */
m_m6850_sound_status |= 0x02;
}
/* main -> sound CPU communications */
if (m_m6850_data_ready)
{
/* set the overrun bit if the data in the destination hasn't been read yet */
if (m_m6850_sound_status & 0x01)
m_m6850_sound_status |= 0x20;
/* copy the main CPU's output to our input */
m_m6850_sound_input = m_m6850_output;
/* set the receive register full bit */
m_m6850_sound_status |= 0x01;
/* set the main CPU's trasmitter register empty bit */
m_m6850_status |= 0x02;
m_m6850_data_ready = 0;
}
/* check for reset states */
if ((m_m6850_control & 3) == 3)
{
m_m6850_status = 0x02;
m_m6850_data_ready = 0;
}
if ((m_m6850_sound_control & 3) == 3)
m_m6850_sound_status = 0x02;
/* check for transmit/receive IRQs on the main CPU */
new_state = 0;
if ((m_m6850_control & 0x80) && (m_m6850_status & 0x21)) new_state = 1;
if ((m_m6850_control & 0x60) == 0x20 && (m_m6850_status & 0x02)) new_state = 1;
/* apply the change */
if (new_state && !(m_m6850_status & 0x80))
{
m_maincpu->set_input_line(M6809_FIRQ_LINE, ASSERT_LINE);
m_m6850_status |= 0x80;
}
else if (!new_state && (m_m6850_status & 0x80))
{
m_maincpu->set_input_line(M6809_FIRQ_LINE, CLEAR_LINE);
m_m6850_status &= ~0x80;
}
/* check for transmit/receive IRQs on the sound CPU */
new_state = 0;
if ((m_m6850_sound_control & 0x80) && (m_m6850_sound_status & 0x21)) new_state = 1;
if ((m_m6850_sound_control & 0x60) == 0x20 && (m_m6850_sound_status & 0x02)) new_state = 1;
if (!(m_counter_control & 0x20)) new_state = 0;
/* apply the change */
if (new_state && !(m_m6850_sound_status & 0x80))
{
m_audiocpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
m_m6850_sound_status |= 0x80;
}
else if (!new_state && (m_m6850_sound_status & 0x80))
{
m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
m_m6850_sound_status &= ~0x80;
}
m_uint = bool(state);
}
/*************************************
*
* 6850 UART (main CPU)
*
*************************************/
READ8_MEMBER(balsente_state::m6850_r)
WRITE_LINE_MEMBER(balsente_state::uint_propagate_w)
{
int result;
/* status register is at offset 0 */
if (offset == 0)
{
result = m_m6850_status;
}
/* input register is at offset 1 */
else
{
result = m_m6850_input;
/* clear the overrun and receive buffer full bits */
m_m6850_status &= ~0x21;
m6850_update_io();
}
return result;
}
TIMER_CALLBACK_MEMBER(balsente_state::m6850_data_ready_callback)
{
/* set the output data byte and indicate that we're ready to go */
m_m6850_output = param;
m_m6850_data_ready = 1;
m6850_update_io();
}
TIMER_CALLBACK_MEMBER(balsente_state::m6850_w_callback)
{
/* indicate that the transmit buffer is no longer empty and update the I/O state */
m_m6850_status &= ~0x02;
m6850_update_io();
/* set a timer for 500usec later to actually transmit the data */
/* (this is very important for several games, esp Snacks'n Jaxson) */
machine().scheduler().timer_set(attotime::from_usec(500), timer_expired_delegate(FUNC(balsente_state::m6850_data_ready_callback),this), param);
}
WRITE8_MEMBER(balsente_state::m6850_w)
{
/* control register is at offset 0 */
if (offset == 0)
{
m_m6850_control = data;
/* re-update since interrupt enables could have been modified */
m6850_update_io();
}
/* output register is at offset 1; set a timer to synchronize the CPUs */
else
machine().scheduler().synchronize(timer_expired_delegate(FUNC(balsente_state::m6850_w_callback),this), data);
}
/*************************************
*
* 6850 UART (sound CPU)
*
*************************************/
READ8_MEMBER(balsente_state::m6850_sound_r)
{
int result;
/* status register is at offset 0 */
if (offset == 0)
{
result = m_m6850_sound_status;
}
/* input register is at offset 1 */
else
{
result = m_m6850_sound_input;
/* clear the overrun and receive buffer full bits */
m_m6850_sound_status &= ~0x21;
m6850_update_io();
}
return result;
}
WRITE8_MEMBER(balsente_state::m6850_sound_w)
{
/* control register is at offset 0 */
if (offset == 0)
m_m6850_sound_control = data;
/* output register is at offset 1 */
else
{
m_m6850_sound_output = data;
m_m6850_sound_status &= ~0x02;
}
/* re-update since interrupt enables could have been modified */
m6850_update_io();
if (state && BIT(m_counter_control, 5))
m_audiocpu->set_input_line(INPUT_LINE_NMI, m_uint ? ASSERT_LINE : CLEAR_LINE);
}
@ -764,8 +565,9 @@ WRITE8_MEMBER(balsente_state::counter_control_w)
else if (!BIT(data, 2))
set_counter_0_ff(1);
/* bit 5 clears the NMI interrupt; recompute the I/O state now */
m6850_update_io();
/* bit 5 clears the NMI interrupt */
if (BIT(diff_counter_control, 5) && !BIT(data, 5))
m_audiocpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
}