fs3216: First draft of MMU (nw)

This commit is contained in:
AJR 2019-01-10 23:06:24 -05:00
parent 43e33bd7c5
commit 493ef59653

View File

@ -48,11 +48,13 @@ protected:
private:
MC6845_UPDATE_ROW(crt_update_row);
void mmu_reg_w(offs_t offset, u16 data);
DECLARE_READ16_MEMBER(mmu_read);
DECLARE_WRITE16_MEMBER(mmu_write);
DECLARE_WRITE_LINE_MEMBER(mmu_reset_w);
void mmu_init_w(u16 data);
u16 irq_r();
IRQ_CALLBACK_MEMBER(intack);
DECLARE_READ8_MEMBER(ctc_r);
@ -80,10 +82,10 @@ private:
required_shared_ptr<u16> m_videoram;
required_region_ptr<u8> m_chargen;
u32 m_mmu_reg[4];
std::unique_ptr<u8[]> m_fdc_ram;
bool m_in_reset;
bool m_mmu_init;
bool m_from_reset;
};
@ -92,14 +94,15 @@ void fs3216_state::machine_start()
m_fdc_ram = make_unique_clear<u8[]>(0x400);
save_pointer(NAME(m_fdc_ram), 0x400);
save_item(NAME(m_in_reset));
save_item(NAME(m_mmu_init));
std::fill(std::begin(m_mmu_reg), std::end(m_mmu_reg), 0);
save_item(NAME(m_mmu_reg));
save_item(NAME(m_from_reset));
}
void fs3216_state::machine_reset()
{
m_in_reset = true;
m_mmu_init = false;
m_from_reset = true;
// FIXME: fix the 68000 so that it doesn't read vectors during device_reset
m_maincpu->reset();
@ -126,46 +129,63 @@ MC6845_UPDATE_ROW(fs3216_state::crt_update_row)
}
void fs3216_state::mmu_reg_w(offs_t offset, u16 data)
{
// 3x SN74LS374N for each of the four spaces
u32 &reg = m_mmu_reg[offset >> 1];
if (BIT(offset, 0))
reg = (reg & 0xff0000) | data;
else
reg = (reg & 0x00ffff) | (data & 0x00ff) << 16;
}
READ16_MEMBER(fs3216_state::mmu_read)
{
if (m_in_reset)
const bool a23 = BIT(offset, 22);
const bool mmu_disable = !a23 /*&& BIT(m_maincpu->get_fc(), 2)*/;
const u32 mmu_reg = mmu_disable ? (m_from_reset ? 0xfffe00 : 0xfff000) : m_mmu_reg[(offset >> 20) & 3];
if (!mmu_disable && !machine().side_effects_disabled())
{
if (m_mmu_init && !BIT(offset, 22) && !machine().side_effects_disabled())
m_in_reset = false;
else
offset = (offset & 0x03ffff) | 0x1c0000;
// TODO: do limit check and cause BERR on failure
}
// TODO: MMU segments
return m_clb->read16(space, offset & 0x1fffff, mem_mask);
offs_t clbaddr = offset + ((mmu_reg & 0x000fff) << 9);
clbaddr = (clbaddr & 0x1fffff) | (clbaddr & 0x100000) << 1;
return m_clb->read16(space, clbaddr, mem_mask);
}
WRITE16_MEMBER(fs3216_state::mmu_write)
{
if (m_in_reset)
const bool a23 = BIT(offset, 22);
const bool mmu_disable = !a23 /*&& BIT(m_maincpu->get_fc(), 2)*/;
const u32 mmu_reg = mmu_disable ? (m_from_reset ? 0xfffe00 : 0xfff000) : m_mmu_reg[(offset >> 20) & 3];
if (!mmu_disable && !machine().side_effects_disabled())
{
if (m_mmu_init && !BIT(offset, 22) && !machine().side_effects_disabled())
m_in_reset = false;
else
offset = (offset & 0x03ffff) | 0x1c0000;
// TODO: do limit/write protect check and cause BERR on failure
}
// TODO: MMU segments
m_clb->write16(space, offset & 0x1fffff, data, mem_mask);
offs_t clbaddr = offset + ((mmu_reg & 0x000fff) << 9);
clbaddr = (clbaddr & 0x1fffff) | (clbaddr & 0x100000) << 1;
m_clb->write16(space, clbaddr, data, mem_mask);
}
WRITE_LINE_MEMBER(fs3216_state::mmu_reset_w)
{
if (state)
{
m_in_reset = true;
m_mmu_init = false;
}
m_from_reset = true;
}
void fs3216_state::mmu_init_w(u16 data)
{
m_mmu_init = true;
m_from_reset = BIT(data, 0);
}
u16 fs3216_state::irq_r()
{
// TODO
return 0xfff8;
}
IRQ_CALLBACK_MEMBER(fs3216_state::intack)
@ -237,28 +257,30 @@ void fs3216_state::main_map(address_map &map)
void fs3216_state::clb_map(address_map &map)
{
map(0x000000, 0x017fff).ram();
map(0x380000, 0x383fff).rom().region("momrom", 0);
map(0x392000, 0x392003).m(m_fdc, FUNC(upd765a_device::map)).umask16(0x00ff);
map(0x392041, 0x392041).w(FUNC(fs3216_state::floppy_select_w));
map(0x392051, 0x392051).r(FUNC(fs3216_state::floppy_status_r));
map(0x394680, 0x39468f).rw(FUNC(fs3216_state::ctc_r), FUNC(fs3216_state::ctc_w)).umask16(0x00ff);
map(0x394701, 0x394701).rw("dart", FUNC(z80dart_device::da_r), FUNC(z80dart_device::da_w));
map(0x394709, 0x394709).rw("dart", FUNC(z80dart_device::ca_r), FUNC(z80dart_device::ca_w));
map(0x394711, 0x394711).rw("dart", FUNC(z80dart_device::db_r), FUNC(z80dart_device::db_w));
map(0x394719, 0x394719).rw("dart", FUNC(z80dart_device::cb_r), FUNC(z80dart_device::cb_w));
map(0x3a0000, 0x3a1fff).rom().region("video", 0);
map(0x3a4001, 0x3a4001).w("crtc", FUNC(mc6845_device::address_w));
map(0x3a4003, 0x3a4003).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x3a8000, 0x3a8fff).ram().share("videoram"); // 2x M58725P
map(0x3b0000, 0x3b1fff).rom().region("comm_a", 0);
map(0x3c0000, 0x3c1fff).rom().region("comm_b", 0);
//map(0x3e0000, 0x3e1fff).rom().region("wd1001_clb", 0);
map(0x3f5000, 0x3f5001).w(FUNC(fs3216_state::mmu_init_w));
map(0x3f6000, 0x3f6001).w(FUNC(fs3216_state::fdc_reset_w));
map(0x3f6800, 0x3f6fff).rw(FUNC(fs3216_state::fdc_ram_r), FUNC(fs3216_state::fdc_ram_w)).umask16(0x00ff);
map(0x3f7000, 0x3f7001).r(FUNC(fs3216_state::earom_store_r));
map(0x3f7200, 0x3f7201).r(FUNC(fs3216_state::earom_recall_r));
map(0x3f7400, 0x3f75ff).rw(m_earom, FUNC(x2212_device::read), FUNC(x2212_device::write)).umask16(0x00ff);
map(0x780000, 0x783fff).rom().region("momrom", 0);
map(0x792000, 0x792003).m(m_fdc, FUNC(upd765a_device::map)).umask16(0x00ff);
map(0x792041, 0x792041).w(FUNC(fs3216_state::floppy_select_w));
map(0x792051, 0x792051).r(FUNC(fs3216_state::floppy_status_r));
map(0x794680, 0x79468f).rw(FUNC(fs3216_state::ctc_r), FUNC(fs3216_state::ctc_w)).umask16(0x00ff);
map(0x794701, 0x794701).rw("dart", FUNC(z80dart_device::da_r), FUNC(z80dart_device::da_w));
map(0x794709, 0x794709).rw("dart", FUNC(z80dart_device::ca_r), FUNC(z80dart_device::ca_w));
map(0x794711, 0x794711).rw("dart", FUNC(z80dart_device::db_r), FUNC(z80dart_device::db_w));
map(0x794719, 0x794719).rw("dart", FUNC(z80dart_device::cb_r), FUNC(z80dart_device::cb_w));
map(0x7a0000, 0x7a1fff).rom().region("video", 0);
map(0x7a4001, 0x7a4001).w("crtc", FUNC(mc6845_device::address_w));
map(0x7a4003, 0x7a4003).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w));
map(0x7a8000, 0x7a8fff).ram().share("videoram"); // 2x M58725P
map(0x7b0000, 0x7b1fff).rom().region("comm_a", 0);
map(0x7c0000, 0x7c1fff).rom().region("comm_b", 0);
//map(0x7e0000, 0x7e1fff).rom().region("wd1001_clb", 0);
map(0x7f1000, 0x7f1001).r(FUNC(fs3216_state::irq_r));
map(0x7f3000, 0x7f300f).w(FUNC(fs3216_state::mmu_reg_w));
map(0x7f5000, 0x7f5001).w(FUNC(fs3216_state::mmu_init_w));
map(0x7f6000, 0x7f6001).w(FUNC(fs3216_state::fdc_reset_w));
map(0x7f6800, 0x7f6fff).rw(FUNC(fs3216_state::fdc_ram_r), FUNC(fs3216_state::fdc_ram_w)).umask16(0x00ff);
map(0x7f7000, 0x7f7001).r(FUNC(fs3216_state::earom_store_r));
map(0x7f7200, 0x7f7201).r(FUNC(fs3216_state::earom_recall_r));
map(0x7f7400, 0x7f75ff).rw(m_earom, FUNC(x2212_device::read), FUNC(x2212_device::write)).umask16(0x00ff);
}
void fs3216_state::wdcpu_prog_map(address_map &map)
@ -291,6 +313,8 @@ void fs3216_state::fs3216(machine_config &config)
m_ctc->zc_callback<0>().set("dart", FUNC(z80dart_device::rxca_w));
m_ctc->zc_callback<0>().append("dart", FUNC(z80dart_device::txca_w));
m_ctc->zc_callback<1>().set("dart", FUNC(z80dart_device::rxtxcb_w));
m_ctc->zc_callback<1>().append(m_ctc, FUNC(z80ctc_device::trg2));
m_ctc->zc_callback<2>().set(m_ctc, FUNC(z80ctc_device::trg3));
Z80DART(config, "dart", 44.2368_MHz_XTAL / 8); // Z8470BPS
@ -322,7 +346,7 @@ INPUT_PORTS_END
// XTALs on Comm A board (1000014-01 2 Port / 1000171-01 4 Port Rev. 7; 10000065-01 Rev. 3): two K1135CM Dual Baud Rate Generators (7D, 8D)
// XTALs on Comm B board (1001651-01 Rev. G): none
// XTALs on Video Controller board (1000443-1 Rev. I): 14.580 MHz (1H)
// XTALs on WD-1001 CLB Disk Controller board (1473-008): 20.000 (Y1), 8.00? [somewhat defaced] (Y2)
// XTALs on WD-1001 CLB Disk Controller board (1473-008): 20.000 (Y1), 8.000 (Y2)
ROM_START(fs3216)
ROM_REGION16_BE(0x4000, "momrom", 0)
ROM_LOAD16_BYTE("17k_1260-02_h.bin", 0x0000, 0x2000, CRC(75ed6de8) SHA1(0360548493b778995ae436da475b6356945e1872))