decompiled_code:
__int64 render_sprites()
{
unsigned int i; // ebx
char v1; // r8
int v2; // er14
unsigned int v3; // er13
__int64 v4; // r12
int v5; // eax
int v6; // edx
__int64 result; // rax
unsigned __int8 v8; // r14
__int16 v9; // r13
unsigned __int8 v10; // r12
__int16 v11; // dx
unsigned __int8 v12; // r8
int v13; // er15
char v14; // r14
unsigned __int16 v15; // ax
char v16; // [rsp+Dh] [rbp-33h]
unsigned __int8 v17; // [rsp+Eh] [rbp-32h]
char v18; // [rsp+Eh] [rbp-32h]
unsigned __int8 v19; // [rsp+Fh] [rbp-31h]

memset(scanline_obj_priority, 0, sizeof(scanline_obj_priority));
for ( i = 65024; i != 65184; i += 4 )
{
v8 = memory_read(i);
v9 = v8 - 16;
v10 = memory_read(i + 1);
v17 = memory_read(i + 2);
result = memory_read(i + 3);
v19 = result;
if ( v8 )
{
if ( v9 <= 143 )
{
v11 = v10 - 8;
if ( v10 )
{
if ( v11 <= 159 )
{
v12 = *(_BYTE *)(gb + 51955LL);
result = v12;
if ( v9 <= v12 )
{
v13 = v12;
result = (unsigned __int8)sprite_height;
if ( v12 < (unsigned __int8)sprite_height + v9 )
{
v14 = v8 - 16;
if ( (((int)v19 >> 2) & 0x10) != 0 )
v1 = sprite_height - 1 - v12 + v14;
else
v1 = v12 - v14;
v15 = ((v19 << 10) & 0x2000) + 2 * (v1 + 8 * v17);
v18 = *(_BYTE *)(gb + v15 + 0x8000LL);
v16 = *(_BYTE *)(gb + (unsigned __int16)(v15 + 1) + 0x8000LL);
v3 = v11;
v4 = v11;
v2 = 0;
result = ((int)v19 >> 2) & 8;
do
{
if ( v3 <= 0x9F && !scanline_obj_priority[v4] && ((v19 & 0x80u) == 0 || !scanline_bg_priority[v4]) )
{
scanline_obj_priority[v4] = 1;
v5 = 128 >> flip_table[v2 | ((int)v19 >> 2) & 8];
v6 = 4 * ((int)(unsigned __int8)(v5 & v16) >> (7 - flip_table[v2 | ((int)v19 >> 2) & 8]));
result = (unsigned int)(2
* ((int)(unsigned __int8)(v18 & v5) >> (7
- flip_table[v2 | ((int)v19 >> 2) & 8])));
LOBYTE(result) = v6 | result;
if ( (_BYTE)result )
result = update_screen_buffer(
v13,
v3,
(unsigned __int16)((*(unsigned __int8 *)(gb
+ (unsigned __int8)(8 * (v19 & 7) + result + 1)
+ 51696LL) << 8) | *(unsigned __int8 *)(gb + (unsigned __int8)(8 * (v19 & 7) + result) + 51696LL)));
}
++v2;
++v3;
++v4;
}
while ( v2 != 8 );
}
}
}
}
}
}
}
return result;
}

canonical_decompiled_code:
__int64 func2()
{
unsigned int i; // ebx
char v1; // r8
int v2; // er14
unsigned int v3; // er13
__int64 v4; // r12
int v5; // eax
int v6; // edx
__int64 result; // rax
unsigned __int8 v8; // r14
__int16 v9; // r13
unsigned __int8 v10; // r12
__int16 v11; // dx
unsigned __int8 v12; // r8
int v13; // er15
char v14; // r14
unsigned __int16 v15; // ax
char v16; // [rsp+Dh] [rbp-33h]
unsigned __int8 v17; // [rsp+Eh] [rbp-32h]
char v18; // [rsp+Eh] [rbp-32h]
unsigned __int8 v19; // [rsp+Fh] [rbp-31h]

memset(scanline_obj_priority, 0, sizeof(scanline_obj_priority));
for ( i = 65024; i != 65184; i += 4 )
{
v8 = memory_read(i);
v9 = v8 - 16;
v10 = memory_read(i + 1);
v17 = memory_read(i + 2);
result = memory_read(i + 3);
v19 = result;
if ( v8 )
{
if ( v9 <= 143 )
{
v11 = v10 - 8;
if ( v10 )
{
if ( v11 <= 159 )
{
v12 = *(_BYTE *)(gb + 51955LL);
result = v12;
if ( v9 <= v12 )
{
v13 = v12;
result = (unsigned __int8)sprite_height;
if ( v12 < (unsigned __int8)sprite_height + v9 )
{
v14 = v8 - 16;
if ( (((int)v19 >> 2) & 0x10) != 0 )
v1 = sprite_height - 1 - v12 + v14;
else
v1 = v12 - v14;
v15 = ((v19 << 10) & 0x2000) + 2 * (v1 + 8 * v17);
v18 = *(_BYTE *)(gb + v15 + 0x8000LL);
v16 = *(_BYTE *)(gb + (unsigned __int16)(v15 + 1) + 0x8000LL);
v3 = v11;
v4 = v11;
v2 = 0;
result = ((int)v19 >> 2) & 8;
do
{
if ( v3 <= 0x9F && !scanline_obj_priority[v4] && ((v19 & 0x80u) == 0 || !scanline_bg_priority[v4]) )
{
scanline_obj_priority[v4] = 1;
v5 = 128 >> flip_table[v2 | ((int)v19 >> 2) & 8];
v6 = 4 * ((int)(unsigned __int8)(v5 & v16) >> (7 - flip_table[v2 | ((int)v19 >> 2) & 8]));
result = (unsigned int)(2
* ((int)(unsigned __int8)(v18 & v5) >> (7
- flip_table[v2 | ((int)v19 >> 2) & 8])));
LOBYTE(result) = v6 | result;
if ( (_BYTE)result )
result = func0(
v13,
v3,
(unsigned __int16)((*(unsigned __int8 *)(gb
+ (unsigned __int8)(8 * (v19 & 7) + result + 1)
+ 51696LL) << 8) | *(unsigned __int8 *)(gb + (unsigned __int8)(8 * (v19 & 7) + result) + 51696LL)));
}
++v2;
++v3;
++v4;
}
while ( v2 != 8 );
}
}
}
}
}
}
}
return result;
}

original_code:
void render_sprites(void) {
    memset(scanline_obj_priority, 0, 160);
    uint16_t sprite_attribute_index = 0xFE00;
    int sprite_count = 40;
    for(int sprite = 0; sprite < sprite_count; ++sprite) {
        s16 y_position = ((s16)memory_read(sprite_attribute_index++)) - 16;
        s16 x_position = ((s16)memory_read(sprite_attribute_index++)) - 8;
        uint8_t tile_number = memory_read(sprite_attribute_index++);
        uint8_t tile_attributes = memory_read(sprite_attribute_index++);
        if(y_position == -16 || y_position >= 144)
            continue;
        if(x_position == -8 || x_position >= 160)
            continue;
        s16 scanline = gb->hw_registers[LY];
        if((scanline >= y_position) && (scanline < (y_position + sprite_height))) {
            uint8_t pallete_number = tile_attributes & 0x07;
            uint16_t vram_offset = (tile_attributes & 0x08) << 10;
            uint8_t x_flip = (tile_attributes & 0x20) >> 2;
            uint8_t y_flip = (tile_attributes & 0x40) >> 2;
            uint8_t bg_priority = tile_attributes & 0x80;
            s8 sprite_line = scanline - y_position;
            if(y_flip) {
                sprite_line -= ( sprite_height - 1 );
                sprite_line *= -1;
            }
            uint16_t sprite_address = vram_offset + (tile_number * 16) + (sprite_line * 2);
            uint8_t low = gb->vram[sprite_address++];
            uint8_t high = gb->vram[sprite_address];
            for(int sprite_pixel = 0; sprite_pixel < 8; ++sprite_pixel){
                int x_pixel = x_position + sprite_pixel;
                if(x_pixel < 0 || x_pixel > 159 || scanline_obj_priority[x_pixel]) {
                    continue;
                }
                if(bg_priority && scanline_bg_priority[x_pixel]) {
                    continue;
                }
                scanline_obj_priority[x_pixel] = 0x01;
                uint8_t shift = flip_table[x_flip | sprite_pixel];
                uint8_t bit = 0x80 >> shift;
                shift = 7 - shift;
                uint8_t pallete_index_offset;
                pallete_index_offset = ((low & bit) >> shift) << 1;
                pallete_index_offset |= ((high & bit) >> shift) << 2;
                if(pallete_index_offset == 0) {
                    continue;
                }
                uint8_t pallete_index = pallete_index_offset + pallete_number * 8;
                uint16_t pallete_entry;
                pallete_entry = gb->ob_pallete[pallete_index++];
                pallete_entry |= (gb->ob_pallete[pallete_index] << 8);
                update_screen_buffer(scanline, x_pixel, pallete_entry);
            }
        }
    }
}

canonical_original_code:
void render_sprites() {
    memset(scanline_obj_priority, 0, 160);
    unsigned short sprite_attribute_index = 0xFE00;
    int sprite_count = 40;
    for(int sprite = 0; sprite < sprite_count; ++sprite) {
        short y_position = ((s16)memory_read(sprite_attribute_index++)) - 16;
        short x_position = ((s16)memory_read(sprite_attribute_index++)) - 8;
        unsigned char tile_number = memory_read(sprite_attribute_index++);
        unsigned char tile_attributes = memory_read(sprite_attribute_index++);
        if(y_position == -16 || y_position >= 144)
            continue;
        if(x_position == -8 || x_position >= 160)
            continue;
        short scanline = gb->hw_registers[LY];
        if((scanline >= y_position) && (scanline < (y_position + sprite_height))) {
            unsigned char pallete_number = tile_attributes & 0x07;
            unsigned short vram_offset = (tile_attributes & 0x08) << 10;
            unsigned char x_flip = (tile_attributes & 0x20) >> 2;
            unsigned char y_flip = (tile_attributes & 0x40) >> 2;
            unsigned char bg_priority = tile_attributes & 0x80;
            char sprite_line = scanline - y_position;
            if(y_flip) {
                sprite_line -= ( sprite_height - 1 );
                sprite_line *= -1;
            }
            unsigned short sprite_address = vram_offset + (tile_number * 16) + (sprite_line * 2);
            unsigned char low = gb->vram[sprite_address++];
            unsigned char high = gb->vram[sprite_address];
            for(int sprite_pixel = 0; sprite_pixel < 8; ++sprite_pixel){
                int x_pixel = x_position + sprite_pixel;
                if(x_pixel < 0 || x_pixel > 159 || scanline_obj_priority[x_pixel]) {
                    continue;
                }
                if(bg_priority && scanline_bg_priority[x_pixel]) {
                    continue;
                }
                scanline_obj_priority[x_pixel] = 0x01;
                unsigned char shift = flip_table[x_flip | sprite_pixel];
                unsigned char bit = 0x80 >> shift;
                shift = 7 - shift;
                unsigned char pallete_index_offset;
                pallete_index_offset = ((low & bit) >> shift) << 1;
                pallete_index_offset |= ((high & bit) >> shift) << 2;
                if(pallete_index_offset == 0) {
                    continue;
                }
                unsigned char pallete_index = pallete_index_offset + pallete_number * 8;
                unsigned short pallete_entry;
                pallete_entry = gb->ob_pallete[pallete_index++];
                pallete_entry |= (gb->ob_pallete[pallete_index] << 8);
                update_screen_buffer(scanline, x_pixel, pallete_entry);
            }
        }
    }
}

variable_types: sprite int

variable_types: scanline short


repo: tylerschloesser/cgbemu-core

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

if ( screen_initialized )
_assert_fail("screen_initialized == false", "screen.c", 0x26u, "initialize_screen");
result = memset(screen_buffer, 0, sizeof(screen_buffer));
screen_initialized = 1;
return result;
}

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

if ( screen_initialized )
_assert_fail("screen_initialized == false", "screen.c", 0x26u, "initialize_screen");
result = memset(screen_buffer, 0, sizeof(screen_buffer));
screen_initialized = 1;
return result;
}

original_code:
void initialize_screen() {
    ((screen_initialized == 0) ? (void) (0) : __assert_fail ("screen_initialized == false", "screen.c", 38, __extension__ __PRETTY_FUNCTION__));
    memset(screen_buffer, 0, (144 * 160) * sizeof(uint16_t));
    screen_initialized = 1;
}

canonical_original_code:
void initialize_screen() {
    ((screen_initialized == 0) ? (void) (0) : __assert_fail ("screen_initialized == false", "screen.c", 38, __extension__ __PRETTY_FUNCTION__));
    memset(screen_buffer, 0, (144 * 160) * sizeof(unsigned short));
    screen_initialized = 1;
}

return_type: void


decompiled_code:
__int16 __fastcall update_lcd_control_register(char a1)
{
__int16 result; // ax

bg_enabled = a1 & 1;
obj_enabled = a1 & 2;
sprite_height = (a1 & 4) == 0 ? 8 : 16;
bg_tile_map = (a1 & 8) == 0 ? 6144 : 7168;
if ( (a1 & 0x10) != 0 )
{
tile_data = 0;
signed_tiles = 0;
}
else
{
tile_data = 2048;
signed_tiles = 1;
}
tile_data_offset = tile_data;
window_enabled = a1 & 0x20;
result = (a1 & 0x40) == 0 ? 6144 : 7168;
window_tile_map = result;
lcd_enabled = a1 & 0x80;
return result;
}

canonical_decompiled_code:
__int16 __fastcall func4(char a1)
{
__int16 result; // ax

bg_enabled = a1 & 1;
obj_enabled = a1 & 2;
sprite_height = (a1 & 4) == 0 ? 8 : 16;
bg_tile_map = (a1 & 8) == 0 ? 6144 : 7168;
if ( (a1 & 0x10) != 0 )
{
tile_data = 0;
signed_tiles = 0;
}
else
{
tile_data = 2048;
signed_tiles = 1;
}
tile_data_offset = tile_data;
window_enabled = a1 & 0x20;
result = (a1 & 0x40) == 0 ? 6144 : 7168;
window_tile_map = result;
lcd_enabled = a1 & 0x80;
return result;
}

