// File: /workspace/github_c_makefile_star2_O1/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 0xb4d4(%rip), %rax      # 0x1ca94
movl (%rax), %r8d
leaq 0xa8(%rsp), %rdi
xorl %ecx, %ecx
callq 0x10b28
testl %eax, %eax
je 0x115ee
leaq 0x5d87(%rip), %rsi      # 0x17364
movl $0xfffffff6, %edi       # imm = 0xFFFFFFF6
xorl %eax, %eax
callq 0x9f8f
jmp 0x117bd
movq 0xa9db(%rip), %rbp      # 0x1bfd0
movq (%rbp), %rcx
leaq 0x5d7d(%rip), %rdi      # 0x1737d
movl $0x36, %esi
movl $0x1, %edx
callq 0x3560
movq (%rbp), %rcx
leaq 0x5d9a(%rip), %rdi      # 0x173b4
movl $0x26, %esi
movl $0x1, %edx
callq 0x3560
movq (%rbp), %rcx
leaq 0x5da7(%rip), %rdi      # 0x173db
movl $0x44, %esi
movl $0x1, %edx
callq 0x3560
testq %rbx, %rbx
je 0x1165d
movq (%rbp), %rdi
leaq 0x5dcd(%rip), %rsi      # 0x17420
movq %rbx, %rdx
xorl %eax, %eax
callq 0x3320
leaq 0xa8(%rsp), %rbx
leaq 0x20(%rsp), %r14
leaq 0x10(%rsp), %r15
xorl %r13d, %r13d
xorl %r12d, %r12d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x10d2d
testq %rax, %rax
je 0x1169e
cmpb $0x0, (%rax)
je 0x1169e
movq (%rbp), %rsi
movq %rax, %rdi
callq 0x3220
movq (%rbp), %rdi
callq 0x33d0
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movq $0x1, 0x20(%rsp)
movaps %xmm0, 0x10(%rsp)
movl $0x1, %edi
movq %r14, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r15, %r8
callq 0x3390
testl %eax, %eax
js 0x11728
je 0x1178b
callq 0x3300
testl %r12d, %r12d
setne %dl
movl %eax, %ecx
shll $0x18, %ecx
cmpl $0x1000000, %ecx        # imm = 0x1000000
sete %sil
testb %sil, %dl
je 0x11744
movl $0x1, %r12d
movl $0x1, %r13d
jmp 0x1178b
callq 0x3080
movl (%rax), %edx
movl $0xfffffff4, %edi       # imm = 0xFFFFFFF4
leaq 0x5cf2(%rip), %rsi      # 0x1742d
xorl %eax, %eax
callq 0x9f8f
jmp 0x1178b
movl %ecx, %edx
xorl $0x1000000, %edx        # imm = 0x1000000
orl %edx, %r12d
jne 0x11759
movl $0x1, %r12d
jmp 0x1178b
cmpl $0x7000000, %ecx        # imm = 0x7000000
jne 0x11772
movw $0x3e, 0x8(%rsp)
movl $0x4c45423c, 0x4(%rsp)  # imm = 0x4C45423C
jmp 0x1177b
movb %al, 0x4(%rsp)
movb $0x0, 0x5(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x10c34
xorl %r12d, %r12d
testl %r13d, %r13d
je 0x11675
leaq 0xa8(%rsp), %rdi
callq 0x10b8e
movq (%rbp), %rcx
leaq 0x5ca6(%rip), %rdi      # 0x17452
movl $0x24, %esi
movl $0x1, %edx
callq 0x3560
xorl %eax, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq