// File: /workspace/github_cpp_makefile_star2_O3/thanoskoutr[P]Chip-8-Emulator/chip8.cpp
// Function: Chip8::loadApplication(char const*)
int Chip8::loadApplication(const char * file)
{
	initialize();

  /* Open File */
  FILE *fptr;
  unsigned long file_size;

  if ((fptr = fopen(file,"rb")) == NULL)
  {
    printf("Error! opening program\n");
    return 1;
  }

  /* Check file size */
  fseek(fptr, 0, SEEK_END); // seek to end of file (non-portable !)
  file_size = ftell(fptr);
  fseek(fptr, 0, SEEK_SET); // seek back to beginning of file
  printf("Filesize: %ld bytes\n", file_size);

  /* Allocate memory to contain the whole file */
  char *buffer = (char*) malloc(sizeof(char)*file_size);
  if (buffer == NULL)
  {
    fprintf(stderr, "Memory error! Could not allocate %ld bytes of memory\n", file_size);
    fclose(fptr);
    return 1;
  }

  /* Copy the file into the buffer */
  size_t res = fread(buffer, 1, file_size, fptr);
  if (res != file_size)
  {
    fprintf(stderr, "Read error! Could not read %ld bytes of memory\n", file_size);
    fclose(fptr);
    free(buffer);
    return 1;
  }

  /* Copy buffer to Chip8 memory */
  if (file_size > MEMORY_SIZE - 512) // If file cannot fit into memory
  {
    fprintf(stderr, "Error! Program of %ld bytes too big for memory \n", file_size);
    fclose(fptr);
    free(buffer);
    return 1;
  }
  for(unsigned int i = 0; i < file_size; i++)
    memory[i + 512] = buffer[i];  // Start program at (0x200 == 512)

  /* Close File, Free Buffer */
  fclose(fptr);
  free(buffer);

  return 0;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r15
movw $0x0, 0x812(%rdi)
movl $0x2000000, 0x1824(%rdi) # imm = 0x2000000
incq %rdi
leaq 0x814(%r15), %r14
movl $0x810, %edx            # imm = 0x810
xorl %esi, %esi
callq 0x2110
xorps %xmm0, %xmm0
movups %xmm0, 0x1828(%r15)
movups %xmm0, 0x1838(%r15)
movl $0x0, 0x1848(%r15)
leaq 0x864(%r15), %rdi
movl $0xfc0, %edx            # imm = 0xFC0
xorl %esi, %esi
callq 0x2110
leaq 0x3c03(%rip), %rsi      # 0x61b0
movl $0x50, %edx
movq %r14, %rdi
callq 0x21a0
movb $0x1, (%r15)
leaq 0x1ad7(%rip), %rsi      # 0x409c
movq %rbx, %rdi
callq 0x2250
testq %rax, %rax
je 0x267a
movq %rax, %rbx
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x2220
movq %rbx, %rdi
callq 0x2030
movq %rax, %r15
movq %rbx, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2220
leaq 0x1a99(%rip), %rdi      # 0x409f
movq %r15, %rsi
xorl %eax, %eax
callq 0x2070
movq %r15, %rdi
callq 0x2280
testq %rax, %rax
je 0x2697
movq %rax, %r12
movl $0x1, %esi
movq %rax, %rdi
movq %r15, %rdx
movq %rbx, %rcx
callq 0x22b0
cmpq %r15, %rax
jne 0x26bc
cmpq $0xe00, %r15            # imm = 0xE00
ja 0x26cf
testq %r15, %r15
je 0x2666
xorl %eax, %eax
movb (%r12,%rax), %cl
leal 0x200(%rax), %edx
movb %cl, (%r14,%rdx)
incq %rax
cmpl %r15d, %eax
jb 0x2650
movq %rbx, %rdi
callq 0x21f0
movq %r12, %rdi
callq 0x2260
xorl %eax, %eax
jmp 0x268b
leaq 0x1b46(%rip), %rdi      # 0x41c7
callq 0x22d0
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0x393a(%rip), %rax      # 0x5fd8
movq (%rax), %rdi
leaq 0x1a0c(%rip), %rsi      # 0x40b4
movq %r15, %rdx
xorl %eax, %eax
callq 0x2290
movq %rbx, %rdi
callq 0x21f0
jmp 0x2686
movq 0x3915(%rip), %rax      # 0x5fd8
movq (%rax), %rdi
leaq 0x1a1d(%rip), %rsi      # 0x40ea
jmp 0x26e0
movq 0x3902(%rip), %rax      # 0x5fd8
movq (%rax), %rdi
leaq 0x1a3a(%rip), %rsi      # 0x411a
movq %r15, %rdx
xorl %eax, %eax
callq 0x2290
movq %rbx, %rdi
callq 0x21f0
movq %r12, %rdi
callq 0x2260
jmp 0x2686