summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/audio/starwars.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/audio/starwars.c')
-rw-r--r--src/mame/audio/starwars.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/mame/audio/starwars.c b/src/mame/audio/starwars.c
new file mode 100644
index 00000000000..742342bb3b4
--- /dev/null
+++ b/src/mame/audio/starwars.c
@@ -0,0 +1,247 @@
+/***************************************************************************
+
+ Atari Star Wars hardware
+
+ This file is Copyright 1997, Steve Baines.
+ Modified by Frank Palazzolo for sound support
+
+***************************************************************************/
+
+#include "driver.h"
+#include "cpu/m6809/m6809.h"
+#include "sound/5220intf.h"
+#include "includes/starwars.h"
+
+/* Sound commands from the main CPU are stored in a single byte */
+/* register. The main CPU then interrupts the Sound CPU. */
+
+static int port_A = 0; /* 6532 port A data register */
+
+ /* Configured as follows: */
+ /* d7 (in) Main Ready Flag */
+ /* d6 (in) Sound Ready Flag */
+ /* d5 (out) Mute Speech */
+ /* d4 (in) Not Sound Self Test */
+ /* d3 (out) Hold Main CPU in Reset? */
+ /* + enable delay circuit? */
+ /* d2 (in) TMS5220 Not Ready */
+ /* d1 (out) TMS5220 Not Read */
+ /* d0 (out) TMS5220 Not Write */
+
+static int port_B = 0; /* 6532 port B data register */
+ /* (interfaces to TMS5220 data bus) */
+
+static int irq_flag = 0; /* 6532 interrupt flag register */
+
+static int port_A_ddr = 0; /* 6532 Data Direction Register A */
+static int port_B_ddr = 0; /* 6532 Data Direction Register B */
+ /* for each bit, 0 = input, 1 = output */
+
+static int PA7_irq = 0; /* IRQ-on-write flag (sound CPU) */
+
+static int sound_data; /* data for the sound cpu */
+static int main_data; /* data for the main cpu */
+
+
+
+/*************************************
+ *
+ * Sound interrupt generation
+ *
+ *************************************/
+
+static TIMER_CALLBACK( snd_interrupt )
+{
+ irq_flag |= 0x80; /* set timer interrupt flag */
+ cpunum_set_input_line(1, M6809_IRQ_LINE, ASSERT_LINE);
+}
+
+
+
+/*************************************
+ *
+ * M6532 I/O read
+ *
+ *************************************/
+
+READ8_HANDLER( starwars_m6532_r )
+{
+ static int temp;
+
+ switch (offset)
+ {
+ case 0: /* 0x80 - Read Port A */
+
+ /* Note: bit 4 is always set to avoid sound self test */
+
+ return port_A|0x10|(!tms5220_ready_r()<<2);
+
+ case 1: /* 0x81 - Read Port A DDR */
+ return port_A_ddr;
+
+ case 2: /* 0x82 - Read Port B */
+ return port_B; /* speech data read? */
+
+ case 3: /* 0x83 - Read Port B DDR */
+ return port_B_ddr;
+
+ case 5: /* 0x85 - Read Interrupt Flag Register */
+ if (irq_flag)
+ cpunum_set_input_line(1, M6809_IRQ_LINE, CLEAR_LINE);
+ temp = irq_flag;
+ irq_flag = 0; /* Clear int flags */
+ return temp;
+
+ default:
+ return 0;
+ }
+
+ return 0; /* will never execute this */
+}
+
+
+
+/*************************************
+ *
+ * M6532 I/O write
+ *
+ *************************************/
+
+WRITE8_HANDLER( starwars_m6532_w )
+{
+ switch (offset)
+ {
+ case 0: /* 0x80 - Port A Write */
+
+ /* Write to speech chip on PA0 falling edge */
+
+ if((port_A&0x01)==1)
+ {
+ port_A = (port_A&(~port_A_ddr))|(data&port_A_ddr);
+ if ((port_A&0x01)==0)
+ tms5220_data_w(0,port_B);
+ }
+ else
+ port_A = (port_A&(~port_A_ddr))|(data&port_A_ddr);
+
+ return;
+
+ case 1: /* 0x81 - Port A DDR Write */
+ port_A_ddr = data;
+ return;
+
+ case 2: /* 0x82 - Port B Write */
+ /* TMS5220 Speech Data on port B */
+
+ /* ignore DDR for now */
+ port_B = data;
+
+ return;
+
+ case 3: /* 0x83 - Port B DDR Write */
+ port_B_ddr = data;
+ return;
+
+ case 7: /* 0x87 - Enable Interrupt on PA7 Transitions */
+
+ /* This feature is emulated now. When the Main CPU */
+ /* writes to mainwrite, it may send an IRQ to the */
+ /* sound CPU, depending on the state of this flag. */
+
+ PA7_irq = data;
+ return;
+
+
+ case 0x1f: /* 0x9f - Set Timer to decrement every n*1024 clocks, */
+ /* With IRQ enabled on countdown */
+
+ /* Should be decrementing every data*1024 6532 clock cycles */
+ /* 6532 runs at 1.5 MHz */
+
+ timer_set(attotime_mul(ATTOTIME_IN_HZ(1500000), data * 1024), 0, snd_interrupt);
+ return;
+
+ default:
+ return;
+ }
+
+ return; /* will never execute this */
+
+}
+
+
+
+/*************************************
+ *
+ * Sound CPU to/from main CPU
+ *
+ *************************************/
+
+static TIMER_CALLBACK( sound_callback )
+{
+ port_A |= 0x40; /* result from sound cpu pending */
+ main_data = param;
+ cpu_boost_interleave(attotime_zero, ATTOTIME_IN_USEC(100));
+}
+
+READ8_HANDLER( starwars_sin_r )
+{
+ port_A &= 0x7f; /* ready to receive new commands from main */
+ if (PA7_irq)
+ cpunum_set_input_line(1, M6809_IRQ_LINE, CLEAR_LINE);
+ return sound_data;
+}
+
+
+WRITE8_HANDLER( starwars_sout_w )
+{
+ timer_call_after_resynch(data, sound_callback);
+}
+
+
+
+/*************************************
+ *
+ * Main CPU to/from source CPU
+ *
+ *************************************/
+
+READ8_HANDLER( starwars_main_read_r )
+{
+ port_A &= 0xbf; /* ready to receive new commands from sound cpu */
+ return main_data;
+}
+
+
+READ8_HANDLER( starwars_main_ready_flag_r )
+{
+ return (port_A & 0xc0); /* only upper two flag bits mapped */
+}
+
+static TIMER_CALLBACK( main_callback )
+{
+ if (port_A & 0x80)
+ logerror ("Sound data not read %x\n",sound_data);
+
+ port_A |= 0x80; /* command from main cpu pending */
+ sound_data = param;
+ cpu_boost_interleave(attotime_zero, ATTOTIME_IN_USEC(100));
+
+ if (PA7_irq)
+ cpunum_set_input_line(1, M6809_IRQ_LINE, ASSERT_LINE);
+}
+
+WRITE8_HANDLER( starwars_main_wr_w )
+{
+ timer_call_after_resynch(data, main_callback);
+}
+
+
+WRITE8_HANDLER( starwars_soundrst_w )
+{
+ port_A &= 0x3f;
+
+ /* reset sound CPU here */
+ cpunum_set_input_line(1, INPUT_LINE_RESET, PULSE_LINE);
+}
+