Author: aandrejevic
Date: Sat Jun 29 21:37:44 2013
New Revision: 59374
URL:
http://svn.reactos.org/svn/reactos?rev=59374&view=rev
Log:
[NTVDM]
Fix several bugs.
Implement some interrupt 1Ah services in the BIOS.
Modified:
branches/ntvdm/subsystems/ntvdm/bios.c
branches/ntvdm/subsystems/ntvdm/bios.h
branches/ntvdm/subsystems/ntvdm/dos.c
branches/ntvdm/subsystems/ntvdm/emulator.c
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 Jun 29 21:37:44 2013
@@ -22,6 +22,8 @@
static WORD BiosKbdBuffer[BIOS_KBD_BUFFER_SIZE];
static UINT BiosKbdBufferStart = 0, BiosKbdBufferEnd = 0;
static BOOLEAN BiosKbdBufferEmpty = TRUE;
+static DWORD BiosTickCount = 0;
+static BOOLEAN BiosPassedMidnight = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/
@@ -405,6 +407,44 @@
}
}
+VOID BiosTimeService()
+{
+ DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
+ DWORD Ecx = EmulatorGetRegister(EMULATOR_REG_CX);
+ DWORD Edx = EmulatorGetRegister(EMULATOR_REG_DX);
+
+ switch (HIBYTE(Eax))
+ {
+ case 0x00:
+ {
+ /* Set AL to 1 if midnight had passed, 0 otherwise */
+ Eax &= 0xFFFFFF00;
+ if (BiosPassedMidnight) Eax |= 1;
+
+ /* Return the tick count in CX:DX */
+ EmulatorSetRegister(EMULATOR_REG_AX, Eax);
+ EmulatorSetRegister(EMULATOR_REG_CX, HIWORD(BiosTickCount));
+ EmulatorSetRegister(EMULATOR_REG_DX, LOWORD(BiosTickCount));
+
+ /* Reset the midnight flag */
+ BiosPassedMidnight = FALSE;
+
+ break;
+ }
+
+ case 0x01:
+ {
+ /* Set the tick count to CX:DX */
+ BiosTickCount = MAKELONG(LOWORD(Edx), LOWORD(Ecx));
+
+ /* Reset the midnight flag */
+ BiosPassedMidnight = FALSE;
+
+ break;
+ }
+ }
+}
+
VOID BiosHandleIrq(BYTE IrqNumber)
{
switch (IrqNumber)
@@ -412,6 +452,9 @@
/* PIT IRQ */
case 0:
{
+ /* Increase the system tick count */
+ BiosTickCount++;
+
/* Perform the system timer interrupt */
EmulatorInterrupt(0x1C);
Modified: branches/ntvdm/subsystems/ntvdm/bios.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.h?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] Sat Jun 29 21:37:44 2013
@@ -22,8 +22,9 @@
#define BIOS_PIC_MASTER_INT 0x08
#define BIOS_PIC_SLAVE_INT 0x70
#define BIOS_SEGMENT 0xF000
-#define VIDEO_BIOS_INTERRUPT 0x10
-#define VIDEO_KBD_INTERRUPT 0x16
+#define BIOS_VIDEO_INTERRUPT 0x10
+#define BIOS_KBD_INTERRUPT 0x16
+#define BIOS_TIME_INTERRUPT 0x1A
#define CONSOLE_FONT_HEIGHT 8
#define BIOS_KBD_BUFFER_SIZE 256
@@ -36,6 +37,7 @@
WORD BiosGetCharacter();
VOID BiosVideoService();
VOID BiosKeyboardService();
+VOID BiosTimeService();
VOID BiosHandleIrq(BYTE IrqNumber);
#endif
Modified: branches/ntvdm/subsystems/ntvdm/dos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] Sat Jun 29 21:37:44 2013
@@ -311,14 +311,7 @@
/* Initialize the handle table */
for (i = 0; i < 20; i++) PspBlock->HandleTable[i] = 0xFF;
- /* Did we get an environment segment? */
- if (!Environment)
- {
- /* No, copy the one from the parent */
- Environment = DosCopyEnvironmentBlock((CurrentPsp != SYSTEM_PSP)
- ? SEGMENT_TO_PSP(CurrentPsp)->EnvBlock
- : SYSTEM_ENV_BLOCK);
- }
+
PspBlock->EnvBlock = Environment;
@@ -342,13 +335,13 @@
BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock)
{
- BOOLEAN Success = FALSE;
+ BOOLEAN Success = FALSE, AllocatedEnvBlock = FALSE;
HANDLE FileHandle = INVALID_HANDLE_VALUE, FileMapping = NULL;
LPBYTE Address = NULL;
LPSTR ProgramFilePath, Parameters[128];
CHAR CommandLineCopy[128];
INT ParamCount = 0;
- WORD i, Segment, FileSize, ExeSize;
+ WORD i, Segment = 0, FileSize, ExeSize;
PIMAGE_DOS_HEADER Header;
PDWORD RelocationTable;
PWORD RelocWord;
@@ -392,6 +385,18 @@
Address = (LPBYTE)MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, 0);
if (Address == NULL) goto Cleanup;
+ /* Did we get an environment segment? */
+ if (!EnvBlock)
+ {
+ /* Set a flag to know if the environment block was allocated here */
+ AllocatedEnvBlock = TRUE;
+
+ /* No, copy the one from the parent */
+ EnvBlock = DosCopyEnvironmentBlock((CurrentPsp != SYSTEM_PSP)
+ ? SEGMENT_TO_PSP(CurrentPsp)->EnvBlock
+ : SYSTEM_ENV_BLOCK);
+ }
+
/* Check if this is an EXE file or a COM file */
if (Address[0] == 'M' && Address[1] == 'Z')
{
@@ -423,6 +428,7 @@
/* The process owns its own memory */
DosChangeMemoryOwner(Segment, Segment);
+ DosChangeMemoryOwner(EnvBlock, Segment);
/* Copy the program to Segment:0100 */
RtlCopyMemory((PVOID)((ULONG_PTR)BaseAddress
@@ -456,7 +462,8 @@
/* Execute */
CurrentPsp = Segment;
DiskTransferArea = MAKELONG(0x80, Segment);
- EmulatorExecute(Segment + Header->e_cs, sizeof(DOS_PSP) + Header->e_ip);
+ EmulatorExecute(Segment + Header->e_cs + (sizeof(DOS_PSP) >> 4),
+ Header->e_ip);
Success = TRUE;
}
@@ -496,6 +503,13 @@
}
Cleanup:
+ if (!Success)
+ {
+ /* It was not successful, cleanup the DOS memory */
+ if (AllocatedEnvBlock) DosFreeMemory(EnvBlock);
+ if (Segment) DosFreeMemory(Segment);
+ }
+
/* Unmap the file*/
if (Address != NULL) UnmapViewOfFile(Address);
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Sat Jun 29 21:37:44 2013
@@ -199,27 +199,35 @@
{
/* It was an IRQ from the master PIC */
BiosHandleIrq(IntNum - BIOS_PIC_MASTER_INT);
+ return;
}
else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum <
BIOS_PIC_SLAVE_INT + 8)
{
/* It was an IRQ from the slave PIC */
BiosHandleIrq(IntNum - BIOS_PIC_SLAVE_INT + 8);
+ return;
}
switch (IntNum)
{
- case VIDEO_BIOS_INTERRUPT:
+ case BIOS_VIDEO_INTERRUPT:
{
/* This is the video BIOS interrupt, call the BIOS */
BiosVideoService();
break;
}
- case VIDEO_KBD_INTERRUPT:
+ case BIOS_KBD_INTERRUPT:
{
/* This is the keyboard BIOS interrupt, call the BIOS */
BiosKeyboardService();
break;
}
+ case BIOS_TIME_INTERRUPT:
+ {
+ /* This is the time BIOS interrupt, call the BIOS */
+ BiosTimeService();
+ break;
+ }
case 0x20:
{
DosInt20h(CodeSegment);
@@ -233,6 +241,11 @@
case 0x23:
{
DosBreakInterrupt();
+ break;
+ }
+ default:
+ {
+ DPRINT1("Unhandled interrupt: 0x%02X\n", IntNum);
break;
}
}