Dout

decompiled_code:
__int64 __fastcall Dout(int a1, int a2)
{
__int64 result; // rax
__int64 v3; // rdx

if ( a1 )
{
if ( a2 == 1 )
{
*(_DWORD *)pbdr_1 |= a1;
result = 0LL;
}
else if ( a2 )
{
puts("digital output error");
result = 0xFFFFFFFFLL;
}
else
{
*(_DWORD *)pbdr_1 &= ~a1;
result = 0LL;
}
}
else
{
v3 = start + 4LL;
*(_DWORD *)(start + 20LL) = 255;
result = 0LL;
pbdr_1 = v3;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, int a2)
{
__int64 result; // rax
__int64 v3; // rdx

if ( a1 )
{
if ( a2 == 1 )
{
*(_DWORD *)pbdr_1 |= a1;
result = 0LL;
}
else if ( a2 )
{
puts("digital output error");
result = 0xFFFFFFFFLL;
}
else
{
*(_DWORD *)pbdr_1 &= ~a1;
result = 0LL;
}
}
else
{
v3 = start + 4LL;
*(_DWORD *)(start + 20LL) = 255;
result = 0LL;
pbdr_1 = v3;
}
return result;
}

original_code:
int Dout(int pin, int state)
{
 static unsigned int *pbdr, *pbddr;
 if (pin == 0) {
  pbdr = (unsigned int *)(start + 0x04);
  pbddr = (unsigned int *)(start + 0x14);
  *pbddr = 0xFF;
  return 0;
 }
 if (state == 1) {
  *pbdr = (*pbdr | pin);
 } else if (state == 0) {
  *pbdr = (*pbdr & (~pin));
 } else {
  printf("digital output error\n");
  return -1;
 }
 return 0;
}

canonical_original_code:
int Dout(int pin, int state)
{
 static unsigned int *pbdr; static unsigned int *pbddr;
 if (pin == 0) {
  pbdr = (unsigned int *)(start + 0x04);
  pbddr = (unsigned int *)(start + 0x14);
  *pbddr = 0xFF;
  return 0;
 }
 if (state == 1) {
  *pbdr = (*pbdr | pin);
 } else if (state == 0) {
  *pbdr = (*pbdr & (~pin));
 } else {
  printf("digital output error\n");
  return -1;
 }
 return 0;
}

variable_types: pin int

variable_types: state int

variable_types:
pbdr
unsigned int *

variable_types:
pbddr
unsigned int *


PWM

repo: mmsi/dbes

decompiled_code:
__int64 __fastcall PWM(unsigned __int8 a1, int a2)
{
__int64 result; // rax
int v3; // eax
__int64 v4; // rdx
unsigned __int16 v5; // di

if ( a2 == 1 )
{
*(_BYTE *)pwm_high_lsb_1 = 0;
*(_BYTE *)pwm_msbs_2 = 15;
*(_BYTE *)pwm_low_lsb_0 = -1;
*(_BYTE *)xdio_mode_3 &= 0xFDu;
result = 0LL;
}
else if ( a2 == 2 )
{
v5 = 16 * a1;
*(_BYTE *)pwm_high_lsb_1 = v5;
*(_BYTE *)pwm_msbs_2 = ((unsigned __int16)(4095 - v5) >> 8) | ((int)v5 >> 4) & 0xF0;
*(_BYTE *)pwm_low_lsb_0 = ~(_BYTE)v5;
*(_BYTE *)xdio_mode_3 |= 2u;
result = 0LL;
}
else if ( a2 )
{
result = 0LL;
}
else
{
v3 = getpagesize();
xdio_mode_3 = (__int64)mmap(0LL, v3, 3, 1, devmem, 314572800LL);
pwm_msbs_2 = xdio_mode_3 + 1;
pwm_high_lsb_1 = xdio_mode_3 + 2;
v4 = xdio_mode_3 + 3;
*(_BYTE *)xdio_mode_3 = -63;
result = 0LL;
pwm_low_lsb_0 = v4;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned __int8 a1, int a2)
{
__int64 result; // rax
int v3; // eax
__int64 v4; // rdx
unsigned __int16 v5; // di

if ( a2 == 1 )
{
*(_BYTE *)pwm_high_lsb_1 = 0;
*(_BYTE *)pwm_msbs_2 = 15;
*(_BYTE *)pwm_low_lsb_0 = -1;
*(_BYTE *)xdio_mode_3 &= 0xFDu;
result = 0LL;
}
else if ( a2 == 2 )
{
v5 = 16 * a1;
*(_BYTE *)pwm_high_lsb_1 = v5;
*(_BYTE *)pwm_msbs_2 = ((unsigned __int16)(4095 - v5) >> 8) | ((int)v5 >> 4) & 0xF0;
*(_BYTE *)pwm_low_lsb_0 = ~(_BYTE)v5;
*(_BYTE *)xdio_mode_3 |= 2u;
result = 0LL;
}
else if ( a2 )
{
result = 0LL;
}
else
{
v3 = getpagesize();
xdio_mode_3 = (__int64)mmap(0LL, v3, 3, 1, devmem, 314572800LL);
pwm_msbs_2 = xdio_mode_3 + 1;
pwm_high_lsb_1 = xdio_mode_3 + 2;
v4 = xdio_mode_3 + 3;
*(_BYTE *)xdio_mode_3 = -63;
result = 0LL;
pwm_low_lsb_0 = v4;
}
return result;
}

original_code:
int PWM(unsigned char rate, int mode)
{
 static unsigned char *xdio_mode, *pwm_msbs, *pwm_high_lsb, *pwm_low_lsb;
 unsigned char *start;
 unsigned short rate_s;
 switch (mode) {
  case 0:
   start = mmap(0, getpagesize(), 0x1|0x2, 0x01,
       devmem, 0x12C00000);
   xdio_mode = (start + 0);
   pwm_msbs = (start + 1);
   pwm_high_lsb = (start + 2);
   pwm_low_lsb = (start + 3);
   *xdio_mode = 0xC1;
   break;
  case 1:
   *pwm_high_lsb = 0x00;
   *pwm_msbs = 0x0F;
   *pwm_low_lsb = 0xFF;
   *xdio_mode = (*xdio_mode & 0xFD);
   break;
  case 2:
   rate_s = ((unsigned short)rate * 16);
   *pwm_high_lsb = (char)(rate_s & 0xFF);
   *pwm_msbs = (char)(((rate_s & 0xF00) >> 4)+(((0xFFF - rate_s) & 0xF00) >> 8));
   *pwm_low_lsb = (char)((0xFFF - rate_s) & 0xFF);
   *xdio_mode = (*xdio_mode | 0x2);
 }
 return 0;
}

canonical_original_code:
int PWM(unsigned char rate, int mode)
{
 static unsigned char *xdio_mode; static unsigned char *pwm_msbs; static unsigned char *pwm_high_lsb; static unsigned char *pwm_low_lsb;
 unsigned char *start;
 unsigned short rate_s;
 switch (mode) {
  case 0:
   start = mmap(0, getpagesize(), 0x1|0x2, 0x01,
       devmem, 0x12C00000);
   xdio_mode = (start + 0);
   pwm_msbs = (start + 1);
   pwm_high_lsb = (start + 2);
   pwm_low_lsb = (start + 3);
   *xdio_mode = 0xC1;
   break;
  case 1:
   *pwm_high_lsb = 0x00;
   *pwm_msbs = 0x0F;
   *pwm_low_lsb = 0xFF;
   *xdio_mode = (*xdio_mode & 0xFD);
   break;
  case 2:
   rate_s = ((unsigned short)rate * 16);
   *pwm_high_lsb = (char)(rate_s & 0xFF);
   *pwm_msbs = (char)(((rate_s & 0xF00) >> 4)+(((0xFFF - rate_s) & 0xF00) >> 8));
   *pwm_low_lsb = (char)((0xFFF - rate_s) & 0xFF);
   *xdio_mode = (*xdio_mode | 0x2);
 }
 return 0;
}

variable_types:
rate
unsigned char

variable_types: mode int

variable_types:
start
unsigned char *

return_type: int


repo: mncoppola/cardamine

decompiled_code:
__m128i *enable_bootROM()
{
__m128i *result; // rax

result = (__m128i *)mem_base;
tmp_storage = (__int128)_mm_loadu_si128((const __m128i *)mem_base);
*(&tmp_storage + 1) = (__int128)_mm_loadu_si128((const __m128i *)mem_base + 1);
*(&tmp_storage + 2) = (__int128)_mm_loadu_si128(result + 2);
*(&tmp_storage + 3) = (__int128)_mm_loadu_si128(result + 3);
*(&tmp_storage + 4) = (__int128)_mm_loadu_si128(result + 4);
*(&tmp_storage + 5) = (__int128)_mm_loadu_si128(result + 5);
*(&tmp_storage + 6) = (__int128)_mm_loadu_si128(result + 6);
*(&tmp_storage + 7) = (__int128)_mm_loadu_si128(result + 7);
*(&tmp_storage + 8) = (__int128)_mm_loadu_si128(result + 8);
*(&tmp_storage + 9) = (__int128)_mm_loadu_si128(result + 9);
*(&tmp_storage + 10) = (__int128)_mm_loadu_si128(result + 10);
*(&tmp_storage + 11) = (__int128)_mm_loadu_si128(result + 11);
*(&tmp_storage + 12) = (__int128)_mm_loadu_si128(result + 12);
*(&tmp_storage + 13) = (__int128)_mm_loadu_si128(result + 13);
*(&tmp_storage + 14) = (__int128)_mm_loadu_si128(result + 14);
*(&tmp_storage + 15) = (__int128)_mm_loadu_si128(result + 15);
*result = _mm_load_si128(gb_boot_rom);
result[1] = _mm_load_si128(&gb_boot_rom[1]);
result[2] = _mm_load_si128(&gb_boot_rom[2]);
result[3] = _mm_load_si128(&gb_boot_rom[3]);
result[4] = _mm_load_si128(&gb_boot_rom[4]);
result[5] = _mm_load_si128(&gb_boot_rom[5]);
result[6] = _mm_load_si128(&gb_boot_rom[6]);
result[7] = _mm_load_si128(&gb_boot_rom[7]);
result[8] = _mm_load_si128(&gb_boot_rom[8]);
result[9] = _mm_load_si128(&gb_boot_rom[9]);
result[10] = _mm_load_si128(&gb_boot_rom[10]);
result[11] = _mm_load_si128(&gb_boot_rom[11]);
result[12] = _mm_load_si128(&gb_boot_rom[12]);
result[13] = _mm_load_si128(&gb_boot_rom[13]);
result[14] = _mm_load_si128(&gb_boot_rom[14]);
result[15] = _mm_load_si128(&gb_boot_rom[15]);
return result;
}

canonical_decompiled_code:
__m128i *func0()
{
__m128i *result; // rax

result = (__m128i *)mem_base;
tmp_storage = (__int128)_mm_loadu_si128((const __m128i *)mem_base);
*(&tmp_storage + 1) = (__int128)_mm_loadu_si128((const __m128i *)mem_base + 1);
*(&tmp_storage + 2) = (__int128)_mm_loadu_si128(result + 2);
*(&tmp_storage + 3) = (__int128)_mm_loadu_si128(result + 3);
*(&tmp_storage + 4) = (__int128)_mm_loadu_si128(result + 4);
*(&tmp_storage + 5) = (__int128)_mm_loadu_si128(result + 5);
*(&tmp_storage + 6) = (__int128)_mm_loadu_si128(result + 6);
*(&tmp_storage + 7) = (__int128)_mm_loadu_si128(result + 7);
*(&tmp_storage + 8) = (__int128)_mm_loadu_si128(result + 8);
*(&tmp_storage + 9) = (__int128)_mm_loadu_si128(result + 9);
*(&tmp_storage + 10) = (__int128)_mm_loadu_si128(result + 10);
*(&tmp_storage + 11) = (__int128)_mm_loadu_si128(result + 11);
*(&tmp_storage + 12) = (__int128)_mm_loadu_si128(result + 12);
*(&tmp_storage + 13) = (__int128)_mm_loadu_si128(result + 13);
*(&tmp_storage + 14) = (__int128)_mm_loadu_si128(result + 14);
*(&tmp_storage + 15) = (__int128)_mm_loadu_si128(result + 15);
*result = _mm_load_si128(gb_boot_rom);
result[1] = _mm_load_si128(&gb_boot_rom[1]);
result[2] = _mm_load_si128(&gb_boot_rom[2]);
result[3] = _mm_load_si128(&gb_boot_rom[3]);
result[4] = _mm_load_si128(&gb_boot_rom[4]);
result[5] = _mm_load_si128(&gb_boot_rom[5]);
result[6] = _mm_load_si128(&gb_boot_rom[6]);
result[7] = _mm_load_si128(&gb_boot_rom[7]);
result[8] = _mm_load_si128(&gb_boot_rom[8]);
result[9] = _mm_load_si128(&gb_boot_rom[9]);
result[10] = _mm_load_si128(&gb_boot_rom[10]);
result[11] = _mm_load_si128(&gb_boot_rom[11]);
result[12] = _mm_load_si128(&gb_boot_rom[12]);
result[13] = _mm_load_si128(&gb_boot_rom[13]);
result[14] = _mm_load_si128(&gb_boot_rom[14]);
result[15] = _mm_load_si128(&gb_boot_rom[15]);
return result;
}

original_code:
void enable_bootROM ( void )
{
    memcpy(tmp_storage, mem_base, 256);
    memcpy(mem_base, gb_boot_rom, 256);
}

canonical_original_code:
void enable_bootROM()
{
    memcpy(tmp_storage, mem_base, 256);
    memcpy(mem_base, gb_boot_rom, 256);
}

return_type: void


decompiled_code:
__int64 __fastcall init_rom(const char *a1)
{
int v1; // eax
int v2; // ebp

v1 = open(a1, 0);
if ( v1 < 0 )
{
perror("open");
exit(1);
}
v2 = v1;
lseek(v1, 0LL, 2);
lseek(v2, 0LL, 0);
read(v2, mem_base, 0x4000uLL);
enable_bootROM();
return disable_bootROM();
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1)
{
int v1; // eax
int v2; // ebp

v1 = open(a1, 0);
if ( v1 < 0 )
{
perror("open");
exit(1);
}
v2 = v1;
lseek(v1, 0LL, 2);
lseek(v2, 0LL, 0);
read(v2, mem_base, 0x4000uLL);
func0();
return func1();
}

original_code:
void init_rom ( char *rom_filename )
{
    int fd, rom_size;
    if ( (fd = open(rom_filename, 00)) < 0 )
    {
        perror("open");
        exit(1);
    }
    rom_size = lseek(fd, 0, 2);
    lseek(fd, 0, 0);
    read(fd, mem_base, 0x4000);
    enable_bootROM();
    disable_bootROM();
}

canonical_original_code:
void init_rom(char *rom_filename)
{
    int fd; int rom_size;
    if ( (fd = open(rom_filename, 00)) < 0 )
    {
        perror("open");
        exit(1);
    }
    rom_size = lseek(fd, 0, 2);
    lseek(fd, 0, 0);
    read(fd, mem_base, 0x4000);
    enable_bootROM();
    disable_bootROM();
}

variable_types: fd int


main

canonical_name: main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
init_mem(argc, argv, envp);
init_rom(argv[1]);
init_cpu();
init_interrupt();
init_audio();
init_video();
init_timer();
init_joypad();
init_serial();
while ( 1 )
{
exec_instruction();
check_interrupts();
cycle_video();
cycle_timer();
}
}

original_code:
int main ( int argc, char **argv )
{
    init_mem();
    init_rom(argv[1]);
    init_cpu();
    init_interrupt();
    init_audio();
    init_video();
    init_timer();
    init_joypad();
    init_serial();
    while ( 1 )
    {
        exec_instruction();
        check_interrupts();
        cycle_video();
        cycle_timer();
    }
    return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
    init_mem();
    init_rom(argv[1]);
    init_cpu();
    init_interrupt();
    init_audio();
    init_video();
    init_timer();
    init_joypad();
    init_serial();
    while ( 1 )
    {
        exec_instruction();
        check_interrupts();
        cycle_video();
        cycle_timer();
    }
    return 0;
}

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
__int64 check_coincidence()
{
__int64 result; // rax
char v1; // al

result = (unsigned __int8)lcd_LY_compare;
if ( lcd_line == lcd_LY_compare )
{
lcd_coincidence_flag = 1;
if ( LYC_LY_coincidence_interrupt )
{
v1 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v1 | 2));
}
}
else
{
lcd_coincidence_flag = 0;
}
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 result; // rax
char v1; // al

