jedi: Moderate driver overhaul

- Split NVRAM between two 4-bit X2212 devices
- Guarantee an invalid checksum when default NVRAM data is used (so that the manufacturer's high scores will be installed)
- Soundlatch modernization
- Use WSQ handler to drive TMS5220
This commit is contained in:
AJR 2018-06-12 10:35:16 -04:00
parent 4c62c8a48f
commit 755f17458b
3 changed files with 68 additions and 128 deletions

View File

@ -16,40 +16,6 @@
/*************************************
*
* Start
*
*************************************/
void jedi_state::sound_start()
{
/* set up save state */
save_item(NAME(m_audio_latch));
save_item(NAME(m_audio_ack_latch));
save_item(NAME(m_speech_strobe_state));
}
/*************************************
*
* Reset
*
*************************************/
void jedi_state::sound_reset()
{
/* init globals */
m_audio_latch = 0;
m_audio_ack_latch = 0;
*m_audio_comm_stat = 0;
*m_speech_data = 0;
m_speech_strobe_state = 0;
}
/*************************************
*
* Interrupt handling
@ -72,53 +38,20 @@ WRITE8_MEMBER(jedi_state::irq_ack_w)
WRITE_LINE_MEMBER(jedi_state::audio_reset_w)
{
m_audiocpu->set_input_line(INPUT_LINE_RESET, state ? CLEAR_LINE : ASSERT_LINE);
if (!state)
m_tms->set_output_gain(ALL_OUTPUTS, 0.0);
}
TIMER_CALLBACK_MEMBER(jedi_state::delayed_audio_latch_w)
READ8_MEMBER(jedi_state::audio_comm_stat_r)
{
m_audio_latch = param;
*m_audio_comm_stat |= 0x80;
}
WRITE8_MEMBER(jedi_state::jedi_audio_latch_w)
{
machine().scheduler().synchronize(timer_expired_delegate(FUNC(jedi_state::delayed_audio_latch_w), this), data);
}
READ8_MEMBER(jedi_state::audio_latch_r)
{
*m_audio_comm_stat &= ~0x80;
return m_audio_latch;
return (m_soundlatch->pending_r() << 7) | (m_sacklatch->pending_r() << 6);
}
CUSTOM_INPUT_MEMBER(jedi_state::jedi_audio_comm_stat_r)
{
return *m_audio_comm_stat >> 6;
}
/*************************************
*
* Sound CPU -> Main CPU communications
*
*************************************/
READ8_MEMBER(jedi_state::jedi_audio_ack_latch_r)
{
*m_audio_comm_stat &= ~0x40;
return m_audio_ack_latch;
}
WRITE8_MEMBER(jedi_state::audio_ack_latch_w)
{
m_audio_ack_latch = data;
*m_audio_comm_stat |= 0x40;
return (m_soundlatch->pending_r() << 1) | m_sacklatch->pending_r();
}
@ -131,13 +64,7 @@ WRITE8_MEMBER(jedi_state::audio_ack_latch_w)
WRITE8_MEMBER(jedi_state::speech_strobe_w)
{
int new_speech_strobe_state = (~offset >> 8) & 1;
if ((new_speech_strobe_state != m_speech_strobe_state) && new_speech_strobe_state)
{
m_tms->data_w(space, 0, *m_speech_data);
}
m_speech_strobe_state = new_speech_strobe_state;
m_tms->wsq_w(BIT(offset, 8));
}
@ -149,7 +76,8 @@ READ8_MEMBER(jedi_state::speech_ready_r)
WRITE8_MEMBER(jedi_state::speech_reset_w)
{
/* not supported by the TMS5220 emulator */
// Flip-flop at 8C controls the power supply to the TMS5220 (through transistors Q6 and Q7)
m_tms->set_output_gain(ALL_OUTPUTS, BIT(data, 0) ? 1.0 : 0.0);
}
@ -168,14 +96,14 @@ void jedi_state::audio_map(address_map &map)
map(0x0820, 0x082f).mirror(0x07c0).rw("pokey3", FUNC(pokey_device::read), FUNC(pokey_device::write));
map(0x0830, 0x083f).mirror(0x07c0).rw("pokey4", FUNC(pokey_device::read), FUNC(pokey_device::write));
map(0x1000, 0x1000).mirror(0x00ff).nopr().w(FUNC(jedi_state::irq_ack_w));
map(0x1100, 0x1100).mirror(0x00ff).nopr().writeonly().share("speech_data");
map(0x1100, 0x1100).mirror(0x00ff).nopr().w("tms", FUNC(tms5220_device::data_w));
map(0x1200, 0x13ff).nopr().w(FUNC(jedi_state::speech_strobe_w));
map(0x1400, 0x1400).mirror(0x00ff).nopr().w(FUNC(jedi_state::audio_ack_latch_w));
map(0x1400, 0x1400).mirror(0x00ff).nopr().w("sacklatch", FUNC(generic_latch_8_device::write));
map(0x1500, 0x1500).mirror(0x00ff).nopr().w(FUNC(jedi_state::speech_reset_w));
map(0x1600, 0x17ff).noprw();
map(0x1800, 0x1800).mirror(0x03ff).r(FUNC(jedi_state::audio_latch_r)).nopw();
map(0x1800, 0x1800).mirror(0x03ff).r("soundlatch", FUNC(generic_latch_8_device::read)).nopw();
map(0x1c00, 0x1c00).mirror(0x03fe).r(FUNC(jedi_state::speech_ready_r)).nopw();
map(0x1c01, 0x1c01).mirror(0x03fe).readonly().nopw().share("audio_comm_stat");
map(0x1c01, 0x1c01).mirror(0x03fe).r(FUNC(jedi_state::audio_comm_stat_r)).nopw();
map(0x2000, 0x7fff).noprw();
map(0x8000, 0xffff).rom();
}
@ -217,4 +145,7 @@ MACHINE_CONFIG_START(jedi_state::jedi_audio)
MCFG_DEVICE_ADD("tms", TMS5220, JEDI_TMS5220_CLOCK)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 1.0)
MCFG_GENERIC_LATCH_8_ADD("soundlatch") // 5E (LS374) + 3E (LS279) pins 13-15
MCFG_GENERIC_LATCH_8_ADD("sacklatch") // 4E (LS374) + 3E (LS279) pins 1-4
MACHINE_CONFIG_END

