Author: aandrejevic
Date: Sat Aug 17 18:44:16 2013
New Revision: 59764
URL:
http://svn.reactos.org/svn/reactos?rev=59764&view=rev
Log:
[SOFT386]
Implement Soft386LoadSegment.
[NTVDM]
Fix BiosPrintCharacter (Adapted from a patch by Hermes Belusca-Maito).
Modified:
branches/ntvdm/lib/soft386/common.c
branches/ntvdm/lib/soft386/common.h
branches/ntvdm/subsystems/ntvdm/bios.c
Modified: branches/ntvdm/lib/soft386/common.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.c?rev=…
==============================================================================
--- branches/ntvdm/lib/soft386/common.c [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/common.c [iso-8859-1] Sat Aug 17 18:44:16 2013
@@ -10,6 +10,16 @@
#include "common.h"
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static
+inline
+INT
+Soft386GetCurrentPrivLevel(PSOFT386_STATE State)
+{
+ return GET_SEGMENT_RPL(State->SegmentRegs[SOFT386_REG_CS].Selector);
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
inline
@@ -48,7 +58,7 @@
return FALSE;
}
- if (GET_SEGMENT_DPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
+ if (GET_SEGMENT_RPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
{
// TODO: Generate exception #GP
return FALSE;
@@ -131,7 +141,7 @@
return FALSE;
}
- if (GET_SEGMENT_DPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
+ if (GET_SEGMENT_RPL(CachedDescriptor->Selector) >
CachedDescriptor->Dpl)
{
// TODO: Generate exception #GP
return FALSE;
@@ -299,4 +309,114 @@
return TRUE;
}
+inline
+BOOLEAN
+Soft386LoadSegment(PSOFT386_STATE State, INT Segment, WORD Selector)
+{
+ PSOFT386_SEG_REG CachedDescriptor;
+ SOFT386_GDT_ENTRY GdtEntry;
+
+ ASSERT(Segment < SOFT386_NUM_SEG_REGS);
+
+ /* Get the cached descriptor */
+ CachedDescriptor = &State->SegmentRegs[Segment];
+
+ /* Check for protected mode */
+ if (State->ControlRegisters[SOFT386_REG_CR0] & SOFT386_CR0_PE)
+ {
+ /* Make sure the GDT contains the entry */
+ if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1))
+ {
+ // TODO: Exception #GP
+ return FALSE;
+ }
+
+ /* Read the GDT */
+ // FIXME: This code is only correct when paging is disabled!!!
+ if (State->MemReadCallback)
+ {
+ State->MemReadCallback(State,
+ State->Gdtr.Address
+ + GET_SEGMENT_INDEX(Selector),
+ &GdtEntry,
+ sizeof(GdtEntry));
+ }
+ else
+ {
+ RtlMoveMemory(&GdtEntry,
+ (LPVOID)(State->Gdtr.Address
+ + GET_SEGMENT_INDEX(Selector)),
+ sizeof(GdtEntry));
+ }
+
+ /* Check if we are loading SS */
+ if (Segment == SOFT386_REG_SS)
+ {
+ if (GET_SEGMENT_INDEX(Selector) == 0)
+ {
+ // TODO: Exception #GP
+ return FALSE;
+ }
+
+ if (GdtEntry.Executable || !GdtEntry.ReadWrite)
+ {
+ // TODO: Exception #GP
+ return FALSE;
+ }
+
+ if ((GET_SEGMENT_RPL(Selector) != Soft386GetCurrentPrivLevel(State))
+ || (GET_SEGMENT_RPL(Selector) != GdtEntry.Dpl))
+ {
+ // TODO: Exception #GP
+ return FALSE;
+ }
+
+ if (!GdtEntry.Present)
+ {
+ // TODO: Exception #SS
+ return FALSE;
+ }
+ }
+ else
+ {
+ if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl)
+ && (Soft386GetCurrentPrivLevel(State) > GdtEntry.Dpl))
+ {
+ // TODO: Exception #GP
+ return FALSE;
+ }
+
+ if (!GdtEntry.Present)
+ {
+ // TODO: Exception #NP
+ return FALSE;
+ }
+ }
+
+ /* Update the cache entry */
+ CachedDescriptor->Selector = Selector;
+ CachedDescriptor->Base = GdtEntry.Base | (GdtEntry.BaseHigh << 24);
+ CachedDescriptor->Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16);
+ CachedDescriptor->Accessed = GdtEntry.Accessed;
+ CachedDescriptor->ReadWrite = GdtEntry.ReadWrite;
+ CachedDescriptor->DirConf = GdtEntry.DirConf;
+ CachedDescriptor->Executable = GdtEntry.Executable;
+ CachedDescriptor->SystemType = GdtEntry.SystemType;
+ CachedDescriptor->Dpl = GdtEntry.Dpl;
+ CachedDescriptor->Present = GdtEntry.Present;
+ CachedDescriptor->Size = GdtEntry.Size;
+
+ /* Check for page granularity */
+ if (GdtEntry.Granularity) CachedDescriptor->Limit <<= 12;
+ }
+ else
+ {
+ /* Update the selector and base */
+ CachedDescriptor->Selector = Selector;
+ CachedDescriptor->Base = Selector << 4;
+ }
+
+ return TRUE;
+}
+
/* EOF */
Modified: branches/ntvdm/lib/soft386/common.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/lib/soft386/common.h?rev=…
==============================================================================
--- branches/ntvdm/lib/soft386/common.h [iso-8859-1] (original)
+++ branches/ntvdm/lib/soft386/common.h [iso-8859-1] Sat Aug 17 18:44:16 2013
@@ -15,7 +15,8 @@
/* DEFINES ********************************************************************/
-#define GET_SEGMENT_DPL(s) ((s) & 3)
+#define GET_SEGMENT_RPL(s) ((s) & 3)
+#define GET_SEGMENT_INDEX(s) ((s) & 0xFFF8)
/* FUNCTIONS ******************************************************************/
@@ -58,6 +59,15 @@
PULONG Value
);
+inline
+BOOLEAN
+Soft386LoadSegment
+(
+ PSOFT386_STATE State,
+ INT Segment,
+ WORD Selector
+);
+
#endif // _COMMON_H_
/* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/bios.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Sat Aug 17 18:44:16 2013
@@ -356,7 +356,7 @@
{
Character = Buffer[Counter++];
- /* Read from video memory */
+ /* Write to video memory */
VgaWriteMemory(VideoAddress + (i * Bda->ScreenColumns + j) *
sizeof(WORD),
(LPVOID)&Character,
sizeof(WORD));
@@ -701,33 +701,78 @@
Row = HIBYTE(Bda->CursorPosition[Page]);
Column = LOBYTE(Bda->CursorPosition[Page]);
- /* Write the character */
- VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG,
- (Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
- (LPVOID)&CharData,
- sizeof(WORD));
-
- /* Advance the cursor */
- Column++;
+ 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 = (Attribute << 8) | ' ';
+ VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG,
+ Page * Bda->VideoPageSize
+ + (Row * Bda->ScreenColumns + Column) * sizeof(WORD)),
+ (LPVOID)&CharData,
+ sizeof(WORD));
+ }
+ 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 */
+ VgaWriteMemory(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 */
+ if (Column >= Bda->ScreenColumns)
+ {
+ /* Return to the first column and go to the next line */
Column = 0;
-
- if (Row == Bda->ScreenRows)
- {
- /* The screen must be scrolled */
- SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows
};
-
- BiosScrollWindow(SCROLL_DIRECTION_UP,
- 1,
- Rectangle,
- Page,
- DEFAULT_ATTRIBUTE);
- }
- else Row++;
+ 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);
}
/* Set the cursor position */
@@ -820,8 +865,8 @@
};
/* Call the internal function */
- BiosScrollWindow((HIBYTE(Eax) == 0x06)
- ? SCROLL_DIRECTION_UP : SCROLL_DIRECTION_DOWN,
+ BiosScrollWindow((HIBYTE(Eax) == 0x06) ? SCROLL_DIRECTION_UP
+ : SCROLL_DIRECTION_DOWN,
LOBYTE(Eax),
Rectangle,
Bda->VideoPage,