summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/v60/v60.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/cpu/v60/v60.c')
-rw-r--r--src/emu/cpu/v60/v60.c743
1 files changed, 743 insertions, 0 deletions
diff --git a/src/emu/cpu/v60/v60.c b/src/emu/cpu/v60/v60.c
new file mode 100644
index 00000000000..c405054e287
--- /dev/null
+++ b/src/emu/cpu/v60/v60.c
@@ -0,0 +1,743 @@
+// V60.C
+// Undiscover the beast!
+// Main hacking and coding by Farfetch'd
+// Portability fixes by Richter Belmont
+
+#include "debugger.h"
+#include "v60.h"
+
+// memory accessors
+#include "v60mem.c"
+
+
+// macros stolen from MAME for flags calc
+// note that these types are in x86 naming:
+// byte = 8 bit, word = 16 bit, long = 32 bit
+
+// parameter x = result, y = source 1, z = source 2
+
+#define SetOFL_Add(x,y,z) (_OV = (((x) ^ (y)) & ((x) ^ (z)) & 0x80000000) ? 1: 0)
+#define SetOFW_Add(x,y,z) (_OV = (((x) ^ (y)) & ((x) ^ (z)) & 0x8000) ? 1 : 0)
+#define SetOFB_Add(x,y,z) (_OV = (((x) ^ (y)) & ((x) ^ (z)) & 0x80) ? 1 : 0)
+
+#define SetOFL_Sub(x,y,z) (_OV = (((z) ^ (y)) & ((z) ^ (x)) & 0x80000000) ? 1 : 0)
+#define SetOFW_Sub(x,y,z) (_OV = (((z) ^ (y)) & ((z) ^ (x)) & 0x8000) ? 1 : 0)
+#define SetOFB_Sub(x,y,z) (_OV = (((z) ^ (y)) & ((z) ^ (x)) & 0x80) ? 1 : 0)
+
+#define SetCFB(x) {_CY = ((x) & 0x100) ? 1 : 0; }
+#define SetCFW(x) {_CY = ((x) & 0x10000) ? 1 : 0; }
+#define SetCFL(x) {_CY = ((x) & (((UINT64)1) << 32)) ? 1 : 0; }
+
+#define SetSF(x) (_S = (x))
+#define SetZF(x) (_Z = (x))
+
+#define SetSZPF_Byte(x) {_Z = ((UINT8)(x)==0); _S = ((x)&0x80) ? 1 : 0; }
+#define SetSZPF_Word(x) {_Z = ((UINT16)(x)==0); _S = ((x)&0x8000) ? 1 : 0; }
+#define SetSZPF_Long(x) {_Z = ((UINT32)(x)==0); _S = ((x)&0x80000000) ? 1 : 0; }
+
+#define ORB(dst,src) { (dst) |= (src); _CY = _OV = 0; SetSZPF_Byte(dst); }
+#define ORW(dst,src) { (dst) |= (src); _CY = _OV = 0; SetSZPF_Word(dst); }
+#define ORL(dst,src) { (dst) |= (src); _CY = _OV = 0; SetSZPF_Long(dst); }
+
+#define ANDB(dst,src) { (dst) &= (src); _CY = _OV = 0; SetSZPF_Byte(dst); }
+#define ANDW(dst,src) { (dst) &= (src); _CY = _OV = 0; SetSZPF_Word(dst); }
+#define ANDL(dst,src) { (dst) &= (src); _CY = _OV = 0; SetSZPF_Long(dst); }
+
+#define XORB(dst,src) { (dst) ^= (src); _CY = _OV = 0; SetSZPF_Byte(dst); }
+#define XORW(dst,src) { (dst) ^= (src); _CY = _OV = 0; SetSZPF_Word(dst); }
+#define XORL(dst,src) { (dst) ^= (src); _CY = _OV = 0; SetSZPF_Long(dst); }
+
+#define SUBB(dst, src) { unsigned res=(dst)-(src); SetCFB(res); SetOFB_Sub(res,src,dst); SetSZPF_Byte(res); dst=(UINT8)res; }
+#define SUBW(dst, src) { unsigned res=(dst)-(src); SetCFW(res); SetOFW_Sub(res,src,dst); SetSZPF_Word(res); dst=(UINT16)res; }
+#define SUBL(dst, src) { UINT64 res=(UINT64)(dst)-(INT64)(src); SetCFL(res); SetOFL_Sub(res,src,dst); SetSZPF_Long(res); dst=(UINT32)res; }
+
+#define ADDB(dst, src) { unsigned res=(dst)+(src); SetCFB(res); SetOFB_Add(res,src,dst); SetSZPF_Byte(res); dst=(UINT8)res; }
+#define ADDW(dst, src) { unsigned res=(dst)+(src); SetCFW(res); SetOFW_Add(res,src,dst); SetSZPF_Word(res); dst=(UINT16)res; }
+#define ADDL(dst, src) { UINT64 res=(UINT64)(dst)+(UINT64)(src); SetCFL(res); SetOFL_Add(res,src,dst); SetSZPF_Long(res); dst=(UINT32)res; }
+
+#define SETREG8(a, b) (a) = ((a) & ~0xff) | ((b) & 0xff)
+#define SETREG16(a, b) (a) = ((a) & ~0xffff) | ((b) & 0xffff)
+
+typedef struct
+{
+ UINT8 CY;
+ UINT8 OV;
+ UINT8 S;
+ UINT8 Z;
+} Flags;
+
+// v60 Register Inside (Hm... It's not a pentium inside :-))) )
+static struct v60info {
+ struct cpu_info info;
+ UINT32 reg[68];
+ Flags flags;
+ UINT8 irq_line;
+ UINT8 nmi_line;
+ int (*irq_cb)(int irqline);
+ UINT32 PPC;
+} v60;
+
+static int v60_ICount;
+static int v60_stall_io;
+
+/*
+ * Prevent warnings on NetBSD. All identifiers beginning with an underscore
+ * followed by an uppercase letter are reserved by the C standard (ISO/IEC
+ * 9899:1999, 7.1.3) to be used by the implementation. It'd be best to rename
+ * all such instances, but this is less intrusive and error-prone.
+ */
+#undef _S
+
+#define _CY v60.flags.CY
+#define _OV v60.flags.OV
+#define _S v60.flags.S
+#define _Z v60.flags.Z
+
+
+// Defines of all v60 register...
+#define R0 v60.reg[0]
+#define R1 v60.reg[1]
+#define R2 v60.reg[2]
+#define R3 v60.reg[3]
+#define R4 v60.reg[4]
+#define R5 v60.reg[5]
+#define R6 v60.reg[6]
+#define R7 v60.reg[7]
+#define R8 v60.reg[8]
+#define R9 v60.reg[9]
+#define R10 v60.reg[10]
+#define R11 v60.reg[11]
+#define R12 v60.reg[12]
+#define R13 v60.reg[13]
+#define R14 v60.reg[14]
+#define R15 v60.reg[15]
+#define R16 v60.reg[16]
+#define R17 v60.reg[17]
+#define R18 v60.reg[18]
+#define R19 v60.reg[19]
+#define R20 v60.reg[20]
+#define R21 v60.reg[21]
+#define R22 v60.reg[22]
+#define R23 v60.reg[23]
+#define R24 v60.reg[24]
+#define R25 v60.reg[25]
+#define R26 v60.reg[26]
+#define R27 v60.reg[27]
+#define R28 v60.reg[28]
+#define AP v60.reg[29]
+#define FP v60.reg[30]
+#define SP v60.reg[31]
+
+#define PC v60.reg[32]
+#define PSW v60.reg[33]
+
+// Privileged registers
+#define ISP v60.reg[36]
+#define L0SP v60.reg[37]
+#define L1SP v60.reg[38]
+#define L2SP v60.reg[39]
+#define L3SP v60.reg[40]
+#define SBR v60.reg[41]
+#define TR v60.reg[42]
+#define SYCW v60.reg[43]
+#define TKCW v60.reg[44]
+#define PIR v60.reg[45]
+//10-14 reserved
+#define PSW2 v60.reg[51]
+#define ATBR0 v60.reg[52]
+#define ATLR0 v60.reg[53]
+#define ATBR1 v60.reg[54]
+#define ATLR1 v60.reg[55]
+#define ATBR2 v60.reg[56]
+#define ATLR2 v60.reg[57]
+#define ATBR3 v60.reg[58]
+#define ATLR3 v60.reg[59]
+#define TRMODE v60.reg[60]
+#define ADTR0 v60.reg[61]
+#define ADTR1 v60.reg[62]
+#define ADTMR0 v60.reg[63]
+#define ADTMR1 v60.reg[64]
+//29-31 reserved
+
+// Register names
+const char *v60_reg_names[69] = {
+ "R0", "R1", "R2", "R3",
+ "R4", "R5", "R6", "R7",
+ "R8", "R9", "R10", "R11",
+ "R12", "R13", "R14", "R15",
+ "R16", "R17", "R18", "R19",
+ "R20", "R21", "R22", "R23",
+ "R24", "R25", "R26", "R27",
+ "R28", "AP", "FP", "SP",
+ "PC", "PSW","Unk","Unk",
+ "ISP", "L0SP", "L1SP", "L2SP",
+ "L3SP", "SBR","TR","SYCW",
+ "TKCW", "PIR", "Reserved","Reserved",
+ "Reserved","Reserved","Reserved","PSW2",
+ "ATBR0", "ATLR0", "ATBR1", "ATLR1",
+ "ATBR2", "ATLR2", "ATBR3", "ATLR3",
+ "TRMODE", "ADTR0", "ADTR1","ADTMR0",
+ "ADTMR1","Reserved","Reserved","Reserved"
+};
+
+// Defines...
+#define NORMALIZEFLAGS() \
+{ \
+ _S = _S ? 1 : 0; \
+ _OV = _OV ? 1 : 0; \
+ _Z = _Z ? 1 : 0; \
+ _CY = _CY ? 1 : 0; \
+}
+
+static void v60_try_irq(void);
+
+
+INLINE void v60SaveStack(void)
+{
+ if (PSW & 0x10000000)
+ ISP = SP;
+ else
+ v60.reg[37 + ((PSW >> 24) & 3)] = SP;
+}
+
+INLINE void v60ReloadStack(void)
+{
+ if (PSW & 0x10000000)
+ SP = ISP;
+ else
+ SP = v60.reg[37 + ((PSW >> 24) & 3)];
+}
+
+INLINE UINT32 v60ReadPSW(void)
+{
+ PSW &= 0xfffffff0;
+ PSW |= (_Z?1:0) | (_S?2:0) | (_OV?4:0) | (_CY?8:0);
+ return PSW;
+}
+
+INLINE void v60WritePSW(UINT32 newval)
+{
+ /* determine if we need to save/restore the stacks */
+ int updateStack = 0;
+
+ /* if the interrupt state is changing, we definitely need to update */
+ if ((newval ^ PSW) & 0x10000000)
+ updateStack = 1;
+
+ /* if we are not in interrupt mode and the level is changing, we also must update */
+ else if (!(PSW & 0x10000000) && ((newval ^ PSW) & 0x03000000))
+ updateStack = 1;
+
+ /* save the previous stack value */
+ if (updateStack)
+ v60SaveStack();
+
+ /* set the new value and update the flags */
+ PSW = newval;
+ _Z = (UINT8)(PSW & 1);
+ _S = (UINT8)(PSW & 2);
+ _OV = (UINT8)(PSW & 4);
+ _CY = (UINT8)(PSW & 8);
+
+ /* fetch the new stack value */
+ if (updateStack)
+ v60ReloadStack();
+}
+
+
+INLINE UINT32 v60_update_psw_for_exception(int is_interrupt, int target_level)
+{
+ UINT32 oldPSW = v60ReadPSW();
+ UINT32 newPSW = oldPSW;
+
+ // Change to interrupt context
+ newPSW &= ~(3 << 24); // PSW.EL = 0
+ newPSW |= target_level << 24; // set target level
+ newPSW &= ~(1 << 18); // PSW.IE = 0
+ newPSW &= ~(1 << 16); // PSW.TE = 0
+ newPSW &= ~(1 << 27); // PSW.TP = 0
+ newPSW &= ~(1 << 17); // PSW.AE = 0
+ newPSW &= ~(1 << 29); // PSW.EM = 0
+ if (is_interrupt)
+ newPSW |= (1 << 28);// PSW.IS = 1
+ newPSW |= (1 << 31); // PSW.ASA = 1
+ v60WritePSW(newPSW);
+
+ return oldPSW;
+}
+
+
+#define GETINTVECT(nint) MemRead32((SBR & ~0xfff) + (nint)*4)
+#define EXCEPTION_CODE_AND_SIZE(code, size) (((code) << 16) | (size))
+
+
+// Addressing mode decoding functions
+#include "am.c"
+
+// Opcode functions
+#include "op12.c"
+#include "op2.c"
+#include "op3.c"
+#include "op4.c"
+#include "op5.c"
+#include "op6.c"
+#include "op7a.c"
+
+static UINT32 opUNHANDLED(void)
+{
+ fatalerror("Unhandled OpCode found : %02x at %08x", OpRead16(PC), PC);
+ return 0; /* never reached, fatalerror won't return */
+}
+
+// Opcode jump table
+#include "optable.c"
+
+#ifdef UNUSED_FUNCTION
+static int v60_default_irq_cb(int irqline)
+{
+ return 0;
+}
+#endif
+
+static void base_init(const char *type, int index, int (*irqcallback)(int))
+{
+ v60_stall_io = 0;
+ v60.irq_cb = irqcallback;
+ v60.irq_line = CLEAR_LINE;
+ v60.nmi_line = CLEAR_LINE;
+
+ state_save_register_item_array(type, index, v60.reg);
+ state_save_register_item(type, index, v60.irq_line);
+ state_save_register_item(type, index, v60.nmi_line);
+ state_save_register_item(type, index, v60.PPC);
+ state_save_register_item(type, index, _CY);
+ state_save_register_item(type, index, _OV);
+ state_save_register_item(type, index, _S);
+ state_save_register_item(type, index, _Z);
+}
+
+static void v60_init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ base_init("v60", index, irqcallback);
+ // Set PIR (Processor ID) for NEC v60. LSB is reserved to NEC,
+ // so I don't know what it contains.
+ PIR = 0x00006000;
+ v60.info = v60_i;
+}
+
+static void v70_init(int index, int clock, const void *config, int (*irqcallback)(int))
+{
+ base_init("v70", index, irqcallback);
+ // Set PIR (Processor ID) for NEC v70. LSB is reserved to NEC,
+ // so I don't know what it contains.
+ PIR = 0x00007000;
+ v60.info = v70_i;
+}
+
+static void v60_reset(void)
+{
+ PSW = 0x10000000;
+ PC = v60.info.start_pc;
+ SBR = 0x00000000;
+ SYCW = 0x00000070;
+ TKCW = 0x0000e000;
+ PSW2 = 0x0000f002;
+ ChangePC(PC);
+
+ _CY = 0;
+ _OV = 0;
+ _S = 0;
+ _Z = 0;
+}
+
+static void v60_exit(void)
+{
+}
+
+void v60_stall(void)
+{
+ v60_stall_io = 1;
+}
+
+static void v60_do_irq(int vector)
+{
+ UINT32 oldPSW = v60_update_psw_for_exception(1, 0);
+
+ // Push PC and PSW onto the stack
+ SP-=4;
+ MemWrite32(SP, oldPSW);
+ SP-=4;
+ MemWrite32(SP, PC);
+
+ // Jump to vector for user interrupt
+ PC = GETINTVECT(vector);
+}
+
+static void v60_try_irq(void)
+{
+ if(v60.irq_line == CLEAR_LINE)
+ return;
+ if((PSW & (1<<18)) != 0) {
+ int vector;
+ if(v60.irq_line != ASSERT_LINE)
+ v60.irq_line = CLEAR_LINE;
+
+ vector = v60.irq_cb(0);
+
+ v60_do_irq(vector + 0x40);
+ } else if(v60.irq_line == PULSE_LINE)
+ v60.irq_line = CLEAR_LINE;
+}
+
+static void set_irq_line(int irqline, int state)
+{
+ if(irqline == INPUT_LINE_NMI) {
+ switch(state) {
+ case ASSERT_LINE:
+ if(v60.nmi_line == CLEAR_LINE) {
+ v60.nmi_line = ASSERT_LINE;
+ v60_do_irq(2);
+ }
+ break;
+ case CLEAR_LINE:
+ v60.nmi_line = CLEAR_LINE;
+ break;
+ case HOLD_LINE:
+ case PULSE_LINE:
+ v60.nmi_line = CLEAR_LINE;
+ v60_do_irq(2);
+ break;
+ }
+ } else {
+ v60.irq_line = state;
+ v60_try_irq();
+ }
+}
+
+// Actual cycles/instruction is unknown
+
+static int v60_execute(int cycles)
+{
+ UINT32 inc;
+
+ v60_ICount = cycles;
+ if(v60.irq_line != CLEAR_LINE)
+ v60_try_irq();
+ while(v60_ICount >= 0) {
+ v60.PPC = PC;
+ CALL_MAME_DEBUG;
+ v60_ICount -= 8; /* fix me -- this is just an average */
+ inc = OpCodeTable[OpRead8(PC)]();
+ PC += inc;
+ if(v60.irq_line != CLEAR_LINE)
+ v60_try_irq();
+ }
+
+ return cycles - v60_ICount;
+}
+
+static void v60_get_context(void *dst)
+{
+ if(dst)
+ *(struct v60info *)dst = v60;
+}
+
+static void v60_set_context(void *src)
+{
+ if(src)
+ {
+ v60 = *(struct v60info *)src;
+ ChangePC(PC);
+ }
+}
+
+
+#ifdef MAME_DEBUG
+offs_t v60_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
+offs_t v70_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram);
+#endif /* MAME_DEBUG */
+
+
+/**************************************************************************
+ * Generic set_info
+ **************************************************************************/
+
+static void v60_set_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are set as 64-bit signed integers --- */
+ case CPUINFO_INT_INPUT_STATE + 0: set_irq_line(0, info->i); break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: set_irq_line(INPUT_LINE_NMI, info->i); break;
+
+ case CPUINFO_INT_PC: PC = info->i; ChangePC(PC); break;
+ case CPUINFO_INT_SP: SP = info->i; break;
+
+ case CPUINFO_INT_REGISTER + V60_R0: R0 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R1: R1 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R2: R2 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R3: R3 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R4: R4 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R5: R5 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R6: R6 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R7: R7 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R8: R8 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R9: R9 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R10: R10 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R11: R11 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R12: R12 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R13: R13 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R14: R14 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R15: R15 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R16: R16 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R17: R17 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R18: R18 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R19: R19 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R20: R20 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R21: R21 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R22: R22 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R23: R23 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R24: R24 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R25: R25 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R26: R26 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R27: R27 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_R28: R28 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_AP: AP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_FP: FP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_SP: SP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_PC: PC = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_PSW: v60WritePSW(info->i); break;
+ case CPUINFO_INT_REGISTER + V60_ISP: ISP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_L0SP: L0SP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_L1SP: L1SP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_L2SP: L2SP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_L3SP: L3SP = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_SBR: SBR = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_TR: TR = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_SYCW: SYCW = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_TKCW: TKCW = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_PIR: PIR = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_PSW2: PSW2 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR0: ATBR0 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR0: ATLR0 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR1: ATBR1 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR1: ATLR1 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR2: ATBR2 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR2: ATLR2 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR3: ATBR3 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR3: ATLR3 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_TRMODE: TRMODE = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ADTR0: ADTR0 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ADTR1: ADTR1 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ADTMR0: ADTMR0 = info->i; break;
+ case CPUINFO_INT_REGISTER + V60_ADTMR1: ADTMR1 = info->i; break;
+ }
+}
+
+
+
+/**************************************************************************
+ * Generic get_info
+ **************************************************************************/
+
+void v60_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_CONTEXT_SIZE: info->i = sizeof(v60); break;
+ case CPUINFO_INT_INPUT_LINES: info->i = 1; break;
+ case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0; break;
+ case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break;
+ case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break;
+ case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 1; break;
+ case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 22; break;
+ case CPUINFO_INT_MIN_CYCLES: info->i = 1; break;
+ case CPUINFO_INT_MAX_CYCLES: info->i = 1; break;
+
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 16; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 24; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_DATA: info->i = 0; break;
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_IO: info->i = 16; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_IO: info->i = 24; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_IO: info->i = 0; break;
+
+ case CPUINFO_INT_INPUT_STATE + 0: info->i = v60.irq_line; break;
+ case CPUINFO_INT_INPUT_STATE + INPUT_LINE_NMI: info->i = v60.nmi_line; break;
+
+ case CPUINFO_INT_PREVIOUSPC: info->i = v60.PPC; break;
+
+ case CPUINFO_INT_REGISTER + V60_R0: info->i = R0; break;
+ case CPUINFO_INT_REGISTER + V60_R1: info->i = R1; break;
+ case CPUINFO_INT_REGISTER + V60_R2: info->i = R2; break;
+ case CPUINFO_INT_REGISTER + V60_R3: info->i = R3; break;
+ case CPUINFO_INT_REGISTER + V60_R4: info->i = R4; break;
+ case CPUINFO_INT_REGISTER + V60_R5: info->i = R5; break;
+ case CPUINFO_INT_REGISTER + V60_R6: info->i = R6; break;
+ case CPUINFO_INT_REGISTER + V60_R7: info->i = R7; break;
+ case CPUINFO_INT_REGISTER + V60_R8: info->i = R8; break;
+ case CPUINFO_INT_REGISTER + V60_R9: info->i = R9; break;
+ case CPUINFO_INT_REGISTER + V60_R10: info->i = R10; break;
+ case CPUINFO_INT_REGISTER + V60_R11: info->i = R11; break;
+ case CPUINFO_INT_REGISTER + V60_R12: info->i = R12; break;
+ case CPUINFO_INT_REGISTER + V60_R13: info->i = R13; break;
+ case CPUINFO_INT_REGISTER + V60_R14: info->i = R14; break;
+ case CPUINFO_INT_REGISTER + V60_R15: info->i = R15; break;
+ case CPUINFO_INT_REGISTER + V60_R16: info->i = R16; break;
+ case CPUINFO_INT_REGISTER + V60_R17: info->i = R17; break;
+ case CPUINFO_INT_REGISTER + V60_R18: info->i = R18; break;
+ case CPUINFO_INT_REGISTER + V60_R19: info->i = R19; break;
+ case CPUINFO_INT_REGISTER + V60_R20: info->i = R20; break;
+ case CPUINFO_INT_REGISTER + V60_R21: info->i = R21; break;
+ case CPUINFO_INT_REGISTER + V60_R22: info->i = R22; break;
+ case CPUINFO_INT_REGISTER + V60_R23: info->i = R23; break;
+ case CPUINFO_INT_REGISTER + V60_R24: info->i = R24; break;
+ case CPUINFO_INT_REGISTER + V60_R25: info->i = R25; break;
+ case CPUINFO_INT_REGISTER + V60_R26: info->i = R26; break;
+ case CPUINFO_INT_REGISTER + V60_R27: info->i = R27; break;
+ case CPUINFO_INT_REGISTER + V60_R28: info->i = R28; break;
+ case CPUINFO_INT_REGISTER + V60_AP: info->i = AP; break;
+ case CPUINFO_INT_REGISTER + V60_FP: info->i = FP; break;
+ case CPUINFO_INT_SP:
+ case CPUINFO_INT_REGISTER + V60_SP: info->i = SP; break;
+ case CPUINFO_INT_PC:
+ case CPUINFO_INT_REGISTER + V60_PC: info->i = PC; break;
+ case CPUINFO_INT_REGISTER + V60_PSW: info->i = v60ReadPSW(); break;
+ case CPUINFO_INT_REGISTER + V60_ISP: info->i = ISP; break;
+ case CPUINFO_INT_REGISTER + V60_L0SP: info->i = L0SP; break;
+ case CPUINFO_INT_REGISTER + V60_L1SP: info->i = L1SP; break;
+ case CPUINFO_INT_REGISTER + V60_L2SP: info->i = L2SP; break;
+ case CPUINFO_INT_REGISTER + V60_L3SP: info->i = L3SP; break;
+ case CPUINFO_INT_REGISTER + V60_SBR: info->i = SBR; break;
+ case CPUINFO_INT_REGISTER + V60_TR: info->i = TR; break;
+ case CPUINFO_INT_REGISTER + V60_SYCW: info->i = SYCW; break;
+ case CPUINFO_INT_REGISTER + V60_TKCW: info->i = TKCW; break;
+ case CPUINFO_INT_REGISTER + V60_PIR: info->i = PIR; break;
+ case CPUINFO_INT_REGISTER + V60_PSW2: info->i = PSW2; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR0: info->i = ATBR0; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR0: info->i = ATLR0; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR1: info->i = ATBR1; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR1: info->i = ATLR1; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR2: info->i = ATBR2; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR2: info->i = ATLR2; break;
+ case CPUINFO_INT_REGISTER + V60_ATBR3: info->i = ATBR3; break;
+ case CPUINFO_INT_REGISTER + V60_ATLR3: info->i = ATLR3; break;
+ case CPUINFO_INT_REGISTER + V60_TRMODE: info->i = TRMODE; break;
+ case CPUINFO_INT_REGISTER + V60_ADTR0: info->i = ADTR0; break;
+ case CPUINFO_INT_REGISTER + V60_ADTR1: info->i = ADTR1; break;
+ case CPUINFO_INT_REGISTER + V60_ADTMR0: info->i = ADTMR0; break;
+ case CPUINFO_INT_REGISTER + V60_ADTMR1: info->i = ADTMR1; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_SET_INFO: info->setinfo = v60_set_info; break;
+ case CPUINFO_PTR_GET_CONTEXT: info->getcontext = v60_get_context; break;
+ case CPUINFO_PTR_SET_CONTEXT: info->setcontext = v60_set_context; break;
+ case CPUINFO_PTR_INIT: info->init = v60_init; break;
+ case CPUINFO_PTR_RESET: info->reset = v60_reset; break;
+ case CPUINFO_PTR_EXIT: info->exit = v60_exit; break;
+ case CPUINFO_PTR_EXECUTE: info->execute = v60_execute; break;
+ case CPUINFO_PTR_BURN: info->burn = NULL; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = v60_dasm; break;
+#endif /* MAME_DEBUG */
+ case CPUINFO_PTR_INSTRUCTION_COUNTER: info->icount = &v60_ICount; break;
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "V60"); break;
+ case CPUINFO_STR_CORE_FAMILY: strcpy(info->s, "NEC V60"); break;
+ case CPUINFO_STR_CORE_VERSION: strcpy(info->s, "1.0"); break;
+ case CPUINFO_STR_CORE_FILE: strcpy(info->s, __FILE__); break;
+ case CPUINFO_STR_CORE_CREDITS: strcpy(info->s, "Farfetch'd and R.Belmont"); break;
+
+ case CPUINFO_STR_FLAGS: strcpy(info->s, " "); break;
+
+ case CPUINFO_STR_REGISTER + V60_R0: sprintf(info->s, "R0:%08X", R0); break;
+ case CPUINFO_STR_REGISTER + V60_R1: sprintf(info->s, "R1:%08X", R1); break;
+ case CPUINFO_STR_REGISTER + V60_R2: sprintf(info->s, "R2:%08X", R2); break;
+ case CPUINFO_STR_REGISTER + V60_R3: sprintf(info->s, "R3:%08X", R3); break;
+ case CPUINFO_STR_REGISTER + V60_R4: sprintf(info->s, "R4:%08X", R4); break;
+ case CPUINFO_STR_REGISTER + V60_R5: sprintf(info->s, "R5:%08X", R5); break;
+ case CPUINFO_STR_REGISTER + V60_R6: sprintf(info->s, "R6:%08X", R6); break;
+ case CPUINFO_STR_REGISTER + V60_R7: sprintf(info->s, "R7:%08X", R7); break;
+ case CPUINFO_STR_REGISTER + V60_R8: sprintf(info->s, "R8:%08X", R8); break;
+ case CPUINFO_STR_REGISTER + V60_R9: sprintf(info->s, "R9:%08X", R9); break;
+ case CPUINFO_STR_REGISTER + V60_R10: sprintf(info->s, "R10:%08X", R10); break;
+ case CPUINFO_STR_REGISTER + V60_R11: sprintf(info->s, "R11:%08X", R11); break;
+ case CPUINFO_STR_REGISTER + V60_R12: sprintf(info->s, "R12:%08X", R12); break;
+ case CPUINFO_STR_REGISTER + V60_R13: sprintf(info->s, "R13:%08X", R13); break;
+ case CPUINFO_STR_REGISTER + V60_R14: sprintf(info->s, "R14:%08X", R14); break;
+ case CPUINFO_STR_REGISTER + V60_R15: sprintf(info->s, "R15:%08X", R15); break;
+ case CPUINFO_STR_REGISTER + V60_R16: sprintf(info->s, "R16:%08X", R16); break;
+ case CPUINFO_STR_REGISTER + V60_R17: sprintf(info->s, "R17:%08X", R17); break;
+ case CPUINFO_STR_REGISTER + V60_R18: sprintf(info->s, "R18:%08X", R18); break;
+ case CPUINFO_STR_REGISTER + V60_R19: sprintf(info->s, "R19:%08X", R19); break;
+ case CPUINFO_STR_REGISTER + V60_R20: sprintf(info->s, "R20:%08X", R20); break;
+ case CPUINFO_STR_REGISTER + V60_R21: sprintf(info->s, "R21:%08X", R21); break;
+ case CPUINFO_STR_REGISTER + V60_R22: sprintf(info->s, "R22:%08X", R22); break;
+ case CPUINFO_STR_REGISTER + V60_R23: sprintf(info->s, "R23:%08X", R23); break;
+ case CPUINFO_STR_REGISTER + V60_R24: sprintf(info->s, "R24:%08X", R24); break;
+ case CPUINFO_STR_REGISTER + V60_R25: sprintf(info->s, "R25:%08X", R25); break;
+ case CPUINFO_STR_REGISTER + V60_R26: sprintf(info->s, "R26:%08X", R26); break;
+ case CPUINFO_STR_REGISTER + V60_R27: sprintf(info->s, "R27:%08X", R27); break;
+ case CPUINFO_STR_REGISTER + V60_R28: sprintf(info->s, "R28:%08X", R28); break;
+ case CPUINFO_STR_REGISTER + V60_AP: sprintf(info->s, "AP:%08X", AP); break;
+ case CPUINFO_STR_REGISTER + V60_FP: sprintf(info->s, "FP:%08X", FP); break;
+ case CPUINFO_STR_REGISTER + V60_SP: sprintf(info->s, "SP:%08X", SP); break;
+ case CPUINFO_STR_REGISTER + V60_PC: sprintf(info->s, "PC:%08X", PC); break;
+ case CPUINFO_STR_REGISTER + V60_PSW: sprintf(info->s, "PSW:%08X", v60ReadPSW()); break;
+ case CPUINFO_STR_REGISTER + V60_ISP: sprintf(info->s, "ISP:%08X", ISP); break;
+ case CPUINFO_STR_REGISTER + V60_L0SP: sprintf(info->s, "L0SP:%08X", L0SP); break;
+ case CPUINFO_STR_REGISTER + V60_L1SP: sprintf(info->s, "L1SP:%08X", L1SP); break;
+ case CPUINFO_STR_REGISTER + V60_L2SP: sprintf(info->s, "L2SP:%08X", L2SP); break;
+ case CPUINFO_STR_REGISTER + V60_L3SP: sprintf(info->s, "L3SP:%08X", L3SP); break;
+ case CPUINFO_STR_REGISTER + V60_SBR: sprintf(info->s, "SBR:%08X", SBR); break;
+ case CPUINFO_STR_REGISTER + V60_TR: sprintf(info->s, "TR:%08X", TR); break;
+ case CPUINFO_STR_REGISTER + V60_SYCW: sprintf(info->s, "SYCW:%08X", SYCW); break;
+ case CPUINFO_STR_REGISTER + V60_TKCW: sprintf(info->s, "TKCW:%08X", TKCW); break;
+ case CPUINFO_STR_REGISTER + V60_PIR: sprintf(info->s, "PIR:%08X", PIR); break;
+ case CPUINFO_STR_REGISTER + V60_PSW2: sprintf(info->s, "PSW2:%08X", PSW2); break;
+ case CPUINFO_STR_REGISTER + V60_ATBR0: sprintf(info->s, "ATBR0:%08X", ATBR0); break;
+ case CPUINFO_STR_REGISTER + V60_ATLR0: sprintf(info->s, "ATLR0:%08X", ATLR0); break;
+ case CPUINFO_STR_REGISTER + V60_ATBR1: sprintf(info->s, "ATBR1:%08X", ATBR1); break;
+ case CPUINFO_STR_REGISTER + V60_ATLR1: sprintf(info->s, "ATLR1:%08X", ATLR1); break;
+ case CPUINFO_STR_REGISTER + V60_ATBR2: sprintf(info->s, "ATBR2:%08X", ATBR2); break;
+ case CPUINFO_STR_REGISTER + V60_ATLR2: sprintf(info->s, "ATLR2:%08X", ATLR2); break;
+ case CPUINFO_STR_REGISTER + V60_ATBR3: sprintf(info->s, "ATBR3:%08X", ATBR3); break;
+ case CPUINFO_STR_REGISTER + V60_ATLR3: sprintf(info->s, "ATLR3:%08X", ATLR3); break;
+ case CPUINFO_STR_REGISTER + V60_TRMODE: sprintf(info->s, "TRMODE:%08X", TRMODE); break;
+ case CPUINFO_STR_REGISTER + V60_ADTR0: sprintf(info->s, "ADTR0:%08X", ADTR0); break;
+ case CPUINFO_STR_REGISTER + V60_ADTR1: sprintf(info->s, "ADTR1:%08X", ADTR1); break;
+ case CPUINFO_STR_REGISTER + V60_ADTMR0: sprintf(info->s, "ADTMR0:%08X", ADTMR0); break;
+ case CPUINFO_STR_REGISTER + V60_ADTMR1: sprintf(info->s, "ADTMR1:%08X", ADTMR1); break;
+ }
+}
+
+
+/**************************************************************************
+ * CPU-specific set_info
+ **************************************************************************/
+
+void v70_get_info(UINT32 state, cpuinfo *info)
+{
+ switch (state)
+ {
+ /* --- the following bits of info are returned as 64-bit signed integers --- */
+ case CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACE_PROGRAM: info->i = 32; break;
+ case CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACE_PROGRAM: info->i = 0; break;
+
+ /* --- the following bits of info are returned as pointers to data or functions --- */
+ case CPUINFO_PTR_INIT: info->init = v70_init; break;
+#ifdef MAME_DEBUG
+ case CPUINFO_PTR_DISASSEMBLE: info->disassemble = v70_dasm; break;
+#endif /* MAME_DEBUG */
+
+ /* --- the following bits of info are returned as NULL-terminated strings --- */
+ case CPUINFO_STR_NAME: strcpy(info->s, "V70"); break;
+
+ default: v60_get_info(state, info); break;
+ }
+}