decompiled_code:
void __fastcall free_payload_subscribe(void *ptr)
{
_QWORD *v2; // rdi
__int64 v3; // rax

v2 = *(_QWORD **)ptr;
if ( v2 )
{
while ( 1 )
{
v3 = v2[2];
if ( !v3 )
break;
*(_QWORD *)ptr = v3;
free(v2);
v2 = *(_QWORD **)ptr;
if ( !*(_QWORD *)ptr )
goto LABEL_6;
}
free(v2);
}
LABEL_6:
free(ptr);
}

canonical_decompiled_code:
void __fastcall func7(void *ptr)
{
_QWORD *v2; // rdi
__int64 v3; // rax

v2 = *(_QWORD **)ptr;
if ( v2 )
{
while ( 1 )
{
v3 = v2[2];
if ( !v3 )
break;
*(_QWORD *)ptr = v3;
free(v2);
v2 = *(_QWORD **)ptr;
if ( !*(_QWORD *)ptr )
goto LABEL_6;
}
free(v2);
}
LABEL_6:
free(ptr);
}

original_code:
void free_payload_subscribe(payload_subscribe_t* payload)
{
    payload_subscribe_topic_t* topics;
    while (payload->topics)
    {
        topics = payload->topics;
        if (! topics->next)
        {
            free (topics);
            break;
        }
        else
        {
            payload->topics = topics->next;
            free (topics);
        }
    }
    free (payload);
}

canonical_original_code:
void free_payload_subscribe(struct payload_subscribe_s *payload)
{
    struct payload_subscribe_topic_s *topics;
    while (payload->topics)
    {
        topics = payload->topics;
        if (! topics->next)
        {
            free (topics);
            break;
        }
        else
        {
            payload->topics = topics->next;
            free (topics);
        }
    }
    free (payload);
}

variable_types: struct payload_subscribe_s { struct payload_subscribe_topic_s { unsigned char *topic_name; unsigned char qos; struct payload_subscribe_topic_s *next; } *topics; } *

user_defined_types: struct payload_subscribe_s { struct payload_subscribe_topic_s *topics; }


repo: wowsoso/mqtts

decompiled_code:
__int64 __fastcall unsubscribe_topic(__int64 a1, __int64 a2)
{
_QWORD *v2; // rdi
_QWORD *v3; // rdx

v2 = *(_QWORD **)(a1 + 40);
if ( !v2 )
return 0LL;
v3 = v2;
while ( v2[1] != a2 )
{
v3 = v2;
if ( !v2[2] )
return 0LL;
v2 = (_QWORD *)v2[2];
}
v3[2] = v2[2];
free(v2);
return 0LL;
}

original_code:
int unsubscribe_topic(topic_t* topics, void* connection)
{
    subscriber_t* subscribers = topics->subscribers;
    subscriber_t* subscriber = subscribers;
    while (subscribers)
    {
        if (subscribers->connection == connection)
        {
            subscriber->next = subscribers->next;
            free (subscribers);
            break;
        }
        else
        {
            subscriber = subscribers;
            subscribers = subscribers->next;
        }
    }
    return 0;
}

canonical_original_code:
int unsubscribe_topic(struct topic_s *topics, void *connection)
{
    struct subscriber_s *subscribers = topics->subscribers;
    struct subscriber_s *subscriber = subscribers;
    while (subscribers)
    {
        if (subscribers->connection == connection)
        {
            subscriber->next = subscribers->next;
            free (subscribers);
            break;
        }
        else
        {
            subscriber = subscribers;
            subscribers = subscribers->next;
        }
    }
    return 0;
}

variable_types: struct topic_s { unsigned char *name; struct topic_s *sub; struct topic_s *next; unsigned long sub_size; struct topic_message_s { unsigned char *message; struct topic_message_s *next; } *topic_message; struct subscriber_s { unsigned char qos; void *connection; struct subscriber_s *next; } *subscribers; } *

variable_types:
connection
void *

return_type: int

user_defined_types: struct topic_s { unsigned char *name; struct topic_s *sub; struct topic_s *next; unsigned long sub_size; struct topic_message_s *topic_message; struct subscriber_s *subscribers; }


original_code:
topic_t* make_topic(uint8_t* topic_str, uint8_t* message)
{
    uint8_t* buf;
    uint8_t* saveptr;
    topic_t* topic;
    topic_t* _topic;
    char* delim = "/";
    if (strlen (topic_str))
    {
        buf = strtok_r(topic_str, delim, &saveptr);
    }
    else
    {
        return ((void *)0);
    }
    if (! (topic = malloc (sizeof (topic_t))))
    {
        return ((void *)0);
    }
    topic->name = buf;
    topic->sub_size = 0;
    topic->sub = ((void *)0);
    topic->next = ((void *)0);
    topic->topic_message = ((void *)0);
    _topic = topic;
    while (strlen (saveptr))
    {
        if (strlen (saveptr))
        {
            buf = strtok_r(saveptr, delim, &saveptr);
        }
        else
        {
            break;
        }
        if (! (_topic->sub = malloc (sizeof( topic_t))))
        {
            free (topic);
            return ((void *)0);
        }
        _topic->sub_size++;
        _topic->sub->name = buf;
        _topic->sub->sub_size = 0;
        _topic->sub->sub = ((void *)0);
        _topic->sub->next = ((void *)0);
        _topic->topic_message = ((void *)0);
        _topic = _topic->sub;
    }
    while (_topic->topic_message)
    {
        _topic->topic_message = _topic->topic_message->next;
    }
    if (message)
    {
        _topic->topic_message = malloc (sizeof (topic_message_t));
        _topic->topic_message->message = message;
        _topic->topic_message->next = ((void *)0);
    }
    return topic;
}

canonical_original_code:
struct topic_s *make_topic(unsigned char *topic_str, unsigned char *message)
{
    unsigned char *buf;
    unsigned char *saveptr;
    struct topic_s *topic;
    struct topic_s *_topic;
    char *delim = "/";
    if (strlen (topic_str))
    {
        buf = strtok_r(topic_str, delim, &saveptr);
    }
    else
    {
        return ((void *)0);
    }
    if (! (topic = malloc (sizeof (topic_t))))
    {
        return ((void *)0);
    }
    topic->name = buf;
    topic->sub_size = 0;
    topic->sub = ((void *)0);
    topic->next = ((void *)0);
    topic->topic_message = ((void *)0);
    _topic = topic;
    while (strlen (saveptr))
    {
        if (strlen (saveptr))
        {
            buf = strtok_r(saveptr, delim, &saveptr);
        }
        else
        {
            break;
        }
        if (! (_topic->sub = malloc (sizeof( topic_t))))
        {
            free (topic);
            return ((void *)0);
        }
        _topic->sub_size++;
        _topic->sub->name = buf;
        _topic->sub->sub_size = 0;
        _topic->sub->sub = ((void *)0);
        _topic->sub->next = ((void *)0);
        _topic->topic_message = ((void *)0);
        _topic = _topic->sub;
    }
    while (_topic->topic_message)
    {
        _topic->topic_message = _topic->topic_message->next;
    }
    if (message)
    {
        _topic->topic_message = malloc (sizeof (topic_message_t));
        _topic->topic_message->message = message;
        _topic->topic_message->next = ((void *)0);
    }
    return topic;
}

variable_types:
message
unsigned char *

variable_types:
buf
unsigned char *

variable_types:
saveptr
unsigned char *

variable_types:
delim
char *

return_type: struct topic_s { unsigned char *name; struct topic_s *sub; struct topic_s *next; unsigned long sub_size; struct topic_message_s { unsigned char *message; struct topic_message_s *next; } *topic_message; struct subscriber_s { unsigned char qos; void *connection; struct subscriber_s *next; } *subscribers; } *


