fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
1/*****************************************************************************
2 * pce *
3 *****************************************************************************/
4
5/*****************************************************************************
6 * File name: src/cpu/e8086/flags.c *
7 * Created: 2003-04-18 by Hampa Hug <hampa@hampa.ch> *
8 * Copyright: (C) 2003-2009 Hampa Hug <hampa@hampa.ch> *
9 *****************************************************************************/
10
11/*****************************************************************************
12 * This program is free software. You can redistribute it and / or modify it *
13 * under the terms of the GNU General Public License version 2 as published *
14 * by the Free Software Foundation. *
15 * *
16 * This program is distributed in the hope that it will be useful, but *
17 * WITHOUT ANY WARRANTY, without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General *
19 * Public License for more details. *
20 *****************************************************************************/
21
22
23#include "e8086.h"
24#include "internal.h"
25
26
27static
28char parity[256] = {
29 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
30 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
31 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
32 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
33 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
34 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
35 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
36 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
37 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
38 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
39 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
40 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
41 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
42 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
43 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
44 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
45};
46
47
48/*************************************************************************
49 * Flags functions
50 *************************************************************************/
51
52void e86_set_flg_szp_8 (e8086_t *c, unsigned char val)
53{
54 unsigned short set;
55
56 set = 0;
57
58 val &= 0xff;
59
60 if (val == 0) {
61 set |= E86_FLG_Z;
62 }
63 else if (val & 0x80) {
64 set |= E86_FLG_S;
65 }
66
67 if (parity[val] == 0) {
68 set |= E86_FLG_P;
69 }
70
71 c->flg &= ~(E86_FLG_S | E86_FLG_Z | E86_FLG_P);
72 c->flg |= set;
73}
74
75void e86_set_flg_szp_16 (e8086_t *c, unsigned short val)
76{
77 unsigned short set;
78
79 set = 0;
80
81 if ((val & 0xffff) == 0) {
82 set |= E86_FLG_Z;
83 }
84 else if (val & 0x8000) {
85 set |= E86_FLG_S;
86 }
87
88 if (parity[val & 0xff] == 0) {
89 set |= E86_FLG_P;
90 }
91
92 c->flg &= ~(E86_FLG_S | E86_FLG_Z | E86_FLG_P);
93 c->flg |= set;
94}
95
96void e86_set_flg_log_8 (e8086_t *c, unsigned char val)
97{
98 e86_set_flg_szp_8 (c, val);
99
100 c->flg &= ~(E86_FLG_C | E86_FLG_O);
101}
102
103void e86_set_flg_log_16 (e8086_t *c, unsigned short val)
104{
105 e86_set_flg_szp_16 (c, val);
106
107 c->flg &= ~(E86_FLG_C | E86_FLG_O);
108}
109
110void e86_set_flg_add_8 (e8086_t *c, unsigned char s1, unsigned char s2)
111{
112 unsigned short set;
113 unsigned short dst;
114
115 e86_set_flg_szp_8 (c, s1 + s2);
116
117 set = 0;
118
119 dst = (unsigned short) s1 + (unsigned short) s2;
120
121 if (dst & 0xff00) {
122 set |= E86_FLG_C;
123 }
124
125 if ((dst ^ s1) & (dst ^ s2) & 0x80) {
126 set |= E86_FLG_O;
127 }
128
129 if ((s1 ^ s2 ^ dst) & 0x10) {
130 set |= E86_FLG_A;
131 }
132
133 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
134 c->flg |= set;
135}
136
137void e86_set_flg_add_16 (e8086_t *c, unsigned short s1, unsigned short s2)
138{
139 unsigned short set;
140 unsigned long dst;
141
142 e86_set_flg_szp_16 (c, s1 + s2);
143
144 set = 0;
145
146 dst = (unsigned long) s1 + (unsigned long) s2;
147
148 if (dst & 0xffff0000) {
149 set |= E86_FLG_C;
150 }
151
152 if ((dst ^ s1) & (dst ^ s2) & 0x8000) {
153 set |= E86_FLG_O;
154 }
155
156 if ((s1 ^ s2 ^ dst) & 0x10) {
157 set |= E86_FLG_A;
158 }
159
160 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
161 c->flg |= set;
162}
163
164void e86_set_flg_adc_8 (e8086_t *c, unsigned char s1, unsigned char s2, unsigned char s3)
165{
166 unsigned short set;
167 unsigned short dst;
168
169 e86_set_flg_szp_8 (c, s1 + s2 + s3);
170
171 set = 0;
172
173 dst = (unsigned short) s1 + (unsigned short) s2 + (unsigned short) s3;
174
175 if (dst & 0xff00) {
176 set |= E86_FLG_C;
177 }
178
179 if ((dst ^ s1) & (dst ^ s2) & 0x80) {
180 set |= E86_FLG_O;
181 }
182
183 if ((s1 ^ s2 ^ dst) & 0x10) {
184 set |= E86_FLG_A;
185 }
186
187 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
188 c->flg |= set;
189}
190
191void e86_set_flg_adc_16 (e8086_t *c, unsigned short s1, unsigned short s2, unsigned short s3)
192{
193 unsigned short set;
194 unsigned long dst;
195
196 e86_set_flg_szp_16 (c, s1 + s2 + s3);
197
198 set = 0;
199
200 dst = (unsigned long) s1 + (unsigned long) s2 + (unsigned long) s3;
201
202 if (dst & 0xffff0000) {
203 set |= E86_FLG_C;
204 }
205
206 if ((dst ^ s1) & (dst ^ s2) & 0x8000) {
207 set |= E86_FLG_O;
208 }
209
210 if ((s1 ^ s2 ^ dst) & 0x10) {
211 set |= E86_FLG_A;
212 }
213
214 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
215 c->flg |= set;
216}
217
218void e86_set_flg_sbb_8 (e8086_t *c, unsigned char s1, unsigned char s2, unsigned char s3)
219{
220 unsigned short set;
221 unsigned short dst;
222
223 e86_set_flg_szp_8 (c, s1 - s2 - s3);
224
225 set = 0;
226
227 dst = s1 - s2 - s3;
228
229 if (dst & 0xff00) {
230 set |= E86_FLG_C;
231 }
232
233 if ((s1 ^ dst) & (s1 ^ s2) & 0x80) {
234 set |= E86_FLG_O;
235 }
236
237 if ((s1 ^ s2 ^ dst) & 0x10) {
238 set |= E86_FLG_A;
239 }
240
241 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
242 c->flg |= set;
243}
244
245void e86_set_flg_sbb_16 (e8086_t *c, unsigned short s1, unsigned short s2, unsigned short s3)
246{
247 unsigned short set;
248 unsigned long dst;
249
250 e86_set_flg_szp_16 (c, s1 - s2 - s3);
251
252 set = 0;
253
254 dst = (unsigned long) s1 - (unsigned long) s2 - (unsigned long) s3;
255
256 if (dst & 0xffff0000) {
257 set |= E86_FLG_C;
258 }
259
260 if ((s1 ^ dst) & (s1 ^ s2) & 0x8000) {
261 set |= E86_FLG_O;
262 }
263
264 if ((s1 ^ s2 ^ dst) & 0x10) {
265 set |= E86_FLG_A;
266 }
267
268 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
269 c->flg |= set;
270}
271
272void e86_set_flg_sub_8 (e8086_t *c, unsigned char s1, unsigned char s2)
273{
274 unsigned short set;
275 unsigned short dst;
276
277 e86_set_flg_szp_8 (c, s1 - s2);
278
279 set = 0;
280
281 dst = s1 - s2;
282
283 if (dst & 0xff00) {
284 set |= E86_FLG_C;
285 }
286
287 if ((s1 ^ dst) & (s1 ^ s2) & 0x80) {
288 set |= E86_FLG_O;
289 }
290
291 if ((s1 ^ s2 ^ dst) & 0x10) {
292 set |= E86_FLG_A;
293 }
294
295 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
296 c->flg |= set;
297}
298
299void e86_set_flg_sub_16 (e8086_t *c, unsigned short s1, unsigned short s2)
300{
301 unsigned short set;
302 unsigned long dst;
303
304 e86_set_flg_szp_16 (c, s1 - s2);
305
306 set = 0;
307
308 dst = (unsigned long) s1 - (unsigned long) s2;
309
310 if (dst & 0xffff0000) {
311 set |= E86_FLG_C;
312 }
313
314 if ((s1 ^ dst) & (s1 ^ s2) & 0x8000) {
315 set |= E86_FLG_O;
316 }
317
318 if ((s1 ^ s2 ^ dst) & 0x10) {
319 set |= E86_FLG_A;
320 }
321
322 c->flg &= ~(E86_FLG_C | E86_FLG_O | E86_FLG_A);
323 c->flg |= set;
324}