// File: /workspace/github_cpp_makefile_star2_O2/RegulusImpact[P]sadboy/src/MMU.cpp
// Function: MMU::Write(unsigned short, unsigned char)
void MMU::Write(uint16_t addr, uint8_t val) {
    // RAM[addr] = val;


    // cartridge / bios
    // we don't write to cart
    // if (addr <= 0x7FFF)
    //     cart[addr] = val;
    // sram
    if (addr >= 0xA000 && addr <= 0xBFFF)
        sram[addr - 0xA000] = val;
    // video ram
    else if (addr >= 0x8000 && addr <= 0x9FFF) {
        vram[addr - 0x8000] = val;
        if (addr <= 0x97FF) {
            UpdateTile(addr);
        }
    }

    // writable ram
    else if (addr >= 0xC000 && addr <= 0xDFFF)
        wram[addr - 0xC000] = val;

    // more writable ram
    else if (addr >= 0xE000 && addr <= 0xFDFF)
        wram[addr - 0xE000] = val;

    // oam
    else if (addr >= 0xFE00 && addr <= 0xFEFF)
        oam[addr - 0xFE00] = val;

    // io
    // this includes FFOO - user input joypad
    // timers
    // gpu

    else if (addr >= 0xFF80 && addr <= 0xFFFE)
        hram[addr - 0xFF80] = val;
    else if (addr >= 0xFF00 && addr <= 0xFF7F) {
        // io[addr - 0xFF00] = val;


        // stupid timers div and tima
        if (addr == 0xFF04) {
            io[0xFF04 - 0xFF00] = 0;
            io[0xFF05 - 0xFF00] = 0;
        } else if (addr == 0xFF0F) {
            if (Read(0xFFFF) > 0) {
                io[addr - 0xFF00] = val;
            }
        } else if (addr == 0xFF40)
            io[addr - 0xFF00] = val;

        else if (addr == 0xFF42)
            io[addr - 0xFF00] = val;

        else if (addr == 0xFF43)
            io[addr - 0xFF00] = val;

        else if (addr == 0xFF46) {
            Copy(0xFE00, ((uint16_t)val) << 8, 160); // oam dma

            // io[addr - 0xFF00] = val;
        }

        else if (addr == 0xFF47) { // setup bgp
            for (int ii = 0; ii < 4; ii++) {
                bgp[ii] = palette[(val >> ( ii * 2)) & 3];
            }

            io[addr - 0xFF00] = val;
        }

        else if (addr == 0xFF48) { // setup OBP0 ; sprites
            for (int ii = 0; ii < 4; ii++) {
                obp[0][ii] = palette[(val >> ( ii * 2)) & 3];
            }

            io[addr - 0xFF00] = val;
        }

        else if (addr == 0xFF49) { // setup OBP1 ; sprites
            for (int ii = 0; ii < 4; ii++) {
                obp[1][ii] = palette[(val >> ( ii * 2)) & 3];
            }

            io[addr - 0xFF00] = val;
        } else {
            io[addr - 0xFF00] = val;
        }
    }
    else if (addr == 0xFFFF)
        interrupt = val;

    if (0xFF50 == addr && 1 == val) {
        readBios = false;
    }

    // oh christ what are we doing....
    if (addr == 0xFF02) {// || addr == 0x0081) {
        char c = Read(0xFF01);

        if (c == '\n' || c == '\r') {
            std::cout << std::endl;

            // probably the title when the first newline occurs
            enableDebugger = true;
        } else if (c >= 0x20) {
            //c[0] = Read(0xFF01);
            std::cout << c;
            // if (c == 'd') exit(1);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl %esi, %eax
andl $0xe000, %eax           # imm = 0xE000
cmpw $0xa000, %ax            # imm = 0xA000
jne 0x16589
addl $0xffff6000, %esi       # imm = 0xFFFF6000
movb %dl, 0x8000(%rbx,%rsi)
jmp 0x165dd
cmpw $0x9fff, %si            # imm = 0x9FFF
jg 0x165b6
movl %esi, %eax
addl $0xffff8000, %eax       # imm = 0xFFFF8000
movb %dl, 0xa100(%rbx,%rax)
cmpw $0x97ff, %si            # imm = 0x97FF
ja 0x165dd
movzwl %si, %esi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x16928
cmpw $0xc000, %ax            # imm = 0xC000
jne 0x165c4
addl $0xffff4000, %esi       # imm = 0xFFFF4000
jmp 0x165d6
leal 0x2000(%rsi), %eax
cmpw $0x1dff, %ax            # imm = 0x1DFF
ja 0x165e4
addl $0xffff2000, %esi       # imm = 0xFFFF2000
movb %dl, 0xc200(%rbx,%rsi)
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
movl %esi, %eax
andl $0xff00, %eax           # imm = 0xFF00
cmpw $0xfe00, %ax            # imm = 0xFE00
jne 0x16600
addl $0xffff0200, %esi       # imm = 0xFFFF0200
movb %dl, 0xc100(%rbx,%rsi)
jmp 0x165dd
leal 0x80(%rsi), %eax
cmpw $0x7e, %ax
ja 0x1661b
addl $0xffff0080, %esi       # imm = 0xFFFF0080
movb %dl, 0xe200(%rbx,%rsi)
jmp 0x165dd
movl %esi, %eax
andl $0xff80, %eax           # imm = 0xFF80
cmpw $0xff00, %ax            # imm = 0xFF00
jne 0x1664c
movzbl %sil, %eax
leal -0x40(%rax), %ecx
cmpl $0x9, %ecx
ja 0x1665a
leaq 0x4bf1(%rip), %rax      # 0x1b22c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movb %dl, 0xa040(%rbx)
jmp 0x165dd
cmpw $-0x1, %si
jne 0x165dd
movb %dl, 0xe280(%rbx)
jmp 0x165dd
cmpl $0x4, %eax
je 0x167c6
cmpl $0xf, %eax
jne 0x16680
cmpb $0x0, 0xe280(%rbx)
je 0x165dd
movb %dl, 0xa00f(%rbx)
jmp 0x165dd
movl %esi, %eax
addl $0xffff0100, %eax       # imm = 0xFFFF0100
addq %rbx, %rax
addq $0xa000, %rax           # imm = 0xA000
jmp 0x16772
movzbl %dl, %edx
shll $0x8, %edx
movl $0xa0, %ecx
movq %rbx, %rdi
movl $0xfe00, %esi           # imm = 0xFE00
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x16992
movb %dl, 0xa043(%rbx)
jmp 0x165dd
movb %dl, 0xa042(%rbx)
jmp 0x165dd
movzbl %dl, %eax
leaq 0xe3a6(%rbx), %rdi
xorl %ecx, %ecx
cmpq $0x8, %rcx
je 0x166f9
movl %eax, %r8d
shrl %cl, %r8d
andl $0x3, %r8d
movb 0xe39a(%rbx,%r8), %r8b
movb %r8b, (%rdi)
addq $0x2, %rcx
incq %rdi
jmp 0x166d5
leaq 0xa049(%rbx), %rax
jmp 0x16772
movzbl %dl, %eax
leaq 0xe3a2(%rbx), %rdi
xorl %ecx, %ecx
cmpq $0x8, %rcx
je 0x16732
movl %eax, %r8d
shrl %cl, %r8d
andl $0x3, %r8d
movb 0xe39a(%rbx,%r8), %r8b
movb %r8b, (%rdi)
addq $0x2, %rcx
incq %rdi
jmp 0x1670e
leaq 0xa048(%rbx), %rax
jmp 0x16772
movzbl %dl, %eax
leaq 0xe39e(%rbx), %rdi
xorl %ecx, %ecx
cmpq $0x8, %rcx
je 0x1676b
movl %eax, %r8d
shrl %cl, %r8d
andl $0x3, %r8d
movb 0xe39a(%rbx,%r8), %r8b
movb %r8b, (%rdi)
addq $0x2, %rcx
incq %rdi
jmp 0x16747
leaq 0xa047(%rbx), %rax
movb %dl, (%rax)
cmpw $0xff50, %si            # imm = 0xFF50
setne %al
cmpb $0x1, %dl
setne %cl
orb %al, %cl
jne 0x16792
movb $0x0, 0xe398(%rbx)
jmp 0x165dd
cmpw $0xff02, %si            # imm = 0xFF02
jne 0x165dd
movzbl 0xa001(%rbx), %eax
cmpl $0xd, %eax
je 0x167ae
cmpl $0xa, %eax
jne 0x167d3
movq 0xf813(%rip), %rdi      # 0x25fc8
callq 0x4190
movb $0x1, 0xe399(%rbx)
jmp 0x165dd
andw $0x0, 0xa004(%rbx)
jmp 0x165dd
cmpb $0x20, %al
jl 0x165dd
movsbl %al, %esi
movq 0xf7e3(%rip), %rdi      # 0x25fc8
addq $0x8, %rsp
popq %rbx
popq %rbp
jmp 0x43f0