decompiled_code:
// write access to const memory has been detected, the output may be wrong!
__int64 __fastcall insert_topic(__int64 a1, const char *a2, __int64 a3)
{
__int64 v3; // rbx
__int64 result; // rax
size_t v6; // rax
void *v7; // r13
size_t v8; // rax
char *v9; // rbp
__int64 v10; // rax
__int64 v11; // rax
__int64 v12; // rax
char *save_ptr[6]; // [rsp+0h] [rbp-30h] BYREF

if ( !a1 )
return 0xFFFFFFFFLL;
v3 = a1;
result = 0xFFFFFFFFLL;
if ( *a2 )
{
v6 = strlen(a2);
v7 = malloc(v6 + 1);
v8 = strlen(a2);
memset(v7, 0, v8 + 1);
strcpy((char *)v7, a2);
v9 = strtok_r((char *)v7, "/", save_ptr);
while ( 1 )
{
if ( !strcmp(*(const char **)v3, v9) )
{
if ( !*save_ptr[0] )
{
v10 = *(_QWORD *)(v3 + 32);
if ( v10 )
{
v11 = *(_QWORD *)(v10 + 8);
if ( v11 )
*(_QWORD *)(v3 + 32) = v11;
if ( a3 )
{
LABEL_8:
**(_QWORD **)(v3 + 32) = a3;
*(_QWORD *)(*(_QWORD *)(v3 + 32) + 8LL) = 0LL;
}
}
else if ( a3 )
{
*(_QWORD *)((char *)&loc_1E + 2) = malloc(0x10uLL);
goto LABEL_8;
}
free(v7);
return 1LL;
}
v9 = strtok_r(save_ptr[0], "/", save_ptr);
v12 = *(_QWORD *)(v3 + 8);
}
else
{
v12 = *(_QWORD *)(v3 + 16);
}
if ( !v12 )
break;
v3 = v12;
}
*(_QWORD *)(v3 + 16) = make_topic((char *)v7, a3);
free(v7);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const char *a2, __int64 a3)
{
__int64 v3; // rbx
__int64 result; // rax
size_t v6; // rax
void *v7; // r13
size_t v8; // rax
char *v9; // rbp
__int64 v10; // rax
__int64 v11; // rax
__int64 v12; // rax
char *save_ptr[6]; // [rsp+0h] [rbp-30h] BYREF

if ( !a1 )
return 0xFFFFFFFFLL;
v3 = a1;
result = 0xFFFFFFFFLL;
if ( *a2 )
{
v6 = strlen(a2);
v7 = malloc(v6 + 1);
v8 = strlen(a2);
memset(v7, 0, v8 + 1);
strcpy((char *)v7, a2);
v9 = strtok_r((char *)v7, "/", save_ptr);
while ( 1 )
{
if ( !strcmp(*(const char **)v3, v9) )
{
if ( !*save_ptr[0] )
{
v10 = *(_QWORD *)(v3 + 32);
if ( v10 )
{
v11 = *(_QWORD *)(v10 + 8);
if ( v11 )
*(_QWORD *)(v3 + 32) = v11;
if ( a3 )
{
LABEL_8:
**(_QWORD **)(v3 + 32) = a3;
*(_QWORD *)(*(_QWORD *)(v3 + 32) + 8LL) = 0LL;
}
}
else if ( a3 )
{
*(_QWORD *)((char *)&loc_1E + 2) = malloc(0x10uLL);
goto LABEL_8;
}
free(v7);
return 1LL;
}
v9 = strtok_r(save_ptr[0], "/", save_ptr);
v12 = *(_QWORD *)(v3 + 8);
}
else
{
v12 = *(_QWORD *)(v3 + 16);
}
if ( !v12 )
break;
v3 = v12;
}
*(_QWORD *)(v3 + 16) = func1((char *)v7, a3);
free(v7);
result = 0LL;
}
return result;
}

original_code:
int insert_topic(topic_t* topics, uint8_t* topic_str, uint8_t* message)
{
    uint8_t* buf;
    uint8_t* saveptr;
    topic_t* topic;
    topic_t* _topic;
    topic_t* _topics = topics;
    topic_t* __topics;
    uint8_t* _buf;
    char* delim = "/";
    if (! topics)
    {
        return -1;
    }
    if (strlen (topic_str))
    {
        _buf = malloc(strlen (topic_str) + 1);
        memset (_buf, 0, strlen (topic_str) + 1);
        strcpy (_buf, topic_str);
        buf = strtok_r (_buf, delim, &saveptr);
    }
    else
    {
        return -1;
    }
    while (_topics)
    {
        __topics = _topics;
        if (! strcmp (_topics->name, buf))
        {
            if (! strlen (saveptr))
            {
                while (_topics->topic_message)
                {
                    if (_topics->topic_message->next)
                    {
                        _topics->topic_message = _topics->topic_message->next;
                    }
                    break;
                }
                if (message)
                {
                    if (! _topics->topic_message)
                    {
                        _topic->topic_message = malloc (sizeof (topic_message_t));
                    }
                    _topics->topic_message->message = message;
                    _topics->topic_message->next = ((void *)0);
                }
                free (_buf);
                return 1;
            }
            else {
                if (strlen (saveptr))
                {
                    buf = strtok_r (saveptr, delim, &saveptr);
                }
                else
                {
                    free (_buf);
                    return -1;
                }
                _topics = _topics->sub;
            }
        }
        else
        {
            _topics = _topics->next;
        }
    }
    __topics->next = make_topic (_buf, message);
    free (_buf);
    return 0;
}

canonical_original_code:
int insert_topic(struct topic_s *topics, unsigned char *topic_str, unsigned char *message)
{
    unsigned char *buf;
    unsigned char *saveptr;
    struct topic_s *topic;
    struct topic_s *_topic;
    struct topic_s *_topics = topics;
    struct topic_s *__topics;
    unsigned char *_buf;
    char *delim = "/";
    if (! topics)
    {
        return -1;
    }
    if (strlen (topic_str))
    {
        _buf = malloc(strlen (topic_str) + 1);
        memset (_buf, 0, strlen (topic_str) + 1);
        strcpy (_buf, topic_str);
        buf = strtok_r (_buf, delim, &saveptr);
    }
    else
    {
        return -1;
    }
    while (_topics)
    {
        __topics = _topics;
        if (! strcmp (_topics->name, buf))
        {
            if (! strlen (saveptr))
            {
                while (_topics->topic_message)
                {
                    if (_topics->topic_message->next)
                    {
                        _topics->topic_message = _topics->topic_message->next;
                    }
                    break;
                }
                if (message)
                {
                    if (! _topics->topic_message)
                    {
                        _topic->topic_message = malloc (sizeof (topic_message_t));
                    }
                    _topics->topic_message->message = message;
                    _topics->topic_message->next = ((void *)0);
                }
                free (_buf);
                return 1;
            }
            else {
                if (strlen (saveptr))
                {
                    buf = strtok_r (saveptr, delim, &saveptr);
                }
                else
                {
                    free (_buf);
                    return -1;
                }
                _topics = _topics->sub;
            }
        }
        else
        {
            _topics = _topics->next;
        }
    }
    __topics->next = make_topic (_buf, message);
    free (_buf);
    return 0;
}

user_defined_types: struct topic_message_s { unsigned char *message; struct topic_message_s *next; }

user_defined_types: struct subscriber_s { unsigned char qos; void *connection; struct subscriber_s *next; }


decompiled_code:
__int64 __fastcall get_topic(__int64 a1, const char *a2)
{
__int64 v2; // rbx
size_t v3; // rax
void *v4; // r12
size_t v5; // rax
char *v6; // rbp
char *save_ptr[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = 0LL;
if ( *a2 )
{
v2 = a1;
v3 = strlen(a2);
v4 = malloc(v3 + 1);
v5 = strlen(a2);
memset(v4, 0, v5 + 1);
strcpy((char *)v4, a2);
v6 = strtok_r((char *)v4, "/", save_ptr);
free(v4);
if ( a1 )
{
do
{
if ( !strcmp(*(const char **)v2, v6) )
{
if ( !*save_ptr[0] )
return v2;
v6 = strtok_r(save_ptr[0], "/", save_ptr);
v2 = *(_QWORD *)(v2 + 8);
}
else
{
v2 = *(_QWORD *)(v2 + 16);
}
}
while ( v2 );
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, const char *a2)
{
__int64 v2; // rbx
size_t v3; // rax
void *v4; // r12
size_t v5; // rax
char *v6; // rbp
char *save_ptr[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = 0LL;
if ( *a2 )
{
v2 = a1;
v3 = strlen(a2);
v4 = malloc(v3 + 1);
v5 = strlen(a2);
memset(v4, 0, v5 + 1);
strcpy((char *)v4, a2);
v6 = strtok_r((char *)v4, "/", save_ptr);
free(v4);
if ( a1 )
{
do
{
if ( !strcmp(*(const char **)v2, v6) )
{
if ( !*save_ptr[0] )
return v2;
v6 = strtok_r(save_ptr[0], "/", save_ptr);
v2 = *(_QWORD *)(v2 + 8);
}
else
{
v2 = *(_QWORD *)(v2 + 16);
}
}
while ( v2 );
}
}
return v2;
}

original_code:
topic_t* get_topic(topic_t* topics, uint8_t* topic_str)
{
    uint8_t* buf;
    uint8_t* _buf;
    uint8_t* saveptr;
    char* delim = "/";
    if (strlen (topic_str))
    {
        _buf = malloc (strlen (topic_str) + 1);
        memset (_buf, 0, strlen (topic_str) + 1);
        strcpy (_buf, topic_str);
        buf = strtok_r(_buf, delim, &saveptr);
        free (_buf);
    }
    else
    {
        return ((void *)0);
    }
    while (topics)
    {
        if (! strcmp(topics->name, buf))
        {
            if (strlen (saveptr))
            {
                buf = strtok_r(saveptr, delim, &saveptr);
            }
            else
            {
                return topics;
            }
            topics = topics->sub;
            continue;
        }
        else
        {
            topics = topics->next;
            continue;
        }
    }
    return ((void *)0);
}

canonical_original_code:
struct topic_s *get_topic(struct topic_s *topics, unsigned char *topic_str)
{
    unsigned char *buf;
    unsigned char *_buf;
    unsigned char *saveptr;
    char *delim = "/";
    if (strlen (topic_str))
    {
        _buf = malloc (strlen (topic_str) + 1);
        memset (_buf, 0, strlen (topic_str) + 1);
        strcpy (_buf, topic_str);
        buf = strtok_r(_buf, delim, &saveptr);
        free (_buf);
    }
    else
    {
        return ((void *)0);
    }
    while (topics)
    {
        if (! strcmp(topics->name, buf))
        {
            if (strlen (saveptr))
            {
                buf = strtok_r(saveptr, delim, &saveptr);
            }
            else
            {
                return topics;
            }
            topics = topics->sub;
            continue;
        }
        else
        {
            topics = topics->next;
            continue;
        }
    }
    return ((void *)0);
}

variable_types:
topics
struct topic_s *


decompiled_code:
__int64 __fastcall insert_subscriber(__int64 a1, __int64 a2)
{
__int64 v2; // rax
_QWORD *v3; // rax
__int64 result; // rax
__int64 v5; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
v2 = *(_QWORD *)(a1 + 40);
if ( v2 )
{
v5 = *(_QWORD *)(v2 + 8);
while ( v5 != a2 )
;
result = 0xFFFFFFFFLL;
}
else
{
v3 = malloc(0x18uLL);
*(_QWORD *)(a1 + 40) = v3;
*v3 = 0LL;
v3[2] = 0LL;
v3[1] = a2;
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, __int64 a2)
{
__int64 v2; // rax
_QWORD *v3; // rax
__int64 result; // rax
__int64 v5; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
v2 = *(_QWORD *)(a1 + 40);
if ( v2 )
{
v5 = *(_QWORD *)(v2 + 8);
while ( v5 != a2 )
;
result = 0xFFFFFFFFLL;
}
else
{
v3 = malloc(0x18uLL);
*(_QWORD *)(a1 + 40) = v3;
*v3 = 0LL;
v3[2] = 0LL;
v3[1] = a2;
result = 0LL;
}
return result;
}

original_code:
int insert_subscriber(topic_t* topic, void* connection)
{
    subscriber_t* subscribers;
    subscriber_t* _subscribers;
    if (! topic)
    {
        return -1;
    }
    if (! topic->subscribers)
    {
        topic->subscribers = malloc (sizeof (subscriber_t));
        memset (topic->subscribers, 0, sizeof (subscriber_t));
        topic->subscribers->connection = connection;
        topic->subscribers->next = ((void *)0);
        return 0;
    }
    _subscribers = topic->subscribers;
    while (_subscribers)
    {
        if (_subscribers->connection == connection)
        {
            return -1;
        }
        continue;
    }
    subscribers = malloc (sizeof (subscriber_t));
    memset (subscribers, 0, sizeof (subscriber_t));
    subscribers->connection = connection;
    subscribers->next = topic->subscribers;
    topic->subscribers = subscribers;
    return 0;
}

canonical_original_code:
int insert_subscriber(struct topic_s *topic, void *connection)
{
    struct subscriber_s *subscribers;
    struct subscriber_s *_subscribers;
    if (! topic)
    {
        return -1;
    }
    if (! topic->subscribers)
    {
        topic->subscribers = malloc (sizeof (subscriber_t));
        memset (topic->subscribers, 0, sizeof (subscriber_t));
        topic->subscribers->connection = connection;
        topic->subscribers->next = ((void *)0);
        return 0;
    }
    _subscribers = topic->subscribers;
    while (_subscribers)
    {
        if (_subscribers->connection == connection)
        {
            return -1;
        }
        continue;
    }
    subscribers = malloc (sizeof (subscriber_t));
    memset (subscribers, 0, sizeof (subscriber_t));
    subscribers->connection = connection;
    subscribers->next = topic->subscribers;
    topic->subscribers = subscribers;
    return 0;
}

variable_types: struct subscriber_s { unsigned char qos; void *connection; struct subscriber_s *next; } *


decompiled_code:
__int64 __fastcall init_event(int fd, struct epoll_event *event)
{
int v2; // eax
unsigned int v3; // ebx

v2 = epoll_create1(0);
if ( v2 == -1 )
{
perror("epoll_create");
abort();
}
v3 = v2;
event->data.fd = fd;
event->events = -2147483647;
if ( epoll_ctl(v2, 1, fd, event) == -1 )
{
perror("epoll_ctl");
abort();
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func0(int fd, struct epoll_event *event)
{
int v2; // eax
unsigned int v3; // ebx

v2 = epoll_create1(0);
if ( v2 == -1 )
{
perror("epoll_create");
abort();
}
v3 = v2;
event->data.fd = fd;
event->events = -2147483647;
if ( epoll_ctl(v2, 1, fd, event) == -1 )
{
perror("epoll_ctl");
abort();
}
return v3;
}

original_code:
int init_event(int sfd, struct epoll_event* event, struct epoll_event* events)
{
    int s;
    int efd;
    if ((efd = epoll_create1 (0)) == -1)
    {
        perror ("epoll_create");
        abort ();
    };
    event->data.fd = sfd;
    event->events = EPOLLIN | EPOLLET;
    if ((s = epoll_ctl (efd, 1, sfd, event)) == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
    events = calloc (40000, sizeof (*event));
    return efd;
}

canonical_original_code:
int init_event(int sfd, struct epoll_event *event, struct epoll_event *events)
{
    int s;
    int efd;
    if ((efd = epoll_create1 (0)) == -1)
    {
        perror ("epoll_create");
        abort ();
    };
    event->data.fd = sfd;
    event->events = EPOLLIN | EPOLLET;
    if ((s = epoll_ctl (efd, 1, sfd, event)) == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
    events = calloc (40000, sizeof (*event));
    return efd;
}

variable_types: sfd int

variable_types: struct epoll_event { unsigned int events; union epoll_data { void *ptr; int fd; unsigned int u32; unsigned long u64; } data; } *

variable_types:
events
struct epoll_event *

variable_types: s int

variable_types: efd int

user_defined_types: struct epoll_event { unsigned int events; union epoll_data data; }


decompiled_code:
int __fastcall add_event(struct epoll_event *event, int epfd, int a3, int a4)
{
int result; // eax

event->data.fd = a3;
event->events = a4 | 0x80000000;
result = epoll_ctl(epfd, 1, a3, event);
if ( result == -1 )
{
perror("epoll_ctl");
abort();
}
return result;
}

canonical_decompiled_code:
int __fastcall func1(struct epoll_event *event, int epfd, int a3, int a4)
{
int result; // eax

event->data.fd = a3;
event->events = a4 | 0x80000000;
result = epoll_ctl(epfd, 1, a3, event);
if ( result == -1 )
{
perror("epoll_ctl");
abort();
}
return result;
}

original_code:
void add_event(struct epoll_event* event, int efd, int fd, int mask)
{
    int s;
    event->data.fd = fd;
    event->events = mask | EPOLLET;
    if ((s = epoll_ctl (efd, 1, fd, event)) == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
}

canonical_original_code:
void add_event(struct epoll_event *event, int efd, int fd, int mask)
{
    int s;
    event->data.fd = fd;
    event->events = mask | EPOLLET;
    if ((s = epoll_ctl (efd, 1, fd, event)) == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
}

variable_types: fd int

variable_types: mask int

return_type: void

user_defined_types: union epoll_data { void *ptr; int fd; unsigned int u32; unsigned long u64; }


decompiled_code:
int __fastcall mod_event(struct epoll_event *event, int epfd, int a3, int a4)
{
int result; // eax

event->data.fd = a3;
event->events = a4 | 0x80000000;
result = epoll_ctl(epfd, 3, a3, event);
if ( result == -1 )
{
perror("epoll_ctl");
abort();
}
return result;
}

canonical_decompiled_code:
int __fastcall func2(struct epoll_event *event, int epfd, int a3, int a4)
{
int result; // eax

event->data.fd = a3;
event->events = a4 | 0x80000000;
result = epoll_ctl(epfd, 3, a3, event);
if ( result == -1 )
{
perror("epoll_ctl");
abort();
}
return result;
}

original_code:
void mod_event(struct epoll_event* event, int efd, int fd, int mask)
{
    int s;
    event->data.fd = fd;
    event->events = mask | EPOLLET;
    if ((s = epoll_ctl (efd, 3, fd, event)) == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
}

canonical_original_code:
void mod_event(struct epoll_event *event, int efd, int fd, int mask)
{
    int s;
    event->data.fd = fd;
    event->events = mask | EPOLLET;
    if ((s = epoll_ctl (efd, 3, fd, event)) == -1)
    {
        perror ("epoll_ctl");
        abort ();
    }
}


strcopy

decompiled_code:
char *__fastcall strcopy(char *src)
{
size_t v1; // rax
char *v2; // rax
char *v3; // rbx

v1 = strlen(src);
v2 = (char *)malloc(v1 + 1);
v3 = v2;
if ( v2 )
strcpy(v2, src);
return v3;
}

canonical_decompiled_code:
char *__fastcall func0(char *src)
{
size_t v1; // rax
char *v2; // rax
char *v3; // rbx

v1 = strlen(src);
v2 = (char *)malloc(v1 + 1);
v3 = v2;
if ( v2 )
strcpy(v2, src);
return v3;
}

original_code:
static char* strcopy(const char* key)
{
    char* _key;
    if (! (_key = malloc (strlen (key) + 1)))
    {
        return ((void *)0);
    }
    strcpy(_key, key);
    return _key;
}

canonical_original_code:
static char *strcopy(char *key)
{
    char *_key;
    if (! (_key = malloc (strlen (key) + 1)))
    {
        return ((void *)0);
    }
    strcpy(_key, key);
    return _key;
}

variable_types:
key
char *

return_type: char *


hashfunc

decompiled_code:
__int64 __fastcall hashfunc(char *src)
{
size_t v1; // rax
char *v2; // rax
char *v3; // rbx
char *v4; // rsi
char v5; // al
__int64 v6; // rcx

v1 = strlen(src);
v2 = (char *)malloc(v1 + 1);
if ( !v2 )
return -1LL;
v3 = v2;
strcpy(v2, src);
v4 = v3 + 1;
v5 = *v3;
if ( !*v3 )
return 5381LL;
v6 = 5381LL;
do
{
v6 += 32 * v6 + v5;
v5 = *v4++;
}
while ( v5 );
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func1(char *src)
{
size_t v1; // rax
char *v2; // rax
char *v3; // rbx
char *v4; // rsi
char v5; // al
__int64 v6; // rcx

v1 = strlen(src);
v2 = (char *)malloc(v1 + 1);
if ( !v2 )
return -1LL;
v3 = v2;
strcpy(v2, src);
v4 = v3 + 1;
v5 = *v3;
if ( !*v3 )
return 5381LL;
v6 = 5381LL;
do
{
v6 += 32 * v6 + v5;
v5 = *v4++;
}
while ( v5 );
return v6;
}

original_code:
unsigned long hashfunc(const char* key)
{
    unsigned long hash = 5381;
    int c;
    char* _key;
    if (! (_key = malloc (strlen(key) + 1)))
    {
        return -1;
    }
    strcpy(_key, key);
    while (c = *_key++)
    {
        hash = ((hash << 5) + hash) + c;
    }
    return hash;
}

canonical_original_code:
unsigned long hashfunc(char *key)
{
    unsigned long hash = 5381;
    int c;
    char *_key;
    if (! (_key = malloc (strlen(key) + 1)))
    {
        return -1;
    }
    strcpy(_key, key);
    while (c = *_key++)
    {
        hash = ((hash << 5) + hash) + c;
    }
    return hash;
}

variable_types:
hash
unsigned long

variable_types: c int

return_type: unsigned long


decompiled_code:
void __fastcall hasht_free(void *ptr)
{
unsigned __int64 v2; // rbp
__int64 v3; // rbx
void *v4; // rdi

if ( *((_QWORD *)ptr + 1) )
{
v2 = 0LL;
do
{
v3 = *(_QWORD *)(*(_QWORD *)ptr + 8 * v2);
while ( v3 )
{
free(*(void **)v3);
v4 = (void *)v3;
v3 = *(_QWORD *)(v3 + 16);
free(v4);
}
++v2;
}
while ( *((_QWORD *)ptr + 1) > v2 );
}
free(*(void **)ptr);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func2(void *ptr)
{
unsigned __int64 v2; // rbp
__int64 v3; // rbx
void *v4; // rdi

if ( *((_QWORD *)ptr + 1) )
{
v2 = 0LL;
do
{
v3 = *(_QWORD *)(*(_QWORD *)ptr + 8 * v2);
while ( v3 )
{
free(*(void **)v3);
v4 = (void *)v3;
v3 = *(_QWORD *)(v3 + 16);
free(v4);
}
++v2;
}
while ( *((_QWORD *)ptr + 1) > v2 );
}
free(*(void **)ptr);
free(ptr);
}

original_code:
void hasht_free(hasht_t* hasht)
{
 size_t i;
 hash_buckets_t* bucket;
    hash_buckets_t* old_bucket;
 for(i=0; i < hasht->size; i++) {
  bucket = hasht->buckets[i];
  while(bucket)
        {
   free(bucket->key);
   old_bucket = bucket;
   bucket = bucket->next;
   free (old_bucket);
  }
 }
 free (hasht->buckets);
 free (hasht);
}

canonical_original_code:
void hasht_free(struct hasht_s *hasht)
{
 unsigned long i;
 struct hash_buckets_s *bucket;
    struct hash_buckets_s *old_bucket;
 for(i=0; i < hasht->size; i++) {
  bucket = hasht->buckets[i];
  while(bucket)
        {
   free(bucket->key);
   old_bucket = bucket;
   bucket = bucket->next;
   free (old_bucket);
  }
 }
 free (hasht->buckets);
 free (hasht);
}

variable_types: struct hasht_s { struct hash_buckets_s { char *key; void *value; struct hash_buckets_s *next; } **buckets; unsigned long size; } *

variable_types:
i
unsigned long

user_defined_types: struct hasht_s { struct hash_buckets_s **buckets; unsigned long size; }


decompiled_code:
int __fastcall hasht_insert(_QWORD *a1, char *a2, __int64 a3)
{
unsigned __int64 v4; // r14
__int64 v5; // rbx
int result; // eax
_QWORD *v7; // rbx
char *v8; // rax
_QWORD *v9; // r14

v4 = 8 * ((unsigned __int64)hashfunc(a2) % a1[1]);
v5 = *(_QWORD *)(*a1 + v4);
if ( v5 )
{
while ( 1 )
{
result = strcmp(*(const char **)v5, a2);
if ( !result )
break;
v5 = *(_QWORD *)(v5 + 16);
if ( !v5 )
goto LABEL_4;
}
*(_QWORD *)(v5 + 8) = a3;
}
else
{
LABEL_4:
v7 = malloc(0x18uLL);
if ( v7 )
{
v8 = strcopy(a2);
*v7 = v8;
if ( v8 )
{
v7[1] = a3;
v9 = (_QWORD *)(*a1 + v4);
v7[2] = *v9;
*v9 = v7;
result = 0;
}
else
{
free(v7);
result = -1;
}
}
else
{
result = -1;
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func3(_QWORD *a1, char *a2, __int64 a3)
{
unsigned __int64 v4; // r14
__int64 v5; // rbx
int result; // eax
_QWORD *v7; // rbx
char *v8; // rax
_QWORD *v9; // r14

v4 = 8 * ((unsigned __int64)func1(a2) % a1[1]);
v5 = *(_QWORD *)(*a1 + v4);
if ( v5 )
{
while ( 1 )
{
result = strcmp(*(const char **)v5, a2);
if ( !result )
break;
v5 = *(_QWORD *)(v5 + 16);
if ( !v5 )
goto LABEL_4;
}
*(_QWORD *)(v5 + 8) = a3;
}
else
{
LABEL_4:
v7 = malloc(0x18uLL);
if ( v7 )
{
v8 = func0(a2);
*v7 = v8;
if ( v8 )
{
v7[1] = a3;
v9 = (_QWORD *)(*a1 + v4);
v7[2] = *v9;
*v9 = v7;
result = 0;
}
else
{
free(v7);
result = -1;
}
}
else
{
result = -1;
}
}
return result;
}

original_code:
int hasht_insert(hasht_t* hasht, const char* key, void* value)
{
    hash_buckets_t* bucket;
    size_t hash = hashfunc (key) % hasht->size;
    bucket = hasht->buckets[hash];
    while (bucket) {
        if(!strcmp(bucket->key, key)) {
            bucket->value = value;
            return 0;
        }
        else
        {
            bucket = bucket->next;
        }
    }
    if(! (bucket = malloc (sizeof (hash_buckets_t))))
    {
        return -1;
    }
    if (! (bucket->key = strcopy (key))) {
        free (bucket);
        return -1;
    }
    bucket->value = value;
    bucket->next = hasht->buckets[hash];
    hasht->buckets[hash] = bucket;
    return 0;
}

canonical_original_code:
int hasht_insert(struct hasht_s *hasht, char *key, void *value)
{
    struct hash_buckets_s *bucket;
    unsigned long hash = hashfunc (key) % hasht->size;
    bucket = hasht->buckets[hash];
    while (bucket) {
        if(!strcmp(bucket->key, key)) {
            bucket->value = value;
            return 0;
        }
        else
        {
            bucket = bucket->next;
        }
    }
    if(! (bucket = malloc (sizeof (hash_buckets_t))))
    {
        return -1;
    }
    if (! (bucket->key = strcopy (key))) {
        free (bucket);
        return -1;
    }
    bucket->value = value;
    bucket->next = hasht->buckets[hash];
    hasht->buckets[hash] = bucket;
    return 0;
}

variable_types:
value
void *

variable_types: struct hash_buckets_s { char *key; void *value; struct hash_buckets_s *next; } *


decompiled_code:
__int64 __fastcall hasht_remove(_QWORD *a1, char *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
char *v4; // r12
unsigned int v5; // ebx
unsigned __int64 v7; // [rsp+8h] [rbp-40h]

v7 = (unsigned __int64)hashfunc(a2) % a1[1];
v2 = *(_QWORD *)(*a1 + 8 * v7);
if ( !v2 )
return (unsigned int)-1;
v3 = 0LL;
while ( 1 )
{
v4 = *(char **)v2;
v5 = strcmp(*(const char **)v2, a2);
if ( !v5 )
break;
v3 = v2;
if ( !*(_QWORD *)(v2 + 16) )
return (unsigned int)-1;
v2 = *(_QWORD *)(v2 + 16);
}
free(v4);
if ( v3 )
*(_QWORD *)(v3 + 16) = *(_QWORD *)(v2 + 16);
else
*(_QWORD *)(*a1 + 8 * v7) = *(_QWORD *)(v2 + 16);
free((void *)v2);
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func4(_QWORD *a1, char *a2)
{
__int64 v2; // rbp
__int64 v3; // r14
char *v4; // r12
unsigned int v5; // ebx
unsigned __int64 v7; // [rsp+8h] [rbp-40h]

v7 = (unsigned __int64)func1(a2) % a1[1];
v2 = *(_QWORD *)(*a1 + 8 * v7);
if ( !v2 )
return (unsigned int)-1;
v3 = 0LL;
while ( 1 )
{
v4 = *(char **)v2;
v5 = strcmp(*(const char **)v2, a2);
if ( !v5 )
break;
v3 = v2;
if ( !*(_QWORD *)(v2 + 16) )
return (unsigned int)-1;
v2 = *(_QWORD *)(v2 + 16);
}
free(v4);
if ( v3 )
*(_QWORD *)(v3 + 16) = *(_QWORD *)(v2 + 16);
else
*(_QWORD *)(*a1 + 8 * v7) = *(_QWORD *)(v2 + 16);
free((void *)v2);
return v5;
}

original_code:
int hasht_remove(hasht_t* hasht, const char *key)
{
    hash_buckets_t* bucket;
    hash_buckets_t* prev_bucket = ((void *)0);
    size_t hash = hashfunc (key) % hasht->size;
    bucket = hasht->buckets[hash];
    while (bucket)
    {
        if(! strcmp (bucket->key, key))
        {
            free (bucket->key);
            if (prev_bucket) prev_bucket->next = bucket->next;
            else hasht->buckets[hash] = bucket->next;
            free (bucket);
            return 0;
        }
        else
        {
            prev_bucket = bucket;
            bucket = bucket->next;
        }
    }
    return -1;
}

canonical_original_code:
int hasht_remove(struct hasht_s *hasht, char *key)
{
    struct hash_buckets_s *bucket;
    struct hash_buckets_s *prev_bucket = ((void *)0);
    unsigned long hash = hashfunc (key) % hasht->size;
    bucket = hasht->buckets[hash];
    while (bucket)
    {
        if(! strcmp (bucket->key, key))
        {
            free (bucket->key);
            if (prev_bucket) prev_bucket->next = bucket->next;
            else hasht->buckets[hash] = bucket->next;
            free (bucket);
            return 0;
        }
        else
        {
            prev_bucket = bucket;
            bucket = bucket->next;
        }
    }
    return -1;
}

user_defined_types: struct hash_buckets_s { char *key; void *value; struct hash_buckets_s *next; }


decompiled_code:
__int64 __fastcall hasht_get(_QWORD *a1, char *a2)
{
__int64 v2; // rbx

v2 = *(_QWORD *)(*a1 + 8 * ((unsigned __int64)hashfunc(a2) % a1[1]));
if ( v2 )
{
while ( strcmp(*(const char **)v2, a2) )
{
v2 = *(_QWORD *)(v2 + 16);
if ( !v2 )
return v2;
}
v2 = *(_QWORD *)(v2 + 8);
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(_QWORD *a1, char *a2)
{
__int64 v2; // rbx

v2 = *(_QWORD *)(*a1 + 8 * ((unsigned __int64)func1(a2) % a1[1]));
if ( v2 )
{
while ( strcmp(*(const char **)v2, a2) )
{
v2 = *(_QWORD *)(v2 + 16);
if ( !v2 )
return v2;
}
v2 = *(_QWORD *)(v2 + 8);
}
return v2;
}

original_code:
void* hasht_get(hasht_t* hasht, const char *key)
{
    hash_buckets_t* bucket;
    size_t hash= hashfunc (key) % hasht->size;
    bucket = hasht->buckets[hash];
    while(bucket) {
        if(! strcmp (bucket->key, key))
        {
            return bucket->value;
        }
        bucket = bucket->next;
    }
    return ((void *)0);
}

canonical_original_code:
void *hasht_get(struct hasht_s *hasht, char *key)
{
    struct hash_buckets_s *bucket;
    unsigned long hash = hashfunc (key) % hasht->size;
    bucket = hasht->buckets[hash];
    while(bucket) {
        if(! strcmp (bucket->key, key))
        {
            return bucket->value;
        }
        bucket = bucket->next;
    }
    return ((void *)0);
}

return_type: void *


decompiled_code:
void __fastcall set_nonblocking(int fd)
{
unsigned int v1; // eax

v1 = fcntl(fd, 3);
if ( v1 == -1 )
{
perror("fcntl(F_GETFL)");
}
else if ( (v1 & 0x800) == 0 )
{
BYTE1(v1) |= 8u;
if ( fcntl(fd, 4, v1) == -1 )
perror("fcntl(F_SETFL)");
}
}

canonical_decompiled_code:
void __fastcall func1(int fd)
{
unsigned int v1; // eax

v1 = fcntl(fd, 3);
if ( v1 == -1 )
{
perror("fcntl(F_GETFL)");
}
else if ( (v1 & 0x800) == 0 )
{
BYTE1(v1) |= 8u;
if ( fcntl(fd, 4, v1) == -1 )
perror("fcntl(F_SETFL)");
}
}

original_code:
void set_nonblocking(int fd)
{
    int flags = fcntl(fd, 3);
    if (flags == -1)
    {
        perror ("fcntl(F_GETFL)");
    }
    if ((flags & 04000) == 04000)
    {
        return;
    }
    flags = fcntl(fd, 4, flags | 04000);
    if (flags == -1)
    {
        perror ("fcntl(F_SETFL)");
    }
}

variable_types: flags int


decompiled_code:
__int64 __fastcall init_net(__int64 a1, const char *a2)
{
int v2; // eax
struct addrinfo *v3; // rbx
int v4; // eax
unsigned int v5; // ebp
const char *v7; // rax
struct addrinfo *pai; // [rsp+8h] [rbp-50h] BYREF
struct addrinfo req; // [rsp+10h] [rbp-48h] BYREF

*(_QWORD *)&req.ai_flags = 1LL;
*(_QWORD *)&req.ai_socktype = 1LL;
*(_QWORD *)&req.ai_addrlen = 0LL;
req.ai_addr = 0LL;
req.ai_canonname = 0LL;
req.ai_next = 0LL;
v2 = getaddrinfo(0LL, a2, &req, &pai);
if ( v2 )
{
v7 = gai_strerror(v2);
fprintf(stderr, "getaddrinfo: %s\n", v7);
v5 = -1;
}
else
{
v3 = pai;
if ( pai )
{
while ( 1 )
{
v4 = socket(v3->ai_family, v3->ai_socktype, v3->ai_protocol);
v5 = v4;
if ( v4 != -1 )
break;
v3 = v3->ai_next;
if ( !v3 )
goto LABEL_9;
}
bind(v4, v3->ai_addr, v3->ai_addrlen);
freeaddrinfo(pai);
set_nonblocking(v5);
if ( listen(v5, 128) == -1 )
perror("listen error");
}
else
{
LABEL_9:
fwrite("Could not bind\n", 1uLL, 0xFuLL, stderr);
v5 = -1;
}
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const char *a2)
{
int v2; // eax
struct addrinfo *v3; // rbx
int v4; // eax
unsigned int v5; // ebp
const char *v7; // rax
struct addrinfo *pai; // [rsp+8h] [rbp-50h] BYREF
struct addrinfo req; // [rsp+10h] [rbp-48h] BYREF

*(_QWORD *)&req.ai_flags = 1LL;
*(_QWORD *)&req.ai_socktype = 1LL;
*(_QWORD *)&req.ai_addrlen = 0LL;
req.ai_addr = 0LL;
req.ai_canonname = 0LL;
req.ai_next = 0LL;
v2 = getaddrinfo(0LL, a2, &req, &pai);
if ( v2 )
{
v7 = gai_strerror(v2);
fprintf(stderr, "getaddrinfo: %s\n", v7);
v5 = -1;
}
else
{
v3 = pai;
if ( pai )
{
while ( 1 )
{
v4 = socket(v3->ai_family, v3->ai_socktype, v3->ai_protocol);
v5 = v4;
if ( v4 != -1 )
break;
v3 = v3->ai_next;
if ( !v3 )
goto LABEL_9;
}
bind(v4, v3->ai_addr, v3->ai_addrlen);
freeaddrinfo(pai);
func1(v5);
if ( listen(v5, 128) == -1 )
perror("listen error");
}
else
{
LABEL_9:
fwrite("Could not bind\n", 1uLL, 0xFuLL, stderr);
v5 = -1;
}
}
return v5;
}

original_code:
int init_net(struct addrinfo* res, char* port)
{
    int s;
    int sfd;
    struct addrinfo hints;
    struct addrinfo* res0;
    memset (&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = 0;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0x0001;
    if ((s = getaddrinfo(((void *)0), port, &hints, &res0)) != 0) {
        fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s));
        return -1;
    }
    for (res = res0; res != ((void *)0); res = res->ai_next)
    {
        sfd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sfd == -1)
            continue;
        if ((s = bind (sfd, res->ai_addr, res->ai_addrlen)) == 0);
        {
            break;
        }
        close (sfd);
    }
    if (res == ((void *)0))
    {
        fprintf (stderr, "Could not bind\n");
        return -1;
    }
    freeaddrinfo (res0);
    set_nonblocking (sfd);
    if ((s = listen (sfd, 128) == -1))
    {
        perror ("listen error");
    }
    return sfd;
}

canonical_original_code:
int init_net(struct addrinfo *res, char *port)
{
    int s;
    int sfd;
    struct addrinfo hints;
    struct addrinfo *res0;
    memset (&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = 0;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = 0x0001;
    if ((s = getaddrinfo(((void *)0), port, &hints, &res0)) != 0) {
        fprintf (stderr, "getaddrinfo: %s\n", gai_strerror (s));
        return -1;
    }
    for (res = res0; res != ((void *)0); res = res->ai_next)
    {
        sfd = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sfd == -1)
            continue;
        if ((s = bind (sfd, res->ai_addr, res->ai_addrlen)) == 0);
        {
            break;
        }
        close (sfd);
    }
    if (res == ((void *)0))
    {
        fprintf (stderr, "Could not bind\n");
        return -1;
    }
    freeaddrinfo (res0);
    set_nonblocking (sfd);
    if ((s = listen (sfd, 128) == -1))
    {
        perror ("listen error");
    }
    return sfd;
}

variable_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr { unsigned short sa_family; char sa_data[14]; } *ai_addr; char *ai_canonname; struct addrinfo *ai_next; } *

variable_types:
port
char *

user_defined_types: struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; unsigned int ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }


ConsoleReset

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

result = console_buffer;
console_buffer[0] = 0;
return result;
}

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

result = console_buffer;
console_buffer[0] = 0;
return result;
}

original_code:
void ConsoleReset(void)
{
    console_buffer[0] = '\0';
}

canonical_original_code:
void ConsoleReset()
{
    console_buffer[0] = '\0';
}


ConsolePrint

decompiled_code:
char *ConsolePrint(char *format, ...)
{
char v2[1032]; // [rsp+0h] [rbp-4D8h] BYREF
gcc_va_list arg; // [rsp+408h] [rbp-D0h] BYREF

va_start(arg, format);
vsnprintf(v2, 0x400uLL, format, arg);
return strcat(console_buffer, v2);
}

canonical_decompiled_code:
char *func1(char *format, ...)
{
char v2[1032]; // [rsp+0h] [rbp-4D8h] BYREF
gcc_va_list arg; // [rsp+408h] [rbp-D0h] BYREF

va_start(arg, format);
vsnprintf(v2, 0x400uLL, format, arg);
return strcat(console_buffer, v2);
}

original_code:
void ConsolePrint(const char * msg, ...)
{
    va_list args;
 char buffer[1024];
 __builtin_va_start(args,msg);
 vsnprintf(buffer, sizeof(buffer), msg, args);
 __builtin_va_end(args);
    strcat(console_buffer,buffer);
}

canonical_original_code:
void ConsolePrint(char *msg, ...)
{
    __builtin_va_list args;
 char buffer[1024];
 __builtin_va_start(args,msg);
 vsnprintf(buffer, sizeof(buffer), msg, args);
 __builtin_va_end(args);
    strcat(console_buffer,buffer);
}

variable_types:
msg
char *

variable_types:
buffer
char [1024]


ConsoleShow

decompiled_code:
int ConsoleShow()
{
return fprintf((FILE *)"error.log", console_buffer, 0LL);
}

canonical_decompiled_code:
int func2()
{
return fprintf((FILE *)"error.log", console_buffer, 0LL);
}

original_code:
void ConsoleShow(void)
{
 fprintf("error.log", console_buffer, ((void *)0));
}

canonical_original_code:
void ConsoleShow()
{
 fprintf("error.log", console_buffer, ((void *)0));
}


decompiled_code:
void __fastcall memset_rand(_BYTE *a1, int a2)
{
_BYTE *v2; // rbx

if ( a2 )
{
v2 = a1;
do
*v2++ = rand();
while ( v2 != &a1[a2 - 1 + 1] );
}
}

canonical_decompiled_code:
void __fastcall func3(_BYTE *a1, int a2)
{
_BYTE *v2; // rbx

if ( a2 )
{
v2 = a1;
do
*v2++ = rand();
while ( v2 != &a1[a2 - 1 + 1] );
}
}

original_code:
void memset_rand(u8 * start, u32 size)
{
 while(size--) *start++ = rand();
}

canonical_original_code:
void memset_rand(unsigned char *start, unsigned int size)
{
 while(size--) *start++ = rand();
}

variable_types:
start
unsigned char *

variable_types:
size
unsigned int


asciihextoint

decompiled_code:
__int64 __fastcall asciihextoint(char *a1)
{
const __int32_t *v1; // rsi
__int64 v2; // rdx
__int32_t v4; // eax

v1 = *_ctype_toupper_loc();
v2 = 0LL;
while ( 1 )
{
v4 = v1[*a1];
if ( !(_BYTE)v4 )
return v2;
if ( (unsigned __int8)(v4 - 48) > 9u )
break;
v2 = (char)v4 - 48 + 16 * v2;
LABEL_5:
++a1;
}
if ( (unsigned __int8)(v4 - 65) <= 5u )
{
v2 = 16 * v2 + (char)v4 - 55;
goto LABEL_5;
}
return -1LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *a1)
{
const __int32_t *v1; // rsi
__int64 v2; // rdx
__int32_t v4; // eax

v1 = *_ctype_toupper_loc();
v2 = 0LL;
while ( 1 )
{
v4 = v1[*a1];
if ( !(_BYTE)v4 )
return v2;
if ( (unsigned __int8)(v4 - 48) > 9u )
break;
v2 = (char)v4 - 48 + 16 * v2;
LABEL_5:
++a1;
}
if ( (unsigned __int8)(v4 - 65) <= 5u )
{
v2 = 16 * v2 + (char)v4 - 55;
goto LABEL_5;
}
return -1LL;
}

original_code:
u64 asciihextoint(const char * text)
{
    long int value = 0, i = 0;
    while(1)
    {
        char char_ = toupper(text[i++]);
        if(char_ == '\0') return value;
        else if(char_ >= '0' && char_ <= '9') value = (value <<4) + (char_ - '0');
        else if(char_ >= 'A' && char_ <= 'F') value = (value <<4) + (char_ - 'A' + 10);
        else return 0xFFFFFFFFFFFFFFFFULL;
    }
}

canonical_original_code:
unsigned long long asciihextoint(char *text)
{
    long value = 0; long i = 0;
    while(1)
    {
        char char_ = toupper(text[i++]);
        if(char_ == '\0') return value;
        else if(char_ >= '0' && char_ <= '9') value = (value <<4) + (char_ - '0');
        else if(char_ >= 'A' && char_ <= 'F') value = (value <<4) + (char_ - 'A' + 10);
        else return 0xFFFFFFFFFFFFFFFFULL;
    }
}

variable_types:
text
char *

variable_types: value long

variable_types: i long

return_type: unsigned long long


asciidectoint

decompiled_code:
__int64 __fastcall asciidectoint(char *a1)
{
const __int32_t *v1; // rsi
__int64 i; // rdx
__int32_t v4; // eax

v1 = *_ctype_toupper_loc();
for ( i = 0LL; ; i = (char)v4 - 48 + 10 * i )
{
v4 = v1[*a1];
if ( !(_BYTE)v4 )
return i;
++a1;
if ( (unsigned __int8)(v4 - 48) > 9u )
break;
}
return -1LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *a1)
{
const __int32_t *v1; // rsi
__int64 i; // rdx
__int32_t v4; // eax

v1 = *_ctype_toupper_loc();
for ( i = 0LL; ; i = (char)v4 - 48 + 10 * i )
{
v4 = v1[*a1];
if ( !(_BYTE)v4 )
return i;
++a1;
if ( (unsigned __int8)(v4 - 48) > 9u )
break;
}
return -1LL;
}

original_code:
u64 asciidectoint(const char * text)
{
    long int value = 0, i = 0;
    while(1)
    {
        char char_ = toupper(text[i++]);
        if(char_ == '\0') return value;
        else if(char_ >= '0' && char_ <= '9') value = (value*10) + (char_ - '0');
        else return 0xFFFFFFFFFFFFFFFFULL;
    }
}

canonical_original_code:
unsigned long long asciidectoint(char *text)
{
    long value = 0; long i = 0;
    while(1)
    {
        char char_ = toupper(text[i++]);
        if(char_ == '\0') return value;
        else if(char_ >= '0' && char_ <= '9') value = (value*10) + (char_ - '0');
        else return 0xFFFFFFFFFFFFFFFFULL;
    }
}


DebugMessage

decompiled_code:
int DebugMessage(char *format, ...)
{
_DWORD *v1; // rax
char v3[1032]; // [rsp+0h] [rbp-4D8h] BYREF
gcc_va_list arg; // [rsp+408h] [rbp-D0h] BYREF

va_start(arg, format);
vsnprintf(v3, 0x400uLL, format, arg);
v1 = &EmulatorConfig;
if ( EmulatorConfig )
{
MESSAGE_SHOWING = 1;
LODWORD(v1) = fprintf((FILE *)"debug.log", v3, "debug");
MESSAGE_SHOWING = 0;
}
return (int)v1;
}

canonical_decompiled_code:
int func6(char *format, ...)
{
_DWORD *v1; // rax
char v3[1032]; // [rsp+0h] [rbp-4D8h] BYREF
gcc_va_list arg; // [rsp+408h] [rbp-D0h] BYREF

va_start(arg, format);
vsnprintf(v3, 0x400uLL, format, arg);
v1 = &EmulatorConfig;
if ( EmulatorConfig )
{
MESSAGE_SHOWING = 1;
LODWORD(v1) = fprintf((FILE *)"debug.log", v3, "debug");
MESSAGE_SHOWING = 0;
}
return (int)v1;
}

original_code:
void DebugMessage(const char * msg, ...)
{
    va_list args;
 char buffer[1024];
 __builtin_va_start(args,msg);
 vsnprintf(buffer, sizeof(buffer), msg, args);
 __builtin_va_end(args);
    if(EmulatorConfig.debug_msg_enable) {
        MESSAGE_SHOWING = 1;
        fprintf("debug.log", buffer, "debug");
        MESSAGE_SHOWING = 0;
    }
}

canonical_original_code:
void DebugMessage(char *msg, ...)
{
    __builtin_va_list args;
 char buffer[1024];
 __builtin_va_start(args,msg);
 vsnprintf(buffer, sizeof(buffer), msg, args);
 __builtin_va_end(args);
    if(EmulatorConfig.debug_msg_enable) {
        MESSAGE_SHOWING = 1;
        fprintf("debug.log", buffer, "debug");
        MESSAGE_SHOWING = 0;
    }
}


ErrorMessage

decompiled_code:
_DWORD *ErrorMessage(char *format, ...)
{
_DWORD *result; // rax
char v2[1032]; // [rsp+0h] [rbp-4D8h] BYREF
gcc_va_list arg; // [rsp+408h] [rbp-D0h] BYREF

va_start(arg, format);
vsnprintf(v2, 0x400uLL, format, arg);
result = MESSAGE_SHOWING;
MESSAGE_SHOWING[0] = 0;
return result;
}

canonical_decompiled_code:
_DWORD *func7(char *format, ...)
{
_DWORD *result; // rax
char v2[1032]; // [rsp+0h] [rbp-4D8h] BYREF
gcc_va_list arg; // [rsp+408h] [rbp-D0h] BYREF

va_start(arg, format);
vsnprintf(v2, 0x400uLL, format, arg);
result = MESSAGE_SHOWING;
MESSAGE_SHOWING[0] = 0;
return result;
}

original_code:
void ErrorMessage(const char * msg, ...)
{
    va_list args;
 char buffer[1024];
 __builtin_va_start(args,msg);
 vsnprintf(buffer, sizeof(buffer), msg, args);
 __builtin_va_end(args);
    MESSAGE_SHOWING = 1;
    MESSAGE_SHOWING = 0;
}

canonical_original_code:
void ErrorMessage(char *msg, ...)
{
    __builtin_va_list args;
 char buffer[1024];
 __builtin_va_start(args,msg);
 vsnprintf(buffer, sizeof(buffer), msg, args);
 __builtin_va_end(args);
    MESSAGE_SHOWING = 1;
    MESSAGE_SHOWING = 0;
}


original_code:
void GBA_CPUChangeMode(u32 value)
{
    static const u32 mode_value[CPU_MODE_NUMBER] = {
        (0x10),(0x11),(0x12),(0x13),(0x17),(0x1B),(0x1F)
    };
    if(mode_value[CPU.MODE] == value) return;
    switch(CPU.MODE)
    {
        case CPU_USER: case CPU_SYSTEM:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R_user[i] = CPU.R[i+8];
            break;
        }
        case CPU_FIQ:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R_fiq[i] = CPU.R[i+8];
            CPU.SPSR_fiq = CPU.SPSR;
            break;
        }
        case CPU_SUPERVISOR:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_svc = CPU.R[13];
            CPU.R14_svc = CPU.R[14];
            CPU.SPSR_svc = CPU.SPSR;
            break;
        }
        case CPU_ABORT:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_abt = CPU.R[13];
            CPU.R14_abt = CPU.R[14];
            CPU.SPSR_abt = CPU.SPSR;
            break;
        }
        case CPU_IRQ:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_irq = CPU.R[13];
            CPU.R14_irq = CPU.R[14];
            CPU.SPSR_irq = CPU.SPSR;
            break;
        }
        case CPU_UNDEFINED:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_und = CPU.R[13];
            CPU.R14_und = CPU.R[14];
            CPU.SPSR_und = CPU.SPSR;
            break;
        }
        default:
            return;
    }
    if(value == mode_value[CPU_USER]) CPU.MODE = CPU_USER;
    else if(value == mode_value[CPU_FIQ]) CPU.MODE = CPU_FIQ;
    else if(value == mode_value[CPU_IRQ]) CPU.MODE = CPU_IRQ;
    else if(value == mode_value[CPU_SUPERVISOR]) CPU.MODE = CPU_SUPERVISOR;
    else if(value == mode_value[CPU_ABORT]) CPU.MODE = CPU_ABORT;
    else if(value == mode_value[CPU_UNDEFINED]) CPU.MODE = CPU_UNDEFINED;
    else if(value == mode_value[CPU_SYSTEM]) CPU.MODE = CPU_SYSTEM;
    else
    {
        DebugMessage("Trying to change to CPU mode 0x%02X (invalid).",value);
        GBA_ExecutionBreak();
        return;
    }
    switch(CPU.MODE)
    {
        case CPU_USER: case CPU_SYSTEM:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R[i+8] = CPU.R_user[i];
            break;
        }
        case CPU_FIQ:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R[i+8] = CPU.R_fiq[i];
            CPU.SPSR = CPU.SPSR_fiq;
            break;
        }
        case CPU_SUPERVISOR:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_svc;
            CPU.R[14] = CPU.R14_svc;
            CPU.SPSR = CPU.SPSR_svc;
            break;
        }
        case CPU_ABORT:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_abt;
            CPU.R[14] = CPU.R14_abt;
            CPU.SPSR = CPU.SPSR_abt;
            break;
        }
        case CPU_IRQ:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_irq;
            CPU.R[14] = CPU.R14_irq;
            CPU.SPSR = CPU.SPSR_irq;
            break;
        }
        case CPU_UNDEFINED:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_und;
            CPU.R[14] = CPU.R14_und;
            CPU.SPSR = CPU.SPSR_und;
            break;
        }
        default:
            return;
    }
    return;
}

canonical_original_code:
void GBA_CPUChangeMode(unsigned int value)
{
    static unsigned int mode_value[-1] = {
        (0x10),(0x11),(0x12),(0x13),(0x17),(0x1B),(0x1F)
    };
    if(mode_value[CPU.MODE] == value) return;
    switch(CPU.MODE)
    {
        case CPU_USER: case CPU_SYSTEM:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R_user[i] = CPU.R[i+8];
            break;
        }
        case CPU_FIQ:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R_fiq[i] = CPU.R[i+8];
            CPU.SPSR_fiq = CPU.SPSR;
            break;
        }
        case CPU_SUPERVISOR:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_svc = CPU.R[13];
            CPU.R14_svc = CPU.R[14];
            CPU.SPSR_svc = CPU.SPSR;
            break;
        }
        case CPU_ABORT:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_abt = CPU.R[13];
            CPU.R14_abt = CPU.R[14];
            CPU.SPSR_abt = CPU.SPSR;
            break;
        }
        case CPU_IRQ:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_irq = CPU.R[13];
            CPU.R14_irq = CPU.R[14];
            CPU.SPSR_irq = CPU.SPSR;
            break;
        }
        case CPU_UNDEFINED:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R_user[i] = CPU.R[i+8];
            CPU.R13_und = CPU.R[13];
            CPU.R14_und = CPU.R[14];
            CPU.SPSR_und = CPU.SPSR;
            break;
        }
        default:
            return;
    }
    if(value == mode_value[CPU_USER]) CPU.MODE = CPU_USER;
    else if(value == mode_value[CPU_FIQ]) CPU.MODE = CPU_FIQ;
    else if(value == mode_value[CPU_IRQ]) CPU.MODE = CPU_IRQ;
    else if(value == mode_value[CPU_SUPERVISOR]) CPU.MODE = CPU_SUPERVISOR;
    else if(value == mode_value[CPU_ABORT]) CPU.MODE = CPU_ABORT;
    else if(value == mode_value[CPU_UNDEFINED]) CPU.MODE = CPU_UNDEFINED;
    else if(value == mode_value[CPU_SYSTEM]) CPU.MODE = CPU_SYSTEM;
    else
    {
        DebugMessage("Trying to change to CPU mode 0x%02X (invalid).",value);
        GBA_ExecutionBreak();
        return;
    }
    switch(CPU.MODE)
    {
        case CPU_USER: case CPU_SYSTEM:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R[i+8] = CPU.R_user[i];
            break;
        }
        case CPU_FIQ:
        {
            int i;
            for(i = 0; i < 7; i++) CPU.R[i+8] = CPU.R_fiq[i];
            CPU.SPSR = CPU.SPSR_fiq;
            break;
        }
        case CPU_SUPERVISOR:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_svc;
            CPU.R[14] = CPU.R14_svc;
            CPU.SPSR = CPU.SPSR_svc;
            break;
        }
        case CPU_ABORT:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_abt;
            CPU.R[14] = CPU.R14_abt;
            CPU.SPSR = CPU.SPSR_abt;
            break;
        }
        case CPU_IRQ:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_irq;
            CPU.R[14] = CPU.R14_irq;
            CPU.SPSR = CPU.SPSR_irq;
            break;
        }
        case CPU_UNDEFINED:
        {
            int i;
            for(i = 0; i < 5; i++) CPU.R[i+8] = CPU.R_user[i];
            CPU.R[13] = CPU.R13_und;
            CPU.R[14] = CPU.R14_und;
            CPU.SPSR = CPU.SPSR_und;
            break;
        }
        default:
            return;
    }
    return;
}

