z80dma.cpp: burst mode and refactoring (#12494)

* zorba fix: restore deffered rdy write
* fix 'x1turbo40 suikoden'
This commit is contained in:
holub 2024-08-11 20:00:58 -04:00 committed by GitHub
parent 9ef0f8f38f
commit 339bb27586
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
31 changed files with 393 additions and 448 deletions

View File

@ -304,9 +304,10 @@ void luxor_55_21046_device::device_add_mconfig(machine_config & config)
m_maincpu->set_daisy_config(z80_daisy_chain);
m_maincpu->set_addrmap(AS_PROGRAM, &luxor_55_21046_device::luxor_55_21046_mem);
m_maincpu->set_addrmap(AS_IO, &luxor_55_21046_device::luxor_55_21046_io);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80DMA(config, m_dma, 16_MHz_XTAL / 4);
m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set(FUNC(luxor_55_21046_device::dma_int_w));
m_dma->in_mreq_callback().set(FUNC(luxor_55_21046_device::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(luxor_55_21046_device::memory_write_byte));

View File

@ -254,9 +254,10 @@ void luxor_55_21056_device::device_add_mconfig(machine_config &config)
m_maincpu->set_memory_map(&luxor_55_21056_device::luxor_55_21056_mem);
m_maincpu->set_io_map(&luxor_55_21056_device::luxor_55_21056_io);
m_maincpu->set_daisy_config(daisy_chain);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80DMA(config, m_dma, XTAL(8'000'000)/2);
m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dma->in_mreq_callback().set(FUNC(luxor_55_21056_device::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(luxor_55_21056_device::memory_write_byte));

View File

@ -18,8 +18,6 @@
- rewrite to match documentation
- implement missing features
- implement more asserts
- implement a INPUT_LINE_BUSREQ for Z80. As a workaround,
HALT is used. This implies burst mode.
**********************************************************************/
@ -27,16 +25,18 @@
#include "z80dma.h"
#define LOG_DMA (1U << 1)
#define LOG_INT (1U << 2)
//#define VERBOSE (LOG_GENERAL | LOG_DMA)
//#define VERBOSE (LOG_GENERAL | LOG_DMA | LOG_INT)
#include "logmacro.h"
#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__)
#define LOGINT(...) LOGMASKED(LOG_INT, __VA_ARGS__)
//**************************************************************************
// CONSTANTS
//**************************************************************************
/****************************************************************************
* CONSTANTS
****************************************************************************/
enum
{
INT_RDY = 0,
@ -45,12 +45,25 @@ enum
INT_MATCH_END_OF_BLOCK
};
enum
{
SEQ_WAIT_READY = 0,
SEQ_REQUEST_BUS,
SEQ_WAITING_ACK,
SEQ_TRANS1_INC_DEC_SOURCE_ADDRESS,
SEQ_TRANS1_READ_SOURCE,
SEQ_TRANS1_INC_DEC_DEST_ADDRESS,
SEQ_TRANS1_WRITE_DEST,
SEQ_TRANS1_BYTE_MATCH,
SEQ_TRANS1_INC_BYTE_COUNTER,
SEQ_TRANS1_SET_FLAGS,
SEQ_FINISH
};
//**************************************************************************
// MACROS
//**************************************************************************
/****************************************************************************
* MACROS
****************************************************************************/
#define GET_REGNUM(_r) (&(_r) - &(WR0))
#define WR0 REG(0, 0)
#define WR1 REG(1, 0)
@ -91,13 +104,12 @@ enum
#define PORTA_MEMORY (((WR1 >> 3) & 0x01) == 0x00)
#define PORTB_MEMORY (((WR2 >> 3) & 0x01) == 0x00)
#define PORTA_CYCLE_LEN (4-(PORTA_TIMING & 0x03))
#define PORTB_CYCLE_LEN (4-(PORTB_TIMING & 0x03))
#define PORTA_IS_SOURCE ((WR0 >> 2) & 0x01)
#define PORTB_IS_SOURCE (!PORTA_IS_SOURCE)
#define TRANSFER_MODE (WR0 & 0x03)
#define OPERATING_MODE ((WR4 >> 5) & 0x03) // 0b00: Byte; 0b01: Continuous; 0b10: Burst; 0b11: Do not program
#define MATCH_F_SET (m_status &= ~0x10)
#define MATCH_F_CLEAR (m_status |= 0x10)
#define EOB_F_SET (m_status &= ~0x20)
@ -114,23 +126,20 @@ enum
#define PULSE_GENERATED (INTERRUPT_CTRL & 0x04)
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
// device type definition
/****************************************************************************
* device type definition
****************************************************************************/
DEFINE_DEVICE_TYPE(Z80DMA, z80dma_device, "z80dma", "Z80 DMA Controller")
//-------------------------------------------------
// z80dma_device - constructor
//-------------------------------------------------
z80dma_device::z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
/****************************************************************************
* z80dma_device - constructor
****************************************************************************/
z80dma_device::z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: z80dma_device(mconfig, Z80DMA, tag, owner, clock)
{
}
z80dma_device::z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
z80dma_device::z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, type, tag, owner, clock)
, device_z80daisy_interface(mconfig, *this)
, m_out_busreq_cb(*this)
@ -144,15 +153,13 @@ z80dma_device::z80dma_device(const machine_config &mconfig, device_type type, co
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
/****************************************************************************
* device_start - device-specific startup
****************************************************************************/
void z80dma_device::device_start()
{
// allocate timer
m_timer = timer_alloc(FUNC(z80dma_device::timerproc), this);
m_timer = timer_alloc(FUNC(z80dma_device::clock_w), this);
// register for state saving
save_item(NAME(m_regs));
@ -160,7 +167,7 @@ void z80dma_device::device_start()
save_item(NAME(m_num_follow));
save_item(NAME(m_cur_follow));
save_item(NAME(m_status));
save_item(NAME(m_dma_enabled));
save_item(NAME(m_dma_seq));
save_item(NAME(m_vector));
save_item(NAME(m_iei));
save_item(NAME(m_ip));
@ -171,27 +178,29 @@ void z80dma_device::device_start()
save_item(NAME(m_byte_counter));
save_item(NAME(m_rdy));
save_item(NAME(m_force_ready));
save_item(NAME(m_is_read));
save_item(NAME(m_wait));
save_item(NAME(m_busrq_ack));
save_item(NAME(m_is_pulse));
save_item(NAME(m_cur_cycle));
save_item(NAME(m_latch));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
/****************************************************************************
* device_reset - device-specific reset
****************************************************************************/
void z80dma_device::device_reset()
{
m_timer->reset();
m_status = 0;
m_dma_seq = ~0;
m_rdy = 0;
m_force_ready = 0;
m_wait = 0;
m_num_follow = 0;
m_dma_enabled = 0;
m_read_num_follow = m_read_cur_follow = 0;
m_reset_pointer = 0;
m_is_read = false;
m_busrq_ack = 0;
m_is_pulse = false;
memset(m_regs, 0, sizeof(m_regs));
memset(m_regs_follow, 0, sizeof(m_regs_follow));
@ -201,21 +210,17 @@ void z80dma_device::device_reset()
m_ip = 0;
m_ius = 0;
m_vector = 0;
update_status();
}
/****************************************************************************
* DAISY CHAIN INTERFACE
****************************************************************************/
//**************************************************************************
// DAISY CHAIN INTERFACE
//**************************************************************************
//-------------------------------------------------
// z80daisy_irq_state - return the overall IRQ
// state for this device
//-------------------------------------------------
/****************************************************************************
* z80daisy_irq_state - return the overall IRQ
* state for this device
****************************************************************************/
int z80dma_device::z80daisy_irq_state()
{
int state = 0;
@ -230,23 +235,20 @@ int z80dma_device::z80daisy_irq_state()
// interrupt under service
state = Z80_DAISY_IEO;
}
LOG("Z80DMA Interrupt State: %u\n", state);
LOGINT("Z80DMA Interrupt State: %u\n", state);
return state;
}
//-------------------------------------------------
// z80daisy_irq_ack - acknowledge an IRQ and
// return the appropriate vector
//-------------------------------------------------
/****************************************************************************
* z80daisy_irq_ack - acknowledge an IRQ and
* return the appropriate vector
****************************************************************************/
int z80dma_device::z80daisy_irq_ack()
{
if (m_ip)
{
LOG("Z80DMA Interrupt Acknowledge\n");
LOGINT("Z80DMA Interrupt Acknowledge\n");
// clear interrupt pending flag
m_ip = 0;
@ -257,70 +259,74 @@ int z80dma_device::z80daisy_irq_ack()
return m_vector;
}
//logerror("z80dma_irq_ack: failed to find an interrupt to ack!\n");
return 0;
else
{
LOGINT("z80dma_irq_ack: failed to find an interrupt to ack!\n");
return 0;
}
}
//-------------------------------------------------
// z80daisy_irq_reti - clear the interrupt
// pending state to allow other interrupts through
//-------------------------------------------------
/****************************************************************************
* z80daisy_irq_reti - clear the interrupt
* pending state to allow other interrupts through
****************************************************************************/
void z80dma_device::z80daisy_irq_reti()
{
if (m_ius)
{
LOG("Z80DMA Return from Interrupt\n");
LOGINT("Z80DMA Return from Interrupt\n");
// clear interrupt under service flag
m_ius = 0;
interrupt_check();
return;
}
//logerror("z80dma_irq_reti: failed to find an interrupt to clear IEO on!\n");
else
{
LOGINT("z80dma_irq_reti: failed to find an interrupt to clear IEO on!\n");
}
}
//**************************************************************************
// INTERNAL STATE MANAGEMENT
//**************************************************************************
//-------------------------------------------------
// is_ready - ready for DMA transfer?
//-------------------------------------------------
int z80dma_device::is_ready()
void z80dma_device::enable()
{
return (m_force_ready) || (m_rdy == READY_ACTIVE_HIGH);
const attotime curtime = machine().time();
m_timer->adjust(attotime::from_ticks(curtime.as_ticks(clock()) + 1, clock()) - curtime, 0, clocks_to_attotime(1));
m_dma_seq = SEQ_WAIT_READY;
}
void z80dma_device::disable()
{
m_timer->reset();
if (m_busrq_ack == 1)
{
m_out_busreq_cb(CLEAR_LINE);
}
}
//-------------------------------------------------
// interrupt_check - update IRQ line state
//-------------------------------------------------
/****************************************************************************
* is_ready - ready for DMA transfer?
****************************************************************************/
int z80dma_device::is_ready()
{
return m_force_ready || (m_rdy == READY_ACTIVE_HIGH);
}
/****************************************************************************
* interrupt_check - update IRQ line state
****************************************************************************/
void z80dma_device::interrupt_check()
{
m_out_int_cb(m_ip ? ASSERT_LINE : CLEAR_LINE);
int ieo = m_iei;
if (m_ip) {
ieo = 0;
}
m_out_ieo_cb(ieo);
m_out_ieo_cb(m_ip ? 0 : m_iei);
}
//-------------------------------------------------
// trigger_interrupt - trigger DMA interrupt
//-------------------------------------------------
/****************************************************************************
* trigger_interrupt - trigger DMA interrupt
****************************************************************************/
void z80dma_device::trigger_interrupt(int level)
{
if (!m_ius && INTERRUPT_ENABLE)
@ -340,23 +346,19 @@ void z80dma_device::trigger_interrupt(int level)
m_status &= ~0x08;
LOG("Z80DMA Interrupt Pending\n");
LOGINT("Z80DMA Interrupt Pending\n");
interrupt_check();
}
}
//-------------------------------------------------
// do_read - perform DMA read
//-------------------------------------------------
/****************************************************************************
* do_read - perform DMA read
****************************************************************************/
void z80dma_device::do_read()
{
uint8_t mode;
mode = TRANSFER_MODE;
switch(mode) {
switch(TRANSFER_MODE)
{
case TM_TRANSFER:
case TM_SEARCH:
case TM_SEARCH_TRANSFER:
@ -380,16 +382,14 @@ void z80dma_device::do_read()
}
break;
default:
logerror("z80dma_do_operation: invalid mode %d!\n", mode);
logerror("z80dma_do_operation: invalid mode %d!\n", TRANSFER_MODE);
break;
}
}
//-------------------------------------------------
// do_write - perform DMA write
//-------------------------------------------------
/****************************************************************************
* do_write - perform DMA write
****************************************************************************/
void z80dma_device::do_transfer_write()
{
if (PORTA_IS_SOURCE)
@ -414,25 +414,19 @@ void z80dma_device::do_transfer_write()
void z80dma_device::do_search()
{
uint8_t load_byte,match_byte;
load_byte = m_latch | MASK_BYTE;
match_byte = MATCH_BYTE | MASK_BYTE;
//LOG("%02x %02x\n",load_byte,match_byte));
if (load_byte == match_byte)
const u8 load_byte = m_latch | MASK_BYTE;
const u8 match_byte = MATCH_BYTE | MASK_BYTE;
LOGDMA("SEARCH: %02x %02x\n", load_byte, match_byte);
if (INT_ON_MATCH && load_byte == match_byte)
{
if (INT_ON_MATCH)
{
trigger_interrupt(INT_MATCH);
}
trigger_interrupt(INT_MATCH);
}
}
void z80dma_device::do_write()
{
uint8_t mode;
mode = TRANSFER_MODE;
switch(mode) {
switch(TRANSFER_MODE)
{
case TM_TRANSFER:
do_transfer_write();
break;
@ -447,7 +441,7 @@ void z80dma_device::do_write()
break;
default:
logerror("z80dma_do_operation: invalid mode %d!\n", mode);
logerror("z80dma_do_operation: invalid mode %d!\n", TRANSFER_MODE);
break;
}
@ -457,140 +451,170 @@ void z80dma_device::do_write()
m_byte_counter++;
}
//-------------------------------------------------
// timerproc
//-------------------------------------------------
TIMER_CALLBACK_MEMBER(z80dma_device::timerproc)
/****************************************************************************
* clock_w - raising edge
****************************************************************************/
TIMER_CALLBACK_MEMBER(z80dma_device::clock_w)
{
if (--m_cur_cycle)
switch (m_dma_seq)
{
return;
}
if (PULSE_GENERATED)
{
if (m_is_pulse)
{
m_out_int_cb(CLEAR_LINE);
m_is_pulse = false;
}
else
{
if ((m_byte_counter & 0xff)==PULSE_CTRL && is_ready())
case SEQ_WAIT_READY:
if (is_ready())
{
m_is_pulse = true;
m_out_int_cb(ASSERT_LINE);
// Continuos mode only request BUS during start
if (OPERATING_MODE != 0b01 || m_byte_counter == 0)
{
m_dma_seq = SEQ_REQUEST_BUS;
}
else
{
m_dma_seq = SEQ_TRANS1_INC_DEC_SOURCE_ADDRESS;
}
}
}
}
break;
if (m_is_read && !is_ready()) return;
case SEQ_REQUEST_BUS:
if (m_busrq_ack == 0)
{
m_out_busreq_cb(ASSERT_LINE);
}
m_dma_seq = SEQ_WAITING_ACK;
break;
if (m_is_read)
{
/* TODO: there's a nasty recursion bug with Alpha for Sharp X1 Turbo on the transfers with this function! */
do_read();
m_is_read = false;
m_cur_cycle = (PORTA_IS_SOURCE ? PORTA_CYCLE_LEN : PORTB_CYCLE_LEN);
}
else
{
do_write();
m_is_read = true;
m_cur_cycle = (PORTB_IS_SOURCE ? PORTA_CYCLE_LEN : PORTB_CYCLE_LEN);
case SEQ_WAITING_ACK:
if (m_busrq_ack == 1)
{
m_dma_seq = SEQ_TRANS1_INC_DEC_SOURCE_ADDRESS;
}
break;
// param==1 indicates final transfer
m_timer->set_param(m_byte_counter == m_count);
}
case SEQ_TRANS1_INC_DEC_SOURCE_ADDRESS:
{
if (PULSE_GENERATED && (m_byte_counter & 0xff) == PULSE_CTRL)
{
m_is_pulse = true;
m_out_int_cb(ASSERT_LINE);
}
if (m_is_read && param)
{
m_dma_enabled = 0; //FIXME: Correct?
m_status = 0x09;
const attotime clock = clocks_to_attotime(1);
const attotime next = clock * (3 - ((PORTA_IS_SOURCE ? PORTA_TIMING : PORTB_TIMING) & 0x03));
m_timer->adjust(next, 0, clock);
m_status |= !is_ready() << 1; // ready line status
m_dma_seq = SEQ_TRANS1_READ_SOURCE;
}
break;
if(TRANSFER_MODE == TM_TRANSFER) m_status |= 0x10; // no match found
case SEQ_TRANS1_READ_SOURCE:
if (!m_wait)
{
// TODO: there's a nasty recursion bug with Alpha for Sharp X1 Turbo on the transfers with this function!
do_read();
update_status();
LOG("Z80DMA End of Block\n");
m_dma_seq = SEQ_TRANS1_INC_DEC_DEST_ADDRESS;
}
break;
if (INT_ON_END_OF_BLOCK)
{
trigger_interrupt(INT_END_OF_BLOCK);
}
case SEQ_TRANS1_INC_DEC_DEST_ADDRESS:
{
const attotime clock = clocks_to_attotime(1);
const attotime next = clock * (3 - ((PORTB_IS_SOURCE ? PORTA_TIMING : PORTB_TIMING) & 0x03));
m_timer->adjust(next, 0, clock);
if (AUTO_RESTART)
{
LOG("Z80DMA Auto Restart\n");
m_dma_seq = SEQ_TRANS1_WRITE_DEST;
}
break;
m_dma_enabled = 1;
m_addressA = PORTA_ADDRESS;
m_addressB = PORTB_ADDRESS;
m_count = BLOCKLEN;
m_byte_counter = 0;
m_status |= 0x30;
m_timer->set_param(0);
}
case SEQ_TRANS1_WRITE_DEST:
if (!m_wait)
{
// hack?: count=0 cause infinite loop in 'x1turbo40 suikoden' and makes it work.
const bool is_final = m_count && m_byte_counter == m_count;
do_write();
if (PULSE_GENERATED && m_is_pulse)
{
m_out_int_cb(CLEAR_LINE);
m_is_pulse = false;
}
const u8 mode = is_final ? 0b11 : OPERATING_MODE;
switch (mode)
{
case 0b00: // Byte/Single/byte-at-a-time
m_out_busreq_cb(CLEAR_LINE);
m_dma_seq = SEQ_WAIT_READY;
break;
case 0b10: // Burst/Demand
if (is_ready())
{
m_dma_seq = SEQ_TRANS1_INC_DEC_SOURCE_ADDRESS;
}
else
{
m_out_busreq_cb(CLEAR_LINE);
m_dma_seq = SEQ_WAIT_READY;
}
break;
case 0b01: // Continuous/Block
m_dma_seq = is_ready() ? SEQ_TRANS1_INC_DEC_SOURCE_ADDRESS : SEQ_WAIT_READY;
break;
default: // Undefined || final
m_dma_seq = SEQ_FINISH;
break;
}
}
break;
case SEQ_TRANS1_BYTE_MATCH:
case SEQ_TRANS1_INC_BYTE_COUNTER:
case SEQ_TRANS1_SET_FLAGS:
case SEQ_FINISH:
disable();
m_status = 0x09;
m_status |= !is_ready() << 1; // ready line status
if(TRANSFER_MODE == TM_TRANSFER) m_status |= 0x10; // no match found
LOG("Z80DMA End of Block\n");
if (INT_ON_END_OF_BLOCK)
{
trigger_interrupt(INT_END_OF_BLOCK);
}
if (AUTO_RESTART)
{
LOG("Z80DMA Auto Restart\n");
m_addressA = PORTA_ADDRESS;
m_addressB = PORTB_ADDRESS;
m_count = BLOCKLEN;
m_byte_counter = 0;
m_status |= 0x30;
enable();
}
break;
default:
break;
}
}
//-------------------------------------------------
// update_status - update DMA status
//-------------------------------------------------
/****************************************************************************
* READ/WRITE INTERFACES
****************************************************************************/
void z80dma_device::update_status()
/****************************************************************************
* read - register read
****************************************************************************/
u8 z80dma_device::read()
{
// no transfer is active right now; is there a transfer pending right now?
bool const pending_transfer = is_ready() && m_dma_enabled;
if (pending_transfer)
{
m_is_read = true;
m_cur_cycle = (PORTA_IS_SOURCE ? PORTA_CYCLE_LEN : PORTB_CYCLE_LEN);
attotime const next = attotime::from_hz(clock());
m_timer->adjust(
attotime::zero,
m_timer->param(),
// 1 byte transferred in 4 clock cycles
next);
}
else
{
if (m_is_read)
{
// no transfers active right now
m_timer->reset();
}
}
// set the busreq line
m_out_busreq_cb(pending_transfer ? ASSERT_LINE : CLEAR_LINE);
}
//**************************************************************************
// READ/WRITE INTERFACES
//**************************************************************************
//-------------------------------------------------
// read - register read
//-------------------------------------------------
uint8_t z80dma_device::read()
{
uint8_t res;
if(m_read_num_follow == 0) // special case: Legend of Kage on X1 Turbo
res = m_status;
else {
res = m_read_regs_follow[m_read_cur_follow];
}
const u8 res = m_read_regs_follow[m_read_cur_follow];
m_read_cur_follow++;
if(m_read_cur_follow >= m_read_num_follow)
@ -601,12 +625,10 @@ uint8_t z80dma_device::read()
return res;
}
//-------------------------------------------------
// write - register write
//-------------------------------------------------
void z80dma_device::write(uint8_t data)
/****************************************************************************
* write - register write
****************************************************************************/
void z80dma_device::write(u8 data)
{
if (m_num_follow == 0)
{
@ -647,6 +669,11 @@ void z80dma_device::write(uint8_t data)
m_regs_follow[m_num_follow++] = GET_REGNUM(MASK_BYTE);
if (data & 0x10)
m_regs_follow[m_num_follow++] = GET_REGNUM(MATCH_BYTE);
if (BIT(data, 6))
{
enable();
}
}
else if ((data & 0x83) == 0x81) // WR4
{
@ -667,8 +694,6 @@ void z80dma_device::write(uint8_t data)
else if ((data & 0x83) == 0x83) // WR6
{
LOG("Z80DMA WR6 %02x\n", data);
m_dma_enabled = 0;
WR6 = data;
switch (data)
@ -691,30 +716,33 @@ void z80dma_device::write(uint8_t data)
case COMMAND_INITIATE_READ_SEQUENCE:
LOG("Z80DMA Initiate Read Sequence\n");
m_read_cur_follow = m_read_num_follow = 0;
if(READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
if(READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter & 0xff; } //byte counter (low)
if(READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter >> 8; } //byte counter (high)
if(READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
if(READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
if(READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
if(READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)
if (READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
if (READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter & 0xff; } //byte counter (low)
if (READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter >> 8; } //byte counter (high)
if (READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
if (READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
if (READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
if (READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)
break;
case COMMAND_RESET:
LOG("Z80DMA Reset\n");
m_dma_enabled = 0;
disable();
m_force_ready = 0;
m_ip = 0;
m_ius = 0;
interrupt_check();
// Needs six reset commands to reset the DMA
{
uint8_t WRi;
u8 WRi;
for(WRi=0;WRi<7;WRi++)
for (WRi = 0; WRi < 7; WRi++)
REG(WRi,m_reset_pointer) = 0;
m_reset_pointer++;
if(m_reset_pointer >= 6) { m_reset_pointer = 0; }
if (m_reset_pointer >= 6)
{
m_reset_pointer = 0;
}
}
m_status = 0x38;
break;
@ -725,17 +753,16 @@ void z80dma_device::write(uint8_t data)
m_count = BLOCKLEN;
m_byte_counter = 0;
m_status |= 0x30;
m_timer->set_param(0);
LOG("Z80DMA Load A: %x B: %x N: %x\n", m_addressA, m_addressB, m_count);
break;
case COMMAND_DISABLE_DMA:
LOG("Z80DMA Disable DMA\n");
m_dma_enabled = 0;
disable();
break;
case COMMAND_ENABLE_DMA:
LOG("Z80DMA Enable DMA\n");
m_dma_enabled = 1;
enable();
break;
case COMMAND_READ_MASK_FOLLOWS:
LOG("Z80DMA Set Read Mask\n");
@ -745,10 +772,9 @@ void z80dma_device::write(uint8_t data)
LOG("Z80DMA Continue\n");
m_count = BLOCKLEN;
m_byte_counter = 0;
m_dma_enabled = 1;
//enable(); //???m_dma_enabled = 1;
//"match not found" & "end of block" status flags zeroed here
m_status |= 0x30;
m_timer->set_param(0);
break;
case COMMAND_RESET_PORT_A_TIMING:
LOG("Z80DMA Reset Port A Timing\n");
@ -782,9 +808,8 @@ void z80dma_device::write(uint8_t data)
default:
logerror("Z80DMA Unknown WR6 command %02x\n", data);
}
update_status();
}
else if(data == 0x8e) //newtype on Sharp X1, unknown purpose
else if (data == 0x8e) //newtype on Sharp X1, unknown purpose
logerror("Z80DMA Unknown base register %02x\n", data);
else
fatalerror("Z80DMA '%s' Unknown base register %02x\n", tag(), data);
@ -797,7 +822,7 @@ void z80dma_device::write(uint8_t data)
int nreg = m_regs_follow[m_cur_follow];
m_regs[nreg] = data;
m_cur_follow++;
if (m_cur_follow>=m_num_follow)
if (m_cur_follow >= m_num_follow)
m_num_follow = 0;
if (nreg == REGNUM(4,3))
{
@ -812,64 +837,51 @@ void z80dma_device::write(uint8_t data)
{
m_read_cur_follow = m_read_num_follow = 0;
if(READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
if(READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter & 0xff; } //byte counter (low)
if(READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter >> 8; } //byte counter (high)
if(READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
if(READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
if(READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
if(READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)
if (READ_MASK & 0x01) { m_read_regs_follow[m_read_num_follow++] = m_status; }
if (READ_MASK & 0x02) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter & 0xff; } //byte counter (low)
if (READ_MASK & 0x04) { m_read_regs_follow[m_read_num_follow++] = m_byte_counter >> 8; } //byte counter (high)
if (READ_MASK & 0x08) { m_read_regs_follow[m_read_num_follow++] = m_addressA & 0xff; } //port A address (low)
if (READ_MASK & 0x10) { m_read_regs_follow[m_read_num_follow++] = m_addressA >> 8; } //port A address (high)
if (READ_MASK & 0x20) { m_read_regs_follow[m_read_num_follow++] = m_addressB & 0xff; } //port B address (low)
if (READ_MASK & 0x40) { m_read_regs_follow[m_read_num_follow++] = m_addressB >> 8; } //port B address (high)
}
m_reset_pointer++;
if(m_reset_pointer >= 6) { m_reset_pointer = 0; }
if (m_reset_pointer >= 6)
{
m_reset_pointer = 0;
}
}
}
//-------------------------------------------------
// rdy_write_callback - deferred RDY signal write
//-------------------------------------------------
/****************************************************************************
* rdy_write_callback - deferred RDY signal write
****************************************************************************/
TIMER_CALLBACK_MEMBER(z80dma_device::rdy_write_callback)
{
// normalize state
m_rdy = param;
m_status = (m_status & 0xFD) | (!is_ready() << 1);
update_status();
if (is_ready() && INT_ON_READY)
{
trigger_interrupt(INT_RDY);
}
}
//-------------------------------------------------
// rdy_w - ready input
//-------------------------------------------------
/****************************************************************************
* rdy_w - ready input
****************************************************************************/
void z80dma_device::rdy_w(int state)
{
LOG("Z80DMA RDY: %d Active High: %d\n", state, READY_ACTIVE_HIGH);
machine().scheduler().synchronize(timer_expired_delegate(FUNC(z80dma_device::rdy_write_callback),this), state);
}
//-------------------------------------------------
// wait_w - wait input
//-------------------------------------------------
void z80dma_device::wait_w(int state)
{
}
//-------------------------------------------------
// bai_w - bus acknowledge input
//-------------------------------------------------
/****************************************************************************
* bai_w - bus acknowledge input
****************************************************************************/
void z80dma_device::bai_w(int state)
{
m_busrq_ack = state;
}

View File

@ -49,7 +49,7 @@ class z80dma_device : public device_t,
{
public:
// construction/destruction
z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
z80dma_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
auto out_busreq_callback() { return m_out_busreq_cb.bind(); }
auto out_int_callback() { return m_out_int_cb.bind(); }
@ -60,12 +60,12 @@ public:
auto in_iorq_callback() { return m_in_iorq_cb.bind(); }
auto out_iorq_callback() { return m_out_iorq_cb.bind(); }
uint8_t read();
virtual void write(uint8_t data);
u8 read();
virtual void write(u8 data);
void iei_w(int state) { m_iei = state; interrupt_check(); }
void rdy_w(int state);
void wait_w(int state);
void wait_w(int state) { m_wait = state; }
void bai_w(int state);
protected:
@ -90,14 +90,15 @@ protected:
static inline constexpr int TM_SEARCH = 0x02;
static inline constexpr int TM_SEARCH_TRANSFER = 0x03;
z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
z80dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
// device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
// internal helpers
bool is_dma_enabled() const noexcept { return m_dma_enabled; }
void enable();
void disable();
u8 num_follow() const noexcept { return m_num_follow; }
virtual int is_ready();
void interrupt_check();
@ -107,14 +108,14 @@ protected:
void do_transfer_write();
void do_search();
uint16_t &REG(unsigned m, unsigned s) noexcept { return m_regs[REGNUM(m, s)]; }
u16 &REG(unsigned m, unsigned s) noexcept { return m_regs[REGNUM(m, s)]; }
static constexpr unsigned REGNUM(unsigned m, unsigned s) { return (m << 3) + s; }
uint16_t m_addressA;
uint16_t m_addressB;
uint16_t m_count;
uint16_t m_byte_counter;
u16 m_addressA;
u16 m_addressB;
u16 m_count;
u16 m_byte_counter;
private:
// device_z80daisy_interface implementation
@ -122,10 +123,7 @@ private:
virtual int z80daisy_irq_ack() override;
virtual void z80daisy_irq_reti() override;
TIMER_CALLBACK_MEMBER(timerproc);
void update_status();
TIMER_CALLBACK_MEMBER(clock_w);
TIMER_CALLBACK_MEMBER(rdy_write_callback);
// internal state
@ -140,30 +138,30 @@ private:
emu_timer *m_timer;
uint16_t m_regs[(6 << 3) + 1 + 1];
uint8_t m_num_follow;
uint8_t m_cur_follow;
uint8_t m_regs_follow[5];
uint8_t m_read_num_follow;
uint8_t m_read_cur_follow;
uint8_t m_read_regs_follow[7];
uint8_t m_status;
uint8_t m_dma_enabled;
u16 m_regs[(6 << 3) + 1 + 1];
u8 m_num_follow;
u8 m_cur_follow;
u8 m_regs_follow[5];
u8 m_read_num_follow;
u8 m_read_cur_follow;
u8 m_read_regs_follow[7];
u8 m_status;
int m_dma_seq;
int m_rdy;
int m_force_ready;
uint8_t m_reset_pointer;
u8 m_reset_pointer;
bool m_is_read;
int m_wait;
int m_busrq_ack;
bool m_is_pulse;
uint8_t m_cur_cycle;
uint8_t m_latch;
u8 m_latch;
// interrupts
int m_iei; // interrupt enable input
int m_ip; // interrupt pending
int m_ius; // interrupt under service
uint8_t m_vector; // interrupt vector
u8 m_vector; // interrupt vector
};

View File

@ -450,6 +450,7 @@ void super6_state::super6(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &super6_state::super6_mem);
m_maincpu->set_addrmap(AS_IO, &super6_state::super6_io);
//m_maincpu->set_daisy_config(super6_daisy_chain);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
// devices
Z80CTC(config, m_ctc, 24_MHz_XTAL / 4);
@ -458,7 +459,7 @@ void super6_state::super6(machine_config &config)
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
Z80DMA(config, m_dma, 24_MHz_XTAL / 6);
m_dma->out_busreq_callback().set(m_dma, FUNC(z80dma_device::bai_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set(m_ctc, FUNC(z80ctc_device::trg2));
m_dma->in_mreq_callback().set(FUNC(super6_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(super6_state::memory_write_byte));

View File

@ -224,9 +224,7 @@ void altos5_state::io_write_byte(offs_t offset, uint8_t data)
void altos5_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state); // tell dma that bus has been granted
setup_banks(state); // adjust banking for dma or cpu
}
@ -387,6 +385,7 @@ void altos5_state::altos5(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &altos5_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &altos5_state::io_map);
m_maincpu->set_daisy_config(daisy_chain_intf);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
/* devices */
Z80DMA(config, m_dma, 8_MHz_XTAL / 2);

View File

@ -281,13 +281,6 @@ void aussiebyte_state::io_write_byte(offs_t offset, u8 data)
prog_space.write_byte(offset, data);
}
void aussiebyte_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
/***********************************************************
DMA selector
@ -505,6 +498,7 @@ void aussiebyte_state::aussiebyte(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &aussiebyte_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &aussiebyte_state::io_map);
m_maincpu->set_daisy_config(daisy_chain_intf);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -544,7 +538,7 @@ void aussiebyte_state::aussiebyte(machine_config &config)
Z80DMA(config, m_dma, 16_MHz_XTAL / 4);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dma->out_busreq_callback().set(FUNC(aussiebyte_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
// BAO, not used
m_dma->in_mreq_callback().set(FUNC(aussiebyte_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(aussiebyte_state::memory_write_byte));

View File

@ -102,7 +102,6 @@ private:
void rtc_w(offs_t offset, u8 data);
void fdc_intrq_w(int state);
void fdc_drq_w(int state);
void busreq_w(int state);
void sio1_rdya_w(int state);
void sio1_rdyb_w(int state);
void sio2_rdya_w(int state);

View File

@ -97,7 +97,6 @@ private:
void portec_w(u8 data);
static void floppy_formats(format_registration &fr);
void cent_busy_w(int state);
void busreq_w(int state);
u8 memory_read_byte(offs_t offset);
void memory_write_byte(offs_t offset, u8 data);
u8 io_read_byte(offs_t offset);
@ -301,13 +300,6 @@ void excali64_state::portec_w(u8 data)
m_fdc->dden_w(BIT(data, 2));
}
void excali64_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
u8 excali64_state::memory_read_byte(offs_t offset)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
@ -592,6 +584,7 @@ void excali64_state::excali64(machine_config &config)
Z80(config, m_maincpu, 16_MHz_XTAL / 4);
m_maincpu->set_addrmap(AS_PROGRAM, &excali64_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &excali64_state::io_map);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
I8251(config, "uart", 0);
//uart.txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
@ -643,7 +636,7 @@ void excali64_state::excali64(machine_config &config)
FLOPPY_CONNECTOR(config, "fdc:1", excali64_floppies, "525qd", excali64_state::floppy_formats).enable_sound(true);
Z80DMA(config, m_dma, 16_MHz_XTAL / 4);
m_dma->out_busreq_callback().set(FUNC(excali64_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->in_mreq_callback().set(FUNC(excali64_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(excali64_state::memory_write_byte));
m_dma->in_iorq_callback().set(FUNC(excali64_state::io_read_byte));

View File

@ -635,14 +635,6 @@ static const z80_daisy_config super80_daisy_chain[] =
// Z80DMA
//-------------------------------------------------
void super80v_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
uint8_t super80v_state::memory_read_byte(offs_t offset)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
@ -788,6 +780,7 @@ void super80v_state::super80v(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &super80v_state::super80v_map);
m_maincpu->set_addrmap(AS_IO, &super80v_state::super80v_io);
m_maincpu->set_daisy_config(super80_daisy_chain);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80PIO(config, m_pio, MASTER_CLOCK/6);
m_pio->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
@ -844,7 +837,7 @@ void super80v_state::super80v(machine_config &config)
TIMER(config, "timer_k").configure_periodic(FUNC(super80v_state::timer_k), attotime::from_hz(300)); // keyb scan
Z80DMA(config, m_dma, MASTER_CLOCK/6);
m_dma->out_busreq_callback().set(FUNC(super80v_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
//ba0 - not connected
m_dma->in_mreq_callback().set(FUNC(super80v_state::memory_read_byte));

View File

@ -147,7 +147,6 @@ protected:
void port3f_w(u8 data);
u8 port3e_r();
std::unique_ptr<u8[]> m_vram;
void busreq_w(int state);
uint8_t memory_read_byte(offs_t offset);
void memory_write_byte(offs_t offset, uint8_t data);
uint8_t io_read_byte(offs_t offset);

View File

@ -554,9 +554,10 @@ void sorcerer_state::sorcererb(machine_config &config)
{
sorcerer(config);
m_maincpu->set_addrmap(AS_IO, &sorcerer_state::sorcererb_io);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80DMA(config, m_dma, ES_CPU_CLOCK);
m_dma->out_busreq_callback().set([this] (bool state) {sorcerer_state::busreq_w(state); });
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->in_mreq_callback().set(FUNC(sorcerer_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(sorcerer_state::memory_write_byte));
m_dma->in_iorq_callback().set(FUNC(sorcerer_state::io_read_byte));

View File

@ -148,7 +148,6 @@ private:
bool m_halt = 0;
virtual void machine_start() override;
virtual void machine_reset() override;
void busreq_w(bool state);
u8 memory_read_byte(offs_t offset);
void memory_write_byte(offs_t offset, u8 data);
u8 io_read_byte(offs_t offset);

View File

@ -259,14 +259,6 @@ void sorcerer_state::port34_w(u8 data)
}
// ************ DIGITRIO DMA **************
void sorcerer_state::busreq_w(bool state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
u8 sorcerer_state::memory_read_byte(offs_t offset)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);

View File

@ -305,6 +305,7 @@ void hds200_state::hds200(machine_config &config)
Z80(config, m_maincpu, 8_MHz_XTAL / 2); // divider not verified
m_maincpu->set_addrmap(AS_PROGRAM, &hds200_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &hds200_state::io_map);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
input_merger_device &z80_irq(INPUT_MERGER_ANY_HIGH(config, "z80_irq"));
z80_irq.output_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
@ -312,7 +313,7 @@ void hds200_state::hds200(machine_config &config)
NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
Z80DMA(config, m_dma, 8_MHz_XTAL / 2); // divider not verified
m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->in_mreq_callback().set(FUNC(hds200_state::dma_mreq_r));
m_dma->out_mreq_callback().set(FUNC(hds200_state::dma_mreq_w));

View File

@ -77,7 +77,6 @@ protected:
virtual void machine_reset() override;
private:
void busreq_w(int state);
uint8_t memory_r(offs_t offset);
void memory_w(offs_t offset, uint8_t data);
uint8_t io_r(offs_t offset);
@ -387,12 +386,6 @@ void kdt6_state::siob_tx_w(int state)
// MACHINE
//**************************************************************************
void kdt6_state::busreq_w(int state)
{
m_cpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state);
}
uint8_t kdt6_state::memory_r(offs_t offset)
{
return m_ram[m_dma_map << 16 | offset];
@ -627,6 +620,7 @@ void kdt6_state::psi98(machine_config &config)
m_cpu->set_addrmap(AS_PROGRAM, &kdt6_state::psi98_mem);
m_cpu->set_addrmap(AS_IO, &kdt6_state::psi98_io);
m_cpu->set_daisy_config(daisy_chain_intf);
m_cpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
// video hardware
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -653,7 +647,7 @@ void kdt6_state::psi98(machine_config &config)
TIMER(config, m_beep_timer).configure_generic(FUNC(kdt6_state::beeper_off));
Z80DMA(config, m_dma, 16_MHz_XTAL / 4);
m_dma->out_busreq_callback().set(FUNC(kdt6_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_cpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline(m_cpu, INPUT_LINE_IRQ0);
m_dma->in_mreq_callback().set(FUNC(kdt6_state::memory_r));
m_dma->out_mreq_callback().set(FUNC(kdt6_state::memory_w));

View File

@ -341,10 +341,11 @@ void mario_state::mario_base(machine_config &config)
Z80(config, m_maincpu, Z80_CLOCK); /* verified on pcb */
m_maincpu->set_addrmap(AS_PROGRAM, &mario_state::mario_map);
m_maincpu->set_addrmap(AS_IO, &mario_state::mario_io_map);
downcast<z80_device &>(*m_maincpu).busack_cb().set(m_z80dma, FUNC(z80dma_device::bai_w));
/* devices */
Z80DMA(config, m_z80dma, Z80_CLOCK);
m_z80dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_z80dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_z80dma->in_mreq_callback().set(FUNC(mario_state::memory_read_byte));
m_z80dma->out_mreq_callback().set(FUNC(mario_state::memory_write_byte));

View File

@ -80,7 +80,6 @@ private:
void memory_write_byte(offs_t offset, uint8_t data);
uint8_t io_read_byte(offs_t offset);
void io_write_byte(offs_t offset, uint8_t data);
void busreq_w(int state);
void tc_w(int state);
void rt1715_floppy_enable(uint8_t data);
uint8_t k7658_led1_r();
@ -401,13 +400,6 @@ void rt1715_state::io_write_byte(offs_t offset, uint8_t data)
prog_space.write_byte(offset, data);
}
void rt1715_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
/***************************************************************************
VIDEO EMULATION
***************************************************************************/
@ -796,6 +788,7 @@ void rt1715_state::rt1715w(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &rt1715_state::rt1715w_mem);
m_maincpu->set_addrmap(AS_IO, &rt1715_state::rt1715w_io);
m_maincpu->set_daisy_config(rt1715w_daisy_chain);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
MCFG_MACHINE_START_OVERRIDE(rt1715_state, rt1715w)
MCFG_MACHINE_RESET_OVERRIDE(rt1715_state, rt1715w)
@ -812,7 +805,7 @@ void rt1715_state::rt1715w(machine_config &config)
FLOPPY_CONNECTOR(config, "i8272:1", rt1715w_floppies, "525qd", floppy_image_device::default_mfm_floppy_formats);
Z80DMA(config, m_dma, 15.9744_MHz_XTAL / 4);
m_dma->out_busreq_callback().set(FUNC(rt1715_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set(FUNC(rt1715_state::tc_w));
m_dma->in_mreq_callback().set(FUNC(rt1715_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(rt1715_state::memory_write_byte));

View File

@ -340,6 +340,7 @@ void idpartner_state::partner_base(machine_config &config)
m_maincpu->set_daisy_config(daisy_chain);
m_maincpu->set_addrmap(AS_PROGRAM, &idpartner_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &idpartner_state::io_map);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80SIO(config, m_sio1, XTAL(8'000'000) / 2);
m_sio1->out_txda_callback().set(m_serial[0], FUNC(rs232_port_device::write_txd));
@ -378,7 +379,7 @@ void idpartner_state::partner_base(machine_config &config)
m_ctc->zc_callback<2>().set(m_ctc, FUNC(z80ctc_device::trg3)); // optional
Z80DMA(config, m_dma, XTAL(8'000'000) / 2);
m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set(m_fdc, FUNC(i8272a_device::tc_line_w));
m_dma->in_mreq_callback().set(FUNC(idpartner_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(idpartner_state::memory_write_byte));

View File

@ -2265,6 +2265,7 @@ void x1turbo_state::x1turbo(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &x1turbo_state::x1turbo_mem);
m_maincpu->set_daisy_config(x1turbo_daisy);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
m_iobank->set_map(&x1turbo_state::x1turbo_io_banks);
@ -2272,7 +2273,7 @@ void x1turbo_state::x1turbo(machine_config &config)
sio.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
Z80DMA(config, m_dma, MAIN_CLOCK/4);
m_dma->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dma->in_mreq_callback().set(FUNC(x1turbo_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(x1turbo_state::memory_write_byte));

View File

@ -80,7 +80,7 @@ public:
, m_view7(*this, "mem_view7")
, m_copper(*this, "copper")
, m_ctc(*this, "ctc")
, m_dma(*this, "dma")
, m_dma(*this, "ndma")
, m_i2cmem(*this, "i2cmem")
, m_sdcard(*this, "sdcard")
, m_ay(*this, "ay%u", 0U)
@ -2256,6 +2256,7 @@ void specnext_state::nr_1a_ula_clip_y2_w(u8 data)
static const z80_daisy_config z80_daisy_chain[] =
{
{ "ndma" },
{ "ctc" },
{ nullptr }
};
@ -3448,12 +3449,14 @@ void specnext_state::tbblue(machine_config &config)
m_maincpu->in_nextreg_cb().set(FUNC(specnext_state::reg_r));
m_maincpu->out_retn_seen_cb().set(FUNC(specnext_state::leave_nmi));
m_maincpu->nomreq_cb().set_nop();
m_maincpu->busack_cb().set(m_dma, FUNC(specnext_dma_device::bai_w));
SPECNEXT_CTC(config, m_ctc, 28_MHz_XTAL / 8);
m_ctc->intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
SPECNEXT_DMA(config, m_dma, 28_MHz_XTAL / 8);
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dma->in_mreq_callback().set([this](offs_t offset) { return m_program.read_byte(offset); });
m_dma->out_mreq_callback().set([this](offs_t offset, u8 data) { m_program.write_byte(offset, data); });
m_dma->in_iorq_callback().set([this](offs_t offset) { return m_io.read_byte(offset); });

View File

@ -37,11 +37,6 @@ specnext_dma_device::specnext_dma_device(const machine_config &mconfig, const ch
{
}
int specnext_dma_device::is_ready()
{
return is_dma_enabled() || z80dma_device::is_ready();
}
void specnext_dma_device::write(u8 data)
{
z80dma_device::write(data);
@ -74,8 +69,7 @@ void specnext_dma_device::do_write()
if (m_byte_counter)
m_addressB += PORTB_FIXED ? 0 : PORTB_INC ? 1 : -1;
u8 const mode = TRANSFER_MODE;
switch (mode)
switch (TRANSFER_MODE)
{
case TM_TRANSFER:
do_transfer_write();
@ -91,7 +85,7 @@ void specnext_dma_device::do_write()
break;
default:
logerror("z80dma_do_operation: invalid mode %d!\n", mode);
logerror("z80dma_do_operation: invalid mode %d!\n", TRANSFER_MODE);
break;
}

View File

@ -20,7 +20,6 @@ protected:
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
virtual int is_ready() override;
virtual void do_write() override;
private:

View File

@ -132,7 +132,6 @@ private:
template <unsigned N> void irq_w(int state);
// DMA controller handlers
void busreq_w(int state);
uint8_t memory_read_byte(offs_t offset);
void memory_write_byte(offs_t offset, uint8_t data);
uint8_t io_read_byte(offs_t offset);
@ -160,7 +159,7 @@ private:
required_memory_bank m_bank1;
required_region_ptr<uint8_t> m_p_chargen;
required_device<cpu_device> m_maincpu;
required_device<z80_device> m_maincpu;
required_device<z80dma_device> m_dma;
required_device<i8251_device> m_uart0;
required_device<i8251_device> m_uart1;
@ -257,6 +256,7 @@ void zorba_state::zorba(machine_config &config)
Z80(config, m_maincpu, 24_MHz_XTAL / 6);
m_maincpu->set_addrmap(AS_PROGRAM, &zorba_state::zorba_mem);
m_maincpu->set_addrmap(AS_IO, &zorba_state::zorba_io);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -276,8 +276,7 @@ void zorba_state::zorba(machine_config &config)
/* devices */
Z80DMA(config, m_dma, 24_MHz_XTAL / 6);
// busack on cpu connects to bai pin
m_dma->out_busreq_callback().set(FUNC(zorba_state::busreq_w)); //connects to busreq on cpu
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set("irq0", FUNC(input_merger_device::in_w<0>));
//ba0 - not connected
m_dma->in_mreq_callback().set(FUNC(zorba_state::memory_read_byte));
@ -495,13 +494,6 @@ template <unsigned N> void zorba_state::irq_w(int state)
// DMA controller handlers
//-------------------------------------------------
void zorba_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
uint8_t zorba_state::memory_read_byte(offs_t offset)
{
return m_maincpu->space(AS_PROGRAM).read_byte(offset);

View File

@ -124,7 +124,6 @@ private:
void data_bank_w(offs_t offset, u8 data);
void video_bank_w(offs_t offset, u8 data);
void dma_busreq_w(int state);
u8 dma_memory_r(offs_t offset);
void dma_memory_w(offs_t offset, u8 data);
u8 dma_io_r(offs_t offset);
@ -186,14 +185,6 @@ void anoworld_state::video_bank_w(offs_t offset, u8 data)
LOG("PPI port C video_bank_w: %02x\n", data);
}
void anoworld_state::dma_busreq_w(int state)
{
// HACK: grant bus request immediately
LOGDMA("dma_busreq_w %d\n", state);
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_dma->bai_w(state);
}
u8 anoworld_state::dma_memory_r(offs_t offset)
{
LOGDMA("dma_memory_r %04X\n", offset);
@ -388,6 +379,7 @@ void anoworld_state::anoworld(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &anoworld_state::main_program_map);
m_maincpu->set_addrmap(AS_IO, &anoworld_state::main_io_map);
m_maincpu->set_daisy_config(main_daisy_chain);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80(config, m_audiocpu, 4_MHz_XTAL);
m_audiocpu->set_addrmap(AS_PROGRAM, &anoworld_state::audio_program_map);
@ -398,7 +390,7 @@ void anoworld_state::anoworld(machine_config &config)
ctc0.intr_callback().set_inputline("maincpu", 0);
Z80DMA(config, m_dma, 4_MHz_XTAL);
m_dma->out_busreq_callback().set(FUNC(anoworld_state::dma_busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline("maincpu", 0);
m_dma->in_mreq_callback().set(FUNC(anoworld_state::dma_memory_r));
m_dma->out_mreq_callback().set(FUNC(anoworld_state::dma_memory_w));

View File

@ -95,7 +95,6 @@ private:
uint8_t disable_rom_r();
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
void busreq_w(int state);
uint8_t memory_read_byte(offs_t offset);
void memory_write_byte(offs_t offset, uint8_t data);
uint8_t io_read_byte(offs_t offset);
@ -273,13 +272,6 @@ void hhtiger_state::write(offs_t offset, uint8_t data)
}
void hhtiger_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
uint8_t hhtiger_state::memory_read_byte(offs_t offset)
{
address_space& prog_space = m_maincpu->space(AS_PROGRAM);
@ -463,10 +455,11 @@ void hhtiger_state::hhtiger(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &hhtiger_state::z80_mem);
m_maincpu->set_addrmap(AS_IO, &hhtiger_state::z80_io);
m_maincpu->set_daisy_config(daisy_chain_intf);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
Z80DMA(config, m_dma, 16_MHz_XTAL / 4);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dma->out_busreq_callback().set(FUNC(hhtiger_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->in_mreq_callback().set(FUNC(hhtiger_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(hhtiger_state::memory_write_byte));
m_dma->in_iorq_callback().set(FUNC(hhtiger_state::io_read_byte));

View File

@ -199,13 +199,14 @@ void ts802_state::ts802(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &ts802_state::ts802_mem);
m_maincpu->set_addrmap(AS_IO, &ts802_state::ts802_io);
//m_maincpu->set_daisy_config(daisy_chain_intf); // causes problems
m_maincpu->busack_cb().set("dma", FUNC(z80dma_device::bai_w));
/* Devices */
GENERIC_TERMINAL(config, m_terminal, 0);
m_terminal->set_keyboard_callback(FUNC(ts802_state::kbd_put));
z80dma_device& dma(Z80DMA(config, "dma", 16_MHz_XTAL / 4));
dma.out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
dma.out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
dma.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
dma.in_mreq_callback().set(FUNC(ts802_state::memory_read_byte));
dma.out_mreq_callback().set(FUNC(ts802_state::memory_write_byte));

View File

@ -273,6 +273,7 @@ void ts816_state::ts816(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &ts816_state::ts816_mem);
m_maincpu->set_addrmap(AS_IO, &ts816_state::ts816_io);
m_maincpu->set_daisy_config(daisy_chain);
m_maincpu->busack_cb().set("dma", FUNC(z80dma_device::bai_w));
/* video hardware */
GENERIC_TERMINAL(config, m_terminal, 0);
@ -312,7 +313,7 @@ void ts816_state::ts816(machine_config &config)
ctc2.intr_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
z80dma_device& dma(Z80DMA(config, "dma", XTAL(16'000'000) / 4));
//dma.out_busreq_callback().set(FUNC(ts816_state::busreq_w));
dma.out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
dma.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
}

View File

@ -700,6 +700,7 @@ void trs80m2_state::trs80m2(machine_config &config)
m_maincpu->set_daisy_config(trs80m2_daisy_chain);
m_maincpu->set_addrmap(AS_PROGRAM, &trs80m2_state::z80_mem);
m_maincpu->set_addrmap(AS_IO, &trs80m2_state::z80_io);
m_maincpu->busack_cb().set(m_dmac, FUNC(z80dma_device::bai_w));
// video hardware
screen_device &screen(SCREEN(config, SCREEN_TAG, SCREEN_TYPE_RASTER, rgb_t::green()));
@ -738,7 +739,7 @@ void trs80m2_state::trs80m2(machine_config &config)
m_ctc->zc_callback<2>().set(Z80SIO_TAG, FUNC(z80sio_device::rxtxcb_w));
Z80DMA(config, m_dmac, 8_MHz_XTAL / 2);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dmac->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dmac->in_mreq_callback().set(FUNC(trs80m2_state::read));
m_dmac->out_mreq_callback().set(FUNC(trs80m2_state::write));
@ -789,6 +790,7 @@ void trs80m16_state::trs80m16(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &trs80m16_state::z80_mem);
m_maincpu->set_addrmap(AS_IO, &trs80m16_state::m16_z80_io);
m_maincpu->set_irq_acknowledge_callback(AM9519A_TAG, FUNC(am9519_device::iack_cb));
m_maincpu->busack_cb().set(m_dmac, FUNC(z80dma_device::bai_w));
M68000(config, m_subcpu, 24_MHz_XTAL / 4);
m_subcpu->set_addrmap(AS_PROGRAM, &trs80m16_state::m68000_mem);
@ -831,7 +833,7 @@ void trs80m16_state::trs80m16(machine_config &config)
m_ctc->zc_callback<2>().set(Z80SIO_TAG, FUNC(z80sio_device::rxtxcb_w));
Z80DMA(config, m_dmac, 8_MHz_XTAL / 2);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dmac->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dmac->in_mreq_callback().set(FUNC(trs80m2_state::read));
m_dmac->out_mreq_callback().set(FUNC(trs80m2_state::write));

View File

@ -1112,6 +1112,7 @@ void bullet_state::bullet(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &bullet_state::bullet_mem);
m_maincpu->set_addrmap(AS_IO, &bullet_state::bullet_io);
m_maincpu->set_daisy_config(daisy_chain);
m_maincpu->busack_cb().set(m_dmac, FUNC(z80dma_device::bai_w));
// devices
Z80CTC(config, m_ctc, 16_MHz_XTAL / 4);
@ -1134,7 +1135,7 @@ void bullet_state::bullet(machine_config &config)
m_dart->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
Z80DMA(config, m_dmac, 16_MHz_XTAL / 4);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dmac->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dmac->in_mreq_callback().set(FUNC(bullet_state::dma_mreq_r));
m_dmac->out_mreq_callback().set(FUNC(bullet_state::dma_mreq_w));
@ -1193,6 +1194,7 @@ void bulletf_state::bulletf(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &bulletf_state::bulletf_mem);
m_maincpu->set_addrmap(AS_IO, &bulletf_state::bulletf_io);
m_maincpu->set_daisy_config(daisy_chain);
m_maincpu->busack_cb().set(m_dmac, FUNC(z80dma_device::bai_w));
// devices
Z80CTC(config, m_ctc, 16_MHz_XTAL / 4);
@ -1215,7 +1217,7 @@ void bulletf_state::bulletf(machine_config &config)
m_dart->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
Z80DMA(config, m_dmac, 16_MHz_XTAL / 4);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_dmac->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dmac->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dmac->in_mreq_callback().set(FUNC(bullet_state::dma_mreq_r));
m_dmac->out_mreq_callback().set(FUNC(bullet_state::dma_mreq_w));

View File

@ -131,7 +131,6 @@ private:
u8 kbd_r();
void kbd_put(u8 data);
void clock_w(int state);
void busreq_w(int state);
void ctc_z1_w(int state);
void sio_wrdya_w(int state);
void sio_wrdyb_w(int state);
@ -233,13 +232,6 @@ void bigbord2_state::fdc_drq_w(int state)
/* Z80 DMA */
void bigbord2_state::busreq_w(int state)
{
// since our Z80 has no support for BUSACK, we assume it is granted immediately
m_maincpu->set_input_line(Z80_INPUT_LINE_BUSRQ, state);
m_dma->bai_w(state); // tell dma that bus has been granted
}
u8 bigbord2_state::memory_read_byte(offs_t offset)
{
return m_mem->read_byte(offset);
@ -595,6 +587,7 @@ void bigbord2_state::bigbord2(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &bigbord2_state::mem_map);
m_maincpu->set_addrmap(AS_IO, &bigbord2_state::io_map);
m_maincpu->set_daisy_config(daisy_chain);
m_maincpu->busack_cb().set(m_dma, FUNC(z80dma_device::bai_w));
/* video hardware */
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
@ -607,7 +600,7 @@ void bigbord2_state::bigbord2(machine_config &config)
/* devices */
Z80DMA(config, m_dma, MAIN_CLOCK); // U62
m_dma->out_busreq_callback().set(FUNC(bigbord2_state::busreq_w));
m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ);
m_dma->out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0);
m_dma->in_mreq_callback().set(FUNC(bigbord2_state::memory_read_byte));
m_dma->out_mreq_callback().set(FUNC(bigbord2_state::memory_write_byte));