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