repo: vedantk/evt-server

decompiled_code:
int __fastcall evt_server_start(__int64 a1, void *a2)
{
event_init();
qword_950 = a1;
return pthread_create(&newthread, 0LL, server_worker, a2);
}

canonical_decompiled_code:
int __fastcall func2(__int64 a1, void *a2)
{
event_init();
qword_950 = a1;
return pthread_create(&newthread, 0LL, server_worker, a2);
}

original_code:
int evt_server_start(evt_callback cb, void* arg)
{
 event_init();
 serv.handler = cb;
 return pthread_create(&serv.server, ((void *)0), server_worker, arg);
}

canonical_original_code:
int evt_server_start(void (*cb)(int fd, short evt, void *arg), void *arg)
{
 event_init();
 serv.handler = cb;
 return pthread_create(&serv.server, ((void *)0), server_worker, arg);
}

variable_types:
cb
void (*)(int fd, short evt, void *arg)

variable_types:
arg
void *


decompiled_code:
struct addrinfo *get_server_addrinfo()
{
return ai;
}

canonical_decompiled_code:
struct addrinfo *func3()
{
return ai;
}

original_code:
struct addrinfo* get_server_addrinfo()
{
 return serv.ai;
}

canonical_original_code:
struct addrinfo *get_server_addrinfo()
{
 return serv.ai;
}

return_type: 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; } *

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; }


decompiled_code:
int __fastcall print_addrinfo(const char **a1)
{
return printf(
"ai_flags; %d\nai_family; %d\nai_socktype; %d\nai_protocol; %d\nai_addrlen; %u\nai_canonname; %s\n",
*(unsigned int *)a1,
*((unsigned int *)a1 + 1),
*((unsigned int *)a1 + 2),
*((unsigned int *)a1 + 3),
*((unsigned int *)a1 + 4),
a1[4]);
}

canonical_decompiled_code:
int __fastcall func4(const char **a1)
{
return printf(
"ai_flags; %d\nai_family; %d\nai_socktype; %d\nai_protocol; %d\nai_addrlen; %u\nai_canonname; %s\n",
*(unsigned int *)a1,
*((unsigned int *)a1 + 1),
*((unsigned int *)a1 + 2),
*((unsigned int *)a1 + 3),
*((unsigned int *)a1 + 4),
a1[4]);
}

original_code:
void print_addrinfo(struct addrinfo* ai)
{
 printf ("ai_flags; %d\n"
  "ai_family; %d\n"
  "ai_socktype; %d\n"
  "ai_protocol; %d\n"
  "ai_addrlen; %u\n"
  "ai_canonname; %s\n"
 , ai->ai_flags, ai->ai_family, ai->ai_socktype,
 ai->ai_protocol, ai->ai_addrlen, ai->ai_canonname);
}

canonical_original_code:
void print_addrinfo(struct addrinfo *ai)
{
 printf ("ai_flags; %d\n"
  "ai_family; %d\n"
  "ai_socktype; %d\n"
  "ai_protocol; %d\n"
  "ai_addrlen; %u\n"
  "ai_canonname; %s\n"
 , ai->ai_flags, ai->ai_family, ai->ai_socktype,
 ai->ai_protocol, ai->ai_addrlen, ai->ai_canonname);
}

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; } *

return_type: void


decompiled_code:
__int64 get_sockaddr_size()
{
return (unsigned int)len;
}

canonical_decompiled_code:
__int64 func5()
{
return (unsigned int)len;
}

original_code:
int get_sockaddr_size()
{
 return serv.socksize;
}

return_type: int


decompiled_code:
_WORD *new_sockaddr()
{
_WORD *result; // rax

result = calloc(1uLL, (unsigned int)len);
*result = ai->ai_family;
return result;
}

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

result = calloc(1uLL, (unsigned int)len);
*result = ai->ai_family;
return result;
}

original_code:
struct sockaddr* new_sockaddr()
{
 struct sockaddr* sa = calloc(1, serv.socksize);
 sa->sa_family = serv.ai->ai_family;
 return sa;
}

canonical_original_code:
struct sockaddr *new_sockaddr()
{
 struct sockaddr *sa = calloc(1, serv.socksize);
 sa->sa_family = serv.ai->ai_family;
 return sa;
}

variable_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; } *


original_code:
int serialize_addr(struct sockaddr* src, char* dest, int size)
{
 if (serv.ai->ai_family == 2) {
  if (size < IP4_SOCKLEN) return 0;
  sa4_serial* dsa4 = (sa4_serial*) dest;
  struct sockaddr_in* sa4 = (struct sockaddr_in*) src;
  dsa4->sin_family = htons(sa4->sin_family);
  dsa4->sin_port = htons(sa4->sin_port);
  dsa4->sin_addr = htonl(sa4->sin_addr.s_addr);
  return IP4_SOCKLEN;
 } else {
  if (size < IP6_SOCKLEN) return 0;
  struct sockaddr_in6* dsa6 = (struct sockaddr_in6*) dest;
  struct sockaddr_in6* sa6 = (struct sockaddr_in6*) src;
  dsa6->sin6_family = htons(sa6->sin6_family);
  dsa6->sin6_port = htons(sa6->sin6_port);
  dsa6->sin6_flowinfo = htonl(sa6->sin6_flowinfo);
  dsa6->sin6_scope_id = htonl(sa6->sin6_scope_id);
  memcpy(&dsa6->sin6_addr.__in6_u.__u6_addr8,
         &sa6->sin6_addr.__in6_u.__u6_addr8, 16);
  return IP6_SOCKLEN;
 }
}

canonical_original_code:
int serialize_addr(struct sockaddr *src, char *dest, int size)
{
 if (serv.ai->ai_family == 2) {
  if (size < IP4_SOCKLEN) return 0;
  struct sa4_serial *dsa4 = (sa4_serial*) dest;
  struct sockaddr_in *sa4 = (struct sockaddr_in*) src;
  dsa4->sin_family = htons(sa4->sin_family);
  dsa4->sin_port = htons(sa4->sin_port);
  dsa4->sin_addr = htonl(sa4->sin_addr.s_addr);
  return IP4_SOCKLEN;
 } else {
  if (size < IP6_SOCKLEN) return 0;
  struct sockaddr_in6 *dsa6 = (struct sockaddr_in6*) dest;
  struct sockaddr_in6 *sa6 = (struct sockaddr_in6*) src;
  dsa6->sin6_family = htons(sa6->sin6_family);
  dsa6->sin6_port = htons(sa6->sin6_port);
  dsa6->sin6_flowinfo = htonl(sa6->sin6_flowinfo);
  dsa6->sin6_scope_id = htonl(sa6->sin6_scope_id);
  memcpy(&dsa6->sin6_addr.__in6_u.__u6_addr8,
         &sa6->sin6_addr.__in6_u.__u6_addr8, 16);
  return IP6_SOCKLEN;
 }
}

variable_types:
dest
char *

variable_types: size int

variable_types: struct sa4_serial { short sin_family; unsigned short sin_port; unsigned int sin_addr; } *

variable_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr { unsigned int s_addr; } sin_addr; unsigned char sin_zero[-1]; } *

variable_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; } sin6_addr; unsigned int sin6_scope_id; } *

user_defined_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; }

user_defined_types: struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; unsigned char sin_zero[-1]; }

user_defined_types: struct sockaddr_in6 { unsigned short sin6_family; unsigned short sin6_port; unsigned int sin6_flowinfo; struct in6_addr sin6_addr; unsigned int sin6_scope_id; }


original_code:
int deserialize_addr(char* src, struct sockaddr* dest, int size)
{
 if (serv.ai->ai_family == 2) {
  if (size < IP4_SOCKLEN) return 0;
  sa4_serial* sa4 = (sa4_serial*) src;
  struct sockaddr_in* dsa4 = (struct sockaddr_in*) dest;
  dsa4->sin_family = ntohs(sa4->sin_family);
  if (dsa4->sin_family != 2) return 0;
  dsa4->sin_port = ntohs(sa4->sin_port);
  dsa4->sin_addr.s_addr = ntohl(sa4->sin_addr);
  return IP4_SOCKLEN;
 } else {
  if (size < IP6_SOCKLEN) return 0;
  struct sockaddr_in6* sa6 = (struct sockaddr_in6*) src;
  struct sockaddr_in6* dsa6 = (struct sockaddr_in6*) dest;
  dsa6->sin6_family = ntohs(sa6->sin6_family);
  if (dsa6->sin6_family != 10) return 0;
  dsa6->sin6_port = ntohs(sa6->sin6_port);
  dsa6->sin6_flowinfo = ntohl(sa6->sin6_flowinfo);
  memcpy(&dsa6->sin6_addr.__in6_u.__u6_addr8,
         &sa6->sin6_addr.__in6_u.__u6_addr8, 16);
  dsa6->sin6_scope_id = ntohl(sa6->sin6_scope_id);
  return IP6_SOCKLEN;
 }
}

canonical_original_code:
int deserialize_addr(char *src, struct sockaddr *dest, int size)
{
 if (serv.ai->ai_family == 2) {
  if (size < IP4_SOCKLEN) return 0;
  struct sa4_serial *sa4 = (sa4_serial*) src;
  struct sockaddr_in *dsa4 = (struct sockaddr_in*) dest;
  dsa4->sin_family = ntohs(sa4->sin_family);
  if (dsa4->sin_family != 2) return 0;
  dsa4->sin_port = ntohs(sa4->sin_port);
  dsa4->sin_addr.s_addr = ntohl(sa4->sin_addr);
  return IP4_SOCKLEN;
 } else {
  if (size < IP6_SOCKLEN) return 0;
  struct sockaddr_in6 *sa6 = (struct sockaddr_in6*) src;
  struct sockaddr_in6 *dsa6 = (struct sockaddr_in6*) dest;
  dsa6->sin6_family = ntohs(sa6->sin6_family);
  if (dsa6->sin6_family != 10) return 0;
  dsa6->sin6_port = ntohs(sa6->sin6_port);
  dsa6->sin6_flowinfo = ntohl(sa6->sin6_flowinfo);
  memcpy(&dsa6->sin6_addr.__in6_u.__u6_addr8,
         &sa6->sin6_addr.__in6_u.__u6_addr8, 16);
  dsa6->sin6_scope_id = ntohl(sa6->sin6_scope_id);
  return IP6_SOCKLEN;
 }
}

variable_types:
src
char *

user_defined_types: struct sa4_serial { short sin_family; unsigned short sin_port; unsigned int sin_addr; }

user_defined_types: struct in6_addr { union { unsigned char __u6_addr8[16]; unsigned short __u6_addr16[8]; unsigned int __u6_addr32[4]; } __in6_u; }


