// File: /workspace/github_cpp_makefile_star2_O3/donfreiday[P]gb/mmu.cpp
// Function: MMU::write8(unsigned short, unsigned char)
void MMU::write8(u16 addr, u8 value) {
  // External RAM switch
  if (addr <= 0x1FFF) {
  }

  // ROM
  else if (addr >= 0x2000 && addr <= 0x3FFF) {
    switch (mbc.type) {
      case 1:
      case 2:
      case 3:
        value &= 0x0F;
        if (!value) {
          value = 1;
        }
        mbc.romBank = (mbc.romBank & 0x60) + value;
        mbc.romOffset = mbc.romBank * 0x4000;
        break;
      default:
        break;
    }
  }

  // RAM
  else if (addr >= 0x4000 && addr <= 0x5FFF) {
    switch (mbc.type) {
      case 1:
      case 2:
      case 3:
        // RAM bank
        if (mbc.mode) {
          mbc.ramOffset = (value & 3) * 0x2000;
        } else {
          // ROM bank
          mbc.romBank = (mbc.romBank & 0x1F) + ((value & 3) << 5);
          mbc.romOffset = mbc.romBank * 0x4000;
        }
        break;
      default:
        break;
    }
  }

  else if (addr >= 0x6000 && addr <= 0x7FFF) {
    switch (mbc.type) {
      case 2:
      case 3:
        mbc.mode = value & 1;
        break;
      default:
        break;
    }
  }

  // RAM, external
  else if (addr >= 0xA000 && addr <= 0xBFFF) {
    ram[mbc.ramOffset + (addr & 0x1FFF)] = value;
  }

  // WRAM shadow
  else if (addr >= 0xE000 && addr <= 0xFDFF) {
    memory[addr - 0x1000] = value;
  }

  // Writes to DIV reset it to zero
  else if (addr == DIV) {
    memory[DIV] = 0;
  }

  // Joypad class handles its register
  else if (addr == JOYP) {
    memory[addr] = joypad->read(value);
  }

  // CPU IF always polls high on bits 5-7
  else if (addr == IF) {
    value |= 0xE0;
    memory[addr] = value;
  }

  // Writes to current scanline register reset it
  else if (addr == LY) {
    memory[addr] = 0;
  }

  // DMA
  else if (addr == DMA) {
    memory[0xFF46] = value;
    dma(value);
  }

  // Unmap bootrom
  else if (addr == 0xFF50) {
    return;
  }

  // Default
  else {
    memory[addr] = value;
  }
}

// Assembly:
cmpl $0x2000, %esi           # imm = 0x2000
jb 0x37b39
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movzwl %si, %eax
cmpl $0x3fff, %eax           # imm = 0x3FFF
ja 0x37a9b
movb (%rbx), %al
decb %al
cmpb $0x2, %al
ja 0x37b33
andb $0xf, %dl
movzbl %dl, %eax
cmpb $0x2, %al
movl $0x1, %ecx
cmovael %eax, %ecx
movb 0x1(%rbx), %al
andb $0x60, %al
orb %cl, %al
movb %al, 0x1(%rbx)
shll $0xe, %ecx
movw %cx, 0x2(%rbx)
jmp 0x37b33
cmpl $0x5fff, %eax           # imm = 0x5FFF
ja 0x37ac3
movb (%rbx), %al
decb %al
cmpb $0x2, %al
ja 0x37b33
cmpb $0x0, 0x6(%rbx)
je 0x37afa
andb $0x3, %dl
movzbl %dl, %eax
shll $0xd, %eax
movw %ax, 0x4(%rbx)
jmp 0x37b33
testw %si, %si
js 0x37ad8
movb (%rbx), %al
andb $-0x2, %al
cmpb $0x2, %al
jne 0x37b33
andb $0x1, %dl
movb %dl, 0x6(%rbx)
jmp 0x37b33
movl %esi, %ecx
andl $0xe000, %ecx           # imm = 0xE000
cmpl $0xa000, %ecx           # imm = 0xA000
jne 0x37b17
movzwl 0x4(%rbx), %ecx
andl $0x1fff, %eax           # imm = 0x1FFF
addq 0x50(%rbx), %rax
movb %dl, (%rcx,%rax)
jmp 0x37b33
movzbl 0x1(%rbx), %eax
movl %eax, %ecx
andb $0x1f, %cl
shlb $0x5, %dl
andb $0x60, %dl
orb %cl, %dl
movb %dl, 0x1(%rbx)
shll $0xe, %eax
movw %ax, 0x2(%rbx)
jmp 0x37b33
addl $0x2000, %esi           # imm = 0x2000
movzwl %si, %ecx
cmpl $0x1dff, %ecx           # imm = 0x1DFF
ja 0x37b3a
movq 0x8(%rbx), %rcx
movb %dl, -0x1000(%rcx,%rax)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
cmpl $0xff43, %eax           # imm = 0xFF43
jg 0x37b65
cmpl $0xff00, %eax           # imm = 0xFF00
je 0x37b83
cmpl $0xff04, %eax           # imm = 0xFF04
je 0x37ba8
cmpl $0xff0f, %eax           # imm = 0xFF0F
jne 0x37b7a
orb $-0x20, %dl
movq 0x8(%rbx), %rax
movb %dl, 0xff0f(%rax)
jmp 0x37b33
cmpl $0xff44, %eax           # imm = 0xFF44
je 0x37b9b
cmpl $0xff46, %eax           # imm = 0xFF46
je 0x37bb8
cmpl $0xff50, %eax           # imm = 0xFF50
je 0x37b33
movq 0x8(%rbx), %rcx
jmp 0x37af5
movq 0x70(%rbx), %rdi
movzbl %dl, %esi
callq 0x3778c
movq 0x8(%rbx), %rcx
movb %al, 0xff00(%rcx)
jmp 0x37b33
movq 0x8(%rbx), %rax
movb $0x0, 0xff44(%rax)
jmp 0x37b33
movq 0x8(%rbx), %rax
movb $0x0, 0xff04(%rax)
jmp 0x37b33
movq 0x8(%rbx), %rax
movb %dl, 0xff46(%rax)
movzbl %dl, %eax
shll $0x8, %eax
xorl %ecx, %ecx
movq 0x8(%rbx), %rdx
leaq (%rdx,%rcx), %rsi
movb (%rax,%rsi), %sil
movb %sil, 0xfe00(%rdx,%rcx)
incq %rcx
cmpq $0xa0, %rcx
jne 0x37bca
jmp 0x37b33
nop