summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/nec/v25priv.h
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/nec/v25priv.h')
-rw-r--r--trunk/src/emu/cpu/nec/v25priv.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/nec/v25priv.h b/trunk/src/emu/cpu/nec/v25priv.h
new file mode 100644
index 00000000000..87ced6cdb2e
--- /dev/null
+++ b/trunk/src/emu/cpu/nec/v25priv.h
@@ -0,0 +1,258 @@
+/* Cpu types, steps of 8 to help the cycle count calculation */
+#define V33_TYPE 0
+#define V30_TYPE 8
+#define V20_TYPE 16
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE 1
+#endif
+
+/* interrupt vectors */
+enum
+{
+ NEC_DIVIDE_VECTOR = 0,
+ NEC_TRAP_VECTOR = 1,
+ NEC_NMI_VECTOR = 2,
+ NEC_BRKV_VECTOR = 4,
+ NEC_CHKIND_VECTOR = 5,
+ NEC_IBRK_VECTOR = 19,
+ NEC_INTTU0_VECTOR = 28,
+ NEC_INTTU1_VECTOR = 29,
+ NEC_INTTU2_VECTOR = 30,
+ NEC_INTD0_VECTOR = 20,
+ NEC_INTD1_VECTOR = 21,
+ NEC_INTP0_VECTOR = 24,
+ NEC_INTP1_VECTOR = 25,
+ NEC_INTP2_VECTOR = 26,
+ NEC_INTSER0_VECTOR = 12,
+ NEC_INTSR0_VECTOR = 13,
+ NEC_INTST0_VECTOR = 14,
+ NEC_INTSER1_VECTOR = 16,
+ NEC_INTSR1_VECTOR = 17,
+ NEC_INTST1_VECTOR = 18,
+ NEC_INTTB_VECTOR = 31
+};
+
+/* interrupt sources */
+typedef enum
+{
+ BRK = 0,
+ INT_IRQ = 1,
+ NMI_IRQ = 1 << 1,
+ INTTU0 = 1 << 2,
+ INTTU1 = 1 << 3,
+ INTTU2 = 1 << 4,
+ INTD0 = 1 << 5,
+ INTD1 = 1 << 6,
+ INTP0 = 1 << 7,
+ INTP1 = 1 << 8,
+ INTP2 = 1 << 9,
+ INTSER0 = 1 << 10,
+ INTSR0 = 1 << 11,
+ INTST0 = 1 << 12,
+ INTSER1 = 1 << 13,
+ INTSR1 = 1 << 14,
+ INTST1 = 1 << 15,
+ INTTB = 1 << 16,
+ BRKN = 1 << 17,
+ BRKS = 1 << 18
+} INTSOURCES;
+
+/* internal RAM and register banks */
+typedef union
+{
+ UINT16 w[128];
+ UINT8 b[256];
+} internalram;
+
+typedef struct _v25_state_t v25_state_t;
+struct _v25_state_t
+{
+ internalram ram;
+ offs_t fetch_xor;
+
+ UINT16 ip;
+
+ /* PSW flags */
+ INT32 SignVal;
+ UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
+ UINT8 IBRK, F0, F1, TF, IF, DF, MF; /* 0 or 1 valued flags */
+ UINT8 RBW, RBB; /* current register bank base, preshifted for word and byte registers */
+
+ /* interrupt related */
+ UINT32 pending_irq;
+ UINT32 unmasked_irq;
+ UINT32 bankswitch_irq;
+ UINT8 priority_inttu, priority_intd, priority_intp, priority_ints0, priority_ints1;
+ UINT8 IRQS, ISPR;
+ UINT32 nmi_state;
+ UINT32 irq_state;
+ UINT32 poll_state;
+ UINT32 mode_state;
+ UINT32 intp_state[3];
+ UINT8 no_interrupt;
+ UINT8 halted;
+
+ /* timer related */
+ UINT16 TM0, MD0, TM1, MD1;
+ UINT8 TMC0, TMC1;
+ emu_timer *timers[4];
+
+ /* system control */
+ UINT8 RAMEN, TB, PCK; /* PRC register */
+ UINT32 IDB;
+
+ device_irq_callback irq_callback;
+ legacy_cpu_device *device;
+ address_space *program;
+ direct_read_data *direct;
+ address_space *io;
+ int icount;
+
+ const nec_config *config;
+
+ UINT8 prefetch_size;
+ UINT8 prefetch_cycles;
+ INT8 prefetch_count;
+ UINT8 prefetch_reset;
+ UINT32 chip_type;
+
+ UINT32 prefix_base; /* base address of the latest prefix segment */
+ UINT8 seg_prefix; /* prefix segment indicator */
+};
+
+enum {
+ VECTOR_PC = 0x02/2,
+ PSW_SAVE = 0x04/2,
+ PC_SAVE = 0x06/2
+};
+
+typedef enum {
+ DS1 = 0x0E/2,
+ PS = 0x0C/2,
+ SS = 0x0A/2,
+ DS0 = 0x08/2
+} SREGS;
+
+typedef enum {
+ AW = 0x1E/2,
+ CW = 0x1C/2,
+ DW = 0x1A/2,
+ BW = 0x18/2,
+ SP = 0x16/2,
+ BP = 0x14/2,
+ IX = 0x12/2,
+ IY = 0x10/2
+} WREGS;
+
+typedef enum {
+ AL = NATIVE_ENDIAN_VALUE_LE_BE(0x1E, 0x1F),
+ AH = NATIVE_ENDIAN_VALUE_LE_BE(0x1F, 0x1E),
+ CL = NATIVE_ENDIAN_VALUE_LE_BE(0x1C, 0x1D),
+ CH = NATIVE_ENDIAN_VALUE_LE_BE(0x1D, 0x1C),
+ DL = NATIVE_ENDIAN_VALUE_LE_BE(0x1A, 0x1B),
+ DH = NATIVE_ENDIAN_VALUE_LE_BE(0x1B, 0x1A),
+ BL = NATIVE_ENDIAN_VALUE_LE_BE(0x18, 0x19),
+ BH = NATIVE_ENDIAN_VALUE_LE_BE(0x19, 0x18)
+} BREGS;
+
+#define SetRB(x) do { nec_state->RBW = (x) << 4; nec_state->RBB = (x) << 5; } while (0)
+
+#define Sreg(x) nec_state->ram.w[nec_state->RBW + (x)]
+#define Wreg(x) nec_state->ram.w[nec_state->RBW + (x)]
+#define Breg(x) nec_state->ram.b[nec_state->RBB + (x)]
+
+#define PC(n) ((Sreg(PS)<<4)+(n)->ip)
+
+#define CF (nec_state->CarryVal!=0)
+#define SF (nec_state->SignVal<0)
+#define ZF (nec_state->ZeroVal==0)
+#define PF parity_table[(BYTE)nec_state->ParityVal]
+#define AF (nec_state->AuxVal!=0)
+#define OF (nec_state->OverVal!=0)
+#define RB (nec_state->RBW >> 4)
+
+/************************************************************************/
+
+UINT8 v25_read_byte(v25_state_t *nec_state, unsigned a);
+UINT16 v25_read_word(v25_state_t *nec_state, unsigned a);
+void v25_write_byte(v25_state_t *nec_state, unsigned a, UINT8 d);
+void v25_write_word(v25_state_t *nec_state, unsigned a, UINT16 d);
+
+#define read_mem_byte(a) v25_read_byte(nec_state,(a))
+#define read_mem_word(a) v25_read_word(nec_state,(a))
+#define write_mem_byte(a,d) v25_write_byte(nec_state,(a),(d))
+#define write_mem_word(a,d) v25_write_word(nec_state,(a),(d))
+
+#define read_port_byte(a) nec_state->io->read_byte(a)
+#define read_port_word(a) nec_state->io->read_word_unaligned(a)
+#define write_port_byte(a,d) nec_state->io->write_byte((a),(d))
+#define write_port_word(a,d) nec_state->io->write_word_unaligned((a),(d))
+
+/************************************************************************/
+
+#define CHANGE_PC do { EMPTY_PREFETCH(); } while (0)
+
+#define SegBase(Seg) (Sreg(Seg) << 4)
+
+#define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS)) ? nec_state->prefix_base : Sreg(Seg) << 4)
+
+#define GetMemB(Seg,Off) (read_mem_byte(DefaultBase(Seg) + (Off)))
+#define GetMemW(Seg,Off) (read_mem_word(DefaultBase(Seg) + (Off)))
+
+#define PutMemB(Seg,Off,x) { write_mem_byte(DefaultBase(Seg) + (Off), (x)); }
+#define PutMemW(Seg,Off,x) { write_mem_word(DefaultBase(Seg) + (Off), (x)); }
+
+/* prefetch timing */
+
+#define FETCH() fetch(nec_state)
+#define FETCHWORD() fetchword(nec_state)
+#define EMPTY_PREFETCH() nec_state->prefetch_reset = 1
+
+
+#define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS)<<4)+Wreg(SP)), val); }
+#define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS)<<4) + ((Wreg(SP)-2) & 0xffff))); }
+
+#define GetModRM UINT32 ModRM=FETCH()
+
+/* Cycle count macros:
+ CLK - cycle count is the same on all processors
+ CLKS - cycle count differs between processors, list all counts
+ CLKW - cycle count for word read/write differs for odd/even source/destination address
+ CLKM - cycle count for reg/mem instructions
+ CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses
+
+
+ Prefetch & buswait time is not emulated.
+ Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated.
+*/
+
+#define CLK(all) nec_state->icount-=all
+#define CLKS(v20,v30,v33) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33; nec_state->icount-=(ccount>>nec_state->chip_type)&0x7f; }
+#define CLKW(v20o,v30o,v33o,v20e,v30e,v33e,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
+#define CLKM(v20,v30,v33,v20m,v30m,v33m) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33, mcount=(v20m<<16)|(v30m<<8)|v33m; nec_state->icount-=( ModRM >=0xc0 )?((ccount>>nec_state->chip_type)&0x7f):((mcount>>nec_state->chip_type)&0x7f); }
+#define CLKR(v20o,v30o,v33o,v20e,v30e,v33e,vall,addr) { const UINT32 ocount=(v20o<<16)|(v30o<<8)|v33o, ecount=(v20e<<16)|(v30e<<8)|v33e; if (ModRM >=0xc0) nec_state->icount-=vall; else nec_state->icount-=(addr&1)?((ocount>>nec_state->chip_type)&0x7f):((ecount>>nec_state->chip_type)&0x7f); }
+
+/************************************************************************/
+#define CompressFlags() (WORD)(CF | (nec_state->IBRK << 1) | (PF << 2) | (nec_state->F0 << 3) | (AF << 4) \
+ | (nec_state->F1 << 5) | (ZF << 6) | (SF << 7) | (nec_state->TF << 8) | (nec_state->IF << 9) \
+ | (nec_state->DF << 10) | (OF << 11) | (RB << 12) | (nec_state->MF << 15))
+
+#define ExpandFlags(f) \
+{ \
+ nec_state->CarryVal = (f) & 0x0001; \
+ nec_state->IBRK = ((f) & 0x0002) == 0x0002; \
+ nec_state->ParityVal = !((f) & 0x0004); \
+ nec_state->F0 = ((f) & 0x0008) == 0x0008; \
+ nec_state->AuxVal = (f) & 0x0010; \
+ nec_state->F1 = ((f) & 0x0020) == 0x0020; \
+ nec_state->ZeroVal = !((f) & 0x0040); \
+ nec_state->SignVal = (f) & 0x0080 ? -1 : 0; \
+ nec_state->TF = ((f) & 0x0100) == 0x0100; \
+ nec_state->IF = ((f) & 0x0200) == 0x0200; \
+ nec_state->DF = ((f) & 0x0400) == 0x0400; \
+ nec_state->OverVal = (f) & 0x0800; \
+ /* RB only changes on BRKCS/RETRBI/TSKSW, so skip it */ \
+ nec_state->MF = ((f) & 0x8000) == 0x8000; \
+}