fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 324 lines 7.0 kB view raw
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}