i8089: channel priorities [Carl]

i8251: fix rx (nw)
z80dart: fix rx (nw)
imd_dsk: fix free array crash (nw)
(mess) isbc_215g: hdd seeks (nw)
This commit is contained in:
cracyc 2014-03-12 21:43:05 +00:00
parent 1bb1db4384
commit ff808d1af4
11 changed files with 126 additions and 28 deletions

View File

@ -100,6 +100,7 @@ void i8089_device::device_start()
save_item(NAME(m_master));
save_item(NAME(m_ca));
save_item(NAME(m_sel));
save_item(NAME(m_last_chan));
// assign memory spaces
m_mem = &space(AS_PROGRAM);
@ -125,6 +126,7 @@ void i8089_device::device_config_complete()
void i8089_device::device_reset()
{
m_initialized = false;
m_last_chan = 0;
}
//-------------------------------------------------
@ -325,9 +327,24 @@ void i8089_device::execute_run()
{
do
{
// allocate cycles to the two channels, very very incomplete
m_icount -= m_ch1->execute_run();
m_icount -= m_ch2->execute_run();
bool next_chan;
if(m_ch1->chan_prio() < m_ch2->chan_prio())
next_chan = 0;
else if(m_ch1->chan_prio() > m_ch2->chan_prio())
next_chan = 1;
else if(m_ch1->priority() && !m_ch2->priority())
next_chan = 0;
else if(!m_ch1->priority() && m_ch2->priority())
next_chan = 1;
else
next_chan = !m_last_chan;
m_last_chan = next_chan;
if(!next_chan)
m_icount -= m_ch1->execute_run();
else
m_icount -= m_ch2->execute_run();
}
while (m_icount > 0);
}
@ -349,9 +366,9 @@ WRITE_LINE_MEMBER( i8089_device::ca_w )
else
{
if (m_sel == 0)
m_ch1->attention();
m_ch1->ca();
else
m_ch2->attention();
m_ch2->ca();
}
}

View File

@ -148,6 +148,7 @@ private:
// state of input pins
int m_ca;
int m_sel;
bool m_last_chan;
};

View File

@ -75,6 +75,7 @@ void i8089_channel::device_start()
save_item(NAME(m_xfer_pending));
save_item(NAME(m_dma_value));
save_item(NAME(m_dma_state));
save_item(NAME(m_prio));
for (int i = 0; i < ARRAY_LENGTH(m_r); i++)
{
@ -97,6 +98,7 @@ void i8089_channel::device_reset()
m_r[i].w = 0;
m_r[i].t = 0;
}
m_prio = PRIO_IDLE;
}
@ -109,6 +111,8 @@ void i8089_channel::set_reg(int reg, UINT32 value, int tag)
if((reg == BC) || (reg == IX) || (reg == CC) || (reg == MC))
{
m_r[reg].w = value & 0xffff;
if((reg == CC) && executing())
m_prio = chained() ? PRIO_PROG_CHAIN : PRIO_PROG;
return;
}
m_r[reg].w = value & 0xfffff;
@ -130,6 +134,7 @@ void i8089_channel::set_reg(int reg, UINT32 value, int tag)
bool i8089_channel::executing() { return BIT(m_r[PSW].w, 2); }
bool i8089_channel::transferring() { return BIT(m_r[PSW].w, 6); }
bool i8089_channel::priority() { return BIT(m_r[PSW].w, 7); }
int i8089_channel::chan_prio() { return m_prio; }
bool i8089_channel::chained() { return CC_CHAIN; }
bool i8089_channel::lock() { return CC_LOCK; }
@ -204,6 +209,12 @@ int i8089_channel::execute_run()
{
m_icount = 0;
if (chan_prio() == PRIO_CHAN_ATTN)
{
attention();
return m_icount++;
}
// active transfer?
if (transferring())
{
@ -387,7 +398,12 @@ int i8089_channel::execute_run()
// dma transfer pending?
if (m_xfer_pending)
{
m_r[PSW].w |= 1 << 6;
m_prio = PRIO_DMA;
}
else
m_prio = chained() ? PRIO_PROG_CHAIN : PRIO_PROG;
// fetch first two instruction bytes
UINT16 op = m_iop->read_word(m_r[TP].t, m_r[TP].w);
@ -702,6 +718,7 @@ void i8089_channel::attention()
m_r[TP].t = 1;
m_r[PSW].w |= 1 << 2;
m_prio = chained() ? PRIO_PROG_CHAIN : PRIO_PROG;
if (VERBOSE)
{
@ -716,6 +733,7 @@ void i8089_channel::attention()
case 2:
if (VERBOSE)
logerror("%s('%s'): command received: invalid command 010\n", shortname(), tag());
m_prio = PRIO_IDLE;
break;
@ -728,9 +746,10 @@ void i8089_channel::attention()
lpd(PP, CP, m_r[CP].w + 2);
lpd(TP, PP, m_r[PP].w);
movbi_mi(CP, (INT8) 0xff, 1);
movbi_mi(CP, (INT8) 0xff, m_r[CP].w + 1);
m_r[PSW].w |= 1 << 2;
m_prio = chained() ? PRIO_PROG_CHAIN : PRIO_PROG;
if (VERBOSE)
{
@ -744,6 +763,7 @@ void i8089_channel::attention()
case 4:
if (VERBOSE)
logerror("%s('%s'): command received: invalid command 100\n", shortname(), tag());
m_prio = PRIO_IDLE;
break;
@ -758,6 +778,7 @@ void i8089_channel::attention()
movbi_mi(CP, (INT8) 0xff, m_r[CP].w + 1);
m_r[PSW].w |= 1 << 2;
m_prio = chained() ? PRIO_PROG_CHAIN : PRIO_PROG;
if (VERBOSE)
{
@ -790,6 +811,11 @@ void i8089_channel::attention()
}
}
void i8089_channel::ca()
{
m_prio = PRIO_CHAN_ATTN;
}
WRITE_LINE_MEMBER( i8089_channel::ext_w )
{
if (VERBOSE)

View File

@ -54,8 +54,10 @@ public:
bool executing();
bool transferring();
bool priority();
int chan_prio();
bool chained();
bool lock();
void ca();
DECLARE_WRITE_LINE_MEMBER( ext_w );
DECLARE_WRITE_LINE_MEMBER( drq_w );
@ -199,6 +201,19 @@ private:
DMA_COMPARE,
DMA_TERMINATE
};
int m_prio;
// priority
enum
{
PRIO_DMA = 1,
PRIO_DMA_TERM = 1,
PRIO_PROG_CHAIN = 1,
PRIO_CHAN_ATTN,
PRIO_PROG,
PRIO_IDLE
};
};

View File

@ -131,6 +131,7 @@ void i8089_channel::hlt()
{
movbi_mi(CP, 0x00, m_r[CP].w + 1);
m_r[PSW].w &= ~(1 << 2);
m_prio = PRIO_IDLE;
}
void i8089_channel::inc_r(int r)

View File

@ -686,7 +686,7 @@ void i8251_device::device_timer(emu_timer &timer, device_timer_id id, int param,
WRITE_LINE_MEMBER(i8251_device::write_rxd)
{
m_rxd = state;
device_serial_interface::rx_w(state);
// device_serial_interface::rx_w(state);
}
WRITE_LINE_MEMBER(i8251_device::write_cts)

View File

@ -1337,5 +1337,7 @@ void z80dart_channel::set_rts(int state)
WRITE_LINE_MEMBER(z80dart_channel::write_rx)
{
m_rxd = state;
device_serial_interface::rx_w(state);
//only use rx_w when self-clocked
if(m_rxc)
device_serial_interface::rx_w(state);
}

View File

@ -410,7 +410,7 @@ bool imd_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
for(int i=0; i<sector_count; i++)
if(sects[i].data && (sects[i].data < img || sects[i].data >= img+size))
global_free(sects[i].data);
global_free_array(sects[i].data);
}
return true;

View File

@ -61,12 +61,24 @@ public:
static ADDRESS_MAP_START(rpc86_mem, AS_PROGRAM, 16, isbc_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x00000, 0x0ffff) AM_RAM
AM_RANGE(0x00000, 0x3ffff) AM_RAM
AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION("user1",0)
ADDRESS_MAP_END
static ADDRESS_MAP_START(rpc86_io, AS_IO, 16, isbc_state)
ADDRESS_MAP_UNMAP_HIGH
AM_RANGE(0x0080, 0x008f) AM_DEVREADWRITE8("sbx1", isbx_slot_device, mcs0_r, mcs0_w, 0x00ff)
AM_RANGE(0x0090, 0x009f) AM_DEVREADWRITE8("sbx1", isbx_slot_device, mcs1_r, mcs1_w, 0x00ff)
AM_RANGE(0x00a0, 0x00af) AM_DEVREADWRITE8("sbx2", isbx_slot_device, mcs0_r, mcs0_w, 0x00ff)
AM_RANGE(0x00b0, 0x00bf) AM_DEVREADWRITE8("sbx2", isbx_slot_device, mcs1_r, mcs1_w, 0x00ff)
AM_RANGE(0x00c0, 0x00c3) AM_DEVREADWRITE8("pic_0", pic8259_device, read, write, 0x00ff)
AM_RANGE(0x00c4, 0x00c7) AM_DEVREADWRITE8("pic_0", pic8259_device, read, write, 0x00ff)
AM_RANGE(0x00c8, 0x00cf) AM_DEVREADWRITE8("ppi", i8255_device, read, write, 0x00ff)
AM_RANGE(0x00d0, 0x00d7) AM_DEVREADWRITE8("pit", pit8253_device, read, write, 0x00ff)
AM_RANGE(0x00d8, 0x00d9) AM_DEVREADWRITE8("uart8251", i8251_device, data_r, data_w, 0x00ff)
AM_RANGE(0x00da, 0x00db) AM_DEVREADWRITE8("uart8251", i8251_device, status_r, control_w, 0x00ff)
AM_RANGE(0x00dc, 0x00dd) AM_DEVREADWRITE8("uart8251", i8251_device, data_r, data_w, 0x00ff)
AM_RANGE(0x00de, 0x00df) AM_DEVREADWRITE8("uart8251", i8251_device, status_r, control_w, 0x00ff)
ADDRESS_MAP_END
static ADDRESS_MAP_START(isbc86_mem, AS_PROGRAM, 16, isbc_state)
@ -132,10 +144,6 @@ static DEVICE_INPUT_DEFAULTS_START( isbc86_terminal )
DEVICE_INPUT_DEFAULTS( "TERM_STOPBITS", 0xff, 0x03 ) // 2
DEVICE_INPUT_DEFAULTS_END
static DEVICE_INPUT_DEFAULTS_START( rpc86_terminal )
// No UART hooked up yet
DEVICE_INPUT_DEFAULTS_END
static DEVICE_INPUT_DEFAULTS_START( isbc286_terminal )
DEVICE_INPUT_DEFAULTS( "TERM_TXBAUD", 0xff, 0x06 ) // 9600
DEVICE_INPUT_DEFAULTS( "TERM_RXBAUD", 0xff, 0x06 ) // 9600
@ -267,9 +275,30 @@ static MACHINE_CONFIG_START( rpc86, isbc_state )
MCFG_CPU_IO_MAP(rpc86_io)
MCFG_PIC8259_ADD("pic_0", INPUTLINE(":maincpu", 0), VCC, NULL)
MCFG_DEVICE_ADD("pit", PIT8253, 0)
MCFG_PIT8253_CLK0(XTAL_22_1184MHz/18)
MCFG_PIT8253_OUT0_HANDLER(DEVWRITELINE("pic_0", pic8259_device, ir2_w))
MCFG_PIT8253_CLK1(XTAL_22_1184MHz/144)
MCFG_PIT8253_CLK2(XTAL_22_1184MHz/18)
MCFG_PIT8253_OUT2_HANDLER(WRITELINE(isbc_state, isbc86_tmr2_w))
MCFG_I8255A_ADD("ppi", isbc86_ppi_interface)
MCFG_DEVICE_ADD("uart8251", I8251, 0)
MCFG_I8251_TXD_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_txd))
MCFG_I8251_DTR_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_dtr))
MCFG_I8251_RTS_HANDLER(DEVWRITELINE("rs232", rs232_port_device, write_rts))
MCFG_I8251_RXRDY_HANDLER(DEVWRITELINE("pic_0", pic8259_device, ir6_w))
/* video hardware */
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, "serial_terminal")
MCFG_DEVICE_CARD_DEVICE_INPUT_DEFAULTS("serial_terminal", rpc86_terminal)
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, NULL)
MCFG_ISBX_SLOT_ADD("sbx1", 0, isbx_cards, NULL)
//MCFG_ISBX_SLOT_MINTR0_CALLBACK(DEVWRITELINE("pic_0", pic8259_device, ir3_w))
//MCFG_ISBX_SLOT_MINTR1_CALLBACK(DEVWRITELINE("pic_0", pic8259_device, ir4_w))
MCFG_ISBX_SLOT_ADD("sbx2", 0, isbx_cards, NULL)
//MCFG_ISBX_SLOT_MINTR0_CALLBACK(DEVWRITELINE("pic_0", pic8259_device, ir5_w))
//MCFG_ISBX_SLOT_MINTR1_CALLBACK(DEVWRITELINE("pic_0", pic8259_device, ir6_w))
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( isbc286, isbc_state )
@ -341,9 +370,6 @@ ROM_START( isbc286 )
ROM_REGION( 0x20000, "user1", ROMREGION_ERASEFF )
ROM_LOAD16_BYTE( "u79.bin", 0x00001, 0x10000, CRC(144182ea) SHA1(4620ca205a6ac98fe2636183eaead7c4bfaf7a72))
ROM_LOAD16_BYTE( "u36.bin", 0x00000, 0x10000, CRC(22db075f) SHA1(fd29ea77f5fc0697c8f8b66aca549aad5b9db3ea))
// ROM_REGION( 0x4000, "isbc215", ROMREGION_ERASEFF )
// ROM_LOAD16_BYTE( "174581.001.bin", 0x0000, 0x2000, CRC(ccdbc7ab) SHA1(5c2ebdde1b0252124177221ba9cacdb6d925a24d))
// ROM_LOAD16_BYTE( "174581.002.bin", 0x0001, 0x2000, CRC(6190fa67) SHA1(295dd4e75f699aaf93227cc4876cee8accae383a))
ROM_END
ROM_START( isbc2861 )

View File

@ -89,7 +89,7 @@ READ16_MEMBER(isbc_215g_device::io_r)
data |= (m_sbx1->get_card_device() ? 0 : 1) << 8;
data |= m_isbx_irq[0] << 9;
data |= m_isbx_irq[1] << 10;
data |= m_index << 15;
data |= ((m_index--) <= 0) ? 0x8000 : 0; // fake an index pulse
break;
case 0x04:
//read status 2
@ -170,16 +170,16 @@ WRITE16_MEMBER(isbc_215g_device::io_w)
else if(m_amsrch)
logerror("isbc_215g: address search without read gate\n");
case 0x01:
m_stepdir = (data & 0x80) ? 0 : 1;
m_stepdir = (data & 0x80) ? 1 : 0;
break;
case 0x04:
//clear index and id latch
m_index = false;
m_index = 10;
m_idfound = false;
break;
case 0x08:
//cmd data bus/head sel
m_head = data & 3;
m_head = data & 7;
m_out_irq_func((data & 0x100) ? 1 : 0);
break;
case 0x0c:
@ -192,6 +192,14 @@ WRITE16_MEMBER(isbc_215g_device::io_w)
// 5: extr 2
// 6: format
// 7: format wr gate
if(!m_step && (data & 1) && m_geom[m_drive])
{
if(m_cyl[m_drive] && !m_stepdir)
m_cyl[m_drive]--;
else if((m_cyl[m_drive] < m_geom[m_drive]->cylinders) && m_stepdir)
m_cyl[m_drive]++;
}
m_step = data & 1;
m_drive = (data >> 3) & 1; // st406 two drives only
if(((data >> 1) & 1) != m_fdctc)
{
@ -342,11 +350,12 @@ void isbc_215g_device::device_start()
m_maincpu_mem = &machine().device<cpu_device>(m_maincpu_tag)->space(AS_PROGRAM);
m_cyl[0] = m_cyl[1] = 0;
m_idcompare[0] = m_idcompare[1] = m_idcompare[2] = m_idcompare[3] = 0;
m_index = false;
m_index = 10;
m_idfound = false;
m_drive = 0;
m_head = 0;
m_stepdir = false;
m_step = false;
m_out_irq_func.resolve_safe();
@ -356,10 +365,11 @@ WRITE8_MEMBER(isbc_215g_device::write)
{
if(!offset)
{
data &= 3;
if(!data && (m_reset == 2))
m_dmac->reset();
m_out_irq_func(0);
m_dmac->ca_w(data != 2);
m_dmac->ca_w(data == 1);
m_dmac->ca_w(0);
m_reset = data;
}

View File

@ -52,10 +52,10 @@ private:
const char *m_maincpu_tag;
address_space *m_maincpu_mem;
UINT16 m_cyl[2];
UINT8 m_idcompare[4], m_drive, m_head;
bool m_idfound, m_index, m_stepdir, m_wrgate, m_rdgate, m_amsrch;
UINT8 m_idcompare[4], m_drive, m_head, m_index;
bool m_idfound, m_stepdir, m_wrgate, m_rdgate, m_amsrch;
bool m_isbx_irq[4], m_fdctc;
bool m_isbx_irq[4], m_fdctc, m_step;
const struct hard_disk_info* m_geom[2];
};