added tty
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
tty: tty.S
|
||||
as -o tty.o tty.S
|
||||
ld -o tty tty.o
|
||||
clean:
|
||||
rm -f tty tty.o
|
||||
@@ -0,0 +1,255 @@
|
||||
.intel_syntax noprefix
|
||||
|
||||
# syscall numbers
|
||||
.equ SYS_READ, 0
|
||||
.equ SYS_WRITE, 1
|
||||
.equ SYS_OPEN, 2
|
||||
.equ SYS_CLOSE, 3
|
||||
.equ SYS_POLL, 7
|
||||
.equ SYS_IOCTL, 16
|
||||
.equ SYS_EXIT, 60
|
||||
|
||||
# ioctl / termios
|
||||
.equ TCGETS, 0x5401
|
||||
.equ TCSETS, 0x5402
|
||||
.equ TERMIOS_SIZE, 60 # sizeof(struct termios) on x86_64
|
||||
|
||||
# termios c_lflag bits to clear
|
||||
.equ ICANON, 0x2
|
||||
.equ ECHO, 0x8
|
||||
.equ ISIG, 0x1
|
||||
|
||||
# termios c_iflag bits to clear
|
||||
.equ IGNBRK, 0x1
|
||||
.equ BRKINT, 0x2
|
||||
.equ PARMRK, 0x8
|
||||
.equ ISTRIP, 0x20
|
||||
.equ INLCR, 0x40
|
||||
.equ IGNCR, 0x80
|
||||
.equ ICRNL, 0x100
|
||||
.equ IXON, 0x400
|
||||
|
||||
# termios c_oflag bits to clear
|
||||
.equ OPOST, 0x1
|
||||
|
||||
# termios c_cflag
|
||||
.equ CSIZE, 0x30
|
||||
.equ PARENB, 0x100
|
||||
.equ CS8, 0x30
|
||||
.equ CLOCAL, 0x800
|
||||
.equ CREAD, 0x80
|
||||
|
||||
# baud
|
||||
.equ B115200, 0x1002
|
||||
|
||||
# open flags
|
||||
.equ O_RDWR, 0x2
|
||||
.equ O_NOCTTY, 0x100
|
||||
|
||||
# poll
|
||||
.equ POLLIN, 0x1
|
||||
.equ POLLFD_SIZE, 8
|
||||
|
||||
# termios field offsets
|
||||
.equ OFLAG_OFF, 4
|
||||
.equ CFLAG_OFF, 8
|
||||
.equ LFLAG_OFF, 12
|
||||
.equ CC_OFF, 17 # c_cc array offset
|
||||
.equ VMIN, 6 # c_cc index
|
||||
.equ VTIME, 5 # c_cc index
|
||||
.equ ISPEED_OFF, 52
|
||||
.equ OSPEED_OFF, 56
|
||||
|
||||
.data
|
||||
devpath: .asciz "/dev/ttyUSB0"
|
||||
banner: .ascii "Holck's minitty - ctrl-d to exit!\r\n"
|
||||
.equ BANNER_LEN, . - banner
|
||||
|
||||
.bss
|
||||
.align 8
|
||||
serial_fd: .quad 0
|
||||
old_termios: .space TERMIOS_SIZE
|
||||
raw_termios: .space TERMIOS_SIZE
|
||||
ser_termios: .space TERMIOS_SIZE
|
||||
pollfds: .space POLLFD_SIZE * 2 # two pollfd structs
|
||||
buf: .space 256
|
||||
|
||||
.text
|
||||
.globl _start
|
||||
|
||||
_start:
|
||||
# Open serial port
|
||||
mov rdi, offset devpath
|
||||
mov rsi, O_RDWR | O_NOCTTY
|
||||
xor rdx, rdx
|
||||
mov rax, SYS_OPEN
|
||||
syscall
|
||||
test rax, rax
|
||||
js exit_fail
|
||||
mov [serial_fd], rax
|
||||
|
||||
# Get serial termios & configure
|
||||
mov rdi, rax
|
||||
mov rsi, TCGETS
|
||||
lea rdx, [ser_termios]
|
||||
mov rax, SYS_IOCTL
|
||||
syscall
|
||||
|
||||
# cfmakeraw equivalent for serial
|
||||
lea rbx, [ser_termios]
|
||||
# iflag: clear everything raw clears
|
||||
and dword ptr [rbx], ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON)
|
||||
# oflag: clear OPOST
|
||||
and dword ptr [rbx + OFLAG_OFF], ~OPOST
|
||||
# cflag: CS8, CLOCAL, CREAD, no parity
|
||||
mov eax, [rbx + CFLAG_OFF]
|
||||
and eax, ~(CSIZE | PARENB)
|
||||
or eax, CS8 | CLOCAL | CREAD
|
||||
mov [rbx + CFLAG_OFF], eax
|
||||
# lflag: clear ECHO, ICANON, ISIG
|
||||
and dword ptr [rbx + LFLAG_OFF], ~(ECHO|ICANON|ISIG)
|
||||
# VMIN=0, VTIME=1
|
||||
mov byte ptr [rbx + CC_OFF + VMIN], 0
|
||||
mov byte ptr [rbx + CC_OFF + VTIME], 1
|
||||
# baud 115200
|
||||
mov dword ptr [rbx + ISPEED_OFF], B115200
|
||||
mov dword ptr [rbx + OSPEED_OFF], B115200
|
||||
|
||||
mov rdi, [serial_fd]
|
||||
mov rsi, TCSETS
|
||||
lea rdx, [ser_termios]
|
||||
mov rax, SYS_IOCTL
|
||||
syscall
|
||||
|
||||
# Save stdin termios
|
||||
xor rdi, rdi
|
||||
mov rsi, TCGETS
|
||||
lea rdx, [old_termios]
|
||||
mov rax, SYS_IOCTL
|
||||
syscall
|
||||
|
||||
# Copy old to raw and make raw
|
||||
lea rsi, [old_termios]
|
||||
lea rdi, [raw_termios]
|
||||
mov rcx, TERMIOS_SIZE
|
||||
rep movsb
|
||||
|
||||
lea rbx, [raw_termios]
|
||||
and dword ptr [rbx], ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON)
|
||||
and dword ptr [rbx + OFLAG_OFF], ~OPOST
|
||||
mov eax, [rbx + CFLAG_OFF]
|
||||
and eax, ~(CSIZE | PARENB)
|
||||
or eax, CS8
|
||||
mov [rbx + CFLAG_OFF], eax
|
||||
and dword ptr [rbx + LFLAG_OFF], ~(ECHO|ICANON|ISIG)
|
||||
mov byte ptr [rbx + CC_OFF + VMIN], 1
|
||||
mov byte ptr [rbx + CC_OFF + VTIME], 0
|
||||
|
||||
# Set stdin raw
|
||||
xor rdi, rdi
|
||||
mov rsi, TCSETS
|
||||
lea rdx, [raw_termios]
|
||||
mov rax, SYS_IOCTL
|
||||
syscall
|
||||
|
||||
# Print banner
|
||||
mov rdi, 1
|
||||
lea rsi, [banner]
|
||||
mov rdx, BANNER_LEN
|
||||
mov rax, SYS_WRITE
|
||||
syscall
|
||||
|
||||
# Setup pollfds: [0]=stdin, [1]=serial
|
||||
lea rbx, [pollfds]
|
||||
mov dword ptr [rbx], 0 # fd = stdin
|
||||
mov word ptr [rbx + 4], POLLIN # events
|
||||
mov word ptr [rbx + 6], 0 # revents
|
||||
|
||||
mov eax, [serial_fd]
|
||||
mov dword ptr [rbx + 8], eax # fd = serial
|
||||
mov word ptr [rbx + 12], POLLIN
|
||||
mov word ptr [rbx + 14], 0
|
||||
|
||||
poll_loop:
|
||||
lea rdi, [pollfds]
|
||||
mov rsi, 2
|
||||
mov rdx, -1 # infinite timeout
|
||||
mov rax, SYS_POLL
|
||||
syscall
|
||||
|
||||
# Check stdin
|
||||
lea rbx, [pollfds]
|
||||
movzx eax, word ptr [rbx + 6] # revents
|
||||
test eax, POLLIN
|
||||
jz check_serial
|
||||
|
||||
# Read stdin
|
||||
xor rdi, rdi
|
||||
lea rsi, [buf]
|
||||
mov rdx, 256
|
||||
mov rax, SYS_READ
|
||||
syscall
|
||||
test rax, rax
|
||||
jle done
|
||||
|
||||
# Scan for Ctrl-D (0x04)
|
||||
mov rcx, rax
|
||||
lea rsi, [buf]
|
||||
scan:
|
||||
cmp byte ptr [rsi], 4
|
||||
je done
|
||||
inc rsi
|
||||
dec rcx
|
||||
jnz scan
|
||||
|
||||
# Write to serial
|
||||
mov rdi, [serial_fd]
|
||||
lea rsi, [buf]
|
||||
mov rdx, rax
|
||||
mov rax, SYS_WRITE
|
||||
syscall
|
||||
|
||||
check_serial:
|
||||
lea rbx, [pollfds]
|
||||
movzx eax, word ptr [rbx + 14] # revents
|
||||
test eax, POLLIN
|
||||
jz poll_loop
|
||||
|
||||
# Read serial
|
||||
mov rdi, [serial_fd]
|
||||
lea rsi, [buf]
|
||||
mov rdx, 256
|
||||
mov rax, SYS_READ
|
||||
syscall
|
||||
test rax, rax
|
||||
jle poll_loop
|
||||
|
||||
# Write to stdout
|
||||
mov rdx, rax
|
||||
mov rdi, 1
|
||||
lea rsi, [buf]
|
||||
mov rax, SYS_WRITE
|
||||
syscall
|
||||
jmp poll_loop
|
||||
|
||||
done:
|
||||
# Restore stdin termios
|
||||
xor rdi, rdi
|
||||
mov rsi, TCSETS
|
||||
lea rdx, [old_termios]
|
||||
mov rax, SYS_IOCTL
|
||||
syscall
|
||||
|
||||
# Close serial
|
||||
mov rdi, [serial_fd]
|
||||
mov rax, SYS_CLOSE
|
||||
syscall
|
||||
|
||||
xor rdi, rdi
|
||||
mov rax, SYS_EXIT
|
||||
syscall
|
||||
|
||||
exit_fail:
|
||||
mov rdi, 1
|
||||
mov rax, SYS_EXIT
|
||||
syscall
|
||||
Reference in New Issue
Block a user