From ab1a064e2914bac8b3f14b353a68b36f3a9251f5 Mon Sep 17 00:00:00 2001 From: Curt Coder Date: Mon, 15 Oct 2012 14:03:10 +0000 Subject: [PATCH] (MESS) c128: MMU fixes. (nw) --- src/mess/machine/mos8722.c | 294 +++++++++++++++++++++---------------- src/mess/machine/mos8722.h | 6 +- 2 files changed, 171 insertions(+), 129 deletions(-) diff --git a/src/mess/machine/mos8722.c b/src/mess/machine/mos8722.c index 3df9842c1d9..95ec3c41282 100644 --- a/src/mess/machine/mos8722.c +++ b/src/mess/machine/mos8722.c @@ -55,7 +55,7 @@ enum #define CR_ROM_LO BIT(m_reg[CR], 1) #define CR_ROM_MID ((m_reg[CR] >> 2) & 0x03) #define CR_ROM_HI ((m_reg[CR] >> 4) & 0x03) -#define CR_RAM ((m_reg[CR] >> 6) & 0x03) +#define CR_A16 BIT(m_reg[CR], 6) // mode configuration register @@ -161,13 +161,15 @@ void mos8722_device::device_start() void mos8722_device::device_reset() { - for (int i = 0; i < 12; i++) + for (int i = 0; i < 16; i++) { m_reg[i] = 0; } - m_p0l_written = false; - m_p1l_written = false; + m_reg[P1L] = 0x01; + + m_p0h_latch = 0; + m_p1h_latch = 0; m_out_z80en_func(MCR_8500); m_out_fsdir_func(MCR_FSDIR); @@ -180,32 +182,44 @@ void mos8722_device::device_reset() UINT8 mos8722_device::read(offs_t offset, UINT8 data) { - if (!MCR_C64) + if (MCR_C64) return data; + + if (!CR_IO && offset >= 0xd500 && offset < 0xd50c) { - if (!CR_IO && offset >= 0xd500 && offset < 0xd50c) + switch (offset & 0x0f) { - switch (offset & 0x0f) - { - case MCR: - data = m_reg[MCR] & 0x49; + case CR: + data = m_reg[CR] | 0x80; + break; - data |= m_in_game_func() << 4; - data |= m_in_exrom_func() << 5; - data |= m_in_sense40_func() << 7; - break; + case MCR: + data = m_reg[MCR] | 0x06; - case VR: - data = 0x20; - break; + data &= ((m_in_game_func() << 4) | ~0x10); + data &= ((m_in_exrom_func() << 5) | ~0x20); + data &= ((m_in_sense40_func() << 7) | ~0x80); + break; - default: - data = m_reg[offset & 0x0f]; - break; - } + case VR: + data = 0x20; + break; + + default: + data = m_reg[offset & 0x0f]; + break; } - else if (offset == 0xff00) + } + else if (offset >= 0xff00 && offset < 0xff05) + { + switch (offset & 0x0f) { - return m_reg[CR]; + case CR: + data = m_reg[CR] | 0x80; + break; + + default: + data = m_reg[offset & 0x0f]; + break; } } @@ -219,52 +233,76 @@ UINT8 mos8722_device::read(offs_t offset, UINT8 data) WRITE8_MEMBER( mos8722_device::write ) { - if (!MCR_C64) + if (MCR_C64) return; + + if (!CR_IO && offset >= 0xd500 && offset < 0xd50c) { - if (!CR_IO && offset >= 0xd500 && offset < 0xd50c) + if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data); + + switch (offset & 0x0f) { - if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data); + case CR: + m_reg[CR] = data & 0x7f; + break; - m_reg[offset & 0x0f] = data; + case PCRA: + case PCRB: + case PCRC: + case PCRD: + m_reg[offset & 0x0f] = data & 0x7f; + break; - switch (offset & 0x0f) - { - case MCR: - m_out_z80en_func(MCR_8500); - m_out_fsdir_func(MCR_FSDIR); - break; + case MCR: + { + int _8500 = MCR_8500; + int fsdir = MCR_FSDIR; - case P0L: - m_p0l_written = true; - break; - - case P0H: - m_p0l_written = false; - break; - - case P1L: - m_p1l_written = true; - break; - - case P1H: - m_p1l_written = false; - break; - } + m_reg[MCR] = data; + + if (_8500 != MCR_8500) m_out_z80en_func(MCR_8500); + if (fsdir != MCR_FSDIR) m_out_fsdir_func(MCR_FSDIR); + break; } - else if (offset >= 0xff00 && offset < 0xff05) + + case RCR: + m_reg[RCR] = data & 0x4f; + break; + + case P0L: + m_reg[P0L] = data; + m_reg[P0H] = m_p0h_latch; + break; + + case P0H: + m_p0h_latch = data & 0x01; + break; + + case P1L: + m_reg[P1L] = data; + m_reg[P1H] = m_p1h_latch; + break; + + case P1H: + m_p1h_latch = data & 0x01; + break; + + default: + m_reg[offset & 0x0f] = data; + } + } + else if (offset >= 0xff00 && offset < 0xff05) + { + if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data); + + switch (offset & 0x0f) { - if (LOG) logerror("MOS8722 '%s' Write %01x : %02x\n", tag(), offset & 0x0f, data); + case CR: + m_reg[CR] = data & 0x7f; + break; - switch (offset & 0x0f) - { - case CR: - m_reg[CR] = data; - break; - - default: - m_reg[CR] = m_reg[offset & 0x0f]; - break; - } + default: + m_reg[CR] = m_reg[offset & 0x0f]; + break; } } } @@ -286,100 +324,104 @@ READ_LINE_MEMBER( mos8722_device::fsdir_r ) offs_t mos8722_device::ta_r(offs_t offset, int aec, int *ms0, int *ms1, int *ms2, int *ms3, int *cas0, int *cas1) { - offs_t ta = offset & 0xff00; + offs_t ta; - if (!aec) + *ms0 = 1; + *ms1 = 1; + *ms2 = CR_IO; + *ms3 = !MCR_C64; + + if (aec) { - ta = 0xf000 | (offset & 0xf00); - } + // CPU access + ta = offset & 0xff00; - if (!MCR_C64) - { - *ms0 = 1; - *ms1 = 1; - *ms2 = CR_IO; + *cas0 = CR_A16; + *cas1 = !*cas0; - if (offset < 0x1000 && !MCR_8500) + if (!MCR_C64) { - ta = 0xd000 | (offset & 0xf00); - - *ms0 = 0; - *ms1 = 0; - } - else if (offset >= 0x4000 && offset < 0x8000) - { - *ms0 = CR_ROM_LO; - *ms1 = CR_ROM_LO; - } - else if (offset >= 0x8000 && offset < 0xc000) - { - *ms0 = BIT(CR_ROM_MID, 0); - *ms1 = BIT(CR_ROM_MID, 1); - } - else if (offset >= 0xc000) - { - *ms0 = BIT(CR_ROM_HI, 0); - *ms1 = BIT(CR_ROM_HI, 1); - } - - if (*ms0 == 1 && *ms1 == 1) - { - if (aec) + if (offset >= 0xff00 && offset < 0xff05) { - *cas0 = BIT(CR_RAM, 0); - *cas1 = BIT(CR_RAM, 1); + // MMU registers + *cas0 = 1; + *cas1 = 1; + } + else if (!MCR_8500 && !CR_A16 && offset < 0x1000) + { + // Z80 ROM + ta = 0xd000 | (offset & 0xf00); + *ms0 = 0; + *ms1 = 0; + } + else + { if (offset < 0x0100) { - if (m_p0l_written && m_reg[P0L]) - { - ta = m_reg[P0L] << 8; + // page 0 pointer + ta = m_reg[P0L] << 8; - *cas0 = P0H_A16 ? 1 : 0; - *cas1 = P0H_A16 ? 0 : 1; - } + *cas0 = P0H_A16; + *cas1 = !*cas0; } else if (offset < 0x0200) { - if (m_p1l_written && m_reg[P1L]) - { - ta = m_reg[P1L] << 8; + // page 1 pointer + ta = m_reg[P1L] << 8; - *cas0 = P1H_A16 ? 1 : 0; - *cas1 = P1H_A16 ? 0 : 1; + *cas0 = P1H_A16; + *cas1 = !*cas0; + } + else if (offset >= 0x4000 && offset < 0x8000) + { + // low ROM + *ms0 = CR_ROM_LO; + *ms1 = CR_ROM_LO; + } + else if (offset >= 0x8000 && offset < 0xc000) + { + // middle ROM + *ms0 = BIT(CR_ROM_MID, 0); + *ms1 = BIT(CR_ROM_MID, 1); + } + else if (offset >= 0xc000) + { + // high ROM + *ms0 = BIT(CR_ROM_HI, 0); + *ms1 = BIT(CR_ROM_HI, 1); + } + + if (*ms0 && *ms1) + { + if ((offset >> 8) == m_reg[P0L]) + { + ta = 0x0000; + } + else if ((offset >> 8) == m_reg[P1L]) + { + ta = 0x0100; } } if ((RCR_BOTTOM && offset < RCR_BOTTOM_ADDRESS[RCR_SHARE]) || (RCR_TOP && offset >= RCR_TOP_ADDRESS[RCR_SHARE])) { + // RAM sharing *cas0 = 0; - *cas1 = 1; + *cas1 = !*cas0; } } - else - { - *cas0 = RCR_VA16 ? 1 : 0; - *cas1 = RCR_VA16 ? 0 : 1; - } - } - else - { - *cas0 = 1; - *cas1 = 1; } } else { - *ms0 = 1; - *ms1 = 1; - *ms2 = 1; + // VIC access + ta = 0xf000 | (offset & 0xf00); - *cas0 = 0; - *cas1 = 1; + *cas0 = RCR_VA16; + *cas1 = !*cas0; } - *ms3 = !MCR_C64; - return ta; } diff --git a/src/mess/machine/mos8722.h b/src/mess/machine/mos8722.h index 743b453b616..ee7cdf98d4b 100644 --- a/src/mess/machine/mos8722.h +++ b/src/mess/machine/mos8722.h @@ -102,10 +102,10 @@ private: devcb_resolved_read_line m_in_exrom_func; devcb_resolved_read_line m_in_sense40_func; - UINT8 m_reg[12]; + UINT8 m_reg[16]; - bool m_p0l_written; - bool m_p1l_written; + UINT8 m_p0h_latch; + UINT8 m_p1h_latch; };