@@ -14,12 +14,13 @@ iterations.
14
14
ZR36057 is known to have two HW quirks that are been fixed with ZR36067.
15
15
16
16
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;
18
18
- Hookup busmaster;
19
19
- What are i2c 0x8e >> 1 address device checks for?
20
20
\- Can't be adv7175 (0xd4 >> 1) nor adv7176 (0x54 >> 1)
21
21
...
22
22
- Soft Reset & Write lock mechanisms (each register have separate macro-groups);
23
+ - GuestBus slot mechanism (relevant when multiple devices are hooked);
23
24
- eventually decouple AV PCI controller part from the actual client cards;
24
25
25
26
Known mix-ins:
@@ -37,20 +38,22 @@ Known mix-ins:
37
38
#include " zr36057.h"
38
39
39
40
#define LOG_WARN (1U << 1 )
41
+ #define LOG_PO (1U << 2 ) // PostOffice interactions
40
42
41
- #define VERBOSE (LOG_GENERAL | LOG_WARN)
43
+ #define VERBOSE (LOG_GENERAL | LOG_WARN | LOG_PO )
42
44
// #define LOG_OUTPUT_FUNC osd_printf_info
43
45
#include " logmacro.h"
44
46
45
47
#define LOGWARN (...) LOGMASKED(LOG_WARN, __VA_ARGS__)
46
-
48
+ # define LOGPO (...) LOGMASKED(LOG_PO, __VA_ARGS__)
47
49
48
50
DEFINE_DEVICE_TYPE (ZR36057_PCI, zr36057_device, " zr36057" , " Zoran ZR36057-based Enhanced Multimedia Controller" )
49
51
// DEFINE_DEVICE_TYPE(ZR36067_PCI, zr36067_device, "zr36067", "Zoran ZR36067-based AV Controller")
50
52
51
53
52
54
zr36057_device::zr36057_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
53
55
: pci_card_device(mconfig, type, tag, owner, clock)
56
+ , m_guest(*this , " guest" )
54
57
, m_decoder(*this , " decoder" )
55
58
{
56
59
// ZR36057PQC Video cutting chipset
@@ -73,11 +76,13 @@ zr36057_device::zr36057_device(const machine_config &mconfig, const char *tag, d
73
76
74
77
void zr36057_device::device_add_mconfig (machine_config &config)
75
78
{
76
- // 27'000'000 xtal near ZR36060
79
+ ZR36060 (config, m_guest, XTAL ( 27'000'000 ));
77
80
78
81
SAA7110A (config, m_decoder, XTAL (26'800'000 ));
79
82
m_decoder->sda_callback ().set ([this ](int state) { m_decoder_sdao_state = state; });
80
83
84
+ // ADV7176(config, m_encoder, XTAL(27'000'000));
85
+
81
86
// S-Video input/output
82
87
// composite video input/output
83
88
@@ -116,15 +121,27 @@ void zr36057_device::device_reset()
116
121
void zr36057_device::software_reset ()
117
122
{
118
123
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 );
121
129
122
130
m_pci_waitstate_control = 0 ;
123
131
m_gpio_ddr = 0xff ; // all inputs
124
132
// GuestBus ID default
125
133
// m_gpio_data = 0xf0;
126
134
for (int i = 0 ; i < 4 ; i++)
127
135
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 ;
128
145
}
129
146
130
147
void zr36057_device::config_map (address_map &map)
@@ -134,33 +151,46 @@ void zr36057_device::config_map(address_map &map)
134
151
map (0x3f , 0x3f ).lr8 (NAME ([] () { return 0x10 ; }));
135
152
}
136
153
137
- // Application Specific Register
154
+ // Application Specific Register(s)
138
155
void zr36057_device::asr_map (address_map &map)
139
156
{
140
157
map (0x000 , 0x003 ).lrw32 (
141
158
NAME ([this ] (offs_t offset) {
142
159
// NOTE: wants to read-back here, throws "Bus Master ASIC error" otherwise (?)
143
160
LOG (" Video Front End Horizontal Configuration R\n " );
144
- return m_video_frontend .horizontal_config ;
161
+ return m_vfe .horizontal_config ;
145
162
}),
146
163
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 );
148
165
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 (" \t VSPOL %d VSTART %d VEND %d\n " , m_vfe.hspol , m_vfe.hstart , m_vfe.hend );
149
170
})
150
171
);
151
172
map (0x004 , 0x007 ).lrw32 (
152
173
NAME ([this ] (offs_t offset) {
153
174
LOG (" Video Front End Vertical Configuration R\n " );
154
- return m_video_frontend .vertical_config ;
175
+ return m_vfe .vertical_config ;
155
176
}),
156
177
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 );
158
179
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 (" \t VSPOL %d VSTART %d VEND %d\n " , m_vfe.vspol , m_vfe.vstart , m_vfe.vend );
159
184
})
160
185
);
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
164
194
map (0x028 , 0x02b ).lrw32 (
165
195
NAME ([this ] (offs_t offset) {
166
196
return (m_softreset << 24 ) | (m_pci_waitstate_control << 16 ) | m_gpio_ddr;
@@ -191,6 +221,7 @@ void zr36057_device::asr_map(address_map &map)
191
221
192
222
// The doc claims 0xf0 default for GPIO, but win98 driver will throw "subvendor ID failed"
193
223
// while testing various ID combinations here
224
+ // This should come from GDAT pin at strapping time
194
225
return (0x7e << 24 ) | (m_guestbus.time [3 ] << 12 ) | (m_guestbus.time [2 ] << 8 ) | (m_guestbus.time [1 ] << 4 ) | (m_guestbus.time [0 ] << 0 );
195
226
}),
196
227
NAME ([this ] (offs_t offset, u32 data, u32 mem_mask) {
@@ -212,7 +243,11 @@ void zr36057_device::asr_map(address_map &map)
212
243
}
213
244
})
214
245
);
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
216
251
map (0x044 , 0x047 ).lrw32 (
217
252
NAME ([this ] (offs_t offset) {
218
253
LOG (" I2C R\n " );
@@ -229,4 +264,112 @@ void zr36057_device::asr_map(address_map &map)
229
264
}
230
265
})
231
266
);
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
+ }
232
375
}
0 commit comments