z180: added support for DREQ, TEND signals; fixed dma0 count, DREQ handling (#2256)

This commit is contained in:
BartmanAbyss 2017-04-25 19:59:30 +02:00 committed by Olivier Galibert
parent 2b066459bd
commit 7830e17e58
2 changed files with 56 additions and 16 deletions

View File

@ -128,6 +128,16 @@ offs_t z180_device::disasm_disassemble(std::ostream &stream, offs_t pc, const ui
#define Z180_TXA1 0x00200000 /* O asynchronous transmit data 1 (active high) */
#define Z180_TXS 0x00400000 /* O clocked serial transmit data (active high) */
bool z180_device::get_tend0()
{
return !!(m_iol & Z180_TEND0);
}
bool z180_device::get_tend1()
{
return !!(m_iol & Z180_TEND1);
}
/*
* Prevent warnings on NetBSD. All identifiers beginning with an underscore
* followed by an uppercase letter are reserved by the C standard (ISO/IEC
@ -1587,7 +1597,7 @@ int z180_device::z180_dma0(int max_cycles)
return 0;
}
while (count-- > 0)
while (count > 0)
{
/* last transfer happening now? */
if (bcr0 == 1)
@ -1598,19 +1608,23 @@ int z180_device::z180_dma0(int max_cycles)
{
case 0x00: /* memory SAR0+1 to memory DAR0+1 */
m_program->write_byte(dar0++, m_program->read_byte(sar0++));
bcr0--;
break;
case 0x04: /* memory SAR0-1 to memory DAR0+1 */
m_program->write_byte(dar0++, m_program->read_byte(sar0--));
bcr0--;
break;
case 0x08: /* memory SAR0 fixed to memory DAR0+1 */
m_program->write_byte(dar0++, m_program->read_byte(sar0));
bcr0--;
break;
case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */
if (m_iol & Z180_DREQ0)
{
m_program->write_byte(dar0++, IN(sar0));
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
if (IO_DCNTL & Z180_DCNTL_DMS0)
{
m_iol &= ~Z180_DREQ0;
count = 0;
@ -1619,19 +1633,23 @@ int z180_device::z180_dma0(int max_cycles)
break;
case 0x10: /* memory SAR0+1 to memory DAR0-1 */
m_program->write_byte(dar0--, m_program->read_byte(sar0++));
bcr0--;
break;
case 0x14: /* memory SAR0-1 to memory DAR0-1 */
m_program->write_byte(dar0--, m_program->read_byte(sar0--));
bcr0--;
break;
case 0x18: /* memory SAR0 fixed to memory DAR0-1 */
m_program->write_byte(dar0--, m_program->read_byte(sar0));
bcr0--;
break;
case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */
if (m_iol & Z180_DREQ0)
{
m_program->write_byte(dar0--, IN(sar0));
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
if (IO_DCNTL & Z180_DCNTL_DMS0)
{
m_iol &= ~Z180_DREQ0;
count = 0;
@ -1640,9 +1658,11 @@ int z180_device::z180_dma0(int max_cycles)
break;
case 0x20: /* memory SAR0+1 to memory DAR0 fixed */
m_program->write_byte(dar0, m_program->read_byte(sar0++));
bcr0--;
break;
case 0x24: /* memory SAR0-1 to memory DAR0 fixed */
m_program->write_byte(dar0, m_program->read_byte(sar0--));
bcr0--;
break;
case 0x28: /* reserved */
break;
@ -1652,8 +1672,9 @@ int z180_device::z180_dma0(int max_cycles)
if (m_iol & Z180_DREQ0)
{
OUT(dar0, m_program->read_byte(sar0++));
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
if (IO_DCNTL & Z180_DCNTL_DMS0)
{
m_iol &= ~Z180_DREQ0;
count = 0;
@ -1664,8 +1685,9 @@ int z180_device::z180_dma0(int max_cycles)
if (m_iol & Z180_DREQ0)
{
OUT(dar0, m_program->read_byte(sar0--));
bcr0--;
/* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0)
if (IO_DCNTL & Z180_DCNTL_DMS0)
{
m_iol &= ~Z180_DREQ0;
count = 0;
@ -1677,7 +1699,6 @@ int z180_device::z180_dma0(int max_cycles)
case 0x3c: /* reserved */
break;
}
bcr0--;
count--;
cycles += 6;
if (cycles > max_cycles)
@ -2506,12 +2527,24 @@ void z180_device::execute_set_input(int irqline, int state)
{
LOG(("Z180 '%s' set_irq_line %d = %d\n",tag() , irqline,state));
/* update the IRQ state */
m_irq_state[irqline] = state;
if (daisy_chain_present())
m_irq_state[0] = daisy_update_irq_state();
if(irqline == Z180_INPUT_LINE_IRQ0 || irqline == Z180_INPUT_LINE_IRQ1 || irqline == Z180_INPUT_LINE_IRQ2) {
/* update the IRQ state */
m_irq_state[irqline] = state;
if(daisy_chain_present())
m_irq_state[0] = daisy_update_irq_state();
/* the main execute loop will take the interrupt */
/* the main execute loop will take the interrupt */
} else if(irqline == Z180_INPUT_LINE_DREQ0) {
auto iol = m_iol & ~Z180_DREQ0;
if(state == ASSERT_LINE)
iol |= Z180_DREQ0;
z180_write_iolines(iol);
} else if(irqline == Z180_INPUT_LINE_DREQ0) {
auto iol = m_iol & ~Z180_DREQ1;
if(state == ASSERT_LINE)
iol |= Z180_DREQ1;
z180_write_iolines(iol);
}
}
}

View File

@ -116,10 +116,14 @@ enum
Z180_TABLE_ex /* cycles counts for taken jr/jp/call and interrupt latency (rst opcodes) */
};
#define Z180_IRQ0 0 /* Execute IRQ1 */
#define Z180_IRQ1 1 /* Execute IRQ1 */
#define Z180_IRQ2 2 /* Execute IRQ2 */
// input lines
enum {
Z180_INPUT_LINE_IRQ0, /* Execute IRQ1 */
Z180_INPUT_LINE_IRQ1, /* Execute IRQ1 */
Z180_INPUT_LINE_IRQ2, /* Execute IRQ2 */
Z180_INPUT_LINE_DREQ0, /* Start DMA0 */
Z180_INPUT_LINE_DREQ1 /* Start DMA1 */
};
class z180_device : public cpu_device, public z80_daisy_chain_interface
{
@ -127,6 +131,9 @@ public:
// construction/destruction
z180_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
bool get_tend0();
bool get_tend1();
protected:
// device-level overrides
virtual void device_start() override;
@ -135,7 +142,7 @@ protected:
// device_execute_interface overrides
virtual uint32_t execute_min_cycles() const override { return 1; }
virtual uint32_t execute_max_cycles() const override { return 16; }
virtual uint32_t execute_input_lines() const override { return 3; }
virtual uint32_t execute_input_lines() const override { return 5; }
virtual uint32_t execute_default_irq_vector() const override { return 0xff; }
virtual void execute_run() override;
virtual void execute_burn(int32_t cycles) override;