// File: /workspace/github_c_makefile_star2_O0/qad114[P]yobeboy/src/memory.c
// Function: MEM_loadROM
void MEM_loadROM(Memory* mem, const char* path) {
    // Open file and get size
    FILE* file = fopen(path, "rb");
    if (file == NULL) {
        perror("Error while opening ROM");
        exit(1);
    }
    fseek(file, 0L, SEEK_END);
    size_t filesize = ftell(file);
    rewind(file);

    // Load ROM into banks array
    mem->romBanks = malloc(filesize); // freed in main.c:quit
    assert(fread(mem->romBanks, 1, filesize, file) == filesize);
    fclose(file);

    // Load cartridge data
    Cartridge* cart = mem->cartridge;
    mem->cartridge = malloc(sizeof(*cart)); // freed in main.c:quit
    CART_init(mem->cartridge, mem);

    // Set fixed bank to bank 0
    mem->romBank0 = mem->romBanks;

    // Set variable bank to 1
    mem->romBankN = mem->romBanks + 0x4000;

    // Set number of banks
    mem->romBanksNo = ((int[]){2, 4, 8, 16, 32, 64, 128, 256, 512})[mem->cartridge->romSize];
    printf("%d\n", mem->romBanksNo);

    // Initialize external RAM
    mem->extRamEnabled = false;
    mem->extRamBanksNo = ((int[]){0, 0, 1, 4, 16, 8})[mem->cartridge->ramSize];

    if (mem->extRamBanksNo != 0) {
        mem->extRamBanks = calloc(0x2000 * mem->extRamBanksNo, 1);
        mem->extRam = mem->extRamBanks + 0;
    } else {
        mem->extRam = NULL;
    }

    // Handle saving if MBC includes battery
    uint8_t mbcCode = mem->romBank0[0x0147];
    if (strchr((const char []){0x03, 0x06, 0x09, 0x0D, 0x0F, 0x10, 0x13, 0x1B, 0x1E, 0x22, '\0'}, mbcCode)) {
        mem->battery = 1;
        mem->romPath = malloc(strlen(path) + 1); // freed in main.c:quit
        strcpy(mem->romPath, path);
        char* saveFileName = malloc(strlen(path) + 5); // freed at the end of this block
        snprintf(saveFileName, strlen(path) + 5, "%s.sav", path);
        FILE* saveFile = fopen(saveFileName, "rb");
        if (saveFile != NULL) {
            filesize = mem->extRamBanksNo * 0x2000;
            assert(fread(mem->extRamBanks, 1, filesize, saveFile) == filesize);
            fclose(saveFile);
        }
        free(saveFileName);

    } else {
        mem->battery = 0;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x18fa(%rip), %rsi      # 0xe9f8
callq 0x21b0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xd124
leaq 0x18e6(%rip), %rdi      # 0xe9fb
callq 0x2130
movl $0x1, %edi
callq 0x21d0
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x2190
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2080
movq -0x20(%rbp), %rdi
callq 0x2210
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10018(%rax)
movq -0x8(%rbp), %rax
movq 0x10018(%rax), %rdi
movq -0x20(%rbp), %rdx
movq -0x18(%rbp), %rcx
movl $0x1, %esi
callq 0x2240
cmpq -0x20(%rbp), %rax
jne 0xd188
jmp 0xd1a7
leaq 0x1884(%rip), %rdi      # 0xea13
leaq 0x18b1(%rip), %rsi      # 0xea47
movl $0x8f, %edx
leaq 0x18b2(%rip), %rcx      # 0xea54
callq 0x20f0
movq -0x18(%rbp), %rdi
callq 0x2180
movq -0x8(%rbp), %rax
movq 0x10038(%rax), %rax
movq %rax, -0x28(%rbp)
movl $0x1c, %edi
callq 0x2210
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10038(%rax)
movq -0x8(%rbp), %rax
movq 0x10038(%rax), %rdi
movq -0x8(%rbp), %rsi
callq 0x27d0
movq -0x8(%rbp), %rax
movq 0x10018(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10000(%rax)
movq -0x8(%rbp), %rax
movq 0x10018(%rax), %rcx
addq $0x4000, %rcx           # imm = 0x4000
movq -0x8(%rbp), %rax
movq %rcx, 0x10008(%rax)
leaq -0x4c(%rbp), %rdi
leaq 0x1893(%rip), %rsi      # 0xeabc
movl $0x24, %edx
callq 0x2120
movq -0x8(%rbp), %rax
movq 0x10038(%rax), %rax
movzbl 0x12(%rax), %eax
movl -0x4c(%rbp,%rax,4), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x10020(%rax)
movq -0x8(%rbp), %rax
movl 0x10020(%rax), %esi
leaq 0x181c(%rip), %rdi      # 0xea7d
movb $0x0, %al
callq 0x2050
movq -0x8(%rbp), %rax
movb $0x0, 0x10034(%rax)
movq 0x1866(%rip), %rax      # 0xeae0
movq %rax, -0x64(%rbp)
movq 0x1863(%rip), %rax      # 0xeae8
movq %rax, -0x5c(%rbp)
movq 0x1860(%rip), %rax      # 0xeaf0
movq %rax, -0x54(%rbp)
movq -0x8(%rbp), %rax
movq 0x10038(%rax), %rax
movzbl 0x13(%rax), %eax
movl -0x64(%rbp,%rax,4), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x10030(%rax)
movq -0x8(%rbp), %rax
cmpl $0x0, 0x10030(%rax)
je 0xd2fe
movq -0x8(%rbp), %rax
movl 0x10030(%rax), %eax
shll $0xd, %eax
movslq %eax, %rdi
movl $0x1, %esi
callq 0x2100
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10028(%rax)
movq -0x8(%rbp), %rax
movq 0x10028(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10010(%rax)
jmp 0xd30d
movq -0x8(%rbp), %rax
movq $0x0, 0x10010(%rax)
movq -0x8(%rbp), %rax
movq 0x10000(%rax), %rax
movb 0x147(%rax), %al
movb %al, -0x65(%rbp)
movb $0x3, -0x70(%rbp)
movb $0x6, -0x6f(%rbp)
movb $0x9, -0x6e(%rbp)
movb $0xd, -0x6d(%rbp)
movb $0xf, -0x6c(%rbp)
movb $0x10, -0x6b(%rbp)
movb $0x13, -0x6a(%rbp)
movb $0x1b, -0x69(%rbp)
movb $0x1e, -0x68(%rbp)
movb $0x22, -0x67(%rbp)
movb $0x0, -0x66(%rbp)
leaq -0x70(%rbp), %rdi
movzbl -0x65(%rbp), %esi
callq 0x20b0
cmpq $0x0, %rax
je 0xd47c
movq -0x8(%rbp), %rax
movl $0x1, 0x10040(%rax)
movq -0x10(%rbp), %rdi
callq 0x20c0
movq %rax, %rdi
addq $0x1, %rdi
callq 0x2210
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10048(%rax)
movq -0x8(%rbp), %rax
movq 0x10048(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x2160
movq -0x10(%rbp), %rdi
callq 0x20c0
movq %rax, %rdi
addq $0x5, %rdi
callq 0x2210
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x10(%rbp), %rdi
callq 0x20c0
movq -0x88(%rbp), %rdi
movq %rax, %rsi
addq $0x5, %rsi
movq -0x10(%rbp), %rcx
leaq 0x15fe(%rip), %rdx      # 0xe9ed
movb $0x0, %al
callq 0x2250
movq -0x78(%rbp), %rdi
leaq 0x15f7(%rip), %rsi      # 0xe9f8
callq 0x21b0
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
je 0xd471
movq -0x8(%rbp), %rax
movl 0x10030(%rax), %eax
shll $0xd, %eax
cltq
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq 0x10028(%rax), %rdi
movq -0x20(%rbp), %rdx
movq -0x80(%rbp), %rcx
movl $0x1, %esi
callq 0x2240
cmpq -0x20(%rbp), %rax
jne 0xd449
jmp 0xd468
leaq 0x1631(%rip), %rdi      # 0xea81
leaq 0x15f0(%rip), %rsi      # 0xea47
movl $0xb7, %edx
leaq 0x15f1(%rip), %rcx      # 0xea54
callq 0x20f0
movq -0x80(%rbp), %rdi
callq 0x2180
movq -0x78(%rbp), %rdi
callq 0x21c0
jmp 0xd48a
movq -0x8(%rbp), %rax
movl $0x0, 0x10040(%rax)
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)