Made the 6850 ACIA a device

This commit is contained in:
Nathan Woods 2008-12-03 12:54:32 +00:00
parent d924407859
commit e1c8b38b66
5 changed files with 358 additions and 292 deletions

View File

@ -1,17 +1,30 @@
/*
6850 ACIA
*/
/*********************************************************************
6850acia.c
6850 ACIA code
*********************************************************************/
#include "driver.h"
#include "deprecat.h"
#include "timer.h"
#include "6850acia.h"
/***************************************************************************
MACROS
***************************************************************************/
#define CR1_0 0x03
#define CR4_2 0x1C
#define CR6_5 0x60
#define CR7 0x80
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
enum serial_state
{
START,
@ -28,21 +41,8 @@ enum parity_type
EVEN
};
static const int ACIA6850_DIVIDE[3] = { 1, 16, 64 };
static const int ACIA6850_WORD[8][3] =
{
{ 7, EVEN, 2 },
{ 7, ODD, 2 },
{ 7, EVEN, 1 },
{ 7, ODD, 1 },
{ 8, NONE, 2 },
{ 8, NONE, 1 },
{ 8, EVEN, 1 },
{ 8, ODD, 1 }
};
typedef struct _acia_6850_
typedef struct _acia6850_t acia6850_t;
struct _acia6850_t
{
UINT8 ctrl;
UINT8 status;
@ -91,20 +91,68 @@ typedef struct _acia_6850_
emu_timer *rx_timer;
emu_timer *tx_timer;
void (*int_callback)(int param);
} acia_6850;
void (*int_callback)(const device_config *device, int param);
};
static acia_6850 acia[MAX_ACIA];
/***************************************************************************
LOCAL VARIABLES
***************************************************************************/
static const int ACIA6850_DIVIDE[3] = { 1, 16, 64 };
static const int ACIA6850_WORD[8][3] =
{
{ 7, EVEN, 2 },
{ 7, ODD, 2 },
{ 7, EVEN, 1 },
{ 7, ODD, 1 },
{ 8, NONE, 2 },
{ 8, NONE, 1 },
{ 8, EVEN, 1 },
{ 8, ODD, 1 }
};
/***************************************************************************
PROTOTYPES
***************************************************************************/
static TIMER_CALLBACK( receive_event );
static TIMER_CALLBACK( transmit_event );
/*
Reset the chip
*/
static void acia6850_reset(int which)
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
INLINE acia6850_t *get_token(const device_config *device)
{
acia_6850 *acia_p = &acia[which];
assert(device != NULL);
assert(device->type == ACIA6850);
return (acia6850_t *) device->token;
}
INLINE acia6850_interface *get_interface(const device_config *device)
{
assert(device != NULL);
assert(device->type == ACIA6850);
return (acia6850_interface *) device->static_config;
}
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
/*-------------------------------------------------
DEVICE_RESET( acia6850 )
-------------------------------------------------*/
static DEVICE_RESET( acia6850 )
{
acia6850_t *acia_p = get_token(device);
int cts = 0, dcd = 0;
if (acia_p->cts_pin)
@ -135,7 +183,7 @@ static void acia6850_reset(int which)
if (acia_p->int_callback)
{
acia_p->int_callback(1);
acia_p->int_callback(device, 1);
}
if (acia_p->first_reset)
@ -156,17 +204,16 @@ static void acia6850_reset(int which)
}
}
/*
Called by drivers
*/
void acia6850_config(int which, const struct acia6850_interface *intf)
{
acia_6850 *acia_p = &acia[which];
if (which >= MAX_ACIA)
{
return;
}
/*-------------------------------------------------
DEVICE_START( acia6850 )
-------------------------------------------------*/
static DEVICE_START( acia6850 )
{
acia6850_t *acia_p = get_token(device);
acia6850_interface *intf = get_interface(device);
acia_p->rx_clock = intf->rx_clock;
acia_p->tx_clock = intf->tx_clock;
@ -177,8 +224,8 @@ void acia6850_config(int which, const struct acia6850_interface *intf)
acia_p->cts_pin = intf->cts_pin;
acia_p->rts_pin = intf->rts_pin;
acia_p->dcd_pin = intf->dcd_pin;
acia_p->rx_timer = timer_alloc(Machine, receive_event, NULL);
acia_p->tx_timer = timer_alloc(Machine, transmit_event, NULL);
acia_p->rx_timer = timer_alloc(device->machine, receive_event, (void *) device);
acia_p->tx_timer = timer_alloc(device->machine, transmit_event, (void *) device);
acia_p->int_callback = intf->int_callback;
acia_p->first_reset = 1;
acia_p->status_read = 0;
@ -187,38 +234,40 @@ void acia6850_config(int which, const struct acia6850_interface *intf)
timer_reset(acia_p->rx_timer, attotime_never);
timer_reset(acia_p->tx_timer, attotime_never);
state_save_register_item("acia6850", NULL, which, acia_p->ctrl);
state_save_register_item("acia6850", NULL, which, acia_p->status);
state_save_register_item("acia6850", NULL, which, acia_p->rx_clock);
state_save_register_item("acia6850", NULL, which, acia_p->tx_clock);
state_save_register_item("acia6850", NULL, which, acia_p->rx_counter);
state_save_register_item("acia6850", NULL, which, acia_p->tx_counter);
state_save_register_item("acia6850", NULL, which, acia_p->rx_shift);
state_save_register_item("acia6850", NULL, which, acia_p->tx_shift);
state_save_register_item("acia6850", NULL, which, acia_p->rdr);
state_save_register_item("acia6850", NULL, which, acia_p->tdr);
state_save_register_item("acia6850", NULL, which, acia_p->rx_bits);
state_save_register_item("acia6850", NULL, which, acia_p->tx_bits);
state_save_register_item("acia6850", NULL, which, acia_p->rx_parity);
state_save_register_item("acia6850", NULL, which, acia_p->tx_parity);
state_save_register_item("acia6850", NULL, which, acia_p->tx_int);
state_save_register_item("acia6850", device->tag, 0, acia_p->ctrl);
state_save_register_item("acia6850", device->tag, 0, acia_p->status);
state_save_register_item("acia6850", device->tag, 0, acia_p->rx_clock);
state_save_register_item("acia6850", device->tag, 0, acia_p->tx_clock);
state_save_register_item("acia6850", device->tag, 0, acia_p->rx_counter);
state_save_register_item("acia6850", device->tag, 0, acia_p->tx_counter);
state_save_register_item("acia6850", device->tag, 0, acia_p->rx_shift);
state_save_register_item("acia6850", device->tag, 0, acia_p->tx_shift);
state_save_register_item("acia6850", device->tag, 0, acia_p->rdr);
state_save_register_item("acia6850", device->tag, 0, acia_p->tdr);
state_save_register_item("acia6850", device->tag, 0, acia_p->rx_bits);
state_save_register_item("acia6850", device->tag, 0, acia_p->tx_bits);
state_save_register_item("acia6850", device->tag, 0, acia_p->rx_parity);
state_save_register_item("acia6850", device->tag, 0, acia_p->tx_parity);
state_save_register_item("acia6850", device->tag, 0, acia_p->tx_int);
state_save_register_item("acia6850", NULL, which, acia_p->divide);
state_save_register_item("acia6850", NULL, which, acia_p->overrun);
state_save_register_item("acia6850", NULL, which, acia_p->reset);
state_save_register_item("acia6850", NULL, which, acia_p->first_reset);
state_save_register_item("acia6850", NULL, which, acia_p->rts);
state_save_register_item("acia6850", NULL, which, acia_p->brk);
state_save_register_item("acia6850", NULL, which, acia_p->status_read);
state_save_register_item("acia6850", device->tag, 0, acia_p->divide);
state_save_register_item("acia6850", device->tag, 0, acia_p->overrun);
state_save_register_item("acia6850", device->tag, 0, acia_p->reset);
state_save_register_item("acia6850", device->tag, 0, acia_p->first_reset);
state_save_register_item("acia6850", device->tag, 0, acia_p->rts);
state_save_register_item("acia6850", device->tag, 0, acia_p->brk);
state_save_register_item("acia6850", device->tag, 0, acia_p->status_read);
return DEVICE_START_OK;
}
/*
Read Status Register
*/
static UINT8 acia6850_stat_r(int which)
/*-------------------------------------------------
acia6850_stat_r - Read Status Register
-------------------------------------------------*/
READ8_DEVICE_HANDLER( acia6850_stat_r )
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
acia_p->status_read = 1;
@ -226,12 +275,13 @@ static UINT8 acia6850_stat_r(int which)
}
/*
Write Control Register
*/
static void acia6850_ctrl_w(int which, UINT8 data)
/*-------------------------------------------------
acia6850_ctrl_w - Write Control Register
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( acia6850_ctrl_w )
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
int wordsel;
int divide;
@ -245,7 +295,7 @@ static void acia6850_ctrl_w(int which, UINT8 data)
if (divide == 3)
{
acia_p->reset = 1;
acia6850_reset(which);
device_reset(device);
}
else
{
@ -313,20 +363,24 @@ static void acia6850_ctrl_w(int which, UINT8 data)
if (acia_p->rx_clock)
{
attotime rx_period = attotime_mul(ATTOTIME_IN_HZ(acia_p->rx_clock), acia_p->divide);
timer_adjust_periodic(acia_p->rx_timer, rx_period, which, rx_period);
timer_adjust_periodic(acia_p->rx_timer, rx_period, 0, rx_period);
}
if (acia_p->tx_clock)
{
attotime tx_period = attotime_mul(ATTOTIME_IN_HZ(acia_p->tx_clock), acia_p->divide);
timer_adjust_periodic(acia_p->tx_timer, tx_period, which, tx_period);
timer_adjust_periodic(acia_p->tx_timer, tx_period, 0, tx_period);
}
}
}
static void acia6850_check_interrupts(int which)
/*-------------------------------------------------
acia6850_check_interrupts
-------------------------------------------------*/
static void acia6850_check_interrupts(const device_config *device)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
int irq = (acia_p->tx_int && (acia_p->status & ACIA6850_STATUS_TDRE)) ||
((acia_p->ctrl & 0x80) && ((acia_p->status & (ACIA6850_STATUS_RDRF|ACIA6850_STATUS_DCD)) || acia_p->overrun));
@ -337,7 +391,7 @@ static void acia6850_check_interrupts(int which)
if (acia_p->int_callback)
{
acia_p->int_callback(0);
acia_p->int_callback(device, 0);
}
}
else
@ -346,38 +400,40 @@ static void acia6850_check_interrupts(int which)
if (acia_p->int_callback)
{
acia_p->int_callback(1);
acia_p->int_callback(device, 1);
}
}
}
/*
Write transmit register
*/
static void acia6850_data_w(running_machine *machine, int which, UINT8 data)
/*-------------------------------------------------
acia6850_data_w - Write transmit register
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( acia6850_data_w )
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
if (!acia_p->reset)
{
acia_p->tdr = data;
acia_p->status &= ~ACIA6850_STATUS_TDRE;
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
}
else
{
logerror("ACIA %d: Data write while in reset! (%x)\n", which, cpu_get_previouspc(machine->activecpu));
logerror("ACIA %p: Data write while in reset! (%x)\n", device, cpu_get_previouspc(device->machine->activecpu));
}
}
/*
Read character
*/
static UINT8 acia6850_data_r(int which)
/*-------------------------------------------------
acia6850_data_r - Read character
-------------------------------------------------*/
READ8_DEVICE_HANDLER( acia6850_data_r )
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
acia_p->status &= ~(ACIA6850_STATUS_RDRF | ACIA6850_STATUS_IRQ | ACIA6850_STATUS_PE);
@ -398,18 +454,19 @@ static UINT8 acia6850_data_r(int which)
acia_p->overrun = 0;
}
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
return acia_p->rdr;
}
/*
Transmit a bit
*/
static void tx_tick(int which)
/*-------------------------------------------------
tx_tick - Transmit a bit
-------------------------------------------------*/
static void tx_tick(const device_config *device)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
if (acia_p->cts_pin && *acia_p->cts_pin)
{
@ -457,7 +514,7 @@ static void tx_tick(int which)
acia_p->status |= ACIA6850_STATUS_TDRE;
}
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
acia_p->tx_state = DATA;
}
@ -522,20 +579,26 @@ static void tx_tick(int which)
}
/* Called on transmit timer event */
/*-------------------------------------------------
TIMER_CALLBACK( transmit_event )
-------------------------------------------------*/
static TIMER_CALLBACK( transmit_event )
{
int which = param;
acia_6850 *acia_p = &acia[which];
tx_tick(which);
const device_config *device = ptr;
acia6850_t *acia_p = get_token(device);
tx_tick(device);
acia_p->tx_counter = 0;
}
/* As above, but using the tx pin */
void acia_tx_clock_in(int which)
/*-------------------------------------------------
acia_tx_clock_in - As above, but using the tx pin
-------------------------------------------------*/
void acia_tx_clock_in(const device_config *device)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
if (acia_p->cts_pin && *acia_p->cts_pin)
{
@ -550,24 +613,25 @@ void acia_tx_clock_in(int which)
if ( acia_p->tx_counter > acia_p->divide-1)
{
tx_tick(which);
tx_tick(device);
acia_p->tx_counter = 0;
}
}
/*
Receive a bit
*/
static void rx_tick(int which)
/*-------------------------------------------------
rx_tick - Receive a bit
-------------------------------------------------*/
static void rx_tick(const device_config *device)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
if (acia_p->dcd_pin && *acia_p->dcd_pin)
{
acia_p->status |= ACIA6850_STATUS_DCD;
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
}
else if ((acia_p->status & (ACIA6850_STATUS_DCD|ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD)
{
@ -605,7 +669,7 @@ static void rx_tick(int which)
if (acia_p->status & ACIA6850_STATUS_RDRF)
{
acia_p->overrun = 1;
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
}
acia_p->rx_state = acia_p->parity == NONE ? STOP : PARITY;
@ -653,7 +717,7 @@ static void rx_tick(int which)
//logerror("ACIA6850 #%u: RX DATA %x\n", which, acia_p->rx_shift);
acia_p->rdr = acia_p->rx_shift;
acia_p->status |= ACIA6850_STATUS_RDRF;
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
}
acia_p->rx_state = START;
@ -682,7 +746,7 @@ static void rx_tick(int which)
//logerror("ACIA6850 #%u: RX DATA %x\n", which, acia_p->rx_shift);
acia_p->rdr = acia_p->rx_shift;
acia_p->status |= ACIA6850_STATUS_RDRF;
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
}
acia_p->rx_state = START;
@ -698,25 +762,33 @@ static void rx_tick(int which)
}
}
/* Called on receive timer event */
/*-------------------------------------------------
TIMER_CALLBACK( receive_event ) - Called on
receive timer event
-------------------------------------------------*/
static TIMER_CALLBACK( receive_event )
{
int which = param;
acia_6850 *acia_p = &acia[which];
rx_tick(which);
const device_config *device = ptr;
acia6850_t *acia_p = get_token(device);
rx_tick(device);
acia_p->rx_counter = 0;
}
/* As above, but using the rx pin */
void acia_rx_clock_in(int which)
/*-------------------------------------------------
acia_rx_clock_in - As above, but using the rx pin
-------------------------------------------------*/
void acia_rx_clock_in(const device_config *device)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
if (acia_p->dcd_pin && *acia_p->dcd_pin)
{
acia_p->status |= ACIA6850_STATUS_DCD;
acia6850_check_interrupts(which);
acia6850_check_interrupts(device);
}
else if ((acia_p->status & (ACIA6850_STATUS_DCD|ACIA6850_STATUS_IRQ)) == ACIA6850_STATUS_DCD)
{
@ -727,83 +799,88 @@ void acia_rx_clock_in(int which)
if ( acia_p->rx_counter > acia_p->divide-1)
{
rx_tick(which);
rx_tick(device);
acia_p->rx_counter = 0;
}
}
/* Set clock frequencies dynamically */
void acia6850_set_rx_clock(int which, int clock)
/*-------------------------------------------------
acia6850_set_rx_clock - Set clock frequencies
dynamically
-------------------------------------------------*/
void acia6850_set_rx_clock(const device_config *device, int clock)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
acia_p->rx_clock = clock;
}
void acia6850_set_tx_clock(int which, int clock)
/*-------------------------------------------------
acia6850_set_tx_clock - Set clock frequencies
dynamically
-------------------------------------------------*/
void acia6850_set_tx_clock(const device_config *device, int clock)
{
acia_6850 *acia_p = &acia[which];
acia6850_t *acia_p = get_token(device);
acia_p->tx_clock = clock;
}
WRITE8_HANDLER( acia6850_0_ctrl_w ) { acia6850_ctrl_w(0, data); }
WRITE8_HANDLER( acia6850_1_ctrl_w ) { acia6850_ctrl_w(1, data); }
WRITE8_HANDLER( acia6850_2_ctrl_w ) { acia6850_ctrl_w(2, data); }
WRITE8_HANDLER( acia6850_3_ctrl_w ) { acia6850_ctrl_w(3, data); }
/*-------------------------------------------------
DEVICE_SET_INFO( acia6850 )
-------------------------------------------------*/
WRITE8_HANDLER( acia6850_0_data_w ) { acia6850_data_w(space->machine, 0, data); }
WRITE8_HANDLER( acia6850_1_data_w ) { acia6850_data_w(space->machine, 1, data); }
WRITE8_HANDLER( acia6850_2_data_w ) { acia6850_data_w(space->machine, 2, data); }
WRITE8_HANDLER( acia6850_3_data_w ) { acia6850_data_w(space->machine, 3, data); }
static DEVICE_SET_INFO( acia6850 )
{
switch (state)
{
/* no parameters to set */
}
}
READ8_HANDLER( acia6850_0_stat_r ) { return acia6850_stat_r(0); }
READ8_HANDLER( acia6850_1_stat_r ) { return acia6850_stat_r(1); }
READ8_HANDLER( acia6850_2_stat_r ) { return acia6850_stat_r(2); }
READ8_HANDLER( acia6850_3_stat_r ) { return acia6850_stat_r(3); }
READ8_HANDLER( acia6850_0_data_r ) { return acia6850_data_r(0); }
READ8_HANDLER( acia6850_1_data_r ) { return acia6850_data_r(1); }
READ8_HANDLER( acia6850_2_data_r ) { return acia6850_data_r(2); }
READ8_HANDLER( acia6850_3_data_r ) { return acia6850_data_r(3); }
/*-------------------------------------------------
DEVICE_GET_INFO( acia6850 )
-------------------------------------------------*/
READ16_HANDLER( acia6850_0_stat_lsb_r ) { return acia6850_stat_r(0); }
READ16_HANDLER( acia6850_1_stat_lsb_r ) { return acia6850_stat_r(1); }
READ16_HANDLER( acia6850_2_stat_lsb_r ) { return acia6850_stat_r(2); }
READ16_HANDLER( acia6850_3_stat_lsb_r ) { return acia6850_stat_r(3); }
DEVICE_GET_INFO( acia6850 )
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(acia6850_t); break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
READ16_HANDLER( acia6850_0_stat_msb_r ) { return acia6850_stat_r(0) << 8; }
READ16_HANDLER( acia6850_1_stat_msb_r ) { return acia6850_stat_r(1) << 8; }
READ16_HANDLER( acia6850_2_stat_msb_r ) { return acia6850_stat_r(2) << 8; }
READ16_HANDLER( acia6850_3_stat_msb_r ) { return acia6850_stat_r(3) << 8; }
/* --- the following bits of info are returned as pointers to data or functions --- */
case DEVINFO_FCT_SET_INFO: info->set_info = DEVICE_SET_INFO_NAME(acia6850); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(acia6850); break;
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(acia6850); break;
READ16_HANDLER( acia6850_0_data_lsb_r ) { return acia6850_data_r(0); }
READ16_HANDLER( acia6850_1_data_lsb_r ) { return acia6850_data_r(1); }
READ16_HANDLER( acia6850_2_data_lsb_r ) { return acia6850_data_r(2); }
READ16_HANDLER( acia6850_3_data_lsb_r ) { return acia6850_data_r(3); }
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: info->s = "6850 ACIA"; break;
case DEVINFO_STR_FAMILY: info->s = "6850 ACIA"; break;
case DEVINFO_STR_VERSION: info->s = "1.0"; break;
case DEVINFO_STR_SOURCE_FILE: info->s = __FILE__; break;
case DEVINFO_STR_CREDITS: /* Nothing */ break;
}
}
READ16_HANDLER( acia6850_0_data_msb_r ) { return acia6850_data_r(0) << 8; }
READ16_HANDLER( acia6850_1_data_msb_r ) { return acia6850_data_r(1) << 8; }
READ16_HANDLER( acia6850_2_data_msb_r ) { return acia6850_data_r(2) << 8; }
READ16_HANDLER( acia6850_3_data_msb_r ) { return acia6850_data_r(3) << 8; }
WRITE16_HANDLER( acia6850_0_ctrl_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_ctrl_w(0, (data >> 8) & 0xff); }
WRITE16_HANDLER( acia6850_1_ctrl_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_ctrl_w(1, (data >> 8) & 0xff); }
WRITE16_HANDLER( acia6850_2_ctrl_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_ctrl_w(2, (data >> 8) & 0xff); }
WRITE16_HANDLER( acia6850_3_ctrl_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_ctrl_w(3, (data >> 8) & 0xff); }
/* ----------------------------------------------------------------------- */
WRITE16_HANDLER( acia6850_0_ctrl_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_ctrl_w(0, data & 0xff); }
WRITE16_HANDLER( acia6850_1_ctrl_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_ctrl_w(1, data & 0xff); }
WRITE16_HANDLER( acia6850_2_ctrl_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_ctrl_w(2, data & 0xff); }
WRITE16_HANDLER( acia6850_3_ctrl_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_ctrl_w(3, data & 0xff); }
READ16_DEVICE_HANDLER( acia6850_stat_lsb_r ) { return acia6850_stat_r(device, 0) << 0; }
READ16_DEVICE_HANDLER( acia6850_stat_msb_r ) { return acia6850_stat_r(device, 0) << 8; }
WRITE16_HANDLER( acia6850_0_data_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_data_w(space->machine, 0, (data >> 8) & 0xff); }
WRITE16_HANDLER( acia6850_1_data_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_data_w(space->machine, 1, (data >> 8) & 0xff); }
WRITE16_HANDLER( acia6850_2_data_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_data_w(space->machine, 2, (data >> 8) & 0xff); }
WRITE16_HANDLER( acia6850_3_data_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_data_w(space->machine, 3, (data >> 8) & 0xff); }
READ16_DEVICE_HANDLER( acia6850_data_lsb_r ) { return acia6850_data_r(device, 0) << 0; }
READ16_DEVICE_HANDLER( acia6850_data_msb_r ) { return acia6850_data_r(device, 0) << 8; }
WRITE16_HANDLER( acia6850_0_data_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_data_w(space->machine, 0, data & 0xff); }
WRITE16_HANDLER( acia6850_1_data_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_data_w(space->machine, 1, data & 0xff); }
WRITE16_HANDLER( acia6850_2_data_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_data_w(space->machine, 2, data & 0xff); }
WRITE16_HANDLER( acia6850_3_data_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_data_w(space->machine, 3, data & 0xff); }
WRITE16_DEVICE_HANDLER( acia6850_ctrl_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_ctrl_w(device, 0, (data >> 8) & 0xff); }
WRITE16_DEVICE_HANDLER( acia6850_ctrl_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_ctrl_w(device, 0, (data >> 0) & 0xff); }
WRITE16_DEVICE_HANDLER( acia6850_data_msb_w ) { if (ACCESSING_BITS_8_15) acia6850_data_w(device, 0, (data >> 8) & 0xff); }
WRITE16_DEVICE_HANDLER( acia6850_data_lsb_w ) { if (ACCESSING_BITS_0_7) acia6850_data_w(device, 0, (data >> 0) & 0xff); }

