ins8154: Updated to use devcb calls, cleaned up

This commit is contained in:
Dirk Best 2010-02-22 11:35:38 +00:00
parent b7927daaff
commit 4c15a5dfd7
2 changed files with 182 additions and 148 deletions

View File

@ -1,22 +1,23 @@
/***************************************************************************** /***************************************************************************
*
* machine/ins8154.h National Semiconductor INS8154
*
* INS8154 N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O) N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O)
*
* Written by Dirk Best, January 2008
* TODO: Strobed modes
* TODO: Strobed modes
* ***************************************************************************/
****************************************************************************/
#include "emu.h" #include "emu.h"
#include "ins8154.h" #include "ins8154.h"
#define VERBOSE 1 /***************************************************************************
#define LOG(x) do { if (VERBOSE) logerror x; } while (0) CONSTANTS
***************************************************************************/
#define VERBOSE 1
/* Mode Definition Register */ /* Mode Definition Register */
enum enum
@ -27,11 +28,22 @@ enum
MDR_STROBED_OUTPUT_3STATE = 0xe0 MDR_STROBED_OUTPUT_3STATE = 0xe0
}; };
typedef struct _ins8154_t ins8154_t;
struct _ins8154_t
{
const ins8154_interface *intf; /* Pointer to our interface */
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef struct _ins8154_state ins8154_state;
struct _ins8154_state
{
/* i/o lines */
devcb_resolved_read8 in_a_func;
devcb_resolved_write8 out_a_func;
devcb_resolved_read8 in_b_func;
devcb_resolved_write8 out_b_func;
devcb_resolved_write_line out_irq_func;
/* registers */
UINT8 in_a; /* Input Latch Port A */ UINT8 in_a; /* Input Latch Port A */
UINT8 in_b; /* Input Latch Port B */ UINT8 in_b; /* Input Latch Port B */
UINT8 out_a; /* Output Latch Port A */ UINT8 out_a; /* Output Latch Port A */
@ -42,79 +54,62 @@ struct _ins8154_t
}; };
static DEVICE_START( ins8154 ) /*****************************************************************************
INLINE FUNCTIONS
*****************************************************************************/
INLINE ins8154_state *get_safe_token(running_device *device)
{ {
ins8154_t *ins8154 = (ins8154_t *)device->token; assert(device != NULL);
assert(device->token != NULL);
assert(device->type == INS8154);
/* validate arguments */ return (ins8154_state *)device->token;
assert(device->tag != NULL);
/* assign interface */
ins8154->intf = (const ins8154_interface*)device->baseconfig().static_config;
/* register for state saving */
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->in_a);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->in_b);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->out_a);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->out_b);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->mdr);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->odra);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->odrb);
} }
static DEVICE_RESET( ins8154 ) /***************************************************************************
{ IMPLEMENTATION
ins8154_t *ins8154 = (ins8154_t *)device->token; ***************************************************************************/
ins8154->in_a = 0;
ins8154->in_b = 0;
ins8154->out_a = 0;
ins8154->out_b = 0;
ins8154->mdr = 0;
ins8154->odra = 0;
ins8154->odrb = 0;
}
READ8_DEVICE_HANDLER( ins8154_r ) READ8_DEVICE_HANDLER( ins8154_r )
{ {
ins8154_t *i = (ins8154_t *)device->token; ins8154_state *ins8154 = get_safe_token(device);
UINT8 val = 0xff; UINT8 val = 0xff;
if (offset > 0x24) if (offset > 0x24)
{ {
logerror("INS8154 (%08x): Read from unknown offset %02x!\n", if (VERBOSE)
cpu_get_pc( device->machine->firstcpu ), offset); logerror("%s: INS8154 '%s' Read from invalid offset %02x!\n", cpuexec_describe_context(device->machine), device->tag.cstr(), offset);
return 0xff; return 0xff;
} }
switch (offset) switch (offset)
{ {
case 0x20: case 0x20:
if (i->intf->in_a_func) if (ins8154->in_a_func.read != NULL)
val = i->intf->in_a_func(device, 0); val = devcb_call_read8(&ins8154->in_a_func, 0);
i->in_a = val; ins8154->in_a = val;
break; break;
case 0x21: case 0x21:
if (i->intf->in_b_func) if (ins8154->in_b_func.read != NULL)
val = i->intf->in_b_func(device, 0); val = devcb_call_read8(&ins8154->in_b_func, 0);
i->in_b = val; ins8154->in_b = val;
break; break;
default: default:
if (offset < 0x08) if (offset < 0x08)
{ {
if (i->intf->in_a_func) if (ins8154->in_a_func.read != NULL)
val = (i->intf->in_a_func(device, 0) << (8 - offset)) & 0x80; val = (devcb_call_read8(&ins8154->in_a_func, 0) << (8 - offset)) & 0x80;
i->in_a = val; ins8154->in_a = val;
} }
else else
{ {
if (i->intf->in_a_func) if (ins8154->in_b_func.read != NULL)
val = (i->intf->in_a_func(device, 0) << (8 - (offset >> 4))) & 0x80; val = (devcb_call_read8(&ins8154->in_b_func, 0) << (8 - (offset >> 4))) & 0x80;
i->in_b = val; ins8154->in_b = val;
} }
break; break;
} }
@ -124,48 +119,34 @@ READ8_DEVICE_HANDLER( ins8154_r )
WRITE8_DEVICE_HANDLER( ins8154_porta_w ) WRITE8_DEVICE_HANDLER( ins8154_porta_w )
{ {
ins8154_t *i = (ins8154_t *)device->token; ins8154_state *ins8154 = get_safe_token(device);
i->out_a = data; ins8154->out_a = data;
/* Test if any pins are set as outputs */ /* Test if any pins are set as outputs */
if (i->odra) if (ins8154->odra)
{ devcb_call_write8(&ins8154->out_a_func, 0, (data & ins8154->odra) | (ins8154->odra ^ 0xff));
if (i->intf->out_a_func)
i->intf->out_a_func(device, 0, (data & i->odra) | (i->odra ^ 0xff));
else
logerror("INS8154 (%08x): Write to port A but no write handler defined!\n",
cpu_get_pc( device->machine->firstcpu ) );
}
} }
WRITE8_DEVICE_HANDLER( ins8154_portb_w ) WRITE8_DEVICE_HANDLER( ins8154_portb_w )
{ {
ins8154_t *i = (ins8154_t *)device->token; ins8154_state *ins8154 = get_safe_token(device);
i->out_b = data; ins8154->out_b = data;
/* Test if any pins are set as outputs */ /* Test if any pins are set as outputs */
if (i->odrb) if (ins8154->odrb)
{ devcb_call_write8(&ins8154->out_b_func, 0, (data & ins8154->odrb) | (ins8154->odrb ^ 0xff));
if (i->intf->out_b_func)
i->intf->out_b_func(device, 0, (data & i->odrb) | (i->odrb ^ 0xff));
else
logerror("INS8154 (%08x): Write to port B but no write handler defined!\n",
cpu_get_pc( device->machine->firstcpu ) );
}
} }
WRITE8_DEVICE_HANDLER( ins8154_w ) WRITE8_DEVICE_HANDLER( ins8154_w )
{ {
ins8154_t *i = (ins8154_t *)device->token; ins8154_state *ins8154 = get_safe_token(device);
if (offset > 0x24) if (offset > 0x24)
{ {
logerror("INS8154 (%04x): Write %02x to invalid offset %02x!\n", if (VERBOSE)
cpu_get_pc( device->machine->firstcpu ), data, offset); logerror("%s: INS8154 '%s' Write %02x to invalid offset %02x!\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data, offset);
return; return;
} }
@ -180,21 +161,24 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
break; break;
case 0x22: case 0x22:
LOG(("INS8154 (%04x): ODR for port A set to %02x\n", if (VERBOSE)
cpu_get_pc( device->machine->firstcpu ), data)); logerror("%s: INS8154 '%s' ODRA set to %02x\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data);
i->odra = data;
ins8154->odra = data;
break; break;
case 0x23: case 0x23:
LOG(("INS8154 (%04x): ODR for port B set to %02x\n", if (VERBOSE)
cpu_get_pc( device->machine->firstcpu ), data)); logerror("%s: INS8154 '%s' ODRB set to %02x\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data);
i->odrb = data;
ins8154->odrb = data;
break; break;
case 0x24: case 0x24:
LOG(("INS8154 (%04x): MDR set to %02x\n", if (VERBOSE)
cpu_get_pc( device->machine->firstcpu ), data)); logerror("%s: INS8154 '%s' MDR set to %02x\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data);
i->mdr = data;
ins8154->mdr = data;
break; break;
default: default:
@ -203,11 +187,11 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
/* Set bit */ /* Set bit */
if (offset < 0x08) if (offset < 0x08)
{ {
ins8154_porta_w(device, 0, i->out_a |= offset & 0x07); ins8154_porta_w(device, 0, ins8154->out_a |= offset & 0x07);
} }
else else
{ {
ins8154_portb_w(device, 0, i->out_b |= (offset >> 4) & 0x07); ins8154_portb_w(device, 0, ins8154->out_b |= (offset >> 4) & 0x07);
} }
} }
else else
@ -215,11 +199,11 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
/* Clear bit */ /* Clear bit */
if (offset < 0x08) if (offset < 0x08)
{ {
ins8154_porta_w(device, 0, i->out_a & ~(offset & 0x07)); ins8154_porta_w(device, 0, ins8154->out_a & ~(offset & 0x07));
} }
else else
{ {
ins8154_portb_w(device, 0, i->out_b & ~((offset >> 4) & 0x07)); ins8154_portb_w(device, 0, ins8154->out_b & ~((offset >> 4) & 0x07));
} }
} }
@ -228,25 +212,59 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
} }
DEVICE_GET_INFO( ins8154 ) /*****************************************************************************
DEVICE INTERFACE
*****************************************************************************/
static DEVICE_START( ins8154 )
{ {
switch (state) ins8154_state *ins8154 = get_safe_token(device);
{ const ins8154_interface *intf = (const ins8154_interface *)device->baseconfig().static_config;
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break;
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(ins8154_t); break;
/* --- the following bits of info are returned as pointers to data or functions --- */ /* validate some basic stuff */
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ins8154); break; assert(intf != NULL);
case DEVINFO_FCT_STOP: /* Nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(ins8154); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */ /* resolve callbacks */
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor INS8154"); break; devcb_resolve_read8(&ins8154->in_a_func, &intf->in_a_func, device);
case DEVINFO_STR_FAMILY: strcpy(info->s, "INS8154"); break; devcb_resolve_write8(&ins8154->out_a_func, &intf->out_a_func, device);
case DEVINFO_STR_VERSION: strcpy(info->s, "1.0"); break; devcb_resolve_read8(&ins8154->in_b_func, &intf->in_b_func, device);
case DEVINFO_STR_SOURCE_FILE: strcpy(info->s, __FILE__); break; devcb_resolve_write8(&ins8154->out_b_func, &intf->out_b_func, device);
case DEVINFO_STR_CREDITS: strcpy(info->s, "Copyright MESS Team"); break; devcb_resolve_write_line(&ins8154->out_irq_func, &intf->out_irq_func, device);
}
/* register for state saving */
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->in_a);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->in_b);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->out_a);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->out_b);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->mdr);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->odra);
state_save_register_item(device->machine, "ins8154", device->tag, 0, ins8154->odrb);
} }
static DEVICE_RESET( ins8154 )
{
ins8154_state *ins8154 = get_safe_token(device);
ins8154->in_a = 0;
ins8154->in_b = 0;
ins8154->out_a = 0;
ins8154->out_b = 0;
ins8154->mdr = 0;
ins8154->odra = 0;
ins8154->odrb = 0;
}
/***************************************************************************
DEVICE GETINFO
***************************************************************************/
static const char DEVTEMPLATE_SOURCE[] = __FILE__;
#define DEVTEMPLATE_ID(p,s) p##ins8154##s
#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET
#define DEVTEMPLATE_NAME "INS8154"
#define DEVTEMPLATE_FAMILY "INS8154"
#define DEVTEMPLATE_VERSION "1.1"
#define DEVTEMPLATE_CREDITS "Copyright MESS Team"
#include "devtempl.h"

View File

@ -1,60 +1,76 @@
/*****************************************************************************
*
* machine/ins8154.h
*
* INS8154 N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O)
*
****************************************************************************/
#ifndef INS8154_H_
#define INS8154_H_
/*************************************************************************** /***************************************************************************
MACROS
National Semiconductor INS8154
N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O)
_____ _____
PB6 1 |* \_/ | 40 VCC
PB5 2 | | 39 PB7
PB4 3 | | 38 NWDS
PB3 4 | | 37 NRDS
PB2 5 | | 36 NRST
PB1 6 | | 35 _CS0
PB0 7 | | 34 CS1
DB7 8 | | 33 M/_IO
DB6 9 | | 32 AD6
DB5 10 | INS8154 | 31 AD5
DB4 11 | | 30 AD4
DB3 12 | | 29 AD3
DB2 13 | | 28 AD2
DB1 14 | | 27 AD1
DB0 15 | | 26 AD0
PA7 16 | | 25 INTR
PA6 17 | | 24 PA0
PA5 18 | | 23 PA1
PA4 19 | | 22 PA2
GND 20 |_____________| 21 PA3
***************************************************************************/ ***************************************************************************/
#define INS8154 DEVICE_GET_INFO_NAME(ins8154) #ifndef __INS8154_H__
#define __INS8154_H__
#include "devcb.h"
/*************************************************************************** /***************************************************************************
TYPE DEFINITIONS TYPE DEFINITIONS
***************************************************************************/ ***************************************************************************/
typedef void (*ins8154_irq_func)(running_device *device, int state);
#define INS8154_IRQ(name) void name(running_device *device, int state )
/******************* Interface **********************************************/
typedef struct _ins8154_interface ins8154_interface; typedef struct _ins8154_interface ins8154_interface;
struct _ins8154_interface struct _ins8154_interface
{ {
read8_device_func in_a_func; devcb_read8 in_a_func;
read8_device_func in_b_func; devcb_write8 out_a_func;
write8_device_func out_a_func; devcb_read8 in_b_func;
write8_device_func out_b_func; devcb_write8 out_b_func;
ins8154_irq_func irq_func; devcb_write_line out_irq_func;
}; };
/***************************************************************************
FUNCTION PROTOTYPES
***************************************************************************/
DEVICE_GET_INFO( ins8154 ); DEVICE_GET_INFO( ins8154 );
/******************* Standard 8-bit CPU interfaces, D0-D7 *******************/
READ8_DEVICE_HANDLER( ins8154_r ); READ8_DEVICE_HANDLER( ins8154_r );
WRITE8_DEVICE_HANDLER( ins8154_w ); WRITE8_DEVICE_HANDLER( ins8154_w );
/******************* 8-bit A/B port interfaces ******************************/
WRITE8_DEVICE_HANDLER( ins8154_porta_w ); WRITE8_DEVICE_HANDLER( ins8154_porta_w );
WRITE8_DEVICE_HANDLER( ins8154_portb_w ); WRITE8_DEVICE_HANDLER( ins8154_portb_w );
/*************************************************************************** /***************************************************************************
DEVICE CONFIGURATION MACROS DEVICE CONFIGURATION MACROS
***************************************************************************/ ***************************************************************************/
#define INS8154 DEVICE_GET_INFO_NAME(ins8154)
#define MDRV_INS8154_ADD(_tag, _intrf) \ #define MDRV_INS8154_ADD(_tag, _intrf) \
MDRV_DEVICE_ADD(_tag, INS8154, 0) \ MDRV_DEVICE_ADD(_tag, INS8154, 0) \
MDRV_DEVICE_CONFIG(_intrf) MDRV_DEVICE_CONFIG(_intrf)
#endif /* INS8154_H_ */
#endif /* __INS8154_H__ */