- Complete memory map

- Cyrsals
- Driver state structure
- Text layer is rendered at the same time as the background
This commit is contained in:
Zsolt Vasvari 2008-02-20 05:25:29 +00:00
parent cc998eae3a
commit df91564d03
6 changed files with 486 additions and 370 deletions

1
.gitattributes vendored
View File

@ -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

229
src/mame/audio/jedi.c Normal file
View File

@ -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

View File

@ -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 )

View File

@ -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 );

View File

@ -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 \

View File

@ -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