diff --git a/src/emu/cpu/i8089/i8089.c b/src/emu/cpu/i8089/i8089.c index cc09f5f5226..93f49c583c9 100644 --- a/src/emu/cpu/i8089/i8089.c +++ b/src/emu/cpu/i8089/i8089.c @@ -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(); } } diff --git a/src/emu/cpu/i8089/i8089.h b/src/emu/cpu/i8089/i8089.h index a991dfe6e17..24392df74af 100644 --- a/src/emu/cpu/i8089/i8089.h +++ b/src/emu/cpu/i8089/i8089.h @@ -148,6 +148,7 @@ private: // state of input pins int m_ca; int m_sel; + bool m_last_chan; }; diff --git a/src/emu/cpu/i8089/i8089_channel.c b/src/emu/cpu/i8089/i8089_channel.c index 7fafd7d6fdd..4d72529a114 100644 --- a/src/emu/cpu/i8089/i8089_channel.c +++ b/src/emu/cpu/i8089/i8089_channel.c @@ -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) diff --git a/src/emu/cpu/i8089/i8089_channel.h b/src/emu/cpu/i8089/i8089_channel.h index 6b130f89ffb..2ec3d70626c 100644 --- a/src/emu/cpu/i8089/i8089_channel.h +++ b/src/emu/cpu/i8089/i8089_channel.h @@ -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 + }; }; diff --git a/src/emu/cpu/i8089/i8089_ops.c b/src/emu/cpu/i8089/i8089_ops.c index 90bb8dcb986..9b8a0311248 100644 --- a/src/emu/cpu/i8089/i8089_ops.c +++ b/src/emu/cpu/i8089/i8089_ops.c @@ -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) diff --git a/src/emu/machine/i8251.c b/src/emu/machine/i8251.c index baad70314b2..ff11f7d3848 100644 --- a/src/emu/machine/i8251.c +++ b/src/emu/machine/i8251.c @@ -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) diff --git a/src/emu/machine/z80dart.c b/src/emu/machine/z80dart.c index de3aacd4b67..4d76388202e 100644 --- a/src/emu/machine/z80dart.c +++ b/src/emu/machine/z80dart.c @@ -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); } diff --git a/src/lib/formats/imd_dsk.c b/src/lib/formats/imd_dsk.c index 2f0ee10635d..317c4620831 100644 --- a/src/lib/formats/imd_dsk.c +++ b/src/lib/formats/imd_dsk.c @@ -410,7 +410,7 @@ bool imd_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) for(int i=0; i= img+size)) - global_free(sects[i].data); + global_free_array(sects[i].data); } return true; diff --git a/src/mess/drivers/isbc.c b/src/mess/drivers/isbc.c index 233b67728b8..11258b5e27d 100644 --- a/src/mess/drivers/isbc.c +++ b/src/mess/drivers/isbc.c @@ -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 ) diff --git a/src/mess/machine/isbc_215g.c b/src/mess/machine/isbc_215g.c index 5f5d6d1cf25..f6fd84012bd 100644 --- a/src/mess/machine/isbc_215g.c +++ b/src/mess/machine/isbc_215g.c @@ -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(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; } diff --git a/src/mess/machine/isbc_215g.h b/src/mess/machine/isbc_215g.h index 568c0671190..9d1b537b601 100644 --- a/src/mess/machine/isbc_215g.h +++ b/src/mess/machine/isbc_215g.h @@ -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]; };