variable_types:
value
unsigned int

variable_types: i int


decompiled_code:
__int64 retro_api_version()
{
return 1LL;
}

canonical_decompiled_code:
__int64 func1()
{
return 1LL;
}

original_code: unsigned retro_api_version(void) { return 1; }

canonical_original_code: unsigned int retro_api_version() { return 1; }

return_type: unsigned int


decompiled_code:
void retro_set_video_refresh()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code: void retro_set_video_refresh(retro_video_refresh_t cb) { video_cb = cb; }

canonical_original_code: void retro_set_video_refresh(void (*cb)(void *data, unsigned int width, unsigned int height, unsigned long pitch)) { video_cb = cb; }

variable_types: void (*)(void *data, unsigned int width, unsigned int height, unsigned long pitch)


decompiled_code:
void retro_set_audio_sample()
{
;
}

canonical_decompiled_code:
void func3()
{
;
}

original_code: void retro_set_audio_sample(retro_audio_sample_t cb) { (void)cb; }

canonical_original_code: void retro_set_audio_sample(void (*cb)(short left, short right)) { (void)cb; }

variable_types:
cb
void (*)(short left, short right)


decompiled_code:
void retro_set_audio_sample_batch()
{
;
}

canonical_decompiled_code:
void func4()
{
;
}