original_code:
void update_lcd_control_register(uint8_t lcd_control)
{
    bg_enabled = (lcd_control & 0x01);
    obj_enabled = (lcd_control & 0x02);
    if(lcd_control & 0x04) {
        sprite_height = 16;
    } else {
        sprite_height = 8;
    }
    if(lcd_control & 0x08){
        bg_tile_map = 0x1C00;
    } else {
        bg_tile_map = 0x1800;
    }
    if(lcd_control & 0x10) {
        tile_data = 0x0000;
        signed_tiles = 0x00;
    } else {
        tile_data = 0x0800;
        signed_tiles = 0x01;
    }
    tile_data_offset = tile_data;
    window_enabled = (lcd_control & 0x20);
    if(lcd_control & 0x40) {
        window_tile_map = 0x1C00;
    } else {
        window_tile_map = 0x1800;
    }
    lcd_enabled = (lcd_control & 0x80);
}

canonical_original_code:
void update_lcd_control_register(unsigned char lcd_control)
{
    bg_enabled = (lcd_control & 0x01);
    obj_enabled = (lcd_control & 0x02);
    if(lcd_control & 0x04) {
        sprite_height = 16;
    } else {
        sprite_height = 8;
    }
    if(lcd_control & 0x08){
        bg_tile_map = 0x1C00;
    } else {
        bg_tile_map = 0x1800;
    }
    if(lcd_control & 0x10) {
        tile_data = 0x0000;
        signed_tiles = 0x00;
    } else {
        tile_data = 0x0800;
        signed_tiles = 0x01;
    }
    tile_data_offset = tile_data;
    window_enabled = (lcd_control & 0x20);
    if(lcd_control & 0x40) {
        window_tile_map = 0x1C00;
    } else {
        window_tile_map = 0x1800;
    }
    lcd_enabled = (lcd_control & 0x80);
}


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

if ( bg_enabled )
result = render_background();
if ( obj_enabled )
result = render_sprites();
return result;
}

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

if ( bg_enabled )
result = func1();
if ( obj_enabled )
result = func2();
return result;
}

original_code:
void render_scanline(void)
{
    if(bg_enabled) {
        render_background();
    }
    if(obj_enabled) {
        render_sprites();
    }
}

canonical_original_code:
void render_scanline()
{
    if(bg_enabled) {
        render_background();
    }
    if(obj_enabled) {
        render_sprites();
    }
}


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

if ( initialized )
_assert_fail("initialized == false", "joypad.c", 0x14u, "initialize_joypad");
joypad_state = -1;
result = gb;
*(_BYTE *)(gb + 51887LL) |= 0xFu;
initialized = 1;
return result;
}

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

if ( initialized )
_assert_fail("initialized == false", "joypad.c", 0x14u, "initialize_joypad");
joypad_state = -1;
result = gb;
*(_BYTE *)(gb + 51887LL) |= 0xFu;
initialized = 1;
return result;
}

original_code:
void initialize_joypad()
{
    ((initialized == 0) ? (void) (0) : __assert_fail ("initialized == false", "joypad.c", 20, __extension__ __PRETTY_FUNCTION__));
    joypad_state = 0xFF;
    gb->hw_registers[P1] |= 0xF;
    initialized = 1;
}


decompiled_code:
__int64 reinitialize_joypad()
{
if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x1Eu, "reinitialize_joypad");
initialized = 0;
return initialize_joypad();
}

canonical_decompiled_code:
__int64 func1()
{
if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x1Eu, "reinitialize_joypad");
initialized = 0;
return func0();
}

original_code:
void reinitialize_joypad()
{
    ((initialized == 1) ? (void) (0) : __assert_fail ("initialized == true", "joypad.c", 30, __extension__ __PRETTY_FUNCTION__));
    initialized = 0;
    initialize_joypad();
}


decompiled_code:
__int64 get_joypad_state()
{
char v0; // dl
__int64 result; // rax
int v2; // ecx

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x26u, "get_joypad_state");
v0 = *(_BYTE *)(gb + 51887LL);
result = 15LL;
v2 = v0 & 0x30;
if ( (v0 & 0x30) != 0 )
{
if ( (v0 & 0x10) != 0 )
{
result = 0xFFFFFFFFLL;
if ( (v0 & 0x20) == 0 )
result = v2 | (unsigned int)((unsigned __int8)joypad_state >> 4);
}
else
{
result = v2 | joypad_state & 0xFu;
}
}
return result;
}

canonical_decompiled_code:
__int64 func2()
{
char v0; // dl
__int64 result; // rax
int v2; // ecx

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x26u, "get_joypad_state");
v0 = *(_BYTE *)(gb + 51887LL);
result = 15LL;
v2 = v0 & 0x30;
if ( (v0 & 0x30) != 0 )
{
if ( (v0 & 0x10) != 0 )
{
result = 0xFFFFFFFFLL;
if ( (v0 & 0x20) == 0 )
result = v2 | (unsigned int)((unsigned __int8)joypad_state >> 4);
}
else
{
result = v2 | joypad_state & 0xFu;
}
}
return result;
}

original_code:
u8 get_joypad_state() {
    ((initialized == 1) ? (void) (0) : __assert_fail ("initialized == true", "joypad.c", 38, __extension__ __PRETTY_FUNCTION__));
    u8 joypad_select = gb->hw_registers[P1] & 0x30;
    if((joypad_select & 0x30) == 0) {
        return (joypad_select | 0x0F);
    } else if((joypad_select & 0x10) == 0) {
        return (joypad_select | ((joypad_state >> 0) & 0x0F));
    } else if((joypad_select & 0x20) == 0) {
        return (joypad_select | ((joypad_state >> 4) & 0x0F));
    }
    return 0xFF;
}

canonical_original_code:
unsigned char get_joypad_state() {
    ((initialized == 1) ? (void) (0) : __assert_fail ("initialized == true", "joypad.c", 38, __extension__ __PRETTY_FUNCTION__));
    unsigned char joypad_select = gb->hw_registers[P1] & 0x30;
    if((joypad_select & 0x30) == 0) {
        return (joypad_select | 0x0F);
    } else if((joypad_select & 0x10) == 0) {
        return (joypad_select | ((joypad_state >> 0) & 0x0F));
    } else if((joypad_select & 0x20) == 0) {
        return (joypad_select | ((joypad_state >> 4) & 0x0F));
    }
    return 0xFF;
}

return_type: unsigned char


decompiled_code:
__int64 __fastcall joypad_down(int a1)
{
__int64 result; // rax

if ( !initialized )
_assert_fail("initialized", "joypad.c", 0x3Au, "joypad_down");
if ( a1 > 7 )
_assert_fail("gb_key < 8", "joypad.c", 0x3Bu, "joypad_down");
joypad_state &= __ROL4__(-2, a1);
result = get_joypad_state() & 0xF;
*(_BYTE *)(gb + 51887LL) |= result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(int a1)
{
__int64 result; // rax

if ( !initialized )
_assert_fail("initialized", "joypad.c", 0x3Au, "joypad_down");
if ( a1 > 7 )
_assert_fail("gb_key < 8", "joypad.c", 0x3Bu, "joypad_down");
joypad_state &= __ROL4__(-2, a1);
result = func2() & 0xF;
*(_BYTE *)(gb + 51887LL) |= result;
return result;
}

original_code:
void joypad_down(int gb_key) {
    ((initialized) ? (void) (0) : __assert_fail ("initialized", "joypad.c", 58, __extension__ __PRETTY_FUNCTION__));
    ((gb_key < 8) ? (void) (0) : __assert_fail ("gb_key < 8", "joypad.c", 59, __extension__ __PRETTY_FUNCTION__));
    joypad_state &= ~(1 << gb_key);
    gb->hw_registers[P1] |= (get_joypad_state() & 0x0F);
}


decompiled_code:
__int64 __fastcall joypad_up(int a1)
{
__int64 result; // rax

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x46u, "joypad_up");
if ( a1 > 7 )
_assert_fail("gb_key < 8", "joypad.c", 0x47u, "joypad_up");
joypad_state |= 1 << a1;
result = get_joypad_state() & 0xF;
*(_BYTE *)(gb + 51887LL) |= result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1)
{
__int64 result; // rax

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x46u, "joypad_up");
if ( a1 > 7 )
_assert_fail("gb_key < 8", "joypad.c", 0x47u, "joypad_up");
joypad_state |= 1 << a1;
result = func2() & 0xF;
*(_BYTE *)(gb + 51887LL) |= result;
return result;
}

original_code:
void joypad_up(int gb_key) {
    ((initialized == 1) ? (void) (0) : __assert_fail ("initialized == true", "joypad.c", 70, __extension__ __PRETTY_FUNCTION__));
    ((gb_key < 8) ? (void) (0) : __assert_fail ("gb_key < 8", "joypad.c", 71, __extension__ __PRETTY_FUNCTION__));
    joypad_state |= (1 << gb_key);
    gb->hw_registers[P1] |= (get_joypad_state() & 0x0F);
}


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

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x53u, "joypad_select_button_keys");
result = gb;
*(_BYTE *)(gb + 51887LL) = -33;
return result;
}

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

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x53u, "joypad_select_button_keys");
result = gb;
*(_BYTE *)(gb + 51887LL) = -33;
return result;
}

original_code:
void joypad_select_button_keys() {
    ((initialized == 1) ? (void) (0) : __assert_fail ("initialized == true", "joypad.c", 83, __extension__ __PRETTY_FUNCTION__));
    gb->hw_registers[P1] = ~0x20;
    gb->hw_registers[P1] |= ((joypad_state >> 4) & 0x0F);
}


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

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x62u, "joypad_select_direction_keys");
result = gb;
*(_BYTE *)(gb + 51887LL) = -17;
return result;
}

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

if ( !initialized )
_assert_fail("initialized == true", "joypad.c", 0x62u, "joypad_select_direction_keys");
result = gb;
*(_BYTE *)(gb + 51887LL) = -17;
return result;
}

original_code:
void joypad_select_direction_keys() {
    ((initialized == 1) ? (void) (0) : __assert_fail ("initialized == true", "joypad.c", 98, __extension__ __PRETTY_FUNCTION__));
    gb->hw_registers[P1] = ~0x10;
    gb->hw_registers[P1] |= ((joypad_state >> 0) & 0x0F);
}


decompiled_code:
__int64 cgbemu_run_to_vblank()
{
return emulate_cpu();
}

canonical_decompiled_code:
__int64 func0()
{
return emulate_cpu();
}

original_code:
void cgbemu_run_to_vblank()
{
    emulate_cpu();
}


decompiled_code:
__int64 __fastcall initialize_cgbemu(__int64 a1, __int64 a2)
{
unsigned int v2; // ebx

if ( !a1 )
_assert_fail("cartridge_filepath", "cgbemu.c", 0xFu, "initialize_cgbemu");
initialize_gameboy(a2 != 0);
v2 = initialize_cartridge(a1);
if ( v2 )
return 1;
initialize_cpu(a2 != 0);
initialize_joypad();
initialize_screen();
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, __int64 a2)
{
unsigned int v2; // ebx

if ( !a1 )
_assert_fail("cartridge_filepath", "cgbemu.c", 0xFu, "initialize_cgbemu");
initialize_gameboy(a2 != 0);
v2 = initialize_cartridge(a1);
if ( v2 )
return 1;
initialize_cpu(a2 != 0);
initialize_joypad();
initialize_screen();
return v2;
}

original_code:
int initialize_cgbemu(const char* cartridge_filepath, const char* bios_filepath) {
    ((cartridge_filepath) ? (void) (0) : __assert_fail ("cartridge_filepath", "cgbemu.c", 15, __extension__ __PRETTY_FUNCTION__));
    if(cartridge_filepath == ((void *)0)) {
        fprintf(stderr, "No cartridge filepath provided\n");
        return 1;
    }
    _Bool use_bios = bios_filepath == ((void *)0) ? 0 : 1;
    initialize_gameboy(use_bios, bios_filepath);
    if(initialize_cartridge(cartridge_filepath) != 0) {
        return 1;
    }
    initialize_cpu(use_bios);
    initialize_joypad();
    initialize_screen();
    return 0;
}

canonical_original_code:
int initialize_cgbemu(char *cartridge_filepath, char *bios_filepath) {
    ((cartridge_filepath) ? (void) (0) : __assert_fail ("cartridge_filepath", "cgbemu.c", 15, __extension__ __PRETTY_FUNCTION__));
    if(cartridge_filepath == ((void *)0)) {
        fprintf(stderr, "No cartridge filepath provided\n");
        return 1;
    }
    _Bool use_bios = bios_filepath == ((void *)0) ? 0 : 1;
    initialize_gameboy(use_bios, bios_filepath);
    if(initialize_cartridge(cartridge_filepath) != 0) {
        return 1;
    }
    initialize_cpu(use_bios);
    initialize_joypad();
    initialize_screen();
    return 0;
}

return_type: int


