Converted ADC083x converters to be MAME devices

This commit is contained in:
Fabio Priuli 2009-06-01 10:44:07 +00:00
parent b5c8272ad8
commit 1bcf4e7b9e
5 changed files with 496 additions and 357 deletions

View File

@ -1,192 +1,168 @@
/*
* ADC0831/ADC0832/ADC0834/ADC0838
*
* 8-Bit Serial I/O A/D Converters with Muliplexer Options
*
*/
/***************************************************************************
National Semiconductor ADC0831 / ADC0832 / ADC0834 / ADC0838
8-Bit serial I/O A/D Converters with Muliplexer Options
2009-06 Converted to be a device
***************************************************************************/
#include <stdarg.h>
#include "driver.h"
#include "machine/adc083x.h"
#include "adc083x.h"
#define VERBOSE_LEVEL ( 0 )
#define VERBOSE_LEVEL (0)
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level, const char *s_fmt, ... )
{
if( VERBOSE_LEVEL >= n_level )
if (VERBOSE_LEVEL >= n_level)
{
va_list v;
char buf[ 32768 ];
va_start( v, s_fmt );
vsprintf( buf, s_fmt, v );
va_end( v );
logerror( "%s: %s", cpuexec_describe_context(machine), buf );
va_start(v, s_fmt);
vsprintf(buf, s_fmt, v);
va_end(v);
logerror("%s: %s", cpuexec_describe_context(machine), buf);
}
}
struct adc083x_chip
/***************************************************************************
PARAMETERS
***************************************************************************/
enum
{
STATE_IDLE,
STATE_WAIT_FOR_START,
STATE_SHIFT_MUX,
STATE_MUX_SETTLE,
STATE_OUTPUT_MSB_FIRST,
STATE_WAIT_FOR_SE,
STATE_OUTPUT_LSB_FIRST,
STATE_FINISHED
};
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef struct _adc083x_state adc083x_state;
struct _adc083x_state
{
int type;
double (*input_callback)(running_machine *machine, int input);
INT32 CS;
INT32 CLK;
INT32 DI;
INT32 SE;
INT32 SARS;
INT32 DO;
INT32 SGL;
INT32 ODD;
INT32 SEL1;
INT32 SEL0;
devcb_resolved_read8 input_callback_r;
INT32 cs;
INT32 clk;
INT32 di;
INT32 se;
INT32 sars;
INT32 _do;
INT32 sgl;
INT32 odd;
INT32 sel1;
INT32 sel0;
INT32 state;
INT32 bit;
INT32 output;
INT32 mux_bits;
};
#define STATE_IDLE ( 0 )
#define STATE_WAIT_FOR_START ( 1 )
#define STATE_SHIFT_MUX ( 2 )
#define STATE_MUX_SETTLE ( 3 )
#define STATE_OUTPUT_MSB_FIRST ( 4 )
#define STATE_WAIT_FOR_SE ( 5 )
#define STATE_OUTPUT_LSB_FIRST ( 6 )
#define STATE_FINISHED ( 7 )
static struct adc083x_chip adc083x[ MAX_ADC083X_CHIPS ];
void adc083x_init( running_machine *machine, int chip, int type, double (*input_callback)(running_machine *machine, int input) )
/***************************************************************************
INLINE FUNCTIONS
***************************************************************************/
INLINE adc083x_state *get_safe_token(const device_config *device)
{
struct adc083x_chip *c;
if( chip >= MAX_ADC083X_CHIPS )
{
verboselog( machine, 0, "adc083x_init( %d ) chip out of range\n", chip );
return;
}
c = &adc083x[ chip ];
c->type = type;
c->input_callback = input_callback;
c->CS = 0;
c->CLK = 0;
c->DI = 0;
c->SE = 0;
if( c->type == ADC0834 || c->type == ADC0838 )
{
c->SARS = 1;
}
else
{
c->SARS = 0;
}
c->DO = 1;
c->SGL = 0;
c->ODD = 0;
c->SEL1 = 0;
c->SEL0 = 0;
c->state = STATE_IDLE;
c->bit = 0;
c->output = 0;
switch( c->type )
{
case ADC0831:
c->mux_bits = 0;
break;
case ADC0832:
c->mux_bits = 2;
break;
case ADC0834:
c->mux_bits = 3;
break;
case ADC0838:
c->mux_bits = 4;
break;
}
state_save_register_item( machine, "adc083x", NULL, chip, c->CS );
state_save_register_item( machine, "adc083x", NULL, chip, c->CLK );
state_save_register_item( machine, "adc083x", NULL, chip, c->DI );
state_save_register_item( machine, "adc083x", NULL, chip, c->SE );
state_save_register_item( machine, "adc083x", NULL, chip, c->SARS );
state_save_register_item( machine, "adc083x", NULL, chip, c->DO );
state_save_register_item( machine, "adc083x", NULL, chip, c->SGL );
state_save_register_item( machine, "adc083x", NULL, chip, c->ODD );
state_save_register_item( machine, "adc083x", NULL, chip, c->SEL1 );
state_save_register_item( machine, "adc083x", NULL, chip, c->SEL0 );
state_save_register_item( machine, "adc083x", NULL, chip, c->state );
state_save_register_item( machine, "adc083x", NULL, chip, c->bit );
state_save_register_item( machine, "adc083x", NULL, chip, c->output );
assert(device != NULL);
assert(device->token != NULL);
assert((device->type == ADC083X));
return (adc083x_state *)device->token;
}
void adc083x_cs_write( running_machine *machine, int chip, int cs )
INLINE const adc083x_interface *get_interface(const device_config *device)
{
struct adc083x_chip *c;
assert(device != NULL);
assert((device->type == ADC083X));
return (const adc083x_interface *) device->static_config;
}
if( chip >= MAX_ADC083X_CHIPS )
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
/*-------------------------------------------------
adc083x_cs_write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( adc083x_cs_write )
{
adc083x_state *adc083x = get_safe_token(device);
if (adc083x->cs != data)
{
verboselog( machine, 0, "adc083x_cs_write( %d ) chip out of range\n", chip );
return;
verboselog(device->machine, 2, "adc083x_cs_write( %s, %d )\n", device->tag, data);
}
c = &adc083x[ chip ];
if( c->CS != cs )
if (adc083x->cs == 0 && data != 0)
{
verboselog( machine, 2, "adc083x_cs_write( %d, %d )\n", chip, cs );
}
if( c->CS == 0 && cs != 0 )
{
c->state = STATE_IDLE;
if( c->type == ADC0834 || c->type == ADC0838 )
adc083x->state = STATE_IDLE;
if (adc083x->type == ADC0834 || adc083x->type == ADC0838)
{
c->SARS = 1;
adc083x->sars = 1;
}
c->DO = 1;
adc083x->_do = 1;
}
if( c->CS != 0 && cs == 0 )
if (adc083x->cs != 0 && data == 0)
{
if( c->type == ADC0831 )
if (adc083x->type == ADC0831)
{
c->state = STATE_MUX_SETTLE;
adc083x->state = STATE_MUX_SETTLE;
}
else
{
c->state = STATE_WAIT_FOR_START;
adc083x->state = STATE_WAIT_FOR_START;
}
if( c->type == ADC0834 || c->type == ADC0838 )
if (adc083x->type == ADC0834 || adc083x->type == ADC0838)
{
c->SARS = 1;
adc083x->sars = 1;
}
c->DO = 1;
adc083x->_do = 1;
}
c->CS = cs;
adc083x->cs = data;
}
static int adc083x_conversion( running_machine *machine, int chip )
/*-------------------------------------------------
adc083x_conversion
-------------------------------------------------*/
static UINT8 adc083x_conversion( const device_config *device )
{
struct adc083x_chip *c = &adc083x[ chip ];
adc083x_state *adc083x = get_safe_token(device);
int result;
int positive_channel = ADC083X_AGND;
int negative_channel = ADC083X_AGND;
double positive = 0;
double negative = 0;
double gnd = c->input_callback( machine, ADC083X_AGND );
double vref = c->input_callback( machine, ADC083X_VREF );
double vref = (double)(5 * devcb_call_read8(&adc083x->input_callback_r, ADC083X_VREF)) / 255.0;
UINT8 gnd = devcb_call_read8(&adc083x->input_callback_r, ADC083X_AGND);
switch( c->type )
switch (adc083x->type)
{
case ADC0831:
positive_channel = ADC083X_CH0;
negative_channel = ADC083X_CH1;
break;
case ADC0832:
positive_channel = ADC083X_CH0 + c->ODD;
if( c->SGL == 0 )
positive_channel = ADC083X_CH0 + adc083x->odd;
if (adc083x->sgl == 0)
{
negative_channel = positive_channel ^ 1;
}
@ -196,8 +172,8 @@ static int adc083x_conversion( running_machine *machine, int chip )
}
break;
case ADC0834:
positive_channel = ADC083X_CH0 + c->ODD + ( c->SEL1 * 2 );
if( c->SGL == 0 )
positive_channel = ADC083X_CH0 + adc083x->odd + (adc083x->sel1 * 2);
if (adc083x->sgl == 0)
{
negative_channel = positive_channel ^ 1;
}
@ -207,8 +183,8 @@ static int adc083x_conversion( running_machine *machine, int chip )
}
break;
case ADC0838:
positive_channel = ADC083X_CH0 + c->ODD + ( c->SEL0 * 2 ) + ( c->SEL1 * 4 );
if( c->SGL == 0 )
positive_channel = ADC083X_CH0 + adc083x->odd + (adc083x->sel0 * 2) + (adc083x->sel1 * 4);
if (adc083x->sgl == 0)
{
negative_channel = positive_channel ^ 1;
}
@ -219,21 +195,22 @@ static int adc083x_conversion( running_machine *machine, int chip )
break;
}
if( positive_channel != ADC083X_AGND )
if (positive_channel != ADC083X_AGND)
{
positive = c->input_callback( machine, positive_channel ) - gnd;
positive = (double)(5 * (devcb_call_read8(&adc083x->input_callback_r, positive_channel) - gnd)) / 255.0;
}
if( negative_channel != ADC083X_AGND )
if (negative_channel != ADC083X_AGND)
{
negative = c->input_callback( machine, negative_channel ) - gnd;
negative = (double)(5 * (devcb_call_read8(&adc083x->input_callback_r, negative_channel) - gnd)) / 255.0;
}
result = (int)( ( ( positive - negative ) * 255 ) / vref );
if( result < 0 )
result = (int)(((positive - negative) * 255) / vref);
logerror("%d", result);
if (result < 0)
{
result = 0;
}
else if( result > 255 )
else if (result > 255)
{
result = 255;
}
@ -241,218 +218,300 @@ static int adc083x_conversion( running_machine *machine, int chip )
return result;
}
void adc083x_clk_write( running_machine *machine, int chip, int clk )
/*-------------------------------------------------
adc083x_clk_write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( adc083x_clk_write )
{
struct adc083x_chip *c;
adc083x_state *adc083x = get_safe_token(device);
if( chip >= MAX_ADC083X_CHIPS )
if (adc083x->clk != data)
{
verboselog( machine, 0, "adc083x_clk_write( %d ) chip out of range\n", chip );
return;
verboselog(device->machine, 2, "adc083x_clk_write( %s, %d )\n", device->tag, data);
}
c = &adc083x[ chip ];
if( c->CLK != clk )
if (adc083x->cs == 0)
{
verboselog( machine, 2, "adc083x_clk_write( %d, %d )\n", chip, clk );
}
if( c->CS == 0 )
{
if( c->CLK == 0 && clk != 0 )
if (adc083x->clk == 0 && data != 0)
{
switch( c->state )
switch (adc083x->state)
{
case STATE_WAIT_FOR_START:
if( c->DI != 0 )
if (adc083x->di != 0)
{
verboselog( machine, 1, "adc083x %d got start bit\n", chip );
c->state = STATE_SHIFT_MUX;
c->SARS = 0;
c->SGL = 0;
c->ODD = 0;
c->SEL1 = 0;
c->SEL0 = 0;
c->bit = 0;
verboselog(device->machine, 1, "adc083x %s got start bit\n", device->tag);
adc083x->state = STATE_SHIFT_MUX;
adc083x->sars = 0;
adc083x->sgl = 0;
adc083x->odd = 0;
adc083x->sel1 = 0;
adc083x->sel0 = 0;
adc083x->bit = 0;
}
else
{
verboselog( machine, 1, "adc083x %d not start bit\n", chip );
verboselog(device->machine, 1, "adc083x %s not start bit\n", device->tag);
}
break;
case STATE_SHIFT_MUX:
switch( c->bit )
switch (adc083x->bit)
{
case 0:
if( c->DI != 0 )
if (adc083x->di != 0)
{
c->SGL = 1;
adc083x->sgl = 1;
}
verboselog( machine, 1, "adc083x %d SGL <- %d\n", chip, c->SGL );
verboselog(device->machine, 1, "adc083x %s sgl <- %d\n", device->tag, adc083x->sgl);
break;
case 1:
if( c->DI != 0 )
if (adc083x->di != 0)
{
c->ODD = 1;
adc083x->odd = 1;
}
verboselog( machine, 1, "adc083x %d ODD <- %d\n", chip, c->ODD );
verboselog(device->machine, 1, "adc083x %s odd <- %d\n", device->tag, adc083x->odd);
break;
case 2:
if( c->DI != 0 )
if (adc083x->di != 0)
{
c->SEL1 = 1;
adc083x->sel1 = 1;
}
verboselog( machine, 1, "adc083x %d SEL1 <- %d\n", chip, c->SEL1 );
verboselog(device->machine, 1, "adc083x %s sel1 <- %d\n", device->tag, adc083x->sel1);
break;
case 3:
if( c->DI != 0 )
if (adc083x->di != 0)
{
c->SEL0 = 1;
adc083x->sel0 = 1;
}
verboselog( machine, 1, "adc083x %d SEL0 <- %d\n", chip, c->SEL0 );
verboselog(device->machine, 1, "adc083x %s sel0 <- %d\n", device->tag, adc083x->sel0);
break;
}
c->bit++;
if( c->bit == c->mux_bits )
adc083x->bit++;
if (adc083x->bit == adc083x->mux_bits)
{
c->state = STATE_MUX_SETTLE;
adc083x->state = STATE_MUX_SETTLE;
}
break;
case STATE_WAIT_FOR_SE:
c->SARS = 0;
if( c->type == ADC0838 && c->SE != 0 )
adc083x->sars = 0;
if (adc083x->type == ADC0838 && adc083x->se != 0)
{
verboselog( machine, 1, "adc083x %d not SE\n", chip );
verboselog(device->machine, 1, "adc083x %s not se\n", device->tag);
}
else
{
verboselog( machine, 1, "adc083x %d got SE\n", chip );
c->state = STATE_OUTPUT_LSB_FIRST;
c->bit = 1;
verboselog(device->machine, 1, "adc083x %s got se\n", device->tag);
adc083x->state = STATE_OUTPUT_LSB_FIRST;
adc083x->bit = 1;
}
break;
}
}
if( c->CLK != 0 && clk == 0 )
if (adc083x->clk != 0 && data == 0)
{
switch( c->state )
switch (adc083x->state)
{
case STATE_MUX_SETTLE:
verboselog( machine, 1, "adc083x %d mux settle\n", chip );
c->output = adc083x_conversion( machine, chip );
c->state = STATE_OUTPUT_MSB_FIRST;
c->bit = 7;
if( c->type == ADC0834 || c->type == ADC0838 )
verboselog(device->machine, 1, "adc083x %s mux settle\n", device->tag);
adc083x->output = adc083x_conversion(device);
adc083x->state = STATE_OUTPUT_MSB_FIRST;
adc083x->bit = 7;
if (adc083x->type == ADC0834 || adc083x->type == ADC0838)
{
c->SARS = 1;
adc083x->sars = 1;
}
c->DO = 0;
adc083x->_do = 0;
break;
case STATE_OUTPUT_MSB_FIRST:
c->DO = ( c->output >> c->bit ) & 1;
verboselog( machine, 1, "adc083x %d msb %d -> %d\n", chip, c->bit, c->DO );
c->bit--;
if( c->bit < 0 )
adc083x->_do = (adc083x->output >> adc083x->bit) & 1;
verboselog(device->machine, 1, "adc083x %s msb %d -> %d\n", device->tag, adc083x->bit, adc083x->_do);
adc083x->bit--;
if (adc083x->bit < 0)
{
if( c->type == ADC0831 )
if (adc083x->type == ADC0831)
{
c->state = STATE_FINISHED;
adc083x->state = STATE_FINISHED;
}
else
{
c->state = STATE_WAIT_FOR_SE;
adc083x->state = STATE_WAIT_FOR_SE;
}
}
break;
case STATE_OUTPUT_LSB_FIRST:
c->DO = ( c->output >> c->bit ) & 1;
verboselog( machine, 1, "adc083x %d lsb %d -> %d\n", chip, c->bit, c->DO );
c->bit++;
if( c->bit == 8 )
adc083x->_do = (adc083x->output >> adc083x->bit) & 1;
verboselog(device->machine, 1, "adc083x %s lsb %d -> %d\n", device->tag, adc083x->bit, adc083x->_do);
adc083x->bit++;
if (adc083x->bit == 8)
{
c->state = STATE_FINISHED;
adc083x->state = STATE_FINISHED;
}
break;
case STATE_FINISHED:
c->state = STATE_IDLE;
c->DO = 0;
adc083x->state = STATE_IDLE;
adc083x->_do = 0;
break;
}
}
}
c->CLK = clk;
adc083x->clk = data;
}
void adc083x_di_write( running_machine *machine, int chip, int di )
/*-------------------------------------------------
adc083x_di_write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( adc083x_di_write )
{
struct adc083x_chip *c;
adc083x_state *adc083x = get_safe_token(device);
if( chip >= MAX_ADC083X_CHIPS )
if (adc083x->di != data)
{
verboselog( machine, 0, "adc083x_di_write( %d ) chip out of range\n", chip );
return;
verboselog(device->machine, 2, "adc083x_di_write( %s, %d )\n", device->tag, data);
}
c = &adc083x[ chip ];
if( c->DI != di )
{
verboselog( machine, 2, "adc083x_di_write( %d, %d )\n", chip, di );
}
c->DI = di;
adc083x->di = data;
}
void adc083x_se_write( running_machine *machine, int chip, int se )
/*-------------------------------------------------
adc083x_se_write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( adc083x_se_write )
{
struct adc083x_chip *c;
adc083x_state *adc083x = get_safe_token(device);
if( chip >= MAX_ADC083X_CHIPS )
if (adc083x->se != data)
{
verboselog( machine, 0, "adc083x_se_write( %d ) chip out of range\n", chip );
return;
verboselog(device->machine, 2, "adc083x_se_write( %s, %d )\n", device->tag, data);
}
c = &adc083x[ chip ];
if( c->SE != se )
{
verboselog( machine, 2, "adc083x_se_write( %d, %d )\n", chip, se );
}
c->SE = se;
adc083x->se = data;
}
int adc083x_sars_read( running_machine *machine, int chip )
/*-------------------------------------------------
adc083x_sars_read
-------------------------------------------------*/
READ8_DEVICE_HANDLER( adc083x_sars_read )
{
struct adc083x_chip *c;
adc083x_state *adc083x = get_safe_token(device);
if( chip >= MAX_ADC083X_CHIPS )
{
verboselog( machine, 0, "adc083x_sars_read( %d ) chip out of range\n", chip );
return 0;
}
c = &adc083x[ chip ];
verboselog( machine, 1, "adc083x_sars_read( %d ) %d\n", chip, c->SARS );
return c->SARS;
verboselog(device->machine, 1, "adc083x_sars_read( %s ) %d\n", device->tag, adc083x->sars);
return adc083x->sars;
}
int adc083x_do_read( running_machine *machine, int chip )
/*-------------------------------------------------
adc083x_do_read
-------------------------------------------------*/
READ8_DEVICE_HANDLER( adc083x_do_read )
{
struct adc083x_chip *c;
adc083x_state *adc083x = get_safe_token(device);
if( chip >= MAX_ADC083X_CHIPS )
verboselog(device->machine, 1, "adc083x_sars_read( %s ) %d\n", device->tag, adc083x->_do);
return adc083x->_do;
}
/*-------------------------------------------------
DEVICE_START( adc083x )
-------------------------------------------------*/
static DEVICE_START( adc083x )
{
adc083x_state *adc083x = get_safe_token(device);
const adc083x_interface *intf = get_interface(device);
/* validate configuration */
assert(intf->type >= ADC0831 && intf->type < MAX_ADC083X_TYPES);
adc083x->type = intf->type;
switch (adc083x->type)
{
verboselog( machine, 0, "adc083x_do_read( %d ) chip out of range\n", chip );
return 0;
case ADC0831:
adc083x->sars = 1;
adc083x->mux_bits = 0;
break;
case ADC0832:
adc083x->sars = 1;
adc083x->mux_bits = 2;
break;
case ADC0834:
adc083x->sars = 0;
adc083x->mux_bits = 3;
break;
case ADC0838:
adc083x->sars = 0;
adc083x->mux_bits = 4;
break;
}
c = &adc083x[ chip ];
/* resolve callbacks */
devcb_resolve_read8(&adc083x->input_callback_r, &intf->input_callback_r, device);
verboselog( machine, 1, "adc083x_do_read( %d ) %d\n", chip, c->DO );
return c->DO;
/* register for state saving */
state_save_register_global(device->machine, adc083x->cs);
state_save_register_global(device->machine, adc083x->clk);
state_save_register_global(device->machine, adc083x->di);
state_save_register_global(device->machine, adc083x->se);
state_save_register_global(device->machine, adc083x->sars);
state_save_register_global(device->machine, adc083x->_do);
state_save_register_global(device->machine, adc083x->sgl);
state_save_register_global(device->machine, adc083x->odd);
state_save_register_global(device->machine, adc083x->sel1);
state_save_register_global(device->machine, adc083x->sel0);
state_save_register_global(device->machine, adc083x->state);
state_save_register_global(device->machine, adc083x->bit);
state_save_register_global(device->machine, adc083x->output);
state_save_register_global(device->machine, adc083x->mux_bits);
}
/*-------------------------------------------------
DEVICE_REseT( adc083x )
-------------------------------------------------*/
static DEVICE_RESET( adc083x )
{
adc083x_state *adc083x = get_safe_token(device);
adc083x->cs = 0;
adc083x->clk = 0;
adc083x->di = 0;
adc083x->se = 0;
adc083x->_do = 1;
adc083x->sgl = 0;
adc083x->odd = 0;
adc083x->sel1 = 0;
adc083x->sel0 = 0;
adc083x->state = STATE_IDLE;
adc083x->bit = 0;
adc083x->output = 0;
}
/*-------------------------------------------------
device definition
-------------------------------------------------*/
INLINE const char *get_adc083x_name(const device_config *device)
{
const adc083x_interface *intf = get_interface(device);
switch (intf->type)
{
default:
case ADC0831: return "A/D Converter 0831";
case ADC0832: return "A/D Converter 0832";
case ADC0834: return "A/D Converter 0834";
case ADC0838: return "A/D Converter 0838";
}
}
static const char *DEVTEMPLATE_SOURCE = __FILE__;
#define DEVTEMPLATE_ID(p,s) p##adc083x##s
#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET
#define DEVTEMPLATE_NAME get_adc083x_name(device)
#define DEVTEMPLATE_FAMILY "National Semiconductor A/D Converters 083x"
#define DEVTEMPLATE_CLASS DEVICE_CLASS_PERIPHERAL
#include "devtempl.h"

View File

@ -1,38 +1,79 @@
/*
* ADC0831/ADC0832/ADC0834/ADC0838
*
* 8-Bit Serial I/O A/D Converters with Muliplexer Options
*
*/
/***************************************************************************
#if !defined( ADC083X_H )
#define ADC083X_H ( 1 )
National Semiconductor ADC0831 / ADC0832 / ADC0834 / ADC0838
#define MAX_ADC083X_CHIPS ( 1 )
8-Bit serial I/O A/D Converters with Muliplexer Options
#define ADC083X_CH0 ( 0 )
#define ADC083X_CH1 ( 1 )
#define ADC083X_CH2 ( 2 )
#define ADC083X_CH3 ( 3 )
#define ADC083X_CH4 ( 4 )
#define ADC083X_CH5 ( 5 )
#define ADC083X_CH6 ( 6 )
#define ADC083X_CH7 ( 7 )
#define ADC083X_COM ( 8 )
#define ADC083X_AGND ( 9 )
#define ADC083X_VREF ( 10 )
***************************************************************************/
#define ADC0831 ( 0 )
#define ADC0832 ( 1 )
#define ADC0834 ( 2 )
#define ADC0838 ( 3 )
#ifndef __ADC083X_H__
#define __ADC083X_H__
void adc083x_init( running_machine *machine, int chip, int type, double (*input_callback)( running_machine *machine, int input ) );
extern void adc083x_cs_write( running_machine *machine, int chip, int cs );
extern void adc083x_clk_write( running_machine *machine, int chip, int clk );
extern void adc083x_di_write( running_machine *machine, int chip, int di );
extern void adc083x_se_write( running_machine *machine, int chip, int se );
extern int adc083x_sars_read( running_machine *machine, int chip );
extern int adc083x_do_read( running_machine *machine, int chip );
#include "devcb.h"
#endif
/***************************************************************************
CONSTANTS
***************************************************************************/
/* enumeration specifying which model we are emulating */
enum
{
ADC0831,
ADC0832,
ADC0834,
ADC0838,
MAX_ADC083X_TYPES
};
#define ADC083X_CH0 0
#define ADC083X_CH1 1
#define ADC083X_CH2 2
#define ADC083X_CH3 3
#define ADC083X_CH4 4
#define ADC083X_CH5 5
#define ADC083X_CH6 6
#define ADC083X_CH7 7
#define ADC083X_COM 8
#define ADC083X_AGND 9
#define ADC083X_VREF 10
/***************************************************************************
MACROS / CONSTANTS
***************************************************************************/
#define ADC083X DEVICE_GET_INFO_NAME(adc083x)
#define MDRV_ADC083X_ADD(_tag, _config) \
MDRV_DEVICE_ADD(_tag, ADC083X, 0) \
MDRV_DEVICE_CONFIG(_config)
#define MDRV_ADC083X_REMOVE(_tag) \
MDRV_DEVICE_REMOVE(_tag)
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
typedef struct _adc083x_interface adc083x_interface;
struct _adc083x_interface
{
int type;
devcb_read8 input_callback_r;
};
/***************************************************************************
PROTOTYPES
***************************************************************************/
/* device interface */
DEVICE_GET_INFO( adc083x );
extern WRITE8_DEVICE_HANDLER( adc083x_cs_write );
extern WRITE8_DEVICE_HANDLER( adc083x_clk_write );
extern WRITE8_DEVICE_HANDLER( adc083x_di_write );
extern WRITE8_DEVICE_HANDLER( adc083x_se_write );
extern READ8_DEVICE_HANDLER( adc083x_sars_read );
extern READ8_DEVICE_HANDLER( adc083x_do_read );
#endif /* __ADC083X_H__ */