original_code: void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { audio_batch_cb = cb; }

canonical_original_code: void retro_set_audio_sample_batch(unsigned long (*cb)(short *data, unsigned long frames)) { audio_batch_cb = cb; }

variable_types: unsigned long (*)(short *data, unsigned long frames)


decompiled_code:
void retro_set_input_poll()
{
;
}

canonical_decompiled_code:
void func5()
{
;
}

original_code: void retro_set_input_poll(retro_input_poll_t cb) { input_poll_cb = cb; }

canonical_original_code: void retro_set_input_poll(void (*cb)()) { input_poll_cb = cb; }

variable_types:
cb
void (*)()


decompiled_code:
void retro_set_input_state()
{
;
}

canonical_decompiled_code:
void func6()
{
;
}

original_code: void retro_set_input_state(retro_input_state_t cb) { input_state_cb = cb; }

canonical_original_code: void retro_set_input_state(short (*cb)(unsigned int port, unsigned int device, unsigned int index, unsigned int id)) { input_state_cb = cb; }

variable_types: short (*)(unsigned int port, unsigned int device, unsigned int index, unsigned int id)


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

*(_QWORD *)a1 = "Giibii Advance";
*(_QWORD *)(a1 + 8) = "v1.0.0";
result = "gba|bin|agp";
*(_QWORD *)(a1 + 16) = "gba|bin|agp";
*(_BYTE *)(a1 + 25) = 0;
*(_BYTE *)(a1 + 24) = 1;
return result;
}

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

