1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /***************************************************************************
4
5 3DO M2 Bulldog ASIC
6
7 ***************************************************************************/
8
9 #include "emu.h"
10 #include "3dom2.h"
11
12 #include <algorithm> // std::min
13
14
15 //**************************************************************************
16 // MACROS / CONSTANTS
17 //**************************************************************************
18
19 // Device type definitions
20 DEFINE_DEVICE_TYPE(M2_BDA, m2_bda_device, "m2bda", "3DO M2 Bulldog ASIC")
21 DEFINE_DEVICE_TYPE(M2_POWERBUS, m2_powerbus_device, "m2powerbus", "BDA PowerBus Controller")
22 DEFINE_DEVICE_TYPE(M2_MEMCTL, m2_memctl_device, "m2memctl", "BDA Memory Controller")
23 DEFINE_DEVICE_TYPE(M2_VDU, m2_vdu_device, "m2vdu", "BDA VDU")
24 DEFINE_DEVICE_TYPE(M2_CTRLPORT, m2_ctrlport_device, "m2ctrlport", "BDA Control Ports")
25 DEFINE_DEVICE_TYPE(M2_MPEG, m2_mpeg_device, "m2mpeg", "3DO MPEG Decoder")
26 DEFINE_DEVICE_TYPE(M2_CDE, m2_cde_device, "m2cde", "3DO M2 CDE ASIC")
27
28
29
30 //**************************************************************************
31 // VDU REGISTER DEFINITIONS
32 //**************************************************************************
33
34 #define VDU_VLOC 0x00
35 #define VDU_VINT 0x04
36 #define VDU_VDC0 0x08
37 #define VDU_VDC1 0x0c
38 #define VDU_FV0A 0x10
39 #define VDU_FV1A 0x14
40 #define VDU_AVDI 0x1c
41 #define VDU_VDLI 0x20
42 #define VDU_VCFG 0x24
43 #define VDU_DMT0 0x28
44 #define VDU_DMT1 0x2c
45 #define VDU_LFSR 0x30
46 #define VDU_VRST 0x34
47
48 //-------------------------------------------------
49 // VLOC
50 //-------------------------------------------------
51 #define VDU_VLOC_VCOUNT_MASK 0x00003FF8
52 #define VDU_VLOC_VCOUNT_SHIFT 3
53 #define VDU_VLOC_VIDEOFIELD 0x00004000
54 #define VDU_VLOC_RESERVED 0xFFFF8007
55
56 //-------------------------------------------------
57 // VINT
58 //-------------------------------------------------
59 #define VDU_VINT_VINT0 0x80000000
60 #define VDU_VINT_VLINE0_MASK 0x7FF00000
61 #define VDU_VINT_VLINE0_SHIFT 20
62 #define VDU_VINT_VINT1 0x00008000
63 #define VDU_VINT_VLINE1_MASK 0x00007FF0
64 #define VDU_VINT_VLINE1_SHIFT 4
65 #define VDU_VINT_RESERVED 0x000F000F
66
67 //-------------------------------------------------
68 // VDC0/VDC1
69 //-------------------------------------------------
70 #define VDU_VDC_HINT 0x02000000
71 #define VDU_VDC_VINT 0x01000000
72 #define VDU_VDC_DITHER 0x00400000
73 #define VDU_VDC_MTXBYP 0x00200000
74 #define VDU_VDC_RESERVED 0xFC9FFFFF
75
76 //-------------------------------------------------
77 // AVDI
78 //-------------------------------------------------
79 #define VDU_AVDI_HSTART_MASK 0xFFE00000
80 #define VDU_AVDI_HWIDTH_MASK 0x0003FF80
81 #define VDU_AVDI_HDOUBLE 0x00000008
82 #define VDU_AVDI_VDOUBLE 0x00000004
83 #define VDU_AVDI_RESERVED 0x001C0073
84 #define VDU_AVDI_HSTART_SHIFT 21
85 #define VDU_AVDI_HWIDTH_SHIFT 7
86
87 //-------------------------------------------------
88 // VDLI
89 //-------------------------------------------------
90 #define VDU_VDLI_BYPASSTYPE 0x10000000
91 #define VDU_VDLI_FBFORMAT 0x04000000
92 #define VDU_VDLI_ONEVINTDIS 0x00400000
93 #define VDU_VDLI_RANDOMDITHER 0x00200000
94 #define VDU_VDLI_RESERVED 0xEB9FFFFF
95 #define VDU_VDLI_BYPASSTYPE_MSB 0
96 #define VDU_VDLI_BYPASSTYPE_LSB 0x10000000
97 #define VDU_VDLI_FBFORMAT_16 0
98 #define VDU_VDLI_FBFORMAT_32 0x04000000
99
100 //-------------------------------------------------
101 // VCFG
102 //-------------------------------------------------
103
104 //-------------------------------------------------
105 // VRST
106 //-------------------------------------------------
107 #define VDU_VRST_DVERESET 0x00000002
108 #define VDU_VRST_VIDRESET 0x00000001
109 #define VDU_VRST_RESERVED 0xFFFFFFFC
110
111
112 //-------------------------------------------------
113 // VDL DMA CONTROL WORD
114 //-------------------------------------------------
115 #define VDL_DMA_MOD_MASK 0xFF000000
116 #define VDL_DMA_ENABLE 0x00200000
117 #define VDL_DMA_NOBUCKET 0x00020000
118 #define VDL_DMA_LDLOWER 0x00010000
119 #define VDL_DMA_LDUPPER 0x00008000
120 #define VDL_DMA_NWORDS_MASK 0x00007E00
121 #define VDL_DMA_NLINES_MASK 0x000001FF
122 #define VDL_DMA_RESERVED 0x00DC0000
123 #define VDL_DMA_NWORDS_SHIFT 9
124 #define VDL_DMA_MOD_SHIFT 24
125 #define VDL_DMA_NLINES_SHIFT 0
126
127 //-------------------------------------------------
128 // VDL DC CONTROL WORD
129 //-------------------------------------------------
130 #define VDL_DC 0x80000000
131 #define VDL_DC_0 0x00000000
132 #define VDL_DC_1 0x10000000
133 #define VDL_DC_HINTCTL_MASK 0x00060000
134 #define VDL_DC_HINTCTL_SHIFT 17
135 #define VDL_DC_VINTCTL_MASK 0x00018000
136 #define VDL_DC_VINTCTL_SHIFT 15
137 #define VDL_DC_DITHERCTL_MASK 0x00001800
138 #define VDL_DC_DITHERCTL_SHIFT 11
139 #define VDL_DC_MTXBYPCTL_MASK 0x00000600
140 #define VDL_DC_MTXBYPCTL_SHIFT 9
141 #define VDL_DC_RESERVED 0x0FF861FF
142 #define VDL_CTL_DISABLE 0
143 #define VDL_CTL_ENABLE 1
144 #define VDL_CTL_NOP 2
145
146 //-------------------------------------------------
147 // VDL AV CONTROL WORD
148 //-------------------------------------------------
149 #define VDL_AV 0xA0000000
150 #define VDL_AV_HSTART_MASK 0x1FFC0000
151 #define VDL_AV_HSTART_SHIFT 18
152 #define VDL_AV_LD_HSTART 0x00020000
153 #define VDL_AV_HWIDTH_MASK 0x0001FFC0
154 #define VDL_AV_HWIDTH_SHIFT 6
155 #define VDL_AV_LD_HWIDTH 0x00000020
156 #define VDL_AV_HDOUBLE 0x00000010
157 #define VDL_AV_VDOUBLE 0x00000008
158 #define VDL_AV_LD_HDOUBLE 0x00000004
159 #define VDL_AV_LD_VDOUBLE 0x00000002
160 #define VDL_AV_RESERVED 0x00000001
161
162 //-------------------------------------------------
163 // VDL LC CONTROL WORD
164 //-------------------------------------------------
165 #define VDL_LC 0xC0000000
166 #define VDL_LC_BYPASSTYPE 0x02000000
167 #define VDL_LC_FBFORMAT 0x00800000
168 #define VDL_LC_ONEVINTDIS 0x00080000
169 #define VDL_LC_RANDOMDITHER 0x00040000
170 #define VDL_LC_LD_BYPASSTYPE 0x00002000
171 #define VDL_LC_LD_FBFORMAT 0x00001000
172 #define VDL_LC_RESERVED 0x1D73CFFF
173 #define VDL_LC_BYPASSTYPE_MSB 0x00000000
174 #define VDL_LC_BYPASSTYPE_LSB 0x02000000
175 #define VDL_LC_FBFORMAT_16 0x00000000
176 #define VDL_LC_FBFORMAT_32 0x00800000
177
178 //-------------------------------------------------
179 // VDL DMA CONTROL WORD
180 //-------------------------------------------------
181
182 #define VDL_NOP 0xe1000000
183
184
185
186 /***************************************************************************
187 SUPPORT FUNCTIONS
188 ***************************************************************************/
189
write_m2_reg(uint32_t & reg,uint32_t data,m2_reg_wmode mode)190 static void write_m2_reg(uint32_t ®, uint32_t data, m2_reg_wmode mode)
191 {
192 switch (mode)
193 {
194 case REG_WRITE: reg = data; break;
195 case REG_SET: reg |= data; break;
196 case REG_CLEAR: reg &= ~data; break;
197 default:
198 throw emu_fatalerror("write_m2_reg: Bad register write mode");
199 }
200 }
201
202
203
204 //**************************************************************************
205 // BDA DEVICE
206 //**************************************************************************
207
208 //-------------------------------------------------
209 // m2_bda_device - constructor
210 //-------------------------------------------------
211
m2_bda_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)212 m2_bda_device::m2_bda_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
213 device_t(mconfig, M2_BDA, tag, owner, clock),
214 m_cpu1(*this, finder_base::DUMMY_TAG),
215 m_cpu2(*this, finder_base::DUMMY_TAG),
216 m_cde(*this, finder_base::DUMMY_TAG),
217 m_videores_in(*this),
218 m_memctl(*this, "memctl"),
219 m_powerbus(*this, "powerbus"),
220 m_vdu(*this, "vdu"),
221 m_ctrlport(*this, "ctrlport"),
222 m_dspp(*this, "dspp"),
223 m_mpeg(*this, "mpeg"),
224 m_te(*this, "te"),
225 m_dac_l(*this),
226 m_dac_r(*this)
227 {
228 }
229
230
231 //-------------------------------------------------
232 // device_start - device-specific startup
233 //-------------------------------------------------
234
device_start()235 void m2_bda_device::device_start()
236 {
237 // Resolve callbacks
238 m_videores_in.resolve_safe(0);
239 m_dac_l.resolve_safe();
240 m_dac_r.resolve_safe();
241
242 // Allocate RAM
243 uint32_t ram_size = (m_rambank_size[0] + m_rambank_size[1]) * 1024 * 1024;
244 m_ram = auto_alloc_array(machine(), uint32_t, ram_size / sizeof(uint32_t));
245 m_ram_mask = ram_size - 1;
246
247 // Install RAM and handlers into the CPU address spaces
248 configure_ppc_address_map(m_cpu1->space(AS_PROGRAM));
249 configure_ppc_address_map(m_cpu2->space(AS_PROGRAM));
250
251 // Register state for saving
252 save_pointer(NAME(m_ram), ram_size / sizeof(uint32_t));
253
254 // Set a timer to pull data from the DSPP FIFO into the DACs
255 m_dac_timer = timer_alloc(0);
256 m_dac_timer->adjust(attotime::from_hz(16.9345));
257 }
258
259
260 //-------------------------------------------------
261 // device_reset - device-specific reset
262 //-------------------------------------------------
263
device_reset()264 void m2_bda_device::device_reset()
265 {
266
267 }
268
269
270 //-------------------------------------------------
271 // device_post_load - device-specific post-load
272 //-------------------------------------------------
273
device_post_load()274 void m2_bda_device::device_post_load()
275 {
276
277 }
278
279
280 //-------------------------------------------------
281 // machine_config_fragment - declare sub-devices
282 //-------------------------------------------------
283
device_add_mconfig(machine_config & config)284 void m2_bda_device::device_add_mconfig(machine_config &config)
285 {
286 M2_MEMCTL(config, m_memctl, DERIVED_CLOCK(1, 1));
287
288 M2_POWERBUS(config, m_powerbus, DERIVED_CLOCK(1, 1));
289
290 M2_VDU(config, m_vdu, DERIVED_CLOCK(1, 1));
291 m_vdu->vint0_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_VINT0_LINE>));
292 m_vdu->vint1_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_VINT1_LINE>));
293
294 M2_CTRLPORT(config, m_ctrlport, DERIVED_CLOCK(1, 1));
295
296 M2_MPEG(config, m_mpeg, DERIVED_CLOCK(1, 1));
297 // m_mpeg->int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_MPEG_LINE>));
298
299 DSPP(config, m_dspp, DERIVED_CLOCK(1, 1));
300 m_dspp->int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_DSP_LINE>));
301 m_dspp->dma_read_handler().set(FUNC(m2_bda_device::read_bus8));
302 m_dspp->dma_write_handler().set(FUNC(m2_bda_device::write_bus8));
303
304 M2_TE(config, m_te, DERIVED_CLOCK(1, 1));
305 m_te->general_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_TRIGEN_LINE>));
306 m_te->dfinstr_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_TRIDFINST_LINE>));
307 m_te->iminstr_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_TRIDMINST_LINE>));
308 m_te->listend_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_TRILISTEND_LINE>));
309 m_te->winclip_int_handler().set(m_powerbus, FUNC(m2_powerbus_device::int_line<BDAINT_TRIWINCLIP_LINE>));
310 }
311
312
313 //-------------------------------------------------
314 // device_timer - device-specific timers
315 //-------------------------------------------------
316
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)317 void m2_bda_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
318 {
319 switch (id)
320 {
321 case 0:
322 {
323 m_dac_l(m_dspp->read_output_fifo());
324 m_dac_r(m_dspp->read_output_fifo());
325 m_dac_timer->adjust(attotime::from_hz(44100));
326 break;
327 }
328 }
329 }
330
331
332
333 /***************************************************************************
334 PUBLIC FUNCTIONS
335 ***************************************************************************/
336
337 //-------------------------------------------------
338 // cpu_id_r - read from CPU ID register
339 //-------------------------------------------------
340
cpu_id_r(address_space & space)341 uint32_t m2_bda_device::cpu_id_r(address_space &space)
342 {
343 uint32_t data = 0;
344
345 // .x...... ........ ........ ........ - Video type (0 = Arcade, 1 = NTSC/PAL)
346 // x....... ........ ........ ........ - CPU ID (0 = CPU1, 1 = CPU2)
347
348 if (&space.device() == m_cpu2)
349 data |= 0x80000000;
350
351 if (m_videores_in() != 0)
352 data |= 0x40000000;
353
354 return data;
355 }
356
357
358 //-------------------------------------------------
359 // cpu_id_w - Write to CPU ID register
360 //-------------------------------------------------
361
cpu_id_w(address_space & space,uint32_t data)362 void m2_bda_device::cpu_id_w(address_space &space, uint32_t data)
363 {
364 // TODO: How should this work?
365 logerror("%s: CPUID: %x\n", machine().describe_context(), data);
366 }
367
368
369 //-------------------------------------------------
370 // read_bus8 - Read 8-bit data from the PowerBus
371 //-------------------------------------------------
372
read_bus8(offs_t offset)373 uint8_t m2_bda_device::read_bus8(offs_t offset)
374 {
375 assert(offset >= RAM_BASE && offset <= RAM_BASE + m_ram_mask);
376
377 offset &= m_ram_mask;
378 uint8_t *ptr = reinterpret_cast<uint8_t *>(&m_ram[0]) + BYTE8_XOR_BE(offset);
379 return *ptr;
380 }
381
382
383 //-------------------------------------------------
384 // read_bus16 - Read 16-bit data from the PowerBus
385 //-------------------------------------------------
386
read_bus16(offs_t offset)387 uint16_t m2_bda_device::read_bus16(offs_t offset)
388 {
389 assert(offset >= RAM_BASE && offset <= RAM_BASE + m_ram_mask);
390
391 offset &= m_ram_mask;
392 uint8_t *ptr = reinterpret_cast<uint8_t *>(&m_ram[0]) + WORD2_XOR_BE(offset);
393 return *reinterpret_cast<uint16_t *>(ptr);
394 }
395
396
397 //-------------------------------------------------
398 // read_bus32 - Read 32-bit data from the PowerBus
399 //-------------------------------------------------
400
read_bus32(offs_t offset)401 uint32_t m2_bda_device::read_bus32(offs_t offset)
402 {
403 assert(offset >= RAM_BASE && offset <= RAM_BASE + m_ram_mask);
404
405 offset &= m_ram_mask;
406
407 uint8_t *ptr = reinterpret_cast<uint8_t *>(&m_ram[0]) + DWORD_XOR_BE(offset);
408 return *reinterpret_cast<uint32_t *>(ptr);
409 }
410
411
412 //-------------------------------------------------
413 // write_bus8 - Write 8-bit data to the PowerBus
414 //-------------------------------------------------
415
write_bus8(offs_t offset,uint8_t data)416 void m2_bda_device::write_bus8(offs_t offset, uint8_t data)
417 {
418 assert(offset >= RAM_BASE && offset <= RAM_BASE + m_ram_mask);
419
420 offset &= m_ram_mask;
421 uint8_t *ptr = reinterpret_cast<uint8_t *>(&m_ram[0]) + BYTE8_XOR_BE(offset);
422 *ptr = data;
423 }
424
425
426 //-------------------------------------------------
427 // write_bus16 - Write 16-bit data to the PowerBus
428 //-------------------------------------------------
429
write_bus16(offs_t offset,uint16_t data)430 void m2_bda_device::write_bus16(offs_t offset, uint16_t data)
431 {
432 assert(offset >= RAM_BASE && offset <= RAM_BASE + m_ram_mask);
433
434 offset &= m_ram_mask;
435 uint8_t *ptr = reinterpret_cast<uint8_t *>(&m_ram[0]) + WORD2_XOR_BE(offset);
436 *reinterpret_cast<uint16_t *>(ptr) = data;
437 }
438
439
440 //-------------------------------------------------
441 // write_bus32 - Write 32-bit data to the PowerBus
442 //-------------------------------------------------
443
write_bus32(offs_t offset,uint32_t data)444 void m2_bda_device::write_bus32(offs_t offset, uint32_t data)
445 {
446 assert(offset >= RAM_BASE && offset <= RAM_BASE + m_ram_mask);
447
448 offset &= m_ram_mask;
449 uint8_t *ptr = reinterpret_cast<uint8_t *>(&m_ram[0]) + DWORD_XOR_BE(offset);
450 *reinterpret_cast<uint32_t *>(ptr) = data;
451 }
452
453
454
455 /***************************************************************************
456 PRIVATE FUNCTIONS
457 ***************************************************************************/
458
459 //-------------------------------------------------
460 // configure_ppc_address_map -
461 //-------------------------------------------------
462
configure_ppc_address_map(address_space & space)463 void m2_bda_device::configure_ppc_address_map(address_space &space)
464 {
465 // Install shared RAM
466 space.install_ram(RAM_BASE, RAM_BASE + m_ram_mask, m_ram);
467
468 // Install TE texture RAM window
469 space.install_ram(TE_TRAM_BASE, TE_TRAM_BASE + TE_TRAM_MASK, m_te->tram_ptr());
470
471 // Install BDA sub-devices
472 space.install_readwrite_handler(POWERBUS_BASE, POWERBUS_BASE + DEVICE_MASK,read32sm_delegate(*m_powerbus, FUNC(m2_powerbus_device::read)), write32sm_delegate(*m_powerbus, FUNC(m2_powerbus_device::write)), 0xffffffffffffffffULL);
473 space.install_readwrite_handler(MEMCTL_BASE, MEMCTL_BASE + DEVICE_MASK, read32s_delegate(*m_memctl, FUNC(m2_memctl_device::read)), write32s_delegate(*m_memctl, FUNC(m2_memctl_device::write)), 0xffffffffffffffffULL);
474 space.install_readwrite_handler(VDU_BASE, VDU_BASE + DEVICE_MASK, read32s_delegate(*m_vdu, FUNC(m2_vdu_device::read)), write32s_delegate(*m_vdu, FUNC(m2_vdu_device::write)), 0xffffffffffffffffULL);
475 space.install_readwrite_handler(TE_BASE, TE_BASE + DEVICE_MASK, read32sm_delegate(*m_te, FUNC(m2_te_device::read)), write32sm_delegate(*m_te, FUNC(m2_te_device::write)), 0xffffffffffffffffULL);
476 space.install_readwrite_handler(DSP_BASE, DSP_BASE + DEVICE_MASK, read32sm_delegate(*m_dspp, FUNC(dspp_device::read)), write32sm_delegate(*m_dspp, FUNC(dspp_device::write)), 0xffffffffffffffffULL);
477 space.install_readwrite_handler(CTRLPORT_BASE, CTRLPORT_BASE + DEVICE_MASK,read32sm_delegate(*m_ctrlport, FUNC(m2_ctrlport_device::read)), write32sm_delegate(*m_ctrlport, FUNC(m2_ctrlport_device::write)), 0xffffffffffffffffULL);
478 space.install_readwrite_handler(MPEG_BASE, MPEG_BASE + DEVICE_MASK, read32sm_delegate(*m_mpeg, FUNC(m2_mpeg_device::read)), write32sm_delegate(*m_mpeg, FUNC(m2_mpeg_device::write)), 0xffffffffffffffffULL);
479
480 space.install_readwrite_handler(CPUID_BASE, CPUID_BASE + DEVICE_MASK, read32mo_delegate(*this, FUNC(m2_bda_device::cpu_id_r)), write32mo_delegate(*this, FUNC(m2_bda_device::cpu_id_w)), 0xffffffffffffffffULL);
481
482 space.install_readwrite_handler(SLOT4_BASE, SLOT4_BASE + SLOT_MASK, read32_delegate(*m_cde, FUNC(m2_cde_device::read)), write32_delegate(*m_cde, FUNC(m2_cde_device::write)), 0xffffffffffffffffULL);
483 }
484
485
486
487 //**************************************************************************
488 // POWERBUS DEVICE
489 //**************************************************************************
490
491
492 //-------------------------------------------------
493 // m2_powerbus_device - constructor
494 //-------------------------------------------------
495
m2_powerbus_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)496 m2_powerbus_device::m2_powerbus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
497 device_t(mconfig, M2_POWERBUS, tag, owner, clock),
498 m_int_handler(*this)
499 {
500
501 }
502
503
504 //-------------------------------------------------
505 // device_start - device-specific startup
506 //-------------------------------------------------
507
device_start()508 void m2_powerbus_device::device_start()
509 {
510 // Resolve callbacks
511 m_int_handler.resolve();
512
513 // Register state for saving
514 save_item(NAME(m_ctrl));
515 save_item(NAME(m_int_enable));
516 save_item(NAME(m_int_status));
517 save_item(NAME(m_err_status));
518 save_item(NAME(m_err_address));
519 }
520
521
522 //-------------------------------------------------
523 // device_reset - device-specific reset
524 //-------------------------------------------------
525
device_reset()526 void m2_powerbus_device::device_reset()
527 {
528 m_ctrl = 0;
529 m_int_enable = 0;
530 m_int_status = 0;
531 m_err_status = 0;
532 m_err_address = 0;
533 }
534
535
536 /***************************************************************************
537 PUBLIC FUNCTIONS
538 ***************************************************************************/
539
540 //-------------------------------------------------
541 // read -
542 //-------------------------------------------------
543
read(offs_t offset)544 uint32_t m2_powerbus_device::read(offs_t offset)
545 {
546 const uint32_t byte_offs = offset << 2;
547 uint32_t data = 0;
548
549 switch (byte_offs)
550 {
551 case BDAPCTL_PBINTENSET:
552 {
553 data = m_int_enable;
554 break;
555 }
556 case BDAPCTL_PBINTSTAT:
557 {
558 data = m_int_status;
559 break;
560 }
561 default:
562 logerror("%s: POWERBUS R: [%x] %x\n", machine().describe_context(), byte_offs, data);
563 }
564
565 return data;
566 }
567
568
569 //-------------------------------------------------
570 // write -
571 //-------------------------------------------------
572
write(offs_t offset,uint32_t data)573 void m2_powerbus_device::write(offs_t offset, uint32_t data)
574 {
575 uint32_t byte_offs = offset << 2;
576
577 switch (byte_offs & ~0x400)
578 {
579 case BDAPCTL_PBINTENSET:
580 {
581 write_m2_reg(m_int_enable, data, byte_offs & 0x400 ? REG_CLEAR : REG_SET);
582 update_interrupts();
583 break;
584 }
585 case BDAPCTL_ERRSTAT:
586 {
587 #if 1 // TODO
588 if (byte_offs & 0x400)
589 {
590 write_m2_reg(m_int_status, data, REG_CLEAR);
591 }
592 else
593 {
594 if (data == 1)
595 write_m2_reg(m_int_status, data, REG_SET);
596 }
597 update_interrupts();
598 #endif
599 break;
600 }
601 default:
602 logerror("%s: POWERBUS W: [%x] %x (PC:%x)\n", machine().describe_context(), byte_offs, data);
603 }
604 }
605
606
607 /***************************************************************************
608 PRIVATE FUNCTIONS
609 ***************************************************************************/
610
611 //-------------------------------------------------
612 // update_interrupts -
613 //-------------------------------------------------
614
update_interrupts()615 void m2_powerbus_device::update_interrupts()
616 {
617 m_int_handler(m_int_status & m_int_enable ? ASSERT_LINE : CLEAR_LINE);
618 }
619
620
621
622 //**************************************************************************
623 // MEMORY CONTROLLER DEVICE
624 //**************************************************************************
625
626
627 //-------------------------------------------------
628 // m2_memctl_device - constructor
629 //-------------------------------------------------
630
m2_memctl_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)631 m2_memctl_device::m2_memctl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
632 : device_t(mconfig, M2_MEMCTL, tag, owner, clock),
633 m_gpio_in(*this),
634 m_gpio_out(*this)
635 {
636 }
637
638
639 //-------------------------------------------------
640 // device_start - device-specific startup
641 //-------------------------------------------------
642
device_start()643 void m2_memctl_device::device_start()
644 {
645 // Resolve our callbacks
646 m_gpio_in.resolve_all_safe(0);
647 m_gpio_out.resolve_all_safe();
648
649 // TODO: DELETE ME
650 m2_bda_device *m_bda = (m2_bda_device*)owner(); // TEMP
651
652 // Configure the memory configuration register
653 uint32_t bank1 = m_bda->get_rambank_size(0);
654 uint32_t bank2 = m_bda->get_rambank_size(1);
655
656 m_mcfg = (ramsize_to_mcfg_field(bank2) << MCFG_SS1_SHIFT) | (ramsize_to_mcfg_field(bank1) << MCFG_SS0_SHIFT);
657
658 // Register state for saving
659 save_item(NAME(m_mcfg));
660 save_item(NAME(m_mref));
661 save_item(NAME(m_mcntl));
662 save_item(NAME(m_reset));
663 }
664
665
666 //-------------------------------------------------
667 // device_reset - device-specific reset
668 //-------------------------------------------------
669
device_reset()670 void m2_memctl_device::device_reset()
671 {
672 // TODO: Need postload to set GPIO also?
673 m_mref = 0;
674 }
675
676
677 /***************************************************************************
678 PUBLIC FUNCTIONS
679 ***************************************************************************/
680
681 //-------------------------------------------------
682 // read -
683 //-------------------------------------------------
684
read(offs_t offset,uint32_t mem_mask)685 uint32_t m2_memctl_device::read(offs_t offset, uint32_t mem_mask)
686 {
687 uint32_t byte_offs = offset << 2;
688 uint32_t data = 0;
689
690 switch (byte_offs)
691 {
692 case MCTL_MCONFIG:
693 {
694 data = m_mcfg;
695 break;
696 }
697 case MCTL_MREF:
698 {
699 if ((m_mref & MREF_GPIO0_GP) && !(m_mref & MREF_GPIO0_OUT))
700 {
701 if (m_gpio_in[0]())
702 m_mref |= MREF_GPIO0_VALUE;
703 else
704 m_mref &= ~MREF_GPIO0_VALUE;
705 }
706
707 if ((m_mref & MREF_GPIO1_GP) && !(m_mref & MREF_GPIO1_OUT))
708 {
709 if (m_gpio_in[1]())
710 m_mref |= MREF_GPIO1_VALUE;
711 else
712 m_mref &= ~MREF_GPIO1_VALUE;
713 }
714
715 if ((m_mref & MREF_GPIO2_GP) && !(m_mref & MREF_GPIO2_OUT))
716 {
717 if (m_gpio_in[2]())
718 m_mref |= MREF_GPIO2_VALUE;
719 else
720 m_mref &= ~MREF_GPIO2_VALUE;
721 }
722
723 if ((m_mref & MREF_GPIO3_GP) && !(m_mref & MREF_GPIO3_OUT))
724 {
725 if (m_gpio_in[3]())
726 m_mref |= MREF_GPIO3_VALUE;
727 else
728 m_mref &= ~MREF_GPIO3_VALUE;
729 }
730
731 data = m_mref;
732 break;
733 }
734 case MCTL_MCNTL:
735 case MCTL_MRESET:
736 //logerror("%s: MEMCTL READ: %x %x\n", machine().describe_context(), byte_offs, mem_mask);
737 break;
738 }
739
740 return data;
741 }
742
743
744 //-------------------------------------------------
745 // write -
746 //-------------------------------------------------
747
write(offs_t offset,uint32_t data,uint32_t mem_mask)748 void m2_memctl_device::write(offs_t offset, uint32_t data, uint32_t mem_mask)
749 {
750 uint32_t byte_offs = offset << 2;
751
752 switch (byte_offs)
753 {
754 case MCTL_MCONFIG:
755 {
756 m_mcfg = data;
757 break;
758 }
759 case MCTL_MREF:
760 {
761 // Set any general purpose outputs
762 if (data & (MREF_GPIO0_GP | MREF_GPIO0_OUT))
763 m_gpio_out[0](data & MREF_GPIO0_VALUE ? 1 : 0);
764
765 if (data & (MREF_GPIO1_GP | MREF_GPIO1_OUT))
766 m_gpio_out[1](data & MREF_GPIO1_VALUE ? 1 : 0);
767
768 if (data & (MREF_GPIO2_GP | MREF_GPIO2_OUT))
769 m_gpio_out[2](data & MREF_GPIO2_VALUE ? 1 : 0);
770
771 if (data & (MREF_GPIO3_GP | MREF_GPIO3_OUT))
772 m_gpio_out[3](data & MREF_GPIO3_VALUE ? 1 : 0);
773
774 m_mref = data;
775 break;
776 }
777 case MCTL_MCNTL:
778 case MCTL_MRESET:
779 //logerror("%s: MEMCTL WRITE: %x %x %x\n", machine().describe_context(), data, byte_offs);
780 break;
781 }
782 }
783
784
785
786 //**************************************************************************
787 // VDU DEVICE
788 //**************************************************************************
789
790
791 //-------------------------------------------------
792 // m2_vdu_device - constructor
793 //-------------------------------------------------
794
m2_vdu_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)795 m2_vdu_device::m2_vdu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
796 : device_t(mconfig, M2_VDU, tag, owner, clock),
797 m_screen(*this, finder_base::DUMMY_TAG),
798 m_vint0_int_handler(*this),
799 m_vint1_int_handler(*this)
800 {
801
802 }
803
804
805 //-------------------------------------------------
806 // device_start - device-specific startup
807 //-------------------------------------------------
808
device_start()809 void m2_vdu_device::device_start()
810 {
811 // Resolve callbacks
812 m_vint0_int_handler.resolve_safe();
813 m_vint1_int_handler.resolve_safe();
814
815 // Initialize line interrupt timers
816 m_vint0_timer = timer_alloc(TIMER_ID_VINT0);
817 m_vint1_timer = timer_alloc(TIMER_ID_VINT1);
818
819 // Calculate H/V count bias values (1 = start of blanking)
820 const rectangle visarea = m_screen->visible_area();
821
822 m_hstart = visarea.min_x;
823 m_htotal = visarea.max_x + 1;
824
825 m_vstart = visarea.min_y;
826 m_vtotal = visarea.max_y + 1;
827
828 // Register state for saving
829 save_item(NAME(m_vint));
830 save_item(NAME(m_vdc0));
831 save_item(NAME(m_vdc1));
832 save_item(NAME(m_fv0a));
833 save_item(NAME(m_fv1a));
834 save_item(NAME(m_avdi));
835 save_item(NAME(m_vdli));
836 save_item(NAME(m_vcfg));
837 save_item(NAME(m_dmt0));
838 save_item(NAME(m_dmt1));
839 save_item(NAME(m_vrst));
840 }
841
842
843 //-------------------------------------------------
844 // device_reset - device-specific reset
845 //-------------------------------------------------
846
device_reset()847 void m2_vdu_device::device_reset()
848 {
849 m_fv0a = 0;
850 m_fv1a = 0;
851 m_avdi = 0;
852 m_vdli = 0;
853 m_vint = 0;
854 m_vcfg = 0;
855 m_dmt0 = 0;
856 m_dmt1 = 0;
857
858 m_vint0_timer->adjust(attotime::never);
859 m_vint1_timer->adjust(attotime::never);
860 }
861
862
863 //-------------------------------------------------
864 // device_timer - device-specific timers
865 //-------------------------------------------------
866
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)867 void m2_vdu_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
868 {
869 switch (id)
870 {
871 case TIMER_ID_VINT0:
872 {
873 m_vint |= VDU_VINT_VINT0;
874 m_vint0_int_handler(ASSERT_LINE);
875 set_vint_timer(0);
876 break;
877 }
878 case TIMER_ID_VINT1:
879 {
880 m_vint |= VDU_VINT_VINT1;
881 m_vint1_int_handler(ASSERT_LINE);
882 set_vint_timer(1);
883 break;
884 }
885 }
886 }
887
888
889
890 /***************************************************************************
891 PUBLIC FUNCTIONS
892 ***************************************************************************/
893
894 //-------------------------------------------------
895 // read -
896 //-------------------------------------------------
897
read(offs_t offset,uint32_t mem_mask)898 uint32_t m2_vdu_device::read(offs_t offset, uint32_t mem_mask)
899 {
900 uint32_t byte_offs = offset << 2;
901 uint32_t data = 0;
902
903 switch (byte_offs)
904 {
905 case VDU_VLOC:
906 {
907 // TODO: Check me
908 uint32_t mpos = m_screen->vpos();
909 uint32_t vpos = ((mpos + m_vstart) % m_vtotal) + 1;
910 data = vpos << VDU_VLOC_VCOUNT_SHIFT;
911 break;
912 }
913 case VDU_VINT:
914 {
915 data = m_vint;
916 break;
917 }
918 case VDU_VDC0:
919 case VDU_VDC1:
920 case VDU_FV0A:
921 case VDU_FV1A:
922 case VDU_AVDI:
923 case VDU_VDLI:
924 case VDU_VCFG:
925 case VDU_DMT0:
926 case VDU_DMT1:
927 case VDU_LFSR:
928 {
929 //logerror("%s: VDU READ: %x %x\n", machine().describe_context(), byte_offs, mem_mask);
930 break;
931 }
932 }
933
934 return data;
935 }
936
937
938 //-------------------------------------------------
939 // write -
940 //-------------------------------------------------
941
write(offs_t offset,uint32_t data,uint32_t mem_mask)942 void m2_vdu_device::write(offs_t offset, uint32_t data, uint32_t mem_mask)
943 {
944 uint32_t byte_offs = offset << 2;
945 m2_reg_wmode wmode = byte_offs & 0x400 ? REG_CLEAR : REG_WRITE;
946
947 // logerror("%s: VDU WRITE: %03x %08x %x\n", machine().describe_context(), byte_offs, data, mem_mask);
948 byte_offs &= ~0x400;
949 switch (byte_offs)
950 {
951 case VDU_VINT:
952 {
953 uint32_t old = m_vint;
954 write_m2_reg(m_vint, data, wmode);
955
956 // Update line interrupts if changed
957 if ((m_vint & VDU_VINT_VLINE0_MASK) != (old & VDU_VINT_VLINE0_MASK))
958 set_vint_timer(0);
959
960 if ((m_vint & VDU_VINT_VLINE1_MASK) != (old & VDU_VINT_VLINE1_MASK))
961 set_vint_timer(1);
962
963 // Clear interrupt bits
964 if ((old & VDU_VINT_VINT0) && !(m_vint & VDU_VINT_VINT0))
965 m_vint0_int_handler(CLEAR_LINE);
966
967 if ((old & VDU_VINT_VINT1) && !(m_vint & VDU_VINT_VINT1))
968 m_vint1_int_handler(CLEAR_LINE);
969
970 break;
971 }
972 case VDU_FV0A:
973 {
974 m_fv0a = data;
975 break;
976 }
977 case VDU_FV1A:
978 {
979 m_fv1a = data;
980 break;
981 }
982 case VDU_VCFG:
983 {
984 m_vcfg = data;
985 break;
986 }
987 case VDU_VRST:
988 {
989 m_vrst = data;
990 break;
991 }
992 default:
993 {
994 logerror("%s: VDU WRITE: %x %x %x\n", machine().describe_context(), byte_offs, data, mem_mask);
995 break;
996 }
997 }
998 }
999
1000
1001 //-------------------------------------------------
1002 // parse_dc_word -
1003 //-------------------------------------------------
1004
parse_dc_word(uint32_t cmd)1005 void m2_vdu_device::parse_dc_word(uint32_t cmd)
1006 {
1007 // Determine the control register
1008 uint32_t &vdc = cmd & VDL_DC_1 ? m_vdc1 : m_vdc0;
1009
1010 // Horizontal interpolation
1011 uint32_t hint = (cmd & VDL_DC_HINTCTL_MASK) >> VDL_DC_HINTCTL_SHIFT;
1012
1013 if (hint == VDL_CTL_ENABLE)
1014 vdc |= VDU_VDC_HINT;
1015 else if (hint == VDL_CTL_DISABLE)
1016 vdc &= ~VDU_VDC_HINT;
1017
1018
1019 // Vertical interpolation
1020 uint32_t vint = (cmd & VDL_DC_VINTCTL_MASK) >> VDL_DC_VINTCTL_SHIFT;
1021
1022 if (vint == VDL_CTL_ENABLE)
1023 vdc |= VDU_VDC_VINT;
1024 else if (vint == VDL_CTL_DISABLE)
1025 vdc &= ~VDU_VDC_VINT;
1026
1027
1028 // Dithering
1029 uint32_t dith = (cmd & VDL_DC_DITHERCTL_MASK) >> VDL_DC_DITHERCTL_SHIFT;
1030
1031 if (dith == VDL_CTL_ENABLE)
1032 vdc |= VDU_VDC_DITHER;
1033 else if (dith == VDL_CTL_DISABLE)
1034 vdc &= ~VDU_VDC_DITHER;
1035
1036
1037 // MTXBYP (?)
1038 uint32_t mtxbyp = (cmd & VDL_DC_MTXBYPCTL_MASK) >> VDL_DC_MTXBYPCTL_SHIFT;
1039
1040 if (mtxbyp == VDL_CTL_ENABLE)
1041 vdc |= VDU_VDC_MTXBYP;
1042 else if (mtxbyp == VDL_CTL_DISABLE)
1043 vdc &= ~VDU_VDC_MTXBYP;
1044 }
1045
1046
1047 //-------------------------------------------------
1048 // parse_av_word -
1049 //-------------------------------------------------
1050
parse_av_word(uint32_t cmd)1051 void m2_vdu_device::parse_av_word(uint32_t cmd)
1052 {
1053 if (cmd & VDL_AV_LD_HSTART)
1054 {
1055 uint32_t hstart = (cmd & VDL_AV_HSTART_MASK) >> VDL_AV_HSTART_SHIFT;
1056 m_avdi &= ~VDU_AVDI_HSTART_MASK;
1057 m_avdi |= hstart << VDU_AVDI_HSTART_SHIFT;
1058 }
1059 if (cmd & VDL_AV_LD_HWIDTH)
1060 {
1061 uint32_t hwidth = (cmd & VDL_AV_HWIDTH_MASK) >> VDL_AV_HWIDTH_SHIFT;
1062 m_avdi &= ~VDU_AVDI_HWIDTH_MASK;
1063 m_avdi |= hwidth << VDU_AVDI_HWIDTH_SHIFT;
1064 }
1065 if (cmd & VDL_AV_LD_HDOUBLE)
1066 {
1067 if (cmd & VDL_AV_HDOUBLE)
1068 m_avdi |= VDU_AVDI_HDOUBLE;
1069 else
1070 m_avdi &= ~VDU_AVDI_HDOUBLE;
1071 }
1072 if (cmd & VDL_AV_LD_VDOUBLE)
1073 {
1074 if (cmd & VDL_AV_VDOUBLE)
1075 m_avdi |= VDU_AVDI_VDOUBLE;
1076 else
1077 m_avdi &= ~VDU_AVDI_VDOUBLE;
1078 }
1079 }
1080
1081
1082 //-------------------------------------------------
1083 // parse_lc_word -
1084 //-------------------------------------------------
1085
parse_lc_word(uint32_t cmd)1086 void m2_vdu_device::parse_lc_word(uint32_t cmd)
1087 {
1088 // TODO: This may not be used
1089 if (cmd & VDL_LC_LD_BYPASSTYPE)
1090 {
1091 m_vdli &= ~VDU_VDLI_BYPASSTYPE;
1092 m_vdli |= (cmd & VDU_VDLI_BYPASSTYPE) == VDU_VDLI_BYPASSTYPE_MSB ? VDU_VDLI_BYPASSTYPE_MSB : VDU_VDLI_BYPASSTYPE_LSB;
1093 }
1094 if (cmd & VDL_LC_LD_FBFORMAT)
1095 {
1096 m_vdli &= ~VDU_VDLI_FBFORMAT;
1097 m_vdli |= (cmd & VDL_LC_FBFORMAT) == VDL_LC_FBFORMAT_32 ? VDU_VDLI_FBFORMAT_32 : VDU_VDLI_FBFORMAT_16;
1098 }
1099
1100 // Seems these two are always set by the command word
1101 if (cmd & VDL_LC_RANDOMDITHER)
1102 m_vdli |= VDU_VDLI_RANDOMDITHER;
1103 else
1104 m_vdli &= ~VDU_VDLI_RANDOMDITHER;
1105
1106 if (cmd & VDL_LC_ONEVINTDIS)
1107 m_vdli |= VDU_VDLI_ONEVINTDIS;
1108 else
1109 m_vdli &= ~VDU_VDLI_ONEVINTDIS;
1110 }
1111
1112
1113 //-------------------------------------------------
1114 // draw_scanline - Draw a scanline
1115 //-------------------------------------------------
1116
draw_scanline(uint32_t * dst,uint32_t srclower,uint32_t srcupper)1117 void m2_vdu_device::draw_scanline(uint32_t *dst, uint32_t srclower, uint32_t srcupper)
1118 {
1119 m2_bda_device *m_bda = (m2_bda_device*)owner(); // TEMP
1120
1121 uint32_t hs = (m_avdi & VDU_AVDI_HSTART_MASK) >> VDU_AVDI_HSTART_SHIFT;
1122 uint32_t hw = (m_avdi & VDU_AVDI_HWIDTH_MASK) >> VDU_AVDI_HWIDTH_SHIFT;
1123
1124 bool is32bpp = m_vdli & VDU_VDLI_FBFORMAT_32 ? true : false;
1125 // bool bypassmsb = m_vdli & VDU_VDLI_BYPASSTYPE_MSB ? true : false;
1126 // bool randomdith = m_vdli & VDU_VDLI_RANDOMDITHER ? true : false;
1127
1128 uint32_t h = 0;
1129
1130 // Left border
1131 while (h < hs)
1132 {
1133 *dst++ = rgb_t::black();
1134 ++h;
1135 }
1136
1137 // Active video area
1138 uint32_t vismax = std::min<uint32_t>(h + hw, m_htotal);
1139
1140 if (is32bpp)
1141 {
1142 while (h < vismax)
1143 {
1144 *dst++ = m_bda->read_bus32(srclower);
1145 srclower += 4;
1146 ++h;
1147 }
1148 }
1149 else
1150 {
1151 while (h < vismax)
1152 {
1153 uint16_t srcdata = m_bda->read_bus16(srclower);
1154 *dst++ = pal555(srcdata, 10, 5, 0);
1155 srclower += 2;
1156 ++h;
1157 }
1158 }
1159
1160 // Right border
1161 while (h < m_htotal)
1162 {
1163 *dst++ = rgb_t::black();
1164 ++h;
1165 }
1166 }
1167
1168
1169 //-------------------------------------------------
1170 // draw_scanline_double - Draw a pixel-doubled scanline
1171 //-------------------------------------------------
1172
draw_scanline_double(uint32_t * dst,uint32_t srclower,uint32_t srcupper)1173 void m2_vdu_device::draw_scanline_double(uint32_t *dst, uint32_t srclower, uint32_t srcupper)
1174 {
1175 m2_bda_device *m_bda = (m2_bda_device*)owner(); // TEMP
1176
1177 uint32_t hs = (m_avdi & VDU_AVDI_HSTART_MASK) >> VDU_AVDI_HSTART_SHIFT;
1178 uint32_t hw = (m_avdi & VDU_AVDI_HWIDTH_MASK) >> VDU_AVDI_HWIDTH_SHIFT;
1179
1180 bool is32bpp = m_vdli & VDU_VDLI_FBFORMAT_32 ? true : false;
1181 // bool bypassmsb = m_vdli & VDU_VDLI_BYPASSTYPE_MSB ? true : false;
1182 // bool randomdith = m_vdli & VDU_VDLI_RANDOMDITHER ? true : false;
1183
1184 uint32_t h = 0;
1185
1186 // Left border
1187 while (h < hs)
1188 {
1189 *dst++ = rgb_t::black();
1190 ++h;
1191 }
1192
1193 // Active video area
1194 uint32_t vismax = std::min<uint32_t>(h + hw, m_htotal);
1195
1196 if (is32bpp)
1197 {
1198 while (h < vismax)
1199 {
1200 uint32_t srcdata = m_bda->read_bus32(srclower);
1201
1202 srclower += 4;
1203 *dst++ = srcdata;
1204 *dst++ = srcdata;
1205 ++h;
1206 }
1207 }
1208 else
1209 {
1210 while (h < vismax)
1211 {
1212 uint32_t srcdata = m_bda->read_bus16(srclower);
1213 srcdata = pal555(srcdata, 10, 5, 0);
1214
1215 srclower += 2;
1216 *dst++ = srcdata;
1217 *dst++ = srcdata;
1218 ++h;
1219 }
1220 }
1221
1222 // Right border
1223 while (h < m_htotal)
1224 {
1225 *dst++ = rgb_t::black();
1226 ++h;
1227 }
1228 }
1229
1230
1231 //-------------------------------------------------
1232 // core_update_screen -
1233 //-------------------------------------------------
1234
1235
1236
1237 //-------------------------------------------------
1238 // screen_update -
1239 //-------------------------------------------------
1240
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)1241 uint32_t m2_vdu_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
1242 {
1243 m2_bda_device *m_bda = (m2_bda_device*)owner(); // TEMP
1244
1245 // TODO: Interlace mode
1246 uint32_t addr = m_fv0a;//screen.frame_number() & 1 ? m_fv1a : m_fv0a;
1247
1248 // Fill entire screen with black if disabled
1249 if ((m_vrst & (VDU_VRST_VIDRESET | VDU_VRST_DVERESET)) || addr == 0)
1250 {
1251 bitmap.fill(rgb_t::black());
1252 return 0;
1253 }
1254
1255 // Processing begins at VSYNC
1256 uint32_t v = 0;
1257
1258 // Process VDLs until all lines are exhausted
1259 while (v < m_vtotal)
1260 {
1261 // Fetch the 4 header words
1262 uint32_t dmactl = m_bda->read_bus32(addr);
1263 uint32_t lower = m_bda->read_bus32(addr + 4);
1264 uint32_t upper = m_bda->read_bus32(addr + 8);
1265 uint32_t next = m_bda->read_bus32(addr + 12);
1266
1267 addr += 16;
1268
1269 // Word count includes the header
1270 uint32_t words = (dmactl & VDL_DMA_NWORDS_MASK) >> VDL_DMA_NWORDS_SHIFT;
1271 words -= 4;
1272
1273 // Check and adjust the line count
1274 uint32_t lines = (dmactl & VDL_DMA_NLINES_MASK) >> VDL_DMA_NLINES_SHIFT;
1275
1276 if (lines > 0)
1277 {
1278 uint32_t vend = v + lines;
1279
1280 if (vend > m_vtotal)
1281 lines = vend - m_vtotal;
1282 }
1283 else
1284 {
1285 // A zero count denotes all of the remaining screen lines
1286 lines = m_vtotal - v;
1287 }
1288
1289 // Parse the command list and update video registers accordingly
1290 while (words-- > 0)
1291 {
1292 uint32_t cmd = m_bda->read_bus32(addr);
1293 addr += 4;
1294
1295 switch (cmd & 0xe0000000)
1296 {
1297 case VDL_DC:
1298 {
1299 parse_dc_word(cmd);
1300 break;
1301 }
1302 case VDL_AV:
1303 {
1304 parse_av_word(cmd);
1305 break;
1306 }
1307 case VDL_LC:
1308 {
1309 parse_lc_word(cmd);
1310 break;
1311 }
1312 default:
1313 {
1314 if (cmd != VDL_NOP)
1315 fatalerror("VDU: Unknown VDL command word\n");
1316 break;
1317 }
1318 }
1319 }
1320
1321 // DMA from RAM to the display
1322 if (dmactl & VDL_DMA_ENABLE)
1323 {
1324 bool hdouble = m_avdi & VDU_AVDI_HDOUBLE ? true : false;
1325 bool vdouble = m_avdi & VDU_AVDI_VDOUBLE ? true : false;
1326 // bool onevintdis = m_vdli & VDU_VDLI_ONEVINTDIS ? true : false;
1327
1328 uint32_t srclower = lower;
1329 uint32_t srcupper = upper;
1330 uint32_t mod = ((dmactl & VDL_DMA_MOD_MASK) >> VDL_DMA_MOD_SHIFT) << 5;
1331
1332 // Draw these lines
1333 while (lines--)
1334 {
1335 // Line doubling is easily handled
1336 for (uint32_t ys = vdouble ? 2 : 1; ys > 0; --ys)
1337 {
1338 if (hdouble)
1339 draw_scanline_double(&bitmap.pix(v, 0), srclower, srcupper);
1340 else
1341 draw_scanline(&bitmap.pix(v, 0), srclower, srcupper);
1342
1343 ++v;
1344 }
1345 // Update the source addresses
1346 srclower += mod;
1347 srcupper += mod;
1348 }
1349 }
1350 else
1351 {
1352 // Blank this block of lines if DMA is disabled
1353 while (lines--)
1354 {
1355 uint32_t *dst = &bitmap.pix(v, cliprect.min_x);
1356
1357 for (uint32_t x = cliprect.min_x; x <= cliprect.max_x; ++x)
1358 *dst++ = rgb_t::black();
1359
1360 ++v;
1361 }
1362 }
1363
1364 // Jump to the next VDL
1365 addr = next;
1366 }
1367
1368 return 0;
1369 }
1370
1371
1372 //-------------------------------------------------
1373 // set_vint_timer -
1374 //-------------------------------------------------
1375
set_vint_timer(uint32_t id)1376 void m2_vdu_device::set_vint_timer(uint32_t id)
1377 {
1378 uint32_t v;
1379 emu_timer *timer = (id == 0) ? m_vint0_timer : m_vint1_timer;
1380
1381 if (id == 0)
1382 v = (m_vint & VDU_VINT_VLINE0_MASK) >> VDU_VINT_VLINE0_SHIFT;
1383 else
1384 v = (m_vint & VDU_VINT_VLINE1_MASK) >> VDU_VINT_VLINE1_SHIFT;
1385
1386 if (v == 0)
1387 {
1388 // Apparently 0 is invalid
1389 timer->adjust(attotime::never);
1390 }
1391 else
1392 {
1393 // Adjust the count to what the core expects
1394 uint32_t vadj = (v - 1 + (m_vtotal - m_vstart)) % m_vtotal;
1395 timer->adjust(m_screen->time_until_pos(vadj));
1396 }
1397 }
1398
1399
1400
1401 //**************************************************************************
1402 // CONTROL PORTS DEVICE
1403 //**************************************************************************
1404
1405 //-------------------------------------------------
1406 // m2_ctrlport_device - constructor
1407 //-------------------------------------------------
1408
m2_ctrlport_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)1409 m2_ctrlport_device::m2_ctrlport_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
1410 : device_t(mconfig, M2_CTRLPORT, tag, owner, clock)
1411 {
1412
1413 }
1414
1415
1416 //-------------------------------------------------
1417 // device_start - device-specific startup
1418 //-------------------------------------------------
1419
device_start()1420 void m2_ctrlport_device::device_start()
1421 {
1422
1423 }
1424
1425
1426 //-------------------------------------------------
1427 // device_reset - device-specific reset
1428 //-------------------------------------------------
1429
device_reset()1430 void m2_ctrlport_device::device_reset()
1431 {
1432
1433 }
1434
1435
1436 /***************************************************************************
1437 PUBLIC FUNCTIONS
1438 ***************************************************************************/
1439
1440 //-------------------------------------------------
1441 // read -
1442 //-------------------------------------------------
1443
read(offs_t offset)1444 uint32_t m2_ctrlport_device::read(offs_t offset)
1445 {
1446 //const uint32_t byte_offs = offset << 2;
1447 uint32_t data = machine().rand();
1448
1449 //switch (byte_offs)
1450 //{
1451 //default:
1452 //logerror("%s: CTRLPORT R: [%x] %x\n", machine().describe_context(), byte_offs, data);
1453 //}
1454
1455 return data;
1456 }
1457
1458
1459 //-------------------------------------------------
1460 // write -
1461 //-------------------------------------------------
1462
write(offs_t offset,uint32_t data)1463 void m2_ctrlport_device::write(offs_t offset, uint32_t data)
1464 {
1465 //uint32_t byte_offs = offset << 2;
1466
1467 //switch (byte_offs)
1468 //{
1469 //default:
1470 //logerror("%s: CTRLPORT W: [%x] %x\n", machine().describe_context(), byte_offs, data);
1471 //}
1472 }
1473
1474
1475 /***************************************************************************
1476 PRIVATE FUNCTIONS
1477 ***************************************************************************/
1478
1479
1480
1481
1482
1483 //**************************************************************************
1484 // CDE DEVICE
1485 //**************************************************************************
1486
1487 //-------------------------------------------------
1488 // m2_cde_device - constructor
1489 //-------------------------------------------------
1490
m2_cde_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)1491 m2_cde_device::m2_cde_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
1492 : device_t(mconfig, M2_CDE, tag, owner, clock),
1493 m_cpu1(*this, finder_base::DUMMY_TAG),
1494 m_bda(*this, finder_base::DUMMY_TAG),
1495 m_int_handler(*this),
1496 m_sdbg_out_handler(*this)
1497 {
1498 }
1499
1500
1501 //-------------------------------------------------
1502 // device_start - device-specific startup
1503 //-------------------------------------------------
1504
device_start()1505 void m2_cde_device::device_start()
1506 {
1507 // Resolve callbacks
1508 m_int_handler.resolve_safe();
1509 m_sdbg_out_handler.resolve_safe();
1510
1511 // Init DMA
1512 m_dma[0].m_timer = timer_alloc(TIMER_ID_DMA1);
1513 m_dma[1].m_timer = timer_alloc(TIMER_ID_DMA2);
1514
1515 // Register state for saving
1516 save_item(NAME(m_sdbg_cntl));
1517 save_item(NAME(m_int_status));
1518 save_item(NAME(m_int_enable));
1519 save_item(NAME(m_bblock_en));
1520 save_item(NAME(m_visa_dis));
1521
1522 for (uint32_t i = 0; i < 8; ++i)
1523 {
1524 save_item(NAME(m_bio_device[i].m_setup), i);
1525 save_item(NAME(m_bio_device[i].m_cycle_time), i);
1526 }
1527
1528 for (uint32_t i = 0; i < 2; ++i)
1529 {
1530 save_item(NAME(m_dma[i].m_cntl), i);
1531 save_item(NAME(m_dma[i].m_cbad), i);
1532 save_item(NAME(m_dma[i].m_cpad), i);
1533 save_item(NAME(m_dma[i].m_ccnt), i);
1534 save_item(NAME(m_dma[i].m_nbad), i);
1535 save_item(NAME(m_dma[i].m_npad), i);
1536 save_item(NAME(m_dma[i].m_ncnt), i);
1537 // timer
1538 }
1539 }
1540
1541 //-------------------------------------------------
1542 // device_reset - device-specific reset
1543 //-------------------------------------------------
1544
device_reset()1545 void m2_cde_device::device_reset()
1546 {
1547 m_sdbg_cntl = 0;
1548 m_int_status = 0;
1549 m_int_enable = 0;
1550
1551 // TODO? Boot block is clear on reset
1552 m_bblock_en = 1; // ?
1553 m_visa_dis = 0;
1554
1555 reset_dma(0);
1556 reset_dma(1);
1557 }
1558
1559
1560 //-------------------------------------------------
1561 // device_post_load - device-specific post-load
1562 //-------------------------------------------------
1563
device_post_load()1564 void m2_cde_device::device_post_load()
1565 {
1566
1567 }
1568
1569
1570 //-------------------------------------------------
1571 // device_timer - a timer
1572 //-------------------------------------------------
1573
device_timer(emu_timer & timer,device_timer_id id,int param,void * ptr)1574 void m2_cde_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1575 {
1576 switch (id)
1577 {
1578 case TIMER_ID_READY:
1579 // TODO ?
1580 set_interrupt(CDE_ID_READY);
1581 break;
1582
1583 case TIMER_ID_DMA1:
1584 next_dma(0);
1585 break;
1586
1587 case TIMER_ID_DMA2:
1588 next_dma(1);
1589 break;
1590
1591 default:
1592 throw emu_fatalerror("m2_cde_device::device_timer: Unknown CDE timer ID");
1593 }
1594 }
1595
1596
1597 //-------------------------------------------------
1598 // set_interrupt -
1599 //-------------------------------------------------
1600
set_interrupt(uint32_t intmask)1601 void m2_cde_device::set_interrupt(uint32_t intmask)
1602 {
1603 m_int_status |= (uint32_t)intmask;
1604 update_interrupts();
1605 }
1606
1607
1608 //-------------------------------------------------
1609 // update_interrupts -
1610 //-------------------------------------------------
1611
update_interrupts()1612 void m2_cde_device::update_interrupts()
1613 {
1614 if (m_int_status & m_int_enable)
1615 m_int_handler(ASSERT_LINE);
1616 else
1617 m_int_handler(CLEAR_LINE);
1618 }
1619
1620
1621
1622 /***************************************************************************
1623 PUBLIC FUNCTIONS
1624 ***************************************************************************/
1625
1626 //-------------------------------------------------
1627 // read -
1628 //-------------------------------------------------
1629
read(address_space & space,offs_t offset,uint32_t mem_mask)1630 uint32_t m2_cde_device::read(address_space &space, offs_t offset, uint32_t mem_mask)
1631 {
1632 const uint32_t byte_offs = offset << 2;
1633 uint32_t data = 0;
1634
1635 switch (byte_offs)
1636 {
1637 case CDE_DEVICE_ID:
1638 {
1639 data = 0x00010000;
1640 break;
1641 }
1642 case CDE_VERSION:
1643 {
1644 data = 0; // TODO
1645 break;
1646 }
1647 case CDE_SDBG_CNTL:
1648 {
1649 data = m_sdbg_cntl;
1650 break;
1651 }
1652 case CDE_SDBG_RD:
1653 {
1654 data = m_sdbg_in;
1655 break;
1656 }
1657 case CDE_INT_STS:
1658 {
1659 data = m_int_status;
1660 break;
1661 }
1662 case CDE_CD_STS_RD:
1663 {
1664 data = 0x000; // Status ready = 0x100
1665 break;
1666 }
1667 case CDE_INT_ENABLE:
1668 {
1669 data = m_int_enable;
1670 break;
1671 }
1672 case CDE_DEV_DETECT:
1673 {
1674 data = 0x0; // ?
1675 break;
1676 };
1677 case CDE_BBLOCK:
1678 {
1679 // 8, 80
1680 data = 0x80; // Needs to be non-zero
1681 break;
1682 }
1683 case CDE_UNIQ_ID_RD:
1684 {
1685 data = 0xffffffff; // ?
1686 break;
1687 }
1688 case CDE_BBLOCK_EN:
1689 {
1690 data = m_bblock_en;
1691 break;
1692 }
1693 case CDE_SYSTEM_CONF:
1694 {
1695 data = m_syscfg;
1696 break;
1697 }
1698 case CDE_MICRO_STATUS:
1699 {
1700 data = 0x20; // TODO
1701 break;
1702 }
1703 case CDE_MICRO_RWS:
1704 {
1705 break;
1706 }
1707 case CDE_VISA_DIS:
1708 {
1709 data = m_visa_dis;
1710 break;
1711 }
1712 case CDE_DMA1_CNTL:
1713 case CDE_DMA2_CNTL:
1714 {
1715 uint32_t ch = (byte_offs & 0x20) ? 1 : 0;
1716 data = m_dma[ch].m_cntl;
1717 break;
1718 }
1719 default:
1720 {
1721 //logerror("%s: CDE_R UNHANDLED: 0x%.8x 0x%.8x\n", machine().describe_context(), byte_offs, mem_mask));
1722 }
1723 }
1724
1725 return data;
1726 }
1727
1728
1729 //-------------------------------------------------
1730 // write -
1731 //-------------------------------------------------
1732
write(address_space & space,offs_t offset,uint32_t data,uint32_t mem_mask)1733 void m2_cde_device::write(address_space &space, offs_t offset, uint32_t data, uint32_t mem_mask)
1734 {
1735 uint32_t byte_offs = offset << 2;
1736 uint32_t dmach = byte_offs & 0x20 ? 1 : 0;
1737
1738 m2_reg_wmode wm_cw = byte_offs & 0x400 ? REG_CLEAR : REG_WRITE;
1739 m2_reg_wmode wm_cs = byte_offs & 0x400 ? REG_CLEAR : REG_SET;
1740
1741 byte_offs &= ~0x400;
1742
1743 switch (byte_offs)
1744 {
1745 case CDE_SDBG_CNTL:
1746 {
1747 // ........ ........ xxxxxxxx xxxx.... Clock scaler (written with 33MHz/38400 = 868)
1748 write_m2_reg(m_sdbg_cntl, data, wm_cw);
1749 break;
1750 }
1751 case CDE_SDBG_WRT:
1752 {
1753 m_sdbg_out_handler(data);
1754 set_interrupt(CDE_SDBG_WRT_DONE);
1755 break;
1756 }
1757 case CDE_INT_STS:
1758 {
1759 write_m2_reg(m_int_status, data, wm_cw);
1760 update_interrupts();
1761 break;
1762 }
1763 case CDE_INT_ENABLE:
1764 {
1765 write_m2_reg(m_int_enable, data, wm_cs);
1766 update_interrupts();
1767 break;
1768 }
1769 case CDE_RESET_CNTL:
1770 {
1771 if (data & 1)
1772 {
1773 // TODO: Should we reset both CPUs?
1774 downcast<cpu_device *>(&space.device())->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
1775
1776 // TODO: Is this correct?
1777 m_bblock_en = 0;
1778 }
1779 else if (data & 2)
1780 {
1781 // TODO: Hard reset
1782 }
1783
1784 break;
1785 }
1786 case CDE_CD_CMD_WRT:
1787 {
1788 //set_interrupt(CDE_CD_CMD_WRT_DONE); // ?
1789 //set_interrupt(CDE_CD_STS_FL_DONE); // ?
1790 break;
1791 };
1792 case CDE_UNIQ_ID_CMD:
1793 {
1794 // TODO: What is this?
1795 timer_set(attotime::from_usec(250), TIMER_ID_READY);
1796 break;
1797 }
1798 case CDE_BBLOCK:
1799 {
1800 break;
1801 }
1802
1803 case CDE_DEV0_SETUP:
1804 case CDE_DEV1_SETUP:
1805 case CDE_DEV2_SETUP:
1806 case CDE_DEV3_SETUP:
1807 case CDE_DEV4_SETUP:
1808 case CDE_DEV5_SETUP:
1809 case CDE_DEV6_SETUP:
1810 case CDE_DEV7_SETUP:
1811 {
1812 uint32_t id = (byte_offs - CDE_DEV0_SETUP) >> 3;
1813 write_m2_reg(m_bio_device[id].m_setup, data, wm_cw);
1814 break;
1815 }
1816
1817 case CDE_DEV0_CYCLE_TIME:
1818 case CDE_DEV1_CYCLE_TIME:
1819 case CDE_DEV2_CYCLE_TIME:
1820 case CDE_DEV3_CYCLE_TIME:
1821 case CDE_DEV4_CYCLE_TIME:
1822 case CDE_DEV5_CYCLE_TIME:
1823 case CDE_DEV6_CYCLE_TIME:
1824 case CDE_DEV7_CYCLE_TIME:
1825 {
1826 uint32_t id = (byte_offs - CDE_DEV0_CYCLE_TIME) >> 3;
1827 write_m2_reg(m_bio_device[id].m_cycle_time, data, wm_cw);
1828 break;
1829 }
1830
1831 // case CDE_SYSTEM_CONF:
1832 case CDE_VISA_DIS:
1833 {
1834 write_m2_reg(m_visa_dis, data, wm_cw);
1835 break;
1836 }
1837 case CDE_MICRO_RWS:
1838 case CDE_MICRO_WI:
1839 case CDE_MICRO_WOB:
1840 case CDE_MICRO_WO:
1841 case CDE_MICRO_STATUS:
1842 {
1843 break;
1844 }
1845
1846 case CDE_DMA1_CNTL:
1847 case CDE_DMA2_CNTL:
1848 {
1849 uint32_t &ctrl = m_dma[dmach].m_cntl;
1850 uint32_t old = ctrl;
1851
1852 write_m2_reg(ctrl, data, wm_cw);
1853
1854 if (!(old & CDE_DMA_RESET) && (ctrl & CDE_DMA_RESET))
1855 reset_dma(dmach);
1856
1857 if (!(old & CDE_DMA_CURR_VALID) && (ctrl & CDE_DMA_CURR_VALID))
1858 start_dma(dmach);
1859
1860 break;
1861 }
1862 case CDE_DMA1_CBAD:
1863 case CDE_DMA2_CBAD:
1864 {
1865 write_m2_reg(m_dma[dmach].m_cbad, data, wm_cw);
1866 break;
1867 }
1868 case CDE_DMA1_CPAD:
1869 case CDE_DMA2_CPAD:
1870 {
1871 write_m2_reg(m_dma[dmach].m_cpad, data, wm_cw);
1872 break;
1873 }
1874 case CDE_DMA1_CCNT:
1875 case CDE_DMA2_CCNT:
1876 {
1877 write_m2_reg(m_dma[dmach].m_ccnt, data, wm_cw);
1878 break;
1879 }
1880 default:
1881 {
1882 //logerror("%s: CDE_W UNHANDLED: 0x%.8x 0x%.8x 0x%.8x\n", machine().describe_context(), byte_offs, data, mem_mask);
1883 }
1884 }
1885 }
1886
1887
1888 //-------------------------------------------------
1889 // sdbg_in -
1890 //-------------------------------------------------
1891
sdbg_in(uint32_t data)1892 void m2_cde_device::sdbg_in(uint32_t data)
1893 {
1894 m_sdbg_in = data;
1895 set_interrupt(CDE_SDBG_RD_DONE);
1896 }
1897
1898
1899
1900
1901 /***************************************************************************
1902 PRIVATE FUNCTIONS
1903 ***************************************************************************/
1904
1905 //-------------------------------------------------
1906 // reset_dma - Reset a DMA channel
1907 //-------------------------------------------------
1908
reset_dma(uint32_t ch)1909 void m2_cde_device::reset_dma(uint32_t ch)
1910 {
1911 m_dma[ch].m_cntl = 0;
1912 m_dma[ch].m_timer->adjust(attotime::never);
1913 }
1914
1915
1916 //-------------------------------------------------
1917 // start_dma - DMA between the PowerBus and BioBus
1918 //-------------------------------------------------
1919
start_dma(uint32_t ch)1920 void m2_cde_device::start_dma(uint32_t ch)
1921 {
1922 dma_channel &dma_ch = m_dma[ch];
1923 address_space *dma_space = &m_cpu1->space();
1924
1925 // TODO: DMA timing is probably inaccurate
1926 attotime delay = attotime::from_nsec(10);// * dma_ch.m_ccnt;
1927
1928 // attotime delay = clocks_to_attotime(4 * dma_ch.m_ccnt);
1929 dma_ch.m_timer->adjust(delay);
1930
1931 if (dma_ch.m_cntl & CDE_DMA_DIRECTION)
1932 {
1933 // PowerBus to BioBus
1934 throw emu_fatalerror("m2_cde_device::start_dma: CDE PowerBus to BioBus DMA currently unsupported");
1935 }
1936 else
1937 {
1938 // BioBus to PowerBus
1939 #if 0
1940 logerror("%s: CDE DMA %u: [%.8x] -> [%.8x], 0x%.8x bytes\n", machine().describe_context(), ch, dma_ch.m_cbad, dma_ch.m_cpad, dma_ch.m_ccnt);
1941 #endif
1942 // Determine the BioBus device from the address
1943 const uint32_t slot = address_to_biobus_slot(dma_ch.m_cbad);
1944
1945 // Get the device parameters
1946 const uint32_t setup = m_bio_device[slot].m_setup;
1947
1948 if (setup & CDE_DATAWIDTH_16)
1949 {
1950 // 16-bit case
1951 if (dma_ch.m_ccnt & 1)
1952 throw emu_fatalerror("m2_cde_device::start_dma: 16-bit DMA: Byte count must be even?");
1953 if (dma_ch.m_cpad & 1)
1954 throw emu_fatalerror("m2_cde_device::start_dma: 16-bit DMA: DMA destination must be word aligned?");
1955
1956 const uint32_t srcinc = setup & CDE_READ_SETUP_IO ? 0 : 2;
1957
1958 while (dma_ch.m_ccnt > 0)
1959 {
1960 uint16_t data = dma_space->read_word_unaligned(dma_ch.m_cbad); // FIX ME
1961 dma_space->write_word(dma_ch.m_cpad, data);
1962
1963 dma_ch.m_cbad += srcinc;
1964 dma_ch.m_cpad += 2;
1965 dma_ch.m_ccnt -= 2;
1966 }
1967 }
1968 else
1969 {
1970 // 8-bit case
1971 const uint32_t srcinc = setup & CDE_READ_SETUP_IO ? 0 : 1;
1972
1973 fatalerror("8-bit DMA untested\n");
1974
1975 while (dma_ch.m_ccnt > 0)
1976 {
1977 uint8_t data = dma_space->read_byte(dma_ch.m_cbad);
1978 dma_space->write_byte(dma_ch.m_cpad, data);
1979
1980 dma_ch.m_cbad += srcinc;
1981 dma_ch.m_cpad += 1;
1982 dma_ch.m_ccnt -= 1;
1983 }
1984 }
1985 }
1986 }
1987
1988 //-------------------------------------------------
1989 // next_dma - Start the next DMA if set
1990 //-------------------------------------------------
1991
next_dma(uint32_t ch)1992 void m2_cde_device::next_dma(uint32_t ch)
1993 {
1994 dma_channel &dma_ch = m_dma[ch];
1995
1996 // TODO: HACK!
1997 #if 1
1998 m_cpu1->set_cache_dirty();
1999 #endif
2000
2001 if (dma_ch.m_ccnt != 0)
2002 throw emu_fatalerror("m2_cde_device::next_dma: DMA count non-zero during next DMA");
2003
2004 if (dma_ch.m_cntl & CDE_DMA_NEXT_VALID)
2005 {
2006 logerror("NEXT DMA CODE UNTESTED");
2007
2008 // Update current address and count registers
2009 dma_ch.m_cbad = dma_ch.m_nbad;
2010 dma_ch.m_cpad = dma_ch.m_npad;
2011 dma_ch.m_ccnt = dma_ch.m_ncnt;
2012 dma_ch.m_cntl |= CDE_DMA_CURR_VALID;
2013
2014 // Disable looping
2015 if (!(dma_ch.m_cntl & CDE_DMA_GO_FOREVER))
2016 dma_ch.m_cntl &= ~CDE_DMA_NEXT_VALID;
2017
2018 start_dma(ch);
2019 }
2020 else
2021 {
2022 // DMA complete
2023 dma_ch.m_cntl &= ~CDE_DMA_CURR_VALID;
2024 set_interrupt(ch == 0 ? CDE_DMA1_DONE : CDE_DMA2_DONE);
2025 }
2026 }
2027
2028
2029 /***************************************************************************
2030 MPEG DEVICE
2031 ***************************************************************************/
2032
2033 //-------------------------------------------------
2034 // m2_mpeg_device - constructor
2035 //-------------------------------------------------
2036
m2_mpeg_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)2037 m2_mpeg_device::m2_mpeg_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
2038 device_t(mconfig, M2_MPEG, tag, owner, clock)
2039 {
2040 }
2041
2042
2043 //-------------------------------------------------
2044 // device_start - device-specific startup
2045 //-------------------------------------------------
2046
device_start()2047 void m2_mpeg_device::device_start()
2048 {
2049
2050 }
2051
2052 //-------------------------------------------------
2053 // device_reset - device-specific reset
2054 //-------------------------------------------------
2055
device_reset()2056 void m2_mpeg_device::device_reset()
2057 {
2058
2059 }
2060
2061 //-------------------------------------------------
2062 // read
2063 //-------------------------------------------------
2064
read(offs_t offset)2065 uint32_t m2_mpeg_device::read(offs_t offset)
2066 {
2067 logerror("%s: MPEG READ: %08X\n", machine().describe_context(), offset);
2068 return 0;
2069 }
2070
2071 //-------------------------------------------------
2072 // write
2073 //-------------------------------------------------
2074
write(offs_t offset,uint32_t data)2075 void m2_mpeg_device::write(offs_t offset, uint32_t data)
2076 {
2077 logerror("%s: MPEG WRITE: %08X %08X\n", machine().describe_context(), offset, data);
2078 }
2079