zr36110: Add skeleton

hrdvd: Hook up the mpeg chip
This commit is contained in:
Olivier Galibert 2023-05-07 13:03:25 +02:00
parent 8f05076b07
commit 029264ad48
7 changed files with 325 additions and 47 deletions

View File

@ -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

View File

@ -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();
}

View File

@ -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)

View File

@ -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) {

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}