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