From 2dd1a7191fe3f785de1b56f2a07ed9ce5dd2d302 Mon Sep 17 00:00:00 2001 From: Aaron Giles Date: Sun, 19 Sep 2010 20:46:16 +0000 Subject: [PATCH] Converted amiga drivers to use driver_devices. Merged common code between legacy Amiga and AGA video systems. [Atari Ace] From: Atari Ace Date: Sun, Sep 19, 2010 at 4:17 PM Subject: [patch] Implement amiga_state To: submit@mamedev.org Cc: atariace@hotmail.com Hi mamedev, These two patches add an amiga_state class to the amiga drivers. The first adds missing machine, device params to external functions, makes akiko a proper device and adjusts video/amiga.c and video/amigaaga.c to be more similar. The second patch then implements the classes, also merging ~300 lines of identical code in amigaaga.c. More code code be merged if desired with a little more effort. ~aa --- src/mame/audio/amiga.c | 40 +-- src/mame/drivers/alg.c | 89 ++++-- src/mame/drivers/arcadia.c | 46 +-- src/mame/drivers/cubocd32.c | 209 +++++++------ src/mame/drivers/mquake.c | 11 +- src/mame/drivers/upscope.c | 14 +- src/mame/includes/amiga.h | 120 +++++-- src/mame/includes/cubocd32.h | 19 +- src/mame/machine/amiga.c | 290 ++++++++--------- src/mame/machine/cubocd32.c | 457 ++++++++++++++------------- src/mame/video/amiga.c | 374 +++++++++++----------- src/mame/video/amigaaga.c | 587 ++++++++--------------------------- 12 files changed, 1036 insertions(+), 1220 deletions(-) diff --git a/src/mame/audio/amiga.c b/src/mame/audio/amiga.c index c2449ca7fdd..9f94ea8f929 100644 --- a/src/mame/audio/amiga.c +++ b/src/mame/audio/amiga.c @@ -63,16 +63,13 @@ struct _amiga_audio }; +INLINE amiga_audio *get_safe_token( running_device *device ) +{ + assert(device != NULL); + assert(device->type() == AMIGA); -/************************************* - * - * Globals - * - *************************************/ - -static amiga_audio *audio_state; - - + return (amiga_audio *)downcast(device)->token(); +} /************************************* * @@ -86,7 +83,7 @@ static TIMER_CALLBACK( signal_irq ) } -static void dma_reload(audio_channel *chan) +static void dma_reload(amiga_state *state, audio_channel *chan) { chan->curlocation = CUSTOM_REG_LONG(REG_AUD0LCH + chan->index * 8); chan->curlength = CUSTOM_REG(REG_AUD0LEN + chan->index * 8); @@ -102,8 +99,10 @@ static void dma_reload(audio_channel *chan) * *************************************/ -void amiga_audio_data_w(int which, UINT16 data) +void amiga_audio_data_w(running_device *device, int which, UINT16 data) { + amiga_audio *audio_state = get_safe_token(device); + audio_state->channel[which].manualmode = TRUE; } @@ -115,8 +114,10 @@ void amiga_audio_data_w(int which, UINT16 data) * *************************************/ -void amiga_audio_update(void) +void amiga_audio_update(running_device *device) { + amiga_audio *audio_state = get_safe_token(device); + stream_update(audio_state->stream); } @@ -124,6 +125,7 @@ void amiga_audio_update(void) static STREAM_UPDATE( amiga_stream_update ) { + amiga_state *state = device->machine->driver_data(); amiga_audio *audio = (amiga_audio *)param; int channum, sampoffs = 0; @@ -148,7 +150,7 @@ static STREAM_UPDATE( amiga_stream_update ) { audio_channel *chan = &audio->channel[channum]; if (!chan->dmaenabled && ((CUSTOM_REG(REG_DMACON) >> channum) & 1)) - dma_reload(chan); + dma_reload(state, chan); chan->dmaenabled = (CUSTOM_REG(REG_DMACON) >> channum) & 1; } @@ -223,13 +225,13 @@ static STREAM_UPDATE( amiga_stream_update ) chan->curlocation++; if (chan->dmaenabled && !(chan->curlocation & 1)) { - CUSTOM_REG(REG_AUD0DAT + channum * 8) = amiga_chip_ram_r(chan->curlocation); + CUSTOM_REG(REG_AUD0DAT + channum * 8) = (*state->chip_ram_r)(state, chan->curlocation); if (chan->curlength != 0) chan->curlength--; /* if we run out of data, reload the dma */ if (chan->curlength == 0) - dma_reload(chan); + dma_reload(state, chan); } /* latch the next byte of the sample */ @@ -263,15 +265,13 @@ static STREAM_UPDATE( amiga_stream_update ) static DEVICE_START( amiga_sound ) { - running_machine *machine = device->machine; + amiga_audio *audio_state = get_safe_token(device); int i; - /* allocate a new audio state */ - audio_state = (amiga_audio *)downcast(device)->token(); for (i = 0; i < 4; i++) { audio_state->channel[i].index = i; - audio_state->channel[i].irq_timer = timer_alloc(machine, signal_irq, NULL); + audio_state->channel[i].irq_timer = timer_alloc(device->machine, signal_irq, NULL); } /* create the stream */ @@ -284,7 +284,7 @@ DEVICE_GET_INFO( amiga_sound ) switch (state) { /* --- the following bits of info are returned as 64-bit signed integers --- */ - case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(*audio_state); break; + case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(amiga_audio); break; /* --- the following bits of info are returned as pointers to data or functions --- */ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(amiga_sound); break; diff --git a/src/mame/drivers/alg.c b/src/mame/drivers/alg.c index 2161c5cfbf2..f6ddd2c3dff 100644 --- a/src/mame/drivers/alg.c +++ b/src/mame/drivers/alg.c @@ -29,10 +29,18 @@ #include "machine/nvram.h" -static running_device *laserdisc; -static emu_timer *serial_timer; -static UINT8 serial_timer_active; -static UINT16 input_select; +class alg_state : public amiga_state +{ +public: + alg_state(running_machine &machine, const driver_device_config_base &config) + : amiga_state(machine, config) { } + + + running_device *laserdisc; + emu_timer *serial_timer; + UINT8 serial_timer_active; + UINT16 input_select; +}; static TIMER_CALLBACK( response_timer ); @@ -74,7 +82,7 @@ static VIDEO_START( alg ) /* configure pen 4096 as transparent in the renderer and use it for the genlock color */ palette_set_color(machine, 4096, MAKE_ARGB(0,0,0,0)); - amiga_set_genlock_color(4096); + amiga_set_genlock_color(machine, 4096); } @@ -87,10 +95,11 @@ static VIDEO_START( alg ) static MACHINE_START( alg ) { - laserdisc = machine->device("laserdisc"); + alg_state *state = machine->driver_data(); + state->laserdisc = machine->device("laserdisc"); - serial_timer = timer_alloc(machine, response_timer, NULL); - serial_timer_active = FALSE; + state->serial_timer = timer_alloc(machine, response_timer, NULL); + state->serial_timer_active = FALSE; } @@ -109,44 +118,50 @@ static MACHINE_RESET( alg ) static TIMER_CALLBACK( response_timer ) { + alg_state *state = machine->driver_data(); + /* if we still have data to send, do it now */ - if (laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) + if (laserdisc_line_r(state->laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) { - UINT8 data = laserdisc_data_r(laserdisc); + UINT8 data = laserdisc_data_r(state->laserdisc); if (data != 0x0a) mame_printf_debug("Sending serial data = %02X\n", data); amiga_serial_in_w(machine, data); } /* if there's more to come, set another timer */ - if (laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) - timer_adjust_oneshot(serial_timer, amiga_get_serial_char_period(machine), 0); + if (laserdisc_line_r(state->laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) + timer_adjust_oneshot(state->serial_timer, amiga_get_serial_char_period(machine), 0); else - serial_timer_active = FALSE; + state->serial_timer_active = FALSE; } static void vsync_callback(running_machine *machine) { + alg_state *state = machine->driver_data(); + /* if we have data available, set a timer to read it */ - if (!serial_timer_active && laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) + if (!state->serial_timer_active && laserdisc_line_r(state->laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) { - timer_adjust_oneshot(serial_timer, amiga_get_serial_char_period(machine), 0); - serial_timer_active = TRUE; + timer_adjust_oneshot(state->serial_timer, amiga_get_serial_char_period(machine), 0); + state->serial_timer_active = TRUE; } } static void serial_w(running_machine *machine, UINT16 data) { + alg_state *state = machine->driver_data(); + /* write to the laserdisc player */ - laserdisc_data_w(laserdisc, data & 0xff); + laserdisc_data_w(state->laserdisc, data & 0xff); /* if we have data available, set a timer to read it */ - if (!serial_timer_active && laserdisc_line_r(laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) + if (!state->serial_timer_active && laserdisc_line_r(state->laserdisc, LASERDISC_LINE_DATA_AVAIL) == ASSERT_LINE) { - timer_adjust_oneshot(serial_timer, amiga_get_serial_char_period(machine), 0); - serial_timer_active = TRUE; + timer_adjust_oneshot(state->serial_timer, amiga_get_serial_char_period(machine), 0); + state->serial_timer_active = TRUE; } } @@ -160,33 +175,40 @@ static void serial_w(running_machine *machine, UINT16 data) static void alg_potgo_w(running_machine *machine, UINT16 data) { + alg_state *state = machine->driver_data(); + /* bit 15 controls whether pin 9 is input/output */ /* bit 14 controls the value, which selects which player's controls to read */ - input_select = (data & 0x8000) ? ((data >> 14) & 1) : 0; + state->input_select = (data & 0x8000) ? ((data >> 14) & 1) : 0; } static CUSTOM_INPUT( lightgun_pos_r ) { + alg_state *state = field->port->machine->driver_data(); int x = 0, y = 0; /* get the position based on the input select */ - get_lightgun_pos(*field->port->machine->primary_screen, input_select, &x, &y); + get_lightgun_pos(*field->port->machine->primary_screen, state->input_select, &x, &y); return (y << 8) | (x >> 2); } static CUSTOM_INPUT( lightgun_trigger_r ) { + alg_state *state = field->port->machine->driver_data(); + /* read the trigger control based on the input select */ - return (input_port_read(field->port->machine, "TRIGGERS") >> input_select) & 1; + return (input_port_read(field->port->machine, "TRIGGERS") >> state->input_select) & 1; } static CUSTOM_INPUT( lightgun_holster_r ) { + alg_state *state = field->port->machine->driver_data(); + /* read the holster control based on the input select */ - return (input_port_read(field->port->machine, "TRIGGERS") >> (2 + input_select)) & 1; + return (input_port_read(field->port->machine, "TRIGGERS") >> (2 + state->input_select)) & 1; } @@ -257,9 +279,9 @@ static WRITE8_DEVICE_HANDLER( alg_cia_1_porta_w ) static ADDRESS_MAP_START( main_map_r1, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(alg_state, chip_ram, chip_ram_size) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE(&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE_MEMBER(alg_state, custom_regs) AM_RANGE(0xe80000, 0xe8ffff) AM_READWRITE(amiga_autoconfig_r, amiga_autoconfig_w) AM_RANGE(0xfc0000, 0xffffff) AM_ROM AM_REGION("user1", 0) /* System ROM */ @@ -270,9 +292,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( main_map_r2, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(alg_state, chip_ram, chip_ram_size) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE(&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE_MEMBER(alg_state, custom_regs) AM_RANGE(0xe80000, 0xe8ffff) AM_READWRITE(amiga_autoconfig_r, amiga_autoconfig_w) AM_RANGE(0xfc0000, 0xffffff) AM_ROM AM_REGION("user1", 0) /* System ROM */ @@ -283,9 +305,9 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( main_map_picmatic, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(alg_state, chip_ram, chip_ram_size) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE(&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE_MEMBER(alg_state, custom_regs) AM_RANGE(0xe80000, 0xe8ffff) AM_READWRITE(amiga_autoconfig_r, amiga_autoconfig_w) AM_RANGE(0xfc0000, 0xffffff) AM_ROM AM_REGION("user1", 0) /* System ROM */ @@ -404,7 +426,7 @@ static const mos6526_interface cia_1_intf = DEVCB_NULL /* port B */ }; -static MACHINE_CONFIG_START( alg_r1, driver_device ) +static MACHINE_CONFIG_START( alg_r1, alg_state ) /* basic machine hardware */ MDRV_CPU_ADD("maincpu", M68000, AMIGA_68000_NTSC_CLOCK) @@ -418,7 +440,7 @@ static MACHINE_CONFIG_START( alg_r1, driver_device ) MDRV_LASERDISC_OVERLAY(amiga, 512*2, 262, BITMAP_FORMAT_INDEXED16) MDRV_LASERDISC_OVERLAY_CLIP((129-8)*2, (449+8-1)*2, 44-8, 244+8-1) - /* video hardware */ + /* video hardware */ MDRV_LASERDISC_SCREEN_ADD_NTSC("screen", BITMAP_FORMAT_INDEXED16) MDRV_SCREEN_REFRESH_RATE(59.997) MDRV_SCREEN_SIZE(512*2, 262) @@ -658,6 +680,7 @@ ROM_END static void alg_init(running_machine *machine) { + alg_state *state = machine->driver_data(); static const amiga_machine_interface alg_intf = { ANGUS_CHIP_RAM_MASK, @@ -672,7 +695,7 @@ static void alg_init(running_machine *machine) amiga_machine_config(machine, &alg_intf); /* set up memory */ - memory_configure_bank(machine, "bank1", 0, 1, amiga_chip_ram, 0); + memory_configure_bank(machine, "bank1", 0, 1, state->chip_ram, 0); memory_configure_bank(machine, "bank1", 1, 1, memory_region(machine, "user1"), 0); } diff --git a/src/mame/drivers/arcadia.c b/src/mame/drivers/arcadia.c index 46c04643279..92c086f28cd 100644 --- a/src/mame/drivers/arcadia.c +++ b/src/mame/drivers/arcadia.c @@ -55,13 +55,14 @@ -/************************************* - * - * Globals - * - *************************************/ +class arcadia_state : public amiga_state +{ +public: + arcadia_state(running_machine &machine, const driver_device_config_base &config) + : amiga_state(machine, config) { } -static UINT8 coin_counter[2]; + UINT8 coin_counter[2]; +}; @@ -136,6 +137,8 @@ static WRITE8_DEVICE_HANDLER( arcadia_cia_0_portb_w ) /* writing a 0 in the low bit clears one of the coins */ if ((data & 1) == 0) { + UINT8 *coin_counter = device->machine->driver_data()->coin_counter; + if (coin_counter[0] > 0) coin_counter[0]--; else if (coin_counter[1] > 0) @@ -153,23 +156,29 @@ static WRITE8_DEVICE_HANDLER( arcadia_cia_0_portb_w ) static CUSTOM_INPUT( coin_counter_r ) { + int coin = (FPTR)param; + UINT8 *coin_counter = field->port->machine->driver_data()->coin_counter; + /* return coin counter values */ - return *(UINT8 *)param & 3; + return coin_counter[coin] & 3; } static INPUT_CHANGED( coin_changed_callback ) { - UINT8 *counter = (UINT8 *)param; + int coin = (FPTR)param; + UINT8 *coin_counter = field->port->machine->driver_data()->coin_counter; /* check for a 0 -> 1 transition */ - if (!oldval && newval && *counter < 3) - *counter += 1; + if (!oldval && newval && coin_counter[coin] < 3) + coin_counter[coin] += 1; } static void arcadia_reset_coins(running_machine *machine) { + UINT8 *coin_counter = machine->driver_data()->coin_counter; + /* reset coin counters */ coin_counter[0] = coin_counter[1] = 0; } @@ -184,9 +193,9 @@ static void arcadia_reset_coins(running_machine *machine) static ADDRESS_MAP_START( amiga_map, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(arcadia_state, chip_ram, chip_ram_size) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE(&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE_MEMBER(arcadia_state, custom_regs) AM_RANGE(0xe80000, 0xe8ffff) AM_READWRITE(amiga_autoconfig_r, amiga_autoconfig_w) AM_RANGE(0xf80000, 0xffffff) AM_ROM AM_REGION("user1", 0) /* Kickstart BIOS */ @@ -218,8 +227,8 @@ static INPUT_PORTS_START( arcadia ) PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_LOW ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) - PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(coin_counter_r, &coin_counter[0]) - PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(coin_counter_r, &coin_counter[1]) + PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(coin_counter_r, 0) + PORT_BIT( 0xc0, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(coin_counter_r, 1) PORT_START("JOY0DAT") PORT_BIT( 0x0303, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM(amiga_joystick_convert, "P1JOY") @@ -249,8 +258,8 @@ static INPUT_PORTS_START( arcadia ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_START("COINS") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_changed_callback, &coin_counter[0]) - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED(coin_changed_callback, &coin_counter[1]) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_CHANGED(coin_changed_callback, 0) + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_CHANGED(coin_changed_callback, 1) INPUT_PORTS_END @@ -287,7 +296,7 @@ static const mos6526_interface cia_1_intf = DEVCB_NULL }; -static MACHINE_CONFIG_START( arcadia, driver_device ) +static MACHINE_CONFIG_START( arcadia, arcadia_state ) /* basic machine hardware */ MDRV_CPU_ADD("maincpu", M68000, AMIGA_68000_NTSC_CLOCK) @@ -753,6 +762,7 @@ INLINE void generic_decode(running_machine *machine, const char *tag, int bit7, static void arcadia_init(running_machine *machine) { + arcadia_state *state = machine->driver_data(); static const amiga_machine_interface arcadia_intf = { ANGUS_CHIP_RAM_MASK, @@ -768,7 +778,7 @@ static void arcadia_init(running_machine *machine) amiga_machine_config(machine, &arcadia_intf); /* set up memory */ - memory_configure_bank(machine, "bank1", 0, 1, amiga_chip_ram, 0); + memory_configure_bank(machine, "bank1", 0, 1, state->chip_ram, 0); memory_configure_bank(machine, "bank1", 1, 1, memory_region(machine, "user1"), 0); /* OnePlay bios is encrypted, TenPlay is not */ diff --git a/src/mame/drivers/cubocd32.c b/src/mame/drivers/cubocd32.c index 3972c6a62b9..8b2bb74534e 100644 --- a/src/mame/drivers/cubocd32.c +++ b/src/mame/drivers/cubocd32.c @@ -338,7 +338,7 @@ routines : #define MGNUMBER_USE_JOY 1 -static void handle_cd32_joystick_cia(UINT8 pra, UINT8 dra); +static void handle_cd32_joystick_cia(running_machine *machine, UINT8 pra, UINT8 dra); static WRITE32_HANDLER( aga_overlay_w ) { @@ -382,7 +382,7 @@ static WRITE8_DEVICE_HANDLER( cd32_cia_0_porta_w ) /* bit 2 = Power Led on Amiga */ set_led_status(device->machine, 0, (data & 2) ? 0 : 1); - handle_cd32_joystick_cia(data, mos6526_r(device, 2)); + handle_cd32_joystick_cia(device->machine, data, mos6526_r(device, 2)); } /************************************* @@ -415,13 +415,13 @@ static WRITE8_DEVICE_HANDLER( cd32_cia_0_portb_w ) static ADDRESS_MAP_START( cd32_map, ADDRESS_SPACE_PROGRAM, 32 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x1fffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram32) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x1fffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(cubocd32_state, chip_ram, chip_ram_size) AM_RANGE(0x800000, 0x800003) AM_READ_PORT("DIPSW1") AM_RANGE(0x800010, 0x800013) AM_READ_PORT("DIPSW2") - AM_RANGE(0xb80000, 0xb8003f) AM_READWRITE(amiga_akiko32_r, amiga_akiko32_w) + AM_RANGE(0xb80000, 0xb8003f) AM_DEVREADWRITE("akiko", amiga_akiko32_r, amiga_akiko32_w) AM_RANGE(0xbfa000, 0xbfa003) AM_WRITE(aga_overlay_w) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE16(amiga_cia_r, amiga_cia_w, 0xffffffff) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE16(amiga_custom_r, amiga_custom_w, 0xffffffff) AM_BASE((UINT32**)&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE16(amiga_custom_r, amiga_custom_w, 0xffffffff) AM_BASE_MEMBER(cubocd32_state, custom_regs) AM_RANGE(0xe00000, 0xe7ffff) AM_ROM AM_REGION("user1", 0x80000) /* CD32 Extended ROM */ AM_RANGE(0xa00000, 0xf7ffff) AM_NOP AM_RANGE(0xf80000, 0xffffff) AM_ROM AM_REGION("user1", 0x0) /* Kickstart */ @@ -433,98 +433,97 @@ ADDRESS_MAP_END * *************************************/ -static UINT16 potgo_value = 0; -static int cd32_shifter[2]; -static void (*cubocd32_input_hack)(running_machine *machine) = 0; - static void cubocd32_potgo_w(running_machine *machine, UINT16 data) { + cubocd32_state *state = machine->driver_data(); int i; - if (cubocd32_input_hack != NULL) - cubocd32_input_hack(machine); + if (state->input_hack != NULL) + (*state->input_hack)(machine); - potgo_value = potgo_value & 0x5500; - potgo_value |= data & 0xaa00; + state->potgo_value = state->potgo_value & 0x5500; + state->potgo_value |= data & 0xaa00; - for (i = 0; i < 8; i += 2) + for (i = 0; i < 8; i += 2) { UINT16 dir = 0x0200 << i; if (data & dir) { UINT16 d = 0x0100 << i; - potgo_value &= ~d; - potgo_value |= data & d; + state->potgo_value &= ~d; + state->potgo_value |= data & d; } - } - for (i = 0; i < 2; i++) + } + for (i = 0; i < 2; i++) { - UINT16 p5dir = 0x0200 << (i * 4); /* output enable P5 */ - UINT16 p5dat = 0x0100 << (i * 4); /* data P5 */ - if ((potgo_value & p5dir) && (potgo_value & p5dat)) - cd32_shifter[i] = 8; - } + UINT16 p5dir = 0x0200 << (i * 4); /* output enable P5 */ + UINT16 p5dat = 0x0100 << (i * 4); /* data P5 */ + if ((state->potgo_value & p5dir) && (state->potgo_value & p5dat)) + state->cd32_shifter[i] = 8; + } } -static void handle_cd32_joystick_cia(UINT8 pra, UINT8 dra) +static void handle_cd32_joystick_cia(running_machine *machine, UINT8 pra, UINT8 dra) { - static int oldstate[2]; - int i; + cubocd32_state *state = machine->driver_data(); + int i; - for (i = 0; i < 2; i++) + for (i = 0; i < 2; i++) { UINT8 but = 0x40 << i; UINT16 p5dir = 0x0200 << (i * 4); /* output enable P5 */ UINT16 p5dat = 0x0100 << (i * 4); /* data P5 */ - if (!(potgo_value & p5dir) || !(potgo_value & p5dat)) + if (!(state->potgo_value & p5dir) || !(state->potgo_value & p5dat)) { - if ((dra & but) && (pra & but) != oldstate[i]) + if ((dra & but) && (pra & but) != state->oldstate[i]) { if (!(pra & but)) { - cd32_shifter[i]--; - if (cd32_shifter[i] < 0) - cd32_shifter[i] = 0; + state->cd32_shifter[i]--; + if (state->cd32_shifter[i] < 0) + state->cd32_shifter[i] = 0; } } } - oldstate[i] = pra & but; - } + state->oldstate[i] = pra & but; + } } -static UINT16 handle_joystick_potgor (running_machine *machine, UINT16 potgor) +static UINT16 handle_joystick_potgor(running_machine *machine, UINT16 potgor) { + cubocd32_state *state = machine->driver_data(); static const char *const player_portname[] = { "P2", "P1" }; - int i; + int i; - for (i = 0; i < 2; i++) + for (i = 0; i < 2; i++) { UINT16 p9dir = 0x0800 << (i * 4); /* output enable P9 */ UINT16 p9dat = 0x0400 << (i * 4); /* data P9 */ UINT16 p5dir = 0x0200 << (i * 4); /* output enable P5 */ UINT16 p5dat = 0x0100 << (i * 4); /* data P5 */ - /* p5 is floating in input-mode */ - potgor &= ~p5dat; - potgor |= potgo_value & p5dat; - if (!(potgo_value & p9dir)) + /* p5 is floating in input-mode */ + potgor &= ~p5dat; + potgor |= state->potgo_value & p5dat; + if (!(state->potgo_value & p9dir)) potgor |= p9dat; - /* P5 output and 1 -> shift register is kept reset (Blue button) */ - if ((potgo_value & p5dir) && (potgo_value & p5dat)) - cd32_shifter[i] = 8; - /* shift at 1 == return one, >1 = return button states */ - if (cd32_shifter[i] == 0) + /* P5 output and 1 -> shift register is kept reset (Blue button) */ + if ((state->potgo_value & p5dir) && (state->potgo_value & p5dat)) + state->cd32_shifter[i] = 8; + /* shift at 1 == return one, >1 = return button states */ + if (state->cd32_shifter[i] == 0) potgor &= ~p9dat; /* shift at zero == return zero */ - if (cd32_shifter[i] >= 2 && (input_port_read(machine, player_portname[i]) & (1 << (cd32_shifter[i] - 2)))) + if (state->cd32_shifter[i] >= 2 && (input_port_read(machine, player_portname[i]) & (1 << (state->cd32_shifter[i] - 2)))) potgor &= ~p9dat; - } - return potgor; + } + return potgor; } static CUSTOM_INPUT(cubo_input) { - return handle_joystick_potgor(field->port->machine, potgo_value) >> 10; + cubocd32_state *state = field->port->machine->driver_data(); + return handle_joystick_potgor(field->port->machine, state->potgo_value) >> 10; } static INPUT_PORTS_START( cd32 ) @@ -1051,11 +1050,12 @@ static const i2cmem_interface i2cmem_interface = I2CMEM_SLAVE_ADDRESS, NVRAM_PAGE_SIZE, NVRAM_SIZE }; -static MACHINE_CONFIG_START( cd32, driver_device ) +static MACHINE_CONFIG_START( cd32, cubocd32_state ) /* basic machine hardware */ MDRV_CPU_ADD("maincpu", M68EC020, AMIGA_68EC020_PAL_CLOCK) /* 14.3 Mhz */ MDRV_CPU_PROGRAM_MAP(cd32_map) + MDRV_DEVICE_ADD("akiko", AKIKO, 0) MDRV_MACHINE_RESET(amiga) @@ -1075,15 +1075,15 @@ static MACHINE_CONFIG_START( cd32, driver_device ) MDRV_VIDEO_UPDATE(amiga_aga) /* sound hardware */ - MDRV_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") + MDRV_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") - MDRV_SOUND_ADD("amiga", AMIGA, 3579545) - MDRV_SOUND_ROUTE(0, "lspeaker", 0.25) - MDRV_SOUND_ROUTE(1, "rspeaker", 0.25) - MDRV_SOUND_ROUTE(2, "rspeaker", 0.25) - MDRV_SOUND_ROUTE(3, "lspeaker", 0.25) + MDRV_SOUND_ADD("amiga", AMIGA, 3579545) + MDRV_SOUND_ROUTE(0, "lspeaker", 0.25) + MDRV_SOUND_ROUTE(1, "rspeaker", 0.25) + MDRV_SOUND_ROUTE(2, "rspeaker", 0.25) + MDRV_SOUND_ROUTE(3, "lspeaker", 0.25) - MDRV_SOUND_ADD( "cdda", CDDA, 0 ) + MDRV_SOUND_ADD( "cdda", CDDA, 0 ) MDRV_SOUND_ROUTE( 0, "lspeaker", 0.50 ) MDRV_SOUND_ROUTE( 1, "rspeaker", 0.50 ) @@ -1157,6 +1157,7 @@ ROM_END static DRIVER_INIT( cd32 ) { + cubocd32_state *state = machine->driver_data(); static const amiga_machine_interface cubocd32_intf = { AGA_CHIP_RAM_MASK, @@ -1171,14 +1172,11 @@ static DRIVER_INIT( cd32 ) amiga_machine_config(machine, &cubocd32_intf); /* set up memory */ - memory_configure_bank(machine, "bank1", 0, 1, amiga_chip_ram32, 0); + memory_configure_bank(machine, "bank1", 0, 1, state->chip_ram, 0); memory_configure_bank(machine, "bank1", 1, 1, memory_region(machine, "user1"), 0); - /* intialize akiko */ - amiga_akiko_init(machine); - /* input hack */ - cubocd32_input_hack = NULL; + state->input_hack = NULL; } @@ -1190,126 +1188,147 @@ static DRIVER_INIT( cd32 ) static void cndypuzl_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w(0x051c02, 0x0000); + //(*state->chip_ram_w)(0x051c02, 0x0000); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - amiga_chip_ram_w(r_A5 - 0x7ebe, 0x0000); + (*state->chip_ram_w)(state, r_A5 - 0x7ebe, 0x0000); } } static DRIVER_INIT(cndypuzl) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = cndypuzl_input_hack; + state->input_hack = cndypuzl_input_hack; } static void haremchl_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w8(0x002907, 0x00); + //amiga_chip_ram_w8(state, 0x002907, 0x00); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - UINT32 r_A2 = (amiga_chip_ram_r(r_A5 - 0x7f00 + 0) << 16) | (amiga_chip_ram_r(r_A5 - 0x7f00 + 2)); - amiga_chip_ram_w8(r_A2 + 0x1f, 0x00); + UINT32 r_A2 = ((*state->chip_ram_r)(state, r_A5 - 0x7f00 + 0) << 16) | ((*state->chip_ram_r)(state, r_A5 - 0x7f00 + 2)); + amiga_chip_ram_w8(state, r_A2 + 0x1f, 0x00); } } static DRIVER_INIT(haremchl) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = haremchl_input_hack; + state->input_hack = haremchl_input_hack; } static void lsrquiz_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w8(0x001e1b, 0x00); + //amiga_chip_ram_w8(state, 0x001e1b, 0x00); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - UINT32 r_A2 = (amiga_chip_ram_r(r_A5 - 0x7fe0 + 0) << 16) | (amiga_chip_ram_r(r_A5 - 0x7fe0 + 2)); - amiga_chip_ram_w8(r_A2 + 0x13, 0x00); + UINT32 r_A2 = ((*state->chip_ram_r)(state, r_A5 - 0x7fe0 + 0) << 16) | ((*state->chip_ram_r)(state, r_A5 - 0x7fe0 + 2)); + amiga_chip_ram_w8(state, r_A2 + 0x13, 0x00); } } static DRIVER_INIT(lsrquiz) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = lsrquiz_input_hack; + state->input_hack = lsrquiz_input_hack; } /* The hack isn't working if you exit the test mode with P1 button 2 ! */ static void lsrquiz2_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w8(0x046107, 0x00); + //amiga_chip_ram_w8(state, 0x046107, 0x00); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - UINT32 r_A2 = (amiga_chip_ram_r(r_A5 - 0x7fdc + 0) << 16) | (amiga_chip_ram_r(r_A5 - 0x7fdc + 2)); - amiga_chip_ram_w8(r_A2 + 0x17, 0x00); + UINT32 r_A2 = ((*state->chip_ram_r)(state, r_A5 - 0x7fdc + 0) << 16) | ((*state->chip_ram_r)(state, r_A5 - 0x7fdc + 2)); + amiga_chip_ram_w8(state, r_A2 + 0x17, 0x00); } } static DRIVER_INIT(lsrquiz2) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = lsrquiz2_input_hack; + state->input_hack = lsrquiz2_input_hack; } static void lasstixx_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w8(0x00281c, 0x00); + //amiga_chip_ram_w8(state, 0x00281c, 0x00); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - UINT32 r_A2 = (amiga_chip_ram_r(r_A5 - 0x7fa2 + 0) << 16) | (amiga_chip_ram_r(r_A5 - 0x7fa2 + 2)); - amiga_chip_ram_w8(r_A2 + 0x24, 0x00); + UINT32 r_A2 = ((*state->chip_ram_r)(state, r_A5 - 0x7fa2 + 0) << 16) | ((*state->chip_ram_r)(state, r_A5 - 0x7fa2 + 2)); + amiga_chip_ram_w8(state, r_A2 + 0x24, 0x00); } } static DRIVER_INIT(lasstixx) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = lasstixx_input_hack; + state->input_hack = lasstixx_input_hack; } static void mgnumber_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w(0x04bfa0, 0x0000); + //(*state->chip_ram_w)(0x04bfa0, 0x0000); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - amiga_chip_ram_w(r_A5 - 0x7ed8, 0x0000); + (*state->chip_ram_w)(state, r_A5 - 0x7ed8, 0x0000); } } static DRIVER_INIT(mgnumber) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = mgnumber_input_hack; + state->input_hack = mgnumber_input_hack; } static void mgprem11_input_hack(running_machine *machine) { - if(cpu_get_pc(machine->device("maincpu")) < amiga_chip_ram_size) + cubocd32_state *state = machine->driver_data(); + + if (cpu_get_pc(machine->device("maincpu")) < state->chip_ram_size) { -// amiga_chip_ram_w8(0x044f7e, 0x00); + //amiga_chip_ram_w8(state, 0x044f7e, 0x00); UINT32 r_A5 = cpu_get_reg(machine->device("maincpu"), M68K_A5); - amiga_chip_ram_w8(r_A5 - 0x7eca, 0x00); + amiga_chip_ram_w8(state, r_A5 - 0x7eca, 0x00); } } static DRIVER_INIT(mgprem11) { + cubocd32_state *state = machine->driver_data(); DRIVER_INIT_CALL(cd32); - cubocd32_input_hack = mgprem11_input_hack; + state->input_hack = mgprem11_input_hack; } /***************************************************************************************************/ diff --git a/src/mame/drivers/mquake.c b/src/mame/drivers/mquake.c index ef2109de5e5..9a86c7f2894 100644 --- a/src/mame/drivers/mquake.c +++ b/src/mame/drivers/mquake.c @@ -140,9 +140,9 @@ static WRITE16_HANDLER( coin_chip_w ) static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(amiga_state, chip_ram, chip_ram_size) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE(&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE_MEMBER(amiga_state, custom_regs) AM_RANGE(0xe80000, 0xe8ffff) AM_READWRITE(amiga_autoconfig_r, amiga_autoconfig_w) AM_RANGE(0xfc0000, 0xffffff) AM_ROM AM_REGION("user1", 0) /* System ROM */ @@ -357,7 +357,7 @@ static const mos6526_interface cia_1_intf = DEVCB_NULL }; -static MACHINE_CONFIG_START( mquake, driver_device ) +static MACHINE_CONFIG_START( mquake, amiga_state ) /* basic machine hardware */ MDRV_CPU_ADD("maincpu", M68000, AMIGA_68000_NTSC_CLOCK) @@ -366,7 +366,7 @@ static MACHINE_CONFIG_START( mquake, driver_device ) MDRV_MACHINE_RESET(mquake) MDRV_NVRAM_ADD_0FILL("nvram") - /* video hardware */ + /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) MDRV_SCREEN_ADD("screen", RASTER) @@ -447,6 +447,7 @@ ROM_END static DRIVER_INIT(mquake) { + amiga_state *state = machine->driver_data(); static const amiga_machine_interface mquake_intf = { ANGUS_CHIP_RAM_MASK, @@ -459,7 +460,7 @@ static DRIVER_INIT(mquake) amiga_machine_config(machine, &mquake_intf); /* set up memory */ - memory_configure_bank(machine, "bank1", 0, 1, amiga_chip_ram, 0); + memory_configure_bank(machine, "bank1", 0, 1, state->chip_ram, 0); memory_configure_bank(machine, "bank1", 1, 1, memory_region(machine, "user1"), 0); } diff --git a/src/mame/drivers/upscope.c b/src/mame/drivers/upscope.c index 6700c7891ee..331481f3d37 100644 --- a/src/mame/drivers/upscope.c +++ b/src/mame/drivers/upscope.c @@ -30,11 +30,11 @@ #include "machine/nvram.h" -class upscope_state : public driver_device +class upscope_state : public amiga_state { public: upscope_state(running_machine &machine, const driver_device_config_base &config) - : driver_device(machine, config) { } + : amiga_state(machine, config) { } UINT8 m_nvram[0x100]; }; @@ -248,9 +248,9 @@ static WRITE8_DEVICE_HANDLER( upscope_cia_1_porta_w ) static ADDRESS_MAP_START( main_map, ADDRESS_SPACE_PROGRAM, 16 ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE(&amiga_chip_ram) AM_SIZE(&amiga_chip_ram_size) + AM_RANGE(0x000000, 0x07ffff) AM_RAMBANK("bank1") AM_BASE_SIZE_MEMBER(upscope_state, chip_ram, chip_ram_size) AM_RANGE(0xbfd000, 0xbfefff) AM_READWRITE(amiga_cia_r, amiga_cia_w) - AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE(&amiga_custom_regs) + AM_RANGE(0xc00000, 0xdfffff) AM_READWRITE(amiga_custom_r, amiga_custom_w) AM_BASE_MEMBER(upscope_state, custom_regs) AM_RANGE(0xe80000, 0xe8ffff) AM_READWRITE(amiga_autoconfig_r, amiga_autoconfig_w) AM_RANGE(0xfc0000, 0xffffff) AM_ROM AM_REGION("user1", 0) /* System ROM */ @@ -321,7 +321,7 @@ static MACHINE_CONFIG_START( upscope, upscope_state ) MDRV_MACHINE_RESET(amiga) MDRV_NVRAM_ADD_0FILL("nvram") - /* video hardware */ + /* video hardware */ MDRV_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) MDRV_SCREEN_ADD("screen", RASTER) @@ -391,6 +391,7 @@ ROM_END static DRIVER_INIT( upscope ) { + upscope_state *state = machine->driver_data(); static const amiga_machine_interface upscope_intf = { ANGUS_CHIP_RAM_MASK, @@ -403,11 +404,10 @@ static DRIVER_INIT( upscope ) amiga_machine_config(machine, &upscope_intf); /* allocate NVRAM */ - upscope_state *state = machine->driver_data(); machine->device("nvram")->set_base(state->m_nvram, sizeof(state->m_nvram)); /* set up memory */ - memory_configure_bank(machine, "bank1", 0, 1, amiga_chip_ram, 0); + memory_configure_bank(machine, "bank1", 0, 1, state->chip_ram, 0); memory_configure_bank(machine, "bank1", 1, 1, memory_region(machine, "user1"), 0); } diff --git a/src/mame/includes/amiga.h b/src/mame/includes/amiga.h index bba8987d966..1d04ecd6c5d 100644 --- a/src/mame/includes/amiga.h +++ b/src/mame/includes/amiga.h @@ -13,13 +13,23 @@ Ernesto Corvi & Mariusz Wojcieszek #include "devlegcy.h" +/************************************* + * + * Debugging + * + *************************************/ + +#define LOG_COPPER 0 +#define GUESS_COPPER_OFFSET 0 +#define LOG_SPRITE_DMA 0 + /* A bit of a trick here: some registers are 32-bit. In order to efficiently */ /* read them on both big-endian and little-endian systems, we store the custom */ /* registers in 32-bit natural order. This means we need to XOR the register */ /* address with 1 on little-endian systems. */ -#define CUSTOM_REG(x) (amiga_custom_regs[BYTE_XOR_BE(x)]) +#define CUSTOM_REG(x) (state->custom_regs[BYTE_XOR_BE(x)]) #define CUSTOM_REG_SIGNED(x) ((INT16)CUSTOM_REG(x)) -#define CUSTOM_REG_LONG(x) (*(UINT32 *)&amiga_custom_regs[x]) +#define CUSTOM_REG_LONG(x) (*(UINT32 *)&state->custom_regs[x]) /* A = Angus @@ -354,22 +364,79 @@ struct _amiga_autoconfig_device void (*uninstall)(running_machine *machine, offs_t base); /* memory uninstallation */ }; +typedef struct _autoconfig_device autoconfig_device; +struct _autoconfig_device +{ + autoconfig_device * next; + amiga_autoconfig_device device; + offs_t base; +}; + +class amiga_state : public driver_device +{ +public: + amiga_state(running_machine &machine, const driver_device_config_base &config) + : driver_device(machine, config) { } + + UINT16 *chip_ram; + size_t chip_ram_size; + UINT16 (*chip_ram_r)(amiga_state *state, offs_t offset); + void (*chip_ram_w)(amiga_state *state, offs_t offset, UINT16 data); + UINT16 *custom_regs; + + const amiga_machine_interface *intf; + autoconfig_device *autoconfig_list; + autoconfig_device *cur_autoconfig; + emu_timer * irq_timer; + emu_timer * blitter_timer; + running_device *sound_device; + + /* sprite states */ + UINT8 sprite_comparitor_enable_mask; + UINT8 sprite_dma_reload_mask; + UINT8 sprite_dma_live_mask; + UINT8 sprite_ctl_written; + UINT32 sprite_shiftreg[8]; + UINT8 sprite_remain[8]; + + /* copper states */ + UINT32 copper_pc; + UINT8 copper_waiting; + UINT8 copper_waitblit; + UINT16 copper_waitval; + UINT16 copper_waitmask; + UINT16 copper_pending_offset; + UINT16 copper_pending_data; +#if GUESS_COPPER_OFFSET + int wait_offset; +#endif + + /* playfield states */ + int last_scanline; + int ham_color; + + /* misc states */ + UINT16 genlock_color; + + /* separate 6 in-order bitplanes into 2 x 3-bit bitplanes in two nibbles */ + UINT8 separate_bitplanes[2][64]; + + /* aga */ + int aga_diwhigh_written; + pen_t aga_palette[256]; + UINT64 aga_bpldat[8]; + UINT16 aga_sprdata[8][4]; + UINT16 aga_sprdatb[8][4]; + int aga_sprite_fetched_words; + int aga_sprite_dma_used_words[8]; +}; + /*----------- defined in machine/amiga.c -----------*/ -extern UINT16 *amiga_chip_ram; -extern UINT32 *amiga_chip_ram32; -extern size_t amiga_chip_ram_size; - -extern UINT16 *amiga_custom_regs; -extern UINT16 *amiga_expansion_ram; -extern UINT16 *amiga_autoconfig_mem; - extern const char *const amiga_custom_names[0x100]; -extern UINT16 (*amiga_chip_ram_r)(offs_t offset); -extern void (*amiga_chip_ram_w)(offs_t offset, UINT16 data); -extern void amiga_chip_ram_w8(offs_t offset, UINT8 data); +extern void amiga_chip_ram_w8(amiga_state *state, offs_t offset, UINT8 data); void amiga_machine_config(running_machine *machine, const amiga_machine_interface *intf); @@ -393,42 +460,41 @@ WRITE16_HANDLER( amiga_autoconfig_w ); void amiga_cia_0_irq(running_device *device, int state); void amiga_cia_1_irq(running_device *device, int state); -const amiga_machine_interface *amiga_get_interface(void); +const amiga_machine_interface *amiga_get_interface(running_machine *machine); /*----------- defined in audio/amiga.c -----------*/ DECLARE_LEGACY_SOUND_DEVICE(AMIGA, amiga_sound); -void amiga_audio_update(void); -void amiga_audio_data_w(int which, UINT16 data); +void amiga_audio_update(running_device *device); +void amiga_audio_data_w(running_device *device, int which, UINT16 data); /*----------- defined in video/amiga.c -----------*/ +extern const UINT16 amiga_expand_byte[256]; + PALETTE_INIT( amiga ); VIDEO_START( amiga ); VIDEO_UPDATE( amiga ); +void amiga_copper_setpc(running_machine *machine, UINT32 pc); +int amiga_copper_execute_next(running_machine *machine, int xpos); + UINT32 amiga_gethvpos(screen_device &screen); -void copper_setpc(UINT32 pc); -void amiga_set_genlock_color(UINT16 color); +void amiga_set_genlock_color(running_machine *machine, UINT16 color); void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanline); -void amiga_sprite_dma_reset(int which); -void amiga_sprite_enable_comparitor(int which, int enable); +void amiga_sprite_dma_reset(running_machine *machine, int which); +void amiga_sprite_enable_comparitor(running_machine *machine, int which, int enable); /*----------- defined in video/amigaaga.c -----------*/ VIDEO_START( amiga_aga ); VIDEO_UPDATE( amiga_aga ); -UINT32 amiga_aga_gethvpos(screen_device &screen); -void aga_copper_setpc(UINT32 pc); -void amiga_aga_set_genlock_color(UINT16 color); void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanline); -void amiga_aga_sprite_dma_reset(int which); -void amiga_aga_sprite_enable_comparitor(int which, int enable); -void aga_palette_write(int color_reg, UINT16 data); -void aga_diwhigh_written(int written); +void amiga_aga_palette_write(running_machine *machine, int color_reg, UINT16 data); +void amiga_aga_diwhigh_written(running_machine *machine, int written); #endif /* __AMIGA_H__ */ diff --git a/src/mame/includes/cubocd32.h b/src/mame/includes/cubocd32.h index f9e10326f2c..b1551b6037a 100644 --- a/src/mame/includes/cubocd32.h +++ b/src/mame/includes/cubocd32.h @@ -7,10 +7,23 @@ CuboCD32 definitions #ifndef __CUBOCD32_H__ #define __CUBOCD32_H__ +class cubocd32_state : public amiga_state +{ +public: + cubocd32_state(running_machine &machine, const driver_device_config_base &config) + : amiga_state(machine, config) { } + + UINT16 potgo_value; + int cd32_shifter[2]; + void (*input_hack)(running_machine *machine); + int oldstate[2]; +}; + /*----------- defined in machine/cubocd32.c -----------*/ -extern void amiga_akiko_init(running_machine* machine); -extern READ32_HANDLER(amiga_akiko32_r); -extern WRITE32_HANDLER(amiga_akiko32_w); +READ32_DEVICE_HANDLER( amiga_akiko32_r ); +WRITE32_DEVICE_HANDLER( amiga_akiko32_w ); + +DECLARE_LEGACY_DEVICE(AKIKO, akiko); #endif /* __CUBOCD32_H__ */ diff --git a/src/mame/machine/amiga.c b/src/mame/machine/amiga.c index 0030d3fff75..34733733ee9 100644 --- a/src/mame/machine/amiga.c +++ b/src/mame/machine/amiga.c @@ -40,43 +40,12 @@ -/************************************* - * - * Type definitions - * - *************************************/ - -typedef struct _autoconfig_device autoconfig_device; -struct _autoconfig_device -{ - autoconfig_device * next; - amiga_autoconfig_device device; - offs_t base; -}; - - - /************************************* * * Globals * *************************************/ -UINT16 *amiga_chip_ram; -UINT32 *amiga_chip_ram32; -size_t amiga_chip_ram_size; - -UINT16 *amiga_custom_regs; -UINT16 *amiga_expansion_ram; -UINT16 *amiga_autoconfig_mem; - -static const amiga_machine_interface *amiga_intf; - -static autoconfig_device *autoconfig_list; -static autoconfig_device *cur_autoconfig; -static emu_timer * amiga_irq_timer; -static emu_timer * amiga_blitter_timer; - const char *const amiga_custom_names[0x100] = { /* 0x000 */ @@ -183,23 +152,19 @@ static TIMER_CALLBACK( scanline_callback ); * *************************************/ -UINT16 (*amiga_chip_ram_r)(offs_t offset); -void (*amiga_chip_ram_w)(offs_t offset, UINT16 data); - -static UINT16 amiga_chip_ram16_r(offs_t offset) +static UINT16 amiga_chip_ram16_r(amiga_state *state, offs_t offset) { - extern const amiga_machine_interface *amiga_intf; - offset &= amiga_intf->chip_ram_mask; - return (offset < amiga_chip_ram_size) ? amiga_chip_ram[offset/2] : 0xffff; + offset &= state->intf->chip_ram_mask; + return (offset < state->chip_ram_size) ? state->chip_ram[offset/2] : 0xffff; } -static UINT16 amiga_chip_ram32_r(offs_t offset) +static UINT16 amiga_chip_ram32_r(amiga_state *state, offs_t offset) { - extern const amiga_machine_interface *amiga_intf; - offset &= amiga_intf->chip_ram_mask; + offset &= state->intf->chip_ram_mask; - if ( offset < amiga_chip_ram_size ) + if (offset < state->chip_ram_size) { + UINT32 *amiga_chip_ram32 = (UINT32 *)state->chip_ram; UINT32 dat = amiga_chip_ram32[offset / 4]; if ( offset & 2 ) @@ -211,22 +176,21 @@ static UINT16 amiga_chip_ram32_r(offs_t offset) return 0xffff; } -static void amiga_chip_ram16_w(offs_t offset, UINT16 data) +static void amiga_chip_ram16_w(amiga_state *state, offs_t offset, UINT16 data) { - extern const amiga_machine_interface *amiga_intf; - offset &= amiga_intf->chip_ram_mask; + offset &= state->intf->chip_ram_mask; - if (offset < amiga_chip_ram_size) - amiga_chip_ram[offset/2] = data; + if (offset < state->chip_ram_size) + state->chip_ram[offset/2] = data; } -static void amiga_chip_ram32_w(offs_t offset, UINT16 data) +static void amiga_chip_ram32_w(amiga_state *state, offs_t offset, UINT16 data) { - extern const amiga_machine_interface *amiga_intf; - offset &= amiga_intf->chip_ram_mask; + offset &= state->intf->chip_ram_mask; - if ( offset < amiga_chip_ram_size ) + if (offset < state->chip_ram_size) { + UINT32 *amiga_chip_ram32 = (UINT32 *)state->chip_ram; UINT32 dat = amiga_chip_ram32[offset / 4]; if ( offset & 2 ) @@ -245,11 +209,11 @@ static void amiga_chip_ram32_w(offs_t offset, UINT16 data) } -void amiga_chip_ram_w8(offs_t offset, UINT8 data) +void amiga_chip_ram_w8(amiga_state *state, offs_t offset, UINT8 data) { UINT16 dat; - dat = amiga_chip_ram_r(offset); + dat = (*state->chip_ram_r)(state, offset); if (offset & 0x01) { dat &= 0xff00; @@ -260,7 +224,7 @@ void amiga_chip_ram_w8(offs_t offset, UINT8 data) dat &= 0x00ff; dat |= ((UINT16)data) << 8; } - amiga_chip_ram_w(offset,dat); + (*state->chip_ram_w)(state, offset, dat); } /************************************* @@ -271,28 +235,32 @@ void amiga_chip_ram_w8(offs_t offset, UINT8 data) void amiga_machine_config(running_machine *machine, const amiga_machine_interface *intf) { - amiga_intf = intf; + amiga_state *state = machine->driver_data(); + state->intf = intf; /* setup chipmem handlers */ if ( IS_AGA(intf) ) { - amiga_chip_ram_r = amiga_chip_ram32_r; - amiga_chip_ram_w = amiga_chip_ram32_w; + state->chip_ram_r = amiga_chip_ram32_r; + state->chip_ram_w = amiga_chip_ram32_w; } else { - amiga_chip_ram_r = amiga_chip_ram16_r; - amiga_chip_ram_w = amiga_chip_ram16_w; + state->chip_ram_r = amiga_chip_ram16_r; + state->chip_ram_w = amiga_chip_ram16_w; } /* setup the timers */ - amiga_irq_timer = timer_alloc(machine, amiga_irq_proc, NULL); - amiga_blitter_timer = timer_alloc(machine, amiga_blitter_proc, NULL); + state->irq_timer = timer_alloc(machine, amiga_irq_proc, NULL); + state->blitter_timer = timer_alloc(machine, amiga_blitter_proc, NULL); + + state->sound_device = machine->device("amiga"); } static void amiga_m68k_reset(running_device *device) { + amiga_state *state = device->machine->driver_data(); address_space *space = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM); logerror("Executed RESET at PC=%06x\n", cpu_get_pc(space->cpu)); @@ -304,7 +272,7 @@ static void amiga_m68k_reset(running_device *device) autoconfig_reset(device->machine); /* set the overlay bit */ - if ( IS_AGA(amiga_intf) ) + if ( IS_AGA(state->intf) ) { space->write_byte( 0xbfa001, 1 ); } @@ -317,14 +285,16 @@ static void amiga_m68k_reset(running_device *device) MACHINE_RESET( amiga ) { + amiga_state *state = machine->driver_data(); + /* set m68k reset function */ m68k_set_reset_callback(machine->device("maincpu"), amiga_m68k_reset); amiga_m68k_reset(machine->device("maincpu")); /* call the system-specific callback */ - if (amiga_intf->reset_callback) - (*amiga_intf->reset_callback)(machine); + if (state->intf->reset_callback) + (*state->intf->reset_callback)(machine); /* start the scanline timer */ timer_set(machine, machine->primary_screen->time_until_pos(0), NULL, 0, scanline_callback); @@ -340,6 +310,7 @@ MACHINE_RESET( amiga ) static TIMER_CALLBACK( scanline_callback ) { + amiga_state *state = machine->driver_data(); int scanline = param; running_device *cia_0 = machine->device("cia_0"); running_device *cia_1 = machine->device("cia_1"); @@ -354,8 +325,8 @@ static TIMER_CALLBACK( scanline_callback ) mos6526_tod_w(cia_0, 1); /* call the system-specific callback */ - if (amiga_intf->scanline0_callback != NULL) - (*amiga_intf->scanline0_callback)(machine); + if (state->intf->scanline0_callback != NULL) + (*state->intf->scanline0_callback)(machine); } /* on every scanline, clock the second CIA TOD */ @@ -364,14 +335,14 @@ static TIMER_CALLBACK( scanline_callback ) /* render up to this scanline */ if (!machine->primary_screen->update_partial(scanline)) { - if (IS_AGA(amiga_intf)) + if (IS_AGA(state->intf)) amiga_aga_render_scanline(machine, NULL, scanline); else amiga_render_scanline(machine, NULL, scanline); } /* force a sound update */ - amiga_audio_update(); + amiga_audio_update(state->sound_device); /* set timer for next line */ scanline = (scanline + 1) % machine->primary_screen->height(); @@ -388,6 +359,7 @@ static TIMER_CALLBACK( scanline_callback ) static void update_irqs(running_machine *machine) { + amiga_state *state = machine->driver_data(); int ints = CUSTOM_REG(REG_INTENA) & CUSTOM_REG(REG_INTREQ); /* Master interrupt switch */ @@ -425,8 +397,10 @@ static void update_irqs(running_machine *machine) static TIMER_CALLBACK( amiga_irq_proc ) { + amiga_state *state = machine->driver_data(); + update_irqs(machine); - timer_reset( amiga_irq_timer, attotime_never); + timer_reset( state->irq_timer, attotime_never); } @@ -459,7 +433,7 @@ CUSTOM_INPUT( amiga_joystick_convert ) * *************************************/ -static UINT32 blit_ascending(void) +static UINT32 blit_ascending(amiga_state *state) { UINT32 shifta = (CUSTOM_REG(REG_BLTCON0) >> 12) & 0xf; UINT32 shiftb = (CUSTOM_REG(REG_BLTCON1) >> 12) & 0xf; @@ -482,21 +456,21 @@ static UINT32 blit_ascending(void) /* fetch data for A */ if (CUSTOM_REG(REG_BLTCON0) & 0x0800) { - CUSTOM_REG(REG_BLTADAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTAPTH)); + CUSTOM_REG(REG_BLTADAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTAPTH)); CUSTOM_REG_LONG(REG_BLTAPTH) += 2; } /* fetch data for B */ if (CUSTOM_REG(REG_BLTCON0) & 0x0400) { - CUSTOM_REG(REG_BLTBDAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTBPTH)); + CUSTOM_REG(REG_BLTBDAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTBPTH)); CUSTOM_REG_LONG(REG_BLTBPTH) += 2; } /* fetch data for C */ if (CUSTOM_REG(REG_BLTCON0) & 0x0200) { - CUSTOM_REG(REG_BLTCDAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTCPTH)); + CUSTOM_REG(REG_BLTCDAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTCPTH)); CUSTOM_REG_LONG(REG_BLTCPTH) += 2; } @@ -552,7 +526,7 @@ static UINT32 blit_ascending(void) /* write to the destination */ if (CUSTOM_REG(REG_BLTCON0) & 0x0100) { - amiga_chip_ram_w(CUSTOM_REG_LONG(REG_BLTDPTH), tempd); + (*state->chip_ram_w)(state, CUSTOM_REG_LONG(REG_BLTDPTH), tempd); CUSTOM_REG_LONG(REG_BLTDPTH) += 2; } } @@ -580,7 +554,7 @@ static UINT32 blit_ascending(void) * *************************************/ -static UINT32 blit_descending(void) +static UINT32 blit_descending(amiga_state *state) { UINT32 fill_exclusive = (CUSTOM_REG(REG_BLTCON1) >> 4); UINT32 fill_inclusive = (CUSTOM_REG(REG_BLTCON1) >> 3); @@ -607,21 +581,21 @@ static UINT32 blit_descending(void) /* fetch data for A */ if (CUSTOM_REG(REG_BLTCON0) & 0x0800) { - CUSTOM_REG(REG_BLTADAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTAPTH)); + CUSTOM_REG(REG_BLTADAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTAPTH)); CUSTOM_REG_LONG(REG_BLTAPTH) -= 2; } /* fetch data for B */ if (CUSTOM_REG(REG_BLTCON0) & 0x0400) { - CUSTOM_REG(REG_BLTBDAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTBPTH)); + CUSTOM_REG(REG_BLTBDAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTBPTH)); CUSTOM_REG_LONG(REG_BLTBPTH) -= 2; } /* fetch data for C */ if (CUSTOM_REG(REG_BLTCON0) & 0x0200) { - CUSTOM_REG(REG_BLTCDAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTCPTH)); + CUSTOM_REG(REG_BLTCDAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTCPTH)); CUSTOM_REG_LONG(REG_BLTCPTH) -= 2; } @@ -694,7 +668,7 @@ static UINT32 blit_descending(void) /* write to the destination */ if (CUSTOM_REG(REG_BLTCON0) & 0x0100) { - amiga_chip_ram_w(CUSTOM_REG_LONG(REG_BLTDPTH), tempd); + (*state->chip_ram_w)(state, CUSTOM_REG_LONG(REG_BLTDPTH), tempd); CUSTOM_REG_LONG(REG_BLTDPTH) -= 2; } } @@ -761,7 +735,7 @@ static UINT32 blit_descending(void) BLTAMOD = 4 * (dy - dx) and BLTBMOD = 4 * dy. */ -static UINT32 blit_line(void) +static UINT32 blit_line(amiga_state *state) { UINT32 singlemode = (CUSTOM_REG(REG_BLTCON1) & 0x0002) ? 0x0000 : 0xffff; UINT32 singlemask = 0xffff; @@ -786,7 +760,7 @@ static UINT32 blit_line(void) /* fetch data for C */ if (CUSTOM_REG(REG_BLTCON0) & 0x0200) - CUSTOM_REG(REG_BLTCDAT) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BLTCPTH)); + CUSTOM_REG(REG_BLTCDAT) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BLTCPTH)); /* rotate the A data according to the shift */ tempa = CUSTOM_REG(REG_BLTADAT) >> (CUSTOM_REG(REG_BLTCON0) >> 12); @@ -837,7 +811,7 @@ static UINT32 blit_line(void) blitsum |= tempd; /* write to the destination */ - amiga_chip_ram_w(CUSTOM_REG_LONG(REG_BLTDPTH), tempd); + (*state->chip_ram_w)(state, CUSTOM_REG_LONG(REG_BLTDPTH), tempd); /* always increment along the major axis */ if (CUSTOM_REG(REG_BLTCON1) & 0x0010) @@ -914,6 +888,7 @@ static UINT32 blit_line(void) static TIMER_CALLBACK( amiga_blitter_proc ) { + amiga_state *state = machine->driver_data(); UINT32 blitsum = 0; /* logging */ @@ -938,16 +913,16 @@ static TIMER_CALLBACK( amiga_blitter_proc ) switch (CUSTOM_REG(REG_BLTCON1) & 0x0003) { case 0: /* ascending */ - blitsum = blit_ascending(); + blitsum = blit_ascending(state); break; case 2: /* descending */ - blitsum = blit_descending(); + blitsum = blit_descending(state); break; case 1: /* line */ case 3: - blitsum = blit_line(); + blitsum = blit_line(state); break; } @@ -962,7 +937,7 @@ static TIMER_CALLBACK( amiga_blitter_proc ) amiga_custom_w(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), REG_INTREQ, 0x8000 | INTENA_BLIT, 0xffff); /* reset the blitter timer */ - timer_reset( amiga_blitter_timer, attotime_never); + timer_reset( state->blitter_timer, attotime_never); } @@ -975,6 +950,7 @@ static TIMER_CALLBACK( amiga_blitter_proc ) static void blitter_setup(address_space *space) { + amiga_state *state = space->machine->driver_data(); int ticks, width, height, blittime; /* is there another blitting in progress? */ @@ -1019,14 +995,14 @@ static void blitter_setup(address_space *space) } /* AGA has twice the bus bandwidth, so blits take half the time */ - if ( IS_AGA(amiga_intf) ) + if ( IS_AGA(state->intf) ) blittime /= 2; /* signal blitter busy */ CUSTOM_REG(REG_DMACON) |= 0x4000; /* set a timer */ - timer_adjust_oneshot( amiga_blitter_timer, downcast(space->cpu)->cycles_to_attotime( blittime ), 0); + timer_adjust_oneshot( state->blitter_timer, downcast(space->cpu)->cycles_to_attotime( blittime ), 0); } @@ -1132,6 +1108,7 @@ void amiga_cia_1_irq(running_device *device, int state) static void custom_reset(running_machine *machine) { + amiga_state *state = machine->driver_data(); int clock = cputag_get_clock(machine, "maincpu"); UINT16 vidmode = (clock == AMIGA_68000_NTSC_CLOCK || clock == AMIGA_68EC020_NTSC_CLOCK ) ? 0x1000 : 0x0000; /* NTSC or PAL? */ @@ -1141,7 +1118,7 @@ static void custom_reset(running_machine *machine) CUSTOM_REG(REG_VPOSR) = vidmode; CUSTOM_REG(REG_SERDATR) = 0x3000; - switch (amiga_intf->chip_ram_mask) + switch (state->intf->chip_ram_mask) { case ANGUS_CHIP_RAM_MASK: case FAT_ANGUS_CHIP_RAM_MASK: @@ -1151,7 +1128,7 @@ static void custom_reset(running_machine *machine) case ECS_CHIP_RAM_MASK: CUSTOM_REG(REG_VPOSR) |= 0x2000; CUSTOM_REG(REG_DENISEID) = 0x00FC; - if (IS_AGA(amiga_intf)) + if (IS_AGA(state->intf)) { CUSTOM_REG(REG_VPOSR) |= 0x0300; CUSTOM_REG(REG_DENISEID) = 0x00F8; @@ -1170,6 +1147,7 @@ static void custom_reset(running_machine *machine) READ16_HANDLER( amiga_custom_r ) { + amiga_state *state = space->machine->driver_data(); UINT16 temp; switch (offset & 0xff) @@ -1182,17 +1160,11 @@ READ16_HANDLER( amiga_custom_r ) case REG_VPOSR: CUSTOM_REG(REG_VPOSR) &= 0xff00; - if (IS_AGA(amiga_intf)) - CUSTOM_REG(REG_VPOSR) |= amiga_aga_gethvpos(*space->machine->primary_screen) >> 16; - else - CUSTOM_REG(REG_VPOSR) |= amiga_gethvpos(*space->machine->primary_screen) >> 16; + CUSTOM_REG(REG_VPOSR) |= amiga_gethvpos(*space->machine->primary_screen) >> 16; return CUSTOM_REG(REG_VPOSR); case REG_VHPOSR: - if (IS_AGA(amiga_intf)) - return amiga_aga_gethvpos(*space->machine->primary_screen) & 0xffff; - else - return amiga_gethvpos(*space->machine->primary_screen) & 0xffff; + return amiga_gethvpos(*space->machine->primary_screen) & 0xffff; case REG_SERDATR: CUSTOM_REG(REG_SERDATR) &= ~0x4000; @@ -1200,13 +1172,13 @@ READ16_HANDLER( amiga_custom_r ) return CUSTOM_REG(REG_SERDATR); case REG_JOY0DAT: - if (amiga_intf->joy0dat_r != NULL) - return (*amiga_intf->joy0dat_r)(space->machine); + if (state->intf->joy0dat_r != NULL) + return (*state->intf->joy0dat_r)(space->machine); return input_port_read_safe(space->machine, "JOY0DAT", 0xffff); case REG_JOY1DAT: - if (amiga_intf->joy1dat_r != NULL) - return (*amiga_intf->joy1dat_r)(space->machine); + if (state->intf->joy1dat_r != NULL) + return (*state->intf->joy1dat_r)(space->machine); return input_port_read_safe(space->machine, "JOY1DAT", 0xffff); case REG_ADKCONR: @@ -1222,8 +1194,8 @@ READ16_HANDLER( amiga_custom_r ) return input_port_read_safe(space->machine, "POT1DAT", 0x0000); case REG_DSKBYTR: - if (amiga_intf->dskbytr_r != NULL) - return (*amiga_intf->dskbytr_r)(space->machine); + if (state->intf->dskbytr_r != NULL) + return (*state->intf->dskbytr_r)(space->machine); return 0x0000; case REG_INTENAR: @@ -1233,17 +1205,11 @@ READ16_HANDLER( amiga_custom_r ) return CUSTOM_REG(REG_INTREQ); case REG_COPJMP1: - if (IS_AGA(amiga_intf)) - aga_copper_setpc(CUSTOM_REG_LONG(REG_COP1LCH)); - else - copper_setpc(CUSTOM_REG_LONG(REG_COP1LCH)); + amiga_copper_setpc(space->machine, CUSTOM_REG_LONG(REG_COP1LCH)); break; case REG_COPJMP2: - if (IS_AGA(amiga_intf)) - aga_copper_setpc(CUSTOM_REG_LONG(REG_COP2LCH)); - else - copper_setpc(CUSTOM_REG_LONG(REG_COP2LCH)); + amiga_copper_setpc(space->machine, CUSTOM_REG_LONG(REG_COP2LCH)); break; case REG_CLXDAT: @@ -1271,6 +1237,8 @@ READ16_HANDLER( amiga_custom_r ) static TIMER_CALLBACK( finish_serial_write ) { + amiga_state *state = machine->driver_data(); + /* mark the transfer buffer empty */ CUSTOM_REG(REG_SERDATR) |= 0x3000; @@ -1281,6 +1249,7 @@ static TIMER_CALLBACK( finish_serial_write ) WRITE16_HANDLER( amiga_custom_w ) { + amiga_state *state = space->machine->driver_data(); running_device *cia_0; running_device *cia_1; UINT16 temp; @@ -1299,18 +1268,18 @@ WRITE16_HANDLER( amiga_custom_w ) break; case REG_DSKLEN: - if (amiga_intf->dsklen_w != NULL) - (*amiga_intf->dsklen_w)(space->machine, data); + if (state->intf->dsklen_w != NULL) + (*state->intf->dsklen_w)(space->machine, data); break; case REG_POTGO: - if (amiga_intf->potgo_w != NULL) - (*amiga_intf->potgo_w)(space->machine, data); + if (state->intf->potgo_w != NULL) + (*state->intf->potgo_w)(space->machine, data); break; case REG_SERDAT: - if (amiga_intf->serdat_w != NULL) - (*amiga_intf->serdat_w)(space->machine, data); + if (state->intf->serdat_w != NULL) + (*state->intf->serdat_w)(space->machine, data); CUSTOM_REG(REG_SERDATR) &= ~0x3000; timer_set(space->machine, amiga_get_serial_char_period(space->machine), NULL, 0, finish_serial_write); break; @@ -1325,7 +1294,7 @@ WRITE16_HANDLER( amiga_custom_w ) break; case REG_BLTSIZV: /* ECS-AGA only */ - if ( IS_ECS_OR_AGA(amiga_intf) ) + if ( IS_ECS_OR_AGA(state->intf) ) { CUSTOM_REG(REG_BLTSIZV) = data & 0x7fff; if ( CUSTOM_REG(REG_BLTSIZV) == 0 ) CUSTOM_REG(REG_BLTSIZV) = 0x8000; @@ -1333,7 +1302,7 @@ WRITE16_HANDLER( amiga_custom_w ) break; case REG_BLTSIZH: /* ECS-AGA only */ - if ( IS_ECS_OR_AGA(amiga_intf) ) + if ( IS_ECS_OR_AGA(state->intf) ) { CUSTOM_REG(REG_BLTSIZH) = data & 0x7ff; if ( CUSTOM_REG(REG_BLTSIZH) == 0 ) CUSTOM_REG(REG_BLTSIZH) = 0x800; @@ -1342,7 +1311,7 @@ WRITE16_HANDLER( amiga_custom_w ) break; case REG_BLTCON0L: /* ECS-AGA only */ - if ( IS_ECS_OR_AGA(amiga_intf) ) + if ( IS_ECS_OR_AGA(state->intf) ) { CUSTOM_REG(REG_BLTCON0) &= 0xff00; CUSTOM_REG(REG_BLTCON0) |= data & 0xff; @@ -1351,51 +1320,36 @@ WRITE16_HANDLER( amiga_custom_w ) case REG_SPR0PTH: case REG_SPR1PTH: case REG_SPR2PTH: case REG_SPR3PTH: case REG_SPR4PTH: case REG_SPR5PTH: case REG_SPR6PTH: case REG_SPR7PTH: - data &= ( amiga_intf->chip_ram_mask >> 16 ); + data &= ( state->intf->chip_ram_mask >> 16 ); break; case REG_SPR0PTL: case REG_SPR1PTL: case REG_SPR2PTL: case REG_SPR3PTL: case REG_SPR4PTL: case REG_SPR5PTL: case REG_SPR6PTL: case REG_SPR7PTL: - if (IS_AGA(amiga_intf)) - amiga_aga_sprite_dma_reset((offset - REG_SPR0PTL) / 2); - else - amiga_sprite_dma_reset((offset - REG_SPR0PTL) / 2); + amiga_sprite_dma_reset(space->machine, (offset - REG_SPR0PTL) / 2); break; case REG_SPR0CTL: case REG_SPR1CTL: case REG_SPR2CTL: case REG_SPR3CTL: case REG_SPR4CTL: case REG_SPR5CTL: case REG_SPR6CTL: case REG_SPR7CTL: /* disable comparitor on writes here */ - if (IS_AGA(amiga_intf)) - amiga_aga_sprite_enable_comparitor((offset - REG_SPR0CTL) / 4, FALSE); - else - amiga_sprite_enable_comparitor((offset - REG_SPR0CTL) / 4, FALSE); + amiga_sprite_enable_comparitor(space->machine, (offset - REG_SPR0CTL) / 4, FALSE); break; case REG_SPR0DATA: case REG_SPR1DATA: case REG_SPR2DATA: case REG_SPR3DATA: case REG_SPR4DATA: case REG_SPR5DATA: case REG_SPR6DATA: case REG_SPR7DATA: /* enable comparitor on writes here */ - if (IS_AGA(amiga_intf)) - amiga_aga_sprite_enable_comparitor((offset - REG_SPR0DATA) / 4, TRUE); - else - amiga_sprite_enable_comparitor((offset - REG_SPR0DATA) / 4, TRUE); + amiga_sprite_enable_comparitor(space->machine, (offset - REG_SPR0DATA) / 4, TRUE); break; case REG_COP1LCH: case REG_COP2LCH: - data &= ( amiga_intf->chip_ram_mask >> 16 ); + data &= ( state->intf->chip_ram_mask >> 16 ); break; case REG_COPJMP1: - if (IS_AGA(amiga_intf)) - aga_copper_setpc(CUSTOM_REG_LONG(REG_COP1LCH)); - else - copper_setpc(CUSTOM_REG_LONG(REG_COP1LCH)); + amiga_copper_setpc(space->machine, CUSTOM_REG_LONG(REG_COP1LCH)); break; case REG_COPJMP2: - if (IS_AGA(amiga_intf)) - aga_copper_setpc(CUSTOM_REG_LONG(REG_COP2LCH)); - else - copper_setpc(CUSTOM_REG_LONG(REG_COP2LCH)); + amiga_copper_setpc(space->machine, CUSTOM_REG_LONG(REG_COP2LCH)); break; case REG_DDFSTRT: @@ -1413,7 +1367,7 @@ WRITE16_HANDLER( amiga_custom_w ) break; case REG_DMACON: - amiga_audio_update(); + amiga_audio_update(state->sound_device); /* bits BBUSY (14) and BZERO (13) are read-only */ data &= 0x9fff; @@ -1421,7 +1375,7 @@ WRITE16_HANDLER( amiga_custom_w ) /* if 'blitter-nasty' has been turned on and we have a blit pending, reschedule it */ if ( ( data & 0x400 ) && ( CUSTOM_REG(REG_DMACON) & 0x4000 ) ) - timer_adjust_oneshot( amiga_blitter_timer, downcast(space->cpu)->cycles_to_attotime( BLITTER_NASTY_DELAY ), 0); + timer_adjust_oneshot( state->blitter_timer, downcast(space->cpu)->cycles_to_attotime( BLITTER_NASTY_DELAY ), 0); break; @@ -1432,7 +1386,7 @@ WRITE16_HANDLER( amiga_custom_w ) CUSTOM_REG(offset) = data; if ( temp & 0x8000 ) /* if we're enabling irq's, delay a bit */ - timer_adjust_oneshot( amiga_irq_timer, downcast(space->cpu)->cycles_to_attotime( AMIGA_IRQ_DELAY_CYCLES ), 0); + timer_adjust_oneshot( state->irq_timer, downcast(space->cpu)->cycles_to_attotime( AMIGA_IRQ_DELAY_CYCLES ), 0); else /* if we're disabling irq's, process right away */ update_irqs(space->machine); break; @@ -1451,13 +1405,13 @@ WRITE16_HANDLER( amiga_custom_w ) CUSTOM_REG(offset) = data; if ( temp & 0x8000 ) /* if we're generating irq's, delay a bit */ - timer_adjust_oneshot( amiga_irq_timer, space->machine->device("maincpu")->cycles_to_attotime( AMIGA_IRQ_DELAY_CYCLES ), 0); + timer_adjust_oneshot( state->irq_timer, space->machine->device("maincpu")->cycles_to_attotime( AMIGA_IRQ_DELAY_CYCLES ), 0); else /* if we're clearing irq's, process right away */ update_irqs(space->machine); break; case REG_ADKCON: - amiga_audio_update(); + amiga_audio_update(state->sound_device); data = (data & 0x8000) ? (CUSTOM_REG(offset) | (data & 0x7fff)) : (CUSTOM_REG(offset) & ~(data & 0x7fff)); break; @@ -1465,16 +1419,16 @@ WRITE16_HANDLER( amiga_custom_w ) case REG_AUD1LCL: case REG_AUD1LCH: case REG_AUD1LEN: case REG_AUD1PER: case REG_AUD1VOL: case REG_AUD2LCL: case REG_AUD2LCH: case REG_AUD2LEN: case REG_AUD2PER: case REG_AUD2VOL: case REG_AUD3LCL: case REG_AUD3LCH: case REG_AUD3LEN: case REG_AUD3PER: case REG_AUD3VOL: - amiga_audio_update(); + amiga_audio_update(state->sound_device); break; case REG_AUD0DAT: case REG_AUD1DAT: case REG_AUD2DAT: case REG_AUD3DAT: - amiga_audio_data_w((offset - REG_AUD0DAT) / 8, data); + amiga_audio_data_w(state->sound_device, (offset - REG_AUD0DAT) / 8, data); break; case REG_BPL1PTH: case REG_BPL2PTH: case REG_BPL3PTH: case REG_BPL4PTH: case REG_BPL5PTH: case REG_BPL6PTH: - data &= ( amiga_intf->chip_ram_mask >> 16 ); + data &= ( state->intf->chip_ram_mask >> 16 ); break; case REG_BPLCON0: @@ -1494,9 +1448,9 @@ WRITE16_HANDLER( amiga_custom_w ) case REG_COLOR20: case REG_COLOR21: case REG_COLOR22: case REG_COLOR23: case REG_COLOR24: case REG_COLOR25: case REG_COLOR26: case REG_COLOR27: case REG_COLOR28: case REG_COLOR29: case REG_COLOR30: case REG_COLOR31: - if ( IS_AGA(amiga_intf)) + if (IS_AGA(state->intf)) { - aga_palette_write(offset - REG_COLOR00, data); + amiga_aga_palette_write(space->machine, offset - REG_COLOR00, data); } else { @@ -1506,19 +1460,19 @@ WRITE16_HANDLER( amiga_custom_w ) break; case REG_DIWSTRT: case REG_DIWSTOP: - if (IS_AGA(amiga_intf)) - aga_diwhigh_written(0); + if (IS_AGA(state->intf)) + amiga_aga_diwhigh_written(space->machine, 0); break; case REG_DIWHIGH: - if (IS_AGA(amiga_intf)) - aga_diwhigh_written(1); + if (IS_AGA(state->intf)) + amiga_aga_diwhigh_written(space->machine, 1); break; default: break; } - if (IS_AGA(amiga_intf)) + if (IS_AGA(state->intf)) CUSTOM_REG(offset) = data; else if (offset <= REG_COLOR31) @@ -1535,6 +1489,7 @@ WRITE16_HANDLER( amiga_custom_w ) void amiga_serial_in_w(running_machine *machine, UINT16 data) { + amiga_state *state = machine->driver_data(); address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); int mask = (CUSTOM_REG(REG_SERPER) & 0x8000) ? 0x1ff : 0xff; @@ -1556,6 +1511,7 @@ void amiga_serial_in_w(running_machine *machine, UINT16 data) attotime amiga_get_serial_char_period(running_machine *machine) { + amiga_state *state = machine->driver_data(); UINT32 divisor = (CUSTOM_REG(REG_SERPER) & 0x7fff) + 1; UINT32 baud = cputag_get_clock(machine, "maincpu") / 2 / divisor; UINT32 numbits = 2 + ((CUSTOM_REG(REG_SERPER) & 0x8000) ? 9 : 8); @@ -1572,6 +1528,7 @@ attotime amiga_get_serial_char_period(running_machine *machine) void amiga_add_autoconfig(running_machine *machine, const amiga_autoconfig_device *device) { + amiga_state *state = machine->driver_data(); autoconfig_device *dev, **d; /* validate the data */ @@ -1581,7 +1538,7 @@ void amiga_add_autoconfig(running_machine *machine, const amiga_autoconfig_devic /* allocate memory and link it in at the end of the list */ dev = auto_alloc(machine, autoconfig_device); dev->next = NULL; - for (d = &autoconfig_list; *d; d = &(*d)->next) ; + for (d = &state->autoconfig_list; *d; d = &(*d)->next) ; *d = dev; /* fill in the data */ @@ -1599,10 +1556,11 @@ void amiga_add_autoconfig(running_machine *machine, const amiga_autoconfig_devic static void autoconfig_reset(running_machine *machine) { + amiga_state *state = machine->driver_data(); autoconfig_device *dev; /* uninstall any installed devices */ - for (dev = autoconfig_list; dev; dev = dev->next) + for (dev = state->autoconfig_list; dev; dev = dev->next) if (dev->base && dev->device.uninstall) { (*dev->device.uninstall)(machine, dev->base); @@ -1610,7 +1568,7 @@ static void autoconfig_reset(running_machine *machine) } /* reset the current autoconfig */ - cur_autoconfig = autoconfig_list; + state->cur_autoconfig = state->autoconfig_list; } @@ -1623,6 +1581,8 @@ static void autoconfig_reset(running_machine *machine) READ16_HANDLER( amiga_autoconfig_r ) { + amiga_state *state = space->machine->driver_data(); + autoconfig_device *cur_autoconfig = state->cur_autoconfig; UINT8 byte; int i; @@ -1760,6 +1720,8 @@ READ16_HANDLER( amiga_autoconfig_r ) WRITE16_HANDLER( amiga_autoconfig_w ) { + amiga_state *state = space->machine->driver_data(); + autoconfig_device *cur_autoconfig = state->cur_autoconfig; int move_to_next = FALSE; logerror("autoconfig_w(%02X) = %04X & %04X\n", offset, data, mem_mask); @@ -1797,7 +1759,7 @@ WRITE16_HANDLER( amiga_autoconfig_w ) logerror("Install to %06X\n", cur_autoconfig->base); if (cur_autoconfig->base && cur_autoconfig->device.install) (*cur_autoconfig->device.install)(space->machine, cur_autoconfig->base); - cur_autoconfig = cur_autoconfig->next; + state->cur_autoconfig = cur_autoconfig->next; } } @@ -1809,7 +1771,7 @@ WRITE16_HANDLER( amiga_autoconfig_w ) * *************************************/ -const amiga_machine_interface *amiga_get_interface(void) +const amiga_machine_interface *amiga_get_interface(running_machine *machine) { - return amiga_intf; + return machine->driver_data()->intf; } diff --git a/src/mame/machine/cubocd32.c b/src/mame/machine/cubocd32.c index e7500e12c2b..4c366513e1d 100644 --- a/src/mame/machine/cubocd32.c +++ b/src/mame/machine/cubocd32.c @@ -27,8 +27,12 @@ TODO: Add CDDA support #define CD_SECTOR_TIME (1000/((150*1024)/2048)) /* 1X CDROM sector time in msec (300KBps) */ -static struct akiko_def +typedef struct _akiko_state akiko_state; +struct _akiko_state { + running_machine *machine; + address_space *space; + /* chunky to planar converter */ UINT32 c2p_input_buffer[8]; UINT32 c2p_output_buffer[8]; @@ -61,75 +65,88 @@ static struct akiko_def emu_timer *dma_timer; emu_timer *frame_timer; running_device *i2cmem; -} akiko; +}; static TIMER_CALLBACK(akiko_dma_proc); static TIMER_CALLBACK(akiko_frame_proc); -static void amiga_akiko_exit(running_machine& machine) +INLINE akiko_state *get_safe_token(running_device *device) { - if( akiko.cdrom ) { - cdrom_close(akiko.cdrom); - akiko.cdrom = (cdrom_file *)NULL; + assert(device != NULL); + assert(device->type() == AKIKO); + + return (akiko_state *)downcast(device)->token(); +} + +static DEVICE_STOP( akiko ) +{ + akiko_state *state = get_safe_token(device); + if( state->cdrom ) + { + cdrom_close(state->cdrom); + state->cdrom = (cdrom_file *)NULL; } } -void amiga_akiko_init(running_machine* machine) +static DEVICE_START( akiko ) { - akiko.c2p_input_index = 0; - akiko.c2p_output_index = 0; + running_machine *machine = device->machine; + akiko_state *state = get_safe_token(device); - akiko.i2c_scl_out = 0; - akiko.i2c_scl_dir = 0; - akiko.i2c_sda_out = 0; - akiko.i2c_sda_dir = 0; + state->machine = machine; + state->space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); + state->c2p_input_index = 0; + state->c2p_output_index = 0; - akiko.cdrom_status[0] = akiko.cdrom_status[1] = 0; - akiko.cdrom_address[0] = akiko.cdrom_address[1] = 0; - akiko.cdrom_track_index = 0; - akiko.cdrom_lba_start = 0; - akiko.cdrom_lba_end = 0; - akiko.cdrom_lba_cur = 0; - akiko.cdrom_readmask = 0; - akiko.cdrom_readreqmask = 0; - akiko.cdrom_dmacontrol = 0; - akiko.cdrom_numtracks = 0; - akiko.cdrom_speed = 0; - akiko.cdrom_cmd_start = 0; - akiko.cdrom_cmd_end = 0; - akiko.cdrom_cmd_resp = 0; - akiko.cdrom = cdrom_open(get_disk_handle(machine, "cdrom")); - akiko.cdrom_toc = NULL; - akiko.dma_timer = timer_alloc(machine, akiko_dma_proc, NULL); - akiko.frame_timer = timer_alloc(machine, akiko_frame_proc, NULL); - akiko.i2cmem = machine->device("i2cmem"); + state->i2c_scl_out = 0; + state->i2c_scl_dir = 0; + state->i2c_sda_out = 0; + state->i2c_sda_dir = 0; - machine->add_notifier(MACHINE_NOTIFY_EXIT, amiga_akiko_exit); + state->cdrom_status[0] = state->cdrom_status[1] = 0; + state->cdrom_address[0] = state->cdrom_address[1] = 0; + state->cdrom_track_index = 0; + state->cdrom_lba_start = 0; + state->cdrom_lba_end = 0; + state->cdrom_lba_cur = 0; + state->cdrom_readmask = 0; + state->cdrom_readreqmask = 0; + state->cdrom_dmacontrol = 0; + state->cdrom_numtracks = 0; + state->cdrom_speed = 0; + state->cdrom_cmd_start = 0; + state->cdrom_cmd_end = 0; + state->cdrom_cmd_resp = 0; + state->cdrom = cdrom_open(get_disk_handle(machine, "cdrom")); + state->cdrom_toc = NULL; + state->dma_timer = timer_alloc(machine, akiko_dma_proc, state); + state->frame_timer = timer_alloc(machine, akiko_frame_proc, state); + state->i2cmem = machine->device("i2cmem"); /* create the TOC table */ - if ( akiko.cdrom != NULL && cdrom_get_last_track(akiko.cdrom) ) + if ( state->cdrom != NULL && cdrom_get_last_track(state->cdrom) ) { UINT8 *p; - int i, addrctrl = cdrom_get_adr_control( akiko.cdrom, 0 ); + int i, addrctrl = cdrom_get_adr_control( state->cdrom, 0 ); UINT32 discend; - discend = cdrom_get_track_start(akiko.cdrom,cdrom_get_last_track(akiko.cdrom)-1); - discend += cdrom_get_toc(akiko.cdrom)->tracks[cdrom_get_last_track(akiko.cdrom)-1].frames; + discend = cdrom_get_track_start(state->cdrom,cdrom_get_last_track(state->cdrom)-1); + discend += cdrom_get_toc(state->cdrom)->tracks[cdrom_get_last_track(state->cdrom)-1].frames; discend = lba_to_msf(discend); - akiko.cdrom_numtracks = cdrom_get_last_track(akiko.cdrom)+3; + state->cdrom_numtracks = cdrom_get_last_track(state->cdrom)+3; - akiko.cdrom_toc = auto_alloc_array(machine, UINT8, 13*akiko.cdrom_numtracks); - memset( akiko.cdrom_toc, 0, 13*akiko.cdrom_numtracks); + state->cdrom_toc = auto_alloc_array(machine, UINT8, 13*state->cdrom_numtracks); + memset( state->cdrom_toc, 0, 13*state->cdrom_numtracks); - p = akiko.cdrom_toc; + p = state->cdrom_toc; p[1] = ((addrctrl & 0x0f) << 4) | ((addrctrl & 0xf0) >> 4); p[3] = 0xa0; /* first track */ p[8] = 1; p += 13; p[1] = 0x01; p[3] = 0xa1; /* last track */ - p[8] = cdrom_get_last_track(akiko.cdrom); + p[8] = cdrom_get_last_track(state->cdrom); p += 13; p[1] = 0x01; p[3] = 0xa2; /* disc end */ @@ -138,12 +155,12 @@ void amiga_akiko_init(running_machine* machine) p[10] = discend & 0xff; p += 13; - for( i = 0; i < cdrom_get_last_track(akiko.cdrom); i++ ) + for( i = 0; i < cdrom_get_last_track(state->cdrom); i++ ) { - UINT32 trackpos = cdrom_get_track_start(akiko.cdrom,i); + UINT32 trackpos = cdrom_get_track_start(state->cdrom,i); trackpos = lba_to_msf(trackpos); - addrctrl = cdrom_get_adr_control( akiko.cdrom, i ); + addrctrl = cdrom_get_adr_control( state->cdrom, i ); p[1] = ((addrctrl & 0x0f) << 4) | ((addrctrl & 0xf0) >> 4); p[3] = dec_2_bcd( i+1 ); @@ -156,41 +173,41 @@ void amiga_akiko_init(running_machine* machine) } } -static void akiko_nvram_write(running_machine *machine, UINT32 data) +static void akiko_nvram_write(akiko_state *state, UINT32 data) { - akiko.i2c_scl_out = BIT(data,31); - akiko.i2c_sda_out = BIT(data,30); - akiko.i2c_scl_dir = BIT(data,15); - akiko.i2c_sda_dir = BIT(data,14); + state->i2c_scl_out = BIT(data,31); + state->i2c_sda_out = BIT(data,30); + state->i2c_scl_dir = BIT(data,15); + state->i2c_sda_dir = BIT(data,14); - i2cmem_scl_write( akiko.i2cmem, akiko.i2c_scl_out ); - i2cmem_sda_write( akiko.i2cmem, akiko.i2c_sda_out ); + i2cmem_scl_write( state->i2cmem, state->i2c_scl_out ); + i2cmem_sda_write( state->i2cmem, state->i2c_sda_out ); } -static UINT32 akiko_nvram_read(running_machine *machine) +static UINT32 akiko_nvram_read(akiko_state *state) { UINT32 v = 0; - if ( akiko.i2c_scl_dir ) + if ( state->i2c_scl_dir ) { - v |= akiko.i2c_scl_out << 31; + v |= state->i2c_scl_out << 31; } else { v |= 0 << 31; } - if ( akiko.i2c_sda_dir ) + if ( state->i2c_sda_dir ) { - v |= akiko.i2c_sda_out << 30; + v |= state->i2c_sda_out << 30; } else { - v |= i2cmem_sda_read( akiko.i2cmem ) << 30; + v |= i2cmem_sda_read( state->i2cmem ) << 30; } - v |= akiko.i2c_scl_dir << 15; - v |= akiko.i2c_sda_dir << 14; + v |= state->i2c_scl_dir << 15; + v |= state->i2c_sda_dir << 14; return v; } @@ -201,34 +218,35 @@ static UINT32 akiko_nvram_read(running_machine *machine) * ************************************/ -static void akiko_c2p_write(UINT32 data) +static void akiko_c2p_write(akiko_state *state, UINT32 data) { - akiko.c2p_input_buffer[akiko.c2p_input_index] = data; - akiko.c2p_input_index++; - akiko.c2p_input_index &= 7; - akiko.c2p_output_index = 0; + state->c2p_input_buffer[state->c2p_input_index] = data; + state->c2p_input_index++; + state->c2p_input_index &= 7; + state->c2p_output_index = 0; } -static UINT32 akiko_c2p_read(void) +static UINT32 akiko_c2p_read(akiko_state *state) { UINT32 val; - if ( akiko.c2p_output_index == 0 ) + if ( state->c2p_output_index == 0 ) { int i; for ( i = 0; i < 8; i++ ) - akiko.c2p_output_buffer[i] = 0; + state->c2p_output_buffer[i] = 0; - for (i = 0; i < 8 * 32; i++) { - if (akiko.c2p_input_buffer[7 - (i >> 5)] & (1 << (i & 31))) - akiko.c2p_output_buffer[i & 7] |= 1 << (i >> 3); + for (i = 0; i < 8 * 32; i++) + { + if (state->c2p_input_buffer[7 - (i >> 5)] & (1 << (i & 31))) + state->c2p_output_buffer[i & 7] |= 1 << (i >> 3); } } - akiko.c2p_input_index = 0; - val = akiko.c2p_output_buffer[akiko.c2p_output_index]; - akiko.c2p_output_index++; - akiko.c2p_output_index &= 7; + state->c2p_input_index = 0; + val = state->c2p_output_buffer[state->c2p_output_index]; + state->c2p_output_index++; + state->c2p_output_index &= 7; return val; } @@ -269,30 +287,30 @@ static const char* get_akiko_reg_name(int reg) * ************************************/ -static void akiko_cdda_stop( running_machine *machine ) +static void akiko_cdda_stop(akiko_state *state) { - running_device *cdda = cdda_from_cdrom(machine, akiko.cdrom); + running_device *cdda = cdda_from_cdrom(state->machine, state->cdrom); if (cdda != NULL) { cdda_stop_audio(cdda); - timer_reset( akiko.frame_timer, attotime_never ); + timer_reset( state->frame_timer, attotime_never ); } } -static void akiko_cdda_play( running_machine *machine, UINT32 lba, UINT32 num_blocks ) +static void akiko_cdda_play(akiko_state *state, UINT32 lba, UINT32 num_blocks) { - running_device *cdda = cdda_from_cdrom(machine, akiko.cdrom); + running_device *cdda = cdda_from_cdrom(state->machine, state->cdrom); if (cdda != NULL) { cdda_start_audio(cdda, lba, num_blocks); - timer_adjust_oneshot( akiko.frame_timer, ATTOTIME_IN_HZ( 75 ), 0 ); + timer_adjust_oneshot( state->frame_timer, ATTOTIME_IN_HZ( 75 ), 0 ); } } -static void akiko_cdda_pause( running_machine *machine, int pause ) +static void akiko_cdda_pause(akiko_state *state, int pause) { - running_device *cdda = cdda_from_cdrom(machine, akiko.cdrom); + running_device *cdda = cdda_from_cdrom(state->machine, state->cdrom); if (cdda != NULL) { if (cdda_audio_active(cdda) && cdda_audio_paused(cdda) != pause ) @@ -301,19 +319,19 @@ static void akiko_cdda_pause( running_machine *machine, int pause ) if ( pause ) { - timer_reset( akiko.frame_timer, attotime_never ); + timer_reset( state->frame_timer, attotime_never ); } else { - timer_adjust_oneshot( akiko.frame_timer, ATTOTIME_IN_HZ( 75 ), 0 ); + timer_adjust_oneshot( state->frame_timer, ATTOTIME_IN_HZ( 75 ), 0 ); } } } } -static UINT8 akiko_cdda_getstatus( running_machine *machine, UINT32 *lba ) +static UINT8 akiko_cdda_getstatus(akiko_state *state, UINT32 *lba) { - running_device *cdda = cdda_from_cdrom(machine, akiko.cdrom); + running_device *cdda = cdda_from_cdrom(state->machine, state->cdrom); if ( lba ) *lba = 0; @@ -341,33 +359,34 @@ static UINT8 akiko_cdda_getstatus( running_machine *machine, UINT32 *lba ) return 0x15; /* no audio status */ } -static void akiko_set_cd_status( running_machine *machine, UINT32 status ) +static void akiko_set_cd_status(akiko_state *state, UINT32 status) { - akiko.cdrom_status[0] |= status; + state->cdrom_status[0] |= status; - if ( akiko.cdrom_status[0] & akiko.cdrom_status[1] ) + if ( state->cdrom_status[0] & state->cdrom_status[1] ) { if (LOG_AKIKO_CD) logerror( "Akiko CD IRQ\n" ); - amiga_custom_w(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff); + amiga_custom_w(state->space, REG_INTREQ, 0x8000 | INTENA_PORTS, 0xffff); } } static TIMER_CALLBACK(akiko_frame_proc) { - running_device *cdda = cdda_from_cdrom(machine, akiko.cdrom); + akiko_state *state = (akiko_state *)param; + running_device *cdda = cdda_from_cdrom(machine, state->cdrom); (void)param; if (cdda != NULL) { - UINT8 s = akiko_cdda_getstatus(machine, NULL); + UINT8 s = akiko_cdda_getstatus(state, NULL); if ( s == 0x11 ) { - akiko_set_cd_status( machine, 0x80000000 ); /* subcode ready */ + akiko_set_cd_status(state, 0x80000000); /* subcode ready */ } - timer_adjust_oneshot( akiko.frame_timer, ATTOTIME_IN_HZ( 75 ), 0 ); + timer_adjust_oneshot( state->frame_timer, ATTOTIME_IN_HZ( 75 ), 0 ); } } @@ -384,28 +403,30 @@ static UINT32 lba_from_triplet( UINT8 *triplet ) static TIMER_CALLBACK(akiko_dma_proc) { + akiko_state *state = (akiko_state *)ptr; UINT8 buf[2352]; int index; - if ( (akiko.cdrom_dmacontrol & 0x04000000) == 0 ) + if ( (state->cdrom_dmacontrol & 0x04000000) == 0 ) return; - if ( akiko.cdrom_readreqmask == 0 ) + if ( state->cdrom_readreqmask == 0 ) return; - index = (akiko.cdrom_lba_cur - akiko.cdrom_lba_start) & 0x0f; + index = (state->cdrom_lba_cur - state->cdrom_lba_start) & 0x0f; - if ( akiko.cdrom_readreqmask & ( 1 << index ) ) + if ( state->cdrom_readreqmask & ( 1 << index ) ) { - UINT32 track = cdrom_get_track( akiko.cdrom, akiko.cdrom_lba_cur ); - UINT32 datasize = cdrom_get_toc( akiko.cdrom )->tracks[track].datasize; - UINT32 subsize = cdrom_get_toc( akiko.cdrom )->tracks[track].subsize; + amiga_state *amiga = machine->driver_data(); + UINT32 track = cdrom_get_track( state->cdrom, state->cdrom_lba_cur ); + UINT32 datasize = cdrom_get_toc( state->cdrom )->tracks[track].datasize; + UINT32 subsize = cdrom_get_toc( state->cdrom )->tracks[track].subsize; int i; - UINT32 curmsf = lba_to_msf( akiko.cdrom_lba_cur ); + UINT32 curmsf = lba_to_msf( state->cdrom_lba_cur ); memset( buf, 0, 16 ); - buf[3] = akiko.cdrom_lba_cur - akiko.cdrom_lba_start; + buf[3] = state->cdrom_lba_cur - state->cdrom_lba_start; memset( &buf[4], 0xff, 8 ); buf[12] = (curmsf >> 16) & 0xff; @@ -414,22 +435,22 @@ static TIMER_CALLBACK(akiko_dma_proc) buf[15] = 0x01; /* mode1 */ datasize = 2048; - if ( !cdrom_read_data( akiko.cdrom, akiko.cdrom_lba_cur, &buf[16], CD_TRACK_MODE1 ) ) + if ( !cdrom_read_data( state->cdrom, state->cdrom_lba_cur, &buf[16], CD_TRACK_MODE1 ) ) { - logerror( "AKIKO: Read error trying to read sector %08x!\n", akiko.cdrom_lba_cur ); + logerror( "AKIKO: Read error trying to read sector %08x!\n", state->cdrom_lba_cur ); return; } if ( subsize ) { - if ( !cdrom_read_subcode( akiko.cdrom, akiko.cdrom_lba_cur, &buf[16+datasize] ) ) + if ( !cdrom_read_subcode( state->cdrom, state->cdrom_lba_cur, &buf[16+datasize] ) ) { - logerror( "AKIKO: Read error trying to read subcode for sector %08x!\n", akiko.cdrom_lba_cur ); + logerror( "AKIKO: Read error trying to read subcode for sector %08x!\n", state->cdrom_lba_cur ); return; } } - if (LOG_AKIKO_CD) logerror( "DMA: sector %d - address %08x\n", akiko.cdrom_lba_cur, akiko.cdrom_address[0] + (index*4096) ); + if (LOG_AKIKO_CD) logerror( "DMA: sector %d - address %08x\n", state->cdrom_lba_cur, state->cdrom_address[0] + (index*4096) ); for( i = 0; i < 2352; i += 2 ) { @@ -439,39 +460,39 @@ static TIMER_CALLBACK(akiko_dma_proc) data <<= 8; data |= buf[i+1]; - amiga_chip_ram_w( akiko.cdrom_address[0] + (index*4096) + i, data ); + (*amiga->chip_ram_w)( amiga, state->cdrom_address[0] + (index*4096) + i, data ); } - akiko.cdrom_readmask |= ( 1 << index ); - akiko.cdrom_readreqmask &= ~( 1 << index ); - akiko.cdrom_lba_cur++; + state->cdrom_readmask |= ( 1 << index ); + state->cdrom_readreqmask &= ~( 1 << index ); + state->cdrom_lba_cur++; } - if ( akiko.cdrom_readreqmask == 0 ) - akiko_set_cd_status(machine, 0x04000000); + if ( state->cdrom_readreqmask == 0 ) + akiko_set_cd_status(state, 0x04000000); else - timer_adjust_oneshot( akiko.dma_timer, ATTOTIME_IN_USEC( CD_SECTOR_TIME / akiko.cdrom_speed ), 0 ); + timer_adjust_oneshot( state->dma_timer, ATTOTIME_IN_USEC( CD_SECTOR_TIME / state->cdrom_speed ), 0 ); } -static void akiko_start_dma( void ) +static void akiko_start_dma(akiko_state *state) { - if ( akiko.cdrom_readreqmask == 0 ) + if ( state->cdrom_readreqmask == 0 ) return; - if ( akiko.cdrom_lba_start > akiko.cdrom_lba_end ) + if ( state->cdrom_lba_start > state->cdrom_lba_end ) return; - if ( akiko.cdrom_speed == 0 ) + if ( state->cdrom_speed == 0 ) return; - akiko.cdrom_lba_cur = akiko.cdrom_lba_start; + state->cdrom_lba_cur = state->cdrom_lba_start; - timer_adjust_oneshot( akiko.dma_timer, ATTOTIME_IN_USEC( CD_SECTOR_TIME / akiko.cdrom_speed ), 0 ); + timer_adjust_oneshot( state->dma_timer, ATTOTIME_IN_USEC( CD_SECTOR_TIME / state->cdrom_speed ), 0 ); } -static void akiko_setup_response( address_space *space, int len, UINT8 *r1 ) +static void akiko_setup_response( akiko_state *state, int len, UINT8 *r1 ) { - int resp_addr = akiko.cdrom_address[1]; + int resp_addr = state->cdrom_address[1]; UINT8 resp_csum = 0xff; UINT8 resp_buffer[32]; int i; @@ -488,23 +509,24 @@ static void akiko_setup_response( address_space *space, int len, UINT8 *r1 ) for( i = 0; i < len; i++ ) { - space->write_byte( resp_addr + ((akiko.cdrom_cmd_resp + i) & 0xff), resp_buffer[i] ); + state->space->write_byte( resp_addr + ((state->cdrom_cmd_resp + i) & 0xff), resp_buffer[i] ); } - akiko.cdrom_cmd_resp = (akiko.cdrom_cmd_resp+len) & 0xff; + state->cdrom_cmd_resp = (state->cdrom_cmd_resp+len) & 0xff; - akiko_set_cd_status( space->machine, 0x10000000 ); /* new data available */ + akiko_set_cd_status(state, 0x10000000); /* new data available */ } static TIMER_CALLBACK( akiko_cd_delayed_cmd ) { + akiko_state *state = (akiko_state *)ptr; UINT8 resp[32]; UINT8 cddastatus; - if ( akiko.cdrom_status[0] & 0x10000000 ) + if ( state->cdrom_status[0] & 0x10000000 ) return; - cddastatus = akiko_cdda_getstatus(machine, NULL); + cddastatus = akiko_cdda_getstatus(state, NULL); if ( cddastatus == 0x11 || cddastatus == 0x12 ) return; @@ -516,39 +538,38 @@ static TIMER_CALLBACK( akiko_cd_delayed_cmd ) if ( param == 0x05 ) { - address_space *space = cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM); if (LOG_AKIKO_CD) logerror( "AKIKO: Completing Command %d\n", param ); resp[0] = 0x06; - if ( akiko.cdrom == NULL || akiko.cdrom_numtracks == 0 ) + if ( state->cdrom == NULL || state->cdrom_numtracks == 0 ) { resp[1] = 0x80; - akiko_setup_response( space, 15, resp ); + akiko_setup_response( state, 15, resp ); } else { resp[1] = 0x00; - memcpy( &resp[2], &akiko.cdrom_toc[13*akiko.cdrom_track_index], 13 ); + memcpy( &resp[2], &state->cdrom_toc[13*state->cdrom_track_index], 13 ); - akiko.cdrom_track_index = ( akiko.cdrom_track_index + 1 ) % akiko.cdrom_numtracks; + state->cdrom_track_index = ( state->cdrom_track_index + 1 ) % state->cdrom_numtracks; - akiko_setup_response( space, 15, resp ); + akiko_setup_response( state, 15, resp ); } } } -static void akiko_update_cdrom(address_space *space) +static void akiko_update_cdrom(akiko_state *state) { UINT8 resp[32], cmdbuf[32]; - if ( akiko.cdrom_status[0] & 0x10000000 ) + if ( state->cdrom_status[0] & 0x10000000 ) return; - while ( akiko.cdrom_cmd_start != akiko.cdrom_cmd_end ) + while ( state->cdrom_cmd_start != state->cdrom_cmd_end ) { - UINT32 cmd_addr = akiko.cdrom_address[1] + 0x200 + akiko.cdrom_cmd_start; - int cmd = space->read_byte( cmd_addr ); + UINT32 cmd_addr = state->cdrom_address[1] + 0x200 + state->cdrom_cmd_start; + int cmd = state->space->read_byte( cmd_addr ); memset( resp, 0, sizeof( resp ) ); resp[0] = cmd; @@ -561,27 +582,27 @@ static void akiko_update_cdrom(address_space *space) { resp[1] = 0x00; - if ( akiko_cdda_getstatus(space->machine, NULL) == 0x11 ) + if ( akiko_cdda_getstatus(state, NULL) == 0x11 ) resp[1] = 0x08; - akiko_cdda_pause( space->machine, 1 ); + akiko_cdda_pause(state, 1); - akiko.cdrom_cmd_start = (akiko.cdrom_cmd_start+2) & 0xff; + state->cdrom_cmd_start = (state->cdrom_cmd_start+2) & 0xff; - akiko_setup_response( space, 2, resp ); + akiko_setup_response( state, 2, resp ); } else if ( cmd == 0x03 ) /* unpause audio (and check audiocd playing status) */ { resp[1] = 0x00; - if ( akiko_cdda_getstatus(space->machine, NULL) == 0x11 ) + if ( akiko_cdda_getstatus(state, NULL) == 0x11 ) resp[1] = 0x08; - akiko_cdda_pause( space->machine, 0 ); + akiko_cdda_pause(state, 0); - akiko.cdrom_cmd_start = (akiko.cdrom_cmd_start+2) & 0xff; + state->cdrom_cmd_start = (state->cdrom_cmd_start+2) & 0xff; - akiko_setup_response( space, 2, resp ); + akiko_setup_response( state, 2, resp ); } else if ( cmd == 0x04 ) /* seek/read/play cd multi command */ { @@ -590,67 +611,67 @@ static void akiko_update_cdrom(address_space *space) for( i = 0; i < 13; i++ ) { - cmdbuf[i] = space->read_byte( cmd_addr ); + cmdbuf[i] = state->space->read_byte( cmd_addr ); cmd_addr &= 0xffffff00; - cmd_addr += ( akiko.cdrom_cmd_start + i + 1 ) & 0xff; + cmd_addr += ( state->cdrom_cmd_start + i + 1 ) & 0xff; } - akiko.cdrom_cmd_start = (akiko.cdrom_cmd_start+13) & 0xff; + state->cdrom_cmd_start = (state->cdrom_cmd_start+13) & 0xff; - if ( akiko.cdrom == NULL || akiko.cdrom_numtracks == 0 ) + if ( state->cdrom == NULL || state->cdrom_numtracks == 0 ) { resp[1] = 0x80; - akiko_setup_response( space, 2, resp ); + akiko_setup_response( state, 2, resp ); } else { startpos = lba_from_triplet( &cmdbuf[1] ); endpos = lba_from_triplet( &cmdbuf[4] ); - akiko_cdda_stop(space->machine); + akiko_cdda_stop(state); resp[1] = 0x00; if ( cmdbuf[7] == 0x80 ) { - if (LOG_AKIKO_CD) logerror( "%s:AKIKO CD: Data read - start lba: %08x - end lba: %08x\n", cpuexec_describe_context(space->machine), startpos, endpos ); - akiko.cdrom_speed = (cmdbuf[8] & 0x40) ? 2 : 1; - akiko.cdrom_lba_start = startpos; - akiko.cdrom_lba_end = endpos; + if (LOG_AKIKO_CD) logerror( "%s:AKIKO CD: Data read - start lba: %08x - end lba: %08x\n", cpuexec_describe_context(state->machine), startpos, endpos ); + state->cdrom_speed = (cmdbuf[8] & 0x40) ? 2 : 1; + state->cdrom_lba_start = startpos; + state->cdrom_lba_end = endpos; resp[1] = 0x02; } else if ( cmdbuf[10] & 0x04 ) { logerror( "AKIKO CD: Audio Play - start lba: %08x - end lba: %08x\n", startpos, endpos ); - akiko_cdda_play( space->machine, startpos, endpos - startpos ); + akiko_cdda_play(state, startpos, endpos - startpos); resp[1] = 0x08; } else { if (LOG_AKIKO_CD) logerror( "AKIKO CD: Seek - start lba: %08x - end lba: %08x\n", startpos, endpos ); - akiko.cdrom_track_index = 0; + state->cdrom_track_index = 0; - for( i = 0; i < cdrom_get_last_track(akiko.cdrom); i++ ) + for( i = 0; i < cdrom_get_last_track(state->cdrom); i++ ) { - if ( startpos <= cdrom_get_track_start( akiko.cdrom, i ) ) + if ( startpos <= cdrom_get_track_start( state->cdrom, i ) ) { /* reset to 0 */ - akiko.cdrom_track_index = i + 2; - akiko.cdrom_track_index %= akiko.cdrom_numtracks; + state->cdrom_track_index = i + 2; + state->cdrom_track_index %= state->cdrom_numtracks; break; } } } - akiko_setup_response( space, 2, resp ); + akiko_setup_response( state, 2, resp ); } } else if ( cmd == 0x05 ) /* read toc */ { - akiko.cdrom_cmd_start = (akiko.cdrom_cmd_start+3) & 0xff; + state->cdrom_cmd_start = (state->cdrom_cmd_start+3) & 0xff; - timer_set( space->machine, ATTOTIME_IN_MSEC(1), NULL, resp[0], akiko_cd_delayed_cmd ); + timer_set( state->machine, ATTOTIME_IN_MSEC(1), state, resp[0], akiko_cd_delayed_cmd ); break; } @@ -660,7 +681,7 @@ static void akiko_update_cdrom(address_space *space) resp[1] = 0x00; - (void)akiko_cdda_getstatus( space->machine, &lba ); + (void)akiko_cdda_getstatus(state, &lba); if ( lba > 0 ) { @@ -669,8 +690,8 @@ static void akiko_update_cdrom(address_space *space) UINT32 track; int addrctrl; - track = cdrom_get_track(akiko.cdrom, lba); - addrctrl = cdrom_get_adr_control(akiko.cdrom, track); + track = cdrom_get_track(state->cdrom, lba); + addrctrl = cdrom_get_adr_control(state->cdrom, track); resp[2] = 0x00; resp[3] = ((addrctrl & 0x0f) << 4) | ((addrctrl & 0xf0) >> 4); @@ -678,7 +699,7 @@ static void akiko_update_cdrom(address_space *space) resp[5] = 0; /* index */ disk_pos = lba_to_msf(lba); - track_pos = lba_to_msf(lba - cdrom_get_track_start(akiko.cdrom, track)); + track_pos = lba_to_msf(lba - cdrom_get_track_start(state->cdrom, track)); /* track position */ resp[6] = (track_pos >> 16) & 0xff; @@ -696,18 +717,18 @@ static void akiko_update_cdrom(address_space *space) resp[1] = 0x80; } - akiko_setup_response( space, 15, resp ); + akiko_setup_response( state, 15, resp ); } else if ( cmd == 0x07 ) /* check door status */ { resp[1] = 0x01; - akiko.cdrom_cmd_start = (akiko.cdrom_cmd_start+2) & 0xff; + state->cdrom_cmd_start = (state->cdrom_cmd_start+2) & 0xff; - if ( akiko.cdrom == NULL || akiko.cdrom_numtracks == 0 ) + if ( state->cdrom == NULL || state->cdrom_numtracks == 0 ) resp[1] = 0x80; - akiko_setup_response( space, 20, resp ); + akiko_setup_response( state, 20, resp ); break; } else @@ -717,8 +738,10 @@ static void akiko_update_cdrom(address_space *space) } } -READ32_HANDLER(amiga_akiko32_r) +READ32_DEVICE_HANDLER( amiga_akiko32_r ) { + akiko_state *state = get_safe_token(device); + address_space *space = state->space; UINT32 retval; if ( LOG_AKIKO && offset < (0x30/4) ) @@ -729,48 +752,48 @@ READ32_HANDLER(amiga_akiko32_r) switch( offset ) { case 0x00/4: /* ID */ - if ( akiko.cdrom != NULL ) cdda_set_cdrom(space->machine->device("cdda"), akiko.cdrom); + if ( state->cdrom != NULL ) cdda_set_cdrom(space->machine->device("cdda"), state->cdrom); return 0x0000cafe; case 0x04/4: /* CDROM STATUS 1 */ - return akiko.cdrom_status[0]; + return state->cdrom_status[0]; case 0x08/4: /* CDROM STATUS 2 */ - return akiko.cdrom_status[1]; + return state->cdrom_status[1]; case 0x10/4: /* CDROM ADDRESS 1 */ - return akiko.cdrom_address[0]; + return state->cdrom_address[0]; case 0x14/4: /* CDROM ADDRESS 2 */ - return akiko.cdrom_address[1]; + return state->cdrom_address[1]; case 0x18/4: /* CDROM COMMAND 1 */ - akiko_update_cdrom(space); - retval = akiko.cdrom_cmd_start; + akiko_update_cdrom(state); + retval = state->cdrom_cmd_start; retval <<= 8; - retval |= akiko.cdrom_cmd_resp; + retval |= state->cdrom_cmd_resp; retval <<= 8; return retval; case 0x1C/4: /* CDROM COMMAND 2 */ - akiko_update_cdrom(space); - retval = akiko.cdrom_cmd_end; + akiko_update_cdrom(state); + retval = state->cdrom_cmd_end; retval <<= 16; return retval; case 0x20/4: /* CDROM DMA SECTOR READ MASK */ - retval = akiko.cdrom_readmask << 16; + retval = state->cdrom_readmask << 16; return retval; case 0x24/4: /* CDROM DMA ENABLE? */ - retval = akiko.cdrom_dmacontrol; + retval = state->cdrom_dmacontrol; return retval; case 0x30/4: /* NVRAM */ - return akiko_nvram_read(space->machine); + return akiko_nvram_read(state); case 0x38/4: /* C2P */ - return akiko_c2p_read(); + return akiko_c2p_read(state); default: break; @@ -779,8 +802,11 @@ READ32_HANDLER(amiga_akiko32_r) return 0; } -WRITE32_HANDLER(amiga_akiko32_w) +WRITE32_DEVICE_HANDLER( amiga_akiko32_w ) { + akiko_state *state = get_safe_token(device); + address_space *space = state->space; + if ( LOG_AKIKO && offset < (0x30/4) ) { logerror( "Writing AKIKO reg %0x [%s] with %08x at PC=%06x\n", offset, get_akiko_reg_name(offset), data, cpu_get_pc(space->cpu) ); @@ -789,67 +815,82 @@ WRITE32_HANDLER(amiga_akiko32_w) switch( offset ) { case 0x04/4: /* CDROM STATUS 1 */ - akiko.cdrom_status[0] = data; + state->cdrom_status[0] = data; break; case 0x08/4: /* CDROM STATUS 2 */ - akiko.cdrom_status[1] = data; - akiko.cdrom_status[0] &= data; + state->cdrom_status[1] = data; + state->cdrom_status[0] &= data; break; case 0x10/4: /* CDROM ADDRESS 1 */ - akiko.cdrom_address[0] = data; + state->cdrom_address[0] = data; break; case 0x14/4: /* CDROM ADDRESS 2 */ - akiko.cdrom_address[1] = data; + state->cdrom_address[1] = data; break; case 0x18/4: /* CDROM COMMAND 1 */ if ( ACCESSING_BITS_16_23 ) - akiko.cdrom_cmd_start = ( data >> 16 ) & 0xff; + state->cdrom_cmd_start = ( data >> 16 ) & 0xff; if ( ACCESSING_BITS_8_15 ) - akiko.cdrom_cmd_resp = ( data >> 8 ) & 0xff; + state->cdrom_cmd_resp = ( data >> 8 ) & 0xff; - akiko_update_cdrom(space); + akiko_update_cdrom(state); break; case 0x1C/4: /* CDROM COMMAND 2 */ if ( ACCESSING_BITS_16_23 ) - akiko.cdrom_cmd_end = ( data >> 16 ) & 0xff; + state->cdrom_cmd_end = ( data >> 16 ) & 0xff; - akiko_update_cdrom(space); + akiko_update_cdrom(state); break; case 0x20/4: /* CDROM DMA SECTOR READ REQUEST WRITE */ if (LOG_AKIKO_CD) logerror( "Read Req mask W: data %08x - mem mask %08x\n", data, mem_mask ); if ( ACCESSING_BITS_16_31 ) { - akiko.cdrom_readreqmask = (data >> 16); - akiko.cdrom_readmask = 0; + state->cdrom_readreqmask = (data >> 16); + state->cdrom_readmask = 0; } break; case 0x24/4: /* CDROM DMA ENABLE? */ if (LOG_AKIKO_CD) logerror( "DMA enable W: data %08x - mem mask %08x\n", data, mem_mask ); - if ( ( akiko.cdrom_dmacontrol ^ data ) & 0x04000000 ) + if ( ( state->cdrom_dmacontrol ^ data ) & 0x04000000 ) { if ( data & 0x04000000 ) - akiko_start_dma(); + akiko_start_dma(state); } - akiko.cdrom_dmacontrol = data; + state->cdrom_dmacontrol = data; break; case 0x30/4: - akiko_nvram_write(space->machine, data); + akiko_nvram_write(state, data); break; case 0x38/4: - akiko_c2p_write(data); + akiko_c2p_write(state, data); break; default: break; } } + +/*------------------------------------------------- + device definition +-------------------------------------------------*/ + +static const char DEVTEMPLATE_SOURCE[] = __FILE__; + +#define DEVTEMPLATE_ID(p,s) p##akiko##s +#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_STOP +#define DEVTEMPLATE_NAME "Akiko" +#define DEVTEMPLATE_FAMILY "Amiga" +#include "devtempl.h" + + +DEFINE_LEGACY_DEVICE(AKIKO, akiko); diff --git a/src/mame/video/amiga.c b/src/mame/video/amiga.c index 5c3f862fc9f..94bca1169d2 100644 --- a/src/mame/video/amiga.c +++ b/src/mame/video/amiga.c @@ -11,18 +11,6 @@ -/************************************* - * - * Debugging - * - *************************************/ - -#define LOG_COPPER 0 -#define GUESS_COPPER_OFFSET 0 -#define LOG_SPRITE_DMA 0 - - - /************************************* * * Macros @@ -33,41 +21,6 @@ -/************************************* - * - * Statics - * - *************************************/ - -/* sprite states */ -static UINT8 sprite_comparitor_enable_mask; -static UINT8 sprite_dma_reload_mask; -static UINT8 sprite_dma_live_mask; -static UINT32 sprite_shiftreg[8]; -static UINT8 sprite_remain[8]; - -/* playfield states */ -static int last_scanline; -static UINT16 ham_color; - -/* copper states */ -static UINT32 copper_pc; -static UINT8 copper_waiting; -static UINT8 copper_waitblit; -static UINT16 copper_waitval; -static UINT16 copper_waitmask; -static UINT16 copper_pending_offset; -static UINT16 copper_pending_data; - -/* misc states */ -static UINT16 genlock_color; - -#if GUESS_COPPER_OFFSET -static int wait_offset = 3; -#endif - - - /************************************* * * Tables @@ -75,7 +28,7 @@ static int wait_offset = 3; *************************************/ /* expand an 8-bit bit pattern into 16 bits, every other bit */ -static const UINT16 expand_byte[256] = +const UINT16 amiga_expand_byte[256] = { 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, @@ -112,9 +65,6 @@ static const UINT16 expand_byte[256] = 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 }; -/* separate 6 in-order bitplanes into 2 x 3-bit bitplanes in two nibbles */ -static UINT8 separate_bitplanes[2][64]; - /************************************* @@ -141,6 +91,7 @@ PALETTE_INIT( amiga ) VIDEO_START( amiga ) { + amiga_state *state = machine->driver_data(); int j; /* generate tables that produce the correct playfield color for dual playfield mode */ @@ -149,12 +100,18 @@ VIDEO_START( amiga ) int pf1pix = ((j >> 0) & 1) | ((j >> 1) & 2) | ((j >> 2) & 4); int pf2pix = ((j >> 1) & 1) | ((j >> 2) & 2) | ((j >> 3) & 4); - separate_bitplanes[0][j] = (pf1pix || !pf2pix) ? pf1pix : (pf2pix + 8); - separate_bitplanes[1][j] = pf2pix ? (pf2pix + 8) : pf1pix; + state->separate_bitplanes[0][j] = (pf1pix || !pf2pix) ? pf1pix : (pf2pix + 8); + state->separate_bitplanes[1][j] = pf2pix ? (pf2pix + 8) : pf1pix; } +#if GUESS_COPPER_OFFSET + state->wait_offset = 3; +#endif + /* reset the genlock color */ - genlock_color = 0xffff; + state->genlock_color = 0xffff; + + state->sprite_ctl_written = 0; } @@ -167,12 +124,13 @@ VIDEO_START( amiga ) UINT32 amiga_gethvpos(screen_device &screen) { - UINT32 hvpos = (last_scanline << 8) | (screen.hpos() >> 2); + amiga_state *state = screen.machine->driver_data(); + UINT32 hvpos = (state->last_scanline << 8) | (screen.hpos() >> 2); UINT32 latchedpos = input_port_read_safe(screen.machine, "HVPOS", 0); /* if there's no latched position, or if we are in the active display area */ /* but before the latching point, return the live HV position */ - if ((CUSTOM_REG(REG_BPLCON0) & 0x0008) == 0 || latchedpos == 0 || (last_scanline >= 20 && hvpos < latchedpos)) + if ((CUSTOM_REG(REG_BPLCON0) & 0x0008) == 0 || latchedpos == 0 || (state->last_scanline >= 20 && hvpos < latchedpos)) return hvpos; /* otherwise, return the latched position */ @@ -187,9 +145,11 @@ UINT32 amiga_gethvpos(screen_device &screen) * *************************************/ -void amiga_set_genlock_color(UINT16 color) +void amiga_set_genlock_color(running_machine *machine, UINT16 color) { - genlock_color = color; + amiga_state *state = machine->driver_data(); + + state->genlock_color = color; } @@ -200,18 +160,21 @@ void amiga_set_genlock_color(UINT16 color) * *************************************/ -void copper_setpc(UINT32 pc) +void amiga_copper_setpc(running_machine *machine, UINT32 pc) { + amiga_state *state = machine->driver_data(); + if (LOG_COPPER) logerror("copper_setpc(%06x)\n", pc); - copper_pc = pc; - copper_waiting = FALSE; + state->copper_pc = pc; + state->copper_waiting = FALSE; } -static int copper_execute_next(running_machine *machine, int xpos) +int amiga_copper_execute_next(running_machine *machine, int xpos) { + amiga_state *state = machine->driver_data(); int word0, word1; /* bail if not enabled */ @@ -219,34 +182,34 @@ static int copper_execute_next(running_machine *machine, int xpos) return 511; /* flush any pending writes */ - if (copper_pending_offset) + if (state->copper_pending_offset) { if (LOG_COPPER) - logerror("%02X.%02X: Write to %s = %04x\n", last_scanline, xpos / 2, amiga_custom_names[copper_pending_offset & 0xff], copper_pending_data); + logerror("%02X.%02X: Write to %s = %04x\n", state->last_scanline, xpos / 2, amiga_custom_names[state->copper_pending_offset & 0xff], state->copper_pending_data); - amiga_custom_w(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), copper_pending_offset, copper_pending_data, 0xffff); - copper_pending_offset = 0; + amiga_custom_w(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), state->copper_pending_offset, state->copper_pending_data, 0xffff); + state->copper_pending_offset = 0; } /* if we're waiting, check for a breakthrough */ - if (copper_waiting) + if (state->copper_waiting) { - int curpos = (last_scanline << 8) | (xpos >> 1); + int curpos = (state->last_scanline << 8) | (xpos >> 1); /* if we're past the wait time, stop it and hold up 2 cycles */ - if ((curpos & copper_waitmask) >= (copper_waitval & copper_waitmask) && - (!copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY))) + if ((curpos & state->copper_waitmask) >= (state->copper_waitval & state->copper_waitmask) && + (!state->copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY))) { - copper_waiting = FALSE; + state->copper_waiting = FALSE; #if GUESS_COPPER_OFFSET - return xpos + COPPER_CYCLES_TO_PIXELS(1 + wait_offset); + return xpos + COPPER_CYCLES_TO_PIXELS(1 + state->wait_offset); #else return xpos + COPPER_CYCLES_TO_PIXELS(1 + 3); #endif } /* otherwise, see if this line is even a possibility; if not, punt */ - if (((curpos | 0xff) & copper_waitmask) < (copper_waitval & copper_waitmask)) + if (((curpos | 0xff) & state->copper_waitmask) < (state->copper_waitval & state->copper_waitmask)) return 511; /* else just advance another pixel */ @@ -255,17 +218,17 @@ static int copper_execute_next(running_machine *machine, int xpos) } /* fetch the first data word */ - word0 = amiga_chip_ram_r(copper_pc); - copper_pc += 2; + word0 = (*state->chip_ram_r)(state, state->copper_pc); + state->copper_pc += 2; xpos += COPPER_CYCLES_TO_PIXELS(1); /* fetch the second data word */ - word1 = amiga_chip_ram_r(copper_pc); - copper_pc += 2; + word1 = (*state->chip_ram_r)(state, state->copper_pc); + state->copper_pc += 2; xpos += COPPER_CYCLES_TO_PIXELS(1); if (LOG_COPPER) - logerror("%02X.%02X: Copper inst @ %06x = %04x %04x\n", last_scanline, xpos / 2, copper_pc, word0, word1); + logerror("%02X.%02X: Copper inst @ %06x = %04x %04x\n", state->last_scanline, xpos / 2, state->copper_pc, word0, word1); /* handle a move */ if ((word0 & 1) == 0) @@ -278,56 +241,56 @@ static int copper_execute_next(running_machine *machine, int xpos) { /* write it at the *end* of this instruction's cycles */ /* needed for Arcadia's Fast Break */ - copper_pending_offset = word0; - copper_pending_data = word1; + state->copper_pending_offset = word0; + state->copper_pending_data = word1; } /* illegal writes suspend until next frame */ else { if (LOG_COPPER) - logerror("%02X.%02X: Aborting copper on illegal write\n", last_scanline, xpos / 2); + logerror("%02X.%02X: Aborting copper on illegal write\n", state->last_scanline, xpos / 2); - copper_waitval = 0xffff; - copper_waitmask = 0xffff; - copper_waitblit = FALSE; - copper_waiting = TRUE; + state->copper_waitval = 0xffff; + state->copper_waitmask = 0xffff; + state->copper_waitblit = FALSE; + state->copper_waiting = TRUE; return 511; } } else { /* extract common wait/skip values */ - copper_waitval = word0 & 0xfffe; - copper_waitmask = word1 | 0x8001; - copper_waitblit = (~word1 >> 15) & 1; + state->copper_waitval = word0 & 0xfffe; + state->copper_waitmask = word1 | 0x8001; + state->copper_waitblit = (~word1 >> 15) & 1; /* handle a wait */ if ((word1 & 1) == 0) { if (LOG_COPPER) - logerror(" Waiting for %04x & %04x (currently %04x)\n", copper_waitval, copper_waitmask, (last_scanline << 8) | (xpos >> 1)); + logerror(" Waiting for %04x & %04x (currently %04x)\n", state->copper_waitval, state->copper_waitmask, (state->last_scanline << 8) | (xpos >> 1)); - copper_waiting = TRUE; + state->copper_waiting = TRUE; } /* handle a skip */ else { - int curpos = (last_scanline << 8) | (xpos >> 1); + int curpos = (state->last_scanline << 8) | (xpos >> 1); if (LOG_COPPER) - logerror(" Skipping if %04x & %04x (currently %04x)\n", copper_waitval, copper_waitmask, (last_scanline << 8) | (xpos >> 1)); + logerror(" Skipping if %04x & %04x (currently %04x)\n", state->copper_waitval, state->copper_waitmask, (state->last_scanline << 8) | (xpos >> 1)); /* if we're past the wait time, stop it and hold up 2 cycles */ - if ((curpos & copper_waitmask) >= (copper_waitval & copper_waitmask) && - (!copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY))) + if ((curpos & state->copper_waitmask) >= (state->copper_waitval & state->copper_waitmask) && + (!state->copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY))) { if (LOG_COPPER) logerror(" Skipped\n"); /* count the cycles it out have taken to fetch the next instruction */ - copper_pc += 4; + state->copper_pc += 4; xpos += COPPER_CYCLES_TO_PIXELS(2); } } @@ -345,22 +308,31 @@ static int copper_execute_next(running_machine *machine, int xpos) * *************************************/ -void amiga_sprite_dma_reset(int which) +void amiga_sprite_dma_reset(running_machine *machine, int which) { - sprite_dma_reload_mask |= 1 << which; - sprite_dma_live_mask |= 1 << which; + amiga_state *state = machine->driver_data(); + + if (LOG_SPRITE_DMA) logerror("sprite %d dma reset\n", which ); + state->sprite_dma_reload_mask |= 1 << which; + state->sprite_dma_live_mask |= 1 << which; } -void amiga_sprite_enable_comparitor(int which, int enable) +void amiga_sprite_enable_comparitor(running_machine *machine, int which, int enable) { + amiga_state *state = machine->driver_data(); + + if (LOG_SPRITE_DMA) logerror("sprite %d comparitor %sable\n", which, enable ? "en" : "dis" ); if (enable) { - sprite_comparitor_enable_mask |= 1 << which; - sprite_dma_live_mask &= ~(1 << which); + state->sprite_comparitor_enable_mask |= 1 << which; + state->sprite_dma_live_mask &= ~(1 << which); } else - sprite_comparitor_enable_mask &= ~(1 << which); + { + state->sprite_comparitor_enable_mask &= ~(1 << which); + state->sprite_ctl_written |= (1 << which); + } } @@ -371,7 +343,15 @@ void amiga_sprite_enable_comparitor(int which, int enable) * *************************************/ -static void update_sprite_dma(int scanline) +INLINE void fetch_sprite_data(amiga_state *state, int scanline, int sprite) +{ + CUSTOM_REG(REG_SPR0DATA + 4 * sprite) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + CUSTOM_REG(REG_SPR0DATB + 4 * sprite) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; + if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X\n", scanline, sprite, CUSTOM_REG(REG_SPR0DATA + 4 * sprite), CUSTOM_REG(REG_SPR0DATB + 4 * sprite)); +} + +static void update_sprite_dma(amiga_state *state, int scanline) { int dmaenable = (CUSTOM_REG(REG_DMACON) & (DMACON_SPREN | DMACON_DMAEN)) == (DMACON_SPREN | DMACON_DMAEN); int num, maxdma; @@ -388,15 +368,15 @@ static void update_sprite_dma(int scanline) int vstart, vstop; /* if we are == VSTOP, fetch new control words */ - if (dmaenable && (sprite_dma_live_mask & bitmask) && (sprite_dma_reload_mask & bitmask)) + if (dmaenable && (state->sprite_dma_live_mask & bitmask) && (state->sprite_dma_reload_mask & bitmask)) { /* disable the sprite */ - sprite_comparitor_enable_mask &= ~bitmask; - sprite_dma_reload_mask &= ~bitmask; + state->sprite_comparitor_enable_mask &= ~bitmask; + state->sprite_dma_reload_mask &= ~bitmask; /* fetch data into the control words */ - CUSTOM_REG(REG_SPR0POS + 4 * num) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0); - CUSTOM_REG(REG_SPR0CTL + 4 * num) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2); + CUSTOM_REG(REG_SPR0POS + 4 * num) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0); + CUSTOM_REG(REG_SPR0CTL + 4 * num) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 4; if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: pos=%04X ctl=%04X\n", scanline, num, CUSTOM_REG(REG_SPR0POS + 4 * num), CUSTOM_REG(REG_SPR0CTL + 4 * num)); } @@ -408,27 +388,25 @@ static void update_sprite_dma(int scanline) /* if we hit vstart, enable the comparitor */ if (scanline == vstart) { - sprite_comparitor_enable_mask |= 1 << num; + state->sprite_comparitor_enable_mask |= 1 << num; if (LOG_SPRITE_DMA) logerror("%3d:sprite %d comparitor enable\n", scanline, num); } /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */ if (scanline == vstop) { - sprite_comparitor_enable_mask &= ~bitmask; - sprite_dma_reload_mask |= 1 << num; + state->sprite_ctl_written &= ~bitmask; + state->sprite_comparitor_enable_mask &= ~bitmask; + state->sprite_dma_reload_mask |= 1 << num; CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0; /* just a guess */ CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0; if (LOG_SPRITE_DMA) logerror("%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num); } /* fetch data if this sprite is enabled */ - if (dmaenable && (sprite_dma_live_mask & bitmask) && (sprite_comparitor_enable_mask & bitmask)) + if (dmaenable && (state->sprite_dma_live_mask & bitmask) && (state->sprite_comparitor_enable_mask & bitmask)) { - CUSTOM_REG(REG_SPR0DATA + 4 * num) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0); - CUSTOM_REG(REG_SPR0DATB + 4 * num) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2); - CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 4; - if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X\n", scanline, num, CUSTOM_REG(REG_SPR0DATA + 4 * num), CUSTOM_REG(REG_SPR0DATB + 4 * num)); + fetch_sprite_data(state, scanline, num); } } } @@ -443,37 +421,37 @@ static void update_sprite_dma(int scanline) INLINE UINT32 interleave_sprite_data(UINT16 lobits, UINT16 hibits) { - return (expand_byte[lobits & 0xff] << 0) | (expand_byte[lobits >> 8] << 16) | - (expand_byte[hibits & 0xff] << 1) | (expand_byte[hibits >> 8] << 17); + return (amiga_expand_byte[lobits & 0xff] << 0) | (amiga_expand_byte[lobits >> 8] << 16) | + (amiga_expand_byte[hibits & 0xff] << 1) | (amiga_expand_byte[hibits >> 8] << 17); } -static int get_sprite_pixel(int x) +static int get_sprite_pixel(amiga_state *state, int x) { int pixels = 0; int num, pair; /* loop over sprite channels */ for (num = 0; num < 8; num++) - if (sprite_comparitor_enable_mask & (1 << num)) + if (state->sprite_comparitor_enable_mask & (1 << num)) { /* if we're not currently clocking, check against hstart */ - if (sprite_remain[num] == 0) + if (state->sprite_remain[num] == 0) { int hstart = ((CUSTOM_REG(REG_SPR0POS + 4 * num) & 0xff) << 1) | (CUSTOM_REG(REG_SPR0CTL + 4 * num) & 1); if (hstart == x) { - sprite_remain[num] = 16; - sprite_shiftreg[num] = interleave_sprite_data(CUSTOM_REG(REG_SPR0DATA + 4 * num), CUSTOM_REG(REG_SPR0DATB + 4 * num)); + state->sprite_remain[num] = 16; + state->sprite_shiftreg[num] = interleave_sprite_data(CUSTOM_REG(REG_SPR0DATA + 4 * num), CUSTOM_REG(REG_SPR0DATB + 4 * num)); } } /* clock the next pixel if we're doing it */ - if (sprite_remain[num] != 0) + if (state->sprite_remain[num] != 0) { - sprite_remain[num]--; - pixels |= (sprite_shiftreg[num] & 0xc0000000) >> (16 + 2 * (7 - num)); - sprite_shiftreg[num] <<= 2; + state->sprite_remain[num]--; + pixels |= (state->sprite_shiftreg[num] & 0xc0000000) >> (16 + 2 * (7 - num)); + state->sprite_shiftreg[num] <<= 2; } } @@ -491,6 +469,7 @@ static int get_sprite_pixel(int x) 0x0000, 0x0800, 0x2000, 0x2a00, 0x4000, 0x4c00, 0x7000, 0x7e00 }; int collide; + const int esprm = 0x10, osprm = 0x10; /* OR the two sprite bits together so we only have 1 bit per sprite */ collide = pixels | (pixels >> 1); @@ -513,18 +492,19 @@ static int get_sprite_pixel(int x) sprite present bitmask in bits 6-9 topmost sprite pair index in bits 10-11 */ + UINT32 result = (collide << 6) | (pair << 10); /* attached case */ if (CUSTOM_REG(REG_SPR1CTL + 8 * pair) & 0x0080) - return (pixels & 0xf) | 0x10 | (collide << 6) | (pair << 10); + return (pixels & 0xf) | osprm | result; /* lower-numbered sprite of pair */ else if (pixels & 3) - return (pixels & 3) | 0x10 | (pair << 2) | (collide << 6) | (pair << 10); + return (pixels & 3) | esprm | (pair << 2) | result; /* higher-numbered sprite of pair */ else - return ((pixels >> 2) & 3) | 0x10 | (pair << 2) | (collide << 6) | (pair << 10); + return ((pixels >> 2) & 3) | osprm | (pair << 2) | result; } } @@ -539,7 +519,7 @@ static int get_sprite_pixel(int x) * *************************************/ -INLINE UINT8 assemble_odd_bitplanes(int planes, int obitoffs) +INLINE UINT8 assemble_odd_bitplanes(amiga_state *state, int planes, int obitoffs) { UINT8 pix = (CUSTOM_REG(REG_BPL1DAT) >> obitoffs) & 1; if (planes >= 3) @@ -552,7 +532,7 @@ INLINE UINT8 assemble_odd_bitplanes(int planes, int obitoffs) } -INLINE UINT8 assemble_even_bitplanes(int planes, int ebitoffs) +INLINE UINT8 assemble_even_bitplanes(amiga_state *state, int planes, int ebitoffs) { UINT8 pix = 0; if (planes >= 2) @@ -568,6 +548,11 @@ INLINE UINT8 assemble_even_bitplanes(int planes, int ebitoffs) return pix; } +INLINE void fetch_bitplane_data(amiga_state *state, int plane) +{ + CUSTOM_REG(REG_BPL1DAT + plane) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)); + CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; +} /************************************* @@ -576,27 +561,27 @@ INLINE UINT8 assemble_even_bitplanes(int planes, int ebitoffs) * *************************************/ -INLINE int update_ham(int newpix) +INLINE int update_ham(amiga_state *state, int newpix) { switch (newpix >> 4) { case 0: - ham_color = CUSTOM_REG(REG_COLOR00 + (newpix & 0xf)); + state->ham_color = CUSTOM_REG(REG_COLOR00 + (newpix & 0xf)); break; case 1: - ham_color = (ham_color & 0xff0) | ((newpix & 0xf) << 0); + state->ham_color = (state->ham_color & 0xff0) | ((newpix & 0xf) << 0); break; case 2: - ham_color = (ham_color & 0x0ff) | ((newpix & 0xf) << 8); + state->ham_color = (state->ham_color & 0x0ff) | ((newpix & 0xf) << 8); break; case 3: - ham_color = (ham_color & 0xf0f) | ((newpix & 0xf) << 4); + state->ham_color = (state->ham_color & 0xf0f) | ((newpix & 0xf) << 4); break; } - return ham_color; + return state->ham_color; } @@ -609,6 +594,7 @@ INLINE int update_ham(int newpix) void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanline) { + amiga_state *state = machine->driver_data(); UINT16 save_color0 = CUSTOM_REG(REG_COLOR00); int ddf_start_pixel = 0, ddf_stop_pixel = 0; int hires = 0, dualpf = 0, lace = 0, ham = 0; @@ -624,29 +610,30 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl int edelay = 0, odelay = 0; int next_copper_x; int pl; + const int defbitoffs = 15; - last_scanline = scanline; + state->last_scanline = scanline; /* on the first scanline, reset the COPPER and HAM color */ if (scanline == 0) { - copper_setpc(CUSTOM_REG_LONG(REG_COP1LCH)); - ham_color = CUSTOM_REG(REG_COLOR00); + amiga_copper_setpc(machine, CUSTOM_REG_LONG(REG_COP1LCH)); + state->ham_color = CUSTOM_REG(REG_COLOR00); } /* update sprite data fetching */ - update_sprite_dma(scanline); + update_sprite_dma(state, scanline); /* start of a new line, signal we're not done with it and fill up vars */ if (bitmap != NULL) dst = BITMAP_ADDR16(bitmap, scanline, 0); /* all sprites off at the start of the line */ - memset(sprite_remain, 0, sizeof(sprite_remain)); + memset(state->sprite_remain, 0, sizeof(state->sprite_remain)); /* temporary set color 0 to the genlock color */ - if (genlock_color != 0xffff) - CUSTOM_REG(REG_COLOR00) = genlock_color; + if (state->genlock_color != 0xffff) + CUSTOM_REG(REG_COLOR00) = state->genlock_color; /* loop over the line */ next_copper_x = 2; /* copper runs on odd timeslots */ @@ -659,10 +646,10 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl { /* execute the next batch, restoring and re-saving color 0 around it */ CUSTOM_REG(REG_COLOR00) = save_color0; - next_copper_x = copper_execute_next(machine, x); + next_copper_x = amiga_copper_execute_next(machine, x); save_color0 = CUSTOM_REG(REG_COLOR00); - if (genlock_color != 0xffff) - CUSTOM_REG(REG_COLOR00) = genlock_color; + if (state->genlock_color != 0xffff) + CUSTOM_REG(REG_COLOR00) = state->genlock_color; /* compute update-related register values */ planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12; @@ -673,18 +660,20 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* compute the pixel fetch parameters */ ddf_start_pixel = ( CUSTOM_REG(REG_DDFSTRT) & 0xfc ) * 2 + (hires ? 9 : 17); - ddf_stop_pixel = ( CUSTOM_REG(REG_DDFSTOP) & 0xfc ) * 2 + (hires ? (9 + 15) : (17 + 15)); + ddf_stop_pixel = ( CUSTOM_REG(REG_DDFSTOP) & 0xfc ) * 2 + (hires ? (9 + defbitoffs) : (17 + defbitoffs)); if ( ( CUSTOM_REG(REG_DDFSTRT) ^ CUSTOM_REG(REG_DDFSTOP) ) & 0x04 ) ddf_stop_pixel += 8; /* compute the horizontal start/stop */ hstart = CUSTOM_REG(REG_DIWSTRT) & 0xff; - hstop = 0x100 + (CUSTOM_REG(REG_DIWSTOP) & 0xff); + hstop = (CUSTOM_REG(REG_DIWSTOP) & 0xff); + hstop |= 0x100; /* compute the vertical start/stop */ vstart = CUSTOM_REG(REG_DIWSTRT) >> 8; - vstop = (CUSTOM_REG(REG_DIWSTOP) >> 8) | ((~CUSTOM_REG(REG_DIWSTOP) >> 7) & 0x100); + vstop = (CUSTOM_REG(REG_DIWSTOP) >> 8); + vstop |= ((~CUSTOM_REG(REG_DIWSTOP) >> 7) & 0x100); /* extract playfield priorities */ pf1pri = CUSTOM_REG(REG_BPLCON2) & 7; @@ -708,8 +697,8 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl if ( hires ) { - obitoffs = 15 + ( odelay << 1 ); - ebitoffs = 15 + ( edelay << 1 ); + obitoffs = defbitoffs + ( odelay << 1 ); + ebitoffs = defbitoffs + ( edelay << 1 ); } else { @@ -719,8 +708,8 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl edelay = ( edelay + 8 ) & 0x0f; } - obitoffs = 15 + odelay; - ebitoffs = 15 + edelay; + obitoffs = defbitoffs + odelay; + ebitoffs = defbitoffs + edelay; } for (pl = 0; pl < 6; pl++) @@ -728,7 +717,7 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl } /* need to run the sprite engine every pixel to ensure display */ - sprpix = get_sprite_pixel(x); + sprpix = get_sprite_pixel(state, x); /* to render, we must have bitplane DMA enabled, at least 1 plane, and be within the */ /* vertical display window */ @@ -741,15 +730,16 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl if (x >= ddf_start_pixel && x <= ddf_stop_pixel + odelay) { /* if we need to fetch more data, do it now */ - if (obitoffs == 15) + if (obitoffs == defbitoffs) + { for (pl = 0; pl < planes; pl += 2) { - CUSTOM_REG(REG_BPL1DAT + pl) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2)); - CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += 2; + fetch_bitplane_data(state, pl); } + } /* now assemble the bits */ - pfpix0 |= assemble_odd_bitplanes(planes, obitoffs); + pfpix0 |= assemble_odd_bitplanes(state, planes, obitoffs); obitoffs--; /* for high res, assemble a second set of bits */ @@ -758,16 +748,15 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* reset bit offsets and fetch more data if needed */ if (obitoffs < 0) { - obitoffs = 15; + obitoffs = defbitoffs; for (pl = 0; pl < planes; pl += 2) { - CUSTOM_REG(REG_BPL1DAT + pl) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2)); - CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += 2; + fetch_bitplane_data(state, pl); } } - pfpix1 |= assemble_odd_bitplanes(planes, obitoffs); + pfpix1 |= assemble_odd_bitplanes(state, planes, obitoffs); obitoffs--; } else @@ -775,22 +764,23 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* reset bit offsets if needed */ if (obitoffs < 0) - obitoffs = 15; + obitoffs = defbitoffs; } /* fetch the even bits if we are within the fetching region */ if (x >= ddf_start_pixel && x <= ddf_stop_pixel + edelay) { /* if we need to fetch more data, do it now */ - if (ebitoffs == 15) + if (ebitoffs == defbitoffs) + { for (pl = 1; pl < planes; pl += 2) { - CUSTOM_REG(REG_BPL1DAT + pl) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2)); - CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += 2; + fetch_bitplane_data(state, pl); } + } /* now assemble the bits */ - pfpix0 |= assemble_even_bitplanes(planes, ebitoffs); + pfpix0 |= assemble_even_bitplanes(state, planes, ebitoffs); ebitoffs--; /* for high res, assemble a second set of bits */ @@ -799,16 +789,15 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* reset bit offsets and fetch more data if needed */ if (ebitoffs < 0) { - ebitoffs = 15; + ebitoffs = defbitoffs; for (pl = 1; pl < planes; pl += 2) { - CUSTOM_REG(REG_BPL1DAT + pl) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2)); - CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += 2; + fetch_bitplane_data(state, pl); } } - pfpix1 |= assemble_even_bitplanes(planes, ebitoffs); + pfpix1 |= assemble_even_bitplanes(state, planes, ebitoffs); ebitoffs--; } else @@ -816,7 +805,7 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* reset bit offsets if needed */ if (ebitoffs < 0) - ebitoffs = 15; + ebitoffs = defbitoffs; } /* compute playfield/sprite collisions for first pixel */ @@ -840,17 +829,22 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* if we are within the display region, render */ if (dst != NULL && x >= hstart && x < hstop) { + int pix, pri; + /* hold-and-modify mode -- assume low-res (hi-res not supported by the hardware) */ if (ham) { /* update the HAM color */ - pfpix0 = update_ham(pfpix0); + pfpix0 = update_ham(state, pfpix0); + + pix = sprpix & 0x1f; + pri = (sprpix >> 10); /* sprite has priority */ - if (sprpix && pf1pri > (sprpix >> 10)) + if (sprpix && pf1pri > pri) { dst[x*2+0] = - dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + (sprpix & 0x1f)); + dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix); } /* playfield has priority */ @@ -864,15 +858,14 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl /* dual playfield mode */ else if (dualpf) { - int pix; - /* mask out the sprite if it doesn't have priority */ pix = sprpix & 0x1f; + pri = (sprpix >> 10); if (pix) { - if ((pfpix0 & 0x15) && pf1pri <= (sprpix >> 10)) + if ((pfpix0 & 0x15) && pf1pri <= pri) pix = 0; - if ((pfpix0 & 0x2a) && pf2pri <= (sprpix >> 10)) + if ((pfpix0 & 0x2a) && pf2pri <= pri) pix = 0; } @@ -880,15 +873,15 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl if (pix) dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + pix); else - dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]); + dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + state->separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]); /* mask out the sprite if it doesn't have priority */ pix = sprpix & 0x1f; if (pix) { - if ((pfpix1 & 0x15) && pf1pri <= (sprpix >> 10)) + if ((pfpix1 & 0x15) && pf1pri <= pri) pix = 0; - if ((pfpix1 & 0x2a) && pf2pri <= (sprpix >> 10)) + if ((pfpix1 & 0x2a) && pf2pri <= pri) pix = 0; } @@ -896,17 +889,20 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl if (pix) dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix); else - dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]); + dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + state->separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]); } /* single playfield mode */ else { + pix = sprpix & 0x1f; + pri = (sprpix >> 10); + /* sprite has priority */ - if (sprpix && pf1pri > (sprpix >> 10)) + if (sprpix && pf1pri > pri) { dst[x*2+0] = - dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + (sprpix & 0x1f)); + dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix); } /* playfield has priority */ @@ -961,9 +957,9 @@ void amiga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanl if (machine->primary_screen->frame_number() % 64 == 0 && scanline == 0) { if (input_code_pressed(machine, KEYCODE_Q)) - popmessage("%d", wait_offset -= 1); + popmessage("%d", state->wait_offset -= 1); if (input_code_pressed(machine, KEYCODE_W)) - popmessage("%d", wait_offset += 1); + popmessage("%d", state->wait_offset += 1); } #endif } diff --git a/src/mame/video/amigaaga.c b/src/mame/video/amigaaga.c index 9191f560faf..013d7f570d4 100644 --- a/src/mame/video/amigaaga.c +++ b/src/mame/video/amigaaga.c @@ -22,130 +22,22 @@ To do: -/************************************* - * - * Debugging - * - *************************************/ - -#define LOG_COPPER 0 -#define GUESS_COPPER_OFFSET 0 -#define LOG_SPRITE_DMA 0 - - - -/************************************* - * - * Macros - * - *************************************/ - -#define COPPER_CYCLES_TO_PIXELS(x) (4 * (x)) - - - /************************************* * * Statics * *************************************/ -/* palette */ -static pen_t aga_palette[256]; - -/* AGA bpldat registers */ -static UINT64 aga_bpldat[8]; - -/* sprite states */ -static UINT8 sprite_comparitor_enable_mask; -static UINT8 sprite_dma_reload_mask; -static UINT8 sprite_dma_live_mask; -static UINT8 sprite_ctl_written; -static UINT32 sprite_shiftreg[8]; -static UINT8 sprite_remain[8]; -static UINT16 aga_sprdata[8][4]; -static UINT16 aga_sprdatb[8][4]; -static int aga_sprite_fetched_words; -static int aga_sprite_dma_used_words[8]; - -/* playfield states */ -static int last_scanline; -static pen_t ham_color; -static int diwhigh_written; - -/* copper states */ -static UINT32 copper_pc; -static UINT8 copper_waiting; -static UINT8 copper_waitblit; -static UINT16 copper_waitval; -static UINT16 copper_waitmask; -static UINT16 copper_pending_offset; -static UINT16 copper_pending_data; - -/* misc states */ -static UINT16 genlock_color; - -#if GUESS_COPPER_OFFSET -static int wait_offset = 3; -#endif - - - -/************************************* - * - * Tables - * - *************************************/ - -/* expand an 8-bit bit pattern into 16 bits, every other bit */ -static const UINT16 expand_byte[256] = -{ - 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, - 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, - 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, - 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, - 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, - 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, - 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, - 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, - 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, - 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, - 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, - 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, - 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, - 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, - 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, - 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, - - 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, - 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, - 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, - 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, - 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, - 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, - 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, - 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, - 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, - 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, - 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, - 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, - 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, - 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, - 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, - 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 -}; - -/* separate 6 in-order bitplanes into 2 x 3-bit bitplanes in two nibbles */ -static UINT8 separate_bitplanes[2][64]; - /************************************* * * Palette * *************************************/ -void aga_palette_write(int color_reg, UINT16 data) +void amiga_aga_palette_write(running_machine *machine, int color_reg, UINT16 data) { + amiga_state *state = machine->driver_data(); + pen_t *aga_palette = state->aga_palette; int r,g,b; int cr,cg,cb; int color; @@ -181,232 +73,11 @@ void aga_palette_write(int color_reg, UINT16 data) VIDEO_START( amiga_aga ) { - int j; + amiga_state *state = machine->driver_data(); - /* generate tables that produce the correct playfield color for dual playfield mode */ - for (j = 0; j < 64; j++) - { - int pf1pix = ((j >> 0) & 1) | ((j >> 1) & 2) | ((j >> 2) & 4); - int pf2pix = ((j >> 1) & 1) | ((j >> 2) & 2) | ((j >> 3) & 4); + VIDEO_START_CALL( amiga ); - separate_bitplanes[0][j] = (pf1pix || !pf2pix) ? pf1pix : (pf2pix + 8); - separate_bitplanes[1][j] = pf2pix ? (pf2pix + 8) : pf1pix; - } - - /* reset the genlock color */ - genlock_color = 0xffff; - - sprite_ctl_written = 0; - diwhigh_written = 0; -} - - - -/************************************* - * - * Beam position - * - *************************************/ - -UINT32 amiga_aga_gethvpos(screen_device &screen) -{ - UINT32 hvpos = (last_scanline << 8) | (screen.hpos() >> 2); - UINT32 latchedpos = input_port_read_safe(screen.machine, "HVPOS", 0); - - /* if there's no latched position, or if we are in the active display area */ - /* but before the latching point, return the live HV position */ - if ((CUSTOM_REG(REG_BPLCON0) & 0x0008) == 0 || latchedpos == 0 || (last_scanline >= 20 && hvpos < latchedpos)) - return hvpos; - - /* otherwise, return the latched position */ - return latchedpos; -} - - - -/************************************* - * - * Genlock interaction - * - *************************************/ - -void amiga_aga_set_genlock_color(UINT16 color) -{ - genlock_color = color; -} - - - -/************************************* - * - * Copper emulation - * - *************************************/ - -void aga_copper_setpc(UINT32 pc) -{ - if (LOG_COPPER) - logerror("copper_setpc(%06x)\n", pc); - - copper_pc = pc; - copper_waiting = FALSE; -} - -static int copper_execute_next(running_machine *machine, int xpos) -{ - int word0, word1; - - /* bail if not enabled */ - if ((CUSTOM_REG(REG_DMACON) & (DMACON_COPEN | DMACON_DMAEN)) != (DMACON_COPEN | DMACON_DMAEN)) - return 511; - - /* flush any pending writes */ - if (copper_pending_offset) - { - if (LOG_COPPER) - logerror("%02X.%02X: Write to %s = %04x\n", last_scanline, xpos / 2, amiga_custom_names[copper_pending_offset & 0xff], copper_pending_data); - - amiga_custom_w(cputag_get_address_space(machine, "maincpu", ADDRESS_SPACE_PROGRAM), copper_pending_offset, copper_pending_data, 0xffff); - copper_pending_offset = 0; - } - - /* if we're waiting, check for a breakthrough */ - if (copper_waiting) - { - int curpos = (last_scanline << 8) | (xpos >> 1); - - /* if we're past the wait time, stop it and hold up 2 cycles */ - if ((curpos & copper_waitmask) >= (copper_waitval & copper_waitmask) && - (!copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY))) - { - copper_waiting = FALSE; -#if GUESS_COPPER_OFFSET - return xpos + COPPER_CYCLES_TO_PIXELS(1 + wait_offset); -#else - return xpos + COPPER_CYCLES_TO_PIXELS(1 + 3); -#endif - } - - /* otherwise, see if this line is even a possibility; if not, punt */ - if (((curpos | 0xff) & copper_waitmask) < (copper_waitval & copper_waitmask)) - return 511; - - /* else just advance another pixel */ - xpos += COPPER_CYCLES_TO_PIXELS(1); - return xpos; - } - - /* fetch the first data word */ - word0 = amiga_chip_ram_r(copper_pc); - copper_pc += 2; - xpos += COPPER_CYCLES_TO_PIXELS(1); - - /* fetch the second data word */ - word1 = amiga_chip_ram_r(copper_pc); - copper_pc += 2; - xpos += COPPER_CYCLES_TO_PIXELS(1); - - if (LOG_COPPER) - logerror("%02X.%02X: Copper inst @ %06x = %04x %04x\n", last_scanline, xpos / 2, copper_pc, word0, word1); - - /* handle a move */ - if ((word0 & 1) == 0) - { - int min = (CUSTOM_REG(REG_COPCON) & 2) ? 0x20 : 0x40; - - /* do the write if we're allowed */ - word0 = (word0 >> 1) & 0xff; - if (word0 >= min) - { - /* write it at the *end* of this instruction's cycles */ - /* needed for Arcadia's Fast Break */ - copper_pending_offset = word0; - copper_pending_data = word1; - } - - /* illegal writes suspend until next frame */ - else - { - if (LOG_COPPER) - logerror("%02X.%02X: Aborting copper on illegal write\n", last_scanline, xpos / 2); - - copper_waitval = 0xffff; - copper_waitmask = 0xffff; - copper_waitblit = FALSE; - copper_waiting = TRUE; - return 511; - } - } - else - { - /* extract common wait/skip values */ - copper_waitval = word0 & 0xfffe; - copper_waitmask = word1 | 0x8001; - copper_waitblit = (~word1 >> 15) & 1; - - /* handle a wait */ - if ((word1 & 1) == 0) - { - if (LOG_COPPER) - logerror(" Waiting for %04x & %04x (currently %04x)\n", copper_waitval, copper_waitmask, (last_scanline << 8) | (xpos >> 1)); - - copper_waiting = TRUE; - } - - /* handle a skip */ - else - { - int curpos = (last_scanline << 8) | (xpos >> 1); - - if (LOG_COPPER) - logerror(" Skipping if %04x & %04x (currently %04x)\n", copper_waitval, copper_waitmask, (last_scanline << 8) | (xpos >> 1)); - - /* if we're past the wait time, stop it and hold up 2 cycles */ - if ((curpos & copper_waitmask) >= (copper_waitval & copper_waitmask) && - (!copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY))) - { - if (LOG_COPPER) - logerror(" Skipped\n"); - - /* count the cycles it out have taken to fetch the next instruction */ - copper_pc += 4; - xpos += COPPER_CYCLES_TO_PIXELS(2); - } - } - } - - /* advance and consume 8 cycles */ - return xpos; -} - - -/************************************* - * - * External sprite controls - * - *************************************/ - -void amiga_aga_sprite_dma_reset(int which) -{ - if (LOG_SPRITE_DMA) logerror("sprite %d dma reset\n", which ); - sprite_dma_reload_mask |= 1 << which; - sprite_dma_live_mask |= 1 << which; -} - - -void amiga_aga_sprite_enable_comparitor(int which, int enable) -{ - if (LOG_SPRITE_DMA) logerror("sprite %d comparitor %sable\n", which, enable ? "en" : "dis" ); - if (enable) - { - sprite_comparitor_enable_mask |= 1 << which; - sprite_dma_live_mask &= ~(1 << which); - } - else - { - sprite_comparitor_enable_mask &= ~(1 << which); - sprite_ctl_written |= (1 << which); - } + state->aga_diwhigh_written = 0; } @@ -417,54 +88,54 @@ void amiga_aga_sprite_enable_comparitor(int which, int enable) * *************************************/ -INLINE void fetch_sprite_data(int scanline, int sprite) +INLINE void fetch_sprite_data(amiga_state *state, int scanline, int sprite) { switch((CUSTOM_REG(REG_FMODE) >> 2) & 0x03) { case 0: - aga_sprdata[sprite][0] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdatb[sprite][0] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdata[sprite][0] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdatb[sprite][0] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprite_fetched_words = 1; - if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X\n", scanline, sprite, aga_sprdata[sprite][0], aga_sprdatb[sprite][0]); + state->aga_sprite_fetched_words = 1; + if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X\n", scanline, sprite, state->aga_sprdata[sprite][0], state->aga_sprdatb[sprite][0]); break; case 1: case 2: - aga_sprdata[sprite][0] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdata[sprite][1] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdata[sprite][0] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdata[sprite][1] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprdatb[sprite][0] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdatb[sprite][1] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdatb[sprite][0] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdatb[sprite][1] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprite_fetched_words = 2; - if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X %04X-%04X\n", scanline, sprite, aga_sprdata[sprite][0], aga_sprdatb[sprite][0], aga_sprdata[sprite][1], aga_sprdatb[sprite][1] ); + state->aga_sprite_fetched_words = 2; + if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X %04X-%04X\n", scanline, sprite, state->aga_sprdata[sprite][0], state->aga_sprdatb[sprite][0], state->aga_sprdata[sprite][1], state->aga_sprdatb[sprite][1] ); break; case 3: - aga_sprdata[sprite][0] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdata[sprite][1] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdata[sprite][0] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdata[sprite][1] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprdata[sprite][2] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdata[sprite][3] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdata[sprite][2] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdata[sprite][3] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprdatb[sprite][0] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdatb[sprite][1] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdatb[sprite][0] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdatb[sprite][1] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprdatb[sprite][2] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); - aga_sprdatb[sprite][3] = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); + state->aga_sprdatb[sprite][2] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0); + state->aga_sprdatb[sprite][3] = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4; - aga_sprite_fetched_words = 4; + state->aga_sprite_fetched_words = 4; if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X %04X-%04X %04X-%04X %04X-%04X\n", scanline, sprite, - aga_sprdata[sprite][0], aga_sprdatb[sprite][0], - aga_sprdata[sprite][1], aga_sprdatb[sprite][1], - aga_sprdata[sprite][2], aga_sprdatb[sprite][2], - aga_sprdata[sprite][3], aga_sprdatb[sprite][3]); + state->aga_sprdata[sprite][0], state->aga_sprdatb[sprite][0], + state->aga_sprdata[sprite][1], state->aga_sprdatb[sprite][1], + state->aga_sprdata[sprite][2], state->aga_sprdatb[sprite][2], + state->aga_sprdata[sprite][3], state->aga_sprdatb[sprite][3]); break; } - aga_sprite_dma_used_words[sprite] = 0; + state->aga_sprite_dma_used_words[sprite] = 0; } -static void update_sprite_dma(int scanline) +static void update_sprite_dma(amiga_state *state, int scanline) { int dmaenable = (CUSTOM_REG(REG_DMACON) & (DMACON_SPREN | DMACON_DMAEN)) == (DMACON_SPREN | DMACON_DMAEN); int num, maxdma; @@ -481,15 +152,15 @@ static void update_sprite_dma(int scanline) int vstart, vstop; /* if we are == VSTOP, fetch new control words */ - if (dmaenable && (sprite_dma_live_mask & bitmask) && (sprite_dma_reload_mask & bitmask) && !(sprite_ctl_written & bitmask)) + if (dmaenable && (state->sprite_dma_live_mask & bitmask) && (state->sprite_dma_reload_mask & bitmask) && !(state->sprite_ctl_written & bitmask)) { /* disable the sprite */ - sprite_comparitor_enable_mask &= ~bitmask; - sprite_dma_reload_mask &= ~bitmask; + state->sprite_comparitor_enable_mask &= ~bitmask; + state->sprite_dma_reload_mask &= ~bitmask; /* fetch data into the control words */ - CUSTOM_REG(REG_SPR0POS + 4 * num) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0); - CUSTOM_REG(REG_SPR0CTL + 4 * num) = amiga_chip_ram_r(CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2); + CUSTOM_REG(REG_SPR0POS + 4 * num) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0); + CUSTOM_REG(REG_SPR0CTL + 4 * num) = (*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2); CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 4; /* fetch additional words */ switch((CUSTOM_REG(REG_FMODE) >> 2) & 0x03) @@ -514,25 +185,25 @@ static void update_sprite_dma(int scanline) /* if we hit vstart, enable the comparitor */ if (scanline == vstart) { - sprite_comparitor_enable_mask |= 1 << num; + state->sprite_comparitor_enable_mask |= 1 << num; if (LOG_SPRITE_DMA) logerror("%3d:sprite %d comparitor enable\n", scanline, num); } /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */ if (scanline == vstop) { - sprite_ctl_written &= ~bitmask; - sprite_comparitor_enable_mask &= ~bitmask; - sprite_dma_reload_mask |= 1 << num; + state->sprite_ctl_written &= ~bitmask; + state->sprite_comparitor_enable_mask &= ~bitmask; + state->sprite_dma_reload_mask |= 1 << num; CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0; /* just a guess */ CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0; if (LOG_SPRITE_DMA) logerror("%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num); } /* fetch data if this sprite is enabled */ - if (dmaenable && (sprite_dma_live_mask & bitmask) && (sprite_comparitor_enable_mask & bitmask)) + if (dmaenable && (state->sprite_dma_live_mask & bitmask) && (state->sprite_comparitor_enable_mask & bitmask)) { - fetch_sprite_data(scanline, num); + fetch_sprite_data(state, scanline, num); } } } @@ -547,46 +218,47 @@ static void update_sprite_dma(int scanline) INLINE UINT32 interleave_sprite_data(UINT16 lobits, UINT16 hibits) { - return (expand_byte[lobits & 0xff] << 0) | (expand_byte[lobits >> 8] << 16) | - (expand_byte[hibits & 0xff] << 1) | (expand_byte[hibits >> 8] << 17); + return (amiga_expand_byte[lobits & 0xff] << 0) | (amiga_expand_byte[lobits >> 8] << 16) | + (amiga_expand_byte[hibits & 0xff] << 1) | (amiga_expand_byte[hibits >> 8] << 17); } -static int get_sprite_pixel(int x) +static int get_sprite_pixel(amiga_state *state, int x) { int pixels = 0; int num, pair; /* loop over sprite channels */ for (num = 0; num < 8; num++) - if (sprite_comparitor_enable_mask & (1 << num)) + if (state->sprite_comparitor_enable_mask & (1 << num)) { /* if we're not currently clocking, check against hstart */ - if (sprite_remain[num] == 0) + if (state->sprite_remain[num] == 0) { int hstart = ((CUSTOM_REG(REG_SPR0POS + 4 * num) & 0xff) << 1) | (CUSTOM_REG(REG_SPR0CTL + 4 * num) & 1); if (hstart == x) { - sprite_remain[num] = 16; - sprite_shiftreg[num] = interleave_sprite_data(aga_sprdata[num][0], aga_sprdatb[num][0]); - aga_sprite_dma_used_words[num] = 1; + state->sprite_remain[num] = 16; + state->sprite_shiftreg[num] = interleave_sprite_data(state->aga_sprdata[num][0], state->aga_sprdatb[num][0]); + state->aga_sprite_dma_used_words[num] = 1; } } /* clock the next pixel if we're doing it */ - if (sprite_remain[num] != 0) + if (state->sprite_remain[num] != 0) { - sprite_remain[num]--; - pixels |= (sprite_shiftreg[num] & 0xc0000000) >> (16 + 2 * (7 - num)); - sprite_shiftreg[num] <<= 2; + state->sprite_remain[num]--; + pixels |= (state->sprite_shiftreg[num] & 0xc0000000) >> (16 + 2 * (7 - num)); + state->sprite_shiftreg[num] <<= 2; - if (sprite_remain[num] == 0) + if (state->sprite_remain[num] == 0) { - if (aga_sprite_dma_used_words[num] < aga_sprite_fetched_words) + if (state->aga_sprite_dma_used_words[num] < state->aga_sprite_fetched_words) { - sprite_remain[num] = 16; - sprite_shiftreg[num] = interleave_sprite_data(aga_sprdata[num][aga_sprite_dma_used_words[num]], aga_sprdatb[num][aga_sprite_dma_used_words[num]]); - aga_sprite_dma_used_words[num]++; + int w = state->aga_sprite_dma_used_words[num]; + state->sprite_remain[num] = 16; + state->sprite_shiftreg[num] = interleave_sprite_data(state->aga_sprdata[num][w], state->aga_sprdatb[num][w]); + state->aga_sprite_dma_used_words[num]++; } } } @@ -630,20 +302,21 @@ static int get_sprite_pixel(int x) /* final result is: topmost sprite color in bits 0-7 sprite present bitmask in bits 8-9 - topmost sprite pair index in bits 12-11 + topmost sprite pair index in bits 12-13 */ + UINT32 result = (collide << 8) | (pair << 12); /* attached case */ if (CUSTOM_REG(REG_SPR1CTL + 8 * pair) & 0x0080) - return (pixels & 0xf) | osprm | (collide << 8) | (pair << 12); + return (pixels & 0xf) | osprm | result; /* lower-numbered sprite of pair */ else if (pixels & 3) - return (pixels & 3) | esprm | (pair << 2) | (collide << 8) | (pair << 12); + return (pixels & 3) | esprm | (pair << 2) | result; /* higher-numbered sprite of pair */ else - return ((pixels >> 2) & 3) | osprm | (pair << 2) | (collide << 8) | (pair << 12); + return ((pixels >> 2) & 3) | osprm | (pair << 2) | result; } } @@ -658,8 +331,9 @@ static int get_sprite_pixel(int x) * *************************************/ -INLINE UINT8 assemble_odd_bitplanes(int planes, int obitoffs) +INLINE UINT8 assemble_odd_bitplanes(amiga_state *state, int planes, int obitoffs) { + UINT64 *aga_bpldat = state->aga_bpldat; UINT8 pix = (aga_bpldat[0] >> obitoffs) & 1; if (planes >= 3) { @@ -675,11 +349,12 @@ INLINE UINT8 assemble_odd_bitplanes(int planes, int obitoffs) } -INLINE UINT8 assemble_even_bitplanes(int planes, int ebitoffs) +INLINE UINT8 assemble_even_bitplanes(amiga_state *state, int planes, int ebitoffs) { UINT8 pix = 0; if (planes >= 2) { + UINT64 *aga_bpldat = state->aga_bpldat; pix |= ((aga_bpldat[1] >> ebitoffs) & 1) << 1; if (planes >= 4) { @@ -695,37 +370,41 @@ INLINE UINT8 assemble_even_bitplanes(int planes, int ebitoffs) return pix; } -INLINE void fetch_bitplane_data(int plane) +INLINE void fetch_bitplane_data(amiga_state *state, int plane) { + UINT64 *aga_bpldat = state->aga_bpldat; + switch (CUSTOM_REG(REG_FMODE) & 0x03) { case 0: - aga_bpldat[plane] = (UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)); + aga_bpldat[plane] = (UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)); CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; break; case 1: case 2: - aga_bpldat[plane] = (UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)) << 16; + aga_bpldat[plane] = (UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)) << 16; CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; - aga_bpldat[plane] |= ((UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2))); + aga_bpldat[plane] |= ((UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2))); CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; break; case 3: - aga_bpldat[plane] = (UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)) << 48; + aga_bpldat[plane] = (UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)) << 48; CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; - aga_bpldat[plane] |= ((UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2))) << 32; + aga_bpldat[plane] |= ((UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2))) << 32; CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; - aga_bpldat[plane] |= ((UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2))) << 16; + aga_bpldat[plane] |= ((UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2))) << 16; CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; - aga_bpldat[plane] |= (UINT64)amiga_chip_ram_r(CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)); + aga_bpldat[plane] |= (UINT64)(*state->chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2)); CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2; break; } } -void aga_diwhigh_written(int written) +void amiga_aga_diwhigh_written(running_machine *machine, int written) { - diwhigh_written = written; + amiga_state *state = machine->driver_data(); + + state->aga_diwhigh_written = written; } /************************************* @@ -734,27 +413,27 @@ void aga_diwhigh_written(int written) * *************************************/ -INLINE int update_ham(int newpix) +INLINE int update_ham(amiga_state *state, int newpix) { switch (newpix & 0x03) { case 0: - ham_color = aga_palette[(newpix >> 2) & 0x3f]; + state->ham_color = state->aga_palette[(newpix >> 2) & 0x3f]; break; case 1: - ham_color = MAKE_RGB(RGB_RED(ham_color), RGB_GREEN(ham_color), (newpix & 0xfc) | (RGB_BLUE(ham_color) & 0x03)); + state->ham_color = MAKE_RGB(RGB_RED(state->ham_color), RGB_GREEN(state->ham_color), (newpix & 0xfc) | (RGB_BLUE(state->ham_color) & 0x03)); break; case 2: - ham_color = MAKE_RGB((newpix & 0xfc) | (RGB_RED(ham_color) & 0x03), RGB_GREEN(ham_color), RGB_BLUE(ham_color)); + state->ham_color = MAKE_RGB((newpix & 0xfc) | (RGB_RED(state->ham_color) & 0x03), RGB_GREEN(state->ham_color), RGB_BLUE(state->ham_color)); break; case 3: - ham_color = MAKE_RGB(RGB_RED(ham_color), (newpix & 0xfc) | (RGB_GREEN(ham_color) & 0x03), RGB_BLUE(ham_color)); + state->ham_color = MAKE_RGB(RGB_RED(state->ham_color), (newpix & 0xfc) | (RGB_GREEN(state->ham_color) & 0x03), RGB_BLUE(state->ham_color)); break; } - return ham_color; + return state->ham_color; } @@ -767,6 +446,7 @@ INLINE int update_ham(int newpix) void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int scanline) { + amiga_state *state = machine->driver_data(); UINT16 save_color0 = CUSTOM_REG(REG_COLOR00); int ddf_start_pixel = 0, ddf_stop_pixel = 0; int hires = 0, dualpf = 0, lace = 0, ham = 0; @@ -782,31 +462,31 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s int edelay = 0, odelay = 0; int next_copper_x; int pl; - pen_t ham_pix; int defbitoffs = 0; + pen_t *aga_palette = state->aga_palette; - last_scanline = scanline; + state->last_scanline = scanline; /* on the first scanline, reset the COPPER and HAM color */ if (scanline == 0) { - aga_copper_setpc(CUSTOM_REG_LONG(REG_COP1LCH)); - ham_color = CUSTOM_REG(REG_COLOR00); + amiga_copper_setpc(machine, CUSTOM_REG_LONG(REG_COP1LCH)); + state->ham_color = CUSTOM_REG(REG_COLOR00); } /* update sprite data fetching */ - update_sprite_dma(scanline); + update_sprite_dma(state, scanline); /* start of a new line, signal we're not done with it and fill up vars */ if (bitmap != NULL) dst = BITMAP_ADDR32(bitmap, scanline, 0); /* all sprites off at the start of the line */ - memset(sprite_remain, 0, sizeof(sprite_remain)); + memset(state->sprite_remain, 0, sizeof(state->sprite_remain)); /* temporary set color 0 to the genlock color */ - if (genlock_color != 0xffff) - CUSTOM_REG(REG_COLOR00) = genlock_color; + if (state->genlock_color != 0xffff) + CUSTOM_REG(REG_COLOR00) = state->genlock_color; /* loop over the line */ next_copper_x = 2; /* copper runs on odd timeslots */ @@ -819,10 +499,10 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s { /* execute the next batch, restoring and re-saving color 0 around it */ CUSTOM_REG(REG_COLOR00) = save_color0; - next_copper_x = copper_execute_next(machine, x); + next_copper_x = amiga_copper_execute_next(machine, x); save_color0 = CUSTOM_REG(REG_COLOR00); - if (genlock_color != 0xffff) - CUSTOM_REG(REG_COLOR00) = genlock_color; + if (state->genlock_color != 0xffff) + CUSTOM_REG(REG_COLOR00) = state->genlock_color; /* compute update-related register values */ planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12; @@ -854,7 +534,7 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s hstart = CUSTOM_REG(REG_DIWSTRT) & 0xff; hstop = (CUSTOM_REG(REG_DIWSTOP) & 0xff); - if (diwhigh_written) + if (state->aga_diwhigh_written) { hstart |= ((CUSTOM_REG(REG_DIWHIGH) >> 5) & 1) << 8; hstop |= ((CUSTOM_REG(REG_DIWHIGH) >> 13) & 1) << 8; @@ -872,15 +552,14 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s /* compute the vertical start/stop */ vstart = CUSTOM_REG(REG_DIWSTRT) >> 8; vstop = (CUSTOM_REG(REG_DIWSTOP) >> 8); - if (diwhigh_written) + if (state->aga_diwhigh_written) { vstart |= (CUSTOM_REG(REG_DIWHIGH) & 7) << 8; vstop |= ((CUSTOM_REG(REG_DIWHIGH) >> 8) & 7) << 8; } else { - if ((vstop & 0x80) == 0) - vstop |= 0x100; + vstop |= ((~CUSTOM_REG(REG_DIWSTOP) >> 7) & 0x100); } /* extract playfield priorities */ @@ -890,7 +569,6 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s /* extract collision masks */ ocolmask = (CUSTOM_REG(REG_CLXCON) >> 6) & 0x15; ecolmask = (CUSTOM_REG(REG_CLXCON) >> 6) & 0x2a; - } /* clear the target pixels to the background color as a starting point */ @@ -922,11 +600,11 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s } for (pl = 0; pl < 8; pl++) - aga_bpldat[pl] = 0; + state->aga_bpldat[pl] = 0; } /* need to run the sprite engine every pixel to ensure display */ - sprpix = get_sprite_pixel(x); + sprpix = get_sprite_pixel(state, x); /* to render, we must have bitplane DMA enabled, at least 1 plane, and be within the */ /* vertical display window */ @@ -943,12 +621,12 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s { for (pl = 0; pl < planes; pl += 2) { - fetch_bitplane_data(pl); + fetch_bitplane_data(state, pl); } } /* now assemble the bits */ - pfpix0 |= assemble_odd_bitplanes(planes, obitoffs); + pfpix0 |= assemble_odd_bitplanes(state, planes, obitoffs); obitoffs--; /* for high res, assemble a second set of bits */ @@ -961,11 +639,11 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s for (pl = 0; pl < planes; pl += 2) { - fetch_bitplane_data(pl); + fetch_bitplane_data(state, pl); } } - pfpix1 |= assemble_odd_bitplanes(planes, obitoffs); + pfpix1 |= assemble_odd_bitplanes(state, planes, obitoffs); obitoffs--; } else @@ -984,12 +662,12 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s { for (pl = 1; pl < planes; pl += 2) { - fetch_bitplane_data(pl); + fetch_bitplane_data(state, pl); } } /* now assemble the bits */ - pfpix0 |= assemble_even_bitplanes(planes, ebitoffs); + pfpix0 |= assemble_even_bitplanes(state, planes, ebitoffs); ebitoffs--; /* for high res, assemble a second set of bits */ @@ -1002,11 +680,11 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s for (pl = 1; pl < planes; pl += 2) { - fetch_bitplane_data(pl); + fetch_bitplane_data(state, pl); } } - pfpix1 |= assemble_even_bitplanes(planes, ebitoffs); + pfpix1 |= assemble_even_bitplanes(state, planes, ebitoffs); ebitoffs--; } else @@ -1038,39 +716,43 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s /* if we are within the display region, render */ if (dst != NULL && x >= hstart && x < hstop) { + int pix, pri; + /* hold-and-modify mode -- assume low-res (hi-res not supported by the hardware) */ if (ham) { /* update the HAM color */ - ham_pix = update_ham(pfpix0); + pfpix0 = update_ham(state, pfpix0); + + pix = sprpix & 0xff; + pri = (sprpix >> 10); /* sprite has priority */ - if (sprpix && pf1pri > (sprpix >> 10)) + if (sprpix && pf1pri > pri) { dst[x*2+0] = - dst[x*2+1] = aga_palette[sprpix & 0xff]; + dst[x*2+1] = aga_palette[pix]; } /* playfield has priority */ else { dst[x*2+0] = - dst[x*2+1] = ham_pix; + dst[x*2+1] = pfpix0; } } /* dual playfield mode */ else if (dualpf) { - int pix; - /* mask out the sprite if it doesn't have priority */ pix = sprpix & 0x1f; + pri = (sprpix >> 12); if (pix) { - if ((pfpix0 & 0x15) && pf1pri <= (sprpix >> 12)) + if ((pfpix0 & 0x15) && pf1pri <= pri) pix = 0; - if ((pfpix0 & 0x2a) && pf2pri <= (sprpix >> 12)) + if ((pfpix0 & 0x2a) && pf2pri <= pri) pix = 0; } @@ -1078,15 +760,15 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s if (pix) dst[x*2+0] = aga_palette[pix]; else - dst[x*2+0] = aga_palette[separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]]; + dst[x*2+0] = aga_palette[state->separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]]; /* mask out the sprite if it doesn't have priority */ pix = sprpix & 0xff; if (pix) { - if ((pfpix1 & 0x15) && pf1pri <= (sprpix >> 12)) + if ((pfpix1 & 0x15) && pf1pri <= pri) pix = 0; - if ((pfpix1 & 0x2a) && pf2pri <= (sprpix >> 12)) + if ((pfpix1 & 0x2a) && pf2pri <= pri) pix = 0; } @@ -1094,17 +776,20 @@ void amiga_aga_render_scanline(running_machine *machine, bitmap_t *bitmap, int s if (pix) dst[x*2+1] = aga_palette[pix]; else - dst[x*2+1] = aga_palette[separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]]; + dst[x*2+1] = aga_palette[state->separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]]; } /* single playfield mode */ else { + pix = sprpix & 0xff; + pri = (sprpix >> 12); + /* sprite has priority */ - if (sprpix && pf1pri > (sprpix >> 12)) + if (sprpix && pf1pri > pri) { dst[x*2+0] = - dst[x*2+1] = aga_palette[(sprpix & 0xff)]; + dst[x*2+1] = aga_palette[pix]; } /* playfield has priority */