summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/sound/ay8910.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/sound/ay8910.c')
-rw-r--r--src/emu/sound/ay8910.c238
1 files changed, 112 insertions, 126 deletions
diff --git a/src/emu/sound/ay8910.c b/src/emu/sound/ay8910.c
index e9a614487d6..c12ef2f3999 100644
--- a/src/emu/sound/ay8910.c
+++ b/src/emu/sound/ay8910.c
@@ -187,8 +187,29 @@ struct _ay8910_context
INT32 vol_table[NUM_CHANNELS][16];
INT32 env_table[NUM_CHANNELS][32];
INT32 vol3d_table[8*32*32*32];
+ devcb_resolved_read8 portAread;
+ devcb_resolved_read8 portBread;
+ devcb_resolved_write8 portAwrite;
+ devcb_resolved_write8 portBwrite;
};
+INLINE ay8910_context *get_safe_token(const device_config *device)
+{
+ assert(device != NULL);
+ assert(device->token != NULL);
+ assert(device->type == SOUND);
+ assert(sound_get_type(device) == SOUND_AY8910 ||
+ sound_get_type(device) == SOUND_AY8912 ||
+ sound_get_type(device) == SOUND_AY8913 ||
+ sound_get_type(device) == SOUND_AY8930 ||
+ sound_get_type(device) == SOUND_YM2149 ||
+ sound_get_type(device) == SOUND_YM3439 ||
+ sound_get_type(device) == SOUND_YMZ284 ||
+ sound_get_type(device) == SOUND_YMZ294);
+ return (ay8910_context *)device->token;
+}
+
+
/*************************************
*
* Static
@@ -386,9 +407,6 @@ INLINE UINT16 mix_3D(ay8910_context *psg)
static void ay8910_write_reg(ay8910_context *psg, int r, int v)
{
- /* temporary hack until this is converted to a device */
- const address_space *space = memory_find_address_space(psg->device->machine->cpu[0], ADDRESS_SPACE_PROGRAM);
-
//if (r >= 11 && r <= 13 ) printf("%d %x %02x\n", PSG->index, r, v);
psg->regs[r] = v;
@@ -413,16 +431,14 @@ static void ay8910_write_reg(ay8910_context *psg, int r, int v)
((psg->last_enable & 0x40) != (psg->regs[AY_ENABLE] & 0x40)))
{
/* write out 0xff if port set to input */
- if (psg->intf->portAwrite)
- (*psg->intf->portAwrite)(space, 0, (psg->regs[AY_ENABLE] & 0x40) ? psg->regs[AY_PORTA] : 0xff);
+ devcb_call_write8(&psg->portAwrite, 0, (psg->regs[AY_ENABLE] & 0x40) ? psg->regs[AY_PORTA] : 0xff);
}
if ((psg->last_enable == -1) ||
((psg->last_enable & 0x80) != (psg->regs[AY_ENABLE] & 0x80)))
{
/* write out 0xff if port set to input */
- if (psg->intf->portBwrite)
- (*psg->intf->portBwrite)(space, 0, (psg->regs[AY_ENABLE] & 0x80) ? psg->regs[AY_PORTB] : 0xff);
+ devcb_call_write8(&psg->portBwrite, 0, (psg->regs[AY_ENABLE] & 0x80) ? psg->regs[AY_PORTB] : 0xff);
}
psg->last_enable = psg->regs[AY_ENABLE];
@@ -447,8 +463,8 @@ static void ay8910_write_reg(ay8910_context *psg, int r, int v)
case AY_PORTA:
if (psg->regs[AY_ENABLE] & 0x40)
{
- if (psg->intf->portAwrite)
- (*psg->intf->portAwrite)(space, 0, psg->regs[AY_PORTA]);
+ if (psg->portAwrite.write)
+ devcb_call_write8(&psg->portAwrite, 0, psg->regs[AY_PORTA]);
else
logerror("warning - write %02x to 8910 '%s' Port A\n",psg->regs[AY_PORTA],psg->device->tag);
}
@@ -460,8 +476,8 @@ static void ay8910_write_reg(ay8910_context *psg, int r, int v)
case AY_PORTB:
if (psg->regs[AY_ENABLE] & 0x80)
{
- if (psg->intf->portBwrite)
- (*psg->intf->portBwrite)(space, 0, psg->regs[AY_PORTB]);
+ if (psg->portBwrite.write)
+ devcb_call_write8(&psg->portBwrite, 0, psg->regs[AY_PORTB]);
else
logerror("warning - write %02x to 8910 '%s' Port B\n",psg->regs[AY_PORTB],psg->device->tag);
}
@@ -670,6 +686,10 @@ void *ay8910_start_ym(void *infoptr, sound_type chip_type, const device_config *
}
info->device = device;
info->intf = intf;
+ devcb_resolve_read8(&info->portAread, &intf->portAread, device);
+ devcb_resolve_read8(&info->portBread, &intf->portBread, device);
+ devcb_resolve_write8(&info->portAwrite, &intf->portAwrite, device);
+ devcb_resolve_write8(&info->portBwrite, &intf->portBwrite, device);
if ((info->intf->flags & AY8910_SINGLE_OUTPUT) != 0)
{
logerror("AY-3-8910/YM2149 using single output!\n");
@@ -699,9 +719,9 @@ void *ay8910_start_ym(void *infoptr, sound_type chip_type, const device_config *
/* The envelope is pacing twice as fast for the YM2149 as for the AY-3-8910, */
/* This handled by the step parameter. Consequently we use a divider of 8 here. */
- info->channel = stream_create(device, 0, info->streams, clock / 8, info, ay8910_update);
+ info->channel = stream_create(device, 0, info->streams, device->clock / 8, info, ay8910_update);
- ay8910_set_clock_ym(info,clock);
+ ay8910_set_clock_ym(info,device->clock);
ay8910_statesave(info, device);
return info;
@@ -733,9 +753,9 @@ void ay8910_reset_ym(void *chip)
psg->ready = 1;
}
-void ay8910_set_volume(int chip,int channel,int volume)
+void ay8910_set_volume(const device_config *device,int channel,int volume)
{
- ay8910_context *psg = sndti_token(SOUND_AY8910, chip);
+ ay8910_context *psg = get_safe_token(device);
int ch;
for (ch = 0; ch < psg->streams; ch++)
@@ -775,8 +795,6 @@ void ay8910_write_ym(void *chip, int addr, int data)
int ay8910_read_ym(void *chip)
{
ay8910_context *psg = chip;
- /* temporary hack until this is converted to a device */
- const address_space *space = memory_find_address_space(psg->device->machine->cpu[0], ADDRESS_SPACE_PROGRAM);
int r = psg->register_latch;
if (r > 15) return 0;
@@ -790,16 +808,16 @@ int ay8910_read_ym(void *chip)
even if the port is set as output, we still need to return the external
data. Some games, like kidniki, need this to work.
*/
- if (psg->intf->portAread)
- psg->regs[AY_PORTA] = (*psg->intf->portAread)(space, 0);
+ if (psg->portAread.read)
+ psg->regs[AY_PORTA] = devcb_call_read8(&psg->portAread, 0);
else
logerror("%s: warning - read 8910 '%s' Port A\n",cpuexec_describe_context(psg->device->machine),psg->device->tag);
break;
case AY_PORTB:
if ((psg->regs[AY_ENABLE] & 0x80) != 0)
logerror("warning: read from 8910 '%s' Port B set as output\n",psg->device->tag);
- if (psg->intf->portBread)
- psg->regs[AY_PORTB] = (*psg->intf->portBread)(space, 0);
+ if (psg->portBread.read)
+ psg->regs[AY_PORTB] = devcb_call_read8(&psg->portBread, 0);
else
logerror("%s: warning - read 8910 '%s' Port B\n",cpuexec_describe_context(psg->device->machine),psg->device->tag);
break;
@@ -813,138 +831,128 @@ int ay8910_read_ym(void *chip)
*
*************************************/
-static SND_START( ay8910 )
+static DEVICE_START( ay8910 )
{
static const ay8910_interface generic_ay8910 =
{
AY8910_LEGACY_OUTPUT,
AY8910_DEFAULT_LOADS,
- NULL, NULL, NULL, NULL
+ DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL
};
const ay8910_interface *intf = (device->static_config ? device->static_config : &generic_ay8910);
- ay8910_start_ym(device->token, SOUND_AY8910, device, clock, intf);
+ ay8910_start_ym(get_safe_token(device), SOUND_AY8910, device, device->clock, intf);
}
-static SND_START( ym2149 )
+static DEVICE_START( ym2149 )
{
static const ay8910_interface generic_ay8910 =
{
AY8910_LEGACY_OUTPUT,
AY8910_DEFAULT_LOADS,
- NULL, NULL, NULL, NULL
+ DEVCB_NULL, DEVCB_NULL, DEVCB_NULL, DEVCB_NULL
};
const ay8910_interface *intf = (device->static_config ? device->static_config : &generic_ay8910);
- ay8910_start_ym(device->token, SOUND_YM2149, device, clock, intf);
-}
-
-static SND_STOP( ay8910 )
-{
- ay8910_stop_ym(device->token);
+ ay8910_start_ym(get_safe_token(device), SOUND_YM2149, device, device->clock, intf);
}
-static SND_RESET( ay8910 )
+static DEVICE_STOP( ay8910 )
{
- ay8910_reset_ym(device->token);
+ ay8910_stop_ym(get_safe_token(device));
}
-static SND_SET_INFO( ay8910 )
+static DEVICE_RESET( ay8910 )
{
- switch (state)
- {
- /* no parameters to set */
- }
+ ay8910_reset_ym(get_safe_token(device));
}
-SND_GET_INFO( ay8910 )
+DEVICE_GET_INFO( ay8910 )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
- case SNDINFO_INT_TOKEN_BYTES: info->i = sizeof(ay8910_context); break;
- case SNDINFO_FCT_ALIAS: info->type = SOUND_AY8910; break;
+ case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ay8910_context); break;
/* --- the following bits of info are returned as pointers to data or functions --- */
- case SNDINFO_PTR_SET_INFO: info->set_info = SND_SET_INFO_NAME( ay8910 ); break;
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ay8910 ); break;
- case SNDINFO_PTR_STOP: info->stop = SND_STOP_NAME( ay8910 ); break;
- case SNDINFO_PTR_RESET: info->reset = SND_RESET_NAME( ay8910 ); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ay8910 ); break;
+ case DEVINFO_FCT_STOP: info->stop = DEVICE_STOP_NAME( ay8910 ); break;
+ case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME( ay8910 ); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
- case SNDINFO_STR_NAME: strcpy(info->s, "AY-3-8910A"); break;
- case SNDINFO_STR_CORE_FAMILY: strcpy(info->s, "PSG"); break;
- case SNDINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
- case SNDINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
- case SNDINFO_STR_CORE_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "AY-3-8910A"); break;
+ case DEVINFO_STR_FAMILY: strcpy(info->s, "PSG"); break;
+ case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break;
+ case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break;
+ case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright Nicola Salmoria and the MAME Team"); break;
}
}
-SND_GET_INFO( ay8912 )
+DEVICE_GET_INFO( ay8912 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ay8910 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "AY-3-8912A"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ay8910 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "AY-3-8912A"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
-SND_GET_INFO( ay8913 )
+DEVICE_GET_INFO( ay8913 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ay8910 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "AY-3-8913A"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ay8910 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "AY-3-8913A"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
-SND_GET_INFO( ay8930 )
+DEVICE_GET_INFO( ay8930 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ay8910 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "AY8930"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ay8910 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "AY8930"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
-SND_GET_INFO( ym2149 )
+DEVICE_GET_INFO( ym2149 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ym2149 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "YM2149"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ym2149 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "YM2149"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
-SND_GET_INFO( ym3439 )
+DEVICE_GET_INFO( ym3439 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ym2149 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "YM3439"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ym2149 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "YM3439"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
-SND_GET_INFO( ymz284 )
+DEVICE_GET_INFO( ymz284 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ym2149 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "YMZ284"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ym2149 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "YMZ284"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
-SND_GET_INFO( ymz294 )
+DEVICE_GET_INFO( ymz294 )
{
switch (state)
{
- case SNDINFO_PTR_START: info->start = SND_START_NAME( ym2149 ); break;
- case SNDINFO_STR_NAME: strcpy(info->s, "YMZ294"); break;
- default: SND_GET_INFO_CALL(ay8910); break;
+ case DEVINFO_FCT_START: info->start = DEVICE_START_NAME( ym2149 ); break;
+ case DEVINFO_STR_NAME: strcpy(info->s, "YMZ294"); break;
+ default: DEVICE_GET_INFO_CALL(ay8910); break;
}
}
@@ -954,50 +962,28 @@ SND_GET_INFO( ymz294 )
*
*************************************/
-READ8_HANDLER( ay8910_read_port_0_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 0)); }
-READ8_HANDLER( ay8910_read_port_1_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 1)); }
-READ8_HANDLER( ay8910_read_port_2_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 2)); }
-READ8_HANDLER( ay8910_read_port_3_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 3)); }
-READ8_HANDLER( ay8910_read_port_4_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 4)); }
-READ16_HANDLER( ay8910_read_port_0_lsb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 0)); }
-READ16_HANDLER( ay8910_read_port_1_lsb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 1)); }
-READ16_HANDLER( ay8910_read_port_2_lsb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 2)); }
-READ16_HANDLER( ay8910_read_port_3_lsb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 3)); }
-READ16_HANDLER( ay8910_read_port_4_lsb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 4)); }
-READ16_HANDLER( ay8910_read_port_0_msb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 0)) << 8; }
-READ16_HANDLER( ay8910_read_port_1_msb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 1)) << 8; }
-READ16_HANDLER( ay8910_read_port_2_msb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 2)) << 8; }
-READ16_HANDLER( ay8910_read_port_3_msb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 3)) << 8; }
-READ16_HANDLER( ay8910_read_port_4_msb_r ) { return ay8910_read_ym(sndti_token(SOUND_AY8910, 4)) << 8; }
-
-WRITE8_HANDLER( ay8910_control_port_0_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data); }
-WRITE8_HANDLER( ay8910_control_port_1_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data); }
-WRITE8_HANDLER( ay8910_control_port_2_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data); }
-WRITE8_HANDLER( ay8910_control_port_3_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data); }
-WRITE8_HANDLER( ay8910_control_port_4_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data); }
-WRITE16_HANDLER( ay8910_control_port_0_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data & 0xff); }
-WRITE16_HANDLER( ay8910_control_port_1_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data & 0xff); }
-WRITE16_HANDLER( ay8910_control_port_2_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data & 0xff); }
-WRITE16_HANDLER( ay8910_control_port_3_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data & 0xff); }
-WRITE16_HANDLER( ay8910_control_port_4_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data & 0xff); }
-WRITE16_HANDLER( ay8910_control_port_0_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),0,data >> 8); }
-WRITE16_HANDLER( ay8910_control_port_1_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 1),0,data >> 8); }
-WRITE16_HANDLER( ay8910_control_port_2_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),0,data >> 8); }
-WRITE16_HANDLER( ay8910_control_port_3_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),0,data >> 8); }
-WRITE16_HANDLER( ay8910_control_port_4_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),0,data >> 8); }
-
-WRITE8_HANDLER( ay8910_write_port_0_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 0),1,data); }
-WRITE8_HANDLER( ay8910_write_port_1_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 1),1,data); }
-WRITE8_HANDLER( ay8910_write_port_2_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 2),1,data); }
-WRITE8_HANDLER( ay8910_write_port_3_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 3),1,data); }
-WRITE8_HANDLER( ay8910_write_port_4_w ) { ay8910_write_ym(sndti_token(SOUND_AY8910, 4),1,data); }
-WRITE16_HANDLER( ay8910_write_port_0_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),1,data & 0xff); }
-WRITE16_HANDLER( ay8910_write_port_1_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 1),1,data & 0xff); }
-WRITE16_HANDLER( ay8910_write_port_2_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),1,data & 0xff); }
-WRITE16_HANDLER( ay8910_write_port_3_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),1,data & 0xff); }
-WRITE16_HANDLER( ay8910_write_port_4_lsb_w ) { if (ACCESSING_BITS_0_7) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),1,data & 0xff); }
-WRITE16_HANDLER( ay8910_write_port_0_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 0),1,data >> 8); }
-WRITE16_HANDLER( ay8910_write_port_1_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 1),1,data >> 8); }
-WRITE16_HANDLER( ay8910_write_port_2_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 2),1,data >> 8); }
-WRITE16_HANDLER( ay8910_write_port_3_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 3),1,data >> 8); }
-WRITE16_HANDLER( ay8910_write_port_4_msb_w ) { if (ACCESSING_BITS_8_15) ay8910_write_ym(sndti_token(SOUND_AY8910, 4),1,data >> 8); }
+READ8_DEVICE_HANDLER( ay8910_r )
+{
+ return ay8910_read_ym(get_safe_token(device));
+}
+
+WRITE8_DEVICE_HANDLER( ay8910_data_address_w )
+{
+ /* note that directly connecting BC1 to A0 puts data on 0 and address on 1 */
+ ay8910_write_ym(get_safe_token(device), ~offset & 1, data);
+}
+
+WRITE8_DEVICE_HANDLER( ay8910_address_data_w )
+{
+ ay8910_write_ym(get_safe_token(device), offset & 1, data);
+}
+
+WRITE8_DEVICE_HANDLER( ay8910_address_w )
+{
+ ay8910_data_address_w(device, 1, data);
+}
+
+WRITE8_DEVICE_HANDLER( ay8910_data_w )
+{
+ ay8910_data_address_w(device, 0, data);
+}