result = (unsigned __int8)lcd_LY_compare;
if ( lcd_line == lcd_LY_compare )
{
lcd_coincidence_flag = 1;
if ( LYC_LY_coincidence_interrupt )
{
v1 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v1 | 2));
}
}
else
{
lcd_coincidence_flag = 0;
}
return result;
}

original_code:
void check_coincidence ( void )
{
    if ( lcd_line == lcd_LY_compare )
    {
        lcd_coincidence_flag = 1;
        if ( LYC_LY_coincidence_interrupt )
            set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
    }
    else
    {
        lcd_coincidence_flag = 0;
    }
}

canonical_original_code:
void check_coincidence()
{
    if ( lcd_line == lcd_LY_compare )
    {
        lcd_coincidence_flag = 1;
        if ( LYC_LY_coincidence_interrupt )
            set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
    }
    else
    {
        lcd_coincidence_flag = 0;
    }
}


decompiled_code:
__int64 update_STAT()
{
__int64 result; // rax
char v1; // al
char v2; // al
char v3; // al
char v4; // al
char v5; // al

result = (unsigned int)(lcd_cycles + cpu_cycles);
lcd_cycles += cpu_cycles;
if ( lcd_mode_flag == 2 )
{
if ( (unsigned int)result > 0x4F )
{
result = (unsigned int)(result - 80);
lcd_mode_flag = 3;
lcd_cycles = result;
}
}
else if ( (unsigned __int8)lcd_mode_flag > 2u )
{
if ( lcd_mode_flag == 3 && (unsigned int)result > 0xAB )
{
lcd_mode_flag = 0;
if ( mode_0_H_Blank_interrupt )
{
v2 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(v2 | 2));
LODWORD(result) = lcd_cycles;
}
result = (unsigned int)(result - 172);
lcd_cycles = result;
}
}
else if ( lcd_mode_flag )
{
if ( (unsigned int)result > 0x1C7 )
{
++lcd_line;
check_coincidence();
result = (unsigned __int8)lcd_line;
if ( lcd_line == -102 )
{
lcd_line = 0;
}
else if ( lcd_line == 1 )
{
lcd_line = 0;
lcd_mode_flag = 2;
result = check_coincidence();
if ( mode_2_OAM_interrupt )
{
v4 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v4 | 2));
}
}
lcd_cycles -= 456;
}
}
else if ( (unsigned int)result > 0xCB )
{
++lcd_line;
result = check_coincidence();
if ( lcd_line == -112 )
{
lcd_mode_flag = 1;
if ( mode_1_V_Blank_interrupt )
{
v5 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(v5 | 2));
}
v1 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v1 | 1));
}
else
{
lcd_mode_flag = 2;
if ( mode_2_OAM_interrupt )
{
v3 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v3 | 2));
}
}
lcd_cycles -= 204;
}
return result;
}

canonical_decompiled_code:
__int64 func1()
{
__int64 result; // rax
char v1; // al
char v2; // al
char v3; // al
char v4; // al
char v5; // al

result = (unsigned int)(lcd_cycles + cpu_cycles);
lcd_cycles += cpu_cycles;
if ( lcd_mode_flag == 2 )
{
if ( (unsigned int)result > 0x4F )
{
result = (unsigned int)(result - 80);
lcd_mode_flag = 3;
lcd_cycles = result;
}
}
else if ( (unsigned __int8)lcd_mode_flag > 2u )
{
if ( lcd_mode_flag == 3 && (unsigned int)result > 0xAB )
{
lcd_mode_flag = 0;
if ( mode_0_H_Blank_interrupt )
{
v2 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(v2 | 2));
LODWORD(result) = lcd_cycles;
}
result = (unsigned int)(result - 172);
lcd_cycles = result;
}
}
else if ( lcd_mode_flag )
{
if ( (unsigned int)result > 0x1C7 )
{
++lcd_line;
func0();
result = (unsigned __int8)lcd_line;
if ( lcd_line == -102 )
{
lcd_line = 0;
}
else if ( lcd_line == 1 )
{
lcd_line = 0;
lcd_mode_flag = 2;
result = func0();
if ( mode_2_OAM_interrupt )
{
v4 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v4 | 2));
}
}
lcd_cycles -= 456;
}
}
else if ( (unsigned int)result > 0xCB )
{
++lcd_line;
result = func0();
if ( lcd_line == -112 )
{
lcd_mode_flag = 1;
if ( mode_1_V_Blank_interrupt )
{
v5 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(v5 | 2));
}
v1 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v1 | 1));
}
else
{
lcd_mode_flag = 2;
if ( mode_2_OAM_interrupt )
{
v3 = get_mem8(65295LL);
result = set_mem8(65295LL, (unsigned int)(v3 | 2));
}
}
lcd_cycles -= 204;
}
return result;
}

original_code:
void update_STAT ( void )
{
    lcd_cycles += cpu_cycles;
    switch ( lcd_mode_flag )
    {
        case 0:
            if ( lcd_cycles >= 204 )
            {
                lcd_line++;
                check_coincidence();
                if ( lcd_line == 144 )
                {
                    lcd_mode_flag = 1;
                    if ( mode_1_V_Blank_interrupt )
                        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                    set_mem8(0xff0f, (get_mem8(0xff0f) | 0x1));
                }
                else
                {
                    lcd_mode_flag = 2;
                    if ( mode_2_OAM_interrupt )
                        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                }
                lcd_cycles -= 204;
            }
            break;
        case 1:
            if ( lcd_cycles >= 456 )
            {
                lcd_line++;
                check_coincidence();
                if ( lcd_line == 154 )
                {
                    lcd_line = 0;
                }
                else if ( lcd_line == 1 )
                {
                    lcd_line = 0;
                    lcd_mode_flag = 2;
                    check_coincidence();
                    if ( mode_2_OAM_interrupt )
                        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                }
                lcd_cycles -= 456;
            }
            break;
        case 2:
            if ( lcd_cycles >= 80 )
            {
                lcd_mode_flag = 3;
                lcd_cycles -= 80;
            }
            break;
        case 3:
            if ( lcd_cycles >= 172 )
            {
                lcd_mode_flag = 0;
                if ( mode_0_H_Blank_interrupt )
                    set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                lcd_cycles -= 172;
            }
            break;
    }
}

canonical_original_code:
void update_STAT()
{
    lcd_cycles += cpu_cycles;
    switch ( lcd_mode_flag )
    {
        case 0:
            if ( lcd_cycles >= 204 )
            {
                lcd_line++;
                check_coincidence();
                if ( lcd_line == 144 )
                {
                    lcd_mode_flag = 1;
                    if ( mode_1_V_Blank_interrupt )
                        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                    set_mem8(0xff0f, (get_mem8(0xff0f) | 0x1));
                }
                else
                {
                    lcd_mode_flag = 2;
                    if ( mode_2_OAM_interrupt )
                        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                }
                lcd_cycles -= 204;
            }
            break;
        case 1:
            if ( lcd_cycles >= 456 )
            {
                lcd_line++;
                check_coincidence();
                if ( lcd_line == 154 )
                {
                    lcd_line = 0;
                }
                else if ( lcd_line == 1 )
                {
                    lcd_line = 0;
                    lcd_mode_flag = 2;
                    check_coincidence();
                    if ( mode_2_OAM_interrupt )
                        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                }
                lcd_cycles -= 456;
            }
            break;
        case 2:
            if ( lcd_cycles >= 80 )
            {
                lcd_mode_flag = 3;
                lcd_cycles -= 80;
            }
            break;
        case 3:
            if ( lcd_cycles >= 172 )
            {
                lcd_mode_flag = 0;
                if ( mode_0_H_Blank_interrupt )
                    set_mem8(0xff0f, (get_mem8(0xff0f) | 0x2));
                lcd_cycles -= 172;
            }
            break;
    }
}


decompiled_code:
void init_video()
{
lcd_cycles = 0;
}

canonical_decompiled_code:
void func2()
{
lcd_cycles = 0;
}

original_code:
void init_video ( void )
{
    lcd_cycles = 0;
}

canonical_original_code:
void init_video()
{
    lcd_cycles = 0;
}


decompiled_code:
// attributes: thunk
__int64 cycle_video()
{
return update_STAT();
}

canonical_decompiled_code:
__int64 func3()
{
return func1();
}

original_code:
void cycle_video ( void )
{
    update_STAT();
}

canonical_original_code:
void cycle_video()
{
    update_STAT();
}


