// File: nicklausw[P]snesasm/snesasm.cpp
// Function: snes()
void snes()
{
  unsigned char build_byte = 0x00;
  
  if (lohirom == hirom) {
    build_byte += 0x1;
  }
  
  if (sfrom == slowrom) {
    build_byte += 0x20;
  }
  
  base = 0x8000;
  
  org = 0xFFC0;
  if (name_flag == true) {
    for (unsigned int name_counter = 0; name_counter < name.length(); name_counter++) {
      write_byte(name[name_counter]);
    }
  }
  
  org = 0xFFD5;
  write_byte(build_byte);
  write_byte(carttype);
  write_byte(romsize);
  write_byte(0);
  write_byte(0);
  write_byte(licenseecode);
  write_byte(version);
  
  // clear checksum bytes
  write_byte(0);
  write_byte(0);
  write_byte(0);
  write_byte(0);
  
  
  if (compcheck_flag == true) {
  // the weird part, checksum calculation.
  auto checksum = 0ULL;
  auto inverse = 0ULL;
  for (auto counter = 0ULL; counter < rom.size(); counter++) {
    checksum += rom[counter];
  }
  
  
  checksum += 0x1FE; // add inverse to checksum
  checksum &= 0xFFFF; // lower 16 bytes
  inverse = checksum ^ 0xFFFF; // 0xFFFF - checksum
  
  
  // write to rom
  org = 0xFFDC;
  write_byte(inverse & 0xFF);
  write_byte(inverse >> 8);
  write_byte(checksum & 0xFF);
  write_byte(checksum >> 8);
  }
}

// Assembly:
subq $0x38, %rsp
movb $0x0, 0x37(%rsp)
movzbl 0xa4c4(%rip), %eax      # 0x162b4
cmpl $0x1, %eax
jne 0xbe01
movzbl 0x37(%rsp), %eax
addl $0x1, %eax
movb %al, 0x37(%rsp)
movzbl 0xa4ad(%rip), %eax      # 0x162b5
cmpl $0x0, %eax
jne 0xbe19
movzbl 0x37(%rsp), %eax
addl $0x20, %eax
movb %al, 0x37(%rsp)
movq $0x8000, 0xa3ec(%rip) # imm = 0x8000
movq $0xffc0, 0xa3e9(%rip) # imm = 0xFFC0
movb 0xa455(%rip), %al       # 0x1628a
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xbe92
movl $0x0, 0x30(%rsp)
movl 0x30(%rsp), %eax
movq %rax, 0x10(%rsp)
leaq 0xa439(%rip), %rdi      # 0x16290
callq 0x22c0
movq %rax, %rcx
movq 0x10(%rsp), %rax
cmpq %rcx, %rax
jae 0xbe90
movl 0x30(%rsp), %eax
movl %eax, %esi
leaq 0xa41a(%rip), %rdi      # 0x16290
callq 0x2390
movzbl (%rax), %edi
callq 0xc810
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0xbe47
jmp 0xbe92
movq $0xffd5, 0xa37b(%rip) # imm = 0xFFD5
movzbl 0x37(%rsp), %edi
callq 0xc810
movzbl 0xa403(%rip), %edi      # 0x162b1
callq 0xc810
movzbl 0xa3f6(%rip), %edi      # 0x162b0
callq 0xc810
xorl %edi, %edi
callq 0xc810
xorl %edi, %edi
callq 0xc810
movzbl 0xa3de(%rip), %edi      # 0x162b2
callq 0xc810
movzbl 0xa3d3(%rip), %edi      # 0x162b3
callq 0xc810
xorl %edi, %edi
callq 0xc810
xorl %edi, %edi
callq 0xc810
xorl %edi, %edi
callq 0xc810
xorl %edi, %edi
callq 0xc810
movb 0xa381(%rip), %al       # 0x16288
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0xc004
movq $0x0, 0x28(%rsp)
movq $0x0, 0x20(%rsp)
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0xa397(%rip), %rdi      # 0x162d8
callq 0xd670
movq %rax, %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
jae 0xbf81
movq 0x18(%rsp), %rsi
leaq 0xa379(%rip), %rdi      # 0x162d8
callq 0xd590
movzbl (%rax), %eax
addq 0x28(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0xbf30
movq 0x28(%rsp), %rax
addq $0x1fe, %rax            # imm = 0x1FE
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
andq $0xffff, %rax           # imm = 0xFFFF
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rax
xorq $0xffff, %rax           # imm = 0xFFFF
movq %rax, 0x20(%rsp)
movq $0xffdc, 0xa25c(%rip) # imm = 0xFFDC
movq 0x20(%rsp), %rax
andq $0xff, %rax
movzbl %al, %edi
callq 0xc810
movq 0x20(%rsp), %rax
shrq $0x8, %rax
movzbl %al, %edi
callq 0xc810
movq 0x28(%rsp), %rax
andq $0xff, %rax
movzbl %al, %edi
callq 0xc810
movq 0x28(%rsp), %rax
shrq $0x8, %rax
movzbl %al, %edi
callq 0xc810
addq $0x38, %rsp
retq
nopl (%rax)