View File

@ -165,9 +165,6 @@ void jedi_state::machine_start()
/* configure the banks */
membank("bank1")->configure_entries(0, 3, memregion("maincpu")->base() + 0x10000, 0x4000);
/* set up save state */
save_item(NAME(m_nvram_enabled));
}
@ -180,9 +177,8 @@ void jedi_state::machine_start()
void jedi_state::machine_reset()
{
/* init globals */
m_a2d_select = 0;
m_nvram_enabled = 0;
m_novram[0]->recall(1);
m_novram[1]->recall(1);
}
@ -223,20 +219,36 @@ WRITE_LINE_MEMBER(jedi_state::coin_counter_right_w)
/*************************************
*
* NVRAM
* X2212-30 NOVRAM
*
*************************************/
WRITE8_MEMBER(jedi_state::nvram_data_w)
READ8_MEMBER(jedi_state::novram_data_r)
{
if (m_nvram_enabled)
m_nvram[offset] = data;
return (m_novram[0]->read(space, offset) & 0x0f) | (m_novram[1]->read(space, offset) << 4);
}
WRITE8_MEMBER(jedi_state::nvram_enable_w)
WRITE8_MEMBER(jedi_state::novram_data_w)
{
m_nvram_enabled = ~offset & 1;
m_novram[0]->write(space, offset, data & 0x0f);
m_novram[1]->write(space, offset, data >> 4);
}
WRITE8_MEMBER(jedi_state::novram_recall_w)
{
m_novram[0]->recall(BIT(offset, 0));
m_novram[1]->recall(BIT(offset, 0));
}
WRITE8_MEMBER(jedi_state::novram_store_w)
{
m_novram[0]->store(1);
m_novram[1]->store(1);
m_novram[0]->store(0);
m_novram[1]->store(0);
}
@ -250,19 +262,19 @@ WRITE8_MEMBER(jedi_state::nvram_enable_w)
void jedi_state::main_map(address_map &map)
{
map(0x0000, 0x07ff).ram();
map(0x0800, 0x08ff).mirror(0x0300).ram().w(FUNC(jedi_state::nvram_data_w)).share("nvram");
map(0x0800, 0x08ff).mirror(0x0300).rw(FUNC(jedi_state::novram_data_r), FUNC(jedi_state::novram_data_w));
map(0x0c00, 0x0c00).mirror(0x03fe).portr("0c00").nopw();
map(0x0c01, 0x0c01).mirror(0x03fe).portr("0c01").nopw();
map(0x1000, 0x13ff).noprw();
map(0x1400, 0x1400).mirror(0x03ff).r(FUNC(jedi_state::jedi_audio_ack_latch_r)).nopw();
map(0x1400, 0x1400).mirror(0x03ff).r("sacklatch", FUNC(generic_latch_8_device::read)).nopw();
map(0x1800, 0x1800).mirror(0x03ff).r("adc", FUNC(adc0808_device::data_r)).nopw();
map(0x1c00, 0x1c01).mirror(0x007e).nopr().w(FUNC(jedi_state::nvram_enable_w));
map(0x1c00, 0x1c01).mirror(0x007e).nopr().w(FUNC(jedi_state::novram_recall_w));
map(0x1c80, 0x1c87).mirror(0x0078).nopr().w("adc", FUNC(adc0808_device::address_offset_start_w));
map(0x1d00, 0x1d00).mirror(0x007f).noprw(); /* write: NVRAM store */
map(0x1d00, 0x1d00).mirror(0x007f).nopr().w(FUNC(jedi_state::novram_store_w));
map(0x1d80, 0x1d80).mirror(0x007f).nopr().w("watchdog", FUNC(watchdog_timer_device::reset_w));
map(0x1e00, 0x1e00).mirror(0x007f).nopr().w(FUNC(jedi_state::main_irq_ack_w));
map(0x1e80, 0x1e87).mirror(0x0078).nopr().w("outlatch", FUNC(ls259_device::write_d7));
map(0x1f00, 0x1f00).mirror(0x007f).nopr().w(FUNC(jedi_state::jedi_audio_latch_w));
map(0x1f00, 0x1f00).mirror(0x007f).nopr().w("soundlatch", FUNC(generic_latch_8_device::write));
map(0x1f80, 0x1f80).mirror(0x007f).nopr().w(FUNC(jedi_state::rom_banksel_w));
map(0x2000, 0x27ff).ram().share("backgroundram");
map(0x2800, 0x2fff).ram().share("paletteram");
@ -324,9 +336,10 @@ MACHINE_CONFIG_START(jedi_state::jedi)
MCFG_QUANTUM_TIME(attotime::from_hz(240))
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_X2212_ADD("novram12b")
MCFG_X2212_ADD("novram12c")
MCFG_DEVICE_ADD("adc", ADC0809, JEDI_AUDIO_CPU_OSC / 2 / 9)
MCFG_DEVICE_ADD("adc", ADC0809, JEDI_AUDIO_CPU_OSC / 2 / 9) // nominally 666 kHz
MCFG_ADC0808_IN0_CB(IOPORT("STICKY"))
MCFG_ADC0808_IN1_CB(NOOP) // SPARE
MCFG_ADC0808_IN2_CB(IOPORT("STICKX"))
@ -386,6 +399,14 @@ ROM_START( jedi )
ROM_REGION( 0x1000, "proms", 0 ) /* background smoothing */
ROM_LOAD( "136030-117.bin", 0x0000, 0x0400, CRC(9831bd55) SHA1(12945ef2d1582914125b9ee591567034d71d6573) )
ROM_LOAD( "136030-118.bin", 0x0800, 0x0400, CRC(261fbfe7) SHA1(efc65a74a3718563a07b718e34d8a7aa23339a69) )
// NOVRAM default fills are specified to guarantee an invalid checksum
ROM_REGION( 0x100, "novram12b", 0 )
ROM_FILL( 0x00, 0x100, 0x0f )
ROM_FILL( 0x50, 0x010, 0x00 )
ROM_REGION( 0x100, "novram12c", 0 )
ROM_FILL( 0x00, 0x100, 0x0f )
ROM_FILL( 0x50, 0x010, 0x00 )
ROM_END

View File

@ -10,6 +10,8 @@
#pragma once
#include "machine/gen_latch.h"
#include "machine/x2212.h"
#include "sound/tms5220.h"
#include "screen.h"
@ -28,17 +30,17 @@ class jedi_state : public driver_device
public:
jedi_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_nvram(*this, "nvram") ,
m_backgroundram(*this, "backgroundram"),
m_paletteram(*this, "paletteram"),
m_foregroundram(*this, "foregroundram"),
m_spriteram(*this, "spriteram"),
m_smoothing_table(*this, "smoothing_table"),
m_audio_comm_stat(*this, "audio_comm_stat"),
m_speech_data(*this, "speech_data"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_soundlatch(*this, "soundlatch"),
m_sacklatch(*this, "sacklatch"),
m_tms(*this, "tms"),
m_novram(*this, "novram12%c", 'b'),
m_screen(*this, "screen")
{ }
@ -48,33 +50,27 @@ public:
protected:
DECLARE_WRITE8_MEMBER(main_irq_ack_w);
DECLARE_WRITE8_MEMBER(rom_banksel_w);
DECLARE_READ8_MEMBER(a2d_data_r);
DECLARE_WRITE8_MEMBER(a2d_select_w);
DECLARE_WRITE_LINE_MEMBER(coin_counter_left_w);
DECLARE_WRITE_LINE_MEMBER(coin_counter_right_w);
DECLARE_WRITE8_MEMBER(nvram_data_w);
DECLARE_WRITE8_MEMBER(nvram_enable_w);
DECLARE_READ8_MEMBER(novram_data_r);
DECLARE_WRITE8_MEMBER(novram_data_w);
DECLARE_WRITE8_MEMBER(novram_recall_w);
DECLARE_WRITE8_MEMBER(novram_store_w);
DECLARE_WRITE8_MEMBER(jedi_vscroll_w);
DECLARE_WRITE8_MEMBER(jedi_hscroll_w);
DECLARE_WRITE8_MEMBER(irq_ack_w);
DECLARE_WRITE_LINE_MEMBER(audio_reset_w);
DECLARE_WRITE8_MEMBER(jedi_audio_latch_w);
DECLARE_READ8_MEMBER(audio_latch_r);
DECLARE_READ8_MEMBER(jedi_audio_ack_latch_r);
DECLARE_WRITE8_MEMBER(audio_ack_latch_w);
DECLARE_READ8_MEMBER(audio_comm_stat_r);
DECLARE_WRITE8_MEMBER(speech_strobe_w);
DECLARE_READ8_MEMBER(speech_ready_r);
DECLARE_WRITE8_MEMBER(speech_reset_w);
virtual void machine_start() override;
virtual void machine_reset() override;
virtual void sound_start() override;
virtual void sound_reset() override;
virtual void video_start() override;
DECLARE_WRITE_LINE_MEMBER(foreground_bank_w);
DECLARE_WRITE_LINE_MEMBER(video_off_w);
uint32_t screen_update_jedi(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(generate_interrupt);
TIMER_CALLBACK_MEMBER(delayed_audio_latch_w);
void get_pens(pen_t *pens);
void do_pen_lookup(bitmap_rgb32 &bitmap, const rectangle &cliprect);
void draw_background_and_text(bitmap_rgb32 &bitmap, const rectangle &cliprect);
@ -85,11 +81,7 @@ protected:
void main_map(address_map &map);
private:
required_shared_ptr<uint8_t> m_nvram;
/* machine state */
uint8_t m_a2d_select;
uint8_t m_nvram_enabled;
emu_timer *m_interrupt_timer;
/* video state */
@ -103,16 +95,12 @@ private:
bool m_foreground_bank;
bool m_video_off;
/* audio state */
uint8_t m_audio_latch;
uint8_t m_audio_ack_latch;
required_shared_ptr<uint8_t> m_audio_comm_stat;
required_shared_ptr<uint8_t> m_speech_data;
uint8_t m_speech_strobe_state;
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<generic_latch_8_device> m_soundlatch;
required_device<generic_latch_8_device> m_sacklatch;
required_device<tms5220_device> m_tms;
required_device_array<x2212_device, 2> m_novram;
required_device<screen_device> m_screen;
};