From de57ef7b9707af44358e703a70433294ba79c76e Mon Sep 17 00:00:00 2001 From: AJR Date: Sat, 17 Aug 2019 22:38:28 -0400 Subject: atronic.cpp: Add more onboard devices, including new PCF8584 skeleton (nw) --- scripts/src/machine.lua | 12 ++ scripts/target/mame/arcade.lua | 4 +- scripts/target/mame/mess.lua | 1 + src/devices/machine/pcf8584.cpp | 245 ++++++++++++++++++++++++++++++++++++++++ src/devices/machine/pcf8584.h | 101 +++++++++++++++++ src/mame/drivers/atronic.cpp | 41 ++++++- 6 files changed, 400 insertions(+), 4 deletions(-) create mode 100644 src/devices/machine/pcf8584.cpp create mode 100644 src/devices/machine/pcf8584.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index f660735d7ad..97dfa1465e2 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2265,6 +2265,18 @@ if (MACHINES["PCF8583"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/pcf8584.h,MACHINES["PCF8584"] = true +--------------------------------------------------- + +if (MACHINES["PCF8584"]~=null) then + files { + MAME_DIR .. "src/devices/machine/pcf8584.cpp", + MAME_DIR .. "src/devices/machine/pcf8584.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/pcf8593.h,MACHINES["PCF8593"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index b613c0e6f56..b31cf941291 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -446,7 +446,7 @@ MACHINES["DS1204"] = true MACHINES["DS1205"] = true MACHINES["DS1302"] = true --MACHINES["DS1315"] = true ---MACHINES["DS1386"] = true +MACHINES["DS1386"] = true MACHINES["DS17X85"] = true MACHINES["DS1994"] = true MACHINES["DS2401"] = true @@ -558,6 +558,8 @@ MACHINES["OUTPUT_LATCH"] = true MACHINES["PC_FDC"] = true MACHINES["PC_LPT"] = true --MACHINES["PCCARD"] = true +--MACHINES["PCF8583"] = true +MACHINES["PCF8584"] = true MACHINES["PCF8593"] = true MACHINES["PCI"] = true MACHINES["PCKEYBRD"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 82f5d5b70b3..33d9f63f578 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -568,6 +568,7 @@ MACHINES["PC_FDC"] = true MACHINES["PC_LPT"] = true MACHINES["PCCARD"] = true MACHINES["PCF8583"] = true +--MACHINES["PCF8584"] = true MACHINES["PCF8593"] = true MACHINES["PCI"] = true MACHINES["PCKEYBRD"] = true diff --git a/src/devices/machine/pcf8584.cpp b/src/devices/machine/pcf8584.cpp new file mode 100644 index 00000000000..ad2d54f676d --- /dev/null +++ b/src/devices/machine/pcf8584.cpp @@ -0,0 +1,245 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Philips PCF8584 I²C Bus Controller + + This is a comprehensive protocol interface chip for Philips' I²C + serial bus, supporting master and slave modes for both receiving + and transmitting data. The register interface is similar but not + identical to that provided by certain Philips 80C51-derived + microcontrollers. + + TODO: actually implement the protocol + +**********************************************************************/ + +#include "emu.h" +#include "pcf8584.h" + +#define VERBOSE 1 +#include "logmacro.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// device type definition +DEFINE_DEVICE_TYPE(PCF8584, pcf8584_device, "pcf8584", "PCF8584 I2C Bus Controller") + + +//************************************************************************** +// LOOKUP TABLES +//************************************************************************** + +// prescalers based on 1.5 MHz internal frequency +const u32 pcf8584_device::s_prescaler[4] = { 50, 100, 400, 3000 }; + +// dividers for clock input +const u32 pcf8584_device::s_divider[8] = { 2, 2, 2, 2, 3, 4, 5, 8 }; + +// debugging strings +const char *const pcf8584_device::s_nominal_clock[8] = { "3", "3", "3", "3", "4.43", "6", "8", "12" }; +const char *const pcf8584_device::s_bus_function[4] = { "NOP", "stop", "start", "data chaining" }; + + +//************************************************************************** +// DEVICE CONSTRUCTION AND INITIALIZATION +//************************************************************************** + +//------------------------------------------------- +// pcf8584_device - constructor +//------------------------------------------------- + +pcf8584_device::pcf8584_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, PCF8584, tag, owner, clock) + , m_sda_callback(*this) + , m_sda_out_callback(*this) + , m_scl_callback(*this) + , m_int_callback(*this) + , m_68k_bus(false) + , m_s0_data_buffer(0) + , m_s0_shift_register(0) + , m_s0_own_address(0) + , m_s1_status(0) + , m_s1_control(0) + , m_s2_clock(0) + , m_s3_vector(0) +{ +} + + +//------------------------------------------------- +// device_resolve_objects - resolve objects that +// may be needed for other devices to set +// initial conditions at start time +//------------------------------------------------- + +void pcf8584_device::device_resolve_objects() +{ + m_sda_callback.resolve_safe(1); + m_sda_out_callback.resolve_safe(); + m_scl_callback.resolve_safe(); + m_int_callback.resolve_safe(); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void pcf8584_device::device_start() +{ + // register internal state + save_item(NAME(m_s0_data_buffer)); + save_item(NAME(m_s0_shift_register)); + save_item(NAME(m_s0_own_address)); + save_item(NAME(m_s1_status)); + save_item(NAME(m_s1_control)); + save_item(NAME(m_s2_clock)); + save_item(NAME(m_s3_vector)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void pcf8584_device::device_reset() +{ + // reset all flags except for PIN + m_s1_status = 0x80; + m_s1_control = 0x00; + + // vector isn't actually set to 0x0f until R/_W is pulled low without _CS, but who's counting? + m_s3_vector = m_68k_bus ? 0x0f : 0x00; +} + + +//************************************************************************** +// REGISTER INTERFACE +//************************************************************************** + +//------------------------------------------------- +// set_shift_register - write data to S0 +//------------------------------------------------- + +void pcf8584_device::set_shift_register(u8 data) +{ + LOG("%s: Shift register = %s%02XH\n", machine().describe_context(), data >= 0xa0 ? "0" : "", data); + m_s0_shift_register = data; +} + + +//------------------------------------------------- +// set_own_address - write data to S0' +//------------------------------------------------- + +void pcf8584_device::set_own_address(u8 data) +{ + LOG("%s: Own address = %s%02XH\n", machine().describe_context(), (data & 0x7f) >= 0x60 ? "0" : "", (data << 1) & 0xfe); + m_s0_own_address = data; +} + + +//------------------------------------------------- +// set_control - write data to S1 +//------------------------------------------------- + +void pcf8584_device::set_control(u8 data) +{ + if (BIT(data, 7) != BIT(m_s1_status, 7)) + { + LOG("%s: PIN %sactive\n", machine().describe_context(), BIT(data, 7) ? "in" : ""); + if (BIT(data, 7)) + m_s1_status = 0x80; + else + m_s1_status &= 0x7f; + } + + if (BIT(data, 6) != BIT(m_s1_control, 6)) + LOG("%s: Serial output %sabled%s\n", machine().describe_context(), BIT(data, 6) ? "en" : "dis", + (data & 0x60) == 0x60 ? " (4-wire)" : ""); + if (BIT(data, 3) != BIT(m_s1_control, 3)) + LOG("%s: Interrupt output %sabled\n", machine().describe_context(), BIT(data, 3) ? "en" : "dis"); + if ((data & 0x06) != (m_s1_control & 0x06)) + LOG("%s: Bus function = %s\n", machine().describe_context(), s_bus_function[(data & 0x06) >> 1]); + if (BIT(data, 0) != BIT(m_s1_control, 0)) + LOG("%s: Acknowledge pulse %sabled\n", machine().describe_context(), BIT(data, 0) ? "en" : "dis"); + + m_s1_control = data & 0x7f; +} + + +//------------------------------------------------- +// set_clock_frequency - write data to S2 +//------------------------------------------------- + +void pcf8584_device::set_clock_frequency(u8 data) +{ + LOG("%s: SCL frequency = %.2f kHz (fCLK is nominally %s MHz)\n", machine().describe_context(), + (clocks_to_attotime(s_divider[(data & 0x1c) >> 2] * s_prescaler[data & 0x03]) / 3).as_hz() / 1000.0, + s_nominal_clock[(data & 0x1c) >> 2]); + m_s2_clock = data & 0x1f; +} + + +//------------------------------------------------- +// set_vector - write data to S3 +//------------------------------------------------- + +void pcf8584_device::set_vector(u8 data) +{ + LOG("%s: Interrupt vector = %s%02XH\n", machine().describe_context(), data >= 0xa0 ? "0" : "", data); + m_s3_vector = data; +} + + +//------------------------------------------------- +// read - input from register to bus +//------------------------------------------------- + +u8 pcf8584_device::read(offs_t offset) +{ + if (BIT(offset, 0)) + return eso() ? m_s1_status : m_s1_control | (m_s1_status & 0x80); + else if (es2() && !es1()) + return m_s3_vector; + else if (eso()) + return m_s0_data_buffer; + else if (es1()) + return m_s2_clock; + else + return m_s0_own_address; +} + + +//------------------------------------------------- +// write - output from bus to register +//------------------------------------------------- + +void pcf8584_device::write(offs_t offset, u8 data) +{ + if (BIT(offset, 0)) + set_control(data); + else if (es2() && !es1()) + set_vector(data); + else if (eso()) + set_shift_register(data); + else if (es1()) + set_clock_frequency(data); + else + set_own_address(data); + +} + + +//------------------------------------------------- +// iack - acknowledge interrupt with vector +//------------------------------------------------- + +IRQ_CALLBACK_MEMBER(pcf8584_device::iack) +{ + return m_s3_vector; +} diff --git a/src/devices/machine/pcf8584.h b/src/devices/machine/pcf8584.h new file mode 100644 index 00000000000..eda20a4df28 --- /dev/null +++ b/src/devices/machine/pcf8584.h @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:AJR +/********************************************************************** + + Philips PCF8584 I²C Bus Controller + +*********************************************************************** + ____ ____ + CLK 1 |* \_/ | 20 Vdd + (SDA OUT) SDA 2 | | 19 _RESET/_STROBE + (SCL IN) SCL 3 | | 18 _WR (R/_W) + (SDA IN) _IACK 4 | | 17 _CS + (SCL OUT) _INT 5 | | 16 _RD (_DTACK) + A0 6 | PCF8584 | 15 DB7 + DB0 7 | | 14 DB6 + DB1 8 | | 13 DB5 + DB2 9 | | 12 DB4 + Vss 10 |___________| 11 DB3 + +**********************************************************************/ + +#ifndef MAME_MACHINE_PCF8584_H +#define MAME_MACHINE_PCF8584_H 1 + +#pragma once + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> pcf8584_device + +class pcf8584_device : public device_t +{ + static const u32 s_prescaler[4]; + static const u32 s_divider[8]; + static const char *const s_nominal_clock[8]; + static const char *const s_bus_function[4]; + +public: + // device type constructor + pcf8584_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // callback configuration + auto sda_cb() { return m_sda_callback.bind(); } + auto sda_out_cb() { return m_sda_out_callback.bind(); } + auto scl_cb() { return m_scl_callback.bind(); } + auto int_cb() { return m_int_callback.bind(); } + + // bus type configuration + void set_80xx_bus() { m_68k_bus = false; } + void set_68000_bus() { m_68k_bus = true; } + + // CPU interface + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + IRQ_CALLBACK_MEMBER(iack); + +protected: + // device-specific overrides + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + // internal helpers + bool eso() const { return BIT(m_s1_control, 6); } + bool es1() const { return BIT(m_s1_control, 5); } + bool es2() const { return BIT(m_s1_control, 4); } + bool eni() const { return BIT(m_s1_control, 3); } + + // write helpers + void set_shift_register(u8 data); + void set_own_address(u8 data); + void set_control(u8 data); + void set_clock_frequency(u8 data); + void set_vector(u8 data); + + // callback objects + devcb_read_line m_sda_callback; + devcb_write_line m_sda_out_callback; + devcb_write_line m_scl_callback; + devcb_write_line m_int_callback; + + // misc. parameters + bool m_68k_bus; + + // internal registers + u8 m_s0_data_buffer; + u8 m_s0_shift_register; + u8 m_s0_own_address; + u8 m_s1_status; + u8 m_s1_control; + u8 m_s2_clock; + u8 m_s3_vector; +}; + +// device type declaration +DECLARE_DEVICE_TYPE(PCF8584, pcf8584_device) + +#endif // MAME_MACHINE_PCF8584_H diff --git a/src/mame/drivers/atronic.cpp b/src/mame/drivers/atronic.cpp index f518c27594e..95ebf7718fe 100644 --- a/src/mame/drivers/atronic.cpp +++ b/src/mame/drivers/atronic.cpp @@ -317,6 +317,9 @@ Markings bottom: 6 470.5020 00.07 #include "emu.h" #include "cpu/z180/z180.h" #include "cpu/tms34010/tms34010.h" +#include "machine/ds1386.h" +#include "machine/pcf8584.h" +#include "machine/z80scc.h" #include "emupal.h" #include "screen.h" #include "video/ramdac.h" @@ -336,6 +339,11 @@ public: void atronic(machine_config &config); private: + u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); + + u8 serial_r(); + void serial_w(u8 data); + void atronic_map(address_map &map); void atronic_portmap(address_map &map); @@ -357,18 +365,39 @@ private: }; +u32 atronic_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) +{ + return 0; +} + + +u8 atronic_state::serial_r() +{ + // bit 3 = serial input? + return 0xff; +} + +void atronic_state::serial_w(u8 data) +{ + // bits 7 & 6 = serial clock and data? +} + + void atronic_state::atronic_map(address_map &map) { map(0x00000, 0x7ffff).rom(); - map(0xf8000, 0xfffff).ram(); + map(0xf8000, 0xfffff).rw("timekpr", FUNC(ds1386_32k_device::data_r), FUNC(ds1386_32k_device::data_w)); } void atronic_state::atronic_portmap(address_map &map) { -// ADDRESS_MAP_GLOBAL_MASK(0xff) map.unmap_value_high(); - map(0x00, 0x3f).ram(); + map(0x0000, 0x003f).noprw(); // internal registers + map(0x0068, 0x0069).rw("i2cbc", FUNC(pcf8584_device::read), FUNC(pcf8584_device::write)); + map(0x0074, 0x0074).r(FUNC(atronic_state::serial_r)); + map(0x0078, 0x007b).rw("scc", FUNC(scc85c30_device::ab_dc_r), FUNC(scc85c30_device::ab_dc_w)); + map(0x0270, 0x0270).w(FUNC(atronic_state::serial_w)); } @@ -440,6 +469,12 @@ void atronic_state::atronic(machine_config &config) m_maincpu->set_addrmap(AS_IO, &atronic_state::atronic_portmap); m_maincpu->set_vblank_int("screen", FUNC(atronic_state::irq0_line_hold)); + DS1386_32K(config, "timekpr", 32768); + + PCF8584(config, "i2cbc", 3000000); + + SCC85C30(config, "scc", 5000000); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); m_screen->set_raw(VIDEO_CLOCK/2, 640, 0, 512, 257, 0, 224); // ?? m_screen->set_screen_update("tms", FUNC(tms34020_device::tms340x0_rgb32)); -- cgit v1.2.3