|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * MC68000 emulation - machine dependent bits
5: *
6: * Copyright 1996 Bernd Schmidt
7: * Copyright 2004-2005 Richard Drummond
8: */
9:
10: /*
11: * Machine dependent structure for holding the 68k CCR flags
12: */
13: struct flag_struct {
14: unsigned int cznv;
15: unsigned int x;
16: };
17:
18: extern struct flag_struct regflags;
19:
20: /*
21: * The bits in the cznv field in the above structure are assigned to
22: * allow the easy mirroring of the x86 condition flags. (For example,
23: * from the AX register - the x86 overflow flag can be copied to AL
24: * with a setto %AL instr and the other flags copied to AH with an
25: * lahf instr).
26: *
27: * The 68k CZNV flags are thus assinged in cznv as:
28: *
29: * <--AL--> <--AH-->
30: * 76543210 FEDCBA98 --------- ---------
31: * xxxxxxxV NZxxxxxC xxxxxxxxx xxxxxxxxx
32: */
33:
34: #define FLAGBIT_N 15
35: #define FLAGBIT_Z 14
36: #define FLAGBIT_C 8
37: #define FLAGBIT_V 0
38: #define FLAGBIT_X 8
39:
40: #define FLAGVAL_N (1 << FLAGBIT_N)
41: #define FLAGVAL_Z (1 << FLAGBIT_Z)
42: #define FLAGVAL_C (1 << FLAGBIT_C)
43: #define FLAGVAL_V (1 << FLAGBIT_V)
44: #define FLAGVAL_X (1 << FLAGBIT_X)
45:
46: #define SET_ZFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_Z) | (((y) ? 1 : 0) << FLAGBIT_Z))
47: #define SET_CFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_C) | (((y) ? 1 : 0) << FLAGBIT_C))
48: #define SET_VFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_V) | (((y) ? 1 : 0) << FLAGBIT_V))
49: #define SET_NFLG(y) (regflags.cznv = (regflags.cznv & ~FLAGVAL_N) | (((y) ? 1 : 0) << FLAGBIT_N))
50: #define SET_XFLG(y) (regflags.x = ((y) ? 1 : 0) << FLAGBIT_X)
51:
52: #define GET_ZFLG() ((regflags.cznv >> FLAGBIT_Z) & 1)
53: #define GET_CFLG() ((regflags.cznv >> FLAGBIT_C) & 1)
54: #define GET_VFLG() ((regflags.cznv >> FLAGBIT_V) & 1)
55: #define GET_NFLG() ((regflags.cznv >> FLAGBIT_N) & 1)
56: #define GET_XFLG() ((regflags.x >> FLAGBIT_X) & 1)
57:
58: #define CLEAR_CZNV() (regflags.cznv = 0)
59: #define GET_CZNV() (regflags.cznv)
60: #define IOR_CZNV(X) (regflags.cznv |= (X))
61: #define SET_CZNV(X) (regflags.cznv = (X))
62:
63: #define COPY_CARRY() (regflags.x = regflags.cznv)
64:
65:
66: /*
67: * Test CCR condition
68: */
69: STATIC_INLINE int cctrue (int cc)
70: {
71: uae_u32 cznv = regflags.cznv;
72:
73: switch (cc) {
74: case 0: return 1; /* T */
75: case 1: return 0; /* F */
76: case 2: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) == 0; /* !CFLG && !ZFLG HI */
77: case 3: return (cznv & (FLAGVAL_C | FLAGVAL_Z)) != 0; /* CFLG || ZFLG LS */
78: case 4: return (cznv & FLAGVAL_C) == 0; /* !CFLG CC */
79: case 5: return (cznv & FLAGVAL_C) != 0; /* CFLG CS */
80: case 6: return (cznv & FLAGVAL_Z) == 0; /* !ZFLG NE */
81: case 7: return (cznv & FLAGVAL_Z) != 0; /* ZFLG EQ */
82: case 8: return (cznv & FLAGVAL_V) == 0; /* !VFLG VC */
83: case 9: return (cznv & FLAGVAL_V) != 0; /* VFLG VS */
84: case 10: return (cznv & FLAGVAL_N) == 0; /* !NFLG PL */
85: case 11: return (cznv & FLAGVAL_N) != 0; /* NFLG MI */
86: case 12: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) == 0; /* NFLG == VFLG GE */
87: case 13: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & FLAGVAL_N) != 0; /* NFLG != VFLG LT */
88: case 14: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG && (NFLG == VFLG) GT */
89: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) == 0;
90: case 15: cznv &= (FLAGVAL_N | FLAGVAL_Z | FLAGVAL_V); /* ZFLG && (NFLG != VFLG) LE */
91: return (((cznv << (FLAGBIT_N - FLAGBIT_V)) ^ cznv) & (FLAGVAL_N | FLAGVAL_Z)) != 0;
92: }
93: return 0;
94: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.