diff options
author | 2022-09-09 20:39:37 -0400 | |
---|---|---|
committer | 2022-09-09 20:39:37 -0400 | |
commit | 6ad47786319509598312b74e9c67495cd5750ebb (patch) | |
tree | a0f12cf0aee88d061a8c2441ef6149998ea57acb /src/devices | |
parent | 719c36ef8131656dcc4d692647cb6c903263a2e0 (diff) |
m50734: Add A-D converter
Diffstat (limited to 'src/devices')
-rw-r--r-- | src/devices/cpu/m6502/m50734.cpp | 43 | ||||
-rw-r--r-- | src/devices/cpu/m6502/m50734.h | 17 |
2 files changed, 53 insertions, 7 deletions
diff --git a/src/devices/cpu/m6502/m50734.cpp b/src/devices/cpu/m6502/m50734.cpp index a0c89dacc50..dda9a6c8969 100644 --- a/src/devices/cpu/m6502/m50734.cpp +++ b/src/devices/cpu/m6502/m50734.cpp @@ -23,21 +23,21 @@ m50734_device::m50734_device(const machine_config &mconfig, const char *tag, dev , m_data_config("data", ENDIANNESS_LITTLE, 8, 16, 0) , m_port_in_cb(*this) , m_port_out_cb(*this) + , m_analog_in_cb(*this) , m_port_latch{0, 0, 0, 0} , m_port_3state{0, 0, 0, 0} + , m_ad_control(0) + , m_ad_register(0) { program_config.m_internal_map = address_map_constructor(FUNC(m50734_device::internal_map), this); } device_memory_interface::space_config_vector m50734_device::memory_space_config() const { + space_config_vector scv = m740_device::memory_space_config(); if (has_configured_map(AS_DATA)) - return space_config_vector { - std::make_pair(AS_PROGRAM, &program_config), - std::make_pair(AS_DATA, &m_data_config) - }; - else - return m740_device::memory_space_config(); + scv.emplace_back(AS_DATA, &m_data_config); + return scv; } void m50734_device::device_resolve_objects() @@ -46,6 +46,7 @@ void m50734_device::device_resolve_objects() m_port_in_cb[n].resolve_safe(m_port_3state[n]); m_port_in_cb[4].resolve_safe(0); m_port_out_cb.resolve_all_safe(); + m_analog_in_cb.resolve_all_safe(0); } void m50734_device::device_start() @@ -54,10 +55,14 @@ void m50734_device::device_start() space(has_space(AS_DATA) ? AS_DATA : AS_PROGRAM).specific(m_data); + m_ad_timer = timer_alloc(FUNC(m50734_device::ad_complete), this); + save_item(NAME(m_port_latch)); save_item(NAME(m_port_direction)); save_item(NAME(m_p0_function)); save_item(NAME(m_p2_p3_function)); + save_item(NAME(m_ad_control)); + save_item(NAME(m_ad_register)); } void m50734_device::device_reset() @@ -70,6 +75,8 @@ void m50734_device::device_reset() m_port_out_cb[n](m_port_3state[n]); m_p0_function = 0x00; m_p2_p3_function = 0x00; + m_ad_control |= 0x04; + m_ad_timer->adjust(attotime::never); } void m50734_device::read_dummy(u16 adr) @@ -148,9 +155,33 @@ void m50734_device::p2_p3_function_w(u8 data) m_p2_p3_function = data & 0xc7; } +u8 m50734_device::ad_control_r() +{ + return m_ad_control; +} + +void m50734_device::ad_control_w(u8 data) +{ + m_ad_control = data & 0x03; + m_ad_timer->adjust(cycles_to_attotime(72)); // 36 µsec at 8 MHz +} + +TIMER_CALLBACK_MEMBER(m50734_device::ad_complete) +{ + m_ad_register = m_analog_in_cb[m_ad_control & 0x03](); + m_ad_control |= 0x04; +} + +u8 m50734_device::ad_r() +{ + return m_ad_register; +} + void m50734_device::internal_map(address_map &map) { // TODO: timers, etc. + map(0x00e9, 0x00e9).rw(FUNC(m50734_device::ad_control_r), FUNC(m50734_device::ad_control_w)); + map(0x00ea, 0x00ea).r(FUNC(m50734_device::ad_r)); map(0x00eb, 0x00eb).r(FUNC(m50734_device::p4_r)); map(0x00ed, 0x00ed).rw(FUNC(m50734_device::p2_p3_function_r), FUNC(m50734_device::p2_p3_function_w)); map(0x00ee, 0x00ef).rw(FUNC(m50734_device::port_r<3>), FUNC(m50734_device::port_w<3>)); diff --git a/src/devices/cpu/m6502/m50734.h b/src/devices/cpu/m6502/m50734.h index 4e71585e821..425b6a34e34 100644 --- a/src/devices/cpu/m6502/m50734.h +++ b/src/devices/cpu/m6502/m50734.h @@ -66,6 +66,10 @@ public: auto p3_in_cb() { return m_port_in_cb[3].bind(); } auto p3_out_cb() { return m_port_out_cb[3].bind(); } auto p4_in_cb() { return m_port_in_cb[4].bind(); } + auto an0_in_cb() { return m_analog_in_cb[0].bind(); } + auto an1_in_cb() { return m_analog_in_cb[1].bind(); } + auto an2_in_cb() { return m_analog_in_cb[2].bind(); } + auto an3_in_cb() { return m_analog_in_cb[3].bind(); } // port three-state output configuration void set_p0_3state(u8 value) { assert(!configured()); m_port_3state[0] = value; } @@ -92,7 +96,6 @@ protected: virtual void write_data(u16 adr, u8 val) override; private: - void internal_map(address_map &map); template <int N> u8 port_r(offs_t offset); template <int N> void port_w(offs_t offset, u8 data); u8 p4_r(); @@ -100,18 +103,30 @@ private: void p0_function_w(u8 data); u8 p2_p3_function_r(); void p2_p3_function_w(u8 data); + u8 ad_control_r(); + void ad_control_w(u8 data); + u8 ad_r(); + + TIMER_CALLBACK_MEMBER(ad_complete); + + void internal_map(address_map &map); const address_space_config m_data_config; memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_data; devcb_read8::array<5> m_port_in_cb; devcb_write8::array<4> m_port_out_cb; + devcb_read8::array<4> m_analog_in_cb; + + emu_timer *m_ad_timer; u8 m_port_latch[4]; u8 m_port_direction[4]; u8 m_port_3state[4]; u8 m_p0_function; u8 m_p2_p3_function; + u8 m_ad_control; + u8 m_ad_register; }; DECLARE_DEVICE_TYPE(M50734, m50734_device) |