home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / cpem8010.zip / z80.cc < prev   
C/C++ Source or Header  |  1995-02-16  |  54KB  |  1,826 lines

  1. //     $Id: z80.cc 1.5 1995/02/16 22:56:17 rg Exp $    
  2. //      Copyright (c) 1994 by R. Griech
  3. //
  4. //  Z80 Simulation
  5. //  --------------
  6. //  Here the Z80 emulation is contained.  The Z80 is simulated thru big
  7. //  switch statements.  For GNUC && 386 there exists an optimization with
  8. //  asm-statements.  No other secrets exists...
  9. //
  10. //  possible problem areas
  11. //  ----------------------
  12. //  - a 486/33MHz emulates a ~4-6MHz Z80
  13. //  - this is not a complete emulation, especially I/O has no definition
  14. //
  15. //  doubtful constructs
  16. //  -------------------
  17. //  - sometimes the switch-statements have definitions of 0 and 255 without
  18. //    corresponding opcodes.  This is required for the peephole to detect
  19. //    a complete range for a switch for unsigned char
  20. //
  21.  
  22.  
  23.  
  24. #include <stdio.h>
  25. #include "glob.h"
  26.  
  27.  
  28.  
  29. //#undef __GNUC__
  30. #define ALIGN ".align 2,0x90; "
  31.  
  32.  
  33.  
  34. //
  35. //
  36. //  Organisation:
  37. //  Carry,B,A, d.h. für SBC A,D  wird mit SubTab[carry][regD][regA] zugegriffen
  38. //  Dies wird zwecks dem Cache gemacht (denke an INC, DEC)
  39. //  Platz zwischen AddTab und SubTab lassen, da die sich im Cache gegenseitig stören
  40. //
  41. unsigned char FTab[256];
  42. struct _bytewise { unsigned char F,A; };    // same order as in struct _byteregs
  43. typedef union {
  44.    unsigned short AF;
  45.    struct _bytewise b;
  46. } MatAF;
  47. #if !(__i386__  &&  __GNUC__)
  48.    MatAF AddTab[2][256][256];
  49. #endif
  50. MatAF RlcTab[256][2],  RlTab[256][2],
  51.       RrcTab[256][2],  RrTab[256][2],
  52.       SlaTab[256][2],  SraTab[256][2], SrlTab[256][2];
  53. #if !(__i386__  &&  __GNUC__)
  54.    MatAF SubTab[2][256][256];
  55. #endif
  56.  
  57.  
  58.  
  59. //
  60. //
  61. //  opcode counter for profiling
  62. //
  63. #ifdef DEBUG
  64. int CntOp[256], CntOpCB[256], CntOpED[256],
  65.     CntOpIX[256], CntOpIXCB[256], CntOpIY[256], CntOpIYCB[256];
  66. #endif
  67.  
  68.  
  69.  
  70. #ifdef __i386__
  71.  
  72. #define SIGN8(X)  ((int)( (signed char)(X) ))
  73. #define SIGN16(X) ((int)( (short)(X) ))
  74.  
  75. #else
  76.  
  77. static inline int SIGN8( int n )
  78. {
  79.    return( (n <= 127) ? n : n-0x100 );
  80. }   // SIGN8
  81.  
  82. static inline int SIGN16( int n )
  83. {
  84.    return( (n <= 32767) ? n : n-0x10000 );
  85. }   // SIGN16
  86.  
  87. #endif
  88.  
  89.  
  90.  
  91. //////////////////////////////////////////////////////////////////////
  92.  
  93.  
  94.  
  95. #if __i386__  &&  __GNUC__
  96. #define ADD( s,l )                                    \
  97. {                                            \
  98.    asm("movb %2,%%al ; addb %%al,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  99.        ALIGN "1: ; andb $209,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  100.        : "=m" (r.b.A), "=m" (r.b.F)                            \
  101.        : "m"  (s)                                    \
  102.        : "%eax", "%cc" );                                \
  103.    rPC += l;                                        \
  104. }                                            \
  105. break
  106. #else
  107. #define ADD( s,l )                \
  108. {                        \
  109.    r.w.AF = AddTab[0][s][r.b.A].AF;        \
  110.    rPC += l;                    \
  111. }                        \
  112. break
  113. #endif
  114.  
  115.  
  116. #if __i386__  &&  __GNUC__
  117. #define ADC( s,l )                                    \
  118. {                                            \
  119.    asm("movb %1,%%ah ; sahf ;"                                \
  120.        "movb %2,%%al ; adcb %%al,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  121.        ALIGN "1: ; andb $209,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  122.        : "=m" (r.b.A), "=m" (r.b.F)                            \
  123.        : "m"  (s)                                    \
  124.        : "%eax", "%cc" );                                \
  125.    rPC += l;                                        \
  126. }                                            \
  127. break
  128. #else
  129. #define ADC( s,l )                \
  130. {                        \
  131.    unsigned char c = (r.b.F & F_C) ? 1 : 0;    \
  132.    r.w.AF = AddTab[c][s][r.b.A].AF;        \
  133.    rPC += l;                    \
  134. }                        \
  135. break
  136. #endif
  137.  
  138.  
  139. #if __i386__  &&  __GNUC__
  140. #define ADC16( s )                                    \
  141. {                                            \
  142.    asm("movb %1,%%ah ; sahf ;"                                \
  143.        " movw %2,%%ax ; adcw %%ax,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  144.        ALIGN "1: ; andb $193,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  145.        : "=m" (r.w.HL), "=m" (r.b.F)                            \
  146.        : "m"  (s)                                    \
  147.        : "%eax", "%cc" );                                \
  148.    rPC += 2;                                        \
  149. }                                            \
  150. break
  151. #else
  152. #define ADC16( s )                    \
  153. {                            \
  154.    unsigned char c = (r.b.F & F_C) ? 1 : 0;        \
  155.    unsigned ures = r.w.HL + s + c;            \
  156.    int sres = SIGN16(r.w.HL) + SIGN16(s) + c;        \
  157.    r.b.F = 0;                        \
  158.    if (sres > 32767  ||  sres < -32768)            \
  159.        r.b.F = F_PE;                    \
  160.    r.w.HL = ures & 0xffff;                \
  161.    r.b.F = r.b.F | ((r.w.HL >= 0x8000) ? F_S : 0)  |    \
  162.                    ((ures   >= 0x10000) ? F_C : 0) |    \
  163.                    ((r.w.HL == 0) ? F_Z : 0);        \
  164.    rPC += 2;                        \
  165. }                            \
  166. break
  167. #endif
  168.  
  169.  
  170. #if __i386__  &&  __GNUC__
  171. #define ADD16( d,s,l )                                    \
  172. {                                            \
  173.    asm("movb %0,%%cl ; andb $196,%%cl ; movw %2,%%ax ; addw %%ax,%1 ; movb $1,%%al ;"    \
  174.        "jc 1f ; xorb %%al,%%al ;" ALIGN "1: ; orb %%cl,%%al ; movb %%al,%0"        \
  175.        : "=m" (r.b.F), "=m" (d)                                \
  176.        : "m" (s)                                    \
  177.        : "%eax", "%cc", "%ecx" );                            \
  178.    rPC += l;                                        \
  179. }                                            \
  180. break
  181. #else
  182. #define ADD16( d,s,l )                            \
  183. {                                    \
  184.    int ures = d + s;                            \
  185.    d = ures & 0xffff;                            \
  186.    r.b.F = (r.b.F & (F_S|F_Z|F_PE)) | ((ures >= 0x10000) ? F_C : 0);    \
  187.    rPC += l;                                \
  188. }                                    \
  189. break
  190. #endif
  191.  
  192.  
  193. #if __i386__  &&  __GNUC__
  194. #define AND( s,l )                        \
  195. {                                \
  196.    asm("movb %2,%%al ; andb %%al,%0 ; lahf ; andb $196,%%ah ;"    \
  197.        "orb $16,%%ah ; movb %%ah,%1"                \
  198.        : "=m" (r.b.A), "=m" (r.b.F)                \
  199.        : "m" (s)                        \
  200.        : "%eax", "%cc");                    \
  201.    rPC += l;                            \
  202. }                                \
  203. break
  204. #else
  205. #define AND( s,l )                \
  206. {                        \
  207.    r.b.A &= s;                    \
  208.    r.b.F = FTab[r.b.A] | F_H;            \
  209.    rPC += l;                    \
  210. }                        \
  211. break
  212. #endif
  213.  
  214.  
  215. #if __i386__  &&  __GNUC__
  216. #define BIT( bi,d,l )                                 \
  217. {                                         \
  218.    asm("movb %0,%%al ; andb $1,%%al ; orb $16,%%al ;"                 \
  219.        "testb %1,%2 ; jnz 1f ; orb $64,%%al ;" ALIGN "1: ; movb %%al,%0"    \
  220.        : "=m" (r.b.F)                                 \
  221.        : "n" (1 << bi), "m" (d)                             \
  222.        : "%eax", "%cc" );                             \
  223.    rPC += l;                                     \
  224. }                                         \
  225. break
  226. #else
  227. #define BIT( bi,d,l )                        \
  228. {                                \
  229.    r.b.F = (r.b.F & F_C) | F_H | ((d & (1 << bi)) ? 0 : F_Z);    \
  230.    rPC += l;                            \
  231. }                                \
  232. break
  233. #endif
  234.  
  235.  
  236. #define CALL( a,l )                \
  237. {                        \
  238.    r.w.SP -= 2;                    \
  239.    W( Mem+r.w.SP ) = rPC+l-Mem;            \
  240.    rPC = a+Mem;                    \
  241. }                        \
  242. break
  243.  
  244. #define CALLf( flg )                \
  245. {                        \
  246.    rPC += 3;                    \
  247.    if (!(r.b.F & flg)) {            \
  248.       r.w.SP -= 2;                \
  249.       W(Mem+r.w.SP) = rPC-Mem;            \
  250.       rPC = W(rPC-2)+Mem;            \
  251.    }                        \
  252. }                        \
  253. break
  254.  
  255. #define CALLt( flg )                \
  256. {                        \
  257.    rPC += 3;                    \
  258.    if (r.b.F & flg) {                \
  259.       r.w.SP -= 2;                \
  260.       W(Mem+r.w.SP) = rPC-Mem;            \
  261.       rPC = W(rPC-2)+Mem;            \
  262.    }                        \
  263. }                        \
  264. break
  265.  
  266.  
  267. #if __i386__  &&  __GNUC__
  268. #define CP( s,l )                                    \
  269. {                                            \
  270.    asm("movb %2,%%al ; cmpb %%al,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  271.        ALIGN "1: ; andb $211,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  272.        : "=m" (r.b.A), "=m" (r.b.F)                            \
  273.        : "m"  (s)                                    \
  274.        : "%eax", "%cc" );                                \
  275.    rPC += l;                                        \
  276. }
  277. #else
  278. #define CP( s,l )                \
  279. {                        \
  280.    r.b.F = SubTab[0][s][r.b.A].b.F;        \
  281.    rPC += l;                    \
  282. }
  283. #endif
  284.  
  285.  
  286. #if __i386__  &&  __GNUC__
  287. #define DEC( d,l )                                \
  288. {                                        \
  289.    asm("movb %1,%%ah ; sahf ;"                            \
  290.        " decb %0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"        \
  291.        ALIGN "1: ; andb $211,%%ah ; orb %%ah,%%al ; movb %%al,%1"        \
  292.        : "=m" (d), "=m" (r.b.F)                            \
  293.        :                                    \
  294.        : "%eax", "%cc" );                            \
  295.    rPC += l;                                    \
  296. }                                        \
  297. break
  298. #else
  299. #define DEC( d,l )                        \
  300. {                                \
  301.    r.b.F = (SubTab[0][1][d].b.F & ~F_C)  |  (r.b.F & F_C);    \
  302.    d--;                                \
  303.    rPC += l;                            \
  304. }                                \
  305. break
  306. #endif
  307.  
  308.  
  309. #define DEC16( d,l )                \
  310. {                        \
  311.    d--;                        \
  312.    rPC += l;                    \
  313. }                        \
  314. break
  315.  
  316. #define DJNZ()                    \
  317. {                        \
  318.    rPC += 2;                    \
  319.    r.b.B--;                    \
  320.    if (r.b.B)                    \
  321.       rPC += SB(rPC-1);                \
  322. }                        \
  323. break
  324.  
  325.  
  326. //
  327. //
  328. //  first operand should contain the more complicated address expression
  329. //
  330. #if __i386__  &&  __GNUC__
  331. #define _EX16(s1,s2)                    \
  332. {                            \
  333.    asm("movw %1,%%ax ; xchgw %%ax,%0 ; movw %%ax,%1"    \
  334.        : "=m" (s1), "=m" (s2)                \
  335.        :                        \
  336.        : "%eax" );                    \
  337. }
  338. #else
  339. #define _EX16(s1,s2)                \
  340. {                        \
  341.    unsigned short t = s1;            \
  342.    s1 = s2;                    \
  343.    s2 = t;                    \
  344. }
  345. #endif
  346.  
  347.  
  348. #if __i386__  &&  __GNUC__
  349. #define INC( d,l )                                \
  350. {                                        \
  351.    asm("movb %1,%%ah ; sahf ;"                            \
  352.        "incb %0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"        \
  353.        ALIGN "1: ; andb $209,%%ah ; orb %%ah,%%al ; movb %%al,%1"        \
  354.        : "=m" (d), "=m" (r.b.F)                            \
  355.        :                                    \
  356.        : "%eax", "%cc" );                            \
  357.    rPC += l;                                    \
  358. }                                        \
  359. break
  360. #else
  361. #define INC( d,l )                        \
  362. {                                \
  363.    r.b.F = (AddTab[0][1][d].b.F & ~F_C)  |  (r.b.F & F_C);    \
  364.    d++;                                \
  365.    rPC += l;                            \
  366. }                                \
  367. break
  368. #endif
  369.  
  370.  
  371. #define INC16( d,l )                \
  372. {                        \
  373.    d++;                        \
  374.    rPC += l;                    \
  375. }                        \
  376. break
  377.  
  378. #define JP( a )                    \
  379. {                        \
  380.    rPC = a+Mem;                    \
  381. }                        \
  382. break
  383.  
  384. #define JPf( flg )                \
  385. {                        \
  386.    rPC += 3;                    \
  387.    if (!(r.b.F & flg))                \
  388.       rPC = W(rPC-2)+Mem;            \
  389. }                        \
  390. break
  391.  
  392. #define JPt( flg )                \
  393. {                        \
  394.    rPC += 3;                    \
  395.    if (r.b.F & flg)                \
  396.       rPC = W(rPC-2)+Mem;            \
  397. }                        \
  398. break
  399.  
  400. #define JR()                    \
  401. {                        \
  402.    rPC += 2+SB(rPC+1);                \
  403. }                        \
  404. break
  405.  
  406. #define JRf( flg )                \
  407. {                        \
  408.    rPC += 2;                    \
  409.    if (!(r.b.F & flg))                \
  410.       rPC += SB(rPC-1);                \
  411. }                        \
  412. break
  413.  
  414. #define JRt( flg )                \
  415. {                        \
  416.    rPC += 2;                    \
  417.    if (r.b.F & flg)                \
  418.       rPC += SB(rPC-1);                \
  419. }                        \
  420. break
  421.  
  422. #define LD16( d,s,l )                \
  423. {                        \
  424.    d = s;                    \
  425.    rPC += l;                    \
  426. }                        \
  427. break
  428.  
  429. #define LD8( d,s,l )                \
  430. {                        \
  431.    d = s;                    \
  432.    rPC += l;                    \
  433. }                        \
  434. break
  435.  
  436.  
  437. #if __i386__  &&  __GNUC__
  438. #define NEG8( d )                                \
  439. {                                        \
  440.    asm("negb %0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"        \
  441.        ALIGN "1: ; andb $211,%%ah ; orb %%ah,%%al ; movb %%al,%1"        \
  442.        : "=m" (d), "=m" (r.b.F)                            \
  443.        :                                    \
  444.        : "%eax", "%cc");                            \
  445.    rPC += 2;                                    \
  446. }
  447. #else
  448. #define NEG8( d )                \
  449. {                        \
  450.    r.w.AF = SubTab[0][r.b.A][0].AF;        \
  451.    rPC += 2;                    \
  452. }
  453. #endif
  454.  
  455.  
  456. #if __i386__  &&  __GNUC__
  457. #define OR( s,l )                        \
  458. {                                \
  459.    asm("movb %2,%%al ; orb %%al,%0 ; lahf ; andb $196,%%ah ;"    \
  460.        "movb %%ah,%1"                        \
  461.        : "=m" (r.b.A), "=m" (r.b.F)                \
  462.        : "m" (s)                        \
  463.        : "%eax", "%cc");                    \
  464.    rPC += l;                            \
  465. }                                \
  466. break
  467. #else
  468. #define OR( s,l )                \
  469. {                        \
  470.    r.b.A |= s;                    \
  471.    r.b.F = FTab[r.b.A];                \
  472.    rPC += l;                    \
  473. }                        \
  474. break
  475. #endif
  476.  
  477.  
  478. #define POP( d,l )                \
  479. {                        \
  480.    d = W( Mem+r.w.SP );                \
  481.    r.w.SP += 2;                    \
  482.    rPC += l;                    \
  483. }                        \
  484. break
  485.  
  486. #define PUSH( s,l )                \
  487. {                        \
  488.    r.w.SP -= 2;                    \
  489.    W( Mem+r.w.SP ) = s;                \
  490.    rPC += l;                    \
  491. }                        \
  492. break
  493.  
  494.  
  495. #if __i386__  &&  __GNUC__
  496. #define RES( b,d,l )                \
  497. {                        \
  498.    asm("andb %1,%0"                \
  499.        : "=m" (d)                \
  500.        : "n" (~(1 << b))            \
  501.        : "%cc" );                \
  502.    rPC += l;                    \
  503. }                        \
  504. break
  505. #else
  506. #define RES( b,d,l )                \
  507. {                        \
  508.    d &= ~(1 << b);                \
  509.    rPC += l;                    \
  510. }                        \
  511. break
  512. #endif
  513.  
  514.  
  515. #define RET()                    \
  516. {                        \
  517.    rPC = W( Mem+r.w.SP )+Mem;            \
  518.    r.w.SP += 2;                    \
  519. }                        \
  520. break
  521.  
  522. #define RETf( flg )                \
  523. {                        \
  524.    if (!(r.b.F & flg)) {            \
  525.       rPC = W( Mem+r.w.SP )+Mem;        \
  526.       r.w.SP += 2;                \
  527.    }                        \
  528.    else                        \
  529.       rPC += 1;                    \
  530. }                        \
  531. break
  532.  
  533. #define RETt( flg )                \
  534. {                        \
  535.    if (r.b.F & flg) {                \
  536.       rPC = W( Mem+r.w.SP )+Mem;        \
  537.       r.w.SP += 2;                \
  538.    }                        \
  539.    else                        \
  540.        rPC += 1;                \
  541. }                        \
  542. break
  543.  
  544. #define _ROT( d,TAB,l )                \
  545. {                        \
  546.    unsigned char c = (r.b.F & F_C) ? 1 : 0;    \
  547.    r.b.F = TAB[d][c].b.F;            \
  548.    d = TAB[d][c].b.A;                \
  549.    rPC += l;                    \
  550. }                        \
  551. break
  552.  
  553. #define _ROTA( TAB,l )                \
  554. {                        \
  555.    unsigned char c = (r.b.F & F_C) ? 1 : 0;    \
  556.    r.w.AF = TAB[r.b.A][c].AF;            \
  557.    rPC += l;                    \
  558. }                        \
  559. break
  560.  
  561. #define _ROTAA( TAB )                            \
  562. {                                    \
  563.    unsigned char c = (r.b.F & F_C) ? 1 : 0;                \
  564.    r.b.F = (TAB[r.b.A][c].b.F & F_C)  |  (r.b.F & (F_S|F_Z|F_PE));    \
  565.    r.b.A = TAB[r.b.A][c].b.A;                        \
  566.    rPC += 1;                                \
  567. }                                    \
  568. break
  569.  
  570.  
  571. #if __i386__  &&  __GNUC__
  572. #define SBC( s,l )                                    \
  573. {                                            \
  574.    asm("movb %1,%%ah ; sahf ;"                                \
  575.        "movb %2,%%al ; sbbb %%al,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  576.        ALIGN "1: ; andb $211,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  577.        : "=m" (r.b.A), "=m" (r.b.F)                            \
  578.        : "m"  (s)                                    \
  579.        : "%eax", "%cc" );                                \
  580.    rPC += l;                                        \
  581. }                                            \
  582. break
  583. #else
  584. #define SBC( s,l )                \
  585. {                        \
  586.    unsigned char c = (r.b.F & F_C) ? 1 : 0;    \
  587.    r.w.AF = SubTab[c][s][r.b.A].AF;        \
  588.    rPC += l;                    \
  589. }                        \
  590. break
  591. #endif
  592.  
  593.  
  594. #if __i386__  &&  __GNUC__
  595. #define SBC16( s )                                    \
  596. {                                            \
  597.    asm("movb %1,%%ah ; sahf ;"                                \
  598.        "movw %2,%%ax ; sbbw %%ax,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  599.        ALIGN "1: ; andb $195,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  600.        : "=m" (r.w.HL), "=m" (r.b.F)                            \
  601.        : "m"  (s)                                    \
  602.        : "%eax", "%cc" );                                \
  603.    rPC += 2;                                        \
  604. }                                            \
  605. break
  606. #else
  607. #define SBC16( s )                    \
  608. {                            \
  609.    unsigned char c = (r.b.F & F_C) ? 1 : 0;        \
  610.    unsigned ures = r.w.HL - s - c;            \
  611.    int sres = SIGN16(r.w.HL) - SIGN16(s) - c;        \
  612.    r.b.F = 0;                        \
  613.    if (sres > 32767  ||  sres < -32768)            \
  614.        r.b.F = F_PE;                    \
  615.    r.w.HL = ures & 0xffff;                \
  616.    r.b.F = r.b.F | ((r.w.HL >= 0x8000) ? F_S : 0)  |    \
  617.                    ((ures   >= 0x10000) ? F_C : 0) |    \
  618.                    ((r.w.HL == 0) ? F_Z : 0) | F_N;    \
  619.    rPC += 2;                        \
  620. }                            \
  621. break
  622. #endif
  623.  
  624.  
  625. #if __i386__  &&  __GNUC__
  626. #define SUB( s,l )                                    \
  627. {                                            \
  628.    asm("movb %2,%%al ; subb %%al,%0 ; lahf ; movb $4,%%al ; jo 1f ; xorb %%al,%%al ;"    \
  629.        ALIGN "1: ; andb $211,%%ah ; orb %%ah,%%al ; movb %%al,%1"            \
  630.        : "=m" (r.b.A), "=m" (r.b.F)                            \
  631.        : "m"  (s)                                    \
  632.        : "%eax", "%cc" );                                \
  633.    rPC += l;                                        \
  634. }                                            \
  635. break
  636. #else
  637. #define SUB( s,l )                \
  638. {                        \
  639.    r.w.AF = SubTab[0][s][r.b.A].AF;        \
  640.    rPC += l;                    \
  641. }                        \
  642. break
  643. #endif
  644.  
  645.  
  646. #if __i386__  &&  __GNUC__
  647. #define SET( b,d,l )                \
  648. {                        \
  649.    asm("orb %1,%0"                \
  650.        : "=m" (d)                \
  651.        : "n" (1 << b)                \
  652.        : "%cc" );                \
  653.    rPC += l;                    \
  654. }                        \
  655. break
  656. #else
  657. #define SET( b,d,l )                \
  658. {                        \
  659.    d |= (1 << b);                \
  660.    rPC += l;                    \
  661. }                        \
  662. break
  663. #endif
  664.  
  665.  
  666. #if __i386__  &&  __GNUC__
  667. #define XOR( s,l )                        \
  668. {                                \
  669.    asm("movb %2,%%al ; xorb %%al,%0 ; lahf ; andb $196,%%ah ;"    \
  670.        "movb %%ah,%1"                        \
  671.        : "=m" (r.b.A), "=m" (r.b.F)                \
  672.        : "m" (s)                        \
  673.        : "%eax", "%cc");                    \
  674.    rPC += l;                            \
  675. }                                \
  676. break
  677. #else
  678. #define XOR( s,l )                \
  679. {                        \
  680.    r.b.A ^= s;                    \
  681.    r.b.F = FTab[r.b.A];                \
  682.    rPC += l;                    \
  683. }                        \
  684. break
  685. #endif
  686.  
  687.  
  688.  
  689. #ifdef DEBUG
  690. #  define CNTOP( TAB,CODE )  (++TAB [ CODE ])
  691. #else
  692. #  define CNTOP( TAB,CODE )
  693. #endif
  694.  
  695.  
  696. #define INDEX_OPS(JJ)                                    \
  697. {                                            \
  698.    CNTOP( CntOp ## JJ, B(rPC+1) );                            \
  699.    switch( B(rPC+1) ) {                                    \
  700.       case 0x00:  r.b.A = 0xff;  goto DEF_ ## JJ;                    \
  701.       case 0x09:  ADD16( r.w.JJ,r.w.BC,2 );                        \
  702.       case 0x19:  ADD16( r.w.JJ,r.w.DE,2 );                        \
  703.                                             \
  704.       case 0x21:  LD16( r.w.JJ,W(rPC+2), 4 );                        \
  705.       case 0x22:  LD16( W(Mem+W(rPC+2)),r.w.JJ, 4 );                    \
  706.       case 0x23:  INC16( r.w.JJ, 2 );                            \
  707.       case 0x29:  ADD16( r.w.JJ,r.w.JJ,2 );                        \
  708.       case 0x2a:  LD16( r.w.JJ,W(Mem+W(rPC+2)), 4 );                    \
  709.       case 0x2b:  DEC16( r.w.JJ, 2 );                            \
  710.                                             \
  711.       case 0x34:  INC( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  712.       case 0x35:  DEC( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  713.       case 0x36:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),B(rPC+3), 4 );                \
  714.       case 0x39:  ADD16( r.w.JJ,r.w.SP,2 );                        \
  715.                                             \
  716.       case 0x46:  LD8( r.b.B,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  717.       case 0x4e:  LD8( r.b.C,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  718.                                             \
  719.       case 0x56:  LD8( r.b.D,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  720.       case 0x5e:  LD8( r.b.E,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  721.                                             \
  722.       case 0x66:  LD8( r.b.H,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  723.       case 0x6e:  LD8( r.b.L,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  724.                                             \
  725.       case 0x70:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.B, 3 );                \
  726.       case 0x71:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.C, 3 );                \
  727.       case 0x72:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.D, 3 );                \
  728.       case 0x73:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.E, 3 );                \
  729.       case 0x74:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.H, 3 );                \
  730.       case 0x75:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.L, 3 );                \
  731.       case 0x77:  LD8( B(Mem+r.w.JJ+SB(rPC+2)),r.b.A, 3 );                \
  732.       case 0x7e:  LD8( r.b.A,B(Mem+r.w.JJ+SB(rPC+2)), 3 );                \
  733.                                             \
  734.       case 0x86:  ADD( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  735.       case 0x8e:  ADC( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  736.       case 0x96:  SUB( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  737.       case 0x9e:  SBC( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  738.       case 0xa6:  AND( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  739.       case 0xae:  XOR( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  740.       case 0xb6:  OR( B(Mem+r.w.JJ+SB(rPC+2)), 3 );                    \
  741.       case 0xbe:  CP( B(Mem+r.w.JJ+SB(rPC+2)), 3 );    break;                \
  742.                                             \
  743.       case 0xcb:                                    \
  744.          {                                        \
  745.             CNTOP( CntOp ## JJ ## CB, B(rPC+3) );                    \
  746.             switch( B(rPC+3) ) {                            \
  747.                case 0x00:  r.b.A = 0xff;  goto DEF_ ## JJ ## _cb;            \
  748.                case 0x06:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),RlcTab,4 );            \
  749.                case 0x0e:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),RrcTab,4 );            \
  750.                case 0x16:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),RlTab,4 );            \
  751.                case 0x1e:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),RrTab,4 );            \
  752.                case 0x26:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),SlaTab,4 );            \
  753.                case 0x2e:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),SraTab,4 );            \
  754.                case 0x3e:  _ROT( B(Mem+r.w.JJ+SB(rPC+2)),SrlTab,4 );            \
  755.                case 0x46:  BIT( 0,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  756.                case 0x4e:  BIT( 1,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  757.                case 0x56:  BIT( 2,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  758.                case 0x5e:  BIT( 3,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  759.                case 0x66:  BIT( 4,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  760.                case 0x6e:  BIT( 5,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  761.                case 0x76:  BIT( 6,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  762.                case 0x7e:  BIT( 7,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  763.                case 0x86:  RES( 0,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  764.                case 0x8e:  RES( 1,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  765.                case 0x96:  RES( 2,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  766.                case 0x9e:  RES( 3,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  767.                case 0xa6:  RES( 4,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  768.                case 0xae:  RES( 5,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  769.                case 0xb6:  RES( 6,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  770.                case 0xbe:  RES( 7,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  771.                case 0xc6:  SET( 0,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  772.                case 0xce:  SET( 1,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  773.                case 0xd6:  SET( 2,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  774.                case 0xde:  SET( 3,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  775.                case 0xe6:  SET( 4,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  776.                case 0xee:  SET( 5,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  777.                case 0xf6:  SET( 6,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  778.                case 0xfe:  SET( 7,B(Mem+r.w.JJ+SB(rPC+2)), 4 );                \
  779.                case 0xff:  r.b.A = 0xff;  goto DEF_ ## JJ ## _cb;            \
  780.                default:                                    \
  781.                DEF_ ## JJ ## _cb:                            \
  782.                   r.w.PC = rPC-Mem;                            \
  783.                   RegisterDump( r,"ill opcode detected (CB " #JJ " extension)",0 );    \
  784.                   CoreDump();                                \
  785.                   ExitCode = 3;                                \
  786.                   goto finished;                            \
  787.                   break;                                \
  788.             }                                        \
  789.          }                                        \
  790.          break;                                        \
  791.       case 0xe1:  POP( r.w.JJ, 2 );                            \
  792.       case 0xe3:                                    /* EX (SP),JJ */            \
  793.          _EX16( W(Mem+r.w.SP),r.w.JJ );  rPC += 2;  break;                \
  794.       case 0xe5:  PUSH( r.w.JJ, 2 );                            \
  795.       case 0xe9:  JP( r.w.JJ );                                \
  796.       case 0xf9:  LD16( r.w.SP,r.w.JJ,2 );                        \
  797.       case 0xff:  r.b.A = 0xff;  goto DEF_ ## JJ;                    \
  798.       default:                                        \
  799.       DEF_ ## JJ:                                    \
  800.          r.w.PC = rPC-Mem;                                \
  801.          RegisterDump( r,"ill opcode detected (" #JJ " extension)",0 );            \
  802.          CoreDump();                                    \
  803.          ExitCode = 3;                                    \
  804.          goto finished;                                    \
  805.          break;                                        \
  806.    }                                            \
  807. }                                            \
  808. break
  809.  
  810.  
  811.  
  812. void Z80Emu( REGS *preg )
  813. {
  814.    REGS r;
  815. #if __i386__  &&  __GNUC__
  816.    register unsigned char *rPC asm("%ebx");
  817. #else
  818.    register unsigned char *rPC;
  819. #endif
  820.  
  821.    if (opt_Verbose)
  822.       fprintf( stderr,"Z80Emu...\r\n" );
  823.  
  824.    r   = *preg;
  825.    rPC = r.w.PC+Mem;
  826.  
  827.    for (;;) {
  828.  
  829. #ifdef DEBUG
  830.       ++CntOp[ B(rPC) ];
  831.       if (opt_SingleStep) {
  832.          r.w.PC = rPC-Mem;
  833.          RegisterDump( r,"single step",0 );
  834.       }
  835. #endif
  836.  
  837.       switch ( B(rPC) )
  838.      {
  839.      case 0x00:                                                     // NOP
  840.         rPC += 1;
  841.         break;
  842.          case 0x01:  LD16( r.w.BC,W(rPC+1), 3 );
  843.          case 0x02:  LD8( B(Mem+r.w.BC),r.b.A, 1 );
  844.          case 0x03:  INC16( r.w.BC, 1 );
  845.          case 0x04:  INC( r.b.B, 1 );
  846.          case 0x05:  DEC( r.b.B, 1 );
  847.          case 0x06:  LD8( r.b.B,B(rPC+1), 2 );
  848.          case 0x07:  _ROTAA( RlcTab );
  849.          case 0x08:                                                     // EX AF,AF'
  850.             _EX16( r.w.AF,r.w.AF2 );  rPC += 1;  break;
  851.          case 0x09:  ADD16( r.w.HL,r.w.BC, 1 );
  852.          case 0x0a:  LD8( r.b.A,B(Mem+r.w.BC), 1 );
  853.          case 0x0b:  DEC16( r.w.BC, 1 );
  854.          case 0x0c:  INC( r.b.C, 1 );
  855.          case 0x0d:  DEC( r.b.C, 1 );
  856.          case 0x0e:  LD8( r.b.C,B(rPC+1), 2 );
  857.          case 0x0f:  _ROTAA( RrcTab );
  858.  
  859.          case 0x10:  DJNZ();
  860.          case 0x11:  LD16( r.w.DE,W(rPC+1), 3 );
  861.          case 0x12:  LD8( B(Mem+r.w.DE),r.b.A, 1 );
  862.          case 0x13:  INC16( r.w.DE, 1 );
  863.          case 0x14:  INC( r.b.D, 1 );
  864.          case 0x15:  DEC( r.b.D, 1 );
  865.          case 0x16:  LD8( r.b.D,B(rPC+1), 2 );
  866.          case 0x17:  _ROTAA( RlTab );
  867.          case 0x18:  JR();
  868.          case 0x19:  ADD16( r.w.HL,r.w.DE, 1 );
  869.          case 0x1a:  LD8( r.b.A,B(Mem+r.w.DE), 1 );
  870.          case 0x1b:  DEC16( r.w.DE, 1 );
  871.          case 0x1c:  INC( r.b.E, 1 );
  872.          case 0x1d:  DEC( r.b.E, 1 );
  873.          case 0x1e:  LD8( r.b.E,B(rPC+1), 2 );
  874.          case 0x1f:  _ROTAA( RrTab );
  875.  
  876.          case 0x20:  JRf( F_Z );
  877.          case 0x21:  LD16( r.w.HL,W(rPC+1), 3 );
  878.          case 0x22:  LD16( W(Mem+W(rPC+1)),r.w.HL, 3 );
  879.          case 0x23:  INC16( r.w.HL, 1 );
  880.          case 0x24:  INC( r.b.H, 1 );
  881.          case 0x25:  DEC( r.b.H, 1 );
  882.          case 0x26:  LD8( r.b.H,B(rPC+1), 2 );
  883.          case 0x27:                                                     // DAA
  884.             if (r.b.F & F_N) {
  885.                unsigned short c = r.b.A;
  886.                unsigned char nf = 0;
  887.                if (opt_Quest) {
  888.                   r.w.PC = rPC-Mem;
  889.                   RegisterDump( r,"DAA for F_N (not tested, before)",0 );
  890.                }
  891.                if (r.b.F & F_H  ||  (c & 0x0f) >= 0x0a) {
  892.                   c -= 0x06;
  893.                   if (c >= 0x100)
  894.                      r.b.F |= F_C;
  895.                   nf = F_H;
  896.                }
  897.                if (r.b.F & F_C  ||  c >= 0xa0) {
  898.                   c -= 0x60;
  899.                   nf |= F_C;
  900.                }
  901.                r.b.A = c;
  902.                r.b.F = FTab[r.b.A] | nf;
  903.                if (opt_Quest) {
  904.                   r.w.PC = rPC-Mem;
  905.                   RegisterDump( r,"DAA for F_N (not tested, after)",0 );
  906.                }
  907.             } else {
  908.                unsigned short c = r.b.A;
  909.                unsigned char nf = 0;
  910.                if (r.b.F & F_H  ||  (c & 0x0f) >= 0x0a) {
  911.                   c += 0x06;
  912.                   if (c >= 0x100)
  913.                      r.b.F |= F_C;
  914.                   nf |= F_H;           // siehe 386er Buch für Beschreibung von DAA
  915.                }
  916.                if (r.b.F & F_C  ||  c >= 0xa0) {
  917.                   c += 0x60;
  918.                   nf |= F_C;
  919.                }
  920.                r.b.A = c;
  921.                r.b.F = FTab[r.b.A] | nf;
  922.             }
  923.             rPC += 1;
  924.             break;
  925.          case 0x28:  JRt( F_Z );
  926.          case 0x29:  ADD16( r.w.HL,r.w.HL, 1 );
  927.          case 0x2a:  LD16( r.w.HL,W(Mem+W(rPC+1)), 3 );
  928.          case 0x2b:  DEC16( r.w.HL, 1 );
  929.          case 0x2c:  INC( r.b.L, 1 );
  930.          case 0x2d:  DEC( r.b.L, 1 );
  931.          case 0x2e:  LD8( r.b.L,B(rPC+1), 2 );
  932.          case 0x2f:                                                     // CPL
  933.             r.b.A = ~r.b.A;
  934.             r.b.F |= (F_H|F_N);
  935.             rPC += 1;
  936.             break;
  937.  
  938.          case 0x30:  JRf( F_C );
  939.          case 0x31:  LD16( r.w.SP,W(rPC+1), 3 );
  940.          case 0x32:  LD8( B(Mem+W(rPC+1)),r.b.A, 3 );
  941.          case 0x33:  INC16( r.w.SP, 1 );
  942.          case 0x34:  INC( B(Mem+r.w.HL), 1 );
  943.          case 0x35:  DEC( B(Mem+r.w.HL), 1 );
  944.          case 0x36:  LD8( B(Mem+r.w.HL),B(rPC+1), 2 );
  945.          case 0x37:                                                     // SCF
  946.             r.b.F = (r.b.F & (F_S|F_Z|F_PE)) | F_C;
  947.             rPC += 1;
  948.             break;
  949.          case 0x38:  JRt( F_C );
  950.          case 0x39:  ADD16( r.w.HL,r.w.SP, 1 );
  951.          case 0x3a:  LD8( r.b.A,B(Mem+W(rPC+1)), 3 );
  952.          case 0x3b:  DEC16( r.w.SP, 1 );
  953.          case 0x3c:  INC( r.b.A, 1 );
  954.          case 0x3d:  DEC( r.b.A, 1 );
  955.          case 0x3e:  LD8( r.b.A,B(rPC+1), 2 );
  956.          case 0x3f:                                                     // CCF
  957.             r.b.F = (r.b.F & (F_S|F_Z|F_PE|F_C)) ^ F_C;
  958.             rPC += 1;
  959.             break;
  960.  
  961.          case 0x40:  LD8( r.b.B,r.b.B, 1 );
  962.          case 0x41:  LD8( r.b.B,r.b.C, 1 );
  963.          case 0x42:  LD8( r.b.B,r.b.D, 1 );
  964.          case 0x43:  LD8( r.b.B,r.b.E, 1 );
  965.          case 0x44:  LD8( r.b.B,r.b.H, 1 );
  966.          case 0x45:  LD8( r.b.B,r.b.L, 1 );
  967.          case 0x46:  LD8( r.b.B,B(Mem+r.w.HL), 1 );
  968.          case 0x47:  LD8( r.b.B,r.b.A, 1 );
  969.          case 0x48:  LD8( r.b.C,r.b.B, 1 );
  970.          case 0x49:  LD8( r.b.C,r.b.C, 1 );
  971.          case 0x4a:  LD8( r.b.C,r.b.D, 1 );
  972.          case 0x4b:  LD8( r.b.C,r.b.E, 1 );
  973.          case 0x4c:  LD8( r.b.C,r.b.H, 1 );
  974.          case 0x4d:  LD8( r.b.C,r.b.L, 1 );
  975.          case 0x4e:  LD8( r.b.C,B(Mem+r.w.HL), 1 );
  976.          case 0x4f:  LD8( r.b.C,r.b.A, 1 );
  977.  
  978.          case 0x50:  LD8( r.b.D,r.b.B, 1 );
  979.          case 0x51:  LD8( r.b.D,r.b.C, 1 );
  980.          case 0x52:  LD8( r.b.D,r.b.D, 1 );
  981.          case 0x53:  LD8( r.b.D,r.b.E, 1 );
  982.          case 0x54:  LD8( r.b.D,r.b.H, 1 );
  983.          case 0x55:  LD8( r.b.D,r.b.L, 1 );
  984.          case 0x56:  LD8( r.b.D,B(Mem+r.w.HL), 1 );
  985.          case 0x57:  LD8( r.b.D,r.b.A, 1 );
  986.          case 0x58:  LD8( r.b.E,r.b.B, 1 );
  987.          case 0x59:  LD8( r.b.E,r.b.C, 1 );
  988.          case 0x5a:  LD8( r.b.E,r.b.D, 1 );
  989.          case 0x5b:  LD8( r.b.E,r.b.E, 1 );
  990.          case 0x5c:  LD8( r.b.E,r.b.H, 1 );
  991.          case 0x5d:  LD8( r.b.E,r.b.L, 1 );
  992.          case 0x5e:  LD8( r.b.E,B(Mem+r.w.HL), 1 );
  993.          case 0x5f:  LD8( r.b.E,r.b.A, 1 );
  994.  
  995.          case 0x60:  LD8( r.b.H,r.b.B, 1 );
  996.          case 0x61:  LD8( r.b.H,r.b.C, 1 );
  997.          case 0x62:  LD8( r.b.H,r.b.D, 1 );
  998.          case 0x63:  LD8( r.b.H,r.b.E, 1 );
  999.          case 0x64:  LD8( r.b.H,r.b.H, 1 );
  1000.          case 0x65:  LD8( r.b.H,r.b.L, 1 );
  1001.          case 0x66:  LD8( r.b.H,B(Mem+r.w.HL), 1 );
  1002.          case 0x67:  LD8( r.b.H,r.b.A, 1 );
  1003.          case 0x68:  LD8( r.b.L,r.b.B, 1 );
  1004.          case 0x69:  LD8( r.b.L,r.b.C, 1 );
  1005.          case 0x6a:  LD8( r.b.L,r.b.D, 1 );
  1006.          case 0x6b:  LD8( r.b.L,r.b.E, 1 );
  1007.          case 0x6c:  LD8( r.b.L,r.b.H, 1 );
  1008.          case 0x6d:  LD8( r.b.L,r.b.L, 1 );
  1009.          case 0x6e:  LD8( r.b.L,B(Mem+r.w.HL), 1 );
  1010.          case 0x6f:  LD8( r.b.L,r.b.A, 1 );
  1011.  
  1012.          case 0x70:  LD8( B(Mem+r.w.HL),r.b.B, 1 );
  1013.          case 0x71:  LD8( B(Mem+r.w.HL),r.b.C, 1 );
  1014.          case 0x72:  LD8( B(Mem+r.w.HL),r.b.D, 1 );
  1015.          case 0x73:  LD8( B(Mem+r.w.HL),r.b.E, 1 );
  1016.          case 0x74:  LD8( B(Mem+r.w.HL),r.b.H, 1 );
  1017.          case 0x75:  LD8( B(Mem+r.w.HL),r.b.L, 1 );
  1018.          case 0x76:                                                     // HALT
  1019.             if (opt_Quest) {
  1020.                r.w.PC = rPC-Mem;
  1021.                RegisterDump( r,"HALT opcode",0 );
  1022.             }
  1023.             rPC += 1;
  1024.             break;
  1025.          case 0x77:  LD8( B(Mem+r.w.HL),r.b.A, 1 );
  1026.          case 0x78:  LD8( r.b.A,r.b.B, 1 );
  1027.          case 0x79:  LD8( r.b.A,r.b.C, 1 );
  1028.          case 0x7a:  LD8( r.b.A,r.b.D, 1 );
  1029.          case 0x7b:  LD8( r.b.A,r.b.E, 1 );
  1030.          case 0x7c:  LD8( r.b.A,r.b.H, 1 );
  1031.          case 0x7d:  LD8( r.b.A,r.b.L, 1 );
  1032.          case 0x7e:  LD8( r.b.A,B(Mem+r.w.HL), 1 );
  1033.          case 0x7f:  LD8( r.b.A,r.b.A, 1 );
  1034.  
  1035.          case 0x80:  ADD( r.b.B, 1 );
  1036.          case 0x81:  ADD( r.b.C, 1 );
  1037.          case 0x82:  ADD( r.b.D, 1 );
  1038.          case 0x83:  ADD( r.b.E, 1 );
  1039.          case 0x84:  ADD( r.b.H, 1 );
  1040.          case 0x85:  ADD( r.b.L, 1 );
  1041.          case 0x86:  ADD( B(Mem+r.w.HL), 1 );
  1042.          case 0x87:  ADD( r.b.A, 1 );
  1043.          case 0x88:  ADC( r.b.B, 1 );
  1044.          case 0x89:  ADC( r.b.C, 1 );
  1045.          case 0x8a:  ADC( r.b.D, 1 );
  1046.          case 0x8b:  ADC( r.b.E, 1 );
  1047.          case 0x8c:  ADC( r.b.H, 1 );
  1048.          case 0x8d:  ADC( r.b.L, 1 );
  1049.          case 0x8e:  ADC( B(Mem+r.w.HL), 1 );
  1050.          case 0x8f:  ADC( r.b.A, 1 );
  1051.  
  1052.          case 0x90:  SUB( r.b.B, 1 );
  1053.          case 0x91:  SUB( r.b.C, 1 );
  1054.          case 0x92:  SUB( r.b.D, 1 );
  1055.          case 0x93:  SUB( r.b.E, 1 );
  1056.          case 0x94:  SUB( r.b.H, 1 );
  1057.          case 0x95:  SUB( r.b.L, 1 );
  1058.          case 0x96:  SUB( B(Mem+r.w.HL), 1 );
  1059.          case 0x97:  SUB( r.b.A, 1 );
  1060.          case 0x98:  SBC( r.b.B, 1 );
  1061.          case 0x99:  SBC( r.b.C, 1 );
  1062.          case 0x9a:  SBC( r.b.D, 1 );
  1063.          case 0x9b:  SBC( r.b.E, 1 );
  1064.          case 0x9c:  SBC( r.b.H, 1 );
  1065.          case 0x9d:  SBC( r.b.L, 1 );
  1066.          case 0x9e:  SBC( B(Mem+r.w.HL), 1 );
  1067.          case 0x9f:  SBC( r.b.A, 1 );
  1068.  
  1069.          case 0xa0:  AND( r.b.B,1 );
  1070.          case 0xa1:  AND( r.b.C,1 );
  1071.          case 0xa2:  AND( r.b.D,1 );
  1072.          case 0xa3:  AND( r.b.E,1 );
  1073.          case 0xa4:  AND( r.b.H,1 );
  1074.          case 0xa5:  AND( r.b.L,1 );
  1075.          case 0xa6:  AND( B(Mem+r.w.HL),1 );
  1076.          case 0xa7:  AND( r.b.A,1 );
  1077.          case 0xa8:  XOR( r.b.B,1 );
  1078.          case 0xa9:  XOR( r.b.C,1 );
  1079.          case 0xaa:  XOR( r.b.D,1 );
  1080.          case 0xab:  XOR( r.b.E,1 );
  1081.          case 0xac:  XOR( r.b.H,1 );
  1082.          case 0xad:  XOR( r.b.L,1 );
  1083.          case 0xae:  XOR( B(Mem+r.w.HL),1 );
  1084.          case 0xaf:  XOR( r.b.A,1 );
  1085.  
  1086.          case 0xb0:  OR( r.b.B,1 );
  1087.          case 0xb1:  OR( r.b.C,1 );
  1088.          case 0xb2:  OR( r.b.D,1 );
  1089.          case 0xb3:  OR( r.b.E,1 );
  1090.          case 0xb4:  OR( r.b.H,1 );
  1091.          case 0xb5:  OR( r.b.L,1 );
  1092.          case 0xb6:  OR( B(Mem+r.w.HL),1 );
  1093.          case 0xb7:  OR( r.b.A,1 );
  1094.          case 0xb8:  CP( r.b.B,1 );            break;
  1095.          case 0xb9:  CP( r.b.C,1 );            break;
  1096.          case 0xba:  CP( r.b.D,1 );            break;
  1097.          case 0xbb:  CP( r.b.E,1 );            break;
  1098.          case 0xbc:  CP( r.b.H,1 );            break;
  1099.          case 0xbd:  CP( r.b.L,1 );            break;
  1100.          case 0xbe:  CP( B(Mem+r.w.HL),1 );    break;
  1101.          case 0xbf:  CP( r.b.A,1 );            break;
  1102.  
  1103.          case 0xc0:  RETf( F_Z );
  1104.          case 0xc1:  POP( r.w.BC,1 );
  1105.          case 0xc2:  JPf( F_Z );
  1106.          case 0xc3:  JP( W(rPC+1) );
  1107.          case 0xc4:  CALLf( F_Z );
  1108.          case 0xc5:  PUSH( r.w.BC,1 );
  1109.          case 0xc6:  ADD( B(rPC+1), 2 );
  1110.          case 0xc7:  CALL( 0x00,1 );
  1111.          case 0xc8:  RETt( F_Z );
  1112.          case 0xc9:  RET();
  1113.          case 0xca:  JPt( F_Z );
  1114.          case 0xcb:
  1115.             {
  1116. #ifdef DEBUG
  1117.            ++CntOpCB[ B(rPC+1) ];
  1118. #endif
  1119.                switch( B(rPC+1) )
  1120.           {
  1121.           case 0x00:  _ROT( r.b.B,RlcTab,2 );
  1122.           case 0x01:  _ROT( r.b.C,RlcTab,2 );
  1123.           case 0x02:  _ROT( r.b.D,RlcTab,2 );
  1124.           case 0x03:  _ROT( r.b.E,RlcTab,2 );
  1125.           case 0x04:  _ROT( r.b.H,RlcTab,2 );
  1126.           case 0x05:  _ROT( r.b.L,RlcTab,2 );
  1127.           case 0x06:  _ROT( B(Mem+r.w.HL),RlcTab,2 );
  1128.           case 0x07:  _ROTA( RlcTab,2 );
  1129.           case 0x08:  _ROT( r.b.B,RrcTab,2 );
  1130.           case 0x09:  _ROT( r.b.C,RrcTab,2 );
  1131.           case 0x0a:  _ROT( r.b.D,RrcTab,2 );
  1132.           case 0x0b:  _ROT( r.b.E,RrcTab,2 );
  1133.           case 0x0c:  _ROT( r.b.H,RrcTab,2 );
  1134.           case 0x0d:  _ROT( r.b.L,RrcTab,2 );
  1135.           case 0x0e:  _ROT( B(Mem+r.w.HL),RrcTab,2 );
  1136.           case 0x0f:  _ROTA( RrcTab,2 );
  1137.  
  1138.           case 0x10:  _ROT( r.b.B,RlTab,2 );
  1139.           case 0x11:  _ROT( r.b.C,RlTab,2 );
  1140.           case 0x12:  _ROT( r.b.D,RlTab,2 );
  1141.           case 0x13:  _ROT( r.b.E,RlTab,2 );
  1142.           case 0x14:  _ROT( r.b.H,RlTab,2 );
  1143.           case 0x15:  _ROT( r.b.L,RlTab,2 );
  1144.           case 0x16:  _ROT( B(Mem+r.w.HL),RlTab,2 );
  1145.           case 0x17:  _ROTA( RlTab,2 );
  1146.           case 0x18:  _ROT( r.b.B,RrTab,2 );
  1147.           case 0x19:  _ROT( r.b.C,RrTab,2 );
  1148.           case 0x1a:  _ROT( r.b.D,RrTab,2 );
  1149.           case 0x1b:  _ROT( r.b.E,RrTab,2 );
  1150.           case 0x1c:  _ROT( r.b.H,RrTab,2 );
  1151.           case 0x1d:  _ROT( r.b.L,RrTab,2 );
  1152.           case 0x1e:  _ROT( B(Mem+r.w.HL),RrTab,2 );
  1153.           case 0x1f:  _ROTA( RrTab,2 );
  1154.  
  1155.           case 0x20:  _ROT( r.b.B,SlaTab,2 );
  1156.           case 0x21:  _ROT( r.b.C,SlaTab,2 );
  1157.           case 0x22:  _ROT( r.b.D,SlaTab,2 );
  1158.           case 0x23:  _ROT( r.b.E,SlaTab,2 );
  1159.           case 0x24:  _ROT( r.b.H,SlaTab,2 );
  1160.           case 0x25:  _ROT( r.b.L,SlaTab,2 );
  1161.           case 0x26:  _ROT( B(Mem+r.w.HL),SlaTab,2 );
  1162.           case 0x27:  _ROTA( SlaTab,2 );
  1163.           case 0x28:  _ROT( r.b.B,SraTab,2 );
  1164.           case 0x29:  _ROT( r.b.C,SraTab,2 );
  1165.           case 0x2a:  _ROT( r.b.D,SraTab,2 );
  1166.           case 0x2b:  _ROT( r.b.E,SraTab,2 );
  1167.           case 0x2c:  _ROT( r.b.H,SraTab,2 );
  1168.           case 0x2d:  _ROT( r.b.L,SraTab,2 );
  1169.           case 0x2e:  _ROT( B(Mem+r.w.HL),SraTab,2 );
  1170.           case 0x2f:  _ROTA( SraTab,2 );
  1171.  
  1172.           case 0x38:  _ROT( r.b.B,SrlTab,2 );
  1173.           case 0x39:  _ROT( r.b.C,SrlTab,2 );
  1174.           case 0x3a:  _ROT( r.b.D,SrlTab,2 );
  1175.           case 0x3b:  _ROT( r.b.E,SrlTab,2 );
  1176.           case 0x3c:  _ROT( r.b.H,SrlTab,2 );
  1177.           case 0x3d:  _ROT( r.b.L,SrlTab,2 );
  1178.           case 0x3e:  _ROT( B(Mem+r.w.HL),SrlTab,2 );
  1179.           case 0x3f:  _ROTA( SrlTab,2 );
  1180.  
  1181.           case 0x40:  BIT( 0,r.b.B, 2 );
  1182.           case 0x41:  BIT( 0,r.b.C, 2 );
  1183.           case 0x42:  BIT( 0,r.b.D, 2 );
  1184.           case 0x43:  BIT( 0,r.b.E, 2 );
  1185.           case 0x44:  BIT( 0,r.b.H, 2 );
  1186.           case 0x45:  BIT( 0,r.b.L, 2 );
  1187.           case 0x46:  BIT( 0,B(Mem+r.w.HL), 2 );
  1188.           case 0x47:  BIT( 0,r.b.A, 2 );
  1189.  
  1190.           case 0x48:  BIT( 1,r.b.B, 2 );
  1191.           case 0x49:  BIT( 1,r.b.C, 2 );
  1192.           case 0x4a:  BIT( 1,r.b.D, 2 );
  1193.           case 0x4b:  BIT( 1,r.b.E, 2 );
  1194.           case 0x4c:  BIT( 1,r.b.H, 2 );
  1195.           case 0x4d:  BIT( 1,r.b.L, 2 );
  1196.           case 0x4e:  BIT( 1,B(Mem+r.w.HL), 2 );
  1197.           case 0x4f:  BIT( 1,r.b.A, 2 );
  1198.  
  1199.           case 0x50:  BIT( 2,r.b.B, 2 );
  1200.           case 0x51:  BIT( 2,r.b.C, 2 );
  1201.           case 0x52:  BIT( 2,r.b.D, 2 );
  1202.           case 0x53:  BIT( 2,r.b.E, 2 );
  1203.           case 0x54:  BIT( 2,r.b.H, 2 );
  1204.           case 0x55:  BIT( 2,r.b.L, 2 );
  1205.           case 0x56:  BIT( 2,B(Mem+r.w.HL), 2 );
  1206.           case 0x57:  BIT( 2,r.b.A, 2 );
  1207.  
  1208.           case 0x58:  BIT( 3,r.b.B, 2 );
  1209.           case 0x59:  BIT( 3,r.b.C, 2 );
  1210.           case 0x5a:  BIT( 3,r.b.D, 2 );
  1211.           case 0x5b:  BIT( 3,r.b.E, 2 );
  1212.           case 0x5c:  BIT( 3,r.b.H, 2 );
  1213.           case 0x5d:  BIT( 3,r.b.L, 2 );
  1214.           case 0x5e:  BIT( 3,B(Mem+r.w.HL), 2 );
  1215.           case 0x5f:  BIT( 3,r.b.A, 2 );
  1216.  
  1217.           case 0x60:  BIT( 4,r.b.B, 2 );
  1218.           case 0x61:  BIT( 4,r.b.C, 2 );
  1219.           case 0x62:  BIT( 4,r.b.D, 2 );
  1220.           case 0x63:  BIT( 4,r.b.E, 2 );
  1221.           case 0x64:  BIT( 4,r.b.H, 2 );
  1222.           case 0x65:  BIT( 4,r.b.L, 2 );
  1223.           case 0x66:  BIT( 4,B(Mem+r.w.HL), 2 );
  1224.           case 0x67:  BIT( 4,r.b.A, 2 );
  1225.  
  1226.           case 0x68:  BIT( 5,r.b.B, 2 );
  1227.           case 0x69:  BIT( 5,r.b.C, 2 );
  1228.           case 0x6a:  BIT( 5,r.b.D, 2 );
  1229.           case 0x6b:  BIT( 5,r.b.E, 2 );
  1230.           case 0x6c:  BIT( 5,r.b.H, 2 );
  1231.           case 0x6d:  BIT( 5,r.b.L, 2 );
  1232.           case 0x6e:  BIT( 5,B(Mem+r.w.HL), 2 );
  1233.           case 0x6f:  BIT( 5,r.b.A, 2 );
  1234.  
  1235.           case 0x70:  BIT( 6,r.b.B, 2 );
  1236.           case 0x71:  BIT( 6,r.b.C, 2 );
  1237.           case 0x72:  BIT( 6,r.b.D, 2 );
  1238.           case 0x73:  BIT( 6,r.b.E, 2 );
  1239.           case 0x74:  BIT( 6,r.b.H, 2 );
  1240.           case 0x75:  BIT( 6,r.b.L, 2 );
  1241.           case 0x76:  BIT( 6,B(Mem+r.w.HL), 2 );
  1242.           case 0x77:  BIT( 6,r.b.A, 2 );
  1243.  
  1244.           case 0x78:  BIT( 7,r.b.B, 2 );
  1245.           case 0x79:  BIT( 7,r.b.C, 2 );
  1246.           case 0x7a:  BIT( 7,r.b.D, 2 );
  1247.           case 0x7b:  BIT( 7,r.b.E, 2 );
  1248.           case 0x7c:  BIT( 7,r.b.H, 2 );
  1249.           case 0x7d:  BIT( 7,r.b.L, 2 );
  1250.           case 0x7e:  BIT( 7,B(Mem+r.w.HL), 2 );
  1251.           case 0x7f:  BIT( 7,r.b.A, 2 );
  1252.  
  1253.           case 0x80:  RES( 0,r.b.B, 2 );
  1254.           case 0x81:  RES( 0,r.b.C, 2 );
  1255.           case 0x82:  RES( 0,r.b.D, 2 );
  1256.           case 0x83:  RES( 0,r.b.E, 2 );
  1257.           case 0x84:  RES( 0,r.b.H, 2 );
  1258.           case 0x85:  RES( 0,r.b.L, 2 );
  1259.           case 0x86:  RES( 0,B(Mem+r.w.HL), 2 );
  1260.           case 0x87:  RES( 0,r.b.A, 2 );
  1261.  
  1262.           case 0x88:  RES( 1,r.b.B, 2 );
  1263.           case 0x89:  RES( 1,r.b.C, 2 );
  1264.           case 0x8a:  RES( 1,r.b.D, 2 );
  1265.           case 0x8b:  RES( 1,r.b.E, 2 );
  1266.           case 0x8c:  RES( 1,r.b.H, 2 );
  1267.           case 0x8d:  RES( 1,r.b.L, 2 );
  1268.           case 0x8e:  RES( 1,B(Mem+r.w.HL), 2 );
  1269.           case 0x8f:  RES( 1,r.b.A, 2 );
  1270.  
  1271.           case 0x90:  RES( 2,r.b.B, 2 );
  1272.           case 0x91:  RES( 2,r.b.C, 2 );
  1273.           case 0x92:  RES( 2,r.b.D, 2 );
  1274.           case 0x93:  RES( 2,r.b.E, 2 );
  1275.           case 0x94:  RES( 2,r.b.H, 2 );
  1276.           case 0x95:  RES( 2,r.b.L, 2 );
  1277.           case 0x96:  RES( 2,B(Mem+r.w.HL), 2 );
  1278.           case 0x97:  RES( 2,r.b.A, 2 );
  1279.  
  1280.           case 0x98:  RES( 3,r.b.B, 2 );
  1281.           case 0x99:  RES( 3,r.b.C, 2 );
  1282.           case 0x9a:  RES( 3,r.b.D, 2 );
  1283.           case 0x9b:  RES( 3,r.b.E, 2 );
  1284.           case 0x9c:  RES( 3,r.b.H, 2 );
  1285.           case 0x9d:  RES( 3,r.b.L, 2 );
  1286.           case 0x9e:  RES( 3,B(Mem+r.w.HL), 2 );
  1287.           case 0x9f:  RES( 3,r.b.A, 2 );
  1288.  
  1289.           case 0xa0:  RES( 4,r.b.B, 2 );
  1290.           case 0xa1:  RES( 4,r.b.C, 2 );
  1291.           case 0xa2:  RES( 4,r.b.D, 2 );
  1292.           case 0xa3:  RES( 4,r.b.E, 2 );
  1293.           case 0xa4:  RES( 4,r.b.H, 2 );
  1294.           case 0xa5:  RES( 4,r.b.L, 2 );
  1295.           case 0xa6:  RES( 4,B(Mem+r.w.HL), 2 );
  1296.           case 0xa7:  RES( 4,r.b.A, 2 );
  1297.  
  1298.           case 0xa8:  RES( 5,r.b.B, 2 );
  1299.           case 0xa9:  RES( 5,r.b.C, 2 );
  1300.           case 0xaa:  RES( 5,r.b.D, 2 );
  1301.           case 0xab:  RES( 5,r.b.E, 2 );
  1302.           case 0xac:  RES( 5,r.b.H, 2 );
  1303.           case 0xad:  RES( 5,r.b.L, 2 );
  1304.           case 0xae:  RES( 5,B(Mem+r.w.HL), 2 );
  1305.           case 0xaf:  RES( 5,r.b.A, 2 );
  1306.  
  1307.           case 0xb0:  RES( 6,r.b.B, 2 );
  1308.           case 0xb1:  RES( 6,r.b.C, 2 );
  1309.           case 0xb2:  RES( 6,r.b.D, 2 );
  1310.           case 0xb3:  RES( 6,r.b.E, 2 );
  1311.           case 0xb4:  RES( 6,r.b.H, 2 );
  1312.           case 0xb5:  RES( 6,r.b.L, 2 );
  1313.           case 0xb6:  RES( 6,B(Mem+r.w.HL), 2 );
  1314.           case 0xb7:  RES( 6,r.b.A, 2 );
  1315.  
  1316.           case 0xb8:  RES( 7,r.b.B, 2 );
  1317.           case 0xb9:  RES( 7,r.b.C, 2 );
  1318.           case 0xba:  RES( 7,r.b.D, 2 );
  1319.           case 0xbb:  RES( 7,r.b.E, 2 );
  1320.           case 0xbc:  RES( 7,r.b.H, 2 );
  1321.           case 0xbd:  RES( 7,r.b.L, 2 );
  1322.           case 0xbe:  RES( 7,B(Mem+r.w.HL), 2 );
  1323.           case 0xbf:  RES( 7,r.b.A, 2 );
  1324.  
  1325.           case 0xc0:  SET( 0,r.b.B, 2 );
  1326.           case 0xc1:  SET( 0,r.b.C, 2 );
  1327.           case 0xc2:  SET( 0,r.b.D, 2 );
  1328.           case 0xc3:  SET( 0,r.b.E, 2 );
  1329.           case 0xc4:  SET( 0,r.b.H, 2 );
  1330.           case 0xc5:  SET( 0,r.b.L, 2 );
  1331.           case 0xc6:  SET( 0,B(Mem+r.w.HL), 2 );
  1332.           case 0xc7:  SET( 0,r.b.A, 2 );
  1333.  
  1334.           case 0xc8:  SET( 1,r.b.B, 2 );
  1335.           case 0xc9:  SET( 1,r.b.C, 2 );
  1336.           case 0xca:  SET( 1,r.b.D, 2 );
  1337.           case 0xcb:  SET( 1,r.b.E, 2 );
  1338.           case 0xcc:  SET( 1,r.b.H, 2 );
  1339.           case 0xcd:  SET( 1,r.b.L, 2 );
  1340.           case 0xce:  SET( 1,B(Mem+r.w.HL), 2 );
  1341.           case 0xcf:  SET( 1,r.b.A, 2 );
  1342.  
  1343.           case 0xd0:  SET( 2,r.b.B, 2 );
  1344.           case 0xd1:  SET( 2,r.b.C, 2 );
  1345.           case 0xd2:  SET( 2,r.b.D, 2 );
  1346.           case 0xd3:  SET( 2,r.b.E, 2 );
  1347.           case 0xd4:  SET( 2,r.b.H, 2 );
  1348.           case 0xd5:  SET( 2,r.b.L, 2 );
  1349.           case 0xd6:  SET( 2,B(Mem+r.w.HL), 2 );
  1350.           case 0xd7:  SET( 2,r.b.A, 2 );
  1351.  
  1352.           case 0xd8:  SET( 3,r.b.B, 2 );
  1353.           case 0xd9:  SET( 3,r.b.C, 2 );
  1354.           case 0xda:  SET( 3,r.b.D, 2 );
  1355.           case 0xdb:  SET( 3,r.b.E, 2 );
  1356.           case 0xdc:  SET( 3,r.b.H, 2 );
  1357.           case 0xdd:  SET( 3,r.b.L, 2 );
  1358.           case 0xde:  SET( 3,B(Mem+r.w.HL), 2 );
  1359.           case 0xdf:  SET( 3,r.b.A, 2 );
  1360.  
  1361.           case 0xe0:  SET( 4,r.b.B, 2 );
  1362.           case 0xe1:  SET( 4,r.b.C, 2 );
  1363.           case 0xe2:  SET( 4,r.b.D, 2 );
  1364.           case 0xe3:  SET( 4,r.b.E, 2 );
  1365.           case 0xe4:  SET( 4,r.b.H, 2 );
  1366.           case 0xe5:  SET( 4,r.b.L, 2 );
  1367.           case 0xe6:  SET( 4,B(Mem+r.w.HL), 2 );
  1368.           case 0xe7:  SET( 4,r.b.A, 2 );
  1369.  
  1370.           case 0xe8:  SET( 5,r.b.B, 2 );
  1371.           case 0xe9:  SET( 5,r.b.C, 2 );
  1372.           case 0xea:  SET( 5,r.b.D, 2 );
  1373.           case 0xeb:  SET( 5,r.b.E, 2 );
  1374.           case 0xec:  SET( 5,r.b.H, 2 );
  1375.           case 0xed:  SET( 5,r.b.L, 2 );
  1376.           case 0xee:  SET( 5,B(Mem+r.w.HL), 2 );
  1377.           case 0xef:  SET( 5,r.b.A, 2 );
  1378.  
  1379.           case 0xf0:  SET( 6,r.b.B, 2 );
  1380.           case 0xf1:  SET( 6,r.b.C, 2 );
  1381.           case 0xf2:  SET( 6,r.b.D, 2 );
  1382.           case 0xf3:  SET( 6,r.b.E, 2 );
  1383.           case 0xf4:  SET( 6,r.b.H, 2 );
  1384.           case 0xf5:  SET( 6,r.b.L, 2 );
  1385.           case 0xf6:  SET( 6,B(Mem+r.w.HL), 2 );
  1386.           case 0xf7:  SET( 6,r.b.A, 2 );
  1387.  
  1388.           case 0xf8:  SET( 7,r.b.B, 2 );
  1389.           case 0xf9:  SET( 7,r.b.C, 2 );
  1390.           case 0xfa:  SET( 7,r.b.D, 2 );
  1391.           case 0xfb:  SET( 7,r.b.E, 2 );
  1392.           case 0xfc:  SET( 7,r.b.H, 2 );
  1393.           case 0xfd:  SET( 7,r.b.L, 2 );
  1394.           case 0xfe:  SET( 7,B(Mem+r.w.HL), 2 );
  1395.           case 0xff:  SET( 7,r.b.A, 2 );
  1396.  
  1397.           default:
  1398.              r.w.PC = rPC-Mem;
  1399.              RegisterDump( r,"ill opcode detected (CB extension)",0 );
  1400.              CoreDump();
  1401.              ExitCode = 3;
  1402.              goto finished;
  1403.              break;
  1404.           }
  1405.             }
  1406.             break;
  1407.          case 0xcc:  CALLt( F_Z );
  1408.          case 0xcd:  CALL( W(rPC+1),3 );
  1409.          case 0xce:  ADC( B(rPC+1), 2 );
  1410.          case 0xcf:  CALL( 0x08,1 );
  1411.  
  1412.          case 0xd0:  RETf( F_C );
  1413.          case 0xd1:  POP( r.w.DE,1 );
  1414.          case 0xd2:  JPf( F_C );
  1415.          case 0xd4:  CALLf( F_C );
  1416.          case 0xd5:  PUSH( r.w.DE,1 );
  1417.          case 0xd6:  SUB( B(rPC+1), 2 );
  1418.          case 0xd8:  RETt( F_C );
  1419.          case 0xd9:                                                     // EXX
  1420.             _EX16( r.w.BC,r.w.BC2 );  _EX16( r.w.DE,r.w.DE2 );
  1421.             _EX16( r.w.HL,r.w.HL2 );  rPC += 1;  break;
  1422.          case 0xda:  JPt( F_C );
  1423.          case 0xd7:  CALL( 0x10,1 );
  1424.          case 0xdc:  CALLt( F_C );
  1425.          case 0xdd:  INDEX_OPS( IX );
  1426.          case 0xde:  SBC( B(rPC+1), 2 );
  1427.          case 0xdf:  CALL( 0x18,1 );
  1428.  
  1429.          case 0xe0:  RETf( F_PE );
  1430.          case 0xe1:  POP( r.w.HL,1 );
  1431.          case 0xe2:  JPf( F_PE );
  1432.          case 0xe3:                                                     // EX (SP),HL
  1433.             _EX16( W(Mem+r.w.SP),r.w.HL );  rPC += 1;  break;
  1434.          case 0xe4:  CALLf( F_PE );
  1435.          case 0xe5:  PUSH( r.w.HL,1 );
  1436.          case 0xe6:  AND( B(rPC+1),2 );
  1437.          case 0xe7:  CALL( 0x20,1 );
  1438.          case 0xe8:  RETt( F_PE );
  1439.          case 0xe9:  JP( r.w.HL );
  1440.          case 0xea:  JPt( F_PE );
  1441.          case 0xeb:                                                     // EX DE,HL
  1442.             _EX16( r.w.DE,r.w.HL );  rPC += 1;  break;
  1443.          case 0xec:  CALLt( F_PE );
  1444.          case 0xed:
  1445.             {
  1446. #ifdef DEBUG
  1447.            ++CntOpED[ B(rPC+1) ];
  1448. #endif
  1449.                switch( B(rPC+1) )
  1450.           {
  1451.           case 0x00:
  1452.              r.b.A = 0xff;
  1453.              goto DEF_ed;
  1454.  
  1455.           case 0x42:  SBC16( r.w.BC );
  1456.           case 0x43:  LD16( W(Mem+W(rPC+2)),r.w.BC, 4 );
  1457.           case 0x44:  NEG8( r.b.A );  break;
  1458.           case 0x4a:  ADC16( r.w.BC );
  1459.           case 0x4b:  LD16( r.w.BC,W(Mem+W(rPC+2)), 4 );
  1460.  
  1461.           case 0x52:  SBC16( r.w.DE );
  1462.           case 0x53:  LD16( W(Mem+W(rPC+2)),r.w.DE, 4 );
  1463.           case 0x57:                        // LD A,I
  1464.              {
  1465.             if (opt_Quest) {
  1466.                r.w.PC = rPC-Mem;
  1467.                RegisterDump( r,"LD A,I (not meaningful)",0 );
  1468.             }
  1469.              }
  1470.              LD8( r.b.A,r.b.I,2 );
  1471.           case 0x5a:  ADC16( r.w.DE );
  1472.           case 0x5b:  LD16( r.w.DE,W(Mem+W(rPC+2)), 4 );
  1473.  
  1474.           case 0x62:  SBC16( r.w.HL );
  1475.           case 0x63:  LD16( W(Mem+W(rPC+2)),r.w.HL, 4 );
  1476.           case 0x67:                                            // RRD
  1477.              {
  1478.             unsigned char d1 = (r.b.A << 4) & 0xf0;
  1479.             unsigned char d2 = (B(Mem+r.w.HL) >> 4) & 0x0f;
  1480.             unsigned char d3 = B(Mem+r.w.HL) & 0x0f;
  1481.             B(Mem+r.w.HL) = d1 + d2;
  1482.             r.b.A = (r.b.A & 0xf0) + d3;
  1483.             r.b.F = (r.b.F & F_C) | FTab[r.b.A];
  1484.              }
  1485.              rPC += 2;
  1486.              break;
  1487.           case 0x6a:  ADC16( r.w.HL );
  1488.           case 0x6b:  LD16( r.w.HL,W(Mem+W(rPC+2)), 4 );
  1489.           case 0x6f:                                            // RLD
  1490.              {
  1491.             unsigned char d1 = r.b.A & 0x0f;
  1492.             unsigned char d2 = (B(Mem+r.w.HL) >> 4) & 0x0f;
  1493.             unsigned char d3 = (B(Mem+r.w.HL) << 4) & 0xf0;
  1494.             B(Mem+r.w.HL) = d1 + d3;
  1495.             r.b.A = (r.b.A & 0xf0) + d2;
  1496.             r.b.F = (r.b.F & F_C) | FTab[r.b.A];
  1497.              }
  1498.              rPC += 2;
  1499.              break;
  1500.  
  1501.           case 0x72:  SBC16( r.w.SP );
  1502.           case 0x73:  LD16( W(Mem+W(rPC+2)),r.w.SP, 4 );
  1503.           case 0x7a:  ADC16( r.w.SP );
  1504.           case 0x7b:  LD16( r.w.SP,W(Mem+W(rPC+2)), 4 );
  1505.  
  1506.           case 0xa0:                                            // LDI
  1507.              {
  1508.             B(Mem + r.w.DE++) = B(Mem + r.w.HL++);
  1509.             r.w.BC--;
  1510.             r.b.F = (r.b.F & (F_S|F_Z|F_C)) | (r.w.BC ? F_PE : 0);
  1511.              }
  1512.              rPC += 2;
  1513.              break;
  1514.           case 0xa1:                                            // CPI
  1515.              {
  1516.             CP( B(Mem+r.w.HL),0 );       // changes r.b.F
  1517.             r.w.HL++;
  1518.             r.w.BC--;
  1519.             r.b.F = (r.b.F & ~F_PE)  |  (r.w.BC ? F_PE : 0);
  1520.              }
  1521.              rPC += 2;
  1522.              break;
  1523.           case 0xa8:                                            // LDD
  1524.              {
  1525.             B(Mem + r.w.DE--) = B(Mem + r.w.HL--);
  1526.             r.w.BC--;
  1527.             r.b.F = (r.b.F & (F_S|F_Z|F_C)) | (r.w.BC ? F_PE : 0);
  1528.              }
  1529.              rPC += 2;
  1530.              break;
  1531.  
  1532.           case 0xb0:                                            // LDIR
  1533.              do {
  1534.             B(Mem + r.w.DE++) = B(Mem + r.w.HL++);
  1535.              } while (--r.w.BC != 0);
  1536.              r.b.F &= (F_S|F_Z|F_C);
  1537.              rPC += 2;
  1538.              break;
  1539.           case 0xb1:                                            // CPIR
  1540.              {
  1541.             do {
  1542.                CP( B(Mem+r.w.HL),0 );     // changes r.b.F
  1543.                r.w.HL++;
  1544.                r.w.BC--;
  1545.             } while (r.w.BC  &&  (r.b.F & F_Z) == 0);
  1546.             r.b.F = (r.b.F & ~F_PE)  |  (r.w.BC ? F_PE : 0);
  1547.              }
  1548.              rPC += 2;
  1549.              break;
  1550.           case 0xb8:                                            // LDDR
  1551.              do {
  1552.             B(Mem + r.w.DE--) = B(Mem + r.w.HL--);
  1553.              } while (--r.w.BC != 0);
  1554.              r.b.F &= (F_S|F_Z|F_C);
  1555.              rPC += 2;
  1556.              break;
  1557.           case 0xb9:                                            // CPDR
  1558.              {
  1559.             do {
  1560.                CP( B(Mem+r.w.HL),0 );     // changes r.b.F
  1561.                r.w.HL--;
  1562.                r.w.BC--;
  1563.             } while (r.w.BC  &&  (r.b.F & F_Z) == 0);
  1564.             r.b.F = (r.b.F & ~F_PE)  |  (r.w.BC ? F_PE : 0);
  1565.              }
  1566.              rPC += 2;
  1567.              break;
  1568.  
  1569.           case 0xff:
  1570.              r.b.A = 0xff;
  1571.              goto DEF_ed;
  1572.  
  1573.           default:
  1574.             DEF_ed:
  1575.              r.w.PC = rPC-Mem;
  1576.              RegisterDump( r,"ill opcode detected (ED extension)",0 );
  1577.              CoreDump();
  1578.              ExitCode = 3;
  1579.              goto finished;
  1580.              break;
  1581.           }
  1582.             }
  1583.             break;
  1584.          case 0xee:  XOR( B(rPC+1),2 );
  1585.          case 0xef:  CALL( 0x28,1 );
  1586.  
  1587.          case 0xf0:  RETf( F_S );
  1588.          case 0xf1:  POP( r.w.AF,1 );
  1589.          case 0xf2:  JPf( F_S );
  1590.          case 0xf3:                                                     // DI
  1591.         {
  1592.            if (opt_Quest) {
  1593.           r.w.PC = rPC-Mem;
  1594.           RegisterDump( r,"DI (not meaningful)",0 );
  1595.            }
  1596.         }
  1597.             rPC += 1;
  1598.             break;
  1599.          case 0xf4:  CALLf( F_S );
  1600.          case 0xf5:  PUSH( r.w.AF,1 );
  1601.          case 0xf6:  OR( B(rPC+1),2 );
  1602.          case 0xf7:  CALL( 0x30,1 );
  1603.          case 0xf8:  RETt( F_S );
  1604.          case 0xf9:  LD16( r.w.SP,r.w.HL, 1 );
  1605.          case 0xfa:  JPt( F_S );                                        // JP M
  1606.          case 0xfb:                                                     // EI
  1607.         {
  1608.            if (opt_Quest) {
  1609.           r.w.PC = rPC-Mem;
  1610.           RegisterDump( r,"EI (not meaningful)",0 );
  1611.            }
  1612.         }
  1613.             rPC += 1;
  1614.             break;
  1615.          case 0xfc:  CALLt( F_S );
  1616.          case 0xfd:  INDEX_OPS( IY );
  1617.          case 0xfe:  CP( B(rPC+1),2 );   break;
  1618.          case 0xff:  CALL( 0x38,1 );
  1619.          default:
  1620.             r.w.PC = rPC-Mem;
  1621.             RegisterDump( r,"ill opcode detected",0 );
  1622.             CoreDump();
  1623.             ExitCode = 3;
  1624.             goto finished;
  1625.             break;
  1626.      }
  1627.  
  1628.       if (rPC-Mem >= BDOS_BEG) {
  1629.          if (rPC-Mem == BDOS_BEG+6) {
  1630.             r.w.PC = rPC-Mem;
  1631.             Bdos( &r );
  1632.          }
  1633.          else if (rPC-Mem >= BIOS_BEG) {
  1634.             r.w.PC = rPC-Mem;
  1635.             Bios( &r );
  1636.          }
  1637.          else {
  1638.             r.w.PC = rPC-Mem;
  1639.             RegisterDump( r,"ill PC in BDOS/BIOS area",1 );
  1640.             ExitCode = 3;
  1641.             goto finished;
  1642.          }
  1643.          if (ExitCode != 0) {
  1644.             if (ExitCode < 0)
  1645.                ExitCode = 0;
  1646.             goto finished;
  1647.          }
  1648.          rPC = W(Mem+r.w.SP)+Mem;
  1649.          r.w.SP += 2;
  1650.       }
  1651.    }
  1652.   finished:
  1653.    r.w.PC = rPC-Mem;
  1654.    *preg = r;
  1655. }   // Z80Emu
  1656.  
  1657.  
  1658.  
  1659. static inline int ParEven( int A )
  1660. {
  1661.    int cnt = 0;
  1662.    for (;  A != 0;  A &= (A-1))
  1663.       cnt++;
  1664.    return( (cnt % 2) == 0 );
  1665. }   // ParEven
  1666.  
  1667.  
  1668.  
  1669. void Z80EmuInit( void )
  1670. //
  1671. //  materialisierte Funktionen (FB) berechnen
  1672. //
  1673. {
  1674.    static int RunningFromCore = 0;
  1675.    int A,C;
  1676.  
  1677. #ifdef DEBUG
  1678.    int i;
  1679.    for (i = 0;  i <= 255;  i++) {
  1680.       CntOp[i] = 0;
  1681.       CntOpED[i] = 0;
  1682.       CntOpCB[i] = 0;
  1683.       CntOpIX[i] = 0;
  1684.       CntOpIXCB[i] = 0;
  1685.       CntOpIY[i] = 0;
  1686.       CntOpIYCB[i] = 0;
  1687.    }
  1688. #endif
  1689.  
  1690.    if (RunningFromCore)
  1691.       return;
  1692.  
  1693.    RunningFromCore = 1;
  1694.    for (A = 0;  A <= 0xff;  A++)
  1695.       FTab[A] = ((A == 0)   ? F_Z  : 0)  |
  1696.                 ((A >= 128) ? F_S  : 0)  |
  1697.                 (ParEven(A) ? F_PE : 0);
  1698.  
  1699.    for (A = 0;  A <= 0xff;  A++) {
  1700.       for (C = 0;  C <= 1;  C++) {
  1701.          unsigned char res;
  1702.  
  1703.          res = (A & 0x80) ? ((A << 1) + 1) : (A << 1);
  1704.          RlcTab[A][C].b.F  = FTab[res] | ((A & 0x80) ? F_C : 0);
  1705.          RlcTab[A][C].b.A  = res;
  1706.  
  1707.          res = (C) ? ((A << 1) + 1) : (A << 1);
  1708.          RlTab[A][C].b.F   = FTab[res] | ((A & 0x80) ? F_C : 0);
  1709.          RlTab[A][C].b.A   = res;
  1710.  
  1711.          res = (A & 0x01) ? ((A >> 1) | 0x80) : (A >> 1);
  1712.          RrcTab[A][C].b.F  = FTab[res] | ((A & 0x01) ? F_C : 0);
  1713.          RrcTab[A][C].b.A  = res;
  1714.  
  1715.          res = (C) ? ((A >> 1) + 0x80) : (A >> 1);
  1716.          RrTab[A][C].b.F   = FTab[res] | ((A & 0x01) ? F_C : 0);
  1717.          RrTab[A][C].b.A   = res;
  1718.  
  1719.          res = A << 1;
  1720.          SlaTab[A][C].b.F  = FTab[res] | ((A & 0x80) ? F_C : 0);
  1721.          SlaTab[A][C].b.A  = res;
  1722.  
  1723.          res = (A & 0x80) ? ((A >> 1) + 0x80) : (A >> 1);
  1724.          SraTab[A][C].b.F  = FTab[res] | ((A & 0x01) ? F_C : 0);
  1725.          SraTab[A][C].b.A  = res;
  1726.  
  1727.          res = A >> 1;
  1728.          SrlTab[A][C].b.F  = FTab[res] | ((A & 0x01) ? F_C : 0);
  1729.          SrlTab[A][C].b.A  = res;
  1730.       }
  1731.    }
  1732.  
  1733. #if !(__i386__  &&  __GNUC__)
  1734.    for (C = 0;  C <= 1;  C++) {
  1735.       int B;
  1736.       for (B = 0;  B <= 0xff;  B++) {
  1737.          for (A = 0;  A <= 0xff;  A++) {
  1738.             int sres;
  1739.             unsigned char flg;
  1740.  
  1741.             flg = FTab[(A+B+C) & 0xff] & ~F_PE;
  1742.             if (A+B+C >= 0x100)
  1743.                flg |= F_C;
  1744.             if ((A&0x0f) + (B&0x0f) + C >= 0x10)
  1745.                flg |= F_H;
  1746.             sres = SIGN8(A) + SIGN8(B) + C;
  1747.             if (sres > 127  ||  sres < -128)
  1748.                flg |= F_PE;
  1749.             AddTab[C][B][A].b.F = flg;
  1750.             AddTab[C][B][A].b.A = A+B+C;
  1751.  
  1752.             flg = FTab[(A-B-C) & 0xff] & ~F_PE;
  1753.             if (A-B-C < 0)
  1754.                flg |= F_C;
  1755.             if ((A&0x0f) - (B&0x0f) - C < 0)
  1756.                flg |= F_H;
  1757.             sres = SIGN8(A) - SIGN8(B) - C;
  1758.             if (sres > 127  ||  sres < -128)
  1759.                flg |= F_PE;
  1760.             SubTab[C][B][A].b.F = flg | F_N;
  1761.             SubTab[C][B][A].b.A = A-B-C;
  1762.          }
  1763.       }
  1764.    }
  1765. #endif
  1766. }   // Z80EmuInit
  1767.  
  1768.  
  1769.  
  1770. //////////////////////////////////////////////////////////////////
  1771.  
  1772.  
  1773.  
  1774. #ifdef DEBUG
  1775. static void ShowTab( int Tab[], char *Id )
  1776. {
  1777.    int cnt,i;
  1778.    int max,maxndx,total;
  1779.    int first = 1;
  1780.  
  1781.    for (total = 0, i = 0;  i <= 255;  total += Tab[i++] )
  1782.       ;
  1783.    for (cnt = 0;  cnt < 40;  cnt++) {
  1784.       max    = Tab[0];
  1785.       maxndx = 0;
  1786.       for (i = 1;  i <= 255;  i++) {
  1787.      if (Tab[i] > max) {
  1788.         max    = Tab[i];
  1789.         maxndx = i;
  1790.      }
  1791.       }
  1792.       if (max == 0)
  1793.      break;
  1794.       if (first) {
  1795.      fprintf( DIAG,"\r\n%s, total %d:", Id,total );
  1796.      first = 0;
  1797.       }
  1798.       if (cnt % 5 == 0)
  1799.      fprintf( DIAG,"\r\n" );
  1800.       else
  1801.      fprintf( DIAG," | " );
  1802.       fprintf( DIAG,"%02x: %-8d", maxndx,max );
  1803.       Tab[maxndx] = 0;
  1804.    }
  1805.    if (cnt)
  1806.       fprintf( DIAG,"\r\n" );
  1807. }   // ShowTab
  1808. #endif
  1809.  
  1810.  
  1811.  
  1812. void Z80EmuExit( void )
  1813. {
  1814. #ifdef DEBUG
  1815.    if (opt_Profile) {
  1816.       ShowTab( CntOp,    "Opcodes" );
  1817.       ShowTab( CntOpED,  "ED-Ext" );
  1818.       ShowTab( CntOpCB,  "CB-Ext" );
  1819.       ShowTab( CntOpIX,  "DD-Ext" );
  1820.       ShowTab( CntOpIXCB,"DDCB-Ext" );
  1821.       ShowTab( CntOpIY,  "FD-Ext" );
  1822.       ShowTab( CntOpIYCB,"FDCB-Ext" );
  1823.    }
  1824. #endif
  1825. }   // Z80EmuExit
  1826.