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,13 +1,16 @@
/* /***************************************************************************
* ADC0831/ADC0832/ADC0834/ADC0838
* National Semiconductor ADC0831 / ADC0832 / ADC0834 / ADC0838
* 8-Bit Serial I/O A/D Converters with Muliplexer Options
* 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 "driver.h"
#include "machine/adc083x.h" #include "adc083x.h"
#define VERBOSE_LEVEL (0) #define VERBOSE_LEVEL (0)
@ -24,169 +27,142 @@ INLINE void ATTR_PRINTF(3,4) verboselog( running_machine *machine, int n_level,
} }
} }
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; int type;
double (*input_callback)(running_machine *machine, int input);
INT32 CS; devcb_resolved_read8 input_callback_r;
INT32 CLK;
INT32 DI; INT32 cs;
INT32 SE; INT32 clk;
INT32 SARS; INT32 di;
INT32 DO; INT32 se;
INT32 SGL; INT32 sars;
INT32 ODD; INT32 _do;
INT32 SEL1; INT32 sgl;
INT32 SEL0; INT32 odd;
INT32 sel1;
INT32 sel0;
INT32 state; INT32 state;
INT32 bit; INT32 bit;
INT32 output; INT32 output;
INT32 mux_bits; 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; assert(device != NULL);
assert(device->token != NULL);
if( chip >= MAX_ADC083X_CHIPS ) assert((device->type == ADC083X));
{ return (adc083x_state *)device->token;
verboselog( machine, 0, "adc083x_init( %d ) chip out of range\n", chip );
return;
} }
c = &adc083x[ chip ]; INLINE const adc083x_interface *get_interface(const device_config *device)
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; assert(device != NULL);
assert((device->type == ADC083X));
return (const adc083x_interface *) device->static_config;
}
/***************************************************************************
IMPLEMENTATION
***************************************************************************/
/*-------------------------------------------------
adc083x_cs_write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( adc083x_cs_write )
{
adc083x_state *adc083x = get_safe_token(device);
if (adc083x->cs != data)
{
verboselog(device->machine, 2, "adc083x_cs_write( %s, %d )\n", device->tag, data);
}
if (adc083x->cs == 0 && data != 0)
{
adc083x->state = STATE_IDLE;
if (adc083x->type == ADC0834 || adc083x->type == ADC0838)
{
adc083x->sars = 1;
}
adc083x->_do = 1;
}
if (adc083x->cs != 0 && data == 0)
{
if (adc083x->type == ADC0831)
{
adc083x->state = STATE_MUX_SETTLE;
} }
else else
{ {
c->SARS = 0; adc083x->state = STATE_WAIT_FOR_START;
}
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 ); if (adc083x->type == ADC0834 || adc083x->type == ADC0838)
state_save_register_item( machine, "adc083x", NULL, chip, c->CLK ); {
state_save_register_item( machine, "adc083x", NULL, chip, c->DI ); adc083x->sars = 1;
state_save_register_item( machine, "adc083x", NULL, chip, c->SE ); }
state_save_register_item( machine, "adc083x", NULL, chip, c->SARS ); adc083x->_do = 1;
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 );
} }
void adc083x_cs_write( running_machine *machine, int chip, int cs ) adc083x->cs = data;
{
struct adc083x_chip *c;
if( chip >= MAX_ADC083X_CHIPS )
{
verboselog( machine, 0, "adc083x_cs_write( %d ) chip out of range\n", chip );
return;
} }
c = &adc083x[ chip ]; /*-------------------------------------------------
adc083x_conversion
-------------------------------------------------*/
if( c->CS != cs ) static UINT8 adc083x_conversion( const device_config *device )
{ {
verboselog( machine, 2, "adc083x_cs_write( %d, %d )\n", chip, cs ); adc083x_state *adc083x = get_safe_token(device);
}
if( c->CS == 0 && cs != 0 )
{
c->state = STATE_IDLE;
if( c->type == ADC0834 || c->type == ADC0838 )
{
c->SARS = 1;
}
c->DO = 1;
}
if( c->CS != 0 && cs == 0 )
{
if( c->type == ADC0831 )
{
c->state = STATE_MUX_SETTLE;
}
else
{
c->state = STATE_WAIT_FOR_START;
}
if( c->type == ADC0834 || c->type == ADC0838 )
{
c->SARS = 1;
}
c->DO = 1;
}
c->CS = cs;
}
static int adc083x_conversion( running_machine *machine, int chip )
{
struct adc083x_chip *c = &adc083x[ chip ];
int result; int result;
int positive_channel = ADC083X_AGND; int positive_channel = ADC083X_AGND;
int negative_channel = ADC083X_AGND; int negative_channel = ADC083X_AGND;
double positive = 0; double positive = 0;
double negative = 0; double negative = 0;
double gnd = c->input_callback( machine, ADC083X_AGND ); double vref = (double)(5 * devcb_call_read8(&adc083x->input_callback_r, ADC083X_VREF)) / 255.0;
double vref = c->input_callback( machine, ADC083X_VREF ); UINT8 gnd = devcb_call_read8(&adc083x->input_callback_r, ADC083X_AGND);
switch( c->type ) switch (adc083x->type)
{ {
case ADC0831: case ADC0831:
positive_channel = ADC083X_CH0; positive_channel = ADC083X_CH0;
negative_channel = ADC083X_CH1; negative_channel = ADC083X_CH1;
break; break;
case ADC0832: case ADC0832:
positive_channel = ADC083X_CH0 + c->ODD; positive_channel = ADC083X_CH0 + adc083x->odd;
if( c->SGL == 0 ) if (adc083x->sgl == 0)
{ {
negative_channel = positive_channel ^ 1; negative_channel = positive_channel ^ 1;
} }
@ -196,8 +172,8 @@ static int adc083x_conversion( running_machine *machine, int chip )
} }
break; break;
case ADC0834: case ADC0834:
positive_channel = ADC083X_CH0 + c->ODD + ( c->SEL1 * 2 ); positive_channel = ADC083X_CH0 + adc083x->odd + (adc083x->sel1 * 2);
if( c->SGL == 0 ) if (adc083x->sgl == 0)
{ {
negative_channel = positive_channel ^ 1; negative_channel = positive_channel ^ 1;
} }
@ -207,8 +183,8 @@ static int adc083x_conversion( running_machine *machine, int chip )
} }
break; break;
case ADC0838: case ADC0838:
positive_channel = ADC083X_CH0 + c->ODD + ( c->SEL0 * 2 ) + ( c->SEL1 * 4 ); positive_channel = ADC083X_CH0 + adc083x->odd + (adc083x->sel0 * 2) + (adc083x->sel1 * 4);
if( c->SGL == 0 ) if (adc083x->sgl == 0)
{ {
negative_channel = positive_channel ^ 1; negative_channel = positive_channel ^ 1;
} }
@ -221,14 +197,15 @@ static int adc083x_conversion( running_machine *machine, int chip )
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); result = (int)(((positive - negative) * 255) / vref);
logerror("%d", result);
if (result < 0) if (result < 0)
{ {
result = 0; result = 0;
@ -241,218 +218,300 @@ static int adc083x_conversion( running_machine *machine, int chip )
return result; return result;
} }
void adc083x_clk_write( running_machine *machine, int chip, int clk ) /*-------------------------------------------------
{ adc083x_clk_write
struct adc083x_chip *c; -------------------------------------------------*/
if( chip >= MAX_ADC083X_CHIPS ) WRITE8_DEVICE_HANDLER( adc083x_clk_write )
{ {
verboselog( machine, 0, "adc083x_clk_write( %d ) chip out of range\n", chip ); adc083x_state *adc083x = get_safe_token(device);
return;
if (adc083x->clk != data)
{
verboselog(device->machine, 2, "adc083x_clk_write( %s, %d )\n", device->tag, data);
} }
c = &adc083x[ chip ]; if (adc083x->cs == 0)
if( c->CLK != clk )
{ {
verboselog( machine, 2, "adc083x_clk_write( %d, %d )\n", chip, clk ); if (adc083x->clk == 0 && data != 0)
}
if( c->CS == 0 )
{ {
if( c->CLK == 0 && clk != 0 ) switch (adc083x->state)
{
switch( c->state )
{ {
case STATE_WAIT_FOR_START: case STATE_WAIT_FOR_START:
if( c->DI != 0 ) if (adc083x->di != 0)
{ {
verboselog( machine, 1, "adc083x %d got start bit\n", chip ); verboselog(device->machine, 1, "adc083x %s got start bit\n", device->tag);
c->state = STATE_SHIFT_MUX; adc083x->state = STATE_SHIFT_MUX;
c->SARS = 0; adc083x->sars = 0;
c->SGL = 0; adc083x->sgl = 0;
c->ODD = 0; adc083x->odd = 0;
c->SEL1 = 0; adc083x->sel1 = 0;
c->SEL0 = 0; adc083x->sel0 = 0;
c->bit = 0; adc083x->bit = 0;
} }
else else
{ {
verboselog( machine, 1, "adc083x %d not start bit\n", chip ); verboselog(device->machine, 1, "adc083x %s not start bit\n", device->tag);
} }
break; break;
case STATE_SHIFT_MUX: case STATE_SHIFT_MUX:
switch( c->bit ) switch (adc083x->bit)
{ {
case 0: 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; break;
case 1: 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; break;
case 2: 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; break;
case 3: 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; break;
} }
c->bit++; adc083x->bit++;
if( c->bit == c->mux_bits ) if (adc083x->bit == adc083x->mux_bits)
{ {
c->state = STATE_MUX_SETTLE; adc083x->state = STATE_MUX_SETTLE;
} }
break; break;
case STATE_WAIT_FOR_SE: case STATE_WAIT_FOR_SE:
c->SARS = 0; adc083x->sars = 0;
if( c->type == ADC0838 && c->SE != 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 else
{ {
verboselog( machine, 1, "adc083x %d got SE\n", chip ); verboselog(device->machine, 1, "adc083x %s got se\n", device->tag);
c->state = STATE_OUTPUT_LSB_FIRST; adc083x->state = STATE_OUTPUT_LSB_FIRST;
c->bit = 1; adc083x->bit = 1;
} }
break; break;
} }
} }
if( c->CLK != 0 && clk == 0 ) if (adc083x->clk != 0 && data == 0)
{ {
switch( c->state ) switch (adc083x->state)
{ {
case STATE_MUX_SETTLE: case STATE_MUX_SETTLE:
verboselog( machine, 1, "adc083x %d mux settle\n", chip ); verboselog(device->machine, 1, "adc083x %s mux settle\n", device->tag);
c->output = adc083x_conversion( machine, chip ); adc083x->output = adc083x_conversion(device);
c->state = STATE_OUTPUT_MSB_FIRST; adc083x->state = STATE_OUTPUT_MSB_FIRST;
c->bit = 7; adc083x->bit = 7;
if( c->type == ADC0834 || c->type == ADC0838 ) if (adc083x->type == ADC0834 || adc083x->type == ADC0838)
{ {
c->SARS = 1; adc083x->sars = 1;
} }
c->DO = 0; adc083x->_do = 0;
break; break;
case STATE_OUTPUT_MSB_FIRST: case STATE_OUTPUT_MSB_FIRST:
c->DO = ( c->output >> c->bit ) & 1; adc083x->_do = (adc083x->output >> adc083x->bit) & 1;
verboselog( machine, 1, "adc083x %d msb %d -> %d\n", chip, c->bit, c->DO ); verboselog(device->machine, 1, "adc083x %s msb %d -> %d\n", device->tag, adc083x->bit, adc083x->_do);
c->bit--; adc083x->bit--;
if( c->bit < 0 ) if (adc083x->bit < 0)
{ {
if( c->type == ADC0831 ) if (adc083x->type == ADC0831)
{ {
c->state = STATE_FINISHED; adc083x->state = STATE_FINISHED;
} }
else else
{ {
c->state = STATE_WAIT_FOR_SE; adc083x->state = STATE_WAIT_FOR_SE;
} }
} }
break; break;
case STATE_OUTPUT_LSB_FIRST: case STATE_OUTPUT_LSB_FIRST:
c->DO = ( c->output >> c->bit ) & 1; adc083x->_do = (adc083x->output >> adc083x->bit) & 1;
verboselog( machine, 1, "adc083x %d lsb %d -> %d\n", chip, c->bit, c->DO ); verboselog(device->machine, 1, "adc083x %s lsb %d -> %d\n", device->tag, adc083x->bit, adc083x->_do);
c->bit++; adc083x->bit++;
if( c->bit == 8 ) if (adc083x->bit == 8)
{ {
c->state = STATE_FINISHED; adc083x->state = STATE_FINISHED;
} }
break; break;
case STATE_FINISHED: case STATE_FINISHED:
c->state = STATE_IDLE; adc083x->state = STATE_IDLE;
c->DO = 0; adc083x->_do = 0;
break; 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 ); verboselog(device->machine, 2, "adc083x_di_write( %s, %d )\n", device->tag, data);
return;
} }
c = &adc083x[ chip ]; adc083x->di = data;
}
if( c->DI != di ) /*-------------------------------------------------
adc083x_se_write
-------------------------------------------------*/
WRITE8_DEVICE_HANDLER( adc083x_se_write )
{ {
verboselog( machine, 2, "adc083x_di_write( %d, %d )\n", chip, di ); adc083x_state *adc083x = get_safe_token(device);
}
c->DI = di; if (adc083x->se != data)
}
void adc083x_se_write( running_machine *machine, int chip, int se )
{ {
struct adc083x_chip *c; verboselog(device->machine, 2, "adc083x_se_write( %s, %d )\n", device->tag, data);
}
if( chip >= MAX_ADC083X_CHIPS ) adc083x->se = data;
}
/*-------------------------------------------------
adc083x_sars_read
-------------------------------------------------*/
READ8_DEVICE_HANDLER( adc083x_sars_read )
{ {
verboselog( machine, 0, "adc083x_se_write( %d ) chip out of range\n", chip ); adc083x_state *adc083x = get_safe_token(device);
return;
verboselog(device->machine, 1, "adc083x_sars_read( %s ) %d\n", device->tag, adc083x->sars);
return adc083x->sars;
} }
c = &adc083x[ chip ]; /*-------------------------------------------------
adc083x_do_read
-------------------------------------------------*/
if( c->SE != se ) READ8_DEVICE_HANDLER( adc083x_do_read )
{ {
verboselog( machine, 2, "adc083x_se_write( %d, %d )\n", chip, se ); adc083x_state *adc083x = get_safe_token(device);
verboselog(device->machine, 1, "adc083x_sars_read( %s ) %d\n", device->tag, adc083x->_do);
return adc083x->_do;
} }
c->SE = se;
}
int adc083x_sars_read( running_machine *machine, int chip ) /*-------------------------------------------------
DEVICE_START( adc083x )
-------------------------------------------------*/
static DEVICE_START( adc083x )
{ {
struct adc083x_chip *c; adc083x_state *adc083x = get_safe_token(device);
const adc083x_interface *intf = get_interface(device);
if( chip >= MAX_ADC083X_CHIPS ) /* validate configuration */
assert(intf->type >= ADC0831 && intf->type < MAX_ADC083X_TYPES);
adc083x->type = intf->type;
switch (adc083x->type)
{ {
verboselog( machine, 0, "adc083x_sars_read( %d ) chip out of range\n", chip ); case ADC0831:
return 0; 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_sars_read( %d ) %d\n", chip, c->SARS ); /* register for state saving */
return c->SARS; 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);
} }
int adc083x_do_read( running_machine *machine, int chip ) /*-------------------------------------------------
DEVICE_REseT( adc083x )
-------------------------------------------------*/
static DEVICE_RESET( adc083x )
{ {
struct adc083x_chip *c; adc083x_state *adc083x = get_safe_token(device);
if( chip >= MAX_ADC083X_CHIPS ) 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)
{ {
verboselog( machine, 0, "adc083x_do_read( %d ) chip out of range\n", chip ); const adc083x_interface *intf = get_interface(device);
return 0; 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";
}
} }
c = &adc083x[ chip ]; static const char *DEVTEMPLATE_SOURCE = __FILE__;
verboselog( machine, 1, "adc083x_do_read( %d ) %d\n", chip, c->DO ); #define DEVTEMPLATE_ID(p,s) p##adc083x##s
return c->DO; #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 ) National Semiconductor ADC0831 / ADC0832 / ADC0834 / ADC0838
#define ADC083X_H ( 1 )
#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 ) #ifndef __ADC083X_H__
#define ADC0832 ( 1 ) #define __ADC083X_H__
#define ADC0834 ( 2 )
#define ADC0838 ( 3 )
void adc083x_init( running_machine *machine, int chip, int type, double (*input_callback)( running_machine *machine, int input ) ); #include "devcb.h"
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 );
#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 ) 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 ) static WRITE32_HANDLER( adc0834_w )
{ {
running_machine *machine = space->machine; const device_config *adc0834 = devtag_get_device(space->machine, "adc0834");
adc083x_clk_write( machine, 0, ( data >> 24 ) & 1 ); adc083x_clk_write(adc0834, 0, (data >> 24) & 1);
adc083x_di_write( machine, 0, ( data >> 25 ) & 1 ); adc083x_di_write(adc0834, 0, (data >> 25) & 1);
adc083x_cs_write( machine, 0, ( data >> 26 ) & 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: case ADC083X_CH0:
return ( (double)5 * input_port_read(machine, "AN0" ) ) / 255; // steer return input_port_read(device->machine, "AN0"); // steer
case ADC083X_CH1: case ADC083X_CH1:
return ( (double)5 * input_port_read(machine, "AN1" ) ) / 255; // gas return input_port_read(device->machine, "AN1"); // gas
case ADC083X_VREF: case ADC083X_VREF:
return 5; return 255;
} }
return 0; return 0;
} }
static const adc083x_interface konamigx_adc_interface = {
ADC0834,
DEVCB_HANDLER(adc0834_callback)
};
static READ32_HANDLER( le2_gun_H_r ) static READ32_HANDLER( le2_gun_H_r )
{ {
int p1x = input_port_read(space->machine, "LIGHT0_X")*290/0xff+20; 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_CONFIG(k054539_config)
MDRV_SOUND_ROUTE(0, "lspeaker", 1.0) MDRV_SOUND_ROUTE(0, "lspeaker", 1.0)
MDRV_SOUND_ROUTE(1, "rspeaker", 1.0) MDRV_SOUND_ROUTE(1, "rspeaker", 1.0)
MDRV_ADC083X_ADD( "adc0834", konamigx_adc_interface )
MACHINE_DRIVER_END MACHINE_DRIVER_END
static MACHINE_DRIVER_START( dragoonj ) static MACHINE_DRIVER_START( dragoonj )
@ -3410,8 +3419,6 @@ static DRIVER_INIT(konamigx)
int i, match; int i, match;
int readback = 0; int readback = 0;
adc083x_init( machine, 0, ADC0834, adc0834_callback );
konamigx_cfgport = -1; konamigx_cfgport = -1;
last_prot_op = -1; last_prot_op = -1;
last_prot_clk = 0; last_prot_clk = 0;

View File

@ -351,6 +351,7 @@ static READ32_HANDLER( mb89371_r )
static READ32_HANDLER( jamma_r ) static READ32_HANDLER( jamma_r )
{ {
running_machine *machine = space->machine; running_machine *machine = space->machine;
const device_config *adc0834 = devtag_get_device(space->machine, "adc0834");
UINT32 data = 0; UINT32 data = 0;
switch (offset) switch (offset)
@ -368,7 +369,7 @@ static READ32_HANDLER( jamma_r )
data |= ds2401_read( machine, security_cart_number ) << 14; 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 ] ) switch( chiptype[ security_cart_number ] )
{ {
@ -411,15 +412,16 @@ static READ32_HANDLER( jamma_r )
static WRITE32_HANDLER( jamma_w ) static WRITE32_HANDLER( jamma_w )
{ {
running_machine *machine = space->machine; 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 ); verboselog( machine, 2, "jamma_w( %08x, %08x, %08x )\n", offset, mem_mask, data );
switch( offset ) switch( offset )
{ {
case 0: case 0:
adc083x_cs_write( machine, 0, ( data >> 1 ) & 1 ); adc083x_cs_write(adc0834, 0, (data >> 1) & 1);
adc083x_clk_write( machine, 0, ( data >> 2 ) & 1 ); adc083x_clk_write(adc0834, 0, (data >> 2) & 1);
adc083x_di_write( machine, 0, ( data >> 0 ) & 1 ); adc083x_di_write(adc0834, 0, (data >> 0) & 1);
adc083x_se_write( machine, 0, 0 ); adc083x_se_write(adc0834, 0, 0);
break; break;
default: default:
@ -1384,6 +1386,7 @@ static ADDRESS_MAP_START( konami573_map, ADDRESS_SPACE_PROGRAM, 32 )
ADDRESS_MAP_END ADDRESS_MAP_END
static void flash_init( running_machine *machine ) static void flash_init( running_machine *machine )
{ {
int i; int i;
@ -1440,26 +1443,6 @@ static void flash_init( running_machine *machine )
state_save_register_global(machine, control ); 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) static void *atapi_get_device(void)
{ {
void *ret; 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_target );
state_save_register_item_array( machine, "KSYS573", NULL, 0, m_p_n_root_start ); 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); flash_init(machine);
} }
@ -2783,6 +2765,36 @@ static DRIVER_INIT( salarymc )
state_save_register_global(machine, salarymc_lamp_clk ); 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 ) static MACHINE_DRIVER_START( konami573 )
/* basic machine hardware */ /* basic machine hardware */
MDRV_CPU_ADD("maincpu", PSXCPU, XTAL_67_7376MHz ) 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_SOUND_ROUTE( 1, "rspeaker", 1.0 )
MDRV_M48T58_ADD( "m48t58" ) MDRV_M48T58_ADD( "m48t58" )
MDRV_ADC083X_ADD( "adc0834", konami573_adc_interface )
MACHINE_DRIVER_END MACHINE_DRIVER_END
static INPUT_PORTS_START( konami573 ) static INPUT_PORTS_START( konami573 )
PORT_START("IN0") PORT_START("IN0")
PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN ) 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 */ PORT_BIT( 0x08000000, IP_ACTIVE_LOW, IPT_UNUSED ) /* P2 BUTTON6 */
INPUT_PORTS_END INPUT_PORTS_END
#define SYS573_BIOS_A ROM_LOAD( "700a01.22g", 0x0000000, 0x080000, CRC(11812ef8) SHA1(e1284add4aaddd5337bd7f4e27614460d52b5b48)) #define SYS573_BIOS_A ROM_LOAD( "700a01.22g", 0x0000000, 0x080000, CRC(11812ef8) SHA1(e1284add4aaddd5337bd7f4e27614460d52b5b48))
// BIOS // BIOS

View File

@ -282,12 +282,14 @@ static VIDEO_UPDATE( zr107 )
static CUSTOM_INPUT( adcdo_r ) 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 ) static READ8_HANDLER( sysreg_r )
{ {
UINT32 r = 0; UINT32 r = 0;
const device_config *adc0838 = devtag_get_device(space->machine, "adc0838");
static const char *const portnames[] = { "IN0", "IN1", "IN2", "IN3" }; static const char *const portnames[] = { "IN0", "IN1", "IN2", "IN3" };
switch (offset) switch (offset)
@ -306,7 +308,7 @@ static READ8_HANDLER( sysreg_r )
0x20 = SARS (A/D busy flag) 0x20 = SARS (A/D busy flag)
0x10 = EEPDO (EEPROM DO) 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; break;
case 5: /* Parallel data port */ case 5: /* Parallel data port */
@ -317,6 +319,8 @@ static READ8_HANDLER( sysreg_r )
static WRITE8_HANDLER( sysreg_w ) static WRITE8_HANDLER( sysreg_w )
{ {
const device_config *adc0838 = devtag_get_device(space->machine, "adc0838");
switch (offset) switch (offset)
{ {
case 0: /* LED Register 0 */ case 0: /* LED Register 0 */
@ -365,9 +369,9 @@ static WRITE8_HANDLER( sysreg_w )
if (data & 0x40) /* CG Board 0 IRQ Ack */ if (data & 0x40) /* CG Board 0 IRQ Ack */
cputag_set_input_line(space->machine, "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE); cputag_set_input_line(space->machine, "maincpu", INPUT_LINE_IRQ0, CLEAR_LINE);
set_cgboard_id((data >> 4) & 3); set_cgboard_id((data >> 4) & 3);
adc083x_cs_write(space->machine, 0, (data >> 2) & 1); adc083x_cs_write(adc0838, 0, (data >> 2) & 1);
adc083x_di_write(space->machine, 0, (data >> 1) & 1); adc083x_di_write(adc0838, 0, (data >> 1) & 1);
adc083x_clk_write(space->machine, 0, (data >> 0) & 1); adc083x_clk_write(adc0838, 0, (data >> 0) & 1);
mame_printf_debug("System register 1 = %02X\n", data); mame_printf_debug("System register 1 = %02X\n", data);
break; 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_vcth = 0;
static int ccu_vctl = 0; static int ccu_vctl = 0;
static READ32_HANDLER( ccu_r ) static READ32_HANDLER( ccu_r )
@ -697,6 +679,38 @@ static const sharc_config sharc_cfg =
BOOT_MODE_EPROM 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 /* PowerPC interrupts
IRQ0: Vblank IRQ0: Vblank
@ -756,6 +770,8 @@ static MACHINE_DRIVER_START( zr107 )
MDRV_SOUND_CONFIG(k054539_config) MDRV_SOUND_CONFIG(k054539_config)
MDRV_SOUND_ROUTE(0, "lspeaker", 0.75) MDRV_SOUND_ROUTE(0, "lspeaker", 0.75)
MDRV_SOUND_ROUTE(1, "rspeaker", 0.75) MDRV_SOUND_ROUTE(1, "rspeaker", 0.75)
MDRV_ADC083X_ADD("adc0838", zr107_adc_interface)
MACHINE_DRIVER_END MACHINE_DRIVER_END
static MACHINE_DRIVER_START( jetwave ) static MACHINE_DRIVER_START( jetwave )
@ -801,6 +817,8 @@ static MACHINE_DRIVER_START( jetwave )
MDRV_SOUND_CONFIG(k054539_config) MDRV_SOUND_CONFIG(k054539_config)
MDRV_SOUND_ROUTE(0, "lspeaker", 0.75) MDRV_SOUND_ROUTE(0, "lspeaker", 0.75)
MDRV_SOUND_ROUTE(1, "rspeaker", 0.75) MDRV_SOUND_ROUTE(1, "rspeaker", 0.75)
MDRV_ADC083X_ADD("adc0838", zr107_adc_interface)
MACHINE_DRIVER_END 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); K001005_preprocess_texture_data(memory_region(machine, "gfx1"), memory_region_length(machine, "gfx1"), 0);
K056800_init(machine, sound_irq_callback); K056800_init(machine, sound_irq_callback);
adc083x_init(machine, 0, ADC0838, adc0838_callback);
} }
static DRIVER_INIT(zr107) static DRIVER_INIT(zr107)