*(_QWORD *)a1 = "Giibii Advance";
*(_QWORD *)(a1 + 8) = "v1.0.0";
result = "gba|bin|agp";
*(_QWORD *)(a1 + 16) = "gba|bin|agp";
*(_BYTE *)(a1 + 25) = 0;
*(_BYTE *)(a1 + 24) = 1;
return result;
}

original_code:
void retro_get_system_info(struct retro_system_info *info)
{
 info->library_name = "Giibii Advance";
 info->library_version = "v1.0.0";
 info->valid_extensions = "gba|bin|agp";
 info->block_extract = 0;
 info->need_fullpath = 1;
}

variable_types: struct retro_system_info { char *library_name; char *library_version; char *valid_extensions; _Bool need_fullpath; _Bool block_extract; } *


decompiled_code:
__int64 __fastcall retro_load_game(const char **a1)
{
__int64 v1; // rdx
char *v3; // [rsp+8h] [rbp-10h] BYREF

extract_directory(g_rom_dir, *a1, 1024LL);
if ( !(unsigned __int8)extract_directory((char *)&loc_9, (const char *)&v3, v1) || !v3 )
{
fprintf(stderr, "[giibiiadvance]: Defaulting system directory to %s.\n", g_rom_dir);
v3 = g_rom_dir;
}
snprintf("/", 2uLL, "%s", g_rom_dir);
init_audio();
system_init();
return system_reset();
}

