CC = ia16-elf-gcc
LD = ia16-elf-ld
-CFLAGS = -march=i8088 -mtune=i8088 -MMD
+warn = -pedantic -Wall
+inc = -nostdinc -Isrc -Isrc/libc
+
+CFLAGS = -march=i8088 -mtune=i8088 $(warn) $(inc) -MMD
LDFLAGS = -T kern.ld -Map kern.map
$(img): $(bin)
#define FP_SEG(x) ((uint16_t)((uint32_t)(x) >> 16))
#define FP_OFFS(x) ((uint16_t)(x))
-#define MK_FP(s, o) (((uint32_t)(s) << 16) | (uint32_t)(o))
+#define MK_FP(s, o) (void __far*)(((uint32_t)(s) << 16) | (uint32_t)(o))
#define enable() asm("sti")
#define disable() asm("cli")
struct console {
void (*clear)(void*);
- void (*putc)(void*, char c);
+ 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);
+
+
#endif /* CON_H_ */
+++ /dev/null
-#include "disp.h"
-#include "asmutil.h"
-
-static void detect_video(void);
-static int detect_vgainfo(void);
-static int detect_egainfo(void);
-static void detect_eqlist(void);
-
-struct console con_disp = { clear_disp, disp_putc, 0 };
-
-static uint16_t __far *vmem;
-static uint16_t cur_attr;
-static int cur_x, cur_y;
-static int cur_scroll;
-static int mono;
-
-void init_disp(void)
-{
- detect_video();
-}
-
-static void detect_video(void)
-{
- mono = 0;
- disp_type = DISP_UNK;
-
- if(detect_vgainfo() == 0) {
- goto done;
- }
- if(detect_egainfo() == 0) {
- goto done;
- }
- detect_eqlist();
-
-done:
- vmem = mono ? MK_FP(0xb000, 0) : MK_FP(0xb800, 0);
-}
-
-static int detect_vgainfo(void)
-{
- union regs regs;
-
- regs.w.ax = 0x1a00;
- int86(0x10, ®s, ®s);
- if(regs.h.al != 0x1a) {
- return -1;
- }
-
- switch(regs.h.bl) {
- case 1:
- disp_type = DISP_MDA;
- mono = 1;
- break;
- case 2:
- disp_type = DISP_CGA;
- break;
- case 4:
- disp_type = DISP_EGA;
- break;
- case 5:
- disp_type = DISP_EGA;
- mono = 1;
- break;
- case 6:
- disp_type = DISP_PGA;
- break;
- case 7:
- disp_type = DISP_VGA;
- mono = 1;
- break;
- case 8:
- disp_type = DISP_VGA;
- break;
- case 0xa:
- case 0xc:
- disp_type = DISP_MCGA;
- break;
- case 0xb:
- disp_type = DISP_MCGA;
- mono = 1;
- break;
- default:
- return -1;
- }
- return 0;
-}
-
-static int detect_egainfo(void)
-{
- union regs regs;
-
- regs.w.ax = 0x1200;
- regs.w.bx = 0xff10;
- int86(0x10, ®s, ®s);
- if(regs.h.bh == 0xff) {
- return -1;
- }
-
- disp_type = DISP_EGA;
- mono = regs.h.bh;
- return 0;
-}
-
-static void detect_eqlist(void)
-{
- union regs regs;
-
- int86(0x11, ®s, ®s);
- switch(regs.w.ax & 0x30) {
- case 0:
- disp_type = DISP_EGA;
- break;
-
- case 0x10:
- case 0x20:
- disp_type = DISP_CGA;
- break;
-
- case 0x30:
- disp_type = DISP_MDA;
- mono = 1;
- break;
- }
-}
-
-void clear_disp(void)
-{
-}
-
-void scroll_disp(int line)
-{
-}
-
-void set_cursor(int x, int y)
-{
- cur_x = x;
- cur_y = y;
-}
-
-void set_fgcolor(int color)
-{
- cur_attr = (cur_attr & 0xf0) | color;
-}
-
-void set_bgcolor(int color)
-{
- cur_attr = (cur_attr & 0x0f) | (color << 4);
-}
-
-void draw_glyph(int x, int y, int c, int attr)
-{
- vmem[y * 80 + x] = (uint16_t)c | ((uint16_t)attr << 8);
-}
-
-void draw_text(int x, int y, const char *s, int attr)
-{
- uint16_t __far *ptr = vmem + y * 80 + x;
-
- while(*s) {
- *ptr++ = (uint16_t)*s++ | ((uint16_t)attr << 8);
- }
-}
-
-
+++ /dev/null
-#ifndef DISP_H_
-#define DISP_H_
-
-#include <inttypes.h>
-#include "con.h"
-
-enum {
- BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LTGREY,
- GREY, LTBLUE, LTGREEN, LTCYAN, LTRED, LTMAGENTA, YELLOW, WHITE
-};
-
-enum { DISP_UNK, DISP_MDA, DISP_CGA, DISP_EGA, DISP_PGA, DISP_MCGA, DISP_VGA };
-
-#define DISP_ATTR(fg, bg) (((uint8_t)(bg) << 4) | ((uint8_t)(fg)))
-
-extern struct console con_disp;
-int disp_type;
-
-void init_disp(void);
-
-void clear_disp(void);
-void scroll_disp(int line);
-
-void set_cursor(int x, int y);
-void set_fgcolor(int color);
-void set_bgcolor(int color);
-
-void draw_glyph(int x, int y, int c, int attr);
-void draw_text(int x, int y, const char *s, int attr);
-
-#endif /* DISP_H_ */
typedef unsigned short uint16_t;
typedef unsigned long uint32_t;
+typedef int ssize_t;
+typedef unsigned int size_t;
+
#endif /* KLIBC_INTTYPES_H_ */
--- /dev/null
+#ifndef STRING_H_
+#define STRING_H_
+
+#include <inttypes.h>
+
+void *memset(void *s, int c, size_t n);
+void __far *fmemset(void __far *s, int c, size_t n);
+
+#endif /* STRING_H_ */
--- /dev/null
+#include <string.h>
+#include "vid.h"
+#include "asmutil.h"
+
+#define CRTC_ADDR_PORT (iobase | 4)
+#define CRTC_DATA_PORT (iobase | 5)
+
+/* CRTC registers */
+#define CRTC_START_H 0x0c
+#define CRTC_START_L 0x0d
+#define CRTC_CURPOS_H 0x0e
+#define CRTC_CURPOS_L 0x0f
+
+static void detect_video(void);
+static int detect_vgainfo(void);
+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;
+
+static uint16_t cur_attr;
+static int cur_x, cur_y;
+static int cur_scroll;
+static int mono;
+
+void vid_init(void)
+{
+ detect_video();
+ if(mono) {
+ vmem = MK_FP(0xb000, 0);
+ iobase = 0x3b0;
+ } else {
+ vmem = MK_FP(0xb800, 0);
+ iobase = 0x3d0;
+ }
+
+ vid_reset();
+}
+
+static void detect_video(void)
+{
+ mono = 0;
+ vid_type = VID_UNK;
+
+ if(detect_vgainfo() == 0) {
+ return;
+ }
+ if(detect_egainfo() == 0) {
+ return;
+ }
+ detect_eqlist();
+}
+
+static int detect_vgainfo(void)
+{
+ union regs regs;
+
+ regs.w.ax = 0x1a00;
+ int86(0x10, ®s, ®s);
+ if(regs.h.al != 0x1a) {
+ return -1;
+ }
+
+ switch(regs.h.bl) {
+ case 1:
+ vid_type = VID_MDA;
+ mono = 1;
+ break;
+ case 2:
+ vid_type = VID_CGA;
+ break;
+ case 4:
+ vid_type = VID_EGA;
+ break;
+ case 5:
+ vid_type = VID_EGA;
+ mono = 1;
+ break;
+ case 6:
+ vid_type = VID_PGA;
+ break;
+ case 7:
+ vid_type = VID_VGA;
+ mono = 1;
+ break;
+ case 8:
+ vid_type = VID_VGA;
+ break;
+ case 0xa:
+ case 0xc:
+ vid_type = VID_MCGA;
+ break;
+ case 0xb:
+ vid_type = VID_MCGA;
+ mono = 1;
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+static int detect_egainfo(void)
+{
+ union regs regs;
+
+ regs.w.ax = 0x1200;
+ regs.w.bx = 0xff10;
+ int86(0x10, ®s, ®s);
+ if(regs.h.bh == 0xff) {
+ return -1;
+ }
+
+ vid_type = VID_EGA;
+ mono = regs.h.bh;
+ return 0;
+}
+
+static void detect_eqlist(void)
+{
+ union regs regs;
+
+ int86(0x11, ®s, ®s);
+ switch(regs.w.ax & 0x30) {
+ case 0:
+ vid_type = VID_EGA;
+ break;
+
+ case 0x10:
+ case 0x20:
+ vid_type = VID_CGA;
+ break;
+
+ case 0x30:
+ vid_type = VID_MDA;
+ mono = 1;
+ break;
+ }
+}
+
+void vid_reset(void)
+{
+ vid_fgcolor(WHITE);
+ vid_bgcolor(BLACK);
+ vid_scroll(0);
+ vid_setcursor(0, 0);
+ fmemset(vmem, 0, 80 * 25 * 2);
+}
+
+void vid_clearline(int row)
+{
+ int i;
+ uint16_t __far *ptr;
+
+ row += cur_scroll;
+
+ ptr = vmem + row * 80;
+ for(i=0; i<80; i++) {
+ ptr[i] = cur_attr;
+ }
+
+ if(row - 32 >= 0) {
+ /* write a copy to wrap-around future scrolling */
+ ptr -= 80 * 32;
+ for(i=0; i<80; i++) {
+ ptr[i] = cur_attr;
+ }
+ }
+}
+
+void vid_clear(void)
+{
+ int i;
+ for(i=0; i<25; i++) {
+ vid_clearline(i);
+ }
+}
+
+void vid_scroll(int line)
+{
+ int offs;
+ cur_scroll = line & 0x1f;
+ offs = cur_scroll * 80;
+ crtc_write(CRTC_START_H, offs >> 8);
+ crtc_write(CRTC_START_L, offs);
+}
+
+void vid_setcursor(int x, int y)
+{
+ int loc = (y + cur_scroll) * 80 + x;
+ cur_x = x;
+ cur_y = y;
+ crtc_write(CRTC_CURPOS_H, loc >> 8);
+ crtc_write(CRTC_CURPOS_L, loc);
+}
+
+void vid_fgcolor(int color)
+{
+ cur_attr = (cur_attr & 0xf0) | color;
+}
+
+void vid_bgcolor(int color)
+{
+ cur_attr = (cur_attr & 0x0f) | (color << 4);
+}
+
+void vid_glyph(int x, int y, int c, int attr)
+{
+ uint16_t __far *ptr;
+ uint16_t val = (c & 0xff) | attr;
+
+ y += cur_scroll;
+
+ ptr = vmem + y * 80 + x;
+ *ptr = val;
+
+ if(y - 32 >= 0) {
+ /* write a copy to wrap-around future scrolling */
+ ptr -= 80 * 32;
+ *ptr = val;
+ }
+}
+
+void vid_text(int x, int y, const char *s, int attr)
+{
+ int len = 0;
+ uint16_t __far *ptr;
+
+ y += cur_scroll;
+
+ ptr = vmem + y * 80 + x;
+ while(*s) {
+ *ptr++ = (*s++ & 0xff) | attr;
+ len++;
+ }
+
+ if(y - 32 >= 0) {
+ /* write a copy to wrap-around future scrolling */
+ ptr -= 80 * 32 + len;
+ s -= len;
+ while(*s) {
+ *ptr++ = (*s++ & 0xff) | attr;
+ }
+ }
+}
+
+static void crtc_write(int reg, unsigned char val)
+{
+ outp(CRTC_ADDR_PORT, reg);
+ outp(CRTC_DATA_PORT, val);
+}
--- /dev/null
+#ifndef VID_H_
+#define VID_H_
+
+#include <inttypes.h>
+#include "con.h"
+
+enum {
+ BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LTGREY,
+ GREY, LTBLUE, LTGREEN, LTCYAN, LTRED, LTMAGENTA, YELLOW, WHITE
+};
+
+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;
+
+void vid_init(void);
+void vid_reset(void);
+
+void vid_clearline(int row);
+void vid_clear(void);
+void vid_scroll(int line);
+
+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_text(int x, int y, const char *s, int attr);
+
+#endif /* VID_H_ */