home *** CD-ROM | disk | FTP | other *** search
- // display.cpp the Display class methods
- //
- // (c) Aspen Scientific 1989. All Rights Reserved.
- // Author: Vaughn Vernon
-
- #include "display.cls"
-
- // for Microsoft C, not Zortech
- #ifndef __ZTC__
- # include <memory.h>
- # include <conio.h>
- #else
- static void movedata(unsigned, unsigned, unsigned, unsigned, unsigned);
- #endif
-
- // ***************************************************************
- // ** the Display methods in this file are implemented for MS-DOS
- // ** in a text display (non-graphics) environment. it uses
- // ** 8086 interrupts and the Microsoft C int86() function, as
- // ** well as far pointers to the video memory map segment.
- // ***************************************************************
-
- #include <dos.h>
-
- static union REGS vRegs;
- static union REGS videoSaveMode;
- static const unsigned monoSeg = 0xb000;
- static const unsigned colorSeg = 0xb800;
-
- #if defined(M_I86SM) || defined(M_I86MM)
- static unsigned ds;
- #endif
-
- static unsigned map[80];
-
- Display::Display(const Mouse * mou) : cursor(0,0)
- {
- if (init == 1)
- return;
-
- mouse = mou;
-
- // for small and medium models (small data), need data seg
- struct SREGS segs;
- segread(&segs);
- ds = segs.ds;
-
- // find out the current video mode, save
- // it, then set the new mode if necessary.
-
- vRegs.h.ah = 0x0f;
- int86(0x10, &vRegs, &vRegs);
- videoSaveMode = vRegs;
-
- // return of 7 in AL register is mono
- if (vRegs.h.al == 7) {
- videoSeg = monoSeg;
- color = 0;
- snow = 0;
- }
- else {
-
- videoSeg = colorSeg;
- color = 1;
-
- if (vRegs.h.al != 3) {
- vRegs.h.ah = 0;
- vRegs.h.al = 3;
- int86(0x10, &vRegs, &vRegs);
- }
-
- // check for a snowing display; an EGA
- // or VGA is automatic no-snow.
-
- unsigned EGAMemory, EGAMode;
-
- vRegs.h.ah = 0x12;
- vRegs.h.bl = 0x10;
- int86(0x10, &vRegs, &vRegs);
-
- EGAMemory = vRegs.h.bl;
- EGAMode = vRegs.h.bh;
-
- // if the returned memory is out of range, or
- // the ega/vga card is not attached to the color
- // display (EGAMode != 0), assume snow.
-
- if (EGAMemory < 0 || EGAMemory > 3 || EGAMode != 0)
- snow = 1;
- else
- snow = 0;
- }
-
- // set the Display size
- origin(Point(0,0));
- corner(Point(24,79));
-
- clear();
-
- draw();
-
- init=1;
- }
-
- Display::~Display()
- {
- clear();
- cursor(0,0);
- draw();
- vRegs = videoSaveMode;
- int86(0x10, &vRegs, &vRegs);
- }
-
- void
- Display::clear()
- {
- Point size = extent();
-
- mouse->hide();
-
- vRegs.h.dh = size.x() + 1;
- vRegs.h.dl = size.y() + 1;
- vRegs.h.bh = defAttr.get() >> 8;
- vRegs.x.cx = 0;
- vRegs.h.al = 0;
- vRegs.h.ah = 6;
- int86(0x10, &vRegs, &vRegs);
-
- mouse->show();
- }
-
- void
- Display::operator()(unsigned row, unsigned col)
- {
- Point top, bot;
-
- top = origin();
- bot = corner();
-
- if (row < top.x() || row > bot.x() ||
- col < top.y() || col > bot.y())
- return;
-
- // move cursor
- cursor(int(row), int(col));
- draw();
- }
-
- void
- Display::cursorOff()
- {
- vRegs.x.cx = 0x2000;
- vRegs.h.ah = 1;
- int86(0x10, &vRegs, &vRegs);
- }
-
- void
- Display::cursorOn()
- {
- if (hasColor())
- vRegs.x.cx = 0x0607;
- else
- vRegs.x.cx = 0x0b0c;
-
- vRegs.h.ah = 1;
- int86(0x10, &vRegs, &vRegs);
- }
-
- void
- Display::putString(Point & p, const unsigned char * s, DisplayAttr & a)
- {
- cursor = p;
-
- register unsigned c = cursor.y();
- register unsigned len=0;
- unsigned *mp = map;
- for ( ; c <= width() && *s; ++c, ++len)
- *mp++ = (unsigned)*s++ | a.get();
-
- mouse->hide();
-
- // protect against flicker
- if (snow)
- while ((inp(0x03da) & 8) == 0)
- ;
-
- #if defined(M_I86SM) || defined(M_I86MM)
- movedata(ds, (unsigned)map,
- #else
- movedata(FP_SEG(map), FP_OFF(map),
- #endif
- videoSeg, cursor.x() * 160 + cursor.y() * 2, len * 2);
-
- mouse->show();
-
- cursor(cursor.x(), c);
- }
-
- void
- Display::putChar(Point & p, unsigned char c, DisplayAttr & a)
- {
- cursor = p;
-
- *map = c | a.get();
-
- mouse->hide();
-
- // protect against flicker
- if (snow)
- while ((inp(0x03da) & 8) == 0)
- ;
-
- #if defined(M_I86SM) || defined(M_I86MM)
- movedata(ds, (unsigned)map,
- #else
- movedata(FP_SEG(map), FP_OFF(map),
- #endif
- videoSeg, cursor.x() * 160 + cursor.y() * 2, 2);
-
- mouse->show();
-
- if (cursor.y() != width())
- cursor(cursor.x(), cursor.y() + 1);
- }
-
- // just update cursor
- void
- Display::draw()
- {
- vRegs.h.dh = cursor.x();
- vRegs.h.dl = cursor.y();
- vRegs.h.bh = 0;
- vRegs.h.ah = 2;
- int86(0x10, &vRegs, &vRegs);
- }
-
- #ifdef __ZTC__
-
- static void
- movedata(unsigned sSeg, unsigned sOff, unsigned dSeg, unsigned dOff, unsigned n)
- {
- unsigned far *src, far *dest;
-
- src = MK_FP(sSeg, sOff);
- dest = MK_FP(dSeg, dOff);
-
- // divide by 2
- n >>= 1;
-
- for (register int i=0; i < n; ++i)
- *dest++ = *src++;
- }
-
- #endif
-