/* 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(); }