decompiled_code:
__int64 __fastcall copy_ip_addr(__int64 a1, __m128i *a2, int a3)
{
__int64 result; // rax

if ( ai->ai_family == 2 )
{
result = 0LL;
if ( a3 > 3 )
{
a2->m128i_i32[0] = *(_DWORD *)(a1 + 4);
result = 4LL;
}
}
else
{
result = 0LL;
if ( a3 > 15 )
{
*a2 = _mm_loadu_si128((const __m128i *)(a1 + 8));
result = 16LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, __m128i *a2, int a3)
{
__int64 result; // rax

if ( ai->ai_family == 2 )
{
result = 0LL;
if ( a3 > 3 )
{
a2->m128i_i32[0] = *(_DWORD *)(a1 + 4);
result = 4LL;
}
}
else
{
result = 0LL;
if ( a3 > 15 )
{
*a2 = _mm_loadu_si128((const __m128i *)(a1 + 8));
result = 16LL;
}
}
return result;
}

original_code:
int copy_ip_addr(struct sockaddr* src, char* buf, int size)
{
 if (serv.ai->ai_family == 2) {
  if (size < 4) return 0;
  struct sockaddr_in* sa4 = (struct sockaddr_in*) src;
  memcpy(buf, &sa4->sin_addr.s_addr, 4);
  return 4;
 } else {
  if (size < 16) return 0;
  struct sockaddr_in6* sa6 = (struct sockaddr_in6*) src;
  memcpy(buf, &sa6->sin6_addr.__in6_u.__u6_addr8, 16);
  return 16;
 }
}

canonical_original_code:
int copy_ip_addr(struct sockaddr *src, char *buf, int size)
{
 if (serv.ai->ai_family == 2) {
  if (size < 4) return 0;
  struct sockaddr_in *sa4 = (struct sockaddr_in*) src;
  memcpy(buf, &sa4->sin_addr.s_addr, 4);
  return 4;
 } else {
  if (size < 16) return 0;
  struct sockaddr_in6 *sa6 = (struct sockaddr_in6*) src;
  memcpy(buf, &sa6->sin6_addr.__in6_u.__u6_addr8, 16);
  return 16;
 }
}

variable_types:
buf
char *


decompiled_code:
__int64 get_nr_cpus()
{
return sysconf(84);
}

canonical_decompiled_code:
__int64 func10()
{
return sysconf(84);
}

original_code:
int get_nr_cpus()
{
 return sysconf(_SC_NPROCESSORS_ONLN);
}


decompiled_code:
int __fastcall print_buffer(const char *a1, char *a2, int a3)
{
char *v4; // rbx

puts(a1);
if ( a3 > 0 )
{
v4 = a2;
do
printf("%d ", (unsigned int)*v4++);
while ( v4 != &a2[a3] );
}
return puts(&s);
}

canonical_decompiled_code:
int __fastcall func11(const char *a1, char *a2, int a3)
{
char *v4; // rbx

puts(a1);
if ( a3 > 0 )
{
v4 = a2;
do
printf("%d ", (unsigned int)*v4++);
while ( v4 != &a2[a3] );
}
return puts(&s);
}

original_code:
void print_buffer(const char* name, void* buf, int size)
{
 int i;
 char* buffer = buf;
 puts(name);
 for (i = 0; i < size; ++i) {
  printf("%d ", buffer[i]);
 }
 puts("");
}

canonical_original_code:
void print_buffer(char *name, void *buf, int size)
{
 int i;
 char *buffer = buf;
 puts(name);
 for (i = 0; i < size; ++i) {
  printf("%d ", buffer[i]);
 }
 puts("");
}

variable_types:
name
char *

variable_types:
buf
void *

variable_types: i int

variable_types:
buffer
char *


decompiled_code:
__int64 __fastcall sys_error(const char *a1)
{
perror(a1);
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func12(const char *a1)
{
perror(a1);
return 0xFFFFFFFFLL;
}

original_code:
int sys_error(const char* msg)
{
 perror(msg);
 return -1;
}

canonical_original_code:
int sys_error(char *msg)
{
 perror(msg);
 return -1;
}

variable_types:
msg
char *


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

if ( pool != -1 )
return 0xFFFFFFFFLL;
pool = a2;
qword_928 = a1;
result = 0LL;
if ( a2 > 0 )
{
dword_930 = 0;
ptr = calloc(a2, 0x48uLL);
v3 = 0LL;
while ( !pthread_create((pthread_t *)((char *)ptr + v3), 0LL, dispatch_worker, (char *)ptr + v3) )
{
v3 += 72LL;
if ( v3 == 72LL * (unsigned int)a2 )
return (unsigned int)a2;
}
pool = 0;
free(ptr);
result = sys_error("Failed to start threads.");
}
return result;
}

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

if ( pool != -1 )
return 0xFFFFFFFFLL;
pool = a2;
qword_928 = a1;
result = 0LL;
if ( a2 > 0 )
{
dword_930 = 0;
ptr = calloc(a2, 0x48uLL);
v3 = 0LL;
while ( !pthread_create((pthread_t *)((char *)ptr + v3), 0LL, dispatch_worker, (char *)ptr + v3) )
{
v3 += 72LL;
if ( v3 == 72LL * (unsigned int)a2 )
return (unsigned int)a2;
}
pool = 0;
free(ptr);
result = func12("Failed to start threads.");
}
return result;
}

original_code:
int evt_server_threads(evt_callback tcb, int nr)
{
 if (pool.nr != -1) return -1;
 pool.nr = nr;
 pool.slave = tcb;
 if (nr <= 0) return 0;
 pool.last_sched = 0;
 pool.conns = calloc(nr, sizeof(cli_queue));
 int i;
 int ret;
 for (i = 0; i < nr; ++i) {
  ret = pthread_create(&pool.conns[i].tid, ((void *)0),
         dispatch_worker, &pool.conns[i]);
  if (ret != 0) {
   pool.nr = 0;
   free(pool.conns);
   return sys_error("Failed to start threads.");
  }
 }
 return nr;
}

canonical_original_code:
int evt_server_threads(void (*tcb)(int fd, short evt, void *arg), int nr)
{
 if (pool.nr != -1) return -1;
 pool.nr = nr;
 pool.slave = tcb;
 if (nr <= 0) return 0;
 pool.last_sched = 0;
 pool.conns = calloc(nr, sizeof(cli_queue));
 int i;
 int ret;
 for (i = 0; i < nr; ++i) {
  ret = pthread_create(&pool.conns[i].tid, ((void *)0),
         dispatch_worker, &pool.conns[i]);
  if (ret != 0) {
   pool.nr = 0;
   free(pool.conns);
   return sys_error("Failed to start threads.");
  }
 }
 return nr;
}

variable_types:
tcb
void (*)(int fd, short evt, void *arg)

variable_types: nr int

variable_types: ret int


decompiled_code:
int __fastcall evt_tcp(int a1, struct sockaddr *a2)
{
int result; // eax

result = accept(a1, a2, (socklen_t *)&len);
if ( result == -1 )
result = sys_error("accept");
return result;
}

canonical_decompiled_code:
int __fastcall func14(int a1, struct sockaddr *a2)
{
int result; // eax

result = accept(a1, a2, (socklen_t *)&len);
if ( result == -1 )
result = func12("accept");
return result;
}

original_code:
int evt_tcp(sockfd_t fd, struct sockaddr* sock)
{
 sockfd_t conn = accept(fd, sock, &serv.socksize);
 if (conn == -1) {
  return sys_error("accept");
 }
 return conn;
}

canonical_original_code:
int evt_tcp(int fd, struct sockaddr *sock)
{
 int conn = accept(fd, sock, &serv.socksize);
 if (conn == -1) {
  return sys_error("accept");
 }
 return conn;
}

variable_types: fd int

variable_types: conn int


decompiled_code:
__int64 __fastcall evt_udp(int a1, void *a2, int a3, int a4, struct sockaddr *a5)
{
unsigned int v5; // edx

v5 = recvfrom(a1, a2, a3, a4, a5, (socklen_t *)&len);
if ( v5 == -1 )
v5 = sys_error("recvfrom");
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func15(int a1, void *a2, int a3, int a4, struct sockaddr *a5)
{
unsigned int v5; // edx

v5 = recvfrom(a1, a2, a3, a4, a5, (socklen_t *)&len);
if ( v5 == -1 )
v5 = func12("recvfrom");
return v5;
}

original_code:
int evt_udp(sockfd_t fd, char* buf, int size, int flags,
  struct sockaddr* sock)
{
 int len = recvfrom(fd, buf, size, flags, sock, &serv.socksize);
 if (len == -1) {
  return sys_error("recvfrom");
 }
 return len;
}

canonical_original_code:
int evt_udp(int fd, char *buf, int size, int flags, struct sockaddr *sock)
{
 int len = recvfrom(fd, buf, size, flags, sock, &serv.socksize);
 if (len == -1) {
  return sys_error("recvfrom");
 }
 return len;
}

variable_types: flags int

variable_types: struct sockaddr { unsigned short sa_family; char sa_data[14]; } *

variable_types: len int


decompiled_code:
int __fastcall evt_close(int fd)
{
if ( shutdown(fd, 2) )
sys_error("evt_close: shutdown");
return close(fd);
}

canonical_decompiled_code:
int __fastcall func16(int fd)
{
if ( shutdown(fd, 2) )
func12("evt_close: shutdown");
return close(fd);
}

original_code:
void evt_close(sockfd_t fd)
{
 if (shutdown(fd, SHUT_RDWR) != 0) {
  sys_error("evt_close: shutdown");
 }
 close(fd);
}

canonical_original_code:
void evt_close(int fd)
{
 if (shutdown(fd, SHUT_RDWR) != 0) {
  sys_error("evt_close: shutdown");
 }
 close(fd);
}


getnetinfo

decompiled_code:
struct addrinfo *__fastcall getnetinfo(char *name, unsigned int a2, int a3)
{
int v3; // eax
int v5; // ebx
const char *v6; // rax
char v7[8]; // [rsp+0h] [rbp-48h] BYREF
struct addrinfo *pai; // [rsp+8h] [rbp-40h] BYREF
struct addrinfo req; // [rsp+10h] [rbp-38h] BYREF

*(_QWORD *)&req.ai_flags = 1LL;
req.ai_protocol = 0;
*(_QWORD *)&req.ai_addrlen = 0LL;
req.ai_addr = 0LL;
req.ai_canonname = 0LL;
req.ai_next = 0LL;
req.ai_socktype = a3;
snprintf(v7, 8uLL, "%d", a2);
v3 = getaddrinfo(name, v7, &req, &pai);
if ( v3 )
{
v5 = v3;
sys_error("getaddrinfo");
v6 = gai_strerror(v5);
fprintf(stderr, "getaddrinfo %s\n", v6);
}
return pai;
}

canonical_decompiled_code:
struct addrinfo *__fastcall func17(char *name, unsigned int a2, int a3)
{
int v3; // eax
int v5; // ebx
const char *v6; // rax
char v7[8]; // [rsp+0h] [rbp-48h] BYREF
struct addrinfo *pai; // [rsp+8h] [rbp-40h] BYREF
struct addrinfo req; // [rsp+10h] [rbp-38h] BYREF

*(_QWORD *)&req.ai_flags = 1LL;
req.ai_protocol = 0;
*(_QWORD *)&req.ai_addrlen = 0LL;
req.ai_addr = 0LL;
req.ai_canonname = 0LL;
req.ai_next = 0LL;
req.ai_socktype = a3;
snprintf(v7, 8uLL, "%d", a2);
v3 = getaddrinfo(name, v7, &req, &pai);
if ( v3 )
{
v5 = v3;
func12("getaddrinfo");
v6 = gai_strerror(v5);
fprintf(stderr, "getaddrinfo %s\n", v6);
}
return pai;
}

original_code:
struct addrinfo* getnetinfo(const char* host, int port, int socktype)
{
 struct addrinfo hints;
 struct addrinfo* result;
 memset(&hints, 0, sizeof(struct addrinfo));
 hints.ai_family = 0;
 hints.ai_socktype = socktype;
 hints.ai_flags = 0x0001;
 char portstr[8];
 snprintf(portstr, sizeof(portstr), "%d", port);
 int err;
 if ((err = getaddrinfo(host, portstr, &hints, &result)) != 0) {
  sys_error("getaddrinfo");
  fprintf(stderr, "getaddrinfo %s\n", gai_strerror(err));
 }
 return result;
}

canonical_original_code:
struct addrinfo *getnetinfo(char *host, int port, int socktype)
{
 struct addrinfo hints;
 struct addrinfo *result;
 memset(&hints, 0, sizeof(struct addrinfo));
 hints.ai_family = 0;
 hints.ai_socktype = socktype;
 hints.ai_flags = 0x0001;
 char portstr[8];
 snprintf(portstr, sizeof(portstr), "%d", port);
 int err;
 if ((err = getaddrinfo(host, portstr, &hints, &result)) != 0) {
  sys_error("getaddrinfo");
  fprintf(stderr, "getaddrinfo %s\n", gai_strerror(err));
 }
 return result;
}

variable_types:
host
char *

variable_types: port int

variable_types: socktype int

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:
portstr
char [8]

variable_types: err int


decompiled_code:
__int64 __fastcall evt_server_init(unsigned int a1, int a2)
{
serv = a1;
dword_944 = a2;
ai = getnetinfo(0LL, a1, a2);
LODWORD(len) = ai->ai_addrlen;
pool = -1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func18(unsigned int a1, int a2)
{
serv = a1;
dword_944 = a2;
ai = func17(0LL, a1, a2);
LODWORD(len) = ai->ai_addrlen;
pool = -1;
return 0LL;
}

original_code:
int evt_server_init(int port, int socktype)
{
 serv.port = port;
 serv.socktype = socktype;
 serv.ai = getnetinfo(((void *)0), port, socktype);
 serv.socksize = serv.ai->ai_addrlen;
 pool.nr = -1;
 return 0;
}


decompiled_code:
__int64 __fastcall get_conn_to_host(char *a1, unsigned int a2, int a3)
{
struct addrinfo *v4; // rax
struct addrinfo *v5; // r12
struct addrinfo *v6; // rbx
int v7; // eax
unsigned int v8; // ebp

v4 = getnetinfo(a1, a2, a3);
v5 = v4;
if ( v4 )
{
v6 = v4;
while ( 1 )
{
v7 = socket(v6->ai_family, v6->ai_socktype, v6->ai_protocol);
v8 = v7;
if ( v7 >= 0 )
break;
v6 = v6->ai_next;
if ( !v6 )
goto LABEL_5;
}
if ( a3 == 1 && connect(v7, v6->ai_addr, len) == -1 )
{
evt_close(v8);
freeaddrinfo(v5);
v8 = sys_error("connect");
}
else
{
freeaddrinfo(v5);
}
}
else
{
LABEL_5:
freeaddrinfo(v5);
v8 = sys_error("socket");
}
return v8;
}

canonical_decompiled_code:
__int64 __fastcall func19(char *a1, unsigned int a2, int a3)
{
struct addrinfo *v4; // rax
struct addrinfo *v5; // r12
struct addrinfo *v6; // rbx
int v7; // eax
unsigned int v8; // ebp

v4 = func17(a1, a2, a3);
v5 = v4;
if ( v4 )
{
v6 = v4;
while ( 1 )
{
v7 = socket(v6->ai_family, v6->ai_socktype, v6->ai_protocol);
v8 = v7;
if ( v7 >= 0 )
break;
v6 = v6->ai_next;
if ( !v6 )
goto LABEL_5;
}
if ( a3 == 1 && connect(v7, v6->ai_addr, len) == -1 )
{
func16(v8);
freeaddrinfo(v5);
v8 = func12("connect");
}
else
{
freeaddrinfo(v5);
}
}
else
{
LABEL_5:
freeaddrinfo(v5);
v8 = func12("socket");
}
return v8;
}

original_code:
int get_conn_to_host(const char* host, int port, int socktype)
{
 sockfd_t sock;
 struct addrinfo *rp, *result = getnetinfo(host, port, socktype);
 for (rp = result; rp != ((void *)0); rp = rp->ai_next) {
  sock = socket(rp->ai_family, rp->ai_socktype,
         rp->ai_protocol);
  if (sock >= 0) break;
 }
 if (rp == ((void *)0)) {
  freeaddrinfo(result);
  return sys_error("socket");
 }
 if (socktype == SOCK_STREAM) {
  if (connect(sock, rp->ai_addr, serv.socksize) == -1) {
   evt_close(sock);
   freeaddrinfo(result);
   return sys_error("connect");
  }
 }
 freeaddrinfo(result);
 return sock;
}

canonical_original_code:
int get_conn_to_host(char *host, int port, int socktype)
{
 int sock;
 struct addrinfo *rp; struct addrinfo *result = getnetinfo(host, port, socktype);
 for (rp = result; rp != ((void *)0); rp = rp->ai_next) {
  sock = socket(rp->ai_family, rp->ai_socktype,
         rp->ai_protocol);
  if (sock >= 0) break;
 }
 if (rp == ((void *)0)) {
  freeaddrinfo(result);
  return sys_error("socket");
 }
 if (socktype == SOCK_STREAM) {
  if (connect(sock, rp->ai_addr, serv.socksize) == -1) {
   evt_close(sock);
   freeaddrinfo(result);
   return sys_error("connect");
  }
 }
 freeaddrinfo(result);
 return sock;
}

variable_types: sock int


decompiled_code:
int __fastcall get_conn_to_addr(__int64 a1, __int16 a2, int a3)
{
bool v5; // zf
int v6; // edx
int result; // eax

v5 = a3 == 1;
v6 = 6;
if ( !v5 )
v6 = 17;
result = socket(ai->ai_family, a3, v6);
if ( result < 0 )
return sys_error("socket");
*(_WORD *)(a1 + 32) = a2;
return result;
}

canonical_decompiled_code:
int __fastcall func20(__int64 a1, __int16 a2, int a3)
{
bool v5; // zf
int v6; // edx
int result; // eax

v5 = a3 == 1;
v6 = 6;
if ( !v5 )
v6 = 17;
result = socket(ai->ai_family, a3, v6);
if ( result < 0 )
return func12("socket");
*(_WORD *)(a1 + 32) = a2;
return result;
}

original_code:
int get_conn_to_addr(struct sockaddr* addr, int port, int socktype)
{
 int ai_protocol = (socktype == SOCK_STREAM)
     ? IPPROTO_TCP : IPPROTO_UDP;
 sockfd_t fd = socket(serv.ai->ai_family, socktype, ai_protocol);
 if (fd < 0) {
  return sys_error("socket");
 }
 memcpy(addr + 2, &port, 2);
 return fd;
}

canonical_original_code:
int get_conn_to_addr(struct sockaddr *addr, int port, int socktype)
{
 int ai_protocol = (socktype == SOCK_STREAM)
     ? IPPROTO_TCP : IPPROTO_UDP;
 int fd = socket(serv.ai->ai_family, socktype, ai_protocol);
 if (fd < 0) {
  return sys_error("socket");
 }
 memcpy(addr + 2, &port, 2);
 return fd;
}


decompiled_code:
__int64 __fastcall set_nonblocking(int fd)
{
unsigned int v1; // eax
int v2; // ebx

v1 = fcntl(fd, 3, 0LL);
if ( v1 == -1 )
v1 = 0;
BYTE1(v1) |= 8u;
v2 = fcntl(fd, 4, v1);
if ( v2 < 0 )
sys_error("Setting O_NONBLOCK failed.");
return (unsigned int)v2;
}

canonical_decompiled_code:
__int64 __fastcall func21(int fd)
{
unsigned int v1; // eax
int v2; // ebx

v1 = fcntl(fd, 3, 0LL);
if ( v1 == -1 )
v1 = 0;
BYTE1(v1) |= 8u;
v2 = fcntl(fd, 4, v1);
if ( v2 < 0 )
func12("Setting O_NONBLOCK failed.");
return (unsigned int)v2;
}

original_code:
int set_nonblocking(sockfd_t fd)
{
 int flags;
 if ((flags = fcntl(fd, 3, 0)) == -1) {
  flags = 0;
 }
 int ret = fcntl(fd, 4, flags | 04000);
 if (ret < 0) {
  sys_error("Setting O_NONBLOCK failed.");
 }
 return ret;
}

canonical_original_code:
int set_nonblocking(int fd)
{
 int flags;
 if ((flags = fcntl(fd, 3, 0)) == -1) {
  flags = 0;
 }
 int ret = fcntl(fd, 4, flags | 04000);
 if (ret < 0) {
  sys_error("Setting O_NONBLOCK failed.");
 }
 return ret;
}


decompiled_code:
__int64 __fastcall cq_front(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func23(__int64 a1)
{
return *(_QWORD *)(a1 + 16);
}

original_code:
client* cq_front(cli_queue* q)
{
 return q->head;
}

canonical_original_code:
struct client *cq_front(struct cli_queue *q)
{
 return q->head;
}

variable_types: struct cli_queue { unsigned long tid; int size; struct client *head; struct client *tail; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } lock; } *

return_type: struct client { int conn; short evt; void *arg; struct client *next; } *

user_defined_types: struct cli_queue { unsigned long tid; int size; struct client *head; struct client *tail; union pthread_mutex_t lock; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }


original_code:
void cq_push_back(cli_queue* q, sockfd_t conn, short evt, void* arg)
{
 client* p = malloc(sizeof(client));
 p->conn = conn;
 p->evt = evt;
 p->arg = arg;
 p->next = ((void *)0);
 pthread_mutex_lock(&q->lock);
 if (((void *)0) == q->head && ((void *)0) == q->tail) {
  q->head = q->tail = p;
 } else {
  q->tail->next = p;
  q->tail = p;
 }
 ++q->size;
 pthread_mutex_unlock(&q->lock);
}

canonical_original_code:
void cq_push_back(struct cli_queue *q, int conn, short evt, void *arg)
{
 struct client *p = malloc(sizeof(client));
 p->conn = conn;
 p->evt = evt;
 p->arg = arg;
 p->next = ((void *)0);
 pthread_mutex_lock(&q->lock);
 if (((void *)0) == q->head && ((void *)0) == q->tail) {
  q->head = q->tail = p;
 } else {
  q->tail->next = p;
  q->tail = p;
 }
 ++q->size;
 pthread_mutex_unlock(&q->lock);
}

variable_types: struct cli_queue { unsigned long tid; int size; struct client { int conn; short evt; void *arg; struct client *next; } *head; struct client *tail; union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } lock; } *

variable_types: evt short

variable_types:
arg
void *


decompiled_code:
void evt_server_stop()
{
__int64 v0; // rbx
int v1; // ebp

if ( (unsigned int)event_loopexit(&min_time) )
event_loopbreak();
if ( pool > 0 )
{
v0 = 0LL;
v1 = 0;
do
{
cq_push_back((__int64)ptr + v0, -1, 0, 0LL);
while ( *(int *)((char *)ptr + v0 + 8) > 1 )
usleep(0x3E8u);
++v1;
v0 += 72LL;
}
while ( pool > v1 );
free(ptr);
}
freeaddrinfo(ai);
}

canonical_decompiled_code:
void func25()
{
__int64 v0; // rbx
int v1; // ebp

if ( (unsigned int)event_loopexit(&min_time) )
event_loopbreak();
if ( pool > 0 )
{
v0 = 0LL;
v1 = 0;
do
{
func24((__int64)ptr + v0, -1, 0, 0LL);
while ( *(int *)((char *)ptr + v0 + 8) > 1 )
usleep(0x3E8u);
++v1;
v0 += 72LL;
}
while ( pool > v1 );
free(ptr);
}
freeaddrinfo(ai);
}

original_code:
void evt_server_stop()
{
 if (event_loopexit(&min_time) != 0) {
  event_loopbreak();
 }
 if (pool.nr > 0) {
  int i;
  for (i = 0; i < pool.nr; ++i) {
   cq_push_back(&pool.conns[i], -1, 0, ((void *)0));
   while (pool.conns[i].size > 1) {
    usleep(1000);
   }
  }
  free(pool.conns);
 }
 freeaddrinfo(serv.ai);
}

variable_types: i int


decompiled_code:
int __fastcall evt_thread_dispatch(int a1, __int16 a2, __int64 a3)
{
int v3; // ebx
int result; // eax

v3 = (dword_930 + 1) % pool;
result = cq_push_back((__int64)ptr + 72 * v3, a1, a2, a3);
dword_930 = v3;
return result;
}

canonical_decompiled_code:
int __fastcall func26(int a1, __int16 a2, __int64 a3)
{
int v3; // ebx
int result; // eax

v3 = (dword_930 + 1) % pool;
result = func24((__int64)ptr + 72 * v3, a1, a2, a3);
dword_930 = v3;
return result;
}

original_code:
void evt_thread_dispatch(sockfd_t conn, short evt, void* arg)
{
 int i = (pool.last_sched + 1) % pool.nr;
 cq_push_back(&pool.conns[i], conn, evt, arg);
 pool.last_sched = i;
}

canonical_original_code:
void evt_thread_dispatch(int conn, short evt, void *arg)
{
 int i = (pool.last_sched + 1) % pool.nr;
 cq_push_back(&pool.conns[i], conn, evt, arg);
 pool.last_sched = i;
}


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

result = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 16LL);
*(_QWORD *)(a1 + 16) = result;
if ( !result )
*(_QWORD *)(a1 + 24) = 0LL;
--*(_DWORD *)(a1 + 8);
return result;
}

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

result = *(_QWORD *)(*(_QWORD *)(a1 + 16) + 16LL);
*(_QWORD *)(a1 + 16) = result;
if ( !result )
*(_QWORD *)(a1 + 24) = 0LL;
--*(_DWORD *)(a1 + 8);
return result;
}

original_code:
void cq_pop_front(cli_queue* q)
{
 client* h = q->head;
 client* p = h->next;
 q->head = p;
 if (((void *)0) == q->head) {
  q->tail = ((void *)0);
 }
 --q->size;
}

canonical_original_code:
void cq_pop_front(struct cli_queue *q)
{
 struct client *h = q->head;
 struct client *p = h->next;
 q->head = p;
 if (((void *)0) == q->head) {
  q->tail = ((void *)0);
 }
 --q->size;
}

variable_types: struct client { int conn; short evt; void *arg; struct client *next; } *

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


decompiled_code:
void *__fastcall dispatch_worker(void *a1)
{
pthread_mutex_t *v2; // r12
unsigned int *v3; // rbx
__int64 v4; // rdi

*((_DWORD *)a1 + 2) = 0;
*((_QWORD *)a1 + 3) = 0LL;
*((_QWORD *)a1 + 2) = 0LL;
v2 = (pthread_mutex_t *)((char *)a1 + 32);
pthread_mutex_init((pthread_mutex_t *)((char *)a1 + 32), 0LL);
while ( 1 )
{
while ( 1 )
{
pthread_mutex_lock(v2);
if ( *((int *)a1 + 2) > 0 )
break;
pthread_mutex_unlock(v2);
usleep(0x3E8u);
}
v3 = (unsigned int *)cq_front((__int64)a1);
cq_pop_front((__int64)a1);
pthread_mutex_unlock(v2);
v4 = *v3;
if ( (_DWORD)v4 == -1 )
break;
qword_928(v4, (unsigned int)*((__int16 *)v3 + 2), *((_QWORD *)v3 + 1));
free(v3);
}
free(v3);
pthread_mutex_destroy(v2);
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func28(void *a1)
{
pthread_mutex_t *v2; // r12
unsigned int *v3; // rbx
__int64 v4; // rdi

*((_DWORD *)a1 + 2) = 0;
*((_QWORD *)a1 + 3) = 0LL;
*((_QWORD *)a1 + 2) = 0LL;
v2 = (pthread_mutex_t *)((char *)a1 + 32);
pthread_mutex_init((pthread_mutex_t *)((char *)a1 + 32), 0LL);
while ( 1 )
{
while ( 1 )
{
pthread_mutex_lock(v2);
if ( *((int *)a1 + 2) > 0 )
break;
pthread_mutex_unlock(v2);
usleep(0x3E8u);
}
v3 = (unsigned int *)func23((__int64)a1);
func27((__int64)a1);
pthread_mutex_unlock(v2);
v4 = *v3;
if ( (_DWORD)v4 == -1 )
break;
qword_928(v4, (unsigned int)*((__int16 *)v3 + 2), *((_QWORD *)v3 + 1));
free(v3);
}
free(v3);
pthread_mutex_destroy(v2);
return 0LL;
}

original_code:
void* dispatch_worker(void* arg)
{
 cli_queue* q = arg;
 q->size = 0;
 q->head = q->tail = ((void *)0);
 pthread_mutex_init(&q->lock, ((void *)0));
 while (1) {
  pthread_mutex_lock(&q->lock);
  if (q->size > 0) {
   client* cli = cq_front(q);
   cq_pop_front(q);
   pthread_mutex_unlock(&q->lock);
   if (cli->conn == -1) {
    free(cli);
    pthread_mutex_destroy(&q->lock);
    return ((void *)0);
   } else {
    pool.slave(cli->conn, cli->evt,
        cli->arg);
    free(cli);
   }
  } else {
   pthread_mutex_unlock(&q->lock);
   usleep(1000);
  }
 }
 return ((void *)0);
}

canonical_original_code:
void *dispatch_worker(void *arg)
{
 struct cli_queue *q = arg;
 q->size = 0;
 q->head = q->tail = ((void *)0);
 pthread_mutex_init(&q->lock, ((void *)0));
 while (1) {
  pthread_mutex_lock(&q->lock);
  if (q->size > 0) {
   struct client *cli = cq_front(q);
   cq_pop_front(q);
   pthread_mutex_unlock(&q->lock);
   if (cli->conn == -1) {
    free(cli);
    pthread_mutex_destroy(&q->lock);
    return ((void *)0);
   } else {
    pool.slave(cli->conn, cli->evt,
        cli->arg);
    free(cli);
   }
  } else {
   pthread_mutex_unlock(&q->lock);
   usleep(1000);
  }
 }
 return ((void *)0);
}

return_type: void *

user_defined_types: struct client { int conn; short evt; void *arg; struct client *next; }


pushbyte

repo: vegard/rgbds-linux

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

result = *(_QWORD *)(a1 + 264);
*(_QWORD *)(a1 + 264) = result + 1;
*(_BYTE *)(a1 + result + 8) = a2;
return result;
}

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

result = *(_QWORD *)(a1 + 264);
*(_QWORD *)(a1 + 264) = result + 1;
*(_BYTE *)(a1 + result + 8) = a2;
return result;
}

original_code:
void pushbyte(struct Expression *expr, int b)
{
 expr->tRPN[expr->nRPNLength++] = b & 0xFF;
}

variable_types: struct Expression { long nVal; unsigned char tRPN[256]; unsigned long nRPNLength; unsigned long nRPNOut; unsigned long isReloc; unsigned long isPCRel; } *

variable_types: b int


original_code:
UWORD rpn_PopByte(struct Expression *expr)
{
 if (expr->nRPNOut == expr->nRPNLength) {
  return (0xDEAD);
 } else
  return (expr->tRPN[expr->nRPNOut++]);
}

canonical_original_code:
unsigned short rpn_PopByte(struct Expression *expr)
{
 if (expr->nRPNOut == expr->nRPNLength) {
  return (0xDEAD);
 } else
  return (expr->tRPN[expr->nRPNOut++]);
}

return_type: unsigned short

user_defined_types: struct Expression { long nVal; unsigned char tRPN[256]; unsigned long nRPNLength; unsigned long nRPNOut; unsigned long isReloc; unsigned long isPCRel; }


decompiled_code:
__int64 __fastcall rpn_isReloc(__int64 a1)
{
return *(_QWORD *)(a1 + 280);
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
return *(_QWORD *)(a1 + 280);
}

original_code:
ULONG rpn_isReloc(struct Expression * expr)
{
 return (expr->isReloc);
}

canonical_original_code:
unsigned long rpn_isReloc(struct Expression *expr)
{
 return (expr->isReloc);
}

return_type: unsigned long


