mirror of
https://github.com/holub/mame
synced 2025-04-23 17:00:53 +03:00
ins8154: Updated to use devcb calls, cleaned up
This commit is contained in:
parent
b7927daaff
commit
4c15a5dfd7
@ -1,22 +1,23 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* machine/ins8154.h
|
||||
*
|
||||
* INS8154 N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O)
|
||||
*
|
||||
* Written by Dirk Best, January 2008
|
||||
*
|
||||
* TODO: Strobed modes
|
||||
*
|
||||
****************************************************************************/
|
||||
/***************************************************************************
|
||||
|
||||
National Semiconductor INS8154
|
||||
|
||||
N-Channel 128-by-8 Bit RAM Input/Output (RAM I/O)
|
||||
|
||||
|
||||
TODO: Strobed modes
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ins8154.h"
|
||||
|
||||
|
||||
#define VERBOSE 1
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
/***************************************************************************
|
||||
CONSTANTS
|
||||
***************************************************************************/
|
||||
|
||||
#define VERBOSE 1
|
||||
|
||||
/* Mode Definition Register */
|
||||
enum
|
||||
@ -27,11 +28,22 @@ enum
|
||||
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_b; /* Input Latch Port B */
|
||||
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 */
|
||||
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);
|
||||
return (ins8154_state *)device->token;
|
||||
}
|
||||
|
||||
|
||||
static DEVICE_RESET( ins8154 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
IMPLEMENTATION
|
||||
***************************************************************************/
|
||||
|
||||
READ8_DEVICE_HANDLER( ins8154_r )
|
||||
{
|
||||
ins8154_t *i = (ins8154_t *)device->token;
|
||||
ins8154_state *ins8154 = get_safe_token(device);
|
||||
UINT8 val = 0xff;
|
||||
|
||||
if (offset > 0x24)
|
||||
{
|
||||
logerror("INS8154 (%08x): Read from unknown offset %02x!\n",
|
||||
cpu_get_pc( device->machine->firstcpu ), offset);
|
||||
if (VERBOSE)
|
||||
logerror("%s: INS8154 '%s' Read from invalid offset %02x!\n", cpuexec_describe_context(device->machine), device->tag.cstr(), offset);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x20:
|
||||
if (i->intf->in_a_func)
|
||||
val = i->intf->in_a_func(device, 0);
|
||||
i->in_a = val;
|
||||
if (ins8154->in_a_func.read != NULL)
|
||||
val = devcb_call_read8(&ins8154->in_a_func, 0);
|
||||
ins8154->in_a = val;
|
||||
break;
|
||||
|
||||
case 0x21:
|
||||
if (i->intf->in_b_func)
|
||||
val = i->intf->in_b_func(device, 0);
|
||||
i->in_b = val;
|
||||
if (ins8154->in_b_func.read != NULL)
|
||||
val = devcb_call_read8(&ins8154->in_b_func, 0);
|
||||
ins8154->in_b = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (offset < 0x08)
|
||||
{
|
||||
if (i->intf->in_a_func)
|
||||
val = (i->intf->in_a_func(device, 0) << (8 - offset)) & 0x80;
|
||||
i->in_a = val;
|
||||
if (ins8154->in_a_func.read != NULL)
|
||||
val = (devcb_call_read8(&ins8154->in_a_func, 0) << (8 - offset)) & 0x80;
|
||||
ins8154->in_a = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i->intf->in_a_func)
|
||||
val = (i->intf->in_a_func(device, 0) << (8 - (offset >> 4))) & 0x80;
|
||||
i->in_b = val;
|
||||
if (ins8154->in_b_func.read != NULL)
|
||||
val = (devcb_call_read8(&ins8154->in_b_func, 0) << (8 - (offset >> 4))) & 0x80;
|
||||
ins8154->in_b = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -124,48 +119,34 @@ READ8_DEVICE_HANDLER( ins8154_r )
|
||||
|
||||
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 */
|
||||
if (i->odra)
|
||||
{
|
||||
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 ) );
|
||||
}
|
||||
if (ins8154->odra)
|
||||
devcb_call_write8(&ins8154->out_a_func, 0, (data & ins8154->odra) | (ins8154->odra ^ 0xff));
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
if (i->odrb)
|
||||
{
|
||||
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 ) );
|
||||
}
|
||||
if (ins8154->odrb)
|
||||
devcb_call_write8(&ins8154->out_b_func, 0, (data & ins8154->odrb) | (ins8154->odrb ^ 0xff));
|
||||
}
|
||||
|
||||
|
||||
WRITE8_DEVICE_HANDLER( ins8154_w )
|
||||
{
|
||||
ins8154_t *i = (ins8154_t *)device->token;
|
||||
ins8154_state *ins8154 = get_safe_token(device);
|
||||
|
||||
if (offset > 0x24)
|
||||
{
|
||||
logerror("INS8154 (%04x): Write %02x to invalid offset %02x!\n",
|
||||
cpu_get_pc( device->machine->firstcpu ), data, offset);
|
||||
if (VERBOSE)
|
||||
logerror("%s: INS8154 '%s' Write %02x to invalid offset %02x!\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data, offset);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -180,21 +161,24 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
LOG(("INS8154 (%04x): ODR for port A set to %02x\n",
|
||||
cpu_get_pc( device->machine->firstcpu ), data));
|
||||
i->odra = data;
|
||||
if (VERBOSE)
|
||||
logerror("%s: INS8154 '%s' ODRA set to %02x\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data);
|
||||
|
||||
ins8154->odra = data;
|
||||
break;
|
||||
|
||||
case 0x23:
|
||||
LOG(("INS8154 (%04x): ODR for port B set to %02x\n",
|
||||
cpu_get_pc( device->machine->firstcpu ), data));
|
||||
i->odrb = data;
|
||||
if (VERBOSE)
|
||||
logerror("%s: INS8154 '%s' ODRB set to %02x\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data);
|
||||
|
||||
ins8154->odrb = data;
|
||||
break;
|
||||
|
||||
case 0x24:
|
||||
LOG(("INS8154 (%04x): MDR set to %02x\n",
|
||||
cpu_get_pc( device->machine->firstcpu ), data));
|
||||
i->mdr = data;
|
||||
if (VERBOSE)
|
||||
logerror("%s: INS8154 '%s' MDR set to %02x\n", cpuexec_describe_context(device->machine), device->tag.cstr(), data);
|
||||
|
||||
ins8154->mdr = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -203,11 +187,11 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
|
||||
/* Set bit */
|
||||
if (offset < 0x08)
|
||||
{
|
||||
ins8154_porta_w(device, 0, i->out_a |= offset & 0x07);
|
||||
ins8154_porta_w(device, 0, ins8154->out_a |= offset & 0x07);
|
||||
}
|
||||
else
|
||||
{
|
||||
ins8154_portb_w(device, 0, i->out_b |= (offset >> 4) & 0x07);
|
||||
ins8154_portb_w(device, 0, ins8154->out_b |= (offset >> 4) & 0x07);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -215,11 +199,11 @@ WRITE8_DEVICE_HANDLER( ins8154_w )
|
||||
/* Clear bit */
|
||||
if (offset < 0x08)
|
||||
{
|
||||
ins8154_porta_w(device, 0, i->out_a & ~(offset & 0x07));
|
||||
ins8154_porta_w(device, 0, ins8154->out_a & ~(offset & 0x07));
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* --- 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;
|
||||
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 pointers to data or functions --- */
|
||||
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(ins8154); break;
|
||||
case DEVINFO_FCT_STOP: /* Nothing */ break;
|
||||
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(ins8154); break;
|
||||
/* validate some basic stuff */
|
||||
assert(intf != NULL);
|
||||
|
||||
/* --- the following bits of info are returned as NULL-terminated strings --- */
|
||||
case DEVINFO_STR_NAME: strcpy(info->s, "National Semiconductor INS8154"); break;
|
||||
case DEVINFO_STR_FAMILY: strcpy(info->s, "INS8154"); 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 MESS Team"); break;
|
||||
}
|
||||
/* resolve callbacks */
|
||||
devcb_resolve_read8(&ins8154->in_a_func, &intf->in_a_func, device);
|
||||
devcb_resolve_write8(&ins8154->out_a_func, &intf->out_a_func, device);
|
||||
devcb_resolve_read8(&ins8154->in_b_func, &intf->in_b_func, device);
|
||||
devcb_resolve_write8(&ins8154->out_b_func, &intf->out_b_func, device);
|
||||
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"
|
||||
|
@ -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
|
||||
***************************************************************************/
|
||||
|
||||
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;
|
||||
|
||||
struct _ins8154_interface
|
||||
{
|
||||
read8_device_func in_a_func;
|
||||
read8_device_func in_b_func;
|
||||
write8_device_func out_a_func;
|
||||
write8_device_func out_b_func;
|
||||
ins8154_irq_func irq_func;
|
||||
devcb_read8 in_a_func;
|
||||
devcb_write8 out_a_func;
|
||||
devcb_read8 in_b_func;
|
||||
devcb_write8 out_b_func;
|
||||
devcb_write_line out_irq_func;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
DEVICE_GET_INFO( ins8154 );
|
||||
|
||||
|
||||
/******************* Standard 8-bit CPU interfaces, D0-D7 *******************/
|
||||
|
||||
READ8_DEVICE_HANDLER( ins8154_r );
|
||||
WRITE8_DEVICE_HANDLER( ins8154_w );
|
||||
|
||||
|
||||
/******************* 8-bit A/B port interfaces ******************************/
|
||||
|
||||
WRITE8_DEVICE_HANDLER( ins8154_porta_w );
|
||||
WRITE8_DEVICE_HANDLER( ins8154_portb_w );
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define INS8154 DEVICE_GET_INFO_NAME(ins8154)
|
||||
|
||||
#define MDRV_INS8154_ADD(_tag, _intrf) \
|
||||
MDRV_DEVICE_ADD(_tag, INS8154, 0) \
|
||||
MDRV_DEVICE_CONFIG(_intrf)
|
||||
|
||||
#endif /* INS8154_H_ */
|
||||
|
||||
#endif /* __INS8154_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user