summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Joakim Larsson Edström <joakimlarsson42@gmail.com>2017-07-08 23:48:01 +0200
committer GitHub <noreply@github.com>2017-07-08 23:48:01 +0200
commit28b81207884139faa15be7b03225d9156fdab2c1 (patch)
tree3808a20a0eb4aa3cb540d3e2e80c1dbdb00041b7
parente5d06a506659bce3fd9d1ab9b0c9b2ee896f534b (diff)
parentba55423dbcf6654795713ed0c0ea934fd9178ac6 (diff)
Merge pull request #2452 from JoakimLarsson/fccpu1_3
New device: MC14411 Bit Rate Generator
-rw-r--r--scripts/src/machine.lua12
-rw-r--r--scripts/target/mame/arcade.lua1
-rw-r--r--scripts/target/mame/mess.lua1
-rw-r--r--src/devices/machine/mc14411.cpp202
-rw-r--r--src/devices/machine/mc14411.h160
-rw-r--r--src/mame/drivers/force68k.cpp180
6 files changed, 485 insertions, 71 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua
index c1cc2afe1dc..db1feb75e54 100644
--- a/scripts/src/machine.lua
+++ b/scripts/src/machine.lua
@@ -1576,6 +1576,18 @@ end
---------------------------------------------------
--
+--@src/devices/machine/mc14411.h,MACHINES["MC14411"] = true
+---------------------------------------------------
+
+if (MACHINES["MC14411"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/machine/mc14411.cpp",
+ MAME_DIR .. "src/devices/machine/mc14411.h",
+ }
+end
+
+---------------------------------------------------
+--
--@src/devices/machine/mc2661.h,MACHINES["MC2661"] = true
---------------------------------------------------
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 3eab870d2a7..5b6b2e1c725 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -472,6 +472,7 @@ MACHINES["MB87078"] = true
--MACHINES["MB8795"] = true
MACHINES["MB89352"] = true
MACHINES["MB89371"] = true
+--MACHINES["MC14411"] = true
MACHINES["MC146818"] = true
MACHINES["MC2661"] = true
MACHINES["MC6843"] = true
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index d5fe0319ca5..6b2bcde8273 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -462,6 +462,7 @@ MACHINES["MB87078"] = true
MACHINES["MB8795"] = true
MACHINES["MB89352"] = true
MACHINES["MB89371"] = true
+MACHINES["MC14411"] = true
MACHINES["MC146818"] = true
MACHINES["MC2661"] = true
MACHINES["MC6843"] = true
diff --git a/src/devices/machine/mc14411.cpp b/src/devices/machine/mc14411.cpp
new file mode 100644
index 00000000000..9fffadb0261
--- /dev/null
+++ b/src/devices/machine/mc14411.cpp
@@ -0,0 +1,202 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+/*********************************************************************
+
+ mc14411.cpp
+
+ Motorola Bit Rate Generator
+
+ This device assumed a fixed rate clock/crystal and does not support
+ changing it through pin 21. All other features are implemented.
+
+*********************************************************************/
+
+#include "emu.h"
+#include "mc14411.h"
+
+/***************************************************************************
+ MACROS
+***************************************************************************/
+
+//#define LOG_GENERAL (1U << 0) // Already defined in logmacro.h
+#define LOG_SETUP (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL|LOG_SETUP)
+//#define LOG_OUTPUT_FUNC printf
+
+#include "logmacro.h"
+
+//#define LOG(...) LOGMASKED(LOG_GENERAL, __VA_ARGS__) // Already defined in logmacro.h
+#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#define LLFORMAT "%I64d"
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#define LLFORMAT "%lld"
+#endif
+
+/***************************************************************************
+ LOCAL VARIABLES
+***************************************************************************/
+// 0/0 0/1 1/0 1/1 RSB/RSA
+// X1 X8 X16 X64
+const int mc14411_device::counter_divider[16][4] = {
+ { 192, 24, 12, 3 }, // F1
+ { 256, 32, 16, 4 }, // F2
+ { 384, 48, 24, 6 }, // F3
+ { 512, 64, 32, 8 }, // F4
+ { 768, 96, 48, 12 }, // F5
+ { 1024, 128, 64, 16 }, // F6
+ { 1536, 192, 96, 24 }, // F7
+ { 3072, 384, 192, 48 }, // F8
+ { 6144, 768, 384, 96 }, // F9
+ { 9216, 1152, 576, 144 }, // F10
+ { 12288, 1536, 768, 192 }, // F11
+ { 13696, 1712, 856, 214 }, // F12
+ { 16768, 2096, 1048, 262 }, // F13
+ { 24576, 3072, 1536, 384 }, // F14
+ { 2, 2, 2, 2 }, // F15
+ { 1, 1, 1, 1 } // F16
+};
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+// device type definition
+DEFINE_DEVICE_TYPE(MC14411, mc14411_device, "mc14411", "MC14411 BRG")
+
+/***************************************************************************
+ LIVE DEVICE
+***************************************************************************/
+mc14411_device::mc14411_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : mc14411_device(mconfig, MC14411, tag, owner, clock)
+{
+}
+
+mc14411_device::mc14411_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_out_fx_cbs{*this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this, *this }
+ , m_divider(0)
+ , m_reset(CLEAR_LINE)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+void mc14411_device::device_start()
+{
+ LOGSETUP("%s\n", FUNCNAME);
+
+ memset(m_fx_timer, '\0', sizeof(m_fx_timer));
+ for (int i = F1; i <= F16; i++)
+ {
+ m_out_fx_cbs[i].resolve();
+ if (!m_out_fx_cbs[i].isnull()) m_fx_timer[i] = timer_alloc(i);
+ }
+
+ save_item(NAME(m_divider));
+ save_item(NAME(m_reset));
+
+ m_reset_timer = timer_alloc(TIMER_ID_RESET);
+
+}
+
+//------------------------------------------------------------------------
+// device_reset - is called by the mame framework or by the owning device
+// driver or by ASSERTING the reset line through set_reset_line
+//------------------------------------------------------------------------
+void mc14411_device::device_reset()
+{
+ LOGSETUP("%s\n", FUNCNAME);
+
+ for (int i = F1; i <= F16; i++)
+ {
+ if (!m_out_fx_cbs[i].isnull())
+ {
+ // Reset line according to datasheet and remember it for transitions to come
+ (m_out_fx_cbs[i])(m_fx_state[i] = (i < F15 ? 0 : 1));
+
+ // Arm the timer based on the selected divider and the crystal value
+ double hz = clock()/counter_divider[i][m_divider] * 2; // 2 flanks per cycle
+ m_fx_timer[i]->adjust(attotime::from_hz(hz), i, attotime::from_hz(hz));
+ LOGSETUP(" - arming timer for F%d at %fHz\n", i + 1, hz);
+ }
+ }
+
+ if (m_reset == ASSERT_LINE)
+ {
+ m_reset_timer->adjust(attotime::from_nsec((double)900), TIMER_ID_RESET, attotime::from_nsec((double)900));
+ }
+}
+
+//-------------------------------------------------
+// device_timer - handler timer events
+//-------------------------------------------------
+void mc14411_device::device_timer (emu_timer &timer, device_timer_id id, int32_t param, void *ptr)
+{
+ if (id >= F1 && id <= F16)
+ {
+ (m_out_fx_cbs[id])(m_fx_state[id]++ & 1);
+ }
+ else if (id == TIMER_ID_RESET)
+ {
+ // NOTE: This check could be triggered by either faulty hardware design or non accurate emulation so is just informative if the reset line is handled
+ // explicitelly instead of relying on calling device_reset
+ if (!(m_reset == ASSERT_LINE))
+ {
+ LOG("Reset pulse is too short, should be 900nS minimum");
+ logerror("Reset pulse is too short, should be 900nS minimum");
+ }
+ }
+ else
+ {
+ LOG("Unhandled Timer ID %d\n", id);
+ }
+}
+
+//--------------------------------------------------------
+// rate_select_w - implements the RSA and RSB input pins
+// TODO: Needs to check real device behaviour how changing
+// divider at run time affects wave forms
+//--------------------------------------------------------
+WRITE8_MEMBER( mc14411_device::rate_select_w)
+{
+ LOGSETUP("%s %02x\n", FUNCNAME, data);
+
+ m_divider = data & 3;
+
+ for (int i = F1; i <= F16; i++)
+ {
+ if (!m_out_fx_cbs[i].isnull())
+ {
+ // Re-arm the timer based on the new selected divider and the crystal value
+ double hz = clock()/counter_divider[i][m_divider] * 2; // 2 flanks per cycle
+ m_fx_timer[i]->adjust(attotime::from_hz(hz), i, attotime::from_hz(hz));
+ LOGSETUP(" - Re-arming timer for F%d at %fHz\n", i + 1, hz);
+ }
+ }
+}
+
+//------------------------------------------------
+// reset_w - implements software controlled reset
+//------------------------------------------------
+WRITE_LINE_MEMBER( mc14411_device::reset_w)
+{
+ LOGSETUP("%s %02x\n", FUNCNAME, state);
+
+ m_reset = state;
+
+ if (m_reset == ASSERT_LINE)
+ {
+ LOGSETUP(" - Asserting reset\n");
+ device_reset();
+ }
+ else
+ {
+ LOGSETUP(" - Clearing reset\n");
+ }
+}
diff --git a/src/devices/machine/mc14411.h b/src/devices/machine/mc14411.h
new file mode 100644
index 00000000000..d5d6f29d662
--- /dev/null
+++ b/src/devices/machine/mc14411.h
@@ -0,0 +1,160 @@
+// license:BSD-3-Clause
+// copyright-holders:Joakim Larsson Edstrom
+/**********************************************************************
+*
+* Motorola MC14411 - bit rate generator. It utilizes a frequency divider
+* network to provide a wide range of output frequencies. A crystal controlled
+* oscillator is the clock source for the network. A 2 bit adress is used to
+* select one of four multiple output clock rates.
+*
+* - Single 5V sower supply
+* - Internal Oscillator Crystal Controlled for stability (1.8432 MHz)
+* - Sixteen Different Output Clock Rates
+* - 50% Output Duty Cycle
+* - Programmable Time Bases for one of four Multiple Output Rates
+* - Buffered Output compatible with low power TTL
+* - Noice immunity = 45% of VDD Typlical
+* - Diode protection on All Inputs
+* - External Clock may be applied to pin 21
+* - Internal pullup on reset input
+* _____ _____
+* F1 1 |* \_/ | 24 VDD
+* F3 2 | | 23 Rate Select A
+* F5 3 | | 22 Rate Select B
+* F7 4 | | 21 Xtal In
+* F8 5 | | 20 Xtal Out
+* F10 6 | | 19 F16
+* F9 7 | MC14411 | 18 F15
+* F11 8 | | 17 F2
+* F14 9 | | 16 F4
+* Reset* 10 | | 15 F6
+* Not Used 11 | | 14 F12
+* VSS 12 |_____________| 13 F13
+*
+*
+* +----------+-------Output Rates (Hz)-------+
+* | Output | Rate Select B and A pins |
+* | Number | X64 11| X16 10| X8 01 | X1 00 |
+* |----------+-------------------------------+
+* | Fl | 614.4k| 153.6k| 76.8k| 9600 |
+* | F2 | 46O.8k| 115.2k| 57.6k| 7200 |
+* | F3 | 3O7.2k| 76.8k| 38.4k| 4800 |
+* | F4 | 23O.4k| 57.6k| 28.8k| 3600 |
+* | F5 | 153.6k| 38.4k| 19.2k| 2400 |
+* | F6 | 115.2k| 28.8k| 14.4k| 1800 |
+* | F7 | 76.8k| 19.2k| 9600 | 1200 |
+* | FS | 38.4k| 9600 | 4800 | 600 |
+* | F9 | 19.2k| 4800 | 2400 | 300 |
+* | F1O | 12.8k| 3200 | 1600 | 200 |
+* | Fll | 9600 | 2400 | 1200 | 150 |
+* | F12 | 8613.2| 2153.3| 1076.6| 134.5|
+* | F13 | 7035.5| 1758.8| 879.4| 109.9|
+* | F14 | 4800 | 1200 | 600 | 75 |
+* | F15 | 921.6k| 921.6k| 921.6k| 921.6k|
+* | F16 | 1.843M| 1.843M| 1.843M| 1.843M|
+* +------------------------------------------+
+* - F16 is a buffered oscillator output
+*
+* The device is designed to work with 1.843MHz crystal so it is assumed that
+* an external clock source attached to pin 21 is also fixed thus not need to
+* interface through a callback interface.
+**********************************************************************/
+
+#ifndef MAME_MACHINE_MC14411_H
+#define MAME_MACHINE_MC14411_H
+
+#pragma once
+
+//**************************************************************************
+// DEVICE CONFIGURATION MACROS
+//**************************************************************************
+#define MCFG_MC14411_ADD(_tag, _clock) MCFG_DEVICE_ADD(_tag, MC14411, _clock)
+
+#define MCFG_MC14411_F1_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 0, DEVCB_##_devcb);
+#define MCFG_MC14411_F2_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 1, DEVCB_##_devcb);
+#define MCFG_MC14411_F3_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 2, DEVCB_##_devcb);
+#define MCFG_MC14411_F4_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 3, DEVCB_##_devcb);
+#define MCFG_MC14411_F5_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 4, DEVCB_##_devcb);
+#define MCFG_MC14411_F6_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 5, DEVCB_##_devcb);
+#define MCFG_MC14411_F7_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 6, DEVCB_##_devcb);
+#define MCFG_MC14411_F8_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 7, DEVCB_##_devcb);
+#define MCFG_MC14411_F9_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 8, DEVCB_##_devcb);
+#define MCFG_MC14411_F10_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 9, DEVCB_##_devcb);
+#define MCFG_MC14411_F11_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 10, DEVCB_##_devcb);
+#define MCFG_MC14411_F12_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 11, DEVCB_##_devcb);
+#define MCFG_MC14411_F13_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 12, DEVCB_##_devcb);
+#define MCFG_MC14411_F14_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 13, DEVCB_##_devcb);
+#define MCFG_MC14411_F15_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 14, DEVCB_##_devcb);
+#define MCFG_MC14411_F16_CB(_devcb) devcb = &mc14411_device::set_out_fx_cb(*device, 15, DEVCB_##_devcb);
+
+#define MCFG_MC14411_RSA 0x01
+#define MCFG_MC14411_RSB 0x02
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+class mc14411_device : public device_t
+{
+public:
+ // construction/destruction
+ mc14411_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template <class Object> static devcb_base &set_out_fx_cb(device_t &device, int index, Object &&cb) { return downcast<mc14411_device &>(device).m_out_fx_cbs[index].set_callback(std::forward<Object>(cb)); }
+
+ DECLARE_WRITE_LINE_MEMBER(reset_w);
+ DECLARE_WRITE8_MEMBER(rate_select_w);
+
+protected:
+ mc14411_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+private:
+ // timers
+ enum // indexes
+ {
+ F1 = 0,
+ F2 = 1,
+ F3 = 2,
+ F4 = 3,
+ F5 = 4,
+ F6 = 5,
+ F7 = 6,
+ F8 = 7,
+ F9 = 8,
+ F10 = 9,
+ F11 = 10,
+ F12 = 11,
+ F13 = 12,
+ F14 = 13,
+ F15 = 14,
+ F16 = 15
+ };
+
+ emu_timer *m_fx_timer[16];
+
+ enum
+ {
+ TIMER_ID_RESET = 16
+ };
+ emu_timer *m_reset_timer;
+
+ // F1-F16 Output line states
+ uint32_t m_fx_state[16];
+
+ // divider matrix
+ static const int counter_divider[16][4];
+
+ devcb_write_line m_out_fx_cbs[16];
+
+ uint32_t m_divider; // main divider to use, 0-3 column index into counter_divider
+ uint32_t m_reset; // Reset line state
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(MC14411, mc14411_device)
+
+#endif // MAME_MACHINE_MC14411_H
diff --git a/src/mame/drivers/force68k.cpp b/src/mame/drivers/force68k.cpp
index df819171453..ce88a10c054 100644
--- a/src/mame/drivers/force68k.cpp
+++ b/src/mame/drivers/force68k.cpp
@@ -81,6 +81,7 @@
#include "machine/mm58167.h"
#include "machine/68230pit.h"
#include "machine/6850acia.h"
+#include "machine/mc14411.h"
#include "machine/clock.h"
#include "bus/centronics/ctronics.h"
#include "bus/generic/slot.h"
@@ -90,9 +91,6 @@
#include "bus/vme/vme_fcisio.h"
#include "bus/vme/vme_fcscsi.h"
-#define LOG(x) x
-
-#define BAUDGEN_CLOCK XTAL_1_8432MHz
/*
* The baudrate on the Force68k CPU-1 to CPU-6 is generated by a
* Motorola 14411 bitrate generator, the CPU-6 documents matches the circuits
@@ -123,6 +121,31 @@
* so the system rom MUST setup the acia to divide by 16 to generate the correct baudrate.
*
*/
+
+//**************************************************************************
+// CONFIGURABLE LOGGING
+//**************************************************************************
+//#define LOG_GENERAL (1U << 0) // defined in logmacro.h
+#define LOG_SETUP (1U << 1)
+
+//#define VERBOSE (LOG_GENERAL | LOG_SETUP)
+//#define LOG_OUTPUT_FUNC printf
+#include "logmacro.h"
+
+// #define LOG(...) LOGMASKED(LOG_SETUP, __VA_ARGS__) // defined in logmacro.h
+#define LOGSETUP(...) LOGMASKED(LOG_SETUP, __VA_ARGS__)
+
+//**************************************************************************
+// MACROS / CONSTANTS
+//**************************************************************************
+
+#ifdef _MSC_VER
+#define FUNCNAME __func__
+#else
+#define FUNCNAME __PRETTY_FUNCTION__
+#endif
+
+#define BAUDGEN_CLOCK XTAL_1_8432MHz
#define ACIA_CLOCK (BAUDGEN_CLOCK / 12)
class force68k_state : public driver_device
@@ -133,6 +156,7 @@ public:
, m_maincpu(*this, "maincpu")
, m_rtc(*this, "rtc")
, m_pit(*this, "pit")
+ , m_brg(*this, "brg")
, m_aciahost(*this, "aciahost")
, m_aciaterm(*this, "aciaterm")
, m_aciaremt(*this, "aciaremt")
@@ -152,6 +176,7 @@ public:
DECLARE_WRITE16_MEMBER (vme_a16_w);
virtual void machine_start () override;
// clocks
+ DECLARE_WRITE_LINE_MEMBER (write_acia_clock);
DECLARE_WRITE_LINE_MEMBER (write_aciahost_clock);
DECLARE_WRITE_LINE_MEMBER (write_aciaterm_clock);
DECLARE_WRITE_LINE_MEMBER (write_aciaremt_clock);
@@ -169,6 +194,7 @@ private:
required_device<cpu_device> m_maincpu;
required_device<mm58167_device> m_rtc;
required_device<pit68230_device> m_pit;
+ required_device<mc14411_device> m_brg;
required_device<acia6850_device> m_aciahost;
required_device<acia6850_device> m_aciaterm;
required_device<acia6850_device> m_aciaremt;
@@ -187,24 +213,24 @@ private:
};
static ADDRESS_MAP_START (force68k_mem, AS_PROGRAM, 16, force68k_state)
-ADDRESS_MAP_UNMAP_HIGH
-AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */
-AM_RANGE (0x000008, 0x01ffff) AM_RAM /* DRAM CPU-1B */
+ ADDRESS_MAP_UNMAP_HIGH
+ AM_RANGE (0x000000, 0x000007) AM_ROM AM_READ (bootvect_r) /* Vectors mapped from System EPROM */
+ AM_RANGE (0x000008, 0x01ffff) AM_RAM /* DRAM CPU-1B */
//AM_RANGE (0x020000, 0x07ffff) AM_RAM /* Additional DRAM CPU-1D */
-AM_RANGE (0x080000, 0x083fff) AM_ROM /* System EPROM Area 16Kb DEBUGGER supplied as default on CPU-1B/D */
-AM_RANGE (0x084000, 0x09ffff) AM_ROM /* System EPROM Area 112Kb additional space for System ROM */
+ AM_RANGE (0x080000, 0x083fff) AM_ROM /* System EPROM Area 16Kb DEBUGGER supplied as default on CPU-1B/D */
+ AM_RANGE (0x084000, 0x09ffff) AM_ROM /* System EPROM Area 112Kb additional space for System ROM */
//AM_RANGE (0x0a0000, 0x0bffff) AM_ROM /* User EPROM/SRAM Area, max 128Kb mapped by a cartslot */
-AM_RANGE (0x0c0040, 0x0c0041) AM_DEVREADWRITE8 ("aciahost", acia6850_device, status_r, control_w, 0x00ff)
-AM_RANGE (0x0c0042, 0x0c0043) AM_DEVREADWRITE8 ("aciahost", acia6850_device, data_r, data_w, 0x00ff)
-AM_RANGE (0x0c0080, 0x0c0081) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, status_r, control_w, 0xff00)
-AM_RANGE (0x0c0082, 0x0c0083) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, data_r, data_w, 0xff00)
-AM_RANGE (0x0c0100, 0x0c0101) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, status_r, control_w, 0x00ff)
-AM_RANGE (0x0c0102, 0x0c0103) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, data_r, data_w, 0x00ff)
-AM_RANGE (0x0c0400, 0x0c042f) AM_DEVREADWRITE8 ("rtc", mm58167_device, read, write, 0x00ff)
-AM_RANGE (0x0e0000, 0x0e0035) AM_DEVREADWRITE8 ("pit", pit68230_device, read, write, 0x00ff)
-// AM_RANGE(0x0e0200, 0x0e0380) AM_READWRITE(fpu_r, fpu_w) /* optional FPCP 68881 FPU interface */
-AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) */
-AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) */
+ AM_RANGE (0x0c0040, 0x0c0041) AM_DEVREADWRITE8 ("aciahost", acia6850_device, status_r, control_w, 0x00ff)
+ AM_RANGE (0x0c0042, 0x0c0043) AM_DEVREADWRITE8 ("aciahost", acia6850_device, data_r, data_w, 0x00ff)
+ AM_RANGE (0x0c0080, 0x0c0081) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, status_r, control_w, 0xff00)
+ AM_RANGE (0x0c0082, 0x0c0083) AM_DEVREADWRITE8 ("aciaterm", acia6850_device, data_r, data_w, 0xff00)
+ AM_RANGE (0x0c0100, 0x0c0101) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, status_r, control_w, 0x00ff)
+ AM_RANGE (0x0c0102, 0x0c0103) AM_DEVREADWRITE8 ("aciaremt", acia6850_device, data_r, data_w, 0x00ff)
+ AM_RANGE (0x0c0400, 0x0c042f) AM_DEVREADWRITE8 ("rtc", mm58167_device, read, write, 0x00ff)
+ AM_RANGE (0x0e0000, 0x0e0035) AM_DEVREADWRITE8 ("pit", pit68230_device, read, write, 0x00ff)
+//AM_RANGE(0x0e0200, 0x0e0380) AM_READWRITE(fpu_r, fpu_w) /* optional FPCP 68881 FPU interface */
+ AM_RANGE(0x100000, 0xfeffff) AM_READWRITE(vme_a24_r, vme_a24_w) /* VMEbus Rev B addresses (24 bits) */
+ AM_RANGE(0xff0000, 0xffffff) AM_READWRITE(vme_a16_r, vme_a16_w) /* VMEbus Rev B addresses (16 bits) */
ADDRESS_MAP_END
/* Input ports */
@@ -253,7 +279,7 @@ INPUT_PORTS_END
*/
WRITE_LINE_MEMBER (force68k_state::centronics_ack_w)
{
-// LOG (logerror ("centronics_ack_w(%d) %lld\n", state, m_maincpu->total_cycles ()));
+ LOG("%s(%d)\n", FUNCNAME, state);
m_centronics_ack = state;
m_pit->h1_set (state);
}
@@ -262,7 +288,7 @@ WRITE_LINE_MEMBER (force68k_state::centronics_ack_w)
* The centronics busy signal is not used by the ROM driver afaik
*/
WRITE_LINE_MEMBER (force68k_state::centronics_busy_w){
-// LOG (logerror ("centronics_busy_w(%d) %lld\n", state, m_maincpu->total_cycles ()));
+ LOG("%s(%d)\n", FUNCNAME, state);
m_centronics_busy = state;
}
@@ -270,7 +296,7 @@ WRITE_LINE_MEMBER (force68k_state::centronics_busy_w){
* The centronics perror signal is not used by the ROM driver afaik
*/
WRITE_LINE_MEMBER (force68k_state::centronics_perror_w){
-// LOG (logerror ("centronics_perror_w(%d) %lld\n", state, m_maincpu->total_cycles ()));
+ LOG("%s(%d)\n", FUNCNAME, state);
m_centronics_perror = state;
}
@@ -278,7 +304,7 @@ WRITE_LINE_MEMBER (force68k_state::centronics_perror_w){
* The centronics select signal is expected by the ROM on Port B bit 0
*/
WRITE_LINE_MEMBER (force68k_state::centronics_select_w){
-// LOG (logerror ("centronics_select_w(%d) %lld\n", state, m_maincpu->total_cycles ()));
+ LOG("%s(%d)\n", FUNCNAME, state);
m_centronics_select = state;
m_pit->portb_setbit (0, state);
}
@@ -286,26 +312,29 @@ WRITE_LINE_MEMBER (force68k_state::centronics_select_w){
/* Start it up */
void force68k_state::machine_start ()
{
- LOG (logerror ("machine_start\n"));
+ LOG("%s\n", FUNCNAME);
- save_item (NAME (m_centronics_busy));
- save_item (NAME (m_centronics_ack));
- save_item (NAME (m_centronics_select));
- save_item (NAME (m_centronics_perror));
+ save_item (NAME (m_centronics_busy));
+ save_item (NAME (m_centronics_ack));
+ save_item (NAME (m_centronics_select));
+ save_item (NAME (m_centronics_perror));
- /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
- m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0x080000);
+ /* Setup pointer to bootvector in ROM for bootvector handler bootvect_r */
+ m_sysrom = (uint16_t*)(memregion ("maincpu")->base () + 0x080000);
- /* Map user ROM/RAM socket(s) */
- if (m_cart->exists())
- {
- m_usrrom = (uint16_t*)m_cart->get_rom_base();
+ /* Map user ROM/RAM socket(s) */
+ if (m_cart->exists())
+ {
+ m_usrrom = (uint16_t*)m_cart->get_rom_base();
#if 0 // This should be the correct way but produces odd and even bytes swapped
- m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(generic_slot_device::read16_rom), (generic_slot_device*)m_cart));
+ m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(generic_slot_device::read16_rom), (generic_slot_device*)m_cart));
#else // So we installs a custom very ineffecient handler for now until we understand hwp to solve the problem better
- m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(force68k_state::read16_rom), this));
+ m_maincpu->space(AS_PROGRAM).install_read_handler(0xa0000, 0xbffff, read16_delegate(FUNC(force68k_state::read16_rom), this));
#endif
- }
+ }
+
+ // Set up the BRG divider. TODO: Make RSA a selectable DIP switch RSB is always set High
+ m_brg->rate_select_w( m_maincpu->space(AS_PROGRAM), 0, MCFG_MC14411_RSB, 0xff);
}
/* A very ineffecient User cart emulation of two 8 bit sockets (odd and even) */
@@ -316,7 +345,7 @@ READ16_MEMBER (force68k_state::read16_rom){
/* Boot vector handler, the PCB hardwires the first 8 bytes from 0x80000 to 0x0 */
READ16_MEMBER (force68k_state::bootvect_r){
- return m_sysrom [offset];
+ return m_sysrom [offset];
}
/* 10. The VMEbus (text from board documentation)
@@ -339,39 +368,45 @@ READ16_MEMBER (force68k_state::bootvect_r){
/* Dummy VME access methods until the VME bus device is ready for use */
READ16_MEMBER (force68k_state::vme_a24_r){
- LOG (logerror ("vme_a24_r\n"));
+ LOG("%s\n", FUNCNAME);
return (uint16_t) 0;
}
WRITE16_MEMBER (force68k_state::vme_a24_w){
- LOG (logerror ("vme_a24_w\n"));
+ LOG("%s\n", FUNCNAME);
}
READ16_MEMBER (force68k_state::vme_a16_r){
- LOG (logerror ("vme_16_r\n"));
+ LOG("%s\n", FUNCNAME);
return (uint16_t) 0;
}
WRITE16_MEMBER (force68k_state::vme_a16_w){
- LOG (logerror ("vme_a16_w\n"));
+ LOG("%s\n", FUNCNAME);
}
/*
* Serial port clock sources can all be driven by different outputs of the 14411
+ * TODO: Add DIP switches so bitrate can be selected individually for all three ports
*/
-WRITE_LINE_MEMBER (force68k_state::write_aciahost_clock){
- m_aciahost->write_txc (state);
- m_aciahost->write_rxc (state);
+WRITE_LINE_MEMBER (force68k_state::write_acia_clock){
+ write_aciahost_clock(state);
+ write_aciaterm_clock(state);
+ write_aciaremt_clock(state);
}
+WRITE_LINE_MEMBER (force68k_state::write_aciahost_clock){
+ m_aciahost->write_txc (state);
+ m_aciahost->write_rxc (state);
+}
WRITE_LINE_MEMBER (force68k_state::write_aciaterm_clock){
- m_aciaterm->write_txc (state);
- m_aciaterm->write_rxc (state);
+ m_aciaterm->write_txc (state);
+ m_aciaterm->write_rxc (state);
}
WRITE_LINE_MEMBER (force68k_state::write_aciaremt_clock){
- m_aciaremt->write_txc (state);
- m_aciaremt->write_rxc (state);
+ m_aciaremt->write_txc (state);
+ m_aciaremt->write_rxc (state);
}
/*
@@ -392,12 +427,12 @@ WRITE_LINE_MEMBER (force68k_state::write_aciaremt_clock){
// Implementation of static 2 x 64K EPROM in sockets J10/J11 as 16 bit wide cartridge for easier
// software handling. TODO: make configurable according to table above.
static MACHINE_CONFIG_START( fccpu1_eprom_sockets )
- MCFG_GENERIC_CARTSLOT_ADD("exp_rom1", generic_plain_slot, "fccpu1_cart")
- MCFG_GENERIC_EXTENSIONS("bin,rom")
- MCFG_GENERIC_WIDTH(GENERIC_ROM16_WIDTH)
- MCFG_GENERIC_ENDIAN(ENDIANNESS_BIG)
- MCFG_GENERIC_LOAD(force68k_state, exp1_load)
-// MCFG_SOFTWARE_LIST_ADD("cart_list", "fccpu1_cart")
+ MCFG_GENERIC_CARTSLOT_ADD("exp_rom1", generic_plain_slot, "fccpu1_cart")
+ MCFG_GENERIC_EXTENSIONS("bin,rom")
+ MCFG_GENERIC_WIDTH(GENERIC_ROM16_WIDTH)
+ MCFG_GENERIC_ENDIAN(ENDIANNESS_BIG)
+ MCFG_GENERIC_LOAD(force68k_state, exp1_load)
+// MCFG_SOFTWARE_LIST_ADD("cart_list", "fccpu1_cart")
MACHINE_CONFIG_END
/***************************
@@ -405,19 +440,19 @@ MACHINE_CONFIG_END
****************************/
image_init_result force68k_state::force68k_load_cart(device_image_interface &image, generic_slot_device *slot)
{
- uint32_t size = slot->common_get_size("rom");
+ uint32_t size = slot->common_get_size("rom");
- if (size > 0x20000) // Max 128Kb
- {
- LOG( printf("Cartridge size exceeding max size (128Kb): %d\n", size) );
- image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cartridge size exceeding max size (128Kb)");
- return image_init_result::FAIL;
- }
+ if (size > 0x20000) // Max 128Kb
+ {
+ LOG("Cartridge size exceeding max size (128Kb): %d\n", size);
+ image.seterror(IMAGE_ERROR_UNSPECIFIED, "Cartridge size exceeding max size (128Kb)");
+ return image_init_result::FAIL;
+ }
- slot->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG);
- slot->common_load_rom(slot->get_rom_base(), size, "rom");
+ slot->rom_alloc(size, GENERIC_ROM16_WIDTH, ENDIANNESS_BIG);
+ slot->common_load_rom(slot->get_rom_base(), size, "rom");
- return image_init_result::PASS;
+ return image_init_result::PASS;
}
@@ -449,8 +484,8 @@ static MACHINE_CONFIG_START (fccpu1)
MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("aciahost", acia6850_device, write_rxd))
MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("aciahost", acia6850_device, write_cts))
- MCFG_DEVICE_ADD ("aciahost_clock", CLOCK, ACIA_CLOCK)
- MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciahost_clock))
+// MCFG_DEVICE_ADD ("aciahost_clock", CLOCK, ACIA_CLOCK)
+// MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciahost_clock))
/* P4/Terminal Port config */
MCFG_DEVICE_ADD ("aciaterm", ACIA6850, 0)
@@ -462,14 +497,17 @@ static MACHINE_CONFIG_START (fccpu1)
MCFG_RS232_RXD_HANDLER (DEVWRITELINE ("aciaterm", acia6850_device, write_rxd))
MCFG_RS232_CTS_HANDLER (DEVWRITELINE ("aciaterm", acia6850_device, write_cts))
- MCFG_DEVICE_ADD ("aciaterm_clock", CLOCK, ACIA_CLOCK)
- MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciaterm_clock))
+// MCFG_DEVICE_ADD ("aciaterm_clock", CLOCK, ACIA_CLOCK)
+// MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciaterm_clock))
/* P5/Remote Port config */
MCFG_DEVICE_ADD ("aciaremt", ACIA6850, 0)
- MCFG_DEVICE_ADD ("aciaremt_clock", CLOCK, ACIA_CLOCK)
- MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciaterm_clock))
+// MCFG_DEVICE_ADD ("aciaremt_clock", CLOCK, ACIA_CLOCK)
+// MCFG_CLOCK_SIGNAL_HANDLER (WRITELINE (force68k_state, write_aciaremt_clock))
+
+ MCFG_MC14411_ADD ("brg", XTAL_1_8432MHz)
+ MCFG_MC14411_F1_CB(WRITELINE (force68k_state, write_acia_clock))
/* RTC Real Time Clock device */
MCFG_DEVICE_ADD ("rtc", MM58167, XTAL_32_768kHz)