442 lines
6.5 KiB
C
442 lines
6.5 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1995 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
disp_tm.c
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Ted Miller 6-July-1995
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This routine contains low-level routines to operate on a
|
|||
|
CGA-style text mode video buffer.
|
|||
|
|
|||
|
It collects up various other bits and pieces that were written by
|
|||
|
others and once contained in other source files.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "bootx86.h"
|
|||
|
#include "displayp.h"
|
|||
|
|
|||
|
//
|
|||
|
// Standard cga 80x25 text mode's video buffer address,
|
|||
|
// resolution, etc.
|
|||
|
//
|
|||
|
#define VIDEO_BUFFER_VA 0xb8000
|
|||
|
#define VIDEO_ROWS 25
|
|||
|
#define VIDEO_COLUMNS 80
|
|||
|
#define VIDEO_BYTES_PER_ROW (VIDEO_COLUMNS*2)
|
|||
|
|
|||
|
//
|
|||
|
// Various globals to track location on screen, attribute, etc.
|
|||
|
//
|
|||
|
PUCHAR Vp = (PUCHAR)VIDEO_BUFFER_VA;
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmPositionCursor(
|
|||
|
USHORT Row,
|
|||
|
USHORT Column
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Sets the position of the soft cursor. That is, it doesn't move the
|
|||
|
hardware cursor but sets the location of the next write to the
|
|||
|
screen.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Row - Row coordinate of where character is to be written.
|
|||
|
|
|||
|
Column - Column coordinate of where character is to be written.
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
if(Row >= VIDEO_ROWS) {
|
|||
|
Row = VIDEO_ROWS-1;
|
|||
|
}
|
|||
|
|
|||
|
if(Column >= VIDEO_COLUMNS) {
|
|||
|
Column = VIDEO_COLUMNS-1;
|
|||
|
}
|
|||
|
|
|||
|
Vp = (PUCHAR)(VIDEO_BUFFER_VA + (Row * VIDEO_BYTES_PER_ROW) + (2 * Column));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmStringOut(
|
|||
|
IN PUCHAR String
|
|||
|
)
|
|||
|
{
|
|||
|
PUCHAR p = String;
|
|||
|
|
|||
|
while(*p) {
|
|||
|
p = TextTmCharOut(p);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
PUCHAR
|
|||
|
TextTmCharOut(
|
|||
|
PUCHAR pc
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Writes a character on the display at the current position.
|
|||
|
Newlines and tabs are interpreted and acted upon.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
c - pointer to character to write
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Pointer to next char in string
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
{
|
|||
|
unsigned u;
|
|||
|
UCHAR c;
|
|||
|
UCHAR temp;
|
|||
|
|
|||
|
c = *pc;
|
|||
|
|
|||
|
switch (c) {
|
|||
|
case '\n':
|
|||
|
if(TextRow == (VIDEO_ROWS-1)) {
|
|||
|
TextTmScrollDisplay();
|
|||
|
TextSetCursorPosition(0,TextRow);
|
|||
|
} else {
|
|||
|
TextSetCursorPosition(0,TextRow+1);
|
|||
|
}
|
|||
|
break;
|
|||
|
|
|||
|
case '\r':
|
|||
|
//
|
|||
|
// ignore
|
|||
|
//
|
|||
|
break;
|
|||
|
|
|||
|
case '\t':
|
|||
|
temp = ' ';
|
|||
|
u = 8 - (TextColumn % 8);
|
|||
|
while(u--) {
|
|||
|
TextTmCharOut(&temp);
|
|||
|
}
|
|||
|
TextSetCursorPosition(TextColumn+u,TextRow);
|
|||
|
break;
|
|||
|
|
|||
|
default :
|
|||
|
*Vp++ = c;
|
|||
|
*Vp++ = TextCurrentAttribute;
|
|||
|
TextSetCursorPosition(TextColumn+1,TextRow);
|
|||
|
}
|
|||
|
|
|||
|
return(pc+1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmFillAttribute(
|
|||
|
IN UCHAR Attribute,
|
|||
|
IN ULONG Length
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Changes the screen attribute starting at the current cursor position.
|
|||
|
The cursor is not moved.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Attribute - Supplies the new attribute
|
|||
|
|
|||
|
Length - Supplies the length of the area to change (in bytes)
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PUCHAR Temp;
|
|||
|
|
|||
|
Temp = Vp+1;
|
|||
|
|
|||
|
while((Vp+1+Length*2) > Temp) {
|
|||
|
*Temp++ = (UCHAR)Attribute;
|
|||
|
Temp++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmClearToEndOfLine(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears from the current cursor position to the end of the line
|
|||
|
by writing blanks with the current video attribute.
|
|||
|
The cursor position is not changed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PUSHORT p;
|
|||
|
unsigned u;
|
|||
|
|
|||
|
//
|
|||
|
// Calculate address of current cursor position
|
|||
|
//
|
|||
|
p = (PUSHORT)((PUCHAR)VIDEO_BUFFER_VA + (TextRow*VIDEO_BYTES_PER_ROW)) + TextColumn;
|
|||
|
|
|||
|
//
|
|||
|
// Fill with blanks up to end of line.
|
|||
|
//
|
|||
|
for(u=TextColumn; u<VIDEO_COLUMNS; u++) {
|
|||
|
*p++ = (TextCurrentAttribute << 8) + ' ';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmClearFromStartOfLine(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears from the start of the line to the current cursor position
|
|||
|
by writing blanks with the current video attribute.
|
|||
|
The cursor position is not changed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PUSHORT p;
|
|||
|
unsigned u;
|
|||
|
|
|||
|
//
|
|||
|
// Calculate address of start of line in video buffer
|
|||
|
//
|
|||
|
p = (PUSHORT)((PUCHAR)VIDEO_BUFFER_VA + (TextRow*VIDEO_BYTES_PER_ROW));
|
|||
|
|
|||
|
//
|
|||
|
// Fill with blanks up to char before cursor position.
|
|||
|
//
|
|||
|
for(u=0; u<TextColumn; u++) {
|
|||
|
*p++ = (TextCurrentAttribute << 8) + ' ';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmClearToEndOfDisplay(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears from the current cursor position to the end of the video
|
|||
|
display by writing blanks with the current video attribute.
|
|||
|
The cursor position is not changed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
USHORT x,y;
|
|||
|
PUSHORT p;
|
|||
|
|
|||
|
//
|
|||
|
// Clear current line
|
|||
|
//
|
|||
|
TextTmClearToEndOfLine();
|
|||
|
|
|||
|
//
|
|||
|
// Clear the remaining lines
|
|||
|
//
|
|||
|
p = (PUSHORT)((PUCHAR)VIDEO_BUFFER_VA + ((TextRow+1)*VIDEO_BYTES_PER_ROW));
|
|||
|
|
|||
|
for(y=TextRow+1; y<VIDEO_ROWS; y++) {
|
|||
|
|
|||
|
for(x=0; x<VIDEO_COLUMNS; x++) {
|
|||
|
|
|||
|
*p++ =(TextCurrentAttribute << 8) + ' ';
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmClearDisplay(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Clears the text-mode video display by writing blanks with
|
|||
|
the current video attribute over the entire display.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
unsigned u;
|
|||
|
|
|||
|
//
|
|||
|
// Write blanks in the current attribute to the entire screen.
|
|||
|
//
|
|||
|
for(u=0; u<VIDEO_ROWS*VIDEO_COLUMNS; u++) {
|
|||
|
((PUSHORT)VIDEO_BUFFER_VA)[u] = (TextCurrentAttribute << 8) + ' ';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmScrollDisplay(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Scrolls the display up one line. The cursor position is not changed.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Returns:
|
|||
|
|
|||
|
Nothing
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PUSHORT Sp,Dp;
|
|||
|
USHORT i,j,c;
|
|||
|
|
|||
|
Dp = (PUSHORT) VIDEO_BUFFER_VA;
|
|||
|
Sp = (PUSHORT) (VIDEO_BUFFER_VA + VIDEO_BYTES_PER_ROW);
|
|||
|
|
|||
|
//
|
|||
|
// Move each row up one row
|
|||
|
//
|
|||
|
for(i=0 ; i < (USHORT)(VIDEO_ROWS-1) ; i++) {
|
|||
|
for(j=0; j < (USHORT)VIDEO_COLUMNS; j++) {
|
|||
|
*Dp++ = *Sp++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Write blanks in the bottom line, using the attribute
|
|||
|
// from the leftmost char on the bottom line on the screen.
|
|||
|
//
|
|||
|
c = (*Dp & (USHORT)0xff00) + (USHORT)' ';
|
|||
|
|
|||
|
for(i=0; i < (USHORT)VIDEO_COLUMNS; ++i) {
|
|||
|
*Dp++ = c;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
TextTmSetCurrentAttribute(
|
|||
|
IN UCHAR Attribute
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Noop.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Attribute - New attribute to set to.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Nothing.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
UNREFERENCED_PARAMETER(Attribute);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
CHAR TmGraphicsChars[GraphicsCharMax] = { '<EFBFBD>','<EFBFBD>','<EFBFBD>','<EFBFBD>','<EFBFBD>','<EFBFBD>' };
|
|||
|
|
|||
|
UCHAR
|
|||
|
TextTmGetGraphicsChar(
|
|||
|
IN GraphicsChar WhichOne
|
|||
|
)
|
|||
|
{
|
|||
|
return((UCHAR)TmGraphicsChars[WhichOne]);
|
|||
|
}
|