diff options
| author | hachem <im@hachem.wtf> | 2026-10-04 02:02:15 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-10-04 02:02:15 +0200 |
| commit | 7c1bd03a71cccfcf48e79d241787021b0de98e73 (patch) | |
| tree | b7131a1f4eee60d24781d3f549d191e17793c282 /user | |
| parent | 627f05098785327744e666c9149375125499d2ff (diff) | |
feat: add more user programs
Diffstat (limited to 'user')
| -rw-r--r-- | user/calc.c | 78 | ||||
| -rw-r--r-- | user/hexview.c | 91 | ||||
| -rw-r--r-- | user/primes.c | 42 | ||||
| -rw-r--r-- | user/program.c | 63 | ||||
| -rw-r--r-- | user/user.h | 97 |
5 files changed, 308 insertions, 63 deletions
diff --git a/user/calc.c b/user/calc.c new file mode 100644 index 0000000..2d0e3f8 --- /dev/null +++ b/user/calc.c @@ -0,0 +1,78 @@ +#include "user.h" + +static int is_digit(char character) +{ + return character >= '0' && character <= '9'; +} + +void _start(void) +{ + put("calc, e.g. 3 + 4 * 2 (left to right), empty line quits\n"); + + char line[128]; + for (;;) + { + put("> "); + int length = read_line(line, 128); + put("\n"); + if (length == 0) + break; + + long accumulator = 0; + char operator = '+'; + int valid = 1; + int saw_number = 0; + int position = 0; + while (position < length) + { + char character = line[position]; + if (character == ' ') + { + position++; + continue; + } + if (is_digit(character)) + { + long value = 0; + while (position < length && is_digit(line[position])) + value = value * 10 + (line[position++] - '0'); + if (operator == '+') + accumulator += value; + else if (operator == '-') + accumulator -= value; + else if (operator == '*') + accumulator *= value; + else if (operator == '/' || operator == '%') + { + if (value == 0) + { + put("divide by zero\n"); + valid = 0; + break; + } + accumulator = (operator == '/') ? accumulator / value : accumulator % value; + } + saw_number = 1; + } + else if (character == '+' || character == '-' || character == '*' + || character == '/' || character == '%') + { + operator = character; + position++; + } + else + { + put("bad character\n"); + valid = 0; + break; + } + } + if (valid && saw_number) + { + put("= "); + put_int(accumulator); + put("\n"); + } + } + sys_exit(0); +} diff --git a/user/hexview.c b/user/hexview.c new file mode 100644 index 0000000..f2425e1 --- /dev/null +++ b/user/hexview.c @@ -0,0 +1,91 @@ +// hexview, a ring 3 program that dumps a file from the revel fs. nav is n/p/q +// since the keyboard only gives us decoded ascii, no arrow keys yet + +#include "user.h" + +static const char HEX[] = "0123456789abcdef"; + +static void put_hex8(unsigned char byte) +{ + char digits[2] = { HEX[byte >> 4], HEX[byte & 15] }; + sys_write(digits, 2); +} + +static void put_hex32(unsigned long value) +{ + char digits[8]; + for (int nibble = 0; nibble < 8; nibble++) + digits[nibble] = HEX[(value >> ((7 - nibble) * 4)) & 15]; + sys_write(digits, 8); +} + +#define PAGE 256 +#define COLS 16 + +void _start(void) +{ + put("hexview, type a filename\nfile: "); + char name[64]; + read_line(name, 64); + put("\n"); + + long size = sys_fs_size(name); + if (size < 0) + { + put("no such file\n"); + sys_exit(1); + } + + unsigned long offset = 0; + char buffer[PAGE]; + for (;;) + { + long count = sys_fs_read(name, offset, buffer, PAGE); + + put("--- "); + put(name); + put(" @ 0x"); + put_hex32(offset); + put(" / 0x"); + put_hex32((unsigned long)size); + put(" ---\n"); + + for (long row = 0; row < count; row += COLS) + { + put_hex32(offset + (unsigned long)row); + put(": "); + for (int column = 0; column < COLS; column++) + { + if (row + column < count) + { + put_hex8((unsigned char)buffer[row + column]); + sys_write(" ", 1); + } + else + put(" "); + } + put(" "); + for (int column = 0; column < COLS && row + column < count; column++) + { + char character = buffer[row + column]; + if (character >= 32 && character < 127) + sys_write(&character, 1); + else + sys_write(".", 1); + } + put("\n"); + } + + put("[n]ext [p]rev [q]uit > "); + char key = (char)sys_read(); + put("\n"); + if (key == 'q') + break; + if (key == 'n' && offset + PAGE < (unsigned long)size) + offset += PAGE; + if (key == 'p' && offset >= PAGE) + offset -= PAGE; + } + + sys_exit(0); +} diff --git a/user/primes.c b/user/primes.c new file mode 100644 index 0000000..49c545a --- /dev/null +++ b/user/primes.c @@ -0,0 +1,42 @@ +#include "user.h" + +void _start(void) +{ + put("primes up to N, enter N (empty line quits)\n"); + char line[32]; + for (;;) + { + put("> "); + int length = read_line(line, 32); + put("\n"); + if (length == 0) + break; + + long limit = 0; + for (int position = 0; position < length; position++) + if (line[position] >= '0' && line[position] <= '9') + limit = limit * 10 + (line[position] - '0'); + + int count = 0; + for (long candidate = 2; candidate <= limit; candidate++) + { + int prime = 1; + for (long divisor = 2; divisor * divisor <= candidate; divisor++) + if (candidate % divisor == 0) + { + prime = 0; + break; + } + if (prime) + { + put_int(candidate); + put(" "); + count++; + } + } + put("\n"); + put_int(count); + put(" primes\n"); + } + sys_exit(0); +} diff --git a/user/program.c b/user/program.c deleted file mode 100644 index 65621f5..0000000 --- a/user/program.c +++ /dev/null @@ -1,63 +0,0 @@ -static long sys_write(const char* buffer, unsigned long buffer_length) -{ - long ret; - __asm__ volatile("int $0x80" : "=a"(ret) : "a"(1L), "D"(buffer), "S"(buffer_length) : "memory"); - return ret; -} - -static long sys_read(void) -{ - long ret; - __asm__ volatile("int $0x80" : "=a"(ret) : "a"(2L) : "memory"); - return ret; -} - -static void sys_exit(long code) -{ - __asm__ volatile("int $0x80" : : "a"(0L), "D"(code) : "memory"); - for (;;); -} - -static void put(const char* string) -{ - unsigned long n = 0; - while (string[n]) - n++; - sys_write(string, n); -} - -void _start(void) -{ - put("what's your name? "); - char name[64]; - int name_length = 0; - - for (;;) - { - char character = (char)sys_read(); - if (character == '\n') - break; - - if (character == '\b') - { - if (name_length > 0) - { - name_length--; - sys_write("\b \b", 3); - } - - continue; - } - - if (name_length < 63) - { - name[name_length++] = character; - sys_write(&character, 1); - } - } - - put("\noue va te faire foutre "); - sys_write(name, name_length); - put("\n"); - sys_exit(0); -} diff --git a/user/user.h b/user/user.h new file mode 100644 index 0000000..676326b --- /dev/null +++ b/user/user.h @@ -0,0 +1,97 @@ +// shared syscall stubs + tiny helpers for revel ring 3 programs + +static long sys_write(const char* buffer, unsigned long length) +{ + long result; + __asm__ volatile("int $0x80" : "=a"(result) : "a"(1L), "D"(buffer), "S"(length) : "memory"); + return result; +} + +static long sys_read(void) +{ + long result; + __asm__ volatile("int $0x80" : "=a"(result) : "a"(2L) : "memory"); + return result; +} + +static void sys_exit(long code) +{ + __asm__ volatile("int $0x80" : : "a"(0L), "D"(code) : "memory"); + for (;;); +} + +static long sys_fs_size(const char* name) +{ + long result; + __asm__ volatile("int $0x80" : "=a"(result) : "a"(4L), "D"(name) : "memory"); + return result; +} + +static long sys_fs_read(const char* name, unsigned long offset, char* buffer, unsigned long length) +{ + long result; + __asm__ volatile("int $0x80" + : "=a"(result) + : "a"(5L), "D"(name), "S"(offset), "d"(buffer), "c"(length) + : "memory"); + return result; +} + +static void put(const char* string) +{ + unsigned long length = 0; + while (string[length]) + length++; + sys_write(string, length); +} + +static int read_line(char* buffer, int max_length) +{ + int length = 0; + for (;;) + { + char character = (char)sys_read(); + if (character == '\n') + break; + if (character == '\b') + { + if (length > 0) + { + length--; + sys_write("\b \b", 3); + } + continue; + } + if (length < max_length - 1) + { + buffer[length++] = character; + sys_write(&character, 1); + } + } + buffer[length] = 0; + return length; +} + +static void put_int(long value) +{ + char buffer[21]; + int length = 0; + int negative = value < 0; + unsigned long magnitude = negative ? (unsigned long)(-value) : (unsigned long)value; + if (magnitude == 0) + buffer[length++] = '0'; + while (magnitude > 0) + { + buffer[length++] = (char)('0' + magnitude % 10); + magnitude /= 10; + } + if (negative) + buffer[length++] = '-'; + for (int left = 0, right = length - 1; left < right; left++, right--) + { + char swap = buffer[left]; + buffer[left] = buffer[right]; + buffer[right] = swap; + } + sys_write(buffer, length); +} |
