Skip to content

Commit a3bdebb

Browse files
committed
pci/zr36057.cpp: preliminary PostOffice interactions, kick off enough glue logic with a ZR36060 so that DC10+ passes board tests
1 parent 4f8fb4b commit a3bdebb

File tree

6 files changed

+333
-21
lines changed

6 files changed

+333
-21
lines changed

scripts/src/video.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1697,6 +1697,18 @@ if (VIDEOS["X1_001"]~=null) then
16971697
}
16981698
end
16991699

1700+
--------------------------------------------------
1701+
--
1702+
--@src/devices/video/zr36060.h,VIDEOS["ZR36060"] = true
1703+
--------------------------------------------------
1704+
1705+
if (VIDEOS["ZR36060"]~=null) then
1706+
files {
1707+
MAME_DIR .. "src/devices/video/zr36060.cpp",
1708+
MAME_DIR .. "src/devices/video/zr36060.h",
1709+
}
1710+
end
1711+
17001712
--------------------------------------------------
17011713
--
17021714
--@src/devices/video/zr36110.h,VIDEOS["ZR36110"] = true

src/devices/bus/pci/zr36057.cpp

Lines changed: 158 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ iterations.
1414
ZR36057 is known to have two HW quirks that are been fixed with ZR36067.
1515
1616
TODO:
17-
- Currently at dc10plus HW test "Error at M-JPEG codec", requires ZR36060 to continue;
17+
- Enough to pass board functions in dc10plus HW test, requires VSYNC signal from ZR36060 to continue;
1818
- Hookup busmaster;
1919
- What are i2c 0x8e >> 1 address device checks for?
2020
\- Can't be adv7175 (0xd4 >> 1) nor adv7176 (0x54 >> 1)
2121
...
2222
- Soft Reset & Write lock mechanisms (each register have separate macro-groups);
23+
- GuestBus slot mechanism (relevant when multiple devices are hooked);
2324
- eventually decouple AV PCI controller part from the actual client cards;
2425
2526
Known mix-ins:
@@ -37,20 +38,22 @@ Known mix-ins:
3738
#include "zr36057.h"
3839

3940
#define LOG_WARN (1U << 1)
41+
#define LOG_PO (1U << 2) // PostOffice interactions
4042

41-
#define VERBOSE (LOG_GENERAL | LOG_WARN)
43+
#define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_PO)
4244
//#define LOG_OUTPUT_FUNC osd_printf_info
4345
#include "logmacro.h"
4446

4547
#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
46-
48+
#define LOGPO(...) LOGMASKED(LOG_PO, __VA_ARGS__)
4749

4850
DEFINE_DEVICE_TYPE(ZR36057_PCI, zr36057_device, "zr36057", "Zoran ZR36057-based Enhanced Multimedia Controller")
4951
//DEFINE_DEVICE_TYPE(ZR36067_PCI, zr36067_device, "zr36067", "Zoran ZR36067-based AV Controller")
5052

5153

