// File: khedoros[P]khednes/mem.cpp
// Function: mem::write(unsigned int, unsigned char)
void mem::write(unsigned int address, unsigned char val) {
        address&=0xFFFF;
        written_to[address]=true;
        if(address>=0x2000&&address<0x4000) {
                //cout<<"Writing to PPU "<<endl;
                pu.reg_write((address&7)+0x2000,val,cycle);
        }
        else if(address<=0x1FFF) {
                ram[address&0x7FF]=val;
        }
        else if(address==0x4014) {
                for(int ii=0;ii<256;ii++) {
                        pu.dma(this->read(((int(val))<<(8))+ii),cycle);
                }
        }
        else if((address>=0x4000&&address<0x4014)||address==0x4015||address==0x4017) {
                //util::debug(ORIGIN,"TODO: unimplemented audio stuff.\n");
                snd.reg_write(frame, cycle, address,val);
        }
        else if(address==0x4016) {
                //util::debug(ORIGIN,"TODO: unimplemented joypad handling.\n");
                if((val&0x01)==1) {
                                        joy1_strobe=true;
                                        joy1_bit=0;
                                        joy2_bit=0;
                                }
                                else {
                                        joy1_strobe=false;
                                }
        }
        else if(address>=0x6000&&address<=0x7fff) {
            //std::cout<<"Writing SRAM address "<<std::hex<<(address&0x1fff)<<std::endl;
            sram[address&0x1fff]=val;
        }
        else if(address>=0x8000&&address<=0xffff) {
            if(pu.phase(cycle) == ppu::RENDER) {
                //cout<<dec<<cycle<<": 0x"<<hex<<address<<" = "<<int(val)<<dec<<endl;
            }
            cart.put_pbyte(cycle, val,address);
        }
        else {
                if(cart.isNSF()) {
                    cart.put_pbyte(cycle, val, address);
                }
                else {
                    printf("Hey! Don't try to write %02x to %04x!!\n",val,address);
                    util::debug(ORIGIN,"I don't know what writing %02x to %04x does.\n",val,address);
                }
        }
}

// Assembly:
subq $0x38, %rsp
movb %dl, %al
movq %rdi, 0x30(%rsp)
movl %esi, 0x2c(%rsp)
movb %al, 0x2b(%rsp)
movq 0x30(%rsp), %rdi
movq %rdi, 0x18(%rsp)
movl 0x2c(%rsp), %eax
andl $0xffff, %eax           # imm = 0xFFFF
movl %eax, 0x2c(%rsp)
addq $0x98, %rdi
movl 0x2c(%rsp), %eax
movl %eax, %esi
callq 0x15080
movl $0x1, (%rax)
cmpl $0x2000, 0x2c(%rsp)     # imm = 0x2000
jb 0x14b90
cmpl $0x4000, 0x2c(%rsp)     # imm = 0x4000
jae 0x14b90
movq 0x18(%rsp), %rcx
movq 0x8(%rcx), %rdi
movl 0x2c(%rsp), %esi
andl $0x7, %esi
addl $0x2000, %esi           # imm = 0x2000
movb 0x2b(%rsp), %al
movl 0x18(%rcx), %ecx
movzbl %al, %edx
callq 0x1d050
jmp 0x14dab
cmpl $0x1fff, 0x2c(%rsp)     # imm = 0x1FFF
ja 0x14bc8
movq 0x18(%rsp), %rdi
movb 0x2b(%rsp), %al
movb %al, 0x17(%rsp)
addq $0x20, %rdi
movl 0x2c(%rsp), %eax
andl $0x7ff, %eax            # imm = 0x7FF
movl %eax, %eax
movl %eax, %esi
callq 0x114a0
movb 0x17(%rsp), %cl
movb %cl, (%rax)
jmp 0x14da9
cmpl $0x4014, 0x2c(%rsp)     # imm = 0x4014
jne 0x14c2a
movl $0x0, 0x24(%rsp)
cmpl $0x100, 0x24(%rsp)      # imm = 0x100
jge 0x14c25
movq 0x18(%rsp), %rdi
movq 0x8(%rdi), %rax
movq %rax, 0x8(%rsp)
movzbl 0x2b(%rsp), %esi
shll $0x8, %esi
addl 0x24(%rsp), %esi
callq 0x14460
movq 0x18(%rsp), %rcx
movq 0x8(%rsp), %rdi
movl 0x18(%rcx), %edx
movzbl %al, %esi
callq 0x1d000
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x14bda
jmp 0x14da7
cmpl $0x4000, 0x2c(%rsp)     # imm = 0x4000
jb 0x14c3e
cmpl $0x4014, 0x2c(%rsp)     # imm = 0x4014
jb 0x14c52
cmpl $0x4015, 0x2c(%rsp)     # imm = 0x4015
je 0x14c52
cmpl $0x4017, 0x2c(%rsp)     # imm = 0x4017
jne 0x14c75
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
movl 0x50(%rax), %esi
movl 0x18(%rax), %edx
movl 0x2c(%rsp), %ecx
movzbl 0x2b(%rsp), %r8d
callq 0x24330
jmp 0x14da5
cmpl $0x4016, 0x2c(%rsp)     # imm = 0x4016
jne 0x14cb3
movzbl 0x2b(%rsp), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0x14ca5
movq 0x18(%rsp), %rax
movb $0x1, 0x54(%rax)
movl $0x0, 0x58(%rax)
movl $0x0, 0x5c(%rax)
jmp 0x14cae
movq 0x18(%rsp), %rax
movb $0x0, 0x54(%rax)
jmp 0x14da3
cmpl $0x6000, 0x2c(%rsp)     # imm = 0x6000
jb 0x14cf5
cmpl $0x7fff, 0x2c(%rsp)     # imm = 0x7FFF
ja 0x14cf5
movq 0x18(%rsp), %rdi
movb 0x2b(%rsp), %al
movb %al, 0x7(%rsp)
addq $0x38, %rdi
movl 0x2c(%rsp), %eax
andl $0x1fff, %eax           # imm = 0x1FFF
movl %eax, %eax
movl %eax, %esi
callq 0x114a0
movb 0x7(%rsp), %cl
movb %cl, (%rax)
jmp 0x14da1
cmpl $0x8000, 0x2c(%rsp)     # imm = 0x8000
jb 0x14d3c
cmpl $0xffff, 0x2c(%rsp)     # imm = 0xFFFF
ja 0x14d3c
movq 0x18(%rsp), %rax
movq 0x8(%rax), %rdi
movl 0x18(%rax), %esi
callq 0x1dc80
cmpl $0x3, %eax
jne 0x14d21
jmp 0x14d21
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movl 0x18(%rax), %esi
movzbl 0x2b(%rsp), %edx
movl 0x2c(%rsp), %ecx
callq 0x111b0
jmp 0x14d9f
movq 0x18(%rsp), %rax
movq (%rax), %rdi
callq 0x10f10
testb $0x1, %al
jne 0x14d4f
jmp 0x14d6a
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movl 0x18(%rax), %esi
movzbl 0x2b(%rsp), %edx
movl 0x2c(%rsp), %ecx
callq 0x111b0
jmp 0x14d9d
movzbl 0x2b(%rsp), %esi
movl 0x2c(%rsp), %edx
leaq 0x16d57(%rip), %rdi     # 0x2bad1
movb $0x0, %al
callq 0x4050
movzbl 0x2b(%rsp), %edx
movl 0x2c(%rsp), %ecx
movl $0x3, %edi
leaq 0x16d63(%rip), %rsi     # 0x2baf9
movb $0x0, %al
callq 0x20e00
jmp 0x14d9f
jmp 0x14da1
jmp 0x14da3
jmp 0x14da5
jmp 0x14da7
jmp 0x14da9
jmp 0x14dab
addq $0x38, %rsp
retq