home *** CD-ROM | disk | FTP | other *** search
- /*
- TWEAK 1.0 - Mold your own VGA modes
-
- by Robert Schmidt of Ztiff Zox Softwear, 1992-93
-
- For documentation, see TWEAK.DOC.
-
-
- This file is formatted with a tab-width of 4.
- It's been compiled with Borland C++ 3.0 and 3.1, large model.
- It might work with older Turbo versions, or even Microsoft C++, DJGPP,
- Zortech and the lot. What would I know, I can't afford more than
- one compiler.
-
- Please send me any changes you do to enhance TWEAK or make it compatible
- with other compilers, 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...?
-
- TWEAK was based on information found in George Sutty & Steve Blair's
- "Advanced Programmer's Guide to the EGA/VGA" (Brady). While not a
- magnificent book, it covers the basics and all registers. No mention
- of tweaking of any kind, but all register values for the standard
- EGA/VGA modes are appendixed.
-
- Disclaimer:
-
- I don't think this is neccessary in PD stuff, but anyways: This
- product, TWEAK, referred to as THE WORK OF ART, is provided as is,
- as they say. From now on, I'll refer to myself as THE ARTIST, and
- you as THE ART LOVER. THE ARTIST doesn't know what 'as is' means to
- THE ART LOVERS, but to THE ARTIST it means that THE ART LOVER ain't
- got no friggin' right to hold THE ARTIST responsible for anything
- mean, nice, cool, devastating, awesome or terrible happening to
- THE ART LOVER, THE ART LOVER's computer or any part within and
- outside, THE ART LOVER's family, ex-family and their kin,
- THE ART LOVER's sex life, THE ART LOVER's house, car, boat, in short:
- THE ART LOVER's anything, as a consequence of using, not using, or
- abusing THE WORK OF ART or any part contained within, including
- executable, documentation, source, recommendations and references.
- 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 won't.
- I've never heard of any damage arising from trying out TWEAK, or from
- fiddling with the VGA registers in general.
-
- History:
-
- 0.9
- First version available to the public.
- Aw, what the heck, I'll admit this is the first version ever...
- I know the usage of C++ classes may look a little stupid,
- but it works.
- Another stupid, *stupid* thing is the mixed use of conio and
- iostream, but hey, it works too!
- This version is not commented whatsoever.
- Pretty lame interface - no help.
- Test screens assume text start at segment 0xb800, and graphics
- at 0xa000.
- 1.0
- Changed from small to large memory model. Not that I need it, it
- just makes the code more readable.
- Commented heavily, and beautified the code.
- Nearly rewrote the program completely, by using another OO strategy.
- Changed use of abort() to exit(1).
- Text test pattern now fills entire text buffer from 0xb800:0x0000
- to 0xb800:0xffff.
- TWEAK now captures whatever screen mode is active at startup,
- instead of defaulting to BIOS mode 3 (80x25).
- The screen is reset to the startup BIOS mode at exit, too.
- Added 'S' and 'L' as synonyms for F9 and F10.
- Added Shift+TAB as a companion to TAB.
- Editing screen now uses 80x50 instead of 80x25.
- Added one text test screen which uses the 8x8 font.
- Added online help, not context sensitive as promised. Maybe later.
- Edititing screen is cleared when a test is initiated, so that it
- is easier to see that something happened if the wrong test
- screen is selected.
- Removed startup banner.
- Removed use of cout and cin for screen/keyboard I/O, in favour of
- the colors and windows provided by conio.h.
- Instead, I use fstreams for *file* I/O... much more convenient than
- FILEs.
- Made the interface more cheerful by using lots of colors.
- */
-
- #ifndef __LARGE__
- # ifndef __COMPACT__
- # ifndef __HUGE__
- # error A large data model is required!
- # endif
- # endif
- #endif
-
-
- #include <stdio.h>
- #include <dos.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <fstream.h>
-
- #include "Screen.HPP"
- #include "Register.HPP"
- #include "RegTable.HPP"
- #include "TestPat.HPP"
-
-
- void helpWindow()
- {
- tempBuffer swap(textScr);
- swap.save();
- window(40,1,editWidth,21);
- textattr(HELP_COLOR);
- clrscr();
- window(41,2,80,21);
- gotoxy(1,1);
- cprintf("TWEAK 1.0 by Robert Schmidt\n\r"
- "Quick reference:\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: test register set with pattern\n\r"
- "'H': show this help window\n\r"
- "ESC: Quit TWEAK immediately\n\r"
- "\n\r"
- "For more information, see the TWEAK.DOC\n\r"
- "file. Now press the 'any' key to\n\r"
- "return!"
- );
- getch();
- window(1,1,editWidth,editHeight);
- swap.restore();
- }
-
-
- main()
- {
- // Initialize the register table with descriptions and all.
- RegisterTable regTable("TWEAK.DAT");
- TestPatterns test;
-
- int parentBiosMode = getBiosMode();
- // 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:
-
- test.tellTest();
- regTable.showBitMask();
- regTable.printAllCon();
- gotoxy(42, editHeight-7);
- textattr(HELP_COLOR);
- cprintf("(Press H if you need help)");
-
- // Start the main keyboard polling loop:
-
- while (!quit)
- {
- int key = getch();
- if (!key)
- key = getch() << 8;
-
- keyentry:
- switch (key)
- {
- case 0x4700: //HOME
- regTable.setSelect(0);
- break;
- case 0x4800: //UP
- --regTable;
- break;
- case 0x4F00: //END
- regTable.setSelect(regTable.getMaxReg());
- break;
- case 0x5000: //DOWN
- ++regTable;
- 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
- **regTable ^= (1<<7-((key>>8)-0x3B));
- break;
- case 0x4300: //F9
- case 0x4400: //F10
-
- // Handle file operations (save/load):
- char *fname = new char[127];
- int r;
- int save=(key==0x4300);
-
- // Prompt for filename.
- gotoxy(42,editHeight-1);
- textattr(PROMPT_COLOR);
- cprintf(save?"Save":"Load");
- cprintf(" file name: ");
- clreol();
- gets(fname);
-
- gotoxy(42,editHeight-1); // Get ready for error if bad
- textattr(ERROR_COLOR); // luck strikes
- if (save)
- {
- ofstream out(fname, ios::trunc|ios::binary|ios::out);
- if (out.bad())
- cprintf("Error opening %s", fname);
- else
- {
- out << regTable;
- if (out.bad())
- cprintf("Error writing ", fname);
- }
- }
- else
- {
- ifstream in(fname, ios::binary|ios::in|ios::nocreate);
- if (in.bad())
- cprintf("Error opening ", fname);
- else
- {
- in >> regTable;
- if (in.bad())
- cprintf("Error reading ", fname);
- }
- }
-
- delete[] fname;
- // Update screen to reflect changes (if any).
- regTable.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': case 'a': case 'b':
- case 'c': case 'd': case 'e': case 'f':
- // Input hexadecimal number:
- gotoxy(40*(regTable.getSelect()/editHeight)+38,
- regTable.getSelect()%editHeight+1);
- ungetch(key);
- cprintf("%c \b", key);
- unsigned char newValue;
- cscanf("%2hx", &newValue);
- **regTable = newValue;
- break;
-
- case 'H':
- case 'h':
- // Help:
- helpWindow();
- break;
- // Alternate file I/O keys:
- case 'S':
- case 's':
- key = 0x4300;
- goto keyentry;
- case 'L':
- case 'l':
- key = 0x4400;
- goto keyentry;
-
- case 'M':
- case 'm':
-
- // Select a BIOS mode to work out from.
- int baseMode;
- gotoxy(42,editHeight-2);
- textattr(PROMPT_COLOR);
- cprintf("Base BIOS screen mode: 0x");
- clreol();
- cscanf("%2hx",&baseMode);
- swap.save(); //save edit buffer
-
- // Set the selected mode, and grab register values.
- setBiosMode(baseMode);
- regTable.in();
- swap.restore(); //reset edit mode and buffer
- regTable.printAllCon();
- break;
- case 8:
- (*regTable).toggleEnable();
- break;
- case '-':
- // Decrease register value
- // Note that * (dereferencing) is overloaded for both
- // RegisterTable and Register! Pretty fancy :)
- (**regTable)--;
- break;
- case '+':
- // Increase register value
- (**regTable)++;
- break;
- case 13: //ENTER
- // Test the screen mode.
- swap.save();
- // Clear the text screen, so the user can see something is
- // happening.
- clrscr();
- // memset(textScr, 0, sizeof(unsigned)*editSize);
- regTable.out();
- test.run();
- getch();
- swap.restore();
- break;
- case 9: //TAB
- // Select next test pattern:
- ++test;
- test.tellTest();
- break;
- case 0x0F00: // shift-TAB
- // Select previous test pattern:
- --test;
- test.tellTest();
- break;
- case 27: //ESC
- // Quit TWEAK:
- quit = 1;
- break;
- }
- // Update the bit pattern display and register info:
- regTable.showBitMask();
- regTable.updateSelect();
- }
-
- // Reset BIOS mode detected at startup.
- setBiosMode(parentBiosMode);
-
- return 0;
- }