Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /********************************************************************************/
  2. /*                                                                              */
  3. /* CZ80 opcode include source file                                              */
  4. /* C Z80 emulator version 0.91                                                  */
  5. /* Copyright 2004-2005 Stephane Dallongeville                                   */
  6. /*                                                                              */
  7. /********************************************************************************/
  8.  
  9. #if CZ80_USE_JUMPTABLE
  10.     goto *JumpTable[Opcode];
  11. #else
  12. switch (Opcode)
  13. {
  14. #endif
  15.  
  16.     // 8 BITS LOAD
  17.    
  18.     OP(0x00):   // NOP
  19.  
  20.     OP(0x40):   // LD   B,B
  21.     OP(0x49):   // LD   C,C
  22.     OP(0x52):   // LD   D,D
  23.     OP(0x5b):   // LD   E,E
  24.     OP(0x64):   // LD   H,H
  25.     OP(0x6d):   // LD   L,L
  26.     OP(0x7f):   // LD   A,A
  27. OP_NOP:
  28.         RET(4)
  29.  
  30.     OP(0x41):   // LD   B,C
  31.     OP(0x42):   // LD   B,D
  32.     OP(0x43):   // LD   B,E
  33.     OP(0x44):   // LD   B,H
  34.     OP(0x45):   // LD   B,L
  35.     OP(0x47):   // LD   B,A
  36.  
  37.     OP(0x48):   // LD   C,B
  38.     OP(0x4a):   // LD   C,D
  39.     OP(0x4b):   // LD   C,E
  40.     OP(0x4c):   // LD   C,H
  41.     OP(0x4d):   // LD   C,L
  42.     OP(0x4f):   // LD   C,A
  43.  
  44.     OP(0x50):   // LD   D,B
  45.     OP(0x51):   // LD   D,C
  46.     OP(0x53):   // LD   D,E
  47.     OP(0x54):   // LD   D,H
  48.     OP(0x55):   // LD   D,L
  49.     OP(0x57):   // LD   D,A
  50.  
  51.     OP(0x58):   // LD   E,B
  52.     OP(0x59):   // LD   E,C
  53.     OP(0x5a):   // LD   E,D
  54.     OP(0x5c):   // LD   E,H
  55.     OP(0x5d):   // LD   E,L
  56.     OP(0x5f):   // LD   E,A
  57.  
  58.     OP(0x60):   // LD   H,B
  59.     OP(0x61):   // LD   H,C
  60.     OP(0x62):   // LD   H,D
  61.     OP(0x63):   // LD   H,E
  62.     OP(0x65):   // LD   H,L
  63.     OP(0x67):   // LD   H,A
  64.  
  65.     OP(0x68):   // LD   L,B
  66.     OP(0x69):   // LD   L,C
  67.     OP(0x6a):   // LD   L,D
  68.     OP(0x6b):   // LD   L,E
  69.     OP(0x6c):   // LD   L,H
  70.     OP(0x6f):   // LD   L,A
  71.  
  72.     OP(0x78):   // LD   A,B
  73.     OP(0x79):   // LD   A,C
  74.     OP(0x7a):   // LD   A,D
  75.     OP(0x7b):   // LD   A,E
  76.     OP(0x7c):   // LD   A,H
  77.     OP(0x7d):   // LD   A,L
  78. OP_LD_R_R:
  79.         zR8((Opcode >> 3) & 7) = zR8(Opcode & 7);
  80.         RET(4)
  81.  
  82.     OP(0x06):   // LD   B,#imm
  83.     OP(0x0e):   // LD   C,#imm
  84.     OP(0x16):   // LD   D,#imm
  85.     OP(0x1e):   // LD   E,#imm
  86.     OP(0x26):   // LD   H,#imm
  87.     OP(0x2e):   // LD   L,#imm
  88.     OP(0x3e):   // LD   A,#imm
  89. OP_LD_R_imm:
  90.         zR8(Opcode >> 3) = FETCH_BYTE;
  91.         RET(7)
  92.  
  93.     OP(0x46):   // LD   B,(HL)
  94.     OP(0x4e):   // LD   C,(HL)
  95.     OP(0x56):   // LD   D,(HL)
  96.     OP(0x5e):   // LD   E,(HL)
  97.     OP(0x66):   // LD   H,(HL)
  98.     OP(0x6e):   // LD   L,(HL)
  99.     OP(0x7e):   // LD   A,(HL)
  100. /* OP_LD_R_mHL: */
  101.         PRE_IO
  102.         READ_BYTE(zHL, zR8((Opcode >> 3) & 7))
  103.         POST_IO
  104.         RET(7)
  105.  
  106.     OP(0x70):   // LD   (HL),B
  107.     OP(0x71):   // LD   (HL),C
  108.     OP(0x72):   // LD   (HL),D
  109.     OP(0x73):   // LD   (HL),E
  110.     OP(0x74):   // LD   (HL),H
  111.     OP(0x75):   // LD   (HL),L
  112.     OP(0x77):   // LD   (HL),A
  113. /* OP_LD_mHL_R: */
  114.         PRE_IO
  115.         WRITE_BYTE(zHL, zR8(Opcode & 7))
  116.         POST_IO
  117.         RET(7)
  118.  
  119.     OP(0x36):   // LD (HL), #imm
  120. /* OP_LD_mHL_imm: */
  121.         PRE_IO
  122.         WRITE_BYTE(zHL, FETCH_BYTE)
  123.         POST_IO
  124.         RET(10)
  125.  
  126.     {
  127.         uint16_t adr;
  128.    
  129.     OP(0x0a):   // LD   A,(BC)
  130. OP_LOAD_A_mBC:
  131.         adr = zBC;
  132.         goto OP_LOAD_A_mxx;
  133.        
  134.     OP(0x1a):   // LD   A,(DE)
  135. OP_LOAD_A_mDE:
  136.         adr = zDE;
  137.  
  138. OP_LOAD_A_mxx:
  139.         PRE_IO
  140.         READ_BYTE(adr, zA)
  141.         POST_IO
  142.         RET(7)
  143.  
  144.     OP(0x3a):   // LD   A,(nn)
  145. OP_LOAD_A_mNN:
  146.         PRE_IO
  147.         FETCH_WORD(adr)
  148.         READ_BYTE(adr, zA)
  149.         POST_IO
  150.         RET(13)
  151.  
  152.     OP(0x02):   // LD   (BC),A
  153. OP_LOAD_mBC_A:
  154.         adr = zBC;
  155.         goto OP_LOAD_mxx_A;
  156.  
  157.     OP(0x12):   // LD   (DE),A
  158. OP_LOAD_mDE_A:
  159.         adr = zDE;
  160.  
  161. OP_LOAD_mxx_A:
  162.         PRE_IO
  163.         WRITE_BYTE(adr, zA)
  164.         POST_IO
  165.         RET(7)
  166.  
  167.     OP(0x32):   // LD   (nn),A
  168. OP_LOAD_mNN_A:
  169.         PRE_IO
  170.         FETCH_WORD(adr)
  171.         WRITE_BYTE(adr, zA)
  172.         POST_IO
  173.         RET(13)
  174.     }
  175.  
  176.     // 16 BITS LOAD
  177.  
  178.     OP(0x01):   // LD   BC,nn
  179.     OP(0x11):   // LD   DE,nn
  180.     OP(0x21):   // LD   HL,nn
  181. OP_LOAD_RR_imm16:
  182.         FETCH_WORD(zR16(Opcode >> 4))
  183.         RET(10)
  184.  
  185.     OP(0x31):   // LD   SP,nn
  186. OP_LOAD_SP_imm16:
  187.         FETCH_WORD(zSP)
  188.         RET(10)
  189.  
  190.     OP(0xf9):   // LD   SP,HL
  191. OP_LD_SP_xx:
  192.         zSP = data->W;
  193.         RET(6)
  194.  
  195.     {
  196.         uint16_t adr;
  197.  
  198.     OP(0x2a):   // LD   HL,(nn)
  199. OP_LD_xx_mNN:
  200.         PRE_IO
  201.         FETCH_WORD(adr)
  202.         READ_WORD_LE(adr, data->W)
  203.         POST_IO
  204.         RET(16)
  205.  
  206.     OP(0x22):   // LD   (nn),HL
  207. OP_LD_mNN_xx:
  208.         PRE_IO
  209.         FETCH_WORD(adr)
  210.         WRITE_WORD_LE(adr, data->W)
  211.         POST_IO
  212.         RET(16)
  213.     }
  214.  
  215.     // PUSH / POP
  216.  
  217.     OP(0xf1):   // POP  AF
  218. OP_POP_AF:
  219.     {
  220.         uint16_t res;
  221.  
  222.         PRE_IO
  223.         POP_16(res)
  224.         zA = res >> 8;
  225.         zF = res & 0xFF;
  226.         POST_IO
  227.         RET(10)
  228.     }
  229.  
  230.     OP(0xc1):   // POP  BC
  231.     OP(0xd1):   // POP  DE
  232. OP_POP_RR:
  233.         data = pzR16((Opcode >> 4) & 3);
  234.  
  235.     OP(0xe1):   // POP  HL
  236. OP_POP:
  237.         PRE_IO
  238.         POP_16(data->W)
  239.         POST_IO
  240.         RET(10)
  241.  
  242.     OP(0xf5):   // PUSH AF
  243. OP_PUSH_AF:
  244.         PRE_IO
  245.         PUSH_16((zA << 8) | zF);
  246.         POST_IO
  247.         RET(11)
  248.  
  249.     OP(0xc5):   // PUSH BC
  250.     OP(0xd5):   // PUSH DE
  251. OP_PUSH_RR:
  252.         data = pzR16((Opcode >> 4) & 3);
  253.  
  254.     OP(0xe5):   // PUSH HL
  255. OP_PUSH:
  256.         PRE_IO
  257.         PUSH_16(data->W);
  258.         POST_IO
  259.         RET(11)
  260.  
  261.     // EXCHANGE & BLOCK TRANSFERT / SEARCH
  262.  
  263.     {
  264.         uint16_t tmp;
  265.  
  266.     OP(0x08):   // EX   AF,AF'
  267. OP_EX_AF_AF2:
  268.        tmp = zFA;
  269.        zFA = zFA2;
  270.        zFA2 = tmp;
  271.        RET(4)
  272.  
  273.    OP(0xeb):   // EX   DE,HL
  274. OP_EX_DE_HL:
  275.        tmp = zDE;
  276.        zDE = zHL;
  277.        zHL = tmp;
  278.        RET(4)
  279.  
  280.    OP(0xd9):   // EXX
  281. OP_EXX:
  282.        tmp = zBC;
  283.        zBC = zBC2;
  284.        zBC2 = tmp;
  285.        tmp = zDE;
  286.        zDE = zDE2;
  287.        zDE2 = tmp;
  288.        tmp = zHL;
  289.        zHL = zHL2;
  290.        zHL2 = tmp;
  291.        RET(4)
  292.    }
  293.  
  294.    OP(0xe3):   // EX   HL,(SP)
  295.    {
  296.        uint16_t adr;
  297.        uint16_t tmp;
  298.        
  299. OP_EX_xx_mSP:
  300.        PRE_IO
  301.        adr = zSP;
  302.        tmp = data->W;
  303.        READ_WORD_LE(adr, data->W)
  304.        WRITE_WORD_LE(adr, tmp)
  305.        POST_IO
  306.        RET(19)
  307.    }
  308.  
  309.    // 8 BITS ARITHMETIC
  310.  
  311.    OP(0x04):   // INC  B
  312.    OP(0x0c):   // INC  C
  313.    OP(0x14):   // INC  D
  314.    OP(0x1c):   // INC  E
  315.    OP(0x24):   // INC  H
  316.    OP(0x2c):   // INC  L
  317.    OP(0x3c):   // INC  A
  318. OP_INC_R:
  319.        zR8(Opcode >> 3)++;
  320.        zF = (zF & CZ80_CF) | SZXYHV_inc[zR8(Opcode >> 3)];
  321.        RET(4)
  322.  
  323.    {
  324.        uint16_t adr;
  325.        uint16_t res;
  326.        
  327. OP_INC_mIx:
  328.        adr = data->W + FETCH_BYTE_S;
  329.        CCnt -= 11;
  330.        goto OP_INC_m;
  331.  
  332.    OP(0x34):   // INC  (HL)
  333.        adr = zHL;
  334.        
  335. OP_INC_m:
  336.        PRE_IO
  337.        READ_BYTE(adr, res)
  338.        res = (res + 1) & 0xFF;
  339.        WRITE_BYTE(adr, res)
  340.        zF = (zF & CZ80_CF) | SZXYHV_inc[res];
  341.        POST_IO
  342.        RET(11)
  343.    }
  344.  
  345.    OP(0x05):   // DEC  B
  346.    OP(0x0d):   // DEC  C
  347.    OP(0x15):   // DEC  D
  348.    OP(0x1d):   // DEC  E
  349.    OP(0x25):   // DEC  H
  350.    OP(0x2d):   // DEC  L
  351.    OP(0x3d):   // DEC  A
  352. OP_DEC_R:
  353.        zR8(Opcode >> 3)--;
  354.        zF = (zF & CZ80_CF) | SZXYHV_dec[zR8(Opcode >> 3)];
  355.        RET(4)
  356.  
  357.    {
  358.        uint16_t adr;
  359.        uint16_t res;
  360.  
  361. OP_DEC_mIx:
  362.        adr = data->W + FETCH_BYTE_S;
  363.        CCnt -= 11;
  364.        goto OP_DEC_m;
  365.  
  366.    OP(0x35):   // DEC  (HL)
  367.        adr = zHL;
  368.  
  369. OP_DEC_m:
  370.        PRE_IO
  371.        READ_BYTE(adr, res)
  372.        res = (res - 1) & 0xFF;
  373.        WRITE_BYTE(adr, res)
  374.        zF = (zF & CZ80_CF) | SZXYHV_dec[res];
  375.        POST_IO
  376.        RET(11)
  377.    }
  378.  
  379.    {
  380.        uint8_t val;
  381.        uint16_t res;
  382.  
  383.    // ADD
  384.  
  385. OP_ADD_mIx:
  386.        PRE_IO
  387.        READ_BYTE(data->W + FETCH_BYTE_S, val)
  388.        POST_IO
  389.        CCnt -= 11;
  390.        goto OP_ADD;
  391.  
  392.    OP(0xc6):   // ADD  A,n
  393. OP_ADD_imm:
  394.        val = FETCH_BYTE;
  395.        CCnt -= 3;
  396.        goto OP_ADD;
  397.  
  398.    OP(0x86):   // ADD  A,(HL)
  399. /* OP_ADD_mHL: */
  400.        PRE_IO
  401.        READ_BYTE(zHL, val)
  402.        POST_IO
  403.        CCnt -= 3;
  404.        goto OP_ADD;
  405.  
  406. OP_ADD_IxH:
  407.        val = data->B.H;
  408.        goto OP_ADD;
  409.  
  410. OP_ADD_IxL:
  411.        val = data->B.L;
  412.        goto OP_ADD;
  413.  
  414.    OP(0x80):   // ADD  A,B
  415.    OP(0x81):   // ADD  A,C
  416.    OP(0x82):   // ADD  A,D
  417.    OP(0x83):   // ADD  A,E
  418.    OP(0x84):   // ADD  A,H
  419.    OP(0x85):   // ADD  A,L
  420.    OP(0x87):   // ADD  A,A
  421. OP_ADD_R:
  422.        val = zR8(Opcode & 7);
  423.  
  424. OP_ADD:
  425. // bench : maybe use src instead of zA in zF calculation
  426.        res = zA + val;
  427.        zF = SZXY[res & 0xFF] |                                 // S/Z/X/Y flag
  428.            ((zA ^ res ^ val) & CZ80_HF) |                      // H flag
  429.            (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5) |   // V flag
  430.            ((res >> 8) & CZ80_CF);                             // C flag
  431.        zA = res;
  432.        RET(4)
  433.  
  434.    // ADC
  435.  
  436. OP_ADC_mIx:
  437.        PRE_IO
  438.        READ_BYTE(data->W + FETCH_BYTE_S, val)
  439.        POST_IO
  440.        CCnt -= 11;
  441.        goto OP_ADC;
  442.  
  443.    OP(0xce):   // ADC  A,n
  444. OP_ADC_imm:
  445.        val = FETCH_BYTE;
  446.        CCnt -= 3;
  447.        goto OP_ADC;
  448.  
  449.    OP(0x8e):   // ADC  A,(HL)
  450. /* OP_ADC_mHL: */
  451.        PRE_IO
  452.        READ_BYTE(zHL, val)
  453.        POST_IO
  454.        CCnt -= 3;
  455.        goto OP_ADC;
  456.  
  457. OP_ADC_IxH:
  458.        val = data->B.H;
  459.        goto OP_ADC;
  460.  
  461. OP_ADC_IxL:
  462.        val = data->B.L;
  463.        goto OP_ADC;
  464.  
  465.    OP(0x88):   // ADC  A,B
  466.    OP(0x89):   // ADC  A,C
  467.    OP(0x8a):   // ADC  A,D
  468.    OP(0x8b):   // ADC  A,E
  469.    OP(0x8c):   // ADC  A,H
  470.    OP(0x8d):   // ADC  A,L
  471.    OP(0x8f):   // ADC  A,A
  472. OP_ADC_R:
  473.        val = zR8(Opcode & 7);
  474.  
  475. OP_ADC:
  476. // bench : maybe use src instead of zA in zF calculation
  477.        res = (zA + val) + (zF & CZ80_CF);
  478.        zF = SZXY[res & 0xFF] |                                 // S/Z/X/Y flag
  479.            ((zA ^ res ^ val) & CZ80_HF) |                      // H flag
  480.            (((val ^ zA ^ 0x80) & (val ^ res) & 0x80) >> 5) |   // V flag
  481.            ((res >> 8) & CZ80_CF);                             // C flag
  482.        zA = res;
  483.        RET(4)
  484.  
  485.    // SUB
  486.  
  487. OP_SUB_mIx:
  488.        PRE_IO
  489.        READ_BYTE(data->W + FETCH_BYTE_S, val)
  490.        POST_IO
  491.        CCnt -= 11;
  492.        goto OP_SUB;
  493.  
  494.    OP(0xd6):   // SUB  A,n
  495. OP_SUB_imm:
  496.        val = FETCH_BYTE;
  497.        CCnt -= 3;
  498.        goto OP_SUB;
  499.  
  500.    OP(0x96):   // SUB  (HL)
  501. /* OP_SUB_mHL: */
  502.        PRE_IO
  503.        READ_BYTE(zHL, val)
  504.        POST_IO
  505.        CCnt -= 3;
  506.        goto OP_SUB;
  507.  
  508. OP_SUB_IxH:
  509.        val = data->B.H;
  510.        goto OP_SUB;
  511.  
  512. OP_SUB_IxL:
  513.        val = data->B.L;
  514.        goto OP_SUB;
  515.  
  516.    OP(0x90):   // SUB  B
  517.    OP(0x91):   // SUB  C
  518.    OP(0x92):   // SUB  D
  519.    OP(0x93):   // SUB  E
  520.    OP(0x94):   // SUB  H
  521.    OP(0x95):   // SUB  L
  522.    OP(0x97):   // SUB  A
  523. OP_SUB_R:
  524.        val = zR8(Opcode & 7);
  525.  
  526. OP_SUB:
  527. // bench : maybe use src instead of zA in zF calculation
  528.        res = zA - val;
  529.        zF = SZXY[res & 0xFF] |                             // S/Z/X/Y flag
  530.            ((zA ^ res ^ val) & CZ80_HF) |                  // H flag
  531.            (((val ^ zA) & (zA ^ res) & 0x80) >> 5) |       // V flag
  532.            ((res >> 8) & CZ80_CF) | CZ80_NF;               // C/N flag
  533.        zA = res;
  534.        RET(4)
  535.  
  536.    // SBC
  537.  
  538. OP_SBC_mIx:
  539.        PRE_IO
  540.        READ_BYTE(data->W + FETCH_BYTE_S, val)
  541.        POST_IO
  542.        CCnt -= 11;
  543.        goto OP_SBC;
  544.  
  545.    OP(0xde):   // SBC  A,n
  546. OP_SBC_imm:
  547.        val = FETCH_BYTE;
  548.        CCnt -= 3;
  549.        goto OP_SBC;
  550.  
  551.    OP(0x9e):   // SBC  A,(HL)
  552. /* OP_SBC_mHL: */
  553.        PRE_IO
  554.        READ_BYTE(zHL, val)
  555.        POST_IO
  556.        CCnt -= 3;
  557.        goto OP_SBC;
  558.  
  559. OP_SBC_IxH:
  560.        val = data->B.H;
  561.        goto OP_SBC;
  562.  
  563. OP_SBC_IxL:
  564.        val = data->B.L;
  565.        goto OP_SBC;
  566.  
  567.    OP(0x98):   // SBC  A,B
  568.    OP(0x99):   // SBC  A,C
  569.    OP(0x9a):   // SBC  A,D
  570.    OP(0x9b):   // SBC  A,E
  571.    OP(0x9c):   // SBC  A,H
  572.    OP(0x9d):   // SBC  A,L
  573.    OP(0x9f):   // SBC  A,A
  574. OP_SBC_R:
  575.        val = zR8(Opcode & 7);
  576.  
  577. OP_SBC:
  578. // bench : maybe use src instead of zA in zF calculation
  579.        res = zA - (val + (zF & CZ80_CF));
  580.        zF = SZXY[res & 0xFF] |                             // S/Z/X/Y flag
  581.            ((zA ^ res ^ val) & CZ80_HF) |                  // H flag
  582.            (((val ^ zA) & (zA ^ res) & 0x80) >> 5) |       // V flag
  583.            ((res >> 8) & CZ80_CF) | CZ80_NF;               // C/N flag
  584.        zA = res;
  585.        RET(4)
  586.  
  587.    // CP
  588.  
  589. OP_CP_mIx:
  590.        PRE_IO
  591.        READ_BYTE(data->W + FETCH_BYTE_S, val)
  592.        POST_IO
  593.        CCnt -= 11;
  594.        goto OP_CP;
  595.  
  596.    OP(0xfe):   // CP   n
  597. OP_CP_imm:
  598.        val = FETCH_BYTE;
  599.        CCnt -= 3;
  600.        goto OP_CP;
  601.  
  602.    OP(0xbe):   // CP   (HL)
  603. /* OP_CP_mHL: */
  604.        PRE_IO
  605.        READ_BYTE(zHL, val)
  606.        POST_IO
  607.        CCnt -= 3;
  608.        goto OP_CP;
  609.  
  610. OP_CP_IxH:
  611.        val = data->B.H;
  612.        goto OP_CP;
  613.  
  614. OP_CP_IxL:
  615.        val = data->B.L;
  616.        goto OP_CP;
  617.  
  618.    OP(0xb8):   // CP   B
  619.    OP(0xb9):   // CP   C
  620.    OP(0xba):   // CP   D
  621.    OP(0xbb):   // CP   E
  622.    OP(0xbc):   // CP   H
  623.    OP(0xbd):   // CP   L
  624.    OP(0xbf):   // CP   A
  625. OP_CP_R:
  626.        val = zR8(Opcode & 7);
  627.  
  628. OP_CP:
  629. // bench : maybe use src instead of zA in zF calculation
  630.        res = zA - val;
  631. #if CZ80_DEBUG
  632.        zF = SZXY[res & 0xFF] |                             // S/Z/X/Y flag
  633.            ((zA ^ res ^ val) & CZ80_HF) |                  // H flag
  634.            (((val ^ zA) & (zA ^ res) & 0x80) >> 5) |       // V flag
  635.            ((res >> 8) & CZ80_CF) | CZ80_NF;               // C/N flag
  636. #else
  637.        zF = (SZXY[res & 0xFF] & ~(CZ80_XF | CZ80_YF)) |    // S/Z flag
  638.            (val & (CZ80_XF | CZ80_YF)) |                   // X/Y flag
  639.            ((zA ^ res ^ val) & CZ80_HF) |                  // H flag
  640.            (((val ^ zA) & (zA ^ res) & 0x80) >> 5) |       // V flag
  641.            ((res >> 8) & CZ80_CF) | CZ80_NF;               // C/N flag
  642. #endif
  643.        RET(4)
  644.    }
  645.    
  646.    // AND
  647.  
  648.    {
  649.        uint8_t val;
  650.  
  651.    OP(0xa6):   // AND  (HL)
  652. /* OP_AND_mHL: */
  653.        PRE_IO
  654.        READ_BYTE(zHL, val)
  655.        POST_IO
  656.        goto OP_AND_;
  657.  
  658.    OP(0xe6):   // AND  A,n
  659. OP_AND_imm:
  660.        val = FETCH_BYTE;
  661.  
  662. OP_AND_:
  663.        zA = zA & val;
  664.        zF = SZXYP[zA] | CZ80_HF;
  665.        RET(7)
  666.  
  667. OP_AND_IxL:
  668.        val = data->B.L;
  669.        goto OP_AND;
  670.  
  671. OP_AND_IxH:
  672.        val = data->B.H;
  673.        goto OP_AND;
  674.  
  675.    OP(0xa0):   // AND  B
  676.    OP(0xa1):   // AND  C
  677.    OP(0xa2):   // AND  D
  678.    OP(0xa3):   // AND  E
  679.    OP(0xa4):   // AND  H
  680.    OP(0xa5):   // AND  L
  681. OP_AND_R:
  682.        val = zR8(Opcode & 7);
  683.  
  684. OP_AND:
  685.        zA = zA & val;
  686.        
  687.    OP(0xa7):   // AND  A
  688. OP_AND_A:
  689.        zF = SZXYP[zA] | CZ80_HF;
  690.        RET(4)
  691.  
  692.    // XOR
  693.  
  694.    OP(0xae):   // XOR  (HL)
  695. /* OP_XOR_mHL: */
  696.        PRE_IO
  697.        READ_BYTE(zHL, val)
  698.        POST_IO
  699.        goto OP_XOR_;
  700.  
  701.    OP(0xee):   // XOR  A,n
  702. OP_XOR_imm:
  703.        val = FETCH_BYTE;
  704.        
  705. OP_XOR_:
  706.        zA = zA ^ val;
  707.        zF = SZXYP[zA];
  708.        RET(7)
  709.  
  710. OP_XOR_IxL:
  711.        val = data->B.L;
  712.        goto OP_XOR;
  713.  
  714. OP_XOR_IxH:
  715.        val = data->B.H;
  716.        goto OP_XOR;
  717.  
  718.    OP(0xa8):   // XOR  B
  719.    OP(0xa9):   // XOR  C
  720.    OP(0xaa):   // XOR  D
  721.    OP(0xab):   // XOR  E
  722.    OP(0xac):   // XOR  H
  723.    OP(0xad):   // XOR  L
  724. OP_XOR_R:
  725.        val = zR8(Opcode & 7);
  726.  
  727. OP_XOR:
  728.        zA = zA ^ val;
  729.        zF = SZXYP[zA];
  730.        RET(4)
  731.  
  732.    OP(0xaf):   // XOR  A
  733. OP_XOR_A:
  734.        zA = 0;
  735.        zF = SZXYP[zA];
  736.        RET(4)
  737.        
  738.    // OR
  739.  
  740.    OP(0xb6):   // OR   (HL)
  741. /* OP_OR_mHL: */
  742.        PRE_IO
  743.        READ_BYTE(zHL, val)
  744.        POST_IO
  745.        goto OP_OR_;
  746.    
  747.    OP(0xf6):   // OR   A,n
  748. OP_OR_imm:
  749.        val = FETCH_BYTE;
  750.  
  751. OP_OR_:
  752.        zA = zA | val;
  753.        zF = SZXYP[zA];
  754.        RET(7)
  755.  
  756. OP_OR_IxL:
  757.        val = data->B.L;
  758.        goto OP_OR;
  759.  
  760. OP_OR_IxH:
  761.        val = data->B.H;
  762.        goto OP_OR;
  763.  
  764.    OP(0xb0):   // OR   B
  765.    OP(0xb1):   // OR   C
  766.    OP(0xb2):   // OR   D
  767.    OP(0xb3):   // OR   E
  768.    OP(0xb4):   // OR   H
  769.    OP(0xb5):   // OR   L
  770. OP_OR_R:
  771.        val = zR8(Opcode & 7);
  772.  
  773. OP_OR:
  774.        zA = zA | val;
  775.  
  776.    OP(0xb7):   // OR   A
  777. OP_OR_A:
  778.        zF = SZXYP[zA];
  779.        RET(4)
  780.    }
  781.  
  782.  
  783.    // MISC ARITHMETIC & CPU CONTROL
  784.  
  785.    OP(0x27):   // DAA
  786. OP_DAA:
  787.    {
  788.        uint8_t _F;
  789.        uint8_t cf, nf, hf, lo, hi, diff;
  790.        
  791.        _F = zF;
  792.        cf = _F & CZ80_CF;
  793.        nf = _F & CZ80_NF;
  794.        hf = _F & CZ80_HF;
  795.        lo = zA & 0x0F;
  796.        hi = zA >> 4;
  797.  
  798.        if (cf)
  799.        {
  800.            diff = (lo <= 9 && !hf) ? 0x60 : 0x66;
  801.        }
  802.        else
  803.        {
  804.            if (lo >= 10)
  805.            {
  806.                diff = hi <= 8 ? 0x06 : 0x66;
  807.            }
  808.            else
  809.            {
  810.                if (hi >= 10)
  811.                {
  812.                    diff = hf ? 0x66 : 0x60;
  813.                }
  814.                else
  815.                {
  816.                    diff = hf ? 0x06 : 0x00;
  817.                }
  818.            }
  819.        }
  820.        if (nf) zA -= diff;
  821.        else zA += diff;
  822.  
  823.        _F = SZXYP[zA] | (_F & CZ80_NF);
  824.        if (cf || (lo <= 9 ? hi >= 10 : hi >= 9)) _F |= CZ80_CF;
  825.        if (nf ? hf && lo <= 5 : lo >= 10) _F |= CZ80_HF;
  826.        zF = _F;
  827.        RET(4)
  828.    }
  829.  
  830.    OP(0x2f):   // CPL
  831. OP_CPL:
  832.        zA ^= 0xFF;
  833.        zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF | CZ80_CF)) |
  834.            CZ80_HF | CZ80_NF |
  835.            (zA & (CZ80_XF | CZ80_YF));
  836.        RET(4)
  837.  
  838.    OP(0x37):   // SCF
  839. OP_SCF:
  840.        zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF)) |
  841.            (zA & (CZ80_XF | CZ80_YF)) |
  842.            CZ80_CF;
  843.        RET(4)
  844.  
  845.    OP(0x3f):   // CCF
  846. OP_CCF:
  847.        zF = ((zF & (CZ80_SF | CZ80_ZF | CZ80_PF | CZ80_CF)) |
  848.            ((zF & CZ80_CF) << 4) |
  849.            (zA & (CZ80_XF | CZ80_YF))) ^
  850.            CZ80_CF;
  851.        RET(4)
  852.  
  853.    OP(0x76):   // HALT
  854. OP_HALT:
  855.        // HALTED state
  856.        CPU->Status |= CZ80_HALTED;
  857.        // release remaining cycles...
  858.        CCnt = 0;
  859.        goto Cz80_Exec_Really_End;
  860.  
  861.    OP(0xf3):   // DI
  862. OP_DI:
  863.        zIFF = 0;
  864. #if CZ80_DEBUG
  865.        RET(4)
  866. #else
  867.        CCnt -= 4;
  868.        // can't take interrupt after DI so we force next instruction execution
  869.         goto Cz80_Exec;
  870. #endif
  871.  
  872.     OP(0xfb):   // EI
  873.     OP_EI:
  874.         zIFF = CZ80_IFF | (CZ80_IFF << 8);
  875. #if CZ80_DEBUG
  876.         RET(4)
  877. #else
  878.         // release remaining cycles...
  879.         CPU->CycleSup += CCnt - 4;
  880.         CCnt = 0;
  881.         // can't take interrupt after EI so we force next instruction execution
  882.        goto Cz80_Exec;
  883. #endif
  884.  
  885.    // 16 BITS ARITHMETIC
  886.  
  887.    OP(0x03):   // INC  BC
  888. OP_INC_BC:
  889.        zBC++;
  890.        RET(6)
  891.        
  892.    OP(0x13):   // INC  DE
  893. OP_INC_DE:
  894.        zDE++;
  895.        RET(6)
  896.        
  897.    OP(0x23):   // INC  HL
  898. OP_INC_xx:
  899.        data->W++;
  900.        RET(6)
  901.  
  902.    OP(0x33):   // INC  SP
  903. OP_INC_SP:
  904.        zSP++;
  905.        RET(6)
  906.  
  907.    OP(0x0b):   // DEC  BC
  908. OP_DEC_BC:
  909.        zBC--;
  910.        RET(6)
  911.  
  912.    OP(0x1b):   // DEC  DE
  913. OP_DEC_DE:
  914.        zDE--;
  915.        RET(6)
  916.  
  917.    OP(0x2b):   // DEC  HL
  918. OP_DEC_xx:
  919.        data->W--;
  920.        RET(6)
  921.  
  922.    OP(0x3b):   // DEC  SP
  923. OP_DEC_SP:
  924.        zSP--;
  925.        RET(6)
  926.  
  927.    // ADD16
  928.  
  929.    {
  930.        uint16_t src;
  931.        uint32_t res;
  932.  
  933.    OP(0x39):   // ADD  xx,SP
  934. OP_ADD16_xx_SP:
  935.        src = zSP;
  936.        goto OP_ADD16;
  937.  
  938.    OP(0x29):   // ADD  xx,xx
  939. OP_ADD16_xx_xx:
  940.        src = data->W;
  941.        goto OP_ADD16;
  942.  
  943.    OP(0x09):   // ADD  xx,BC
  944. OP_ADD16_xx_BC:
  945.        src = zBC;
  946.        goto OP_ADD16;
  947.  
  948.    OP(0x19):   // ADD  xx,DE
  949. OP_ADD16_xx_DE:
  950.        src = zDE;
  951.  
  952. OP_ADD16:
  953.        res = src + data->W;
  954. #if CZ80_DEBUG
  955.        zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_VF)) |     // S/Z/V flag
  956.            (((src ^ data->W ^ res) >> 8) & CZ80_HF) |  // H flag
  957.            ((res >> 16) & CZ80_CF);                    // C flag
  958. #else
  959.        zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_VF)) |     // S/Z/V flag
  960.            (((src ^ data->W ^ res) >> 8) & CZ80_HF) |  // H flag
  961.            ((res >> 8) & (CZ80_XF | CZ80_YF)) |        // X/Y flag
  962.            ((res >> 16) & CZ80_CF);                    // C flag
  963. #endif
  964.        data->W = res;
  965.        RET(11)
  966.    }
  967.  
  968.    // ROTATE
  969.  
  970.    {
  971.        uint8_t A;
  972.        uint8_t F;
  973.        
  974.    OP(0x07):   // RLCA
  975. OP_RLCA:
  976.        A = zA;
  977.        zA = (A << 1) | (A >> 7);
  978.        zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF)) |     // S/Z/P flag
  979.            (zA & (CZ80_XF | CZ80_YF | CZ80_CF));       // X/Y/C
  980.        RET(4)
  981.  
  982.    OP(0x0f):   // RRCA
  983. OP_RRCA:
  984.        A = zA;
  985.        zA = (A >> 1) | (A << 7);
  986.        zF = (zF & (CZ80_SF | CZ80_ZF | CZ80_PF)) |     // S/Z/P flag
  987.            (zA & (CZ80_XF | CZ80_YF)) |                // X/Y flag
  988.            (A & CZ80_CF);                              // C flag
  989.        RET(4)
  990.  
  991.    OP(0x17):   // RLA
  992. OP_RLA:
  993.        A = zA;
  994.        F = zF;
  995.        zA = (A << 1) | (F & CZ80_CF);
  996.        zF = (F & (CZ80_SF | CZ80_ZF | CZ80_PF)) |      // S/Z/P flag
  997.            (zA & (CZ80_XF | CZ80_YF)) |                // X/Y flag
  998.            (A >> 7);                                   // C flag
  999.        RET(4)
  1000.  
  1001.    OP(0x1f):   // RRA
  1002. OP_RRA:
  1003.        A = zA;
  1004.        F = zF;
  1005.        zA = (A >> 1) | (F << 7);
  1006.        zF = (F & (CZ80_SF | CZ80_ZF | CZ80_PF)) |      // S/Z/P flag
  1007.            (zA & (CZ80_XF | CZ80_YF)) |                // X/Y flag
  1008.            (A & CZ80_CF);                              // C flag
  1009.        RET(4)
  1010.    }
  1011.  
  1012.    // JUMP
  1013.  
  1014.    OP(0xd2):   // JP   NC,nn
  1015. OP_JP_NC:
  1016.        if (!(zF & CZ80_CF)) goto OP_JP;
  1017.        PC += 2;
  1018.        RET(10);
  1019.  
  1020.    OP(0xda):   // JP   C,nn
  1021. OP_JP_C:
  1022.        if (zF & CZ80_CF) goto OP_JP;
  1023.        PC += 2;
  1024.        RET(10);
  1025.  
  1026.    OP(0xe2):   // JP   PO,nn
  1027. OP_JP_PO:
  1028.        if (!(zF & CZ80_VF)) goto OP_JP;
  1029.        PC += 2;
  1030.        RET(10);
  1031.  
  1032.    OP(0xea):   // JP   PE,nn
  1033. OP_JP_PE:
  1034.        if (zF & CZ80_VF) goto OP_JP;
  1035.        PC += 2;
  1036.        RET(10);
  1037.  
  1038.    OP(0xf2):   // JP   P,nn
  1039. OP_JP_P:
  1040.        if (!(zF & CZ80_SF)) goto OP_JP;
  1041.        PC += 2;
  1042.        RET(10);
  1043.  
  1044.    OP(0xfa):   // JP   M,nn
  1045. OP_JP_M:
  1046.        if (zF & CZ80_SF) goto OP_JP;
  1047.        PC += 2;
  1048.        RET(10);
  1049.  
  1050.    OP(0xca):   // JP   Z,nn
  1051. OP_JP_Z:
  1052.        if (zF & CZ80_ZF) goto OP_JP;
  1053.        PC += 2;
  1054.        RET(10);
  1055.  
  1056.    OP(0xc2):   // JP   NZ,nn
  1057. OP_JP_NZ:
  1058.        if (!(zF & CZ80_ZF)) goto OP_JP;
  1059.        PC += 2;
  1060.        RET(10);
  1061.  
  1062.    {
  1063.        uint16_t newPC;
  1064.  
  1065.    OP(0xc3):   // JP   nn
  1066. OP_JP:
  1067.        newPC = GET_WORD;
  1068.        SET_PC(newPC);
  1069.        RET(10)
  1070.  
  1071.    OP(0xe9):   // JP   (xx)
  1072. OP_JP_xx:
  1073.        newPC = data->W;
  1074.        SET_PC(newPC);
  1075.        RET(4)
  1076.    }
  1077.  
  1078.    
  1079.    OP(0x38):   // JR   C,n
  1080. OP_JR_C:
  1081.        if (zF & CZ80_CF) goto OP_JR;
  1082.        PC++;
  1083.        RET(7)
  1084.  
  1085.    OP(0x30):   // JR   NC,n
  1086. OP_JR_NC:
  1087.        if (!(zF & CZ80_CF)) goto OP_JR;
  1088.        PC++;
  1089.        RET(7)
  1090.  
  1091.    OP(0x28):   // JR   Z,n
  1092. OP_JR_Z:
  1093.        if (zF & CZ80_ZF) goto OP_JR;
  1094.        PC++;
  1095.        RET(7)
  1096.  
  1097.    OP(0x20):   // JR   NZ,n
  1098. OP_JR_NZ:
  1099.        if (!(zF & CZ80_ZF)) goto OP_JR;
  1100.        PC++;
  1101.        RET(7)
  1102.  
  1103.    OP(0x10):   // DJNZ n
  1104. OP_DJNZ:
  1105.        CCnt--;
  1106.        if (--zB) goto OP_JR;
  1107.        PC++;
  1108.        RET(9)
  1109.  
  1110.    OP(0x18):   // JR   n
  1111. OP_JR:
  1112.    {
  1113.        uintptr_t adr;
  1114.  
  1115.        adr = FETCH_BYTE_S;
  1116.        // no rebase needed here...
  1117.        PC += adr;
  1118.        RET(12)
  1119.    }
  1120.  
  1121.    // CALL & RETURN
  1122.  
  1123.    OP(0xd4):   // CALL NC,nn
  1124. OP_CALL_NC:
  1125.        if (!(zF & CZ80_CF)) goto OP_CALL;
  1126.        PC += 2;
  1127.        RET(10)
  1128.  
  1129.    OP(0xdc):   // CALL C,nn
  1130. OP_CALL_C:
  1131.        if (zF & CZ80_CF) goto OP_CALL;
  1132.        PC += 2;
  1133.        RET(10)
  1134.  
  1135.    OP(0xe4):   // CALL PO,nn
  1136. OP_CALL_PO:
  1137.        if (!(zF & CZ80_VF)) goto OP_CALL;
  1138.        PC += 2;
  1139.        RET(10)
  1140.  
  1141.    OP(0xec):   // CALL PE,nn
  1142. OP_CALL_PE:
  1143.        if (zF & CZ80_VF) goto OP_CALL;
  1144.        PC += 2;
  1145.        RET(10)
  1146.  
  1147.    OP(0xf4):   // CALL P,nn
  1148. OP_CALL_P:
  1149.        if (!(zF & CZ80_SF)) goto OP_CALL;
  1150.        PC += 2;
  1151.        RET(10)
  1152.  
  1153.    OP(0xfc):   // CALL M,nn
  1154. OP_CALL_M:
  1155.        if (zF & CZ80_SF) goto OP_CALL;
  1156.        PC += 2;
  1157.        RET(10)
  1158.  
  1159.    OP(0xcc):   // CALL Z,nn
  1160. OP_CALL_Z:
  1161.        if (zF & CZ80_ZF) goto OP_CALL;
  1162.        PC += 2;
  1163.        RET(10)
  1164.  
  1165.    OP(0xc4):   // CALL NZ,nn
  1166. OP_CALL_NZ:
  1167.        if (!(zF & CZ80_ZF)) goto OP_CALL;
  1168.        PC += 2;
  1169.        RET(10)
  1170.  
  1171.    OP(0xcd):   // CALL nn
  1172. OP_CALL:
  1173.    {
  1174.        uint16_t oldRPC;
  1175.        uint16_t newPC;
  1176.  
  1177.        PRE_IO
  1178.        FETCH_WORD(newPC);
  1179.        oldRPC = PC;
  1180.        PUSH_16(oldRPC);
  1181.        SET_PC(newPC);
  1182.        POST_IO
  1183.        RET(17)
  1184.    }
  1185.  
  1186.    OP(0xd0):   // RET  NC
  1187. OP_RET_NC:
  1188.        if (!(zF & CZ80_CF)) goto OP_RET_COND;
  1189.        RET(5)
  1190.  
  1191.    OP(0xd8):   // RET  C
  1192. OP_RET_C:
  1193.        if (zF & CZ80_CF) goto OP_RET_COND;
  1194.        RET(5)
  1195.  
  1196.    OP(0xe0):   // RET  PO
  1197. OP_RET_PO:
  1198.        if (!(zF & CZ80_VF)) goto OP_RET_COND;
  1199.        RET(5)
  1200.  
  1201.    OP(0xe8):   // RET  PE
  1202. OP_RET_PE:
  1203.        if (zF & CZ80_VF) goto OP_RET_COND;
  1204.        RET(5)
  1205.  
  1206.    OP(0xf0):   // RET  P
  1207. OP_RET_P:
  1208.        if (!(zF & CZ80_SF)) goto OP_RET_COND;
  1209.        RET(5)
  1210.  
  1211.    OP(0xf8):   // RET  M
  1212. OP_RET_M:
  1213.        if (zF & CZ80_SF) goto OP_RET_COND;
  1214.        RET(5)
  1215.  
  1216.    OP(0xc0):   // RET  NZ
  1217. OP_RET_NZ:
  1218.        if (!(zF & CZ80_ZF)) goto OP_RET_COND;
  1219.        RET(5)
  1220.  
  1221.    OP(0xc8):   // RET  Z
  1222. OP_RET_Z:
  1223.        if (zF & CZ80_ZF) goto OP_RET_COND;
  1224.        RET(5)
  1225.  
  1226. OP_RET_COND:
  1227.        CCnt -= 7;
  1228.  
  1229.    OP(0xc9):   // RET
  1230. OP_RET:
  1231.    {
  1232.        uint16_t newPC;
  1233.  
  1234.        PRE_IO
  1235.        POP_16(newPC);
  1236.        SET_PC(newPC);
  1237.        POST_IO
  1238.        RET(10)
  1239.    }
  1240.  
  1241.  
  1242.    OP(0xc7):   // RST  0
  1243.    OP(0xcf):   // RST  1
  1244.    OP(0xd7):   // RST  2
  1245.    OP(0xdf):   // RST  3
  1246.    OP(0xe7):   // RST  4
  1247.    OP(0xef):   // RST  5
  1248.    OP(0xf7):   // RST  6
  1249.    OP(0xff):   // RST  7
  1250. OP_RST:
  1251.    {
  1252.        uint16_t src;
  1253.        uint16_t newPC;
  1254.  
  1255.        src = PC;
  1256.        PUSH_16(src);
  1257.        newPC = Opcode & 0x38;
  1258.        SET_PC(newPC);
  1259.        RET(11)
  1260.    }
  1261.  
  1262.    // INPUT & OUTPUT
  1263.  
  1264.    {
  1265.        uint16_t adr;
  1266.        
  1267.    OP(0xd3):   // OUT  (n),A
  1268. OP_OUT_mN_A:
  1269.        adr = (zA << 8) | FETCH_BYTE;
  1270.        OUT(adr, zA)
  1271.        RET(11)
  1272.  
  1273.    OP(0xdb):   // IN   A,(n)
  1274. OP_IN_A_mN:
  1275.        adr = (zA << 8) | FETCH_BYTE;
  1276.        IN(adr, zA)
  1277.        RET(11)
  1278.    }
  1279.    
  1280.    // PREFIXE
  1281.    
  1282.    OP(0xcb):   // CB PREFIXE (BIT & SHIFT INSTRUCTIONS)
  1283. /* CB_PREFIXE: */
  1284.        Opcode = FETCH_BYTE;
  1285.        #include "cz80_opcb.inc"
  1286.  
  1287.    OP(0xed):   // ED PREFIXE
  1288. ED_PREFIXE:
  1289.        CCnt -= 4;
  1290.        Opcode = FETCH_BYTE;
  1291.        #include "cz80_oped.inc"
  1292.  
  1293.    OP(0xdd):   // DD PREFIXE (IX)
  1294. DD_PREFIXE:
  1295.        data = pzIX;
  1296.        goto XY_PREFIXE;
  1297.  
  1298.    OP(0xfd):   // FD PREFIXE (IY)
  1299. FD_PREFIXE:
  1300.        data = pzIY;
  1301.        
  1302. XY_PREFIXE:
  1303.        CCnt -= 4;
  1304.        Opcode = FETCH_BYTE;
  1305.        #include "cz80_opxy.inc"
  1306.  
  1307. #if CZ80_USE_JUMPTABLE
  1308. #else
  1309. }
  1310. #endif
  1311.  
  1312.