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