// File: khedoros[P]khednes/ppu3.cpp
// Function: ppu::reg_write(unsigned int, unsigned char, unsigned int)
void ppu::reg_write(const unsigned int addr,const unsigned char val, const unsigned int cycle) {
    //cout<<"!! "<<phases[phase(cycle)]<<" Write address: 0x"<<hex<<addr<<" Value: 0x"<<int(val)<<dec<<" Cycle: "<<cycle<<endl;
    ppu_phase curphase = phase(cycle);
    if(curphase == RENDER) ++s.writes_during_render;
    switch(addr) {
        case 0x2000:
        {
            int bg_table = control0.bg_table;
            int spr_table = control0.sprite_table;
            control0.reg = val;
            vram_ptr_reset.fields.page_y = (control0.base_addr & 2)/2;
            vram_ptr_reset.fields.page_x = (control0.base_addr & 1);

            int xscroll = (control0.base_addr%2) * 32 + vram_ptr_reset.fields.tile_x;
            int yscroll = (control0.base_addr/2) * 30 + vram_ptr_reset.fields.tile_y;
            if(curphase != RENDER && curphase != POST_RENDER) { //keeps track of where the screen will start
                set_scroll(xscroll*8+fine_x, yscroll*8+vram_ptr_reset.fields.fine_y);
                cart.ppu_change(cycle, BG_CHANGE_ADDR, control0.bg_table);
                cart.ppu_change(cycle, SPR_CHANGE_ADDR, control0.sprite_table);
                //if(control0.bg_table != bg_table) cout<<"Changed the bg table (to "<<control0.bg_table<<"), cycle: "<<cycle<<endl;
                //if(control0.sprite_table != spr_table) cout<<"Changed the sprite table (to "<<control0.sprite_table<<"), cycle: "<<cycle<<endl;
            } else { //keeps track of when (during rendering) the reset shifts, but only worry about the X reset
                set_scroll(xscroll*8+fine_x, yscroll*8+vram_ptr_reset.fields.fine_y, cycle%CLK_PER_LINE, cycle/CLK_PER_LINE);
                if(control0.bg_table != bg_table) {
                    //cout<<"Changed the bg table mid-frame! (to "<<control0.bg_table<<"), cycle: "<<cycle<<endl;
                    cart.ppu_change(cycle, BG_CHANGE_ADDR, 1 - control0.bg_table);
                }
                if(control0.sprite_table != spr_table) {
                    //cout<<"Changed the sprite table mid-frame! (to "<<control0.sprite_table<<"), cycle: "<<cycle<<endl;
                    cart.ppu_change(cycle, SPR_CHANGE_ADDR, 1 - control0.sprite_table);
                }
            }
        }
            break;
        case 0x2001:
            /*
            cout<<"Wrote "<<hex<<val<<dec<<" to 2001 (Color disabled: "<<control1.bits.color_disabled
                <<" show left bg: "<<control1.bits.show_left_bg<<" show left sprites: "<<control1.bits.show_left_sprites
                <<" show bg: "<<control1.bits.show_bg<<" show sprites: "<<control1.bits.show_sprites<<endl;
            */
            control1.reg = val;
            break;
        case 0x2003:
            spraddr = val;
            break;
        case 0x2004:
            if(spraddr/4 == 0) recalc_s0 = true;
            recalc_overflow = true;
            sprites[spraddr/4].val[spraddr%4] = val;
            spraddr++;
            break;
        case 0x2005:
            if(!scroll_latch) {
                vram_ptr_reset.fields.tile_x = (val & 0xf8)>>(3) ;
                fine_x = (val & 0x7);
                //cout<<"Set X reset to ("<<(control0.base_addr&1)*256+vram_ptr_reset.fields.tile_x*8+fine_x<<", "
                //    <<(control0.base_addr&2)*120+vram_ptr_reset.fields.tile_y*8+vram_ptr_reset.fields.fine_y<<") at cycle "
                //    <<cycle<<" ("<<cycle/CLK_PER_LINE<<", "<<cycle%CLK_PER_LINE<<") ("<<phases[curphase]<<")"<<endl;
            }
            else {
                vram_ptr_reset.fields.tile_y = (val & 0xf8)>>(3);
                vram_ptr_reset.fields.fine_y = (val & 0x7);
                //cout<<"Set Y reset to ("<<(control0.base_addr&1)*256+vram_ptr_reset.fields.tile_x*8+fine_x<<", "
                //    <<(control0.base_addr&2)*120+vram_ptr_reset.fields.tile_y*8+vram_ptr_reset.fields.fine_y<<") at cycle "
                //    <<cycle<<" ("<<cycle/CLK_PER_LINE<<", "<<cycle%CLK_PER_LINE<<") ("<<phases[curphase]<<")"<<endl;
            }
            if(curphase != RENDER) { //keeps track of where the screen will start
                int xscroll = (control0.base_addr%2) * 32 + vram_ptr_reset.fields.tile_x;
                int yscroll = (control0.base_addr/2) * 30 + vram_ptr_reset.fields.tile_y;
                set_scroll(xscroll*8+fine_x, yscroll*8+vram_ptr_reset.fields.fine_y);
            }
            else if(curphase == RENDER) { //keeps track of when (during rendering) the reset shifts, but only worry about the X reset
                int xscroll = (control0.base_addr%2) * 32 + vram_ptr_reset.fields.tile_x;
                int yscroll = (control0.base_addr/2) * 30 + vram_ptr_reset.fields.tile_y;
                set_scroll(xscroll*8+fine_x, yscroll*8+vram_ptr_reset.fields.fine_y, cycle%CLK_PER_LINE, cycle/CLK_PER_LINE);
            }
            scroll_latch = !scroll_latch;
            break;
        case 0x2006:
            if(!scroll_latch) {
                vram_ptr_reset.bytes.high = val;
                vram_ptr_reset.bytes.pad = 0;
            }
            else {
                vram_ptr_reset.bytes.low = val;
                vram_ptr = vram_ptr_reset;
            }

            if(curphase != RENDER) { //keep track of where the screen starts
                int xscroll = (control0.base_addr%2) * 32 + vram_ptr_reset.fields.tile_x;
                int yscroll = (control0.base_addr/2) * 30 + vram_ptr_reset.fields.tile_y;
                //cout<<"2006: set scroll to ("<<yscroll<<", "<<xscroll<<")"<<endl;
                set_scroll(xscroll*8+fine_x, yscroll*8+vram_ptr_reset.fields.fine_y);
            }
            else if(curphase == RENDER) {
                int xscroll = (control0.base_addr%2) * 32 + vram_ptr_reset.fields.tile_x;
                int yscroll = (control0.base_addr/2) * 30 + vram_ptr_reset.fields.tile_y;
                set_scroll(xscroll*8+fine_x, yscroll*8+vram_ptr_reset.fields.fine_y, cycle%CLK_PER_LINE, cycle/CLK_PER_LINE);
            }
            scroll_latch = !scroll_latch;
            break;
        case 0x2007:
            //cout<<"0x2007 (0x"<<hex<<vram_ptr.pointer<<dec<<"): "<<hex<<int(val)<<dec<<"(";
            if(vram_ptr.pointer < 0x2000) {
                //cout<<"Writing to Pattern Table)"<<endl;
                bool wrote = cart.put_cbyte(val, vram_ptr.pointer);
                if(wrote) {
                    int table = (vram_ptr.pointer < 0x1000)?0:1;
                    int tile = (vram_ptr.pointer & 0xfff) / 16;
                    for(int palnum = 0; palnum < 8; ++palnum) {
                        unget_Surface(table, tile, palnum);
                    }
                }
            }
            else {
                unsigned int ptr = vram_ptr.pointer;
                if(ptr >= 0x3000 && ptr < 0x3F00) ptr -= 0x1000;
                if(ptr < 0x23C0) {
                    //cout<<"Writing to Name Table 0)"<<endl;
                    nt[0][ptr - 0x2000] = val;
                }
                else if(ptr < 0x2400) {
                    //cout<<"Writing to Attribute Table 0)"<<endl;
                    at[0][ptr - 0x23C0] = val;
                }
                else if(ptr < 0x27C0) {
                    //cout<<"Writing to Name Table 1)"<<endl;
                    nt[1][ptr - 0x2400] = val;
                }
                else if(ptr < 0x2800) {
                    //cout<<"Writing to Attribute Table 1)"<<endl;
                    at[1][ptr - 0x27C0] = val;
                }
                else if(ptr < 0x2BC0) {
                    //cout<<"Writing to Name Table 2)"<<endl;
                    nt[2][ptr - 0x2800] = val;
                }
                else if(ptr < 0x2C00) {
                    //cout<<"Writing to Attribute Table 2)"<<endl;
                    at[2][ptr - 0x2BC0] = val;
                }
                else if(ptr < 0x2FC0) {
                    //cout<<"Writing to Name Table 3)"<<endl;
                    nt[3][ptr - 0x2C00] = val;
                }
                else if(ptr < 0x3000) {
                    //cout<<"Writing to Attribute Table 3)"<<endl;
                    at[3][ptr - 0x2FC0] = val;
                }
                else {
                    ptr &= 0x1f;
                    if(ptr < 0x10) {
                        //cout<<"Writing to Background Palette)"<<endl;
                    }
                    else {
                        //cout<<"Writing to Sprite Palette)"<<endl;
                    }
                    int oldval = *(pal[ptr]);
                    if(val != oldval) {
                        *(pal[ptr]) = (val&0x3f);
                        //cout<<hex<<"Palette value "<<ptr<<" changed, clearing palette "<<(ptr>>(2))<<" tiles"<<endl;
                        for(int table = 0; table < 2; ++table) {
                            for(int tile = 0; tile < 256; ++tile) {
                                unget_Surface(table, tile, ptr>>(2));
                            }
                        }
                    }
                }
            }
            vram_ptr.pointer++;
            if(control0.v_inc_down) vram_ptr.pointer +=31;
            break;
        default:
            cout<<"Writing to register 0x"<<hex<<addr<<" isn't handled."<<dec<<endl;
        break;
    }
    ++s.writes;
}