decompiled_code:
__int64 __fastcall rpn_isPCRelative(__int64 a1)
{
return *(_QWORD *)(a1 + 288);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
return *(_QWORD *)(a1 + 288);
}

original_code:
ULONG rpn_isPCRelative(struct Expression * expr)
{
 return (expr->isPCRel);
}

canonical_original_code:
unsigned long rpn_isPCRelative(struct Expression *expr)
{
 return (expr->isPCRel);
}


decompiled_code:
__int64 __fastcall rpn_RangeCheck(_QWORD *a1, const void *a2, __int64 a3, __int64 a4)
{
qmemcpy(a1, a2, 0x128uLL);
if ( !rpn_isReloc((__int64)a2) )
return (*a1 <= a4) & (unsigned __int8)(*a1 >= a3);
pushbyte((__int64)a1, 24);
pushbyte((__int64)a1, a3);
pushbyte((__int64)a1, SBYTE1(a3));
pushbyte((__int64)a1, SBYTE2(a3));
pushbyte((__int64)a1, SBYTE3(a3));
pushbyte((__int64)a1, a4);
pushbyte((__int64)a1, SBYTE1(a4));
pushbyte((__int64)a1, SBYTE2(a4));
pushbyte((__int64)a1, SBYTE3(a4));
return 1LL;
}

original_code:
int rpn_RangeCheck(struct Expression *expr, struct Expression *src, SLONG low,
     SLONG high)
{
 *expr = *src;
 if (rpn_isReloc(src)) {
  pushbyte(expr, RPN_RANGECHECK);
  pushbyte(expr, low);
  pushbyte(expr, low >> 8);
  pushbyte(expr, low >> 16);
  pushbyte(expr, low >> 24);
  pushbyte(expr, high);
  pushbyte(expr, high >> 8);
  pushbyte(expr, high >> 16);
  pushbyte(expr, high >> 24);
  return (1);
 } else {
  return (expr->nVal >= low && expr->nVal <= high);
 }
}

canonical_original_code:
int rpn_RangeCheck(struct Expression *expr, struct Expression *src, long low, long high)
{
 *expr = *src;
 if (rpn_isReloc(src)) {
  pushbyte(expr, RPN_RANGECHECK);
  pushbyte(expr, low);
  pushbyte(expr, low >> 8);
  pushbyte(expr, low >> 16);
  pushbyte(expr, low >> 24);
  pushbyte(expr, high);
  pushbyte(expr, high >> 8);
  pushbyte(expr, high >> 16);
  pushbyte(expr, high >> 24);
  return (1);
 } else {
  return (expr->nVal >= low && expr->nVal <= high);
 }
}

variable_types:
src
struct Expression *

variable_types: low long

variable_types: high long


decompiled_code:
__int64 __fastcall rpn_CheckHRAM(void *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
return pushbyte((__int64)a1, 22);
}

canonical_decompiled_code:
__int64 __fastcall func10(void *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
return func1((__int64)a1, 22);
}

original_code:
void rpn_CheckHRAM(struct Expression *expr, struct Expression *src)
{
 *expr = *src;
 pushbyte(expr, RPN_HRAM);
}


decompiled_code:
__int64 __fastcall rpn_LOGNOT(void *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
return pushbyte((__int64)a1, 12);
}

canonical_decompiled_code:
__int64 __fastcall func11(void *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
return func1((__int64)a1, 12);
}

original_code:
void rpn_LOGNOT(struct Expression *expr, struct Expression *src)
{
 *expr = *src;
 pushbyte(expr, RPN_LOGUNNOT);
}


decompiled_code:
__int64 __fastcall rpn_LOGOR(_QWORD *a1, const void *a2, size_t *a3)
{
_BOOL4 v4; // eax

mergetwoexpressions(a1, a2, a3);
v4 = 1;
if ( !*a1 )
v4 = *a3 != 0;
*a1 = v4;
return pushbyte((__int64)a1, 11);
}

canonical_decompiled_code:
__int64 __fastcall func12(_QWORD *a1, const void *a2, size_t *a3)
{
_BOOL4 v4; // eax

func0(a1, a2, a3);
v4 = 1;
if ( !*a1 )
v4 = *a3 != 0;
*a1 = v4;
return func1((__int64)a1, 11);
}

original_code:
void rpn_LOGOR(struct Expression *expr, struct Expression *src1,
        struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal || src2->nVal);
 pushbyte(expr, RPN_LOGOR);
}


decompiled_code:
__int64 __fastcall rpn_LOGAND(_QWORD *a1, const void *a2, size_t *a3)
{
_BOOL4 v4; // eax

mergetwoexpressions(a1, a2, a3);
v4 = 0;
if ( *a1 )
v4 = *a3 != 0;
*a1 = v4;
return pushbyte((__int64)a1, 10);
}

canonical_decompiled_code:
__int64 __fastcall func13(_QWORD *a1, const void *a2, size_t *a3)
{
_BOOL4 v4; // eax

func0(a1, a2, a3);
v4 = 0;
if ( *a1 )
v4 = *a3 != 0;
*a1 = v4;
return func1((__int64)a1, 10);
}

original_code:
void rpn_LOGAND(struct Expression *expr, struct Expression *src1,
  struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal && src2->nVal);
 pushbyte(expr, RPN_LOGAND);
}


decompiled_code:
__int64 __fastcall rpn_LOGEQU(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 = *a1 == *a3;
return pushbyte((__int64)a1, 13);
}

canonical_decompiled_code:
__int64 __fastcall func14(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 = *a1 == *a3;
return func1((__int64)a1, 13);
}

original_code:
void rpn_LOGEQU(struct Expression *expr, struct Expression *src1,
  struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal == src2->nVal);
 pushbyte(expr, RPN_LOGEQ);
}


decompiled_code:
__int64 __fastcall rpn_LOGGT(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 = *a1 > (__int64)*a3;
return pushbyte((__int64)a1, 15);
}

canonical_decompiled_code:
__int64 __fastcall func15(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 = *a1 > (__int64)*a3;
return func1((__int64)a1, 15);
}

original_code:
void rpn_LOGGT(struct Expression *expr, struct Expression *src1,
        struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal > src2->nVal);
 pushbyte(expr, RPN_LOGGT);
}


decompiled_code:
__int64 __fastcall rpn_LOGLT(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 = *a1 < (__int64)*a3;
return pushbyte((__int64)a1, 16);
}

canonical_decompiled_code:
__int64 __fastcall func16(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 = *a1 < (__int64)*a3;
return func1((__int64)a1, 16);
}

original_code:
void rpn_LOGLT(struct Expression *expr, struct Expression *src1,
        struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal < src2->nVal);
 pushbyte(expr, RPN_LOGLT);
}


decompiled_code:
__int64 __fastcall rpn_LOGGE(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 = *a1 >= (__int64)*a3;
return pushbyte((__int64)a1, 17);
}

canonical_decompiled_code:
__int64 __fastcall func17(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 = *a1 >= (__int64)*a3;
return func1((__int64)a1, 17);
}

original_code:
void rpn_LOGGE(struct Expression *expr, struct Expression *src1,
        struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal >= src2->nVal);
 pushbyte(expr, RPN_LOGGE);
}


decompiled_code:
__int64 __fastcall rpn_LOGLE(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 = *a1 <= (__int64)*a3;
return pushbyte((__int64)a1, 18);
}

canonical_decompiled_code:
__int64 __fastcall func18(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 = *a1 <= (__int64)*a3;
return func1((__int64)a1, 18);
}

original_code:
void rpn_LOGLE(struct Expression *expr, struct Expression *src1,
        struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal <= src2->nVal);
 pushbyte(expr, RPN_LOGLE);
}


decompiled_code:
__int64 __fastcall rpn_LOGNE(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 = *a1 != *a3;
return pushbyte((__int64)a1, 14);
}

canonical_decompiled_code:
__int64 __fastcall func19(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 = *a1 != *a3;
return func1((__int64)a1, 14);
}

original_code:
void rpn_LOGNE(struct Expression *expr, struct Expression *src1,
        struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal != src2->nVal);
 pushbyte(expr, RPN_LOGNE);
}


decompiled_code:
__int64 __fastcall rpn_ADD(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 += *a3;
return pushbyte((__int64)a1, 0);
}

canonical_decompiled_code:
__int64 __fastcall func20(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 += *a3;
return func1((__int64)a1, 0);
}

original_code:
void rpn_ADD(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal + src2->nVal);
 pushbyte(expr, RPN_ADD);
}


decompiled_code:
__int64 __fastcall rpn_SUB(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 -= *a3;
return pushbyte((__int64)a1, 1);
}

canonical_decompiled_code:
__int64 __fastcall func21(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 -= *a3;
return func1((__int64)a1, 1);
}

original_code:
void rpn_SUB(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal - src2->nVal);
 pushbyte(expr, RPN_SUB);
}


decompiled_code:
__int64 __fastcall rpn_XOR(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 ^= *a3;
return pushbyte((__int64)a1, 8);
}

canonical_decompiled_code:
__int64 __fastcall func22(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 ^= *a3;
return func1((__int64)a1, 8);
}

original_code:
void rpn_XOR(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal ^ src2->nVal);
 pushbyte(expr, RPN_XOR);
}


decompiled_code:
__int64 __fastcall rpn_OR(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 |= *a3;
return pushbyte((__int64)a1, 6);
}

canonical_decompiled_code:
__int64 __fastcall func23(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 |= *a3;
return func1((__int64)a1, 6);
}

original_code:
void rpn_OR(struct Expression *expr, struct Expression *src1,
     struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal | src2->nVal);
 pushbyte(expr, RPN_OR);
}


decompiled_code:
__int64 __fastcall rpn_AND(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 &= *a3;
return pushbyte((__int64)a1, 7);
}

canonical_decompiled_code:
__int64 __fastcall func24(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 &= *a3;
return func1((__int64)a1, 7);
}

original_code:
void rpn_AND(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal & src2->nVal);
 pushbyte(expr, RPN_AND);
}


decompiled_code:
__int64 __fastcall rpn_SHL(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 <<= *a3;
return pushbyte((__int64)a1, 19);
}

canonical_decompiled_code:
__int64 __fastcall func25(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 <<= *a3;
return func1((__int64)a1, 19);
}

original_code:
void rpn_SHL(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal << src2->nVal);
 pushbyte(expr, RPN_SHL);
}


decompiled_code:
__int64 __fastcall rpn_SHR(__int64 *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 >>= *a3;
return pushbyte((__int64)a1, 20);
}

canonical_decompiled_code:
__int64 __fastcall func26(__int64 *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 >>= *a3;
return func1((__int64)a1, 20);
}

original_code:
void rpn_SHR(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal >> src2->nVal);
 pushbyte(expr, RPN_SHR);
}


decompiled_code:
__int64 __fastcall rpn_MUL(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 *= *a3;
return pushbyte((__int64)a1, 2);
}

canonical_decompiled_code:
__int64 __fastcall func27(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 *= *a3;
return func1((__int64)a1, 2);
}

original_code:
void rpn_MUL(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal * src2->nVal);
 pushbyte(expr, RPN_MUL);
}


decompiled_code:
__int64 __fastcall rpn_DIV(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 /= (__int64)*a3;
return pushbyte((__int64)a1, 3);
}

canonical_decompiled_code:
__int64 __fastcall func28(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 /= (__int64)*a3;
return func1((__int64)a1, 3);
}

original_code:
void rpn_DIV(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal / src2->nVal);
 pushbyte(expr, RPN_DIV);
}


decompiled_code:
__int64 __fastcall rpn_MOD(_QWORD *a1, const void *a2, size_t *a3)
{
mergetwoexpressions(a1, a2, a3);
*a1 %= (__int64)*a3;
return pushbyte((__int64)a1, 4);
}

canonical_decompiled_code:
__int64 __fastcall func29(_QWORD *a1, const void *a2, size_t *a3)
{
func0(a1, a2, a3);
*a1 %= (__int64)*a3;
return func1((__int64)a1, 4);
}

original_code:
void rpn_MOD(struct Expression *expr, struct Expression *src1,
      struct Expression *src2)
{
 mergetwoexpressions(expr,src1,src2);
 expr->nVal = (expr->nVal % src2->nVal);
 pushbyte(expr, RPN_MOD);
}


decompiled_code:
__int64 __fastcall rpn_UNNEG(_QWORD *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
*a1 = -*a1;
return pushbyte((__int64)a1, 5);
}

canonical_decompiled_code:
__int64 __fastcall func30(_QWORD *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
*a1 = -*a1;
return func1((__int64)a1, 5);
}

original_code:
void rpn_UNNEG(struct Expression *expr, struct Expression *src)
{
 *expr = *src;
 expr->nVal = -expr->nVal;
 pushbyte(expr, RPN_UNSUB);
}


decompiled_code:
__int64 __fastcall rpn_UNNOT(_QWORD *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
*a1 ^= 0xFFFFFFFFuLL;
return pushbyte((__int64)a1, 9);
}

canonical_decompiled_code:
__int64 __fastcall func31(_QWORD *a1, const void *a2)
{
qmemcpy(a1, a2, 0x128uLL);
*a1 ^= 0xFFFFFFFFuLL;
return func1((__int64)a1, 9);
}

original_code:
void rpn_UNNOT(struct Expression *expr, struct Expression *src)
{
 *expr = *src;
 expr->nVal = expr->nVal ^ 0xFFFFFFFF;
 pushbyte(expr, RPN_UNNOT);
}


decompiled_code:
__int64 __fastcall area_Avail(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rdx

v1 = BankFree[a1];
if ( !v1 )
return 0LL;
v2 = 0LL;
do
{
v2 += *(_QWORD *)(v1 + 8);
v1 = *(_QWORD *)(v1 + 24);
}
while ( v1 );
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
__int64 v1; // rax
__int64 v2; // rdx

v1 = BankFree[a1];
if ( !v1 )
return 0LL;
v2 = 0LL;
do
{
v2 += *(_QWORD *)(v1 + 8);
v1 = *(_QWORD *)(v1 + 24);
}
while ( v1 );
return v2;
}

original_code:
SLONG area_Avail(SLONG bank)
{
 SLONG r;
 struct sFreeArea *pArea;
 r = 0;
 pArea = BankFree[bank];
 while (pArea) {
  r += pArea->nSize;
  pArea = pArea->pNext;
 }
 return (r);
}

