// File: /workspace/github_c_makefile_star2_O1/j-hoppe[P]tu58fs/main.c
// Function: run_emulator
void run_emulator(void) {
	// a sanity check for blocksize definition
	if (TU58_BLOCKSIZE % TU_DATA_LEN != 0)
		fatal("illegal BLOCKSIZE (%d) / TU_DATA_LEN (%d) ratio", TU58_BLOCKSIZE,
		TU_DATA_LEN);

	// say hello
	info("TU58 emulation start");
#ifdef DEVICEDIALOG
	info("0-7 device dialog, R restart, S toggle send init, V toggle verbose, D toggle debug, Q quit");
#else
	info("R restart, S toggle send init, V toggle verbose, D toggle debug, Q quit");
#endif

	// run the emulator
	if (pthread_create(&th_run, NULL, tu58_server, NULL))
		error("unable to create emulation thread");

	// run the monitor
	if (pthread_create(&th_monitor, NULL, tu58_monitor, NULL))
		error("unable to create monitor thread");

	// loop on user input
	for (;;) {
		uint8_t c;

		// get char from stdin (if available)
		if ((c = toupper(conget())) > 0) {
#ifdef DEVICEDIALOG
			if (c >= '0' && c <= '7') {
				image_t *img = NULL;
				int unit = c - '0';
				// number of open device?
				if (IMAGE_UNIT_VALID(unit))
				img = tu58image_get(unit);
				if (img && img->open)
				device_dialog(img);
			}
#endif
			if (c == 'V') {
				// toggle verbosity
				opt_verbose ^= 1;
				opt_debug = 0;
				info("verbosity set to %s; debug %s", opt_verbose ? "ON" : "OFF",
						opt_debug ? "ON" : "OFF");
			} else if (c == 'D') {
				// toggle debug
				opt_verbose = 1;
				opt_debug ^= 1;
				info("verbosity set to %s; debug %s", opt_verbose ? "ON" : "OFF",
						opt_debug ? "ON" : "OFF");
			} else if (c == 'S') {
				// toggle sending init string
				tu58_doinit = (tu58_doinit + 1) % 2;
				if (opt_debug)
					fprintf(ferr, "\n");
				info("send of <INIT> %sabled", tu58_doinit ? "en" : "dis");
			} else if (c == 'R') {
				// kill and restart the emulator
				if (pthread_cancel(th_run))
					error("unable to cancel emulation thread");
				if (pthread_join(th_run, NULL))
					error("unable to join on emulation thread");
				if (pthread_create(&th_run, NULL, tu58_server, NULL))
					error("unable to restart emulation thread");
			} else if (c == 'Q') {
				// kill the emulator and exit
				if (pthread_cancel(th_monitor))
					error("unable to cancel monitor thread");
				if (pthread_cancel(th_run))
					error("unable to cancel emulation thread");
				break;
			}
		}

		// wait a bit
		delay_ms(25);

	} // for (;;)

	// wait for emulator to finish
	if (pthread_join(th_run, NULL))
		error("unable to join on emulation thread");

	// all done
	info("TU58 emulation end");
	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
leaq 0xe84a(%rip), %rdi      # 0x12113
xorl %eax, %eax
callq 0xa127
leaq 0xe851(%rip), %rdi      # 0x12128
xorl %eax, %eax
callq 0xa127
leaq 0x1a383(%rip), %rdi     # 0x1dc68
leaq 0x2f5b(%rip), %rdx      # 0x6847
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3450
testl %eax, %eax
je 0x3907
leaq 0xe870(%rip), %rdi      # 0x12170
xorl %eax, %eax
callq 0xa054
leaq 0x1a362(%rip), %rdi     # 0x1dc70
leaq 0x3d9d(%rip), %rdx      # 0x76b2
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3450
testl %eax, %eax
je 0x3930
leaq 0xe869(%rip), %rdi      # 0x12192
xorl %eax, %eax
callq 0xa054
leaq 0xe899(%rip), %rbx      # 0x121d0
leaq 0x12ccf(%rip), %r14     # 0x1660d
leaq 0xe86d(%rip), %r15      # 0x121b2
leaq 0xe6b8(%rip), %r12      # 0x12004
leaq 0x1a52e(%rip), %r13     # 0x1de81
leaq 0xe87a(%rip), %rbp      # 0x121d4
callq 0x8b42
movl %eax, %edi
callq 0x30f0
movzbl %al, %eax
leal -0x51(%rax), %ecx
cmpl $0x5, %ecx
ja 0x39ea
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movq 0x1a2e7(%rip), %rdi     # 0x1dc68
callq 0x3590
testl %eax, %eax
je 0x3998
leaq 0xe85e(%rip), %rdi      # 0x121ef
xorl %eax, %eax
callq 0xa054
movq 0x1a2c9(%rip), %rdi     # 0x1dc68
xorl %esi, %esi
callq 0x3570
testl %eax, %eax
je 0x39b8
leaq 0xe860(%rip), %rdi      # 0x12211
xorl %eax, %eax
callq 0xa054
leaq 0x1a2a9(%rip), %rdi     # 0x1dc68
xorl %esi, %esi
leaq 0x2e7f(%rip), %rdx      # 0x6847
xorl %ecx, %ecx
callq 0x3450
testl %eax, %eax
je 0x3a9e
leaq 0xe856(%rip), %rdi      # 0x12234
xorl %eax, %eax
callq 0xa054
jmp 0x3a9e
cmpl $0x44, %eax
jne 0x3a9e
movl $0x1, 0x19077(%rip)     # 0x1ca74
movl 0x19081(%rip), %eax     # 0x1ca84
movl %eax, %ecx
xorl $0x1, %ecx
movl %ecx, 0x19076(%rip)     # 0x1ca84
cmpl $0x1, %eax
movq %r14, %rdx
cmoveq %rbx, %rdx
movq %r15, %rdi
movq %r14, %rsi
jmp 0x3a97
movb (%r13), %al
notb %al
andb $0x1, %al
movb %al, (%r13)
cmpl $0x0, 0x19051(%rip)     # 0x1ca84
je 0x3a49
leaq 0x1a804(%rip), %rax     # 0x1e240
movq (%rax), %rsi
movl $0xa, %edi
callq 0x32a0
cmpb $0x0, (%r13)
leaq 0x119b8(%rip), %rsi     # 0x1540d
leaq 0xe78f(%rip), %rax      # 0x121eb
cmoveq %rax, %rsi
movq %rbp, %rdi
xorl %eax, %eax
callq 0xa127
jmp 0x3a9e
movl 0x19002(%rip), %eax     # 0x1ca74
movl %eax, %ecx
xorl $0x1, %ecx
movl %ecx, 0x18ff7(%rip)     # 0x1ca74
movl $0x0, 0x18ffd(%rip)     # 0x1ca84
cmpl $0x1, %eax
movq %r14, %rsi
cmoveq %rbx, %rsi
movq %r15, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0xa127
movl $0x19, %edi
callq 0xa411
jmp 0x395a
movq 0x1a1bc(%rip), %rdi     # 0x1dc70
callq 0x3590
testl %eax, %eax
je 0x3acb
leaq 0xe793(%rip), %rdi      # 0x12257
xorl %eax, %eax
callq 0xa054
movq 0x1a196(%rip), %rdi     # 0x1dc68
callq 0x3590
testl %eax, %eax
je 0x3ae9
leaq 0xe70d(%rip), %rdi      # 0x121ef
xorl %eax, %eax
callq 0xa054
movq 0x1a178(%rip), %rdi     # 0x1dc68
xorl %esi, %esi
callq 0x3570
testl %eax, %eax
je 0x3b09
leaq 0xe70f(%rip), %rdi      # 0x12211
xorl %eax, %eax
callq 0xa054
leaq 0xe767(%rip), %rdi      # 0x12277
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa127