// File: /workspace/github_cpp_makefile_star2_O2/NGageMegaman[P]NEScutre/src/mem.cpp
// Function: Mem::write_byte(unsigned short, unsigned char)
void Mem::write_byte(uint16_t addr, uint8_t data) {
    //Mirroring
    if (addr > 0x07FF) {
	if (addr < 0x1000)
	    addr -= 0x0800;
	else if (addr < 0x1800)
	    addr -= 0x1000;
	else if (addr < 0x2000)
	    addr -= 0x1800;
    }
    //PPU regs mirroring
    if (addr > 0x2007 && addr < 0x4000) {
	addr = (addr & 7) + 0x2000;
    }
    
    if (addr == 0x2000)
	mem_ppu->write_PPUCTRL(data);
    else if (addr == 0x2001)
	mem_ppu->write_PPUMASK(data);
    //else if (addr == 0x2002)
	//ppu->PPUSTATUS = data;
    else if (addr == 0x2003)
	mem_ppu->write_OAMADDR(data);
    else if (addr == 0x2004)
	mem_ppu->write_OAMDATA(data);
    else if (addr == 0x2005)
	mem_ppu->write_PPUSCROLL(data);
    else if (addr == 0x2006)
	mem_ppu->write_PPUADDR(data);
    else if (addr == 0x2007)
	mem_ppu->write_PPUDATA(data);
    else if (addr == 0x4014) {
	uint8_t data_array[256];
	for (int i = 0; i < 256; ++i) 
	    data_array[i] = ram[(unsigned) (data << 8) + i];
	    
	mem_ppu->write_OAMDMA(data_array);
    }
    else if (addr == 0x4016 && data == 1) {
	controller_read_latch = 0;
	controller_latch = 0;
	XEvent event;
	while (XPending(di)) {
	    XNextEvent(di, &event);
	    int a;
	    if (event.type == KeyRelease) {
		a = event.xkey.keycode;
		if (a == 52)       //z_key
	    	    controller_inputs &= 0xfe;
	    	else if (a == 53)  //x_key
	    	    controller_inputs &= 0xfd;
	    	else if (a == 22)  //backspace_key
	    	    controller_inputs &= 0xfb;
	    	else if (a == 36)  //enter_key
	    	    controller_inputs &= 0xf7;
	    	else if (a == 111)  //up_key
	    	    controller_inputs &= 0xef;
	    	else if (a == 116)  //down_key
	    	    controller_inputs &= 0xdf;
	    	else if (a == 113)  //left_key
	    	    controller_inputs &= 0xbf;
	    	else if (a == 114)  //right_key
	    	    controller_inputs &= 0x7f;
	    }
	    if (event.type == KeyPress) {
		a = event.xkey.keycode;
		if (a == 52)       //z_key
	    	    controller_inputs |= 0x01;
	    	else if (a == 53)  //x_key
	    	    controller_inputs |= 0x02;
	    	else if (a == 22)  //backspace_key
	    	    controller_inputs |= 0x04;
	    	else if (a == 36)  //enter_key
	    	    controller_inputs |= 0x08;
	    	else if (a == 111)  //up_key
	    	    controller_inputs |= 0x10;
	    	else if (a == 116)  //down_key
	    	    controller_inputs |= 0x20;
	    	else if (a == 113)  //left_key
	    	    controller_inputs |= 0x40;
	    	else if (a == 114)  //right_key
	    	    controller_inputs |= 0x80;
	    }
	}
	controller_latch = controller_inputs;
    }
    else if (addr == 0x4016 && data == 0) {
	controller_read_latch = 1;
    }
    else
	ram[addr] = data;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rdi, %rbx
cmpw $0x800, %si             # imm = 0x800
jb 0x2d34
cmpw $0xfff, %si             # imm = 0xFFF
ja 0x2d15
addl $0xfffff800, %esi       # imm = 0xFFFFF800
jmp 0x2d34
cmpw $0x17ff, %si            # imm = 0x17FF
ja 0x2d24
addl $0xfffff000, %esi       # imm = 0xFFFFF000
jmp 0x2d34
leal -0x1800(%rsi), %eax
cmpw $0x2000, %si            # imm = 0x2000
cmovael %esi, %eax
movl %eax, %esi
leal -0x2008(%rsi), %ecx
movl %esi, %eax
andl $0x2007, %eax           # imm = 0x2007
cmpw $0x1ff8, %cx            # imm = 0x1FF8
cmovael %esi, %eax
movzwl %ax, %ecx
leal -0x2000(%rcx), %esi
cmpl $0x7, %esi
ja 0x2d84
leaq 0x180a(%rip), %rdi      # 0x4568
movslq (%rdi,%rsi,4), %rsi
addq %rdi, %rsi
jmpq *%rsi
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3248
cmpl $0x4014, %ecx           # imm = 0x4014
jne 0x2daf
movzbl %dl, %eax
shll $0x8, %eax
addq %rbx, %rax
xorl %ecx, %ecx
cmpq $0x100, %rcx            # imm = 0x100
je 0x2fd9
movb (%rax,%rcx), %dl
movb %dl, (%rsp,%rcx)
incq %rcx
jmp 0x2d97
cmpb $0x1, %dl
jne 0x2fea
cmpw $0x4016, %ax            # imm = 0x4016
jne 0x2fea
andw $0x0, 0x10008(%rbx)
movq %rsp, %r14
leaq 0x17b4(%rip), %r15      # 0x4588
leaq 0x17c5(%rip), %r12      # 0x45a0
movq 0x10010(%rbx), %rdi
callq 0x1100
testl %eax, %eax
je 0x2ffd
movq 0x10010(%rbx), %rdi
movq %r14, %rsi
callq 0x1180
movl (%rsp), %eax
cmpl $0x2, %eax
je 0x2e44
cmpl $0x3, %eax
jne 0x2ddb
movl 0x54(%rsp), %eax
leal -0x6f(%rax), %ecx
cmpl $0x5, %ecx
jbe 0x2e81
cmpl $0x16, %eax
je 0x2ee6
cmpl $0x24, %eax
je 0x2f0e
cmpl $0x35, %eax
je 0x2efa
cmpl $0x34, %eax
jne 0x2ddb
movb 0x1000a(%rbx), %al
andb $-0x2, %al
jmp 0x2f20
movl 0x54(%rsp), %eax
leal -0x6f(%rax), %ecx
cmpl $0x5, %ecx
jbe 0x2e97
cmpl $0x16, %eax
je 0x2ef0
cmpl $0x24, %eax
je 0x2f18
cmpl $0x35, %eax
je 0x2f04
cmpl $0x34, %eax
jne 0x2ddb
movb 0x1000a(%rbx), %al
orb $0x1, %al
jmp 0x2f20
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movb 0x1000a(%rbx), %al
andb $-0x11, %al
jmp 0x2f20
movslq (%r15,%rcx,4), %rax
addq %r15, %rax
jmpq *%rax
movb 0x1000a(%rbx), %al
orb $0x10, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
andb $0x7f, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
orb $-0x80, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
andb $-0x21, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
andb $-0x41, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
orb $0x20, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
orb $0x40, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
andb $-0x5, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
orb $0x4, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
andb $-0x3, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
orb $0x2, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
andb $-0x9, %al
jmp 0x2f20
movb 0x1000a(%rbx), %al
orb $0x8, %al
movb %al, 0x1000a(%rbx)
jmp 0x2ddb
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3342
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3390
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x33f8
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3430
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3438
movq 0x10000(%rbx), %rdi
movzbl %dl, %esi
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x3266
movq 0x10000(%rbx), %rdi
movq %rsp, %rsi
callq 0x340e
jmp 0x300e
testb %dl, %dl
jne 0x300b
cmpw $0x4016, %ax            # imm = 0x4016
jne 0x300b
movb $0x1, 0x10009(%rbx)
jmp 0x300e
movb 0x1000a(%rbx), %al
movb %al, 0x10008(%rbx)
jmp 0x300e
movb %dl, (%rbx,%rcx)
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r14
popq %r15
retq
nopl (%rax)