*/
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
#include "contty.h"
#include "serial.h"
#include "asmops.h"
#define CRTC_REG_CURLOC_L 0x0f
#define VMEM_CHAR(c, attr) \
- ((uint16_t)(c) | ((uint16_t)(attr) << 8))
+ (((uint16_t)(c) & 0xff) | ((uint16_t)(attr) << 8))
static void scroll(void);
static void crtc_cursor(int x, int y);
static void crtc_setstart(int y);
static inline unsigned char crtc_read(int reg);
static inline void crtc_write(int reg, unsigned char val);
-static inline void crtc_write_bits(int reg, unsigned char val, unsigned char mask);
extern int cursor_x, cursor_y;
static unsigned char txattr = 0x07;
static int start_line;
+static unsigned char cy0, cy1;
+static int curvis;
+static int scr_on = 1;
int con_init(void)
{
#endif
#ifdef CON_TEXTMODE
+ cy0 = crtc_read(CRTC_REG_CURSTART);
+ curvis = cy0 & 0x20 ? 1 : 0;
+ cy0 &= 0x1f;
+ cy1 = crtc_read(CRTC_REG_CUREND) & 0x1f;
+
con_show_cursor(1);
crtc_setstart(0);
crtc_cursor(cursor_x, cursor_y);
- /*
- printf("curloc: %x %x\n", (unsigned int)crtc_read(CRTC_REG_CURLOC_H),
- (unsigned int)crtc_read(CRTC_REG_CURLOC_L));
- printf("curstart: %x\n", (unsigned int)crtc_read(CRTC_REG_CURSTART));
- printf("curend: %x\n", (unsigned int)crtc_read(CRTC_REG_CUREND));
- */
+ scr_on = 1;
#endif
return 0;
}
+void con_scr_enable(void)
+{
+ scr_on = 1;
+}
+
+void con_scr_disable(void)
+{
+ scr_on = 0;
+}
+
void con_show_cursor(int show)
{
#ifdef CON_TEXTMODE
- unsigned char val = show ? 0 : 0x20;
-
- crtc_write_bits(CRTC_REG_CURSTART, val, 0x20);
+ unsigned char val = cy0 & 0x1f;
+ if(!show) {
+ val |= 0x20;
+ }
+ crtc_write(CRTC_REG_CURSTART, val);
+ curvis = show;
#endif
}
#endif
}
+void con_curattr(int shape, int blink)
+{
+#ifdef CON_TEXTMODE
+ unsigned char start;
+ cy0 = (shape == CON_CURSOR_LINE) ? 0xd : 0;
+ cy1 = 0xe;
+
+ start = cy0;
+ if(curvis) {
+ start |= 0x20;
+ }
+
+ crtc_write(CRTC_REG_CURSTART, start);
+ crtc_write(CRTC_REG_CUREND, cy0);
+#endif
+}
+
void con_fgcolor(int c)
{
txattr = (txattr & 0xf0) | c;
txattr = (txattr & 0x0f) | (c << 4);
}
+void con_setattr(unsigned char attr)
+{
+ txattr = attr;
+}
+
+unsigned char con_getattr(void)
+{
+ return txattr;
+}
+
void con_clear(void)
{
#ifdef CON_TEXTMODE
- memset(TEXT_ADDR, 0, NCOLS * NROWS * 2);
+ memset16(TEXT_ADDR, VMEM_CHAR(' ', txattr), NCOLS * NROWS);
start_line = 0;
crtc_setstart(0);
void con_putchar(int c)
{
#ifdef CON_TEXTMODE
- uint16_t *ptr;
-
- switch(c) {
- case '\n':
- linefeed();
- case '\r':
- cursor_x = 0;
- crtc_cursor(cursor_x, cursor_y);
- break;
-
- case '\t':
- cursor_x = (cursor_x & 0x7) + 8;
- if(cursor_x >= NCOLS) {
+ if(scr_on) {
+ switch(c) {
+ case '\n':
linefeed();
+ case '\r':
cursor_x = 0;
+ crtc_cursor(cursor_x, cursor_y);
+ break;
+
+ case '\t':
+ cursor_x = (cursor_x & 0x7) + 8;
+ if(cursor_x >= NCOLS) {
+ linefeed();
+ cursor_x = 0;
+ }
+ crtc_cursor(cursor_x, cursor_y);
+ break;
+
+ case '\b':
+ if(cursor_x > 0) cursor_x--;
+ con_putchar_scr(cursor_x, cursor_y, ' ');
+ crtc_cursor(cursor_x, cursor_y);
+ break;
+
+ default:
+ con_putchar_scr(cursor_x, cursor_y, c);
+
+ if(++cursor_x >= NCOLS) {
+ linefeed();
+ cursor_x = 0;
+ }
+ crtc_cursor(cursor_x, cursor_y);
}
- crtc_cursor(cursor_x, cursor_y);
- break;
-
- default:
- ptr = (uint16_t*)TEXT_ADDR;
- ptr[(cursor_y + start_line) * NCOLS + cursor_x] = VMEM_CHAR(c, txattr);
-
- if(++cursor_x >= NCOLS) {
- linefeed();
- cursor_x = 0;
- }
- crtc_cursor(cursor_x, cursor_y);
}
#endif
#endif
}
+void con_putchar_scr(int x, int y, int c)
+{
+#ifdef CON_TEXTMODE
+ uint16_t *ptr = (uint16_t*)TEXT_ADDR;
+ ptr[(y + start_line) * NCOLS + x] = VMEM_CHAR(c, txattr);
+#endif
+}
+
+int con_printf(int x, int y, const char *fmt, ...)
+{
+#ifdef CON_TEXTMODE
+ va_list ap;
+ char buf[81];
+ char *ptr = buf;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, 80, fmt, ap);
+ va_end(ap);
+
+ while(*ptr && x < 80) {
+ con_putchar_scr(x++, y, *ptr++);
+ }
+ return ptr - buf;
+#else
+ return 0;
+#endif
+}
+
static void scroll(void)
{
int new_line;
outb(reg, CRTC_ADDR);
outb(val, CRTC_DATA);
}
-
-static inline void crtc_write_bits(int reg, unsigned char val, unsigned char mask)
-{
- unsigned char prev;
- outb(reg, CRTC_ADDR);
- prev = inb(CRTC_DATA);
- val = (prev & ~mask) | (val & mask);
- outb(val, CRTC_DATA);
-}