diff --git a/.gitattributes b/.gitattributes index 00d9589b3df..78fcce56467 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2246,6 +2246,7 @@ src/mame/includes/psx.h svneol=native#text/plain src/mame/includes/qix.h svneol=native#text/plain src/mame/includes/rampart.h svneol=native#text/plain src/mame/includes/realbrk.h svneol=native#text/plain +src/mame/includes/redalert.h svneol=native#text/plain src/mame/includes/relief.h svneol=native#text/plain src/mame/includes/rescap.h svneol=native#text/plain src/mame/includes/segag80r.h svneol=native#text/plain diff --git a/src/mame/audio/redalert.c b/src/mame/audio/redalert.c index f726cb24b68..9c8ff9ed13b 100644 --- a/src/mame/audio/redalert.c +++ b/src/mame/audio/redalert.c @@ -1,121 +1,228 @@ /*************************************************************************** -Irem Red Alert sound hardware + Irem Red Alert hardware -The manual lists two sets of sounds. + If you have any questions about how this driver works, don't hesitate to + ask. - Mike Balfour (mab22@po.cwru.edu) -Analogue: -- Formation Aircraft -- Dive bombers -- Helicopters -- Launcher firing -- Explosion #1 -- Explosion #2 -- Explosion #3 - -Digital: -- Melody #1. Starting sound. -- Melody #2. Ending sound -- Time signal -- Chirping birds -- Alarm -- Excellent -- Coin insertion -- MIRV division -- Megaton bomb - long -- Megaton bomb - short -- Megaton bomb landing - -If you have any questions about how this driver works, don't hesitate to -ask. - Mike Balfour (mab22@po.cwru.edu) -***************************************************************************/ +****************************************************************************/ #include "driver.h" -#include "cpu/m6502/m6502.h" +#include "rescap.h" #include "cpu/i8085/i8085.h" #include "sound/ay8910.h" +#include "sound/hc55516.h" -static int AY8910_A_input_data = 0; -static int c030_data = 0; -static int sound_register_IC1 = 0; -static int sound_register_IC2 = 0; -WRITE8_HANDLER( redalert_c030_w ) + +#define AUDIO_PCB_CLOCK (XTAL_12_5MHz) +#define AUDIO_CPU_CLOCK (AUDIO_PCB_CLOCK / 12) +#define AY8910_CLOCK (AUDIO_PCB_CLOCK / 6) +#define AUDIO_CPU_IRQ_FREQ (1.0 / attotime_to_double(PERIOD_OF_555_ASTABLE(RES_K(120), RES_K(2.7), CAP_U(0.01)))) + +#define VOICE_PCB_CLOCK (XTAL_6MHz) +#define VOICE_CPU_CLOCK (VOICE_PCB_CLOCK) +#define HC55516_CLOCK (VOICE_PCB_CLOCK / 256) + + + +/************************************* + * + * Statics + * + *************************************/ + +static UINT8 audio_register_IC1; +static UINT8 audio_register_IC2; + + + +/************************************* + * + * Analog sounds + * + *************************************/ + +static WRITE8_HANDLER( redalert_analog_w ) { - c030_data = data & 0x3F; + /* this port triggers analog sounds + D0 = Formation Aircraft? + D1 = Dive bombers? + D2 = Helicopters? + D3 = Launcher firing? + D4 = Explosion #1? + D5 = Explosion #2? + D6 = Explosion #3? */ - /* Is this some type of sound command? */ - if (data & 0x80) - /* Cause an NMI on the voice CPU here? */ - cpunum_set_input_line(2,I8085_RST75_LINE,HOLD_LINE); + logerror("Analog: %02X\n",data); } -READ8_HANDLER( redalert_voicecommand_r ) + + +/************************************* + * + * Audio board + * + *************************************/ + +WRITE8_HANDLER( redalert_audio_command_w ) { - return c030_data; + /* the byte is connected to port A of the AY8910 */ + soundlatch_w(0, data); + + /* D7 is also connected to the NMI input of the CPU - + the NMI is actually toggled by a 74121 */ + if ((data & 0x80) == 0x00) + cpunum_set_input_line(1, INPUT_LINE_NMI, PULSE_LINE); } -WRITE8_HANDLER( redalert_soundlatch_w ) -{ - /* The byte is connected to Port A of the AY8910 */ - AY8910_A_input_data = data; - /* Bit D7 is also connected to the NMI input of the CPU */ - if ((data & 0x80)!=0x80) - cpunum_set_input_line(1,INPUT_LINE_NMI,PULSE_LINE); -} - -READ8_HANDLER( redalert_AY8910_A_r ) -{ - return AY8910_A_input_data; -} - -WRITE8_HANDLER( redalert_AY8910_w ) +static WRITE8_HANDLER( redalert_AY8910_w ) { /* BC2 is connected to a pull-up resistor, so BC2=1 always */ - switch (data) + switch (data & 0x03) { + /* BC1=0, BDIR=0 : inactive */ case 0x00: - /* BC1=0, BDIR=0 : INACTIVE */ break; + + /* BC1=1, BDIR=0 : read from PSG */ case 0x01: - /* BC1=1, BDIR=0 : READ FROM PSG */ - sound_register_IC1 = AY8910_read_port_0_r(offset); + audio_register_IC1 = AY8910_read_port_0_r(offset); break; + + /* BC1=0, BDIR=1 : write to PSG */ case 0x02: - /* BC1=0, BDIR=1 : WRITE TO PSG */ - AY8910_write_port_0_w(offset,sound_register_IC2); - break; - case 0x03: - /* BC1=1, BDIR=1 : LATCH ADDRESS */ - AY8910_control_port_0_w(offset,sound_register_IC2); + AY8910_write_port_0_w(offset, audio_register_IC2); break; + + /* BC1=1, BDIR=1 : latch address */ default: - logerror("Invalid Sound Command: %02X\n",data); + case 0x03: + AY8910_control_port_0_w(offset, audio_register_IC2); break; } } -READ8_HANDLER( redalert_sound_register_IC1_r ) + +static READ8_HANDLER( audio_register_IC1_r ) { - return sound_register_IC1; + return audio_register_IC1; } -WRITE8_HANDLER( redalert_sound_register_IC2_w ) + +static WRITE8_HANDLER( audio_register_IC2_w ) { - sound_register_IC2 = data; + audio_register_IC2 = data; } -WRITE8_HANDLER( redalert_AY8910_B_w ) + +static const struct AY8910interface ay8910_interface = { - /* I'm fairly certain this port triggers analog sounds */ - logerror("Port B Trigger: %02X\n",data); - /* D0 = Formation Aircraft? */ - /* D1 = Dive bombers? */ - /* D2 = Helicopters? */ - /* D3 = Launcher firing? */ - /* D4 = Explosion #1? */ - /* D5 = Explosion #2? */ - /* D6 = Explosion #3? */ + soundlatch_r, 0, /* port A/B read */ + 0, redalert_analog_w /* port A/B write */ +}; + + +static ADDRESS_MAP_START( redalert_audio_map, ADDRESS_SPACE_PROGRAM, 8 ) + ADDRESS_MAP_FLAGS( AMEF_ABITS(15) ) + AM_RANGE(0x0000, 0x03ff) AM_MIRROR(0x0c00) AM_RAM + AM_RANGE(0x1000, 0x1000) AM_MIRROR(0x0ffe) AM_READWRITE(MRA8_NOP, redalert_AY8910_w) + AM_RANGE(0x1001, 0x1001) AM_MIRROR(0x0ffe) AM_READWRITE(audio_register_IC1_r, audio_register_IC2_w) + AM_RANGE(0x2000, 0x6fff) AM_NOP + AM_RANGE(0x7000, 0x77ff) AM_MIRROR(0x0800) AM_ROM +ADDRESS_MAP_END + + +static SOUND_START( redalert_audio ) +{ + state_save_register_global(audio_register_IC1); + state_save_register_global(audio_register_IC2); } + + +/************************************* + * + * Voice board + * + *************************************/ + +WRITE8_HANDLER( redalert_voice_command_w ) +{ + soundlatch2_w(0, (data & 0x78) >> 3); + + cpunum_set_input_line(2, I8085_RST75_LINE, (~data & 0x80) ? ASSERT_LINE : CLEAR_LINE); +} + + +static void sod_callback(int data) +{ + hc55516_digit_w(0, data); +} + + +static int sid_callback(void) +{ + return hc55516_clock_state_r(0); +} + + +static SOUND_START( redalert_voice ) +{ + cpunum_set_info_fct(2, CPUINFO_PTR_I8085_SOD_CALLBACK, (void *)sod_callback); + cpunum_set_info_fct(2, CPUINFO_PTR_I8085_SID_CALLBACK, (void *)sid_callback); +} + + +static ADDRESS_MAP_START( redalert_voice_map, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x3fff) AM_ROM + AM_RANGE(0x4000, 0x7fff) AM_NOP + AM_RANGE(0x8000, 0x83ff) AM_MIRROR(0x3c00) AM_RAM + AM_RANGE(0xc000, 0xc000) AM_MIRROR(0x3fff) AM_READWRITE(soundlatch2_r, MWA8_NOP) +ADDRESS_MAP_END + + + +/************************************* + * + * Audio start + * + *************************************/ + +static SOUND_START( redalert ) +{ + SOUND_START_CALL(redalert_audio); + SOUND_START_CALL(redalert_voice); +} + + + +/************************************* + * + * Machine driver + * + *************************************/ + +MACHINE_DRIVER_START( redalert_audio ) + + MDRV_CPU_ADD(M6502, AUDIO_CPU_CLOCK) + MDRV_CPU_PROGRAM_MAP(redalert_audio_map,0) + MDRV_CPU_PERIODIC_INT(irq0_line_hold, AUDIO_CPU_IRQ_FREQ) + + MDRV_CPU_ADD(8085A, VOICE_CPU_CLOCK) + MDRV_CPU_PROGRAM_MAP(redalert_voice_map,0) + + MDRV_SOUND_START( redalert ) + + MDRV_SPEAKER_STANDARD_MONO("mono") + + MDRV_SOUND_ADD(AY8910, AY8910_CLOCK) + MDRV_SOUND_CONFIG(ay8910_interface) + MDRV_SOUND_ROUTE(0, "mono", 0.50) + MDRV_SOUND_ROUTE(1, "mono", 0.50) + /* channel C is used a noise source and is not connected to a speaker */ + + MDRV_SOUND_ADD(HC55516, HC55516_CLOCK) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) +MACHINE_DRIVER_END diff --git a/src/mame/drivers/redalert.c b/src/mame/drivers/redalert.c index c12e5a81556..5ba5c3d7d8f 100644 --- a/src/mame/drivers/redalert.c +++ b/src/mame/drivers/redalert.c @@ -1,181 +1,200 @@ /*************************************************************************** -Irem Red Alert Driver + Irem Red Alert hardware -Everything in this driver is guesswork and speculation. If something -seems wrong, it probably is. + If you have any questions about how this driver works, don't hesitate to + ask. - Mike Balfour (mab22@po.cwru.edu) -If you have any questions about how this driver works, don't hesitate to -ask. - Mike Balfour (mab22@po.cwru.edu) -***************************************************************************/ + ******************************************************************** + IREM 'DEMONEYE-X' proto 1981 + + proto sound board + + 8910 + 6821 8910 + 6802 sound6 sound7 + 3.579545MHz + + main board M-27M-C + + 11.73MHz 6502 x x x xx + x x x on + 4116 8 + 4116 - + 4116 9 + 4116 6 + 4116 A + 4116 7 + 4116 B + 4116 + + sub board 1 M-27Sb + + 1a2 + + 2114 + 2114 + 2114 <- two parts piggy-backed + 2114 <- two parts piggy-backed + 2114 2114 + 2114 2114 + + sub board 2 M-42-S + + 1a clr(missing) + + 2114 + 2114 + 2114 + 2114 + 2114 + 2114 + + ********************************************************************* + + Known issues/to-do's: + * Analog sounds + * DIP switches have a different meaning in test mode (see manual) + * Video timing from schematics + * Audio CPU NMI is generated by a 74121 multivibrator, the correct + pulse length is not emulated + +****************************************************************************/ #include "driver.h" #include "machine/6821pia.h" -#include "sound/ay8910.h" - -/* video/redalert.c */ -extern UINT8 *redalert_backram; -extern UINT8 *redalert_spriteram1; -extern UINT8 *redalert_spriteram2; -extern UINT8 *redalert_spriteram3; -extern UINT8 *redalert_characterram; -extern UINT8 *redalert_characterram2; -WRITE8_HANDLER( redalert_backram_w ); -WRITE8_HANDLER( redalert_spriteram1_w ); -WRITE8_HANDLER( redalert_spriteram2_w ); -WRITE8_HANDLER( redalert_spriteram3_w ); -WRITE8_HANDLER( redalert_spriteram4_w ); -WRITE8_HANDLER( redalert_characterram_w ); -WRITE8_HANDLER( redalert_characterram2_w ); -extern VIDEO_UPDATE( redalert ); -WRITE8_HANDLER( redalert_c040_w ); -WRITE8_HANDLER( demoneye_c040_w ); -WRITE8_HANDLER( redalert_backcolor_w ); +#include "redalert.h" -/* audio/redalert.c */ -WRITE8_HANDLER( redalert_c030_w ); -READ8_HANDLER( redalert_voicecommand_r ); -WRITE8_HANDLER( redalert_soundlatch_w ); -READ8_HANDLER( redalert_AY8910_A_r ); -WRITE8_HANDLER( redalert_AY8910_B_w ); -WRITE8_HANDLER( redalert_AY8910_w ); -READ8_HANDLER( redalert_sound_register_IC1_r ); -WRITE8_HANDLER( redalert_sound_register_IC2_w ); +#define MAIN_PCB_CLOCK (XTAL_12_5MHz) +#define MAIN_CPU_CLOCK (MAIN_PCB_CLOCK / 16) -static ADDRESS_MAP_START( redalert_readmem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x01ff) AM_READ(MRA8_RAM) /* Zero page / stack */ - AM_RANGE(0x0200, 0x0fff) AM_READ(MRA8_RAM) /* ? */ - AM_RANGE(0x1000, 0x1fff) AM_READ(MRA8_RAM) /* Scratchpad video RAM */ - AM_RANGE(0x2000, 0x4fff) AM_READ(MRA8_RAM) /* Video RAM */ - AM_RANGE(0x5000, 0xbfff) AM_READ(MRA8_ROM) - AM_RANGE(0xc100, 0xc100) AM_READ(input_port_0_r) - AM_RANGE(0xc110, 0xc110) AM_READ(input_port_1_r) - AM_RANGE(0xc120, 0xc120) AM_READ(input_port_2_r) - AM_RANGE(0xc170, 0xc170) AM_READ(watchdog_reset_r) - AM_RANGE(0xf000, 0xffff) AM_READ(MRA8_ROM) /* remapped ROM for 6502 vectors */ -ADDRESS_MAP_END -static ADDRESS_MAP_START( redalert_writemem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x01ff) AM_WRITE(MWA8_RAM) - AM_RANGE(0x0200, 0x0fff) AM_WRITE(MWA8_RAM) /* ? */ - AM_RANGE(0x1000, 0x1fff) AM_WRITE(MWA8_RAM) /* Scratchpad video RAM */ - AM_RANGE(0x2000, 0x3fff) AM_WRITE(redalert_backram_w) AM_BASE(&redalert_backram) - AM_RANGE(0x4000, 0x43ff) AM_WRITE(MWA8_RAM) AM_BASE(&videoram) AM_SIZE(&videoram_size) - AM_RANGE(0x4400, 0x47ff) AM_WRITE(redalert_spriteram1_w) AM_BASE(&redalert_spriteram1) - AM_RANGE(0x4800, 0x4bff) AM_WRITE(redalert_characterram_w) AM_BASE(&redalert_characterram) - AM_RANGE(0x4c00, 0x4fff) AM_WRITE(redalert_spriteram2_w) AM_BASE(&redalert_spriteram2) - AM_RANGE(0x5000, 0xbfff) AM_WRITE(MWA8_ROM) - AM_RANGE(0xc130, 0xc130) AM_WRITE(redalert_c030_w) - AM_RANGE(0xc140, 0xc140) AM_WRITE(redalert_c040_w) - AM_RANGE(0xc150, 0xc150) AM_WRITE(redalert_backcolor_w) - AM_RANGE(0xc160, 0xc160) AM_WRITE(redalert_soundlatch_w) - AM_RANGE(0xf000, 0xffff) AM_WRITE(MWA8_ROM) -ADDRESS_MAP_END +/* PIA 0, sound CPU */ +static const pia6821_interface pia_0_intf = +{ + /*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0, + /*outputs: A/B,CA/B2 */ 0, 0, 0, 0, + /*irqs : A/B */ 0, 0 +}; -static ADDRESS_MAP_START( redalert_sound_readmem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x03ff) AM_READ(MRA8_RAM) - AM_RANGE(0x7800, 0x7fff) AM_READ(MRA8_ROM) - AM_RANGE(0xf800, 0xffff) AM_READ(MRA8_ROM) - AM_RANGE(0x1001, 0x1001) AM_READ(redalert_sound_register_IC1_r) -ADDRESS_MAP_END +static MACHINE_START( demoneye ) +{ + pia_config(0, &pia_0_intf); +} -static ADDRESS_MAP_START( redalert_sound_writemem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x03ff) AM_WRITE(MWA8_RAM) - AM_RANGE(0x7800, 0x7fff) AM_WRITE(MWA8_ROM) - AM_RANGE(0xf800, 0xffff) AM_WRITE(MWA8_ROM) - AM_RANGE(0x1000, 0x1000) AM_WRITE(redalert_AY8910_w) - AM_RANGE(0x1001, 0x1001) AM_WRITE(redalert_sound_register_IC2_w) -ADDRESS_MAP_END +static MACHINE_RESET( demoneye ) +{ + pia_reset(); +} -static ADDRESS_MAP_START( redalert_voice_readmem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x3fff) AM_READ(MRA8_ROM) - AM_RANGE(0x8000, 0x83ff) AM_READ(MRA8_RAM) - AM_RANGE(0xc000, 0xc000) AM_READ(redalert_voicecommand_r) /* reads command from D0-D5? */ -ADDRESS_MAP_END -static ADDRESS_MAP_START( redalert_voice_writemem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x3fff) AM_WRITE(MWA8_ROM) - AM_RANGE(0x8000, 0x83ff) AM_WRITE(MWA8_RAM) + +/************************************* + * + * Interrupt generation + * + *************************************/ + +static INTERRUPT_GEN( redalert_interrupt ) +{ + if( readinputport(3) ) + cpunum_set_input_line(0, INPUT_LINE_NMI, PULSE_LINE); + + cpunum_set_input_line(0, 0, HOLD_LINE); +} + + + +/************************************* + * + * Memory handlers + * + *************************************/ + +static ADDRESS_MAP_START( redalert_main_map, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x1fff) AM_RAM + AM_RANGE(0x2000, 0x3fff) AM_READWRITE(MRA8_RAM, redalert_bitmap_videoram_w) AM_BASE(&redalert_bitmap_videoram) + AM_RANGE(0x4000, 0x4fff) AM_RAM AM_BASE(&redalert_charmap_videoram) + AM_RANGE(0x5000, 0xbfff) AM_ROM + AM_RANGE(0xc000, 0xc000) AM_MIRROR(0x0f8f) AM_READWRITE(input_port_0_r, MWA8_NOP) + AM_RANGE(0xc010, 0xc010) AM_MIRROR(0x0f8f) AM_READWRITE(input_port_1_r, MWA8_NOP) + AM_RANGE(0xc020, 0xc020) AM_MIRROR(0x0f8f) AM_READWRITE(input_port_2_r, MWA8_NOP) + AM_RANGE(0xc030, 0xc030) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, redalert_audio_command_w) + AM_RANGE(0xc040, 0xc040) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE(&redalert_video_control) + AM_RANGE(0xc050, 0xc050) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE(&redalert_bitmap_color) + AM_RANGE(0xc060, 0xc060) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, redalert_voice_command_w) + AM_RANGE(0xc070, 0xc070) AM_MIRROR(0x0f8f) AM_READWRITE(watchdog_reset_r, MWA8_NOP) + AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION(REGION_CPU1, 0x8000) ADDRESS_MAP_END -static ADDRESS_MAP_START( demoneye_readmem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x01ff) AM_READ(MRA8_RAM) /* Zero page / stack */ - AM_RANGE(0x0200, 0x0fff) AM_READ(MRA8_RAM) /* ? */ - AM_RANGE(0x1000, 0x1fff) AM_READ(MRA8_RAM) /* Scratchpad video RAM */ - AM_RANGE(0x2000, 0x4fff) AM_READ(MRA8_RAM) /* Video RAM */ - AM_RANGE(0x5000, 0x5fff) AM_READ(MRA8_RAM) - AM_RANGE(0x6000, 0xbfff) AM_READ(MRA8_ROM) - AM_RANGE(0xc100, 0xc100) AM_READ(input_port_0_r) - AM_RANGE(0xc110, 0xc110) AM_READ(input_port_1_r) - AM_RANGE(0xc120, 0xc120) AM_READ(input_port_2_r) - AM_RANGE(0xf000, 0xffff) AM_READ(MRA8_ROM) /* remapped ROM for 6502 vectors */ +static ADDRESS_MAP_START( demoneye_main_map, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x1fff) AM_RAM + AM_RANGE(0x2000, 0x3fff) AM_READWRITE(MRA8_RAM, redalert_bitmap_videoram_w) AM_BASE(&redalert_bitmap_videoram) + AM_RANGE(0x4000, 0x4fff) AM_RAM AM_BASE(&redalert_charmap_videoram) + AM_RANGE(0x5000, 0x5fff) AM_RAM +// AM_RANGE(0x5000, 0x53ff) AM_WRITE(MWA8_RAM) AM_BASE(&videoram) AM_SIZE(&videoram_size) +// AM_RANGE(0x5400, 0x57ff) AM_WRITE(MWA8_RAM) AM_BASE(&redalert_spriteram3) +// AM_RANGE(0x5800, 0x5bff) AM_WRITE(MWA8_RAM) //??? +// AM_RANGE(0x5c00, 0x5fff) AM_WRITE(MWA8_RAM) //??? + AM_RANGE(0x6000, 0xbfff) AM_ROM + AM_RANGE(0xc000, 0xc000) AM_MIRROR(0x0f8f) AM_READWRITE(input_port_0_r, MWA8_NOP) + AM_RANGE(0xc010, 0xc010) AM_MIRROR(0x0f8f) AM_READWRITE(input_port_1_r, MWA8_NOP) + AM_RANGE(0xc020, 0xc020) AM_MIRROR(0x0f8f) AM_READWRITE(input_port_2_r, MWA8_NOP) + AM_RANGE(0xc030, 0xc030) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_NOP) + AM_RANGE(0xc040, 0xc040) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE(&redalert_video_control) + AM_RANGE(0xc050, 0xc050) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE(&redalert_bitmap_color) + AM_RANGE(0xc060, 0xc060) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_NOP) + AM_RANGE(0xc070, 0xc070) AM_MIRROR(0x0f8f) AM_READWRITE(MRA8_NOP, MWA8_NOP) + AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION(REGION_CPU1, 0x8000) ADDRESS_MAP_END -static ADDRESS_MAP_START( demoneye_writemem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x01ff) AM_WRITE(MWA8_RAM) - AM_RANGE(0x0200, 0x0fff) AM_WRITE(MWA8_RAM) /* ? */ - AM_RANGE(0x1000, 0x1fff) AM_WRITE(MWA8_RAM) /* Scratchpad video RAM */ - AM_RANGE(0x2000, 0x3fff) AM_WRITE(redalert_backram_w) AM_BASE(&redalert_backram) - AM_RANGE(0x4000, 0x43ff) AM_WRITE(redalert_characterram_w) AM_BASE(&redalert_characterram) - AM_RANGE(0x4400, 0x47ff) AM_WRITE(redalert_spriteram1_w) AM_BASE(&redalert_spriteram1) - AM_RANGE(0x4800, 0x4bff) AM_WRITE(redalert_characterram2_w) AM_BASE(&redalert_characterram2) - AM_RANGE(0x4c00, 0x4fff) AM_WRITE(redalert_spriteram2_w) AM_BASE(&redalert_spriteram2) - AM_RANGE(0x5000, 0x53ff) AM_WRITE(MWA8_RAM) AM_BASE(&videoram) AM_SIZE(&videoram_size) - AM_RANGE(0x5400, 0x57ff) AM_WRITE(redalert_spriteram3_w) AM_BASE(&redalert_spriteram3) - AM_RANGE(0x5800, 0x5bff) AM_WRITE(MWA8_RAM) //??? - AM_RANGE(0x5c00, 0x5fff) AM_WRITE(MWA8_RAM) //??? - AM_RANGE(0x6000, 0xbfff) AM_WRITE(MWA8_ROM) - AM_RANGE(0xc130, 0xc130) AM_WRITE(MWA8_NOP) - AM_RANGE(0xc140, 0xc140) AM_WRITE(demoneye_c040_w) - AM_RANGE(0xc150, 0xc150) AM_WRITE(redalert_backcolor_w) - AM_RANGE(0xc160, 0xc160) AM_WRITE(MWA8_NOP) - AM_RANGE(0xc161, 0xc161) AM_WRITE(MWA8_NOP) - AM_RANGE(0xc162, 0xc162) AM_WRITE(watchdog_reset_w) - AM_RANGE(0xc163, 0xc163) AM_WRITE(MWA8_NOP) - AM_RANGE(0xc170, 0xc170) AM_WRITE(MWA8_NOP) - AM_RANGE(0xf000, 0xffff) AM_WRITE(MWA8_ROM) -ADDRESS_MAP_END +//static ADDRESS_MAP_START( demoneye_sound_readmem, ADDRESS_SPACE_PROGRAM, 8 ) +// AM_RANGE(0x0000, 0x007f) AM_READ(MRA8_RAM) +// AM_RANGE(0x0500, 0x0503) AM_READ(pia_0_r) +// AM_RANGE(0x2000, 0x2fff) AM_READ(MRA8_ROM) +// AM_RANGE(0xf000, 0xffff) AM_READ(MRA8_ROM) +//ADDRESS_MAP_END -static ADDRESS_MAP_START( demoneye_sound_readmem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x007f) AM_READ(MRA8_RAM) - AM_RANGE(0x0500, 0x0503) AM_READ(pia_0_r) - AM_RANGE(0x2000, 0x2fff) AM_READ(MRA8_ROM) - AM_RANGE(0xf000, 0xffff) AM_READ(MRA8_ROM) -ADDRESS_MAP_END +//static ADDRESS_MAP_START( demoneye_sound_writemem, ADDRESS_SPACE_PROGRAM, 8 ) +// AM_RANGE(0x0000, 0x007f) AM_WRITE(MWA8_RAM) +// AM_RANGE(0x0500, 0x0503) AM_WRITE(pia_0_w) +// AM_RANGE(0x2000, 0x2fff) AM_WRITE(MWA8_ROM) +// AM_RANGE(0xf000, 0xffff) AM_WRITE(MWA8_ROM) +//ADDRESS_MAP_END -static ADDRESS_MAP_START( demoneye_sound_writemem, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x007f) AM_WRITE(MWA8_RAM) - AM_RANGE(0x0500, 0x0503) AM_WRITE(pia_0_w) - AM_RANGE(0x2000, 0x2fff) AM_WRITE(MWA8_ROM) - AM_RANGE(0xf000, 0xffff) AM_WRITE(MWA8_ROM) -ADDRESS_MAP_END +/************************************* + * + * Port definitions + * + *************************************/ + static INPUT_PORTS_START( redalert ) - PORT_START /* DIP Switches */ - PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) + PORT_START + PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) ) PORT_DIPLOCATION("SW:1,2") PORT_DIPSETTING( 0x00, "3" ) PORT_DIPSETTING( 0x01, "4" ) PORT_DIPSETTING( 0x02, "5" ) PORT_DIPSETTING( 0x03, "6" ) - PORT_DIPNAME( 0x04, 0x00, "Cabinet in Service Mode" ) + PORT_DIPNAME( 0x04, 0x00, "Cabinet in Service Mode" ) PORT_DIPLOCATION("SW:3") PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) PORT_DIPSETTING( 0x04, DEF_STR( Cocktail ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) + PORT_DIPNAME( 0x08, 0x00, DEF_STR( Bonus_Life ) ) PORT_DIPLOCATION("SW:4") PORT_DIPSETTING( 0x00, "5000" ) PORT_DIPSETTING( 0x08, "7000" ) - PORT_DIPNAME( 0x30, 0x10, DEF_STR( Coinage ) ) + PORT_DIPNAME( 0x30, 0x10, DEF_STR( Coinage ) ) PORT_DIPLOCATION("SW:5,6") PORT_DIPSETTING( 0x30, DEF_STR( 2C_1C ) ) PORT_DIPSETTING( 0x10, DEF_STR( 1C_1C ) ) PORT_DIPSETTING( 0x20, DEF_STR( 1C_2C ) ) PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet ) ) + PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SW:7") PORT_DIPSETTING( 0x40, DEF_STR( Upright ) ) PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) ) - PORT_SERVICE( 0x80, IP_ACTIVE_HIGH ) + PORT_SERVICE_DIPLOC( 0x80, IP_ACTIVE_HIGH, "SW:8" ) PORT_START /* IN1 */ PORT_BIT ( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) @@ -252,210 +271,49 @@ static INPUT_PORTS_START( demoneye ) INPUT_PORTS_END -static const gfx_layout backlayout = -{ - 8,8, /* 8*8 characters */ - 0x400, /* 1024 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* No info needed for bit offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 /* every char takes 8 consecutive bytes */ -}; -static const gfx_layout charlayout = -{ - 8,8, /* 8*8 characters */ - 128, /* 128 characters */ - 1, /* 1 bits per pixel */ - { 0 }, /* No info needed for bit offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 /* every char takes 8 consecutive bytes */ -}; - -static const gfx_layout spritelayout = -{ - 8,8, /* 8*8 characters */ - 128, /* 128 characters */ - 2, /* 2 bits per pixel */ - { 0, 0x800*8 }, /* No info needed for bit offsets */ - { 0, 1, 2, 3, 4, 5, 6, 7 }, - { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, - 8*8 /* every char takes 8 consecutive bytes */ -}; - -static GFXDECODE_START( redalert ) - GFXDECODE_ENTRY( 0, 0x3000, backlayout, 0, 8 ) /* the game dynamically modifies this */ - GFXDECODE_ENTRY( 0, 0x4800, charlayout, 0, 8 ) /* the game dynamically modifies this */ - GFXDECODE_ENTRY( 0, 0x4400, spritelayout,16, 4 ) /* the game dynamically modifies this */ -GFXDECODE_END - -static GFXDECODE_START( demoneye ) - GFXDECODE_ENTRY( 0, 0x3000, backlayout, 0, 8 ) /* the game dynamically modifies this */ - GFXDECODE_ENTRY( 0, 0x4800, spritelayout,16, 4 ) /* the game dynamically modifies this */ - GFXDECODE_ENTRY( 0, 0x4400, spritelayout,16, 4 ) /* the game dynamically modifies this */ - GFXDECODE_ENTRY( 0, 0x5400, spritelayout,16, 4 ) /* the game dynamically modifies this */ -GFXDECODE_END - -/* Arbitrary colortable */ -static const UINT16 colortable_source[] = -{ - 0,7, - 0,6, - 0,2, - 0,4, - 0,3, - 0,6, - 0,1, - 0,8, - - 0,8,8,8, - 0,6,4,7, - 0,6,4,1, - 0,8,5,1, -}; - -static PALETTE_INIT( redalert ) -{ - /* Arbitrary colors */ - palette_set_color(machine,0,MAKE_RGB(0x40,0x80,0xff)); /* Background */ - palette_set_color(machine,1,MAKE_RGB(0x00,0x00,0xff)); /* Blue */ - palette_set_color(machine,2,MAKE_RGB(0xff,0x00,0xff)); /* Magenta */ - palette_set_color(machine,3,MAKE_RGB(0x00,0xff,0xff)); /* Cyan */ - palette_set_color(machine,4,MAKE_RGB(0xff,0x00,0x00)); /* Red */ - palette_set_color(machine,5,MAKE_RGB(0xff,0x80,0x00)); /* Orange */ - palette_set_color(machine,6,MAKE_RGB(0xff,0xff,0x00)); /* Yellow */ - palette_set_color(machine,7,MAKE_RGB(0xff,0xff,0xff)); /* White */ - palette_set_color(machine,8,MAKE_RGB(0x00,0x00,0x00)); /* Black */ - - memcpy(colortable,colortable_source,sizeof(colortable_source)); -} - -static INTERRUPT_GEN( redalert_interrupt ) -{ - if( readinputport(3) ) - { - cpunum_set_input_line(0, INPUT_LINE_NMI, PULSE_LINE); - } - else - { - cpunum_set_input_line(0, 0, HOLD_LINE); - } -} - -static const struct AY8910interface redalert_ay8910_interface = -{ - redalert_AY8910_A_r, /* Port A Read */ - 0, /* Port B Read */ - 0, /* Port A Write */ - redalert_AY8910_B_w /* Port B Write */ -}; +/************************************* + * + * Machine drivers + * + *************************************/ static MACHINE_DRIVER_START( redalert ) /* basic machine hardware */ - MDRV_CPU_ADD(M6502, 1000000) /* ???? */ - MDRV_CPU_PROGRAM_MAP(redalert_readmem,redalert_writemem) + MDRV_CPU_ADD(M6502, MAIN_CPU_CLOCK) + MDRV_CPU_PROGRAM_MAP(redalert_main_map,0) MDRV_CPU_VBLANK_INT(redalert_interrupt,1) - MDRV_CPU_ADD(M6502, 1000000) - /* audio CPU */ /* 1 MHz */ - MDRV_CPU_PROGRAM_MAP(redalert_sound_readmem,redalert_sound_writemem) - /* IRQ is hooked to a 555 timer, whose freq is 1150 Hz */ - MDRV_CPU_PERIODIC_INT(irq0_line_hold,1150) - - MDRV_CPU_ADD(8085A, 2000000) - /* audio CPU */ /* 1 MHz? */ - MDRV_CPU_PROGRAM_MAP(redalert_voice_readmem,redalert_voice_writemem) - - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - /* video hardware */ - MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(32*8, 32*8) - MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MDRV_GFXDECODE(redalert) - MDRV_PALETTE_LENGTH(9) - MDRV_COLORTABLE_LENGTH(sizeof(colortable_source) / sizeof(colortable_source[0])) + MDRV_IMPORT_FROM(redalert_video) - MDRV_PALETTE_INIT(redalert) - MDRV_VIDEO_START(generic) - MDRV_VIDEO_UPDATE(redalert) - - /* sound hardware */ - MDRV_SPEAKER_STANDARD_MONO("mono") - MDRV_SOUND_ADD(AY8910, 2000000) - MDRV_SOUND_CONFIG(redalert_ay8910_interface) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + /* audio hardware */ + MDRV_IMPORT_FROM(redalert_audio) MACHINE_DRIVER_END -/* PIA 0, sound CPU */ -static const pia6821_interface pia_0_intf = -{ - /*inputs : A/B,CA/B1,CA/B2 */ 0, 0, 0, 0, 0, 0, - /*outputs: A/B,CA/B2 */ 0, 0, 0, 0, - /*irqs : A/B */ 0, 0 -}; - -static MACHINE_START( demoneye ) -{ - pia_config(0, &pia_0_intf); -} - -static MACHINE_RESET( demoneye ) -{ - pia_reset(); -} - static MACHINE_DRIVER_START( demoneye ) /* basic machine hardware */ - MDRV_CPU_ADD(M6502, 11730000/2) /* 11.73MHz */ - MDRV_CPU_PROGRAM_MAP(demoneye_readmem,demoneye_writemem) + MDRV_CPU_ADD(M6502, MAIN_CPU_CLOCK) + MDRV_CPU_PROGRAM_MAP(demoneye_main_map,0) MDRV_CPU_VBLANK_INT(redalert_interrupt,1) - MDRV_CPU_ADD(M6802, 3579545) /* 3.579545 MHz */ - /* audio CPU */ - MDRV_CPU_PROGRAM_MAP(demoneye_sound_readmem,demoneye_sound_writemem) - - MDRV_SCREEN_REFRESH_RATE(60) - MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) - - MDRV_MACHINE_START(demoneye) - MDRV_MACHINE_RESET(demoneye) + MDRV_MACHINE_START( demoneye ) + MDRV_MACHINE_RESET( demoneye ) /* video hardware */ - MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) - MDRV_SCREEN_SIZE(32*8, 32*8) - MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) - MDRV_GFXDECODE(demoneye) - MDRV_PALETTE_LENGTH(9) - MDRV_COLORTABLE_LENGTH(sizeof(colortable_source) / sizeof(colortable_source[0])) - - MDRV_PALETTE_INIT(redalert) - MDRV_VIDEO_START(generic) - MDRV_VIDEO_UPDATE(redalert) - - /* sound hardware */ - MDRV_SPEAKER_STANDARD_MONO("mono") - - MDRV_SOUND_ADD(AY8910, 3579545) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) - - MDRV_SOUND_ADD(AY8910, 3579545) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) + MDRV_IMPORT_FROM(redalert_video) MACHINE_DRIVER_END -/*************************************************************************** - Game ROMs -***************************************************************************/ +/************************************* + * + * ROM definitions + * + *************************************/ ROM_START( redalert ) ROM_REGION( 0x10000, REGION_CPU1, 0 ) @@ -463,14 +321,12 @@ ROM_START( redalert ) ROM_LOAD( "rag6", 0x6000, 0x1000, CRC(cb2a308c) SHA1(9f3bc22bad31165e080e81d4a3fb0ec2aad235fe) ) ROM_LOAD( "rag7n", 0x7000, 0x1000, CRC(82ab2dae) SHA1(f8328b048384afac245f1c16a2d0864ffe0b4741) ) ROM_LOAD( "rag8n", 0x8000, 0x1000, CRC(b80eece9) SHA1(d986449bdb1d94832187c7f953f01330391ef4c9) ) - ROM_RELOAD( 0xf000, 0x1000 ) ROM_LOAD( "rag9", 0x9000, 0x1000, CRC(2b7d1295) SHA1(1498af0c55bd38fe79b91afc38921085102ebbc3) ) ROM_LOAD( "ragab", 0xa000, 0x1000, CRC(ab99f5ed) SHA1(a93713bb03d61cce64adc89b874b67adea7c53cd) ) ROM_LOAD( "ragb", 0xb000, 0x1000, CRC(8e0d1661) SHA1(bff4ddca761ddd70113490f50777e62c66813685) ) ROM_REGION( 0x10000, REGION_CPU2, 0 ) - ROM_LOAD( "w3s1", 0x7800, 0x0800, CRC(4af956a5) SHA1(25368a40d7ebc60316fd2d78ec4c686e701b96dc) ) - ROM_RELOAD( 0xf800, 0x0800 ) + ROM_LOAD( "w3s1", 0x7000, 0x0800, CRC(4af956a5) SHA1(25368a40d7ebc60316fd2d78ec4c686e701b96dc) ) ROM_REGION( 0x10000, REGION_CPU3, 0 ) ROM_LOAD( "ras1b", 0x0000, 0x1000, CRC(ec690845) SHA1(26a84738bd45ed21dac6c8383ebd9c3b9831024a) ) @@ -478,64 +334,16 @@ ROM_START( redalert ) ROM_LOAD( "ras3", 0x2000, 0x1000, CRC(20d56f3e) SHA1(5c32ee3365407e6d3f7ab5662e9ecbac437ed4cb) ) ROM_LOAD( "ras4", 0x3000, 0x1000, CRC(130e66db) SHA1(385b8f889fee08fddbb2f75a691af569109eacd1) ) - ROM_REGION( 0x0200, REGION_PROMS, 0 ) /* unknow */ + ROM_REGION( 0x0200, REGION_PROMS, 0 ) /* color PROM */ ROM_LOAD( "m-257sc.1a", 0x0000, 0x0200, CRC(b1aca792) SHA1(db37f99b9880cc3c434e2a55a0bbb017d9a72aa3) ) ROM_END -/******************************************************************** -IREM 'DEMONEYE-X' proto 1981 - -proto sound board - -8910 -6821 8910 -6802 sound6 sound7 - 3.579545MHz - - main board M-27M-C - - 11.73MHz 6502 x x x xx - x x x on - 4116 8 - 4116 - - 4116 9 - 4116 6 - 4116 A - 4116 7 - 4116 B - 4116 - - sub board 1 M-27Sb - - 1a2 - - 2114 - 2114 - 2114 <- two parts piggy-backed - 2114 <- two parts piggy-backed - 2114 2114 - 2114 2114 - -sub board 2 M-42-S - - 1a clr(missing) - - 2114 - 2114 - 2114 - 2114 - 2114 - 2114 - -*********************************************************************/ - ROM_START( demoneye ) ROM_REGION( 0x10000, REGION_CPU1, 0 ) ROM_LOAD( "demoneye.6", 0x6000, 0x1000, CRC(b03ee3a9) SHA1(66b6115fbb4e8097152702022c59c464e8211e5a) ) ROM_LOAD( "demoneye.7", 0x7000, 0x1000, CRC(667a5de7) SHA1(c3ce7fbbc6c98250e9d5f85854e6887017ca5ff9) ) ROM_LOAD( "demoneye.8", 0x8000, 0x1000, CRC(257484d7) SHA1(3937cce546462a471adbdc1da63ddfc20cfc7b79) ) - ROM_RELOAD( 0xf000, 0x1000 ) ROM_LOAD( "demoneye.9", 0x9000, 0x1000, CRC(bd8d79a8) SHA1(68c1443ef78b545eb9e612573b86515c3ad7f103) ) ROM_LOAD( "demoneye.a", 0xa000, 0x1000, CRC(a27d08aa) SHA1(659ad22778e852fc58f3951d62bc01151c973d36) ) ROM_LOAD( "demoneye.b", 0xb000, 0x1000, CRC(1fd3585b) SHA1(b1697b7b21b739499fda1e155530dbfab89f3358) ) @@ -544,10 +352,18 @@ ROM_START( demoneye ) ROM_LOAD( "demoneye.7s", 0x2000, 0x1000, CRC(8fdc9364) SHA1(3fccb5b22f08d6a0cde85863c1ce5399c84f233e) ) ROM_LOAD( "demoneye.6s", 0xf000, 0x1000, CRC(0a23def9) SHA1(b52f52be312ec7810e3c9cbd3913e887f983b1ee) ) - ROM_REGION( 0x0400, REGION_USER1, 0 ) /* unknow */ + ROM_REGION( 0x0400, REGION_PROMS, 0 ) /* unknow */ ROM_LOAD( "demoneye.1a", 0x0000, 0x0200, CRC(d03488ea) SHA1(11027f502ad2a9255b2e5611ab2eee16ede1d704) ) ROM_LOAD( "demoneye.1a2", 0x0200, 0x0200, CRC(eaf5a66e) SHA1(d8ebe05ba5d75fbf6ad45f710e5bd27b6afad44b) ) ROM_END -GAME( 1981, redalert, 0, redalert, redalert, 0, ROT270, "Irem + GDI", "Red Alert", GAME_WRONG_COLORS | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND ) -GAME( 1981, demoneye, 0, demoneye, demoneye, 0, ROT270, "Irem", "Demoneye-X", GAME_WRONG_COLORS | GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND ) + + +/************************************* + * + * Game drivers + * + *************************************/ + +GAME( 1981, redalert, 0, redalert, redalert, 0, ROT270, "Irem + GDI", "Red Alert", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE ) +GAME( 1981, demoneye, 0, demoneye, demoneye, 0, ROT270, "Irem", "Demoneye-X", GAME_WRONG_COLORS | GAME_IMPERFECT_GRAPHICS | GAME_NO_SOUND | GAME_SUPPORTS_SAVE ) diff --git a/src/mame/includes/redalert.h b/src/mame/includes/redalert.h new file mode 100644 index 00000000000..4d7f0a08113 --- /dev/null +++ b/src/mame/includes/redalert.h @@ -0,0 +1,26 @@ +/*************************************************************************** + + Irem Red Alert hardware + + If you have any questions about how this driver works, don't hesitate to + ask. - Mike Balfour (mab22@po.cwru.edu) + +****************************************************************************/ + +/*----------- defined in audio/redalert.c -----------*/ + +WRITE8_HANDLER( redalert_audio_command_w ); +WRITE8_HANDLER( redalert_voice_command_w ); + +MACHINE_DRIVER_EXTERN( redalert_audio ); + + +/*----------- defined in video/redalert.c -----------*/ + +extern UINT8 *redalert_bitmap_videoram; +extern UINT8 *redalert_bitmap_color; +extern UINT8 *redalert_charmap_videoram; +extern UINT8 *redalert_video_control; +WRITE8_HANDLER( redalert_bitmap_videoram_w ); + +MACHINE_DRIVER_EXTERN( redalert_video ); diff --git a/src/mame/video/redalert.c b/src/mame/video/redalert.c index d7770f3c444..0a47620ae47 100644 --- a/src/mame/video/redalert.c +++ b/src/mame/video/redalert.c @@ -1,289 +1,237 @@ /*************************************************************************** - video.c + Irem Red Alert hardware - Functions to emulate the video hardware of the machine. + If you have any questions about how this driver works, don't hesitate to + ask. - Mike Balfour (mab22@po.cwru.edu) -***************************************************************************/ +****************************************************************************/ #include "driver.h" - -UINT8 *redalert_backram; -UINT8 *redalert_spriteram1; -UINT8 *redalert_spriteram2; -UINT8 *redalert_spriteram3; -UINT8 *redalert_characterram; -UINT8 *redalert_characterram2; - -static UINT8 redalert_dirtyback[0x400]; -static UINT8 redalert_dirtycharacter[0x100]; -static UINT8 redalert_dirtycharacter2[0x100]; -static UINT8 redalert_backcolor[0x400]; +#include "video/resnet.h" -/* There might be a color PROM that dictates this? */ -/* These guesses are based on comparing the color bars on the test - screen with the picture in the manual */ -static const UINT8 color_lookup[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,3,3,3,3, - 1,1,1,1,1,1,1,1,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +#define NUM_CHARMAP_PENS 0x200 +#define NUM_BITMAP_PENS 8 - 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, - 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 -}; -static int backcolor, flip=0; -WRITE8_HANDLER( redalert_c040_w ) +/************************************* + * + * Global variables + * + *************************************/ + +UINT8 *redalert_bitmap_videoram; +UINT8 *redalert_bitmap_color; +UINT8 *redalert_charmap_videoram; + +UINT8 *redalert_video_control; + + + +/************************************* + * + * Local variable + * + *************************************/ + +static UINT8 *redalert_bitmap_colorram; + + + +/************************************* + * + * Bitmap videoram write handler + * + *************************************/ + +WRITE8_HANDLER( redalert_bitmap_videoram_w ) { - /* Only seems to load D0-D3 into a flip-flop. */ - /* D0/D1 seem to head off to unconnected circuits */ - /* D2 connects to a "NL" line, and NOTted to a "NH" line */ - /* D3 connects to a "YI" line */ - - /* - D0 == 1 -> 1 player - D1 == 1 and D0 == 1 -> 2 players - */ - flip = !(data & 0x04); + redalert_bitmap_videoram[offset ] = data; + redalert_bitmap_colorram[offset >> 3] = *redalert_bitmap_color & 0x07; } -WRITE8_HANDLER( redalert_backcolor_w ) + + +/************************************* + * + * Color generation + * + *************************************/ + +static void get_pens(pen_t *pens) { - /* Only seems to load D0-D2 into a flip-flop. */ - /* Outputs feed into RAM which seems to feed to RGB lines. */ - backcolor = data & 0x07; -} + static const int resistances_bitmap[] = { 100 }; + static const int resistances_charmap_rg[] = { 390, 220, 180 }; + static const int resistances_charmap_b[] = { 220, 100 }; + static const int resistances_back_r[] = { 1000 + 100 }; + static const int resistances_back_gb[] = { 100 + 470 }; -WRITE8_HANDLER( demoneye_c040_w ) -{ - /* - D0 == 1 -> 1 player - D1 == 1 and D0 == 1 -> 2 players - */ - flip = data & 0x04; -} + offs_t offs; + double scaler; + double bitmap_weight[1]; + double charmap_rg_weights[3]; + double charmap_b_weights[2]; + double back_r_weight[1]; + double back_gb_weight[1]; -/*************************************************************************** -redalert_backram_w -***************************************************************************/ + scaler = compute_resistor_weights(0, 0xff, -1, + 1, resistances_bitmap, bitmap_weight, 470, 0, + 3, resistances_charmap_rg, charmap_rg_weights, 470, 0, + 2, resistances_charmap_b, charmap_b_weights, 470, 0); -WRITE8_HANDLER( redalert_backram_w ) -{ - int charnum; + compute_resistor_weights(0, 0xff, scaler, + 1, resistances_back_r, back_r_weight, 470, 0, + 1, resistances_back_gb, back_gb_weight, 470, 0, + 0, 0, 0, 0, 0); - charnum = offset / 8 % 0x400; - - if ((redalert_backram[offset] != data) || - (redalert_backcolor[charnum] != backcolor)) + /* the character layer colors come from the PROM */ + for (offs = 0; offs < NUM_CHARMAP_PENS; offs++) { - redalert_dirtyback[charnum] = 1; - redalert_backcolor[charnum] = backcolor; + UINT8 data = memory_region(REGION_PROMS)[offs]; - redalert_backram[offset] = data; - } -} + /* very strange mapping */ + UINT8 r0_bit = (data >> 2) & 0x01; + UINT8 r1_bit = (data >> 6) & 0x01; + UINT8 r2_bit = (data >> 4) & 0x01; + UINT8 g0_bit = (data >> 1) & 0x01; + UINT8 g1_bit = (data >> 3) & 0x01; + UINT8 g2_bit = (data >> 5) & 0x01; + UINT8 b0_bit = (data >> 0) & 0x01; + UINT8 b1_bit = (data >> 7) & 0x01; -/*************************************************************************** -redalert_spriteram1_w -***************************************************************************/ + UINT8 r = combine_3_weights(charmap_rg_weights, r0_bit, r1_bit, r2_bit); + UINT8 g = combine_3_weights(charmap_rg_weights, g0_bit, g1_bit, g2_bit); + UINT8 b = combine_2_weights(charmap_b_weights, b0_bit, b1_bit); -WRITE8_HANDLER( redalert_spriteram1_w ) -{ - if (redalert_spriteram1[offset] != data) - { - redalert_dirtycharacter[((offset / 8) % 0x80) + 0x80] = 1; - - redalert_spriteram1[offset] = data; - } -} - -/*************************************************************************** -redalert_spriteram2_w -***************************************************************************/ - -WRITE8_HANDLER( redalert_spriteram2_w ) -{ - if (redalert_spriteram2[offset] != data) - { - - redalert_dirtycharacter[((offset / 8) % 0x80) + 0x80] = 1; - - redalert_spriteram2[offset] = data; - } -} - -/*************************************************************************** -redalert_characterram_w -***************************************************************************/ - -WRITE8_HANDLER( redalert_characterram_w ) -{ - if (redalert_characterram[offset] != data) - { - redalert_dirtycharacter[((offset / 8) % 0x80)] = 1; - - redalert_characterram[offset] = data; - } -} - -WRITE8_HANDLER( redalert_characterram2_w ) -{ - if (redalert_characterram2[offset] != data) - { - redalert_dirtycharacter[((offset / 8) % 0x80)] = 1; - - redalert_characterram2[offset] = data; - } -} - -WRITE8_HANDLER( redalert_spriteram3_w ) -{ - if (redalert_spriteram3[offset] != data) - { - redalert_dirtycharacter2[((offset / 8) % 0x80) + 0x80] = 1; - - redalert_spriteram3[offset] = data; + pens[offs] = MAKE_RGB(r, g, b); } + /* the bitmap layer colors are directly mapped */ + for (offs = 0; offs < NUM_BITMAP_PENS; offs++) + { + UINT8 r_bit = (offs >> 2) & 0x01; + UINT8 g_bit = (offs >> 1) & 0x01; + UINT8 b_bit = (offs >> 0) & 0x01; + + UINT8 r = bitmap_weight[r_bit]; + UINT8 g = bitmap_weight[g_bit]; + UINT8 b = bitmap_weight[b_bit]; + + pens[NUM_CHARMAP_PENS + offs] = MAKE_RGB(r, g, b); + } + + /* background color */ + pens[NUM_CHARMAP_PENS + NUM_BITMAP_PENS] = MAKE_RGB(back_r_weight[0], back_gb_weight[0], back_gb_weight[0]); } -VIDEO_UPDATE( redalert ) + +/************************************* + * + * Video hardware start + * + *************************************/ + +static VIDEO_START( redalert ) { - int offs,i; + redalert_bitmap_colorram = auto_malloc(0x0400); - /* for every character in the Video RAM */ - for (offs = videoram_size - 1;offs >= 0;offs--) + state_save_register_global_pointer(redalert_bitmap_colorram, 0x0400); +} + + + +/************************************* + * + * Video update + * + *************************************/ + +static VIDEO_UPDATE( redalert ) +{ + pen_t pens[NUM_CHARMAP_PENS + NUM_BITMAP_PENS + 1]; + offs_t offs; + + get_pens(pens); + + for (offs = 0; offs < 0x2000; offs++) { - int charcode; - int stat_transparent; - int sx,sy,color; + int i; + UINT8 charmap_data_1; + UINT8 charmap_data_2; - charcode = videoram[offs]; + UINT8 y = offs & 0xff; + UINT8 x = (~offs >> 8) << 3; - /* decode modified background */ - if (redalert_dirtyback[offs] == 1) + UINT8 bitmap_data = redalert_bitmap_videoram[offs]; + UINT8 bitmap_color = redalert_bitmap_colorram[offs >> 3]; + + UINT8 charmap_code = redalert_charmap_videoram[offs >> 3]; + offs_t charmap_data_base = ((charmap_code & 0x7f) << 3) | (offs & 0x07); + + /* D7 of the char code selects the char set to use */ + if (charmap_code & 0x80) { - decodechar(machine->gfx[0],offs,redalert_backram); - redalert_dirtyback[offs] = 2; + charmap_data_1 = redalert_charmap_videoram[0x0400 | charmap_data_base]; + charmap_data_2 = redalert_charmap_videoram[0x0c00 | charmap_data_base]; + } + else + { + charmap_data_1 = 0; /* effectively disables A0 of the color PROM */ + charmap_data_2 = redalert_charmap_videoram[0x0800 | charmap_data_base]; } - /* decode modified characters */ - if (redalert_dirtycharacter[charcode] == 1) + for (i = 0; i < 8; i++) { - if (charcode < 0x80) - decodechar(machine->gfx[1],charcode,redalert_characterram); + pen_t pen; + + int bitmap_bit = bitmap_data & 0x80; + UINT8 color_prom_a0_a1 = ((charmap_data_2 & 0x80) >> 6) | ((charmap_data_1 & 0x80) >> 7); + + /* determine priority */ + if ((color_prom_a0_a1 == 0) || (bitmap_bit && ((charmap_code & 0xc0) == 0xc0))) + pen = bitmap_bit ? pens[NUM_CHARMAP_PENS + bitmap_color] : pens[NUM_CHARMAP_PENS + NUM_BITMAP_PENS]; else - decodechar(machine->gfx[2],charcode-0x80,redalert_spriteram1); - redalert_dirtycharacter[charcode] = 2; - } + pen = pens[((charmap_code & 0xfe) << 1) | color_prom_a0_a1]; - if (redalert_dirtycharacter2[charcode] == 1) - { - decodechar(machine->gfx[3],charcode-0x80,redalert_spriteram3); - redalert_dirtycharacter2[charcode] = 2; - } + if (*redalert_video_control & 0x04) + *BITMAP_ADDR32(bitmap, y, x) = pen; + else + *BITMAP_ADDR32(bitmap, y ^ 0xff, x ^ 0xff) = pen; - sx = 31 - offs / 32; - sy = offs % 32; - - stat_transparent = TRANSPARENCY_NONE; - - /* First layer of color */ - if (charcode >= 0xC0) - { - stat_transparent = TRANSPARENCY_COLOR; - - color = color_lookup[charcode]; - - drawgfx(tmpbitmap,machine->gfx[2], - charcode-0x80, - color, - 0,0, - 8*sx,8*sy, - &machine->screen[0].visarea,TRANSPARENCY_NONE,0); - - if( redalert_dirtycharacter2[charcode] != 0 ) - drawgfx(tmpbitmap,machine->gfx[3], - charcode-0x80, - color, - 0,0, - 8*sx,8*sy, - &machine->screen[0].visarea,TRANSPARENCY_COLOR,0); - - } - - /* Second layer - background */ - color = redalert_backcolor[offs]; - drawgfx(tmpbitmap,machine->gfx[0], - offs, - color, - 0,0, - 8*sx,8*sy, - &machine->screen[0].visarea,stat_transparent,0); - - /* Third layer - alphanumerics & sprites */ - if (charcode < 0x80) - { - color = color_lookup[charcode]; - drawgfx(tmpbitmap,machine->gfx[1], - charcode, - color, - 0,0, - 8*sx,8*sy, - &machine->screen[0].visarea,TRANSPARENCY_COLOR,0); - } - else if (charcode < 0xC0) - { - color = color_lookup[charcode]; - drawgfx(tmpbitmap,machine->gfx[2], - charcode-0x80, - color, - 0,0, - 8*sx,8*sy, - &machine->screen[0].visarea,TRANSPARENCY_COLOR,0); - - if( redalert_dirtycharacter2[charcode] != 0 ) - drawgfx(tmpbitmap,machine->gfx[3], - charcode-0x80, - color, - 0,0, - 8*sx,8*sy, - &machine->screen[0].visarea,TRANSPARENCY_COLOR,0); + /* next pixel */ + x = x + 1; + bitmap_data = bitmap_data << 1; + charmap_data_1 = charmap_data_1 << 1; + charmap_data_2 = charmap_data_2 << 1; } } - for (i = 0;i < 256;i++) - { - if (redalert_dirtycharacter[i] == 2) - redalert_dirtycharacter[i] = 0; - - if (redalert_dirtycharacter2[i] == 2) - redalert_dirtycharacter2[i] = 0; - } - - for (i = 0;i < 0x400;i++) - { - if (redalert_dirtyback[i] == 2) - redalert_dirtyback[i] = 0; - } - - /* copy the character mapped graphics */ - copybitmap(bitmap,tmpbitmap,flip,flip,0,0,cliprect,TRANSPARENCY_NONE,0); - return 0; } + + + +/************************************* + * + * Machine driver + * + *************************************/ + +MACHINE_DRIVER_START( redalert_video ) + + MDRV_SCREEN_REFRESH_RATE(60) + MDRV_SCREEN_VBLANK_TIME(DEFAULT_60HZ_VBLANK_DURATION) + + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + MDRV_VIDEO_START(redalert) + MDRV_VIDEO_UPDATE(redalert) + + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) + MDRV_SCREEN_SIZE(32*8, 32*8) + MDRV_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) + +MACHINE_DRIVER_END