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
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
tty: tty.c
|
||||||
|
$(CC) -o $@ $<
|
||||||
|
clean:
|
||||||
|
rm -f tty
|
||||||
+58
@@ -0,0 +1,58 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
int fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
|
||||||
|
if (fd < 0) { perror("open"); return 1; }
|
||||||
|
|
||||||
|
// Configure serial port
|
||||||
|
struct termios tty;
|
||||||
|
tcgetattr(fd, &tty);
|
||||||
|
cfmakeraw(&tty);
|
||||||
|
cfsetspeed(&tty, B115200);
|
||||||
|
tty.c_cflag |= CLOCAL | CREAD;
|
||||||
|
tty.c_cc[VMIN] = 0;
|
||||||
|
tty.c_cc[VTIME] = 1;
|
||||||
|
tcsetattr(fd, TCSANOW, &tty);
|
||||||
|
|
||||||
|
// Set stdin to raw mode
|
||||||
|
struct termios old_stdin, raw_stdin;
|
||||||
|
tcgetattr(STDIN_FILENO, &old_stdin);
|
||||||
|
raw_stdin = old_stdin;
|
||||||
|
cfmakeraw(&raw_stdin);
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &raw_stdin);
|
||||||
|
|
||||||
|
write(STDOUT_FILENO, "Holcks minitty - ctrl-d to exit\r\n", 33);
|
||||||
|
|
||||||
|
struct pollfd fds[2] = {
|
||||||
|
{ .fd = STDIN_FILENO, .events = POLLIN },
|
||||||
|
{ .fd = fd, .events = POLLIN },
|
||||||
|
};
|
||||||
|
|
||||||
|
char buf[256];
|
||||||
|
while (1) {
|
||||||
|
poll(fds, 2, -1);
|
||||||
|
if (fds[0].revents & POLLIN) {
|
||||||
|
int n = read(STDIN_FILENO, buf, sizeof(buf));
|
||||||
|
if (n > 0) {
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
if (buf[i] == 4) goto done; // Ctrl-D
|
||||||
|
write(fd, buf, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (fds[1].revents & POLLIN) {
|
||||||
|
int n = read(fd, buf, sizeof(buf));
|
||||||
|
if (n > 0) write(STDOUT_FILENO, buf, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
tcsetattr(STDIN_FILENO, TCSANOW, &old_stdin);
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
## 2026-04-10 20:39:49
|
||||||
|
User [chat]: Hello!
|
||||||
|
AI: Hello, Anders! How are you doing today? Is there anything specific you'd like to talk about or any questions I can help you with?
|
||||||
|
|
||||||
|
## 2026-04-10 20:40:00
|
||||||
|
User [chat]: What are you doing?
|
||||||
|
AI: I'm currently processing your messages and waiting to see how I can help you, Anders! Since I'm an AI, I don't have a physical life, so I spend my time analyzing text, answering questions, and chattin
|
||||||
|
|
||||||
|
## 2026-04-10 20:41:29
|
||||||
|
User [chat]: How can I control fans in Linux?
|
||||||
|
AI: Controlling fans in Linux, Anders, is a bit of a delicate process because it requires interacting directly with your motherboard's hardware controllers. The most standard approach involves using a com
|
||||||
|
|
||||||
|
## 2026-04-10 21:45:34
|
||||||
|
User [chat]: How can I control fans in Linux?
|
||||||
|
AI: Since you are asking again, Anders, perhaps you are looking for a more structured way to approach this, or maybe you are looking for alternatives to the command-line method I mentioned previously. Let
|
||||||
|
|
||||||
|
## 2026-04-10 23:24:11
|
||||||
|
User: Are you here?
|
||||||
|
AI: Yes, I am here.
|
||||||
|
|
||||||
|
## 2026-04-10 23:24:17
|
||||||
|
User [chat]: Hello
|
||||||
|
AI: Hello there. How are you doing today, Anders?
|
||||||
|
|
||||||
|
## 2026-04-10 23:24:25
|
||||||
|
User [chat]: Not much
|
||||||
|
AI: I'm sorry to hear that. Is everything okay? Or are you just having a quiet day?
|
||||||
|
|
||||||
|
## 2026-04-10 23:26:19
|
||||||
|
User [chat]: All is ok!
|
||||||
|
AI: That's good to hear! Sometimes just having an okay day is exactly what you need. Is there anything on your mind, or anything you'd like to talk about?
|
||||||
|
|
||||||
|
## 2026-04-10 23:26:35
|
||||||
|
User [chat]: Not really, I am just checking if you are running properly.
|
||||||
|
AI: I am running perfectly, thank you for checking in on me, Anders. I am here and ready to chat whenever you are. Is there anything specific you wanted to test or discuss?
|
||||||
|
|
||||||
|
## 2026-04-10 23:27:32
|
||||||
|
User [chat]: Hello
|
||||||
|
AI: Hello again, Anders! Still testing things out, or just saying hi one more time?
|
||||||
|
|
||||||
|
## 2026-04-10 23:28:19
|
||||||
|
User [chat]: Hej
|
||||||
|
AI: Hej! How are things going on your end right now?
|
||||||
Reference in New Issue
Block a user