1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4
5 dsp32.c
6 Core implementation for the portable DSP32 emulator.
7
8 ****************************************************************************
9
10 Important note:
11
12 At this time, the emulator is rather incomplete. However, it is
13 sufficiently complete to run both Race Drivin' and Hard Drivin's
14 Airborne, which is all I was after.
15
16 Things that still need to be implemented:
17
18 * interrupts
19 * carry-reverse add operations
20 * do loops
21 * ieee/dsp conversions
22 * input/output conversion
23 * serial I/O
24
25 In addition, there are several optimizations enabled which make
26 assumptions about the code which may not be valid for other
27 applications. Check dsp32ops.inc for details.
28
29 ***************************************************************************/
30
31 #include "emu.h"
32 #include "dsp32.h"
33 #include "dsp32dis.h"
34 #include "debugger.h"
35
36
37 //**************************************************************************
38 // DEBUGGING
39 //**************************************************************************
40
41 #define DETECT_MISALIGNED_MEMORY 0
42
43
44
45 //**************************************************************************
46 // CONSTANTS
47 //**************************************************************************
48
49 // internal register numbering for PIO registers
50 #define PIO_PAR 0
51 #define PIO_PDR 1
52 #define PIO_EMR 2
53 #define PIO_ESR 3
54 #define PIO_PCR 4
55 #define PIO_PIR 5
56 #define PIO_PARE 6
57 #define PIO_PDR2 7
58 #define PIO_RESERVED 8
59
60 #define UPPER (0x00ff << 8)
61 #define LOWER (0xff00 << 8)
62
63 // bits in the PCR register
64 #define PCR_RESET 0x001
65 #define PCR_REGMAP 0x002
66 #define PCR_ENI 0x004
67 #define PCR_DMA 0x008
68 #define PCR_AUTO 0x010
69 #define PCR_PDFs 0x020
70 #define PCR_PIFs 0x040
71 #define PCR_RES 0x080
72 #define PCR_DMA32 0x100
73 #define PCR_PIO16 0x200
74 #define PCR_FLG 0x400
75
76 // internal flag bits
77 #define UFLAGBIT 1
78 #define VFLAGBIT 2
79
80
81
82 //**************************************************************************
83 // MACROS
84 //**************************************************************************
85
86 // register mapping
87 #define R0 m_r[0]
88 #define R1 m_r[1]
89 #define R2 m_r[2]
90 #define R3 m_r[3]
91 #define R4 m_r[4]
92 #define R5 m_r[5]
93 #define R6 m_r[6]
94 #define R7 m_r[7]
95 #define R8 m_r[8]
96 #define R9 m_r[9]
97 #define R10 m_r[10]
98 #define R11 m_r[11]
99 #define R12 m_r[12]
100 #define R13 m_r[13]
101 #define R14 m_r[14]
102 #define PC m_r[15]
103 #define R0_ALT m_r[16]
104 #define R15 m_r[17]
105 #define R16 m_r[18]
106 #define R17 m_r[19]
107 #define R18 m_r[20]
108 #define R19 m_r[21]
109 #define RMM m_r[22]
110 #define RPP m_r[23]
111 #define R20 m_r[24]
112 #define R21 m_r[25]
113 #define DAUC m_r[26]
114 #define IOC m_r[27]
115 #define R22 m_r[29]
116 #define PCSH m_r[30]
117
118 #define A0 m_a[0]
119 #define A1 m_a[1]
120 #define A2 m_a[2]
121 #define A3 m_a[3]
122 #define A_0 m_a[4]
123 #define A_1 m_a[5]
124
125 #define zFLAG ((m_nzcflags & 0xffffff) == 0)
126 #define nFLAG ((m_nzcflags & 0x800000) != 0)
127 #define cFLAG ((m_nzcflags & 0x1000000) != 0)
128 #define vFLAG ((m_vflags & 0x800000) != 0)
129 #define ZFLAG (m_NZflags == 0)
130 #define NFLAG (m_NZflags < 0)
131 #define UFLAG (m_VUflags & UFLAGBIT)
132 #define VFLAG (m_VUflags & VFLAGBIT)
133
134
135
136 //**************************************************************************
137 // DEVICE INTERFACE
138 //**************************************************************************
139
140 DEFINE_DEVICE_TYPE(DSP32C, dsp32c_device, "dsp32c", "AT&T DSP32C")
141
142 //-------------------------------------------------
143 // dsp32c_device - constructor
144 //-------------------------------------------------
145
dsp32c_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)146 dsp32c_device::dsp32c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
147 : cpu_device(mconfig, DSP32C, tag, owner, clock),
148 m_program_config("program", ENDIANNESS_LITTLE, 32, 24),
149 m_pin(0),
150 m_pout(0),
151 m_ivtp(0),
152 m_nzcflags(0),
153 m_vflags(0),
154 m_NZflags(0),
155 m_VUflags(0),
156 m_abuf_index(0),
157 m_mbuf_index(0),
158 m_par(0),
159 m_pare(0),
160 m_pdr(0),
161 m_pdr2(0),
162 m_pir(0),
163 m_pcr(0),
164 m_emr(0),
165 m_esr(0),
166 m_pcw(0),
167 m_piop(0),
168 m_ibuf(0),
169 m_isr(0),
170 m_obuf(0),
171 m_osr(0),
172 m_iotemp(0),
173 m_lastp(0),
174 m_icount(0),
175 m_lastpins(0),
176 m_ppc(0),
177 m_output_pins_changed(*this)
178 {
179 // set our instruction counter
180 set_icountptr(m_icount);
181 }
182
183 //-------------------------------------------------
184 // device_start - start up the device
185 //-------------------------------------------------
186
device_start()187 void dsp32c_device::device_start()
188 {
189 m_output_pins_changed.resolve_safe();
190
191 // get our address spaces
192 space(AS_PROGRAM).cache(m_cache);
193 space(AS_PROGRAM).specific(m_program);
194
195 // register our state for the debugger
196 state_add(STATE_GENPC, "GENPC", m_r[15]).noshow();
197 state_add(STATE_GENPCBASE, "CURPC", m_ppc).noshow();
198 state_add(STATE_GENSP, "GENSP", m_r[21]).noshow();
199 state_add(STATE_GENFLAGS, "GENFLAGS", m_iotemp).callimport().callexport().formatstr("%6s").noshow();
200 state_add(DSP32_PC, "PC", m_r[15]).mask(0xffffff);
201 for (int regnum = 0; regnum <= 14; regnum++)
202 state_add(DSP32_R0 + regnum, string_format("R%d", regnum).c_str(), m_r[regnum]).mask(0xffffff);
203 state_add(DSP32_R15, "R15", m_r[17]).mask(0xffffff);
204 state_add(DSP32_R16, "R16", m_r[18]).mask(0xffffff);
205 state_add(DSP32_R17, "R17", m_r[19]).mask(0xffffff);
206 state_add(DSP32_R18, "R18", m_r[20]).mask(0xffffff);
207 state_add(DSP32_R19, "R19", m_r[21]).mask(0xffffff);
208 state_add(DSP32_R20, "R20", m_r[24]).mask(0xffffff);
209 state_add(DSP32_R21, "R21", m_r[25]).mask(0xffffff);
210 state_add(DSP32_R22, "R22", m_r[29]).mask(0xffffff);
211 state_add(DSP32_PIN, "PIN", m_pin).mask(0xffffff);
212 state_add(DSP32_POUT, "POUT", m_pout).mask(0xffffff);
213 state_add(DSP32_IVTP, "IVTP", m_ivtp).mask(0xffffff);
214 state_add(DSP32_A0, "A0", m_a[0]).formatstr("%8s");
215 state_add(DSP32_A1, "A1", m_a[1]).formatstr("%8s");
216 state_add(DSP32_A2, "A2", m_a[2]).formatstr("%8s");
217 state_add(DSP32_A3, "A3", m_a[3]).formatstr("%8s");
218 state_add(DSP32_DAUC, "DAUC", m_r[26]).mask(0xff);
219 state_add(DSP32_PAR, "PAR", m_par);
220 state_add(DSP32_PDR, "PDR", m_pdr);
221 state_add(DSP32_PIR, "PIR", m_pir);
222 state_add(DSP32_PCR, "PCR", m_iotemp).mask(0x3ff).callimport();
223 state_add(DSP32_EMR, "EMR", m_emr);
224 state_add(DSP32_ESR, "ESR", m_esr);
225 state_add(DSP32_PCW, "PCW", m_pcw);
226 state_add(DSP32_PIOP, "PIOP", m_piop);
227 state_add(DSP32_IBUF, "IBUF", m_ibuf);
228 state_add(DSP32_ISR, "ISR", m_isr);
229 state_add(DSP32_OBUF, "OBUF", m_obuf);
230 state_add(DSP32_OSR, "OSR" , m_osr);
231 state_add(DSP32_IOC, "IOC", m_r[27]).mask(0xfffff);
232
233 // register our state for saving
234 save_item(NAME(m_r));
235 save_item(NAME(m_pin));
236 save_item(NAME(m_pout));
237 save_item(NAME(m_ivtp));
238 save_item(NAME(m_nzcflags));
239 save_item(NAME(m_vflags));
240 save_item(NAME(m_a));
241 save_item(NAME(m_NZflags));
242 save_item(NAME(m_VUflags));
243 save_item(NAME(m_abuf));
244 save_item(NAME(m_abufreg));
245 save_item(NAME(m_abufVUflags));
246 save_item(NAME(m_abufNZflags));
247 save_item(NAME(m_abufcycle));
248 save_item(NAME(m_abuf_index));
249 save_item(NAME(m_mbufaddr));
250 save_item(NAME(m_mbufdata));
251 save_item(NAME(m_par));
252 save_item(NAME(m_pare));
253 save_item(NAME(m_pdr));
254 save_item(NAME(m_pdr2));
255 save_item(NAME(m_pir));
256 save_item(NAME(m_pcr));
257 save_item(NAME(m_emr));
258 save_item(NAME(m_esr));
259 save_item(NAME(m_pcw));
260 save_item(NAME(m_piop));
261 save_item(NAME(m_ibuf));
262 save_item(NAME(m_isr));
263 save_item(NAME(m_obuf));
264 save_item(NAME(m_osr));
265 save_item(NAME(m_lastpins));
266 save_item(NAME(m_ppc));
267 }
268
269
270 //-------------------------------------------------
271 // device_reset - reset the device
272 //-------------------------------------------------
273
device_reset()274 void dsp32c_device::device_reset()
275 {
276 // reset goes to 0
277 PC = 0;
278
279 // clear some registers
280 m_pcw &= 0x03ff;
281 m_pcr = PCR_RESET;
282 m_esr = 0;
283 m_emr = 0xffff;
284
285 // clear the output pins
286 m_output_pins_changed(0);
287
288 // initialize fixed registers
289 R0 = R0_ALT = 0;
290 RMM = -1;
291 RPP = 1;
292 A_0 = 0.0;
293 A_1 = 1.0;
294
295 // init internal stuff
296 m_abufcycle[0] = m_abufcycle[1] = m_abufcycle[2] = m_abufcycle[3] = 12345678;
297 m_mbufaddr[0] = m_mbufaddr[1] = m_mbufaddr[2] = m_mbufaddr[3] = 1;
298 }
299
300
301 //-------------------------------------------------
302 // memory_space_config - return the configuration
303 // of the specified address space, or nullptr if
304 // the space doesn't exist
305 //-------------------------------------------------
306
memory_space_config() const307 device_memory_interface::space_config_vector dsp32c_device::memory_space_config() const
308 {
309 return space_config_vector {
310 std::make_pair(AS_PROGRAM, &m_program_config)
311 };
312 }
313
314
315 //-------------------------------------------------
316 // state_import - import state into the device,
317 // after it has been set
318 //-------------------------------------------------
319
state_import(const device_state_entry & entry)320 void dsp32c_device::state_import(const device_state_entry &entry)
321 {
322 switch (entry.index())
323 {
324 case STATE_GENFLAGS:
325 break;
326
327 case DSP32_PCR:
328 update_pcr(m_iotemp);
329 break;
330
331 default:
332 fatalerror("dsp32c_device::state_import called for unexpected value\n");
333 }
334 }
335
336
337 //-------------------------------------------------
338 // state_export - export state out of the device
339 //-------------------------------------------------
340
state_export(const device_state_entry & entry)341 void dsp32c_device::state_export(const device_state_entry &entry)
342 {
343 switch (entry.index())
344 {
345 case STATE_GENFLAGS:
346 // no actual flags register, so just make something up
347 m_iotemp = (zFLAG ? 0x01 : 0) |
348 (nFLAG ? 0x02 : 0) |
349 (cFLAG ? 0x04 : 0) |
350 (vFLAG ? 0x08 : 0) |
351 (ZFLAG ? 0x10 : 0) |
352 (NFLAG ? 0x20 : 0) |
353 (UFLAG ? 0x40 : 0) |
354 (VFLAG ? 0x80 : 0);
355 break;
356
357 case DSP32_PCR:
358 m_iotemp = m_pcr;
359 break;
360
361 default:
362 fatalerror("dsp32c_device::state_export called for unexpected value\n");
363 }
364 }
365
366
367 //-------------------------------------------------
368 // state_string_export - export state as a string
369 // for the debugger
370 //-------------------------------------------------
371
state_string_export(const device_state_entry & entry,std::string & str) const372 void dsp32c_device::state_string_export(const device_state_entry &entry, std::string &str) const
373 {
374 switch (entry.index())
375 {
376 case STATE_GENFLAGS:
377 str = string_format("%c%c%c%c%c%c%c%c",
378 NFLAG ? 'N':'.',
379 ZFLAG ? 'Z':'.',
380 UFLAG ? 'U':'.',
381 VFLAG ? 'V':'.',
382 nFLAG ? 'n':'.',
383 zFLAG ? 'z':'.',
384 cFLAG ? 'c':'.',
385 vFLAG ? 'v':'.');
386 break;
387
388 case DSP32_A0:
389 case DSP32_A1:
390 case DSP32_A2:
391 case DSP32_A3:
392 str = string_format("%8g", *(double *)entry.dataptr());
393 break;
394 }
395 }
396
397
398 //-------------------------------------------------
399 // disassemble - call the disassembly
400 // helper function
401 //-------------------------------------------------
402
create_disassembler()403 std::unique_ptr<util::disasm_interface> dsp32c_device::create_disassembler()
404 {
405 return std::make_unique<dsp32c_disassembler>();
406 }
407
408
409
410 //**************************************************************************
411 // MEMORY ACCESSORS
412 //**************************************************************************
413
ROPCODE(offs_t pc)414 inline uint32_t dsp32c_device::ROPCODE(offs_t pc)
415 {
416 return m_cache.read_dword(pc);
417 }
418
RBYTE(offs_t addr)419 inline uint8_t dsp32c_device::RBYTE(offs_t addr)
420 {
421 return m_program.read_byte(addr);
422 }
423
WBYTE(offs_t addr,uint8_t data)424 inline void dsp32c_device::WBYTE(offs_t addr, uint8_t data)
425 {
426 m_program.write_byte(addr, data);
427 }
428
RWORD(offs_t addr)429 inline uint16_t dsp32c_device::RWORD(offs_t addr)
430 {
431 #if DETECT_MISALIGNED_MEMORY
432 if (!WORD_ALIGNED(addr))
433 osd_printf_error("Unaligned word read @ %06X, PC=%06X\n", addr, PC);
434 #endif
435 return m_program.read_word(addr);
436 }
437
RLONG(offs_t addr)438 inline uint32_t dsp32c_device::RLONG(offs_t addr)
439 {
440 #if DETECT_MISALIGNED_MEMORY
441 if (!DWORD_ALIGNED(addr))
442 osd_printf_error("Unaligned long read @ %06X, PC=%06X\n", addr, PC);
443 #endif
444 return m_program.read_dword(addr);
445 }
446
WWORD(offs_t addr,uint16_t data)447 inline void dsp32c_device::WWORD(offs_t addr, uint16_t data)
448 {
449 #if DETECT_MISALIGNED_MEMORY
450 if (!WORD_ALIGNED(addr))
451 osd_printf_error("Unaligned word write @ %06X, PC=%06X\n", addr, PC);
452 #endif
453 m_program.write_word(addr, data);
454 }
455
WLONG(offs_t addr,uint32_t data)456 inline void dsp32c_device::WLONG(offs_t addr, uint32_t data)
457 {
458 #if DETECT_MISALIGNED_MEMORY
459 if (!DWORD_ALIGNED(addr))
460 osd_printf_error("Unaligned long write @ %06X, PC=%06X\n", addr, PC);
461 #endif
462 m_program.write_dword(addr, data);
463 }
464
465
466
467 //**************************************************************************
468 // IRQ HANDLING
469 //**************************************************************************
470
check_irqs()471 void dsp32c_device::check_irqs()
472 {
473 // finish me!
474 }
475
476
set_irq_line(int irqline,int state)477 void dsp32c_device::set_irq_line(int irqline, int state)
478 {
479 // finish me!
480 }
481
482
483
484 //**************************************************************************
485 // REGISTER HANDLING
486 //**************************************************************************
487
update_pcr(uint16_t newval)488 void dsp32c_device::update_pcr(uint16_t newval)
489 {
490 uint16_t oldval = m_pcr;
491 m_pcr = newval;
492
493 // reset the chip if we get a reset
494 if ((oldval & PCR_RESET) == 0 && (newval & PCR_RESET) != 0)
495 reset();
496 }
497
498
499
500 //**************************************************************************
501 // OUTPUT HANDLING
502 //**************************************************************************
503
update_pins(void)504 void dsp32c_device::update_pins(void)
505 {
506 if (m_pcr & PCR_ENI)
507 {
508 uint16_t newoutput = 0;
509
510 if (m_pcr & PCR_PIFs)
511 newoutput |= DSP32_OUTPUT_PIF;
512
513 if (m_pcr & PCR_PDFs)
514 newoutput |= DSP32_OUTPUT_PDF;
515
516 if (newoutput != m_lastpins)
517 {
518 m_lastpins = newoutput;
519 m_output_pins_changed(newoutput);
520 }
521 }
522 }
523
524
525
526 //**************************************************************************
527 // CORE INCLUDE
528 //**************************************************************************
529
530 #include "dsp32ops.hxx"
531
532
533
534 //**************************************************************************
535 // CORE EXECUTION LOOP
536 //**************************************************************************
537
538 //-------------------------------------------------
539 // execute_min_cycles - return minimum number of
540 // cycles it takes for one instruction to execute
541 //-------------------------------------------------
542
execute_min_cycles() const543 uint32_t dsp32c_device::execute_min_cycles() const noexcept
544 {
545 return 4;
546 }
547
548
549 //-------------------------------------------------
550 // execute_max_cycles - return maximum number of
551 // cycles it takes for one instruction to execute
552 //-------------------------------------------------
553
execute_max_cycles() const554 uint32_t dsp32c_device::execute_max_cycles() const noexcept
555 {
556 return 4;
557 }
558
559
560 //-------------------------------------------------
561 // execute_input_lines - return the number of
562 // input/interrupt lines
563 //-------------------------------------------------
564
execute_input_lines() const565 uint32_t dsp32c_device::execute_input_lines() const noexcept
566 {
567 return 2;
568 }
569
570
execute_set_input(int inputnum,int state)571 void dsp32c_device::execute_set_input(int inputnum, int state)
572 {
573 }
574
575
execute_run()576 void dsp32c_device::execute_run()
577 {
578 // skip if halted
579 if ((m_pcr & PCR_RESET) == 0)
580 {
581 m_icount = 0;
582 return;
583 }
584
585 // update buffered accumulator values
586 m_abufcycle[0] += m_icount;
587 m_abufcycle[1] += m_icount;
588 m_abufcycle[2] += m_icount;
589 m_abufcycle[3] += m_icount;
590
591 // handle interrupts
592 check_irqs();
593
594 while (m_icount > 0)
595 execute_one();
596
597 // normalize buffered accumulator values
598 m_abufcycle[0] -= m_icount;
599 m_abufcycle[1] -= m_icount;
600 m_abufcycle[2] -= m_icount;
601 m_abufcycle[3] -= m_icount;
602 }
603
604
605
606 //**************************************************************************
607 // PARALLEL INTERFACE WRITES
608 //**************************************************************************
609
610 const uint32_t dsp32c_device::s_regmap[4][16] =
611 {
612 { // DSP32 compatible mode
613 PIO_PAR|LOWER, PIO_PAR|UPPER, PIO_PDR|LOWER, PIO_PDR|UPPER,
614 PIO_EMR|LOWER, PIO_EMR|UPPER, PIO_ESR|LOWER, PIO_PCR|LOWER,
615 PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER,
616 PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER, PIO_PIR|UPPER
617 },
618 { // DSP32C 8-bit mode
619 PIO_PAR|LOWER, PIO_PAR|UPPER, PIO_PDR|LOWER, PIO_PDR|UPPER,
620 PIO_EMR|LOWER, PIO_EMR|UPPER, PIO_ESR|LOWER, PIO_PCR|LOWER,
621 PIO_PIR|LOWER, PIO_PIR|UPPER, PIO_PCR|UPPER, PIO_PARE|LOWER,
622 PIO_PDR2|LOWER,PIO_PDR2|UPPER,PIO_RESERVED, PIO_RESERVED
623 },
624 { // DSP32C illegal mode
625 PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED,
626 PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED,
627 PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED,
628 PIO_RESERVED, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED
629 },
630 { // DSP32C 16-bit mode
631 PIO_PAR, PIO_RESERVED, PIO_PDR, PIO_RESERVED,
632 PIO_EMR, PIO_RESERVED, PIO_ESR|LOWER, PIO_PCR,
633 PIO_PIR, PIO_RESERVED, PIO_RESERVED, PIO_PARE|LOWER,
634 PIO_PDR2, PIO_RESERVED, PIO_RESERVED, PIO_RESERVED
635 }
636 };
637
638
639
640 //**************************************************************************
641 // PARALLEL INTERFACE WRITES
642 //**************************************************************************
643
dma_increment()644 void dsp32c_device::dma_increment()
645 {
646 if (m_pcr & PCR_AUTO)
647 {
648 int amount = (m_pcr & PCR_DMA32) ? 4 : 2;
649 m_par += amount;
650 if (m_par < amount)
651 m_pare++;
652 }
653 }
654
655
dma_load()656 void dsp32c_device::dma_load()
657 {
658 // only process if DMA is enabled
659 if (m_pcr & PCR_DMA)
660 {
661 uint32_t addr = m_par | (m_pare << 16);
662
663 // 16-bit case
664 if (!(m_pcr & PCR_DMA32))
665 m_pdr = RWORD(addr & 0xfffffe);
666
667 // 32-bit case
668 else
669 {
670 uint32_t temp = RLONG(addr & 0xfffffc);
671 m_pdr = temp >> 16;
672 m_pdr2 = temp & 0xffff;
673 }
674
675 // set the PDF flag to indicate we have data ready
676 update_pcr(m_pcr | PCR_PDFs);
677 }
678 }
679
680
dma_store()681 void dsp32c_device::dma_store()
682 {
683 // only process if DMA is enabled
684 if (m_pcr & PCR_DMA)
685 {
686 uint32_t addr = m_par | (m_pare << 16);
687
688 // 16-bit case
689 if (!(m_pcr & PCR_DMA32))
690 WWORD(addr & 0xfffffe, m_pdr);
691
692 // 32-bit case
693 else
694 WLONG(addr & 0xfffffc, (m_pdr << 16) | m_pdr2);
695
696 // clear the PDF flag to indicate we have taken the data
697 update_pcr(m_pcr & ~PCR_PDFs);
698 }
699 }
700
701
pio_w(int reg,int data)702 void dsp32c_device::pio_w(int reg, int data)
703 {
704 uint16_t mask;
705 uint8_t mode;
706
707 // look up register and mask
708 mode = ((m_pcr >> 8) & 2) | ((m_pcr >> 1) & 1);
709 reg = s_regmap[mode][reg];
710 mask = reg >> 8;
711 if (mask == 0x00ff) data <<= 8;
712 data &= ~mask;
713 reg &= 0xff;
714
715 // switch off the register
716 switch (reg)
717 {
718 case PIO_PAR:
719 m_par = (m_par & mask) | data;
720
721 // trigger a load on the upper half
722 if (!(mask & 0xff00))
723 dma_load();
724 break;
725
726 case PIO_PARE:
727 m_pare = (m_pare & mask) | data;
728 break;
729
730 case PIO_PDR:
731 m_pdr = (m_pdr & mask) | data;
732
733 // trigger a write and PDF setting on the upper half
734 if (!(mask & 0xff00))
735 {
736 dma_store();
737 dma_increment();
738 update_pins();
739 }
740 break;
741
742 case PIO_PDR2:
743 m_pdr2 = (m_pdr2 & mask) | data;
744 break;
745
746 case PIO_EMR:
747 m_emr = (m_emr & mask) | data;
748 break;
749
750 case PIO_ESR:
751 m_esr = (m_esr & mask) | data;
752 break;
753
754 case PIO_PCR:
755 mask |= 0x0060;
756 data &= ~mask;
757 update_pcr((m_pcr & mask) | data);
758 break;
759
760 case PIO_PIR:
761 m_pir = (m_pir & mask) | data;
762
763 // set PIF on upper half
764 if (!(mask & 0xff00))
765 {
766 update_pcr(m_pcr | PCR_PIFs);
767 update_pins();
768 }
769 break;
770
771 // error case
772 default:
773 logerror("dsp32_pio_w called on invalid register %d\n", reg);
774 break;
775 }
776 }
777
778
779
780 //**************************************************************************
781 // PARALLEL INTERFACE READS
782 //**************************************************************************
783
pio_r(int reg)784 int dsp32c_device::pio_r(int reg)
785 {
786 uint16_t mask, result = 0xffff;
787 uint8_t mode, shift = 0;
788
789 // look up register and mask
790 mode = ((m_pcr >> 8) & 2) | ((m_pcr >> 1) & 1);
791 reg = s_regmap[mode][reg];
792 mask = reg >> 8;
793 if (mask == 0x00ff) mask = 0xff00, shift = 8;
794 reg &= 0xff;
795
796 // switch off the register
797 switch (reg)
798 {
799 case PIO_PAR:
800 result = m_par | 1;
801 break;
802
803 case PIO_PARE:
804 result = m_pare;
805 break;
806
807 case PIO_PDR:
808 result = m_pdr;
809
810 // trigger an increment on the lower half
811 if (shift != 8)
812 dma_increment();
813
814 // trigger a fetch on the upper half
815 if (!(mask & 0xff00))
816 {
817 dma_load();
818 update_pins();
819 }
820 break;
821
822 case PIO_PDR2:
823 result = m_pdr2;
824 break;
825
826 case PIO_EMR:
827 result = m_emr;
828 break;
829
830 case PIO_ESR:
831 result = m_esr;
832 break;
833
834 case PIO_PCR:
835 result = m_pcr;
836 break;
837
838 case PIO_PIR:
839 if (!(mask & 0xff00))
840 {
841 update_pcr(m_pcr & ~PCR_PIFs); // clear PIFs
842 update_pins();
843 }
844 result = m_pir;
845 break;
846
847 // error case
848 default:
849 logerror("dsp32_pio_w called on invalid register %d\n", reg);
850 break;
851 }
852
853 return (result >> shift) & ~mask;
854 }
855