decompiled_code:
__int16 __fastcall GBA_SaveWrite8(int a1, unsigned __int8 a2)
{
unsigned __int8 *v2; // rax
__int64 v3; // rbx
__int64 v4; // rbx
__int64 v5; // rbx
__int64 v6; // rax
char *v7; // rcx

LODWORD(v2) = SAVE_TYPE;
if ( SAVE_TYPE == 7 )
{
if ( a1 == 234902869 && a2 == 0xAA )
{
SAVE_TYPE = 4;
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
printf("FLASH (Default to 128KB)");
LOWORD(v2) = SAVE_TYPE;
if ( (int)SAVE_TYPE <= 3 )
{
if ( (int)SAVE_TYPE <= 1 )
{
v3 = 21845LL;
if ( SAVE_TYPE != 1 )
return (__int16)v2;
goto LABEL_29;
}
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE > 1u )
goto LABEL_21;
LABEL_37:
if ( ((unsigned __int8)v2 & 1) == 0 && a2 == 0xAA )
{
FLASH_CMD_STATE = 1;
return (__int16)v2;
}
goto LABEL_42;
}
if ( SAVE_TYPE != 4 )
return (__int16)v2;
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE <= 1u )
goto LABEL_37;
goto LABEL_9;
}
LOWORD(v2) = a1;
if ( (unsigned int)(a1 - 234881024) > 0xFFFF )
return (__int16)v2;
SAVE_TYPE = 1;
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
printf("SRAM (32KB)");
LODWORD(v2) = SAVE_TYPE;
}
if ( (int)v2 > 3 )
{
if ( (_DWORD)v2 != 4 )
return (__int16)v2;
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE <= 1u )
{
LABEL_30:
if ( a1 != 234902869 )
{
if ( a1 != 234891946 )
return (__int16)v2;
if ( a2 == 85 && ((unsigned __int8)v2 & 1) != 0 )
{
FLASH_CMD_STATE = 2;
return (__int16)v2;
}
goto LABEL_42;
}
goto LABEL_37;
}
LABEL_9:
if ( (_DWORD)v2 != 2 )
{
if ( (_DWORD)v2 != 3 )
return (__int16)v2;
if ( FLASH_CMD == 160 )
{
v5 = (unsigned int)(a1 - 234881024);
if ( (unsigned int)v5 <= 0xFFFF )
*(_BYTE *)(FLASH_1M_PTR[0] + v5) = a2;
}
else if ( FLASH_CMD == 176 && a1 == 234881024 )
{
if ( (a2 & 1) != 0 )
v7 = (char *)&unk_10000 + (_QWORD)&FLASH_BUFFER1M;
else
v7 = (char *)&FLASH_BUFFER1M;
FLASH_1M_PTR[0] = v7;
}
goto LABEL_14;
}
LODWORD(v2) = a1;
BYTE1(v2) = BYTE1(a1) & 0xF;
if ( (_DWORD)v2 != 234881024 || a2 != 48 )
{
if ( a1 == 234902869 )
{
FLASH_CMD_STATE = 0;
if ( a2 != 0x90 )
{
if ( a2 <= 0x90u )
{
if ( a2 == 16 )
{
if ( FLASH_CMD == 128 )
{
memset(&FLASH_BUFFER1M, 255, (size_t)&unk_20000);
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 16;
FLASH_STATE = 1;
return (__int16)v2;
}
goto LABEL_15;
}
goto LABEL_57;
}
if ( a2 != 0xA0 )
{
if ( a2 == 0xB0 )
{
FLASH_CMD_STATE = 3;
FLASH_CMD = 176;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 0;
return (__int16)v2;
}
goto LABEL_70;
}
LABEL_65:
FLASH_CMD_STATE = 3;
FLASH_CMD = 160;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 0;
return (__int16)v2;
}
LABEL_71:
FLASH_CMD = 144;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 1;
return (__int16)v2;
}
LABEL_42:
FLASH_CMD_STATE = 0;
return (__int16)v2;
}
if ( FLASH_CMD == 128 )
{
v6 = LODWORD(FLASH_1M_PTR[0]) + (a1 & 0xF000u);
*(_QWORD *)(unsigned int)v6 = -1LL;
*(_QWORD *)(v6 + 4087) = -1LL;
memset(
(void *)((v6 + 8) & 0xFFFFFFFFFFFFFFF8LL),
0xFFu,
8LL * (((unsigned int)v6 - (((_DWORD)v6 + 8) & 0xFFFFFFF8) + 4095) >> 3));
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 48;
FLASH_STATE = 1;
goto LABEL_42;
}
LABEL_41:
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 0;
FLASH_STATE = 0;
goto LABEL_42;
}
if ( (int)v2 > 1 )
{
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE > 1u )
{
LABEL_21:
if ( (_DWORD)v2 != 2 )
{
if ( (_DWORD)v2 != 3 )
return (__int16)v2;
if ( FLASH_CMD == 160 )
{
v4 = (unsigned int)(a1 - 234881024);
if ( (unsigned int)v4 <= 0xFFFF )
FLASH_BUFFER512[v4] = a2;
}
LABEL_14:
FLASH_CMD_STATE = 0;
LABEL_15:
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 0;
FLASH_STATE = 0;
return (__int16)v2;
}
LODWORD(v2) = a1;
BYTE1(v2) = BYTE1(a1) & 0xF;
if ( (_DWORD)v2 != 234881024 || a2 != 48 )
{
if ( a1 == 234902869 )
{
FLASH_CMD_STATE = 0;
if ( a2 != 0x90 )
{
if ( a2 <= 0x90u )
{
if ( a2 == 16 )
{
if ( FLASH_CMD == 128 )
{
memset(FLASH_BUFFER512, 255, (size_t)&unk_10000);
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 16;
FLASH_STATE = 1;
return (__int16)v2;
}
goto LABEL_15;
}
LABEL_57:
if ( a2 == 0x80 )
{
FLASH_CMD = 128;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 1;
return (__int16)v2;
}
LABEL_70:
FLASH_STATE = 0;
v2 = (unsigned __int8 *)&FLASH_CMD;
FLASH_CMD = 0;
return (__int16)v2;
}
if ( a2 != 0xA0 )
goto LABEL_70;
goto LABEL_65;
}
goto LABEL_71;
}
goto LABEL_42;
}
if ( FLASH_CMD == 128 )
{
memset((void *)((unsigned int)FLASH_BUFFER512 + (a1 & 0xF000)), 0xFFu, 0xFF8uLL);
FLASH_CMD = 48;
*(_WORD *)((char *)&loc_FFB + (unsigned int)FLASH_BUFFER512 + (a1 & 0xF000) + 1) = -1;
v2 = (unsigned __int8 *)&FLASH_STATE;
*(_DWORD *)((char *)&loc_FF4 + (unsigned int)FLASH_BUFFER512 + (a1 & 0xF000) + 4) = -1;
*((_BYTE *)&loc_FFB + (unsigned int)FLASH_BUFFER512 + (a1 & 0xF000) + 3) = -1;
FLASH_STATE = 1;
goto LABEL_42;
}
goto LABEL_41;
}
goto LABEL_30;
}
if ( (_DWORD)v2 == 1 )
{
v3 = (unsigned int)(a1 - 234881024);
if ( (unsigned int)v3 <= 0x7FFF )
{
LABEL_29:
v2 = SRAM_BUFFER;
SRAM_BUFFER[v3] = a2;
return (__int16)v2;
}
}
return (__int16)v2;
}

canonical_decompiled_code:
__int16 __fastcall func7(int a1, unsigned __int8 a2)
{
unsigned __int8 *v2; // rax
__int64 v3; // rbx
__int64 v4; // rbx
__int64 v5; // rbx
__int64 v6; // rax
char *v7; // rcx

LODWORD(v2) = SAVE_TYPE;
if ( SAVE_TYPE == 7 )
{
if ( a1 == 234902869 && a2 == 0xAA )
{
SAVE_TYPE = 4;
func1();
func4();
printf("FLASH (Default to 128KB)");
LOWORD(v2) = SAVE_TYPE;
if ( (int)SAVE_TYPE <= 3 )
{
if ( (int)SAVE_TYPE <= 1 )
{
v3 = 21845LL;
if ( SAVE_TYPE != 1 )
return (__int16)v2;
goto LABEL_29;
}
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE > 1u )
goto LABEL_21;
LABEL_37:
if ( ((unsigned __int8)v2 & 1) == 0 && a2 == 0xAA )
{
FLASH_CMD_STATE = 1;
return (__int16)v2;
}
goto LABEL_42;
}
if ( SAVE_TYPE != 4 )
return (__int16)v2;
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE <= 1u )
goto LABEL_37;
goto LABEL_9;
}
LOWORD(v2) = a1;
if ( (unsigned int)(a1 - 234881024) > 0xFFFF )
return (__int16)v2;
SAVE_TYPE = 1;
func1();
func4();
printf("SRAM (32KB)");
LODWORD(v2) = SAVE_TYPE;
}
if ( (int)v2 > 3 )
{
if ( (_DWORD)v2 != 4 )
return (__int16)v2;
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE <= 1u )
{
LABEL_30:
if ( a1 != 234902869 )
{
if ( a1 != 234891946 )
return (__int16)v2;
if ( a2 == 85 && ((unsigned __int8)v2 & 1) != 0 )
{
FLASH_CMD_STATE = 2;
return (__int16)v2;
}
goto LABEL_42;
}
goto LABEL_37;
}
LABEL_9:
if ( (_DWORD)v2 != 2 )
{
if ( (_DWORD)v2 != 3 )
return (__int16)v2;
if ( FLASH_CMD == 160 )
{
v5 = (unsigned int)(a1 - 234881024);
if ( (unsigned int)v5 <= 0xFFFF )
*(_BYTE *)(FLASH_1M_PTR[0] + v5) = a2;
}
else if ( FLASH_CMD == 176 && a1 == 234881024 )
{
if ( (a2 & 1) != 0 )
v7 = (char *)&unk_10000 + (_QWORD)&FLASH_BUFFER1M;
else
v7 = (char *)&FLASH_BUFFER1M;
FLASH_1M_PTR[0] = v7;
}
goto LABEL_14;
}
LODWORD(v2) = a1;
BYTE1(v2) = BYTE1(a1) & 0xF;
if ( (_DWORD)v2 != 234881024 || a2 != 48 )
{
if ( a1 == 234902869 )
{
FLASH_CMD_STATE = 0;
if ( a2 != 0x90 )
{
if ( a2 <= 0x90u )
{
if ( a2 == 16 )
{
if ( FLASH_CMD == 128 )
{
memset(&FLASH_BUFFER1M, 255, (size_t)&unk_20000);
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 16;
FLASH_STATE = 1;
return (__int16)v2;
}
goto LABEL_15;
}
goto LABEL_57;
}
if ( a2 != 0xA0 )
{
if ( a2 == 0xB0 )
{
FLASH_CMD_STATE = 3;
FLASH_CMD = 176;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 0;
return (__int16)v2;
}
goto LABEL_70;
}
LABEL_65:
FLASH_CMD_STATE = 3;
FLASH_CMD = 160;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 0;
return (__int16)v2;
}
LABEL_71:
FLASH_CMD = 144;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 1;
return (__int16)v2;
}
LABEL_42:
FLASH_CMD_STATE = 0;
return (__int16)v2;
}
if ( FLASH_CMD == 128 )
{
v6 = LODWORD(FLASH_1M_PTR[0]) + (a1 & 0xF000u);
*(_QWORD *)(unsigned int)v6 = -1LL;
*(_QWORD *)(v6 + 4087) = -1LL;
memset(
(void *)((v6 + 8) & 0xFFFFFFFFFFFFFFF8LL),
0xFFu,
8LL * (((unsigned int)v6 - (((_DWORD)v6 + 8) & 0xFFFFFFF8) + 4095) >> 3));
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 48;
FLASH_STATE = 1;
goto LABEL_42;
}
LABEL_41:
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 0;
FLASH_STATE = 0;
goto LABEL_42;
}
if ( (int)v2 > 1 )
{
LODWORD(v2) = FLASH_CMD_STATE;
if ( FLASH_CMD_STATE > 1u )
{
LABEL_21:
if ( (_DWORD)v2 != 2 )
{
if ( (_DWORD)v2 != 3 )
return (__int16)v2;
if ( FLASH_CMD == 160 )
{
v4 = (unsigned int)(a1 - 234881024);
if ( (unsigned int)v4 <= 0xFFFF )
FLASH_BUFFER512[v4] = a2;
}
LABEL_14:
FLASH_CMD_STATE = 0;
LABEL_15:
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 0;
FLASH_STATE = 0;
return (__int16)v2;
}
LODWORD(v2) = a1;
BYTE1(v2) = BYTE1(a1) & 0xF;
if ( (_DWORD)v2 != 234881024 || a2 != 48 )
{
if ( a1 == 234902869 )
{
FLASH_CMD_STATE = 0;
if ( a2 != 0x90 )
{
if ( a2 <= 0x90u )
{
if ( a2 == 16 )
{
if ( FLASH_CMD == 128 )
{
memset(FLASH_BUFFER512, 255, (size_t)&unk_10000);
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_CMD = 16;
FLASH_STATE = 1;
return (__int16)v2;
}
goto LABEL_15;
}
LABEL_57:
if ( a2 == 0x80 )
{
FLASH_CMD = 128;
v2 = (unsigned __int8 *)&FLASH_STATE;
FLASH_STATE = 1;
return (__int16)v2;
}
LABEL_70:
FLASH_STATE = 0;
v2 = (unsigned __int8 *)&FLASH_CMD;
FLASH_CMD = 0;
return (__int16)v2;
}
if ( a2 != 0xA0 )
goto LABEL_70;
goto LABEL_65;
}
goto LABEL_71;
}
goto LABEL_42;
}
if ( FLASH_CMD == 128 )
{
memset((void *)((unsigned int)FLASH_BUFFER512 + (a1 & 0xF000)), 0xFFu, 0xFF8uLL);
FLASH_CMD = 48;
*(_WORD *)((char *)&loc_FFB + (unsigned int)FLASH_BUFFER512 + (a1 & 0xF000) + 1) = -1;
v2 = (unsigned __int8 *)&FLASH_STATE;
*(_DWORD *)((char *)&loc_FF4 + (unsigned int)FLASH_BUFFER512 + (a1 & 0xF000) + 4) = -1;
*((_BYTE *)&loc_FFB + (unsigned int)FLASH_BUFFER512 + (a1 & 0xF000) + 3) = -1;
FLASH_STATE = 1;
goto LABEL_42;
}
goto LABEL_41;
}
goto LABEL_30;
}
if ( (_DWORD)v2 == 1 )
{
v3 = (unsigned int)(a1 - 234881024);
if ( (unsigned int)v3 <= 0x7FFF )
{
LABEL_29:
v2 = SRAM_BUFFER;
SRAM_BUFFER[v3] = a2;
return (__int16)v2;
}
}
return (__int16)v2;
}

original_code:
void GBA_SaveWrite8(u32 address, u8 data)
{
    if(SAVE_TYPE == SAV_AUTODETECT)
    {
        if((address == 0x0E005555) && (data == 0xAA))
        {
            SAVE_TYPE = SAV_FLASH1M;
            GBA_ResetSaveBuffer();
            GBA_SaveReadFile();
            printf("FLASH (Default to 128KB)");
        }
        else if((address >= 0x0E000000) && (address < 0x0E010000))
        {
            SAVE_TYPE = SAV_SRAM;
            GBA_ResetSaveBuffer();
            GBA_SaveReadFile();
            printf("SRAM (32KB)");
        }
    }
    switch(SAVE_TYPE)
    {
        case SAV_SRAM:
        {
            if((address >= 0x0E000000) && (address < 0x0E008000))
                SRAM_BUFFER[address-0x0E000000] = data;
            return;
        }
        case SAV_FLASH:
        case SAV_FLASH512:
        {
            if(FLASH_CMD_STATE < 2)
            {
                if(address == 0x0E005555)
                {
                    if((data == 0xAA) && (FLASH_CMD_STATE == 0)) FLASH_CMD_STATE = 1;
                    else FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E002AAA)
                {
                    if((FLASH_CMD_STATE == 1) && (data == 0x55)) FLASH_CMD_STATE = 2;
                    else FLASH_CMD_STATE = 0;
                }
            }
            else if(FLASH_CMD_STATE == 2)
            {
                if( ((address&0xFF000000) == 0x0E000000) && ((address&0x00FF0FFF) == 0) && (data == 0x30) )
                {
                    if(FLASH_CMD == 0x80)
                    {
                        memset((void*)((u32)FLASH_BUFFER512+(address&0x0000F000)),0xFF,0xFFF);
                        FLASH_CMD = 0x30;
                        FLASH_STATE = 1;
                    }
                    else
                    {
                        FLASH_CMD = 0;
                        FLASH_STATE = 0;
                    }
                    FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E005555)
                {
                    FLASH_CMD_STATE = 0;
                    switch(data)
                    {
                        case 0x10:
                            if(FLASH_CMD == 0x80)
                            {
                                memset(FLASH_BUFFER512,0xFF,sizeof(FLASH_BUFFER512));
                                FLASH_CMD = 0x10;
                                FLASH_STATE = 1;
                            }
                            else
                            {
                                FLASH_CMD = 0;
                                FLASH_STATE = 0;
                            }
                            return;
                        case 0x80:
                            FLASH_CMD = 0x80;
                            FLASH_STATE = 1;
                            return;
                        case 0x90:
                            FLASH_CMD = 0x90;
                            FLASH_STATE = 1;
                            return;
                        case 0xA0:
                            FLASH_CMD = 0xA0;
                            FLASH_STATE = 0;
                            FLASH_CMD_STATE = 3;
                            return;
                        case 0xF0:
                        default:
                            FLASH_STATE = 0;
                            FLASH_CMD = 0;
                            return;
                    }
                }
                else FLASH_CMD_STATE = 0;
            }
            else if(FLASH_CMD_STATE == 3)
            {
                if(FLASH_CMD == 0xA0)
                {
                    if((address >= 0x0E000000) && (address < 0x0E010000))
                        FLASH_BUFFER512[address-0x0E000000] = data;
                }
                FLASH_CMD_STATE = 0;
                FLASH_CMD = 0;
                FLASH_STATE = 0;
            }
            return;
        }
        case SAV_FLASH1M:
        {
            if(FLASH_CMD_STATE < 2)
            {
                if(address == 0x0E005555)
                {
                    if((data == 0xAA) && (FLASH_CMD_STATE == 0)) FLASH_CMD_STATE = 1;
                    else FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E002AAA)
                {
                    if((FLASH_CMD_STATE == 1) && (data == 0x55)) FLASH_CMD_STATE = 2;
                    else FLASH_CMD_STATE = 0;
                }
            }
            else if(FLASH_CMD_STATE == 2)
            {
                if( ((address&0xFF000000) == 0x0E000000) && ((address&0x00FF0FFF) == 0) && (data == 0x30) )
                {
                    if(FLASH_CMD == 0x80)
                    {
                        memset((void*)((u32)FLASH_1M_PTR+(address&0x0000F000)),0xFF,0xFFF);
                        FLASH_CMD = 0x30;
                        FLASH_STATE = 1;
                    }
                    else
                    {
                        FLASH_CMD = 0;
                        FLASH_STATE = 0;
                    }
                    FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E005555)
                {
                    FLASH_CMD_STATE = 0;
                    switch(data)
                    {
                        case 0x10:
                            if(FLASH_CMD == 0x80)
                            {
                                memset(FLASH_BUFFER1M,0xFF,sizeof(FLASH_BUFFER1M));
                                FLASH_CMD = 0x10;
                                FLASH_STATE = 1;
                            }
                            else
                            {
                                FLASH_CMD = 0;
                                FLASH_STATE = 0;
                            }
                            return;
                        case 0x80:
                            FLASH_CMD = 0x80;
                            FLASH_STATE = 1;
                            return;
                        case 0x90:
                            FLASH_CMD = 0x90;
                            FLASH_STATE = 1;
                            return;
                        case 0xA0:
                            FLASH_CMD = 0xA0;
                            FLASH_STATE = 0;
                            FLASH_CMD_STATE = 3;
                            return;
                        case 0xB0:
                            FLASH_CMD = 0xB0;
                            FLASH_STATE = 0;
                            FLASH_CMD_STATE = 3;
                            return;
                        case 0xF0:
                        default:
                            FLASH_STATE = 0;
                            FLASH_CMD = 0;
                            return;
                    }
                }
                else FLASH_CMD_STATE = 0;
            }
            else if(FLASH_CMD_STATE == 3)
            {
                if(FLASH_CMD == 0xA0)
                {
                    if((address >= 0x0E000000) && (address < 0x0E010000))
                        FLASH_1M_PTR[address-0x0E000000] = data;
                }
                else if(FLASH_CMD == 0xB0)
                {
                    if(address == 0x0E000000)
                    {
                        FLASH_1M_PTR = (data&1) ? &(FLASH_BUFFER1M[0x10000]) : FLASH_BUFFER1M;
                    }
                }
                FLASH_CMD_STATE = 0;
                FLASH_CMD = 0;
                FLASH_STATE = 0;
            }
            return;
        }
        case SAV_EEPROM:
        {
            return;
        }
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return;
    }
}

canonical_original_code:
void GBA_SaveWrite8(unsigned int address, unsigned char data)
{
    if(SAVE_TYPE == SAV_AUTODETECT)
    {
        if((address == 0x0E005555) && (data == 0xAA))
        {
            SAVE_TYPE = SAV_FLASH1M;
            GBA_ResetSaveBuffer();
            GBA_SaveReadFile();
            printf("FLASH (Default to 128KB)");
        }
        else if((address >= 0x0E000000) && (address < 0x0E010000))
        {
            SAVE_TYPE = SAV_SRAM;
            GBA_ResetSaveBuffer();
            GBA_SaveReadFile();
            printf("SRAM (32KB)");
        }
    }
    switch(SAVE_TYPE)
    {
        case SAV_SRAM:
        {
            if((address >= 0x0E000000) && (address < 0x0E008000))
                SRAM_BUFFER[address-0x0E000000] = data;
            return;
        }
        case SAV_FLASH:
        case SAV_FLASH512:
        {
            if(FLASH_CMD_STATE < 2)
            {
                if(address == 0x0E005555)
                {
                    if((data == 0xAA) && (FLASH_CMD_STATE == 0)) FLASH_CMD_STATE = 1;
                    else FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E002AAA)
                {
                    if((FLASH_CMD_STATE == 1) && (data == 0x55)) FLASH_CMD_STATE = 2;
                    else FLASH_CMD_STATE = 0;
                }
            }
            else if(FLASH_CMD_STATE == 2)
            {
                if( ((address&0xFF000000) == 0x0E000000) && ((address&0x00FF0FFF) == 0) && (data == 0x30) )
                {
                    if(FLASH_CMD == 0x80)
                    {
                        memset((void *)((unsigned int)FLASH_BUFFER512+(address&0x0000F000)),0xFF,0xFFF);
                        FLASH_CMD = 0x30;
                        FLASH_STATE = 1;
                    }
                    else
                    {
                        FLASH_CMD = 0;
                        FLASH_STATE = 0;
                    }
                    FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E005555)
                {
                    FLASH_CMD_STATE = 0;
                    switch(data)
                    {
                        case 0x10:
                            if(FLASH_CMD == 0x80)
                            {
                                memset(FLASH_BUFFER512,0xFF,sizeof(FLASH_BUFFER512));
                                FLASH_CMD = 0x10;
                                FLASH_STATE = 1;
                            }
                            else
                            {
                                FLASH_CMD = 0;
                                FLASH_STATE = 0;
                            }
                            return;
                        case 0x80:
                            FLASH_CMD = 0x80;
                            FLASH_STATE = 1;
                            return;
                        case 0x90:
                            FLASH_CMD = 0x90;
                            FLASH_STATE = 1;
                            return;
                        case 0xA0:
                            FLASH_CMD = 0xA0;
                            FLASH_STATE = 0;
                            FLASH_CMD_STATE = 3;
                            return;
                        case 0xF0:
                        default:
                            FLASH_STATE = 0;
                            FLASH_CMD = 0;
                            return;
                    }
                }
                else FLASH_CMD_STATE = 0;
            }
            else if(FLASH_CMD_STATE == 3)
            {
                if(FLASH_CMD == 0xA0)
                {
                    if((address >= 0x0E000000) && (address < 0x0E010000))
                        FLASH_BUFFER512[address-0x0E000000] = data;
                }
                FLASH_CMD_STATE = 0;
                FLASH_CMD = 0;
                FLASH_STATE = 0;
            }
            return;
        }
        case SAV_FLASH1M:
        {
            if(FLASH_CMD_STATE < 2)
            {
                if(address == 0x0E005555)
                {
                    if((data == 0xAA) && (FLASH_CMD_STATE == 0)) FLASH_CMD_STATE = 1;
                    else FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E002AAA)
                {
                    if((FLASH_CMD_STATE == 1) && (data == 0x55)) FLASH_CMD_STATE = 2;
                    else FLASH_CMD_STATE = 0;
                }
            }
            else if(FLASH_CMD_STATE == 2)
            {
                if( ((address&0xFF000000) == 0x0E000000) && ((address&0x00FF0FFF) == 0) && (data == 0x30) )
                {
                    if(FLASH_CMD == 0x80)
                    {
                        memset((void *)((unsigned int)FLASH_1M_PTR+(address&0x0000F000)),0xFF,0xFFF);
                        FLASH_CMD = 0x30;
                        FLASH_STATE = 1;
                    }
                    else
                    {
                        FLASH_CMD = 0;
                        FLASH_STATE = 0;
                    }
                    FLASH_CMD_STATE = 0;
                }
                else if(address == 0x0E005555)
                {
                    FLASH_CMD_STATE = 0;
                    switch(data)
                    {
                        case 0x10:
                            if(FLASH_CMD == 0x80)
                            {
                                memset(FLASH_BUFFER1M,0xFF,sizeof(FLASH_BUFFER1M));
                                FLASH_CMD = 0x10;
                                FLASH_STATE = 1;
                            }
                            else
                            {
                                FLASH_CMD = 0;
                                FLASH_STATE = 0;
                            }
                            return;
                        case 0x80:
                            FLASH_CMD = 0x80;
                            FLASH_STATE = 1;
                            return;
                        case 0x90:
                            FLASH_CMD = 0x90;
                            FLASH_STATE = 1;
                            return;
                        case 0xA0:
                            FLASH_CMD = 0xA0;
                            FLASH_STATE = 0;
                            FLASH_CMD_STATE = 3;
                            return;
                        case 0xB0:
                            FLASH_CMD = 0xB0;
                            FLASH_STATE = 0;
                            FLASH_CMD_STATE = 3;
                            return;
                        case 0xF0:
                        default:
                            FLASH_STATE = 0;
                            FLASH_CMD = 0;
                            return;
                    }
                }
                else FLASH_CMD_STATE = 0;
            }
            else if(FLASH_CMD_STATE == 3)
            {
                if(FLASH_CMD == 0xA0)
                {
                    if((address >= 0x0E000000) && (address < 0x0E010000))
                        FLASH_1M_PTR[address-0x0E000000] = data;
                }
                else if(FLASH_CMD == 0xB0)
                {
                    if(address == 0x0E000000)
                    {
                        FLASH_1M_PTR = (data&1) ? &(FLASH_BUFFER1M[0x10000]) : FLASH_BUFFER1M;
                    }
                }
                FLASH_CMD_STATE = 0;
                FLASH_CMD = 0;
                FLASH_STATE = 0;
            }
            return;
        }
        case SAV_EEPROM:
        {
            return;
        }
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return;
    }
}

variable_types:
data
unsigned char


decompiled_code:
__int64 __fastcall GBA_SaveWrite16(int a1, char a2)
{
__int64 result; // rax
int v4; // eax
__int64 v5; // rsi

result = (unsigned int)SAVE_TYPE;
if ( SAVE_TYPE == 7 )
{
SAVE_TYPE = 0;
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
printf("EEPROM");
result = (unsigned int)SAVE_TYPE;
}
if ( !(_DWORD)result )
{
result = gba_dma3enabled();
if ( (_DWORD)result )
{
if ( eeprom_detect_size )
{
eeprom_detect_size = 0;
if ( (unsigned int)gba_dma3numchunks() == 9 )
{
EEPROM_SIZE = 512;
EEPROM_ADDRESS_BUS = 6;
EEPROM_ADDRESS_MASK = 511;
printf(" 512B");
}
else if ( (unsigned int)gba_dma3numchunks() == 17 )
{
EEPROM_SIZE = 0x2000;
EEPROM_ADDRESS_BUS = 14;
EEPROM_ADDRESS_MASK = 0x1FFF;
printf(" 8KB");
}
else
{
v5 = (unsigned int)gba_dma3numchunks();
ErrorMessage("EEPROM: Failed size autodetection. %d", v5);
printf("\nFailed size autodetection.");
}
}
a1 = (unsigned __int8)a1;
if ( !(_BYTE)a1 )
{
EEPROM_DATA_STREAMING = 0;
v4 = 1;
LABEL_9:
EEPROM_CMD_LEN = v4;
result = (__int64)&EEPROM_ADDRESS;
EEPROM_CMD = a2 & 1 | a1;
EEPROM_ADDRESS = 0;
return result;
}
if ( EEPROM_CMD_LEN <= 1u )
{
v4 = EEPROM_CMD_LEN + 1;
a1 = 2 * EEPROM_CMD;
goto LABEL_9;
}
if ( EEPROM_CMD_LEN < (unsigned int)(EEPROM_ADDRESS_BUS + 2) )
{
++EEPROM_CMD_LEN;
result = (unsigned int)(2 * EEPROM_ADDRESS);
EEPROM_ADDRESS = result | a2 & 1;
return result;
}
if ( EEPROM_CMD_LEN == EEPROM_ADDRESS_BUS + 2 )
{
EEPROM_CMD_LEN = EEPROM_ADDRESS_BUS + 3;
result = EEPROM_CMD;
if ( EEPROM_CMD == 3 )
{
EEPROM_CMD_LEN = 0;
EEPROM_DATA_STREAMING = 68;
result = (__int64)&EEPROM_READ_BUFFER;
EEPROM_READ_BUFFER = EEPROM_BUFFER[EEPROM_ADDRESS_MASK & EEPROM_ADDRESS];
}
else
{
if ( EEPROM_CMD != 2 )
{
LABEL_22:
EEPROM_CMD_LEN = 0;
return result;
}
EEPROM_READ_BUFFER = a2 & 1;
result = (__int64)&EEPROM_DATA_STREAMING;
EEPROM_DATA_STREAMING = 1;
}
}
else
{
result = EEPROM_DATA_STREAMING;
if ( EEPROM_DATA_STREAMING <= 0x3F )
{
result = ++EEPROM_DATA_STREAMING;
EEPROM_READ_BUFFER = (2LL * EEPROM_READ_BUFFER) | a2 & 1;
return result;
}
if ( EEPROM_DATA_STREAMING == 64 )
{
result = (unsigned int)(EEPROM_ADDRESS_MASK & EEPROM_ADDRESS);
EEPROM_BUFFER[result] = EEPROM_READ_BUFFER;
goto LABEL_22;
}
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(int a1, char a2)
{
__int64 result; // rax
int v4; // eax
__int64 v5; // rsi

result = (unsigned int)SAVE_TYPE;
if ( SAVE_TYPE == 7 )
{
SAVE_TYPE = 0;
func1();
func4();
printf("EEPROM");
result = (unsigned int)SAVE_TYPE;
}
if ( !(_DWORD)result )
{
result = gba_dma3enabled();
if ( (_DWORD)result )
{
if ( eeprom_detect_size )
{
eeprom_detect_size = 0;
if ( (unsigned int)gba_dma3numchunks() == 9 )
{
EEPROM_SIZE = 512;
EEPROM_ADDRESS_BUS = 6;
EEPROM_ADDRESS_MASK = 511;
printf(" 512B");
}
else if ( (unsigned int)gba_dma3numchunks() == 17 )
{
EEPROM_SIZE = 0x2000;
EEPROM_ADDRESS_BUS = 14;
EEPROM_ADDRESS_MASK = 0x1FFF;
printf(" 8KB");
}
else
{
v5 = (unsigned int)gba_dma3numchunks();
ErrorMessage("EEPROM: Failed size autodetection. %d", v5);
printf("\nFailed size autodetection.");
}
}
a1 = (unsigned __int8)a1;
if ( !(_BYTE)a1 )
{
EEPROM_DATA_STREAMING = 0;
v4 = 1;
LABEL_9:
EEPROM_CMD_LEN = v4;
result = (__int64)&EEPROM_ADDRESS;
EEPROM_CMD = a2 & 1 | a1;
EEPROM_ADDRESS = 0;
return result;
}
if ( EEPROM_CMD_LEN <= 1u )
{
v4 = EEPROM_CMD_LEN + 1;
a1 = 2 * EEPROM_CMD;
goto LABEL_9;
}
if ( EEPROM_CMD_LEN < (unsigned int)(EEPROM_ADDRESS_BUS + 2) )
{
++EEPROM_CMD_LEN;
result = (unsigned int)(2 * EEPROM_ADDRESS);
EEPROM_ADDRESS = result | a2 & 1;
return result;
}
if ( EEPROM_CMD_LEN == EEPROM_ADDRESS_BUS + 2 )
{
EEPROM_CMD_LEN = EEPROM_ADDRESS_BUS + 3;
result = EEPROM_CMD;
if ( EEPROM_CMD == 3 )
{
EEPROM_CMD_LEN = 0;
EEPROM_DATA_STREAMING = 68;
result = (__int64)&EEPROM_READ_BUFFER;
EEPROM_READ_BUFFER = EEPROM_BUFFER[EEPROM_ADDRESS_MASK & EEPROM_ADDRESS];
}
else
{
if ( EEPROM_CMD != 2 )
{
LABEL_22:
EEPROM_CMD_LEN = 0;
return result;
}
EEPROM_READ_BUFFER = a2 & 1;
result = (__int64)&EEPROM_DATA_STREAMING;
EEPROM_DATA_STREAMING = 1;
}
}
else
{
result = EEPROM_DATA_STREAMING;
if ( EEPROM_DATA_STREAMING <= 0x3F )
{
result = ++EEPROM_DATA_STREAMING;
EEPROM_READ_BUFFER = (2LL * EEPROM_READ_BUFFER) | a2 & 1;
return result;
}
if ( EEPROM_DATA_STREAMING == 64 )
{
result = (unsigned int)(EEPROM_ADDRESS_MASK & EEPROM_ADDRESS);
EEPROM_BUFFER[result] = EEPROM_READ_BUFFER;
goto LABEL_22;
}
}
}
}
return result;
}

original_code:
void GBA_SaveWrite16(u32 address, u16 data)
{
    if(SAVE_TYPE == SAV_AUTODETECT)
    {
        {
            SAVE_TYPE = SAV_EEPROM;
            GBA_ResetSaveBuffer();
            GBA_SaveReadFile();
            printf("EEPROM");
        }
    }
    switch(SAVE_TYPE)
    {
        case SAV_EEPROM:
        {
            if(gba_dma3enabled())
            {
                if(eeprom_detect_size)
                {
                    eeprom_detect_size = 0;
                    if(gba_dma3numchunks() == 9)
                    {
                        EEPROM_SIZE = 512;
                        EEPROM_ADDRESS_BUS = 6;
                        EEPROM_ADDRESS_MASK = 0x1FF;
                        printf(" 512B");
                    }
                    else if(gba_dma3numchunks() == 17)
                    {
                        EEPROM_SIZE = 8*1024;
                        EEPROM_ADDRESS_BUS = 14;
                        EEPROM_ADDRESS_MASK = 0x1FFF;
                        printf(" 8KB");
                    }
                    else
                    {
                        ErrorMessage("EEPROM: Failed size autodetection. %d", gba_dma3numchunks());
                        printf("\nFailed size autodetection.");
                    }
                }
                data &= 1; address &= 0xFF;
                if(address == 0) { EEPROM_CMD_LEN = 0; EEPROM_CMD = 0; EEPROM_DATA_STREAMING = 0; }
                if(EEPROM_CMD_LEN < 2)
                {
                    EEPROM_CMD_LEN++;
                    EEPROM_CMD <<= 1; EEPROM_CMD |= data;
                    EEPROM_ADDRESS = 0;
                }
                else if(EEPROM_CMD_LEN < 2+EEPROM_ADDRESS_BUS)
                {
                    EEPROM_CMD_LEN++;
                    EEPROM_ADDRESS <<= 1; EEPROM_ADDRESS |= data;
                }
                else if(EEPROM_CMD_LEN == 2+EEPROM_ADDRESS_BUS)
                {
                    EEPROM_CMD_LEN++;
                    if(EEPROM_CMD == 3)
                    {
                        EEPROM_CMD_LEN = 0;
                        EEPROM_DATA_STREAMING = 68;
                        u32 addr = EEPROM_ADDRESS&EEPROM_ADDRESS_MASK;
                        EEPROM_READ_BUFFER = EEPROM_BUFFER[addr];
                    }
                    else if(EEPROM_CMD == 2)
                    {
                        EEPROM_READ_BUFFER = (u64)(data & 1);
                        EEPROM_DATA_STREAMING = 1;
                    }
                    else
                    {
                        EEPROM_CMD_LEN = 0;
                    }
                }
                else
                {
                    if(EEPROM_DATA_STREAMING < 64)
                    {
                        EEPROM_READ_BUFFER<<=1;
                        EEPROM_READ_BUFFER |= (u64)(data & 1);
                        EEPROM_DATA_STREAMING++;
                    }
                    else if(EEPROM_DATA_STREAMING == 64)
                    {
                        u32 addr = EEPROM_ADDRESS&EEPROM_ADDRESS_MASK;
                        EEPROM_BUFFER[addr] = EEPROM_READ_BUFFER;
                        EEPROM_CMD_LEN = 0;
                    }
                }
            }
            return;
        }
        case SAV_SRAM:
        case SAV_FLASH:
        case SAV_FLASH512:
        case SAV_FLASH1M:
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return;
    }
    return;
}

canonical_original_code:
void GBA_SaveWrite16(unsigned int address, unsigned short data)
{
    if(SAVE_TYPE == SAV_AUTODETECT)
    {
        {
            SAVE_TYPE = SAV_EEPROM;
            GBA_ResetSaveBuffer();
            GBA_SaveReadFile();
            printf("EEPROM");
        }
    }
    switch(SAVE_TYPE)
    {
        case SAV_EEPROM:
        {
            if(gba_dma3enabled())
            {
                if(eeprom_detect_size)
                {
                    eeprom_detect_size = 0;
                    if(gba_dma3numchunks() == 9)
                    {
                        EEPROM_SIZE = 512;
                        EEPROM_ADDRESS_BUS = 6;
                        EEPROM_ADDRESS_MASK = 0x1FF;
                        printf(" 512B");
                    }
                    else if(gba_dma3numchunks() == 17)
                    {
                        EEPROM_SIZE = 8*1024;
                        EEPROM_ADDRESS_BUS = 14;
                        EEPROM_ADDRESS_MASK = 0x1FFF;
                        printf(" 8KB");
                    }
                    else
                    {
                        ErrorMessage("EEPROM: Failed size autodetection. %d", gba_dma3numchunks());
                        printf("\nFailed size autodetection.");
                    }
                }
                data &= 1; address &= 0xFF;
                if(address == 0) { EEPROM_CMD_LEN = 0; EEPROM_CMD = 0; EEPROM_DATA_STREAMING = 0; }
                if(EEPROM_CMD_LEN < 2)
                {
                    EEPROM_CMD_LEN++;
                    EEPROM_CMD <<= 1; EEPROM_CMD |= data;
                    EEPROM_ADDRESS = 0;
                }
                else if(EEPROM_CMD_LEN < 2+EEPROM_ADDRESS_BUS)
                {
                    EEPROM_CMD_LEN++;
                    EEPROM_ADDRESS <<= 1; EEPROM_ADDRESS |= data;
                }
                else if(EEPROM_CMD_LEN == 2+EEPROM_ADDRESS_BUS)
                {
                    EEPROM_CMD_LEN++;
                    if(EEPROM_CMD == 3)
                    {
                        EEPROM_CMD_LEN = 0;
                        EEPROM_DATA_STREAMING = 68;
                        unsigned int addr = EEPROM_ADDRESS&EEPROM_ADDRESS_MASK;
                        EEPROM_READ_BUFFER = EEPROM_BUFFER[addr];
                    }
                    else if(EEPROM_CMD == 2)
                    {
                        EEPROM_READ_BUFFER = (u64)(data & 1);
                        EEPROM_DATA_STREAMING = 1;
                    }
                    else
                    {
                        EEPROM_CMD_LEN = 0;
                    }
                }
                else
                {
                    if(EEPROM_DATA_STREAMING < 64)
                    {
                        EEPROM_READ_BUFFER<<=1;
                        EEPROM_READ_BUFFER |= (u64)(data & 1);
                        EEPROM_DATA_STREAMING++;
                    }
                    else if(EEPROM_DATA_STREAMING == 64)
                    {
                        unsigned int addr = EEPROM_ADDRESS&EEPROM_ADDRESS_MASK;
                        EEPROM_BUFFER[addr] = EEPROM_READ_BUFFER;
                        EEPROM_CMD_LEN = 0;
                    }
                }
            }
            return;
        }
        case SAV_SRAM:
        case SAV_FLASH:
        case SAV_FLASH512:
        case SAV_FLASH1M:
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return;
    }
    return;
}

variable_types:
address
unsigned int

variable_types:
data
unsigned short

variable_types:
addr
unsigned int

return_type: void


decompiled_code:
__int64 GBA_TimerSetup0()
{
__int16 v0; // ax
char v1; // cl
__int64 result; // rax
__int16 v3; // cx
__int16 v4; // cx

v0 = Mem[147589];
*((_WORD *)&Timer + 6) = v0 & 4;
*((_WORD *)&Timer + 7) = v0 & 0x40;
v1 = v0;
result = gba_timerclockspertic[v0 & 3];
v3 = v1 & 0x80;
*((_WORD *)&Timer + 8) = v3;
*((_DWORD *)&Timer + 2) = result;
if ( v3 )
{
v4 = Timer;
*((_DWORD *)&Timer + 1) = result;
Mem[147588] = v4;
}
return result;
}

canonical_decompiled_code:
__int64 func1()
{
__int16 v0; // ax
char v1; // cl
__int64 result; // rax
__int16 v3; // cx
__int16 v4; // cx

v0 = Mem[147589];
*((_WORD *)&Timer + 6) = v0 & 4;
*((_WORD *)&Timer + 7) = v0 & 0x40;
v1 = v0;
result = gba_timerclockspertic[v0 & 3];
v3 = v1 & 0x80;
*((_WORD *)&Timer + 8) = v3;
*((_DWORD *)&Timer + 2) = result;
if ( v3 )
{
v4 = Timer;
*((_DWORD *)&Timer + 1) = result;
Mem[147588] = v4;
}
return result;
}


decompiled_code:
__int64 GBA_TimerSetup1()
{
__int16 v0; // ax
char v1; // cl
__int64 result; // rax
__int16 v3; // cx
__int16 v4; // cx

v0 = Mem[147591];
*((_WORD *)&Timer + 16) = v0 & 4;
*((_WORD *)&Timer + 17) = v0 & 0x40;
v1 = v0;
result = gba_timerclockspertic[v0 & 3];
v3 = v1 & 0x80;
*((_WORD *)&Timer + 18) = v3;
*((_DWORD *)&Timer + 7) = result;
if ( v3 )
{
v4 = *((_WORD *)&Timer + 10);
*((_DWORD *)&Timer + 6) = result;
Mem[147590] = v4;
}
return result;
}


decompiled_code:
__int64 GBA_TimerSetup2()
{
__int16 v0; // ax
char v1; // cl
__int64 result; // rax
__int16 v3; // cx
__int16 v4; // cx

v0 = Mem[147593];
*((_WORD *)&Timer + 26) = v0 & 4;
*((_WORD *)&Timer + 27) = v0 & 0x40;
v1 = v0;
result = gba_timerclockspertic[v0 & 3];
v3 = v1 & 0x80;
*((_WORD *)&Timer + 28) = v3;
*((_DWORD *)&Timer + 12) = result;
if ( v3 )
{
v4 = *((_WORD *)&Timer + 20);
*((_DWORD *)&Timer + 11) = result;
Mem[147592] = v4;
}
return result;
}

canonical_original_code:
void GBA_TimerSetup2()
{
    Timer[2].cascade = (*((unsigned short *)&Mem.io_regs[((0x0400010A))-(0x04000000)]))&(1<<(2));
    Timer[2].irqenable = (*((unsigned short *)&Mem.io_regs[((0x0400010A))-(0x04000000)]))&(1<<(6));
    Timer[2].enabled = (*((unsigned short *)&Mem.io_regs[((0x0400010A))-(0x04000000)]))&(1<<(7));
    Timer[2].clockspertick = gba_timerclockspertic[(*((unsigned short *)&Mem.io_regs[((0x0400010A))-(0x04000000)]))&3];
    if(Timer[2].enabled)
    {
        (*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) = Timer[2].start;
        Timer[2].remainingclocks = Timer[2].clockspertick;
    }
}


decompiled_code:
__int64 GBA_TimerSetup3()
{
__int16 v0; // ax
char v1; // cl
__int64 result; // rax
__int16 v3; // cx
__int16 v4; // cx

v0 = Mem[147595];
*((_WORD *)&Timer + 36) = v0 & 4;
*((_WORD *)&Timer + 37) = v0 & 0x40;
v1 = v0;
result = gba_timerclockspertic[v0 & 3];
v3 = v1 & 0x80;
*((_WORD *)&Timer + 38) = v3;
*((_DWORD *)&Timer + 17) = result;
if ( v3 )
{
v4 = *((_WORD *)&Timer + 30);
*((_DWORD *)&Timer + 16) = result;
Mem[147594] = v4;
}
return result;
}

canonical_original_code:
void GBA_TimerSetup3()
{
    Timer[3].cascade = (*((unsigned short *)&Mem.io_regs[((0x0400010E))-(0x04000000)]))&(1<<(2));
    Timer[3].irqenable = (*((unsigned short *)&Mem.io_regs[((0x0400010E))-(0x04000000)]))&(1<<(6));
    Timer[3].enabled = (*((unsigned short *)&Mem.io_regs[((0x0400010E))-(0x04000000)]))&(1<<(7));
    Timer[3].clockspertick = gba_timerclockspertic[(*((unsigned short *)&Mem.io_regs[((0x0400010E))-(0x04000000)]))&3];
    if(Timer[3].enabled)
    {
        (*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) = Timer[3].start;
        Timer[3].remainingclocks = Timer[3].clockspertick;
    }
}


decompiled_code:
__int64 __fastcall GBA_TimersUpdate(int a1)
{
__int64 result; // rax
__int64 v3; // rsi
__int64 v4; // r8
__int64 v5; // rdx
char v6; // cl
int v7; // er9
bool v8; // zf
__int64 v9; // r8
int v10; // eax
unsigned __int16 v11; // di
__int64 v12; // rsi
unsigned __int16 v13; // dx
char v14; // cl
int v15; // er13
int v16; // esi
int v17; // er8
char v18; // cl
__int16 v19; // r10
unsigned __int16 v20; // dx
int v21; // esi
int v22; // er8
char v23; // cl
__int16 v24; // r10
unsigned __int16 v25; // dx
int v26; // [rsp+Ch] [rbp-2Ch]
unsigned int v27; // [rsp+Ch] [rbp-2Ch]
unsigned int v28; // [rsp+Ch] [rbp-2Ch]
unsigned int v29; // [rsp+Ch] [rbp-2Ch]
int v30; // [rsp+Ch] [rbp-2Ch]
int v31; // [rsp+Ch] [rbp-2Ch]

if ( !*((_WORD *)&Timer + 8) )
{
if ( !*((_WORD *)&Timer + 18) || *((_WORD *)&Timer + 16) )
{
result = 0x7FFFFFFFLL;
if ( !*((_WORD *)&Timer + 28) || *((_WORD *)&Timer + 26) )
goto LABEL_50;
goto LABEL_37;
}
LODWORD(result) = 0x7FFFFFFF;
goto LABEL_5;
}
v9 = 0LL;
v10 = *((_DWORD *)&Timer + 1) - a1;
*((_DWORD *)&Timer + 1) = v10;
LABEL_21:
v11 = Mem[147588];
LABEL_22:
v12 = *((unsigned int *)&Timer + 2);
v13 = v11;
v14 = 0;
while ( v10 <= 0 )
{
v10 += v12;
v14 = 1;
if ( !++v13 )
{
*((_DWORD *)&Timer + 1) = v10;
Mem[147588] = 0;
GBA_SoundTimerCheck(0LL, v12, 0LL, 1LL, v9);
v11 = Timer;
v8 = *((_WORD *)&Timer + 7) == 0;
Mem[147588] = Timer;
if ( v8 )
{
v10 = *((_DWORD *)&Timer + 1);
v9 = 1LL;
goto LABEL_22;
}
GBA_CallInterrupt(8LL);
v10 = *((_DWORD *)&Timer + 1);
v9 = 1LL;
goto LABEL_21;
}
}
if ( v14 )
{
*((_DWORD *)&Timer + 1) = v10;
Mem[147588] = v13;
}
else
{
v13 = v11;
}
result = (0x10000 - (unsigned int)v13) * v10;
if ( !*((_WORD *)&Timer + 18) )
{
LABEL_49:
if ( !*((_WORD *)&Timer + 28) || *((_WORD *)&Timer + 26) )
goto LABEL_50;
goto LABEL_37;
}
if ( *((_WORD *)&Timer + 16) )
{
if ( (_DWORD)v9 )
{
v8 = Mem[147590]++ == 0xFFFF;
if ( v8 )
{
v8 = *((_WORD *)&Timer + 17) == 0;
Mem[147590] = *((_WORD *)&Timer + 10);
if ( v8 )
{
if ( !*((_WORD *)&Timer + 28) )
goto LABEL_50;
}
else
{
v28 = result;
GBA_CallInterrupt(16LL);
result = v28;
if ( !*((_WORD *)&Timer + 28) )
goto LABEL_50;
}
if ( *((_WORD *)&Timer + 26) )
{
LABEL_15:
v8 = Mem[147592]++ == 0xFFFF;
if ( v8 )
{
v8 = *((_WORD *)&Timer + 27) == 0;
Mem[147592] = *((_WORD *)&Timer + 20);
if ( v8 )
{
if ( !*((_WORD *)&Timer + 38) )
return result;
}
else
{
v27 = result;
GBA_CallInterrupt(32LL);
result = v27;
if ( !*((_WORD *)&Timer + 38) )
return result;
}
if ( *((_WORD *)&Timer + 36) )
goto LABEL_46;
}
else if ( !*((_WORD *)&Timer + 38) || *((_WORD *)&Timer + 36) )
{
return result;
}
goto LABEL_52;
}
goto LABEL_37;
}
}
goto LABEL_49;
}
LABEL_5:
LODWORD(v3) = *((_DWORD *)&Timer + 6) - a1;
*((_DWORD *)&Timer + 6) = v3;
LABEL_6:
v4 = (unsigned __int16)Mem[147590];
LABEL_7:
v5 = (unsigned int)v4;
v6 = 0;
while ( (int)v3 <= 0 )
{
v3 = (unsigned int)(*((_DWORD *)&Timer + 7) + v3);
v6 = 1;
LOWORD(v5) = v5 + 1;
if ( !(_WORD)v5 )
{
v26 = result;
Mem[147590] = 0;
*((_DWORD *)&Timer + 6) = v3;
GBA_SoundTimerCheck(1LL, v3, v5, 1LL, v4);
v4 = *((unsigned __int16 *)&Timer + 10);
v8 = *((_WORD *)&Timer + 17) == 0;
LODWORD(result) = v26;
Mem[147590] = v4;
if ( v8 )
{
LODWORD(v3) = *((_DWORD *)&Timer + 6);
goto LABEL_7;
}
GBA_CallInterrupt(16LL);
LODWORD(v3) = *((_DWORD *)&Timer + 6);
LODWORD(result) = v26;
goto LABEL_6;
}
}
if ( v6 )
{
*((_DWORD *)&Timer + 6) = v3;
LODWORD(v4) = (unsigned __int16)v5;
Mem[147590] = v5;
}
result = min(result, (0x10000 - (int)v4) * (int)v3);
if ( !*((_WORD *)&Timer + 28) )
goto LABEL_50;
if ( *((_WORD *)&Timer + 26) )
{
if ( v7 )
goto LABEL_15;
LABEL_50:
if ( !*((_WORD *)&Timer + 38) || *((_WORD *)&Timer + 36) )
return result;
LABEL_52:
v21 = *((_DWORD *)&Timer + 16) - a1;
*((_DWORD *)&Timer + 16) = v21;
LABEL_53:
v22 = (unsigned __int16)Mem[147594];
v23 = 0;
v24 = *((_WORD *)&Timer + 30);
v25 = Mem[147594];
while ( v21 <= 0 )
{
v21 += *((_DWORD *)&Timer + 17);
v23 = 1;
if ( !++v25 )
{
if ( *((_WORD *)&Timer + 37) )
{
*((_DWORD *)&Timer + 16) = v21;
Mem[147594] = v24;
v31 = result;
GBA_CallInterrupt(64LL);
v21 = *((_DWORD *)&Timer + 16);
LODWORD(result) = v31;
goto LABEL_53;
}
v25 = *((_WORD *)&Timer + 30);
}
}
if ( v23 )
{
*((_DWORD *)&Timer + 16) = v21;
v22 = v25;
Mem[147594] = v25;
}
return min(result, (0x10000 - v22) * v21);
}
LABEL_37:
v15 = 0;
v16 = *((_DWORD *)&Timer + 11) - a1;
*((_DWORD *)&Timer + 11) = v16;
LABEL_38:
v17 = (unsigned __int16)Mem[147592];
v18 = 0;
v19 = *((_WORD *)&Timer + 20);
v20 = Mem[147592];
while ( v16 <= 0 )
{
v16 += *((_DWORD *)&Timer + 12);
v18 = 1;
if ( !++v20 )
{
v15 = 1;
if ( *((_WORD *)&Timer + 27) )
{
*((_DWORD *)&Timer + 11) = v16;
Mem[147592] = v19;
v30 = result;
GBA_CallInterrupt(32LL);
v16 = *((_DWORD *)&Timer + 11);
LODWORD(result) = v30;
goto LABEL_38;
}
v20 = *((_WORD *)&Timer + 20);
}
}
if ( v18 )
{
*((_DWORD *)&Timer + 11) = v16;
v17 = v20;
Mem[147592] = v20;
}
result = min(result, (0x10000 - v17) * v16);
if ( *((_WORD *)&Timer + 38) )
{
if ( *((_WORD *)&Timer + 36) )
{
if ( !v15 )
return result;
LABEL_46:
v8 = Mem[147594]++ == 0xFFFF;
if ( v8 )
{
v8 = *((_WORD *)&Timer + 37) == 0;
Mem[147594] = *((_WORD *)&Timer + 30);
if ( !v8 )
{
v29 = result;
GBA_CallInterrupt(64LL);
result = v29;
}
}
return result;
}
goto LABEL_52;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1)
{
__int64 result; // rax
__int64 v3; // rsi
__int64 v4; // r8
__int64 v5; // rdx
char v6; // cl
int v7; // er9
bool v8; // zf
__int64 v9; // r8
int v10; // eax
unsigned __int16 v11; // di
__int64 v12; // rsi
unsigned __int16 v13; // dx
char v14; // cl
int v15; // er13
int v16; // esi
int v17; // er8
char v18; // cl
__int16 v19; // r10
unsigned __int16 v20; // dx
int v21; // esi
int v22; // er8
char v23; // cl
__int16 v24; // r10
unsigned __int16 v25; // dx
int v26; // [rsp+Ch] [rbp-2Ch]
unsigned int v27; // [rsp+Ch] [rbp-2Ch]
unsigned int v28; // [rsp+Ch] [rbp-2Ch]
unsigned int v29; // [rsp+Ch] [rbp-2Ch]
int v30; // [rsp+Ch] [rbp-2Ch]
int v31; // [rsp+Ch] [rbp-2Ch]

if ( !*((_WORD *)&Timer + 8) )
{
if ( !*((_WORD *)&Timer + 18) || *((_WORD *)&Timer + 16) )
{
result = 0x7FFFFFFFLL;
if ( !*((_WORD *)&Timer + 28) || *((_WORD *)&Timer + 26) )
goto LABEL_50;
goto LABEL_37;
}
LODWORD(result) = 0x7FFFFFFF;
goto LABEL_5;
}
v9 = 0LL;
v10 = *((_DWORD *)&Timer + 1) - a1;
*((_DWORD *)&Timer + 1) = v10;
LABEL_21:
v11 = Mem[147588];
LABEL_22:
v12 = *((unsigned int *)&Timer + 2);
v13 = v11;
v14 = 0;
while ( v10 <= 0 )
{
v10 += v12;
v14 = 1;
if ( !++v13 )
{
*((_DWORD *)&Timer + 1) = v10;
Mem[147588] = 0;
GBA_SoundTimerCheck(0LL, v12, 0LL, 1LL, v9);
v11 = Timer;
v8 = *((_WORD *)&Timer + 7) == 0;
Mem[147588] = Timer;
if ( v8 )
{
v10 = *((_DWORD *)&Timer + 1);
v9 = 1LL;
goto LABEL_22;
}
GBA_CallInterrupt(8LL);
v10 = *((_DWORD *)&Timer + 1);
v9 = 1LL;
goto LABEL_21;
}
}
if ( v14 )
{
*((_DWORD *)&Timer + 1) = v10;
Mem[147588] = v13;
}
else
{
v13 = v11;
}
result = (0x10000 - (unsigned int)v13) * v10;
if ( !*((_WORD *)&Timer + 18) )
{
LABEL_49:
if ( !*((_WORD *)&Timer + 28) || *((_WORD *)&Timer + 26) )
goto LABEL_50;
goto LABEL_37;
}
if ( *((_WORD *)&Timer + 16) )
{
if ( (_DWORD)v9 )
{
v8 = Mem[147590]++ == 0xFFFF;
if ( v8 )
{
v8 = *((_WORD *)&Timer + 17) == 0;
Mem[147590] = *((_WORD *)&Timer + 10);
if ( v8 )
{
if ( !*((_WORD *)&Timer + 28) )
goto LABEL_50;
}
else
{
v28 = result;
GBA_CallInterrupt(16LL);
result = v28;
if ( !*((_WORD *)&Timer + 28) )
goto LABEL_50;
}
if ( *((_WORD *)&Timer + 26) )
{
LABEL_15:
v8 = Mem[147592]++ == 0xFFFF;
if ( v8 )
{
v8 = *((_WORD *)&Timer + 27) == 0;
Mem[147592] = *((_WORD *)&Timer + 20);
if ( v8 )
{
if ( !*((_WORD *)&Timer + 38) )
return result;
}
else
{
v27 = result;
GBA_CallInterrupt(32LL);
result = v27;
if ( !*((_WORD *)&Timer + 38) )
return result;
}
if ( *((_WORD *)&Timer + 36) )
goto LABEL_46;
}
else if ( !*((_WORD *)&Timer + 38) || *((_WORD *)&Timer + 36) )
{
return result;
}
goto LABEL_52;
}
goto LABEL_37;
}
}
goto LABEL_49;
}
LABEL_5:
LODWORD(v3) = *((_DWORD *)&Timer + 6) - a1;
*((_DWORD *)&Timer + 6) = v3;
LABEL_6:
v4 = (unsigned __int16)Mem[147590];
LABEL_7:
v5 = (unsigned int)v4;
v6 = 0;
while ( (int)v3 <= 0 )
{
v3 = (unsigned int)(*((_DWORD *)&Timer + 7) + v3);
v6 = 1;
LOWORD(v5) = v5 + 1;
if ( !(_WORD)v5 )
{
v26 = result;
Mem[147590] = 0;
*((_DWORD *)&Timer + 6) = v3;
GBA_SoundTimerCheck(1LL, v3, v5, 1LL, v4);
v4 = *((unsigned __int16 *)&Timer + 10);
v8 = *((_WORD *)&Timer + 17) == 0;
LODWORD(result) = v26;
Mem[147590] = v4;
if ( v8 )
{
LODWORD(v3) = *((_DWORD *)&Timer + 6);
goto LABEL_7;
}
GBA_CallInterrupt(16LL);
LODWORD(v3) = *((_DWORD *)&Timer + 6);
LODWORD(result) = v26;
goto LABEL_6;
}
}
if ( v6 )
{
*((_DWORD *)&Timer + 6) = v3;
LODWORD(v4) = (unsigned __int16)v5;
Mem[147590] = v5;
}
result = func0(result, (0x10000 - (int)v4) * (int)v3);
if ( !*((_WORD *)&Timer + 28) )
goto LABEL_50;
if ( *((_WORD *)&Timer + 26) )
{
if ( v7 )
goto LABEL_15;
LABEL_50:
if ( !*((_WORD *)&Timer + 38) || *((_WORD *)&Timer + 36) )
return result;
LABEL_52:
v21 = *((_DWORD *)&Timer + 16) - a1;
*((_DWORD *)&Timer + 16) = v21;
LABEL_53:
v22 = (unsigned __int16)Mem[147594];
v23 = 0;
v24 = *((_WORD *)&Timer + 30);
v25 = Mem[147594];
while ( v21 <= 0 )
{
v21 += *((_DWORD *)&Timer + 17);
v23 = 1;
if ( !++v25 )
{
if ( *((_WORD *)&Timer + 37) )
{
*((_DWORD *)&Timer + 16) = v21;
Mem[147594] = v24;
v31 = result;
GBA_CallInterrupt(64LL);
v21 = *((_DWORD *)&Timer + 16);
LODWORD(result) = v31;
goto LABEL_53;
}
v25 = *((_WORD *)&Timer + 30);
}
}
if ( v23 )
{
*((_DWORD *)&Timer + 16) = v21;
v22 = v25;
Mem[147594] = v25;
}
return func0(result, (0x10000 - v22) * v21);
}
LABEL_37:
v15 = 0;
v16 = *((_DWORD *)&Timer + 11) - a1;
*((_DWORD *)&Timer + 11) = v16;
LABEL_38:
v17 = (unsigned __int16)Mem[147592];
v18 = 0;
v19 = *((_WORD *)&Timer + 20);
v20 = Mem[147592];
while ( v16 <= 0 )
{
v16 += *((_DWORD *)&Timer + 12);
v18 = 1;
if ( !++v20 )
{
v15 = 1;
if ( *((_WORD *)&Timer + 27) )
{
*((_DWORD *)&Timer + 11) = v16;
Mem[147592] = v19;
v30 = result;
GBA_CallInterrupt(32LL);
v16 = *((_DWORD *)&Timer + 11);
LODWORD(result) = v30;
goto LABEL_38;
}
v20 = *((_WORD *)&Timer + 20);
}
}
if ( v18 )
{
*((_DWORD *)&Timer + 11) = v16;
v17 = v20;
Mem[147592] = v20;
}
result = func0(result, (0x10000 - v17) * v16);
if ( *((_WORD *)&Timer + 38) )
{
if ( *((_WORD *)&Timer + 36) )
{
if ( !v15 )
return result;
LABEL_46:
v8 = Mem[147594]++ == 0xFFFF;
if ( v8 )
{
v8 = *((_WORD *)&Timer + 37) == 0;
Mem[147594] = *((_WORD *)&Timer + 30);
if ( !v8 )
{
v29 = result;
GBA_CallInterrupt(64LL);
result = v29;
}
}
return result;
}
goto LABEL_52;
}
return result;
}

original_code:
s32 GBA_TimersUpdate(s32 clocks)
{
    int timer0overflowed = 0;
    int timer1overflowed = 0;
    int timer2overflowed = 0;
    s32 returnclocks = 0x7FFFFFFF;
    if(Timer[0].enabled)
    {
        {
            Timer[0].remainingclocks -= clocks;
            while(Timer[0].remainingclocks <= 0)
            {
                Timer[0].remainingclocks += Timer[0].clockspertick;
                (*((u16*)&Mem.io_regs[((0x04000100))-(0x04000000)])) ++;
                if((*((u16*)&Mem.io_regs[((0x04000100))-(0x04000000)])) == 0)
                {
                    GBA_SoundTimerCheck(0);
                    (*((u16*)&Mem.io_regs[((0x04000100))-(0x04000000)])) = Timer[0].start;
                    if(Timer[0].irqenable) GBA_CallInterrupt((1<<(3)));
                    timer0overflowed = 1;
                }
            }
            returnclocks = Timer[0].remainingclocks * (0x10000-(u32)(*((u16*)&Mem.io_regs[((0x04000100))-(0x04000000)])));
        }
    }
    if(Timer[1].enabled)
    {
        if(Timer[1].cascade == 0)
        {
            Timer[1].remainingclocks -= clocks;
            while(Timer[1].remainingclocks <= 0)
            {
                Timer[1].remainingclocks += Timer[1].clockspertick;
                (*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)])) ++;
                if((*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)])) == 0)
                {
                    GBA_SoundTimerCheck(1);
                    (*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)])) = Timer[1].start;
                    if(Timer[1].irqenable) GBA_CallInterrupt((1<<(4)));
                    timer1overflowed = 1;
                }
            }
            returnclocks = min(returnclocks,Timer[1].remainingclocks * (0x10000-(u32)(*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)]))));
        }
        else if(timer0overflowed)
        {
            (*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)])) ++;
            if((*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)])) == 0)
            {
                (*((u16*)&Mem.io_regs[((0x04000104))-(0x04000000)])) = Timer[1].start;
                if(Timer[1].irqenable) GBA_CallInterrupt((1<<(4)));
                timer1overflowed = 1;
            }
        }
    }
    if(Timer[2].enabled)
    {
        if(Timer[2].cascade == 0)
        {
            Timer[2].remainingclocks -= clocks;
            while(Timer[2].remainingclocks <= 0)
            {
                Timer[2].remainingclocks += Timer[2].clockspertick;
                (*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)])) ++;
                if((*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)])) == 0)
                {
                    (*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)])) = Timer[2].start;
                    if(Timer[2].irqenable) GBA_CallInterrupt((1<<(5)));
                    timer2overflowed = 1;
                }
            }
            returnclocks = min(returnclocks,Timer[2].remainingclocks * (0x10000-(u32)(*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)]))));
        }
        else if(timer1overflowed)
        {
            (*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)])) ++;
            if((*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)])) == 0)
            {
                (*((u16*)&Mem.io_regs[((0x04000108))-(0x04000000)])) = Timer[2].start;
                if(Timer[2].irqenable) GBA_CallInterrupt((1<<(5)));
                timer2overflowed = 1;
            }
        }
    }
    if(Timer[3].enabled)
    {
        if(Timer[3].cascade == 0)
        {
            Timer[3].remainingclocks -= clocks;
            while(Timer[3].remainingclocks <= 0)
            {
                Timer[3].remainingclocks += Timer[3].clockspertick;
                (*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)])) ++;
                if((*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)])) == 0)
                {
                    (*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)])) = Timer[3].start;
                    if(Timer[3].irqenable) GBA_CallInterrupt((1<<(6)));
                }
            }
            returnclocks = min(returnclocks,Timer[3].remainingclocks * (0x10000-(u32)(*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)]))));
        }
        else if(timer2overflowed)
        {
            (*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)])) ++;
            if((*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)])) == 0)
            {
                (*((u16*)&Mem.io_regs[((0x0400010C))-(0x04000000)])) = Timer[3].start;
                if(Timer[3].irqenable) GBA_CallInterrupt((1<<(6)));
            }
        }
    }
    return returnclocks;
}

canonical_original_code:
int GBA_TimersUpdate(int clocks)
{
    int timer0overflowed = 0;
    int timer1overflowed = 0;
    int timer2overflowed = 0;
    int returnclocks = 0x7FFFFFFF;
    if(Timer[0].enabled)
    {
        {
            Timer[0].remainingclocks -= clocks;
            while(Timer[0].remainingclocks <= 0)
            {
                Timer[0].remainingclocks += Timer[0].clockspertick;
                (*((unsigned short *)&Mem.io_regs[((0x04000100))-(0x04000000)])) ++;
                if((*((unsigned short *)&Mem.io_regs[((0x04000100))-(0x04000000)])) == 0)
                {
                    GBA_SoundTimerCheck(0);
                    (*((unsigned short *)&Mem.io_regs[((0x04000100))-(0x04000000)])) = Timer[0].start;
                    if(Timer[0].irqenable) GBA_CallInterrupt((1<<(3)));
                    timer0overflowed = 1;
                }
            }
            returnclocks = Timer[0].remainingclocks * (0x10000-(u32)(*((unsigned short *)&Mem.io_regs[((0x04000100))-(0x04000000)])));
        }
    }
    if(Timer[1].enabled)
    {
        if(Timer[1].cascade == 0)
        {
            Timer[1].remainingclocks -= clocks;
            while(Timer[1].remainingclocks <= 0)
            {
                Timer[1].remainingclocks += Timer[1].clockspertick;
                (*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)])) ++;
                if((*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)])) == 0)
                {
                    GBA_SoundTimerCheck(1);
                    (*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)])) = Timer[1].start;
                    if(Timer[1].irqenable) GBA_CallInterrupt((1<<(4)));
                    timer1overflowed = 1;
                }
            }
            returnclocks = min(returnclocks,Timer[1].remainingclocks * (0x10000-(u32)(*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)]))));
        }
        else if(timer0overflowed)
        {
            (*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)])) ++;
            if((*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)])) == 0)
            {
                (*((unsigned short *)&Mem.io_regs[((0x04000104))-(0x04000000)])) = Timer[1].start;
                if(Timer[1].irqenable) GBA_CallInterrupt((1<<(4)));
                timer1overflowed = 1;
            }
        }
    }
    if(Timer[2].enabled)
    {
        if(Timer[2].cascade == 0)
        {
            Timer[2].remainingclocks -= clocks;
            while(Timer[2].remainingclocks <= 0)
            {
                Timer[2].remainingclocks += Timer[2].clockspertick;
                (*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) ++;
                if((*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) == 0)
                {
                    (*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) = Timer[2].start;
                    if(Timer[2].irqenable) GBA_CallInterrupt((1<<(5)));
                    timer2overflowed = 1;
                }
            }
            returnclocks = min(returnclocks,Timer[2].remainingclocks * (0x10000-(u32)(*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)]))));
        }
        else if(timer1overflowed)
        {
            (*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) ++;
            if((*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) == 0)
            {
                (*((unsigned short *)&Mem.io_regs[((0x04000108))-(0x04000000)])) = Timer[2].start;
                if(Timer[2].irqenable) GBA_CallInterrupt((1<<(5)));
                timer2overflowed = 1;
            }
        }
    }
    if(Timer[3].enabled)
    {
        if(Timer[3].cascade == 0)
        {
            Timer[3].remainingclocks -= clocks;
            while(Timer[3].remainingclocks <= 0)
            {
                Timer[3].remainingclocks += Timer[3].clockspertick;
                (*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) ++;
                if((*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) == 0)
                {
                    (*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) = Timer[3].start;
                    if(Timer[3].irqenable) GBA_CallInterrupt((1<<(6)));
                }
            }
            returnclocks = min(returnclocks,Timer[3].remainingclocks * (0x10000-(u32)(*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)]))));
        }
        else if(timer2overflowed)
        {
            (*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) ++;
            if((*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) == 0)
            {
                (*((unsigned short *)&Mem.io_regs[((0x0400010C))-(0x04000000)])) = Timer[3].start;
                if(Timer[3].irqenable) GBA_CallInterrupt((1<<(6)));
            }
        }
    }
    return returnclocks;
}

