1 /********************************************************************
2 
3  Hyperstone E1-32XS cpu emulator
4  written by Pierpaolo Prazzoli
5 
6  All the types are compatible:
7  - Hyperstone E1-32
8  - Hyperstone E1-16
9  - Hyperstone E1-32X
10  - Hyperstone E1-16X
11  - Hyperstone E1-32XN
12  - Hyperstone E1-32XT
13  - Hyperstone E1-16XT
14  - Hyperstone E1-32XS
15  - Hyperstone E1-16XS
16  - Hyperstone E1-32XP (ever released?)
17  - Hyperstone E1-32XSB (compatible?)
18  - Hyperstone E1-16XSB (compatible?)
19 
20  TODO:
21  - Fix the debug interface
22  - Check if the inverted values are correct and also the sign is correct
23  - Check the signs where it's not specified in the docs and if the range is good
24  - Check register bounds when Lsf, Ldf, Rsf and Rdf are used
25  - Check the delay
26  - Check operation with 7 bits variables
27  - Check if	L0 is always interpreted as L16
28  - Load / Store instruction should use the pipeline
29  - Add the latency
30  - Add Interrupts
31  - Add floating point opcodes
32  - Add cast when 8/16 bits are read used?
33  - All the TODO in the source
34  - Are the read/write functions used correct?
35 
36  CHANGELOG:
37 
38  Pierpaolo Prazzoli - 10/26/03
39 	- Changed get_lrconst to get_const and changed it to use the removed GET_CONST_RR
40 	  macro.
41 	- Removed the High flag used in some opcodes, it should be used only in
42 	  MOV and MOVI instruction.
43 	- Fixed MOV and MOVI instruction.
44 	- Set to 1 FP is SR register at reset.
45 	  (From the doc: A Call, Trap or Software instruction increments the FP and sets FL
46 	  to 6, thus creating a new stack frame with the length of 6 registers).
47 
48  MooglyGuy - 10/25/03
49  	- Fixed CALL enough that it at least jumps to the right address, no word
50  	  yet as to whether or not it's working enough to return.
51  	- Added get_lrconst() to get the const value for the CALL operand, since
52  	  apparently using immediate_value() was wrong. The code is ugly, but it
53  	  works properly. Vampire 1/2 now gets far enough to try to test its RAM.
54  	- Just from looking at it, CALL apparently doesn't frame properly. I'm not
55  	  sure about FRAME, but perhaps it doesn't work properly - I'm not entirely
56  	  positive. The return address when vamphalf's memory check routine is
57  	  called at FFFFFD7E is stored in register L8, and then the RET instruction
58  	  at the end of the routine uses L1 as the return address, so that might
59  	  provide some clues as to how it works.
60  	- I'd almost be willing to bet money that there's no framing at all since
61  	  the values in L0 - L15 as displayed by the debugger would change during a
62  	  CALL or FRAME operation. I'll look when I'm in the mood.
63  	- The mood struck me, and I took a look at SET_L_REG and GET_L_REG.
64  	  Apparently no matter what the current frame pointer is they'll always use
65  	  local_regs[0] through local_regs[15].
66 
67  MooglyGuy - 08/20/03
68  	- Added H flag support for MOV and MOVI
69  	- Changed init routine to set S flag on boot. Apparently the CPU defaults to
70  	  supervisor mode as opposed to user mode when it powers on, as shown by the
71  	  vamphalf power-on routines. Makes sense, too, since if the machine booted
72  	  in user mode, it would be impossible to get into supervisor mode.
73 
74  Pierpaolo Prazzoli	- 08/19/03
75 	- Added check for D_BIT and S_BIT where PC or SR must or must not be denoted.
76 	  (movd, divu, divs, ldxx1, ldxx2, stxx1, stxx2, mulu, muls, set, mul
77 	  call, chk)
78 
79  MooglyGuy - 08/17/03
80 	- Working on support for H flag, nothing quite done yet
81 	- Added trap Range Error for CHK PC, PC
82 	- Fixed relative jumps, they have to be taken from the opcode following the
83 	  jump minstead of the jump opcode itself.
84 
85  Pierpaolo Prazzoli	- 08/17/03
86 	- Fixed get_pcrel() when OP & 0x80 is set.
87 	- Decremented PC by 2 also in MOV, ADD, ADDI, SUM, SUB and added the check if
88 	  D_BIT is not set. (when pc is changed they are implicit branch)
89 
90  MooglyGuy - 08/17/03
91     - Implemented a crude hack to set FL in the SR to 6, since according to the docs
92       that's supposed to happen each time a trap occurs, apparently including when
93       the processor starts up. The 3rd opcode executed in vamphalf checks to see if
94       the FL flag in SR 6, so it's apparently the "correct" behaviour despite the
95       docs not saying anything on it. If FL is not 6, the branch falls through and
96       encounters a CHK PC, L2, which at that point will always throw a range trap.
97       The range trap vector contains 00000000 (CHK PC, PC), which according to the
98       docs will always throw a range trap (which would effectively lock the system).
99       This revealed a bug: CHK PC, PC apparently does not throw a range trap, which
100       needs to be fixed. Now that the "correct" behaviour is hacked in with the FL
101       flags, it reveals yet another bug in that the branch is interpreted as being
102       +0x8700. This means that the PC then wraps around to 000082B0, give or take
103       a few bytes. While it does indeed branch to valid code, I highly doubt that
104       this is the desired effect. Check for signed/unsigned relative branch, maybe?
105 
106  MooglyGuy - 08/16/03
107  	- Fixed the debugger at least somewhat so that it displays hex instead of decimal,
108  	  and so that it disassembles opcodes properly.
109  	- Fixed e132xs_execute() to increment PC *after* executing the opcode instead of
110  	  before. This is probably why vamphalf was booting to fffffff8, but executing at
111  	  fffffffa instead.
112  	- Changed execute_trap to decrement PC by 2 so that the next opcode isn't skipped
113  	  after a trap
114  	- Changed execute_br to decrement PC by 2 so that the next opcode isn't skipped
115  	  after a branch
116  	- Changed e132xs_movi to decrement PC by 2 when G0 (PC) is modified so that the
117  	  next opcode isn't skipped after a branch
118  	- Changed e132xs_movi to default to a UINT32 being moved into the register
119  	  as opposed to a UINT8. This is wrong, the bit width is quite likely to be
120  	  dependent on the n field in the Rimm instruction type. However, vamphalf uses
121  	  MOVI G0,[FFFF]FBAC (n=$13) since there's apparently no absolute branch opcode.
122  	  What kind of CPU is this that it doesn't have an absolute jump in its branch
123  	  instructions and you have to use an immediate MOV to do an abs. jump!?
124 
125 *********************************************************************/
126 
127 /*
128 
129 Add in cpuintrf.c
130 
131 #if (HAS_E132XS)
132 #include "cpu/e132xs/e132xs.h"
133 #endif
134 
135 //TODO: check -> nirq,dirq,mem,shift,bits,align
136 #if (HAS_E132XS)
137 	CPU0(E132XS,   e132xs, 	 1,0,1.00, 32, 32bedw,	  0,32,BE,4, 6	),
138 #endif
139 
140 Add in cpuintrf.h
141 
142 #if (HAS_E132XS)
143 	CPU_E132XS,
144 #endif
145 
146 Add in rules.mak
147 
148 CPU=$(strip $(findstring E132XS@,$(CPUS)))
149 ifneq ($(CPU),)
150 OBJDIRS += $(OBJ)/cpu/e132xs
151 CPUDEFS += -DHAS_E132XS=1
152 CPUOBJS += $(OBJ)/cpu/e132xs/e132xs.o
153 DBGOBJS += $(OBJ)/cpu/e132xs/32xsdasm.o
154 $(OBJ)/cpu/e132xs/e132xs.o: e132xs.c e132xs.h
155 else
156 CPUDEFS += -DHAS_E132XS=0
157 endif
158 
159 Add in mame.mak
160 
161 CPUS+=E132XS@
162 
163 */
164 
165 #include "driver.h"
166 #include "cpuintrf.h"
167 #include "state.h"
168 #include "mamedbg.h"
169 #include "e132xs.h"
170 
171 int e132xs_ICount;
172 int h_clear;
173 
174 void e132xs_chk(void);
175 void e132xs_movd(void);
176 void e132xs_divu(void);
177 void e132xs_divs(void);
178 void e132xs_xm(void);
179 void e132xs_mask(void);
180 void e132xs_sum(void);
181 void e132xs_sums(void);
182 void e132xs_cmp(void);
183 void e132xs_mov(void);
184 void e132xs_add(void);
185 void e132xs_adds(void);
186 void e132xs_cmpb(void);
187 void e132xs_andn(void);
188 void e132xs_or(void);
189 void e132xs_xor(void);
190 void e132xs_subc(void);
191 void e132xs_not(void);
192 void e132xs_sub(void);
193 void e132xs_subs(void);
194 void e132xs_addc(void);
195 void e132xs_and(void);
196 void e132xs_neg(void);
197 void e132xs_negs(void);
198 void e132xs_cmpi(void);
199 void e132xs_movi(void);
200 void e132xs_addi(void);
201 void e132xs_addsi(void);
202 void e132xs_cmpbi(void);
203 void e132xs_andni(void);
204 void e132xs_ori(void);
205 void e132xs_xori(void);
206 void e132xs_shrdi(void);
207 void e132xs_shrd(void);
208 void e132xs_shr(void);
209 void e132xs_sardi(void);
210 void e132xs_sard(void);
211 void e132xs_sar(void);
212 void e132xs_shldi(void);
213 void e132xs_shld(void);
214 void e132xs_shl(void);
215 void reserved(void);
216 void e132xs_testlz(void);
217 void e132xs_rol(void);
218 void e132xs_ldxx1(void);
219 void e132xs_ldxx2(void);
220 void e132xs_stxx1(void);
221 void e132xs_stxx2(void);
222 void e132xs_shri(void);
223 void e132xs_sari(void);
224 void e132xs_shli(void);
225 void e132xs_mulu(void);
226 void e132xs_muls(void);
227 void e132xs_set(void);
228 void e132xs_mul(void);
229 void e132xs_fadd(void);
230 void e132xs_faddd(void);
231 void e132xs_fsub(void);
232 void e132xs_fsubd(void);
233 void e132xs_fmul(void);
234 void e132xs_fmuld(void);
235 void e132xs_fdiv(void);
236 void e132xs_fdivd(void);
237 void e132xs_fcmp(void);
238 void e132xs_fcmpd(void);
239 void e132xs_fcmpu(void);
240 void e132xs_fcmpud(void);
241 void e132xs_fcvt(void);
242 void e132xs_fcvtd(void);
243 void e132xs_extend(void);
244 void e132xs_do(void);
245 void e132xs_ldwr(void);
246 void e132xs_lddr(void);
247 void e132xs_ldwp(void);
248 void e132xs_lddp(void);
249 void e132xs_stwr(void);
250 void e132xs_stdr(void);
251 void e132xs_stwp(void);
252 void e132xs_stdp(void);
253 void e132xs_dbv(void);
254 void e132xs_dbnv(void);
255 void e132xs_dbe(void);
256 void e132xs_dbne(void);
257 void e132xs_dbc(void);
258 void e132xs_dbnc(void);
259 void e132xs_dbse(void);
260 void e132xs_dbht(void);
261 void e132xs_dbn(void);
262 void e132xs_dbnn(void);
263 void e132xs_dble(void);
264 void e132xs_dbgt(void);
265 void e132xs_dbr(void);
266 void e132xs_frame(void);
267 void e132xs_call(void);
268 void e132xs_bv(void);
269 void e132xs_bnv(void);
270 void e132xs_be(void);
271 void e132xs_bne(void);
272 void e132xs_bc(void);
273 void e132xs_bnc(void);
274 void e132xs_bse(void);
275 void e132xs_bht(void);
276 void e132xs_bn(void);
277 void e132xs_bnn(void);
278 void e132xs_ble(void);
279 void e132xs_bgt(void);
280 void e132xs_br(void);
281 void e132xs_trap(void);
282 
283 /* Registers */
284 enum
285 {
286 
287 	E132XS_PC = 1,
288 	E132XS_SR,
289 	E132XS_FER,
290 	E132XS_SP,
291 	E132XS_UB,
292 	E132XS_BCR,
293 	E132XS_TPR,
294 	E132XS_TCR,
295 	E132XS_TR,
296 	E132XS_WCR,
297 	E132XS_ISR,
298 	E132XS_FCR,
299 	E132XS_MCR,
300 	E132XS_G0,  E132XS_G1,  E132XS_G2,  E132XS_G3,
301 	E132XS_G4,  E132XS_G5,  E132XS_G6,  E132XS_G7,
302 	E132XS_G8,  E132XS_G9,  E132XS_G10, E132XS_G11,
303 	E132XS_G12, E132XS_G13, E132XS_G14, E132XS_G15,
304 	E132XS_L0,  E132XS_L1,  E132XS_L2,  E132XS_L3,
305 	E132XS_L4,  E132XS_L5,  E132XS_L6,  E132XS_L7,
306 	E132XS_L8,  E132XS_L9,  E132XS_L10, E132XS_L11,
307 	E132XS_L12, E132XS_L13, E132XS_L14, E132XS_L15,
308 };
309 
310 /* Internal registers */
311 typedef struct
312 {
313 	UINT32 global_regs[32];
314 	UINT32 local_regs[64]; /*stack registers which contain the most recent stack*/
315 						   /*current stack frame (maximun 16 registers) is always in registers*/
316 
317 	/* internal stuff */
318 	UINT32			ppc; /*previous pc*/
319 	UINT16			op;	 /*opcode*/
320 	int				delay;
321 	int				delay_pc;
322 
323 } e132xs_regs;
324 
325 static e132xs_regs e132xs;
326 
327 /* Opcodes table */
328 static void (*e132xs_op[0x100])(void) = {
329 	e132xs_chk,	 e132xs_chk,  e132xs_chk,   e132xs_chk,		/* CHK - CHKZ - NOP */
330 	e132xs_movd, e132xs_movd, e132xs_movd,  e132xs_movd,	/* MOVD - RET */
331 	e132xs_divu, e132xs_divu, e132xs_divu,  e132xs_divu,	/* DIVU */
332 	e132xs_divs, e132xs_divs, e132xs_divs,  e132xs_divs,	/* DIVS */
333 	e132xs_xm,	 e132xs_xm,   e132xs_xm,    e132xs_xm,		/* XMx - XXx */
334 	e132xs_mask, e132xs_mask, e132xs_mask,  e132xs_mask,	/* MASK */
335 	e132xs_sum,  e132xs_sum,  e132xs_sum,   e132xs_sum,		/* SUM */
336 	e132xs_sums, e132xs_sums, e132xs_sums,  e132xs_sums,	/* SUMS */
337 	e132xs_cmp,  e132xs_cmp,  e132xs_cmp,   e132xs_cmp,		/* CMP */
338 	e132xs_mov,  e132xs_mov,  e132xs_mov,   e132xs_mov,		/* MOV */
339 	e132xs_add,  e132xs_add,  e132xs_add,   e132xs_add,		/* ADD */
340 	e132xs_adds, e132xs_adds, e132xs_adds,  e132xs_adds,	/* ADDS */
341 	e132xs_cmpb, e132xs_cmpb, e132xs_cmpb,  e132xs_cmpb,	/* CMPB */
342 	e132xs_andn, e132xs_andn, e132xs_andn,  e132xs_andn,	/* ANDN */
343 	e132xs_or,   e132xs_or,   e132xs_or,    e132xs_or,		/* OR */
344 	e132xs_xor,  e132xs_xor,  e132xs_xor,   e132xs_xor,		/* XOR */
345 	e132xs_subc, e132xs_subc, e132xs_subc,  e132xs_subc,	/* SUBC */
346 	e132xs_not,  e132xs_not,  e132xs_not,   e132xs_not,		/* NOT */
347 	e132xs_sub,  e132xs_sub,  e132xs_sub,   e132xs_sub,		/* SUB */
348 	e132xs_subs, e132xs_subs, e132xs_subs,  e132xs_subs,	/* SUBS */
349 	e132xs_addc, e132xs_addc, e132xs_addc,  e132xs_addc,	/* ADDC */
350 	e132xs_and,  e132xs_and,  e132xs_and,   e132xs_and,		/* AND */
351 	e132xs_neg,  e132xs_neg,  e132xs_neg,   e132xs_neg,		/* NEG */
352 	e132xs_negs, e132xs_negs, e132xs_negs,  e132xs_negs,	/* NEGS */
353 	e132xs_cmpi, e132xs_cmpi, e132xs_cmpi,  e132xs_cmpi,	/* CMPI */
354 	e132xs_movi, e132xs_movi, e132xs_movi,  e132xs_movi,	/* MOVI */
355 	e132xs_addi, e132xs_addi, e132xs_addi,  e132xs_addi,	/* ADDI */
356 	e132xs_addsi,e132xs_addsi,e132xs_addsi, e132xs_addsi,	/* ADDSI */
357 	e132xs_cmpbi,e132xs_cmpbi,e132xs_cmpbi, e132xs_cmpbi,	/* CMPBI */
358 	e132xs_andni,e132xs_andni,e132xs_andni, e132xs_andni,	/* ANDNI */
359 	e132xs_ori,  e132xs_ori,  e132xs_ori,   e132xs_ori,		/* ORI */
360 	e132xs_xori, e132xs_xori, e132xs_xori,  e132xs_xori,	/* XORI */
361 	e132xs_shrdi,e132xs_shrdi,e132xs_shrd,  e132xs_shr,		/* SHRDI, SHRD, SHR */
362 	e132xs_sardi,e132xs_sardi,e132xs_sard,  e132xs_sar,		/* SARDI, SARD, SAR */
363 	e132xs_shldi,e132xs_shldi,e132xs_shld,  e132xs_shl,		/* SHLDI, SHLD, SHL */
364 	reserved,    reserved,	  e132xs_testlz,e132xs_rol,		/* RESERVED, TESTLZ, ROL */
365 	e132xs_ldxx1,e132xs_ldxx1,e132xs_ldxx1, e132xs_ldxx1,	/* LDxx.D/A/IOD/IOA */
366 	e132xs_ldxx2,e132xs_ldxx2,e132xs_ldxx2, e132xs_ldxx2,	/* LDxx.N/S */
367 	e132xs_stxx1,e132xs_stxx1,e132xs_stxx1,e132xs_stxx1,	/* STxx.D/A/IOD/IOA */
368 	e132xs_stxx2,e132xs_stxx2,e132xs_stxx2,e132xs_stxx2,	/* STxx.N/S */
369 	e132xs_shri, e132xs_shri, e132xs_shri,  e132xs_shri,	/* SHRI */
370 	e132xs_sari, e132xs_sari, e132xs_sari,  e132xs_sari,	/* SARI */
371 	e132xs_shli, e132xs_shli, e132xs_shli,  e132xs_shli,	/* SHLI */
372 	reserved,    reserved,    reserved,     reserved,		/* RESERVED */
373 	e132xs_mulu, e132xs_mulu, e132xs_mulu,  e132xs_mulu,	/* MULU */
374 	e132xs_muls, e132xs_muls, e132xs_muls,  e132xs_muls,	/* MULS */
375 	e132xs_set,  e132xs_set,  e132xs_set,   e132xs_set,		/* SETxx - SETADR - FETCH */
376 	e132xs_mul,  e132xs_mul,  e132xs_mul,   e132xs_mul,		/* MUL */
377 	e132xs_fadd, e132xs_faddd,e132xs_fsub,  e132xs_fsubd,	/* FADD, FADDD, FSUB, FSUBD */
378 	e132xs_fmul, e132xs_fmuld,e132xs_fdiv,  e132xs_fdivd,	/* FMUL, FMULD, FDIV, FDIVD */
379 	e132xs_fcmp, e132xs_fcmpd,e132xs_fcmpu, e132xs_fcmpud,	/* FCMP, FCMPD, FCMPU, FCMPUD */
380 	e132xs_fcvt, e132xs_fcvtd,e132xs_extend,e132xs_do,		/* FCVT, FCVTD, EXTEND, DO */
381 	e132xs_ldwr, e132xs_ldwr, e132xs_lddr,  e132xs_lddr,	/* LDW.R, LDD.R */
382 	e132xs_ldwp, e132xs_ldwp, e132xs_lddp,  e132xs_lddp,	/* LDW.P, LDD.P */
383 	e132xs_stwr, e132xs_stwr, e132xs_stdr,  e132xs_stdr,	/* STW.R, STD.R */
384 	e132xs_stwp, e132xs_stwp, e132xs_stdp,  e132xs_stdp,	/* STW.P, STD.P */
385 	e132xs_dbv,  e132xs_dbnv, e132xs_dbe,   e132xs_dbne,	/* DBV, DBNV, DBE, DBNE */
386 	e132xs_dbc,  e132xs_dbnc, e132xs_dbse,  e132xs_dbht,	/* DBC, DBNC, DBSE, DBHT */
387 	e132xs_dbn,  e132xs_dbnn, e132xs_dble,  e132xs_dbgt,	/* DBN, DBNN, DBLE, DBGT */
388 	e132xs_dbr,  e132xs_frame,e132xs_call,  e132xs_call,	/* DBR, FRAME, CALL */
389 	e132xs_bv,   e132xs_bnv,  e132xs_be,    e132xs_bne,		/* BV, BNV, BE, BNE */
390 	e132xs_bc,   e132xs_bnc,  e132xs_bse,   e132xs_bht,		/* BC, BNC, BSE, BHT */
391 	e132xs_bn,   e132xs_bnn,  e132xs_ble,   e132xs_bgt,		/* BN, BNN, BLE, BGT */
392 	e132xs_br,   e132xs_trap, e132xs_trap,  e132xs_trap		/* BR, TRAPxx - TRAP */
393 };
394 
395 static UINT32 entry_point = 0xffffff00;	/*default @ MEM3*/
396 
397 /* Return the entry point for a determinated trap */
get_trap_addr(UINT8 trap_no)398 UINT32 get_trap_addr(UINT8 trap_no)
399 {
400 	UINT32 addr;
401 	if( entry_point & 0xffffff00 ) /* @ MEM3 */
402 	{
403 		addr = trap_no * 4;
404 	}
405 	else
406 	{
407 		addr = (63 - trap_no) * 4;
408 	}
409 	addr |= entry_point;
410 	return addr;
411 }
412 
413 /* Return the entry point for a determinated emulated code (the one for "extend" opcode is reserved) */
get_emu_code_addr(UINT8 num)414 UINT32 get_emu_code_addr(UINT8 num) /* num is OP */
415 {
416 	UINT32 addr;
417 	if( entry_point & 0xffffff00 ) /* @ MEM3 */
418 	{
419 		addr = (entry_point - 0x100) | (num << 4);
420 	}
421 	else
422 	{
423 		addr = entry_point | (0x10c | ((0x0f - num) << 4));
424 	}
425 	return addr;
426 }
427 
428 #define OP					e132xs.op
429 
430 /* TODO: i need to use these 3 define?*/
431 #define SET_PC(val)		PC = (val & 0xfffffffe) /*PC(0) = 0*/
432 #define SET_SP(val)		SP = (val & 0xfffffffc) /*SP(0) = SP(1) = 0*/
433 #define SET_UB(val)		UB = (val & 0xfffffffc) /*UB(0) = UB(1) = 0*/
434 
435 #define PPC				e132xs.ppc /*previous pc*/
436 #define PC				e132xs.global_regs[0] /*Program Counter*/
437 #define SR				e132xs.global_regs[1] /*Status Register*/
438 #define FER				e132xs.global_regs[2] /*Floating-Point Exception Register*/
439 /*#define ?? global_regs[3 - 15] */ /*General Purpose Registers*/
440 /*#define ?? global_regs[16] */ /*reserved*/
441 /*#define ?? global_regs[17] */ /*reserved*/
442 #define SP				e132xs.global_regs[18] /*Stack Pointer*/
443 #define UB				e132xs.global_regs[19] /*Upper Stack Bound*/
444 #define BCR				e132xs.global_regs[20] /*Bus Control Register*/
445 #define TPR				e132xs.global_regs[21] /*Timer Prescaler Register*/
446 #define TCR				e132xs.global_regs[22] /*Timer Compare Register*/
447 #define TR				e132xs.global_regs[23] /*Timer Register*/
448 #define WCR				e132xs.global_regs[24] /*Watchdog Compare Register*/
449 #define ISR				e132xs.global_regs[25] /*Input Status Register*/
450 #define FCR				e132xs.global_regs[26] /*Function Control Register*/
451 #define MCR				e132xs.global_regs[27] /*Memory Control Register*/
452 /*#define ??			e132xs.global_regs[28] */ /*reserved*/
453 /*#define ??			e132xs.global_regs[29] */ /*reserved*/
454 /*#define ??			e132xs.global_regs[30] */ /*reserved*/
455 /*#define ??			e132xs.global_regs[31] */ /*reserved*/
456 
457 /* Registers Number	*/
458 #define REG_BCR			20
459 #define REG_TPR			21
460 #define REG_FCR			26
461 #define REG_MCR			27
462 
463 #define GET_G_REG(code)			e132xs.global_regs[code]
464 #define GET_L_REG(code)			e132xs.local_regs[code]
465 #define SET_G_REG(code,val)		e132xs.global_regs[code] = val
466 #define SET_L_REG(code,val)		e132xs.local_regs[code] = val
467 
468 #define S_BIT					((OP & 0x100) >> 8)
469 #define N_BIT					S_BIT	/*it's the same bit but with different name and use*/
470 #define D_BIT					((OP & 0x200) >> 9)
471 #define N_VALUE					((N_BIT << 4 ) | (OP & 0x0f))
472 #define D_CODE					((OP & 0xf0) >> 4)
473 #define S_CODE					(OP & 0x0f)
474 #define SIGN_BIT(val)			((val & 0x80000000) >> 31)
475 #define NOINC					0
476 #define INC						1
477 
478 #define SET_RD(val,inc)										\
479 		if( D_BIT )											\
480 		{													\
481 			SET_L_REG(D_CODE + inc, val);					\
482 		}													\
483 		else												\
484 		{													\
485 			SET_G_REG(D_CODE + inc, val);					\
486 		}
487 
488 #define SET_LD(val,inc)										\
489 		if( !D_CODE )										\
490 			SET_L_REG(16 + inc, val);						\
491 		else												\
492 			SET_L_REG(D_CODE + inc, val);
493 
494 #define SET_RS(val,inc)										\
495 		if( S_BIT )											\
496 		{													\
497 			SET_L_REG(S_CODE + inc, val);					\
498 		}													\
499 		else												\
500 		{													\
501 			SET_G_REG(D_CODE + inc, val);	\
502 		}
503 
504 /* SR flags */
505 #define GET_C					( SR & 0x00000001) /*bit 0 */ /*CARRY*/
506 #define GET_Z					((SR & 0x00000002)>>1) /*bit 1 */ /*ZERO*/
507 #define GET_N					((SR & 0x00000004)>>2) /*bit 2 */ /*NEGATIVE*/
508 #define GET_V					((SR & 0x00000008)>>3) /*bit 3 */ /*OVERFLOW*/
509 #define GET_M					((SR & 0x00000010)>>4) /*bit 4 */ /*CACHE-MODE*/
510 #define GET_H					((SR & 0x00000020)>>5) /*bit 5 */ /*HIGHGLOBAL*/
511 /*#define RESERVED				((SR & 0x00000040)>>6) */ /*bit 6 //always 0*/
512 #define GET_I					((SR & 0x00000080)>>7) /*bit 7 */ /*INTERRUPT-MODE*/
513 #define GET_FTE					((SR & 0x00001f00)>>8) /*bits 12 - 8 	*/ /*Floating-Point Trap Enable*/
514 #define	GET_FRM					((SR & 0x00006000)>>13) /*bits 14 - 13 */ /*Floating-Point Rounding Mode*/
515 #define GET_L					((SR & 0x00008000)>>15) /*bit 15 */ /*INTERRUPT-LOCK*/
516 #define GET_T					((SR & 0x00010000)>>16) /*bit 16 */ /*TRACE-MODE*/
517 #define GET_P					((SR & 0x00020000)>>17) /*bit 17 */ /*TRACE PENDING*/
518 #define GET_S					((SR & 0x00040000)>>18) /*bit 18 */ /*SUPERVISOR STATE*/
519 #define GET_ILC					((SR & 0x00180000)>>19) /*bits 20 - 19 */ /*INSTRUCTION-LENGTH*/
520 #define GET_FL					((SR & 0x01e00000)>>21) /*bits 24 - 21 */ /*FRAME LENGTH*/
521 #define GET_FP					((SR & 0xfe000000)>>25) /*bits 31 - 25 */ /*FRAME POINTER*/
522 
523 /* TODO: do i need to use this?*/
524 #define SET_SR(val)				(SR = (SR & 0xffff0000) | (val & 0x0000ffff)) /*when SR is addressed, only low 15 bits can be changed*/
525 
526 #define SET_C(val)				(SR = (SR & 0xfffffffe) |  val)
527 #define SET_Z(val)				(SR = (SR & 0xfffffffd) | (val << 1))
528 #define SET_N(val)				(SR = (SR & 0xfffffffb) | (val << 2))
529 #define SET_V(val)				(SR = (SR & 0xfffffff7) | (val << 3))
530 #define SET_M(val)				(SR = (SR & 0xffffffef) | (val << 4))
531 #define SET_H(val)				(SR = (SR & 0xffffffdf) | (val << 5))
532 /*#define RESERVED*/
533 #define SET_I(val)				(SR = (SR & 0xffffff7f) | (val << 7))
534 #define SET_FTE(val)			(SR = (SR & 0xffffe0ff) | (val << 8))
535 #define	SET_FRM(val)			(SR = (SR & 0xffff9fff) | (val << 13))
536 #define SET_L(val)				(SR = (SR & 0xffff7fff) | (val << 15))
537 #define SET_T(val)				(SR = (SR & 0xfffeffff) | (val << 16))
538 #define SET_P(val)				(SR = (SR & 0xfffdffff) | (val << 17))
539 #define SET_S(val)				(SR = (SR & 0xfffbffff) | (val << 18))
540 #define SET_ILC(val)			(SR = (SR & 0xffe7ffff) | (val << 19))
541 #define SET_FL(val)				(SR = (SR & 0xfe1fffff) | (val << 21))
542 #define SET_FP(val)				(SR = (SR & 0x1fffffff) | (val << 25))
543 
544 /* TODO: do i need to use these?*/
545 /* FER flags */
546 #define GET_ACCRUED				(FER & 0x0000001f) /*bits  4 - 0 */ /*Floating-Point Accrued Exceptions*/
547 #define GET_ACTUAL				(FER & 0x00001f00) /*bits 12 - 8 */ /*Floating-Point Actual  Exceptions*/
548 /*other bits are reversed, in particular 7 - 5 for the operating system.*/
549 /*the user program can only changes the above 2 flags*/
550 
551 
552 static UINT8 e132xs_reg_layout[] =
553 {
554 	E132XS_PC,  E132XS_SR,  E132XS_FER, E132XS_SP,  E132XS_UB,  -1,
555 	E132XS_BCR, E132XS_ISR, E132XS_FCR, E132XS_MCR, -1,
556 	E132XS_TR,  E132XS_TPR, E132XS_TCR, E132XS_WCR, -1,
557 	E132XS_G0,  E132XS_G1,  E132XS_G2,  E132XS_G3,  -1,
558 	E132XS_G4,  E132XS_G5,  E132XS_G6,  E132XS_G7,  -1,
559 	E132XS_G8,  E132XS_G9,  E132XS_G10, E132XS_G11, -1,
560 	E132XS_G12, E132XS_G13, E132XS_G14, E132XS_G15, -1,
561 	E132XS_L0,  E132XS_L1,  E132XS_L2,  E132XS_L3,  -1,
562 	E132XS_L4,  E132XS_L5,  E132XS_L6,  E132XS_L7,  -1,
563 	E132XS_L8,  E132XS_L9,  E132XS_L10, E132XS_L11, -1,
564 	E132XS_L12, E132XS_L13, E132XS_L14, E132XS_L15, 0
565 };
566 
567 UINT8 e132xs_win_layout[] =
568 {
569 	0, 0,80, 8, /* register window (top rows) */
570 	0, 9,34,13, /* disassembler window (left, middle columns) */
571 	35, 9,46, 6, /* memory #1 window (right, upper middle) */
572 	35,16,46, 6, /* memory #2 window (right, lower middle) */
573 	0,23,80, 1  /* command line window (bottom row) */
574 };
575 
e132xs_set_entry_point(int which)576 void e132xs_set_entry_point(int which)
577 {
578 	switch( which )
579 	{
580 		case E132XS_ENTRY_MEM0:
581 			entry_point = 0x00000000;
582 			break;
583 
584 		case E132XS_ENTRY_MEM1:
585 			entry_point = 0x40000000;
586 			break;
587 
588 		case E132XS_ENTRY_MEM2:
589 			entry_point = 0x80000000;
590 			break;
591 
592 		case E132XS_ENTRY_MEM3:
593 			entry_point = 0xffffff00;
594 			break;
595 
596 		case E132XS_ENTRY_IRAM:
597 			entry_point = 0xc0000000;
598 			break;
599 
600 		default:
601 			log_cb(RETRO_LOG_DEBUG, LOGPRE "E1-32XS: Entry Point Error. Target not defined (= %d)\n",which);
602 			break;
603 	}
604 }
605 
immediate_value(void)606 INT32 immediate_value(void)
607 {
608 	INT16 imm1, imm2;
609 	INT32 ret;
610 
611 	switch( N_VALUE )
612 	{
613 		case 0:	case 1:  case 2:  case 3:  case 4:  case 5:  case 6:  case 7: case 8:
614 		case 9:	case 10: case 11: case 12: case 13: case 14: case 15: case 16:
615 			return N_VALUE;
616 
617 		case 17:
618 			PC += 2;
619 			imm1 = READ_OP(PC);
620 			PC += 2;
621 			imm2 = READ_OP(PC);
622 			ret = (imm1 << 16) | imm2;
623 			return ret;
624 
625 
626 		case 18:
627 			PC += 2;
628 			ret = (UINT32) READ_OP(PC);
629 			return ret;
630 
631 		case 19:
632 			PC += 2;
633 			ret = 0xffff0000 | ((INT32) READ_OP(PC));
634 			return ret;
635 
636 		case 20:
637 			return 32;	/*bit 5 = 1, others = 0*/
638 
639 		case 21:
640 			return 64;	/*bit 6 = 1, others = 0*/
641 
642 		case 22:
643 			return 128; /*bit 7 = 1, others = 0*/
644 
645 		case 23:
646 			return 0x80000000; /*bit 31 = 1, others = 0 (2 at the power of 31)*/
647 
648 		case 24:
649 			return -8;
650 
651 		case 25:
652 			return -7;
653 
654 		case 26:
655 			return -6;
656 
657 		case 27:
658 			return -5;
659 
660 		case 28:
661 			return -4;
662 
663 		case 29:
664 			return -3;
665 
666 		case 30:
667 			return -2;
668 
669 		case 31:
670 			return -1;
671 	}
672 
673 	return 0; /*it should never executed*/
674 }
675 
get_const(void)676 INT32 get_const(void)
677 {
678 	INT32 const_val;
679 	INT16 imm1;
680 
681 	PC += 2;
682 	imm1 = READ_OP(PC);
683 
684 	if( E_BIT(imm1) )
685 	{
686 		INT16 imm2;
687 
688 		PC += 2;
689 		imm2 = READ_OP(PC);
690 
691 		const_val = imm2;
692 		const_val |= ((imm1 & 0x3fff) << 16 );
693 
694 		if( S_BIT_CONST(imm1) )
695 		{
696 			const_val |= 0xc0000000;
697 		}
698 	}
699 	else
700 	{
701 		const_val = imm1 & 0x3fff;
702 
703 		if( S_BIT_CONST(imm1) )
704 		{
705 			const_val |= 0xffffc000;
706 		}
707 	}
708 
709 	return const_val;
710 }
711 
get_pcrel(void)712 INT32 get_pcrel(void)
713 {
714 	INT32 ret;
715 
716 	if( OP & 0x80 )
717 	{
718 		UINT16 next;
719 		PC += 2;
720 		next = READ_OP(PC);
721 
722 		ret = (OP & 0x7f) << 16;
723 
724 		ret |= (next & 0xfffe);
725 
726 		if( next & 1 )
727 			ret |= 0xff800000;
728 	}
729 	else
730 	{
731 		ret = OP & 0x7e;
732 
733 		if( OP & 1 )
734 			ret |= 0xffffff80;
735 	}
736 
737 	return ret;
738 }
739 
get_dis(UINT32 val)740 INT32 get_dis(UINT32 val )
741 {
742 	INT32 ret;
743 
744 	if( E_BIT(val) )
745 	{
746 		UINT16 next;
747 
748 		PC += 2;
749 
750 		next = READ_OP(PC);
751 
752 		ret = next;
753 		ret |= ( ( val & 0xfff ) << 16 );
754 
755 		if( S_BIT_CONST(val) )
756 		{
757 			ret |= 0xf0000000;
758 		}
759 	}
760 	else
761 	{
762 		ret = val & 0xfff;
763 		if( S_BIT_CONST(val) )
764 		{
765 			ret |= 0xfffff000;
766 		}
767 	}
768 
769 	return ret;
770 }
771 
execute_br(INT32 rel)772 void execute_br(INT32 rel)
773 {
774 	/* Reip - TODO: if in get_pcrel() is read the next pc, do i need to increment the pc?*/
775 	/* MooglyGuy - No, you need to decrement it by two, since after e132xs_execute() you'll
776 	               be incrementing PC by two. If you don't decrement, it'll skip over the
777 	               next opcode. See below. */
778 	PPC = PC;
779 	PC += rel;
780 /*	PC -= 2;*/
781 	SET_M(0);
782 
783 	/*TODO: change when there's latency*/
784 /*	if target is on-chip cache*/
785 	e132xs_ICount -= 2;
786 /*	else 2 + memory read latency*/
787 
788 }
789 
execute_dbr(INT32 rel)790 void execute_dbr(INT32 rel)
791 {
792 	/* Reip - TODO: if in get_pcrel() is read the next pc, do i need to increment the pc?*/
793 	/*              block all the exception except the reset*/
794 	/* MooglyGuy - Well, I'm not quite sure about that. */
795 
796 	e132xs.delay_pc = PC + rel;
797 	e132xs.delay    = DELAY_TAKEN;
798 
799 	/*TODO: change when there's latency*/
800 /*	if target in on-chip cache*/
801 	e132xs_ICount -= 1;
802 /*	else 1 + memory read latency cycles exceeding (dealy instruction cycles - 1)*/
803 }
804 
execute_trap(UINT32 addr)805 void execute_trap(UINT32 addr)
806 {
807 	UINT32 write_addr;
808 
809 	write_addr = GET_FP + GET_FL;
810 	WRITE_W(write_addr, (PC & 0xfffffffe) | GET_S);
811 	WRITE_W(write_addr + 1, SR); /*TODO: or +4 because it's 32bit?*/
812 	SET_FP(write_addr);
813 	SET_FL(6);
814 	SET_M(0);
815 	SET_T(0);
816 	SET_L(1);
817 	SET_S(1);
818 	PPC = PC;
819 	PC = addr;
820 	PC -= 2;
821 
822 	e132xs_ICount -= 2;	/* TODO: + delay...*/
823 }
824 
e132xs_init(void)825 void e132xs_init(void)
826 {
827 	int cpu = cpu_getactivecpu();
828 
829 	/*TODO: add the reserved registers too? and the local registers too?*/
830 
831 	state_save_register_UINT32("e132xs", cpu, "PC",  &PC,  1);
832 	state_save_register_UINT32("e132xs", cpu, "SR",  &SR,  1);
833 	state_save_register_UINT32("e132xs", cpu, "FER", &FER, 1);
834 	state_save_register_UINT32("e132xs", cpu, "SP",  &SP,  1);
835 	state_save_register_UINT32("e132xs", cpu, "UB",  &UB,  1);
836 	state_save_register_UINT32("e132xs", cpu, "BCR", &BCR, 1);
837 	state_save_register_UINT32("e132xs", cpu, "TPR", &TPR, 1);
838 	state_save_register_UINT32("e132xs", cpu, "TCR", &TCR, 1);
839 	state_save_register_UINT32("e132xs", cpu, "TR",  &TR,  1);
840 	state_save_register_UINT32("e132xs", cpu, "WCR", &WCR, 1);
841 	state_save_register_UINT32("e132xs", cpu, "ISR", &ISR, 1);
842 	state_save_register_UINT32("e132xs", cpu, "FCR", &FCR, 1);
843 	state_save_register_UINT32("e132xs", cpu, "MCR", &MCR, 1);
844 }
845 
e132xs_reset(void * param)846 void e132xs_reset(void *param)
847 {
848 	/*TODO: other to do at reset?*/
849 
850 	SET_S(1);
851 	SET_FL(6);
852 	SET_FP(1);
853 
854 	PC = get_trap_addr(RESET);
855 }
856 
e132xs_exit(void)857 void e132xs_exit(void)
858 {
859 	/* nothing */
860 }
861 
e132xs_execute(int cycles)862 int e132xs_execute(int cycles)
863 {
864 	e132xs_ICount = cycles;
865 
866 	do
867 	{
868 		PPC = PC;	/* copy PC to previous PC */
869 
870 		if( e132xs.delay == DELAY_EXECUTE )
871 		{
872 			/*TODO: should i use change_pc32bedw or something similar?*/
873 			PC = e132xs.delay_pc;
874 			e132xs.delay_pc = 0;
875 			e132xs.delay = NO_DELAY;
876 		}
877 
878 		CALL_MAME_DEBUG;
879 
880 		OP = READ_OP(PC);
881 
882 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Executing opcode %04x at PC %08x\n", OP, PC );
883 
884 		if(GET_H)
885 		{
886 			h_clear = 1;
887 		}
888 
889 		e132xs_op[(OP & 0xff00) >> 8]();
890 
891 		if(h_clear == 1)
892 		{
893 			SET_H(0);
894 			h_clear = 0;
895 		}
896 
897 		PC += 2;
898 
899 		if( e132xs.delay == DELAY_TAKEN )
900 		{
901 			e132xs.delay--;
902 		}
903 
904 	} while( e132xs_ICount > 0 );
905 
906 	return cycles - e132xs_ICount;  /*TODO: check this*/
907 }
908 
e132xs_get_context(void * regs)909 unsigned e132xs_get_context(void *regs)
910 {
911 	/* copy the context */
912 	if( regs )
913 		*(e132xs_regs *)regs = e132xs;
914 
915 	/* return the context size */
916 	return sizeof(e132xs_regs);
917 }
918 
e132xs_set_context(void * regs)919 void e132xs_set_context(void *regs)
920 {
921 	/* copy the context */
922 	if (regs)
923 		e132xs = *(e132xs_regs *)regs;
924 
925 	/*TODO: other to do? check interrupt?*/
926 
927 }
928 
e132xs_get_reg(int regnum)929 unsigned e132xs_get_reg(int regnum)
930 {
931 	switch( regnum )
932 	{
933 		case REG_PC:
934 		case E132XS_PC:			return PC;
935 		case E132XS_SR:			return SR;
936 		case E132XS_FER:		return FER;
937 		case REG_SP:
938 		case E132XS_SP:			return SP;
939 		case E132XS_UB:			return UB;
940 		case E132XS_BCR:		return BCR;
941 		case E132XS_TPR:		return TPR;
942 		case E132XS_TCR:		return TCR;
943 		case E132XS_TR:			return TR;
944 		case E132XS_WCR:		return WCR;
945 		case E132XS_ISR:		return ISR;
946 		case E132XS_FCR:		return FCR;
947 
948 		case REG_PREVIOUSPC:	return PPC;
949 
950 		default:
951 			if (regnum <= REG_SP_CONTENTS)
952 			{
953 				/*TODO: add stack*/
954 			}
955 	}
956 
957 	return 0;
958 }
959 
e132xs_set_reg(int regnum,unsigned val)960 void e132xs_set_reg(int regnum, unsigned val)
961 {
962 	switch( regnum )
963 	{
964 		case REG_PC:
965 		case E132XS_PC:			PC  = val;	break;
966 		case E132XS_SR:			SR  = val;	break;
967 		case E132XS_FER:		FER = val;	break;
968 		case REG_SP:
969 		case E132XS_SP:			SP  = val;	break;
970 		case E132XS_UB:			UB  = val;	break;
971 		case E132XS_BCR:		BCR = val;	break;
972 		case E132XS_TPR:		TPR = val;	break;
973 		case E132XS_TCR:		TCR = val;	break;
974 		case E132XS_TR:			TR  = val;	break;
975 		case E132XS_WCR:		WCR = val;	break;
976 		case E132XS_ISR:		ISR = val;	break;
977 		case E132XS_FCR:		FCR = val;	break;
978 
979 		default:
980 			if (regnum <= REG_SP_CONTENTS)
981 			{
982 				/*TODO: add stack*/
983 			}
984 	}
985 
986 }
987 
e132xs_set_irq_line(int irqline,int state)988 void e132xs_set_irq_line(int irqline, int state)
989 {
990 }
991 
e132xs_set_irq_callback(int (* callback)(int irqline))992 void e132xs_set_irq_callback(int (*callback)(int irqline))
993 {
994 }
995 
e132xs_info(void * context,int regnum)996 const char *e132xs_info(void *context, int regnum)
997 {
998 	static char buffer[16][47+1]; /* TODO: check the length!*/
999 	static int which = 0;
1000 	e132xs_regs *r = context;
1001 
1002 	which = (which+1) % 16;
1003 	buffer[which][0] = '\0';
1004 	if( !context )
1005 		r = &e132xs;
1006 
1007 	switch (regnum)
1008 	{
1009 		case CPU_INFO_REG+E132XS_PC:  sprintf(buffer[which], "PC:%08X",  r->global_regs[0]); break;
1010 		case CPU_INFO_REG+E132XS_SR:  sprintf(buffer[which], "SR:%08X",  r->global_regs[1]); break;
1011 		case CPU_INFO_REG+E132XS_FER: sprintf(buffer[which], "FER:%08X", r->global_regs[2]); break;
1012 		case CPU_INFO_REG+E132XS_SP:  sprintf(buffer[which], "SP:%08X",  r->global_regs[18]); break;
1013 		case CPU_INFO_REG+E132XS_UB:  sprintf(buffer[which], "UB:%08X",  r->global_regs[19]); break;
1014 		case CPU_INFO_REG+E132XS_BCR: sprintf(buffer[which], "BCR:%08X", r->global_regs[20]); break;
1015 		case CPU_INFO_REG+E132XS_TPR: sprintf(buffer[which], "TPR:%08X", r->global_regs[21]); break;
1016 		case CPU_INFO_REG+E132XS_TCR: sprintf(buffer[which], "TCR:%08X", r->global_regs[22]); break;
1017 		case CPU_INFO_REG+E132XS_TR:  sprintf(buffer[which], "TR:%08X",  r->global_regs[23]); break;
1018 		case CPU_INFO_REG+E132XS_WCR: sprintf(buffer[which], "WCR:%08X", r->global_regs[24]); break;
1019 		case CPU_INFO_REG+E132XS_ISR: sprintf(buffer[which], "ISR:%08X", r->global_regs[25]); break;
1020 		case CPU_INFO_REG+E132XS_FCR: sprintf(buffer[which], "FCR:%08X", r->global_regs[26]); break;
1021 		case CPU_INFO_REG+E132XS_MCR: sprintf(buffer[which], "MCR:%08X", r->global_regs[27]); break;
1022 		case CPU_INFO_REG+E132XS_G0:  sprintf(buffer[which], "G0 :%08X", r->global_regs[0]); break;
1023 		case CPU_INFO_REG+E132XS_G1:  sprintf(buffer[which], "G1 :%08X", r->global_regs[1]); break;
1024 		case CPU_INFO_REG+E132XS_G2:  sprintf(buffer[which], "G2 :%08X", r->global_regs[2]); break;
1025 		case CPU_INFO_REG+E132XS_G3:  sprintf(buffer[which], "G3 :%08X", r->global_regs[3]); break;
1026 		case CPU_INFO_REG+E132XS_G4:  sprintf(buffer[which], "G4 :%08X", r->global_regs[4]); break;
1027 		case CPU_INFO_REG+E132XS_G5:  sprintf(buffer[which], "G5 :%08X", r->global_regs[5]); break;
1028 		case CPU_INFO_REG+E132XS_G6:  sprintf(buffer[which], "G6 :%08X", r->global_regs[6]); break;
1029 		case CPU_INFO_REG+E132XS_G7:  sprintf(buffer[which], "G7 :%08X", r->global_regs[7]); break;
1030 		case CPU_INFO_REG+E132XS_G8:  sprintf(buffer[which], "G8 :%08X", r->global_regs[8]); break;
1031 		case CPU_INFO_REG+E132XS_G9:  sprintf(buffer[which], "G9 :%08X", r->global_regs[9]); break;
1032 		case CPU_INFO_REG+E132XS_G10: sprintf(buffer[which], "G10:%08X", r->global_regs[10]); break;
1033 		case CPU_INFO_REG+E132XS_G11: sprintf(buffer[which], "G11:%08X", r->global_regs[11]); break;
1034 		case CPU_INFO_REG+E132XS_G12: sprintf(buffer[which], "G12:%08X", r->global_regs[12]); break;
1035 		case CPU_INFO_REG+E132XS_G13: sprintf(buffer[which], "G13:%08X", r->global_regs[13]); break;
1036 		case CPU_INFO_REG+E132XS_G14: sprintf(buffer[which], "G14:%08X", r->global_regs[14]); break;
1037 		case CPU_INFO_REG+E132XS_G15: sprintf(buffer[which], "G15:%08X", r->global_regs[15]); break;
1038 		case CPU_INFO_REG+E132XS_L0:  sprintf(buffer[which], "L0 :%08X", r->local_regs[0]); break;
1039 		case CPU_INFO_REG+E132XS_L1:  sprintf(buffer[which], "L1 :%08X", r->local_regs[1]); break;
1040 		case CPU_INFO_REG+E132XS_L2:  sprintf(buffer[which], "L2 :%08X", r->local_regs[2]); break;
1041 		case CPU_INFO_REG+E132XS_L3:  sprintf(buffer[which], "L3 :%08X", r->local_regs[3]); break;
1042 		case CPU_INFO_REG+E132XS_L4:  sprintf(buffer[which], "L4 :%08X", r->local_regs[4]); break;
1043 		case CPU_INFO_REG+E132XS_L5:  sprintf(buffer[which], "L5 :%08X", r->local_regs[5]); break;
1044 		case CPU_INFO_REG+E132XS_L6:  sprintf(buffer[which], "L6 :%08X", r->local_regs[6]); break;
1045 		case CPU_INFO_REG+E132XS_L7:  sprintf(buffer[which], "L7 :%08X", r->local_regs[7]); break;
1046 		case CPU_INFO_REG+E132XS_L8:  sprintf(buffer[which], "L8 :%08X", r->local_regs[8]); break;
1047 		case CPU_INFO_REG+E132XS_L9:  sprintf(buffer[which], "L9 :%08X", r->local_regs[9]); break;
1048 		case CPU_INFO_REG+E132XS_L10: sprintf(buffer[which], "L10:%08X", r->local_regs[10]); break;
1049 		case CPU_INFO_REG+E132XS_L11: sprintf(buffer[which], "L11:%08X", r->local_regs[11]); break;
1050 		case CPU_INFO_REG+E132XS_L12: sprintf(buffer[which], "L12:%08X", r->local_regs[12]); break;
1051 		case CPU_INFO_REG+E132XS_L13: sprintf(buffer[which], "L13:%08X", r->local_regs[13]); break;
1052 		case CPU_INFO_REG+E132XS_L14: sprintf(buffer[which], "L14:%08X", r->local_regs[14]); break;
1053 		case CPU_INFO_REG+E132XS_L15: sprintf(buffer[which], "L15:%08X", r->local_regs[15]); break;
1054 		case CPU_INFO_FLAGS:
1055 			sprintf(buffer[which], "%c%c%c%c%c%c%c%c%c%c%c%c FTE:%x FRM:%x ILC:%x FL:%x FP:%x",
1056 				r->global_regs[1] & 0x40000 ? 'S':'.',
1057 				r->global_regs[1] & 0x20000 ? 'P':'.',
1058 				r->global_regs[1] & 0x10000 ? 'T':'.',
1059 				r->global_regs[1] & 0x80000 ? 'L':'.',
1060 				r->global_regs[1] & 0x00080 ? 'I':'.',
1061 				r->global_regs[1] & 0x00040 ? '?':'.',
1062 				r->global_regs[1] & 0x00020 ? 'H':'.',
1063 				r->global_regs[1] & 0x00010 ? 'M':'.',
1064 				r->global_regs[1] & 0x00008 ? 'V':'.',
1065 				r->global_regs[1] & 0x00004 ? 'N':'.',
1066 				r->global_regs[1] & 0x00002 ? 'Z':'.',
1067 				r->global_regs[1] & 0x00001 ? 'C':'.',
1068 				(r->global_regs[1] & 0x00001f00)>>8,
1069 				(r->global_regs[1] & 0x00006000)>>13,
1070 				(r->global_regs[1] & 0x00180000)>>19,
1071 				(r->global_regs[1] & 0x01e00000)>>21,
1072 				(r->global_regs[1] & 0xfe000000)>>25);
1073 			break;
1074 
1075 		case CPU_INFO_NAME: return "E1-32XS";
1076 		case CPU_INFO_FAMILY: return "Hyperstone E1-32XS";
1077 		case CPU_INFO_VERSION: return "0.1";
1078 		case CPU_INFO_FILE: return __FILE__;
1079 		case CPU_INFO_CREDITS: return "Copyright Pierpaolo Prazzoli and Ryan Holtz";
1080 		case CPU_INFO_REG_LAYOUT: return (const char *)e132xs_reg_layout;
1081 		case CPU_INFO_WIN_LAYOUT: return (const char *)e132xs_win_layout;
1082 	}
1083 	return buffer[which];
1084 }
1085 
e132xs_dasm(char * buffer,unsigned pc)1086 unsigned e132xs_dasm(char *buffer, unsigned pc)
1087 {
1088 #ifdef MAME_DEBUG
1089 	return dasm_e132xs( buffer, pc );
1090 #else
1091 	sprintf(buffer, "$%08x", READ_OP(pc));
1092 	return 1;
1093 #endif
1094 }
1095 
1096 
1097 /* Opcodes */
1098 /*TODO: Add the opcodes inline?*/
1099 
e132xs_chk(void)1100 void e132xs_chk(void)
1101 {
1102 	UINT32 val1, val2;
1103 
1104 	if( S_BIT )
1105 	{
1106 		val1 = GET_L_REG(S_CODE);
1107 	}
1108 	else
1109 	{
1110 		val1 = GET_G_REG(S_CODE);
1111 	}
1112 
1113 	if( D_BIT )
1114 	{
1115 		val2 = GET_L_REG(D_CODE);
1116 	}
1117 	else
1118 	{
1119 		val2 = GET_G_REG(D_CODE);
1120 	}
1121 
1122 	/*TODO: test it with Rs = PC and CHK, PC, PC*/
1123 
1124 	/*if CHK, L0, L0 -> NOP, only in the debugger, here it's the same*/
1125 	if( (!(S_CODE == SR_CODE && !S_BIT) && (val2 > val1)) || ((S_CODE == SR_CODE && !S_BIT) && (val2 == 0)) )
1126 	{
1127 		UINT32 addr = get_trap_addr(RANGE_ERROR);
1128 		execute_trap(addr);
1129 	}
1130 	if((S_CODE == PC_CODE && !S_BIT) && (D_CODE == PC_CODE && !D_BIT))
1131 	{
1132 		UINT32 addr = get_trap_addr(RANGE_ERROR);
1133 		execute_trap(addr);
1134 	}
1135 
1136 	e132xs_ICount -= 1;
1137 }
1138 
e132xs_movd(void)1139 void e132xs_movd(void)
1140 {
1141 	/*Rd denotes PC*/
1142 	if( D_CODE == PC_CODE && !D_BIT )
1143 	{
1144 		/* RET instruction*/
1145 
1146 		unsigned char old_s, old_l;
1147 		UINT8 difference; /*really it's 7 bits*/
1148 
1149 		if( (S_CODE == PC_CODE && !S_BIT) || (S_CODE == SR_CODE && !S_BIT) )
1150 		{	/*future expansion*/
1151 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC or SR used in RET instruction @ %x\n", PC );
1152 		}
1153 		else
1154 		{
1155 			old_s = GET_S;
1156 			old_l = GET_L;
1157 			PPC = PC;
1158 
1159 			if( S_BIT )
1160 			{
1161 				PC = GET_L_REG(S_CODE) & 0xfffffffe;
1162 				SR = (GET_L_REG(S_CODE + INC) & 0xffe00000) | ((GET_L_REG(S_CODE) & 0x01) << 18 ) | (GET_L_REG(S_CODE + INC) & 0x3ffff);
1163 				SET_S(GET_L_REG(S_CODE) & 0x01);
1164 			}
1165 			else
1166 			{
1167 				PC = GET_G_REG(S_CODE) & 0xfffffffe;
1168 				SR = (GET_G_REG(S_CODE + INC) & 0xffe00000) | ((GET_G_REG(S_CODE) & 0x01) << 18 ) | (GET_G_REG(S_CODE + INC) & 0x3ffff);
1169 				SET_S(GET_G_REG(S_CODE) & 0x01);
1170 			}
1171 
1172 			SET_ILC(0);
1173 
1174 			if( (!old_s && GET_S) || (!GET_S && !old_l && GET_L))
1175 			{
1176 				UINT32 addr = get_trap_addr(PRIVILEGE_ERROR);
1177 				execute_trap(addr);
1178 			}
1179 
1180 			difference = GET_FP - ( ( SP & 0x1fc ) >> 2 );
1181 
1182 			/* bit 6 of difference is sign*/
1183 			if( difference & 0x40 ) /*else it's finished*/
1184 			{
1185 				do
1186 				{
1187 					SP -= 4;
1188 
1189 					SET_L_REG( ( SP & 0xfc ), READ_W( SP ) );
1190 
1191 					difference++;
1192 					difference = ((difference & 0x7f) + ((difference & 0x80) >> 7)) & 0x7f; /*TODO: ok?*/
1193 
1194 				} while( !( difference & 0x40 ) );
1195 			}
1196 		}
1197 
1198 		/*TODO: no 1!*/
1199 		e132xs_ICount -= 1;
1200 	}
1201 	/*Rd doesn't denote PC and Rs denotes SR*/
1202 	else if( S_CODE == SR_CODE && !S_BIT )
1203 	{
1204 		SET_RD(0, NOINC);
1205 		SET_RD(0, INC);
1206 		SET_Z(1);
1207 		SET_N(0);
1208 		/*SET_V(); */ /*undefined*/
1209 
1210 		e132xs_ICount -= 2;
1211 	}
1212 	/*Rd doesn't denote PC and Rs doesn't denote SR*/
1213 	else
1214 	{
1215 		UINT32 val1, val2;
1216 		UINT64 tmp;
1217 
1218 		if( S_BIT )
1219 		{
1220 			val1 = GET_L_REG(S_CODE);
1221 			val2 = GET_L_REG(S_CODE + INC);
1222 		}
1223 		else
1224 		{
1225 			val1 = GET_G_REG(S_CODE);
1226 			val2 = GET_G_REG(S_CODE + INC);
1227 		}
1228 
1229 		SET_RD(val1, NOINC);
1230 		SET_RD(val2, INC);
1231 		tmp = COMBINE_U64_U32_U32(val1, val2);
1232 		SET_Z(tmp == 0 ? 1 : 0);
1233 		SET_N(SIGN_BIT(val1));
1234 		/*SET_V(); */ /*undefined*/
1235 
1236 		e132xs_ICount -= 2;
1237 	}
1238 }
1239 
e132xs_divu(void)1240 void e132xs_divu(void)
1241 {
1242 	UINT64 dividend;
1243 	UINT32 dividend_low, dividend_high;
1244 	UINT32 divisor;
1245 
1246 	/*TODO: can D_CODE be PC or SR?*/
1247 
1248 	if( S_CODE == D_CODE && S_CODE == (D_CODE + INC) )
1249 	{
1250 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted the same register code in DIVU instruction @ %x\n", PC );
1251 	}
1252 	else
1253 	{
1254 		if( (S_CODE == PC_CODE && !S_BIT) && (S_CODE == SR_CODE && !S_BIT) )
1255 		{
1256 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC / SR as source register in DIVU instruction @ %x\n", PC );
1257 		}
1258 		else
1259 		{
1260 			if( S_BIT )
1261 			{
1262 				divisor = GET_L_REG(S_CODE);
1263 			}
1264 			else
1265 			{
1266 				divisor = GET_G_REG(S_CODE);
1267 			}
1268 
1269 			if( D_BIT )
1270 			{
1271 				dividend_high = GET_L_REG(D_CODE);
1272 				dividend_low  = GET_L_REG(D_CODE + INC);
1273 			}
1274 			else
1275 			{
1276 				dividend_high = GET_G_REG(D_CODE);
1277 				dividend_low  = GET_G_REG(D_CODE + INC);
1278 			}
1279 
1280 			dividend = COMBINE_U64_U32_U32(dividend_high, dividend_low);
1281 
1282 			if( divisor == 0 || dividend > 0xffffffff )
1283 			{
1284 				/*Rd*/ /*Rdf -> undefined*/
1285 				/*Z -> undefined*/
1286 				/*N -> undefined*/
1287 				UINT32 addr;
1288 				SET_V(1);
1289 				addr = get_trap_addr(RANGE_ERROR);
1290 				execute_trap(addr);
1291 			}
1292 			else
1293 			{
1294 				UINT32 quotient, remainder;
1295 
1296 				quotient = dividend / divisor;
1297 				remainder = dividend % divisor;
1298 
1299 				SET_RD( remainder, NOINC );
1300 				SET_RD( quotient, INC );
1301 				SET_Z((quotient == 0 ? 1 : 0));
1302 				SET_N(SIGN_BIT(quotient));
1303 				SET_V(0);
1304 			}
1305 		}
1306 	}
1307 
1308 	e132xs_ICount -= 36;
1309 }
1310 
e132xs_divs(void)1311 void e132xs_divs(void)
1312 {
1313 	INT64 dividend;
1314 	INT32 dividend_low, dividend_high;
1315 	INT32 divisor;
1316 
1317 	/*TODO: can D_CODE be PC or SR?*/
1318 
1319 	if( S_CODE == D_CODE && S_CODE == (D_CODE + INC) )
1320 	{
1321 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted the same register code in DIVS instruction @ %x\n", PC );
1322 	}
1323 	else
1324 	{
1325 		if( (S_CODE == PC_CODE && !S_BIT) && (S_CODE == SR_CODE && !S_BIT) )
1326 		{
1327 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC / SR as source register in DIVS instruction @ %x\n", PC );
1328 		}
1329 		else
1330 		{
1331 			if( S_BIT )
1332 			{
1333 				divisor = GET_L_REG(S_CODE);
1334 			}
1335 			else
1336 			{
1337 				divisor = GET_G_REG(S_CODE);
1338 			}
1339 
1340 			if( D_BIT )
1341 			{
1342 				dividend_high = GET_L_REG(D_CODE);
1343 				dividend_low  = GET_L_REG(D_CODE + INC);
1344 			}
1345 			else
1346 			{
1347 				dividend_high = GET_G_REG(D_CODE);
1348 				dividend_low  = GET_G_REG(D_CODE + INC);
1349 			}
1350 
1351 			dividend = (INT64) COMBINE_64_32_32(dividend_high, dividend_low);
1352 
1353 			if( divisor == 0 || dividend > 0xffffffff || (dividend_high & 0x80000000) )
1354 			{
1355 				/*Rd*/ /*Rdf -> undefined*/
1356 				/*Z -> undefined*/
1357 				/*N -> undefined*/
1358 				UINT32 addr;
1359 				SET_V(1);
1360 				addr = get_trap_addr(RANGE_ERROR);
1361 				execute_trap(addr);
1362 			}
1363 			else
1364 			{
1365 				INT32 quotient, remainder;
1366 
1367 				quotient = dividend / divisor;
1368 				remainder = dividend % divisor;
1369 				/*a non-zero remainder has the sign bit of the dividend*/
1370 				/*TODO: add the above comment? isn't the dividend non-negative signed?*/
1371 
1372 				SET_RD( remainder, NOINC );
1373 				SET_RD( quotient, INC );
1374 				SET_Z((quotient == 0 ? 1 : 0));
1375 				SET_N(SIGN_BIT(quotient));
1376 				SET_V(0);
1377 			}
1378 		}
1379 	}
1380 
1381 	e132xs_ICount -= 36;
1382 }
1383 
e132xs_xm(void)1384 void e132xs_xm(void)
1385 {
1386 	UINT32 val;
1387 	UINT16 next_source;
1388 	unsigned int x_code, lim;
1389 
1390 	if( S_BIT )
1391 	{
1392 		val = GET_L_REG(S_CODE);
1393 	}
1394 	else
1395 	{
1396 		val = GET_G_REG(S_CODE);
1397 	}
1398 
1399 	PC += 2;
1400 
1401 	next_source = READ_OP(PC);
1402 
1403 	x_code = X_CODE(next_source);
1404 
1405 	if( E_BIT(next_source) )
1406 	{
1407 		UINT16 next_source_2;
1408 
1409 		PC += 2;
1410 
1411 		next_source_2 = READ_OP(PC);
1412 
1413 		lim = ((next_source & 0xfff) << 5 ) | next_source_2;
1414 	}
1415 	else
1416 	{
1417 		lim = next_source & 0xfff;
1418 	}
1419 
1420 	switch( x_code )
1421 	{
1422 		case 0:
1423 		case 1:
1424 		case 2:
1425 		case 3:
1426 			if( val > lim )
1427 			{
1428 				UINT32 addr = get_trap_addr(RANGE_ERROR);
1429 				execute_trap(addr);
1430 			}
1431 			else
1432 			{
1433 				val <<= x_code;
1434 			}
1435 
1436 			break;
1437 
1438 		case 4:
1439 		case 5:
1440 		case 6:
1441 		case 7:
1442 			x_code -= 4;
1443 			val <<= x_code;
1444 
1445 			break;
1446 	}
1447 
1448 	SET_RD(val, NOINC);
1449 
1450 	e132xs_ICount -= 1;
1451 }
1452 
e132xs_mask(void)1453 void e132xs_mask(void)
1454 {
1455 	INT32 val, const_val;
1456 
1457 	if( S_BIT )
1458 	{
1459 		val = GET_L_REG(S_CODE);
1460 	}
1461 	else
1462 	{
1463 		val = GET_G_REG(S_CODE);
1464 	}
1465 
1466 	const_val = get_const();
1467 
1468 	val &= const_val;
1469 
1470 	SET_RD(val, NOINC);
1471 
1472 	SET_Z((val == 0 ? 1: 0));
1473 
1474 	e132xs_ICount -= 1;
1475 }
1476 
e132xs_sum(void)1477 void e132xs_sum(void)
1478 {
1479 	UINT32 op1;
1480 	INT32 const_val;
1481 
1482 	if( S_BIT )
1483 	{
1484 		op1 = GET_L_REG(S_CODE);
1485 	}
1486 	else
1487 	{
1488 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1489 			op1 = GET_C;
1490 		else
1491 			op1 = GET_G_REG(S_CODE);
1492 	}
1493 
1494 	const_val = get_const();
1495 
1496 	if(D_CODE == PC_CODE && !D_BIT)
1497 		PC -= 2;
1498 
1499 	op1 += const_val;
1500 	SET_RD(op1, NOINC);
1501 	SET_Z((op1 == 0 ? 1: 0));
1502 	SET_N(SIGN_BIT(op1)); /*sign*/
1503 /*	SET_V(); */ /*TODO!*/
1504 /*	SET_C(); */ /*carry //TODO!*/
1505 
1506 	e132xs_ICount -= 1;
1507 }
1508 
e132xs_sums(void)1509 void e132xs_sums(void)
1510 {
1511 	INT32 op1, const_val;
1512 
1513 	if( S_BIT )
1514 	{
1515 		op1 = GET_L_REG(S_CODE);
1516 	}
1517 	else
1518 	{
1519 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1520 			op1 = GET_C;
1521 		else
1522 			op1 = GET_G_REG(S_CODE);
1523 	}
1524 
1525 	const_val = get_const();
1526 
1527 	op1 += const_val;
1528 	SET_RD(op1, NOINC);
1529 	SET_Z((op1 == 0 ? 1: 0));
1530 	SET_N(SIGN_BIT(op1)); /*sign*/
1531 /*	SET_V(); */ /*TODO!*/
1532 
1533 	e132xs_ICount -= 1;
1534 
1535 	if( GET_V && S_CODE != 1 )
1536 	{
1537 		UINT32 addr = get_trap_addr(RANGE_ERROR);
1538 		execute_trap(addr);
1539 	}
1540 }
1541 
e132xs_cmp(void)1542 void e132xs_cmp(void)
1543 {
1544 	UINT32 op1, op2;
1545 
1546 	if( S_BIT )
1547 	{
1548 		op1 = GET_L_REG(S_CODE);
1549 	}
1550 	else
1551 	{
1552 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1553 			op1 = GET_C;
1554 		else
1555 			op1 = GET_G_REG(S_CODE);
1556 	}
1557 
1558 	if( D_BIT )
1559 	{
1560 		op2 = GET_L_REG(D_CODE);
1561 	}
1562 	else
1563 	{
1564 		op2 = GET_G_REG(D_CODE);
1565 	}
1566 
1567 	if( op1 == op2 )
1568 		SET_Z(1);
1569 	else
1570 		SET_Z(0);
1571 
1572 	if( (INT32) op2 < (INT32) op1 )	/*TODO: should it be if( op2 < (INT32) op1 ) or is the one already implemented?*/
1573 		SET_N(1);
1574 	else
1575 		SET_N(0);
1576 
1577 /*	SET_V(); */ /*TODO!*/
1578 
1579 	if( op2 < op1 )
1580 		SET_C(1); /*borrow*/
1581 	else
1582 		SET_C(0); /*borrow*/
1583 
1584 	e132xs_ICount -= 1;
1585 }
1586 
e132xs_mov(void)1587 void e132xs_mov(void)
1588 {
1589 	UINT32 val;
1590 
1591 	if( S_BIT )
1592 	{
1593 		val = GET_L_REG(S_CODE);
1594 	}
1595 	else
1596 	{
1597 		if( !GET_H )
1598 		{
1599 			val = GET_G_REG(S_CODE);
1600 		}
1601 		else
1602 		{
1603 			UINT8 s_code = S_CODE + 16;
1604 
1605 			if( !(s_code == REG_BCR || s_code == REG_TPR || s_code == REG_FCR || s_code == REG_MCR) )
1606 			{
1607 				val = GET_G_REG(s_code);
1608 			}
1609 			else
1610 			{
1611 				/* Write only registers */
1612 				val = 0;
1613 			}
1614 		}
1615 	}
1616 
1617 	if( D_BIT )
1618 	{
1619 		SET_L_REG(D_CODE, val);
1620 	}
1621 	else
1622 	{
1623 		if( !GET_S && GET_H )
1624 		{
1625 			UINT32 addr = get_trap_addr(PRIVILEGE_ERROR);
1626 			execute_trap(addr);
1627 		}
1628 		else
1629 		{
1630 			SET_G_REG(D_CODE + GET_H * 16, val);
1631 		}
1632 	}
1633 
1634 	if(D_CODE == PC_CODE && !D_BIT && !GET_H)
1635 		PC -= 2;
1636 
1637 	SET_Z((val == 0 ? 1: 0));
1638 	SET_N(SIGN_BIT(val));
1639 
1640 	e132xs_ICount -= 1;
1641 }
1642 
e132xs_add(void)1643 void e132xs_add(void)
1644 {
1645 	UINT32 op1, op2;
1646 
1647 	if( S_BIT )
1648 	{
1649 		op1 = GET_L_REG(S_CODE);
1650 	}
1651 	else
1652 	{
1653 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1654 			op1 = GET_C;
1655 		else
1656 			op1 = GET_G_REG(S_CODE);
1657 	}
1658 
1659 	if( D_BIT )
1660 	{
1661 		op2 = GET_L_REG(D_CODE);
1662 	}
1663 	else
1664 	{
1665 		op2 = GET_G_REG(D_CODE);
1666 	}
1667 
1668 	if(D_CODE == PC_CODE && !D_BIT)
1669 		PC -= 2;
1670 
1671 	op2 += op1;
1672 	SET_RD(op2, NOINC);
1673 	SET_Z((op2 == 0 ? 1: 0));
1674 	SET_N(SIGN_BIT(op2)); /*sign*/
1675 /*	SET_V(); */ /*TODO!*/
1676 /*	SET_C(); */ /*carry //TODO!*/
1677 
1678 	e132xs_ICount -= 1;
1679 }
1680 
e132xs_adds(void)1681 void e132xs_adds(void)
1682 {
1683 	INT32 op1, op2;
1684 
1685 	if( S_BIT )
1686 	{
1687 		op1 = GET_L_REG(S_CODE);
1688 	}
1689 	else
1690 	{
1691 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1692 			op1 = GET_C;
1693 		else
1694 			op1 = GET_G_REG(S_CODE);
1695 	}
1696 
1697 	if( D_BIT )
1698 	{
1699 		op2 = GET_L_REG(D_CODE);
1700 	}
1701 	else
1702 	{
1703 		op2 = GET_G_REG(D_CODE);
1704 	}
1705 
1706 	op2 += op1;
1707 	SET_RD(op2, NOINC);
1708 	SET_Z((op2 == 0 ? 1: 0));
1709 	SET_N(SIGN_BIT(op2)); /*sign*/
1710 /*	SET_V(); */ /*TODO!*/
1711 
1712 	e132xs_ICount -= 1;
1713 
1714 	if( GET_V )
1715 	{
1716 		UINT32 addr = get_trap_addr(RANGE_ERROR);
1717 		execute_trap(addr);
1718 	}
1719 }
1720 
e132xs_cmpb(void)1721 void e132xs_cmpb(void)
1722 {
1723 	UINT32 val1, val2;
1724 
1725 	if( S_BIT )
1726 	{
1727 		val1 = GET_L_REG(S_CODE);
1728 	}
1729 	else
1730 	{
1731 		val1 = GET_G_REG(S_CODE);
1732 	}
1733 
1734 	if( D_BIT )
1735 	{
1736 		val2 = GET_L_REG(D_CODE);
1737 	}
1738 	else
1739 	{
1740 		val2 = GET_G_REG(D_CODE);
1741 	}
1742 
1743 	SET_Z(((val1 & val2) == 0 ? 1: 0));
1744 
1745 	e132xs_ICount -= 1;
1746 }
1747 
e132xs_andn(void)1748 void e132xs_andn(void)
1749 {
1750 	UINT32 op1, op2, ret;
1751 
1752 	if( S_BIT )
1753 	{
1754 		op1 = ~GET_L_REG(S_CODE);
1755 	}
1756 	else
1757 	{
1758 		op1 = ~GET_G_REG(S_CODE);
1759 	}
1760 
1761 	if( D_BIT )
1762 	{
1763 		op2 = GET_L_REG(D_CODE);
1764 	}
1765 	else
1766 	{
1767 		op2 = GET_G_REG(D_CODE);
1768 	}
1769 
1770 	ret = op1 & op2;
1771 
1772 	SET_RD(ret, NOINC);
1773 	SET_Z((ret == 0 ? 1: 0));
1774 
1775 	e132xs_ICount -= 1;
1776 }
1777 
e132xs_or(void)1778 void e132xs_or(void)
1779 {
1780 	UINT32 op1, op2, ret;
1781 
1782 	if( S_BIT )
1783 	{
1784 		op1 = GET_L_REG(S_CODE);
1785 	}
1786 	else
1787 	{
1788 		op1 = GET_G_REG(S_CODE);
1789 	}
1790 
1791 	if( D_BIT )
1792 	{
1793 		op2 = GET_L_REG(D_CODE);
1794 	}
1795 	else
1796 	{
1797 		op2 = GET_G_REG(D_CODE);
1798 	}
1799 
1800 	ret = op1 | op2;
1801 
1802 	SET_RD(ret, NOINC);
1803 	SET_Z((ret == 0 ? 1: 0));
1804 
1805 	e132xs_ICount -= 1;
1806 }
1807 
e132xs_xor(void)1808 void e132xs_xor(void)
1809 {
1810 	UINT32 op1, op2, ret;
1811 
1812 	if( S_BIT )
1813 	{
1814 		op1 = GET_L_REG(S_CODE);
1815 	}
1816 	else
1817 	{
1818 		op1 = GET_G_REG(S_CODE);
1819 	}
1820 
1821 	if( D_BIT )
1822 	{
1823 		op2 = GET_L_REG(D_CODE);
1824 	}
1825 	else
1826 	{
1827 		op2 = GET_G_REG(D_CODE);
1828 	}
1829 
1830 	ret = op1 ^ op2;
1831 
1832 	SET_RD(ret, NOINC);
1833 	SET_Z((ret == 0 ? 1: 0));
1834 
1835 	e132xs_ICount -= 1;
1836 }
1837 
e132xs_subc(void)1838 void e132xs_subc(void)
1839 {
1840 	UINT32 op1, op2;
1841 
1842 	op1 = GET_C;
1843 	if( S_BIT )
1844 	{
1845 		op1 += GET_L_REG(S_CODE);
1846 	}
1847 	else
1848 	{
1849 		if( S_CODE != SR_CODE ) /*source doesn't denote SR*/
1850 			op1 += GET_G_REG(S_CODE);
1851 	}
1852 
1853 	if( D_BIT )
1854 	{
1855 		op2 = GET_L_REG(D_CODE);
1856 	}
1857 	else
1858 	{
1859 		op2 = GET_G_REG(D_CODE);
1860 	}
1861 
1862 	op2 -= op1;
1863 	SET_RD(op2, NOINC);
1864 	SET_Z(GET_Z & (op2 == 0 ? 1: 0));
1865 	SET_N(SIGN_BIT(op2)); /*sign*/
1866 /*	SET_V(); */ /*TODO!*/
1867 /*	SET_C(); */ /*borrow //TODO!*/
1868 
1869 	e132xs_ICount -= 1;
1870 }
1871 
e132xs_not(void)1872 void e132xs_not(void)
1873 {
1874 	UINT32 ret;
1875 
1876 	if( S_BIT )
1877 	{
1878 		ret = ~GET_L_REG(S_CODE);
1879 	}
1880 	else
1881 	{
1882 		ret = ~GET_G_REG(S_CODE);
1883 	}
1884 
1885 	SET_RD(ret, NOINC);
1886 	SET_Z((ret == 0 ? 1: 0));
1887 
1888 	e132xs_ICount -= 1;
1889 }
1890 
e132xs_sub(void)1891 void e132xs_sub(void)
1892 {
1893 	UINT32 op1, op2;
1894 
1895 	if( S_BIT )
1896 	{
1897 		op1 = GET_L_REG(S_CODE);
1898 	}
1899 	else
1900 	{
1901 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1902 			op1 = GET_C;
1903 		else
1904 			op1 = GET_G_REG(S_CODE);
1905 	}
1906 
1907 	if( D_BIT )
1908 	{
1909 		op2 = GET_L_REG(D_CODE);
1910 	}
1911 	else
1912 	{
1913 		op2 = GET_G_REG(D_CODE);
1914 	}
1915 
1916 	if(D_CODE == PC_CODE && !D_BIT)
1917 		PC -= 2;
1918 
1919 	op2 -= op1;
1920 	SET_RD(op2, NOINC);
1921 	SET_Z((op2 == 0 ? 1: 0));
1922 	SET_N(SIGN_BIT(op2)); /*sign*/
1923 /*	SET_V(); */ /*TODO!*/
1924 /*	SET_C(); */ /*borrow //TODO!*/
1925 
1926 	e132xs_ICount -= 1;
1927 }
1928 
e132xs_subs(void)1929 void e132xs_subs(void)
1930 {
1931 	INT32 op1, op2;
1932 
1933 	if( S_BIT )
1934 	{
1935 		op1 = GET_L_REG(S_CODE);
1936 	}
1937 	else
1938 	{
1939 		if( S_CODE == SR_CODE ) /*source denotes SR*/
1940 			op1 = GET_C;
1941 		else
1942 			op1 = GET_G_REG(S_CODE);
1943 	}
1944 
1945 	if( D_BIT )
1946 	{
1947 		op2 = GET_L_REG(D_CODE);
1948 	}
1949 	else
1950 	{
1951 		op2 = GET_G_REG(D_CODE);
1952 	}
1953 
1954 	op2 -= op1;
1955 	SET_RD(op2, NOINC);
1956 	SET_Z((op2 == 0 ? 1: 0));
1957 	SET_N(SIGN_BIT(op2)); /*sign*/
1958 /*	SET_V(); */ /*TODO!*/
1959 
1960 	e132xs_ICount -= 1;
1961 
1962 	if( GET_V )
1963 	{
1964 		UINT32 addr = get_trap_addr(RANGE_ERROR);
1965 		execute_trap(addr);
1966 	}
1967 }
1968 
e132xs_addc(void)1969 void e132xs_addc(void)
1970 {
1971 	UINT32 op1, op2;
1972 
1973 	op1 = GET_C;
1974 	if( S_BIT )
1975 	{
1976 		op1 += GET_L_REG(S_CODE);
1977 	}
1978 	else
1979 	{
1980 		if( S_CODE != SR_CODE ) /*source doesn't denote SR*/
1981 			op1 += GET_G_REG(S_CODE);
1982 	}
1983 
1984 	if( D_BIT )
1985 	{
1986 		op2 = GET_L_REG(D_CODE);
1987 	}
1988 	else
1989 	{
1990 		op2 = GET_G_REG(D_CODE);
1991 	}
1992 
1993 	op2 += op1;
1994 	SET_RD(op2, NOINC);
1995 	SET_Z(GET_Z & (op2 == 0 ? 1: 0));
1996 	SET_N(SIGN_BIT(op2)); /*sign*/
1997 /*	SET_V(); */ /*TODO!*/
1998 /*	SET_C(); */ /*carry //TODO!*/
1999 
2000 	e132xs_ICount -= 1;
2001 }
2002 
e132xs_and(void)2003 void e132xs_and(void)
2004 {
2005 	UINT32 op1, op2, ret;
2006 
2007 	if( S_BIT )
2008 	{
2009 		op1 = GET_L_REG(S_CODE);
2010 	}
2011 	else
2012 	{
2013 		op1 = GET_G_REG(S_CODE);
2014 	}
2015 
2016 	if( D_BIT )
2017 	{
2018 		op2 = GET_L_REG(D_CODE);
2019 	}
2020 	else
2021 	{
2022 		op2 = GET_G_REG(D_CODE);
2023 	}
2024 
2025 	ret = op1 & op2;
2026 
2027 	SET_RD(ret, NOINC);
2028 	SET_Z((ret == 0 ? 1: 0));
2029 
2030 	e132xs_ICount -= 1;
2031 }
2032 
e132xs_neg(void)2033 void e132xs_neg(void)
2034 {
2035 	UINT32 op1, op2;
2036 
2037 	if( S_BIT )
2038 	{
2039 		op1 = GET_L_REG(S_CODE);
2040 
2041 	}
2042 	else
2043 	{
2044 		if( S_CODE == SR_CODE ) /*source denote SR*/
2045 			op1 = GET_C;
2046 		else
2047 			op1 = GET_G_REG(S_CODE);
2048 	}
2049 
2050 	op2 = -op1;
2051 
2052 	SET_RD(op2, NOINC);
2053 	SET_Z(GET_Z & (op2 == 0 ? 1: 0));
2054 	SET_N(SIGN_BIT(op2)); /*sign*/
2055 /*	SET_V(); */ /*TODO!*/
2056 /*	SET_C(); */ /*carry //TODO!*/
2057 
2058 	e132xs_ICount -= 1;
2059 }
2060 
e132xs_negs(void)2061 void e132xs_negs(void)
2062 {
2063 	INT32 op1, op2;
2064 
2065 	if( S_BIT )
2066 	{
2067 		op1 = GET_L_REG(S_CODE);
2068 	}
2069 	else
2070 	{
2071 		if( S_CODE == SR_CODE ) /*source denotes SR*/
2072 			op1 = GET_C;
2073 		else
2074 			op1 = GET_G_REG(S_CODE);
2075 	}
2076 
2077 	op2 = -op1;
2078 
2079 	SET_RD(op2, NOINC);
2080 	SET_Z((op2 == 0 ? 1: 0));
2081 	SET_N(SIGN_BIT(op2)); /*sign*/
2082 /*	SET_V(); */ /*TODO!*/
2083 
2084 	e132xs_ICount -= 1;
2085 
2086 	if( GET_V && S_CODE != 1 ) /*trap doesn't occur when source is SR*/
2087 	{
2088 		UINT32 addr = get_trap_addr(RANGE_ERROR);
2089 		execute_trap(addr);
2090 	}
2091 }
2092 
e132xs_cmpi(void)2093 void e132xs_cmpi(void)
2094 {
2095 	UINT32 op1, op2;
2096 
2097 	op1 = immediate_value();
2098 
2099 	if( D_BIT )
2100 	{
2101 		op2 = GET_L_REG(D_CODE);
2102 	}
2103 	else
2104 	{
2105 		op2 = GET_G_REG(D_CODE);
2106 	}
2107 
2108 	if( op1 == op2 )
2109 		SET_Z(1);
2110 	else
2111 		SET_Z(0);
2112 
2113 	if( (INT32) op2 < (INT32) op1 )	/*TODO: should it be if( op2 < (INT32) op1 ) or is the one already implemented?*/
2114 		SET_N(1);
2115 	else
2116 		SET_N(0);
2117 
2118 /*	SET_V(); */ /*TODO!*/
2119 
2120 	if( op2 < op1 )
2121 		SET_C(1); /*borrow*/
2122 	else
2123 		SET_C(0); /*borrow*/
2124 
2125 	e132xs_ICount -= 1;
2126 }
2127 
e132xs_movi(void)2128 void e132xs_movi(void)
2129 {
2130 	UINT32 val;
2131 
2132 	val = immediate_value();
2133 
2134 	log_cb(RETRO_LOG_DEBUG, LOGPRE "Setting register %02x to value %08x\n", D_CODE, val );
2135 
2136 	if( D_BIT )
2137 	{
2138 		SET_L_REG(D_CODE, val);
2139 	}
2140 	else
2141 	{
2142 		if( !GET_S && GET_H )
2143 		{
2144 			UINT32 addr = get_trap_addr(PRIVILEGE_ERROR);
2145 			execute_trap(addr);
2146 		}
2147 		else
2148 		{
2149 			SET_G_REG(D_CODE + GET_H * 16, val);
2150 		}
2151 	}
2152 
2153 	if(D_CODE == PC_CODE && !D_BIT && !GET_H)
2154 		PC -= 2;
2155 
2156 	SET_Z((val == 0 ? 1: 0));
2157 	SET_N(SIGN_BIT(val));
2158 
2159 	e132xs_ICount -= 1;
2160 }
2161 
e132xs_addi(void)2162 void e132xs_addi(void)
2163 {
2164 	UINT32 op1, op2;
2165 
2166 	if( D_BIT )
2167 	{
2168 		op2 = GET_L_REG(D_CODE);
2169 	}
2170 	else
2171 	{
2172 		op2 = GET_G_REG(D_CODE);
2173 	}
2174 
2175 	if( !N_VALUE )
2176 		op1 = GET_C & ((GET_Z == 0 ? 1 : 0) | (op2 & 0x01));
2177 	else
2178 		op1 = immediate_value();
2179 
2180 	if(D_CODE == PC_CODE && !D_BIT)
2181 		PC -= 2;
2182 
2183 	op2 += op1;
2184 	SET_RD(op2, NOINC);
2185 	SET_Z((op2 == 0 ? 1: 0));
2186 	SET_N(SIGN_BIT(op2)); /*sign*/
2187 /*	SET_V(); */ /*TODO!*/
2188 /*	SET_C(); */ /*carry //TODO!*/
2189 
2190 	e132xs_ICount -= 1;
2191 }
2192 
e132xs_addsi(void)2193 void e132xs_addsi(void)
2194 {
2195 	INT32 op1, op2;
2196 
2197 	if( D_BIT )
2198 	{
2199 		op2 = GET_L_REG(D_CODE);
2200 	}
2201 	else
2202 	{
2203 		op2 = GET_G_REG(D_CODE);
2204 	}
2205 
2206 	if( !N_VALUE )
2207 		op1 = GET_C & ((GET_Z == 0 ? 1 : 0) | (op2 & 0x01));
2208 	else
2209 		op1 = immediate_value();
2210 
2211 	op2 += op1;
2212 	SET_RD(op2, NOINC);
2213 	SET_Z((op2 == 0 ? 1: 0));
2214 	SET_N(SIGN_BIT(op2)); /*sign*/
2215 /*	SET_V(); */ /*TODO!*/
2216 
2217 	e132xs_ICount -= 1;
2218 
2219 	if( GET_V )
2220 	{
2221 		UINT32 addr = get_trap_addr(RANGE_ERROR);
2222 		execute_trap(addr);
2223 	}
2224 }
2225 
e132xs_cmpbi(void)2226 void e132xs_cmpbi(void)
2227 {
2228 	UINT32 val1, val2;
2229 
2230 	val1 = 0;
2231 	if( N_VALUE )
2232 	{
2233 		if( N_VALUE == 31 )
2234 			val1 = 0x7fffffff; /*bit 31 = 0, others = 1*/
2235 		else
2236 			val1 = (UINT32) immediate_value();
2237 	}
2238 
2239 	if( D_BIT )
2240 	{
2241 		val2 = GET_L_REG(D_CODE);
2242 	}
2243 	else
2244 	{
2245 		val2 = GET_G_REG(D_CODE);
2246 	}
2247 
2248 	if( N_VALUE )
2249 	{
2250 		SET_Z(((val1 & val2) == 0 ? 1: 0));
2251 	}
2252 	else
2253 	{
2254 		if( !(val2 & 0xff000000) || !(val2 & 0x00ff0000) || !(val2 & 0x0000ff00) || !(val2 & 0x000000ff) )
2255 			SET_Z(1);
2256 		else
2257 			SET_Z(0);
2258 
2259 	}
2260 
2261 	e132xs_ICount -= 1;
2262 }
2263 
e132xs_andni(void)2264 void e132xs_andni(void)
2265 {
2266 	UINT32 op1, op2, ret;
2267 
2268 	if( N_VALUE == 31 )
2269 		op1 = ~0x7fffffff; /*bit 31 = 0, others = 1*/
2270 	else
2271 		op1 = ~immediate_value();
2272 
2273 	if( D_BIT )
2274 	{
2275 		op2 = GET_L_REG(D_CODE);
2276 	}
2277 	else
2278 	{
2279 		op2 = GET_G_REG(D_CODE);
2280 	}
2281 
2282 	ret = op1 & op2;
2283 
2284 	SET_RD(ret, NOINC);
2285 	SET_Z((ret == 0 ? 1: 0));
2286 
2287 	e132xs_ICount -= 1;
2288 }
2289 
e132xs_ori(void)2290 void e132xs_ori(void)
2291 {
2292 	UINT32 op1, op2, ret;
2293 
2294 	op1 = immediate_value();
2295 
2296 	if( D_BIT )
2297 	{
2298 		op2 = GET_L_REG(D_CODE);
2299 	}
2300 	else
2301 	{
2302 		op2 = GET_G_REG(D_CODE);
2303 	}
2304 
2305 	ret = op1 | op2;
2306 
2307 	SET_RD(ret, NOINC);
2308 	SET_Z((ret == 0 ? 1: 0));
2309 
2310 	e132xs_ICount -= 1;
2311 }
2312 
e132xs_xori(void)2313 void e132xs_xori(void)
2314 {
2315 	UINT32 op1, op2, ret;
2316 
2317 	op1 = immediate_value();
2318 
2319 	if( D_BIT )
2320 	{
2321 		op2 = GET_L_REG(D_CODE);
2322 	}
2323 	else
2324 	{
2325 		op2 = GET_G_REG(D_CODE);
2326 	}
2327 
2328 	ret = op1 ^ op2;
2329 
2330 	SET_RD(ret, NOINC);
2331 	SET_Z((ret == 0 ? 1: 0));
2332 
2333 	e132xs_ICount -= 1;
2334 }
2335 
e132xs_shrdi(void)2336 void e132xs_shrdi(void)
2337 {
2338 	UINT32 low_order, high_order;
2339 	UINT64 val;
2340 
2341 	high_order = GET_L_REG(D_CODE);
2342 	low_order = GET_L_REG(D_CODE + INC);
2343 
2344 	val = COMBINE_U64_U32_U32(high_order, low_order);
2345 
2346 	val >>= N_VALUE;
2347 
2348 	high_order = (val & 0xffffffff00000000) >> 32;
2349 	low_order = val & 0x00000000ffffffff;
2350 
2351 	SET_RD(high_order, NOINC);
2352 	SET_RD(low_order, INC);
2353 	SET_Z((val == 0 ? 1: 0));
2354 	SET_N(SIGN_BIT(high_order));
2355 /*	SET_C(); */ /*TODO!*/
2356 
2357 	e132xs_ICount -= 2;
2358 }
2359 
e132xs_shrd(void)2360 void e132xs_shrd(void)
2361 {
2362 	UINT32 low_order, high_order;
2363 	UINT64 val;
2364 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2365 
2366 	/*RESULT UNDEFINED IF LS DENOTES THE SAME REGISTER AS LD OR LDF*/
2367 	if( S_CODE != D_CODE && S_CODE != (D_CODE + INC) )
2368 	{
2369 		high_order = GET_L_REG(D_CODE);
2370 		low_order = GET_L_REG(D_CODE + INC);
2371 
2372 		val = COMBINE_U64_U32_U32(high_order, low_order);
2373 
2374 		val >>= n;
2375 
2376 		high_order = (val & 0xffffffff00000000) >> 32;
2377 		low_order = val & 0x00000000ffffffff;
2378 
2379 		SET_RD(high_order, NOINC);
2380 		SET_RD(low_order, INC);
2381 		SET_Z((val == 0 ? 1: 0));
2382 		SET_N(SIGN_BIT(high_order));
2383 /*		SET_C(); */ /*TODO!*/
2384 	}
2385 
2386 	e132xs_ICount -= 2;
2387 }
2388 
e132xs_shr(void)2389 void e132xs_shr(void)
2390 {
2391 	UINT32 ret;
2392 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2393 
2394 	ret = GET_L_REG(D_CODE);
2395 
2396 	ret >>= n;
2397 	SET_RD(ret, NOINC);
2398 	SET_Z((ret == 0 ? 1: 0));
2399 	SET_N(SIGN_BIT(ret));
2400 /*	SET_C(); */ /*??? //TODO!*/
2401 
2402 	e132xs_ICount -= 1;
2403 }
2404 
e132xs_sardi(void)2405 void e132xs_sardi(void)
2406 {
2407 	INT32 low_order, high_order;
2408 	INT64 val;
2409 	int sign_bit;
2410 
2411 	high_order = GET_L_REG(D_CODE);
2412 	low_order = GET_L_REG(D_CODE + INC);
2413 
2414 	val = (INT64) COMBINE_64_32_32(high_order, low_order);
2415 
2416 	sign_bit = (val & 0x8000000000000000) >> 63;
2417 	val >>= N_VALUE;
2418 
2419 	if( sign_bit )
2420 	{
2421 		int i;
2422 		for( i = 0; i < N_VALUE; i++ )
2423 		{
2424 			val |= (0x8000000000000000 >> i);
2425 		}
2426 	}
2427 
2428 	high_order = (val & 0xffffffff00000000) >> 32;
2429 	low_order = val & 0x00000000ffffffff;
2430 
2431 	SET_RD(high_order, NOINC);
2432 	SET_RD(low_order, INC);
2433 	SET_Z((val == 0 ? 1: 0));
2434 	SET_N(SIGN_BIT(high_order));
2435 /*	SET_C(); */ /*?? //TODO!*/
2436 
2437 	e132xs_ICount -= 2;
2438 }
2439 
e132xs_sard(void)2440 void e132xs_sard(void)
2441 {
2442 	INT32 low_order, high_order;
2443 	INT64 val;
2444 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2445 	int sign_bit;
2446 
2447 	/*RESULT UNDEFINED IF LS DENOTES THE SAME REGISTER AS LD OR LDF*/
2448 	if( S_CODE != D_CODE && S_CODE != (D_CODE + INC) )
2449 	{
2450 		high_order = GET_L_REG(D_CODE);
2451 		low_order = GET_L_REG(D_CODE + INC);
2452 
2453 		val = (INT64) COMBINE_64_32_32(high_order, low_order);
2454 		sign_bit = (val & 0x8000000000000000) >> 63;
2455 
2456 		val >>= n;
2457 
2458 		if( sign_bit )
2459 		{
2460 			int i;
2461 			for( i = 0; i < n; i++ )
2462 			{
2463 				val |= (0x8000000000000000 >> i);
2464 			}
2465 		}
2466 
2467 		high_order = (val & 0xffffffff00000000) >> 32;
2468 		low_order = val & 0x00000000ffffffff;
2469 
2470 		SET_RD(high_order, NOINC);
2471 		SET_RD(low_order, INC);
2472 		SET_Z((val == 0 ? 1: 0));
2473 		SET_N(SIGN_BIT(high_order));
2474 /*		SET_C(); */ /*TODO!*/
2475 	}
2476 
2477 	e132xs_ICount -= 2;
2478 }
2479 
e132xs_sar(void)2480 void e132xs_sar(void)
2481 {
2482 	INT32 ret;
2483 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2484 	int sign_bit;
2485 
2486 	ret = GET_L_REG(D_CODE);
2487 	sign_bit = (ret & 0x80000000) >> 31;
2488 
2489 	ret >>= n;
2490 
2491 	if( sign_bit )
2492 	{
2493 		int i;
2494 		for( i = 0; i < n; i++ )
2495 		{
2496 			ret |= (0x80000000 >> i);
2497 		}
2498 	}
2499 
2500 	SET_RD(ret, NOINC);
2501 	SET_Z((ret == 0 ? 1: 0));
2502 	SET_N(SIGN_BIT(ret));
2503 /*	SET_C(); */ /*TODO!*/
2504 
2505 	e132xs_ICount -= 1;
2506 }
2507 
e132xs_shldi(void)2508 void e132xs_shldi(void)
2509 {
2510 	UINT32 low_order, high_order;
2511 	UINT64 val;
2512 
2513 	high_order = GET_L_REG(D_CODE);
2514 	low_order = GET_L_REG(D_CODE + INC);
2515 
2516 	val = COMBINE_U64_U32_U32(high_order, low_order);
2517 
2518 	val <<= N_VALUE;
2519 
2520 	high_order = (val & 0xffffffff00000000) >> 32;
2521 	low_order = val & 0x00000000ffffffff;
2522 
2523 	SET_RD(high_order, NOINC);
2524 	SET_RD(low_order, INC);
2525 	SET_Z((val == 0 ? 1: 0));
2526 	SET_N(SIGN_BIT(high_order));
2527 /*	SET_V(); */ /* = ~GET_N ? //TODO!*/
2528 /*	SET_C(); */ /*undefined*/
2529 
2530 	e132xs_ICount -= 2;
2531 }
2532 
e132xs_shld(void)2533 void e132xs_shld(void)
2534 {
2535 	UINT32 low_order, high_order;
2536 	UINT64 val;
2537 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2538 
2539 	/*RESULT UNDEFINED IF LS DENOTES THE SAME REGISTER AS LD OR LDF*/
2540 	if( S_CODE != D_CODE && S_CODE != (D_CODE + INC) )
2541 	{
2542 		high_order = GET_L_REG(D_CODE);
2543 		low_order = GET_L_REG(D_CODE + INC);
2544 
2545 		val = COMBINE_U64_U32_U32(high_order, low_order);
2546 
2547 		val <<= n;
2548 
2549 		high_order = (val & 0xffffffff00000000) >> 32;
2550 		low_order = val & 0x00000000ffffffff;
2551 
2552 		SET_RD(high_order, NOINC);
2553 		SET_RD(low_order, INC);
2554 		SET_Z((val == 0 ? 1: 0));
2555 		SET_N(SIGN_BIT(high_order));
2556 	/*	SET_V(); */ /* = ~GET_N ? //TODO!*/
2557 	/*	SET_C(); */ /*undefined*/
2558 	}
2559 
2560 	e132xs_ICount -= 2;
2561 }
2562 
e132xs_shl(void)2563 void e132xs_shl(void)
2564 {
2565 	UINT32 ret;
2566 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2567 
2568 	ret = GET_L_REG(D_CODE);
2569 
2570 	ret <<= n;
2571 	SET_RD(ret, NOINC);
2572 	SET_Z((ret == 0 ? 1: 0));
2573 	SET_N(SIGN_BIT(ret));
2574 /*	SET_V(); */ /* = ~GET_N ? //TODO!*/
2575 /*	SET_C(); */ /*undefined*/
2576 
2577 	e132xs_ICount -= 1;
2578 }
2579 
reserved(void)2580 void reserved(void)
2581 {
2582 	log_cb(RETRO_LOG_DEBUG, LOGPRE "- Reserved opcode executed @ %x, OP = %x\n", OP, PC );
2583 }
2584 
e132xs_testlz(void)2585 void e132xs_testlz(void)
2586 {
2587 	UINT8 zeros = 0;
2588 	UINT32 code = GET_L_REG(S_CODE);
2589 	int mask;
2590 
2591 	for( mask = 0x80000000; ; mask >>= 1 )
2592 	{
2593 		if( code & mask )
2594 			break;
2595 		else
2596 			zeros++;
2597 
2598 		if( zeros == 32 )
2599 			break;
2600 	}
2601 
2602 	SET_L_REG(D_CODE, zeros);
2603 
2604 	e132xs_ICount -= 2;
2605 }
2606 
e132xs_rol(void)2607 void e132xs_rol(void)
2608 {
2609 	UINT32 val;
2610 	unsigned int n = OP & 0x1f; /*TODO: is it correct? documentation says bits 4..0 of source, but source uses bits are 3..0*/
2611 
2612 	val = GET_L_REG(D_CODE);
2613 
2614 	/*TODO: if n = 0 skip it ?*/
2615 	while( n > 0 )
2616 	{
2617 		val = (val << 1) | ((val & 0x80000000) >> 31);
2618 		n--;
2619 	}
2620 
2621 	SET_Z((val == 0 ? 1: 0));
2622 	SET_N(SIGN_BIT(val));
2623 	/*V -> undefined*/
2624 	/*C -> undefined*/
2625 
2626 	e132xs_ICount -= 1;
2627 }
2628 
2629 /*TODO: add trap error*/
e132xs_ldxx1(void)2630 void e132xs_ldxx1(void)
2631 {
2632 	UINT32 load;
2633 	UINT16 next_op;
2634 	INT32 dis;
2635 
2636 	PC += 2;
2637 	next_op = READ_OP(PC);
2638 	dis = get_dis( next_op );
2639 
2640 	if( D_CODE == SR_CODE && !D_BIT )
2641 	{
2642 		switch( DD( next_op ) )
2643 		{
2644 			case 0:
2645 				/* LDBS.A*/
2646 				load = (INT8) READ_B(dis);
2647 				SET_RS( load, NOINC );
2648 
2649 				break;
2650 
2651 			case 1:
2652 				/* LDBU.A*/
2653 				load = (UINT8) READ_B(dis);
2654 				SET_RS( load, NOINC );
2655 
2656 				break;
2657 
2658 			case 2:
2659 				/* LDHS.A*/
2660 				if( dis & 1 )
2661 				{
2662 					load = (INT16) READ_HW(dis);
2663 					SET_RS( load, NOINC );
2664 				}
2665 				/* LDHU.A*/
2666 				else
2667 				{
2668 					load = (UINT16) READ_HW(dis);
2669 					SET_RS( load, NOINC );
2670 				}
2671 
2672 				break;
2673 
2674 			case 3:
2675 				/* LDD.IOA*/
2676 				if( ( dis & 2 ) && ( dis & 1 ) )
2677 				{
2678 					/* used in an I/O address*/
2679 					load = READ_W(dis);
2680 					SET_RS( load, NOINC );
2681 					load = READ_W(dis + 4);
2682 					SET_RS( load, INC );
2683 
2684 				}
2685 				/* LDW.IOA*/
2686 				else if( ( dis & 2 ) && !( dis & 1 ) )
2687 				{
2688 					/* used in an I/O address*/
2689 					load = READ_W(dis);
2690 					SET_RS( load, NOINC );
2691 				}
2692 				/* LDD.A*/
2693 				else if( !( dis & 2 ) && ( dis & 1 ) )
2694 				{
2695 					load = READ_W(dis);
2696 					SET_RS( load, NOINC );
2697 					load = READ_W(dis + 4);
2698 					SET_RS( load, INC );
2699 				}
2700 				/* LDW.A*/
2701 				else
2702 				{
2703 					load = READ_W(dis);
2704 					SET_RS( load, NOINC );
2705 				}
2706 
2707 				break;
2708 		}
2709 	}
2710 	else
2711 	{
2712 		switch( DD( next_op ) )
2713 		{
2714 			case 0:
2715 				/* LDBS.D*/
2716 				if( D_BIT )
2717 				{
2718 					load = (INT8) READ_B( GET_L_REG(D_CODE) + dis );
2719 				}
2720 				else
2721 				{
2722 					load = (INT8) READ_B( GET_G_REG(D_CODE) + dis );
2723 				}
2724 				SET_RS( load, NOINC );
2725 
2726 				break;
2727 
2728 			case 1:
2729 				/* LDBU.D*/
2730 				if( D_BIT )
2731 				{
2732 					load = (UINT8) READ_B( GET_L_REG(D_CODE) + dis );
2733 				}
2734 				else
2735 				{
2736 					load = (UINT8) READ_B( GET_G_REG(D_CODE) + dis );
2737 				}
2738 				SET_RS( load, NOINC );
2739 
2740 				break;
2741 
2742 			case 2:
2743 				/* LDHS.D*/
2744 				if( dis & 1 )
2745 				{
2746 					if( D_BIT )
2747 					{
2748 						load = (INT16) READ_HW( GET_L_REG(D_CODE) + dis );
2749 					}
2750 					else
2751 					{
2752 						load = (INT16) READ_HW( GET_G_REG(D_CODE) + dis );
2753 					}
2754 					SET_RS( load, NOINC );
2755 				}
2756 				/* LDHU.D*/
2757 				else
2758 				{
2759 					if( D_BIT )
2760 					{
2761 						load = (UINT16) READ_HW( GET_L_REG(D_CODE) + dis );
2762 					}
2763 					else
2764 					{
2765 						load = (UINT16) READ_HW( GET_G_REG(D_CODE) + dis );
2766 					}
2767 					SET_RS( load, NOINC );
2768 				}
2769 
2770 				break;
2771 
2772 			case 3:
2773 				/* LDD.IOD*/
2774 				if( ( dis & 2 ) && ( dis & 1 ) )
2775 				{
2776 					/* used in an I/O address*/
2777 
2778 					if( D_BIT )
2779 					{
2780 						load = READ_W( GET_L_REG(D_CODE) + dis );
2781 					}
2782 					else
2783 					{
2784 						load = READ_W( GET_G_REG(D_CODE) + dis );
2785 					}
2786 					SET_RS( load, NOINC );
2787 
2788 					if( D_BIT )
2789 					{
2790 						load = READ_W( GET_L_REG(D_CODE) + dis + 4 );
2791 					}
2792 					else
2793 					{
2794 						load = READ_W( GET_G_REG(D_CODE) + dis + 4 );
2795 					}
2796 					SET_RS( load, INC );
2797 
2798 					e132xs_ICount -= 1; /*extra cycle*/
2799 				}
2800 				/* LDW.IOD*/
2801 				else if( ( dis & 2 ) && !( dis & 1 ) )
2802 				{
2803 					/* used in an I/O address*/
2804 
2805 					if( D_BIT )
2806 					{
2807 						load = READ_W( GET_L_REG(D_CODE) + dis );
2808 					}
2809 					else
2810 					{
2811 						load = READ_W( GET_G_REG(D_CODE) + dis );
2812 					}
2813 					SET_RS( load, NOINC );
2814 				}
2815 				/* LDD.D*/
2816 				else if( !( dis & 2 ) && ( dis & 1 ) )
2817 				{
2818 					if( D_BIT )
2819 					{
2820 						load = READ_W( GET_L_REG(D_CODE) + dis );
2821 					}
2822 					else
2823 					{
2824 						load = READ_W( GET_G_REG(D_CODE) + dis );
2825 					}
2826 					SET_RS( load, NOINC );
2827 
2828 					if( D_BIT )
2829 					{
2830 						load = READ_W( GET_L_REG(D_CODE) + dis + 4 );
2831 					}
2832 					else
2833 					{
2834 						load = READ_W( GET_G_REG(D_CODE) + dis + 4 );
2835 					}
2836 					SET_RS( load, INC );
2837 
2838 					e132xs_ICount -= 1; /*extra cycle*/
2839 				}
2840 				/* LDW.D*/
2841 				else
2842 				{
2843 					if( D_BIT )
2844 					{
2845 						load = READ_W( GET_L_REG(D_CODE) + dis );
2846 					}
2847 					else
2848 					{
2849 						load = READ_W( GET_G_REG(D_CODE) + dis );
2850 					}
2851 					SET_RS( load, NOINC );
2852 				}
2853 
2854 				break;
2855 		}
2856 	}
2857 
2858 	e132xs_ICount -= 1;
2859 }
2860 
e132xs_ldxx2(void)2861 void e132xs_ldxx2(void)
2862 {
2863 	UINT32 load;
2864 	UINT16 next_op;
2865 	INT32 dis;
2866 
2867 	PC += 2;
2868 	next_op = READ_OP(PC);
2869 	dis = get_dis( next_op );
2870 
2871 	if( (D_CODE == PC_CODE && !D_BIT) || (D_CODE == SR_CODE && !D_BIT) )
2872 	{
2873 		log_cb(RETRO_LOG_DEBUG, LOGPRE "- In e132xs_ldxx2 must not denote PC or SR. PC = %x\n", PC );
2874 	}
2875 	else
2876 	{
2877 
2878 		switch( DD( next_op ) )
2879 		{
2880 			case 0:
2881 				/* LDBS.N*/
2882 				if( D_BIT )
2883 				{
2884 					load = (INT8) READ_B( GET_L_REG(D_CODE) );
2885 					SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2886 				}
2887 				else
2888 				{
2889 					load = (INT8) READ_B( GET_G_REG(D_CODE) );
2890 					SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
2891 				}
2892 				SET_RS( load, NOINC );
2893 
2894 				break;
2895 
2896 			case 1:
2897 				/* LDBU.N*/
2898 				if( D_BIT )
2899 				{
2900 					load = (UINT8) READ_B( GET_L_REG(D_CODE) );
2901 					SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2902 				}
2903 				else
2904 				{
2905 					load = (UINT8) READ_B( GET_G_REG(D_CODE) );
2906 					SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
2907 				}
2908 				SET_RS( load, NOINC );
2909 
2910 				break;
2911 
2912 			case 2:
2913 				/* LDHS.N*/
2914 				if( dis & 1 )
2915 				{
2916 					if( D_BIT )
2917 					{
2918 						load = (INT16) READ_HW( GET_L_REG(D_CODE) );
2919 						SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2920 					}
2921 					else
2922 					{
2923 						load = (INT16) READ_HW( GET_G_REG(D_CODE) );
2924 						SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
2925 					}
2926 					SET_RS( load, NOINC );
2927 				}
2928 				/* LDHU.N*/
2929 				else
2930 				{
2931 					if( D_BIT )
2932 					{
2933 						load = (UINT16) READ_HW( GET_L_REG(D_CODE) );
2934 						SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2935 					}
2936 					else
2937 					{
2938 						load = (UINT16) READ_HW( GET_G_REG(D_CODE) );
2939 						SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
2940 					}
2941 					SET_RS( load, NOINC );
2942 				}
2943 
2944 				break;
2945 
2946 			case 3:
2947 				/* LDW.S*/
2948 				if( ( dis & 2 ) && ( dis & 1 ) )
2949 				{
2950 					/*TODO: other? read notes in the docs*/
2951 					if( D_BIT )
2952 					{
2953 						load = READ_W( GET_L_REG(D_CODE) );
2954 						SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2955 					}
2956 					else
2957 					{
2958 						load = READ_W( GET_G_REG(D_CODE) );
2959 						SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
2960 					}
2961 					SET_RS( load, NOINC );
2962 
2963 					e132xs_ICount -= 2; /*extra cycles*/
2964 				}
2965 				/* Reserved*/
2966 				else if( ( dis & 2 ) && !( dis & 1 ) )
2967 				{
2968 					log_cb(RETRO_LOG_DEBUG, LOGPRE "- Reserved Load instruction @ %x\n", PC );
2969 				}
2970 				/* LDD.N*/
2971 				else if( !( dis & 2 ) && ( dis & 1 ) )
2972 				{
2973 					if( D_BIT )
2974 					{
2975 						load = READ_W( GET_L_REG(D_CODE) );
2976 						SET_RS( READ_W( GET_L_REG(D_CODE) + 4 ), INC );
2977 						SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2978 					}
2979 					else
2980 					{
2981 						load = READ_W( GET_G_REG(D_CODE) );
2982 						SET_RS( READ_W( GET_G_REG(D_CODE) + 4 ), INC );
2983 						SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
2984 					}
2985 					SET_RS( load, NOINC );
2986 
2987 					e132xs_ICount -= 1; /*extra cycle*/
2988 				}
2989 				/* LDW.N*/
2990 				else
2991 				{
2992 					if( D_BIT )
2993 					{
2994 						load = READ_W( GET_L_REG(D_CODE) );
2995 						SET_RD( GET_L_REG(D_CODE) + dis, NOINC );
2996 					}
2997 					else
2998 					{
2999 						load = READ_W( GET_G_REG(D_CODE) );
3000 						SET_RD( GET_G_REG(D_CODE) + dis, NOINC );
3001 					}
3002 					SET_RS( load, NOINC );
3003 				}
3004 
3005 				break;
3006 		}
3007 	}
3008 
3009 	e132xs_ICount -= 1;
3010 }
3011 
3012 
3013 /*TODO: add trap error*/
e132xs_stxx1(void)3014 void e132xs_stxx1(void)
3015 {
3016 	UINT32 val;
3017 	UINT16 next_op;
3018 	INT32 dis;
3019 
3020 	PC += 2;
3021 	next_op = READ_OP(PC);
3022 	dis = get_dis( next_op );
3023 
3024 	if( S_BIT )
3025 	{
3026 		val = GET_L_REG(S_CODE);
3027 	}
3028 	else
3029 	{
3030 		val = GET_G_REG(S_CODE);
3031 	}
3032 
3033 	if( D_CODE == SR_CODE && !D_BIT )
3034 	{
3035 		switch( DD( next_op ) )
3036 		{
3037 			case 0:
3038 				/* STBS.A*/
3039 				WRITE_B( dis, (INT8) val );
3040 
3041 				break;
3042 
3043 			case 1:
3044 				/* STBU.A*/
3045 				WRITE_B( dis, (UINT8) val );
3046 
3047 				break;
3048 
3049 			case 2:
3050 				/* STHS.A*/
3051 				if( dis & 1 )
3052 				{
3053 					WRITE_HW( dis, (INT16) val );
3054 				}
3055 				/* STHU.A*/
3056 				else
3057 				{
3058 					WRITE_HW( dis, (UINT16) val );
3059 				}
3060 
3061 				break;
3062 
3063 			case 3:
3064 				/* STD.IOA*/
3065 				if( ( dis & 2 ) && ( dis & 1 ) )
3066 				{
3067 					/* used in an I/O address*/
3068 					UINT32 val2;
3069 
3070 					if( S_BIT )
3071 					{
3072 						val2 = GET_L_REG(S_CODE + INC);
3073 					}
3074 					else
3075 					{
3076 						val2 = GET_G_REG(S_CODE + INC);
3077 					}
3078 
3079 					WRITE_W( dis, val );
3080 					WRITE_W( dis + 4, val2 );
3081 
3082 					e132xs_ICount -= 1; /*extra cycle*/
3083 				}
3084 				/* STW.IOA*/
3085 				else if( ( dis & 2 ) && !( dis & 1 ) )
3086 				{
3087 					/* used in an I/O address*/
3088 					WRITE_W( dis, val );
3089 				}
3090 				/* STD.A*/
3091 				else if( !( dis & 2 ) && ( dis & 1 ) )
3092 				{
3093 					UINT32 val2;
3094 
3095 					if( S_BIT )
3096 					{
3097 						val2 = GET_L_REG(S_CODE + INC);
3098 					}
3099 					else
3100 					{
3101 						val2 = GET_G_REG(S_CODE + INC);
3102 					}
3103 
3104 					WRITE_W( dis, val );
3105 					WRITE_W( dis + 4, val2 );
3106 
3107 					e132xs_ICount -= 1; /*extra cycle*/
3108 				}
3109 				/* STW.A*/
3110 				else
3111 				{
3112 					WRITE_W( dis, val );
3113 				}
3114 
3115 				break;
3116 		}
3117 	}
3118 	else
3119 	{
3120 		switch( DD( next_op ) )
3121 		{
3122 			case 0:
3123 				/* STBS.D*/
3124 				if( D_BIT )
3125 				{
3126 					WRITE_B( GET_L_REG(D_CODE) + dis, (INT8) val );
3127 				}
3128 				else
3129 				{
3130 					WRITE_B( GET_G_REG(D_CODE) + dis, (INT8) val );
3131 				}
3132 
3133 				break;
3134 
3135 			case 1:
3136 				/* STBU.D*/
3137 				if( D_BIT )
3138 				{
3139 					WRITE_B( GET_L_REG(D_CODE) + dis, (UINT8) val );
3140 				}
3141 				else
3142 				{
3143 					WRITE_B( GET_G_REG(D_CODE) + dis, (UINT8) val );
3144 				}
3145 
3146 				break;
3147 
3148 			case 2:
3149 				/* STHS.D*/
3150 				if( dis & 1 )
3151 				{
3152 					if( D_BIT )
3153 					{
3154 						WRITE_HW( GET_L_REG(D_CODE) + dis, (INT16) val );
3155 					}
3156 					else
3157 					{
3158 						WRITE_HW( GET_G_REG(D_CODE) + dis, (INT16) val );
3159 					}
3160 				}
3161 				/* STHU.D*/
3162 				else
3163 				{
3164 					if( D_BIT )
3165 					{
3166 						WRITE_HW( GET_L_REG(D_CODE) + dis, (UINT16) val );
3167 					}
3168 					else
3169 					{
3170 						WRITE_HW( GET_G_REG(D_CODE) + dis, (UINT16) val );
3171 					}
3172 				}
3173 
3174 				break;
3175 
3176 			case 3:
3177 				/* STD.IOD*/
3178 				if( ( dis & 2 ) && ( dis & 1 ) )
3179 				{
3180 					/* used in an I/O address*/
3181 					UINT32 val2;
3182 
3183 					if( S_BIT )
3184 					{
3185 						val2 = GET_L_REG(S_CODE + INC);
3186 					}
3187 					else
3188 					{
3189 						val2 = GET_G_REG(S_CODE + INC);
3190 					}
3191 
3192 					if( D_BIT )
3193 					{
3194 						WRITE_W( GET_L_REG(D_CODE) + dis, val );
3195 						WRITE_W( GET_L_REG(D_CODE) + dis + 4, val2 );
3196 					}
3197 					else
3198 					{
3199 						WRITE_W( GET_G_REG(D_CODE) + dis, val );
3200 						WRITE_W( GET_G_REG(D_CODE) + dis + 4, val2 );
3201 					}
3202 
3203 					e132xs_ICount -= 1; /*extra cycle*/
3204 				}
3205 				/* STW.IOD*/
3206 				else if( ( dis & 2 ) && !( dis & 1 ) )
3207 				{
3208 					/* used in an I/O address*/
3209 					if( D_BIT )
3210 					{
3211 						WRITE_W( GET_L_REG(D_CODE) + dis, val );
3212 					}
3213 					else
3214 					{
3215 						WRITE_W( GET_G_REG(D_CODE) + dis, val );
3216 					}
3217 				}
3218 				/* STD.D*/
3219 				else if( !( dis & 2 ) && ( dis & 1 ) )
3220 				{
3221 					UINT32 val2;
3222 
3223 					if( S_BIT )
3224 					{
3225 						val2 = GET_L_REG(S_CODE + INC);
3226 					}
3227 					else
3228 					{
3229 						val2 = GET_G_REG(S_CODE + INC);
3230 					}
3231 
3232 					if( D_BIT )
3233 					{
3234 						WRITE_W( GET_L_REG(D_CODE) + dis, val );
3235 						WRITE_W( GET_L_REG(D_CODE) + dis + 4, val2 );
3236 					}
3237 					else
3238 					{
3239 						WRITE_W( GET_G_REG(D_CODE) + dis, val );
3240 						WRITE_W( GET_G_REG(D_CODE) + dis + 4, val2 );
3241 					}
3242 
3243 					e132xs_ICount -= 1; /*extra cycle*/
3244 				}
3245 				/* STW.D*/
3246 				else
3247 				{
3248 					if( D_BIT )
3249 					{
3250 						WRITE_W( GET_L_REG(D_CODE) + dis, val );
3251 					}
3252 					else
3253 					{
3254 						WRITE_W( GET_G_REG(D_CODE) + dis, val );
3255 					}
3256 				}
3257 
3258 				break;
3259 		}
3260 	}
3261 
3262 	e132xs_ICount -= 1;
3263 }
3264 
e132xs_stxx2(void)3265 void e132xs_stxx2(void)
3266 {
3267 	UINT32 val, addr;
3268 	UINT16 next_op;
3269 	INT32 dis;
3270 
3271 	PC += 2;
3272 	next_op = READ_OP(PC);
3273 	dis = get_dis( next_op );
3274 
3275 	if( (D_CODE == PC_CODE && !D_BIT) || (D_CODE == SR_CODE && !D_BIT) )
3276 	{
3277 		log_cb(RETRO_LOG_DEBUG, LOGPRE "In e132xs_stxx2 must not denote PC or SR. PC = %x\n", PC );
3278 	}
3279 	else
3280 	{
3281 
3282 		if( S_BIT )
3283 		{
3284 			val = GET_L_REG(S_CODE);
3285 		}
3286 		else
3287 		{
3288 			val = GET_G_REG(S_CODE);
3289 		}
3290 
3291 		if( D_BIT )
3292 		{
3293 			addr = GET_L_REG(D_CODE);
3294 			SET_L_REG( D_CODE, addr + dis );
3295 		}
3296 		else
3297 		{
3298 			addr = GET_G_REG(D_CODE);
3299 			SET_G_REG( D_CODE, addr + dis );
3300 		}
3301 
3302 		switch( DD( next_op ) )
3303 		{
3304 			case 0:
3305 				/* STBS.N*/
3306 				WRITE_B( addr, (INT8) val );
3307 
3308 				break;
3309 
3310 			case 1:
3311 				/* STBU.N*/
3312 				WRITE_B( addr, (UINT8) val );
3313 
3314 				break;
3315 
3316 			case 2:
3317 				/* STHS.N*/
3318 				if( dis & 1 )
3319 				{
3320 					WRITE_HW( addr, (INT16) val );
3321 				}
3322 				/* STHU.N*/
3323 				else
3324 				{
3325 					WRITE_HW( addr, (UINT16) val );
3326 				}
3327 
3328 				break;
3329 
3330 			case 3:
3331 				/* STW.S*/
3332 				if( ( dis & 2 ) && ( dis & 1 ) )
3333 				{
3334 					WRITE_W( addr, val );
3335 
3336 					e132xs_ICount -= 2; /*extra cycles*/
3337 				}
3338 				/* Reserved*/
3339 				else if( ( dis & 2 ) && !( dis & 1 ) )
3340 				{
3341 					log_cb(RETRO_LOG_DEBUG, LOGPRE "Reserved Store instruction @ %x\n", PC );
3342 				}
3343 				/* STD.N*/
3344 				else if( !( dis & 2 ) && ( dis & 1 ) )
3345 				{
3346 					UINT32 val2;
3347 
3348 					if( S_BIT )
3349 					{
3350 						val2 = GET_L_REG(S_CODE + INC);
3351 					}
3352 					else
3353 					{
3354 						val2 = GET_G_REG(S_CODE + INC);
3355 					}
3356 
3357 					WRITE_W( addr, val );
3358 					WRITE_W( addr + 4, val2 );
3359 
3360 					e132xs_ICount -= 1; /*extra cycle*/
3361 				}
3362 				/* STW.N*/
3363 				else
3364 				{
3365 					WRITE_W( addr, val );
3366 				}
3367 
3368 				break;
3369 		}
3370 	}
3371 
3372 	e132xs_ICount -= 1;
3373 }
3374 
e132xs_shri(void)3375 void e132xs_shri(void)
3376 {
3377 	UINT32 val;
3378 
3379 	if( D_BIT )
3380 	{
3381 		val = GET_L_REG(D_CODE);
3382 	}
3383 	else
3384 	{
3385 		val = GET_G_REG(D_CODE);
3386 	}
3387 
3388 	val >>= N_VALUE;
3389 
3390 	SET_RD(val, NOINC);
3391 	SET_Z((val == 0 ? 1: 0));
3392 	SET_N(SIGN_BIT(val));
3393 /*	SET_C(); */ /* 1 if( val & n ) ? //TODO!*/
3394 
3395 	e132xs_ICount -= 1;
3396 }
3397 
e132xs_sari(void)3398 void e132xs_sari(void)
3399 {
3400 	INT32 val;
3401 	int sign_bit;
3402 
3403 	if( D_BIT )
3404 	{
3405 		val = GET_L_REG(D_CODE);
3406 	}
3407 	else
3408 	{
3409 		val = GET_G_REG(D_CODE);
3410 	}
3411 
3412 	sign_bit = (val & 0x80000000) >> 31;
3413 	val >>= N_VALUE;
3414 
3415 	if( sign_bit )
3416 	{
3417 		int i;
3418 		for( i = 0; i < N_VALUE; i++ )
3419 		{
3420 			val |= (0x80000000 >> i);
3421 		}
3422 	}
3423 
3424 	SET_RD(val, NOINC);
3425 	SET_Z((val == 0 ? 1: 0));
3426 	SET_N(SIGN_BIT(val));
3427 /*	SET_C(); */ /* 1 if( val & n ) ? //TODO!*/
3428 
3429 	e132xs_ICount -= 1;
3430 }
3431 
e132xs_shli(void)3432 void e132xs_shli(void)
3433 {
3434 	UINT32 val;
3435 
3436 	if( D_BIT )
3437 	{
3438 		val = GET_L_REG(D_CODE);
3439 	}
3440 	else
3441 	{
3442 		val = GET_G_REG(D_CODE);
3443 	}
3444 
3445 	val <<= N_VALUE;
3446 	SET_RD(val, NOINC);
3447 	SET_Z((val == 0 ? 1: 0));
3448 	SET_N(SIGN_BIT(val)); /*sign*/
3449 /*	SET_V(); */ /* = ~GET_N ? //TODO!*/
3450 /*	SET_C(); */ /*undefined*/
3451 
3452 	e132xs_ICount -= 1;
3453 }
3454 
e132xs_mulu(void)3455 void e132xs_mulu(void)
3456 {
3457 	UINT32 op1, op2, low_order, high_order;
3458 	UINT64 double_word;
3459 
3460 	op1 = op2 = 0;
3461 
3462 	/*PC or SR aren't denoted, else result is undefined*/
3463 	if( (S_CODE == PC_CODE && !S_BIT) || (S_CODE == SR_CODE && !S_BIT) || (D_CODE == PC_CODE && !D_BIT) || (D_CODE == SR_CODE && !D_BIT) )
3464 	{
3465 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC or SR in MULU instruction @ x\n", PC );
3466 	}
3467 	else
3468 	{
3469 		if( S_BIT )
3470 		{
3471 			op1 = GET_L_REG(S_CODE);
3472 		}
3473 		else
3474 		{
3475 			op1 = GET_G_REG(S_CODE);
3476 		}
3477 
3478 		if( D_BIT )
3479 		{
3480 			op2 = GET_L_REG(D_CODE);
3481 		}
3482 		else
3483 		{
3484 			op2 = GET_G_REG(D_CODE);
3485 		}
3486 
3487 		double_word = (op1 * op2);
3488 		low_order = double_word & 0x00000000ffffffff;
3489 		high_order = (double_word & 0xffffffff00000000) >> 32;
3490 
3491 		SET_RD(high_order, NOINC);
3492 		SET_RD(low_order, INC);
3493 		SET_Z((double_word == 0 ? 1: 0));
3494 		SET_N(SIGN_BIT(high_order)); /*sign*/
3495 	/*	SET_V(); */ /*undefined*/
3496 	/*	SET_C(); */ /*undefined*/
3497 	}
3498 
3499 	if( op1 <= 0xffff  && op2 <= 0xffff )
3500 		e132xs_ICount -= 4;
3501 	else
3502 		e132xs_ICount -= 6;
3503 }
3504 
e132xs_muls(void)3505 void e132xs_muls(void)
3506 {
3507 	INT32 op1, op2, low_order, high_order;
3508 	INT64 double_word;
3509 
3510 	op1 = op2 = 0;
3511 
3512 	/*PC or SR aren't denoted, else result is undefined*/
3513 	if( (S_CODE == PC_CODE && !S_BIT) || (S_CODE == SR_CODE && !S_BIT) || (D_CODE == PC_CODE && !D_BIT) || (D_CODE == SR_CODE && !D_BIT) )
3514 	{
3515 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC or SR in MULS instruction @ x\n", PC );
3516 	}
3517 	else
3518 	{
3519 		if( S_BIT )
3520 		{
3521 			op1 = GET_L_REG(S_CODE);
3522 		}
3523 		else
3524 		{
3525 			op1 = GET_G_REG(S_CODE);
3526 		}
3527 
3528 		if( D_BIT )
3529 		{
3530 			op2 = GET_L_REG(D_CODE);
3531 		}
3532 		else
3533 		{
3534 			op2 = GET_G_REG(D_CODE);
3535 		}
3536 
3537 		double_word = (op1 * op2);
3538 		low_order = double_word & 0x00000000ffffffff;
3539 		high_order = (double_word & 0xffffffff00000000) >> 32;
3540 
3541 		SET_RD(high_order, NOINC);
3542 		SET_RD(low_order, INC);
3543 		SET_Z((double_word == 0 ? 1: 0));
3544 		SET_N(SIGN_BIT(high_order)); /*sign*/
3545 	/*	SET_V(); */ /*undefined*/
3546 	/*	SET_C(); */ /*undefined*/
3547 	}
3548 
3549 	if( ( op1 >= 0xffff8000 && op1 <= 0x7fff ) && ( op2 >= 0xffff8000 && op2 <= 0x7fff ) )
3550 		e132xs_ICount -= 4;
3551 	else
3552 		e132xs_ICount -= 6;
3553 }
3554 
e132xs_set(void)3555 void e132xs_set(void)
3556 {
3557 	int n = N_VALUE;
3558 
3559 	if( D_CODE == PC_CODE && !D_BIT )
3560 	{
3561 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC in e132xs_set @ %x, it is reserved for future use\n", PC );
3562 	}
3563 	else if( D_CODE == SR_CODE && !D_BIT )
3564 	{
3565 		/*TODO: add fetch opcode (when is there the pipeline?)*/
3566 
3567 		/*TODO: no 1!*/
3568 		e132xs_ICount -= 1;
3569 	}
3570 	else
3571 	{
3572 		switch( n )
3573 		{
3574 			/* SETADR*/
3575 			case 0:
3576 			{
3577 				UINT32 val;
3578 				val =  (SP & 0xfffffe00) | (GET_FP << 2);
3579 
3580 				/*plus carry into bit 9*/
3581 				val += (((SP & 0x100) && !SIGN_BIT(SR)) ? 1 : 0);
3582 
3583 				SET_RD(val, NOINC);
3584 
3585 				break;
3586 			}
3587 			/* Reserved*/
3588 			case 1:
3589 			case 16:
3590 			case 17:
3591 			case 19:
3592 				log_cb(RETRO_LOG_DEBUG, LOGPRE "Used reserved N value (%d) in e132xs_set @ %x\n", n, PC );
3593 				break;
3594 
3595 			/* SETxx*/
3596 			case 2:
3597 				SET_RD(1, NOINC);
3598 				break;
3599 
3600 			case 3:
3601 				SET_RD(0, NOINC);
3602 				break;
3603 
3604 			case 4:
3605 				if( GET_N || GET_Z )
3606 				{
3607 					SET_RD(1, NOINC);
3608 				}
3609 				else
3610 				{
3611 					SET_RD(0, NOINC);
3612 				}
3613 
3614 				break;
3615 
3616 			case 5:
3617 				if( !GET_N && !GET_Z )
3618 				{
3619 					SET_RD(1, NOINC);
3620 				}
3621 				else
3622 				{
3623 					SET_RD(0, NOINC);
3624 				}
3625 
3626 				break;
3627 
3628 			case 6:
3629 				if( GET_N )
3630 				{
3631 					SET_RD(1, NOINC);
3632 				}
3633 				else
3634 				{
3635 					SET_RD(0, NOINC);
3636 				}
3637 
3638 				break;
3639 
3640 			case 7:
3641 				if( !GET_N )
3642 				{
3643 					SET_RD(1, NOINC);
3644 				}
3645 				else
3646 				{
3647 					SET_RD(0, NOINC);
3648 				}
3649 
3650 				break;
3651 
3652 			case 8:
3653 				if( GET_C || GET_Z )
3654 				{
3655 					SET_RD(1, NOINC);
3656 				}
3657 				else
3658 				{
3659 					SET_RD(0, NOINC);
3660 				}
3661 
3662 				break;
3663 
3664 			case 9:
3665 				if( !GET_C && !GET_Z )
3666 				{
3667 					SET_RD(1, NOINC);
3668 				}
3669 				else
3670 				{
3671 					SET_RD(0, NOINC);
3672 				}
3673 
3674 				break;
3675 
3676 			case 10:
3677 				if( GET_C )
3678 				{
3679 					SET_RD(1, NOINC);
3680 				}
3681 				else
3682 				{
3683 					SET_RD(0, NOINC);
3684 				}
3685 
3686 				break;
3687 
3688 			case 11:
3689 				if( !GET_C )
3690 				{
3691 					SET_RD(1, NOINC);
3692 				}
3693 				else
3694 				{
3695 					SET_RD(0, NOINC);
3696 				}
3697 
3698 				break;
3699 
3700 			case 12:
3701 				if( GET_Z )
3702 				{
3703 					SET_RD(1, NOINC);
3704 				}
3705 				else
3706 				{
3707 					SET_RD(0, NOINC);
3708 				}
3709 
3710 				break;
3711 
3712 			case 13:
3713 				if( !GET_Z )
3714 				{
3715 					SET_RD(1, NOINC);
3716 				}
3717 				else
3718 				{
3719 					SET_RD(0, NOINC);
3720 				}
3721 
3722 				break;
3723 
3724 			case 14:
3725 				if( GET_V )
3726 				{
3727 					SET_RD(1, NOINC);
3728 				}
3729 				else
3730 				{
3731 					SET_RD(0, NOINC);
3732 				}
3733 
3734 				break;
3735 
3736 			case 15:
3737 				if( !GET_V )
3738 				{
3739 					SET_RD(1, NOINC);
3740 				}
3741 				else
3742 				{
3743 					SET_RD(0, NOINC);
3744 				}
3745 
3746 				break;
3747 
3748 			case 18:
3749 				SET_RD(-1, NOINC);
3750 
3751 				break;
3752 
3753 			case 20:
3754 				if( GET_N || GET_Z )
3755 				{
3756 					SET_RD(-1, NOINC);
3757 				}
3758 				else
3759 				{
3760 					SET_RD(0, NOINC);
3761 				}
3762 
3763 				break;
3764 
3765 			case 21:
3766 				if( !GET_N && !GET_Z )
3767 				{
3768 					SET_RD(-1, NOINC);
3769 				}
3770 				else
3771 				{
3772 					SET_RD(0, NOINC);
3773 				}
3774 
3775 				break;
3776 
3777 			case 22:
3778 				if( GET_N )
3779 				{
3780 					SET_RD(-1, NOINC);
3781 				}
3782 				else
3783 				{
3784 					SET_RD(0, NOINC);
3785 				}
3786 
3787 				break;
3788 
3789 			case 23:
3790 				if( !GET_N )
3791 				{
3792 					SET_RD(-1, NOINC);
3793 				}
3794 				else
3795 				{
3796 					SET_RD(0, NOINC);
3797 				}
3798 
3799 				break;
3800 
3801 			case 24:
3802 				if( GET_C || GET_Z )
3803 				{
3804 					SET_RD(-1, NOINC);
3805 				}
3806 				else
3807 				{
3808 					SET_RD(0, NOINC);
3809 				}
3810 
3811 				break;
3812 
3813 			case 25:
3814 				if( !GET_C && !GET_Z )
3815 				{
3816 					SET_RD(-1, NOINC);
3817 				}
3818 				else
3819 				{
3820 					SET_RD(0, NOINC);
3821 				}
3822 
3823 				break;
3824 
3825 			case 26:
3826 				if( GET_C )
3827 				{
3828 					SET_RD(-1, NOINC);
3829 				}
3830 				else
3831 				{
3832 					SET_RD(0, NOINC);
3833 				}
3834 
3835 				break;
3836 
3837 			case 27:
3838 				if( !GET_C )
3839 				{
3840 					SET_RD(-1, NOINC);
3841 				}
3842 				else
3843 				{
3844 					SET_RD(0, NOINC);
3845 				}
3846 
3847 				break;
3848 
3849 			case 28:
3850 				if( GET_Z )
3851 				{
3852 					SET_RD(-1, NOINC);
3853 				}
3854 				else
3855 				{
3856 					SET_RD(0, NOINC);
3857 				}
3858 
3859 				break;
3860 
3861 			case 29:
3862 				if( !GET_Z )
3863 				{
3864 					SET_RD(-1, NOINC);
3865 				}
3866 				else
3867 				{
3868 					SET_RD(0, NOINC);
3869 				}
3870 
3871 				break;
3872 
3873 			case 30:
3874 				if( GET_V )
3875 				{
3876 					SET_RD(-1, NOINC);
3877 				}
3878 				else
3879 				{
3880 					SET_RD(0, NOINC);
3881 				}
3882 
3883 				break;
3884 
3885 			case 31:
3886 				if( !GET_V )
3887 				{
3888 					SET_RD(-1, NOINC);
3889 				}
3890 				else
3891 				{
3892 					SET_RD(0, NOINC);
3893 				}
3894 
3895 				break;
3896 
3897 			default:
3898 				log_cb(RETRO_LOG_DEBUG, LOGPRE "N value (%d) non defined in e132xs_set @ %x\n", n, PC );
3899 		}
3900 
3901 		e132xs_ICount -= 1;
3902 	}
3903 }
3904 
e132xs_mul(void)3905 void e132xs_mul(void)
3906 {
3907 	INT32 op1, op2;
3908 	INT32 single_word;
3909 
3910 	op1 = op2 = 0;
3911 
3912 	/*PC or SR aren't denoted, else result is undefined*/
3913 	if( (S_CODE == PC_CODE && !S_BIT) || (S_CODE == SR_CODE && !S_BIT) || (D_CODE == PC_CODE && !D_BIT) || (D_CODE == SR_CODE && !D_BIT) )
3914 	{
3915 		log_cb(RETRO_LOG_DEBUG, LOGPRE "Denoted PC or SR in MUL instruction @ x\n", PC );
3916 	}
3917 	else
3918 	{
3919 		if( S_BIT )
3920 		{
3921 			op1 = GET_L_REG(S_CODE);
3922 		}
3923 		else
3924 		{
3925 			op1 = GET_G_REG(S_CODE);
3926 		}
3927 
3928 		if( D_BIT )
3929 		{
3930 			op2 = GET_L_REG(D_CODE);
3931 		}
3932 		else
3933 		{
3934 			op2 = GET_G_REG(D_CODE);
3935 		}
3936 
3937 		single_word = (op1 * op2) & 0xffffffff; /*only the low-order word is taken*/
3938 
3939 		SET_RD(single_word, NOINC);
3940 		SET_Z((single_word == 0 ? 1: 0));
3941 		SET_N(SIGN_BIT(single_word)); /*sign*/
3942 	/*	SET_V(); */ /*undefined*/
3943 	/*	SET_C(); */ /*undefined*/
3944 	}
3945 
3946 	if( ( op1 >= 0xffff8000 && op1 <= 0x7fff ) && ( op2 >= 0xffff8000 && op2 <= 0x7fff ) )
3947 		e132xs_ICount -= 3;
3948 	else
3949 		e132xs_ICount -= 5;
3950 }
3951 
e132xs_fadd(void)3952 void e132xs_fadd(void)
3953 {
3954 }
3955 
e132xs_faddd(void)3956 void e132xs_faddd(void)
3957 {
3958 }
3959 
e132xs_fsub(void)3960 void e132xs_fsub(void)
3961 {
3962 }
3963 
e132xs_fsubd(void)3964 void e132xs_fsubd(void)
3965 {
3966 }
3967 
e132xs_fmul(void)3968 void e132xs_fmul(void)
3969 {
3970 }
3971 
e132xs_fmuld(void)3972 void e132xs_fmuld(void)
3973 {
3974 }
3975 
e132xs_fdiv(void)3976 void e132xs_fdiv(void)
3977 {
3978 }
3979 
e132xs_fdivd(void)3980 void e132xs_fdivd(void)
3981 {
3982 }
3983 
e132xs_fcmp(void)3984 void e132xs_fcmp(void)
3985 {
3986 }
3987 
e132xs_fcmpd(void)3988 void e132xs_fcmpd(void)
3989 {
3990 }
3991 
e132xs_fcmpu(void)3992 void e132xs_fcmpu(void)
3993 {
3994 }
3995 
e132xs_fcmpud(void)3996 void e132xs_fcmpud(void)
3997 {
3998 }
3999 
e132xs_fcvt(void)4000 void e132xs_fcvt(void)
4001 {
4002 }
4003 
e132xs_fcvtd(void)4004 void e132xs_fcvtd(void)
4005 {
4006 }
4007 
e132xs_extend(void)4008 void e132xs_extend(void)
4009 {
4010 	/*TODO: add locks, overflow error and other things*/
4011 	UINT16 ext_opcode;
4012 	UINT32 vals, vald;
4013 
4014 	vals = GET_L_REG(S_CODE);
4015 	vald = GET_L_REG(D_CODE);
4016 
4017 	PC += 2;
4018 	ext_opcode = READ_OP(PC);
4019 
4020 	switch( ext_opcode )
4021 	{
4022 		/* signed or unsigned multiplication, single word product*/
4023 		case EMUL:
4024 		{
4025 			UINT32 result;
4026 
4027 			result = vals * vald;
4028 			SET_G_REG(15, result);
4029 
4030 			break;
4031 		}
4032 		/* unsigned multiplication, double word product*/
4033 		case EMULU:
4034 		{
4035 			UINT64 result;
4036 
4037 			result = vals * vald;
4038 			vals = (result & 0xffffffff00000000) >> 32;
4039 			vald = result & 0x00000000ffffffff;
4040 			SET_G_REG(14, vals);
4041 			SET_G_REG(15, vald);
4042 
4043 			break;
4044 		}
4045 		/* signed multiplication, double word product*/
4046 		case EMULS:
4047 		{
4048 			INT64 result;
4049 
4050 			result = (INT32)vals * (INT32)vald;
4051 			vals = (result & 0xffffffff00000000) >> 32;
4052 			vald = result & 0x00000000ffffffff;
4053 			SET_G_REG(14, vals);
4054 			SET_G_REG(15, vald);
4055 
4056 			break;
4057 		}
4058 		/* signed multiply/add, single word product sum*/
4059 		case EMAC:
4060 		{
4061 			INT32 result;
4062 
4063 			result = GET_G_REG(15) + ((INT32)vals * (INT32)vald);
4064 			SET_G_REG(15, result);
4065 
4066 			break;
4067 		}
4068 		/* signed multiply/add, double word product sum*/
4069 		case EMACD:
4070 		{
4071 			INT64 result;
4072 
4073 			result = COMBINE_64_32_32(GET_G_REG(14), GET_G_REG(15)) + ((INT32)vals * (INT32)vald);
4074 
4075 			vals = (result & 0xffffffff00000000) >> 32;
4076 			vald = result & 0x00000000ffffffff;
4077 			SET_G_REG(14, vals);
4078 			SET_G_REG(15, vald);
4079 
4080 			break;
4081 		}
4082 		/* signed multiply/substract, single word product difference*/
4083 		case EMSUB:
4084 		{
4085 			INT32 result;
4086 
4087 			result = GET_G_REG(15) - ((INT32)vals * (INT32)vald);
4088 			SET_G_REG(15, result);
4089 
4090 			break;
4091 		}
4092 		/* signed multiply/substract, double word product difference*/
4093 		case EMSUBD:
4094 		{
4095 			INT64 result;
4096 
4097 			result = COMBINE_64_32_32(GET_G_REG(14), GET_G_REG(15)) - ((INT32)vals * (INT32)vald);
4098 
4099 			vals = (result & 0xffffffff00000000) >> 32;
4100 			vald = result & 0x00000000ffffffff;
4101 			SET_G_REG(14, vals);
4102 			SET_G_REG(15, vald);
4103 
4104 			break;
4105 		}
4106 		/* signed half-word multiply/add, single word product sum*/
4107 		case EHMAC:
4108 		{
4109 			INT32 result;
4110 
4111 			result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) + ((vald & 0xffff) * (vals & 0xffff));
4112 			SET_G_REG(15, result);
4113 
4114 			break;
4115 		}
4116 		/* signed half-word multiply/add, double word product sum*/
4117 		case EHMACD:
4118 		{
4119 			INT64 result;
4120 
4121 			result = COMBINE_64_32_32(GET_G_REG(14), GET_G_REG(15)) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) + ((vald & 0xffff) * (vals & 0xffff));
4122 
4123 			vals = (result & 0xffffffff00000000) >> 32;
4124 			vald = result & 0x00000000ffffffff;
4125 			SET_G_REG(14, vals);
4126 			SET_G_REG(15, vald);
4127 
4128 			break;
4129 		}
4130 		/* half-word complex multiply*/
4131 		case EHCMULD:
4132 		{
4133 			UINT32 result;
4134 
4135 			result = (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
4136 			SET_G_REG(14, result);
4137 
4138 			result = (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
4139 			SET_G_REG(15, result);
4140 
4141 			break;
4142 		}
4143 		/* half-word complex multiply/add*/
4144 		case EHCMACD:
4145 		{
4146 			UINT32 result;
4147 
4148 			result = GET_G_REG(14) + (((vald & 0xffff0000) >> 16) * ((vals & 0xffff0000) >> 16)) - ((vald & 0xffff) * (vals & 0xffff));
4149 			SET_G_REG(14, result);
4150 
4151 			result = GET_G_REG(15) + (((vald & 0xffff0000) >> 16) * (vals & 0xffff)) + ((vald & 0xffff) * ((vals & 0xffff0000) >> 16));
4152 			SET_G_REG(15, result);
4153 
4154 			break;
4155 		}
4156 		/* half-word (complex) add/substract*/
4157 		/* Ls is not used and should denote the same register as Ld*/
4158 		case EHCSUMD:
4159 		{
4160 			UINT32 result;
4161 
4162 			result = ((((vals & 0xffff0000) >> 16) + GET_G_REG(14)) << 16) & 0xffff0000;
4163 			result |= ((vals & 0xffff) + GET_G_REG(15)) & 0xffff;
4164 			SET_G_REG(14, result);
4165 
4166 			result = ((((vals & 0xffff0000) >> 16) - GET_G_REG(14)) << 16) & 0xffff0000;
4167 			result |= ((vals & 0xffff) - GET_G_REG(15)) & 0xffff;
4168 			SET_G_REG(15, result);
4169 
4170 			break;
4171 		}
4172 		/* half-word (complex) add/substract with fixed point adjustment*/
4173 		/* Ls is not used and should denote the same register as Ld*/
4174 		case EHCFFTD:
4175 		{
4176 			UINT32 result;
4177 
4178 			result = ((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) << 16) & 0xffff0000;
4179 			result |= ((vals & 0xffff) + (GET_G_REG(15) >> 15)) & 0xffff;
4180 			SET_G_REG(14, result);
4181 
4182 			result = ((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) << 16) & 0xffff0000;
4183 			result |= ((vals & 0xffff) - (GET_G_REG(15) >> 15)) & 0xffff;
4184 			SET_G_REG(15, result);
4185 
4186 			break;
4187 		}
4188 		/* half-word (complex) add/substract with fixed point adjustment and shift*/
4189 		/* Ls is not used and should denote the same register as Ld*/
4190 		case EHCFFTSD:
4191 		{
4192 			UINT32 result;
4193 
4194 			result = (((((vals & 0xffff0000) >> 16) + (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000;
4195 			result |= ((((vals & 0xffff) + (GET_G_REG(15) >> 15)) >> 1) & 0xffff);
4196 			SET_G_REG(14, result);
4197 
4198 			result = (((((vals & 0xffff0000) >> 16) - (GET_G_REG(14) >> 15)) >> 1) << 16) & 0xffff0000;
4199 			result |= ((((vals & 0xffff) - (GET_G_REG(15) >> 15)) >> 1) & 0xffff);
4200 			SET_G_REG(15, result);
4201 
4202 			break;
4203 		}
4204 		default:
4205 			log_cb(RETRO_LOG_DEBUG, LOGPRE "Illegal extended opcode (%x) @ %x\n", ext_opcode, PC );
4206 			break;
4207 	}
4208 
4209 	e132xs_ICount -= 1; /*TODO: with the latency it can change*/
4210 }
4211 
e132xs_do(void)4212 void e132xs_do(void)
4213 {
4214 }
4215 
e132xs_ldwr(void)4216 void e132xs_ldwr(void)
4217 {
4218 	UINT32 val;
4219 
4220 	val = GET_L_REG( D_CODE );
4221 
4222 	if( S_BIT )
4223 	{
4224 		SET_L_REG( S_CODE, READ_W(val) );
4225 	}
4226 	else
4227 	{
4228 		SET_G_REG( S_CODE, READ_W(val) );
4229 	}
4230 
4231 	e132xs_ICount -= 1;
4232 }
4233 
e132xs_lddr(void)4234 void e132xs_lddr(void)
4235 {
4236 	UINT32 val_high, val_low;
4237 
4238 	val_high = GET_L_REG( D_CODE );
4239 	val_low = GET_L_REG( D_CODE ) + 4;
4240 
4241 	if( S_BIT )
4242 	{
4243 		SET_L_REG( S_CODE, READ_W(val_high) );
4244 		SET_L_REG( S_CODE + INC, READ_W(val_low) );
4245 	}
4246 	else
4247 	{
4248 		SET_G_REG( S_CODE, READ_W(val_high) );
4249 		SET_G_REG( S_CODE + INC, READ_W(val_low) );
4250 	}
4251 
4252 	e132xs_ICount -= 2;
4253 }
4254 
e132xs_ldwp(void)4255 void e132xs_ldwp(void)
4256 {
4257 	UINT32 val;
4258 
4259 	val = GET_L_REG( D_CODE );
4260 
4261 	if( S_BIT )
4262 	{
4263 		SET_L_REG( S_CODE, READ_W(val) );
4264 	}
4265 	else
4266 	{
4267 		SET_G_REG( S_CODE, READ_W(val) );
4268 	}
4269 
4270 	SET_L_REG( D_CODE, val + 4 );
4271 
4272 	e132xs_ICount -= 1;
4273 }
4274 
e132xs_lddp(void)4275 void e132xs_lddp(void)
4276 {
4277 	UINT32 val_high, val_low;
4278 
4279 	val_high = GET_L_REG( D_CODE );
4280 	val_low = GET_L_REG( D_CODE ) + 4;
4281 
4282 	if( S_BIT )
4283 	{
4284 		SET_L_REG( S_CODE, READ_W(val_high) );
4285 		SET_L_REG( S_CODE + INC, READ_W(val_low) );
4286 	}
4287 	else
4288 	{
4289 		SET_G_REG( S_CODE, READ_W(val_high) );
4290 		SET_G_REG( S_CODE + INC, READ_W(val_low) );
4291 	}
4292 
4293 	SET_L_REG( D_CODE, GET_L_REG( D_CODE ) + 8 );
4294 
4295 	e132xs_ICount -= 2;
4296 }
4297 
e132xs_stwr(void)4298 void e132xs_stwr(void)
4299 {
4300 	UINT32 val;
4301 
4302 	if( S_BIT )
4303 	{
4304 		val = GET_L_REG(S_CODE);
4305 	}
4306 	else
4307 	{
4308 		val = GET_G_REG(S_CODE);
4309 	}
4310 
4311 	WRITE_W( GET_L_REG(D_CODE), val );
4312 
4313 	e132xs_ICount -= 1;
4314 }
4315 
e132xs_stdr(void)4316 void e132xs_stdr(void)
4317 {
4318 	UINT32 val_high, val_low;
4319 
4320 	if( S_BIT )
4321 	{
4322 		val_high = GET_L_REG(S_CODE);
4323 		val_low  = GET_L_REG(S_CODE + INC);
4324 	}
4325 	else
4326 	{
4327 		val_high = GET_G_REG(S_CODE);
4328 		val_low  = GET_G_REG(S_CODE + INC);
4329 	}
4330 
4331 	WRITE_W( GET_L_REG(D_CODE), val_high );
4332 	WRITE_W( GET_L_REG(D_CODE) + 4, val_low );
4333 
4334 	e132xs_ICount -= 2;
4335 }
4336 
e132xs_stwp(void)4337 void e132xs_stwp(void)
4338 {
4339 	UINT32 val;
4340 
4341 	if( S_BIT )
4342 	{
4343 		val = GET_L_REG(S_CODE);
4344 	}
4345 	else
4346 	{
4347 		val = GET_G_REG(S_CODE);
4348 	}
4349 
4350 	WRITE_W( GET_L_REG(D_CODE), val );
4351 	SET_L_REG( D_CODE, GET_L_REG(D_CODE) + 4 );
4352 
4353 	e132xs_ICount -= 1;
4354 }
4355 
e132xs_stdp(void)4356 void e132xs_stdp(void)
4357 {
4358 	UINT32 val_high, val_low;
4359 
4360 	if( S_BIT )
4361 	{
4362 		val_high = GET_L_REG(S_CODE);
4363 		val_low  = GET_L_REG(S_CODE + INC);
4364 	}
4365 	else
4366 	{
4367 		val_high = GET_G_REG(S_CODE);
4368 		val_low  = GET_G_REG(S_CODE + INC);
4369 	}
4370 
4371 	WRITE_W( GET_L_REG(D_CODE), val_high );
4372 	WRITE_W( GET_L_REG(D_CODE) + 4, val_low );
4373 	SET_L_REG( D_CODE, GET_L_REG(D_CODE) + 8 );
4374 
4375 	e132xs_ICount -= 2;
4376 }
4377 
e132xs_dbv(void)4378 void e132xs_dbv(void)
4379 {
4380 	if( GET_V )
4381 		execute_dbr(get_pcrel());
4382 	else
4383 		e132xs_ICount -= 1;
4384 }
4385 
e132xs_dbnv(void)4386 void e132xs_dbnv(void)
4387 {
4388 	if( !GET_V )
4389 		execute_dbr(get_pcrel());
4390 	else
4391 		e132xs_ICount -= 1;
4392 }
4393 
e132xs_dbe(void)4394 void e132xs_dbe(void) /*or DBZ*/
4395 {
4396 	if( GET_Z )
4397 		execute_dbr(get_pcrel());
4398 	else
4399 		e132xs_ICount -= 1;
4400 }
4401 
e132xs_dbne(void)4402 void e132xs_dbne(void) /*or DBNZ*/
4403 {
4404 	if( !GET_Z )
4405 		execute_dbr(get_pcrel());
4406 	else
4407 		e132xs_ICount -= 1;
4408 }
4409 
e132xs_dbc(void)4410 void e132xs_dbc(void) /*or DBST*/
4411 {
4412 	if( GET_C )
4413 		execute_dbr(get_pcrel());
4414 	else
4415 		e132xs_ICount -= 1;
4416 }
4417 
e132xs_dbnc(void)4418 void e132xs_dbnc(void) /*or DBHE*/
4419 {
4420 	if( !GET_C )
4421 		execute_dbr(get_pcrel());
4422 	else
4423 		e132xs_ICount -= 1;
4424 }
4425 
e132xs_dbse(void)4426 void e132xs_dbse(void)
4427 {
4428 	if( GET_C || GET_Z )
4429 		execute_dbr(get_pcrel());
4430 	else
4431 		e132xs_ICount -= 1;
4432 }
4433 
e132xs_dbht(void)4434 void e132xs_dbht(void)
4435 {
4436 	if( !GET_C && !GET_Z )
4437 		execute_dbr(get_pcrel());
4438 	else
4439 		e132xs_ICount -= 1;
4440 }
4441 
e132xs_dbn(void)4442 void e132xs_dbn(void) /*or DBLT*/
4443 {
4444 	if( GET_N )
4445 		execute_dbr(get_pcrel());
4446 	else
4447 		e132xs_ICount -= 1;
4448 }
4449 
e132xs_dbnn(void)4450 void e132xs_dbnn(void) /*or DBGE*/
4451 {
4452 	if( !GET_N )
4453 		execute_dbr(get_pcrel());
4454 	else
4455 		e132xs_ICount -= 1;
4456 }
4457 
e132xs_dble(void)4458 void e132xs_dble(void)
4459 {
4460 	if( GET_N || GET_Z )
4461 		execute_dbr(get_pcrel());
4462 	else
4463 		e132xs_ICount -= 1;
4464 }
4465 
e132xs_dbgt(void)4466 void e132xs_dbgt(void)
4467 {
4468 	if( !GET_N && !GET_Z )
4469 		execute_dbr(get_pcrel());
4470 	else
4471 		e132xs_ICount -= 1;
4472 }
4473 
e132xs_dbr(void)4474 void e132xs_dbr(void)
4475 {
4476 	execute_dbr(get_pcrel());
4477 }
4478 
e132xs_frame(void)4479 void e132xs_frame(void)
4480 {
4481 	/*TODO: check the bounds?*/
4482 
4483 	UINT8 difference; /*really it's 7 bits*/
4484 
4485 	SET_FP((GET_FP - S_CODE));
4486 
4487 	if( D_CODE )
4488 		SET_FL( D_CODE );
4489 	else
4490 		SET_FL( 16 ); /*when Ld is L0*/
4491 
4492 	SET_M( 0 );
4493 
4494 	/*TODO: SP uses bits 8..0 as in the doc or 7..2 ?*/
4495 	if( GET_FL )
4496 		difference = ( SP & 0x1fc ) + ( 64 - 10 ) - ( GET_FP + GET_FL );
4497 	else
4498 		difference = ( SP & 0x1fc ) + ( 64 - 10 ) - ( GET_FP + 16 );
4499 
4500 	/* bit 6 of difference is sign*/
4501 	if( difference & 0x40 ) /*else it's finished*/
4502 	{
4503 		unsigned char tmp_flag;
4504 
4505 		tmp_flag = ( SP >= UB ? 1 : 0 );
4506 
4507 		do
4508 		{
4509 			WRITE_W(SP, ( SP & 0xfc ) );
4510 			SP += 4;
4511 			difference++;
4512 			difference = ((difference & 0x7f) + ((difference & 0x80) >> 7)) & 0x7f;
4513 
4514 		} while( !( difference & 0x40 ) );
4515 
4516 		if( tmp_flag )
4517 		{
4518 			UINT32 addr = get_trap_addr(FRAME_ERROR);
4519 			execute_trap(addr);
4520 		}
4521 	}
4522 
4523 	/*TODO: no 1!*/
4524 	e132xs_ICount -= 1;
4525 }
4526 
e132xs_call(void)4527 void e132xs_call(void)
4528 {
4529 	INT32 const_val;
4530 
4531 	/*TODO: add -> bit 0 of const must be 0 ?*/
4532 	const_val = get_const();
4533 
4534 	log_cb(RETRO_LOG_DEBUG, LOGPRE "Immediate value for CALL: %04x\n", const_val );
4535 
4536 	if( !(S_CODE == SR_CODE && !S_BIT) )
4537 	{
4538 		if( S_BIT )
4539 		{
4540 			const_val += GET_L_REG(S_CODE);
4541 		}
4542 		else
4543 		{
4544 			const_val += GET_G_REG(S_CODE);
4545 		}
4546 	}
4547 
4548 	SET_LD(((PC & 0xfffffffe) | GET_S), NOINC);
4549 	SET_LD(SR, INC);
4550 
4551 	if( D_CODE )
4552 		SET_FP((GET_FP + D_CODE));
4553 	else
4554 		SET_FP((GET_FP + 16));
4555 
4556 	SET_FL(6);
4557 	SET_M(0);
4558 
4559 	PPC = PC;
4560 	PC = const_val;
4561 
4562 	/*TODO: add interrupt locks, errors, ....*/
4563 
4564 	/*TODO: no 1!*/
4565 	e132xs_ICount -= 1;
4566 }
4567 
e132xs_bv(void)4568 void e132xs_bv(void)
4569 {
4570 	if( GET_V )
4571 		execute_br(get_pcrel());
4572 	else
4573 		e132xs_ICount -= 1;
4574 }
4575 
e132xs_bnv(void)4576 void e132xs_bnv(void)
4577 {
4578 	if( !GET_V )
4579 		execute_br(get_pcrel());
4580 	else
4581 		e132xs_ICount -= 1;
4582 }
4583 
e132xs_be(void)4584 void e132xs_be(void) /*or BZ*/
4585 {
4586 	if( GET_Z )
4587 		execute_br(get_pcrel());
4588 	else
4589 		e132xs_ICount -= 1;
4590 }
4591 
e132xs_bne(void)4592 void e132xs_bne(void) /*or BNZ*/
4593 {
4594 	if( !GET_Z )
4595 		execute_br(get_pcrel());
4596 	else
4597 		e132xs_ICount -= 1;
4598 }
4599 
e132xs_bc(void)4600 void e132xs_bc(void) /*or BST*/
4601 {
4602 	if( GET_C )
4603 		execute_br(get_pcrel());
4604 	else
4605 		e132xs_ICount -= 1;
4606 }
4607 
e132xs_bnc(void)4608 void e132xs_bnc(void) /*or BHE*/
4609 {
4610 	if( !GET_C )
4611 		execute_br(get_pcrel());
4612 	else
4613 		e132xs_ICount -= 1;
4614 }
4615 
e132xs_bse(void)4616 void e132xs_bse(void)
4617 {
4618 	if( GET_C || GET_Z )
4619 		execute_br(get_pcrel());
4620 	else
4621 		e132xs_ICount -= 1;
4622 }
4623 
e132xs_bht(void)4624 void e132xs_bht(void)
4625 {
4626 	if( !GET_C && !GET_Z )
4627 		execute_br(get_pcrel());
4628 	else
4629 		e132xs_ICount -= 1;
4630 }
4631 
e132xs_bn(void)4632 void e132xs_bn(void) /*or BLT*/
4633 {
4634 	if( GET_N )
4635 		execute_br(get_pcrel());
4636 	else
4637 		e132xs_ICount -= 1;
4638 }
4639 
e132xs_bnn(void)4640 void e132xs_bnn(void) /*or BGE*/
4641 {
4642 	if( !GET_N )
4643 		execute_br(get_pcrel());
4644 	else
4645 		e132xs_ICount -= 1;
4646 }
4647 
e132xs_ble(void)4648 void e132xs_ble(void)
4649 {
4650 	if( GET_N || GET_Z )
4651 		execute_br(get_pcrel());
4652 	else
4653 		e132xs_ICount -= 1;
4654 }
4655 
e132xs_bgt(void)4656 void e132xs_bgt(void)
4657 {
4658 	if( !GET_N && !GET_Z )
4659 		execute_br(get_pcrel());
4660 	else
4661 		e132xs_ICount -= 1;
4662 }
4663 
e132xs_br(void)4664 void e132xs_br(void)
4665 {
4666 	execute_br(get_pcrel());
4667 }
4668 
e132xs_trap(void)4669 void e132xs_trap(void)
4670 {
4671 	unsigned int code;
4672 	UINT32 addr;
4673 
4674 	addr = 0xffffff00 | (OP & 0xfc); /*TODO: what do i need to use? 0xffffff00 or entry_point or GET_TRAP_ADDR ?*/
4675 	/*TODO: what is the trapno ?*/
4676 	code = ((OP & 0x300) >> 6) | (OP & 0x03);
4677 
4678 	switch( code )
4679 	{
4680 	/*	case 0:
4681 		case 1:
4682 		case 2:
4683 		case 3:
4684 			log_cb(RETRO_LOG_DEBUG, LOGPRE "- Trap code not available (%d) @ %x\n", trapno, PC );
4685 			break;
4686 	*/
4687 		case TRAPLE:
4688 			if( GET_N || GET_Z )
4689 				execute_trap(addr);
4690 
4691 			break;
4692 
4693 		case TRAPGT:
4694 			if( !GET_N && !GET_Z )
4695 				execute_trap(addr);
4696 
4697 			break;
4698 
4699 		case TRAPLT:
4700 			if( GET_N )
4701 				execute_trap(addr);
4702 
4703 			break;
4704 
4705 		case TRAPGE:
4706 			if( !GET_N )
4707 				execute_trap(addr);
4708 
4709 			break;
4710 
4711 		case TRAPSE:
4712 			if( GET_C || GET_Z )
4713 				execute_trap(addr);
4714 
4715 			break;
4716 
4717 		case TRAPHT:
4718 			if( !GET_C && !GET_Z )
4719 				execute_trap(addr);
4720 
4721 			break;
4722 
4723 		case TRAPST:
4724 			if( GET_C )
4725 				execute_trap(addr);
4726 
4727 			break;
4728 
4729 		case TRAPHE:
4730 			if( !GET_C )
4731 				execute_trap(addr);
4732 
4733 			break;
4734 
4735 		case TRAPE:
4736 			if( GET_Z )
4737 				execute_trap(addr);
4738 
4739 			break;
4740 
4741 		case TRAPNE:
4742 			if( !GET_Z )
4743 				execute_trap(addr);
4744 
4745 			break;
4746 
4747 		case TRAPV:
4748 			if( GET_V )
4749 				execute_trap(addr);
4750 
4751 			break;
4752 
4753 		case TRAP:
4754 			execute_trap(addr);
4755 
4756 			break;
4757 
4758 		default:
4759 			e132xs_ICount -= 1;
4760 	}
4761 }
4762