From cdde55f54a0880bde5694fcdea8e386ada0cd5ce Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 13 Dec 2008 19:50:39 -0500 Subject: [PATCH] Add a first cut at text. --- aseg-paging/Makefile | 1 + aseg-paging/firstrun.c | 4 ++ include/fb.h | 1 + include/text.h | 9 ++++ video/text.c | 95 ++++++++++++++++++++++++++++++++++++++++++ video/tnt2.c | 5 ++- 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 include/text.h create mode 100644 video/text.c diff --git a/aseg-paging/Makefile b/aseg-paging/Makefile index 73d7feb..1eeee83 100644 --- a/aseg-paging/Makefile +++ b/aseg-paging/Makefile @@ -47,6 +47,7 @@ OBJS = ../ich2/smi.o \ ../video/tnt2.o \ ../video/fb.o \ ../video/checksumrect.o \ + ../video/text.o \ drivers.o \ ../lib/minilib.o \ ../lib/doprnt.o \ diff --git a/aseg-paging/firstrun.c b/aseg-paging/firstrun.c index 48a1ac0..0233a7c 100644 --- a/aseg-paging/firstrun.c +++ b/aseg-paging/firstrun.c @@ -5,6 +5,7 @@ #include #include "vga-overlay.h" #include +#include #include "../net/net.h" extern int _bss, _bssend; @@ -43,6 +44,9 @@ void smi_init() { output("Found a card"); } outputf("Driver probe complete"); + + /* Load in fonts. */ + text_init(); smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler); smi_enable_event(SMI_EVENT_FAST_TIMER); diff --git a/include/fb.h b/include/fb.h index 19dae0b..dd86894 100644 --- a/include/fb.h +++ b/include/fb.h @@ -21,6 +21,7 @@ struct vmode { struct fbdevice { unsigned char *fbaddr; + unsigned char *textbase; /* A safe place to put a textfb. */ void *priv; getvmode_t getvmode; checksum_rect_t checksum_rect; diff --git a/include/text.h b/include/text.h new file mode 100644 index 0000000..9506d40 --- /dev/null +++ b/include/text.h @@ -0,0 +1,9 @@ +#ifndef _TEXT_H + +#include + +extern void text_init(); +extern void text_render(unsigned char *buf, unsigned int x, unsigned int y, unsigned int w, unsigned int h); +extern uint32_t text_checksum(int x, int y, int w, int h); + +#endif diff --git a/video/text.c b/video/text.c new file mode 100644 index 0000000..c9068b9 --- /dev/null +++ b/video/text.c @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include + +static unsigned char _font[256 * 32]; + +/* Must be called from a firstrun context, where we don't care about saving + * 0x3CE state. */ +void text_init() +{ + unsigned char oldread; + outb(0x3CE, 0x05 /* Mode register */); + outb(0x3CF, inb(0x3CF) & ~(0x10 /* Odd/even */)); + outb(0x3CE, 0x04 /* Read register */); + oldread = inb(0x3CF); + outb(0x3CF, 0x02 /* Font plane */); + memcpy(_font, p2v(0xB8000), sizeof(_font)); + outb(0x3CF, oldread); +} + +void text_render(unsigned char *buf, unsigned int x, unsigned int y, unsigned int w, unsigned int h) +{ + unsigned char *video = p2v(0xB8000); + unsigned int textx = x / 9; + unsigned int texty = y / 14; + unsigned int cx, cy; + unsigned char ch, at, font; + + for (cy = y; cy < (y + h); cy++) + { + texty = cy / 14; + textx = cx / 9; + ch = video[texty * 50 + textx * 2]; + at = video[texty * 50 + textx * 2 + 1]; + font = _font[ch * 32 + cy % 14]; + for (cx = x; cx < (x + w); cx++) + { + unsigned int pos = cx % 9; + if (pos == 0) + { + textx = cx / 9; + ch = video[texty * 50 + textx * 2]; + at = video[texty * 50 + textx * 2 + 1]; + font = _font[ch * 32 + cy % 14]; + } + /* XXX always BGR888 */ + if (pos == 8) /* 9th pixel is cloned */ + pos = 7; + if ((font >> (7 - pos)) & 1) + { + *(buf++) = (at & 0x01) ? 0xFF : 0x00; + *(buf++) = (at & 0x02) ? 0xFF : 0x00; + *(buf++) = (at & 0x04) ? 0xFF : 0x00; + } else { + *(buf++) = (at & 0x10) ? 0xFF : 0x00; + *(buf++) = (at & 0x20) ? 0xFF : 0x00; + *(buf++) = (at & 0x40) ? 0xFF : 0x00; + } + } + } +} + +uint32_t text_checksum(int x, int y, int w, int h) +{ + unsigned char *video = p2v(0xB8000); + unsigned int textx = x / 9; + unsigned int texty = y / 14; + int cx, cy; + unsigned char ch, at; + uint32_t cksm = 0; + + for (cy = y; cy < (y + h); cy++) + { + texty = cy / 14; + textx = cx / 9; + ch = video[texty * 50 + textx * 2]; + at = video[texty * 50 + textx * 2 + 1]; + for (cx = x; cx < (x + w); cx++) + { + unsigned int pos = cx % 9; + if (pos == 0) + { + textx = cx / 9; + ch = video[texty * 50 + textx * 2]; + at = video[texty * 50 + textx * 2 + 1]; + } + + cksm += ch + (at << 16); + } + } + + return cksm; +} diff --git a/video/tnt2.c b/video/tnt2.c index c79912c..f23a9d7 100644 --- a/video/tnt2.c +++ b/video/tnt2.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "checksumrect.h" @@ -33,11 +34,11 @@ static void tnt2_getvmode(void *priv) break; case 0: tnt2_fb.curmode.text = 1; - tnt2_fb.checksum_rect = (checksum_rect_t) 0; + tnt2_fb.checksum_rect = (checksum_rect_t) text_checksum; break; default: tnt2_fb.curmode.text = 1; - tnt2_fb.checksum_rect = (checksum_rect_t) 0; + tnt2_fb.checksum_rect = (checksum_rect_t) text_checksum; outputf("Unknown TNT2 format %x", vgard(0x28)); break; } -- 2.39.2