variable_types: clocks int

variable_types: returnclocks int

return_type: int


min

decompiled_code:
__int64 __fastcall min(unsigned int a1, unsigned int a2)
{
__int64 result; // rax

result = a1;
if ( (int)a2 <= (int)a1 )
result = a2;
return result;
}

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

result = a1;
if ( (int)a2 <= (int)a1 )
result = a2;
return result;
}

original_code: static inline s32 min(s32 a, s32 b) { return ((a < b) ? a : b); }

canonical_original_code: static inline int min(int a, int b) { return ((a < b) ? a : b); }

variable_types: a int

variable_types: b int


decompiled_code:
__int64 __fastcall GBA_UpdateScreenTimings(int a1)
{
__int64 result; // rax
unsigned int v2; // eax
int v3; // edx
__int16 v4; // cx
__int16 v5; // dx
int v6; // ecx
__int16 v7; // dx

justchangedscreenmode = 0;
result = scrclocks - a1;
scrclocks -= a1;
if ( screenmode == 2 )
{
if ( (int)result <= 0 )
{
GBA_InterruptLCD(16LL);
screenmode = 3;
hblinterruptexecuted_0 = 0;
result = scrclocks + 272;
scrclocks += 272;
}
}
else if ( screenmode > 2u )
{
if ( screenmode != 3 )
return result;
if ( (int)result > 0 )
goto LABEL_5;
v2 = result + 960;
v3 = ly + 1;
v4 = *((_WORD *)&Mem + 147462);
ly = v3;
if ( v3 == 227 )
{
screenmode = 2;
v4 &= 0xFFFCu;
*((_WORD *)&Mem + 147463) = 227;
scrclocks = v2;
}
else
{
if ( v3 == 228 )
{
ly = 0;
v3 = 0;
*((_WORD *)&Mem + 147463) = 0;
screenmode = 0;
}
else
{
*((_WORD *)&Mem + 147463) = v3;
v4 &= 0xFFFDu;
screenmode = 2;
}
scrclocks = v2;
}
if ( HIBYTE(v4) == v3 )
{
*((_WORD *)&Mem + 147462) = v4 | 4;
GBA_InterruptLCD(32LL);
result = scrclocks;
}
else
{
result = scrclocks;
*((_WORD *)&Mem + 147462) = v4 & 0xFFFB;
}
}
else if ( screenmode )
{
if ( (int)result > 0 )
{
LABEL_5:
if ( (int)result <= 226 && !hblinterruptexecuted_0 )
{
hblinterruptexecuted_0 = 1;
*((_WORD *)&Mem + 147462) |= 2u;
}
return result;
}
v5 = *((_WORD *)&Mem + 147462);
v6 = ly + 1;
ly = v6;
*((_WORD *)&Mem + 147463) = v6;
if ( v6 == 160 )
{
*((_WORD *)&Mem + 147462) = v5 | 1;
GBA_InterruptLCD(8LL);
scrclocks += 960;
v7 = *((_WORD *)&Mem + 147462);
screenmode = 2;
v6 = ly;
}
else
{
screenmode = 0;
v7 = v5 & 0xFFFD;
scrclocks = result + 960;
}
if ( HIBYTE(v7) == v6 )
{
*((_WORD *)&Mem + 147462) = v7 | 4;
GBA_InterruptLCD(32LL);
}
else
{
*((_WORD *)&Mem + 147462) = v7 & 0xFFFB;
}
justchangedscreenmode = 1;
result = scrclocks;
}
else if ( (int)result <= 0 )
{
if ( *((char *)&Mem + 294920) < 0 )
GBA_DrawScanlineWhite(ly);
else
GBA_DrawScanline(ly);
GBA_InterruptLCD(16LL);
screenmode = 1;
justchangedscreenmode = 1;
hblinterruptexecuted_0 = 0;
result = scrclocks + 272;
scrclocks += 272;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1)
{
__int64 result; // rax
unsigned int v2; // eax
int v3; // edx
__int16 v4; // cx
__int16 v5; // dx
int v6; // ecx
__int16 v7; // dx

justchangedscreenmode = 0;
result = scrclocks - a1;
scrclocks -= a1;
if ( screenmode == 2 )
{
if ( (int)result <= 0 )
{
GBA_InterruptLCD(16LL);
screenmode = 3;
hblinterruptexecuted_0 = 0;
result = scrclocks + 272;
scrclocks += 272;
}
}
else if ( screenmode > 2u )
{
if ( screenmode != 3 )
return result;
if ( (int)result > 0 )
goto LABEL_5;
v2 = result + 960;
v3 = ly + 1;
v4 = *((_WORD *)&Mem + 147462);
ly = v3;
if ( v3 == 227 )
{
screenmode = 2;
v4 &= 0xFFFCu;
*((_WORD *)&Mem + 147463) = 227;
scrclocks = v2;
}
else
{
if ( v3 == 228 )
{
ly = 0;
v3 = 0;
*((_WORD *)&Mem + 147463) = 0;
screenmode = 0;
}
else
{
*((_WORD *)&Mem + 147463) = v3;
v4 &= 0xFFFDu;
screenmode = 2;
}
scrclocks = v2;
}
if ( HIBYTE(v4) == v3 )
{
*((_WORD *)&Mem + 147462) = v4 | 4;
GBA_InterruptLCD(32LL);
result = scrclocks;
}
else
{
result = scrclocks;
*((_WORD *)&Mem + 147462) = v4 & 0xFFFB;
}
}
else if ( screenmode )
{
if ( (int)result > 0 )
{
LABEL_5:
if ( (int)result <= 226 && !hblinterruptexecuted_0 )
{
hblinterruptexecuted_0 = 1;
*((_WORD *)&Mem + 147462) |= 2u;
}
return result;
}
v5 = *((_WORD *)&Mem + 147462);
v6 = ly + 1;
ly = v6;
*((_WORD *)&Mem + 147463) = v6;
if ( v6 == 160 )
{
*((_WORD *)&Mem + 147462) = v5 | 1;
GBA_InterruptLCD(8LL);
scrclocks += 960;
v7 = *((_WORD *)&Mem + 147462);
screenmode = 2;
v6 = ly;
}
else
{
screenmode = 0;
v7 = v5 & 0xFFFD;
scrclocks = result + 960;
}
if ( HIBYTE(v7) == v6 )
{
*((_WORD *)&Mem + 147462) = v7 | 4;
GBA_InterruptLCD(32LL);
}
else
{
*((_WORD *)&Mem + 147462) = v7 & 0xFFFB;
}
justchangedscreenmode = 1;
result = scrclocks;
}
else if ( (int)result <= 0 )
{
if ( *((char *)&Mem + 294920) < 0 )
GBA_DrawScanlineWhite(ly);
else
GBA_DrawScanline(ly);
GBA_InterruptLCD(16LL);
screenmode = 1;
justchangedscreenmode = 1;
hblinterruptexecuted_0 = 0;
result = scrclocks + 272;
scrclocks += 272;
}
return result;
}

canonical_original_code:
int GBA_UpdateScreenTimings(int clocks)
{
    static int hblinterruptexecuted = 0;
    scrclocks -= clocks;
    justchangedscreenmode = 0;
    switch(screenmode)
    {
        case (0):
        {
            if(scrclocks <= 0)
            {
                if((*((unsigned short *)&Mem.io_regs[((0x04000000))-(0x04000000)]))&(1<<(7))) GBA_DrawScanlineWhite(ly);
                else GBA_DrawScanline(ly);
                GBA_InterruptLCD((1<<(4)));
                screenmode = (1);
                scrclocks = (272)+scrclocks;
                justchangedscreenmode = 1;
                hblinterruptexecuted = 0;
            }
            break;
        }
        case (1):
        {
            if(scrclocks <= 0)
            {
                ly++;
                (*((unsigned short *)&Mem.io_regs[((0x04000006))-(0x04000000)])) = ly;
                if(ly == 160)
                {
                    (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) |= (1<<(0));
                    GBA_InterruptLCD((1<<(3)));
                    screenmode = (2);
                    scrclocks = (960)+scrclocks;
                }
                else
                {
                    (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) &= ~(1<<(1));
                    screenmode = (0);
                    scrclocks = (960)+scrclocks;
                }
                if(((*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)]))>>8) == ly) { (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) |= (1<<(2)); GBA_InterruptLCD((1<<(5))); }
                else (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) &= ~(1<<(2));
                justchangedscreenmode = 1;
            }
            else if( (scrclocks <= ((272)-(1006-(960)))) && (hblinterruptexecuted == 0) )
            {
                (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) |= (1<<(1));
                hblinterruptexecuted = 1;
            }
            break;
        }
        case (2):
        {
            if(scrclocks <= 0)
            {
                GBA_InterruptLCD((1<<(4)));
                screenmode = (3);
                scrclocks = (272)+scrclocks;
                hblinterruptexecuted = 0;
            }
            break;
        }
        case (3):
        {
            if(scrclocks <= 0)
            {
                ly++;
                if(ly == 227)
                {
                    (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) &= ~((1<<(0))|(1<<(1)));
                    (*((unsigned short *)&Mem.io_regs[((0x04000006))-(0x04000000)])) = ly;
                    screenmode = (2);
                    scrclocks = (960)+scrclocks;
                }
                else if(ly == 228)
                {
                    ly = 0;
                    (*((unsigned short *)&Mem.io_regs[((0x04000006))-(0x04000000)])) = 0;
                    screenmode = (0);
                    scrclocks = (960)+scrclocks;
                }
                else
                {
                    (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) &= ~(1<<(1));
                    (*((unsigned short *)&Mem.io_regs[((0x04000006))-(0x04000000)])) = ly;
                    screenmode = (2);
                    scrclocks = (960)+scrclocks;
                }
                if(((*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)]))>>8) == ly) { (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) |= (1<<(2)); GBA_InterruptLCD((1<<(5))); }
                else (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) &= ~(1<<(2));
            }
            else if( (scrclocks <= ((272)-(1006-(960)))) && (hblinterruptexecuted == 0) )
            {
                (*((unsigned short *)&Mem.io_regs[((0x04000004))-(0x04000000)])) |= (1<<(1));
                hblinterruptexecuted = 1;
            }
            break;
        }
        default:
            break;
    }
    return scrclocks;
}

variable_types: hblinterruptexecuted int


decompiled_code:
_DWORD *GBA_InterruptInit()
{
_DWORD *result; // rax

scrclocks = 960;
screenmode = 0;
ly = 0;
result = &justchangedscreenmode;
justchangedscreenmode = 0;
return result;
}

canonical_decompiled_code:
_DWORD *func1()
{
_DWORD *result; // rax

scrclocks = 960;
screenmode = 0;
ly = 0;
result = &justchangedscreenmode;
justchangedscreenmode = 0;
return result;
}

original_code:
void GBA_InterruptInit(void)
{
    scrclocks = (960);
    screenmode = (0);
    ly = 0;
    justchangedscreenmode = 0;
}

canonical_original_code:
void GBA_InterruptInit()
{
    scrclocks = (960);
    screenmode = (0);
    ly = 0;
    justchangedscreenmode = 0;
}


canonical_original_code:
void GBA_HeaderCheck(void *rom)
{
    int showconsole = 0;
    struct _gba_header_ *header = (_gba_header_*)rom;
    ConsoleReset();
 printf("Checking cartridge...\n");
    char text[13];
    memcpy(text,header->game_title,12);
    text[12] = '\0';
 printf("Game title: %s\n",text);
 memcpy(text,header->game_code,4);
 text[4] = '\0';
 printf("Game code: %s\n",text);
 memcpy(text,header->maker_code,2);
 text[2] = '\0';
 printf("Maker code: %s\n",text);
    unsigned char nintendo_logo[156] = {
        0x24,0xFF,0xAE,0x51,0x69,0x9A,0xA2,0x21,0x3D,0x84,0x82,0x0A,0x84,0xE4,0x09,0xAD,
        0x11,0x24,0x8B,0x98,0xC0,0x81,0x7F,0x21,0xA3,0x52,0xBE,0x19,0x93,0x09,0xCE,0x20,
        0x10,0x46,0x4A,0x4A,0xF8,0x27,0x31,0xEC,0x58,0xC7,0xE8,0x33,0x82,0xE3,0xCE,0xBF,
        0x85,0xF4,0xDF,0x94,0xCE,0x4B,0x09,0xC1,0x94,0x56,0x8A,0xC0,0x13,0x72,0xA7,0xFC,
        0x9F,0x84,0x4D,0x73,0xA3,0xCA,0x9A,0x61,0x58,0x97,0xA3,0x27,0xFC,0x03,0x98,0x76,
        0x23,0x1D,0xC7,0x61,0x03,0x04,0xAE,0x56,0xBF,0x38,0x84,0x00,0x40,0xA7,0x0E,0xFD,
        0xFF,0x52,0xFE,0x03,0x6F,0x95,0x30,0xF1,0x97,0xFB,0xC0,0x85,0x60,0xD6,0x80,0x25,
        0xA9,0x63,0xBE,0x03,0x01,0x4E,0x38,0xE2,0xF9,0xA2,0x34,0xFF,0xBB,0x3E,0x03,0x44,
        0x78,0x00,0x90,0xCB,0x88,0x11,0x3A,0x94,0x65,0xC0,0x7C,0x63,0x87,0xF0,0x3C,0xAF,
        0xD6,0x25,0xE4,0x8B,0x38,0x0A,0xAC,0x72,0x21,0xD4,0xF8,0x07
    };
    int logo_bad = 0;
    int i = 0;
    for(i = 0; i < 156; i++) logo_bad |= (nintendo_logo[i] != header->nintendo_logo[i]);
    printf("Nintendo Logo... %s\n",(logo_bad==0) ? "OK" : "BAD [!]");
    if(logo_bad) if(EmulatorConfig.debug_msg_enable) showconsole = 1;
    unsigned char debugging_enable = header->nintendo_logo[0x9C-0x04];
    if( ( (debugging_enable & ((1<<(2))|(1<<(7)))) == (1<<(2)) ) || ( (debugging_enable & ((1<<(2))|(1<<(7)))) == (1<<(9)) ) )
    {
        if(EmulatorConfig.debug_msg_enable) showconsole = 1;
        printf("[!]Header byte 0x9C = %02X -> Debug (?)\n",debugging_enable);
    }
    else if( (debugging_enable & ((1<<(2))|(1<<(7)))) == ((1<<(2))|(1<<(7))) )
    {
        if(EmulatorConfig.debug_msg_enable) showconsole = 1;
        printf("[!]Header byte 0x9C = %02X -> Debugging enabled!\n",debugging_enable);
    }
    unsigned char cartridge_key_number_LSBs = header->nintendo_logo[0x9E - 0x04];
    if(cartridge_key_number_LSBs & ((1<<(0))|(1<<(1))))
    {
        if(EmulatorConfig.debug_msg_enable) showconsole = 1;
        printf("[!]Header byte 0x9E = %02X -> Key number (?)\n",cartridge_key_number_LSBs);
    }
 printf("Fixed 96h... %s\n",header->fixed_96h == 0x96 ? "OK" : "BAD [!]");
    if(header->fixed_96h != 0x96) if(EmulatorConfig.debug_msg_enable) showconsole = 1;
    printf("Main unit code: %02X\n",header->main_unit_code);
    printf("Device type: %02X\n",header->device_type);
    printf("Software version: %02X\n",header->software_version);
    unsigned char check = 0;
    for(i = 0xA0; i <= 0xBC; i++) check -= (((unsigned char *)rom)[i]);
    check -= 0x19;
    printf("Complement check: %02X -- Obtained: %02X -- %s\n",header->complement_check,check,
        header->complement_check == check ? "OK" : "BAD [!]");
    if(header->complement_check != check) if(EmulatorConfig.debug_msg_enable) showconsole = 1;
    printf("Save type: %s", GBA_GetSaveTypeString());
    if(showconsole) ConsoleShow();
}

variable_types:
rom
void *

variable_types: showconsole int

variable_types: struct _gba_header_ { unsigned int entry_point; unsigned char nintendo_logo[156]; char game_title[12]; char game_code[4]; char maker_code[2]; unsigned char fixed_96h; unsigned char main_unit_code; unsigned char device_type; unsigned char reserved_1[7]; unsigned char software_version; unsigned char complement_check; unsigned char reserved_2[2]; unsigned int ram_entry_point; unsigned char boot_mode; unsigned char slave_ID_number; unsigned char unused[26]; unsigned int joybus_entry_point; } *

variable_types:
text
char [13]

variable_types: i int

variable_types:
check
unsigned char


decompiled_code:
__int64 __fastcall tca6416a_read_gpio(__int64 a1, unsigned __int8 a2, unsigned __int8 a3)
{
__int64 result; // rax
unsigned __int8 v4; // bl
__int64 v5; // rdx
char v6[9]; // [rsp+Fh] [rbp-9h] BYREF

if ( (unsigned __int8)(a3 - 8) <= 7u )
{
v4 = a3 - 8;
v5 = 1LL;
}
else
{
result = 0xFFFFFFFFLL;
if ( a3 > 7u )
return result;
v4 = a3;
v5 = 0LL;
}
get_i2c_register(a1, a2, v5, v6);
return ((int)(unsigned __int8)v6[0] >> v4) & 1;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned __int8 a2, unsigned __int8 a3)
{
__int64 result; // rax
unsigned __int8 v4; // bl
__int64 v5; // rdx
char v6[9]; // [rsp+Fh] [rbp-9h] BYREF

if ( (unsigned __int8)(a3 - 8) <= 7u )
{
v4 = a3 - 8;
v5 = 1LL;
}
else
{
result = 0xFFFFFFFFLL;
if ( a3 > 7u )
return result;
v4 = a3;
v5 = 0LL;
}
get_i2c_register(a1, a2, v5, v6);
return ((int)(unsigned __int8)v6[0] >> v4) & 1;
}

original_code:
uint8_t tca6416a_read_gpio(int i2cdev, uint8_t ic_addr, uint8_t gpio)
 {
   unsigned char in_bank, out_bank, current_bank_state;
   if((gpio > 7) && (gpio <= 15))
    {
     gpio -= 8;
     in_bank = 0x1;
    }
   else if((gpio >= 0) && (gpio < 8))
    {
     in_bank = 0x0;
    }
   else
    return -1;
  get_i2c_register(i2cdev, ic_addr, in_bank, &current_bank_state);
  if(current_bank_state & (1 << gpio))
   return 1;
  else
   return 0;
 }

