-
Notifications
You must be signed in to change notification settings - Fork 1
/
handlers.c
152 lines (126 loc) · 4.09 KB
/
handlers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/**********************************/
/* */
/* Copyright 2000, David Grant */
/* */
/* see LICENSE for more details */
/* */
/**********************************/
#include <stdio.h>
#include <stdarg.h>
#include "coldfire.h"
TRACER_DEFAULT_CHANNEL(handlers);
void SR_Set(s16 Instr, s32 Source, s32 Destination, s32 Result)
{
char Sm = (Source >= 0) ? 0 : 1;
char Dm = (Destination >= 0) ? 0 : 1;
char Rm = (Result >= 0) ? 0 : 1;
struct _sr sr_bak;
memcpy(&sr_bak, &memory_core.sr, sizeof(struct _sr));
TRACE("Setting Source=0x%08lx, Destination=0x%08lx, Result=0x%08lx\n", Source, Destination, Result);
TRACE("Sm=%d, Dm=%d, Rm=%d\n", Sm,Dm,Rm);
/* Clear out VCX */
memory_core.sr.v = 0;
memory_core.sr.c = 0;
memory_core.sr.x = 0;
/* N - Set if result is -ve, cleared otherwise
* They all do this */
memory_core.sr.n = Rm ? SR_N : 0;
/* Z - Set if result is zero, cleared otherwise
* They all do this too, except I_ADDX, I_SUBX, I_NEGX */
memory_core.sr.z = (Result == 0) ? SR_Z : 0;
switch(Instr) {
case I_ADDX:
/* Z - cleared if result is non-zero, unchanged otherwise */
case I_ADD: case I_ADDI: case I_ADDQ:
/* Set the status register */
/* X - Set to value of carry bit
N - Set if result is -ve, cleared otherwise
Z - Set if result is zero, cleared otherwise
V - Set if an overflow occurs, cleared otherwise
C - Set if a carry is generated, cleared otherwise
*/
if(Instr==I_ADDX) {
/* If result is 0, Z is unaffected, else cleared */
memory_core.sr.z = (Result == 0) ? sr_bak.z : 0;
}
if((Sm && Dm && !Rm) || (!Sm && !Dm && Rm) )
memory_core.sr.v = SR_V;
if((Sm && Dm) || (!Rm && Dm) || (Sm && !Rm) ) {
memory_core.sr.c = SR_C;
memory_core.sr.x = SR_X;
}
break;
case I_SUBX:
/* Z - cleared if result is non-zero, unchanged otherwise */
case I_SUB: case I_SUBI: case I_SUBQ:
/* Set the status register */
/* X - Set to value of carry bit
N - Set if result is -ve, cleared otherwise
Z - Set if result is zero, cleared otherwise
V - Set if an overflow occurs, cleared otherwise
C - Set if a borrow occurs, cleared otherwise
*/
if(Instr==I_SUBX) {
memory_core.sr.z = (Result == 0) ? sr_bak.z : 0;
}
if((!Sm && Dm && !Rm) || (Sm && !Dm && Rm) )
memory_core.sr.v = SR_V;
if((Sm && !Dm) || (Rm && !Dm) || (Sm && Rm) ) {
memory_core.sr.c = SR_C;
memory_core.sr.x = SR_X;
}
break;
case I_CMP: case I_CMPA: case I_CMPI:
/* Set the status register
* X - Not affected
* N - Set if result is -ve, cleared otherwise
* Z - Set if result is zero, cleared otherwise
* V - Set if an overflow occurs, cleared otherwise
* C - Set if a borrow occurs, cleared otherwise
*/
if((!Sm && Dm && !Rm) || (Sm && !Dm && Rm) )
memory_core.sr.v = SR_V;
if((Sm && !Dm) || (Rm && !Dm) || (Sm && Rm) )
memory_core.sr.c = SR_C;
/* Restore X */
memory_core.sr.x = sr_bak.x;
break;
case I_NEG:
/* X - Set to value of carry bit
N - Set if result is -ve, cleared otherwise
Z - Set if result is zero, cleared otherwise
V - Set if an overflow occurs, cleared otherwise
C - Cleared if the result is zero, set otherwise
*/
if(Dm && Rm) memory_core.sr.v = SR_V;
if(Dm || Rm) {
memory_core.sr.c = SR_C;
memory_core.sr.x = SR_X;
}
break;
case I_NEGX:
/* X - Set to value of carry bit
N - Set if result is -ve, cleared otherwise
Z - Cleared if the result is non-zero, unchanged otherwise
V - Set if an overflow occurs, cleared otherwise
C - Cleared if the result is zero, set otherwise
*/
memory_core.sr.z = (Result == 0) ? sr_bak.z : 0;
if(Dm && Rm) memory_core.sr.v = SR_V;
if(Dm || Rm) {
memory_core.sr.c = SR_C;
memory_core.sr.x = SR_X;
}
break;
default:
ERR("Called with unknown instruction %d\n", Instr);
break;
}
TRACE("X:%d, Neg:%d, Zero:%d, Overflow:%d, Carry:%d\n",
memory_core.sr.x ? 1 : 0,
memory_core.sr.n ? 1 : 0,
memory_core.sr.z ? 1 : 0,
memory_core.sr.v ? 1 : 0,
memory_core.sr.c ? 1 : 0);
return;
}