decompiled_code:
__int64 __fastcall cgbemu_set_button_pressed(int a1, char a2)
{
__int64 v2; // rdi
__int64 result; // rax

switch ( a1 )
{
case 0:
v2 = 2LL;
goto LABEL_3;
case 1:
v2 = 3LL;
goto LABEL_3;
case 2:
v2 = 0LL;
goto LABEL_3;
case 3:
v2 = 1LL;
goto LABEL_3;
case 4:
v2 = 4LL;
goto LABEL_3;
case 5:
v2 = 5LL;
goto LABEL_3;
case 6:
v2 = 6LL;
goto LABEL_3;
case 7:
v2 = 7LL;
LABEL_3:
if ( a2 )
result = joypad_down(v2);
else
result = joypad_up(v2);
break;
default:
return result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, char a2)
{
__int64 v2; // rdi
__int64 result; // rax

switch ( a1 )
{
case 0:
v2 = 2LL;
goto LABEL_3;
case 1:
v2 = 3LL;
goto LABEL_3;
case 2:
v2 = 0LL;
goto LABEL_3;
case 3:
v2 = 1LL;
goto LABEL_3;
case 4:
v2 = 4LL;
goto LABEL_3;
case 5:
v2 = 5LL;
goto LABEL_3;
case 6:
v2 = 6LL;
goto LABEL_3;
case 7:
v2 = 7LL;
LABEL_3:
if ( a2 )
result = joypad_down(v2);
else
result = joypad_up(v2);
break;
default:
return result;
}
return result;
}

original_code:
void cgbemu_set_button_pressed(Button button, _Bool pressed)
{
    int gb_key;
    switch(button) {
        case UP:
            gb_key = JOYPAD_UP;
            break;
        case DOWN:
            gb_key = JOYPAD_DOWN;
            break;
        case RIGHT:
            gb_key = JOYPAD_RIGHT;
            break;
        case LEFT:
            gb_key = JOYPAD_LEFT;
            break;
        case A:
            gb_key = JOYPAD_A;
            break;
        case B:
            gb_key = JOYPAD_B;
            break;
        case SELECT:
            gb_key = JOYPAD_SELECT;
            break;
        case START:
            gb_key = JOYPAD_START;
            break;
        default:
            return;
    }
    if(pressed) {
        joypad_down(gb_key);
    } else {
        joypad_up(gb_key);
    }
}

canonical_original_code:
void cgbemu_set_button_pressed(enum Button button, _Bool pressed)
{
    int gb_key;
    switch(button) {
        case UP:
            gb_key = JOYPAD_UP;
            break;
        case DOWN:
            gb_key = JOYPAD_DOWN;
            break;
        case RIGHT:
            gb_key = JOYPAD_RIGHT;
            break;
        case LEFT:
            gb_key = JOYPAD_LEFT;
            break;
        case A:
            gb_key = JOYPAD_A;
            break;
        case B:
            gb_key = JOYPAD_B;
            break;
        case SELECT:
            gb_key = JOYPAD_SELECT;
            break;
        case START:
            gb_key = JOYPAD_START;
            break;
        default:
            return;
    }
    if(pressed) {
        joypad_down(gb_key);
    } else {
        joypad_up(gb_key);
    }
}

variable_types: enum Button { UP=0, DOWN=1, RIGHT=2, LEFT=3, A=4, B=5, SELECT=6, START=7 }


decompiled_code:
void *cgbemu_get_screen_buffer()
{
return &screen_buffer;
}

canonical_decompiled_code:
void *func3()
{
return &screen_buffer;
}

original_code:
uint16_t* cgbemu_get_screen_buffer()
{
    return (uint16_t*)screen_buffer;
}

canonical_original_code:
unsigned short *cgbemu_get_screen_buffer()
{
    return (unsigned short *)screen_buffer;
}

return_type: unsigned short *


decompiled_code:
__int64 cgbemu_save_state()
{
return gameboy_save_state();
}

canonical_decompiled_code:
__int64 func4()
{
return gameboy_save_state();
}

original_code:
void cgbemu_save_state(const char* filepath) {
    gameboy_save_state(filepath);
}

canonical_original_code:
void cgbemu_save_state(char *filepath) {
    gameboy_save_state(filepath);
}

variable_types:
filepath
char *


decompiled_code:
__int64 cgbemu_load_state()
{
return gameboy_load_state();
}

canonical_decompiled_code:
__int64 func5()
{
return gameboy_load_state();
}

original_code:
void cgbemu_load_state(const char* filepath) {
    gameboy_load_state(filepath);
}

canonical_original_code:
void cgbemu_load_state(char *filepath) {
    gameboy_load_state(filepath);
}


decompiled_code:
__int64 __fastcall get_cartridge_ram_size(int a1)
{
__int64 result; // rax

if ( a1 == 2 )
return 0x2000LL;
if ( a1 > 2 )
{
result = 0xFFFFFFFFLL;
if ( a1 == 3 )
result = 0x8000LL;
}
else
{
result = (unsigned int)a1;
if ( a1 )
{
result = 0xFFFFFFFFLL;
if ( a1 == 1 )
result = 2048LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
__int64 result; // rax

if ( a1 == 2 )
return 0x2000LL;
if ( a1 > 2 )
{
result = 0xFFFFFFFFLL;
if ( a1 == 3 )
result = 0x8000LL;
}
else
{
result = (unsigned int)a1;
if ( a1 )
{
result = 0xFFFFFFFFLL;
if ( a1 == 1 )
result = 2048LL;
}
}
return result;
}

original_code:
static int get_cartridge_ram_size(int header_value) {
    switch(header_value) {
        case 0:
            return 0;
        case 1:
            return 0x800;
        case 2:
            return 0x2000;
        case 3:
            return 0x8000;
    }
    return -1;
}


decompiled_code:
__int64 __fastcall get_cartridge_rom_size(unsigned int a1)
{
__int64 result; // rax

result = (unsigned int)(0x8000 << a1);
if ( a1 >= 8 )
result = 0xFFFFFFFFLL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int a1)
{
__int64 result; // rax

result = (unsigned int)(0x8000 << a1);
if ( a1 >= 8 )
result = 0xFFFFFFFFLL;
return result;
}

original_code:
static int get_cartridge_rom_size(int header_value) {
    if(header_value >= 0 && header_value <= 7) {
        return(0x8000 << header_value);
    }
    return -1;
}


decompiled_code:
__int64 verify_cartridge()
{
int v0; // ebx
int v1; // edx
unsigned __int8 *v2; // rax
__int64 v3; // rsi
__int64 v4; // rax
__int16 v5; // r12
unsigned int v6; // ebx
unsigned __int16 v7; // r12
__int64 result; // rax

v0 = get_cartridge_rom_size(*(unsigned __int8 *)(*(_QWORD *)(cartridge + 40) + 328LL));
printf("expected ROM size: %i KiB\n", (unsigned int)(v0 / 1024));
v1 = *(_DWORD *)(cartridge + 60);
if ( v1 == v0 )
{
if ( v1 )
{
v2 = *(unsigned __int8 **)(cartridge + 40);
v3 = (__int64)&v2[v1 - 1 + 1];
LOWORD(v1) = 0;
do
LOWORD(v1) = *v2++ + (_WORD)v1;
while ( v2 != (unsigned __int8 *)v3 );
}
v4 = *(_QWORD *)(cartridge + 40);
v5 = *(unsigned __int8 *)(v4 + 334);
LOBYTE(v4) = *(_BYTE *)(v4 + 335);
v6 = (unsigned __int16)(v1 - (v5 + (unsigned __int8)v4));
v7 = (v5 << 8) | (unsigned __int8)v4;
result = 0LL;
if ( v7 != v6 )
{
puts("WARNING: invalid checksum");
printf("\t%X != %X\n", v6, v7);
result = 0LL;
}
}
else
{
puts("The size of the Cartridge is invalid");
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 func3()
{
int v0; // ebx
int v1; // edx
unsigned __int8 *v2; // rax
__int64 v3; // rsi
__int64 v4; // rax
__int16 v5; // r12
unsigned int v6; // ebx
unsigned __int16 v7; // r12
__int64 result; // rax

v0 = func1(*(unsigned __int8 *)(*(_QWORD *)(cartridge + 40) + 328LL));
printf("expected ROM size: %i KiB\n", (unsigned int)(v0 / 1024));
v1 = *(_DWORD *)(cartridge + 60);
if ( v1 == v0 )
{
if ( v1 )
{
v2 = *(unsigned __int8 **)(cartridge + 40);
v3 = (__int64)&v2[v1 - 1 + 1];
LOWORD(v1) = 0;
do
LOWORD(v1) = *v2++ + (_WORD)v1;
while ( v2 != (unsigned __int8 *)v3 );
}
v4 = *(_QWORD *)(cartridge + 40);
v5 = *(unsigned __int8 *)(v4 + 334);
LOBYTE(v4) = *(_BYTE *)(v4 + 335);
v6 = (unsigned __int16)(v1 - (v5 + (unsigned __int8)v4));
v7 = (v5 << 8) | (unsigned __int8)v4;
result = 0LL;
if ( v7 != v6 )
{
puts("WARNING: invalid checksum");
printf("\t%X != %X\n", v6, v7);
result = 0LL;
}
}
else
{
puts("The size of the Cartridge is invalid");
result = 1LL;
}
return result;
}

original_code:
static int verify_cartridge(void) {
    int expected_cartridge_rom_size =
       get_cartridge_rom_size(cartridge->rom[0x148]);
    printf("expected ROM size: %i KiB\n",
            expected_cartridge_rom_size / 1024);
    if(cartridge->rom_size != expected_cartridge_rom_size) {
        printf("The size of the Cartridge is invalid\n");
        return 1;
    }
    uint32_t sum = 0;
    for(int i = 0; i < cartridge->rom_size; ++i) {
        sum += cartridge->rom[i];
    }
    sum -= ((u16)cartridge->rom[0x14e] + cartridge->rom[0x14f]);
    sum &= 0x0000FFFF;
    u16 checksum = (cartridge->rom[0x014E] << 8) | cartridge->rom[0x014F];
    if(sum != checksum) {
        printf("WARNING: invalid checksum\n");
        printf("\t%X != %X\n", sum, checksum);
    }
    return 0;
}

canonical_original_code:
static int verify_cartridge() {
    int expected_cartridge_rom_size = get_cartridge_rom_size(cartridge->rom[0x148]);
    printf("expected ROM size: %i KiB\n",
            expected_cartridge_rom_size / 1024);
    if(cartridge->rom_size != expected_cartridge_rom_size) {
        printf("The size of the Cartridge is invalid\n");
        return 1;
    }
    unsigned int sum = 0;
    for(int i = 0; i < cartridge->rom_size; ++i) {
        sum += cartridge->rom[i];
    }
    sum -= ((unsigned short)cartridge->rom[0x14e] + cartridge->rom[0x14f]);
    sum &= 0x0000FFFF;
    unsigned short checksum = (cartridge->rom[0x014E] << 8) | cartridge->rom[0x014F];
    if(sum != checksum) {
        printf("WARNING: invalid checksum\n");
        printf("\t%X != %X\n", sum, checksum);
    }
    return 0;
}

variable_types:
sum
unsigned int

variable_types: i int

variable_types:
checksum
unsigned short


decompiled_code:
int print_cartridge_info()
{
__int64 v0; // rcx
__int64 i; // rax
char v3[308]; // [rsp+0h] [rbp-144h]
char v4[16]; // [rsp+134h] [rbp-10h] BYREF

if ( !cartridge )
_assert_fail("cartridge", "cartridge.c", 0xCAu, "print_cartridge_info");
puts("---Cartridge Information---");
v4[15] = 0;
v0 = *(_QWORD *)(cartridge + 40);
for ( i = 308LL; i != 324; ++i )
v3[i] = *(_BYTE *)(v0 + i);
printf("Title: %s\n", v4);
printf("Type: %s\n", (const char *)(cartridge + 4));
printf("RAM: %i KiB\n", *(_DWORD *)(cartridge + 56) >> 10);
printf("ROM: %i KiB\n", *(_DWORD *)(cartridge + 60) >> 10);
return putchar(10);
}

canonical_decompiled_code:
int func4()
{
__int64 v0; // rcx
__int64 i; // rax
char v3[308]; // [rsp+0h] [rbp-144h]
char v4[16]; // [rsp+134h] [rbp-10h] BYREF

if ( !cartridge )
_assert_fail("cartridge", "cartridge.c", 0xCAu, "print_cartridge_info");
puts("---Cartridge Information---");
v4[15] = 0;
v0 = *(_QWORD *)(cartridge + 40);
for ( i = 308LL; i != 324; ++i )
v3[i] = *(_BYTE *)(v0 + i);
printf("Title: %s\n", v4);
printf("Type: %s\n", (const char *)(cartridge + 4));
printf("RAM: %i KiB\n", *(_DWORD *)(cartridge + 56) >> 10);
printf("ROM: %i KiB\n", *(_DWORD *)(cartridge + 60) >> 10);
return putchar(10);
}

original_code:
static void print_cartridge_info(void) {
    ((cartridge) ? (void) (0) : __assert_fail ("cartridge", "cartridge.c", 202, __extension__ __PRETTY_FUNCTION__));
    printf("---Cartridge Information---\n");
    char title[0x10];
    title[0x10 - 1] = '\0';
    for(int i = 0x134; i < 0x144; ++i) {
        title[i - 0x134] = cartridge->rom[i];
    }
    printf("Title: %s\n", title);
    printf("Type: %s\n", cartridge->name);
    printf("RAM: %i KiB\n", cartridge->ram_size / 1024);
    printf("ROM: %i KiB\n", cartridge->rom_size / 1024);
    printf("\n");
}

canonical_original_code:
static void print_cartridge_info() {
    ((cartridge) ? (void) (0) : __assert_fail ("cartridge", "cartridge.c", 202, __extension__ __PRETTY_FUNCTION__));
    printf("---Cartridge Information---\n");
    char title[16];
    title[0x10 - 1] = '\0';
    for(int i = 0x134; i < 0x144; ++i) {
        title[i - 0x134] = cartridge->rom[i];
    }
    printf("Title: %s\n", title);
    printf("Type: %s\n", cartridge->name);
    printf("RAM: %i KiB\n", cartridge->ram_size / 1024);
    printf("ROM: %i KiB\n", cartridge->rom_size / 1024);
    printf("\n");
}

variable_types:
title
char [16]


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

result = cartridge;
if ( !cartridge )
_assert_fail("cartridge != NULL", "cartridge.c", 0x36u, "cartridge_update_mbc");
switch ( *(_DWORD *)(cartridge + 36) )
{
case 0:
return result;
case 1:
*(_QWORD *)(cartridge + 88) = &mbc1_read;
*(_QWORD *)(result + 96) = &mbc1_write;
break;
case 2:
*(_QWORD *)(cartridge + 88) = &mbc2_read;
*(_QWORD *)(result + 96) = &mbc2_write;
break;
case 3:
*(_QWORD *)(cartridge + 88) = &mbc3_read;
*(_QWORD *)(result + 96) = &mbc3_write;
break;
case 4:
*(_QWORD *)(cartridge + 88) = &mbc4_read;
*(_QWORD *)(result + 96) = &mbc4_write;
break;
case 5:
*(_QWORD *)(cartridge + 88) = &mbc5_read;
*(_QWORD *)(result + 96) = &mbc5_write;
break;
default:
fwrite("Unsupported MBC\n", 1uLL, 0x10uLL, stderr);
_assert_fail("false", "cartridge.c", 0x51u, "cartridge_update_mbc");
}
return result;
}

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

result = cartridge;
if ( !cartridge )
_assert_fail("cartridge != NULL", "cartridge.c", 0x36u, "cartridge_update_mbc");
switch ( *(_DWORD *)(cartridge + 36) )
{
case 0:
return result;
case 1:
*(_QWORD *)(cartridge + 88) = &mbc1_read;
*(_QWORD *)(result + 96) = &mbc1_write;
break;
case 2:
*(_QWORD *)(cartridge + 88) = &mbc2_read;
*(_QWORD *)(result + 96) = &mbc2_write;
break;
case 3:
*(_QWORD *)(cartridge + 88) = &mbc3_read;
*(_QWORD *)(result + 96) = &mbc3_write;
break;
case 4:
*(_QWORD *)(cartridge + 88) = &mbc4_read;
*(_QWORD *)(result + 96) = &mbc4_write;
break;
case 5:
*(_QWORD *)(cartridge + 88) = &mbc5_read;
*(_QWORD *)(result + 96) = &mbc5_write;
break;
default:
fwrite("Unsupported MBC\n", 1uLL, 0x10uLL, stderr);
_assert_fail("false", "cartridge.c", 0x51u, "cartridge_update_mbc");
}
return result;
}

original_code:
void cartridge_update_mbc(void) {
    ((cartridge != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge != NULL", "cartridge.c", 54, __extension__ __PRETTY_FUNCTION__));
    switch(cartridge->mbc) {
        case NONE:
            break;
        case MBC1:
            cartridge->read = &mbc1_read;
            cartridge->write = &mbc1_write;
            break;
        case MBC2:
            cartridge->read = &mbc2_read;
            cartridge->write = &mbc2_write;
            break;
        case MBC3:
            cartridge->read = &mbc3_read;
            cartridge->write = &mbc3_write;
            break;
        case MBC4:
            cartridge->read = &mbc4_read;
            cartridge->write = &mbc4_write;
            break;
        case MBC5:
            cartridge->read = &mbc5_read;
            cartridge->write = &mbc5_write;
            break;
        default:
            fprintf(stderr, "Unsupported MBC\n");
            ((0) ? (void) (0) : __assert_fail ("false", "cartridge.c", 81, __extension__ __PRETTY_FUNCTION__));
            break;
    }
}

canonical_original_code:
void cartridge_update_mbc() {
    ((cartridge != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge != NULL", "cartridge.c", 54, __extension__ __PRETTY_FUNCTION__));
    switch(cartridge->mbc) {
        case NONE:
            break;
        case MBC1:
            cartridge->read = &mbc1_read;
            cartridge->write = &mbc1_write;
            break;
        case MBC2:
            cartridge->read = &mbc2_read;
            cartridge->write = &mbc2_write;
            break;
        case MBC3:
            cartridge->read = &mbc3_read;
            cartridge->write = &mbc3_write;
            break;
        case MBC4:
            cartridge->read = &mbc4_read;
            cartridge->write = &mbc4_write;
            break;
        case MBC5:
            cartridge->read = &mbc5_read;
            cartridge->write = &mbc5_write;
            break;
        default:
            fprintf(stderr, "Unsupported MBC\n");
            ((0) ? (void) (0) : __assert_fail ("false", "cartridge.c", 81, __extension__ __PRETTY_FUNCTION__));
            break;
    }
}


decompiled_code:
__int64 __fastcall get_has_battery(__int64 a1)
{
__int64 result; // rax

if ( !a1 )
_assert_fail("cartridge_type != NULL", "cartridge.c", 0x5Au, "get_has_battery");
switch ( *(_DWORD *)(a1 + 40) )
{
case 3:
case 5:
case 7:
case 0xA:
case 0xB:
case 0xC:
case 0xF:
case 0x12:
case 0x15:
case 0x18:
case 0x1C:
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
__int64 result; // rax

if ( !a1 )
_assert_fail("cartridge_type != NULL", "cartridge.c", 0x5Au, "get_has_battery");
switch ( *(_DWORD *)(a1 + 40) )
{
case 3:
case 5:
case 7:
case 0xA:
case 0xB:
case 0xC:
case 0xF:
case 0x12:
case 0x15:
case 0x18:
case 0x1C:
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
_Bool get_has_battery(CartridgeType* cartridge_type) {
    ((cartridge_type != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge_type != NULL", "cartridge.c", 90, __extension__ __PRETTY_FUNCTION__));
    switch(cartridge_type->id) {
        case ID_MBC1_RAM_BATTERY:
        case ID_MBC2_BATTERY:
        case ID_ROM_RAM_BATTERY:
        case ID_MMM01_RAM_BATTERY:
        case ID_MBC3_TIMER_BATTERY:
        case ID_MBC3_TIMER_RAM_BATTERY:
        case ID_MBC3_RAM_BATTERY:
        case ID_MBC4_RAM_BATTERY:
        case ID_MBC5_RAM_BATTERY:
        case ID_MBC5_RUMBLE_RAM_BATTERY:
        case ID_HUC1_RAM_BATTERY:
            return 1;
    }
    return 0;
}

canonical_original_code:
_Bool get_has_battery(struct CartridgeType *cartridge_type) {
    ((cartridge_type != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge_type != NULL", "cartridge.c", 90, __extension__ __PRETTY_FUNCTION__));
    switch(cartridge_type->id) {
        case ID_MBC1_RAM_BATTERY:
        case ID_MBC2_BATTERY:
        case ID_ROM_RAM_BATTERY:
        case ID_MMM01_RAM_BATTERY:
        case ID_MBC3_TIMER_BATTERY:
        case ID_MBC3_TIMER_RAM_BATTERY:
        case ID_MBC3_RAM_BATTERY:
        case ID_MBC4_RAM_BATTERY:
        case ID_MBC5_RAM_BATTERY:
        case ID_MBC5_RUMBLE_RAM_BATTERY:
        case ID_HUC1_RAM_BATTERY:
            return 1;
    }
    return 0;
}

variable_types: struct CartridgeType { int header_value; enum MemoryBankController { NONE=0, MBC1=1, MBC2=2, MBC3=3, MBC4=4, MBC5=5, UNSUPPORTED=6 } mbc; char name[32]; int id; } *

user_defined_types: struct CartridgeType { int header_value; enum MemoryBankController mbc; char name[32]; int id; }


decompiled_code:
char *__fastcall get_cartridge_type(int a1)
{
_DWORD *v1; // rdx
int v2; // eax

v1 = &cartridge_types;
v2 = 0;
while ( *v1 != a1 )
{
++v2;
v1 += 11;
if ( v2 == 29 )
return 0LL;
}
return (char *)&cartridge_types + 44 * v2;
}

canonical_decompiled_code:
char *__fastcall func7(int a1)
{
_DWORD *v1; // rdx
int v2; // eax

v1 = &cartridge_types;
v2 = 0;
while ( *v1 != a1 )
{
++v2;
v1 += 11;
if ( v2 == 29 )
return 0LL;
}
return (char *)&cartridge_types + 44 * v2;
}

original_code:
CartridgeType* get_cartridge_type(int header_value) {
    for(int i = 0; i < (sizeof(cartridge_types) / sizeof(CartridgeType)); ++i) {
        if(cartridge_types[i].header_value == header_value) {
            return &cartridge_types[i];
        }
    }
    return ((void *)0);
}

canonical_original_code:
struct CartridgeType *get_cartridge_type(int header_value) {
    for(int i = 0; i < (sizeof(cartridge_types) / sizeof(CartridgeType)); ++i) {
        if(cartridge_types[i].header_value == header_value) {
            return &cartridge_types[i];
        }
    }
    return ((void *)0);
}

return_type: struct CartridgeType { int header_value; enum MemoryBankController { NONE=0, MBC1=1, MBC2=2, MBC3=3, MBC4=4, MBC5=5, UNSUPPORTED=6 } mbc; char name[32]; int id; } *


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

result = *(_QWORD *)(cartridge + 40) + (*(unsigned __int16 *)(cartridge + 80) << 14);
*(_QWORD *)(cartridge + 64) = result;
return result;
}

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

result = *(_QWORD *)(cartridge + 40) + (*(unsigned __int16 *)(cartridge + 80) << 14);
*(_QWORD *)(cartridge + 64) = result;
return result;
}

original_code:
void cartridge_update_selected_rom(void) {
    cartridge->selected_rom =
        &cartridge->rom[cartridge->selected_rom_bank * 0x4000];
}

canonical_original_code:
void cartridge_update_selected_rom() {
    cartridge->selected_rom =
        &cartridge->rom[cartridge->selected_rom_bank * 0x4000];
}


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

result = *(_QWORD *)(cartridge + 48) + (*(unsigned __int16 *)(cartridge + 82) << 13);
*(_QWORD *)(cartridge + 72) = result;
return result;
}

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

result = *(_QWORD *)(cartridge + 48) + (*(unsigned __int16 *)(cartridge + 82) << 13);
*(_QWORD *)(cartridge + 72) = result;
return result;
}

original_code:
void cartridge_update_selected_ram(void) {
    cartridge->selected_ram =
        &cartridge->ram[cartridge->selected_ram_bank * 0x2000];
}

canonical_original_code:
void cartridge_update_selected_ram() {
    cartridge->selected_ram =
        &cartridge->ram[cartridge->selected_ram_bank * 0x2000];
}


decompiled_code:
__int64 __fastcall initialize_cartridge(const char *a1)
{
__int64 v1; // r12
__int64 v2; // rbx
unsigned int v3; // eax
char *v4; // rax
__int64 v5; // rbx
__int64 v6; // rax
unsigned int v7; // ebx
void *v8; // rax

if ( !a1 )
_assert_fail("cartridge_filepath", "cartridge.c", 0x9Au, "initialize_cartridge");
if ( cartridge )
_assert_fail("cartridge == NULL", "cartridge.c", 0x9Bu, "initialize_cartridge");
cartridge = (__int64)calloc(0x70uLL, 1uLL);
if ( !cartridge )
_assert_fail("cartridge", "cartridge.c", 0x9Eu, "initialize_cartridge");
if ( (unsigned int)read_cartridge(a1) )
return 1;
v1 = cartridge;
v2 = *(_QWORD *)(cartridge + 40);
v3 = get_cartridge_ram_size(*(unsigned __int8 *)(v2 + 329));
*(_DWORD *)(v1 + 56) = v3;
if ( *(_QWORD *)(v1 + 48) )
_assert_fail("cartridge->ram == NULL", "cartridge.c", 0xA8u, "initialize_cartridge");
if ( v3 )
{
v8 = malloc(v3);
*(_QWORD *)(v1 + 48) = v8;
if ( !v8 )
_assert_fail("cartridge->ram != NULL", "cartridge.c", 0xACu, "initialize_cartridge");
}
v4 = get_cartridge_type(*(unsigned __int8 *)(v2 + 327));
v5 = (__int64)v4;
if ( !v4 )
_assert_fail("cartridge_type != NULL", "cartridge.c", 0xB4u, "initialize_cartridge");
*(_DWORD *)v1 = *((_DWORD *)v4 + 10);
v6 = cartridge;
*(__m128i *)(cartridge + 4) = _mm_loadu_si128((const __m128i *)(v5 + 8));
*(__m128i *)(v6 + 20) = _mm_loadu_si128((const __m128i *)(v5 + 24));
*(_DWORD *)(cartridge + 36) = *(_DWORD *)(v5 + 4);
cartridge_update_mbc();
*(_BYTE *)(cartridge + 106) = get_has_battery(v5);
cartridge_update_selected_rom();
cartridge_update_selected_ram();
v7 = verify_cartridge();
if ( v7 )
return 1;
print_cartridge_info();
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func10(const char *a1)
{
__int64 v1; // r12
__int64 v2; // rbx
unsigned int v3; // eax
char *v4; // rax
__int64 v5; // rbx
__int64 v6; // rax
unsigned int v7; // ebx
void *v8; // rax

if ( !a1 )
_assert_fail("cartridge_filepath", "cartridge.c", 0x9Au, "initialize_cartridge");
if ( cartridge )
_assert_fail("cartridge == NULL", "cartridge.c", 0x9Bu, "initialize_cartridge");
cartridge = (__int64)calloc(0x70uLL, 1uLL);
if ( !cartridge )
_assert_fail("cartridge", "cartridge.c", 0x9Eu, "initialize_cartridge");
if ( (unsigned int)func2(a1) )
return 1;
v1 = cartridge;
v2 = *(_QWORD *)(cartridge + 40);
v3 = func0(*(unsigned __int8 *)(v2 + 329));
*(_DWORD *)(v1 + 56) = v3;
if ( *(_QWORD *)(v1 + 48) )
_assert_fail("cartridge->ram == NULL", "cartridge.c", 0xA8u, "initialize_cartridge");
if ( v3 )
{
v8 = malloc(v3);
*(_QWORD *)(v1 + 48) = v8;
if ( !v8 )
_assert_fail("cartridge->ram != NULL", "cartridge.c", 0xACu, "initialize_cartridge");
}
v4 = func7(*(unsigned __int8 *)(v2 + 327));
v5 = (__int64)v4;
if ( !v4 )
_assert_fail("cartridge_type != NULL", "cartridge.c", 0xB4u, "initialize_cartridge");
*(_DWORD *)v1 = *((_DWORD *)v4 + 10);
v6 = cartridge;
*(__m128i *)(cartridge + 4) = _mm_loadu_si128((const __m128i *)(v5 + 8));
*(__m128i *)(v6 + 20) = _mm_loadu_si128((const __m128i *)(v5 + 24));
*(_DWORD *)(cartridge + 36) = *(_DWORD *)(v5 + 4);
func5();
*(_BYTE *)(cartridge + 106) = func6(v5);
func8();
func9();
v7 = func3();
if ( v7 )
return 1;
func4();
return v7;
}

original_code:
int initialize_cartridge(const char* cartridge_filepath) {
    ((cartridge_filepath) ? (void) (0) : __assert_fail ("cartridge_filepath", "cartridge.c", 154, __extension__ __PRETTY_FUNCTION__));
    ((cartridge == ((void *)0)) ? (void) (0) : __assert_fail ("cartridge == NULL", "cartridge.c", 155, __extension__ __PRETTY_FUNCTION__));
    cartridge = (Cartridge*)calloc(sizeof(Cartridge), 1);
    ((cartridge) ? (void) (0) : __assert_fail ("cartridge", "cartridge.c", 158, __extension__ __PRETTY_FUNCTION__));
    if(read_cartridge(cartridge_filepath) != 0) {
        return 1;
    }
    cartridge->ram_size = get_cartridge_ram_size(cartridge->rom[0x0149]);
    ((cartridge->ram_size >= 0) ? (void) (0) : __assert_fail ("cartridge->ram_size >= 0", "cartridge.c", 167, __extension__ __PRETTY_FUNCTION__));
    ((cartridge->ram == ((void *)0)) ? (void) (0) : __assert_fail ("cartridge->ram == NULL", "cartridge.c", 168, __extension__ __PRETTY_FUNCTION__));
    if(cartridge->ram_size > 0) {
        cartridge->ram = (uint8_t*)malloc(cartridge->ram_size);
        ((cartridge->ram != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge->ram != NULL", "cartridge.c", 172, __extension__ __PRETTY_FUNCTION__));
    } else {
        cartridge->ram = ((void *)0);
    }
    CartridgeType* cartridge_type = get_cartridge_type(cartridge->rom[0x0147]);
    ((cartridge_type != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge_type != NULL", "cartridge.c", 180, __extension__ __PRETTY_FUNCTION__));
    cartridge->id = cartridge_type->id;
    memcpy(cartridge->name, cartridge_type->name, 32);
    cartridge->mbc = cartridge_type->mbc;
    cartridge_update_mbc();
    cartridge->has_battery = get_has_battery(cartridge_type);
    cartridge_update_selected_rom();
    cartridge_update_selected_ram();
    if(verify_cartridge() != 0) {
        return 1;
    }
    print_cartridge_info();
    return 0;
}

canonical_original_code:
int initialize_cartridge(char *cartridge_filepath) {
    ((cartridge_filepath) ? (void) (0) : __assert_fail ("cartridge_filepath", "cartridge.c", 154, __extension__ __PRETTY_FUNCTION__));
    ((cartridge == ((void *)0)) ? (void) (0) : __assert_fail ("cartridge == NULL", "cartridge.c", 155, __extension__ __PRETTY_FUNCTION__));
    cartridge = (struct Cartridge *)calloc(sizeof(Cartridge), 1);
    ((cartridge) ? (void) (0) : __assert_fail ("cartridge", "cartridge.c", 158, __extension__ __PRETTY_FUNCTION__));
    if(read_cartridge(cartridge_filepath) != 0) {
        return 1;
    }
    cartridge->ram_size = get_cartridge_ram_size(cartridge->rom[0x0149]);
    ((cartridge->ram_size >= 0) ? (void) (0) : __assert_fail ("cartridge->ram_size >= 0", "cartridge.c", 167, __extension__ __PRETTY_FUNCTION__));
    ((cartridge->ram == ((void *)0)) ? (void) (0) : __assert_fail ("cartridge->ram == NULL", "cartridge.c", 168, __extension__ __PRETTY_FUNCTION__));
    if(cartridge->ram_size > 0) {
        cartridge->ram = (unsigned char *)malloc(cartridge->ram_size);
        ((cartridge->ram != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge->ram != NULL", "cartridge.c", 172, __extension__ __PRETTY_FUNCTION__));
    } else {
        cartridge->ram = ((void *)0);
    }
    struct CartridgeType *cartridge_type = get_cartridge_type(cartridge->rom[0x0147]);
    ((cartridge_type != ((void *)0)) ? (void) (0) : __assert_fail ("cartridge_type != NULL", "cartridge.c", 180, __extension__ __PRETTY_FUNCTION__));
    cartridge->id = cartridge_type->id;
    memcpy(cartridge->name, cartridge_type->name, 32);
    cartridge->mbc = cartridge_type->mbc;
    cartridge_update_mbc();
    cartridge->has_battery = get_has_battery(cartridge_type);
    cartridge_update_selected_rom();
    cartridge_update_selected_ram();
    if(verify_cartridge() != 0) {
        return 1;
    }
    print_cartridge_info();
    return 0;
}

user_defined_types: struct Cartridge { enum CartridgeId id; char name[32]; enum MemoryBankController mbc; unsigned char *rom; unsigned char *ram; unsigned int ram_size; unsigned int rom_size; unsigned char *selected_rom; unsigned char *selected_ram; unsigned short selected_rom_bank; unsigned short selected_ram_bank; unsigned char (*read)(unsigned short); void (*write)(unsigned short, unsigned char); _Bool ram_enabled; unsigned char banking_mode; _Bool has_battery; unsigned char rtc_register; }

user_defined_types: enum MemoryBankController { NONE=0, MBC1=1, MBC2=2, MBC3=3, MBC4=4, MBC5=5, UNSUPPORTED=6 }

user_defined_types: enum CartridgeId { ID_ROM_ONLY=0, ID_MBC1=1, ID_MBC1_RAM=2, ID_MBC1_RAM_BATTERY=3, ID_MBC2=4, ID_MBC2_BATTERY=5, ID_ROM_RAM=6, ID_ROM_RAM_BATTERY=7, ID_MMM01=8, ID_MMM01_RAM=9, ID_MMM01_RAM_BATTERY=10, ID_MBC3_TIMER_BATTERY=11, ID_MBC3_TIMER_RAM_BATTERY=12, ID_MBC3=13, ID_MBC3_RAM=14, ID_MBC3_RAM_BATTERY=15, ID_MBC4=16, ID_MBC4_RAM=17, ID_MBC4_RAM_BATTERY=18, ID_MBC5=19, ID_MBC5_RAM=20, ID_MBC5_RAM_BATTERY=21, ID_MBC5_RUMBLE=22, ID_MBC5_RUMBLE_RAM=23, ID_MBC5_RUMBLE_RAM_BATTERY=24, ID_POCKET_CAMERA=25, ID_BANDAI_TAMA5=26, ID_HUC3=27, ID_HUC1_RAM_BATTERY=28 }


decompiled_code:
__int64 get_save_state_size()
{
return (unsigned int)(*((_DWORD *)cartridge + 14) + 52184);
}

canonical_decompiled_code:
__int64 func0()
{
return (unsigned int)(*((_DWORD *)cartridge + 14) + 52184);
}

original_code:
static int get_save_state_size() {
    return(sizeof(Cpu) + sizeof(Cartridge) + cartridge->ram_size + sizeof(GameboyColor));
}


swap

decompiled_code:
__int64 __fastcall swap(_BYTE *a1, _BYTE *a2)
{
__int64 result; // rax

result = (unsigned __int8)*a1;
*a1 = *a2;
*a2 = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_BYTE *a1, _BYTE *a2)
{
__int64 result; // rax

result = (unsigned __int8)*a1;
*a1 = *a2;
*a2 = result;
return result;
}

original_code:
void swap(uint8_t* a, uint8_t* b) {
    uint8_t c = *a;
    *a = *b;
    *b = c;
}

canonical_original_code:
void swap(unsigned char *a, unsigned char *b) {
    unsigned char c = *a;
    *a = *b;
    *b = c;
}

variable_types:
a
unsigned char *

variable_types:
b
unsigned char *

variable_types:
c
unsigned char


decompiled_code:
void *enable_bios()
{
void *result; // rax
__int64 i; // rbx
__int64 j; // rbx

result = gb;
if ( !gb )
_assert_fail("gb", "gameboy.c", 0x22u, "enable_bios");
if ( !cartridge )
_assert_fail("cartridge", "gameboy.c", 0x24u, "enable_bios");
if ( !*((_QWORD *)cartridge + 5) )
_assert_fail("cartridge->rom", "gameboy.c", 0x25u, "enable_bios");
if ( *((_BYTE *)gb + 52018) )
{
for ( i = 0LL; i != 256; ++i )
swap((_BYTE *)(*((_QWORD *)cartridge + 5) + i), (_BYTE *)gb + i + 49312);
for ( j = 49824LL; j != 51616; ++j )
result = (void *)swap((_BYTE *)(*((_QWORD *)cartridge + 5) + j - 49312), (_BYTE *)gb + j);
}
return result;
}

canonical_decompiled_code:
void *func3()
{
void *result; // rax
__int64 i; // rbx
__int64 j; // rbx

result = gb;
if ( !gb )
_assert_fail("gb", "gameboy.c", 0x22u, "enable_bios");
if ( !cartridge )
_assert_fail("cartridge", "gameboy.c", 0x24u, "enable_bios");
if ( !*((_QWORD *)cartridge + 5) )
_assert_fail("cartridge->rom", "gameboy.c", 0x25u, "enable_bios");
if ( *((_BYTE *)gb + 52018) )
{
for ( i = 0LL; i != 256; ++i )
func2((_BYTE *)(*((_QWORD *)cartridge + 5) + i), (_BYTE *)gb + i + 49312);
for ( j = 49824LL; j != 51616; ++j )
result = (void *)func2((_BYTE *)(*((_QWORD *)cartridge + 5) + j - 49312), (_BYTE *)gb + j);
}
return result;
}

original_code:
static void enable_bios()
{
    ((gb) ? (void) (0) : __assert_fail ("gb", "gameboy.c", 34, __extension__ __PRETTY_FUNCTION__));
    ((gb->bios) ? (void) (0) : __assert_fail ("gb->bios", "gameboy.c", 35, __extension__ __PRETTY_FUNCTION__));
    ((cartridge) ? (void) (0) : __assert_fail ("cartridge", "gameboy.c", 36, __extension__ __PRETTY_FUNCTION__));
    ((cartridge->rom) ? (void) (0) : __assert_fail ("cartridge->rom", "gameboy.c", 37, __extension__ __PRETTY_FUNCTION__));
    if(gb->use_bios) {
        for(int i = 0; i < 0x100; ++i) {
            swap(&cartridge->rom[i], &gb->bios[i]);
        }
        for(int i = 0x200; i < 0x900; ++i) {
            swap(&cartridge->rom[i], &gb->bios[i]);
        }
    }
}


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

result = gb;
if ( !gb )
_assert_fail("gb", "gameboy.c", 0x32u, "gameboy_disable_bios");
if ( *((_BYTE *)gb + 52018) )
result = enable_bios();
return result;
}

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

result = gb;
if ( !gb )
_assert_fail("gb", "gameboy.c", 0x32u, "gameboy_disable_bios");
if ( *((_BYTE *)gb + 52018) )
result = func3();
return result;
}

original_code:
void gameboy_disable_bios() {
    ((gb) ? (void) (0) : __assert_fail ("gb", "gameboy.c", 50, __extension__ __PRETTY_FUNCTION__));
    if(gb->use_bios)
        enable_bios();
}


decompiled_code:
char *gameboy_update_selected_ram()
{
char *result; // rax

result = (char *)gb + 4096 * *((unsigned __int8 *)gb + 51999);
*((_QWORD *)gb + 6453) = result;
return result;
}

canonical_decompiled_code:
char *func5()
{
char *result; // rax

result = (char *)gb + 4096 * *((unsigned __int8 *)gb + 51999);
*((_QWORD *)gb + 6453) = result;
return result;
}

original_code:
void gameboy_update_selected_ram(void)
{
    u32 ram_bank = gb->hw_registers[SVBK];
    gb->selected_ram = &gb->ram[ram_bank * 0x1000];
}

canonical_original_code:
void gameboy_update_selected_ram()
{
    unsigned int ram_bank = gb->hw_registers[SVBK];
    gb->selected_ram = &gb->ram[ram_bank * 0x1000];
}


decompiled_code:
char *gameboy_update_selected_vram()
{
char *result; // rax

result = (char *)gb + 0x2000 * *((unsigned __int8 *)gb + 51966) + 0x8000;
*((_QWORD *)gb + 6452) = result;
return result;
}

canonical_decompiled_code:
char *func6()
{
char *result; // rax

result = (char *)gb + 0x2000 * *((unsigned __int8 *)gb + 51966) + 0x8000;
*((_QWORD *)gb + 6452) = result;
return result;
}

original_code:
void gameboy_update_selected_vram(void)
{
    u32 vram_bank = gb->hw_registers[VBK];
    gb->selected_vram = &gb->vram[vram_bank * 0x2000];
}

canonical_original_code:
void gameboy_update_selected_vram()
{
    unsigned int vram_bank = gb->hw_registers[VBK];
    gb->selected_vram = &gb->vram[vram_bank * 0x2000];
}


decompiled_code:
__int64 __fastcall initialize_gameboy(unsigned __int8 a1, char *a2)
{
char *v2; // rax
__int64 result; // rax
int v4; // edx

fprintf(stderr, "initialize_gameboy(use_bios=%i, bios_filepath=%s)\n", a1, a2);
if ( gameboy_initialized )
_assert_fail("gameboy_initialized == false", "gameboy.c", 0x5Eu, "initialize_gameboy");
v2 = (char *)calloc(0xCB38uLL, 1uLL);
gb = v2;
if ( !v2 )
_assert_fail("gb", "gameboy.c", 0x62u, "initialize_gameboy");
if ( !a1 )
{
*(_QWORD *)(v2 + 51887) = 0xCF0000000FLL;
*(_QWORD *)(v2 + 51895) = 0x100000000000000LL;
*(_QWORD *)(v2 + 51903) = 0x87C1F38000LL;
*(_QWORD *)(v2 + 51911) = 0LL;
*(_QWORD *)(v2 + 51919) = 0x80F37700000000LL;
*(_QWORD *)(v2 + 51927) = 0LL;
*(_QWORD *)(v2 + 51935) = 0xFF00FF00FF00FF00LL;
*(_QWORD *)(v2 + 51943) = 0xFF00FF00FF00FF00LL;
*(_QWORD *)(v2 + 51951) = 0xFC00009100000191LL;
*(_QWORD *)(v2 + 51959) = 0xC000000000LL;
*(_QWORD *)(v2 + 51967) = 0xFFFFFFFFFF00LL;
*(_QWORD *)(v2 + 51975) = 0LL;
*(_QWORD *)(v2 + 51983) = 0LL;
*(_QWORD *)(v2 + 51991) = 8454272LL;
*(_QWORD *)(v2 + 51999) = 1LL;
*(_QWORD *)(v2 + 52007) = 0LL;
v2[51967] = 17;
LABEL_5:
*((_BYTE *)gb + 52018) = a1;
gameboy_update_selected_ram();
gameboy_update_selected_vram();
gameboy_initialized = 1;
return 0LL;
}
v4 = read_bios(a2);
result = 1LL;
if ( !v4 )
{
*((_BYTE *)gb + 51967) = 0;
enable_bios();
goto LABEL_5;
}
return result;
}

original_code:
int initialize_gameboy(_Bool use_bios, const char* bios_filepath)
{
    fprintf(stderr, "initialize_gameboy(use_bios=%i, bios_filepath=%s)\n",use_bios, bios_filepath);
    ((gameboy_initialized == 0) ? (void) (0) : __assert_fail ("gameboy_initialized == false", "gameboy.c", 94, __extension__ __PRETTY_FUNCTION__));
    gb = (GameboyColor*)calloc(sizeof(GameboyColor), 1);
    ((gb) ? (void) (0) : __assert_fail ("gb", "gameboy.c", 98, __extension__ __PRETTY_FUNCTION__));
    if(gb == ((void *)0)) {
        return 1;
    }
    if(use_bios == 0) {
        memcpy(gb->hw_registers, hw_registers, 0x80);
    }
    if(use_bios) {
        if(read_bios(bios_filepath) != 0) {
            return 1;
        }
        gb->hw_registers[BLCK] = 0x00;
        enable_bios();
    } else {
        gb->hw_registers[BLCK] = 0x11;
    }
    gb->use_bios = use_bios;
    gameboy_update_selected_ram();
    gameboy_update_selected_vram();
    gameboy_initialized = 1;
    return 0;
}

canonical_original_code:
int initialize_gameboy(_Bool use_bios, char *bios_filepath)
{
    fprintf(stderr, "initialize_gameboy(use_bios=%i, bios_filepath=%s)\n",use_bios, bios_filepath);
    ((gameboy_initialized == 0) ? (void) (0) : __assert_fail ("gameboy_initialized == false", "gameboy.c", 94, __extension__ __PRETTY_FUNCTION__));
    gb = (struct GameboyColor *)calloc(sizeof(GameboyColor), 1);
    ((gb) ? (void) (0) : __assert_fail ("gb", "gameboy.c", 98, __extension__ __PRETTY_FUNCTION__));
    if(gb == ((void *)0)) {
        return 1;
    }
    if(use_bios == 0) {
        memcpy(gb->hw_registers, hw_registers, 0x80);
    }
    if(use_bios) {
        if(read_bios(bios_filepath) != 0) {
            return 1;
        }
        gb->hw_registers[BLCK] = 0x00;
        enable_bios();
    } else {
        gb->hw_registers[BLCK] = 0x11;
    }
    gb->use_bios = use_bios;
    gameboy_update_selected_ram();
    gameboy_update_selected_vram();
    gameboy_initialized = 1;
    return 0;
}

user_defined_types: struct GameboyColor { unsigned char ram[32768]; unsigned char vram[16384]; unsigned char oam[160]; unsigned char bios[2304]; unsigned char *selected_vram; unsigned char *selected_ram; unsigned char bg_pallete[64]; unsigned char ob_pallete[64]; unsigned char hram[127]; unsigned char hw_registers[128]; unsigned char ie_register; unsigned char ime_flag; _Bool cgb_mode; _Bool use_bios; }


decompiled_code:
void termination_handler()
{
do_exit = -1;
}

canonical_decompiled_code:
void func7()
{
do_exit = -1;
}

original_code:
void termination_handler(int signum)
{
 do_exit = -1;
}

variable_types: signum int


usage

decompiled_code:
void __fastcall __noreturn usage(const char *a1)
{
fprintf(stderr, "Usage: %s [-i radio][-o playback][freq(MHz)]\n", a1);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func8(const char *a1)
{
fprintf(stderr, "Usage: %s [-i radio][-o playback][freq(MHz)]\n", a1);
exit(1);
}

original_code:
void usage(char *progname)
{
 fprintf(stderr, "Usage: %s [-i radio][-o playback][freq(MHz)]\n",
  progname);
 exit(1);
}

variable_types:
progname
char *


decompiled_code:
__int64 setup_lcd_8bit()
{
__int64 v0; // rax
__int64 result; // rax

v0 = gpio;
*(_DWORD *)(gpio + 40) = 1920;
*(_DWORD *)(v0 + 28) = 384;
*(_DWORD *)(v0 + 28) = (_DWORD)&dword_400000;
usleep(0x14u);
result = gpio;
*(_DWORD *)(gpio + 40) = (_DWORD)&dword_400000;
return result;
}


decompiled_code:
int init_switch()
{
*(_DWORD *)(gpio + 4) |= 0x200000u;
*(_DWORD *)(gpio + 4) &= 0xFF1FFFFF;
return usleep(1u);
}

canonical_decompiled_code:
int func11()
{
*(_DWORD *)(gpio + 4) |= 0x200000u;
*(_DWORD *)(gpio + 4) &= 0xFF1FFFFF;
return usleep(1u);
}


decompiled_code:
__int64 get_switch()
{
return *(_DWORD *)(gpio + 52) & 0x10;
}

original_code:
int get_switch(void)
{
 return *(gpio+13) & (0x01 << (4));
}

canonical_original_code:
int get_switch()
{
 return *(gpio+13) & (0x01 << (4));
}


decompiled_code:
int init_led()
{
*(_DWORD *)(gpio + 4) &= 0xFF1FFFFF;
*(_DWORD *)(gpio + 4) |= 0x200000u;
return usleep(1u);
}

canonical_decompiled_code:
int func13()
{
*(_DWORD *)(gpio + 4) &= 0xFF1FFFFF;
*(_DWORD *)(gpio + 4) |= 0x200000u;
return usleep(1u);
}


decompiled_code:
__int64 __fastcall led_ctl(int a1)
{
__int64 result; // rax

result = gpio;
if ( a1 <= 0 )
*(_DWORD *)(gpio + 40) = 0x20000;
else
*(_DWORD *)(gpio + 28) = 0x20000;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(int a1)
{
__int64 result; // rax

result = gpio;
if ( a1 <= 0 )
*(_DWORD *)(gpio + 40) = 0x20000;
else
*(_DWORD *)(gpio + 28) = 0x20000;
return result;
}

variable_types: on int


decompiled_code:
int init_lcd()
{
_DWORD *v0; // rax

*(_DWORD *)(gpio + 4) &= 0xFFFFFFC7;
*(_DWORD *)(gpio + 4) |= 8u;
v0 = (_DWORD *)gpio;
*(_DWORD *)(gpio + 8) &= 0xFFFFFE3F;
v0[2] |= 0x40u;
*v0 &= 0xFF1FFFFF;
*(_DWORD *)gpio |= 0x200000u;
*(_DWORD *)gpio &= 0xF8FFFFFF;
*(_DWORD *)gpio |= 0x1000000u;
*(_DWORD *)gpio &= 0xC7FFFFFF;
*(_DWORD *)gpio |= 0x8000000u;
*(_DWORD *)(gpio + 4) &= 0xFFFFFFF8;
*(_DWORD *)(gpio + 4) |= 1u;
usleep(1u);
setup_lcd_4bit();
set_ctl(40);
usleep(0x32u);
set_ctl(8);
usleep(0x32u);
set_ctl(1);
usleep(0xBB8u);
set_ctl(6);
usleep(0x32u);
set_ctl(20);
usleep(0x32u);
set_ctl(12);
return usleep(0x32u);
}

canonical_decompiled_code:
int func15()
{
_DWORD *v0; // rax

*(_DWORD *)(gpio + 4) &= 0xFFFFFFC7;
*(_DWORD *)(gpio + 4) |= 8u;
v0 = (_DWORD *)gpio;
*(_DWORD *)(gpio + 8) &= 0xFFFFFE3F;
v0[2] |= 0x40u;
*v0 &= 0xFF1FFFFF;
*(_DWORD *)gpio |= 0x200000u;
*(_DWORD *)gpio &= 0xF8FFFFFF;
*(_DWORD *)gpio |= 0x1000000u;
*(_DWORD *)gpio &= 0xC7FFFFFF;
*(_DWORD *)gpio |= 0x8000000u;
*(_DWORD *)(gpio + 4) &= 0xFFFFFFF8;
*(_DWORD *)(gpio + 4) |= 1u;
usleep(1u);
func8();
func9(40);
usleep(0x32u);
func9(8);
usleep(0x32u);
func9(1);
usleep(0xBB8u);
func9(6);
usleep(0x32u);
func9(20);
usleep(0x32u);
func9(12);
return usleep(0x32u);
}


decompiled_code:
int __fastcall write_str(char a1, _BYTE *a2)
{
int v3; // ebx
int result; // eax

if ( a1 == 1 )
set_ctl(128);
else
set_ctl(192);
usleep(0x32u);
v3 = 16;
do
{
if ( *a2 )
result = write_char((char)*a2++);
else
result = write_char(32);
--v3;
}
while ( v3 );
return result;
}

canonical_decompiled_code:
int __fastcall func16(char a1, _BYTE *a2)
{
int v3; // ebx
int result; // eax

if ( a1 == 1 )
func9(128);
else
func9(192);
usleep(0x32u);
v3 = 16;
do
{
if ( *a2 )
result = func10((char)*a2++);
else
result = func10(32);
--v3;
}
while ( v3 );
return result;
}

original_code:
void write_str(char line, char *str)
{
 int i;
 if (line==1) {
  set_ctl((0x80));
 } else {
  set_ctl((0xC0));
 }
 usleep(50);
 for (i=0; i<16; i++) {
  if (*str != '\0') {
   write_char(*str);
   str++;
  } else {
   write_char(' ');
  }
 }
}

variable_types: line char

variable_types:
str
char *


decompiled_code:
int __fastcall write_str_auto(_BYTE *a1)
{
int v2; // ebp
int v3; // ebp
int result; // eax

set_ctl(128);
usleep(0x32u);
v2 = 16;
do
{
if ( *a1 )
write_char((char)*a1++);
else
write_char(32);
--v2;
}
while ( v2 );
set_ctl(192);
usleep(0x32u);
v3 = 16;
do
{
if ( *a1 )
result = write_char((char)*a1++);
else
result = write_char(32);
--v3;
}
while ( v3 );
return result;
}

canonical_decompiled_code:
int __fastcall func17(_BYTE *a1)
{
int v2; // ebp
int v3; // ebp
int result; // eax

func9(128);
usleep(0x32u);
v2 = 16;
do
{
if ( *a1 )
func10((char)*a1++);
else
func10(32);
--v2;
}
while ( v2 );
func9(192);
usleep(0x32u);
v3 = 16;
do
{
if ( *a1 )
result = func10((char)*a1++);
else
result = func10(32);
--v3;
}
while ( v3 );
return result;
}

original_code:
void write_str_auto(char *str)
{
 int i;
 set_ctl((0x80));
 usleep(50);
 for (i=0; i<16; i++) {
  if (*str != '\0') {
   write_char(*str);
   str++;
  } else {
   write_char(' ');
  }
 }
 set_ctl((0xC0));
 usleep(50);
 for (; i<32; i++) {
  if (*str != '\0') {
   write_char(*str);
   str++;
  } else {
   write_char(' ');
  }
 }
}


decompiled_code:
__int64 setup_io()
{
char *v0; // rax
int v1; // eax
void *v2; // rax
__int64 result; // rax

v0 = malloc(0x1FFFuLL);
gpio_mem = v0;
if ( !v0 )
return 0xFFFFFFFFLL;
if ( ((unsigned __int16)v0 & 0xFFF) != 0 )
gpio_mem = (char *)v0 - ((unsigned __int16)v0 & 0xFFF) + 4096;
v1 = open("/dev/mem", 1052674);
mem_fd = v1;
if ( v1 < 0 )
{
printf("mem_fd %d", (unsigned int)v1);
result = 4294967294LL;
}
else
{
v2 = mmap(gpio_mem, 0x1000uLL, 3, 17, v1, 538968064LL);
gpio_map = (__int64)v2;
if ( (__int64)v2 < 0 )
{
result = 4294967293LL;
}
else
{
gpio = (__int64)v2;
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 func18()
{
char *v0; // rax
int v1; // eax
void *v2; // rax
__int64 result; // rax

v0 = malloc(0x1FFFuLL);
gpio_mem = v0;
if ( !v0 )
return 0xFFFFFFFFLL;
if ( ((unsigned __int16)v0 & 0xFFF) != 0 )
gpio_mem = (char *)v0 - ((unsigned __int16)v0 & 0xFFF) + 4096;
v1 = open("/dev/mem", 1052674);
mem_fd = v1;
if ( v1 < 0 )
{
printf("mem_fd %d", (unsigned int)v1);
result = 4294967294LL;
}
else
{
v2 = mmap(gpio_mem, 0x1000uLL, 3, 17, v1, 538968064LL);
gpio_map = (__int64)v2;
if ( (__int64)v2 < 0 )
{
result = 4294967293LL;
}
else
{
gpio = (__int64)v2;
result = 0LL;
}
}
return result;
}

original_code:
int setup_io(void)
{
 gpio_mem = malloc((4*1024) + ((4*1024) -1));
 if (gpio_mem == ((void *)0)) {
  return -1;
 }
 if ((unsigned long)gpio_mem % (4*1024)) {
  gpio_mem += (4*1024) - ((unsigned long)gpio_mem % (4*1024));
 }
 mem_fd = open("/dev/mem", 02|04010000);
 if ((long)mem_fd < 0) {
  printf("mem_fd %d", mem_fd);
  return -2;
 }
 gpio_map = (char *)mmap((caddr_t)gpio_mem,
        (4*1024),
        0x1|0x2,
        0x01|0x10,
        mem_fd, (0x20000000 + 0x200000));
 if ((long)gpio_map < 0) {
  return -3;
 }
 gpio = (volatile unsigned*)gpio_map;
 return 0;
}

canonical_original_code:
int setup_io()
{
 gpio_mem = malloc((4*1024) + ((4*1024) -1));
 if (gpio_mem == ((void *)0)) {
  return -1;
 }
 if ((unsigned long)gpio_mem % (4*1024)) {
  gpio_mem += (4*1024) - ((unsigned long)gpio_mem % (4*1024));
 }
 mem_fd = open("/dev/mem", 02|04010000);
 if ((long)mem_fd < 0) {
  printf("mem_fd %d", mem_fd);
  return -2;
 }
 gpio_map = (char *)mmap((char *)gpio_mem,
        (4*1024),
        0x1|0x2,
        0x01|0x10,
        mem_fd, (0x20000000 + 0x200000));
 if ((long)gpio_map < 0) {
  return -3;
 }
 gpio = (unsigned int *)gpio_map;
 return 0;
}


repo: typpo/lok

decompiled_code:
int usage()
{
return printf("lok your_sqlite.db");
}

canonical_decompiled_code:
int func0()
{
return printf("lok your_sqlite.db");
}

original_code:
void usage()
{
  printf("lok your_sqlite.db");
}


decompiled_code:
__int64 __fastcall init_db(__int64 a1)
{
int v1; // edx
__int64 result; // rax

v1 = db_start(a1, "testkey");
result = 1LL;
if ( v1 >= 0 )
{
db_create_table();
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
int v1; // edx
__int64 result; // rax

v1 = db_start(a1, "testkey");
result = 1LL;
if ( v1 >= 0 )
{
db_create_table();
result = 0LL;
}
return result;
}

original_code:
int init_db(char *dbfile)
{
  if (db_start(dbfile, "testkey") < 0) {
    return 1;
  }
  db_create_table();
  return 0;
}

variable_types:
dbfile
char *


decompiled_code:
int init_curses()
{
initscr();
start_color();
cbreak();
noecho();
nonl();
return init_pair(1, 1, 0);
}

canonical_decompiled_code:
int func2()
{
initscr();
start_color();
cbreak();
noecho();
nonl();
return init_pair(1, 1, 0);
}

original_code:
void init_curses()
{
  initscr();
  start_color();
  cbreak();
  noecho();
  nonl();
  init_pair(1, 1, 0);
}


shutdown

decompiled_code:
__int64 shutdown()
{
db_free_notes(notes, (unsigned int)num_notes);
return db_shutdown();
}

canonical_decompiled_code:
__int64 func3()
{
db_free_notes(notes, (unsigned int)num_notes);
return db_shutdown();
}

original_code:
void shutdown()
{
  db_free_notes(notes, num_notes);
  db_shutdown();
}


decompiled_code:
char *input_key()
{
int v0; // ebp
char *v1; // rbx
char *v2; // rax
char v4; // al
char v5[56]; // [rsp+0h] [rbp-38h] BYREF

v0 = 0;
v1 = v5;
do
{
while ( 1 )
{
v4 = wgetch(stdscr);
if ( v4 != 7 )
break;
if ( v1 <= v5 )
goto LABEL_7;
*(v1 - 1) = 0;
--v0;
--v1;
}
if ( (unsigned __int8)(v4 - 32) <= 0x5Eu )
{
*v1 = v4;
++v0;
++v1;
}
if ( v4 == 10 )
goto LABEL_3;
LABEL_7:
;
}
while ( v0 <= 29 );
puts("\nReached key maximum");
LABEL_3:
*v1 = 0;
v2 = (char *)malloc(0x1FuLL);
return strncpy(v2, v5, 0x1EuLL);
}

canonical_decompiled_code:
char *func4()
{
int v0; // ebp
char *v1; // rbx
char *v2; // rax
char v4; // al
char v5[56]; // [rsp+0h] [rbp-38h] BYREF

v0 = 0;
v1 = v5;
do
{
while ( 1 )
{
v4 = wgetch(stdscr);
if ( v4 != 7 )
break;
if ( v1 <= v5 )
goto LABEL_7;
*(v1 - 1) = 0;
--v0;
--v1;
}
if ( (unsigned __int8)(v4 - 32) <= 0x5Eu )
{
*v1 = v4;
++v0;
++v1;
}
if ( v4 == 10 )
goto LABEL_3;
LABEL_7:
;
}
while ( v0 <= 29 );
puts("\nReached key maximum");
LABEL_3:
*v1 = 0;
v2 = (char *)malloc(0x1FuLL);
return strncpy(v2, v5, 0x1EuLL);
}

original_code:
char *input_key()
{
  char key;
  char plaintext[30 +1];
  char *ptr = plaintext;
  int len = 0;
  do {
    if (len >= 30) {
      printf("\nReached key maximum\n");
      break;
    }
    key = wgetch(stdscr);
    switch (key) {
      case (char) 0407:
        if (ptr > plaintext) {
          *(--ptr) = 0;
          len--;
        }
        break;
      default:
        if (key > 31 && key < 127) {
          *(ptr++) = key;
          len++;
        }
    }
  } while (key != '\n');
  *ptr = 0;
  char *ret = malloc(sizeof(char)*(30 +1));
  strncpy(ret, plaintext, 30);
  return ret;
}

canonical_original_code:
char *input_key()
{
  char key;
  char plaintext[-1];
  char *ptr = plaintext;
  int len = 0;
  do {
    if (len >= 30) {
      printf("\nReached key maximum\n");
      break;
    }
    key = wgetch(stdscr);
    switch (key) {
      case (char) 0407:
        if (ptr > plaintext) {
          *(--ptr) = 0;
          len--;
        }
        break;
      default:
        if (key > 31 && key < 127) {
          *(ptr++) = key;
          len++;
        }
    }
  } while (key != '\n');
  *ptr = 0;
  char *ret = malloc(sizeof(char)*(30 +1));
  strncpy(ret, plaintext, 30);
  return ret;
}

variable_types: key char

variable_types:
plaintext
char [-1]

variable_types:
ptr
char *

variable_types: len int

variable_types:
ret
char *

return_type: char *


decompiled_code:
__int64 load_notes()
{
unsigned int v0; // ebx

if ( (unsigned int)db_fetch_notes(0LL, &notes, &num_notes) )
{
puts("Couldn't get notes from db.");
v0 = 1;
}
else
{
v0 = 0;
create_menu();
}
return v0;
}

canonical_decompiled_code:
__int64 func7()
{
unsigned int v0; // ebx

if ( (unsigned int)db_fetch_notes(0LL, &notes, &num_notes) )
{
puts("Couldn't get notes from db.");
v0 = 1;
}
else
{
v0 = 0;
func5();
}
return v0;
}

original_code:
int load_notes()
{
  if (db_fetch_notes(0, &notes, &num_notes)) {
    printf("Couldn't get notes from db.\n");
    return 1;
  }
  create_menu();
  return 0;
}


decompiled_code:
__int64 reload_notes()
{
db_free_notes(notes, (unsigned int)num_notes);
clear_menu();
return load_notes();
}

canonical_decompiled_code:
__int64 func8()
{
db_free_notes(notes, (unsigned int)num_notes);
func6();
return func7();
}

original_code:
int reload_notes()
{
  db_free_notes(notes, num_notes);
  clear_menu();
  return load_notes();
}


titleFromInput

decompiled_code:
char *__fastcall titleFromInput(char *src, char *dest)
{
int v2; // eax
__int64 v3; // rbx
char *result; // rax

v2 = strcspn(src, "\n");
if ( v2 > 10 )
v2 = 10;
v3 = v2;
result = strncpy(dest, src, v2);
dest[v3] = 0;
return result;
}

canonical_decompiled_code:
char *__fastcall func9(char *src, char *dest)
{
int v2; // eax
__int64 v3; // rbx
char *result; // rax

v2 = strcspn(src, "\n");
if ( v2 > 10 )
v2 = 10;
v3 = v2;
result = strncpy(dest, src, v2);
dest[v3] = 0;
return result;
}

original_code:
void titleFromInput(char *input, char *title)
{
  int newline = strcspn(input, "\n");
  int term = newline < 10 ? newline : 10;
  strncpy(title, input, term);
  title[term] = 0;
}

variable_types:
input
char *

variable_types:
title
char *

variable_types: newline int

variable_types: term int


decompiled_code:
int do_add()
{
int result; // eax
char dest[11]; // [rsp+Dh] [rbp-1Bh] BYREF
void *ptr; // [rsp+18h] [rbp-10h] BYREF

def_prog_mode();
endwin();
if ( (int)editor_do("tmp", &unk_7E0, &ptr) < 0 )
{
wrefresh(stdscr);
result = reset_prog_mode();
}
else
{
titleFromInput((char *)ptr, dest);
db_insert_note(dest, ptr);
free(ptr);
reload_notes();
wrefresh(stdscr);
result = reset_prog_mode();
}
return result;
}

canonical_decompiled_code:
int func10()
{
int result; // eax
char dest[11]; // [rsp+Dh] [rbp-1Bh] BYREF
void *ptr; // [rsp+18h] [rbp-10h] BYREF

def_prog_mode();
endwin();
if ( (int)editor_do("tmp", &unk_7E0, &ptr) < 0 )
{
wrefresh(stdscr);
result = reset_prog_mode();
}
else
{
func9((char *)ptr, dest);
db_insert_note(dest, ptr);
free(ptr);
func8();
wrefresh(stdscr);
result = reset_prog_mode();
}
return result;
}

original_code:
void do_add()
{
  def_prog_mode();
  endwin();
  char *input;
  if (editor_do("tmp", "", &input) < 0) {
    if (!input) {
      free(input);
    }
    wrefresh(stdscr);
    reset_prog_mode();
    return;
  }
  char title[10 +1];
  titleFromInput(input, title);
  db_insert_note(title, input);
  free(input);
  reload_notes();
  wrefresh(stdscr);
  reset_prog_mode();
}

canonical_original_code:
void do_add()
{
  def_prog_mode();
  endwin();
  char *input;
  if (editor_do("tmp", "", &input) < 0) {
    if (!input) {
      free(input);
    }
    wrefresh(stdscr);
    reset_prog_mode();
    return;
  }
  char title[-1];
  titleFromInput(input, title);
  db_insert_note(title, input);
  free(input);
  reload_notes();
  wrefresh(stdscr);
  reset_prog_mode();
}

variable_types:
title
char [-1]


decompiled_code:
int __fastcall do_edit(unsigned int a1)
{
int v1; // eax
char dest[11]; // [rsp+Dh] [rbp-1Bh] BYREF
void *ptr; // [rsp+18h] [rbp-10h] BYREF

def_prog_mode();
endwin();
printf("Editing %d\n", a1);
v1 = editor_do("tmp", *(_QWORD *)(notes + 40LL * (int)a1 + 16), &ptr);
if ( v1 >= 0 )
{
if ( v1 )
{
titleFromInput((char *)ptr, dest);
db_edit_note(*(_QWORD *)(notes + 40LL * (int)a1), dest, ptr);
reload_notes();
}
free(ptr);
}
wrefresh(stdscr);
return reset_prog_mode();
}

canonical_decompiled_code:
int __fastcall func11(unsigned int a1)
{
int v1; // eax
char dest[11]; // [rsp+Dh] [rbp-1Bh] BYREF
void *ptr; // [rsp+18h] [rbp-10h] BYREF

def_prog_mode();
endwin();
printf("Editing %d\n", a1);
v1 = editor_do("tmp", *(_QWORD *)(notes + 40LL * (int)a1 + 16), &ptr);
if ( v1 >= 0 )
{
if ( v1 )
{
func9((char *)ptr, dest);
db_edit_note(*(_QWORD *)(notes + 40LL * (int)a1), dest, ptr);
func8();
}
free(ptr);
}
wrefresh(stdscr);
return reset_prog_mode();
}

original_code:
void do_edit(int index)
{
  def_prog_mode();
  endwin();
  char *input;
  printf("Editing %d\n", index);
  int edit_result = editor_do("tmp", notes[index].text, &input);
  if (edit_result < 0) {
    goto restore;
  } else if (edit_result != 0) {
    char title[10 +1];
    titleFromInput(input, title);
    db_edit_note(notes[index].id, title, input);
    reload_notes();
  }
  free(input);
restore:
  wrefresh(stdscr);
  reset_prog_mode();
}

canonical_original_code:
void do_edit(int index)
{
  def_prog_mode();
  endwin();
  char *input;
  printf("Editing %d\n", index);
  int edit_result = editor_do("tmp", notes[index].text, &input);
  if (edit_result < 0) {
    goto restore;
  } else if (edit_result != 0) {
    char title[-1];
    titleFromInput(input, title);
    db_edit_note(notes[index].id, title, input);
    reload_notes();
  }
  free(input);
restore:
  wrefresh(stdscr);
  reset_prog_mode();
}

variable_types: index int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx

if ( (unsigned int)init_db((__int64)"test.db") )
{
puts("db connection failed.");
v3 = 1;
}
else
{
init_curses();
v3 = start_main_window(notes, (unsigned int)num_notes) != 0;
endwin();
shutdown();
}
return v3;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx

if ( (unsigned int)func1((__int64)"test.db") )
{
puts("db connection failed.");
v3 = 1;
}
else
{
func2();
v3 = func14(notes, (unsigned int)num_notes) != 0;
endwin();
func3();
}
return v3;
}

original_code:
int main(int argc, char **argv)
{
  if (init_db("test.db")) {
    printf("db connection failed.\n");
    return 1;
  }
  init_curses();
  int retval = 0;
  if (start_main_window(notes, num_notes))
    retval = 1;
  endwin();
  shutdown();
  return retval;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: retval int


decompiled_code:
__int64 __fastcall db_start(__int64 a1)
{
__int64 result; // rax
const char *v2; // rax

result = sqlite3_open(a1, &handle);
if ( (_DWORD)result )
{
v2 = (const char *)sqlite3_errmsg(handle);
fprintf(stderr, "Couldn't load database: %s\n", v2);
sqlite3_close(handle);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 result; // rax
const char *v2; // rax

result = sqlite3_open(a1, &handle);
if ( (_DWORD)result )
{
v2 = (const char *)sqlite3_errmsg(handle);
fprintf(stderr, "Couldn't load database: %s\n", v2);
sqlite3_close(handle);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int db_start(char *path, char *key)
{
 if (sqlite3_open(path, &handle)) {
  fprintf(stderr, "Couldn't load database: %s\n",
   sqlite3_errmsg(handle));
  sqlite3_close(handle);
  return -1;
 }
 return 0;
}

variable_types:
path
char *

variable_types:
key
char *


decompiled_code:
int db_shutdown()
{
int result; // eax
const char *v1; // rax

result = sqlite3_close(handle);
if ( result )
{
v1 = (const char *)sqlite3_errmsg(handle);
result = fprintf(stderr, "Couldn't close database: %s\n", v1);
}
return result;
}

canonical_decompiled_code:
int func1()
{
int result; // eax
const char *v1; // rax

result = sqlite3_close(handle);
if ( result )
{
v1 = (const char *)sqlite3_errmsg(handle);
result = fprintf(stderr, "Couldn't close database: %s\n", v1);
}
return result;
}

original_code:
void db_shutdown()
{
 if (sqlite3_close(handle)) {
  fprintf(stderr, "Couldn't close database: %s\n",
   sqlite3_errmsg(handle));
 }
}


decompiled_code:
__int64 db_create_table()
{
return sqlite3_exec(
handle,
"CREATE TABLE IF NOT EXISTS notes(id INTEGER PRIMARY KEY,title TEXT NOT NULL,text TEXT NOT NULL, edited DATE N"
"OT NULL, added DATE NOT NULL)",
0LL,
0LL,
0LL);
}

canonical_decompiled_code:
__int64 func2()
{
return sqlite3_exec(
handle,
"CREATE TABLE IF NOT EXISTS notes(id INTEGER PRIMARY KEY,title TEXT NOT NULL,text TEXT NOT NULL, edited DATE N"
"OT NULL, added DATE NOT NULL)",
0LL,
0LL,
0LL);
}

original_code:
int db_create_table()
{
 char *query =
     "CREATE TABLE IF NOT EXISTS notes(id INTEGER PRIMARY KEY,title TEXT NOT NULL,text TEXT NOT NULL, edited DATE NOT NULL, added DATE NOT NULL)";
 return sqlite3_exec(handle, query, 0, 0, 0);
}

variable_types:
query
char *


decompiled_code:
void __fastcall db_free_notes(void *ptr, int a2)
{
void **v2; // rbx

if ( a2 > 0 )
{
v2 = (void **)ptr;
do
{
free(*v2);
free(v2[1]);
free(v2[3]);
free(v2[4]);
free(v2[2]);
v2 += 5;
}
while ( v2 != (void **)((char *)ptr + 40 * (unsigned int)(a2 - 1) + 40) );
}
free(ptr);
}

canonical_decompiled_code:
void __fastcall func6(void *ptr, int a2)
{
void **v2; // rbx

if ( a2 > 0 )
{
v2 = (void **)ptr;
do
{
free(*v2);
free(v2[1]);
free(v2[3]);
free(v2[4]);
free(v2[2]);
v2 += 5;
}
while ( v2 != (void **)((char *)ptr + 40 * (unsigned int)(a2 - 1) + 40) );
}
free(ptr);
}

original_code:
void db_free_notes(lok_item_t * buf, int num_items)
{
 for (int i = 0; i < num_items; i++) {
  free(buf[i].id);
  free(buf[i].title);
  free(buf[i].edited);
  free(buf[i].added);
  free(buf[i].text);
 }
 free(buf);
}

canonical_original_code:
void db_free_notes(struct lok_item_t *buf, int num_items)
{
 for (int i = 0; i < num_items; i++) {
  free(buf[i].id);
  free(buf[i].title);
  free(buf[i].edited);
  free(buf[i].added);
  free(buf[i].text);
 }
 free(buf);
}

variable_types: struct lok_item_t { char *id; char *title; char *text; char *edited; char *added; } *

variable_types: i int


decompiled_code:
char *__fastcall skip_dots(const char *a1)
{
char *result; // rax

result = strstr(a1, "..");
if ( result && *result == 46 )
{
do
++result;
while ( *result == 46 );
}
return result;
}

canonical_decompiled_code:
char *__fastcall func0(const char *a1)
{
char *result; // rax

result = strstr(a1, "..");
if ( result && *result == 46 )
{
do
++result;
while ( *result == 46 );
}
return result;
}

original_code:
static char *
skip_dots(const char *pos)
{
 pos = strstr(pos, "..");
 if (!pos)
  return ((void *)0);
 while (*pos == '.')
  pos++;
 return (char *) pos;
}

canonical_original_code:
static char *skip_dots(char *pos)
{
 pos = strstr(pos, "..");
 if (!pos)
  return ((void *)0);
 while (*pos == '.')
  pos++;
 return (char *) pos;
}

variable_types:
pos
char *


original_code:
int
do_ses_cmd(int fd, uint8_t cmd, uint8_t page_nr, uint8_t flags,
    uint8_t cmd_len, int dxfer_direction, void *buf, int buf_len)
{
 unsigned char scsi_cmd_buf[16] = {
  cmd,
  flags,
  page_nr,
  (buf_len >> 8) & 0xff,
  buf_len & 0xff,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 struct sense_data_t sense_data;
 sg_io_hdr_t hdr;
 int i, rc;
 for (i = 0; i < 3; i++) {
  memset(&hdr, 0, sizeof(hdr));
  memset(&sense_data, 0, sizeof(struct sense_data_t));
  hdr.interface_id = 'S';
  hdr.dxfer_direction = dxfer_direction;
  hdr.cmd_len = cmd_len;
  hdr.mx_sb_len = sizeof(sense_data);
  hdr.iovec_count = 0;
  hdr.dxfer_len = buf_len;
  hdr.dxferp = buf;
  hdr.cmdp = scsi_cmd_buf;
  hdr.sbp = (unsigned char *)&sense_data;
  hdr.timeout = 120 * 1000;
  hdr.flags = 0;
  hdr.pack_id = 0;
  hdr.usr_ptr = 0;
  rc = ioctl(fd, 0x2285, &hdr);
  if ((rc == 0) && (hdr.masked_status == 0x01))
   rc = 0x01;
  else if ((rc == 0) && (hdr.host_status || hdr.driver_status))
   rc = -5;
  if (rc == 0 || hdr.host_status == 1)
   break;
 }
 return rc;
}

canonical_original_code:
int do_ses_cmd(int fd, unsigned char cmd, unsigned char page_nr, unsigned char flags, unsigned char cmd_len, int dxfer_direction, void *buf, int buf_len)
{
 unsigned char scsi_cmd_buf[16] = {
  cmd,
  flags,
  page_nr,
  (buf_len >> 8) & 0xff,
  buf_len & 0xff,
  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 struct sense_data_t sense_data;
 struct sg_io_hdr hdr;
 int i; int rc;
 for (i = 0; i < 3; i++) {
  memset(&hdr, 0, sizeof(hdr));
  memset(&sense_data, 0, sizeof(struct sense_data_t));
  hdr.interface_id = 'S';
  hdr.dxfer_direction = dxfer_direction;
  hdr.cmd_len = cmd_len;
  hdr.mx_sb_len = sizeof(sense_data);
  hdr.iovec_count = 0;
  hdr.dxfer_len = buf_len;
  hdr.dxferp = buf;
  hdr.cmdp = scsi_cmd_buf;
  hdr.sbp = (unsigned char *)&sense_data;
  hdr.timeout = 120 * 1000;
  hdr.flags = 0;
  hdr.pack_id = 0;
  hdr.usr_ptr = 0;
  rc = ioctl(fd, 0x2285, &hdr);
  if ((rc == 0) && (hdr.masked_status == 0x01))
   rc = 0x01;
  else if ((rc == 0) && (hdr.host_status || hdr.driver_status))
   rc = -5;
  if (rc == 0 || hdr.host_status == 1)
   break;
 }
 return rc;
}

variable_types: fd int

variable_types:
cmd
unsigned char

variable_types:
flags
unsigned char

variable_types:
buf
void *

variable_types: struct sense_data_t { unsigned char error_code; unsigned char segment_numb; unsigned char sense_key; unsigned char info[4]; unsigned char add_sense_len; unsigned char cmd_spec_info[4]; unsigned char add_sense_code; unsigned char add_sense_code_qual; unsigned char field_rep_unit_code; unsigned char sense_key_spec[3]; unsigned char add_sense_bytes[]; }

variable_types: struct sg_io_hdr { int interface_id; int dxfer_direction; unsigned char cmd_len; unsigned char mx_sb_len; unsigned short iovec_count; unsigned int dxfer_len; void *dxferp; unsigned char *cmdp; unsigned char *sbp; unsigned int timeout; unsigned int flags; int pack_id; void *usr_ptr; unsigned char status; unsigned char masked_status; unsigned char msg_status; unsigned char sb_len_wr; unsigned short host_status; unsigned short driver_status; int resid; unsigned int duration; unsigned int info; }

variable_types: rc int


decompiled_code:
char *__fastcall trim_location_code(__int64 a1)
{
char *result; // rax

strcpy((char *)(a1 + 128), (const char *)(a1 + 256));
result = strchr((const char *)(a1 + 128), 45);
if ( result && (!strcmp(result, "-P1-C1") || !strcmp(result, "-P1-C2")) )
*result = 0;
return result;
}

canonical_decompiled_code:
char *__fastcall func4(__int64 a1)
{
char *result; // rax

strcpy((char *)(a1 + 128), (const char *)(a1 + 256));
result = strchr((const char *)(a1 + 128), 45);
if ( result && (!strcmp(result, "-P1-C1") || !strcmp(result, "-P1-C2")) )
*result = 0;
return result;
}

original_code:
void
trim_location_code(struct dev_vpd *vpd)
{
 char *hyphen;
 strcpy(vpd->location, vpd->full_loc);
 hyphen = strchr(vpd->location, '-');
 if (hyphen && (!strcmp(hyphen, "-P1-C1") || !strcmp(hyphen, "-P1-C2")))
  *hyphen = '\0';
}

variable_types: struct dev_vpd { char mtm[128]; char location[128]; char full_loc[128]; char sn[128]; char fru[128]; struct dev_vpd *next; } *

variable_types:
hyphen
char *


decompiled_code:
int __fastcall get_diagnostic_page(int a1, char a2, char a3, __int64 a4, int a5)
{
return do_ses_cmd(a1, a2, a3, 1, 0x10u, -3, a4, a5);
}

canonical_decompiled_code:
int __fastcall func2(int a1, char a2, char a3, __int64 a4, int a5)
{
return func1(a1, a2, a3, 1, 0x10u, -3, a4, a5);
}

original_code:
int
get_diagnostic_page(int fd, uint8_t cmd, uint8_t page_nr, void *buf,
      int buf_len)
{
 return do_ses_cmd(fd, cmd, page_nr, 0x1, 16, -3,
        buf, buf_len);
}

canonical_original_code:
int get_diagnostic_page(int fd, unsigned char cmd, unsigned char page_nr, void *buf, int buf_len)
{
 return do_ses_cmd(fd, cmd, page_nr, 0x1, 16, -3,
        buf, buf_len);
}


original_code:
int
get_vpd_page(int fd, char command, char page_nr, void *buf, int buf_len)
{
 unsigned char scsi_cmd_buf[16] =
  { command,
   0x01,
   page_nr,
   (buf_len >> 8) & 0xff,
   buf_len & 0xff,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 struct sense_data_t sense_data;
 sg_io_hdr_t hdr;
 int i, rc;
 for (i = 0; i < 3; i++) {
  memset(&hdr, 0, sizeof(hdr));
  memset(&sense_data, 0, sizeof(struct sense_data_t));
  hdr.interface_id = 'S';
  hdr.dxfer_direction = -3;
  hdr.cmd_len = 16;
  hdr.mx_sb_len = sizeof(sense_data);
  hdr.iovec_count = 0;
  hdr.dxfer_len = buf_len;
  hdr.dxferp = buf;
  hdr.cmdp = scsi_cmd_buf;
  hdr.sbp = (unsigned char *)&sense_data;
  hdr.timeout = 120 * 1000;
  hdr.flags = 0;
  hdr.pack_id = 0;
  hdr.usr_ptr = 0;
  rc = ioctl(fd, 0x2285, &hdr);
  if ((rc == 0) && (hdr.masked_status == 0x01))
   rc = 0x01;
  else if ((rc == 0) && (hdr.host_status || hdr.driver_status))
   rc = -5;
  if (rc == 0 || hdr.host_status == 1)
   break;
 }
 return rc;
}

canonical_original_code:
int get_vpd_page(int fd, char command, char page_nr, void *buf, int buf_len)
{
 unsigned char scsi_cmd_buf[16] = { command,
   0x01,
   page_nr,
   (buf_len >> 8) & 0xff,
   buf_len & 0xff,
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 struct sense_data_t sense_data;
 struct sg_io_hdr hdr;
 int i; int rc;
 for (i = 0; i < 3; i++) {
  memset(&hdr, 0, sizeof(hdr));
  memset(&sense_data, 0, sizeof(struct sense_data_t));
  hdr.interface_id = 'S';
  hdr.dxfer_direction = -3;
  hdr.cmd_len = 16;
  hdr.mx_sb_len = sizeof(sense_data);
  hdr.iovec_count = 0;
  hdr.dxfer_len = buf_len;
  hdr.dxferp = buf;
  hdr.cmdp = scsi_cmd_buf;
  hdr.sbp = (unsigned char *)&sense_data;
  hdr.timeout = 120 * 1000;
  hdr.flags = 0;
  hdr.pack_id = 0;
  hdr.usr_ptr = 0;
  rc = ioctl(fd, 0x2285, &hdr);
  if ((rc == 0) && (hdr.masked_status == 0x01))
   rc = 0x01;
  else if ((rc == 0) && (hdr.host_status || hdr.driver_status))
   rc = -5;
  if (rc == 0 || hdr.host_status == 1)
   break;
 }
 return rc;
}

variable_types: command char

user_defined_types: struct sense_data_t { unsigned char error_code; unsigned char segment_numb; unsigned char sense_key; unsigned char info[4]; unsigned char add_sense_len; unsigned char cmd_spec_info[4]; unsigned char add_sense_code; unsigned char add_sense_code_qual; unsigned char field_rep_unit_code; unsigned char sense_key_spec[3]; unsigned char add_sense_bytes[]; }

user_defined_types: struct sg_io_hdr { int interface_id; int dxfer_direction; unsigned char cmd_len; unsigned char mx_sb_len; unsigned short iovec_count; unsigned int dxfer_len; void *dxferp; unsigned char *cmdp; unsigned char *sbp; unsigned int timeout; unsigned int flags; int pack_id; void *usr_ptr; unsigned char status; unsigned char masked_status; unsigned char msg_status; unsigned char sb_len_wr; unsigned short host_status; unsigned short driver_status; int resid; unsigned int duration; unsigned int info; }