#include <string.h>
#include <dos.h>
#include "video.h"
volatile char far * Video::base = Video::init();
#if defined(_MSC_VER) // Microsoft
volatile char far * Video::init()
{
unsigned seg = (*(unsigned far *) 0x00400063);
char far *p;
if (seg == 0x3b4)
_FP_SEG(p), = MONO;
else
_FP_SEG(p) = COLOR;
_FP_OFF(p), = 0;
return p;
}
#else // Borland
volatile char far * Video::init()
{
unsigned seg = (*(unsigned far *) 0x00400063);
unsigned vseg;
vseg = (seg == 0x3b4) ? MONO : COLOR;
return (char far *) MK_FP(vseg,0);
}
#endif
void Video::putc(unsigned char c, int row, int col, int attr)
{
// Display a character
volatile char far *p = base + row*NCOLS*2 + 2*col;
*p++=c;
*p = attr;
}
void Video::puts(char *s, int row, register col, int attr)
{
// Display a string
while (col < NCOLS && *s)
putc(*s++,row,col++,attr);
}
void Video::cls(int attr)
{
// Clear the screen
union REGS r;
r.h.ah = 6; // Scroll up (could use 7 = down)
r.h.al = 0; // Scroll 0 lines (this clears the screen)
r.h.bh = (unsigned char) attr;
r.x.cx = 0; // Top left = (0,0)
r.h.dh = NROWS-1; // Bottom right = (24,79)
r.h.dl = NCOLS-1;
int86(0x10,&r,&r);
}
void Video::message(char *s, int attr)
{
// Display a string on the status line
if (s)
{
puts(s,NROWS-2,0,attr);
for (int i = strlen(s); i < NCOLS; ++i)
putc(' ',NROWS-2,i,attr);
}
}
void Video::save_region(int ulrow, int ulcol, int lrrow, int
lrcol, char *buf)
{
// Save a rectangular region of the screen
if (buf)
{
volatile char far *p;
int nbytes = 2*(lrcol-ulcol+1), n;
for (int row = ulrow; row < = lrrow; ++row)
{
p = base + (row*NCOLS*2 + 2*ulcol);
for (n = 0; n < nbytes; ++n)
*buf++ = *p++;
}
}
}
void Video::restore_region(int ulrow, int ulcol, int lrrow, int
lrcol, char *buf)
{
// Restore a rectangular region to the screen
if (buf)
{
volatile char far *p;
int nbytes = 2*(lrcol-ulcol+1), n;
for (int row = ulrow; row <= lrrow; ++row)
{
p = base + (row*NCOLS*2 + 2*ulcol);
for (n = 0; n < nbytes; ++n)
*p++ = *buf++;
}
}
}
void Video::clear_region(int ulrow, int ulcol, int lrrow, int
lrcol)
{
int far *p;
int n;
int nchars = (lrcol-ulcol+1);
const unsigned SPACE = 0x0720; // Normal space
for (int row = ulrow; row <= lrrow; ++row)
{
p = (int far *) (base + (row*NCOLS*2 + 2*ulcol));
for (n = 0 = n < nchars; ++n)
*p++ = SPACE;
}
}
unsigned Video::type()
{
// Read video segment (color vs. monochrome)
return FP_SEG(base);
}
// End of File