// File: /workspace/github_cpp_makefile_star2_O2/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 0xafc0
movl %ebp, %edi
movq %rbx, %rsi
callq 0xc8ef
callq 0xb42f
callq 0x6837
callq 0xa9a8
pushq $-0x1
popq %rbx
testl %eax, %eax
jne 0xcf94
callq 0xacb6
testl %eax, %eax
jne 0xcf94
callq 0xb3b4
movb $0x1, 0xebba(%rip)      # 0x1b83a
callq 0x9035
xorl %ebx, %ebx
movb %bl, 0xebad(%rip)       # 0x1b83a
callq 0xa788
leaq 0x7(%rsp), %rdx
movb %bl, (%rdx)
leaq -0x9a(%rip), %rsi       # 0xcc06
pushq $0x10
popq %rdi
callq 0x60d0
movq 0x812649(%rip), %rdi    # 0x81f2f8
callq 0x6470
movq %rax, 0x8(%rsp)
leaq 0x10(%rsp), %r15
leaq 0x766b(%rip), %rbp      # 0x14330
leaq 0x4754(%rip), %r12      # 0x11420
leaq 0x813ab9(%rip), %r13    # 0x82078c
xorl %r14d, %r14d
movq 0xe793(%rip), %rax      # 0x1b470
movw %bx, 0x2fe(%rax)
movq %r15, %rdi
callq 0x6240
testl %eax, %eax
je 0xce27
movl 0x10(%rsp), %eax
cmpl $0x300, %eax            # imm = 0x300
je 0xcd33
cmpl $0x100, %eax            # imm = 0x100
je 0xcf59
cmpl 0x812624(%rip), %eax    # 0x81f334
jne 0xcce4
callq 0xb5f3
callq 0xf95e
movb (%r13), %al
movb %al, 0x80eb22(%rip)     # 0x81b848
callq 0xa815
movl $0x22fb, %r14d          # imm = 0x22FB
jmp 0xcce4
movl 0x24(%rsp), %eax
movl %eax, %ecx
shrl $0x16, %ecx
orl %eax, %ecx
andl $0x1ff, %ecx            # imm = 0x1FF
movb (%rcx,%rbp), %cl
testb %cl, %cl
je 0xcd8f
movb %cl, 0xe983(%rip)       # 0x1b6d4
movzwl 0x28(%rsp), %eax
testw $0x3c3, %ax             # imm = 0x3C3
je 0xcce4
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
testw $0x300, %ax             # imm = 0x300
movzbl %cl, %eax
cmovel %edx, %eax
movb %al, 0xe94a(%rip)       # 0x1b6d4
jmp 0xcce4
addl $0xbfffffa8, %eax       # imm = 0xBFFFFFA8
cmpl $0xa, %eax
ja 0xcce4
movslq (%r12,%rax,4), %rax
addq %r12, %rax
jmpq *%rax
xorl %edi, %edi
callq 0x8347
jmp 0xcce4
pushq $0x3
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x8
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x1
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x2
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x6
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x4
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x5
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x9
popq %rdi
callq 0x8347
jmp 0xcce4
pushq $0x7
popq %rdi
callq 0x8347
jmp 0xcce4
cmpl $0x23f, %ebx            # imm = 0x23F
jg 0xce97
testl %r14d, %r14d
jne 0xcea4
movl %ebx, %edi
callq 0xb605
movb $0x1, 0xe88e(%rip)      # 0x1b6d0
movb 0xe88b(%rip), %al       # 0x1b6d3
movb %al, 0xe884(%rip)       # 0x1b6d2
pushq $0x58
popq %rdi
callq 0xfa39
movq 0x8124ab(%rip), %rsi    # 0x81f308
movl %ebx, %edi
movq 0x8(%rsp), %rdx
callq 0xcb92
movb $0x0, 0xe860(%rip)      # 0x1b6d0
movb 0xe85d(%rip), %al       # 0x1b6d3
orb $0x2, %al
movb %al, 0xe854(%rip)       # 0x1b6d2
pushq $0xc
popq %r14
movl %r14d, %edi
callq 0xfa39
movb 0xe843(%rip), %al       # 0x1b6d3
orb $0x3, %al
jmp 0xcf41
cmpl $0x254, %ebx            # imm = 0x254
ja 0xceac
testl %r14d, %r14d
je 0xced8
decl %r14d
jmp 0xcf52
cmpb $0x1, 0x7(%rsp)
jne 0xcecb
movb $0x0, 0x7(%rsp)
movq 0x812439(%rip), %rdi    # 0x81f2f8
callq 0x63d0
xorl %ebx, %ebx
jmp 0xccd6
pushq $0x1
popq %rdi
callq 0x62b0
jmp 0xccd6
movl %ebx, %edi
callq 0xb605
movb 0xe7ee(%rip), %al       # 0x1b6d3
cmpl $0x240, %ebx            # imm = 0x240
jne 0xcf0f
orb $0x20, %al
movb %al, 0xe7dd(%rip)       # 0x1b6d2
pushq $0x20
popq %rdi
callq 0xfa39
movb 0xe7d0(%rip), %al       # 0x1b6d3
orb $0x30, %al
movb %al, 0xe7c7(%rip)       # 0x1b6d2
pushq $0x38
jmp 0xcf19
orb $0x30, %al
movb %al, 0xe7bb(%rip)       # 0x1b6d2
pushq $0x58
popq %rdi
callq 0xfa39
movb 0xe7ae(%rip), %al       # 0x1b6d3
orb $0x32, %al
movb %al, 0xe7a5(%rip)       # 0x1b6d2
pushq $0xc
popq %r14
movl %r14d, %edi
callq 0xfa39
movb 0xe794(%rip), %al       # 0x1b6d3
orb $0x33, %al
movb %al, 0xe78b(%rip)       # 0x1b6d2
movl %r14d, %edi
callq 0xfa39
xorl %r14d, %r14d
incl %ebx
jmp 0xccd6
movl 0x8123d1(%rip), %edi    # 0x81f330
callq 0x6170
movq 0x81238d(%rip), %rdi    # 0x81f2f8
callq 0x6030
movq 0x812389(%rip), %rdi    # 0x81f300
callq 0x6340
callq 0x6070
movq 0xe4e8(%rip), %rdi      # 0x1b470
testq %rdi, %rdi
je 0xcf92
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