// File: klyushinmisha[P]GBEmu/./src/Memory.cpp
// Function: Memory::Write(int, unsigned char)
void Memory::Write(int addr, byte value)
{
    gb->Sync();

    if (addr < 0x8000)
        return;
    //    CheckMBC(addr, value);

    //Checks writing to special registers
    //which have unusual behaviour
    switch (addr)
    {
        case 0xFF00:
            //INPUT
            RAM[0xFF00] &= 0b11001111;
            RAM[0xFF00] |= (byte)(value & 0b110000);
            return;

        case 0xFF04:
            //DIV
            RAM[0xFF04] = 0;
            return;

        case 0xFF41:
            //STAT
            value &= 0b11111000;
            RAM[0xFF41] &= 7;
            RAM[0xFF41] |= value;
            return;

        case 0xFF44:
            //LYCounter
            RAM[0xFF44] = 0;
            return;

        case 0xFF46:
            gb->DMATransfer = true;
            break;
    }

    //This space copys value to C000-DE00
    if ((addr >= 0xE000) & (addr < 0xFE00))
    {
        RAM[addr] = value;
        addr -= 0x2000;
    }

    //Writing to external RAM
    if ((addr > 0x9FFF) & (addr < 0xBFFF) & (RAMBank != 0))
        cartridgeData[RAMBank - 1][addr - 0x8000] = value;
    else if (addr > 0x7FFF)
        RAM[addr] = value;

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movb %al, -0xd(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq (%rax), %rdi
callq 0x30c0
cmpl $0x8000, -0xc(%rbp)     # imm = 0x8000
jge 0x93d2
jmp 0x9593
movl -0xc(%rbp), %eax
movl %eax, -0x1c(%rbp)
subl $0xff00, %eax           # imm = 0xFF00
je 0x941c
jmp 0x93e1
movl -0x1c(%rbp), %eax
subl $0xff04, %eax           # imm = 0xFF04
je 0x9459
jmp 0x93ed
movl -0x1c(%rbp), %eax
subl $0xff41, %eax           # imm = 0xFF41
je 0x946d
jmp 0x93f9
movl -0x1c(%rbp), %eax
subl $0xff44, %eax           # imm = 0xFF44
je 0x94ae
jmp 0x9409
movl -0x1c(%rbp), %eax
subl $0xff46, %eax           # imm = 0xFF46
je 0x94c2
jmp 0x94cd
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rcx
movzbl 0xff00(%rcx), %edx
andl $0xcf, %edx
movb %dl, 0xff00(%rcx)
movzbl -0xd(%rbp), %ecx
andl $0x30, %ecx
movzbl %cl, %edx
movq 0x28(%rax), %rax
movzbl 0xff00(%rax), %ecx
orl %edx, %ecx
movb %cl, 0xff00(%rax)
jmp 0x9593
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movb $0x0, 0xff04(%rax)
jmp 0x9593
movq -0x18(%rbp), %rax
movzbl -0xd(%rbp), %ecx
andl $0xf8, %ecx
movb %cl, -0xd(%rbp)
movq 0x28(%rax), %rcx
movzbl 0xff41(%rcx), %edx
andl $0x7, %edx
movb %dl, 0xff41(%rcx)
movzbl -0xd(%rbp), %edx
movq 0x28(%rax), %rax
movzbl 0xff41(%rax), %ecx
orl %edx, %ecx
movb %cl, 0xff41(%rax)
jmp 0x9593
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movb $0x0, 0xff44(%rax)
jmp 0x9593
movq -0x18(%rbp), %rax
movq (%rax), %rax
movb $0x1, 0x58(%rax)
cmpl $0xe000, -0xc(%rbp)     # imm = 0xE000
setge %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0xfe00, -0xc(%rbp)     # imm = 0xFE00
setl %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x9510
movq -0x18(%rbp), %rax
movb -0xd(%rbp), %dl
movq 0x28(%rax), %rax
movslq -0xc(%rbp), %rcx
movb %dl, (%rax,%rcx)
movl -0xc(%rbp), %eax
subl $0x2000, %eax           # imm = 0x2000
movl %eax, -0xc(%rbp)
movq -0x18(%rbp), %rcx
cmpl $0x9fff, -0xc(%rbp)     # imm = 0x9FFF
setg %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0xbfff, -0xc(%rbp)     # imm = 0xBFFF
setl %dl
andb $0x1, %dl
movzbl %dl, %edx
andl %edx, %eax
movzbl 0x1d(%rcx), %ecx
cmpl $0x0, %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x9576
movq -0x18(%rbp), %rcx
movb -0xd(%rbp), %dl
movq 0x20(%rcx), %rax
movzbl 0x1d(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movl -0xc(%rbp), %ecx
subl $0x8000, %ecx           # imm = 0x8000
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x9593
cmpl $0x7fff, -0xc(%rbp)     # imm = 0x7FFF
jle 0x9591
movq -0x18(%rbp), %rax
movb -0xd(%rbp), %dl
movq 0x28(%rax), %rax
movslq -0xc(%rbp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x9593
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)