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