Listing 10 video.h: IBM PC memory-mapped video output

#undef putc      // Don't want any macro surprises

class Video
{
public:
    enum screen_size {NROWS = 25, NCOLS = 80};
    enum display {COLOR = 0xb800, MONO,= 0xb000};
    
    // Order essential in the following!!!
    enum colors {BLACK, BLUE, GREEN, CYAN, RED, MAGENTA,
                 BROWN, LT_GRAY, DK_GRAY, LT_BLUE,
                 LT_GREEN, LT_CYAN, LT_RED, LT_MAGENTA,
                 YELLOW, WHITE, NORMAL = LT_GRAY};

    enum mono_stuff {NO_DISPLAY = 0, UNDERLINE = 1,
                     REVERSE = 0x70};

    // Make a basic foreground color a background color
    static unsigned bkgr(unsigned c);
    
    // Turn on the high intensity bit
    static unsigned bright(unsigned c);
    
    // Turn on the blink bit
    static unsigned blink(unsigned c);
    
    static void putc(unsigned char,int,int,int=NORMAL);
    static void puts(char *,int,int,int=NORMAL);
    static void cls(int=NORMAL);
    static void message(char *, int=NORMAL);
    static void save_region(int, int, int, int, char *);
    static void restore_region(int, int, int, int, char *);
    static void clear_region(int, int, int, int);
    static void save_message();
    static void restore_message();
    static unsigned type();
    static volatile char far * init();
    
private:
    // Pointer to Video RAM:
    static volatile char far *base;
    
    // Status-line buffer
    static char msg_buf[2*NCOLS];
};

inline unsigned Video::bkgr(unsigned c)
{
    return c << 4;
}

inline unsigned Video::bright(unsigned c)
{
    return c | 0x08;
}

inline unsigned Video::blink(unsigned c)
{
    return c | 0x80;
}

inline void Video::save_message()
{
    save_region(NROWS-2,0,NROWS-2,NCOLS-1,msg_buf);
}

inline void Video::restore_message()
{
    restore_region(NROWS-2,0,NROWS-2,NCOLS-1,msg_buf);
}
// End of File