DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* 00020 Lazy flag system was designed after the same kind of system used in Bochs. 00021 Probably still some bugs left in here. 00022 */ 00023 00024 #include "dosbox.h" 00025 #include "cpu.h" 00026 #include "lazyflags.h" 00027 #include "pic.h" 00028 00029 LazyFlags lflags; 00030 00031 /* CF Carry Flag -- Set on high-order bit carry or borrow; cleared 00032 otherwise. 00033 */ 00034 Bit32u get_CF(void) { 00035 00036 switch (lflags.type) { 00037 case t_UNKNOWN: 00038 case t_INCb: 00039 case t_INCw: 00040 case t_INCd: 00041 case t_DECb: 00042 case t_DECw: 00043 case t_DECd: 00044 case t_MUL: 00045 return GETFLAG(CF); 00046 case t_ADDb: 00047 return (lf_resb<lf_var1b); 00048 case t_ADDw: 00049 return (lf_resw<lf_var1w); 00050 case t_ADDd: 00051 return (lf_resd<lf_var1d); 00052 case t_ADCb: 00053 return (lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b)); 00054 case t_ADCw: 00055 return (lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w)); 00056 case t_ADCd: 00057 return (lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d)); 00058 case t_SBBb: 00059 return (lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff)); 00060 case t_SBBw: 00061 return (lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff)); 00062 case t_SBBd: 00063 return (lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff)); 00064 case t_SUBb: 00065 case t_CMPb: 00066 return (lf_var1b<lf_var2b); 00067 case t_SUBw: 00068 case t_CMPw: 00069 return (lf_var1w<lf_var2w); 00070 case t_SUBd: 00071 case t_CMPd: 00072 return (lf_var1d<lf_var2d); 00073 case t_SHLb: 00074 if (lf_var2b>8) return false; 00075 else return (lf_var1b >> (8-lf_var2b)) & 1; 00076 case t_SHLw: 00077 if (lf_var2b>16) return false; 00078 else return (lf_var1w >> (16-lf_var2b)) & 1; 00079 case t_SHLd: 00080 case t_DSHLw: /* Hmm this is not correct for shift higher than 16 */ 00081 case t_DSHLd: 00082 return (lf_var1d >> (32 - lf_var2b)) & 1; 00083 case t_RCRb: 00084 case t_SHRb: 00085 return (lf_var1b >> (lf_var2b - 1)) & 1; 00086 case t_RCRw: 00087 case t_SHRw: 00088 return (lf_var1w >> (lf_var2b - 1)) & 1; 00089 case t_RCRd: 00090 case t_SHRd: 00091 case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ 00092 case t_DSHRd: 00093 return (lf_var1d >> (lf_var2b - 1)) & 1; 00094 case t_SARb: 00095 return (((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1; 00096 case t_SARw: 00097 return (((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1; 00098 case t_SARd: 00099 return (((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1; 00100 case t_NEGb: 00101 return lf_var1b; 00102 case t_NEGw: 00103 return lf_var1w; 00104 case t_NEGd: 00105 return lf_var1d; 00106 case t_ORb: 00107 case t_ORw: 00108 case t_ORd: 00109 case t_ANDb: 00110 case t_ANDw: 00111 case t_ANDd: 00112 case t_XORb: 00113 case t_XORw: 00114 case t_XORd: 00115 case t_TESTb: 00116 case t_TESTw: 00117 case t_TESTd: 00118 return false; /* Set to false */ 00119 case t_DIV: 00120 return false; /* Unkown */ 00121 default: 00122 LOG(LOG_CPU,LOG_ERROR)("get_CF Unknown %d",(int)lflags.type); 00123 } 00124 return 0; 00125 } 00126 00127 /* AF Adjust flag -- Set on carry from or borrow to the low order 00128 four bits of AL; cleared otherwise. Used for decimal 00129 arithmetic. 00130 */ 00131 Bit32u get_AF(void) { 00132 Bitu type=lflags.type; 00133 switch (type) { 00134 case t_UNKNOWN: 00135 return GETFLAG(AF); 00136 case t_ADDb: 00137 case t_ADCb: 00138 case t_SBBb: 00139 case t_SUBb: 00140 case t_CMPb: 00141 return ((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10; 00142 case t_ADDw: 00143 case t_ADCw: 00144 case t_SBBw: 00145 case t_SUBw: 00146 case t_CMPw: 00147 return ((lf_var1w ^ lf_var2w) ^ lf_resw) & 0x10; 00148 case t_ADCd: 00149 case t_ADDd: 00150 case t_SBBd: 00151 case t_SUBd: 00152 case t_CMPd: 00153 return ((lf_var1d ^ lf_var2d) ^ lf_resd) & 0x10; 00154 case t_INCb: 00155 return (lf_resb & 0x0f) == 0; 00156 case t_INCw: 00157 return (lf_resw & 0x0f) == 0; 00158 case t_INCd: 00159 return (lf_resd & 0x0f) == 0; 00160 case t_DECb: 00161 return (lf_resb & 0x0f) == 0x0f; 00162 case t_DECw: 00163 return (lf_resw & 0x0f) == 0x0f; 00164 case t_DECd: 00165 return (lf_resd & 0x0f) == 0x0f; 00166 case t_NEGb: 00167 return lf_var1b & 0x0f; 00168 case t_NEGw: 00169 return lf_var1w & 0x0f; 00170 case t_NEGd: 00171 return lf_var1d & 0x0f; 00172 case t_SHLb: 00173 case t_SHRb: 00174 case t_SARb: 00175 return lf_var2b & 0x1f; 00176 case t_SHLw: 00177 case t_SHRw: 00178 case t_SARw: 00179 return lf_var2w & 0x1f; 00180 case t_SHLd: 00181 case t_SHRd: 00182 case t_SARd: 00183 return lf_var2d & 0x1f; 00184 case t_ORb: 00185 case t_ORw: 00186 case t_ORd: 00187 case t_ANDb: 00188 case t_ANDw: 00189 case t_ANDd: 00190 case t_XORb: 00191 case t_XORw: 00192 case t_XORd: 00193 case t_TESTb: 00194 case t_TESTw: 00195 case t_TESTd: 00196 case t_DSHLw: 00197 case t_DSHLd: 00198 case t_DSHRw: 00199 case t_DSHRd: 00200 case t_DIV: 00201 case t_MUL: 00202 return false; /* Unkown */ 00203 default: 00204 LOG(LOG_CPU,LOG_ERROR)("get_AF Unknown %d",(int)lflags.type); 00205 } 00206 return 0; 00207 } 00208 00209 /* ZF Zero Flag -- Set if result is zero; cleared otherwise. 00210 */ 00211 00212 Bit32u get_ZF(void) { 00213 Bitu type=lflags.type; 00214 switch (type) { 00215 case t_UNKNOWN: 00216 return GETFLAG(ZF); 00217 case t_ADDb: 00218 case t_ORb: 00219 case t_ADCb: 00220 case t_SBBb: 00221 case t_ANDb: 00222 case t_XORb: 00223 case t_SUBb: 00224 case t_CMPb: 00225 case t_INCb: 00226 case t_DECb: 00227 case t_TESTb: 00228 case t_SHLb: 00229 case t_SHRb: 00230 case t_SARb: 00231 case t_NEGb: 00232 return (lf_resb==0); 00233 case t_ADDw: 00234 case t_ORw: 00235 case t_ADCw: 00236 case t_SBBw: 00237 case t_ANDw: 00238 case t_XORw: 00239 case t_SUBw: 00240 case t_CMPw: 00241 case t_INCw: 00242 case t_DECw: 00243 case t_TESTw: 00244 case t_SHLw: 00245 case t_SHRw: 00246 case t_SARw: 00247 case t_DSHLw: 00248 case t_DSHRw: 00249 case t_NEGw: 00250 return (lf_resw==0); 00251 case t_ADDd: 00252 case t_ORd: 00253 case t_ADCd: 00254 case t_SBBd: 00255 case t_ANDd: 00256 case t_XORd: 00257 case t_SUBd: 00258 case t_CMPd: 00259 case t_INCd: 00260 case t_DECd: 00261 case t_TESTd: 00262 case t_SHLd: 00263 case t_SHRd: 00264 case t_SARd: 00265 case t_DSHLd: 00266 case t_DSHRd: 00267 case t_NEGd: 00268 return (lf_resd==0); 00269 case t_DIV: 00270 case t_MUL: 00271 return false; /* Unkown */ 00272 default: 00273 LOG(LOG_CPU,LOG_ERROR)("get_ZF Unknown %d",(int)lflags.type); 00274 } 00275 return false; 00276 } 00277 /* SF Sign Flag -- Set equal to high-order bit of result (0 is 00278 positive, 1 if negative). 00279 */ 00280 Bit32u get_SF(void) { 00281 Bitu type=lflags.type; 00282 switch (type) { 00283 case t_UNKNOWN: 00284 return GETFLAG(SF); 00285 case t_ADDb: 00286 case t_ORb: 00287 case t_ADCb: 00288 case t_SBBb: 00289 case t_ANDb: 00290 case t_XORb: 00291 case t_SUBb: 00292 case t_CMPb: 00293 case t_INCb: 00294 case t_DECb: 00295 case t_TESTb: 00296 case t_SHLb: 00297 case t_SHRb: 00298 case t_SARb: 00299 case t_NEGb: 00300 return (lf_resb&0x80); 00301 case t_ADDw: 00302 case t_ORw: 00303 case t_ADCw: 00304 case t_SBBw: 00305 case t_ANDw: 00306 case t_XORw: 00307 case t_SUBw: 00308 case t_CMPw: 00309 case t_INCw: 00310 case t_DECw: 00311 case t_TESTw: 00312 case t_SHLw: 00313 case t_SHRw: 00314 case t_SARw: 00315 case t_DSHLw: 00316 case t_DSHRw: 00317 case t_NEGw: 00318 return (lf_resw&0x8000); 00319 case t_ADDd: 00320 case t_ORd: 00321 case t_ADCd: 00322 case t_SBBd: 00323 case t_ANDd: 00324 case t_XORd: 00325 case t_SUBd: 00326 case t_CMPd: 00327 case t_INCd: 00328 case t_DECd: 00329 case t_TESTd: 00330 case t_SHLd: 00331 case t_SHRd: 00332 case t_SARd: 00333 case t_DSHLd: 00334 case t_DSHRd: 00335 case t_NEGd: 00336 return (lf_resd&0x80000000); 00337 case t_DIV: 00338 case t_MUL: 00339 return false; /* Unkown */ 00340 default: 00341 LOG(LOG_CPU,LOG_ERROR)("get_SF Unkown %d",(int)lflags.type); 00342 } 00343 return false; 00344 00345 } 00346 Bit32u get_OF(void) { 00347 Bitu type=lflags.type; 00348 switch (type) { 00349 case t_UNKNOWN: 00350 case t_MUL: 00351 return GETFLAG(OF); 00352 case t_ADDb: 00353 case t_ADCb: 00354 return ((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var2b)) & 0x80; 00355 case t_ADDw: 00356 case t_ADCw: 00357 return ((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var2w)) & 0x8000; 00358 case t_ADDd: 00359 case t_ADCd: 00360 return ((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var2d)) & 0x80000000; 00361 case t_SBBb: 00362 case t_SUBb: 00363 case t_CMPb: 00364 return ((lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb)) & 0x80; 00365 case t_SBBw: 00366 case t_SUBw: 00367 case t_CMPw: 00368 return ((lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw)) & 0x8000; 00369 case t_SBBd: 00370 case t_SUBd: 00371 case t_CMPd: 00372 return ((lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd)) & 0x80000000; 00373 case t_INCb: 00374 return (lf_resb == 0x80); 00375 case t_INCw: 00376 return (lf_resw == 0x8000); 00377 case t_INCd: 00378 return (lf_resd == 0x80000000); 00379 case t_DECb: 00380 return (lf_resb == 0x7f); 00381 case t_DECw: 00382 return (lf_resw == 0x7fff); 00383 case t_DECd: 00384 return (lf_resd == 0x7fffffff); 00385 case t_NEGb: 00386 return (lf_var1b == 0x80); 00387 case t_NEGw: 00388 return (lf_var1w == 0x8000); 00389 case t_NEGd: 00390 return (lf_var1d == 0x80000000); 00391 case t_SHLb: 00392 return (lf_resb ^ lf_var1b) & 0x80; 00393 case t_SHLw: 00394 case t_DSHRw: 00395 case t_DSHLw: 00396 return (lf_resw ^ lf_var1w) & 0x8000; 00397 case t_SHLd: 00398 case t_DSHRd: 00399 case t_DSHLd: 00400 return (lf_resd ^ lf_var1d) & 0x80000000; 00401 case t_SHRb: 00402 if ((lf_var2b&0x1f)==1) return (lf_var1b > 0x80); 00403 else return false; 00404 case t_SHRw: 00405 if ((lf_var2b&0x1f)==1) return (lf_var1w > 0x8000); 00406 else return false; 00407 case t_SHRd: 00408 if ((lf_var2b&0x1f)==1) return (lf_var1d > 0x80000000); 00409 else return false; 00410 case t_ORb: 00411 case t_ORw: 00412 case t_ORd: 00413 case t_ANDb: 00414 case t_ANDw: 00415 case t_ANDd: 00416 case t_XORb: 00417 case t_XORw: 00418 case t_XORd: 00419 case t_TESTb: 00420 case t_TESTw: 00421 case t_TESTd: 00422 case t_SARb: 00423 case t_SARw: 00424 case t_SARd: 00425 return false; /* Return false */ 00426 case t_DIV: 00427 return false; /* Unkown */ 00428 default: 00429 LOG(LOG_CPU,LOG_ERROR)("get_OF Unkown %d",(int)lflags.type); 00430 } 00431 return false; 00432 } 00433 00434 #define PARITY16(x) (parity_lookup[((x)>>8)&0xff]^parity_lookup[(x)&0xff]^FLAG_PF) 00435 #define PARITY32(x) (PARITY16((x)&0xffff)^PARITY16(((x)>>16)&0xffff)^FLAG_PF) 00436 00437 Bit16u parity_lookup[256] = { 00438 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00439 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00440 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00441 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00442 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00443 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00444 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00445 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00446 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00447 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00448 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00449 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00450 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, 00451 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00452 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 00453 FLAG_PF, 0, 0, FLAG_PF, 0, FLAG_PF, FLAG_PF, 0, 0, FLAG_PF, FLAG_PF, 0, FLAG_PF, 0, 0, FLAG_PF 00454 }; 00455 00456 Bit32u get_PF(void) { 00457 switch (lflags.type) { 00458 case t_UNKNOWN: 00459 return GETFLAG(PF); 00460 case t_XORd: 00461 case t_ADDd: 00462 case t_SUBd: 00463 case t_ANDd: 00464 case t_ADCd: 00465 case t_SHRd: 00466 case t_SHLd: 00467 case t_SARd: 00468 case t_ORd: 00469 return PARITY32(lf_resd); 00470 case t_XORw: 00471 case t_ADDw: 00472 case t_SUBw: 00473 case t_ANDw: 00474 case t_ADCw: 00475 case t_SHRw: 00476 case t_SHLw: 00477 case t_SARw: 00478 case t_ORw: 00479 return PARITY16(lf_resw); 00480 default: 00481 return (parity_lookup[lf_resb]); 00482 } 00483 return 0; 00484 } 00485 00486 00487 #if 0 00488 00489 Bitu FillFlags(void) { 00490 // if (lflags.type==t_UNKNOWN) return reg_flags; 00491 Bitu new_word=(reg_flags & ~FLAG_MASK); 00492 if (get_CF()) new_word|=FLAG_CF; 00493 if (get_PF()) new_word|=FLAG_PF; 00494 if (get_AF()) new_word|=FLAG_AF; 00495 if (get_ZF()) new_word|=FLAG_ZF; 00496 if (get_SF()) new_word|=FLAG_SF; 00497 if (get_OF()) new_word|=FLAG_OF; 00498 reg_flags=new_word; 00499 lflags.type=t_UNKNOWN; 00500 return reg_flags; 00501 } 00502 00503 #else 00504 00505 #define DOFLAG_PF reg_flags=(reg_flags & ~FLAG_PF) | parity_lookup[lf_resb]; 00506 00507 #define DOFLAG_AF reg_flags=(reg_flags & ~FLAG_AF) | (((lf_var1b ^ lf_var2b) ^ lf_resb) & 0x10U); 00508 00509 #define DOFLAG_ZFb SETFLAGBIT(ZF,lf_resb==0); 00510 #define DOFLAG_ZFw SETFLAGBIT(ZF,lf_resw==0); 00511 #define DOFLAG_ZFd SETFLAGBIT(ZF,lf_resd==0); 00512 00513 #define DOFLAG_SFb reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resb & 0x80U) >> 0U); 00514 #define DOFLAG_SFw reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resw & 0x8000U) >> 8U); 00515 #define DOFLAG_SFd reg_flags=(reg_flags & ~FLAG_SF) | ((lf_resd & 0x80000000U) >> 24U); 00516 00517 #define SETCF(NEWBIT) reg_flags=(reg_flags & ~FLAG_CF)|(NEWBIT); 00518 00519 #define SET_FLAG SETFLAGBIT 00520 00521 Bitu FillFlags(void) { 00522 switch (lflags.type) { 00523 case t_UNKNOWN: 00524 break; 00525 case t_ADDb: 00526 SET_FLAG(CF,(lf_resb<lf_var1b)); 00527 DOFLAG_AF; 00528 DOFLAG_ZFb; 00529 DOFLAG_SFb; 00530 SET_FLAG(OF,((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var1b)) & 0x80); 00531 DOFLAG_PF; 00532 break; 00533 case t_ADDw: 00534 SET_FLAG(CF,(lf_resw<lf_var1w)); 00535 DOFLAG_AF; 00536 DOFLAG_ZFw; 00537 DOFLAG_SFw; 00538 SET_FLAG(OF,((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var1w)) & 0x8000); 00539 DOFLAG_PF; 00540 break; 00541 case t_ADDd: 00542 SET_FLAG(CF,(lf_resd<lf_var1d)); 00543 DOFLAG_AF; 00544 DOFLAG_ZFd; 00545 DOFLAG_SFd; 00546 SET_FLAG(OF,((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var1d)) & 0x80000000); 00547 DOFLAG_PF; 00548 break; 00549 case t_ADCb: 00550 SET_FLAG(CF,(lf_resb < lf_var1b) || (lflags.oldcf && (lf_resb == lf_var1b))); 00551 DOFLAG_AF; 00552 DOFLAG_ZFb; 00553 DOFLAG_SFb; 00554 SET_FLAG(OF,((lf_var1b ^ lf_var2b ^ 0x80) & (lf_resb ^ lf_var1b)) & 0x80); 00555 DOFLAG_PF; 00556 break; 00557 case t_ADCw: 00558 SET_FLAG(CF,(lf_resw < lf_var1w) || (lflags.oldcf && (lf_resw == lf_var1w))); 00559 DOFLAG_AF; 00560 DOFLAG_ZFw; 00561 DOFLAG_SFw; 00562 SET_FLAG(OF,((lf_var1w ^ lf_var2w ^ 0x8000) & (lf_resw ^ lf_var1w)) & 0x8000); 00563 DOFLAG_PF; 00564 break; 00565 case t_ADCd: 00566 SET_FLAG(CF,(lf_resd < lf_var1d) || (lflags.oldcf && (lf_resd == lf_var1d))); 00567 DOFLAG_AF; 00568 DOFLAG_ZFd; 00569 DOFLAG_SFd; 00570 SET_FLAG(OF,((lf_var1d ^ lf_var2d ^ 0x80000000) & (lf_resd ^ lf_var1d)) & 0x80000000); 00571 DOFLAG_PF; 00572 break; 00573 00574 00575 case t_SBBb: 00576 SET_FLAG(CF,(lf_var1b < lf_resb) || (lflags.oldcf && (lf_var2b==0xff))); 00577 DOFLAG_AF; 00578 DOFLAG_ZFb; 00579 DOFLAG_SFb; 00580 SET_FLAG(OF,(lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb) & 0x80); 00581 DOFLAG_PF; 00582 break; 00583 case t_SBBw: 00584 SET_FLAG(CF,(lf_var1w < lf_resw) || (lflags.oldcf && (lf_var2w==0xffff))); 00585 DOFLAG_AF; 00586 DOFLAG_ZFw; 00587 DOFLAG_SFw; 00588 SET_FLAG(OF,(lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw) & 0x8000); 00589 DOFLAG_PF; 00590 break; 00591 case t_SBBd: 00592 SET_FLAG(CF,(lf_var1d < lf_resd) || (lflags.oldcf && (lf_var2d==0xffffffff))); 00593 DOFLAG_AF; 00594 DOFLAG_ZFd; 00595 DOFLAG_SFd; 00596 SET_FLAG(OF,(lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd) & 0x80000000); 00597 DOFLAG_PF; 00598 break; 00599 00600 00601 case t_SUBb: 00602 case t_CMPb: 00603 SET_FLAG(CF,(lf_var1b<lf_var2b)); 00604 DOFLAG_AF; 00605 DOFLAG_ZFb; 00606 DOFLAG_SFb; 00607 SET_FLAG(OF,(lf_var1b ^ lf_var2b) & (lf_var1b ^ lf_resb) & 0x80); 00608 DOFLAG_PF; 00609 break; 00610 case t_SUBw: 00611 case t_CMPw: 00612 SET_FLAG(CF,(lf_var1w<lf_var2w)); 00613 DOFLAG_AF; 00614 DOFLAG_ZFw; 00615 DOFLAG_SFw; 00616 SET_FLAG(OF,(lf_var1w ^ lf_var2w) & (lf_var1w ^ lf_resw) & 0x8000); 00617 DOFLAG_PF; 00618 break; 00619 case t_SUBd: 00620 case t_CMPd: 00621 SET_FLAG(CF,(lf_var1d<lf_var2d)); 00622 DOFLAG_AF; 00623 DOFLAG_ZFd; 00624 DOFLAG_SFd; 00625 SET_FLAG(OF,(lf_var1d ^ lf_var2d) & (lf_var1d ^ lf_resd) & 0x80000000); 00626 DOFLAG_PF; 00627 break; 00628 00629 00630 case t_ORb: 00631 SET_FLAG(CF,false); 00632 SET_FLAG(AF,false); 00633 DOFLAG_ZFb; 00634 DOFLAG_SFb; 00635 SET_FLAG(OF,false); 00636 DOFLAG_PF; 00637 break; 00638 case t_ORw: 00639 SET_FLAG(CF,false); 00640 SET_FLAG(AF,false); 00641 DOFLAG_ZFw; 00642 DOFLAG_SFw; 00643 SET_FLAG(OF,false); 00644 DOFLAG_PF; 00645 break; 00646 case t_ORd: 00647 SET_FLAG(CF,false); 00648 SET_FLAG(AF,false); 00649 DOFLAG_ZFd; 00650 DOFLAG_SFd; 00651 SET_FLAG(OF,false); 00652 DOFLAG_PF; 00653 break; 00654 00655 00656 case t_TESTb: 00657 case t_ANDb: 00658 SET_FLAG(CF,false); 00659 SET_FLAG(AF,false); 00660 DOFLAG_ZFb; 00661 DOFLAG_SFb; 00662 SET_FLAG(OF,false); 00663 DOFLAG_PF; 00664 break; 00665 case t_TESTw: 00666 case t_ANDw: 00667 SET_FLAG(CF,false); 00668 SET_FLAG(AF,false); 00669 DOFLAG_ZFw; 00670 DOFLAG_SFw; 00671 SET_FLAG(OF,false); 00672 DOFLAG_PF; 00673 break; 00674 case t_TESTd: 00675 case t_ANDd: 00676 SET_FLAG(CF,false); 00677 SET_FLAG(AF,false); 00678 DOFLAG_ZFd; 00679 DOFLAG_SFd; 00680 SET_FLAG(OF,false); 00681 DOFLAG_PF; 00682 break; 00683 00684 00685 case t_XORb: 00686 SET_FLAG(CF,false); 00687 SET_FLAG(AF,false); 00688 DOFLAG_ZFb; 00689 DOFLAG_SFb; 00690 SET_FLAG(OF,false); 00691 DOFLAG_PF; 00692 break; 00693 case t_XORw: 00694 SET_FLAG(CF,false); 00695 SET_FLAG(AF,false); 00696 DOFLAG_ZFw; 00697 DOFLAG_SFw; 00698 SET_FLAG(OF,false); 00699 DOFLAG_PF; 00700 break; 00701 case t_XORd: 00702 SET_FLAG(CF,false); 00703 SET_FLAG(AF,false); 00704 DOFLAG_ZFd; 00705 DOFLAG_SFd; 00706 SET_FLAG(OF,false); 00707 DOFLAG_PF; 00708 break; 00709 00710 00711 case t_SHLb: 00712 if (lf_var2b>8) SET_FLAG(CF,false); 00713 else SET_FLAG(CF,(lf_var1b >> (8-lf_var2b)) & 1); 00714 DOFLAG_ZFb; 00715 DOFLAG_SFb; 00716 SET_FLAG(OF,((unsigned int)lf_resb >> 7U) ^ GETFLAG(CF)); /* MSB of result XOR CF. WARNING: This only works because FLAGS_CF == 1 */ 00717 DOFLAG_PF; 00718 SET_FLAG(AF,(lf_var2b&0x1f)); 00719 break; 00720 case t_SHLw: 00721 if (lf_var2b>16) SET_FLAG(CF,false); 00722 else SET_FLAG(CF,(lf_var1w >> (16-lf_var2b)) & 1); 00723 DOFLAG_ZFw; 00724 DOFLAG_SFw; 00725 SET_FLAG(OF,((unsigned int)lf_resw >> 15U) ^ GETFLAG(CF)); /* MSB of result XOR CF. WARNING: This only works because FLAGS_CF == 1 */ 00726 DOFLAG_PF; 00727 SET_FLAG(AF,(lf_var2w&0x1f)); 00728 break; 00729 case t_SHLd: 00730 SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); 00731 DOFLAG_ZFd; 00732 DOFLAG_SFd; 00733 SET_FLAG(OF,((unsigned int)lf_resd >> 31U) ^ GETFLAG(CF)); /* MSB of result XOR CF. WARNING: This only works because FLAGS_CF == 1 */ 00734 DOFLAG_PF; 00735 SET_FLAG(AF,(lf_var2d&0x1f)); 00736 break; 00737 00738 00739 case t_DSHLw: 00740 SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); 00741 DOFLAG_ZFw; 00742 DOFLAG_SFw; 00743 SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); 00744 DOFLAG_PF; 00745 break; 00746 case t_DSHLd: 00747 SET_FLAG(CF,(lf_var1d >> (32 - lf_var2b)) & 1); 00748 DOFLAG_ZFd; 00749 DOFLAG_SFd; 00750 SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); 00751 DOFLAG_PF; 00752 break; 00753 00754 00755 case t_SHRb: 00756 SET_FLAG(CF,(lf_var1b >> (lf_var2b - 1)) & 1); 00757 DOFLAG_ZFb; 00758 DOFLAG_SFb; 00759 if ((lf_var2b&0x1f)==1) SET_FLAG(OF,(lf_var1b >= 0x80)); 00760 else SET_FLAG(OF,false); 00761 DOFLAG_PF; 00762 SET_FLAG(AF,(lf_var2b&0x1f)); 00763 break; 00764 case t_SHRw: 00765 SET_FLAG(CF,(lf_var1w >> (lf_var2b - 1)) & 1); 00766 DOFLAG_ZFw; 00767 DOFLAG_SFw; 00768 if ((lf_var2w&0x1f)==1) SET_FLAG(OF,(lf_var1w >= 0x8000)); 00769 else SET_FLAG(OF,false); 00770 DOFLAG_PF; 00771 SET_FLAG(AF,(lf_var2w&0x1f)); 00772 break; 00773 case t_SHRd: 00774 SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); 00775 DOFLAG_ZFd; 00776 DOFLAG_SFd; 00777 if ((lf_var2d&0x1f)==1) SET_FLAG(OF,(lf_var1d >= 0x80000000)); 00778 else SET_FLAG(OF,false); 00779 DOFLAG_PF; 00780 SET_FLAG(AF,(lf_var2d&0x1f)); 00781 break; 00782 00783 00784 case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ 00785 SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); 00786 DOFLAG_ZFw; 00787 DOFLAG_SFw; 00788 SET_FLAG(OF,(lf_resw ^ lf_var1w) & 0x8000); 00789 DOFLAG_PF; 00790 break; 00791 case t_DSHRd: 00792 SET_FLAG(CF,(lf_var1d >> (lf_var2b - 1)) & 1); 00793 DOFLAG_ZFd; 00794 DOFLAG_SFd; 00795 SET_FLAG(OF,(lf_resd ^ lf_var1d) & 0x80000000); 00796 DOFLAG_PF; 00797 break; 00798 00799 00800 case t_SARb: 00801 SET_FLAG(CF,(((Bit8s) lf_var1b) >> (lf_var2b - 1)) & 1); 00802 DOFLAG_ZFb; 00803 DOFLAG_SFb; 00804 SET_FLAG(OF,false); 00805 DOFLAG_PF; 00806 SET_FLAG(AF,(lf_var2b&0x1f)); 00807 break; 00808 case t_SARw: 00809 SET_FLAG(CF,(((Bit16s) lf_var1w) >> (lf_var2b - 1)) & 1); 00810 DOFLAG_ZFw; 00811 DOFLAG_SFw; 00812 SET_FLAG(OF,false); 00813 DOFLAG_PF; 00814 SET_FLAG(AF,(lf_var2w&0x1f)); 00815 break; 00816 case t_SARd: 00817 SET_FLAG(CF,(((Bit32s) lf_var1d) >> (lf_var2b - 1)) & 1); 00818 DOFLAG_ZFd; 00819 DOFLAG_SFd; 00820 SET_FLAG(OF,false); 00821 DOFLAG_PF; 00822 SET_FLAG(AF,(lf_var2d&0x1f)); 00823 break; 00824 00825 case t_INCb: 00826 SET_FLAG(AF,(lf_resb & 0x0f) == 0); 00827 DOFLAG_ZFb; 00828 DOFLAG_SFb; 00829 SET_FLAG(OF,(lf_resb == 0x80)); 00830 DOFLAG_PF; 00831 break; 00832 case t_INCw: 00833 SET_FLAG(AF,(lf_resw & 0x0f) == 0); 00834 DOFLAG_ZFw; 00835 DOFLAG_SFw; 00836 SET_FLAG(OF,(lf_resw == 0x8000)); 00837 DOFLAG_PF; 00838 break; 00839 case t_INCd: 00840 SET_FLAG(AF,(lf_resd & 0x0f) == 0); 00841 DOFLAG_ZFd; 00842 DOFLAG_SFd; 00843 SET_FLAG(OF,(lf_resd == 0x80000000)); 00844 DOFLAG_PF; 00845 break; 00846 00847 case t_DECb: 00848 SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); 00849 DOFLAG_ZFb; 00850 DOFLAG_SFb; 00851 SET_FLAG(OF,(lf_resb == 0x7f)); 00852 DOFLAG_PF; 00853 break; 00854 case t_DECw: 00855 SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); 00856 DOFLAG_ZFw; 00857 DOFLAG_SFw; 00858 SET_FLAG(OF,(lf_resw == 0x7fff)); 00859 DOFLAG_PF; 00860 break; 00861 case t_DECd: 00862 SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); 00863 DOFLAG_ZFd; 00864 DOFLAG_SFd; 00865 SET_FLAG(OF,(lf_resd == 0x7fffffff)); 00866 DOFLAG_PF; 00867 break; 00868 00869 case t_NEGb: 00870 SET_FLAG(CF,(lf_var1b!=0)); 00871 SET_FLAG(AF,(lf_resb & 0x0f) != 0); 00872 DOFLAG_ZFb; 00873 DOFLAG_SFb; 00874 SET_FLAG(OF,(lf_var1b == 0x80)); 00875 DOFLAG_PF; 00876 break; 00877 case t_NEGw: 00878 SET_FLAG(CF,(lf_var1w!=0)); 00879 SET_FLAG(AF,(lf_resw & 0x0f) != 0); 00880 DOFLAG_ZFw; 00881 DOFLAG_SFw; 00882 SET_FLAG(OF,(lf_var1w == 0x8000)); 00883 DOFLAG_PF; 00884 break; 00885 case t_NEGd: 00886 SET_FLAG(CF,(lf_var1d!=0)); 00887 SET_FLAG(AF,(lf_resd & 0x0f) != 0); 00888 DOFLAG_ZFd; 00889 DOFLAG_SFd; 00890 SET_FLAG(OF,(lf_var1d == 0x80000000)); 00891 DOFLAG_PF; 00892 break; 00893 00894 00895 case t_DIV: 00896 case t_MUL: 00897 break; 00898 00899 default: 00900 LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",(int)lflags.type); 00901 return 0; 00902 } 00903 lflags.type=t_UNKNOWN; 00904 return reg_flags; 00905 } 00906 00907 void FillFlagsNoCFOF(void) { 00908 switch (lflags.type) { 00909 case t_UNKNOWN: 00910 return; 00911 case t_ADDb: 00912 DOFLAG_AF; 00913 DOFLAG_ZFb; 00914 DOFLAG_SFb; 00915 DOFLAG_PF; 00916 break; 00917 case t_ADDw: 00918 DOFLAG_AF; 00919 DOFLAG_ZFw; 00920 DOFLAG_SFw; 00921 DOFLAG_PF; 00922 break; 00923 case t_ADDd: 00924 DOFLAG_AF; 00925 DOFLAG_ZFd; 00926 DOFLAG_SFd; 00927 DOFLAG_PF; 00928 break; 00929 case t_ADCb: 00930 DOFLAG_AF; 00931 DOFLAG_ZFb; 00932 DOFLAG_SFb; 00933 DOFLAG_PF; 00934 break; 00935 case t_ADCw: 00936 DOFLAG_AF; 00937 DOFLAG_ZFw; 00938 DOFLAG_SFw; 00939 DOFLAG_PF; 00940 break; 00941 case t_ADCd: 00942 DOFLAG_AF; 00943 DOFLAG_ZFd; 00944 DOFLAG_SFd; 00945 DOFLAG_PF; 00946 break; 00947 00948 00949 case t_SBBb: 00950 DOFLAG_AF; 00951 DOFLAG_ZFb; 00952 DOFLAG_SFb; 00953 DOFLAG_PF; 00954 break; 00955 case t_SBBw: 00956 DOFLAG_AF; 00957 DOFLAG_ZFw; 00958 DOFLAG_SFw; 00959 DOFLAG_PF; 00960 break; 00961 case t_SBBd: 00962 DOFLAG_AF; 00963 DOFLAG_ZFd; 00964 DOFLAG_SFd; 00965 DOFLAG_PF; 00966 break; 00967 00968 00969 case t_SUBb: 00970 case t_CMPb: 00971 DOFLAG_AF; 00972 DOFLAG_ZFb; 00973 DOFLAG_SFb; 00974 DOFLAG_PF; 00975 break; 00976 case t_SUBw: 00977 case t_CMPw: 00978 DOFLAG_AF; 00979 DOFLAG_ZFw; 00980 DOFLAG_SFw; 00981 DOFLAG_PF; 00982 break; 00983 case t_SUBd: 00984 case t_CMPd: 00985 DOFLAG_AF; 00986 DOFLAG_ZFd; 00987 DOFLAG_SFd; 00988 DOFLAG_PF; 00989 break; 00990 00991 00992 case t_ORb: 00993 SET_FLAG(AF,false); 00994 DOFLAG_ZFb; 00995 DOFLAG_SFb; 00996 DOFLAG_PF; 00997 break; 00998 case t_ORw: 00999 SET_FLAG(AF,false); 01000 DOFLAG_ZFw; 01001 DOFLAG_SFw; 01002 DOFLAG_PF; 01003 break; 01004 case t_ORd: 01005 SET_FLAG(AF,false); 01006 DOFLAG_ZFd; 01007 DOFLAG_SFd; 01008 DOFLAG_PF; 01009 break; 01010 01011 01012 case t_TESTb: 01013 case t_ANDb: 01014 SET_FLAG(AF,false); 01015 DOFLAG_ZFb; 01016 DOFLAG_SFb; 01017 DOFLAG_PF; 01018 break; 01019 case t_TESTw: 01020 case t_ANDw: 01021 SET_FLAG(AF,false); 01022 DOFLAG_ZFw; 01023 DOFLAG_SFw; 01024 DOFLAG_PF; 01025 break; 01026 case t_TESTd: 01027 case t_ANDd: 01028 SET_FLAG(AF,false); 01029 DOFLAG_ZFd; 01030 DOFLAG_SFd; 01031 DOFLAG_PF; 01032 break; 01033 01034 01035 case t_XORb: 01036 SET_FLAG(AF,false); 01037 DOFLAG_ZFb; 01038 DOFLAG_SFb; 01039 DOFLAG_PF; 01040 break; 01041 case t_XORw: 01042 SET_FLAG(AF,false); 01043 DOFLAG_ZFw; 01044 DOFLAG_SFw; 01045 DOFLAG_PF; 01046 break; 01047 case t_XORd: 01048 SET_FLAG(AF,false); 01049 DOFLAG_ZFd; 01050 DOFLAG_SFd; 01051 DOFLAG_PF; 01052 break; 01053 01054 01055 case t_SHLb: 01056 DOFLAG_ZFb; 01057 DOFLAG_SFb; 01058 DOFLAG_PF; 01059 SET_FLAG(AF,(lf_var2b&0x1f)); 01060 break; 01061 case t_SHLw: 01062 DOFLAG_ZFw; 01063 DOFLAG_SFw; 01064 DOFLAG_PF; 01065 SET_FLAG(AF,(lf_var2w&0x1f)); 01066 break; 01067 case t_SHLd: 01068 DOFLAG_ZFd; 01069 DOFLAG_SFd; 01070 DOFLAG_PF; 01071 SET_FLAG(AF,(lf_var2d&0x1f)); 01072 break; 01073 01074 01075 case t_DSHLw: 01076 DOFLAG_ZFw; 01077 DOFLAG_SFw; 01078 DOFLAG_PF; 01079 break; 01080 case t_DSHLd: 01081 DOFLAG_ZFd; 01082 DOFLAG_SFd; 01083 DOFLAG_PF; 01084 break; 01085 01086 01087 case t_SHRb: 01088 DOFLAG_ZFb; 01089 DOFLAG_SFb; 01090 DOFLAG_PF; 01091 SET_FLAG(AF,(lf_var2b&0x1f)); 01092 break; 01093 case t_SHRw: 01094 DOFLAG_ZFw; 01095 DOFLAG_SFw; 01096 DOFLAG_PF; 01097 SET_FLAG(AF,(lf_var2w&0x1f)); 01098 break; 01099 case t_SHRd: 01100 DOFLAG_ZFd; 01101 DOFLAG_SFd; 01102 DOFLAG_PF; 01103 SET_FLAG(AF,(lf_var2d&0x1f)); 01104 break; 01105 01106 01107 case t_DSHRw: /* Hmm this is not correct for shift higher than 16 */ 01108 DOFLAG_ZFw; 01109 DOFLAG_SFw; 01110 DOFLAG_PF; 01111 break; 01112 case t_DSHRd: 01113 DOFLAG_ZFd; 01114 DOFLAG_SFd; 01115 DOFLAG_PF; 01116 break; 01117 01118 01119 case t_SARb: 01120 DOFLAG_ZFb; 01121 DOFLAG_SFb; 01122 DOFLAG_PF; 01123 SET_FLAG(AF,(lf_var2b&0x1f)); 01124 break; 01125 case t_SARw: 01126 DOFLAG_ZFw; 01127 DOFLAG_SFw; 01128 DOFLAG_PF; 01129 SET_FLAG(AF,(lf_var2w&0x1f)); 01130 break; 01131 case t_SARd: 01132 DOFLAG_ZFd; 01133 DOFLAG_SFd; 01134 DOFLAG_PF; 01135 SET_FLAG(AF,(lf_var2d&0x1f)); 01136 break; 01137 01138 case t_INCb: 01139 SET_FLAG(AF,(lf_resb & 0x0f) == 0); 01140 DOFLAG_ZFb; 01141 DOFLAG_SFb; 01142 DOFLAG_PF; 01143 break; 01144 case t_INCw: 01145 SET_FLAG(AF,(lf_resw & 0x0f) == 0); 01146 DOFLAG_ZFw; 01147 DOFLAG_SFw; 01148 DOFLAG_PF; 01149 break; 01150 case t_INCd: 01151 SET_FLAG(AF,(lf_resd & 0x0f) == 0); 01152 DOFLAG_ZFd; 01153 DOFLAG_SFd; 01154 DOFLAG_PF; 01155 break; 01156 01157 case t_DECb: 01158 SET_FLAG(AF,(lf_resb & 0x0f) == 0x0f); 01159 DOFLAG_ZFb; 01160 DOFLAG_SFb; 01161 DOFLAG_PF; 01162 break; 01163 case t_DECw: 01164 SET_FLAG(AF,(lf_resw & 0x0f) == 0x0f); 01165 DOFLAG_ZFw; 01166 DOFLAG_SFw; 01167 DOFLAG_PF; 01168 break; 01169 case t_DECd: 01170 SET_FLAG(AF,(lf_resd & 0x0f) == 0x0f); 01171 DOFLAG_ZFd; 01172 DOFLAG_SFd; 01173 DOFLAG_PF; 01174 break; 01175 01176 case t_NEGb: 01177 SET_FLAG(AF,(lf_resb & 0x0f) != 0); 01178 DOFLAG_ZFb; 01179 DOFLAG_SFb; 01180 DOFLAG_PF; 01181 break; 01182 case t_NEGw: 01183 SET_FLAG(AF,(lf_resw & 0x0f) != 0); 01184 DOFLAG_ZFw; 01185 DOFLAG_SFw; 01186 DOFLAG_PF; 01187 break; 01188 case t_NEGd: 01189 SET_FLAG(AF,(lf_resd & 0x0f) != 0); 01190 DOFLAG_ZFd; 01191 DOFLAG_SFd; 01192 DOFLAG_PF; 01193 break; 01194 01195 01196 case t_DIV: 01197 case t_MUL: 01198 break; 01199 01200 default: 01201 LOG(LOG_CPU,LOG_ERROR)("Unhandled flag type %d",(int)lflags.type); 01202 break; 01203 } 01204 lflags.type=t_UNKNOWN; 01205 } 01206 01207 void DestroyConditionFlags(void) { 01208 lflags.type=t_UNKNOWN; 01209 } 01210 01211 #endif 01212 01213 // save state support 01214 void POD_Save_CPU_Flags( std::ostream& stream ) 01215 { 01216 // - pure data 01217 WRITE_POD( &lflags, lflags ); 01218 } 01219 01220 void POD_Load_CPU_Flags( std::istream& stream ) 01221 { 01222 // - pure data 01223 READ_POD( &lflags, lflags ); 01224 }