View File

@ -1,7 +1,20 @@
#ifndef ACIA6850_H
#define ACIA6850_H
/*********************************************************************
#define MAX_ACIA 4
6850acia.h
6850 ACIA code
*********************************************************************/
#ifndef __ACIA6850_H__
#define __ACIA6850_H__
/***************************************************************************
MACROS
***************************************************************************/
#define ACIA6850 DEVICE_GET_INFO_NAME(acia6850)
#define ACIA6850_STATUS_RDRF 0x01
#define ACIA6850_STATUS_TDRE 0x02
@ -12,7 +25,14 @@
#define ACIA6850_STATUS_PE 0x40
#define ACIA6850_STATUS_IRQ 0x80
struct acia6850_interface
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef struct _acia6850_interface acia6850_interface;
struct _acia6850_interface
{
int tx_clock;
int rx_clock;
@ -23,74 +43,35 @@ struct acia6850_interface
UINT8 *rts_pin;
UINT8 *dcd_pin;
void (*int_callback)(int state);
void (*int_callback)(const device_config *device, int state);
};
void acia6850_config(int which, const struct acia6850_interface *intf);
void acia_tx_clock_in(int which);
void acia_rx_clock_in(int which);
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
void acia6850_set_rx_clock(int which, int clock);
void acia6850_set_tx_clock(int which, int clock);
DEVICE_GET_INFO( acia6850 );
WRITE8_HANDLER( acia6850_0_ctrl_w );
WRITE8_HANDLER( acia6850_1_ctrl_w );
WRITE8_HANDLER( acia6850_2_ctrl_w );
WRITE8_HANDLER( acia6850_3_ctrl_w );
void acia_tx_clock_in(const device_config *device) ATTR_NONNULL;
void acia_rx_clock_in(const device_config *device) ATTR_NONNULL;
WRITE8_HANDLER( acia6850_0_data_w );
WRITE8_HANDLER( acia6850_1_data_w );
WRITE8_HANDLER( acia6850_2_data_w );
WRITE8_HANDLER( acia6850_3_data_w );
void acia6850_set_rx_clock(const device_config *device, int clock) ATTR_NONNULL;
void acia6850_set_tx_clock(const device_config *device, int clock) ATTR_NONNULL;
READ8_HANDLER( acia6850_0_stat_r );
READ8_HANDLER( acia6850_1_stat_r );
READ8_HANDLER( acia6850_2_stat_r );
READ8_HANDLER( acia6850_3_stat_r );
WRITE8_DEVICE_HANDLER( acia6850_ctrl_w );
READ8_DEVICE_HANDLER( acia6850_stat_r );
WRITE8_DEVICE_HANDLER( acia6850_data_w );
READ8_DEVICE_HANDLER( acia6850_data_r );
READ8_HANDLER( acia6850_0_data_r );
READ8_HANDLER( acia6850_1_data_r );
READ8_HANDLER( acia6850_2_data_r );
READ8_HANDLER( acia6850_3_data_r );
READ16_DEVICE_HANDLER( acia6850_stat_lsb_r );
READ16_DEVICE_HANDLER( acia6850_stat_msb_r );
READ16_DEVICE_HANDLER( acia6850_data_lsb_r );
READ16_DEVICE_HANDLER( acia6850_data_msb_r );
READ16_HANDLER( acia6850_0_stat_lsb_r );
READ16_HANDLER( acia6850_1_stat_lsb_r );
READ16_HANDLER( acia6850_2_stat_lsb_r );
READ16_HANDLER( acia6850_3_stat_lsb_r );
WRITE16_DEVICE_HANDLER( acia6850_ctrl_msb_w );
WRITE16_DEVICE_HANDLER( acia6850_ctrl_lsb_w );
WRITE16_DEVICE_HANDLER( acia6850_data_msb_w );
WRITE16_DEVICE_HANDLER( acia6850_data_lsb_w );
READ16_HANDLER( acia6850_0_stat_msb_r );
READ16_HANDLER( acia6850_1_stat_msb_r );
READ16_HANDLER( acia6850_2_stat_msb_r );
READ16_HANDLER( acia6850_3_stat_msb_r );
READ16_HANDLER( acia6850_0_data_lsb_r );
READ16_HANDLER( acia6850_1_data_lsb_r );
READ16_HANDLER( acia6850_2_data_lsb_r );
READ16_HANDLER( acia6850_3_data_lsb_r );
READ16_HANDLER( acia6850_0_data_msb_r );
READ16_HANDLER( acia6850_1_data_msb_r );
READ16_HANDLER( acia6850_2_data_msb_r );
READ16_HANDLER( acia6850_3_data_msb_r );
WRITE16_HANDLER( acia6850_0_ctrl_msb_w );
WRITE16_HANDLER( acia6850_1_ctrl_msb_w );
WRITE16_HANDLER( acia6850_2_ctrl_msb_w );
WRITE16_HANDLER( acia6850_3_ctrl_msb_w );
WRITE16_HANDLER( acia6850_0_ctrl_lsb_w );
WRITE16_HANDLER( acia6850_1_ctrl_lsb_w );
WRITE16_HANDLER( acia6850_2_ctrl_lsb_w );
WRITE16_HANDLER( acia6850_3_ctrl_lsb_w );
WRITE16_HANDLER( acia6850_0_data_msb_w );
WRITE16_HANDLER( acia6850_1_data_msb_w );
WRITE16_HANDLER( acia6850_2_data_msb_w );
WRITE16_HANDLER( acia6850_3_data_msb_w );
WRITE16_HANDLER( acia6850_0_data_lsb_w );
WRITE16_HANDLER( acia6850_1_data_lsb_w );
WRITE16_HANDLER( acia6850_2_data_lsb_w );
WRITE16_HANDLER( acia6850_3_data_lsb_w );
#endif
#endif /* __ACIA6850_H__ */

