mirror of
https://github.com/holub/mame
synced 2025-04-25 09:50:04 +03:00
balsente.cpp: Use ACIA devices for sound communication
This commit is contained in:
parent
810da767b7
commit
3acfb25aaf
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user