/*
    (c) 2011-2013 Hermes/Estwald <www.elotrolado.net>
    IrisManager (HMANAGER port) (c) 2011 D_Skywalk <http://david.dantoine.org>

    HMANAGER4 is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    HMANAGER4 is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with HMANAGER4.  If not, see <http://www.gnu.org/licenses/>.

*/


#include "ps3_discless.h"
#include "utils.h"

#include "ps3_storage_bin.h"

int zlib_decompress(char *source, char *dest, int in_size, int *out_size);

extern int firmware;
extern char self_path[MAXPATHLEN];

u64 lv2peek(u64 addr);
u64 lv2poke(u64 addr, u64 value);
extern u64 syscall_base;
extern u64 restore_syscall8[2];

u64 syscall_40(u64 cmd, u64 arg);


u8 in_51[8]= {
    0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

u8 out_51[]= {
    0x00, 0x20, 0x0e, 0x01, 0x01, 0x01, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00
};

u8 in_bb[8]= {
    0xbb, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
};

u8 out_bb[]= {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

u8 in_a4[8]= {
    0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0
};

u8 out_a4[]= {
    0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03
};

u8 in_ad[8]= {
    0xad, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

u8 out_ad[]= {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00
};

u8 in_43[8]= {
    0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

u8 out_43[]= {
    0x00, 0x12, 0x01, 0x01, 0x00, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xaa, 0x00,
    0x00, 0x00
};

u8 in_46[8]= {
    0x46, 0x01, 0xff, 0x40, 0x00, 0x00, 0x00, 0x00
};

u8 out_46[]= {
    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

u8 in_46b[8]= {
    0x46, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00
};

u8 out_46b[]= {
    0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x03, 0x00, 0x01, 0x05, 0x07, 0x04,
    0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0d, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x08, 0x03, 0x14,
    0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46,
    0x46, 0x46, 0x46, 0x46, 0xff, 0x00, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

u8 in_46c[8]= {
    0x4a, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00
};

u8 out_46c[]= {
    0x00, 0x06, 0x04, 0x56, 0x00, 0x02, 0x00, 0x00
};

void send_async_data_table(void)
{
    u32 pos = 0x7DF000;

    int n = 18 * 4, m;
    u32 data[4096];

    data[0] = pos + n;
    data[1] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_51, 8);
    n += 8;
    m = sizeof(out_51);
    memcpy((void *) &data[n>>2], (void *) out_51, m);
    n = ((n + m + 7) & ~7);

    data[2] = pos + n;
    data[3] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_bb, 8);
    n += 8;
    m = sizeof(out_bb);
    memcpy((void *) &data[n>>2], (void *) out_bb, m);
    n = ((n + m + 7) & ~7);

    data[4] = pos + n;
    data[5] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_a4, 8);
    n += 8;
    m = sizeof(out_a4);
    memcpy((void *) &data[n>>2], (void *) out_a4, m);
    n = ((n + m + 7) & ~7);

    data[6]= pos + n;
    data[7]= pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_ad, 8);
    n += 8;
    m = sizeof(out_ad);
    memcpy((void *) &data[n>>2], (void *) out_ad, m);
    n = ((n + m + 7) & ~7);

    data[8] = pos + n;
    data[9] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_43, 8);
    n += 8;
    m = sizeof(out_43);
    memcpy((void *) &data[n>>2], (void *) out_43, m);
    n = ((n + m + 7) & ~7);

    data[10] = pos + n;
    data[11] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_46, 8);
    n += 8;
    m = sizeof(out_46);
    memcpy((void *) &data[n>>2], (void *) out_46, m);
    n = ((n + m + 7) & ~7);

    data[12] = pos + n;
    data[13] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_46b, 8);
    n += 8;
    m = sizeof(out_46b);
    memcpy((void *) &data[n>>2], (void *) out_46b, m);
    n = ((n + m + 7) & ~7);

    data[14] = pos + n;
    data[15] = pos + n + 8;
    memcpy((void *) &data[n>>2], (void *) in_46c, 8);
    n += 8;
    m = sizeof(out_51);
    memcpy((void *) &data[n>>2], (void *) out_46c, m);
    n = ((n + m + 7) & ~7);

    data[16] = data[17]=0;

    sys8_memcpy(0x8000000000000000ULL + (u64) pos, (u64) data, (u64) n);

    syscall_40(2, 0x8000000000000000ULL + (u64) pos);
}

static u64 PAYLOAD_BASE = 0ULL;

static void write_htab(void)
{
    u64 cont = 0;
    lv1_reg regs_i, regs_o;
    u32 val;

    while(cont < 0x80)
    {
        val = (cont << 7);

        regs_i.reg3  = 0;
        regs_i.reg4  = (cont << 3ULL);
        regs_i.reg5  = lv2peek(0x800000000f000000ULL | ((u64) val));
        regs_i.reg6  = lv2peek(0x800000000f000008ULL | ((u64) val));
        regs_i.reg6  = (regs_i.reg6  & 0xff0000ULL) | 0x190ULL;
        regs_i.reg11 = 1;

        sys8_lv1_syscall(&regs_i, &regs_o);

        cont++;
    }
}


bool load_ps3_discless_payload()
{
    if(lv2peek(0x80000000000004E8ULL)) goto skip_the_load; //payload already loaded

    if(!ps3_storage_bin_size) return false;

    if(!syscall_base)
    {
        DrawDialogOK("syscall_base is empty!");
        return false;
    }

    write_htab();

    PAYLOAD_BASE = 0x80000000007FE000ULL;

    u64 *addr = (u64 *) memalign(8, ps3_storage_bin_size + 31);

    if(!addr)
    {
        DrawDialogOK("Memory is full!");
        exit(0);
    }

    memcpy((char *) addr, (char *) ps3_storage_bin, ps3_storage_bin_size);

    addr[1]  =  syscall_base;
    addr[2]  += PAYLOAD_BASE; // sys 40
    addr[3]  =  lv2peek(syscall_base + (u64) (40  * 8));
    addr[4]  += PAYLOAD_BASE;
    addr[5]  =  lv2peek(syscall_base + (u64) (130 * 8));
    addr[6]  += PAYLOAD_BASE;
    addr[7]  =  lv2peek(syscall_base + (u64) (879 * 8));
    addr[8]  += PAYLOAD_BASE;
    addr[9]  =  lv2peek(syscall_base + (u64) (864 * 8));
    addr[10] += PAYLOAD_BASE;
    addr[11] =  lv2peek(syscall_base + (u64) (619 * 8));
    addr[12] += PAYLOAD_BASE;
    addr[13] =  lv2peek(syscall_base + (u64) (837 * 8));
    addr[14] += PAYLOAD_BASE;
    addr[15] =  lv2peek(syscall_base + (u64) (609 * 8));

    for(u8 n = 0; n < 100; n++)
    {
        lv2poke(0x80000000000004E8ULL, PAYLOAD_BASE);

        sys8_memcpyinstr(PAYLOAD_BASE, (u64) addr, (u64) ((ps3_storage_bin_size + 7) & ~7));

        lv2poke(syscall_base + (u64) (40  * 8), PAYLOAD_BASE + 0x10ULL); // syscall management
        lv2poke(syscall_base + (u64) (130 * 8), PAYLOAD_BASE + 0x20ULL); // sys_event_queue_receive
        lv2poke(syscall_base + (u64) (879 * 8), PAYLOAD_BASE + 0x30ULL); // sys_ss_media_id
        lv2poke(syscall_base + (u64) (864 * 8), PAYLOAD_BASE + 0x40ULL); // storage_manager
        lv2poke(syscall_base + (u64) (619 * 8), PAYLOAD_BASE + 0x50ULL); // sys_storage_async_send_device_command
        lv2poke(syscall_base + (u64) (837 * 8), PAYLOAD_BASE + 0x60ULL); // sys_fs_mount
        lv2poke(syscall_base + (u64) (609 * 8), PAYLOAD_BASE + 0x70ULL); // sys_storage_get_device_info

        usleep(1000);
    }

    sleep(1);

    free(addr);

skip_the_load:
    send_async_data_table();

    return true;
}

/*
static u64 lv1poke(u64 addr, u64 value)
{
    lv2syscall2(9, (u64) addr, (u64) value);
    return_to_user_prog(u64);
}
*/

#define MAMBA_PRX_LOADER_INSTALL_OFFSET				0x80000000007F0000ULL
#define MAMBA_PRX_LOADER_SYSCALL_NUM				1022

#define SYSCALL1022_OPCODE_LOAD_MAMBA			0x7755

