// File: /workspace/github_cpp_makefile_star2_O1/mdpkh[P]retro6k/src/main.cpp
// Function: main
int main(int argc, char** argv)
{
	if (int rv = InitPaths())
		return rv;
	if (int rv = ReadArgs(argc, argv))
		return rv;
	LoadConfig();
	CollapsePaths();
	if (int rv = InitMainWindow())
		return rv;
	if (int rv = InitMemory())
		return rv;
	if (int rv = InitSound())
		return rv;
	menuhassound = true;
	PickAndInsertCartridge();
	menuhassound = false;
	if (int rv = InitEmulator())
		return rv;
	int resetcounter = 0;
	int scanline = 0;
	bool nextframe = false;
	SDL_TimerID frame_timer_id = SDL_AddTimer(16, SetBool, &nextframe);
	SDL_Surface* mwsurface = SDL_GetWindowSurface(mainwindow);
	while (true)
	{
		sysram[0x02fe] = scanline;
		sysram[0x02ff] = scanline >> 8;
		SDL_Event event;
		while (SDL_PollEvent(&event))
		{
			unsigned char inkey;
			switch (event.type)
			{
			case SDL_KEYDOWN:
				if (inkey = keytrans[(event.key.keysym.sym | (event.key.keysym.sym >> 22)) & 0x1ff])
				{
					keypressregister = inkey;
					if (event.key.keysym.mod & KMOD_SHIFT)
						keypressregister ^= 0x20;
					if (event.key.keysym.mod & KMOD_CTRL)
						keypressregister ^= 0x60;
					if (event.key.keysym.mod & KMOD_ALT)
						keypressregister ^= 0x80;
					break;
				}
				switch (event.key.keysym.sym)
				{
				case SDLK_KP_ENTER:
				case SDLK_KP_0:
					DoMenu(0);
					break;
				case SDLK_KP_1:
					DoMenu(1);
					break;
				case SDLK_KP_2:
					DoMenu(2);
					break;
				case SDLK_KP_3:
					DoMenu(3);
					break;
				case SDLK_KP_4:
					DoMenu(4);
					break;
				case SDLK_KP_5:
					DoMenu(5);
					break;
				case SDLK_KP_6:
					DoMenu(6);
					break;
				case SDLK_KP_7:
					DoMenu(7);
					break;
				case SDLK_KP_8:
					DoMenu(8);
					break;
				case SDLK_KP_9:
					DoMenu(9);
					break;
				}
				break;
			case SDL_QUIT:
				goto cleanup;
			default:
				if (event.type == UE_RESETCPU)
				{
					LogReset();
					reset6502();
					stackbase = GetSP();
					resetcounter = 8955;
					LogStep();
				}
			}
		}
		// 6502 clocked at 4MHz, pixel clock at 34.96MHz)
		if (scanline < 576)
		{
			if (!resetcounter)
			{
				LogScanline(scanline);
				videobusy = true;
				videostate = 0x00 | videomode;
				// run 6502 for 21.967963386728 microseconds (768 pixel ticks, 88 cpu cycles)
				exec6502(88);
				RenderScanline(scanline, framebuffer, mwsurface);
				videobusy = false;
				videostate = 0x02 | videomode;
				// run 6502 for 5.949656750572 microseconds (208 pixel ticks, 24 cpu cycles)
				exec6502(12);
				videostate = 0x03 | videomode;
				exec6502(12);
			}
			else
				--resetcounter;
			++scanline;
		}
		else if (scanline < 597)
		{
			// TODO: issue IRQ if video interrupt condition is met
			if (!resetcounter)
			{
				// run 6502 for 27.9176201373 microseconds (976 pixel ticks, 112 cpu cycles)
				LogScanline(scanline);
				if (scanline == 576)
				{
					videostate = 0x20 | videomode;
					exec6502(32);
					videostate = 0x30 | videomode;
					exec6502(56);
					videostate = 0x32 | videomode;
					exec6502(12);
					videostate = 0x33 | videomode;
					exec6502(12);
				}
				else {
					videostate = 0x30 | videomode;
					exec6502(88);
					videostate = 0x32 | videomode;
					exec6502(12);
					videostate = 0x33 | videomode;
					exec6502(12);
				}
			}
			else
				--resetcounter;
			++scanline;
		}
		else if (nextframe)
		{
			scanline = 0;
			nextframe = false;
			SDL_UpdateWindowSurface(mainwindow);
			//RandomBitFlip();
		}
		else
		{
			SDL_Delay(1);
		}
	}
	SDL_RemoveTimer(frame_timer_id);
cleanup:
	SDL_CloseAudioDevice(sounddev);
	SDL_DestroyWindow(mainwindow);
	SDL_FreeSurface(cellcanvas);
	SDL_Quit();
	delete[] sysram;
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, %rbx
movl %edi, %ebp
callq 0xc02a
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe011
movq 0xdeca(%rip), %r14      # 0x1c370
movq 0xdecb(%rip), %rbx      # 0x1c378
cmpq %rbx, %r14
je 0xe4cf
addq $0x28, %r14
movq -0x28(%r14), %rdi
callq 0xf37b
testb %al, %al
jne 0xe4cf
leaq 0x28(%r14), %rax
cmpq %rbx, %r14
movq %rax, %r14
jne 0xe4b6
callq 0x6b27
callq 0xb8f6
xorl %ebp, %ebp
testl %eax, %eax
setne %bpl
negl %ebp
testl %eax, %eax
jne 0xe834
callq 0xbc86
xorl %ebx, %ebx
movl %eax, %ecx
negl %ecx
movl $0x0, %ecx
sbbl %ecx, %ecx
orl %ebp, %ecx
testl %eax, %eax
je 0xe50a
movl %ecx, %ebp
jmp 0xe834
movl %ecx, 0x4(%rsp)
callq 0xc46c
movb $0x1, 0xe310(%rip)      # 0x1c82a
callq 0x991e
movb %bl, 0xe305(%rip)       # 0x1c82a
callq 0xb461
leaq 0x3(%rsp), %rdx
movb %bl, (%rdx)
leaq -0x16b(%rip), %rsi      # 0xe3cd
movl $0x10, %edi
callq 0x60c0
movq 0x811d9f(%rip), %rdi    # 0x8202e8
callq 0x6460
movq %rax, 0x8(%rsp)
leaq 0x10(%rsp), %r15
leaq 0x7d51(%rip), %r13      # 0x162b0
xorl %r12d, %r12d
movq 0xdef7(%rip), %rax      # 0x1c460
movw %bx, 0x2fe(%rax)
movq %r15, %rdi
callq 0x6220
testl %eax, %eax
je 0xe6ab
movl 0x10(%rsp), %eax
cmpl $0x100, %eax            # imm = 0x100
je 0xe5ef
cmpl $0x300, %eax            # imm = 0x300
jne 0xe5fc
movl 0x24(%rsp), %eax
movl %eax, %ecx
shrl $0x16, %ecx
orl %eax, %ecx
andl $0x1ff, %ecx            # imm = 0x1FF
movb (%rcx,%r13), %cl
testb %cl, %cl
je 0xe634
movb %cl, 0xe10f(%rip)       # 0x1c6c4
movzwl 0x28(%rsp), %eax
testb $0x3, %al
je 0xe5c7
xorb $0x20, %cl
movb %cl, 0xe0fd(%rip)       # 0x1c6c4
testb $-0x40, %al
je 0xe5d2
xorb $0x60, 0xe0f2(%rip)     # 0x1c6c4
xorl %r14d, %r14d
movb $0x1, %bpl
testl $0x300, %eax            # imm = 0x300
je 0xe69d
xorb $-0x80, 0xe0da(%rip)    # 0x1c6c4
jmp 0xe69d
movl $0x8, %r14d
xorl %ebp, %ebp
jmp 0xe69d
xorl %r14d, %r14d
movb $0x1, %bpl
cmpl 0x811d1c(%rip), %eax    # 0x820324
jne 0xe69d
callq 0xc760
callq 0x11166
leaq 0x81315d(%rip), %rax    # 0x82177c
movb (%rax), %al
movb %al, 0x80e211(%rip)     # 0x81c838
callq 0xb665
movl $0x22fb, %r12d          # imm = 0x22FB
jmp 0xe69d
xorl %r14d, %r14d
movb $0x1, %bpl
addl $0xbfffffa8, %eax       # imm = 0xBFFFFFA8
cmpl $0xa, %eax
ja 0xe69d
leaq 0x4d4d(%rip), %rcx      # 0x13398
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %r14d, %r14d
xorl %edi, %edi
jmp 0xe698
movl $0x3, %edi
jmp 0xe698
movl $0x8, %edi
jmp 0xe698
movl $0x1, %edi
jmp 0xe698
movl $0x2, %edi
jmp 0xe698
movl $0x6, %edi
jmp 0xe698
movl $0x4, %edi
jmp 0xe698
movl $0x5, %edi
jmp 0xe698
movl $0x9, %edi
jmp 0xe698
movl $0x7, %edi
callq 0x8a97
testb %bpl, %bpl
jne 0xe570
jmp 0xe7e4
cmpl $0x23f, %ebx            # imm = 0x23F
jg 0xe71b
testl %r12d, %r12d
jne 0xe728
movl %ebx, %edi
callq 0xc7b7
movb $0x1, 0xdffa(%rip)      # 0x1c6c0
movb 0xdff7(%rip), %al       # 0x1c6c3
movb %al, 0xdff0(%rip)       # 0x1c6c2
movl $0x58, %edi
callq 0x1126d
movq 0x811c15(%rip), %rsi    # 0x8202f8
movl %ebx, %edi
movq 0x8(%rsp), %rdx
callq 0xe336
movb $0x0, 0xdfca(%rip)      # 0x1c6c0
movb 0xdfc7(%rip), %al       # 0x1c6c3
orb $0x2, %al
movb %al, 0xdfbe(%rip)       # 0x1c6c2
movl $0xc, %edi
callq 0x1126d
movb 0xdfaf(%rip), %al       # 0x1c6c3
orb $0x3, %al
jmp 0xe7cc
cmpl $0x254, %ebx            # imm = 0x254
jg 0xe730
testl %r12d, %r12d
je 0xe75e
decl %r12d
jmp 0xe7df
cmpb $0x1, 0x3(%rsp)
jne 0xe74f
movb $0x0, 0x3(%rsp)
movq 0x811ba5(%rip), %rdi    # 0x8202e8
callq 0x63d0
xorl %ebx, %ebx
jmp 0xe7e1
movl $0x1, %edi
callq 0x6290
jmp 0xe7e1
movl %ebx, %edi
callq 0xc7b7
movb 0xdf58(%rip), %al       # 0x1c6c3
cmpl $0x240, %ebx            # imm = 0x240
jne 0xe79a
orb $0x20, %al
movb %al, 0xdf47(%rip)       # 0x1c6c2
movl $0x20, %edi
callq 0x1126d
movb 0xdf38(%rip), %al       # 0x1c6c3
orb $0x30, %al
movb %al, 0xdf2f(%rip)       # 0x1c6c2
movl $0x38, %edi
jmp 0xe7a7
orb $0x30, %al
movb %al, 0xdf20(%rip)       # 0x1c6c2
movl $0x58, %edi
callq 0x1126d
movb 0xdf11(%rip), %al       # 0x1c6c3
orb $0x32, %al
movb %al, 0xdf08(%rip)       # 0x1c6c2
movl $0xc, %edi
callq 0x1126d
movb 0xdef9(%rip), %al       # 0x1c6c3
orb $0x33, %al
movb %al, 0xdef0(%rip)       # 0x1c6c2
movl $0xc, %edi
callq 0x1126d
xorl %r12d, %r12d
incl %ebx
xorl %r14d, %r14d
testl %r14d, %r14d
je 0xe562
cmpl $0x8, %r14d
jne 0xe830
movl 0x811b27(%rip), %edi    # 0x820320
callq 0x6170
movq 0x811ae3(%rip), %rdi    # 0x8202e8
callq 0x6030
movq 0x811adf(%rip), %rdi    # 0x8202f0
callq 0x6320
callq 0x6070
movq 0xdc3e(%rip), %rdi      # 0x1c460
xorl %ebp, %ebp
testq %rdi, %rdi
je 0xe834
callq 0x6450
jmp 0xe834
movl 0x4(%rsp), %ebp
movl %ebp, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop