// File: /workspace/github_c_makefile_star2_O2/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 0xc5f0(%rip), %rax      # 0x1ca84
movl (%rax), %r8d
leaq 0x28(%rsp), %rdi
xorl %ecx, %ecx
callq 0xfa60
testl %eax, %eax
je 0x104bd
leaq 0x5efe(%rip), %rsi      # 0x163ac
pushq $-0xa
popq %rdi
xorl %eax, %eax
callq 0x982c
jmp 0x10669
movq 0xbb0c(%rip), %r15      # 0x1bfd0
movq (%r15), %rcx
leaq 0x5ef7(%rip), %rdi      # 0x163c5
pushq $0x36
popq %rsi
pushq $0x1
popq %r14
movq %r14, %rdx
callq 0x3550
movq (%r15), %rcx
leaq 0x5f15(%rip), %rdi      # 0x163fc
pushq $0x26
popq %rsi
movq %r14, %rdx
callq 0x3550
movq (%r15), %rcx
leaq 0x5f27(%rip), %rdi      # 0x16423
pushq $0x44
popq %rsi
movq %r14, %rdx
callq 0x3550
testq %rbx, %rbx
je 0x10520
movq (%r15), %rdi
leaq 0x5f52(%rip), %rsi      # 0x16468
movq %rbx, %rdx
xorl %eax, %eax
callq 0x3310
xorl %r13d, %r13d
leaq 0x28(%rsp), %rbx
pushq $0x1
popq %r12
leaq 0x58(%rsp), %r14
leaq 0x10(%rsp), %r15
xorl %ebp, %ebp
testl %ebp, %ebp
jne 0x10641
movq %rbx, %rdi
xorl %esi, %esi
callq 0xfc70
testq %rax, %rax
je 0x10570
cmpb $0x0, (%rax)
je 0x10570
movq 0xba75(%rip), %rbp      # 0x1bfd0
movq (%rbp), %rsi
movq %rax, %rdi
callq 0x3210
movq (%rbp), %rdi
callq 0x33c0
xorl %eax, %eax
cmpq $0x10, %rax
je 0x10583
andq $0x0, 0x58(%rsp,%rax,8)
incq %rax
jmp 0x10572
orb $0x1, 0x58(%rsp)
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movl %r12d, %edi
movq %r14, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r15, %r8
callq 0x3380
testl %eax, %eax
js 0x10600
xorl %ebp, %ebp
testl %eax, %eax
je 0x1061a
callq 0x32f0
testl %r13d, %r13d
setne %sil
movl %eax, %edx
shll $0x18, %edx
cmpl $0x1000000, %edx        # imm = 0x1000000
sete %dil
movl %r12d, %ecx
movl %r12d, %ebp
testb %dil, %sil
jne 0x1061d
movl %edx, %ecx
xorl $0x1000000, %ecx        # imm = 0x1000000
orl %ecx, %r13d
movl %r12d, %ecx
movl $0x0, %ebp
je 0x1061d
cmpl $0x7000000, %edx        # imm = 0x7000000
jne 0x10625
movw $0x3e, 0x8(%rsp)
movl $0x4c45423c, 0x4(%rsp)  # imm = 0x4C45423C
jmp 0x1062e
callq 0x3080
movl (%rax), %edx
xorl %ebp, %ebp
pushq $-0xc
popq %rdi
leaq 0x5e62(%rip), %rsi      # 0x16475
xorl %eax, %eax
callq 0x982c
movl %r13d, %ecx
movl %ecx, %r13d
jmp 0x10538
movb %al, 0x4(%rsp)
movb $0x0, 0x5(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0xfb75
xorl %ecx, %ecx
xorl %ebp, %ebp
jmp 0x1061d
leaq 0x28(%rsp), %rdi
callq 0xfac0
movq 0xb97e(%rip), %rax      # 0x1bfd0
movq (%rax), %rcx
leaq 0x5e3e(%rip), %rdi      # 0x1649a
pushq $0x24
popq %rsi
pushq $0x1
popq %rdx
callq 0x3550
xorl %eax, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq