mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +03:00
jazz: wip checkpoint (nw)
At this point, jazz can start Windows NT 4.0 from cdrom, but crashes launching the session manager just prior to running setup.
This commit is contained in:
parent
71c134c887
commit
a035eafdfe
@ -3857,3 +3857,15 @@ if (MACHINES["DC7085"]~=null) then
|
||||
MAME_DIR .. "src/devices/machine/dc7085.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/i82357.h,MACHINES["I82357"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (MACHINES["I82357"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/i82357.cpp",
|
||||
MAME_DIR .. "src/devices/machine/i82357.h",
|
||||
}
|
||||
end
|
||||
|
@ -682,6 +682,7 @@ MACHINES["IOPTIMER"] = true
|
||||
MACHINES["Z8038"] = true
|
||||
MACHINES["AIC6250"] = true
|
||||
MACHINES["DC7085"] = true
|
||||
MACHINES["I82357"] = true
|
||||
|
||||
--------------------------------------------------
|
||||
-- specify available bus cores
|
||||
|
307
src/devices/machine/i82357.cpp
Normal file
307
src/devices/machine/i82357.cpp
Normal file
@ -0,0 +1,307 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
/*
|
||||
* An implementation of the Intel 82357 Integrated System Peripheral.
|
||||
*
|
||||
* This device was one part of the 3-chip Intel 82350 EISA bus chipset.
|
||||
*
|
||||
* Sources:
|
||||
*
|
||||
* http://bitsavers.org/components/intel/_dataBooks/1996_Intel_Peripheral_Components.pdf
|
||||
*
|
||||
* TODO
|
||||
* - expose everything to an actual EISA bus
|
||||
* - 32-bit dma functionality
|
||||
*
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "i82357.h"
|
||||
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
|
||||
//#define VERBOSE (LOG_GENERAL)
|
||||
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(I82357, i82357_device, "i82357", "Intel 82357 Integrated System Peripheral")
|
||||
|
||||
i82357_device::i82357_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, I82357, tag, owner, clock)
|
||||
, m_pic(*this, "pic%u", 0)
|
||||
, m_pit(*this, "pit%u", 0)
|
||||
, m_dma(*this, "dma%u", 0)
|
||||
, m_out_rtc(*this)
|
||||
, m_out_nmi(*this)
|
||||
, m_out_spkr(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void i82357_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
PIC8259(config, m_pic[0], 0);
|
||||
m_pic[0]->in_sp_callback().set_constant(1);
|
||||
m_pic[0]->read_slave_ack_callback().set(
|
||||
[this](offs_t offset)
|
||||
{
|
||||
if (offset == 2)
|
||||
return m_pic[1]->acknowledge();
|
||||
|
||||
return u32(0);
|
||||
});
|
||||
|
||||
PIC8259(config, m_pic[1], 0);
|
||||
m_pic[1]->out_int_callback().set(m_pic[0], FUNC(pic8259_device::ir2_w));
|
||||
m_pic[1]->in_sp_callback().set_constant(0);
|
||||
|
||||
PIT8254(config, m_pit[0], 0);
|
||||
PIT8254(config, m_pit[1], 0);
|
||||
|
||||
// timer 1 counter 0: system timer
|
||||
m_pit[0]->set_clk<0>(clock() / 12);
|
||||
m_pit[0]->out_handler<0>().set(m_pic[0], FUNC(pic8259_device::ir0_w));
|
||||
|
||||
// timer 1 counter 1: refresh request
|
||||
m_pit[0]->set_clk<1>(clock() / 12);
|
||||
m_pit[0]->out_handler<1>().set(
|
||||
[this](int state)
|
||||
{
|
||||
// FIXME: not accurate, but good enough to pass diagnostic
|
||||
if (state)
|
||||
m_nmi_reg ^= NMI_REFRESH;
|
||||
|
||||
m_pit[1]->write_gate2(state);
|
||||
});
|
||||
|
||||
// timer 1 counter 2: speaker
|
||||
m_pit[0]->set_clk<2>(clock() / 12);
|
||||
m_pit[0]->out_handler<2>().set(
|
||||
[this](int state)
|
||||
{
|
||||
if (state)
|
||||
m_nmi_reg |= NMI_T1C2_STATE;
|
||||
else
|
||||
m_nmi_reg &= ~NMI_T1C2_STATE;
|
||||
|
||||
m_out_spkr((m_nmi_reg & NMI_T1C2_STATE) && (m_nmi_reg & NMI_SPEAKER_DATA));
|
||||
});
|
||||
|
||||
// timer 2 counter 0: fail-safe timer
|
||||
m_pit[1]->set_clk<0>(clock() / 48);
|
||||
m_pit[1]->out_handler<0>().set(
|
||||
[this](int state)
|
||||
{
|
||||
if (state && (m_nmi_ext & NMI_EXT_EN_FAILSAFE))
|
||||
{
|
||||
m_nmi_ext |= NMI_EXT_FAILSAFE;
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
});
|
||||
|
||||
// timer 2 counter 1: does not exist
|
||||
|
||||
// timer 2 counter 2: cpu speed control
|
||||
m_pit[1]->set_clk<2>(8_MHz_XTAL);
|
||||
//m_pit[1]->out_handler<2>().set();
|
||||
|
||||
EISA_DMA(config, m_dma[0], clock() / 3);
|
||||
EISA_DMA(config, m_dma[1], clock() / 3);
|
||||
m_dma[1]->out_dack_callback<0>().set(m_dma[0], FUNC(eisa_dma_device::hack_w)).invert();
|
||||
}
|
||||
|
||||
void i82357_device::map(address_map &map)
|
||||
{
|
||||
map(0x000, 0x00f).rw(m_dma[0], FUNC(eisa_dma_device::read), FUNC(eisa_dma_device::write));
|
||||
map(0x020, 0x021).rw(m_pic[0], FUNC(pic8259_device::read), FUNC(pic8259_device::write));
|
||||
map(0x040, 0x043).rw(m_pit[0], FUNC(pit8254_device::read), FUNC(pit8254_device::write));
|
||||
map(0x048, 0x04b).rw(m_pit[1], FUNC(pit8254_device::read), FUNC(pit8254_device::write));
|
||||
|
||||
// FIXME: also 0x065 - "NMI Status"
|
||||
map(0x061, 0x061).rw(FUNC(i82357_device::nmi_reg_r), FUNC(i82357_device::nmi_reg_w));
|
||||
|
||||
// NMI Enable Register (0x70, 72, 74, 76)
|
||||
map(0x070, 0x077).lw8("nmi_rtc",
|
||||
[this](address_space &space, offs_t offset, u8 data)
|
||||
{
|
||||
m_nmi_enabled = !BIT(data, 7);
|
||||
|
||||
m_out_rtc(space, 0, data & 0x7f);
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}).umask64(0xff);
|
||||
|
||||
map(0x081, 0x081).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<2>), FUNC(eisa_dma_device::set_address_page<2>));
|
||||
map(0x082, 0x082).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<3>), FUNC(eisa_dma_device::set_address_page<3>));
|
||||
map(0x083, 0x083).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<1>), FUNC(eisa_dma_device::set_address_page<1>));
|
||||
map(0x087, 0x087).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page<0>), FUNC(eisa_dma_device::set_address_page<0>));
|
||||
map(0x089, 0x089).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<2>), FUNC(eisa_dma_device::set_address_page<2>));
|
||||
map(0x08a, 0x08a).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<3>), FUNC(eisa_dma_device::set_address_page<3>));
|
||||
map(0x08b, 0x08b).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<1>), FUNC(eisa_dma_device::set_address_page<1>));
|
||||
map(0x08f, 0x08f).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page<0>), FUNC(eisa_dma_device::set_address_page<0>));
|
||||
|
||||
// TODO: also 0xa4, a8, ac, b0, b4, b8, bc
|
||||
map(0x0a0, 0x0a1).rw(m_pic[1], FUNC(pic8259_device::read), FUNC(pic8259_device::write));
|
||||
map(0x0c0, 0x0df).rw(m_dma[1], FUNC(eisa_dma_device::read), FUNC(eisa_dma_device::write)).umask16(0x00ff);
|
||||
|
||||
map(0x401, 0x401).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<0>), FUNC(eisa_dma_device::set_count_high<0>));
|
||||
map(0x403, 0x403).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<1>), FUNC(eisa_dma_device::set_count_high<1>));
|
||||
map(0x405, 0x405).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<2>), FUNC(eisa_dma_device::set_count_high<2>));
|
||||
map(0x407, 0x407).rw(m_dma[0], FUNC(eisa_dma_device::get_count_high<3>), FUNC(eisa_dma_device::set_count_high<3>));
|
||||
|
||||
//map(0x40a, 0x40a); // DMA1 Set Chaining Mode (w)/Interrupt Status (r)
|
||||
//map(0x40b, 0x40b); // DMA1 Ext Write Mode (w)
|
||||
//map(0x40c, 0x40c); // Chain Buffer Control
|
||||
//map(0x40d, 0x40d); // Stepping Level Register (ro)
|
||||
//map(0x40e, 0x40e); // ISP Test Register
|
||||
//map(0x40f, 0x40f); // ISP Test Register
|
||||
|
||||
map(0x461, 0x461).rw(FUNC(i82357_device::nmi_ext_r), FUNC(i82357_device::nmi_ext_w));
|
||||
map(0x462, 0x462).lw8("nmi_ioport",
|
||||
[this](u8 data)
|
||||
{
|
||||
if (m_nmi_ext & NMI_EXT_EN_IOPORT)
|
||||
{
|
||||
m_nmi_ext |= NMI_EXT_IOPORT;
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
});
|
||||
//map(0x464, 0x464); // Last 32-bit bus master granted (L)
|
||||
|
||||
map(0x481, 0x481).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<2>), FUNC(eisa_dma_device::set_address_page_high<2>));
|
||||
map(0x482, 0x482).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<3>), FUNC(eisa_dma_device::set_address_page_high<3>));
|
||||
map(0x483, 0x483).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<1>), FUNC(eisa_dma_device::set_address_page_high<1>));
|
||||
map(0x487, 0x487).rw(m_dma[0], FUNC(eisa_dma_device::get_address_page_high<0>), FUNC(eisa_dma_device::set_address_page_high<0>));
|
||||
map(0x489, 0x489).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<2>), FUNC(eisa_dma_device::set_address_page_high<2>));
|
||||
map(0x48a, 0x48a).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<3>), FUNC(eisa_dma_device::set_address_page_high<3>));
|
||||
map(0x48b, 0x48b).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<1>), FUNC(eisa_dma_device::set_address_page_high<1>));
|
||||
map(0x48f, 0x48f).rw(m_dma[1], FUNC(eisa_dma_device::get_address_page_high<0>), FUNC(eisa_dma_device::set_address_page_high<0>));
|
||||
|
||||
map(0x4c2, 0x4c2).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<0>), FUNC(eisa_dma_device::set_count_high<0>));
|
||||
map(0x4c6, 0x4c6).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<1>), FUNC(eisa_dma_device::set_count_high<1>));
|
||||
map(0x4ca, 0x4ca).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<2>), FUNC(eisa_dma_device::set_count_high<2>));
|
||||
map(0x4ce, 0x4ce).rw(m_dma[1], FUNC(eisa_dma_device::get_count_high<3>), FUNC(eisa_dma_device::set_count_high<3>));
|
||||
map(0x4d0, 0x4d1).lrw8("elcr",
|
||||
[this](offs_t offset) { return m_elcr[offset]; },
|
||||
[this](offs_t offset, u8 data) { m_elcr[offset] = data; });
|
||||
|
||||
//map(0x4d4, 0x4d4); // DMA2 Set Chaining Mode
|
||||
//map(0x4d6, 0x4d6); // DMA2 Ext Write Mode Register
|
||||
|
||||
map(0x4e0, 0x4e3).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<0>), FUNC(eisa_dma_device::set_stop<0>));
|
||||
map(0x4e4, 0x4e7).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<1>), FUNC(eisa_dma_device::set_stop<1>));
|
||||
map(0x4e8, 0x4eb).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<2>), FUNC(eisa_dma_device::set_stop<2>));
|
||||
map(0x4ec, 0x4ef).rw(m_dma[0], FUNC(eisa_dma_device::get_stop<3>), FUNC(eisa_dma_device::set_stop<3>));
|
||||
|
||||
map(0x4f0, 0x4f3).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<0>), FUNC(eisa_dma_device::set_stop<0>)); // reserved
|
||||
map(0x4f4, 0x4f7).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<1>), FUNC(eisa_dma_device::set_stop<1>));
|
||||
map(0x4f8, 0x4fb).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<2>), FUNC(eisa_dma_device::set_stop<2>));
|
||||
map(0x4fc, 0x4ff).rw(m_dma[1], FUNC(eisa_dma_device::get_stop<3>), FUNC(eisa_dma_device::set_stop<3>));
|
||||
}
|
||||
|
||||
void i82357_device::device_start()
|
||||
{
|
||||
m_out_rtc.resolve_safe();
|
||||
m_out_nmi.resolve_safe();
|
||||
m_out_spkr.resolve_safe();
|
||||
|
||||
m_nmi_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(i82357_device::nmi_check), this));
|
||||
}
|
||||
|
||||
void i82357_device::device_reset()
|
||||
{
|
||||
m_elcr[0] = 0;
|
||||
m_elcr[1] = 0;
|
||||
|
||||
m_nmi_enabled = true;
|
||||
m_nmi_reg = 0;
|
||||
m_nmi_ext = 0;
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
void i82357_device::nmi_reg_w(u8 data)
|
||||
{
|
||||
m_pit[0]->write_gate2(!!(data & NMI_T1C2_GATE));
|
||||
|
||||
// clear parity nmi
|
||||
if (data & NMI_PARITY_DISABLE)
|
||||
m_nmi_reg &= ~NMI_PARITY;
|
||||
|
||||
// clear iochk nmi
|
||||
if (data & NMI_IOCHK_DISABLE)
|
||||
m_nmi_reg &= ~NMI_IOCHK;
|
||||
|
||||
m_nmi_reg = (m_nmi_reg & ~NMI_WMASK) | (data & NMI_WMASK);
|
||||
|
||||
// update speaker state
|
||||
m_out_spkr((m_nmi_reg & NMI_T1C2_STATE) && (m_nmi_reg & NMI_SPEAKER_DATA));
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
void i82357_device::nmi_ext_w(u8 data)
|
||||
{
|
||||
if (!(data & NMI_EXT_EN_IOPORT))
|
||||
m_nmi_ext &= ~NMI_EXT_IOPORT;
|
||||
|
||||
if (!(data & NMI_EXT_EN_TIMEOUT))
|
||||
m_nmi_ext &= ~NMI_EXT_TIMEOUT;
|
||||
|
||||
if (!(data & NMI_EXT_EN_FAILSAFE))
|
||||
m_nmi_ext &= ~NMI_EXT_FAILSAFE;
|
||||
|
||||
m_nmi_ext = (m_nmi_ext & ~NMI_EXT_WMASK) | (data & NMI_EXT_WMASK);
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(i82357_device::in_iochk)
|
||||
{
|
||||
if (!state && !(m_nmi_reg & NMI_PARITY_DISABLE))
|
||||
{
|
||||
m_nmi_reg |= NMI_IOCHK;
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
else
|
||||
m_nmi_reg &= ~NMI_IOCHK;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(i82357_device::in_parity)
|
||||
{
|
||||
if (!state && !(m_nmi_reg & NMI_IOCHK_DISABLE))
|
||||
{
|
||||
m_nmi_reg |= NMI_PARITY;
|
||||
|
||||
m_nmi_check->adjust(attotime::zero);
|
||||
}
|
||||
else
|
||||
m_nmi_reg &= ~NMI_PARITY;
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(i82357_device::nmi_check)
|
||||
{
|
||||
if (m_nmi_enabled)
|
||||
{
|
||||
if ((m_nmi_reg & NMI_NMI) || (m_nmi_ext & NMI_EXT_NMI))
|
||||
{
|
||||
if (!m_out_nmi_asserted)
|
||||
{
|
||||
m_out_nmi_asserted = true;
|
||||
m_out_nmi(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// disabled or no source
|
||||
if (m_out_nmi_asserted)
|
||||
{
|
||||
m_out_nmi_asserted = false;
|
||||
m_out_nmi(0);
|
||||
}
|
||||
}
|
91
src/devices/machine/i82357.h
Normal file
91
src/devices/machine/i82357.h
Normal file
@ -0,0 +1,91 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Patrick Mackinlay
|
||||
|
||||
#ifndef MAME_MACHINE_I82357_H
|
||||
#define MAME_MACHINE_I82357_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "machine/pic8259.h"
|
||||
#include "machine/pit8253.h"
|
||||
#include "machine/am9517a.h"
|
||||
|
||||
class i82357_device : public device_t
|
||||
{
|
||||
public:
|
||||
i82357_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
auto out_rtc_cb() { return m_out_rtc.bind(); }
|
||||
auto out_int_cb() { return subdevice<pic8259_device>("pic0")->out_int_callback(); }
|
||||
auto out_nmi_cb() { return m_out_nmi.bind(); }
|
||||
auto out_spkr_cb() { return m_out_spkr.bind(); }
|
||||
|
||||
u32 eisa_irq_ack() { return m_pic[0]->acknowledge(); }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER(in_iochk);
|
||||
DECLARE_WRITE_LINE_MEMBER(in_parity);
|
||||
|
||||
void map(address_map &map);
|
||||
|
||||
protected:
|
||||
// standard device_t overrides
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
void nmi_reg_w(u8 data);
|
||||
void nmi_ext_w(u8 data);
|
||||
u8 nmi_reg_r() { return m_nmi_reg; }
|
||||
u8 nmi_ext_r() { return m_nmi_ext; }
|
||||
|
||||
TIMER_CALLBACK_MEMBER(nmi_check);
|
||||
|
||||
private:
|
||||
required_device_array<pic8259_device, 2> m_pic;
|
||||
required_device_array<pit8254_device, 2> m_pit;
|
||||
required_device_array<eisa_dma_device, 2> m_dma;
|
||||
|
||||
devcb_write8 m_out_rtc;
|
||||
devcb_write_line m_out_nmi;
|
||||
devcb_write_line m_out_spkr;
|
||||
|
||||
enum nmi_reg_mask : u8
|
||||
{
|
||||
NMI_T1C2_GATE = 0x01,
|
||||
NMI_SPEAKER_DATA = 0x02,
|
||||
NMI_PARITY_DISABLE = 0x04,
|
||||
NMI_IOCHK_DISABLE = 0x08,
|
||||
NMI_REFRESH = 0x10,
|
||||
NMI_T1C2_STATE = 0x20,
|
||||
NMI_IOCHK = 0x40,
|
||||
NMI_PARITY = 0x80,
|
||||
|
||||
NMI_WMASK = 0x0f,
|
||||
NMI_NMI = 0xc0,
|
||||
};
|
||||
enum nmi_ext_mask : u8
|
||||
{
|
||||
NMI_EXT_BUS_RESET = 0x01, // bus reset (read/write)
|
||||
NMI_EXT_EN_IOPORT = 0x02,
|
||||
NMI_EXT_EN_FAILSAFE = 0x04,
|
||||
NMI_EXT_EN_TIMEOUT = 0x08,
|
||||
NMI_EXT_8US_TIMEOUT = 0x10, // 8us EISA bus master timeout occurred
|
||||
NMI_EXT_IOPORT = 0x20, // NMI I/O port interrupt pending
|
||||
NMI_EXT_TIMEOUT = 0x40, // EISA bus master timeout occurred, NMI requested
|
||||
NMI_EXT_FAILSAFE = 0x80, // Fail-safe timer is active, NMI requested
|
||||
|
||||
NMI_EXT_WMASK = 0x0f,
|
||||
NMI_EXT_NMI = 0xe0,
|
||||
};
|
||||
u8 m_elcr[2];
|
||||
|
||||
emu_timer *m_nmi_check;
|
||||
bool m_out_nmi_asserted;
|
||||
bool m_nmi_enabled;
|
||||
u8 m_nmi_reg;
|
||||
u8 m_nmi_ext;
|
||||
};
|
||||
|
||||
DECLARE_DEVICE_TYPE(I82357, i82357_device)
|
||||
|
||||
#endif // MAME_MACHINE_I82357_H
|
@ -13,7 +13,10 @@
|
||||
* http://www.sensi.org/~alec/mips/mips-history.html
|
||||
*
|
||||
* TODO
|
||||
* - everything (skeleton only)
|
||||
* - make it boot Windows NT
|
||||
* - big-endian support for RISC/os
|
||||
* - EISA bus and slots
|
||||
* - slotify and improve graphics board
|
||||
*
|
||||
* Unconfirmed parts lists from ARCSystem reference design (which appears to
|
||||
* be very similar or identical to the Jazz system) taken from:
|
||||
@ -69,35 +72,110 @@ void jazz_state::machine_reset()
|
||||
|
||||
void jazz_state::init_common()
|
||||
{
|
||||
// map the configured ram
|
||||
m_maincpu->space(AS_PROGRAM).install_ram(0, m_ram->mask(), m_ram->pointer());
|
||||
// map the configured ram and vram
|
||||
m_cpu->space(0).install_ram(0x00000000, 0x00000000 | m_ram->mask(), m_ram->pointer());
|
||||
m_cpu->space(0).install_ram(0x40000000, 0x40000000 | m_vram->mask(), m_vram->pointer());
|
||||
}
|
||||
|
||||
void jazz_state::jazz_common_map(address_map &map)
|
||||
{
|
||||
map(0x1fc00000, 0x1fc3ffff).r(m_flash, FUNC(amd_28f020_device::read));
|
||||
|
||||
// FIXME: lots of guesswork and assumptions here for now
|
||||
map(0x40000000, 0x407fffff).ram().share("vram"); // local video memory
|
||||
map(0x60000000, 0x6000013f).lr8("video_rom",
|
||||
[](offs_t offset)
|
||||
{
|
||||
/*
|
||||
* Board_Identifier, PROM_Stride, PROM_Width, PROM_Size
|
||||
* 0=JazzVideoG300, 1=JazzVideoG364, 2=JazzVideoVxl, 0x10=MipsVideoG364, 0x11=MaximumJazzVideo (jazzvideog364 osc period == 123077, MipsVideoG364 = 200000)
|
||||
* Test_Byte_0 - Test_Byte_3
|
||||
* VideoMemorySize, VideoControlSize
|
||||
* CodeOffset, CodeSize
|
||||
* ID string
|
||||
*/
|
||||
/*
|
||||
static u8 const jazz_g364[] =
|
||||
{
|
||||
0x01, 0x08, 0x01, 0x20, 'J', 'a', 'z', 'z',
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||
'J', 'a', 'z', 'z', ' ', 'G', '3', '6',
|
||||
'4', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static u8 const mips_g364[] =
|
||||
{
|
||||
0x10, 0x08, 0x01, 0x20, 'J', 'a', 'z', 'z',
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||
'M', 'i', 'p', 's', ' ', 'G', '3', '6',
|
||||
'4', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
*/
|
||||
|
||||
static u8 const bogus_g364[] =
|
||||
{
|
||||
0x10, 0x00, 0x00, 0x00, 'J', 'a', 'z', 'z',
|
||||
0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00,
|
||||
0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
|
||||
'M', 'i', 'p', 's', ' ', 'G', '3', '6',
|
||||
'4', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
return bogus_g364[offset];
|
||||
}).umask64(0xff);
|
||||
|
||||
map(0x60080000, 0x60081fff).m(m_ramdac, FUNC(g364_device::map)); // local video control
|
||||
map(0x60180000, 0x60180007).lw32("g364_reset", [this](u32 data) { m_ramdac->reset(); });
|
||||
|
||||
map(0x80000000, 0x80000fff).m(m_mct_adr, FUNC(jazz_mct_adr_device::map));
|
||||
map(0x80001000, 0x80001fff).m(m_network, FUNC(dp83932c_device::map));
|
||||
//map(0x80002000, 0x80002fff).m(m_scsi, FUNC(ncr5390_device::map)).umask32(0x000000ff);
|
||||
map(0x80003000, 0x80003fff).m(m_fdc, FUNC(n82077aa_device::map));
|
||||
//map(0x80004000, 0x80004fff).rw(m_rtc, FUNC(mc146818_device::read), FUNC(mc146818_device::write));
|
||||
//map(0x80005000, 0x80005fff).m() // keyboard/mouse
|
||||
//map(0x80006000, 0x80006fff).m() // serial1
|
||||
//map(0x80007000, 0x80007fff).m() // serial2
|
||||
//map(0x80008000, 0x80008fff).m() // parallel
|
||||
map(0x80009000, 0x80009fff).ram().share("nvram"); // unprotected?
|
||||
map(0x8000a000, 0x8000afff).ram().share("nvram"); // protected?
|
||||
map(0x8000b000, 0x8000bfff).ram().share("nvram"); // read-only? also sonic IO access?
|
||||
|
||||
map(0x80001000, 0x800010ff).m(m_network, FUNC(dp83932c_device::map)).umask32(0x0000ffff);
|
||||
map(0x80002000, 0x8000200f).m(m_scsi, FUNC(ncr53c94_device::map));
|
||||
map(0x80003000, 0x8000300f).m(m_fdc, FUNC(n82077aa_device::map));
|
||||
map(0x80004000, 0x80004007).lrw8("rtc",
|
||||
[this](address_space &space, offs_t offset) { return m_rtc->read(space, 1); },
|
||||
[this](address_space &space, offs_t offset, u8 data) { m_rtc->write(space, 1, data); }).umask64(0xff);
|
||||
map(0x80005000, 0x80005007).rw(m_kbdc, FUNC(at_keyboard_controller_device::data_r), FUNC(at_keyboard_controller_device::data_w)).umask64(0x00ff);
|
||||
map(0x80005000, 0x80005007).rw(m_kbdc, FUNC(at_keyboard_controller_device::status_r), FUNC(at_keyboard_controller_device::command_w)).umask64(0xff00);
|
||||
map(0x80006000, 0x80006007).rw(m_ace[0], FUNC(ns16550_device::ins8250_r), FUNC(ns16550_device::ins8250_w));
|
||||
map(0x80007000, 0x80007007).rw(m_ace[1], FUNC(ns16550_device::ins8250_r), FUNC(ns16550_device::ins8250_w));
|
||||
map(0x80008000, 0x80008007).rw(m_lpt, FUNC(pc_lpt_device::read), FUNC(pc_lpt_device::write)).umask64(0xffffffff);
|
||||
map(0x80009000, 0x8000afff).ram().share("nvram"); // 9000-9fff unprotected/a000-afff protected?
|
||||
map(0x8000b000, 0x8000b007).lr8("mac", [this](offs_t offset)
|
||||
{
|
||||
// mac address and checksum
|
||||
static u8 const mac[] = { 0x00, 0x00, 0x6b, 0x12, 0x34, 0x56, 0x00, 0xf7 };
|
||||
|
||||
return mac[offset];
|
||||
});
|
||||
// 3 4k pages of nvram: read/write, protected, read-only
|
||||
// last page holds ethernet mac and checksum in bytes 0-7
|
||||
|
||||
//map(0x8000c000, 0x8000cfff) // sound
|
||||
map(0x8000d000, 0x8000dfff).noprw(); // dummy dma device?
|
||||
//map(0x8000d000, 0x8000dfff).noprw(); // dummy dma device?
|
||||
map(0x8000d600, 0x8000d607).nopw();
|
||||
|
||||
map(0x8000f000, 0x8000f001).rw(FUNC(jazz_state::led_r), FUNC(jazz_state::led_w));
|
||||
map(0x8000f000, 0x8000f007).lrw8(
|
||||
"led",
|
||||
[this]() { return m_led; },
|
||||
[this](u8 data)
|
||||
{
|
||||
logerror("led 0x%02x (%s)\n", data, machine().describe_context());
|
||||
m_led = data;
|
||||
}).umask64(0xff);
|
||||
|
||||
//map(0x800e0000, 0x800e0000).rw(FUNC(jazz_state::dram_config_r), FUNC(jazz_state::dram_config_w));
|
||||
// lots of byte data written to 800
|
||||
//map(0x800e0000, 0x800fffff).m() // dram config
|
||||
|
||||
map(0xe0800000, 0xe0bfffff).ram().share("vram"); // framebuffer?
|
||||
map(0x90000000, 0x90ffffff).m(m_isp, FUNC(i82357_device::map));
|
||||
|
||||
//map(0x91000000, 0x91ffffff).m();
|
||||
//map(0x92000000, 0x92ffffff).m(); // EISA I/O ports?
|
||||
//map(0x93000000, 0x93ffffff).m(); // EISA memory
|
||||
|
||||
map(0xf0000000, 0xf0000007).r(m_mct_adr, FUNC(jazz_mct_adr_device::isr_r)).umask64(0xffff);
|
||||
map(0xf0000000, 0xf0000007).rw(m_mct_adr, FUNC(jazz_mct_adr_device::imr_r), FUNC(jazz_mct_adr_device::imr_w)).umask64(0xffff0000);
|
||||
|
||||
map(0xfff00000, 0xfff3ffff).r(m_flash, FUNC(amd_28f020_device::read)); // mirror?
|
||||
}
|
||||
@ -108,46 +186,62 @@ static void jazz_scsi_devices(device_slot_interface &device)
|
||||
device.option_add("cdrom", NSCSI_CDROM);
|
||||
}
|
||||
|
||||
FLOPPY_FORMATS_MEMBER(jazz_state::floppy_formats)
|
||||
FLOPPY_PC_FORMAT
|
||||
FLOPPY_FORMATS_END
|
||||
|
||||
void jazz_state::jazz(machine_config &config)
|
||||
{
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &jazz_state::jazz_common_map);
|
||||
R4000(config, m_cpu, 50_MHz_XTAL);
|
||||
m_cpu->set_addrmap(0, &jazz_state::jazz_common_map);
|
||||
|
||||
RAM(config, m_ram, 0);
|
||||
m_ram->set_default_size("8M");
|
||||
m_ram->set_extra_options("16M,32M,64M,128M,256M");
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("16M");
|
||||
m_ram->set_extra_options("32M,64M,128M,256M");
|
||||
m_ram->set_default_value(0);
|
||||
|
||||
RAM(config, m_vram);
|
||||
m_vram->set_default_size("2M");
|
||||
m_vram->set_default_value(0);
|
||||
|
||||
// FIXME: may require big and little endian variants
|
||||
// local bus dma, timer and interrupt controller
|
||||
JAZZ_MCT_ADR(config, m_mct_adr, 0);
|
||||
m_mct_adr->set_bus(m_cpu, 0);
|
||||
m_mct_adr->out_int_dma_cb().set_inputline(m_cpu, INPUT_LINE_IRQ0);
|
||||
m_mct_adr->out_int_device_cb().set_inputline(m_cpu, INPUT_LINE_IRQ1);
|
||||
m_mct_adr->out_int_timer_cb().set_inputline(m_cpu, INPUT_LINE_IRQ4);
|
||||
m_mct_adr->eisa_iack_cb().set(m_isp, FUNC(i82357_device::eisa_irq_ack));
|
||||
|
||||
// scsi bus and devices
|
||||
NSCSI_BUS(config, m_scsibus, 0);
|
||||
|
||||
nscsi_connector &harddisk(NSCSI_CONNECTOR(config, "scsi:0", 0));
|
||||
jazz_scsi_devices(harddisk);
|
||||
harddisk.set_default_option("harddisk");
|
||||
|
||||
nscsi_connector &cdrom(NSCSI_CONNECTOR(config, "scsi:6", 0));
|
||||
jazz_scsi_devices(cdrom);
|
||||
cdrom.set_default_option("cdrom");
|
||||
|
||||
jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:1", 0));
|
||||
jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:2", 0));
|
||||
jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:3", 0));
|
||||
jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:4", 0));
|
||||
jazz_scsi_devices(NSCSI_CONNECTOR(config, "scsi:5", 0));
|
||||
NSCSI_BUS(config, m_scsibus);
|
||||
NSCSI_CONNECTOR(config, "scsi:0", jazz_scsi_devices, "harddisk");
|
||||
NSCSI_CONNECTOR(config, "scsi:1", jazz_scsi_devices, nullptr);
|
||||
NSCSI_CONNECTOR(config, "scsi:2", jazz_scsi_devices, nullptr);
|
||||
NSCSI_CONNECTOR(config, "scsi:3", jazz_scsi_devices, nullptr);
|
||||
NSCSI_CONNECTOR(config, "scsi:4", jazz_scsi_devices, nullptr);
|
||||
NSCSI_CONNECTOR(config, "scsi:5", jazz_scsi_devices, nullptr);
|
||||
NSCSI_CONNECTOR(config, "scsi:6", jazz_scsi_devices, "cdrom");
|
||||
|
||||
// scsi host adapter
|
||||
nscsi_connector &adapter(NSCSI_CONNECTOR(config, "scsi:7", 0));
|
||||
adapter.option_add_internal("host", NCR53C90A);
|
||||
adapter.set_default_option("host");
|
||||
adapter.set_fixed(true);
|
||||
NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr53c94", NCR53C94).clock(24_MHz_XTAL).machine_config(
|
||||
[this](device_t *device)
|
||||
{
|
||||
ncr53c94_device &adapter = downcast<ncr53c94_device &>(*device);
|
||||
|
||||
adapter.irq_handler_cb().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<5>));;
|
||||
adapter.drq_handler_cb().set(m_mct_adr, FUNC(jazz_mct_adr_device::drq<0>));
|
||||
|
||||
subdevice<jazz_mct_adr_device>(":mct_adr")->dma_r_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_r));
|
||||
subdevice<jazz_mct_adr_device>(":mct_adr")->dma_w_cb<0>().set(adapter, FUNC(ncr53c94_device::dma_w));
|
||||
});
|
||||
|
||||
// floppy controller and drive
|
||||
N82077AA(config, m_fdc, 24_MHz_XTAL);
|
||||
m_fdc->intrq_wr_callback().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<1>));
|
||||
m_fdc->drq_wr_callback().set(m_mct_adr, FUNC(jazz_mct_adr_device::drq<1>));
|
||||
FLOPPY_CONNECTOR(config, "fdc:0", "35hd", FLOPPY_35_HD, true, jazz_state::floppy_formats).enable_sound(false);
|
||||
m_mct_adr->dma_r_cb<1>().set(m_fdc, FUNC(n82077aa_device::dma_r));
|
||||
m_mct_adr->dma_w_cb<1>().set(m_fdc, FUNC(n82077aa_device::dma_w));
|
||||
|
||||
MC146818(config, m_rtc, 32.768_kHz_XTAL);
|
||||
|
||||
@ -155,57 +249,112 @@ void jazz_state::jazz(machine_config &config)
|
||||
|
||||
AMD_28F020(config, m_flash);
|
||||
|
||||
// pc keyboard controller?
|
||||
// pc keyboard connector
|
||||
pc_kbdc_device &kbdc(PC_KBDC(config, "pc_kbdc", 0));
|
||||
kbdc.out_clock_cb().set(m_kbdc, FUNC(at_keyboard_controller_device::kbd_clk_w));
|
||||
kbdc.out_data_cb().set(m_kbdc, FUNC(at_keyboard_controller_device::kbd_data_w));
|
||||
kbdc.out_clock_cb().set(m_kbdc, FUNC(ps2_keyboard_controller_device::kbd_clk_w));
|
||||
kbdc.out_data_cb().set(m_kbdc, FUNC(ps2_keyboard_controller_device::kbd_data_w));
|
||||
|
||||
// keyboard port
|
||||
pc_kbdc_slot_device &kbd(PC_KBDC_SLOT(config, "kbd", 0));
|
||||
pc_at_keyboards(kbd);
|
||||
kbd.set_default_option(STR_KBD_IBM_PC_AT_84);
|
||||
kbd.set_default_option(STR_KBD_MICROSOFT_NATURAL);
|
||||
kbd.set_pc_kbdc_slot(&kbdc);
|
||||
|
||||
// at keyboard controller
|
||||
AT_KEYBOARD_CONTROLLER(config, m_kbdc, 12_MHz_XTAL);
|
||||
m_kbdc->hot_res().set_inputline(m_maincpu, INPUT_LINE_RESET);
|
||||
// keyboard controller
|
||||
PS2_KEYBOARD_CONTROLLER(config, m_kbdc, 12_MHz_XTAL);
|
||||
//m_kbdc->hot_res().set_inputline(m_cpu, INPUT_LINE_RESET);
|
||||
m_kbdc->hot_res().set([this](int state) { if (!state) m_cpu->reset(); });
|
||||
m_kbdc->kbd_clk().set(kbdc, FUNC(pc_kbdc_device::clock_write_from_mb));
|
||||
m_kbdc->kbd_data().set(kbdc, FUNC(pc_kbdc_device::data_write_from_mb));
|
||||
m_kbdc->kbd_irq().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<6>));;
|
||||
|
||||
//m_kbdc->mouse_clk().set();
|
||||
//m_kbdc->mouse_data().set();
|
||||
m_kbdc->mouse_irq().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<7>));
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(78643200, 1280, 0, 1280, 1024, 0, 1024);
|
||||
m_screen->set_screen_update("g364", FUNC(g364_device::screen_update));
|
||||
m_screen->screen_vblank().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<3>)); // maybe?
|
||||
|
||||
G364(config, m_ramdac, 5_MHz_XTAL); // FIXME: guessed clock
|
||||
m_ramdac->set_screen(m_screen);
|
||||
m_ramdac->set_vram(m_vram);
|
||||
|
||||
// WD16C552 (two 16550 + pc_lpt)
|
||||
NS16550(config, m_ace[0], 4233600);
|
||||
rs232_port_device &serial0(RS232_PORT(config, "serial0", default_rs232_devices, nullptr));
|
||||
|
||||
m_ace[0]->out_dtr_callback().set(serial0, FUNC(rs232_port_device::write_dtr));
|
||||
m_ace[0]->out_rts_callback().set(serial0, FUNC(rs232_port_device::write_rts));
|
||||
m_ace[0]->out_tx_callback().set(serial0, FUNC(rs232_port_device::write_txd));
|
||||
m_ace[0]->out_int_callback().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<8>));
|
||||
|
||||
serial0.cts_handler().set(m_ace[0], FUNC(ns16550_device::cts_w));
|
||||
serial0.dcd_handler().set(m_ace[0], FUNC(ns16550_device::dcd_w));
|
||||
serial0.dsr_handler().set(m_ace[0], FUNC(ns16550_device::dsr_w));
|
||||
serial0.ri_handler().set(m_ace[0], FUNC(ns16550_device::ri_w));
|
||||
serial0.rxd_handler().set(m_ace[0], FUNC(ns16550_device::rx_w));
|
||||
|
||||
NS16550(config, m_ace[1], 8_MHz_XTAL);
|
||||
rs232_port_device &serial1(RS232_PORT(config, "serial1", default_rs232_devices, nullptr));
|
||||
|
||||
m_ace[1]->out_dtr_callback().set(serial1, FUNC(rs232_port_device::write_dtr));
|
||||
m_ace[1]->out_rts_callback().set(serial1, FUNC(rs232_port_device::write_rts));
|
||||
m_ace[1]->out_tx_callback().set(serial1, FUNC(rs232_port_device::write_txd));
|
||||
m_ace[1]->out_int_callback().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<9>));
|
||||
|
||||
serial1.cts_handler().set(m_ace[1], FUNC(ns16550_device::cts_w));
|
||||
serial1.dcd_handler().set(m_ace[1], FUNC(ns16550_device::dcd_w));
|
||||
serial1.dsr_handler().set(m_ace[1], FUNC(ns16550_device::dsr_w));
|
||||
serial1.ri_handler().set(m_ace[1], FUNC(ns16550_device::ri_w));
|
||||
serial1.rxd_handler().set(m_ace[1], FUNC(ns16550_device::rx_w));
|
||||
|
||||
PC_LPT(config, m_lpt, 0);
|
||||
m_lpt->irq_handler().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<0>));
|
||||
|
||||
// TODO: sound, interrupt 2, drq 2(l) & 3(r)
|
||||
|
||||
// buzzer
|
||||
SPEAKER(config, "mono").front_center();
|
||||
SPEAKER_SOUND(config, m_buzzer);
|
||||
m_buzzer->add_route(ALL_OUTPUTS, "mono", 0.50);
|
||||
|
||||
DP83932C(config, m_network, 20_MHz_XTAL);
|
||||
m_network->out_int_cb().set(m_mct_adr, FUNC(jazz_mct_adr_device::irq<4>));
|
||||
m_network->set_ram(RAM_TAG);
|
||||
|
||||
I82357(config, m_isp, 14.318181_MHz_XTAL);
|
||||
m_isp->out_rtc_cb().set(m_rtc, FUNC(mc146818_device::write));
|
||||
m_isp->out_int_cb().set_inputline(m_cpu, INPUT_LINE_IRQ2);
|
||||
m_isp->out_nmi_cb().set_inputline(m_cpu, INPUT_LINE_IRQ3);
|
||||
m_isp->out_spkr_cb().set(m_buzzer, FUNC(speaker_sound_device::level_w));
|
||||
|
||||
// TODO: 4 EISA slots
|
||||
}
|
||||
|
||||
void jazz_state::mmr4000be(machine_config &config)
|
||||
{
|
||||
R4000BE(config, m_maincpu, 50_MHz_XTAL);
|
||||
|
||||
jazz(config);
|
||||
|
||||
m_cpu->set_config(r4000_device::CONFIG_BE, r4000_device::CONFIG_BE);
|
||||
}
|
||||
|
||||
void jazz_state::mmr4000le(machine_config &config)
|
||||
{
|
||||
R4000LE(config, m_maincpu, 50_MHz_XTAL);
|
||||
|
||||
jazz(config);
|
||||
|
||||
m_cpu->set_config(0, r4000_device::CONFIG_BE);
|
||||
}
|
||||
|
||||
ROM_START(mmr4000be)
|
||||
ROM_REGION32_BE(0x40000, "flash", 0)
|
||||
ROM_REGION64_BE(0x40000, "flash", 0)
|
||||
ROM_SYSTEM_BIOS(0, "riscos", "R4000 RISC/os PROM")
|
||||
ROMX_LOAD("riscos.bin", 0x00000, 0x40000, CRC(cea6bc8f) SHA1(3e47b4ad5d1a0c7aac649e6aef3df1bf86fc938b), ROM_BIOS(0))
|
||||
ROM_END
|
||||
|
||||
ROM_START(mmr4000le)
|
||||
ROM_REGION32_LE(0x40000, "flash", 0)
|
||||
ROM_REGION64_LE(0x40000, "flash", 0)
|
||||
ROM_SYSTEM_BIOS(0, "ntprom", "R4000 Windows NT PROM")
|
||||
ROMX_LOAD("ntprom.bin", 0x00000, 0x40000, CRC(d91018d7) SHA1(316de17820192c89b8ee6d9936ab8364a739ca53), ROM_BIOS(0))
|
||||
ROM_END
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cpu/mips/mips3.h"
|
||||
#include "cpu/mips/r4000.h"
|
||||
|
||||
// memory
|
||||
#include "machine/ram.h"
|
||||
@ -17,14 +17,21 @@
|
||||
#include "machine/jazz_mct_adr.h"
|
||||
#include "machine/dp83932c.h"
|
||||
#include "machine/mc146818.h"
|
||||
#include "machine/ins8250.h"
|
||||
#include "machine/ncr5390.h"
|
||||
#include "machine/upd765.h"
|
||||
#include "machine/at_keybc.h"
|
||||
#include "machine/pc_lpt.h"
|
||||
#include "machine/i82357.h"
|
||||
|
||||
// video
|
||||
#include "screen.h"
|
||||
#include "video/ims_cvc.h"
|
||||
|
||||
// audio
|
||||
#include "sound/spkrdev.h"
|
||||
#include "speaker.h"
|
||||
|
||||
// busses and connectors
|
||||
#include "machine/nscsi_bus.h"
|
||||
#include "machine/nscsi_cd.h"
|
||||
@ -33,17 +40,20 @@
|
||||
#include "bus/pc_kbd/pc_kbdc.h"
|
||||
#include "bus/pc_kbd/keyboards.h"
|
||||
|
||||
#include "imagedev/floppy.h"
|
||||
#include "formats/pc_dsk.h"
|
||||
|
||||
class jazz_state : public driver_device
|
||||
{
|
||||
public:
|
||||
jazz_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_maincpu(*this, "cpu")
|
||||
, m_cpu(*this, "cpu")
|
||||
, m_ram(*this, "ram")
|
||||
, m_vram(*this, "vram")
|
||||
, m_mct_adr(*this, "mct_adr")
|
||||
, m_scsibus(*this, "scsi")
|
||||
, m_scsi(*this, "scsi:7:host")
|
||||
, m_scsi(*this, "scsi:7:ncr53c94")
|
||||
, m_fdc(*this, "fdc")
|
||||
, m_rtc(*this, "rtc")
|
||||
, m_nvram(*this, "nvram")
|
||||
@ -52,6 +62,10 @@ public:
|
||||
, m_network(*this, "net")
|
||||
, m_screen(*this, "screen")
|
||||
, m_ramdac(*this, "g364")
|
||||
, m_ace(*this, "ace%u", 0)
|
||||
, m_lpt(*this, "lpt")
|
||||
, m_isp(*this, "isp")
|
||||
, m_buzzer(*this, "buzzer")
|
||||
{
|
||||
}
|
||||
|
||||
@ -65,32 +79,35 @@ protected:
|
||||
|
||||
// machine config
|
||||
void jazz(machine_config &config);
|
||||
|
||||
public:
|
||||
void mmr4000be(machine_config &config);
|
||||
void mmr4000le(machine_config &config);
|
||||
|
||||
void init_common();
|
||||
|
||||
DECLARE_FLOPPY_FORMATS(floppy_formats);
|
||||
|
||||
protected:
|
||||
// devices
|
||||
required_device<mips3_device> m_maincpu;
|
||||
required_device<r4000_device> m_cpu;
|
||||
required_device<ram_device> m_ram;
|
||||
required_device<ram_device> m_vram;
|
||||
required_device<jazz_mct_adr_device> m_mct_adr;
|
||||
required_device<nscsi_bus_device> m_scsibus;
|
||||
required_device<ncr5390_device> m_scsi;
|
||||
required_device<ncr53c94_device> m_scsi;
|
||||
required_device<n82077aa_device> m_fdc;
|
||||
required_device<mc146818_device> m_rtc;
|
||||
required_device<nvram_device> m_nvram;
|
||||
required_device<amd_28f020_device> m_flash;
|
||||
required_device<at_keyboard_controller_device> m_kbdc;
|
||||
required_device<ps2_keyboard_controller_device> m_kbdc;
|
||||
required_device<dp83932c_device> m_network;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<g364_device> m_ramdac;
|
||||
|
||||
// helpers
|
||||
u8 led_r() { return m_led; }
|
||||
void led_w(const u8 data) { logerror("led 0x%02x\n", data); m_led = data; }
|
||||
required_device_array<ns16550_device, 2> m_ace;
|
||||
required_device<pc_lpt_device> m_lpt;
|
||||
required_device<i82357_device> m_isp;
|
||||
required_device<speaker_sound_device> m_buzzer;
|
||||
|
||||
private:
|
||||
// machine state
|
||||
|
@ -20,7 +20,10 @@
|
||||
* http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/arch/arc/jazz/
|
||||
*
|
||||
* TODO
|
||||
* - everything (skeleton only)
|
||||
* - proper width dma
|
||||
* - dma address translation errors
|
||||
* - I/O cache
|
||||
* - revision 2 device
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
@ -33,19 +36,271 @@ DEFINE_DEVICE_TYPE(JAZZ_MCT_ADR, jazz_mct_adr_device, "jazz_mct_adr", "Jazz MCT-
|
||||
|
||||
jazz_mct_adr_device::jazz_mct_adr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, JAZZ_MCT_ADR, tag, owner, clock)
|
||||
, m_bus(*this, finder_base::DUMMY_TAG, -1, 64)
|
||||
, m_out_int_dma(*this)
|
||||
, m_out_int_device(*this)
|
||||
, m_out_int_timer(*this)
|
||||
, m_eisa_iack(*this)
|
||||
, m_dma_r{ *this, *this, *this, *this }
|
||||
, m_dma_w{ *this, *this, *this, *this }
|
||||
{
|
||||
}
|
||||
|
||||
void jazz_mct_adr_device::map(address_map &map)
|
||||
{
|
||||
map(0x000, 0x003).lr32("config", [](){ return 0x00000000; });
|
||||
map(0x008, 0x00b).lr32("revision", [](){ return 0xf0000000; });
|
||||
map(0x000, 0x007).lrw32("configuration", [this](){ return m_config; }, [this](u32 data) { m_config = data; });
|
||||
map(0x008, 0x00f).lr32("revision_level", [](){ return 1; });
|
||||
map(0x010, 0x017).lr32("invalid_address", []() { return 0; });
|
||||
map(0x018, 0x01f).lrw32("translation_base", [this]() { return m_trans_tbl_base; }, [this](u32 data) { LOG("tbl base 0x%08x\n", data); m_trans_tbl_base = data; });
|
||||
map(0x020, 0x027).lrw32("translation_limit", [this]() { return m_trans_tbl_limit; }, [this](u32 data) { m_trans_tbl_limit = data; });
|
||||
map(0x028, 0x02f).lrw32("translation_invalidate", []() { return 0; }, [](u32 data) { });
|
||||
map(0x030, 0x037).lw32("cache_maintenance", [this](u32 data) { m_ioc_maint = data; });
|
||||
map(0x038, 0x03f).lr32("remote_failed_address", []() { return 0; });
|
||||
map(0x040, 0x047).lr32("memory_failed_address", []() { return 0; });
|
||||
map(0x048, 0x04f).lw32("io_cache_physical_tag", [this](u32 data) { m_ioc_physical_tag = data; });
|
||||
map(0x050, 0x057).lw32("io_cache_logical_tag", [this](u32 data) { m_ioc_logical_tag = data; });
|
||||
map(0x058, 0x05f).lrw32("io_cache_byte_mask",
|
||||
// FIXME: hack to pass diagnostics
|
||||
[this]()
|
||||
{
|
||||
u32 const data = m_ioc_byte_mask;
|
||||
|
||||
if (data == 0xffffffff)
|
||||
m_ioc_byte_mask = 0;
|
||||
return data;
|
||||
},
|
||||
[this](u32 data) { m_ioc_byte_mask |= data; });
|
||||
map(0x060, 0x067).lw32("io_cache_buffer_window_lo", [this](u32 data)
|
||||
{
|
||||
// FIXME: hack to pass diagnostics
|
||||
if (m_ioc_logical_tag == 0x80000001 && m_ioc_byte_mask == 0x0f0f0f0f)
|
||||
{
|
||||
u32 const address = (m_ioc_physical_tag & ~0x1) + ((m_ioc_maint & 0x3) << 3);
|
||||
|
||||
m_bus->write_dword(address, data);
|
||||
}
|
||||
});
|
||||
// io_cache_buffer_window_hi
|
||||
map(0x070, 0x0ef).lrw32("remote_speed",
|
||||
[this](offs_t offset) { return m_remote_speed[offset >> 1]; },
|
||||
[this](offs_t offset, u32 data) { m_remote_speed[offset >> 1] = data; });
|
||||
// parity_diagnostic_lo
|
||||
// parity_diagnostic_hi
|
||||
map(0x100, 0x1ff).lrw32("dma_reg",
|
||||
[this](offs_t offset) { return m_dma_reg[offset >> 1]; },
|
||||
[this](offs_t offset, u32 data)
|
||||
{
|
||||
unsigned const reg = offset >> 1;
|
||||
|
||||
LOG("dma_reg %d data 0x%08x (%s)\n", offset, data, machine().describe_context());
|
||||
|
||||
m_dma_reg[reg] = data;
|
||||
|
||||
if ((reg == REG_ENABLE) && (data & DMA_ENABLE))
|
||||
LOG("dma started address 0x%08x count %d\n", translate_address(m_dma_reg[(0 << 2) + REG_ADDRESS]), m_dma_reg[(0 << 2) + REG_COUNT]);
|
||||
});
|
||||
map(0x200, 0x207).lr32("interrupt_source", []() { return 0; });
|
||||
map(0x208, 0x20f).lr32("error_type", []() { return 0; });
|
||||
map(0x210, 0x217).lrw32("refresh_rate", [this]() { return m_memory_refresh_rate; }, [this](u32 data) { m_memory_refresh_rate = data; });
|
||||
// refresh_counter
|
||||
map(0x220, 0x227).lrw32("system_security", [this]() { return m_nvram_protect; }, [this](u32 data) { LOG("nvram_protect 0x%08x (%s)\n", data, machine().describe_context()); m_nvram_protect = data; });
|
||||
map(0x228, 0x22f).lw32("interrupt_interval", [this](u32 data)
|
||||
{
|
||||
LOG("timer_w 0x%08x\n", data);
|
||||
|
||||
attotime interval = attotime::from_ticks((data + 1) & 0x1ff, 1000);
|
||||
|
||||
m_interval_timer->adjust(interval, 0, interval);
|
||||
});
|
||||
map(0x230, 0x237).lr32("interval_timer", [this]() { if (m_out_int_timer_asserted) { m_out_int_timer_asserted = false; m_out_int_timer(0); } return 0; });
|
||||
map(0x238, 0x23b).lr32("interrupt_acknowledge", [this]() { return m_eisa_iack(); });
|
||||
}
|
||||
|
||||
void jazz_mct_adr_device::device_start()
|
||||
{
|
||||
m_out_int_dma.resolve();
|
||||
m_out_int_device.resolve();
|
||||
m_out_int_timer.resolve();
|
||||
m_eisa_iack.resolve();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
m_dma_r[i].resolve_safe(0xff);
|
||||
m_dma_w[i].resolve_safe();
|
||||
}
|
||||
|
||||
m_config = 0x104; // REV1, REV2 is 0x410
|
||||
|
||||
m_ioc_maint = 0;
|
||||
m_ioc_physical_tag = 0;
|
||||
m_ioc_logical_tag = 0;
|
||||
m_trans_tbl_base = 0;
|
||||
m_trans_tbl_limit = 0;
|
||||
m_ioc_byte_mask = 0;
|
||||
|
||||
for (u32 &val : m_remote_speed)
|
||||
val = 0x7;
|
||||
|
||||
for (u32 &val : m_dma_reg)
|
||||
val = 0;
|
||||
|
||||
m_memory_refresh_rate = 0x18186;
|
||||
m_nvram_protect = 0x7;
|
||||
|
||||
m_irq_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(jazz_mct_adr_device::irq_check), this));
|
||||
m_dma_check = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(jazz_mct_adr_device::dma_check), this));
|
||||
m_interval_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(jazz_mct_adr_device::interval_timer), this));
|
||||
|
||||
m_out_int_timer_asserted = false;
|
||||
m_out_int_device_asserted = false;
|
||||
}
|
||||
|
||||
void jazz_mct_adr_device::device_reset()
|
||||
{
|
||||
m_isr = 0;
|
||||
m_imr = 0; // 0x10;
|
||||
|
||||
m_interval_timer->adjust(attotime::from_usec(1), 0, attotime::from_usec(1));
|
||||
}
|
||||
|
||||
void jazz_mct_adr_device::set_irq_line(int irq, int state)
|
||||
{
|
||||
if ((irq != 3) && (m_isr & (1 << irq)) ^ (state << irq))
|
||||
LOG("set_irq_line %d state %d m_imr 0x%04x\n", irq, state, m_imr);
|
||||
|
||||
if (state)
|
||||
m_isr |= (1 << irq);
|
||||
else
|
||||
m_isr &= ~(1 << irq);
|
||||
|
||||
m_irq_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(jazz_mct_adr_device::irq_check)
|
||||
{
|
||||
if (bool(m_isr & m_imr) != m_out_int_device_asserted)
|
||||
{
|
||||
m_out_int_device_asserted = bool(m_isr & m_imr);
|
||||
|
||||
m_out_int_device(m_out_int_device_asserted ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
u16 jazz_mct_adr_device::isr_r()
|
||||
{
|
||||
u16 const pending = m_isr & m_imr;
|
||||
|
||||
// FIXME: really?
|
||||
//m_out_int_device(CLEAR_LINE);
|
||||
|
||||
for (u16 irq = 0; irq < 16; irq++)
|
||||
if (BIT(pending, irq))
|
||||
return (irq + 1) << 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void jazz_mct_adr_device::imr_w(u16 data)
|
||||
{
|
||||
LOG("imr_w 0x%04x (%s)\n", data, machine().describe_context());
|
||||
|
||||
m_imr = data;
|
||||
|
||||
m_irq_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(jazz_mct_adr_device::interval_timer)
|
||||
{
|
||||
//m_out_int_timer(CLEAR_LINE);
|
||||
if (!m_out_int_timer_asserted)
|
||||
{
|
||||
m_out_int_timer_asserted = true;
|
||||
m_out_int_timer(1);
|
||||
}
|
||||
}
|
||||
|
||||
void jazz_mct_adr_device::set_drq_line(int channel, int state)
|
||||
{
|
||||
m_drq_active[channel] = state == ASSERT_LINE;
|
||||
|
||||
if (state)
|
||||
m_dma_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(jazz_mct_adr_device::dma_check)
|
||||
{
|
||||
bool active = false;
|
||||
|
||||
for (int channel = 0; channel < 4; channel++)
|
||||
{
|
||||
if (!m_drq_active[channel])
|
||||
continue;
|
||||
|
||||
// reg 0x00: 0x00000011 - mode (ch0) (WIDTH16 | ATIME_80)
|
||||
// reg 0x20: 0x0000000a - mode (ch1) (WIDTH8 | ATIME_120)
|
||||
// reg 0x18: 0x00000f20 - address
|
||||
// reg 0x10: 0x00000024 - count
|
||||
// reg 0x08: 0x00000001 - enable (ENABLE | !WRITE)
|
||||
|
||||
// check channel enabled
|
||||
if (!(m_dma_reg[(channel << 2) + REG_ENABLE] & DMA_ENABLE))
|
||||
return;
|
||||
|
||||
// check transfer count
|
||||
if (!m_dma_reg[(channel << 2) + REG_COUNT])
|
||||
return;
|
||||
|
||||
u32 const address = translate_address(m_dma_reg[(channel << 2) + REG_ADDRESS]);
|
||||
|
||||
// perform dma transfer
|
||||
if (m_dma_reg[(channel << 2) + REG_ENABLE] & DMA_DIRECTION)
|
||||
{
|
||||
u8 const data = m_bus->read_byte(address);
|
||||
|
||||
//LOG("dma_w data 0x%02x address 0x%08x\n", data, m_dma_reg[(number << 2) + 3]);
|
||||
|
||||
m_dma_w[channel](data);
|
||||
}
|
||||
else
|
||||
{
|
||||
u8 const data = m_dma_r[channel]();
|
||||
|
||||
//LOG("dma_r data 0x%02x address 0x%08x\n", data, m_dma_reg[(number << 2) + 3]);
|
||||
|
||||
m_bus->write_byte(address, data);
|
||||
}
|
||||
|
||||
// increment address, decrement count
|
||||
m_dma_reg[(channel << 2) + REG_ADDRESS]++;
|
||||
m_dma_reg[(channel << 2) + REG_COUNT]--;
|
||||
|
||||
// set terminal count flag
|
||||
if (!m_dma_reg[(channel << 2) + REG_COUNT])
|
||||
{
|
||||
m_dma_reg[(channel << 2) + REG_ENABLE] |= DMA_TERMINAL_COUNT;
|
||||
|
||||
// TODO: dma interrupts
|
||||
if (m_dma_reg[(channel << 2) + REG_ENABLE] & DMA_INTERRUPT_ENABLE)
|
||||
logerror("dma interrupt enable - interrupt expected\n");
|
||||
}
|
||||
|
||||
if (m_drq_active[channel])
|
||||
active = true;
|
||||
}
|
||||
|
||||
if (active)
|
||||
m_dma_check->adjust(attotime::zero);
|
||||
}
|
||||
|
||||
u32 jazz_mct_adr_device::translate_address(u32 logical_address)
|
||||
{
|
||||
u32 page = logical_address >> 12;
|
||||
if (page < (m_trans_tbl_limit) >> 3)
|
||||
{
|
||||
u32 entry_address = (m_trans_tbl_base & 0x7fffffff) + page * 8;
|
||||
|
||||
return m_bus->read_dword(entry_address) | (logical_address & 0xfff);
|
||||
}
|
||||
else
|
||||
return 0; // FIXME: address error
|
||||
}
|
||||
|
@ -11,12 +11,137 @@ class jazz_mct_adr_device : public device_t
|
||||
public:
|
||||
jazz_mct_adr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// configuration
|
||||
template <typename T> void set_bus(T &&tag, int spacenum) { m_bus.set_tag(std::forward<T>(tag), spacenum); }
|
||||
|
||||
auto out_int_dma_cb() { return m_out_int_dma.bind(); }
|
||||
auto out_int_device_cb() { return m_out_int_device.bind(); }
|
||||
auto out_int_timer_cb() { return m_out_int_timer.bind(); }
|
||||
auto eisa_iack_cb() { return m_eisa_iack.bind(); }
|
||||
|
||||
template <unsigned DMA> auto dma_r_cb() { return m_dma_r[DMA].bind(); }
|
||||
template <unsigned DMA> auto dma_w_cb() { return m_dma_w[DMA].bind(); }
|
||||
|
||||
template <unsigned IRQ> DECLARE_WRITE_LINE_MEMBER(irq) { set_irq_line(IRQ, state); }
|
||||
template <unsigned DRQ> DECLARE_WRITE_LINE_MEMBER(drq) { set_drq_line(DRQ, state); }
|
||||
|
||||
virtual void map(address_map &map);
|
||||
|
||||
u16 isr_r();
|
||||
u16 imr_r() { return m_imr; }
|
||||
void imr_w(u16 data);
|
||||
|
||||
protected:
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
private:
|
||||
void set_irq_line(int number, int state);
|
||||
void set_drq_line(int channel, int state);
|
||||
|
||||
TIMER_CALLBACK_MEMBER(irq_check);
|
||||
TIMER_CALLBACK_MEMBER(dma_check);
|
||||
TIMER_CALLBACK_MEMBER(interval_timer);
|
||||
|
||||
u32 translate_address(u32 logical_address);
|
||||
|
||||
required_address_space m_bus;
|
||||
|
||||
devcb_write_line m_out_int_dma;
|
||||
devcb_write_line m_out_int_device;
|
||||
devcb_write_line m_out_int_timer;
|
||||
devcb_read32 m_eisa_iack;
|
||||
|
||||
devcb_read8 m_dma_r[4];
|
||||
devcb_write8 m_dma_w[4];
|
||||
bool m_drq_active[4];
|
||||
|
||||
emu_timer *m_irq_check;
|
||||
emu_timer *m_dma_check;
|
||||
emu_timer *m_interval_timer;
|
||||
|
||||
enum isr_mask : u16
|
||||
{
|
||||
ISR_PRINTER = 0x0001,
|
||||
ISR_FLOPPY = 0x0002,
|
||||
ISR_SOUND = 0x0004,
|
||||
ISR_VIDEO = 0x0008,
|
||||
ISR_NETWORK = 0x0010,
|
||||
ISR_SCSI = 0x0020,
|
||||
ISR_KEYBOARD = 0x0040,
|
||||
ISR_MOUSE = 0x0080,
|
||||
ISR_SERIAL0 = 0x0100,
|
||||
ISR_SERIAL1 = 0x0200,
|
||||
};
|
||||
u16 m_isr; // local bus interrupt source
|
||||
u16 m_imr; // local bus interrupt mask
|
||||
|
||||
u32 m_config;
|
||||
|
||||
enum dma_register : unsigned
|
||||
{
|
||||
REG_MODE = 0,
|
||||
REG_ENABLE = 1,
|
||||
REG_COUNT = 2,
|
||||
REG_ADDRESS = 3,
|
||||
};
|
||||
enum dma_mode_mask : u32
|
||||
{
|
||||
DMA_ACCESS_TIME = 0x00000007,
|
||||
DMA_TRANSFER_WIDTH = 0x00000018,
|
||||
DMA_INTERRUPT_ENABLE = 0x00000020,
|
||||
DMA_BURST_MODE = 0x00000040,
|
||||
DMA_FAST_DMA_CYCLE = 0x00000080,
|
||||
};
|
||||
enum dma_access_time : u32
|
||||
{
|
||||
ACCESS_40NS = 0x00,
|
||||
ACCESS_80NS = 0x01,
|
||||
ACCESS_120NS = 0x02,
|
||||
ACCESS_160NS = 0x03,
|
||||
ACCESS_200NS = 0x04,
|
||||
ACCESS_240NS = 0x05,
|
||||
ACCESS_280NS = 0x06,
|
||||
ACCESS_320NS = 0x07,
|
||||
};
|
||||
enum dma_transfer_width : u32
|
||||
{
|
||||
WIDTH_8BITS = 0x08,
|
||||
WIDTH_16BITS = 0x10,
|
||||
WIDTH_32BITS = 0x18,
|
||||
};
|
||||
enum dma_enable_mask : u32
|
||||
{
|
||||
DMA_ENABLE = 0x00000001,
|
||||
DMA_DIRECTION = 0x00000002, // 1 == write to device
|
||||
DMA_TERMINAL_COUNT = 0x00000100,
|
||||
DMA_MEMORY_ERROR = 0x00000200,
|
||||
DMA_TRANSLATION_ERROR = 0x00000400,
|
||||
};
|
||||
enum dma_interrupt_source : u32
|
||||
{
|
||||
DMA_INTERRUPT_PENDING = 0x000000ff,
|
||||
DMA_PARITY_ERROR = 0x00000100,
|
||||
DMA_ADDRESS_ERROR = 0000000200,
|
||||
DMA_CACHE_FLUSH_ERROR = 0x00000400,
|
||||
};
|
||||
|
||||
u32 m_trans_tbl_base;
|
||||
u32 m_trans_tbl_limit;
|
||||
u32 m_ioc_maint;
|
||||
u32 m_ioc_physical_tag;
|
||||
u32 m_ioc_logical_tag;
|
||||
u32 m_ioc_byte_mask;
|
||||
u32 m_remote_speed[16];
|
||||
u32 m_dma_reg[32];
|
||||
u32 m_memory_refresh_rate;
|
||||
u32 m_nvram_protect;
|
||||
|
||||
u32 m_dma_address[4];
|
||||
|
||||
bool m_out_int_timer_asserted;
|
||||
bool m_out_int_device_asserted;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
Loading…
Reference in New Issue
Block a user