00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef Z80_MACROS_H
00021 #define Z80_MACROS_H
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 #define z80_int_handler \
00099 { \
00100 if (_IFF1) \
00101 { \
00102 _R++; \
00103 _IFF1 = _IFF2 = 0; \
00104 z80.int_pending = 0; \
00105 cpc.gatearray().setSlCount(cpc.gatearray().slCount() & 0xdf); \
00106 if (_HALT) \
00107 { \
00108 _HALT = 0; \
00109 _PC++; \
00110 } \
00111 if (_IM < 2) \
00112 { \
00113 iCycleCount = 20; \
00114 if (iWSAdjust) \
00115 { \
00116 iCycleCount -= 4; \
00117 } \
00118 RST(0x0038); \
00119 z80_wait_states \
00120 } \
00121 else \
00122 { \
00123 REGPAIR addr; \
00124 iCycleCount = 28; \
00125 if (iWSAdjust) \
00126 { \
00127 iCycleCount -= 4; \
00128 } \
00129 write_mem(--_SP, z80.PC.b.h); \
00130 write_mem(--_SP, z80.PC.b.l); \
00131 addr.b.l = 0xff; \
00132 addr.b.h = _I; \
00133 z80.PC.b.l = read_mem(addr.w.l); \
00134 z80.PC.b.h = read_mem(addr.w.l+1); \
00135 z80_wait_states \
00136 } \
00137 } \
00138 }
00139
00140
00141 #define ADC(value) \
00142 { \
00143 unsigned val = value; \
00144 unsigned res = _A + val + (_F & Cflag); \
00145 _F = SZ[res & 0xff] | ((res >> 8) & Cflag) | ((_A ^ res ^ val) & Hflag) | \
00146 (((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
00147 _A = res; \
00148 }
00149
00150 #define ADD(value) \
00151 { \
00152 unsigned val = value; \
00153 unsigned res = _A + val; \
00154 _F = SZ[(UBYTE)res] | ((res >> 8) & Cflag) | ((_A ^ res ^ val) & Hflag) | \
00155 (((val ^ _A ^ 0x80) & (val ^ res) & 0x80) >> 5); \
00156 _A = (UBYTE)res; \
00157 }
00158
00159 #define ADD16(dest, src) \
00160 { \
00161 DWORD res = z80.dest.d + z80.src.d; \
00162 _F = (_F & (Sflag | Zflag | Vflag)) | (((z80.dest.d ^ res ^ z80.src.d) >> 8) & Hflag) | \
00163 ((res >> 16) & Cflag) | ((res >> 8) & Xflags); \
00164 z80.dest.w.l = (UWORD)res; \
00165 }
00166
00167 #define AND(val) \
00168 { \
00169 _A &= val; \
00170 _F = SZP[_A] | Hflag; \
00171 }
00172
00173 #define CALL \
00174 { \
00175 REGPAIR dest; \
00176 dest.b.l = read_mem(_PC++); \
00177 dest.b.h = read_mem(_PC++); \
00178 write_mem(--_SP, z80.PC.b.h); \
00179 write_mem(--_SP, z80.PC.b.l); \
00180 _PC = dest.w.l; \
00181 }
00182
00183 #define CP(value) \
00184 { \
00185 unsigned val = value; \
00186 unsigned res = _A - val; \
00187 _F = (SZ[res & 0xff] & (Sflag | Zflag)) | (val & Xflags) | ((res >> 8) & Cflag) | Nflag | ((_A ^ res ^ val) & Hflag) | \
00188 ((((val ^ _A) & (_A ^ res)) >> 5) & Vflag); \
00189 }
00190
00191 #define DAA \
00192 { \
00193 int idx = _A; \
00194 if(_F & Cflag) \
00195 idx |= 0x100; \
00196 if(_F & Hflag) \
00197 idx |= 0x200; \
00198 if(_F & Nflag) \
00199 idx |= 0x400; \
00200 _AF = DAATable[idx]; \
00201 }
00202
00203 #define DEC(reg) \
00204 { \
00205 reg--; \
00206 _F = (_F & Cflag) | SZHV_dec[reg]; \
00207 }
00208
00209 #define JR \
00210 { \
00211 signed char offset; \
00212 offset = (signed char)(read_mem(_PC)); \
00213 _PC += offset + 1; \
00214 }
00215
00216 #define EXX \
00217 { \
00218 REGPAIR temp; \
00219 temp = z80.BCx; \
00220 z80.BCx = z80.BC; \
00221 z80.BC = temp; \
00222 temp = z80.DEx; \
00223 z80.DEx = z80.DE; \
00224 z80.DE = temp; \
00225 temp = z80.HLx; \
00226 z80.HLx = z80.HL; \
00227 z80.HL = temp; \
00228 }
00229
00230 #define EX(op1, op2) \
00231 { \
00232 REGPAIR temp; \
00233 temp = op1; \
00234 op1 = op2; \
00235 op2 = temp; \
00236 }
00237
00238 #define EX_SP(reg) \
00239 { \
00240 REGPAIR temp; \
00241 temp.b.l = read_mem(_SP++); \
00242 temp.b.h = read_mem(_SP); \
00243 write_mem(_SP--, z80.reg.b.h); \
00244 write_mem(_SP, z80.reg.b.l); \
00245 z80.reg.w.l = temp.w.l; \
00246 }
00247
00248 #define INC(reg) \
00249 { \
00250 reg++; \
00251 _F = (_F & Cflag) | SZHV_inc[reg]; \
00252 }
00253
00254 #define JP \
00255 { \
00256 REGPAIR addr; \
00257 addr.b.l = read_mem(_PC++); \
00258 addr.b.h = read_mem(_PC); \
00259 _PC = addr.w.l; \
00260 }
00261
00262 #define LD16_MEM(reg) \
00263 { \
00264 REGPAIR addr; \
00265 addr.b.l = read_mem(_PC++); \
00266 addr.b.h = read_mem(_PC++); \
00267 z80.reg.b.l = read_mem(addr.w.l); \
00268 z80.reg.b.h = read_mem(addr.w.l+1); \
00269 }
00270
00271 #define LDMEM_16(reg) \
00272 { \
00273 REGPAIR addr; \
00274 addr.b.l = read_mem(_PC++); \
00275 addr.b.h = read_mem(_PC++); \
00276 write_mem(addr.w.l, z80.reg.b.l); \
00277 write_mem(addr.w.l+1, z80.reg.b.h); \
00278 }
00279
00280 #define OR(val) \
00281 { \
00282 _A |= val; \
00283 _F = SZP[_A]; \
00284 }
00285
00286 #define POP(reg) \
00287 { \
00288 z80.reg.b.l = read_mem(_SP++); \
00289 z80.reg.b.h = read_mem(_SP++); \
00290 }
00291
00292 #define PUSH(reg) \
00293 { \
00294 write_mem(--_SP, z80.reg.b.h); \
00295 write_mem(--_SP, z80.reg.b.l); \
00296 }
00297
00298 #define RET \
00299 { \
00300 z80.PC.b.l = read_mem(_SP++); \
00301 z80.PC.b.h = read_mem(_SP++); \
00302 }
00303
00304 #define RLA \
00305 { \
00306 UBYTE res = (_A << 1) | (_F & Cflag); \
00307 UBYTE carry = (_A & 0x80) ? Cflag : 0; \
00308 _F = (_F & (Sflag | Zflag | Pflag)) | carry | (res & Xflags); \
00309 _A = res; \
00310 }
00311
00312 #define RLCA \
00313 { \
00314 _A = (_A << 1) | (_A >> 7); \
00315 _F = (_F & (Sflag | Zflag | Pflag)) | (_A & (Xflags | Cflag)); \
00316 }
00317
00318 #define RRA \
00319 { \
00320 UBYTE res = (_A >> 1) | (_F << 7); \
00321 UBYTE carry = (_A & 0x01) ? Cflag : 0; \
00322 _F = (_F & (Sflag | Zflag | Pflag)) | carry | (res & Xflags); \
00323 _A = res; \
00324 }
00325
00326 #define RRCA \
00327 { \
00328 _F = (_F & (Sflag | Zflag | Pflag)) | (_A & Cflag); \
00329 _A = (_A >> 1) | (_A << 7); \
00330 _F |= (_A & Xflags); \
00331 }
00332
00333 #define RST(addr) \
00334 { \
00335 write_mem(--_SP, z80.PC.b.h); \
00336 write_mem(--_SP, z80.PC.b.l); \
00337 _PC = addr; \
00338 }
00339
00340 #define SBC(value) \
00341 { \
00342 unsigned val = value; \
00343 unsigned res = _A - val - (_F & Cflag); \
00344 _F = SZ[res & 0xff] | ((res >> 8) & Cflag) | Nflag | ((_A ^ res ^ val) & Hflag) | \
00345 (((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
00346 _A = res; \
00347 }
00348
00349 #define SUB(value) \
00350 { \
00351 unsigned val = value; \
00352 unsigned res = _A - val; \
00353 _F = SZ[res & 0xff] | ((res >> 8) & Cflag) | Nflag | ((_A ^ res ^ val) & Hflag) | \
00354 (((val ^ _A) & (_A ^ res) & 0x80) >> 5); \
00355 _A = res; \
00356 }
00357
00358 #define XOR(val) \
00359 { \
00360 _A ^= val; \
00361 _F = SZP[_A]; \
00362 }
00363
00364 #define BIT(bit, reg) \
00365 _F = (_F & Cflag) | Hflag | SZ_BIT[reg & (1 << bit)]
00366
00367 #define BIT_XY BIT
00368
00369
00370
00371 #define ADC16(reg) \
00372 { \
00373 DWORD res = _HLdword + z80.reg.d + (_F & Cflag); \
00374 _F = (((_HLdword ^ res ^ z80.reg.d) >> 8) & Hflag) | \
00375 ((res >> 16) & Cflag) | \
00376 ((res >> 8) & (Sflag | Xflags)) | \
00377 ((res & 0xffff) ? 0 : Zflag) | \
00378 (((z80.reg.d ^ _HLdword ^ 0x8000) & (z80.reg.d ^ res) & 0x8000) >> 13); \
00379 _HL = (UWORD)res; \
00380 }
00381
00382 #define CPD \
00383 { \
00384 UBYTE val = read_mem(_HL); \
00385 UBYTE res = _A - val; \
00386 _HL--; \
00387 _BC--; \
00388 _F = (_F & Cflag) | (SZ[res] & ~Xflags) | ((_A ^ val ^ res) & Hflag) | Nflag; \
00389 if(_F & Hflag) res -= 1; \
00390 if(res & 0x02) _F |= 0x20; \
00391 if(res & 0x08) _F |= 0x08; \
00392 if(_BC) _F |= Vflag; \
00393 }
00394
00395 #define CPDR \
00396 CPD; \
00397 if(_BC && !(_F & Zflag)) \
00398 { \
00399 iCycleCount += cc_ex[bOpCode]; \
00400 _PC -= 2; \
00401 iWSAdjust++; \
00402 }
00403
00404 #define CPI \
00405 { \
00406 UBYTE val = read_mem(_HL); \
00407 UBYTE res = _A - val; \
00408 _HL++; \
00409 _BC--; \
00410 _F = (_F & Cflag) | (SZ[res] & ~Xflags) | ((_A ^ val ^ res) & Hflag) | Nflag; \
00411 if(_F & Hflag) res -= 1; \
00412 if(res & 0x02) _F |= 0x20; \
00413 if(res & 0x08) _F |= 0x08; \
00414 if(_BC) _F |= Vflag; \
00415 }
00416
00417 #define CPIR \
00418 CPI; \
00419 if(_BC && !(_F & Zflag)) \
00420 { \
00421 iCycleCount += cc_ex[bOpCode]; \
00422 _PC -= 2; \
00423 iWSAdjust++; \
00424 }
00425
00426 #define IND \
00427 { \
00428 UBYTE io = z80_IN_handler(z80.BC); \
00429 _B--; \
00430 write_mem(_HL, io); \
00431 _HL--; \
00432 _F = SZ[_B]; \
00433 if(io & Sflag) _F |= Nflag; \
00434 if((((_C - 1) & 0xff) + io) & 0x100) _F |= Hflag | Cflag; \
00435 if((drep_tmp1[_C & 3][io & 3] ^ breg_tmp2[_B] ^ (_C >> 2) ^ (io >> 2)) & 1) \
00436 _F |= Pflag; \
00437 }
00438
00439 #define INDR \
00440 IND; \
00441 if(_B) \
00442 { \
00443 iCycleCount += cc_ex[bOpCode]; \
00444 _PC -= 2; \
00445 }
00446
00447 #define INI \
00448 { \
00449 UBYTE io = z80_IN_handler(z80.BC); \
00450 _B--; \
00451 write_mem(_HL, io); \
00452 _HL++; \
00453 _F = SZ[_B]; \
00454 if(io & Sflag) _F |= Nflag; \
00455 if((((_C + 1) & 0xff) + io) & 0x100) _F |= Hflag | Cflag; \
00456 if((irep_tmp1[_C & 3][io & 3] ^ breg_tmp2[_B] ^ (_C >> 2) ^ (io >> 2)) & 1) \
00457 _F |= Pflag; \
00458 }
00459
00460 #define INIR \
00461 INI; \
00462 if(_B) \
00463 { \
00464 iCycleCount += cc_ex[bOpCode]; \
00465 _PC -= 2; \
00466 }
00467
00468 #define LDD \
00469 { \
00470 UBYTE io = read_mem(_HL); \
00471 write_mem(_DE, io); \
00472 _F &= Sflag | Zflag | Cflag; \
00473 if((_A + io) & 0x02) _F |= 0x20; \
00474 if((_A + io) & 0x08) _F |= 0x08; \
00475 _HL--; \
00476 _DE--; \
00477 _BC--; \
00478 if(_BC) _F |= Vflag; \
00479 }
00480
00481 #define LDDR \
00482 LDD; \
00483 if(_BC) \
00484 { \
00485 iCycleCount += cc_ex[bOpCode]; \
00486 _PC -= 2; \
00487 }
00488
00489 #define LDI \
00490 { \
00491 UBYTE io = read_mem(_HL); \
00492 write_mem(_DE, io); \
00493 _F &= Sflag | Zflag | Cflag; \
00494 if((_A + io) & 0x02) _F |= 0x20; \
00495 if((_A + io) & 0x08) _F |= 0x08; \
00496 _HL++; \
00497 _DE++; \
00498 _BC--; \
00499 if(_BC) _F |= Vflag; \
00500 }
00501
00502 #define LDIR \
00503 LDI; \
00504 if(_BC) \
00505 { \
00506 iCycleCount += cc_ex[bOpCode]; \
00507 _PC -= 2; \
00508 }
00509
00510 #define NEG \
00511 { \
00512 UBYTE value = _A; \
00513 _A = 0; \
00514 SUB(value); \
00515 }
00516
00517 #define OUTD \
00518 { \
00519 UBYTE io = read_mem(_HL); \
00520 _B--; \
00521 z80_OUT_handler(z80.BC, io); \
00522 _HL--; \
00523 _F = SZ[_B]; \
00524 if(io & Sflag) _F |= Nflag; \
00525 if((((_C - 1) & 0xff) + io) & 0x100) _F |= Hflag | Cflag; \
00526 if((drep_tmp1[_C & 3][io & 3] ^ breg_tmp2[_B] ^ (_C >> 2) ^ (io >> 2)) & 1) \
00527 _F |= Pflag; \
00528 }
00529
00530 #define OTDR \
00531 OUTD; \
00532 if(_B) \
00533 { \
00534 iCycleCount += cc_ex[bOpCode]; \
00535 _PC -= 2; \
00536 }
00537
00538 #define OUTI \
00539 { \
00540 UBYTE io = read_mem(_HL); \
00541 _B--; \
00542 z80_OUT_handler(z80.BC, io); \
00543 _HL++; \
00544 _F = SZ[_B]; \
00545 if(io & Sflag) _F |= Nflag; \
00546 if((((_C + 1) & 0xff) + io) & 0x100) _F |= Hflag | Cflag; \
00547 if((irep_tmp1[_C & 3][io & 3] ^ breg_tmp2[_B] ^ (_C >> 2) ^ (io >> 2)) & 1) \
00548 _F |= Pflag; \
00549 }
00550
00551 #define OTIR \
00552 OUTI; \
00553 if(_B) \
00554 { \
00555 iCycleCount += cc_ex[bOpCode]; \
00556 _PC -= 2; \
00557 }
00558
00559 #define RLD \
00560 { \
00561 UBYTE n = read_mem(_HL); \
00562 write_mem(_HL, (n << 4) | (_A & 0x0f)); \
00563 _A = (_A & 0xf0) | (n >> 4); \
00564 _F = (_F & Cflag) | SZP[_A]; \
00565 }
00566
00567 #define RRD \
00568 { \
00569 UBYTE n = read_mem(_HL); \
00570 write_mem(_HL, (n >> 4) | (_A << 4)); \
00571 _A = (_A & 0xf0) | (n & 0x0f); \
00572 _F = (_F & Cflag) | SZP[_A]; \
00573 }
00574
00575 #define SBC16(reg) \
00576 { \
00577 DWORD res = _HLdword - z80.reg.d - (_F & Cflag); \
00578 _F = (((_HLdword ^ res ^ z80.reg.d) >> 8) & Hflag) | Nflag | \
00579 ((res >> 16) & Cflag) | \
00580 ((res >> 8) & (Sflag | Xflags)) | \
00581 ((res & 0xffff) ? 0 : Zflag) | \
00582 (((z80.reg.d ^ _HLdword) & (_HLdword ^ res) &0x8000) >> 13); \
00583 _HL = (UWORD)res; \
00584 }
00585
00586
00587 #endif // Z80_MACROS_H