summaryrefslogtreecommitdiffstatshomepage
path: root/src/mess/audio/arcadia.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mess/audio/arcadia.c')
-rw-r--r--src/mess/audio/arcadia.c166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/mess/audio/arcadia.c b/src/mess/audio/arcadia.c
new file mode 100644
index 00000000000..575eb10dbd0
--- /dev/null
+++ b/src/mess/audio/arcadia.c
@@ -0,0 +1,166 @@
+/***************************************************************************
+
+ PeT mess@utanet.at
+ main part in video/
+
+ Refined with recording/analysis on MPT-03 (PAL UVI chip) by plgDavid
+
+ NTSC UVI sound clock: 15734Hz (arcadia)
+ PAL UVI sound clock: 15625Hz (Soundic MPT-03 - owned by plgDavid)
+***************************************************************************/
+
+
+#include "includes/arcadia.h"
+
+//known UVI audio clocks
+#define UVI_NTSC 15734
+#define UVI_PAL 15625
+
+/* we need to create pulse transitions that sound 'decent'
+ with the current mess/mame interp scheme
+
+ this is not needed anymore with the new trick in streams.c
+*/
+
+#define OSAMP 1
+
+//lfsr is 9 bits long (and same as Atari TIA pure noise)
+#define LFSR_MASK (1<<8)
+
+//makes alien invaders samples noise sync.
+#define LFSR_INIT 0x00f0
+
+//lfsr states at resynch borders
+//0x01c1
+//0x01e0
+//0x00f0 //good synch
+//0x0178
+//0x01bc
+
+
+// device type definition
+const device_type ARCADIA_SOUND = &device_creator<arcadia_sound_device>;
+
+//-------------------------------------------------
+// arcadia_sound_device - constructor
+//-------------------------------------------------
+
+arcadia_sound_device::arcadia_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
+ : device_t(mconfig, ARCADIA_SOUND, "Arcadia Custom Sound", tag, owner, clock),
+ device_sound_interface(mconfig, *this)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+void arcadia_sound_device::device_start()
+{
+ m_channel = machine().sound().stream_alloc(*this, 0, 1, UVI_PAL*OSAMP, this);
+ m_lfsr = LFSR_INIT;
+ m_tval = 1;
+ logerror("arcadia_sound start\n");
+}
+
+//-------------------------------------------------
+// sound_stream_update - handle update requests for
+// our sound stream
+//-------------------------------------------------
+
+void arcadia_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
+{
+ int i;
+ stream_sample_t *buffer = outputs[0];
+
+ for (i = 0; i < samples; i++, buffer++)
+ {
+ *buffer = 0;
+
+ //if minimal pitch ?
+ if (m_reg[1]){
+ switch (m_mode){
+ //dont play anything
+ case 0:break;
+
+ //tone only
+ case 1:
+ *buffer = m_volume * m_tval;
+ break;
+
+ //noise only
+ case 2:
+ *buffer = m_volume * m_nval;
+ break;
+
+ //tone AND noise (bitwise and)
+ case 3:
+ *buffer = m_volume * (m_tval & m_nval);
+ break;
+ }
+
+ //counter
+ m_pos++;
+
+ if (m_pos >= m_size){
+
+ //calculate new noise bit ( taps: 0000T000T)
+ unsigned char newBit = m_lfsr & 1; //first tap
+ newBit = (newBit ^ ((m_lfsr & 0x10)?1:0) );//xor with second tap
+
+ m_nval = m_lfsr & 1; //taking new output from LSB
+ m_lfsr = m_lfsr >> 1;//shifting
+
+ //insert new bit at end position (size-1) (only if non null)
+ if (newBit)
+ m_lfsr |= LFSR_MASK;
+
+ //invert tone
+ m_tval = !m_tval;
+
+ m_pos = 0;
+ }
+ }
+ }
+}
+
+
+
+//-------------------------------------------------
+// soundport_w
+//-------------------------------------------------
+
+WRITE8_MEMBER(arcadia_sound_device::write)
+{
+ m_channel->update();
+ m_reg[offset] = data;
+
+ //logerror("arcadia_sound write:%x=%x\n",offset,data);
+
+ switch (offset)
+ {
+ case 1:
+ //as per Gobbler samples:
+ //the freq counter is only applied on the next change in the flip flop
+ m_size = (data & 0x7f)*OSAMP;
+ //logerror("arcadia_sound write: frq:%d\n",data);
+
+ //reset LFSR
+ if(!m_size)
+ m_lfsr = LFSR_INIT;
+ break;
+
+ case 2:
+ m_volume = (data & 0x07) * 0x800;
+ m_mode = (data & 0x18) >> 3;
+
+ //logerror("arcadia_sound write: vol:%d mode:%d\n",m_volume,m_mode );
+
+ if (m_mode != m_omode){
+ //not 100% sure about this, maybe we should not reset anything
+ //m_pos = 0;
+ m_tval = 0;
+ }
+ m_omode = m_mode;
+ break;
+ }
+}