canonical_original_code:
long area_Avail(long bank)
{
 long r;
 struct sFreeArea *pArea;
 r = 0;
 pArea = BankFree[bank];
 while (pArea) {
  r += pArea->nSize;
  pArea = pArea->pNext;
 }
 return (r);
}

variable_types: bank long

variable_types: r long

variable_types: struct sFreeArea { long nOrg; long nSize; struct sFreeArea *pPrev; } *

return_type: long


original_code:
SLONG area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
{
 struct sFreeArea *pArea;
 pArea = *ppArea;
 while (pArea) {
  if (org >= pArea->nOrg
      && (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) {
   if (org == pArea->nOrg) {
    pArea->nOrg += size;
    pArea->nSize -= size;
    return (org);
   } else {
    if ((org + size - 1) ==
        (pArea->nOrg + pArea->nSize - 1)) {
     pArea->nSize -= size;
     return (org);
    } else {
     struct sFreeArea *pNewArea;
     if ((pNewArea =
          (struct sFreeArea *)
          malloc(sizeof(struct sFreeArea)))
         != ((void *)0)) {
      *pNewArea = *pArea;
      pNewArea->pPrev = pArea;
      pArea->pNext = pNewArea;
      pArea->nSize =
          org - pArea->nOrg;
      pNewArea->nOrg = org + size;
      pNewArea->nSize -=
          size + pArea->nSize;
      return (org);
     } else
      fatalerror("Out of memory!");
    }
   }
  }
  ppArea = &(pArea->pNext);
  pArea = *ppArea;
 }
 return (-1);
}

canonical_original_code:
long area_AllocAbs(struct sFreeArea **ppArea, long org, long size)
{
 struct sFreeArea *pArea;
 pArea = *ppArea;
 while (pArea) {
  if (org >= pArea->nOrg
      && (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) {
   if (org == pArea->nOrg) {
    pArea->nOrg += size;
    pArea->nSize -= size;
    return (org);
   } else {
    if ((org + size - 1) ==
        (pArea->nOrg + pArea->nSize - 1)) {
     pArea->nSize -= size;
     return (org);
    } else {
     struct sFreeArea *pNewArea;
     if ((pNewArea =
          (struct sFreeArea *)
          malloc(sizeof(struct sFreeArea)))
         != ((void *)0)) {
      *pNewArea = *pArea;
      pNewArea->pPrev = pArea;
      pArea->pNext = pNewArea;
      pArea->nSize =
          org - pArea->nOrg;
      pNewArea->nOrg = org + size;
      pNewArea->nSize -=
          size + pArea->nSize;
      return (org);
     } else
      fatalerror("Out of memory!");
    }
   }
  }
  ppArea = &(pArea->pNext);
  pArea = *ppArea;
 }
 return (-1);
}

variable_types: struct sFreeArea { long nOrg; long nSize; struct sFreeArea *pPrev; } **

variable_types: org long

variable_types: size long


decompiled_code:
__int64 __fastcall area_AllocAbsCODEAnyBank(__int64 a1, __int64 a2)
{
__int64 v2; // rbx

v2 = 1LL;
while ( area_AllocAbs((__m128i **)&BankFree[v2], a1, a2) != a1 )
{
if ( ++v2 == 256 )
return -1LL;
}
return v2;
}

original_code:
SLONG area_AllocAbsCODEAnyBank(SLONG org, SLONG size)
{
 SLONG i;
 for (i = 1; i <= 255; i += 1) {
  if (area_AllocAbs(&BankFree[i], org, size) == org)
   return (i);
 }
 return (-1);
}

canonical_original_code:
long area_AllocAbsCODEAnyBank(long org, long size)
{
 long i;
 for (i = 1; i <= 255; i += 1) {
  if (area_AllocAbs(&BankFree[i], org, size) == org)
   return (i);
 }
 return (-1);
}

variable_types: i long


original_code:
SLONG area_Alloc(struct sFreeArea ** ppArea, SLONG size)
{
 struct sFreeArea *pArea;
 pArea = *ppArea;
 while (pArea) {
  if (size <= pArea->nSize) {
   SLONG r;
   r = pArea->nOrg;
   pArea->nOrg += size;
   pArea->nSize -= size;
   return (r);
  }
  ppArea = &(pArea->pNext);
  pArea = *ppArea;
 }
 return (-1);
}

canonical_original_code:
long area_Alloc(struct sFreeArea **ppArea, long size)
{
 struct sFreeArea *pArea;
 pArea = *ppArea;
 while (pArea) {
  if (size <= pArea->nSize) {
   long r;
   r = pArea->nOrg;
   pArea->nOrg += size;
   pArea->nSize -= size;
   return (r);
  }
  ppArea = &(pArea->pNext);
  pArea = *ppArea;
 }
 return (-1);
}

user_defined_types: struct sFreeArea { long nOrg; long nSize; struct sFreeArea *pPrev; }


decompiled_code:
__int64 __fastcall area_AllocCODEAnyBank(__int64 a1)
{
__int64 v1; // rbx
__int64 result; // rax

v1 = 1LL;
while ( 1 )
{
result = area_Alloc((__int64 **)&BankFree[v1], a1);
if ( result != -1 )
break;
if ( ++v1 == 256 )
return result;
}
return (v1 << 16) | result;
}

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

v1 = 1LL;
while ( 1 )
{
result = func3((__int64 **)&BankFree[v1], a1);
if ( result != -1 )
break;
if ( ++v1 == 256 )
return result;
}
return (v1 << 16) | result;
}

original_code:
SLONG area_AllocCODEAnyBank(SLONG size)
{
 SLONG i, org;
 for (i = 1; i <= 255; i += 1) {
  if ((org = area_Alloc(&BankFree[i], size)) != -1)
   return ((i << 16) | org);
 }
 return (-1);
}

canonical_original_code:
long area_AllocCODEAnyBank(long size)
{
 long i; long org;
 for (i = 1; i <= 255; i += 1) {
  if ((org = area_Alloc(&BankFree[i], size)) != -1)
   return ((i << 16) | org);
 }
 return (-1);
}


FindLargestCode

original_code:
struct sSection *FindLargestCode(void)
{
 struct sSection *pSection, *r = ((void *)0);
 SLONG nLargest = 0;
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0 && pSection->Type == SECT_CODE) {
   if (pSection->nByteSize > nLargest) {
    nLargest = pSection->nByteSize;
    r = pSection;
   }
  }
  pSection = pSection->pNext;
 }
 return (r);
}

canonical_original_code:
struct sSection *FindLargestCode()
{
 struct sSection *pSection; struct sSection *r = ((void *)0);
 long nLargest = 0;
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0 && pSection->Type == SECT_CODE) {
   if (pSection->nByteSize > nLargest) {
    nLargest = pSection->nByteSize;
    r = pSection;
   }
  }
  pSection = pSection->pNext;
 }
 return (r);
}

variable_types: struct sSection { long nBank; long nOrg; char oAssigned; long nByteSize; enum eSectionType { SECT_BSS=0, SECT_VRAM=1, SECT_CODE=2, SECT_HOME=3, SECT_HRAM=4 } Type; unsigned char *pData; long nNumberOfSymbols; struct sSymbol { char *pzName; enum eSymbolType { SYM_LOCAL=0, SYM_IMPORT=1, SYM_EXPORT=2 } Type; long nSectionID; struct sSection *pSection; long nOffset; } **tSymbols; struct sPatch { char *pzFilename; long nLineNo; long nOffset; enum ePatchType { PATCH_BYTE=0, PATCH_WORD_L=1, PATCH_LONG_L=2, PATCH_WORD_B=3, PATCH_LONG_B=4 } Type; long nRPNSize; unsigned char *pRPN; struct sPatch *pNext; char oRelocPatch; } *pPatches; struct sSection *pNext; } *

variable_types: nLargest long

user_defined_types: struct sSection { long nBank; long nOrg; char oAssigned; long nByteSize; enum eSectionType Type; unsigned char *pData; long nNumberOfSymbols; struct sSymbol **tSymbols; struct sPatch *pPatches; struct sSection *pNext; }

user_defined_types: struct sPatch { char *pzFilename; long nLineNo; long nOffset; enum ePatchType Type; long nRPNSize; unsigned char *pRPN; struct sPatch *pNext; char oRelocPatch; }

user_defined_types: struct sSymbol { char *pzName; enum eSymbolType Type; long nSectionID; struct sSection *pSection; long nOffset; }


AssignCodeSections

decompiled_code:
__int64 AssignCodeSections()
{
__int64 result; // rax
__int64 v1; // rbx
__int64 v2; // rax
__int64 v3; // rax

while ( 1 )
{
result = FindLargestCode();
v1 = result;
if ( !result )
break;
v2 = area_AllocCODEAnyBank(*(_QWORD *)(result + 24));
if ( v2 == -1 )
{
fatalerror("Unable to place CODE section anywhere");
}
else
{
*(_QWORD *)(v1 + 8) = (unsigned __int16)v2;
v3 = v2 >> 16;
*(_QWORD *)v1 = v3;
*(_BYTE *)(v1 + 16) = 1;
if ( v3 > MaxBankUsed )
MaxBankUsed = v3;
}
}
return result;
}

canonical_decompiled_code:
__int64 func6()
{
__int64 result; // rax
__int64 v1; // rbx
__int64 v2; // rax
__int64 v3; // rax

while ( 1 )
{
result = func5();
v1 = result;
if ( !result )
break;
v2 = func4(*(_QWORD *)(result + 24));
if ( v2 == -1 )
{
fatalerror("Unable to place CODE section anywhere");
}
else
{
*(_QWORD *)(v1 + 8) = (unsigned __int16)v2;
v3 = v2 >> 16;
*(_QWORD *)v1 = v3;
*(_BYTE *)(v1 + 16) = 1;
if ( v3 > MaxBankUsed )
MaxBankUsed = v3;
}
}
return result;
}

original_code:
void AssignCodeSections(void)
{
 struct sSection *pSection;
 while ((pSection = FindLargestCode())) {
  SLONG org;
  if ((org = area_AllocCODEAnyBank(pSection->nByteSize)) != -1) {
   pSection->nOrg = org & 0xFFFF;
   pSection->nBank = org >> 16;
   pSection->oAssigned = 1;
   {if( (pSection->nBank)>MaxBankUsed ) MaxBankUsed=(pSection->nBank);};
  } else
   fatalerror("Unable to place CODE section anywhere");
 }
}

canonical_original_code:
void AssignCodeSections()
{
 struct sSection *pSection;
 while ((pSection = FindLargestCode())) {
  long org;
  if ((org = area_AllocCODEAnyBank(pSection->nByteSize)) != -1) {
   pSection->nOrg = org & 0xFFFF;
   pSection->nBank = org >> 16;
   pSection->oAssigned = 1;
   {if( (pSection->nBank)>MaxBankUsed ) MaxBankUsed=(pSection->nBank);};
  } else
   fatalerror("Unable to place CODE section anywhere");
 }
}

user_defined_types: enum eSectionType { SECT_BSS=0, SECT_VRAM=1, SECT_CODE=2, SECT_HOME=3, SECT_HRAM=4 }

user_defined_types: enum ePatchType { PATCH_BYTE=0, PATCH_WORD_L=1, PATCH_LONG_L=2, PATCH_WORD_B=3, PATCH_LONG_B=4 }

user_defined_types: enum eSymbolType { SYM_LOCAL=0, SYM_IMPORT=1, SYM_EXPORT=2 }


original_code:
void GBROM_AssignSections(void)
{
 SLONG i;
 struct sSection *pSection;
 MaxBankUsed = 0;
 for (i = 0; i < 259; i += 1) {
  BankFree[i] = malloc(sizeof *BankFree[i]);
  if (!BankFree[i])
   fatalerror("Out of memory!");
  if (i == 0) {
   BankFree[i]->nOrg = 0x0000;
   if (options & 0x01) {
    BankFree[i]->nSize = 0x8000;
    MaxAvail[i] = 0x8000;
   } else {
    BankFree[i]->nSize = 0x4000;
    MaxAvail[i] = 0x4000;
   }
  } else if (i >= 1 && i <= 255) {
   BankFree[i]->nOrg = 0x4000;
   if (options & 0x01) {
    BankFree[i]->nSize = 0;
    MaxAvail[i] = 0;
   } else {
    BankFree[i]->nSize = 0x4000;
    MaxAvail[i] = 0x4000;
   }
  } else if (i == BANK_BSS) {
   BankFree[i]->nOrg = 0xC000;
   BankFree[i]->nSize = 0x2000;
   MaxAvail[i] = 0x2000;
  } else if (i == BANK_VRAM) {
   BankFree[i]->nOrg = 0x8000;
   BankFree[i]->nSize = 0x2000;
   MaxAvail[i] = 0x2000;
  } else if (i == BANK_HRAM) {
   BankFree[i]->nOrg = 0xFF80;
   BankFree[i]->nSize = 0x007F;
   MaxAvail[i] = 0x007F;
  }
  BankFree[i]->pPrev = ((void *)0);
  BankFree[i]->pNext = ((void *)0);
 }
 pSection = pSections;
 while (pSection) {
  if ((pSection->nOrg != -1 || pSection->nBank != -1)
      && pSection->oAssigned == 0) {
   switch (pSection->Type) {
   case SECT_BSS:
    if (area_AllocAbs
        (&BankFree[BANK_BSS], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed BSS section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_BSS;
    break;
   case SECT_HRAM:
    if (area_AllocAbs
        (&BankFree[BANK_HRAM], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed HRAM section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_HRAM;
    break;
   case SECT_VRAM:
    if (area_AllocAbs
        (&BankFree[BANK_VRAM], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed VRAM section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_VRAM;
    break;
   case SECT_HOME:
    if (area_AllocAbs
        (&BankFree[BANK_HOME], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed HOME section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_HOME;
    break;
   case SECT_CODE:
    if (pSection->nBank == -1) {
    } else {
     if (pSection->nOrg == -1) {
     } else {
      if (pSection->nBank >= 1
          && pSection->nBank <= 255) {
       if (area_AllocAbs
           (&BankFree
            [pSection->nBank],
            pSection->nOrg,
            pSection->
            nByteSize) !=
           pSection->nOrg) {
        sprintf
            (temptext,
             "Unable to load fixed CODE/DATA section at $%lX in bank $%02lX",
             pSection->
             nOrg,
             pSection->
             nBank);
        fatalerror
            (temptext);
       }
       {if( (pSection-> nBank)>MaxBankUsed ) MaxBankUsed=(pSection-> nBank);};
       pSection->oAssigned = 1;
      } else {
       sprintf(temptext,
        "Unable to load fixed CODE/DATA section at $%lX in bank $%02lX",
        pSection->nOrg,
        pSection->
        nBank);
       fatalerror(temptext);
      }
     }
    }
    break;
   }
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
      && pSection->Type == SECT_CODE
      && pSection->nOrg == -1 && pSection->nBank != -1) {
   if (pSection->nBank >= 1 && pSection->nBank <= 255) {
    if ((pSection->nOrg =
         area_Alloc(&BankFree[pSection->nBank],
      pSection->nByteSize)) == -1) {
     sprintf(temptext,
      "Unable to load fixed CODE/DATA section into bank $%02lX",
      pSection->nBank);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    {if( (pSection->nBank)>MaxBankUsed ) MaxBankUsed=(pSection->nBank);};
   } else {
    sprintf(temptext,
     "Unable to load fixed CODE/DATA section into bank $%02lX",
     pSection->nBank);
    fatalerror(temptext);
   }
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
      && pSection->Type == SECT_CODE
      && pSection->nOrg != -1 && pSection->nBank == -1) {
   if ((pSection->nBank =
        area_AllocAbsCODEAnyBank(pSection->nOrg,
            pSection->nByteSize)) ==
       -1) {
    sprintf(temptext,
     "Unable to load fixed CODE/DATA section at $%lX into any bank",
     pSection->nOrg);
    fatalerror(temptext);
   }
   pSection->oAssigned = 1;
   {if( (pSection->nBank)>MaxBankUsed ) MaxBankUsed=(pSection->nBank);};
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0) {
   switch (pSection->Type) {
   case SECT_BSS:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_BSS],
      pSection->nByteSize)) == -1) {
     fatalerror("BSS section too large\n");
    }
    pSection->nBank = BANK_BSS;
    pSection->oAssigned = 1;
    break;
   case SECT_HRAM:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_HRAM],
      pSection->nByteSize)) == -1) {
     fatalerror("HRAM section too large");
    }
    pSection->nBank = BANK_HRAM;
    pSection->oAssigned = 1;
    break;
   case SECT_VRAM:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_VRAM],
      pSection->nByteSize)) == -1) {
     fatalerror("VRAM section too large");
    }
    pSection->nBank = BANK_VRAM;
    pSection->oAssigned = 1;
    break;
   case SECT_HOME:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_HOME],
      pSection->nByteSize)) == -1) {
     fatalerror("HOME section too large");
    }
    pSection->nBank = BANK_HOME;
    pSection->oAssigned = 1;
    break;
   case SECT_CODE:
    break;
   default:
    fatalerror("(INTERNAL) Unknown section type!");
    break;
   }
  }
  pSection = pSection->pNext;
 }
 AssignCodeSections();
}

