1 #define fatalerror	printf
2 
3 #define FPCC_N			0x08000000
4 #define FPCC_Z			0x04000000
5 #define FPCC_I			0x02000000
6 #define FPCC_NAN		0x01000000
7 
8 #define DOUBLE_INFINITY					U64(0x7ff0000000000000)
9 #define DOUBLE_EXPONENT					U64(0x7ff0000000000000)
10 #define DOUBLE_MANTISSA					U64(0x000fffffffffffff)
11 
SET_CONDITION_CODES(fp_reg reg)12 INLINE void SET_CONDITION_CODES(fp_reg reg)
13 {
14 	REG_FPSR &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);
15 
16 	// sign flag
17 	if (reg.i & U64(0x8000000000000000))
18 	{
19 		REG_FPSR |= FPCC_N;
20 	}
21 
22 	// zero flag
23 	if ((reg.i & U64(0x7fffffffffffffff)) == 0)
24 	{
25 		REG_FPSR |= FPCC_Z;
26 	}
27 
28 	// infinity flag
29 	if ((reg.i & U64(0x7fffffffffffffff)) == DOUBLE_INFINITY)
30 	{
31 		REG_FPSR |= FPCC_I;
32 	}
33 
34 	// NaN flag
35 	if (((reg.i & DOUBLE_EXPONENT) == DOUBLE_EXPONENT) && ((reg.i & DOUBLE_MANTISSA) != 0))
36 	{
37 		REG_FPSR |= FPCC_NAN;
38 	}
39 }
40 
TEST_CONDITION(int condition)41 INLINE int TEST_CONDITION(int condition)
42 {
43 	int n = (REG_FPSR & FPCC_N) != 0;
44 	int z = (REG_FPSR & FPCC_Z) != 0;
45 	int nan = (REG_FPSR & FPCC_NAN) != 0;
46 	int r = 0;
47 	switch (condition)
48 	{
49 		case 0x00:		return 0;							// False
50 		case 0x01:		return (z);							// Equal
51 		case 0x0e:		return (!z);						// Not Equal
52 		case 0x0f:		return 1;							// True
53 		case 0x12:		return (!(nan || z || n));			// Greater Than
54 		case 0x13:		return (z || !(nan || n));			// Greater or Equal
55 		case 0x14:		return (n && !(nan || z));			// Less Than
56 		case 0x15:		return (z || (n && !nan));			// Less Than or Equal
57 		case 0x1a:		return (nan || !(n || z));			// Not Less Than or Equal
58 		case 0x1b:		return (nan || z || !n);			// Not Less Than
59 		case 0x1c:		return (nan || (n && !z));			// Not Greater or Equal Than
60 		case 0x1d:		return (nan || z || n);				// Not Greater Than
61 
62 		default:		fatalerror("M68040: test_condition: unhandled condition %02X\n", condition);
63 	}
64 
65 	return r;
66 }
67 
READ_EA_8(int ea)68 static UINT8 READ_EA_8(int ea)
69 {
70 	int mode = (ea >> 3) & 0x7;
71 	int reg = (ea & 0x7);
72 
73 	switch (mode)
74 	{
75 		case 0:		// Dn
76 		{
77 			return REG_D[reg];
78 		}
79 		case 5:		// (d16, An)
80 		{
81 			UINT32 ea = EA_AY_DI_8();
82 			return m68ki_read_8(ea);
83 		}
84 		case 6:		// (An) + (Xn) + d8
85 		{
86 			UINT32 ea = EA_AY_IX_8();
87 			return m68ki_read_8(ea);
88 		}
89 		case 7:
90 		{
91 			switch (reg)
92 			{
93 				case 1:		// (xxx).L
94 				{
95 					UINT32 d1 = OPER_I_16();
96 					UINT32 d2 = OPER_I_16();
97 					UINT32 ea = (d1 << 16) | d2;
98 					return m68ki_read_8(ea);
99 				}
100 				case 4:		// #<data>
101 				{
102 					return  OPER_I_8();
103 				}
104 				default:	fatalerror("MC68040: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
105 			}
106 			break;
107 		}
108 		default:	fatalerror("MC68040: READ_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
109 	}
110 
111 	return 0;
112 }
113 
READ_EA_16(int ea)114 static UINT16 READ_EA_16(int ea)
115 {
116 	int mode = (ea >> 3) & 0x7;
117 	int reg = (ea & 0x7);
118 
119 	switch (mode)
120 	{
121 		case 0:		// Dn
122 		{
123 			return (UINT16)(REG_D[reg]);
124 		}
125 		case 2:		// (An)
126 		{
127 			UINT32 ea = REG_A[reg];
128 			return m68ki_read_16(ea);
129 		}
130 		case 5:		// (d16, An)
131 		{
132 			UINT32 ea = EA_AY_DI_16();
133 			return m68ki_read_16(ea);
134 		}
135 		case 6:		// (An) + (Xn) + d8
136 		{
137 			UINT32 ea = EA_AY_IX_16();
138 			return m68ki_read_16(ea);
139 		}
140 		case 7:
141 		{
142 			switch (reg)
143 			{
144 				case 1:		// (xxx).L
145 				{
146 					UINT32 d1 = OPER_I_16();
147 					UINT32 d2 = OPER_I_16();
148 					UINT32 ea = (d1 << 16) | d2;
149 					return m68ki_read_16(ea);
150 				}
151 				case 4:		// #<data>
152 				{
153 					return OPER_I_16();
154 				}
155 
156 				default:	fatalerror("MC68040: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
157 			}
158 			break;
159 		}
160 		default:	fatalerror("MC68040: READ_EA_16: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
161 	}
162 
163 	return 0;
164 }
165 
READ_EA_32(int ea)166 static UINT32 READ_EA_32(int ea)
167 {
168 	int mode = (ea >> 3) & 0x7;
169 	int reg = (ea & 0x7);
170 
171 	switch (mode)
172 	{
173 		case 0:		// Dn
174 		{
175 			return REG_D[reg];
176 		}
177 		case 2:		// (An)
178 		{
179 			UINT32 ea = REG_A[reg];
180 			return m68ki_read_32(ea);
181 		}
182 		case 3:		// (An)+
183 		{
184 			UINT32 ea = EA_AY_PI_32();
185 			return m68ki_read_32(ea);
186 		}
187 		case 5:		// (d16, An)
188 		{
189 			UINT32 ea = EA_AY_DI_32();
190 			return m68ki_read_32(ea);
191 		}
192 		case 6:		// (An) + (Xn) + d8
193 		{
194 			UINT32 ea = EA_AY_IX_32();
195 			return m68ki_read_32(ea);
196 		}
197 		case 7:
198 		{
199 			switch (reg)
200 			{
201 				case 1:		// (xxx).L
202 				{
203 					UINT32 d1 = OPER_I_16();
204 					UINT32 d2 = OPER_I_16();
205 					UINT32 ea = (d1 << 16) | d2;
206 					return m68ki_read_32(ea);
207 				}
208 				case 2:		// (d16, PC)
209 				{
210 					UINT32 ea = EA_PCDI_32();
211 					return m68ki_read_32(ea);
212 				}
213 				case 4:		// #<data>
214 				{
215 					return  OPER_I_32();
216 				}
217 				default:	fatalerror("MC68040: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
218 			}
219 			break;
220 		}
221 		default:	fatalerror("MC68040: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
222 	}
223 	return 0;
224 }
225 
WRITE_EA_32(int ea,UINT32 data)226 static void WRITE_EA_32(int ea, UINT32 data)
227 {
228 	int mode = (ea >> 3) & 0x7;
229 	int reg = (ea & 0x7);
230 
231 	switch (mode)
232 	{
233 		case 0:		// Dn
234 		{
235 			REG_D[reg] = data;
236 			break;
237 		}
238 		case 2:		// (An)
239 		{
240 			UINT32 ea = REG_A[reg];
241 			m68ki_write_32(ea, data);
242 			break;
243 		}
244 		case 3:		// (An)+
245 		{
246 			UINT32 ea = EA_AY_PI_32();
247 			m68ki_write_32(ea, data);
248 			break;
249 		}
250 		case 4:		// -(An)
251 		{
252 			UINT32 ea = EA_AY_PD_32();
253 			m68ki_write_32(ea, data);
254 			break;
255 		}
256 		case 5:		// (d16, An)
257 		{
258 			UINT32 ea = EA_AY_DI_32();
259 			m68ki_write_32(ea, data);
260 			break;
261 		}
262 		case 6:		// (An) + (Xn) + d8
263 		{
264 			UINT32 ea = EA_AY_IX_32();
265 			m68ki_write_32(ea, data);
266 			break;
267 		}
268 		case 7:
269 		{
270 			switch (reg)
271 			{
272 				case 1:		// (xxx).L
273 				{
274 					UINT32 d1 = OPER_I_16();
275 					UINT32 d2 = OPER_I_16();
276 					UINT32 ea = (d1 << 16) | d2;
277 					m68ki_write_32(ea, data);
278 					break;
279 				}
280 				case 2:		// (d16, PC)
281 				{
282 					UINT32 ea = EA_PCDI_32();
283 					m68ki_write_32(ea, data);
284 					break;
285 				}
286 				default:	fatalerror("MC68040: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
287 			}
288 			break;
289 		}
290 		default:	fatalerror("MC68040: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
291 	}
292 }
293 
READ_EA_64(int ea)294 static UINT64 READ_EA_64(int ea)
295 {
296 	int mode = (ea >> 3) & 0x7;
297 	int reg = (ea & 0x7);
298 	UINT32 h1, h2;
299 
300 	switch (mode)
301 	{
302 		case 2:		// (An)
303 		{
304 			UINT32 ea = REG_A[reg];
305 			h1 = m68ki_read_32(ea+0);
306 			h2 = m68ki_read_32(ea+4);
307 			return  (UINT64)(h1) << 32 | (UINT64)(h2);
308 		}
309 		case 3:		// (An)+
310 		{
311 			UINT32 ea = REG_A[reg];
312 			REG_A[reg] += 8;
313 			h1 = m68ki_read_32(ea+0);
314 			h2 = m68ki_read_32(ea+4);
315 			return  (UINT64)(h1) << 32 | (UINT64)(h2);
316 		}
317 		case 5:		// (d16, An)
318 		{
319 			UINT32 ea = EA_AY_DI_32();
320 			h1 = m68ki_read_32(ea+0);
321 			h2 = m68ki_read_32(ea+4);
322 			return  (UINT64)(h1) << 32 | (UINT64)(h2);
323 		}
324 		case 7:
325 		{
326 			switch (reg)
327 			{
328 				case 4:		// #<data>
329 				{
330 					h1 = OPER_I_32();
331 					h2 = OPER_I_32();
332 					return  (UINT64)(h1) << 32 | (UINT64)(h2);
333 				}
334 				case 2:		// (d16, PC)
335 				{
336 					UINT32 ea = EA_PCDI_32();
337 					h1 = m68ki_read_32(ea+0);
338 					h2 = m68ki_read_32(ea+4);
339 					return  (UINT64)(h1) << 32 | (UINT64)(h2);
340 				}
341 				default:	fatalerror("MC68040: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
342 			}
343 			break;
344 		}
345 		default:	fatalerror("MC68040: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
346 	}
347 
348 	return 0;
349 }
350 
WRITE_EA_64(int ea,UINT64 data)351 static void WRITE_EA_64(int ea, UINT64 data)
352 {
353 	int mode = (ea >> 3) & 0x7;
354 	int reg = (ea & 0x7);
355 
356 	switch (mode)
357 	{
358 		case 2:		// (An)
359 		{
360 			UINT32 ea = REG_A[reg];
361 			m68ki_write_32(ea, (UINT32)(data >> 32));
362 			m68ki_write_32(ea, (UINT32)(data));
363 			break;
364 		}
365 		case 4:		// -(An)
366 		{
367 			UINT32 ea;
368 			REG_A[reg] -= 8;
369 			ea = REG_A[reg];
370 			m68ki_write_32(ea+0, (UINT32)(data >> 32));
371 			m68ki_write_32(ea+4, (UINT32)(data));
372 			break;
373 		}
374 		case 5:		// (d16, An)
375 		{
376 			UINT32 ea = EA_AY_DI_32();
377 			m68ki_write_32(ea+0, (UINT32)(data >> 32));
378 			m68ki_write_32(ea+4, (UINT32)(data));
379 			break;
380 		}
381 		default:	fatalerror("MC68040: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (UINT32)(data >> 32), (UINT32)(data), REG_PC);
382 	}
383 }
384 
READ_EA_FPE(int ea)385 static fp_reg READ_EA_FPE(int ea)
386 {
387 	fp_reg r;
388 	int mode = (ea >> 3) & 0x7;
389 	int reg = (ea & 0x7);
390 
391 	// TODO: convert to extended floating-point!
392 
393 	switch (mode)
394 	{
395 		case 3:		// (An)+
396 		{
397 			UINT32 d1,d2,d3;
398 			UINT32 ea = REG_A[reg];
399 			REG_A[reg] += 12;
400 			d1 = m68ki_read_32(ea+0);
401 			d2 = m68ki_read_32(ea+4);
402 			d3 = m68ki_read_32(ea+8);
403 			r.i = (UINT64)(d1) << 32 | (UINT64)(d2);
404 			break;
405 		}
406 		default:	fatalerror("MC68040: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC);
407 	}
408 
409 	return r;
410 }
411 
WRITE_EA_FPE(int ea,fp_reg fpr)412 static void WRITE_EA_FPE(int ea, fp_reg fpr)
413 {
414 	int mode = (ea >> 3) & 0x7;
415 	int reg = (ea & 0x7);
416 
417 	// TODO: convert to extended floating-point!
418 
419 	switch (mode)
420 	{
421 		case 4:		// -(An)
422 		{
423 			UINT32 ea;
424 			REG_A[reg] -= 12;
425 			ea = REG_A[reg];
426 			m68ki_write_32(ea+0, (UINT32)((UINT64)fpr.i >> 32));
427 			m68ki_write_32(ea+4, (UINT32)(fpr.i));
428 			m68ki_write_32(ea+8, 0);
429 			break;
430 		}
431 		default:	fatalerror("MC68040: WRITE_EA_FPE: unhandled mode %d, reg %d, data %f at %08X\n", mode, reg, fpr.f, REG_PC);
432 	}
433 }
434 
435 
fpgen_rm_reg(UINT16 w2)436 static void fpgen_rm_reg(UINT16 w2)
437 {
438 	int ea = REG_IR & 0x3f;
439 	int rm = (w2 >> 14) & 0x1;
440 	int src = (w2 >> 10) & 0x7;
441 	int dst = (w2 >>  7) & 0x7;
442 	int opmode = w2 & 0x7f;
443 	double source;
444 
445 	if (rm)
446 	{
447 		switch (src)
448 		{
449 			case 0:		// Long-Word Integer
450 			{
451 				INT32 d = READ_EA_32(ea);
452 				source = (double)(d);
453 				break;
454 			}
455 			case 1:		// Single-precision Real
456 			{
457 				UINT32 d = READ_EA_32(ea);
458 				source = (double)(*(float*)&d);
459 				break;
460 			}
461 			case 2:		// Extended-precision Real
462 			{
463 				fatalerror("fpgen_rm_reg: extended-precision real load unimplemented at %08X\n", REG_PC-4);
464 				break;
465 			}
466 			case 3:		// Packed-decimal Real
467 			{
468 				fatalerror("fpgen_rm_reg: packed-decimal real load unimplemented at %08X\n", REG_PC-4);
469 				break;
470 			}
471 			case 4:		// Word Integer
472 			{
473 				INT16 d = READ_EA_16(ea);
474 				source = (double)(d);
475 				break;
476 			}
477 			case 5:		// Double-precision Real
478 			{
479 				UINT64 d = READ_EA_64(ea);
480 				source = *(double*)&d;
481 				break;
482 			}
483 			case 6:		// Byte Integer
484 			{
485 				INT8 d = READ_EA_8(ea);
486 				source = (double)(d);
487 				break;
488 			}
489 			default:	fatalerror("fmove_rm_reg: invalid source specifier at %08X\n", REG_PC-4);
490 		}
491 	}
492 	else
493 	{
494 		source = REG_FP[src].f;
495 	}
496 
497 	switch (opmode)
498 	{
499 		case 0x00:		// FMOVE
500 		{
501 			REG_FP[dst].f = source;
502 			USE_CYCLES(4);
503 			break;
504 		}
505 		case 0x04:		// FSQRT
506 		{
507 			REG_FP[dst].f = sqrt(source);
508 			SET_CONDITION_CODES(REG_FP[dst]);
509 			USE_CYCLES(109);
510 			break;
511 		}
512 		case 0x18:		// FABS
513 		{
514 			REG_FP[dst].f = fabs(source);
515 			SET_CONDITION_CODES(REG_FP[dst]);
516 			USE_CYCLES(3);
517 			break;
518 		}
519 		case 0x1a:		// FNEG
520 		{
521 			REG_FP[dst].f = -source;
522 			SET_CONDITION_CODES(REG_FP[dst]);
523 			USE_CYCLES(3);
524 			break;
525 		}
526 		case 0x20:		// FDIV
527 		{
528 			REG_FP[dst].f /= source;
529 			USE_CYCLES(43);
530 			break;
531 		}
532 		case 0x22:		// FADD
533 		{
534 			REG_FP[dst].f += source;
535 			SET_CONDITION_CODES(REG_FP[dst]);
536 			USE_CYCLES(9);
537 			break;
538 		}
539 		case 0x23:		// FMUL
540 		{
541 			REG_FP[dst].f *= source;
542 			SET_CONDITION_CODES(REG_FP[dst]);
543 			USE_CYCLES(11);
544 			break;
545 		}
546 		case 0x28:		// FSUB
547 		{
548 			REG_FP[dst].f -= source;
549 			SET_CONDITION_CODES(REG_FP[dst]);
550 			USE_CYCLES(9);
551 			break;
552 		}
553 		case 0x38:		// FCMP
554 		{
555 			fp_reg res;
556 			res.f = REG_FP[dst].f - source;
557 			SET_CONDITION_CODES(res);
558 			USE_CYCLES(7);
559 			break;
560 		}
561 		case 0x3a:		// FTST
562 		{
563 			fp_reg res;
564 			res.f = source;
565 			SET_CONDITION_CODES(res);
566 			USE_CYCLES(7);
567 			break;
568 		}
569 
570 		default:	fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
571 	}
572 }
573 
fmove_reg_mem(UINT16 w2)574 static void fmove_reg_mem(UINT16 w2)
575 {
576 	int ea = REG_IR & 0x3f;
577 	int src = (w2 >>  7) & 0x7;
578 	int dst = (w2 >> 10) & 0x7;
579 	//int kfactor = w2 & 0x7f;
580 
581 	switch (dst)
582 	{
583 		case 0:		// Long-Word Integer
584 		{
585 			INT32 d = (INT32)(REG_FP[src].f);
586 			WRITE_EA_32(ea, d);
587 			break;
588 		}
589 		case 1:		// Single-precision Real
590 		{
591 			float f = (float)(REG_FP[src].f);
592 			UINT32 d = *(UINT32 *)&f;
593 			WRITE_EA_32(ea, d);
594 			break;
595 		}
596 		case 2:		// Extended-precision Real
597 		{
598 			fatalerror("fmove_reg_mem: extended-precision real store unimplemented at %08X\n", REG_PC-4);
599 			break;
600 		}
601 		case 3:		// Packed-decimal Real with Static K-factor
602 		{
603 			fatalerror("fmove_reg_mem: packed-decimal real store unimplemented at %08X\n", REG_PC-4);
604 			break;
605 		}
606 		case 4:		// Word Integer
607 		{
608 			fatalerror("fmove_reg_mem: word integer store unimplemented at %08X\n", REG_PC-4);
609 			break;
610 		}
611 		case 5:		// Double-precision Real
612 		{
613 			UINT64 d = REG_FP[src].i;
614 			WRITE_EA_64(ea, d);
615 			break;
616 		}
617 		case 6:		// Byte Integer
618 		{
619 			fatalerror("fmove_reg_mem: byte integer store unimplemented at %08X\n", REG_PC-4);
620 			break;
621 		}
622 		case 7:		// Packed-decimal Real with Dynamic K-factor
623 		{
624 			fatalerror("fmove_reg_mem: packed-decimal real store unimplemented at %08X\n", REG_PC-4);
625 			break;
626 		}
627 	}
628 
629 	USE_CYCLES(12);
630 }
631 
fmove_fpcr(UINT16 w2)632 static void fmove_fpcr(UINT16 w2)
633 {
634 	int ea = REG_IR & 0x3f;
635 	int dir = (w2 >> 13) & 0x1;
636 	int reg = (w2 >> 10) & 0x7;
637 
638 	if (dir)	// From system control reg to <ea>
639 	{
640 		switch (reg)
641 		{
642 			case 1:		WRITE_EA_32(ea, REG_FPIAR); break;
643 			case 2:		WRITE_EA_32(ea, REG_FPSR); break;
644 			case 4:		WRITE_EA_32(ea, REG_FPCR); break;
645 			default:	fatalerror("fmove_fpcr: unknown reg %d, dir %d\n", reg, dir);
646 		}
647 	}
648 	else		// From <ea> to system control reg
649 	{
650 		switch (reg)
651 		{
652 			case 1:		REG_FPIAR = READ_EA_32(ea); break;
653 			case 2:		REG_FPSR = READ_EA_32(ea); break;
654 			case 4:		REG_FPCR = READ_EA_32(ea); break;
655 			default:	fatalerror("fmove_fpcr: unknown reg %d, dir %d\n", reg, dir);
656 		}
657 	}
658 
659 	USE_CYCLES(10);
660 }
661 
fmovem(UINT16 w2)662 static void fmovem(UINT16 w2)
663 {
664 	int i;
665 	int ea = REG_IR & 0x3f;
666 	int dir = (w2 >> 13) & 0x1;
667 	int mode = (w2 >> 11) & 0x3;
668 	int reglist = w2 & 0xff;
669 
670 	if (dir)	// From FP regs to mem
671 	{
672 		switch (mode)
673 		{
674 			case 0:		// Static register list, predecrement addressing mode
675 			{
676 				for (i=0; i < 8; i++)
677 				{
678 					if (reglist & (1 << i))
679 					{
680 						WRITE_EA_FPE(ea, REG_FP[i]);
681 						USE_CYCLES(2);
682 					}
683 				}
684 				break;
685 			}
686 
687 			default:	fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
688 		}
689 	}
690 	else		// From mem to FP regs
691 	{
692 		switch (mode)
693 		{
694 			case 2:		// Static register list, postincrement addressing mode
695 			{
696 				for (i=0; i < 8; i++)
697 				{
698 					if (reglist & (1 << i))
699 					{
700 						REG_FP[7-i] = READ_EA_FPE(ea);
701 						USE_CYCLES(2);
702 					}
703 				}
704 				break;
705 			}
706 
707 			default:	fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
708 		}
709 	}
710 }
711 
fbcc16(void)712 static void fbcc16(void)
713 {
714 	INT32 offset;
715 	int condition = REG_IR & 0x3f;
716 
717 	offset = (INT16)(OPER_I_16());
718 
719 	// TODO: condition and jump!!!
720 	if (TEST_CONDITION(condition))
721 	{
722 		m68ki_trace_t0();			   /* auto-disable (see m68kcpu.h) */
723 		m68ki_branch_16(offset-2);
724 	}
725 
726 	USE_CYCLES(7);
727 }
728 
fbcc32(void)729 static void fbcc32(void)
730 {
731 	INT32 offset;
732 	int condition = REG_IR & 0x3f;
733 
734 	offset = OPER_I_32();
735 
736 	// TODO: condition and jump!!!
737 	if (TEST_CONDITION(condition))
738 	{
739 		m68ki_trace_t0();			   /* auto-disable (see m68kcpu.h) */
740 		m68ki_branch_32(offset-4);
741 	}
742 
743 	USE_CYCLES(7);
744 }
745 
746 
m68040_fpu_op0(void)747 void m68040_fpu_op0(void)
748 {
749 	switch ((REG_IR >> 6) & 0x3)
750 	{
751 		case 0:
752 		{
753 			UINT16 w2 = OPER_I_16();
754 			switch ((w2 >> 13) & 0x7)
755 			{
756 				case 0x0:	// FPU ALU FP, FP
757 				case 0x2:	// FPU ALU ea, FP
758 				{
759 					fpgen_rm_reg(w2);
760 					break;
761 				}
762 
763 				case 0x3:	// FMOVE FP, ea
764 				{
765 					fmove_reg_mem(w2);
766 					break;
767 				}
768 
769 				case 0x4:	// FMOVE ea, FPCR
770 				case 0x5:	// FMOVE FPCR, ea
771 				{
772 					fmove_fpcr(w2);
773 					break;
774 				}
775 
776 				case 0x6:	// FMOVEM ea, list
777 				case 0x7:	// FMOVEM list, ea
778 				{
779 					fmovem(w2);
780 					break;
781 				}
782 
783 				default:	fatalerror("m68040_fpu_op0: unimplemented subop %d at %08X\n", (w2 >> 13) & 0x7, REG_PC-4);
784 			}
785 			break;
786 		}
787 
788 		case 2:		// FBcc disp16
789 		{
790 			fbcc16();
791 			break;
792 		}
793 		case 3:		// FBcc disp32
794 		{
795 			fbcc32();
796 			break;
797 		}
798 
799 		default:	fatalerror("m68040_fpu_op0: unimplemented main op %d\n", (REG_IR >> 6)	& 0x3);
800 	}
801 }
802 
m68040_fpu_op1(void)803 void m68040_fpu_op1(void)
804 {
805 	int ea = REG_IR & 0x3f;
806 
807 	switch ((REG_IR >> 6) & 0x3)
808 	{
809 		case 0:		// FSAVE <ea>
810 		{
811 			WRITE_EA_32(ea, 0x00000000);
812 			// TODO: correct state frame
813 			break;
814 		}
815 
816 		case 1:		// FRESTORE <ea>
817 		{
818 			READ_EA_32(ea);
819 			// TODO: correct state frame
820 			break;
821 		}
822 
823 		default:	fatalerror("m68040_fpu_op1: unimplemented op %d at %08X\n", (REG_IR >> 6) & 0x3, REG_PC-2);
824 	}
825 }
826 
827 
828 
829