From ed2f586df867ea2e999107c018c681d23fb2d3a4 Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Tue, 10 Dec 2019 23:47:13 +0100 Subject: Using an emu_timer to control the READY line. --- src/devices/sound/sn76496.cpp | 38 +++++++++++++++----------------------- src/devices/sound/sn76496.h | 7 +++---- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/devices/sound/sn76496.cpp b/src/devices/sound/sn76496.cpp index 6765fb3393f..763a243f03d 100644 --- a/src/devices/sound/sn76496.cpp +++ b/src/devices/sound/sn76496.cpp @@ -125,6 +125,10 @@ * add PSSJ-3 support for the later Tandy 1000 series computers. * NCR8496's output is inverted, PSSJ-3's output is not. + 10/12/2019: Michael Zapf + * READY line handling by own emu_timer, not depending on sound_stream_update + + TODO: * Implement the TMS9919 - any difference to sn94624? * Implement the T6W28; has registers in a weird order, needs writes to be 'sanitized' first. Also is stereo, similar to game gear. @@ -255,7 +259,6 @@ void sn76496_base_device::device_start() m_RNG = m_feedback_mask; m_output[3] = m_RNG & 1; - m_cycles_to_ready = 1; // assume ready is not active immediately on init. is this correct? m_stereo_mask = 0xFF; // all channels enabled m_current_clock = m_clock_divider-1; @@ -282,6 +285,9 @@ void sn76496_base_device::device_start() m_ready_state = true; + m_ready_timer = timer_alloc(0); + m_ready_handler(ASSERT_LINE); + register_for_save_states(); } @@ -297,6 +303,11 @@ void sn76496_base_device::stereo_w(u8 data) else fatalerror("sn76496_base_device: Call to stereo write with mono chip!\n"); } +void sn76496_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + m_ready_handler(ASSERT_LINE); +} + void sn76496_base_device::write(u8 data) { int n, r, c; @@ -304,10 +315,6 @@ void sn76496_base_device::write(u8 data) // update the output buffer before changing the registers m_sound->update(); - // set number of cycles until READY is active; this is always one - // 'sample', i.e. it equals the clock divider exactly - m_cycles_to_ready = 1; - if (data & 0x80) { r = (data & 0x70) >> 4; @@ -355,6 +362,9 @@ void sn76496_base_device::write(u8 data) } break; } + + m_ready_handler(CLEAR_LINE); + m_ready_timer->adjust(attotime::from_hz(clock()/(4*m_clock_divider))); } inline bool sn76496_base_device::in_noise_mode() @@ -362,21 +372,6 @@ inline bool sn76496_base_device::in_noise_mode() return ((m_register[6] & 4)!=0); } -void sn76496_base_device::countdown_cycles() -{ - if (m_cycles_to_ready > 0) - { - m_cycles_to_ready--; - if (m_ready_state==true) m_ready_handler(CLEAR_LINE); - m_ready_state = false; - } - else - { - if (m_ready_state==false) m_ready_handler(ASSERT_LINE); - m_ready_state = true; - } -} - void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) { int i; @@ -396,8 +391,6 @@ void sn76496_base_device::sound_stream_update(sound_stream &stream, stream_sampl else // ready for new divided clock, make a new sample { m_current_clock = m_clock_divider-1; - // decrement Cycles to READY by one - countdown_cycles(); // handle channels 0,1,2 for (i = 0; i < 3; i++) @@ -478,7 +471,6 @@ void sn76496_base_device::register_for_save_states() save_item(NAME(m_period)); save_item(NAME(m_count)); save_item(NAME(m_output)); - save_item(NAME(m_cycles_to_ready)); // save_item(NAME(m_sega_style_psg)); } diff --git a/src/devices/sound/sn76496.h b/src/devices/sound/sn76496.h index cd7b4a6c509..07fb3a47932 100644 --- a/src/devices/sound/sn76496.h +++ b/src/devices/sound/sn76496.h @@ -23,7 +23,6 @@ class sn76496_base_device : public device_t, public device_sound_interface { public: auto ready_cb() { return m_ready_handler.bind(); } - void stereo_w(u8 data); void write(u8 data); DECLARE_READ_LINE_MEMBER( ready_r ) { return m_ready_state ? 1 : 0; } @@ -51,10 +50,9 @@ protected: private: inline bool in_noise_mode(); void register_for_save_states(); - void countdown_cycles(); + void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; bool m_ready_state; - devcb_write_line m_ready_handler; sound_stream* m_sound; @@ -78,7 +76,8 @@ private: int32_t m_period[4]; // Length of 1/2 of waveform int32_t m_count[4]; // Position within the waveform int32_t m_output[4]; // 1-bit output of each channel, pre-volume - int32_t m_cycles_to_ready; // number of cycles until the READY line goes active + + emu_timer *m_ready_timer; }; // SN76496: Whitenoise verified, phase verified, periodic verified (by Michael Zapf) -- cgit v1.2.3