diff --git a/src/emu/machine/upd7002.c b/src/emu/machine/upd7002.c index dc6572645a0..5358062f57c 100644 --- a/src/emu/machine/upd7002.c +++ b/src/emu/machine/upd7002.c @@ -10,112 +10,126 @@ #include "emu.h" #include "upd7002.h" -#include "devlegcy.h" -struct uPD7002_t +/* Device Interface */ + +const device_type UPD7002 = &device_creator; + +upd7002_device::upd7002_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, UPD7002, "uPD7002", tag, owner, clock, "upd7002", __FILE__) { - /* Pointer to our interface */ - const uPD7002_interface *intf; +} - /* Status Register - D0 and D1 define the currently selected input channel - D2 flag output - D3 0 = 8 bit mode 1 = 12 bit mode - D4 2nd MSB of conversion - D5 MSB of conversion - D6 0 = busy, 1 = not busy (~busy) - D7 0 = conversion completed, 1 = conversion not completed (~EOC) - */ - int status; +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- - /* High data byte - This byte contains the 8 most significant bits of the analogue to digital conversion. */ - int data1; +void upd7002_device::device_config_complete() +{ + // inherit a copy of the static data + const upd7002_interface *intf = reinterpret_cast(static_config()); + if (intf != NULL) + *static_cast(this) = *intf; - /* Low data byte - In 12 bit mode: Bits 7 to 4 define the four low order bits of the conversion. - In 8 bit mode. All bits 7 to 4 are inaccurate. - Bits 3 to 0 are always set to low. */ - int data0; + // or initialize to defaults if none provided + else + { + get_analogue_func = NULL; + eoc_func = NULL; + } +} +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- - /* temporary store of the next A to D conversion */ - int digitalvalue; +void upd7002_device::device_start() +{ + // register for state saving + save_item(NAME(m_status)); + save_item(NAME(m_data1)); + save_item(NAME(m_data0)); + save_item(NAME(m_digitalvalue)); + save_item(NAME(m_conversion_counter)); +} - /* this counter is used to check a full end of conversion has been reached - if the uPD7002 is half way through one conversion and a new conversion is requested - the counter at the end of the first conversion will not match and not be processed - only then at the end of the second conversion will the conversion complete function run */ - int conversion_counter; -}; +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void upd7002_device::device_reset() +{ + m_status = 0; + m_data1 = 0; + m_data0 = 0; + m_digitalvalue = 0; + m_conversion_counter = 0; +} /***************************************************************************** Implementation *****************************************************************************/ -INLINE uPD7002_t *get_safe_token(device_t *device) -{ - assert(device != NULL); - assert(device->type() == UPD7002); - return (uPD7002_t *)downcast(device)->token(); -} - -READ8_DEVICE_HANDLER ( uPD7002_EOC_r ) +READ8_MEMBER( upd7002_device::eoc_r ) { - uPD7002_t *uPD7002 = get_safe_token(device); - return (uPD7002->status>>7)&0x01; + return (m_status>>7)&0x01; } -static TIMER_CALLBACK(uPD7002_conversioncomplete) +void upd7002_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { - device_t *device = (device_t *)ptr; - uPD7002_t *uPD7002 = get_safe_token(device); - - int counter_value = param; - if (counter_value==uPD7002->conversion_counter) + switch (id) { - // this really always does a 12 bit conversion - uPD7002->data1 = uPD7002->digitalvalue>>8; - uPD7002->data0 = uPD7002->digitalvalue&0xf0; + case TIMER_CONVERSION_COMPLETE: + { + int counter_value = param; + if (counter_value==m_conversion_counter) + { + // this really always does a 12 bit conversion + m_data1 = m_digitalvalue>>8; + m_data0 = m_digitalvalue&0xf0; - // set the status register with top 2 MSB, not busy and conversion complete - uPD7002->status = (uPD7002->status & 0x0f)|((uPD7002->data1 & 0xc0)>>2)|0x40; + // set the status register with top 2 MSB, not busy and conversion complete + m_status = (m_status & 0x0f)|((m_data1 & 0xc0)>>2)|0x40; - // call the EOC function with EOC from status - // uPD7002_EOC_r(0) this has just been set to 0 - if (uPD7002->intf->EOC_func) (uPD7002->intf->EOC_func)(device,0); - uPD7002->conversion_counter=0; + // call the EOC function with EOC from status + // eoc_r(0) this has just been set to 0 + if (eoc_func) (eoc_func)(this,0); + m_conversion_counter=0; + } + break; + } + default: + assert_always(FALSE, "Unknown id in upd7002_device::device_timer"); } } -READ8_DEVICE_HANDLER ( uPD7002_r ) +READ8_MEMBER( upd7002_device::read ) { - uPD7002_t *uPD7002 = get_safe_token(device); - switch(offset&0x03) { case 0: - return uPD7002->status; + return m_status; case 1: - return uPD7002->data1; + return m_data1; case 2: case 3: - return uPD7002->data0; + return m_data0; } return 0; } -WRITE8_DEVICE_HANDLER ( uPD7002_w ) +WRITE8_MEMBER( upd7002_device::write ) { - uPD7002_t *uPD7002 = get_safe_token(device); /* logerror("write to uPD7002 $%02X = $%02X\n",offset,data); */ switch(offset&0x03) @@ -135,28 +149,28 @@ WRITE8_DEVICE_HANDLER ( uPD7002_w ) */ /* set D6=0 busy ,D7=1 conversion not complete */ - uPD7002->status=(data & 0x0f) | 0x80; + m_status=(data & 0x0f) | 0x80; // call the EOC function with EOC from status - // uPD7002_EOC_r(0) this has just been set to 1 - if (uPD7002->intf->EOC_func) uPD7002->intf->EOC_func(device, 1); + // eoc_r(0) this has just been set to 1 + if (eoc_func) eoc_func(this, 1); /* the uPD7002 works by sampling the analogue value at the start of the conversion so it is read hear and stored until the end of the A to D conversion */ // this function should return a 16 bit value. - uPD7002->digitalvalue = uPD7002->intf->get_analogue_func(device, uPD7002->status & 0x03); + m_digitalvalue = get_analogue_func(this, m_status & 0x03); - uPD7002->conversion_counter++; + m_conversion_counter++; // call a timer to start the conversion - if (uPD7002->status & 0x08) + if (m_status & 0x08) { // 12 bit conversion takes 10ms - space.machine().scheduler().timer_set(attotime::from_msec(10), FUNC(uPD7002_conversioncomplete), uPD7002->conversion_counter, (void *)device); + timer_set(attotime::from_msec(10), TIMER_CONVERSION_COMPLETE, m_conversion_counter); } else { // 8 bit conversion takes 4ms - space.machine().scheduler().timer_set(attotime::from_msec(4), FUNC(uPD7002_conversioncomplete), uPD7002->conversion_counter, (void *)device); + timer_set(attotime::from_msec(4), TIMER_CONVERSION_COMPLETE, m_conversion_counter); } break; @@ -172,75 +186,3 @@ WRITE8_DEVICE_HANDLER ( uPD7002_w ) break; } } - -/* Device Interface */ - -static DEVICE_START( uPD7002 ) -{ - uPD7002_t *uPD7002 = get_safe_token(device); - // validate arguments - - assert(device != NULL); - assert(device->tag() != NULL); - assert(device->static_config() != NULL); - - uPD7002->intf = (const uPD7002_interface*)device->static_config(); - uPD7002->status = 0; - uPD7002->data1 = 0; - uPD7002->data0 = 0; - uPD7002->digitalvalue = 0; - uPD7002->conversion_counter = 0; - - // register for state saving - state_save_register_item(device->machine(), "uPD7002", device->tag(), 0, uPD7002->status); - state_save_register_item(device->machine(), "uPD7002", device->tag(), 0, uPD7002->data1); - state_save_register_item(device->machine(), "uPD7002", device->tag(), 0, uPD7002->data0); - state_save_register_item(device->machine(), "uPD7002", device->tag(), 0, uPD7002->digitalvalue); - state_save_register_item(device->machine(), "uPD7002", device->tag(), 0, uPD7002->conversion_counter); -} - -static DEVICE_RESET( uPD7002 ) -{ - uPD7002_t *uPD7002 = get_safe_token(device); - uPD7002->status = 0; - uPD7002->data1 = 0; - uPD7002->data0 = 0; - uPD7002->digitalvalue = 0; - uPD7002->conversion_counter = 0; -} - -const device_type UPD7002 = &device_creator; - -uPD7002_device::uPD7002_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, UPD7002, "uPD7002", tag, owner, clock, "upd7002", __FILE__) -{ - m_token = global_alloc_clear(uPD7002_t); -} - -//------------------------------------------------- -// device_config_complete - perform any -// operations now that the configuration is -// complete -//------------------------------------------------- - -void uPD7002_device::device_config_complete() -{ -} - -//------------------------------------------------- -// device_start - device-specific startup -//------------------------------------------------- - -void uPD7002_device::device_start() -{ - DEVICE_START_NAME( uPD7002 )(this); -} - -//------------------------------------------------- -// device_reset - device-specific reset -//------------------------------------------------- - -void uPD7002_device::device_reset() -{ - DEVICE_RESET_NAME( uPD7002 )(this); -} diff --git a/src/emu/machine/upd7002.h b/src/emu/machine/upd7002.h index d7456ed0f44..aa6f83e400d 100644 --- a/src/emu/machine/upd7002.h +++ b/src/emu/machine/upd7002.h @@ -11,59 +11,88 @@ #ifndef UPD7002_H_ #define UPD7002_H_ +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +typedef int (*upd7002_get_analogue_func)(device_t *device, int channel_number); +#define UPD7002_GET_ANALOGUE(name) int name(device_t *device, int channel_number ) + +typedef void (*upd7002_eoc_func)(device_t *device, int data); +#define UPD7002_EOC(name) void name(device_t *device, int data ) + + +struct upd7002_interface +{ + upd7002_get_analogue_func get_analogue_func; + upd7002_eoc_func eoc_func; +}; + /*************************************************************************** MACROS ***************************************************************************/ -class uPD7002_device : public device_t +class upd7002_device : public device_t, + public upd7002_interface { public: - uPD7002_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - ~uPD7002_device() { global_free(m_token); } + upd7002_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + ~upd7002_device() {} - // access to legacy token - void *token() const { assert(m_token != NULL); return m_token; } + DECLARE_READ8_MEMBER ( eoc_r ); + DECLARE_READ8_MEMBER ( read ); + DECLARE_WRITE8_MEMBER ( write ); + protected: // device-level overrides virtual void device_config_complete(); virtual void device_start(); virtual void device_reset(); + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); + private: // internal state - void *m_token; + + /* Status Register + D0 and D1 define the currently selected input channel + D2 flag output + D3 0 = 8 bit mode 1 = 12 bit mode + D4 2nd MSB of conversion + D5 MSB of conversion + D6 0 = busy, 1 = not busy (~busy) + D7 0 = conversion completed, 1 = conversion not completed (~EOC) + */ + int m_status; + + /* High data byte + This byte contains the 8 most significant bits of the analogue to digital conversion. */ + int m_data1; + + /* Low data byte + In 12 bit mode: Bits 7 to 4 define the four low order bits of the conversion. + In 8 bit mode. All bits 7 to 4 are inaccurate. + Bits 3 to 0 are always set to low. */ + int m_data0; + + + /* temporary store of the next A to D conversion */ + int m_digitalvalue; + + /* this counter is used to check a full end of conversion has been reached + if the uPD7002 is half way through one conversion and a new conversion is requested + the counter at the end of the first conversion will not match and not be processed + only then at the end of the second conversion will the conversion complete function run */ + int m_conversion_counter; + + enum + { + TIMER_CONVERSION_COMPLETE + }; }; extern const device_type UPD7002; -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -typedef int (*uPD7002_get_analogue_func)(device_t *device, int channel_number); -#define UPD7002_GET_ANALOGUE(name) int name(device_t *device, int channel_number ) - -typedef void (*uPD7002_eoc_func)(device_t *device, int data); -#define UPD7002_EOC(name) void name(device_t *device, int data ) - - -struct uPD7002_interface -{ - uPD7002_get_analogue_func get_analogue_func; - uPD7002_eoc_func EOC_func; -}; - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* Standard handlers */ - -DECLARE_READ8_DEVICE_HANDLER ( uPD7002_EOC_r ); -DECLARE_READ8_DEVICE_HANDLER ( uPD7002_r ); -DECLARE_WRITE8_DEVICE_HANDLER ( uPD7002_w ); - - /*************************************************************************** DEVICE CONFIGURATION MACROS ***************************************************************************/ diff --git a/src/mess/drivers/bbc.c b/src/mess/drivers/bbc.c index 102b45feb1e..44868583a35 100644 --- a/src/mess/drivers/bbc.c +++ b/src/mess/drivers/bbc.c @@ -46,7 +46,6 @@ #include "cpu/m6502/m65sc02.h" #include "machine/6522via.h" #include "machine/mc146818.h" /* RTC & CMOS RAM */ -#include "machine/upd7002.h" #include "bus/centronics/ctronics.h" #include "bus/econet/econet.h" #include "sound/tms5220.h" /* Speech */ @@ -184,7 +183,7 @@ static ADDRESS_MAP_START( bbcb_mem, AS_PROGRAM, 8, bbc_state ) AM_RANGE(0xfe60, 0xfe7f) AM_DEVREADWRITE("via6522_1", via6522_device, read, write) /* fe60-fe7f 6522 VIA USER VIA */ AM_RANGE(0xfe80, 0xfe9f) AM_READWRITE(bbc_disc_r, bbc_disc_w) /* fe80-fe9f 8271 FDC Floppy disc controller */ AM_RANGE(0xfea0, 0xfebf) AM_READ(bbc_fe_r) /* fea0-febf 68B54 ADLC ECONET controller */ - AM_RANGE(0xfec0, 0xfedf) AM_DEVREADWRITE_LEGACY("upd7002", uPD7002_r, uPD7002_w) /* fec0-fedf uPD7002 Analogue to digital converter */ + AM_RANGE(0xfec0, 0xfedf) AM_DEVREADWRITE("upd7002", upd7002_device, read, write) /* fec0-fedf uPD7002 Analogue to digital converter */ AM_RANGE(0xfee0, 0xfeff) AM_READ(bbc_fe_r) /* fee0-feff Tube ULA Tube system interface */ AM_RANGE(0xff00, 0xffff) AM_ROM AM_REGION("user1", 0x43f00) /* ff00-ffff OS Rom (continued) */ ADDRESS_MAP_END @@ -213,7 +212,7 @@ static ADDRESS_MAP_START( bbcbp_mem, AS_PROGRAM, 8, bbc_state ) AM_RANGE(0xfe60, 0xfe7f) AM_DEVREADWRITE("via6522_1", via6522_device, read, write) /* fe60-fe7f 6522 VIA USER VIA */ AM_RANGE(0xfe80, 0xfe9f) AM_READWRITE(bbc_wd1770_read, bbc_wd1770_write) /* fe80-fe9f 1770 FDC Floppy disc controller */ AM_RANGE(0xfea0, 0xfebf) AM_READ(bbc_fe_r) /* fea0-febf 68B54 ADLC ECONET controller */ - AM_RANGE(0xfec0, 0xfedf) AM_DEVREADWRITE_LEGACY("upd7002", uPD7002_r, uPD7002_w) /* fec0-fedf uPD7002 Analogue to digital converter */ + AM_RANGE(0xfec0, 0xfedf) AM_DEVREADWRITE("upd7002", upd7002_device, read, write) /* fec0-fedf uPD7002 Analogue to digital converter */ AM_RANGE(0xfee0, 0xfeff) AM_READ(bbc_fe_r) /* fee0-feff Tube ULA Tube system interface */ AM_RANGE(0xff00, 0xffff) AM_ROM AM_REGION("user1", 0x43f00) /* ff00-ffff OS Rom (continued) */ ADDRESS_MAP_END @@ -243,7 +242,7 @@ static ADDRESS_MAP_START( bbcbp128_mem, AS_PROGRAM, 8, bbc_state ) AM_RANGE(0xfe60, 0xfe7f) AM_DEVREADWRITE("via6522_1", via6522_device, read, write) /* fe60-fe7f 6522 VIA USER VIA */ AM_RANGE(0xfe80, 0xfe9f) AM_READWRITE(bbc_wd1770_read, bbc_wd1770_write) /* fe80-fe9f 1770 FDC Floppy disc controller */ AM_RANGE(0xfea0, 0xfebf) AM_READ(bbc_fe_r) /* fea0-febf 68B54 ADLC ECONET controller */ - AM_RANGE(0xfec0, 0xfedf) AM_DEVREADWRITE_LEGACY("upd7002", uPD7002_r, uPD7002_w) /* fec0-fedf uPD7002 Analogue to digital converter */ + AM_RANGE(0xfec0, 0xfedf) AM_DEVREADWRITE("upd7002", upd7002_device, read, write) /* fec0-fedf uPD7002 Analogue to digital converter */ AM_RANGE(0xfee0, 0xfeff) AM_READ(bbc_fe_r) /* fee0-feff Tube ULA Tube system interface */ AM_RANGE(0xff00, 0xffff) AM_ROM AM_REGION("user1", 0x43f00) /* ff00-ffff OS Rom (continued) */ ADDRESS_MAP_END @@ -1108,8 +1107,8 @@ ROM_START(bbcb) //ROM_LOAD("torchz80_094.bin", 0x0000, 0x2000, CRC(49989bd4) SHA1(62b57c858a3baa4ff943c31f77d331c414772a61)) //ROM_LOAD("torchz80_102.bin", 0x0000, 0x2000, CRC(2eb40a21) SHA1(e6ee738e5f2f8556002b79d18caa8ef21f14e08d)) - ROM_REGION(0x8000, "vsm", 0) /* system speech PHROM */ - ROM_LOAD("phroma.bin", 0x0000, 0x4000, CRC(98e1bf9e) SHA1(b369809275cb67dfd8a749265e91adb2d2558ae6)) + //ROM_REGION(0x8000, "vsm", 0) /* system speech PHROM */ + //ROM_LOAD("phroma.bin", 0x0000, 0x4000, CRC(98e1bf9e) SHA1(b369809275cb67dfd8a749265e91adb2d2558ae6)) ROM_END ROM_START(bbcb_de) diff --git a/src/mess/includes/bbc.h b/src/mess/includes/bbc.h index 518bf5f7620..770c4712ca5 100644 --- a/src/mess/includes/bbc.h +++ b/src/mess/includes/bbc.h @@ -44,6 +44,7 @@ public: m_rs232(*this, RS232_TAG), m_via6522_0(*this, "via6522_0"), m_via6522_1(*this, "via6522_1"), + m_upd7002(*this, "upd7002"), m_ACCCON_IRR(CLEAR_LINE), m_via_system_irq(CLEAR_LINE), m_via_user_irq(CLEAR_LINE), @@ -72,6 +73,7 @@ public: optional_device m_rs232; required_device m_via6522_0; optional_device m_via6522_1; + optional_device m_upd7002; void check_interrupts(); @@ -405,6 +407,6 @@ extern const wd17xx_interface bbc_wd17xx_interface; /* tape support */ -extern const uPD7002_interface bbc_uPD7002; +extern const upd7002_interface bbc_uPD7002; #endif /* BBC_H_ */ diff --git a/src/mess/machine/bbc.c b/src/mess/machine/bbc.c index f8baa294f31..6d08083f8ad 100644 --- a/src/mess/machine/bbc.c +++ b/src/mess/machine/bbc.c @@ -18,7 +18,6 @@ #include "machine/wd17xx.h" #include "imagedev/flopdrv.h" #include "includes/bbc.h" -#include "machine/upd7002.h" #include "machine/i8271.h" #include "machine/mc146818.h" #include "bus/centronics/ctronics.h" @@ -582,7 +581,7 @@ READ8_MEMBER(bbc_state::bbcm_r) return m_acia->data_read(space,0); } if ((myo>=0x10) && (myo<=0x17)) return 0xfe; /* Serial System Chip */ - if ((myo>=0x18) && (myo<=0x1f)) return uPD7002_r(machine().device("upd7002"), space, myo-0x18); /* A to D converter */ + if ((myo>=0x18) && (myo<=0x1f)) return m_upd7002->read(space, myo-0x18); /* A to D converter */ if ((myo>=0x20) && (myo<=0x23)) return 0xfe; /* VideoULA */ if ((myo>=0x24) && (myo<=0x27)) return bbcm_wd1770l_read(space, myo-0x24); /* 1770 */ if ((myo>=0x28) && (myo<=0x2f)) return bbcm_wd1770_read(space, myo-0x28); /* disc control latch */ @@ -616,7 +615,7 @@ WRITE8_MEMBER(bbc_state::bbcm_w) m_acia->data_write(space, 0, data); } if ((myo>=0x10) && (myo<=0x17)) bbc_SerialULA_w(space, myo-0x10, data); /* Serial System Chip */ - if ((myo>=0x18) && (myo<=0x1f)) uPD7002_w(machine().device("upd7002"), space, myo-0x18, data); /* A to D converter */ + if ((myo>=0x18) && (myo<=0x1f)) m_upd7002->write(space, myo-0x18, data); /* A to D converter */ if ((myo>=0x20) && (myo<=0x23)) bbc_videoULA_w(space, myo-0x20, data); /* VideoULA */ if ((myo>=0x24) && (myo<=0x27)) bbcm_wd1770l_write(space, myo-0x24, data); /* 1770 */ if ((myo>=0x28) && (myo<=0x2f)) bbcm_wd1770_write(space, myo-0x28, data); /* disc control latch */ @@ -1210,7 +1209,7 @@ static UPD7002_EOC(BBC_uPD7002_EOC) via_0->write_cb1(data); } -const uPD7002_interface bbc_uPD7002 = +const upd7002_interface bbc_uPD7002 = { BBC_get_analogue_input, BBC_uPD7002_EOC