// File: /workspace/github_cpp_makefile_star2_O2/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 $0x78, %rsp
movq %rdi, (%rsp)
movq (%rdi), %rdi
callq 0x8f3e
movl %eax, %ebp
testb $0x1, %bpl
je 0xd51b
movq (%rsp), %rdi
xorl %esi, %esi
callq 0xc6b0
testb $0x2, %bpl
je 0xd52d
pushq $0x1
popq %rsi
movq (%rsp), %rdi
callq 0xc6b0
movq (%rsp), %rcx
movl 0x6e8(%rcx), %eax
addq %rax, 0x1d8(%rcx)
movl 0x2185c(%rcx), %edx
incl %edx
movl %edx, %eax
movl %edx, 0x2185c(%rcx)
cmpb $0x0, 0x6e4(%rcx)
je 0xd560
movb $0x0, 0x6e4(%rcx)
jmp 0xd567
movb $0x0, 0x6e3(%rcx)
movl %eax, %edx
andl $0x1, %edx
movl $0x15cfe, %eax          # imm = 0x15CFE
movl %edx, 0x64(%rsp)
subl %edx, %eax
movl %eax, 0x6e8(%rcx)
cmpb $0x1, 0x21860(%rcx)
jne 0xd5a3
pushq $0x3f
popq %rbp
testl %ebp, %ebp
js 0xd7fb
movq %rcx, %rdi
movl %ebp, %esi
callq 0xdabc
movq (%rsp), %rcx
decl %ebp
jmp 0xd589
testb $0x8, 0x21854(%rcx)
je 0xda74
movl 0x1e8(%rcx), %edi
movl 0x1ec(%rcx), %eax
pushq $0x8
popq %rsi
movl %eax, 0x3c(%rsp)
cltd
idivl %esi
movl %eax, 0x38(%rsp)
leaq 0x1f0(%rcx), %rax
movq %rax, 0x68(%rsp)
leaq 0x8(%rcx), %rax
movq %rax, 0x28(%rsp)
movb $0x1, %cl
xorl %r15d, %r15d
leal 0x100(%rdi), %eax
movl %eax, 0x54(%rsp)
cltd
idivl %esi
movl %eax, 0x30(%rsp)
movq %rdi, 0x70(%rsp)
movl %edi, %eax
cltd
idivl %esi
movl %eax, 0x60(%rsp)
shll $0x3, %eax
movl %eax, 0x5c(%rsp)
movq (%rsp), %rdi
testb $0x1, %cl
je 0xda66
cmpq $0x0, 0x200(%rdi)
setne %al
movb %al, 0xf(%rsp)
je 0xd635
movq 0x68(%rsp), %rax
movq (%rax), %rax
movl 0x14(%rax), %eax
jmp 0xd63a
movl $0xf0, %eax
addl 0x1ec(%rdi), %eax
movl %eax, 0x58(%rsp)
cltd
idivl %esi
movl %eax, 0x14(%rsp)
movl 0x38(%rsp), %eax
movl %eax, %r12d
cmpl 0x14(%rsp), %r12d
jg 0xd797
imull $0xaa8, %r15d, %esi     # imm = 0xAA8
subl 0x64(%rsp), %esi
addl $0x1bf9, %esi           # imm = 0x1BF9
movq (%rsp), %rbx
movq %rbx, %rdi
callq 0xde5e
testb $0x10, 0x21854(%rbx)
jne 0xd761
movq %r15, 0x48(%rsp)
movl %r12d, %eax
cltd
pushq $0x1e
popq %rcx
idivl %ecx
movl %edx, %r15d
cltd
pushq $0x2
popq %rcx
idivl %ecx
addl %edx, %edx
movl %edx, 0x18(%rsp)
movl %r15d, 0x20(%rsp)
shll $0x5, %r15d
movq %r12, 0x40(%rsp)
leal (,%r12,8), %eax
movl %eax, 0x10(%rsp)
movl 0x5c(%rsp), %r12d
movl 0x60(%rsp), %r13d
cmpl 0x30(%rsp), %r13d
jg 0xd74c
movl %r13d, %eax
cltd
pushq $0x20
popq %rcx
idivl %ecx
movl %edx, %ebx
cltd
pushq $0x2
popq %rcx
idivl %ecx
movl %edx, %ebp
addl 0x18(%rsp), %ebp
movq (%rsp), %r14
movq %r14, %rdi
movl %ebp, %esi
movl %ebx, %edx
movl 0x20(%rsp), %ecx
callq 0xdd2a
movslq %ebp, %rcx
movq 0x16f0(%r14,%rcx,8), %rcx
addl %r15d, %ebx
movslq %ebx, %rdx
movzbl (%rcx,%rdx), %edx
movl 0x21850(%r14), %esi
shrl $0x4, %esi
andl $0x1, %esi
movq %r14, %rdi
movl %eax, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0xcf7a
movq 0x28(%rsp), %rdi
movq %rax, %rsi
movl %r12d, %edx
movl 0x10(%rsp), %ecx
callq 0x105c8
incl %r13d
addl $0x8, %r12d
jmp 0xd6c8
movq 0x48(%rsp), %r15
incl %r15d
movq 0x40(%rsp), %r12
incl %r12d
jmp 0xd652
movq %rbx, %rdi
leal (,%r15,8), %ebx
xorl %r14d, %r14d
cmpq $0x40, %r14
je 0xd687
movzbl 0x208(%rdi,%r14,4), %eax
cmpl %ebx, %eax
jg 0xd792
movl %r14d, %esi
callq 0xdabc
movq (%rsp), %rdi
incq %r14
jmp 0xd76f
movq 0x28(%rsp), %rdi
movq 0x70(%rsp), %rsi
movl 0x3c(%rsp), %edx
movl 0x54(%rsp), %ecx
movl 0x58(%rsp), %r14d
movl %r14d, %r8d
callq 0x10634
movq (%rsp), %rdi
cmpq $0x0, 0x200(%rdi)
pushq $0x8
popq %rsi
movb 0xf(%rsp), %cl
je 0xd60e
movq 0x68(%rsp), %rdi
movq (%rdi), %rax
movl 0x10(%rax), %ebx
movl %ecx, %ebp
callq 0xe0b4
movl %ebp, %ecx
movq %rbx, %rdi
pushq $0x8
popq %rsi
movl %r14d, 0x3c(%rsp)
movl 0x14(%rsp), %eax
movl %eax, 0x38(%rsp)
jmp 0xd5e4
leaq 0x8(%rcx), %rax
movq %rax, 0x30(%rsp)
pushq $0x10
popq %rax
xorl %r12d, %r12d
movl %eax, 0x18(%rsp)
movq (%rsp), %r15
movq 0x30(%rsp), %r14
cmpq $0x10, %r12
je 0xd89b
movq %r12, %rax
orq $0x10, %rax
movq %rax, 0x20(%rsp)
movl %r12d, %ebp
shll $0x4, %ebp
cmpl 0x18(%rsp), %ebp
je 0xd88a
xorl %r13d, %r13d
pushq $0x10
popq %rbx
subl $0x1, %ebx
jb 0xd886
movl %r13d, %edx
orl $0x1e0, %edx            # imm = 0x1E0
movq 0x1750(%r15,%r12,8), %rax
movzbl (%rax), %ecx
movq %r14, %rdi
movl %ebp, %esi
callq 0x10482
movl %r13d, %edx
orl $0x1f0, %edx            # imm = 0x1F0
movq 0x20(%rsp), %rax
movq 0x1750(%r15,%rax,8), %rax
movzbl (%rax), %ecx
movq %r14, %rdi
movl %ebp, %esi
callq 0x10482
incl %r13d
jmp 0xd83b
incl %ebp
jmp 0xd82f
incq %r12
addl $0x10, 0x18(%rsp)
movq (%rsp), %rcx
jmp 0xd817
xorl %esi, %esi
movq (%rsp), %r14
cmpq $0x4, %rsi
je 0xd98c
leal -0x1(%rsi), %eax
movq %rax, 0x20(%rsp)
xorl %edx, %edx
movq %rsi, 0x28(%rsp)
cmpq $0x20, %rdx
je 0xd984
leal (,%rdx,8), %eax
movl %eax, 0x10(%rsp)
xorl %r13d, %r13d
xorl %ebx, %ebx
movq %rdx, 0x18(%rsp)
cmpq $0xf0, %rbx
je 0xd97c
movq 0x16f0(%rcx,%rsi,8), %rax
addq %rdx, %rax
movzbl (%rax,%rbx,4), %r15d
movq %rcx, %rdi
movl %r13d, %ecx
callq 0xdd2a
xorl %ebp, %ebp
movl $0x0, %r12d
cmpl $0x2, 0x20(%rsp)
ja 0xd92a
leaq 0x5bd9(%rip), %rcx      # 0x134f0
movq 0x20(%rsp), %rdx
movl (%rcx,%rdx,4), %ebp
leaq 0x5bd6(%rip), %rcx      # 0x134fc
movl (%rcx,%rdx,4), %r12d
orl 0x10(%rsp), %r12d
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 0xcf7a
addl %ebx, %ebp
movq 0x30(%rsp), %rdi
movq %rax, %rsi
movl %r12d, %edx
movl %ebp, %ecx
callq 0x105c8
movq %r14, %rcx
addq $0x8, %rbx
incl %r13d
movq 0x28(%rsp), %rsi
movq 0x18(%rsp), %rdx
jmp 0xd8d9
incq %rdx
jmp 0xd8ba
incq %rsi
jmp 0xd8a1
xorl %eax, %eax
cmpl $0x2, %eax
je 0xda74
movl %eax, %edx
shll $0x7, %edx
movq %rdx, 0x40(%rsp)
movl %eax, %edx
shll $0x8, %edx
movl %edx, 0x14(%rsp)
xorl %edx, %edx
movl %eax, 0x48(%rsp)
cmpl $0x10, %edx
je 0xda5f
movq 0x40(%rsp), %rax
leal (%rax,%rdx,8), %eax
movl %eax, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
movl %edx, %eax
shll $0x4, %eax
orl 0x14(%rsp), %eax
movl %eax, 0x10(%rsp)
xorl %ebp, %ebp
movl $0x300, %r14d           # imm = 0x300
cmpl $0x10, %ebp
je 0xda4f
movl %ebp, 0x18(%rsp)
orl 0x10(%rsp), %ebp
xorl %r15d, %r15d
cmpl $0x8, %r15d
je 0xda43
movl %r15d, %r12d
orl 0x20(%rsp), %r12d
xorl %r13d, %r13d
cmpl $0x8, %r13d
je 0xda3e
leal (%r14,%r13), %ebx
movq %rcx, %rdi
movl %ebp, %esi
movl %r13d, %edx
movl %r15d, %ecx
callq 0xdd86
cltq
leaq 0x5a9d(%rip), %rcx      # 0x134c0
movl (%rcx,%rax,4), %ecx
movq 0x30(%rsp), %rdi
movl %ebx, %esi
movl %r12d, %edx
callq 0x10482
movq (%rsp), %rcx
incl %r13d
jmp 0xda00
incl %r15d
jmp 0xd9ef
movl 0x18(%rsp), %ebp
incl %ebp
addl $0x8, %r14d
jmp 0xd9df
movq 0x28(%rsp), %rdx
incl %edx
movl 0x48(%rsp), %eax
jmp 0xd9b0
incl %eax
jmp 0xd98e
movl $0x186a0, %esi          # imm = 0x186A0
callq 0xde5e
movq (%rsp), %rcx
testb $0x18, 0x21854(%rcx)
je 0xda96
leaq 0x8(%rcx), %rdi
movq 0x1750(%rcx), %rax
movzbl (%rax), %esi
xorl %edx, %edx
callq 0x101a0
movq (%rsp), %rcx
leaq 0x8(%rcx), %rdi
movq %rcx, %rbx
callq 0xff54
movzbl 0x21850(%rbx), %eax
shrl $0x7, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop