Subversion Repositories Kolibri OS

Rev

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

  1. /*====================================================================/*
  2.   opcodes_ed.c -> This file executes the ED opcodes.
  3.  
  4.   Another prefix that "creates" new instructions. This prefix also
  5.   introduces some undocumented opcodes that we've tried to include
  6.   here. Maybe their implementation it's wrong: if you can find any
  7.   mistake about how we have implemented/interpreted them, please
  8.   let us know.
  9.  
  10.  This program is free software; you can redistribute it and/or modify
  11.  it under the terms of the GNU General Public License as published by
  12.  the Free Software Foundation; either version 2 of the License, or
  13.  (at your option) any later version.
  14.  
  15.  This program is distributed in the hope that it will be useful,
  16.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  GNU General Public License for more details.
  19.  
  20.  You should have received a copy of the GNU General Public License
  21.  along with this program; if not, write to the Free Software
  22.  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24.  Copyright (c) 2000 Santiago Romero Iglesias.
  25.  Email: sromero@escomposlinux.org
  26.  =====================================================================*/
  27.  
  28. /* 8 clock cycles minimum = ED opcode = 4 + 4 */
  29.  
  30. opcode = Z80ReadMem( r_PC );
  31. r_PC++;
  32.  
  33. switch(opcode)
  34. {
  35.   case  LD_BC_xNNe  :  LOAD_rr_nn(r_BC); AddCycles( 4+4+12 ); break;
  36.   case  LD_DE_xNNe  :  LOAD_rr_nn(r_DE); AddCycles( 4+4+12 ); break;
  37.   case  LD_HL_xNNe  :  LOAD_rr_nn(r_HL); AddCycles( 4+4+12 ); break;
  38.   case  LD_SP_xNNe  :  LOAD_rr_nn(r_SP); AddCycles( 4+4+12 ); break;
  39.  
  40.   case  LD_xNNe_BC  :  STORE_nn_rr(r_BC); AddCycles( 4+4+12 ); break;
  41.   case  LD_xNNe_DE  :  STORE_nn_rr(r_DE); AddCycles( 4+4+12 ); break;
  42.   case  LD_xNNe_HL  :  STORE_nn_rr(r_HL); AddCycles( 4+4+12 ); break;
  43.   case  LD_xNNe_SP  :  STORE_nn_rr(r_SP); AddCycles( 4+4+12 ); break;
  44.  
  45.   case  NEG         :
  46.   case  ED_5C       :
  47.   case  ED_74       :
  48.   case  ED_7C       :
  49.   case  ED_6C       :
  50.   case  ED_54       :
  51.   case  ED_4C       :
  52.   case  ED_64       :  NEG_A(); AddCycles( 4+4 ); break;
  53.  
  54.   case  RETI        :
  55.   case  RETN        :
  56.   case  ED_65       :
  57.   case  ED_6D       :
  58.   case  ED_75       :
  59.   case  ED_7D       :
  60.   case  ED_5D       :
  61.   case  ED_55       :
  62.                        r_IFF1 = r_IFF2;
  63.                        RET_nn();
  64.                        AddCycles( 4+4+6 ); break;
  65.  
  66.   case  IM_0        :
  67.   case  ED_4E       :                               /* * IM 0/1 */
  68.   case  ED_6E       :
  69.   case  ED_66       :  regs->IM = 0;
  70.                        AddCycles( 4+4 ); break;     /* * IM 0 */
  71.  
  72.  
  73.   case  IM_1        :
  74.   case  ED_76       :  regs->IM = 1;
  75.                        AddCycles( 4+4 ); break;
  76.  
  77.   case  IM_2        :
  78.   case  ED_7E       :  regs->IM = 2;
  79.                        AddCycles( 4+4 ); break;
  80.  
  81.   case  ED_77       :
  82.   case  ED_7F       :  AddCycles( 4+4 ); break;     /* * NOP */
  83.  
  84.   case  OUT_xC_B    :  Z80OutPort(regs,r_BC, r_B); AddCycles( 4+4+4 ); break;
  85.   case  OUT_xC_C    :  Z80OutPort(regs,r_BC, r_C); AddCycles( 4+4+4 ); break;
  86.   case  OUT_xC_D    :  Z80OutPort(regs,r_BC, r_D); AddCycles( 4+4+4 ); break;
  87.   case  OUT_xC_E    :  Z80OutPort(regs,r_BC, r_E); AddCycles( 4+4+4 ); break;
  88.   case  OUT_xC_H    :  Z80OutPort(regs,r_BC, r_H); AddCycles( 4+4+4 ); break;
  89.   case  OUT_xC_L    :  Z80OutPort(regs,r_BC, r_L); AddCycles( 4+4+4 ); break;
  90.   case  OUT_xC_A    :  Z80OutPort(regs,r_BC, r_A); AddCycles( 4+4+4 ); break;
  91.   /* * OUT (C), 0 */
  92.   case  ED_71       :  Z80OutPort(regs,r_BC, 0);  AddCycles( 4+4+4 ); break;
  93.  
  94.   case  IN_B_xC     :  IN(r_B, r_BC); AddCycles( 4+4+4 ); break;
  95.   case  IN_C_xC     :  IN(r_C, r_BC); AddCycles( 4+4+4 ); break;
  96.   case  IN_D_xC     :  IN(r_D, r_BC); AddCycles( 4+4+4 ); break;
  97.   case  IN_E_xC     :  IN(r_E, r_BC); AddCycles( 4+4+4 ); break;
  98.   case  IN_L_xC     :  IN(r_L, r_BC); AddCycles( 4+4+4 ); break;
  99.   case  IN_H_xC     :  IN(r_H, r_BC); AddCycles( 4+4+4 ); break;
  100.   case  IN_A_xC     :  IN(r_A, r_BC); AddCycles( 4+4+4 ); break;
  101.   case  IN_F_xC     :  IN(r_meml, r_BC); AddCycles( 4+4+4 ); break;
  102.  
  103.   case  LD_A_I      :  r_A = regs->I;
  104.                        r_F = ( r_F & FLAG_C )|sz53_table[r_A]|
  105.                              ( regs->IFF2 ? FLAG_V:0 );
  106.                        AddCycles( 4+4+1 ); break;
  107.  
  108.   case  LD_I_A      :  regs->I = r_A; AddCycles( 4+4+1 ); break;
  109.  
  110.  
  111.   case  LD_A_R      :  r_A = ( regs->R.W & 0x7f ) | (regs->R.W & 0x80);
  112.                        r_F = (r_F&FLAG_C)|sz53_table[r_A] | (regs->IFF2?FLAG_V:0);
  113.                        AddCycles( 4+4+1 ); break;
  114.  
  115.   case  LD_R_A      :  regs->R.W = r_A;
  116.                        AddCycles( 4+4+1 ); break;
  117.  
  118.  
  119.   case  ADC_HL_BC   :  ADC_WORD(r_BC); AddCycles( 4+4+4+1+2 ); break;
  120.   case  ADC_HL_DE   :  ADC_WORD(r_DE); AddCycles( 4+4+4+1+2 ); break;
  121.   case  ADC_HL_HL   :  ADC_WORD(r_HL); AddCycles( 4+4+4+1+2 ); break;
  122.   case  ADC_HL_SP   :  ADC_WORD(r_SP); AddCycles( 4+4+4+1+2 ); break;
  123.  
  124.   case  SBC_HL_BC   :  SBC_WORD(r_BC); AddCycles( 4+4+4+1+2 ); break;
  125.   case  SBC_HL_DE   :  SBC_WORD(r_DE); AddCycles( 4+4+4+1+2 ); break;
  126.   case  SBC_HL_HL   :  SBC_WORD(r_HL); AddCycles( 4+4+4+1+2 ); break;
  127.   case  SBC_HL_SP   :  SBC_WORD(r_SP); AddCycles( 4+4+4+1+2 ); break;
  128.  
  129.   case  RRD         :  r_meml = Z80ReadMem(r_HL);
  130.                        Z80WriteMem(r_HL,  ( r_A << 4 ) | ( r_meml >> 4 ), regs );
  131.                        r_A = ( r_A & 0xf0 ) | ( r_meml & 0x0f );
  132.                        r_F = ( r_F & FLAG_C ) | sz53p_table[r_A];
  133.                        AddCycles( 4+4+10 ); break;
  134.  
  135.   case  RLD         :  r_meml = Z80ReadMem(r_HL);
  136.                        Z80WriteMem(r_HL, (r_meml << 4 ) | ( r_A & 0x0f ), regs );
  137.                        r_A = ( r_A & 0xf0 ) | ( r_meml >> 4 );
  138.                        r_F = ( r_F & FLAG_C ) | sz53p_table[r_A];
  139.                        AddCycles( 4+4+10 ); break;
  140.  
  141.   case  LDI         :  r_meml = Z80ReadMem(r_HL); r_HL++;
  142.                        Z80WriteMem( r_DE, r_meml, regs ); r_DE++;
  143.                        r_BC--; r_meml += r_A;
  144.                        r_F = ( r_F & ( FLAG_C|FLAG_Z|FLAG_S ) ) |
  145.                        ( r_BC ? FLAG_V:0 ) | ( r_meml & FLAG_3 ) |
  146.                        ((r_meml & 0x02) ? FLAG_5 : 0 );
  147.                        AddCycles( 4+4+4+4 ); break;
  148.  
  149.   case  LDIR        :  r_meml = Z80ReadMem(r_HL); r_HL++;
  150.                        Z80WriteMem( r_DE, r_meml, regs ); r_DE++;
  151.                        r_BC--; r_meml += r_A;
  152.                        r_F = ( r_F & ( FLAG_C|FLAG_Z|FLAG_S ) ) |
  153.                        ( r_BC ? FLAG_V:0 ) | ( r_meml & FLAG_3 ) |
  154.                        ((r_meml & 0x02) ? FLAG_5 : 0 );
  155.                        AddCycles( 4+4+4+4 );
  156.                        if( r_BC ) { r_PC-=2; AddCycles(5); }
  157.                        break;
  158.  
  159.   case  LDD         :  r_meml = Z80ReadMem(r_HL); r_HL--;
  160.                        Z80WriteMem( r_DE, r_meml, regs ); r_DE--;
  161.                        r_BC--; r_meml += r_A;
  162.                        r_F = ( r_F & ( FLAG_C | FLAG_Z | FLAG_S ) ) |
  163.                        (r_BC ? FLAG_V : 0 ) | ( r_meml & FLAG_3 ) |
  164.                        ((r_meml & 0x02) ? FLAG_5 : 0 );
  165.                        AddCycles( 4+4+4+4 ); break;
  166.  
  167.  
  168.   case  LDDR        :  r_meml = Z80ReadMem(r_HL);
  169.                        Z80WriteMem( r_DE, r_meml, regs );
  170.                        r_HL--; r_DE--; r_BC--; r_meml += r_A;
  171.                        r_F = ( r_F & ( FLAG_C | FLAG_Z | FLAG_S ) ) |
  172.                        (r_BC ? FLAG_V : 0 ) | ( r_meml & FLAG_3 ) |
  173.                        ((r_meml & 0x02) ? FLAG_5 : 0 );
  174.                        AddCycles( 4+4+4+4+1 );
  175.                        if( r_BC ) { r_PC-=2; AddCycles(4); }
  176.                        break;
  177.  
  178.   // I had lots of problems with CPI, INI, CPD, IND, OUTI, OUTD and so...
  179.   // Thanks a lot to Philip Kendall for letting me to take a look to his
  180.   // fuse emulator and allowing me to use their flag routines :-)
  181.   case CPI          :  r_meml = Z80ReadMem(r_HL);
  182.                        r_memh = r_A - r_meml;
  183.                        r_opl = ( (r_A & 0x08) >> 3 ) |
  184.                                ( ( (r_meml) & 0x08 ) >> 2 ) |
  185.                                ( (r_meml & 0x08) >> 1 );
  186.                                r_HL++; r_BC--;
  187.                        r_F = ( r_F & FLAG_C ) |
  188.                              ( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
  189.                              halfcarry_sub_table[r_opl] |
  190.                              ( r_memh ? 0 : FLAG_Z ) |
  191.                              ( r_memh & FLAG_S );
  192.                              if( r_F & FLAG_H) r_memh--;
  193.                              r_F |= ( r_memh & FLAG_3 ) |
  194.                                     ( (r_memh&0x02) ? FLAG_5 : 0 );
  195.                        AddCycles( 4+4+4+4); break;
  196.  
  197.   case CPIR         :  r_meml = Z80ReadMem(r_HL);
  198.                        r_memh = r_A - r_meml;
  199.                        r_opl = ( (r_A & 0x08) >> 3 ) |
  200.                                ( ( (r_meml) & 0x08 ) >> 2 ) |
  201.                                ( (r_meml & 0x08) >> 1 );
  202.                                r_HL++; r_BC--;
  203.                        r_F = ( r_F & FLAG_C ) |
  204.                              ( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
  205.                              halfcarry_sub_table[r_opl] |
  206.                              ( r_memh ? 0 : FLAG_Z ) |
  207.                              ( r_memh & FLAG_S );
  208.                              if( r_F & FLAG_H) r_memh--;
  209.                              r_F |= ( r_memh & FLAG_3 ) |
  210.                                     ( (r_memh&0x02) ? FLAG_5 : 0 );
  211.                        if( ( r_F & ( FLAG_V | FLAG_Z ) ) == FLAG_V )
  212.                         { AddCycles(5); r_PC-=2; }
  213.                        AddCycles( 4+4+4+4); break;
  214.  
  215.   case  CPD         :  r_meml = Z80ReadMem(r_HL);
  216.                        r_memh = r_A-r_meml;
  217.                        r_opl = ( (r_A & 0x08) >> 3 ) |
  218.                                 ( ( (r_meml) & 0x08 ) >> 2 ) |
  219.                                 ( (r_memh & 0x08) >> 1 );
  220.                        r_HL--; r_BC--;
  221.                        r_F = ( r_F & FLAG_C ) |
  222.                               ( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
  223.                               halfcarry_sub_table[r_opl] |
  224.                               ( r_memh ? 0 : FLAG_Z ) |
  225.                               ( r_memh & FLAG_S );
  226.                        if(r_F & FLAG_H) r_memh--;
  227.                        r_F |= ( r_memh & FLAG_3 ) |
  228.                                ( (r_memh&0x02) ? FLAG_5 : 0 );
  229.                        AddCycles( 4+4+4+4); break;
  230.  
  231.   case  CPDR        :  r_meml = Z80ReadMem(r_HL);
  232.                        r_memh = r_A-r_meml;
  233.                        r_opl = ( (r_A & 0x08) >> 3 ) |
  234.                                 ( ( (r_meml) & 0x08 ) >> 2 ) |
  235.                                 ( (r_memh & 0x08) >> 1 );
  236.                        r_HL--; r_BC--;
  237.                        r_F = ( r_F & FLAG_C ) |
  238.                               ( r_BC ? ( FLAG_V | FLAG_N ) : FLAG_N ) |
  239.                               halfcarry_sub_table[r_opl] |
  240.                               ( r_memh ? 0 : FLAG_Z ) |
  241.                               ( r_memh & FLAG_S );
  242.                        if(r_F & FLAG_H) r_memh--;
  243.                        r_F |= ( r_memh & FLAG_3 ) |
  244.                                ( (r_memh&0x02) ? FLAG_5 : 0 );
  245.                        if( ( r_F & ( FLAG_V | FLAG_Z ) ) == FLAG_V )
  246.                         { AddCycles(5); r_PC-=2; }
  247.                        AddCycles( 4+4+4+4 ); break;
  248.  
  249. /*
  250.                        // OUTI contributed by Alvaro Alea
  251.   case OUTI :           Z80OutPort( regs, r_BC, Z80ReadMem( r_HL )) ;
  252.                         r_HL++ ; r_B-- ;
  253.                         if (r_B==0)
  254.                             r_F |= FLAG_Z;
  255.                         else
  256.                             r_F &= !FLAG_Z;
  257.                         r_F |= FLAG_N;
  258.                         AddCycles( 4+4+4+4 ); break;
  259. */
  260.                    
  261.   // I/O block instructions by Metalbrain - 14-5-2001
  262.   case  IND         :  r_meml = Z80InPort((r_BC)); r_memh=0;
  263.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  264.                        (r_B)--;
  265.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  266.                        r_F &= 0xE8;
  267.                        Z80WriteMem( r_HL, r_meml, regs );
  268.                        r_F |= ( (r_meml & 0x80 ) >> 6);
  269.                        r_opl = r_C; r_oph = 0;
  270.                        r_opl--;
  271.                        r_op += r_mem;
  272.                        r_oph += (r_oph << 4);
  273.                        r_F |= r_oph;
  274.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  275.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
  276.                        r_HL--;
  277.                        AddCycles( 4+4+4+4); break;
  278.  
  279.   case  INDR        :  r_meml = Z80InPort((r_BC)); r_memh=0;
  280.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  281.                        (r_B)--;
  282.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  283.                        r_F &= 0xE8;
  284.                        Z80WriteMem( r_HL, r_meml, regs );
  285.                        r_F |= ( (r_meml & 0x80 ) >> 6);
  286.                        r_opl = r_C; r_oph = 0;
  287.                        r_opl--;
  288.                        r_op += r_mem;
  289.                        r_oph += (r_oph << 4);
  290.                        r_F |= r_oph;
  291.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  292.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
  293.                        r_HL--;
  294.                        if( r_B ) { r_PC-=2; AddCycles(5); }
  295.                        AddCycles( 4+4+4+4); break;
  296.  
  297.   case  INI         :  r_meml = Z80InPort((r_BC)); r_memh=0;
  298.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  299.                        (r_B)--;
  300.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  301.                        r_F &= 0xE8;
  302.                        Z80WriteMem( r_HL, r_meml, regs );
  303.                        r_F |= ( (r_meml & 0x80 ) >> 6);
  304.                        r_opl = r_C; r_oph = 0;
  305.                        r_opl++;
  306.                        r_op += r_mem;
  307.                        r_oph += (r_oph << 4);
  308.                        r_F |= r_oph;
  309.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  310.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
  311.                        r_HL++;
  312.                        AddCycles( 4+4+4+4); break;
  313.  
  314.  
  315.   case  INIR        :  r_meml = Z80InPort((r_BC)); r_memh=0;
  316.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  317.                        (r_B)--;
  318.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  319.                        r_F &= 0xE8;
  320.                        Z80WriteMem( r_HL, r_meml, regs );
  321.                        r_F |= ( (r_meml & 0x80 ) >> 6);
  322.                        r_opl = r_C; r_oph = 0;
  323.                        r_opl++;
  324.                        r_op += r_mem;
  325.                        r_oph += (r_oph << 4);
  326.                        r_F |= r_oph;
  327.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  328.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
  329.                        r_HL++;
  330.                        if( r_B ) { r_PC-=2; AddCycles(5); }
  331.                        AddCycles( 4+4+4+4); break;
  332.  
  333.   case  OUTI        :  r_meml = Z80ReadMem(r_HL); r_memh = 0;
  334.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  335.                        (r_B)--;
  336.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  337.                        r_F &= 0xE8;
  338.                        Z80OutPort( regs, r_BC, r_meml);
  339.                        r_F |= ((r_meml & 0x80 ) >> 6);
  340.                        r_opl = r_C; r_oph=0;
  341.                        r_opl++;
  342.                        r_op += r_mem;
  343.                        r_oph += (r_oph<<4);
  344.                        r_F |= r_oph;
  345.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  346.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
  347.                        r_HL++;
  348.                        AddCycles( 4+4+4+4); break;
  349.  
  350.   case  OTIR        :  r_meml = Z80ReadMem(r_HL); r_memh = 0;
  351.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  352.                        (r_B)--;
  353.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  354.                        r_F &= 0xE8;
  355.                        Z80OutPort( regs, r_BC, r_meml);
  356.                        r_F |= ((r_meml & 0x80 ) >> 6);
  357.                        r_opl = r_C; r_oph=0;
  358.                        r_opl++;
  359.                        r_op += r_mem;
  360.                        r_oph += (r_oph<<4);
  361.                        r_F |= r_oph;
  362.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  363.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_inc1_table[(r_opl)] );
  364.                        r_HL++;
  365.                        if( r_B ) { r_PC-=2; AddCycles(5); }
  366.                        AddCycles( 4+4+4+4); break;
  367.  
  368.  
  369.   case  OUTD        :  r_meml = Z80ReadMem(r_HL); r_memh = 0;
  370.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  371.                        (r_B)--;
  372.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  373.                        r_F &= 0xE8;
  374.                        Z80OutPort( regs, r_BC, r_meml);
  375.                        r_F |= ((r_meml & 0x80 ) >> 6);
  376.                        r_opl = r_C; r_oph=0;
  377.                        r_opl--;
  378.                        r_op += r_mem;
  379.                        r_oph += (r_oph<<4);
  380.                        r_F |= r_oph;
  381.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  382.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
  383.                        r_HL--;
  384.                        AddCycles( 4+4+4+4); break;
  385.  
  386.   case  OTDR        :  r_meml = Z80ReadMem(r_HL); r_memh = 0;
  387.                        r_F = ( r_F & FLAG_C ) | ( (r_B)&0x0f ? 0 : FLAG_H ) | FLAG_N; \
  388.                        (r_B)--;
  389.                        r_F |= ( (r_B)==0x7f ? FLAG_V : 0 ) | sz53_table[(r_B)];
  390.                        r_F &= 0xE8;
  391.                        Z80OutPort( regs, r_BC, r_meml);
  392.                        r_F |= ((r_meml & 0x80 ) >> 6);
  393.                        r_opl = r_C; r_oph=0;
  394.                        r_opl--;
  395.                        r_op += r_mem;
  396.                        r_oph += (r_oph<<4);
  397.                        r_F |= r_oph;
  398.                        r_opl = (r_meml & 7) + ( (r_C & 7) << 3 );
  399.                        r_F |= ( ioblock_2_table[(r_B)] ^ ioblock_dec1_table[(r_opl)] );
  400.                        r_HL--;
  401.                        if( r_B ) { r_PC-=2; AddCycles(5); }
  402.                        AddCycles( 4+4+4+4); break;
  403.  
  404. // End of Metalbrain's contribution
  405.  
  406.   case PREFIX_ED:      AddCycles( 4 );     /* ED ED xx = 12 cycles min = 4+8 */
  407.                        r_PC-- ;
  408.                        break;
  409.  
  410.   default:
  411. // exit(1);
  412.      AddCycles( 4+4 );   /* Just a NOP */
  413. ///!!!    if(regs->DecodingErrors)
  414. ///!!!      printf( "z80 core: Unknown instruction: ED %02Xh at PC=%04Xh.\n",
  415. ///!!!               Z80ReadMem(r_PC-1),r_PC-2 );
  416.     break;
  417. }
  418.