macros.h

00001 /***************************************************************************
00002  *   Copyright (C) 2005 by Fred Klaus                                      *
00003  *   frednet@web.de                                                        *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #ifndef Z80_MACROS_H
00021 #define Z80_MACROS_H
00022 
00023 //#define z80_wait_states iCycleCount=0;
00024 //#define z80_int_handler iCycleCount=iCycleCount;
00025 
00026 
00027 /*
00028 #define z80_wait_states \
00029 { \
00030    vdu.access_video_memory(iCycleCount >> 2); \
00031    if (sound.sndEnabled()) { \
00032       psg.setCycleCountHigh(psg.cycleCountHigh() + iCycleCount); \
00033       if (psg.cycleCountHigh() >= sound.sndCycleCountInitHigh()) { \
00034          psg.setCycleCountBoth(psg.cycleCountBoth() - sound.sndCycleCountInitBoth()); \
00035          (sound.*(psg.synthesizer()))(); \
00036       } \
00037    } \
00038    if (fdc.phase() == EXEC_PHASE) { \
00039       fdc.setTimeout(fdc.timeout() - iCycleCount); \
00040       if (fdc.timeout() <= 0) { \
00041          fdc.addFlags(OVERRUN_flag); \
00042          if (fdc.cmdDirection() == FDC_TO_CPU) { \
00043             fdc.read_data(); \
00044          } \
00045          else { \
00046             fdc.write_data(0xff); \
00047          } \
00048       } \
00049    } \*/
00050    /*if ((cpc.tape_motor) && (cpc.tape_play_button)) { \
00051       iTapeCycleCount -= iCycleCount; \
00052       if (iTapeCycleCount <= 0) { \
00053          Tape_UpdateLevel(); \
00054       } \
00055    }*/ /*\
00056    cpc.setCycleCount(cpc.cycleCount() - iCycleCount); \
00057 }
00058 
00059 
00060 #define z80_int_handler \
00061 { \
00062    if (_IFF1) { // process interrupts? \
00063       _R++; \
00064       _IFF1 = _IFF2 = 0; // clear interrupt flip-flops \
00065       z80.int_pending = 0; \
00066       cpc.gatearray().setSlCount(cpc.gatearray().slCount() & 0xdf); // clear bit 5 of GA scanline counter  \
00067       if (_HALT) { // HALT instruction active?  \
00068          _HALT = 0; // exit HALT 'loop'  \
00069          _PC++; // correct PC  \
00070       } \
00071       if (_IM < 2) { // interrupt mode 0 or 1? (IM0 = IM1 on the CPC)  \
00072          iCycleCount = 20; \
00073          if (iWSAdjust) { \
00074             iCycleCount -= 4; \
00075          } \
00076          RST(0x0038); \
00077          z80_wait_states \
00078       } \
00079       else { // interrupt mode 2  \
00080          REGPAIR addr; \
00081          iCycleCount = 28; // was 76  \
00082          if (iWSAdjust) { \
00083             iCycleCount -= 4; \
00084          } \
00085          write_mem(--_SP, z80.PC.b.h); // store high byte of current PC  \
00086          write_mem(--_SP, z80.PC.b.l); // store low byte of current PC  \
00087          addr.b.l = 0xff; // assemble pointer  \
00088          addr.b.h = _I; \
00089          z80.PC.b.l = read_mem(addr.w.l); // retrieve low byte of vector  \
00090          z80.PC.b.h = read_mem(addr.w.l+1); // retrieve high byte of vector  \
00091          z80_wait_states \
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++); /* subroutine address low byte */ \
00177    dest.b.h = read_mem(_PC++); /* subroutine address high byte */ \
00178    write_mem(--_SP, z80.PC.b.h); /* store high byte of current PC */ \
00179    write_mem(--_SP, z80.PC.b.l); /* store low byte of current PC */ \
00180    _PC = dest.w.l; /* continue execution at subroutine */ \
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)); /* grab signed jump offset */ \
00213    _PC += offset + 1; /* add offset & correct PC */ \
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); /* store high byte of current PC */ \
00336    write_mem(--_SP, z80.PC.b.l); /* store low byte of current PC */ \
00337    _PC = addr; /* continue execution at restart address */ \
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

Generated on Fri Mar 16 21:30:28 2007 for roland.kdevelop by  doxygen 1.5.0