// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x54(%rbp)
movl $0x0, -0x58(%rbp)
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
leaq 0xba62(%rip), %rax      # 0x23d84
movl (%rax), %r8d
leaq -0x50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
callq 0x170d0
cmpl $0x0, %eax
je 0x18352
movl $0xfffffff6, %edi       # imm = 0xFFFFFFF6
leaq 0x6031(%rip), %rsi      # 0x1e374
movb $0x0, %al
callq 0xcd70
movl %eax, -0x4(%rbp)
jmp 0x185aa
movq 0xac77(%rip), %rax      # 0x22fd0
movq (%rax), %rdi
leaq 0x602a(%rip), %rsi      # 0x1e38d
movb $0x0, %al
callq 0x3300
movq 0xac5f(%rip), %rax      # 0x22fd0
movq (%rax), %rdi
leaq 0x6049(%rip), %rsi      # 0x1e3c4
movb $0x0, %al
callq 0x3300
movq 0xac47(%rip), %rax      # 0x22fd0
movq (%rax), %rdi
leaq 0x6058(%rip), %rsi      # 0x1e3eb
movb $0x0, %al
callq 0x3300
cmpq $0x0, -0x20(%rbp)
je 0x183bd
movq 0xac28(%rip), %rax      # 0x22fd0
movq (%rax), %rdi
movq -0x20(%rbp), %rdx
leaq 0x607a(%rip), %rsi      # 0x1e430
movb $0x0, %al
callq 0x3300
jmp 0x183bf
cmpl $0x0, -0x54(%rbp)
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x183d1
jmp 0x18582
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
callq 0x175b0
movq %rax, -0xf8(%rbp)
cmpq $0x0, -0xf8(%rbp)
je 0x18424
movq -0xf8(%rbp), %rdi
callq 0x3190
cmpq $0x0, %rax
je 0x18424
movq -0xf8(%rbp), %rdi
movq 0xabc3(%rip), %rax      # 0x22fd0
movq (%rax), %rsi
callq 0x3210
movq 0xabb4(%rip), %rax      # 0x22fd0
movq (%rax), %rdi
callq 0x33b0
jmp 0x18426
leaq -0xe0(%rbp), %rax
movq %rax, -0x108(%rbp)
movl $0x0, -0xfc(%rbp)
movl -0xfc(%rbp), %eax
cmpq $0x10, %rax
jae 0x18470
movq -0x108(%rbp), %rax
movl -0xfc(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0xfc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xfc(%rbp)
jmp 0x1843e
jmp 0x18472
movq -0xe0(%rbp), %rax
orq $0x1, %rax
movq %rax, -0xe0(%rbp)
movq $0x0, -0xe8(%rbp)
movq $0x0, -0xf0(%rbp)
movl $0x1, %edi
leaq -0xe0(%rbp), %rsi
xorl %eax, %eax
movl %eax, %ecx
leaq -0xf0(%rbp), %r8
movq %rcx, %rdx
callq 0x3370
movl %eax, -0x5c(%rbp)
cmpl $0x0, -0x5c(%rbp)
jge 0x184e1
callq 0x3070
movl (%rax), %edx
movl $0xfffffff4, %edi       # imm = 0xFFFFFFF4
leaq 0x5f68(%rip), %rsi      # 0x1e43d
movb $0x0, %al
callq 0xcd70
jmp 0x1857d
cmpl $0x0, -0x5c(%rbp)
jle 0x1857b
callq 0x32e0
movb %al, -0x109(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x18511
movsbl -0x109(%rbp), %eax
cmpl $0x1, %eax
jne 0x18511
movl $0x1, -0x54(%rbp)
jmp 0x18579
cmpl $0x0, -0x58(%rbp)
jne 0x1852c
movsbl -0x109(%rbp), %eax
cmpl $0x1, %eax
jne 0x1852c
movl $0x1, -0x58(%rbp)
jmp 0x18577
movl $0x0, -0x58(%rbp)
movsbl -0x109(%rbp), %eax
cmpl $0x7, %eax
jne 0x18554
leaq -0x113(%rbp), %rdi
leaq 0x41f9(%rip), %rsi      # 0x1c746
callq 0x30c0
jmp 0x18567
movb -0x109(%rbp), %al
movb %al, -0x113(%rbp)
movb $0x0, -0x112(%rbp)
leaq -0x113(%rbp), %rsi
leaq -0x50(%rbp), %rdi
callq 0x173b0
jmp 0x18579
jmp 0x1857b
jmp 0x1857d
jmp 0x183bf
leaq -0x50(%rbp), %rdi
callq 0x17200
movq 0xaa3e(%rip), %rax      # 0x22fd0
movq (%rax), %rdi
leaq 0x5ec6(%rip), %rsi      # 0x1e462
movb $0x0, %al
callq 0x3300
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq