1 /*****************************************************************************
2 *
3 * upd7810.c
4 * Portable uPD7810/11, 7810H/11H, 78C10/C11/C14 emulator V0.3
5 *
6 * Copyright (c) 2001 Juergen Buchmueller, all rights reserved.
7 *
8 * Copyright (C) 1998,1999,2000 Juergen Buchmueller, all rights reserved.
9 * You can contact me at juergen@mame.net or pullmoll@stop1984.com
10 *
11 * - This source code is released as freeware for non-commercial purposes
12 * as part of the M.A.M.E. (Multiple Arcade Machine Emulator) project.
13 * The licensing terms of MAME apply to this piece of code for the MAME
14 * project and derviative works, as defined by the MAME license. You
15 * may opt to make modifications, improvements or derivative works under
16 * that same conditions, and the MAME project may opt to keep
17 * modifications, improvements or derivatives under their terms exclusively.
18 *
19 * - Alternatively you can choose to apply the terms of the "GPL" (see
20 * below) to this - and only this - piece of code or your derivative works.
21 * Note that in no case your choice can have any impact on any other
22 * source code of the MAME project, or binary, or executable, be it closely
23 * or losely related to this piece of code.
24 *
25 * - At your choice you are also free to remove either licensing terms from
26 * this file and continue to use it under only one of the two licenses. Do this
27 * if you think that licenses are not compatible (enough) for you, or if you
28 * consider either license 'too restrictive' or 'too free'.
29 *
30 * - GPL (GNU General Public License)
31 * This program is free software; you can redistribute it and/or
32 * modify it under the terms of the GNU General Public License
33 * as published by the Free Software Foundation; either version 2
34 * of the License, or (at your option) any later version.
35 *
36 * This program is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License
42 * along with this program; if not, write to the Free Software
43 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
44 *
45 *
46 * This work is based on the
47 * "NEC Electronics User's Manual, April 1987"
48 *
49 * NS20030115:
50 * - fixed INRW_wa()
51 * - TODO: add 7807, differences are listed below.
52 * I only added support for these opcodes needed by homedata.c (yes, I am
53 * lazy):
54 * 4C CE (MOV A,PT)
55 * 48 AC (EXA)
56 * 48 AD (EXR)
57 * 48 AE (EXH)
58 * 48 AF (EXX)
59 * 50 xx (SKN bit)
60 * 58 xx (SETB)
61 * 5B xx (CLR)
62 * 5D xx (SK bit)
63 *
64 *****************************************************************************/
65 /* Hau around 23 May 2004
66 gta, gti, dgt fixed
67 working reg opcodes fixed
68 sio input fixed
69 --
70 PeT around 19 February 2002
71 type selection/gamemaster support added
72 gamemaster init hack? added
73 ORAX added
74 jre negativ fixed
75 prefixed opcodes skipping fixed
76 interrupts fixed and improved
77 sub(and related)/add/daa flags fixed
78 mvi ports,... fixed
79 rll, rlr, drll, drlr fixed
80 rets fixed
81 l0, l1 skipping fixed
82 calt fixed
83 */
84
85 /*
86
87 7807 DESCRIPTION
88
89
90
91 PA0 1 64 Vcc
92 PA1 2 63 Vdd
93 PA2 3 62 PD7/AD7
94 PA3 4 61 PD6/AD6
95 PA4 5 60 PD5/AD5
96 PA5 6 59 PD4/AD4
97 PA6 7 58 PD3/AD3
98 PA7 8 57 PD2/AD2
99 PB0 9 56 PD1/AD1
100 PB1 10 55 PD0/AD0
101 PB2 11 54 PF7/AB15
102 PB3 12 53 PF6/AB14
103 PB4 13 52 PF5/AB13
104 PB5 14 51 PF4/AB12
105 PB6 15 50 PF3/AB11
106 PB7 16 49 PF2/AB10
107 PC0 17 48 PF1/AB9
108 PC1 18 47 PF0/AB8
109 PC2 19 46 ALE
110 PC3 20 45 WR*
111 PC4 21 44 RD*
112 PC5 22 43 HLDA
113 PC6 23 42 HOLD
114 PC7 24 41 PT7
115 NMI* 25 40 PT6
116 INT1 26 39 PT5
117 MODE1 27 38 PT4
118 RESET* 28 37 PT3
119 MODE0 29 36 PT2
120 X2 30 35 PT1
121 X1 31 34 PT0
122 Vss 32 33 Vth
123
124 PA, PB, PC, PD, and PF is bidirectional I/O port
125 and PT is comparator input port in uPD7808.
126 uPD7807 uses PD port as data I/O and bottom address output,
127 and uses PF port as top address output.
128
129 NMI* is non maskable interrupt input signal (negative edge trigger).
130
131 INT1 is interrupt input (positive edge trigger). It can be used as
132 AC zero-cross input or trigger source of 16bit timer counter.
133
134 MODE0 and MODE1 is input terminal which decides total amount of
135 external memory of uPD7807 (4KByte, 16KBYte, and 64KByte).
136 It also decides number of PF ports used as top address output.
137 4KByte mode: PF0~PF3=address output, PF4~PF7=data I/O port
138 16KByte mode: PF0~PF5=address output, PF6~PF7=data I/O port
139 64KByte mode: PF0~PF7=address output
140
141 RESET* is system rest terminal.
142
143 X1 and X2 does clock signal generation (connect OSC and condenser).
144
145 Vth is used to determine threshold voltage for PT port.
146 PT0~PT7 is connected to + input of each comparator,
147 and Vth deterimnes voltage connected to - input of PT0~PT7.
148 But the voltage of Vth is not directly connected to comapators.
149 It is connected via 16-level programmable voltage separate circuit.
150
151 HOLD and HLDA is terminal for DMA. RD*, WR*, and ALE is bus
152 interface signal (they are same type of Intel 8085).
153 Unlike 8085, I/O address space is not available, so IO /M* signal
154 does not exist. Read/write of external memory can be done
155 by RD*, WR*, and ALE only.
156
157 Vcc and Vss is main power source. Vdd is backup power source
158 for internal RWM (32 Byte).
159
160
161 PA and PB is I/O port. They have control register MA and MB.
162 If control register is set to 1, the port is input.
163 If control register is set to 0, the port is output.
164 They are set to 1 by reset.
165
166 PT is input-only port. It is consisted of input terminal PT0~PT7
167 and Vth (set threshold voltage). Each PT input has analog comparator
168 and latch, and + input of analog comparator is connected to
169 PT terminal. Every - input of analog comparator is connected
170 to devided voltage of Vth. Voltage dividing level can be set by
171 bottom 4bits of MT (mode T) register. The range is 1/16~16/16 of Vth.
172
173 Other internal I/Os are
174 8bit timer (x2): Upcounter. If the counter matches to specified value,
175 the timer is reset and counts again from 0.
176 You can also set it to generate interrupt, or invert output flip-flop
177 when the counter matches to specified value.
178 Furthermore, you can output that flip-flop output to PC4/TO output,
179 connect it to clock input of timer/event counter or watchdog timer.
180 Or you can use it as bitrate clock of serial interface.
181 Note: There is only 1 output flip-flop for 2 timers.
182 If you use it for timer output of 1 timer, another timer cannot be used
183 for other than interrupt generator.
184 Clock input for timer can be switched between internal clock (2 type)
185 or PC3/TI input. You can set 1 timer's match-output as another timer's
186 clock input, so that you can use them as 1 16bit timer.
187
188 16bit timer/event counter (x1): It can be used as
189 - Interval timer
190 - External event counter
191 - Frequency measurement
192 - Pulse width measurement
193 - Programmable rectangle wave output
194 - One pulse output
195 Related terminals are PC5/CI input, PC6/CO0 output, and PC7/CO1.
196 You can measure CI input's H duration, or you can output timing signal
197 (with phase difference) to CO0 and CO1.
198
199 serial I/F (x1): has 3 modes.
200 - Asynchronous mode
201 - Synchronous mode
202 - I/O interface mode
203 In all 3 modes, bitrate can be internal fixed clock, or timer output,
204 or external clock.
205 In asynchronous mode, you can
206 - switch 7bit/8bit data
207 - set parity ON/OFF and EVEN/ODD
208 - set 1/2 stop bit
209
210
211
212
213 DIFFERENCES BETWEEN 7810 and 7807
214
215 --------------------------
216 8bit transfer instructions
217 --------------------------
218
219 7810
220 inst. 1st byte 2nd byte state action
221 EXX 00001001 4 Swap BC DE HL
222 EXA 00001000 4 Swap VA EA
223 EXH 01010000 4 Swap HL
224 BLOCK 00110001 13(C+1) (DE)+ <- (HL)+, C <- C - 1, until CY
225
226 7807
227 inst. 1st byte 2nd byte state action
228 EXR 01001000 10101101 8 Swap VA BC DE HL EA
229 EXX 01001000 10101111 8 Swap BC DE HL
230 EXA 01001000 10101100 8 Swap VA EA
231 EXH 01001000 10101110 8 Swap HL
232 BLOCK D+ 00010000 13(C+1) (DE)+ <- (HL)+, C <- C - 1, until CY
233 BLOCK D- 00010001 13(C+1) (DE)- <- (HL)-, C <- C - 1, until CY
234
235
236 ---------------------------
237 16bit transfer instructions
238 ---------------------------
239 All instructions are same except operand sr4 of DMOV instruction.
240 7810
241 V0-sr4 -function
242 0-ECNT-timer/event counter upcounter
243 1-ECPT-timer/event counter capture
244
245 7807
246 V1-V0- sr4 -function
247 0- 0-ECNT -timer/event counter upcounter
248 0- 1-ECPT0-timer/event counter capture 0
249 1- 0-ECPT1-timer/event counter capture 1
250
251
252 -----------------------------------------
253 8bit operation instructions for registers
254 -----------------------------------------
255 All instructions are same.
256
257
258 --------------------------------------
259 8bit operation instructions for memory
260 --------------------------------------
261 All instructions are same.
262
263
264 -----------------------------------------
265 Operation instructions for immediate data
266 -----------------------------------------
267 uPD7807 has read-only PT port and special register group sr5 for it.
268 ins. 1st byte 2nd byte 3rd 4th state func
269 GTI sr5, byte 01100100 s0101sss dd 14 !CY sr5 - byte - 1
270 LTI sr5, byte 01100100 s0111sss dd 14 CY sr5 - byte
271 NEI sr5, byte 01100100 s1101sss dd 14 !Z sr5 - byte
272 EQI sr5, byte 01100100 s1111sss dd 14 Z sr5 - byte
273 ONI sr5, byte 01100100 s1001sss dd 14 !Z sr5 & byte
274 OFFI sr5, byte 01100100 s1011sss dd 14 Z sr5 & byte
275
276 S5-S4-S3-S2-S1-S0-sr -sr1-sr2-sr5-register function
277 0 0 1 1 1 0 --- PT --- PT comparator input port T data
278 1 0 0 1 0 0 WDM WDM --- --- watchdog timer mode register
279 1 0 0 1 0 1 MT --- --- --- port T mode
280
281 7807 doesn't have registers below
282 0 0 1 0 0 0 ANM ANM ANM A/D channel mode
283 1 0 0 0 0 0 --- CR0 --- A/D conversion result 0
284 1 0 0 0 0 1 --- CR1 --- A/D conversion result 1
285 1 0 0 0 1 0 --- CR2 --- A/D conversion result 2
286 1 0 0 0 1 1 --- CR3 --- A/D conversion result 3
287 1 0 1 0 0 0 ZCM --- --- zero cross mode
288
289 Special register operand (includes registers for I/O ports) has
290 6 groups - sr, sr1, sr2, sr3, sr4, and sr5. Among these groups,
291 sr, sr1, sr2, and sr5 includes registers described in the table
292 below, and expressed as bit pattern S5-S0.
293
294 S5S4S3S2S1S0 sr sr1 sr2 sr5 register function
295 0 0 0 0 0 0 PA PA PA PA port A
296 0 0 0 0 0 1 PB PB PB PB port B
297 0 0 0 0 1 0 PC PC PC PC port C
298 0 0 0 0 1 1 PD PD PD PD port D
299 0 0 0 1 0 1 PF PF PF PF port F
300 0 0 0 1 1 0 MKH MKH MKH MKH mask high
301 0 0 0 1 1 1 MKL MKL MKL MKL mask low
302 0 0 1 0 0 1 SMH SMH SMH SMH serial mode high
303 0 0 1 0 1 0 SML --- --- --- serial mode low
304 0 0 1 0 1 1 EOM EOM EOM EOM timer/event counter output mode
305 0 0 1 1 0 0 ETMM --- --- --- timer/event counter mode
306 0 0 1 1 0 1 TMM TMM TMM TMM timer mode
307 0 0 1 1 1 0 --- PT --- PT port T
308 0 1 0 0 0 0 MM --- --- --- memory mapping
309 0 1 0 0 0 1 MCC --- --- --- mode control C
310 0 1 0 0 1 0 MA --- --- --- mode A
311 0 1 0 0 1 1 MB --- --- --- mode B
312 0 1 0 1 0 0 MC --- --- --- mode C
313 0 1 0 1 1 1 MF --- --- --- mode F
314 0 1 1 0 0 0 TXB --- --- --- Tx buffer
315 0 1 1 0 0 1 --- RXB --- --- Rx buffer
316 0 1 1 0 1 0 TM0 --- --- --- timer register 0
317 0 1 1 0 1 1 TM1 --- --- --- timer register 1
318 1 0 0 1 0 0 WDM WDM --- --- watchdog timer mode
319 1 0 0 1 0 1 MT --- --- --- mode T
320
321 For sr and sr1, all 6bits (S5, S4, S3, S2, S1, and S0) are used.
322 For sr2 and sr5, only 4bits (S3, S2, S1, AND S0) are used.
323 They are expressed as 'ssssss' and 's sss' in operation code.
324 Note that 's sss' (of sr2 and sr5) is located separately.
325 S0 is rightmost bit (LSB).
326
327
328 --------------------------------------------
329 Operation instructions for working registers
330 --------------------------------------------
331 All instructions are same.
332
333
334 --------------------------------------------------------------------------
335 16bit operation instructions and divider/multiplier operation instructions
336 --------------------------------------------------------------------------
337 All instructions are same.
338
339
340 ------------------------------------------
341 Increment/decrement operation instructions
342 ------------------------------------------
343 All instructions are same.
344
345
346 ----------------------------
347 Other operation instructions
348 ----------------------------
349 7807 has CMC instruction (inverts CY flag).
350 ins. 1st byte 2nd byte 3rd 4th state func
351 CMC 01001000 10101010 8 CY <- !CY
352
353
354 ---------------------------
355 Rotation/shift instructions
356 ---------------------------
357 All instructions are same.
358
359
360 -----------------------------
361 Jump/call/return instructions
362 -----------------------------
363 All instructions are same.
364
365
366 -----------------
367 Skip instructions
368 -----------------
369 7807 doesn't have this
370 ins. 1st byte 2nd byte 3rd 4th state func
371 BIT bit, wa 01011bbb wwwwwwww 10* bit skip if (V.wa).bit = 1
372
373 Instead, 7807 has these bit manipulation instructions.
374 ins. 1st byte 2nd byte 3rd 4th state func
375 MOV CY, bit 01011111 bbbbbbbb 10* CY <- (bit)
376 MOV bit, CY 01011010 bbbbbbbb 13* (bit) <- CY
377 AND CY, bit 00110001 bbbbbbbb 10* CY <- CY & (bit)
378 OR CY, bit 01011100 bbbbbbbb 10* CY <- CY | (bit)
379 XOR CY, bit 01011110 bbbbbbbb 10* CY <- CY ^ (bit)
380 SETB bit 01011000 bbbbbbbb 13* (bit) <- 1
381 CLR bit 01011011 bbbbbbbb 13* (bit) <- 0
382 NOT bit 01011001 bbbbbbbb 13* (bit) <- !(bit)
383 SK bit 01011101 bbbbbbbb 10* (b) skip if (bit) = 1
384 SKN bit 01010000 bbbbbbbb 10* !(b) skip if (bit) = 0
385
386
387 ------------------------
388 CPU control instructions
389 ------------------------
390 ins. 1st byte 2nd byte 3rd 4th state func
391 HLT 01001000 00111011 11/12 halt
392 11 state in uPD7807 and uPD7810, 12 state in uPD78C10.
393
394 STOP 01001000 10111011 12 stop
395 7807 doesn't have STOP instruction.
396
397 */
398
399
400 #include "burnint.h"
401 #include "driver.h"
402 #include "state.h"
403 //#include "mamedbg.h"
404 #include "upd7810_intf.h"
405
core_set_irq(INT32,INT32 line,INT32 state)406 static void core_set_irq(INT32 /*cpu*/, INT32 line, INT32 state)
407 {
408 upd7810SetIRQLine(line, state);
409 }
410
411 cpu_core_config upd7810Config =
412 {
413 "upd7810",
414 upd7810Open,
415 upd7810Close,
416 upd7810CheatRead,
417 upd7810CheatWrite,
418 upd7810GetActive,
419 upd7810TotalCycles,
420 upd7810NewFrame,
421 upd7810Idle,
422 core_set_irq,
423 upd7810Run,
424 upd7810RunEnd,
425 upd7810Reset,
426 0x10000,
427 0
428 };
429
430 static UINT8 (*an0_func)();
431 static UINT8 (*an1_func)();
432 static UINT8 (*an2_func)();
433 static UINT8 (*an3_func)();
434 static UINT8 (*an4_func)();
435 static UINT8 (*an5_func)();
436 static UINT8 (*an6_func)();
437 static UINT8 (*an7_func)();
438
439 static UINT8 *mem[3][0x100];
440
441 static UINT8 (*read_byte_8)(UINT16) = NULL;
442 static void (*write_byte_8)(UINT16,UINT8) = NULL;
443
444 static UINT8 (*io_read_byte_8)(UINT8) = NULL;
445 static void (*io_write_byte_8)(UINT8,UINT8) = NULL;
446
dummy_write(UINT16,UINT8)447 static void dummy_write(UINT16,UINT8) {}
dummy_read(UINT16)448 static UINT8 dummy_read(UINT16) { return 0; }
dummy_write_port(UINT8,UINT8)449 static void dummy_write_port(UINT8,UINT8) {}
dummy_read_port(UINT8)450 static UINT8 dummy_read_port(UINT8) { return 0; }
451
cpu_readop(UINT16 address)452 static UINT8 cpu_readop(UINT16 address)
453 {
454 if (mem[2][address/0x100]) {
455 return mem[2][address/0x100][address & 0xff];
456 }
457
458 if (read_byte_8) {
459 return read_byte_8(address);
460 }
461
462 return 0;
463 }
464
cpu_readop_arg(UINT16 address)465 static UINT8 cpu_readop_arg(UINT16 address)
466 {
467 if (mem[0][address/0x100]) {
468 return mem[0][address/0x100][address & 0xff];
469 }
470
471 if (read_byte_8) {
472 return read_byte_8(address);
473 }
474
475 return 0;
476 }
477
program_read_byte_8(UINT16 address)478 static UINT8 program_read_byte_8(UINT16 address)
479 {
480 if (mem[2][address/0x100]) {
481 return mem[0][address/0x100][address & 0xff];
482 }
483
484 if (read_byte_8) {
485 return read_byte_8(address);
486 }
487
488 return 0;
489 }
490
program_write_byte_8(UINT16 address,UINT8 data)491 static void program_write_byte_8(UINT16 address, UINT8 data)
492 {
493 if (mem[1][address/0x100]) {
494 mem[1][address/0x100][address & 0xff] = data;
495 return;
496 }
497
498 if (write_byte_8) {
499 write_byte_8(address,data);
500 return;
501 }
502 }
503
upd7810CheatWrite(UINT32 address,UINT8 data)504 void upd7810CheatWrite(UINT32 address, UINT8 data)
505 {
506 if (mem[0][address/0x100]) {
507 mem[0][address/0x100][address & 0xff] = data;
508 }
509 if (mem[1][address/0x100]) {
510 mem[1][address/0x100][address & 0xff] = data;
511 }
512 if (mem[2][address/0x100]) {
513 mem[2][address/0x100][address & 0xff] = data;
514 }
515 }
516
upd7810CheatRead(UINT32 address)517 UINT8 upd7810CheatRead(UINT32 address)
518 {
519 return program_read_byte_8(address);
520 }
521
upd7810SetReadPortHandler(UINT8 (* read_port)(UINT8))522 void upd7810SetReadPortHandler(UINT8 (*read_port)(UINT8))
523 {
524 io_read_byte_8 = read_port;
525 }
526
upd7810SetWritePortHandler(void (* write_port)(UINT8,UINT8))527 void upd7810SetWritePortHandler(void (*write_port)(UINT8,UINT8))
528 {
529 io_write_byte_8 = write_port;
530 }
531
upd7810SetReadHandler(UINT8 (* read)(UINT16))532 void upd7810SetReadHandler(UINT8 (*read)(UINT16))
533 {
534 read_byte_8 = read;
535 }
536
upd7810SetWriteHandler(void (* write)(UINT16,UINT8))537 void upd7810SetWriteHandler(void (*write)(UINT16,UINT8))
538 {
539 write_byte_8 = write;
540 }
541
upd7810MapMemory(UINT8 * src,UINT16 start,UINT16 finish,UINT8 map)542 void upd7810MapMemory(UINT8 *src, UINT16 start, UINT16 finish, UINT8 map)
543 {
544 UINT16 len = (finish-start) >> 8;
545
546 for (INT32 i = 0; i < len+1; i++)
547 {
548 UINT32 offset = i + (start >> 8);
549 if (map & (1 << 0)) mem[0][offset] = src + (i << 8);
550 if (map & (1 << 1)) mem[1][offset] = src + (i << 8);
551 if (map & (1 << 2)) mem[2][offset] = src + (i << 8);
552 }
553 }
554
555
556 static const struct opcode_s *opXX; // = opXX_7810;
557 static INT32 upd7810_config_type = TYPE_7810;
558 INT32 (*upd7810_io_callback)(INT32 ioline, INT32 state) = NULL;
559 INT32 (*upd7810_irq_callback)(INT32 line) = NULL;
560 #define change_pc(x) PC = (x)
561
562
563 static UPD7810 upd7810;
564 static int upd7810_icount;
565 static int upd7810_total_cycles;
566 static int upd7810_current_cycles;
567
568 #if 0
569 /* Layout of the registers in the debugger */
570 static UINT8 upd7810_reg_layout[] = {
571 UPD7810_PC, UPD7810_PSW, UPD7810_A, UPD7810_V, UPD7810_EA, UPD7810_BC, UPD7810_DE, UPD7810_HL, -1,
572 UPD7810_SP, UPD7810_MM, UPD7810_A2, UPD7810_V2, UPD7810_EA2, UPD7810_BC2, UPD7810_DE2, UPD7810_HL2, -1,
573 UPD7810_TMM, UPD7810_CNT0, UPD7810_TM0, UPD7810_CNT1, UPD7810_TM1, -1,
574 UPD7810_ETMM, UPD7810_ECNT, UPD7810_ECPT, UPD7810_ETM0, UPD7810_ETM1, -1,
575 UPD7810_TXB, UPD7810_RXB, UPD7810_CR0, UPD7810_CR1, UPD7810_CR2, UPD7810_CR3, -1,
576 UPD7810_TXD, UPD7810_RXD, UPD7810_SCK, UPD7810_TI, UPD7810_TO, UPD7810_CI, UPD7810_CO0, UPD7810_CO1, 0
577 };
578
579 /* Layout of the debugger windows x,y,w,h */
580 static UINT8 upd7810_win_layout[] = {
581 0, 0,80, 6, /* register window (top rows) */
582 0, 7,24,15, /* disassembler window (left colums) */
583 25, 7,55, 7, /* memory #1 window (right, upper middle) */
584 25,15,55, 7, /* memory #2 window (right, lower middle) */
585 0,23,80, 1, /* command line window (bottom rows) */
586 };
587 #endif
588
589 #define CY 0x01
590 #define F1 0x02
591 #define L0 0x04
592 #define L1 0x08
593 #define HC 0x10
594 #define SK 0x20
595 #define Z 0x40
596 #define F7 0x80
597
598 /* IRR flags */
599 #define INTNMI 0x0001
600 #define INTFT0 0x0002
601 #define INTFT1 0x0004
602 #define INTF1 0x0008
603 #define INTF2 0x0010
604 #define INTFE0 0x0020
605 #define INTFE1 0x0040
606 #define INTFEIN 0x0080
607 #define INTFAD 0x0100
608 #define INTFSR 0x0200
609 #define INTFST 0x0400
610 #define INTER 0x0800
611 #define INTOV 0x1000
612 #define INTF0 0x2000
613
614 /* ITF flags */
615 #define INTAN4 0x0001
616 #define INTAN5 0x0002
617 #define INTAN6 0x0004
618 #define INTAN7 0x0008
619 #define INTSB 0x0010
620
621 #define PPC upd7810.ppc.w.l
622 #define PC upd7810.pc.w.l
623 #define PCL upd7810.pc.b.l
624 #define PCH upd7810.pc.b.h
625 #define PCD upd7810.pc.d
626 #define SP upd7810.sp.w.l
627 #define SPL upd7810.sp.b.l
628 #define SPH upd7810.sp.b.h
629 #define SPD upd7810.sp.d
630 #define PSW upd7810.psw
631 #define OP upd7810.op
632 #define OP2 upd7810.op2
633 #define IFF upd7810.iff
634 #define EA upd7810.ea.w.l
635 #define EAL upd7810.ea.b.l
636 #define EAH upd7810.ea.b.h
637 #define VA upd7810.va.w.l
638 #define V upd7810.va.b.h
639 #define A upd7810.va.b.l
640 #define VAD upd7810.va.d
641 #define BC upd7810.bc.w.l
642 #define B upd7810.bc.b.h
643 #define C upd7810.bc.b.l
644 #define DE upd7810.de.w.l
645 #define D upd7810.de.b.h
646 #define E upd7810.de.b.l
647 #define HL upd7810.hl.w.l
648 #define H upd7810.hl.b.h
649 #define L upd7810.hl.b.l
650 #define EA2 upd7810.ea2.w.l
651 #define VA2 upd7810.va2.w.l
652 #define BC2 upd7810.bc2.w.l
653 #define DE2 upd7810.de2.w.l
654 #define HL2 upd7810.hl2.w.l
655
656 #define OVC0 upd7810.ovc0
657 #define OVC1 upd7810.ovc1
658 #define OVCE upd7810.ovce
659 #define OVCF upd7810.ovcf
660 #define OVCS upd7810.ovcs
661 #define EDGES upd7810.edges
662
663 #define CNT0 upd7810.cnt.b.l
664 #define CNT1 upd7810.cnt.b.h
665 #define TM0 upd7810.tm.b.l
666 #define TM1 upd7810.tm.b.h
667 #define ECNT upd7810.ecnt.w.l
668 #define ECPT upd7810.ecnt.w.h
669 #define ETM0 upd7810.etm.w.l
670 #define ETM1 upd7810.etm.w.h
671
672 #define MA upd7810.ma
673 #define MB upd7810.mb
674 #define MCC upd7810.mcc
675 #define MC upd7810.mc
676 #define MM upd7810.mm
677 #define MF upd7810.mf
678 #define TMM upd7810.tmm
679 #define ETMM upd7810.etmm
680 #define EOM upd7810.eom
681 #define SML upd7810.sml
682 #define SMH upd7810.smh
683 #define ANM upd7810.anm
684 #define MKL upd7810.mkl
685 #define MKH upd7810.mkh
686 #define ZCM upd7810.zcm
687
688 #define CR0 upd7810.cr0
689 #define CR1 upd7810.cr1
690 #define CR2 upd7810.cr2
691 #define CR3 upd7810.cr3
692 #define RXB upd7810.rxb
693 #define TXB upd7810.txb
694
695 #define RXD upd7810.rxd
696 #define TXD upd7810.txd
697 #define SCK upd7810.sck
698 #define TI upd7810.ti
699 #define TO upd7810.to
700 #define CI upd7810.ci
701 #define LV0 upd7810.lv0
702 #define LV1 upd7810.lv1
703 #define CO0 upd7810.co0
704 #define CO1 upd7810.co1
705
706 #define IRR upd7810.irr
707 #define ITF upd7810.itf
708
709 struct opcode_s {
710 void (*opfunc)(void);
711 UINT8 oplen;
712 UINT8 cycles;
713 UINT8 cycles_skip;
714 UINT8 mask_l0_l1;
715 };
716
717 #define RDOP(O) O = cpu_readop(PCD); PC++
718 #define RDOPARG(A) A = cpu_readop_arg(PCD); PC++
719 #define RM(A) program_read_byte_8(A)
720 #define WM(A,V) program_write_byte_8(A,V)
721
722 #define ZHC_ADD(after,before,carry) \
723 if (after == 0) PSW |= Z; else PSW &= ~Z; \
724 if (after == before) \
725 PSW = (PSW&~CY) | (carry); \
726 else if (after < before) \
727 PSW |= CY; \
728 else \
729 PSW &= ~CY; \
730 if ((after & 15) < (before & 15)) \
731 PSW |= HC; \
732 else \
733 PSW &= ~HC; \
734
735 #define ZHC_SUB(after,before,carry) \
736 if (after == 0) PSW |= Z; else PSW &= ~Z; \
737 if (before == after) \
738 PSW = (PSW & ~CY) | (carry); \
739 else if (after > before) \
740 PSW |= CY; \
741 else \
742 PSW &= ~CY; \
743 if ((after & 15) > (before & 15)) \
744 PSW |= HC; \
745 else \
746 PSW &= ~HC; \
747
748 #define SKIP_CY if (CY == (PSW & CY)) PSW |= SK
749 #define SKIP_NC if (0 == (PSW & CY)) PSW |= SK
750 #define SKIP_Z if (Z == (PSW & Z)) PSW |= SK
751 #define SKIP_NZ if (0 == (PSW & Z)) PSW |= SK
752 #define SET_Z(n) if (n) PSW &= ~Z; else PSW |= Z
753
RP(INT32 port)754 static UINT8 RP(INT32 port)
755 {
756 UINT8 data = 0xff;
757 switch (port)
758 {
759 case UPD7810_PORTA:
760 if (upd7810.ma) // NS20031301 no need to read if the port is set as output
761 upd7810.pa_in = io_read_byte_8(port);
762 data = (upd7810.pa_in & upd7810.ma) | (upd7810.pa_out & ~upd7810.ma);
763 break;
764 case UPD7810_PORTB:
765 if (upd7810.mb) // NS20031301 no need to read if the port is set as output
766 upd7810.pb_in = io_read_byte_8(port);
767 data = (upd7810.pb_in & upd7810.mb) | (upd7810.pb_out & ~upd7810.mb);
768 break;
769 case UPD7810_PORTC:
770 if (upd7810.mc) // NS20031301 no need to read if the port is set as output
771 upd7810.pc_in = io_read_byte_8(port);
772 data = (upd7810.pc_in & upd7810.mc) | (upd7810.pc_out & ~upd7810.mc);
773 if (upd7810.mcc & 0x01) /* PC0 = TxD output */
774 data = (data & ~0x01) | (upd7810.txd & 1 ? 0x01 : 0x00);
775 if (upd7810.mcc & 0x02) /* PC1 = RxD input */
776 data = (data & ~0x02) | (upd7810.rxd & 1 ? 0x02 : 0x00);
777 if (upd7810.mcc & 0x04) /* PC2 = SCK input/output */
778 data = (data & ~0x04) | (upd7810.sck & 1 ? 0x04 : 0x00);
779 if (upd7810.mcc & 0x08) /* PC3 = TI input */
780 data = (data & ~0x08) | (upd7810.ti & 1 ? 0x08 : 0x00);
781 if (upd7810.mcc & 0x10) /* PC4 = TO output */
782 data = (data & ~0x10) | (upd7810.to & 1 ? 0x10 : 0x00);
783 if (upd7810.mcc & 0x20) /* PC5 = CI input */
784 data = (data & ~0x20) | (upd7810.ci & 1 ? 0x20 : 0x00);
785 if (upd7810.mcc & 0x40) /* PC6 = CO0 output */
786 data = (data & ~0x40) | (upd7810.co0 & 1 ? 0x40 : 0x00);
787 if (upd7810.mcc & 0x80) /* PC7 = CO1 output */
788 data = (data & ~0x80) | (upd7810.co1 & 1 ? 0x80 : 0x00);
789 break;
790 case UPD7810_PORTD:
791 upd7810.pd_in = io_read_byte_8(port);
792 switch (upd7810.mm & 0x07)
793 {
794 case 0x00: /* PD input mode, PF port mode */
795 data = upd7810.pd_in;
796 break;
797 case 0x01: /* PD output mode, PF port mode */
798 data = upd7810.pd_out;
799 break;
800 default: /* PD extension mode, PF port/extension mode */
801 data = 0xff; /* what do we see on the port here? */
802 break;
803 }
804 break;
805 case UPD7810_PORTF:
806 upd7810.pf_in = io_read_byte_8(port);
807 switch (upd7810.mm & 0x06)
808 {
809 case 0x00: /* PD input/output mode, PF port mode */
810 data = (upd7810.pf_in & upd7810.mf) | (upd7810.pf_out & ~upd7810.mf);
811 break;
812 case 0x02: /* PD extension mode, PF0-3 extension mode, PF4-7 port mode */
813 data = (upd7810.pf_in & upd7810.mf) | (upd7810.pf_out & ~upd7810.mf);
814 data |= 0x0f; /* what would we see on the lower bits here? */
815 break;
816 case 0x04: /* PD extension mode, PF0-5 extension mode, PF6-7 port mode */
817 data = (upd7810.pf_in & upd7810.mf) | (upd7810.pf_out & ~upd7810.mf);
818 data |= 0x3f; /* what would we see on the lower bits here? */
819 break;
820 case 0x06:
821 data = 0xff; /* what would we see on the lower bits here? */
822 break;
823 }
824 break;
825 case UPD7807_PORTT: // NS20031301 partial implementation
826 data = io_read_byte_8(port);
827 break;
828 //default:
829 // logerror("uPD7810 internal error: RP() called with invalid port number\n");
830 }
831 return data;
832 }
833
WP(INT32 port,UINT8 data)834 static void WP(INT32 port, UINT8 data)
835 {
836 switch (port)
837 {
838 case UPD7810_PORTA:
839 upd7810.pa_out = data;
840 // data = (data & ~upd7810.ma) | (upd7810.pa_in & upd7810.ma);
841 data = (data & ~upd7810.ma) | (upd7810.ma); // NS20031401
842 io_write_byte_8(port, data);
843 break;
844 case UPD7810_PORTB:
845 upd7810.pb_out = data;
846 // data = (data & ~upd7810.mb) | (upd7810.pb_in & upd7810.mb);
847 data = (data & ~upd7810.mb) | (upd7810.mb); // NS20031401
848 io_write_byte_8(port, data);
849 break;
850 case UPD7810_PORTC:
851 upd7810.pc_out = data;
852 // data = (data & ~upd7810.mc) | (upd7810.pc_in & upd7810.mc);
853 data = (data & ~upd7810.mc) | (upd7810.mc); // NS20031401
854 if (upd7810.mcc & 0x01) /* PC0 = TxD output */
855 data = (data & ~0x01) | (upd7810.txd & 1 ? 0x01 : 0x00);
856 if (upd7810.mcc & 0x02) /* PC1 = RxD input */
857 data = (data & ~0x02) | (upd7810.rxd & 1 ? 0x02 : 0x00);
858 if (upd7810.mcc & 0x04) /* PC2 = SCK input/output */
859 data = (data & ~0x04) | (upd7810.sck & 1 ? 0x04 : 0x00);
860 if (upd7810.mcc & 0x08) /* PC3 = TI input */
861 data = (data & ~0x08) | (upd7810.ti & 1 ? 0x08 : 0x00);
862 if (upd7810.mcc & 0x10) /* PC4 = TO output */
863 data = (data & ~0x10) | (upd7810.to & 1 ? 0x10 : 0x00);
864 if (upd7810.mcc & 0x20) /* PC5 = CI input */
865 data = (data & ~0x20) | (upd7810.ci & 1 ? 0x20 : 0x00);
866 if (upd7810.mcc & 0x40) /* PC6 = CO0 output */
867 data = (data & ~0x40) | (upd7810.co0 & 1 ? 0x40 : 0x00);
868 if (upd7810.mcc & 0x80) /* PC7 = CO1 output */
869 data = (data & ~0x80) | (upd7810.co1 & 1 ? 0x80 : 0x00);
870 io_write_byte_8(port, data);
871 break;
872 case UPD7810_PORTD:
873 upd7810.pd_out = data;
874 switch (upd7810.mm & 0x07)
875 {
876 case 0x00: /* PD input mode, PF port mode */
877 data = upd7810.pd_in;
878 break;
879 case 0x01: /* PD output mode, PF port mode */
880 data = upd7810.pd_out;
881 break;
882 default: /* PD extension mode, PF port/extension mode */
883 return;
884 }
885 io_write_byte_8(port, data);
886 break;
887 case UPD7810_PORTF:
888 upd7810.pf_out = data;
889 data = (data & ~upd7810.mf) | (upd7810.pf_in & upd7810.mf);
890 switch (upd7810.mm & 0x06)
891 {
892 case 0x00: /* PD input/output mode, PF port mode */
893 break;
894 case 0x02: /* PD extension mode, PF0-3 extension mode, PF4-7 port mode */
895 data |= 0x0f; /* what would come out for the lower bits here? */
896 break;
897 case 0x04: /* PD extension mode, PF0-5 extension mode, PF6-7 port mode */
898 data |= 0x3f; /* what would come out for the lower bits here? */
899 break;
900 case 0x06:
901 data |= 0xff; /* what would come out for the lower bits here? */
902 break;
903 }
904 io_write_byte_8(port, data);
905 break;
906 //default:
907 // logerror("uPD7810 internal error: RP() called with invalid port number\n");
908 }
909 }
910
upd7810_take_irq(void)911 static void upd7810_take_irq(void)
912 {
913 UINT16 vector = 0;
914 int irqline = 0;
915
916 /* global interrupt disable? */
917 if (0 == IFF)
918 return;
919
920 /* check the interrupts in priority sequence */
921 if (IRR & INTNMI)
922 {
923 /* Nonmaskable interrupt */
924 irqline = CPU_IRQLINE_NMI;
925 vector = 0x0004;
926 IRR &= ~INTNMI;
927 }
928 else
929 if ((IRR & INTFT0) && 0 == (MKL & 0x02))
930 {
931 vector = 0x0008;
932 if (!((IRR & INTFT1) && 0 == (MKL & 0x04)))
933 IRR&=~INTFT0;
934 }
935 else
936 if ((IRR & INTFT1) && 0 == (MKL & 0x04))
937 {
938 vector = 0x0008;
939 IRR&=~INTFT1;
940 }
941 else
942 if ((IRR & INTF1) && 0 == (MKL & 0x08))
943 {
944 irqline = UPD7810_INTF1;
945 vector = 0x0010;
946 if (!((IRR & INTF2) && 0 == (MKL & 0x10)))
947 IRR&=~INTF1;
948 }
949 else
950 if ((IRR & INTF2) && 0 == (MKL & 0x10))
951 {
952 irqline = UPD7810_INTF2;
953 vector = 0x0010;
954 IRR&=~INTF2;
955 }
956 else
957 if ((IRR & INTFE0) && 0 == (MKL & 0x20))
958 {
959 vector = 0x0018;
960 if (!((IRR & INTFE1) && 0 == (MKL & 0x40)))
961 IRR&=~INTFE0;
962 }
963 else
964 if ((IRR & INTFE1) && 0 == (MKL & 0x40))
965 {
966 vector = 0x0018;
967 IRR&=~INTFE1;
968 }
969 else
970 if ((IRR & INTFEIN) && 0 == (MKL & 0x80))
971 {
972 vector = 0x0020;
973 }
974 else
975 if ((IRR & INTFAD) && 0 == (MKH & 0x01))
976 {
977 vector = 0x0020;
978 }
979 else
980 if ((IRR & INTFSR) && 0 == (MKH & 0x02))
981 {
982 vector = 0x0028;
983 IRR&=~INTFSR;
984 }
985 else
986 if ((IRR & INTFST) && 0 == (MKH & 0x04))
987 {
988 vector = 0x0028;
989 IRR&=~INTFST;
990 }
991
992 if (vector)
993 {
994 /* acknowledge external IRQ */
995 if (irqline && upd7810_irq_callback)
996 (*upd7810_irq_callback)(irqline);
997 SP--;
998 WM( SP, PSW );
999 SP--;
1000 WM( SP, PCH );
1001 SP--;
1002 WM( SP, PCL );
1003 IFF = 0;
1004 PSW &= ~(SK|L0|L1);
1005 PC = vector;
1006 }
1007 }
1008
upd7810_co0_output_change()1009 static void upd7810_co0_output_change()
1010 {
1011 /* Output LV0 Content to CO0 */
1012 CO0 = LV0;
1013
1014 /* LV0 Level Inversion */
1015 if (EOM & 0x02)
1016 LV0 ^= 1;
1017
1018 //m_co0_func(CO0);
1019 }
1020
upd7810_co1_output_change()1021 static void upd7810_co1_output_change()
1022 {
1023 /* Output LV1 Content to CO1 */
1024 CO1 = LV1;
1025
1026 /* LV1 Level Inversion */
1027 if (EOM & 0x20)
1028 LV1 ^= 1;
1029
1030 //m_co1_func(CO1);
1031 }
1032
upd7810_write_EOM()1033 static void upd7810_write_EOM()
1034 {
1035 switch (EOM & 0x0c)
1036 {
1037 case 0x04: /* To Reset LV0 */
1038 LV0 = 0;
1039 EOM &= 0xfb; /* LRE0 is reset to 0 */
1040 break;
1041 case 0x08: /* To Set LV0 */
1042 LV0 = 1;
1043 EOM &= 0xf7; /* LRE1 is reset to 0 */
1044 break;
1045 }
1046 /* Output LV0 Content */
1047 if (EOM & 0x01) {
1048 upd7810_co0_output_change();
1049 EOM &= 0xfe; /* LO0 is reset to 0 */
1050 }
1051
1052 switch (EOM & 0xc0)
1053 {
1054 case 0x40: /* To Reset LV1 */
1055 LV1 = 0;
1056 EOM &= 0xbf; /* LRE2 is reset to 0 */
1057 break;
1058 case 0x80: /* To Set LV1 */
1059 LV1 = 1;
1060 EOM &= 0x7f; /* LRE3 is reset to 0 */
1061 break;
1062 }
1063 /* Output LV1 Content */
1064 if (EOM & 0x10) {
1065 upd7810_co1_output_change();
1066 EOM &= 0xef; /* LO1 is reset to 0 */
1067 }
1068 }
1069
1070 #if 0
1071 OLD
1072 static void upd7810_write_EOM(void)
1073 {
1074 if (EOM & 0x01) /* output LV0 content ? */
1075 {
1076 switch (EOM & 0x0e)
1077 {
1078 case 0x02: /* toggle CO0 */
1079 CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2);
1080 break;
1081 case 0x04: /* reset CO0 */
1082 CO0 = 0;
1083 break;
1084 case 0x08: /* set CO0 */
1085 CO0 = 1;
1086 break;
1087 }
1088 }
1089 if (EOM & 0x10) /* output LV0 content ? */
1090 {
1091 switch (EOM & 0xe0)
1092 {
1093 case 0x20: /* toggle CO1 */
1094 CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2);
1095 break;
1096 case 0x40: /* reset CO1 */
1097 CO1 = 0;
1098 break;
1099 case 0x80: /* set CO1 */
1100 CO1 = 1;
1101 break;
1102 }
1103 }
1104 }
1105 #endif
1106
upd7810_write_TXB(void)1107 static void upd7810_write_TXB(void)
1108 {
1109 upd7810.txbuf = 1;
1110 }
1111
1112 #define PAR7(n) ((((n)>>6)^((n)>>5)^((n)>>4)^((n)>>3)^((n)>>2)^((n)>>1)^((n)))&1)
1113 #define PAR8(n) ((((n)>>7)^((n)>>6)^((n)>>5)^((n)>>4)^((n)>>3)^((n)>>2)^((n)>>1)^((n)))&1)
1114
upd7810_sio_output(void)1115 static void upd7810_sio_output(void)
1116 {
1117 /* shift out more bits? */
1118 if (upd7810.txcnt > 0)
1119 {
1120 TXD = upd7810.txs & 1;
1121 if (upd7810_io_callback)
1122 (*upd7810_io_callback)(UPD7810_TXD,TXD);
1123 upd7810.txs >>= 1;
1124 upd7810.txcnt--;
1125 if (0 == upd7810.txcnt)
1126 IRR |= INTFST; /* serial transfer completed */
1127 }
1128 else
1129 if (SMH & 0x04) /* send enable ? */
1130 {
1131 /* nothing written into the transmitter buffer ? */
1132 if (0 == upd7810.txbuf)
1133 return;
1134 upd7810.txbuf = 0;
1135
1136 if (SML & 0x03) /* asynchronous mode ? */
1137 {
1138 switch (SML & 0xfc)
1139 {
1140 case 0x48: /* 7bits, no parity, 1 stop bit */
1141 case 0x68: /* 7bits, no parity, 1 stop bit (parity select = 1 but parity is off) */
1142 /* insert start bit in bit0, stop bit int bit8 */
1143 upd7810.txs = (TXB << 1) | (1 << 8);
1144 upd7810.txcnt = 9;
1145 break;
1146 case 0x4c: /* 8bits, no parity, 1 stop bit */
1147 case 0x6c: /* 8bits, no parity, 1 stop bit (parity select = 1 but parity is off) */
1148 /* insert start bit in bit0, stop bit int bit9 */
1149 upd7810.txs = (TXB << 1) | (1 << 9);
1150 upd7810.txcnt = 10;
1151 break;
1152 case 0x58: /* 7bits, odd parity, 1 stop bit */
1153 /* insert start bit in bit0, parity in bit 8, stop bit in bit9 */
1154 upd7810.txs = (TXB << 1) | (PAR7(TXB) << 8) | (1 << 9);
1155 upd7810.txcnt = 10;
1156 break;
1157 case 0x5c: /* 8bits, odd parity, 1 stop bit */
1158 /* insert start bit in bit0, parity in bit 9, stop bit int bit10 */
1159 upd7810.txs = (TXB << 1) | (PAR8(TXB) << 9) | (1 << 10);
1160 upd7810.txcnt = 11;
1161 break;
1162 case 0x78: /* 7bits, even parity, 1 stop bit */
1163 /* insert start bit in bit0, parity in bit 8, stop bit in bit9 */
1164 upd7810.txs = (TXB << 1) | ((PAR7(TXB) ^ 1) << 8) | (1 << 9);
1165 upd7810.txcnt = 10;
1166 break;
1167 case 0x7c: /* 8bits, even parity, 1 stop bit */
1168 /* insert start bit in bit0, parity in bit 9, stop bit int bit10 */
1169 upd7810.txs = (TXB << 1) | ((PAR8(TXB) ^ 1) << 9) | (1 << 10);
1170 upd7810.txcnt = 11;
1171 break;
1172 case 0xc8: /* 7bits, no parity, 2 stop bits */
1173 case 0xe8: /* 7bits, no parity, 2 stop bits (parity select = 1 but parity is off) */
1174 /* insert start bit in bit0, stop bits int bit8+9 */
1175 upd7810.txs = (TXB << 1) | (3 << 8);
1176 upd7810.txcnt = 10;
1177 break;
1178 case 0xcc: /* 8bits, no parity, 2 stop bits */
1179 case 0xec: /* 8bits, no parity, 2 stop bits (parity select = 1 but parity is off) */
1180 /* insert start bit in bit0, stop bits in bits9+10 */
1181 upd7810.txs = (TXB << 1) | (3 << 9);
1182 upd7810.txcnt = 11;
1183 break;
1184 case 0xd8: /* 7bits, odd parity, 2 stop bits */
1185 /* insert start bit in bit0, parity in bit 8, stop bits in bits9+10 */
1186 upd7810.txs = (TXB << 1) | (PAR7(TXB) << 8) | (3 << 9);
1187 upd7810.txcnt = 11;
1188 break;
1189 case 0xdc: /* 8bits, odd parity, 2 stop bits */
1190 /* insert start bit in bit0, parity in bit 9, stop bits int bit10+11 */
1191 upd7810.txs = (TXB << 1) | (PAR8(TXB) << 9) | (3 << 10);
1192 upd7810.txcnt = 12;
1193 break;
1194 case 0xf8: /* 7bits, even parity, 2 stop bits */
1195 /* insert start bit in bit0, parity in bit 8, stop bits in bit9+10 */
1196 upd7810.txs = (TXB << 1) | ((PAR7(TXB) ^ 1) << 8) | (3 << 9);
1197 upd7810.txcnt = 11;
1198 break;
1199 case 0xfc: /* 8bits, even parity, 2 stop bits */
1200 /* insert start bit in bit0, parity in bit 9, stop bits int bits10+10 */
1201 upd7810.txs = (TXB << 1) | ((PAR8(TXB) ^ 1) << 9) | (1 << 10);
1202 upd7810.txcnt = 12;
1203 break;
1204 }
1205 }
1206 else
1207 {
1208 /* synchronous mode */
1209 upd7810.txs = TXB;
1210 upd7810.txcnt = 8;
1211 }
1212 }
1213 }
1214
upd7810_sio_input(void)1215 static void upd7810_sio_input(void)
1216 {
1217 /* sample next bit? */
1218 if (upd7810.rxcnt > 0)
1219 {
1220 if (upd7810_io_callback)
1221 RXD = (*upd7810_io_callback)(UPD7810_RXD,RXD);
1222 upd7810.rxs = (upd7810.rxs >> 1) | ((UINT16)RXD << 15);
1223 upd7810.rxcnt--;
1224 if (0 == upd7810.rxcnt)
1225 {
1226 /* reset the TSK bit */
1227 SMH &= ~0x40;
1228 /* serial receive completed interrupt */
1229 IRR |= INTFSR;
1230 /* now extract the data from the shift register */
1231 if (SML & 0x03) /* asynchronous mode ? */
1232 {
1233 switch (SML & 0xfc)
1234 {
1235 case 0x48: /* 7bits, no parity, 1 stop bit */
1236 case 0x68: /* 7bits, no parity, 1 stop bit (parity select = 1 but parity is off) */
1237 upd7810.rxs >>= 16 - 9;
1238 RXB = (upd7810.rxs >> 1) & 0x7f;
1239 if ((1 << 8) != (upd7810.rxs & (1 | (1 << 8))))
1240 IRR |= INTER; /* framing error */
1241 break;
1242 case 0x4c: /* 8bits, no parity, 1 stop bit */
1243 case 0x6c: /* 8bits, no parity, 1 stop bit (parity select = 1 but parity is off) */
1244 upd7810.rxs >>= 16 - 10;
1245 RXB = (upd7810.rxs >> 1) & 0xff;
1246 if ((1 << 9) != (upd7810.rxs & (1 | (1 << 9))))
1247 IRR |= INTER; /* framing error */
1248 break;
1249 case 0x58: /* 7bits, odd parity, 1 stop bit */
1250 upd7810.rxs >>= 16 - 10;
1251 RXB = (upd7810.rxs >> 1) & 0x7f;
1252 if ((1 << 9) != (upd7810.rxs & (1 | (1 << 9))))
1253 IRR |= INTER; /* framing error */
1254 if (PAR7(RXB) != ((upd7810.rxs >> 8) & 1))
1255 IRR |= INTER; /* parity error */
1256 break;
1257 case 0x5c: /* 8bits, odd parity, 1 stop bit */
1258 upd7810.rxs >>= 16 - 11;
1259 RXB = (upd7810.rxs >> 1) & 0xff;
1260 if ((1 << 10) != (upd7810.rxs & (1 | (1 << 10))))
1261 IRR |= INTER; /* framing error */
1262 if (PAR8(RXB) != ((upd7810.rxs >> 9) & 1))
1263 IRR |= INTER; /* parity error */
1264 break;
1265 case 0x78: /* 7bits, even parity, 1 stop bit */
1266 upd7810.rxs >>= 16 - 10;
1267 RXB = (upd7810.rxs >> 1) & 0x7f;
1268 if ((1 << 9) != (upd7810.rxs & (1 | (1 << 9))))
1269 IRR |= INTER; /* framing error */
1270 if (PAR7(RXB) != ((upd7810.rxs >> 8) & 1))
1271 IRR |= INTER; /* parity error */
1272 break;
1273 case 0x7c: /* 8bits, even parity, 1 stop bit */
1274 upd7810.rxs >>= 16 - 11;
1275 RXB = (upd7810.rxs >> 1) & 0xff;
1276 if ((1 << 10) != (upd7810.rxs & (1 | (1 << 10))))
1277 IRR |= INTER; /* framing error */
1278 if (PAR8(RXB) != ((upd7810.rxs >> 9) & 1))
1279 IRR |= INTER; /* parity error */
1280 break;
1281 case 0xc8: /* 7bits, no parity, 2 stop bits */
1282 case 0xe8: /* 7bits, no parity, 2 stop bits (parity select = 1 but parity is off) */
1283 upd7810.rxs >>= 16 - 10;
1284 RXB = (upd7810.rxs >> 1) & 0x7f;
1285 if ((3 << 9) != (upd7810.rxs & (1 | (3 << 9))))
1286 IRR |= INTER; /* framing error */
1287 if (PAR7(RXB) != ((upd7810.rxs >> 8) & 1))
1288 IRR |= INTER; /* parity error */
1289 break;
1290 case 0xcc: /* 8bits, no parity, 2 stop bits */
1291 case 0xec: /* 8bits, no parity, 2 stop bits (parity select = 1 but parity is off) */
1292 upd7810.rxs >>= 16 - 11;
1293 RXB = (upd7810.rxs >> 1) & 0xff;
1294 if ((3 << 10) != (upd7810.rxs & (1 | (3 << 10))))
1295 IRR |= INTER; /* framing error */
1296 if (PAR8(RXB) != ((upd7810.rxs >> 9) & 1))
1297 IRR |= INTER; /* parity error */
1298 break;
1299 case 0xd8: /* 7bits, odd parity, 2 stop bits */
1300 upd7810.rxs >>= 16 - 11;
1301 RXB = (upd7810.rxs >> 1) & 0x7f;
1302 if ((3 << 10) != (upd7810.rxs & (1 | (3 << 10))))
1303 IRR |= INTER; /* framing error */
1304 if (PAR7(RXB) != ((upd7810.rxs >> 8) & 1))
1305 IRR |= INTER; /* parity error */
1306 break;
1307 case 0xdc: /* 8bits, odd parity, 2 stop bits */
1308 upd7810.rxs >>= 16 - 12;
1309 RXB = (upd7810.rxs >> 1) & 0xff;
1310 if ((3 << 11) != (upd7810.rxs & (1 | (3 << 11))))
1311 IRR |= INTER; /* framing error */
1312 if (PAR8(RXB) != ((upd7810.rxs >> 9) & 1))
1313 IRR |= INTER; /* parity error */
1314 break;
1315 case 0xf8: /* 7bits, even parity, 2 stop bits */
1316 upd7810.rxs >>= 16 - 11;
1317 RXB = (upd7810.rxs >> 1) & 0x7f;
1318 if ((3 << 10) != (upd7810.rxs & (1 | (3 << 10))))
1319 IRR |= INTER; /* framing error */
1320 if (PAR7(RXB) != ((upd7810.rxs >> 8) & 1))
1321 IRR |= INTER; /* parity error */
1322 break;
1323 case 0xfc: /* 8bits, even parity, 2 stop bits */
1324 upd7810.rxs >>= 16 - 12;
1325 RXB = (upd7810.rxs >> 1) & 0xff;
1326 if ((3 << 11) != (upd7810.rxs & (1 | (3 << 11))))
1327 IRR |= INTER; /* framing error */
1328 if (PAR8(RXB) != ((upd7810.rxs >> 9) & 1))
1329 IRR |= INTER; /* parity error */
1330 break;
1331 }
1332 }
1333 else
1334 {
1335 upd7810.rxs >>= 16 - 8;
1336 RXB = upd7810.rxs;
1337 // upd7810.rxcnt = 8;
1338 }
1339 }
1340 }
1341 else
1342 if (SMH & 0x08) /* receive enable ? */
1343 {
1344 if (SML & 0x03) /* asynchronous mode ? */
1345 {
1346 switch (SML & 0xfc)
1347 {
1348 case 0x48: /* 7bits, no parity, 1 stop bit */
1349 case 0x68: /* 7bits, no parity, 1 stop bit (parity select = 1 but parity is off) */
1350 upd7810.rxcnt = 9;
1351 break;
1352 case 0x4c: /* 8bits, no parity, 1 stop bit */
1353 case 0x6c: /* 8bits, no parity, 1 stop bit (parity select = 1 but parity is off) */
1354 upd7810.rxcnt = 10;
1355 break;
1356 case 0x58: /* 7bits, odd parity, 1 stop bit */
1357 upd7810.rxcnt = 10;
1358 break;
1359 case 0x5c: /* 8bits, odd parity, 1 stop bit */
1360 upd7810.rxcnt = 11;
1361 break;
1362 case 0x78: /* 7bits, even parity, 1 stop bit */
1363 upd7810.rxcnt = 10;
1364 break;
1365 case 0x7c: /* 8bits, even parity, 1 stop bit */
1366 upd7810.rxcnt = 11;
1367 break;
1368 case 0xc8: /* 7bits, no parity, 2 stop bits */
1369 case 0xe8: /* 7bits, no parity, 2 stop bits (parity select = 1 but parity is off) */
1370 upd7810.rxcnt = 10;
1371 break;
1372 case 0xcc: /* 8bits, no parity, 2 stop bits */
1373 case 0xec: /* 8bits, no parity, 2 stop bits (parity select = 1 but parity is off) */
1374 upd7810.rxcnt = 11;
1375 break;
1376 case 0xd8: /* 7bits, odd parity, 2 stop bits */
1377 upd7810.rxcnt = 11;
1378 break;
1379 case 0xdc: /* 8bits, odd parity, 2 stop bits */
1380 upd7810.rxcnt = 12;
1381 break;
1382 case 0xf8: /* 7bits, even parity, 2 stop bits */
1383 upd7810.rxcnt = 11;
1384 break;
1385 case 0xfc: /* 8bits, even parity, 2 stop bits */
1386 upd7810.rxcnt = 12;
1387 break;
1388 }
1389 }
1390 else
1391 /* TSK bit set ? */
1392 if (SMH & 0x40)
1393 {
1394 upd7810.rxcnt = 8;
1395 }
1396 }
1397 }
1398
upd7810_handle_timer0(int cycles,int clkdiv)1399 static void upd7810_handle_timer0(int cycles, int clkdiv)
1400 {
1401 OVC0 += cycles;
1402 while (OVC0 >= clkdiv)
1403 {
1404 OVC0 -= clkdiv;
1405 CNT0++;
1406 if (CNT0 == TM0)
1407 {
1408 CNT0 = 0;
1409 IRR |= INTFT0;
1410 /* timer F/F source is timer 0 ? */
1411 if (0x00 == (TMM & 0x03))
1412 {
1413 TO ^= 1;
1414 if (upd7810_io_callback)
1415 (*upd7810_io_callback)(UPD7810_TO,TO);
1416 }
1417 /* timer 1 chained with timer 0 ? */
1418 if ((TMM & 0xe0) == 0x60)
1419 {
1420 CNT1++;
1421 if (CNT1 == TM1)
1422 {
1423 CNT1 = 0;
1424 IRR |= INTFT1;
1425 /* timer F/F source is timer 1 ? */
1426 if (0x01 == (TMM & 0x03))
1427 {
1428 TO ^= 1;
1429 if (upd7810_io_callback)
1430 (*upd7810_io_callback)(UPD7810_TO,TO);
1431 }
1432 }
1433 }
1434 }
1435 }
1436 }
1437
upd7810_handle_timer1(int cycles,int clkdiv)1438 static void upd7810_handle_timer1(int cycles, int clkdiv)
1439 {
1440 OVC1 += cycles;
1441 while (OVC1 >= clkdiv)
1442 {
1443 OVC1 -= clkdiv;
1444 CNT1++;
1445 if (CNT1 == TM1)
1446 {
1447 CNT1 = 0;
1448 IRR |= INTFT1;
1449 /* timer F/F source is timer 1 ? */
1450 if (0x01 == (TMM & 0x03))
1451 {
1452 TO ^= 1;
1453 if (upd7810_io_callback)
1454 (*upd7810_io_callback)(UPD7810_TO,TO);
1455 }
1456 }
1457 }
1458 }
1459
upd7810_timers(int cycles)1460 static void upd7810_timers(int cycles)
1461 {
1462 /**** TIMER 0 ****/
1463 if (TMM & 0x10) /* timer 0 upcounter reset ? */
1464 CNT0 = 0;
1465 else
1466 {
1467 switch (TMM & 0x0c) /* timer 0 clock source */
1468 {
1469 case 0x00: /* clock divided by 12 */
1470 upd7810_handle_timer0(cycles, 12);
1471 break;
1472 case 0x04: /* clock divided by 384 */
1473 upd7810_handle_timer0(cycles, 384);
1474 break;
1475 case 0x08: /* external signal at TI */
1476 break;
1477 case 0x0c: /* disabled */
1478 break;
1479 }
1480 }
1481
1482 /**** TIMER 1 ****/
1483 if (TMM & 0x80) /* timer 1 upcounter reset ? */
1484 CNT1 = 0;
1485 else
1486 {
1487 switch (TMM & 0x60) /* timer 1 clock source */
1488 {
1489 case 0x00: /* clock divided by 12 */
1490 upd7810_handle_timer1(cycles, 12);
1491 break;
1492 case 0x20: /* clock divided by 384 */
1493 upd7810_handle_timer1(cycles, 384);
1494 break;
1495 case 0x40: /* external signal at TI */
1496 break;
1497 case 0x60: /* clocked with timer 0 */
1498 break;
1499 }
1500 }
1501
1502 /**** TIMER F/F ****/
1503 /* timer F/F source is clock divided by 3 ? */
1504 if (0x02 == (TMM & 0x03))
1505 {
1506 OVCF += cycles;
1507 while (OVCF >= 3)
1508 {
1509 TO ^= 1;
1510 if (upd7810_io_callback)
1511 (*upd7810_io_callback)(UPD7810_TO,TO);
1512 OVCF -= 3;
1513 }
1514 }
1515
1516 /**** ETIMER ****/
1517 /* ECNT clear */
1518 if (0x00 == (ETMM & 0x0c))
1519 ECNT = 0;
1520 else
1521 if (0x00 == (ETMM & 0x03) || (0x01 == (ETMM & 0x03) && CI))
1522 {
1523 OVCE += cycles;
1524 /* clock divided by 12 */
1525 while (OVCE >= 12)
1526 {
1527 OVCE -= 12;
1528 ECNT++;
1529 /* Interrupt Control Circuit */
1530 if (ETM0 == ECNT)
1531 IRR |= INTFE0;
1532 if (ETM1 == ECNT)
1533 IRR |= INTFE1;
1534 /* Conditions When ECNT Causes a CO0 Output Change */
1535 if (((0x00 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 */
1536 /* ((0x10 == (ETMM & 0x30)) prohibited */
1537 ((0x20 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 or at falling CI input */
1538 ((0x30 == (ETMM & 0x30)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */
1539 {
1540 upd7810_co0_output_change();
1541 }
1542 /* Conditions When ECNT Causes a CO1 Output Change */
1543 if (((0x00 == (ETMM & 0xc0)) && (ETM1 == ECNT)) || /* set CO1 if ECNT == ETM1 */
1544 /* ((0x40 == (ETMM & 0xc0)) prohibited */
1545 ((0x80 == (ETMM & 0xc0)) && (ETM1 == ECNT)) || /* set CO1 if ECNT == ETM1 or at falling CI input */
1546 ((0xc0 == (ETMM & 0xc0)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */
1547 {
1548 upd7810_co1_output_change();
1549 }
1550 /* How and When ECNT is Cleared */
1551 switch (ETMM & 0x0c)
1552 {
1553 case 0x00: /* clear ECNT */
1554 break;
1555 case 0x04: /* free running */
1556 if (0 == ECNT)
1557 ITF |= INTOV; /* set overflow flag if counter wrapped */
1558 break;
1559 case 0x08: /* reset at falling edge of CI or TO */
1560 break;
1561 case 0x0c: /* reset if ECNT == ETM1 */
1562 if (ETM1 == ECNT)
1563 ECNT = 0;
1564 break;
1565 }
1566 }
1567 }
1568
1569 /**** SIO ****/
1570 switch (SMH & 0x03)
1571 {
1572 case 0x00: /* interval timer F/F */
1573 break;
1574 case 0x01: /* internal clock divided by 384 */
1575 OVCS += cycles;
1576 while (OVCS >= 384)
1577 {
1578 OVCS -= 384;
1579 if (0 == (EDGES ^= 1))
1580 upd7810_sio_input();
1581 else
1582 upd7810_sio_output();
1583 }
1584 break;
1585 case 0x02: /* internal clock divided by 24 */
1586 OVCS += cycles;
1587 while (OVCS >= 24)
1588 {
1589 OVCS -= 24;
1590 if (0 == (EDGES ^= 1))
1591 upd7810_sio_input();
1592 else
1593 upd7810_sio_output();
1594 }
1595 break;
1596 }
1597
1598 /**** ADC ****/
1599 upd7810.adcnt += cycles;
1600 if (upd7810.PANM != ANM)
1601 {
1602 /* reset A/D converter */
1603 upd7810.adcnt = 0;
1604 if (ANM & 0x10)
1605 upd7810.adtot = 144;
1606 else
1607 upd7810.adtot = 192;
1608 upd7810.adout = 0;
1609 upd7810.shdone = 0;
1610 if (ANM & 0x01)
1611 {
1612 /* select mode */
1613 upd7810.adin = (ANM >> 1) & 0x07;
1614 }
1615 else
1616 {
1617 /* scan mode */
1618 upd7810.adin = 0;
1619 upd7810.adrange = (ANM >> 1) & 0x04;
1620 }
1621 }
1622 upd7810.PANM = ANM;
1623 if (ANM & 0x01)
1624 {
1625 /* select mode */
1626 if (upd7810.shdone == 0)
1627 {
1628 switch (upd7810.adin)
1629 {
1630 case 0: upd7810.tmpcr = an0_func(); break;
1631 case 1: upd7810.tmpcr = an1_func(); break;
1632 case 2: upd7810.tmpcr = an2_func(); break;
1633 case 3: upd7810.tmpcr = an3_func(); break;
1634 case 4: upd7810.tmpcr = an4_func(); break;
1635 case 5: upd7810.tmpcr = an5_func(); break;
1636 case 6: upd7810.tmpcr = an6_func(); break;
1637 case 7: upd7810.tmpcr = an7_func(); break;
1638 }
1639 upd7810.shdone = 1;
1640 }
1641 if (upd7810.adcnt > upd7810.adtot)
1642 {
1643 upd7810.adcnt -= upd7810.adtot;
1644 switch (upd7810.adout)
1645 {
1646 // volfied code checks bit 0x80, old code set bit 0x01, TODO: verify which bits are set on real hw
1647 case 0: CR0 = upd7810.tmpcr ? 0xff:0x00; break;
1648 case 1: CR1 = upd7810.tmpcr ? 0xff:0x00; break;
1649 case 2: CR2 = upd7810.tmpcr ? 0xff:0x00; break;
1650 case 3: CR3 = upd7810.tmpcr ? 0xff:0x00; break;
1651 }
1652 upd7810.adout = (upd7810.adout + 1) & 0x03;
1653 if (upd7810.adout == 0)
1654 IRR |= INTFAD;
1655 upd7810.shdone = 0;
1656 }
1657 }
1658 else
1659 {
1660 /* scan mode */
1661 if (upd7810.shdone == 0)
1662 {
1663 switch (upd7810.adin | upd7810.adrange)
1664 {
1665 case 0: upd7810.tmpcr = an0_func(); break;
1666 case 1: upd7810.tmpcr = an1_func(); break;
1667 case 2: upd7810.tmpcr = an2_func(); break;
1668 case 3: upd7810.tmpcr = an3_func(); break;
1669 case 4: upd7810.tmpcr = an4_func(); break;
1670 case 5: upd7810.tmpcr = an5_func(); break;
1671 case 6: upd7810.tmpcr = an6_func(); break;
1672 case 7: upd7810.tmpcr = an7_func(); break;
1673 }
1674 upd7810.shdone = 1;
1675 }
1676 if (upd7810.adcnt > upd7810.adtot)
1677 {
1678 upd7810.adcnt -= upd7810.adtot;
1679 switch (upd7810.adout)
1680 {
1681 case 0: CR0 = upd7810.tmpcr ? 0xff:0x00; break;
1682 case 1: CR1 = upd7810.tmpcr ? 0xff:0x00; break;
1683 case 2: CR2 = upd7810.tmpcr ? 0xff:0x00; break;
1684 case 3: CR3 = upd7810.tmpcr ? 0xff:0x00; break;
1685 }
1686 upd7810.adin = (upd7810.adin + 1) & 0x07;
1687 upd7810.adout = (upd7810.adout + 1) & 0x03;
1688 if (upd7810.adout == 0)
1689 IRR |= INTFAD;
1690 upd7810.shdone = 0;
1691 }
1692 }
1693 }
1694
1695 #include "7810tbl.c"
1696 #include "7810ops.c"
1697
fake_an_func()1698 static UINT8 fake_an_func()
1699 {
1700 return 0;
1701 }
1702
upd7810SetAnfunc(INT32 select,UINT8 (* func)())1703 void upd7810SetAnfunc(INT32 select, UINT8 (*func)())
1704 {
1705 switch (select & 7)
1706 {
1707 case 0: an0_func = func; break;
1708 case 1: an1_func = func; break;
1709 case 2: an2_func = func; break;
1710 case 3: an3_func = func; break;
1711 case 4: an4_func = func; break;
1712 case 5: an5_func = func; break;
1713 case 6: an6_func = func; break;
1714 case 7: an7_func = func; break;
1715 }
1716 }
1717
upd7810Open(INT32)1718 void upd7810Open(INT32)
1719 {
1720 // only one CPU supported
1721 }
1722
upd7810Close()1723 void upd7810Close()
1724 {
1725
1726 }
1727
upd7810GetActive()1728 INT32 upd7810GetActive()
1729 {
1730 return 0; // only one cpu supported
1731 }
1732
upd7810_init(INT32 (* io_callback)(INT32 ioline,INT32 state))1733 static void upd7810_init(INT32 (*io_callback)(INT32 ioline, INT32 state))
1734 {
1735 upd7810_io_callback = io_callback;
1736
1737 read_byte_8 = dummy_read;
1738 write_byte_8 = dummy_write;
1739 io_read_byte_8 = dummy_read_port;
1740 io_write_byte_8 = dummy_write_port;
1741
1742 memset (mem, 0, 3 * 0x100 * sizeof(UINT8*));
1743
1744 an0_func = fake_an_func;
1745 an1_func = fake_an_func;
1746 an2_func = fake_an_func;
1747 an3_func = fake_an_func;
1748 an4_func = fake_an_func;
1749 an5_func = fake_an_func;
1750 an6_func = fake_an_func;
1751 an7_func = fake_an_func;
1752
1753 CpuCheatRegister(0, &upd7810Config);
1754
1755 #if 0
1756 int cpu = cpu_getactivecpu();
1757
1758 state_save_register_UINT16("upd7810", cpu, "ppc", &upd7810.ppc.w.l, 1);
1759 state_save_register_UINT16("upd7810", cpu, "pc", &upd7810.pc.w.l, 1);
1760 state_save_register_UINT16("upd7810", cpu, "sp", &upd7810.sp.w.l, 1);
1761 state_save_register_UINT8 ("upd7810", cpu, "psw", &upd7810.psw, 1);
1762 state_save_register_UINT8 ("upd7810", cpu, "op", &upd7810.op, 1);
1763 state_save_register_UINT8 ("upd7810", cpu, "op2", &upd7810.op2, 1);
1764 state_save_register_UINT8 ("upd7810", cpu, "iff", &upd7810.iff, 1);
1765 state_save_register_UINT16("upd7810", cpu, "ea", &upd7810.ea.w.l, 1);
1766 state_save_register_UINT16("upd7810", cpu, "va", &upd7810.va.w.l, 1);
1767 state_save_register_UINT16("upd7810", cpu, "bc", &upd7810.bc.w.l, 1);
1768 state_save_register_UINT16("upd7810", cpu, "de", &upd7810.de.w.l, 1);
1769 state_save_register_UINT16("upd7810", cpu, "hl", &upd7810.hl.w.l, 1);
1770 state_save_register_UINT16("upd7810", cpu, "ea2", &upd7810.ea2.w.l, 1);
1771 state_save_register_UINT16("upd7810", cpu, "va2", &upd7810.va2.w.l, 1);
1772 state_save_register_UINT16("upd7810", cpu, "bc2", &upd7810.bc2.w.l, 1);
1773 state_save_register_UINT16("upd7810", cpu, "de2", &upd7810.de2.w.l, 1);
1774 state_save_register_UINT16("upd7810", cpu, "hl2", &upd7810.hl2.w.l, 1);
1775 state_save_register_UINT32("upd7810", cpu, "cnt", &upd7810.cnt.d, 1);
1776 state_save_register_UINT32("upd7810", cpu, "tm", &upd7810.tm.d, 1);
1777 state_save_register_UINT32("upd7810", cpu, "ecnt", &upd7810.ecnt.d, 1);
1778 state_save_register_UINT32("upd7810", cpu, "etm", &upd7810.etm.d, 1);
1779 state_save_register_UINT8 ("upd7810", cpu, "ma", &upd7810.ma, 1);
1780 state_save_register_UINT8 ("upd7810", cpu, "mb", &upd7810.mb, 1);
1781 state_save_register_UINT8 ("upd7810", cpu, "mcc", &upd7810.mcc, 1);
1782 state_save_register_UINT8 ("upd7810", cpu, "mc", &upd7810.mc, 1);
1783 state_save_register_UINT8 ("upd7810", cpu, "mm", &upd7810.mm, 1);
1784 state_save_register_UINT8 ("upd7810", cpu, "mf", &upd7810.mf, 1);
1785 state_save_register_UINT8 ("upd7810", cpu, "tmm", &upd7810.tmm, 1);
1786 state_save_register_UINT8 ("upd7810", cpu, "etmm", &upd7810.etmm, 1);
1787 state_save_register_UINT8 ("upd7810", cpu, "eom", &upd7810.eom, 1);
1788 state_save_register_UINT8 ("upd7810", cpu, "sml", &upd7810.sml, 1);
1789 state_save_register_UINT8 ("upd7810", cpu, "smh", &upd7810.smh, 1);
1790 state_save_register_UINT8 ("upd7810", cpu, "anm", &upd7810.anm, 1);
1791 state_save_register_UINT8 ("upd7810", cpu, "mkl", &upd7810.mkl, 1);
1792 state_save_register_UINT8 ("upd7810", cpu, "mkh", &upd7810.mkh, 1);
1793 state_save_register_UINT8 ("upd7810", cpu, "zcm", &upd7810.zcm, 1);
1794 state_save_register_UINT8 ("upd7810", cpu, "pa_out", &upd7810.pa_out, 1);
1795 state_save_register_UINT8 ("upd7810", cpu, "pb_out", &upd7810.pb_out, 1);
1796 state_save_register_UINT8 ("upd7810", cpu, "pc_out", &upd7810.pc_out, 1);
1797 state_save_register_UINT8 ("upd7810", cpu, "pd_out", &upd7810.pd_out, 1);
1798 state_save_register_UINT8 ("upd7810", cpu, "pf_out", &upd7810.pf_out, 1);
1799 state_save_register_UINT8 ("upd7810", cpu, "cr0", &upd7810.cr0, 1);
1800 state_save_register_UINT8 ("upd7810", cpu, "cr1", &upd7810.cr1, 1);
1801 state_save_register_UINT8 ("upd7810", cpu, "cr2", &upd7810.cr2, 1);
1802 state_save_register_UINT8 ("upd7810", cpu, "cr3", &upd7810.cr3, 1);
1803 state_save_register_UINT8 ("upd7810", cpu, "txb", &upd7810.txb, 1);
1804 state_save_register_UINT8 ("upd7810", cpu, "rxb", &upd7810.rxb, 1);
1805 state_save_register_UINT8 ("upd7810", cpu, "txd", &upd7810.txd, 1);
1806 state_save_register_UINT8 ("upd7810", cpu, "rxd", &upd7810.rxd, 1);
1807 state_save_register_UINT8 ("upd7810", cpu, "sck", &upd7810.sck, 1);
1808 state_save_register_UINT8 ("upd7810", cpu, "ti", &upd7810.ti, 1);
1809 state_save_register_UINT8 ("upd7810", cpu, "to", &upd7810.to, 1);
1810 state_save_register_UINT8 ("upd7810", cpu, "ci", &upd7810.ci, 1);
1811 state_save_register_UINT8 ("upd7810", cpu, "co0", &upd7810.co0, 1);
1812 state_save_register_UINT8 ("upd7810", cpu, "co1", &upd7810.co1, 1);
1813 state_save_register_UINT16("upd7810", cpu, "irr", &upd7810.irr, 1);
1814 state_save_register_UINT16("upd7810", cpu, "itf", &upd7810.itf, 1);
1815 state_save_register_INT32 ("upd7810", cpu, "ovc0", &upd7810.ovc0, 1);
1816 state_save_register_INT32 ("upd7810", cpu, "ovc1", &upd7810.ovc1, 1);
1817 state_save_register_INT32 ("upd7810", cpu, "ovcf", &upd7810.ovcf, 1);
1818 state_save_register_INT32 ("upd7810", cpu, "ovcs", &upd7810.ovcs, 1);
1819 state_save_register_UINT8 ("upd7810", cpu, "edges",&upd7810.edges,1);
1820 #endif
1821 }
1822
upd7810Scan(INT32 nAction)1823 INT32 upd7810Scan(INT32 nAction)
1824 {
1825 struct BurnArea ba;
1826
1827 if (nAction & ACB_DRIVER_DATA)
1828 {
1829 ba.Data = &upd7810;
1830 ba.nLen = sizeof(upd7810);
1831 ba.nAddress = 0;
1832 ba.szName = "Upd7810 Regs";
1833 BurnAcb(&ba);
1834
1835 SCAN_VAR(upd7810_icount);
1836 SCAN_VAR(upd7810_total_cycles);
1837 SCAN_VAR(upd7810_current_cycles);
1838 }
1839
1840 return 0;
1841 }
1842
upd7810Init(INT32 (* io_callback)(INT32 ioline,INT32 state))1843 void upd7810Init(INT32 (*io_callback)(INT32 ioline, INT32 state))
1844 {
1845 upd7810_init(io_callback);
1846
1847 opXX = opXX_7810;
1848
1849 }
1850
upd7807Init(INT32 (* io_callback)(INT32 ioline,INT32 state))1851 void upd7807Init(INT32 (*io_callback)(INT32 ioline, INT32 state))
1852 {
1853 upd7810_init(io_callback);
1854
1855 opXX = opXX_7807;
1856
1857 }
1858
upd7810Reset()1859 void upd7810Reset()
1860 {
1861 memset(&upd7810, 0, sizeof(upd7810));
1862 MA = 0xff;
1863 MB = 0xff;
1864 MC = 0xff;
1865
1866 MF = 0xff;
1867 TMM = 0xff;
1868 ETMM = 0xff;
1869 // gamemaster falling block "and"s to enable interrupts
1870 MKL = 0xff;
1871 MKH = 0xff; //?
1872
1873 upd7810_icount = 0;
1874 upd7810_total_cycles = 0;
1875 upd7810_current_cycles = 0;
1876
1877 upd7810.PANM = 0xff; //reset
1878 }
1879
upd7810Exit()1880 void upd7810Exit()
1881 {
1882 upd7810_io_callback = NULL;
1883 upd7810_config_type = 0;
1884 }
1885
1886 static int run_end = 0;
1887
upd7810Run(INT32 cycles)1888 INT32 upd7810Run(INT32 cycles)
1889 {
1890 upd7810_current_cycles = cycles;
1891 upd7810_icount = cycles;
1892
1893 run_end = 0;
1894
1895 do
1896 {
1897 int cc = 0;
1898
1899 #if 0
1900 CALL_MAME_DEBUG;
1901 #endif
1902 PPC = PC;
1903
1904 RDOP(OP);
1905
1906 /*
1907 * clear L0 and/or L1 flags for all opcodes except
1908 * L0 for "MVI L,xx" or "LXI H,xxxx"
1909 * L1 for "MVI A,xx"
1910 */
1911 PSW &= ~opXX[OP].mask_l0_l1;
1912
1913 /* skip flag set and not SOFTI opcode? */
1914 if ((PSW & SK) && (OP != 0x72))
1915 {
1916 if (opXX[OP].cycles)
1917 {
1918 cc = opXX[OP].cycles_skip;
1919 PC += opXX[OP].oplen - 1;
1920 }
1921 else
1922 {
1923 RDOP(OP2);
1924
1925 switch (OP)
1926 {
1927 case 0x48:
1928 cc = op48[OP2].cycles_skip;
1929 PC += op48[OP2].oplen - 2;
1930 break;
1931 case 0x4c:
1932 cc = op4C[OP2].cycles_skip;
1933 PC += op4C[OP2].oplen - 2;
1934 break;
1935 case 0x4d:
1936 cc = op4D[OP2].cycles_skip;
1937 PC += op4D[OP2].oplen - 2;
1938 break;
1939 case 0x60:
1940 cc = op60[OP2].cycles_skip;
1941 PC += op60[OP2].oplen - 2;
1942 break;
1943 case 0x64:
1944 cc = op64[OP2].cycles_skip;
1945 PC += op64[OP2].oplen - 2;
1946 break;
1947 case 0x70:
1948 cc = op70[OP2].cycles_skip;
1949 PC += op70[OP2].oplen - 2;
1950 break;
1951 case 0x74:
1952 cc = op74[OP2].cycles_skip;
1953 PC += op74[OP2].oplen - 2;
1954 break;
1955 //default:
1956 // osd_die("uPD7810 internal error: check cycle counts for main\n");
1957 }
1958 }
1959
1960 PSW &= ~SK;
1961 upd7810_timers( cc );
1962 //change_pc( PCD );
1963 }
1964 else
1965 {
1966 cc = opXX[OP].cycles;
1967 upd7810_timers( cc );
1968 (*opXX[OP].opfunc)();
1969 }
1970
1971 upd7810_icount -= cc;
1972 upd7810_take_irq();
1973
1974 if (run_end) {
1975 run_end = 0;
1976 break;
1977 }
1978 } while (upd7810_icount > 0);
1979
1980 upd7810_total_cycles += (upd7810_current_cycles - upd7810_icount);
1981
1982 INT32 ret = cycles - upd7810_icount;
1983
1984 upd7810_current_cycles = 0;
1985 upd7810_icount = 0;
1986
1987 return ret;
1988 }
1989
upd7810TotalCycles()1990 INT32 upd7810TotalCycles()
1991 {
1992 return upd7810_total_cycles + (upd7810_current_cycles - upd7810_icount);
1993 }
1994
upd7810NewFrame()1995 void upd7810NewFrame()
1996 {
1997 upd7810_total_cycles = 0;
1998 upd7810_current_cycles = 0;
1999 upd7810_icount = 0;
2000 }
2001
upd7810RunEnd()2002 void upd7810RunEnd()
2003 {
2004 run_end = 1;
2005 }
2006
upd7810Idle(INT32 cycles)2007 INT32 upd7810Idle(INT32 cycles)
2008 {
2009 upd7810_total_cycles += cycles;
2010 return cycles;
2011 }
2012
2013 #if 0
2014 static void upd7810_get_context (void *dst)
2015 {
2016 if (dst)
2017 memcpy(dst, &upd7810, sizeof(upd7810));
2018 }
2019
2020 static void upd7810_set_context (void *src)
2021 {
2022 if (src)
2023 memcpy(&upd7810, src, sizeof(upd7810));
2024 }
2025 #endif
2026
2027 // if probs with taito c-chip, add the edge level checks hereunder in latest upd7810 core
set_irq_line(int irqline,int state)2028 static void set_irq_line(int irqline, int state)
2029 {
2030 if (state != CLEAR_LINE)
2031 {
2032 if (irqline == CPU_IRQLINE_NMI)
2033 {
2034 /* no nested NMIs ? */
2035 // if (0 == (IRR & INTNMI))
2036 {
2037 IRR |= INTNMI;
2038 }
2039 }
2040 else
2041 if (irqline == UPD7810_INTF1)
2042 IRR |= INTF1;
2043 else
2044 if (irqline == UPD7810_INTF2)
2045 IRR |= INTF2;
2046 // gamemaster hack
2047 else
2048 if (irqline == UPD7810_INTFE1)
2049 IRR |= INTFE1;
2050 // else
2051 // logerror("upd7810_set_irq_line invalid irq line #%d\n", irqline);
2052 }
2053 /* resetting interrupt requests is done with the SKIT/SKNIT opcodes only! */
2054 }
2055
upd7810SetIRQLine(INT32 line,INT32 state)2056 void upd7810SetIRQLine(INT32 line, INT32 state)
2057 {
2058 if (state == CPU_IRQSTATUS_AUTO)
2059 {
2060 set_irq_line(line, 1);
2061 upd7810Run(10);
2062 set_irq_line(line, 0);
2063
2064 }
2065 else
2066 {
2067 set_irq_line(line, state);
2068 //upd7810Run(10);
2069 }
2070 }
2071
2072 #if 0
2073
2074 static offs_t upd7810_dasm(char *buffer, offs_t pc)
2075 {
2076 #ifdef MAME_DEBUG
2077 return Dasm7810( buffer, pc );
2078 #else
2079 UINT8 op = cpu_readop(pc);
2080 sprintf( buffer, "$%02X", op );
2081 return 1;
2082 #endif
2083 }
2084
2085
2086 static offs_t upd7807_dasm(char *buffer, offs_t pc)
2087 {
2088 #ifdef MAME_DEBUG
2089 return Dasm7807( buffer, pc );
2090 #else
2091 UINT8 op = cpu_readop(pc);
2092 sprintf( buffer, "$%02X", op );
2093 return 1;
2094 #endif
2095 }
2096
2097
2098 /**************************************************************************
2099 * Generic set_info
2100 **************************************************************************/
2101
2102 static void upd7810_set_info(UINT32 state, union cpuinfo *info)
2103 {
2104 switch (state)
2105 {
2106 /* --- the following bits of info are set as 64-bit signed integers --- */
2107 case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break;
2108 case CPUINFO_INT_INPUT_STATE + UPD7810_INTF1: set_irq_line(UPD7810_INTF1, info->i); break;
2109 case CPUINFO_INT_INPUT_STATE + UPD7810_INTF2: set_irq_line(UPD7810_INTF2, info->i); break;
2110 case CPUINFO_INT_INPUT_STATE + UPD7810_INTFE1: set_irq_line(UPD7810_INTFE1, info->i); break;
2111
2112 case CPUINFO_INT_PC: PC = info->i; change_pc(PCD); break;
2113 case CPUINFO_INT_REGISTER + UPD7810_PC: PC = info->i; break;
2114 case CPUINFO_INT_SP:
2115 case CPUINFO_INT_REGISTER + UPD7810_SP: SP = info->i; break;
2116 case CPUINFO_INT_REGISTER + UPD7810_PSW: PSW = info->i; break;
2117 case CPUINFO_INT_REGISTER + UPD7810_A: A = info->i; break;
2118 case CPUINFO_INT_REGISTER + UPD7810_V: V = info->i; break;
2119 case CPUINFO_INT_REGISTER + UPD7810_EA: EA = info->i; break;
2120 case CPUINFO_INT_REGISTER + UPD7810_VA: VA = info->i; break;
2121 case CPUINFO_INT_REGISTER + UPD7810_BC: BC = info->i; break;
2122 case CPUINFO_INT_REGISTER + UPD7810_DE: DE = info->i; break;
2123 case CPUINFO_INT_REGISTER + UPD7810_HL: HL = info->i; break;
2124 case CPUINFO_INT_REGISTER + UPD7810_EA2: EA2 = info->i; break;
2125 case CPUINFO_INT_REGISTER + UPD7810_VA2: VA2 = info->i; break;
2126 case CPUINFO_INT_REGISTER + UPD7810_BC2: BC2 = info->i; break;
2127 case CPUINFO_INT_REGISTER + UPD7810_DE2: DE2 = info->i; break;
2128 case CPUINFO_INT_REGISTER + UPD7810_HL2: HL2 = info->i; break;
2129 case CPUINFO_INT_REGISTER + UPD7810_CNT0: CNT0 = info->i; break;
2130 case CPUINFO_INT_REGISTER + UPD7810_CNT1: CNT1 = info->i; break;
2131 case CPUINFO_INT_REGISTER + UPD7810_TM0: TM0 = info->i; break;
2132 case CPUINFO_INT_REGISTER + UPD7810_TM1: TM1 = info->i; break;
2133 case CPUINFO_INT_REGISTER + UPD7810_ECNT: ECNT = info->i; break;
2134 case CPUINFO_INT_REGISTER + UPD7810_ECPT: ECPT = info->i; break;
2135 case CPUINFO_INT_REGISTER + UPD7810_ETM0: ETM0 = info->i; break;
2136 case CPUINFO_INT_REGISTER + UPD7810_ETM1: ETM1 = info->i; break;
2137 case CPUINFO_INT_REGISTER + UPD7810_MA: MA = info->i; break;
2138 case CPUINFO_INT_REGISTER + UPD7810_MB: MB = info->i; break;
2139 case CPUINFO_INT_REGISTER + UPD7810_MCC: MCC = info->i; break;
2140 case CPUINFO_INT_REGISTER + UPD7810_MC: MC = info->i; break;
2141 case CPUINFO_INT_REGISTER + UPD7810_MM: MM = info->i; break;
2142 case CPUINFO_INT_REGISTER + UPD7810_MF: MF = info->i; break;
2143 case CPUINFO_INT_REGISTER + UPD7810_TMM: TMM = info->i; break;
2144 case CPUINFO_INT_REGISTER + UPD7810_ETMM: ETMM = info->i; break;
2145 case CPUINFO_INT_REGISTER + UPD7810_EOM: EOM = info->i; break;
2146 case CPUINFO_INT_REGISTER + UPD7810_SML: SML = info->i; break;
2147 case CPUINFO_INT_REGISTER + UPD7810_SMH: SMH = info->i; break;
2148 case CPUINFO_INT_REGISTER + UPD7810_ANM: ANM = info->i; break;
2149 case CPUINFO_INT_REGISTER + UPD7810_MKL: MKL = info->i; break;
2150 case CPUINFO_INT_REGISTER + UPD7810_MKH: MKH = info->i; break;
2151 case CPUINFO_INT_REGISTER + UPD7810_ZCM: ZCM = info->i; break;
2152 case CPUINFO_INT_REGISTER + UPD7810_TXB: TXB = info->i; break;
2153 case CPUINFO_INT_REGISTER + UPD7810_RXB: RXB = info->i; break;
2154 case CPUINFO_INT_REGISTER + UPD7810_CR0: CR0 = info->i; break;
2155 case CPUINFO_INT_REGISTER + UPD7810_CR1: CR1 = info->i; break;
2156 case CPUINFO_INT_REGISTER + UPD7810_CR2: CR2 = info->i; break;
2157 case CPUINFO_INT_REGISTER + UPD7810_CR3: CR3 = info->i; break;
2158 case CPUINFO_INT_REGISTER + UPD7810_TXD: TXD = info->i; break;
2159 case CPUINFO_INT_REGISTER + UPD7810_RXD: RXD = info->i; break;
2160 case CPUINFO_INT_REGISTER + UPD7810_SCK: SCK = info->i; break;
2161 case CPUINFO_INT_REGISTER + UPD7810_TI: TI = info->i; break;
2162 case CPUINFO_INT_REGISTER + UPD7810_TO: TO = info->i; break;
2163 case CPUINFO_INT_REGISTER + UPD7810_CI: CI = info->i; break;
2164 case CPUINFO_INT_REGISTER + UPD7810_CO0: CO0 = info->i; break;
2165 case CPUINFO_INT_REGISTER + UPD7810_CO1: CO1 = info->i; break;
2166
2167 /* --- the following bits of info are set as pointers to data or functions --- */
2168 case CPUINFO_PTR_IRQ_CALLBACK: upd7810.irq_callback = info->irqcallback; break;
2169 }
2170 }
2171
2172
2173
2174 /**************************************************************************
2175 * Generic get_info
2176 **************************************************************************/
2177
2178 void upd7810_get_info(UINT32 state, union cpuinfo *info)
2179 {
2180 switch (state)
2181 {
2182 /* --- the following bits of info are returned as 64-bit signed integers --- */
2183 case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(upd7810); break;
2184 case CPUINFO_INT_INPUT_LINES: info->i = 2; break;
2185 case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
2186 case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
2187 case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
2188 case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
2189 case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break;
2190 case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
2191 case CPUINFO_INT_MAX_CYCLES: info->i = 40; break;
2192
2193 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 8; break;
2194 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
2195 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
2196 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
2197 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
2198 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
2199 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break;
2200 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 8; break;
2201 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
2202
2203 case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = (IRR & INTNMI) ? ASSERT_LINE : CLEAR_LINE; break;
2204 case CPUINFO_INT_INPUT_STATE + UPD7810_INTF1: info->i = (IRR & INTF1) ? ASSERT_LINE : CLEAR_LINE; break;
2205 case CPUINFO_INT_INPUT_STATE + UPD7810_INTF2: info->i = (IRR & INTF2) ? ASSERT_LINE : CLEAR_LINE; break;
2206 case CPUINFO_INT_INPUT_STATE + UPD7810_INTFE1: info->i = (IRR & INTFE1) ? ASSERT_LINE : CLEAR_LINE; break;
2207
2208 case CPUINFO_INT_PREVIOUSPC: info->i = PPC; break;
2209
2210 case CPUINFO_INT_PC:
2211 case CPUINFO_INT_REGISTER + UPD7810_PC: info->i = PC; break;
2212 case CPUINFO_INT_SP:
2213 case CPUINFO_INT_REGISTER + UPD7810_SP: info->i = SP; break;
2214 case CPUINFO_INT_REGISTER + UPD7810_PSW: info->i = PSW; break;
2215 case CPUINFO_INT_REGISTER + UPD7810_EA: info->i = EA; break;
2216 case CPUINFO_INT_REGISTER + UPD7810_VA: info->i = VA; break;
2217 case CPUINFO_INT_REGISTER + UPD7810_BC: info->i = BC; break;
2218 case CPUINFO_INT_REGISTER + UPD7810_DE: info->i = DE; break;
2219 case CPUINFO_INT_REGISTER + UPD7810_HL: info->i = HL; break;
2220 case CPUINFO_INT_REGISTER + UPD7810_EA2: info->i = EA2; break;
2221 case CPUINFO_INT_REGISTER + UPD7810_VA2: info->i = VA2; break;
2222 case CPUINFO_INT_REGISTER + UPD7810_BC2: info->i = BC2; break;
2223 case CPUINFO_INT_REGISTER + UPD7810_DE2: info->i = DE2; break;
2224 case CPUINFO_INT_REGISTER + UPD7810_HL2: info->i = HL2; break;
2225 case CPUINFO_INT_REGISTER + UPD7810_CNT0: info->i = CNT0; break;
2226 case CPUINFO_INT_REGISTER + UPD7810_CNT1: info->i = CNT1; break;
2227 case CPUINFO_INT_REGISTER + UPD7810_TM0: info->i = TM0; break;
2228 case CPUINFO_INT_REGISTER + UPD7810_TM1: info->i = TM1; break;
2229 case CPUINFO_INT_REGISTER + UPD7810_ECNT: info->i = ECNT; break;
2230 case CPUINFO_INT_REGISTER + UPD7810_ECPT: info->i = ECPT; break;
2231 case CPUINFO_INT_REGISTER + UPD7810_ETM0: info->i = ETM0; break;
2232 case CPUINFO_INT_REGISTER + UPD7810_ETM1: info->i = ETM1; break;
2233 case CPUINFO_INT_REGISTER + UPD7810_MA: info->i = MA; break;
2234 case CPUINFO_INT_REGISTER + UPD7810_MB: info->i = MB; break;
2235 case CPUINFO_INT_REGISTER + UPD7810_MCC: info->i = MCC; break;
2236 case CPUINFO_INT_REGISTER + UPD7810_MC: info->i = MC; break;
2237 case CPUINFO_INT_REGISTER + UPD7810_MM: info->i = MM; break;
2238 case CPUINFO_INT_REGISTER + UPD7810_MF: info->i = MF; break;
2239 case CPUINFO_INT_REGISTER + UPD7810_TMM: info->i = TMM; break;
2240 case CPUINFO_INT_REGISTER + UPD7810_ETMM: info->i = ETMM; break;
2241 case CPUINFO_INT_REGISTER + UPD7810_EOM: info->i = EOM; break;
2242 case CPUINFO_INT_REGISTER + UPD7810_SML: info->i = SML; break;
2243 case CPUINFO_INT_REGISTER + UPD7810_SMH: info->i = SMH; break;
2244 case CPUINFO_INT_REGISTER + UPD7810_ANM: info->i = ANM; break;
2245 case CPUINFO_INT_REGISTER + UPD7810_MKL: info->i = MKL; break;
2246 case CPUINFO_INT_REGISTER + UPD7810_MKH: info->i = MKH; break;
2247 case CPUINFO_INT_REGISTER + UPD7810_ZCM: info->i = ZCM; break;
2248 case CPUINFO_INT_REGISTER + UPD7810_TXB: info->i = TXB; break;
2249 case CPUINFO_INT_REGISTER + UPD7810_RXB: info->i = RXB; break;
2250 case CPUINFO_INT_REGISTER + UPD7810_CR0: info->i = CR0; break;
2251 case CPUINFO_INT_REGISTER + UPD7810_CR1: info->i = CR1; break;
2252 case CPUINFO_INT_REGISTER + UPD7810_CR2: info->i = CR2; break;
2253 case CPUINFO_INT_REGISTER + UPD7810_CR3: info->i = CR3; break;
2254 case CPUINFO_INT_REGISTER + UPD7810_TXD: info->i = TXD; break;
2255 case CPUINFO_INT_REGISTER + UPD7810_RXD: info->i = RXD; break;
2256 case CPUINFO_INT_REGISTER + UPD7810_SCK: info->i = SCK; break;
2257 case CPUINFO_INT_REGISTER + UPD7810_TI: info->i = TI; break;
2258 case CPUINFO_INT_REGISTER + UPD7810_TO: info->i = TO; break;
2259 case CPUINFO_INT_REGISTER + UPD7810_CI: info->i = CI; break;
2260 case CPUINFO_INT_REGISTER + UPD7810_CO0: info->i = CO0; break;
2261 case CPUINFO_INT_REGISTER + UPD7810_CO1: info->i = CO1; break;
2262
2263 /* --- the following bits of info are returned as pointers to data or functions --- */
2264 case CPUINFO_PTR_SET_INFO: info->setinfo = upd7810_set_info; break;
2265 case CPUINFO_PTR_GET_CONTEXT: info->getcontext = upd7810_get_context; break;
2266 case CPUINFO_PTR_SET_CONTEXT: info->setcontext = upd7810_set_context; break;
2267 case CPUINFO_PTR_INIT: info->init = upd7810_init; break;
2268 case CPUINFO_PTR_RESET: info->reset = upd7810_reset; break;
2269 case CPUINFO_PTR_EXIT: info->exit = upd7810_exit; break;
2270 case CPUINFO_PTR_EXECUTE: info->execute = upd7810_execute; break;
2271 case CPUINFO_PTR_BURN: info->burn = NULL; break;
2272 case CPUINFO_PTR_DISASSEMBLE: info->disassemble = upd7810_dasm; break;
2273 case CPUINFO_PTR_IRQ_CALLBACK: info->irqcallback = upd7810.irq_callback; break;
2274 case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &upd7810_icount; break;
2275 case CPUINFO_PTR_REGISTER_LAYOUT: info->p = upd7810_reg_layout; break;
2276 case CPUINFO_PTR_WINDOW_LAYOUT: info->p = upd7810_win_layout; break;
2277
2278 /* --- the following bits of info are returned as NULL-terminated strings --- */
2279 case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "uPD7810"); break;
2280 case CPUINFO_STR_CORE_FAMILY: strcpy(info->s = cpuintrf_temp_str(), "NEC uPD7810"); break;
2281 case CPUINFO_STR_CORE_VERSION: strcpy(info->s = cpuintrf_temp_str(), "0.3"); break;
2282 case CPUINFO_STR_CORE_FILE: strcpy(info->s = cpuintrf_temp_str(), __FILE__); break;
2283 case CPUINFO_STR_CORE_CREDITS: strcpy(info->s = cpuintrf_temp_str(), "Copyright (c) 2001 Juergen Buchmueller, all rights reserved."); break;
2284
2285 case CPUINFO_STR_FLAGS:
2286 sprintf(info->s = cpuintrf_temp_str(), "%s:%s:%s:%s:%s:%s",
2287 upd7810.psw & 0x40 ? "ZF":"--",
2288 upd7810.psw & 0x20 ? "SK":"--",
2289 upd7810.psw & 0x10 ? "HC":"--",
2290 upd7810.psw & 0x08 ? "L1":"--",
2291 upd7810.psw & 0x04 ? "L0":"--",
2292 upd7810.psw & 0x01 ? "CY":"--");
2293 break;
2294
2295 case CPUINFO_STR_REGISTER + UPD7810_PC: sprintf(info->s = cpuintrf_temp_str(), "PC :%04X", upd7810.pc.w.l); break;
2296 case CPUINFO_STR_REGISTER + UPD7810_SP: sprintf(info->s = cpuintrf_temp_str(), "SP :%04X", upd7810.sp.w.l); break;
2297 case CPUINFO_STR_REGISTER + UPD7810_PSW: sprintf(info->s = cpuintrf_temp_str(), "PSW :%02X", upd7810.psw); break;
2298 case CPUINFO_STR_REGISTER + UPD7810_A: sprintf(info->s = cpuintrf_temp_str(), "A :%02X", upd7810.va.b.l); break;
2299 case CPUINFO_STR_REGISTER + UPD7810_V: sprintf(info->s = cpuintrf_temp_str(), "V :%02X", upd7810.va.b.h); break;
2300 case CPUINFO_STR_REGISTER + UPD7810_EA: sprintf(info->s = cpuintrf_temp_str(), "EA :%04X", upd7810.ea.w.l); break;
2301 case CPUINFO_STR_REGISTER + UPD7810_BC: sprintf(info->s = cpuintrf_temp_str(), "BC :%04X", upd7810.bc.w.l); break;
2302 case CPUINFO_STR_REGISTER + UPD7810_DE: sprintf(info->s = cpuintrf_temp_str(), "DE :%04X", upd7810.de.w.l); break;
2303 case CPUINFO_STR_REGISTER + UPD7810_HL: sprintf(info->s = cpuintrf_temp_str(), "HL :%04X", upd7810.hl.w.l); break;
2304 case CPUINFO_STR_REGISTER + UPD7810_A2: sprintf(info->s = cpuintrf_temp_str(), "A' :%02X", upd7810.va2.b.l); break;
2305 case CPUINFO_STR_REGISTER + UPD7810_V2: sprintf(info->s = cpuintrf_temp_str(), "V' :%02X", upd7810.va2.b.h); break;
2306 case CPUINFO_STR_REGISTER + UPD7810_EA2: sprintf(info->s = cpuintrf_temp_str(), "EA' :%04X", upd7810.ea2.w.l); break;
2307 case CPUINFO_STR_REGISTER + UPD7810_BC2: sprintf(info->s = cpuintrf_temp_str(), "BC' :%04X", upd7810.bc2.w.l); break;
2308 case CPUINFO_STR_REGISTER + UPD7810_DE2: sprintf(info->s = cpuintrf_temp_str(), "DE' :%04X", upd7810.de2.w.l); break;
2309 case CPUINFO_STR_REGISTER + UPD7810_HL2: sprintf(info->s = cpuintrf_temp_str(), "HL' :%04X", upd7810.hl2.w.l); break;
2310 case CPUINFO_STR_REGISTER + UPD7810_CNT0: sprintf(info->s = cpuintrf_temp_str(), "CNT0:%02X", upd7810.cnt.b.l); break;
2311 case CPUINFO_STR_REGISTER + UPD7810_CNT1: sprintf(info->s = cpuintrf_temp_str(), "CNT1:%02X", upd7810.cnt.b.h); break;
2312 case CPUINFO_STR_REGISTER + UPD7810_TM0: sprintf(info->s = cpuintrf_temp_str(), "TM0 :%02X", upd7810.tm.b.l); break;
2313 case CPUINFO_STR_REGISTER + UPD7810_TM1: sprintf(info->s = cpuintrf_temp_str(), "TM1 :%02X", upd7810.tm.b.h); break;
2314 case CPUINFO_STR_REGISTER + UPD7810_ECNT: sprintf(info->s = cpuintrf_temp_str(), "ECNT:%04X", upd7810.ecnt.w.l); break;
2315 case CPUINFO_STR_REGISTER + UPD7810_ECPT: sprintf(info->s = cpuintrf_temp_str(), "ECPT:%04X", upd7810.ecnt.w.h); break;
2316 case CPUINFO_STR_REGISTER + UPD7810_ETM0: sprintf(info->s = cpuintrf_temp_str(), "ETM0:%04X", upd7810.etm.w.l); break;
2317 case CPUINFO_STR_REGISTER + UPD7810_ETM1: sprintf(info->s = cpuintrf_temp_str(), "ETM1:%04X", upd7810.etm.w.h); break;
2318 case CPUINFO_STR_REGISTER + UPD7810_MA: sprintf(info->s = cpuintrf_temp_str(), "MA :%02X", upd7810.ma); break;
2319 case CPUINFO_STR_REGISTER + UPD7810_MB: sprintf(info->s = cpuintrf_temp_str(), "MB :%02X", upd7810.mb); break;
2320 case CPUINFO_STR_REGISTER + UPD7810_MCC: sprintf(info->s = cpuintrf_temp_str(), "MCC :%02X", upd7810.mcc); break;
2321 case CPUINFO_STR_REGISTER + UPD7810_MC: sprintf(info->s = cpuintrf_temp_str(), "MC :%02X", upd7810.mc); break;
2322 case CPUINFO_STR_REGISTER + UPD7810_MM: sprintf(info->s = cpuintrf_temp_str(), "MM :%02X", upd7810.mm); break;
2323 case CPUINFO_STR_REGISTER + UPD7810_MF: sprintf(info->s = cpuintrf_temp_str(), "MF :%02X", upd7810.mf); break;
2324 case CPUINFO_STR_REGISTER + UPD7810_TMM: sprintf(info->s = cpuintrf_temp_str(), "TMM :%02X", upd7810.tmm); break;
2325 case CPUINFO_STR_REGISTER + UPD7810_ETMM: sprintf(info->s = cpuintrf_temp_str(), "ETMM:%02X", upd7810.etmm); break;
2326 case CPUINFO_STR_REGISTER + UPD7810_EOM: sprintf(info->s = cpuintrf_temp_str(), "EOM :%02X", upd7810.eom); break;
2327 case CPUINFO_STR_REGISTER + UPD7810_SML: sprintf(info->s = cpuintrf_temp_str(), "SML :%02X", upd7810.sml); break;
2328 case CPUINFO_STR_REGISTER + UPD7810_SMH: sprintf(info->s = cpuintrf_temp_str(), "SMH :%02X", upd7810.smh); break;
2329 case CPUINFO_STR_REGISTER + UPD7810_ANM: sprintf(info->s = cpuintrf_temp_str(), "ANM :%02X", upd7810.anm); break;
2330 case CPUINFO_STR_REGISTER + UPD7810_MKL: sprintf(info->s = cpuintrf_temp_str(), "MKL :%02X", upd7810.mkl); break;
2331 case CPUINFO_STR_REGISTER + UPD7810_MKH: sprintf(info->s = cpuintrf_temp_str(), "MKH :%02X", upd7810.mkh); break;
2332 case CPUINFO_STR_REGISTER + UPD7810_ZCM: sprintf(info->s = cpuintrf_temp_str(), "ZCM :%02X", upd7810.zcm); break;
2333 case CPUINFO_STR_REGISTER + UPD7810_CR0: sprintf(info->s = cpuintrf_temp_str(), "CR0 :%02X", upd7810.cr0); break;
2334 case CPUINFO_STR_REGISTER + UPD7810_CR1: sprintf(info->s = cpuintrf_temp_str(), "CR1 :%02X", upd7810.cr1); break;
2335 case CPUINFO_STR_REGISTER + UPD7810_CR2: sprintf(info->s = cpuintrf_temp_str(), "CR2 :%02X", upd7810.cr2); break;
2336 case CPUINFO_STR_REGISTER + UPD7810_CR3: sprintf(info->s = cpuintrf_temp_str(), "CR3 :%02X", upd7810.cr3); break;
2337 case CPUINFO_STR_REGISTER + UPD7810_RXB: sprintf(info->s = cpuintrf_temp_str(), "RXB :%02X", upd7810.rxb); break;
2338 case CPUINFO_STR_REGISTER + UPD7810_TXB: sprintf(info->s = cpuintrf_temp_str(), "TXB :%02X", upd7810.txb); break;
2339 case CPUINFO_STR_REGISTER + UPD7810_TXD: sprintf(info->s = cpuintrf_temp_str(), "TXD :%d", upd7810.txd); break;
2340 case CPUINFO_STR_REGISTER + UPD7810_RXD: sprintf(info->s = cpuintrf_temp_str(), "RXD :%d", upd7810.rxd); break;
2341 case CPUINFO_STR_REGISTER + UPD7810_SCK: sprintf(info->s = cpuintrf_temp_str(), "SCK :%d", upd7810.sck); break;
2342 case CPUINFO_STR_REGISTER + UPD7810_TI: sprintf(info->s = cpuintrf_temp_str(), "TI :%d", upd7810.ti); break;
2343 case CPUINFO_STR_REGISTER + UPD7810_TO: sprintf(info->s = cpuintrf_temp_str(), "TO :%d", upd7810.to); break;
2344 case CPUINFO_STR_REGISTER + UPD7810_CI: sprintf(info->s = cpuintrf_temp_str(), "CI :%d", upd7810.ci); break;
2345 case CPUINFO_STR_REGISTER + UPD7810_CO0: sprintf(info->s = cpuintrf_temp_str(), "CO0 :%d", upd7810.co0 & 1); break;
2346 case CPUINFO_STR_REGISTER + UPD7810_CO1: sprintf(info->s = cpuintrf_temp_str(), "CO1 :%d", upd7810.co1 & 1); break;
2347 }
2348 }
2349
2350
2351 /**************************************************************************
2352 * CPU-specific set_info
2353 **************************************************************************/
2354
2355 void upd7807_get_info(UINT32 state, union cpuinfo *info)
2356 {
2357 switch (state)
2358 {
2359 /* --- the following bits of info are returned as pointers to data or functions --- */
2360 case CPUINFO_PTR_RESET: info->reset = upd7807_reset; break;
2361 case CPUINFO_PTR_DISASSEMBLE: info->disassemble = upd7807_dasm; break;
2362
2363 /* --- the following bits of info are returned as NULL-terminated strings --- */
2364 case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "uPD7807"); break;
2365
2366 default:
2367 upd7810_get_info(state, info);
2368 break;
2369 }
2370 }
2371 #endif
2372