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