diff options
Diffstat (limited to 'trunk/src/emu/machine/adc1038.c')
-rw-r--r-- | trunk/src/emu/machine/adc1038.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/trunk/src/emu/machine/adc1038.c b/trunk/src/emu/machine/adc1038.c new file mode 100644 index 00000000000..acf2ee32274 --- /dev/null +++ b/trunk/src/emu/machine/adc1038.c @@ -0,0 +1,177 @@ +/*************************************************************************** + + National Semiconductor ADC1038 + + 10-Bit Serial I/O A/D Converters with Analog Multiplexer and + Track/hold Function + +***************************************************************************/ + +#include "emu.h" +#include "adc1038.h" + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +typedef struct _adc1038_state adc1038_state; +struct _adc1038_state +{ + int cycle; + int clk; + int adr; + int data_in; + int data_out; + int adc_data; + int sars; + adc1038_input_read_func input_callback_r; + + int gticlub_hack; +}; + +/***************************************************************************** + INLINE FUNCTIONS +*****************************************************************************/ + +INLINE adc1038_state *adc1038_get_safe_token( device_t *device ) +{ + assert(device != NULL); + assert(device->type() == ADC1038); + + return (adc1038_state *)downcast<legacy_device_base *>(device)->token(); +} + +INLINE const adc1038_interface *adc1038_get_interface( device_t *device ) +{ + assert(device != NULL); + assert((device->type() == ADC1038)); + return (const adc1038_interface *) device->static_config(); +} + +/***************************************************************************** + DEVICE HANDLERS +*****************************************************************************/ + +READ_LINE_DEVICE_HANDLER( adc1038_do_read ) +{ + adc1038_state *adc1038 = adc1038_get_safe_token(device); + + //printf("ADC DO\n"); + return adc1038->data_out; +} + +WRITE_LINE_DEVICE_HANDLER( adc1038_di_write ) +{ + adc1038_state *adc1038 = adc1038_get_safe_token(device); + + adc1038->data_in = state; +} + +WRITE_LINE_DEVICE_HANDLER( adc1038_clk_write ) +{ + adc1038_state *adc1038 = adc1038_get_safe_token(device); + + // GTI Club doesn't sync on SARS + if (adc1038->gticlub_hack) + { + if (adc1038->clk == 0 && state == 0) + { + adc1038->cycle = 0; + + /* notice that adc1038->adr is always < 7! */ + adc1038->adc_data = adc1038->input_callback_r(device, adc1038->adr); + } + } + + if (state == 1) + { + //printf("ADC CLK, DI = %d, cycle = %d\n", adc1038->data_in, adc1038->cycle); + + if (adc1038->cycle == 0) // A2 + { + adc1038->adr = 0; + adc1038->adr |= (adc1038->data_in << 2); + } + else if (adc1038->cycle == 1) // A1 + { + adc1038->adr |= (adc1038->data_in << 1); + } + else if (adc1038->cycle == 2) // A0 + { + adc1038->adr |= (adc1038->data_in << 0); + } + + adc1038->data_out = (adc1038->adc_data & 0x200) ? 1 : 0; + adc1038->adc_data <<= 1; + + adc1038->cycle++; + } + + adc1038->clk = state; +} + +READ_LINE_DEVICE_HANDLER( adc1038_sars_read ) +{ + adc1038_state *adc1038 = adc1038_get_safe_token(device); + + adc1038->cycle = 0; + + /* notice that adc1038->adr is always < 7! */ + adc1038->adc_data = adc1038->input_callback_r(device, adc1038->adr); + + adc1038->data_out = (adc1038->adc_data & 0x200) ? 1 : 0; + adc1038->adc_data <<= 1; + + adc1038->sars ^= 1; + return adc1038->sars; +} + + +/***************************************************************************** + DEVICE INTERFACE +*****************************************************************************/ + +static DEVICE_START( adc1038 ) +{ + adc1038_state *adc1038 = adc1038_get_safe_token(device); + const adc1038_interface *intf = adc1038_get_interface(device); + + adc1038->gticlub_hack = intf->gticlub_hack; + adc1038->input_callback_r = intf->input_callback_r; + + device->save_item(NAME(adc1038->cycle)); + device->save_item(NAME(adc1038->clk)); + device->save_item(NAME(adc1038->adr)); + device->save_item(NAME(adc1038->data_in)); + device->save_item(NAME(adc1038->data_out)); + device->save_item(NAME(adc1038->adc_data)); + device->save_item(NAME(adc1038->sars)); +} + +static DEVICE_RESET( adc1038 ) +{ + adc1038_state *adc1038 = adc1038_get_safe_token(device); + + adc1038->cycle = 0; + adc1038->clk = 0; + adc1038->adr = 0; + adc1038->data_in = 0; + adc1038->data_out = 0; + adc1038->adc_data = 0; + adc1038->sars = 1; +} + +/*------------------------------------------------- + device definition +-------------------------------------------------*/ + +static const char DEVTEMPLATE_SOURCE[] = __FILE__; + +#define DEVTEMPLATE_ID( p, s ) p##adc1038##s +#define DEVTEMPLATE_FEATURES DT_HAS_START | DT_HAS_RESET +#define DEVTEMPLATE_NAME "A/D Converters 1038" +#define DEVTEMPLATE_FAMILY "National Semiconductor A/D Converters 1038" +#include "devtempl.h" + + +DEFINE_LEGACY_DEVICE(ADC1038, adc1038); |