View File

@ -73,7 +73,6 @@
******************************************************************************/
#include "driver.h"
#include "deprecat.h"
#include "machine/6850acia.h"
#include "machine/meters.h"
#include "cpu/z80/z80.h"
@ -1316,10 +1315,10 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( z80_io_map, ADDRESS_SPACE_IO, 8 )
ADDRESS_MAP_GLOBAL_MASK(0xff)
AM_RANGE(0x00, 0x23) AM_READWRITE(chipset_r, chipset_w)
AM_RANGE(0x24, 0x24) AM_WRITE(acia6850_0_ctrl_w)
AM_RANGE(0x25, 0x25) AM_WRITE(acia6850_0_data_w)
AM_RANGE(0x26, 0x26) AM_READ(acia6850_0_stat_r)
AM_RANGE(0x27, 0x27) AM_READ(acia6850_0_data_r)
AM_RANGE(0x24, 0x24) AM_DEVWRITE(ACIA6850, "acia6850_0", acia6850_ctrl_w)
AM_RANGE(0x25, 0x25) AM_DEVWRITE(ACIA6850, "acia6850_0", acia6850_data_w)
AM_RANGE(0x26, 0x26) AM_DEVREAD(ACIA6850, "acia6850_0", acia6850_stat_r)
AM_RANGE(0x27, 0x27) AM_DEVREAD(ACIA6850, "acia6850_0", acia6850_data_r)
AM_RANGE(0x30, 0x30) AM_READ(fdctrl_r)
AM_RANGE(0x31, 0x31) AM_READWRITE(fddata_r, fdctrl_w)
AM_RANGE(0x40, 0x40) AM_WRITE(rombank_w)
@ -1447,10 +1446,10 @@ static ADDRESS_MAP_START( m6809_prog_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x2E00, 0x2E00) AM_READ(int_latch_r)
AM_RANGE(0x3001, 0x3001) AM_WRITE(ay8910_write_port_0_w)
AM_RANGE(0x3201, 0x3201) AM_WRITE(ay8910_control_port_0_w)
AM_RANGE(0x3404, 0x3404) AM_READWRITE(acia6850_1_stat_r, acia6850_1_ctrl_w)
AM_RANGE(0x3405, 0x3405) AM_READWRITE(acia6850_1_data_r, acia6850_1_data_w)
AM_RANGE(0x3406, 0x3406) AM_READWRITE(acia6850_2_stat_r, acia6850_2_ctrl_w)
AM_RANGE(0x3407, 0x3407) AM_READWRITE(acia6850_2_data_r, acia6850_2_data_w)
AM_RANGE(0x3404, 0x3404) AM_DEVREADWRITE(ACIA6850, "acia6850_1", acia6850_stat_r, acia6850_ctrl_w)
AM_RANGE(0x3405, 0x3405) AM_DEVREADWRITE(ACIA6850, "acia6850_1", acia6850_data_r, acia6850_data_w)
AM_RANGE(0x3406, 0x3406) AM_DEVREADWRITE(ACIA6850, "acia6850_2", acia6850_stat_r, acia6850_ctrl_w)
AM_RANGE(0x3407, 0x3407) AM_DEVREADWRITE(ACIA6850, "acia6850_2", acia6850_data_r, acia6850_data_w)
// AM_RANGE(0x3408, 0x3408) AM_NOP
// AM_RANGE(0x340A, 0x340A) AM_NOP
// AM_RANGE(0x3600, 0x3600) AM_NOP
@ -1577,21 +1576,21 @@ static void init_ram(void)
memset(video_ram, 0, 0x20000);
}
static void z80_acia_irq(int state)
static void z80_acia_irq(const device_config *device, int state)
{
acia_irq = state ? CLEAR_LINE : ASSERT_LINE;
update_irqs(Machine);
update_irqs(device->machine);
}
static void m6809_data_irq(int state)
static void m6809_data_irq(const device_config *device, int state)
{
cpu_set_input_line(Machine->cpu[1], M6809_IRQ_LINE, state ? CLEAR_LINE : ASSERT_LINE);
cpu_set_input_line(device->machine->cpu[1], M6809_IRQ_LINE, state ? CLEAR_LINE : ASSERT_LINE);
}
/*
What are the correct ACIA clocks ?
*/
static const struct acia6850_interface z80_acia_if =
static const acia6850_interface z80_acia_if =
{
500000,
500000,
@ -1603,7 +1602,7 @@ static const struct acia6850_interface z80_acia_if =
z80_acia_irq
};
static const struct acia6850_interface m6809_acia_if =
static const acia6850_interface m6809_acia_if =
{
500000,
500000,
@ -1615,7 +1614,7 @@ static const struct acia6850_interface m6809_acia_if =
NULL
};
static const struct acia6850_interface data_acia_if =
static const acia6850_interface data_acia_if =
{
500000,
500000,
@ -1674,11 +1673,6 @@ static DRIVER_INIT( bfcobra )
/* Fixed 16kB ROM region */
memory_set_bankptr(machine, 4, memory_region(machine, "user1"));
/* Configure the ACIAs */
acia6850_config(0, &z80_acia_if);
acia6850_config(1, &m6809_acia_if);
acia6850_config(2, &data_acia_if);
/* TODO: Properly sort out the data ACIA */
data_r = 1;
@ -1744,6 +1738,14 @@ static MACHINE_DRIVER_START( bfcobra )
MDRV_VIDEO_START(bfcobra)
MDRV_VIDEO_UPDATE(bfcobra)
/* ACIAs */
MDRV_DEVICE_ADD("acia6850_0", ACIA6850)
MDRV_DEVICE_CONFIG(z80_acia_if)
MDRV_DEVICE_ADD("acia6850_1", ACIA6850)
MDRV_DEVICE_CONFIG(m6809_acia_if)
MDRV_DEVICE_ADD("acia6850_2", ACIA6850)
MDRV_DEVICE_CONFIG(data_acia_if)
MACHINE_DRIVER_END
/***************************************************************************

View File

@ -621,8 +621,6 @@
#include "machine/6850acia.h"
#include "sound/ay8910.h"
#include "deprecat.h"
/* UART */
static UINT8 tx_line;
@ -646,14 +644,13 @@ static READ8_HANDLER( dipsw_1_r )
return input_port_read(space->machine, "SW1");
}
static void tx_rx_clk (int dsw2)
static void tx_rx_clk (const device_config *device, int dsw2)
{
int trx_clk;
dsw2 = input_port_read(Machine, "SW2");
dsw2 = input_port_read(device->machine, "SW2");
trx_clk = UART_CLOCK * dsw2 / 128;
acia6850_set_rx_clock(0, trx_clk);
acia6850_set_tx_clock(0, trx_clk);
acia6850_set_rx_clock(device, trx_clk);
acia6850_set_tx_clock(device, trx_clk);
return;
}
@ -761,8 +758,8 @@ static ADDRESS_MAP_START( sys903_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0881, 0x0881) AM_DEVREADWRITE(MC6845, "crtc", mc6845_register_r, mc6845_register_w)
AM_RANGE(0x08c4, 0x08c7) AM_READWRITE(pia_0_r, pia_0_w)
AM_RANGE(0x08c8, 0x08cb) AM_READWRITE(pia_1_r, pia_1_w)
AM_RANGE(0x08d0, 0x08d0) AM_READWRITE(acia6850_0_stat_r, acia6850_0_ctrl_w)
AM_RANGE(0x08d1, 0x08d1) AM_READWRITE(acia6850_0_data_r, acia6850_0_data_w)
AM_RANGE(0x08d0, 0x08d0) AM_DEVREADWRITE(ACIA6850, "acia6850_0", acia6850_stat_r, acia6850_ctrl_w)
AM_RANGE(0x08d1, 0x08d1) AM_DEVREADWRITE(ACIA6850, "acia6850_0", acia6850_data_r, acia6850_data_w)
AM_RANGE(0x1000, 0x13ff) AM_RAM_WRITE(calomega_videoram_w) AM_BASE(&videoram)
AM_RANGE(0x1400, 0x17ff) AM_RAM_WRITE(calomega_colorram_w) AM_BASE(&colorram)
AM_RANGE(0x1800, 0x3fff) AM_ROM
@ -1842,7 +1839,7 @@ static const pia6821_interface sys905_pia1_intf =
* ACIA Interface *
***********************/
static const struct acia6850_interface acia6850_intf =
static const acia6850_interface acia6850_intf =
{
UART_CLOCK,
UART_CLOCK,
@ -1863,7 +1860,6 @@ static MACHINE_START( sys903 )
{
pia_config(0, &sys903_pia0_intf);
pia_config(1, &sys903_pia1_intf);
acia6850_config(0, &acia6850_intf);
}
static MACHINE_START( sys905 )
@ -1940,6 +1936,10 @@ static MACHINE_DRIVER_START( sys903 )
MDRV_SOUND_ADD("ay8912", AY8912, SND_CLOCK) /* confirmed */
MDRV_SOUND_CONFIG(sys903_ay8912_intf)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
/* acia */
MDRV_DEVICE_ADD("acia6850_0", ACIA6850)
MDRV_DEVICE_CONFIG(acia6850_intf)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( sys905 )

View File

@ -279,22 +279,22 @@ static void update_mpu68_interrupts(running_machine *machine)
/* Communications with 6809 board */
/* Clock values are currently unknown, and are derived from the 68k board.*/
static void m6809_acia_irq(int state)
static void m6809_acia_irq(const device_config *device, int state)
{
m68k_acia_cts = state;
cpu_set_input_line(Machine->cpu[0], M6809_IRQ_LINE, state?ASSERT_LINE:CLEAR_LINE);
cpu_set_input_line(device->machine->cpu[0], M6809_IRQ_LINE, state?ASSERT_LINE:CLEAR_LINE);
}
static void m68k_acia_irq(int state)
static void m68k_acia_irq(const device_config *device, int state)
{
m6809_acia_cts = state;
m6850_irq_state = state;
update_mpu68_interrupts(Machine);
update_mpu68_interrupts(device->machine);
}
static const struct acia6850_interface m6809_acia_if =
static const acia6850_interface m6809_acia_if =
{
0,
0,
@ -307,7 +307,7 @@ static const struct acia6850_interface m6809_acia_if =
};
static const struct acia6850_interface m68k_acia_if =
static const acia6850_interface m68k_acia_if =
{
0,
0,
@ -333,10 +333,12 @@ static WRITE8_HANDLER( vid_o1_callback )
if (data)
{
acia_tx_clock_in(0);
acia_rx_clock_in(0);
acia_tx_clock_in(1);
acia_rx_clock_in(1);
const device_config *acia_0 = device_list_find_by_tag(space->machine->config->devicelist, ACIA6850, "acia6850_0");
const device_config *acia_1 = device_list_find_by_tag(space->machine->config->devicelist, ACIA6850, "acia6850_1");
acia_tx_clock_in(acia_0);
acia_rx_clock_in(acia_0);
acia_tx_clock_in(acia_1);
acia_rx_clock_in(acia_1);
}
}
@ -1356,8 +1358,6 @@ MACHINE_START( mpu4_vid )
/* setup communications */
serial_card_connected=1;
acia6850_config(0, &m6809_acia_if);
acia6850_config(1, &m68k_acia_if);
/* setup 8 mechanical meters */
Mechmtr_init(8);
@ -1436,8 +1436,8 @@ static ADDRESS_MAP_START( mpu4_68k_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w)
/* comms with the MPU4 */
AM_RANGE(0xff8000, 0xff8001) AM_READWRITE(acia6850_1_stat_lsb_r, acia6850_1_ctrl_lsb_w)
AM_RANGE(0xff8002, 0xff8003) AM_READWRITE(acia6850_1_data_lsb_r, acia6850_1_data_lsb_w)
AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE(ACIA6850, "acia6850_1", acia6850_stat_lsb_r, acia6850_ctrl_lsb_w)
AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE(ACIA6850, "acia6850_1", acia6850_data_lsb_r, acia6850_data_lsb_w)
AM_RANGE(0xff9000, 0xff900f) AM_READWRITE(ptm6840_1_lsb_r,ptm6840_1_lsb_w) /* 6840PTM */
@ -1448,8 +1448,8 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( mpu4_6809_map, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x0000, 0x07FF) AM_RAM AM_BASE(&generic_nvram) AM_SIZE(&generic_nvram_size)
AM_RANGE(0x0800, 0x0800) AM_READWRITE(acia6850_0_stat_r, acia6850_0_ctrl_w)
AM_RANGE(0x0801, 0x0801) AM_READWRITE(acia6850_0_data_r, acia6850_0_data_w)
AM_RANGE(0x0800, 0x0800) AM_DEVREADWRITE(ACIA6850, "acia6850_0", acia6850_stat_r, acia6850_ctrl_w)
AM_RANGE(0x0801, 0x0801) AM_DEVREADWRITE(ACIA6850, "acia6850_0", acia6850_data_r, acia6850_data_w)
AM_RANGE(0x0880, 0x0881) AM_NOP /* Could be a UART datalogger is here. */
@ -1492,8 +1492,8 @@ static ADDRESS_MAP_START( vp_68k_map, ADDRESS_SPACE_PROGRAM, 16 )
/* AM_RANGE(0xe05000, 0xe05001) AM_READWRITE(adpcm_r, adpcm_w) */
/* comms with the MPU4 */
AM_RANGE(0xff8000, 0xff8001) AM_READWRITE(acia6850_1_stat_lsb_r, acia6850_1_ctrl_lsb_w)
AM_RANGE(0xff8002, 0xff8003) AM_READWRITE(acia6850_1_data_lsb_r, acia6850_1_data_lsb_w)
AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE(ACIA6850, "acia6850_1", acia6850_stat_lsb_r, acia6850_ctrl_lsb_w)
AM_RANGE(0xff8002, 0xff8003) AM_DEVREADWRITE(ACIA6850, "acia6850_1", acia6850_data_lsb_r, acia6850_data_lsb_w)
AM_RANGE(0xff9000, 0xff900f) AM_READ( ptm6840_1_lsb_r)
AM_RANGE(0xff9000, 0xff900f) AM_WRITE( ptm6840_1_lsb_w)
@ -1688,6 +1688,12 @@ static MACHINE_DRIVER_START( mpu4_vid )
MDRV_SOUND_ADD("saa", SAA1099, 8000000)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "left", 1.00)
MDRV_SOUND_ROUTE(ALL_OUTPUTS, "right", 1.00)
/* ACIAs */
MDRV_DEVICE_ADD("acia6850_0", ACIA6850)
MDRV_DEVICE_CONFIG(m6809_acia_if)
MDRV_DEVICE_ADD("acia6850_1", ACIA6850)
MDRV_DEVICE_CONFIG(m68k_acia_if)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( vgpoker )