--- /dev/null
+/*\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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+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
--- /dev/null
+/*\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 ®Table)\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
--- /dev/null
+#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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+# 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
--- /dev/null
+#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
--- /dev/null
+ 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
--- /dev/null
+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
--- /dev/null
+; 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
--- /dev/null
+ 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
--- /dev/null
+----------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
--- /dev/null
+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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+#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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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 ®[r];\r
+ return 0;\r
+ }\r
+\r
+\r
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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 ®Tab)\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
--- /dev/null
+/*\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
--- /dev/null
+/*\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
--- /dev/null
+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
--- /dev/null
+\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
--- /dev/null
+/*\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
--- /dev/null
+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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+wsample lib.exe\r
+setres 80 50\r
+wprof lib.smp\r
--- /dev/null
+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
--- /dev/null
+/*\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
--- /dev/null
+rem wcc -ml lib.c
+wcl -0 -ml /l=dos lib