diff --git a/ROM2/Makefile b/ROM2/Makefile
index 71e8c7d8281aadf5ceac4dc250cb5a4b4ae84c51..17063d4da4c3a386f5fbdd0ad47d46c29100eac0 100644
--- a/ROM2/Makefile
+++ b/ROM2/Makefile
@@ -41,7 +41,7 @@ rom2.elf: $(OBJS) memory.x
 	$(SIZE) $@
 
 clean:
-	rm -f *.o *.elf *.s19 *.b *.a rom.tar.bz2 romsrc.c
+	rm -f *.o *.elf *.s19 *.b *.a rom.tar.bz2 romsrc.c crctab.h
 
 #
 # Some useful rules
@@ -53,12 +53,20 @@ size:   rom2.s19
 	$(SIZE) $<
 
 rom.tar.bz2:
-	rm -f romsrc.c
+	rm -f romsrc.c crctab.h
 	tar cjf rom.tar.bz2 README Makefile *.c *.h *.s *.x
 
 romsrc.c: rom.tar.bz2
 	perl -w src2c.pl < $< > $@
 
+xmodem.c: crctab.h
+
+gencrctab: gencrctab.c
+	gcc -o $@ $<
+
+crctab.h: gencrctab
+	./gencrctab > $@
+
 #
 # Implicit rules
 #
diff --git a/ROM2/gencrctab.c b/ROM2/gencrctab.c
new file mode 100644
index 0000000000000000000000000000000000000000..e9f9650e565703e2c42a6270f51307360b557270
--- /dev/null
+++ b/ROM2/gencrctab.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#define CRC16 0x1021		/* Generator polynomial (X^16 + X^12 + X^5 + 1) */
+int main() {
+	int val;
+	printf("const u16 crctab[] = {\n\t");
+	for (val = 0; val <= 255; val++) {
+		int i;
+		unsigned int crc;
+		crc = val << 8;
+		for (i = 0; i < 8; i++) {
+			crc <<= 1;
+			if (crc & 0x10000)
+				crc ^= CRC16;
+		}
+		printf("0x%04x,", crc&0xffff);
+		if ((val+1)%8 == 0) printf("\n\t");
+    }
+	printf("};\n");
+	return 0;
+}
diff --git a/ROM2/xmodem.c b/ROM2/xmodem.c
index 7615d9bff363c51e10592ca62f9124804286563c..3aa776a6b795694e4cdebd2511a46dbbff44338c 100644
--- a/ROM2/xmodem.c
+++ b/ROM2/xmodem.c
@@ -21,6 +21,7 @@
 #include "chime.h"
 #include "sci.h"
 #include "xmodem.h"
+#include "crctab.h"
 
 /* These definitions are for xmodem protocol. */
 
@@ -51,28 +52,6 @@ readchar (int timeout)
   return 0;
 }
 
-#define CRC16 0x1021		/* Generator polynomial (X^16 + X^12 + X^5 + 1) */
-
-
-/* Call this to init the fast CRC-16 calculation table.  */
-
-static short crctab(u8 val) {
-      int i;
-      unsigned int crc;
-
-      crc = val << 8;
-
-      for (i = 0; i < 8; ++i)
-	{
-	  crc <<= 1;
-
-	  if (crc & 0x10000)
-	    crc ^= CRC16;
-	}
-
-	  return crc;
-}
-
 /* Calculate a CRC-16 for the LEN byte message pointed at by P.  */
 /* Pads with ^Z if necessary */
 
@@ -83,11 +62,11 @@ docrc (unsigned char *p, int len)
   unsigned short crc = 0;
 
   while (len-- > 0)
-    crc = (crc << 8) ^ crctab((crc >> 8) ^ *p++);
+    crc = (crc << 8) ^ crctab[(crc >> 8) ^ *p++];
   if (len2 < 128) {
     len = 128-len;
     while (len-- > 0)
-      crc = (crc << 8) ^ crctab((crc >> 8) ^ 0x1a);
+      crc = (crc << 8) ^ crctab[(crc >> 8) ^ 0x1a];
   }
 
   return crc;