diff options
author | 2019-09-09 22:38:20 +0200 | |
---|---|---|
committer | 2019-09-09 22:38:20 +0200 | |
commit | 451066eaca54e95dea450fcebf58cdda34518492 (patch) | |
tree | 60fe6b153e3b603ff7f893616fe0aa1d432cfe59 | |
parent | d4e2fbd306bf9f847fed16b9a9112eb6d8f56c8e (diff) |
-saa7191: Skeleton device for the Philips SAA7191 Digital Multistandard Colour Decoder (DSMD), nw
-sgi_mc: Fixed a silly oversight which should fix an Indigo 2 regression, nw
-vino: Added kludge devcbs for I2C data out/in/stop, nw
-rw-r--r-- | scripts/target/mame/mess.lua | 2 | ||||
-rw-r--r-- | src/mame/drivers/indy_indigo2.cpp | 14 | ||||
-rw-r--r-- | src/mame/machine/saa7191.cpp | 231 | ||||
-rw-r--r-- | src/mame/machine/saa7191.h | 177 | ||||
-rw-r--r-- | src/mame/machine/sgi.cpp | 2 | ||||
-rw-r--r-- | src/mame/machine/vino.cpp | 9 | ||||
-rw-r--r-- | src/mame/machine/vino.h | 8 |
7 files changed, 439 insertions, 4 deletions
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 441a69a72e8..0eb53373609 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3185,6 +3185,8 @@ files { MAME_DIR .. "src/mame/drivers/octane.cpp", MAME_DIR .. "src/mame/machine/vino.cpp", MAME_DIR .. "src/mame/machine/vino.h", + MAME_DIR .. "src/mame/machine/saa7191.cpp", + MAME_DIR .. "src/mame/machine/saa7191.h", MAME_DIR .. "src/mame/machine/sgi.cpp", MAME_DIR .. "src/mame/machine/sgi.h", MAME_DIR .. "src/mame/machine/hal2.cpp", diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index 67cb1d7d889..79f691084ea 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -5,8 +5,9 @@ * SGI IP22/IP24 Indigo2/Indy workstation * * Known Issues: -* - The proper hookup for the MAC address is unknown, requiring -* a fake MAC to be set up before any IRIX installers will proceed. +* - The MAC address is supplied by the NVRAM, requiring the user to +* use "setenv -f eaddr 08:00:69:xx:yy:zz" from the Indy boot PROM +* before any IRIX installers will proceed. * - The Gentoo Linux live CD hangs on starting the kernel. * * Memory map: @@ -68,6 +69,7 @@ #include "bus/nscsi/hd.h" #include "machine/sgi.h" #include "machine/vino.h" +#include "machine/saa7191.h" #include "machine/wd33c9x.h" #include "sound/cdda.h" @@ -93,6 +95,7 @@ public: , m_ioc2(*this, "ioc2") , m_rtc(*this, "rtc") , m_vino(*this, "vino") + , m_dmsd(*this, "dmsd") , m_gio64(*this, "gio64") , m_gio64_gfx(*this, "gio64_gfx") , m_gio64_exp0(*this, "gio64_exp0") @@ -141,6 +144,7 @@ protected: required_device<ioc2_device> m_ioc2; required_device<ds1386_device> m_rtc; optional_device<vino_device> m_vino; + optional_device<saa7191_device> m_dmsd; optional_device<gio64_device> m_gio64; optional_device<gio64_slot_device> m_gio64_gfx; optional_device<gio64_slot_device> m_gio64_exp0; @@ -393,7 +397,13 @@ void ip24_state::ip24(machine_config &config) m_hpc3->set_addrmap(hpc3_device::AS_PIO6, &ip24_state::pio6_map); SGI_IOC2_GUINNESS(config, m_ioc2, m_maincpu); + + SAA7191(config, m_dmsd); VINO(config, m_vino); + m_vino->i2c_data_out().set(m_dmsd, FUNC(saa7191_device::i2c_data_w)); + m_vino->i2c_data_in().set(m_dmsd, FUNC(saa7191_device::i2c_data_r)); + m_vino->i2c_stop().set(m_dmsd, FUNC(saa7191_device::i2c_stop_w)); + DS1386_8K(config, m_rtc, 32768); } diff --git a/src/mame/machine/saa7191.cpp b/src/mame/machine/saa7191.cpp new file mode 100644 index 00000000000..58adc913ebf --- /dev/null +++ b/src/mame/machine/saa7191.cpp @@ -0,0 +1,231 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************* + + saa7191.cpp + + Philips SAA7191B Digital Multistandard Colour Decoder (DMSD) + + TODO: + - Actual functionality + +*********************************************************************/ + +#include "emu.h" +#include "saa7191.h" + +#define LOG_UNKNOWN (1 << 0) +#define LOG_READS (1 << 1) +#define LOG_WRITES (1 << 2) +#define LOG_ERRORS (1 << 3) +#define LOG_I2C_IGNORES (1 << 4) +#define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_ERRORS | LOG_I2C_IGNORES | LOG_UNKNOWN) + +#define VERBOSE (LOG_DEFAULT) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(SAA7191, saa7191_device, "saa7191", "Philips SAA7191 DMSD") + +saa7191_device::saa7191_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SAA7191, tag, owner, clock) + , m_chr_in(*this) + , m_cvbs_in(*this) + , m_y_out(*this) + , m_uv_out(*this) + , m_hs_out(*this) + , m_vs_out(*this) +{ +} + +void saa7191_device::device_start() +{ + save_item(NAME(m_status)); + save_item(NAME(m_regs)); + save_item(NAME(m_i2c_write_addr)); + save_item(NAME(m_i2c_read_addr)); + save_item(NAME(m_i2c_subaddr)); + save_item(NAME(m_i2c_state)); + + m_chr_in.resolve_safe(0); + m_cvbs_in.resolve_safe(0); + + m_y_out.resolve_safe(); + m_uv_out.resolve_safe(); + m_hs_out.resolve_safe(); + m_vs_out.resolve_safe(); + + m_input_clock = timer_alloc(TIMER_INPUT_CLOCK); + m_input_clock->adjust(attotime::never); +} + +void saa7191_device::device_reset() +{ + m_status = 0; + memset(m_regs, 0, sizeof(uint8_t) * REG_COUNT); + + m_i2c_write_addr = 0x8a; + m_i2c_read_addr = 0x8b; + m_i2c_subaddr = 0x00; + m_i2c_state = I2C_STATE_IDLE; + + m_input_clock->adjust(attotime::never); +} + +void saa7191_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ +} + +WRITE8_MEMBER(saa7191_device::i2c_data_w) +{ + switch (m_i2c_state) + { + case I2C_STATE_IDLE: + if (data == m_i2c_write_addr) + m_i2c_state = I2C_STATE_SUBADDR_WRITE; + else if (data == m_i2c_read_addr) + m_i2c_state = I2C_STATE_SUBADDR_READ; + else + LOGMASKED(LOG_I2C_IGNORES, "I2C idle, address %02x ignored (mine are R:%02x/W:%02x)\n", data, m_i2c_read_addr, m_i2c_write_addr); + break; + case I2C_STATE_SUBADDR_WRITE: + m_i2c_subaddr = data; + m_i2c_state = I2C_STATE_DATA_WRITE; + break; + case I2C_STATE_SUBADDR_READ: + m_i2c_subaddr = data; + m_i2c_state = I2C_STATE_DATA_READ; + break; + case I2C_STATE_DATA_WRITE: + reg_w(space, m_i2c_subaddr, data); + m_i2c_subaddr = (m_i2c_subaddr + 1) % REG_COUNT; + break; + case I2C_STATE_DATA_READ: + LOGMASKED(LOG_ERRORS, "I2C is expecting a data read, but data was written, returning to idle\n"); + m_i2c_state = I2C_STATE_IDLE; + break; + default: + LOGMASKED(LOG_ERRORS, "Unknown I2C state %d, returning to idle\n", m_i2c_state); + m_i2c_state = I2C_STATE_IDLE; + break; + } +} + +READ8_MEMBER(saa7191_device::i2c_data_r) +{ + if (m_i2c_state != I2C_STATE_DATA_READ) + { + LOGMASKED(LOG_ERRORS, "i2c_data_r called, but we are in state %d and not expecting a data read, returning to idle\n", m_i2c_state); + m_i2c_state = I2C_STATE_IDLE; + return 0; + } + if (m_i2c_subaddr == 0x01) + { + LOGMASKED(LOG_READS, "i2c_data_r: Status = %02x\n", m_status); + m_i2c_subaddr = (m_i2c_subaddr + 1) % REG_COUNT; + return m_status; + } + LOGMASKED(LOG_UNKNOWN, "i2c_data_r: Unknown Sub-Address %02x, returning 0\n", m_i2c_subaddr); + m_i2c_subaddr = (m_i2c_subaddr + 1) % REG_COUNT; + return 0; +} + +WRITE_LINE_MEMBER(saa7191_device::i2c_stop_w) +{ + if (state) + m_i2c_state = I2C_STATE_IDLE; +} + +WRITE_LINE_MEMBER(saa7191_device::iicsa_w) +{ + m_i2c_write_addr = state ? 0x8e : 0x8a; + m_i2c_read_addr = m_i2c_write_addr | 1; +} + +WRITE8_MEMBER(saa7191_device::reg_w) +{ + if (m_i2c_subaddr < REG_COUNT) + { + m_regs[m_i2c_subaddr] = data; + } + + switch (m_i2c_subaddr) + { + case REG_IDEL: + LOGMASKED(LOG_WRITES, "i2c_data_w: Increment delay = %02x\n", data); + break; + case REG_HSYB: + LOGMASKED(LOG_WRITES, "i2c_data_w: H sync begin, 50Hz = %02x\n", data); + break; + case REG_HSYS: + LOGMASKED(LOG_WRITES, "i2c_data_w: H sync stop, 50Hz = %02x\n", data); + break; + case REG_HCLB: + LOGMASKED(LOG_WRITES, "i2c_data_w: H clamp begin, 50Hz = %02x\n", data); + break; + case REG_HCLS: + LOGMASKED(LOG_WRITES, "i2c_data_w: H clamp stop, 50Hz = %02x\n", data); + break; + case REG_HPHI: + LOGMASKED(LOG_WRITES, "i2c_data_w: H sync after PHI1, 50Hz = %02x\n", data); + break; + case REG_LUMC: + LOGMASKED(LOG_WRITES, "i2c_data_w: Luminance control = %02x\n", data); + break; + case REG_HUEC: + LOGMASKED(LOG_WRITES, "i2c_data_w: Hue control = %02x\n", data); + break; + case REG_CKTQ: + LOGMASKED(LOG_WRITES, "i2c_data_w: Colour killer threshold QAM = %02x\n", data); + break; + case REG_CKTS: + LOGMASKED(LOG_WRITES, "i2c_data_w: Colour killer threshold SECAM = %02x\n", data); + break; + case REG_PLSE: + LOGMASKED(LOG_WRITES, "i2c_data_w: PAL switch sensitivity = %02x\n", data); + break; + case REG_SESE: + LOGMASKED(LOG_WRITES, "i2c_data_w: SECAM switch sensitivity = %02x\n", data); + break; + case REG_GAIN: + LOGMASKED(LOG_WRITES, "i2c_data_w: Chroma gain control settings = %02x\n", data); + break; + case REG_STDC: + LOGMASKED(LOG_WRITES, "i2c_data_w: Standard/mode control = %02x\n", data); + break; + case REG_IOCK: + LOGMASKED(LOG_WRITES, "i2c_data_w: I/O and clock control = %02x\n", data); + break; + case REG_CTL1: + LOGMASKED(LOG_WRITES, "i2c_data_w: Control #1 = %02x\n", data); + break; + case REG_CTL2: + LOGMASKED(LOG_WRITES, "i2c_data_w: Control #2 = %02x\n", data); + break; + case REG_CHCV: + LOGMASKED(LOG_WRITES, "i2c_data_w: Chroma gain reference = %02x\n", data); + break; + case REG_HS6B: + LOGMASKED(LOG_WRITES, "i2c_data_w: H sync begin, 60Hz = %02x\n", data); + break; + case REG_HS6S: + LOGMASKED(LOG_WRITES, "i2c_data_w: H sync stop, 60Hz = %02x\n", data); + break; + case REG_HC6B: + LOGMASKED(LOG_WRITES, "i2c_data_w: H clamp begin, 60Hz = %02x\n", data); + break; + case REG_HC6S: + LOGMASKED(LOG_WRITES, "i2c_data_w: H clamp stop, 60Hz = %02x\n", data); + break; + case REG_HP6I: + LOGMASKED(LOG_WRITES, "i2c_data_w: H sync after PHI1, 60Hz = %02x\n", data); + break; + default: + LOGMASKED(LOG_WRITES, "i2c_data_w: Unknown Register %02x = %02x (ignored)\n", m_i2c_subaddr, data); + if (m_i2c_subaddr < REG_COUNT) + { + m_regs[m_i2c_subaddr] = 0; + } + break; + } +} + diff --git a/src/mame/machine/saa7191.h b/src/mame/machine/saa7191.h new file mode 100644 index 00000000000..b641aa46190 --- /dev/null +++ b/src/mame/machine/saa7191.h @@ -0,0 +1,177 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************* + + saa7191.h + + Philips SAA7191B Digital Multistandard Colour Decoder (DMSD) + + TODO: + - Actual functionality + +*********************************************************************/ + +#ifndef MAME_MACHINE_SAA7191_H +#define MAME_MACHINE_SAA7191_H + +#pragma once + +class saa7191_device : public device_t +{ +public: + saa7191_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); + + DECLARE_WRITE8_MEMBER(i2c_data_w); + DECLARE_READ8_MEMBER(i2c_data_r); + DECLARE_WRITE_LINE_MEMBER(i2c_stop_w); + + DECLARE_WRITE_LINE_MEMBER(iicsa_w); + + auto chr_in() { return m_chr_in.bind(); } + auto cvbs_in() { return m_cvbs_in.bind(); } + + auto y_out() { return m_y_out.bind(); } + auto uv_out() { return m_uv_out.bind(); } + auto hs_out() { return m_hs_out.bind(); } + auto vs_out() { return m_vs_out.bind(); } + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + DECLARE_WRITE8_MEMBER(reg_w); + + enum + { + REG_IDEL = 0x00, + REG_HSYB = 0x01, + REG_HSYS = 0x02, + REG_HCLB = 0x03, + REG_HCLS = 0x04, + REG_HPHI = 0x05, + REG_LUMC = 0x06, + REG_HUEC = 0x07, + REG_CKTQ = 0x08, + REG_CKTS = 0x09, + REG_PLSE = 0x0a, + REG_SESE = 0x0b, + REG_GAIN = 0x0c, + REG_STDC = 0x0d, + REG_IOCK = 0x0e, + REG_CTL1 = 0x0f, + REG_CTL2 = 0x10, + REG_CHCV = 0x11, + REG_HS6B = 0x14, + REG_HS6S = 0x15, + REG_HC6B = 0x16, + REG_HC6S = 0x17, + REG_HP6I = 0x18, + REG_COUNT, + + LUMC_APER_SHIFT = 0, + LUMC_APER_MASK = (3 << LUMC_APER_SHIFT), + LUMC_CORI_SHIFT = 2, + LUMC_CORI_MASK = (3 << LUMC_CORI_SHIFT), + LUMC_BPSS_SHIFT = 4, + LUMC_BPSS_MASK = (3 << LUMC_BPSS_SHIFT), + LUMC_PREF_BIT = 6, + LUMC_PREF_MASK = (1 << LUMC_PREF_BIT), + LUMC_BYPS_BIT = 7, + LUMC_BYPS_MASK = (1 << LUMC_BYPS_BIT), + + CKTQ_SHIFT = 3, + CKTQ_MASK = (0x1f << CKTQ_SHIFT), + CKTS_SHIFT = 3, + CKTS_MASK = (0x1f << CKTS_SHIFT), + + GAIN_LFIS_SHIFT = 5, + GAIN_LFIS_MASK = (3 << GAIN_LFIS_SHIFT), + GAIN_COLO_BIT = 7, + GAIN_COLO_MASK = (1 << GAIN_COLO_BIT), + GAIN_MASK = GAIN_LFIS_MASK | GAIN_COLO_MASK, + + STDC_SECS_BIT = 0, + STDC_SECS_MASK = (1 << STDC_SECS_BIT), + STDC_GPSW0_BIT = 1, + STDC_GPSW0_MASK = (1 << STDC_GPSW0_BIT), + STDC_HRMV_BIT = 2, + STDC_HRMV_MASK = (1 << STDC_HRMV_BIT), + STDC_NFEN_BIT = 3, + STDC_NFEN_MASK = (1 << STDC_NFEN_BIT), + STDC_VTRC_BIT = 7, + STDC_VTRC_MASK = (1 << STDC_VTRC_BIT), + STDC_MASK = STDC_SECS_MASK | STDC_GPSW0_MASK | STDC_HRMV_MASK | STDC_NFEN_MASK | STDC_VTRC_MASK, + + IOCK_GPSW1_BIT = 0, + IOCK_GPSW1_MASK = (1 << IOCK_GPSW1_BIT), + IOCK_GPSW2_BIT = 1, + IOCK_GPSW2_MASK = (1 << IOCK_GPSW2_BIT), + IOCK_CHRS_BIT = 2, + IOCK_CHRS_MASK = (1 << IOCK_CHRS_BIT), + IOCK_OEDY_BIT = 3, + IOCK_OEDY_MASK = (1 << IOCK_OEDY_BIT), + IOCK_OEVS_BIT = 4, + IOCK_OEVS_MASK = (1 << IOCK_OEVS_BIT), + IOCK_OEHS_BIT = 5, + IOCK_OEHS_MASK = (1 << IOCK_OEHS_BIT), + IOCK_OEDC_BIT = 6, + IOCK_OEDC_MASK = (1 << IOCK_OEDC_BIT), + IOCK_HPLL_BIT = 7, + IOCK_HPLL_MASK = (1 << IOCK_HPLL_BIT), + + CTL1_YDEL_SHIFT = 0, + CTL1_YDEL_MASK = (7 << CTL1_YDEL_SHIFT), + CTL1_OFTS_BIT = 3, + CTL1_OFTS_MASK = (1 << CTL1_OFTS_BIT), + CTL1_SCEN_BIT = 4, + CTL1_SCEN_MASK = (1 << CTL1_SCEN_BIT), + CTL1_SXCR_BIT = 5, + CTL1_SXCR_MASK = (1 << CTL1_SXCR_BIT), + CTL1_FSEL_BIT = 6, + CTL1_FSEL_MASK = (1 << CTL1_FSEL_BIT), + CTL1_AUFD_BIT = 7, + CTL1_AUFD_MASK = (1 << CTL1_AUFD_BIT), + + CTL2_VNOI_SHIFT = 0, + CTL2_VNOI_MASK = (3 << CTL2_VNOI_SHIFT), + CTL2_HRFS_SHIFT = 2, + CTL2_HRFS_MASK = (1 << CTL2_HRFS_SHIFT), + CTL2_MASK = CTL2_VNOI_MASK | CTL2_HRFS_MASK + }; + + enum + { + I2C_STATE_IDLE, + I2C_STATE_SUBADDR_READ, + I2C_STATE_SUBADDR_WRITE, + I2C_STATE_DATA_READ, + I2C_STATE_DATA_WRITE + }; + + static constexpr device_timer_id TIMER_INPUT_CLOCK = 0; + + emu_timer *m_input_clock; + + uint8_t m_status; + uint8_t m_regs[REG_COUNT]; + + uint8_t m_i2c_write_addr; + uint8_t m_i2c_read_addr; + uint8_t m_i2c_subaddr; + int m_i2c_state; + + devcb_read8 m_chr_in; + devcb_read8 m_cvbs_in; + + devcb_write8 m_y_out; + devcb_write8 m_uv_out; + devcb_write_line m_hs_out; + devcb_write_line m_vs_out; +}; + +DECLARE_DEVICE_TYPE(SAA7191, saa7191_device) + +#endif // MAME_MACHINE_SAA7191_H
\ No newline at end of file diff --git a/src/mame/machine/sgi.cpp b/src/mame/machine/sgi.cpp index b978fc1f3df..f1fe3f20a21 100644 --- a/src/mame/machine/sgi.cpp +++ b/src/mame/machine/sgi.cpp @@ -84,7 +84,7 @@ void sgi_mc_device::device_resolve_objects() void sgi_mc_device::device_start() { m_sys_id = 0x03; // rev. C MC - m_sys_id = m_eisa_present() << 4; + m_sys_id |= m_eisa_present() << 4; m_rpss_timer = timer_alloc(TIMER_RPSS); m_rpss_timer->adjust(attotime::never); diff --git a/src/mame/machine/vino.cpp b/src/mame/machine/vino.cpp index 0535ed1d567..5f1044b2d39 100644 --- a/src/mame/machine/vino.cpp +++ b/src/mame/machine/vino.cpp @@ -2,7 +2,7 @@ // copyright-holders:Ryan Holtz /********************************************************************* - vino.c + vino.cpp Silicon Graphics VINO (Video-In, No Out) controller emulation @@ -23,6 +23,9 @@ DEFINE_DEVICE_TYPE(VINO, vino_device, "vino", "SGI VINO Controller") vino_device::vino_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, VINO, tag, owner, clock) + , m_i2c_data_out(*this) + , m_i2c_data_in(*this) + , m_i2c_stop(*this) { } @@ -58,6 +61,10 @@ void vino_device::device_start() save_item(NAME(m_channels[i].m_fifo_gio_ptr), i); save_item(NAME(m_channels[i].m_fifo_video_ptr), i); } + + m_i2c_data_out.resolve_safe(); + m_i2c_data_in.resolve_safe(0x00); + m_i2c_stop.resolve_safe(); } void vino_device::device_reset() diff --git a/src/mame/machine/vino.h b/src/mame/machine/vino.h index 446664e626f..0c11247c2ab 100644 --- a/src/mame/machine/vino.h +++ b/src/mame/machine/vino.h @@ -21,6 +21,10 @@ public: DECLARE_READ32_MEMBER(read); DECLARE_WRITE32_MEMBER(write); + auto i2c_data_out() { return m_i2c_data_out.bind(); } + auto i2c_data_in() { return m_i2c_data_in.bind(); } + auto i2c_stop() { return m_i2c_stop.bind(); } + protected: // device-level overrides virtual void device_start() override; @@ -155,6 +159,10 @@ private: uint32_t m_i2c_ctrl; uint32_t m_i2c_data; channel_t m_channels[2]; + + devcb_write8 m_i2c_data_out; + devcb_read8 m_i2c_data_in; + devcb_write_line m_i2c_stop; }; DECLARE_DEVICE_TYPE(VINO, vino_device) |