canonical_original_code:
void GBROM_AssignSections()
{
 long i;
 struct sSection *pSection;
 MaxBankUsed = 0;
 for (i = 0; i < 259; i += 1) {
  BankFree[i] = malloc(sizeof *BankFree[i]);
  if (!BankFree[i])
   fatalerror("Out of memory!");
  if (i == 0) {
   BankFree[i]->nOrg = 0x0000;
   if (options & 0x01) {
    BankFree[i]->nSize = 0x8000;
    MaxAvail[i] = 0x8000;
   } else {
    BankFree[i]->nSize = 0x4000;
    MaxAvail[i] = 0x4000;
   }
  } else if (i >= 1 && i <= 255) {
   BankFree[i]->nOrg = 0x4000;
   if (options & 0x01) {
    BankFree[i]->nSize = 0;
    MaxAvail[i] = 0;
   } else {
    BankFree[i]->nSize = 0x4000;
    MaxAvail[i] = 0x4000;
   }
  } else if (i == BANK_BSS) {
   BankFree[i]->nOrg = 0xC000;
   BankFree[i]->nSize = 0x2000;
   MaxAvail[i] = 0x2000;
  } else if (i == BANK_VRAM) {
   BankFree[i]->nOrg = 0x8000;
   BankFree[i]->nSize = 0x2000;
   MaxAvail[i] = 0x2000;
  } else if (i == BANK_HRAM) {
   BankFree[i]->nOrg = 0xFF80;
   BankFree[i]->nSize = 0x007F;
   MaxAvail[i] = 0x007F;
  }
  BankFree[i]->pPrev = ((void *)0);
  BankFree[i]->pNext = ((void *)0);
 }
 pSection = pSections;
 while (pSection) {
  if ((pSection->nOrg != -1 || pSection->nBank != -1)
      && pSection->oAssigned == 0) {
   switch (pSection->Type) {
   case SECT_BSS:
    if (area_AllocAbs
        (&BankFree[BANK_BSS], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed BSS section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_BSS;
    break;
   case SECT_HRAM:
    if (area_AllocAbs
        (&BankFree[BANK_HRAM], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed HRAM section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_HRAM;
    break;
   case SECT_VRAM:
    if (area_AllocAbs
        (&BankFree[BANK_VRAM], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed VRAM section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_VRAM;
    break;
   case SECT_HOME:
    if (area_AllocAbs
        (&BankFree[BANK_HOME], pSection->nOrg,
         pSection->nByteSize) != pSection->nOrg) {
     sprintf(temptext,
      "Unable to load fixed HOME section at $%lX",
      pSection->nOrg);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    pSection->nBank = BANK_HOME;
    break;
   case SECT_CODE:
    if (pSection->nBank == -1) {
    } else {
     if (pSection->nOrg == -1) {
     } else {
      if (pSection->nBank >= 1
          && pSection->nBank <= 255) {
       if (area_AllocAbs
           (&BankFree
            [pSection->nBank],
            pSection->nOrg,
            pSection->
            nByteSize) !=
           pSection->nOrg) {
        sprintf
            (temptext,
             "Unable to load fixed CODE/DATA section at $%lX in bank $%02lX",
             pSection->
             nOrg,
             pSection->
             nBank);
        fatalerror
            (temptext);
       }
       {if( (pSection-> nBank)>MaxBankUsed ) MaxBankUsed=(pSection-> nBank);};
       pSection->oAssigned = 1;
      } else {
       sprintf(temptext,
        "Unable to load fixed CODE/DATA section at $%lX in bank $%02lX",
        pSection->nOrg,
        pSection->
        nBank);
       fatalerror(temptext);
      }
     }
    }
    break;
   }
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
      && pSection->Type == SECT_CODE
      && pSection->nOrg == -1 && pSection->nBank != -1) {
   if (pSection->nBank >= 1 && pSection->nBank <= 255) {
    if ((pSection->nOrg =
         area_Alloc(&BankFree[pSection->nBank],
      pSection->nByteSize)) == -1) {
     sprintf(temptext,
      "Unable to load fixed CODE/DATA section into bank $%02lX",
      pSection->nBank);
     fatalerror(temptext);
    }
    pSection->oAssigned = 1;
    {if( (pSection->nBank)>MaxBankUsed ) MaxBankUsed=(pSection->nBank);};
   } else {
    sprintf(temptext,
     "Unable to load fixed CODE/DATA section into bank $%02lX",
     pSection->nBank);
    fatalerror(temptext);
   }
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
      && pSection->Type == SECT_CODE
      && pSection->nOrg != -1 && pSection->nBank == -1) {
   if ((pSection->nBank =
        area_AllocAbsCODEAnyBank(pSection->nOrg,
            pSection->nByteSize)) ==
       -1) {
    sprintf(temptext,
     "Unable to load fixed CODE/DATA section at $%lX into any bank",
     pSection->nOrg);
    fatalerror(temptext);
   }
   pSection->oAssigned = 1;
   {if( (pSection->nBank)>MaxBankUsed ) MaxBankUsed=(pSection->nBank);};
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0) {
   switch (pSection->Type) {
   case SECT_BSS:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_BSS],
      pSection->nByteSize)) == -1) {
     fatalerror("BSS section too large\n");
    }
    pSection->nBank = BANK_BSS;
    pSection->oAssigned = 1;
    break;
   case SECT_HRAM:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_HRAM],
      pSection->nByteSize)) == -1) {
     fatalerror("HRAM section too large");
    }
    pSection->nBank = BANK_HRAM;
    pSection->oAssigned = 1;
    break;
   case SECT_VRAM:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_VRAM],
      pSection->nByteSize)) == -1) {
     fatalerror("VRAM section too large");
    }
    pSection->nBank = BANK_VRAM;
    pSection->oAssigned = 1;
    break;
   case SECT_HOME:
    if ((pSection->nOrg =
         area_Alloc(&BankFree[BANK_HOME],
      pSection->nByteSize)) == -1) {
     fatalerror("HOME section too large");
    }
    pSection->nBank = BANK_HOME;
    pSection->oAssigned = 1;
    break;
   case SECT_CODE:
    break;
   default:
    fatalerror("(INTERNAL) Unknown section type!");
    break;
   }
  }
  pSection = pSection->pNext;
 }
 AssignCodeSections();
}


decompiled_code:
__int64 PSION2_AssignSections()
{
__int64 v0; // rax
__int64 result; // rax
_QWORD *v2; // rcx
__int64 v3; // rdx
_QWORD *v4; // rcx
__int64 v5; // rdx

BankFree[0] = (__int64)malloc(0x20uLL);
if ( !BankFree[0] )
fatalerror("Out of memory!");
*(_QWORD *)BankFree[0] = 0LL;
v0 = BankFree[0];
*(_QWORD *)(BankFree[0] + 8) = 0x10000LL;
MaxAvail[0] = 0x10000LL;
*(_QWORD *)(v0 + 16) = 0LL;
*(_QWORD *)(v0 + 24) = 0LL;
result = pSections;
if ( pSections )
{
do
{
if ( !*(_BYTE *)(result + 16) && *(_DWORD *)(result + 32) == 2 )
{
*(_BYTE *)(result + 16) = 1;
*(_QWORD *)result = 0LL;
v2 = (_QWORD *)BankFree[0];
v3 = *(_QWORD *)BankFree[0];
*(_QWORD *)(result + 8) = *(_QWORD *)BankFree[0];
*v2 = *(_QWORD *)(result + 24) + v3;
*(_QWORD *)(BankFree[0] + 8) -= *(_QWORD *)(result + 24);
}
result = *(_QWORD *)(result + 72);
}
while ( result );
for ( result = pSections; result; result = *(_QWORD *)(result + 72) )
{
if ( !*(_BYTE *)(result + 16) && !*(_DWORD *)(result + 32) )
{
*(_BYTE *)(result + 16) = 1;
*(_QWORD *)result = 0LL;
v4 = (_QWORD *)BankFree[0];
v5 = *(_QWORD *)BankFree[0];
*(_QWORD *)(result + 8) = *(_QWORD *)BankFree[0];
*v4 = *(_QWORD *)(result + 24) + v5;
*(_QWORD *)(BankFree[0] + 8) -= *(_QWORD *)(result + 24);
}
}
}
return result;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 v0; // rax
__int64 result; // rax
_QWORD *v2; // rcx
__int64 v3; // rdx
_QWORD *v4; // rcx
__int64 v5; // rdx

BankFree[0] = (__int64)malloc(0x20uLL);
if ( !BankFree[0] )
fatalerror("Out of memory!");
*(_QWORD *)BankFree[0] = 0LL;
v0 = BankFree[0];
*(_QWORD *)(BankFree[0] + 8) = 0x10000LL;
MaxAvail[0] = 0x10000LL;
*(_QWORD *)(v0 + 16) = 0LL;
*(_QWORD *)(v0 + 24) = 0LL;
result = pSections;
if ( pSections )
{
do
{
if ( !*(_BYTE *)(result + 16) && *(_DWORD *)(result + 32) == 2 )
{
*(_BYTE *)(result + 16) = 1;
*(_QWORD *)result = 0LL;
v2 = (_QWORD *)BankFree[0];
v3 = *(_QWORD *)BankFree[0];
*(_QWORD *)(result + 8) = *(_QWORD *)BankFree[0];
*v2 = *(_QWORD *)(result + 24) + v3;
*(_QWORD *)(BankFree[0] + 8) -= *(_QWORD *)(result + 24);
}
result = *(_QWORD *)(result + 72);
}
while ( result );
for ( result = pSections; result; result = *(_QWORD *)(result + 72) )
{
if ( !*(_BYTE *)(result + 16) && !*(_DWORD *)(result + 32) )
{
*(_BYTE *)(result + 16) = 1;
*(_QWORD *)result = 0LL;
v4 = (_QWORD *)BankFree[0];
v5 = *(_QWORD *)BankFree[0];
*(_QWORD *)(result + 8) = *(_QWORD *)BankFree[0];
*v4 = *(_QWORD *)(result + 24) + v5;
*(_QWORD *)(BankFree[0] + 8) -= *(_QWORD *)(result + 24);
}
}
}
return result;
}

original_code:
void PSION2_AssignSections(void)
{
 struct sSection *pSection;
 BankFree[0] = malloc(sizeof *BankFree[0]);
 if (!BankFree[0])
  fatalerror("Out of memory!");
 BankFree[0]->nOrg = 0x0000;
 BankFree[0]->nSize = 0x10000;
 MaxAvail[0] = 0x10000;
 BankFree[0]->pPrev = ((void *)0);
 BankFree[0]->pNext = ((void *)0);
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
    && pSection->Type == SECT_CODE) {
   pSection->oAssigned = 1;
   pSection->nBank = 0;
   pSection->nOrg = BankFree[0]->nOrg;
   BankFree[0]->nOrg += pSection->nByteSize;
   BankFree[0]->nSize -= pSection->nByteSize;
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
    && pSection->Type == SECT_BSS) {
   pSection->oAssigned = 1;
   pSection->nBank = 0;
   pSection->nOrg = BankFree[0]->nOrg;
   BankFree[0]->nOrg += pSection->nByteSize;
   BankFree[0]->nSize -= pSection->nByteSize;
  }
  pSection = pSection->pNext;
 }
}

canonical_original_code:
void PSION2_AssignSections()
{
 struct sSection *pSection;
 BankFree[0] = malloc(sizeof *BankFree[0]);
 if (!BankFree[0])
  fatalerror("Out of memory!");
 BankFree[0]->nOrg = 0x0000;
 BankFree[0]->nSize = 0x10000;
 MaxAvail[0] = 0x10000;
 BankFree[0]->pPrev = ((void *)0);
 BankFree[0]->pNext = ((void *)0);
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
    && pSection->Type == SECT_CODE) {
   pSection->oAssigned = 1;
   pSection->nBank = 0;
   pSection->nOrg = BankFree[0]->nOrg;
   BankFree[0]->nOrg += pSection->nByteSize;
   BankFree[0]->nSize -= pSection->nByteSize;
  }
  pSection = pSection->pNext;
 }
 pSection = pSections;
 while (pSection) {
  if (pSection->oAssigned == 0
    && pSection->Type == SECT_BSS) {
   pSection->oAssigned = 1;
   pSection->nBank = 0;
   pSection->nOrg = BankFree[0]->nOrg;
   BankFree[0]->nOrg += pSection->nByteSize;
   BankFree[0]->nSize -= pSection->nByteSize;
  }
  pSection = pSection->pNext;
 }
}


AssignSections

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

result = outputtype;
if ( !outputtype )
return GBROM_AssignSections();
if ( outputtype == 1 )
result = PSION2_AssignSections();
return result;
}

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

result = outputtype;
if ( !outputtype )
return func7();
if ( outputtype == 1 )
result = func8();
return result;
}

original_code:
void AssignSections(void)
{
 switch (outputtype) {
 case OUTPUT_GBROM:
  GBROM_AssignSections();
  break;
 case OUTPUT_PSION2:
  PSION2_AssignSections();
  break;
 }
}

canonical_original_code:
void AssignSections()
{
 switch (outputtype) {
 case OUTPUT_GBROM:
  GBROM_AssignSections();
  break;
 case OUTPUT_PSION2:
  PSION2_AssignSections();
  break;
 }
}


CreateSymbolTable

decompiled_code:
__int64 CreateSymbolTable()
{
__int64 result; // rax
_QWORD *v1; // rbp
__int64 v2; // rbx
_QWORD *v3; // rax
_QWORD *v4; // rdx

result = sym_Init();
v1 = (_QWORD *)pSections;
if ( pSections )
{
do
{
result = v1[6];
v2 = result - 1;
if ( result )
{
while ( 1 )
{
v3 = *(_QWORD **)(v1[7] + 8 * v2);
if ( *((_DWORD *)v3 + 2) == 2 )
{
v4 = (_QWORD *)v3[3];
if ( !v4 || v4 == v1 )
{
if ( v4 )
sym_CreateSymbol(*v3, v1[1] + v3[4], (unsigned int)*(char *)v1);
else
sym_CreateSymbol(*v3, v3[4], 0xFFFFFFFFLL);
}
}
result = v2 - 1;
if ( !v2 )
break;
--v2;
}
}
v1 = (_QWORD *)v1[9];
}
while ( v1 );
}
return result;
}

canonical_decompiled_code:
__int64 func10()
{
__int64 result; // rax
_QWORD *v1; // rbp
__int64 v2; // rbx
_QWORD *v3; // rax
_QWORD *v4; // rdx

result = sym_Init();
v1 = (_QWORD *)pSections;
if ( pSections )
{
do
{
result = v1[6];
v2 = result - 1;
if ( result )
{
while ( 1 )
{
v3 = *(_QWORD **)(v1[7] + 8 * v2);
if ( *((_DWORD *)v3 + 2) == 2 )
{
v4 = (_QWORD *)v3[3];
if ( !v4 || v4 == v1 )
{
if ( v4 )
sym_CreateSymbol(*v3, v1[1] + v3[4], (unsigned int)*(char *)v1);
else
sym_CreateSymbol(*v3, v3[4], 0xFFFFFFFFLL);
}
}
result = v2 - 1;
if ( !v2 )
break;
--v2;
}
}
v1 = (_QWORD *)v1[9];
}
while ( v1 );
}
return result;
}

original_code:
void CreateSymbolTable(void)
{
 struct sSection *pSect;
 sym_Init();
 pSect = pSections;
 while (pSect) {
  SLONG i;
  i = pSect->nNumberOfSymbols;
  while (i--) {
   if ((pSect->tSymbols[i]->Type == SYM_EXPORT) &&
       ((pSect->tSymbols[i]->pSection == pSect) ||
        (pSect->tSymbols[i]->pSection == ((void *)0)))) {
    if (pSect->tSymbols[i]->pSection == ((void *)0))
     sym_CreateSymbol(pSect->tSymbols[i]->
        pzName,
        pSect->tSymbols[i]->
        nOffset, -1);
    else
     sym_CreateSymbol(pSect->tSymbols[i]->
        pzName,
        pSect->nOrg +
        pSect->tSymbols[i]->
        nOffset, pSect->nBank);
   }
  }
  pSect = pSect->pNext;
 }
}

canonical_original_code:
void CreateSymbolTable()
{
 struct sSection *pSect;
 sym_Init();
 pSect = pSections;
 while (pSect) {
  long i;
  i = pSect->nNumberOfSymbols;
  while (i--) {
   if ((pSect->tSymbols[i]->Type == SYM_EXPORT) &&
       ((pSect->tSymbols[i]->pSection == pSect) ||
        (pSect->tSymbols[i]->pSection == ((void *)0)))) {
    if (pSect->tSymbols[i]->pSection == ((void *)0))
     sym_CreateSymbol(pSect->tSymbols[i]->
        pzName,
        pSect->tSymbols[i]->
        nOffset, -1);
    else
     sym_CreateSymbol(pSect->tSymbols[i]->
        pzName,
        pSect->nOrg +
        pSect->tSymbols[i]->
        nOffset, pSect->nBank);
   }
  }
  pSect = pSect->pNext;
 }
}


decompiled_code:
__int64 math_DefinePI()
{
return sym_AddEqu(&unk_344, 205887LL);
}

canonical_decompiled_code:
__int64 func0()
{
return sym_AddEqu(&unk_344, 205887LL);
}

original_code:
void math_DefinePI(void)
{
 sym_AddEqu("_PI", ((SLONG)((acos(-1))*65536.0)));
}

canonical_original_code:
void math_DefinePI()
{
 sym_AddEqu("_PI", ((SLONG)((acos(-1))*65536.0)));
}


rpnpush

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

result = rpnp++;
rpnstack[result] = a1;
return result;
}

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

result = rpnp++;
rpnstack[result] = a1;
return result;
}

original_code:
void rpnpush(SLONG i)
{
 rpnstack[rpnp++] = i;
}

canonical_original_code:
void rpnpush(long i)
{
 rpnstack[rpnp++] = i;
}


rpnpop

decompiled_code:
__int64 rpnpop()
{
--rpnp;
return rpnstack[rpnp];
}

canonical_decompiled_code:
__int64 func1()
{
--rpnp;
return rpnstack[rpnp];
}

original_code:
SLONG rpnpop(void)
{
 return (rpnstack[--rpnp]);
}

canonical_original_code:
long rpnpop()
{
 return (rpnstack[--rpnp]);
}


getsymvalue

decompiled_code:
__int64 __fastcall getsymvalue(__int64 a1)
{
const char **v1; // rdx
int v2; // eax
__int64 result; // rax

v1 = *(const char ***)(*(_QWORD *)(pCurrentSection + 56) + 8 * a1);
v2 = *((_DWORD *)v1 + 2);
if ( v2 == 1 )
return sym_GetValue(*v1);
if ( (v2 & 0xFFFFFFFD) != 0 )
{
fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
result = 0LL;
}
else if ( !strcmp(*v1, "@") )
{
result = nPC;
}
else
{
result = (__int64)&v1[4][*((_QWORD *)v1[3] + 1)];
}
return result;
}

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

v1 = *(const char ***)(*(_QWORD *)(pCurrentSection + 56) + 8 * a1);
v2 = *((_DWORD *)v1 + 2);
if ( v2 == 1 )
return sym_GetValue(*v1);
if ( (v2 & 0xFFFFFFFD) != 0 )
{
fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
result = 0LL;
}
else if ( !strcmp(*v1, "@") )
{
result = nPC;
}
else
{
result = (__int64)&v1[4][*((_QWORD *)v1[3] + 1)];
}
return result;
}

original_code:
SLONG getsymvalue(SLONG symid)
{
 switch (pCurrentSection->tSymbols[symid]->Type) {
 case SYM_IMPORT:
  return (sym_GetValue(pCurrentSection->tSymbols[symid]->pzName));
  break;
 case SYM_EXPORT:
 case SYM_LOCAL:
  {
   if (strcmp
       (pCurrentSection->tSymbols[symid]->pzName,
        "@") == 0) {
    return (nPC);
   } else
    return (pCurrentSection->tSymbols[symid]->
     nOffset +
     pCurrentSection->tSymbols[symid]->
     pSection->nOrg);
  }
 default:
  break;
 }
 fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
 return (0);
}

canonical_original_code:
long getsymvalue(long symid)
{
 switch (pCurrentSection->tSymbols[symid]->Type) {
 case SYM_IMPORT:
  return (sym_GetValue(pCurrentSection->tSymbols[symid]->pzName));
  break;
 case SYM_EXPORT:
 case SYM_LOCAL:
  {
   if (strcmp
       (pCurrentSection->tSymbols[symid]->pzName,
        "@") == 0) {
    return (nPC);
   } else
    return (pCurrentSection->tSymbols[symid]->
     nOffset +
     pCurrentSection->tSymbols[symid]->
     pSection->nOrg);
  }
 default:
  break;
 }
 fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
 return (0);
}

variable_types: symid long


getsymbank

decompiled_code:
__int64 __fastcall getsymbank(__int64 a1)
{
__int64 v1; // rdx
int v2; // eax

v1 = *(_QWORD *)(*(_QWORD *)(pCurrentSection + 56) + 8 * a1);
v2 = *(_DWORD *)(v1 + 8);
if ( v2 == 1 )
return sym_GetBank(*(_QWORD *)v1);
if ( (v2 & 0xFFFFFFFD) == 0 )
return **(_QWORD **)(v1 + 24);
fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
__int64 v1; // rdx
int v2; // eax

v1 = *(_QWORD *)(*(_QWORD *)(pCurrentSection + 56) + 8 * a1);
v2 = *(_DWORD *)(v1 + 8);
if ( v2 == 1 )
return sym_GetBank(*(_QWORD *)v1);
if ( (v2 & 0xFFFFFFFD) == 0 )
return **(_QWORD **)(v1 + 24);
fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
return 0LL;
}

original_code:
SLONG getsymbank(SLONG symid)
{
 switch (pCurrentSection->tSymbols[symid]->Type) {
 case SYM_IMPORT:
  return (sym_GetBank(pCurrentSection->tSymbols[symid]->pzName));
  break;
 case SYM_EXPORT:
 case SYM_LOCAL:
  return (pCurrentSection->tSymbols[symid]->pSection->nBank);
 default:
  break;
 }
 fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
 return (0);
}

canonical_original_code:
long getsymbank(long symid)
{
 switch (pCurrentSection->tSymbols[symid]->Type) {
 case SYM_IMPORT:
  return (sym_GetBank(pCurrentSection->tSymbols[symid]->pzName));
  break;
 case SYM_EXPORT:
 case SYM_LOCAL:
  return (pCurrentSection->tSymbols[symid]->pSection->nBank);
 default:
  break;
 }
 fatalerror("*INTERNAL* UNKNOWN SYMBOL TYPE");
 return (0);
}


calcrpn

