// File: /workspace/github_c_makefile_star2_O2/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 0xd879(%rip), %rdi      # 0x11113
xorl %eax, %eax
callq 0x99c3
leaq 0xd880(%rip), %rdi      # 0x11128
xorl %eax, %eax
callq 0x99c3
leaq 0x1a3a2(%rip), %rdi     # 0x1dc58
leaq 0x2bfb(%rip), %rdx      # 0x64b8
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3440
testl %eax, %eax
je 0x38d8
leaq 0xd89f(%rip), %rdi      # 0x11170
xorl %eax, %eax
callq 0x98f2
leaq 0x1a381(%rip), %rdi     # 0x1dc60
leaq 0x3a4d(%rip), %rdx      # 0x7333
xorl %esi, %esi
xorl %ecx, %ecx
callq 0x3440
testl %eax, %eax
je 0x3901
leaq 0xd898(%rip), %rdi      # 0x11192
xorl %eax, %eax
callq 0x98f2
leaq 0xd8c8(%rip), %rbx      # 0x111d0
leaq 0x11d49(%rip), %r14     # 0x15658
leaq 0xd89c(%rip), %r15      # 0x111b2
pushq $0x19
popq %rbp
leaq 0xd6e4(%rip), %r13      # 0x11004
leaq 0x1a54a(%rip), %r12     # 0x1de71
callq 0x867f
movl %eax, %edi
callq 0x30e0
movzbl %al, %eax
leal -0x51(%rax), %ecx
cmpl $0x5, %ecx
ja 0x39b8
movslq (%r13,%rcx,4), %rax
addq %r13, %rax
jmpq *%rax
movq 0x1a309(%rip), %rdi     # 0x1dc58
callq 0x3580
testl %eax, %eax
je 0x3966
leaq 0xd890(%rip), %rdi      # 0x111ef
xorl %eax, %eax
callq 0x98f2
movq 0x1a2eb(%rip), %rdi     # 0x1dc58
xorl %esi, %esi
callq 0x3560
testl %eax, %eax
je 0x3986
leaq 0xd892(%rip), %rdi      # 0x11211
xorl %eax, %eax
callq 0x98f2
leaq 0x1a2cb(%rip), %rdi     # 0x1dc58
xorl %esi, %esi
leaq 0x2b22(%rip), %rdx      # 0x64b8
xorl %ecx, %ecx
callq 0x3440
testl %eax, %eax
je 0x3a6c
leaq 0xd888(%rip), %rdi      # 0x11234
xorl %eax, %eax
callq 0x98f2
jmp 0x3a6c
cmpl $0x44, %eax
jne 0x3a6c
movl $0x1, 0x19099(%rip)     # 0x1ca64
movl 0x190a3(%rip), %eax     # 0x1ca74
movl %eax, %ecx
xorl $0x1, %ecx
movl %ecx, 0x19098(%rip)     # 0x1ca74
cmpl $0x1, %eax
movq %r14, %rdx
cmoveq %rbx, %rdx
movq %r15, %rdi
movq %r14, %rsi
jmp 0x3a65
movb (%r12), %al
notb %al
andb $0x1, %al
movb %al, (%r12)
cmpl $0x0, 0x19073(%rip)     # 0x1ca74
je 0x3a19
leaq 0x1a826(%rip), %rax     # 0x1e230
movq (%rax), %rsi
pushq $0xa
popq %rdi
callq 0x3290
movb (%r12), %al
testb %al, %al
leaq 0x10a33(%rip), %rsi     # 0x14455
leaq 0xd7c2(%rip), %rax      # 0x111eb
cmoveq %rax, %rsi
leaq 0xd7a0(%rip), %rdi      # 0x111d4
xorl %eax, %eax
callq 0x99c3
jmp 0x3a6c
movl 0x19021(%rip), %eax     # 0x1ca64
movl %eax, %ecx
xorl $0x1, %ecx
movl %ecx, 0x19016(%rip)     # 0x1ca64
andl $0x0, 0x1901f(%rip)     # 0x1ca74
cmpl $0x1, %eax
movq %r14, %rsi
cmoveq %rbx, %rsi
movq %r15, %rdi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x99c3
movl %ebp, %edi
callq 0x9c93
jmp 0x3927
movq 0x1a1e1(%rip), %rdi     # 0x1dc60
callq 0x3580
testl %eax, %eax
je 0x3a96
leaq 0xd7c8(%rip), %rdi      # 0x11257
xorl %eax, %eax
callq 0x98f2
movq 0x1a1bb(%rip), %rdi     # 0x1dc58
callq 0x3580
testl %eax, %eax
je 0x3ab4
leaq 0xd742(%rip), %rdi      # 0x111ef
xorl %eax, %eax
callq 0x98f2
movq 0x1a19d(%rip), %rdi     # 0x1dc58
xorl %esi, %esi
callq 0x3560
testl %eax, %eax
je 0x3ad4
leaq 0xd744(%rip), %rdi      # 0x11211
xorl %eax, %eax
callq 0x98f2
leaq 0xd79c(%rip), %rdi      # 0x11277
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x99c3