From df91564d031d23da4140c5490c0e9a50539af803 Mon Sep 17 00:00:00 2001 From: Zsolt Vasvari Date: Wed, 20 Feb 2008 05:25:29 +0000 Subject: [PATCH] - Complete memory map - Cyrsals - Driver state structure - Text layer is rendered at the same time as the background --- .gitattributes | 1 + src/mame/audio/jedi.c | 229 +++++++++++++++++++++++++++++ src/mame/drivers/jedi.c | 304 +++++++++++---------------------------- src/mame/includes/jedi.h | 59 ++++++-- src/mame/mame.mak | 2 +- src/mame/video/jedi.c | 261 ++++++++++++++++----------------- 6 files changed, 486 insertions(+), 370 deletions(-) create mode 100644 src/mame/audio/jedi.c diff --git a/.gitattributes b/.gitattributes index 0dd8ef7fe86..1b18d45d30b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1074,6 +1074,7 @@ src/mame/audio/invinco.c svneol=native#text/plain src/mame/audio/irem.c svneol=native#text/plain src/mame/audio/irem.h svneol=native#text/plain src/mame/audio/jaguar.c svneol=native#text/plain +src/mame/audio/jedi.c svneol=native#text/plain src/mame/audio/laserbat.c svneol=native#text/plain src/mame/audio/leland.c svneol=native#text/plain src/mame/audio/llander.c svneol=native#text/plain diff --git a/src/mame/audio/jedi.c b/src/mame/audio/jedi.c new file mode 100644 index 00000000000..4380363822f --- /dev/null +++ b/src/mame/audio/jedi.c @@ -0,0 +1,229 @@ +/*************************************************************************** + + Atari Return of the Jedi hardware + + driver by Dan Boris + +***************************************************************************/ + +#include "driver.h" +#include "deprecat.h" +#include "cpu/m6502/m6502.h" +#include "sound/5220intf.h" +#include "sound/pokey.h" +#include "jedi.h" + + + +/************************************* + * + * Start + * + *************************************/ + +static SOUND_START( jedi ) +{ + jedi_state *state = machine->driver_data; + + /* set up save state */ + state_save_register_global(state->audio_latch); + state_save_register_global(state->audio_ack_latch); + state_save_register_global(state->speech_strobe_state); +} + + + +/************************************* + * + * Reset + * + *************************************/ + +static SOUND_RESET( jedi ) +{ + jedi_state *state = machine->driver_data; + + /* init globals */ + state->audio_latch = 0; + state->audio_ack_latch = 0; + *state->audio_comm_stat = 0; + *state->speech_data = 0; + state->speech_strobe_state = 0; +} + + + +/************************************* + * + * Interrupt handling + * + *************************************/ + +static WRITE8_HANDLER( irq_ack_w ) +{ + cpunum_set_input_line(Machine, 1, M6502_IRQ_LINE, CLEAR_LINE); +} + + + +/************************************* + * + * Main CPU -> Sound CPU communications + * + *************************************/ + +WRITE8_HANDLER( jedi_audio_reset_w ) +{ + cpunum_set_input_line(Machine, 1, INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE); +} + + +static TIMER_CALLBACK( delayed_audio_latch_w ) +{ + jedi_state *state = machine->driver_data; + + state->audio_latch = param; + *state->audio_comm_stat |= 0x80; +} + + +WRITE8_HANDLER( jedi_audio_latch_w ) +{ + timer_call_after_resynch(NULL, data, delayed_audio_latch_w); +} + + +static READ8_HANDLER( audio_latch_r ) +{ + jedi_state *state = Machine->driver_data; + + *state->audio_comm_stat &= ~0x80; + return state->audio_latch; +} + + +CUSTOM_INPUT( jedi_audio_comm_stat_r ) +{ + jedi_state *state = Machine->driver_data; + + return *state->audio_comm_stat >> 6; +} + + + +/************************************* + * + * Sound CPU -> Main CPU communications + * + *************************************/ + +READ8_HANDLER( jedi_audio_ack_latch_r ) +{ + jedi_state *state = Machine->driver_data; + + *state->audio_comm_stat &= ~0x40; + return state->audio_ack_latch; +} + + +static WRITE8_HANDLER( audio_ack_latch_w ) +{ + jedi_state *state = Machine->driver_data; + + state->audio_ack_latch = data; + *state->audio_comm_stat |= 0x40; +} + + + +/************************************* + * + * Speech access + * + *************************************/ + +static WRITE8_HANDLER( speech_strobe_w ) +{ + jedi_state *state = Machine->driver_data; + int new_speech_strobe_state = (~offset >> 8) & 1; + + if ((new_speech_strobe_state != state->speech_strobe_state) && new_speech_strobe_state) + tms5220_data_w(0, *state->speech_data); + state->speech_strobe_state = new_speech_strobe_state; +} + + +static READ8_HANDLER( speech_ready_r ) +{ + return (!tms5220_ready_r()) << 7; +} + + +static WRITE8_HANDLER( speech_reset_w ) +{ + /* not supported by the TMS5220 emulator */ +} + + + +/************************************* + * + * Audio CPU memory handlers + * + *************************************/ + +static ADDRESS_MAP_START( audio_map, ADDRESS_SPACE_PROGRAM, 8 ) + AM_RANGE(0x0000, 0x07ff) AM_RAM + AM_RANGE(0x0800, 0x080f) AM_MIRROR(0x07c0) AM_READWRITE(pokey1_r, pokey1_w) + AM_RANGE(0x0810, 0x081f) AM_MIRROR(0x07c0) AM_READWRITE(pokey2_r, pokey2_w) + AM_RANGE(0x0820, 0x082f) AM_MIRROR(0x07c0) AM_READWRITE(pokey3_r, pokey3_w) + AM_RANGE(0x0830, 0x083f) AM_MIRROR(0x07c0) AM_READWRITE(pokey4_r, pokey4_w) + AM_RANGE(0x1000, 0x1000) AM_MIRROR(0x00ff) AM_READWRITE(MRA8_NOP, irq_ack_w) + AM_RANGE(0x1100, 0x1100) AM_MIRROR(0x00ff) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE_MEMBER(jedi_state, speech_data) + AM_RANGE(0x1200, 0x13ff) AM_READWRITE(MRA8_NOP, speech_strobe_w) + AM_RANGE(0x1400, 0x1400) AM_MIRROR(0x00ff) AM_READWRITE(MRA8_NOP, audio_ack_latch_w) + AM_RANGE(0x1500, 0x1500) AM_MIRROR(0x00ff) AM_READWRITE(MRA8_NOP, speech_reset_w) + AM_RANGE(0x1600, 0x17ff) AM_NOP + AM_RANGE(0x1800, 0x1800) AM_MIRROR(0x03ff) AM_READWRITE(audio_latch_r, MWA8_NOP) + AM_RANGE(0x1c00, 0x1c00) AM_MIRROR(0x03fe) AM_READWRITE(speech_ready_r, MWA8_NOP) + AM_RANGE(0x1c01, 0x1c01) AM_MIRROR(0x03fe) AM_READWRITE(MRA8_RAM, MWA8_NOP) AM_BASE_MEMBER(jedi_state, audio_comm_stat) + AM_RANGE(0x2000, 0x7fff) AM_NOP + AM_RANGE(0x8000, 0xffff) AM_ROM +ADDRESS_MAP_END + + + +/************************************* + * + * Machine driver + * + *************************************/ + +MACHINE_DRIVER_START( jedi_audio ) + + MDRV_CPU_ADD(M6502, JEDI_AUDIO_CPU_CLOCK) + MDRV_CPU_PROGRAM_MAP(audio_map,0) + + MDRV_SOUND_START(jedi) + MDRV_SOUND_RESET(jedi) + + MDRV_SPEAKER_STANDARD_STEREO("left", "right") + + MDRV_SOUND_ADD(POKEY, JEDI_POKEY_CLOCK) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.30) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.30) + + MDRV_SOUND_ADD(POKEY, JEDI_POKEY_CLOCK) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.30) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.30) + + MDRV_SOUND_ADD(POKEY, JEDI_POKEY_CLOCK) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.30) + + MDRV_SOUND_ADD(POKEY, JEDI_POKEY_CLOCK) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.30) + + MDRV_SOUND_ADD(TMS5220, JEDI_TMS5220_CLOCK) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) + MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) +MACHINE_DRIVER_END diff --git a/src/mame/drivers/jedi.c b/src/mame/drivers/jedi.c index fa5ce824025..69187854719 100644 --- a/src/mame/drivers/jedi.c +++ b/src/mame/drivers/jedi.c @@ -7,6 +7,11 @@ Games supported: * Return of the Jedi + Notes: + * The schematics show the smoothing PROMs as being twice as large, + but the current sizes are confirmed via a PCB. The PROMs + are 82S137 devices. + **************************************************************************** Memory map @@ -108,27 +113,9 @@ #include "driver.h" #include "deprecat.h" #include "cpu/m6502/m6502.h" -#include "sound/5220intf.h" -#include "sound/pokey.h" #include "jedi.h" -/* constants */ -#define MAIN_CPU_OSC 10000000 -#define SOUND_CPU_OSC 12096000 - - -/* local variables */ -static UINT8 control_num; -static UINT8 sound_latch; -static UINT8 sound_ack_latch; -static UINT8 sound_comm_stat; -static UINT8 speech_write_buffer; -static UINT8 speech_strobe_state; -static UINT8 nvram_enabled; - -static emu_timer *jedi_timer; - /************************************* * @@ -138,6 +125,7 @@ static emu_timer *jedi_timer; static TIMER_CALLBACK( generate_interrupt ) { + jedi_state *state = machine->driver_data; int scanline = param; /* IRQ is set by /32V */ @@ -148,7 +136,7 @@ static TIMER_CALLBACK( generate_interrupt ) scanline += 32; if (scanline > 256) scanline = 32; - timer_adjust_oneshot(jedi_timer,video_screen_get_time_until_pos(0, scanline, 0), scanline); + timer_adjust_oneshot(state->interrupt_timer, video_screen_get_time_until_pos(0, scanline, 0), scanline); } @@ -158,42 +146,43 @@ static WRITE8_HANDLER( main_irq_ack_w ) } -static WRITE8_HANDLER( sound_irq_ack_w ) -{ - cpunum_set_input_line(Machine, 1, M6502_IRQ_LINE, CLEAR_LINE); -} +/************************************* + * + * Start + * + *************************************/ static MACHINE_START( jedi ) { + jedi_state *state = machine->driver_data; + /* set a timer to run the interrupts */ - jedi_timer = timer_alloc(generate_interrupt, NULL); - timer_adjust_oneshot(jedi_timer,video_screen_get_time_until_pos(0, 32, 0), 32); + state->interrupt_timer = timer_alloc(generate_interrupt, NULL); + timer_adjust_oneshot(state->interrupt_timer, video_screen_get_time_until_pos(0, 32, 0), 32); /* configure the banks */ memory_configure_bank(1, 0, 3, memory_region(REGION_CPU1) + 0x10000, 0x4000); /* set up save state */ - state_save_register_global(control_num); - state_save_register_global(sound_latch); - state_save_register_global(sound_ack_latch); - state_save_register_global(sound_comm_stat); - state_save_register_global(speech_write_buffer); - state_save_register_global(speech_strobe_state); - state_save_register_global(nvram_enabled); + state_save_register_global(state->nvram_enabled); } + +/************************************* + * + * Reset + * + *************************************/ + static MACHINE_RESET( jedi ) { + jedi_state *state = machine->driver_data; + /* init globals */ - control_num = 0; - sound_latch = 0; - sound_ack_latch = 0; - sound_comm_stat = 0; - speech_write_buffer = 0; - speech_strobe_state = 0; - nvram_enabled = 0; + state->a2d_select = 0; + state->nvram_enabled = 0; } @@ -213,60 +202,6 @@ static WRITE8_HANDLER( rom_banksel_w ) -/************************************* - * - * Main CPU -> Sound CPU communications - * - *************************************/ - -static WRITE8_HANDLER( sound_reset_w ) -{ - cpunum_set_input_line(Machine, 1, INPUT_LINE_RESET, (data & 1) ? CLEAR_LINE : ASSERT_LINE); -} - - -static TIMER_CALLBACK( delayed_sound_latch_w ) -{ - sound_latch = param; - sound_comm_stat |= 0x80; -} - - -static WRITE8_HANDLER( sound_latch_w ) -{ - timer_call_after_resynch(NULL, data, delayed_sound_latch_w); -} - - -static READ8_HANDLER( sound_latch_r ) -{ - sound_comm_stat &= ~0x80; - return sound_latch; -} - - - -/************************************* - * - * Sound CPU -> Main CPU communications - * - *************************************/ - -static READ8_HANDLER( sound_ack_latch_r ) -{ - sound_comm_stat &= ~0x40; - return sound_ack_latch; -} - - -static WRITE8_HANDLER( sound_ack_latch_w ) -{ - sound_ack_latch = data; - sound_comm_stat |= 0x40; -} - - - /************************************* * * I/O ports @@ -275,31 +210,24 @@ static WRITE8_HANDLER( sound_ack_latch_w ) static READ8_HANDLER( a2d_data_r ) { - switch (control_num) + jedi_state *state = Machine->driver_data; + UINT8 ret = 0; + + switch (state->a2d_select) { - case 0: return readinputport(2); - case 2: return readinputport(3); - default: return 0; + case 0: ret = readinputport(2); break; + case 2: ret = readinputport(3); break; } - return 0; -} - -static READ8_HANDLER( special_port1_r ) -{ - return readinputport(1) ^ ((sound_comm_stat >> 1) & 0x60); + return ret; } static WRITE8_HANDLER( a2d_select_w ) { - control_num = offset; -} + jedi_state *state = Machine->driver_data; - -static READ8_HANDLER( soundstat_r ) -{ - return sound_comm_stat; + state->a2d_select = offset; } @@ -310,35 +238,6 @@ static WRITE8_HANDLER( jedi_coin_counter_w ) -/************************************* - * - * Speech access - * - *************************************/ - -static WRITE8_HANDLER( speech_data_w ) -{ - speech_write_buffer = data; -} - - -static WRITE8_HANDLER( speech_strobe_w ) -{ - int state = (~offset >> 8) & 1; - - if ((state ^ speech_strobe_state) && state) - tms5220_data_w(0, speech_write_buffer); - speech_strobe_state = state; -} - - -static READ8_HANDLER( speech_ready_r ) -{ - return (!tms5220_ready_r()) << 7; -} - - - /************************************* * * NVRAM @@ -347,14 +246,18 @@ static READ8_HANDLER( speech_ready_r ) static WRITE8_HANDLER( nvram_data_w ) { - if (nvram_enabled) + jedi_state *state = Machine->driver_data; + + if (state->nvram_enabled) generic_nvram[offset] = data; } static WRITE8_HANDLER( nvram_enable_w ) { - nvram_enabled = ~offset & 1; + jedi_state *state = Machine->driver_data; + + state->nvram_enabled = ~offset & 1; } @@ -367,60 +270,39 @@ static WRITE8_HANDLER( nvram_enable_w ) static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 8 ) AM_RANGE(0x0000, 0x07ff) AM_RAM - AM_RANGE(0x0800, 0x08ff) AM_READWRITE(MRA8_RAM, nvram_data_w) AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size) - AM_RANGE(0x0c00, 0x0c00) AM_READ(input_port_0_r) - AM_RANGE(0x0c01, 0x0c01) AM_READ(special_port1_r) - AM_RANGE(0x1400, 0x1400) AM_READ(sound_ack_latch_r) - AM_RANGE(0x1800, 0x1800) AM_READ(a2d_data_r) - AM_RANGE(0x1c00, 0x1c01) AM_WRITE(nvram_enable_w) - AM_RANGE(0x1c80, 0x1c82) AM_WRITE(a2d_select_w) - AM_RANGE(0x1d00, 0x1d00) AM_WRITE(MWA8_NOP) /* NVRAM store */ - AM_RANGE(0x1d80, 0x1d80) AM_WRITE(watchdog_reset_w) - AM_RANGE(0x1e00, 0x1e00) AM_WRITE(main_irq_ack_w) - AM_RANGE(0x1e80, 0x1e81) AM_WRITE(jedi_coin_counter_w) - AM_RANGE(0x1e82, 0x1e83) AM_WRITE(MWA8_NOP) /* LED control; not used */ - AM_RANGE(0x1e84, 0x1e84) AM_WRITE(MWA8_RAM) AM_BASE(&jedi_foreground_bank) - AM_RANGE(0x1e86, 0x1e86) AM_WRITE(sound_reset_w) - AM_RANGE(0x1e87, 0x1e87) AM_WRITE(jedi_video_off_w) - AM_RANGE(0x1f00, 0x1f00) AM_WRITE(sound_latch_w) - AM_RANGE(0x1f80, 0x1f80) AM_WRITE(rom_banksel_w) - AM_RANGE(0x2000, 0x27ff) AM_RAM AM_BASE(&jedi_backgroundram) - AM_RANGE(0x2800, 0x2fff) AM_RAM AM_BASE(&jedi_paletteram) - AM_RANGE(0x3000, 0x37bf) AM_RAM AM_BASE(&jedi_foregroundram) - AM_RANGE(0x37c0, 0x3bff) AM_RAM AM_BASE(&jedi_spriteram) - AM_RANGE(0x3c00, 0x3c01) AM_WRITE(jedi_vscroll_w) - AM_RANGE(0x3d00, 0x3d01) AM_WRITE(jedi_hscroll_w) - AM_RANGE(0x3e00, 0x3fff) AM_WRITE(jedi_PIXIRAM_w) + AM_RANGE(0x0800, 0x08ff) AM_MIRROR(0x0380) AM_READWRITE(MRA8_RAM, nvram_data_w) AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size) + AM_RANGE(0x0c00, 0x0c00) AM_MIRROR(0x03fe) AM_READWRITE(input_port_0_r, MWA8_NOP) + AM_RANGE(0x0c01, 0x0c01) AM_MIRROR(0x03fe) AM_READWRITE(input_port_1_r, MWA8_NOP) + AM_RANGE(0x1000, 0x13ff) AM_NOP + AM_RANGE(0x1400, 0x1400) AM_MIRROR(0x03ff) AM_READWRITE(jedi_audio_ack_latch_r, MWA8_NOP) + AM_RANGE(0x1800, 0x1800) AM_MIRROR(0x03ff) AM_READWRITE(a2d_data_r, MWA8_NOP) + AM_RANGE(0x1c00, 0x1c01) AM_MIRROR(0x007f) AM_READWRITE(MRA8_NOP, nvram_enable_w) + AM_RANGE(0x1c80, 0x1c82) AM_MIRROR(0x0078) AM_READWRITE(MRA8_NOP, a2d_select_w) + AM_RANGE(0x1c83, 0x1c87) AM_MIRROR(0x0078) AM_NOP + AM_RANGE(0x1d00, 0x1d00) AM_MIRROR(0x007f) AM_READWRITE(MRA8_NOP, MWA8_NOP) /* write: NVRAM store */ + AM_RANGE(0x1d80, 0x1d80) AM_MIRROR(0x007f) AM_READWRITE(MRA8_NOP, watchdog_reset_w) + AM_RANGE(0x1e00, 0x1e00) AM_MIRROR(0x007f) AM_READWRITE(MRA8_NOP, main_irq_ack_w) + AM_RANGE(0x1e80, 0x1e81) AM_MIRROR(0x0078) AM_READWRITE(MRA8_NOP, jedi_coin_counter_w) + AM_RANGE(0x1e82, 0x1e83) AM_MIRROR(0x0078) AM_READWRITE(MRA8_NOP, MWA8_NOP) /* write: LED control - not used */ + AM_RANGE(0x1e84, 0x1e84) AM_MIRROR(0x0078) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE_MEMBER(jedi_state, foreground_bank) + AM_RANGE(0x1e85, 0x1e85) AM_MIRROR(0x0078) AM_NOP + AM_RANGE(0x1e86, 0x1e86) AM_MIRROR(0x0078) AM_READWRITE(MRA8_NOP, jedi_audio_reset_w) + AM_RANGE(0x1e87, 0x1e87) AM_MIRROR(0x0078) AM_READWRITE(MRA8_NOP, MWA8_RAM) AM_BASE_MEMBER(jedi_state, video_off) + AM_RANGE(0x1f00, 0x1f00) AM_MIRROR(0x007f) AM_READWRITE(MRA8_NOP, jedi_audio_latch_w) + AM_RANGE(0x1f80, 0x1f80) AM_MIRROR(0x007f) AM_READWRITE(MRA8_NOP, rom_banksel_w) + AM_RANGE(0x2000, 0x27ff) AM_RAM AM_BASE_MEMBER(jedi_state, backgroundram) + AM_RANGE(0x2800, 0x2fff) AM_RAM AM_BASE_MEMBER(jedi_state, paletteram) + AM_RANGE(0x3000, 0x37bf) AM_RAM AM_BASE_MEMBER(jedi_state, foregroundram) + AM_RANGE(0x37c0, 0x3bff) AM_RAM AM_BASE_MEMBER(jedi_state, spriteram) + AM_RANGE(0x3c00, 0x3c01) AM_MIRROR(0x00fe) AM_READWRITE(MRA8_NOP, jedi_vscroll_w) + AM_RANGE(0x3d00, 0x3d01) AM_MIRROR(0x00fe) AM_READWRITE(MRA8_NOP, jedi_hscroll_w) + AM_RANGE(0x3e00, 0x3e00) AM_MIRROR(0x01ff) AM_WRITE(MWA8_RAM) AM_BASE_MEMBER(jedi_state, smoothing_table) AM_RANGE(0x4000, 0x7fff) AM_ROMBANK(1) AM_RANGE(0x8000, 0xffff) AM_ROM ADDRESS_MAP_END -/************************************* - * - * Sound CPU memory handlers - * - *************************************/ - -static ADDRESS_MAP_START( sound_map, ADDRESS_SPACE_PROGRAM, 8 ) - AM_RANGE(0x0000, 0x07ff) AM_RAM - AM_RANGE(0x0800, 0x080f) AM_READWRITE(pokey1_r, pokey1_w) - AM_RANGE(0x0810, 0x081f) AM_READWRITE(pokey2_r, pokey2_w) - AM_RANGE(0x0820, 0x082f) AM_READWRITE(pokey3_r, pokey3_w) - AM_RANGE(0x0830, 0x083f) AM_READWRITE(pokey4_r, pokey4_w) - AM_RANGE(0x1000, 0x1000) AM_WRITE(sound_irq_ack_w) - AM_RANGE(0x1100, 0x11ff) AM_WRITE(speech_data_w) - AM_RANGE(0x1200, 0x13ff) AM_WRITE(speech_strobe_w) - AM_RANGE(0x1400, 0x1400) AM_WRITE(sound_ack_latch_w) - AM_RANGE(0x1800, 0x1800) AM_READ(sound_latch_r) - AM_RANGE(0x1c00, 0x1c00) AM_READ(speech_ready_r) - AM_RANGE(0x1c01, 0x1c01) AM_READ(soundstat_r) - AM_RANGE(0x8000, 0xffff) AM_ROM -ADDRESS_MAP_END - - - /************************************* * * Port definitions @@ -442,7 +324,7 @@ static INPUT_PORTS_START( jedi ) PORT_BIT( 0x03, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_TILT ) PORT_BIT( 0x18, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x60, IP_ACTIVE_HIGH, IPT_SPECIAL ) /* sound comm */ + PORT_BIT( 0x60, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(jedi_audio_comm_stat_r, 0) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_VBLANK ) PORT_START /* analog Y */ @@ -462,14 +344,12 @@ INPUT_PORTS_END static MACHINE_DRIVER_START( jedi ) + MDRV_DRIVER_DATA(jedi_state) + /* basic machine hardware */ - MDRV_CPU_ADD(M6502,MAIN_CPU_OSC/2/2) /* 2.5MHz */ + MDRV_CPU_ADD(M6502, JEDI_MAIN_CPU_CLOCK) MDRV_CPU_PROGRAM_MAP(main_map,0) - MDRV_CPU_ADD(M6502,SOUND_CPU_OSC/2/4) /* 1.5MHz */ - MDRV_CPU_PROGRAM_MAP(sound_map,0) - - MDRV_SCREEN_REFRESH_RATE(60) MDRV_INTERLEAVE(4) MDRV_MACHINE_START(jedi) @@ -477,34 +357,10 @@ static MACHINE_DRIVER_START( jedi ) MDRV_NVRAM_HANDLER(generic_0fill) /* video hardware */ - MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) - MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) - MDRV_SCREEN_SIZE(64*8, 262) /* verify vert size */ - MDRV_SCREEN_VISIBLE_AREA(0*8, 37*8-1, 0*8, 30*8-1) + MDRV_IMPORT_FROM(jedi_video) - MDRV_VIDEO_START(jedi) - MDRV_VIDEO_UPDATE(jedi) - - /* sound hardware */ - MDRV_SPEAKER_STANDARD_STEREO("left", "right") - - MDRV_SOUND_ADD(POKEY, SOUND_CPU_OSC/2/4) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.30) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.30) - - MDRV_SOUND_ADD(POKEY, SOUND_CPU_OSC/2/4) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.30) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.30) - - MDRV_SOUND_ADD(POKEY, SOUND_CPU_OSC/2/4) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 0.30) - - MDRV_SOUND_ADD(POKEY, SOUND_CPU_OSC/2/4) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 0.30) - - MDRV_SOUND_ADD(TMS5220, SOUND_CPU_OSC/2/9) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.0) - MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.0) + /* audio hardware */ + MDRV_IMPORT_FROM(jedi_audio) MACHINE_DRIVER_END @@ -541,8 +397,8 @@ ROM_START( jedi ) ROM_LOAD( "136030-129.01k", 0x18000, 0x8000, CRC(ac86b98c) SHA1(9f86c8801a7293fa46e9432f1651dd85bf00f4b9) ) ROM_REGION( 0x1000, REGION_PROMS, 0 ) /* background smoothing */ - ROM_LOAD( "136030-117.bin", 0x0000, 0x0400, CRC(9831bd55) SHA1(12945ef2d1582914125b9ee591567034d71d6573) ) /* Prom is a 82S137 */ - ROM_LOAD( "136030-118.bin", 0x0800, 0x0400, CRC(261fbfe7) SHA1(efc65a74a3718563a07b718e34d8a7aa23339a69) ) /* Prom is a 82S137 */ + ROM_LOAD( "136030-117.bin", 0x0000, 0x0400, CRC(9831bd55) SHA1(12945ef2d1582914125b9ee591567034d71d6573) ) + ROM_LOAD( "136030-118.bin", 0x0800, 0x0400, CRC(261fbfe7) SHA1(efc65a74a3718563a07b718e34d8a7aa23339a69) ) ROM_END @@ -553,4 +409,4 @@ ROM_END * *************************************/ -GAME( 1984, jedi, 0, jedi, jedi, 0, ROT0, "Atari", "Return of the Jedi", GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE ) +GAME( 1984, jedi, 0, jedi, jedi, 0, ROT0, "Atari", "Return of the Jedi", GAME_SUPPORTS_SAVE ) diff --git a/src/mame/includes/jedi.h b/src/mame/includes/jedi.h index 4535d463f3e..2150fb25e92 100644 --- a/src/mame/includes/jedi.h +++ b/src/mame/includes/jedi.h @@ -4,18 +4,57 @@ *************************************************************************/ + +/* oscillators and clocks */ +#define JEDI_MAIN_CPU_OSC (XTAL_10MHz) +#define JEDI_AUDIO_CPU_OSC (XTAL_12_096MHz) +#define JEDI_MAIN_CPU_CLOCK (JEDI_MAIN_CPU_OSC / 4) +#define JEDI_AUDIO_CPU_CLOCK (JEDI_AUDIO_CPU_OSC / 8) +#define JEDI_POKEY_CLOCK (JEDI_AUDIO_CPU_CLOCK) +#define JEDI_TMS5220_CLOCK (JEDI_AUDIO_CPU_OSC / 2 / 9) /* div by 9 is via a binary counter that counts from 7 to 16 */ + + +typedef struct _jedi_state jedi_state; +struct _jedi_state +{ + /* machine state */ + UINT8 a2d_select; + UINT8 nvram_enabled; + emu_timer *interrupt_timer; + + /* video state */ + UINT8 *foregroundram; + UINT8 *backgroundram; + UINT8 *spriteram; + UINT8 *paletteram; + UINT8 *foreground_bank; + UINT8 *video_off; + UINT8 *smoothing_table; + UINT32 vscroll; + UINT32 hscroll; + + /* audio state */ + UINT8 audio_latch; + UINT8 audio_ack_latch; + UINT8 *audio_comm_stat; + UINT8 *speech_data; + UINT8 speech_strobe_state; +}; + + +/*----------- defined in audio/jedi.c -----------*/ + +MACHINE_DRIVER_EXTERN( jedi_audio ); + +WRITE8_HANDLER( jedi_audio_reset_w ); +WRITE8_HANDLER( jedi_audio_latch_w ); +READ8_HANDLER( jedi_audio_ack_latch_r ); +CUSTOM_INPUT( jedi_audio_comm_stat_r ); + + /*----------- defined in video/jedi.c -----------*/ -extern UINT8 *jedi_foregroundram; -extern UINT8 *jedi_backgroundram; -extern UINT8 *jedi_spriteram; -extern UINT8 *jedi_paletteram; -extern UINT8 *jedi_foreground_bank; - -VIDEO_START( jedi ); -VIDEO_UPDATE( jedi ); +MACHINE_DRIVER_EXTERN( jedi_video ); WRITE8_HANDLER( jedi_vscroll_w ); WRITE8_HANDLER( jedi_hscroll_w ); -WRITE8_HANDLER( jedi_video_off_w ); -WRITE8_HANDLER( jedi_PIXIRAM_w ); diff --git a/src/mame/mame.mak b/src/mame/mame.mak index 1dcaa175b22..2eb0bbafc68 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -490,7 +490,7 @@ $(MAMEOBJ)/atari.a: \ $(DRIVERS)/gauntlet.o $(VIDEO)/gauntlet.o \ $(DRIVERS)/harddriv.o $(MACHINE)/harddriv.o $(AUDIO)/harddriv.o $(VIDEO)/harddriv.o \ $(DRIVERS)/irobot.o $(MACHINE)/irobot.o $(VIDEO)/irobot.o \ - $(DRIVERS)/jedi.o $(VIDEO)/jedi.o \ + $(DRIVERS)/jedi.o $(AUDIO)/jedi.o $(VIDEO)/jedi.o \ $(DRIVERS)/klax.o $(VIDEO)/klax.o \ $(DRIVERS)/liberatr.o $(VIDEO)/liberatr.o \ $(DRIVERS)/mediagx.o \ diff --git a/src/mame/video/jedi.c b/src/mame/video/jedi.c index 3e9a9aa272f..f2181e5b341 100644 --- a/src/mame/video/jedi.c +++ b/src/mame/video/jedi.c @@ -2,6 +2,8 @@ Atari Return of the Jedi hardware + driver by Dan Boris + Return of the Jedi has a peculiar playfield/motion object priority system. That is, there is no priority system ;-) The color of the pixel which appears on screen depends on @@ -13,40 +15,27 @@ ***************************************************************************/ #include "driver.h" +#include "deprecat.h" #include "jedi.h" #define NUM_PENS (0x1000) -/* globals */ -UINT8 *jedi_foregroundram; -UINT8 *jedi_backgroundram; -UINT8 *jedi_spriteram; -UINT8 *jedi_paletteram; -UINT8 *jedi_foreground_bank; - -/* local variables */ -static UINT32 jedi_vscroll; -static UINT32 jedi_hscroll; -static UINT8 video_off; -static UINT8 smoothing_table; - - /************************************* * - * Video startup + * Start * *************************************/ -VIDEO_START( jedi ) +static VIDEO_START( jedi ) { + jedi_state *state = machine->driver_data; + /* register for saving */ - state_save_register_global(jedi_vscroll); - state_save_register_global(jedi_hscroll); - state_save_register_global(video_off); - state_save_register_global(smoothing_table); + state_save_register_global(state->vscroll); + state_save_register_global(state->hscroll); } @@ -77,7 +66,7 @@ VIDEO_START( jedi ) * *************************************/ -static void get_pens(pen_t *pens) +static void get_pens(jedi_state *state, pen_t *pens) { offs_t offs; @@ -85,7 +74,7 @@ static void get_pens(pen_t *pens) { int r, g, b, bits, intensity; - UINT16 color = jedi_paletteram[offs] | (jedi_paletteram[offs | 0x400] << 8); + UINT16 color = state->paletteram[offs] | (state->paletteram[offs | 0x400] << 8); intensity = (color >> 9) & 7; bits = (color >> 6) & 7; @@ -100,12 +89,12 @@ static void get_pens(pen_t *pens) } -static void do_pen_lookup(mame_bitmap *bitmap, const rectangle *cliprect) +static void do_pen_lookup(jedi_state *state, mame_bitmap *bitmap, const rectangle *cliprect) { int y, x; pen_t pens[NUM_PENS]; - get_pens(pens); + get_pens(state, pens); for (y = cliprect->min_y; y <= cliprect->max_y; y++) for(x = cliprect->min_x; x <= cliprect->max_x; x++) @@ -122,139 +111,116 @@ static void do_pen_lookup(mame_bitmap *bitmap, const rectangle *cliprect) WRITE8_HANDLER( jedi_vscroll_w ) { - jedi_vscroll = data | (offset << 8); + jedi_state *state = Machine->driver_data; + + state->vscroll = data | (offset << 8); } WRITE8_HANDLER( jedi_hscroll_w ) { - jedi_hscroll = data | (offset << 8); + jedi_state *state = Machine->driver_data; + + state->hscroll = data | (offset << 8); } /************************************* * - * Video control + * Background/text layer drawing + * with smoothing * *************************************/ -WRITE8_HANDLER( jedi_video_off_w ) -{ - video_off = data; -} - - -WRITE8_HANDLER( jedi_PIXIRAM_w ) -{ - /* this should really be 0x07, but the PROMs were - dumped at half size */ - smoothing_table = data & 0x03; -} - - - -/************************************* - * - * Foreground drawing - * - *************************************/ - -static void draw_foreground(mame_bitmap *bitmap) -{ - offs_t offs; - UINT32 *dst = BITMAP_ADDR32(bitmap, 0, 0); - - /* draw the bitmap 4 pixels at a time */ - for (offs = 0; offs < 0x7c00; offs++) - { - UINT16 code = ((*jedi_foreground_bank & 0x80) << 1) | - jedi_foregroundram[((offs & 0x7c00) >> 4) | ((offs & 0x7e) >> 1)]; - - UINT8 data = memory_region(REGION_GFX1)[(code << 4) | ((offs & 0x380) >> 6) | (offs & 0x01)]; - - /* the background pixel determines pen address bits A8 and A9 */ - dst[0] = (dst[0] & 0xff) | ((data & 0xc0) << 2); - dst[1] = (dst[1] & 0xff) | ((data & 0x30) << 4); - dst[2] = (dst[2] & 0xff) | ((data & 0x0c) << 6); - dst[3] = (dst[3] & 0xff) | ((data & 0x03) << 8); - - dst = dst + 4; - } -} - - - -/************************************* - * - * Background drawing with smoothing - * - *************************************/ - -static void draw_and_smooth_background(mame_bitmap *bitmap, const rectangle *cliprect) +static void draw_background_and_text(jedi_state *state, mame_bitmap *bitmap, const rectangle *cliprect) { int y; - UINT32 background_line_buffer[0x200]; /* RAM chip at 2A */ + int background_line_buffer[0x200]; /* RAM chip at 2A */ - UINT8 *prom1 = &memory_region(REGION_PROMS)[0x0000 | (smoothing_table << 8)]; - UINT8 *prom2 = &memory_region(REGION_PROMS)[0x0800 | (smoothing_table << 8)]; + UINT8 *tx_gfx = memory_region(REGION_GFX1); + UINT8 *bg_gfx = memory_region(REGION_GFX2); + UINT8 *prom1 = &memory_region(REGION_PROMS)[0x0000 | ((*state->smoothing_table & 0x03) << 8)]; + UINT8 *prom2 = &memory_region(REGION_PROMS)[0x0800 | ((*state->smoothing_table & 0x03) << 8)]; + int vscroll = state->vscroll; + int hscroll = state->hscroll; + int tx_bank = *state->foreground_bank; + UINT8 *tx_ram = state->foregroundram; + UINT8 *bg_ram = state->backgroundram; - memset(background_line_buffer, 0, 0x200 * sizeof(UINT32)); + memset(background_line_buffer, 0, 0x200 * sizeof(int)); for (y = cliprect->min_y; y <= cliprect->max_y; y++) { int x; - UINT32 last_col = 0; + int bg_last_col = 0; for (x = cliprect->min_x; x <= cliprect->max_x; x += 2) { - UINT32 col; - UINT32 tempcol; - offs_t gfx_offs; - UINT8 data1; - UINT8 data2; + int tx_col1, tx_col2, bg_col; + int bg_tempcol; + offs_t tx_gfx_offs, bg_gfx_offs; + int tx_data, bg_data1, bg_data2; - int sy = y + jedi_vscroll; - int sx = x + jedi_hscroll; + int sy = y + vscroll; + int sx = x + hscroll; - offs_t backgroundram_offs = ((sy & 0x1f0) << 1) | ((sx & 0x1f0) >> 4); + /* determine offsets into video memory */ + offs_t tx_offs = ((y & 0xf8) << 3) | (x >> 3); + offs_t bg_offs = ((sy & 0x1f0) << 1) | ((sx & 0x1f0) >> 4); - /* shuffle the bank bits in */ - UINT8 bank = jedi_backgroundram[0x0400 | backgroundram_offs]; - UINT16 code = jedi_backgroundram[0x0000 | backgroundram_offs] | - ((bank & 0x01) << 8) | - ((bank & 0x08) << 6) | - ((bank & 0x02) << 9); + /* get the character codes */ + int tx_code = ((tx_bank & 0x80) << 1) | tx_ram[tx_offs]; + int bg_bank = bg_ram[0x0400 | bg_offs]; + int bg_code = bg_ram[0x0000 | bg_offs] | + ((bg_bank & 0x01) << 8) | + ((bg_bank & 0x08) << 6) | + ((bg_bank & 0x02) << 9); - /* flip X */ - if (bank & 0x04) + /* background flip X */ + if (bg_bank & 0x04) sx = sx ^ 0x0f; - /* get the pointer to the graphics */ - gfx_offs = (code << 4) | (sy & 0x0e) | (((sx & 0x08) >> 3)); + /* calculate the address of the gfx data */ + tx_gfx_offs = (tx_code << 4) | ((y & 0x07) << 1) | ((( x & 0x04) >> 2)); + bg_gfx_offs = (bg_code << 4) | (sy & 0x0e) | (((sx & 0x08) >> 3)); - data1 = memory_region(REGION_GFX2)[0x0000 | gfx_offs]; - data2 = memory_region(REGION_GFX2)[0x8000 | gfx_offs]; + /* get the gfx data */ + tx_data = tx_gfx[ tx_gfx_offs]; + bg_data1 = bg_gfx[0x0000 | bg_gfx_offs]; + bg_data2 = bg_gfx[0x8000 | bg_gfx_offs]; - /* the foreground pixel determines pen address bits A0-A3 */ + /* the text layer pixel determines pen address bits A8 and A9 */ + if (x & 0x02) + { + tx_col1 = ((tx_data & 0x0c) << 6); + tx_col2 = ((tx_data & 0x03) << 8); + } + else + { + tx_col1 = ((tx_data & 0xc0) << 2); + tx_col2 = ((tx_data & 0x30) << 4); + } + + /* the background pixel determines pen address bits A0-A3 */ switch (sx & 0x06) { - case 0x00: col = ((data1 & 0x80) >> 4) | ((data1 & 0x08) >> 1) | ((data2 & 0x80) >> 6) | ((data2 & 0x08) >> 3); break; - case 0x02: col = ((data1 & 0x40) >> 3) | ((data1 & 0x04) >> 0) | ((data2 & 0x40) >> 5) | ((data2 & 0x04) >> 2); break; - case 0x04: col = ((data1 & 0x20) >> 2) | ((data1 & 0x02) << 1) | ((data2 & 0x20) >> 4) | ((data2 & 0x02) >> 1); break; - default: col = ((data1 & 0x10) >> 1) | ((data1 & 0x01) << 2) | ((data2 & 0x10) >> 3) | ((data2 & 0x01) >> 0); break; + case 0x00: bg_col = ((bg_data1 & 0x80) >> 4) | ((bg_data1 & 0x08) >> 1) | ((bg_data2 & 0x80) >> 6) | ((bg_data2 & 0x08) >> 3); break; + case 0x02: bg_col = ((bg_data1 & 0x40) >> 3) | ((bg_data1 & 0x04) >> 0) | ((bg_data2 & 0x40) >> 5) | ((bg_data2 & 0x04) >> 2); break; + case 0x04: bg_col = ((bg_data1 & 0x20) >> 2) | ((bg_data1 & 0x02) << 1) | ((bg_data2 & 0x20) >> 4) | ((bg_data2 & 0x02) >> 1); break; + default: bg_col = ((bg_data1 & 0x10) >> 1) | ((bg_data1 & 0x01) << 2) | ((bg_data2 & 0x10) >> 3) | ((bg_data2 & 0x01) >> 0); break; } /* the first pixel is smoothed via a lookup using the current and last pixel value - the next pixel just uses the current value directly. After we done with a pixel save it for later in the line buffer RAM */ - tempcol = prom1[(last_col << 4) | col]; - *BITMAP_ADDR32(bitmap, y, x + 0) = prom2[(background_line_buffer[x + 0] << 4) | tempcol]; - *BITMAP_ADDR32(bitmap, y, x + 1) = prom2[(background_line_buffer[x + 1] << 4) | col]; - background_line_buffer[x + 0] = tempcol; - background_line_buffer[x + 1] = col; + bg_tempcol = prom1[(bg_last_col << 4) | bg_col]; + *BITMAP_ADDR32(bitmap, y, x + 0) = tx_col1 | prom2[(background_line_buffer[x + 0] << 4) | bg_tempcol]; + *BITMAP_ADDR32(bitmap, y, x + 1) = tx_col2 | prom2[(background_line_buffer[x + 1] << 4) | bg_col]; + background_line_buffer[x + 0] = bg_tempcol; + background_line_buffer[x + 1] = bg_col; - last_col = col; + bg_last_col = bg_col; } } } @@ -267,9 +233,10 @@ static void draw_and_smooth_background(mame_bitmap *bitmap, const rectangle *cli * *************************************/ -static void draw_sprites(mame_bitmap *bitmap) +static void draw_sprites(jedi_state *state, mame_bitmap *bitmap, const rectangle *cliprect) { offs_t offs; + UINT8 *spriteram = state->spriteram; for (offs = 0x00; offs < 0x30; offs++) { @@ -278,16 +245,16 @@ static void draw_sprites(mame_bitmap *bitmap) UINT8 *gfx; /* coordinates adjustments made to match screenshot */ - UINT8 y = 240 - jedi_spriteram[offs + 0x80] + 1; - int flip_x = jedi_spriteram[offs + 0x40] & 0x10; - int flip_y = jedi_spriteram[offs + 0x40] & 0x20; - int tall = jedi_spriteram[offs + 0x40] & 0x08; + UINT8 y = 240 - spriteram[offs + 0x80] + 1; + int flip_x = spriteram[offs + 0x40] & 0x10; + int flip_y = spriteram[offs + 0x40] & 0x20; + int tall = spriteram[offs + 0x40] & 0x08; /* shuffle the bank bits in */ - UINT16 code = jedi_spriteram[offs] | - ((jedi_spriteram[offs + 0x40] & 0x04) << 8) | - ((jedi_spriteram[offs + 0x40] & 0x40) << 3) | - ((jedi_spriteram[offs + 0x40] & 0x02) << 7); + UINT16 code = spriteram[offs] | + ((spriteram[offs + 0x40] & 0x04) << 8) | + ((spriteram[offs + 0x40] & 0x40) << 3) | + ((spriteram[offs + 0x40] & 0x02) << 7); /* adjust for double-height */ if (tall) @@ -307,7 +274,10 @@ static void draw_sprites(mame_bitmap *bitmap) for (sy = 0; sy < y_size; sy++) { int i; - UINT16 x = jedi_spriteram[offs + 0x100] + ((jedi_spriteram[offs + 0x40] & 0x01) << 8) - 2; + UINT16 x = spriteram[offs + 0x100] + ((spriteram[offs + 0x40] & 0x01) << 8) - 2; + + if ((y < cliprect->min_y) || (y > cliprect->max_y)) + continue; if (flip_x) x = x + 7; @@ -357,21 +327,42 @@ static void draw_sprites(mame_bitmap *bitmap) * *************************************/ -VIDEO_UPDATE( jedi ) +static VIDEO_UPDATE( jedi ) { + jedi_state *state = machine->driver_data; + /* if no video, clear it all to black */ - if (video_off) + if (*state->video_off & 0x01) fillbitmap(bitmap, RGB_BLACK, cliprect); else { - /* draw the background - it needs to be done first */ - draw_and_smooth_background(bitmap, cliprect); - - draw_foreground(bitmap); - draw_sprites(bitmap); - - do_pen_lookup(bitmap, cliprect); + /* draw the background/text layers, followed by the sprites + - it needs to be done in this order*/ + draw_background_and_text(state, bitmap, cliprect); + draw_sprites(state, bitmap, cliprect); + do_pen_lookup(state, bitmap, cliprect); } return 0; } + + + +/************************************* + * + * Machine driver + * + *************************************/ + +MACHINE_DRIVER_START( jedi_video ) + + MDRV_SCREEN_REFRESH_RATE(60) + + MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER) + MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) + MDRV_SCREEN_SIZE(64*8, 262) /* verify vert size */ + MDRV_SCREEN_VISIBLE_AREA(0*8, 37*8-1, 0*8, 30*8-1) + + MDRV_VIDEO_START(jedi) + MDRV_VIDEO_UPDATE(jedi) +MACHINE_DRIVER_END