canonical_decompiled_code:
__int64 __fastcall func9(const char **a1)
{
__int64 v1; // rdx
char *v3; // [rsp+8h] [rbp-10h] BYREF

func0(g_rom_dir, *a1, 1024LL);
if ( !(unsigned __int8)func0((char *)&loc_9, (const char *)&v3, v1) || !v3 )
{
fprintf(stderr, "[giibiiadvance]: Defaulting system directory to %s.\n", g_rom_dir);
v3 = g_rom_dir;
}
snprintf("/", 2uLL, "%s", g_rom_dir);
init_audio();
system_init();
return system_reset();
}

original_code:
_Bool retro_load_game(const struct retro_game_info *info)
{
 const char *full_path;
 const char *dir;
 char slash;
 extract_directory(g_rom_dir, info->path, sizeof(g_rom_dir));
 if (!environ_cb(9, &dir) || !dir)
 {
  fprintf(stderr, "[giibiiadvance]: Defaulting system directory to %s.\n", g_rom_dir);
  dir = g_rom_dir;
 }
 slash = '/';
 snprintf("/", sizeof("/"), "%s", g_rom_dir);
 full_path = info->path;
 init_audio();
 system_init();
 system_reset();
}

canonical_original_code:
_Bool retro_load_game(struct retro_game_info *info)
{
 char *full_path;
 char *dir;
 char slash;
 extract_directory(g_rom_dir, info->path, sizeof(g_rom_dir));
 if (!environ_cb(9, &dir) || !dir)
 {
  fprintf(stderr, "[giibiiadvance]: Defaulting system directory to %s.\n", g_rom_dir);
  dir = g_rom_dir;
 }
 slash = '/';
 snprintf("/", sizeof("/"), "%s", g_rom_dir);
 full_path = info->path;
 init_audio();
 system_init();
 system_reset();
}

variable_types: struct retro_game_info { char *path; void *data; unsigned long size; char *meta; } *

variable_types:
dir
char *

variable_types: slash char


decompiled_code:
void retro_deinit()
{
;
}

canonical_decompiled_code:
void func11()
{
;
}

original_code:
void retro_deinit(void)
{
}

canonical_original_code:
void retro_deinit()
{
}


decompiled_code:
__int64 retro_reset()
{
return system_reset();
}

canonical_decompiled_code:
__int64 func12()
{
return system_reset();
}

original_code: void retro_reset(void) { system_reset(); }

canonical_original_code: void retro_reset() { system_reset(); }


decompiled_code:
void retro_run()
{
;
}

canonical_decompiled_code:
void func13()
{
;
}

original_code:
void retro_run(void)
{
}

canonical_original_code:
void retro_run()
{
}


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

result = (unsigned int)inited;
if ( inited )
{
if ( a1 )
GBA_SaveWriteFile();
GBA_MemoryEnd();
inited = 0;
result = 1LL;
}
return result;
}

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

result = (unsigned int)inited;
if ( inited )
{
if ( a1 )
GBA_SaveWriteFile();
GBA_MemoryEnd();
inited = 0;
result = 1LL;
}
return result;
}

original_code:
int GBA_EndRom(int save)
{
    if(inited == 0) return 0;
    if(save) GBA_SaveWriteFile();
    GBA_MemoryEnd();
    inited = 0;
    return 1;
}

variable_types: save int


decompiled_code:
__int64 __fastcall GBA_InitRom(__int64 a1, __int64 a2, unsigned int a3)
{
if ( inited )
GBA_EndRom(1);
if ( a3 > 0x2000000 )
{
ErrorMessage("Rom too big!\nSize = 0x%08X bytes\nMax = 0x02000000 bytes", a3);
GBA_ROM_SIZE = 0x2000000;
}
else
{
GBA_ROM_SIZE = a3;
}
GBA_DetectSaveType(a2, a3);
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
GBA_HeaderCheck(a2);
GBA_CPUInit();
GBA_InterruptInit();
GBA_TimerInitAll();
GBA_MemoryInit(a1, a2, GBA_ROM_SIZE);
GBA_UpdateDrawScanlineFn();
GBA_DMA0Setup();
GBA_DMA1Setup();
GBA_DMA2Setup();
GBA_DMA3Setup();
GBA_SoundInit();
GBA_FillFadeTables();
clocks = 1;
lastresidualclocks = 0;
inited = 1;
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2, unsigned int a3)
{
if ( inited )
func4(1);
if ( a3 > 0x2000000 )
{
ErrorMessage("Rom too big!\nSize = 0x%08X bytes\nMax = 0x02000000 bytes", a3);
GBA_ROM_SIZE = 0x2000000;
}
else
{
GBA_ROM_SIZE = a3;
}
GBA_DetectSaveType(a2, a3);
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
GBA_HeaderCheck(a2);
GBA_CPUInit();
GBA_InterruptInit();
GBA_TimerInitAll();
GBA_MemoryInit(a1, a2, GBA_ROM_SIZE);
GBA_UpdateDrawScanlineFn();
GBA_DMA0Setup();
GBA_DMA1Setup();
GBA_DMA2Setup();
GBA_DMA3Setup();
GBA_SoundInit();
GBA_FillFadeTables();
clocks = 1;
lastresidualclocks = 0;
inited = 1;
return 1LL;
}

original_code:
int GBA_InitRom(void * bios_ptr, void * rom_ptr, u32 romsize)
{
    if(inited) GBA_EndRom(1);
    if(romsize > 0x02000000)
    {
        ErrorMessage("Rom too big!\nSize = 0x%08X bytes\nMax = 0x02000000 bytes",romsize);
        GBA_ROM_SIZE = 0x02000000;
    }
    else
    {
        GBA_ROM_SIZE = romsize;
    }
    GBA_DetectSaveType(rom_ptr,romsize);
    GBA_ResetSaveBuffer();
    GBA_SaveReadFile();
    GBA_HeaderCheck(rom_ptr);
    GBA_CPUInit();
    GBA_InterruptInit();
    GBA_TimerInitAll();
    GBA_MemoryInit(bios_ptr,rom_ptr,GBA_ROM_SIZE);
    GBA_UpdateDrawScanlineFn();
    GBA_DMA0Setup();
    GBA_DMA1Setup();
    GBA_DMA2Setup();
    GBA_DMA3Setup();
    GBA_SoundInit();
    GBA_FillFadeTables();
    clocks = 1;
    lastresidualclocks = 0;
    inited = 1;
    return 1;
}

canonical_original_code:
int GBA_InitRom(void *bios_ptr, void *rom_ptr, unsigned int romsize)
{
    if(inited) GBA_EndRom(1);
    if(romsize > 0x02000000)
    {
        ErrorMessage("Rom too big!\nSize = 0x%08X bytes\nMax = 0x02000000 bytes",romsize);
        GBA_ROM_SIZE = 0x02000000;
    }
    else
    {
        GBA_ROM_SIZE = romsize;
    }
    GBA_DetectSaveType(rom_ptr,romsize);
    GBA_ResetSaveBuffer();
    GBA_SaveReadFile();
    GBA_HeaderCheck(rom_ptr);
    GBA_CPUInit();
    GBA_InterruptInit();
    GBA_TimerInitAll();
    GBA_MemoryInit(bios_ptr,rom_ptr,GBA_ROM_SIZE);
    GBA_UpdateDrawScanlineFn();
    GBA_DMA0Setup();
    GBA_DMA1Setup();
    GBA_DMA2Setup();
    GBA_DMA3Setup();
    GBA_SoundInit();
    GBA_FillFadeTables();
    clocks = 1;
    lastresidualclocks = 0;
    inited = 1;
    return 1;
}

variable_types:
romsize
unsigned int


decompiled_code:
__int64 GBA_Reset()
{
GBA_CPUClearHalted();
return GBA_Swi(38LL);
}

canonical_decompiled_code:
__int64 func6()
{
GBA_CPUClearHalted();
return GBA_Swi(38LL);
}

original_code:
void GBA_Reset(void)
{
    GBA_CPUClearHalted();
    GBA_Swi(0x26);
}

canonical_original_code:
void GBA_Reset()
{
    GBA_CPUClearHalted();
    GBA_Swi(0x26);
}


decompiled_code:
__int64 __fastcall GBA_RunFor(int a1)
{
int v1; // ebp
unsigned int v2; // er13
int v3; // ebx
unsigned int v4; // er13
int v5; // ebx
unsigned int v6; // ebx
unsigned int v7; // er14
unsigned int v8; // eax
unsigned int v9; // er14
unsigned int v10; // eax
unsigned int v11; // er14
unsigned int v12; // eax
int v13; // ebx
int v14; // ebx
unsigned int v15; // er12
int v16; // ebx
unsigned int v17; // ebx
unsigned int v18; // er12
unsigned int v19; // eax
unsigned int v20; // er12
unsigned int v21; // eax
unsigned int v22; // er12
unsigned int v23; // eax
int v24; // eax

v1 = lastresidualclocks + a1;
if ( lastresidualclocks + a1 < clocks )
{
v2 = 0;
}
else
{
v2 = 0;
do
{
if ( (unsigned int)GBA_DMAisWorking() )
{
v13 = clocks;
v6 = v13 - GBA_DMAGetExtraClocksElapsed();
}
else
{
if ( (unsigned int)GBA_InterruptCheck() )
{
v3 = GBA_MemoryGetAccessCycles(0, 1, CPU[18]);
v4 = CPU[15];
v5 = GBA_MemoryGetAccessCyclesNoSeq(1, v4) + v3;
v6 = GBA_MemoryGetAccessCyclesSeq(1, v4) + v5;
}
else
{
v6 = clocks - GBA_Execute((unsigned int)clocks);
}
v2 = 1;
}
v7 = GBA_UpdateScreenTimings(v6);
clocks = v7;
v8 = GBA_DMAUpdate(v6);
v9 = min(v8, v7);
clocks = v9;
v10 = GBA_TimersUpdate(v6);
v11 = min(v10, v9);
clocks = v11;
v12 = GBA_SoundUpdate(v6);
clocks = min(v12, v11);
v1 -= v6;
}
while ( clocks <= v1 );
}
for ( ; v1 > 0; clocks = min(v23, v22) )
{
if ( (unsigned int)GBA_DMAisWorking() )
{
v17 = v1 - GBA_DMAGetExtraClocksElapsed();
v1 = GBA_DMAGetExtraClocksElapsed();
}
else
{
if ( (unsigned int)GBA_InterruptCheck() )
{
v14 = GBA_MemoryGetAccessCycles(0, 1, CPU[18]);
v15 = CPU[15];
v16 = GBA_MemoryGetAccessCyclesNoSeq(1, v15) + v14;
v17 = GBA_MemoryGetAccessCyclesSeq(1, v15) + v16;
v1 -= v17;
}
else
{
v24 = GBA_Execute((unsigned int)v1);
v17 = v1 - v24;
v1 = v24;
}
v2 = 1;
}
v18 = GBA_UpdateScreenTimings(v17);
clocks = v18;
v19 = GBA_DMAUpdate(v17);
v20 = min(v19, v18);
clocks = v20;
v21 = GBA_TimersUpdate(v17);
v22 = min(v21, v20);
clocks = v22;
v23 = GBA_SoundUpdate(v17);
}
lastresidualclocks = v1;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(int a1)
{
int v1; // ebp
unsigned int v2; // er13
int v3; // ebx
unsigned int v4; // er13
int v5; // ebx
unsigned int v6; // ebx
unsigned int v7; // er14
unsigned int v8; // eax
unsigned int v9; // er14
unsigned int v10; // eax
unsigned int v11; // er14
unsigned int v12; // eax
int v13; // ebx
int v14; // ebx
unsigned int v15; // er12
int v16; // ebx
unsigned int v17; // ebx
unsigned int v18; // er12
unsigned int v19; // eax
unsigned int v20; // er12
unsigned int v21; // eax
unsigned int v22; // er12
unsigned int v23; // eax
int v24; // eax

v1 = lastresidualclocks + a1;
if ( lastresidualclocks + a1 < clocks )
{
v2 = 0;
}
else
{
v2 = 0;
do
{
if ( (unsigned int)GBA_DMAisWorking() )
{
v13 = clocks;
v6 = v13 - GBA_DMAGetExtraClocksElapsed();
}
else
{
if ( (unsigned int)GBA_InterruptCheck() )
{
v3 = func0(0, 1, CPU[18]);
v4 = CPU[15];
v5 = func1(1, v4) + v3;
v6 = func2(1, v4) + v5;
}
else
{
v6 = clocks - GBA_Execute((unsigned int)clocks);
}
v2 = 1;
}
v7 = GBA_UpdateScreenTimings(v6);
clocks = v7;
v8 = GBA_DMAUpdate(v6);
v9 = func3(v8, v7);
clocks = v9;
v10 = GBA_TimersUpdate(v6);
v11 = func3(v10, v9);
clocks = v11;
v12 = GBA_SoundUpdate(v6);
clocks = func3(v12, v11);
v1 -= v6;
}
while ( clocks <= v1 );
}
for ( ; v1 > 0; clocks = func3(v23, v22) )
{
if ( (unsigned int)GBA_DMAisWorking() )
{
v17 = v1 - GBA_DMAGetExtraClocksElapsed();
v1 = GBA_DMAGetExtraClocksElapsed();
}
else
{
if ( (unsigned int)GBA_InterruptCheck() )
{
v14 = func0(0, 1, CPU[18]);
v15 = CPU[15];
v16 = func1(1, v15) + v14;
v17 = func2(1, v15) + v16;
v1 -= v17;
}
else
{
v24 = GBA_Execute((unsigned int)v1);
v17 = v1 - v24;
v1 = v24;
}
v2 = 1;
}
v18 = GBA_UpdateScreenTimings(v17);
clocks = v18;
v19 = GBA_DMAUpdate(v17);
v20 = func3(v19, v18);
clocks = v20;
v21 = GBA_TimersUpdate(v17);
v22 = func3(v21, v20);
clocks = v22;
v23 = GBA_SoundUpdate(v17);
}
lastresidualclocks = v1;
return v2;
}

original_code:
u32 GBA_RunFor(s32 totalclocks)
{
    s32 residualclocks, executedclocks;
    totalclocks += lastresidualclocks;
    u32 has_executed = 0;
    while(totalclocks >= clocks)
    {
        if(GBA_DMAisWorking())
        {
            executedclocks = clocks - GBA_DMAGetExtraClocksElapsed();
        }
        else
        {
            has_executed = 1;
            if(GBA_InterruptCheck())
            {
                executedclocks = GBA_MemoryGetAccessCycles(0,1,CPU.OldPC) + GBA_MemoryGetAccessCyclesNoSeq(1,CPU.R[(15)]) +
                        GBA_MemoryGetAccessCyclesSeq(1,CPU.R[(15)]);
            }
            else
            {
                residualclocks = GBA_Execute(clocks);
                executedclocks = clocks-residualclocks;
            }
        }
        clocks = GBA_UpdateScreenTimings(executedclocks);
        clocks = min(GBA_DMAUpdate(executedclocks),clocks);
        clocks = min(GBA_TimersUpdate(executedclocks),clocks);
        clocks = min(GBA_SoundUpdate(executedclocks),clocks);
        totalclocks -= executedclocks;
    }
    while(totalclocks > 0)
    {
        if(GBA_DMAisWorking())
        {
            executedclocks = totalclocks - GBA_DMAGetExtraClocksElapsed();
            totalclocks = GBA_DMAGetExtraClocksElapsed();
        }
        else
        {
            has_executed = 1;
            if(GBA_InterruptCheck())
            {
                executedclocks = GBA_MemoryGetAccessCycles(0,1,CPU.OldPC) + GBA_MemoryGetAccessCyclesNoSeq(1,CPU.R[(15)]) +
                        GBA_MemoryGetAccessCyclesSeq(1,CPU.R[(15)]);
                residualclocks = totalclocks - executedclocks;
            }
            else
            {
                residualclocks = GBA_Execute(totalclocks);
                executedclocks = totalclocks-residualclocks;
            }
            totalclocks = residualclocks;
        }
        clocks = GBA_UpdateScreenTimings(executedclocks);
        clocks = min(GBA_DMAUpdate(executedclocks),clocks);
        clocks = min(GBA_TimersUpdate(executedclocks),clocks);
        clocks = min(GBA_SoundUpdate(executedclocks),clocks);
    }
    lastresidualclocks = totalclocks;
    return has_executed;
}

canonical_original_code:
unsigned int GBA_RunFor(int totalclocks)
{
    int residualclocks; int executedclocks;
    totalclocks += lastresidualclocks;
    unsigned int has_executed = 0;
    while(totalclocks >= clocks)
    {
        if(GBA_DMAisWorking())
        {
            executedclocks = clocks - GBA_DMAGetExtraClocksElapsed();
        }
        else
        {
            has_executed = 1;
            if(GBA_InterruptCheck())
            {
                executedclocks = GBA_MemoryGetAccessCycles(0,1,CPU.OldPC) + GBA_MemoryGetAccessCyclesNoSeq(1,CPU.R[(15)]) +
                        GBA_MemoryGetAccessCyclesSeq(1,CPU.R[(15)]);
            }
            else
            {
                residualclocks = GBA_Execute(clocks);
                executedclocks = clocks-residualclocks;
            }
        }
        clocks = GBA_UpdateScreenTimings(executedclocks);
        clocks = min(GBA_DMAUpdate(executedclocks),clocks);
        clocks = min(GBA_TimersUpdate(executedclocks),clocks);
        clocks = min(GBA_SoundUpdate(executedclocks),clocks);
        totalclocks -= executedclocks;
    }
    while(totalclocks > 0)
    {
        if(GBA_DMAisWorking())
        {
            executedclocks = totalclocks - GBA_DMAGetExtraClocksElapsed();
            totalclocks = GBA_DMAGetExtraClocksElapsed();
        }
        else
        {
            has_executed = 1;
            if(GBA_InterruptCheck())
            {
                executedclocks = GBA_MemoryGetAccessCycles(0,1,CPU.OldPC) + GBA_MemoryGetAccessCyclesNoSeq(1,CPU.R[(15)]) +
                        GBA_MemoryGetAccessCyclesSeq(1,CPU.R[(15)]);
                residualclocks = totalclocks - executedclocks;
            }
            else
            {
                residualclocks = GBA_Execute(totalclocks);
                executedclocks = totalclocks-residualclocks;
            }
            totalclocks = residualclocks;
        }
        clocks = GBA_UpdateScreenTimings(executedclocks);
        clocks = min(GBA_DMAUpdate(executedclocks),clocks);
        clocks = min(GBA_TimersUpdate(executedclocks),clocks);
        clocks = min(GBA_SoundUpdate(executedclocks),clocks);
    }
    lastresidualclocks = totalclocks;
    return has_executed;
}

variable_types: totalclocks int

variable_types: residualclocks int

variable_types: executedclocks int


decompiled_code:
__int64 GBA_DebugStep()
{
int i; // ebx
__int64 result; // rax

for ( i = 1000000; ; --i )
{
while ( (unsigned int)GBA_RunFor(1) )
{
result = GBA_CPUGetHalted();
if ( !(_DWORD)result )
return result;
}
result = (unsigned int)(i - 1);
if ( i <= 0 )
break;
}
return result;
}

canonical_decompiled_code:
__int64 func8()
{
int i; // ebx
__int64 result; // rax

for ( i = 1000000; ; --i )
{
while ( (unsigned int)func7(1) )
{
result = GBA_CPUGetHalted();
if ( !(_DWORD)result )
return result;
}
result = (unsigned int)(i - 1);
if ( i <= 0 )
break;
}
return result;
}

original_code:
void GBA_DebugStep(void)
{
    int clockstostop = 1000000;
    do
    {
        while(!GBA_RunFor(1)) if(clockstostop-- <= 0) return;
    }
    while( (GBA_CPUGetHalted()) );
}

canonical_original_code:
void GBA_DebugStep()
{
    int clockstostop = 1000000;
    do
    {
        while(!GBA_RunFor(1)) if(clockstostop-- <= 0) return;
    }
    while( (GBA_CPUGetHalted()) );
}

variable_types: clockstostop int


decompiled_code:
__int64 __fastcall str_cmp_len(__int64 a1, __int64 a2, int a3)
{
__int64 v3; // rax

if ( a3 <= 0 )
return 1LL;
v3 = 0LL;
while ( *(_BYTE *)(a1 + v3) == *(_BYTE *)(a2 + v3) )
{
if ( ++v3 == a3 )
return 1LL;
}
return 0LL;
}

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

if ( a3 <= 0 )
return 1LL;
v3 = 0LL;
while ( *(_BYTE *)(a1 + v3) == *(_BYTE *)(a2 + v3) )
{
if ( ++v3 == a3 )
return 1LL;
}
return 0LL;
}

original_code:
static inline int str_cmp_len(const char * str1, const char * str2, int len)
{
    int i;
    for(i = 0; i < len; i++) if(str1[i] != str2[i]) return 0;
    return 1;
}

canonical_original_code:
static inline int str_cmp_len(char *str1, char *str2, int len)
{
    int i;
    for(i = 0; i < len; i++) if(str1[i] != str2[i]) return 0;
    return 1;
}

variable_types: len int


decompiled_code:
unsigned __int64 GBA_ResetSaveBuffer()
{
unsigned __int64 result; // rax

result = (unsigned int)SAVE_TYPE;
if ( (int)SAVE_TYPE > 3 )
{
if ( SAVE_TYPE == 4 )
{
FLASH_CMD = 0;
FLASH_CMD_STATE = 0;
FLASH_STATE = 0;
FLASH_1M_PTR = &FLASH_BUFFER1M;
result = (unsigned __int64)memset(&FLASH_BUFFER1M, 0, (size_t)&unk_20000);
}
}
else if ( (int)SAVE_TYPE > 1 )
{
FLASH_CMD = 0;
FLASH_CMD_STATE = 0;
FLASH_STATE = 0;
result = (unsigned __int64)memset(&FLASH_BUFFER512, 0, (size_t)&unk_10000);
}
else if ( SAVE_TYPE )
{
if ( SAVE_TYPE == 1 )
result = (unsigned __int64)memset(&SRAM_BUFFER, 0, 0x8000uLL);
}
else
{
eeprom_detect_size = 1;
EEPROM_SIZE = 0;
EEPROM_ADDRESS_BUS = 14;
EEPROM_ADDRESS = 0;
EEPROM_CMD = 0;
EEPROM_CMD_LEN = 0;
EEPROM_DATA_STREAMING = 0;
result = 0LL;
memset(&EEPROM_BUFFER, 0, 0x2000uLL);
}
return result;
}

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

result = (unsigned int)SAVE_TYPE;
if ( (int)SAVE_TYPE > 3 )
{
if ( SAVE_TYPE == 4 )
{
FLASH_CMD = 0;
FLASH_CMD_STATE = 0;
FLASH_STATE = 0;
FLASH_1M_PTR = &FLASH_BUFFER1M;
result = (unsigned __int64)memset(&FLASH_BUFFER1M, 0, (size_t)&unk_20000);
}
}
else if ( (int)SAVE_TYPE > 1 )
{
FLASH_CMD = 0;
FLASH_CMD_STATE = 0;
FLASH_STATE = 0;
result = (unsigned __int64)memset(&FLASH_BUFFER512, 0, (size_t)&unk_10000);
}
else if ( SAVE_TYPE )
{
if ( SAVE_TYPE == 1 )
result = (unsigned __int64)memset(&SRAM_BUFFER, 0, 0x8000uLL);
}
else
{
eeprom_detect_size = 1;
EEPROM_SIZE = 0;
EEPROM_ADDRESS_BUS = 14;
EEPROM_ADDRESS = 0;
EEPROM_CMD = 0;
EEPROM_CMD_LEN = 0;
EEPROM_DATA_STREAMING = 0;
result = 0LL;
memset(&EEPROM_BUFFER, 0, 0x2000uLL);
}
return result;
}

original_code:
void GBA_ResetSaveBuffer(void)
{
    switch(SAVE_TYPE)
    {
        case SAV_SRAM:
            memset(SRAM_BUFFER,0,sizeof(SRAM_BUFFER));
            return;
        case SAV_FLASH:
        case SAV_FLASH512:
            FLASH_CMD = 0; FLASH_CMD_STATE = 0; FLASH_STATE = 0;
            memset(FLASH_BUFFER512,0,sizeof(FLASH_BUFFER512));
            return;
        case SAV_FLASH1M:
            FLASH_CMD = 0; FLASH_CMD_STATE = 0; FLASH_STATE = 0;
            FLASH_1M_PTR = FLASH_BUFFER1M;
            memset(FLASH_BUFFER1M,0,sizeof(FLASH_BUFFER1M));
            return;
        case SAV_EEPROM:
            eeprom_detect_size = 1;
            EEPROM_SIZE = 0; EEPROM_ADDRESS_BUS = 14;
            EEPROM_ADDRESS = 0;
            EEPROM_CMD = 0; EEPROM_CMD_LEN = 0; EEPROM_DATA_STREAMING = 0;
            memset(EEPROM_BUFFER,0,sizeof(EEPROM_BUFFER));
            return;
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return;
    }
}

