// File: 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 %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x48(%rbp)
callq 0x25a0
movq -0x18(%rbp), %rdi
leaq 0x4938(%rip), %rsi      # 0x7040
callq 0x22e0
movq %rax, -0x20(%rbp)
cmpq $0x0, %rax
jne 0x2731
leaq 0x4925(%rip), %rdi      # 0x7043
movb $0x0, %al
callq 0x2060
movl $0x1, -0x4(%rbp)
jmp 0x28ad
movq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0x2, %edx
callq 0x22c0
movq -0x20(%rbp), %rdi
callq 0x2030
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
xorl %edx, %edx
callq 0x22c0
movq -0x28(%rbp), %rsi
leaq 0x48f1(%rip), %rdi      # 0x705b
movb $0x0, %al
callq 0x2060
movq -0x28(%rbp), %rdi
shlq $0x0, %rdi
callq 0x2320
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x27ba
movq 0x7848(%rip), %rax      # 0x9fd8
movq (%rax), %rdi
movq -0x28(%rbp), %rdx
leaq 0x48d2(%rip), %rsi      # 0x7070
movb $0x0, %al
callq 0x2330
movq -0x20(%rbp), %rdi
callq 0x2240
movl $0x1, -0x4(%rbp)
jmp 0x28ad
movq -0x30(%rbp), %rdi
movq -0x28(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl $0x1, %esi
callq 0x2350
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x28(%rbp), %rax
je 0x2818
movq 0x77f3(%rip), %rax      # 0x9fd8
movq (%rax), %rdi
movq -0x28(%rbp), %rdx
leaq 0x48b3(%rip), %rsi      # 0x70a6
movb $0x0, %al
callq 0x2330
movq -0x20(%rbp), %rdi
callq 0x2240
movq -0x30(%rbp), %rdi
callq 0x22f0
movl $0x1, -0x4(%rbp)
jmp 0x28ad
cmpq $0xe00, -0x28(%rbp)     # imm = 0xE00
jbe 0x2859
movq 0x77af(%rip), %rax      # 0x9fd8
movq (%rax), %rdi
movq -0x28(%rbp), %rdx
leaq 0x489f(%rip), %rsi      # 0x70d6
movb $0x0, %al
callq 0x2330
movq -0x20(%rbp), %rdi
callq 0x2240
movq -0x30(%rbp), %rdi
callq 0x22f0
movl $0x1, -0x4(%rbp)
jmp 0x28ad
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpq -0x28(%rbp), %rax
jae 0x2894
movq -0x48(%rbp), %rax
movq -0x30(%rbp), %rcx
movl -0x3c(%rbp), %edx
movb (%rcx,%rdx), %dl
movl -0x3c(%rbp), %ecx
addl $0x200, %ecx            # imm = 0x200
movl %ecx, %ecx
movb %dl, 0x814(%rax,%rcx)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x2860
movq -0x20(%rbp), %rdi
callq 0x2240
movq -0x30(%rbp), %rdi
callq 0x22f0
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)