5254
zr36057_device::zr36057_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
5355
: pci_card_device(mconfig, type, tag, owner, clock)
56+
, m_guest(*this, "guest")
5457
, m_decoder(*this, "decoder")
5558
{
5659
// ZR36057PQC Video cutting chipset
@@ -73,11 +76,13 @@ zr36057_device::zr36057_device(const machine_config &mconfig, const char *tag, d
7376

7477
void zr36057_device::device_add_mconfig(machine_config &config)
7578
{
76-
// 27'000'000 xtal near ZR36060
79+
ZR36060(config, m_guest, XTAL(27'000'000));
7780

7881
SAA7110A(config, m_decoder, XTAL(26'800'000));
7982
m_decoder->sda_callback().set([this](int state) { m_decoder_sdao_state = state; });
8083

84+
//ADV7176(config, m_encoder, XTAL(27'000'000));
85+
8186
// S-Video input/output
8287
// composite video input/output
8388

@@ -116,15 +121,27 @@ void zr36057_device::device_reset()
116121
void zr36057_device::software_reset()
117122
{
118123
LOG("SoftReset\n");
119-
m_video_frontend.horizontal_config = (0 << 30) | (0x001 << 10) | (0x3ff << 0);
120-
m_video_frontend.vertical_config = (0 << 30) | (0x001 << 10) | (0x3ff << 0);
124+
m_vfe.hspol = m_vfe.vspol = 0;
125+
m_vfe.hstart = m_vfe.vstart = 0x001;
126+
m_vfe.hend = m_vfe.vend = 0x3ff;
127+
m_vfe.horizontal_config = (m_vfe.hspol << 30) | (m_vfe.hstart << 10) | (m_vfe.hend << 0);
128+
m_vfe.vertical_config = (m_vfe.vspol << 30) | (m_vfe.vstart << 10) | (m_vfe.vend << 0);
121129

122130
m_pci_waitstate_control = 0;
123131
m_gpio_ddr = 0xff; // all inputs
124132
// GuestBus ID default
125133
// m_gpio_data = 0xf0;
126134
for (int i = 0; i < 4; i++)
127135
m_guestbus.time[i] = 0;
136+
137+
m_jpeg_guest_id = 4;
138+
m_jpeg_guest_reg = 0;
139+
140+
m_po.pending = false;
141+
m_po.time_out = false;
142+
m_po.dir = true;
143+
m_po.guest_id = 0;
144+
m_po.guest_reg = 0;
128145
}
129146

130147
void zr36057_device::config_map(address_map &map)
@@ -134,33 +151,46 @@ void zr36057_device::config_map(address_map &map)
134151
map(0x3f, 0x3f).lr8(NAME([] () { return 0x10; }));
135152
}
136153

137-
// Application Specific Register
154+
// Application Specific Register(s)
138155
void zr36057_device::asr_map(address_map &map)
139156
{
140157
map(0x000, 0x003).lrw32(
141158
NAME([this] (offs_t offset) {
142159
// NOTE: wants to read-back here, throws "Bus Master ASIC error" otherwise (?)
143160
LOG("Video Front End Horizontal Configuration R\n");
144-
return m_video_frontend.horizontal_config;
161+
return m_vfe.horizontal_config;
145162
}),
146163
NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
147-
COMBINE_DATA(&m_video_frontend.horizontal_config);
164+
COMBINE_DATA(&m_vfe.horizontal_config);
148165
LOG("Video Front End Horizontal Configuration W %08x & %08x\n", data, mem_mask);
166+
m_vfe.hspol = BIT(m_vfe.horizontal_config, 30);
167+
m_vfe.hstart = (m_vfe.horizontal_config >> 10) & 0x3ff;
168+
m_vfe.hend = (m_vfe.horizontal_config >> 0) & 0x3ff;
169+
LOG("\tVSPOL %d VSTART %d VEND %d\n", m_vfe.hspol, m_vfe.hstart, m_vfe.hend);
149170
})
150171
);
151172
map(0x004, 0x007).lrw32(
152173
NAME([this] (offs_t offset) {
153174
LOG("Video Front End Vertical Configuration R\n");
154-
return m_video_frontend.vertical_config;
175+
return m_vfe.vertical_config;
155176
}),
156177
NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
157-
COMBINE_DATA(&m_video_frontend.vertical_config);
178+
COMBINE_DATA(&m_vfe.vertical_config);
158179
LOG("Video Front End Vertical Configuration %08x & %08\n", data, mem_mask);
180+
m_vfe.vspol = BIT(m_vfe.vertical_config, 30);
181+
m_vfe.vstart = (m_vfe.vertical_config >> 10) & 0x3ff;
182+
m_vfe.vend = (m_vfe.vertical_config >> 0) & 0x3ff;
183+
LOG("\tVSPOL %d VSTART %d VEND %d\n", m_vfe.vspol, m_vfe.vstart, m_vfe.vend);
159184
})
160185
);
161-
162-
// ...
163-
186+
// map(0x008, 0x00b) VFE Config, Video Scaler and Pixel Format
187+
// map(0x00c, 0x00f) Video Display Top
188+
// map(0x010, 0x013) Video Display Bottom
189+
// map(0x014, 0x017) Video Display Stride, Status and Frame Grab
190+
// map(0x018, 0x01b) Video Display Configuration
191+
// map(0x01c, 0x01f) Masking Map Top
192+
// map(0x020, 0x023) Masking Map Bottom
193+
// map(0x024, 0x027) Overlay Control
164194
map(0x028, 0x02b).lrw32(
165195
NAME([this] (offs_t offset) {
166196
return (m_softreset << 24) | (m_pci_waitstate_control << 16) | m_gpio_ddr;
@@ -191,6 +221,7 @@ void zr36057_device::asr_map(address_map &map)
191221

192222
// The doc claims 0xf0 default for GPIO, but win98 driver will throw "subvendor ID failed"
193223
// while testing various ID combinations here
224+
// This should come from GDAT pin at strapping time
194225
return (0x7e << 24) | (m_guestbus.time[3] << 12) | (m_guestbus.time[2] << 8) | (m_guestbus.time[1] << 4) | (m_guestbus.time[0] << 0);
195226
}),
196227
NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
@@ -212,7 +243,11 @@ void zr36057_device::asr_map(address_map &map)
212243
}
213244
})
214245
);
215-
246+
// map(0x030, 0x033) MPEG Code Source Address
247+
// map(0x034, 0x037) MPEG Code Transfer Control
248+
// map(0x038, 0x03b) MPEG Code Memory Pointer
249+
// map(0x03c, 0x03f) Interrupt Status
250+
// map(0x040, 0x043) Interrupt Control
216251
map(0x044, 0x047).lrw32(
217252
NAME([this] (offs_t offset) {
218253
LOG("I2C R\n");
@@ -229,4 +264,112 @@ void zr36057_device::asr_map(address_map &map)
229264
}
230265
})
231266
);
267+
// map(0x100, 0x103) JPEG Mode and Control
268+
// map(0x104, 0x107) JPEG Process Control
269+
// map(0x108, 0x10b) Vertical Sync Parameters (as sync master)
270+
// map(0x10c, 0x10f) Horizontal Sync Parameters (as sync master)
271+
// map(0x110, 0x113) Field Horizontal Active Portion
272+
// map(0x114, 0x117) Field Vertical Active Portion
273+
// map(0x118, 0x11b) Field Process Parameters
274+
// map(0x11c, 0x11f) JPEG Code Base Address
275+
// map(0x120, 0x123) JPEG Code FIFO Threshold
276+
map(0x124, 0x124).lrw8(
277+
NAME([this] (offs_t offset) {
278+
LOG("JPEG Codec Guest ID R\n");
279+
return (m_jpeg_guest_id << 4) | (m_jpeg_guest_reg << 0);
280+
}),
281+
NAME([this] (offs_t offset, u8 data) {
282+
m_jpeg_guest_id = (data >> 4) & 7;
283+
m_jpeg_guest_reg = (data >> 0) & 7;
284+
LOG("JPEG Codec Guest ID W %02x\n", data);
285+
})
286+
);
287+
map(0x12c, 0x12f).lrw32(
288+
NAME([this] (offs_t offset) {
289+
LOG("GuestBus Control (II) R\n");
290+
291+
return (0 << 16) | (m_guestbus.time[7] << 12) | (m_guestbus.time[6] << 8) | (m_guestbus.time[5] << 4) | (m_guestbus.time[4] << 0);
292+
}),
293+
NAME([this] (offs_t offset, u32 data, u32 mem_mask) {
294+
LOG("GuestBus Control (II) W %08x & %08x\n", data, mem_mask);
295+
296+
if (ACCESSING_BITS_8_15)
297+
{
298+
m_guestbus.time[7] = (data >> 12) & 0xf;
299+
m_guestbus.time[6] = (data >> 8) & 0xf;
300+
}
301+
302+
if (ACCESSING_BITS_0_7)
303+
{
304+
m_guestbus.time[5] = (data >> 4) & 0xf;
305+
m_guestbus.time[4] = (data >> 0) & 0xf;
306+
}
307+
})
308+
);
309+
310+
map(0x200, 0x2ff).rw(FUNC(zr36057_device::postoffice_r), FUNC(zr36057_device::postoffice_w));
311+
// map(0x300, 0x303) Still Transfer
312+
}
313+
314+
// TODO: PostOffice accesses thru GuestBus are dictated with PCI clock cycles, asynchronous
315+
// We pretend they are synchronous as a starting point, and one port only (which may matter later
316+
// with CODE transfers). A time out happens 64 PCI cycles later in ZR36067, '120 halves that threshold.
317+
// This should eventually be expressed in a osd_work_queue, with guestbus address_space roughly as:
318+
// for (int i = 0; i < 8; i++)
319+
// {
320+
// if (<is_device_installed>)
321+
// map(0 | (i << 2), 3 | (i << 2)).flags(<fn>).m(m_guest[i], map);
322+
// else
323+
// map(0 | (i << 2), 3 | (i << 2)).flags(<abort_fn>);
324+
// }
325+
u32 zr36057_device::postoffice_r(offs_t offset)
326+
{
327+
//LOGPO("PO R %d %d\n", m_po.guest_id, m_po.guest_reg);
328+
u8 res = 0;
329+
if (m_po.guest_id == 0)
330+
{
331+
if (m_po.dir == false)
332+
res = m_guest->read(m_po.guest_reg);
333+
}
334+
else if (!machine().side_effects_disabled())
335+
{
336+
m_po.time_out = true;
337+
LOGWARN("Warning: PO access unmapped POGuestID read %d %02x\n", m_po.guest_id, m_po.guest_reg);
338+
}
339+
340+
return (m_po.pending << 25)
341+
| (m_po.time_out << 24)
342+
| (m_po.dir << 23)
343+
| (m_po.guest_id << 20)
344+
| (m_po.guest_reg << 16)
345+
| res;
346+
}
347+
348+
void zr36057_device::postoffice_w(offs_t offset, u32 data, u32 mem_mask)
349+
{
350+
// clear a previously set time out flag
351+
if (BIT(data, 24))
352+
m_po.time_out = false;
353+
m_po.dir = !!(BIT(data, 23));
354+
m_po.guest_id = (data >> 20) & 7;
355+
m_po.guest_reg = (data >> 16) & 7;
356+
LOGPO("PO W [%08x] %08x & %08x PODir %s POGuestID %d POGuestReg %d POData %02x\n"
357+
, offset << 2
358+
, data
359+
, mem_mask
360+
, m_po.dir ? "Write" : "Read"
361+
, m_po.guest_id
362+
, m_po.guest_reg
363+
, data & 0xff
364+
);
365+
if (m_po.guest_id == 0)
366+
{
367+
if (m_po.dir == true)
368+
m_guest->write(m_po.guest_reg, data & 0xff);
369+
}
370+
else
371+
{
372+
m_po.time_out = true;
373+
LOGWARN("Warning: PO access unmapped POGuestID write %d %02x\n", m_po.guest_id, m_po.guest_reg);
374+
}
232375
}

src/devices/bus/pci/zr36057.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "pci_slot.h"
1010
#include "video/saa7110.h"
11+
#include "video/zr36060.h"
1112

1213
class zr36057_device : public pci_card_device
1314
{
@@ -25,29 +26,42 @@ class zr36057_device : public pci_card_device
2526

2627
// virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
2728

28-
// virtual void map_extra(uint64_t memory_window_start, uint64_t memory_window_end, uint64_t memory_offset, address_space *memory_space,
29-
// uint64_t io_window_start, uint64_t io_window_end, uint64_t io_offset, address_space *io_space) override;
30-
3129
virtual void config_map(address_map &map) override ATTR_COLD;
3230

3331
private:
32+
required_device<zr36060_device> m_guest;
3433
required_device<saa7110a_device> m_decoder;
3534
void asr_map(address_map &map) ATTR_COLD;
3635

3736
void software_reset();
37+
u32 postoffice_r(offs_t offset);
38+
void postoffice_w(offs_t offset, u32 data, u32 mem_mask);
3839

40+
// Video Front End
3941
struct {
4042
u32 horizontal_config;
4143
u32 vertical_config;
42-
} m_video_frontend;
44+
int hspol, vspol;
45+
u16 hstart, hend, vstart, vend;
46+
} m_vfe;
47+
48+
u8 m_jpeg_guest_id, m_jpeg_guest_reg;
4349

4450
bool m_softreset;
4551
u8 m_gpio_ddr, m_pci_waitstate_control;
4652

4753
struct {
48-
u8 time[4];
54+
u8 time[8];
4955
} m_guestbus;
5056

57+
struct {
58+
bool dir; /**< true: Write, false: Read */
59+
bool time_out;
60+
bool pending;
61+
u8 guest_id;
62+
u8 guest_reg;
63+
} m_po; /**< PostOffice */
64+
5165
int m_decoder_sdao_state;
5266
};
5367

0 commit comments

Comments
 (0)