// File: /workspace/github_c_makefile_star2_O3/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 0xe85a(%rip), %rdi      # 0x12113
xorl %eax, %eax
callq 0xa10f
leaq 0xe861(%rip), %rdi      # 0x12128
xorl %eax, %eax
callq 0xa10f
leaq 0x1a383(%rip), %rdi     # 0x1dc58
leaq 0x2ef7(%rip), %rdx      # 0x67d3
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3440
testl %eax, %eax
je 0x38f7
leaq 0xe880(%rip), %rdi      # 0x12170
xorl %eax, %eax
callq 0xa03c
leaq 0x1a362(%rip), %rdi     # 0x1dc60
leaq 0x3d75(%rip), %rdx      # 0x767a
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3440
testl %eax, %eax
je 0x3920
leaq 0xe879(%rip), %rdi      # 0x12192
xorl %eax, %eax
callq 0xa03c
leaq 0xe8a9(%rip), %rbx      # 0x121d0
leaq 0x12d77(%rip), %r14     # 0x166a5
leaq 0xe87d(%rip), %r15      # 0x121b2
leaq 0xe6c8(%rip), %r12      # 0x12004
leaq 0x1a52e(%rip), %r13     # 0x1de71
leaq 0xe88a(%rip), %rbp      # 0x121d4
callq 0x8a9c
movl %eax, %edi
callq 0x30e0
movzbl %al, %eax
leal -0x51(%rax), %ecx
cmpl $0x5, %ecx
ja 0x39da
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movq 0x1a2e7(%rip), %rdi     # 0x1dc58
callq 0x3580
testl %eax, %eax
je 0x3988
leaq 0xe86e(%rip), %rdi      # 0x121ef
xorl %eax, %eax
callq 0xa03c
movq 0x1a2c9(%rip), %rdi     # 0x1dc58
xorl %esi, %esi
callq 0x3560
testl %eax, %eax
je 0x39a8
leaq 0xe870(%rip), %rdi      # 0x12211
xorl %eax, %eax
callq 0xa03c
leaq 0x1a2a9(%rip), %rdi     # 0x1dc58
xorl %esi, %esi
leaq 0x2e1b(%rip), %rdx      # 0x67d3
xorl %ecx, %ecx
callq 0x3440
testl %eax, %eax
je 0x3a8f
leaq 0xe866(%rip), %rdi      # 0x12234
xorl %eax, %eax
callq 0xa03c
jmp 0x3a8f
cmpl $0x44, %eax
jne 0x3a8f
movl $0x1, 0x19077(%rip)     # 0x1ca64
movl 0x19081(%rip), %eax     # 0x1ca74
movl %eax, %ecx
xorl $0x1, %ecx
movl %ecx, 0x19076(%rip)     # 0x1ca74
cmpl $0x1, %eax
movq %r14, %rdx
cmoveq %rbx, %rdx
movq %r15, %rdi
movq %r14, %rsi
jmp 0x3a88
movb (%r13), %al
notb %al
andb $0x1, %al
movb %al, (%r13)
cmpl $0x0, 0x19051(%rip)     # 0x1ca74
je 0x3a3d
leaq 0x1a804(%rip), %rax     # 0x1e230
movq (%rax), %rsi
movl $0xa, %edi
callq 0x3290
movb (%r13), %al
testb %al, %al
leaq 0x11a37(%rip), %rsi     # 0x1547d
leaq 0xe79e(%rip), %rax      # 0x121eb
cmoveq %rax, %rsi
movq %rbp, %rdi
xorl %eax, %eax
callq 0xa10f
jmp 0x3a8f
movl 0x19001(%rip), %eax     # 0x1ca64
movl %eax, %ecx
xorl $0x1, %ecx
movl %ecx, 0x18ff6(%rip)     # 0x1ca64
movl $0x0, 0x18ffc(%rip)     # 0x1ca74
cmpl $0x1, %eax
movq %r14, %rsi
cmoveq %rbx, %rsi
movq %r15, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0xa10f
movl $0x19, %edi
callq 0xa3f4
jmp 0x394a
movq 0x1a1bb(%rip), %rdi     # 0x1dc60
callq 0x3580
testl %eax, %eax
je 0x3abc
leaq 0xe7a2(%rip), %rdi      # 0x12257
xorl %eax, %eax
callq 0xa03c
movq 0x1a195(%rip), %rdi     # 0x1dc58
callq 0x3580
testl %eax, %eax
je 0x3ada
leaq 0xe71c(%rip), %rdi      # 0x121ef
xorl %eax, %eax
callq 0xa03c
movq 0x1a177(%rip), %rdi     # 0x1dc58
xorl %esi, %esi
callq 0x3560
testl %eax, %eax
je 0x3afa
leaq 0xe71e(%rip), %rdi      # 0x12211
xorl %eax, %eax
callq 0xa03c
leaq 0xe776(%rip), %rdi      # 0x12277
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa10f