int syscall_load_mamba(char* payload_path)
{
    lv2syscall2(MAMBA_PRX_LOADER_SYSCALL_NUM, SYSCALL1022_OPCODE_LOAD_MAMBA, (uint64_t)payload_path);
	return_to_user_prog(int);
}

bool load_ps3_mamba_payload()
{
    bool use_lz = true;

    if(sys8_mamba() == 0x666) return true;  // MAMBA is already running

    if(!syscall_base)
    {
        DrawDialogOK("syscall_base is empty!");
        return false;
    }

    write_htab();


    char payload_file[MAXPATHLEN];
    int out_size = 0, file_size = 0;

    ///// PRX_LOADER PAYLOAD FILE /////
    sprintf(payload_file, "%s/USRDIR/payloads/payload_%X.bin", self_path, firmware);

    uint64_t *payload = (uint64_t *) LoadFile((char *) payload_file, &file_size);
    ///////////////////////////////////



    ///// MAMBA_PRX_LOADER_INSTALL /////
    lv2poke(0x80000000000004E8ULL, 0);						//Disable the disc-less payload (if it was previously loaded)
    lv2poke(0x8000000000003D90ULL, 0x386000014E800020ULL);  //Patch permission 4.xx, usually "fixed" by warez payload

    if(file_size > 3000 && file_size < 4200)
    {
        for(int i = 0; i < (file_size / 8); i++) lv2poke(MAMBA_PRX_LOADER_INSTALL_OFFSET + (i * 8), payload[i]);

        free(payload);

        // install prx loader payload
        const uint64_t payload_opd = MAMBA_PRX_LOADER_INSTALL_OFFSET + file_size + 0x10;
        lv2poke(payload_opd, MAMBA_PRX_LOADER_INSTALL_OFFSET);
        lv2poke(syscall_base + (8 * MAMBA_PRX_LOADER_SYSCALL_NUM), payload_opd);

        // install mamba 3.x
        sprintf(payload_file, "%s/USRDIR/mamba/mamba_%X.bin", self_path, firmware);

        if(file_exists(payload_file))
        {
            if (syscall_load_mamba(payload_file) != 0) return false;
            return true;
        }
    }
    /////////////////////////////////////


    ///// MAMBA 2.x /////
    sprintf(payload_file, "%s/USRDIR/mamba/mamba_%X.lz.bin", self_path, firmware);

    if(file_exists(payload_file) == false)
    {
        sprintf(payload_file, "/dev_hdd0/game/IRISMAN00/USRDIR/mamba/mamba_%X.lz.bin", firmware);

        if(file_exists(payload_file) == false)
            {sprintf(payload_file, "%s/USRDIR/mamba/mamba_%X.bin", self_path, firmware); use_lz = false;}
    }

    if(file_exists(payload_file) == false) return false;
    /////////////////////

    u64 *addr = (u64 *) memalign(128, 0x20000);

    if(!addr)
    {
        DrawDialogOK("Memory is full");
        exit(0);
    }

    memset((char *) addr, 0, 0x20000); file_size = 0;

    char *mamba_payload = LoadFile((char *) payload_file, &file_size);

    if(file_size < 20000)
    {
        if(mamba_payload) free(mamba_payload);

        free(addr);
        return false;
    }

    if(use_lz)
    {
        zlib_decompress((char *) mamba_payload, (char *) addr, file_size, &out_size);
    }
    else
    {
        out_size = file_size; memcpy(addr, mamba_payload, out_size);
    }

    if(mamba_payload) free(mamba_payload);

    out_size = (out_size + 0x4000) & ~127;
    u64 lv2_mem = sys8_alloc(out_size, 0x27ULL); // alloc LV2 memory

    if(!lv2_mem)
    {
        free(addr);
        DrawDialogOK("LV2 memory is full!");
        exit(0);
    }

    // install mamba in syscall 40 address ( when mamba is loaded, syscall 40 is disabled and syscalls 6,7,8,9,10,11 are created )
    for(u8 n = 0; n < 100; n++)
    {
            lv2poke(lv2_mem, lv2_mem + 0x8ULL);
        sys8_memcpy(lv2_mem + 8, (u64) addr, out_size);


        lv2poke(syscall_base + (u64) (40 * 8), lv2_mem);  // syscall management
        lv2poke(0x80000000000004E8ULL, 0);

        usleep(1000);
    }


    free(addr);
    return true;
}
