hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/user
diff options
context:
space:
mode:
Diffstat (limited to 'user')
-rw-r--r--user/calc.c78
-rw-r--r--user/hexview.c91
-rw-r--r--user/primes.c42
-rw-r--r--user/program.c63
-rw-r--r--user/user.h97
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);
+}