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_TXA1 0x00200000 /* O asynchronous transmit data 1 (active high) */
#define Z180_TXS 0x00400000 /* O clocked serial transmit data (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 * Prevent warnings on NetBSD. All identifiers beginning with an underscore
* followed by an uppercase letter are reserved by the C standard (ISO/IEC * 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; return 0;
} }
while (count-- > 0) while (count > 0)
{ {
/* last transfer happening now? */ /* last transfer happening now? */
if (bcr0 == 1) if (bcr0 == 1)
@ -1598,19 +1608,23 @@ int z180_device::z180_dma0(int max_cycles)
{ {
case 0x00: /* memory SAR0+1 to memory DAR0+1 */ case 0x00: /* memory SAR0+1 to memory DAR0+1 */
m_program->write_byte(dar0++, m_program->read_byte(sar0++)); m_program->write_byte(dar0++, m_program->read_byte(sar0++));
bcr0--;
break; break;
case 0x04: /* memory SAR0-1 to memory DAR0+1 */ case 0x04: /* memory SAR0-1 to memory DAR0+1 */
m_program->write_byte(dar0++, m_program->read_byte(sar0--)); m_program->write_byte(dar0++, m_program->read_byte(sar0--));
bcr0--;
break; break;
case 0x08: /* memory SAR0 fixed to memory DAR0+1 */ case 0x08: /* memory SAR0 fixed to memory DAR0+1 */
m_program->write_byte(dar0++, m_program->read_byte(sar0)); m_program->write_byte(dar0++, m_program->read_byte(sar0));
bcr0--;
break; break;
case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */ case 0x0c: /* I/O SAR0 fixed to memory DAR0+1 */
if (m_iol & Z180_DREQ0) if (m_iol & Z180_DREQ0)
{ {
m_program->write_byte(dar0++, IN(sar0)); m_program->write_byte(dar0++, IN(sar0));
bcr0--;
/* edge sensitive DREQ0 ? */ /* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0) if (IO_DCNTL & Z180_DCNTL_DMS0)
{ {
m_iol &= ~Z180_DREQ0; m_iol &= ~Z180_DREQ0;
count = 0; count = 0;
@ -1619,19 +1633,23 @@ int z180_device::z180_dma0(int max_cycles)
break; break;
case 0x10: /* memory SAR0+1 to memory DAR0-1 */ case 0x10: /* memory SAR0+1 to memory DAR0-1 */
m_program->write_byte(dar0--, m_program->read_byte(sar0++)); m_program->write_byte(dar0--, m_program->read_byte(sar0++));
bcr0--;
break; break;
case 0x14: /* memory SAR0-1 to memory DAR0-1 */ case 0x14: /* memory SAR0-1 to memory DAR0-1 */
m_program->write_byte(dar0--, m_program->read_byte(sar0--)); m_program->write_byte(dar0--, m_program->read_byte(sar0--));
bcr0--;
break; break;
case 0x18: /* memory SAR0 fixed to memory DAR0-1 */ case 0x18: /* memory SAR0 fixed to memory DAR0-1 */
m_program->write_byte(dar0--, m_program->read_byte(sar0)); m_program->write_byte(dar0--, m_program->read_byte(sar0));
bcr0--;
break; break;
case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */ case 0x1c: /* I/O SAR0 fixed to memory DAR0-1 */
if (m_iol & Z180_DREQ0) if (m_iol & Z180_DREQ0)
{ {
m_program->write_byte(dar0--, IN(sar0)); m_program->write_byte(dar0--, IN(sar0));
bcr0--;
/* edge sensitive DREQ0 ? */ /* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0) if (IO_DCNTL & Z180_DCNTL_DMS0)
{ {
m_iol &= ~Z180_DREQ0; m_iol &= ~Z180_DREQ0;
count = 0; count = 0;
@ -1640,9 +1658,11 @@ int z180_device::z180_dma0(int max_cycles)
break; break;
case 0x20: /* memory SAR0+1 to memory DAR0 fixed */ case 0x20: /* memory SAR0+1 to memory DAR0 fixed */
m_program->write_byte(dar0, m_program->read_byte(sar0++)); m_program->write_byte(dar0, m_program->read_byte(sar0++));
bcr0--;
break; break;
case 0x24: /* memory SAR0-1 to memory DAR0 fixed */ case 0x24: /* memory SAR0-1 to memory DAR0 fixed */
m_program->write_byte(dar0, m_program->read_byte(sar0--)); m_program->write_byte(dar0, m_program->read_byte(sar0--));
bcr0--;
break; break;
case 0x28: /* reserved */ case 0x28: /* reserved */
break; break;
@ -1652,8 +1672,9 @@ int z180_device::z180_dma0(int max_cycles)
if (m_iol & Z180_DREQ0) if (m_iol & Z180_DREQ0)
{ {
OUT(dar0, m_program->read_byte(sar0++)); OUT(dar0, m_program->read_byte(sar0++));
bcr0--;
/* edge sensitive DREQ0 ? */ /* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0) if (IO_DCNTL & Z180_DCNTL_DMS0)
{ {
m_iol &= ~Z180_DREQ0; m_iol &= ~Z180_DREQ0;
count = 0; count = 0;
@ -1664,8 +1685,9 @@ int z180_device::z180_dma0(int max_cycles)
if (m_iol & Z180_DREQ0) if (m_iol & Z180_DREQ0)
{ {
OUT(dar0, m_program->read_byte(sar0--)); OUT(dar0, m_program->read_byte(sar0--));
bcr0--;
/* edge sensitive DREQ0 ? */ /* edge sensitive DREQ0 ? */
if (IO_DCNTL & Z180_DCNTL_DIM0) if (IO_DCNTL & Z180_DCNTL_DMS0)
{ {
m_iol &= ~Z180_DREQ0; m_iol &= ~Z180_DREQ0;
count = 0; count = 0;
@ -1677,7 +1699,6 @@ int z180_device::z180_dma0(int max_cycles)
case 0x3c: /* reserved */ case 0x3c: /* reserved */
break; break;
} }
bcr0--;
count--; count--;
cycles += 6; cycles += 6;
if (cycles > max_cycles) 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)); LOG(("Z180 '%s' set_irq_line %d = %d\n",tag() , irqline,state));
/* update the IRQ state */ if(irqline == Z180_INPUT_LINE_IRQ0 || irqline == Z180_INPUT_LINE_IRQ1 || irqline == Z180_INPUT_LINE_IRQ2) {
m_irq_state[irqline] = state; /* update the IRQ state */
if (daisy_chain_present()) m_irq_state[irqline] = state;
m_irq_state[0] = daisy_update_irq_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) */ Z180_TABLE_ex /* cycles counts for taken jr/jp/call and interrupt latency (rst opcodes) */
}; };
#define Z180_IRQ0 0 /* Execute IRQ1 */ // input lines
#define Z180_IRQ1 1 /* Execute IRQ1 */ enum {
#define Z180_IRQ2 2 /* Execute IRQ2 */ 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 class z180_device : public cpu_device, public z80_daisy_chain_interface
{ {
@ -127,6 +131,9 @@ public:
// construction/destruction // construction/destruction
z180_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock); z180_device(const machine_config &mconfig, const char *_tag, device_t *_owner, uint32_t _clock);
bool get_tend0();
bool get_tend1();
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;
@ -135,7 +142,7 @@ protected:
// device_execute_interface overrides // device_execute_interface overrides
virtual uint32_t execute_min_cycles() const override { return 1; } virtual uint32_t execute_min_cycles() const override { return 1; }
virtual uint32_t execute_max_cycles() const override { return 16; } 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 uint32_t execute_default_irq_vector() const override { return 0xff; }
virtual void execute_run() override; virtual void execute_run() override;
virtual void execute_burn(int32_t cycles) override; virtual void execute_burn(int32_t cycles) override;