diff options
Diffstat (limited to 'src/devices/bus/pci/zr36057.cpp')
-rw-r--r-- | src/devices/bus/pci/zr36057.cpp | 173 |
1 files changed, 158 insertions, 15 deletions
diff --git a/src/devices/bus/pci/zr36057.cpp b/src/devices/bus/pci/zr36057.cpp index 0d3964e2a0c..57fbf9f056e 100644 --- a/src/devices/bus/pci/zr36057.cpp +++ b/src/devices/bus/pci/zr36057.cpp @@ -14,12 +14,13 @@ iterations. ZR36057 is known to have two HW quirks that are been fixed with ZR36067. TODO: -- Currently at dc10plus HW test "Error at M-JPEG codec", requires ZR36060 to continue; +- Enough to pass board functions in dc10plus HW test, requires VSYNC signal from ZR36060 to continue; - Hookup busmaster; - What are i2c 0x8e >> 1 address device checks for? \- Can't be adv7175 (0xd4 >> 1) nor adv7176 (0x54 >> 1) ... - Soft Reset & Write lock mechanisms (each register have separate macro-groups); +- GuestBus slot mechanism (relevant when multiple devices are hooked); - eventually decouple AV PCI controller part from the actual client cards; Known mix-ins: @@ -37,13 +38,14 @@ Known mix-ins: #include "zr36057.h" #define LOG_WARN (1U << 1) +#define LOG_PO (1U << 2) // PostOffice interactions -#define VERBOSE (LOG_GENERAL | LOG_WARN) +#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_PO) //#define LOG_OUTPUT_FUNC osd_printf_info #include "logmacro.h" #define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__) - +#define LOGPO(...) LOGMASKED(LOG_PO, __VA_ARGS__) DEFINE_DEVICE_TYPE(ZR36057_PCI, zr36057_device, "zr36057", "Zoran ZR36057-based Enhanced Multimedia Controller") //DEFINE_DEVICE_TYPE(ZR36067_PCI, zr36067_device, "zr36067", "Zoran ZR36067-based AV Controller") @@ -51,6 +53,7 @@ DEFINE_DEVICE_TYPE(ZR36057_PCI, zr36057_device, "zr36057", "Zoran ZR36057-ba zr36057_device::zr36057_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : pci_card_device(mconfig, type, tag, owner, clock) + , m_guest(*this, "guest") , m_decoder(*this, "decoder") { // ZR36057PQC Video cutting chipset @@ -73,11 +76,13 @@ zr36057_device::zr36057_device(const machine_config &mconfig, const char *tag, d void zr36057_device::device_add_mconfig(machine_config &config) { - // 27'000'000 xtal near ZR36060 + ZR36060(config, m_guest, XTAL(27'000'000)); SAA7110A(config, m_decoder, XTAL(26'800'000)); m_decoder->sda_callback().set([this](int state) { m_decoder_sdao_state = state; }); + //ADV7176(config, m_encoder, XTAL(27'000'000)); + // S-Video input/output // composite video input/output @@ -116,8 +121,11 @@ void zr36057_device::device_reset() void zr36057_device::software_reset() { LOG("SoftReset\n"); - m_video_frontend.horizontal_config = (0 << 30) | (0x001 << 10) | (0x3ff << 0); - m_video_frontend.vertical_config = (0 << 30) | (0x001 << 10) | (0x3ff << 0); + m_vfe.hspol = m_vfe.vspol = 0; + m_vfe.hstart = m_vfe.vstart = 0x001; + m_vfe.hend = m_vfe.vend = 0x3ff; + m_vfe.horizontal_config = (m_vfe.hspol << 30) | (m_vfe.hstart << 10) | (m_vfe.hend << 0); + m_vfe.vertical_config = (m_vfe.vspol << 30) | (m_vfe.vstart << 10) | (m_vfe.vend << 0); m_pci_waitstate_control = 0; m_gpio_ddr = 0xff; // all inputs @@ -125,6 +133,15 @@ void zr36057_device::software_reset() // m_gpio_data = 0xf0; for (int i = 0; i < 4; i++) m_guestbus.time[i] = 0; + + m_jpeg_guest_id = 4; + m_jpeg_guest_reg = 0; + + m_po.pending = false; + m_po.time_out = false; + m_po.dir = true; + m_po.guest_id = 0; + m_po.guest_reg = 0; } void zr36057_device::config_map(address_map &map) @@ -134,33 +151,46 @@ void zr36057_device::config_map(address_map &map) map(0x3f, 0x3f).lr8(NAME([] () { return 0x10; })); } -// Application Specific Register +// Application Specific Register(s) void zr36057_device::asr_map(address_map &map) { map(0x000, 0x003).lrw32( NAME([this] (offs_t offset) { // NOTE: wants to read-back here, throws "Bus Master ASIC error" otherwise (?) LOG("Video Front End Horizontal Configuration R\n"); - return m_video_frontend.horizontal_config; + return m_vfe.horizontal_config; }), NAME([this] (offs_t offset, u32 data, u32 mem_mask) { - COMBINE_DATA(&m_video_frontend.horizontal_config); + COMBINE_DATA(&m_vfe.horizontal_config); LOG("Video Front End Horizontal Configuration W %08x & %08x\n", data, mem_mask); + m_vfe.hspol = BIT(m_vfe.horizontal_config, 30); + m_vfe.hstart = (m_vfe.horizontal_config >> 10) & 0x3ff; + m_vfe.hend = (m_vfe.horizontal_config >> 0) & 0x3ff; + LOG("\tVSPOL %d VSTART %d VEND %d\n", m_vfe.hspol, m_vfe.hstart, m_vfe.hend); }) ); map(0x004, 0x007).lrw32( NAME([this] (offs_t offset) { LOG("Video Front End Vertical Configuration R\n"); - return m_video_frontend.vertical_config; + return m_vfe.vertical_config; }), NAME([this] (offs_t offset, u32 data, u32 mem_mask) { - COMBINE_DATA(&m_video_frontend.vertical_config); + COMBINE_DATA(&m_vfe.vertical_config); LOG("Video Front End Vertical Configuration %08x & %08\n", data, mem_mask); + m_vfe.vspol = BIT(m_vfe.vertical_config, 30); + m_vfe.vstart = (m_vfe.vertical_config >> 10) & 0x3ff; + m_vfe.vend = (m_vfe.vertical_config >> 0) & 0x3ff; + LOG("\tVSPOL %d VSTART %d VEND %d\n", m_vfe.vspol, m_vfe.vstart, m_vfe.vend); }) ); - - // ... - +// map(0x008, 0x00b) VFE Config, Video Scaler and Pixel Format +// map(0x00c, 0x00f) Video Display Top +// map(0x010, 0x013) Video Display Bottom +// map(0x014, 0x017) Video Display Stride, Status and Frame Grab +// map(0x018, 0x01b) Video Display Configuration +// map(0x01c, 0x01f) Masking Map Top +// map(0x020, 0x023) Masking Map Bottom +// map(0x024, 0x027) Overlay Control map(0x028, 0x02b).lrw32( NAME([this] (offs_t offset) { return (m_softreset << 24) | (m_pci_waitstate_control << 16) | m_gpio_ddr; @@ -191,6 +221,7 @@ void zr36057_device::asr_map(address_map &map) // The doc claims 0xf0 default for GPIO, but win98 driver will throw "subvendor ID failed" // while testing various ID combinations here + // This should come from GDAT pin at strapping time return (0x7e << 24) | (m_guestbus.time[3] << 12) | (m_guestbus.time[2] << 8) | (m_guestbus.time[1] << 4) | (m_guestbus.time[0] << 0); }), NAME([this] (offs_t offset, u32 data, u32 mem_mask) { @@ -212,7 +243,11 @@ void zr36057_device::asr_map(address_map &map) } }) ); - +// map(0x030, 0x033) MPEG Code Source Address +// map(0x034, 0x037) MPEG Code Transfer Control +// map(0x038, 0x03b) MPEG Code Memory Pointer +// map(0x03c, 0x03f) Interrupt Status +// map(0x040, 0x043) Interrupt Control map(0x044, 0x047).lrw32( NAME([this] (offs_t offset) { LOG("I2C R\n"); @@ -229,4 +264,112 @@ void zr36057_device::asr_map(address_map &map) } }) ); +// map(0x100, 0x103) JPEG Mode and Control +// map(0x104, 0x107) JPEG Process Control +// map(0x108, 0x10b) Vertical Sync Parameters (as sync master) +// map(0x10c, 0x10f) Horizontal Sync Parameters (as sync master) +// map(0x110, 0x113) Field Horizontal Active Portion +// map(0x114, 0x117) Field Vertical Active Portion +// map(0x118, 0x11b) Field Process Parameters +// map(0x11c, 0x11f) JPEG Code Base Address +// map(0x120, 0x123) JPEG Code FIFO Threshold + map(0x124, 0x124).lrw8( + NAME([this] (offs_t offset) { + LOG("JPEG Codec Guest ID R\n"); + return (m_jpeg_guest_id << 4) | (m_jpeg_guest_reg << 0); + }), + NAME([this] (offs_t offset, u8 data) { + m_jpeg_guest_id = (data >> 4) & 7; + m_jpeg_guest_reg = (data >> 0) & 7; + LOG("JPEG Codec Guest ID W %02x\n", data); + }) + ); + map(0x12c, 0x12f).lrw32( + NAME([this] (offs_t offset) { + LOG("GuestBus Control (II) R\n"); + + return (0 << 16) | (m_guestbus.time[7] << 12) | (m_guestbus.time[6] << 8) | (m_guestbus.time[5] << 4) | (m_guestbus.time[4] << 0); + }), + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOG("GuestBus Control (II) W %08x & %08x\n", data, mem_mask); + + if (ACCESSING_BITS_8_15) + { + m_guestbus.time[7] = (data >> 12) & 0xf; + m_guestbus.time[6] = (data >> 8) & 0xf; + } + + if (ACCESSING_BITS_0_7) + { + m_guestbus.time[5] = (data >> 4) & 0xf; + m_guestbus.time[4] = (data >> 0) & 0xf; + } + }) + ); + + map(0x200, 0x2ff).rw(FUNC(zr36057_device::postoffice_r), FUNC(zr36057_device::postoffice_w)); +// map(0x300, 0x303) Still Transfer +} + +// TODO: PostOffice accesses thru GuestBus are dictated with PCI clock cycles, asynchronous +// We pretend they are synchronous as a starting point, and one port only (which may matter later +// with CODE transfers). A time out happens 64 PCI cycles later in ZR36067, '120 halves that threshold. +// This should eventually be expressed in a osd_work_queue, with guestbus address_space roughly as: +// for (int i = 0; i < 8; i++) +// { +// if (<is_device_installed>) +// map(0 | (i << 2), 3 | (i << 2)).flags(<fn>).m(m_guest[i], map); +// else +// map(0 | (i << 2), 3 | (i << 2)).flags(<abort_fn>); +// } +u32 zr36057_device::postoffice_r(offs_t offset) +{ + //LOGPO("PO R %d %d\n", m_po.guest_id, m_po.guest_reg); + u8 res = 0; + if (m_po.guest_id == 0) + { + if (m_po.dir == false) + res = m_guest->read(m_po.guest_reg); + } + else if (!machine().side_effects_disabled()) + { + m_po.time_out = true; + LOGWARN("Warning: PO access unmapped POGuestID read %d %02x\n", m_po.guest_id, m_po.guest_reg); + } + + return (m_po.pending << 25) + | (m_po.time_out << 24) + | (m_po.dir << 23) + | (m_po.guest_id << 20) + | (m_po.guest_reg << 16) + | res; +} + +void zr36057_device::postoffice_w(offs_t offset, u32 data, u32 mem_mask) +{ + // clear a previously set time out flag + if (BIT(data, 24)) + m_po.time_out = false; + m_po.dir = !!(BIT(data, 23)); + m_po.guest_id = (data >> 20) & 7; + m_po.guest_reg = (data >> 16) & 7; + LOGPO("PO W [%08x] %08x & %08x PODir %s POGuestID %d POGuestReg %d POData %02x\n" + , offset << 2 + , data + , mem_mask + , m_po.dir ? "Write" : "Read" + , m_po.guest_id + , m_po.guest_reg + , data & 0xff + ); + if (m_po.guest_id == 0) + { + if (m_po.dir == true) + m_guest->write(m_po.guest_reg, data & 0xff); + } + else + { + m_po.time_out = true; + LOGWARN("Warning: PO access unmapped POGuestID write %d %02x\n", m_po.guest_id, m_po.guest_reg); + } } |