2 TWEAK 1.6á - Mold your own VGA modes
\r
4 by Robert Schmidt of Ztiff Zox Softwear, (C) Copyright 1992-93
\r
6 For documentation, see TWEAK.DOC.
\r
12 First version available to the public.
\r
13 Aw, what the heck, I'll admit this is the first version ever...
\r
14 I know the usage of C++ classes may look a little stupid,
\r
16 Another stupid, *stupid* thing is the mixed use of conio and
\r
17 iostream, but hey, it works too!
\r
18 This version is not commented whatsoever.
\r
19 Pretty lame interface - no help.
\r
20 Test screens assume text start at segment 0xb800, and graphics
\r
23 Changed from small to large memory model. Not that I need it, it
\r
24 just makes the code more readable.
\r
25 Commented heavily, and beautified the code.
\r
26 Nearly rewrote the program completely, by using another OO strategy.
\r
27 Changed use of abort() to exit(1).
\r
28 Text test pattern now fills entire text buffer from 0xb800:0x0000
\r
30 TWEAK now captures whatever screen mode is active at startup,
\r
31 instead of defaulting to BIOS mode 3 (80x25).
\r
32 The screen is reset to the startup BIOS mode at exit, too.
\r
33 Added 'S' and 'L' as synonyms for F9 and F10.
\r
34 Added Shift+TAB as a companion to TAB.
\r
35 Editing screen now uses 80x50 instead of 80x25.
\r
36 Added one text test screen which uses the 8x8 font.
\r
37 Added online help, not context sensitive as promised. Maybe later.
\r
38 Edititing screen is cleared when a test is initiated, so that it
\r
39 is easier to see that something happened if the wrong test
\r
41 Removed startup banner.
\r
42 Removed use of cout and cin for screen/keyboard I/O, in favour of
\r
43 the colors and windows provided by conio.h.
\r
44 Instead, I use fstreams for *file* I/O... much more convenient than
\r
46 Made the interface more cheerful by using lots of colors.
\r
48 Nuked a serious bug in the text test pattern. At the end, it
\r
49 wrote characters far outside of the video buffer, overwriting
\r
50 0x800 bytes at the start of the 0xC000 segment.
\r
51 Most PCs have ROM in this area, so I didn't notice the
\r
52 bug until I ran TWEAK on some 486s with a SCSI harddisk.
\r
53 I think those map some RAM to that segment, in any case
\r
54 TWEAK crashed whenever the text pattern was used on those
\r
56 I Decided not to read back the registers when returning from the
\r
57 test screen. It was not very usable, and imposed some
\r
58 problems when using different test screens.
\r
61 Added the AutoDetect testing pattern, which makes use of my new,
\r
62 mode independant VGA graphics library to make the testing
\r
63 much more interesting and informative. Might add simple
\r
64 menus to this later.
\r
65 Fixed a bug in the VGA library for Chained 256-color modes, which
\r
66 caused scrolling to go four times as far as intended.
\r
67 Made the help window larger, more readable.
\r
68 Added question of confirmation to quit when ESC is pressed.
\r
69 Added lots more sample modes (from xlib06).
\r
71 Added the mode heuristics seen in the autodetect test screen to
\r
72 the editor screen. This gives the user instant feedback on
\r
74 Fixed the RegTable::out() method to correctly reset the sequencer.
\r
75 Result: no flickering when testing modes.
\r
76 The autodetect screen sets the VGA palettes to the BIOS default.
\r
80 # ifndef __COMPACT__
\r
82 # error A large data model is required!
\r
92 #include <fstream.h>
\r
96 #include "Screen.HPP"
\r
97 #include "RegEdit.HPP"
\r
98 #include "TestPat.HPP"
\r
99 #include "detect.hpp"
\r
104 tempBuffer swap(textScr);
\r
106 window(5,5,editWidth-5,33);
\r
107 textattr(HELP_COLOR);
\r
109 window(6,6,editWidth-6,32);
\r
111 cprintf("TWEAK 1.6á by Robert Schmidt - Ztiff Zox Softwear\n\r"
\r
112 "Quick reference help screen\n\r"
\r
114 "Up/Down/Home/End: select register\n\r"
\r
115 " Backspace: enable/disable register\n\r"
\r
116 " 2 hex digits: set register value\n\r"
\r
117 " -/+: decrease/increase register value\n\r"
\r
118 " F1-F8: toggle register bits 7-0\n\r"
\r
119 " F9 or 'S': save register set to file\n\r"
\r
120 " F10 or 'L': load set from file\n\r"
\r
121 " 'M': select BIOS mode to work from\n\r"
\r
122 " TAB/Shift-TAB: select test screen\n\r"
\r
123 " ENTER: show test screen\n\r"
\r
124 " 'H': show this help window\n\r"
\r
125 " ESC: Quit TWEAK immediately\n\r"
\r
127 "The mode heuristics shown are NOT perfect. It is practically\n\r"
\r
128 "impossible to foresee what your screen will show. Use the\n\r"
\r
129 "values given as guidance, or hints.\n\r"
\r
131 "When viewing the autodetect test screen, you may use the\n\r"
\r
132 "arrows to scroll over the virtual screen. Press ESC or ENTER\n\r"
\r
135 "For more information, see the TWEAK.DOC file.\n\r"
\r
136 "Now press the 'any' key to return to the editor.\n\r"
\r
139 window(1,1,editWidth,editHeight);
\r
144 void prompt(char *p = 0, int attr = PROMPT_COLOR)
\r
147 gotoxy(42,editHeight-1);
\r
155 int main(int argc, char **argv)
\r
157 // Initialize the register table with descriptions and all.
\r
158 RegisterEditor regEditor(ifstream("TWEAK.DAT"));
\r
161 int parentBiosMode = getBiosMode();
\r
163 // Set our default editing screen, and get its dimensions
\r
167 text_info *ti = new text_info;
\r
169 editMode = ti->currmode;
\r
170 editHeight = ti->screenheight;
\r
171 editWidth = ti->screenwidth;
\r
172 editSize = editHeight * editWidth;
\r
175 tempBuffer swap(textScr); // Establish the temporary screen buffer
\r
177 unsigned char quit = 0; // Non-zero when a quit command is
\r
179 int key; // The last key pressed.
\r
181 // Build the editing screen:
\r
183 regEditor.printAllCon();
\r
184 gotoxy(42, editHeight-20);
\r
185 textattr(HELP_COLOR);
\r
186 cprintf("(Press H if you need help)");
\r
188 ModeInfo minfo(regEditor);
\r
190 // Start the main keyboard polling loop:
\r
195 regEditor.showBitMask();
\r
197 regEditor.updateSelect();
\r
201 key = getch() << 8;
\r
203 key = tolower(key);
\r
208 case 0x4700: //HOME
\r
209 regEditor.setSelect(0);
\r
215 regEditor.setSelect(regEditor.getMaxReg());
\r
217 case 0x5000: //DOWN
\r
221 // Function keys - toggle single bit in selected reg.
\r
230 **regEditor ^= (1<<7-((key>>8)-0x3B));
\r
235 // Handle file operations (save/load):
\r
237 int save=(key==0x4300);
\r
239 // Prompt for filename.
\r
241 prompt("Save file name: ");
\r
243 prompt("Load file name: ");
\r
245 if (strlen(fname) == 0)
\r
247 prompt("File operation canceled.");
\r
251 prompt(0, ERROR_COLOR); // prepare for error
\r
254 ofstream out(fname, ios::trunc|ios::binary|ios::out);
\r
256 cprintf("Error creating '%s'!", fname);
\r
261 cprintf("Error writing '%s'!", fname);
\r
265 cprintf(" written.");
\r
271 ifstream in(fname, ios::binary|ios::in|ios::nocreate);
\r
273 cprintf("Error opening '%s'!", fname);
\r
278 cprintf("Error reading '%s'!", fname);
\r
287 // Update screen to reflect changes (if any).
\r
288 regEditor.printAllCon();
\r
292 case '0': case '1': case '2': case '3': case '4': case '5':
\r
293 case '6': case '7': case '8': case '9': case 'a': case 'b':
\r
294 case 'c': case 'd': case 'e': case 'f':
\r
295 // Input hexadecimal number:
\r
296 gotoxy(40*(regEditor.getSelect()/editHeight)+38,
\r
297 regEditor.getSelect()%editHeight+1);
\r
299 cprintf("%c \b", key);
\r
300 unsigned char newValue;
\r
301 cscanf("%2hx", &newValue);
\r
302 (*regEditor).setValue(newValue);
\r
310 // Alternate file I/O keys:
\r
321 // Select a BIOS mode to work from.
\r
323 prompt("Base BIOS screen mode: 0x");
\r
324 cscanf("%2hx",&baseMode);
\r
325 swap.save(); //save edit buffer
\r
327 // Set the selected mode, and grab register values.
\r
328 setBiosMode(baseMode);
\r
330 swap.restore(); //reset edit mode and buffer
\r
331 regEditor.printAllCon();
\r
333 cprintf("Got registers from mode 0x%02x", baseMode);
\r
337 (*regEditor).toggleEnable();
\r
342 // Decrease register value:
\r
343 // Note that * (dereferencing) is overloaded for both
\r
344 // RegisterTable and Register! Pretty fancy, but hard
\r
350 // Increase register value
\r
355 // Test the screen mode.
\r
357 // Clear the text screen, so the user can see something is
\r
358 // happening even if he chose the wrong test screen.
\r
360 test.run(regEditor);
\r
365 // Select next test pattern:
\r
369 case 0x0F00: // shift-TAB
\r
370 // Select previous test pattern:
\r
376 prompt("Really quit [n]?");
\r
377 if (toupper(getch()) == 'Y')
\r
382 minfo.detectFrom(regEditor);
\r
385 // Reset BIOS mode detected at startup.
\r
386 setBiosMode(parentBiosMode);
\r