decompiled_code:
__int64 __fastcall handle_ioregs_read(__int16 a1, _BYTE *a2)
{
__int64 result; // rax
char v3; // al
char v4; // dl

switch ( a1 )
{
case -256:
*a2 = (32 * P15_select_button_keys) & 0x20 | (16 * P14_select_direction_keys) & 0x10 | (8 * P13_input_down) & 8 | P10_input_right & 1 | (4 * P12_input_up) & 4 | (2 * P11_input_left) & 2;
goto LABEL_5;
case -255:
*a2 = serial_transfer_data;
return 1LL;
case -254:
*a2 = serial_shift_clock | (serial_transfer_start_flag << 7);
return 1LL;
case -252:
*a2 = div_reg;
return 1LL;
case -251:
*a2 = timer_counter;
return 1LL;
case -250:
*a2 = timer_modulo;
return 1LL;
case -249:
*a2 = timer_input_clock_select | (4 * timer_enabled);
return 1LL;
case -240:
*a2 = channel1_number_of_sweep_shift | (16 * channel1_sweep_time) | (4 * channel1_sweep_increase_decrease);
return 1LL;
case -239:
*a2 = channel1_wave_pattern_duty << 6;
return 1LL;
case -238:
*a2 = channel1_number_of_envelope_sweep | (16 * channel1_initial_volume_of_envelope) | (8
* channel1_envelope_direction);
return 1LL;
case -237:
case -232:
case -227:
case -176:
*a2 = 0;
return 1LL;
case -236:
*a2 = channel1_counter_consecutive_selection << 6;
return 1LL;
case -234:
*a2 = channel2_wave_pattern_duty << 6;
return 1LL;
case -233:
*a2 = channel2_number_of_envelope_sweep | (16 * channel2_initial_volume_of_envelope) | (8
* channel2_envelope_direction);
return 1LL;
case -231:
*a2 = channel2_counter_consecutive_selection << 6;
return 1LL;
case -230:
*a2 = channel3_sound_enabled << 7;
return 1LL;
case -229:
*a2 = channel3_sound_length;
return 1LL;
case -228:
*a2 = 32 * channel3_select_output_level;
return 1LL;
case -226:
*a2 = channel3_counter_consecutive_selection << 6;
return 1LL;
case -224:
*a2 = channel4_sound_length;
return 1LL;
case -223:
*a2 = channel4_number_of_envelope_sweep | (16 * channel4_initial_volume_of_envelope) | (8
* channel4_envelope_direction);
return 1LL;
case -222:
*a2 = channel4_dividing_ratio_of_frequencies | (16 * channel4_shift_clock_frequency) | (8
* channel4_counter_step_width);
return 1LL;
case -221:
*a2 = channel4_counter_consecutive_selection << 6;
return 1LL;
case -220:
*a2 = (output_vin_to_SO2_terminal << 7) | SO1_output_level | (16 * SO2_output_level) | (8
* output_vin_to_SO1_terminal);
return 1LL;
case -219:
v3 = (32 * output_sound_2_to_SO2_terminal) & 0x20 | (16 * output_sound_1_to_SO2_terminal) & 0x10 | (8 * output_sound_4_to_SO1_terminal) & 8 | (4 * output_sound_3_to_SO1_terminal) & 4 | (2 * output_sound_2_to_SO1_terminal) & 2 | (output_sound_4_to_SO2_terminal << 7) | output_sound_1_to_SO1_terminal & 1;
v4 = output_sound_3_to_SO2_terminal;
goto LABEL_16;
case -218:
*a2 = (8 * sound_4_ON_flag) & 8 | (4 * sound_3_ON_flag) & 4 | (2 * sound_2_ON_flag) & 2 | (audio_enabled << 7) | sound_1_ON_flag & 1;
return 1LL;
case -192:
v3 = (32 * window_display_enable) & 0x20 | (16 * bg_window_tile_data_select) & 0x10 | (8
* bg_tile_map_display_select) & 8 | (4 * sprite_size) & 4 | (2 * sprite_display_enable) & 2 | (lcd_display_enable << 7) | bg_display & 1;
v4 = window_tile_map_display_select;
LABEL_16:
*a2 = (v4 << 6) & 0x40 | v3;
result = 1LL;
break;
case -191:
*a2 = (LYC_LY_coincidence_interrupt << 6) | (32 * mode_2_OAM_interrupt) | (16 * mode_1_V_Blank_interrupt) | lcd_mode_flag | (8 * mode_0_H_Blank_interrupt) | (4 * lcd_coincidence_flag);
result = 1LL;
break;
case -190:
*a2 = lcd_scroll_y;
result = 1LL;
break;
case -189:
*a2 = lcd_scroll_x;
result = 1LL;
break;
case -188:
*a2 = lcd_line;
result = 1LL;
break;
case -187:
*a2 = lcd_LY_compare;
result = 1LL;
break;
case -186:
LABEL_5:
result = 1LL;
break;
case -185:
*a2 = (shade_for_color_3 << 6) | shade_for_color_0 | (16 * shade_for_color_2) | (4 * shade_for_color_1);
result = 1LL;
break;
case -184:
*a2 = (sprite_0_shade_for_color_2 << 6) | (16 * sprite_0_shade_for_color_1) | (4 * sprite_0_shade_for_color_0);
result = 1LL;
break;
case -183:
*a2 = (sprite_1_shade_for_color_2 << 6) | (16 * sprite_1_shade_for_color_1) | (4 * sprite_1_shade_for_color_0);
result = 1LL;
break;
case -182:
*a2 = window_y_position;
result = 1LL;
break;
case -181:
*a2 = window_x_position;
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int16 a1, _BYTE *a2)
{
__int64 result; // rax
char v3; // al
char v4; // dl

switch ( a1 )
{
case -256:
*a2 = (32 * P15_select_button_keys) & 0x20 | (16 * P14_select_direction_keys) & 0x10 | (8 * P13_input_down) & 8 | P10_input_right & 1 | (4 * P12_input_up) & 4 | (2 * P11_input_left) & 2;
goto LABEL_5;
case -255:
*a2 = serial_transfer_data;
return 1LL;
case -254:
*a2 = serial_shift_clock | (serial_transfer_start_flag << 7);
return 1LL;
case -252:
*a2 = div_reg;
return 1LL;
case -251:
*a2 = timer_counter;
return 1LL;
case -250:
*a2 = timer_modulo;
return 1LL;
case -249:
*a2 = timer_input_clock_select | (4 * timer_enabled);
return 1LL;
case -240:
*a2 = channel1_number_of_sweep_shift | (16 * channel1_sweep_time) | (4 * channel1_sweep_increase_decrease);
return 1LL;
case -239:
*a2 = channel1_wave_pattern_duty << 6;
return 1LL;
case -238:
*a2 = channel1_number_of_envelope_sweep | (16 * channel1_initial_volume_of_envelope) | (8
* channel1_envelope_direction);
return 1LL;
case -237:
case -232:
case -227:
case -176:
*a2 = 0;
return 1LL;
case -236:
*a2 = channel1_counter_consecutive_selection << 6;
return 1LL;
case -234:
*a2 = channel2_wave_pattern_duty << 6;
return 1LL;
case -233:
*a2 = channel2_number_of_envelope_sweep | (16 * channel2_initial_volume_of_envelope) | (8
* channel2_envelope_direction);
return 1LL;
case -231:
*a2 = channel2_counter_consecutive_selection << 6;
return 1LL;
case -230:
*a2 = channel3_sound_enabled << 7;
return 1LL;
case -229:
*a2 = channel3_sound_length;
return 1LL;
case -228:
*a2 = 32 * channel3_select_output_level;
return 1LL;
case -226:
*a2 = channel3_counter_consecutive_selection << 6;
return 1LL;
case -224:
*a2 = channel4_sound_length;
return 1LL;
case -223:
*a2 = channel4_number_of_envelope_sweep | (16 * channel4_initial_volume_of_envelope) | (8
* channel4_envelope_direction);
return 1LL;
case -222:
*a2 = channel4_dividing_ratio_of_frequencies | (16 * channel4_shift_clock_frequency) | (8
* channel4_counter_step_width);
return 1LL;
case -221:
*a2 = channel4_counter_consecutive_selection << 6;
return 1LL;
case -220:
*a2 = (output_vin_to_SO2_terminal << 7) | SO1_output_level | (16 * SO2_output_level) | (8
* output_vin_to_SO1_terminal);
return 1LL;
case -219:
v3 = (32 * output_sound_2_to_SO2_terminal) & 0x20 | (16 * output_sound_1_to_SO2_terminal) & 0x10 | (8 * output_sound_4_to_SO1_terminal) & 8 | (4 * output_sound_3_to_SO1_terminal) & 4 | (2 * output_sound_2_to_SO1_terminal) & 2 | (output_sound_4_to_SO2_terminal << 7) | output_sound_1_to_SO1_terminal & 1;
v4 = output_sound_3_to_SO2_terminal;
goto LABEL_16;
case -218:
*a2 = (8 * sound_4_ON_flag) & 8 | (4 * sound_3_ON_flag) & 4 | (2 * sound_2_ON_flag) & 2 | (audio_enabled << 7) | sound_1_ON_flag & 1;
return 1LL;
case -192:
v3 = (32 * window_display_enable) & 0x20 | (16 * bg_window_tile_data_select) & 0x10 | (8
* bg_tile_map_display_select) & 8 | (4 * sprite_size) & 4 | (2 * sprite_display_enable) & 2 | (lcd_display_enable << 7) | bg_display & 1;
v4 = window_tile_map_display_select;
LABEL_16:
*a2 = (v4 << 6) & 0x40 | v3;
result = 1LL;
break;
case -191:
*a2 = (LYC_LY_coincidence_interrupt << 6) | (32 * mode_2_OAM_interrupt) | (16 * mode_1_V_Blank_interrupt) | lcd_mode_flag | (8 * mode_0_H_Blank_interrupt) | (4 * lcd_coincidence_flag);
result = 1LL;
break;
case -190:
*a2 = lcd_scroll_y;
result = 1LL;
break;
case -189:
*a2 = lcd_scroll_x;
result = 1LL;
break;
case -188:
*a2 = lcd_line;
result = 1LL;
break;
case -187:
*a2 = lcd_LY_compare;
result = 1LL;
break;
case -186:
LABEL_5:
result = 1LL;
break;
case -185:
*a2 = (shade_for_color_3 << 6) | shade_for_color_0 | (16 * shade_for_color_2) | (4 * shade_for_color_1);
result = 1LL;
break;
case -184:
*a2 = (sprite_0_shade_for_color_2 << 6) | (16 * sprite_0_shade_for_color_1) | (4 * sprite_0_shade_for_color_0);
result = 1LL;
break;
case -183:
*a2 = (sprite_1_shade_for_color_2 << 6) | (16 * sprite_1_shade_for_color_1) | (4 * sprite_1_shade_for_color_0);
result = 1LL;
break;
case -182:
*a2 = window_y_position;
result = 1LL;
break;
case -181:
*a2 = window_x_position;
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
int handle_ioregs_read ( unsigned short addr, char *value )
{
    switch ( addr )
    {
        case 0xff00:
            *value = (((P10_input_right) & 1) | (((P11_input_left) & 1) << 1) | (((P12_input_up) & 1) << 2) | (((P13_input_down) & 1) << 3) | (((P14_select_direction_keys) & 1) << 4) | (((P15_select_button_keys) & 1) << 5) | (((0) & 1) << 6) | (((0) & 1) << 7));
            break;
        case 0xff01:
            *value = serial_transfer_data;
            break;
        case 0xff02:
            *value = serial_shift_clock | (serial_transfer_start_flag << 7);
            break;
        case 0xff04:
            *value = div_reg;
            break;
        case 0xff05:
            *value = timer_counter;
            break;
        case 0xff06:
            *value = timer_modulo;
            break;
        case 0xff07:
            *value = timer_input_clock_select | (timer_enabled << 2);
            break;
        case 0xff10:
            *value = channel1_number_of_sweep_shift | (channel1_sweep_increase_decrease << 2) | (channel1_sweep_time << 4);
            break;
        case 0xff11:
            *value = channel1_wave_pattern_duty << 6;
            break;
        case 0xff12:
            *value = channel1_number_of_envelope_sweep | (channel1_envelope_direction << 3) |
                     (channel1_initial_volume_of_envelope << 4);
            break;
        case 0xff13:
            *value = 0;
            break;
        case 0xff14:
            *value = channel1_counter_consecutive_selection << 6;
            break;
        case 0xff16:
            *value = channel2_wave_pattern_duty << 6;
            break;
        case 0xff17:
            *value = channel2_number_of_envelope_sweep | (channel2_envelope_direction << 3) |
                     (channel2_initial_volume_of_envelope << 4);
            break;
        case 0xff18:
            *value = 0;
            break;
        case 0xff19:
            *value = channel2_counter_consecutive_selection << 6;
            break;
        case 0xff1a:
            *value = channel3_sound_enabled << 7;
            break;
        case 0xff1b:
            *value = channel3_sound_length;
            break;
        case 0xff1c:
            *value = channel3_select_output_level << 5;
            break;
        case 0xff1d:
            *value = 0;
            break;
        case 0xff1e:
            *value = channel3_counter_consecutive_selection << 6;
            break;
        case 0xff20:
            *value = channel4_sound_length;
            break;
        case 0xff21:
            *value = channel4_number_of_envelope_sweep | (channel4_envelope_direction << 3) |
                     (channel4_initial_volume_of_envelope << 4);
            break;
        case 0xff22:
            *value = channel4_dividing_ratio_of_frequencies | (channel4_counter_step_width << 3) |
                     (channel4_shift_clock_frequency << 4);
            break;
        case 0xff23:
            *value = channel4_counter_consecutive_selection << 6;
            break;
        case 0xff24:
            *value = SO1_output_level | (output_vin_to_SO1_terminal << 3) |
                     (SO2_output_level << 4) | (output_vin_to_SO2_terminal << 7);
            break;
        case 0xff25:
            *value = (((output_sound_1_to_SO1_terminal) & 1) | (((output_sound_2_to_SO1_terminal) & 1) << 1) | (((output_sound_3_to_SO1_terminal) & 1) << 2) | (((output_sound_4_to_SO1_terminal) & 1) << 3) | (((output_sound_1_to_SO2_terminal) & 1) << 4) | (((output_sound_2_to_SO2_terminal) & 1) << 5) | (((output_sound_3_to_SO2_terminal) & 1) << 6) | (((output_sound_4_to_SO2_terminal) & 1) << 7));
            break;
        case 0xff26:
            *value = (((sound_1_ON_flag) & 1) | (((sound_2_ON_flag) & 1) << 1) | (((sound_3_ON_flag) & 1) << 2) | (((sound_4_ON_flag) & 1) << 3) | (((0) & 1) << 4) | (((0) & 1) << 5) | (((0) & 1) << 6) | (((audio_enabled) & 1) << 7));
            break;
        case 0xff40:
            *value = (((bg_display) & 1) | (((sprite_display_enable) & 1) << 1) | (((sprite_size) & 1) << 2) | (((bg_tile_map_display_select) & 1) << 3) | (((bg_window_tile_data_select) & 1) << 4) | (((window_display_enable) & 1) << 5) | (((window_tile_map_display_select) & 1) << 6) | (((lcd_display_enable) & 1) << 7));
            break;
        case 0xff41:
            *value = lcd_mode_flag | (lcd_coincidence_flag << 2) | (mode_0_H_Blank_interrupt << 3) |
                     (mode_1_V_Blank_interrupt << 4) | (mode_2_OAM_interrupt << 5) | (LYC_LY_coincidence_interrupt << 6);
            break;
        case 0xff42:
            *value = lcd_scroll_y;
            break;
        case 0xff43:
            *value = lcd_scroll_x;
            break;
        case 0xff44:
            *value = lcd_line;
            break;
        case 0xff45:
            *value = lcd_LY_compare;
            break;
        case 0xff46:
            break;
        case 0xff47:
            *value = shade_for_color_0 | (shade_for_color_1 << 2) | (shade_for_color_2 << 4) | (shade_for_color_3 << 6);
            break;
        case 0xff48:
            *value = (sprite_0_shade_for_color_0 << 2) | (sprite_0_shade_for_color_1 << 4) | (sprite_0_shade_for_color_2 << 6);
            break;
        case 0xff49:
            *value = (sprite_1_shade_for_color_0 << 2) | (sprite_1_shade_for_color_1 << 4) | (sprite_1_shade_for_color_2 << 6);
            break;
        case 0xff4a:
            *value = window_y_position;
            break;
        case 0xff4b:
            *value = window_x_position;
            break;
        case 0xff50:
            *value = 0;
            break;
        default:
            return 0;
    }
    return 1;
}

canonical_original_code:
int handle_ioregs_read(unsigned short addr, char *value)
{
    switch ( addr )
    {
        case 0xff00:
            *value = (((P10_input_right) & 1) | (((P11_input_left) & 1) << 1) | (((P12_input_up) & 1) << 2) | (((P13_input_down) & 1) << 3) | (((P14_select_direction_keys) & 1) << 4) | (((P15_select_button_keys) & 1) << 5) | (((0) & 1) << 6) | (((0) & 1) << 7));
            break;
        case 0xff01:
            *value = serial_transfer_data;
            break;
        case 0xff02:
            *value = serial_shift_clock | (serial_transfer_start_flag << 7);
            break;
        case 0xff04:
            *value = div_reg;
            break;
        case 0xff05:
            *value = timer_counter;
            break;
        case 0xff06:
            *value = timer_modulo;
            break;
        case 0xff07:
            *value = timer_input_clock_select | (timer_enabled << 2);
            break;
        case 0xff10:
            *value = channel1_number_of_sweep_shift | (channel1_sweep_increase_decrease << 2) | (channel1_sweep_time << 4);
            break;
        case 0xff11:
            *value = channel1_wave_pattern_duty << 6;
            break;
        case 0xff12:
            *value = channel1_number_of_envelope_sweep | (channel1_envelope_direction << 3) |
                     (channel1_initial_volume_of_envelope << 4);
            break;
        case 0xff13:
            *value = 0;
            break;
        case 0xff14:
            *value = channel1_counter_consecutive_selection << 6;
            break;
        case 0xff16:
            *value = channel2_wave_pattern_duty << 6;
            break;
        case 0xff17:
            *value = channel2_number_of_envelope_sweep | (channel2_envelope_direction << 3) |
                     (channel2_initial_volume_of_envelope << 4);
            break;
        case 0xff18:
            *value = 0;
            break;
        case 0xff19:
            *value = channel2_counter_consecutive_selection << 6;
            break;
        case 0xff1a:
            *value = channel3_sound_enabled << 7;
            break;
        case 0xff1b:
            *value = channel3_sound_length;
            break;
        case 0xff1c:
            *value = channel3_select_output_level << 5;
            break;
        case 0xff1d:
            *value = 0;
            break;
        case 0xff1e:
            *value = channel3_counter_consecutive_selection << 6;
            break;
        case 0xff20:
            *value = channel4_sound_length;
            break;
        case 0xff21:
            *value = channel4_number_of_envelope_sweep | (channel4_envelope_direction << 3) |
                     (channel4_initial_volume_of_envelope << 4);
            break;
        case 0xff22:
            *value = channel4_dividing_ratio_of_frequencies | (channel4_counter_step_width << 3) |
                     (channel4_shift_clock_frequency << 4);
            break;
        case 0xff23:
            *value = channel4_counter_consecutive_selection << 6;
            break;
        case 0xff24:
            *value = SO1_output_level | (output_vin_to_SO1_terminal << 3) |
                     (SO2_output_level << 4) | (output_vin_to_SO2_terminal << 7);
            break;
        case 0xff25:
            *value = (((output_sound_1_to_SO1_terminal) & 1) | (((output_sound_2_to_SO1_terminal) & 1) << 1) | (((output_sound_3_to_SO1_terminal) & 1) << 2) | (((output_sound_4_to_SO1_terminal) & 1) << 3) | (((output_sound_1_to_SO2_terminal) & 1) << 4) | (((output_sound_2_to_SO2_terminal) & 1) << 5) | (((output_sound_3_to_SO2_terminal) & 1) << 6) | (((output_sound_4_to_SO2_terminal) & 1) << 7));
            break;
        case 0xff26:
            *value = (((sound_1_ON_flag) & 1) | (((sound_2_ON_flag) & 1) << 1) | (((sound_3_ON_flag) & 1) << 2) | (((sound_4_ON_flag) & 1) << 3) | (((0) & 1) << 4) | (((0) & 1) << 5) | (((0) & 1) << 6) | (((audio_enabled) & 1) << 7));
            break;
        case 0xff40:
            *value = (((bg_display) & 1) | (((sprite_display_enable) & 1) << 1) | (((sprite_size) & 1) << 2) | (((bg_tile_map_display_select) & 1) << 3) | (((bg_window_tile_data_select) & 1) << 4) | (((window_display_enable) & 1) << 5) | (((window_tile_map_display_select) & 1) << 6) | (((lcd_display_enable) & 1) << 7));
            break;
        case 0xff41:
            *value = lcd_mode_flag | (lcd_coincidence_flag << 2) | (mode_0_H_Blank_interrupt << 3) |
                     (mode_1_V_Blank_interrupt << 4) | (mode_2_OAM_interrupt << 5) | (LYC_LY_coincidence_interrupt << 6);
            break;
        case 0xff42:
            *value = lcd_scroll_y;
            break;
        case 0xff43:
            *value = lcd_scroll_x;
            break;
        case 0xff44:
            *value = lcd_line;
            break;
        case 0xff45:
            *value = lcd_LY_compare;
            break;
        case 0xff46:
            break;
        case 0xff47:
            *value = shade_for_color_0 | (shade_for_color_1 << 2) | (shade_for_color_2 << 4) | (shade_for_color_3 << 6);
            break;
        case 0xff48:
            *value = (sprite_0_shade_for_color_0 << 2) | (sprite_0_shade_for_color_1 << 4) | (sprite_0_shade_for_color_2 << 6);
            break;
        case 0xff49:
            *value = (sprite_1_shade_for_color_0 << 2) | (sprite_1_shade_for_color_1 << 4) | (sprite_1_shade_for_color_2 << 6);
            break;
        case 0xff4a:
            *value = window_y_position;
            break;
        case 0xff4b:
            *value = window_x_position;
            break;
        case 0xff50:
            *value = 0;
            break;
        default:
            return 0;
    }
    return 1;
}

variable_types:
addr
unsigned short

variable_types:
value
char *


decompiled_code:
__int64 __fastcall handle_ioregs_write(__int16 a1, char a2)
{
__int64 result; // rax

switch ( a1 )
{
case -256:
P15_select_button_keys = (a2 >> 5) & 1;
P14_select_direction_keys = (a2 >> 4) & 1;
goto LABEL_4;
case -255:
serial_transfer_data = a2;
result = 1LL;
break;
case -254:
serial_shift_clock = a2 & 1;
result = 1LL;
serial_transfer_start_flag = (a2 >> 7) & 1;
break;
case -252:
div_reg = 0;
result = 1LL;
break;
case -251:
timer_counter = a2;
result = 1LL;
break;
case -250:
timer_modulo = a2;
result = 1LL;
break;
case -249:
timer_counter = 0;
timer_input_clock_select = a2 & 2;
timer_enabled = (a2 & 4) != 0;
result = 1LL;
break;
case -240:
result = 1LL;
if ( audio_enabled < 0 )
{
channel1_number_of_sweep_shift = a2 & 7;
channel1_sweep_time = (a2 >> 4) & 7;
channel1_sweep_increase_decrease = (a2 >> 3) & 1;
}
break;
case -239:
result = 1LL;
if ( audio_enabled < 0 )
{
channel1_wave_pattern_duty = (unsigned __int8)a2 >> 6;
channel1_sound_length_data = a2 & 0x3F;
}
break;
case -238:
result = 1LL;
if ( audio_enabled < 0 )
{
channel1_number_of_envelope_sweep = a2 & 7;
channel1_initial_volume_of_envelope = (unsigned __int8)a2 >> 4;
channel1_envelope_direction = (a2 >> 3) & 1;
}
break;
case -237:
result = 1LL;
if ( audio_enabled < 0 )
channel1_frequency = channel1_frequency & 0x700 | a2;
break;
case -236:
result = 1LL;
if ( audio_enabled < 0 )
{
HIBYTE(channel1_frequency) = a2 & 3;
channel1_initial = (a2 >> 7) & 1;
channel1_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -234:
result = 1LL;
if ( audio_enabled < 0 )
{
channel2_wave_pattern_duty = (unsigned __int8)a2 >> 6;
channel2_sound_length_data = a2 & 0x3F;
}
break;
case -233:
result = 1LL;
if ( audio_enabled < 0 )
{
channel2_number_of_envelope_sweep = a2 & 7;
channel2_initial_volume_of_envelope = (unsigned __int8)a2 >> 4;
channel2_envelope_direction = (a2 >> 3) & 1;
}
break;
case -232:
result = 1LL;
if ( audio_enabled < 0 )
channel2_frequency = channel2_frequency & 0x700 | a2;
break;
case -231:
result = 1LL;
if ( audio_enabled < 0 )
{
HIBYTE(channel2_frequency) = a2 & 3;
channel2_initial = (a2 >> 7) & 1;
channel2_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -230:
result = 1LL;
if ( audio_enabled < 0 )
channel3_sound_enabled = (a2 >> 7) & 1;
break;
case -229:
result = 1LL;
if ( audio_enabled < 0 )
channel3_sound_length = a2;
break;
case -228:
result = 1LL;
if ( audio_enabled < 0 )
channel3_select_output_level = ((unsigned __int8)a2 >> 5) & 3;
break;
case -227:
result = 1LL;
if ( audio_enabled < 0 )
channel3_frequency = channel3_frequency & 0x700 | a2;
break;
case -226:
result = 1LL;
if ( audio_enabled < 0 )
{
HIBYTE(channel3_frequency) = a2 & 3;
channel3_initial = (a2 >> 7) & 1;
channel3_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -224:
result = 1LL;
if ( audio_enabled < 0 )
channel4_sound_length = a2;
break;
case -223:
result = 1LL;
if ( audio_enabled < 0 )
{
channel4_number_of_envelope_sweep = a2 & 7;
channel4_initial_volume_of_envelope = (unsigned __int8)a2 >> 4;
channel4_envelope_direction = (a2 >> 3) & 1;
}
break;
case -222:
result = 1LL;
if ( audio_enabled < 0 )
{
channel4_dividing_ratio_of_frequencies = a2 & 7;
channel4_shift_clock_frequency = (unsigned __int8)a2 >> 4;
channel4_counter_step_width = (a2 >> 3) & 1;
}
break;
case -221:
result = 1LL;
if ( audio_enabled < 0 )
{
channel4_initial = (a2 >> 7) & 1;
channel4_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -220:
result = 1LL;
if ( audio_enabled < 0 )
{
SO1_output_level = a2 & 7;
output_vin_to_SO1_terminal = (a2 >> 3) & 1;
output_vin_to_SO2_terminal = (a2 >> 7) & 1;
SO2_output_level = (a2 >> 4) & 7;
}
break;
case -219:
result = 1LL;
if ( audio_enabled < 0 )
{
output_sound_1_to_SO1_terminal = a2 & 1;
output_sound_2_to_SO1_terminal = (a2 >> 1) & 1;
output_sound_3_to_SO1_terminal = (a2 >> 2) & 1;
output_sound_4_to_SO1_terminal = (a2 >> 3) & 1;
output_sound_1_to_SO2_terminal = (a2 >> 4) & 1;
output_sound_2_to_SO2_terminal = (a2 >> 5) & 1;
output_sound_4_to_SO2_terminal = (a2 >> 7) & 1;
output_sound_3_to_SO2_terminal = (a2 >> 6) & 1;
}
break;
case -218:
result = 1LL;
audio_enabled = (a2 >> 7) & 1;
break;
case -192:
bg_display = a2 & 1;
sprite_display_enable = (a2 >> 1) & 1;
sprite_size = (a2 >> 2) & 1;
bg_tile_map_display_select = (a2 >> 3) & 1;
bg_window_tile_data_select = (a2 >> 4) & 1;
window_display_enable = (a2 >> 5) & 1;
lcd_display_enable = (a2 >> 7) & 1;
window_tile_map_display_select = (a2 >> 6) & 1;
result = 1LL;
break;
case -191:
mode_0_H_Blank_interrupt = (a2 >> 3) & 1;
mode_1_V_Blank_interrupt = (a2 >> 4) & 1;
LYC_LY_coincidence_interrupt = (a2 >> 6) & 1;
mode_2_OAM_interrupt = (a2 >> 5) & 1;
result = 1LL;
break;
case -190:
lcd_scroll_y = a2;
result = 1LL;
break;
case -189:
lcd_scroll_x = a2;
result = 1LL;
break;
case -188:
lcd_line = 0;
result = 1LL;
lcd_mode_flag = 2;
break;
case -187:
lcd_LY_compare = a2;
result = 1LL;
break;
case -186:
LABEL_4:
result = 1LL;
break;
case -185:
shade_for_color_0 = a2 & 2;
shade_for_color_1 = (a2 >> 2) & 3;
shade_for_color_3 = (unsigned __int8)a2 >> 6;
shade_for_color_2 = (a2 >> 4) & 3;
result = 1LL;
break;
case -184:
sprite_0_shade_for_color_0 = (a2 >> 2) & 3;
sprite_0_shade_for_color_2 = (unsigned __int8)a2 >> 6;
sprite_0_shade_for_color_1 = (a2 >> 4) & 3;
result = 1LL;
break;
case -183:
sprite_1_shade_for_color_0 = (a2 >> 2) & 3;
sprite_1_shade_for_color_2 = (unsigned __int8)a2 >> 6;
sprite_1_shade_for_color_1 = (a2 >> 4) & 3;
result = 1LL;
break;
case -182:
window_y_position = a2;
result = 1LL;
break;
case -181:
window_x_position = a2;
result = 1LL;
break;
case -176:
disable_bootROM();
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int16 a1, char a2)
{
__int64 result; // rax

switch ( a1 )
{
case -256:
P15_select_button_keys = (a2 >> 5) & 1;
P14_select_direction_keys = (a2 >> 4) & 1;
goto LABEL_4;
case -255:
serial_transfer_data = a2;
result = 1LL;
break;
case -254:
serial_shift_clock = a2 & 1;
result = 1LL;
serial_transfer_start_flag = (a2 >> 7) & 1;
break;
case -252:
div_reg = 0;
result = 1LL;
break;
case -251:
timer_counter = a2;
result = 1LL;
break;
case -250:
timer_modulo = a2;
result = 1LL;
break;
case -249:
timer_counter = 0;
timer_input_clock_select = a2 & 2;
timer_enabled = (a2 & 4) != 0;
result = 1LL;
break;
case -240:
result = 1LL;
if ( audio_enabled < 0 )
{
channel1_number_of_sweep_shift = a2 & 7;
channel1_sweep_time = (a2 >> 4) & 7;
channel1_sweep_increase_decrease = (a2 >> 3) & 1;
}
break;
case -239:
result = 1LL;
if ( audio_enabled < 0 )
{
channel1_wave_pattern_duty = (unsigned __int8)a2 >> 6;
channel1_sound_length_data = a2 & 0x3F;
}
break;
case -238:
result = 1LL;
if ( audio_enabled < 0 )
{
channel1_number_of_envelope_sweep = a2 & 7;
channel1_initial_volume_of_envelope = (unsigned __int8)a2 >> 4;
channel1_envelope_direction = (a2 >> 3) & 1;
}
break;
case -237:
result = 1LL;
if ( audio_enabled < 0 )
channel1_frequency = channel1_frequency & 0x700 | a2;
break;
case -236:
result = 1LL;
if ( audio_enabled < 0 )
{
HIBYTE(channel1_frequency) = a2 & 3;
channel1_initial = (a2 >> 7) & 1;
channel1_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -234:
result = 1LL;
if ( audio_enabled < 0 )
{
channel2_wave_pattern_duty = (unsigned __int8)a2 >> 6;
channel2_sound_length_data = a2 & 0x3F;
}
break;
case -233:
result = 1LL;
if ( audio_enabled < 0 )
{
channel2_number_of_envelope_sweep = a2 & 7;
channel2_initial_volume_of_envelope = (unsigned __int8)a2 >> 4;
channel2_envelope_direction = (a2 >> 3) & 1;
}
break;
case -232:
result = 1LL;
if ( audio_enabled < 0 )
channel2_frequency = channel2_frequency & 0x700 | a2;
break;
case -231:
result = 1LL;
if ( audio_enabled < 0 )
{
HIBYTE(channel2_frequency) = a2 & 3;
channel2_initial = (a2 >> 7) & 1;
channel2_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -230:
result = 1LL;
if ( audio_enabled < 0 )
channel3_sound_enabled = (a2 >> 7) & 1;
break;
case -229:
result = 1LL;
if ( audio_enabled < 0 )
channel3_sound_length = a2;
break;
case -228:
result = 1LL;
if ( audio_enabled < 0 )
channel3_select_output_level = ((unsigned __int8)a2 >> 5) & 3;
break;
case -227:
result = 1LL;
if ( audio_enabled < 0 )
channel3_frequency = channel3_frequency & 0x700 | a2;
break;
case -226:
result = 1LL;
if ( audio_enabled < 0 )
{
HIBYTE(channel3_frequency) = a2 & 3;
channel3_initial = (a2 >> 7) & 1;
channel3_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -224:
result = 1LL;
if ( audio_enabled < 0 )
channel4_sound_length = a2;
break;
case -223:
result = 1LL;
if ( audio_enabled < 0 )
{
channel4_number_of_envelope_sweep = a2 & 7;
channel4_initial_volume_of_envelope = (unsigned __int8)a2 >> 4;
channel4_envelope_direction = (a2 >> 3) & 1;
}
break;
case -222:
result = 1LL;
if ( audio_enabled < 0 )
{
channel4_dividing_ratio_of_frequencies = a2 & 7;
channel4_shift_clock_frequency = (unsigned __int8)a2 >> 4;
channel4_counter_step_width = (a2 >> 3) & 1;
}
break;
case -221:
result = 1LL;
if ( audio_enabled < 0 )
{
channel4_initial = (a2 >> 7) & 1;
channel4_counter_consecutive_selection = (a2 >> 6) & 1;
}
break;
case -220:
result = 1LL;
if ( audio_enabled < 0 )
{
SO1_output_level = a2 & 7;
output_vin_to_SO1_terminal = (a2 >> 3) & 1;
output_vin_to_SO2_terminal = (a2 >> 7) & 1;
SO2_output_level = (a2 >> 4) & 7;
}
break;
case -219:
result = 1LL;
if ( audio_enabled < 0 )
{
output_sound_1_to_SO1_terminal = a2 & 1;
output_sound_2_to_SO1_terminal = (a2 >> 1) & 1;
output_sound_3_to_SO1_terminal = (a2 >> 2) & 1;
output_sound_4_to_SO1_terminal = (a2 >> 3) & 1;
output_sound_1_to_SO2_terminal = (a2 >> 4) & 1;
output_sound_2_to_SO2_terminal = (a2 >> 5) & 1;
output_sound_4_to_SO2_terminal = (a2 >> 7) & 1;
output_sound_3_to_SO2_terminal = (a2 >> 6) & 1;
}
break;
case -218:
result = 1LL;
audio_enabled = (a2 >> 7) & 1;
break;
case -192:
bg_display = a2 & 1;
sprite_display_enable = (a2 >> 1) & 1;
sprite_size = (a2 >> 2) & 1;
bg_tile_map_display_select = (a2 >> 3) & 1;
bg_window_tile_data_select = (a2 >> 4) & 1;
window_display_enable = (a2 >> 5) & 1;
lcd_display_enable = (a2 >> 7) & 1;
window_tile_map_display_select = (a2 >> 6) & 1;
result = 1LL;
break;
case -191:
mode_0_H_Blank_interrupt = (a2 >> 3) & 1;
mode_1_V_Blank_interrupt = (a2 >> 4) & 1;
LYC_LY_coincidence_interrupt = (a2 >> 6) & 1;
mode_2_OAM_interrupt = (a2 >> 5) & 1;
result = 1LL;
break;
case -190:
lcd_scroll_y = a2;
result = 1LL;
break;
case -189:
lcd_scroll_x = a2;
result = 1LL;
break;
case -188:
lcd_line = 0;
result = 1LL;
lcd_mode_flag = 2;
break;
case -187:
lcd_LY_compare = a2;
result = 1LL;
break;
case -186:
LABEL_4:
result = 1LL;
break;
case -185:
shade_for_color_0 = a2 & 2;
shade_for_color_1 = (a2 >> 2) & 3;
shade_for_color_3 = (unsigned __int8)a2 >> 6;
shade_for_color_2 = (a2 >> 4) & 3;
result = 1LL;
break;
case -184:
sprite_0_shade_for_color_0 = (a2 >> 2) & 3;
sprite_0_shade_for_color_2 = (unsigned __int8)a2 >> 6;
sprite_0_shade_for_color_1 = (a2 >> 4) & 3;
result = 1LL;
break;
case -183:
sprite_1_shade_for_color_0 = (a2 >> 2) & 3;
sprite_1_shade_for_color_2 = (unsigned __int8)a2 >> 6;
sprite_1_shade_for_color_1 = (a2 >> 4) & 3;
result = 1LL;
break;
case -182:
window_y_position = a2;
result = 1LL;
break;
case -181:
window_x_position = a2;
result = 1LL;
break;
case -176:
disable_bootROM();
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
int handle_ioregs_write ( unsigned short addr, char value )
{
    switch ( addr )
    {
        case 0xff00:
            P14_select_direction_keys = ((value & (1 << 4)) >> 4);
            P15_select_button_keys = ((value & (1 << 5)) >> 5);
            break;
        case 0xff01:
            serial_transfer_data = value;
            break;
        case 0xff02:
            serial_shift_clock = ((value & (1 << 0)) >> 0);
            serial_transfer_start_flag = ((value & (1 << 7)) >> 7);
            break;
        case 0xff04:
            div_reg = 0;
            break;
        case 0xff05:
            timer_counter = value & 0xff;
            break;
        case 0xff06:
            timer_modulo = value;
            break;
        case 0xff07:
            timer_enabled = ((value & (1 << 2)) >> 2);
            timer_input_clock_select = value & 0x2;
            timer_counter = 0;
            break;
        case 0xff10:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_number_of_sweep_shift = value & 0x7;
                channel1_sweep_increase_decrease = ((value & (1 << 3)) >> 3);
                channel1_sweep_time = (value & 0x70) >> 4;
            }
            break;
        case 0xff11:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_sound_length_data = value & 0x3f;
                channel1_wave_pattern_duty = (value & 0xc0) >> 6;
            }
            break;
        case 0xff12:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_number_of_envelope_sweep = value & 0x7;
                channel1_envelope_direction = ((value & (1 << 3)) >> 3);
                channel1_initial_volume_of_envelope = (value & 0xf0) >> 4;
            }
            break;
        case 0xff13:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_frequency = (channel1_frequency & 0x700) | value;
            }
            break;
        case 0xff14:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_frequency = (channel1_frequency & 0xff) | ((value & 0x3) << 8);
                channel1_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel1_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff16:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_sound_length_data = value & 0x3f;
                channel2_wave_pattern_duty = (value & 0xc0) >> 6;
            }
            break;
        case 0xff17:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_number_of_envelope_sweep = value & 0x7;
                channel2_envelope_direction = ((value & (1 << 3)) >> 3);
                channel2_initial_volume_of_envelope = (value & 0xf0) >> 4;
            }
            break;
        case 0xff18:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_frequency = (channel2_frequency & 0x700) | value;
            }
            break;
        case 0xff19:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_frequency = (channel2_frequency & 0xff) | ((value & 0x3) << 8);
                channel2_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel2_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff1a:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_sound_enabled = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff1b:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_sound_length = value;
            }
            break;
        case 0xff1c:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_select_output_level = (value & 0x60) >> 5;
            }
            break;
        case 0xff1d:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_frequency = (channel3_frequency & 0x700) | value;
            }
            break;
        case 0xff1e:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_frequency = (channel3_frequency & 0xff) | ((value & 0x3) << 8);
                channel3_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel3_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff20:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_sound_length = value;
            }
            break;
        case 0xff21:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_number_of_envelope_sweep = value & 0x7;
                channel4_envelope_direction = ((value & (1 << 3)) >> 3);
                channel4_initial_volume_of_envelope = (value & 0xf0) >> 4;
            }
            break;
        case 0xff22:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_dividing_ratio_of_frequencies = value & 0x7;
                channel4_counter_step_width = ((value & (1 << 3)) >> 3);
                channel4_shift_clock_frequency = (value & 0xf0) >> 4;
            }
            break;
        case 0xff23:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel4_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff24:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                SO1_output_level = value & 0x7;
                output_vin_to_SO1_terminal = ((value & (1 << 3)) >> 3);
                SO2_output_level = (value & 0x70) >> 4;
                output_vin_to_SO2_terminal = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff25:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                output_sound_1_to_SO1_terminal = ((value & (1 << 0)) >> 0);
                output_sound_2_to_SO1_terminal = ((value & (1 << 1)) >> 1);
                output_sound_3_to_SO1_terminal = ((value & (1 << 2)) >> 2);
                output_sound_4_to_SO1_terminal = ((value & (1 << 3)) >> 3);
                output_sound_1_to_SO2_terminal = ((value & (1 << 4)) >> 4);
                output_sound_2_to_SO2_terminal = ((value & (1 << 5)) >> 5);
                output_sound_3_to_SO2_terminal = ((value & (1 << 6)) >> 6);
                output_sound_4_to_SO2_terminal = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff26:
            audio_enabled = ((value & (1 << 7)) >> 7);
            break;
        case 0xff40:
            bg_display = ((value & (1 << 0)) >> 0);
            sprite_display_enable = ((value & (1 << 1)) >> 1);
            sprite_size = ((value & (1 << 2)) >> 2);
            bg_tile_map_display_select = ((value & (1 << 3)) >> 3);
            bg_window_tile_data_select = ((value & (1 << 4)) >> 4);
            window_display_enable = ((value & (1 << 5)) >> 5);
            window_tile_map_display_select = ((value & (1 << 6)) >> 6);
            lcd_display_enable = ((value & (1 << 7)) >> 7);
            break;
        case 0xff41:
            mode_0_H_Blank_interrupt = ((value & (1 << 3)) >> 3);
            mode_1_V_Blank_interrupt = ((value & (1 << 4)) >> 4);
            mode_2_OAM_interrupt = ((value & (1 << 5)) >> 5);
            LYC_LY_coincidence_interrupt = ((value & (1 << 6)) >> 6);
            break;
        case 0xff42:
            lcd_scroll_y = value;
            break;
        case 0xff43:
            lcd_scroll_x = value;
            break;
        case 0xff44:
            lcd_line = 0;
            lcd_mode_flag = 0x2;
            break;
        case 0xff45:
            lcd_LY_compare = value;
            break;
        case 0xff46:
            break;
        case 0xff47:
            shade_for_color_0 = value & 0x2;
            shade_for_color_1 = (value & 0xc) >> 2;
            shade_for_color_2 = (value & 0x30) >> 4;
            shade_for_color_3 = (value & 0xc0) >> 6;
            break;
        case 0xff48:
            sprite_0_shade_for_color_0 = (value & 0xc) >> 2;
            sprite_0_shade_for_color_1 = (value & 0x30) >> 4;
            sprite_0_shade_for_color_2 = (value & 0xc0) >> 6;
            break;
        case 0xff49:
            sprite_1_shade_for_color_0 = (value & 0xc) >> 2;
            sprite_1_shade_for_color_1 = (value & 0x30) >> 4;
            sprite_1_shade_for_color_2 = (value & 0xc0) >> 6;
            break;
        case 0xff4a:
            window_y_position = value;
            break;
        case 0xff4b:
            window_x_position = value;
            break;
        case 0xff50:
            disable_bootROM();
            break;
        default:
            return 0;
    }
    return 1;
}

canonical_original_code:
int handle_ioregs_write(unsigned short addr, char value)
{
    switch ( addr )
    {
        case 0xff00:
            P14_select_direction_keys = ((value & (1 << 4)) >> 4);
            P15_select_button_keys = ((value & (1 << 5)) >> 5);
            break;
        case 0xff01:
            serial_transfer_data = value;
            break;
        case 0xff02:
            serial_shift_clock = ((value & (1 << 0)) >> 0);
            serial_transfer_start_flag = ((value & (1 << 7)) >> 7);
            break;
        case 0xff04:
            div_reg = 0;
            break;
        case 0xff05:
            timer_counter = value & 0xff;
            break;
        case 0xff06:
            timer_modulo = value;
            break;
        case 0xff07:
            timer_enabled = ((value & (1 << 2)) >> 2);
            timer_input_clock_select = value & 0x2;
            timer_counter = 0;
            break;
        case 0xff10:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_number_of_sweep_shift = value & 0x7;
                channel1_sweep_increase_decrease = ((value & (1 << 3)) >> 3);
                channel1_sweep_time = (value & 0x70) >> 4;
            }
            break;
        case 0xff11:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_sound_length_data = value & 0x3f;
                channel1_wave_pattern_duty = (value & 0xc0) >> 6;
            }
            break;
        case 0xff12:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_number_of_envelope_sweep = value & 0x7;
                channel1_envelope_direction = ((value & (1 << 3)) >> 3);
                channel1_initial_volume_of_envelope = (value & 0xf0) >> 4;
            }
            break;
        case 0xff13:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_frequency = (channel1_frequency & 0x700) | value;
            }
            break;
        case 0xff14:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel1_frequency = (channel1_frequency & 0xff) | ((value & 0x3) << 8);
                channel1_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel1_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff16:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_sound_length_data = value & 0x3f;
                channel2_wave_pattern_duty = (value & 0xc0) >> 6;
            }
            break;
        case 0xff17:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_number_of_envelope_sweep = value & 0x7;
                channel2_envelope_direction = ((value & (1 << 3)) >> 3);
                channel2_initial_volume_of_envelope = (value & 0xf0) >> 4;
            }
            break;
        case 0xff18:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_frequency = (channel2_frequency & 0x700) | value;
            }
            break;
        case 0xff19:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel2_frequency = (channel2_frequency & 0xff) | ((value & 0x3) << 8);
                channel2_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel2_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff1a:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_sound_enabled = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff1b:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_sound_length = value;
            }
            break;
        case 0xff1c:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_select_output_level = (value & 0x60) >> 5;
            }
            break;
        case 0xff1d:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_frequency = (channel3_frequency & 0x700) | value;
            }
            break;
        case 0xff1e:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel3_frequency = (channel3_frequency & 0xff) | ((value & 0x3) << 8);
                channel3_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel3_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff20:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_sound_length = value;
            }
            break;
        case 0xff21:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_number_of_envelope_sweep = value & 0x7;
                channel4_envelope_direction = ((value & (1 << 3)) >> 3);
                channel4_initial_volume_of_envelope = (value & 0xf0) >> 4;
            }
            break;
        case 0xff22:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_dividing_ratio_of_frequencies = value & 0x7;
                channel4_counter_step_width = ((value & (1 << 3)) >> 3);
                channel4_shift_clock_frequency = (value & 0xf0) >> 4;
            }
            break;
        case 0xff23:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                channel4_counter_consecutive_selection = ((value & (1 << 6)) >> 6);
                channel4_initial = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff24:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                SO1_output_level = value & 0x7;
                output_vin_to_SO1_terminal = ((value & (1 << 3)) >> 3);
                SO2_output_level = (value & 0x70) >> 4;
                output_vin_to_SO2_terminal = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff25:
            if ( ((audio_enabled & (1 << 7)) >> 7) )
            {
                output_sound_1_to_SO1_terminal = ((value & (1 << 0)) >> 0);
                output_sound_2_to_SO1_terminal = ((value & (1 << 1)) >> 1);
                output_sound_3_to_SO1_terminal = ((value & (1 << 2)) >> 2);
                output_sound_4_to_SO1_terminal = ((value & (1 << 3)) >> 3);
                output_sound_1_to_SO2_terminal = ((value & (1 << 4)) >> 4);
                output_sound_2_to_SO2_terminal = ((value & (1 << 5)) >> 5);
                output_sound_3_to_SO2_terminal = ((value & (1 << 6)) >> 6);
                output_sound_4_to_SO2_terminal = ((value & (1 << 7)) >> 7);
            }
            break;
        case 0xff26:
            audio_enabled = ((value & (1 << 7)) >> 7);
            break;
        case 0xff40:
            bg_display = ((value & (1 << 0)) >> 0);
            sprite_display_enable = ((value & (1 << 1)) >> 1);
            sprite_size = ((value & (1 << 2)) >> 2);
            bg_tile_map_display_select = ((value & (1 << 3)) >> 3);
            bg_window_tile_data_select = ((value & (1 << 4)) >> 4);
            window_display_enable = ((value & (1 << 5)) >> 5);
            window_tile_map_display_select = ((value & (1 << 6)) >> 6);
            lcd_display_enable = ((value & (1 << 7)) >> 7);
            break;
        case 0xff41:
            mode_0_H_Blank_interrupt = ((value & (1 << 3)) >> 3);
            mode_1_V_Blank_interrupt = ((value & (1 << 4)) >> 4);
            mode_2_OAM_interrupt = ((value & (1 << 5)) >> 5);
            LYC_LY_coincidence_interrupt = ((value & (1 << 6)) >> 6);
            break;
        case 0xff42:
            lcd_scroll_y = value;
            break;
        case 0xff43:
            lcd_scroll_x = value;
            break;
        case 0xff44:
            lcd_line = 0;
            lcd_mode_flag = 0x2;
            break;
        case 0xff45:
            lcd_LY_compare = value;
            break;
        case 0xff46:
            break;
        case 0xff47:
            shade_for_color_0 = value & 0x2;
            shade_for_color_1 = (value & 0xc) >> 2;
            shade_for_color_2 = (value & 0x30) >> 4;
            shade_for_color_3 = (value & 0xc0) >> 6;
            break;
        case 0xff48:
            sprite_0_shade_for_color_0 = (value & 0xc) >> 2;
            sprite_0_shade_for_color_1 = (value & 0x30) >> 4;
            sprite_0_shade_for_color_2 = (value & 0xc0) >> 6;
            break;
        case 0xff49:
            sprite_1_shade_for_color_0 = (value & 0xc) >> 2;
            sprite_1_shade_for_color_1 = (value & 0x30) >> 4;
            sprite_1_shade_for_color_2 = (value & 0xc0) >> 6;
            break;
        case 0xff4a:
            window_y_position = value;
            break;
        case 0xff4b:
            window_x_position = value;
            break;
        case 0xff50:
            disable_bootROM();
            break;
        default:
            return 0;
    }
    return 1;
}

variable_types: value char


decompiled_code:
__int64 increment_timer()
{
__int64 result; // rax
char v1; // al

if ( (unsigned __int16)timer_counter <= 0xFFu )
return (unsigned int)(unsigned __int16)timer_counter++ + 1;
v1 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(v1 | 4));
result = (unsigned __int8)timer_modulo;
timer_counter = (unsigned __int8)timer_modulo;
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 result; // rax
char v1; // al

if ( (unsigned __int16)timer_counter <= 0xFFu )
return (unsigned int)(unsigned __int16)timer_counter++ + 1;
v1 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(v1 | 4));
result = (unsigned __int8)timer_modulo;
timer_counter = (unsigned __int8)timer_modulo;
return result;
}

original_code:
void increment_timer ( void )
{
    if ( timer_counter > 0xff )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x4));
        timer_counter = timer_modulo & 0xff;
    }
    else
    {
        timer_counter++;
    }
}

canonical_original_code:
void increment_timer()
{
    if ( timer_counter > 0xff )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) | 0x4));
        timer_counter = timer_modulo & 0xff;
    }
    else
    {
        timer_counter++;
    }
}


decompiled_code:
__int64 update_TIMA()
{
__int64 result; // rax

result = (unsigned __int8)timer_input_clock_select;
if ( timer_input_clock_select )
{
switch ( timer_input_clock_select )
{
case 1:
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0xF )
{
timer_cycles -= 16;
result = increment_timer();
}
break;
case 2:
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0x3F )
{
timer_cycles -= 64;
result = increment_timer();
}
break;
case 3:
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0xFF )
{
timer_cycles -= 256;
result = increment_timer();
}
break;
}
}
else
{
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0x3FF )
{
timer_cycles -= 1024;
result = increment_timer();
}
}
return result;
}

canonical_decompiled_code:
__int64 func1()
{
__int64 result; // rax

result = (unsigned __int8)timer_input_clock_select;
if ( timer_input_clock_select )
{
switch ( timer_input_clock_select )
{
case 1:
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0xF )
{
timer_cycles -= 16;
result = func0();
}
break;
case 2:
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0x3F )
{
timer_cycles -= 64;
result = func0();
}
break;
case 3:
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0xFF )
{
timer_cycles -= 256;
result = func0();
}
break;
}
}
else
{
result = (unsigned int)timer_cycles;
if ( (unsigned int)timer_cycles > 0x3FF )
{
timer_cycles -= 1024;
result = func0();
}
}
return result;
}

original_code:
void update_TIMA ( void )
{
    if ( (timer_input_clock_select == 0) && (timer_cycles >= 1024) )
    {
        timer_cycles -= 1024;
        increment_timer();
    }
    else if ( (timer_input_clock_select == 1) && (timer_cycles >= 16) )
    {
        timer_cycles -= 16;
        increment_timer();
    }
    else if ( (timer_input_clock_select == 2) && (timer_cycles >= 64) )
    {
        timer_cycles -= 64;
        increment_timer();
    }
    else if ( (timer_input_clock_select == 3) && (timer_cycles >= 256) )
    {
        timer_cycles -= 256;
        increment_timer();
    }
}

canonical_original_code:
void update_TIMA()
{
    if ( (timer_input_clock_select == 0) && (timer_cycles >= 1024) )
    {
        timer_cycles -= 1024;
        increment_timer();
    }
    else if ( (timer_input_clock_select == 1) && (timer_cycles >= 16) )
    {
        timer_cycles -= 16;
        increment_timer();
    }
    else if ( (timer_input_clock_select == 2) && (timer_cycles >= 64) )
    {
        timer_cycles -= 64;
        increment_timer();
    }
    else if ( (timer_input_clock_select == 3) && (timer_cycles >= 256) )
    {
        timer_cycles -= 256;
        increment_timer();
    }
}


decompiled_code:
__int64 update_DIV()
{
__int64 result; // rax

result = (unsigned int)(div_cycles + cpu_cycles);
if ( (unsigned int)result > 0xFF )
{
result = (unsigned int)(result - 256);
++div_reg;
}
div_cycles = result;
return result;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 result; // rax

result = (unsigned int)(div_cycles + cpu_cycles);
if ( (unsigned int)result > 0xFF )
{
result = (unsigned int)(result - 256);
++div_reg;
}
div_cycles = result;
return result;
}

