Merge pull request #1956 from JoakimLarsson/vme_2

New Device: BIM 68153 + updated fccpu20, fcisio, 68230, miniforce
This commit is contained in:
R. Belmont 2017-01-12 14:16:59 -05:00 committed by GitHub
commit b7f222a94a
10 changed files with 926 additions and 125 deletions

View File

@ -234,6 +234,18 @@ if (MACHINES["ACIA6850"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/68153bim.h,MACHINES["BIM68153"] = true
---------------------------------------------------
if (MACHINES["BIM68153"]~=null) then
files {
MAME_DIR .. "src/devices/machine/68153bim.cpp",
MAME_DIR .. "src/devices/machine/68153bim.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/68230pit.h,MACHINES["PIT68230"] = true

View File

@ -387,6 +387,7 @@ MACHINES["AT45DBXX"] = true
MACHINES["ATAFLASH"] = true
MACHINES["AY31015"] = true
MACHINES["BANKDEV"] = true
--MACHINES["BIM68153"] = true
MACHINES["CDP1852"] = true
MACHINES["CDP1871"] = true
MACHINES["CMOS40105"] = true
@ -505,6 +506,7 @@ MACHINES["PCF8593"] = true
MACHINES["PCI"] = true
MACHINES["PCKEYBRD"] = true
MACHINES["PIC8259"] = true
--MACHINES["PIT68230"] = true
MACHINES["PIT8253"] = true
MACHINES["PLA"] = true
--MACHINES["PROFILE"] = true

View File

@ -376,6 +376,7 @@ MACHINES["AT45DBXX"] = true
MACHINES["ATAFLASH"] = true
MACHINES["AY31015"] = true
MACHINES["BANKDEV"] = true
MACHINES["BIM68153"] = true
MACHINES["CDP1852"] = true
MACHINES["CDP1871"] = true
MACHINES["CDP1879"] = true

View File

@ -130,6 +130,7 @@
#include "cpu/m68000/m68000.h"
#include "machine/scnxx562.h"
#include "machine/68230pit.h"
#include "machine/68153bim.h"
#include "bus/rs232/rs232.h"
#include "machine/clock.h"
#include "vme_fcisio.h"
@ -202,6 +203,8 @@ static MACHINE_CONFIG_FRAGMENT (fcisio1)
MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_20MHz / 2)
MCFG_PIT68230_PB_INPUT_CB(READ8(vme_fcisio1_card_device, config_rd))
MCFG_MC68153_ADD("bim", XTAL_20MHz / 2)
MACHINE_CONFIG_END
/* ROM definitions */
@ -328,6 +331,7 @@ vme_fcisio1_card_device::vme_fcisio1_card_device(const machine_config &mconfig,
,m_duscc2(*this, "duscc2")
,m_duscc3(*this, "duscc3")
,m_pit (*this, "pit")
,m_bim (*this, "bim")
{
LOG("%s\n", FUNCNAME);
}
@ -341,6 +345,7 @@ vme_fcisio1_card_device::vme_fcisio1_card_device(const machine_config &mconfig,
,m_duscc2(*this, "duscc2")
,m_duscc3(*this, "duscc3")
,m_pit (*this, "pit")
,m_bim (*this, "bim")
{
LOG("%s %s\n", tag, FUNCNAME);
}

View File

@ -6,6 +6,7 @@
#include "machine/scnxx562.h"
#include "machine/68230pit.h"
#include "machine/68153bim.h"
#include "bus/vme/vme.h"
extern const device_type VME_FCISIO1;
@ -41,6 +42,7 @@ private:
required_device<duscc68562_device> m_duscc3;
required_device<pit68230_device> m_pit;
required_device<bim68153_device> m_bim;
// Pointer to System ROMs needed by bootvect_r
uint16_t *m_sysrom;

View File

@ -0,0 +1,420 @@
// license:BSD-3-Clause
// copyright-holders: Joakim Larsson Edstrom
/***************************************************************************
68153 BIM Bus Interrupter Module
The Bus Interrupter Module (BIM) provides an interface between interrupting devices and a system bus such as
the VMEbus or VERSAbus. It generates a maximum of 7 bus interrupts on the IRQ1-IRQ7 outputs and responds to
interrupt acknowledge cycles for up to 4 independent slaves. The BIM can also supply an interrupt vector
during an interrupt acknowledge cycle. Moreover, it sits in the interrupt acknowledge daisychain which allows
for multiple interrupts on the level acknowledged.
----- Features ----------------------------------------------------------
x 4 channels
x Programmable Interrupt Request levels
x Programmable Interrupt Vectors
x Daisy Chain support
Full functionality is implemented
-------------------------------------------------------------------------
Level of implementation: x = done p = partial
-------------------------------------------------------------------------
*/
#include "cpu/m68000/m68000.h"
#include "68153bim.h"
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
#define LOG_PRINTF 0x04
#define LOG_INT 0x08
#define LOG_READ 0x10
#define LOG_IACK 0x20
#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_INT | LOG_IACK) //LOG_GENERAL | LOG_READ)
#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
#define LOGINT(...) LOGMASK(LOG_INT, __VA_ARGS__)
#define LOGR(...) LOGMASK(LOG_READ, __VA_ARGS__)
#define LOGIACK(...) LOGMASK(LOG_IACK, __VA_ARGS__)
#if VERBOSE & LOG_PRINTF
#define logerror printf
#endif
#ifdef _MSC_VER
#define FUNCNAME __func__
#else
#define FUNCNAME __PRETTY_FUNCTION__
#endif
#define CHN0_TAG "ch0"
#define CHN1_TAG "ch1"
#define CHN2_TAG "ch2"
#define CHN3_TAG "ch3"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
// device type definition
const device_type MC68153_CHANNEL = &device_creator<bim68153_channel>;
const device_type MC68153 = &device_creator<bim68153_device>;
const device_type EI68C153 = &device_creator<ei68c153_device>;
//-------------------------------------------------
// device_mconfig_additions -
//-------------------------------------------------
MACHINE_CONFIG_FRAGMENT( m68153 )
MCFG_DEVICE_ADD(CHN0_TAG, MC68153_CHANNEL, 0)
MCFG_DEVICE_ADD(CHN1_TAG, MC68153_CHANNEL, 0)
MCFG_DEVICE_ADD(CHN2_TAG, MC68153_CHANNEL, 0)
MCFG_DEVICE_ADD(CHN3_TAG, MC68153_CHANNEL, 0)
MACHINE_CONFIG_END
machine_config_constructor bim68153_device::device_mconfig_additions() const
{
LOG("%s\n", FUNCNAME);
return MACHINE_CONFIG_NAME( m68153 );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// bim68153_device - constructor
//-------------------------------------------------
bim68153_device::bim68153_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, uint32_t variant, const char *shortname, const char *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source)
,m_chn{{*this, CHN0_TAG}, {*this, CHN1_TAG}, {*this, CHN2_TAG}, {*this, CHN3_TAG}}
,m_out_int_cb(*this)
,m_out_intal0_cb(*this)
,m_out_intal1_cb(*this)
,m_out_iackout_cb(*this)
,m_iackin(ASSERT_LINE)
,m_irq_level(0)
{
LOG("%s\n", FUNCNAME);
}
bim68153_device::bim68153_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MC68153, "Motorola MC68153 BIM", tag, owner, clock, "m68153bim", __FILE__)
,m_chn{{*this, CHN0_TAG}, {*this, CHN1_TAG}, {*this, CHN2_TAG}, {*this, CHN3_TAG}}
,m_out_int_cb(*this)
,m_out_intal0_cb(*this)
,m_out_intal1_cb(*this)
,m_out_iackout_cb(*this)
,m_iackin(ASSERT_LINE)
,m_irq_level(0)
{
LOG("%s\n", FUNCNAME);
}
/* The EPIC EI68C153 is a CMOS implementation that is fully compatible with the bipolar MC68153 from Motorola */
ei68c153_device::ei68c153_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bim68153_device(mconfig, EI68C153, "EPIC EI68C153 BIM", tag, owner, clock, TYPE_EI68C153, "ei68c153", __FILE__)
{
LOG("%s\n", FUNCNAME);
}
//-------------------------------------------------
// get_channel_index
//-------------------------------------------------
int bim68153_device::get_channel_index(bim68153_channel *ch)
{
assert(ch == m_chn[CHN_0] || ch == m_chn[CHN_1] || ch == m_chn[CHN_2] || ch == m_chn[CHN_3]);
if (ch == m_chn[CHN_0]) return 0;
else if (ch == m_chn[CHN_1]) return 1;
else if (ch == m_chn[CHN_2]) return 2;
else return 3;
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void bim68153_device::device_start()
{
LOG("%s\n", FUNCNAME);
// resolve callbacks
m_out_int_cb.resolve_safe();
m_out_intal0_cb.resolve_safe();
m_out_intal1_cb.resolve_safe();
m_out_iackout_cb.resolve_safe(0);
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void bim68153_device::device_reset()
{
LOG("%s %s \n",tag(), FUNCNAME);
// Reset on all channels
for (auto & elem : m_chn)
elem->reset();
}
/*
* Interrupts
* The BIM accepts device interrupt requests on inputs INT0, INT1, INT2 and INT3. Each input is regulated by
* Bit 4 (IRE) of the associated control register (CRO controls INT0, CR! controls INT1,etc.). If IRE (Interrupt
* Enable) is set and a device input is asserted, an Interrupt Request open-collector output (IRQ1 - IRQ7)
* is asserted. The asserted IRQX output is selected by the value programmed in Bits 0, 1, and 2 of the control
* register (L0, L1, and L3). This 3-bit field determines the interrupt request level as set by software.
*
* Two or more interrupt sources can be programmed to the same request level. The corresponding IRQX output
* will remain asserted until multiple interrupt acknowledge cycles respond to all requests.
*
* If the interrupt request level is set to zero, the interrupt is disabled because there is no corresponding IRQ output.
*/
/*
The response of an interrupt Handler to a bus interrupt request is an interrupt acknowledge cycle. The IACK
cycle is initiated in BIM by receiving IACK low R/W, A1, A2, A3 are latched, and the interrupt level on line A1-A3
is compared with any interrupt requests pending in the chip. Further activity can be one of four cases.*/
#define MAX_VECTOR 255
IRQ_CALLBACK_MEMBER(bim68153_device::iack)
{
int vec = M68K_INT_ACK_AUTOVECTOR;
int found = 0;
// int level = 0;
int ch = -1;
LOGIACK("%s %s()\n", tag(), FUNCNAME);
/* 1. No further action required — This occurs if IACKIN is not asserted. Asserting IACKN only starts the BIM activity.
* If the daisy chain signal never reaches the BIM (IACKIN is not asserted), another interrupter has responded to the
* IACK cycle. The cycle will end, the IACK is negated, and no additional action is required. */
if (m_iackin == CLEAR_LINE)
{
m_out_iackout_cb(CLEAR_LINE);
m_out_int_cb(CLEAR_LINE); // should really be tristated
return MAX_VECTOR + 1; // This is a 68K emulation specific response and will terminate the iack cycle
}
for (auto & elem : m_chn)
{ // If this channel has interrupts enabled and pending
if (elem->m_int_state == bim68153_channel::PENDING && elem->m_control & bim68153_channel::REG_CNTRL_INT_ENABLE)
{ // and the level matches
if ((elem->m_control & bim68153_channel::REG_CNTRL_INT_LVL_MSK) == irqline)
{ // then remember it
ch = get_channel_index(elem);
}
found = 1;
}
}
/* 2. Pass on the interrupt daisy chain — For this case, IACKIN input is asserted by the preceding daisy chain interrupter,
* and IACKOUT output is in turn asserted. The daisy chain signal is passed on when no interrupts are pending on a matching
* level or when any possible interrupts are disabled. The Interrupt Enable (IRE) bit of a control register can disable any
* interrupt requests, and in turn, any possible matches */
if (found == 0)
{
m_out_iackout_cb(CLEAR_LINE); // No more interrupts to serve, pass the message to next device in daisy chain
m_out_int_cb(CLEAR_LINE); // should really be tristated but board driver must make sure to mitigate if this is a problem
return MAX_VECTOR + 1; // This is a 68K emulation specific response and will terminate the iack cycle
}
m_irq_level = m_chn[ch]->m_control & bim68153_channel::REG_CNTRL_INT_LVL_MSK;
if ((m_chn[ch]->m_control & bim68153_channel::REG_CNTRL_INT_EXT) == 0)
{
/* 3. Respond internally - For this case, IACKIN is asserted and a match is found. The BIM completes the IACK cycle by
* supplying an interrupt vector from the proper vector register followed by a DTACK signal asserted because the interrupt
* acknowledge cycle is completed by this device. For the BIM to respond in this mode of operation, the EXTERNAL/INTERNAl
* control register bit (X/IN) must be zero. For each source of interrupt request, the associated control register determines
* the BIM response to an IACK cycle, and the X/IN bit sets this response either internally (X/IN = 0 ) or externally (X/IN = 1). */
vec = m_chn[ch]->m_vector; // Internal vector
}
else
{
/* 4. Respond externally — For the final case, IACKIN is also asserted, a match is found and the associated control register has
* X/IN bit set to one. The BIM does not assert IACKOUT and does assert INTAE low.INTAE signals that the requesting device must
* complete the IACK cycle (supplying a vector and DTACK) and that the 2-bit code contained on outputs INTALO and INTAL1 shows
* which interrupt source is being acknowledged*/
vec = m_chn[ch]->m_out_iack_cb(); // External vector
/* Also support INTAL0 and INTAL1 in case additional logic relies on it */
m_out_intal0_cb( ch & 1);
m_out_intal1_cb((ch >> 1) & 1);
/* TODO: Figure out a way to update the vector in case INTAL0/INTAL1 is involved creating it */
}
LOGIACK(" - Interrupt Acknowledge Vector %02x, next interrupt is off %02x\n", vec, m_irq_level);
if (m_chn[ch]->m_control & bim68153_channel::REG_CNTRL_INT_AUT_DIS)
{
LOGIACK(" - Interrupts on channel %d disabled due to the IRAC (Auto Clear) bit is set\n", ch);
m_chn[ch]->m_control &= ~bim68153_channel::REG_CNTRL_INT_ENABLE;
}
// This is not explicitly said in the 68153 datasheet but what would a flag be used for otherwise?
m_chn[ch]->m_control &= ~bim68153_channel::REG_CNTRL_INT_FLAG;
m_out_iackout_cb(CLEAR_LINE);
m_out_int_cb(CLEAR_LINE);
return vec;
}
int bim68153_device::get_irq_level()
{
LOGINT("%s %s() - %02x\n", tag(), FUNCNAME, m_irq_level);
return m_irq_level;
}
//-------------------------------------------------
// trigger_interrupt -
//-------------------------------------------------
void bim68153_device::trigger_interrupt(int ch)
{
LOGINT("%s %s CHN:%d\n",FUNCNAME, tag(), ch);
if (!(m_chn[ch]->m_control & bim68153_channel::REG_CNTRL_INT_ENABLE))
{
LOGINT("Interrupt Enable for channel %d is not set, blocking attempt to interrupt\n", ch);
return;
}
m_irq_level = (m_chn[ch]->m_control & bim68153_channel::REG_CNTRL_INT_LVL_MSK);
// trigger interrupt
m_chn[ch]->m_int_state = bim68153_channel::PENDING;
// assert daisy chain
m_out_iackout_cb(ASSERT_LINE);
// Set flag
// This is not explicitly said in the 68153 datasheet but what would a flag be used for otherwise?
m_chn[ch]->m_control |= bim68153_channel::REG_CNTRL_INT_FLAG;
// assert interrupt
m_out_int_cb(ASSERT_LINE);
}
//-------------------------------------------------
// read
//-------------------------------------------------
READ8_MEMBER( bim68153_device::read )
{
int vc = offset & REG_VECTOR;
int ch = offset & CHN_MSK;
LOGR(" * %s %d Reg %s -> %02x \n", m_owner->tag(), ch, vc ? "vector" : "control",
vc ? m_chn[ch]->do_bimreg_vector_r() : m_chn[ch]->do_bimreg_control_r());
return vc ? m_chn[ch]->do_bimreg_vector_r() : m_chn[ch]->do_bimreg_control_r();
}
//-------------------------------------------------
// write
//-------------------------------------------------
WRITE8_MEMBER( bim68153_device::write )
{
int vc = offset & REG_VECTOR;
int ch = offset & CHN_MSK;
LOGSETUP(" * %s %d Reg %s <- %02x \n", m_owner->tag(), ch, vc ? "vector" : "control", data);
if (vc)
m_chn[ch]->do_bimreg_vector_w(data);
else
m_chn[ch]->do_bimreg_control_w(data);
}
//**************************************************************************
// BIM CHANNEL
//**************************************************************************
bim68153_channel::bim68153_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MC68153_CHANNEL, "BIM channel", tag, owner, clock, "bim68153_channel", __FILE__)
,m_out_iack_cb(*this)
,m_int_state(NONE)
,m_control(0)
,m_vector(0)
{
LOG("%s\n",FUNCNAME);
}
//-------------------------------------------------
// start - channel startup
//-------------------------------------------------
void bim68153_channel::device_start()
{
LOGSETUP("%s\n", FUNCNAME);
m_bim = downcast<bim68153_device *>(owner());
m_index = m_bim->get_channel_index(this);
// state saving
save_item(NAME(m_control));
save_item(NAME(m_vector));
save_item(NAME(m_int_state));
// Resolve callbacks
m_out_iack_cb.resolve_safe(0);
}
//-------------------------------------------------
// reset - reset channel status
//-------------------------------------------------
void bim68153_channel::device_reset()
{
LOGSETUP("%s\n", FUNCNAME);
// Reset all registers
m_control = 0;
m_vector = 0x0f;
m_int_state = NONE;
}
/* Trigger an interrupt */
WRITE_LINE_MEMBER( bim68153_channel::int_w )
{
LOGINT("%s Ch %d: %d\n",FUNCNAME, m_index, state);
if (state == ASSERT_LINE)
{
m_bim->trigger_interrupt(m_index);
}
}
uint8_t bim68153_channel::do_bimreg_control_r()
{
LOG("%s ch %d returns %02x\n", FUNCNAME, m_index, m_control);
return m_control;
}
uint8_t bim68153_channel::do_bimreg_vector_r()
{
LOG("%s ch %d returns %02x\n", FUNCNAME, m_index, m_vector);
return m_vector;
}
void bim68153_channel::do_bimreg_control_w(uint8_t data)
{
LOG("%s ch %d set control to %02x\n", FUNCNAME, m_index, data);
LOGSETUP(" - Lev:%d Auto Disable:%d Int Enable:%d Vector:%d Auto Clear:%d Flag:%d\n",
data & REG_CNTRL_INT_LVL_MSK,
data & REG_CNTRL_INT_AUT_DIS ? 1 : 0,
data & REG_CNTRL_INT_ENABLE ? 1 : 0,
data & REG_CNTRL_INT_EXT ? 1 : 0,
data & REG_CNTRL_INT_AUT_CLR ? 1 : 0,
data & REG_CNTRL_INT_FLAG ? 1 : 0);
m_control = data;
}
void bim68153_channel::do_bimreg_vector_w(uint8_t data)
{
LOG("%s ch %d set vector to %02x\n", FUNCNAME, m_index, data);
m_vector = data;
}

View File

@ -0,0 +1,225 @@
// license:BSD-3-Clause
// copyright-holders:Joakim Larsson Edstrom
/**********************************************************************
*
* Motorola MC68153 BIM - Bus Interrupter Module
*
* _____ _____
* Vcc 1 |* \_/ | 40 A3
* RW* 2 | | 39 A2
* CS* 3 | | 38 A1
* DTACK* 4 | | 37 D7
* IACK* 5 | | 36 D6
* IACKIN* 6 | | 35 D5
* IACKOUT* 7 | | 34 D4
* IRQ1* 8 | | 33 D3
* GND 9 | | 32 D2
* GND 10 | | 31 GND
* Vcc 11 | | 30 VCC
* IRQ2* 12 | MC68153 | 29 D1
* IRQ3* 13 | EI68C153 | 28 D0
* IRQ4* 14 | | 27 INTAE*
* IRQ5* 15 | | 26 INTAL1
* IRQ6* 16 | | 25 INTAL0
* IRQ7* 17 | | 24 INT3*
* CLK* 18 | | 23 INT2*
* INT0* 19 | | 22 INT1*
* GND 20 |_____________| 21 Vcc
*
**********************************************************************/
#pragma once
#ifndef MC68153BIM_H
#define MC68153BIM_H
#include "emu.h"
//**************************************************************************
// DEVICE CONFIGURATION MACROS
//**************************************************************************
/* Variant ADD macros - use the right one to enable the right feature set! */
#define MCFG_MC68153_ADD(_tag, _clock) \
MCFG_DEVICE_ADD(_tag, MC68153, _clock)
#define MCFG_EI68C153_ADD(_tag, _clock) \
MCFG_DEVICE_ADD(_tag, EI68C153, _clock)
#define MCFG_BIM68153_OUT_INT_CB(_devcb) \
devcb = &bim68153_device::set_out_int_callback(*device, DEVCB_##_devcb);
// These callback sets INTAL0 and INTAL1 but is probably not needed as the
// shorthand OUT_IACK0..OUT_IACK3 below embedd the channel information
#define MCFG_BIM68153_OUT_INTAL0_CB(_devcb) \
devcb = &bim68153_device::set_out_intal0_callback(*device, DEVCB_##_devcb);
#define MCFG_BIM68153_OUT_INTAL1_CB(_devcb) \
devcb = &bim68153_device::set_out_intal1_callback(*device, DEVCB_##_devcb);
// LOCAL IACK callbacks emulating the INTAL0 and INTAL1 outputs for INTAE requesting a vector from a sub device
#define MCFG_BIM68153_OUT_IACK0_CB(_devcb) \
devcb = &bim68153_device::set_out_iack0_callback(*device, DEVCB_##_devcb);
#define MCFG_BIM68153_OUT_IACK1_CB(_devcb) \
devcb = &bim68153_device::set_out_iack1_callback(*device, DEVCB_##_devcb);
#define MCFG_BIM68153_OUT_IACK2_CB(_devcb) \
devcb = &bim68153_device::set_out_iack2_callback(*device, DEVCB_##_devcb);
#define MCFG_BIM68153_OUT_IACK3_CB(_devcb) \
devcb = &bim68153_device::set_out_iack3_callback(*device, DEVCB_##_devcb);
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class bim68153_device;
class bim68153_channel : public device_t
{
friend class bim68153_device;
public:
bim68153_channel(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
// read register handlers
uint8_t do_bimreg_control_r();
uint8_t do_bimreg_vector_r();
// write register handlers
void do_bimreg_control_w(uint8_t data);
void do_bimreg_vector_w(uint8_t vector);
DECLARE_WRITE_LINE_MEMBER( int_w );
devcb_read8 m_out_iack_cb;
uint8_t m_int_state;
// Register state
uint8_t m_control;
uint8_t m_vector;
protected:
enum
{
NONE = 0,
PENDING = 1,
};
enum
{
RCV_IDLE = 0,
RCV_SEEKING = 1,
RCV_SAMPLING = 2
};
enum
{
REG_CNTRL_INT_LVL_MSK = 0x07,
REG_CNTRL_INT_AUT_DIS = 0x08,
REG_CNTRL_INT_ENABLE = 0x10,
REG_CNTRL_INT_EXT = 0x20,
REG_CNTRL_INT_AUT_CLR = 0x40,
REG_CNTRL_INT_FLAG = 0x80,
};
int m_int; // interrupt request from connected device
int m_index; // Which channel am I?
bim68153_device *m_bim; // my device
};
class bim68153_device : public device_t
{
friend class bim68153_channel;
public:
// construction/destruction
bim68153_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, uint32_t variant, const char *shortname, const char *source);
bim68153_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
IRQ_CALLBACK_MEMBER(iack);
int acknowledge();
int get_irq_level();
template<class _Object> static devcb_base &set_out_int_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_out_int_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_intal0_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_out_intal0_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_intal1_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_out_intal1_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_iack0_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_chn[CHN_0]->m_out_iack_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_iack1_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_chn[CHN_1]->m_out_iack_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_iack2_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_chn[CHN_2]->m_out_iack_cb.set_callback(object); }
template<class _Object> static devcb_base &set_out_iack4_callback(device_t &device, _Object object) { return downcast<bim68153_device &>(device).m_chn[CHN_3]->m_out_iack_cb.set_callback(object); }
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( iackin_w ) { m_iackin = state; }
DECLARE_WRITE_LINE_MEMBER( int0_w ) { m_chn[CHN_0]->int_w(state); }
DECLARE_WRITE_LINE_MEMBER( int1_w ) { m_chn[CHN_1]->int_w(state); }
DECLARE_WRITE_LINE_MEMBER( int2_w ) { m_chn[CHN_2]->int_w(state); }
DECLARE_WRITE_LINE_MEMBER( int3_w ) { m_chn[CHN_3]->int_w(state); }
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual machine_config_constructor device_mconfig_additions() const override;
void trigger_interrupt(int ch);
int get_channel_index(bim68153_channel *ch);
// Register enums
enum
{
REG_CONTROL = 0x00,
REG_VECTOR = 0x04,
CHN_MSK = 0x03,
CHN_0 = 0x00,
CHN_1 = 0x01,
CHN_2 = 0x02,
CHN_3 = 0x03,
};
enum
{
INT_CHN0 = 0,
INT_CHN1 = 1,
INT_CHN2 = 2,
INT_CHN3 = 3,
};
// Variants of BIM
enum
{
TYPE_MC68153 = 0x001,
TYPE_EI68C153 = 0x002,
};
required_device<bim68153_channel> m_chn[4];
devcb_write_line m_out_int_cb;
// iack signalling towards subdevices, see also out_iack_callbacks in each bim68153_channel which overlaps
devcb_write_line m_out_intal0_cb;
devcb_write_line m_out_intal1_cb;
// Daisy chain signals
devcb_read8 m_out_iackout_cb;
int m_iackin;
int m_irq_level;
};
class ei68c153_device : public bim68153_device
{
public :
ei68c153_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
};
// device type definition
extern const device_type MC68153;
extern const device_type EI68C153;
extern const device_type MC68153_CHANNEL;
#endif /* MC68153BIM_H */

View File

@ -23,25 +23,34 @@
#include "68230pit.h"
#define VERBOSE 0
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
#define LOG_PRINTF 0x04
#define LOG_READ 0x08
#define LOG_BIT 0x10
#define LOG_DR 0x20
#define LOG_INT 0x40
#define LOGPRINT(x) { do { if (VERBOSE) logerror x; } while (0); }
#define LOG(x) {} LOGPRINT(x)
#define LOGR(x) {} LOGPRINT(x)
#define LOGBIT(x) {} LOGPRINT(x)
#define LOGDR(x) {} LOGPRINT(x)
#define LOGINT(x) {} LOGPRINT(x)
#define LOGSETUP(x) {} LOGPRINT(x)
#if VERBOSE > 1
#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL | LOG_INT | LOG_BIT | LOG_DR)
#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
#define LOGR(...) LOGMASK(LOG_READ, __VA_ARGS__)
#define LOGBIT(...) LOGMASK(LOG_BIT, __VA_ARGS__)
#define LOGDR(...) LOGMASK(LOG_DR, __VA_ARGS__)
#define LOGINT(...) LOGMASK(LOG_INT, __VA_ARGS__)
#if VERBOSE & LOG_PRINTF
#define logerror printf
#endif
#ifdef _MSC_VER
#define FUNCNAME __func__
#define LLFORMAT "%I64%"
#else
#define FUNCNAME __PRETTY_FUNCTION__
#define LLFORMAT "%lld"
#endif
//**************************************************************************
@ -133,7 +142,7 @@ pit68230_device::pit68230_device(const machine_config &mconfig, const char *tag,
//-------------------------------------------------
void pit68230_device::device_start ()
{
LOG(("%s\n", FUNCNAME));
LOG("%s\n", FUNCNAME);
// resolve callbacks
m_pa_out_cb.resolve_safe();
@ -177,7 +186,7 @@ void pit68230_device::device_start ()
//-------------------------------------------------
void pit68230_device::device_reset ()
{
LOG(("%s %s \n",tag(), FUNCNAME));
LOG("%s %s \n",tag(), FUNCNAME);
m_pgcr = 0;
m_psrr = 0;
@ -201,7 +210,7 @@ void pit68230_device::device_reset ()
*/
uint8_t pit68230_device::irq_piack()
{
LOGINT(("%s %s <- %02x\n",tag(), FUNCNAME, m_pivr));
LOGINT("%s %s <- %02x\n",tag(), FUNCNAME, m_pivr);
return m_pivr;
}
@ -210,7 +219,7 @@ uint8_t pit68230_device::irq_piack()
*/
uint8_t pit68230_device::irq_tiack()
{
LOGINT(("%s %s <- %02x\n",tag(), FUNCNAME, m_tivr));
LOGINT("%s %s <- %02x\n",tag(), FUNCNAME, m_tivr);
return m_tivr;
}
@ -220,7 +229,7 @@ uint8_t pit68230_device::irq_tiack()
*/
void pit68230_device::trigger_interrupt(int source)
{
LOGINT(("%s %s Source: %02x\n",tag(), FUNCNAME, source));
LOGINT("%s %s Source: %02x\n",tag(), FUNCNAME, source);
if (source == INT_TIMER)
{
@ -244,7 +253,7 @@ void pit68230_device::tick_clock()
{
if (m_cntr-- == 0) // Zero detect
{
LOGINT(("Timer reached zero!\n"));
LOGINT("Timer reached zero!\n");
if ((m_tcr & REG_TCR_ZD) == 0)
m_cntr = m_cpr;
else // mask off to 24 bit on rollover
@ -266,7 +275,7 @@ void pit68230_device::device_timer (emu_timer &timer, device_timer_id id, int32_
tick_clock();
break;
default:
LOG(("Unhandled Timer ID %d\n", id));
LOG("Unhandled Timer ID %d\n", id);
break;
}
}
@ -284,11 +293,11 @@ void pit68230_device::portb_setbit(uint8_t bit, uint8_t state)
void pit68230_device::pa_update_bit(uint8_t bit, uint8_t state)
{
LOGBIT(("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state));
LOGBIT("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state);
// Check if requested bit is an output bit and can't be affected
if (m_paddr & (1 << bit))
{
LOG(("- 68230 PIT: tried to set input bit at port A that is programmed as output!\n"));
LOG("- 68230 PIT: tried to set input bit at port A that is programmed as output!\n");
return;
}
if (state)
@ -305,11 +314,11 @@ void pit68230_device::pa_update_bit(uint8_t bit, uint8_t state)
void pit68230_device::pb_update_bit(uint8_t bit, uint8_t state)
{
LOGBIT(("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state));
LOGBIT("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state);
// Check if requested bit is an output bit and can't be affected
if (m_pbddr & (1 << bit))
{
LOG(("- 68230 PIT: tried to set input bit at port B that is programmed as output!\n"));
LOG("- 68230 PIT: tried to set input bit at port B that is programmed as output!\n");
return;
}
if (state)
@ -327,11 +336,11 @@ void pit68230_device::pb_update_bit(uint8_t bit, uint8_t state)
// TODO: Make sure port C is in the right alternate mode
void pit68230_device::pc_update_bit(uint8_t bit, uint8_t state)
{
LOGBIT(("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state));
LOGBIT("%s %s bit %d to %d\n",tag(), FUNCNAME, bit, state);
// Check if requested bit is an output bit and can't be affected
if (m_pcddr & (1 << bit))
{
LOG(("- 68230 PIT: tried to set input bit at port C that is programmed as output!\n"));
LOG("- 68230 PIT: tried to set input bit at port C that is programmed as output!\n");
return;
}
if (state)
@ -365,53 +374,55 @@ static int32_t ow_ofs = 0;
void pit68230_device::wr_pitreg_pgcr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOGSETUP(("PGCR - Mode %d,", (data >> 6) & 3 ));
LOGSETUP((" H34:%s, H12:%s,", (data & 0x20) ? "enabled" : "disabled", (data & 0x10) ? "enabled" : "disabled" ));
LOGSETUP((" Sense assert H4:%s, H3:%s, H2:%s, H1:%s\n",
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
LOGSETUP("PGCR - Mode %d,", (data >> 6) & 3 );
LOGSETUP(" H34:%s, H12:%s,", (data & 0x20) ? "enabled" : "disabled", (data & 0x10) ? "enabled" : "disabled" );
LOGSETUP(" Sense assert H4:%s, H3:%s, H2:%s, H1:%s\n",
data & 0x04 ? "Hi" : "Lo", data & 0x03 ? "Hi" : "Lo",
data & 0x02 ? "Hi" : "Lo", data & 0x01 ? "Hi" : "Lo"));
data & 0x02 ? "Hi" : "Lo", data & 0x01 ? "Hi" : "Lo");
m_pgcr = data;
}
void pit68230_device::wr_pitreg_psrr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOGSETUP(("PSSR - %s pin activated,", data & 0x40 ? "DMA" : "PC4"));
LOGSETUP((" %s pin support %s interrupts,", data & 0x80 ? "PIRQ" : "PC5",
data & 0x08 ? "no" : (data & 0x10 ? "vectored" : "autovectored" ) ));
LOGSETUP((" H prio mode:%d\n", data & 0x03 ));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
LOGSETUP("PSSR - %s pin activated,", data & 0x40 ? "DMA" : "PC4");
LOGSETUP(" %s pin support %s interrupts,", data & 0x80 ? "PIRQ" : "PC5",
data & 0x08 ? "no" : (data & 0x10 ? "vectored" : "autovectored" ) );
LOGSETUP(" H prio mode:%d\n", data & 0x03 );
m_psrr = data;
}
void pit68230_device::wr_pitreg_paddr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOGSETUP(("PADDR"));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
LOGSETUP("%s PADDR: %02x\n", tag(), data);
m_paddr = data;
}
void pit68230_device::wr_pitreg_pbddr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOGSETUP("%s PBDDR: %02x\n", tag(), data);
m_pbddr = data;
}
void pit68230_device::wr_pitreg_pcddr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
LOGSETUP("%s PCDDR: %02x\n", tag(), data);
m_pcddr = data;
}
void pit68230_device::wr_pitreg_pivr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": Not implemented yet\n", FUNCNAME, data, tag()));
LOG("%s(%02x) \"%s\": Not implemented yet\n", FUNCNAME, data, tag());
}
void pit68230_device::wr_pitreg_pacr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
LOGSETUP("%s PACR", tag());
m_pacr = data;
// callbacks
/*PACR in Mode 0
@ -436,18 +447,18 @@ void pit68230_device::wr_pitreg_pacr(uint8_t data)
switch(m_pacr & REG_PACR_H2_CTRL_MASK)
{
case REG_PACR_H2_CTRL_OUT_00:
LOG((" - H2 cleared\n"));
LOGSETUP(" - H2 cleared\n");
m_h2_out_cb(CLEAR_LINE);
break;
case REG_PACR_H2_CTRL_OUT_01:
LOG((" - H2 asserted\n"));
LOGSETUP(" - H2 asserted\n");
m_h2_out_cb(ASSERT_LINE);
break;
case REG_PACR_H2_CTRL_OUT_10:
LOGSETUP((" - interlocked handshake not implemented\n"));
LOGSETUP(" - interlocked handshake not implemented\n");
break;
case REG_PACR_H2_CTRL_OUT_11:
LOGSETUP((" - pulsed handshake not implemented\n"));
LOGSETUP(" - pulsed handshake not implemented\n");
break;
default: logerror(("Undefined H2 mode, broken driver - please report!\n"));
}
@ -455,7 +466,7 @@ void pit68230_device::wr_pitreg_pacr(uint8_t data)
}
else
{
LOG((" - H2 cleared because being disabled in PGCR\n"));
LOGSETUP(" - H2 cleared because being disabled in PGCR\n");
m_h2_out_cb(CLEAR_LINE);
}
}
@ -463,7 +474,7 @@ void pit68230_device::wr_pitreg_pacr(uint8_t data)
// TODO add support for sense status
void pit68230_device::wr_pitreg_pbcr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_pbcr = data;
if ((m_pgcr & REG_PGCR_H34_ENABLE) || ((m_pbcr & REG_PBCR_SUBMODE_MASK) == REG_PBCR_SUBMODE_1X))
{
@ -472,18 +483,18 @@ void pit68230_device::wr_pitreg_pbcr(uint8_t data)
switch(m_pbcr & REG_PBCR_H4_CTRL_MASK)
{
case REG_PBCR_H4_CTRL_OUT_00:
LOG((" - H4 cleared\n"));
LOG(" - H4 cleared\n");
m_h4_out_cb(CLEAR_LINE);
break;
case REG_PBCR_H4_CTRL_OUT_01:
LOG((" - H4 asserted\n"));
LOG(" - H4 asserted\n");
m_h4_out_cb(ASSERT_LINE);
break;
case REG_PBCR_H4_CTRL_OUT_10:
LOGSETUP((" - interlocked handshake not implemented\n"));
LOGSETUP(" - interlocked handshake not implemented\n");
break;
case REG_PBCR_H4_CTRL_OUT_11:
LOGSETUP((" - pulsed handshake not implemented\n"));
LOGSETUP(" - pulsed handshake not implemented\n");
break;
default: logerror(("Undefined H4 mode, broken driver - please report!\n"));
}
@ -491,14 +502,14 @@ void pit68230_device::wr_pitreg_pbcr(uint8_t data)
}
else
{
LOG((" - H4 cleared because being disabled in PGCR\n"));
LOG(" - H4 cleared because being disabled in PGCR\n");
m_h4_out_cb(CLEAR_LINE);
}
}
void pit68230_device::wr_pitreg_padr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_padr = (data & m_paddr);
// callback
@ -507,7 +518,7 @@ void pit68230_device::wr_pitreg_padr(uint8_t data)
void pit68230_device::wr_pitreg_pbdr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_pbdr = (data & m_pbddr);
// callback
@ -516,7 +527,7 @@ void pit68230_device::wr_pitreg_pbdr(uint8_t data)
void pit68230_device::wr_pitreg_pcdr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_pcdr = (data & m_pcddr);
// callback
@ -525,7 +536,7 @@ void pit68230_device::wr_pitreg_pcdr(uint8_t data)
void pit68230_device::wr_pitreg_psr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_psr = data;
}
@ -601,43 +612,43 @@ void pit68230_device::wr_pitreg_tcr(uint8_t data)
int pen = 0;
int sqr = 0;
LOG(("%s(%02x) %s\n", FUNCNAME, data, tag()));
LOG("%s(%02x) %s\n", FUNCNAME, data, tag());
m_tcr = data;
switch (m_tcr & REG_TCR_TOUT_TIACK_MASK)
{
case REG_TCR_PC3_PC7:
case REG_TCR_PC3_PC7_DC: LOG(("- PC3 and PC7 used as I/O pins\n")); break;
case REG_TCR_PC3_PC7_DC: LOG("- PC3 and PC7 used as I/O pins\n"); break;
case REG_TCR_TOUT_PC7_SQ:
case REG_TCR_TOUT_PC7_SQ_DC: LOG(("- PC3 used as SQuare wave TOUT and PC7 used as I/O pin - not implemented yet\n")); sqr = 1; break;
case REG_TCR_TOUT_TIACK: LOG(("- PC3 used as TOUT and PC7 used as TIACK - not implemented yet\n")); tout = 1; tiack = 1; break;
case REG_TCR_TOUT_TIACK_INT: LOG(("- PC3 used as TOUT and PC7 used as TIACK, Interrupts enabled\n")); tout = 1; tiack = 1; irq = 1; break;
case REG_TCR_TOUT_PC7: LOG(("- PC3 used as TOUT and PC7 used as I/O pin - not implemented yet\n")); break;
case REG_TCR_TOUT_PC7_INT: LOG(("- PC3 used as TOUT and PC7 used as I/O pin, Interrupts enabled\n")); tout = 1; irq = 1; break;
case REG_TCR_TOUT_PC7_SQ_DC: LOG("- PC3 used as SQuare wave TOUT and PC7 used as I/O pin - not implemented yet\n"); sqr = 1; break;
case REG_TCR_TOUT_TIACK: LOG("- PC3 used as TOUT and PC7 used as TIACK - not implemented yet\n"); tout = 1; tiack = 1; break;
case REG_TCR_TOUT_TIACK_INT: LOG("- PC3 used as TOUT and PC7 used as TIACK, Interrupts enabled\n"); tout = 1; tiack = 1; irq = 1; break;
case REG_TCR_TOUT_PC7: LOG("- PC3 used as TOUT and PC7 used as I/O pin - not implemented yet\n"); break;
case REG_TCR_TOUT_PC7_INT: LOG("- PC3 used as TOUT and PC7 used as I/O pin, Interrupts enabled\n"); tout = 1; irq = 1; break;
}
switch (m_tcr & REG_TCR_CC_MASK)
{
case REG_TCR_CC_PC2_CLK_PSC: LOG(("- PC2 used as I/O pin,CLK and x32 prescaler are used\n")); clk = 1; psc = 1; break;
case REG_TCR_CC_TEN_CLK_PSC: LOG(("- PC2 used as Timer enable/disable, CLK and presacaler are used - not implemented\n")); pen = 1; clk = 1; psc = 1; break;
case REG_TCR_CC_TIN_PSC: LOG(("- PC2 used as Timer clock and the presacaler is used - not implemented\n")); psc = 1; break;
case REG_TCR_CC_TIN_RAW: LOG(("- PC2 used as Timer clock and the presacaler is NOT used\n")); break;
case REG_TCR_CC_PC2_CLK_PSC: LOG("- PC2 used as I/O pin,CLK and x32 prescaler are used\n"); clk = 1; psc = 1; break;
case REG_TCR_CC_TEN_CLK_PSC: LOG("- PC2 used as Timer enable/disable, CLK and presacaler are used - not implemented\n"); pen = 1; clk = 1; psc = 1; break;
case REG_TCR_CC_TIN_PSC: LOG("- PC2 used as Timer clock and the presacaler is used - not implemented\n"); psc = 1; break;
case REG_TCR_CC_TIN_RAW: LOG("- PC2 used as Timer clock and the presacaler is NOT used\n"); break;
}
LOG(("%s", m_tcr & REG_TCR_ZR ? "- Spec violation, should always be 0!\n" : ""));
LOG(("- Timer %s when reaching 0 (zero)\n", m_tcr & REG_TCR_ZD ? "rolls over" : "reload the preload values"));
LOG(("- Timer is %s\n", m_tcr & REG_TCR_ENABLE ? "enabled" : "disabled"));
LOG("%s", m_tcr & REG_TCR_ZR ? "- Spec violation, should always be 0!\n" : "");
LOG("- Timer %s when reaching 0 (zero)\n", m_tcr & REG_TCR_ZD ? "rolls over" : "reload the preload values");
LOG("- Timer is %s\n", m_tcr & REG_TCR_ENABLE ? "enabled" : "disabled");
if (m_tcr & REG_TCR_ENABLE)
{
m_cntr = 0;
if (pen == 1)
{
LOG(("PC2 enable/disable TBD\n"));
LOG("PC2 enable/disable TBD\n");
}
if (clk == 1)
{
int rate = clock() / (psc == 1 ? 32 : 1);
pit_timer->adjust(attotime::from_hz(rate), TIMER_ID_PIT, attotime::from_hz(rate));
LOG(("PIT timer started @ rate: %d and CLK: %d,\n", rate, clock()));
LOG("PIT timer started @ rate: %d and CLK: %d,\n", rate, clock());
}
}
else
@ -649,34 +660,34 @@ void pit68230_device::wr_pitreg_tcr(uint8_t data)
void pit68230_device::wr_pitreg_tivr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": \n", FUNCNAME, data, tag()));
LOG("%s(%02x) \"%s\": \n", FUNCNAME, data, tag());
m_tivr = data;
}
void pit68230_device::wr_pitreg_cprh(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_cpr &= ~0xff0000;
m_cpr |= ((data << 16) & 0xff0000);
}
void pit68230_device::wr_pitreg_cprm(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_cpr &= ~0x00ff00;
m_cpr |= ((data << 8) & 0x00ff00);
}
void pit68230_device::wr_pitreg_cprl(uint8_t data)
{
LOG(("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data));
LOG("%s(%02x) \"%s\": %s - %02x\n", FUNCNAME, data, tag(), FUNCNAME, data);
m_cpr &= ~0x0000ff;
m_cpr |= ((data << 0) & 0x0000ff);
}
void pit68230_device::wr_pitreg_tsr(uint8_t data)
{
LOG(("%s(%02x) \"%s\": \n", FUNCNAME, data, tag()));
LOG("%s(%02x) \"%s\": \n", FUNCNAME, data, tag());
if (data & 1)
{
m_tsr = 0; // A write resets the TSR;
@ -686,8 +697,8 @@ void pit68230_device::wr_pitreg_tsr(uint8_t data)
WRITE8_MEMBER (pit68230_device::write)
{
LOG(("\"%s\" %s: Register write '%02x' -> [%02x]\n", tag(), FUNCNAME, data, offset ));
LOGSETUP((" * %s Reg %02x <- %02x \n", tag(), offset, data));
LOG("\"%s\" %s: Register write '%02x' -> [%02x]\n", tag(), FUNCNAME, data, offset );
LOGSETUP(" * %s Reg %02x <- %02x \n", tag(), offset, data);
switch (offset) {
case PIT_68230_PGCR: wr_pitreg_pgcr(data); break;
case PIT_68230_PSRR: wr_pitreg_psrr(data); break;
@ -713,7 +724,7 @@ WRITE8_MEMBER (pit68230_device::write)
case PIT_68230_CNTRL: break; // Ignores write per spec, read only register
case PIT_68230_TSR: wr_pitreg_tsr(data); break;
default:
LOG (("Unhandled Write of %02x to register %02x", data, offset));
LOG("Unhandled Write of %02x to register %02x", data, offset);
}
#if VERBOSE > 2
@ -741,49 +752,49 @@ static int32_t or_ofs = 0;
uint8_t pit68230_device::rr_pitreg_pgcr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pgcr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_pgcr);
return m_pgcr;
}
uint8_t pit68230_device::rr_pitreg_psrr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_psrr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_psrr);
return m_psrr & 0x7f; // mask out unused bits
}
uint8_t pit68230_device::rr_pitreg_paddr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_paddr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_paddr);
return m_paddr;
}
uint8_t pit68230_device::rr_pitreg_pbddr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbddr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_pbddr);
return m_pbddr;
}
uint8_t pit68230_device::rr_pitreg_pcddr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pcddr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_pcddr);
return m_pcddr;
}
uint8_t pit68230_device::rr_pitreg_pivr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pivr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_pivr);
return m_pivr;
}
uint8_t pit68230_device::rr_pitreg_pacr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pacr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_pacr);
return m_pacr;
}
uint8_t pit68230_device::rr_pitreg_pbcr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbcr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_pbcr);
return m_pbcr;
}
@ -798,7 +809,7 @@ uint8_t pit68230_device::rr_pitreg_padr()
{
m_padr |= (m_pail & ~m_paddr);
}
LOGDR(("%s %s <- %02x\n",tag(), FUNCNAME, m_padr));
LOGDR("%s %s <- %02x\n",tag(), FUNCNAME, m_padr);
return m_padr;
}
@ -821,7 +832,8 @@ uint8_t pit68230_device::rr_pitreg_pbdr()
m_pbdr |= (m_pbil & ~m_pbddr);
}
//LOGDR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pbdr));
LOGDR("%s %s <- %02x\n",tag(), FUNCNAME, m_pbdr);
return m_pbdr;
}
@ -837,7 +849,8 @@ uint8_t pit68230_device::rr_pitreg_pcdr()
m_pcdr |= (m_pcil & ~m_pcddr);
}
if (m_pcdr != 0) { LOGDR(("%s %s <- %02x\n",tag(), FUNCNAME, m_pcdr)); }
if (m_pcdr != 0) { LOGDR("%s %s <- %02x\n",tag(), FUNCNAME, m_pcdr); }
return m_pcdr;
}
@ -850,7 +863,7 @@ uint8_t pit68230_device::rr_pitreg_paar()
// NOTE: no side effect emulated so using ..padr
uint8_t ret;
ret = m_pa_in_cb();
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, ret));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, ret);
return ret;
}
@ -863,7 +876,7 @@ uint8_t pit68230_device::rr_pitreg_pbar()
// NOTE: no side effect emulated so using ..pbdr
uint8_t ret;
ret = m_pb_in_cb();
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, ret));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, ret);
return ret;
}
@ -875,61 +888,61 @@ uint8_t pit68230_device::rr_pitreg_pbar()
* 3-0 a one is the active or asserted state. */
uint8_t pit68230_device::rr_pitreg_psr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_psr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_psr);
return m_psr;
}
uint8_t pit68230_device::rr_pitreg_tcr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_tcr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_tcr);
return m_tcr;
}
uint8_t pit68230_device::rr_pitreg_tivr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_tivr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_tivr);
return m_tivr;
}
uint8_t pit68230_device::rr_pitreg_cprh()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cpr >> 16) & 0xff));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, (m_cpr >> 16) & 0xff);
return (m_cpr >> 16) & 0xff;
}
uint8_t pit68230_device::rr_pitreg_cprm()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cpr >> 8) & 0xff));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, (m_cpr >> 8) & 0xff);
return (m_cpr >> 8) & 0xff;
}
uint8_t pit68230_device::rr_pitreg_cprl()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cpr >> 0) & 0xff));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, (m_cpr >> 0) & 0xff);
return (m_cpr >> 0) & 0xff;
}
uint8_t pit68230_device::rr_pitreg_cntrh()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 16) & 0xff));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 16) & 0xff);
return (m_cntr >> 16) & 0xff;
}
uint8_t pit68230_device::rr_pitreg_cntrm()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 8) & 0xff));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 8) & 0xff);
return (m_cntr >> 8) & 0xff;
}
uint8_t pit68230_device::rr_pitreg_cntrl()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 0) & 0xff));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, (m_cntr >> 0) & 0xff);
return (m_cntr >> 0) & 0xff;
}
uint8_t pit68230_device::rr_pitreg_tsr()
{
LOGR(("%s %s <- %02x\n",tag(), FUNCNAME, m_tsr));
LOGR("%s %s <- %02x\n",tag(), FUNCNAME, m_tsr);
return m_tsr;
}
@ -961,13 +974,13 @@ READ8_MEMBER (pit68230_device::read){
case PIT_68230_CNTRL: data = rr_pitreg_cntrl(); break;
case PIT_68230_TSR: data = rr_pitreg_tsr(); break;
default:
LOG (("Unhandled read register %02x returning 0x00\n", offset));
LOG("Unhandled read register %02x returning 0x00\n", offset);
data = 0;
}
#if VERBOSE > 2
if (offset != or_ofs || data != or_data || or_cnt >= 1000) {
LOGSETUP((" * %s Reg %02x -> %02x \n", tag(), offset, data));
LOGSETUP(" * %s Reg %02x -> %02x \n", tag(), offset, data);
if (or_cnt > 1)
{
logerror ("\npit68230_device::read: previous identical operation performed %02x times\n", or_cnt);

View File

@ -66,26 +66,47 @@
*
* History of Force Computers
*---------------------------
* see fccpu30.cpp
*
* Misc links about Force Computes and this board:
*------------------------------------------------
* http://bitsavers.trailing-edge.com/pdf/forceComputers/
* http://bitsavers.org/pdf/forceComputers/
*
* Description(s)
* -------------
* CPU-20 has the following feature set
* CPU-20 has the following feature set:
* - 68020 CPU with l6.7MHz Clock Frequency
* - 68881 Floating Point Coprocessor with l6.7MHz Clock Frequency
* - Static RAM 5l2Kbyte with 55ns access time
* - 5l2Kbyte (max) of ROM/EPROM for the system
* - 2 RS232 Multi Protocol Communication Interfaces (110-38400 Baud)
* - Parallel Interface and Timer Chip provides local control and timer function
* - VMXbus Primary Master Interface to p2 connector
* - Local Interrupt handling via interrupt vectors
* - Each VMEbus IRQ level can be enabled/disabled via software
* - Address range for the short I/O address modifies (AM4)
* - Address range for the standard address modifier
* - Single level bus arbiter
* - One level slave bus arbitration
* - Power monitor
* - RESET and SOFTWARE ABORT function switches
* - Fully VMEbus, VMXbus and IEEE Pl~14 compatible
*
* Address Map
* --------------------------------------------------------------------------
* Range Decscription
* --------------------------------------------------------------------------
Basadressen av I / O-enheter:
* 00000000-0xxFFFFF Shared DRAM D8-D32
* 0yy00000-FAFFFFFF VME A32 D8-D32 yy=xx+1
* FB000000-FBFEFFFF VME A24 D8-D32
* FBFF0000-FBFFFFFF VME A16 D8-D32
* FC000000-FCFEFFFF VME A24 D8-D16
* FCFF0000-FCFFFFFF VME A16 D8-D16
* .... TBC
* FF800800 BIM
* FF800C00 PIT
* FF800000 MPCC
* FF800A00 RTC
* --------------------------------------------------------------------------
*
* PIT #1 hardware wiring
@ -121,10 +142,8 @@
*---------------------------------------------------------------------------
* TODO:
* - Find accurate documentation and adjust memory map
* - Add layouts and system description(s)
* - Add layout
* - Write & add 68561 UART
* - Write & add VME device
* - Write & add 68153 BIM
* - Add 68230 PIT
* - Add variants of boards in the CPU-20 and CPU-21 family
* - Add FGA, DUSCC devices and CPU-22 variants
@ -137,19 +156,23 @@
#include "bus/vme/vme_fcisio.h"
#include "bus/vme/vme_fcscsi.h"
#include "bus/rs232/rs232.h"
#include "machine/68230pit.h"
#include "machine/68153bim.h"
#include "machine/clock.h"
#define LOG_GENERAL 0x01
#define LOG_SETUP 0x02
#define LOG_PRINTF 0x04
#define LOG_INT 0x08
#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL)
#define VERBOSE 0 // (LOG_PRINTF | LOG_SETUP | LOG_GENERAL | LOG_INT)
#define LOGMASK(mask, ...) do { if (VERBOSE & mask) logerror(__VA_ARGS__); } while (0)
#define LOGLEVEL(mask, level, ...) do { if ((VERBOSE & mask) >= level) logerror(__VA_ARGS__); } while (0)
#define LOG(...) LOGMASK(LOG_GENERAL, __VA_ARGS__)
#define LOGSETUP(...) LOGMASK(LOG_SETUP, __VA_ARGS__)
#define LOGINT(...) LOGMASK(LOG_INT, __VA_ARGS__)
#if VERBOSE & LOG_PRINTF
#define logerror printf
@ -167,20 +190,33 @@ public:
cpu20_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device (mconfig, type, tag)
, m_maincpu (*this, "maincpu")
, m_pit (*this, "pit")
, m_bim (*this, "bim")
{
}
DECLARE_READ32_MEMBER (bootvect_r);
DECLARE_WRITE32_MEMBER (bootvect_w);
DECLARE_WRITE_LINE_MEMBER(bim_irq_callback);
uint8_t bim_irq_state;
int bim_irq_level;
virtual void machine_start () override;
virtual void machine_reset () override;
private:
required_device<m68000_base_device> m_maincpu;
required_device<pit68230_device> m_pit;
required_device<bim68153_device> m_bim;
// Pointer to System ROMs needed by bootvect_r and masking RAM buffer for post reset accesses
uint32_t *m_sysrom;
uint32_t m_sysram[2];
void update_irq_to_maincpu();
};
/*
*/
static ADDRESS_MAP_START (cpu20_mem, AS_PROGRAM, 32, cpu20_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE (0x00000000, 0x00000007) AM_ROM AM_READ (bootvect_r) /* ROM mirror just during reset */
@ -188,6 +224,11 @@ static ADDRESS_MAP_START (cpu20_mem, AS_PROGRAM, 32, cpu20_state)
AM_RANGE (0x00000008, 0x003fffff) AM_RAM /* RAM installed in machine start */
AM_RANGE (0xff040000, 0xff04ffff) AM_RAM /* RAM installed in machine start */
AM_RANGE (0xff000000, 0xff00ffff) AM_ROM AM_REGION("roms", 0x0000)
// AM_RANGE (0xff800000, 0xff80000f) AM_DEVREADWRITE8("mpcc", mpcc68561_device, read, write, 0x00ff00ff)
// AM_RANGE (0xff800200, 0xff80020f) AM_DEVREADWRITE8("pit2", pit68230_device, read, write, 0xff00ff00)
AM_RANGE (0xff800800, 0xff80080f) AM_DEVREADWRITE8("bim", bim68153_device, read, write, 0xff00ff00)
// AM_RANGE (0xff800a00, 0xff800a0f) AM_DEVREADWRITE8("rtc", rtc_device, read, write, 0x00ff00ff)
AM_RANGE (0xff800c00, 0xff800dff) AM_DEVREADWRITE8("pit", pit68230_device, read, write, 0xffffffff)
ADDRESS_MAP_END
/* Input ports */
@ -241,25 +282,33 @@ WRITE32_MEMBER (cpu20_state::bootvect_w){
m_sysrom = &m_sysram[0]; // redirect all upcomming accesses to masking RAM until reset.
}
#if 0
WRITE_LINE_MEMBER(cpu20_state::bim_irq_callback)
{
LOGINT("%s(%02x)\n", FUNCNAME, state);
bim_irq_state = state;
bim_irq_level = m_bim->get_irq_level();
LOGINT(" - BIM irq level %02x\n", bim_irq_level);
update_irq_to_maincpu();
}
void cpu20_state::update_irq_to_maincpu()
{
LOGINT(("%s()\n", FUNCNAME);
LOGINT((" - fga_irq_level: %02x\n", fga_irq_level));
LOGINT((" - fga_irq_state: %02x\n", fga_irq_state));
switch (fga_irq_level & 0x07)
LOGINT("%s()\n", FUNCNAME);
LOGINT(" - bim_irq_level: %02x\n", bim_irq_level);
LOGINT(" - bim_irq_state: %02x\n", bim_irq_state);
switch (bim_irq_level & 0x07)
{
case 1: m_maincpu->set_input_line(M68K_IRQ_1, fga_irq_state); break;
case 2: m_maincpu->set_input_line(M68K_IRQ_2, fga_irq_state); break;
case 3: m_maincpu->set_input_line(M68K_IRQ_3, fga_irq_state); break;
case 4: m_maincpu->set_input_line(M68K_IRQ_4, fga_irq_state); break;
case 5: m_maincpu->set_input_line(M68K_IRQ_5, fga_irq_state); break;
case 6: m_maincpu->set_input_line(M68K_IRQ_6, fga_irq_state); break;
case 7: m_maincpu->set_input_line(M68K_IRQ_7, fga_irq_state); break;
case 1: m_maincpu->set_input_line(M68K_IRQ_1, bim_irq_state); break;
case 2: m_maincpu->set_input_line(M68K_IRQ_2, bim_irq_state); break;
case 3: m_maincpu->set_input_line(M68K_IRQ_3, bim_irq_state); break;
case 4: m_maincpu->set_input_line(M68K_IRQ_4, bim_irq_state); break;
case 5: m_maincpu->set_input_line(M68K_IRQ_5, bim_irq_state); break;
case 6: m_maincpu->set_input_line(M68K_IRQ_6, bim_irq_state); break;
case 7: m_maincpu->set_input_line(M68K_IRQ_7, bim_irq_state); break;
default: logerror("Programmatic error in %s, please report\n", FUNCNAME);
}
}
#endif
static SLOT_INTERFACE_START(fccpu20_vme_cards)
SLOT_INTERFACE("fcisio", VME_FCISIO1)
@ -273,9 +322,23 @@ static MACHINE_CONFIG_START (cpu20, cpu20_state)
/* basic machine hardware */
MCFG_CPU_ADD ("maincpu", M68020, XTAL_16MHz) /* Crytstal not verified */
MCFG_CPU_PROGRAM_MAP (cpu20_mem)
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE("bim", bim68153_device, iack)
MCFG_VME_DEVICE_ADD("vme")
MCFG_VME_SLOT_ADD ("vme", "slot1", fccpu20_vme_cards, nullptr)
/* PIT Parallel Interface and Timer device, assumed strapped for on board clock */
MCFG_DEVICE_ADD ("pit", PIT68230, XTAL_8_664MHz)
MCFG_PIT68230_TIMER_IRQ_CB(DEVWRITELINE("bim", bim68153_device, int2_w))
// MCFG_DEVICE_ADD ("pit2", PIT68230, XTAL_8_664MHz)
MCFG_MC68153_ADD("bim", XTAL_16MHz / 2)
MCFG_BIM68153_OUT_INT_CB(WRITELINE(cpu20_state, bim_irq_callback))
/*INT0 - Abort switch */
/*INT1 - MPCC@8.064 MHz aswell */
/*INT2 - PI/T timer */
/*INT3 - SYSFAIL/IRQVMX/ACFAIL/MPCC2/3 */
MACHINE_CONFIG_END
/* ROM definitions */
@ -292,7 +355,37 @@ ROM_END
* System ROM information
*
* xxxxxxx bootprom version xxx is released mmm dd, yyyy, coprighted by FORCE Computers Gmbh
*
* BIM setup: (reordered for improved reading)
* : 0 Reg vector <- 1f
* : 1 Reg vector <- 1c
* : 2 Reg vector <- 1d
* : 3 Reg vector <- 1c
* : 0 Reg control <- 57 - Lev:7 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0
* : 1 Reg control <- 54 - Lev:4 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0
* : 2 Reg control <- 55 - Lev:5 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0
* : 3 Reg control <- 54 - Lev:4 Auto Disable:0 Int Enable:1 Vector:0 Auto Clear:1 Flag:0
*
* PIT setup:
* :pit Reg 0a -> 00
* :pit Reg 00 <- 30 - PGCR - Mode 0, H34:enabled, H12:enabled, Sense assert H4:Lo, H3:Lo, H2:Lo, H1:Lo
* :pit Reg 01 <- 08 - PSSR - PC4 pin activated, PC5 pin support no interrupts, H prio mode:0
* :pit Reg 06 <- 84 - PACR
* :pit Reg 02 <- 00 - PADDR: 00
* :pit Reg 07 <- 84 - PBCR
* :pit Reg 09 <- ff - PBDR
* :pit Reg 03 <- ff - PBDDR: ff
* :pit Reg 0c <- 07 - PCDR
* :pit Reg 04 <- 87 - PCDDR: 87
* :pit Reg 15 <- d8 - CPRL
* :pit Reg 14 <- 09 - CPRM
* :pit Reg 13 <- 00 - CPRH
* :pit Reg 10 <- e1 - TCR - PC3 used as TOUT and PC7 used as I/O pin, Interrupts enabled
- PC2 used as I/O pin,CLK and x32 prescaler are used
- Timer reload the preload values when reaching 0 (zero)
- Timer is enabled
*/
/* Driver */
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP (1986, fccpu20, 0, 0, cpu20, cpu20, driver_device, 0, "Force Computers Gmbh", "SYS68K/CPU-20", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_TYPE_COMPUTER )

View File

@ -47,7 +47,7 @@
*
* Misc links about Force Computes and this board:
*------------------------------------------------
* http://bitsavers.trailing-edge.com/pdf/forceComputers/
* http://bitsavers.org/pdf/forceComputers/
*
* Description, from datasheets etc
* --------------------------------
@ -66,6 +66,34 @@
* - One 5 1/4" full height space for the winchester drive
* - Up to 6 free slots for system expansion
*
* Features per version
* --------------------------------------------------------------------------
* Description miniFORCE 2P21A miniFORCE 2P21 miniFORCE 2P21S
* --------------------------------------------------------------------------
* CPU 68020 20 MHz 16.7 MHz 12.5 MHz
* FPU 68881 20 MHz 16.7 MHz 12.5 MHz
* Memory SRAM 512KB 512KB 512KB
* Serial 68561 MPSC 2 RS232 ports 2 RS232 ports 2 RS232 ports
* Winchester HDD 51 MB 51 MB 20 MB
* Floppy 1 MB 1 MB 1 MB
* Timer 68230 PIT 1 1 1
* RTOS PDOS PDOS PDOS
* --------------------------------------------------------------------------
*
* Address Map from CPU-21 board perspective
* --------------------------------------------------------------------------
* Range Decscription
* --------------------------------------------------------------------------
* 00000000-0007FFFF Local 512KB SRAM CPU-21 CPU board
* 00080000-000FFFFF VME A32 512KB SRAM CPU-22 SRAM board (optional)
* 00080000-FAFFFFFF VME A32 Memory if no CPU-22 installed
* 00100000-FAFFFFFF VME A32 Memory if CPU-22 installed
* FCB00000-FCB001FF VME A24 First SIO-1 card (optional)
* FCB01000-FCB0100F VME A24 WFC-l card
* FCB02000-FCB022FF VME A24 ASCU-l/2 card (optional)
* FF000000-FF07FFFF EPROM Area 1
* FF080000-FFFFFFFF Local I/O devices
* --------------------------------------------------------------------------
*/
#include "emu.h"
#include "bus/vme/vme.h"