@@ -1,870 +1,565 @@ 
   
    
    
    using  u8  = uint8_t ; 
 
    
    
    using  s8 = int8_t ; 
 
    
    
    using  u16  = uint16_t ; 
 
    
    
    using  u32  = uint32_t ; 
 
    
    
    using  u64  = uint64_t ; 
 
    
    
     
 
    
    
    u8  op, u, v, fc, *rom0, *rom1, io[512 ], vram[8192 ], wram[16384 ], *eram, *eram1, 
 
    
    
        R[] = {19 , 0 , 216 , 0 , 77 , 1 , 176 , 1 , 254 , 255 }, &F = R[6 ], &A = R[7 ],  
 
    
    
        *R8[] = {&R[1 ], &R[0 ], &R[3 ], &R[2 ], &R[5 ], &R[4 ], &F, &A}, &IF = io[271 ],  
 
    
    
        &LCDC = io[320 ], &LY = io[324 ], &WY = io[330 ], &WX = io[331 ], &IE = io[511 ],  
 
    
    
        IME = 0 , halt = 0 , FM[] = {128 , 128 , 16 , 16 }, FE[] = {0 , 128 , 0 , 16 }, *p;  
 
    
    
    u8  const  *Sk; 
 
    
    
    u16  PC = 256 , U, *RR = (u16  *)R, &HL = RR[2 ], &SP = RR[4 ], 
 
    
    
        *RR2[] = {&RR[0 ], &RR[1 ], &HL, &SP}, *RR3[] = {&RR[0 ], &RR[1 ], &HL, &HL},  
 
    
    
        &DIV = (u16  &)io[259 ], dot = 32 , *P;  
 
    
    
    u32  fb[23040 ], pal[] = {0xffffffff , 0xffaaaaaa , 0xff555555 , 0xff000000 }; 
 
    
    
    u64  bcy, cy = 0 ; 
 
    
    
    int  HA[] = {0 , 0 , 1 , -1 }; 
 
    
    
     
 
    
    
    void  T () { cy += 4 ; } 
 
    
    
    u8  mem (u16  a, u8  x, int  w) { 
 
    
    
      T ();  
 
    
    
      switch  (a >> 12 ) {  
 
    
    
      default :  
 
    
    
      case  2  ... 3 :  
 
    
    
        if  (w)  
 
    
    
          rom1 = rom0 + ((x ? (x & 63 ) : 1 ) << 14 );  
 
    
    
      case  0  ... 1 :  
 
    
    
        return  rom0[a];  
 
    
    
      case  4  ... 5 :  
 
    
    
        if  (w && x <= 3 )  
 
    
    
          eram1 = eram + (x << 13 );  
 
    
    
      case  6  ... 7 :  
 
    
    
        return  rom1[a & 16383 ];  
 
    
    
      case  8  ... 9 :  
 
    
    
        a &= 8191 ;  
 
    
    
        if  (w)  
 
    
    
          vram[a] = x;  
 
    
    
        return  vram[a];  
 
    
    
      case  10  ... 11 :  
 
    
    
        a &= 8191 ;  
 
    
    
        if  (w)  
 
    
    
          eram1[a] = x;  
 
    
    
        return  eram1[a];  
 
    
    
      case  15 :  
 
    
    
        if  (a >= 65024 ) {  
 
    
    
          if  (w) {  
 
    
    
            if  (a == 65350 )  
 
    
    
              for  (int  i = 160 ; --i >= 0 ;)  
 
    
    
                io[i] = mem (x * 256  + i, 0 , 0 );  
 
    
    
            io[a & 511 ] = x;  
 
    
    
          }  
 
    
    
          if  (a == 65280 ) {  
 
    
    
            if  (!(io[256 ] & 16 ))  
 
    
    
              return  ~(16  + Sk[81 ] * 8  + (Sk[82 ] * 4 ) + Sk[80 ] * 2  + Sk[79 ]);  
 
    
    
            if  (!(io[256 ] & 32 ))  
 
    
    
              return  ~(32  + Sk[40 ] * 8  + Sk[43 ] * 4  + Sk[29 ] * 2  + Sk[27 ]);  
 
    
    
            return  255 ;  
 
    
    
    #include  < SDL2/SDL.h>   
 
    
    
    #include  < cstdint>   
 
    
    
    #include  < fcntl.h>   
 
    
    
    #include  < sys/mman.h>   
 
    
    
    #include  < unistd.h>   
 
    
    
     
 
    
    
    #define  OP4_NX8 (_ ) case  _: case  _ + 8 : case  _ + 16 : case  _ + 24 :  
 
    
    
     
 
    
    
    #define  OP4_NX16_REL (_ )                                                        \  
 
    
    
      case  _:                                                                      \  
 
    
    
      case  _ + 16 :                                                                 \  
 
    
    
      case  _ + 32 :                                                                 \  
 
    
    
      case  _ + 48 :                                                                 \  
 
    
    
        opcode_rel = opcode - _;  
 
    
    
     
 
    
    
    #define  OP5_FLAG (_, always )                                                    \  
 
    
    
      OP4_NX8 (_)                                                                   \  
 
    
    
      case always:                                                                 \  
 
    
    
        carry = (opcode == always) ||                                              \  
 
    
    
                (F & F_mask[(opcode - _) / 8]) == F_equals[(opcode - _) / 8];  
 
    
    
     
 
    
    
    #define  OP8_NX8_REL (_ ) OP4_NX8(_) OP4_NX8(_ + 32 ) opcode_rel = opcode - _;  
 
    
    
     
 
    
    
    #define  OP7_PTR (_ )                                                             \  
 
    
    
      case  _:                                                                      \  
 
    
    
      case  _ + 1 :                                                                  \  
 
    
    
      case  _ + 2 :                                                                  \  
 
    
    
      case  _ + 3 :                                                                  \  
 
    
    
      case  _ + 4 :                                                                  \  
 
    
    
      case  _ + 5 :                                                                  \  
 
    
    
      case  _ + 7 :                                                                  \  
 
    
    
        ptr8 = reg8_group[opcode & 7 ];  
 
    
    
     
 
    
    
    #define  OP7_NX8 (_ ) OP4_NX8(_) case  _ + 32  : case  _ + 40  : case  _ + 56 :  
 
    
    
     
 
    
    
    #define  OP7_NX8_PTR (_ ) OP7_NX8(_) ptr8 = reg8_group[(opcode - _) / 8 ];  
 
    
    
     
 
    
    
    #define  OP49_REL (_ )                                                            \  
 
    
    
      OP7_NX8 (_)                                                                   \  
 
    
    
      OP7_NX8(_ + 1 )                                                               \  
 
    
    
      OP7_NX8(_ + 2 )                                                               \  
 
    
    
      OP7_NX8(_ + 3 )                                                               \  
 
    
    
      OP7_NX8(_ + 4 )                                                               \  
 
    
    
      OP7_NX8(_ + 5 )                                                               \  
 
    
    
      OP7_NX8(_ + 7 )                                                               \  
 
    
    
      opcode_rel = opcode - _;  
 
    
    
     
 
    
    
    #define  OP56_PTR_REL (_ ) OP49_REL(_) OP7_PTR(_ + 48 ) opcode_rel = opcode - _;  
 
    
    
     
 
    
    
    #define  OP9_IMM_PTR (_ )                                                         \  
 
    
    
      case  _ + 6 :                                                                  \  
 
    
    
      case  _ + 70 :                                                                 \  
 
    
    
        OP7_PTR (_)                                                                 \  
 
    
    
        operand = (opcode == _ + 6 )    ? read8()                                   \  
 
    
    
                  : (opcode == _ + 70 ) ? read8_pc()                                \  
 
    
    
                                       : *ptr8;  
 
    
    
     
 
    
    
    uint8_t  opcode, opcode_rel, tmp8, operand, carry, neg, *rom0, *rom1, io[512 ], video_ram[8192 ], 
 
    
    
        work_ram[16384 ], *extram, *extrambank,  
 
    
    
        reg8[] = {19 , 0 , 216 , 0 , 77 , 1 , 176 , 1 , 254 , 255 }, &F = reg8[6 ],  
 
    
    
        &A = reg8[7 ], *reg8_group[] = {reg8 + 1 , reg8,     reg8 + 3 , reg8 + 2 ,  
 
    
    
                                       reg8 + 5 , reg8 + 4 , &F,       &A},  
 
    
    
        &IF = io[271 ], &LCDC = io[320 ], &LY = io[324 ], IME, halt, *ptr8;  
 
    
    
     
 
    
    
    uint8_t  const  *key_state; 
 
    
    
     
 
    
    
    uint16_t  PC = 256 , temp16, *reg16 = (uint16_t  *)reg8, &HL = reg16[2 ], 
 
    
    
             &SP = reg16[4 ], &DIV = (uint16_t  &)io[259 ], ppu_dot = 32 , *ptr16,  
 
    
    
             *reg16_group1[] = {reg16, reg16 + 1 , &HL, &SP},  
 
    
    
             *reg16_group2[] = {reg16, reg16 + 1 , &HL, &HL}, prev_cycles, cycles;  
 
    
    
     
 
    
    
    int  tmp, tmp2, 
 
    
    
        HL_add[] = {0 , 0 , 1 , -1 }, F_mask[] = {128 , 128 , 16 , 16 },  
 
    
    
        F_equals[] = {0 , 128 , 0 , 16 }, frame_buffer[23040 ],  
 
    
    
        palette[] = {-1 ,        -23197 ,    -65536 , -16777216 , -1 ,     -8092417 ,  
 
    
    
                     -12961132 , -16777216 , -1 ,     -23197 ,    -65536 , -16777216 };  
 
    
    
     
 
    
    
    void  tick () { cycles += 4 ; } 
 
    
    
     
 
    
    
    uint8_t  mem_access (uint16_t  addr, uint8_t  val, int  write) { 
 
    
    
      tick ();  
 
    
    
      switch  (addr >> 12 ) {  
 
    
    
        case  2 : case  3 :  
 
    
    
          if  (write)  
 
    
    
            rom1 = rom0 + ((val ? val & 63  : 1 ) << 14 );  
 
    
    
     
 
    
    
        case  0 : case  1 :  
 
    
    
          return  rom0[addr];  
 
    
    
     
 
    
    
        case  4 : case  5 :  
 
    
    
          if  (write && val <= 3 )  
 
    
    
            extrambank = extram + (val << 13 );  
 
    
    
     
 
    
    
        case  6 : case  7 :  
 
    
    
          return  rom1[addr & 16383 ];  
 
    
    
     
 
    
    
        case  8 : case  9 :  
 
    
    
          addr &= 8191 ;  
 
    
    
          if  (write)  
 
    
    
            video_ram[addr] = val;  
 
    
    
          return  video_ram[addr];  
 
    
    
     
 
    
    
        case  10 : case  11 :  
 
    
    
          addr &= 8191 ;  
 
    
    
          if  (write)  
 
    
    
            extrambank[addr] = val;  
 
    
    
          return  extrambank[addr];  
 
    
    
     
 
    
    
        case  15 :  
 
    
    
          if  (addr >= 65024 ) {  
 
    
    
            if  (write) {  
 
    
    
              if  (addr == 65350 )  
 
    
    
                for  (int  y = 160 ; --y >= 0 ;)  
 
    
    
                  io[y] = mem_access (val * 256  + y, 0 , 0 );  
 
    
    
              io[addr & 511 ] = val;  
 
    
    
            }  
 
    
    
            if  (addr == 65280 ) {  
 
    
    
              if  (!(io[256 ] & 16 ))  
 
    
    
                return  ~(16  + key_state[81 ] * 8  + key_state[82 ] * 4  + key_state[80 ] * 2  + key_state[79 ]);  
 
    
    
              if  (!(io[256 ] & 32 ))  
 
    
    
                return  ~(32  + key_state[40 ] * 8  + key_state[43 ] * 4  + key_state[29 ] * 2  + key_state[27 ]);  
 
    
    
              return  255 ;  
 
    
    
            }  
 
    
    
            return  io[addr & 511 ];  
 
    
    
          }  
 
    
    
          return  io[a & 511 ];  
 
    
    
        }  
 
    
    
      case  12  ... 14 :  
 
    
    
        a &= 16383 ;  
 
    
    
        if  (w)  
 
    
    
          wram[a] = x;  
 
    
    
        return  wram[a];  
 
    
    
     
 
    
    
        case  12  ... 14 :  
 
    
    
          addr &= 16383 ;  
 
    
    
          if  (write)  
 
    
    
            work_ram[addr] = val;  
 
    
    
          return  work_ram[addr];  
 
    
    
      }  
 
    
    
    }  
 
    
    
    u8  r (u16  a) { return  mem (a, 0 , 0 ); } 
 
    
    
    void  w (u16  a, u8  x) { mem (a, x, 1 ); } 
 
    
    
    void  FS (u8  M, int  Z, int  N, int  H, int  C) { 
 
    
    
      F = (F & M) | (!Z * 128  + N * 64  + H * 32  + C * 16 );  
 
    
    
     
 
    
    
    uint8_t  read8 (uint16_t  addr = HL) { return  mem_access (addr, 0 , 0 ); } 
 
    
    
     
 
    
    
    void  write8 (uint8_t  val, uint16_t  addr = HL) { mem_access (addr, val, 1 ); } 
 
    
    
     
 
    
    
    void  set_flags (uint8_t  mask, int  Z, int  N, int  H, int  C) { 
 
    
    
      F = (F & mask) | (!Z * 128  + N * 64  + H * 32  + C * 16 );  
 
    
    
    }  
 
    
    
    u8  r8 () { return  r (PC++); } 
 
    
    
    u16  r16 (u16  &R = PC) { 
 
    
    
      u = r (R++);  
 
    
    
      return  r (R++) * 256  + u;  
 
    
    
     
 
    
    
    uint8_t  read8_pc () { return  read8 (PC++); } 
 
    
    
     
 
    
    
    uint16_t  read16 (uint16_t  &addr = PC) { 
 
    
    
      tmp8 = read8 (addr++);  
 
    
    
      return  read8 (addr++) * 256  + tmp8;  
 
    
    
    }  
 
    
    
    void  push (u16  x) { 
 
    
    
      w (--SP, x >> 8 );  
 
    
    
      w (--SP, x);  
 
    
    
      T ();  
 
    
    
     
 
    
    
    void  push (uint16_t  addr) { 
 
    
    
      write8 (addr >> 8 , --SP);  
 
    
    
      write8 (addr, --SP);  
 
    
    
      tick ();  
 
    
    
    }  
 
    
    
     
 
    
    
    int  main () { 
 
    
    
      rom1 =  
 
    
    
          (rom0 = (u8  *)mmap (0 , 1048576 , 0x1 , 0x01 , open (" rom.gb" 00 ), 0 )) + 32768 ;  
 
    
    
      int  sav = open (" rom.sav" 0100  | 02 , 0666 );  
 
    
    
      ftruncate (sav, 32768 );  
 
    
    
      eram1 = eram = (u8  *)mmap (0 , 32768 , 0x1  | 0x2 , 0x01 , sav, 0 );  
 
    
    
      rom1 = (rom0 = (uint8_t  *)mmap (0 , 1048576 , PROT_READ, MAP_SHARED,  
 
    
    
                                     open (" rom.gb" 0 )) +  
 
    
    
             32768 ;  
 
    
    
      tmp = open (" rom.sav" 0666 );  
 
    
    
      ftruncate (tmp, 32768 );  
 
    
    
      extrambank = extram =  
 
    
    
          (uint8_t  *)mmap (0 , 32768 , PROT_READ | PROT_WRITE, MAP_SHARED, tmp, 0 );  
 
    
    
      LCDC = 145 ;  
 
    
    
      DIV = 44032 ;  
 
    
    
      SDL_Init ((0x00000001u  | 0x00000010u  | 0x00000020u  | 0x00004000u  |  
 
    
    
                0x00000200u  | 0x00001000u  | 0x00002000u  | 0x00008000u ));  
 
    
    
      SDL_Window *Sw =  
 
    
    
          SDL_CreateWindow (" pokegb" 100 , 100 , 160  * 5 , 144  * 5 , SDL_WINDOW_SHOWN);  
 
    
    
      SDL_Renderer *Sr = SDL_CreateRenderer (Sw, -1 , 0 );  
 
    
    
      SDL_Init (SDL_INIT_VIDEO);  
 
    
    
      SDL_Renderer *Sr = SDL_CreateRenderer (  
 
    
    
          SDL_CreateWindow (" pokegb" 0 , 0 , 800 , 720 , SDL_WINDOW_SHOWN), -1 ,  
 
    
    
          SDL_RENDERER_PRESENTVSYNC);  
 
    
    
      SDL_Texture *St = SDL_CreateTexture (Sr, SDL_PIXELFORMAT_RGBA32,  
 
    
    
                                          SDL_TEXTUREACCESS_STREAMING, 160 , 144 );  
 
    
    
      Sk  = SDL_GetKeyboardState (0 );  
 
    
    
      key_state  = SDL_GetKeyboardState (0 );  
 
    
    
     
 
    
    
      while  (1 ) {  
 
    
    
        bcy  = cy ;  
 
    
    
        if  (IME & IF & IE ) {  
 
    
    
        prev_cycles  = cycles ;  
 
    
    
        if  (IME & IF & io[ 511 ] ) {  
 
    
    
          IF = halt = IME = 0 ;  
 
    
    
          cy  += 8 ;  
 
    
    
          fc  = 1 ;  
 
    
    
          U  = 64 ;  
 
    
    
          goto  CALLU ;  
 
    
    
          cycles  += 8 ;  
 
    
    
          carry  = 1 ;  
 
    
    
          temp16  = 64 ;  
 
    
    
          goto  CALL ;  
 
    
    
        } else  if  (halt)  
 
    
    
          T ();  
 
    
    
          tick ();  
 
    
    
        else   
 
    
    
          switch  ((op  = r8 () )) {  
 
    
    
          switch  (opcode  = read8_pc ( )) {  
 
    
    
          case  0 :  
 
    
    
            break ;  
 
    
    
          case  1 :  
 
    
    
          case  1  + 16 :  
 
    
    
          case  1  + 32 :  
 
    
    
          case  1  + 48 :  
 
    
    
            *RR2[op >> 4 ] = r16 ();  
 
    
    
            break ;  
 
    
    
          case  2 :  
 
    
    
          case  2  + 16 :  
 
    
    
          case  2  + 32 :  
 
    
    
          case  2  + 48 :  
 
    
    
            w (*RR3[op >> 4 ], A);  
 
    
    
            HL += HA[(op - 2 ) / 16 ];  
 
    
    
            break ;  
 
    
    
          case  3 :  
 
    
    
          case  3  + 16 :  
 
    
    
          case  3  + 32 :  
 
    
    
          case  3  + 48 :  
 
    
    
            (*RR2[op >> 4 ])++;  
 
    
    
            T ();  
 
    
    
            break ;  
 
    
    
          case  4 :  
 
    
    
          case  4  + 8 :  
 
    
    
          case  4  + 16 :  
 
    
    
          case  4  + 24 :  
 
    
    
          case  4  + 32 :  
 
    
    
          case  4  + 40 :  
 
    
    
          case  4  + 56 :  
 
    
    
            p = R8[(op - 4 ) / 8 ];  
 
    
    
            ++(*p);  
 
    
    
            FS (16 , *p, 0 , !(*p & 15 ), 0 );  
 
    
    
            break ;  
 
    
    
          case  5 :  
 
    
    
          case  5  + 8 :  
 
    
    
          case  5  + 16 :  
 
    
    
          case  5  + 24 :  
 
    
    
          case  5  + 32 :  
 
    
    
          case  5  + 40 :  
 
    
    
          case  5  + 56 :  
 
    
    
            p = R8[(op - 5 ) / 8 ];  
 
    
    
            --(*p);  
 
    
    
            FS (16 , *p, 1 , (*p & 15 ) == 15 , 0 );  
 
    
    
            break ;  
 
    
    
          case  6 :  
 
    
    
          case  6  + 8 :  
 
    
    
          case  6  + 16 :  
 
    
    
          case  6  + 24 :  
 
    
    
          case  6  + 32 :  
 
    
    
          case  6  + 40 :  
 
    
    
          case  6  + 56 :  
 
    
    
            p = R8[(op - 6 ) / 8 ];  
 
    
    
            *p = r8 ();  
 
    
    
     
 
    
    
          OP4_NX16_REL (1 )  
 
    
    
            *reg16_group1[opcode >> 4 ] = read16 ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP4_NX16_REL (2 )  
 
    
    
            write8 (A, *reg16_group2[opcode >> 4 ]);  
 
    
    
            HL += HL_add[opcode_rel / 16 ];  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP4_NX16_REL (3 )  
 
    
    
            (*reg16_group1[opcode >> 4 ])++;  
 
    
    
            tick ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP7_NX8_PTR (4 )  
 
    
    
            tmp8 = ++(*ptr8);  
 
    
    
            goto  INC_FLAGS;  
 
    
    
     
 
    
    
          case  52 :  
 
    
    
            write8 (tmp8 = read8 () + 1 );  
 
    
    
          INC_FLAGS:  
 
    
    
            set_flags (16 , tmp8, 0 , !(tmp8 & 15 ), 0 );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP7_NX8_PTR (5 )  
 
    
    
            tmp8 = --(*ptr8);  
 
    
    
            goto  DEC_FLAGS;  
 
    
    
     
 
    
    
          case  53 :  
 
    
    
            write8 (tmp8 = read8 () - 1 );  
 
    
    
          DEC_FLAGS:  
 
    
    
            set_flags (16 , tmp8, 1 , tmp8 % 16  == 15 , 0 );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP7_NX8_PTR (6 )  
 
    
    
            *ptr8 = read8_pc ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  7 :  
 
    
    
            A += A + (fc = A >> 7 );  
 
    
    
            FS (0 , 1 , 0 , 0 , fc);  
 
    
    
            break ;  
 
    
    
          case  9 :  
 
    
    
          case  9  + 16 :  
 
    
    
          case  9  + 32 :  
 
    
    
          case  9  + 48 :  
 
    
    
            P = RR2[op >> 4 ];  
 
    
    
            FS (128 , 1 , 0 , HL % 4096  + *P % 4096  > 4095 , HL + *P > 65535 );  
 
    
    
            HL += *P;  
 
    
    
            T ();  
 
    
    
            break ;  
 
    
    
          case  10 :  
 
    
    
          case  10  + 16 :  
 
    
    
          case  10  + 32 :  
 
    
    
          case  10  + 48 :  
 
    
    
            A = r (*RR3[op >> 4 ]);  
 
    
    
            HL += HA[(op - 10 ) / 16 ];  
 
    
    
            break ;  
 
    
    
          case  11 :  
 
    
    
          case  11  + 16 :  
 
    
    
          case  11  + 32 :  
 
    
    
          case  11  + 48 :  
 
    
    
            (*RR2[op >> 4 ])--;  
 
    
    
            T ();  
 
    
    
            A += A + (carry = A >> 7 );  
 
    
    
            goto  CARRY_FLAG;  
 
    
    
     
 
    
    
          OP4_NX16_REL (9 )  
 
    
    
            ptr16 = reg16_group1[opcode >> 4 ];  
 
    
    
            set_flags (128 , 1 , 0 , HL % 4096  + *ptr16 % 4096  > 4095 , HL + *ptr16 > 65535 );  
 
    
    
            HL += *ptr16;  
 
    
    
            tick ();  
 
    
    
            break ;  
 
    
    
          case  15 :  
 
    
    
            A = (fc = A & 1 ) * 128  + A / 2 ;  
 
    
    
            FS (0 , 1 , 0 , 0 , fc);  
 
    
    
     
 
    
    
          OP4_NX16_REL (10 )  
 
    
    
            A = read8 (*reg16_group2[opcode >> 4 ]);  
 
    
    
            HL += HL_add[opcode_rel / 16 ];  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP4_NX16_REL (11 )  
 
    
    
            (*reg16_group1[opcode >> 4 ])--;  
 
    
    
            tick ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  15 :  
 
    
    
            A = (carry = A & 1 ) * 128  + A / 2 ;  
 
    
    
            goto  CARRY_FLAG;  
 
    
    
     
 
    
    
          case  23 :  
 
    
    
            fc = A >> 7 ;  
 
    
    
            A += A + (F >> 4 ) % 2 ;  
 
    
    
            FS (0 , 1 , 0 , 0 , fc);  
 
    
    
            break ;  
 
    
    
          case  32 :  
 
    
    
          case  32  + 8 :  
 
    
    
          case  32  + 16 :  
 
    
    
          case  32  + 24 :  
 
    
    
          case  24 :  
 
    
    
            fc = (op == 24 ) || (F & FM[(op - 32 ) / 8 ]) == FE[(op - 32 ) / 8 ];  
 
    
    
            u = r8 ();  
 
    
    
            if  (fc)  
 
    
    
              PC += (s8)u, T ();  
 
    
    
            carry = A >> 7 ;  
 
    
    
            A += A + F / 16  % 2 ;  
 
    
    
          CARRY_FLAG:  
 
    
    
            set_flags (0 , 1 , 0 , 0 , carry);  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP5_FLAG (32 , 24 )  
 
    
    
            tmp8 = read8_pc ();  
 
    
    
            if  (carry)  
 
    
    
              PC += (int8_t )tmp8, tick ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  39 :  
 
    
    
            fc  = u  = 0 ;  
 
    
    
            carry  = tmp8  = 0 ;  
 
    
    
            if  (F & 32  || (!(F & 64 ) && A % 15  > 9 ))  
 
    
    
              u  = 6 ;  
 
    
    
              tmp8  = 6 ;  
 
    
    
            if  (F & 16  || (!(F & 64 ) && A > 153 ))  
 
    
    
              u  |= 96 , fc  = 1 ;  
 
    
    
            FS (65 , A += (F & 64 ) ? -u  : u , 0 , 0 , fc );  
 
    
    
              tmp8  |= 96 , carry  = 1 ;  
 
    
    
            set_flags (65 , A += (F & 64 ) ? -tmp8  : tmp8 , 0 , 0 , carry );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  47 :  
 
    
    
            A = ~A;  
 
    
    
            FS (129 , 1 , 1 , 1 , 0 );  
 
    
    
            set_flags (129 , 1 , 1 , 1 , 0 );  
 
    
    
            break ;  
 
    
    
          case  52 :  
 
    
    
            u = r (HL) + 1 ;  
 
    
    
            FS (16 , u, 0 , !(u & 15 ), 0 );  
 
    
    
            w (HL, u);  
 
    
    
     
 
    
    
          case  54 :  
 
    
    
            write8 (read8_pc ());  
 
    
    
            break ;  
 
    
    
          case  53 :  
 
    
    
            u = r (HL) - 1 ;  
 
    
    
            FS (16 , u, 1 , u % 16  == 15 , 0 );  
 
    
    
            w (HL, u);  
 
    
    
     
 
    
    
          case  55 : case  63 :  
 
    
    
            set_flags (128 , 1 , 0 , 0 , opcode == 55  ? 1  : !(F & 16 ));  
 
    
    
            break ;  
 
    
    
          case  54 :  
 
    
    
            w (HL, r8 ());  
 
    
    
            break ;  
 
    
    
          case  55 :  
 
    
    
            FS (128 , 1 , 0 , 0 , 1 );  
 
    
    
            break ;  
 
    
    
          case  63 :  
 
    
    
            FS (128 , 1 , 0 , 0 , !(F & 16 ));  
 
    
    
            break ;  
 
    
    
          case  70 :  
 
    
    
          case  70  + 8 :  
 
    
    
          case  70  + 16 :  
 
    
    
          case  70  + 24 :  
 
    
    
          case  70  + 32 :  
 
    
    
          case  70  + 40 :  
 
    
    
          case  70  + 56 :  
 
    
    
            p = R8[(op - 70 ) / 8 ];  
 
    
    
            *p = r (HL);  
 
    
    
            break ;  
 
    
    
          case  64 :  
 
    
    
          case  64  + 8 :  
 
    
    
          case  64  + 16 :  
 
    
    
          case  64  + 24 :  
 
    
    
          case  64  + 32 :  
 
    
    
          case  64  + 40 :  
 
    
    
          case  64  + 56 :  
 
    
    
          case  64  + 1 :  
 
    
    
          case  64  + 1  + 8 :  
 
    
    
          case  64  + 1  + 16 :  
 
    
    
          case  64  + 1  + 24 :  
 
    
    
          case  64  + 1  + 32 :  
 
    
    
          case  64  + 1  + 40 :  
 
    
    
          case  64  + 1  + 56 :  
 
    
    
          case  64  + 2 :  
 
    
    
          case  64  + 2  + 8 :  
 
    
    
          case  64  + 2  + 16 :  
 
    
    
          case  64  + 2  + 24 :  
 
    
    
          case  64  + 2  + 32 :  
 
    
    
          case  64  + 2  + 40 :  
 
    
    
          case  64  + 2  + 56 :  
 
    
    
          case  64  + 3 :  
 
    
    
          case  64  + 3  + 8 :  
 
    
    
          case  64  + 3  + 16 :  
 
    
    
          case  64  + 3  + 24 :  
 
    
    
          case  64  + 3  + 32 :  
 
    
    
          case  64  + 3  + 40 :  
 
    
    
          case  64  + 3  + 56 :  
 
    
    
          case  64  + 4 :  
 
    
    
          case  64  + 4  + 8 :  
 
    
    
          case  64  + 4  + 16 :  
 
    
    
          case  64  + 4  + 24 :  
 
    
    
          case  64  + 4  + 32 :  
 
    
    
          case  64  + 4  + 40 :  
 
    
    
          case  64  + 4  + 56 :  
 
    
    
          case  64  + 5 :  
 
    
    
          case  64  + 5  + 8 :  
 
    
    
          case  64  + 5  + 16 :  
 
    
    
          case  64  + 5  + 24 :  
 
    
    
          case  64  + 5  + 32 :  
 
    
    
          case  64  + 5  + 40 :  
 
    
    
          case  64  + 5  + 56 :  
 
    
    
          case  64  + 7 :  
 
    
    
          case  64  + 7  + 8 :  
 
    
    
          case  64  + 7  + 16 :  
 
    
    
          case  64  + 7  + 24 :  
 
    
    
          case  64  + 7  + 32 :  
 
    
    
          case  64  + 7  + 40 :  
 
    
    
          case  64  + 7  + 56 :  
 
    
    
            *R8[(op - 64 ) / 8 ] = *R8[op & 7 ];  
 
    
    
            break ;  
 
    
    
          case  112 :  
 
    
    
          case  112  + 1 :  
 
    
    
          case  112  + 2 :  
 
    
    
          case  112  + 3 :  
 
    
    
          case  112  + 4 :  
 
    
    
          case  112  + 5 :  
 
    
    
          case  112  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            w (HL, *p);  
 
    
    
     
 
    
    
          OP7_NX8_PTR (70 )  
 
    
    
            *ptr8 = read8 ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP49_REL (64 )  
 
    
    
            *reg8_group[opcode_rel / 8 ] = *reg8_group[opcode & 7 ];  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP7_PTR (112 )  
 
    
    
            write8 (*ptr8);  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  118 :  
 
    
    
            halt = 1 ;  
 
    
    
            break ;  
 
    
    
          case  128  + 6 :  
 
    
    
          case  128  + 70 :  
 
    
    
          case  128 :  
 
    
    
          case  128  + 1 :  
 
    
    
          case  128  + 2 :  
 
    
    
          case  128  + 3 :  
 
    
    
          case  128  + 4 :  
 
    
    
          case  128  + 5 :  
 
    
    
          case  128  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 128  + 6 ) ? r (HL) : (op == 128  + 70 ) ? r8 () : *p;  
 
    
    
            fc = 0 ;  
 
    
    
            goto  ADD;  
 
    
    
          case  136  + 6 :  
 
    
    
          case  136  + 70 :  
 
    
    
          case  136 :  
 
    
    
          case  136  + 1 :  
 
    
    
          case  136  + 2 :  
 
    
    
          case  136  + 3 :  
 
    
    
          case  136  + 4 :  
 
    
    
          case  136  + 5 :  
 
    
    
          case  136  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 136  + 6 ) ? r (HL) : (op == 136  + 70 ) ? r8 () : *p;  
 
    
    
            fc = (F >> 4 ) & 1 ;  
 
    
    
          ADD:  
 
    
    
            FS (0 , u = A + v + fc, 0 , A % 16  + v % 16  + fc > 15 , A + v + fc > 255 );  
 
    
    
            A = u;  
 
    
    
            break ;  
 
    
    
          case  144  + 6 :  
 
    
    
          case  144  + 70 :  
 
    
    
          case  144 :  
 
    
    
          case  144  + 1 :  
 
    
    
          case  144  + 2 :  
 
    
    
          case  144  + 3 :  
 
    
    
          case  144  + 4 :  
 
    
    
          case  144  + 5 :  
 
    
    
          case  144  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 144  + 6 ) ? r (HL) : (op == 144  + 70 ) ? r8 () : *p;  
 
    
    
            fc = 0 ;  
 
    
    
            goto  SUB;  
 
    
    
          case  152  + 6 :  
 
    
    
          case  152  + 70 :  
 
    
    
          case  152 :  
 
    
    
          case  152  + 1 :  
 
    
    
          case  152  + 2 :  
 
    
    
          case  152  + 3 :  
 
    
    
          case  152  + 4 :  
 
    
    
          case  152  + 5 :  
 
    
    
          case  152  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 152  + 6 ) ? r (HL) : (op == 152  + 70 ) ? r8 () : *p;  
 
    
    
            fc = (F >> 4 ) & 1 ;  
 
    
    
          SUB:  
 
    
    
            FS (0 , u = A - v - fc, 1 , A % 16  < v % 16  + fc, A < v + fc);  
 
    
    
            A = u;  
 
    
    
            break ;  
 
    
    
          case  160  + 6 :  
 
    
    
          case  160  + 70 :  
 
    
    
          case  160 :  
 
    
    
          case  160  + 1 :  
 
    
    
          case  160  + 2 :  
 
    
    
          case  160  + 3 :  
 
    
    
          case  160  + 4 :  
 
    
    
          case  160  + 5 :  
 
    
    
          case  160  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 160  + 6 ) ? r (HL) : (op == 160  + 70 ) ? r8 () : *p;  
 
    
    
            FS (0 , A &= v, 0 , 1 , 0 );  
 
    
    
            break ;  
 
    
    
          case  168  + 6 :  
 
    
    
          case  168  + 70 :  
 
    
    
          case  168 :  
 
    
    
          case  168  + 1 :  
 
    
    
          case  168  + 2 :  
 
    
    
          case  168  + 3 :  
 
    
    
          case  168  + 4 :  
 
    
    
          case  168  + 5 :  
 
    
    
          case  168  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 168  + 6 ) ? r (HL) : (op == 168  + 70 ) ? r8 () : *p;  
 
    
    
            FS (0 , A ^= v, 0 , 0 , 0 );  
 
    
    
            break ;  
 
    
    
          case  176  + 6 :  
 
    
    
          case  176  + 70 :  
 
    
    
          case  176 :  
 
    
    
          case  176  + 1 :  
 
    
    
          case  176  + 2 :  
 
    
    
          case  176  + 3 :  
 
    
    
          case  176  + 4 :  
 
    
    
          case  176  + 5 :  
 
    
    
          case  176  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 176  + 6 ) ? r (HL) : (op == 176  + 70 ) ? r8 () : *p;  
 
    
    
            FS (0 , A |= v, 0 , 0 , 0 );  
 
    
    
            break ;  
 
    
    
          case  184  + 6 :  
 
    
    
          case  184  + 70 :  
 
    
    
          case  184 :  
 
    
    
          case  184  + 1 :  
 
    
    
          case  184  + 2 :  
 
    
    
          case  184  + 3 :  
 
    
    
          case  184  + 4 :  
 
    
    
          case  184  + 5 :  
 
    
    
          case  184  + 7 :  
 
    
    
            p = R8[op & 7 ];  
 
    
    
            v = (op == 184  + 6 ) ? r (HL) : (op == 184  + 70 ) ? r8 () : *p;  
 
    
    
            FS (0 , A != v, 1 , A % 16  < v % 16 , A < v);  
 
    
    
     
 
    
    
          OP9_IMM_PTR (128 )  
 
    
    
            neg = carry = 0 ;  
 
    
    
            goto  ALU;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (136 )  
 
    
    
            neg = 0 ;  
 
    
    
            carry = F / 16  % 2 ;  
 
    
    
            goto  ALU;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (144 )  
 
    
    
            carry = 1 ;  
 
    
    
            goto  SUBTRACT;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (152 )  
 
    
    
            carry = !(F / 16  % 2 );  
 
    
    
          SUBTRACT:  
 
    
    
            neg = 1 ;  
 
    
    
            operand = ~operand;  
 
    
    
          ALU:  
 
    
    
            set_flags (0 , tmp8 = A + operand + carry, neg,  
 
    
    
                      (A % 16  + operand % 16  + carry > 15 ) ^ neg,  
 
    
    
                      (A + operand + carry > 255 ) ^ neg);  
 
    
    
            A = tmp8;  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (160 )  
 
    
    
            set_flags (0 , A &= operand, 0 , 1 , 0 );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (168 )  
 
    
    
            set_flags (0 , A ^= operand, 0 , 0 , 0 );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (176 )  
 
    
    
            set_flags (0 , A |= operand, 0 , 0 , 0 );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP9_IMM_PTR (184 )  
 
    
    
            set_flags (0 , A != operand, 1 , A % 16  < operand % 16 , A < operand);  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  217 :  
 
    
    
            fc  = IME = 1 ;  
 
    
    
            carry  = IME = 1 ;  
 
    
    
            goto  RET;  
 
    
    
          case  192 :  
 
    
    
          case  192  + 8 :  
 
    
    
          case  192  + 16 :  
 
    
    
          case  192  + 24 :  
 
    
    
          case  201 :  
 
    
    
            fc = (op == 201 ) || (F & FM[(op - 192 ) / 8 ]) == FE[(op - 192 ) / 8 ];  
 
    
    
     
 
    
    
          OP5_FLAG (192 , 201 )  
 
    
    
          RET:  
 
    
    
            T ();  
 
    
    
            if  (fc)  
 
    
    
              PC = r16 (SP);  
 
    
    
            break ;  
 
    
    
          case  193 :  
 
    
    
          case  193  + 16 :  
 
    
    
          case  193  + 32 :  
 
    
    
          case  193  + 48 :  
 
    
    
            RR[(op - 193 ) >> 4 ] = r16 (SP);  
 
    
    
            break ;  
 
    
    
          case  194 :  
 
    
    
          case  194  + 8 :  
 
    
    
          case  194  + 16 :  
 
    
    
          case  194  + 24 :  
 
    
    
          case  195 :  
 
    
    
            fc = (op == 195 ) || (F & FM[(op - 194 ) / 8 ]) == FE[(op - 194 ) / 8 ];  
 
    
    
            U = r16 ();  
 
    
    
            if  (fc)  
 
    
    
              PC = U, T ();  
 
    
    
            break ;  
 
    
    
          case  196 :  
 
    
    
          case  196  + 8 :  
 
    
    
          case  196  + 16 :  
 
    
    
          case  196  + 24 :  
 
    
    
          case  205 :  
 
    
    
            fc = (op == 205 ) || (F & FM[(op - 196 ) / 8 ]) == FE[(op - 196 ) / 8 ];  
 
    
    
            U = r16 ();  
 
    
    
          CALLU:  
 
    
    
            if  (fc)  
 
    
    
              push (PC), PC = U;  
 
    
    
            break ;  
 
    
    
          case  197 :  
 
    
    
          case  197  + 16 :  
 
    
    
          case  197  + 32 :  
 
    
    
          case  197  + 48 :  
 
    
    
            push (RR[(op - 197 ) >> 4 ]);  
 
    
    
            tick ();  
 
    
    
            if  (carry)  
 
    
    
              PC = read16 (SP);  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP4_NX16_REL (193 )  
 
    
    
            reg16[opcode_rel >> 4 ] = read16 (SP);  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP5_FLAG (194 , 195 )  
 
    
    
            temp16 = read16 ();  
 
    
    
            if  (carry)  
 
    
    
              PC = temp16, tick ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP5_FLAG (196 , 205 )  
 
    
    
            temp16 = read16 ();  
 
    
    
          CALL:  
 
    
    
            if  (carry)  
 
    
    
              push (PC), PC = temp16;  
 
    
    
            break ;  
 
    
    
     
 
    
    
          OP4_NX16_REL (197 )  
 
    
    
            push (reg16[opcode_rel >> 4 ]);  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  203 :  
 
    
    
            switch  ((op = r8 ())) {  
 
    
    
            case  7 :  
 
    
    
              A += A + (fc = (A >> 7 ) & 1 );  
 
    
    
              FS (0 , A, 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  8 :  
 
    
    
            case  8  + 1 :  
 
    
    
            case  8  + 2 :  
 
    
    
            case  8  + 3 :  
 
    
    
            case  8  + 4 :  
 
    
    
            case  8  + 5 :  
 
    
    
            case  8  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              *p = (fc = *p & 1 ) * 128  + *p / 2 ;  
 
    
    
              FS (0 , *p, 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  14 :  
 
    
    
              u = r (HL);  
 
    
    
              fc = u & 1 ;  
 
    
    
              u = fc * 128  + u / 2 ;  
 
    
    
              FS (0 , u, 0 , 0 , fc);  
 
    
    
              w (HL, u);  
 
    
    
              break ;  
 
    
    
            case  16 :  
 
    
    
            case  16  + 1 :  
 
    
    
            case  16  + 2 :  
 
    
    
            case  16  + 3 :  
 
    
    
            case  16  + 4 :  
 
    
    
            case  16  + 5 :  
 
    
    
            case  16  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              fc = *p >> 7 ;  
 
    
    
              FS (0 , *p = *p * 2  + (F >> 4 ) % 2 , 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  24 :  
 
    
    
            case  24  + 1 :  
 
    
    
            case  24  + 2 :  
 
    
    
            case  24  + 3 :  
 
    
    
            case  24  + 4 :  
 
    
    
            case  24  + 5 :  
 
    
    
            case  24  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              fc = *p & 1 ;  
 
    
    
              FS (0 , *p = *p / 2  + ((F * 8 ) & 128 ), 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  32 :  
 
    
    
            case  32  + 1 :  
 
    
    
            case  32  + 2 :  
 
    
    
            case  32  + 3 :  
 
    
    
            case  32  + 4 :  
 
    
    
            case  32  + 5 :  
 
    
    
            case  32  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              fc = (*p >> 7 ) & 1 ;  
 
    
    
              FS (0 , *p *= 2 , 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  40 :  
 
    
    
            case  40  + 1 :  
 
    
    
            case  40  + 2 :  
 
    
    
            case  40  + 3 :  
 
    
    
            case  40  + 4 :  
 
    
    
            case  40  + 5 :  
 
    
    
            case  40  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              fc = *p & 1 ;  
 
    
    
              FS (0 , *p = (s8)*p >> 1 , 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  48 :  
 
    
    
            case  48  + 1 :  
 
    
    
            case  48  + 2 :  
 
    
    
            case  48  + 3 :  
 
    
    
            case  48  + 4 :  
 
    
    
            case  48  + 5 :  
 
    
    
            case  48  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              FS (0 , *p = *p * 16  + *p / 16 , 0 , 0 , 0 );  
 
    
    
              break ;  
 
    
    
            case  54 :  
 
    
    
              u = r (HL);  
 
    
    
              FS (0 , u = u * 16  + u / 16 , 0 , 0 , 0 );  
 
    
    
              w (HL, u);  
 
    
    
              break ;  
 
    
    
            case  56 :  
 
    
    
            case  56  + 1 :  
 
    
    
            case  56  + 2 :  
 
    
    
            case  56  + 3 :  
 
    
    
            case  56  + 4 :  
 
    
    
            case  56  + 5 :  
 
    
    
            case  56  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              fc = *p & 1 ;  
 
    
    
              FS (0 , *p /= 2 , 0 , 0 , fc);  
 
    
    
              break ;  
 
    
    
            case  70 :  
 
    
    
            case  70  + 8 :  
 
    
    
            case  70  + 16 :  
 
    
    
            case  70  + 24 :  
 
    
    
            case  70  + 32 :  
 
    
    
            case  70  + 32  + 8 :  
 
    
    
            case  70  + 32  + 16 :  
 
    
    
            case  70  + 32  + 24 :  
 
    
    
              u = r (HL);  
 
    
    
              goto  BITU;  
 
    
    
            case  64 :  
 
    
    
            case  64  + 8 :  
 
    
    
            case  64  + 16 :  
 
    
    
            case  64  + 24 :  
 
    
    
            case  64  + 32 :  
 
    
    
            case  64  + 40 :  
 
    
    
            case  64  + 56 :  
 
    
    
            case  64  + 1 :  
 
    
    
            case  64  + 1  + 8 :  
 
    
    
            case  64  + 1  + 16 :  
 
    
    
            case  64  + 1  + 24 :  
 
    
    
            case  64  + 1  + 32 :  
 
    
    
            case  64  + 1  + 40 :  
 
    
    
            case  64  + 1  + 56 :  
 
    
    
            case  64  + 2 :  
 
    
    
            case  64  + 2  + 8 :  
 
    
    
            case  64  + 2  + 16 :  
 
    
    
            case  64  + 2  + 24 :  
 
    
    
            case  64  + 2  + 32 :  
 
    
    
            case  64  + 2  + 40 :  
 
    
    
            case  64  + 2  + 56 :  
 
    
    
            case  64  + 3 :  
 
    
    
            case  64  + 3  + 8 :  
 
    
    
            case  64  + 3  + 16 :  
 
    
    
            case  64  + 3  + 24 :  
 
    
    
            case  64  + 3  + 32 :  
 
    
    
            case  64  + 3  + 40 :  
 
    
    
            case  64  + 3  + 56 :  
 
    
    
            case  64  + 4 :  
 
    
    
            case  64  + 4  + 8 :  
 
    
    
            case  64  + 4  + 16 :  
 
    
    
            case  64  + 4  + 24 :  
 
    
    
            case  64  + 4  + 32 :  
 
    
    
            case  64  + 4  + 40 :  
 
    
    
            case  64  + 4  + 56 :  
 
    
    
            case  64  + 5 :  
 
    
    
            case  64  + 5  + 8 :  
 
    
    
            case  64  + 5  + 16 :  
 
    
    
            case  64  + 5  + 24 :  
 
    
    
            case  64  + 5  + 32 :  
 
    
    
            case  64  + 5  + 40 :  
 
    
    
            case  64  + 5  + 56 :  
 
    
    
            case  64  + 7 :  
 
    
    
            case  64  + 7  + 8 :  
 
    
    
            case  64  + 7  + 16 :  
 
    
    
            case  64  + 7  + 24 :  
 
    
    
            case  64  + 7  + 32 :  
 
    
    
            case  64  + 7  + 40 :  
 
    
    
            case  64  + 7  + 56 :  
 
    
    
            case  64  + 48 :  
 
    
    
            case  64  + 48  + 1 :  
 
    
    
            case  64  + 48  + 2 :  
 
    
    
            case  64  + 48  + 3 :  
 
    
    
            case  64  + 48  + 4 :  
 
    
    
            case  64  + 48  + 5 :  
 
    
    
            case  64  + 48  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              u = *p;  
 
    
    
            BITU:  
 
    
    
              FS (16 , u & (1  << ((op - 64 ) / 8 )), 0 , 1 , 0 );  
 
    
    
              break ;  
 
    
    
            case  134 :  
 
    
    
            case  134  + 8 :  
 
    
    
            case  134  + 16 :  
 
    
    
            case  134  + 24 :  
 
    
    
            case  134  + 32 :  
 
    
    
            case  134  + 32  + 8 :  
 
    
    
            case  134  + 32  + 16 :  
 
    
    
            case  134  + 32  + 24 :  
 
    
    
              w (HL, r (HL) & ~(1  << ((op - 134 ) / 8 )));  
 
    
    
              break ;  
 
    
    
            case  128 :  
 
    
    
            case  128  + 8 :  
 
    
    
            case  128  + 16 :  
 
    
    
            case  128  + 24 :  
 
    
    
            case  128  + 32 :  
 
    
    
            case  128  + 40 :  
 
    
    
            case  128  + 56 :  
 
    
    
            case  128  + 1 :  
 
    
    
            case  128  + 1  + 8 :  
 
    
    
            case  128  + 1  + 16 :  
 
    
    
            case  128  + 1  + 24 :  
 
    
    
            case  128  + 1  + 32 :  
 
    
    
            case  128  + 1  + 40 :  
 
    
    
            case  128  + 1  + 56 :  
 
    
    
            case  128  + 2 :  
 
    
    
            case  128  + 2  + 8 :  
 
    
    
            case  128  + 2  + 16 :  
 
    
    
            case  128  + 2  + 24 :  
 
    
    
            case  128  + 2  + 32 :  
 
    
    
            case  128  + 2  + 40 :  
 
    
    
            case  128  + 2  + 56 :  
 
    
    
            case  128  + 3 :  
 
    
    
            case  128  + 3  + 8 :  
 
    
    
            case  128  + 3  + 16 :  
 
    
    
            case  128  + 3  + 24 :  
 
    
    
            case  128  + 3  + 32 :  
 
    
    
            case  128  + 3  + 40 :  
 
    
    
            case  128  + 3  + 56 :  
 
    
    
            case  128  + 4 :  
 
    
    
            case  128  + 4  + 8 :  
 
    
    
            case  128  + 4  + 16 :  
 
    
    
            case  128  + 4  + 24 :  
 
    
    
            case  128  + 4  + 32 :  
 
    
    
            case  128  + 4  + 40 :  
 
    
    
            case  128  + 4  + 56 :  
 
    
    
            case  128  + 5 :  
 
    
    
            case  128  + 5  + 8 :  
 
    
    
            case  128  + 5  + 16 :  
 
    
    
            case  128  + 5  + 24 :  
 
    
    
            case  128  + 5  + 32 :  
 
    
    
            case  128  + 5  + 40 :  
 
    
    
            case  128  + 5  + 56 :  
 
    
    
            case  128  + 7 :  
 
    
    
            case  128  + 7  + 8 :  
 
    
    
            case  128  + 7  + 16 :  
 
    
    
            case  128  + 7  + 24 :  
 
    
    
            case  128  + 7  + 32 :  
 
    
    
            case  128  + 7  + 40 :  
 
    
    
            case  128  + 7  + 56 :  
 
    
    
            case  128  + 48 :  
 
    
    
            case  128  + 48  + 1 :  
 
    
    
            case  128  + 48  + 2 :  
 
    
    
            case  128  + 48  + 3 :  
 
    
    
            case  128  + 48  + 4 :  
 
    
    
            case  128  + 48  + 5 :  
 
    
    
            case  128  + 48  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              *p &= ~(1  << ((op - 128 ) / 8 ));  
 
    
    
              break ;  
 
    
    
            case  198 :  
 
    
    
            case  198  + 8 :  
 
    
    
            case  198  + 16 :  
 
    
    
            case  198  + 24 :  
 
    
    
            case  198  + 32 :  
 
    
    
            case  198  + 32  + 8 :  
 
    
    
            case  198  + 32  + 16 :  
 
    
    
            case  198  + 32  + 24 :  
 
    
    
              w (HL, r (HL) | (1  << ((op - 198 ) / 8 )));  
 
    
    
              break ;  
 
    
    
            case  192 :  
 
    
    
            case  192  + 8 :  
 
    
    
            case  192  + 16 :  
 
    
    
            case  192  + 24 :  
 
    
    
            case  192  + 32 :  
 
    
    
            case  192  + 40 :  
 
    
    
            case  192  + 56 :  
 
    
    
            case  192  + 1 :  
 
    
    
            case  192  + 1  + 8 :  
 
    
    
            case  192  + 1  + 16 :  
 
    
    
            case  192  + 1  + 24 :  
 
    
    
            case  192  + 1  + 32 :  
 
    
    
            case  192  + 1  + 40 :  
 
    
    
            case  192  + 1  + 56 :  
 
    
    
            case  192  + 2 :  
 
    
    
            case  192  + 2  + 8 :  
 
    
    
            case  192  + 2  + 16 :  
 
    
    
            case  192  + 2  + 24 :  
 
    
    
            case  192  + 2  + 32 :  
 
    
    
            case  192  + 2  + 40 :  
 
    
    
            case  192  + 2  + 56 :  
 
    
    
            case  192  + 3 :  
 
    
    
            case  192  + 3  + 8 :  
 
    
    
            case  192  + 3  + 16 :  
 
    
    
            case  192  + 3  + 24 :  
 
    
    
            case  192  + 3  + 32 :  
 
    
    
            case  192  + 3  + 40 :  
 
    
    
            case  192  + 3  + 56 :  
 
    
    
            case  192  + 4 :  
 
    
    
            case  192  + 4  + 8 :  
 
    
    
            case  192  + 4  + 16 :  
 
    
    
            case  192  + 4  + 24 :  
 
    
    
            case  192  + 4  + 32 :  
 
    
    
            case  192  + 4  + 40 :  
 
    
    
            case  192  + 4  + 56 :  
 
    
    
            case  192  + 5 :  
 
    
    
            case  192  + 5  + 8 :  
 
    
    
            case  192  + 5  + 16 :  
 
    
    
            case  192  + 5  + 24 :  
 
    
    
            case  192  + 5  + 32 :  
 
    
    
            case  192  + 5  + 40 :  
 
    
    
            case  192  + 5  + 56 :  
 
    
    
            case  192  + 7 :  
 
    
    
            case  192  + 7  + 8 :  
 
    
    
            case  192  + 7  + 16 :  
 
    
    
            case  192  + 7  + 24 :  
 
    
    
            case  192  + 7  + 32 :  
 
    
    
            case  192  + 7  + 40 :  
 
    
    
            case  192  + 7  + 56 :  
 
    
    
            case  192  + 48 :  
 
    
    
            case  192  + 48  + 1 :  
 
    
    
            case  192  + 48  + 2 :  
 
    
    
            case  192  + 48  + 3 :  
 
    
    
            case  192  + 48  + 4 :  
 
    
    
            case  192  + 48  + 5 :  
 
    
    
            case  192  + 48  + 7 :  
 
    
    
              p = R8[op & 7 ];  
 
    
    
              *p |= 1  << ((op - 192 ) / 8 );  
 
    
    
              break ;  
 
    
    
            default :  
 
    
    
              return  op;  
 
    
    
            switch  (opcode = read8_pc ()) {  
 
    
    
              OP7_PTR (0 )  
 
    
    
                *ptr8 += *ptr8 + (carry = *ptr8 / 128  % 2 );  
 
    
    
                goto  CARRY_ZERO_FLAGS_PTR;  
 
    
    
     
 
    
    
              OP7_PTR (8 )  
 
    
    
                *ptr8 = (carry = *ptr8 & 1 ) * 128  + *ptr8 / 2 ;  
 
    
    
                goto  CARRY_ZERO_FLAGS_PTR;  
 
    
    
     
 
    
    
              case  14 :  
 
    
    
                tmp8 = read8 ();  
 
    
    
                carry = tmp8 & 1 ;  
 
    
    
                write8 (tmp8 = carry * 128  + tmp8 / 2 );  
 
    
    
                goto  CARRY_ZERO_FLAGS_U;  
 
    
    
     
 
    
    
              OP7_PTR (16 )  
 
    
    
                carry = *ptr8 >> 7 ;  
 
    
    
                *ptr8 = *ptr8 * 2  + F / 16  % 2 ;  
 
    
    
                goto  CARRY_ZERO_FLAGS_PTR;  
 
    
    
     
 
    
    
              OP7_PTR (24 )  
 
    
    
                carry = *ptr8 & 1 ;  
 
    
    
                *ptr8 = *ptr8 / 2  + ((F * 8 ) & 128 );  
 
    
    
                goto  CARRY_ZERO_FLAGS_PTR;  
 
    
    
     
 
    
    
              OP7_PTR (32 )  
 
    
    
                carry = *ptr8 / 128  % 2 ;  
 
    
    
                *ptr8 *= 2 ;  
 
    
    
                goto  CARRY_ZERO_FLAGS_PTR;  
 
    
    
     
 
    
    
              OP7_PTR (40 )  
 
    
    
                carry = *ptr8 & 1 ;  
 
    
    
                *ptr8 = (int8_t )*ptr8 >> 1 ;  
 
    
    
                goto  CARRY_ZERO_FLAGS_PTR;  
 
    
    
     
 
    
    
              OP7_PTR (48 )  
 
    
    
                set_flags (0 , *ptr8 = *ptr8 * 16  + *ptr8 / 16 , 0 , 0 , 0 );  
 
    
    
                break ;  
 
    
    
     
 
    
    
              case  54 :  
 
    
    
                tmp8 = read8 ();  
 
    
    
                carry = 0 ;  
 
    
    
                write8 (tmp8 = tmp8 * 16  + tmp8 / 16 );  
 
    
    
              CARRY_ZERO_FLAGS_U:  
 
    
    
                set_flags (0 , tmp8, 0 , 0 , carry);  
 
    
    
                break ;  
 
    
    
     
 
    
    
              OP7_PTR (56 )  
 
    
    
                carry = *ptr8 & 1 ;  
 
    
    
                *ptr8 /= 2 ;  
 
    
    
              CARRY_ZERO_FLAGS_PTR:  
 
    
    
                set_flags (0 , *ptr8, 0 , 0 , carry);  
 
    
    
                break ;  
 
    
    
     
 
    
    
              OP8_NX8_REL (70 )  
 
    
    
                tmp8 = read8 ();  
 
    
    
                goto  BIT_FLAGS;  
 
    
    
     
 
    
    
              OP56_PTR_REL (64 )  
 
    
    
                tmp8 = *ptr8;  
 
    
    
              BIT_FLAGS:  
 
    
    
                set_flags (16 , tmp8 & (1  << opcode_rel / 8 ), 0 , 1 , 0 );  
 
    
    
                break ;  
 
    
    
     
 
    
    
              OP8_NX8_REL (134 )  
 
    
    
                write8 (read8 () & ~(1  << opcode_rel / 8 ));  
 
    
    
                break ;  
 
    
    
     
 
    
    
              OP56_PTR_REL (128 )  
 
    
    
                *ptr8 &= ~(1  << opcode_rel / 8 );  
 
    
    
                break ;  
 
    
    
     
 
    
    
              OP8_NX8_REL (198 )  
 
    
    
                write8 (read8 () | (1  << opcode_rel / 8 ));  
 
    
    
                break ;  
 
    
    
     
 
    
    
              OP56_PTR_REL (192 )  
 
    
    
                *ptr8 |= 1  << opcode_rel / 8 ;  
 
    
    
                break ;  
 
    
    
            }  
 
    
    
            break ;  
 
    
    
           case   224 :  
 
    
    
          case  226 :  
 
    
    
            w ( 65280  + (op  == 224  ? r8 () : R[ 0 ]), A );  
 
    
    
     
 
    
    
          case  224 :  case   226 :  
 
    
    
            write8 (A,  65280  + (opcode  == 224  ? read8_pc () : *reg8) );  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  233 :  
 
    
    
            PC = HL;  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  234 :  
 
    
    
            w ( r16 (), A );  
 
    
    
            write8 (A,  read16 () );  
 
    
    
            break ;  
 
    
    
          case  240 :  
 
    
    
            A = r (65280  | r8 ());  
 
    
    
     
 
    
    
          case  240 : case  250 :  
 
    
    
            A = read8 (opcode == 240  ? 65280  | read8_pc () : read16 ());  
 
    
    
            break ;  
 
    
    
           case   243 :  
 
    
    
          case  251 :  
 
    
    
            IME = op  != 243 ;  
 
    
    
     
 
    
    
          case  243 :  case   251 :  
 
    
    
            IME = opcode  != 243 ;  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  248 :  
 
    
    
            u  = r8 ();  
 
    
    
            FS (0 , 1 , 0 , (u8 )SP + u  > 255 , SP % 16  + u  % 16  > 15 );  
 
    
    
            HL = SP + (s8)u ;  
 
    
    
            T ();  
 
    
    
            tmp8  = read8_pc ();  
 
    
    
            set_flags (0 , 1 , 0 , (uint8_t )SP + tmp8  > 255 , SP % 16  + tmp8  % 16  > 15 );  
 
    
    
            HL = SP + (int8_t )tmp8 ;  
 
    
    
            tick ();  
 
    
    
            break ;  
 
    
    
     
 
    
    
          case  249 :  
 
    
    
            SP = HL;  
 
    
    
            T ();  
 
    
    
            break ;  
 
    
    
          case  250 :  
 
    
    
            A = r (r16 ());  
 
    
    
            tick ();  
 
    
    
            break ;  
 
    
    
          default :  
 
    
    
            return  op;  
 
    
    
          }  
 
    
    
        for  (DIV += cy - bcy; bcy++ < cy;)  
 
    
    
     
 
    
    
        for  (DIV += cycles - prev_cycles; prev_cycles++ != cycles;)  
 
    
    
          if  (LCDC & 128 ) {  
 
    
    
            if  (++dot  == 1  && LY == 144 )  
 
    
    
            if  (++ppu_dot  == 1  && LY == 144 )  
 
    
    
              IF |= 1 ;  
 
    
    
            if  (dot == 456 ) {  
 
    
    
     
 
    
    
            if  (ppu_dot == 456 ) {  
 
    
    
              if  (LY < 144 )  
 
    
    
                for  (int  x = 160 ; --x >= 0 ;) {  
 
    
    
                  u16  win = LCDC & 32  && LY >= WY && x >= WX - 7 ,  
 
    
    
                      base = (LCDC & (win ? 64  : 8 ) ? 7  : 6 ) << 10 ;  
 
    
    
                  u8  mx = win ? x - WX + 7  : x + io[323 ],  
 
    
    
                     my = win ? LY - WY : LY + io[322 ];  
 
    
    
                  u16  tile = vram[base + my / 8  * 32  + mx / 8 ], p = 327 ;  
 
    
    
                  mx = (mx ^ 7 ) & 7 ;  
 
    
    
                  u8  *d = &vram[(LCDC & 16  ? tile : 256  + (s8)tile) * 16  +  
 
    
    
                                (my & 7 ) * 2 ];  
 
    
    
                  u8  c = (d[1 ] >> mx) % 2  * 2  + (d[0 ] >> mx) % 2 ;  
 
    
    
                for  (tmp = 160 ; --tmp >= 0 ;) {  
 
    
    
                  uint8_t  is_window =  
 
    
    
                              LCDC & 32  && LY >= io[330 ] && tmp >= io[331 ] - 7 ,  
 
    
    
                          x_offset = is_window ? tmp - io[331 ] + 7  : tmp + io[323 ],  
 
    
    
                          y_offset = is_window ? LY - io[330 ] : LY + io[322 ];  
 
    
    
                  uint16_t  tile = video_ram[((LCDC & (is_window ? 64  : 8 ) ? 7  : 6 )  
 
    
    
                                             << 10 ) +  
 
    
    
                                            y_offset / 8  * 32  + x_offset / 8 ],  
 
    
    
                           palette_index = 0 ;  
 
    
    
     
 
    
    
                  x_offset = (x_offset ^ 7 ) & 7 ;  
 
    
    
     
 
    
    
                  uint8_t   
 
    
    
                      *tile_data =  
 
    
    
                          &video_ram[(LCDC & 16  ? tile : 256  + (int8_t )tile) * 16  +  
 
    
    
                                     y_offset % 8  * 2 ],  
 
    
    
                      color = (tile_data[1 ] >> x_offset) % 2  * 2  +  
 
    
    
                              (*tile_data >> x_offset) % 2 ;  
 
    
    
     
 
    
    
                  if  (LCDC & 2 )  
 
    
    
                    for  (u8  *o = io; o < io + 160 ; o += 4 ) {  
 
    
    
                      u8  dx = x - o[1 ] + 8 , dy = LY - o[0 ] + 16 ;  
 
    
    
                      if  (dx < 8  && dy < 8 ) {  
 
    
    
                        dx ^= o[3 ] & 32  ? 0  : 7 ;  
 
    
    
                        d = &vram[o[2 ] * 16  + (dy ^ (o[3 ] & 64  ? 7  : 0 )) * 2 ];  
 
    
    
                        u8  nc = (d[1 ] >> dx) % 2  * 2  + (d[0 ] >> dx) % 2 ;  
 
    
    
                        if  (!((o[3 ] & 128 ) && c) && nc) {  
 
    
    
                          c = nc;  
 
    
    
                          p += 1  + !!(o[3 ] & 8 );  
 
    
    
                    for  (uint8_t  *sprite = io; sprite < io + 160 ; sprite += 4 ) {  
 
    
    
                      uint8_t  sprite_x = tmp - sprite[1 ] + 8 ,  
 
    
    
                              sprite_y = LY - *sprite + 16 ;  
 
    
    
                      if  (sprite_x < 8  && sprite_y < 8 ) {  
 
    
    
                        sprite_x ^= sprite[3 ] & 32  ? 0  : 7 ;  
 
    
    
     
 
    
    
                        tile_data =  
 
    
    
                            &video_ram[sprite[2 ] * 16  +  
 
    
    
                                       (sprite_y ^ (sprite[3 ] & 64  ? 7  : 0 )) * 2 ];  
 
    
    
                        uint8_t  sprite_color = (tile_data[1 ] >> sprite_x) % 2  * 2  +  
 
    
    
                                               (*tile_data >> sprite_x) % 2 ;  
 
    
    
     
 
    
    
                        if  (!((sprite[3 ] & 128 ) && color) && sprite_color) {  
 
    
    
                          color = sprite_color;  
 
    
    
                          palette_index += 1  + !!(sprite[3 ] & 8 );  
 
    
    
                          break ;  
 
    
    
                        }  
 
    
    
                      }  
 
    
    
                    }  
 
    
    
                  fb[LY * 160  + x] = pal[(io[p] >> (2  * c)) & 3 ];  
 
    
    
     
 
    
    
                  frame_buffer[LY * 160  + tmp] =  
 
    
    
                      palette[(io[327  + palette_index] >> (2  * color)) % 4  +  
 
    
    
                              palette_index * 4 ];  
 
    
    
                }  
 
    
    
     
 
    
    
              if  (LY == 144 ) {  
 
    
    
                void  *pixels;  
 
    
    
                int  pitch ;  
 
    
    
                SDL_LockTexture (St,  0 , &pixels, &pitch);   
 
    
    
                for  ( int  y =  144 ; --y >=  0 ;)   
 
    
    
                  memcpy (( u8  *)pixels + y * pitch, fb + y *  160 ,  640 );  
 
    
    
                SDL_LockTexture (St,  0 , &pixels, &tmp) ;  
 
    
    
                for  (tmp2 =  144 ; --tmp2 >=  0 ;)   
 
    
    
                   memcpy (( uint8_t  *)pixels + tmp2 * tmp, frame_buffer + tmp2 *  160 ,   
 
    
    
                          640 );  
 
    
    
                SDL_UnlockTexture (St);  
 
    
    
                SDL_RenderCopy (Sr, St, 0 , 0 );  
 
    
    
                SDL_RenderPresent (Sr);  
 
    
    
                SDL_Delay (0 );  
 
    
    
                SDL_Event e;  
 
    
    
                while  (SDL_PollEvent (&e))  
 
    
    
                  if  (e.type  == SDL_QUIT)  
 
    
    
                    return  0 ;  
 
    
    
              }  
 
    
    
     
 
    
    
              LY = (LY + 1 ) % 154 ;  
 
    
    
              dot  = 0 ;  
 
    
    
              ppu_dot  = 0 ;  
 
    
    
            }  
 
    
    
          } else  {  
 
    
    
            LY = dot = 0 ;  
 
    
    
          }  
 
    
    
          } else   
 
    
    
            LY = ppu_dot = 0 ;  
 
    
    
      }  
 
    
    
    }  
 
    
    
    }