decompiled_code:
__int64 __fastcall calcrpn(__int64 a1)
{
__int64 v1; // rbx
_BYTE *v2; // rax
const char **v3; // r12
__int64 v4; // rbx
__int64 v5; // r13
_BYTE *v6; // rbp
__int64 v7; // rbx
__int64 v8; // rbx
__int64 v9; // rbx
__int64 v10; // rbx
__int64 v11; // rbx
__int64 v12; // rbx
__int64 v13; // rbx
__int64 v14; // rax
__int64 v15; // rbx
__int64 v16; // rbx
__int64 v17; // rbx
__int64 v18; // rbx
__int64 v19; // rbx
__int64 v20; // rbx
char v21; // bl
char v22; // bl
unsigned __int64 v23; // rbx
__int64 v24; // rbx
__int64 v25; // r13
__int64 v26; // rax
signed __int64 v27; // r13
__int64 v28; // rax
__int64 v29; // r14
signed __int64 v31; // [rsp+8h] [rbp-40h]

rpnp = 0LL;
v1 = *(_QWORD *)(a1 + 32);
v2 = *(_BYTE **)(a1 + 40);
*(_BYTE *)(a1 + 56) = 0;
if ( v1 > 0 )
{
v3 = (const char **)a1;
while ( 1 )
{
v5 = v1 - 1;
v6 = v2 + 1;
switch ( *v2 )
{
case 0:
v4 = rpnpop(a1);
a1 = v4 + rpnpop(a1);
rpnpush(a1);
break;
case 1:
v7 = rpnpop(a1);
a1 = rpnpop(a1) - v7;
rpnpush(a1);
break;
case 2:
v8 = rpnpop(a1);
a1 = rpnpop(a1) * v8;
rpnpush(a1);
break;
case 3:
v9 = rpnpop(a1);
a1 = rpnpop(a1) / v9;
rpnpush(a1);
break;
case 4:
v10 = rpnpop(a1);
a1 = rpnpop(a1) % v10;
rpnpush(a1);
break;
case 5:
a1 = -rpnpop(a1);
rpnpush(a1);
break;
case 6:
v11 = rpnpop(a1);
a1 = rpnpop(a1) | v11;
rpnpush(a1);
break;
case 7:
v12 = rpnpop(a1);
a1 = rpnpop(a1) & v12;
rpnpush(a1);
break;
case 8:
v13 = rpnpop(a1);
a1 = rpnpop(a1) ^ v13;
rpnpush(a1);
break;
case 9:
a1 = rpnpop(a1) ^ 0xFFFFFFFFLL;
rpnpush(a1);
break;
case 0xA:
v14 = rpnpop(a1);
LODWORD(a1) = 0;
if ( v14 )
LODWORD(a1) = rpnpop(0LL) != 0;
goto LABEL_18;
case 0xB:
LODWORD(a1) = 1;
if ( !((__int64 (*)(void))rpnpop)() )
LODWORD(a1) = rpnpop(1LL) != 0;
LABEL_18:
a1 = (int)a1;
rpnpush((int)a1);
break;
case 0xC:
a1 = ((__int64 (*)(void))rpnpop)() == 0;
rpnpush(a1);
break;
case 0xD:
v15 = ((__int64 (*)(void))rpnpop)();
a1 = v15 == ((__int64 (*)(void))rpnpop)();
rpnpush(a1);
break;
case 0xE:
v16 = ((__int64 (*)(void))rpnpop)();
a1 = v16 != ((__int64 (*)(void))rpnpop)();
rpnpush(a1);
break;
case 0xF:
v17 = ((__int64 (*)(void))rpnpop)();
a1 = ((__int64 (*)(void))rpnpop)() > v17;
rpnpush(a1);
break;
case 0x10:
v18 = ((__int64 (*)(void))rpnpop)();
a1 = ((__int64 (*)(void))rpnpop)() < v18;
rpnpush(a1);
break;
case 0x11:
v19 = ((__int64 (*)(void))rpnpop)();
a1 = ((__int64 (*)(void))rpnpop)() >= v19;
rpnpush(a1);
break;
case 0x12:
v20 = ((__int64 (*)(void))rpnpop)();
a1 = ((__int64 (*)(void))rpnpop)() <= v20;
rpnpush(a1);
break;
case 0x13:
v21 = ((__int64 (*)(void))rpnpop)();
a1 = ((__int64 (*)(void))rpnpop)() << v21;
rpnpush(a1);
break;
case 0x14:
v22 = ((__int64 (*)(void))rpnpop)();
a1 = ((__int64 (*)(void))rpnpop)() >> v22;
rpnpush(a1);
break;
case 0x15:
v6 = v2 + 5;
a1 = getsymbank(((unsigned __int8)v2[4] << 24) | (unsigned __int64)(unsigned __int8)v2[1] | ((unsigned __int8)v2[3] << 16) | ((unsigned __int8)v2[2] << 8));
rpnpush(a1);
v5 = v1 - 5;
break;
case 0x16:
v23 = ((__int64 (*)(void))rpnpop)();
a1 = (unsigned __int8)v23;
rpnpush((unsigned __int8)v23);
if ( v23 - 256 <= 0xFDFF || v23 > 0xFFFF )
{
sprintf(&temptext, "%s(%ld) : Value must be in the HRAM area", *v3, v3[1]);
a1 = (__int64)&temptext;
fatalerror(&temptext);
}
break;
case 0x17:
v24 = ((__int64 (*)(void))rpnpop)();
a1 = (unsigned __int8)v24;
rpnpush((unsigned __int8)v24);
if ( (unsigned __int64)(v24 - 0x2000) > 0xFF )
{
sprintf(&temptext, "%s(%ld) : Value must be in the ZP area", *v3, v3[1]);
a1 = (__int64)&temptext;
fatalerror(&temptext);
}
break;
case 0x18:
v27 = ((unsigned __int8)v2[4] << 24) | (unsigned __int64)(unsigned __int8)v2[1] | ((unsigned __int8)v2[3] << 16) | ((unsigned __int8)v2[2] << 8);
v6 = v2 + 9;
v31 = (unsigned __int8)v2[5] | (unsigned __int64)((unsigned __int8)v2[8] << 24) | ((unsigned __int8)v2[6] << 8) | ((unsigned __int8)v2[7] << 16);
v28 = ((__int64 (*)(void))rpnpop)();
v29 = v28;
if ( v27 > v28 || v31 < v28 )
{
sprintf(&temptext, "%s(%ld) : Value must be in the range [%ld;%ld]", *v3, v3[1], v27, v31);
fatalerror(&temptext);
}
a1 = v29;
rpnpush(v29);
v5 = v1 - 9;
break;
case 0x80:
v6 = v2 + 5;
a1 = ((unsigned __int8)v2[4] << 24) | (unsigned __int64)(unsigned __int8)v2[1] | ((unsigned __int8)v2[3] << 16) | ((unsigned __int8)v2[2] << 8);
rpnpush(a1);
v5 = v1 - 5;
break;
case 0x81:
v6 = v2 + 5;
v25 = ((unsigned __int8)v2[4] << 24) | (unsigned __int64)(unsigned __int8)v2[1] | ((unsigned __int8)v2[3] << 16) | ((unsigned __int8)v2[2] << 8);
v26 = getsymvalue(v25);
rpnpush(v26);
a1 = v25;
*((_BYTE *)v3 + 56) |= getsymbank(v25) != -1;
v5 = v1 - 5;
break;
default:
break;
}
if ( v5 <= 0 )
break;
v2 = v6;
v1 = v5;
}
}
return rpnpop(a1);
}

original_code:
SLONG calcrpn(struct sPatch * pPatch)
{
 SLONG t, size;
 UBYTE *rpn;
 rpnp = 0;
 size = pPatch->nRPNSize;
 rpn = pPatch->pRPN;
 pPatch->oRelocPatch = 0;
 while (size > 0) {
  size -= 1;
  switch (*rpn++) {
  case RPN_ADD:
   rpnpush(rpnpop() + rpnpop());
   break;
  case RPN_SUB:
   t = rpnpop();
   rpnpush(rpnpop() - t);
   break;
  case RPN_MUL:
   rpnpush(rpnpop() * rpnpop());
   break;
  case RPN_DIV:
   t = rpnpop();
   rpnpush(rpnpop() / t);
   break;
  case RPN_MOD:
   t = rpnpop();
   rpnpush(rpnpop() % t);
   break;
  case RPN_UNSUB:
   rpnpush(-rpnpop());
   break;
  case RPN_OR:
   rpnpush(rpnpop() | rpnpop());
   break;
  case RPN_AND:
   rpnpush(rpnpop() & rpnpop());
   break;
  case RPN_XOR:
   rpnpush(rpnpop() ^ rpnpop());
   break;
  case RPN_UNNOT:
   rpnpush(rpnpop() ^ 0xFFFFFFFF);
   break;
  case RPN_LOGAND:
   rpnpush(rpnpop() && rpnpop());
   break;
  case RPN_LOGOR:
   rpnpush(rpnpop() || rpnpop());
   break;
  case RPN_LOGUNNOT:
   rpnpush(!rpnpop());
   break;
  case RPN_LOGEQ:
   rpnpush(rpnpop() == rpnpop());
   break;
  case RPN_LOGNE:
   rpnpush(rpnpop() != rpnpop());
   break;
  case RPN_LOGGT:
   t = rpnpop();
   rpnpush(rpnpop() > t);
   break;
  case RPN_LOGLT:
   t = rpnpop();
   rpnpush(rpnpop() < t);
   break;
  case RPN_LOGGE:
   t = rpnpop();
   rpnpush(rpnpop() >= t);
   break;
  case RPN_LOGLE:
   t = rpnpop();
   rpnpush(rpnpop() <= t);
   break;
  case RPN_SHL:
   t = rpnpop();
   rpnpush(rpnpop() << t);
   break;
  case RPN_SHR:
   t = rpnpop();
   rpnpush(rpnpop() >> t);
   break;
  case RPN_HRAM:
   t = rpnpop();
   rpnpush(t & 0xFF);
   if (t < 0 || (t > 0xFF && t < 0xFF00) || t > 0xFFFF) {
    sprintf(temptext,
     "%s(%ld) : Value must be in the HRAM area",
     pPatch->pzFilename, pPatch->nLineNo);
    fatalerror(temptext);
   }
   break;
  case RPN_PCEZP:
   t = rpnpop();
   rpnpush(t & 0xFF);
   if (t < 0x2000 || t > 0x20FF) {
    sprintf(temptext,
     "%s(%ld) : Value must be in the ZP area",
     pPatch->pzFilename, pPatch->nLineNo);
    fatalerror(temptext);
   }
   break;
  case RPN_CONST:
   t = (*rpn++);
   t |= (*rpn++) << 8;
   t |= (*rpn++) << 16;
   t |= (*rpn++) << 24;
   rpnpush(t);
   size -= 4;
   break;
  case RPN_SYM:
   t = (*rpn++);
   t |= (*rpn++) << 8;
   t |= (*rpn++) << 16;
   t |= (*rpn++) << 24;
   rpnpush(getsymvalue(t));
   pPatch->oRelocPatch |= (getsymbank(t) != -1);
   size -= 4;
   break;
  case RPN_BANK:
   t = (*rpn++);
   t |= (*rpn++) << 8;
   t |= (*rpn++) << 16;
   t |= (*rpn++) << 24;
   rpnpush(getsymbank(t));
   size -= 4;
   break;
  case RPN_RANGECHECK:
   {
    SLONG low, high;
    low = (*rpn++);
    low |= (*rpn++) << 8;
    low |= (*rpn++) << 16;
    low |= (*rpn++) << 24;
    high = (*rpn++);
    high |= (*rpn++) << 8;
    high |= (*rpn++) << 16;
    high |= (*rpn++) << 24;
    t = rpnpop();
    if (t < low || t > high) {
     sprintf(temptext,
      "%s(%ld) : Value must be in the range [%ld;%ld]",
      pPatch->pzFilename,
      pPatch->nLineNo, low, high);
     fatalerror(temptext);
    }
    rpnpush(t);
    size -= 8;
    break;
   }
  }
 }
 return (rpnpop());
}

canonical_original_code:
long calcrpn(struct sPatch *pPatch)
{
 long t; long size;
 unsigned char *rpn;
 rpnp = 0;
 size = pPatch->nRPNSize;
 rpn = pPatch->pRPN;
 pPatch->oRelocPatch = 0;
 while (size > 0) {
  size -= 1;
  switch (*rpn++) {
  case RPN_ADD:
   rpnpush(rpnpop() + rpnpop());
   break;
  case RPN_SUB:
   t = rpnpop();
   rpnpush(rpnpop() - t);
   break;
  case RPN_MUL:
   rpnpush(rpnpop() * rpnpop());
   break;
  case RPN_DIV:
   t = rpnpop();
   rpnpush(rpnpop() / t);
   break;
  case RPN_MOD:
   t = rpnpop();
   rpnpush(rpnpop() % t);
   break;
  case RPN_UNSUB:
   rpnpush(-rpnpop());
   break;
  case RPN_OR:
   rpnpush(rpnpop() | rpnpop());
   break;
  case RPN_AND:
   rpnpush(rpnpop() & rpnpop());
   break;
  case RPN_XOR:
   rpnpush(rpnpop() ^ rpnpop());
   break;
  case RPN_UNNOT:
   rpnpush(rpnpop() ^ 0xFFFFFFFF);
   break;
  case RPN_LOGAND:
   rpnpush(rpnpop() && rpnpop());
   break;
  case RPN_LOGOR:
   rpnpush(rpnpop() || rpnpop());
   break;
  case RPN_LOGUNNOT:
   rpnpush(!rpnpop());
   break;
  case RPN_LOGEQ:
   rpnpush(rpnpop() == rpnpop());
   break;
  case RPN_LOGNE:
   rpnpush(rpnpop() != rpnpop());
   break;
  case RPN_LOGGT:
   t = rpnpop();
   rpnpush(rpnpop() > t);
   break;
  case RPN_LOGLT:
   t = rpnpop();
   rpnpush(rpnpop() < t);
   break;
  case RPN_LOGGE:
   t = rpnpop();
   rpnpush(rpnpop() >= t);
   break;
  case RPN_LOGLE:
   t = rpnpop();
   rpnpush(rpnpop() <= t);
   break;
  case RPN_SHL:
   t = rpnpop();
   rpnpush(rpnpop() << t);
   break;
  case RPN_SHR:
   t = rpnpop();
   rpnpush(rpnpop() >> t);
   break;
  case RPN_HRAM:
   t = rpnpop();
   rpnpush(t & 0xFF);
   if (t < 0 || (t > 0xFF && t < 0xFF00) || t > 0xFFFF) {
    sprintf(temptext,
     "%s(%ld) : Value must be in the HRAM area",
     pPatch->pzFilename, pPatch->nLineNo);
    fatalerror(temptext);
   }
   break;
  case RPN_PCEZP:
   t = rpnpop();
   rpnpush(t & 0xFF);
   if (t < 0x2000 || t > 0x20FF) {
    sprintf(temptext,
     "%s(%ld) : Value must be in the ZP area",
     pPatch->pzFilename, pPatch->nLineNo);
    fatalerror(temptext);
   }
   break;
  case RPN_CONST:
   t = (*rpn++);
   t |= (*rpn++) << 8;
   t |= (*rpn++) << 16;
   t |= (*rpn++) << 24;
   rpnpush(t);
   size -= 4;
   break;
  case RPN_SYM:
   t = (*rpn++);
   t |= (*rpn++) << 8;
   t |= (*rpn++) << 16;
   t |= (*rpn++) << 24;
   rpnpush(getsymvalue(t));
   pPatch->oRelocPatch |= (getsymbank(t) != -1);
   size -= 4;
   break;
  case RPN_BANK:
   t = (*rpn++);
   t |= (*rpn++) << 8;
   t |= (*rpn++) << 16;
   t |= (*rpn++) << 24;
   rpnpush(getsymbank(t));
   size -= 4;
   break;
  case RPN_RANGECHECK:
   {
    long low; long high;
    low = (*rpn++);
    low |= (*rpn++) << 8;
    low |= (*rpn++) << 16;
    low |= (*rpn++) << 24;
    high = (*rpn++);
    high |= (*rpn++) << 8;
    high |= (*rpn++) << 16;
    high |= (*rpn++) << 24;
    t = rpnpop();
    if (t < low || t > high) {
     sprintf(temptext,
      "%s(%ld) : Value must be in the range [%ld;%ld]",
      pPatch->pzFilename,
      pPatch->nLineNo, low, high);
     fatalerror(temptext);
    }
    rpnpush(t);
    size -= 8;
    break;
   }
  }
 }
 return (rpnpop());
}

variable_types: struct sPatch { char *pzFilename; long nLineNo; long nOffset; enum ePatchType { PATCH_BYTE=0, PATCH_WORD_L=1, PATCH_LONG_L=2, PATCH_WORD_B=3, PATCH_LONG_B=4 } Type; long nRPNSize; unsigned char *pRPN; struct sPatch *pNext; char oRelocPatch; } *

variable_types: t long

variable_types:
rpn
unsigned char *