// -*- C++ -*-
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005-2006 Forgotten and the VBA development team

// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

 case 0x00: 
   // NOP
   break;
 case 0x01: 
   // LD BC, NNNN
   BC.B.B0=gbReadOpcode(PC.W++);
   BC.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x02:
   // LD (BC),A
   gbWriteMemory(BC.W,AF.B.B1);
   break;
 case 0x03:
   // INC BC
   BC.W++;
   break;
 case 0x04: 
   // INC B
   BC.B.B1++; 
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B1]| (BC.B.B1&0x0F? 0:H_FLAG);
   break;
 case 0x05:
   // DEC B
   BC.B.B1--; 
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B1]|
     ((BC.B.B1&0x0F)==0x0F? H_FLAG:0);
   break;
 case 0x06:
   // LD B, NN
   BC.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x07:
   // RLCA
   tempValue=AF.B.B1&0x80? C_FLAG:0;
   AF.B.B1=(AF.B.B1<<1)|(AF.B.B1>>7);
   AF.B.B0=tempValue;
   break;
 case 0x08:
   // LD (NNNN), SP
   tempRegister.B.B0=gbReadOpcode(PC.W++);
   tempRegister.B.B1=gbReadOpcode(PC.W++);
   gbWriteMemory(tempRegister.W++,SP.B.B0);
   gbWriteMemory(tempRegister.W,SP.B.B1);
   break;
 case 0x09:
   // ADD HL,BC
   tempRegister.W=(HL.W+BC.W)&0xFFFF;
   AF.B.B0= (AF.B.B0 & Z_FLAG)| ((HL.W^BC.W^tempRegister.W)&0x1000? H_FLAG:0)|
     (((long)HL.W+(long)BC.W)&0x10000? C_FLAG:0);
   HL.W=tempRegister.W;
   break;
 case 0x0a:
   // LD A,(BC)
   AF.B.B1=gbReadMemory(BC.W);
   break;
 case 0x0b:
   // DEC BC
   BC.W--;
   break;   
 case 0x0c:
   // INC C
   BC.B.B0++;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B0]| (BC.B.B0&0x0F? 0:H_FLAG);
   break;
 case 0x0d:
   // DEC C
   BC.B.B0--;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[BC.B.B0]|
     ((BC.B.B0&0x0F)==0x0F? H_FLAG:0);
   break;   
 case 0x0e:
   // LD C, NN
   BC.B.B0=gbReadOpcode(PC.W++);
   break;
 case 0x0f:
   // RRCA
   tempValue=AF.B.B1&0x01;
   AF.B.B1=(AF.B.B1>>1)|(tempValue? 0x80:0);
   AF.B.B0=(tempValue<<4);
   break;
 case 0x10:
   // STOP
   opcode = gbReadOpcode(PC.W++);
   if(gbCgbMode) {
     if(gbMemory[0xff4d] & 1) {
         
       gbSpeedSwitch();
       //clockTicks += 228*144-(gbSpeed ? 62 : 63);
       
       if(gbSpeed == 0)
         gbMemory[0xff4d] = 0x00;
       else
         gbMemory[0xff4d] = 0x80;
     }
   }
   break;
 case 0x11:
   // LD DE, NNNN
   DE.B.B0=gbReadOpcode(PC.W++);
   DE.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x12:
   // LD (DE),A
   gbWriteMemory(DE.W,AF.B.B1);
   break;
 case 0x13:
   // INC DE
   DE.W++;
   break;
 case 0x14:
   // INC D
   DE.B.B1++;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B1]| (DE.B.B1&0x0F? 0:H_FLAG);
   break;
 case 0x15:
   // DEC D
   DE.B.B1--;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B1]|
     ((DE.B.B1&0x0F)==0x0F? H_FLAG:0);
   break;
 case 0x16:
   //  LD D,NN
   DE.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x17:
   // RLA
   tempValue=AF.B.B1&0x80? C_FLAG:0;
   AF.B.B1=(AF.B.B1<<1)|((AF.B.B0&C_FLAG)>>4);
   AF.B.B0=tempValue;
   break;
 case 0x18:
   // JR NN
   PC.W+=(s8)gbReadOpcode(PC.W)+1;
   break;
 case 0x19:
   // ADD HL,DE
   tempRegister.W=(HL.W+DE.W)&0xFFFF;
   AF.B.B0= (AF.B.B0 & Z_FLAG)| ((HL.W^DE.W^tempRegister.W)&0x1000? H_FLAG:0)|
     (((long)HL.W+(long)DE.W)&0x10000? C_FLAG:0);
   HL.W=tempRegister.W;
   break;
 case 0x1a:
   // LD A,(DE)
   AF.B.B1=gbReadMemory(DE.W);
   break;   
 case 0x1b:
   // DEC DE
   DE.W--;
   break;
 case 0x1c:
   // INC E
   DE.B.B0++;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B0]| (DE.B.B0&0x0F? 0:H_FLAG);
   break;
 case 0x1d:
   // DEC E
   DE.B.B0--;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[DE.B.B0]|
     ((DE.B.B0&0x0F)==0x0F? H_FLAG:0);
   break;
 case 0x1e:
   // LD E,NN
   DE.B.B0=gbReadOpcode(PC.W++);
   break;   
 case 0x1f:
   // RRA
   tempValue=AF.B.B1&0x01;
   AF.B.B1=(AF.B.B1>>1)|(AF.B.B0&C_FLAG? 0x80:0);
   AF.B.B0=(tempValue<<4);
   break;
 case 0x20:
   // JR NZ,NN
   if(AF.B.B0&Z_FLAG)
     PC.W++;
   else {
     PC.W+=(s8)gbReadOpcode(PC.W)+1;
     clockTicks++;
   }
   break;
 case 0x21:
   // LD HL,NNNN
   HL.B.B0=gbReadOpcode(PC.W++);
   HL.B.B1=gbReadOpcode(PC.W++);
   break;   
 case 0x22:
   // LDI (HL),A
   gbWriteMemory(HL.W++,AF.B.B1);
   break;
 case 0x23:
   // INC HL
   HL.W++;
   break;
 case 0x24:
   // INC H
   HL.B.B1++;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B1]| (HL.B.B1&0x0F? 0:H_FLAG);
   break;
 case 0x25:
   // DEC H
   HL.B.B1--;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B1]|
     ((HL.B.B1&0x0F)==0x0F? H_FLAG:0);
   break;
 case 0x26:
   // LD H,NN
   HL.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x27:
   // DAA
   tempRegister.W=AF.B.B1;
   if(AF.B.B0&C_FLAG) tempRegister.W|=256;
   if(AF.B.B0&H_FLAG) tempRegister.W|=512;
   if(AF.B.B0&N_FLAG) tempRegister.W|=1024;
   AF.W=DAATable[tempRegister.W];
   break;
 case 0x28:
   // JR Z,NN
   if(AF.B.B0&Z_FLAG) {
     PC.W+=(s8)gbReadOpcode(PC.W)+1;
     clockTicks++;
   } else
     PC.W++;
   break;
 case 0x29:
   // ADD HL,HL
   tempRegister.W=(HL.W+HL.W)&0xFFFF; AF.B.B0= (AF.B.B0 & Z_FLAG)|
                             ((HL.W^HL.W^tempRegister.W)&0x1000? H_FLAG:0)|
                             (((long)HL.W+(long)HL.W)&0x10000? C_FLAG:0);
   HL.W=tempRegister.W;
   break;
 case 0x2a:
   // LDI A,(HL)
   AF.B.B1 = gbReadMemory(HL.W++);
   break;
 case 0x2b:
   // DEC HL
   HL.W--;
   break;   
 case 0x2c:
   // INC L
   HL.B.B0++;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B0]| (HL.B.B0&0x0F? 0:H_FLAG);
   break;
 case 0x2d:
   // DEC L
   HL.B.B0--;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[HL.B.B0]|
     ((HL.B.B0&0x0F)==0x0F? H_FLAG:0);
   break;
 case 0x2e:
   // LD L,NN
   HL.B.B0=gbReadOpcode(PC.W++);
   break;   
 case 0x2f:
   // CPL
   AF.B.B1 ^= 255;
   AF.B.B0|=N_FLAG|H_FLAG;
   break;
 case 0x30:
   // JR NC,NN
   if(AF.B.B0&C_FLAG)
     PC.W++;
   else {
     PC.W+=(s8)gbReadOpcode(PC.W)+1;
     clockTicks++;
   }
   break;
 case 0x31:
   // LD SP,NNNN
   SP.B.B0=gbReadOpcode(PC.W++);
   SP.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x32:
   // LDD (HL),A
   gbWriteMemory(HL.W--,AF.B.B1);
   break;
 case 0x33:
   // INC SP
   SP.W++;
   break;
 case 0x34:
   // INC (HL)
   tempValue=gbReadMemory(HL.W)+1;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[tempValue]| (tempValue&0x0F? 0:H_FLAG);
   gbWriteMemory(HL.W,tempValue);
   break;
 case 0x35:
   // DEC (HL)
   tempValue=gbReadMemory(HL.W)-1;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[tempValue]|
     ((tempValue&0x0F)==0x0F? H_FLAG:0);gbWriteMemory(HL.W,tempValue);
   break;
 case 0x36:
   // LD (HL),NN
   gbWriteMemory(HL.W,gbReadOpcode(PC.W++));
   break;
 case 0x37:
   // SCF
   AF.B.B0 = AF.B.B0 & Z_FLAG | C_FLAG;
   break;   
case 0x38:
  // JR C,NN
  if(AF.B.B0&C_FLAG) {
    PC.W+=(s8)gbReadOpcode(PC.W)+1;
    clockTicks ++;
  } else
    PC.W++;
  break;
 case 0x39:
   // ADD HL,SP
   tempRegister.W=(HL.W+SP.W)&0xFFFF;
   AF.B.B0= (AF.B.B0 & Z_FLAG)| ((HL.W^SP.W^tempRegister.W)&0x1000? H_FLAG:0)|
     (((long)HL.W+(long)SP.W)&0x10000? C_FLAG:0);
   HL.W=tempRegister.W;
   break;
 case 0x3a:
   // LDD A,(HL)
   AF.B.B1 = gbReadMemory(HL.W--);
   break;
 case 0x3b:
   // DEC SP
   SP.W--;
   break;
 case 0x3c:
   // INC A
   AF.B.B1++;
   AF.B.B0= (AF.B.B0 & C_FLAG)|ZeroTable[AF.B.B1]| (AF.B.B1&0x0F? 0:H_FLAG);
   break;
 case 0x3d:
   // DEC A
   AF.B.B1--;
   AF.B.B0= N_FLAG|(AF.B.B0 & C_FLAG)|ZeroTable[AF.B.B1]|
     ((AF.B.B1&0x0F)==0x0F? H_FLAG:0);
   break;
 case 0x3e:
   // LD A,NN
   AF.B.B1=gbReadOpcode(PC.W++);
   break;
 case 0x3f:
   // CCF
   AF.B.B0^=C_FLAG;AF.B.B0&=~(N_FLAG|H_FLAG);
   break;
 case 0x40:
   // LD B,B
   BC.B.B1=BC.B.B1;
   break;
 case 0x41:
   // LD B,C
   BC.B.B1=BC.B.B0;
   break;
 case 0x42:
   // LD B,D
   BC.B.B1=DE.B.B1;
   break;
 case 0x43:
   // LD B,E
   BC.B.B1=DE.B.B0;
   break;
 case 0x44:
   // LD B,H
   BC.B.B1=HL.B.B1;
   break;
 case 0x45:
   // LD B,L
   BC.B.B1=HL.B.B0;
   break;
 case 0x46:
   // LD B,(HL)
   BC.B.B1=gbReadMemory(HL.W);
   break;
 case 0x47:
   // LD B,A
   BC.B.B1=AF.B.B1;
   break;
 case 0x48:
   // LD C,B
   BC.B.B0=BC.B.B1;
   break;
 case 0x49:
   // LD C,C
   BC.B.B0=BC.B.B0;
   break;
 case 0x4a:
   // LD C,D
   BC.B.B0=DE.B.B1;
   break;
 case 0x4b:
   // LD C,E
   BC.B.B0=DE.B.B0;
   break;
 case 0x4c:
   // LD C,H
   BC.B.B0=HL.B.B1;
   break;
 case 0x4d:
   // LD C,L
   BC.B.B0=HL.B.B0;
   break;
 case 0x4e:
   // LD C,(HL)
   BC.B.B0=gbReadMemory(HL.W);
   break;
 case 0x4f:
   // LD C,A
   BC.B.B0=AF.B.B1;
   break;
 case 0x50:
   // LD D,B
   DE.B.B1=BC.B.B1;
   break;
 case 0x51:
   // LD D,C
   DE.B.B1=BC.B.B0;
   break;
 case 0x52:
   // LD D,D
   DE.B.B1=DE.B.B1;
   break;
 case 0x53:
   // LD D,E
   DE.B.B1=DE.B.B0;
   break;
 case 0x54:
   // LD D,H
   DE.B.B1=HL.B.B1;
   break;
 case 0x55:
   // LD D,L
   DE.B.B1=HL.B.B0;
   break;
 case 0x56:
   // LD D,(HL)
   DE.B.B1=gbReadMemory(HL.W);
   break;
 case 0x57:
   // LD D,A
   DE.B.B1=AF.B.B1;
   break;
 case 0x58:
   // LD E,B
   DE.B.B0=BC.B.B1;
   break;
 case 0x59:
   // LD E,C
   DE.B.B0=BC.B.B0;
   break;
 case 0x5a:
   // LD E,D
   DE.B.B0=DE.B.B1;
   break;
 case 0x5b:
   // LD E,E
   DE.B.B0=DE.B.B0;
   break;
 case 0x5c:
   // LD E,H
   DE.B.B0=HL.B.B1;
   break;
 case 0x5d:
   // LD E,L
   DE.B.B0=HL.B.B0;
   break;
 case 0x5e:
   // LD E,(HL)
   DE.B.B0=gbReadMemory(HL.W);
   break;
 case 0x5f:
   // LD E,A
   DE.B.B0=AF.B.B1;
   break;
 case 0x60:
   // LD H,B
   HL.B.B1=BC.B.B1;
   break;
 case 0x61:
   // LD H,C
   HL.B.B1=BC.B.B0;
   break;
 case 0x62:
   // LD H,D
   HL.B.B1=DE.B.B1;
   break;
 case 0x63:
   // LD H,E
   HL.B.B1=DE.B.B0;
   break;
 case 0x64:
   // LD H,H
   HL.B.B1=HL.B.B1;
   break;
 case 0x65:
   // LD H,L
   HL.B.B1=HL.B.B0;
   break;
 case 0x66:
   // LD H,(HL)
   HL.B.B1=gbReadMemory(HL.W);
   break;
 case 0x67:
   // LD H,A
   HL.B.B1=AF.B.B1;
   break;
 case 0x68:
   // LD L,B
   HL.B.B0=BC.B.B1;
   break;
 case 0x69:
   // LD L,C
   HL.B.B0=BC.B.B0;
   break;
 case 0x6a:
   // LD L,D
   HL.B.B0=DE.B.B1;
   break;
 case 0x6b:
   // LD L,E
   HL.B.B0=DE.B.B0;
   break;
 case 0x6c:
   // LD L,H
   HL.B.B0=HL.B.B1;
   break;
 case 0x6d:
   // LD L,L
   HL.B.B0=HL.B.B0;
   break;
 case 0x6e:
   // LD L,(HL)
   HL.B.B0=gbReadMemory(HL.W);
   break;
 case 0x6f:
   // LD L,A
   HL.B.B0=AF.B.B1;
   break;
 case 0x70:
   // LD (HL),B
   gbWriteMemory(HL.W,BC.B.B1);
   break;
 case 0x71:
   // LD (HL),C
   gbWriteMemory(HL.W,BC.B.B0);
   break;
 case 0x72:
   // LD (HL),D
   gbWriteMemory(HL.W,DE.B.B1);
   break;
 case 0x73:
   // LD (HL),E
   gbWriteMemory(HL.W,DE.B.B0);
   break;
 case 0x74:
   // LD (HL),H
   gbWriteMemory(HL.W,HL.B.B1);
   break;
 case 0x75:
   // LD (HL),L
   gbWriteMemory(HL.W,HL.B.B0);
   break;
 case 0x76:
   // HALT
   // If an EI is pending, the interrupts are triggered before Halt state !!
   // Fix Torpedo Range's intro.
   if (IFF & 0x40)
   {
     IFF &= ~0x70;
     IFF |=1;
     PC.W--;
   }
   else
   {
     // if (IE & IF) and interrupts are disabeld, 
     // Halt is cancelled.
     if ((register_IE & register_IF & 0x1f) && !(IFF & 1))
     {
       IFF|=2;
     }
     else
       IFF |= 0x80;
   }
   break;
 case 0x77:
   // LD (HL),A
   gbWriteMemory(HL.W,AF.B.B1);
   break;
 case 0x78:
   // LD A,B
   AF.B.B1=BC.B.B1;
   break;
 case 0x79:
   // LD A,C
   AF.B.B1=BC.B.B0;
   break;
 case 0x7a:
   // LD A,D
   AF.B.B1=DE.B.B1;
   break;
 case 0x7b:
   // LD A,E
   AF.B.B1=DE.B.B0;
   break;
 case 0x7c:
   // LD A,H
   AF.B.B1=HL.B.B1;
   break;
 case 0x7d:
   // LD A,L
   AF.B.B1=HL.B.B0;
   break;
 case 0x7e:
   // LD A,(HL)
   AF.B.B1=gbReadMemory(HL.W);
   break;
 case 0x7f:
   // LD A,A
   AF.B.B1=AF.B.B1;
   break;
 case 0x80:
   // ADD B
   tempRegister.W=AF.B.B1+BC.B.B1;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x81:
   // ADD C
   tempRegister.W=AF.B.B1+BC.B.B0;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x82:
   // ADD D
   tempRegister.W=AF.B.B1+DE.B.B1;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x83:
   // ADD E
   tempRegister.W=AF.B.B1+DE.B.B0;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x84:
   // ADD H
   tempRegister.W=AF.B.B1+HL.B.B1;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x85:
   // ADD L
   tempRegister.W=AF.B.B1+HL.B.B0;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x86:
   // ADD (HL)
   tempValue=gbReadMemory(HL.W);
   tempRegister.W=AF.B.B1+tempValue;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x87:
   // ADD A
   tempRegister.W=AF.B.B1+AF.B.B1;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^AF.B.B1^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x88:
   // ADC B:
   tempRegister.W=AF.B.B1+BC.B.B1+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x89:
   // ADC C
   tempRegister.W=AF.B.B1+BC.B.B0+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x8a:
   // ADC D
   tempRegister.W=AF.B.B1+DE.B.B1+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x8b:
   // ADC E
   tempRegister.W=AF.B.B1+DE.B.B0+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x8c:
   // ADC H
   tempRegister.W=AF.B.B1+HL.B.B1+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0); AF.B.B1=tempRegister.B.B0;
   break;
 case 0x8d:
   // ADC L
   tempRegister.W=AF.B.B1+HL.B.B0+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x8e:
   // ADC (HL)
   tempValue=gbReadMemory(HL.W);
   tempRegister.W=AF.B.B1+tempValue+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x8f:
   // ADC A
   tempRegister.W=AF.B.B1+AF.B.B1+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^AF.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x90:
   // SUB B
   tempRegister.W=AF.B.B1-BC.B.B1;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x91:
   // SUB C
   tempRegister.W=AF.B.B1-BC.B.B0;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x92:
   // SUB D
   tempRegister.W=AF.B.B1-DE.B.B1;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x93:
   // SUB E
   tempRegister.W=AF.B.B1-DE.B.B0;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x94:
   // SUB H
   tempRegister.W=AF.B.B1-HL.B.B1;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x95:
   // SUB L
   tempRegister.W=AF.B.B1-HL.B.B0;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x96:
   // SUB (HL)
   tempValue=gbReadMemory(HL.W);
   tempRegister.W=AF.B.B1-tempValue;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x97:
   // SUB A
   AF.B.B1=0;
   AF.B.B0=N_FLAG|Z_FLAG;
   break;
 case 0x98:
   // SBC B
   tempRegister.W=AF.B.B1-BC.B.B1-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x99:
   // SBC C
   tempRegister.W=AF.B.B1-BC.B.B0-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x9a:
   // SBC D
   tempRegister.W=AF.B.B1-DE.B.B1-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x9b:
   // SBC E
   tempRegister.W=AF.B.B1-DE.B.B0-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x9c:
   // SBC H
   tempRegister.W=AF.B.B1-HL.B.B1-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x9d:
   // SBC L
   tempRegister.W=AF.B.B1-HL.B.B0-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x9e:
   // SBC (HL)
   tempValue=gbReadMemory(HL.W);
   tempRegister.W=AF.B.B1-tempValue-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0x9f:
   // SBC A
   tempRegister.W=AF.B.B1-AF.B.B1-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^AF.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0xa0:
   // AND B
   AF.B.B1&=BC.B.B1;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa1:
   // AND C
   AF.B.B1&=BC.B.B0;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa2:
   // AND_D
   AF.B.B1&=DE.B.B1;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa3:
   // AND E
   AF.B.B1&=DE.B.B0;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa4:
   // AND H
   AF.B.B1&=HL.B.B1;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa5:
   // AND L
   AF.B.B1&=HL.B.B0;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa6:
   // AND (HL)
   tempValue=gbReadMemory(HL.W);
   AF.B.B1&=tempValue;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa7:
   // AND A
   AF.B.B1&=AF.B.B1;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xa8:
   // XOR B
   AF.B.B1^=BC.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xa9:
   // XOR C
   AF.B.B1^=BC.B.B0;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xaa:
   // XOR D
   AF.B.B1^=DE.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xab:
   // XOR E
   AF.B.B1^=DE.B.B0;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xac:
   // XOR H
   AF.B.B1^=HL.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xad:
   // XOR L
   AF.B.B1^=HL.B.B0;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xae:
   // XOR (HL)
   tempValue=gbReadMemory(HL.W);
   AF.B.B1^=tempValue;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xaf:
   // XOR A
   AF.B.B1=0;
   AF.B.B0=Z_FLAG;
   break;
 case 0xb0:
   // OR B
   AF.B.B1|=BC.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb1:
   // OR C
   AF.B.B1|=BC.B.B0;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb2:
   // OR D
   AF.B.B1|=DE.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb3:
   // OR E
   AF.B.B1|=DE.B.B0;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb4:
   // OR H
   AF.B.B1|=HL.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb5:
   // OR L
   AF.B.B1|=HL.B.B0;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb6:
   // OR (HL)
   tempValue=gbReadMemory(HL.W);
   AF.B.B1|=tempValue;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb7:
   // OR A
   AF.B.B1|=AF.B.B1;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xb8:
   // CP B:
   tempRegister.W=AF.B.B1-BC.B.B1;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xb9:
   // CP C
   tempRegister.W=AF.B.B1-BC.B.B0;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^BC.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xba:
   // CP D
   tempRegister.W=AF.B.B1-DE.B.B1;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xbb:
   // CP E
   tempRegister.W=AF.B.B1-DE.B.B0;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^DE.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xbc:
   // CP H
   tempRegister.W=AF.B.B1-HL.B.B1;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B1^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xbd:
   // CP L
   tempRegister.W=AF.B.B1-HL.B.B0;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^HL.B.B0^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xbe:
   // CP (HL)
   tempValue=gbReadMemory(HL.W);
   tempRegister.W=AF.B.B1-tempValue;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xbf:
   // CP A
   AF.B.B0=N_FLAG|Z_FLAG;
   break;
 case 0xc0:
   // RET NZ
   if(!(AF.B.B0&Z_FLAG)) {
     PC.B.B0=gbReadMemory(SP.W++);
     PC.B.B1=gbReadMemory(SP.W++);
     clockTicks += 3;
   }
   break;
 case 0xc1:
   // POP BC
   BC.B.B0=gbReadMemory(SP.W++);
   BC.B.B1=gbReadMemory(SP.W++);
   break;
 case 0xc2:
   // JP NZ,NNNN
   if(AF.B.B0&Z_FLAG)
     PC.W+=2;
   else {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W);
     PC.W=tempRegister.W;
     clockTicks++;
   }
   break;
 case 0xc3:
   // JP NNNN
   tempRegister.B.B0=gbReadOpcode(PC.W++);
   tempRegister.B.B1=gbReadOpcode(PC.W);
   PC.W=tempRegister.W;
   break;
 case 0xc4:
   // CALL NZ,NNNN
   if(AF.B.B0&Z_FLAG)
     PC.W+=2;
   else {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W++);
     gbWriteMemory(--SP.W,PC.B.B1);
     gbWriteMemory(--SP.W,PC.B.B0);
     PC.W=tempRegister.W;
     clockTicks += 3;
   }
   break;
 case 0xc5:
   // PUSH BC
   gbWriteMemory(--SP.W,BC.B.B1);
   gbWriteMemory(--SP.W,BC.B.B0);
   break;
 case 0xc6:
   // ADD NN
   tempValue=gbReadOpcode(PC.W++);
   tempRegister.W=AF.B.B1+tempValue;
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10 ? H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0xc7:
   // RST 00
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0000;
   break;
 case 0xc8:
   // RET Z
   if(AF.B.B0&Z_FLAG) {
     PC.B.B0=gbReadMemory(SP.W++);
     PC.B.B1=gbReadMemory(SP.W++);
     clockTicks += 3;
   }
   break;
 case 0xc9:
   // RET
   PC.B.B0=gbReadMemory(SP.W++);
   PC.B.B1=gbReadMemory(SP.W++);
   break;
 case 0xca:
   // JP Z,NNNN
   if(AF.B.B0&Z_FLAG) {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W);
     PC.W=tempRegister.W;
     clockTicks++;
   } else
     PC.W+=2;
   break;
   // CB done outside
 case 0xcc:
   // CALL Z,NNNN
   if(AF.B.B0&Z_FLAG) {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W++);
     gbWriteMemory(--SP.W,PC.B.B1);
     gbWriteMemory(--SP.W,PC.B.B0);
     PC.W=tempRegister.W;
     clockTicks += 3;
   } else
     PC.W+=2;
   break;
 case 0xcd:
   // CALL NNNN
   tempRegister.B.B0=gbReadOpcode(PC.W++);
   tempRegister.B.B1=gbReadOpcode(PC.W++);
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=tempRegister.W;
   break;
 case 0xce:
   // ADC NN
   tempValue=gbReadOpcode(PC.W++);
   tempRegister.W=AF.B.B1+tempValue+(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= (tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0xcf:
   // RST 08
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0008;
   break;
 case 0xd0:
   // RET NC
   if(!(AF.B.B0&C_FLAG)) {
     PC.B.B0=gbReadMemory(SP.W++);
     PC.B.B1=gbReadMemory(SP.W++);
     clockTicks += 3;
   }
   break;
 case 0xd1:
   // POP DE
   DE.B.B0=gbReadMemory(SP.W++);
   DE.B.B1=gbReadMemory(SP.W++);
   break;
 case 0xd2:
   // JP NC,NNNN
   if(AF.B.B0&C_FLAG)
     PC.W+=2;
   else {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W);
     PC.W=tempRegister.W;
     clockTicks++;
   }
   break;
   // D3 illegal
 case 0xd3:
     PC.W--;
     IFF = 0;
   break;
 case 0xd4:
   // CALL NC,NNNN
   if(AF.B.B0&C_FLAG)
     PC.W+=2;
   else {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W++);
     gbWriteMemory(--SP.W,PC.B.B1);
     gbWriteMemory(--SP.W,PC.B.B0);
     PC.W=tempRegister.W;
     clockTicks += 3;
   }
   break;
 case 0xd5:
   // PUSH DE
   gbWriteMemory(--SP.W,DE.B.B1);
   gbWriteMemory(--SP.W,DE.B.B0);
   break;
 case 0xd6:
   // SUB NN
   tempValue=gbReadOpcode(PC.W++);
   tempRegister.W=AF.B.B1-tempValue;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0xd7:
   // RST 10
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0010;
   break;
 case 0xd8:
   // RET C
   if(AF.B.B0&C_FLAG) {
     PC.B.B0=gbReadMemory(SP.W++);
     PC.B.B1=gbReadMemory(SP.W++);
     clockTicks += 3;
   }
   break;
 case 0xd9:
   // RETI
   PC.B.B0=gbReadMemory(SP.W++);
   PC.B.B1=gbReadMemory(SP.W++);
   IFF |= 0x01;
   break;
 case 0xda:
   // JP C,NNNN
   if(AF.B.B0&C_FLAG) {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W);
     PC.W=tempRegister.W;
     clockTicks++;
   } else
     PC.W+=2;
   break;
   // DB illegal
 case 0xdb:
     PC.W--;
     IFF = 0;
   break;
 case 0xdc:
   // CALL C,NNNN
   if(AF.B.B0&C_FLAG) {
     tempRegister.B.B0=gbReadOpcode(PC.W++);
     tempRegister.B.B1=gbReadOpcode(PC.W++);
     gbWriteMemory(--SP.W,PC.B.B1);
     gbWriteMemory(--SP.W,PC.B.B0);
     PC.W=tempRegister.W;
     clockTicks += 3;
   } else
     PC.W+=2;
   break;
   // DD illegal
 case 0xdd:
     PC.W--;
     IFF = 0;
   break;
 case 0xde:
   // SBC NN
   tempValue=gbReadOpcode(PC.W++);
   tempRegister.W=AF.B.B1-tempValue-(AF.B.B0&C_FLAG ? 1 : 0);
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   AF.B.B1=tempRegister.B.B0;
   break;
 case 0xdf:
   // RST 18
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0018;
   break;
 case 0xe0:
   // LD (FF00+NN),A
   gbWriteMemory(0xff00 + gbReadOpcode(PC.W++),AF.B.B1);
   break;
 case 0xe1:
   // POP HL
   HL.B.B0=gbReadMemory(SP.W++);
   HL.B.B1=gbReadMemory(SP.W++);
   break;
 case 0xe2:
   // LD (FF00+C),A
   gbWriteMemory(0xff00 + BC.B.B0,AF.B.B1);
   break;
   // E3 illegal
   // E4 illegal
 case 0xe3:
 case 0xe4:
     PC.W--;
     IFF = 0;
   break;
 case 0xe5:
   // PUSH HL
   gbWriteMemory(--SP.W,HL.B.B1);
   gbWriteMemory(--SP.W,HL.B.B0);
   break;
 case 0xe6:
   // AND NN
   tempValue=gbReadOpcode(PC.W++);
   AF.B.B1&=tempValue;
   AF.B.B0=H_FLAG|ZeroTable[AF.B.B1];
   break;
 case 0xe7:
   // RST 20
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0020;
   break;
 case 0xe8:
   // ADD SP,NN
   offset = (s8)gbReadOpcode(PC.W++);
   
   if(offset >= 0) {
     tempRegister.W = SP.W + offset;
     AF.B.B0 = (SP.W > tempRegister.W ? C_FLAG : 0) |
       ((SP.W^offset^tempRegister.W)&0x1000? H_FLAG:0);
     SP.W = tempRegister.W;
   } else {
     tempRegister.W = SP.W + offset;
     AF.B.B0 = (SP.W < tempRegister.W ? C_FLAG : 0) |
       ((SP.W^offset^tempRegister.W)&0x1000?H_FLAG:0);
     SP.W = tempRegister.W;
   }
   break;
 case 0xe9:
   // LD PC,HL
   PC.W=HL.W;
   break;
 case 0xea:
   // LD (NNNN),A
   tempRegister.B.B0=gbReadOpcode(PC.W++);
   tempRegister.B.B1=gbReadOpcode(PC.W++);
   gbWriteMemory(tempRegister.W,AF.B.B1);
   break;
   // EB illegal
   // EC illegal
   // ED illegal
 case 0xeb:
 case 0xec:
 case 0xed:
     PC.W--;
     IFF = 0;
   break;
 case 0xee:
   // XOR NN
   tempValue=gbReadOpcode(PC.W++);
   AF.B.B1^=tempValue;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xef:
   // RST 28
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0028;
   break;
 case 0xf0:
   // LD A,(FF00+NN)
   AF.B.B1 = gbReadMemory(0xff00+gbReadOpcode(PC.W++));
   break;
 case 0xf1:
   // POP AF
   AF.B.B0=gbReadMemory(SP.W++);
   AF.B.B1=gbReadMemory(SP.W++);
   break;
 case 0xf2:
   // LD A,(FF00+C)
   AF.B.B1 = gbReadMemory(0xff00+BC.B.B0);
   break;
 case 0xf3:
   // DI
 //   IFF&=0xFE;
     IFF|=0x08;
   break;
   // F4 illegal
 case 0xf4:
     PC.W--;
     IFF = 0;
   break;
 case 0xf5:
   // PUSH AF
   gbWriteMemory(--SP.W,AF.B.B1);
   gbWriteMemory(--SP.W,AF.B.B0);
   break;
 case 0xf6:
   // OR NN
   tempValue=gbReadOpcode(PC.W++);
   AF.B.B1|=tempValue;
   AF.B.B0=ZeroTable[AF.B.B1];
   break;
 case 0xf7:
   // RST 30
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0030;
   break;
 case 0xf8:
   // LD HL,SP+NN
   offset = (s8)gbReadOpcode(PC.W++);
   if(offset >= 0) {
     tempRegister.W = SP.W + offset;
     AF.B.B0 = (SP.W > tempRegister.W ? C_FLAG : 0) |
       ((SP.W^offset^tempRegister.W)&0x1000? H_FLAG:0);
     HL.W = tempRegister.W;
   } else {
     tempRegister.W = SP.W + offset;
     AF.B.B0 = (SP.W < tempRegister.W ? C_FLAG : 0) |
       ((SP.W^offset^tempRegister.W)&0x1000?H_FLAG:0);
     HL.W = tempRegister.W;
   }
   break;
 case 0xf9:
   // LD SP,HL
   SP.W=HL.W;
   break;
 case 0xfa:
   // LD A,(NNNN)
   tempRegister.B.B0=gbReadOpcode(PC.W++);
   tempRegister.B.B1=gbReadOpcode(PC.W++);
   AF.B.B1=gbReadMemory(tempRegister.W);
   break;
 case 0xfb:
   // EI
   if (!(IFF & 0x30))
     // If an EI is executed right before HALT,
     // the interrupts are triggered before the Halt state !!
     // Fix Torpedo Range Intro.
     // IFF |= 0x10 : 1 ticks before the EI enables the interrupts
     // IFF |= 0x40 : marks that an EI is being executed.
     IFF|=0x50;
   break;
   // FC illegal (FC = breakpoint)
 case 0xfc:
    breakpoint = true;
  break;
   // FD illegal
 case 0xfd:
     PC.W--;
     IFF = 0;
   break;
 case 0xfe:
   // CP NN
   tempValue=gbReadOpcode(PC.W++);
   tempRegister.W=AF.B.B1-tempValue;
   AF.B.B0= N_FLAG|(tempRegister.B.B1?C_FLAG:0)|ZeroTable[tempRegister.B.B0]|
     ((AF.B.B1^tempValue^tempRegister.B.B0)&0x10?H_FLAG:0);
   break;
 case 0xff:
   // RST 38
   gbWriteMemory(--SP.W,PC.B.B1);
   gbWriteMemory(--SP.W,PC.B.B0);
   PC.W=0x0038;
   break;
 default:
   if (gbSystemMessage == false)
   {
     systemMessage(0, N_("Unknown opcode %02x at %04x"),
                   gbReadOpcode(PC.W-1),PC.W-1);
     gbSystemMessage =true;
   }
   return;
