mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:42:57 +00:00
[NTVDM]
Add video pages support to INT 10h functions and memory access. [SOFTX86] Fix the opcode check for XLAT. svn path=/branches/ntvdm/; revision=59454
This commit is contained in:
parent
25cbe37d30
commit
be1d88e4b7
2 changed files with 97 additions and 18 deletions
4
lib/3rdparty/softx86/softx86/mov.c
vendored
4
lib/3rdparty/softx86/softx86/mov.c
vendored
|
@ -219,7 +219,7 @@ int Sfx86OpcodeExec_xlat(sx86_ubyte opcode,softx86_ctx* ctx)
|
||||||
else
|
else
|
||||||
seg = ctx->state->segment_override;
|
seg = ctx->state->segment_override;
|
||||||
|
|
||||||
if ((opcode&0xFC) == 0xD7) { // MOV reg,reg/mem or reg/mem,reg
|
if (opcode == 0xD7) { // MOV reg,reg/mem or reg/mem,reg
|
||||||
sx86_ubyte d;
|
sx86_ubyte d;
|
||||||
sx86_udword ofs;
|
sx86_udword ofs;
|
||||||
|
|
||||||
|
@ -239,7 +239,7 @@ int Sfx86OpcodeExec_xlat(sx86_ubyte opcode,softx86_ctx* ctx)
|
||||||
|
|
||||||
int Sfx86OpcodeDec_xlat(sx86_ubyte opcode,softx86_ctx* ctx,char buf[128])
|
int Sfx86OpcodeDec_xlat(sx86_ubyte opcode,softx86_ctx* ctx,char buf[128])
|
||||||
{
|
{
|
||||||
if ((opcode&0xFC) == 0xD7) { // XLAT
|
if (opcode == 0xD7) { // XLAT
|
||||||
strcpy(buf,"XLAT");
|
strcpy(buf,"XLAT");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,11 +72,31 @@ static INT BiosColorNumberToBits(DWORD Colors)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD BiosGetVideoPageSize()
|
||||||
|
{
|
||||||
|
INT i;
|
||||||
|
DWORD BufferSize = VideoModes[CurrentVideoMode].Width
|
||||||
|
* VideoModes[CurrentVideoMode].Height
|
||||||
|
* BiosColorNumberToBits(VideoModes[CurrentVideoMode].Colors)
|
||||||
|
/ 8;
|
||||||
|
|
||||||
|
for (i = 0; i < 32; i++) if ((1 << i) >= BufferSize) break;
|
||||||
|
|
||||||
|
return 1 << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BYTE BiosVideoAddressToPage(ULONG Address)
|
||||||
|
{
|
||||||
|
return (Address - (VideoModes[CurrentVideoMode].Segment << 4))
|
||||||
|
/ BiosGetVideoPageSize();
|
||||||
|
}
|
||||||
|
|
||||||
static COORD BiosVideoAddressToCoord(ULONG Address)
|
static COORD BiosVideoAddressToCoord(ULONG Address)
|
||||||
{
|
{
|
||||||
COORD Result = {0, 0};
|
COORD Result = {0, 0};
|
||||||
INT BitsPerPixel;
|
INT BitsPerPixel;
|
||||||
DWORD Offset = Address - (VideoModes[CurrentVideoMode].Segment << 4);
|
BYTE PageStart = BiosVideoAddressToPage(Address) * BiosGetVideoPageSize();
|
||||||
|
DWORD Offset = Address - (VideoModes[CurrentVideoMode].Segment << 4) - PageStart;
|
||||||
|
|
||||||
if (VideoModes[CurrentVideoMode].Text)
|
if (VideoModes[CurrentVideoMode].Text)
|
||||||
{
|
{
|
||||||
|
@ -403,6 +423,7 @@ VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
COORD Coordinates;
|
COORD Coordinates;
|
||||||
|
BYTE Page;
|
||||||
COORD Origin = { 0, 0 };
|
COORD Origin = { 0, 0 };
|
||||||
COORD UnitSize = { 1, 1 };
|
COORD UnitSize = { 1, 1 };
|
||||||
CHAR_INFO Character;
|
CHAR_INFO Character;
|
||||||
|
@ -419,6 +440,12 @@ VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress)
|
||||||
/* Get the coordinates */
|
/* Get the coordinates */
|
||||||
Coordinates = BiosVideoAddressToCoord(i);
|
Coordinates = BiosVideoAddressToCoord(i);
|
||||||
|
|
||||||
|
/* Get the page number */
|
||||||
|
Page = BiosVideoAddressToPage(i);
|
||||||
|
|
||||||
|
/* Make sure the page is valid */
|
||||||
|
if (Page >= VideoModes[CurrentVideoMode].Pages) continue;
|
||||||
|
|
||||||
/* Fill the rectangle structure */
|
/* Fill the rectangle structure */
|
||||||
Rect.Left = Coordinates.X;
|
Rect.Left = Coordinates.X;
|
||||||
Rect.Top = Coordinates.Y;
|
Rect.Top = Coordinates.Y;
|
||||||
|
@ -430,7 +457,7 @@ VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress)
|
||||||
Character.Attributes = *((PBYTE)((ULONG_PTR)BaseAddress + i + 1));
|
Character.Attributes = *((PBYTE)((ULONG_PTR)BaseAddress + i + 1));
|
||||||
|
|
||||||
/* Write the character */
|
/* Write the character */
|
||||||
WriteConsoleOutputA(BiosConsoleOutput,
|
WriteConsoleOutputA(ConsoleBuffers[Page],
|
||||||
&Character,
|
&Character,
|
||||||
UnitSize,
|
UnitSize,
|
||||||
Origin,
|
Origin,
|
||||||
|
@ -480,6 +507,7 @@ VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
COORD Coordinates;
|
COORD Coordinates;
|
||||||
|
BYTE Page;
|
||||||
WORD Attribute;
|
WORD Attribute;
|
||||||
DWORD CharsWritten;
|
DWORD CharsWritten;
|
||||||
|
|
||||||
|
@ -491,11 +519,17 @@ VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress)
|
||||||
/* Get the coordinates */
|
/* Get the coordinates */
|
||||||
Coordinates = BiosVideoAddressToCoord(i);
|
Coordinates = BiosVideoAddressToCoord(i);
|
||||||
|
|
||||||
|
/* Get the page number */
|
||||||
|
Page = BiosVideoAddressToPage(i);
|
||||||
|
|
||||||
|
/* Make sure the page is valid */
|
||||||
|
if (Page >= VideoModes[CurrentVideoMode].Pages) continue;
|
||||||
|
|
||||||
/* Check if this is a character byte or an attribute byte */
|
/* Check if this is a character byte or an attribute byte */
|
||||||
if ((i - (VideoModes[CurrentVideoMode].Segment << 4)) % 2 == 0)
|
if ((i - (VideoModes[CurrentVideoMode].Segment << 4)) % 2 == 0)
|
||||||
{
|
{
|
||||||
/* This is a regular character */
|
/* This is a regular character */
|
||||||
ReadConsoleOutputCharacterA(BiosConsoleOutput,
|
ReadConsoleOutputCharacterA(ConsoleBuffers[Page],
|
||||||
(LPSTR)((ULONG_PTR)BaseAddress + i),
|
(LPSTR)((ULONG_PTR)BaseAddress + i),
|
||||||
sizeof(CHAR),
|
sizeof(CHAR),
|
||||||
Coordinates,
|
Coordinates,
|
||||||
|
@ -504,7 +538,7 @@ VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is an attribute */
|
/* This is an attribute */
|
||||||
ReadConsoleOutputAttribute(BiosConsoleOutput,
|
ReadConsoleOutputAttribute(ConsoleBuffers[Page],
|
||||||
&Attribute,
|
&Attribute,
|
||||||
sizeof(CHAR),
|
sizeof(CHAR),
|
||||||
Coordinates,
|
Coordinates,
|
||||||
|
@ -614,7 +648,7 @@ VOID BiosVideoService()
|
||||||
/* Set the cursor */
|
/* Set the cursor */
|
||||||
CursorInfo.dwSize = (CursorHeight * 100) / CONSOLE_FONT_HEIGHT;
|
CursorInfo.dwSize = (CursorHeight * 100) / CONSOLE_FONT_HEIGHT;
|
||||||
CursorInfo.bVisible = !Invisible;
|
CursorInfo.bVisible = !Invisible;
|
||||||
SetConsoleCursorInfo(BiosConsoleOutput, &CursorInfo);
|
SetConsoleCursorInfo(ConsoleBuffers[CurrentVideoPage], &CursorInfo);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -622,10 +656,13 @@ VOID BiosVideoService()
|
||||||
/* Set Cursor Position */
|
/* Set Cursor Position */
|
||||||
case 0x02:
|
case 0x02:
|
||||||
{
|
{
|
||||||
|
/* Make sure the selected video page exists */
|
||||||
|
if (HIBYTE(Ebx) >= VideoModes[CurrentVideoMode].Pages) break;
|
||||||
|
|
||||||
Position.X = LOBYTE(Edx);
|
Position.X = LOBYTE(Edx);
|
||||||
Position.Y = HIBYTE(Edx);
|
Position.Y = HIBYTE(Edx);
|
||||||
|
|
||||||
SetConsoleCursorPosition(BiosConsoleOutput, Position);
|
SetConsoleCursorPosition(ConsoleBuffers[HIBYTE(Ebx)], Position);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,9 +671,13 @@ VOID BiosVideoService()
|
||||||
{
|
{
|
||||||
INT StartLine;
|
INT StartLine;
|
||||||
|
|
||||||
|
/* Make sure the selected video page exists */
|
||||||
|
if (HIBYTE(Ebx) >= VideoModes[CurrentVideoMode].Pages) break;
|
||||||
|
|
||||||
/* Retrieve the data */
|
/* Retrieve the data */
|
||||||
GetConsoleCursorInfo(BiosConsoleOutput, &CursorInfo);
|
GetConsoleCursorInfo(ConsoleBuffers[HIBYTE(Ebx)], &CursorInfo);
|
||||||
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ScreenBufferInfo);
|
GetConsoleScreenBufferInfo(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
|
&ScreenBufferInfo);
|
||||||
|
|
||||||
/* Find the first line */
|
/* Find the first line */
|
||||||
StartLine = 32 - ((CursorInfo.dwSize * 32) / 100);
|
StartLine = 32 - ((CursorInfo.dwSize * 32) / 100);
|
||||||
|
@ -650,6 +691,28 @@ VOID BiosVideoService()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Select Active Display Page */
|
||||||
|
case 0x05:
|
||||||
|
{
|
||||||
|
/* Check if the page exists */
|
||||||
|
if (LOBYTE(Eax) >= VideoModes[CurrentVideoMode].Pages) break;
|
||||||
|
|
||||||
|
/* Check if this is the same page */
|
||||||
|
if (LOBYTE(Eax) == CurrentVideoPage) break;
|
||||||
|
|
||||||
|
/* Change the video page */
|
||||||
|
CurrentVideoPage = LOBYTE(Eax);
|
||||||
|
|
||||||
|
/* Set the active page console buffer */
|
||||||
|
SetConsoleActiveScreenBuffer(ConsoleBuffers[CurrentVideoPage]);
|
||||||
|
|
||||||
|
/* Restore the cursor to (0, 0) */
|
||||||
|
Position.X = Position.Y = 0;
|
||||||
|
SetConsoleCursorPosition(BiosConsoleOutput, Position);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Scroll Up/Down Window */
|
/* Scroll Up/Down Window */
|
||||||
case 0x06:
|
case 0x06:
|
||||||
case 0x07:
|
case 0x07:
|
||||||
|
@ -664,7 +727,7 @@ VOID BiosVideoService()
|
||||||
if (HIBYTE(Eax) == 0x06) Position.Y = Rect.Top - LOBYTE(Eax);
|
if (HIBYTE(Eax) == 0x06) Position.Y = Rect.Top - LOBYTE(Eax);
|
||||||
else Position.Y = Rect.Top + LOBYTE(Eax);
|
else Position.Y = Rect.Top + LOBYTE(Eax);
|
||||||
|
|
||||||
ScrollConsoleScreenBuffer(BiosConsoleOutput,
|
ScrollConsoleScreenBuffer(ConsoleBuffers[CurrentVideoPage],
|
||||||
&Rect,
|
&Rect,
|
||||||
&Rect,
|
&Rect,
|
||||||
Position,
|
Position,
|
||||||
|
@ -677,15 +740,23 @@ VOID BiosVideoService()
|
||||||
{
|
{
|
||||||
COORD BufferSize = { 1, 1 }, Origin = { 0, 0 };
|
COORD BufferSize = { 1, 1 }, Origin = { 0, 0 };
|
||||||
|
|
||||||
|
/* Make sure the selected video page exists */
|
||||||
|
if (HIBYTE(Ebx) >= VideoModes[CurrentVideoMode].Pages) break;
|
||||||
|
|
||||||
/* Get the cursor position */
|
/* Get the cursor position */
|
||||||
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ScreenBufferInfo);
|
GetConsoleScreenBufferInfo(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
|
&ScreenBufferInfo);
|
||||||
|
|
||||||
/* Read at cursor position */
|
/* Read at cursor position */
|
||||||
Rect.Left = ScreenBufferInfo.dwCursorPosition.X;
|
Rect.Left = ScreenBufferInfo.dwCursorPosition.X;
|
||||||
Rect.Top = ScreenBufferInfo.dwCursorPosition.Y;
|
Rect.Top = ScreenBufferInfo.dwCursorPosition.Y;
|
||||||
|
|
||||||
/* Read the console output */
|
/* Read the console output */
|
||||||
ReadConsoleOutput(BiosConsoleOutput, &Character, BufferSize, Origin, &Rect);
|
ReadConsoleOutput(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
|
&Character,
|
||||||
|
BufferSize,
|
||||||
|
Origin,
|
||||||
|
&Rect);
|
||||||
|
|
||||||
/* Return the result */
|
/* Return the result */
|
||||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||||
|
@ -700,18 +771,22 @@ VOID BiosVideoService()
|
||||||
{
|
{
|
||||||
DWORD CharsWritten;
|
DWORD CharsWritten;
|
||||||
|
|
||||||
|
/* Make sure the selected video page exists */
|
||||||
|
if (HIBYTE(Ebx) >= VideoModes[CurrentVideoMode].Pages) break;
|
||||||
|
|
||||||
/* Get the cursor position */
|
/* Get the cursor position */
|
||||||
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ScreenBufferInfo);
|
GetConsoleScreenBufferInfo(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
|
&ScreenBufferInfo);
|
||||||
|
|
||||||
/* Write the attribute to the output */
|
/* Write the attribute to the output */
|
||||||
FillConsoleOutputAttribute(BiosConsoleOutput,
|
FillConsoleOutputAttribute(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
LOBYTE(Ebx),
|
LOBYTE(Ebx),
|
||||||
LOWORD(Ecx),
|
LOWORD(Ecx),
|
||||||
ScreenBufferInfo.dwCursorPosition,
|
ScreenBufferInfo.dwCursorPosition,
|
||||||
&CharsWritten);
|
&CharsWritten);
|
||||||
|
|
||||||
/* Write the character to the output */
|
/* Write the character to the output */
|
||||||
FillConsoleOutputCharacterA(BiosConsoleOutput,
|
FillConsoleOutputCharacterA(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
LOBYTE(Eax),
|
LOBYTE(Eax),
|
||||||
LOWORD(Ecx),
|
LOWORD(Ecx),
|
||||||
ScreenBufferInfo.dwCursorPosition,
|
ScreenBufferInfo.dwCursorPosition,
|
||||||
|
@ -725,11 +800,15 @@ VOID BiosVideoService()
|
||||||
{
|
{
|
||||||
DWORD CharsWritten;
|
DWORD CharsWritten;
|
||||||
|
|
||||||
|
/* Make sure the selected video page exists */
|
||||||
|
if (HIBYTE(Ebx) >= VideoModes[CurrentVideoMode].Pages) break;
|
||||||
|
|
||||||
/* Get the cursor position */
|
/* Get the cursor position */
|
||||||
GetConsoleScreenBufferInfo(BiosConsoleOutput, &ScreenBufferInfo);
|
GetConsoleScreenBufferInfo(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
|
&ScreenBufferInfo);
|
||||||
|
|
||||||
/* Write the character to the output */
|
/* Write the character to the output */
|
||||||
FillConsoleOutputCharacterA(BiosConsoleOutput,
|
FillConsoleOutputCharacterA(ConsoleBuffers[HIBYTE(Ebx)],
|
||||||
LOBYTE(Eax),
|
LOBYTE(Eax),
|
||||||
LOWORD(Ecx),
|
LOWORD(Ecx),
|
||||||
ScreenBufferInfo.dwCursorPosition,
|
ScreenBufferInfo.dwCursorPosition,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue