1 /* Cpu types, steps of 8 to help the cycle count calculation */ 2 #define V33_TYPE 0 3 #define V30_TYPE 8 4 #define V20_TYPE 16 5 6 #ifndef FALSE 7 #define FALSE 0 8 #define TRUE 1 9 #endif 10 11 #define cpu_readop cpu_readmem20_op 12 #define cpu_readop_arg cpu_readmem20_arg 13 14 /* interrupt vectors */ 15 enum 16 { 17 NEC_DIVIDE_VECTOR = 0, 18 NEC_TRAP_VECTOR = 1, 19 NEC_NMI_VECTOR = 2, 20 NEC_BRKV_VECTOR = 4, 21 NEC_CHKIND_VECTOR = 5 22 }; 23 24 /* interrupt sources */ 25 typedef enum 26 { 27 BRK = 0, 28 INT_IRQ = 1, 29 NMI_IRQ = 2 30 } INTSOURCES; 31 32 /* NEC registers */ 33 typedef union 34 { /* eight general registers */ 35 UINT16 w[8]; /* viewed as 16 bits registers */ 36 UINT8 b[16]; /* or as 8 bit registers */ 37 } necbasicregs; 38 39 typedef struct _nec_state_t nec_state_t; 40 struct _nec_state_t 41 { 42 necbasicregs regs; 43 UINT32 fetch_xor; 44 UINT16 sregs[4]; 45 46 UINT16 ip; 47 48 /* PSW flags */ 49 INT32 SignVal; 50 UINT32 AuxVal, OverVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */ 51 UINT8 TF, IF, DF, MF; /* 0 or 1 valued flags */ 52 53 /* interrupt related */ 54 UINT32 vector; 55 UINT32 pending_irq; 56 UINT32 nmi_state; 57 UINT32 irq_state; 58 UINT32 poll_state; 59 UINT8 no_interrupt; 60 UINT8 halted; 61 62 INT32 icount; 63 64 UINT8 prefetch_size; 65 UINT8 prefetch_cycles; 66 INT8 prefetch_count; 67 UINT8 prefetch_reset; 68 UINT32 chip_type; 69 70 UINT32 prefix_base; /* base address of the latest prefix segment */ 71 UINT8 seg_prefix; /* prefix segment indicator */ 72 UINT32 cycles_total; 73 INT32 cycles_remaining; 74 INT8 stop_run; 75 }; 76 77 typedef enum { DS1, PS, SS_, DS0 } SREGS; 78 typedef enum { AW, CW, DW, BW, SP, BP, IX, IY } WREGS; 79 80 #ifdef LSB_FIRST 81 typedef enum { 82 AL = 0, //NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1), 83 AH = 1, //NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0), 84 CL = 2, //NATIVE_ENDIAN_VALUE_LE_BE(0x2, 0x3), 85 CH = 3, //NATIVE_ENDIAN_VALUE_LE_BE(0x3, 0x2), 86 DL = 4, //NATIVE_ENDIAN_VALUE_LE_BE(0x4, 0x5), 87 DH = 5, //NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4), 88 BL = 6, //NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7), 89 BH = 7 //NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6), 90 } BREGS; 91 #else 92 typedef enum { 93 AL = 1, //NATIVE_ENDIAN_VALUE_LE_BE(0x0, 0x1), 94 AH = 0, //NATIVE_ENDIAN_VALUE_LE_BE(0x1, 0x0), 95 CL = 3, //NATIVE_ENDIAN_VALUE_LE_BE(0x2, 0x3), 96 CH = 2, //NATIVE_ENDIAN_VALUE_LE_BE(0x3, 0x2), 97 DL = 5, //NATIVE_ENDIAN_VALUE_LE_BE(0x4, 0x5), 98 DH = 4, //NATIVE_ENDIAN_VALUE_LE_BE(0x5, 0x4), 99 BL = 7, //NATIVE_ENDIAN_VALUE_LE_BE(0x6, 0x7), 100 BH = 6 //NATIVE_ENDIAN_VALUE_LE_BE(0x7, 0x6), 101 } BREGS; 102 #endif 103 104 #define Sreg(x) nec_state->sregs[x] 105 #define Wreg(x) nec_state->regs.w[x] 106 #define Breg(x) nec_state->regs.b[x] 107 108 #define PC(n) ((Sreg(PS)<<4)+(n)->ip) 109 110 #define CF (nec_state->CarryVal!=0) 111 #define SF (nec_state->SignVal<0) 112 #define ZF (nec_state->ZeroVal==0) 113 #define PF parity_table[(BYTE)nec_state->ParityVal] 114 #define AF (nec_state->AuxVal!=0) 115 #define OF (nec_state->OverVal!=0) 116 117 /************************************************************************/ 118 119 #define read_mem_byte(a) cpu_readmem20(a) 120 #define read_mem_word(a) (cpu_readmem20(a)+(cpu_readmem20((a)+1)<<8)) //nec_state->program->read_word_unaligned(a) 121 #define write_mem_byte(a,d) cpu_writemem20((a),(d)) 122 //#define write_mem_word(a,d) {cpu_writemem20((a),(unsigned char)(d)); cpu_writemem20((a)+1,(d)>>8); } //nec_state->program->write_word_unaligned((a),(d)) 123 124 #define read_port_byte(a) cpu_readport(a) 125 #define read_port_word(a) (cpu_readport(a)+cpu_readport((a)+1)*256) 126 #define write_port_byte(a,d) cpu_writeport((a),(d)) 127 //#define write_port_word(a,d) { cpu_writeport((a),(unsigned char)(d)); (cpu_writeport((a)+1,(d)>>8); } // nec_state->io->write_word_unaligned((a),(d)) 128 129 /************************************************************************/ 130 131 #define CHANGE_PC do { EMPTY_PREFETCH(); } while (0) 132 133 #define SegBase(Seg) (Sreg(Seg) << 4) 134 135 #define DefaultBase(Seg) ((nec_state->seg_prefix && (Seg==DS0 || Seg==SS_)) ? nec_state->prefix_base : Sreg(Seg) << 4) 136 137 #define GetMemB(Seg,Off) (read_mem_byte(DefaultBase(Seg) + (Off))) 138 #define GetMemW(Seg,Off) (read_mem_word(DefaultBase(Seg) + (Off))) 139 140 #define PutMemB(Seg,Off,x) { write_mem_byte(DefaultBase(Seg) + (Off), (x)); } 141 #define PutMemW(Seg,Off,x) { write_mem_word(DefaultBase(Seg) + (Off), (x)); } 142 143 /* prefetch timing */ 144 145 //#define FETCHWORD() (cpu_readop_arg((Sreg(PS)<<4) + sChipsPtr->ip)+(cpu_readop_arg(((Sreg(PS)<<4) + sChipsPtr->ip+1))<<8)); sChipsPtr->ip+=2 146 #define FETCH() cpu_readop_arg((Sreg(PS)<<4) + sChipsPtr->ip++) 147 #define FETCHWORD() (FETCH() + FETCH() * 256) 148 #define EMPTY_PREFETCH() nec_state->prefetch_reset = 1 149 150 151 #define PUSH(val) { Wreg(SP) -= 2; write_mem_word(((Sreg(SS_)<<4)+Wreg(SP)), val); } 152 #define POP(var) { Wreg(SP) += 2; var = read_mem_word(((Sreg(SS_)<<4) + ((Wreg(SP)-2) & 0xffff))); } 153 154 155 #define GetModRM UINT32 ModRM=FETCH() 156 157 /* Cycle count macros: 158 CLK - cycle count is the same on all processors 159 CLKS - cycle count differs between processors, list all counts 160 CLKW - cycle count for word read/write differs for odd/even source/destination address 161 CLKM - cycle count for reg/mem instructions 162 CLKR - cycle count for reg/mem instructions with different counts for odd/even addresses 163 164 165 Prefetch & buswait time is not emulated. 166 Extra cycles for PUSH'ing or POP'ing registers to odd addresses is not emulated. 167 */ 168 169 #define CLK(all) nec_state->icount-=all 170 #define CLKS(v20,v30,v33) { const UINT32 ccount=(v20<<16)|(v30<<8)|v33; nec_state->icount-=(ccount>>nec_state->chip_type)&0x7f; } 171 #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); } 172 #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); } 173 #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); } 174 175 /************************************************************************/ 176 #define CompressFlags() (WORD)(int(CF) | 0x02 | (int(PF) << 2) | (int(AF) << 4) | (int(ZF) << 6) \ 177 | (int(SF) << 7) | (nec_state->TF << 8) | (nec_state->IF << 9) \ 178 | (nec_state->DF << 10) | (int(OF) << 11) | 0x7000 | (nec_state->MF << 15)) 179 180 #define ExpandFlags(f) \ 181 { \ 182 nec_state->CarryVal = (f) & 0x0001; \ 183 nec_state->ParityVal = !((f) & 0x0004); \ 184 nec_state->AuxVal = (f) & 0x0010; \ 185 nec_state->ZeroVal = !((f) & 0x0040); \ 186 nec_state->SignVal = (f) & 0x0080 ? -1 : 0; \ 187 nec_state->TF = ((f) & 0x0100) == 0x0100; \ 188 nec_state->IF = ((f) & 0x0200) == 0x0200; \ 189 nec_state->DF = ((f) & 0x0400) == 0x0400; \ 190 nec_state->OverVal = (f) & 0x0800; \ 191 nec_state->MF = ((f) & 0x8000) == 0x8000; \ 192 } 193