i8257: new 8257 based on am9517a [Carl]

facnucspmg: fix up dmac and fdc (nw)
This commit is contained in:
cracyc 2014-04-28 03:20:14 +00:00
parent 37b28d339a
commit bb2fcfc661
8 changed files with 925 additions and 15 deletions

2
.gitattributes vendored
View File

@ -2459,6 +2459,8 @@ src/emu/machine/i8251.c svneol=native#text/plain
src/emu/machine/i8251.h svneol=native#text/plain
src/emu/machine/i8255.c svneol=native#text/plain
src/emu/machine/i8255.h svneol=native#text/plain
src/emu/machine/i8257.c svneol=native#text/plain
src/emu/machine/i8257.h svneol=native#text/plain
src/emu/machine/i8271.c svneol=native#text/plain
src/emu/machine/i8271.h svneol=native#text/plain
src/emu/machine/i8279.c svneol=native#text/plain

630
src/emu/machine/i8257.c Normal file
View File

@ -0,0 +1,630 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/***************************************************************************
Intel 8257 DMA Controller emulation
Copyright the MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
***************************************************************************/
#include "i8257.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
const device_type I8257N = &device_creator<i8257n_device>;
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
#define LOG 0
enum
{
REGISTER_ADDRESS = 0,
REGISTER_WORD_COUNT,
REGISTER_STATUS = 8,
REGISTER_COMMAND = REGISTER_STATUS
};
#define MODE_CHAN_ENABLE(x) BIT(m_transfer_mode, x)
#define MODE_ROTATING_PRIORITY BIT(m_transfer_mode, 4)
#define MODE_EXTENDED_WRITE BIT(m_transfer_mode, 5)
#define MODE_TC_STOP BIT(m_transfer_mode, 6)
#define MODE_AUTOLOAD BIT(m_transfer_mode, 7)
#define MODE_TRANSFER_MASK (m_channel[m_current_channel].m_mode)
#define MODE_TRANSFER_VERIFY 0
#define MODE_TRANSFER_WRITE 1
#define MODE_TRANSFER_READ 2
enum
{
STATE_SI,
STATE_S0,
STATE_S1,
STATE_S2,
STATE_S3,
STATE_SW,
STATE_S4,
};
//**************************************************************************
// INLINE HELPERS
//**************************************************************************
//-------------------------------------------------
// dma_request -
//-------------------------------------------------
inline void i8257n_device::dma_request(int channel, int state)
{
if (LOG) logerror("I8257N '%s' Channel %u DMA Request: %u\n", tag(), channel, state);
if (state)
{
m_request |= 1 << channel;
}
else
{
m_request &= ~1 << channel;
}
trigger(1);
}
//-------------------------------------------------
// is_request_active -
//-------------------------------------------------
inline bool i8257n_device::is_request_active(int channel)
{
return (BIT(m_request, channel) && MODE_CHAN_ENABLE(channel)) ? true : false;
}
//-------------------------------------------------
// set_hreq
//-------------------------------------------------
inline void i8257n_device::set_hreq(int state)
{
if (m_hreq != state)
{
m_out_hrq_cb(state);
m_hreq = state;
}
}
//-------------------------------------------------
// set_tc -
//-------------------------------------------------
inline void i8257n_device::set_tc(int state)
{
if (m_tc != state)
{
m_out_tc_cb(state);
m_tc = state;
}
}
//-------------------------------------------------
// set_dack - dack is active low
//-------------------------------------------------
inline void i8257n_device::set_dack()
{
m_out_dack_0_cb(m_current_channel != 0);
m_out_dack_1_cb(m_current_channel != 1);
m_out_dack_2_cb(m_current_channel != 2);
m_out_dack_3_cb(m_current_channel != 3);
}
//-------------------------------------------------
// dma_read -
//-------------------------------------------------
inline void i8257n_device::dma_read()
{
offs_t offset = m_channel[m_current_channel].m_address;
switch (MODE_TRANSFER_MASK)
{
case MODE_TRANSFER_VERIFY:
case MODE_TRANSFER_WRITE:
switch(m_current_channel)
{
case 0:
m_temp = m_in_ior_0_cb(offset);
break;
case 1:
m_temp = m_in_ior_1_cb(offset);
break;
case 2:
m_temp = m_in_ior_2_cb(offset);
break;
case 3:
m_temp = m_in_ior_3_cb(offset);
break;
}
break;
case MODE_TRANSFER_READ:
m_temp = m_in_memr_cb(offset);
break;
}
}
//-------------------------------------------------
// dma_write -
//-------------------------------------------------
inline void i8257n_device::dma_write()
{
offs_t offset = m_channel[m_current_channel].m_address;
switch (MODE_TRANSFER_MASK)
{
case MODE_TRANSFER_VERIFY: {
UINT8 v1 = m_in_memr_cb(offset);
if(0 && m_temp != v1)
logerror("%s: verify error %02x vs. %02x\n", tag(), m_temp, v1);
break;
}
case MODE_TRANSFER_WRITE:
m_out_memw_cb(offset, m_temp);
break;
case MODE_TRANSFER_READ:
switch(m_current_channel)
{
case 0:
m_out_iow_0_cb(offset, m_temp);
break;
case 1:
m_out_iow_1_cb(offset, m_temp);
break;
case 2:
m_out_iow_2_cb(offset, m_temp);
break;
case 3:
m_out_iow_3_cb(offset, m_temp);
break;
}
break;
}
}
//-------------------------------------------------
// end_of_process -
//-------------------------------------------------
inline void i8257n_device::end_of_process()
{
m_status |= 1 << m_current_channel;
m_request &= ~(1 << m_current_channel);
set_tc(1);
if (MODE_AUTOLOAD && (m_current_channel == 2))
{
// autoinitialize
m_channel[2].m_address = m_channel[3].m_address;
m_channel[2].m_count = m_channel[3].m_count;
m_channel[2].m_mode = m_channel[3].m_mode;
}
else if(MODE_TC_STOP)
// disable channel
m_transfer_mode &= ~(1 << m_current_channel);
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// i8257n_device - constructor
//-------------------------------------------------
i8257n_device::i8257n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, I8257N, "I8257N", tag, owner, clock, "i8257n", __FILE__),
device_execute_interface(mconfig, *this),
m_icount(0),
m_hack(0),
m_ready(1),
m_transfer_mode(0),
m_out_hrq_cb(*this),
m_out_tc_cb(*this),
m_in_memr_cb(*this),
m_out_memw_cb(*this),
m_in_ior_0_cb(*this),
m_in_ior_1_cb(*this),
m_in_ior_2_cb(*this),
m_in_ior_3_cb(*this),
m_out_iow_0_cb(*this),
m_out_iow_1_cb(*this),
m_out_iow_2_cb(*this),
m_out_iow_3_cb(*this),
m_out_dack_0_cb(*this),
m_out_dack_1_cb(*this),
m_out_dack_2_cb(*this),
m_out_dack_3_cb(*this)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void i8257n_device::device_start()
{
// set our instruction counter
m_icountptr = &m_icount;
// resolve callbacks
m_out_hrq_cb.resolve_safe();
m_out_tc_cb.resolve_safe();
m_in_memr_cb.resolve();
m_out_memw_cb.resolve_safe();
m_in_ior_0_cb.resolve();
m_in_ior_1_cb.resolve();
m_in_ior_2_cb.resolve();
m_in_ior_3_cb.resolve();
m_out_iow_0_cb.resolve_safe();
m_out_iow_1_cb.resolve_safe();
m_out_iow_2_cb.resolve_safe();
m_out_iow_3_cb.resolve_safe();
m_out_dack_0_cb.resolve_safe();
m_out_dack_1_cb.resolve_safe();
m_out_dack_2_cb.resolve_safe();
m_out_dack_3_cb.resolve_safe();
for (int i = 0; i < 4; i++)
{
m_channel[i].m_address = 0;
m_channel[i].m_count = 0;
m_channel[i].m_mode = 0;
}
// state saving
save_item(NAME(m_msb));
save_item(NAME(m_hreq));
save_item(NAME(m_hack));
save_item(NAME(m_ready));
save_item(NAME(m_state));
save_item(NAME(m_current_channel));
save_item(NAME(m_last_channel));
save_item(NAME(m_transfer_mode));
save_item(NAME(m_status));
save_item(NAME(m_request));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void i8257n_device::device_reset()
{
m_state = STATE_SI;
m_transfer_mode = 0;
m_status = 0;
m_request = 0;
m_msb = 0;
m_current_channel = -1;
m_last_channel = 3;
m_hreq = -1;
m_tc = 0;
set_hreq(0);
set_dack();
}
bool i8257n_device::next_channel()
{
int priority[] = { 0, 1, 2, 3 };
if (MODE_ROTATING_PRIORITY)
{
int last_channel = m_last_channel;
for (int channel = 3; channel >= 0; channel--)
{
priority[channel] = last_channel;
last_channel--;
if (last_channel < 0) last_channel = 3;
}
}
for (int channel = 0; channel < 4; channel++)
{
if (is_request_active(priority[channel]))
{
m_current_channel = m_last_channel = priority[channel];
return true;
}
}
return false;
}
//-------------------------------------------------
// execute_run -
//-------------------------------------------------
void i8257n_device::execute_run()
{
do
{
switch (m_state)
{
case STATE_SI:
set_tc(0);
if(next_channel())
m_state = STATE_S0;
else
{
suspend_until_trigger(1, true);
m_icount = 0;
}
break;
case STATE_S0:
set_hreq(1);
if (m_hack)
{
m_state = STATE_S1;
}
else
{
suspend_until_trigger(1, true);
m_icount = 0;
}
break;
case STATE_S1:
set_tc(0);
m_state = STATE_S2;
break;
case STATE_S2:
set_dack();
m_state = STATE_S3;
break;
case STATE_S3:
dma_read();
if (MODE_EXTENDED_WRITE)
{
dma_write();
}
m_state = m_ready ? STATE_S4 : STATE_SW;
break;
case STATE_SW:
m_state = m_ready ? STATE_S4 : STATE_SW;
break;
case STATE_S4:
if (!MODE_EXTENDED_WRITE)
{
dma_write();
}
m_channel[m_current_channel].m_count--;
m_channel[m_current_channel].m_count &= 0x3fff;
m_channel[m_current_channel].m_address++;
if(!m_channel[m_current_channel].m_count)
end_of_process();
if(next_channel())
m_state = STATE_S1;
else
{
set_hreq(0);
m_current_channel = -1;
m_state = STATE_SI;
set_dack();
}
break;
}
m_icount--;
} while (m_icount > 0);
}
//-------------------------------------------------
// read -
//-------------------------------------------------
READ8_MEMBER( i8257n_device::read )
{
UINT8 data = 0;
if (!BIT(offset, 3))
{
int channel = (offset >> 1) & 0x03;
switch (offset & 0x01)
{
case REGISTER_ADDRESS:
if (m_msb)
{
data = m_channel[channel].m_address >> 8;
}
else
{
data = m_channel[channel].m_address & 0xff;
}
break;
case REGISTER_WORD_COUNT:
if (m_msb)
{
data = (m_channel[channel].m_count >> 8) | (m_channel[channel].m_mode << 6);
}
else
{
data = m_channel[channel].m_count & 0xff;
}
break;
}
m_msb = !m_msb;
}
else if(offset == 8)
{
data = m_status;
// clear TC bits
m_status &= 0xf0;
}
return data;
}
//-------------------------------------------------
// write -
//-------------------------------------------------
WRITE8_MEMBER( i8257n_device::write )
{
if (!BIT(offset, 3))
{
int channel = (offset >> 1) & 0x03;
switch (offset & 0x01)
{
case REGISTER_ADDRESS:
if (m_msb)
{
m_channel[channel].m_address = (data << 8) | (m_channel[channel].m_address & 0xff);
if(MODE_AUTOLOAD && (channel == 2))
m_channel[3].m_address = (data << 8) | (m_channel[3].m_address & 0xff);
}
else
{
m_channel[channel].m_address = (m_channel[channel].m_address & 0xff00) | data;
if(MODE_AUTOLOAD && (channel == 2))
m_channel[3].m_address = (m_channel[3].m_address & 0xff00) | data;
}
break;
case REGISTER_WORD_COUNT:
if (m_msb)
{
m_channel[channel].m_count = ((data & 0x3f) << 8) | (m_channel[channel].m_count & 0xff);
m_channel[channel].m_mode = (data >> 6);
if(MODE_AUTOLOAD && (channel == 2))
m_channel[3].m_count = ((data & 0x3f) << 8) | (m_channel[3].m_count & 0xff);
m_channel[3].m_mode = (data >> 6);
}
else
{
m_channel[channel].m_count = (m_channel[channel].m_count & 0xff00) | data;
if(MODE_AUTOLOAD && (channel == 2))
m_channel[3].m_count = (m_channel[3].m_count & 0xff00) | data;
}
break;
}
m_msb = !m_msb;
}
else if(offset == 8)
{
m_transfer_mode = data;
if (LOG) logerror("I8257N '%s' Command Register: %02x\n", tag(), m_transfer_mode);
}
trigger(1);
}
//-------------------------------------------------
// hlda_w - hold acknowledge
//-------------------------------------------------
WRITE_LINE_MEMBER( i8257n_device::hlda_w )
{
if (LOG) logerror("I8257N '%s' Hold Acknowledge: %u\n", tag(), state);
m_hack = state;
trigger(1);
}
//-------------------------------------------------
// ready_w - ready
//-------------------------------------------------
WRITE_LINE_MEMBER( i8257n_device::ready_w )
{
if (LOG) logerror("I8257N '%s' Ready: %u\n", tag(), state);
m_ready = state;
}
//-------------------------------------------------
// dreq0_w - DMA request for channel 0
//-------------------------------------------------
WRITE_LINE_MEMBER( i8257n_device::dreq0_w )
{
dma_request(0, state);
}
//-------------------------------------------------
// dreq0_w - DMA request for channel 1
//-------------------------------------------------
WRITE_LINE_MEMBER( i8257n_device::dreq1_w )
{
dma_request(1, state);
}
//-------------------------------------------------
// dreq1_w - DMA request for channel 2
//-------------------------------------------------
WRITE_LINE_MEMBER( i8257n_device::dreq2_w )
{
dma_request(2, state);
}
//-------------------------------------------------
// dreq3_w - DMA request for channel 3
//-------------------------------------------------
WRITE_LINE_MEMBER( i8257n_device::dreq3_w )
{
dma_request(3, state);
}

208
src/emu/machine/i8257.h Normal file
View File

@ -0,0 +1,208 @@
// license:BSD-3-Clause
// copyright-holders:Curt Coder
/***************************************************************************
Intel 8257 DMA Controller emulation
Copyright the MESS Team.
Visit http://mamedev.org for licensing and usage restrictions.
****************************************************************************
_____ _____
_I/OR 1 |* \_/ | 40 A7
_I/OW 2 | | 39 A6
_MEMR 3 | | 38 A5
_MEMW 4 | | 37 A4
MARK 5 | | 36 TC
READY 6 | | 35 A3
HLDA 7 | | 34 A2
ADSTB 8 | | 33 A1
AEN 9 | | 32 A0
HRQ 10 | 8257 | 31 Vcc
_CS 11 | | 30 D0
CLK 12 | | 29 D1
RESET 13 | | 28 D2
_DACK2 14 | | 27 D3
_DACK3 15 | | 26 D4
DRQ3 16 | | 25 _DACK0
DRQ2 17 | | 24 _DACK1
DRQ1 18 | | 23 D5
DRQ0 19 | | 22 D6
GND 20 |_____________| 21 D7
***************************************************************************/
#pragma once
#ifndef __I8257N__
#define __I8257N__
#include "emu.h"
/***************************************************************************
DEVICE CONFIGURATION MACROS
***************************************************************************/
#define MCFG_I8257N_ADD(_tag, _clock, _config) \
MCFG_DEVICE_ADD(_tag, I8257N, _clock) \
MCFG_DEVICE_CONFIG(_config)
#define MCFG_I8257N_OUT_HRQ_CB(_devcb) \
devcb = &i8257n_device::set_out_hrq_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_TC_CB(_devcb) \
devcb = &i8257n_device::set_out_tc_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_IN_MEMR_CB(_devcb) \
devcb = &i8257n_device::set_in_memr_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_MEMW_CB(_devcb) \
devcb = &i8257n_device::set_out_memw_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_IN_IOR_0_CB(_devcb) \
devcb = &i8257n_device::set_in_ior_0_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_IN_IOR_1_CB(_devcb) \
devcb = &i8257n_device::set_in_ior_1_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_IN_IOR_2_CB(_devcb) \
devcb = &i8257n_device::set_in_ior_2_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_IN_IOR_3_CB(_devcb) \
devcb = &i8257n_device::set_in_ior_3_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_IOW_0_CB(_devcb) \
devcb = &i8257n_device::set_out_iow_0_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_IOW_1_CB(_devcb) \
devcb = &i8257n_device::set_out_iow_1_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_IOW_2_CB(_devcb) \
devcb = &i8257n_device::set_out_iow_2_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_IOW_3_CB(_devcb) \
devcb = &i8257n_device::set_out_iow_3_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_DACK_0_CB(_devcb) \
devcb = &i8257n_device::set_out_dack_0_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_DACK_1_CB(_devcb) \
devcb = &i8257n_device::set_out_dack_1_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_DACK_2_CB(_devcb) \
devcb = &i8257n_device::set_out_dack_2_callback(*device, DEVCB2_##_devcb);
#define MCFG_I8257N_OUT_DACK_3_CB(_devcb) \
devcb = &i8257n_device::set_out_dack_3_callback(*device, DEVCB2_##_devcb);
// ======================> i8257n_device
class i8257n_device : public device_t,
public device_execute_interface
{
public:
// construction/destruction
i8257n_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
DECLARE_WRITE_LINE_MEMBER( hlda_w );
DECLARE_WRITE_LINE_MEMBER( ready_w );
DECLARE_WRITE_LINE_MEMBER( dreq0_w );
DECLARE_WRITE_LINE_MEMBER( dreq1_w );
DECLARE_WRITE_LINE_MEMBER( dreq2_w );
DECLARE_WRITE_LINE_MEMBER( dreq3_w );
template<class _Object> static devcb2_base &set_out_hrq_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_hrq_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_tc_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_tc_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_in_memr_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_in_memr_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_memw_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_memw_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_in_ior_0_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_in_ior_0_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_in_ior_1_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_in_ior_1_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_in_ior_2_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_in_ior_2_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_in_ior_3_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_in_ior_3_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_iow_0_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_iow_0_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_iow_1_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_iow_1_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_iow_2_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_iow_2_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_iow_3_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_iow_3_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_dack_0_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_dack_0_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_dack_1_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_dack_1_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_dack_2_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_dack_2_cb.set_callback(object); }
template<class _Object> static devcb2_base &set_out_dack_3_callback(device_t &device, _Object object) { return downcast<i8257n_device &>(device).m_out_dack_3_cb.set_callback(object); }
protected:
// device-level overrides
virtual void device_start();
virtual void device_reset();
virtual void execute_run();
int m_icount;
private:
inline void dma_request(int channel, int state);
inline bool is_request_active(int channel);
inline void set_hreq(int state);
inline void set_dack();
inline void dma_read();
inline void dma_write();
inline void end_of_process();
inline void set_tc(int state);
bool next_channel();
bool m_tc;
int m_msb;
int m_hreq;
int m_hack;
int m_ready;
int m_state;
int m_current_channel;
int m_last_channel;
UINT8 m_transfer_mode;
UINT8 m_status;
UINT8 m_request;
UINT8 m_temp;
devcb2_write_line m_out_hrq_cb;
devcb2_write_line m_out_tc_cb;
/* accessors to main memory */
devcb2_read8 m_in_memr_cb;
devcb2_write8 m_out_memw_cb;
/* channel accessors */
devcb2_read8 m_in_ior_0_cb;
devcb2_read8 m_in_ior_1_cb;
devcb2_read8 m_in_ior_2_cb;
devcb2_read8 m_in_ior_3_cb;
devcb2_write8 m_out_iow_0_cb;
devcb2_write8 m_out_iow_1_cb;
devcb2_write8 m_out_iow_2_cb;
devcb2_write8 m_out_iow_3_cb;
devcb2_write_line m_out_dack_0_cb;
devcb2_write_line m_out_dack_1_cb;
devcb2_write_line m_out_dack_2_cb;
devcb2_write_line m_out_dack_3_cb;
struct
{
UINT16 m_address;
UINT16 m_count;
UINT8 m_mode;
} m_channel[4];
};
// device type definition
extern const device_type I8257N;
#endif

View File

@ -590,6 +590,16 @@ ifneq ($(filter I8251,$(MACHINES)),)
MACHINEOBJS += $(MACHINEOBJ)/i8251.o
endif
#-------------------------------------------------
#
#@src/emu/machine/i8257.h,MACHINES += I8257N
#-------------------------------------------------
ifneq ($(filter I8257N,$(MACHINES)),)
MACHINEOBJS += $(MACHINEOBJ)/i8257.o
endif
#-------------------------------------------------
#
#@src/emu/machine/i8271.h,MACHINES += I8271

View File

@ -449,6 +449,9 @@ The arrows denote direction of data flow.
':maincpu' (FC1A9): unmapped program memory write to F004E = 0096 & 00FF
':maincpu' (FC1AE): unmapped program memory write to F004C = 0010 & 00FF
To boot a floppy put "bp fc5fa,1,{ip=c682;g}" and "bp fc6d7,1,{ip=c755;g}"
into the debugger.
****************************************************************************/
#include "emu.h"
@ -456,7 +459,7 @@ The arrows denote direction of data flow.
#include "cpu/i8085/i8085.h"
#include "machine/ram.h"
#include "machine/i8251.h"
#include "machine/8257dma.h"
#include "machine/i8257.h"
#include "machine/upd765.h"
#include "machine/pic8259.h"
#include "machine/pit8253.h"
@ -513,7 +516,7 @@ public:
required_device<pit8253_device> m_pit1;
required_device<pic8259_device> m_pic0;
required_device<pic8259_device> m_pic1;
required_device<i8257_device> m_dmac;
required_device<i8257n_device> m_dmac;
required_device<mc6845_device> m_crtc;
required_device<upd765a_device> m_fdc;
required_shared_ptr<UINT8> m_shared;
@ -535,10 +538,14 @@ public:
DECLARE_WRITE8_MEMBER(keyboard_row_w);
DECLARE_READ8_MEMBER(keyboard_r);
DECLARE_WRITE8_MEMBER(video_ctrl_w);
DECLARE_READ8_MEMBER(vbl_r);
DECLARE_READ8_MEMBER(fdcdma_r);
DECLARE_WRITE8_MEMBER(fdcdma_w);
DECLARE_READ8_MEMBER(get_slave_ack);
DECLARE_WRITE8_MEMBER(dma_page_w);
DECLARE_WRITE_LINE_MEMBER(vsync_w);
DECLARE_WRITE_LINE_MEMBER(tc_w);
DECLARE_WRITE_LINE_MEMBER(hrq_w);
DECLARE_DRIVER_INIT(fanucspmg);
@ -551,6 +558,7 @@ private:
UINT8 m_vbl_ctrl;
UINT8 m_keyboard_row;
UINT8 m_vbl_stat;
UINT8 m_dma_page;
};
DRIVER_INIT_MEMBER(fanucspmg_state, fanucspmg)
@ -574,17 +582,55 @@ WRITE8_MEMBER(fanucspmg_state::shared_w)
m_shared[offset] = data;
}
READ8_MEMBER(fanucspmg_state::vbl_r)
READ8_MEMBER(fanucspmg_state::get_slave_ack)
{
return m_vbl_stat;
if(offset == 7)
return m_pic1->acknowledge();
return 0x00;
}
WRITE_LINE_MEMBER(fanucspmg_state::tc_w)
{
m_fdc->tc_w(state);
}
WRITE_LINE_MEMBER(fanucspmg_state::hrq_w)
{
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_dmac->hlda_w(state);
}
READ8_MEMBER(fanucspmg_state::fdcdma_r)
{
return m_fdc->dma_r();
}
WRITE8_MEMBER(fanucspmg_state::fdcdma_w)
{
m_fdc->dma_w(data);
}
WRITE8_MEMBER(fanucspmg_state::dma_page_w)
{
floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
floppy_image_device *floppy1 = m_fdc->subdevice<floppy_connector>("1")->get_device();
// verify
floppy0->mon_w(!(data & 2));
floppy1->mon_w(!(data & 2));
m_dma_page = (data >> 2) & 0xf;
}
static ADDRESS_MAP_START(maincpu_mem, AS_PROGRAM, 16, fanucspmg_state)
AM_RANGE(0x00000, 0x7ffff) AM_RAM // main RAM
AM_RANGE(0x80000, 0x81fff) AM_RAM
AM_RANGE(0x88000, 0x88001) AM_READ8(vbl_r, 0xffff)
// AM_RANGE(0x80000, 0x83fff) AM_READWRITE8(shared2_r, shared2_w, 0xffff) // Comms with HDD controller ?
// AM_RANGE(0x88000, 0x88001) AM_READ(busy_r)
// AM_RANGE(0x8c000, 0x8c001) AM_WRITE(signal_w)
AM_RANGE(0xf0000, 0xf0003) AM_DEVREADWRITE8(PIC0_TAG, pic8259_device, read, write, 0x00ff)
AM_RANGE(0xf0004, 0xf0007) AM_DEVICE8(FDC_TAG, upd765a_device, map, 0x00ff)
AM_RANGE(0xf0008, 0xf000f) AM_DEVREADWRITE8(PIT0_TAG, pit8253_device, read, write, 0x00ff)
AM_RANGE(0xf0010, 0xf0011) AM_DEVREADWRITE8(USART0_TAG, i8251_device, data_r, data_w, 0x00ff)
@ -595,7 +641,10 @@ static ADDRESS_MAP_START(maincpu_mem, AS_PROGRAM, 16, fanucspmg_state)
AM_RANGE(0xf001a, 0xf001b) AM_DEVREADWRITE8(USART2_TAG, i8251_device, status_r, control_w, 0x00ff)
AM_RANGE(0xf001c, 0xf001d) AM_DEVREADWRITE8(USART3_TAG, i8251_device, data_r, data_w, 0x00ff)
AM_RANGE(0xf001e, 0xf001f) AM_DEVREADWRITE8(USART3_TAG, i8251_device, status_r, control_w, 0x00ff)
AM_RANGE(0xf0020, 0xf0029) AM_DEVREADWRITE8(DMAC_TAG, i8257n_device, read, write, 0xffff)
AM_RANGE(0xf0046, 0xf0047) AM_WRITE8(dma_page_w, 0x00ff)
AM_RANGE(0xf0048, 0xf004f) AM_DEVREADWRITE8(PIT1_TAG, pit8253_device, read, write, 0x00ff)
AM_RANGE(0xf2000, 0xf2003) AM_DEVREADWRITE8(PIC1_TAG, pic8259_device, read, write, 0x00ff)
AM_RANGE(0xf8000, 0xf9fff) AM_READWRITE8(shared_r, shared_w, 0xffff)
AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION(MAINCPU_TAG, 0)
@ -701,18 +750,19 @@ void fanucspmg_state::machine_reset()
m_vbl_ctrl = 0;
m_vram_bank = 0;
m_video_ctrl = 0;
m_dma_page = 0;
}
READ8_MEMBER(fanucspmg_state::memory_read_byte)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
return prog_space.read_byte(offset);
return prog_space.read_byte(offset | (m_dma_page << 16));
}
WRITE8_MEMBER(fanucspmg_state::memory_write_byte)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
return prog_space.write_byte(offset, data);
return prog_space.write_byte(offset | (m_dma_page << 16), data);
}
static MC6845_UPDATE_ROW( fanuc_update_row )
@ -792,6 +842,7 @@ static MACHINE_CONFIG_START( fanucspmg, fanucspmg_state )
MCFG_CPU_ADD(MAINCPU_TAG, I8086, XTAL_15MHz/3)
MCFG_CPU_PROGRAM_MAP(maincpu_mem)
MCFG_CPU_IO_MAP(maincpu_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE(PIC0_TAG, pic8259_device, inta_cb)
MCFG_CPU_ADD(SUBCPU_TAG, I8085A, XTAL_16MHz/2/2)
MCFG_CPU_PROGRAM_MAP(subcpu_mem)
@ -810,14 +861,20 @@ static MACHINE_CONFIG_START( fanucspmg, fanucspmg_state )
MCFG_PIT8253_CLK1(XTAL_15MHz/12)
MCFG_PIT8253_CLK2(XTAL_15MHz/12)
MCFG_DEVICE_ADD(DMAC_TAG, I8257, XTAL_15MHz / 5)
MCFG_I8257_IN_MEMR_CB(READ8(fanucspmg_state, memory_read_byte))
MCFG_I8257_OUT_MEMW_CB(WRITE8(fanucspmg_state, memory_write_byte))
MCFG_DEVICE_ADD(DMAC_TAG, I8257N, XTAL_15MHz / 5)
MCFG_I8257N_OUT_HRQ_CB(WRITELINE(fanucspmg_state, hrq_w))
MCFG_I8257N_OUT_TC_CB(WRITELINE(fanucspmg_state, tc_w))
MCFG_I8257N_IN_MEMR_CB(READ8(fanucspmg_state, memory_read_byte))
MCFG_I8257N_OUT_MEMW_CB(WRITE8(fanucspmg_state, memory_write_byte))
MCFG_I8257N_IN_IOR_0_CB(READ8(fanucspmg_state, fdcdma_r))
MCFG_I8257N_OUT_IOW_0_CB(WRITE8(fanucspmg_state, fdcdma_w))
MCFG_PIC8259_ADD(PIC0_TAG, INPUTLINE("maincpu", 0), VCC, NULL)
MCFG_PIC8259_ADD(PIC1_TAG, INPUTLINE("maincpu", 0), VCC, NULL)
MCFG_PIC8259_ADD(PIC0_TAG, INPUTLINE("maincpu", 0), VCC, READ8(fanucspmg_state, get_slave_ack))
MCFG_PIC8259_ADD(PIC1_TAG, DEVWRITELINE(PIC0_TAG, pic8259_device, ir7_w), GND, NULL)
MCFG_UPD765A_ADD(FDC_TAG, true, true)
MCFG_UPD765_INTRQ_CALLBACK(DEVWRITELINE(PIC0_TAG, pic8259_device, ir3_w))
MCFG_UPD765_DRQ_CALLBACK(DEVWRITELINE(DMAC_TAG, i8257n_device, dreq0_w))
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG":0", fanuc_floppies, "525dd", fanucspmg_state::floppy_formats)
MCFG_FLOPPY_DRIVE_ADD(FDC_TAG":1", fanuc_floppies, "525dd", fanucspmg_state::floppy_formats)

View File

@ -1025,7 +1025,7 @@ void x68k_state::set_bus_error(UINT32 address, bool write, UINT16 mem_mask)
m_maincpu->mmu_tmp_buserror_address = address; // Hack for x68030
m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
timer_set(m_maincpu->cycles_to_attotime(16), TIMER_X68K_BUS_ERROR); // let rmw cycles complete
m_bus_error_timer->adjust(m_maincpu->cycles_to_attotime(16)); // let rmw cycles complete
logerror("%s: Bus error: Unused RAM access [%08x]\n", machine().describe_context(), address);
}
@ -1649,6 +1649,7 @@ DRIVER_INIT_MEMBER(x68k_state,x68000)
m_net_timer = timer_alloc(TIMER_X68K_NET_IRQ);
m_fdc_tc = timer_alloc(TIMER_X68K_FDC_TC);
m_adpcm_timer = timer_alloc(TIMER_X68K_ADPCM);
m_bus_error_timer = timer_alloc(TIMER_X68K_BUS_ERROR);
// Initialise timers for 6-button MD controllers
md_6button_init();

View File

@ -229,6 +229,7 @@ public:
emu_timer* m_vblank_irq;
emu_timer* m_fdc_tc;
emu_timer* m_adpcm_timer;
emu_timer* m_bus_error_timer;
UINT16* m_spriteram;
tilemap_t* m_bg0_8;
tilemap_t* m_bg1_8;

View File

@ -395,6 +395,7 @@ MACHINES += I8243
MACHINES += I8251
MACHINES += I8255
MACHINES += I8257
MACHINES += I8257N
MACHINES += I8271
MACHINES += I8279
MACHINES += I8355