/* 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 */ enum INTSOURCES { 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 }; enum { VECTOR_PC = 0x02/2, PSW_SAVE = 0x04/2, PC_SAVE = 0x06/2 }; enum SREGS { DS1 = 0x0E/2, PS = 0x0C/2, SS = 0x0A/2, DS0 = 0x08/2 }; enum WREGS { AW = 0x1E/2, CW = 0x1C/2, DW = 0x1A/2, BW = 0x18/2, SP = 0x16/2, BP = 0x14/2, IX = 0x12/2, IY = 0x10/2 }; enum BREGS { 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) }; #define SetRB(x) do { m_RBW = (x) << 4; m_RBB = (x) << 5; } while (0) #define Sreg(x) m_ram.w[m_RBW + (x)] #define Wreg(x) m_ram.w[m_RBW + (x)] #define Breg(x) m_ram.b[m_RBB + (x)] #define PC() ((Sreg(PS)<<4)+m_ip) #define CF (m_CarryVal!=0) #define SF (m_SignVal<0) #define ZF (m_ZeroVal==0) #define PF parity_table[(BYTE)m_ParityVal] #define AF (m_AuxVal!=0) #define OF (m_OverVal!=0) #define RB (m_RBW >> 4) /************************************************************************/ #define read_mem_byte(a) v25_read_byte((a)) #define read_mem_word(a) v25_read_word((a)) #define write_mem_byte(a,d) v25_write_byte((a),(d)) #define write_mem_word(a,d) v25_write_word((a),(d)) #define read_port_byte(a) m_io->read_byte(a) #define read_port_word(a) m_io->read_word_unaligned(a) #define write_port_byte(a,d) m_io->write_byte((a),(d)) #define write_port_word(a,d) m_io->write_word_unaligned((a),(d)) /************************************************************************/ #define CHANGE_PC do { EMPTY_PREFETCH(); } while (0) #define SegBase(Seg) (Sreg(Seg) << 4) #define DefaultBase(Seg) ((m_seg_prefix && (Seg==DS0 || Seg==SS)) ? m_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() #define FETCHWORD() fetchword() #define EMPTY_PREFETCH() m_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) m_icount-=all #define CLKS(v20,v30,v33) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33; m_icount-=(ccount>>m_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; m_icount-=(addr&1)?((ocount>>m_chip_type)&0x7f):((ecount>>m_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; m_icount-=( ModRM >=0xc0 )?((ccount>>m_chip_type)&0x7f):((mcount>>m_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) m_icount-=vall; else m_icount-=(addr&1)?((ocount>>m_chip_type)&0x7f):((ecount>>m_chip_type)&0x7f); } /************************************************************************/ #define CompressFlags() (WORD)(CF | (m_IBRK << 1) | (PF << 2) | (m_F0 << 3) | (AF << 4) \ | (m_F1 << 5) | (ZF << 6) | (SF << 7) | (m_TF << 8) | (m_IF << 9) \ | (m_DF << 10) | (OF << 11) | (RB << 12) | (m_MF << 15)) #define ExpandFlags(f) \ { \ m_CarryVal = (f) & 0x0001; \ m_IBRK = ((f) & 0x0002) == 0x0002; \ m_ParityVal = !((f) & 0x0004); \ m_F0 = ((f) & 0x0008) == 0x0008; \ m_AuxVal = (f) & 0x0010; \ m_F1 = ((f) & 0x0020) == 0x0020; \ m_ZeroVal = !((f) & 0x0040); \ m_SignVal = (f) & 0x0080 ? -1 : 0; \ m_TF = ((f) & 0x0100) == 0x0100; \ m_IF = ((f) & 0x0200) == 0x0200; \ m_DF = ((f) & 0x0400) == 0x0400; \ m_OverVal = (f) & 0x0800; \ /* RB only changes on BRKCS/RETRBI/TSKSW, so skip it */ \ m_MF = ((f) & 0x8000) == 0x8000; \ }