// Assembly:
subq $0x88, %rsp
movb %dl, %al
movq %rdi, 0x80(%rsp)
movl %esi, 0x7c(%rsp)
movb %al, 0x7b(%rsp)
movl %ecx, 0x74(%rsp)
movq 0x80(%rsp), %rdi
movq %rdi, 0x18(%rsp)
movl 0x74(%rsp), %esi
callq 0x1dc80
movl %eax, 0x70(%rsp)
cmpl $0x3, 0x70(%rsp)
jne 0x1d0a2
movq 0x18(%rsp), %rax
movl 0x1c4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x1c4(%rax)
movl 0x7c(%rsp), %eax
addl $0xffffe000, %eax       # imm = 0xFFFFE000
movl %eax, %ecx
movq %rcx, 0x10(%rsp)
subl $0x7, %eax
ja 0x1dc05
movq 0x10(%rsp), %rax
leaq 0xf4a9(%rip), %rcx      # 0x2c570
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x18(%rsp), %rcx
movb 0x21850(%rcx), %al
shrb $0x4, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x6c(%rsp)
movb 0x21850(%rcx), %al
shrb $0x3, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, 0x68(%rsp)
movb 0x7b(%rsp), %al
movb %al, 0x21850(%rcx)
movb 0x21850(%rcx), %al
andb $0x3, %al
movzbl %al, %eax
andl $0x2, %eax
movl $0x2, %esi
cltd
idivl %esi
movw %ax, %dx
movw 0x6d8(%rcx), %ax
andw $0x1, %dx
shlw $0xb, %dx
andw $0xf7ff, %ax            # imm = 0xF7FF
orw %dx, %ax
movw %ax, 0x6d8(%rcx)
movb 0x21850(%rcx), %al
andb $0x3, %al
movzbl %al, %eax
andl $0x1, %eax
movw %ax, %dx
movw 0x6d8(%rcx), %ax
andw $0x1, %dx
shlw $0xa, %dx
andw $0xfbff, %ax            # imm = 0xFBFF
orw %dx, %ax
movw %ax, 0x6d8(%rcx)
movb 0x21850(%rcx), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %esi
cltd
idivl %esi
movl %edx, %eax
shll $0x5, %eax
movw 0x6d8(%rcx), %dx
andw $0x1f, %dx
movzwl %dx, %edx
addl %edx, %eax
movl %eax, 0x64(%rsp)
movb 0x21850(%rcx), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %esi
cltd
idivl %esi
imull $0x1e, %eax, %eax
movw 0x6d8(%rcx), %cx
shrw $0x5, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x60(%rsp)
cmpl $0x3, 0x70(%rsp)
je 0x1d25d
cmpl $0x4, 0x70(%rsp)
je 0x1d25d
movq 0x18(%rsp), %rdi
movl 0x64(%rsp), %esi
shll $0x3, %esi
movb 0x6e0(%rdi), %al
andb $0x7, %al
movzbl %al, %eax
addl %eax, %esi
movl 0x60(%rsp), %edx
shll $0x3, %edx
movw 0x6d8(%rdi), %ax
shrw $0xc, %ax
andw $0x7, %ax
movzwl %ax, %eax
addl %eax, %edx
callq 0x1e3c0
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movl 0x74(%rsp), %esi
movb 0x21850(%rax), %al
shrb $0x4, %al
andb $0x1, %al
movzbl %al, %ecx
movl $0x20004, %edx          # imm = 0x20004
callq 0x11240
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movl 0x74(%rsp), %esi
movb 0x21850(%rax), %al
shrb $0x3, %al
andb $0x1, %al
movzbl %al, %ecx
movl $0x20003, %edx          # imm = 0x20003
callq 0x11240
jmp 0x1d349
movq 0x18(%rsp), %rdi
movl 0x64(%rsp), %esi
shll $0x3, %esi
movb 0x6e0(%rdi), %al
andb $0x7, %al
movzbl %al, %eax
addl %eax, %esi
movl 0x60(%rsp), %eax
shll $0x3, %eax
movw 0x6d8(%rdi), %cx
shrw $0xc, %cx
andw $0x7, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0xc(%rsp)
movl 0x74(%rsp), %eax
movl $0x155, %ecx            # imm = 0x155
xorl %edx, %edx
divl %ecx
movl %edx, %ecx
movl 0x74(%rsp), %eax
movl $0x155, %r8d            # imm = 0x155
xorl %edx, %edx
divl %r8d
movl 0xc(%rsp), %edx
movl %eax, %r8d
callq 0x1e3f0
movq 0x18(%rsp), %rax
movb 0x21850(%rax), %al
shrb $0x4, %al
andb $0x1, %al
movzbl %al, %eax
cmpl 0x6c(%rsp), %eax
je 0x1d303
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movl 0x74(%rsp), %esi
movb 0x21850(%rax), %al
shrb $0x4, %al
andb $0x1, %al
movzbl %al, %eax
movl $0x1, %ecx
subl %eax, %ecx
movl $0x20004, %edx          # imm = 0x20004
callq 0x11240
movq 0x18(%rsp), %rax
movb 0x21850(%rax), %al
shrb $0x3, %al
andb $0x1, %al
movzbl %al, %eax
cmpl 0x68(%rsp), %eax
je 0x1d347
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movl 0x74(%rsp), %esi
movb 0x21850(%rax), %al
shrb $0x3, %al
andb $0x1, %al
movzbl %al, %eax
movl $0x1, %ecx
subl %eax, %ecx
movl $0x20003, %edx          # imm = 0x20003
callq 0x11240
jmp 0x1d349
jmp 0x1dc60
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %cl
movb %cl, 0x21854(%rax)
jmp 0x1dc60
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %cl
movb %cl, 0x308(%rax)
jmp 0x1dc60
movq 0x18(%rsp), %rax
movzbl 0x308(%rax), %eax
movl $0x4, %ecx
cltd
idivl %ecx
cmpl $0x0, %eax
jne 0x1d39b
movq 0x18(%rsp), %rax
movb $0x1, 0x6d5(%rax)
movq 0x18(%rsp), %rax
movb $0x1, 0x6d4(%rax)
movb 0x7b(%rsp), %sil
movq %rax, %rcx
addq $0x208, %rcx            # imm = 0x208
movzbl 0x308(%rax), %eax
movl $0x4, %edi
cltd
idivl %edi
movl %eax, %edx
movq 0x18(%rsp), %rax
movslq %edx, %rdx
shlq $0x2, %rdx
addq %rdx, %rcx
movzbl 0x308(%rax), %eax
movl $0x4, %edi
cltd
idivl %edi
movq 0x18(%rsp), %rax
movslq %edx, %rdx
movb %sil, (%rcx,%rdx)
movb 0x308(%rax), %cl
addb $0x1, %cl
movb %cl, 0x308(%rax)
jmp 0x1dc60
movq 0x18(%rsp), %rax
testb $0x1, 0x6e2(%rax)
jne 0x1d462
movq 0x18(%rsp), %rax
movzbl 0x7b(%rsp), %ecx
andl $0xf8, %ecx
sarl $0x3, %ecx
movw %cx, %dx
movw 0x6d8(%rax), %cx
andw $0x1f, %dx
andw $-0x20, %cx
orw %dx, %cx
movw %cx, 0x6d8(%rax)
movzbl 0x7b(%rsp), %ecx
andl $0x7, %ecx
movb %cl, %dl
movb 0x6e0(%rax), %cl
andb $0x7, %dl
andb $-0x8, %cl
orb %dl, %cl
movb %cl, 0x6e0(%rax)
jmp 0x1d4bf
movq 0x18(%rsp), %rax
movzbl 0x7b(%rsp), %ecx
andl $0xf8, %ecx
sarl $0x3, %ecx
movw %cx, %dx
movw 0x6d8(%rax), %cx
andw $0x1f, %dx
shlw $0x5, %dx
andw $0xfc1f, %cx            # imm = 0xFC1F
orw %dx, %cx
movw %cx, 0x6d8(%rax)
movzbl 0x7b(%rsp), %ecx
andl $0x7, %ecx
movw %cx, %dx
movw 0x6d8(%rax), %cx
andw $0x7, %dx
shlw $0xc, %dx
andw $0x8fff, %cx            # imm = 0x8FFF
orw %dx, %cx
movw %cx, 0x6d8(%rax)
cmpl $0x3, 0x70(%rsp)
je 0x1d562
movq 0x18(%rsp), %rdi
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %edx, %eax
shll $0x5, %eax
movw 0x6d8(%rdi), %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x5c(%rsp)
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
imull $0x1e, %eax, %eax
movw 0x6d8(%rdi), %cx
shrw $0x5, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x58(%rsp)
movl 0x5c(%rsp), %esi
shll $0x3, %esi
movb 0x6e0(%rdi), %al
andb $0x7, %al
movzbl %al, %eax
addl %eax, %esi
movl 0x58(%rsp), %edx
shll $0x3, %edx
movw 0x6d8(%rdi), %ax
shrw $0xc, %ax
andw $0x7, %ax
movzwl %ax, %eax
addl %eax, %edx
callq 0x1e3c0
jmp 0x1d62b
cmpl $0x3, 0x70(%rsp)
jne 0x1d629
movq 0x18(%rsp), %rdi
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %edx, %eax
shll $0x5, %eax
movw 0x6d8(%rdi), %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x54(%rsp)
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
imull $0x1e, %eax, %eax
movw 0x6d8(%rdi), %cx
shrw $0x5, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x50(%rsp)
movl 0x54(%rsp), %esi
shll $0x3, %esi
movb 0x6e0(%rdi), %al
andb $0x7, %al
movzbl %al, %eax
addl %eax, %esi
movl 0x50(%rsp), %eax
shll $0x3, %eax
movw 0x6d8(%rdi), %cx
shrw $0xc, %cx
andw $0x7, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x8(%rsp)
movl 0x74(%rsp), %eax
movl $0x155, %ecx            # imm = 0x155
xorl %edx, %edx
divl %ecx
movl %edx, %ecx
movl 0x74(%rsp), %eax
movl $0x155, %r8d            # imm = 0x155
xorl %edx, %edx
divl %r8d
movl 0x8(%rsp), %edx
movl %eax, %r8d
callq 0x1e3f0
jmp 0x1d62b
movq 0x18(%rsp), %rax
movb 0x6e2(%rax), %cl
xorb $-0x1, %cl
andb $0x1, %cl
movb %cl, 0x6e2(%rax)
jmp 0x1dc60
movq 0x18(%rsp), %rax
testb $0x1, 0x6e2(%rax)
jne 0x1d699
movq 0x18(%rsp), %rax
movzbl 0x7b(%rsp), %ecx
movw %cx, %dx
movw 0x6d8(%rax), %cx
andw $0x3f, %dx
shlw $0x8, %dx
andw $0xc0ff, %cx            # imm = 0xC0FF
orw %dx, %cx
movw %cx, 0x6d8(%rax)
movw 0x6d8(%rax), %cx
andw $0x3fff, %cx            # imm = 0x3FFF
orw $0x0, %cx
movw %cx, 0x6d8(%rax)
jmp 0x1d6cd
movq 0x18(%rsp), %rax
movzbl 0x7b(%rsp), %ecx
movw %cx, %dx
movw 0x6d8(%rax), %cx
andw $0xff, %dx
andw $0xff00, %cx            # imm = 0xFF00
orw %dx, %cx
movw %cx, 0x6d8(%rax)
movl 0x6d8(%rax), %ecx
movl %ecx, 0x6dc(%rax)
cmpl $0x3, 0x70(%rsp)
je 0x1d770
movq 0x18(%rsp), %rdi
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %edx, %eax
shll $0x5, %eax
movw 0x6d8(%rdi), %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x4c(%rsp)
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
imull $0x1e, %eax, %eax
movw 0x6d8(%rdi), %cx
shrw $0x5, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x48(%rsp)
movl 0x4c(%rsp), %esi
shll $0x3, %esi
movb 0x6e0(%rdi), %al
andb $0x7, %al
movzbl %al, %eax
addl %eax, %esi
movl 0x48(%rsp), %edx
shll $0x3, %edx
movw 0x6d8(%rdi), %ax
shrw $0xc, %ax
andw $0x7, %ax
movzwl %ax, %eax
addl %eax, %edx
callq 0x1e3c0
jmp 0x1d839
cmpl $0x3, 0x70(%rsp)
jne 0x1d837
movq 0x18(%rsp), %rdi
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %edx, %eax
shll $0x5, %eax
movw 0x6d8(%rdi), %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x44(%rsp)
movb 0x21850(%rdi), %al
andb $0x3, %al
movzbl %al, %eax
movl $0x2, %ecx
cltd
idivl %ecx
imull $0x1e, %eax, %eax
movw 0x6d8(%rdi), %cx
shrw $0x5, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x40(%rsp)
movl 0x44(%rsp), %esi
shll $0x3, %esi
movb 0x6e0(%rdi), %al
andb $0x7, %al
movzbl %al, %eax
addl %eax, %esi
movl 0x40(%rsp), %eax
shll $0x3, %eax
movw 0x6d8(%rdi), %cx
shrw $0xc, %cx
andw $0x7, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, 0x4(%rsp)
movl 0x74(%rsp), %eax
movl $0x155, %ecx            # imm = 0x155
xorl %edx, %edx
divl %ecx
movl %edx, %ecx
movl 0x74(%rsp), %eax
movl $0x155, %r8d            # imm = 0x155
xorl %edx, %edx
divl %r8d
movl 0x4(%rsp), %edx
movl %eax, %r8d
callq 0x1e3f0
jmp 0x1d839
movq 0x18(%rsp), %rax
movb 0x6e2(%rax), %cl
xorb $-0x1, %cl
andb $0x1, %cl
movb %cl, 0x6e2(%rax)
jmp 0x1dc60
movq 0x18(%rsp), %rax
movw 0x6dc(%rax), %ax
andw $0x3fff, %ax            # imm = 0x3FFF
movzwl %ax, %eax
cmpl $0x2000, %eax           # imm = 0x2000
jge 0x1d920
movq 0x18(%rsp), %rax
movq (%rax), %rdi
movzbl 0x7b(%rsp), %esi
movw 0x6dc(%rax), %ax
andw $0x3fff, %ax            # imm = 0x3FFF
movzwl %ax, %edx
callq 0x111f0
andb $0x1, %al
movb %al, 0x3f(%rsp)
testb $0x1, 0x3f(%rsp)
je 0x1d91b
movq 0x18(%rsp), %rax
movw 0x6dc(%rax), %cx
andw $0x3fff, %cx            # imm = 0x3FFF
movzwl %cx, %esi
movl $0x1, %ecx
xorl %edx, %edx
cmpl $0x1000, %esi           # imm = 0x1000
cmovll %edx, %ecx
movl %ecx, 0x38(%rsp)
movw 0x6dc(%rax), %ax
andw $0x3fff, %ax            # imm = 0x3FFF
movzwl %ax, %eax
andl $0xfff, %eax            # imm = 0xFFF
movl $0x10, %ecx
cltd
idivl %ecx
movl %eax, 0x34(%rsp)
movl $0x0, 0x30(%rsp)
cmpl $0x8, 0x30(%rsp)
jge 0x1d919
movq 0x18(%rsp), %rdi
movl 0x38(%rsp), %esi
movl 0x34(%rsp), %edx
movl 0x30(%rsp), %ecx
callq 0x1cc40
movl 0x30(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x30(%rsp)
jmp 0x1d8ef
jmp 0x1d91b
jmp 0x1db86
movq 0x18(%rsp), %rax
movw 0x6dc(%rax), %ax
andw $0x3fff, %ax            # imm = 0x3FFF
movzwl %ax, %eax
movl %eax, 0x2c(%rsp)
cmpl $0x3000, 0x2c(%rsp)     # imm = 0x3000
jb 0x1d958
cmpl $0x3f00, 0x2c(%rsp)     # imm = 0x3F00
jae 0x1d958
movl 0x2c(%rsp), %eax
subl $0x1000, %eax           # imm = 0x1000
movl %eax, 0x2c(%rsp)
cmpl $0x23c0, 0x2c(%rsp)     # imm = 0x23C0
jae 0x1d986
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x16f0(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x2000, %ecx           # imm = 0x2000
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db84
cmpl $0x2400, 0x2c(%rsp)     # imm = 0x2400
jae 0x1d9b4
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x1710(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x23c0, %ecx           # imm = 0x23C0
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db82
cmpl $0x27c0, 0x2c(%rsp)     # imm = 0x27C0
jae 0x1d9e2
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x16f8(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x2400, %ecx           # imm = 0x2400
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db80
cmpl $0x2800, 0x2c(%rsp)     # imm = 0x2800
jae 0x1da10
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x1718(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x27c0, %ecx           # imm = 0x27C0
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db7e
cmpl $0x2bc0, 0x2c(%rsp)     # imm = 0x2BC0
jae 0x1da3e
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x1700(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x2800, %ecx           # imm = 0x2800
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db7c
cmpl $0x2c00, 0x2c(%rsp)     # imm = 0x2C00
jae 0x1da6c
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x1720(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x2bc0, %ecx           # imm = 0x2BC0
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db7a
cmpl $0x2fc0, 0x2c(%rsp)     # imm = 0x2FC0
jae 0x1da9a
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x1708(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x2c00, %ecx           # imm = 0x2C00
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db78
cmpl $0x3000, 0x2c(%rsp)     # imm = 0x3000
jae 0x1dac8
movq 0x18(%rsp), %rax
movb 0x7b(%rsp), %dl
movq 0x1728(%rax), %rax
movl 0x2c(%rsp), %ecx
subl $0x2fc0, %ecx           # imm = 0x2FC0
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
jmp 0x1db76
movl 0x2c(%rsp), %eax
andl $0x1f, %eax
movl %eax, 0x2c(%rsp)
cmpl $0x10, 0x2c(%rsp)
jae 0x1dadc
jmp 0x1dade
jmp 0x1dade
movq 0x18(%rsp), %rax
movl 0x2c(%rsp), %ecx
movq 0x1750(%rax,%rcx,8), %rax
movzbl (%rax), %eax
movl %eax, 0x28(%rsp)
movzbl 0x7b(%rsp), %eax
cmpl 0x28(%rsp), %eax
je 0x1db74
movq 0x18(%rsp), %rax
movzbl 0x7b(%rsp), %ecx
andl $0x3f, %ecx
movl 0x2c(%rsp), %edx
movq 0x1750(%rax,%rdx,8), %rax
movb %cl, (%rax)
movl $0x0, 0x24(%rsp)
cmpl $0x2, 0x24(%rsp)
jge 0x1db72
movl $0x0, 0x20(%rsp)
cmpl $0x100, 0x20(%rsp)      # imm = 0x100
jge 0x1db63
movq 0x18(%rsp), %rdi
movl 0x24(%rsp), %esi
movl 0x20(%rsp), %edx
movl 0x2c(%rsp), %ecx
shrl $0x2, %ecx
callq 0x1cc40
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x1db33
jmp 0x1db65
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x1db24
jmp 0x1db74
jmp 0x1db76
jmp 0x1db78
jmp 0x1db7a
jmp 0x1db7c
jmp 0x1db7e
jmp 0x1db80
jmp 0x1db82
jmp 0x1db84
jmp 0x1db86
movq 0x18(%rsp), %rax
movw 0x6dc(%rax), %cx
andw $0x3fff, %cx            # imm = 0x3FFF
movzwl %cx, %ecx
addl $0x1, %ecx
movw %cx, %dx
movw 0x6dc(%rax), %cx
andw $0x3fff, %dx            # imm = 0x3FFF
andw $0xc000, %cx            # imm = 0xC000
orw %dx, %cx
movw %cx, 0x6dc(%rax)
movb 0x21850(%rax), %al
shrb $0x2, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x1dc03
movq 0x18(%rsp), %rax
movw 0x6dc(%rax), %cx
andw $0x3fff, %cx            # imm = 0x3FFF
movzwl %cx, %ecx
addl $0x1f, %ecx
movw %cx, %dx
movw 0x6dc(%rax), %cx
andw $0x3fff, %dx            # imm = 0x3FFF
andw $0xc000, %cx            # imm = 0xC000
orw %dx, %cx
movw %cx, 0x6dc(%rax)
jmp 0x1dc60
movq 0x193a4(%rip), %rdi     # 0x36fb0
leaq 0xea2b(%rip), %rsi      # 0x2c63e
callq 0x43c0
movq %rax, %rdi
leaq -0xc602(%rip), %rsi     # 0x11620
callq 0x4150
movq %rax, %rdi
movl 0x7c(%rsp), %esi
callq 0x44c0
movq %rax, %rdi
leaq 0xea18(%rip), %rsi      # 0x2c655
callq 0x43c0
movq %rax, %rdi
leaq -0xf1cc(%rip), %rsi     # 0xea80
callq 0x4150
movq %rax, %rdi
movq 0x19335(%rip), %rsi     # 0x36f90
callq 0x4400
movq 0x18(%rsp), %rax
movl 0x1cc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x1cc(%rax)
addq $0x88, %rsp
retq
nopl (%rax)