diff --git a/src/emu/machine/adc083x.c b/src/emu/machine/adc083x.c index f1293314659..a1cd1c42e1e 100644 --- a/src/emu/machine/adc083x.c +++ b/src/emu/machine/adc083x.c @@ -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 #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" diff --git a/src/emu/machine/adc083x.h b/src/emu/machine/adc083x.h index f724322eb2a..ac5b07c4517 100644 --- a/src/emu/machine/adc083x.h +++ b/src/emu/machine/adc083x.h @@ -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__ */ diff --git a/src/mame/drivers/konamigx.c b/src/mame/drivers/konamigx.c index 765f3451095..02e82931522 100644 --- a/src/mame/drivers/konamigx.c +++ b/src/mame/drivers/konamigx.c @@ -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; diff --git a/src/mame/drivers/ksys573.c b/src/mame/drivers/ksys573.c index f7218be5d36..2bf908f54a2 100644 --- a/src/mame/drivers/ksys573.c +++ b/src/mame/drivers/ksys573.c @@ -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 diff --git a/src/mame/drivers/zr107.c b/src/mame/drivers/zr107.c index fe924b0e29f..be54c5bc165 100644 --- a/src/mame/drivers/zr107.c +++ b/src/mame/drivers/zr107.c @@ -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)