// File: /workspace/github_c_makefile_star2_O3/j-hoppe[P]tu58fs/bootloader.c
// Function: run_teletype
int run_teletype(serial_device_t *serialdevice, monitor_type_t monitor_type, char *userinfo) {
#define EXITKEY1 0x01
#define EXITKEY2 0x01

	monitor_t monitor;
	int ready = 0;
	int exitkey1_typed = 0; // 1 if 1st exit hotkey typed

	// no user echo to stdout by monitor_*() functions
	if (monitor_init(&monitor, serialdevice, monitor_type, NULL, opt_usbdelay))
		return error_set(ERROR_MONITOR, "monitor_init in teletype");

	// console is in RAW mode: so do own CR LF
	fprintf(stdout, "\r\nTU58FS: teletype session to PDP-11 console opened.\r\n");
	fprintf(stdout, "TU58FS: ^G sound is shown as \"<BEL>\"\r\n");
	fprintf(stdout, "TU58FS: Terminate teletype session with ^A ^A double key sequence.\r\n");
	if (userinfo)
		fprintf(stdout, "TU58FS: %s\r\n", userinfo);
	while (!ready) {
		int status;
		fd_set readfds;
		struct timeval timeout;

		/*
		 * 1. read char from PDP, echo to user
		 */
		char *s = monitor_gets(&monitor, 0);
		if (s && strlen(s)) {
			// show unprocessed on Linux console
			fputs(s, stdout);
			fflush(stdout);
		}
		/*
		 * 2. if user keyboard input, xmt to PDP-11 and check for exit hot key
		 */
		// http://stackoverflow.com/questions/26948723/checking-the-stdin-buffer-if-its-empty
		FD_ZERO(&readfds);
		FD_SET(STDIN_FILENO, &readfds);
		timeout.tv_sec = timeout.tv_usec = 0; // zero timeout, just poll
		status = select(1, &readfds, NULL, NULL, &timeout); // rtfm
		if (status < 0) {
			error_set(ERROR_TTY, "Teletype keyboard polling,  errno=%u", errno);
		} else if (status > 0) {
			// single char input!
			char c = getchar();

			// test for exit hotkey sequence
			if (exitkey1_typed && c == EXITKEY2) {
				// terminate
				ready = 1;
			} else if (!exitkey1_typed && c == EXITKEY1) {
				exitkey1_typed = 1;
				// do not echo to PDP
			} else {
				char buff[10];
				exitkey1_typed = 0;
				if (c == 0x07)
					strcpy(buff, "<BEL>");
				else {
					// char in buff[0], send it to PDP.
					buff[0] = c;
					buff[1] = 0; // char -> string
				}
				monitor_puts(&monitor, buff);
			}
		}
	}

	monitor_close(&monitor);
	fprintf(stdout, "\r\nTU58FS: teletype session closed.\r\n");
	return ERROR_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rdx, %rbx
movl %esi, %edx
movq %rdi, %rsi
leaq 0xb5a8(%rip), %rax      # 0x1ca84
movl (%rax), %r8d
leaq 0x28(%rsp), %rdi
xorl %ecx, %ecx
callq 0x10aac
testl %eax, %eax
je 0x11507
leaq 0x5f06(%rip), %rsi      # 0x173fc
movl $0xfffffff6, %edi       # imm = 0xFFFFFFF6
xorl %eax, %eax
callq 0x9f73
jmp 0x116bd
movq 0xaac2(%rip), %rbp      # 0x1bfd0
movq (%rbp), %rcx
leaq 0x5efc(%rip), %rdi      # 0x17415
movl $0x36, %esi
movl $0x1, %edx
callq 0x3550
movq (%rbp), %rcx
leaq 0x5f19(%rip), %rdi      # 0x1744c
movl $0x26, %esi
movl $0x1, %edx
callq 0x3550
movq (%rbp), %rcx
leaq 0x5f26(%rip), %rdi      # 0x17473
movl $0x44, %esi
movl $0x1, %edx
callq 0x3550
testq %rbx, %rbx
je 0x11576
movq (%rbp), %rdi
leaq 0x5f4c(%rip), %rsi      # 0x174b8
movq %rbx, %rdx
xorl %eax, %eax
callq 0x3310
leaq 0x60(%rsp), %r13
leaq 0x28(%rsp), %rbx
leaq 0x58(%rsp), %r14
leaq 0x10(%rsp), %r15
xorl %r12d, %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10cb1
testq %rax, %rax
je 0x115b6
cmpb $0x0, (%rax)
je 0x115b6
movq (%rbp), %rsi
movq %rax, %rdi
callq 0x3210
movq (%rbp), %rdi
callq 0x33c0
xorps %xmm0, %xmm0
movups %xmm0, 0x60(%r13)
movups %xmm0, 0x50(%r13)
movups %xmm0, 0x40(%r13)
movups %xmm0, 0x30(%r13)
movups %xmm0, 0x20(%r13)
movups %xmm0, 0x10(%r13)
movups %xmm0, (%r13)
movq $0x0, 0x70(%r13)
movq $0x1, 0x58(%rsp)
movaps %xmm0, 0x10(%rsp)
movl $0x1, %edi
movq %r14, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r15, %r8
callq 0x3380
testl %eax, %eax
js 0x11644
je 0x1158d
callq 0x32f0
testl %r12d, %r12d
setne %dl
movl %eax, %ecx
shll $0x18, %ecx
cmpl $0x1000000, %ecx        # imm = 0x1000000
sete %sil
testb %sil, %dl
jne 0x11697
movl %ecx, %edx
xorl $0x1000000, %edx        # imm = 0x1000000
orl %edx, %r12d
movl $0x1, %r12d
je 0x1158d
jmp 0x11663
callq 0x3080
movl (%rax), %edx
movl $0xfffffff4, %edi       # imm = 0xFFFFFFF4
leaq 0x5e6e(%rip), %rsi      # 0x174c5
xorl %eax, %eax
callq 0x9f73
jmp 0x1158d
cmpl $0x7000000, %ecx        # imm = 0x7000000
jne 0x1167c
movw $0x3e, 0x8(%rsp)
movl $0x4c45423c, 0x4(%rsp)  # imm = 0x4C45423C
jmp 0x11685
movb %al, 0x4(%rsp)
movb $0x0, 0x5(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x10bb8
jmp 0x1158a
leaq 0x28(%rsp), %rdi
callq 0x10b12
movq (%rbp), %rcx
leaq 0x5e3e(%rip), %rdi      # 0x174ea
movl $0x24, %esi
movl $0x1, %edx
callq 0x3550
xorl %eax, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq