// File: /workspace/github_cpp_makefile_star2_O3/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 0xc66f
movl %ebp, %edi
movq %rbx, %rsi
callq 0xe643
movq 0xd8ef(%rip), %r14      # 0x1c370
movq 0xd8f0(%rip), %rbx      # 0x1c378
cmpq %rbx, %r14
je 0xeaaa
addq $0x28, %r14
movq -0x28(%r14), %rdi
callq 0xf963
testb %al, %al
jne 0xeaaa
leaq 0x28(%r14), %rax
cmpq %rbx, %r14
movq %rax, %r14
jne 0xea91
callq 0x6b27
callq 0xbf51
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
testl %eax, %eax
jne 0xee14
callq 0xc2c9
testl %eax, %eax
jne 0xee14
callq 0xcab1
movb $0x1, 0xdd50(%rip)      # 0x1c82a
callq 0x9f6a
xorl %r15d, %r15d
movb %r15b, 0xdd41(%rip)     # 0x1c82a
callq 0xbadb
leaq 0x7(%rsp), %rdx
movb %r15b, (%rdx)
leaq -0x155(%rip), %rsi      # 0xe9a8
movl $0x10, %edi
callq 0x60c0
movq 0x8117da(%rip), %rdi    # 0x8202e8
callq 0x6460
movq %rax, 0x8(%rsp)
leaq 0x10(%rsp), %r14
leaq 0x78dc(%rip), %r12      # 0x16400
leaq 0xdd05(%rip), %rbx      # 0x1c830
xorl %ebp, %ebp
xorl %r13d, %r13d
movq 0xd929(%rip), %rax      # 0x1c460
movw %bp, 0x2fe(%rax)
movq %r14, %rdi
callq 0x6220
testl %eax, %eax
je 0xec9e
movl 0x10(%rsp), %eax
cmpl $0x300, %eax            # imm = 0x300
je 0xebd2
cmpl $0x100, %eax            # imm = 0x100
je 0xedd9
cmpl 0x8117ba(%rip), %eax    # 0x820324
jne 0xeb3e
movslq 0xd785(%rip), %rax      # 0x1c2f8
movl 0x80dcb7(%rip), %edx    # 0x81c830
leal 0x1(%rax), %ecx
andl $0x7ffff, %ecx          # imm = 0x7FFFF
cmpl %edx, %eax
jne 0xeb8e
movl %ecx, 0x80dca4(%rip)    # 0x81c830
movl %ecx, %edx
movslq %edx, %rdx
shlq $0x4, %rdx
movb %r15b, (%rdx,%rbx)
shlq $0x4, %rax
movb $0x1, (%rax,%rbx)
movl %ecx, 0xd751(%rip)      # 0x1c2f8
movb %r15b, 0xdb13(%rip)     # 0x1c6c1
callq 0x11706
leaq 0x812bc2(%rip), %rax    # 0x82177c
movb (%rax), %al
movb %al, 0x80dc76(%rip)     # 0x81c838
callq 0xbcdf
movl $0x22fb, %r13d          # imm = 0x22FB
jmp 0xeb3e
movl 0x24(%rsp), %eax
movl %eax, %ecx
shrl $0x16, %ecx
orl %eax, %ecx
andl $0x1ff, %ecx            # imm = 0x1FF
movb (%rcx,%r12), %cl
testb %cl, %cl
je 0xec35
movb %cl, 0xdad3(%rip)       # 0x1c6c4
movzwl 0x28(%rsp), %eax
testl $0x3c3, %eax            # imm = 0x3C3
je 0xeb3e
movzbl %cl, %edx
xorb $0x20, %cl
testb $0x3, %al
movzbl %cl, %ecx
cmovel %edx, %ecx
movl %ecx, %edx
xorb $0x60, %dl
testb $-0x40, %al
movzbl %dl, %edx
cmovel %ecx, %edx
leal -0x80(%rdx), %ecx
testl $0x300, %eax            # imm = 0x300
movzbl %cl, %eax
cmovel %edx, %eax
movb %al, 0xda94(%rip)       # 0x1c6c4
jmp 0xeb3e
addl $0xbfffffa8, %eax       # imm = 0xBFFFFFA8
cmpl $0xa, %eax
ja 0xeb3e
leaq 0x48a6(%rip), %rcx      # 0x134f0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
xorl %edi, %edi
jmp 0xec94
movl $0x3, %edi
jmp 0xec94
movl $0x8, %edi
jmp 0xec94
movl $0x1, %edi
jmp 0xec94
movl $0x2, %edi
jmp 0xec94
movl $0x6, %edi
jmp 0xec94
movl $0x4, %edi
jmp 0xec94
movl $0x5, %edi
jmp 0xec94
movl $0x9, %edi
jmp 0xec94
movl $0x7, %edi
callq 0x9187
jmp 0xeb3e
cmpl $0x23f, %ebp            # imm = 0x23F
jg 0xed0e
testl %r13d, %r13d
jne 0xed1b
movl %ebp, %edi
callq 0xcdd0
movb $0x1, 0xda07(%rip)      # 0x1c6c0
movb 0xda04(%rip), %al       # 0x1c6c3
movb %al, 0xd9fd(%rip)       # 0x1c6c2
movl $0x58, %edi
callq 0x1180d
movq 0x811622(%rip), %rsi    # 0x8202f8
movl %ebp, %edi
movq 0x8(%rsp), %rdx
callq 0xe911
movb $0x0, 0xd9d7(%rip)      # 0x1c6c0
movb 0xd9d4(%rip), %al       # 0x1c6c3
orb $0x2, %al
movb %al, 0xd9cb(%rip)       # 0x1c6c2
movl $0xc, %edi
callq 0x1180d
movb 0xd9bc(%rip), %al       # 0x1c6c3
orb $0x3, %al
jmp 0xedbf
cmpl $0x254, %ebp            # imm = 0x254
ja 0xed23
testl %r13d, %r13d
je 0xed51
decl %r13d
jmp 0xedd2
cmpb $0x1, 0x7(%rsp)
jne 0xed42
movb $0x0, 0x7(%rsp)
movq 0x8115b2(%rip), %rdi    # 0x8202e8
callq 0x63d0
xorl %ebp, %ebp
jmp 0xeb30
movl $0x1, %edi
callq 0x6290
jmp 0xeb30
movl %ebp, %edi
callq 0xcdd0
movb 0xd965(%rip), %al       # 0x1c6c3
cmpl $0x240, %ebp            # imm = 0x240
jne 0xed8d
orb $0x20, %al
movb %al, 0xd954(%rip)       # 0x1c6c2
movl $0x20, %edi
callq 0x1180d
movb 0xd945(%rip), %al       # 0x1c6c3
orb $0x30, %al
movb %al, 0xd93c(%rip)       # 0x1c6c2
movl $0x38, %edi
jmp 0xed9a
orb $0x30, %al
movb %al, 0xd92d(%rip)       # 0x1c6c2
movl $0x58, %edi
callq 0x1180d
movb 0xd91e(%rip), %al       # 0x1c6c3
orb $0x32, %al
movb %al, 0xd915(%rip)       # 0x1c6c2
movl $0xc, %edi
callq 0x1180d
movb 0xd906(%rip), %al       # 0x1c6c3
orb $0x33, %al
movb %al, 0xd8fd(%rip)       # 0x1c6c2
movl $0xc, %edi
callq 0x1180d
xorl %r13d, %r13d
incl %ebp
jmp 0xeb30
movl 0x811541(%rip), %edi    # 0x820320
callq 0x6170
movq 0x8114fd(%rip), %rdi    # 0x8202e8
callq 0x6030
movq 0x8114f9(%rip), %rdi    # 0x8202f0
callq 0x6320
callq 0x6070
movq 0xd658(%rip), %rdi      # 0x1c460
testq %rdi, %rdi
je 0xee12
callq 0x6450
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop