started organizing console, rudimentary printf, initial device structure
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 13 Aug 2024 00:03:52 +0000 (03:03 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 13 Aug 2024 00:03:52 +0000 (03:03 +0300)
19 files changed:
kern/src/con.c
kern/src/con.h
kern/src/config.h [new file with mode: 0644]
kern/src/dbg.c [new file with mode: 0644]
kern/src/dbg.h [new file with mode: 0644]
kern/src/dev.c [new file with mode: 0644]
kern/src/dev.h [new file with mode: 0644]
kern/src/file.h [new file with mode: 0644]
kern/src/fs.h [new file with mode: 0644]
kern/src/libc/stdarg.h [new file with mode: 0644]
kern/src/libc/stdio.c [new file with mode: 0644]
kern/src/libc/stdio.h [new file with mode: 0644]
kern/src/libc/string.c [new file with mode: 0644]
kern/src/libc/string.h
kern/src/main.c
kern/src/ser.c [new file with mode: 0644]
kern/src/ser.h [new file with mode: 0644]
kern/src/vid.c
kern/src/vid.h

index 8b5a244..633462e 100644 (file)
-#if 0
-#include "con.h"
-
-
-
-#define NCOLS                  80
-#define NROWS                  25
-
-/* must be pow2 */
-#define TEXTBUF_SIZE   256
-
-static char textbuf[TEXTBUF_SIZE][NCOLS];
-static int tbuf_first, tbuf_last;
+#include "config.h"
 
-static int curx, cury, scroll;
-
-#define CURSTACK_SIZE  16
-static unsigned int savecur[CURSTACK_SIZE];
-static int savecur_top;
-
-
-static void newline(void);
+#include "con.h"
+#include "dev.h"
+#include "vid.h"
+#include "dbg.h"
 
+static struct file *devfile;
 
 void con_init(void)
 {
-       con_reset();
-}
-
-void con_reset(void)
-{
-       vga_reset();
-
-       curx = cury = scroll = 0;
-       tbuf_first = tbuf_last = 0;
-       memset(textbuf[0], 0, sizeof textbuf[0]);
-
-       savecur_top = 0;
-}
-
-void con_setcur(int x, int y)
-{
-       curx = x < 0 ? 0 : (x >= NCOLS ? NCOLS - 1 : x);
-       cury = y < 0 ? 0 : (y >= NROWS ? NROWS - 1 : y);
-}
-
-void con_getcur(int *x, int *y)
-{
-       *x = curx;
-       *y = cury;
-}
-
-void con_pushcur(void)
-{
-       if(savecur_top >= CURSTACK_SIZE) return;
-
-       savecur[savecur_top++] = curx | (cury << 16);
-}
-
-void con_popcur(void)
-{
-       if(savecur_top <= 0) return;
-
-       savecur_top--;
-       curx = savecur[savecur_top] & 0xffff;
-       cury = savecur[savecur_top] >> 16;
+       if(!(devfile = dev_open(CONDEV, 0, O_RDWR))) {
+               panic("can't open console device %d,%d\n", CONDEV, 0);
+       }
 }
 
-void con_putchar(int c)
+void con_printf(const char *fmt, ...)
 {
-       switch(c) {
-       case '\t':
-               curx = (curx + 8) & 0xfffffff8;
-               if(curx >= NCOLS) {
-                       newline();
-               }
-               break;
-
-       case '\r':
-               curx = 0;
-               break;
-
-       case '\n':
-               newline();
-               break;
-
-       case '\b':
-               if(curx > 0) {
-                       textbuf[tbuf_last][--curx] = 0;
-                       vga_drawchar(curx, cury, 0);
-               }
-               break;
-
-       default:
-               textbuf[tbuf_last][curx] = c;
-               vga_drawchar(curx, cury, c);
-               if(++curx >= NCOLS) {
-                       newline();
-               }
-               break;
-       }
-
-       if(cury >= NROWS) {
-               cury--;
-               vga_scroll(++scroll);
-               vga_clearline(NROWS - 1);
+       /* TODO */
+       while(*fmt) {
+               con_putchar(*fmt++);
        }
-
-       vid_set_cursor(curx, cury);
 }
 
-static void newline(void)
+void con_putchar(int c)
 {
-       int num;
-
-       curx = 0;
-       cury++;
-
-       num = (tbuf_last + 1) & (TEXTBUF_SIZE - 1);
-
-       if(tbuf_last == tbuf_first) {
-               tbuf_first = num;
+       if(devfile) {
+               devfile->dev->fop->write(devfile, &c, 1);
+       } else {
+               vid_putchar(c);
        }
-       tbuf_last = num;
 }
-#endif
index b5f8545..e6eee5f 100644 (file)
@@ -1,24 +1,9 @@
 #ifndef CON_H_
 #define CON_H_
 
-struct console {
-       void (*clear)(void*);
-       void (*putc)(void*, int c);
-
-       void *data;
-};
-
-void con_init(struct console *con);
-
-void con_reset(struct console *con);
-void con_setcolor(struct console *con, int fg, int bg);
-
-void con_setcur(struct console *con, int x, int y);
-void con_getcur(struct console *con, int *x, int *y);
-void con_pushcur(struct console *con);
-void con_popcur(struct console *con);
-
-void con_putchar(struct console *con, int c);
+void con_init(void);
 
+void con_printf(const char *fmt, ...);
+void con_putchar(int c);
 
 #endif /* CON_H_ */
diff --git a/kern/src/config.h b/kern/src/config.h
new file mode 100644 (file)
index 0000000..d46832b
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef CONFIG_H_
+#define CONFIG_H_
+
+#define VERSTR         "v0.0"
+
+/* CONDEV: which device to use for the kernel console (DEV_VID or DEV_SER) */
+#define CONDEV         DEV_VID
+
+#endif /* CONFIG_H_ */
diff --git a/kern/src/dbg.c b/kern/src/dbg.c
new file mode 100644 (file)
index 0000000..ad4c57a
--- /dev/null
@@ -0,0 +1,6 @@
+#include <stdarg.h>
+#include "dbg.h"
+
+void panic(const char *fmt, ...)
+{
+}
diff --git a/kern/src/dbg.h b/kern/src/dbg.h
new file mode 100644 (file)
index 0000000..acf7d3e
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef DBG_H_
+#define DBG_H_
+
+void panic(const char *fmt, ...);
+
+#endif /* DBG_H_ */
diff --git a/kern/src/dev.c b/kern/src/dev.c
new file mode 100644 (file)
index 0000000..e0635cf
--- /dev/null
@@ -0,0 +1,6 @@
+#include "dev.h"
+
+struct file *dev_open(int major, int minor, unsigned int flags)
+{
+       return 0;       /* TODO */
+}
diff --git a/kern/src/dev.h b/kern/src/dev.h
new file mode 100644 (file)
index 0000000..1f5a883
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef DEV_H_
+#define DEV_H_
+
+#include "file.h"
+
+struct device {
+       struct fileops *fop;
+};
+
+#define MAX_DEVICES            32
+
+#define DEV_VID                0
+#define DEV_SER                1
+
+struct file *dev_open(int major, int minor, unsigned int flags);
+
+#endif /* DEV_H_ */
diff --git a/kern/src/file.h b/kern/src/file.h
new file mode 100644 (file)
index 0000000..4bff2c6
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef FILE_H_
+#define FILE_H_
+
+#include "fs.h"
+
+struct device;
+
+struct file {
+       int type;
+       struct device *dev;
+       int cur_rd, cur_wr;
+};
+
+struct fileops {
+       struct file *(*open)(int inum, unsigned int flags);
+       int (*close)(struct file*);
+       int (*read)(struct file*, void*, int);
+       int (*write)(struct file*, void*, int);
+       int (*ioctl)(struct file*, int, void*, int);
+};
+
+
+#endif /* FILE_H_ */
diff --git a/kern/src/fs.h b/kern/src/fs.h
new file mode 100644 (file)
index 0000000..9ec56f9
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef FS_H_
+#define FS_H_
+
+#define O_RD   1
+#define O_WR   2
+#define O_RDWR (O_RD | O_WR)
+
+struct inode {
+       int inum;
+       int mode;
+       int user, group;
+       int dev_major, dev_minor;
+};
+
+#endif /* FS_H_ */
diff --git a/kern/src/libc/stdarg.h b/kern/src/libc/stdarg.h
new file mode 100644 (file)
index 0000000..bb589db
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef STDARG_H_
+#define STDARG_H_
+
+typedef char *va_list;
+
+#define va_start(ap, last)     ((ap) = (va_list)&(last))
+#define va_arg(ap, type)       ((ap) += sizeof(type), *(type*)(ap))
+#define va_end(ap)
+#define va_copy(dest, src)     ((dest) = (src))
+
+#endif /* STDARG_H_ */
diff --git a/kern/src/libc/stdio.c b/kern/src/libc/stdio.c
new file mode 100644 (file)
index 0000000..5c52d56
--- /dev/null
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+struct outbuf {
+       char *buf;
+       int cur, size;
+};
+
+#define FMT_LONG       1
+#define FMT_RALIGN     2
+
+struct format {
+       int active;
+       int fwidth, fchar;
+       int base;
+       unsigned int flags;
+};
+
+static void reset_format(struct format *fmt);
+static int intern_vprintf(struct outbuf *outbuf, const char *fmt, va_list ap);
+static void wrchar(struct outbuf *outbuf, int c);
+static int wrstr(struct outbuf *outbuf, struct format *fmt, const char *s);
+static int wrint(struct outbuf *outbuf, struct format *fmt, long val);
+static int wruint(struct outbuf *outbuf, struct format *fmt, unsigned long val);
+
+int printf(const char *fmt, ...)
+{
+       int res;
+       va_list ap;
+
+       va_start(ap, fmt);
+       res = intern_vprintf(0, fmt, ap);
+       va_end(ap);
+       return res;
+}
+
+static void reset_format(struct format *fmt)
+{
+       memset(fmt, 0, sizeof *fmt);
+       fmt->fchar = ' ';
+}
+
+static int intern_vprintf(struct outbuf *outbuf, const char *fmtstr, va_list ap)
+{
+       int c, count = 0;
+       char *str;
+       long val;
+       unsigned long uval;
+       struct format fmt;
+
+       reset_format(&fmt);
+
+       while((c = *fmtstr++)) {
+               if(!fmt.active) {
+                       if(c == '%') {
+                               fmt.active = 1;
+                       } else {
+                               wrchar(outbuf, c); count++;
+                       }
+               } else {
+                       /* have already started a format string */
+                       switch(c) {
+                       case '%':
+                               wrchar(outbuf, '%'); count++;
+                               reset_format(&fmt);
+                               break;
+
+                       case 'd':
+                               if(fmt.flags & FMT_LONG) {
+                                       val = va_arg(ap, long);
+                               } else {
+                                       val = va_arg(ap, int);
+                               }
+                               count += wrint(outbuf, &fmt, val);
+                               reset_format(&fmt);
+                               break;
+
+                       case 'x':
+                               fmt.base = 16;
+                       case 'u':
+                               if(fmt.flags & FMT_LONG) {
+                                       uval = va_arg(ap, unsigned long);
+                               } else {
+                                       uval = va_arg(ap, unsigned int);
+                               }
+                               count += wrint(outbuf, &fmt, uval);
+                               reset_format(&fmt);
+                               break;
+
+                       case 's':
+                               str = va_arg(ap, char*);
+                               count += wrstr(outbuf, &fmt, str);
+                               reset_format(&fmt);
+                               break;
+
+                       default:
+                               /* TODO: more format specifiers */
+                               reset_format(&fmt);
+                               break;
+                       }
+               }
+       }
+
+       return count;
+}
+
+static void wrchar(struct outbuf *outbuf, int c)
+{
+       if(outbuf && outbuf->buf) {
+               if(outbuf->cur < outbuf->size) {
+                       outbuf->buf[outbuf->cur++] = c;
+               }
+       } else {
+               putchar(c);
+       }
+}
+
+static int wrstr(struct outbuf *outbuf, struct format *fmt, const char *s)
+{
+       int count = 0;
+       int len;
+
+       if(fmt->flags & FMT_RALIGN) {
+               len = strlen(s);
+               while(len-- < fmt->fwidth) {
+                       wrchar(outbuf, fmt->fchar);
+                       count++;
+               }
+       }
+       while(*s) {
+               wrchar(outbuf, *s++);
+               count++;
+       }
+       return count;
+}
+
+static int wrint(struct outbuf *outbuf, struct format *fmt, long val)
+{
+       return 0;       /* TODO */
+}
+
+static int wruint(struct outbuf *outbuf, struct format *fmt, unsigned long val)
+{
+       return 0;       /* TODO */
+}
diff --git a/kern/src/libc/stdio.h b/kern/src/libc/stdio.h
new file mode 100644 (file)
index 0000000..075715c
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef STDIO_H_
+#define STDIO_H_
+
+#include "con.h"
+
+#define putchar(c)     con_putchar(c)
+
+int printf(const char *fmt, ...);
+
+#endif /* STDIO_H_ */
diff --git a/kern/src/libc/string.c b/kern/src/libc/string.c
new file mode 100644 (file)
index 0000000..8b5325a
--- /dev/null
@@ -0,0 +1,8 @@
+#include "string.h"
+
+int strlen(const char *s)
+{
+       const char *end = s;
+       while(*end) end++;
+       return end - s;
+}
index 46dd696..4c4df55 100644 (file)
@@ -6,4 +6,6 @@
 void *memset(void *s, int c, size_t n);
 void __far *fmemset(void __far *s, int c, size_t n);
 
+int strlen(const char *s);
+
 #endif /* STRING_H_ */
index cc3cd14..b59e371 100644 (file)
@@ -1,9 +1,18 @@
+#include "config.h"
+
+#include <stdio.h>
 #include "intr.h"
 #include "vid.h"
+#include "ser.h"
+#include "con.h"
 
 void kmain(void)
 {
        vid_init();
-       vid_text(0, 0, "hello!", VID_ATTR(LTRED, BLACK));
+       ser_init();
+       con_init();
+
+       printf("eightysix kernel %s\n", VERSTR);
+
        init_intr();
 }
diff --git a/kern/src/ser.c b/kern/src/ser.c
new file mode 100644 (file)
index 0000000..2c6fd74
--- /dev/null
@@ -0,0 +1,6 @@
+#include "ser.h"
+
+int ser_init(void)
+{
+       return -1;      /* TODO */
+}
diff --git a/kern/src/ser.h b/kern/src/ser.h
new file mode 100644 (file)
index 0000000..0a1f418
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef SER_H_
+#define SER_H_
+
+int ser_init(void);
+
+#endif /* SER_H_ */
index 25c7cf1..5cbe7b2 100644 (file)
@@ -17,8 +17,6 @@ static int detect_egainfo(void);
 static void detect_eqlist(void);
 static void crtc_write(int reg, unsigned char val);
 
-//struct console con_vid = { con_clear, con_putc, 0 };
-
 static uint16_t __far *vmem;
 static int iobase;
 
@@ -27,6 +25,9 @@ static int cur_x, cur_y;
 static int cur_scroll;
 static int mono;
 
+int vid_type;
+
+
 void vid_init(void)
 {
        detect_video();
@@ -145,7 +146,7 @@ static void detect_eqlist(void)
 
 void vid_reset(void)
 {
-       vid_fgcolor(WHITE);
+       vid_fgcolor(LTGREY);
        vid_bgcolor(BLACK);
        vid_scroll(0);
        vid_setcursor(0, 0);
@@ -209,7 +210,7 @@ void vid_bgcolor(int color)
        cur_attr = (cur_attr & 0x0f) | (color << 4);
 }
 
-void vid_glyph(int x, int y, int c, int attr)
+void vid_char(int x, int y, int c, int attr)
 {
        uint16_t __far *ptr;
        uint16_t val = c | (attr << 8);
@@ -249,6 +250,43 @@ void vid_text(int x, int y, const char *s, int attr)
        }
 }
 
+void vid_putchar(int c)
+{
+       int x;
+
+       switch(c) {
+       case '\r':
+               vid_setcursor(0, cur_y);
+               break;
+
+       case '\n':
+               if(cur_y >= cur_scroll + 25) {
+                       vid_scroll(cur_scroll + 1);
+                       vid_setcursor(0, cur_y);
+               } else {
+                       vid_setcursor(0, cur_y + 1);
+               }
+               break;
+
+       case '\t':
+               x = (cur_x + 8) & 0xf8;
+               if(x >= 80) {
+                       vid_putchar('\n');
+               } else {
+                       vid_setcursor(x, cur_y);
+               }
+               break;
+
+       default:
+               vid_char(cur_x, cur_y, c, cur_attr);
+               if(cur_x + 1 >= 80) {
+                       vid_putchar('\n');
+               } else {
+                       vid_setcursor(cur_x + 1, cur_y);
+               }
+       }
+}
+
 static void crtc_write(int reg, unsigned char val)
 {
        outp(CRTC_ADDR_PORT, reg);
index 6b3d678..e118ead 100644 (file)
@@ -2,7 +2,6 @@
 #define VID_H_
 
 #include <inttypes.h>
-#include "con.h"
 
 enum {
        BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LTGREY,
@@ -13,8 +12,7 @@ enum { VID_UNK, VID_MDA, VID_CGA, VID_EGA, VID_PGA, VID_MCGA, VID_VGA };
 
 #define VID_ATTR(fg, bg)       (((uint8_t)(bg) << 4) | ((uint8_t)(fg)))
 
-extern struct console con_vid;
-int vid_type;
+extern int vid_type;
 
 void vid_init(void);
 void vid_reset(void);
@@ -27,7 +25,9 @@ void vid_setcursor(int x, int y);
 void vid_fgcolor(int color);
 void vid_bgcolor(int color);
 
-void vid_glyph(int x, int y, int c, int attr);
+void vid_char(int x, int y, int c, int attr);
 void vid_text(int x, int y, const char *s, int attr);
 
+void vid_putchar(int c);
+
 #endif /* VID_H_ */