mirror of
https://github.com/holub/mame
synced 2025-07-02 16:49:22 +03:00
4dpi: wip (nw)
* lance and scsi working * monitor, fx and sash run (latter two from cdrom or network) * irix boots from miniroot but hangs
This commit is contained in:
parent
f8c1f01694
commit
bad674aca2
@ -22,18 +22,22 @@
|
||||
****************************************************************************/
|
||||
/*
|
||||
* Sources:
|
||||
* - http://www.bitsavers.org/pdf/sgi/personal_iris/SGI_IP-6_Schematic.pdf
|
||||
* - http://www.futuretech.blinkenlights.nl/pitechrep.html
|
||||
* - https://hardware.majix.org/computers/sgi.pi/index.shtml
|
||||
* - http://archive.irix.cc/sgistuff/hardware/systems/personal.html
|
||||
* - http://archive.irix.cc/developerforum95/Silicon_Graphics_Developer_Forum_95_The_CD_Volume_2/documents/hw_handbook_html/handbook.html
|
||||
* - https://github.com/NetBSD/src/tree/trunk/sys/arch/sgimips/
|
||||
*
|
||||
* TODO:
|
||||
* - IOC1 and CTL1
|
||||
* - graphics, keyboard, mouse, audio
|
||||
* - graphics, audio
|
||||
*
|
||||
* Status:
|
||||
* - hangs waiting for wd33c93 reset interrupt
|
||||
* - if bypassed, hangs waiting on a timer(?) at bfa40004
|
||||
* - eeprom is glitchy/unreliable
|
||||
* - parity and cache diagnostics fail
|
||||
* - boots monitor and fx/sash from cdrom or network
|
||||
* - hangs after booting irix from miniroot
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
@ -55,6 +59,8 @@
|
||||
#include "machine/nscsi_hd.h"
|
||||
#include "machine/nscsi_cd.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "bus/sgikbd/sgikbd.h"
|
||||
#include "bus/rs232/hlemouse.h"
|
||||
|
||||
// video and audio
|
||||
#include "screen.h"
|
||||
@ -75,9 +81,10 @@ public:
|
||||
, m_rtc(*this, "rtc")
|
||||
, m_pit(*this, "pit")
|
||||
, m_scsi(*this, "scsi:0:wd33c93")
|
||||
, m_net(*this, "net")
|
||||
, m_enet(*this, "enet")
|
||||
, m_duart(*this, "duart%u", 0U)
|
||||
, m_serial(*this, "serial%u", 0U)
|
||||
, m_serial(*this, "serial%u", 1U)
|
||||
, m_leds(*this, "led%u", 0U)
|
||||
{
|
||||
}
|
||||
|
||||
@ -92,30 +99,92 @@ private:
|
||||
required_device<dp8573_device> m_rtc;
|
||||
required_device<pit8254_device> m_pit;
|
||||
required_device<wd33c93_device> m_scsi;
|
||||
required_device<am7990_device> m_net;
|
||||
required_device<am7990_device> m_enet;
|
||||
required_device_array<scn2681_device, 2> m_duart;
|
||||
required_device_array<rs232_port_device, 2> m_serial;
|
||||
|
||||
enum leds : unsigned
|
||||
{
|
||||
LED_HBT = 0, // heartbeat (1Hz)
|
||||
LED_CPU = 1, // cpu activity
|
||||
LED_GFX = 2, // graphics
|
||||
LED_FPU = 3, // fpu present
|
||||
};
|
||||
output_finder<4> m_leds;
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
template <unsigned N> void lio_interrupt(int state) { lio_interrupt(N, state); }
|
||||
void lio_interrupt(unsigned number, int state);
|
||||
void scsi_drq(int state);
|
||||
|
||||
enum sysid_mask : u8
|
||||
{
|
||||
SID_SERDATA = 0x01, // serial memory data output state
|
||||
SID_FPPRES = 0x02, // floating point processor present
|
||||
SID_SERCLK = 0x04, // serial memory clock
|
||||
SID_GDMAERR = 0x08, // error in graphics dma
|
||||
SID_GDMAEN = 0x10, // graphics dma busy
|
||||
SID_GDMARDY = 0x20, // asserted at end of graphics dma
|
||||
SID_GDMARST = 0x40, // asserted in reset of graphics dma
|
||||
SID_VMERMW = 0x80, // asserted in vme read-modify-write
|
||||
};
|
||||
|
||||
enum lio_int_number : unsigned
|
||||
{
|
||||
LIO_D0 = 0, // duart 0 interrupt
|
||||
LIO_D1 = 1, // duart 1 interrupt
|
||||
LIO_VR = 2, // vertical retrace interrupt
|
||||
LIO_CENTR = 3, // parallel port interrupt
|
||||
LIO_SCSI = 4, // scsi interrupt
|
||||
LIO_ENET = 5, // ethernet interrupt
|
||||
LIO_GE = 6, // ge interrupt
|
||||
LIO_FIFO = 7, // fifo full interrupt
|
||||
LIO_AC = 8, // vme ac fail interrupt
|
||||
LIO_VRSTAT = 9, // vert retrace status: no interrupt
|
||||
};
|
||||
|
||||
enum mem_cfg_mask : u8
|
||||
{
|
||||
MCF_4MRAM = 0x10,
|
||||
MCF_MEMSIZE = 0x1f,
|
||||
MCF_TIMERDIS = 0x20, // reduce peripheral r/w strobe
|
||||
MCF_FMEM = 0x40, // reduce cas pulse on reads
|
||||
MCF_REFDIS = 0x80, // disable memory refresh
|
||||
};
|
||||
|
||||
u8 m_mem_cfg;
|
||||
u8 m_ctl_sysid;
|
||||
u8 m_vme_isr;
|
||||
u8 m_vme_imr;
|
||||
u8 m_aux_cpuctrl;
|
||||
u16 m_ctl_cpuctrl;
|
||||
attotime m_refresh_timer;
|
||||
|
||||
u8 m_int_mask;
|
||||
u16 m_lio_isr;
|
||||
u8 m_lio_imr;
|
||||
bool m_lio_int;
|
||||
|
||||
u16 m_scsi_dmalo;
|
||||
unsigned m_scsi_dmapage;
|
||||
std::unique_ptr<u16 []> m_dma_map;
|
||||
};
|
||||
|
||||
void ip6_state::map(address_map &map)
|
||||
{
|
||||
//map(0x10000000, 0x1bffffff); // a32 kernel vme bus, vme modifier 0x09
|
||||
//map(0x1c000000, 0x1cffffff); // a24 kernel vme bus, vme modifier 0x3d
|
||||
//map(0x1e000000, 0x1effffff); // a24 kernel vme bus, vme modifier 0x39
|
||||
//map(0x10000000, 0x1bffffff); // vme a32 modifier 0x09 non-privileged
|
||||
//map(0x1c000000, 0x1cffffff); // vme a24 modifier 0x3d privileged
|
||||
//map(0x1e000000, 0x1effffff); // vme a24 modifier 0x39 non-privileged
|
||||
//map(0x1d000000, 0x1d00ffff); // vme a16 modifier 0x2d privileged
|
||||
//map(0x1d100000, 0x1d10ffff); // vme a16 modifier 0x29 non-privileged
|
||||
|
||||
//map(0x1f900000, 0x1f900000); // i/o controller (also lance and scsi)
|
||||
//map(0x1df00000, 0x1df00003).umask32(0x0000ff00); // VME_IACK: vme interrupt acknowledge
|
||||
|
||||
map(0x1f800000, 0x1f800003).lw8("mem_cfg", [this](u8 data) { m_mem_cfg = data; }).umask32(0xff000000);
|
||||
map(0x1f800000, 0x1f800003).lr8("ctl_sysid", [this]() { return m_ctl_sysid; }).umask32(0x00ff0000);
|
||||
|
||||
map(0x1f840008, 0x1f84000b).ram().umask32(0x000000ff); // vme mask?
|
||||
map(0x1f840000, 0x1f840003).lrw8("vme_isr", [this]() { return m_vme_isr; }, [this](u8 data) { m_vme_isr = data; }).umask32(0x000000ff);
|
||||
map(0x1f840008, 0x1f84000b).lrw8("vme_imr", [this]() { return m_vme_imr; }, [this](u8 data) { m_vme_imr = data; }).umask32(0x000000ff);
|
||||
|
||||
map(0x1f880000, 0x1f880003).lrw16("ctl_cpuctrl",
|
||||
[this]()
|
||||
@ -129,10 +198,14 @@ void ip6_state::map(address_map &map)
|
||||
//BIT(data, 9); // reset system
|
||||
//BIT(data, 10); // enable parity checking
|
||||
//BIT(data, 11); // enable slave accesses
|
||||
//BIT(data, 12); // enable vme arbiter
|
||||
//BIT(data, 13); // write bad parity
|
||||
//BIT(data, 14); // watchdog enable
|
||||
//BIT(data, 15); // unused/fast peripheral cycle?
|
||||
|
||||
m_ctl_cpuctrl = data;
|
||||
}).umask32(0x0000ffff);
|
||||
//map(0x1f8c0000, 0x1f8c0003); // lca readback trigger (b)
|
||||
map(0x1f8e0000, 0x1f8e0003).lrw8("aux_cpuctrl",
|
||||
[this]()
|
||||
{
|
||||
@ -140,50 +213,103 @@ void ip6_state::map(address_map &map)
|
||||
},
|
||||
[this](u8 data)
|
||||
{
|
||||
//BIT(data, 1); // heartbeat
|
||||
//BIT(data, 4); // enable console led(?)/eeprom program enable?
|
||||
// cpu leds
|
||||
m_leds[LED_HBT] = BIT(data, 0);
|
||||
m_leds[LED_CPU] = BIT(data, 1);
|
||||
m_leds[LED_GFX] = BIT(data, 2);
|
||||
m_leds[LED_FPU] = BIT(data, 3);
|
||||
|
||||
//BIT(data, 4); // console led(?) & eeprom program enable
|
||||
m_eeprom->cs_write(BIT(data, 5));
|
||||
m_eeprom->clk_write(BIT(data, 6));
|
||||
//BIT(data, 7); // gfx_reset: reset graphics subsystem
|
||||
|
||||
m_aux_cpuctrl = data;
|
||||
}).umask32(0xff000000);
|
||||
|
||||
map(0x1f950000, 0x1f9501ff).rw(m_net, FUNC(am7990_device::regs_r), FUNC(am7990_device::regs_w)).umask32(0xffff0000);
|
||||
map(0x1f900000, 0x1f900003).lrw16("scsi_dmalo_addr", [this]() { return m_scsi_dmalo; }, [this](u16 data) { m_scsi_dmalo = data; m_scsi_dmapage = 0; }).umask32(0x0000ffff);
|
||||
|
||||
// local interrupt goes to cpu interrupt 1
|
||||
//map(0x1f980000, 0x1f980003).r().umask32(0x0000ffff); // int1_local_status
|
||||
map(0x1f980008, 0x1f98000b).lrw8("int_mask", [this]() { return m_int_mask; }, [this](u8 data) { m_int_mask = data; }).umask32(0x000000ff); // int1_local_mask
|
||||
/*
|
||||
* DMA address mapping table is a pair of CY7C128-35PC 2048x8 SRAMs which
|
||||
* read/write to data bus D27-12. A10 is tied high, giving 1024 entries.
|
||||
*/
|
||||
map(0x1f920000, 0x1f920fff).lrw16("dma_map",
|
||||
[this](offs_t offset)
|
||||
{
|
||||
return m_dma_map[offset];
|
||||
},
|
||||
[this](offs_t offset, u16 data, u16 mem_mask)
|
||||
{
|
||||
mem_mask &= 0x0fff;
|
||||
COMBINE_DATA(&m_dma_map[offset]);
|
||||
}).umask32(0x0000ffff);
|
||||
|
||||
//map(0x1f940000, 0x1f940003).umask32(?); // scsi_flush_addr
|
||||
|
||||
map(0x1f950000, 0x1f9501ff).rw(m_enet, FUNC(am7990_device::regs_r), FUNC(am7990_device::regs_w)).umask32(0xffff0000);
|
||||
map(0x1f960000, 0x1f960007).lr8("enet_reset", [this](offs_t offset) { m_enet->reset_w(!offset); return 0; }).umask32(0xff000000);
|
||||
|
||||
map(0x1f980000, 0x1f980003).lr16("lio_isr", [this]() { return m_lio_isr; }).umask32(0x0000ffff);
|
||||
map(0x1f980008, 0x1f98000b).lrw8("lio_imr", [this]() { return m_lio_imr; }, [this](u8 data) { m_lio_imr = data; }).umask32(0x000000ff);
|
||||
|
||||
map(0x1fa00000, 0x1fa00003).lr8("timer1_ack", [this]() { m_cpu->set_input_line(INPUT_LINE_IRQ4, 0); return 0; }).umask32(0xff000000);
|
||||
map(0x1fa20000, 0x1fa20003).lr8("timer0_ack", [this]() { m_cpu->set_input_line(INPUT_LINE_IRQ2, 0); return 0; }).umask32(0xff000000);
|
||||
//map(0x1fa40000, 0x1fa4000f).rw(m_pit, FUNC(pit8254_device::read), FUNC(pit8254_device::write)).umask32(0xff000000); // NetBSD says 0x1fb40000?
|
||||
|
||||
//map(0x1fa40000, 0x1fa40000); // system bus error address
|
||||
map(0x1fa40004, 0x1fa40007).lrw32("refresh_timer",
|
||||
[this]()
|
||||
{
|
||||
return u32((machine().time() - m_refresh_timer).as_attoseconds() / ATTOSECONDS_PER_NANOSECOND);
|
||||
},
|
||||
[this](u32 data)
|
||||
{
|
||||
m_refresh_timer = machine().time() - attotime::from_nsec(data);
|
||||
});
|
||||
|
||||
//map(0x1fa40008, 0x1fa4000b); // GDMA_DABR_PHYS descriptor array base register
|
||||
//map(0x1fa4000c, 0x1fa4000f); // GDMA_BUFADR_PHYS buffer address register
|
||||
//map(0x1fa40010, 0x1fa400013).umask32(0xffff0000); // GDMA_BURST_PHYS burst/delay register
|
||||
//map(0x1fa40010, 0x1fa400013).umask32(0x0000ffff); // GDMA_BUFLEN_PHYS buffer length register
|
||||
|
||||
//map(0x1fa60000, 0x1fa600003); // VMA_RMW_ADDR
|
||||
|
||||
map(0x1fa80000, 0x1fa80007).lr32("scsi_reset", [this](offs_t offset) { m_scsi->reset_w(!!offset); return 0; });
|
||||
|
||||
// TODO: firmware resets wd33c93 and expects it to produce an interrupt - device emulation is currently wrong
|
||||
//map(0x1fa80008, 0x1fa8000b); // IOC2 configuration register, bus error on IOC1
|
||||
|
||||
//map(0x1faa0000, 0x1faa0003).umask32(0xff000000); // clear lan access bit
|
||||
//map(0x1faa0000, 0x1faa0003).umask32(0x00ff0000); // clear dma access bit
|
||||
//map(0x1faa0000, 0x1faa0003).umask32(0x0000ff00); // clear cpu access bit
|
||||
//map(0x1faa0000, 0x1faa0003).umask32(0x000000ff); // clear vme access bit
|
||||
//map(0x1faa0004, 0x1faa0007).umask32(0x00ff0000); // parity error register
|
||||
|
||||
map(0x1fb00000, 0x1fb00003).rw(m_scsi, FUNC(wd33c93_device::indir_addr_r), FUNC(wd33c93_device::indir_addr_w)).umask32(0x00ff0000);
|
||||
map(0x1fb00100, 0x1fb00103).rw(m_scsi, FUNC(wd33c93_device::indir_reg_r), FUNC(wd33c93_device::indir_reg_w)).umask32(0x00ff0000);
|
||||
|
||||
map(0x1fb40000, 0x1fb4000f).rw(m_pit, FUNC(pit8254_device::read), FUNC(pit8254_device::write)).umask32(0xff000000);
|
||||
|
||||
map(0x1fb80000, 0x1fb800ff).lrw8("duart0",
|
||||
map(0x1fb80000, 0x1fb800ff).lrw8("duarts",
|
||||
[this](offs_t offset)
|
||||
{
|
||||
return m_duart[0]->read(offset >> 2);
|
||||
return m_duart[BIT(offset, 0)]->read(offset >> 2);
|
||||
},
|
||||
[this](offs_t offset, u8 data)
|
||||
{
|
||||
m_duart[0]->write(offset >> 2, data);
|
||||
m_duart[BIT(offset, 0)]->write(offset >> 2, data);
|
||||
}).umask32(0xff000000);
|
||||
|
||||
map(0x1fbc0000, 0x1fbc00ff).rw(m_rtc, FUNC(dp8573_device::read), FUNC(dp8573_device::write)).umask32(0xff000000);
|
||||
map(0x1fbc0000, 0x1fbc007f).rw(m_rtc, FUNC(dp8573_device::read), FUNC(dp8573_device::write)).umask32(0xff000000);
|
||||
|
||||
map(0x1fc00000, 0x1fc3ffff).rom().region("prom", 0);
|
||||
}
|
||||
|
||||
static void scsi_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("cdrom", NSCSI_CDROM);
|
||||
device.option_add("cdrom", NSCSI_CDROM_SGI).machine_config(
|
||||
[](device_t *device)
|
||||
{
|
||||
downcast<nscsi_cdrom_device &>(*device).set_block_size(512);
|
||||
});
|
||||
device.option_add("harddisk", NSCSI_HARDDISK);
|
||||
}
|
||||
|
||||
@ -206,12 +332,12 @@ void ip6_state::configure(machine_config &config)
|
||||
[this](int state)
|
||||
{
|
||||
if (state)
|
||||
m_ctl_sysid |= 0x01;
|
||||
m_ctl_sysid |= SID_SERDATA;
|
||||
else
|
||||
m_ctl_sysid &= ~0x01;
|
||||
m_ctl_sysid &= ~SID_SERDATA;
|
||||
});
|
||||
|
||||
DP8573(config, m_rtc);
|
||||
DP8573(config, m_rtc); // DP8572AN
|
||||
|
||||
PIT8254(config, m_pit);
|
||||
m_pit->set_clk<2>(3.6864_MHz_XTAL);
|
||||
@ -222,11 +348,13 @@ void ip6_state::configure(machine_config &config)
|
||||
|
||||
NSCSI_BUS(config, "scsi");
|
||||
NSCSI_CONNECTOR(config, "scsi:0").option_set("wd33c93", WD33C93).machine_config(
|
||||
[](device_t *device)
|
||||
[this](device_t *device)
|
||||
{
|
||||
device->set_clock(10000000);
|
||||
wd33c93_device &wd33c93(downcast<wd33c93_device &>(*device));
|
||||
|
||||
// TODO: connect irq and drq
|
||||
wd33c93.set_clock(10000000);
|
||||
wd33c93.irq_cb().set(*this, FUNC(ip6_state::lio_interrupt<LIO_SCSI>)).invert();
|
||||
wd33c93.drq_cb().set(*this, FUNC(ip6_state::scsi_drq));
|
||||
});
|
||||
NSCSI_CONNECTOR(config, "scsi:1", scsi_devices, "harddisk", false);
|
||||
NSCSI_CONNECTOR(config, "scsi:2", scsi_devices, nullptr, false);
|
||||
@ -236,42 +364,72 @@ void ip6_state::configure(machine_config &config)
|
||||
NSCSI_CONNECTOR(config, "scsi:6", scsi_devices, "cdrom", false);
|
||||
NSCSI_CONNECTOR(config, "scsi:7", scsi_devices, nullptr, false);
|
||||
|
||||
AM7990(config, m_net);
|
||||
// TODO: irq, drq, memory accessors (via ioc)
|
||||
AM7990(config, m_enet);
|
||||
m_enet->intr_out().set(FUNC(ip6_state::lio_interrupt<LIO_ENET>));
|
||||
m_enet->dma_in().set(
|
||||
[this](offs_t offset)
|
||||
{
|
||||
unsigned const page = 0x200 + (offset >> 12);
|
||||
u32 const address = (u32(m_dma_map[page]) << 12) | (offset & 0xfff);
|
||||
|
||||
// duarts
|
||||
// NOTE: one of these is has 40 pins, while the other has only 24 pins; most
|
||||
// likely the keyboard/mouse one is without and doesn't have any flow control
|
||||
SCN2681(config, m_duart[0], 3.6864_MHz_XTAL);
|
||||
SCN2681(config, m_duart[1], 3.6864_MHz_XTAL); // TODO: probably for the keyboard and mouse
|
||||
return m_cpu->space(0).read_word(address);
|
||||
});
|
||||
m_enet->dma_out().set(
|
||||
[this](offs_t offset, u16 data, u16 mem_mask)
|
||||
{
|
||||
unsigned const page = 0x200 + (offset >> 12);
|
||||
u32 const address = (u32(m_dma_map[page]) << 12) | (offset & 0xfff);
|
||||
|
||||
m_cpu->space(0).write_word(address, data, mem_mask);
|
||||
});
|
||||
|
||||
// duart 0 (keyboard/mouse)
|
||||
SCN2681(config, m_duart[0], 3.6864_MHz_XTAL); // SCN2681AC1N24
|
||||
sgi_keyboard_port_device &keyboard_port(SGIKBD_PORT(config, "keyboard_port", default_sgi_keyboard_devices, "hlekbd"));
|
||||
rs232_port_device &mouse_port(RS232_PORT(config, "mouse_port",
|
||||
[](device_slot_interface &device)
|
||||
{
|
||||
device.option_add("mouse", SGI_HLE_SERIAL_MOUSE);
|
||||
},
|
||||
"mouse"));
|
||||
|
||||
// duart 0 outputs
|
||||
m_duart[0]->irq_cb().set(FUNC(ip6_state::lio_interrupt<LIO_D0>));
|
||||
m_duart[0]->a_tx_cb().set(keyboard_port, FUNC(sgi_keyboard_port_device::write_txd));
|
||||
m_duart[0]->b_tx_cb().set(mouse_port, FUNC(rs232_port_device::write_txd));
|
||||
|
||||
// duart 0 inputs
|
||||
keyboard_port.rxd_handler().set(m_duart[0], FUNC(scn2681_device::rx_a_w));
|
||||
mouse_port.rxd_handler().set(m_duart[0], FUNC(scn2681_device::rx_b_w));
|
||||
|
||||
// duart 1 (serial ports)
|
||||
SCN2681(config, m_duart[1], 3.6864_MHz_XTAL); // SCN2681AC1N40
|
||||
RS232_PORT(config, m_serial[0], default_rs232_devices, "terminal");
|
||||
RS232_PORT(config, m_serial[1], default_rs232_devices, nullptr);
|
||||
|
||||
// duart 0 outputs
|
||||
// TODO: irq
|
||||
m_duart[0]->a_tx_cb().set(m_serial[0], FUNC(rs232_port_device::write_txd));
|
||||
m_duart[0]->b_tx_cb().set(m_serial[1], FUNC(rs232_port_device::write_txd));
|
||||
m_duart[0]->outport_cb().set(
|
||||
// duart 1 outputs
|
||||
m_duart[1]->irq_cb().set(FUNC(ip6_state::lio_interrupt<LIO_D1>));
|
||||
m_duart[1]->a_tx_cb().set(m_serial[0], FUNC(rs232_port_device::write_txd));
|
||||
m_duart[1]->b_tx_cb().set(m_serial[1], FUNC(rs232_port_device::write_txd));
|
||||
m_duart[1]->outport_cb().set(
|
||||
[this](u8 data)
|
||||
{
|
||||
m_serial[0]->write_rts(BIT(data, 0));
|
||||
m_serial[1]->write_rts(BIT(data, 1));
|
||||
m_serial[0]->write_dtr(BIT(data, 2));
|
||||
m_serial[1]->write_dtr(BIT(data, 3));
|
||||
|
||||
// TODO: bit 4-7
|
||||
m_duart[1]->ip5_w(BIT(data, 3));
|
||||
m_duart[1]->ip6_w(BIT(data, 3));
|
||||
m_serial[0]->write_dtr(BIT(data, 4));
|
||||
m_serial[1]->write_dtr(BIT(data, 5));
|
||||
});
|
||||
|
||||
// duart inputs (guessed for now)
|
||||
m_serial[0]->rxd_handler().set(m_duart[0], FUNC(scn2681_device::rx_a_w));
|
||||
m_serial[0]->cts_handler().set(m_duart[0], FUNC(scn2681_device::ip0_w));
|
||||
m_serial[0]->dsr_handler().set(m_duart[0], FUNC(scn2681_device::ip3_w));
|
||||
m_serial[0]->dcd_handler().set(m_duart[0], FUNC(scn2681_device::ip4_w));
|
||||
// duart 1 inputs
|
||||
m_serial[0]->rxd_handler().set(m_duart[1], FUNC(scn2681_device::rx_a_w));
|
||||
m_serial[0]->cts_handler().set(m_duart[1], FUNC(scn2681_device::ip0_w));
|
||||
m_serial[0]->dcd_handler().set(m_duart[1], FUNC(scn2681_device::ip3_w));
|
||||
|
||||
m_serial[1]->rxd_handler().set(m_duart[0], FUNC(scn2681_device::rx_b_w));
|
||||
m_serial[1]->cts_handler().set(m_duart[0], FUNC(scn2681_device::ip1_w));
|
||||
m_serial[1]->dsr_handler().set(m_duart[0], FUNC(scn2681_device::ip5_w));
|
||||
m_serial[1]->dcd_handler().set(m_duart[0], FUNC(scn2681_device::ip6_w));
|
||||
m_serial[1]->rxd_handler().set(m_duart[1], FUNC(scn2681_device::rx_b_w));
|
||||
m_serial[1]->cts_handler().set(m_duart[1], FUNC(scn2681_device::ip1_w));
|
||||
m_serial[1]->dcd_handler().set(m_duart[1], FUNC(scn2681_device::ip2_w));
|
||||
}
|
||||
|
||||
void ip6_state::initialize()
|
||||
@ -279,7 +437,53 @@ void ip6_state::initialize()
|
||||
// map the configured ram
|
||||
m_cpu->space(0).install_ram(0x00000000, m_ram->mask(), m_ram->pointer());
|
||||
|
||||
m_ctl_sysid = 0x02; // fpu present
|
||||
m_ctl_sysid = SID_FPPRES;
|
||||
|
||||
m_lio_isr = 0x3ff;
|
||||
m_lio_imr = 0;
|
||||
m_lio_int = false;
|
||||
|
||||
m_refresh_timer = machine().time();
|
||||
|
||||
m_dma_map = make_unique_clear<u16 []>(2048);
|
||||
|
||||
m_leds.resolve();
|
||||
}
|
||||
|
||||
void ip6_state::lio_interrupt(unsigned number, int state)
|
||||
{
|
||||
u16 const mask = 1 << number;
|
||||
|
||||
// record interrupt state
|
||||
if (!state)
|
||||
m_lio_isr &= ~mask;
|
||||
else
|
||||
m_lio_isr |= mask;
|
||||
|
||||
// update interrupt line
|
||||
bool const lio_int = ~m_lio_isr & m_lio_imr;
|
||||
if (m_lio_imr ^ lio_int)
|
||||
{
|
||||
m_lio_int = lio_int;
|
||||
m_cpu->set_input_line(INPUT_LINE_IRQ1, m_lio_int);
|
||||
}
|
||||
}
|
||||
|
||||
void ip6_state::scsi_drq(int state)
|
||||
{
|
||||
if (state)
|
||||
{
|
||||
u32 const address = (u32(m_dma_map[m_scsi_dmapage]) << 12) | (m_scsi_dmalo & 0x0fff);
|
||||
|
||||
if (m_scsi_dmalo & 0x8000)
|
||||
m_cpu->space(0).write_byte(address, m_scsi->dma_r());
|
||||
else
|
||||
m_scsi->dma_w(m_cpu->space(0).read_byte(address));
|
||||
|
||||
m_scsi_dmalo = (m_scsi_dmalo & 0xf000) | ((m_scsi_dmalo + 1) & 0x0fff);
|
||||
if (!(m_scsi_dmalo & 0x0fff))
|
||||
m_scsi_dmapage++;
|
||||
}
|
||||
}
|
||||
|
||||
ROM_START(4d20)
|
||||
|
Loading…
Reference in New Issue
Block a user