From 3fa50193f6b1e9adfd5b23ecf864ef7349d18b48 Mon Sep 17 00:00:00 2001 From: arbee Date: Mon, 22 May 2023 21:30:36 -0400 Subject: video/atirage.cpp: Fixed Coverity bug, finished and tested GPIO implementation, cleanup. [R. Belmont] apple/imacg3.cpp: Use extracted EDID from the internal monitor, resolution is now set correctly. [R. Belmont, edid.tv] --- src/devices/video/atirage.cpp | 35 +++++++++++++++++++---------------- src/devices/video/atirage.h | 7 +++++-- src/mame/apple/imacg3.cpp | 33 ++++++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/devices/video/atirage.cpp b/src/devices/video/atirage.cpp index ff481f736ef..10048a38a27 100644 --- a/src/devices/video/atirage.cpp +++ b/src/devices/video/atirage.cpp @@ -4,7 +4,7 @@ ATI Rage PCI/AGP SVGA This implementation targets the mach64 VT and 3D Rage chips. Rage 128 has similar registers - but they're mapped differently. + but they're mapped differently. mach64 VT = mach64 with video decoding. Uses a Rage-compatible register layout, as opposed to earlier mach64. mach64 GT = Rage I (mach64 acceleration and VGA with 3D polygons and MPEG-1 decode) @@ -29,7 +29,6 @@ #include "screen.h" #include "atirage.h" -#define LOG_GENERAL (1U << 0) #define LOG_REGISTERS (1U << 1) #define LOG_CRTC (1U << 2) #define LOG_DAC (1U << 3) @@ -267,18 +266,6 @@ u8 atirage_device::regs_0_read(offs_t offset) case CLOCK_CNTL + 2: return m_pll_regs[(m_regs0[CLOCK_CNTL+1] >> 2) & 0xf] << 16; - - case GP_IO: // monitor sense - either 3-line Apple or EDID - return read_gpio() & 0xff; - - case GP_IO + 1: - return (read_gpio() & 0xff00) >> 8; - - case GP_IO + 2: - return (read_gpio() & 0xff0000) >> 16; - - case GP_IO + 3: - return read_gpio() >> 24; } return m_regs0[offset]; @@ -336,7 +323,7 @@ void atirage_device::regs_0_write(offs_t offset, u8 data) case CRTC_DAC_BASE + 3: m_dac_state = 0; - m_dac_rindex = data >> 24; + m_dac_rindex = data; break; case CRTC_OFF_PITCH: @@ -356,7 +343,23 @@ void atirage_device::regs_0_write(offs_t offset, u8 data) case GP_IO + 1: case GP_IO + 2: case GP_IO + 3: - write_gpio(*(u32 *)&m_regs0[GP_IO]); + { + u16 old_data = *(u16 *)&m_regs0[GP_IO]; + const u16 ddr = *(u16 *)&m_regs0[GP_IO+2]; + + old_data &= ddr; // 0 bits are input + + // send the data to an external handler + // AND the pullups by the inverse of DDR, so bits set to input get the pullup + write_gpio(old_data | (m_gpio_pullups & (ddr ^ 0xffff))); + + // get the updated data from the port + u16 new_data = read_gpio(); + new_data &= (ddr ^ 0xffff); // AND against inverted DDR mask so 0 bits are output + new_data |= old_data; + m_regs0[GP_IO] = (new_data & 0xff); + m_regs0[GP_IO + 1] = (new_data >> 8) & 0xff; + } break; } } diff --git a/src/devices/video/atirage.h b/src/devices/video/atirage.h index 54bb6d50b40..464d0de41ef 100644 --- a/src/devices/video/atirage.h +++ b/src/devices/video/atirage.h @@ -21,6 +21,8 @@ public: auto gpio_get_cb() { return read_gpio.bind(); } auto gpio_set_cb() { return write_gpio.bind(); } + void set_gpio_pullups(u16 pullups) { m_gpio_pullups = pullups; } + protected: virtual void device_start() override; virtual void device_add_mconfig(machine_config &config) override; @@ -38,14 +40,15 @@ protected: uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); private: - devcb_read32 read_gpio; - devcb_write32 write_gpio; + devcb_read16 read_gpio; + devcb_write16 write_gpio; u32 m_user_cfg; u32 m_hres, m_vres, m_htotal, m_vtotal, m_format, m_pixel_clock; u8 m_dac_windex, m_dac_rindex, m_dac_state, m_dac_mask; u32 m_dac_colors[256]; u8 m_pll_regs[16]; + u16 m_gpio_pullups; u8 regs_0_read(offs_t offset); void regs_0_write(offs_t offset, u8 data); diff --git a/src/mame/apple/imacg3.cpp b/src/mame/apple/imacg3.cpp index dfadf6ce7ad..9f733a9829a 100644 --- a/src/mame/apple/imacg3.cpp +++ b/src/mame/apple/imacg3.cpp @@ -22,6 +22,7 @@ #include "emu.h" #include "cpu/powerpc/ppc.h" #include "machine/dimm_spd.h" +#include "machine/i2cmem.h" #include "machine/input_merger.h" #include "machine/mpc106.h" #include "machine/opti82c861.h" @@ -46,10 +47,11 @@ public: required_device m_cuda; required_device m_macadb; required_device m_dimm0, m_dimm1; + required_device m_edid; required_device m_ram; private: - u32 m_sense; + u16 m_sense; void imac_map(address_map &map); @@ -67,8 +69,8 @@ private: m_maincpu->set_input_line(PPC_IRQ, state); } - u32 read_sense(); - void write_sense(u32 data); + u16 read_sense(); + void write_sense(u16 data); }; imac_state::imac_state(const machine_config &mconfig, device_type type, const char *tag) : @@ -79,6 +81,7 @@ imac_state::imac_state(const machine_config &mconfig, device_type type, const ch m_macadb(*this, "macadb"), m_dimm0(*this, "dimm0"), m_dimm1(*this, "dimm1"), + m_edid(*this, "edid"), m_ram(*this, RAM_TAG) { } @@ -87,6 +90,8 @@ void imac_state::machine_start() { m_sense = 0; + m_edid->set_address(0x50<<1); + m_mpc106->set_ram_info((u8 *)m_ram->pointer(), m_ram->size()); // start off disabling all of the DIMMs @@ -125,13 +130,21 @@ void imac_state::imac_map(address_map &map) map.unmap_value_high(); } -u32 imac_state::read_sense() +// EDID sense. Rage sends a u32 where the top 16 bits are DDR, the bottom 16 bits are data. +// The return value only needs the data (the lower 16 bits) filled in. +u16 imac_state::read_sense() { - // ID as a 640x480 13" for now (needs EDID, the old Apple protocol isn't supported) - return (m_sense & 0xffff00ff) | (6 << 8); + const u8 out = (m_sense >> 12) & 0xff; + const u8 scl = ((out & 2) >> 1); + const u8 sda = (out & 1); + + m_edid->write_sda(sda); + m_edid->write_scl(scl); + + return (m_edid->read_sda() ? 0x1000 : 0) | (scl ? 0x2000 : 0); } -void imac_state::write_sense(u32 data) +void imac_state::write_sense(u16 data) { m_sense = data; } @@ -153,6 +166,9 @@ void imac_state::imac(machine_config &config) atirage_device &ati(ATI_RAGEIIC(config, "pci:12.0", 14.318181_MHz_XTAL)); ati.gpio_get_cb().set(FUNC(imac_state::read_sense)); ati.gpio_set_cb().set(FUNC(imac_state::write_sense)); + ati.set_gpio_pullups(0x3000); // bits 8 & 9 are the I2C bus + + I2C_24C01(config, m_edid); OPTI_82C861(config, "pci:14.0", 0); @@ -206,6 +222,9 @@ void imac_state::imac(machine_config &config) ROM_START(imac) ROM_REGION(0x100000, "bootrom", ROMREGION_64BIT | ROMREGION_BE) ROM_LOAD( "imacboot.u3", 0x000000, 0x100000, CRC(80d3174b) SHA1(e7a0c71822ec1e08435099af87b38bc82d315ed5) ) + + ROM_REGION(0x80, "edid", 0) + ROM_LOAD( "imac_16843009.edid", 0x000000, 0x000080, CRC(ea3051d1) SHA1(a0b0338cdd8f364135e1496b9a33f7509f0bb104) ) ROM_END static INPUT_PORTS_START(imac) -- cgit v1.2.3