canonical_original_code:
unsigned char tca6416a_read_gpio(int i2cdev, unsigned char ic_addr, unsigned char gpio)
 {
   unsigned char in_bank; unsigned char out_bank; unsigned char current_bank_state;
   if((gpio > 7) && (gpio <= 15))
    {
     gpio -= 8;
     in_bank = 0x1;
    }
   else if((gpio >= 0) && (gpio < 8))
    {
     in_bank = 0x0;
    }
   else
    return -1;
  get_i2c_register(i2cdev, ic_addr, in_bank, &current_bank_state);
  if(current_bank_state & (1 << gpio))
   return 1;
  else
   return 0;
 }

variable_types:
gpio
unsigned char

return_type: unsigned char


decompiled_code:
__int64 __fastcall tca6416a_out_gpio(__int64 a1, unsigned __int8 a2, unsigned __int8 a3, char a4)
{
unsigned __int8 v5; // cl
__int64 result; // rax
unsigned int v7; // er9
unsigned __int8 *v8; // r10
unsigned __int8 v9; // dl
int v10; // eax
unsigned __int8 v11; // al

v5 = a3 - 8;
if ( (unsigned __int8)(a3 - 8) <= 7u )
{
v7 = 3;
v8 = (unsigned __int8 *)&input_regs_bank_1;
}
else
{
result = 0xFFFFFFFFLL;
if ( a3 > 7u )
return result;
v5 = a3;
v7 = 2;
v8 = (unsigned __int8 *)&input_regs_bank_0;
}
v9 = *v8;
v10 = 1 << v5;
if ( a4 == 1 )
v11 = v9 | v10;
else
v11 = v9 & ~(_BYTE)v10;
*v8 = v11;
set_i2c_register(a1, a2, v7, v11);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned __int8 a2, unsigned __int8 a3, char a4)
{
unsigned __int8 v5; // cl
__int64 result; // rax
unsigned int v7; // er9
unsigned __int8 *v8; // r10
unsigned __int8 v9; // dl
int v10; // eax
unsigned __int8 v11; // al

v5 = a3 - 8;
if ( (unsigned __int8)(a3 - 8) <= 7u )
{
v7 = 3;
v8 = (unsigned __int8 *)&input_regs_bank_1;
}
else
{
result = 0xFFFFFFFFLL;
if ( a3 > 7u )
return result;
v5 = a3;
v7 = 2;
v8 = (unsigned __int8 *)&input_regs_bank_0;
}
v9 = *v8;
v10 = 1 << v5;
if ( a4 == 1 )
v11 = v9 | v10;
else
v11 = v9 & ~(_BYTE)v10;
*v8 = v11;
set_i2c_register(a1, a2, v7, v11);
return 0LL;
}

