diff options
Diffstat (limited to 'src/mame/audio/starwars.c')
-rw-r--r-- | src/mame/audio/starwars.c | 247 |
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); +} + |