diff options
author | 2019-03-12 03:28:24 +0100 | |
---|---|---|
committer | 2019-03-12 03:28:36 +0100 | |
commit | 62d9f7d087f9f21dcb1ad7a0dde6106f43d3d883 (patch) | |
tree | a23ee43392519e7e70b4e6631c34c01d780635a8 | |
parent | 54588121aec9ec14d70b44f0245ef1a69d8cff4d (diff) |
f3853: added 3851 and preliminary 38T56 (nw)
-rw-r--r-- | src/devices/cpu/f8/f8.cpp | 4 | ||||
-rw-r--r-- | src/devices/machine/f3853.cpp | 238 | ||||
-rw-r--r-- | src/devices/machine/f3853.h | 60 | ||||
-rw-r--r-- | src/mame/drivers/aci_boris.cpp | 10 | ||||
-rw-r--r-- | src/mame/drivers/chesstrv.cpp | 20 | ||||
-rw-r--r-- | src/mame/drivers/gamemachine.cpp | 19 | ||||
-rw-r--r-- | src/mame/drivers/mk1.cpp | 13 |
7 files changed, 264 insertions, 100 deletions
diff --git a/src/devices/cpu/f8/f8.cpp b/src/devices/cpu/f8/f8.cpp index a93b7aebd3a..ce09d9ca835 100644 --- a/src/devices/cpu/f8/f8.cpp +++ b/src/devices/cpu/f8/f8.cpp @@ -19,7 +19,9 @@ * - 3851 Program Storage Unit (PSU) * - 3852 Dynamic Memory Interface (DMI) * - 3853 Static Memory Interface (SMI) + * - 3854 Direct Memory Access Controller (DMAC) * - 3856 Program Storage Unit (PSU) + * - 38T56 Program Storage Unit (PSU) * - 3861 Peripheral Input/Output (PIO) * - 3871 Peripheral Input/Output (PIO) * @@ -35,7 +37,7 @@ * * Combined packages: * - 3859 = 3850 + 3851 - * - 3870 = 3850 + 3856 + * - 3870 = 3850 + 38T56 * - 3872 = 3870 + extra 2KB ROM * - 3873 = 3870 + extra 64 bytes executable RAM * diff --git a/src/devices/machine/f3853.cpp b/src/devices/machine/f3853.cpp index 85b982634bb..ef08b087d5c 100644 --- a/src/devices/machine/f3853.cpp +++ b/src/devices/machine/f3853.cpp @@ -1,19 +1,19 @@ // license:BSD-3-Clause -// copyright-holders:Wilbert Pol +// copyright-holders:Wilbert Pol, hap /********************************************************************** - Fairchild F3853 SRAM interface with integrated interrupt - controller and timer (SMI) +Fairchild F3853 SRAM interface with integrated interrupt +controller and timer (SMI) - This chip is a timer shift register, basically the same as in the - F3851. +This chip is a timer shift register, basically the same as in the +F3851. - Based on a datasheet obtained from www.freetradezone.com +Based on a datasheet obtained from www.freetradezone.com - 8-bit shift register: - Feedback in0 = !((out3 ^ out4) ^ (out5 ^ out7)) - Interrupts are at 0xfe - 0xff stops the register (0xfe is never reached) +8-bit shift register: +Feedback in0 = !((out3 ^ out4) ^ (out5 ^ out7)) +Interrupts are at 0xfe +0xff stops the register (0xfe is never reached) **********************************************************************/ @@ -21,18 +21,15 @@ #include "f3853.h" - -/*************************************************************************** - IMPLEMENTATION -***************************************************************************/ - //************************************************************************** // LIVE DEVICE //************************************************************************** // device type definition DEFINE_DEVICE_TYPE(F3853, f3853_device, "f3853_device", "F3853 SMI") +DEFINE_DEVICE_TYPE(F3851, f3851_device, "f3851_device", "F3851 PSU") DEFINE_DEVICE_TYPE(F3856, f3856_device, "f3856_device", "F3856 PSU") +DEFINE_DEVICE_TYPE(F38T56, f38t56_device, "f38t56_device", "F38T56 PSU") //------------------------------------------------- // f3853_device - constructor @@ -52,8 +49,26 @@ f3853_device::f3853_device(const machine_config &mconfig, const char *tag, devic f3853_device(mconfig, F3853, tag, owner, clock) { } +f3851_device::f3851_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + f3853_device(mconfig, type, tag, owner, clock), + m_read_port{{*this}, {*this}}, + m_write_port{{*this}, {*this}} +{ } + +f3851_device::f3851_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + f3851_device(mconfig, F3851, tag, owner, clock) +{ } + +f3856_device::f3856_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : + f3851_device(mconfig, type, tag, owner, clock) +{ } + f3856_device::f3856_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : - f3853_device(mconfig, F3856, tag, owner, clock) + f3856_device(mconfig, F3856, tag, owner, clock) +{ } + +f38t56_device::f38t56_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + f3856_device(mconfig, F38T56, tag, owner, clock) { } @@ -64,12 +79,25 @@ void f3853_device::device_resolve_objects() m_int_daisy_chain_callback.bind_relative_to(*owner()); } +void f3851_device::device_resolve_objects() +{ + f3853_device::device_resolve_objects(); + + // 2 I/O ports + for (devcb_read8 &cb : m_read_port) + cb.resolve_safe(0); + for (devcb_write8 &cb : m_write_port) + cb.resolve_safe(); +} + + //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void f3853_device::device_start() { + // lookup table for 3851/3853 lfsr timer uint8_t reg = 0xfe; // Known to get 0xfe after 255 cycles for(int i = reg; i >= 0; i--) { @@ -94,6 +122,18 @@ void f3853_device::device_start() save_item(NAME(m_external_interrupt_line)); } +void f3856_device::device_start() +{ + f3853_device::device_start(); + + m_timer_count = 0; + m_timer_modulo = 0; + m_timer_start = false; + + save_item(NAME(m_timer_count)); + save_item(NAME(m_timer_modulo)); + save_item(NAME(m_timer_start)); +} //------------------------------------------------- // device_reset - device-specific reset @@ -174,46 +214,40 @@ WRITE_LINE_MEMBER(f3853_device::pri_in_w) READ8_MEMBER(f3853_device::read) { - uint8_t data = 0; - - switch (offset) + switch (offset & 3) { + // interrupt vector case 0: - data = m_int_vector >> 8; - break; - + return m_int_vector >> 8; case 1: - data = m_int_vector & 0xff; - break; + return m_int_vector & 0xff; - case 2: // Interrupt control; not readable - case 3: // Timer; not readable - break; + // interrupt control, timer: write-only + default: + return 0; } - - return data; } WRITE8_MEMBER(f3853_device::write) { - switch(offset) + switch (offset & 3) { + // interrupt vector case 0: m_int_vector = (data << 8) | (m_int_vector & 0x00ff); break; - case 1: m_int_vector = data | (m_int_vector & 0xff00); break; // interrupt control case 2: - m_external_enable = ((data & 3) == 1); - m_timer_enable = ((data & 3) == 3); + m_external_enable = (data & 3) == 1; + m_timer_enable = (data & 3) == 3; set_interrupt_request_line(); break; - // timer + // set timer case 3: m_request_flipflop = false; set_interrupt_request_line(); @@ -223,58 +257,146 @@ WRITE8_MEMBER(f3853_device::write) } -READ8_MEMBER(f3856_device::read) +READ8_MEMBER(f3851_device::read) { - uint8_t data = 0; + switch (offset & 3) + { + // I/O ports + case 0: case 1: + return (m_read_port[offset & 1])(offs_t(offset & 1)); - switch (offset) + // interrupt control, timer: write-only + default: + return 0; + } +} + +WRITE8_MEMBER(f3851_device::write) +{ + switch (offset & 3) { - case 0: + // I/O ports + case 0: case 1: + (m_write_port[offset & 1])(offs_t(offset & 1), data); break; - case 1: + // interrupt control, timer: same as 3853 + case 2: case 3: + f3853_device::write(space, offset, data); break; + } +} - case 2: - break; - case 3: - break; +void f3856_device::timer_start(uint8_t value) +{ + m_timer_count = value; + attotime period = (m_timer_start) ? (attotime::from_hz(clock()) * m_prescaler) : attotime::never; + + m_timer->adjust(period); +} + +TIMER_CALLBACK_MEMBER(f3856_device::timer_callback) +{ + if (--m_timer_count == 0) + { + m_timer_count = m_timer_modulo; + if (m_timer_enable) + { + m_request_flipflop = true; + set_interrupt_request_line(); + } } - return data; + timer_start(m_timer_count); } -WRITE8_MEMBER(f3856_device::write) +READ8_MEMBER(f3856_device::read) { - switch(offset) + switch (offset & 3) { - case 0: - break; + // timer: active counter + case 3: + return m_timer_count; - case 1: + // other: same as 3851 + default: + return f3851_device::read(space, offset); + } +} + +WRITE8_MEMBER(f3856_device::write) +{ + switch (offset & 3) + { + // I/O ports: same as 3851 + case 0: case 1: + f3851_device::write(space, offset, data); break; // interrupt control case 2: - // timer prescaler in high 3 bits - static const u8 prescaler[8] = { 0, 2, 5, 10, 20, 40, 100, 200 }; + { + // timer prescaler + static const u8 prescaler[8] = { 32, 128, 8, 2 }; m_prescaler = prescaler[data >> 5 & 7]; - // TODO: event counter mode - if (m_prescaler == 0) - m_prescaler = 100; + // start/stop timer + bool prev = m_timer_start; + m_timer_start = bool(~data & 0x10); + if (m_timer_start != prev) + timer_start(m_timer_count); - m_external_enable = bool(data & 1); + // enable interrupts + m_external_enable = (data & 3) == 1 || (data & 3) == 2; m_timer_enable = bool(data & 2); set_interrupt_request_line(); break; + } - // timer + // set timer case 3: - m_request_flipflop = false; + f3853_device::write(space, offset, data); + break; + } +} + + +WRITE8_MEMBER(f38t56_device::write) +{ + switch (offset & 3) + { + // I/O ports: same as 3851 + default: + f3851_device::write(space, offset, data); + break; + + // interrupt control + case 2: + { + // timer prescaler + m_prescaler = 200; + if (~data & 0x80) m_prescaler /= 20; + if (~data & 0x40) m_prescaler /= 5; + if (~data & 0x20) m_prescaler /= 2; + + // start/stop timer + bool prev = m_timer_start; + m_timer_start = bool(data & 8); + if (m_timer_start != prev) + timer_start(m_timer_count); + + // enable interrupts + m_external_enable = bool(data & 1); + m_timer_enable = bool(data & 2); set_interrupt_request_line(); - timer_start(data); + break; + } + + // set timer + case 3: + m_timer_modulo = data; + f3853_device::write(space, offset, data); break; } } diff --git a/src/devices/machine/f3853.h b/src/devices/machine/f3853.h index d0fbfc09406..523864dd9f8 100644 --- a/src/devices/machine/f3853.h +++ b/src/devices/machine/f3853.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Wilbert Pol +// copyright-holders:Wilbert Pol, hap /*************************************************************************** Fairchild F3853 SRAM interface with integrated interrupt @@ -51,9 +51,6 @@ public: // construction/destruction f3853_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // interrupt vector is a mask option on 3851 and 3856 - void set_int_vector(u16 vector) { m_int_vector = vector; } - auto int_req_callback() { return m_int_req_callback.bind(); } auto pri_out_callback() { return m_pri_out_callback.bind(); } template<typename Object> void set_int_daisy_chain_callback(Object &&cb) { m_int_daisy_chain_callback = std::forward<Object>(cb); } @@ -64,7 +61,7 @@ public: DECLARE_WRITE_LINE_MEMBER(ext_int_w); DECLARE_WRITE_LINE_MEMBER(pri_in_w); - TIMER_CALLBACK_MEMBER(timer_callback); + virtual TIMER_CALLBACK_MEMBER(timer_callback); IRQ_CALLBACK_MEMBER(int_acknowledge); @@ -80,7 +77,7 @@ protected: uint16_t external_interrupt_vector() const { return m_int_vector | uint16_t(0x0080); } void set_interrupt_request_line(); - void timer_start(uint8_t value); + virtual void timer_start(uint8_t value); devcb_write_line m_int_req_callback; devcb_write_line m_pri_out_callback; @@ -101,17 +98,66 @@ protected: uint8_t m_value_to_cycle[0x100]; }; -class f3856_device : public f3853_device +class f3851_device : public f3853_device +{ +public: + f3851_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // interrupt vector is a mask option on 3851 and 3856 + void set_int_vector(u16 vector) { m_int_vector = vector; } + + // bidirectional I/O ports A and B + auto read_a() { return m_read_port[0].bind(); } + auto read_b() { return m_read_port[1].bind(); } + auto write_a() { return m_write_port[0].bind(); } + auto write_b() { return m_write_port[1].bind(); } + + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; + +protected: + f3851_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_resolve_objects() override; + + devcb_read8 m_read_port[2]; + devcb_write8 m_write_port[2]; +}; + +class f3856_device : public f3851_device { public: f3856_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); virtual DECLARE_READ8_MEMBER(read) override; virtual DECLARE_WRITE8_MEMBER(write) override; + + virtual TIMER_CALLBACK_MEMBER(timer_callback) override; + +protected: + f3856_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + virtual void device_start() override; + + virtual void timer_start(uint8_t value) override; + + u8 m_timer_count; + u8 m_timer_modulo; + bool m_timer_start; +}; + +class f38t56_device : public f3856_device +{ +public: + f38t56_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual DECLARE_WRITE8_MEMBER(write) override; }; // device type definition DECLARE_DEVICE_TYPE(F3853, f3853_device) +DECLARE_DEVICE_TYPE(F3851, f3851_device) DECLARE_DEVICE_TYPE(F3856, f3856_device) +DECLARE_DEVICE_TYPE(F38T56, f38t56_device) #endif // MAME_MACHINE_F3853_H diff --git a/src/mame/drivers/aci_boris.cpp b/src/mame/drivers/aci_boris.cpp index c0c33da7bab..2d565714354 100644 --- a/src/mame/drivers/aci_boris.cpp +++ b/src/mame/drivers/aci_boris.cpp @@ -159,7 +159,7 @@ void boris_state::main_io(address_map &map) { map(0x00, 0x00).rw(FUNC(boris_state::input_r), FUNC(boris_state::mux_w)); map(0x01, 0x01).w(FUNC(boris_state::digit_w)); - map(0x0c, 0x0f).rw("f3853", FUNC(f3853_device::read), FUNC(f3853_device::write)); + map(0x0c, 0x0f).rw("smi", FUNC(f3853_device::read), FUNC(f3853_device::write)); } @@ -206,13 +206,13 @@ INPUT_PORTS_END void boris_state::boris(machine_config &config) { /* basic machine hardware */ - F8(config, m_maincpu, 2_MHz_XTAL); + F8(config, m_maincpu, 2_MHz_XTAL); // MK3850, 2MHz XTAL according to schematics m_maincpu->set_addrmap(AS_PROGRAM, &boris_state::main_map); m_maincpu->set_addrmap(AS_IO, &boris_state::main_io); - m_maincpu->set_irq_acknowledge_callback("f3853", FUNC(f3853_device::int_acknowledge)); + m_maincpu->set_irq_acknowledge_callback("smi", FUNC(f3853_device::int_acknowledge)); - f3853_device &f3853(F3853(config, "f3853", 2_MHz_XTAL)); - f3853.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); + f3853_device &smi(F3853(config, "smi", 2_MHz_XTAL)); + smi.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); /* video hardware */ for (int i = 0; i < 8; i++) diff --git a/src/mame/drivers/chesstrv.cpp b/src/mame/drivers/chesstrv.cpp index 6390002269f..d525b75dfc8 100644 --- a/src/mame/drivers/chesstrv.cpp +++ b/src/mame/drivers/chesstrv.cpp @@ -174,9 +174,7 @@ void borisdpl_state::borisdpl_io(address_map &map) { map(0x00, 0x00).rw(FUNC(borisdpl_state::keypad_r), FUNC(borisdpl_state::matrix_w)); map(0x01, 0x01).w(FUNC(borisdpl_state::display_w)); - map(0x04, 0x07).rw("f3856", FUNC(f3856_device::read), FUNC(f3856_device::write)); - map(0x04, 0x04).rw(FUNC(borisdpl_state::ram_r), FUNC(borisdpl_state::ram_w)); - map(0x05, 0x05).rw(FUNC(borisdpl_state::ram_addr_r), FUNC(borisdpl_state::ram_addr_w)); + map(0x04, 0x07).rw("psu", FUNC(f38t56_device::read), FUNC(f38t56_device::write)); } static INPUT_PORTS_START( chesstrv ) @@ -274,14 +272,18 @@ void chesstrv_state::chesstrv(machine_config &config) void borisdpl_state::borisdpl(machine_config &config) { /* basic machine hardware */ - F8(config, m_maincpu, 4000000/2); // Motorola SC80265P, frequency guessed + F8(config, m_maincpu, 3000000/2); // Motorola SC80265P, frequency approximated from video reference m_maincpu->set_addrmap(AS_PROGRAM, &borisdpl_state::chesstrv_mem); m_maincpu->set_addrmap(AS_IO, &borisdpl_state::borisdpl_io); - m_maincpu->set_irq_acknowledge_callback("f3856", FUNC(f3856_device::int_acknowledge)); - - f3856_device &f3856(F3856(config, "f3856", 4000000/2)); - f3856.set_int_vector(0x5020); - f3856.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); + m_maincpu->set_irq_acknowledge_callback("psu", FUNC(f38t56_device::int_acknowledge)); + + f38t56_device &psu(F38T56(config, "psu", 3000000/2)); + psu.set_int_vector(0x5020); + psu.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); + psu.read_a().set(FUNC(borisdpl_state::ram_r)); + psu.write_a().set(FUNC(borisdpl_state::ram_w)); + psu.read_b().set(FUNC(borisdpl_state::ram_addr_r)); + psu.write_b().set(FUNC(borisdpl_state::ram_addr_w)); /* video hardware */ config.set_default_layout(layout_borisdpl); diff --git a/src/mame/drivers/gamemachine.cpp b/src/mame/drivers/gamemachine.cpp index 0ef20a73611..75f0a6ae379 100644 --- a/src/mame/drivers/gamemachine.cpp +++ b/src/mame/drivers/gamemachine.cpp @@ -28,12 +28,12 @@ hardware notes: TODO: - discrete sound, currently it's emulated crudely, just enough to make it beep when supposed to -- MK3870 is not emulated in MAME, plain F8 is used here instead ******************************************************************************/ #include "emu.h" #include "cpu/f8/f8.h" +#include "machine/f3853.h" #include "machine/timer.h" #include "sound/beep.h" #include "speaker.h" @@ -79,7 +79,6 @@ private: DECLARE_WRITE8_MEMBER(digit_w); DECLARE_READ8_MEMBER(input_r); DECLARE_WRITE8_MEMBER(sound_w); - DECLARE_READ8_MEMBER(timer_r); u16 m_inp_mux; u16 m_digit_select; @@ -190,12 +189,6 @@ WRITE8_MEMBER(tgm_state::sound_w) //.. } -READ8_MEMBER(tgm_state::timer_r) -{ - // MK3870 internal timer register (used as RNG here) - return machine().rand(); -} - /****************************************************************************** @@ -212,9 +205,7 @@ void tgm_state::main_io(address_map &map) { map(0x00, 0x00).w(FUNC(tgm_state::mux1_w)); map(0x01, 0x01).rw(FUNC(tgm_state::input_r), FUNC(tgm_state::mux2_w)); - map(0x04, 0x04).w(FUNC(tgm_state::sound_w)); - map(0x05, 0x05).w(FUNC(tgm_state::digit_w)); - map(0x07, 0x07).r(FUNC(tgm_state::timer_r)); + map(0x04, 0x07).rw("psu", FUNC(f38t56_device::read), FUNC(f38t56_device::write)); } @@ -274,10 +265,14 @@ INPUT_PORTS_END void tgm_state::tgm(machine_config &config) { /* basic machine hardware */ - F8(config, m_maincpu, 2000000); // measured around 2.1MHz + F8(config, m_maincpu, 2000000); // MK3870, measured around 2.1MHz m_maincpu->set_addrmap(AS_PROGRAM, &tgm_state::main_map); m_maincpu->set_addrmap(AS_IO, &tgm_state::main_io); + f38t56_device &psu(F38T56(config, "psu", 2000000)); + psu.write_a().set(FUNC(tgm_state::sound_w)); + psu.write_b().set(FUNC(tgm_state::digit_w)); + /* video hardware */ for (int i = 0; i < 12; i++) TIMER(config, m_delay_display[i]).configure_generic(FUNC(tgm_state::delay_display)); diff --git a/src/mame/drivers/mk1.cpp b/src/mame/drivers/mk1.cpp index 29fb4f0a162..aa5ce577ccd 100644 --- a/src/mame/drivers/mk1.cpp +++ b/src/mame/drivers/mk1.cpp @@ -38,9 +38,6 @@ Hardware descriptions: - Hardware addressing is controlled by a NBF4001AE. - Unknown if there is a speaker. -TODO: -- Figure out exact clock frequency - ******************************************************************************/ #include "emu.h" @@ -125,7 +122,7 @@ void mk1_state::mk1_mem(address_map &map) void mk1_state::mk1_io(address_map &map) { map(0x0, 0x1).rw(FUNC(mk1_state::mk1_f8_r), FUNC(mk1_state::mk1_f8_w)); - map(0xc, 0xf).rw("f3853", FUNC(f3853_device::read), FUNC(f3853_device::write)); + map(0xc, 0xf).rw("smi", FUNC(f3853_device::read), FUNC(f3853_device::write)); } @@ -186,13 +183,13 @@ void mk1_state::machine_start() void mk1_state::mk1(machine_config &config) { /* basic machine hardware */ - F8(config, m_maincpu, 2000000); // MK3850 + F8(config, m_maincpu, 2000000); // MK3850, approx 2MHz m_maincpu->set_addrmap(AS_PROGRAM, &mk1_state::mk1_mem); m_maincpu->set_addrmap(AS_IO, &mk1_state::mk1_io); - m_maincpu->set_irq_acknowledge_callback("f3853", FUNC(f3853_device::int_acknowledge)); + m_maincpu->set_irq_acknowledge_callback("smi", FUNC(f3853_device::int_acknowledge)); - f3853_device &f3853(F3853(config, "f3853", 2000000)); - f3853.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); + f3853_device &smi(F3853(config, "smi", 2000000)); + smi.int_req_callback().set_inputline("maincpu", F8_INPUT_LINE_INT_REQ); /* video hardware */ config.set_default_layout(layout_mk1); |