mirror of
https://github.com/reactos/reactos.git
synced 2024-08-04 18:40:59 +00:00
[NTVDM]
- Move console text buffer copy into VGA memory, to the BIOS (function BiosCopyTextConsoleToVgaMemory), and do it just after the BIOS sets its default display mode. - Try to resize "correctly" the console to its original size when cleaning BIOS (Part 2/2, see revision 61538). Still WIP. - Code cleaning in vga.c svn path=/branches/ntvdm/; revision=61542
This commit is contained in:
parent
2a053222a7
commit
425717c483
|
@ -264,9 +264,9 @@ static PVGA_REGISTERS VideoModes[BIOS_MAX_VIDEO_MODE + 1] =
|
|||
&VideoMode_40x25_text, /* Mode 01h */ // 16 color
|
||||
&VideoMode_80x25_text, /* Mode 02h */ // 16 color (mono)
|
||||
&VideoMode_80x25_text, /* Mode 03h */ // 16 color
|
||||
&VideoMode_320x200_4color, /* Mode 04h */ // 4 color
|
||||
&VideoMode_320x200_4color, /* Mode 05h */ // same (m)
|
||||
&VideoMode_640x200_2color, /* Mode 06h */ // 640*200 2 color
|
||||
&VideoMode_320x200_4color, /* Mode 04h */ // CGA 4 color
|
||||
&VideoMode_320x200_4color, /* Mode 05h */ // CGA same (m)
|
||||
&VideoMode_640x200_2color, /* Mode 06h */ // CGA 640*200 2 color
|
||||
NULL, /* Mode 07h */ // MDA monochrome text 80*25
|
||||
NULL, /* Mode 08h */ // PCjr
|
||||
NULL, /* Mode 09h */ // PCjr
|
||||
|
@ -710,6 +710,138 @@ static VOID BiosWriteWindow(LPWORD Buffer, SMALL_RECT Rectangle, BYTE Page)
|
|||
}
|
||||
}
|
||||
|
||||
static BOOLEAN BiosScrollWindow(INT Direction,
|
||||
DWORD Amount,
|
||||
SMALL_RECT Rectangle,
|
||||
BYTE Page,
|
||||
BYTE FillAttribute)
|
||||
{
|
||||
DWORD i;
|
||||
LPWORD WindowData;
|
||||
WORD WindowWidth = Rectangle.Right - Rectangle.Left + 1;
|
||||
WORD WindowHeight = Rectangle.Bottom - Rectangle.Top + 1;
|
||||
DWORD WindowSize = WindowWidth * WindowHeight;
|
||||
|
||||
/* Allocate a buffer for the window */
|
||||
WindowData = (LPWORD)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
WindowSize * sizeof(WORD));
|
||||
if (WindowData == NULL) return FALSE;
|
||||
|
||||
/* Read the window data */
|
||||
BiosReadWindow(WindowData, Rectangle, Page);
|
||||
|
||||
if ((Amount == 0)
|
||||
|| (((Direction == SCROLL_DIRECTION_UP)
|
||||
|| (Direction == SCROLL_DIRECTION_DOWN))
|
||||
&& (Amount >= WindowHeight))
|
||||
|| (((Direction == SCROLL_DIRECTION_LEFT)
|
||||
|| (Direction == SCROLL_DIRECTION_RIGHT))
|
||||
&& (Amount >= WindowWidth)))
|
||||
{
|
||||
/* Fill the window */
|
||||
for (i = 0; i < WindowSize; i++)
|
||||
{
|
||||
WindowData[i] = MAKEWORD(' ', FillAttribute);
|
||||
}
|
||||
|
||||
goto Done;
|
||||
}
|
||||
|
||||
switch (Direction)
|
||||
{
|
||||
case SCROLL_DIRECTION_UP:
|
||||
{
|
||||
RtlMoveMemory(WindowData,
|
||||
&WindowData[WindowWidth * Amount],
|
||||
(WindowSize - WindowWidth * Amount) * sizeof(WORD));
|
||||
|
||||
for (i = 0; i < Amount * WindowWidth; i++)
|
||||
{
|
||||
WindowData[WindowSize - i - 1] = MAKEWORD(' ', FillAttribute);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SCROLL_DIRECTION_DOWN:
|
||||
{
|
||||
RtlMoveMemory(&WindowData[WindowWidth * Amount],
|
||||
WindowData,
|
||||
(WindowSize - WindowWidth * Amount) * sizeof(WORD));
|
||||
|
||||
for (i = 0; i < Amount * WindowWidth; i++)
|
||||
{
|
||||
WindowData[i] = MAKEWORD(' ', FillAttribute);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED!
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
/* Write back the window data */
|
||||
BiosWriteWindow(WindowData, Rectangle, Page);
|
||||
|
||||
/* Free the window buffer */
|
||||
HeapFree(GetProcessHeap(), 0, WindowData);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static VOID BiosCopyTextConsoleToVgaMemory(VOID)
|
||||
{
|
||||
PCHAR_INFO CharBuffer;
|
||||
COORD BufferSize = {Bda->ScreenColumns, Bda->ScreenRows + 1};
|
||||
COORD Origin = { 0, 0 };
|
||||
SMALL_RECT ScreenRect;
|
||||
|
||||
INT i, j;
|
||||
INT Counter = 0;
|
||||
WORD Character;
|
||||
DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage * Bda->VideoPageSize);
|
||||
|
||||
/* Allocate a temporary buffer for ReadConsoleOutput */
|
||||
CharBuffer = HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
BufferSize.X * BufferSize.Y
|
||||
* sizeof(CHAR_INFO));
|
||||
if (CharBuffer == NULL) return;
|
||||
|
||||
ScreenRect.Left = ScreenRect.Top = 0;
|
||||
ScreenRect.Right = BufferSize.X;
|
||||
ScreenRect.Bottom = BufferSize.Y;
|
||||
|
||||
/* Read the data from the console into the temporary buffer... */
|
||||
ReadConsoleOutputA(BiosConsoleOutput,
|
||||
CharBuffer,
|
||||
BufferSize,
|
||||
Origin,
|
||||
&ScreenRect);
|
||||
|
||||
/* ... and copy the temporary buffer into the VGA memory */
|
||||
for (i = 0; i < BufferSize.Y; i++)
|
||||
{
|
||||
for (j = 0; j < BufferSize.X; j++)
|
||||
{
|
||||
Character = MAKEWORD(CharBuffer[Counter].Char.AsciiChar,
|
||||
(BYTE)CharBuffer[Counter].Attributes);
|
||||
++Counter;
|
||||
|
||||
/* Write to video memory */
|
||||
VgaWriteMemory(VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD),
|
||||
(LPVOID)&Character,
|
||||
sizeof(WORD));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers)
|
||||
{
|
||||
INT i;
|
||||
|
@ -850,14 +982,43 @@ static VOID VgaChangePalette(BYTE ModeNumber)
|
|||
VgaSetPalette(Palette, Size);
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
static VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page)
|
||||
{
|
||||
/* Make sure the selected video page is valid */
|
||||
if (Page >= BIOS_MAX_PAGES) return;
|
||||
|
||||
/* Get the cursor location */
|
||||
*Row = HIBYTE(Bda->CursorPosition[Page]);
|
||||
*Column = LOBYTE(Bda->CursorPosition[Page]);
|
||||
}
|
||||
|
||||
static VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page)
|
||||
{
|
||||
/* Make sure the selected video page is valid */
|
||||
if (Page >= BIOS_MAX_PAGES) return;
|
||||
|
||||
/* Update the position in the BDA */
|
||||
Bda->CursorPosition[Page] = MAKEWORD(Column, Row);
|
||||
|
||||
/* Check if this is the current video page */
|
||||
if (Page == Bda->VideoPage)
|
||||
{
|
||||
WORD Offset = Row * Bda->ScreenColumns + Column;
|
||||
|
||||
/* Modify the CRTC registers */
|
||||
VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
|
||||
VgaWritePort(VGA_CRTC_DATA , LOBYTE(Offset));
|
||||
VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
|
||||
VgaWritePort(VGA_CRTC_DATA , HIBYTE(Offset));
|
||||
}
|
||||
}
|
||||
|
||||
BYTE BiosGetVideoMode(VOID)
|
||||
{
|
||||
return Bda->VideoMode;
|
||||
}
|
||||
|
||||
BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
|
||||
static BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
|
||||
{
|
||||
BYTE Page;
|
||||
|
||||
|
@ -870,6 +1031,14 @@ BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
|
|||
|
||||
VgaChangePalette(ModeNumber);
|
||||
|
||||
/*
|
||||
* IBM standard modes do not clear the screen if the
|
||||
* high bit of AL is set (EGA or higher only).
|
||||
* See Ralf Brown: http://www.ctyme.com/intr/rb-0069.htm
|
||||
* for more information.
|
||||
*/
|
||||
if ((ModeNumber & 0x08) == 0) VgaClearMemory();
|
||||
|
||||
// Bda->CrtModeControl;
|
||||
// Bda->CrtColorPaletteMask;
|
||||
// Bda->EGAFlags;
|
||||
|
@ -895,14 +1064,14 @@ BOOLEAN BiosSetVideoMode(BYTE ModeNumber)
|
|||
Bda->ScreenColumns = Resolution.X;
|
||||
Bda->ScreenRows = Resolution.Y - 1;
|
||||
|
||||
/* Set cursor position for each page */
|
||||
/* Set the cursor position for each page */
|
||||
for (Page = 0; Page < BIOS_MAX_PAGES; ++Page)
|
||||
BiosSetCursorPosition(0, 0, Page);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN BiosSetVideoPage(BYTE PageNumber)
|
||||
static BOOLEAN BiosSetVideoPage(BYTE PageNumber)
|
||||
{
|
||||
BYTE Row, Column;
|
||||
|
||||
|
@ -932,391 +1101,7 @@ BOOLEAN BiosSetVideoPage(BYTE PageNumber)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN BiosInitialize(VOID)
|
||||
{
|
||||
/* Initialize the BDA */
|
||||
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
||||
Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
|
||||
/*
|
||||
* Conventional memory size is 640 kB,
|
||||
* see: http://webpages.charter.net/danrollins/techhelp/0184.HTM
|
||||
* and see Ralf Brown: http://www.ctyme.com/intr/rb-0598.htm
|
||||
* for more information.
|
||||
*/
|
||||
Bda->MemorySize = 0x0280;
|
||||
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
|
||||
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
|
||||
Bda->KeybdBufferHead = Bda->KeybdBufferTail = 0;
|
||||
|
||||
/* Initialize the 32-bit Interrupt system */
|
||||
InitializeInt32(BIOS_SEGMENT);
|
||||
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
RegisterInt32(BIOS_VIDEO_INTERRUPT , BiosVideoService );
|
||||
RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
||||
RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
||||
RegisterInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
|
||||
RegisterInt32(BIOS_KBD_INTERRUPT , BiosKeyboardService );
|
||||
RegisterInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
|
||||
RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
|
||||
|
||||
/* Some interrupts are in fact addresses to tables */
|
||||
((PDWORD)BaseAddress)[0x1D] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x1E] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x1F] = (DWORD)NULL;
|
||||
|
||||
((PDWORD)BaseAddress)[0x41] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x43] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x44] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x46] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
|
||||
|
||||
/* Get the input handle to the real console, and check for success */
|
||||
BiosConsoleInput = CreateFileW(L"CONIN$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (BiosConsoleInput == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the output handle to the real console, and check for success */
|
||||
BiosConsoleOutput = CreateFileW(L"CONOUT$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (BiosConsoleOutput == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(BiosConsoleInput);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Save the console screen buffer information */
|
||||
if (!GetConsoleScreenBufferInfo(BiosConsoleOutput, &BiosSavedBufferInfo))
|
||||
{
|
||||
CloseHandle(BiosConsoleOutput);
|
||||
CloseHandle(BiosConsoleInput);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize VGA */
|
||||
if (!VgaInitialize(BiosConsoleOutput))
|
||||
{
|
||||
CloseHandle(BiosConsoleOutput);
|
||||
CloseHandle(BiosConsoleInput);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update the cursor position */
|
||||
BiosSetCursorPosition(BiosSavedBufferInfo.dwCursorPosition.Y,
|
||||
BiosSavedBufferInfo.dwCursorPosition.X,
|
||||
0);
|
||||
|
||||
/* Set the console input mode */
|
||||
SetConsoleMode(BiosConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||
|
||||
/* Initialize PS2 */
|
||||
PS2Initialize(BiosConsoleInput);
|
||||
|
||||
/* Initialize the PIC */
|
||||
PicWriteCommand(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
|
||||
PicWriteCommand(PIC_SLAVE_CMD , PIC_ICW1 | PIC_ICW1_ICW4);
|
||||
|
||||
/* Set the interrupt offsets */
|
||||
PicWriteData(PIC_MASTER_DATA, BIOS_PIC_MASTER_INT);
|
||||
PicWriteData(PIC_SLAVE_DATA , BIOS_PIC_SLAVE_INT);
|
||||
|
||||
/* Tell the master PIC there is a slave at IRQ 2 */
|
||||
PicWriteData(PIC_MASTER_DATA, 1 << 2);
|
||||
PicWriteData(PIC_SLAVE_DATA , 2);
|
||||
|
||||
/* Make sure the PIC is in 8086 mode */
|
||||
PicWriteData(PIC_MASTER_DATA, PIC_ICW4_8086);
|
||||
PicWriteData(PIC_SLAVE_DATA , PIC_ICW4_8086);
|
||||
|
||||
/* Clear the masks for both PICs */
|
||||
PicWriteData(PIC_MASTER_DATA, 0x00);
|
||||
PicWriteData(PIC_SLAVE_DATA , 0x00);
|
||||
|
||||
PitWriteCommand(0x34);
|
||||
PitWriteData(0, 0x00);
|
||||
PitWriteData(0, 0x00);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID BiosCleanup(VOID)
|
||||
{
|
||||
PS2Cleanup();
|
||||
|
||||
/* Restore the old screen buffer */
|
||||
SetConsoleActiveScreenBuffer(BiosConsoleOutput);
|
||||
|
||||
/* Restore the screen buffer size */
|
||||
SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize);
|
||||
|
||||
/* Close the console handles */
|
||||
if (BiosConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleOutput);
|
||||
if (BiosConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleInput);
|
||||
}
|
||||
|
||||
WORD BiosPeekCharacter(VOID)
|
||||
{
|
||||
WORD CharacterData = 0;
|
||||
|
||||
/* Get the key from the queue, but don't remove it */
|
||||
if (BiosKbdBufferTop(&CharacterData)) return CharacterData;
|
||||
else return 0xFFFF;
|
||||
}
|
||||
|
||||
WORD BiosGetCharacter(VOID)
|
||||
{
|
||||
WORD CharacterData = 0;
|
||||
|
||||
/* Check if there is a key available */
|
||||
if (BiosKbdBufferTop(&CharacterData))
|
||||
{
|
||||
/* A key was available, remove it from the queue */
|
||||
BiosKbdBufferPop();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No key available. Set the handler CF to repeat the BOP */
|
||||
setCF(1);
|
||||
// CharacterData = 0xFFFF;
|
||||
}
|
||||
|
||||
return CharacterData;
|
||||
}
|
||||
|
||||
VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page)
|
||||
{
|
||||
/* Make sure the selected video page is valid */
|
||||
if (Page >= BIOS_MAX_PAGES) return;
|
||||
|
||||
/* Get the cursor location */
|
||||
*Row = HIBYTE(Bda->CursorPosition[Page]);
|
||||
*Column = LOBYTE(Bda->CursorPosition[Page]);
|
||||
}
|
||||
|
||||
VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page)
|
||||
{
|
||||
/* Make sure the selected video page is valid */
|
||||
if (Page >= BIOS_MAX_PAGES) return;
|
||||
|
||||
/* Update the position in the BDA */
|
||||
Bda->CursorPosition[Page] = MAKEWORD(Column, Row);
|
||||
|
||||
/* Check if this is the current video page */
|
||||
if (Page == Bda->VideoPage)
|
||||
{
|
||||
WORD Offset = Row * Bda->ScreenColumns + Column;
|
||||
|
||||
/* Modify the CRTC registers */
|
||||
VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG);
|
||||
VgaWritePort(VGA_CRTC_DATA , LOBYTE(Offset));
|
||||
VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG);
|
||||
VgaWritePort(VGA_CRTC_DATA , HIBYTE(Offset));
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN BiosScrollWindow(INT Direction,
|
||||
DWORD Amount,
|
||||
SMALL_RECT Rectangle,
|
||||
BYTE Page,
|
||||
BYTE FillAttribute)
|
||||
{
|
||||
DWORD i;
|
||||
LPWORD WindowData;
|
||||
WORD WindowWidth = Rectangle.Right - Rectangle.Left + 1;
|
||||
WORD WindowHeight = Rectangle.Bottom - Rectangle.Top + 1;
|
||||
DWORD WindowSize = WindowWidth * WindowHeight;
|
||||
|
||||
/* Allocate a buffer for the window */
|
||||
WindowData = (LPWORD)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
WindowSize * sizeof(WORD));
|
||||
if (WindowData == NULL) return FALSE;
|
||||
|
||||
/* Read the window data */
|
||||
BiosReadWindow(WindowData, Rectangle, Page);
|
||||
|
||||
if ((Amount == 0)
|
||||
|| (((Direction == SCROLL_DIRECTION_UP)
|
||||
|| (Direction == SCROLL_DIRECTION_DOWN))
|
||||
&& (Amount >= WindowHeight))
|
||||
|| (((Direction == SCROLL_DIRECTION_LEFT)
|
||||
|| (Direction == SCROLL_DIRECTION_RIGHT))
|
||||
&& (Amount >= WindowWidth)))
|
||||
{
|
||||
/* Fill the window */
|
||||
for (i = 0; i < WindowSize; i++)
|
||||
{
|
||||
WindowData[i] = MAKEWORD(' ', FillAttribute);
|
||||
}
|
||||
|
||||
goto Done;
|
||||
}
|
||||
|
||||
switch (Direction)
|
||||
{
|
||||
case SCROLL_DIRECTION_UP:
|
||||
{
|
||||
RtlMoveMemory(WindowData,
|
||||
&WindowData[WindowWidth * Amount],
|
||||
(WindowSize - WindowWidth * Amount) * sizeof(WORD));
|
||||
|
||||
for (i = 0; i < Amount * WindowWidth; i++)
|
||||
{
|
||||
WindowData[WindowSize - i - 1] = MAKEWORD(' ', FillAttribute);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SCROLL_DIRECTION_DOWN:
|
||||
{
|
||||
RtlMoveMemory(&WindowData[WindowWidth * Amount],
|
||||
WindowData,
|
||||
(WindowSize - WindowWidth * Amount) * sizeof(WORD));
|
||||
|
||||
for (i = 0; i < Amount * WindowWidth; i++)
|
||||
{
|
||||
WindowData[i] = MAKEWORD(' ', FillAttribute);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED!
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
||||
Done:
|
||||
/* Write back the window data */
|
||||
BiosWriteWindow(WindowData, Rectangle, Page);
|
||||
|
||||
/* Free the window buffer */
|
||||
HeapFree(GetProcessHeap(), 0, WindowData);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page)
|
||||
{
|
||||
WORD CharData = MAKEWORD(Character, Attribute);
|
||||
BYTE Row, Column;
|
||||
|
||||
/* Make sure the page exists */
|
||||
if (Page >= BIOS_MAX_PAGES) return;
|
||||
|
||||
/* Get the cursor location */
|
||||
BiosGetCursorPosition(&Row, &Column, Page);
|
||||
|
||||
if (Character == '\a')
|
||||
{
|
||||
/* Bell control character */
|
||||
// NOTE: We may use what the terminal emulator offers to us...
|
||||
Beep(800, 200);
|
||||
return;
|
||||
}
|
||||
else if (Character == '\b')
|
||||
{
|
||||
/* Backspace control character */
|
||||
if (Column > 0)
|
||||
{
|
||||
Column--;
|
||||
}
|
||||
else if (Row > 0)
|
||||
{
|
||||
Column = Bda->ScreenColumns - 1;
|
||||
Row--;
|
||||
}
|
||||
|
||||
/* Erase the existing character */
|
||||
CharData = MAKEWORD(' ', Attribute);
|
||||
EmulatorWriteMemory(&EmulatorContext,
|
||||
TO_LINEAR(TEXT_VIDEO_SEG,
|
||||
Page * Bda->VideoPageSize +
|
||||
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
|
||||
(LPVOID)&CharData,
|
||||
sizeof(WORD));
|
||||
}
|
||||
else if (Character == '\t')
|
||||
{
|
||||
/* Horizontal Tabulation control character */
|
||||
do
|
||||
{
|
||||
// Taken from DOSBox
|
||||
BiosPrintCharacter(' ', Attribute, Page);
|
||||
BiosGetCursorPosition(&Row, &Column, Page);
|
||||
} while (Column % 8);
|
||||
}
|
||||
else if (Character == '\n')
|
||||
{
|
||||
/* Line Feed control character */
|
||||
Row++;
|
||||
}
|
||||
else if (Character == '\r')
|
||||
{
|
||||
/* Carriage Return control character */
|
||||
Column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default character */
|
||||
|
||||
/* Write the character */
|
||||
EmulatorWriteMemory(&EmulatorContext,
|
||||
TO_LINEAR(TEXT_VIDEO_SEG,
|
||||
Page * Bda->VideoPageSize +
|
||||
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
|
||||
(LPVOID)&CharData,
|
||||
sizeof(WORD));
|
||||
|
||||
/* Advance the cursor */
|
||||
Column++;
|
||||
}
|
||||
|
||||
/* Check if it passed the end of the row */
|
||||
if (Column >= Bda->ScreenColumns)
|
||||
{
|
||||
/* Return to the first column and go to the next line */
|
||||
Column = 0;
|
||||
Row++;
|
||||
}
|
||||
|
||||
/* Scroll the screen up if needed */
|
||||
if (Row > Bda->ScreenRows)
|
||||
{
|
||||
/* The screen must be scrolled up */
|
||||
SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows };
|
||||
|
||||
BiosScrollWindow(SCROLL_DIRECTION_UP,
|
||||
1,
|
||||
Rectangle,
|
||||
Page,
|
||||
DEFAULT_ATTRIBUTE);
|
||||
|
||||
Row--;
|
||||
}
|
||||
|
||||
/* Set the cursor position */
|
||||
BiosSetCursorPosition(Row, Column, Page);
|
||||
}
|
||||
|
||||
VOID WINAPI BiosVideoService(LPWORD Stack)
|
||||
static VOID WINAPI BiosVideoService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
|
@ -1324,7 +1109,6 @@ VOID WINAPI BiosVideoService(LPWORD Stack)
|
|||
case 0x00:
|
||||
{
|
||||
BiosSetVideoMode(getAL());
|
||||
VgaClearMemory();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1698,19 +1482,19 @@ VOID WINAPI BiosVideoService(LPWORD Stack)
|
|||
}
|
||||
}
|
||||
|
||||
VOID WINAPI BiosEquipmentService(LPWORD Stack)
|
||||
static VOID WINAPI BiosEquipmentService(LPWORD Stack)
|
||||
{
|
||||
/* Return the equipment list */
|
||||
setAX(Bda->EquipmentList);
|
||||
}
|
||||
|
||||
VOID WINAPI BiosGetMemorySize(LPWORD Stack)
|
||||
static VOID WINAPI BiosGetMemorySize(LPWORD Stack)
|
||||
{
|
||||
/* Return the conventional memory size in kB, typically 640 kB */
|
||||
setAX(Bda->MemorySize);
|
||||
}
|
||||
|
||||
VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||
static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
|
@ -1766,7 +1550,7 @@ VOID WINAPI BiosMiscService(LPWORD Stack)
|
|||
}
|
||||
}
|
||||
|
||||
VOID WINAPI BiosKeyboardService(LPWORD Stack)
|
||||
static VOID WINAPI BiosKeyboardService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
|
@ -1848,7 +1632,7 @@ VOID WINAPI BiosKeyboardService(LPWORD Stack)
|
|||
}
|
||||
}
|
||||
|
||||
VOID WINAPI BiosTimeService(LPWORD Stack)
|
||||
static VOID WINAPI BiosTimeService(LPWORD Stack)
|
||||
{
|
||||
switch (getAH())
|
||||
{
|
||||
|
@ -1886,12 +1670,305 @@ VOID WINAPI BiosTimeService(LPWORD Stack)
|
|||
}
|
||||
}
|
||||
|
||||
VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack)
|
||||
static VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack)
|
||||
{
|
||||
/* Increase the system tick count */
|
||||
Bda->TickCounter++;
|
||||
}
|
||||
|
||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||
|
||||
WORD BiosPeekCharacter(VOID)
|
||||
{
|
||||
WORD CharacterData = 0;
|
||||
|
||||
/* Get the key from the queue, but don't remove it */
|
||||
if (BiosKbdBufferTop(&CharacterData)) return CharacterData;
|
||||
else return 0xFFFF;
|
||||
}
|
||||
|
||||
WORD BiosGetCharacter(VOID)
|
||||
{
|
||||
WORD CharacterData = 0;
|
||||
|
||||
/* Check if there is a key available */
|
||||
if (BiosKbdBufferTop(&CharacterData))
|
||||
{
|
||||
/* A key was available, remove it from the queue */
|
||||
BiosKbdBufferPop();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No key available. Set the handler CF to repeat the BOP */
|
||||
setCF(1);
|
||||
// CharacterData = 0xFFFF;
|
||||
}
|
||||
|
||||
return CharacterData;
|
||||
}
|
||||
|
||||
VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page)
|
||||
{
|
||||
WORD CharData = MAKEWORD(Character, Attribute);
|
||||
BYTE Row, Column;
|
||||
|
||||
/* Make sure the page exists */
|
||||
if (Page >= BIOS_MAX_PAGES) return;
|
||||
|
||||
/* Get the cursor location */
|
||||
BiosGetCursorPosition(&Row, &Column, Page);
|
||||
|
||||
if (Character == '\a')
|
||||
{
|
||||
/* Bell control character */
|
||||
// NOTE: We may use what the terminal emulator offers to us...
|
||||
Beep(800, 200);
|
||||
return;
|
||||
}
|
||||
else if (Character == '\b')
|
||||
{
|
||||
/* Backspace control character */
|
||||
if (Column > 0)
|
||||
{
|
||||
Column--;
|
||||
}
|
||||
else if (Row > 0)
|
||||
{
|
||||
Column = Bda->ScreenColumns - 1;
|
||||
Row--;
|
||||
}
|
||||
|
||||
/* Erase the existing character */
|
||||
CharData = MAKEWORD(' ', Attribute);
|
||||
EmulatorWriteMemory(&EmulatorContext,
|
||||
TO_LINEAR(TEXT_VIDEO_SEG,
|
||||
Page * Bda->VideoPageSize +
|
||||
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
|
||||
(LPVOID)&CharData,
|
||||
sizeof(WORD));
|
||||
}
|
||||
else if (Character == '\t')
|
||||
{
|
||||
/* Horizontal Tabulation control character */
|
||||
do
|
||||
{
|
||||
// Taken from DOSBox
|
||||
BiosPrintCharacter(' ', Attribute, Page);
|
||||
BiosGetCursorPosition(&Row, &Column, Page);
|
||||
} while (Column % 8);
|
||||
}
|
||||
else if (Character == '\n')
|
||||
{
|
||||
/* Line Feed control character */
|
||||
Row++;
|
||||
}
|
||||
else if (Character == '\r')
|
||||
{
|
||||
/* Carriage Return control character */
|
||||
Column = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Default character */
|
||||
|
||||
/* Write the character */
|
||||
EmulatorWriteMemory(&EmulatorContext,
|
||||
TO_LINEAR(TEXT_VIDEO_SEG,
|
||||
Page * Bda->VideoPageSize +
|
||||
(Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
|
||||
(LPVOID)&CharData,
|
||||
sizeof(WORD));
|
||||
|
||||
/* Advance the cursor */
|
||||
Column++;
|
||||
}
|
||||
|
||||
/* Check if it passed the end of the row */
|
||||
if (Column >= Bda->ScreenColumns)
|
||||
{
|
||||
/* Return to the first column and go to the next line */
|
||||
Column = 0;
|
||||
Row++;
|
||||
}
|
||||
|
||||
/* Scroll the screen up if needed */
|
||||
if (Row > Bda->ScreenRows)
|
||||
{
|
||||
/* The screen must be scrolled up */
|
||||
SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows };
|
||||
|
||||
BiosScrollWindow(SCROLL_DIRECTION_UP,
|
||||
1,
|
||||
Rectangle,
|
||||
Page,
|
||||
DEFAULT_ATTRIBUTE);
|
||||
|
||||
Row--;
|
||||
}
|
||||
|
||||
/* Set the cursor position */
|
||||
BiosSetCursorPosition(Row, Column, Page);
|
||||
}
|
||||
|
||||
BOOLEAN BiosInitialize(VOID)
|
||||
{
|
||||
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
|
||||
|
||||
/* Initialize the BDA */
|
||||
Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
|
||||
Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
|
||||
/*
|
||||
* Conventional memory size is 640 kB,
|
||||
* see: http://webpages.charter.net/danrollins/techhelp/0184.HTM
|
||||
* and see Ralf Brown: http://www.ctyme.com/intr/rb-0598.htm
|
||||
* for more information.
|
||||
*/
|
||||
Bda->MemorySize = 0x0280;
|
||||
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
|
||||
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
|
||||
Bda->KeybdBufferHead = Bda->KeybdBufferTail = 0;
|
||||
|
||||
/* Initialize the 32-bit Interrupt system */
|
||||
InitializeInt32(BIOS_SEGMENT);
|
||||
|
||||
/* Register the BIOS 32-bit Interrupts */
|
||||
RegisterInt32(BIOS_VIDEO_INTERRUPT , BiosVideoService );
|
||||
RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
|
||||
RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
|
||||
RegisterInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
|
||||
RegisterInt32(BIOS_KBD_INTERRUPT , BiosKeyboardService );
|
||||
RegisterInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
|
||||
RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
|
||||
|
||||
/* Some interrupts are in fact addresses to tables */
|
||||
((PDWORD)BaseAddress)[0x1D] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x1E] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x1F] = (DWORD)NULL;
|
||||
|
||||
((PDWORD)BaseAddress)[0x41] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x43] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x44] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x46] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
|
||||
((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
|
||||
|
||||
/* Get the input handle to the real console, and check for success */
|
||||
BiosConsoleInput = CreateFileW(L"CONIN$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (BiosConsoleInput == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the output handle to the real console, and check for success */
|
||||
BiosConsoleOutput = CreateFileW(L"CONOUT$",
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL);
|
||||
if (BiosConsoleOutput == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(BiosConsoleInput);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Save the original console screen buffer information */
|
||||
if (!GetConsoleScreenBufferInfo(BiosConsoleOutput, &BiosSavedBufferInfo))
|
||||
{
|
||||
CloseHandle(BiosConsoleOutput);
|
||||
CloseHandle(BiosConsoleInput);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Initialize VGA */
|
||||
if (!VgaInitialize(BiosConsoleOutput))
|
||||
{
|
||||
CloseHandle(BiosConsoleOutput);
|
||||
CloseHandle(BiosConsoleInput);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set the default video mode */
|
||||
BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
|
||||
|
||||
/* Copy console data into VGA memory */
|
||||
BiosCopyTextConsoleToVgaMemory();
|
||||
|
||||
/* Update the cursor position for the current page (page 0) */
|
||||
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo);
|
||||
BiosSetCursorPosition(ConsoleInfo.dwCursorPosition.Y,
|
||||
ConsoleInfo.dwCursorPosition.X,
|
||||
Bda->VideoPage);
|
||||
|
||||
/* Set the console input mode */
|
||||
SetConsoleMode(BiosConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
|
||||
|
||||
/* Initialize PS2 */
|
||||
PS2Initialize(BiosConsoleInput);
|
||||
|
||||
/* Initialize the PIC */
|
||||
PicWriteCommand(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
|
||||
PicWriteCommand(PIC_SLAVE_CMD , PIC_ICW1 | PIC_ICW1_ICW4);
|
||||
|
||||
/* Set the interrupt offsets */
|
||||
PicWriteData(PIC_MASTER_DATA, BIOS_PIC_MASTER_INT);
|
||||
PicWriteData(PIC_SLAVE_DATA , BIOS_PIC_SLAVE_INT);
|
||||
|
||||
/* Tell the master PIC there is a slave at IRQ 2 */
|
||||
PicWriteData(PIC_MASTER_DATA, 1 << 2);
|
||||
PicWriteData(PIC_SLAVE_DATA , 2);
|
||||
|
||||
/* Make sure the PIC is in 8086 mode */
|
||||
PicWriteData(PIC_MASTER_DATA, PIC_ICW4_8086);
|
||||
PicWriteData(PIC_SLAVE_DATA , PIC_ICW4_8086);
|
||||
|
||||
/* Clear the masks for both PICs */
|
||||
PicWriteData(PIC_MASTER_DATA, 0x00);
|
||||
PicWriteData(PIC_SLAVE_DATA , 0x00);
|
||||
|
||||
PitWriteCommand(0x34);
|
||||
PitWriteData(0, 0x00);
|
||||
PitWriteData(0, 0x00);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID BiosCleanup(VOID)
|
||||
{
|
||||
SMALL_RECT ConRect;
|
||||
CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
|
||||
|
||||
PS2Cleanup();
|
||||
|
||||
/* Restore the old screen buffer */
|
||||
SetConsoleActiveScreenBuffer(BiosConsoleOutput);
|
||||
|
||||
/* Restore the original console size */
|
||||
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo);
|
||||
ConRect.Left = 0; // BiosSavedBufferInfo.srWindow.Left;
|
||||
// ConRect.Top = ConsoleInfo.dwCursorPosition.Y / (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1);
|
||||
// ConRect.Top *= (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1);
|
||||
ConRect.Top = ConsoleInfo.dwCursorPosition.Y;
|
||||
ConRect.Right = ConRect.Left + BiosSavedBufferInfo.srWindow.Right - BiosSavedBufferInfo.srWindow.Left;
|
||||
ConRect.Bottom = ConRect.Top + (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top);
|
||||
/* See the following trick explanation in vga.c:VgaEnterTextMode() */
|
||||
SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize);
|
||||
SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &ConRect);
|
||||
// SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &BiosSavedBufferInfo.srWindow);
|
||||
SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize);
|
||||
|
||||
/* Close the console handles */
|
||||
if (BiosConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleOutput);
|
||||
if (BiosConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleInput);
|
||||
}
|
||||
|
||||
VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
|
||||
{
|
||||
switch (IrqNumber)
|
||||
|
|
|
@ -151,31 +151,12 @@ C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
|
|||
|
||||
extern PBIOS_DATA_AREA Bda;
|
||||
|
||||
BOOLEAN BiosInitialize(VOID);
|
||||
VOID BiosCleanup(VOID);
|
||||
BYTE BiosGetVideoMode(VOID);
|
||||
BOOLEAN BiosSetVideoMode(BYTE ModeNumber);
|
||||
WORD BiosPeekCharacter(VOID);
|
||||
WORD BiosGetCharacter(VOID);
|
||||
VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page);
|
||||
VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page);
|
||||
VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page);
|
||||
BOOLEAN BiosScrollWindow(
|
||||
INT Direction,
|
||||
DWORD Amount,
|
||||
SMALL_RECT Rectangle,
|
||||
BYTE Page,
|
||||
BYTE FillAttribute
|
||||
);
|
||||
|
||||
VOID WINAPI BiosVideoService(LPWORD Stack);
|
||||
VOID WINAPI BiosEquipmentService(LPWORD Stack);
|
||||
VOID WINAPI BiosGetMemorySize(LPWORD Stack);
|
||||
VOID WINAPI BiosMiscService(LPWORD Stack);
|
||||
VOID WINAPI BiosKeyboardService(LPWORD Stack);
|
||||
VOID WINAPI BiosTimeService(LPWORD Stack);
|
||||
VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack);
|
||||
|
||||
BOOLEAN BiosInitialize(VOID);
|
||||
VOID BiosCleanup(VOID);
|
||||
VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack);
|
||||
|
||||
#endif // _BIOS_H_
|
||||
|
|
|
@ -171,8 +171,7 @@ static CONST COLORREF VgaDefaultPalette[VGA_MAX_COLORS] =
|
|||
|
||||
#endif
|
||||
|
||||
static HANDLE VgaSavedConsoleHandle = NULL;
|
||||
static CONSOLE_SCREEN_BUFFER_INFO VgaSavedConsoleInfo;
|
||||
static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
|
||||
|
||||
static BYTE VgaMemory[VGA_NUM_BANKS * VGA_BANK_SIZE];
|
||||
static LPVOID ConsoleFramebuffer = NULL;
|
||||
|
@ -234,15 +233,16 @@ static inline DWORD VgaGetAddressSize(VOID)
|
|||
/* Double-word addressing */
|
||||
return 4; // sizeof(DWORD)
|
||||
}
|
||||
|
||||
if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & VGA_CRTC_MODE_CONTROL_BYTE)
|
||||
else if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & VGA_CRTC_MODE_CONTROL_BYTE)
|
||||
{
|
||||
/* Byte addressing */
|
||||
return 1; // sizeof(BYTE)
|
||||
}
|
||||
|
||||
/* Word addressing */
|
||||
return 2; // sizeof(WORD)
|
||||
else
|
||||
{
|
||||
/* Word addressing */
|
||||
return 2; // sizeof(WORD)
|
||||
}
|
||||
}
|
||||
|
||||
static inline DWORD VgaTranslateReadAddress(DWORD Address)
|
||||
|
@ -611,8 +611,8 @@ static VOID VgaLeaveGraphicsMode(VOID)
|
|||
/* Release the console framebuffer mutex */
|
||||
ReleaseMutex(ConsoleMutex);
|
||||
|
||||
/* Switch back to the default console buffer */
|
||||
// SetConsoleActiveScreenBuffer(VgaSavedConsoleHandle);
|
||||
/* Switch back to the default console text buffer */
|
||||
// SetConsoleActiveScreenBuffer(TextConsoleBuffer);
|
||||
|
||||
/* Cleanup the video data */
|
||||
CloseHandle(ConsoleMutex);
|
||||
|
@ -630,8 +630,8 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
|
|||
SetConsoleActiveScreenBuffer(TextConsoleBuffer);
|
||||
|
||||
/* Resize the console */
|
||||
ConRect.Left = 0; // VgaSavedConsoleInfo.srWindow.Left;
|
||||
ConRect.Top = VgaSavedConsoleInfo.srWindow.Top;
|
||||
ConRect.Left = 0; // ConsoleInfo.srWindow.Left;
|
||||
ConRect.Top = ConsoleInfo.srWindow.Top;
|
||||
ConRect.Right = ConRect.Left + Resolution->X - 1;
|
||||
ConRect.Bottom = ConRect.Top + Resolution->Y - 1;
|
||||
/*
|
||||
|
@ -646,7 +646,7 @@ static BOOL VgaEnterTextMode(PCOORD Resolution)
|
|||
SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect);
|
||||
SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution);
|
||||
/* Update the saved console information */
|
||||
GetConsoleScreenBufferInfo(TextConsoleBuffer, &VgaSavedConsoleInfo);
|
||||
GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo);
|
||||
|
||||
/* Allocate a framebuffer */
|
||||
ConsoleFramebuffer = HeapAlloc(GetProcessHeap(),
|
||||
|
@ -690,9 +690,6 @@ static VOID VgaChangeMode(VOID)
|
|||
{
|
||||
COORD Resolution = VgaGetDisplayResolution();
|
||||
|
||||
/* Reset the mode change flag */
|
||||
// ModeChanged = FALSE;
|
||||
|
||||
if (ScreenMode == GRAPHICS_MODE)
|
||||
{
|
||||
/* Leave the current graphics mode */
|
||||
|
@ -929,7 +926,9 @@ static VOID VgaUpdateFramebuffer(VOID)
|
|||
else
|
||||
{
|
||||
/* Text mode */
|
||||
DWORD CurrentAddr;
|
||||
PCHAR_INFO CharBuffer = (PCHAR_INFO)ConsoleFramebuffer;
|
||||
CHAR_INFO CharInfo;
|
||||
|
||||
/* Loop through the scanlines */
|
||||
for (i = 0; i < Resolution.Y; i++)
|
||||
|
@ -937,8 +936,7 @@ static VOID VgaUpdateFramebuffer(VOID)
|
|||
/* Loop through the characters */
|
||||
for (j = 0; j < Resolution.X; j++)
|
||||
{
|
||||
DWORD CurrentAddr = LOWORD((Address + j) * AddressSize);
|
||||
CHAR_INFO CharInfo;
|
||||
CurrentAddr = LOWORD((Address + j) * AddressSize);
|
||||
|
||||
/* Plane 0 holds the character itself */
|
||||
CharInfo.Char.AsciiChar = VgaMemory[CurrentAddr];
|
||||
|
@ -976,7 +974,7 @@ static VOID VgaUpdateTextCursor(VOID)
|
|||
VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG]);
|
||||
|
||||
/* Just return if we are not in text mode */
|
||||
if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) != 0) return;
|
||||
if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) return;
|
||||
|
||||
if (CursorStart < CursorEnd)
|
||||
{
|
||||
|
@ -1078,15 +1076,15 @@ VOID VgaRefreshDisplay(VOID)
|
|||
if (!ModeChanged && !CursorMoved && !PaletteChanged && !NeedsUpdate)
|
||||
return;
|
||||
|
||||
/* Retrieve the current resolution */
|
||||
Resolution = VgaGetDisplayResolution();
|
||||
|
||||
/* Change the display mode */
|
||||
if (ModeChanged) VgaChangeMode();
|
||||
|
||||
/* Change the text cursor location */
|
||||
if (CursorMoved) VgaUpdateTextCursor();
|
||||
|
||||
/* Retrieve the current resolution */
|
||||
Resolution = VgaGetDisplayResolution();
|
||||
|
||||
if (PaletteChanged)
|
||||
{
|
||||
/* Trigger a full update of the screen */
|
||||
|
@ -1492,21 +1490,12 @@ VOID VgaResetPalette(VOID)
|
|||
|
||||
BOOLEAN VgaInitialize(HANDLE TextHandle)
|
||||
{
|
||||
INT i, j;
|
||||
COORD Resolution;
|
||||
DWORD AddressSize;
|
||||
DWORD ScanlineSize;
|
||||
COORD Origin = { 0, 0 };
|
||||
SMALL_RECT ScreenRect;
|
||||
PCHAR_INFO CharBuffer;
|
||||
DWORD Address = 0;
|
||||
DWORD CurrentAddr;
|
||||
/* Save the default text-mode console output handle */
|
||||
if (TextHandle == INVALID_HANDLE_VALUE) return FALSE;
|
||||
TextConsoleBuffer = TextHandle;
|
||||
|
||||
/* Save the console information */
|
||||
if (TextHandle == INVALID_HANDLE_VALUE) return FALSE;
|
||||
VgaSavedConsoleHandle = TextHandle;
|
||||
if (!GetConsoleScreenBufferInfo(VgaSavedConsoleHandle,
|
||||
&VgaSavedConsoleInfo))
|
||||
if (!GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1515,8 +1504,8 @@ BOOLEAN VgaInitialize(HANDLE TextHandle)
|
|||
if (!VgaInitializePalette()) return FALSE;
|
||||
/***/ VgaResetPalette(); /***/
|
||||
|
||||
/* Save the default text-mode console output handle */
|
||||
TextConsoleBuffer = TextHandle;
|
||||
/* Switch to the text buffer */
|
||||
SetConsoleActiveScreenBuffer(TextConsoleBuffer);
|
||||
|
||||
/* Clear the VGA memory */
|
||||
VgaClearMemory();
|
||||
|
@ -1536,45 +1525,6 @@ BOOLEAN VgaInitialize(HANDLE TextHandle)
|
|||
RegisterIoPort(0x3CE, VgaReadPort, VgaWritePort); // VGA_GC_INDEX
|
||||
RegisterIoPort(0x3CF, VgaReadPort, VgaWritePort); // VGA_GC_DATA
|
||||
|
||||
/* Set the default video mode */
|
||||
BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE);
|
||||
VgaChangeMode();
|
||||
|
||||
/* Get the data */
|
||||
Resolution = VgaGetDisplayResolution();
|
||||
CharBuffer = (PCHAR_INFO)ConsoleFramebuffer;
|
||||
AddressSize = VgaGetAddressSize();
|
||||
ScreenRect.Left = ScreenRect.Top = 0;
|
||||
ScreenRect.Right = Resolution.X;
|
||||
ScreenRect.Bottom = Resolution.Y;
|
||||
ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
|
||||
|
||||
/* Read the data from the console into the framebuffer */
|
||||
ReadConsoleOutputA(TextConsoleBuffer,
|
||||
CharBuffer,
|
||||
Resolution,
|
||||
Origin,
|
||||
&ScreenRect);
|
||||
|
||||
/* Loop through the scanlines */
|
||||
for (i = 0; i < Resolution.Y; i++)
|
||||
{
|
||||
/* Loop through the characters */
|
||||
for (j = 0; j < Resolution.X; j++)
|
||||
{
|
||||
CurrentAddr = LOWORD((Address + j) * AddressSize);
|
||||
|
||||
/* Store the character in plane 0 */
|
||||
VgaMemory[CurrentAddr] = CharBuffer[i * Resolution.X + j].Char.AsciiChar;
|
||||
|
||||
/* Store the attribute in plane 1 */
|
||||
VgaMemory[CurrentAddr + VGA_BANK_SIZE] = (BYTE)CharBuffer[i * Resolution.X + j].Attributes;
|
||||
}
|
||||
|
||||
/* Move to the next scanline */
|
||||
Address += ScanlineSize;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue