From 74032daeb88c104c67738774827440f4264b371e Mon Sep 17 00:00:00 2001
From: Joshua Wise <joshua@rebirth.joshuawise.com>
Date: Sun, 14 Dec 2008 00:13:55 -0500
Subject: [PATCH] Add crc32.

---
 TODO                   |  1 +
 aseg-paging/Makefile   |  1 +
 aseg-paging/firstrun.c |  3 +++
 include/crc32.h        | 10 ++++++++++
 lib/crc32.c            | 34 ++++++++++++++++++++++++++++++++++
 video/generic.c        | 13 ++++++-------
 video/text.c           | 23 +++++++++++++++++++++--
 7 files changed, 76 insertions(+), 9 deletions(-)
 create mode 100644 include/crc32.h
 create mode 100644 lib/crc32.c

diff --git a/TODO b/TODO
index 6234244..7a77450 100644
--- a/TODO
+++ b/TODO
@@ -19,3 +19,4 @@ To do list:
 [X] Something has gone very wrong with the receive ring buffer, and on
     occasion, the machine stops receiving forever.
     fixed a few hours later...
+[ ] 'unknown TNT2 format ff', then a hang still happens on occasion
diff --git a/aseg-paging/Makefile b/aseg-paging/Makefile
index 6c0cd76..76af1e4 100644
--- a/aseg-paging/Makefile
+++ b/aseg-paging/Makefile
@@ -54,6 +54,7 @@ OBJS =	../ich2/smi.o \
 	../lib/sprintf.o \
 	../lib/console.o \
 	../lib/serial.o \
+	../lib/crc32.o \
 	keyboard.o \
 	../aseg/packet.o \
 	$(LWIP_OBJS) \
diff --git a/aseg-paging/firstrun.c b/aseg-paging/firstrun.c
index 0233a7c..efa0600 100644
--- a/aseg-paging/firstrun.c
+++ b/aseg-paging/firstrun.c
@@ -7,6 +7,7 @@
 #include <smram.h>
 #include <text.h>
 #include "../net/net.h"
+#include <crc32.h>
 
 extern int _bss, _bssend;
 
@@ -36,6 +37,8 @@ void smi_init() {
 	
 	eth_init();
 	
+	crc32_init();
+	
 	/* After everything is initialized, load drivers. */
 	for (driver = drivers; *driver; driver++)
 	{
diff --git a/include/crc32.h b/include/crc32.h
new file mode 100644
index 0000000..f7d568a
--- /dev/null
+++ b/include/crc32.h
@@ -0,0 +1,10 @@
+#ifndef _CRC32_H
+#define _CRC32_H
+
+#include <stdint.h>
+
+extern uint32_t crc32(unsigned char *buf, int len);
+extern void crc32_init();
+
+#endif
+
diff --git a/lib/crc32.c b/lib/crc32.c
new file mode 100644
index 0000000..fd7bd49
--- /dev/null
+++ b/lib/crc32.c
@@ -0,0 +1,34 @@
+#include <stdint.h>
+
+/* code from http://www.faqs.org/faqs/compression-faq/part1/section-26.html,
+ * presumed public domain */
+
+uint32_t crc32_table[256];
+
+uint32_t crc32(uint8_t *buf, int len)
+{
+	uint8_t *p;
+	uint32_t crc;
+
+	crc = 0xffffffff;       /* preload shift register, per CRC-32 spec */
+	for (p = buf; len > 0; ++p, --len)
+		crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *p];
+	return ~crc;	    /* transmit complement, per CRC-32 spec */
+}
+
+/*
+ * Build auxiliary table for parallel byte-at-a-time CRC-32.
+ */
+#define CRC32_POLY 0x04c11db7     /* AUTODIN II, Ethernet, & FDDI */
+
+void crc32_init()
+{
+	int i, j;
+	uint32_t c;
+
+	for (i = 0; i < 256; ++i) {
+		for (c = i << 24, j = 8; j > 0; --j)
+			c = c & 0x80000000 ? (c << 1) ^ CRC32_POLY : (c << 1);
+		crc32_table[i] = c;
+	}
+}
diff --git a/video/generic.c b/video/generic.c
index 6168df2..d8b320b 100644
--- a/video/generic.c
+++ b/video/generic.c
@@ -1,5 +1,6 @@
 #include <stdint.h>
 #include <fb.h>
+#include <crc32.h>
 
 uint32_t checksum_rect_generic32(int x, int y, int width, int height) {
 
@@ -8,17 +9,15 @@ uint32_t checksum_rect_generic32(int x, int y, int width, int height) {
 	 */
 
         int scanline = fb->curmode.xres * 4;
-        uint32_t * lineaddr;
-        int i, j;
+        unsigned char * lineaddr;
+        int i;
 
         uint32_t sum = 0;
 
         for (i = 0; i < height; i++) {
-                lineaddr = (uint32_t *)(fb->fbaddr + (i + y) * scanline);
+                lineaddr = fb->fbaddr + (i + y) * scanline;
 
-                for (j = 0; j < width; j++) {
-                        sum += lineaddr[j + x];
-                }
+                sum ^= crc32(lineaddr, width * 4);
         }
 
         return sum;
@@ -32,7 +31,7 @@ void copy_pixels_generic32(char *buf, int x, int y, int width, int height)
 	for (cy = y; cy < (y + height); cy++)
 	{
 		fbuf = (unsigned int *)fb->fbaddr;
-		fbuf += y * (fb->curmode.xres) + x;
+		fbuf += cy * (fb->curmode.xres) + x;
 		for (cx = x; cx < (x + width); cx++)
 			*(ibuf++) = *(fbuf++);
 	}
diff --git a/video/text.c b/video/text.c
index 7197bad..e7b0db3 100644
--- a/video/text.c
+++ b/video/text.c
@@ -3,6 +3,8 @@
 #include <paging.h>
 #include <minilib.h>
 #include <stdint.h>
+#include <output.h>
+#include <smram.h>
 
 static unsigned char _font[256 * 32];
 
@@ -11,23 +13,30 @@ static unsigned char _font[256 * 32];
 void text_init()
 {
 	unsigned char oldread;
+	smram_state_t old_state = smram_save_state();
 	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 */);
+	smram_aseg_set_state(SMRAM_ASEG_SMMCODE);
 	memcpy(_font, p2v(0xB8000), sizeof(_font));
+	smram_restore_state(old_state);
 	outb(0x3CF, oldread);
 }
 
 void text_render(char *buf, int x, int y, int w, int h)
 {
-	unsigned char *video = p2v(0xB8000);
+	unsigned char *video = (unsigned char *)0xB8000;
 	unsigned int textx = x / 9;
 	unsigned int texty = y / 14;
 	unsigned int cx, cy;
 	unsigned char ch, at, font;
+	smram_state_t old_state = smram_save_state();
 	
+	outputf("text_render: buf %08x, (%d,%d),(%d,%d)", buf, x, y, w, h);
+	
+	smram_aseg_set_state(SMRAM_ASEG_SMMCODE);
 	for (cy = y; cy < (y + h); cy++)
 	{
 		texty = cy / 14;
@@ -61,16 +70,22 @@ void text_render(char *buf, int x, int y, int w, int h)
 			*(buf++) = 0;
 		}
 	}
+	smram_restore_state(old_state);
 }
 
 uint32_t text_checksum(int x, int y, int w, int h)
 {
-	unsigned char *video = p2v(0xB8000);
+	unsigned char *video = (unsigned char *)0xB8000;
 	unsigned int textx = x / 9;
 	unsigned int texty = y / 14;
 	int cx, cy;
 	unsigned char ch, at;
 	uint32_t cksm = 0;
+	smram_state_t old_state = smram_save_state();
+	
+	outputf("checksum: (%d,%d),(%d,%d)", x,y,w,h);
+	
+	smram_aseg_set_state(SMRAM_ASEG_SMMCODE);
 	
 	for (cy = y; cy < (y + h); cy++)
 	{
@@ -92,5 +107,9 @@ uint32_t text_checksum(int x, int y, int w, int h)
 		}
 	}
 	
+	smram_restore_state(old_state);
+	
+	outputf("checksum: %08x", cksm);
+	
 	return cksm;
 }
-- 
2.43.0