canonical_original_code:
void GBA_ResetSaveBuffer()
{
    switch(SAVE_TYPE)
    {
        case SAV_SRAM:
            memset(SRAM_BUFFER,0,sizeof(SRAM_BUFFER));
            return;
        case SAV_FLASH:
        case SAV_FLASH512:
            FLASH_CMD = 0; FLASH_CMD_STATE = 0; FLASH_STATE = 0;
            memset(FLASH_BUFFER512,0,sizeof(FLASH_BUFFER512));
            return;
        case SAV_FLASH1M:
            FLASH_CMD = 0; FLASH_CMD_STATE = 0; FLASH_STATE = 0;
            FLASH_1M_PTR = FLASH_BUFFER1M;
            memset(FLASH_BUFFER1M,0,sizeof(FLASH_BUFFER1M));
            return;
        case SAV_EEPROM:
            eeprom_detect_size = 1;
            EEPROM_SIZE = 0; EEPROM_ADDRESS_BUS = 14;
            EEPROM_ADDRESS = 0;
            EEPROM_CMD = 0; EEPROM_CMD_LEN = 0; EEPROM_DATA_STREAMING = 0;
            memset(EEPROM_BUFFER,0,sizeof(EEPROM_BUFFER));
            return;
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return;
    }
}


decompiled_code:
__int64 __fastcall GBA_SaveSetFilename(char *src)
{
int v1; // eax
__int64 result; // rax

if ( strlen(src) > 0x7FF )
{
ErrorMessage("Path too long.");
exit(1);
}
strcpy(SAVE_PATH, src);
v1 = strlen(SAVE_PATH);
SAVE_PATH[v1 - 1] = 118;
SAVE_PATH[v1 - 2] = 97;
result = v1 - 3;
SAVE_PATH[(int)result] = 115;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *src)
{
int v1; // eax
__int64 result; // rax

if ( strlen(src) > 0x7FF )
{
ErrorMessage("Path too long.");
exit(1);
}
strcpy(SAVE_PATH, src);
v1 = strlen(SAVE_PATH);
SAVE_PATH[v1 - 1] = 118;
SAVE_PATH[v1 - 2] = 97;
result = v1 - 3;
SAVE_PATH[(int)result] = 115;
return result;
}

original_code:
void GBA_SaveSetFilename(char * rom_path)
{
    if(strlen(rom_path) > ((2048)-1))
    {
        ErrorMessage("Path too long.");
        exit(1);
    }
    strcpy(SAVE_PATH,rom_path);
    int cursor = strlen(SAVE_PATH);
    SAVE_PATH[cursor-1] = 'v';
    SAVE_PATH[cursor-2] = 'a';
    SAVE_PATH[cursor-3] = 's';
}

canonical_original_code:
void GBA_SaveSetFilename(char *rom_path)
{
    if(strlen(rom_path) > ((2048)-1))
    {
        ErrorMessage("Path too long.");
        exit(1);
    }
    strcpy(SAVE_PATH,rom_path);
    int cursor = strlen(SAVE_PATH);
    SAVE_PATH[cursor-1] = 'v';
    SAVE_PATH[cursor-2] = 'a';
    SAVE_PATH[cursor-3] = 's';
}

variable_types: cursor int


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

if ( SAVE_TYPE == 7 )
{
if ( (unsigned int)(a1 - 234881024) > 0xFFFF )
return 0LL;
SAVE_TYPE = 1;
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
printf("SRAM (32KB)");
}
if ( SAVE_TYPE == 1 )
{
result = 0LL;
if ( (unsigned int)(a1 - 234881024) <= 0x7FFF )
result = SRAM_BUFFER[a1 - 234881024];
return result;
}
if ( (int)SAVE_TYPE <= 1 )
return !SAVE_TYPE;
if ( (int)SAVE_TYPE > 3 )
{
if ( SAVE_TYPE == 4 )
{
if ( FLASH_STATE != 1 )
goto LABEL_7;
if ( FLASH_CMD == 144 )
{
if ( a1 == 234881024 )
return 98LL;
if ( a1 == 234881025 )
return 19LL;
goto LABEL_7;
}
if ( FLASH_CMD > 0x90u || (result = 0xFFFFFFFFLL, FLASH_CMD != 128) && (FLASH_CMD & 0xFFFFFFDF) != 16 )
{
LABEL_7:
result = 0LL;
if ( (unsigned int)(a1 - 234881024) <= 0xFFFF )
result = *(unsigned __int8 *)(FLASH_1M_PTR + (unsigned int)(a1 - 234881024));
return result;
}
return result;
}
return 0LL;
}
if ( FLASH_STATE == 1 )
{
if ( FLASH_CMD == 144 )
{
if ( a1 == 234881024 )
return 50LL;
if ( a1 == 234881025 )
return 27LL;
}
else if ( FLASH_CMD <= 0x90u )
{
result = 0xFFFFFFFFLL;
if ( FLASH_CMD == 128 || (FLASH_CMD & 0xFFFFFFDF) == 16 )
return result;
}
}
result = 0LL;
if ( (unsigned int)(a1 - 234881024) <= 0xFFFF )
result = FLASH_BUFFER512[a1 - 234881024];
return result;
}

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

if ( SAVE_TYPE == 7 )
{
if ( (unsigned int)(a1 - 234881024) > 0xFFFF )
return 0LL;
SAVE_TYPE = 1;
func1();
func4();
printf("SRAM (32KB)");
}
if ( SAVE_TYPE == 1 )
{
result = 0LL;
if ( (unsigned int)(a1 - 234881024) <= 0x7FFF )
result = SRAM_BUFFER[a1 - 234881024];
return result;
}
if ( (int)SAVE_TYPE <= 1 )
return !SAVE_TYPE;
if ( (int)SAVE_TYPE > 3 )
{
if ( SAVE_TYPE == 4 )
{
if ( FLASH_STATE != 1 )
goto LABEL_7;
if ( FLASH_CMD == 144 )
{
if ( a1 == 234881024 )
return 98LL;
if ( a1 == 234881025 )
return 19LL;
goto LABEL_7;
}
if ( FLASH_CMD > 0x90u || (result = 0xFFFFFFFFLL, FLASH_CMD != 128) && (FLASH_CMD & 0xFFFFFFDF) != 16 )
{
LABEL_7:
result = 0LL;
if ( (unsigned int)(a1 - 234881024) <= 0xFFFF )
result = *(unsigned __int8 *)(FLASH_1M_PTR + (unsigned int)(a1 - 234881024));
return result;
}
return result;
}
return 0LL;
}
if ( FLASH_STATE == 1 )
{
if ( FLASH_CMD == 144 )
{
if ( a1 == 234881024 )
return 50LL;
if ( a1 == 234881025 )
return 27LL;
}
else if ( FLASH_CMD <= 0x90u )
{
result = 0xFFFFFFFFLL;
if ( FLASH_CMD == 128 || (FLASH_CMD & 0xFFFFFFDF) == 16 )
return result;
}
}
result = 0LL;
if ( (unsigned int)(a1 - 234881024) <= 0xFFFF )
result = FLASH_BUFFER512[a1 - 234881024];
return result;
}

original_code:
u8 GBA_SaveRead8(u32 address)
{
    if(SAVE_TYPE == SAV_AUTODETECT)
    {
        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))
                return SRAM_BUFFER[address-0x0E000000];
            return 0;
        }
        case SAV_FLASH:
        case SAV_FLASH512:
        {
            if(FLASH_STATE == 1)
            {
                switch(FLASH_CMD)
                {
                    case 0x80:
                    case 0x10:
                    case 0x30:
                        return 0xFF;
                    case 0x90:
                    {
                        if(address == 0x0E000000) return 0x32;
                        if(address == 0x0E000001) return 0x1B;
                        break;
                    }
                    default:
                        break;
                }
            }
            if((address >= 0x0E000000) && (address < 0x0E010000))
                return FLASH_BUFFER512[address-0xE000000];
            return 0;
        }
        case SAV_FLASH1M:
        {
            if(FLASH_STATE == 1)
            {
                switch(FLASH_CMD)
                {
                    case 0x80:
                    case 0x10:
                    case 0x30:
                        return 0xFF;
                    case 0x90:
                    {
                        if(address == 0x0E000000) return 0x62;
                        if(address == 0x0E000001) return 0x13;
                        break;
                    }
                    default:
                        break;
                }
            }
            if((address >= 0x0E000000) && (address < 0x0E010000))
                return FLASH_1M_PTR[address-0xE000000];
            return 0;
        }
        case SAV_EEPROM:
        {
            return 1;
        }
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return 0;
    }
}

canonical_original_code:
unsigned char GBA_SaveRead8(unsigned int address)
{
    if(SAVE_TYPE == SAV_AUTODETECT)
    {
        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))
                return SRAM_BUFFER[address-0x0E000000];
            return 0;
        }
        case SAV_FLASH:
        case SAV_FLASH512:
        {
            if(FLASH_STATE == 1)
            {
                switch(FLASH_CMD)
                {
                    case 0x80:
                    case 0x10:
                    case 0x30:
                        return 0xFF;
                    case 0x90:
                    {
                        if(address == 0x0E000000) return 0x32;
                        if(address == 0x0E000001) return 0x1B;
                        break;
                    }
                    default:
                        break;
                }
            }
            if((address >= 0x0E000000) && (address < 0x0E010000))
                return FLASH_BUFFER512[address-0xE000000];
            return 0;
        }
        case SAV_FLASH1M:
        {
            if(FLASH_STATE == 1)
            {
                switch(FLASH_CMD)
                {
                    case 0x80:
                    case 0x10:
                    case 0x30:
                        return 0xFF;
                    case 0x90:
                    {
                        if(address == 0x0E000000) return 0x62;
                        if(address == 0x0E000001) return 0x13;
                        break;
                    }
                    default:
                        break;
                }
            }
            if((address >= 0x0E000000) && (address < 0x0E010000))
                return FLASH_1M_PTR[address-0xE000000];
            return 0;
        }
        case SAV_EEPROM:
        {
            return 1;
        }
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return 0;
    }
}

variable_types:
address
unsigned int

return_type: unsigned char


decompiled_code:
__int64 GBA_SaveRead16()
{
__int64 result; // rax
int v1; // edx

if ( SAVE_TYPE == 7 )
{
SAVE_TYPE = 0;
GBA_ResetSaveBuffer();
GBA_SaveReadFile();
printf("EEPROM");
}
result = 0LL;
if ( !SAVE_TYPE )
{
v1 = gba_dma3enabled();
result = 1LL;
if ( v1 )
{
result = 0LL;
if ( EEPROM_CMD == 3 )
{
if ( (unsigned int)(EEPROM_DATA_STREAMING - 65) <= 3 )
{
--EEPROM_DATA_STREAMING;
result = 0LL;
}
else
{
result = 0LL;
if ( EEPROM_DATA_STREAMING <= 0x40u )
{
--EEPROM_DATA_STREAMING;
result = EEPROM_READ_BUFFER >> 63;
EEPROM_READ_BUFFER *= 2LL;
}
}
}
}
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax
int v1; // edx

if ( SAVE_TYPE == 7 )
{
SAVE_TYPE = 0;
func1();
func4();
printf("EEPROM");
}
result = 0LL;
if ( !SAVE_TYPE )
{
v1 = gba_dma3enabled();
result = 1LL;
if ( v1 )
{
result = 0LL;
if ( EEPROM_CMD == 3 )
{
if ( (unsigned int)(EEPROM_DATA_STREAMING - 65) <= 3 )
{
--EEPROM_DATA_STREAMING;
result = 0LL;
}
else
{
result = 0LL;
if ( EEPROM_DATA_STREAMING <= 0x40u )
{
--EEPROM_DATA_STREAMING;
result = EEPROM_READ_BUFFER >> 63;
EEPROM_READ_BUFFER *= 2LL;
}
}
}
}
}
return result;
}

original_code:
u16 GBA_SaveRead16(u32 address)
{
    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_CMD == 3)
                {
                    if((EEPROM_DATA_STREAMING < 69) && (EEPROM_DATA_STREAMING > 64))
                    {
                        EEPROM_DATA_STREAMING--;
                        return 0;
                    }
                    else if(EEPROM_DATA_STREAMING <= 64)
                    {
                        EEPROM_DATA_STREAMING--;
                        u16 data = (EEPROM_READ_BUFFER&((u64)1<<63))!=0;
                        EEPROM_READ_BUFFER<<=1;
                        return data;
                    }
                }
            }
            else
            {
                return 1;
            }
        }
        case SAV_SRAM:
        case SAV_FLASH:
        case SAV_FLASH512:
        case SAV_FLASH1M:
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return 0;
    }
}

canonical_original_code:
unsigned short GBA_SaveRead16(unsigned int address)
{
    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_CMD == 3)
                {
                    if((EEPROM_DATA_STREAMING < 69) && (EEPROM_DATA_STREAMING > 64))
                    {
                        EEPROM_DATA_STREAMING--;
                        return 0;
                    }
                    else if(EEPROM_DATA_STREAMING <= 64)
                    {
                        EEPROM_DATA_STREAMING--;
                        unsigned short data = (EEPROM_READ_BUFFER&((u64)1<<63))!=0;
                        EEPROM_READ_BUFFER<<=1;
                        return data;
                    }
                }
            }
            else
            {
                return 1;
            }
        }
        case SAV_SRAM:
        case SAV_FLASH:
        case SAV_FLASH512:
        case SAV_FLASH1M:
        case SAV_NONE:
        case SAV_AUTODETECT:
        default:
            return 0;
    }
}

variable_types:
data
unsigned short

return_type: unsigned short