1 // V60.C
2 // Undiscover the beast!
3 // Main hacking and coding by Farfetch'd
4 // Portability fixes by Richter Belmont
5
6 // Note: strange things can happen if setting an interrupt in a write
7 // handler during an RMW op. v60RunEnd() then call the irq from frame! -dink feb.2020
8
9 #include "burnint.h"
10 #include "bitswap.h" // ...xor_le
11 #include "driver.h"
12 #include "v60_intf.h"
13
14 #define offs_t UINT32
15 #define INPUT_LINE_NMI CPU_IRQLINE_NMI
16
17 #define change_pc(x) v60.reg[32] = (x)
18
19 // convert a series of 32 bits into a float
u2f(UINT32 v)20 inline float u2f(UINT32 v)
21 {
22 union {
23 float ff;
24 UINT32 vv;
25 } u;
26 u.vv = v;
27 return u.ff;
28 }
29
30
31 // convert a float into a series of 32 bits
f2u(float f)32 inline UINT32 f2u(float f)
33 {
34 union {
35 float ff;
36 UINT32 vv;
37 } u;
38 u.ff = f;
39 return u.vv;
40 }
41
42
43 //#define LOG_MEM
44
45 #define page_size 0x800
46 #define page_mask 0x7ff
47
48 static UINT8 **mem[3];
49 static UINT32 address_mask;
50
51 static UINT8 (*v60_read8)(UINT32) = NULL;
52 static UINT16 (*v60_read16)(UINT32) = NULL;
53 static UINT32 (*v60_read32)(UINT32) = NULL;
54 static void (*v60_write8)(UINT32,UINT8) = NULL;
55 static void (*v60_write16)(UINT32,UINT16) = NULL;
56 static void (*v60_write32)(UINT32,UINT32) = NULL;
57
58 static UINT8 (*v60_ioread8)(UINT32) = NULL;
59 static UINT16 (*v60_ioread16)(UINT32) = NULL;
60 static UINT32 (*v60_ioread32)(UINT32) = NULL;
61 static void (*v60_iowrite8)(UINT32,UINT8) = NULL;
62 static void (*v60_iowrite16)(UINT32,UINT16) = NULL;
63 static void (*v60_iowrite32)(UINT32,UINT32) = NULL;
64
65
v60SetWriteByteHandler(void (* write)(UINT32,UINT8))66 void v60SetWriteByteHandler(void (*write)(UINT32,UINT8))
67 {
68 v60_write8 = write;
69 }
70
v60SetWriteWordHandler(void (* write)(UINT32,UINT16))71 void v60SetWriteWordHandler(void (*write)(UINT32,UINT16))
72 {
73 v60_write16 = write;
74 }
75
v60SetWriteLongHandler(void (* write)(UINT32,UINT32))76 void v60SetWriteLongHandler(void (*write)(UINT32,UINT32))
77 {
78 v60_write32 = write;
79 }
80
v60SetReadByteHandler(UINT8 (* read)(UINT32))81 void v60SetReadByteHandler(UINT8 (*read)(UINT32))
82 {
83 v60_read8 = read;
84 }
85
v60SetReadWordHandler(UINT16 (* read)(UINT32))86 void v60SetReadWordHandler(UINT16 (*read)(UINT32))
87 {
88 v60_read16 = read;
89 }
90
v60SetReadLongHandler(UINT32 (* read)(UINT32))91 void v60SetReadLongHandler(UINT32 (*read)(UINT32))
92 {
93 v60_read32 = read;
94 }
95
v60SetAddressMask(UINT32 mask)96 void v60SetAddressMask(UINT32 mask)
97 {
98 address_mask = mask;
99 }
100
v60MapMemory(UINT8 * ptr,UINT64 start,UINT64 end,UINT32 flags)101 void v60MapMemory(UINT8 *ptr, UINT64 start, UINT64 end, UINT32 flags)
102 {
103 // error check here!
104
105 for (UINT64 i = start; i < end; i+= page_size)
106 {
107 if (flags & 1) mem[0][i/page_size] = (ptr == NULL) ? NULL : (ptr + (i - start));
108 if (flags & 2) mem[1][i/page_size] = (ptr == NULL) ? NULL : (ptr + (i - start));
109 if (flags & 4) mem[2][i/page_size] = (ptr == NULL) ? NULL : (ptr + (i - start));
110 }
111 }
112
cpu_readop(UINT32 a)113 static UINT8 cpu_readop(UINT32 a)
114 {
115 a &= address_mask;
116
117 if (mem[2][a / page_size]) {
118 #ifdef LOG_MEM
119 // bprintf (0, _T("OP8: %6.6x %2.2x\n"), a, mem[2][a / page_size][a & page_mask]);
120 #endif
121 return mem[2][a / page_size][a & page_mask];
122 }
123
124 if (v60_read8) {
125 #ifdef LOG_MEM
126 bprintf (0, _T("OP8: %6.6x %2.2x\n"), a, v60_read8(a));
127 #endif
128 return v60_read8(a);
129 }
130
131 return 0;
132 }
133
cpu_readop16(UINT32 a)134 static UINT16 cpu_readop16(UINT32 a)
135 {
136 a &= address_mask;
137
138 UINT8 *p = mem[2][a / page_size];
139
140 if (p) {
141 UINT16 *z = (UINT16*)(p + (a & page_mask));
142 #ifdef LOG_MEM
143 // bprintf (0, _T("OP16: %6.6x %4.4x\n"), a, *z);
144 #endif
145 return BURN_ENDIAN_SWAP_INT16(*z);
146 }
147
148 if (v60_read16) {
149 #ifdef LOG_MEM
150 bprintf (0, _T("OP16: %6.6x %4.4x\n"), a, v60_read16(a));
151 #endif
152
153 return v60_read16(a);
154 }
155
156 return 0;
157 }
158
cpu_readop32(UINT32 a)159 static UINT32 cpu_readop32(UINT32 a)
160 {
161 a &= address_mask;
162
163 UINT8 *p = mem[2][a / page_size];
164
165 if (p) {
166 UINT32 *z = (UINT32*)(p + (a & page_mask));
167
168 #ifdef LOG_MEM
169 // bprintf (0, _T("OP32: %6.6x %8.8x\n"), a, *z);
170 #endif
171
172 return BURN_ENDIAN_SWAP_INT32(*z);
173 }
174
175 if (v60_read32) {
176 #ifdef LOG_MEM
177 bprintf (0, _T("OP32: %6.6x %8.8x\n"), a, v60_read32(a));
178 #endif
179
180 return v60_read32(a);
181 }
182
183 return 0;
184 }
185
program_read_word_16le(UINT32 a)186 static UINT16 program_read_word_16le(UINT32 a)
187 {
188 a &= address_mask;
189
190 UINT8 *p = mem[0][a / page_size];
191
192 if (p) {
193 UINT16 *z = (UINT16*)(p + (a & page_mask));
194 #ifdef LOG_MEM
195 bprintf (0, _T("PRW: %6.6x %4.4x\n"), a, *z);
196 #endif
197
198 return BURN_ENDIAN_SWAP_INT16(*z);
199 }
200
201 if (v60_read16) {
202 #ifdef LOG_MEM
203 bprintf (0, _T("PRW: %6.6x %4.4x\n"), a, v60_read16(a));
204 #endif
205 return v60_read16(a);
206 }
207
208 return 0;
209 }
210
program_read_byte_16le(UINT32 a)211 static UINT8 program_read_byte_16le(UINT32 a)
212 {
213 a &= address_mask;
214
215 #ifdef LOG_MEM
216 bprintf (0, _T("PRB: %6.6x\n"), a);
217 #endif
218
219 if (mem[0][a / page_size]) {
220 return mem[0][a / page_size][a & page_mask];
221 }
222
223 if (v60_read8) {
224 return v60_read8(a);
225 }
226
227 return 0;
228 }
229
program_write_word_16le(UINT32 a,UINT16 d)230 static void program_write_word_16le(UINT32 a, UINT16 d)
231 {
232 a &= address_mask;
233 #ifdef LOG_MEM
234 bprintf (0, _T("PWW: %6.6x %4.4x\n"), a,d);
235 #endif
236
237 UINT8 *p = mem[1][a / page_size];
238
239 if (p) {
240 UINT16 *z = (UINT16*)(p + (a & page_mask));
241 *z = BURN_ENDIAN_SWAP_INT16(d);
242 return;
243 }
244
245 if (v60_write16) {
246 v60_write16(a,d);
247 return;
248 }
249 }
250
program_write_byte_16le(UINT32 a,UINT8 d)251 static void program_write_byte_16le(UINT32 a, UINT8 d)
252 {
253 a &= address_mask;
254 #ifdef LOG_MEM
255 bprintf (0, _T("PWB: %6.6x %2.2x\n"), a,d);
256 #endif
257
258 if (mem[1][a / page_size]) {
259 mem[1][a / page_size][a & page_mask] = d;
260 return;
261 }
262
263 if (v60_write8) {
264 return v60_write8(a,d);
265 }
266 }
267
io_read_word_16le(UINT32 a)268 static UINT16 io_read_word_16le(UINT32 a)
269 {
270 if (v60_ioread16) {
271 return v60_ioread16(a);
272 }
273
274 return 0;
275 }
276
io_read_byte_16le(UINT32 a)277 static UINT8 io_read_byte_16le(UINT32 a)
278 {
279 if (v60_ioread8) {
280 return v60_ioread8(a);
281 }
282
283 return 0;
284 }
285
io_write_word_16le(UINT32 a,UINT16 d)286 static void io_write_word_16le(UINT32 a, UINT16 d)
287 {
288 if (v60_iowrite16) {
289 return v60_iowrite16(a,d);
290 }
291 }
292
io_write_byte_16le(UINT32 a,UINT8 d)293 static void io_write_byte_16le(UINT32 a, UINT8 d)
294 {
295 if (v60_iowrite8) {
296 return v60_iowrite8(a,d);
297 }
298 }
299
io_read_dword_32le(UINT32 a)300 static UINT32 io_read_dword_32le(UINT32 a)
301 {
302 if (v60_ioread32) {
303 return v60_ioread32(a);
304 }
305
306 return 0;
307 }
308
io_read_word_32le(UINT32 a)309 static UINT16 io_read_word_32le(UINT32 a)
310 {
311 if (v60_ioread16) {
312 return v60_ioread16(a);
313 }
314
315 return 0;
316 }
317
io_read_byte_32le(UINT32 a)318 static UINT8 io_read_byte_32le(UINT32 a)
319 {
320 if (v60_ioread8) {
321 return v60_ioread8(a);
322 }
323
324 return 0;
325 }
326
io_write_dword_32le(UINT32 a,UINT32 d)327 static void io_write_dword_32le(UINT32 a, UINT32 d)
328 {
329 if (v60_iowrite32) {
330 return v60_iowrite32(a,d);
331 }
332 }
333
io_write_word_32le(UINT32 a,UINT16 d)334 static void io_write_word_32le(UINT32 a, UINT16 d)
335 {
336 if (v60_iowrite16) {
337 return v60_iowrite16(a,d);
338 }
339 }
340
io_write_byte_32le(UINT32 a,UINT8 d)341 static void io_write_byte_32le(UINT32 a, UINT8 d)
342 {
343 if (v60_iowrite8) {
344 return v60_iowrite8(a,d);
345 }
346 }
347
program_read_dword_32le(UINT32 a)348 static UINT32 program_read_dword_32le(UINT32 a)
349 {
350 a &= address_mask;
351
352 UINT32 *p = (UINT32*)mem[0][a / page_size];
353
354 if (p) {
355 return BURN_ENDIAN_SWAP_INT32(p[(a & page_mask)/4]);
356 }
357
358 if (v60_read32) {
359 return v60_read32(a);
360 }
361
362 return 0;
363 }
364
program_read_word_32le(UINT32 a)365 static UINT16 program_read_word_32le(UINT32 a)
366 {
367 a &= address_mask;
368
369 UINT16 *p = (UINT16*)mem[0][a / page_size];
370
371 if (p) {
372 return BURN_ENDIAN_SWAP_INT16(p[(a & page_mask)/2]);
373 }
374
375 if (v60_read16) {
376 return v60_read16(a);
377 }
378
379 return 0;
380 }
381
program_read_byte_32le(UINT32 a)382 static UINT8 program_read_byte_32le(UINT32 a)
383 {
384 a &= address_mask;
385
386 if (mem[0][a / page_size]) {
387 return mem[0][a / page_size][a & page_mask];
388 }
389
390 if (v60_read8) {
391 return v60_read8(a);
392 }
393
394 return 0;
395 }
396
program_write_dword_32le(UINT32 a,UINT32 d)397 static void program_write_dword_32le(UINT32 a, UINT32 d)
398 {
399 a &= address_mask;
400
401 UINT32 *p = (UINT32*)mem[1][a / page_size];
402
403 if (p) {
404 p[(a & page_mask)/4] = BURN_ENDIAN_SWAP_INT32(d);
405 return;
406 }
407
408 if (v60_write32) {
409 v60_write32(a,d);
410 return;
411 }
412 }
413
program_write_word_32le(UINT32 a,UINT16 d)414 static void program_write_word_32le(UINT32 a, UINT16 d)
415 {
416 a &= address_mask;
417
418 UINT16 *p = (UINT16*)mem[1][a / page_size];
419
420 if (p) {
421 p[(a & page_mask)/2] = BURN_ENDIAN_SWAP_INT16(d);
422 return;
423 }
424
425 if (v60_write16) {
426 v60_write16(a,d);
427 return;
428 }
429 }
430
program_write_byte_32le(UINT32 a,UINT8 d)431 static void program_write_byte_32le(UINT32 a, UINT8 d)
432 {
433 a &= address_mask;
434
435 if (mem[1][a / page_size]) {
436 mem[1][a / page_size][a & page_mask] = d;
437 return;
438 }
439
440 if (v60_write8) {
441 return v60_write8(a,d);
442 }
443 }
444
v60WriteWord(UINT32 address,UINT16 data)445 void v60WriteWord(UINT32 address, UINT16 data)
446 {
447 program_write_word_16le(address, data);
448 }
449
v60WriteByte(UINT32 address,UINT8 data)450 void v60WriteByte(UINT32 address, UINT8 data)
451 {
452 program_write_byte_16le(address, data);
453 }
454
v60ReadWord(UINT32 address)455 UINT16 v60ReadWord(UINT32 address)
456 {
457 return program_read_word_16le(address);
458 }
459
v60ReadByte(UINT32 address)460 UINT16 v60ReadByte(UINT32 address)
461 {
462 return program_read_byte_16le(address);
463 }
464
core_set_irq(INT32,INT32 line,INT32 state)465 static void core_set_irq(INT32 /*cpu*/, INT32 line, INT32 state)
466 {
467 v60SetIRQLine(line, state);
468 }
469
470 cpu_core_config v60Config =
471 {
472 "nec v60",
473 v60Open,
474 v60Close,
475 v60CheatRead,
476 v60WriteROM,
477 v60GetActive,
478 v60TotalCycles,
479 v60NewFrame,
480 v60Idle,
481 core_set_irq,
482 v60Run,
483 v60RunEnd,
484 v60Reset,
485 0x1000000,
486 0
487 };
488
489 struct cpu_info {
490 UINT8 (*mr8) (offs_t address);
491 void (*mw8) (offs_t address, UINT8 data);
492 UINT16 (*mr16)(offs_t address);
493 void (*mw16)(offs_t address, UINT16 data);
494 UINT32 (*mr32)(offs_t address);
495 void (*mw32)(offs_t address, UINT32 data);
496 UINT8 (*pr8) (offs_t address);
497 void (*pw8) (offs_t address, UINT8 data);
498 UINT16 (*pr16)(offs_t address);
499 void (*pw16)(offs_t address, UINT16 data);
500 UINT32 (*pr32)(offs_t address);
501 void (*pw32)(offs_t address, UINT32 data);
502 UINT8 (*or8) (offs_t address);
503 UINT16 (*or16)(offs_t address);
504 UINT32 (*or32)(offs_t address);
505 void (*chpc)(offs_t newpc);
506 UINT32 start_pc;
507 };
508
509 typedef struct
510 {
511 UINT8 CY;
512 UINT8 OV;
513 UINT8 S;
514 UINT8 Z;
515 } Flags;
516
517 // v60 Register Inside (Hm... It's not a pentium inside :-))) )
518 static struct v60info {
519 struct cpu_info info;
520 UINT32 reg[68];
521 Flags flags;
522 UINT8 irq_line;
523 UINT8 nmi_line;
524 int (*irq_cb)(int irqline);
525 UINT32 PPC;
526 UINT32 current_cycles;
527 UINT32 cycles;
528 INT32 stall_io;
529 INT32 end_run;
530 } v60;
531
532
533 static int v60_ICount;
534
535
536 // memory accessors
537 #include "v60mem.c"
538
539
540 // macros stolen from MAME for flags calc
541 // note that these types are in x86 naming:
542 // byte = 8 bit, word = 16 bit, long = 32 bit
543
544 // parameter x = result, y = source 1, z = source 2
545
546 #define SetOFL_Add(x,y,z) (_OV = (((x) ^ (y)) & ((x) ^ (z)) & 0x80000000) ? 1: 0)
547 #define SetOFW_Add(x,y,z) (_OV = (((x) ^ (y)) & ((x) ^ (z)) & 0x8000) ? 1 : 0)
548 #define SetOFB_Add(x,y,z) (_OV = (((x) ^ (y)) & ((x) ^ (z)) & 0x80) ? 1 : 0)
549
550 #define SetOFL_Sub(x,y,z) (_OV = (((z) ^ (y)) & ((z) ^ (x)) & 0x80000000) ? 1 : 0)
551 #define SetOFW_Sub(x,y,z) (_OV = (((z) ^ (y)) & ((z) ^ (x)) & 0x8000) ? 1 : 0)
552 #define SetOFB_Sub(x,y,z) (_OV = (((z) ^ (y)) & ((z) ^ (x)) & 0x80) ? 1 : 0)
553
554 #define SetCFB(x) {_CY = ((x) & 0x100) ? 1 : 0; }
555 #define SetCFW(x) {_CY = ((x) & 0x10000) ? 1 : 0; }
556 #define SetCFL(x) {_CY = ((x) & (((UINT64)1) << 32)) ? 1 : 0; }
557
558 #define SetSF(x) (_S = (x))
559 #define SetZF(x) (_Z = (x))
560
561 #define SetSZPF_Byte(x) {_Z = ((UINT8)(x)==0); _S = ((x)&0x80) ? 1 : 0; }
562 #define SetSZPF_Word(x) {_Z = ((UINT16)(x)==0); _S = ((x)&0x8000) ? 1 : 0; }
563 #define SetSZPF_Long(x) {_Z = ((UINT32)(x)==0); _S = ((x)&0x80000000) ? 1 : 0; }
564
565 #define ORB(dst,src) { (dst) |= (src); _OV = 0; SetSZPF_Byte(dst); }
566 #define ORW(dst,src) { (dst) |= (src); _OV = 0; SetSZPF_Word(dst); }
567 #define ORL(dst,src) { (dst) |= (src); _OV = 0; SetSZPF_Long(dst); }
568
569 #define ANDB(dst,src) { (dst) &= (src); _OV = 0; SetSZPF_Byte(dst); }
570 #define ANDW(dst,src) { (dst) &= (src); _OV = 0; SetSZPF_Word(dst); }
571 #define ANDL(dst,src) { (dst) &= (src); _OV = 0; SetSZPF_Long(dst); }
572
573 #define XORB(dst,src) { (dst) ^= (src); _OV = 0; SetSZPF_Byte(dst); }
574 #define XORW(dst,src) { (dst) ^= (src); _OV = 0; SetSZPF_Word(dst); }
575 #define XORL(dst,src) { (dst) ^= (src); _OV = 0; SetSZPF_Long(dst); }
576
577 #define SUBB(dst, src) { unsigned res=(dst)-(src); SetCFB(res); SetOFB_Sub(res,src,dst); SetSZPF_Byte(res); dst=(UINT8)res; }
578 #define SUBW(dst, src) { unsigned res=(dst)-(src); SetCFW(res); SetOFW_Sub(res,src,dst); SetSZPF_Word(res); dst=(UINT16)res; }
579 #define SUBL(dst, src) { UINT64 res=(UINT64)(dst)-(INT64)(src); SetCFL(res); SetOFL_Sub(res,src,dst); SetSZPF_Long(res); dst=(UINT32)res; }
580
581 #define ADDB(dst, src) { unsigned res=(dst)+(src); SetCFB(res); SetOFB_Add(res,src,dst); SetSZPF_Byte(res); dst=(UINT8)res; }
582 #define ADDW(dst, src) { unsigned res=(dst)+(src); SetCFW(res); SetOFW_Add(res,src,dst); SetSZPF_Word(res); dst=(UINT16)res; }
583 #define ADDL(dst, src) { UINT64 res=(UINT64)(dst)+(UINT64)(src); SetCFL(res); SetOFL_Add(res,src,dst); SetSZPF_Long(res); dst=(UINT32)res; }
584
585 #define SETREG8(a, b) (a) = ((a) & ~0xff) | ((b) & 0xff)
586 #define SETREG16(a, b) (a) = ((a) & ~0xffff) | ((b) & 0xffff)
587
588
589 /*
590 * Prevent warnings on NetBSD. All identifiers beginning with an underscore
591 * followed by an uppercase letter are reserved by the C standard (ISO/IEC
592 * 9899:1999, 7.1.3) to be used by the implementation. It'd be best to rename
593 * all such instances, but this is less intrusive and error-prone.
594 */
595 #undef _S
596
597 #define _CY v60.flags.CY
598 #define _OV v60.flags.OV
599 #define _S v60.flags.S
600 #define _Z v60.flags.Z
601
602
603 // Defines of all v60 register...
604 #define R0 v60.reg[0]
605 #define R1 v60.reg[1]
606 #define R2 v60.reg[2]
607 #define R3 v60.reg[3]
608 #define R4 v60.reg[4]
609 #define R5 v60.reg[5]
610 #define R6 v60.reg[6]
611 #define R7 v60.reg[7]
612 #define R8 v60.reg[8]
613 #define R9 v60.reg[9]
614 #define R10 v60.reg[10]
615 #define R11 v60.reg[11]
616 #define R12 v60.reg[12]
617 #define R13 v60.reg[13]
618 #define R14 v60.reg[14]
619 #define R15 v60.reg[15]
620 #define R16 v60.reg[16]
621 #define R17 v60.reg[17]
622 #define R18 v60.reg[18]
623 #define R19 v60.reg[19]
624 #define R20 v60.reg[20]
625 #define R21 v60.reg[21]
626 #define R22 v60.reg[22]
627 #define R23 v60.reg[23]
628 #define R24 v60.reg[24]
629 #define R25 v60.reg[25]
630 #define R26 v60.reg[26]
631 #define R27 v60.reg[27]
632 #define R28 v60.reg[28]
633 #define AP v60.reg[29]
634 #define FP v60.reg[30]
635 #define SP v60.reg[31]
636
637 #define PC v60.reg[32]
638 #define PSW v60.reg[33]
639
640 // Privileged registers
641 #define ISP v60.reg[36]
642 #define L0SP v60.reg[37]
643 #define L1SP v60.reg[38]
644 #define L2SP v60.reg[39]
645 #define L3SP v60.reg[40]
646 #define SBR v60.reg[41]
647 #define TR v60.reg[42]
648 #define SYCW v60.reg[43]
649 #define TKCW v60.reg[44]
650 #define PIR v60.reg[45]
651 //10-14 reserved
652 #define PSW2 v60.reg[51]
653 #define ATBR0 v60.reg[52]
654 #define ATLR0 v60.reg[53]
655 #define ATBR1 v60.reg[54]
656 #define ATLR1 v60.reg[55]
657 #define ATBR2 v60.reg[56]
658 #define ATLR2 v60.reg[57]
659 #define ATBR3 v60.reg[58]
660 #define ATLR3 v60.reg[59]
661 #define TRMODE v60.reg[60]
662 #define ADTR0 v60.reg[61]
663 #define ADTR1 v60.reg[62]
664 #define ADTMR0 v60.reg[63]
665 #define ADTMR1 v60.reg[64]
666 //29-31 reserved
667
668 // Register names
669 const char *v60_reg_names[69] = {
670 "R0", "R1", "R2", "R3",
671 "R4", "R5", "R6", "R7",
672 "R8", "R9", "R10", "R11",
673 "R12", "R13", "R14", "R15",
674 "R16", "R17", "R18", "R19",
675 "R20", "R21", "R22", "R23",
676 "R24", "R25", "R26", "R27",
677 "R28", "AP", "FP", "SP",
678 "PC", "PSW","Unk","Unk",
679 "ISP", "L0SP", "L1SP", "L2SP",
680 "L3SP", "SBR","TR","SYCW",
681 "TKCW", "PIR", "Reserved","Reserved",
682 "Reserved","Reserved","Reserved","PSW2",
683 "ATBR0", "ATLR0", "ATBR1", "ATLR1",
684 "ATBR2", "ATLR2", "ATBR3", "ATLR3",
685 "TRMODE", "ADTR0", "ADTR1","ADTMR0",
686 "ADTMR1","Reserved","Reserved","Reserved"
687 };
688
689 // Defines...
690 #define NORMALIZEFLAGS() \
691 { \
692 _S = _S ? 1 : 0; \
693 _OV = _OV ? 1 : 0; \
694 _Z = _Z ? 1 : 0; \
695 _CY = _CY ? 1 : 0; \
696 }
697
698 static void v60_try_irq(void);
699
700
v60SaveStack(void)701 INLINE void v60SaveStack(void)
702 {
703 if (PSW & 0x10000000)
704 ISP = SP;
705 else
706 v60.reg[37 + ((PSW >> 24) & 3)] = SP;
707 }
708
v60ReloadStack(void)709 INLINE void v60ReloadStack(void)
710 {
711 if (PSW & 0x10000000)
712 SP = ISP;
713 else
714 SP = v60.reg[37 + ((PSW >> 24) & 3)];
715 }
716
v60ReadPSW(void)717 INLINE UINT32 v60ReadPSW(void)
718 {
719 PSW &= 0xfffffff0;
720 PSW |= (_Z?1:0) | (_S?2:0) | (_OV?4:0) | (_CY?8:0);
721 return PSW;
722 }
723
v60WritePSW(UINT32 newval)724 INLINE void v60WritePSW(UINT32 newval)
725 {
726 /* determine if we need to save/restore the stacks */
727 int updateStack = 0;
728
729 /* if the interrupt state is changing, we definitely need to update */
730 if ((newval ^ PSW) & 0x10000000)
731 updateStack = 1;
732
733 /* if we are not in interrupt mode and the level is changing, we also must update */
734 else if (!(PSW & 0x10000000) && ((newval ^ PSW) & 0x03000000))
735 updateStack = 1;
736
737 /* save the previous stack value */
738 if (updateStack)
739 v60SaveStack();
740
741 /* set the new value and update the flags */
742 PSW = newval;
743 _Z = (UINT8)(PSW & 1);
744 _S = (UINT8)(PSW & 2);
745 _OV = (UINT8)(PSW & 4);
746 _CY = (UINT8)(PSW & 8);
747
748 /* fetch the new stack value */
749 if (updateStack)
750 v60ReloadStack();
751 }
752
753
v60_update_psw_for_exception(int is_interrupt,int target_level)754 INLINE UINT32 v60_update_psw_for_exception(int is_interrupt, int target_level)
755 {
756 UINT32 oldPSW = v60ReadPSW();
757 UINT32 newPSW = oldPSW;
758
759 // Change to interrupt context
760 newPSW &= ~(3 << 24); // PSW.EL = 0
761 newPSW |= target_level << 24; // set target level
762 newPSW &= ~(1 << 18); // PSW.IE = 0
763 newPSW &= ~(1 << 16); // PSW.TE = 0
764 newPSW &= ~(1 << 27); // PSW.TP = 0
765 newPSW &= ~(1 << 17); // PSW.AE = 0
766 newPSW &= ~(1 << 29); // PSW.EM = 0
767 if (is_interrupt)
768 newPSW |= (1 << 28);// PSW.IS = 1
769 newPSW |= (1 << 31); // PSW.ASA = 1
770 v60WritePSW(newPSW);
771
772 return oldPSW;
773 }
774
775
776 #define GETINTVECT(nint) MemRead32((SBR & ~0xfff) + (nint)*4)
777 #define EXCEPTION_CODE_AND_SIZE(code, size) (((code) << 16) | (size))
778
779
780 // Addressing mode decoding functions
781 #include "am.c"
782
783 // Opcode functions
784 #include "op12.c"
785 #include "op2.c"
786 #include "op3.c"
787 #include "op4.c"
788 #include "op5.c"
789 #include "op6.c"
790 #include "op7a.c"
791
opUNHANDLED(void)792 static UINT32 opUNHANDLED(void)
793 {
794 //fatalerror("Unhandled OpCode found : %02x at %08x", OpRead16(PC), PC);
795 return 0; /* never reached, fatalerror won't return */
796 }
797
798 // Opcode jump table
799 #include "optable.c"
800
v60_default_irq_cb(int)801 static int v60_default_irq_cb(int )
802 {
803 return 0;
804 }
805
v60GetActive()806 INT32 v60GetActive()
807 {
808 return 0;
809 }
810
v60CheatRead(UINT32 a)811 UINT8 v60CheatRead(UINT32 a)
812 {
813 return program_read_byte_16le(a);
814 }
815
v60WriteROM(UINT32 a,UINT8 d)816 void v60WriteROM(UINT32 a, UINT8 d)
817 {
818 if (mem[0][a / page_size]) {
819 mem[0][a / page_size][a & page_mask] = d;
820 return;
821 }
822
823 if (mem[1][a / page_size]) {
824 mem[1][a / page_size][a & page_mask] = d;
825 return;
826 }
827
828 if (mem[2][a / page_size]) {
829 mem[2][a / page_size][a & page_mask] = d;
830 return;
831 }
832
833 if (v60_write8) {
834 return v60_write8(a,d);
835 }
836 }
837
base_init()838 static void base_init()
839 {
840 memset(&v60, 0x00, sizeof(v60));
841 v60.irq_cb = v60_default_irq_cb;
842 v60.irq_line = CLEAR_LINE;
843 v60.nmi_line = CLEAR_LINE;
844
845 #if 0
846 state_save_register_item_array(type, index, v60.reg);
847 state_save_register_item(type, index, v60.irq_line);
848 state_save_register_item(type, index, v60.nmi_line);
849 state_save_register_item(type, index, v60.PPC);
850 state_save_register_item(type, index, _CY);
851 state_save_register_item(type, index, _OV);
852 state_save_register_item(type, index, _S);
853 state_save_register_item(type, index, _Z);
854 #endif
855 }
856
v60Init()857 void v60Init()
858 {
859 address_mask = 0xffffff;
860
861 for (INT32 i = 0; i < 3; i++) {
862 mem[i] = (UINT8**)BurnMalloc(((address_mask / page_size) + 1) * sizeof(UINT8**));
863 memset (mem[i], 0, ((address_mask / page_size) + 1) * sizeof(UINT8**));
864 }
865
866 base_init();
867 // Set PIR (Processor ID) for NEC v60. LSB is reserved to NEC,
868 // so I don't know what it contains.
869 PIR = 0x00006000;
870 v60.info = v60_i;
871
872 CpuCheatRegister(0, &v60Config);
873 }
874
v70Init()875 void v70Init()
876 {
877 address_mask = 0xffffffff;
878
879 for (INT32 i = 0; i < 3; i++) {
880 mem[i] = (UINT8**)BurnMalloc(0x200000 * sizeof(UINT8**));
881 memset (mem[i], 0, 0x200000 * sizeof(UINT8**));
882 }
883
884 base_init();
885 // Set PIR (Processor ID) for NEC v70. LSB is reserved to NEC,
886 // so I don't know what it contains.
887 PIR = 0x00007000;
888 v60.info = v70_i;
889 }
890
v60Scan(INT32 nAction)891 INT32 v60Scan(INT32 nAction)
892 {
893 struct BurnArea ba;
894
895 if ((nAction & ACB_DRIVER_DATA) == 0) {
896 return 1;
897 }
898
899 ba.Data = &v60.reg;
900 ba.nLen = sizeof(v60.reg);
901 ba.szName = "V60 Regs";
902 BurnAcb(&ba);
903
904 SCAN_VAR(v60.flags);
905 SCAN_VAR(v60.irq_line);
906 SCAN_VAR(v60.nmi_line);
907 SCAN_VAR(v60.PPC);
908 SCAN_VAR(v60.current_cycles);
909 SCAN_VAR(v60.cycles);
910
911 return 0;
912 }
913
v60SetIRQCallback(int (* callback)(int irqline))914 void v60SetIRQCallback(int (*callback)(int irqline))
915 {
916 v60.irq_cb = callback;
917 }
918
v60Reset()919 void v60Reset()
920 {
921 v60.current_cycles = 0;
922 PSW = 0x10000000;
923 PC = v60.info.start_pc;
924 SBR = 0x00000000;
925 SYCW = 0x00000070;
926 TKCW = 0x0000e000;
927 PSW2 = 0x0000f002;
928 ChangePC(PC);
929
930 _CY = 0;
931 _OV = 0;
932 _S = 0;
933 _Z = 0;
934 }
935
v60Open(int)936 void v60Open(int)
937 {
938
939 }
940
v60Close()941 void v60Close()
942 {
943
944 }
945
v60Exit()946 void v60Exit()
947 {
948 for (INT32 i = 0; i < 3; i++) {
949 BurnFree(mem[i]);
950 }
951 }
952
v60_stall(void)953 void v60_stall(void)
954 {
955 v60.stall_io = 1;
956 }
957
v60_do_irq(int vector)958 static void v60_do_irq(int vector)
959 {
960 UINT32 oldPSW = v60_update_psw_for_exception(1, 0);
961
962 // Push PC and PSW onto the stack
963 SP-=4;
964 MemWrite32(SP, oldPSW);
965 SP-=4;
966 MemWrite32(SP, PC);
967
968 // Jump to vector for user interrupt
969 PC = GETINTVECT(vector);
970 }
971
v60_try_irq(void)972 static void v60_try_irq(void)
973 {
974 if(v60.irq_line == CLEAR_LINE)
975 return;
976 if((PSW & (1<<18)) != 0) {
977 int vector;
978 if(v60.irq_line != ASSERT_LINE)
979 v60.irq_line = CLEAR_LINE;
980
981 vector = v60.irq_cb(0);
982
983 v60_do_irq(vector + 0x40);
984 } else if(v60.irq_line == PULSE_LINE)
985 v60.irq_line = CLEAR_LINE;
986 }
987
set_irq_line(int irqline,int state)988 static void set_irq_line(int irqline, int state)
989 {
990 if(irqline == INPUT_LINE_NMI) {
991 switch(state) {
992 case ASSERT_LINE:
993 if(v60.nmi_line == CLEAR_LINE) {
994 v60.nmi_line = ASSERT_LINE;
995 v60_do_irq(2);
996 }
997 break;
998 case CLEAR_LINE:
999 v60.nmi_line = CLEAR_LINE;
1000 break;
1001 case HOLD_LINE:
1002 case PULSE_LINE:
1003 v60.nmi_line = CLEAR_LINE;
1004 v60_do_irq(2);
1005 break;
1006 }
1007 } else {
1008 v60.irq_line = state;
1009 v60_try_irq();
1010 }
1011 }
1012
1013 // Actual cycles/instruction is unknown
1014
v60Run(int cycles)1015 INT32 v60Run(int cycles)
1016 {
1017 UINT32 inc;
1018
1019 v60.end_run = 0;
1020 v60.cycles = cycles;
1021 v60_ICount = cycles;
1022
1023 if(v60.irq_line != CLEAR_LINE)
1024 v60_try_irq();
1025
1026 do {
1027 v60.PPC = PC;
1028 // CALL_MAME_DEBUG;
1029 v60_ICount -= 8; /* fix me -- this is just an average */
1030 inc = OpCodeTable[OpRead8(PC)]();
1031 PC += inc;
1032 if(v60.irq_line != CLEAR_LINE)
1033 v60_try_irq();
1034 } while (v60_ICount > 0 && !v60.end_run);
1035
1036 cycles = cycles - v60_ICount;
1037
1038 v60.cycles = v60_ICount = 0;
1039
1040 v60.current_cycles += cycles;
1041
1042 return cycles;
1043 }
1044
v60SetIRQLine(INT32 irqline,INT32 state)1045 void v60SetIRQLine(INT32 irqline, INT32 state)
1046 {
1047 if (state == CPU_IRQSTATUS_AUTO) {
1048 bprintf(0, _T("v60SetIRQLine(): there is no _AUTO !\n"));
1049 }
1050 else
1051 {
1052 set_irq_line(irqline,state);
1053 }
1054 }
1055
v60TotalCycles()1056 INT32 v60TotalCycles()
1057 {
1058 return v60.current_cycles + (v60.cycles - v60_ICount);
1059 }
1060
v60RunEnd()1061 void v60RunEnd()
1062 {
1063 v60.end_run = 1;
1064 }
1065
v60Idle(INT32 cycles)1066 INT32 v60Idle(INT32 cycles)
1067 {
1068 v60.current_cycles += cycles;
1069
1070 return cycles;
1071 }
1072
v60NewFrame()1073 void v60NewFrame()
1074 {
1075 v60.current_cycles = 0;
1076 }
1077
v60GetPC(INT32)1078 UINT32 v60GetPC(INT32)
1079 {
1080 return v60.reg[32];
1081 }
1082
v60GetRegs(INT32 regs)1083 UINT32 v60GetRegs(INT32 regs)
1084 {
1085 return v60.reg[regs];
1086 }
1087
1088 #if 0
1089 static void v60_get_context(void *dst)
1090 {
1091 if(dst)
1092 *(struct v60info *)dst = v60;
1093 }
1094
1095 static void v60_set_context(void *src)
1096 {
1097 if(src)
1098 {
1099 v60 = *(struct v60info *)src;
1100 ChangePC(PC);
1101 }
1102 }
1103 #endif
1104
1105 #ifdef MAME_DEBUG
1106 offs_t v60_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
1107 offs_t v70_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
1108 #endif /* MAME_DEBUG */
1109
1110
1111 /**************************************************************************
1112 * Generic set_info
1113 **************************************************************************/
1114
1115 #if 0
1116 static void v60_set_info(UINT32 state, union cpuinfo *info)
1117 {
1118 switch (state)
1119 {
1120 /* --- the following bits of info are set as 64-bit signed integers --- */
1121 case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break;
1122 case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break;
1123
1124 case CPUINFO_INT_PC: PC = info->i; ChangePC(PC); break;
1125 case CPUINFO_INT_SP: SP = info->i; break;
1126
1127 case CPUINFO_INT_REGISTER + V60_R0: R0 = info->i; break;
1128 case CPUINFO_INT_REGISTER + V60_R1: R1 = info->i; break;
1129 case CPUINFO_INT_REGISTER + V60_R2: R2 = info->i; break;
1130 case CPUINFO_INT_REGISTER + V60_R3: R3 = info->i; break;
1131 case CPUINFO_INT_REGISTER + V60_R4: R4 = info->i; break;
1132 case CPUINFO_INT_REGISTER + V60_R5: R5 = info->i; break;
1133 case CPUINFO_INT_REGISTER + V60_R6: R6 = info->i; break;
1134 case CPUINFO_INT_REGISTER + V60_R7: R7 = info->i; break;
1135 case CPUINFO_INT_REGISTER + V60_R8: R8 = info->i; break;
1136 case CPUINFO_INT_REGISTER + V60_R9: R9 = info->i; break;
1137 case CPUINFO_INT_REGISTER + V60_R10: R10 = info->i; break;
1138 case CPUINFO_INT_REGISTER + V60_R11: R11 = info->i; break;
1139 case CPUINFO_INT_REGISTER + V60_R12: R12 = info->i; break;
1140 case CPUINFO_INT_REGISTER + V60_R13: R13 = info->i; break;
1141 case CPUINFO_INT_REGISTER + V60_R14: R14 = info->i; break;
1142 case CPUINFO_INT_REGISTER + V60_R15: R15 = info->i; break;
1143 case CPUINFO_INT_REGISTER + V60_R16: R16 = info->i; break;
1144 case CPUINFO_INT_REGISTER + V60_R17: R17 = info->i; break;
1145 case CPUINFO_INT_REGISTER + V60_R18: R18 = info->i; break;
1146 case CPUINFO_INT_REGISTER + V60_R19: R19 = info->i; break;
1147 case CPUINFO_INT_REGISTER + V60_R20: R20 = info->i; break;
1148 case CPUINFO_INT_REGISTER + V60_R21: R21 = info->i; break;
1149 case CPUINFO_INT_REGISTER + V60_R22: R22 = info->i; break;
1150 case CPUINFO_INT_REGISTER + V60_R23: R23 = info->i; break;
1151 case CPUINFO_INT_REGISTER + V60_R24: R24 = info->i; break;
1152 case CPUINFO_INT_REGISTER + V60_R25: R25 = info->i; break;
1153 case CPUINFO_INT_REGISTER + V60_R26: R26 = info->i; break;
1154 case CPUINFO_INT_REGISTER + V60_R27: R27 = info->i; break;
1155 case CPUINFO_INT_REGISTER + V60_R28: R28 = info->i; break;
1156 case CPUINFO_INT_REGISTER + V60_AP: AP = info->i; break;
1157 case CPUINFO_INT_REGISTER + V60_FP: FP = info->i; break;
1158 case CPUINFO_INT_REGISTER + V60_SP: SP = info->i; break;
1159 case CPUINFO_INT_REGISTER + V60_PC: PC = info->i; break;
1160 case CPUINFO_INT_REGISTER + V60_PSW: v60WritePSW(info->i); break;
1161 case CPUINFO_INT_REGISTER + V60_ISP: ISP = info->i; break;
1162 case CPUINFO_INT_REGISTER + V60_L0SP: L0SP = info->i; break;
1163 case CPUINFO_INT_REGISTER + V60_L1SP: L1SP = info->i; break;
1164 case CPUINFO_INT_REGISTER + V60_L2SP: L2SP = info->i; break;
1165 case CPUINFO_INT_REGISTER + V60_L3SP: L3SP = info->i; break;
1166 case CPUINFO_INT_REGISTER + V60_SBR: SBR = info->i; break;
1167 case CPUINFO_INT_REGISTER + V60_TR: TR = info->i; break;
1168 case CPUINFO_INT_REGISTER + V60_SYCW: SYCW = info->i; break;
1169 case CPUINFO_INT_REGISTER + V60_TKCW: TKCW = info->i; break;
1170 case CPUINFO_INT_REGISTER + V60_PIR: PIR = info->i; break;
1171 case CPUINFO_INT_REGISTER + V60_PSW2: PSW2 = info->i; break;
1172 case CPUINFO_INT_REGISTER + V60_ATBR0: ATBR0 = info->i; break;
1173 case CPUINFO_INT_REGISTER + V60_ATLR0: ATLR0 = info->i; break;
1174 case CPUINFO_INT_REGISTER + V60_ATBR1: ATBR1 = info->i; break;
1175 case CPUINFO_INT_REGISTER + V60_ATLR1: ATLR1 = info->i; break;
1176 case CPUINFO_INT_REGISTER + V60_ATBR2: ATBR2 = info->i; break;
1177 case CPUINFO_INT_REGISTER + V60_ATLR2: ATLR2 = info->i; break;
1178 case CPUINFO_INT_REGISTER + V60_ATBR3: ATBR3 = info->i; break;
1179 case CPUINFO_INT_REGISTER + V60_ATLR3: ATLR3 = info->i; break;
1180 case CPUINFO_INT_REGISTER + V60_TRMODE: TRMODE = info->i; break;
1181 case CPUINFO_INT_REGISTER + V60_ADTR0: ADTR0 = info->i; break;
1182 case CPUINFO_INT_REGISTER + V60_ADTR1: ADTR1 = info->i; break;
1183 case CPUINFO_INT_REGISTER + V60_ADTMR0: ADTMR0 = info->i; break;
1184 case CPUINFO_INT_REGISTER + V60_ADTMR1: ADTMR1 = info->i; break;
1185 }
1186 }
1187
1188
1189
1190 /**************************************************************************
1191 * Generic get_info
1192 **************************************************************************/
1193
1194 void v60_get_info(UINT32 state, union cpuinfo *info)
1195 {
1196 switch (state)
1197 {
1198 /* --- the following bits of info are returned as 64-bit signed integers --- */
1199 case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(v60); break;
1200 case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
1201 case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
1202 case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
1203 case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
1204 case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
1205 case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 22; break;
1206 case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
1207 case CPUINFO_INT_MAX_CYCLES: info->i = 1; break;
1208
1209 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
1210 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; break;
1211 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
1212 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
1213 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
1214 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
1215 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break;
1216 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 24; break;
1217 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
1218
1219 case CPUINFO_INT_INPUT_STATE + 0: info->i = v60.irq_line; break;
1220 case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = v60.nmi_line; break;
1221
1222 case CPUINFO_INT_PREVIOUSPC: info->i = v60.PPC; break;
1223
1224 case CPUINFO_INT_REGISTER + V60_R0: info->i = R0; break;
1225 case CPUINFO_INT_REGISTER + V60_R1: info->i = R1; break;
1226 case CPUINFO_INT_REGISTER + V60_R2: info->i = R2; break;
1227 case CPUINFO_INT_REGISTER + V60_R3: info->i = R3; break;
1228 case CPUINFO_INT_REGISTER + V60_R4: info->i = R4; break;
1229 case CPUINFO_INT_REGISTER + V60_R5: info->i = R5; break;
1230 case CPUINFO_INT_REGISTER + V60_R6: info->i = R6; break;
1231 case CPUINFO_INT_REGISTER + V60_R7: info->i = R7; break;
1232 case CPUINFO_INT_REGISTER + V60_R8: info->i = R8; break;
1233 case CPUINFO_INT_REGISTER + V60_R9: info->i = R9; break;
1234 case CPUINFO_INT_REGISTER + V60_R10: info->i = R10; break;
1235 case CPUINFO_INT_REGISTER + V60_R11: info->i = R11; break;
1236 case CPUINFO_INT_REGISTER + V60_R12: info->i = R12; break;
1237 case CPUINFO_INT_REGISTER + V60_R13: info->i = R13; break;
1238 case CPUINFO_INT_REGISTER + V60_R14: info->i = R14; break;
1239 case CPUINFO_INT_REGISTER + V60_R15: info->i = R15; break;
1240 case CPUINFO_INT_REGISTER + V60_R16: info->i = R16; break;
1241 case CPUINFO_INT_REGISTER + V60_R17: info->i = R17; break;
1242 case CPUINFO_INT_REGISTER + V60_R18: info->i = R18; break;
1243 case CPUINFO_INT_REGISTER + V60_R19: info->i = R19; break;
1244 case CPUINFO_INT_REGISTER + V60_R20: info->i = R20; break;
1245 case CPUINFO_INT_REGISTER + V60_R21: info->i = R21; break;
1246 case CPUINFO_INT_REGISTER + V60_R22: info->i = R22; break;
1247 case CPUINFO_INT_REGISTER + V60_R23: info->i = R23; break;
1248 case CPUINFO_INT_REGISTER + V60_R24: info->i = R24; break;
1249 case CPUINFO_INT_REGISTER + V60_R25: info->i = R25; break;
1250 case CPUINFO_INT_REGISTER + V60_R26: info->i = R26; break;
1251 case CPUINFO_INT_REGISTER + V60_R27: info->i = R27; break;
1252 case CPUINFO_INT_REGISTER + V60_R28: info->i = R28; break;
1253 case CPUINFO_INT_REGISTER + V60_AP: info->i = AP; break;
1254 case CPUINFO_INT_REGISTER + V60_FP: info->i = FP; break;
1255 case CPUINFO_INT_SP:
1256 case CPUINFO_INT_REGISTER + V60_SP: info->i = SP; break;
1257 case CPUINFO_INT_PC:
1258 case CPUINFO_INT_REGISTER + V60_PC: info->i = PC; break;
1259 case CPUINFO_INT_REGISTER + V60_PSW: info->i = v60ReadPSW(); break;
1260 case CPUINFO_INT_REGISTER + V60_ISP: info->i = ISP; break;
1261 case CPUINFO_INT_REGISTER + V60_L0SP: info->i = L0SP; break;
1262 case CPUINFO_INT_REGISTER + V60_L1SP: info->i = L1SP; break;
1263 case CPUINFO_INT_REGISTER + V60_L2SP: info->i = L2SP; break;
1264 case CPUINFO_INT_REGISTER + V60_L3SP: info->i = L3SP; break;
1265 case CPUINFO_INT_REGISTER + V60_SBR: info->i = SBR; break;
1266 case CPUINFO_INT_REGISTER + V60_TR: info->i = TR; break;
1267 case CPUINFO_INT_REGISTER + V60_SYCW: info->i = SYCW; break;
1268 case CPUINFO_INT_REGISTER + V60_TKCW: info->i = TKCW; break;
1269 case CPUINFO_INT_REGISTER + V60_PIR: info->i = PIR; break;
1270 case CPUINFO_INT_REGISTER + V60_PSW2: info->i = PSW2; break;
1271 case CPUINFO_INT_REGISTER + V60_ATBR0: info->i = ATBR0; break;
1272 case CPUINFO_INT_REGISTER + V60_ATLR0: info->i = ATLR0; break;
1273 case CPUINFO_INT_REGISTER + V60_ATBR1: info->i = ATBR1; break;
1274 case CPUINFO_INT_REGISTER + V60_ATLR1: info->i = ATLR1; break;
1275 case CPUINFO_INT_REGISTER + V60_ATBR2: info->i = ATBR2; break;
1276 case CPUINFO_INT_REGISTER + V60_ATLR2: info->i = ATLR2; break;
1277 case CPUINFO_INT_REGISTER + V60_ATBR3: info->i = ATBR3; break;
1278 case CPUINFO_INT_REGISTER + V60_ATLR3: info->i = ATLR3; break;
1279 case CPUINFO_INT_REGISTER + V60_TRMODE: info->i = TRMODE; break;
1280 case CPUINFO_INT_REGISTER + V60_ADTR0: info->i = ADTR0; break;
1281 case CPUINFO_INT_REGISTER + V60_ADTR1: info->i = ADTR1; break;
1282 case CPUINFO_INT_REGISTER + V60_ADTMR0: info->i = ADTMR0; break;
1283 case CPUINFO_INT_REGISTER + V60_ADTMR1: info->i = ADTMR1; break;
1284
1285 /* --- the following bits of info are returned as pointers to data or functions --- */
1286 case CPUINFO_PTR_SET_INFO: info->setinfo = v60_set_info; break;
1287 case CPUINFO_PTR_GET_CONTEXT: info->getcontext = v60_get_context; break;
1288 case CPUINFO_PTR_SET_CONTEXT: info->setcontext = v60_set_context; break;
1289 case CPUINFO_PTR_INIT: info->init = v60_init; break;
1290 case CPUINFO_PTR_RESET: info->reset = v60_reset; break;
1291 case CPUINFO_PTR_EXIT: info->exit = v60_exit; break;
1292 case CPUINFO_PTR_EXECUTE: info->execute = v60_execute; break;
1293 case CPUINFO_PTR_BURN: info->burn = NULL; break;
1294 #ifdef MAME_DEBUG
1295 case CPUINFO_PTR_DISASSEMBLE: info->disassemble = v60_dasm; break;
1296 #endif /* MAME_DEBUG */
1297 case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &v60_ICount; break;
1298
1299 /* --- the following bits of info are returned as NULL-terminated strings --- */
1300 case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "V60"); break;
1301 case CPUINFO_STR_CORE_FAMILY: strcpy(info->s = cpuintrf_temp_str(), "NEC V60"); break;
1302 case CPUINFO_STR_CORE_VERSION: strcpy(info->s = cpuintrf_temp_str(), "1.0"); break;
1303 case CPUINFO_STR_CORE_FILE: strcpy(info->s = cpuintrf_temp_str(), __FILE__); break;
1304 case CPUINFO_STR_CORE_CREDITS: strcpy(info->s = cpuintrf_temp_str(), "Farfetch'd and R.Belmont"); break;
1305
1306 case CPUINFO_STR_FLAGS: strcpy(info->s = cpuintrf_temp_str(), " "); break;
1307
1308 case CPUINFO_STR_REGISTER + V60_R0: sprintf(info->s = cpuintrf_temp_str(), "R0:%08X", R0); break;
1309 case CPUINFO_STR_REGISTER + V60_R1: sprintf(info->s = cpuintrf_temp_str(), "R1:%08X", R1); break;
1310 case CPUINFO_STR_REGISTER + V60_R2: sprintf(info->s = cpuintrf_temp_str(), "R2:%08X", R2); break;
1311 case CPUINFO_STR_REGISTER + V60_R3: sprintf(info->s = cpuintrf_temp_str(), "R3:%08X", R3); break;
1312 case CPUINFO_STR_REGISTER + V60_R4: sprintf(info->s = cpuintrf_temp_str(), "R4:%08X", R4); break;
1313 case CPUINFO_STR_REGISTER + V60_R5: sprintf(info->s = cpuintrf_temp_str(), "R5:%08X", R5); break;
1314 case CPUINFO_STR_REGISTER + V60_R6: sprintf(info->s = cpuintrf_temp_str(), "R6:%08X", R6); break;
1315 case CPUINFO_STR_REGISTER + V60_R7: sprintf(info->s = cpuintrf_temp_str(), "R7:%08X", R7); break;
1316 case CPUINFO_STR_REGISTER + V60_R8: sprintf(info->s = cpuintrf_temp_str(), "R8:%08X", R8); break;
1317 case CPUINFO_STR_REGISTER + V60_R9: sprintf(info->s = cpuintrf_temp_str(), "R9:%08X", R9); break;
1318 case CPUINFO_STR_REGISTER + V60_R10: sprintf(info->s = cpuintrf_temp_str(), "R10:%08X", R10); break;
1319 case CPUINFO_STR_REGISTER + V60_R11: sprintf(info->s = cpuintrf_temp_str(), "R11:%08X", R11); break;
1320 case CPUINFO_STR_REGISTER + V60_R12: sprintf(info->s = cpuintrf_temp_str(), "R12:%08X", R12); break;
1321 case CPUINFO_STR_REGISTER + V60_R13: sprintf(info->s = cpuintrf_temp_str(), "R13:%08X", R13); break;
1322 case CPUINFO_STR_REGISTER + V60_R14: sprintf(info->s = cpuintrf_temp_str(), "R14:%08X", R14); break;
1323 case CPUINFO_STR_REGISTER + V60_R15: sprintf(info->s = cpuintrf_temp_str(), "R15:%08X", R15); break;
1324 case CPUINFO_STR_REGISTER + V60_R16: sprintf(info->s = cpuintrf_temp_str(), "R16:%08X", R16); break;
1325 case CPUINFO_STR_REGISTER + V60_R17: sprintf(info->s = cpuintrf_temp_str(), "R17:%08X", R17); break;
1326 case CPUINFO_STR_REGISTER + V60_R18: sprintf(info->s = cpuintrf_temp_str(), "R18:%08X", R18); break;
1327 case CPUINFO_STR_REGISTER + V60_R19: sprintf(info->s = cpuintrf_temp_str(), "R19:%08X", R19); break;
1328 case CPUINFO_STR_REGISTER + V60_R20: sprintf(info->s = cpuintrf_temp_str(), "R20:%08X", R20); break;
1329 case CPUINFO_STR_REGISTER + V60_R21: sprintf(info->s = cpuintrf_temp_str(), "R21:%08X", R21); break;
1330 case CPUINFO_STR_REGISTER + V60_R22: sprintf(info->s = cpuintrf_temp_str(), "R22:%08X", R22); break;
1331 case CPUINFO_STR_REGISTER + V60_R23: sprintf(info->s = cpuintrf_temp_str(), "R23:%08X", R23); break;
1332 case CPUINFO_STR_REGISTER + V60_R24: sprintf(info->s = cpuintrf_temp_str(), "R24:%08X", R24); break;
1333 case CPUINFO_STR_REGISTER + V60_R25: sprintf(info->s = cpuintrf_temp_str(), "R25:%08X", R25); break;
1334 case CPUINFO_STR_REGISTER + V60_R26: sprintf(info->s = cpuintrf_temp_str(), "R26:%08X", R26); break;
1335 case CPUINFO_STR_REGISTER + V60_R27: sprintf(info->s = cpuintrf_temp_str(), "R27:%08X", R27); break;
1336 case CPUINFO_STR_REGISTER + V60_R28: sprintf(info->s = cpuintrf_temp_str(), "R28:%08X", R28); break;
1337 case CPUINFO_STR_REGISTER + V60_AP: sprintf(info->s = cpuintrf_temp_str(), "AP:%08X", AP); break;
1338 case CPUINFO_STR_REGISTER + V60_FP: sprintf(info->s = cpuintrf_temp_str(), "FP:%08X", FP); break;
1339 case CPUINFO_STR_REGISTER + V60_SP: sprintf(info->s = cpuintrf_temp_str(), "SP:%08X", SP); break;
1340 case CPUINFO_STR_REGISTER + V60_PC: sprintf(info->s = cpuintrf_temp_str(), "PC:%08X", PC); break;
1341 case CPUINFO_STR_REGISTER + V60_PSW: sprintf(info->s = cpuintrf_temp_str(), "PSW:%08X", v60ReadPSW()); break;
1342 case CPUINFO_STR_REGISTER + V60_ISP: sprintf(info->s = cpuintrf_temp_str(), "ISP:%08X", ISP); break;
1343 case CPUINFO_STR_REGISTER + V60_L0SP: sprintf(info->s = cpuintrf_temp_str(), "L0SP:%08X", L0SP); break;
1344 case CPUINFO_STR_REGISTER + V60_L1SP: sprintf(info->s = cpuintrf_temp_str(), "L1SP:%08X", L1SP); break;
1345 case CPUINFO_STR_REGISTER + V60_L2SP: sprintf(info->s = cpuintrf_temp_str(), "L2SP:%08X", L2SP); break;
1346 case CPUINFO_STR_REGISTER + V60_L3SP: sprintf(info->s = cpuintrf_temp_str(), "L3SP:%08X", L3SP); break;
1347 case CPUINFO_STR_REGISTER + V60_SBR: sprintf(info->s = cpuintrf_temp_str(), "SBR:%08X", SBR); break;
1348 case CPUINFO_STR_REGISTER + V60_TR: sprintf(info->s = cpuintrf_temp_str(), "TR:%08X", TR); break;
1349 case CPUINFO_STR_REGISTER + V60_SYCW: sprintf(info->s = cpuintrf_temp_str(), "SYCW:%08X", SYCW); break;
1350 case CPUINFO_STR_REGISTER + V60_TKCW: sprintf(info->s = cpuintrf_temp_str(), "TKCW:%08X", TKCW); break;
1351 case CPUINFO_STR_REGISTER + V60_PIR: sprintf(info->s = cpuintrf_temp_str(), "PIR:%08X", PIR); break;
1352 case CPUINFO_STR_REGISTER + V60_PSW2: sprintf(info->s = cpuintrf_temp_str(), "PSW2:%08X", PSW2); break;
1353 case CPUINFO_STR_REGISTER + V60_ATBR0: sprintf(info->s = cpuintrf_temp_str(), "ATBR0:%08X", ATBR0); break;
1354 case CPUINFO_STR_REGISTER + V60_ATLR0: sprintf(info->s = cpuintrf_temp_str(), "ATLR0:%08X", ATLR0); break;
1355 case CPUINFO_STR_REGISTER + V60_ATBR1: sprintf(info->s = cpuintrf_temp_str(), "ATBR1:%08X", ATBR1); break;
1356 case CPUINFO_STR_REGISTER + V60_ATLR1: sprintf(info->s = cpuintrf_temp_str(), "ATLR1:%08X", ATLR1); break;
1357 case CPUINFO_STR_REGISTER + V60_ATBR2: sprintf(info->s = cpuintrf_temp_str(), "ATBR2:%08X", ATBR2); break;
1358 case CPUINFO_STR_REGISTER + V60_ATLR2: sprintf(info->s = cpuintrf_temp_str(), "ATLR2:%08X", ATLR2); break;
1359 case CPUINFO_STR_REGISTER + V60_ATBR3: sprintf(info->s = cpuintrf_temp_str(), "ATBR3:%08X", ATBR3); break;
1360 case CPUINFO_STR_REGISTER + V60_ATLR3: sprintf(info->s = cpuintrf_temp_str(), "ATLR3:%08X", ATLR3); break;
1361 case CPUINFO_STR_REGISTER + V60_TRMODE: sprintf(info->s = cpuintrf_temp_str(), "TRMODE:%08X", TRMODE); break;
1362 case CPUINFO_STR_REGISTER + V60_ADTR0: sprintf(info->s = cpuintrf_temp_str(), "ADTR0:%08X", ADTR0); break;
1363 case CPUINFO_STR_REGISTER + V60_ADTR1: sprintf(info->s = cpuintrf_temp_str(), "ADTR1:%08X", ADTR1); break;
1364 case CPUINFO_STR_REGISTER + V60_ADTMR0: sprintf(info->s = cpuintrf_temp_str(), "ADTMR0:%08X", ADTMR0); break;
1365 case CPUINFO_STR_REGISTER + V60_ADTMR1: sprintf(info->s = cpuintrf_temp_str(), "ADTMR1:%08X", ADTMR1); break;
1366 }
1367 }
1368
1369
1370 /**************************************************************************
1371 * CPU-specific set_info
1372 **************************************************************************/
1373
1374 void v70_get_info(UINT32 state, union cpuinfo *info)
1375 {
1376 switch (state)
1377 {
1378 /* --- the following bits of info are returned as 64-bit signed integers --- */
1379 case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
1380 case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
1381 case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
1382
1383 /* --- the following bits of info are returned as pointers to data or functions --- */
1384 case CPUINFO_PTR_INIT: info->init = v70_init; break;
1385 #ifdef MAME_DEBUG
1386 case CPUINFO_PTR_DISASSEMBLE: info->disassemble = v70_dasm; break;
1387 #endif /* MAME_DEBUG */
1388
1389 /* --- the following bits of info are returned as NULL-terminated strings --- */
1390 case CPUINFO_STR_NAME: strcpy(info->s = cpuintrf_temp_str(), "V70"); break;
1391
1392 default:
1393 v60_get_info(state, info);
1394 break;
1395 }
1396 }
1397 #endif
1398