View File

@ -848,31 +848,38 @@ static WRITE32_HANDLER( sound020_w )
static READ32_HANDLER( adc0834_r )
{
return adc083x_do_read( space->machine, 0 ) << 24;
const device_config *adc0834 = devtag_get_device(space->machine, "adc0834");
return adc083x_do_read(adc0834, 0) << 24;
}
static WRITE32_HANDLER( adc0834_w )
{
running_machine *machine = space->machine;
adc083x_clk_write( machine, 0, ( data >> 24 ) & 1 );
adc083x_di_write( machine, 0, ( data >> 25 ) & 1 );
adc083x_cs_write( machine, 0, ( data >> 26 ) & 1 );
const device_config *adc0834 = devtag_get_device(space->machine, "adc0834");
adc083x_clk_write(adc0834, 0, (data >> 24) & 1);
adc083x_di_write(adc0834, 0, (data >> 25) & 1);
adc083x_cs_write(adc0834, 0, (data >> 26) & 1);
}
static double adc0834_callback( running_machine *machine, int input )
static READ8_DEVICE_HANDLER( adc0834_callback )
{
switch( input )
switch (offset)
{
case ADC083X_CH0:
return ( (double)5 * input_port_read(machine, "AN0" ) ) / 255; // steer
return input_port_read(device->machine, "AN0"); // steer
case ADC083X_CH1:
return ( (double)5 * input_port_read(machine, "AN1" ) ) / 255; // gas
return input_port_read(device->machine, "AN1"); // gas
case ADC083X_VREF:
return 5;
return 255;
}
return 0;
}
static const adc083x_interface konamigx_adc_interface = {
ADC0834,
DEVCB_HANDLER(adc0834_callback)
};
static READ32_HANDLER( le2_gun_H_r )
{
int p1x = input_port_read(space->machine, "LIGHT0_X")*290/0xff+20;
@ -1392,6 +1399,8 @@ static MACHINE_DRIVER_START( konamigx )
MDRV_SOUND_CONFIG(k054539_config)
MDRV_SOUND_ROUTE(0, "lspeaker", 1.0)
MDRV_SOUND_ROUTE(1, "rspeaker", 1.0)
MDRV_ADC083X_ADD( "adc0834", konamigx_adc_interface )
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( dragoonj )
@ -3410,8 +3419,6 @@ static DRIVER_INIT(konamigx)
int i, match;
int readback = 0;
adc083x_init( machine, 0, ADC0834, adc0834_callback );
konamigx_cfgport = -1;
last_prot_op = -1;
last_prot_clk = 0;

View File

@ -351,6 +351,7 @@ static READ32_HANDLER( mb89371_r )
static READ32_HANDLER( jamma_r )
{
running_machine *machine = space->machine;
const device_config *adc0834 = devtag_get_device(space->machine, "adc0834");
UINT32 data = 0;
switch (offset)
@ -368,7 +369,7 @@ static READ32_HANDLER( jamma_r )
data |= ds2401_read( machine, security_cart_number ) << 14;
}
data |= adc083x_do_read( machine, 0 ) << 16;
data |= adc083x_do_read(adc0834, 0) << 16;
switch( chiptype[ security_cart_number ] )
{
@ -411,15 +412,16 @@ static READ32_HANDLER( jamma_r )
static WRITE32_HANDLER( jamma_w )
{
running_machine *machine = space->machine;
const device_config *adc0834 = devtag_get_device(space->machine, "adc0834");
verboselog( machine, 2, "jamma_w( %08x, %08x, %08x )\n", offset, mem_mask, data );
switch( offset )
{
case 0:
adc083x_cs_write( machine, 0, ( data >> 1 ) & 1 );
adc083x_clk_write( machine, 0, ( data >> 2 ) & 1 );
adc083x_di_write( machine, 0, ( data >> 0 ) & 1 );
adc083x_se_write( machine, 0, 0 );
adc083x_cs_write(adc0834, 0, (data >> 1) & 1);
adc083x_clk_write(adc0834, 0, (data >> 2) & 1);
adc083x_di_write(adc0834, 0, (data >> 0) & 1);
adc083x_se_write(adc0834, 0, 0);
break;
default:
@ -1384,6 +1386,7 @@ static ADDRESS_MAP_START( konami573_map, ADDRESS_SPACE_PROGRAM, 32 )
ADDRESS_MAP_END
static void flash_init( running_machine *machine )
{
int i;
@ -1440,26 +1443,6 @@ static void flash_init( running_machine *machine )
state_save_register_global(machine, control );
}
static double analogue_inputs_callback( running_machine *machine, int input )
{
switch( input )
{
case ADC083X_CH0:
return (double) ( input_port_read_safe(machine, "analog0", 0 ) * 5 ) / 255;
case ADC083X_CH1:
return (double) ( input_port_read_safe(machine, "analog1", 0 ) * 5 ) / 255;
case ADC083X_CH2:
return (double) ( input_port_read_safe(machine, "analog2", 0 ) * 5 ) / 255;
case ADC083X_CH3:
return (double) ( input_port_read_safe(machine, "analog3", 0 ) * 5 ) / 255;
case ADC083X_AGND:
return 0;
case ADC083X_VREF:
return 5;
}
return 0;
}
static void *atapi_get_device(void)
{
void *ret;
@ -1570,7 +1553,6 @@ static DRIVER_INIT( konami573 )
state_save_register_item_array( machine, "KSYS573", NULL, 0, m_p_n_root_target );
state_save_register_item_array( machine, "KSYS573", NULL, 0, m_p_n_root_start );
adc083x_init( machine, 0, ADC0834, analogue_inputs_callback );
flash_init(machine);
}
@ -2783,6 +2765,36 @@ static DRIVER_INIT( salarymc )
state_save_register_global(machine, salarymc_lamp_clk );
}
/* ADC0834 Interface */
static READ8_DEVICE_HANDLER( analogue_inputs_callback )
{
switch (offset)
{
case ADC083X_CH0:
return input_port_read_safe(device->machine, "analog0", 0);
case ADC083X_CH1:
return input_port_read_safe(device->machine, "analog1", 0);
case ADC083X_CH2:
return input_port_read_safe(device->machine, "analog2", 0);
case ADC083X_CH3:
return input_port_read_safe(device->machine, "analog3", 0);
case ADC083X_AGND:
return 0;
case ADC083X_VREF:
return 255;
}
return 0;
}
static const adc083x_interface konami573_adc_interface = {
ADC0834,
DEVCB_HANDLER(analogue_inputs_callback)
};
static MACHINE_DRIVER_START( konami573 )
/* basic machine hardware */
MDRV_CPU_ADD("maincpu", PSXCPU, XTAL_67_7376MHz )
@ -2819,8 +2831,11 @@ static MACHINE_DRIVER_START( konami573 )
MDRV_SOUND_ROUTE( 1, "rspeaker", 1.0 )
MDRV_M48T58_ADD( "m48t58" )
MDRV_ADC083X_ADD( "adc0834", konami573_adc_interface )
MACHINE_DRIVER_END
static INPUT_PORTS_START( konami573 )
PORT_START("IN0")
PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
@ -3070,6 +3085,7 @@ static INPUT_PORTS_START( drmn )
PORT_BIT( 0x08000000, IP_ACTIVE_LOW, IPT_UNUSED ) /* P2 BUTTON6 */
INPUT_PORTS_END
#define SYS573_BIOS_A ROM_LOAD( "700a01.22g", 0x0000000, 0x080000, CRC(11812ef8) SHA1(e1284add4aaddd5337bd7f4e27614460d52b5b48))
// BIOS

View File

@ -282,12 +282,14 @@ static VIDEO_UPDATE( zr107 )
static CUSTOM_INPUT( adcdo_r )
{
return adc083x_do_read(field->port->machine, 0);
const device_config *adc0838 = devtag_get_device(field->port->machine, "adc0838");
return adc083x_do_read(adc0838, 0);
}
static READ8_HANDLER( sysreg_r )
{
UINT32 r = 0;
const device_config *adc0838 = devtag_get_device(space->machine, "adc0838");
static const char *const portnames[] = { "IN0", "IN1", "IN2", "IN3" };
switch (offset)
@ -306,7 +308,7 @@ static READ8_HANDLER( sysreg_r )
0x20 = SARS (A/D busy flag)
0x10 = EEPDO (EEPROM DO)
*/
r = (adc083x_sars_read(space->machine, 0) << 5) | (eeprom_read_bit() << 4);
r = (adc083x_sars_read(adc0838, 0) << 5) | (eeprom_read_bit() << 4);
break;
case 5: /* Parallel data port */
@ -317,6 +319,8 @@ static READ8_HANDLER( sysreg_r )
static WRITE8_HANDLER( sysreg_w )
{
const device_config *adc0838 = devtag_get_device(space->machine, "adc0838");
switch (offset)
{
case 0: /* LED Register 0 */
@ -365,9 +369,9 @@ static WRITE8_HANDLER( sysreg_w )
if (data & 0x40) /* CG Board 0 IRQ Ack */
cputag_set_input_line(space->machine, "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
set_cgboard_id((data >> 4) & 3);
adc083x_cs_write(space->machine, 0, (data >> 2) & 1);
adc083x_di_write(space->machine, 0, (data >> 1) & 1);
adc083x_clk_write(space->machine, 0, (data >> 0) & 1);
adc083x_cs_write(adc0838, 0, (data >> 2) & 1);
adc083x_di_write(adc0838, 0, (data >> 1) & 1);
adc083x_clk_write(adc0838, 0, (data >> 0) & 1);
mame_printf_debug("System register 1 = %02X\n", data);
break;
@ -382,28 +386,6 @@ static WRITE8_HANDLER( sysreg_w )
}
}
static double adc0838_callback(running_machine *machine, int input)
{
switch (input)
{
case ADC083X_CH0:
return (double)(5 * input_port_read(machine, "ANALOG1")) / 255.0;
case ADC083X_CH1:
return (double)(5 * input_port_read(machine, "ANALOG2")) / 255.0;
case ADC083X_CH2:
return (double)(5 * input_port_read(machine, "ANALOG3")) / 255.0;
case ADC083X_CH3:
return 0;
case ADC083X_COM:
return 0;
case ADC083X_AGND:
return 0;
case ADC083X_VREF:
return 5;
}
return 0;
}
static int ccu_vcth = 0;
static int ccu_vctl = 0;
static READ32_HANDLER( ccu_r )
@ -697,6 +679,38 @@ static const sharc_config sharc_cfg =
BOOT_MODE_EPROM
};
/* ADC0838 Interface */
static READ8_DEVICE_HANDLER( adc0838_callback )
{
switch (offset)
{
case ADC083X_CH0:
return input_port_read(device->machine, "ANALOG1");
case ADC083X_CH1:
return input_port_read(device->machine, "ANALOG2");
case ADC083X_CH2:
return input_port_read(device->machine, "ANALOG3");
case ADC083X_CH3:
return 0;
case ADC083X_COM:
return 0;
case ADC083X_AGND:
return 0;
case ADC083X_VREF:
return 255;
}
return 0;
}
static const adc083x_interface zr107_adc_interface = {
ADC0838,
DEVCB_HANDLER(adc0838_callback)
};
/* PowerPC interrupts
IRQ0: Vblank
@ -756,6 +770,8 @@ static MACHINE_DRIVER_START( zr107 )
MDRV_SOUND_CONFIG(k054539_config)
MDRV_SOUND_ROUTE(0, "lspeaker", 0.75)
MDRV_SOUND_ROUTE(1, "rspeaker", 0.75)
MDRV_ADC083X_ADD("adc0838", zr107_adc_interface)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( jetwave )
@ -801,6 +817,8 @@ static MACHINE_DRIVER_START( jetwave )
MDRV_SOUND_CONFIG(k054539_config)
MDRV_SOUND_ROUTE(0, "lspeaker", 0.75)
MDRV_SOUND_ROUTE(1, "rspeaker", 0.75)
MDRV_ADC083X_ADD("adc0838", zr107_adc_interface)
MACHINE_DRIVER_END
/*****************************************************************************/
@ -826,8 +844,6 @@ static void init_zr107(running_machine *machine)
K001005_preprocess_texture_data(memory_region(machine, "gfx1"), memory_region_length(machine, "gfx1"), 0);
K056800_init(machine, sound_irq_callback);
adc083x_init(machine, 0, ADC0838, adc0838_callback);
}
static DRIVER_INIT(zr107)