]> 4ch.mooo.com Git - 16.git/commitdiff
added tweak16 for experiments
authorsparky4 <sparky4@cock.li>
Fri, 16 Oct 2015 01:24:51 +0000 (20:24 -0500)
committersparky4 <sparky4@cock.li>
Fri, 16 Oct 2015 01:24:51 +0000 (20:24 -0500)
84 files changed:
16/tweak16/09TO10.CPP [new file with mode: 0755]
16/tweak16/132X25S.TWK [new file with mode: 0755]
16/tweak16/132X43S.TWK [new file with mode: 0755]
16/tweak16/132X50S.TWK [new file with mode: 0755]
16/tweak16/132X60S.TWK [new file with mode: 0755]
16/tweak16/16.2 [new file with mode: 0755]
16/tweak16/16.256 [new file with mode: 0755]
16/tweak16/162.C [new file with mode: 0755]
16/tweak16/162.EXE [new file with mode: 0755]
16/tweak16/192X144.256 [new file with mode: 0755]
16/tweak16/256X192.256 [new file with mode: 0755]
16/tweak16/256X224.256 [new file with mode: 0755]
16/tweak16/256X240.256 [new file with mode: 0755]
16/tweak16/256X256.256 [new file with mode: 0755]
16/tweak16/256X256C.256 [new file with mode: 0755]
16/tweak16/320X200.256 [new file with mode: 0755]
16/tweak16/320X240.256 [new file with mode: 0755]
16/tweak16/320X240.C [new file with mode: 0755]
16/tweak16/320X240.EXE [new file with mode: 0755]
16/tweak16/320X400.256 [new file with mode: 0755]
16/tweak16/360X270.256 [new file with mode: 0755]
16/tweak16/360X360.256 [new file with mode: 0755]
16/tweak16/360X400.256 [new file with mode: 0755]
16/tweak16/360X480.256 [new file with mode: 0755]
16/tweak16/376X564.256 [new file with mode: 0755]
16/tweak16/400X300.256 [new file with mode: 0755]
16/tweak16/400X300S.256 [new file with mode: 0755]
16/tweak16/400X600.256 [new file with mode: 0755]
16/tweak16/400X600S.256 [new file with mode: 0755]
16/tweak16/40X12.TWK [new file with mode: 0755]
16/tweak16/432X600S.256 [new file with mode: 0755]
16/tweak16/640X400S.256 [new file with mode: 0755]
16/tweak16/800X600.16 [new file with mode: 0755]
16/tweak16/800X600S.16 [new file with mode: 0755]
16/tweak16/80X43.TWK [new file with mode: 0755]
16/tweak16/80X50.TWK [new file with mode: 0755]
16/tweak16/C&T.DAT [new file with mode: 0755]
16/tweak16/DETECT.CPP [new file with mode: 0755]
16/tweak16/DETECT.HPP [new file with mode: 0755]
16/tweak16/EXAMPLE1.C [new file with mode: 0755]
16/tweak16/EXAMPLE1.EXE [new file with mode: 0755]
16/tweak16/EXAMPLE2.C [new file with mode: 0755]
16/tweak16/EXAMPLE2.EXE [new file with mode: 0755]
16/tweak16/MAKEFILE [new file with mode: 0755]
16/tweak16/MISC.HPP [new file with mode: 0755]
16/tweak16/MISC/CHIPTECH.TXT [new file with mode: 0755]
16/tweak16/MISC/READ.ME [new file with mode: 0755]
16/tweak16/MISC/SETMODEX.ASM [new file with mode: 0755]
16/tweak16/MISC/VGA.TXT [new file with mode: 0755]
16/tweak16/MISC/VGABIOS.TXT [new file with mode: 0755]
16/tweak16/MODES.DOC [new file with mode: 0755]
16/tweak16/NAMEDREG.CPP [new file with mode: 0755]
16/tweak16/REGEDIT.CPP [new file with mode: 0755]
16/tweak16/REGEDIT.HPP [new file with mode: 0755]
16/tweak16/REGISTER.CPP [new file with mode: 0755]
16/tweak16/REGISTER.HPP [new file with mode: 0755]
16/tweak16/REGTABLE.CPP [new file with mode: 0755]
16/tweak16/REGTABLE.HPP [new file with mode: 0755]
16/tweak16/SCREEN.CPP [new file with mode: 0755]
16/tweak16/SCREEN.HPP [new file with mode: 0755]
16/tweak16/TESTPAT.CPP [new file with mode: 0755]
16/tweak16/TESTPAT.HPP [new file with mode: 0755]
16/tweak16/TWEAK.CPP [new file with mode: 0755]
16/tweak16/TWEAK.DAT [new file with mode: 0755]
16/tweak16/TWEAK.DOC [new file with mode: 0755]
16/tweak16/TWEAK.EXE [new file with mode: 0755]
16/tweak16/TWEAK2C.CPP [new file with mode: 0755]
16/tweak16/TWEAK2C.EXE [new file with mode: 0755]
16/tweak16/TWEAKOLD.DAT [new file with mode: 0755]
16/tweak16/TWKUSER.C [new file with mode: 0755]
16/tweak16/TWKUSER.H [new file with mode: 0755]
16/tweak16/VGALIB.CPP [new file with mode: 0755]
16/tweak16/VGALIB.HPP [new file with mode: 0755]
16/tweak16/XINTRO/LIB.EXE [new file with mode: 0755]
16/tweak16/XINTRO/LIB.SMP [new file with mode: 0755]
16/tweak16/XINTRO/M13ORG.ASC [new file with mode: 0755]
16/tweak16/XINTRO/M13ORG.GIF [new file with mode: 0755]
16/tweak16/XINTRO/MXORG.ASC [new file with mode: 0755]
16/tweak16/XINTRO/MXORG.GIF [new file with mode: 0755]
16/tweak16/XINTRO/RUN.BAT [new file with mode: 0755]
16/tweak16/XINTRO/XINTRO.TXT [new file with mode: 0755]
16/tweak16/XINTRO/XINTRO.zip [new file with mode: 0755]
16/tweak16/XINTRO/lib.c [new file with mode: 0755]
16/tweak16/XINTRO/x.bat [new file with mode: 0755]

diff --git a/16/tweak16/09TO10.CPP b/16/tweak16/09TO10.CPP
new file mode 100755 (executable)
index 0000000..53aa842
--- /dev/null
@@ -0,0 +1,147 @@
+/*\r
+       09TO10 1.0 - convert TWEAK 0.9 files to TWEAK 1.0 files\r
+\r
+       by Robert Schmidt of Ztiff Zox Softwear, 1992-93\r
+\r
+       For documentation, see TWEAK.DOC.\r
+\r
+       Most of the starting definitions was taken from the TWEAK095.CPP\r
+       file included elsewhere, so comments are removed.\r
+*/\r
+\r
+#ifndef __LARGE__\r
+# ifndef __COMPACT__\r
+#  ifndef __HUGE__\r
+#   error A large data model is required!\r
+#  endif\r
+# endif\r
+#endif\r
+\r
+\r
+#include <stdio.h>\r
+#include <dos.h>\r
+#include <stdlib.h>\r
+#include <fstream.h>\r
+#include <io.h>\r
+\r
+#include "Register.hpp"\r
+\r
+\r
+struct vgaRegisterInfo\r
+       {\r
+       char *name;\r
+       unsigned port;\r
+       unsigned char index;\r
+       };\r
+\r
+vgaRegisterInfo table[] =\r
+       {\r
+               {"Misc. output",                        0x3c2,  0x00},\r
+\r
+               {"Horizontal total",            0x3d4,  0x00},\r
+               {"Horizontal disp. enable",     0x3d4,  0x01},\r
+               {"Horizontal blank start",      0x3d4,  0x02},\r
+               {"Horizontal blank end",        0x3d4,  0x03},\r
+               {"Horizontal retrace start",0x3d4,  0x04},\r
+               {"Horizontal retrace end",      0x3d4,  0x05},\r
+               {"Vertical total",                      0x3d4,  0x06},\r
+               {"Overflow register",           0x3d4,  0x07},\r
+               {"Preset row scan",                     0x3d4,  0x08},\r
+               {"Max scan line/char ht.",      0x3d4,  0x09},\r
+\r
+               {"Vertical retrace start",      0x3d4,  0x10},\r
+               {"Vertical retrace end",        0x3d4,  0x11},\r
+               {"Vert. disp. enable end",      0x3d4,  0x12},\r
+               {"Offset/Logical width",        0x3d4,  0x13},\r
+               {"Underline location",          0x3d4,  0x14},\r
+               {"Vertical blank start",        0x3d4,  0x15},\r
+               {"Vertical blank end",          0x3d4,  0x16},\r
+               {"Mode control",                        0x3d4,  0x17},\r
+\r
+               {"Clock mode register",         0x3c4,  0x01},\r
+               {"Color plane write enable",0x3c4,      0x02},\r
+               {"Character gen. select",       0x3c4,  0x03},\r
+               {"Memory mode register",        0x3c4,  0x04},\r
+\r
+               {"Set/reset register",          0x3ce,  0x00},\r
+               {"Set/reset enable",            0x3ce,  0x01},\r
+               {"Color compare",                       0x3ce,  0x02},\r
+               {"Data rotate & function",      0x3ce,  0x03},\r
+               {"Mode register",                       0x3ce,  0x05},\r
+               {"Miscellaneous register",      0x3ce,  0x06},\r
+               {"Color don't care",            0x3ce,  0x07},\r
+               {"Bit mask register",           0x3ce,  0x08},\r
+\r
+               {"Mode control",                        0x3c0,  0x10},\r
+               {"Screen border colour",        0x3c0,  0x11},\r
+               {"Color plane enable",          0x3c0,  0x12},\r
+               {"Horizontal panning",          0x3c0,  0x13},\r
+               {"Color select",                        0x3c0,  0x14}\r
+       };\r
+\r
+const registers = sizeof (table) / sizeof (vgaRegisterInfo);\r
+\r
+\r
+class vgaRegTable\r
+       {\r
+       unsigned char value[registers];\r
+       unsigned char selectedReg;\r
+public:\r
+       void out();\r
+       void in();\r
+       void print(unsigned char selected);\r
+       void printOne(unsigned char r, int isSelected);\r
+       unsigned char& operator [] (unsigned char n)\r
+                                       { return value[n]; }\r
+       };\r
+\r
+\r
+// The main program starts here.\r
+\r
+main(int argc, char **argv)\r
+       {\r
+       if (argc < 3)\r
+               {\r
+               printf("09TO10 version 1.0\n\r"\r
+                          "by Robert Schmidt of Ztiff Zox Softwear 1993\n\r"\r
+                          "\n\r"\r
+                          "Converts TWEAK version 0.9 files to TWEAK version 1.0 files.\n\r"\r
+                          "\n\r"\r
+                          "Syntax:  09TO10 <oldfile> <newfile>\n\r"\r
+                          );\r
+               return 0;\r
+               }\r
+\r
+       vgaRegTable rtab;\r
+\r
+       char *fname = argv[1];\r
+       FILE *f;\r
+       int r;\r
+\r
+       // Open file in selected mode.\r
+       if (!(f=fopen(fname,"rb")))\r
+               {\r
+               perror(fname);\r
+               return 0;\r
+        }\r
+       // Read file:\r
+       for (r=0; r<registers; r++)\r
+               if (fread(&(rtab[r]),1,1,f) == 0)\r
+                       {\r
+                       perror(fname);\r
+                       return 0;\r
+                       }\r
+       fclose(f);\r
+\r
+       ofstream out(argv[2], ios::trunc|ios::binary|ios::out);\r
+       Register reg;\r
+       for (r=0; r<registers; r++)\r
+               {\r
+               reg.setPort(table[r].port);\r
+               reg.setIndex(table[r].index);\r
+               reg.setValue(rtab[r]);\r
+               out << reg;\r
+               }\r
+\r
+       return 0;\r
+       }\r
diff --git a/16/tweak16/132X25S.TWK b/16/tweak16/132X25S.TWK
new file mode 100755 (executable)
index 0000000..7f7156a
Binary files /dev/null and b/16/tweak16/132X25S.TWK differ
diff --git a/16/tweak16/132X43S.TWK b/16/tweak16/132X43S.TWK
new file mode 100755 (executable)
index 0000000..4c677d8
Binary files /dev/null and b/16/tweak16/132X43S.TWK differ
diff --git a/16/tweak16/132X50S.TWK b/16/tweak16/132X50S.TWK
new file mode 100755 (executable)
index 0000000..128b8d5
Binary files /dev/null and b/16/tweak16/132X50S.TWK differ
diff --git a/16/tweak16/132X60S.TWK b/16/tweak16/132X60S.TWK
new file mode 100755 (executable)
index 0000000..72a49a7
Binary files /dev/null and b/16/tweak16/132X60S.TWK differ
diff --git a/16/tweak16/16.2 b/16/tweak16/16.2
new file mode 100755 (executable)
index 0000000..c614393
Binary files /dev/null and b/16/tweak16/16.2 differ
diff --git a/16/tweak16/16.256 b/16/tweak16/16.256
new file mode 100755 (executable)
index 0000000..3a5850a
Binary files /dev/null and b/16/tweak16/16.256 differ
diff --git a/16/tweak16/162.C b/16/tweak16/162.C
new file mode 100755 (executable)
index 0000000..e13988f
--- /dev/null
@@ -0,0 +1,29 @@
+#include "TwkUser.h" // get Register definition\r
+Register pee[] =\r
+       {\r
+       { 0x3c2, 0x0, 0xe3},\r
+       { 0x3d4, 0x0, 0x5f},\r
+       { 0x3d4, 0x1, 0x2f},\r
+       { 0x3d4, 0x2, 0x50},\r
+       { 0x3d4, 0x3, 0x82},\r
+       { 0x3d4, 0x4, 0x54},\r
+       { 0x3d4, 0x5, 0x80},\r
+       { 0x3d4, 0x6, 0xd},\r
+       { 0x3d4, 0x7, 0x3e},\r
+       { 0x3d4, 0x8, 0x0},\r
+       { 0x3d4, 0x9, 0x41},\r
+       { 0x3d4, 0x10, 0xea},\r
+       { 0x3d4, 0x11, 0xac},\r
+       { 0x3d4, 0x12, 0x1f},\r
+       { 0x3d4, 0x13, 0x18},\r
+       { 0x3d4, 0x14, 0x0},\r
+       { 0x3d4, 0x15, 0xe7},\r
+       { 0x3d4, 0x16, 0x6},\r
+       { 0x3d4, 0x17, 0xe3},\r
+       { 0x3c4, 0x1, 0x1},\r
+       { 0x3c4, 0x4, 0x6},\r
+       { 0x3ce, 0x5, 0x40},\r
+       { 0x3ce, 0x6, 0x5},\r
+       { 0x3c0, 0x10, 0x41},\r
+       { 0x3c0, 0x13, 0x0}\r
+       };\r
diff --git a/16/tweak16/162.EXE b/16/tweak16/162.EXE
new file mode 100755 (executable)
index 0000000..9013645
Binary files /dev/null and b/16/tweak16/162.EXE differ
diff --git a/16/tweak16/192X144.256 b/16/tweak16/192X144.256
new file mode 100755 (executable)
index 0000000..c792920
Binary files /dev/null and b/16/tweak16/192X144.256 differ
diff --git a/16/tweak16/256X192.256 b/16/tweak16/256X192.256
new file mode 100755 (executable)
index 0000000..2079ac2
Binary files /dev/null and b/16/tweak16/256X192.256 differ
diff --git a/16/tweak16/256X224.256 b/16/tweak16/256X224.256
new file mode 100755 (executable)
index 0000000..1cff547
Binary files /dev/null and b/16/tweak16/256X224.256 differ
diff --git a/16/tweak16/256X240.256 b/16/tweak16/256X240.256
new file mode 100755 (executable)
index 0000000..c607a62
Binary files /dev/null and b/16/tweak16/256X240.256 differ
diff --git a/16/tweak16/256X256.256 b/16/tweak16/256X256.256
new file mode 100755 (executable)
index 0000000..33c6dcc
Binary files /dev/null and b/16/tweak16/256X256.256 differ
diff --git a/16/tweak16/256X256C.256 b/16/tweak16/256X256C.256
new file mode 100755 (executable)
index 0000000..a87dce4
Binary files /dev/null and b/16/tweak16/256X256C.256 differ
diff --git a/16/tweak16/320X200.256 b/16/tweak16/320X200.256
new file mode 100755 (executable)
index 0000000..316e154
Binary files /dev/null and b/16/tweak16/320X200.256 differ
diff --git a/16/tweak16/320X240.256 b/16/tweak16/320X240.256
new file mode 100755 (executable)
index 0000000..e1f924b
Binary files /dev/null and b/16/tweak16/320X240.256 differ
diff --git a/16/tweak16/320X240.C b/16/tweak16/320X240.C
new file mode 100755 (executable)
index 0000000..0041f3e
--- /dev/null
@@ -0,0 +1,29 @@
+#include "TwkUser.h" // get Register definition\r
+Register Mode320x240[] =\r
+       {\r
+       { 0x3c2, 0x0, 0xe3},\r
+       { 0x3d4, 0x0, 0x5f},\r
+       { 0x3d4, 0x1, 0x4f},\r
+       { 0x3d4, 0x2, 0x50},\r
+       { 0x3d4, 0x3, 0x82},\r
+       { 0x3d4, 0x4, 0x54},\r
+       { 0x3d4, 0x5, 0x80},\r
+       { 0x3d4, 0x6, 0xd},\r
+       { 0x3d4, 0x7, 0x3e},\r
+       { 0x3d4, 0x8, 0x0},\r
+       { 0x3d4, 0x9, 0x41},\r
+       { 0x3d4, 0x10, 0xea},\r
+       { 0x3d4, 0x11, 0xac},\r
+       { 0x3d4, 0x12, 0xdf},\r
+       { 0x3d4, 0x13, 0x28},\r
+       { 0x3d4, 0x14, 0x0},\r
+       { 0x3d4, 0x15, 0xe7},\r
+       { 0x3d4, 0x16, 0x6},\r
+       { 0x3d4, 0x17, 0xe3},\r
+       { 0x3c4, 0x1, 0x1},\r
+       { 0x3c4, 0x4, 0x6},\r
+       { 0x3ce, 0x5, 0x40},\r
+       { 0x3ce, 0x6, 0x5},\r
+       { 0x3c0, 0x10, 0x41},\r
+       { 0x3c0, 0x13, 0x0}\r
+       };\r
diff --git a/16/tweak16/320X240.EXE b/16/tweak16/320X240.EXE
new file mode 100755 (executable)
index 0000000..0d67ae8
Binary files /dev/null and b/16/tweak16/320X240.EXE differ
diff --git a/16/tweak16/320X400.256 b/16/tweak16/320X400.256
new file mode 100755 (executable)
index 0000000..3ceb4bd
Binary files /dev/null and b/16/tweak16/320X400.256 differ
diff --git a/16/tweak16/360X270.256 b/16/tweak16/360X270.256
new file mode 100755 (executable)
index 0000000..e4c1cfb
Binary files /dev/null and b/16/tweak16/360X270.256 differ
diff --git a/16/tweak16/360X360.256 b/16/tweak16/360X360.256
new file mode 100755 (executable)
index 0000000..970bd22
Binary files /dev/null and b/16/tweak16/360X360.256 differ
diff --git a/16/tweak16/360X400.256 b/16/tweak16/360X400.256
new file mode 100755 (executable)
index 0000000..83697d4
Binary files /dev/null and b/16/tweak16/360X400.256 differ
diff --git a/16/tweak16/360X480.256 b/16/tweak16/360X480.256
new file mode 100755 (executable)
index 0000000..c4913f2
Binary files /dev/null and b/16/tweak16/360X480.256 differ
diff --git a/16/tweak16/376X564.256 b/16/tweak16/376X564.256
new file mode 100755 (executable)
index 0000000..28ba1be
Binary files /dev/null and b/16/tweak16/376X564.256 differ
diff --git a/16/tweak16/400X300.256 b/16/tweak16/400X300.256
new file mode 100755 (executable)
index 0000000..cf526b1
Binary files /dev/null and b/16/tweak16/400X300.256 differ
diff --git a/16/tweak16/400X300S.256 b/16/tweak16/400X300S.256
new file mode 100755 (executable)
index 0000000..74bf41e
Binary files /dev/null and b/16/tweak16/400X300S.256 differ
diff --git a/16/tweak16/400X600.256 b/16/tweak16/400X600.256
new file mode 100755 (executable)
index 0000000..c701a92
Binary files /dev/null and b/16/tweak16/400X600.256 differ
diff --git a/16/tweak16/400X600S.256 b/16/tweak16/400X600S.256
new file mode 100755 (executable)
index 0000000..5d18702
Binary files /dev/null and b/16/tweak16/400X600S.256 differ
diff --git a/16/tweak16/40X12.TWK b/16/tweak16/40X12.TWK
new file mode 100755 (executable)
index 0000000..201a1e0
Binary files /dev/null and b/16/tweak16/40X12.TWK differ
diff --git a/16/tweak16/432X600S.256 b/16/tweak16/432X600S.256
new file mode 100755 (executable)
index 0000000..7971fb0
Binary files /dev/null and b/16/tweak16/432X600S.256 differ
diff --git a/16/tweak16/640X400S.256 b/16/tweak16/640X400S.256
new file mode 100755 (executable)
index 0000000..20eb209
Binary files /dev/null and b/16/tweak16/640X400S.256 differ
diff --git a/16/tweak16/800X600.16 b/16/tweak16/800X600.16
new file mode 100755 (executable)
index 0000000..b6f266f
Binary files /dev/null and b/16/tweak16/800X600.16 differ
diff --git a/16/tweak16/800X600S.16 b/16/tweak16/800X600S.16
new file mode 100755 (executable)
index 0000000..81f89f3
Binary files /dev/null and b/16/tweak16/800X600S.16 differ
diff --git a/16/tweak16/80X43.TWK b/16/tweak16/80X43.TWK
new file mode 100755 (executable)
index 0000000..a7d1ee3
Binary files /dev/null and b/16/tweak16/80X43.TWK differ
diff --git a/16/tweak16/80X50.TWK b/16/tweak16/80X50.TWK
new file mode 100755 (executable)
index 0000000..6b81d7a
Binary files /dev/null and b/16/tweak16/80X50.TWK differ
diff --git a/16/tweak16/C&T.DAT b/16/tweak16/C&T.DAT
new file mode 100755 (executable)
index 0000000..8fa3d19
--- /dev/null
@@ -0,0 +1,47 @@
+45\r
+3c2 00 Misc. output\r
+3d4 00 Horizontal total\r
+3d4 01 Horizontal disp. enable\r
+3d4 02 Horizontal blank start\r
+3d4 03 Horizontal blank end\r
+3d4 04 Horizontal retrace start\r
+3d4 05 Horizontal retrace end\r
+3d4 06 Vertical total\r
+3d4 07 Overflow register\r
+3d4 08 Preset row scan\r
+3d4 09 Max scan line/char ht.\r
+3d4 10 Vertical retrace start\r
+3d4 11 Vertical retrace end\r
+3d4 12 Vert. disp. enable end\r
+3d4 13 Offset/Logical width\r
+3d4 14 Underline location\r
+3d4 15 Vertical blank start\r
+3d4 16 Vertical blank end\r
+3d4 17 Mode control\r
+3c4 01 Clock mode register\r
+3c4 02 Color plane write enable\r
+3c4 03 Character gen. select\r
+3c4 04 Memory mode register\r
+3ce 00 Set/reset register\r
+3ce 01 Set/reset enable\r
+3ce 02 Color compare\r
+3ce 03 Data rotate & function\r
+3ce 05 Mode register\r
+3ce 06 Miscellaneous register\r
+3ce 07 Color don't care\r
+3ce 08 Bit mask register\r
+3c0 10 Mode control\r
+3c0 11 Screen border colour\r
+3c0 12 Color plane enable\r
+3c0 13 Horizontal panning\r
+3c0 14 Color select\r
+103 00 C&T: multiple enable\r
+3d6 00 C&T: chip/revision info\r
+3d6 01 C&T: DIP switch states\r
+3d6 02 C&T: cpu interface\r
+3d6 04 C&T: memory mapping\r
+3d6 0b C&T: CPU paging\r
+3d6 14 C&T: emulation mode\r
+3d6 2b C&T: default video reg.\r
+46e8 00 C&T: setup control\r
+\r
diff --git a/16/tweak16/DETECT.CPP b/16/tweak16/DETECT.CPP
new file mode 100755 (executable)
index 0000000..06eeeaa
--- /dev/null
@@ -0,0 +1,135 @@
+/*\r
+ *     Mode detection:\r
+ *     ---------------\r
+ *     Currently incompatible with CGA and Hercules modes.\r
+ *             200-line CGA modes are detected as 100-line.\r
+ *             640x200x2 is detected as 16-color.\r
+ *             Hercules not supported at all.\r
+ *     Monochrome EGA/VGA modes are also *not* supported, due to use of\r
+ *             different port addresses.\r
+ *\r
+ *     Variables of interest:\r
+ *             hPixels, vPixels - the actual resolution of the mode, in characters\r
+ *                     in text modes, in pixels in graphics modes.\r
+ *             adrOffset - the number of addressable bytes between two vertically\r
+ *                     adjacent pixels, or words between two vertically adjacent\r
+ *                     characters in text mode.\r
+ *\r
+ */\r
+\r
+#include "detect.hpp"\r
+#include "screen.hpp"\r
+#include <dos.h>\r
+#include <conio.h>\r
+\r
+\r
+\r
+void ModeInfo::detectFrom(RegisterTable &regTable)\r
+       {\r
+       Register *GCMode = regTable.getRegister(GRACON_ADDR, 0x05);\r
+       Register *GCMisc = regTable.getRegister(GRACON_ADDR, 0x06);\r
+       Register *ACMode = regTable.getRegister(ATTRCON_ADDR, 0x10);\r
+       Register *CRTChde = regTable.getRegister(CRTC_ADDR, 0x01);\r
+       Register *CRTCoflo = regTable.getRegister(CRTC_ADDR, 0x07);\r
+       Register *CRTCscan = regTable.getRegister(CRTC_ADDR, 0x09);\r
+       Register *CRTCvde = regTable.getRegister(CRTC_ADDR, 0x12);\r
+       Register *CRTCoffs = regTable.getRegister(CRTC_ADDR, 0x13);\r
+       Register *CRTCmode = regTable.getRegister(CRTC_ADDR, 0x17);\r
+       Register *SEQmmode = regTable.getRegister(SEQ_ADDR, 0x04);\r
+\r
+       int temp;\r
+       switch ((*GCMode)(5,2))\r
+               {\r
+               case 0:\r
+                       colors = COLOR16;               // might also be COLOR2 !!!\r
+                       hPixelsPerClock = 8;\r
+                       break;\r
+               case 1:\r
+                       colors = COLOR4;\r
+                       hPixelsPerClock = 16;\r
+                       break;\r
+               case 2:\r
+                       colors = COLOR256;\r
+                       hPixelsPerClock = 4;\r
+                       break;\r
+               }\r
+\r
+       temp = (**GCMisc & 1 != 0);\r
+       if (temp == (**ACMode & 1 != 0))\r
+               alphaGraph = temp ? GRAPHICS : ALPHA;\r
+       else\r
+               alphaGraph = AG_CONFLICT;\r
+\r
+       if (alphaGraph == ALPHA)\r
+               hPixelsPerClock = 1;\r
+\r
+       chain4 = (*SEQmmode)(3,1);\r
+       countBy2 = (*CRTCmode)(3,1);\r
+       adrOffset = **CRTCoffs * 2 * (countBy2+1);\r
+\r
+       hClocks = **CRTChde + 1;\r
+       vClocks =\r
+               (**CRTCvde | ((*CRTCoflo)(1,1) << 8) | ((*CRTCoflo)(6,1) << 9)) + 1;\r
+\r
+       xres = hClocks * hPixelsPerClock;\r
+       vxresBytes = vxres = adrOffset * hPixelsPerClock;\r
+\r
+       if (alphaGraph == ALPHA)\r
+               vxresBytes *= 2;\r
+       else\r
+               if (alphaGraph == GRAPHICS)\r
+                       if (colors == COLOR16)\r
+                               vxresBytes /= 8;\r
+                       else\r
+                               if (colors == COLOR256 && !chain4)\r
+                                       vxresBytes /= 4;\r
+\r
+       lineClocks = (*CRTCscan)(0,4) + 1;\r
+       if ((*CRTCscan)(7,1) << 5)\r
+               lineClocks *= 2;\r
+       yres = vClocks / lineClocks;\r
+       spareClocks = vClocks % lineClocks;\r
+       vyres = (alphaGraph == GRAPHICS ? 65536L : 32768L) / vxresBytes;\r
+    xpages = float(vxres)/xres;\r
+       ypages = float(vyres)/yres;\r
+       }\r
+\r
+\r
+GraphicsAPI *ModeInfo::getGraphicsAPI()\r
+       {\r
+       if (alphaGraph == GRAPHICS)\r
+               switch(colors)\r
+                       {\r
+                       case COLOR16:\r
+                               return new Planar16(xres, yres, vxres);\r
+                       case COLOR256:\r
+                               if (chain4)\r
+                                       return new Chained256(xres, yres, vxres);\r
+                               else\r
+                                       return new Unchained256(xres, yres, vxres);\r
+                       }\r
+       return 0;\r
+       }\r
+\r
+void ModeInfo::show()\r
+       {\r
+       window(editWidth/2+2, editHeight-18, editWidth, editHeight-7);\r
+       clrscr();\r
+       textattr(INFO_COLOR);\r
+       cprintf("This seems to be a %d-color\n\r"\r
+                       "%s mode.\n\r\n\r"\r
+                       "Physical resolution: %d x %d\n\r"\r
+                       "Virtual resolution:  %d x %d\n\r\n\r"\r
+                       "Page resolution:     %3.1f x %3.1f",\r
+                       colors,\r
+                       alphaGraph==ALPHA ? "text" :\r
+                               alphaGraph==GRAPHICS ? (chain4 ? "linear graphics" :\r
+                                                                                                "planar graphics") :\r
+                                                                          "graph/text conflict",\r
+                       xres, yres,\r
+                       vxres, vyres,\r
+                       xpages, ypages\r
+                       );\r
+       window(1,1,editWidth,editHeight);\r
+       }\r
+\r
diff --git a/16/tweak16/DETECT.HPP b/16/tweak16/DETECT.HPP
new file mode 100755 (executable)
index 0000000..a26aed9
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef _DETECT_HPP\r
+#define _DETECT_HPP\r
+\r
+#include "misc.hpp"\r
+#include "regtable.hpp"\r
+#include "vgalib.hpp"\r
+\r
+\r
+struct ModeInfo\r
+       {\r
+       enum EmulType { EM_CONFLICT, HERC, CGA, VGA };\r
+       enum ColorsType { COLOR2=2, COLOR4=4, COLOR16=16, COLOR256=256 };\r
+       enum AGType { AG_CONFLICT, ALPHA, GRAPHICS };\r
+\r
+       EmulType emulation;\r
+       AGType alphaGraph;\r
+       ColorsType colors;\r
+       int hClocks, vClocks, xres, yres, lineClocks, spareClocks, adrOffset,\r
+               hPixelsPerClock, vxres, vyres, vxresBytes;\r
+       float xpages, ypages;\r
+       Boolean countBy2, chain4;\r
+\r
+       ModeInfo(RegisterTable &rt)                     { detectFrom(rt); }\r
+       void detectFrom(RegisterTable &);\r
+       GraphicsAPI *getGraphicsAPI();\r
+       void show();\r
+       };\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/EXAMPLE1.C b/16/tweak16/EXAMPLE1.C
new file mode 100755 (executable)
index 0000000..ab486c6
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+       Example1.C version 1.5\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Example of making use of a TWEAK file by loading it directly at\r
+               run-time.  This program needs the file(s) created by TWEAK\r
+               available at run-time.\r
+*/\r
+\r
+#include <dos.h>\r
+#include <mem.h>\r
+#include <alloc.h>\r
+#include <conio.h>\r
+#include "TwkUser.h"   /* declares the neccessary functions and types */\r
+\r
+main()\r
+       {\r
+       /* Define the pointer that should point to the loaded array of\r
+          Registers, and the int to hold its size */\r
+\r
+    RegisterPtr rarray;\r
+       int rsize;\r
+\r
+       int y, lastMode;\r
+\r
+       cprintf("This example program loads a TWEAK register file at run-time\n\r");\r
+       cprintf("and uses this to set Mode X (320x240x256).\n\rPress any key.");\r
+       getch();\r
+\r
+       /* Now use the loadRegArray function declared in TwkUser.h to load the\r
+          TWEAK file.  Memory is automatically allocated.  Note that the\r
+          second argument is the address of the pointer defined above!\r
+          The returned value is the number of Register elements loaded. */\r
+\r
+    rsize = loadRegArray("320x240.256", &rarray);\r
+\r
+       /* Save the number of the current BIOS mode, so we can restore it\r
+          later. */\r
+\r
+       _AH = 0x0f;\r
+       geninterrupt(0x10);\r
+       lastMode = _AL;\r
+\r
+       /* Set mode 13h, to make sure the EGA palette set is correct for a 256\r
+          color mode */\r
+\r
+       _AX = 0x13;\r
+       geninterrupt(0x10);\r
+\r
+       /* rarray now points to the loaded array.  The second argument to\r
+          outRegArray is the number if Register elements in the array. */\r
+\r
+    outRegArray(rarray, rsize);\r
+\r
+       outpw(0x3c4, 0x0f02);                   /* Enable all 4 planes */\r
+\r
+       /* Fill the screen with a blend of pink and green lines, defining the\r
+          palette on the fly. */\r
+\r
+       outp(0x3c8, 0);                                 /* start with color 0 */\r
+       for (y = 0; y<240; y++)\r
+               {\r
+               outp(0x3c9, y>>2);                      /* red component */\r
+               outp(0x3c9, (256-y) >> 2);      /* green component */\r
+               outp(0x3c9, y>>2);                      /* blue component */\r
+               memset((char*)MK_FP(0xa000,0) + y*80, y, 80);\r
+               }\r
+\r
+       /* The mode is now set, so wait for the user to press a key...\r
+          Nothing much interesting to look at, I'm afraid. */\r
+\r
+    getch();\r
+\r
+       /* Restore the saved mode number.  Borland's textmode() won't work, as the\r
+          C library still thinks we're in the mode it detected at startup.\r
+          The palette will be set to the BIOS mode's default. */\r
+\r
+       _AX = lastMode;\r
+       geninterrupt(0x10);\r
+\r
+       /* Free the Register array allocated in loadRegArray.  *You* are\r
+          responsible for doing this! */\r
+\r
+    free(rarray);\r
+\r
+       return 0;\r
+       }\r
diff --git a/16/tweak16/EXAMPLE1.EXE b/16/tweak16/EXAMPLE1.EXE
new file mode 100755 (executable)
index 0000000..60c4f59
Binary files /dev/null and b/16/tweak16/EXAMPLE1.EXE differ
diff --git a/16/tweak16/EXAMPLE2.C b/16/tweak16/EXAMPLE2.C
new file mode 100755 (executable)
index 0000000..ff3d327
--- /dev/null
@@ -0,0 +1,81 @@
+/*\r
+       Example2.C version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Example of making use of a TWEAK file by linking its contents in\r
+       with the program.  This program doesn't need any external files at\r
+       run time.\r
+*/\r
+\r
+#include <mem.h>\r
+#include <dos.h>\r
+#include <alloc.h>\r
+#include <conio.h>\r
+#include "TwkUser.h"\r
+\r
+/*     The following included file defines the Mode320x240 table of Registers.\r
+       The file should be created by running\r
+       TWEAK2C 320x240.256 320x240.c Mode320x240 */\r
+\r
+#include "320x240.c"\r
+\r
+main()\r
+       {\r
+       int y, lastMode;\r
+\r
+       cprintf("This example program was compiled with the C version of a TWEAK\n\r");\r
+       cprintf("register file, and so will not need the external file.\n\r");\r
+       cprintf("The C array is now used to set Mode X (320x240x256).\n\rPress any key.");\r
+       getch();\r
+\r
+       /* Save the number of the current BIOS mode, so we can restore it\r
+          later. */\r
+\r
+       _AH = 0x0f;\r
+       geninterrupt(0x10);\r
+       lastMode = _AL;\r
+\r
+       /* Set mode 13h, to make sure the EGA palette set is correct for a 256\r
+          color mode */\r
+\r
+       _AX = 0x13;\r
+       geninterrupt(0x10);\r
+\r
+       /* Note that no initialization is neccessary now.  The Register array\r
+          is linked in as global data, and is directly accessible.  Take\r
+          note of the way the number of Register elements in the array is\r
+          calculated: */\r
+\r
+       outRegArray(Mode320x240, sizeof(Mode320x240)/sizeof(Register));\r
+\r
+       outpw(0x3c4, 0x0f02);   /* Enable all 4 planes */\r
+\r
+       /* Fill the screen with a blend of red and blue lines, defining the\r
+          palette on the fly. */\r
+\r
+       outp(0x3c8, 0);                                 /* start with color 0 */\r
+       for (y = 0; y<240; y++)\r
+               {\r
+               outp(0x3c9, y>>2);                      /* red component */\r
+               outp(0x3c9, 0);                         /* green component */\r
+               outp(0x3c9, (256-y) >> 2);      /* blue component */\r
+               memset((char*)MK_FP(0xa000,0) + y*80, y, 80);\r
+               }\r
+\r
+       /* The picture is drawn, so wait for user to get tired of it. */\r
+\r
+       getch();\r
+\r
+       /* Restore the saved mode number.  Borland's textmode() won't work, as the\r
+          C library still thinks we're in the mode it detected at startup.\r
+          The palette will be set to the BIOS mode's default. */\r
+\r
+       _AX = lastMode;\r
+       geninterrupt(0x10);\r
+\r
+\r
+       /* Also note that since the array is static, global data, there is\r
+          no pointer to free(), as was done in Example1.C */\r
+\r
+       return 0;\r
+       }\r
diff --git a/16/tweak16/EXAMPLE2.EXE b/16/tweak16/EXAMPLE2.EXE
new file mode 100755 (executable)
index 0000000..ab37728
Binary files /dev/null and b/16/tweak16/EXAMPLE2.EXE differ
diff --git a/16/tweak16/MAKEFILE b/16/tweak16/MAKEFILE
new file mode 100755 (executable)
index 0000000..849178e
--- /dev/null
@@ -0,0 +1,50 @@
+# This is a Borland-specific Makefile.  It may or may not work with\r
+# other makes.  Please mail me your changes to make it more portable.\r
+\r
+.autodepend\r
+\r
+CC = bcc -ml -v -y -O -O2\r
+\r
+all: tweak utilities examples oldtweak\r
+tweak: tweak.exe\r
+oldtweak: tweak095.exe\r
+examples: example1.exe example2.exe\r
+utilities: tweak2c.exe 09to10.exe\r
+\r
+tweak.exe: tweak.obj register.obj namedreg.obj regtable.obj screen.obj \\r
+        testpat.obj vgalib.obj regedit.obj detect.obj\r
+        $(CC) tweak.obj register.obj namedreg.obj regtable.obj screen.obj \\r
+                testpat.obj vgalib.obj regedit.obj detect.obj\r
+\r
+09to10.exe: 09to10.obj register.obj\r
+        $(CC) 09to10.obj register.obj\r
+\r
+example1.exe: example1.obj twkuser.obj\r
+        $(CC) example1.obj twkuser.obj\r
+\r
+example2.exe: example2.obj twkuser.obj tweak2c.exe 320x240.c\r
+        $(CC) example2.obj twkuser.obj\r
+\r
+tweak2c.exe: tweak2c.obj twkuser.obj\r
+        $(CC) tweak2c.obj twkuser.obj\r
+\r
+320x240.c: tweak2c.exe 320x240.256\r
+        tweak2c 320x240.256 320x240.c Mode320x240\r
+\r
+.256.c:\r
+        tweak2c $< $*.c Mode$*\r
+\r
+.16.c:\r
+        tweak2c $< $*.c Mode$*\r
+\r
+.twk.c:\r
+        tweak2c $< $*.c Mode$*\r
+\r
+.c.obj:\r
+        $(CC) -c {$< }\r
+\r
+.cpp.obj:\r
+        $(CC) -c {$< }\r
+\r
+.obj.exe:\r
+        $(CC) $<\r
diff --git a/16/tweak16/MISC.HPP b/16/tweak16/MISC.HPP
new file mode 100755 (executable)
index 0000000..f5b7f65
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _MISC_HPP\r
+#define _MISC_HPP\r
+\r
+enum Boolean { FALSE=(0==1), TRUE=(1==1) };\r
+\r
+template <class T>\r
+inline void swap(T &a, T &b)\r
+       {\r
+       T t(a);\r
+       a = b;\r
+       b = t;\r
+       }\r
+\r
+template <class T>\r
+inline T min(T a, T b)\r
+       {\r
+       return (a<b) ? a : b;\r
+       }\r
+\r
+template <class T>\r
+inline T max(T a, T b)\r
+       {\r
+       return (a>b) ? a : b;\r
+       }\r
+\r
+template <class T>\r
+inline T absolute(T a)\r
+       {\r
+       return (a<0) ? -a : a;\r
+       }\r
+\r
+template <class T>\r
+inline void sort(T &a, T &b)\r
+       {\r
+       if (a>b)\r
+               swap(a, b);\r
+       }\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/MISC/CHIPTECH.TXT b/16/tweak16/MISC/CHIPTECH.TXT
new file mode 100755 (executable)
index 0000000..6e67305
--- /dev/null
@@ -0,0 +1,1135 @@
+  Chips and Technologies Super VGA Chip Sets:\r
+\r
+\r
+    82c450\r
+    82c451  256k DRAM    max 800x600 16col\r
+    82c452    1M DRAM    max 640x480 256col, 1024x768 16col\r
+    82c453    1M VRAM    max 800x600 256 col\r
+    82c455  256k DRAM    Flat Panel version\r
+    82c456  256k DRAM    do\r
+    82c457               do. Full color. \r
+    F65520   1M  D/VRAM  do. Full color. max 1280x1024 16 col & 800x600 256 col\r
+    F65530   1M  D/VRAM  do. Full color. max 1280x1024 16 col & 800x600 256 col\r
+                        Supports Local Bus.    \r
+\r
+\r
+       94h (R/W):  Setup Control Register for Microchannel boards\r
+       bit 0-2  Reserved\r
+            3  Enables Adapter VGA if set\r
+            4  Enters Setup Mode if set\r
+          5-7  Reserved\r
+       Note: This is the same register as 46E8h.\r
+\r
+       100h (R): Microchannel ID low\r
+       bit 0-7  Bit 0-7 of Microchannel Card ID\r
+\r
+       101h (R): Microchannel ID high\r
+       bit 0-7  Bit 8-15 of Microchannel Card ID\r
+\r
+ 102h (R/W): Global Enable\r
+ bit   0  VGA is enabled if set.\r
+\r
+ 103h (R/W): Multiple Enable\r
+ bit 0-3  Multiple VGA Enable\r
+       4  Must be 0 for propper operation of 82c455/6/7.\r
+       6  Extension registers at 3B6h/7h if set,\r
+         3D6h/7h if not.\r
+       7  Extension Registers Access Enable.\r
+         VGA Extension registers at 3d7h can only be\r
+         accessed if this bit is set.\r
+ Note: This register only available in Setup Mode.  \r
+\r
+ 104h (R): Global ID (Setup)             (Only in Setup Mode)\r
+ bit 0-7  Chip I/D.  0A5h if Chips and Tech Chip set.\r
+\r
+ 3C3h (R/W): Setup Control PS/2\r
+ bit   0  Enables motherboard VGA if set\r
+       4  Enters Setup mode if set\r
+\r
+ 3d4h index 22h (R/W): CPU Data Latch or Color Compare from last read\r
+\r
+ 3d4h index 24h (R/W): Attribute Controller flip/flop\r
+\r
+ 3d6h index  0  (R): Chip Version\r
+ bit 0-3  Revision number\r
+     4-7  Chipcode:\r
+          0: 451  1:452  2:455  3:453  5:456  6:457\r
+          7: 65520, 8:65530\r
+\r
+ 3d6h index  1  (R): DIP Switch Register\r
+ bit 0-6  State of the DIP switches.\r
+     0-7  (655x0) Read from Memory Address bus A on Reset.\r
+         Bit 0-1: CPU Bus type    \r
+                   0=PI bus, 1=MC bus, 2=Local bus (65530 only), 3=ISA bus.\r
+               2: Pixel Clock Source (OSC/)\r
+                   0: CLK0-CLK3 are pixel clock inputs. \r
+                      CLK0 or CLK1 is MCLK input.\r
+                   1: CLK0 is MCLK input.\r
+                      CLK1 is pixel clock input.\r
+                      CLK2 is CLKSEL0 output.\r
+                      CLK3 is CLKSEL1 output.   \r
+               3: Memory Clock Source (56M/)\r
+                    0: MCLK = 56.644 MHz (80ns RAM)\r
+                       If bit 2 is 0:\r
+                         CLK0 is 50.350 MHz\r
+                         CLK1 is 56.644 MHz (MCLK source)\r
+                         CLK2 is 40.000 MHz\r
+                         CLK3 is 44.900 MHz\r
+                       If bit 2 is 1:\r
+                         MCLK (CLK0) is 56.644 MHz\r
+                         Clock Select 0 is 40.000 MHz\r
+                         Clock Select 1 is 50.350 MHz\r
+                         Clock Select 2 is user defined\r
+                         Clock Select 3 is 44.900 MHz\r
+                    1: MCLK = 50.350 MHz (100ns RAM)\r
+                       If bit 2 is 0:\r
+                         CLK0 is 50.350 MHz\r
+                         CLK1 is 28.322 MHz (MCLK source)\r
+                         CLK2 is 40.000 MHz\r
+                         CLK3 is 44.900 MHz\r
+                       If bit 2 is 1:\r
+                         MCLK (CLK0) is 50.350 MHz\r
+                         Clock Select 0 is 40.000 MHz\r
+                         Clock Select 1 is 28.322 MHz\r
+                         Clock Select 2 is user defined\r
+                         Clock Select 3 is 44.900 MHz\r
+               4: Transceiver Control\r
+                  If set there are no external transceivers (pin 69 is\r
+                  VGARD output), if clear there are external transceivers\r
+                  (pin 69 is ENAVEE/ output).\r
+\r
+ 3d6h index  2  (R/W): CPU Interface\r
+ bit   0  16bit memory enabled if set\r
+       1  (82c451-453) 16 bit I/O if set\r
+         (82c453 Only) Fast Font Enable   ???\r
+            The byte written to memory is used as a mask\r
+            for painting foreground color to the pixels\r
+            with the corresponding bit set and background\r
+            color to the rest.\r
+         (655x0 Only) Digital Monitor Clock Mode\r
+            0: CLK0 = 25 MHz, CLK1 = 28 MHz\r
+            1: CLK0 = 14 MHz (56MHz /4 or 28MHz /2)\r
+               CLK1 = 16 MHz (50MHz /3)\r
+       2  (82c451/2/3/5) Fast MCA buscycle decoding if set\r
+     3-4  (82c453 and 455-457) Attribute port pairing\r
+            0: Normal Attribute addressing\r
+            1: 3C1h is both read and write, 8 and 16 bit.\r
+            2: 3C1h is both read and write, 8 bit only.\r
+       5  (Not 82c451/2) 10 bit I/O decoding if set, 16 bit else\r
+       6  (82c453 Only) Pel Panning Control\r
+         (655x0 Only) If set external palette registers can be addressed\r
+                     at 83C6h-83C9h. (Brooktree/Sierra type DACs).\r
+       7  (Read Only) Attribute flip-flop status. If set the Attribute\r
+                    register (3C0h) is currently in Data mode.\r
+\r
+ 3d6h index  3  (R/W): ROM Interface                              (not 655x0)\r
+ bit   0  Disable on-card ROM if set.\r
+         Enable ROM at C0000h-C7FFFh if clear.\r
+\r
+ 3d6h index  4  (R/W): Memory Mapping           \r
+ bit 0-1  (82c452/3) Display Memory Size:\r
+                     0: 256Kb, 1: 512Kb, 2: 1Mb.\r
+         (655x0) Memory Configuration\r
+                  0: 2 x 256Kx4 D/VRAM  256K tot   8 bit datapath\r
+                  1: 4 x 256Kx4 D/VRAM  512K tot  16 bit datapath\r
+                  3: 2 x 512Kx8   DRAM    1M tot  16 bit datapath\r
+       2  (82c451/5/6/7) Enable bank access if set\r
+         (82c452/3, 655x0) If set CRTC Address can cross bank boundaries.\r
+       3  (82c457) If set DRAM timing is for 64Kx16 (4 WE, 1 CAS)\r
+                  if clear for 64Kx4 (4 CAS, 1 WE).\r
+         (655x0)  Enables bank addressing if set.\r
+       4  (655x0)  If set VRAM interface, else DRAM interface.\r
+       5  (655x0)  If set CPU memory write buffer is enabled.\r
+       6  (655x0)  If set enables 0WS capability.\r
+       7  (655x0)  If set allows faster 0WS cycle timing.\r
+  \r
+ 3d6h index  5h (R/W): Sequencer Control                       (452/3/7 only)\r
+ bit   2  (82c457)  Clock Pin Polarity.\r
+                   If set CLK0 is defined as a common clock and CLK1/S0\r
+                   and CLK2/S1 are select outputs. If clear one of CLK0,\r
+                   CLK1 and CLK2 is selected as the display clock.\r
+\r
+ 3d6h index  6h (R/W): DRAM Interface                           (82c452 only)\r
+\r
+ 3d6h index  6h (R/W): Palette Control Register                 (655x0 only)\r
+ bit   0  If set enables external DAC if 3d6h index 6 bit 0 is 0.\r
+       1  If set disables the internal DAC.\r
+         Causes the DAC to power down and tri-states the outputs. \r
+       2  If set enables 16 bit/pixel operation.\r
+         Timing to an external DAC will be SC11486 (Tseng) compatible.\r
+         (Two bytes output per pixel, one on the rising edge of PCLK\r
+         and one on the falling edge).\r
+       3  If set 16 bit pixels are 5 red-6 green-5 blue.\r
+         If clear they are 5 bits of each.\r
+       4  If set the Sense Status bit (3C2h bit 4) is driven by the SENSE\r
+         pin from external logic.\r
+       5  If set bypasses the internal RAMDAC.\r
+         This bit should always be clear.\r
+     6-7  Color Reduction Select. \r
+         In flat panel modes these bits determine the algorithm used to\r
+         reduce 18 bit color data to 6 bits for mono panels.\r
+          0: NTSC weighting, 1: Equivalent weight, 2: Green only, 3: Color.\r
+\r
+ 3d6h index  8h (R/W): General Purpose Output Select B Register. (451/2/5/6/7 only)\r
+ bit   0  Select bit B for ERMIN/ pin.\r
+       1  Select bit B for TRAP/ pin.\r
+       2  (82c457) If set PNL14 pin outputs panel data bit 14,\r
+         if clear PNL14 pin outputs DATEN/.   \r
+\r
+ 3d6h index  9h (R/W): General Purpose Output Select A Register. (451/2/5/6/7 only)\r
+ bit   0  Select bit A for ERMIN/ pin.\r
+       1  Select bit A for TRAP/ pin.\r
+         Select A and B determine the output on the pin:\r
+           B      A        Output\r
+         clear  clear      Normal\r
+         clear   set       3-State\r
+          set   clear      Force low\r
+          set    set       Force high \r
\r
+ 3d6h index  Ah (R/W): Cursor Address Top                     (82c452/3 Only)\r
+ bit 0-1  Cursor Address bit 16,17\r
+     2-7  Reserved\r
+\r
+ 3d6h index  Bh (R/W): CPU Paging                         (82c451/5/6/7 only)\r
+ bit 0-1  Bank number in 64k chunks.\r
+ Note: This Bank register is used if in a 256 color mode and\r
+       the chip is a 82c451/5/6/7.\r
+\r
+ 3d6h index  Bh (R/W): Memory Paging Register          (82c452/3, 655x0 only)\r
+ bit   0  Enable extended paging (256 color paging) if set\r
+       1  If set Dual Pages are enabled. A0000h-A7FFFh uses 3d6h \r
+         index 10h, A8000h-AFFFFh uses 3d6h index 11h.\r
+       2  CPU Address divide by 4 (256 color addressing)\r
+       3  (655x0) If set CPU address divide by 2 is enabled.\r
+       4  (65530) If set Memory is mapped as 1MB linear Memory.\r
+\r
+ 3d6h index  Ch (R/W): Start Address Top               (82c452/3, 655x0 Only)\r
+ bit 0-1  Display Start Address bit 16,17.\r
+\r
+ 3d6h index  Dh (R/W): Auxiliary Offset Register\r
+ bit   0  Bit 8 of Offset field. If set each line is >255 words.\r
+       1  Bit 8 of simulated Offset field.\r
+\r
+ 3d6h index  Eh (R/W): Text Mode                         (82c452, 655x0 Only)\r
+ bit   0  (82c452) Extended text Mode Control ??\r
+       1  (82c452) Enable anti-aliased fonts if set\r
+       2  (655x0)  If set cursor is non-blinking.\r
+       3  (655x0)  If set Cursor style is Exclusive-Or.\r
+\r
+ 3d6h index  Fh (R/W): Software Flags 2                          (655x0 only)\r
+ bit 0-7  Software flags. \r
+\r
+ 3d6h index 10h (R/W): Single/Low Map                  (82c452/3, 655x0 Only)\r
+ bit 0-5  (82c452) Bank no in 4K/16K chunks.\r
+     0-7  (82c453) Bank no in 1K/4K chunks.\r
+ Note: This Bank register is used if in single-paging mode\r
+       or if addressing the lower half (32 or 64Kb) of the\r
+       adapters address range.\r
+\r
+ 3d6h index 11h (R/W): High Map                        (82c452/3, 655x0 Only)\r
+ bit 0-5  (82c452) Bank no in 4K/16K chunks.\r
+     0-7  (82c453) Bank no in 1K/4K chunks.\r
+ Note: This Bank register is used if addressing the upper\r
+       half (32 or 64Kb) of the adapters address range.\r
+\r
+ 3d6h index 14h (R/W): Emulation Mode Register\r
+ bit 0-1  Emulation Mode:\r
+          0=VGA/EGA, 1=CGA, 2=MDA and 3=Hercules.\r
+       2  (R) Hercules Configuration (3BFh) bit 0 Readback.\r
+         If set it is possible to set the Graphics Mode bit (3B8h bit 1).\r
+       3  (R) Hercules Configuration (3BFh) bit 1 Readback.\r
+         If set it is possible to set the Graphics Page bit (3B8h bit 7).\r
+       4  Display Enable Status Mode.\r
+         If set bit 0 of the Input Status Register 1 (3dAh)\r
+         shows the Hsync Status (as MDA/Hercules), if clear the\r
+         Display Enable is shown (as CGA/VGA). \r
+       5  Vertical Retrace Status Mode.\r
+         If set bit 3 of the Input Status Register 1 (3dAh)\r
+         shows the Video signal (as MDA/Hercules), if clear the\r
+         Vertical Retrace status is shown (as CGA/VGA). \r
+       6  Vsync Status Mode.\r
+         If clear bit 7 of the Input Status Register 1 (3dAh)\r
+         shows the Vsync Status (as MDA/Hercules).\r
+       7  Interrupt Output Function.\r
+         If clear the IRQ pin will always 3-state, if set it\r
+         will 3-state only when interrupts are disabled.  \r
+\r
+ 3d6h index 15h (R/W): Write Protect Register.\r
+ bit   0  Write Protect Group 1 Registers.\r
+         If set the Sequencer (3C4h), Graphics Controller (3CEh)\r
+         and Attribute Controller (3C0h) registers are write protected.\r
+       1  Write Protect Group 2 Registers.\r
+         If set the Cursor Size Register (3d4h index 9 bits 0-4) \r
+         and the Character Height registers (3d4h index 0Ah and 0Bh)\r
+         are write protected.\r
+       2  Write Protect Group 3 Registers.\r
+         If set CRT registers (3d4h) index: 7 bit 4, 8, 11h bits 4-5,\r
+         13h, 14h, 17h bits 0-1 and 3-7, 18h are write protected.\r
+       3  Write Protect Group 4 Registers.\r
+         If set CRT registers (3d4h) index: 9 bits 5-7, 10h, 11h bits 0-3\r
+         and 6-7, 12h, 15h, 16h, 17h bit 2 are write protected.\r
+       4  Write Protect Group 5 Register.\r
+         If set the Miscellaneous Output (3C2h) and Feature Control\r
+         (3dAh) registers are write protected.\r
+       5  Write Protect Group 6 Registers.\r
+         If set the DAC registers (3C6h-3C9h) are write protected.\r
+       6  Write Protect Group 0 Registers.\r
+         If set CRT registers (3d4h) index: 0, 1, 2, 3, 4, 5, 6,\r
+         7 bits 0-3 and 5-7 are write protected.\r
+\r
+ 3d6h index 16h (R/W): Trap Enable Register.                      (not 655x0)\r
+ bit   0  If set accesses to registers 3B4h or 3B5h cause a Trap.\r
+       1  If set accesses to registers 3B8h or 3BFh cause a Trap.\r
+       2  If set accesses to registers 3C0h-3CFh cause a Trap.\r
+       3  If set accesses to registers 3D4h or 3D5h cause a Trap.\r
+       4  If set accesses to registers 3D8h or 3D9h cause a Trap.\r
+       5  If set accesses to registers 3d4h index 0-0Bh and 10h-18h\r
+         cause a Trap.\r
+\r
+ 3d6h index 17h (R/W): Trap Status Register.                      (not 655x0)\r
+ bit   0  If set a trap occurred due to access to registers 3B4h or 3B5h.\r
+       1  If set a trap occurred due to access to registers 3B8h or 3BFh.\r
+       2  If set a trap occurred due to access to registers 3C0h-3CFh.\r
+       3  If set a trap occurred due to access to registers 3D4h or 3D5h.\r
+       4  If set a trap occurred due to access to registers 3D8h or 3D9h.\r
+       5  If set a trap occurred due to access to registers \r
+         3d4h index 0-0Bh or 10h-18h.\r
+ Note: Any bits in this register can be cleared by writing a 1 bit to them. \r
+\r
+ 3d6h index 18h (R/W): Alternate Horizontal Display Enable End Register\r
+ bit 0-7  This register replaces the Horizontal Display Enable End Register\r
+         (3d4h index 1) in low resolution CGA text and graphics modes,\r
+         Hercules Graphics and all flat panel modes.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+\r
+ 3d6h index 19h (R/W): Alternate Horizontal Sync Start Register\r
+ bit 0-7  This register replaces the Horizontal Sync Start Register\r
+         (3d4h index 4) in low resolution CGA text and graphics modes,\r
+         Hercules Graphics and all flat panel modes.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+\r
+ 3d6h index 1Ah (R/W): Alternate Horizontal Sync End Register\r
+ bit 0-4  Alternate Horizontal Sync End. Replaces 3d4h index 5 bits 0-4.\r
+     5-7  Alternate Horizontal Sync Delay. \r
+         For CRTs replaces 3d4h index 5 bits 5-6.\r
+ Note: This register replaces the Horizontal Sync End Register (3d4h index 5)\r
+       in low resolution CGA text and graphics modes, Hercules Graphics and\r
+       all flat panel modes.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
\r
+ 3d6h index 1Bh (R/W): Alternate Horizontal Total Register\r
+ bit 0-7  This register replaces the Horizontal Total Register\r
+         (3d4h index 0) in low resolution CGA text and graphics modes,\r
+         Hercules Graphics and all flat panel modes.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+\r
+ 3d6h index 1Ch (R/W): Alternate Horizontal Blank Start Register        (CRT)\r
+ bit 0-7  Alternate Horizontal Blank Start.\r
+ Note: For CRT systems this register replaces the Horizontal Blank Start\r
+       Register (3d4h index 2) in low resolution CGA text and graphics\r
+       modes and Hercules Graphics mode.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+ Note: This register has different meaning for CRT and Plat Panel systems.\r
+\r
+ 3d6h index 1Ch (R/W): Alternate Horizontal Blank End Register   (Flat Panel)\r
+ bit 0-7  For Flat Panel systems this value specifies the end of Horizontal\r
+         Blank in terms of character clocks.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+ Note: This register has different meaning for CRT and Plat Panel systems.\r
+\r
+ 3d6h index 1Dh (R/W): Alternate Horizontal Blank End Register          (CRT)\r
+ bit 0-4  Alternate Horizontal Blank End\r
+     5-6  Alternate Display Enable Skew Control. \r
+ Note: For CRT systems this register replaces the Horizontal Blank End\r
+       Register (3d4h index 3) in low resolution CGA text and graphics\r
+       modes, and Hercules Graphics mode.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+ Note: This register has different meaning for CRT and Plat Panel systems.\r
+\r
+ 3d6h index 1Dh (R/W): Alternate Horizontal Blank Start Register (Flat Panel)\r
+ bit 0-7  Alternate Horizontal Blank Start.\r
+ Note: For Flat Panel systems this register replaces the Horizontal Blank\r
+       Start Register (3d4h index 2).\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+ Note: This register has different meaning for CRT and Plat Panel systems.\r
+\r
+ 3d6h index 1Eh (R/W): Alternate Offset Register\r
+ bit 0-7  Alternate Offset.\r
+ Note: This register replaces the Offset Register (3d4h index 13h) in low\r
+       resolution CGA text and graphics modes and Hercules Graphics mode.\r
+ Note: Probably doesn't exist in the 82c451/2/3.\r
+\r
+ 3d6h index 1Fh (R/W): Virtual EGA Switch Register               (655x0 only)\r
+ bit 0-3  If bit 7 is 1 one of these bits is read back in the Input Status\r
+         Register 0 (3C2h bit 4) depending on Miscellaneous Output bits 2-3:\r
+          0: bit 3, 1: bit 2, 2: bit 1, 3:bit 0.\r
+       7  If set one of bits 0-3 is read back in the Input Status Register\r
+         (3C2h) bit 4.\r
+\r
+ 3d6h index 20h (R/W): Sliding Unit Delay                        (452/3 only)\r
+\r
+ 3d6h index 21h (R/W): Sliding Hold A                              (452 only)\r
+\r
+ 3d6h index 22h (R/W): Sliding Hold B                              (452 only)\r
+\r
+ 3d6h index 23h (R/W): Write Mask Control                        (452/3 Only)\r
+ bit   0  Enable VRAM Write Mask function if set\r
+     1-2  Write Bit Mask Select:\r
+          0: Write Bit Mask Pattern Register (3d6h index 24h)\r
+          1: Graphics Controller Bit Mask    (3CEh index 8)\r
+          2: Rotated CPU byte\r
+       3  Enable Fast Read/Modify/Write function if set\r
+\r
+ 3d6h index 24h (R/W): Write Bit Mask Pattern                 (82c452/3 only)\r
+ bit 0-7  Write Bit Mask (if 3d6h index 23h bit 1-2 =0)\r
+\r
+ 3d6h index 24h (R/W): Alternate Maximum Scanline Register       (655x0 only)\r
+ bit 0-4  Number of scanlines -1 per character row of TallFont.\r
+ Note: Used in Flat Panel text modes when TallFont is enabled.\r
+\r
+ 3d6h index 25h (R/W): FP AltGrHVirtPanel Size              (453, 655x0 only)\r
+ bit 0-7  Should be: (9/8)*(3d6h index 1Ch +1) -1.\r
+\r
+ 3d6h index 26h (R/W): Configuration                            (82c453 Only)\r
+ bit   0  PC/AT if set, PS/2 else\r
+     1-2  VRAM memory\r
+          0: 512k   16 chips of  64k x4\r
+          1: 512k    4 chips of 256k x4\r
+          2:   1M    8 chips of 256k x4\r
+          3: 512k    8 chips of  64k x4  ?????\r
+                             maybe 256k ??\r
+\r
+ 3d6h index 27h (R/W): Force Sync State\r
+\r
+ 3d6h index 28h (R/W): Video Interface\r
+ bit   0  BLANK/Display Enable Polarity.\r
+         Positive if set, Negative if clear.\r
+       1  Blank /Display Enable Select (CRT).\r
+         If set the BLANK/ pin outputs DE, if clear BLANK/\r
+       2  Shut Off Video.\r
+         If set the video signal is forced to default video\r
+         (3d6h index 2bh) during the blanking interval. \r
+       3  Shut Off Blank.\r
+         If set the BLANK/ output is forced active\r
+         during the blanking interval.\r
+         (655x0)  Read/writable, but has no function.\r
+       4  (655x0)  256 Color Video Path. \r
+         If set Video Data Path is 8 bits rather than 4 bits.\r
+       5  (655x0)  Interlace Video. CRT graphics modes only.\r
+         If set Video is interlaced.\r
+       6  (655x0)  8-bit Video Pixel Panning.\r
+         If set 3C0h index 13h bits 0-2 are used to control\r
+         pixel panning rather than bits 1-2.\r
+       7  (655x0)  Read/writable, but has no function.\r
+      \r
+ 3d6h index 29h (R/W): External Sync Control                       (452 only)\r
+\r
+ 3d6h index 2Ah (R/W): Frame Interrupt Count                       (452 Only)\r
+ bit 0-4  Generate Vertical Interrupt every (n+1) frames\r
+\r
+ 3d6h index 2Bh (R/W): Default Video Register                       (not 453)\r
+ bit 0-7  On CRTs this is the color displayed during blank time.\r
+\r
+ 3d6h index 2Ch (R/W): FP Vsync (FLM) Delay Register.\r
+ bit 0-7  Number of Hsync pulses between internal Vsync and the\r
+         rising edge of First Line Marker (FLM).\r
+ Note: Only used in Flat Panel modes when 3d6h index 2Fh bit 7 is 0..\r
+\r
+ 3d6h index 2Dh (R/W): FP Hsync (LP) Delay Register.\r
+ bit 0-7  Number of character clocks between the FP Blank inactive\r
+         edge and the rising edge of the LP.\r
+ Note: Only used in Flat Panel modes when 3d6h index 2Fh bit 6 is 0 and\r
+       graphics mode horizontal compression is disabled.\r
+\r
+ 3d6h index 2Eh (R/W): FP Hsync (LP) Delay Register.\r
+ bit 0-7  Number of character clocks between the FP Blank inactive\r
+         edge and the rising edge of the LP.\r
+ Note: Only used in Flat Panel modes when 3d6h index 2Fh bit 6 is 0\r
+       and 9 dot text mode is used.\r
+\r
+ 3d6h index 2Fh (R/W): FP Hsync (LP) Width Register\r
+ bit 0-3  Width of the LP output pulse in number of character clocks.\r
+         Only in 8 dot text modes on Flat Panels.\r
+       4  Bit 8 of the FP Hsync (LP) Delay Register (3d6h index 2Eh).\r
+       5  Bit 8 of the FP Hsync (LP) Delay Register (3d6h index 2Dh).\r
+       6  FP Hsync (LP) Delay Disable.\r
+         If set the FP Hsync (LP) active edge will coincide with the\r
+         FP Blank inactive edge.\r
+       7  FP Vsync (FLM) Delay Disable.\r
+         If set the external FP Vsync (FLM) will coincide with \r
+         the internal FP Vsync (FLM) active edge.\r
+\r
+ 3d6h index 30h (R/W): Graphics Cursor Start Address High\r
+ bit 0-7  Bit 8-15 of the Cursor Start Address.\r
+\r
+ 3d6h index 31h (R/W): Graphics Cursor Start Address Low\r
+ bit 0-7  Lowest 8 bits of the Cursor Start address.\r
+         3d6h index 30h and index Ah forms the upper 10 bits.\r
+         In 256 color modes this address has a granularity\r
+         of 16 bytes and 4 bytes in 16 color modes.\r
+\r
+ 3d6h index 32h (R/W): Graphics Cursor End Address\r
+ bit 0-7  End address of the cursor bit map.\r
+\r
+ 3d6h index 33h (R/W): Graphics Cursor X Position High\r
+ bit 0-3  Bits 8-11 of the X coordinate of the cursor.\r
+\r
+ 3d6h index 34h (R/W): Graphics Cursor X Position Low\r
+ bit 0-7  Lower 8 bits of the X coordinate of the cursor.\r
+\r
+ 3d6h index 35h (R/W): Graphics Cursor Y Position High\r
+ bit 0-3  Bits 8-11 of the Y coordinate of the cursor.\r
+\r
+ 3d6h index 36h (R/W): Graphics Cursor Y Position Low\r
+ bit 0-7  Lower 8 bits of the cursor Y coordinate.\r
+\r
+ 3d6h index 37h (R/W): Graphics Cursor Mode\r
+ bit   0  Cursor Enabled if set\r
+       1  Cursor Status enable\r
+       2  Horizontal Zoom. Zoom to 64 pixels wide if set.\r
+         (Normally 32 pixels wide).\r
+       3  Cursor Blink enabled if set\r
+       4  Cursor Blink Rate. 8 frames if clear, 16 if set\r
+\r
+ 3d6h index 38h (R/W): Graphics Cursor Plane Mask\r
+ bit   0  Enables graphics cursor in bit plane 0 if set\r
+       1  Enables graphics cursor in bit plane 1 if set\r
+       2  Enables graphics cursor in bit plane 2 if set\r
+       3  Enables graphics cursor in bit plane 3 if set\r
+\r
+ 3d6h index 39h (R/W): Graphics Cursor Color 0\r
+ bit 0-7  Background color of Graphics Cursor.\r
+\r
+ 3d6h index 3Ah (R/W): Graphics Cursor Color 1\r
+ bit 0-7  Foreground color of Graphics Cursor.\r
+\r
+ 3d6h index 44h (R/W): Scratch #0 Register           (82c453, 655x0 Only)\r
+ bit 0-7  Available\r
+\r
+ 3d6h index 45h (R/W): Scratch #1/Foreground Color   (82c453 Only)\r
+ bit 0-7  Used as foreground color if in Fast Font Paint mode,\r
+         Available as scratch else.\r
+\r
+ 3d6h index 50h (R/W): Panel Format                  (82c455/6/7 Only)\r
+ bit 0-1  Frame Rate Control\r
+          0: No gray scale simulated for mono,\r
+             8 colors simulated for color panels.\r
+          1: 4 simulated colors for color panels only\r
+             (64 colors displayed).\r
+          2: (82c455/6) 64 gray levels simulated for mono. panels only.\r
+             (82c457)   16 levels simulated for each color output.\r
+                        4096 colors simulated.\r
+          3: (82c457)   3 levels simulated for each color output.\r
+                        27 colors simulated.\r
+     2-3  Pulse Width Modulation\r
+          0: No gray scales for mono or color systems.\r
+          1: 4 colors supported by the color panels only\r
+             (64 colors displayed).\r
+          2: 16 gray levels supported by the mono panels only.\r
+          3: 256 gray levels supported by the\r
+             color single panels only.\r
+            (655x0) Dither Enable.\r
+              0: Disable Dither.\r
+              1: Enable dither for 256 color modes.\r
+              2: Enable dither for all modes. \r
+     4-5  Clock Divide (CD).\r
+          0: Shift Clock = Dot Clock\r
+          1: Shift Clock = Dot Clock/2\r
+          2: Shift Clock = Dot Clock/4\r
+          3: (655x0) Shift Clock = Dot Clock/8.\r
+       7  Shift Clock Mask.\r
+         If set the Shift Clock stops outside the\r
+         Display Enable interval.\r
+     6-7  (655x0)  VAM/FRC Control\r
+           0: bit 2-3 determine the dither:\r
+               0: 6 bpp VAM (dither bits 0-1).\r
+               1: 4 bpp VAM (dither bits 0-1).\r
+               2: 2 bpp VAM (dither bits 2-3).\r
+               3: 1 bpp VAM (dither bits 4-5).\r
+           1: 3 Bits/Pixel VAM (dither bits 1-2).\r
+              Use with bit 2-3=0 or 1 for mono panels,\r
+              Use with bit 2-3=0 for color panels.\r
+           2: (65530) 2-Frame FRC\r
+              3 level gray scale simulation without dither or\r
+              9 level gray scale simulation with dither.\r
+           3: (65530) 3 Bits/Pixel VAM + 2-Frame FRC.\r
+              15-level gray scale simulation without dithering and\r
+              56 level gray scale simulation with dithering.\r
+\r
+\r
+ 3d6h index 51h (R/W): Panel Type                    (82c455/6/7, 655x0 Only)\r
+ bit   0  (82c455/6) Double drive if set, single else\r
+       1  Double panel if set, single else\r
+     2-3  Type of display\r
+          0=LCD, 1=CRT, 2=Plasma or Electrolum.\r
+       2  (655x0) Display Type. 0=CRT, 1=Flat Panel.\r
+       3  (655x0) 8/16 bit FP Video Interface.\r
+         If set the Flat Panel Video interface is 16 bit.\r
+     4-5   0=Color panel 3 bit data pack\r
+          1=Color Panel 1 bit data pack\r
+          2=(82c455/6) Monochrome Panel\r
+          3=(82c457)   Extended 4-bit pack\r
+       4  (655x0) Video Skew. \r
+         If set Video data is delayed 1 shift clock cycle.\r
+       5  (655x0) Shift Clock Mask (SM). Flat Panel mode only.\r
+         If set the shift clock is forced low outside the display\r
+         interval. If clear it also toggles outside the interval.\r
+       6  Flat Panel Compatibility enabled if set\r
+       7  Text Video output polarity\r
+\r
+ 3d6h index 52h (R/W): Panel Size                           (82c455/6/7 Only)\r
+ bit 0-1  Horizontal Size of panel\r
+          1=640 pixels, 2=720 pixels\r
+     3-6  Vertical Size of panel\r
+          1=200 lines, 2=350, 4=400, 8=480 lines\r
+\r
+ 3d6h index 52h (R/W): Power Down Control Register.              (655x0 only)\r
+ bit 0-2  FP Normal Refresh Count. Flat Panel modes only.\r
+         Number of memory refresh cycles to perform per scanline.\r
+       3  Panel Off Mode. If set the CRT/FP interface is inactive.\r
+       4  Panel Off Control Bit 0. Only effective if bit 3 is set.\r
+         If set the Video data, CRT and Flat Panel timing signals\r
+         are forced inactive, rather than only the Video data.\r
+       5  Panel Off Control bit 1. Only effective if bit 3 is set.\r
+         If set inactive video data and/or timing pins are tri-stated\r
+         rather than being driven.\r
+       6  Standby Control. Only effective if the STNDBY/ is low.\r
+         In standby mode the video output, timings and CPU interface\r
+         are inactive. If set set the Display memory refresh is derived\r
+         from the 32kHz input. If clear the DRAMs are self-refreshed.\r
+       7  CRT Mode Panel Off. Only effective in CRT modes.\r
+         If set Video data and timing signals are tri-stated. \r
+\r
+ 3d6h index 53h (R/W): Override Register             (82c455/6/7, 655x0 Only) \r
+ bit   0  Disable AR10D2. If set the ninth pixel of characters is\r
+         controlled by this register, if clear it is controlled \r
+         by the Mode Control Register (3C0h index 10h) bit 2.\r
+       1  Alternate Line Graphics Character Code.\r
+         Only effective if bit 0 is set.\r
+         If set the ninth pixel of a character is forced to the same value\r
+         as the 8th pixel. If clear it is forced to the background color.\r
+       2  (655x0) FRC option 1.\r
+       3  (655x0) FRC option 2.\r
+     4-5  (65530) Pixel Packing. Only effective for Color STN panels.\r
+            0: 3-bit Pack. 3d6h index 50h bits 4-5 can be 0,1 or 2.\r
+            1: 4-bit Pack. 3d6h index 50h bits 4-5 can be 1 or 1.\r
+            3: Extended 4-bit Pack. 3d6h index 50h bits 4-5 must be 1.\r
+       7  (65530) High Color Mode Flat Panel Operation.\r
+         If set Hi-Color operation is enabled in hi-res modes on\r
+         Flat panel. If clear it is enabled in low-res modes.\r
+\r
+\r
+ 3d6h index 54h (R/W): Alternate Miscellaneous Output Register    (82c455/6/7 Only)\r
+ bit   0  Panel Video Skew\r
+     2-3  Clock Select Bits\r
+       6  Hsync. Negative if set, Positive if clear.  \r
+       7  Vsync. Negative if set, Positive if clear.  \r
+ Note: For Flat Panel systems this register replaces the Miscellaneous\r
+            Output Register (3C2h).\r
+\r
+ 3d6h index 54h (R/W): FP Interface Register                    (655x0 Only)   \r
+ bit   0  FP Blank Polarity.\r
+         If set the BLANK/ pin has negative polarity.\r
+       1  If set the BLANK/ pin outputs only the FP Horizontal Blank\r
+         signal, if clear it outputs both Vertical and Horizontal\r
+         Blank signals.\r
+     2-3  FP Clock Select Bits 0-1.\r
+         In Flat Panel modes these bits replace 3C2h bits 2-3.\r
+     4-5  FP Feature Control bits 0-1.\r
+         In Flat Panel modes these bits replace 3dAh bits 0-1.\r
+       6  FP HSync (LP) Polarity.\r
+         If set the HSync (LP) pin has negative polarity.\r
+       7  FP VSync (FLM) Polarity.\r
+         If set the Vsync (FLM) pin has negative polarity. \r
+ Note: This register is only effective in Flat Panel modes.\r
+\r
+ 3d6h index 55h (R/W): Text Mode 350_A                      (82c455/6/7 Only)\r
+ bit 0-3  (Number of blank lines)-1 inserted between text rows\r
+         I.e.  if 5, insert 6 blank lines after a text line.\r
+       4  If clear lines are inserted.\r
+ Note: This register is used if in a 350 line text mode\r
+       and fonts are larger than 8 lines.\r
+\r
+ 3d6h index 55h (R/W): Horizontal Compensation Register          (655x0 Only)\r
+ bit   0  Enable Horizontal Compensation (EHCP)\r
+         If set Horizontal compensation is enabled.\r
+       1  Enable Automatic Horizontal Centring (EAHC)\r
+         If set (and bit 0 is set) EAHC is enabled.\r
+         Horizontal left and right borders will be computed\r
+         automatically.\r
+       2  Enable Text Mode Horizontal Compression (ETHC).\r
+         If set, bit 0 is set and we are in a Flat Panel Text\r
+         mode ETHC is enabled.\r
+         9-dot text modes will be forced to 8-bit.\r
+       5  Enable Automatic Horizontal Doubling (EAHD).\r
+         If set and bit 0 is set, EAHD is enabled.\r
+         If Horizontal Display Width (3d4h index 1) is less\r
+         than or equal to half the Horizontal Panel Size\r
+         (3d6h index 18h) horizontal pixel doubling will be forced.\r
+       6  Alternate CRT Hsync Polarity.\r
+         Negative if set, Positive if clear.\r
+       7  Alternate CRT Vsync Polarity.\r
+         Negative if set, Positive if clear. \r
+\r
+ 3d6h index 56h (R/W): Text Mode 350_B                      (82c455/6/7 Only)\r
+ bit 0-3  (Number of blank lines)-1 inserted between text rows\r
+       4  If clear lines are inserted.\r
+ Note: This register is used if in a 350 line text mode\r
+       and fonts are smaller than or equal to 8 lines.\r
+\r
+ 3d6h index 56h (R/W): Horizontal Centring Register             (655x0 Only)\r
+ bit 0-7  Horizontal Left Border.\r
+         Size of the left border in pixels  -1.\r
+         Only used if in a Flat Panel mode and non-automatic\r
+         horizontal centring is enabled.\r
+\r
+ 3d6h index 57h (R/W): Text Mode 400                        (82c455/6/7 Only)\r
+ bit 0-3  (Number of blank lines)-1 inserted between text rows\r
+       4  If clear lines are inserted.\r
+ Note: This register is used if in a 400 line text mode.\r
+\r
+ 3d6h index 57h (R/W): Vertical Compensation Register            (655x0 Only)\r
+ bit   0  Enable Vertical Compensation if set.\r
+       1  Enable Automatic Vertical Centring.\r
+         If set and bit 0 set, the image will automatically\r
+         be centred vertically.\r
+       2  Enable Text Mode Vertical Stretching.\r
+         If set and bit 0 set, text mode vertical\r
+         stretching is enabled. \r
+     3-4  Text Mode Vertical Stretching. If bit 0 & 2 set.\r
+           0 = Double Scanning (DS) and Line Insertion (LI)\r
+               with priority: DS+li, DS, LI.\r
+           1 = Double Scanning (DS) and Line Insertion (LI)\r
+               with priority: DS+LI, LI, DS.\r
+           2 = Double Scanning (DS) and TallFont (TF)\r
+               with priority: DS+TF, DS, TF.\r
+           3 = Double Scanning (DS) and TallFont (TF)\r
+               with priority: DS+TF, TF, DS.\r
+       5  Enable Vertical Stretching if set and bit 0 set.\r
+       6  Vertical Stretching.If bits 0 and 5 set.\r
+           0 = Double Scanning (DS) and Line Replication (LR)\r
+               with priority: DS+LR, DS, LR.\r
+           1 = Double Scanning (DS) and Line Replication (LR)\r
+               with priority: DS+LR, LR, DS.\r
+\r
+ 3d6h index 58h (R/W): Graphics Mode 350                    (82c455/6/7 Only)\r
+ bit 0-3  Number of scan lines between stretch/delete\r
+       4  Enable vertical Stretching if set\r
+       5  Enable vertical deletion if set\r
+       6  If set the value in bits 0-3 is incremented every other period.\r
+ Note: This register is used if in a 350 line graphics mode.\r
+\r
+ 3d6h index 58h (R/W): Vertical Centring Register               (655x0 Only)  \r
+ bit 0-7  Vertical Top Border LSBs.\r
+         Lower 8 bits of the Vertical Top Border.\r
+         Bits 8-9 are in 3d6h index 59h bits 5-6.\r
+ Note: used only in Flat panel modes when non-automatic\r
+       vertical centring is enabled.\r
+\r
+ 3d6h index 59h (R/W): Graphics Mode 400                    (82c455/6/7 Only)\r
+ bit 0-3  Number of scan lines between stretch/delete\r
+       4  Enable vertical Stretching if set\r
+       5  Enable vertical deletion if set\r
+       6  If set the value in bits 0-3 is incremented every other period.\r
+ Note: This register is used if in a 400 line graphics mode.\r
+\r
+ 3d6h index 59h (R/W): Vertical Line Insertion Register          (655x0 Only)\r
+ bit 0-3  Vertical line Insertion Height.\r
+         Number of lines -1 to insert between text rows.\r
+     5-6  Bits 8-9 of the Vertical Top Border (3d6h index 58h).\r
+ Note: This register is only used in Flat Panel text modes.\r
+       \r
+ 3d6h index 5Ah (R/W): Flat Panel Vertical Display Start_400      (82c455/6/7 Only)\r
+ bit 0-7  For 400 line Flat Panel modes  these are the lower 8 bits of the \r
+         Vertical Display Start (in scanlines). The upper 2 bits are in the\r
+         Flat Panel Vertical Overflow 2 Register (3d6h index 6Bh) bits 2-3.\r
+\r
+ 3d6h index 5Ah (R/W): Vertical Line Replication Register.       (655x0 Only)\r
+ bit 0-3  Vertical line Replication Height.\r
+         Number of lines-1 between replicated lines. \r
+         Double scanned lines are also counted.\r
+ Note: This register is only used when in Flat Panel text modes\r
+       and Line Replication is enabled.\r
+\r
+ 3d6h index 5Bh (R/W): Flat Panel Vertical Display End_400  (82c455/6/7 Only)\r
+ bit 0-7  For 400 line Flat Panel modes these are the lower 8 bits of the \r
+         Vertical Display End (in scanlines). The upper 2 bits are in the\r
+         Flat Panel Vertical Overflow 2 Register (3d6h index 6Bh) bits 6-7.\r
+\r
+ 3d6h index 5Bh (R/W): Panel Power Sequencing Delay register     (65530 Only)\r
+ bit 0-3  Panel Power Down sequencing Delay in 32ms counts. (0-480ms)\r
+     4-7  Panel Power Up Sequencing Delay in 4ms counts. (0-60ms)\r
+ Note: This register is used only when the Panel power Sequencing\r
+       feature is enabled. Default to 81h for compatibility with 65520.\r
+\r
+ 3d6h index 5Ch (R/W): Weight Clock Control Register A        (82c455/6 only)\r
+ bit 0-5  This register is used in Flat Panel mode when bit 7 of the Panel\r
+         Format Register (3d6h index 50h) is set and bits 2-3 of the same\r
+         register is either 1 or 2.\r
+         The time from Hsync to the first pulse on the WGTCLK is this\r
+         value*4 dot clocks.  See also 3d6h index 5Dh and 6Ch.\r
+\r
+ 3d6h index 5Dh (R/W): Weight Clock Control Register B        (82c455/6 only)\r
+ bit 0-5  This register is used in Flat Panel mode when bit 7 of the Panel\r
+         Format Register (3d6h index 50h) is set and bits 2-3 of the same\r
+         register is either 1 or 2.\r
+         The time between WGTCLK pulses is this value*4 dot clocks.\r
+         See also 3d6h index 5Ch and 6Ch.\r
+\r
+ 3d6h index 5Eh (R/W): ACDCLK Control Register       (82c455/6/7, 655x0 only)\r
+ bit 0-6  ACDCLK Count. Number of Hsync pulses between changes in ACDCLK.\r
+       7  If set the ACDCLK phase inverts every frame, if clear the ACDCLK\r
+         changes phase when the number of Hsynmc pulses specified in \r
+         bits 0-6 have elapsed.\r
+   \r
+ 3d6h index 5Fh (R/W): Power Down Mode Refresh Register    (82c455/6/7, 655x0 only)\r
+ bit 0-7  (82c455/6/7) Sleep Mode Refresh Frequency.\r
+         A refresh will happen for every (4*this value)+8 dot clocks.\r
+     0-1  (655x0) Power Down Refresh Frequency.\r
+         Refresh happens every xx micro seconds:  \r
+           0=16usek, 1=32 usek, 2=64 usek and 3=128 usek.\r
\r
+ 3d6h index 60h (R/W): Blink Rate Control            (82c455/6/7, 655x0 Only)\r
+ bit 0-5  Blink Rate.\r
+         Character Blink Freq = Vertical sync Freq * (Blink rate+1)\r
+         Cursor blink freq = Character Blink Freq *2.\r
+     6-7  Blink Cycle  1=25%, 2=50%, 3=75%\r
+\r
+ 3d6h index 61h (R/W): Smartmap Control                (82c455/6, 655x0 Only)\r
+ bit   0  If set enables Smartmap and bypasses internal color lookup table.\r
+     1-4  Threshold for (Foreground - Background) diff\r
+         if diff less than the threshold the foreground and\r
+         background colors will be spread (See 3d6h index 62h).\r
+       5  Smartmap Saturation value.\r
+         If set the result is calculated modulo 16, \r
+         if clear it is rounded to min. or max. values (0 and 0Fh).\r
+       6  (82c456, 655x0) Enhanced text if set\r
+         (reverses attributes 7h and Fh)\r
+       7  (655x0) Text Video Output Polarity (TVP) if set.\r
+         Only effective in Flat Panel modes. \r
+\r
+ 3d6h index 62h (R/W): Smartmap Shift Parameter        (82c455/6, 655x0 Only)\r
+ bit 0-3  Number of levels to shift foreground color\r
+         when too little difference (See 3d6h index 61h bit 1-4).\r
+     4-7  Number of levels to shift background color.\r
+\r
+ 3d6h index 63h (R/W): Graphics Color Mapping Control         (82c455/6 Only)\r
+ bit 0-3  Threshold color value for mono output.\r
+         All colors >= this value will be set to 1,\r
+         all lower to 0.\r
+       4  Use upper 4 bits of 256 color if set, lower if not.\r
+       5  Enable internal color lookup table if set\r
+       6  Write protect internal color look up table if set\r
+       7  Graphics output polarity\r
+\r
+ 3d6h index 63h (R/W): Smartmap Color Mapping Control            (655x0 only)\r
+ bit 0-5  Color Threshold. Used for mapping 6 bit color to 1 bit.\r
+         Color values greater than or equal than this value\r
+         are mapped to 1, and lower values are mapped to 0.\r
+       6  Must be set to 1.\r
+       7  Graphics Video Output Polarity\r
+         Inverted polarity if set, normal if clear.\r
+         Graphics video output only.\r
+\r
+ 3d6h index 64h (R/W): Alternate Vertical Total      (82c455/6/7, 655x0 only) \r
+ bit 0-7  Alternate Vertical Total\r
+ Note: For Flat Panel modes this register replaces the Vertical\r
+       Total Register (3d4h index 6).\r
+\r
+ 3d6h index 65h (R/W): Alternate Overflow            (82c455/6/7, 655x0 only) \r
+ bit   0  Alternate Vertical Total bit 8\r
+       1  (455/6/7) Alternate Vertical Display End bit 8.\r
+         (655x0)   Alternate Vertical Panel Size bit 8.\r
+       2  Alternate Vertical Sync Start bit 8.\r
+       3  (655x0) Alternate Vertical Sync Start bit 10.\r
+       4  (655x0) Alternate Vertical Total bit 10.\r
+       5  Alternate Vertical Total bit 9\r
+       6  (455/6/7) Alternate Vertical Display End bit 9.\r
+         (655x0)   Alternate Vertical Panel Size bit 9.\r
+       7  Alternate Vertical Sync Start bit 9.\r
+\r
+ 3d6h index 66h (R/W): Alternate Vertical Sync Start (82c455/6/7, 655x0 only) \r
+ bit 0-7  Alternate Vertical Sync Start\r
+ Note: For Flat Panel modes this register replaces the Vertical\r
+       Sync Start Register (3d4h index 10h).\r
+\r
+ 3d6h index 67h (R/W): Alternate Vertical Sync End   (82c455/6/7, 655x0 only) \r
+ bit 0-3  Alternate Vertical Sync End\r
+ Note: For Flat Panel modes this register replaces the Vertical\r
+       Sync End Register (3d4h index 11h).\r
+\r
+ 3d6h index 68h (R/W): Alternate Vertical Display Enable    (82c455/6/7 only) \r
+ bit 0-7  Alternate Vertical Display Enable\r
+ Note: For Flat Panel modes this register replaces the Vertical\r
+       Display Enable Register (3d4h index 12h)\r
+\r
+ 3d6h index 69h (R/W): Vertical Panel Size Register.             (655x0 only)\r
+ bit 0-7  Vertical Panel Size. \r
+         Number of scan lines per frame.\r
+\r
+ 3d6h index 69h (R/W): Flat Panel Vertical Display Start_350      (82c455/6/7 only) \r
+ bit 0-7  For 350 line Flat Panel modes these are the lower 8 bits of the \r
+         Vertical Display Start (in scanlines). The upper 2 bits are in the\r
+         Flat Panel Vertical Overflow 2 Register (3d6h index 6Bh) bits 0-1.\r
+\r
+ 3d6h index 6Ah (R/W): Flat Panel Vertical Display End_350  (82c455/6/7 only) \r
+ bit 0-7  For 350 line Flat Panel modes these are the lower 8 bits of the \r
+         Vertical Display End (in scanlines). The upper 2 bits are in the\r
+         Flat Panel Vertical Overflow 2 Register (3d6h index 6Bh) bits 4-5.\r
+\r
+ 3d6h index 6Bh (R/W): Flat Panel Vertical Overflow 2       (82c455/6/7 only)\r
+ bit 0-1  Bits 8-9 of the Vertical Display Start_350 Register\r
+         (3d6h index 69h)\r
+     2-3  Bits 8-9 of the Vertical Display Start_400 Register (3d6h index 5Ah\r
+     4-5  Bits 8-9 of the Vertical Display End_350 Register (3d6h index 6Ah)\r
+     6-7  Bits 8-9 of the Vertical Display End_400 Register (3d6h index 5Bh)\r
+\r
+ 3d6h index 6Ch (R/W): Weight Clock Control Register        (82c455/6/7 only)\r
+ bit 0-5  Weight Clock Control Pulse Count.\r
+         Total number of pulses on the Weight Clock.\r
+         See Also 3d6h index 5Ch and 5Dh.\r
+\r
+ 3d6h index 6Ch (R/w): Programmable Output Drive Register        (655x0 only)\r
+ bit   0  Input Level Sense Selection Mode.\r
+         If set bit 1 is used to determine input threshold.\r
+         If clear chip detects VCC voltage internally.\r
+       1  Input Level Sense Selection Voltage.\r
+         If set VCC for internal logic is 3.3V\r
+         if clear it is 5V.\r
+       2  Flat Panel Interface Output Drive Select\r
+         If set Higher drive, if clear Lower drive.\r
+       3  Bus Interface Output Drive Select.\r
+         If set Higher drive, if clear Lower drive.\r
+       4  Memory Interface output Drive Select.\r
+         If set Higher drive, if clear Lower drive.\r
+               \r
+ 3d6h index 6Dh (R/W): FRC and Palette Control                (82c456/7 Only)\r
+ bit   3  Enable Frame Rate Control\r
+     4-5  Maximum number of gray levels.\r
+           0: 64 level FRC\r
+           1: 16 level FRC with dither for 256 color modes.\r
+           2: 64 level FRC with dither for low gray levels.\r
+           3: 16 level FRC only.\r
+     6-7  Usage of External Palette:\r
+           0: Bypass\r
+           1: Bypass for 16 color modes, use for 256 color.\r
+           2: Always use\r
+           3: 16 grays for 16 color modes, 64 for 256 color.\r
+\r
+ 3d6h index 6Eh (R/W): Polynomial FRC Control          (82c456/7, 655x0 Only)\r
+ bit 0-3  Polynomial N value for Frame Rate Control\r
+     4-7  Polynomial M value.\r
+\r
+ 3d6h index 6Fh (R/W): Frame Buffer Control register             (655x0 only)\r
+ bit   0  Frame Buffer Enable.\r
+         External Frame Buffer enabled if set.\r
+       1  Frame Accelerator enabled if set.\r
+       2  Frame Buffer memory Type.\r
+         If set Frame Buffer consists of 256Kx4 VRAM.\r
+         If clear Frame Buffer consists of 64Kx4 VRAM\r
+     3-5  Frame Buffer Refresh Count.\r
+     6-7  Reserved. Must be set to 0. \r
+ Note: This register effective in Flat Panel mode only.\r
+\r
+ 3d6h index 70h (R/W): Setup/Disable Control Register.           (655x0 only)\r
+ bit   7  3C3/46E8 Register Disabled if set.\r
+     \r
+ 3d6h index 7Dh (R/W): FP Compensation Diagnostic Register       (655x0 only)\r
+ bit 0-7  Reserved. returns 0.\r
+\r
+ 3d6h index 7Eh (R/W): CGA Color Select          \r
+      This is a copy of the CGA Color Select Register at 3D9h.\r
+      The copy at 3D9h is only visible in CGA emulation mode.\r
+      This register is always visible.  \r
+\r
+ 3d6h index 7Fh (R/W): Diagnostic \r
+ bit   0  if set 3-states pins: PALRD/, PALWR/, WR46E8/, HSYNC, VSYNC,\r
+         ACDCLK, BLANK/, P0-7, RDY, DATEN/ AND IRQ/.\r
+       1  If set 3-states pins: WE/, RAS/, CAS0/, CAS1/,\r
+         CAS2/, CAS3/, AA0-7 AND BA0-7.\r
+     2-5  Test Function Pins. Should be 0.\r
+       6  (655x0) Test Function Enabled if set.\r
+       7  (655x0) Special Test Function. Should be set to 0.\r
+  \r
+ 46E8h (R/W): Setup Control PC/AT Register\r
+ bit 0-2  Reserved\r
+       3  Enables Adapter VGA if set\r
+       4  Enters Setup Mode if set\r
+     5-7  Reserved\r
+Note: This is the same register as 94h.\r
+\r
+\r
+  Most every index of 3d6h is used by one one or more chip.\r
+\r
+  Bank Switching:\r
+\r
+   Bank switching is dependent on Chip version:\r
+\r
+                             16 color modes       256 color modes\r
+   Chip         #bank regs   #Banks Granularity   #banks Granularity\r
+   82c451/5/6      1                                  4    64Kbytes\r
+   82c452          2            64     4Kbytes       64    16Kbytes\r
+   82c453          2           256     1Kbytes      256     4Kbytes\r
+\r
+    For the 82c452 & 3  the window to display memory can start on\r
+    any boundary fitting the granularity of the chip/display mode.\r
+    When using 2 bankregisters, the address range available to the\r
+    adapter is split equally between the two bank registers. I.e.\r
+    A000h-A7FFh uses one bank, and A800h-AFFFh the other.\r
+    (Or A000h-AFFFh and B000h-BFFFh respectively if using the full\r
+    128 Kbytes range).\r
+\r
+\r
+\r
+  ID Chips and Technologies Chip Set:\r
+\r
+\r
+    vio($6F00);\r
+    if rp.al=$5F then\r
+      case rp.bl of\r
+       0:Chip&Tech 82c451 !!!\r
+       1:Chip&Tech 82c452 !!!   \r
+       2:Chip&Tech 82c455 !!!\r
+       3:Chip&Tech 82c453 !!!\r
+       5:Chip&Tech 82c456 !!!\r
+       6:Chip&Tech 82c457 !!!\r
+       7:Chip&Tech F65520 !!!\r
+       8:Chip&Tech F65530 !!!\r
+      end;\r
+\r
+\r
+\r
+  Video Modes:\r
+\r
+   60h T  132   25  16  (8x16)\r
+   61h T  132   50  16  (8x8)\r
+   6Ah G  800  600  16  planar\r
+   70h G  800  600  16  planar\r
+   71h G  960  720  16  planar   Cardinal only!\r
+   72h G 1024  768  16  planar\r
+   78h G  640  400 256  packed   Not documented/not all boards\r
+   79h G  640  480 256  packed\r
+   7Ah G  720  540 256  packed   Not documented/not all boards\r
+   7Bh G  800  600 256  packed\r
+   7Ch G  800  600 256  packed   (82c453 Only)\r
+   7Eh G 1024  768 256  packed   (82c453 Only)  \r
+\r
+  Bios Extensions:\r
+----------105F00-----------------------------\r
+INT 10 - Get Controller Information       (Chips and Technologies Super VGA)\r
+       AX = 5F00h\r
+Return: AL = 5F  If extended VGA control function supported\r
+       BL = CHIP Type:\r
+            Bits 4-7:\r
+              0=82c451\r
+              1=82c452\r
+              2=82c455\r
+              3=82c453\r
+              5=82c456 \r
+          Bits 0-3:  Revision Number\r
+       BH = Video Memory Size\r
+              0=256 Kbytes\r
+              1=512 Kbytes\r
+              2=1 Megabyte\r
+       CX = Miscellaneous Information\r
+            Bit 0  Dac Size. 0=6bit, 1=8bit\r
+                1  System Environment. 0=PC/AT, 1=PS/2\r
+                2  Extended text modes supported by BIOS\r
+                3  Reserved\r
+                4  Extended graphics modes supported by BIOS\r
+                5  Reserved\r
+                6  Graphics Cursor supported by BIOS\r
+                7  Anti Alias font supported by BIOS\r
+                8  Preprogrammed emulation supported by BIOS\r
+                9  Auto emulation supported by BIOS\r
+               10  Variable mode set at cold boot supported by BIOS\r
+               11  Variable mode set at warm boot supported by BIOS\r
+               12  Emulation mode set at cold boot supported by BIOS\r
+               13  Emulation mode set at warm boot supported by BIOS\r
+            14-15  Reserved\r
+----------105F01-----------------------------\r
+INT 10 - Set Emulation Mode               (Chips and Technologies Super VGA)\r
+       AX = 5F01h\r
+       BL = Operation Mode\r
+              0-1 Reserved\r
+                2 Enable CGA Emulation\r
+                3 Enable MDA Emulation\r
+                4 Enable Hercules Emulation\r
+                5 Enable EGA Emulation\r
+                6 Enable VGA Emulation\r
+Return: AL = 5Fh  If function supported\r
+       AH = Return Status\r
+              1 If Function Successful, 0 else\r
+----------105F02-----------------------------\r
+INT 10 - Auto Emulation Control           (Chips and Technologies Super VGA)\r
+       AX = 5F02h  Auto Emulation Control\r
+       BL = Selection\r
+              0= Enable Auto Emulation\r
+              1= Disable Auto Emulation\r
+Return: AL = 5Fh  If function supported\r
+       AH = Return Status\r
+              1 If Function Successful, 0 else\r
+----------105F03-----------------------------\r
+INT 10 - Set Power-on Video Configuration (Chips and Technologies Super VGA)\r
+       AX = 5F03h\r
+       BL = Configuration\r
+              0:  Set display mode as specified in the CX register\r
+                  at power-up.\r
+\r
+                  CL=Display Mode\r
+                  CH=Bits 0-1 Scanlines\r
+                                0=200 Lines\r
+                                1=350 Lines\r
+                                2=400 Lines\r
+                     Bit    7 Performance\r
+                                0= Reset after next boot\r
+                                1= Set until changed\r
+\r
+              1:  Set Emulation mode as specified in the CX register\r
+                  at power-up.\r
+\r
+                  CL=Emulation Mode (See 5F01h)\r
+                  CH=Bit 7 Performance\r
+                       0= Reset after next boot\r
+                       1= Set until changed\r
+\r
+Return: AL = 5Fh  If function supported\r
+       AH = Return Status\r
+              1 If Function Successful, 0 else\r
+----------105F90-----------------------------\r
+INT 10 - Return Save/Restore buffer size  (Chips and Technologies Super VGA)\r
+       AX = 5F90h\r
+       CX = Mask State\r
+            Bit 0  Save/Restore video hardware\r
+                1  Save/Restore BIOS data state\r
+                2  Save/Restore DAC state\r
+               15  Save/Restore type\r
+                     0= Save/Restore All state information\r
+                     1= Save/Restore super state information\r
+\r
+Return: AL = 5Fh  If function supported\r
+       BX = Number of 64byte blocks required\r
+----------105F91-----------------------------\r
+INT 10 - Save State                       (Chips and Technologies Super VGA)\r
+       AX = 5F91h\r
+       CX = Mask State\r
+            Bit 0  Save video hardware\r
+                1  Save BIOS data state\r
+                2  Save DAC state\r
+               15  Save type\r
+                     0= Save All state information\r
+                     1= Save super state information\r
+       ES:BX -> Buffer to save in.\r
+Return: AL = 5Fh  If function supported\r
+----------105F92-----------------------------\r
+INT 10 - Restore State                    (Chips and Technologies Super VGA)\r
+       AX = 5F92h\r
+       CX = Mask State\r
+            Bit 0  Restore video hardware\r
+                1  Restore BIOS data state\r
+                2  Restore DAC state\r
+               15  Restore type\r
+                     0= Restore All state information\r
+                     1= Restore super state information\r
+       ES:BX -> Buffer to restore from.\r
+Return: AL = 5Fh  If function supported\r
diff --git a/16/tweak16/MISC/READ.ME b/16/tweak16/MISC/READ.ME
new file mode 100755 (executable)
index 0000000..ba9b56d
--- /dev/null
@@ -0,0 +1,66 @@
+This is the second edition of my VGADOC info-pack on VGA adapters.\r
+\r
+Major improvements include new chipsets added or expanded upon\r
+and much better coverage of Hi/TrueColor.\r
+\r
+Also a number of bugs/misinformations have been corrected.\r
+\r
+For each chipset there is a .txt file with the info.\r
+\r
+\r
+\r
+\r
+Also included is WHATVGA, my utility for testing all this info:\r
+\r
+   whatvga.exe   The test program.\r
+   whatvga.pas   The generel part of the program.\r
+   supervga.pas  The device dependend part of Whatvga\r
+   whatvga.doc   Information and test report.\r
+   whatvga.lst   The list of all modes supported\r
+\r
+\r
+\r
+I'm currently looking for (among other things) the following chipsets:\r
+\r
+  S3        new 928, 801 and 805\r
+  Weitek    W5086, W5186 and new P9000\r
+  IIT       AGX...  (I've got some info, but I sure could use any other)\r
+  Tseng     ET4000W32  The long awaited accelerated version.\r
+  Paradise  WD90c31  - the accelerator part\r
+  Avance    AL2101 - The accelerator part\r
+  Primus    P2000  - The accelerator part\r
+\r
+  HiColor support for any chipset where it is not currently shown.\r
+\r
+\r
+\r
+I'ld be very interested in any information you may be able to supply,\r
+whether as new information, corrections or suggestions.\r
+\r
+Any major contributors will be given credit in future versions.\r
+Please specify if you have special requests as to names or addresses\r
+used (or not used).\r
+\r
+\r
+\r
+While I'll try to answer all queries, experience shows that I sometimes\r
+have trouble keeping up (I have this nasty habit of working 75 hour\r
+weeks).\r
+\r
+\r
+\r
+I can be contacted at the following addresses:\r
+\r
+Usenet:     jesperf@daimi.aau.dk\r
+                                  Please note that this is an account\r
+                                  a friend lets me use, so mail should\r
+                                  be addressed directly to me.\r
+                                  Also lets keep the volume down, ok?\r
+\r
+Phone:      +45 97 51 21 88       !These are at work, so please address\r
+Fax:        +45 97 51 26 21       !any queries explicitly to me.\r
+\r
+Snail-mail: Finn Thoegersen\r
+            Nordbanevej 3 C\r
+            DK-7800 Skive\r
+            Denmark\1a
\ No newline at end of file
diff --git a/16/tweak16/MISC/SETMODEX.ASM b/16/tweak16/MISC/SETMODEX.ASM
new file mode 100755 (executable)
index 0000000..34d0809
--- /dev/null
@@ -0,0 +1,87 @@
+; This file was taken from Michael Abrash' XSHARP package, a library\r
+; for programming mode X (320x240x256).\r
+\r
+; Mode X (320x240, 256 colors) mode set routine. Works on all VGAs.\r
+; C near-callable as:\r
+;       void Set320x240Mode(void);\r
+; Tested with TASM 2.0.\r
+; Modified from public-domain mode set code by John Bridges.\r
+\r
+SC_INDEX equ    03c4h   ;Sequence Controller Index\r
+CRTC_INDEX equ  03d4h   ;CRT Controller Index\r
+MISC_OUTPUT equ 03c2h   ;Miscellaneous Output register\r
+SCREEN_SEG equ  0a000h  ;segment of display memory in mode X\r
+\r
+        .model  small\r
+        .data\r
+; Index/data pairs for CRT Controller registers that differ between\r
+; mode 13h and mode X.\r
+CRTParms label  word\r
+        dw      00d06h  ;vertical total\r
+        dw      03e07h  ;overflow (bit 8 of vertical counts)\r
+        dw      04109h  ;cell height (2 to double-scan)\r
+        dw      0ea10h  ;v sync start\r
+        dw      0ac11h  ;v sync end and protect cr0-cr7\r
+        dw      0df12h  ;vertical displayed\r
+        dw      00014h  ;turn off dword mode\r
+        dw      0e715h  ;v blank start\r
+        dw      00616h  ;v blank end\r
+        dw      0e317h  ;turn on byte mode\r
+CRT_PARM_LENGTH equ     (($-CRTParms)/2)\r
+\r
+        .code\r
+        public  _Set320x240Mode\r
+_Set320x240Mode proc    near\r
+        push    bp      ;preserve caller's stack frame\r
+        push    si      ;preserve C register vars\r
+        push    di      ; (don't count on BIOS preserving anything)\r
+\r
+        mov     ax,13h  ;let the BIOS set standard 256-color\r
+        int     10h     ; mode (320x200 linear)\r
+\r
+        mov     dx,SC_INDEX\r
+        mov     ax,0604h\r
+        out     dx,ax   ;disable chain4 mode\r
+        mov     ax,0100h\r
+        out     dx,ax   ;synchronous reset while switching clocks\r
+\r
+        mov     dx,MISC_OUTPUT\r
+        mov     al,0e7h\r
+        out     dx,al   ;select 28 MHz dot clock & 60 Hz scanning rate\r
+\r
+        mov     dx,SC_INDEX\r
+        mov     ax,0300h\r
+        out     dx,ax   ;undo reset (restart sequencer)\r
+\r
+        mov     dx,CRTC_INDEX ;reprogram the CRT Controller\r
+        mov     al,11h  ;VSync End reg contains register write\r
+        out     dx,al   ; protect bit\r
+        inc     dx      ;CRT Controller Data register\r
+        in      al,dx   ;get current VSync End register setting\r
+        and     al,7fh  ;remove write protect on various\r
+        out     dx,al   ; CRTC registers\r
+        dec     dx      ;CRT Controller Index\r
+        cld\r
+        mov     si,offset CRTParms ;point to CRT parameter table\r
+        mov     cx,CRT_PARM_LENGTH ;# of table entries\r
+SetCRTParmsLoop:\r
+        lodsw           ;get the next CRT Index/Data pair\r
+        out     dx,ax   ;set the next CRT Index/Data pair\r
+        loop    SetCRTParmsLoop\r
+\r
+        mov     dx,SC_INDEX\r
+        mov     ax,0f02h\r
+        out     dx,ax   ;enable writes to all four planes\r
+        mov     ax,SCREEN_SEG ;now clear all display memory, 8 pixels\r
+        mov     es,ax         ; at a time\r
+        sub     di,di   ;point ES:DI to display memory\r
+        sub     ax,ax   ;clear to zero-value pixels\r
+        mov     cx,8000h ;# of words in display memory\r
+        rep     stosw   ;clear all of display memory\r
+\r
+        pop     di      ;restore C register vars\r
+        pop     si\r
+        pop     bp      ;restore caller's stack frame\r
+        ret\r
+_Set320x240Mode endp\r
+        end\r
diff --git a/16/tweak16/MISC/VGA.TXT b/16/tweak16/MISC/VGA.TXT
new file mode 100755 (executable)
index 0000000..12129aa
--- /dev/null
@@ -0,0 +1,551 @@
+       3C0h:  Attribute Controller: Address register\r
+       bit 0-4  Address of data register to write to port 3C0h\r
+               or read from port 3C1h (Reads only on VGA).\r
+            5  If set screen output is enabled and the palette can not be\r
+               modified, if clear screen output is disabled and the palette\r
+               can be modified.\r
+\r
+\r
+        Port 3C0h is special in that it is both address and data-write\r
+        register. Data reads happen from port 3C1h. An internal\r
+        flip-flop remembers whether it is currently acting as\r
+        address or data register.\r
+        Accesses to the attribute controller must be separated by\r
+        at least 250ns.\r
+        Reading port 3dAh will reset the flip-flop to address mode.\r
+\r
+\r
+       3C0h index 0-Fh  (r/W): Attribute: Palette\r
+        bit 0  (EGA) Primary Blue\r
+            1  (EGA) Primary Green\r
+            2  (EGA) Primary Red\r
+            3  (EGA) Secondary Blue\r
+            4  (EGA) Secondary Green\r
+            5  (EGA) Secondary Red\r
+          0-5  (VGA) Index into the 256 color DAC table.\r
+                     May be modified by 3C0h index 10h and 14h.\r
+\r
+       3C0h index 10h (r/W): Attribute: Mode Control Register\r
+        bit 0  Graphics mode if set, Alphanumeric mode else.\r
+            1  Monochrome mode if set, color mode else.\r
+            2  9-bit wide characters if set.\r
+               The 9th bit of characters C0h-DFh will be the same as\r
+               the 8th bit. Otherwise it will be the background color.\r
+            3  If set Attribute bit 7 is blinking, else high intensity.\r
+            5  (VGA Only) If set the PEL panning register (3C0h index 13h)\r
+                          is temporarily set to 0 from when the line\r
+                          compare causes a wrap around until the next\r
+                          vertical retrace when the register is automatically\r
+                          reloaded with the old value, else the PEL\r
+                          panning register ignores line compares.\r
+            6  (VGA Only) If set pixels are 8 bits wide.\r
+                          Used in 256 color modes.\r
+            7  (VGA Only) If set bit 4-5 of the index into the DAC table\r
+                          are taken from port 3C0h index 14h bit 0-1,\r
+                          else the bits in the palette register are used.\r
+\r
+       3C0h index 11h (r/W): Attribute: Overscan Color Register.\r
+       bit 0-5  Color of screen border. Color is defined as in the\r
+               palette registers.\r
+       Note: The EGA requires the Overscan color to be 0 in high resolution\r
+            modes.\r
+\r
+       3C0h index 12h (r/W): Attribute: Color Plane Enable Register\r
+        bit 0  Bit plane 0 is enabled if set.\r
+            1  Bit plane 1 is enabled if set.\r
+            2  Bit plane 2 is enabled if set.\r
+            3  Bit plane 3 is enabled if set.\r
+          4-5  Video Status MUX. Diagnostics use only.\r
+               Two attribute bits appear on bits 4 and 5 of the Input\r
+               Status Register 1 (3dAh).\r
+                 Value       EGA            VGA\r
+                   0      Red/Blue        Bit 2/Bit 0\r
+                   1      Blue'/Green     Bit 5/Bit 4\r
+                   2      Red'/Green'     Bit 3/Bit 1\r
+                   3                      Bit 7/Bit 6\r
+\r
+       3C0h index 13h (r/W): Attribute: Horizontal PEL Panning Register\r
+       bit 0-3  Indicates number of pixels to shift the display left\r
+                Value  9bit textmode   256color mode   Other modes\r
+                   0          1               0              0\r
+                   1          2              n/a             1\r
+                   2          3               1              2\r
+                   3          4              n/a             3\r
+                   4          5               2              4\r
+                   5          6              n/a             5\r
+                   6          7               3              6\r
+                   7          8              n/a             7\r
+                   8          0              n/a            n/a\r
+\r
+       3C0h index 14h (r/W): Attribute: Color Select Register  (VGA Only)\r
+       bit 0-1  If 3C0h index 10h bit 7 is set these 2 bits are used\r
+               as bits 4-5 of the index into the DAC table.\r
+          2-3  These 2 bits are used as bit 6-7 of the index into the\r
+               DAC table except in 256 color mode.\r
+\r
+       Note: this register does not affect 256 color modes.\r
+\r
+\r
+       3C2h (R): Input Status #0 Register\r
+        bit 4  Status of the switch selected by the Miscellaneous Output\r
+               Register 3C2h bit 2-3. Switch high if set.\r
+            5  (EGA Only) Pin 19 of the Feature Connector (FEAT0)\r
+                          is high if set\r
+            6  (EGA Only) Pin 17 of the Feature Connector (FEAT1)\r
+                          is high if set\r
+            7  (EGA Only ??) If set IRQ 2 has happened due to Vertical\r
+                     Retrace. Should be cleared by IRQ 2 interrupt routine\r
+                     by clearing port 3d4h index 11h bit 4.\r
+\r
+\r
+       3C2h (W): Miscellaneous Output Register\r
+        bit 0  If set Color Emulation. Base Address=3Dxh\r
+               else Mono Emulation. Base Address=3Bxh.\r
+            1  Enable CPU Access to video memory if set\r
+          2-3  Clock Select\r
+                 0: 14MHz(EGA)     25MHz(VGA)\r
+                 1: 16MHz(EGA)     28MHz(VGA)\r
+                 2: External(EGA)  Reserved(VGA)\r
+            4  (EGA Only) Disable internal video drivers if set\r
+            5  When in Odd/Even modes Select High 64k bank if set\r
+            6  Horizontal Sync Polarity. Negative if set\r
+            7  Vertical Sync Polarity. Negative if set\r
+               Bit 6-7 indicates the number of lines on the display:\r
+                        0=200(EGA)  Reserved(VGA)\r
+                        1=          400(VGA)\r
+                        2=350(EGA)  350(VGA)\r
+                        3=          480(VGA).\r
+\r
+       Note: Set to all zero on a hardware reset.\r
+       Note: On the VGA this register can be read from port 3CCh.\r
+\r
+\r
+       3C3h (W): Video Subsystem Enable Register\r
+        bit 0  Enables the VGA display if set\r
+\r
+\r
+       3C4h index  0  (r/W): Sequencer: Reset\r
+        bit 0  (EGA) Asynchronous Reset if clear\r
+            0  (VGA) Synchronous Reset just as bit 1\r
+            1  Synchronous Reset if clear\r
+\r
+       3C4h index  1  (r/W): Sequencer: Clocking Mode\r
+        bit 0  If set character clocks are 8 dots wide, else 9.\r
+            1  (EGA Only) If set the CRTC uses 2/5 of the clock cycles, else 4/5.\r
+            2  If set loads video serializers every other character\r
+               clock cycle, else every one.\r
+            3  If set the Dot Clock is Master Clock/2, else same as\r
+               Master Clock (See 3C2h bit 2-3). (Doubles pixels).\r
+            4  (VGA Only) If set loads video serializers every fourth\r
+                          character clock cycle, else every one.\r
+            5  (VGA Only) if set turns off screen and gives all memory\r
+                          cycles to the CPU interface.\r
+\r
+       3C4h index  2  (r/W): Sequencer: Map Mask Register\r
+        bit 0  Enable writes to plane 0 if set\r
+            1  Enable writes to plane 1 if set\r
+            2  Enable writes to plane 2 if set\r
+            3  Enable writes to plane 3 if set\r
+\r
+       3C4h index  3  (r/W): Sequencer: Character Map Select Register\r
+       bit 0-1  (EGA) Selects EGA Character Map (0..3) if bit 3 of\r
+                     the character attribute is clear.\r
+          2-3  (EGA) Selects EGA Character Map (0..3) if bit 3 of\r
+                     the character attribute is set.\r
+        0,1,4  (VGA) Selects VGA Character Map (0..7) if bit 3 of\r
+                     the character attribute is clear.\r
+        2,3,5  (VGA) Selects VGA Character Map (0..7) if bit 3 of\r
+                     the character attribute is set.\r
+\r
+                 Character Maps are placed at:\r
+                  Map no. (EGA/VGA)       Map no. (VGA)\r
+                     0       0k              4      8k\r
+                     1      16k              5     24k\r
+                     2      32k              6     40k\r
+                     3      48k              7     56k\r
+\r
+       3C4h index  4  (r/W): Sequencer: Memory Mode Register\r
+        bit 0  Set if in an alphanumeric mode, clear in graphics modes.\r
+            1  Set if more than 64kbytes on the adapter.\r
+            2  Enables Odd/Even addressing mode if set.\r
+               Odd/Even mode places all odd bytes in plane 1&3, and\r
+               all even bytes in plane 0&2.\r
+            3  (VGA Only)  If set address bit 0-1 selects video memory\r
+                           planes (256 color mode), rather than the\r
+                           Map Mask and Read Map Select Registers.\r
+\r
+       3C4h index 7 (R/W): Sequencer Horizontal Character Counter Reset Register.\r
+                          (VGA  Only).\r
+       Note: Undocumented by IBM. May not be available in all clones.\r
+       Note: A write to this register will cause the Horizontal Character Counter\r
+            to be held reset (=0) until a write happens to any of the Sequencer\r
+            registers index 0..6.\r
+            The Vertical Line counter is clocked by a signal derived from the\r
+            Horizontal Display Enable (which does not occur if the Horizontal\r
+            Character Counter is held reset).\r
+            Thus a write to index 7 during Vertical Retrace can stop the display\r
+            timing and allow software to start the next frame reasonably\r
+            synchronous to an external event.\r
+        \r
+       3C6h (R/W): PEL Mask          (VGA Only)\r
+       bit 0-7  This register is anded with the palette index sent\r
+               for each dot. Should be set to FFh.\r
+\r
+       3C7h (R): DAC State Register  (VGA Only)\r
+       bit 0-1  0 indicates the DAC is in Read Mode and 3 indicates\r
+               write mode.\r
+\r
+       3C7h (W): PEL Address Read Mode           (VGA Only)\r
+       bit 0-7  The PEL data register (0..255) to be read from 3C9h.\r
+\r
+       Note:  After reading the 3 bytes at 3C9h this register will\r
+             increment, pointing to the next data register.\r
+\r
+       3C8h (R/W): PEL Address Write Mode        (VGA Only)\r
+       bit 0-7  The PEL data register (0..255) to be written to 3C9h.\r
+       Note:  After writing the 3 bytes at 3C9h this register will\r
+             increment, pointing to the next data register.\r
+\r
+       3C9h (R/W): PEL Data Register             (VGA Only)\r
+       bit 0-5  Color value\r
+       Note:  Each read or write of this register will cycle through first\r
+             the registers for Red, Blue and Green, then increment the \r
+             appropriate address register, thus the entire palette can be\r
+             loaded by writing 0 to the PEL Address Write Mode register 3C8h\r
+             and then writing all 768 bytes of the palette to this register.\r
+\r
+       3CAh (R): Feature Control Register           (VGA Only)\r
+        Bit 3  (VGA Only) Vertical Sync Select\r
+                  If set Vertical Sync to the monitor is the logical OR\r
+                  of the vertical sync and the vertical display enable.\r
+       Note: This register is written to port 3dAh and read from 3CAh.\r
+\r
+\r
+       3CAh (W): Graphics 2 Position                (EGA Only)\r
+       bit 0-1  Select which bit planes should be controlled by\r
+               Graphics Controller #2. Always set to 1.\r
+\r
+       3CCh (R): Miscellaneous Output Register      (VGA Only)\r
+        bit 0  If set Color Emulation. Base Address=3Dxh\r
+                  else Mono Emulation. Base Address=3Bxh.\r
+            1  Enable CPU Access to video memory if set\r
+          2-3  Clock Select\r
+                 0= 25MHz, 1= 28MHz, 2= Reserved\r
+            5  When in Odd/Even modes Select High 64k bank if set\r
+            6  Horizontal Sync Polarity. Negative if set\r
+            7  Vertical Sync Polarity. Negative if set\r
+               Bit 6-7 indicates the number of lines on the display:\r
+                        0=Reserved, 1=400, 2=350, 3=480.\r
+       Note: This register is written to port 3C2h and read from port 3CCh.\r
+\r
+\r
+       3CCh (W): Graphics 1 Position                (EGA Only)\r
+       bit 0-1  Select which bit planes should be controlled by\r
+               Graphics Controller #1. Always set to 0.\r
+\r
+       3CEh index  0  (r/W): Graphics: Set/Reset Register\r
+        bit 0  If in Write Mode 0 and bit 0 of 3CEh index 1 is set\r
+                a write to display memory will set all the bits in\r
+                plane 0 of the byte to this bit, if the corresponding\r
+                bit is set in the Map Mask Register (3CEh index 8).\r
+            1  Same for plane 1 and bit 1 of 3CEh index 1.\r
+            2  Same for plane 2 and bit 2 of 3CEh index 1.\r
+            3  Same for plane 3 and bit 3 of 3CEh index 1.\r
+\r
+       3CEh index  1  (r/W): Graphics: Enable Set/Reset Register\r
+        bit 0  If set enables Set/reset of plane 0 in Write Mode 0.\r
+            1  Same for plane 1.\r
+            2  Same for plane 2.\r
+            3  Same for plane 3.\r
+\r
+       3CEh index  2  (r/W): Graphics: Color Compare Register\r
+       bit 0-3  In Read Mode 1 each pixel at the address of the byte read\r
+               is compared to this color and the corresponding bit in\r
+               the output set to 1 if they match, 0 if not.\r
+               The Color Don't Care Register (3CEh index 7) can exclude\r
+               bitplanes from the comparison.\r
+\r
+       3CEh index  3  (r/W): Graphics: Data Rotate\r
+       bit 0-2  Number of positions to rotate data right before it is\r
+               written to display memory. Only active in Write Mode 0.\r
+          3-4  In Write Mode 2 this field controls the relation between\r
+               the data written from the CPU, the data latched from the\r
+               previous read and the data written to display memory:\r
+                 0: CPU Data is written unmodified\r
+                 1: CPU data is ANDed with the latched data\r
+                 2: CPU data is ORed  with the latch data.\r
+                 3: CPU data is XORed with the latched data.\r
+\r
+\r
+       3CEh index  4  (r/W): Graphics: Read Map Select Register\r
+       bit 0-1  Number of the plane Read Mode 0 will read from.\r
+\r
+       3CEh index  5  (r/W): Graphics: Mode Register\r
+       bit 0-1  Write Mode: Controls how data from the CPU is\r
+               transformed before being written to display memory:\r
+                 0: Mode 0 works as a Read-Modify-Write operation.\r
+                    First a read access loads the data latches of the EGA/VGA\r
+                    with the value in video memory at the addressed location. \r
+                    Then a write access will provide the destination address \r
+                    and the CPU data byte. The data written is modified by the\r
+                    function code in the Data Rotate register (3CEh index 3) as\r
+                    a function of the CPU data and the latches, then data\r
+                    is rotated as specified by the same register.  \r
+                 1: Mode 1 is used for video to video transfers.\r
+                    A read access will load the data latches with the contents\r
+                    of the addressed byte of video memory. A write access will\r
+                    write the contents of the latches to the addressed byte.\r
+                    Thus a single MOVSB instruction can copy all pixels in the\r
+                    source address byte to the destination address.\r
+                 2: Mode 2 writes a color to all pixels in the addressed byte\r
+                    of video memory. Bit 0 of the CPU data is written to plane 0\r
+                    et cetera. Individual bits can be enabled or disabled through\r
+                    the Bit Mask register (3CEh index 8). \r
+                 3: (VGA Only) Mode 3 can be used to fill an area with a color and\r
+                    pattern. The CPU data is rotated according to 3CEh index 3 \r
+                    bits 0-2 and anded with the Bit Mask Register (3CEh index 8).\r
+                    For each bit in the result the corresponding pixel is set to\r
+                    the color in the Set/Reset Register (3CEh index 0 bits 0-3)\r
+                    if the bit is set and to the contents of the processor latch\r
+                    if the bit is clear.\r
+            2  (EGA Only) Forces all outputs to a high impedance state if set.\r
+            3  Read Mode\r
+                 0: Data is read from one of 4 bit planes depending\r
+                    on the Read Map Select Register (3CEh index 4).\r
+                 1: Data returned is a comparison between the 8 pixels\r
+                    occupying the read byte and the color in the\r
+                    Color Compare Register (3CEh index 2).\r
+                    A bit is set if the color of the corresponding\r
+                    pixel matches the register.\r
+            4  Enables Odd/Even mode if set (See 3C4h index 4 bit 2).\r
+            5  Enables CGA style 4 color pixels using even/odd bit pairs\r
+               if set.\r
+            6  (VGA Only) Enables 256 color mode if set.\r
+\r
+       3CEh index  6  (r/W): Graphics: Miscellaneous Register\r
+        bit 0  Indicates Graphics Mode if set, Alphanumeric mode else.\r
+            1  Enables Odd/Even mode if set.\r
+          2-3  Memory Mapping:\r
+                 0: use A000h-BFFFh\r
+                 1: use A000h-AFFFh   EGA/VGA Graphics modes\r
+                 2: use B000h-B7FFh   Monochrome modes\r
+                 3: use B800h-BFFFh   CGA modes\r
+\r
+       3CEh index  7  (r/W): Graphics: Color Don't Care Register\r
+        bit 0  Ignore bit plane 0 in Read mode 1 if clear.\r
+            1  Ignore bit plane 1 in Read mode 1 if clear.\r
+            2  Ignore bit plane 2 in Read mode 1 if clear.\r
+            3  Ignore bit plane 3 in Read mode 1 if clear.\r
+\r
+       3CEh index  8  (r/W): Graphics: Bit Mask Register\r
+       bit 0-7  Each bit if set enables writing to the corresponding\r
+               bit of a byte in display memory.\r
+\r
+\r
+       3d4h index  0  (r/W): CRTC: Horizontal Total Register\r
+       bit 0-7  (EGA) Horizontal Total Character Clocks-2\r
+          0-7  (VGA) Horizontal Total Character Clocks-5\r
+\r
+       3d4h index  1  (r/W): CRTC: Horizontal Display End Register\r
+       bit 0-7  Number of Character Clocks Displayed -1\r
+\r
+       3d4h index  2  (r/W): CRTC: Start Horizontal Blanking Register\r
+       bit 0-7  The count at which Horizontal Blanking starts\r
+\r
+       3d4h index  3  (r/W): CRTC: End Horizontal Blanking Register\r
+       bit 0-4  Horizontal Blanking ends when the last 5 (6 for VGA)\r
+               bits of the character counter equals this field.\r
+               (VGA) The sixth bit is found in port 3d4h index 5 bit 7.\r
+          5-6  Number of character clocks to delay start of display\r
+               after Horizontal Total has been reached.\r
+            7  (VGA Only) Access to Vertical Retrace registers if set\r
+                          If clear reads to 3d4h index 10h and 11h \r
+                          access the Lightpen readback registers ?? \r
+\r
+       3d4h index  4  (r/W): CRTC: Start Horizontal Retrace Register\r
+       bit 0-7  Horizontal Retrace starts when the Character Counter\r
+               reaches this value.\r
+\r
+       3d4h index  5  (r/W): CRTC: End Horizontal Retrace Register\r
+       bit 0-4  Horizontal Retrace ends when the last 5 bits of the\r
+               character counter equals this value.\r
+          5-6  Number of character clocks to delay start of display\r
+               after Horizontal Retrace.\r
+            7  (EGA) Provides Smooth Scrolling in Odd/Even mode.\r
+                     When set display starts from an odd byte.\r
+            7  (VGA) bit 5 of the End Horizontal Blanking count\r
+                     (See 3d4h index 3 bit 0-4).\r
+\r
+       3d4h index  6  (r/W): CRTC: Vertical Total Register\r
+       bit 0-7  Lower 8 bits of the Vertical Total\r
+               Bit 8 is found in 3d4h index 7 bit 0.\r
+               (VGA) Bit 9 is found in 3d4h index 7 bit 5.\r
+       Note: For the VGA this value is the number of scan lines in the display -2.\r
+\r
+       3d4h index  7  (r/W): CRTC: Overflow Register\r
+        bit 0  Bit 8 of Vertical Total (3d4h index 6)\r
+            1  Bit 8 of Vertical Display End (3d4h index 12h)\r
+            2  Bit 8 of Vertical Retrace Start (3d4h index 10h)\r
+            3  Bit 8 of Start Vertical Blanking (3d4h index 15h)\r
+            4  Bit 8 of Line Compare Register (3d4h index 18h)\r
+            5  (VGA) Bit 9 of Vertical Total (3d4h index 6)\r
+            6  (VGA) Bit 9 of Vertical Display End (3d4h index 12h)\r
+            7  (VGA) Bit 9 of Vertical Retrace Start (3d4h index 10h)\r
+\r
+       3d4h index  8  (r/W): CRTC: Preset Row Scan Register\r
+       bit 0-4  Number of lines we have scrolled down in the first\r
+               character row. Provides Smooth Vertical Scrolling.\r
+          5-6  (VGA Only) Number of bytes to skip at the start of\r
+               scanline. Provides Smooth Horizontal Scrolling\r
+               together with the Horizontal Panning Register\r
+               (3C0h index 13h).\r
+\r
+       3d4h index  9  (r/W): CRTC: Maximum Scan Line Register\r
+       bit 0-4  Number of scan lines in a character row -1\r
+            5  (VGA) Bit 9 of Start Vertical Blanking\r
+            6  (VGA) Bit 9 of Line Compare Register\r
+            7  (VGA) Doubles each scan line if set.\r
+               I.e displays 200 lines on a 400 display.\r
+\r
+       3d4h index  Ah (r/W): CRTC: Cursor Start Register\r
+       bit 0-4  First scanline of cursor within character.\r
+            5  (VGA) Turns Cursor off if set\r
+\r
+       3d4h index  Bh (r/W): CRTC: Cursor End Register\r
+       bit 0-4  Last scanline of cursor within character\r
+          5-6  Delay of cursor data in character clocks.\r
+\r
+       3d4h index  Ch (r/W): CRTC: Start Address High Register\r
+       bit 0-7  Upper 8 bits of the start address of the display buffer\r
+\r
+       3d4h index  Dh (r/W): CRTC: Start Address Low Register\r
+       bit 0-7  Lower 8 bits of the start address of the display buffer\r
+\r
+       3d4h index  Eh (r/W): CRTC: Cursor Location High Register\r
+       bit 0-7  Upper 8 bits of the address of the cursor\r
+\r
+       3d4h index  Fh (r/W): CRTC: Cursor Location Low Register\r
+       bit 0-7  Lower 8 bits of the address of the cursor\r
+\r
+       3d4h index 10h (R): CRTC: Light Pen High Register     (EGA Only)\r
+       bit 0-7  (EGA Only)  Upper 8 bits of the address of the\r
+                           lightpen position.\r
+\r
+       3d4h index 10h (r/W): CRTC: Vertical Retrace Start Register\r
+       bit 0-7  Lower 8 bits of Vertical Retrace Start. Vertical Retrace\r
+               starts when the line counter reaches this value.\r
+               Bit 8 is found in 3d4h index 7 bit 2.\r
+               (VGA Only) Bit 9 is found in 3d4h index 7 bit 7.\r
+\r
+       3d4h index 11h (R): CRTC: Light Pen Low Register      (EGA Only)\r
+       bit 0-7  (EGA Only)  Lower 8 bits of the address of the\r
+                           lightpen position.\r
+\r
+       3d4h index 11h (r/W): CRTC: Vertical Retrace End Register\r
+       bit 0-3  Vertical Retrace ends when the last 4 bits of the\r
+               line counter equals this value.\r
+            4  if clear Clears pending Vertical Interrupts.\r
+            5  Vertical Interrupts (IRQ 2) disabled if set.\r
+               Can usually be left disabled, but some systems\r
+               (including PS/2) require it to be enabled.\r
+            6  (VGA Only) If set selects 5 refresh cycles per\r
+                          scanline rather than 3.\r
+            7  (VGA Only) Disables writing to registers 0-7 if set\r
+                    3d4h index 7 bit 4 is not affected by this bit.\r
+\r
+       3d4h index 12h (r/W): CRTC: Vertical Display End Register\r
+       bit 0-7  Lower 8 bits of Vertical Display End. The display\r
+               ends when the line counter reaches this value.\r
+               Bit 8 is found in 3d4h index 7 bit 1.\r
+               (VGA Only) Bit 9 is found in 3d4h index 7 bit 6.\r
+\r
+       3d4h index 13h (r/W): CRTC: Offset register\r
+       bit 0-7  Number of bytes in a scanline / K. Where K is 2 for\r
+               byte mode, 4 for word mode and 8 for Double Word mode.\r
+\r
+       3d4h index 14h (r/W): CRTC: Underline Location Register\r
+       bit 0-4  Position of underline within Character cell.\r
+            5  (VGA Only) If set memory address is only changed\r
+                          every fourth character clock.\r
+            6  (VGA Only) Double Word mode addressing if set\r
+\r
+       3d4h index 15h (r/W): CRTC: Start Vertical Blank Register\r
+       bit 0-7  Lower 8 bits of Vertical Blank Start. Vertical blanking\r
+               starts when the line counter reaches this value.\r
+               Bit 8 is found in 3d4h index 7 bit 3.\r
+\r
+       3d4h index 16h (r/W): CRTC: End Vertical Blank Register\r
+       bit 0-4  (EGA) Vertical blanking stops when the lower 5 bits\r
+                     of the line counter equals this field.\r
+          0-6  (VGA) Vertical blanking stops when the lower 7 bits\r
+                     of the line counter equals this field.\r
+\r
+       3d4h index 17h (r/W): CRTC: Mode Control Register\r
+        bit 0  If clear use CGA compatible memory addressing system\r
+               by substituting character row scan counter bit 0 for\r
+               address bit 13, thus creating 2 banks for even and\r
+               odd scan lines.\r
+            1  If clear use Hercules compatible memory addressing\r
+               system by substituting character row scan counter bit 1 for\r
+               address bit 14, thus creating 4 banks.\r
+            2  If set increase scan line counter only every second line.\r
+            3  If set increase memory address counter only every other\r
+               character clock.\r
+            4  (EGA Only) If set disable the EGA output drivers. This bit\r
+               is used for other purposes in some Super VGA chips.\r
+            5  When in Word Mode bit 15 is rotated to bit 0 if this bit\r
+               is set else bit 13 is rotated into bit 0.\r
+            6  If clear system is in word mode. Addresses are rotated\r
+               1 position up bringing either bit 13 or 15 into bit 0.\r
+            7  Clearing this bit will reset the display system\r
+               until the bit is set again.\r
+\r
+       3d4h index 18h (r/W): CRTC: Line Compare Register\r
+       bit 0-7  Lower 8 bits of the Line Compare. When the Line counter\r
+                 reaches this value, the display address wraps to 0.\r
+                 Provides Split Screen facilities.\r
+                 Bit 8 is found in 3d4h index 7 bit 4.\r
+                 (VGA Only) Bit 9 is found in 3d4h index 9 bit 6.\r
+\r
+       3d4h index 22h (R): Memory Latch Register              (VGA - Undocumented).\r
+       bit 0-7  Reads the contents of the Graphics Controller Memory Data Latch\r
+               for the plane selected by 3C0h index 4 bit 0-1 (Read Map Select).\r
+       Note: This register is not documented by IBM and may not be available\r
+            on all clones.\r
+\r
+       3d4h index 24h (R): Attribute Controller Toggle Register. \r
+                                                             (VGA - Undocumented).  \r
+       bit 0-4  Attribute Controller Index. \r
+               The current value of the Attribute Index Register.\r
+            5  Palette Address Source. Same as 3C0h bit 5.\r
+            7  If set next read or write to 3C0h will access the data register.       \r
+       Note: This register is not documented by IBM and may not be available\r
+            on all clones.\r
+\r
+       3d4h index 30h-3Fh (W): Clear Vertical Display Enable. (VGA - Undocumented).   \r
+       bit   0  Setting this bit will clear the Vertical Display Enable thus \r
+               blanking the display for the rest of the frame and giving the CPU\r
+               total access to display memory until the start of the next frame.\r
+       Note: This register is not documented by IBM and may not be available\r
+            on all clones.\r
+\r
+       3dAh (R): Input Status #1 Register\r
+        bit 0  Either Vertical or Horizontal Retrace active if set\r
+            1  (EGA Only) Light Pen has triggered if set\r
+            2  (EGA Only) Light Pen switch is open if set\r
+            3  Vertical Retrace in progress if set\r
+          4-5  (EGA Only) Shows two of the 6 color outputs,\r
+               depending on 3C0h index 12h bit 4-5:\r
+                  Attr: Bit 4-5:   Out bit 4  Out bit 5\r
+                           0          Blue       Red\r
+                           1        I Blue       Green\r
+                           2        I Red      I Green\r
+\r
+       3dAh (W): Feature Control Register\r
+        bit 0  (EGA Only) Output to pin 21 of the Feature Connector.\r
+            1  (EGA Only) Output to pin 20 of the Feature Connector.\r
+            3  (VGA Only) Vertical Sync Select\r
+                  If set Vertical Sync to the monitor is the logical OR\r
+                  of the vertical sync and the vertical display enable.\r
+\r
+       Note: On the VGA this register can be read from port 3CAh.\r
diff --git a/16/tweak16/MISC/VGABIOS.TXT b/16/tweak16/MISC/VGABIOS.TXT
new file mode 100755 (executable)
index 0000000..40601ba
--- /dev/null
@@ -0,0 +1,707 @@
+----------1000-------------------------------\r
+INT 10 - VIDEO - SET VIDEO MODE\r
+       AH = 00h\r
+       AL = mode (see below)\r
+Return: AL = video mode flag (Phoenix BIOS)\r
+            20h mode > 7\r
+            30h modes <= 7 except mode 6\r
+            3Fh mode 6\r
+       AL = CRT controller mode byte (Phoenix 386 BIOS v1.10)\r
+Notes:       IBM standard modes do not clear the screen if the high bit of AL is set\r
+      (EGA or higher only)\r
+SeeAlso: AX=0070h,AX=007Eh,AX=10F0h,AX=6F05h,AH=FFh"GO32",INT 5F/AH=00h\r
+\r
+Values for video mode:\r
+     text/ text   pixel pixel    colors  display  scrn system\r
+     grph  resol  box   resoltn          pages   addr\r
+ 00h = T   40x25  8x14           16gray     8    B800 EGA\r
+     = T   40x25  8x16             16       8    B800 MCGA\r
+     = T   40x25  9x16             16       8    B800 VGA\r
+ 01h = T   40x25  8x14             16       8    B800 EGA\r
+     = T   40x25  8x16             16       8    B800 MCGA\r
+     = T   40x25  9x16             16       8    B800 VGA\r
+ 02h = T   80x25  8x14           16gray     4    B800 EGA\r
+     = T   80x25  8x16             16       4    B800 MCGA\r
+     = T   80x25  9x16             16       4    B800 VGA\r
+ 03h = T   80x25  8x14             16       4    B800 EGA\r
+     = T   80x25  8x16             16       4    B800 MCGA\r
+     = T   80x25  9x16             16       4    B800 VGA\r
+ 04h = G   40x25  8x8     320x200           4    B800 CGA,PCjr,EGA,MCGA,VGA\r
+ 05h = G   40x25  8x8     320x200 4gray          B800 CGA,PCjr,EGA\r
+     = G   40x25  8x8     320x200   4            B800 MCGA,VGA\r
+ 06h = G   80x25  8x8     640x200   2            B800 CGA,PCjr,EGA,MCGA,VGA\r
+ 07h = T   80x25  9x14            mono     var   B000 MDA,Hercules,EGA\r
+     = T   80x25  9x16            mono           B000 VGA\r
+ 0Bh =                 reserved (used internally by EGA BIOS)\r
+ 0Ch =                 reserved (used internally by EGA BIOS)\r
+ 0Dh = G   40x25  8x8     320x200  16       8    A000 EGA,VGA\r
+ 0Eh = G   80x25  8x8     640x200  16       4    A000 EGA,VGA\r
+ 0Fh = G   80x25  8x14    640x350 mono      2    A000 EGA,VGA\r
+ 10h = G   80x25  8x14    640x350   4       2    A000 64k EGA\r
+     = G                  640x350  16            A000 256k EGA,VGA\r
+ 11h = G   80x30  8x16    640x480 mono           A000 VGA,MCGA,ATI EGA,ATI VIP\r
+ 12h = G   80x30  8x16    640x480 16/256k        A000 VGA,ATI VIP\r
+     = G   80x30  8x16    640x480 16/64          A000 ATI EGA Wonder\r
+ 13h = G   40x25  8x8     320x200 256/256k       A000 VGA,MCGA,ATI VIP\r
+----------1001-------------------------------\r
+INT 10 - VIDEO - SET TEXT-MODE CURSOR SHAPE\r
+       AH = 01h\r
+       CH = bit 7    should be zero\r
+            bits 6,5 cursor blink\r
+               (00=normal, 01=invisible, 10=erratic, 11=slow)\r
+               (00=normal, other=invisible on EGA/VGA)\r
+            bits 4-0 top scan line containing cursor\r
+       CL = bottom scan line containing cursor (bits 0-4)\r
+Notes: buggy on EGA systems--BIOS remaps cursor shape in 43 line modes, but\r
+       returns unmapped cursor shape\r
+       applications which wish to change the cursor by programming the\r
+       hardware directly on EGA or above should call INT 10/AX=1130h or\r
+       read 0040h:0085h first to determine the current font height\r
+BUG:   AMI 386 BIOS and AST Premier 386 BIOS will lock up the system if AL\r
+       is not equal to the current video mode\r
+SeeAlso: AH=03h,AX=CD05h\r
+----------1002-------------------------------\r
+INT 10 - VIDEO - SET CURSOR POSITION\r
+       AH = 02h\r
+       BH = page number\r
+             0-3 in modes 2&3\r
+             0-7 in modes 0&1\r
+               0 in graphics modes\r
+       DH = row (00h is top)\r
+       DL = column (00h is left)\r
+SeeAlso: AH=03h,AH=05h\r
+----------1003-------------------------------\r
+INT 10 - VIDEO - GET CURSOR POSITION AND SIZE\r
+       AH = 03h\r
+       BH = page number\r
+             0-3 in modes 2&3\r
+             0-7 in modes 0&1\r
+               0 in graphics modes\r
+Return: AX = 0000h (Phoenix BIOS)\r
+       CH = start scan line\r
+       CL = end scan line\r
+       DH = row (00h is top)\r
+       DL = column (00h is left)\r
+Notes: a separate cursor is maintained for each of up to 8 display pages\r
+       many ROM BIOSes incorrectly return the default size for a color display\r
+       (start 06h, end 07h) when a monochrome display is attached\r
+SeeAlso: AH=01h,AH=02h\r
+----------1004-------------------------------\r
+INT 10 - VIDEO - READ LIGHT PEN POSITION (EGA Only)\r
+       AH = 04h\r
+Return: AH = light pen trigger flag\r
+            00h not down/triggered\r
+            01h down/triggered \r
+       DH,DL = row,column of character light pen is on \r
+       CH = pixel row (graphics modes 04h-06h)\r
+       CX = pixel row (graphics modes with >200 rows)\r
+       BX = pixel column\r
+Notes: on a CGA, returned column numbers are always multiples of 2 (320-\r
+       column modes) or 4 (640-column modes)\r
+       returned row numbers are only accurate to two lines\r
+----------1005-------------------------------\r
+INT 10 - VIDEO -  SELECT ACTIVE DISPLAY PAGE\r
+       AH = 05h\r
+       AL = new page number (00h to number of pages - 1) (see AH=00h)\r
+SeeAlso: AH=0Fh\r
+----------1006-------------------------------\r
+INT 10 - VIDEO - SCROLL UP WINDOW\r
+       AH = 06h\r
+       AL = number of lines by which to scroll up (00h = clear entire window)\r
+       BH = attribute used to write blank lines at bottom of window\r
+     CH,CL = row,column of window's upper left corner\r
+     DH,DL = row,column of window's lower right corner\r
+Note:  affects only the currently active page (see AH=05h)\r
+Warning: some implementations have a bug which destroys BP\r
+SeeAlso: AH=07h,AH=72h,AH=73h\r
+----------1007-------------------------------\r
+INT 10 - VIDEO - SCROLL DOWN WINDOW\r
+       AH = 07h\r
+       AL = number of lines by which to scroll down (00h=clear entire window)\r
+       BH = attribute used to write blank lines at top of window\r
+     CH,CL = row,column of window's upper left corner\r
+     DH,DL = row,column of window's lower right corner\r
+Note:  affects only the currently active page (see AH=05h)\r
+Warning: some implementations have a bug which destroys BP\r
+SeeAlso: AH=06h,AH=72h,AH=73h\r
+----------1008-------------------------------\r
+INT 10 - VIDEO - READ CHARACTER AND ATTRIBUTE AT CURSOR POSITION\r
+       AH = 08h\r
+       BH = page number (00h to number of pages - 1) (see AH=00h)\r
+Return: AH = attribute\r
+            bit    7: blink\r
+            bits 6-4: background color\r
+                      000 black\r
+                      001 blue\r
+                      010 green\r
+                      011 cyan\r
+                      100 red\r
+                      101 magenta\r
+                      110 brown\r
+                      111 white\r
+            bits 3-0: foreground color\r
+                      0000 black       1000 dark gray\r
+                      0001 blue        1001 light blue\r
+                      0010 green       1010 light green\r
+                      0011 cyan        1011 light cyan\r
+                      0100 red         1100 light red\r
+                      0101 magenta     1101 light magenta\r
+                      0110 brown       1110 yellow\r
+                      0111 light gray  1111 white\r
+       AL = character\r
+Notes: for monochrome displays, a foreground of 1 with background 0 is underlined\r
+       the blink bit may be reprogrammed to enable intense background colors\r
+       using AX=1003h or by programming the CRT controller\r
+SeeAlso: AH=09h,AX=1003h\r
+----------1009-------------------------------\r
+INT 10 - VIDEO - WRITE CHARACTER AND ATTRIBUTE AT CURSOR POSITION\r
+       AH = 09h\r
+       AL = character to display\r
+       BH = page number (00h to number of pages - 1) (see AH=00h)\r
+       BL = attribute (text mode) or color (graphics mode)\r
+            if bit 7 set in graphics mode, character is xor'ed onto screen\r
+       CX = number of times to write character\r
+Notes: all characters are displayed, including CR, LF, and BS\r
+       replication count in CX may produce an unpredictable result in graphics\r
+       modes if it is greater than the number of positions remaining in the\r
+       current row\r
+SeeAlso: AH=08h,AH=0Ah,AH=4Bh,INT 17/AH=60h,INT 1F,INT 43,INT 44\r
+----------100A-------------------------------\r
+INT 10 - VIDEO - WRITE CHARACTER ONLY AT CURSOR POSITION\r
+       AH = 0Ah\r
+       AL = character to display\r
+       BH = page number (00h to number of pages - 1) (see AH=00h)\r
+       BL = attribute (PCjr only) or color (graphics mode)\r
+            if bit 7 set in graphics mode, character is xor'ed onto screen\r
+       CX = number of times to write character\r
+Notes: all characters are displayed, including CR, LF, and BS\r
+       replication count in CX may produce an unpredictable result in graphics\r
+       modes if it is greater than the number of positions remaining in the\r
+       current row\r
+SeeAlso: AH=08h,AH=09h,AH=4Bh,INT 17/AH=60h,INT 1F,INT 43,INT 44\r
+----------100B--BH00-------------------------\r
+INT 10 - VIDEO - SET BACKGROUND/BORDER COLOR\r
+       AH = 0Bh\r
+       BH = 00h\r
+       BL = background/border color (border only in text modes)\r
+SeeAlso: AH=0Bh/BH=01h\r
+----------100B--BH01-------------------------\r
+INT 10 - VIDEO - SET PALETTE\r
+       AH = 0BH\r
+       BH = 01h\r
+       BL = palette ID\r
+            00h background, green, red, and brown/yellow\r
+            01h background, cyan, magenta, and white\r
+SeeAlso: AH=0Bh/BH=00h\r
+----------100C-------------------------------\r
+INT 10 - VIDEO - WRITE GRAPHICS PIXEL\r
+       AH = 0Ch\r
+       BH = page number\r
+       AL = pixel color (if bit 7 set, value is xor'ed onto screen)\r
+       CX = column\r
+       DX = row\r
+Notes: valid only in graphics modes\r
+       BH is ignored if the current video mode supports only one page\r
+SeeAlso: AH=0Dh,AH=46h\r
+----------100D-------------------------------\r
+INT 10 - VIDEO - READ GRAPHICS PIXEL\r
+       AH = 0Dh\r
+       BH = page number\r
+       CX = column\r
+       DX = row\r
+Return: AL = pixel color\r
+Notes: valid only in graphics modes\r
+       BH is ignored if the current video mode supports only one page\r
+SeeAlso: AH=0Ch,AH=47h\r
+----------100E-------------------------------\r
+INT 10 - VIDEO - TELETYPE OUTPUT\r
+       AH = 0Eh\r
+       AL = character to write\r
+       BH = page number\r
+       BL = foreground color (graphics modes only)\r
+Notes: characters 07h (BEL), 08h (BS), 0Ah (LF), and 0Dh (CR) are interpreted\r
+       and do the expected things\r
+       IBM PC ROMs dated 4/24/81 and 10/19/81 require that BH be the same as\r
+       the current active page\r
+SeeAlso: AH=02h,AH=0Ah\r
+----------100F-------------------------------\r
+INT 10 - VIDEO - GET CURRENT VIDEO MODE\r
+       AH = 0Fh\r
+Return: AH = number of character columns\r
+       AL = display mode (see AH=00h)\r
+       BH = active page (see AH=05h)\r
+Notes: if mode was set with bit 7 set ("no blanking"), the returned mode will\r
+       also have bit 7 set\r
+       EGA, VGA, and UltraVision return either AL=03h (color) or AL=07h\r
+       (monochrome) in all extended-row text modes\r
+SeeAlso: AH=00h,AH=05h,AX=1130h,AX=CD04h\r
+----------101000----------------------------\r
+INT 10 - VIDEO - SET SINGLE PALETTE REGISTER (PCjr,EGA,MCGA,VGA)\r
+       AX = 1000h\r
+       BL = palette register number (00h-0Fh)\r
+          = attribute register number (undocumented)\r
+            10h attribute mode control register (should let BIOS control this)\r
+            11h overscan color register (see also AX=1001h)\r
+            12h color plane enable register (bits 3-0 enable corresponding\r
+                text attribute bit)\r
+            13h horizontal PEL panning register\r
+            14h color select register\r
+       BH = color or attribute register value\r
+Notes: on MCGA, only BX = 0712h is supported\r
+       under UltraVision, the palette locking status (see AX=CD01h)\r
+       determines the outcome\r
+SeeAlso: AX=1002h,AX=1007h,AX=CD01h\r
+----------101001-----------------------------\r
+INT 10 - VIDEO - SET BORDER (OVERSCAN) COLOR (PCjr,EGA,VGA)\r
+       AX = 1001h\r
+       BH = border color (00h-3Fh)\r
+BUG: the original IBM VGA BIOS incorrectly updates the parameter save area\r
+     and places the border color at offset 11h of the palette table\r
+     rather than offset 10h\r
+Note: under UltraVision, the palette locking status (see AX=CD01h)\r
+      determines the outcome\r
+SeeAlso: AX=1002h,AX=1008h,AX=CD01h\r
+----------101002-----------------------------\r
+INT 10 - VIDEO - SET ALL PALETTE REGISTERS (PCjr,EGA,VGA)\r
+       AX = 1002h\r
+       ES:DX -> palette register list\r
+Note: under UltraVision, the palette locking status (see AX=CD01h)\r
+      determines the outcome\r
+SeeAlso: AX=1000h,AX=1001h,AX=1009h,AX=CD01h\r
+\r
+Format of palette register list:\r
+Offset  Size     Description\r
+ 00h   16 BYTEs  colors for palette registers 00h through 0Fh\r
+ 10h      BYTE   border color\r
+----------101003-----------------------------\r
+INT 10 - VIDEO - TOGGLE INTENSITY/BLINKING BIT (Jr, PS, TANDY 1000, EGA, VGA)\r
+       AX = 1003h\r
+       BL = new state\r
+            00h background intensity enabled\r
+            01h blink enabled\r
+Note: although there is no function to get the current status, bit 5 of\r
+      0040h:0065h indicates the state\r
+SeeAlso: AH=08h\r
+----------101007-----------------------------\r
+INT 10 - VIDEO - GET INDIVIDUAL PALETTE REGISTER (VGA,UltraVision v2+)\r
+       AX = 1007h\r
+       BL = palette or attribute (undoc) register number (see AX=1000h)\r
+Return: BH = palette or attribute register value\r
+Notes: UltraVision v2+ supports this function even on color EGA systems in\r
+       video modes 00h-03h, 10h, and 12h; direct programming of the palette\r
+       registers will cause incorrect results because the EGA registers are\r
+       write-only.  To guard against older versions or unsupported video\r
+       modes, programs which expect to use this function on EGA systems\r
+       should set BH to FFh on entry.\r
+SeeAlso: AX=1000h,AX=1009h\r
+----------101008-----------------------------\r
+INT 10 - VIDEO - READ OVERSCAN (BORDER COLOR) REGISTER (VGA,UltraVision v2+)\r
+       AX = 1008h\r
+Return: BH = border color (00h-3Fh)\r
+Notes: UltraVision v2+ supports this function even on color EGA systems in\r
+       video modes 00h-03h, 10h, and 12h; direct programming of the palette\r
+       registers will cause incorrect results because the EGA registers are\r
+       write-only.  To guard against older versions or unsupported video\r
+       modes, programs which expect to use this function on EGA systems\r
+       should set BH to FFh on entry.\r
+SeeAlso: AX=1001h\r
+----------101009-----------------------------\r
+INT 10 - VIDEO - READ ALL PALETTE REGISTERS AND OVERSCAN REGISTER (VGA)\r
+       AX = 1009h\r
+       ES:DX -> 17-byte buffer (see AX=1002h)\r
+Notes: UltraVision v2+ supports this function even on color EGA systems in\r
+       video modes 00h-03h, 10h, and 12h; direct programming of the palette\r
+       registers will cause incorrect results because the EGA registers are\r
+       write-only.  To guard against older versions or unsupported video\r
+       modes, programs which expect to use this function on EGA systems\r
+       should set the ES:DX buffer to FFh before calling.\r
+SeeAlso: AX=1002h,AX=1007h,AX=CD02h\r
+----------101010-----------------------------\r
+INT 10 - VIDEO - SET INDIVIDUAL DAC REGISTER (VGA/MCGA)\r
+       AX = 1010h\r
+       BX = register number\r
+       CH = new value for green (0-63)\r
+       CL = new value for blue (0-63)\r
+       DH = new value for red (0-63)\r
+SeeAlso: AX=1012h,AX=1015h\r
+----------101012-----------------------------\r
+INT 10 - VIDEO - SET BLOCK OF DAC REGISTERS (VGA/MCGA)\r
+       AX = 1012h\r
+       BX = starting color register\r
+       CX = number of registers to set\r
+       ES:DX -> table of 3*CX bytes where each 3 byte group represents one\r
+                byte each of red, green and blue (0-63)\r
+SeeAlso: AX=1010h,AX=1017h\r
+----------101013-----------------------------\r
+INT 10 - VIDEO - SELECT VIDEO DAC COLOR PAGE (VGA)\r
+       AX = 1013h\r
+       BL = subfunction\r
+            00h select paging mode\r
+                BH = 00h select 4 blocks of 64\r
+                BH = 01h select 16 blocks of 16\r
+            01h select page\r
+                BH = page number (00h to 03h) or (00h to 0Fh)\r
+Note: not valid in mode 13h\r
+SeeAlso: AX=101Ah\r
+----------101015-----------------------------\r
+INT 10 - VIDEO - READ INDIVIDUAL DAC REGISTER (VGA/MCGA)\r
+       AX = 1015h\r
+       BL = palette register number\r
+Return: DH = red value\r
+       CH = green value\r
+       CL = blue value\r
+SeeAlso: AX=1010h,AX=1017h\r
+----------101017-----------------------------\r
+INT 10 - VIDEO - READ BLOCK OF DAC REGISTERS (VGA/MCGA)\r
+       AX = 1017h\r
+       BX = starting palette register\r
+       CX = number of palette registers to read\r
+       ES:DX -> buffer (3 * CX bytes in size) (see also AX=1012h)\r
+Return: buffer filled with CX red, green and blue triples\r
+SeeAlso: AX=1012h,AX=1015h\r
+----------101018-----------------------------\r
+INT 10 - VIDEO - undocumented - SET PEL MASK (VGA/MCGA)\r
+       AX = 1018h\r
+       BL = new PEL value\r
+SeeAlso: AX=1019h\r
+----------101019-----------------------------\r
+INT 10 - VIDEO - undocumented - READ PEL MASK (VGA/MCGA)\r
+       AX = 1019h\r
+Return: BL = value read\r
+SeeAlso: AX=1018h\r
+----------10101A-----------------------------\r
+INT 10 - VIDEO - GET VIDEO DAC COLOR-PAGE STATE (VGA)\r
+       AX = 101Ah\r
+Return: BL = paging mode\r
+            00h four pages of 64\r
+            01h sixteen pages of 16\r
+       BH = current page\r
+SeeAlso: AX=1013h\r
+----------10101B-----------------------------\r
+INT 10 - VIDEO - PERFORM GRAY-SCALE SUMMING (VGA/MCGA)\r
+       AX = 101Bh\r
+       BX = starting palette register\r
+       CX = number of registers to convert\r
+SeeAlso: AH=12h/BL=33h\r
+----------1011-------------------------------\r
+INT 10 - VIDEO - TEXT-MODE CHARACTER GENERATOR FUNCTIONS (PS, EGA, VGA)\r
+       AH = 11h\r
+The following functions will cause a mode set, completely resetting\r
+the video environment, but without clearing the video buffer\r
+       AL = 00h, 10h: load user-specified patterns\r
+            ES:BP -> user table\r
+            CX  = count of patterns to store\r
+            DX  = character offset into map 2 block\r
+            BL  = block to load in map 2\r
+            BH  = number of bytes per character pattern\r
+       AL = 01h, 11h: load ROM monochrome patterns (8 by 14)\r
+            BL  = block to load\r
+       AL = 02h, 12h: load ROM 8 by 8 double-dot patterns\r
+            BL  = block to load\r
+       AL = 03h: set block specifier\r
+            BL  = block specifier\r
+              (EGA/MCGA) bits 0,1 = block selected by chars with attribute bit 3=0\r
+                         bits 2,3 = block selected by chars with attribute bit 3=1\r
+                   (VGA) bits 0,1,4 = block selected by attribute bit 3 = 0\r
+                         bits 2,3,5 = block selected by attribute bit 3 = 1\r
+       AL = 04h, 14h: load ROM 8x16 character set (VGA)\r
+            BL  = block to load\r
+The routines called with AL=1xh are designed to be called only\r
+immediately after a mode set and are similar to the routines called\r
+with AL=0xh, except that:\r
+      Page 0 must be active.\r
+      Bytes/character is recalculated.\r
+      Max character rows is recalculated.\r
+      CRT buffer length is recalculated.\r
+      CRTC registers are reprogrammed as follows:\r
+          R09 = bytes/char-1 ; max scan line (mode 7 only)\r
+          R0A = bytes/char-2 ; cursor start\r
+          R0B = 0            ; cursor end\r
+          R12 = ((rows+1)*(bytes/char))-1 ; vertical display end\r
+          R14 = bytes/char     ; underline loc\r
+                 (*** BUG: should be 1 less ***)\r
+SeeAlso: AX=CD10h\r
+----------1011-------------------------------\r
+INT 10 - VIDEO - GRAPHICS-MODE CHARACTER GENERATOR FUNCTIONS (PS, EGA, VGA)\r
+       AH = 11h\r
+       AL = 20h: set user 8 by 8 graphics characters (INT 1F)\r
+                 ES:BP -> user table\r
+       AL = 21h: set user graphics characters\r
+                 ES:BP -> user table\r
+                 CX      = bytes per character\r
+                 BL      = row specifier\r
+                       00h user set\r
+                           DL = number of rows\r
+                       01h 14 rows\r
+                       02h 25 rows\r
+                       03h 43 rows\r
+       AL = 22h: ROM 8 by 14 set\r
+                 BL = row specifier (see above)\r
+       AL = 23h: ROM 8 by 8 double dot\r
+                 BL = row specifier (see above)\r
+       AL = 24h: load 8x16 graphics characters (VGA/MCGA)\r
+                 BL = row specifier (see above)\r
+       AL = 29h: load 8x16 graphics characters (Compaq Systempro)\r
+                 BL = row specifier (see above)\r
+Notes: these functions are meant to be called only after a mode set\r
+       UltraVision v2+ sets INT 43 to the appropriate font for AL=22h,23h,24h,\r
+       and 29h\r
+SeeAlso: INT 1F, INT 43\r
+----------101130-----------------------------\r
+INT 10 - VIDEO - GET FONT INFORMATION (EGA, MCGA, VGA)\r
+       AX = 1130h\r
+       BH = pointer specifier\r
+            00h INT 1Fh pointer\r
+            01h INT 43h pointer\r
+            02h ROM 8x14 character font pointer\r
+            03h ROM 8x8 double dot font pointer\r
+            04h ROM 8x8 double dot font (high 128 characters)\r
+            05h ROM alpha alternate (9 by 14) pointer (EGA,VGA)\r
+            06h ROM 8x16 font (MCGA, VGA)\r
+            07h ROM alternate 9x16 font (VGA only)\r
+            11h (UltraVision v2+) 8x20 font (VGA) or 8x19 font (autosync EGA)\r
+            12h (UltraVision v2+) 8x10 font (VGA) or 8x11 font (autosync EGA)\r
+Return: ES:BP = specified pointer\r
+       CX    = bytes/character\r
+       DL    = character rows on screen - 1\r
+Note: for UltraVision v2+, the 9xN alternate fonts follow the corresponding\r
+      8xN font at ES:BP+256N\r
+SeeAlso: AX=1100h,AX=1120h,INT 1F,INT 43\r
+----------1012--BL10-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (PS, EGA, VGA, MCGA) - GET EGA INFO\r
+       AH = 12h\r
+       BL = 10h\r
+Return: BH = 00h color mode in effect (I/O port 3Dxh)\r
+            01h mono mode in effect (I/O port 3Bxh)\r
+       BL = 00h  64k bytes memory installed\r
+            01h 128k bytes memory installed\r
+            02h 192k bytes memory installed\r
+            03h 256k bytes memory installed\r
+       CH = feature bits\r
+       CL = switch settings\r
+----------1012--BL20-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (PS,EGA,VGA,MCGA) - ALTERNATE PRTSC\r
+       AH = 12h\r
+       BL = 20h  select alternate print screen routine\r
+Notes: installs a PrtSc routine from the video card's BIOS to replace the\r
+       default PrtSc handler from the ROM BIOS, which usually does not\r
+       understand screen heights other than 25 lines\r
+       some adapters disable print-screen instead of enhancing it\r
+SeeAlso: INT 05\r
+----------1012--BL30-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (VGA) - SELECT VERTICAL RESOLUTION\r
+       AH = 12h\r
+       BL = 30h\r
+       AL = vertical resolution\r
+            00h 200 scan lines\r
+            01h 350 scan lines\r
+            02h 400 scan lines\r
+Return: AL = 12h if function supported\r
+----------1012--BL31-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (VGA, MCGA) - PALETTE LOADING\r
+       AH = 12h\r
+       BL = 31h\r
+       AL = 00h enable default palette loading\r
+            01h disable default palette loading\r
+Return: AL = 12h if function supported\r
+----------1012--BL32-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (VGA, MCGA) - VIDEO ADDRESSING\r
+       AH = 12h\r
+       BL = 32h\r
+       AL = 00h enable video addressing\r
+            01h disable video addressing\r
+Return: AL = 12h if function supported\r
+----------1012--BL33-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (VGA, MCGA) - GRAY-SCALE SUMMING\r
+       AH = 12h\r
+       BL = 33h\r
+       AL = 00h enable gray scale summing\r
+            01h disable gray scale summing\r
+Return: AL = 12h if function supported\r
+SeeAlso: AX=101Bh,AX=BF06h\r
+----------1012--BL34-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (VGA) - CURSOR EMULATION\r
+       AH = 12h\r
+       BL = 34h\r
+       AL = 00h enable alphanumeric cursor emulation\r
+            01h disable alphanumeric cursor emulation\r
+Return: AL = 12h if function supported\r
+----------1012--BL35-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (PS) - DISPLAY-SWITCH INTERFACE\r
+       AH = 12h\r
+       BL = 35h\r
+       AL = 00h initial adapter video off\r
+            01h initial planar video on\r
+            02h switch active video off\r
+            03h switch inactive video on\r
+            80h *UNDOCUMENTED* set system board video active flag\r
+       ES:DX -> buffer (128 byte save area if AL = 0, 2 or 3)\r
+Return: AL = 12h if function supported\r
+----------1012--BL36-------------------------\r
+INT 10 - VIDEO - ALTERNATE FUNCTION SELECT (PS, VGA) - VIDEO REFRESH CONTROL\r
+       AH = 12h\r
+       BL = 36h\r
+       AL = 00h enable refresh\r
+            01h disable refresh\r
+Return: AL = 12h if function supported\r
+----------1013-------------------------------\r
+INT 10 - VIDEO - WRITE STRING (AT and later,EGA)\r
+       AH = 13h\r
+       AL = write mode\r
+            bit 0: update cursor after writing\r
+                1: string contains alternating characters and attributes\r
+       BH = page number\r
+       BL = attribute if string contains only characters\r
+       CX = number of characters in string\r
+       DH,DL = row,column at which to start writing\r
+       ES:BP -> string to write\r
+Notes: recognizes CR, LF, BS, and bell\r
+       also available PC or XT with EGA or higher\r
+       HP 95LX only supports write mode 00h\r
+BUG: on the IBM VGA Adapter, any scrolling which may occur is performed on\r
+     the active page rather than the requested page\r
+SeeAlso: AH=09h,AH=0Ah\r
+----------101A-------------------------------\r
+INT 10 - VIDEO - DISPLAY COMBINATION (PS,VGA/MCGA)\r
+       AH = 1Ah\r
+       AL = 00h read display combination code\r
+Return:          BL = active display code (see below)\r
+                BH = alternate display code\r
+            01h set display combination code\r
+                BL = active display code (see below)\r
+                BH = alternate display code\r
+Return: AL = 1Ah if function was supported\r
+\r
+Values for display combination code:\r
+  00h no display\r
+  01h monochrome adapter w/ monochrome display\r
+  02h CGA w/ color display\r
+  03h reserved\r
+  04h EGA w/ color display\r
+  05h EGA w/ monochrome display\r
+  06h PGA w/ color display\r
+  07h VGA w/ monochrome analog display\r
+  08h VGA w/ color analog display\r
+  09h reserved\r
+  0Ah MCGA w/ digital color display\r
+  0Bh MCGA w/ monochrome analog display\r
+  0Ch MCGA w/ color analog display\r
+  FFh unknown display type\r
+----------101B-------------------------------\r
+INT 10 - VIDEO - FUNCTIONALITY/STATE INFORMATION (PS,VGA/MCGA)\r
+       AH = 1Bh\r
+       BX = implementation type\r
+            0000h return functionality/state information\r
+       ES:DI -> 64 byte buffer for state information (see below)\r
+Return: AL = 1Bh if function supported\r
+       ES:DI buffer filled with state information\r
+SeeAlso: AH=15h\r
+\r
+Format of state information:\r
+Offset Size   Description\r
+ 00h   DWORD  address of static functionality table (see below)\r
+ 04h   BYTE   video mode in effect\r
+ 05h   WORD   number of columns\r
+ 07h   WORD   length of regen buffer in bytes\r
+ 09h   WORD   starting address of regen buffer\r
+ 0Bh   WORD   cursor position for page 0\r
+ 0Dh   WORD   cursor position for page 1\r
+ 0Fh   WORD   cursor position for page 2\r
+ 11h   WORD   cursor position for page 3\r
+ 13h   WORD   cursor position for page 4\r
+ 15h   WORD   cursor position for page 5\r
+ 17h   WORD   cursor position for page 6\r
+ 19h   WORD   cursor position for page 7\r
+ 1Bh   WORD   cursor type\r
+ 1Dh   BYTE   active display page\r
+ 1Eh   WORD   CRTC port address\r
+ 20h   BYTE   current setting of register (3?8)\r
+ 21h   BYTE   current setting of register (3?9)\r
+ 22h   BYTE   number of rows\r
+ 23h   WORD   bytes/character\r
+ 25h   BYTE   display combination code of active display\r
+ 26h   BYTE   DCC of alternate display\r
+ 27h   WORD   number of colors supported in current mode\r
+ 29h   BYTE   number of pages supported in current mode\r
+ 2Ah   BYTE   number of scan lines active\r
+             (0,1,2,3) = (200,350,400,480)\r
+ 2Bh   BYTE   primary character block\r
+ 2Ch   BYTE   secondary character block\r
+ 2Dh   BYTE   miscellaneous flags\r
+             bit 0 all modes on all displays on\r
+                 1 gray summing on\r
+                 2 monochrome display attached\r
+                 3 default palette loading disabled\r
+                 4 cursor emulation enabled\r
+                 5 0 = intensity; 1 = blinking\r
+                 6 PS/2 P70 plasma display (without 9-dot wide font) active\r
+                 7 reserved\r
+ 2Eh  3 BYTEs reserved (00h)\r
+ 31h   BYTE   video memory available\r
+             00h = 64K, 01h = 128K, 02h = 192K, 03h = 256K\r
+ 32h   BYTE   save pointer state flags\r
+             bit 0 512 character set active\r
+                 1 dynamic save area present\r
+                 2 alpha font override active\r
+                 3 graphics font override active\r
+                 4 palette override active\r
+                 5 DCC override active\r
+                 6 reserved\r
+                 7 reserved\r
+ 33h 13 BYTEs reserved (00h)\r
+\r
+Format of Static Functionality Table:\r
+Offset Size    Description\r
+ 00h   BYTE    modes supported #1\r
+              bit 0 to bit 7 = 1 modes 0,1,2,3,4,5,6 supported\r
+ 01h   BYTE    modes supported #2\r
+              bit 0 to bit 7 = 1 modes 8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh supported\r
+ 02h   BYTE    modes supported #3\r
+              bit 0 to bit 3 = 1 modes 10h,11h,12h,13h supported\r
+              bit 4 to bit 7 reserved\r
+ 03h  4 BYTEs  reserved\r
+ 07h   BYTE    scan lines supported\r
+              bit 0 to bit 2 = 1 if scan lines 200,350,400 supported\r
+ 08h   BYTE    total number of character blocks available in text modes\r
+ 09h   BYTE    maximum number of active character blocks in text modes\r
+ 0Ah   BYTE    miscellaneous function flags #1\r
+              bit 0 all modes on all displays function supported\r
+                  1 gray summing function supported\r
+                  2 character font loading function supported\r
+                  3 default palette loading enable/disable supported\r
+                  4 cursor emulation function supported\r
+                  5 EGA palette present\r
+                  6 color palette present\r
+                  7 color paging function supported\r
+ 0Bh   BYTE    miscellaneous function flags #2\r
+              bit 0 light pen supported\r
+                  1 save/restore state function 1Ch supported\r
+                  2 intensity blinking function supported\r
+                  3 Display Combination Code supported\r
+                4-7 reserved\r
+ 0Ch   WORD    reserved\r
+ 0Eh   BYTE    save pointer function flags\r
+              bit 0 512 character set supported\r
+                  1 dynamic save area supported\r
+                  2 alpha font override supported\r
+                  3 graphics font override supported\r
+                  4 palette override supported\r
+                  5 DCC extension supported\r
+                  6 reserved\r
+                  7 reserved\r
+ 0Fh   BYTE    reserved\r
+----------101C-------------------------------\r
+INT 10 - VIDEO - SAVE/RESTORE VIDEO STATE (PS50+,VGA)\r
+       AH = 1Ch\r
+       AL = 00h return state buffer size\r
+Return: BX = number of 64-byte blocks needed\r
+            01h save video state\r
+                ES:BX -> buffer\r
+            02h restore video state\r
+                ES:BX -> buffer containing previously saved state\r
+       CX = requested states\r
+            bit 0 video hardware\r
+                1 BIOS data areas\r
+                2 color registers and DAC state\r
+             3-15 reserved\r
+Return: AL = 1Ch if function supported\r
diff --git a/16/tweak16/MODES.DOC b/16/tweak16/MODES.DOC
new file mode 100755 (executable)
index 0000000..1d9df85
--- /dev/null
@@ -0,0 +1,99 @@
+The modes provided with TWEAK range from the obscure to the useful.\r
+This file has some hints and some vital information.\r
+\r
+First of all, a small warning:\r
+\r
+All mode files with an 's' at the and of the name (for example \r
+800x600s.16) use special dot clocks available on my Chips & \r
+Technologies 80c451 SVGA card.  Feel free to try them on your card, but \r
+don't expect them to work on a vanilla VGA.\r
+\r
+Modes with a 'c' at the end of the name are chained modes, to \r
+distinguish them from unchained modes of the same resolution.\r
+\r
+Then, some info about modes of particular interest:\r
+\r
+256x256c.256 - The chained Mode Q:\r
+  o  256x256 in 256 colors\r
+  o  exactly 1 page, uses every single byte of the video segment\r
+  o  1-to-1 linear pixel-to-address mapping, like mode 13h\r
+  o  keep (x,y) coordinates in a single word, and use that word as\r
+     an offset.  (Both x and y fit in a byte!)  No more MULs!\r
+  o  I named it 'Mode Q' for 256-cubed (256x256x256 = 256^3).\r
+\r
+256x256.256 - The unchained Mode Q:\r
+  o  256x256 in 256 colors\r
+  o  exactly 4 pages\r
+  o  4-to-1 planar mapping, like Mode X\r
+\r
+The 256-column modes have been provided in several other vertical\r
+resolutions: 224 and 240 lines\r
+\r
+400x600.256 - new, more stable version\r
+  o  400x600 in 256 colors (unchained)\r
+  o  1 page + 22144 bytes (55.36 lines)\r
+  o  4-to-1 planar mapping\r
+  o  good multisync monitor is still required\r
+\r
+400x300.256 - New square aspect ratio mode\r
+  o  400x300 in 256 colors (unchained)\r
+  o  That means a square aspect ratio if stretched to fill the screen!\r
+  o  2 pages + 22144 bytes (55.36 lines)\r
+  o  4-to-1 planar mapping\r
+  o  NOT based on the above 400x600 mode!  Uses the lowest vertical\r
+     frequency, and should thus prove much more stable than the\r
+     600-line mode.\r
+\r
+360x360.256\r
+  o  Interesting mode, which should work on most VGAs.\r
+\r
+360x270.256\r
+  o  New square aspect ratio mode\r
+\r
+\r
+Known problems:\r
+---------------\r
+  o  The 400x-modes won't work on LCDs and similar equipment\r
+\r
+  o  They also fail (won't synchronize) on cheap, basic VGA monitors\r
+     like the Samsung I used to have.  I think your monitor must\r
+     support SVGA resolutions of 800x600x16 and up for the 400x-modes\r
+     to work.  Your card can probably be plain, vanilla VGA though!\r
+\r
+  o  Don't expect the modes to line up perfectly with your monitor\r
+     screen's edges!  You might have to adjust the size and position of\r
+     the image with your monitor's control knobs.\r
+\r
+I have yet to see a VGA setup which doesn't support Mode Q.  Let me\r
+know if you have trouble.\r
+\r
+\r
+Disclaimer:\r
+-----------\r
+I can't guarantee that any of the above modes will be compatible with\r
+your VGA card.  I will accept no responsibility for damages arising\r
+from the use or abuse of the files included in this archive.\r
+\r
+If any of the above modes don't work on your configuration, send me\r
+an email stating the name/chipset of your (S)VGA card, and monitor\r
+type.  I'm especially interested in any changes you could make to get\r
+them to work!  Also mail me comments and suggestions to the TWEAK\r
+archive.  I will probably release a new version by the end of the\r
+summer.  Current ideas include:\r
+\r
+  o  A tutorial on tweaking in general, with focus on unchained, 256\r
+     color modes.  I ought to explain the significance of all timing\r
+     registers, and their relevance for the resulting resolution.\r
+  o  A program which takes as input a description of a screen mode\r
+     (i.e. resolution, colors) and outputs a list of suggested\r
+     registers settings.\r
+  o  A method of linking TWEAKed 256-color modes to Themie Gouthas' XLIB.\r
+  o  Context sensitive help on most registers and their individual bits\r
+     within the TWEAK utility.\r
+  o  Support for assembler and Pascal output.\r
+\r
+\r
+Regards from\r
+Robert Schmidt of Ztiff Zox Softwear, Norway\r
+\r
+e-mail: robert@stud.unit.no\r
diff --git a/16/tweak16/NAMEDREG.CPP b/16/tweak16/NAMEDREG.CPP
new file mode 100755 (executable)
index 0000000..ed10527
--- /dev/null
@@ -0,0 +1,52 @@
+/*\r
+       NamedReg.CPP version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Defines the member functions of the NamedRegister class declared in\r
+               Register.hpp.\r
+       Defines the stream operator >> to read named register info from\r
+               an istream.  (Text mode)\r
+*/\r
+\r
+#include <conio.h>\r
+#include <iostream.h>\r
+#include <string.h>\r
+#include "Screen.hpp"\r
+#include "Register.hpp"\r
+\r
+\r
+// NamedRegister::printCon() prints the register state to the console.\r
+//     If enableFlag is zero, the value is omitted from the display, and\r
+//     its place is filled with spaces.\r
+\r
+void NamedRegister::printCon()\r
+       {\r
+       textattr(enableFlag?REGENABLE_COLOR:REGDISABLE_COLOR);\r
+       cprintf("%03hx (%02hx) %24s : %02hx", getPort(), getIndex(),\r
+               name, getValue());\r
+       }\r
+\r
+/*\r
+       This operator reads the register port number, index and name from the\r
+       input stream.  (*Not* the value!)  Used for initializing each element\r
+       in the register table used by TWEAK.\r
+*/\r
+\r
+istream& operator>> (istream &in, NamedRegister &r)\r
+       {\r
+       int i;\r
+       char *n = new char[128];\r
+\r
+       in >> hex >> i;\r
+       r.setPort(i);\r
+       in >> i >> ws;\r
+       r.setIndex((unsigned char)(i));\r
+       in.getline(n, 128);\r
+       n[in.gcount()-1] = '\0';\r
+       r.name = new char[strlen(n)+1];\r
+       strcpy(r.name, n);\r
+       delete[] n;\r
+\r
+       return in;\r
+       }\r
+\r
diff --git a/16/tweak16/REGEDIT.CPP b/16/tweak16/REGEDIT.CPP
new file mode 100755 (executable)
index 0000000..f5cbef6
--- /dev/null
@@ -0,0 +1,70 @@
+/*\r
+       RegEdit.HPP\r
+\r
+*/\r
+\r
+#include <conio.h>\r
+#include "Screen.hpp"\r
+#include "RegEdit.HPP"\r
+\r
+\r
+RegisterEditor::RegisterEditor(istream &ins)\r
+       : RegisterTable(ins)\r
+       {\r
+       prevSel = select = 0;\r
+       }\r
+\r
+void RegisterEditor::printCon(int r)\r
+       {\r
+       // This gotoxy divides the registers into two columns.\r
+       gotoxy(40*(r / editHeight) +1, r % editHeight +1);\r
+       // Optionally print the left cursor.\r
+       textattr(CURSOR_COLOR);\r
+       cprintf(r==select ? "\20" : " ");\r
+       // Then put out the meat.\r
+       reg[r].printCon();\r
+       // And possibly the right cursor.\r
+       textattr(CURSOR_COLOR);\r
+       cprintf(r==select ? "\21" : " ");\r
+       // This gotoxy just puts the hardware cursor where it won't distract you.\r
+       gotoxy(40*(r / editHeight)+38, r % editHeight +1);\r
+       }\r
+\r
+void RegisterEditor::printAllCon()\r
+       {\r
+       for (int r = 0; r < registers; r++)\r
+               printCon(r);\r
+       }\r
+\r
+int RegisterEditor::updateSelect()\r
+       {\r
+       if (select < 0)\r
+               select = registers - 1;\r
+       else\r
+               if (select >= registers)\r
+                       select = 0;\r
+       if (prevSel != select)\r
+               {\r
+               printCon(prevSel);\r
+               prevSel = select;\r
+               }\r
+       printCon(select);\r
+       return select;\r
+       }\r
+\r
+\r
+// RegisterEditor::showBitMask() updates the bit pattern display with\r
+//     the value of selected register.  This is TWEAK specific.\r
+\r
+void RegisterEditor::showBitMask()\r
+       {\r
+       gotoxy(42,editHeight-4);\r
+       textattr(BITHEADER_COLOR);\r
+       cprintf("Bit mask: 7 6 5 4 3 2 1 0");\r
+       gotoxy(51,editHeight-3);\r
+       textattr(BITPATTERN_COLOR);\r
+       unsigned char v = reg[select].getValue();\r
+       for (int e=7; e>=0; e--)\r
+               cprintf( v&(1<<e) ? " 1" : " 0");\r
+       }\r
+\r
diff --git a/16/tweak16/REGEDIT.HPP b/16/tweak16/REGEDIT.HPP
new file mode 100755 (executable)
index 0000000..2dd4b40
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _REGEDIT_HPP\r
+#define _REGEDIT_HPP\r
+\r
+#include "RegTable.hpp"\r
+\r
+class RegisterEditor : public RegisterTable\r
+       {\r
+       int select, prevSel;\r
+public:\r
+       RegisterEditor(istream &);\r
+       int operator++()                        { return setSelect(select+1); }\r
+       int operator--()                        { return setSelect(select-1); }\r
+       NamedRegister& operator* (void) { return reg[select]; }\r
+       int getSelect()                         { return select; }\r
+       void printCon(int);\r
+       void printAllCon();\r
+       int updateSelect();\r
+       int setSelect(int s)            { select = s; return updateSelect(); }\r
+       void showBitMask();\r
+       };\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/REGISTER.CPP b/16/tweak16/REGISTER.CPP
new file mode 100755 (executable)
index 0000000..7cb25bc
--- /dev/null
@@ -0,0 +1,129 @@
+/*\r
+       Register.CPP version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Defines the member functions of the Register class declared in\r
+               Register.hpp.\r
+       Defines the stream operators >> and << to read and write register\r
+               info from istreams/to ostreams in *binary* format.\r
+*/\r
+\r
+#include <dos.h>\r
+#include <iostream.h>\r
+#include "Register.hpp"\r
+\r
+\r
+/*\r
+       Register::out()\r
+               Outputs the Register.value to the correct port/index.\r
+               It takes care of handling recognized special cases, like some\r
+               VGA ports, correctly.\r
+*/\r
+\r
+void Register::out()\r
+       {\r
+       switch (port)\r
+               {\r
+               // First handle special cases:\r
+\r
+               case ATTRCON_ADDR:\r
+                       inportb(STATUS_ADDR);           // reset read/write flip-flop\r
+                       outportb(ATTRCON_ADDR, index);\r
+                       outportb(ATTRCON_ADDR, value);\r
+                       break;\r
+\r
+               case SEQ_ADDR:\r
+                       if (index == 1)\r
+                               {\r
+                               // Reset the sequencer if the clock polarity settings\r
+                               //  are being accessed.\r
+                               outport(SEQ_ADDR, 0x0100);\r
+                               outport(SEQ_ADDR, value<<8 | 1);\r
+                               outport(SEQ_ADDR, 0x0300);\r
+                               break;\r
+                               }\r
+               case GRACON_ADDR:\r
+               case CRTC_ADDR:\r
+               case CHIPSTECH:\r
+                       outport(port, index | value<<8);\r
+                       break;\r
+\r
+               case MISC_ADDR:\r
+               case VGAENABLE_ADDR:\r
+               default:                                                // Default is to write the byte\r
+                       outportb(port, value);          //      directly to the port\r
+                       break;\r
+               }\r
+       }\r
+\r
+/*\r
+       Register::in()\r
+               Inputs Register.value to the associated hardware register.\r
+               It takes care of handling recognized special cases,\r
+               like some VGA ports, correctly.\r
+*/\r
+\r
+unsigned char Register::in()\r
+       {\r
+       switch (port)\r
+               {\r
+               // First handle special cases:\r
+\r
+               case MISC_ADDR:\r
+                       value = inportb(0x3cc);         // 0x3c2 is write-only, reading\r
+                                                                               // must be mapped to 0x3cc\r
+                       break;\r
+\r
+               case ATTRCON_ADDR:                              // This 1 is odd.  First do a read to\r
+                       inportb(STATUS_ADDR);           //      reset the index/data flip-flop.\r
+                                                                               //      Then give it the index, but:\r
+                                                                               //      set bit 5!  If cleared, VGA\r
+                                                                               //      output is disabled!\r
+                       outportb(ATTRCON_ADDR, index);\r
+                       value = inportb(ATTRCON_ADDR+1);\r
+                       break;\r
+\r
+               case SEQ_ADDR:                                  // These 3 are similar.  Give it the\r
+               case GRACON_ADDR:                               //      register index, then read the\r
+               case CRTC_ADDR:                                 //      byte from port+1.\r
+               case CHIPSTECH:\r
+                       outportb(port, index);\r
+                       value = inportb(port+1);\r
+                       break;\r
+\r
+               case VGAENABLE_ADDR:\r
+               default:                        // Default is to read the byte\r
+                       value = inportb(port);          //      directly from the port\r
+                       break;\r
+               }\r
+\r
+       return value;                                                   // Return value of first reg.\r
+       }\r
+\r
+/*\r
+       The following stream operators operate on Registers in *binary*\r
+       format, i.e. they are not suitable for communicating with text streams\r
+       like the keyboard or the screen (cin/cout).\r
+*/\r
+\r
+istream& operator>> (istream &in, Register &r)\r
+       {\r
+       r.port = unsigned(in.get()) | (unsigned(in.get()) << 8);\r
+       r.index = in.get();\r
+       r.value = in.get();\r
+\r
+       return in;\r
+       }\r
+\r
+ostream& operator<< (ostream &out, Register &r)\r
+       {\r
+       out.put(char(r.port));\r
+       out.put(char(r.port>>8));\r
+       out.put(r.index);\r
+       out.put(r.value);\r
+\r
+       return out;\r
+       }\r
+\r
+\r
+\r
diff --git a/16/tweak16/REGISTER.HPP b/16/tweak16/REGISTER.HPP
new file mode 100755 (executable)
index 0000000..d980df0
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+       Register.hpp version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Declares the Register class, members defined in Register.cpp.\r
+*/\r
+\r
+#ifndef _Register_HPP\r
+#define _Register_HPP\r
+\r
+#include <iostream.h>\r
+\r
+/*\r
+       xxxxADDR defines the base port number used to access VGA component xxxx,\r
+       and is defined for xxxx =\r
+               ATTRCON         -       Attribute Controller\r
+               MISC            -       Miscellaneous Register\r
+               VGAENABLE       -       VGA Enable Register\r
+               SEQ                     -       Sequencer\r
+               GRACON          -       Graphics Controller\r
+               CRTC            -       Cathode Ray Tube Controller\r
+               STATUS          -       Status Register\r
+*/\r
+\r
+#define ATTRCON_ADDR   0x3c0\r
+#define MISC_ADDR              0x3c2\r
+#define VGAENABLE_ADDR 0x3c3\r
+#define SEQ_ADDR               0x3c4\r
+#define GRACON_ADDR            0x3ce\r
+#define CRTC_ADDR              0x3d4\r
+#define STATUS_ADDR            0x3da\r
+\r
+// SVGA specific registers here:\r
+\r
+#define CHIPSTECH               0x3d6\r
+\r
+\r
+class  Register\r
+       {\r
+       unsigned                port;\r
+       unsigned char   index;\r
+       unsigned char   value;\r
+public:\r
+       Register(unsigned p=0, unsigned char i=0, unsigned char v=0)\r
+               { init(p,i,v); }\r
+       unsigned char init(unsigned p, unsigned char i, unsigned char v)\r
+               { port = p; index = i; return value = v; }\r
+       unsigned char init(Register& r)\r
+               { port = r.port; index = r.index; return value = r.value; }\r
+       void setPort(unsigned p)                { port = p; }\r
+       void setIndex(unsigned char i)  { index = i; }\r
+       void setValue(unsigned char v)  { value = v; }\r
+       unsigned getPort(void) const    { return port; }\r
+       unsigned char getIndex(void) const { return index; }\r
+       unsigned char getValue(void) const { return value; }\r
+       unsigned char operator++(void)  { return value++; }\r
+       unsigned char operator--(void)  { return value--; }\r
+       unsigned char operator++(int)   { return ++value; }\r
+       unsigned char operator--(int)   { return --value; }\r
+       unsigned char &operator *()             { return value; }\r
+       unsigned char operator=(Register &r)\r
+               { return init(r); }\r
+       unsigned operator() (int rbit, int len)\r
+       { return (value >> rbit) & (1 << len)-1; }\r
+\r
+       void out();\r
+       unsigned char in();\r
+\r
+       friend istream& operator>> (istream&, Register&);\r
+       friend ostream& operator<< (ostream&, Register&);\r
+       };\r
+\r
+\r
+class NamedRegister : public Register\r
+       {\r
+       char                    *name;\r
+       char                    enableFlag;\r
+public:\r
+       NamedRegister()                                 { doEnable(); }\r
+       ~NamedRegister()                                { delete name; }\r
+       void doEnable()                                 { enableFlag = 1; }\r
+       void doDisable()                                { enableFlag = 0; }\r
+       void toggleEnable()                             { enableFlag = !enableFlag; }\r
+       char isEnabled()                                { return enableFlag; }\r
+       char *getName()                                 { return name; }\r
+       void printCon();\r
+\r
+       friend istream& operator>> (istream&, NamedRegister&);\r
+       };\r
+\r
+#endif\r
diff --git a/16/tweak16/REGTABLE.CPP b/16/tweak16/REGTABLE.CPP
new file mode 100755 (executable)
index 0000000..d09591f
--- /dev/null
@@ -0,0 +1,123 @@
+/*\r
+       RegTable.CPP version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+       \r
+       Defines the member and friend functions of the RegisterTable class\r
+               declared in RegTable.HPP.\r
+*/\r
+\r
+#include <dos.h>\r
+//#include <conio.h>\r
+#include "RegTable.hpp"\r
+\r
+\r
+RegisterTable::RegisterTable(istream &ins)\r
+       {\r
+       // Read number of registers (first number in file)\r
+       ins >> registers;\r
+       // Allocate enough space\r
+       reg = new NamedRegister[registers];\r
+       // Read reg. descriptions\r
+       for (int i=0; i<registers; i++)\r
+               ins >> reg[i];\r
+       // Get current register configuration from VGA, and use as default\r
+       in();\r
+       }\r
+\r
+\r
+void RegisterTable::in()\r
+       {\r
+       for (int r = 0; r < registers; r++)\r
+               reg[r].in();\r
+       }\r
+\r
+void RegisterTable::out()\r
+       {\r
+       outportb(0x3d4,0x11);                           // Ensure CRT regs. 0-7 are writable!\r
+       int v = inportb(0x3d5);                         //      That is, clear bit 7 of port\r
+       v &= 0x7f;                                                      //      0x3D4, index 0x11.\r
+       outport(0x3d4,0x11 | (v << 8));\r
+\r
+//     outport(0x3c4, 0x0100);                         // reset sequencer\r
+\r
+       for (int r = 0; r < registers; r++)\r
+               if (reg[r].isEnabled())\r
+                       reg[r].out();\r
+\r
+//     outport(0x3c4, 0x0300);                         // re-reset sequencer\r
+       outportb(0x3c0, 0x20);                          // Reenable display data\r
+       }\r
+\r
+/*\r
+       This istream operator >> reads an entire table of Register values\r
+       into 'this' table.\r
+       Notes:\r
+               The stream is read until good() is no longer true.  Not good\r
+                       practice, but hey!\r
+               If the read Register's port and index pair is not found in 'this'\r
+                       table, it is ignored.\r
+               In effect, only the *values* in the table may change after >>,\r
+                       not port or index numbers.\r
+*/\r
+\r
+istream& operator>> (istream &in, RegisterTable &t)\r
+       {\r
+       int r = 0;\r
+       t.doDisable();                                                  // first disable all registers\r
+       while (in.good())\r
+               {\r
+               Register temp;\r
+               in >> temp;\r
+       \r
+               int prevr = r;\r
+       \r
+               //Search for the correct register position:\r
+               while (temp.getPort() != t.reg[r].getPort() ||\r
+                       temp.getIndex() != t.reg[r].getIndex())\r
+                       {\r
+                       if (++r >= t.registers)\r
+                               r = 0;\r
+                       if (r == prevr)                                 // Have we looped around once?\r
+                               goto skip;                                      //      Register not supported!\r
+                       }\r
+               // Correct register found, now store the value and enable it.\r
+               t.reg[r].setValue(temp.getValue());\r
+               t.reg[r].doEnable();                            // enable this single register\r
+       skip:\r
+               }\r
+       return in;\r
+       }\r
+\r
+\r
+//     This operator << sends all enabled registers in t to the out stream.\r
+\r
+ostream& operator<< (ostream &out, RegisterTable &t)\r
+       {\r
+       for (int r = 0; r < t.registers; r++)\r
+               if (t.reg[r].isEnabled())\r
+                       out << Register(t.reg[r]);\r
+       return out;\r
+       }\r
+\r
+void RegisterTable::doEnable()\r
+       {\r
+       for (int r=0; r<registers; r++)\r
+               reg[r].doEnable();\r
+       }\r
+\r
+void RegisterTable::doDisable()\r
+       {\r
+       for (int r=0; r<registers; r++)\r
+               reg[r].doDisable();\r
+       }\r
+\r
+\r
+Register *RegisterTable::getRegister(unsigned p, unsigned char i)\r
+       {\r
+       for (int r = 0; r < registers; ++r)\r
+               if (reg[r].getPort() == p && reg[r].getIndex() == i)\r
+                       return &reg[r];\r
+       return 0;\r
+       }\r
+\r
+\r
diff --git a/16/tweak16/REGTABLE.HPP b/16/tweak16/REGTABLE.HPP
new file mode 100755 (executable)
index 0000000..6fb3e37
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+       RegTable.HPP version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Declares the RegisterTable class and its members, defined in\r
+               RegTable.CPP.\r
+*/\r
+\r
+#ifndef _RegTable_HPP\r
+#define _RegTable_HPP\r
+\r
+#include "Register.HPP"\r
+\r
+\r
+class RegisterTable\r
+       {\r
+protected:\r
+       NamedRegister *reg;\r
+       int registers;\r
+public:\r
+       RegisterTable(istream &);\r
+       ~RegisterTable()                        { delete[] reg; }\r
+\r
+       int getMaxReg()                         { return registers-1; }\r
+       void doEnable();\r
+       void doDisable();\r
+       void in();\r
+       void out();\r
+\r
+    Register *getRegister(unsigned, unsigned char); \r
+\r
+       friend istream& operator>> (istream&, RegisterTable&);\r
+       friend ostream& operator<< (ostream&, RegisterTable&);\r
+       };\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/SCREEN.CPP b/16/tweak16/SCREEN.CPP
new file mode 100755 (executable)
index 0000000..c232bdd
--- /dev/null
@@ -0,0 +1,138 @@
+/*\r
+       Screen.CPP version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Defines some primitives for handling the screen, some screen\r
+               buffer pointers, and the functions that handle the single\r
+               temporary screen used in TWEAK.\r
+\r
+*/\r
+\r
+#include <conio.h>\r
+#include <mem.h>\r
+#include <dos.h>\r
+#include <iostream.h>\r
+#include <stdlib.h>\r
+#include "Screen.HPP"\r
+\r
+char palette16[16];\r
+char palette256[768];\r
+\r
+// editHeight and editWidth hold the dimensions of the editing screen.\r
+//     Not everything is formatted according to those horizontally, but\r
+//     vertically it should work fine.\r
+\r
+unsigned editMode, editHeight, editWidth, editSize;\r
+\r
+// Now for the screens used in TWEAK.\r
+\r
+// This one points to the standard VGA text screen buffer.  textscr[80]\r
+//     addresses the first character/attribute pair on the second line\r
+//     if the current mode is an 80-column one, for example.\r
+\r
+unsigned *textScr = (unsigned far *)MK_FP(0xb800,0);\r
+\r
+// graphScr points to the standard VGA graphics buffer, being 64Kb.\r
+\r
+char *graphScr = (char far *)MK_FP(0xa000,0);\r
+\r
+// setBiosMode() sets the given standard BIOS mode.\r
+\r
+void setBiosMode(int modeno)\r
+       {\r
+       _AX = modeno;\r
+       geninterrupt(0x10);\r
+       }\r
+\r
+// getBiosMode() returns the current BIOS mode.\r
+\r
+int getBiosMode(void)\r
+       {\r
+       _AH = 0x0f;\r
+       geninterrupt(0x10);\r
+       return _AL;\r
+       }\r
+\r
+// The following two functions saves and restores the temporary screen.\r
+//     The tempScr buffer is allocated and destroyed each time.\r
+\r
+void tempBuffer::save(void)\r
+       {\r
+       if (temp)\r
+               delete[] temp;\r
+       if (!(temp = new unsigned[editSize]))\r
+               {\r
+               cout << "Out of memory for swap screen!" << endl;\r
+               exit(1);\r
+               }\r
+       memcpy(temp, link, sizeof(unsigned)*editSize);\r
+       }\r
+\r
+void tempBuffer::restore(void)\r
+       {\r
+       setBiosMode(3);\r
+       textmode(editMode);\r
+       if (temp)\r
+               {\r
+               memcpy(link, temp, sizeof(unsigned)*editSize);\r
+               delete[] temp;\r
+               temp = NULL;\r
+               }\r
+       }\r
+\r
+void getPalette16()\r
+       {\r
+       for (int c=0; c<16; c++)\r
+               {\r
+               outp(0x3c0, 0x20 | c);\r
+               palette16[c] = inp(0x3c0);\r
+               }\r
+       }\r
+\r
+void setEgaPalette(char *p)\r
+       {\r
+       inp(0x3da);\r
+       for (int c=0; c<16; c++)\r
+               {\r
+               outp(0x3c0, c);\r
+               outp(0x3c0, p[c]);\r
+               }\r
+       outp(0x3c0, 0x20);\r
+       }\r
+\r
+void setPalette16()\r
+       {\r
+       char egaPal[] = {0,1,2,3,4,5,0x14,7,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f};\r
+       setEgaPalette(egaPal);\r
+       for (int c=0; c<16; c++)\r
+               {\r
+               outp(0x3c0, 0x20 | c);\r
+               outp(0x3c0, palette16[c]);\r
+               }\r
+       }\r
+\r
+void getPalette256()\r
+       {\r
+       outp(0x3c7, 0);\r
+       for (int c=0; c<768; c++)\r
+               palette256[c] = inp(0x3c9);\r
+       }\r
+\r
+void setPalette256()\r
+       {\r
+       char egaPal[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};\r
+       setEgaPalette(egaPal);\r
+       outp(0x3c8, 0);\r
+       for (int c=0; c<768; c++)\r
+               outp(0x3c9, palette256[c]);\r
+       }\r
+\r
+void preparePalettes()\r
+       {\r
+       int m=getBiosMode();\r
+       setBiosMode(0x13);\r
+       getPalette256();\r
+       setBiosMode(0x12);\r
+       getPalette16();\r
+       setBiosMode(m);\r
+       }
\ No newline at end of file
diff --git a/16/tweak16/SCREEN.HPP b/16/tweak16/SCREEN.HPP
new file mode 100755 (executable)
index 0000000..569039e
--- /dev/null
@@ -0,0 +1,50 @@
+/*\r
+       Screen.HPP version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Declares some primitives for handling the screen, some screen\r
+               buffer pointers, and the functions that handle the single\r
+               temporary screen used in TWEAK.\r
+\r
+       See Screen.CPP for definitions and documentation.\r
+*/\r
+\r
+#ifndef _Screen_HPP\r
+#define _Screen_HPP\r
+\r
+#include <mem.h>\r
+\r
+#define        REGENABLE_COLOR         0x0e\r
+#define REGDISABLE_COLOR       0x07\r
+#define CURSOR_COLOR           0x0f\r
+#define BITHEADER_COLOR                0x04\r
+#define BITPATTERN_COLOR       0x0c\r
+#define TESTHEADER_COLOR       0x09\r
+#define TESTSTRING_COLOR       0x0b\r
+#define PROMPT_COLOR           0x0a\r
+#define ERROR_COLOR                    0x8d\r
+#define HELP_COLOR                     0x4f\r
+#define INFO_COLOR                     0x0f\r
+\r
+extern unsigned editMode, editHeight, editWidth, editSize;\r
+\r
+extern unsigned *textScr;\r
+extern char *graphScr;\r
+\r
+int getBiosMode(void);\r
+void setBiosMode(int);\r
+void preparePalettes();\r
+void setPalette16();\r
+void setPalette256();\r
+\r
+class  tempBuffer\r
+       {\r
+       unsigned *link, *temp;\r
+public:\r
+       tempBuffer(unsigned *l) { link = l; temp = NULL; }\r
+    ~tempBuffer()                      { if (temp) delete[] temp; }\r
+       void save(void);\r
+       void restore(void);\r
+       };\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/TESTPAT.CPP b/16/tweak16/TESTPAT.CPP
new file mode 100755 (executable)
index 0000000..730d109
--- /dev/null
@@ -0,0 +1,440 @@
+/*\r
+       testpat.cpp version 1.6\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Defines the member functions of the TestPatterns class declared in\r
+               testpat.hpp.\r
+\r
+       1.1\r
+               Fixed a couple of bugs in the text mode test.  On some computers\r
+               it would overwrite data in the C000h segment, if RAM had been mapped\r
+               there by QEMM or something similar.\r
+\r
+       Modified June 13-14, 1993 by Peter McDermott\r
+               The 16 color test pattern has been changed.  Now it puts dots from the\r
+               upper left hand corner to down the top and left of the screen to the\r
+               edges.  There is a longer, white dot every 100 pixels.  Also, a color\r
+               bar is displayed across the page.\r
+\r
+       1.6\r
+               Added support for the mode autodetecting scheme, and for VGALIB,\r
+               my mode independant VGA graphics library, to provide more\r
+               intelligent test screens.\r
+*/\r
+\r
+#include <dos.h>\r
+#include <mem.h>\r
+#include <conio.h>\r
+#include <math.h>\r
+#include <string.h>\r
+#include <iostream.h>\r
+#include <stdio.h>\r
+\r
+#include "misc.hpp"\r
+#include "screen.hpp"\r
+#include "vgalib.hpp"\r
+#include "testpat.hpp"\r
+#include "detect.hpp"\r
+#include "screen.hpp"\r
+\r
+extern char *graphScr;\r
+extern unsigned *textScr;\r
+extern unsigned editHeight;\r
+\r
+// These are the text strings identifying each test to the user.\r
+\r
+char *TestPatterns::string[TestPatterns::tests] =\r
+       {\r
+       "Graphics autodetect",\r
+       "Text screen, 16 point",\r
+       "Text screen, 8 point",\r
+       "4 planes, 16 colors",\r
+       "1 plane, 256 colors",\r
+       "4 planes, 256 colors"\r
+       };\r
+\r
+\r
+void color16(unsigned char color)                                      // Peter\r
+{\r
+  // load set/reset register with color to be displayed\r
+  outport(0x3ce,color<<8);\r
+}\r
+\r
+// following is a point routine for 16 color mode\r
+void init16()                                                                          // Peter\r
+{\r
+  // default drawing color is white\r
+  color16(15);\r
+  // load set/reset enable for all display planes\r
+  outport(0x3ce,0x0f01);\r
+  // load map mask register for all display planes\r
+  outport(0x3c4,0x0f02);\r
+  // load function select correctly (logical OR)\r
+  outport(0x3ce,0x2003);\r
+  // set to read mode 0\r
+  outportb(0x3ce,0x05);\r
+  int ModeReg=inportb(0x3cf);\r
+  outport(0x3ce,ModeReg && 0xf7);  // make sure we're in read mode 0\r
+}\r
+\r
+\r
+void point16(unsigned int x, unsigned int y)           // Peter\r
+{\r
+  outportb(0x3d4,0x13);                                //get screen width in words\r
+  unsigned width=inportb(0x3d5)*2;     //convert to bytes\r
+  // load bitmask register with correct value\r
+  outport(0x3ce,(0x80 >> (x % 8) << 8) | 0x08);\r
+  // load the latch register with the data already in display memory\r
+  _AX=graphScr[y*width+x/8];\r
+  // calculate the position in memory of the pixel to be written\r
+  graphScr[y*width+x/8] = 0x00;\r
+}\r
+\r
+\r
+// TestPatterns::run() puts the selected test onto the screen.\r
+\r
+void TestPatterns::run(RegisterTable &regTab)\r
+       {\r
+       unsigned a,c;\r
+       unsigned long offset;\r
+\r
+       regTab.out();\r
+\r
+       outportb(0x3c4,0x02);                   //get write plane enable\r
+       unsigned plane=inportb(0x3c5);\r
+\r
+       outportb(0x3d4,0x13);                           //get screen width in words\r
+       unsigned long width=inportb(0x3d5)*2;   //convert to bytes\r
+\r
+       // Now select the correct initialization method:\r
+\r
+       switch (testNo)\r
+               {\r
+               case test4x16:\r
+               case test1x256:\r
+               case test4x256:\r
+                       // All graphics modes: clear the screen, but take care of\r
+                       //      write enabling all planes.\r
+                       outport(0x3c4,0x0f02);\r
+                       memset(graphScr, 0, 0xffff);\r
+                       graphScr[0xffff] = 0;\r
+                       outportb(0x3c4,0x02);\r
+                       outportb(0x3c5,plane);\r
+                       break;\r
+\r
+               case testText16:                                // set 8x16 font\r
+                       _AX = 0x1104;\r
+                       _BL = 0;\r
+                       geninterrupt(0x10);\r
+                       goto commonText;\r
+               case testText8:                                 // set 8x8 font\r
+                       _AX = 0x1102;\r
+                       _BL = 0;\r
+                       geninterrupt(0x10);\r
+commonText:\r
+                       // Just blank the text screen.\r
+                       memset(textScr, 0, 8000);\r
+               }\r
+\r
+       switch (testNo)\r
+               {\r
+               case autoDetect:\r
+                       ModeInfo minfo(regTab);\r
+                       GraphicsAPI *g = minfo.getGraphicsAPI();\r
+                       if (!g)\r
+                               {\r
+                               setBiosMode(3);\r
+                               cout << "This is not a graphics mode.  Either: -" << endl\r
+                                        << " - Use TAB (->|) to select one of the two "\r
+                                               "available text screens," << endl\r
+                                        << " - Base your mode on one of the BIOS graphics "\r
+                                               "modes, by pressing B and " << endl\r
+                                        << "   typing a graphics mode number, for example "\r
+                                               "0x12 or 0x13, or" << endl\r
+                                        << " - Load a graphics mode file by pressing L and "\r
+                                               "typing the name of the file." << endl << endl\r
+                                        << "Now press any key to return to the editor." << endl;\r
+                               getch();\r
+                               }\r
+                       else\r
+                               {\r
+                               g->setColor(0);\r
+                               g->wipe();\r
+                               int width = g->getVirtualWidth();\r
+                               int height = g->getVirtualHeight();\r
+                               int colors = g->getColors();\r
+                               char txt1[40];\r
+                               int i, j, maxTick = max(width, height);\r
+\r
+                               if (g->getColors() == 256)\r
+                                       setPalette256();\r
+                               else\r
+                                       setPalette16();\r
+\r
+                               for (i = 2; i <= maxTick; i += 2)\r
+                                       {\r
+                                       int coord = i-1;\r
+                                       int color, length;\r
+                                       if (i % 10 == 0)\r
+                                               if (i % 50 == 0)\r
+                                                       if (i % 100 == 0)\r
+                                                               {\r
+                                                               color = 15, length = 10;\r
+                                                               itoa(i, txt1, 10);\r
+                                                               }\r
+                                                       else\r
+                                                               color = 14, length = 7;\r
+                                               else\r
+                                                       color = 13, length = 5;\r
+                                       else\r
+                                               color = 9, length = 2;\r
+                                       if (i <= width)\r
+                                               {\r
+                                               g->setColor(color);\r
+                                               g->vLine(coord, 0, length);\r
+                                               if (length == 10)\r
+                                                       {\r
+                                                       g->setTextJustify(GraphicsAPI::RIGHT,\r
+                                                                                         GraphicsAPI::TOP);\r
+                                                       g->putText(coord, length, txt1);\r
+                                                       }\r
+                                               }\r
+                                       if (i <= height)\r
+                                               {\r
+                                               g->setColor(color);\r
+                                               g->hLine(0, coord, length);\r
+                                               if (length == 10)\r
+                                                       {\r
+                                                       g->setTextJustify(GraphicsAPI::LEFT,\r
+                                                                                         GraphicsAPI::BOTTOM);\r
+                                                       g->putText(length, coord, txt1);\r
+                                                       }\r
+                                               }\r
+                                       }\r
+\r
+                               int middle = width/2;\r
+                               int line = 30;\r
+                               g->setTextJustify(GraphicsAPI::HCENTER, GraphicsAPI::TOP);\r
+                               g->setColor(10);\r
+                               g->putText(middle, line, g->getLibID());\r
+                               g->setColor(12);\r
+                               g->putText(middle, line+=12, "Physical resolution");\r
+                               sprintf(txt1, "%d x %d", g->getWidth(), g->getHeight());\r
+                               g->setColor(15);\r
+                               g->putText(middle, line+=9, txt1);\r
+\r
+                               g->setColor(12);\r
+                               g->putText(middle, line+=12, "Virtual resolution");\r
+                               sprintf(txt1, "%d x %d", width, height);\r
+                               g->setColor(15);\r
+                               g->putText(middle, line+=9, txt1);\r
+\r
+                               g->setColor(12);\r
+                               g->putText(middle, line+=12, "Page resolution");\r
+                               sprintf(txt1, "%3.1f x %3.1f", minfo.xpages, minfo.ypages);\r
+                               g->setColor(15);\r
+                               g->putText(middle, line+=9, txt1);\r
+\r
+                               int hPalSize = width - 40;\r
+                               int vPalSize = height - (line+=22);\r
+                               int palSide = sqrt(colors);\r
+                               int hPalPix = hPalSize/palSide;\r
+                               int vPalPix = vPalSize/palSide;\r
+                               hPalSize = palSide * hPalPix + 1;\r
+                               vPalSize = palSide * vPalPix + 1;\r
+                               for (i = 0; i < colors; ++i)\r
+                                       {\r
+                                       g->setColor(i);\r
+                                       int x = width-hPalSize+(i/palSide)*hPalPix;\r
+                                       int y = height-vPalSize+(i%palSide)*vPalPix;\r
+                                       g->bar(x, y, x+hPalPix, y+vPalPix);\r
+                                       }\r
+\r
+                               int basex=0, basey=0, bdirx=0, bdiry=0, quit=0;\r
+                               while (!quit)\r
+                                       {\r
+                                       if (kbhit())\r
+                                               {\r
+                                               int key = getch();\r
+                                               if (!key && kbhit())\r
+                                                       key = getch() << 8;\r
+\r
+                                               switch (key)\r
+                                                       {\r
+                                                       case 0x4700:\r
+                                                               basex = basey = bdirx = bdiry = 0;\r
+                                                               break;\r
+                                                       case 0x4800:                    //UP\r
+                                                               --bdiry;\r
+                                                               break;\r
+                                                       case 0x4b00:\r
+                                                               --bdirx;\r
+                                                               break;\r
+                                                       case 0x4c00:\r
+                                                               bdirx = bdiry = 0;\r
+                                                               break;\r
+                                                       case 0x4d00:\r
+                                                               ++bdirx;\r
+                                                               break;\r
+                                                       case 0x5000:                    //DOWN\r
+                                                               ++bdiry;\r
+                                                               break;\r
+                                                       case 27:\r
+                                                       case 13:\r
+                                                               quit = 1;\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                       basex += bdirx;\r
+                                       basey += bdiry;\r
+                                       if (basex > width-g->getWidth())\r
+                                               basex = width-g->getWidth(), bdirx = 0;\r
+                                       if (basey > height-g->getHeight())\r
+                                               basey = height-g->getHeight(), bdiry = 0;\r
+                                       if (basex < 0)\r
+                                               basex = bdirx = 0;\r
+                                       if (basey < 0)\r
+                                               basey = bdiry = 0;\r
+\r
+                                       g->setBase(basex, basey);\r
+//                                     bdirx = bdiry = 0;                      // for debugging\r
+                                       }\r
+                               delete g;\r
+                               }\r
+                       break;\r
+\r
+               case testText16:\r
+               case testText8:\r
+\r
+                       // Fill top line with the sequence "0123456789" lt grey/black:\r
+                       a = 0;\r
+                       for (c=0; c<width; c++)\r
+                               textScr[a++] = ('0'+(c+1)%10) | 0x0700;\r
+\r
+                       // Then fill 4 lines with the ASCII set in white on blue:\r
+                       for (c=0; c<5*width; c++)\r
+                               textScr[a++] = c | 0x1f00;\r
+\r
+                       // Now fill the rest with the sequence "ABCDEFGHIJ" in all color\r
+                       //      combinations (except blinking!):\r
+                       c = 0;\r
+                       while (a < 0x4000)      // fixed 0x4800 bug May 7. 1993\r
+                               textScr[a++] = ('A'+c%('K'-'A')) | ((c&0x7f)<<8), c++;\r
+                       getch();\r
+                       break;\r
+\r
+\r
+               case test1x256:\r
+                       width *= 4;\r
+\r
+                       // Fill the first 32 lines with 1 pixel wide colored vertical\r
+                       //      lines.\r
+                       for (c=0; c<width; c++)\r
+                               for (a=0; a<32; a++)\r
+                                       graphScr[a*width+c]=c;\r
+\r
+                       // Fill the rest with 1 pixel high horizontal lines.\r
+                       c=0;\r
+                       offset=32*width;\r
+                       do      {\r
+                               memset(graphScr+offset, c++, width);\r
+                                                       //horizontal lines, 1 color each\r
+                               offset+=width;\r
+                               }\r
+                       while (offset <= 0x10000-width);\r
+                       getch();\r
+                       break;\r
+\r
+               case test4x256:\r
+\r
+                       // This test is affected by the Write Plane Enable register.\r
+                       // First put up 32 horizontal lines in the 32 first colors.\r
+                       for (c=0; c<(width<<5); c++)\r
+                               graphScr[c]=c/width;\r
+\r
+                       // Then fill the rest with vertical lines.  This is too slow!\r
+                       offset=c;\r
+                       c=0;\r
+                       a=1;\r
+                       do      {\r
+                               outportb(0x3c5,a);      //Set write plane enable\r
+                               graphScr[offset]=c;\r
+\r
+                               if ((a<<=1)>8)\r
+                                       {\r
+                                       a=1;\r
+                                       ++offset;\r
+                                       }\r
+                               if ((++c)==width<<2)\r
+                                       c=0;\r
+                               }\r
+                       while (offset <= 0xffff);\r
+                       getch();\r
+                       break;\r
+               case test4x16:\r
+\r
+// This is Peter's 16-color test.  The original test is commented out below.\r
+\r
+                       init16();\r
+                       color16(15);\r
+                       for (a=0; a<(width*8); a+=10) {\r
+                         if (! (a % 100)) {\r
+                               color16(15);\r
+                               point16(a,1);\r
+                               point16(a,2);\r
+                               point16(a,3); }\r
+                         else\r
+                               color16(2);\r
+\r
+                         point16(a,0); }\r
+\r
+                       for (a=0; a<600; a+=10) {\r
+                         if (! (a % 100)) {\r
+                               color16(15);\r
+                               point16(1,a);\r
+                               point16(2,a);\r
+                               point16(3,a); }\r
+                         else\r
+                               color16(2);\r
+\r
+                         point16(0,a); }\r
+\r
+                       // draw 16 color bars across the screen\r
+\r
+                       for (int x = 0; x < (width-2)*8; x++) {\r
+                         color16(x / ((width-2)*8/16));\r
+                         for (int y=10; y < 190; y++) {\r
+                               point16(x+8,y); }}\r
+\r
+/*\r
+                       // Original 16-color test\r
+                       // Fill first 32 lines with thick vertical stripes alternating\r
+                       //      between black and the color selected by Write Plane Enable.\r
+                       for (c=0; c<(width<<5); c++)\r
+                               graphScr[c]=0x0f;\r
+\r
+                       // Fill the rest with various bit patterns, in all colors.\r
+                       for (a=0; a<256; a++)\r
+                               {\r
+                               outportb(0x3c5,a);\r
+                               memset(graphScr+(a+40)*width, a, width);\r
+                               }\r
+*/\r
+                       getch();\r
+                       break;\r
+               }\r
+       }\r
+\r
+\r
+// tellTest() puts the name of the current test at the correct position on\r
+//     the edit screen.\r
+\r
+void TestPatterns::tellTest()\r
+       {\r
+       gotoxy(42,editHeight);\r
+       textattr(TESTHEADER_COLOR);\r
+       cprintf("Current test: ");\r
+       textattr(TESTSTRING_COLOR);\r
+       cprintf(string[testNo]);\r
+       clreol();\r
+       }\r
diff --git a/16/tweak16/TESTPAT.HPP b/16/tweak16/TESTPAT.HPP
new file mode 100755 (executable)
index 0000000..7171bf9
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+       TestPat.hpp version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Declares the TestPatterns class which is further defined in\r
+               TestPat.cpp.\r
+*/\r
+\r
+#ifndef _TestPat_HPP\r
+#define _TestPat_HPP\r
+\r
+#include <stdlib.h>\r
+#include "RegTable.HPP"\r
+\r
+class TestPatterns\r
+       {\r
+public:\r
+       // testType declares the possible types of screen patterns to test your\r
+       //      wonderful modes with.  Note that 'tests' is there just to provide a\r
+       //      constant equaling the number of tests.\r
+       enum testType\r
+               { autoDetect, testText16, testText8, test4x16, test1x256,\r
+                 test4x256, tests };\r
+private:\r
+       static char *string[tests];\r
+       testType testNo;\r
+public:\r
+       TestPatterns(testType t=autoDetect) { testNo = t; }\r
+       testType operator++()   { if (++testNo==tests) testNo=testType(0);\r
+                                                         return testNo; }\r
+       testType operator--()   { if (--testNo<testType(0)) testNo=tests-1;\r
+                                                         return testNo; }\r
+       testType getTest()              { return testNo; }\r
+       void run(RegisterTable &);\r
+       void tellTest();\r
+       };\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/TWEAK.CPP b/16/tweak16/TWEAK.CPP
new file mode 100755 (executable)
index 0000000..202e0d7
--- /dev/null
@@ -0,0 +1,389 @@
+/*\r
+       TWEAK 1.6á - Mold your own VGA modes\r
+\r
+       by Robert Schmidt of Ztiff Zox Softwear, (C) Copyright 1992-93\r
+\r
+       For documentation, see TWEAK.DOC.\r
+\r
+\r
+       History:\r
+\r
+       0.9\r
+               First version available to the public.\r
+               Aw, what the heck, I'll admit this is the first version ever...\r
+               I know the usage of C++ classes may look a little stupid,\r
+                       but it works.\r
+               Another stupid, *stupid* thing is the mixed use of conio and\r
+                       iostream, but hey, it works too!\r
+               This version is not commented whatsoever.\r
+               Pretty lame interface - no help.\r
+               Test screens assume text start at segment 0xb800, and graphics\r
+               at 0xa000.\r
+       1.0\r
+               Changed from small to large memory model.  Not that I need it, it\r
+                       just makes the code more readable.\r
+               Commented heavily, and beautified the code.\r
+               Nearly rewrote the program completely, by using another OO strategy.\r
+               Changed use of abort() to exit(1).\r
+               Text test pattern now fills entire text buffer from 0xb800:0x0000\r
+                       to 0xb800:0xffff.\r
+               TWEAK now captures whatever screen mode is active at startup,\r
+                       instead of defaulting to BIOS mode 3 (80x25).\r
+               The screen is reset to the startup BIOS mode at exit, too.\r
+               Added 'S' and 'L' as synonyms for F9 and F10.\r
+               Added Shift+TAB as a companion to TAB.\r
+               Editing screen now uses 80x50 instead of 80x25.\r
+               Added one text test screen which uses the 8x8 font.\r
+               Added online help, not context sensitive as promised.  Maybe later.\r
+               Edititing screen is cleared when a test is initiated, so that it\r
+                       is easier to see that something happened if the wrong test\r
+                       screen is selected.\r
+               Removed startup banner.\r
+               Removed use of cout and cin for screen/keyboard I/O, in favour of\r
+                       the colors and windows provided by conio.h.\r
+               Instead, I use fstreams for *file* I/O... much more convenient than\r
+                       FILEs.\r
+               Made the interface more cheerful by using lots of colors.\r
+       1.1\r
+               Nuked a serious bug in the text test pattern.  At the end, it\r
+                       wrote characters far outside of the video buffer, overwriting\r
+                       0x800 bytes at the start of the 0xC000 segment.\r
+                       Most PCs have ROM in this area, so I didn't notice the\r
+                       bug until I ran TWEAK on some 486s with a SCSI harddisk.\r
+                       I think those map some RAM to that segment, in any case\r
+                       TWEAK crashed whenever the text pattern was used on those\r
+                       machines.\r
+               I Decided not to read back the registers when returning from the\r
+                       test screen.  It was not very usable, and imposed some\r
+                       problems when using different test screens.\r
+               Never released.\r
+       1.5\r
+               Added the AutoDetect testing pattern, which makes use of my new,\r
+                       mode independant VGA graphics library to make the testing\r
+                       much more interesting and informative.  Might add simple\r
+                       menus to this later.\r
+               Fixed a bug in the VGA library for Chained 256-color modes, which\r
+                       caused scrolling to go four times as far as intended.\r
+               Made the help window larger, more readable.\r
+               Added question of confirmation to quit when ESC is pressed.\r
+               Added lots more sample modes (from xlib06).\r
+       1.6\r
+               Added the mode heuristics seen in the autodetect test screen to\r
+                       the editor screen.  This gives the user instant feedback on\r
+                       his work.\r
+               Fixed the RegTable::out() method to correctly reset the sequencer.\r
+                       Result: no flickering when testing modes.\r
+               The autodetect screen sets the VGA palettes to the BIOS default.\r
+*/\r
+\r
+#ifndef __LARGE__\r
+# ifndef __COMPACT__\r
+#  ifndef __HUGE__\r
+#   error A large data model is required!\r
+#  endif\r
+# endif\r
+#endif\r
+\r
+\r
+#include <stdio.h>\r
+#include <dos.h>\r
+#include <stdlib.h>\r
+#include <conio.h>\r
+#include <fstream.h>\r
+#include <ctype.h>\r
+#include <string.h>\r
+\r
+#include "Screen.HPP"\r
+#include "RegEdit.HPP"\r
+#include "TestPat.HPP"\r
+#include "detect.hpp"\r
+\r
+\r
+void helpWindow()\r
+       {\r
+       tempBuffer swap(textScr);\r
+       swap.save();\r
+       window(5,5,editWidth-5,33);\r
+       textattr(HELP_COLOR);\r
+       clrscr();\r
+       window(6,6,editWidth-6,32);\r
+       gotoxy(1,1);\r
+       cprintf("TWEAK 1.6á by Robert Schmidt - Ztiff Zox Softwear\n\r"\r
+                       "Quick reference help screen\n\r"\r
+                       "\n\r"\r
+                       "Up/Down/Home/End: select register\n\r"\r
+                       "       Backspace: enable/disable register\n\r"\r
+                       "    2 hex digits: set register value\n\r"\r
+                       "             -/+: decrease/increase register value\n\r"\r
+                       "           F1-F8: toggle register bits 7-0\n\r"\r
+                       "       F9 or 'S': save register set to file\n\r"\r
+                       "      F10 or 'L': load set from file\n\r"\r
+                       "             'M': select BIOS mode to work from\n\r"\r
+                       "   TAB/Shift-TAB: select test screen\n\r"\r
+                       "           ENTER: show test screen\n\r"\r
+                       "             'H': show this help window\n\r"\r
+                       "             ESC: Quit TWEAK immediately\n\r"\r
+                       "\n\r"\r
+                       "The mode heuristics shown are NOT perfect.  It is practically\n\r"\r
+                       "impossible to foresee what your screen will show.  Use the\n\r"\r
+                       "values given as guidance, or hints.\n\r"\r
+                       "\n\r"\r
+                       "When viewing the autodetect test screen, you may use the\n\r"\r
+                       "arrows to scroll over the virtual screen.  Press ESC or ENTER\n\r"\r
+                       "to leave.\n\r"\r
+                       "\n\r"\r
+                       "For more information, see the TWEAK.DOC file.\n\r"\r
+                       "Now press the 'any' key to return to the editor.\n\r"\r
+                       );\r
+       getch();\r
+       window(1,1,editWidth,editHeight);\r
+       swap.restore();\r
+       }\r
+\r
+\r
+void prompt(char *p = 0, int attr = PROMPT_COLOR)\r
+       {\r
+       textattr(7);\r
+       gotoxy(42,editHeight-1);\r
+       clreol();\r
+       textattr(attr);\r
+       if (p)\r
+               cprintf(p);\r
+       }\r
+\r
+\r
+int main(int argc, char **argv)\r
+       {\r
+       // Initialize the register table with descriptions and all.\r
+       RegisterEditor regEditor(ifstream("TWEAK.DAT"));\r
+       TestPatterns test;\r
+\r
+       int parentBiosMode = getBiosMode();\r
+       preparePalettes();\r
+       // Set our default editing screen, and get its dimensions\r
+       setBiosMode(3);\r
+       textmode(C4350);\r
+       clrscr();\r
+       text_info *ti = new text_info;\r
+       gettextinfo(ti);\r
+       editMode = ti->currmode;\r
+       editHeight = ti->screenheight;\r
+       editWidth = ti->screenwidth;\r
+       editSize = editHeight * editWidth;\r
+       delete ti;\r
+\r
+       tempBuffer swap(textScr);       // Establish the temporary screen buffer\r
+\r
+       unsigned char quit = 0;                 // Non-zero when a quit command is\r
+                                                                       //      initiated.\r
+       int key;                                                // The last key pressed.\r
+\r
+       // Build the editing screen:\r
+\r
+       regEditor.printAllCon();\r
+       gotoxy(42, editHeight-20);\r
+       textattr(HELP_COLOR);\r
+       cprintf("(Press H if you need help)");\r
+\r
+       ModeInfo minfo(regEditor);\r
+\r
+       // Start the main keyboard polling loop:\r
+\r
+       while (!quit)\r
+               {\r
+               test.tellTest();\r
+               regEditor.showBitMask();\r
+               minfo.show();\r
+               regEditor.updateSelect();\r
+\r
+               int key = getch();\r
+               if (!key)\r
+                       key = getch() << 8;\r
+               else\r
+                       key = tolower(key);\r
+\r
+keyentry:\r
+               switch (key)\r
+                       {\r
+                       case 0x4700:                    //HOME\r
+                               regEditor.setSelect(0);\r
+                               break;\r
+                       case 0x4800:                    //UP\r
+                               --regEditor;\r
+                               break;\r
+                       case 0x4F00:                    //END\r
+                               regEditor.setSelect(regEditor.getMaxReg());\r
+                               break;\r
+                       case 0x5000:                    //DOWN\r
+                               ++regEditor;\r
+                               break;\r
+\r
+                       // Function keys - toggle single bit in selected reg.\r
+                       case 0x3B00:                    //F1\r
+                       case 0x3C00:\r
+                       case 0x3D00:\r
+                       case 0x3E00:\r
+                       case 0x3F00:\r
+                       case 0x4000:\r
+                       case 0x4100:\r
+                       case 0x4200:                    //F8\r
+                               **regEditor ^= (1<<7-((key>>8)-0x3B));\r
+                               break;\r
+\r
+                       case 0x4300:                    //F9\r
+                       case 0x4400:                    //F10\r
+                               // Handle file operations (save/load):\r
+                               char fname[63];\r
+                               int save=(key==0x4300);\r
+\r
+                               // Prompt for filename.\r
+                               if (save)\r
+                                       prompt("Save file name: ");\r
+                               else\r
+                                       prompt("Load file name: ");\r
+                               gets(fname);\r
+                               if (strlen(fname) == 0)\r
+                                       {\r
+                                       prompt("File operation canceled.");\r
+                                       break;\r
+                                       }\r
+\r
+                               prompt(0, ERROR_COLOR); // prepare for error\r
+                               if (save)\r
+                                       {\r
+                                       ofstream out(fname, ios::trunc|ios::binary|ios::out);\r
+                                       if (out.bad())\r
+                                               cprintf("Error creating '%s'!", fname);\r
+                                       else\r
+                                               {\r
+                                               out << regEditor;\r
+                                               if (out.bad())\r
+                                                       cprintf("Error writing '%s'!", fname);\r
+                                               else\r
+                                                       {\r
+                                                       prompt(fname);\r
+                                                       cprintf(" written.");\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               else\r
+                                       {\r
+                                       ifstream in(fname, ios::binary|ios::in|ios::nocreate);\r
+                                       if (in.bad())\r
+                                               cprintf("Error opening '%s'!", fname);\r
+                                       else\r
+                                               {\r
+                                               in >> regEditor;\r
+                                               if (in.bad())\r
+                                                       cprintf("Error reading '%s'!", fname);\r
+                                               else\r
+                                                       {\r
+                                                       prompt(fname);\r
+                                                       cprintf(" read.");\r
+                                                       }\r
+                                               }\r
+                                       }\r
+\r
+                               // Update screen to reflect changes (if any).\r
+                               regEditor.printAllCon();\r
+                               test.tellTest();\r
+                               break;\r
+\r
+                       case '0': case '1': case '2': case '3': case '4': case '5':\r
+                       case '6': case '7': case '8': case '9': case 'a': case 'b':\r
+                       case 'c': case 'd': case 'e': case 'f':\r
+                               // Input hexadecimal number:\r
+                               gotoxy(40*(regEditor.getSelect()/editHeight)+38,\r
+                                       regEditor.getSelect()%editHeight+1);\r
+                               ungetch(key);\r
+                               cprintf("%c \b", key);\r
+                               unsigned char newValue;\r
+                               cscanf("%2hx", &newValue);\r
+                               (*regEditor).setValue(newValue);\r
+                               break;\r
+\r
+                       case 'h':\r
+                               // Help:\r
+                               helpWindow();\r
+                               break;\r
+\r
+                       // Alternate file I/O keys:\r
+                       case 's':\r
+                               key = 0x4300;\r
+                               goto keyentry;\r
+\r
+                       case 'l':\r
+                               key = 0x4400;\r
+                               goto keyentry;\r
+\r
+                       case 'm':\r
+\r
+                               // Select a BIOS mode to work from.\r
+                               int baseMode;\r
+                               prompt("Base BIOS screen mode: 0x");\r
+                               cscanf("%2hx",&baseMode);\r
+                               swap.save();                            //save edit buffer\r
+\r
+                               // Set the selected mode, and grab register values.\r
+                               setBiosMode(baseMode);\r
+                               regEditor.in();\r
+                               swap.restore();                         //reset edit mode and buffer\r
+                               regEditor.printAllCon();\r
+                               prompt();\r
+                               cprintf("Got registers from mode 0x%02x", baseMode);\r
+                               break;\r
+\r
+                       case 8:\r
+                               (*regEditor).toggleEnable();\r
+                               ++regEditor;\r
+                               break;\r
+\r
+                       case '-':\r
+                               // Decrease register value:\r
+                               // Note that * (dereferencing) is overloaded for both\r
+                               //      RegisterTable and Register!  Pretty fancy, but hard\r
+                               //      to read!\r
+                               -- **regEditor;\r
+                               break;\r
+\r
+                       case '+':\r
+                               // Increase register value\r
+                               ++ **regEditor;\r
+                               break;\r
+\r
+                       case 13:        //ENTER\r
+                               // Test the screen mode.\r
+                               swap.save();\r
+                               // Clear the text screen, so the user can see something is\r
+                               //      happening even if he chose the wrong test screen.\r
+                               clrscr();\r
+                               test.run(regEditor);\r
+                               swap.restore();\r
+                               break;\r
+\r
+                       case 9:         //TAB\r
+                               // Select next test pattern:\r
+                               ++test;\r
+                               break;\r
+\r
+                       case 0x0F00: // shift-TAB\r
+                               // Select previous test pattern:\r
+                               --test;\r
+                               break;\r
+\r
+                       case 27:        //ESC\r
+                               // Quit TWEAK:\r
+                               prompt("Really quit [n]?");\r
+                               if (toupper(getch()) == 'Y')\r
+                                       quit = 1;\r
+                               prompt();\r
+                               break;\r
+                       }\r
+               minfo.detectFrom(regEditor);\r
+               }\r
+\r
+       // Reset BIOS mode detected at startup.\r
+       setBiosMode(parentBiosMode);\r
+\r
+       return 0;\r
+       }
\ No newline at end of file
diff --git a/16/tweak16/TWEAK.DAT b/16/tweak16/TWEAK.DAT
new file mode 100755 (executable)
index 0000000..e13336e
--- /dev/null
@@ -0,0 +1,30 @@
+29\r
+3c2 00 Misc. output\r
+3d4 00 Horiz. total\r
+3d4 01 Horiz. disp. enable end\r
+3d4 02 Horiz. blank start\r
+3d4 03 Horiz. blank end\r
+3d4 04 Horiz. retrace start\r
+3d4 05 Horiz. retrace end\r
+3d4 06 Vertical total\r
+3d4 07 Overflow register\r
+3d4 08 Preset row scan\r
+3d4 09 Max scan line/char ht.\r
+3d4 10 Vertical retrace start\r
+3d4 11 Vertical retrace end\r
+3d4 12 Vert. disp. enable end\r
+3d4 13 Offset/Logical width\r
+3d4 14 Underline location\r
+3d4 15 Vertical blank start\r
+3d4 16 Vertical blank end\r
+3d4 17 Mode control\r
+3c4 01 Clock mode register\r
+3c4 03 Character gen. select\r
+3c4 04 Memory mode register\r
+3ce 05 Mode register\r
+3ce 06 Miscellaneous register\r
+3c0 10 Mode control\r
+3c0 11 Screen border colour\r
+3c0 12 Color plane enable\r
+3c0 13 Horizontal panning\r
+3c0 14 Color select\r
diff --git a/16/tweak16/TWEAK.DOC b/16/tweak16/TWEAK.DOC
new file mode 100755 (executable)
index 0000000..ade4bd5
--- /dev/null
@@ -0,0 +1,1054 @@
+\r
+\r
+\r
+\r
+\r
+\r
+                TWEAK 1.6á - Mold your own VGA modes\r
+\r
+         by Robert Schmidt of Ztiff Zox Softwear, 1992-93\r
+\r
+\r
+          This program and the accompanying source files\r
+              are hereby donated to the public domain.\r
+                  (for whatever that's worth...)\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+(Sorry for not page-formatting this doc.  The headers can be found by\r
+doing a text search with your favourite editor.)\r
+\r
+\r
+Contents:\r
+\r
+WHAT IS TWEAK, ANYWAY?\r
+SUGGESTION BOX\r
+DISCLAIMER\r
+A QUICK PRIMER\r
+WHAT HAS TWEAK GOT TO DO WITH THIS?\r
+A COUPLE OF RULES\r
+A TUTORIAL\r
+EDITOR REFERENCE\r
+FREQUENTLY ASKED QUESTIONS\r
+THE TWEAK FILES\r
+USING TWEAK MODES ON YOUR OWN\r
+THE INCLUDED FILES\r
+THE 'MISC' DIRECTORY\r
+CREDITS\r
+BIBLIOGRAPHY\r
+HOW TO REACH ME\r
+\r
+\r
+\r
+\r
+                        WHAT IS TWEAK, ANYWAY?\r
+\r
+\r
+TWEAK is an utility to ease the work of twiddling with the registers on\r
+a standard VGA compatible video card to produce and explore new, previously\r
+undocumented screen modes with weird resolutions.  You will want to\r
+purchase a technical VGA reference to get the full potential out of\r
+TWEAK, but I included some files to get you started (see the section\r
+on the 'MISC' directory).\r
+\r
+TWEAK.EXE is the main executable.  This version is not compatible with \r
+any versions prior to 1.0, so if you want to use files created by \r
+version 0.9x, convert them with 09TO10.EXE.  \r
+\r
+Stop press!  In the subdirectory XINTRO is an article which serves as\r
+an introduction to programming in Mode X (320x240 with 256 colors).\r
+Make sure you read this if you're new to tweaking and Mode X!\r
+\r
+MODES.DOC describes some of the more exciting 256x256, 400x300 \r
+and 400x600 256-color modes!\r
+\r
+\r
+\r
+\r
+                        SUGGESTION BOX\r
+\r
+\r
+All suggestions to enhance or modify TWEAK are welcome, especially bug\r
+reports/fixes.  So are donations, for that matter.  See e-mail and\r
+snail-mail addresses at the end of this file.\r
+\r
+Please send me any changes you make to enhance TWEAK or to make it\r
+compatible with other compilers or video cards, and I will start\r
+including conditional sections for each supported compiler.\r
+Do *not* re-release the changed source without my permission.\r
+Well, how can I stop ya...?\r
+\r
+Any suggestions and contributions will be credited in subsequent\r
+versions, although I can't guarantee that your ideas will actually be\r
+used.\r
+\r
+\r
+\r
+\r
+\r
+                          DISCLAIMER\r
+\r
+\r
+I don't think this is neccessary in PD stuff, but everybody else does\r
+it:\r
+\r
+The author author of this archive has used his best efforts in \r
+preparing it.  However, the author makes no warranty of any kind, \r
+expressed or implied, with regard to the programs, data or \r
+documentation included with the archive.  The author shall not be \r
+liable in any event for incidental or consequential damages in \r
+connection with, or arising out of, the furnishing, performance, \r
+quality, or use of the programs, data or documentation included in this \r
+archive.\r
+\r
+Phew.\r
+\r
+Some time ago, putting illegal or unsupported values or combinations\r
+of such into the video card registers might prove hazardous to both\r
+your monitor and your health.  I have *never* claimed that bad things\r
+can't happen if you use TWEAK, although I'm pretty sure it never will.\r
+I've never heard of any damage arising from trying out TWEAK, or from\r
+general VGA tweaking in any case.  I did receive a mail from a person\r
+whose monitor failed producing the correct colors, after using mode\r
+X.\r
+\r
+\r
+\r
+\r
+\r
+\r
+                           A QUICK PRIMER\r
+\r
+\r
+You never heard about neither documented nor undocumented modes, you \r
+say?  Well, to begin with:  Your VGA card has a number of registers \r
+that control the way the card works.  That is, how it is going to \r
+translate the data that programs put into the video memory, to the \r
+signals that produce text and/or graphics on your monitor.\r
+\r
+The standard interface to a video card on all IBM compatible PCs is the \r
+BIOS, which consists of several device independant routines for setting \r
+screen modes, moving the cursor, writing text, scrolling blocks of text \r
+etc.  The BIOS also takes care of setting the appropriate registers at \r
+appropriate times, for example when changing screen modes.  That way, \r
+programmers have a consistent interface to the VGA, and usually won't \r
+need to tamper with the registers directly.\r
+\r
+A screen mode specifies the resolution of the image you see on the \r
+screen, i.e. the number of pixels (dots) horizontally and vertically, \r
+the number of colors, and wether the screen should be capable of \r
+showing just text, or if graphics are allowed.  These things are \r
+controlled by the VGA registers, and the BIOS contains a number of \r
+predefined tables of register values for the standard VGA modes we've \r
+all come to love and honour.  Mode number 3, for example, is the 80 \r
+characters times 25 lines (80x25) text screen that most people use \r
+daily.  Mode number 19 (or 13h in hexadecimal) is the 256-color 320x200 \r
+mode used in most popular games supporting the VGA.\r
+\r
+\r
+\r
+\r
+\r
+\r
+                WHAT HAS TWEAK GOT TO DO WITH THIS?\r
+\r
+\r
+Well, some people, me included, are of the 'power-hungry' breed.  We want\r
+to exploit the full potential of everything we get between our hands.\r
+We think that the one 320x200 256-color mode supported by all standard VGA\r
+BIOS'es is for wimps.  Some guy came up with the idea of modifying the\r
+register configuration, to achieve greater resolution and a different\r
+video memory layout.\r
+\r
+TWEAK grants you direct access to all the most significant registers\r
+that control such things as resolution and colors.  You may have thought\r
+that your VGA was limited to 320x200 when it was displaying 256 colors?\r
+Well, all VGAs are able to support no less than 400x600 in 256 colors.\r
+(The problem is with the monitors, which might not be sophisticated\r
+enough to support the relatively much higher clock frequency needed to\r
+output that many pixels.  My monitor flickers and rolls occasionaly.)\r
+\r
+Most newer VGA cards' BIOSes add several enhanced modes not supported\r
+by the standard VGA defined by IBM, for example text modes with 132\r
+characters on each line, or graphics resolutions of 800x600, 1280x1024\r
+and more.  Such cards are usually referred to as Super VGAs.  To make it\r
+possible to produce such resolutions, video card developers has had to\r
+add new registers to the set of registers defined by the VGA.  TWEAK is\r
+generally not able to support such extended registers, meaning that you\r
+will not be able to tweak a Super VGA any more than is possible on a\r
+standard VGA.  Extensions that are provided by utilizing undefined bits\r
+in the standard VGA registers are supported however.  The included\r
+Chips & Technologies specific 132x*.twk files are examples of such.\r
+\r
+The main reason for not including Super VGA (SVGA) support is that\r
+there are so many different SVGA standards.  Nearly every developer has\r
+their own standard.  Also, I can see no real reason for wanting to tweak\r
+any SVGAs, as the resolution dimensions they offer usually are far\r
+superior to the VGA's resolutions.  With tweaked VGA modes there's\r
+a much higher propability that they will work on most VGAs and SVGA,\r
+than tweaked SVGA modes.\r
+\r
+If this is the first you have read about VGA registers and the BIOS,\r
+TWEAK.EXE and this documentation alone is not enough to get you going.\r
+You will need, and probably want, a somewhat technical reference to the\r
+VGA, which explains all standard VGA registers and the meaning of every\r
+contained bit.  Although TWEAK doesn't support it, you'll probably want\r
+a reference which also contains some discussion on Super VGAs, just for\r
+your convenience when you want to program serious applications etc.  If\r
+you're of the adventurous breed, check out the VGA.TXT and VGABIOS.TXT\r
+files included in the .\MISC directory.\r
+\r
+You see, tweaking the VGA is not as simple as putting the horizontal\r
+resolution in one register, the vertical in another and the number of\r
+colours in yet another.  Several registers has to be set to cooperating\r
+values that work together to acheive what you want.  Single bits has to\r
+be toggled into the correct states, even before you can see anything on\r
+screen.  TWEAK simplifies this process by letting you do this\r
+interactively, and by letting you test your register set at the touch\r
+of one key (ENTER, actually).  The pre-TWEAK process was to make a small\r
+program that set up the registers in the way the programmer thought\r
+would work.  If it didn't he had to edit the program source file,\r
+recompile, and re-run.  Not seldom, the PC crashed because of some\r
+*really bad* register values, and a full reset was required.\r
+\r
+TWEAK let you save and load register sets to and from files, and let\r
+you select any video mode supported by your BIOS to work out from.\r
+It supports text modes and graphics, 16-color and 256-color.  Monochrome\r
+modes and CGA modes (4- and 2-color), however, are not supported,\r
+because they use another set of I/O ports, and because few people are\r
+really interested in them.\r
+\r
+As of version 1.6, TWEAK further simplifies the VGA tweaking process by \r
+providing instant feedback on the register values, in the form of a \r
+live mode heuristic, i.e. a detection scheme tried to figure out what \r
+type of mode your making, the number of colors, its physical and \r
+virtual resolution, the number of pages (both horizontally and \r
+vertically).\r
+\r
+\r
+\r
+\r
+\r
+\r
+                        A COUPLE OF RULES\r
+\r
+\r
+I'll be the first to admit:  TWEAK isn't much of an editor.  The screen\r
+is boring, there is just one simple help window, no undo command, no\r
+file pick lists etc.  In short, TWEAK is not meant for people not\r
+knowing what they are doing.  I strongly beleive that nothing can be\r
+damaged from the use of TWEAK, but for starters, I'll recommend the\r
+following precautions:\r
+\r
+  *  When loading/saving, take care to check that you selected the\r
+     function (load or save) that you want, before typing a filename\r
+     and pressing Enter.  Also verify that the filename you type when\r
+     saving is the filename that you want, because TWEAK overwrites\r
+     any existing files with the same name without asking for permission.\r
+\r
+  *  If, when you press the Enter screen to test the screen mode,\r
+     nothing appears after 5-10 seconds, press Enter again.  If you're\r
+     not immediately returned to the editing screen, reboot your\r
+     computer by pressing the reset button.  Keep in mind that some of\r
+     the test patterns, especially the 256-color 4-planar one, can be\r
+     slow to put into the video memory buffer, so be a *little*\r
+     patient & tolerant.\r
+\r
+That last rule is present to prevent that the monitor is exposed to crazy\r
+sync timings for too long a time.  And I repeat, there usually never is\r
+any reason to panic, even if your monitor makes strange sounds\r
+('tweeeeee' for example, or 'flick-flick-flick').  Press ENTER, wait for\r
+a couple of seconds more, then reset your computer if the edit screen\r
+doesn't reappear, and try a different approach.\r
+\r
+\r
+\r
+\r
+\r
+\r
+                           A TUTORIAL\r
+\r
+\r
+To start TWEAK, change to the directory where you have put the files,\r
+and type TWEAK at the DOS prompt.  Well, now you're in the editor, and\r
+you can see the following things (you might want to print this tutorial\r
+so you have it on paper):\r
+\r
+  *  One (possibly two) column(s) of VGA registers on the form:\r
+     ppp (ii)         Register Name : vv\r
+     where\r
+       -  ppp is the port number\r
+       -  ii is the index into that port, if applicable\r
+       -  vv is the selected value for this register\r
+     All numbers are hexadecimal.  The current register is marked by one\r
+     arrowhead on each side of the line.  When you first start TWEAK,\r
+     the current register is the top left.\r
+\r
+  *  A bit pattern display showing the bit pattern of the 8-bit value\r
+     contained in the currently selected register.\r
+\r
+  *  The bottom line tells you which test pattern is currently active.\r
+\r
+  *  You will also see the mode heuristic which usually makes a good\r
+     guess at what mode you have at the moment.\r
+\r
+When executed, TWEAK starts up by reading the registers of your current \r
+BIOS mode, so that you have something to work with.  This is usually a \r
+text mode, 80x25 for example, so you'll probably want to set a graphics \r
+mode for more interesting results.\r
+\r
+Now try the following simple tutorial:\r
+\r
+  1. Press H, and a red window should appear, describing all keys\r
+     available for use in TWEAK.  These will also be described below.\r
+\r
+  2. Press M, then type the number 03.  Notice that you don't have to\r
+     press ENTER.  You have now selected BIOS mode 3 as the basis for\r
+     you explorations.  Notice also the information provided by the \r
+     mode heuristic on the right.\r
+\r
+  3. Press TAB until 'Text screen, 16 point' appears at the bottom line,\r
+     if it doesn't already.  TAB selects which test pattern to use, and\r
+     you have now readied the 16-point font version of the text screen\r
+     test.\r
+\r
+  4. Press ENTER.  You should see a screen with numbers along the top\r
+     row, and various characters and colors down the rest of the screen.\r
+     This is the text test pattern, as it looks when viewed in mode 3.\r
+     Press ENTER to return to editing mode.\r
+\r
+  5. Now press F10, and type '40x12' and press ENTER.  This loads the\r
+     file '40x12' and uses its contents as the current register set.  \r
+     Notice how the mode heuristic immediately changes.\r
+\r
+  6. Press ENTER again.  A screen similar to the previous test pattern\r
+     should appear, but the characters should be twice as wide and twice\r
+     as high.  This is a tweaked VGA mode, which is not supported by the\r
+     BIOS.  It looks a little odd, as the bottom line is cut in half,\r
+     making this a 40x12.5 text mode, in fact.  Press ENTER to return.\r
+\r
+  7. Press F10, type '360x480.256' and ENTER.  Take a look at the \r
+     mode heuristic again.  Press TAB until the text 'Graphics \r
+     autodetect' appear in the bottom line.\r
+\r
+  8. Press ENTER.  This is a well known tweaked VGA mode that has even\r
+     been used in commercial games for the PC, but it remains\r
+     unsupported by the BIOS (and it probably always will).  If the\r
+     screen rolls, try adjusting your monitor knobs.  If you can't get a\r
+     steady picture, it probably means your monitor isn't capable of\r
+     handling the horizontal resolution of 360 pixels.\r
+\r
+  9. Try using the arrows to scroll the virtual screen.\r
+\r
+  9. Press ENTER to return to editing, then press ESC and 'Y' to quit \r
+     TWEAK.\r
+\r
+\r
+The last graphics display might not have been especially pleasing to the\r
+eye.  First, if the picture was rolling uncontrollably, you might think\r
+that TWEAK is of no use for you, as your monitor isn't good enough.\r
+However there are still interesting things to try out.  There are\r
+tweaked modes 'available' with a little lower resolution that are almost\r
+guaranteed to work on your monitor, and which are of great interest to\r
+games programmers for example.  The file 320x240.256 contains the\r
+register set for the infamous Mode X, which was 'discovered' and\r
+documented by Michael Abrash in his monthly columns in Doctor Dobbs\r
+Journal.\r
+\r
+Following points 7 onward above, see if you can load Mode X into the \r
+editor and get the test screen going!\r
+\r
+Mode X has the following interesting properties:\r
+\r
+  *  The pixels are 'perfectly' square.  That is, if you try to draw a\r
+     circle with aspect ratio 1:1, it will look like a circle (unless\r
+     your monitor is adjusted to some extreme).  The BIOS mode 13h\r
+     (320x200x256) has pixels that are a little higher than they are\r
+     wide, making 1:1 circles look stretched vertically.\r
+\r
+  *  The video memory is divided into 4 planes, each of which contains\r
+     64 Kb.  By setting the Write Plane Enable register to the actual\r
+     plane, you can address the full 256 Kb of video memory through the\r
+     'tiny' address space of 64 Kb from 0xA000:0 to 0xA000:0xFFFF.\r
+     Thus, you can have more than three full screens in video memory at\r
+     any one time, making you able to perform animation tricks as\r
+     page flipping, and to do fast 32-bit video to video transfers.\r
+\r
+This was just to get you going, and others have written tons of text on\r
+drawing stuff (lines, circles, images) in Mode X.  The rest of this\r
+part will deal with the commands available in TWEAK.  To get more\r
+information about VGA programming in general and registers and Mode X \r
+in particular, check out the reference list somewhere at the end.\r
+\r
+Stop press!  Read the article in the XINTRO subdirectory for an\r
+introduction to Mode X.\r
+\r
+\r
+\r
+\r
+\r
+                         EDITOR REFERENCE\r
+\r
+\r
+This reference applies only to version 1.0 of TWEAK or later, although\r
+*most* keys are supported by the included version 0.95 too.\r
+\r
+Select the register value you want to modify using the following keys:\r
+\r
+     Up         selects previous register\r
+     Down       selects next register\r
+     Home       selects first register\r
+     End        selects last register\r
+\r
+Use these keys to modify a register value:\r
+\r
+     a 2-digit, hexadecimal number : sets the register to the given value\r
+     '-'        decreases the value of the register\r
+     '+'        increases the value of the register\r
+     F1 ... F8  toggle bits 7, 6, ..., 0 of the selected register,\r
+                respectively.\r
+\r
+Use these keys for testing the set of register values:\r
+\r
+     TAB [->|]  cycle among the available test patterns, to find the\r
+                one you think will suit your custom register set.\r
+                Shift+TAB cycles in the opposite direction.\r
+\r
+     ENTER      sends your custom register set to the VGA registers, then\r
+                writes the selected test pattern to the video memory buffer.\r
+\r
+Some other important or useful actions:\r
+\r
+     Backspace  toggles the active state of the current register.  If a\r
+                register is inactive, it color is grey instead of yellow.\r
+                When you test the mode (by pressing ENTER), inactive\r
+                registers will *not* be sent to the VGA card.  Also, they\r
+                will *not* be saved to the file when a Save command is\r
+                executed.  This feature is included to enable you to ignore\r
+                registers that doesn't affect your screen mode.  For\r
+                example, for most practical uses, the Color Compare register\r
+                can be deactivated.\r
+\r
+     'M'        prompts the user for a 2-digit, hexadecimal number\r
+                specifying a standard VGA BIOS screen mode number.  Note\r
+                that TWEAK does *not* support true monochrome modes.\r
+                The VGA is set to this mode using INT 10h with AX=mode\r
+                number.  Then all relevant registers are read from the\r
+                VGA into the editing set, and you're returned to the\r
+                editing screen.\r
+\r
+     F9 or 'S'  prompts the user for a file name, then saves the register\r
+                set to this file, overwriting any pre-existing\r
+                file by the same name.  Inactive registers are not saved,\r
+                thus there are no longer a fixed size to TWEAK's mode\r
+                files.\r
+\r
+     F10 or 'L' prompts the user for a file name, then loads the register\r
+                set from this file, if it exists.  Registers that are\r
+                supported by TWEAK, but that are not included in the file,\r
+                will be deactivated (greyed).\r
+\r
+     ESC        quits TWEAK, if you answer 'y' or 'Y' to the 'Really\r
+               quit?' question.  Make sure you have saved your work.\r
+\r
+Pressing just ENTER at one of the two file name requests will cancel \r
+the file operation.\r
+\r
+\r
+There are currently 6 available test screens with TWEAK.  Numbers in\r
+parentheses are all the standard VGA BIOS modes that display the test\r
+patterns correctly:\r
+\r
+  o  An autodetected graphics screen test.  This will detect *most*\r
+     EGA and VGA graphics modes (of course no monochrome modes), and\r
+     display a pretty screen containing:\r
+\r
+     -  axes along the left and top borders visualizing the resolution.\r
+     -  text telling you both the physical and the virtual resolutions,\r
+        and the number of colors.\r
+     -  the entire palette available in this mode.  Note that the\r
+        palette is *not* set, so the colours are not guaranteed to be\r
+        the normal VGA palette, except in 16-color mode.\r
+\r
+     The following keys are available in the autodetect test screen:\r
+\r
+     -  arrows scroll the screen across the virtual area\r
+     -  ESC returns to the editor\r
+\r
+     If the mode being edited is not a graphics mode, a text screen\r
+     appears with some helping hints.\r
+\r
+  o  2 text test screens at 0B800h\r
+     -  one using the normal 8x16-point VGA font (0, 1, 2, 3)\r
+     -  one using the 8x8-point CGA font (normally used in 43/50-line\r
+        modes, but none of those are defined by the VGA BIOS.  Check\r
+        VGABIOS.DOC for the function to load a specific font in your \r
+       own programs.)\r
+\r
+  o  A screen for 4-planar, 16-color modes at 0A000h (0Dh, 0Eh, 10h,\r
+     12h)\r
+\r
+  o  A screen for 4-chained, 256-color modes at 0A000h (13h)\r
+\r
+  o  A screen for 4-planar, 256-color modes at 0A000h (None supported\r
+     by BIOS)\r
+\r
+See the source (TESTPAT.CPP) for descriptions on how the test patterns are\r
+supposed to look.  Generally, if it looks good, it should be correct.\r
+\r
+\r
+\r
+\r
+\r
+                    FREQUENTLY ASKED QUESTIONS\r
+\r
+\r
+Q:      I'd like to study the register configuration for a screen mode\r
+        supported by my (Super-)VGA.  How do I get to it?\r
+\r
+A:      The 'M' key lets you select a BIOS mode to study.  Note that you\r
+        will need to know the mode number.  Note that TWEAK does not \r
+       support any SVGA-specific registers.\r
+\r
+\r
+Q:      None of the tests seem to produce sane results.  The screen\r
+        a) goes black,\r
+        b) rolls or\r
+        c) the program crashes.\r
+\r
+A:      a)  - Make sure you tried ALL 5 tests.\r
+            - Set the Color Plane Write Enable register to 0Fh.\r
+            - Note that Super VGA modes are generally not supported\r
+              (though they *might* work).\r
+        b)  - The timing/sync registers are not set correctly/in sync.\r
+              See your VGA reference for more information.\r
+            - Try adjusting the knobs on your monitor.\r
+       c)  - I know some (S)VGAs completely hang the system if\r
+             unsupported bit combinations are fed into the Misc.\r
+             Output Register (0x3c2).  This is one of the most useful\r
+             registers, however, so experiment with care, and take note\r
+             of what values causes the crash.\r
+            - You may have hit a major incompatibility/bug.  Send me a\r
+              mail, telling me what kind of hardware you're using.  I\r
+              will probably not be able to fix it, but an incompatibility\r
+              list will be emitted with the next release, if any.\r
+\r
+\r
+Q:      How about a TSR to save the current register configuration from\r
+        any program?\r
+\r
+A:      I've considered this, but haven't had the time.  A hint, though:\r
+        Get CBOOTxxx.ZIP from simtel or any mirror, in .../msdos/sysutl.\r
+        This program lets you break out from most applications,\r
+        *without* resetting the screen mode.  A typical session:\r
+            - Install CBOOT.\r
+            - Run FRACTINT (a fractal explorer package, supporting lots\r
+              of tweaked modes), and select the mode you want to 'grab'.\r
+            - Press ALT+SHIFT+B, and the CBOOT menu pops up.\r
+            - Press '7' to reset interrupt vectors.\r
+            - Press '6' to 'properly' exit from FRACTINT.\r
+            - You might not see it, but you should be at the DOS prompt.\r
+            - Run TWEAK directly, which will start up with the current\r
+              register configuration.  Now you're off!\r
+       From programs (games) which assume total keyboard domination, I\r
+       currently cannot help you grab modes.\r
+\r
+\r
+Q:      I'd like to use tweaked modes in my own programs.\r
+\r
+A:      Provided you have produced TWEAK files corresponding to your\r
+        modes, take a look at the example files for different approaches\r
+        to using the mode files.  The examples are in C, but are simple\r
+        enough, so translation to Pascal should be a breeze.\r
+\r
+\r
+Q:      - What is the register which makes x do y/sets a to b/etc.?\r
+        - Is there a BIOS call to do x?\r
+\r
+A:      First check the VGA.TXT and VGABIOS.TXT files in the MISC\r
+        directory.  If they don't help you, please consider buying a\r
+        technical reference to the VGA.  That would please you and me.\r
+\r
+\r
+Q:      How do I make a mode with resolution x times y with z colors?\r
+\r
+A:      - See the sample *.TWK, *.256 and *.16 files provided with\r
+          TWEAK.  Not a great lot, but you might be able to work out\r
+          something from one of those.\r
+        - Get FRACTINT or SVGABGI, and use the method mentioned above to\r
+          'grab' modes from these programs.\r
+       - Learn what each of the VGA timing registers means.\r
+        - Experiment!  That's what I had to do.\r
+\r
+\r
+Q:      I can't find this MISC or XINTRO directory!\r
+\r
+A:      Make sure you unzip the TWEAK archive with the -d option, which\r
+        is needed to extract subdirectories.  I.e:\r
+          PKUNZIP -D A:TWEAK10\r
+       If you didn't use -D, the files in the MISC directory are mixed\r
+       in with the rest of the TWEAK package files, all in the same\r
+       directory.\r
+\r
+\r
+Q:      I have lots of files with modes that I saved with version 0.9 of\r
+        TWEAK...\r
+\r
+A:      Use the 09TO10 utility to convert them.  Run 09TO10.EXE with no\r
+        parameters for a simple help screen.\r
+\r
+\r
+Q:      What do I need to rebuild TWEAK and/or the utilities?\r
+\r
+A:      You will need Borland C++.  I used version 3.1, but it might\r
+        work as far back as Turbo C++ 1.0.  I included a Makefile to\r
+        make rebuilding as painless as possible, provided you have\r
+        BCC.EXE in your path, and it knows where to find headers and\r
+        libraries (usually it does).  I know some of the sources\r
+       produce warnings, but feel free to ignore them.  I did.\r
+\r
+\r
+Q:      What do I need to use the mode files produced by TWEAK in my own\r
+        programs?\r
+\r
+A:      If you want to use the TwkUser module, you'll need a C compiler.\r
+        I don't think I used anything Borland specific here.\r
+        Otherwise the file format is pretty simple, so you should have\r
+        no problem making similar functions/procedures using any\r
+        language (assembler, Basic, Pascal, Prolog...).\r
+\r
+\r
+Q:      Where can I find more information on tweaking the VGA?\r
+\r
+A:      See the Bibliography section below.  Michael Abrash's articles\r
+        in Doctor Dobb's Journal from a year or so are probably the best\r
+        sources.  Join the rec.games.programmer newsgroup.  There has\r
+        been some discussion on tweaking there, especially mode X\r
+       (320x240x256) and how to optimize code for this mode.\r
+\r
+\r
+Q:      How can I ever repay you for making such a great utility?\r
+\r
+A:      Easy!  The cheapest way is to send me a cool postcard with some\r
+        (readable) words on it.  I will of course accept donations too,\r
+        even though TWEAK is public domain.  See the end of this file.\r
+\r
+\r
+Q:      PKUNZIP refused to unzip the TWEAK archive!\r
+\r
+A:      I guess you decoded this DOC file by hand, then...  well, make\r
+        sure you transfer in BINARY mode from the ftp site, and in \r
+       BINARY from your user account to your PC.\r
+\r
+\r
+Q:      I can't find my question in the Frequently Asked Questions list!\r
+        Does this mean I'm stupid?\r
+\r
+A:      It might.  :-)  However, I just thought up all these questions\r
+        myself, so if you have a suggestion for more FAQs, don't\r
+        hesitate to let me know!  I promise I won't laugh...\r
+\r
+\r
+Q:     The mode heuristic tells me I have the mode I want, but none of \r
+       the test screens works, not even the autodetecting one!\r
+\r
+A:     The heuristic is far from perfect.  It does NOT verify that the \r
+       timing values you are using are sane - it merely checks the \r
+       registers determining the logical resolutions.  The best advice \r
+       I can give is to get a VGA reference and try to learn what the \r
+       horizontal and vertical timing registers do.  TWEAK is less \r
+       intelligent than you (hopefully)!\r
+\r
+\r
+\r
+\r
+                        THE TWEAK FILES\r
+\r
+\r
+The file format used for saved files is pretty simple.  The files will\r
+usually be bigger than the files saved with TWEAK 0.9, and version 0.9\r
+files are *not* readable by version 1.0.  This is undetectable by TWEAK,\r
+because of the simple nature of the files.  (No headers are present!) \r
+If you try, there's a fat chance that your computer will hang.\r
+\r
+Here is the format:\r
+\r
+offset 0: WORD - port number of first register\r
+offset 2: BYTE - index of first register\r
+offset 3: BYTE - value of first register\r
+\r
+offset 4: WORD - port number of second register\r
+.\r
+.etc.\r
+.\r
+\r
+Pretty simple, as you can see, but also flexible from TWEAK's point of\r
+view.  This makes it easy to add new ports if neccessary.  The file size\r
+is not constant, as registers that are disabled at save time are not\r
+written to the file.  Divide the file size by 4 to determine the number\r
+of registers in a file, or just read to EOF (as TWEAK does... :).\r
+\r
+Also note that the VGA registers use varying methods for access.  For\r
+some registers you just send the value directly to the port (ignoring the\r
+index).  For some you send the index to the port, then the value to the\r
+port+1.  For still some you have to ...  Rather, refer to the source\r
+code for all the how-to's...  it's not difficult, just inconvenient, and\r
+it hinders really general storage of register addresses and their values.\r
+\r
+Use the 09TO10.EXE program to convert from version 0.9 files to version\r
+1.0 files.  Run 09TO10.EXE with no parameters for information on how to\r
+use the utility.\r
+\r
+I have selected the following standard of file extensions for\r
+TWEAK-files, but these are just suggestions for my own convenience:\r
+\r
+  o  *.TWK are text modes\r
+  o  *.16 are 16-color graphic modes\r
+  o  *.256 are 256-color graphic modes\r
+\r
+Note that you'll always have to type an extension in TWEAK if you want\r
+any, as TWEAK neither assumes anything nor provides default extensions.\r
+\r
+I have also started addint a 'c' to the name (like in 256x256c.256) if \r
+the mode is chained, i.e. uses linear addressing like mode 13h.  I add \r
+an 's' if the mode is specific to my Chips & Technologies SVGA.\r
+\r
+Make sure you read MODES.DOC!\r
+\r
+\r
+\r
+\r
+\r
+                  USING TWEAK MODES ON YOUR OWN\r
+\r
+\r
+The Register and RegisterTable classes used in TWEAK.CPP might be a\r
+little huge and clumsy to use in your own programs, where you probably\r
+just want to set the registers according to a linked-in array.\r
+Therefore I have provided a simple C module for the following functions:\r
+\r
+  o  Reading a file saved from TWEAK into a dynamically allocated\r
+     array of registers.\r
+  o  Setting VGA registers according to the contents of an array of\r
+     registers.\r
+  o  Setting a single register.\r
+\r
+The types and functions are declared in TWKUSER.H, which should be\r
+included in every source file using these functions.  The definitions\r
+are contained in TWKUSER.C, which should be compiled under the wanted\r
+memory model and linked together with your program modules.  You are\r
+free, in fact you're encouraged to modify the TWKUSER files to suit\r
+your own needs.  In their present form, they just provide enough\r
+functionality to get you started.\r
+\r
+A couple of simple examples are provided - the second one is easiest to\r
+follow, and I think you will prefer that one:\r
+\r
+  o  EXAMPLE1.C - demonstrates how to use a TWEAK-generated file\r
+     in your own program by loading the file at run-time, and setting \r
+     the VGA registers according to the file contents.  The mode file \r
+     has to be available at run-time.\r
+\r
+  o  EXAMPLE2.C - does the same, but now the TWEAK-file is converted to\r
+     a C-includable file by using the TWEAK2C utility.  Thus, the contents\r
+     of the TWEAK file is linked with the program as global data, and no\r
+     external file is needed in addition to the executable.\r
+\r
+Both programs set the VGA to the famous Mode X, 320x240 in 256 colors,\r
+then fill the screen with some colors.\r
+\r
+Note that since the files produced by TWEAK does not keep any \r
+information on what BIOS mode they are based on, you are responsible \r
+for setting the palette used.  Keep in mind that you need to set both \r
+the EGA and VGA palette for 256-color modes!  The easiest way to \r
+accomplish this is to set mode 13h before outputting your register \r
+settings.\r
+\r
+I would very much like to provide similar Borland Pascal examples, but\r
+as I don't have Turbo/Borland Pascal available at the moment, I'm just\r
+going to skip it at this time.  If *you* feel like porting the TwkUser.C\r
+and .H files to a Pascal unit, please do.  It should be a peice of cake.\r
+If you mail the result to me, I'll probably include it in the next release\r
+of TWEAK, and in any case you'll be credited for your contribution.\r
+\r
+\r
+\r
+\r
+\r
+                      THE INCLUDED FILES\r
+\r
+\r
+This is a dump of the 4DOS compatible DESCRIPT.ION file included in this\r
+archive:\r
+\r
+320x200.256 Planar 320x200x256\r
+320x240.256 Planar 320x240x256 (Mode X)\r
+360x480.256 Planar 360x480x256\r
+400x300s.256 Tweaked C&T SVGA planar\r
+400x600.256 Tweaked VGA, req. good monitor\r
+400x600s.256 Tweaked C&T SVGA planar\r
+432x600s.256 Tweaked C&T SVGA planar\r
+800x600s.16 Standard C&T SVGA BIOS mode\r
+40x12.twk Standard VGA BIOS mode 1, double scanned\r
+80x43.twk Standard VGA mode, needs 8x8 font\r
+80x50.twk Standard VGA mode, needs 8x8 font\r
+09to10.cpp Version 0.9x to 1.0 conv. util. source\r
+800x600.16 Tweaked VGA, req. good monitor\r
+example1.c C source for EXAMPLE1.EXE\r
+example2.c C source for EXAMPLE2.EXE\r
+makefile Type MAKE ALL to update TWEAK project\r
+namedreg.cpp C++ source defining NamedReg. members\r
+register.hpp C++ header declaring Register & NamedReg\r
+regtable.cpp C++ source defining RegisterTable\r
+regtable.hpp C++ header declaring RegisterTable\r
+screen.cpp C++ source defining screen functions\r
+screen.hpp C++ header declaring screen functions\r
+tweak.cpp C++ source defining TWEAK's main program\r
+tweak.doc Documentation for the TWEAK archive\r
+tweak2c.cpp C++ source for the TWEAK2C utility\r
+twkuser.c C source defining som usable functions\r
+twkuser.h C header with TwkUser.C prototypes\r
+register.cpp C++ source defining Register members\r
+320x240.c C file created by TWEAK2C\r
+c&t.dat Text file: list of supported registers\r
+256x256.256 Planar 256x256x256 (Mode Q)\r
+256x256c.256 Chained 256x256x256 (Mode Q, chained)\r
+testpat.cpp C++ source defining TestPatterns members\r
+testpat.hpp C++ header declaring TestPatterns\r
+256x240.256 Planar 256x240x256\r
+360x270.256 Experimental mode\r
+400x300.256 Planar 400x300x256 - great!\r
+detect.cpp C++ source for mode detected module\r
+detect.hpp C++ header for detect.cpp\r
+misc.hpp Various common routines and macros\r
+tweak095.cpp C++ source for TWEAK version 0.95\r
+vgalib.cpp The mode-independant VGA library source\r
+vgalib.hpp Header for VGALIB.HPP\r
+regedit.cpp C++ source for the RegisterEditor class\r
+regedit.hpp C++ header for REGEDIT.CPP\r
+descript.ion Descriptions of all files\r
+tweak.prj TWEAK archive BC++ 3.1 project file\r
+320x400.256 Planar 320x400x256\r
+360x360.256 Planar 360x360x256\r
+360x400.256 Planar 360x400x256\r
+376x564.256 Planar 376x564x256\r
+tweakold.dat Data file: list of supported registers\r
+132x25s.twk Standard C&T SVGA BIOS mode\r
+132x43s.twk Standard C&T SVGA BIOS mode\r
+132x50s.twk Standard C&T SVGA BIOS mode\r
+132x60s.twk Ultravision C&T SVGA mode\r
+modes.doc Document on Mode Q, 400x300 and 400x600\r
+\r
+The only files required to run TWEAK are:\r
+\r
+  o  TWEAK.EXE\r
+  o  TWEAK.DAT\r
+\r
+The register definitions have been moved out from the executable into\r
+the external .DAT file, to increase flexibility.  You might edit the\r
+TWEAK.DAT file as you like to include support for any registers you\r
+might think of.  Remember to update the number in the first line to\r
+reflect the number of defined registers.  Note that if your new registers\r
+are not on one of the ports supported by TWEAK.EXE, you might need to\r
+modify and recompile the TWEAK sources to accomodate the new port(s).\r
+See REGISTER.CPP.\r
+\r
+\r
+\r
+Some words on my convention of naming files made by TWEAK:\r
+----------------------------------------------------------\r
+\r
+  o  The general name format is XXXxYYY.CCC, where\r
+        XXX is the horizontal resolution\r
+        YYY is the vertical resolution\r
+        CCC is the number of colors supported, except for text modes,\r
+            which are named *.TWK.\r
+  o  An 's' after YYY specifies a Super VGA specific mode which I grabbed\r
+     from the BIOS of my Chips & Technologies Super VGA.  These modes will\r
+     probably *not* work with your card unless it's C&T compatible!  I've\r
+     had reports that most of these modes even crash some sensitive\r
+     machines/VGA cards.\r
+  o  A 'c' signals a chained 256-color mode, much like mode 13h, as \r
+     opposed to unchained modes like mode X.\r
+\r
+\r
+The Makefile & sources\r
+----------------------\r
+\r
+See the Makefile for all dependencies between the source files.  It's not\r
+very complicated.\r
+\r
+The following makes are defined in the Makefile:\r
+\r
+make tweak: makes the TWEAK executable.\r
+make oldtweak: makes the TWEAK095 executable.\r
+make examples: makes EXAMPLE*.EXE.\r
+make utilities: makes 09TO10.EXE and TWEAK2C.EXE.\r
+make all: combines all the above makes.\r
+\r
+The Makefile is Borland C++/MAKE specific, and uses bcc.exe for all the\r
+work, with one reference to TWEAK2C.EXE.\r
+\r
+When studying the sources, note that TWEAK was started as an experiment\r
+in object oriented programming with C++.  Thus the entire project may look\r
+a bit pompous in its use of classes, overloaded operators and such.\r
+Bear with me.  At last I provided the TwkUser files to help you get\r
+started with something down to earth.\r
+\r
+In their current state, some of the source files produce a couple of\r
+warnings.  These can be ignored.  I do.\r
+\r
+Also note that TwkUser.* and the examples are C (but C++ compatible),\r
+while TWEAK and its utilities are strictly C++.\r
+\r
+\r
+The utilities TWEAK2C and 09TO10\r
+--------------------------------\r
+\r
+The following are dumps of the help screens from there programs:\r
+\r
+"TWEAK2C version 1.0\r
+ by Robert Schmidt of Ztiff Zox Softwear 1993\r
+ Converts a TWEAK version 1.x file to an #include-able C file.\r
+\r
+ Syntax:  TWEAK2C <TWEAK-file> <C file to create> <array name>\r
+ All parameters are required."\r
+\r
+"09TO10 version 1.0\r
+ by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+ Converts TWEAK version 0.9 files to TWEAK version 1.0 files.\r
+\r
+ Syntax:  09TO10 <oldfile> <newfile>"\r
+\r
+For both programs, the following goes:  If the file to be created already\r
+exists, the data contained in the file on disk will be overwritten with the\r
+new data.\r
+\r
+\r
+\r
+\r
+\r
+                      THE 'MISC' DIRECTORY\r
+\r
+\r
+In this directory I have included files from other sources than myself.\r
+\r
+READ.ME\r
+VGA.TXT\r
+VGABIOS.TXT\r
+        I found these files in an archive assembled by Finn Thoegersen\r
+        of Denmark.  I beleive VGABIOS.DOC was taken from Ralph Brown's\r
+        interrupt list.  VGA.TXT lists VGA registers and their purpose,\r
+        but as I never used either VGA.TXT or VGABIOS.TXT, I can't\r
+        guarantee their correctness.  The complete archive containing\r
+        similar info on most popular Super VGAs can be found on\r
+        garbo.uwasa.fi in /pc/doc-hard/vgadoc2.zip.\r
+\r
+CGA160.TXT\r
+        A post grabbed from some newsgroup, discussing tweaking on the\r
+        ancient CGA adapter.  I think 16-color 'graphics' on a CGA\r
+        sounds pretty interesting, so I included it for your enjoyment.\r
+\r
+SETMODEX.ASM\r
+        Michael Abrash's code to set the VGA in the infamous Mode X.\r
+        Provided as an example of how programmers were used to tweaking,\r
+        before TWEAK came along... :)\r
+\r
+\r
+\r
+\r
+\r
+                           CREDITS\r
+\r
+Alphabetically:\r
+\r
+  o  Michael Abrash for doing so much work on Mode X and PC graphics in\r
+     general.\r
+  o  Ralph Brown for the great work on the Interrupt List.\r
+  o  Peter McDermott for an improved 16-color test screen, and valuable\r
+     sugestions, he also inspired me to make the autodetecting test\r
+     screen.\r
+  o  Kai Rohrbacher for helpful bug reports and info on working modes.\r
+  o  Finn Thoegersen for the MISC\VGA*.TXT files.  See MISC\READ.ME\r
+  o  Yaniv Shaya for inspiring me to make finish version 1.0.  Good luck\r
+     with your project!\r
+\r
+\r
+\r
+\r
+\r
+                         BIBLIOGRAPHY\r
+\r
+  o  George Sutty & Steve Blair : "Advanced Pogrammer's Guide to the\r
+     EGA/VGA" from Brady.  A bit old perhaps, but covers all *standard*\r
+     EGA/VGA registers, and discusses most BIOS functions and other\r
+     operations.  Contains disk with C/Pascal source code.\r
+\r
+  o  Michael Abrash : "Power Graphics Programming" from QUE/Programmer's\r
+     Journal.  Collections of (old) articles in Doctor Dobb's Journal on\r
+     EGA/VGA, read modes and write modes, animation, tweaking (320x240\r
+     and 360x480).  His newer ravings in DDJ covers fast 256-color\r
+     bitmaps, compiled bitmaps, 3D graphics, polygons, texture mapping\r
+     among other stuff.  Check out the XSHARP library available on all\r
+     simtel mirrors!\r
+\r
+  o  Ralph Brown's interrupt list is a must for every serious\r
+     programmer, containing, among 1 million other things, a VGA BIOS\r
+     interrupt reference.  Available for anonymous ftp from\r
+     oak.oakland.edu in directory /pub/msdos/info as inter*.zip (Usually\r
+     3 files, around 330 Kb each), and on most serious BBSes.\r
+\r
+  o  Richard F. Ferraro : "Programmer's Guide to the EGA and VGA video\r
+     cards including Super VGA".  I don't have this one, but heard it's\r
+     nice.  The Super VGA reference makes it attractive, though that is\r
+     no help with TWEAK.\r
+\r
+  o  Richard Wilton : "Programmer's Guide to PC & PS/2 Video Systems"\r
+     Less technical, more application/algorithm oriented.  Supposed to be\r
+     good.\r
+\r
+\r
+\r
+\r
+                        HOW TO REACH ME\r
+\r
+\r
+I welcome any suggestions for further improvement of TWEAK.  I also\r
+accept donations if you think it's worth it, or if TWEAK has in any way\r
+helped you out with a tricky problem and you'd like to show your\r
+appreciation.  I will personally e-mail subsequent versions to people who\r
+donate $5 or more.  Make checks payable to Robert Schmidt personally.\r
+\r
+Postcards from all over the world are fun to get.  Please, if you\r
+contact me by ordinary mail, use a postcard with some photos from the\r
+place you live on the front!  I appreciate that a lot.\r
+\r
+\r
+\r
+Internet e-mail: robert@stud.unit.no\r
+\r
+(I guess this should be reachable from Compuserve and other networks\r
+too.  I don't know how, though.)\r
+\r
+If you ever join the IRC service on the Internet, direct a /msg Buuud\r
+for a chat!  I'm on pretty often.\r
+\r
+\r
+\r
+Ordinary (snail-)mail:\r
+\r
+Ztiff Zox Softwear\r
+c/o Robert Schmidt\r
+Stud.post 170\r
+Norwegian Institute of Technology\r
+Trondheim\r
+NORWAY\r
+\r
+\r
+Good luck, and remember the most important bit is to have fun!\r
+\r
diff --git a/16/tweak16/TWEAK.EXE b/16/tweak16/TWEAK.EXE
new file mode 100755 (executable)
index 0000000..ab11b36
Binary files /dev/null and b/16/tweak16/TWEAK.EXE differ
diff --git a/16/tweak16/TWEAK2C.CPP b/16/tweak16/TWEAK2C.CPP
new file mode 100755 (executable)
index 0000000..78b22b7
--- /dev/null
@@ -0,0 +1,58 @@
+/*\r
+       TWEAK2C version 1.0\r
+       by Robert Schmidt of Ztiff Zox Softwear 1993\r
+\r
+       Converts a TWEAK version 1.0 file to an #include-able C file\r
+       defining the equivalent Register array, which is directly\r
+       passable to the outRegArray() function defined in the TwkUser\r
+       module.\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <fstream.h>\r
+\r
+extern "C"\r
+       {\r
+       #include "TwkUser.h"\r
+       }\r
+\r
+main(int argc, char **argv)\r
+       {\r
+       if (argc < 4)\r
+               {\r
+               printf("TWEAK2C version 1.0\n"\r
+                          "by Robert Schmidt of Ztiff Zox Softwear 1993\n"\r
+                          "Converts a TWEAK version 1.x file to an #include-able C file.\n"\r
+                          "\n"\r
+                           "Syntax:  TWEAK2C <TWEAK-file> <C file to create> <array name>\n"\r
+                          "All parameters are required.\n"\r
+                          );\r
+\r
+               return 0;\r
+               }\r
+\r
+       Register *table;\r
+       int regs = loadRegArray(argv[1], &table);\r
+       if (!table)\r
+               return 1;                       // loadRegArray provides error message\r
+\r
+       ofstream out(argv[2], ios::out | ios::trunc);\r
+\r
+       out << "#include \"TwkUser.h\" // get Register definition" << endl;\r
+       out << "Register " << argv[3] << "[] =" << endl;\r
+       out << "\t{" << hex << endl;\r
+\r
+       Register *reg = table;\r
+       while (regs--)\r
+               {\r
+               out << "\t{ 0x" << reg->port << ", 0x" << int(reg->index)\r
+                       << ", 0x" << int(reg->value) << (regs?"},\n":"}\n");\r
+               reg++;\r
+               }\r
+       out << "\t};" << endl;\r
+\r
+       free(table);\r
+\r
+       return 0;\r
+       }\r
diff --git a/16/tweak16/TWEAK2C.EXE b/16/tweak16/TWEAK2C.EXE
new file mode 100755 (executable)
index 0000000..a8b8092
Binary files /dev/null and b/16/tweak16/TWEAK2C.EXE differ
diff --git a/16/tweak16/TWEAKOLD.DAT b/16/tweak16/TWEAKOLD.DAT
new file mode 100755 (executable)
index 0000000..d65d271
--- /dev/null
@@ -0,0 +1,44 @@
+5\r
+\r
+0x3c2 Miscellaneous Output\r
+0\r
+\r
+0x3d4 The CRT Controller\r
+18\r
+0x00 Horiz. total\r
+0x01 Horiz. disp. enable end\r
+0x02 Horiz. blank start\r
+0x03 Horiz. blank end\r
+0x04 Horiz. retrace start\r
+0x05 Horiz. retrace end\r
+0x06 Vertical total\r
+0x07 Overflow register\r
+0x08 Preset row scan\r
+0x09 Max scan line/char ht.\r
+0x10 Vertical retrace start\r
+0x11 Vertical retrace end\r
+0x12 Vert. disp. enable end\r
+0x13 Offset/Logical width\r
+0x14 Underline location\r
+0x15 Vertical blank start\r
+0x16 Vertical blank end\r
+0x17 Mode control\r
+\r
+0x3c4 The Sequencer\r
+3\r
+0x01 Clock mode register\r
+0x03 Character gen. select\r
+0x04 Memory mode register\r
+\r
+0x3ce The Graphics Controller\r
+2\r
+0x05 Mode register\r
+0x06 Miscellaneous register\r
+\r
+0x3c0 The Attribute Controller\r
+5\r
+0x10 Mode control\r
+0x11 Screen border colour\r
+0x12 Color plane enable\r
+0x13 Horizontal panning\r
+0x14 Color select\r
diff --git a/16/tweak16/TWKUSER.C b/16/tweak16/TWKUSER.C
new file mode 100755 (executable)
index 0000000..2a6405f
--- /dev/null
@@ -0,0 +1,134 @@
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <dos.h>\r
+#include <io.h>\r
+#include <fcntl.h>\r
+\r
+#include "TwkUser.h"\r
+\r
+/*\r
+    readyVgaRegs() does the initialization to make the VGA ready to\r
+       accept any combination of configuration register settings.\r
+\r
+       This involves enabling writes to index 0 to 7 of the CRT controller\r
+       (port 0x3d4), by clearing the most significant bit (bit 7) of index\r
+       0x11.\r
+*/\r
+\r
+void readyVgaRegs(void)\r
+       {\r
+       int v;\r
+       outportb(0x3d4,0x11);\r
+    v = inportb(0x3d5) & 0x7f;\r
+       outportb(0x3d4,0x11);\r
+       outportb(0x3d5,v);\r
+       }\r
+\r
+/*\r
+       outReg sets a single register according to the contents of the\r
+       passed Register structure.\r
+*/\r
+\r
+void outReg(Register r)\r
+       {\r
+       switch (r.port)\r
+               {\r
+               /* First handle special cases: */\r
+\r
+               case ATTRCON_ADDR:\r
+                       inportb(STATUS_ADDR);           /* reset read/write flip-flop */\r
+                       outportb(ATTRCON_ADDR, r.index | 0x20);\r
+                                                                               /* ensure VGA output is enabled */\r
+                       outportb(ATTRCON_ADDR, r.value);\r
+                       break;\r
+\r
+               case MISC_ADDR:\r
+               case VGAENABLE_ADDR:\r
+                       outportb(r.port, r.value);      /*      directly to the port */\r
+                       break;\r
+\r
+               case SEQ_ADDR:\r
+               case GRACON_ADDR:\r
+               case CRTC_ADDR:\r
+               default:                                                /* This is the default method: */\r
+                       outportb(r.port, r.index);      /*      index to port                      */\r
+                       outportb(r.port+1, r.value);/*  value to port+1                    */\r
+                       break;\r
+               }\r
+       }\r
+\r
+\r
+/*\r
+       outRegArray sets n registers according to the array pointed to by r.\r
+       First, indexes 0-7 of the CRT controller are enabled for writing.\r
+*/\r
+\r
+void outRegArray(Register *r, int n)\r
+       {\r
+    readyVgaRegs();\r
+       while (n--)\r
+               outReg(*r++);\r
+       }\r
+\r
+\r
+/*\r
+       loadRegArray opens the given file, does some validity checking, then\r
+       reads the entire file into an array of Registers, which is returned\r
+       via the array parameter.\r
+\r
+       You will probably want to provide your own error handling code in\r
+       this function, as it never aborts the program, rather than just\r
+       printing an error message and returning NULL.\r
+\r
+       The returned value is the number of Registers read.  The &array\r
+       parameter is set to the allocated Register array.\r
+\r
+       If you use this function, remember to free() the returned array\r
+       pointer, as it was allocated dynamically using malloc() (unless NULL\r
+       is returned, which designates an error)!\r
+*/\r
+\r
+int loadRegArray(char *fpath, RegisterPtr *array)\r
+       {\r
+       int handle, regs;\r
+       long fsize;\r
+       *array = NULL;\r
+\r
+       if ((handle = open(fpath, O_BINARY | O_RDONLY)) == -1)\r
+               /* error opening file */\r
+               /* include your error handling code here */\r
+               goto fileerror;\r
+\r
+    if ((fsize = filelength(handle)) == -1)\r
+               /* error acquiring file size */\r
+               goto fileerror;\r
+       if (fsize % sizeof(Register))\r
+               {\r
+               printf("Illegal TWEAK file size: %s\n", fpath);\r
+               return 0;\r
+               }\r
+       regs = fsize / sizeof(Register);\r
+\r
+    if (!(*array = (Register *)malloc(fsize)))\r
+               {\r
+               printf("Out of memory allocating buffer for %s\n", fpath);\r
+               return 0;\r
+               }\r
+       if (read(handle, (void*)*array, fsize) == -1)\r
+               /* error reading file */\r
+               goto fileerror;\r
+\r
+    if (close(handle) == -1)\r
+               {\r
+               /* error closing file */\r
+               goto fileerror;\r
+               }\r
+\r
+       /* file read ok, return pointer to buffer */\r
+       return regs;\r
+\r
+fileerror:\r
+       perror(fpath);\r
+       if (*array) free(*array);\r
+       return 0;\r
+       }\r
diff --git a/16/tweak16/TWKUSER.H b/16/tweak16/TWKUSER.H
new file mode 100755 (executable)
index 0000000..dfe79a8
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _TwkUser_h\r
+#define _TwkUser_h\r
+\r
+/*\r
+       xxxxADDR defines the base port number used to access VGA component xxxx,\r
+       and is defined for xxxx =\r
+               ATTRCON         -       Attribute Controller\r
+               MISC            -       Miscellaneous Register\r
+               VGAENABLE       -       VGA Enable Register\r
+               SEQ                     -       Sequencer\r
+               GRACON          -       Graphics Controller\r
+               CRTC            -       Cathode Ray Tube Controller\r
+               STATUS          -       Status Register\r
+*/\r
+\r
+#define ATTRCON_ADDR   0x3c0\r
+#define MISC_ADDR              0x3c2\r
+#define VGAENABLE_ADDR 0x3c3\r
+#define SEQ_ADDR               0x3c4\r
+#define GRACON_ADDR            0x3ce\r
+#define CRTC_ADDR              0x3d4\r
+#define STATUS_ADDR            0x3da\r
+\r
+\r
+/*\r
+       Note that the following C definition of Register is not compatible\r
+       with the C++ definition used in the source code of TWEAK itself!\r
+*/\r
+\r
+typedef struct\r
+       {\r
+       unsigned port;\r
+       unsigned char index;\r
+       unsigned char value;\r
+       } Register;\r
+\r
+typedef Register *RegisterPtr;\r
+\r
+void readyVgaRegs(void);\r
+void outRegArray(Register *r, int n);\r
+void outReg(Register r);\r
+int loadRegArray(char *fpath, RegisterPtr *array);\r
+\r
+#endif\r
+\r
diff --git a/16/tweak16/VGALIB.CPP b/16/tweak16/VGALIB.CPP
new file mode 100755 (executable)
index 0000000..eb65747
--- /dev/null
@@ -0,0 +1,386 @@
+#include <dos.h>\r
+#include <conio.h>\r
+#include <string.h>\r
+\r
+#include "misc.hpp"\r
+#include "screen.hpp"\r
+#include "vgalib.hpp"\r
+\r
+\r
+GraphicsAPI::GraphicsAPI(int xr, int yr, int vxr, int vyr, int clrs)\r
+       {\r
+       int segm, offs;\r
+       xres = xr;\r
+       yres = yr;\r
+       vxres = vxr;\r
+       vyres = vyr;\r
+       colors = clrs;\r
+       libID = "Generic Graphics";\r
+       asm     {\r
+               push    bp\r
+               mov             ax, 1130h\r
+               mov             bh, 03h\r
+               int             10h\r
+               mov             ax, bp\r
+               pop             bp\r
+               mov             [segm], es\r
+               mov             [offs], ax\r
+               }\r
+       font = (unsigned char *)MK_FP(segm, offs);\r
+       fontHeight = fontWidth = 8;\r
+       }\r
+\r
+void GraphicsAPI::hLine(int x, int y, int l)\r
+       {\r
+       while (l--)\r
+               putPixel(x++, y);\r
+       }\r
+\r
+void GraphicsAPI::vLine(int x, int y, int l)\r
+       {\r
+       while (l--)\r
+               putPixel(x, y++);\r
+       }\r
+\r
+/*\r
+ *     Generic line drawing routine, using Bresenham's algorithm.\r
+ *     Taken from Richard Wilton: "PC & PS/2 Video Systems" p. 166-7\r
+ */\r
+\r
+void GraphicsAPI::line(int x1, int y1, int x2, int y2)\r
+       {\r
+       if (x1==x2)\r
+               {\r
+               sort(y1, y2);\r
+               vLine(x1, y1, y2-y1+1);\r
+               return;\r
+               }\r
+       if (y1==y2)\r
+               {\r
+               sort(x1, x2);\r
+               hLine(x1, y1, x2-x1+1);\r
+               }\r
+       int dx = absolute(x2-x1);\r
+       int dy = absolute(y2-y1);\r
+       if (dx >= dy)\r
+               {\r
+               if (x1>x2)\r
+                       {\r
+                       swap(x1, x2);\r
+                       swap(y1, y2);\r
+                       }\r
+               int yincr = 1;\r
+               if (y2<y1)\r
+                       yincr = -yincr;\r
+               int d = 2 * dy - dx;\r
+               int aincr = 2 * (dy - dx);\r
+               int bincr = 2 * dy;\r
+               int x = x1;\r
+               int y = y1;\r
+               putPixel(x, y);\r
+               while (++x <= x2)\r
+                       {\r
+                       if (d >= 0)\r
+                               {\r
+                               y += yincr;\r
+                               d += aincr;\r
+                               }\r
+                       else\r
+                               d += bincr;\r
+                       putPixel(x, y);\r
+                       }\r
+               }\r
+       else\r
+               {\r
+               if (y1>y2)\r
+                       {\r
+                       swap(x1, x2);\r
+                       swap(y1, y2);\r
+                       }                           \r
+               int xincr = 1;\r
+               if (x2<x1)\r
+                       xincr = -xincr;\r
+               int d = 2*dx - dy;\r
+               int aincr = 2 * (dx - dy);\r
+               int bincr = 2 * dx;\r
+               int x = x1;\r
+               int y = y1;\r
+               putPixel(x, y);\r
+               while (++y <= y2)\r
+                       {\r
+                       if (d >= 0)\r
+                               {\r
+                               x += xincr;\r
+                               d += aincr;\r
+                               }\r
+                       else\r
+                               d += bincr;\r
+                       putPixel(x, y);\r
+                       }\r
+               }\r
+       }\r
+\r
+void GraphicsAPI::rectangle(int x1, int y1, int x2, int y2)\r
+       {\r
+       sort(x1, x2);\r
+       sort(y1, y2);\r
+       hLine(x1, y1, x2-x1);\r
+       hLine(x1, y2, x2-x1);\r
+       vLine(x1, y1, y2-y1);\r
+       vLine(x2, y1, y2-y1);\r
+       }\r
+\r
+void GraphicsAPI::bar(int x1, int y1, int x2, int y2)\r
+       {\r
+       int width = x2-x1+1;\r
+       for (int y = y1; y < y2; ++y)\r
+               hLine(x1, y, width);\r
+       }\r
+\r
+void GraphicsAPI::wipe()\r
+       {\r
+       bar(0, 0, vxres, vyres);\r
+       }\r
+\r
+void GraphicsAPI::putChar(int x, int y, int ch)\r
+       {\r
+       unsigned char *fptr = font + fontHeight*ch;\r
+       for (int j=0; j<fontHeight; ++j, ++fptr)\r
+               {\r
+               char mask = *fptr;\r
+               for (int i=0; i<fontWidth; ++i)\r
+                       {\r
+                       asm shl         [mask], 1;\r
+                       asm jnc         skip\r
+                               putPixel(x+i, y+j, color);\r
+                       skip:\r
+                       }\r
+               }\r
+       }\r
+\r
+void GraphicsAPI::putText(int x, int y, char *txt)\r
+       {\r
+       switch (hJustify)\r
+               {\r
+               case HCENTER:\r
+                       x -= fontWidth * strlen(txt) / 2;\r
+                       break;\r
+               case RIGHT:\r
+                       x -= fontWidth * strlen(txt);\r
+                       break;\r
+               }\r
+       switch (vJustify)\r
+               {\r
+               case VCENTER:\r
+                       y -= fontHeight / 2;\r
+                       break;\r
+               case BOTTOM:\r
+                       y -= fontHeight;\r
+                       break;\r
+               }\r
+\r
+       while (*txt)\r
+               {\r
+               putChar(x, y, *(txt++));\r
+               x += fontWidth;\r
+               }\r
+       }\r
+\r
+void GraphicsAPI::setTextJustify(HJustify h, VJustify v)\r
+       {\r
+       hJustify = h;\r
+       vJustify = v;\r
+       }\r
+\r
+\r
+/*\r
+ *     VGAGraphicsAPI\r
+ */\r
+\r
+unsigned char *VGAGraphicsAPI::videoBuf =\r
+       (unsigned char *)MK_FP(0xa000,0);\r
+\r
+VGAGraphicsAPI::VGAGraphicsAPI(int xr, int yr, int vxr, int xb, int clrs)\r
+       : GraphicsAPI(xr, yr, vxr, 65536L/xb, clrs), xbytes(xb)\r
+       {\r
+       libID = "VGA Graphics";\r
+       outp(0x3ce, 0x05);\r
+       int t = inp(0x3cf);\r
+       outpw(0x3ce, 0x05 | (t & 0xfc) << 8);   // write mode 0\r
+       outpw(0x3c4, 0x0f02);                                   // enable all planes\r
+       }\r
+\r
+\r
+void VGAGraphicsAPI::syncWithRefresh()\r
+       {\r
+       while (inp(0x3da)&0x8);\r
+       while (!(inp(0x3da)&0x8));\r
+       }\r
+\r
+unsigned VGAGraphicsAPI::getOffset(int x, int y)\r
+       {\r
+       return y * xbytes + x/(vxres/xbytes);\r
+       }\r
+\r
+void VGAGraphicsAPI::setBase(int x=0, int y=0)\r
+       {\r
+       unsigned offset = getOffset(x,y);\r
+       inp(0x3da);\r
+       outp(0x3c0, 0x33);\r
+       outp(0x3c0, getPelPan(x));\r
+       outpw(0x3d4, 0x0c | (offset & 0xff00));\r
+       outpw(0x3d4, 0x0d | (offset & 0x00ff)<<8);\r
+       syncWithRefresh();\r
+       }\r
+\r
+\r
+/*\r
+ *     Planar16\r
+ */\r
+\r
+Planar16::Planar16(int xr, int yr, int vxr)\r
+       : VGAGraphicsAPI(xr, yr, vxr, vxr>>3, 16)\r
+       {\r
+       libID = "4-plane 16-color mode";\r
+       outpw(0x3ce, 0x0f01);                                   // enable set/reset\r
+       }\r
+\r
+void Planar16::putPixel(int x, int y, int c)\r
+       {\r
+       outpw(0x3ce, 0x00 | (c<<8));            // set/reset to select color\r
+       outpw(0x3ce, 0x08 | 0x8000>>(x&7));     // bit mask to select bit\r
+       unsigned char *pos = graphScr+y*xbytes+(x>>3);\r
+       *pos = *pos;\r
+       }\r
+\r
+int Planar16::getPixel(int x, int y)\r
+       {\r
+       return videoBuf[y*xbytes+x];\r
+       }\r
+\r
+void Planar16::hLine(int x, int y, int l)\r
+       {\r
+       outpw(0x3ce, 0x00 | (color<<8));        // set/reset to select color\r
+       unsigned char *pos = graphScr+y*xbytes+(x>>3);\r
+       int mask;\r
+       int shift = x & 7;\r
+       if (shift > 0)\r
+               {\r
+               mask = 0x00ff >> shift;\r
+               l -= 8 - shift;\r
+               if (l<0)\r
+                       mask &= 0xff << -l;\r
+               outpw(0x3ce, 0x08 | mask << 8); // bit mask to select first bits\r
+               *pos = *pos;\r
+               ++pos;\r
+               }\r
+       if (l >= 8)\r
+               {\r
+               outpw(0x3ce, 0xff08);                   // bit mask to select 8 bits\r
+               memset(pos, 0, l>>3);\r
+               pos += l>>3;\r
+               l -= l & 0xf8;\r
+               }\r
+       if (l >= 0)\r
+               {\r
+               mask = 0xff00 << (8-l);\r
+               outpw(0x3ce, 0x08 | mask);              // bit mask to select last bits\r
+               *pos = *pos;\r
+               }\r
+       }\r
+\r
+int Planar16::getPelPan(int x)\r
+       {\r
+       return x & 7;\r
+       }\r
+\r
+/*\r
+ *     Chained256\r
+ */\r
+\r
+Chained256::Chained256(int xr, int yr, int vxr)\r
+       : VGAGraphicsAPI(xr, yr, vxr, vxr, 256)\r
+       {\r
+       libID = "Chained 256-color mode";\r
+       }\r
+\r
+void Chained256::putPixel(int x, int y, int c)\r
+       {\r
+       videoBuf[y*xbytes+x] = c;\r
+       }\r
+\r
+int Chained256::getPixel(int x, int y)\r
+       {\r
+       return videoBuf[y*xbytes+x];\r
+       }\r
+\r
+void Chained256::hLine(int x, int y, int l)\r
+       {\r
+       memset(graphScr+y*xbytes+x, color, l);\r
+       }\r
+\r
+unsigned Chained256::getOffset(int x, int y)\r
+       {\r
+       return (y * xbytes + x/(vxres/xbytes)) >> 2; \r
+       }\r
+\r
+int Chained256::getPelPan(int x)\r
+       {\r
+       return 2*(x & 3);\r
+       }\r
+\r
+\r
+/*\r
+ *     Unchained256\r
+ */\r
+\r
+Unchained256::Unchained256(int xr, int yr, int vxr)\r
+       : VGAGraphicsAPI(xr, yr, vxr, vxr>>2, 256)\r
+       {\r
+       libID = "Unchained 256-color mode";\r
+       }\r
+\r
+void Unchained256::putPixel(int x, int y, int c)\r
+       {\r
+       outpw(0x3c4, 0x02 | 0x0100<<(x&3));\r
+       videoBuf[y*xbytes+(x>>2)] = c;\r
+       }\r
+\r
+int Unchained256::getPixel(int x, int y)\r
+       {\r
+       return videoBuf[y*xbytes+x];\r
+       }\r
+\r
+void Unchained256::hLine(int x, int y, int l)\r
+       {\r
+       unsigned char *pos = graphScr+y*xbytes+(x>>2);\r
+       int mask;\r
+       int shift = x & 3;\r
+       if (shift > 0)\r
+               {\r
+               mask = 0x000f << shift & 0x000f;\r
+               l -= 4-shift;\r
+               if (l<0)\r
+                       mask &= 0x0f >> -l;\r
+               outpw(0x3c4, 0x02 | mask << 8); // write enable first pixels\r
+               *(pos++) = color;\r
+               }\r
+       if (l >= 4)\r
+               {\r
+               outpw(0x3c4, 0x0f02);                   // write enable 4 pixels\r
+               memset(pos, color, l>>2);\r
+               pos += l>>2;\r
+               l -= l & 0xfc;\r
+               }\r
+       if (l >= 0)\r
+               {\r
+               mask = 0x0f00 >> (4-l) & 0x0f00;\r
+               outpw(0x3c4, 0x02 | mask);              // write enable last pixels\r
+               *pos = color;\r
+               }\r
+       }\r
+\r
+int Unchained256::getPelPan(int x)\r
+       {\r
+       return 2*(x & 3);\r
+       }\r
diff --git a/16/tweak16/VGALIB.HPP b/16/tweak16/VGALIB.HPP
new file mode 100755 (executable)
index 0000000..9fb45a9
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef _VGALIB_HPP\r
+#define _VGALIB_HPP\r
+\r
+class GraphicsAPI;\r
+class VGAGraphicsAPI;\r
+class Chained256;\r
+class Unchained256;\r
+class Planar16;\r
+\r
+class GraphicsAPI\r
+       {\r
+       public:\r
+               enum HJustify   { LEFT, HCENTER, RIGHT };\r
+               enum VJustify   { TOP, VCENTER, BOTTOM };\r
+\r
+       protected:\r
+               int xres, yres, vxres, vyres, color, colors;\r
+               unsigned char *font, *libID;\r
+               int fontWidth, fontHeight;\r
+               HJustify hJustify;\r
+               VJustify vJustify;\r
+       public:\r
+               GraphicsAPI(int, int, int, int, int);\r
+               virtual ~GraphicsAPI()                          {}\r
+               virtual char *getLibID()                        { return libID; }\r
+               virtual int getWidth()                          { return xres; }\r
+               virtual int getHeight()                         { return yres; }\r
+               virtual int getVirtualWidth()           { return vxres; }\r
+               virtual int getVirtualHeight()          { return vyres; }\r
+               virtual long getPageSize()                      { return long(xres)*yres; }\r
+               virtual int getColors()                         { return colors; }\r
+               virtual void setColor(int c)            { color = c; }\r
+               virtual void setBase(int, int)          =0;\r
+               virtual void syncWithRefresh()          =0;\r
+               virtual int getColor()                          { return color; }\r
+               virtual void putPixel(int x, int y)     { putPixel(x, y, color); }\r
+               virtual void putPixel(int x, int y, int c) =0;\r
+               virtual int getPixel(int x, int y)      =0;\r
+               virtual void hLine(int, int, int);\r
+               virtual void vLine(int, int, int);\r
+               virtual void line(int, int, int, int);\r
+               virtual void rectangle(int, int, int, int);\r
+               virtual void bar(int, int, int, int);\r
+               virtual void wipe();\r
+               virtual void putChar(int, int, int);\r
+               virtual void putText(int, int, char*);\r
+               virtual void setTextJustify(HJustify, VJustify);\r
+       };\r
+\r
+class VGAGraphicsAPI : public GraphicsAPI\r
+       {\r
+       protected:\r
+               int xbytes;\r
+               static unsigned char *videoBuf;\r
+        virtual unsigned getOffset(int, int);\r
+               virtual int getPelPan(int) =0;\r
+       public:\r
+               VGAGraphicsAPI(int, int, int, int, int);\r
+               void syncWithRefresh();\r
+               void setBase(int, int);\r
+       };\r
+\r
+class Chained256 : public VGAGraphicsAPI\r
+       {\r
+       protected:\r
+               int getPelPan(int);\r
+               unsigned getOffset(int, int);\r
+       public:\r
+               Chained256(int, int, int);\r
+               void putPixel(int, int, int);\r
+               int getPixel(int, int);\r
+               virtual void hLine(int, int, int);\r
+       };\r
+\r
+class Unchained256 : public VGAGraphicsAPI\r
+       {\r
+       protected:\r
+               int getPelPan(int);\r
+       public:\r
+               Unchained256(int, int, int);\r
+               void putPixel(int, int, int);\r
+               int getPixel(int, int);\r
+               virtual void hLine(int, int, int);\r
+       };\r
+\r
+class Planar16 : public VGAGraphicsAPI\r
+       {\r
+       protected:\r
+               int getPelPan(int);\r
+       public:\r
+               Planar16(int, int, int);\r
+               void putPixel(int, int, int);\r
+               int getPixel(int, int);\r
+               void hLine(int, int, int);\r
+       };\r
+\r
+#endif
\ No newline at end of file
diff --git a/16/tweak16/XINTRO/LIB.EXE b/16/tweak16/XINTRO/LIB.EXE
new file mode 100755 (executable)
index 0000000..b9dd016
Binary files /dev/null and b/16/tweak16/XINTRO/LIB.EXE differ
diff --git a/16/tweak16/XINTRO/LIB.SMP b/16/tweak16/XINTRO/LIB.SMP
new file mode 100755 (executable)
index 0000000..4923a46
Binary files /dev/null and b/16/tweak16/XINTRO/LIB.SMP differ
diff --git a/16/tweak16/XINTRO/M13ORG.ASC b/16/tweak16/XINTRO/M13ORG.ASC
new file mode 100755 (executable)
index 0000000..906ec42
--- /dev/null
@@ -0,0 +1,55 @@
+Figure 1: Memory organization in mode 13h (ASCII version)\r
+         by Robert Schmidt\r
+          (C) 1993 Ztiff Zox Softwear\r
+\r
+a. Imagine that the top of the screen looks like this (pixel values are\r
+   represented by color digits 0-9 for simplicity - actual colors may\r
+   range from 0 to 255) - a screen width of 320 pixels is assumed:\r
+\r
+    address:  0         10                310      319\r
+             ----------------------------------------\r
+             |0123456789012345    .....   0123456789|\r
+             |                                      |\r
+             |                                      |\r
+             |\r
+\r
+b. In VGA memory, the screen is represented as follows (question marks\r
+   represent unused bytes):\r
+\r
+   Plane 0:\r
+\r
+    address:  0         10                310      319\r
+             ----------------------------------------\r
+             |0???4???8???2???    .....   ??2???6???|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   Plane 1:\r
+\r
+    address:  0         10                310      319\r
+             ----------------------------------------\r
+             |?1???5???9???3??    .....   ???3???7??|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   Plane 2:\r
+\r
+    address:  0         10                310      319\r
+             ----------------------------------------\r
+             |??2???6???0???4?    .....   0???4???8?|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   Plane 3:\r
+\r
+    address:  0         10                310      319\r
+             ----------------------------------------\r
+             |???3???7???1???5    .....   ?1???5???9|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   I.e. a plane is selected automatically by the two least significant\r
+   bits of the address of the byte being read from or written two.\r
+   This renders 3/4 of the video memory unavailable and useless, but\r
+   all visible pixels are easily accessed, as each address in the video\r
+   segment provides access to one and ONLY ONE pixel.\r
diff --git a/16/tweak16/XINTRO/M13ORG.GIF b/16/tweak16/XINTRO/M13ORG.GIF
new file mode 100755 (executable)
index 0000000..1fb4fc4
Binary files /dev/null and b/16/tweak16/XINTRO/M13ORG.GIF differ
diff --git a/16/tweak16/XINTRO/MXORG.ASC b/16/tweak16/XINTRO/MXORG.ASC
new file mode 100755 (executable)
index 0000000..295766b
--- /dev/null
@@ -0,0 +1,49 @@
+Figure 2: Memory organization in unchained 256-color modes (like\r
+          Mode X) (ASCII version)\r
+         by Robert Schmidt\r
+          (C) 1993 Ztiff Zox Softwear\r
+\r
+\r
+Imagine that the screen looks the same as in figure 1a.  A screen width\r
+of 320 pixels is still assumed.\r
+\r
+In VGA memory, the screen will be represented as follows:\r
+\r
+   Plane 0:\r
+\r
+    address:  0         10                70       79 (NOT 319!)\r
+             ----------------------------------------\r
+             |0482604826048260    .....   0482604826|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   Plane 1:\r
+\r
+    address:  0         10                70       79\r
+             ----------------------------------------\r
+             |1593715937159371    .....   1593715937|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   Plane 2:\r
+\r
+    address:  0         10                70       79\r
+             ----------------------------------------\r
+             |2604826048260482    .....   2604826048|\r
+             |                                      |\r
+             |                                      |\r
+\r
+   Plane 3:\r
+\r
+    address:  0         10                70       79\r
+             ----------------------------------------\r
+             |3715937159371593    .....   3715937159|\r
+             |                                      |\r
+             |                                      |\r
+\r
+Note that if pixel i is in plane p, pixel i+1 is in plane (p+1)%4.\r
+When the planes are unchained, we need to set the Write Plane Enable\r
+register to select which planes should receive the data when writing,\r
+or the Read Plane Select register when reading.  As is evident, one \r
+address in the video segment provides access to no less than FOUR\r
+different pixels.\r
diff --git a/16/tweak16/XINTRO/MXORG.GIF b/16/tweak16/XINTRO/MXORG.GIF
new file mode 100755 (executable)
index 0000000..31c0ac5
Binary files /dev/null and b/16/tweak16/XINTRO/MXORG.GIF differ
diff --git a/16/tweak16/XINTRO/RUN.BAT b/16/tweak16/XINTRO/RUN.BAT
new file mode 100755 (executable)
index 0000000..9c31c1f
--- /dev/null
@@ -0,0 +1,3 @@
+wsample lib.exe\r
+setres 80 50\r
+wprof lib.smp\r
diff --git a/16/tweak16/XINTRO/XINTRO.TXT b/16/tweak16/XINTRO/XINTRO.TXT
new file mode 100755 (executable)
index 0000000..0ac0585
--- /dev/null
@@ -0,0 +1,569 @@
+Title:         INTRODUCTION TO MODE X (XINTRO.TXT)\r
+\r
+Version:        1.8\r
+\r
+Author:                Robert Schmidt <robert@stud.unit.no>\r
+\r
+Copyright:     (C) 1993 of Ztiff Zox Softwear - refer to Status below.\r
+\r
+Last revision:  25-Nov-93\r
+\r
+Figures:       1. M13ORG - memory organization in mode 13h\r
+               2. MXORG - memory organization in unchained modes\r
+\r
+               The figures are available both as 640x480x16 bitmaps\r
+               (in GIF format), and as 7-bit ASCII text (ASC) files.\r
+\r
+C sources:     1. LIB.C v1.2 - simple graphics library for planar,\r
+                   256-color modes - optionally self-testing.\r
+\r
+                Excerpts from the source(s) appear in this article.\r
+                Whenever there are conflicts, the external source file(s)\r
+               are correct (or, at least, newest), _not_ the excerpts\r
+               provided here.\r
+\r
+Status:                This article, its associated figures and source listings\r
+               named above, are all donated to the public domain.\r
+               Do with it whatever you like, but give credit where\r
+               credit is due.  I would prefer it if this archive was\r
+               distributed in its entirety, including the files\r
+               mentioned above.\r
+\r
+               The standard disclaimer applies.\r
+\r
+Index:         0. ABSTRACT\r
+               1. INTRODUCTION TO THE VGA AND ITS 256-COLOR MODE\r
+               2. GETTING MORE PAGES AND PUTTING YOUR FIRST PIXEL\r
+               3. THE ROAD FROM HERE\r
+               4. BOOKS ON THE SUBJECT\r
+                5. BYE - FOR NOW\r
+\r
+\r
+0. ABSTRACT\r
+\r
+This text gives a fairly basic, yet technical, explanation to what, why\r
+and how Mode X is.  It first tries to explain the layout of the VGA\r
+memory and the shortcomings of the standard 320x200 256-color mode,\r
+then gives instructions on how one can progress from mode 13h to a\r
+multipage, planar 320x200 256-color mode, and from there to the\r
+quasi-standard 320x240 mode, known as Mode X.\r
+\r
+A little experience in programming the standard VGA mode 13h\r
+(320x200 in 256 colors) is assumed.  Likewise a good understanding of\r
+hexadecimal notation and the concepts of segments and I/O ports is\r
+assumed.  Keep a VGA reference handy, which at least should have\r
+definitions of the VGA registers at bit level.\r
+\r
+Throughout the article, a simple graphics library for unchained (planar)\r
+256-color modes is developed.  The library supports the 320x200 and\r
+320x240 modes, active and visible pages, and writing and reading\r
+individual pixels.\r
+\r
+\r
+1. INTRODUCTION TO THE VGA AND ITS 256-COLOR MODE\r
+\r
+Since its first appearance on the motherboards of the IBM PS/2 50, 60\r
+and 80 models in 1987, the Video Graphics Array has been the de facto\r
+standard piece of graphics hardware for IBM and compatible personal\r
+computers.  The abbreviation, VGA, was to most people synonymous with\r
+acceptable resolution (640x480 pixels), and a stunning rainbow of colors\r
+(256 from a palette of 262,144), at least compared to the rather gory\r
+CGA and EGA cards.\r
+\r
+Sadly, to use 256 colors, the VGA BIOS limited the users to 320x200\r
+pixels, i.e. the well-known mode 13h.  This mode has one good and one\r
+bad asset.  The good one is that each one of the 64,000 pixels is easily\r
+addressable in the 64 Kb video memory segment at 0A000h.  Simply calculate\r
+the offset using this formula:\r
+\r
+offset = (y * 320) + x;\r
+\r
+Set the byte at this address (0A000h:offset) to the color you want, and\r
+the pixel is there.  Reading a pixel is just as simple: just read the\r
+corresponding byte.  This was heaven, compared to the havoc of planes and\r
+masking registers needed in 16-color modes.  Suddenly, the distance from a\r
+graphics algorithm on paper to an implemented graphics routine in assembly\r
+was cut down to a fraction.  The results were impressively fast, too!\r
+\r
+The bad asset is that mode 13h is also limited to only one page, i.e.\r
+the VGA can hold only one screenful at any one time (plus 1536 pixels, or\r
+about four lines).  Most 16-color modes let the VGA hold more than one page,\r
+and this enables you to show one of the pages to the user, while drawing on\r
+another page in the meantime.  Page flipping is an important concept in making\r
+flicker free animations.  Nice looking and smooth scrolling is also almost\r
+impossible in mode 13h using plain VGA hardware.\r
+\r
+Now, the alert reader might say: "Hold on a minute!  If mode 13h enables\r
+only one page, this means that there is memory for only one page.  But I\r
+know for a fact that all VGAs have at least 256 Kb RAM, and one 320x200\r
+256-color page should consume only 320*200=64000 bytes, which is less\r
+than 64 Kb.  A standard VGA should room a little more than four 320x200\r
+pages!"  Quite correct, and to see how the BIOS puts this limitation on\r
+mode 13h, I'll elaborate a little on the memory organization of the VGA.\r
+\r
+The memory is separated into four bit planes.  The reason for this stems\r
+from the EGA, where graphics modes were 16-color.  Using bit planes, the\r
+designers chose to let each pixel on screen be addressable by a single\r
+bit in a single byte in the video segment.  Assuming the palette has\r
+not been modified from the default, each plane represent one of the EGA\r
+primary colors: red, green, blue and intensity.  When modifying the bit\r
+representing a pixel, the Write Plane Enable register is set to the\r
+wanted color.  Reading is more complex and slower, since you can\r
+only read from a single plane at a time, by setting the Read Plane\r
+Select register.  Now, since each address in the video segment can\r
+access 8 pixels, and there are 64 Kb addresses, 8 * 65,536 = 524,288\r
+16-color pixels can be accessed.  In a 320x200 16-color mode, this makes\r
+for about 8 (524,288/(320*200)) pages, in 640x480 you get nearly 2\r
+(524,288/(640*480)) pages.\r
+\r
+In a 256-color mode, the picture changes subtly.  The designers decided\r
+to fix the number of bit planes to 4, so extending the logic above to 8\r
+planes and 256 colors does not work.  Instead, one of their goals was to\r
+make the 256-color mode as easily accessible as possible.  Comparing the\r
+8 pixels/address in 16-color modes to the 1-to-1 correspondence of\r
+pixels and addresses of mode 13h, one can say that they have\r
+succeeded, but at a certain cost.  For reasons I am not aware of, the\r
+designers came up with the following effective, but memory-wasting\r
+scheme:\r
+\r
+The address space of mode 13h is divided evenly across the four bit\r
+planes.  When an 8-bit color value is written to a 16-bit address in the\r
+VGA segment, a bit plane is automatically selected by the 2 least\r
+significant bits of the address.  Then all 8 bits of the data is written\r
+to the byte at the 16-bit address in the selected bitplane (have a look at\r
+figure 1).  Reading works exactly the same way.  Since the bit planes are so\r
+closely tied to the address, only every fourth byte in the video memory is\r
+accessible, and 192 Kb of a 256 Kb VGA go to waste.  Eliminating the\r
+need to bother about planes sure is convenient and beneficial, but to\r
+most people the loss of 3/4 of the total VGA memory sounds just hilarious.\r
+\r
+To accomodate this new method of accessing video memory, the VGA\r
+designers introduced a new configuration bit called Chain-4, which\r
+resides as bit number 3 in index 4 of the Sequencer.  In 16-color modes,\r
+the default state for this bit is off (zero), and the VGA operates as\r
+described earlier.  In the VGA's standard 256-color mode, mode 13h, this\r
+bit is turned on (set to one), and this turns the tieing of bit\r
+planes and memory address on.\r
+\r
+In this state, the bit planes are said to be chained together, thus mode\r
+13h is often called a _chained mode_.\r
+\r
+Note that Chain-4 in itself is not enough to set a 256-color mode -\r
+there are other registers which deals with the other subtle changes in\r
+nature from 16 to 256 colors.  But, as we now will base our work with\r
+mode X on mode 13h, which already is 256-color, we won't bother about\r
+these for now.\r
+\r
+\r
+\r
+2. GETTING MORE PAGES AND PUTTING YOUR FIRST PIXEL\r
+\r
+The observant reader might at this time suggest that clearing the\r
+Chain-4 bit after setting mode 13h will give us access to all 256 Kb of\r
+video memory, as the two least significant bits of the byte address\r
+won't be `wasted' on selecting a bit plane.  This is correct.  You might\r
+also start feeling a little uneasy, because something tells you that\r
+you'll instantly loose the simple addressing scheme of mode 13h.  Sadly,\r
+that is also correct.\r
+\r
+At the moment Chain-4 is cleared, each byte offset addresses *four*\r
+sequential pixels, corresponding to the four planes addressed in 16-color\r
+modes.  Every fourth pixel belong in the same plane.  Before writing to a byte\r
+offset in the video segment, you should make sure that the 4-bit mask in the\r
+Write Plane Enable register is set correctly, according to which of the four\r
+addressable pixels you want to modify.  In essence, it works like a 16-color\r
+mode with a twist.  See figure 2.\r
+\r
+So, is this mode X?  Not quite.  We need to elaborate to the VGA how to\r
+fetch data for refreshing the monitor image.  Explaining the logic\r
+behind this is beyond the scope of this getting-you-started text, and it\r
+wouldn't be very interesting anyway.  Also, mode 13h has only 200 lines,\r
+while I promised 240 lines.  I'll fix that later below.  Here is the minimum\r
+snippet of code to initiate the 4 page variant of mode 13h (320x200), written\r
+in plain C, using some DOS specific features (see header for a note about the\r
+sources included):\r
+\r
+----8<-------cut begin------\r
+\r
+/* width and height should specify the mode dimensions.  widthBytes\r
+   specify the width of a line in addressable bytes. */\r
+\r
+int width, height, widthBytes;\r
+\r
+/* actStart specifies the start of the page being accessed by\r
+   drawing operations.  visStart specifies the contents of the Screen\r
+   Start register, i.e. the start of the visible page */\r
+\r
+unsigned actStart, visStart;\r
+\r
+/*\r
+ * set320x200x256_X()\r
+ *     sets mode 13h, then turns it into an unchained (planar), 4-page\r
+ *     320x200x256 mode.\r
+ */\r
+\r
+set320x200x256_X()\r
+       {\r
+\r
+       union REGS r;\r
+\r
+       /* Set VGA BIOS mode 13h: */\r
+\r
+       r.x.ax = 0x0013;\r
+       int86(0x10, &r, &r);\r
+\r
+       /* Turn off the Chain-4 bit (bit 3 at index 4, port 0x3c4): */\r
+\r
+       outport(SEQU_ADDR, 0x0604);\r
+\r
+       /* Turn off word mode, by setting the Mode Control register\r
+          of the CRT Controller (index 0x17, port 0x3d4): */\r
+\r
+       outport(CRTC_ADDR, 0xE317);\r
+\r
+       /* Turn off doubleword mode, by setting the Underline Location\r
+          register (index 0x14, port 0x3d4): */\r
+\r
+       outport(CRTC_ADDR, 0x0014);\r
+\r
+       /* Clear entire video memory, by selecting all four planes, then\r
+          writing 0 to the entire segment. */\r
+\r
+       outport(SEQU_ADDR, 0x0F02);\r
+       memset(vga+1, 0, 0xffff); /* stupid size_t exactly 1 too small */\r
+       vga[0] = 0;\r
+\r
+       /* Update the global variables to reflect the dimensions of this\r
+          mode.  This is needed by most future drawing operations. */\r
+\r
+        width   = 320;\r
+       height  = 200;\r
+\r
+        /* Each byte addresses four pixels, so the width of a scan line\r
+           in *bytes* is one fourth of the number of pixels on a line. */\r
+\r
+        widthBytes = width / 4;\r
+\r
+        /* By default we want screen refreshing and drawing operations\r
+           to be based at offset 0 in the video segment. */\r
+\r
+       actStart = visStart = 0;\r
+\r
+       }\r
+\r
+----8<-------cut end------\r
+\r
+As you can see, I've already provided some of the mechanics needed to\r
+support multiple pages, by providing the actStart and visStart variables.\r
+Selecting pages can be done in one of two contexts:\r
+\r
+       1) selecting the visible page, i.e. which page is visible on\r
+          screen, and\r
+\r
+       2) selecting the active page, i.e. which page is accessed by\r
+          drawing operations\r
+\r
+Selecting the active page is just a matter of offsetting our graphics\r
+operations by the address of the start of the page, as demonstrated in\r
+the put pixel routine below.  Selecting the visual page must be passed\r
+in to the VGA, by setting the Screen Start register.  Sadly enough, the\r
+resolution of this register is limited to one addressable byte, which\r
+means four pixels in unchained 256-color modes.  Some further trickery is \r
+needed for 1-pixel smooth, horizontal scrolling, but I'll make that a subject \r
+for later.  The setXXXStart() functions provided here accept byte\r
+offsets as parameters, so they'll work in any mode.  If widthBytes and\r
+height are set correctly, so will the setXXXPage() functions.\r
+\r
+----8<-------cut begin------\r
+\r
+/*\r
+ * setActiveStart() tells our graphics operations which address in video\r
+ * memory should be considered the top left corner.\r
+ */\r
+\r
+setActiveStart(unsigned offset)\r
+       {\r
+       actStart = offset;\r
+       }\r
+\r
+/*\r
+ * setVisibleStart() tells the VGA from which byte to fetch the first\r
+ * pixel when starting refresh at the top of the screen.  This version\r
+ * won't look very well in time critical situations (games for\r
+ * instance) as the register outputs are not synchronized with the\r
+ * screen refresh.  This refresh might start when the high byte is\r
+ * set, but before the low byte is set, which produces a bad flicker.\r
+ * I won't bother with this now.\r
+ */\r
+\r
+setVisibleStart(unsigned offset)\r
+       {\r
+       visStart = offset;\r
+       outport(CRTC_ADDR, 0x0C);               /* set high byte */\r
+       outport(CRTC_ADDR+1, visStart >> 8);\r
+       outport(CRTC_ADDR, 0x0D);               /* set low byte */\r
+       outport(CRTC_ADDR+1, visStart & 0xff);\r
+       }\r
+\r
+/*\r
+ * setXXXPage() sets the specified page by multiplying the page number\r
+ * with the size of one page at the current resolution, then handing the\r
+ * resulting offset value over to the corresponding setXXXStart()\r
+ * function.  The first page number is 0.\r
+ */\r
+\r
+setActivePage(int page)\r
+       {\r
+       setActiveStart(page * widthBytes * height);\r
+       }\r
+\r
+setVisiblePage(int page)\r
+       {\r
+       setVisibleStart(page * widthBytes * height);\r
+       }\r
+\r
+----8<-------cut end------\r
+\r
+Due to the use of bit planes, the graphics routines tend to get more\r
+complex than in mode 13h, and your first versions will generally tend to\r
+be a little slower than mode 13h algorithms.  Here's a put pixel routine\r
+for any unchained 256-color mode (it assumes that the 'width' variable\r
+from the above code is set correctly).  Optimizing is left as an exercise\r
+to you, the reader.  This will be the only drawing operation I'll cover\r
+in this article, but all general primitives like lines and circles can be \r
+based on this routine.  (You'll probably not want to do that though, due\r
+to the inefficiency.)\r
+\r
+----8<-------cut begin------\r
+\r
+putPixel_X(int x, int y, char color)\r
+       {\r
+\r
+       /* Each address accesses four neighboring pixels, so set\r
+          Write Plane Enable according to which pixel we want\r
+          to modify.  The plane is determined by the two least\r
+          significant bits of the x-coordinate: */\r
+\r
+       outportb(0x3c4, 0x02);\r
+       outportb(0x3c5, 0x01 << (x & 3));\r
+\r
+       /* The offset of the pixel into the video segment is\r
+          offset = (width * y + x) / 4, and write the given\r
+          color to the plane we selected above.  Heed the active\r
+          page start selection. */\r
+\r
+       vga[(unsigned)(widthBytes * y) + (x / 4) + actStart] = color;\r
+\r
+       }\r
+\r
+char getPixel_X(int x, int y)\r
+       {\r
+\r
+       /* Select the plane from which we must read the pixel color: */\r
+\r
+       outport(GRAC_ADDR, 0x04);\r
+       outport(GRAC_ADDR+1, x & 3);\r
+\r
+       return vga[(unsigned)(widthBytes * y) + (x / 4) + actStart];\r
+\r
+       }\r
+\r
+----8<-------cut end------\r
+\r
+\r
+However, by now you should be aware of that the Write Plane Enable\r
+register isn't limited to selecting just one bit plane, like the\r
+Read Plane Select register is.  You can enable any combination of all\r
+four to be written.  This ability to access 4 pixels with one\r
+instruction helps quadrupling the speed in certain respects, especially when \r
+drawing horizontal lines and filling polygons of a constant color.  Also, most \r
+block algorithms can be optimized in various ways so that they need only\r
+a constant number of OUTs (typically four) to the Write Plane Enable\r
+register.  OUT is a relatively slow instruction.\r
+\r
+The gained ability to access the full 256 Kb of memory on a standard\r
+VGA enables you to do paging and all the goodies following from that:\r
+smooth scrolling over large maps, page flipping for flicker free\r
+animation... and I'll leave something for your own imagination.\r
+\r
+In short, the stuff gained from unchaining mode 13h more than \r
+upweighs the additional complexity of using a planar mode.  \r
+\r
+Now, the resolution of the mode is of little interest in this\r
+context.  Nearly any 256-color resolution from (about) 80x8 to 400x300\r
+is available for most VGAs.  I'll dwell particularly by 320x240, as this\r
+is the mode that Michael Abrash introduced as 'Mode X' in his DDJ\r
+articles.  It is also the resolution that most people refer to when\r
+using that phrase.\r
+\r
+The good thing about the 320x240 mode is that the aspect ratio is\r
+1:1, which means that each pixel is 'perfectly' square, i.e. not\r
+rectangular like in 320x200.  An ellipse drawn with the same number of\r
+pixels along both main axes will look like a perfect circle in 320x240,\r
+but like a subtly tall ellipse in 320x200.\r
+\r
+Here's a function which sets the 320x240 mode.  You'll notice that\r
+it depends on the first piece of code above:\r
+\r
+----8<-------cut begin------\r
+\r
+set320x240x256_X()\r
+       {\r
+\r
+       /* Set the unchained version of mode 13h: */\r
+\r
+       set320x200x256_X();\r
+\r
+       /* Modify the vertical sync polarity bits in the Misc. Output\r
+          Register to achieve square aspect ratio: */\r
+\r
+       outportb(0x3C2, 0xE3);\r
+\r
+       /* Modify the vertical timing registers to reflect the increased\r
+          vertical resolution, and to center the image as good as\r
+          possible: */\r
+\r
+       outport(0x3D4, 0x2C11);         /* turn off write protect */\r
+       outport(0x3D4, 0x0D06);         /* vertical total */\r
+       outport(0x3D4, 0x3E07);         /* overflow register */\r
+       outport(0x3D4, 0xEA10);         /* vertical retrace start */\r
+       outport(0x3D4, 0xAC11);         /* vertical retrace end AND wr.prot */\r
+       outport(0x3D4, 0xDF12);         /* vertical display enable end */\r
+       outport(0x3D4, 0xE715);         /* start vertical blanking */\r
+       outport(0x3D4, 0x0616);         /* end vertical blanking */\r
+\r
+       /* Update mode info, so future operations are aware of the\r
+          resolution: */\r
+\r
+       height = 240;\r
+\r
+       }\r
+\r
+----8<-------cut end------\r
+\r
+\r
+As you've figured out, this mode will be completely compatible with the\r
+utility functions presented earlier, thanks to the global variable\r
+'height'.  Boy, am I foreseeing or what!\r
+\r
+Other resolutions are achieved through giving other values to the sync\r
+timing registers of the VGA, but this is quite a large and complex\r
+subject, so I'll postpone this to later, if ever.\r
+\r
+Anyway, I hope I've helped getting you started using mode X.  As far as\r
+I know, the two modes I've used above should work on *any* VGA and Super\r
+VGA available, so this is pretty stable stuff.  Let me know of any \r
+trouble, and - \r
+                       good luck!\r
+\r
+\r
+\r
+3. THE ROAD FROM HERE\r
+\r
+I'm providing information on various libraries and archives which relate\r
+to what this article deals with.  If you want me to add anything to this\r
+list (for future articles), let me know, although I can't promise anything.\r
+I am assuming you have ftp access.\r
+\r
+\r
+wuarchive.wustl.edu:/pub/MSDOS_UPLOADS/programming/xlib06.zip\r
+\r
+This is the current de facto C/assembler library for programming\r
+unchained modes (do not confuse with a X Windows library).  All sources\r
+are included, and the library is totally free.  It has functions for\r
+pixels, lines, circles, bezier curves, mouse handling, sprites (bitmaps),\r
+compiled bitmaps, and supports a number of resolutions.  The version number\r
+('06') is current as of November 1993.\r
+\r
+\r
+graphprg.zip\r
+\r
+Michael Abrash' articles in Doctor Dobbs Journal is always mentioned\r
+with awe.  In this 350 Kb archive, most of his interesting stuff has\r
+been gathered.  Read about Mode X development and techniques from month\r
+to month.  Included is also all the individual source code snippets from\r
+each article, and also the full XSHARP library providing linedrawing,\r
+polygons, bitmaps, solid 3D projection and speedy rendering, and even an\r
+implementation of 2D texture mapping (can be used for quasi-3D texture\r
+mapping), plus an article on assembly optimization on the i86 processor\r
+family.  Definitely recommended.\r
+\r
+\r
+oak.oakland.edu:/pub/msdos/vga/vgadoc2.zip\r
+\r
+This is a bare bones VGA register reference.  It also contains register\r
+references for the CGA, EGA and Hercules cards, in addition to dozens of\r
+SuperVGAs.  Check out the BOOKS section for some decent VGA references\r
+though - you don't want to start tweaking without a real one.\r
+\r
+\r
+wuarchive.wustl.edu:/pub/MSDOS_UPLOADS/programming/tweak15b.zip\r
+\r
+TWEAK might be of interest to the more adventurous reader.  TWEAK lets you\r
+play around with the registers of the VGA in an interactive manner.\r
+Various testing screens for viewing your newmade modes are applied at\r
+the press of a key.  Version 1.5 adds a test screen which autodetects your \r
+graphics mode and displays various information about resolutions etc.\r
+Keep a VGA reference handy.  Don't try it if this is the first time you've \r
+heard of 'registers' or 'mode X' or 'tweaking'.  I was planning a version\r
+based on the Turbo Vision interface, but time has been short.  Maybe later!\r
+\r
+\r
+\r
+\r
+4. BOOKS ON THE SUBJECT\r
+\r
+Extremely little has been published in written form about using\r
+'Mode X'-style modes.  Below are some books which cover VGA programming\r
+at varying degrees of technical level, but the only one to mention\r
+unchained modes and Mode X, is Michael Abrash'.  I'd get one of the VGA\r
+references first, though.\r
+\r
+  o  George Sutty & Steve Blair : "Advanced Pogrammer's Guide to the\r
+     EGA/VGA" from Brady.  A bit old perhaps, but covers all *standard*\r
+     EGA/VGA registers, and discusses most BIOS functions and other\r
+     operations.  Contains disk with C/Pascal/assembler source code.\r
+     There's a sequel out for SuperVGAs, which I haven't seen.\r
+\r
+  o  Michael Abrash : "Power Graphics Programming" from QUE/Programmer's\r
+     Journal.  Collections of (old) articles from Programmer's Journal on\r
+     EGA/VGA, read modes and write modes, animation, tweaking (320x400\r
+     and 360x480).  His newer ravings in DDJ covers fast 256-color\r
+     bitmaps, compiled bitmaps, polygons, 3D graphics, texture mapping\r
+     among other stuff.\r
+\r
+  o  Richard F. Ferraro : "Programmer's Guide to the EGA and VGA video\r
+     cards including Super VGA".  I don't have this one, but heard it's\r
+     nice.  Detailed coverage of all EGA/VGA registers.  The Super VGA\r
+     reference makes it attractive.\r
+\r
+  o  Richard Wilton : "Programmer's Guide to PC & PS/2 Video Systems"\r
+     Less technical, more application/algorithm oriented.  Nice enough,\r
+     even though it is a bit outdated, in that he discusses CGA and\r
+     Hercules cards just as much as EGA/VGA.\r
+\r
+\r
+\r
+\r
+5. BYE - FOR NOW\r
+\r
+I am considering writing a text describing in more detail the process of\r
+using TWEAK to achieve the VGA resolution you want or need.  However, I\r
+thought I'd let this document go first, and see if I get any reactions.\r
+If I don't, I'll stop.  Feel free to forward any suggestions,\r
+criticisms, bombs and beers.\r
+\r
+I can be reached via:\r
+\r
+  o  e-mail: robert@stud.unit.no\r
+\r
+  o  land mail:\r
+\r
+     Robert Schmidt\r
+     Stud.post 170\r
+     NTH\r
+     N-7034 Trondheim\r
+     NORWAY\r
+\r
+Nothing would encourage or please me more than a postcard from where you\r
+live!\r
diff --git a/16/tweak16/XINTRO/XINTRO.zip b/16/tweak16/XINTRO/XINTRO.zip
new file mode 100755 (executable)
index 0000000..a314667
Binary files /dev/null and b/16/tweak16/XINTRO/XINTRO.zip differ
diff --git a/16/tweak16/XINTRO/lib.c b/16/tweak16/XINTRO/lib.c
new file mode 100755 (executable)
index 0000000..ac261a0
--- /dev/null
@@ -0,0 +1,352 @@
+/*\r
+ * LIB.C v1.2a\r
+ *\r
+ * by Robert Schmidt\r
+ * (C)1993 Ztiff Zox Softwear\r
+ *\r
+ * Simple graphics library to accompany the article\r
+ * \r
+ *                     INTRODUCTION TO MODE X.\r
+ * \r
+ * This library provides the basic functions for initializing and using\r
+ * unchained (planar) 256-color VGA modes.  Currently supported are:\r
+ *\r
+ *     - 320x200\r
+ *     - 320x240\r
+ *\r
+ * Functions are provided for:\r
+ *\r
+ *     - initializing one of the available modes\r
+ *     - setting the start address of the VGA refresh data\r
+ *     - setting active and visible display pages\r
+ *     - writing and reading a single pixel to/from video memory\r
+ *\r
+ * The library is provided as a demonstration only, and is not claimed\r
+ * to be particularly efficient or suited for any purpose.  It has only\r
+ * been tested with Borland C++ 3.1 by the author.  Comments on success\r
+ * or disaster with other compilers are welcome.\r
+ *\r
+ * This file is public domain.  Do with it whatever you'd like, but\r
+ * please don't distribute it without the article.\r
+ *\r
+ * Thanks go out to various helpful netters who spotted the 0xE7 bug\r
+ * in the set320x240x256() function!\r
+ *\r
+ * modified by sparky4 so it can be compiled in open watcom ^^\r
+ */\r
+\r
+\r
+/*\r
+ * We 'require' a large data model simply to get rid of explicit 'far'\r
+ * pointers and compiler specific '_fmemset()' functions and the likes.\r
+ */\r
+\r
+#if !defined(__COMPACT__)\r
+# if !defined(__LARGE__)\r
+#  if !defined(__HUGE__)\r
+#   error Large data model required!  Try compiling with 'bcc -ml lib.c'.\r
+#  endif\r
+# endif\r
+#endif\r
+\r
+#include <dos.h>\r
+#include <mem.h>\r
+#include <conio.h>\r
+\r
+/*\r
+ * Comment out the following #define if you don't want the testing main()\r
+ * to be included.\r
+ */\r
+\r
+#define TESTING\r
+\r
+/*\r
+ * Define the port addresses of some VGA registers.\r
+ */\r
+\r
+#define CRTC_ADDR      0x3d4   /* Base port of the CRT Controller (color) */\r
+\r
+#define SEQU_ADDR      0x3c4   /* Base port of the Sequencer */\r
+#define GRAC_ADDR      0x3ce   /* Base port of the Graphics Controller */\r
+\r
+\r
+/*\r
+ * Make a far pointer to the VGA graphics buffer segment.  Your compiler\r
+ * might not have the MK_FP macro, but you'll figure something out.\r
+ */\r
+\r
+typedef unsigned char UCHAR;\r
+UCHAR *vga = (UCHAR *) MK_FP(0xA000, 0);\r
+\r
+/*\r
+ * width and height should specify the mode dimensions.  widthBytes\r
+ * specify the width of a line in addressable bytes.\r
+ */\r
+\r
+unsigned width, height, widthBytes;\r
+\r
+/*\r
+ * actStart specifies the start of the page being accessed by\r
+ * drawing operations.  visStart specifies the contents of the Screen\r
+ * Start register, i.e. the start of the visible page.\r
+ */\r
+\r
+unsigned actStart, visStart;\r
+\r
+/*\r
+ * set320x200x256_X()\r
+ *     sets mode 13h, then turns it into an unchained (planar), 4-page\r
+ *     320x200x256 mode.\r
+ */\r
+\r
+void set320x200x256_X(void)\r
+       {\r
+\r
+       union REGS r;\r
+\r
+       /* Set VGA BIOS mode 13h: */\r
+\r
+       r.x.ax = 0x0013;\r
+       int86(0x10, &r, &r);\r
+\r
+       /* Turn off the Chain-4 bit (bit 3 at index 4, port 0x3c4): */\r
+\r
+       outpw(SEQU_ADDR, 0x0604);\r
+\r
+       /* Turn off word mode, by setting the Mode Control register\r
+          of the CRT Controller (index 0x17, port 0x3d4): */\r
+\r
+       outpw(CRTC_ADDR, 0xE317);\r
+\r
+       /* Turn off doubleword mode, by setting the Underline Location\r
+          register (index 0x14, port 0x3d4): */\r
+\r
+       outpw(CRTC_ADDR, 0x0014);\r
+\r
+       /* Clear entire video memory, by selecting all four planes, then\r
+          writing 0 to entire segment. */\r
+\r
+       outpw(SEQU_ADDR, 0x0F02);\r
+       memset(vga+1, 0, 0xffff); /* stupid size_t exactly 1 too small */\r
+       vga[0] = 0;\r
+\r
+       /* Update the global variables to reflect dimensions of this\r
+          mode.  This is needed by most future drawing operations. */\r
+\r
+       width   = 320;\r
+       height  = 200;\r
+\r
+       /* Each byte addresses four pixels, so the width of a scan line\r
+          in *bytes* is one fourth of the number of pixels on a line. */\r
+\r
+       widthBytes = width / 4;\r
+\r
+       /* By default we want screen refreshing and drawing operations\r
+       to be based at offset 0 in the video segment. */\r
+\r
+       actStart = visStart = 0;\r
+\r
+       }\r
+\r
+/*\r
+ * setActiveStart() tells our graphics operations which address in video\r
+ * memory should be considered the top left corner.\r
+ */\r
+\r
+void setActiveStart(unsigned offset)\r
+       {\r
+       actStart = offset;\r
+       }\r
+\r
+/*\r
+ * setVisibleStart() tells the VGA from which byte to fetch the first\r
+ * pixel when starting refresh at the top of the screen.  This version\r
+ * won't look very well in time critical situations (games for\r
+ * instance) as the register outputs are not synchronized with the\r
+ * screen refresh.  This refresh might start when the high byte is\r
+ * set, but before the low byte is set, which produces a bad flicker.\r
+ */\r
+\r
+void setVisibleStart(unsigned offset)\r
+       {\r
+       visStart = offset;\r
+       outpw(CRTC_ADDR, 0x0C);         /* set high byte */\r
+       outpw(CRTC_ADDR+1, visStart >> 8);\r
+       outpw(CRTC_ADDR, 0x0D);         /* set low byte */\r
+       outpw(CRTC_ADDR+1, visStart & 0xff);\r
+       }\r
+\r
+/*\r
+ * setXXXPage() sets the specified page by multiplying the page number\r
+ * with the size of one page at the current resolution, then handing the\r
+ * resulting offset value over to the corresponding setXXXStart()\r
+ * function.  The first page is number 0.\r
+ */\r
+\r
+void setActivePage(int page)\r
+       {\r
+       setActiveStart(page * widthBytes * height);\r
+       }\r
+\r
+void setVisiblePage(int page)\r
+       {\r
+       setVisibleStart(page * widthBytes * height);\r
+       }\r
+\r
+void putPixel_X(int x, int y, UCHAR color)\r
+       {\r
+\r
+       /* Each address accesses four neighboring pixels, so set\r
+          Write Plane Enable according to which pixel we want\r
+          to modify.  The plane is determined by the two least\r
+          significant bits of the x-coordinate: */\r
+\r
+       outp(0x3c4, 0x02);\r
+       outp(0x3c5, 0x01 << (x & 3));\r
+\r
+       /* The offset of the pixel into the video segment is\r
+          offset = (width * y + x) / 4, and write the given\r
+          color to the plane we selected above.  Heed the active\r
+          page start selection. */\r
+\r
+       vga[(unsigned)(widthBytes * y) + (x / 4) + actStart] = color;\r
+\r
+       }\r
+\r
+UCHAR getPixel_X(int x, int y)\r
+       {\r
+\r
+       /* Select the plane from which we must read the pixel color: */\r
+\r
+       outpw(GRAC_ADDR, 0x04);\r
+       outpw(GRAC_ADDR+1, x & 3);\r
+\r
+       return vga[(unsigned)(widthBytes * y) + (x / 4) + actStart];\r
+\r
+       }\r
+\r
+void set320x240x256_X(void)\r
+       {\r
+\r
+       /* Set the unchained version of mode 13h: */\r
+\r
+       set320x200x256_X();\r
+\r
+       /* Modify the vertical sync polarity bits in the Misc. Output\r
+          Register to achieve square aspect ratio: */\r
+\r
+       outp(0x3C2, 0xE3);\r
+\r
+       /* Modify the vertical timing registers to reflect the increased\r
+          vertical resolution, and to center the image as good as\r
+          possible: */\r
+\r
+       outpw(0x3D4, 0x2C11);           /* turn off write protect */\r
+       outpw(0x3D4, 0x0D06);           /* vertical total */\r
+       outpw(0x3D4, 0x3E07);           /* overflow register */\r
+       outpw(0x3D4, 0xEA10);           /* vertical retrace start */\r
+       outpw(0x3D4, 0xAC11);           /* vertical retrace end AND wr.prot */\r
+       outpw(0x3D4, 0xDF12);           /* vertical display enable end */\r
+       outpw(0x3D4, 0xE715);           /* start vertical blanking */\r
+       outpw(0x3D4, 0x0616);           /* end vertical blanking */\r
+\r
+       /* Update mode info, so future operations are aware of the\r
+          resolution */\r
+\r
+       height = 240;\r
+\r
+       }\r
+\r
+\r
+\r
+/*\r
+ * The library testing routines follows below.\r
+ */\r
+\r
+\r
+#ifdef TESTING\r
+\r
+#include <stdio.h>\r
+#include <conio.h>\r
+\r
+void set80x25(void)\r
+       {\r
+       union REGS r;\r
+       r.x.ax = 0x0003;\r
+       int86(0x10, &r, &r);\r
+       }\r
+\r
+void doTest(void)\r
+       {\r
+       int p, x, y, pages;\r
+\r
+       /* This is the way to calculate the number of pages available. */\r
+\r
+       pages = 65536L/(widthBytes*height);\r
+\r
+       for (p = 0; p < pages; ++p)\r
+               {\r
+               setActivePage(p);\r
+\r
+               /* On each page draw a single colored border, and dump the palette\r
+                  onto a small square about the middle of the page. */\r
+\r
+               for (x = 0; x <= width; ++x)\r
+                       {\r
+                       putPixel_X(x, 0, p+1);\r
+                       putPixel_X(x, height-1, p+1);\r
+                       }\r
+\r
+               for (y = 0; y <= height; ++y)\r
+                       {\r
+                       putPixel_X(0, y, p+1);\r
+                       putPixel_X(width-1, y, p+1);\r
+                       }\r
+\r
+               for (x = 0; x < 16; ++x)\r
+                       for (y = 0; y < 16; ++y)\r
+                               putPixel_X(x+(p+3)*16, y+(p+3)*16, x + y*16);\r
+\r
+               }\r
+\r
+       /* Each pages will now contain a different image.  Let the user cycle\r
+          through all the pages by pressing a key. */\r
+\r
+       for (p = 0; p < pages; ++p)\r
+               {\r
+               setVisiblePage(p);\r
+               getch();\r
+               }\r
+\r
+       }\r
+\r
+\r
+/*\r
+ * Library test (program) entry point.\r
+ */\r
+\r
+int main(void)\r
+       {\r
+//     puts("First, have a look at the 320x200 mode.  I will draw some rubbish");\r
+//     puts("on all of the four pages, then let you cycle through them by");\r
+//     puts("hitting a key on each page.");\r
+//     puts("Press a key when ready...");\r
+//     getch();\r
+\r
+//     set320x200x256_X();\r
+//     doTest();\r
+\r
+//     set80x25();\r
+//     puts("Then, check out Mode X, 320x240 with 3 (and a half) pages.");\r
+//     puts("Press a key when ready...");\r
+//     getch();\r
+\r
+       set320x240x256_X();\r
+       doTest();\r
+\r
+       set80x25();\r
+       puts("Where to next?  It's your move!");\r
+       return 0;\r
+       }\r
+\r
+#endif\r
diff --git a/16/tweak16/XINTRO/x.bat b/16/tweak16/XINTRO/x.bat
new file mode 100755 (executable)
index 0000000..cd011b0
--- /dev/null
@@ -0,0 +1,2 @@
+rem wcc -ml lib.c
+wcl -0 -ml /l=dos lib