mame/src/emu/machine/at28c16.c
Aaron Giles 9b4e46fad5 Changed DEVICE_START functions to return an error code. Currently this
is either DEVICE_START_OK or DEVICE_START_MISSING_DEPENDENCY. The latter
should be returned by a device if there is another device it depends on
which hasn't been started yet. Added new flag in the device interface to
indicate whether a device has been started.

Changed laserdisc interface to explicitly specify the screen and sound
devices it should route to. Drivers no longer have to manually call
laserdisc_vsync(). Instead, the laserdisc code connects up to the routed
screen device and works based on that screen's VBLANK timing. Removed
all existing calls to laserdisc_vsync().

Changed laserdisc behavior so that it completes the previous video read
and initiates the next read at the end of VBLANK instead of the beginning.
This gives player logic time during VBLANK to alter the slider position
prior to fetching the next frame.

Added new laserdisc callback for vsync begin and changed the update
callback to be called at the end of VBLANK. Also added functions to set
the slider speed, advance the slider, and directly control the video/
audio squelch. In addition, there is a new status function to get the
slider position in general terms.

Added parameter to the VBLANK callbacks supported in emu/video.c. Updated
all callers to provide a callback value.

Fixed bug that would cause watchpoints to trigger if you had a memory
window open to the watchpoint address.

Further updates to the PR-8210 ROM simulation. Still not quite there but
the system is much better understood now. Added layout to the PR-8210
which displays the state of the front-panel LEDs.
2008-09-09 16:10:11 +00:00

250 lines
6.4 KiB
C