original_code:
uint8_t tca6416a_out_gpio(int i2cdev, uint8_t ic_addr, uint8_t gpio, uint8_t state)
 {
   unsigned char in_bank, out_bank, *current_bank_state;
   if((gpio > 7) && (gpio <= 15))
    {
     gpio -= 8;
     out_bank = 0x3;
     current_bank_state = &input_regs_bank_1;
    }
   else if((gpio >= 0) && (gpio < 8))
    {
     out_bank = 0x2;
     current_bank_state = &input_regs_bank_0;
    }
   else
    return -1;
   if(state == 1)
    {
     *current_bank_state |= (1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
   else
    {
     *current_bank_state &= ~(1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
 return 0;
 }

canonical_original_code:
unsigned char tca6416a_out_gpio(int i2cdev, unsigned char ic_addr, unsigned char gpio, unsigned char state)
 {
   unsigned char in_bank; unsigned char out_bank; unsigned char *current_bank_state;
   if((gpio > 7) && (gpio <= 15))
    {
     gpio -= 8;
     out_bank = 0x3;
     current_bank_state = &input_regs_bank_1;
    }
   else if((gpio >= 0) && (gpio < 8))
    {
     out_bank = 0x2;
     current_bank_state = &input_regs_bank_0;
    }
   else
    return -1;
   if(state == 1)
    {
     *current_bank_state |= (1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
   else
    {
     *current_bank_state &= ~(1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
 return 0;
 }

variable_types:
state
unsigned char


decompiled_code:
__int64 __fastcall tca6416a_set_gpio(__int64 a1, unsigned __int8 a2, char a3, char a4)
{
char v5; // cl
unsigned int v6; // er12
unsigned __int8 *v7; // r8
__int64 v8; // rdx
unsigned __int8 v9; // cl
unsigned __int8 v11; // cl

v5 = a3 - 8;
if ( (unsigned __int8)(a3 - 8) <= 7u )
{
v7 = (unsigned __int8 *)&input_regs_bank_1;
v8 = 7LL;
if ( a4 == 1 )
goto LABEL_4;
}
else
{
v6 = -1;
if ( (unsigned __int8)a3 > 7u )
return v6;
v5 = a3;
v7 = (unsigned __int8 *)&input_regs_bank_0;
v8 = 6LL;
if ( a4 == 1 )
{
LABEL_4:
v6 = 0;
v9 = *v7 | (1 << v5);
*v7 = v9;
set_i2c_register(a1, a2, v8, v9);
return v6;
}
}
v6 = 0;
if ( a4 )
return v6;
v11 = *v7 & __ROL4__(-2, v5);
*v7 = v11;
set_i2c_register(a1, a2, v8, v11);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, unsigned __int8 a2, char a3, char a4)
{
char v5; // cl
unsigned int v6; // er12
unsigned __int8 *v7; // r8
__int64 v8; // rdx
unsigned __int8 v9; // cl
unsigned __int8 v11; // cl

v5 = a3 - 8;
if ( (unsigned __int8)(a3 - 8) <= 7u )
{
v7 = (unsigned __int8 *)&input_regs_bank_1;
v8 = 7LL;
if ( a4 == 1 )
goto LABEL_4;
}
else
{
v6 = -1;
if ( (unsigned __int8)a3 > 7u )
return v6;
v5 = a3;
v7 = (unsigned __int8 *)&input_regs_bank_0;
v8 = 6LL;
if ( a4 == 1 )
{
LABEL_4:
v6 = 0;
v9 = *v7 | (1 << v5);
*v7 = v9;
set_i2c_register(a1, a2, v8, v9);
return v6;
}
}
v6 = 0;
if ( a4 )
return v6;
v11 = *v7 & __ROL4__(-2, v5);
*v7 = v11;
set_i2c_register(a1, a2, v8, v11);
return 0LL;
}

original_code:
uint8_t tca6416a_set_gpio(int i2cdev, uint8_t ic_addr, uint8_t gpio, uint8_t mode)
 {
   unsigned char in_bank, out_bank, *current_bank_state;
   if((gpio > 7) && (gpio <= 15))
    {
     gpio -= 8;
     out_bank = 0x7;
     current_bank_state = &input_regs_bank_1;
    }
   else if((gpio >= 0) && (gpio < 8))
    {
     out_bank = 0x6;
     current_bank_state = &input_regs_bank_0;
    }
   else
    return -1;
   if(mode == 1)
    {
     *current_bank_state |= (1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
   else if(mode == 0)
    {
     *current_bank_state &= ~(1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
 return 0;
 }

canonical_original_code:
unsigned char tca6416a_set_gpio(int i2cdev, unsigned char ic_addr, unsigned char gpio, unsigned char mode)
 {
   unsigned char in_bank; unsigned char out_bank; unsigned char *current_bank_state;
   if((gpio > 7) && (gpio <= 15))
    {
     gpio -= 8;
     out_bank = 0x7;
     current_bank_state = &input_regs_bank_1;
    }
   else if((gpio >= 0) && (gpio < 8))
    {
     out_bank = 0x6;
     current_bank_state = &input_regs_bank_0;
    }
   else
    return -1;
   if(mode == 1)
    {
     *current_bank_state |= (1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
   else if(mode == 0)
    {
     *current_bank_state &= ~(1 << gpio);
     set_i2c_register(i2cdev, ic_addr, out_bank, *current_bank_state);
    }
 return 0;
 }

variable_types:
mode
unsigned char


decompiled_code:
__int64 __fastcall tca6416a_init(__int64 a1, unsigned __int8 a2)
{
get_i2c_register(a1, a2, 0LL, &output_regs_bank_0);
get_i2c_register((unsigned int)a1, a2, 1LL, &output_regs_bank_1);
get_i2c_register((unsigned int)a1, a2, 4LL, &polarity_regs_bank_0);
get_i2c_register((unsigned int)a1, a2, 5LL, &polarity_regs_bank_1);
get_i2c_register((unsigned int)a1, a2, 6LL, &config_regs_bank_0);
get_i2c_register((unsigned int)a1, a2, 7LL, &config_regs_bank_1);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, unsigned __int8 a2)
{
get_i2c_register(a1, a2, 0LL, &output_regs_bank_0);
get_i2c_register((unsigned int)a1, a2, 1LL, &output_regs_bank_1);
get_i2c_register((unsigned int)a1, a2, 4LL, &polarity_regs_bank_0);
get_i2c_register((unsigned int)a1, a2, 5LL, &polarity_regs_bank_1);
get_i2c_register((unsigned int)a1, a2, 6LL, &config_regs_bank_0);
get_i2c_register((unsigned int)a1, a2, 7LL, &config_regs_bank_1);
return 0LL;
}

original_code:
uint8_t tca6416a_init(int i2cdev, uint8_t ic_addr)
 {
   get_i2c_register(i2cdev, ic_addr, 0x0, &output_regs_bank_0);
   get_i2c_register(i2cdev, ic_addr, 0x1, &output_regs_bank_1);
   get_i2c_register(i2cdev, ic_addr, 0x4, &polarity_regs_bank_0);
   get_i2c_register(i2cdev, ic_addr, 0x5, &polarity_regs_bank_1);
   get_i2c_register(i2cdev, ic_addr, 0x6, &config_regs_bank_0);
   get_i2c_register(i2cdev, ic_addr, 0x7, &config_regs_bank_1);
   return 0;
 }

canonical_original_code:
unsigned char tca6416a_init(int i2cdev, unsigned char ic_addr)
 {
   get_i2c_register(i2cdev, ic_addr, 0x0, &output_regs_bank_0);
   get_i2c_register(i2cdev, ic_addr, 0x1, &output_regs_bank_1);
   get_i2c_register(i2cdev, ic_addr, 0x4, &polarity_regs_bank_0);
   get_i2c_register(i2cdev, ic_addr, 0x5, &polarity_regs_bank_1);
   get_i2c_register(i2cdev, ic_addr, 0x6, &config_regs_bank_0);
   get_i2c_register(i2cdev, ic_addr, 0x7, &config_regs_bank_1);
   return 0;
 }


decompiled_code:
__int64 __fastcall set_i2c_register(int fd, unsigned __int8 a2, unsigned __int8 a3, unsigned __int8 a4)
{
int v4; // er8
__int64 result; // rax
char v6[2]; // [rsp+Eh] [rbp-2Ah] BYREF
__int16 *v7; // [rsp+10h] [rbp-28h] BYREF
int v8; // [rsp+18h] [rbp-20h]
__int16 v9; // [rsp+20h] [rbp-18h] BYREF
int v10; // [rsp+22h] [rbp-16h]
char *v11; // [rsp+28h] [rbp-10h]

v9 = a2;
v11 = v6;
v10 = 0x20000;
v6[0] = a3;
v6[1] = a4;
if ( i2c_debug )
printf("set_i2c_register params: addr: 0x%x, reg: 0x%x, val: 0x%x\n", a2, a3, a4);
v7 = &v9;
v8 = 1;
v4 = ioctl(fd, 0x707uLL, &v7);
result = 0LL;
if ( v4 < 0 )
{
perror("Unable to send data");
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, unsigned __int8 a2, unsigned __int8 a3, unsigned __int8 a4)
{
int v4; // er8
__int64 result; // rax
char v6[2]; // [rsp+Eh] [rbp-2Ah] BYREF
__int16 *v7; // [rsp+10h] [rbp-28h] BYREF
int v8; // [rsp+18h] [rbp-20h]
__int16 v9; // [rsp+20h] [rbp-18h] BYREF
int v10; // [rsp+22h] [rbp-16h]
char *v11; // [rsp+28h] [rbp-10h]

v9 = a2;
v11 = v6;
v10 = 0x20000;
v6[0] = a3;
v6[1] = a4;
if ( i2c_debug )
printf("set_i2c_register params: addr: 0x%x, reg: 0x%x, val: 0x%x\n", a2, a3, a4);
v7 = &v9;
v8 = 1;
v4 = ioctl(fd, 0x707uLL, &v7);
result = 0LL;
if ( v4 < 0 )
{
perror("Unable to send data");
result = 1LL;
}
return result;
}

original_code:
uint8_t set_i2c_register(int file,
                            unsigned char addr,
                            unsigned char reg,
                            unsigned char value) {
    unsigned char outbuf[2];
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[1];
    messages[0].addr = addr;
    messages[0].flags = 0;
    messages[0].len = 2;
    messages[0].buf = outbuf;
    outbuf[0] = reg;
    outbuf[1] = value;
    if(i2c_debug)
     printf("set_i2c_register params: addr: 0x%x, reg: 0x%x, val: 0x%x\n", addr, reg, value);
    packets.msgs = messages;
    packets.nmsgs = 1;
    if(ioctl(file, 0x0707, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }
    return 0;
}

canonical_original_code:
unsigned char set_i2c_register(int file, unsigned char addr, unsigned char reg, unsigned char value) {
    unsigned char outbuf[2];
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[1];
    messages[0].addr = addr;
    messages[0].flags = 0;
    messages[0].len = 2;
    messages[0].buf = outbuf;
    outbuf[0] = reg;
    outbuf[1] = value;
    if(i2c_debug)
     printf("set_i2c_register params: addr: 0x%x, reg: 0x%x, val: 0x%x\n", addr, reg, value);
    packets.msgs = messages;
    packets.nmsgs = 1;
    if(ioctl(file, 0x0707, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }
    return 0;
}

variable_types: file int

variable_types:
addr
unsigned char

variable_types:
reg
unsigned char

variable_types:
value
unsigned char

variable_types:
outbuf
unsigned char [2]

variable_types: struct i2c_rdwr_ioctl_data { struct i2c_msg { unsigned short addr; unsigned short flags; unsigned short len; unsigned char *buf; } *msgs; unsigned int nmsgs; }

variable_types: struct i2c_msg { unsigned short addr; unsigned short flags; unsigned short len; unsigned char *buf; } [1]

user_defined_types: struct i2c_rdwr_ioctl_data { struct i2c_msg *msgs; unsigned int nmsgs; }


decompiled_code:
__int64 __fastcall get_i2c_register(int a1, unsigned __int8 a2, char a3, _BYTE *a4)
{
__int64 result; // rax
char v6; // [rsp+Eh] [rbp-3Ah] BYREF
char v7; // [rsp+Fh] [rbp-39h] BYREF
__int16 *v8; // [rsp+10h] [rbp-38h] BYREF
int v9; // [rsp+18h] [rbp-30h]
__int16 v10; // [rsp+20h] [rbp-28h] BYREF
int v11; // [rsp+22h] [rbp-26h]
char *v12; // [rsp+28h] [rbp-20h]
__int16 v13; // [rsp+30h] [rbp-18h]
int v14; // [rsp+32h] [rbp-16h]
char *v15; // [rsp+38h] [rbp-10h]

v7 = a3;
v12 = &v7;
v15 = &v6;
v10 = a2;
v13 = a2;
v8 = &v10;
v11 = 0x10000;
v14 = 65537;
v9 = 2;
if ( ioctl(a1, 0x707uLL, &v8) < 0 )
{
perror("Unable to send data");
result = 1LL;
}
else
{
*a4 = v6;
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1, unsigned __int8 a2, char a3, _BYTE *a4)
{
__int64 result; // rax
char v6; // [rsp+Eh] [rbp-3Ah] BYREF
char v7; // [rsp+Fh] [rbp-39h] BYREF
__int16 *v8; // [rsp+10h] [rbp-38h] BYREF
int v9; // [rsp+18h] [rbp-30h]
__int16 v10; // [rsp+20h] [rbp-28h] BYREF
int v11; // [rsp+22h] [rbp-26h]
char *v12; // [rsp+28h] [rbp-20h]
__int16 v13; // [rsp+30h] [rbp-18h]
int v14; // [rsp+32h] [rbp-16h]
char *v15; // [rsp+38h] [rbp-10h]

v7 = a3;
v12 = &v7;
v15 = &v6;
v10 = a2;
v13 = a2;
v8 = &v10;
v11 = 0x10000;
v14 = 65537;
v9 = 2;
if ( ioctl(a1, 0x707uLL, &v8) < 0 )
{
perror("Unable to send data");
result = 1LL;
}
else
{
*a4 = v6;
result = 0LL;
}
return result;
}

original_code:
uint8_t get_i2c_register(int file,
                            unsigned char addr,
                            unsigned char reg,
                            unsigned char *val) {
    unsigned char inbuf, outbuf;
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[2];
    outbuf = reg;
    messages[0].addr = addr;
    messages[0].flags = 0;
    messages[0].len = 1;
    messages[0].buf = &outbuf;
    messages[1].addr = addr;
    messages[1].flags = 0x0001 ;
    messages[1].len = 1;
    messages[1].buf = &inbuf;
    packets.msgs = messages;
    packets.nmsgs = 2;
    if(ioctl(file, 0x0707, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }
    *val = inbuf;
    return 0;
}

canonical_original_code:
unsigned char get_i2c_register(int file, unsigned char addr, unsigned char reg, unsigned char *val) {
    unsigned char inbuf; unsigned char outbuf;
    struct i2c_rdwr_ioctl_data packets;
    struct i2c_msg messages[2];
    outbuf = reg;
    messages[0].addr = addr;
    messages[0].flags = 0;
    messages[0].len = 1;
    messages[0].buf = &outbuf;
    messages[1].addr = addr;
    messages[1].flags = 0x0001 ;
    messages[1].len = 1;
    messages[1].buf = &inbuf;
    packets.msgs = messages;
    packets.nmsgs = 2;
    if(ioctl(file, 0x0707, &packets) < 0) {
        perror("Unable to send data");
        return 1;
    }
    *val = inbuf;
    return 0;
}

variable_types:
val
unsigned char *

variable_types:
inbuf
unsigned char

variable_types:
outbuf
unsigned char

variable_types: struct i2c_msg { unsigned short addr; unsigned short flags; unsigned short len; unsigned char *buf; } [2]


route

repo: wpwrak/subosm

original_code:
static void route(struct node *n, int d)
{
 struct edge *e;
 int nd;
 n->distance = d;
 for (e = n->edges; e != n->edges+n->n_edges; e++) {
  nd = d+e->len;
  if (e->n->distance > nd)
   route(e->n, nd);
 }
}

variable_types: struct node { int id; int x; _Bool station; _Bool proposed; int distance; struct edge { struct node *n; int len; int tag; } *edges; int n_edges; int tag; } *

variable_types: d int

variable_types: struct edge { struct node { int id; int x; _Bool station; _Bool proposed; int distance; struct edge *edges; int n_edges; int tag; } *n; int len; int tag; } *

variable_types: nd int


decompiled_code:
__int64 count_routes()
{
char *v0; // rax
unsigned int v1; // er8

if ( !(5LL * n_nodes) )
return 0;
v0 = (char *)&nodes;
v1 = 0;
do
{
if ( v0[12] && (!v0[13] || allow_proposed) )
++v1;
v0 += 40;
}
while ( v0 != (char *)&nodes + 40 * n_nodes );
return v1;
}

canonical_decompiled_code:
__int64 func1()
{
char *v0; // rax
unsigned int v1; // er8

if ( !(5LL * n_nodes) )
return 0;
v0 = (char *)&nodes;
v1 = 0;
do
{
if ( v0[12] && (!v0[13] || allow_proposed) )
++v1;
v0 += 40;
}
while ( v0 != (char *)&nodes + 40 * n_nodes );
return v1;
}

original_code:
static unsigned count_routes(void)
{
 unsigned routes = 0;
 struct node *n;
 for (n = nodes; n != nodes+n_nodes; n++) {
  if (!n->station)
   continue;
  if (n->proposed && !allow_proposed)
   continue;
  routes++;
 }
 return routes;
}

canonical_original_code:
static unsigned int count_routes()
{
 unsigned int routes = 0;
 struct node *n;
 for (n = nodes; n != nodes+n_nodes; n++) {
  if (!n->station)
   continue;
  if (n->proposed && !allow_proposed)
   continue;
  routes++;
 }
 return routes;
}

variable_types:
routes
unsigned int

return_type: unsigned int

user_defined_types: struct node { int id; int x; _Bool station; _Bool proposed; int distance; struct edge *edges; int n_edges; int tag; }

user_defined_types: struct edge { struct node *n; int len; int tag; }


decompiled_code:
__int64 reset_tags()
{
__int64 result; // rax
char *v1; // rsi
char *v2; // rcx
__int64 v3; // rdx
__int64 i; // rdx

result = 5LL * n_nodes;
v1 = (char *)&nodes + 40 * n_nodes;
if ( result )
{
v2 = (char *)&nodes;
do
{
v3 = *((int *)v2 + 8);
result = *((_QWORD *)v2 + 3);
*((_DWORD *)v2 + 9) = 0;
for ( i = result + 16 * v3; result != i; result += 16LL )
*(_DWORD *)(result + 12) = 0;
v2 += 40;
}
while ( v2 != v1 );
}
return result;
}

canonical_decompiled_code:
__int64 func2()
{
__int64 result; // rax
char *v1; // rsi
char *v2; // rcx
__int64 v3; // rdx
__int64 i; // rdx

result = 5LL * n_nodes;
v1 = (char *)&nodes + 40 * n_nodes;
if ( result )
{
v2 = (char *)&nodes;
do
{
v3 = *((int *)v2 + 8);
result = *((_QWORD *)v2 + 3);
*((_DWORD *)v2 + 9) = 0;
for ( i = result + 16 * v3; result != i; result += 16LL )
*(_DWORD *)(result + 12) = 0;
v2 += 40;
}
while ( v2 != v1 );
}
return result;
}

original_code:
static void reset_tags(void)
{
 struct node *n;
 struct edge *e;
 for (n = nodes; n != nodes+n_nodes; n++) {
  n->tag = 0;
  for (e = n->edges; e != n->edges+n->n_edges; e++)
   e->tag = 0;
 }
}

canonical_original_code:
static void reset_tags()
{
 struct node *n;
 struct edge *e;
 for (n = nodes; n != nodes+n_nodes; n++) {
  n->tag = 0;
  for (e = n->edges; e != n->edges+n->n_edges; e++)
   e->tag = 0;
 }
}


original_code:
static void prepare_routing(void)
{
 struct node *n;
 struct edge *e;
 for (n = nodes; n != nodes+n_nodes; n++) {
  n->distance = 1000;
  for (e = n->edges; e != n->edges+n->n_edges; e++)
   e->len = hypot(n->x-e->n->x, n->y-e->n->y);
 }
}

canonical_original_code:
static void prepare_routing()
{
 struct node *n;
 struct edge *e;
 for (n = nodes; n != nodes+n_nodes; n++) {
  n->distance = 1000;
  for (e = n->edges; e != n->edges+n->n_edges; e++)
   e->len = hypot(n->x-e->n->x, n->y-e->n->y);
 }
}


decompiled_code:
__int64 find_distances()
{
unsigned int v0; // er12
__int64 result; // rax
unsigned int v2; // ebp
char *v3; // r13
char *v4; // rbx
int v5; // esi

v0 = count_routes();
result = 5LL * n_nodes;
if ( result )
{
v2 = 0;
v3 = (char *)&nodes;
do
{
while ( 1 )
{
fprintf(stderr, "%u/%u\r", v2, v0);
fflush(stderr);
result = 5LL * n_nodes;
v4 = (char *)&nodes + 40 * n_nodes;
if ( v3[12] )
{
result = 40LL * n_nodes;
v4 = (char *)&nodes + result;
if ( !v3[13] || allow_proposed )
break;
}
v3 += 40;
if ( v3 == v4 )
return result;
}
if ( result )
{
v4 = (char *)&nodes;
do
{
v5 = (int)hypot(
(double)(*((_DWORD *)v3 + 1) - *((_DWORD *)v4 + 1)),
(double)(*((_DWORD *)v3 + 2) - *((_DWORD *)v4 + 2)));
if ( v5 <= 80 && *((_DWORD *)v4 + 4) > v5 )
route((__int64)v4, v5);
v4 += 40;
result = (__int64)&nodes + 40 * n_nodes;
}
while ( v4 != (char *)result );
}
v3 += 40;
++v2;
}
while ( v3 != v4 );
}
return result;
}

canonical_decompiled_code:
__int64 func4()
{
unsigned int v0; // er12
__int64 result; // rax
unsigned int v2; // ebp
char *v3; // r13
char *v4; // rbx
int v5; // esi

v0 = func1();
result = 5LL * n_nodes;
if ( result )
{
v2 = 0;
v3 = (char *)&nodes;
do
{
while ( 1 )
{
fprintf(stderr, "%u/%u\r", v2, v0);
fflush(stderr);
result = 5LL * n_nodes;
v4 = (char *)&nodes + 40 * n_nodes;
if ( v3[12] )
{
result = 40LL * n_nodes;
v4 = (char *)&nodes + result;
if ( !v3[13] || allow_proposed )
break;
}
v3 += 40;
if ( v3 == v4 )
return result;
}
if ( result )
{
v4 = (char *)&nodes;
do
{
v5 = (int)hypot(
(double)(*((_DWORD *)v3 + 1) - *((_DWORD *)v4 + 1)),
(double)(*((_DWORD *)v3 + 2) - *((_DWORD *)v4 + 2)));
if ( v5 <= 80 && *((_DWORD *)v4 + 4) > v5 )
func0((__int64)v4, v5);
v4 += 40;
result = (__int64)&nodes + 40 * n_nodes;
}
while ( v4 != (char *)result );
}
v3 += 40;
++v2;
}
while ( v3 != v4 );
}
return result;
}

original_code:
static void find_distances(void)
{
 struct node *n, *m;
 unsigned done = 0, routes;
 int d;
 routes = count_routes();
 for (n = nodes; n != nodes+n_nodes; n++) {
  fprintf(stderr, "%u/%u\r", done, routes);
  fflush(stderr);
  if (!n->station)
   continue;
  if (n->proposed && !allow_proposed)
   continue;
  for (m = nodes; m != nodes+n_nodes; m++) {
   d = hypot(n->x-m->x, n->y-m->y);
   if (d <= 80 && d < m->distance)
    route(m, d);
  }
  done++;
 }
}

canonical_original_code:
static void find_distances()
{
 struct node *n; struct node *m;
 unsigned int done = 0; unsigned int routes;
 int d;
 routes = count_routes();
 for (n = nodes; n != nodes+n_nodes; n++) {
  fprintf(stderr, "%u/%u\r", done, routes);
  fflush(stderr);
  if (!n->station)
   continue;
  if (n->proposed && !allow_proposed)
   continue;
  for (m = nodes; m != nodes+n_nodes; m++) {
   d = hypot(n->x-m->x, n->y-m->y);
   if (d <= 80 && d < m->distance)
    route(m, d);
  }
  done++;
 }
}

variable_types:
done
unsigned int


recurse

original_code:
static void recurse(struct node *n)
{
 struct edge *edge;
 n->tag = 1;
 for (edge = n->edges; edge != n->edges+n->n_edges; edge++) {
  if (!edge->tag && edge->n->id > n->id)
   printf("%d %d %d # %d\n%d %d %d # %d\n\n",
       n->x, n->y, n->distance, n->id,
       edge->n->x, edge->n->y, n->distance, edge->n->id);
  edge->tag = 1;
  if (!edge->n->tag)
   recurse(edge->n);
 }
}


decompiled_code:
__int64 dump_db()
{
__int64 result; // rax
unsigned int *v1; // rbx

reset_tags();
result = 5LL * n_nodes;
if ( result )
{
v1 = (unsigned int *)&nodes;
do
{
if ( *((_BYTE *)v1 + 12) && (allow_proposed || !*((_BYTE *)v1 + 13)) )
printf("#STATION %d %d %d # %d\n", v1[1], v1[2], v1[4], *v1);
if ( !v1[9] && v1[8] )
{
if ( v1 != (unsigned int *)&nodes )
puts("# new net\n");
recurse(v1);
}
v1 += 10;
result = (__int64)&nodes + 40 * n_nodes;
}
while ( v1 != (unsigned int *)result );
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax
unsigned int *v1; // rbx

func2();
result = 5LL * n_nodes;
if ( result )
{
v1 = (unsigned int *)&nodes;
do
{
if ( *((_BYTE *)v1 + 12) && (allow_proposed || !*((_BYTE *)v1 + 13)) )
printf("#STATION %d %d %d # %d\n", v1[1], v1[2], v1[4], *v1);
if ( !v1[9] && v1[8] )
{
if ( v1 != (unsigned int *)&nodes )
puts("# new net\n");
func5(v1);
}
v1 += 10;
result = (__int64)&nodes + 40 * n_nodes;
}
while ( v1 != (unsigned int *)result );
}
return result;
}

original_code:
static void dump_db(void)
{
 struct node *n;
 reset_tags();
 for (n = nodes; n != nodes+n_nodes; n++) {
  if (n->station && (allow_proposed || !n->proposed))
   printf("#STATION %d %d %d # %d\n",
       n->x, n->y, n->distance, n->id);
  if (n->tag)
   continue;
  if (!n->n_edges)
   continue;
  if (n != nodes)
   printf("# new net\n\n");
  recurse(n);
 }
}

canonical_original_code:
static void dump_db()
{
 struct node *n;
 reset_tags();
 for (n = nodes; n != nodes+n_nodes; n++) {
  if (n->station && (allow_proposed || !n->proposed))
   printf("#STATION %d %d %d # %d\n",
       n->x, n->y, n->distance, n->id);
  if (n->tag)
   continue;
  if (!n->n_edges)
   continue;
  if (n != nodes)
   printf("# new net\n\n");
  recurse(n);
 }
}