diff options
Diffstat (limited to 'trunk/src/emu/cpu/nec/v25priv.h')
-rw-r--r-- | trunk/src/emu/cpu/nec/v25priv.h | 258 |
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; \ +} |