/*
* ATMEL AT28C16
*
* 16K ( 2K x 8 ) Parallel EEPROM
*
*/
#include "driver.h"
#include "machine/at28c16.h"
#define SIZE_DATA ( 0x800 )
#define SIZE_ID ( 0x020 )
#define OFFSET_ID ( SIZE_DATA - SIZE_ID )
typedef struct
{
UINT8 *data;
UINT8 *id;
UINT8 *default_data;
UINT8 *default_id;
int last_write;
int a9_12v;
int oe_12v;
emu_timer *write_timer;
} at28c16_state;
static TIMER_CALLBACK( write_finished )
{
at28c16_state *c = (at28c16_state *) ptr;
c->last_write = -1;
}
/*-------------------------------------------------
get_safe_token - makes sure that the passed
in device is, in fact, an AT28C16
-------------------------------------------------*/
INLINE at28c16_state *get_safe_token(const device_config *device)
{
assert(device != NULL);
assert(device->token != NULL);
assert(device->type == AT28C16);
return (at28c16_state *)device->token;
}
WRITE8_DEVICE_HANDLER( at28c16_w )
{
at28c16_state *c = get_safe_token(device);
if( c->last_write >= 0 )
{
// logerror( "%08x: at28c16_write( %d, %04x, %02x ) busy\n", activecpu_get_pc(), chip, offset, data );
}
else if( c->oe_12v )
{
// logerror( "%08x: at28c16_write( %d, %04x, %02x ) erase\n", activecpu_get_pc(), chip, offset, data );
memset( c->data, 0xff, SIZE_DATA );
memset( c->id, 0xff, SIZE_ID );
c->last_write = 0xff;
timer_adjust_oneshot( c->write_timer, ATTOTIME_IN_USEC( 200 ), 0 );
}
else if( offset >= OFFSET_ID && c->a9_12v )
{
// logerror( "%08x: at28c16_write( %d, %04x, %02x ) id\n", activecpu_get_pc(), chip, offset, data );
c->id[ offset - OFFSET_ID ] = data;
c->last_write = data;
timer_adjust_oneshot( c->write_timer, ATTOTIME_IN_USEC( 200 ), 0 );
}
else
{
// logerror( "%08x: at28c16_write( %d, %04x, %02x ) data\n", activecpu_get_pc(), chip, offset, data );
c->data[ offset ] = data;
c->last_write = data;
timer_adjust_oneshot( c->write_timer, ATTOTIME_IN_USEC( 200 ), 0 );
}
}
READ8_DEVICE_HANDLER( at28c16_r )
{
at28c16_state *c = get_safe_token(device);
if( c->last_write >= 0 )
{
// logerror( "at28c16_read( %04x ) write status\n", offset );
return c->last_write ^ 0x80;
}
else if( offset >= OFFSET_ID && c->a9_12v )
{
// logerror( "at28c16_read( %04x ) id\n", offset );
return c->id[ offset - OFFSET_ID ];
}
else
{
// logerror( "%08x: at28c16_read( %d, %04x ) %02x data\n", activecpu_get_pc(), chip, offset, c->data[ offset ] );
return c->data[ offset ];
}
}
void at28c16_a9_12v( const device_config *device, int a9_12v )
{
at28c16_state *c = get_safe_token(device);
c->a9_12v = a9_12v;
}
void at28c16_oe_12v( const device_config *device, int oe_12v )
{
at28c16_state *c = get_safe_token(device);
c->oe_12v = oe_12v;
}
/*-------------------------------------------------
device start callback
-------------------------------------------------*/
static DEVICE_START(at28c16)
{
at28c16_state *c = get_safe_token(device);
const at28c16_config *config;
char unique_tag[50];
/* validate some basic stuff */
assert(device != NULL);
// assert(device->static_config != NULL);
assert(device->inline_config == NULL);
assert(device->machine != NULL);
assert(device->machine->config != NULL);
c->data = auto_malloc( SIZE_DATA );
c->id = auto_malloc( SIZE_ID );
c->a9_12v = 0;
c->oe_12v = 0;
c->last_write = -1;
c->write_timer = timer_alloc( write_finished, c );
config = device->static_config;
if( config != NULL && config->data != NULL )
{
c->default_data = memory_region( device->machine, config->data );
}
if( config != NULL && config->id != NULL )
{
c->default_id = memory_region( device->machine, config->id );
}
/* create the name for save states */
assert( strlen( device->tag ) < 30 );
state_save_combine_module_and_tag( unique_tag, "at28c16", device->tag );
state_save_register_item_pointer( unique_tag, 0, c->data, SIZE_DATA );
state_save_register_item_pointer( unique_tag, 0, c->id, SIZE_ID );
state_save_register_item( unique_tag, 0, c->a9_12v );
state_save_register_item( unique_tag, 0, c->oe_12v );
state_save_register_item( unique_tag, 0, c->last_write );
return DEVICE_START_OK;
}
/*-------------------------------------------------
device reset callback
-------------------------------------------------*/
static DEVICE_RESET(at28c16)
{
}
static DEVICE_NVRAM(at28c16)
{
at28c16_state *c = get_safe_token(device);
if( read_or_write )
{
mame_fwrite( file, c->data, SIZE_DATA );
mame_fwrite( file, c->id, SIZE_ID );
}
else
{
if( file )
{
mame_fread( file, c->data, SIZE_DATA );
mame_fread( file, c->id, SIZE_ID );
}
else
{
if( c->default_data != NULL )
{
memcpy( c->data, c->default_data, SIZE_DATA );
}
else
{
memset( c->data, 0xff, SIZE_DATA );
}
if( c->default_id != NULL )
{
memcpy( c->id, c->default_id, SIZE_ID );
}
else
{
memset( c->id, 0xff, SIZE_ID );
}
}
}
}
/*-------------------------------------------------
device set info callback
-------------------------------------------------*/
static DEVICE_SET_INFO(at28c16)
{
switch (state)
{
/* no parameters to set */
}
}
/*-------------------------------------------------
device get info callback
-------------------------------------------------*/
DEVICE_GET_INFO(at28c16)
{
switch (state)
{
/* --- the following bits of info are returned as 64-bit signed integers --- */
case DEVINFO_INT_TOKEN_BYTES: info->i = sizeof(at28c16_state); break;
case DEVINFO_INT_INLINE_CONFIG_BYTES: info->i = 0; break; // sizeof(at28c16_config)
case DEVINFO_INT_CLASS: info->i = DEVICE_CLASS_PERIPHERAL; break;
/* --- 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(at28c16); break;
case DEVINFO_FCT_START: info->start = DEVICE_START_NAME(at28c16); break;
case DEVINFO_FCT_STOP: /* nothing */ break;
case DEVINFO_FCT_RESET: info->reset = DEVICE_RESET_NAME(at28c16); break;
case DEVINFO_FCT_NVRAM: info->nvram = DEVICE_NVRAM_NAME(at28c16); break;
/* --- the following bits of info are returned as NULL-terminated strings --- */
case DEVINFO_STR_NAME: info->s = "AT28C16"; break;
case DEVINFO_STR_FAMILY: info->s = "EEPROM"; break;
case DEVINFO_STR_VERSION: info->s = "1.0"; break;
case DEVINFO_STR_SOURCE_FILE: info->s = __FILE__; break;
case DEVINFO_STR_CREDITS: info->s = "Copyright Nicola Salmoria and the MAME Team"; break;
}
}