-#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
#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_ */
--- /dev/null
+#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_ */
--- /dev/null
+#include <stdarg.h>
+#include "dbg.h"
+
+void panic(const char *fmt, ...)
+{
+}
--- /dev/null
+#ifndef DBG_H_
+#define DBG_H_
+
+void panic(const char *fmt, ...);
+
+#endif /* DBG_H_ */
--- /dev/null
+#include "dev.h"
+
+struct file *dev_open(int major, int minor, unsigned int flags)
+{
+ return 0; /* TODO */
+}
--- /dev/null
+#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_ */
--- /dev/null
+#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_ */
--- /dev/null
+#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_ */
--- /dev/null
+#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_ */
--- /dev/null
+#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 */
+}
--- /dev/null
+#ifndef STDIO_H_
+#define STDIO_H_
+
+#include "con.h"
+
+#define putchar(c) con_putchar(c)
+
+int printf(const char *fmt, ...);
+
+#endif /* STDIO_H_ */
--- /dev/null
+#include "string.h"
+
+int strlen(const char *s)
+{
+ const char *end = s;
+ while(*end) end++;
+ return end - s;
+}
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_ */
+#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();
}
--- /dev/null
+#include "ser.h"
+
+int ser_init(void)
+{
+ return -1; /* TODO */
+}
--- /dev/null
+#ifndef SER_H_
+#define SER_H_
+
+int ser_init(void);
+
+#endif /* SER_H_ */
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;
static int cur_scroll;
static int mono;
+int vid_type;
+
+
void vid_init(void)
{
detect_video();
void vid_reset(void)
{
- vid_fgcolor(WHITE);
+ vid_fgcolor(LTGREY);
vid_bgcolor(BLACK);
vid_scroll(0);
vid_setcursor(0, 0);
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);
}
}
+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);
#define VID_H_
#include <inttypes.h>
-#include "con.h"
enum {
BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LTGREY,
#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);
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_ */