original_code:
void update_DIV ( void )
{
    div_cycles += cpu_cycles;
    if ( div_cycles >= 256 )
    {
        div_cycles -= 256;
        div_reg++;
    }
}

canonical_original_code:
void update_DIV()
{
    div_cycles += cpu_cycles;
    if ( div_cycles >= 256 )
    {
        div_cycles -= 256;
        div_reg++;
    }
}


decompiled_code:
__int64 cycle_timer()
{
update_TIMA();
return update_DIV();
}

canonical_decompiled_code:
__int64 func3()
{
func1();
return func2();
}

original_code:
void cycle_timer ( void )
{
    update_TIMA();
    update_DIV();
}

canonical_original_code:
void cycle_timer()
{
    update_TIMA();
    update_DIV();
}


decompiled_code:
void init_timer()
{
div_reg = 0;
}

canonical_decompiled_code:
void func4()
{
div_reg = 0;
}

original_code:
void init_timer ( void )
{
    div_reg = 0;
}

canonical_original_code:
void init_timer()
{
    div_reg = 0;
}


decompiled_code:
__int64 __fastcall get_mem8(unsigned __int16 a1)
{
__int64 result; // rax
char v2[9]; // [rsp+Fh] [rbp-9h] BYREF

if ( (unsigned int)handle_ioregs_read(a1, v2) )
result = (unsigned __int8)v2[0];
else
result = *(unsigned __int8 *)(mem_base + a1);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned __int16 a1)
{
__int64 result; // rax
char v2[9]; // [rsp+Fh] [rbp-9h] BYREF

if ( (unsigned int)handle_ioregs_read(a1, v2) )
result = (unsigned __int8)v2[0];
else
result = *(unsigned __int8 *)(mem_base + a1);
return result;
}

original_code:
char get_mem8 ( unsigned short addr )
{
    char tmp;
    if ( handle_ioregs_read(addr, &tmp) )
        return tmp;
    else
        return *(mem_base + addr);
}

canonical_original_code:
char get_mem8(unsigned short addr)
{
    char tmp;
    if ( handle_ioregs_read(addr, &tmp) )
        return tmp;
    else
        return *(mem_base + addr);
}

variable_types: tmp char

return_type: char


decompiled_code:
__int64 __fastcall get_mem16(unsigned __int16 a1)
{
return *(unsigned __int16 *)(mem_base + a1);
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int16 a1)
{
return *(unsigned __int16 *)(mem_base + a1);
}

original_code:
short get_mem16 ( unsigned short addr )
{
    return *(short *)(mem_base + addr);
}

canonical_original_code:
short get_mem16(unsigned short addr)
{
    return *(short *)(mem_base + addr);
}

return_type: short


decompiled_code:
__int64 __fastcall set_mem8(unsigned __int16 a1, char a2)
{
__int64 result; // rax

result = handle_ioregs_write(a1, (unsigned int)a2);
if ( !(_DWORD)result )
{
result = mem_base;
*(_BYTE *)(mem_base + a1) = a2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned __int16 a1, char a2)
{
__int64 result; // rax

result = handle_ioregs_write(a1, (unsigned int)a2);
if ( !(_DWORD)result )
{
result = mem_base;
*(_BYTE *)(mem_base + a1) = a2;
}
return result;
}

original_code:
void set_mem8 ( unsigned short addr, char value )
{
    if ( handle_ioregs_write(addr, value) )
        return;
    else
        *(mem_base + addr) = value;
}

canonical_original_code:
void set_mem8(unsigned short addr, char value)
{
    if ( handle_ioregs_write(addr, value) )
        return;
    else
        *(mem_base + addr) = value;
}


decompiled_code:
__int64 __fastcall set_mem16(unsigned __int16 a1, __int16 a2)
{
__int64 result; // rax

result = mem_base;
*(_WORD *)(mem_base + a1) = a2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(unsigned __int16 a1, __int16 a2)
{
__int64 result; // rax

result = mem_base;
*(_WORD *)(mem_base + a1) = a2;
return result;
}

original_code:
void set_mem16 ( unsigned short addr, short value )
{
    *(short *)(mem_base + addr) = value;
}

canonical_original_code:
void set_mem16(unsigned short addr, short value)
{
    *(short *)(mem_base + addr) = value;
}

variable_types: value short


decompiled_code:
void *init_mem()
{
void *result; // rax

result = mmap(0LL, 0x10000uLL, 3, 34, 0, 0LL);
mem_base = (__int64)result;
if ( result == (void *)-1LL )
{
perror("mmap");
exit(1);
}
return result;
}

canonical_decompiled_code:
void *func4()
{
void *result; // rax

result = mmap(0LL, 0x10000uLL, 3, 34, 0, 0LL);
mem_base = (__int64)result;
if ( result == (void *)-1LL )
{
perror("mmap");
exit(1);
}
return result;
}


decompiled_code:
void check_interrupts()
{
char v0; // al
int v1; // eax
char v2; // al
char v3; // al
char v4; // al
char v5; // al

if ( ime )
{
if ( (get_mem8(65295LL) & 1) != 0 && (get_mem8(0xFFFFLL) & 1) != 0 )
{
v2 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v2 & 0xFE));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 64;
}
else if ( (get_mem8(65295LL) & 2) != 0 && (get_mem8(0xFFFFLL) & 2) != 0 )
{
v4 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v4 & 0xFD));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 72;
}
else if ( (get_mem8(65295LL) & 4) != 0 && (get_mem8(0xFFFFLL) & 4) != 0 )
{
v0 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v0 & 0xFB));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 80;
}
else if ( (get_mem8(65295LL) & 8) != 0 && (get_mem8(0xFFFFLL) & 8) != 0 )
{
v5 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v5 & 0xF7));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 88;
}
else if ( (get_mem8(65295LL) & 0x10) != 0 && (get_mem8(0xFFFFLL) & 0x10) != 0 )
{
v3 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v3 & 0xEF));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
cpu_cycles = 16;
pc = 96;
v1 = 16;
}
else
{
v1 = cpu_cycles;
}
total_cpu_cycles += v1;
}
}

canonical_decompiled_code:
void func0()
{
char v0; // al
int v1; // eax
char v2; // al
char v3; // al
char v4; // al
char v5; // al

if ( ime )
{
if ( (get_mem8(65295LL) & 1) != 0 && (get_mem8(0xFFFFLL) & 1) != 0 )
{
v2 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v2 & 0xFE));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 64;
}
else if ( (get_mem8(65295LL) & 2) != 0 && (get_mem8(0xFFFFLL) & 2) != 0 )
{
v4 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v4 & 0xFD));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 72;
}
else if ( (get_mem8(65295LL) & 4) != 0 && (get_mem8(0xFFFFLL) & 4) != 0 )
{
v0 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v0 & 0xFB));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 80;
}
else if ( (get_mem8(65295LL) & 8) != 0 && (get_mem8(0xFFFFLL) & 8) != 0 )
{
v5 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v5 & 0xF7));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
v1 = 16;
cpu_cycles = 16;
pc = 88;
}
else if ( (get_mem8(65295LL) & 0x10) != 0 && (get_mem8(0xFFFFLL) & 0x10) != 0 )
{
v3 = get_mem8(65295LL);
set_mem8(65295LL, (unsigned int)(char)(v3 & 0xEF));
ime = 0;
word_2F0 -= 2;
set_mem16((unsigned __int16)word_2F0, (unsigned int)pc);
cpu_cycles = 16;
pc = 96;
v1 = 16;
}
else
{
v1 = cpu_cycles;
}
total_cpu_cycles += v1;
}
}

original_code:
void check_interrupts ( void )
{
    if ( ime == 0 )
        return;
    if ( ((get_mem8(0xff0f) & 0x1) >> 0) && ((get_mem8(0xffff) & 0x1) >> 0) )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) & ~0x1));
        ime = 0;
        do { do { sp -= 2; set_mem16(sp, (pc)); } while (0); pc = (0x40); } while (0);
        cpu_cycles = 16;
    }
    else if ( ((get_mem8(0xff0f) & 0x2) >> 1) && ((get_mem8(0xffff) & 0x2) >> 1) )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) & ~0x2));
        ime = 0;
        do { do { sp -= 2; set_mem16(sp, (pc)); } while (0); pc = (0x48); } while (0);
        cpu_cycles = 16;
    }
    else if ( ((get_mem8(0xff0f) & 0x4) >> 2) && ((get_mem8(0xffff) & 0x4) >> 2) )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) & ~0x4));
        ime = 0;
        do { do { sp -= 2; set_mem16(sp, (pc)); } while (0); pc = (0x50); } while (0);
        cpu_cycles = 16;
    }
    else if ( ((get_mem8(0xff0f) & 0x8) >> 3) && ((get_mem8(0xffff) & 0x8) >> 3) )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) & ~0x8));
        ime = 0;
        do { do { sp -= 2; set_mem16(sp, (pc)); } while (0); pc = (0x58); } while (0);
        cpu_cycles = 16;
    }
    else if ( ((get_mem8(0xff0f) & 0x10) >> 4) && ((get_mem8(0xffff) & 0x10) >> 4) )
    {
        set_mem8(0xff0f, (get_mem8(0xff0f) & ~0x10));
        ime = 0;
        do { do { sp -= 2; set_mem16(sp, (pc)); } while (0); pc = (0x60); } while (0);
        cpu_cycles = 16;
    }
    total_cpu_cycles += cpu_cycles;
}


decompiled_code:
__int64 init_interrupt()
{
ime = 1;
set_mem8(65295LL, 0LL);
return set_mem8(0xFFFFLL, 31LL);
}

canonical_decompiled_code:
__int64 func1()
{
ime = 1;
set_mem8(65295LL, 0LL);
return set_mem8(0xFFFFLL, 31LL);
}

original_code:
void init_interrupt( void )
{
    ime = 1;
    set_mem8(0xff0f, 0);
    set_mem8(0xffff, (0x1 | 0x2 | 0x4 | 0x8 | 0x10));
}

canonical_original_code:
void init_interrupt()
{
    ime = 1;
    set_mem8(0xff0f, 0);
    set_mem8(0xffff, (0x1 | 0x2 | 0x4 | 0x8 | 0x10));
}


repo: mnemonikk/emacs-otr

decompiled_code:
void pools_allocator_free()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
static void
pools_allocator_free (void *allocator_data, void *chunk)
{
}

canonical_original_code:
static void pools_allocator_free(void *allocator_data, void *chunk)
{
}

variable_types:
chunk
void *


decompiled_code:
void __fastcall malloc_allocator_free(__int64 a1, void *a2)
{
free(a2);
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1, void *a2)
{
free(a2);
}

original_code:
static void
malloc_allocator_free (void *allocator_data, void *chunk)
{
    free(chunk);
}

canonical_original_code:
static void malloc_allocator_free(void *allocator_data, void *chunk)
{
    free(chunk);
}


decompiled_code:
void *__fastcall malloc_allocator_alloc(__int64 a1, size_t a2)
{
return malloc(a2);
}

canonical_decompiled_code:
void *__fastcall func2(__int64 a1, size_t a2)
{
return malloc(a2);
}

original_code:
static void*
malloc_allocator_alloc (void *allocator_data, size_t size)
{
    return malloc(size);
}

canonical_original_code:
static void *malloc_allocator_alloc(void *allocator_data, unsigned long size)
{
    return malloc(size);
}

variable_types:
size
unsigned long

return_type: void *


original_code:
static inline void*
pools_alloc (pools_t *pools, size_t size)
{
    void *p;
    size_t padded_size = (size + sizeof(long) - 1) / sizeof(long);
    if (pools->fill_ptr + padded_size >= (((size_t)2048) << pools->active_pool))
 return _pools_alloc(pools, size);
    p = pools->pools[pools->active_pool] + pools->fill_ptr;
    pools->fill_ptr += padded_size;
    return p;
}

canonical_original_code:
static inline void *pools_alloc(struct pools_t *pools, unsigned long size)
{
    void *p;
    unsigned long padded_size = (size + sizeof(long) - 1) / sizeof(long);
    if (pools->fill_ptr + padded_size >= (((unsigned long)2048) << pools->active_pool))
 return _pools_alloc(pools, size);
    p = pools->pools[pools->active_pool] + pools->fill_ptr;
    pools->fill_ptr += padded_size;
    return p;
}

variable_types: struct pools_t { int active_pool; unsigned long fill_ptr; long *pools[20]; } *

variable_types:
p
void *


decompiled_code:
void *__fastcall allocator_strdup(__int64 a1, const char *a2)
{
size_t v2; // r12
void *v3; // rax
void *v4; // r8

v2 = strlen(a2) + 1;
v3 = (void *)(*(__int64 (__fastcall **)(_QWORD, size_t))a1)(*(_QWORD *)(a1 + 16), v2);
v4 = v3;
if ( v3 )
v4 = memcpy(v3, a2, v2);
return v4;
}

canonical_decompiled_code:
void *__fastcall func5(__int64 a1, const char *a2)
{
size_t v2; // r12
void *v3; // rax
void *v4; // r8

v2 = strlen(a2) + 1;
v3 = (void *)(*(__int64 (__fastcall **)(_QWORD, size_t))a1)(*(_QWORD *)(a1 + 16), v2);
v4 = v3;
if ( v3 )
v4 = memcpy(v3, a2, v2);
return v4;
}

original_code:
char*
allocator_strdup (allocator_t *allocator, const char *str)
{
    size_t len = strlen(str) + 1;
    char *copy = (char*)((allocator)->alloc((allocator)->allocator_data, (len)));
    if (copy != 0)
 memcpy(copy, str, len);
    return copy;
}

canonical_original_code:
char *allocator_strdup(struct allocator_t *allocator, char *str)
{
    unsigned long len = strlen(str) + 1;
    char *copy = (char*)((allocator)->alloc((allocator)->allocator_data, (len)));
    if (copy != 0)
 memcpy(copy, str, len);
    return copy;
}

variable_types: struct allocator_t { void *(*alloc)(void *allocator_data, unsigned long size); void (*free)(void *allocator_data, void *chunk); void *allocator_data; } *

variable_types:
str
char *

variable_types:
len
unsigned long

variable_types:
copy
char *

return_type: char *


original_code:
int
init_pools (pools_t *pools)
{
    int i;
    pools->active_pool = 0;
    pools->fill_ptr = 0;
    for (i = 0; i < 20; ++i)
 pools->pools[i] = 0;
    pools->pools[0] = (long*)malloc(sizeof(long) * ((size_t)2048));
    if (pools->pools[0] == 0)
 return 0;
    memset(pools->pools[0], 0, sizeof(long) * ((size_t)2048));
    return 1;
}

canonical_original_code:
int init_pools(struct pools_t *pools)
{
    int i;
    pools->active_pool = 0;
    pools->fill_ptr = 0;
    for (i = 0; i < 20; ++i)
 pools->pools[i] = 0;
    pools->pools[0] = (long *)malloc(sizeof(long) * ((unsigned long)2048));
    if (pools->pools[0] == 0)
 return 0;
    memset(pools->pools[0], 0, sizeof(long) * ((unsigned long)2048));
    return 1;
}

variable_types: i int

user_defined_types: struct pools_t { int active_pool; unsigned long fill_ptr; long *pools[20]; }


decompiled_code:
void __fastcall reset_pools(__int64 a1)
{
*(_DWORD *)a1 = 0;
*(_QWORD *)(a1 + 8) = 0LL;
}

canonical_decompiled_code:
void __fastcall func1(__int64 a1)
{
*(_DWORD *)a1 = 0;
*(_QWORD *)(a1 + 8) = 0LL;
}

original_code:
void
reset_pools (pools_t *pools)
{
    pools->active_pool = 0;
    pools->fill_ptr = 0;
}

canonical_original_code:
void reset_pools(struct pools_t *pools)
{
    pools->active_pool = 0;
    pools->fill_ptr = 0;
}


decompiled_code:
_BOOL8 __fastcall free_pools(__int64 a1)
{
void **v1; // rbx

v1 = (void **)(a1 + 16);
do
{
if ( *v1 )
free(*v1);
++v1;
}
while ( v1 != (void **)(a1 + 176) );
return init_pools(a1);
}

original_code:
void
free_pools (pools_t *pools)
{
    int i;
    for (i = 0; i < 20; ++i)
 if (pools->pools[i] != 0)
     free(pools->pools[i]);
    init_pools(pools);
}

canonical_original_code:
void free_pools(struct pools_t *pools)
{
    int i;
    for (i = 0; i < 20; ++i)
 if (pools->pools[i] != 0)
     free(pools->pools[i]);
    init_pools(pools);
}


filename

decompiled_code:
__int64 __fastcall filename(void *src, unsigned int a2, unsigned int a3, const char *a4)
{
int v6; // ebx
int v7; // eax
int v8; // edx
__int64 result; // rax
char v10; // [rsp+Bh] [rbp-BEDh] BYREF
int v11; // [rsp+Ch] [rbp-BECh] BYREF
char v12[1504]; // [rsp+10h] [rbp-BE8h] BYREF
int v13[2]; // [rsp+5F0h] [rbp-608h] BYREF
char dest[1536]; // [rsp+5F8h] [rbp-600h] BYREF

v10 = 0;
v11 = 0;
v6 = strlen((const char *)src);
_bswap_32(a2);
v7 = _bswap_32(a3);
v13[0] = v8;
v13[1] = v7;
memcpy(dest, src, v6 + 1);
send_buf(v13, (unsigned int)(v6 + 9), &server, 6LL, 0LL, v12);
if ( (unsigned int)select_call((unsigned int)server, 1LL, 0LL, 1LL) != 1
|| (unsigned int)recv_buf(v12, 1500LL, (unsigned int)server, &server, &v10, &v11) == 5 )
{
return 1LL;
}
result = 3LL;
if ( v10 == 8 )
{
printf("Error %s does not exist on %s\n", (const char *)src, a4);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *src, unsigned int a2, unsigned int a3, const char *a4)
{
int v6; // ebx
int v7; // eax
int v8; // edx
__int64 result; // rax
char v10; // [rsp+Bh] [rbp-BEDh] BYREF
int v11; // [rsp+Ch] [rbp-BECh] BYREF
char v12[1504]; // [rsp+10h] [rbp-BE8h] BYREF
int v13[2]; // [rsp+5F0h] [rbp-608h] BYREF
char dest[1536]; // [rsp+5F8h] [rbp-600h] BYREF

v10 = 0;
v11 = 0;
v6 = strlen((const char *)src);
func0(a2);
v7 = func0(a3);
v13[0] = v8;
v13[1] = v7;
memcpy(dest, src, v6 + 1);
send_buf(v13, (unsigned int)(v6 + 9), &server, 6LL, 0LL, v12);
if ( (unsigned int)select_call((unsigned int)server, 1LL, 0LL, 1LL) != 1
|| (unsigned int)recv_buf(v12, 1500LL, (unsigned int)server, &server, &v10, &v11) == 5 )
{
return 1LL;
}
result = 3LL;
if ( v10 == 8 )
{
printf("Error %s does not exist on %s\n", (const char *)src, a4);
result = 0LL;
}
return result;
}

original_code:
STATE filename(char *fname, int32_t buf_size, int32_t window_size,
     char *server_machine) {
   uint8_t packet[1500];
   uint8_t buf[1500];
   uint8_t flag = 0;
   int32_t seq_num = 0;
   int32_t fname_len = strlen(fname) + 1;
   int32_t recv_check = 0;
 buf_size = htonl(buf_size);
 window_size = htonl(window_size);
   memcpy(buf, &buf_size, 4);
 memcpy(&buf[4], &window_size, 4);
   memcpy(&buf[8], fname, fname_len);
   send_buf(buf, fname_len + 8, &server, FNAME, 0, packet);
   if (select_call(server.sk_num, 1, 0, NOT_NULL) == 1) {
      recv_check = recv_buf(packet, 1500, server.sk_num, &server, &flag, &seq_num);
      if (recv_check == CRC_ERROR) {
         return FILENAME;
      }
      if (flag == FNAME_BAD) {
         printf("Error %s does not exist on %s\n", fname, server_machine);
         return (DONE);
      }
      return (FILE_OK);
   }
   return (FILENAME);
}

canonical_original_code:
enum State filename(char *fname, int buf_size, int window_size, char *server_machine) {
   unsigned char packet[1500];
   unsigned char buf[1500];
   unsigned char flag = 0;
   int seq_num = 0;
   int fname_len = strlen(fname) + 1;
   int recv_check = 0;
 buf_size = htonl(buf_size);
 window_size = htonl(window_size);
   memcpy(buf, &buf_size, 4);
 memcpy(&buf[4], &window_size, 4);
   memcpy(&buf[8], fname, fname_len);
   send_buf(buf, fname_len + 8, &server, FNAME, 0, packet);
   if (select_call(server.sk_num, 1, 0, NOT_NULL) == 1) {
      recv_check = recv_buf(packet, 1500, server.sk_num, &server, &flag, &seq_num);
      if (recv_check == CRC_ERROR) {
         return FILENAME;
      }
      if (flag == FNAME_BAD) {
         printf("Error %s does not exist on %s\n", fname, server_machine);
         return (DONE);
      }
      return (FILE_OK);
   }
   return (FILENAME);
}

variable_types:
fname
char *

variable_types:
packet
unsigned char [1500]

variable_types:
buf
unsigned char [1500]

variable_types:
flag
unsigned char

return_type: enum State { DONE=0, FILENAME=1, RECV_DATA=2, FILE_OK=3, SELREJ=4 }


decompiled_code:
void *__fastcall buffer_data(int a1, int a2, int a3, const void *a4, __int64 a5)
{
__int64 v7; // rbx
void *result; // rax
__int64 v9; // rbx

v7 = 1512LL * a2;
result = memcpy((void *)(v7 + *(_QWORD *)(a5 + 8) + 9), a4, a3);
v9 = *(_QWORD *)(a5 + 8) + v7;
*(_DWORD *)(v9 + 4) = a3;
*(_DWORD *)v9 = a1;
*(_BYTE *)(v9 + 8) = 0;
return result;
}

canonical_decompiled_code:
void *__fastcall func2(int a1, int a2, int a3, const void *a4, __int64 a5)
{
__int64 v7; // rbx
void *result; // rax
__int64 v9; // rbx

v7 = 1512LL * a2;
result = memcpy((void *)(v7 + *(_QWORD *)(a5 + 8) + 9), a4, a3);
v9 = *(_QWORD *)(a5 + 8) + v7;
*(_DWORD *)(v9 + 4) = a3;
*(_DWORD *)v9 = a1;
*(_BYTE *)(v9 + 8) = 0;
return result;
}

original_code:
void buffer_data(int32_t seq_num, int32_t seq_num_ndx, int32_t data_len,
       uint8_t *data_buf, Window *window ) {
 memcpy(window->window[seq_num_ndx].data, data_buf, data_len);
 window->window[seq_num_ndx].length = data_len;
 window->window[seq_num_ndx].seq_num = seq_num;
 window->window[seq_num_ndx].written = 0;
}

canonical_original_code:
void buffer_data(int seq_num, int seq_num_ndx, int data_len, unsigned char *data_buf, struct window *window) {
 memcpy(window->window[seq_num_ndx].data, data_buf, data_len);
 window->window[seq_num_ndx].length = data_len;
 window->window[seq_num_ndx].seq_num = seq_num;
 window->window[seq_num_ndx].written = 0;
}

variable_types: struct window { unsigned int window_size; struct packet { int seq_num; unsigned int length; unsigned char written; unsigned char data[1500]; } *window; unsigned int head; } *

user_defined_types: struct window { unsigned int window_size; struct packet *window; unsigned int head; }


decompiled_code:
unsigned int __fastcall check_args(int a1, const char **a2)
{
size_t v2; // rax
size_t v3; // rax
unsigned int v4; // eax
unsigned int result; // eax

if ( a1 != 8 )
{
printf("Usage %s fromFile toFile buffer_size error_rate window_size hostname port\n", *a2);
exit(-1);
}
v2 = strlen(a2[1]);
if ( v2 > 0x3E8 )
{
printf("FROM filename to long needs to be less than 1000 and is: %d\n", v2);
exit(-1);
}
v3 = strlen(a2[2]);
if ( v3 > 0x3E8 )
{
printf("TO filename to long needs to be less than 1000 and is: %d\n", v3);
exit(-1);
}
v4 = atoi(a2[3]);
if ( v4 - 400 > 0x3E8 )
{
printf("Buffer size needs to be between 400 and 1400 and is: %d\n", v4);
exit(-1);
}
result = atoi(a2[4]);
if ( result )
{
printf("Error rate needs to be between 0 and less than 1 and is: %d\n", result);
exit(-1);
}
return result;
}

canonical_decompiled_code:
unsigned int __fastcall func6(int a1, const char **a2)
{
size_t v2; // rax
size_t v3; // rax
unsigned int v4; // eax
unsigned int result; // eax

if ( a1 != 8 )
{
printf("Usage %s fromFile toFile buffer_size error_rate window_size hostname port\n", *a2);
exit(-1);
}
v2 = strlen(a2[1]);
if ( v2 > 0x3E8 )
{
printf("FROM filename to long needs to be less than 1000 and is: %d\n", v2);
exit(-1);
}
v3 = strlen(a2[2]);
if ( v3 > 0x3E8 )
{
printf("TO filename to long needs to be less than 1000 and is: %d\n", v3);
exit(-1);
}
v4 = atoi(a2[3]);
if ( v4 - 400 > 0x3E8 )
{
printf("Buffer size needs to be between 400 and 1400 and is: %d\n", v4);
exit(-1);
}
result = atoi(a2[4]);
if ( result )
{
printf("Error rate needs to be between 0 and less than 1 and is: %d\n", result);
exit(-1);
}
return result;
}

original_code:
void check_args(int argc, char **argv) {
   if (argc != 8) {
      printf("Usage %s fromFile toFile buffer_size error_rate window_size hostname port\n", argv[0]);
      exit(-1);
   }
   if (strlen(argv[1]) > 1000) {
      printf("FROM filename to long needs to be less than 1000 and is: %d\n", strlen(argv[1]));
      exit(-1);
   }
   if (strlen(argv[2]) > 1000) {
      printf("TO filename to long needs to be less than 1000 and is: %d\n", strlen(argv[2]));
      exit(-1);
   }
   if (atoi(argv[3]) < 400 || atoi(argv[3]) > 1400) {
      printf("Buffer size needs to be between 400 and 1400 and is: %d\n", atoi(argv[3]));
      exit(-1);
   }
   if (atoi(argv[4]) < 0 || atoi(argv[4]) >= 1) {
      printf("Error rate needs to be between 0 and less than 1 and is: %d\n", atoi(argv[4]));
      exit(-1);
   }
}

variable_types: argc int

variable_types:
argv
char **