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