// license:BSD-3-Clause // copyright-holders:Nicola Salmoria /*************************************************************************** Sega Zaxxon hardware **************************************************************************** Sound interface is provided by an 8255. The 8255 is a parallel peripheral interface, used also in Scramble. It has three 8-bit outputs. All sounds are generated by discrete circuits. Each sound is triggered by an output pin of the 8255. Zaxxon Sound Information: (from the schematics) by Frank Palazzolo There are four registers in the 8255. they are mapped to (111x xxxx 0011 11pp) by Zaxxon. Zaxxon writes to these at FF3C-FF3F. There are three modes of the 8255, but by the schematics I can see that Zaxxon is using "Mode 0", which is very simple. Important Note: These are all Active-Low outputs. A 1 De-activates the sound, while a 0 Activates/Triggers it Port A Output: FF3C bit7 Battleship bit6 Laser bit5 Base Missle bit4 Homing Missle bit3 Player Ship D bit2 Player Ship C bit1 Player Ship B bit0 Player Ship A Port B Output: FF3D bit7 Cannon bit6 N/C bit5 M-Exp bit4 S-Exp bit3 N/C bit2 N/C bit1 N/C bit0 N/C Port C Output: FF3E bit7 N/C bit6 N/C bit5 N/C bit4 N/C bit3 Alarm 3 bit2 Alarm 2 bit1 N/C bit0 Shot Control Byte: FF3F Should be written an 0x80 for Mode 0 (Very Simple) operation of the 8255 ***************************************************************************/ #include "emu.h" #include "sound/samples.h" #include "includes/zaxxon.h" /************************************* * * Zaxxon sound hardware description * *************************************/ static const char *const zaxxon_sample_names[] = { "*zaxxon", "03", /* 0 - Homing Missile */ "02", /* 1 - Base Missile */ "01", /* 2 - Laser (force field) */ "00", /* 3 - Battleship (end of level boss) */ "11", /* 4 - S-Exp (enemy explosion) */ "10", /* 5 - M-Exp (ship explosion) */ "08", /* 6 - Cannon (ship fire) */ "23", /* 7 - Shot (enemy fire) */ "21", /* 8 - Alarm 2 (target lock) */ "20", /* 9 - Alarm 3 (low fuel) */ "05", /* 10 - initial background noise */ "04", /* 11 - looped asteroid noise */ nullptr }; MACHINE_CONFIG_START(zaxxon_state::zaxxon_samples) MCFG_DEVICE_ADD("samples", SAMPLES) MCFG_SAMPLES_CHANNELS(12) MCFG_SAMPLES_NAMES(zaxxon_sample_names) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.25) MACHINE_CONFIG_END /************************************* * * Zaxxon PPI write handlers * *************************************/ WRITE8_MEMBER(zaxxon_state::zaxxon_sound_a_w) { uint8_t diff = data ^ m_sound_state[0]; m_sound_state[0] = data; /* PLAYER SHIP A/B: volume */ m_samples->set_volume(10, 0.5 + 0.157 * (data & 0x03)); m_samples->set_volume(11, 0.5 + 0.157 * (data & 0x03)); /* PLAYER SHIP C: channel 10 */ if ((diff & 0x04) && !(data & 0x04)) m_samples->start(10, 10, true); if ((diff & 0x04) && (data & 0x04)) m_samples->stop(10); /* PLAYER SHIP D: channel 11 */ if ((diff & 0x08) && !(data & 0x08)) m_samples->start(11, 11, true); if ((diff & 0x08) && (data & 0x08)) m_samples->stop(11); /* HOMING MISSILE: channel 0 */ if ((diff & 0x10) && !(data & 0x10)) m_samples->start(0, 0, true); if ((diff & 0x10) && (data & 0x10)) m_samples->stop(0); /* BASE MISSILE: channel 1 */ if ((diff & 0x20) && !(data & 0x20)) m_samples->start(1, 1); /* LASER: channel 2 */ if ((diff & 0x40) && !(data & 0x40)) m_samples->start(2, 2, true); if ((diff & 0x40) && (data & 0x40)) m_samples->stop(2); /* BATTLESHIP: channel 3 */ if ((diff & 0x80) && !(data & 0x80)) m_samples->start(3, 3, true); if ((diff & 0x80) && (data & 0x80)) m_samples->stop(3); } WRITE8_MEMBER(zaxxon_state::zaxxon_sound_b_w) { uint8_t diff = data ^ m_sound_state[1]; m_sound_state[1] = data; /* S-EXP: channel 4 */ if ((diff & 0x10) && !(data & 0x10)) m_samples->start(4, 4); /* M-EXP: channel 5 */ if ((diff & 0x20) && !(data & 0x20) && !m_samples->playing(5)) m_samples->start(5, 5); /* CANNON: channel 6 */ if ((diff & 0x80) && !(data & 0x80)) m_samples->start(6, 6); } WRITE8_MEMBER(zaxxon_state::zaxxon_sound_c_w) { uint8_t diff = data ^ m_sound_state[2]; m_sound_state[2] = data; /* SHOT: channel 7 */ if ((diff & 0x01) && !(data & 0x01)) m_samples->start(7, 7); /* ALARM2: channel 8 */ if ((diff & 0x04) && !(data & 0x04)) m_samples->start(8, 8); /* ALARM3: channel 9 */ if ((diff & 0x08) && !(data & 0x08) && !m_samples->playing(9)) m_samples->start(9, 9); } /************************************* * * Congo sound hardware description * *************************************/ static const char *const congo_sample_names[] = { "*congo", "gorilla", /* 0 */ "bass", /* 1 */ "congal", /* 2 */ "congah", /* 3 */ "rim", /* 4 */ nullptr }; MACHINE_CONFIG_START(zaxxon_state::congo_samples) MCFG_DEVICE_ADD("samples", SAMPLES) MCFG_SAMPLES_CHANNELS(5) MCFG_SAMPLES_NAMES(congo_sample_names) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "speaker", 0.25) MACHINE_CONFIG_END /************************************* * * Congo PPI write handlers * *************************************/ WRITE8_MEMBER(zaxxon_state::congo_sound_b_w) { uint8_t diff = data ^ m_sound_state[1]; m_sound_state[1] = data; /* bit 7 = mute */ /* GORILLA: channel 0 */ if ((diff & 0x02) && !(data & 0x02) && !m_samples->playing(0)) m_samples->start(0, 0); } WRITE8_MEMBER(zaxxon_state::congo_sound_c_w) { uint8_t diff = data ^ m_sound_state[2]; m_sound_state[2] = data; /* BASS DRUM: channel 1 */ if ((diff & 0x01) && !(data & 0x01)) m_samples->start(1, 1); if ((diff & 0x01) && (data & 0x01)) m_samples->stop(1); /* CONGA (LOW): channel 2 */ if ((diff & 0x02) && !(data & 0x02)) m_samples->start(2, 2); if ((diff & 0x02) && (data & 0x02)) m_samples->stop(2); /* CONGA (HIGH): channel 3 */ if ((diff & 0x04) && !(data & 0x04)) m_samples->start(3, 3); if ((diff & 0x04) && (data & 0x04)) m_samples->stop(3); /* RIM: channel 4 */ if ((diff & 0x08) && !(data & 0x08)) m_samples->start(4, 4); if ((diff & 0x08) && (data & 0x08)) m_samples->stop(4); }