mirror of
https://github.com/holub/mame
synced 2025-05-22 21:58:57 +03:00
Converted amiga drivers to use driver_devices. Merged common code between
legacy Amiga and AGA video systems. [Atari Ace] From: Atari Ace <atari_ace@frontier.com> 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
This commit is contained in:
parent
5c0e08dce2
commit
2dd1a7191f
@ -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<legacy_device_base *>(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_state>();
|
||||
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<legacy_device_base *>(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;
|
||||
|
@ -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<alg_state>();
|
||||
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<alg_state>();
|
||||
|
||||
/* 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<alg_state>();
|
||||
|
||||
/* 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<alg_state>();
|
||||
|
||||
/* 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<alg_state>();
|
||||
|
||||
/* 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<alg_state>();
|
||||
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<alg_state>();
|
||||
|
||||
/* 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<alg_state>();
|
||||
|
||||
/* 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)
|
||||
@ -658,6 +680,7 @@ ROM_END
|
||||
|
||||
static void alg_init(running_machine *machine)
|
||||
{
|
||||
alg_state *state = machine->driver_data<alg_state>();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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<arcadia_state>()->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<arcadia_state>()->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<arcadia_state>()->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<arcadia_state>()->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<arcadia_state>();
|
||||
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 */
|
||||
|
@ -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,19 +433,16 @@ 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<cubocd32_state>();
|
||||
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)
|
||||
{
|
||||
@ -453,22 +450,22 @@ static void cubocd32_potgo_w(running_machine *machine, UINT16 data)
|
||||
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++)
|
||||
{
|
||||
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;
|
||||
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];
|
||||
cubocd32_state *state = machine->driver_data<cubocd32_state>();
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
@ -477,24 +474,25 @@ static void handle_cd32_joystick_cia(UINT8 pra, UINT8 dra)
|
||||
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)
|
||||
{
|
||||
cubocd32_state *state = machine->driver_data<cubocd32_state>();
|
||||
static const char *const player_portname[] = { "P2", "P1" };
|
||||
int i;
|
||||
|
||||
@ -507,16 +505,16 @@ static UINT16 handle_joystick_potgor (running_machine *machine, UINT16 potgor)
|
||||
|
||||
/* p5 is floating in input-mode */
|
||||
potgor &= ~p5dat;
|
||||
potgor |= potgo_value & p5dat;
|
||||
if (!(potgo_value & p9dir))
|
||||
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;
|
||||
if ((state->potgo_value & p5dir) && (state->potgo_value & p5dat))
|
||||
state->cd32_shifter[i] = 8;
|
||||
/* shift at 1 == return one, >1 = return button states */
|
||||
if (cd32_shifter[i] == 0)
|
||||
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;
|
||||
@ -524,7 +522,8 @@ static UINT16 handle_joystick_potgor (running_machine *machine, UINT16 potgor)
|
||||
|
||||
static CUSTOM_INPUT(cubo_input)
|
||||
{
|
||||
return handle_joystick_potgor(field->port->machine, potgo_value) >> 10;
|
||||
cubocd32_state *state = field->port->machine->driver_data<cubocd32_state>();
|
||||
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)
|
||||
|
||||
@ -1157,6 +1157,7 @@ ROM_END
|
||||
|
||||
static DRIVER_INIT( cd32 )
|
||||
{
|
||||
cubocd32_state *state = machine->driver_data<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
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<cubocd32_state>();
|
||||
|
||||
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<cubocd32_state>();
|
||||
DRIVER_INIT_CALL(cd32);
|
||||
cubocd32_input_hack = mgprem11_input_hack;
|
||||
state->input_hack = mgprem11_input_hack;
|
||||
}
|
||||
|
||||
/***************************************************************************************************/
|
||||
|
@ -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)
|
||||
@ -447,6 +447,7 @@ ROM_END
|
||||
|
||||
static DRIVER_INIT(mquake)
|
||||
{
|
||||
amiga_state *state = machine->driver_data<amiga_state>();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
@ -391,6 +391,7 @@ ROM_END
|
||||
|
||||
static DRIVER_INIT( upscope )
|
||||
{
|
||||
upscope_state *state = machine->driver_data<upscope_state>();
|
||||
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<upscope_state>();
|
||||
machine->device<nvram_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);
|
||||
}
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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__ */
|
||||
|
@ -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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
|
||||
/* 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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<cpu_device *>(space->cpu)->cycles_to_attotime( blittime ), 0);
|
||||
timer_adjust_oneshot( state->blitter_timer, downcast<cpu_device *>(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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
UINT16 temp;
|
||||
|
||||
switch (offset & 0xff)
|
||||
@ -1182,16 +1160,10 @@ 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;
|
||||
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;
|
||||
|
||||
case REG_SERDATR:
|
||||
@ -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<amiga_state>();
|
||||
|
||||
/* 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<amiga_state>();
|
||||
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<cpu_device *>(space->cpu)->cycles_to_attotime( BLITTER_NASTY_DELAY ), 0);
|
||||
timer_adjust_oneshot( state->blitter_timer, downcast<cpu_device *>(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<cpu_device *>(space->cpu)->cycles_to_attotime( AMIGA_IRQ_DELAY_CYCLES ), 0);
|
||||
timer_adjust_oneshot( state->irq_timer, downcast<cpu_device *>(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<cpu_device>("maincpu")->cycles_to_attotime( AMIGA_IRQ_DELAY_CYCLES ), 0);
|
||||
timer_adjust_oneshot( state->irq_timer, space->machine->device<cpu_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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>()->intf;
|
||||
}
|
||||
|
@ -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<legacy_device_base *>(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<amiga_state>();
|
||||
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);
|
||||
|
@ -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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
|
||||
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<amiga_state>();
|
||||
|
||||
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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
|
||||
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<amiga_state>();
|
||||
|
||||
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<amiga_state>();
|
||||
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
|
||||
}
|
||||
|
@ -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<amiga_state>();
|
||||
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<amiga_state>();
|
||||
|
||||
/* 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<amiga_state>();
|
||||
|
||||
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<amiga_state>();
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user