// File: /workspace/github_cpp_makefile_star2_O2/nicoeps[P]NicoGB/src/memory.cpp
// Function: Memory::write(unsigned short, unsigned char)
void Memory::write(uint16_t address, uint8_t n) {
    if (address <= 0x7FFF && cartridge.loaded == true) {
        cartridge.write(address, n);
    } else if (address >= 0x8000 && address <= 0x9FFF) {
        vram[address - 0x8000] = n;
    } else if (address >= 0xA000 && address <= 0xBFFF) {
        cartridge.write(address, n); 
    } else if (address >= 0xC000 && address <= 0xDFFF) {
        wram[address - 0xC000] = n;
    } else if (address >= 0xE000 && address <= 0xFDFF) {
        wram[address - 0xE000] = n;
    } else if (address >= 0xFE00 && address <= 0xFE9F) {
        oam[address - 0xFE00] = n;
    } else if ((address >= 0xFF00 && address <= 0xFF7F) || address == 0xFFFF) {
        switch (address) {
            case 0xFF00: joypad.write(n); break;
            case 0xFF04: timer.counter = 0; break;
            case 0xFF05: timer.tima = n; break;
            case 0xFF06: timer.tma = n; break;
            case 0xFF07: timer.tac = n | 0xF8; break;
            case 0xFF40: lcd.lcdc = n; break;
            case 0xFF41: lcd.stat = (lcd.stat & 0x7) | (n & 0x78) | 0x80; break;
            case 0xFF42: lcd.scy = n; break;
            case 0xFF43: lcd.scx = n; break;
            case 0xFF45: lcd.lyc = n; break;
            case 0xFF46: // DMA Transfer
                io[0x46] = n;
                if (dmaCycle > 0xA0) {
                    dmaAddress = n << 8;
                    dmaCycle = 0x0;
                }
                break;
            case 0xFF47: lcd.bgp = n; break;
            case 0xFF48: lcd.obp0 = n; break;
            case 0xFF49: lcd.obp1 = n; break;
            case 0xFF4A: lcd.wy = n; break;
            case 0xFF4B: lcd.wx = n; break;
            case 0xFF50:
                if (n == 0x01 && bootEnabled) {
                    bootEnabled = false;
                    write(0xFF10, 0x80); // NR10
                    write(0xFF11, 0xBF); // NR11
                    write(0xFF12, 0xF3); // NR12
                    write(0xFF14, 0xBF); // NR14
                    write(0xFF16, 0x3F); // NR21
                    write(0xFF17, 0x00); // NR22
                    write(0xFF19, 0xBF); // NR24
                    write(0xFF1A, 0x7F); // NR30
                    write(0xFF1B, 0xFF); // NR31
                    write(0xFF1C, 0x9F); // NR32
                    write(0xFF1E, 0xBF); // NR33
                    write(0xFF20, 0xFF); // NR41
                    write(0xFF21, 0x00); // NR42
                    write(0xFF22, 0x00); // NR43
                    write(0xFF23, 0xBF); // NR30
                    write(0xFF24, 0x77); // NR50
                    write(0xFF25, 0xF3); // NR51
                    write(0xFF26, 0xF1); // NR52
                }
                break;
            case 0xFFFF: io[0xFF] = n; break; // IE
            case 0xFF0F: io[0x0F] = n | 0xE0; break; // IF
            default: io[address - 0xFF00] = n; break;
        }
    } else if (address >= 0xFF80 && address <= 0xFFFE) {
        hram[address - 0xFF80] = n;
    }
}

// Assembly:
testw %si, %si
js 0x627a
movq (%rdi), %rax
cmpb $0x1, 0x20(%rax)
jne 0x6290
movzwl %si, %esi
movzbl %dl, %edx
movq %rax, %rdi
jmp 0x27be
cmpw $0x9fff, %si            # imm = 0x9FFF
ja 0x6290
movq 0x28(%rdi), %rax
movzwl %si, %ecx
movb %dl, -0x8000(%rax,%rcx)
retq
movl %esi, %eax
andl $0xe000, %eax           # imm = 0xE000
cmpw $0xc000, %ax            # imm = 0xC000
je 0x62b2
cmpl $0xa000, %eax           # imm = 0xA000
jne 0x62c1
movq (%rdi), %rdi
movzwl %si, %esi
movzbl %dl, %edx
jmp 0x27be
movq 0x40(%rdi), %rax
movzwl %si, %ecx
movb %dl, -0xc000(%rax,%rcx)
retq
leal 0x2000(%rsi), %eax
cmpw $0x1dff, %ax            # imm = 0x1DFF
ja 0x62dd
movzwl %si, %eax
andl $0x1fff, %eax           # imm = 0x1FFF
movq 0x40(%rdi), %rcx
movb %dl, (%rcx,%rax)
retq
leal 0x200(%rsi), %eax
cmpw $0x9f, %ax
ja 0x62f8
movq 0x58(%rdi), %rax
movzwl %si, %ecx
movb %dl, -0xfe00(%rax,%rcx)
retq
movl %esi, %eax
andl $0xff80, %eax           # imm = 0xFF80
cmpw $0xff00, %ax            # imm = 0xFF00
setne %al
cmpw $-0x1, %si
setne %cl
testb %al, %cl
jne 0x6331
movzbl %sil, %eax
leal -0x40(%rax), %ecx
cmpl $0x10, %ecx
ja 0x6349
leaq 0x36a8(%rip), %rax      # 0x99cc
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movb %dl, 0x18(%rdi)
retq
cmpw $-0x80, %si
jb 0x6348
movq 0x88(%rdi), %rax
movzwl %si, %ecx
movb %dl, -0xff80(%rax,%rcx)
retq
leal -0x4(%rax), %ecx
cmpl $0xb, %ecx
ja 0x636a
leaq 0x3644(%rip), %rax      # 0x999c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq 0x10(%rdi), %rax
andw $0x0, (%rax)
retq
cmpl $0xff, %eax
je 0x64b4
testl %eax, %eax
jne 0x6385
movq 0x8(%rdi), %rdi
movzbl %dl, %esi
jmp 0x560c
movq 0x70(%rdi), %rax
movzwl %si, %ecx
movb %dl, -0xff00(%rax,%rcx)
retq
movb %dl, 0x20(%rdi)
retq
movb %dl, 0x1f(%rdi)
retq
movb %dl, 0x1a(%rdi)
retq
movb %dl, 0x1b(%rdi)
retq
movb %dl, 0x21(%rdi)
retq
movb %dl, 0x1d(%rdi)
retq
movb %dl, 0x1e(%rdi)
retq
movb 0x19(%rdi), %al
andb $0x7, %al
andb $0x78, %dl
orb %al, %dl
orb $-0x80, %dl
movb %dl, 0x19(%rdi)
retq
movb %dl, 0x22(%rdi)
retq
cmpb $0x1, %dl
jne 0x6348
cmpb $0x1, 0x23(%rdi)
jne 0x6348
xorl %eax, %eax
movb %al, 0x23(%rdi)
movq 0x70(%rdi), %rcx
movb $-0x80, 0x10(%rcx)
movq 0x70(%rdi), %rcx
movb $-0x41, %dl
movb %dl, 0x11(%rcx)
movq 0x70(%rdi), %rcx
movb $-0xd, %sil
movb %sil, 0x12(%rcx)
movq 0x70(%rdi), %rcx
movb %dl, 0x14(%rcx)
movq 0x70(%rdi), %rcx
movb $0x3f, 0x16(%rcx)
movq 0x70(%rdi), %rcx
movb %al, 0x17(%rcx)
movq 0x70(%rdi), %rcx
movb %dl, 0x19(%rcx)
movq 0x70(%rdi), %rcx
movb $0x7f, 0x1a(%rcx)
movq 0x70(%rdi), %rcx
movb $-0x1, %r8b
movb %r8b, 0x1b(%rcx)
movq 0x70(%rdi), %rcx
movb $-0x61, 0x1c(%rcx)
movq 0x70(%rdi), %rcx
movb %dl, 0x1e(%rcx)
movq 0x70(%rdi), %rcx
movb %r8b, 0x20(%rcx)
movq 0x70(%rdi), %rcx
movb %al, 0x21(%rcx)
movq 0x70(%rdi), %rcx
movb %al, 0x22(%rcx)
movq 0x70(%rdi), %rax
movb %dl, 0x23(%rax)
movq 0x70(%rdi), %rax
movb $0x77, 0x24(%rax)
movq 0x70(%rdi), %rax
movb %sil, 0x25(%rax)
movq 0x70(%rdi), %rax
movb $-0xf, 0x26(%rax)
retq
movq 0x70(%rdi), %rax
movb %dl, 0x46(%rax)
cmpb $-0x5f, 0x26(%rdi)
jb 0x6348
movzbl %dl, %eax
shll $0x8, %eax
movw %ax, 0x24(%rdi)
movb $0x0, 0x26(%rdi)
retq
movq 0x10(%rdi), %rax
movb %dl, 0x3(%rax)
retq
movq 0x10(%rdi), %rax
movb %dl, 0x2(%rax)
retq
orb $-0x20, %dl
movq 0x70(%rdi), %rax
movb %dl, 0xf(%rax)
retq
orb $-0x8, %dl
movq 0x10(%rdi), %rax
movb %dl, 0x4(%rax)
retq
movq 0x70(%rdi), %rax
movb %dl, 0xff(%rax)
retq
nop