/* * Fast video support for IBM PC like displays. * Use with pcio.c and FASTVIDEO. * For faster display speed, use pcfv.asm instead of this file. * Routines: * fv_init() * putline(row,buf,attr) int row,attr; char *buf; * void t_move(row,col) int row, col; * void t_eeol() * Notes: * The stuff in this file is C versions of the code in pcfv.asm. * The only routine that will really speed things up is putline(). I * don't think the other stuff is called enough to have much effect. * * C Durland Public Domain * J Burnell C for some of the asm routines. 3/92 */ extern int t_ncol, t_nrow; /* in pcio.c */ int tcolor = 7, mcolor = 96; /* text, modeline color defaults */ static char *video_addr; static int BIOS_color; static int phys_cols; /* Because t_ncol can change */ void putline(row, buf, attr) /* note: row is 0 relative */ int row,attr; char *buf; { register int n = t_ncol; register char *display = video_addr +2*row*phys_cols; while (n--) { *display++ = *buf++; /* character */ *display++ = attr; /* attribute */ } } #include void t_move(row,col) int row, col; /* move cursor to (row,col) */ { union REGS rg; rg.h.ah = 2; /* set cursor position function code */ rg.h.dl = col; rg.h.dh = row; rg.h.bh = 0; /* set screen page number */ int86(0x10, &rg, &rg); } void fv_init() { union REGS x; /* Try and figure out addr of video */ x.h.ah = 0xF; int86(0x10,&x,&x); if (x.h.al == 7) video_addr = (char *)0xB0000000L; /* mono */ else video_addr = (char *)0xB8000000L; /* color */ /* Figure out the BIOS color. I'll use that to write the message * line. */ t_move(0,0); t_putchar(' '); /* Let the BIOS write a character and attr */ t_move(0,0); /* read character attr */ x.h.ah = 0x8; int86(0x10,&x,&x); BIOS_color = x.h.ah; if (BIOS_color == 0) BIOS_color = 7; /* make sure cursor displays */ /* Figure out the number of columns (BIOS 40:4A == columns) */ t_ncol = phys_cols = *((unsigned char *)0x0040004AL); /* Figure out the number of rows. * For EGA type displays, the number of rows is in ram. For CGA, it * is fixed. */ t_nrow = 24; /* default */ x.x.ax = 0x1200; x.x.bx = 0x0010; x.x.cx = 0xFFFF; int86(0x10,&x,&x); if (x.x.cx != 0xFFFF) /* is at least EGA */ t_nrow = *((unsigned char *)0x00400084L); /* 40:84 == rows-1 */ } #define NCOL 140 /* maximum number of columns */ #define SPACE ' ' void t_eeol() /* erase to end of line */ { register int n = t_ncol; int CurCol; /* current column cursor */ int CurRow; /* row */ union REGS rg; register char *ScreenAddr; /* address to write to */ /* find the current cursor position */ rg.h.ah = 3; rg.h.bh = 0; /* current page */ int86(0x10, &rg, &rg); CurCol = rg.h.dl; CurRow = rg.h.dh; ScreenAddr = video_addr + CurRow*phys_cols*2 + CurCol*2; /* Note: You could probably save time by writing * (SPACE | (BIOS_color << 8)) to a short int pointer but I don't * think it will make any difference. */ for (n = phys_cols -CurCol; n--; ) { *ScreenAddr++ = SPACE; /* character */ *ScreenAddr++ = BIOS_color; /* attribute */ } }