// File: /workspace/github_cpp_makefile_star2_O3/khedoros[P]khednes/ppu3.cpp
// Function: ppu::calc()
int ppu::calc() {

    int crom_update = cart.changed_crom();
    if((crom_update&1) == 1) clear_surfaces(false);
    if((crom_update&2) == 2) clear_surfaces(true);

    //cout<<"Total cycles: "<<s.cycles<<" Total frames: "<<frame<<endl;
    s.cycles += cycles_per_frame;
    ++frame;

    if(!late_vsync_clear) {
        cleared_vsync = false;
    }
    else late_vsync_clear = false;

    if(frame % 2 == 0) cycles_per_frame = CLK_PER_LINE * LINE_PER_FRAME;
    else cycles_per_frame = CLK_PER_LINE * LINE_PER_FRAME - 1;

    if(table_view) {
        //Draw 64 sprites, always, since I can change the blit location easily in compositor::flip()
        for(int spr=63;spr>=0;--spr) {
            blit_sprite(spr);           
        }
        //Draw the palette
        for(int palnum = 0; palnum < 16; ++palnum) {
            for(int x=palnum*16; x < palnum*16 + 16; ++x)
                for(int y=0; y < 16; ++y) {
                    screen.pset(x,y+480,*pal[palnum]);
                    screen.pset(x,y+496,*pal[palnum+16]);
                }
        }
        //Draw the state of the name table
        for(int table = 0; table < 4; ++table) {
            for(int tile_x = 0; tile_x < 32; ++tile_x) {
                for(int tile_y = 0; tile_y < 30; ++tile_y) {
                    int val = nt[table][tile_y * 32 + tile_x];
                    int pal = get_nt_pal(table, tile_x, tile_y);
                    //screen.erase_nt(x,y);
                    int x_offset = 0;
                    int y_offset = 0;
                    if(table == 1)
                        x_offset = 256;
                    else if(table == 2)
                        y_offset = 240;
                    else if(table == 3) {
                        y_offset=240;
                        x_offset=256;
                    }
                    screen.blit_nt(get_Surface(control0.bg_table, val, pal, 0,0), tile_x*8+x_offset, tile_y*8+y_offset);
                }
            }
        }

        for(int table = 0; table < 2; table++) {
            for(int tile_y = 0; tile_y < 16; tile_y++) {
                for(int tile_x = 0; tile_x < 16; tile_x++) {
                    for(int j=0;j<8;++j) {
                        for(int i=0;i<8;++i) {
                            int x = 768+tile_x*8+i;
                            int y = table*128+tile_y*8+j;
                            int col = get_color(table*256+tile_y*16+tile_x,i,j);
                            int map[] = {74, 64, 67, 71};
                            col = map[col];
                            screen.pset(x, y, col);
                        }
                    }
                }
            }
        }
    }
    else if(control1.bits.show_bg) { //Normal game render

        int xspix = init_scroll_x;
        int yspix = init_scroll_y;

        int xstile = xspix / 8;
        int ystile = yspix / 8;

        int xepix = xspix + 256;
        int xetile = xepix / 8 + 1;

        int yepix = 0;
        //int yetile = 0;

        int curytile = 0;

        unsigned int odd_diff = ((frame % 2 == 0)?0:1);
        bool process = true;
        while(process) {
            if(scroll_shifts.size() > 0) {
                yepix = scroll_shifts.front().second + init_scroll_y;
            }
            else {
                yepix = init_scroll_y + 240;
                process = false;
            }
            int yetile = yepix / 8 + 1;

            for(int yt = ystile; yt < yetile; ++yt) {
                unsigned int curcycle = (unsigned int)((VINT_LINES + PRE_RENDER_LINES) * CLK_PER_LINE - odd_diff) + curytile * 8 * CLK_PER_LINE;
                apply_updates_to(curcycle);

                //Draw sprites that should show by now
                if(control1.bits.show_sprites)
                    for(int i=0;i<64;++i)
                        if(sprites[i].y <= curytile * 8)
                            blit_sprite(i);

                //Draw this line of tiles
                for(int xt = xstile; xt < xetile; ++xt) {
                    int table = ((xt / 32) % 2) + (((yt / 30) % 2) * 2);
                    int tile_x = xt % 32;
                    int tile_y = yt % 30;
                    int pal = get_nt_pal(table, tile_x, tile_y);
                    int val = nt[table][tile_y * 32 + tile_x];
                    screen.blit_nt(get_Surface(control0.bg_table, val, pal, 0, 0), xt*8, yt*8);
                }
                ++curytile;
            }
            //Send that region to compositor to be rendered
            screen.add_nt_area(xspix, yspix, xepix, yepix);

            //Process the rest of the shifts, then delete the entry
            if(scroll_shifts.size() > 0) {
                xspix = scroll_shifts.front().first;
                xstile = xspix / 8;

                xepix = xspix + 256;
                xetile = xepix / 8 + 1;

                yspix = yepix;
                ystile = yetile - 1;
                scroll_shifts.pop_front();
            }
        }
        apply_updates_to(100000); //way past end of frame
    }

    if(control1.bits.show_bg || control1.bits.show_sprites) {
        //Set background color
        screen.fill(*pal[0]);
    }
    //Composite the image and display it
    screen.flip();
    if(control0.generate_vblank) {
        //cout<<"Returning 1 (NMI vblank)"<<endl;
        return 1;
    }
    else {
        //cout<<"Returning 0 (no NMI)"<<endl;
        return 0;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %r13
movq (%rdi), %rdi
callq 0xa062
movl %eax, %ebp
testb $0x1, %bpl
je 0xefe8
movq %r13, %rdi
xorl %esi, %esi
callq 0xdd60
testb $0x2, %bpl
je 0xeffb
movq %r13, %rdi
movl $0x1, %esi
callq 0xdd60
movl 0x6e8(%r13), %eax
addq %rax, 0x1d8(%r13)
movl 0x2185c(%r13), %ecx
incl %ecx
movl %ecx, %eax
movl %ecx, 0x2185c(%r13)
cmpb $0x0, 0x6e4(%r13)
je 0xf02f
movb $0x0, 0x6e4(%r13)
jmp 0xf037
movb $0x0, 0x6e3(%r13)
movl %eax, %ecx
andl $0x1, %ecx
movl $0x15cfe, %eax          # imm = 0x15CFE
movl %ecx, 0x24(%rsp)
subl %ecx, %eax
movl %eax, 0x6e8(%r13)
cmpb $0x1, 0x21860(%r13)
movq %r13, 0x10(%rsp)
jne 0xf2c7
movl $0x3f, %ebp
movq %r13, %rdi
movl %ebp, %esi
callq 0xf61a
addl $-0x1, %ebp
jb 0xf066
leaq 0x8(%r13), %rax
movq %rax, 0x38(%rsp)
movl $0x10, (%rsp)
xorl %r14d, %r14d
movq 0x38(%rsp), %rbx
movq %r14, %r12
orq $0x10, %r12
movl %r14d, %ebp
shll $0x4, %ebp
movl $0x1e0, %r15d           # imm = 0x1E0
movq 0x1750(%r13,%r14,8), %rax
movzbl (%rax), %ecx
movq %rbx, %rdi
movl %ebp, %esi
movl %r15d, %edx
callq 0x125f0
leal 0x10(%r15), %edx
movq 0x1750(%r13,%r12,8), %rax
movzbl (%rax), %ecx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x125f0
incl %r15d
cmpl $0x1f0, %r15d           # imm = 0x1F0
jne 0xf0a0
incl %ebp
cmpl (%rsp), %ebp
jne 0xf09a
incq %r14
addl $0x10, (%rsp)
cmpq $0x10, %r14
jne 0xf08d
xorl %esi, %esi
leal -0x1(%rsi), %eax
movq %rax, (%rsp)
xorl %edx, %edx
movq %rsi, 0x18(%rsp)
leal (,%rdx,8), %eax
movl %eax, 0x30(%rsp)
xorl %ebx, %ebx
xorl %r13d, %r13d
movq 0x10(%rsp), %r14
movq %rdx, 0x40(%rsp)
movq 0x16f0(%r14,%rsi,8), %rax
addq %rdx, %rax
movzbl (%rax,%rbx,4), %r15d
movq %r14, %rdi
movl %r13d, %ecx
callq 0xf888
xorl %ebp, %ebp
movl $0x0, %r12d
cmpl $0x2, (%rsp)
ja 0xf15d
leaq 0x6405(%rip), %rcx      # 0x15550
movq (%rsp), %rdx
movl (%rcx,%rdx,4), %ebp
leaq 0x6403(%rip), %rcx      # 0x1555c
movl (%rcx,%rdx,4), %r12d
addl 0x30(%rsp), %r12d
movq 0x10(%rsp), %r14
movl 0x21850(%r14), %esi
shrl $0x4, %esi
andl $0x1, %esi
movq %r14, %rdi
movl %r15d, %edx
movl %eax, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xe9de
addl %ebx, %ebp
movq 0x38(%rsp), %rdi
movq %rax, %rsi
movl %r12d, %edx
movl %ebp, %ecx
callq 0x1277e
incq %r13
addq $0x8, %rbx
cmpq $0x1e, %r13
movq 0x18(%rsp), %rsi
movq 0x40(%rsp), %rdx
jne 0xf11b
incq %rdx
cmpq $0x20, %rdx
jne 0xf101
incq %rsi
cmpq $0x4, %rsi
jne 0xf0f3
xorl %eax, %eax
movb $0x1, %cl
movq 0x10(%rsp), %r14
movq 0x38(%rsp), %rbp
movl %ecx, 0x24(%rsp)
movl %eax, %ecx
shll $0x7, %ecx
movq %rcx, 0x50(%rsp)
shll $0x8, %eax
xorl %edx, %edx
movl %eax, 0xc(%rsp)
movq 0x50(%rsp), %rcx
leal (%rcx,%rdx,8), %ecx
movq %rcx, 0x30(%rsp)
movq %rdx, 0x28(%rsp)
shll $0x4, %edx
addl %eax, %edx
movq %rdx, 0x58(%rsp)
xorl %ecx, %ecx
movl $0x300, %r15d           # imm = 0x300
movq 0x58(%rsp), %rax
movq %rcx, 0x18(%rsp)
leal (%rcx,%rax), %r12d
movq $0x0, (%rsp)
movq 0x30(%rsp), %rax
movq (%rsp), %rcx
addl %ecx, %eax
movl %eax, 0x40(%rsp)
xorl %r13d, %r13d
leal (%r15,%r13), %ebx
movq %r14, %rdi
movl %r12d, %esi
movl %r13d, %edx
movq (%rsp), %rcx
callq 0xf8f8
cltq
leaq 0x62c0(%rip), %rcx      # 0x15520
movl (%rcx,%rax,4), %ecx
movq %rbp, %rdi
movl %ebx, %esi
movl 0x40(%rsp), %edx
callq 0x125f0
incl %r13d
cmpl $0x8, %r13d
jne 0xf241
movq (%rsp), %rax
incl %eax
movq %rax, (%rsp)
cmpl $0x8, %eax
jne 0xf22f
movq 0x18(%rsp), %rcx
incl %ecx
addl $0x8, %r15d
cmpl $0x10, %ecx
jne 0xf219
movq 0x28(%rsp), %rdx
incl %edx
cmpl $0x10, %edx
movl 0xc(%rsp), %eax
jne 0xf1f5
movl $0x1, %eax
testb $0x1, 0x24(%rsp)
movl $0x0, %ecx
jne 0xf1de
jmp 0xf5d1
testb $0x8, 0x21854(%r13)
je 0xf5d1
movq 0x10(%rsp), %r13
movl 0x1e8(%r13), %eax
leal 0x7(%rax), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
movl 0x1ec(%r13), %edx
sarl $0x3, %ecx
movq %rcx, 0x28(%rsp)
leal 0x7(%rdx), %esi
testl %edx, %edx
movq %rdx, 0x70(%rsp)
cmovnsl %edx, %esi
sarl $0x3, %esi
leal 0x100(%rax), %ecx
movq %rax, 0x78(%rsp)
leal 0x107(%rax), %ebp
testl %ecx, %ecx
movl %ecx, 0x4c(%rsp)
cmovnsl %ecx, %ebp
sarl $0x3, %ebp
incl %ebp
leaq 0x8(%r13), %r14
xorl %r15d, %r15d
movq %r14, 0x50(%rsp)
movq 0x200(%r13), %rax
movq %rax, 0x80(%rsp)
testq %rax, %rax
je 0xf353
movq 0x1f0(%r13), %rax
movl 0x14(%rax), %eax
jmp 0xf358
movl $0xf0, %eax
movl 0x1ec(%r13), %ecx
leal (%rcx,%rax), %edx
addl $0x7, %edx
addl %eax, %ecx
movl %ecx, 0x64(%rsp)
cmovnsl %ecx, %edx
sarl $0x3, %edx
movl %edx, 0xc(%rsp)
cmpl %edx, %esi
movl %esi, 0x68(%rsp)
jg 0xf524
movq 0x28(%rsp), %rax
leal (,%rax,8), %eax
movl %eax, 0x6c(%rsp)
movl %esi, %eax
movq %rax, 0x18(%rsp)
imull $0xaa8, %r15d, %esi     # imm = 0xAA8
subl 0x24(%rsp), %esi
addl $0x1bf9, %esi           # imm = 0x1BF9
movq %r13, %rdi
callq 0xfa14
testb $0x10, 0x21854(%r13)
je 0xf3e7
leal (,%r15,8), %ebx
xorl %r14d, %r14d
movzbl 0x208(%r13,%r14,4), %eax
cmpl %ebx, %eax
jg 0xf3de
movq %r13, %rdi
movl %r14d, %esi
callq 0xf61a
incq %r14
cmpq $0x40, %r14
jne 0xf3c6
movq %r15, 0x58(%rsp)
cmpl %ebp, 0x28(%rsp)
movq 0x50(%rsp), %rbx
movl %ebp, %r12d
jge 0xf502
movq 0x18(%rsp), %rcx
movslq %ecx, %rsi
imulq $-0x77777777, %rsi, %rdi # imm = 0x88888889
shrq $0x20, %rdi
addl %ecx, %edi
movl %edi, %eax
shrl $0x1f, %eax
sarl $0x4, %edi
addl %eax, %edi
movl %edi, %eax
shrl $0x1f, %eax
addl %edi, %eax
andl $-0x2, %eax
movl %edi, %r8d
subl %eax, %r8d
addl %r8d, %r8d
movl %r8d, 0x38(%rsp)
movl %edi, %eax
shll $0x5, %eax
addl %edi, %edi
subl %eax, %edi
addl %ecx, %edi
movq %rdi, 0x40(%rsp)
movl %edi, %eax
shll $0x5, %eax
movl %eax, 0x30(%rsp)
shll $0x3, %esi
movq %rsi, (%rsp)
movl 0x6c(%rsp), %r14d
movq 0x28(%rsp), %r15
leal 0x1f(%r15), %eax
testl %r15d, %r15d
cmovnsl %r15d, %eax
movl %eax, %ecx
shrl $0x1f, %ecx
movq %rbx, %rbp
movl %eax, %ebx
sarl $0x5, %ebx
addl %ebx, %ecx
andl $-0x2, %ecx
subl %ecx, %ebx
addl 0x38(%rsp), %ebx
andl $-0x20, %eax
movl %r15d, %r13d
subl %eax, %r13d
movq 0x10(%rsp), %rdi
movl %ebx, %esi
movl %r13d, %edx
movq 0x40(%rsp), %rcx
callq 0xf888
movslq %ebx, %rcx
movq %rbp, %rbx
movq 0x10(%rsp), %rdx
movq 0x16f0(%rdx,%rcx,8), %rcx
addl 0x30(%rsp), %r13d
movslq %r13d, %rdx
movq 0x10(%rsp), %r13
movzbl (%rcx,%rdx), %edx
movl 0x21850(%r13), %esi
shrl $0x4, %esi
andl $0x1, %esi
movq %r13, %rdi
movl %eax, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xe9de
movq %rbp, %rdi
movq %rax, %rsi
movl %r14d, %edx
movq (%rsp), %rcx
callq 0x1277e
incl %r15d
addl $0x8, %r14d
cmpl %r15d, %r12d
jne 0xf45f
movq 0x58(%rsp), %r15
incl %r15d
movq 0x18(%rsp), %rcx
leal 0x1(%rcx), %eax
cmpl 0xc(%rsp), %ecx
movq %rax, 0x18(%rsp)
movl %r12d, %ebp
jne 0xf398
movq 0x50(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x70(%rsp), %rdx
movl 0x4c(%rsp), %ecx
movl 0x64(%rsp), %ebx
movl %ebx, %r8d
callq 0x127ec
movq 0x200(%r13), %rax
testq %rax, %rax
movl 0x68(%rsp), %esi
je 0xf5b5
movl %ebx, %r12d
movq 0x1f0(%r13), %rbx
movl 0x10(%rbx), %ecx
leal 0x7(%rcx), %edx
testl %ecx, %ecx
cmovnsl %ecx, %edx
sarl $0x3, %edx
movq %rdx, 0x28(%rsp)
leal 0x100(%rcx), %edx
movq %rcx, 0x78(%rsp)
leal 0x107(%rcx), %ebp
testl %edx, %edx
movl %edx, 0x4c(%rsp)
cmovnsl %edx, %ebp
sarl $0x3, %ebp
incl %ebp
decq %rax
movq %rax, 0x200(%r13)
movq %rbx, %rdi
callq 0x4590
movq %rbx, %rdi
callq 0x4380
movl %r12d, %eax
movq %rax, 0x70(%rsp)
movl 0xc(%rsp), %esi
cmpq $0x0, 0x80(%rsp)
jne 0xf333
movq %r13, %rdi
movl $0x186a0, %esi          # imm = 0x186A0
callq 0xfa14
movq 0x10(%rsp), %rbx
testb $0x18, 0x21854(%rbx)
je 0xf5f4
leaq 0x8(%rbx), %rdi
movq 0x1750(%rbx), %rax
movzbl (%rax), %esi
xorl %edx, %edx
callq 0x12306
leaq 0x8(%rbx), %rdi
callq 0x12042
movzbl 0x21850(%rbx), %eax
shrl $0x7, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop