1  /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * MC68000 emulation - machine dependent bits
5   *
6   * Copyright 1996 Bernd Schmidt, Samuel Devulder
7   * Copyright 2004-2007 Richard Drummond
8   */
9 
10  /*
11   * Machine dependent structure for holding the 68k CCR flags
12   */
13 struct flag_struct {
14     unsigned short int cznv;
15     unsigned short int x;
16 };
17 
18 extern struct flag_struct regflags;
19 
20 /*
21  * The bits in the cznv field are assigned in correspondence to the
22  * CZNV flags in the 68k CCR register
23  */
24 #define FLAGBIT_N	3
25 #define FLAGBIT_Z	2
26 #define FLAGBIT_V	1
27 #define FLAGBIT_C	0
28 #define FLAGBIT_X	FLAGBIT_C
29 
30 #define FLAGVAL_N	(1 << FLAGBIT_N)
31 #define FLAGVAL_Z 	(1 << FLAGBIT_Z)
32 #define FLAGVAL_C	(1 << FLAGBIT_C)
33 #define FLAGVAL_V	(1 << FLAGBIT_V)
34 #define FLAGVAL_X	(1 << FLAGBIT_X)
35 
36 #define SET_ZFLG(y)	(regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) ? 1 : 0) << FLAGBIT_Z))
37 #define SET_CFLG(y)	(regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) ? 1 : 0) << FLAGBIT_C))
38 #define SET_VFLG(y)	(regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) ? 1 : 0) << FLAGBIT_V))
39 #define SET_NFLG(y)	(regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) ? 1 : 0) << FLAGBIT_N))
40 #define SET_XFLG(y)	(regflags.x    = ((y) ? 1 : 0) << FLAGBIT_X)
41 
42 #define GET_ZFLG()	((regflags.cznv >> FLAGBIT_Z) & 1)
43 #define GET_CFLG()	((regflags.cznv >> FLAGBIT_C) & 1)
44 #define GET_VFLG()	((regflags.cznv >> FLAGBIT_V) & 1)
45 #define GET_NFLG()	((regflags.cznv >> FLAGBIT_N) & 1)
46 #define GET_XFLG()	((regflags.x    >> FLAGBIT_X) & 1)
47 
48 #define CLEAR_CZNV()	(regflags.cznv  = 0)
49 #define GET_CZNV	(regflags.cznv)
50 #define IOR_CZNV(X) (regflags.cznv |= (X))
51 #define SET_CZNV(X) (regflags.cznv = (X))
52 
53 #define COPY_CARRY (regflags.x = regflags.cznv)
54 
55 /*
56  * Test CCR condition
57  */
cctrue(int cc)58 STATIC_INLINE int cctrue (int cc)
59 {
60     uae_u32 cznv = regflags.cznv;
61 
62     switch (cc) {
63 	case 0:  return 1;								/*				T  */
64 	case 1:  return 0;								/*				F  */
65 	case 2:  return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0;				/* !CFLG && !ZFLG		HI */
66 	case 3:  return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0;				/*  CFLG || ZFLG		LS */
67 	case 4:  return (cznv & FLAGVAL_C) == 0;					/* !CFLG			CC */
68 	case 5:  return (cznv & FLAGVAL_C) != 0;					/*  CFLG			CS */
69 	case 6:  return (cznv & FLAGVAL_Z) == 0;					/* !ZFLG			NE */
70 	case 7:  return (cznv & FLAGVAL_Z) != 0;					/*  ZFLG			EQ */
71 	case 8:  return (cznv & FLAGVAL_V) == 0;					/* !VFLG			VC */
72 	case 9:  return (cznv & FLAGVAL_V) != 0;					/*  VFLG			VS */
73 	case 10: return (cznv & FLAGVAL_N) == 0;					/* !NFLG			PL */
74 	case 11: return (cznv & FLAGVAL_N) != 0;					/*  NFLG			MI */
75 	case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0;	/*  NFLG == VFLG		GE */
76 	case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0;	/*  NFLG != VFLG		LT */
77 	case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V);				/* ZFLG && (NFLG == VFLG)	GT */
78 		 return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0;
79 	case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V);				/* ZFLG && (NFLG != VFLG)	LE */
80 		 return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0;
81     }
82     abort ();
83     return 0;
84 }
85