diff options
| author | 2023-05-07 13:03:25 +0200 | |
|---|---|---|
| committer | 2023-05-07 13:03:59 +0200 | |
| commit | 029264ad4876e9d7a597b078e821bf25bf8e5b3e (patch) | |
| tree | 71a7078c547c8d9c5b842bb118edeea9ef0f679e | |
| parent | 8f05076b076adf494509d1ae5cbd2a6a07b25afa (diff) | |
zr36110: Add skeleton
hrdvd: Hook up the mpeg chip
| -rw-r--r-- | scripts/src/video.lua | 12 | ||||
| -rw-r--r-- | src/devices/bus/ata/atahle.cpp | 10 | ||||
| -rw-r--r-- | src/devices/cpu/h8/h8.cpp | 4 | ||||
| -rw-r--r-- | src/devices/cpu/h8/h8_dma.cpp | 10 | ||||
| -rw-r--r-- | src/devices/video/zr36110.cpp | 218 | ||||
| -rw-r--r-- | src/devices/video/zr36110.h | 64 | ||||
| -rw-r--r-- | src/mame/nichibutsu/hrdvd.cpp | 54 |
7 files changed, 325 insertions, 47 deletions
diff --git a/scripts/src/video.lua b/scripts/src/video.lua index b4c27394006..1d2937e3867 100644 --- a/scripts/src/video.lua +++ b/scripts/src/video.lua @@ -1480,3 +1480,15 @@ if (VIDEOS["X1_001"]~=null) then MAME_DIR .. "src/devices/video/x1_001.h", } end + +-------------------------------------------------- +-- +--@src/devices/video/zr36110.h,VIDEOS["ZR36110"] = true +-------------------------------------------------- + +if (VIDEOS["ZR36110"]~=null) then + files { + MAME_DIR .. "src/devices/video/zr36110.cpp", + MAME_DIR .. "src/devices/video/zr36110.h", + } +end diff --git a/src/devices/bus/ata/atahle.cpp b/src/devices/bus/ata/atahle.cpp index 2c6bb724d61..5d3e413dde2 100644 --- a/src/devices/bus/ata/atahle.cpp +++ b/src/devices/bus/ata/atahle.cpp @@ -464,8 +464,9 @@ void ata_hle_device::read_buffer_empty() m_status &= ~IDE_STATUS_DRQ; - if ((multi_word_dma_mode() >= 0) || (ultra_dma_mode() >= 0)) - set_dmarq(CLEAR_LINE); + // Doesn't matter if we're in dma or not, when the buffer is empty + // there's no more request to be had + set_dmarq(CLEAR_LINE); if (ultra_dma_mode() >= 0) { m_buffer_empty_timer->enable(true); @@ -481,8 +482,9 @@ void ata_hle_device::write_buffer_full() m_status &= ~IDE_STATUS_DRQ; - if ((multi_word_dma_mode() >= 0) || (ultra_dma_mode() >= 0)) - set_dmarq(CLEAR_LINE); + // Doesn't matter if we're in dma or not, when the buffer is full + // there's no more request to be had + set_dmarq(CLEAR_LINE); process_buffer(); } diff --git a/src/devices/cpu/h8/h8.cpp b/src/devices/cpu/h8/h8.cpp index cd40624586c..b66033059e3 100644 --- a/src/devices/cpu/h8/h8.cpp +++ b/src/devices/cpu/h8/h8.cpp @@ -160,11 +160,11 @@ void h8_device::set_current_dma(h8_dma_state *state) current_dma = state; if(!state) logerror("DMA done\n"); - else + else { logerror("New current dma s=%x d=%x is=%d id=%d count=%x m=%d autoreq=%d\n", state->source, state->dest, state->incs, state->incd, state->count, state->mode_16 ? 16 : 8, state->autoreq); - + } } void h8_device::set_current_dtc(h8_dtc_state *state) diff --git a/src/devices/cpu/h8/h8_dma.cpp b/src/devices/cpu/h8/h8_dma.cpp index 1fe9a1f98a2..2c2fa9d3fe5 100644 --- a/src/devices/cpu/h8/h8_dma.cpp +++ b/src/devices/cpu/h8/h8_dma.cpp @@ -430,9 +430,10 @@ bool h8_dma_channel_device::start_test(int vector) if(dte != 3) return false; - if(dmacr & 0x0800) + if(dmacr & 0x0800) { throw emu_fatalerror("%s: DMA startup test in full address/block mode unimplemented.\n", tag()); - else { + + } else { // Normal Mode if(vector == -1) { start(0); @@ -478,8 +479,8 @@ void h8_dma_channel_device::start(int submodule) state[submodule].dest = mar[1]; state[submodule].count = etcr[0] ? etcr[0] : 0x10000; state[submodule].mode_16 = dmacr & 0x8000; - state[submodule].autoreq = (dmacr & 6) == 6; - state[submodule].suspended = !state[submodule].autoreq; // non-auto-request transfers start suspended + state[submodule].autoreq = (dmacr & 6) == 6 || (dmacr & 7) == 3; // autoreq or dreq level + state[submodule].suspended = (dmacr & 6) != 6; // non-auto-request transfers start suspended int32_t step = state[submodule].mode_16 ? 2 : 1; state[submodule].incs = dmacr & 0x2000 ? dmacr & 0x4000 ? -step : step : 0; state[submodule].incd = dmacr & 0x0020 ? dmacr & 0x0040 ? -step : step : 0; @@ -527,7 +528,6 @@ void h8_dma_channel_device::count_last(int submodule) void h8_dma_channel_device::count_done(int submodule) { - logerror("count done on %d\n", submodule); if(!state[submodule].autoreq) cpu->set_input_line(H8_INPUT_LINE_TEND0 + (state[submodule].id >> 1), CLEAR_LINE); if(fae) { diff --git a/src/devices/video/zr36110.cpp b/src/devices/video/zr36110.cpp new file mode 100644 index 00000000000..37caf1c0244 --- /dev/null +++ b/src/devices/video/zr36110.cpp @@ -0,0 +1,218 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Zoran ZR36110 mpeg video decoder + +#include "emu.h" +#include "zr36110.h" + +#define LOG_MICROCODE (1U << 1) +#define LOG_SETUP (1U << 2) + +#define VERBOSE (LOG_GENERAL|LOG_SETUP) +#include "logmacro.h" + +#define LOGMICROCODE(...) LOGMASKED(LOG_MICROCODE, __VA_ARGS__) + +DEFINE_DEVICE_TYPE(ZR36110, zr36110_device, "zr36110", "Zoran ZR36110 mpeg decoder") + +zr36110_device::zr36110_device(const machine_config &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, ZR36110, tag, owner, clock), + m_drq_handler(*this) +{ +} + +void zr36110_device::device_start() +{ + m_drq_handler.resolve_safe(); + + save_item(NAME(m_mc1_adr)); + save_item(NAME(m_mc23_adr)); + save_item(NAME(m_setup_adr)); + save_item(NAME(m_state)); + save_item(NAME(m_setup)); + save_item(NAME(m_cmd_phase)); + save_item(NAME(m_cmd)); + save_item(NAME(m_bus_control)); +} + +void zr36110_device::device_reset() +{ + memset(m_setup, 0, sizeof(m_setup)); + m_setup[0] = 0x10; + m_mc1_adr = 0; + m_mc23_adr = 0; + m_setup_adr = 0; + m_state = S_IDLE; + m_cmd_phase = false; + m_cmd = 0; + m_bus_control = 0x10; +} + +void zr36110_device::mc18_w(u8 data) +{ + m_mc23_adr = 0; + m_setup_adr = 0; + LOGMICROCODE("mc1[%03x] = %02x\n", m_mc1_adr, data); + m_mc1_adr = m_mc1_adr + 1; +} + +void zr36110_device::mc238_w(u8 data) +{ + m_setup_adr = 0; + m_mc1_adr = 0; + LOGMICROCODE("mc23[%03x] = %02x\n", m_mc23_adr, data); + m_mc23_adr = m_mc23_adr + 1; + if(m_mc23_adr >= 0x2000 && m_state == S_INIT) + m_state = S_IDLE; +} + +double zr36110_device::u6_10_to_f(u16 val) +{ + if(val & 0x8000) + return (val - 0x10000) / 1024.0; + else + return val / 1024.0; +} + +double zr36110_device::u5_19_to_f(u32 val) +{ + return val / 524288.0; +} + +void zr36110_device::setup_show() const +{ + LOG_OUTPUT_FUNC("Chip setup:\n"); + LOG_OUTPUT_FUNC(" 00 - buswidth=%d order=%s stream=%s burst_length=%d\n", + m_setup[0x00] & 0x80 ? 16 : 8, + m_setup[0x00] & 0x40 ? "lsb" : "msb", + m_setup[0x00] & 0x20 ? "dma" : "pio", + m_setup[0x00] & 0x1f); + LOG_OUTPUT_FUNC(" 01 - busoff=%d\n", + m_setup[0x01] << 4); + LOG_OUTPUT_FUNC(" 02 - type=%s rate=%s interface=%s half=%s dram=%s start=%s last=%s\n", + m_setup[0x02] & 0x80 ? m_setup[0x02] & 0x04 ? "serial" : "video" : m_setup[0x02] & 0x04 ? "sectors" : "stream", + m_setup[0x02] & 0x40 ? "pal" : "ntsc", + m_setup[0x02] & 0x20 ? "enabled" : "normal", + m_setup[0x02] & 0x10 ? "as-needed" : "always", + m_setup[0x02] & 0x08 ? "8M" : "4M", + m_setup[0x02] & 0x02 ? "sequence" : "any", + m_setup[0x02] & 0x01 ? "image" : "background"); + LOG_OUTPUT_FUNC(" 03 - size=%s hinterpolate=%s color=%s bias=%s fi=%s\n", + m_setup[0x03] & 0x80 ? "sif-prog" : "ccir-int", + m_setup[0x03] & 0x40 ? "off" : "on", + m_setup[0x03] & 0x20 ? (m_setup[0x03] & 0x18) == 0x00 ? "rgb888" : (m_setup[0x03] & 0x18) == 0x08 ? "rgb565" : (m_setup[0x03] & 0x18) == 0x10 ? "rgb555" : "rgb?" : m_setup[0x03] & 0x04 ? "yuv411" : "yuv422", + m_setup[0x03] & 0x02 ? "on" : "off", + m_setup[0x03] & 0x01 ? "blank" : "field"); + LOG_OUTPUT_FUNC(" 04 - signals=%s hsync=%s,%s vsync=%s,%s field=%s,%s clk=%s\n", + m_setup[0x04] & 0x80 ? "output" : "input", + m_setup[0x04] & 0x40 ? "high" : "low", + m_setup[0x04] & 0x08 ? "blank" : "sync", + m_setup[0x04] & 0x20 ? "high" : "low", + m_setup[0x04] & 0x04 ? "blank" : "sync", + m_setup[0x04] & 0x10 ? "high" : "low", + m_setup[0x04] & 0x02 ? "II" : "I", + m_setup[0x04] & 0x01 ? "qclk_v" : "vclk"); + LOG_OUTPUT_FUNC(" 05 - sp2frm=%s sp2clk=%s sp2=%s sp1frm=%s sp1clk=%s sp1=%s\n", + m_setup[0x05] & 0x80 ? m_setup[0x05] & 0x20 ? "window" : "transition" : "pulse", + m_setup[0x05] & 0x40 ? "output" : "input", + m_setup[0x05] & 0x10 ? "on" : "off", + m_setup[0x05] & 0x08 ? m_setup[0x05] & 0x02 ? "window" : "transition" : "pulse", + m_setup[0x05] & 0x04 ? "output" : "input", + m_setup[0x05] & 0x01 ? "on" : "off"); + LOG_OUTPUT_FUNC(" 06 - serial_audio_mp1=%s fi=%s\n", + m_setup[0x06] & 0x02 ? "yes" : "no", + m_setup[0x06] & 0x01 ? "normal" : "resolution"); + LOG_OUTPUT_FUNC(" 08-21 - active=%dx%d offset=%d,%d total=%dx%d blank=%d,%d front_blank=%d,%d delay=%d,%d, sync=%d,%d\n", + (m_setup[0x08] << 8) | m_setup[0x09], + (m_setup[0x14] << 8) | m_setup[0x15], + (m_setup[0x0a] << 8) | m_setup[0x0b], + (m_setup[0x16] << 8) | m_setup[0x17], + (m_setup[0x0c] << 8) | m_setup[0x0d], + (m_setup[0x18] << 8) | m_setup[0x19], + (m_setup[0x0e] << 8) | m_setup[0x0f], + (m_setup[0x1a] << 8) | m_setup[0x1b], + (m_setup[0x10] << 8) | m_setup[0x11], + (m_setup[0x1c] << 8) | m_setup[0x1d], + (m_setup[0x12] << 8) | m_setup[0x13], + (m_setup[0x1e] << 8) | m_setup[0x1f], + m_setup[0x20], + m_setup[0x21]); + LOG_OUTPUT_FUNC(" 22-29 - crv=%f cbu=%f cgv=%f cgu=%f\n", + u6_10_to_f((m_setup[0x22] << 8) | m_setup[0x23]), + u6_10_to_f((m_setup[0x24] << 8) | m_setup[0x25]), + u6_10_to_f((m_setup[0x26] << 8) | m_setup[0x27]), + u6_10_to_f((m_setup[0x28] << 8) | m_setup[0x29])); + LOG_OUTPUT_FUNC(" 2a-2c - background=%d,%d,%d\n", + m_setup[0x2a], + m_setup[0x2b], + m_setup[0x2c]); + LOG_OUTPUT_FUNC(" 2d - high_byte=%02x\n", + m_setup[0x2d]); + LOG_OUTPUT_FUNC(" 2e-40 - spclk=1/%d,1/%d spbr=%f,%f spdelay=%d,%d vdelay=%d vclk=%d\n", + (m_setup[0x34] << 8) | m_setup[0x35], + (m_setup[0x36] << 8) | m_setup[0x37], + u5_19_to_f((m_setup[0x2e] << 16) | (m_setup[0x2f] << 8) | m_setup[0x30]), + u5_19_to_f((m_setup[0x31] << 16) | (m_setup[0x32] << 8) | m_setup[0x33]), + (m_setup[0x38] << 8) | m_setup[0x39], + (m_setup[0x3a] << 8) | m_setup[0x3b], + (m_setup[0x3c] << 8) | m_setup[0x3d], + (m_setup[0x3e] << 16) | (m_setup[0x3f] << 8) | m_setup[0x40]); + LOG_OUTPUT_FUNC(" 42-44 - sp1id=%02x sp2id=%02x vidid=%02x\n", + m_setup[0x42], + m_setup[0x43], + m_setup[0x44]); +} + +void zr36110_device::setup8_w(u8 data) +{ + m_mc1_adr = 0; + m_mc23_adr = 0; + if(m_setup_adr < 0x80) + m_setup[m_setup_adr] = data; + if(m_setup_adr == 0x80 && (VERBOSE & LOG_SETUP)) + setup_show(); + m_setup_adr = m_setup_adr + 1; +} + +void zr36110_device::cmd8_w(u8 data) +{ + LOG("cmd_w %02x\n", data); + + if(m_cmd_phase) { + m_cmd |= data; + switch(m_cmd & 0xff) { + case 0x00: go(); break; + default: + logerror("Unknown command %02x.%02x\n", m_cmd >> 8, m_cmd & 0xff); + } + } else + m_cmd = data << 8; + m_cmd_phase = !m_cmd_phase; +} + +u8 zr36110_device::stat0_r() +{ + return 0x20 | m_state; +} + +u8 zr36110_device::stat1_r() +{ + return 0x0c; +} + +u8 zr36110_device::stat2_r() +{ + return 0x01; +} + +void zr36110_device::go() +{ + if(m_state != S_IDLE) { + logerror("command GO on wrong state, ignoring\n"); + return; + } + logerror("command GO\n"); + m_bus_control = m_setup[0]; + m_state = S_NORMAL; +} diff --git a/src/devices/video/zr36110.h b/src/devices/video/zr36110.h new file mode 100644 index 00000000000..171e3bd1f53 --- /dev/null +++ b/src/devices/video/zr36110.h @@ -0,0 +1,64 @@ +// license:BSD-3-Clause +// copyright-holders:Olivier Galibert + +// Zoran ZR36110 mpeg video decoder + +#ifndef MAME_VIDEO_ZR36110 +#define MAME_VIDEO_ZR36110 + +#pragma once + +class zr36110_device : public device_t +{ +public: + zr36110_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock); + + auto drq_handler() { return m_drq_handler.bind(); } + + void setup8_w(u8 data); // a = 0 + void mc18_w (u8 data); // a = 1 + void cmd8_w (u8 data); // a = 2 + void mc238_w (u8 data); // a = 3 + + u8 stat0_r(); + u8 stat1_r(); + u8 stat2_r(); + u8 user_r (); // a = 3 + +protected: + void device_start(); + void device_reset(); + +private: + enum { + S_INIT = 0x0, + S_IDLE = 0x1, + S_NORMAL = 0x2, + S_PAUSE = 0x3, + S_STEP = 0x4, + S_DFIRST = 0x6, + S_DNEXT = 0x7, + S_END = 0x8 + }; + + devcb_write_line m_drq_handler; + + u8 m_setup[0x80]; + u32 m_mc1_adr; + u32 m_mc23_adr; + u32 m_setup_adr; + u16 m_cmd; + u8 m_state, m_bus_control; + bool m_cmd_phase; + + static double u6_10_to_f(u16 val); + static double u5_19_to_f(u32 val); + void setup_show() const; + + void go(); +}; + +DECLARE_DEVICE_TYPE(ZR36110, zr36110_device) + +#endif + diff --git a/src/mame/nichibutsu/hrdvd.cpp b/src/mame/nichibutsu/hrdvd.cpp index 2c8ac4561d7..21988ef81c2 100644 --- a/src/mame/nichibutsu/hrdvd.cpp +++ b/src/mame/nichibutsu/hrdvd.cpp @@ -14,15 +14,11 @@ DVD Notes: - - TMP68301 communicates with h8 via their respective internal serial comms - - - TMP sends "?P", h8 answers "P01", TMP tends "?S", h8 answers "NG", games says the dvd drive has a problem - - h8 board components: H8/3002 MN7100 8-bit channel data acquisition system Fujitsu MD0208 - Heatsinked chip (TBD) + Zoran ZR36110PQC IDE and RS232c ports xtal 27 MHz, 12.288MHz @@ -43,6 +39,7 @@ #include "machine/nvram.h" #include "machine/timer.h" #include "video/v9938.h" +#include "video/zr36110.h" #include "nichisnd.h" class hrdvd_ata_controller_device : public abstract_ata_interface_device @@ -67,6 +64,7 @@ public: m_maincpu(*this, "maincpu"), m_subcpu(*this, "subcpu"), m_ata(*this, "ata"), + m_mpeg(*this, "mpeg"), m_nichisnd(*this, "nichisnd"), m_key(*this, "KEY.%u", 0), m_region_maincpu(*this, "maincpu") @@ -75,6 +73,7 @@ public: required_device<tmp68301_device> m_maincpu; required_device<h83002_device> m_subcpu; required_device<hrdvd_ata_controller_device> m_ata; + required_device<zr36110_device> m_mpeg; required_device<nichisnd_device> m_nichisnd; required_ioport_array<5> m_key; required_memory_region m_region_maincpu; @@ -90,11 +89,6 @@ public: uint8_t cs0_r(offs_t offset); void cs0_w(offs_t offset, uint8_t data); - uint8_t sec_r(); - void sec_w(uint8_t data); - void sec2_w(uint8_t data); - void sec3_w(uint8_t data); - uint16_t hrdvd_mux_r(); void hrdvd_mux_w(uint16_t data); void tmp68301_parallel_port_w(uint16_t data); @@ -113,28 +107,6 @@ public: static void dvdrom_config(device_t *device); }; -// Some kind of device a table is sent to -uint8_t hrdvd_state::sec_r() -{ - // Bit 3 means ready for upload - return 0x08; -} - -void hrdvd_state::sec_w(uint8_t data) -{ - // Table is 0xe00 bytes at offset 0x1000 of the h8 rom -} - -void hrdvd_state::sec2_w(uint8_t data) -{ - // Table is 0x1000 bytes at offset 0x1e00 of the h8 rom -} - -void hrdvd_state::sec3_w(uint8_t data) -{ - // Another table, partially hardcoded, partially generated -} - uint16_t hrdvd_state::pb_r() { return m_pb; @@ -218,6 +190,7 @@ void hrdvd_ata_controller_device::write(offs_t offset, uint16_t data, uint16_t m internal_write_cs0(offset * 2, data >> 8, 0xff); } + void hrdvd_state::hrdvd_map(address_map &map) { map(0x000000, 0x03ffff).rom(); @@ -231,6 +204,8 @@ void hrdvd_state::hrdvd_map(address_map &map) map(0x800000, 0xbfffff).rom().region("blit_gfx", 0); // GFX ROM routes here + map(0xc80000, 0xcbffff).ram(); // work RAM + map(0xe80000, 0xefffff).ram(); // work RAM } @@ -238,12 +213,16 @@ void hrdvd_state::hrdvd_sub_map(address_map &map) { map(0x000000, 0x01ffff).rom(); - map(0x020008, 0x020008).w (FUNC(hrdvd_state::sec3_w)); - map(0x02000a, 0x02000a).rw(FUNC(hrdvd_state::sec_r), FUNC(hrdvd_state::sec_w)); - map(0x02000e, 0x02000e).w (FUNC(hrdvd_state::sec2_w)); + map(0x020008, 0x020008).rw(m_mpeg, FUNC(zr36110_device::stat0_r), FUNC(zr36110_device::setup8_w)); + map(0x02000a, 0x02000a).rw(m_mpeg, FUNC(zr36110_device::stat1_r), FUNC(zr36110_device::mc18_w)); + map(0x02000c, 0x02000c).rw(m_mpeg, FUNC(zr36110_device::stat2_r), FUNC(zr36110_device::cmd8_w)); + map(0x02000e, 0x02000e). w(m_mpeg, FUNC(zr36110_device::mc238_w)); + map(0x040018, 0x040019).rw(m_ata, FUNC(hrdvd_ata_controller_device::dma_read), FUNC(hrdvd_ata_controller_device::dma_write)); map(0x040028, 0x04002f).rw(m_ata, FUNC(hrdvd_ata_controller_device::read), FUNC(hrdvd_ata_controller_device::write)); + map(0x060000, 0x06bfff).ram(); + map(0x078000, 0x07ffff).mirror(0xf80000).ram(); //.share("nvram"); } @@ -253,7 +232,6 @@ void hrdvd_state::hrdvd_sub_io_map(address_map &map) map(h8_device::PORT_A, h8_device::PORT_A).w (FUNC(hrdvd_state::pa_w)); map(h8_device::PORT_B, h8_device::PORT_B).rw(FUNC(hrdvd_state::pb_r), FUNC(hrdvd_state::pb_w)); // map(h8_device::PORT_6, h8_device::PORT_6).noprw(); -// map(h8_device::PORT_A, h8_device::PORT_A).nopw(); } @@ -420,6 +398,7 @@ WRITE_LINE_MEMBER(hrdvd_state::ata_drq) { // logerror("ata drq %d\n", state); m_pb = (m_pb & 0x7f) | (state ? 0x00 : 0x80); + m_subcpu->set_input_line(H8_INPUT_LINE_DREQ1, state); } void hrdvd_state::tmp68301_parallel_port_w(uint16_t data) @@ -471,6 +450,9 @@ void hrdvd_state::hrdvd(machine_config &config) v9958.int_cb().set_inputline(m_maincpu, 0); SCREEN(config, "screen", SCREEN_TYPE_RASTER); + ZR36110(config, m_mpeg, 27_MHz_XTAL/2); + m_mpeg->drq_handler().set_inputline(m_maincpu, H8_INPUT_LINE_DREQ0); + /* sound hardware */ NICHISND(config, m_nichisnd, 0); } |
