// File: mindbeast[P]rnes/ppu.cpp
// Function: Rnes::Ppu::tick()
void Ppu::tick() {
  uint32_t scanline = getScanline();
  uint32_t lineClock = getScanlineOffset();
  bool isVblank = scanline >= 240 and scanline <= 260;

  // Update vram registers
  if (!isVblank and renderBackgroundEnabled()) {
    if (lineClock == 255 and scanline < 240) {
      render(scanline);
      nes->notifyScanlineComplete();
    }
    if (lineClock == 256) {
      vramYInc();
    }
    if (lineClock == 257) {
      vramXReset();
    }
    if (scanline == 261 and lineClock >= 280 and lineClock <= 304) {
      vramYReset();
    }
  }

  // set and unset vblank register
  if (scanline == vblankScanline and lineClock == 0) {
    setVblankFlag();
    if (nmiOnVblank()) {
      nmiRequested = true;
    }
  } else if (scanline == vblankScanelineEnd and lineClock == 0) {
    clearVblankFlag();
    clearSprite0Hit();
    clearLostSprites();
  } else if (scanline == vblankScanelineEnd and lineClock == (ticksPerScanline - 1)) {
    sdl->renderSync();
    /*
    float currentTime = timerGetMs();
    float diffTime = currentTime - lastFrameTimeMs;
    if (diffTime < frameTimeMs) {
        float waitTime = frameTimeMs - diffTime;
        sleepMs(waitTime);
    }
    lastFrameTimeMs = timerGetMs();
    */
    frame += 1;
  }
  cycle += 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x20(%rbp)
callq 0x25310
movq -0x20(%rbp), %rdi
movzwl %ax, %eax
movl %eax, -0xc(%rbp)
callq 0x25340
movzwl %ax, %eax
movl %eax, -0x10(%rbp)
xorl %eax, %eax
cmpl $0xf0, -0xc(%rbp)
movb %al, -0x12(%rbp)
jb 0x23de9
cmpl $0x104, -0xc(%rbp)      # imm = 0x104
setbe %al
movb %al, -0x12(%rbp)
movb -0x12(%rbp), %al
andb $0x1, %al
movb %al, -0x11(%rbp)
testb $0x1, -0x11(%rbp)
jne 0x23e7f
movq -0x20(%rbp), %rdi
callq 0x24f80
testb $0x1, %al
jne 0x23e0a
jmp 0x23e7f
cmpl $0xff, -0x10(%rbp)
jne 0x23e35
cmpl $0xf0, -0xc(%rbp)
jae 0x23e35
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x24330
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x3c760
cmpl $0x100, -0x10(%rbp)     # imm = 0x100
jne 0x23e47
movq -0x20(%rbp), %rdi
callq 0x235d0
cmpl $0x101, -0x10(%rbp)     # imm = 0x101
jne 0x23e59
movq -0x20(%rbp), %rdi
callq 0x236a0
cmpl $0x105, -0xc(%rbp)      # imm = 0x105
jne 0x23e7d
cmpl $0x118, -0x10(%rbp)     # imm = 0x118
jb 0x23e7d
cmpl $0x130, -0x10(%rbp)     # imm = 0x130
ja 0x23e7d
movq -0x20(%rbp), %rdi
callq 0x236e0
jmp 0x23e7f
cmpl $0xf1, -0xc(%rbp)
jne 0x23eaf
cmpl $0x0, -0x10(%rbp)
jne 0x23eaf
movq -0x20(%rbp), %rdi
callq 0x25360
movq -0x20(%rbp), %rdi
callq 0x25380
testb $0x1, %al
jne 0x23ea6
jmp 0x23ead
movq -0x20(%rbp), %rax
movb $0x1, (%rax)
jmp 0x23f0e
cmpl $0x105, -0xc(%rbp)      # imm = 0x105
jne 0x23edb
cmpl $0x0, -0x10(%rbp)
jne 0x23edb
movq -0x20(%rbp), %rdi
callq 0x24f40
movq -0x20(%rbp), %rdi
callq 0x253a0
movq -0x20(%rbp), %rdi
callq 0x253c0
jmp 0x23f0c
cmpl $0x105, -0xc(%rbp)      # imm = 0x105
jne 0x23f0a
cmpl $0x154, -0x10(%rbp)     # imm = 0x154
jne 0x23f0a
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x417b0
movq -0x20(%rbp), %rax
movq 0x20(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x20(%rax)
jmp 0x23f0c
jmp 0x23f0e
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x18(%rax)
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)