[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 26 Nov 2013 20:20:51 +0000 (20:20 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Tue, 26 Nov 2013 20:20:51 +0000 (20:20 +0000)
- Move some PS/2 initialization from bios.c to ps2.c
- NULLify interrupt entries which are in fact pointers to data tables.
- Add a framework for adding I/O port handlers.

svn path=/branches/ntvdm/; revision=61107

21 files changed:
subsystems/ntvdm/CMakeLists.txt
subsystems/ntvdm/bios.c
subsystems/ntvdm/cmos.c
subsystems/ntvdm/cmos.h
subsystems/ntvdm/dos.c
subsystems/ntvdm/emulator.c
subsystems/ntvdm/emulator.h
subsystems/ntvdm/io.c [new file with mode: 0644]
subsystems/ntvdm/io.h [new file with mode: 0644]
subsystems/ntvdm/ntvdm.c
subsystems/ntvdm/ntvdm.h
subsystems/ntvdm/pic.c
subsystems/ntvdm/pic.h
subsystems/ntvdm/ps2.c
subsystems/ntvdm/ps2.h
subsystems/ntvdm/registers.c
subsystems/ntvdm/speaker.c
subsystems/ntvdm/timer.c
subsystems/ntvdm/timer.h
subsystems/ntvdm/vga.c
subsystems/ntvdm/vga.h

index 45bf971..076c2c8 100644 (file)
@@ -10,6 +10,7 @@ list(APPEND SOURCE
     dos.c
     emulator.c
     int32.c
+    io.c
     pic.c
     ps2.c
     registers.c
index 183ceba..25294bc 100644 (file)
@@ -28,7 +28,6 @@ static BYTE BiosKeyboardMap[256];
 static HANDLE BiosConsoleInput  = INVALID_HANDLE_VALUE;
 static HANDLE BiosConsoleOutput = INVALID_HANDLE_VALUE;
 static CONSOLE_SCREEN_BUFFER_INFO BiosSavedBufferInfo;
-static HANDLE InputThread = NULL;
 
 /*
  * VGA Register Configurations for BIOS Video Modes
@@ -486,6 +485,18 @@ BOOLEAN BiosInitialize(VOID)
     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,
@@ -537,8 +548,8 @@ BOOLEAN BiosInitialize(VOID)
     /* Set the console input mode */
     SetConsoleMode(BiosConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
 
-    /* Start the input thread */
-    InputThread = CreateThread(NULL, 0, &InputThreadProc, BiosConsoleInput, 0, NULL);
+    /* Initialize PS2 */
+    PS2Initialize(BiosConsoleInput);
 
     /* Initialize the PIC */
     PicWriteCommand(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
@@ -569,8 +580,7 @@ BOOLEAN BiosInitialize(VOID)
 
 VOID BiosCleanup(VOID)
 {
-    /* Close the input thread handle */
-    if (InputThread != NULL) CloseHandle(InputThread);
+    PS2Cleanup();
 
     /* Restore the old screen buffer */
     SetConsoleActiveScreenBuffer(BiosConsoleOutput);
index 4b8a7f0..a49a57b 100644 (file)
@@ -10,7 +10,9 @@
 
 #define NDEBUG
 
+#include "emulator.h"
 #include "cmos.h"
+#include "io.h"
 #include "bios.h"
 #include "pic.h"
 
@@ -305,6 +307,19 @@ VOID CmosWriteData(BYTE Value)
     SelectedRegister = CMOS_REG_STATUS_D;
 }
 
+BYTE WINAPI CmosReadPort(ULONG Port)
+{
+    return CmosReadData();
+}
+
+VOID WINAPI CmosWritePort(ULONG Port, BYTE Data)
+{
+    if (Port == CMOS_ADDRESS_PORT)
+        CmosWriteAddress(Data);
+    else if (Port == CMOS_DATA_PORT)
+        CmosWriteData(Data);
+}
+
 DWORD RtcGetTicksPerSecond(VOID)
 {
     BYTE RateSelect = CmosMemory.StatusRegB & 0x0F;
@@ -415,6 +430,10 @@ BOOLEAN CmosInitialize(VOID)
     CmosMemory.Diagnostics    = 0x00;            // Diagnostics must not find any errors.
     CmosMemory.ShutdownStatus = 0x00;
 
+    /* Register the I/O Ports */
+    RegisterIoPort(CMOS_ADDRESS_PORT, NULL        , CmosWritePort);
+    RegisterIoPort(CMOS_DATA_PORT   , CmosReadPort, CmosWritePort);
+
     return TRUE;
 }
 
index 0e8d5f0..401cd08 100644 (file)
 #define CMOS_DEFAULT_STA 0x26
 #define CMOS_DEFAULT_STB CMOS_STB_24HOUR
 
-/* BCD-Binary conversion */
-#define BINARY_TO_BCD(x) (((x / 10) << 4) | (x % 10))
-#define BCD_TO_BINARY(x) (((x >> 4) * 10) + (x & 0x0F))
-
 #define WRITE_CMOS_DATA(Cmos, Value)    \
     ((Cmos).StatusRegB & CMOS_STB_BINARY) ? (Value) : BCD_TO_BINARY(Value)
 
@@ -129,9 +125,6 @@ C_ASSERT(sizeof(CMOS_MEMORY) == 0x40);
 /* FUNCTIONS ******************************************************************/
 
 BOOLEAN IsNmiEnabled(VOID);
-VOID CmosWriteAddress(BYTE Value);
-BYTE CmosReadData(VOID);
-VOID CmosWriteData(BYTE Value);
 DWORD RtcGetTicksPerSecond(VOID);
 VOID RtcPeriodicTick(VOID);
 VOID RtcTimeUpdate(VOID);
index 0a9de21..35e4c6f 100644 (file)
@@ -2580,7 +2580,9 @@ BOOLEAN DosInitialize(VOID)
     /* Register the DOS 32-bit Interrupts */
     RegisterInt32(0x20, DosInt20h        );
     RegisterInt32(0x21, DosInt21h        );
-    RegisterInt32(0x23, DosBreakInterrupt);
+//  RegisterInt32(0x22, DosInt22h        ); // Termination
+    RegisterInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
+//  RegisterInt32(0x24, DosInt24h        ); // Critical Error
     RegisterInt32(0x2F, DosInt2Fh        );
 
     return TRUE;
index 2dc3181..22617c5 100644 (file)
 #define NDEBUG
 
 #include "emulator.h"
-#include "cmos.h"
 #include "bios.h"
 #include "bop.h"
+#include "io.h"
 #include "registers.h"
-#include "dos.h"
-#include "speaker.h"
 #include "vga.h"
 #include "pic.h"
-#include "ps2.h"
-#include "timer.h"
 
 /* PRIVATE VARIABLES **********************************************************/
 
@@ -87,192 +83,6 @@ VOID WINAPI EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffe
     }
 }
 
-VOID WINAPI EmulatorReadIo(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
-{
-    INT i, j;
-    LPBYTE Address = (LPBYTE)Buffer;
-
-    UNREFERENCED_PARAMETER(State);
-
-    for (i = 0; i < DataCount; i++) for (j = 0; j < DataSize; j++)
-    {
-        ULONG CurrentPort = Port + j;
-
-        switch (CurrentPort)
-        {
-            case PIC_MASTER_CMD:
-            case PIC_SLAVE_CMD:
-            {
-                *(Address++) = PicReadCommand(CurrentPort);
-                break;
-            }
-
-            case PIC_MASTER_DATA:
-            case PIC_SLAVE_DATA:
-            {
-                *(Address++) = PicReadData(CurrentPort);
-                break;
-            }
-
-            case PIT_DATA_PORT(0):
-            case PIT_DATA_PORT(1):
-            case PIT_DATA_PORT(2):
-            {
-                *(Address++) = PitReadData(CurrentPort - PIT_DATA_PORT(0));
-                break;
-            }
-
-            case PS2_CONTROL_PORT:
-            {
-                *(Address++) = KeyboardReadStatus();
-                break;
-            }
-
-            case PS2_DATA_PORT:
-            {
-                *(Address++) = KeyboardReadData();
-                break;
-            }
-
-            case CMOS_DATA_PORT:
-            {
-                *(Address++) = CmosReadData();
-                break;
-            }
-
-            case SPEAKER_CONTROL_PORT:
-            {
-                *(Address++) = SpeakerReadStatus();
-                break;
-            }
-
-            case VGA_AC_WRITE:
-            case VGA_AC_READ:
-            case VGA_SEQ_INDEX:
-            case VGA_SEQ_DATA:
-            case VGA_DAC_READ_INDEX:
-            case VGA_DAC_WRITE_INDEX:
-            case VGA_DAC_DATA:
-            case VGA_MISC_READ:
-            case VGA_MISC_WRITE:
-            case VGA_CRTC_INDEX:
-            case VGA_CRTC_DATA:
-            case VGA_GC_INDEX:
-            case VGA_GC_DATA:
-            case VGA_STAT_MONO:
-            case VGA_STAT_COLOR:
-            {
-                *(Address++) = VgaReadPort(CurrentPort);
-                break;
-            }
-
-            default:
-            {
-                DPRINT1("Read from unknown port: 0x%X\n", CurrentPort);
-            }
-        }
-    }
-}
-
-VOID WINAPI EmulatorWriteIo(PFAST486_STATE State, ULONG Port, PVOID Buffer, ULONG DataCount, UCHAR DataSize)
-{
-    INT i, j;
-    LPBYTE Address = (LPBYTE)Buffer;
-
-    UNREFERENCED_PARAMETER(State);
-
-    for (i = 0; i < DataCount; i++) for (j = 0; j < DataSize; j++)
-    {
-        ULONG CurrentPort = Port + j;
-
-        switch (CurrentPort)
-        {
-            case PIT_COMMAND_PORT:
-            {
-                PitWriteCommand(*(Address++));
-                break;
-            }
-
-            case PIT_DATA_PORT(0):
-            case PIT_DATA_PORT(1):
-            case PIT_DATA_PORT(2):
-            {
-                PitWriteData(CurrentPort - PIT_DATA_PORT(0), *(Address++));
-                break;
-            }
-
-            case PIC_MASTER_CMD:
-            case PIC_SLAVE_CMD:
-            {
-                PicWriteCommand(CurrentPort, *(Address++));
-                break;
-            }
-
-            case PIC_MASTER_DATA:
-            case PIC_SLAVE_DATA:
-            {
-                PicWriteData(CurrentPort, *(Address++));
-                break;
-            }
-
-            case PS2_CONTROL_PORT:
-            {
-                KeyboardWriteCommand(*(Address++));
-                break;
-            }
-
-            case PS2_DATA_PORT:
-            {
-                KeyboardWriteData(*(Address++));
-                break;
-            }
-
-            case CMOS_ADDRESS_PORT:
-            {
-                CmosWriteAddress(*(Address++));
-                break;
-            }
-
-            case CMOS_DATA_PORT:
-            {
-                CmosWriteData(*(Address++));
-                break;
-            }
-
-            case SPEAKER_CONTROL_PORT:
-            {
-                SpeakerWriteCommand(*(Address++));
-                break;
-            }
-
-            case VGA_AC_WRITE:
-            case VGA_AC_READ:
-            case VGA_SEQ_INDEX:
-            case VGA_SEQ_DATA:
-            case VGA_DAC_READ_INDEX:
-            case VGA_DAC_WRITE_INDEX:
-            case VGA_DAC_DATA:
-            case VGA_MISC_READ:
-            case VGA_MISC_WRITE:
-            case VGA_CRTC_INDEX:
-            case VGA_CRTC_DATA:
-            case VGA_GC_INDEX:
-            case VGA_GC_DATA:
-            case VGA_STAT_MONO:
-            case VGA_STAT_COLOR:
-            {
-                VgaWritePort(CurrentPort, *(Address++));
-                break;
-            }
-
-            default:
-            {
-                DPRINT1("Write to unknown port: 0x%X\n", CurrentPort);
-            }
-        }
-    }
-}
-
 UCHAR WINAPI EmulatorIntAcknowledge(PFAST486_STATE State)
 {
     UNREFERENCED_PARAMETER(State);
index d0b4e49..d7c3835 100644 (file)
@@ -79,24 +79,6 @@ VOID WINAPI EmulatorWriteMemory
     ULONG Size
 );
 
-VOID WINAPI EmulatorReadIo
-(
-    PFAST486_STATE State,
-    ULONG Port,
-    PVOID Buffer,
-    ULONG DataCount,
-    UCHAR DataSize
-);
-
-VOID WINAPI EmulatorWriteIo
-(
-    PFAST486_STATE State,
-    ULONG Port,
-    PVOID Buffer,
-    ULONG DataCount,
-    UCHAR DataSize
-);
-
 UCHAR WINAPI EmulatorIntAcknowledge
 (
     PFAST486_STATE State
diff --git a/subsystems/ntvdm/io.c b/subsystems/ntvdm/io.c
new file mode 100644 (file)
index 0000000..7ce0cbf
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            io.c
+ * PURPOSE:         I/O Port Handlers
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "emulator.h"
+#include "io.h"
+
+/* PRIVATE VARIABLES **********************************************************/
+
+typedef struct _EMULATOR_IOPORT_HANDLER
+{
+    EMULATOR_IN_PROC  In;
+    EMULATOR_OUT_PROC Out;
+} EMULATOR_IOPORT_HANDLER, *PEMULATOR_IOPORT_HANDLER;
+
+/*
+ * This is the list of registered I/O Port handlers.
+ */
+EMULATOR_IOPORT_HANDLER IoPortProc[EMULATOR_MAX_IOPORTS_NUM];
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+VOID WINAPI RegisterIoPort(ULONG Port,
+                           EMULATOR_IN_PROC  InHandler,
+                           EMULATOR_OUT_PROC OutHandler)
+{
+    if (IoPortProc[Port].In == NULL)
+        IoPortProc[Port].In = InHandler;
+    else
+        DPRINT1("IoPortProc[%d].In already registered\n", Port);
+
+    if (IoPortProc[Port].Out == NULL)
+        IoPortProc[Port].Out = OutHandler;
+    else
+        DPRINT1("IoPortProc[%d].Out already registered\n", Port);
+}
+
+VOID WINAPI
+EmulatorReadIo(PFAST486_STATE State,
+               ULONG Port,
+               PVOID Buffer,
+               ULONG DataCount,
+               UCHAR DataSize)
+{
+    INT i, j;
+    LPBYTE Address = (LPBYTE)Buffer;
+
+    UNREFERENCED_PARAMETER(State);
+
+    for (i = 0; i < DataCount; i++) for (j = 0; j < DataSize; j++)
+    {
+        ULONG CurrentPort = Port + j;
+
+        /* Call the IN Port handler */
+        if (IoPortProc[CurrentPort].In != NULL)
+        {
+            *(Address++) = IoPortProc[CurrentPort].In(CurrentPort);
+        }
+        else
+        {
+            DPRINT1("Read from unknown port: 0x%X\n", CurrentPort);
+            *(Address++) = 0xFF;    // Empty port value
+        }
+    }
+}
+
+VOID WINAPI
+EmulatorWriteIo(PFAST486_STATE State,
+                ULONG Port,
+                PVOID Buffer,
+                ULONG DataCount,
+                UCHAR DataSize)
+{
+    INT i, j;
+    LPBYTE Address = (LPBYTE)Buffer;
+
+    UNREFERENCED_PARAMETER(State);
+
+    for (i = 0; i < DataCount; i++) for (j = 0; j < DataSize; j++)
+    {
+        ULONG CurrentPort = Port + j;
+
+        /* Call the OUT Port handler */
+        if (IoPortProc[CurrentPort].Out != NULL)
+            IoPortProc[CurrentPort].Out(CurrentPort, *(Address++));
+        else
+            DPRINT1("Write to unknown port: 0x%X\n", CurrentPort);
+    }
+}
+
+/* EOF */
diff --git a/subsystems/ntvdm/io.h b/subsystems/ntvdm/io.h
new file mode 100644 (file)
index 0000000..115b910
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            io.c
+ * PURPOSE:         I/O Port Handlers
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ */
+
+#ifndef _IO_H_
+#define _IO_H_
+
+/* DEFINES ********************************************************************/
+
+#define EMULATOR_MAX_IOPORTS_NUM    0x10000
+
+/* FUNCTIONS ******************************************************************/
+
+typedef BYTE (WINAPI *EMULATOR_IN_PROC)(ULONG Port);
+typedef VOID (WINAPI *EMULATOR_OUT_PROC)(ULONG Port, BYTE Data);
+
+VOID WINAPI RegisterIoPort(ULONG Port,
+                           EMULATOR_IN_PROC  InHandler,
+                           EMULATOR_OUT_PROC OutHandler);
+
+VOID WINAPI EmulatorReadIo
+(
+    PFAST486_STATE State,
+    ULONG Port,
+    PVOID Buffer,
+    ULONG DataCount,
+    UCHAR DataSize
+);
+
+VOID WINAPI EmulatorWriteIo
+(
+    PFAST486_STATE State,
+    ULONG Port,
+    PVOID Buffer,
+    ULONG DataCount,
+    UCHAR DataSize
+);
+
+
+#endif // _IO_H_
+
+/* EOF */
index 36e602f..4605469 100644 (file)
@@ -103,6 +103,7 @@ INT wmain(INT argc, WCHAR *argv[])
 
     DPRINT1("\n\n\nNTVDM - Starting '%s'...\n\n\n", CommandLine);
 
+    /* Initialize the emulator */
     if (!EmulatorInitialize())
     {
         wprintf(L"FATAL: Failed to initialize the CPU emulator\n");
@@ -116,6 +117,20 @@ INT wmain(INT argc, WCHAR *argv[])
         goto Cleanup;
     }
 
+    /* Initialize the PIC */
+    if (!PicInitialize())
+    {
+        wprintf(L"FATAL: Failed to initialize the PIC.\n");
+        goto Cleanup;
+    }
+
+    /* Initialize the PIT */
+    if (!PitInitialize())
+    {
+        wprintf(L"FATAL: Failed to initialize the PIT.\n");
+        goto Cleanup;
+    }
+
     /* Initialize the CMOS */
     if (!CmosInitialize())
     {
@@ -123,6 +138,9 @@ INT wmain(INT argc, WCHAR *argv[])
         goto Cleanup;
     }
 
+    /* Initialize the PC Speaker */
+    SpeakerInitialize();
+
     /* Initialize the system BIOS */
     if (!BiosInitialize())
     {
@@ -130,9 +148,6 @@ INT wmain(INT argc, WCHAR *argv[])
         goto Cleanup;
     }
 
-    /* Initialize the PC Speaker */
-    SpeakerInitialize();
-
     /* Initialize the VDM DOS kernel */
     if (!DosInitialize())
     {
index 073d699..c057413 100644 (file)
@@ -27,6 +27,7 @@
 
 /* DEFINES ********************************************************************/
 
+/* Basic Memory Management */
 #define TO_LINEAR(seg, off) (((seg) << 4) + (off))
 #define MAX_SEGMENT 0xFFFF
 #define MAX_OFFSET  0xFFFF
 #define SEG_OFF_TO_PTR(seg, off)    \
     (PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off)))
 
+/* BCD-Binary conversion */
+#define BINARY_TO_BCD(x) ((((x) / 1000) << 12) + (((x) / 100) << 8) + (((x) / 10) << 4) + ((x) % 10))
+#define BCD_TO_BINARY(x) (((x) >> 12) * 1000 + ((x) >> 8) * 100 + ((x) >> 4) * 10 + ((x) & 0x0F))
+
+/* Processor speed */
 #define STEPS_PER_CYCLE 256
 
 /* FUNCTIONS ******************************************************************/
index de7a0a1..ffe2c52 100644 (file)
@@ -10,8 +10,9 @@
 
 #define NDEBUG
 
-#include "pic.h"
 #include "emulator.h"
+#include "io.h"
+#include "pic.h"
 
 /* PRIVATE VARIABLES **********************************************************/
 
@@ -152,6 +153,46 @@ VOID PicWriteData(BYTE Port, BYTE Value)
     Pic->Initialization = FALSE;
 }
 
+BYTE WINAPI PicReadPort(ULONG Port)
+{
+    switch (Port)
+    {
+        case PIC_MASTER_CMD:
+        case PIC_SLAVE_CMD:
+        {
+            return PicReadCommand(Port);
+        }
+
+        case PIC_MASTER_DATA:
+        case PIC_SLAVE_DATA:
+        {
+            return PicReadData(Port);
+        }
+    }
+
+    return 0;
+}
+
+VOID WINAPI PicWritePort(ULONG Port, BYTE Data)
+{
+    switch (Port)
+    {
+        case PIC_MASTER_CMD:
+        case PIC_SLAVE_CMD:
+        {
+            PicWriteCommand(Port, Data);
+            break;
+        }
+
+        case PIC_MASTER_DATA:
+        case PIC_SLAVE_DATA:
+        {
+            PicWriteData(Port, Data);
+            break;
+        }
+    }
+}
+
 VOID PicInterruptRequest(BYTE Number)
 {
     BYTE i;
@@ -249,4 +290,15 @@ BYTE PicGetInterrupt(VOID)
     else return MasterPic.IntOffset + 7;
 }
 
+BOOLEAN PicInitialize(VOID)
+{
+    /* Register the I/O Ports */
+    RegisterIoPort(PIC_MASTER_CMD , PicReadPort, PicWritePort);
+    RegisterIoPort(PIC_SLAVE_CMD  , PicReadPort, PicWritePort);
+    RegisterIoPort(PIC_MASTER_DATA, PicReadPort, PicWritePort);
+    RegisterIoPort(PIC_SLAVE_DATA , PicReadPort, PicWritePort);
+
+    return TRUE;
+}
+
 /* EOF */
index ef60b61..2ff7ed7 100644 (file)
@@ -47,12 +47,11 @@ typedef struct _PIC
 
 /* FUNCTIONS ******************************************************************/
 
-BYTE PicReadCommand(BYTE Port);
 VOID PicWriteCommand(BYTE Port, BYTE Value);
-BYTE PicReadData(BYTE Port);
 VOID PicWriteData(BYTE Port, BYTE Value);
 VOID PicInterruptRequest(BYTE Number);
 BYTE PicGetInterrupt(VOID);
+BOOLEAN PicInitialize(VOID);
 
 #endif // _PIC_H_
 
index 03ff018..13c9406 100644 (file)
@@ -10,8 +10,9 @@
 
 #define NDEBUG
 
-#include "ps2.h"
 #include "emulator.h"
+#include "io.h"
+#include "ps2.h"
 #include "pic.h"
 
 /* PRIVATE VARIABLES **********************************************************/
@@ -24,6 +25,8 @@ static BYTE KeyboardData = 0, KeyboardResponse = 0;
 static BOOLEAN KeyboardReadResponse = FALSE, KeyboardWriteResponse = FALSE;
 static BYTE KeyboardConfig = PS2_DEFAULT_CONFIG;
 
+static HANDLE InputThread = NULL;
+
 /* PRIVATE FUNCTIONS **********************************************************/
 
 static BOOLEAN KeyboardQueuePush(BYTE ScanCode)
@@ -265,6 +268,24 @@ VOID KeyboardWriteData(BYTE Data)
     // TODO: Implement PS/2 device commands
 }
 
+BYTE WINAPI PS2ReadPort(ULONG Port)
+{
+    if (Port == PS2_CONTROL_PORT)
+        return KeyboardReadStatus();
+    else if (Port == PS2_DATA_PORT)
+        return KeyboardReadData();
+    else
+        return 0;
+}
+
+VOID WINAPI PS2WritePort(ULONG Port, BYTE Data)
+{
+    if (Port == PS2_CONTROL_PORT)
+        KeyboardWriteCommand(Data);
+    else if (Port == PS2_DATA_PORT)
+        KeyboardWriteData(Data);
+}
+
 DWORD WINAPI InputThreadProc(LPVOID Parameter)
 {
     INT i;
@@ -325,4 +346,25 @@ DWORD WINAPI InputThreadProc(LPVOID Parameter)
     return 0;
 }
 
+BOOLEAN PS2Initialize(HANDLE ConsoleInput)
+{
+    /* Start the input thread */
+    InputThread = CreateThread(NULL, 0, &InputThreadProc, ConsoleInput, 0, NULL);
+
+    // if (InputThread == NULL) return FALSE;
+
+    /* Register the I/O Ports */
+    RegisterIoPort(PS2_CONTROL_PORT, PS2ReadPort, PS2WritePort);
+    RegisterIoPort(PS2_DATA_PORT   , PS2ReadPort, PS2WritePort);
+
+    return TRUE;
+}
+
+VOID PS2Cleanup(VOID)
+{
+    /* Close the input thread handle */
+    if (InputThread != NULL) CloseHandle(InputThread);
+    InputThread = NULL;
+}
+
 /* EOF */
index 67799a6..e152e2b 100644 (file)
 /* FUNCTIONS ******************************************************************/
 
 BYTE KeyboardReadStatus();
-VOID KeyboardWriteCommand(BYTE Command);
+//VOID KeyboardWriteCommand(BYTE Command);
 BYTE KeyboardReadData();
-VOID KeyboardWriteData(BYTE Data);
-DWORD WINAPI InputThreadProc(LPVOID Parameter);
+//VOID KeyboardWriteData(BYTE Data);
+
+BOOLEAN PS2Initialize(HANDLE ConsoleInput);
+VOID PS2Cleanup(VOID);
 
 #endif // _PS2_H_
 
index c8ab49c..d8b634c 100644 (file)
@@ -668,7 +668,7 @@ VOID
 CDECL
 setMSW(USHORT Value)
 {
-    /* Set the lowest word (8 bits) */
+    /* Set the lower 16 bits (Machine Status Word) of CR0 */
     EmulatorContext.ControlRegisters[FAST486_REG_CR0] &= 0xFFFF0000;
     EmulatorContext.ControlRegisters[FAST486_REG_CR0] |= Value & 0xFFFF;
 }
index 2499a7c..84a8132 100644 (file)
@@ -10,8 +10,9 @@
 
 #define NDEBUG
 
-#include "speaker.h"
 #include "emulator.h"
+#include "speaker.h"
+#include "io.h"
 #include "timer.h"
 
 /* Extra PSDK/NDK Headers */
@@ -29,48 +30,8 @@ HANDLE hBeep = NULL;
 
 /* PUBLIC FUNCTIONS ***********************************************************/
 
-VOID SpeakerInitialize(VOID)
-{
-    NTSTATUS Status;
-    UNICODE_STRING BeepDevice;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoStatusBlock;
-
-    /* Adapted from kernel32:Beep() */
-
-    //
-    // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
-    // after doing a GetProcAddress for it
-    //
-
-    /* Open the device */
-    RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep");
-    InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL);
-    Status = NtCreateFile(&hBeep,
-                          FILE_READ_DATA | FILE_WRITE_DATA,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL,
-                          0,
-                          FILE_SHARE_READ | FILE_SHARE_WRITE,
-                          FILE_OPEN_IF,
-                          0,
-                          NULL,
-                          0);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Failed to open Beep driver, Status 0x%08lx\n", Status);
-    }
-}
-
-VOID SpeakerCleanup(VOID)
-{
-    NtClose(hBeep);
-}
-
 BYTE SpeakerReadStatus(VOID)
 {
-    // DPRINT1("SpeakerReadStatus() == 0x%x\n", Port61hState);
     return Port61hState;
 }
 
@@ -79,8 +40,6 @@ VOID SpeakerWriteCommand(BYTE Value)
     BOOLEAN IsConnectedToPITChannel2;
     UCHAR   SpeakerData;
 
-    // DPRINT1("SpeakerWriteCommand(0x%x)\n", Value);
-
     Port61hState = Value;
     IsConnectedToPITChannel2 = ((Port61hState & 0x01) != 0);
     SpeakerData = (Port61hState & 0x02);
@@ -162,4 +121,56 @@ VOID SpeakerWriteCommand(BYTE Value)
     }
 }
 
+BYTE WINAPI SpeakerReadPort(ULONG Port)
+{
+    return SpeakerReadStatus();
+}
+
+VOID WINAPI SpeakerWritePort(ULONG Port, BYTE Data)
+{
+    SpeakerWriteCommand(Data);
+}
+
+VOID SpeakerInitialize(VOID)
+{
+    NTSTATUS Status;
+    UNICODE_STRING BeepDevice;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    IO_STATUS_BLOCK IoStatusBlock;
+
+    /* Adapted from kernel32:Beep() */
+
+    //
+    // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
+    // after doing a GetProcAddress for it
+    //
+
+    /* Open the device */
+    RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep");
+    InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL);
+    Status = NtCreateFile(&hBeep,
+                          FILE_READ_DATA | FILE_WRITE_DATA,
+                          &ObjectAttributes,
+                          &IoStatusBlock,
+                          NULL,
+                          0,
+                          FILE_SHARE_READ | FILE_SHARE_WRITE,
+                          FILE_OPEN_IF,
+                          0,
+                          NULL,
+                          0);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to open Beep driver, Status 0x%08lx\n", Status);
+    }
+
+    /* Register the I/O Ports */
+    RegisterIoPort(SPEAKER_CONTROL_PORT, SpeakerReadPort, SpeakerWritePort);
+}
+
+VOID SpeakerCleanup(VOID)
+{
+    NtClose(hBeep);
+}
+
 /* EOF */
index 29d20d5..1cdceaf 100644 (file)
@@ -10,6 +10,8 @@
 
 #define NDEBUG
 
+#include "emulator.h"
+#include "io.h"
 #include "timer.h"
 #include "pic.h"
 
@@ -147,6 +149,41 @@ VOID PitWriteData(BYTE Channel, BYTE Value)
     }
 }
 
+static BYTE WINAPI PitReadPort(ULONG Port)
+{
+    switch (Port)
+    {
+        case PIT_DATA_PORT(0):
+        case PIT_DATA_PORT(1):
+        case PIT_DATA_PORT(2):
+        {
+            return PitReadData(Port - PIT_DATA_PORT(0));
+        }
+    }
+
+    return 0;
+}
+
+static VOID WINAPI PitWritePort(ULONG Port, BYTE Data)
+{
+    switch (Port)
+    {
+        case PIT_COMMAND_PORT:
+        {
+            PitWriteCommand(Data);
+            break;
+        }
+
+        case PIT_DATA_PORT(0):
+        case PIT_DATA_PORT(1):
+        case PIT_DATA_PORT(2):
+        {
+            PitWriteData(Port - PIT_DATA_PORT(0), Data);
+            break;
+        }
+    }
+}
+
 VOID PitDecrementCount(DWORD Count)
 {
     INT i;
@@ -311,4 +348,15 @@ DWORD PitGetResolution(VOID)
     return PIT_BASE_FREQUENCY / MinReloadValue;
 }
 
+BOOLEAN PitInitialize(VOID)
+{
+    /* Register the I/O Ports */
+    RegisterIoPort(PIT_COMMAND_PORT, NULL       , PitWritePort);
+    RegisterIoPort(PIT_DATA_PORT(0), PitReadPort, PitWritePort);
+    RegisterIoPort(PIT_DATA_PORT(1), PitReadPort, PitWritePort);
+    RegisterIoPort(PIT_DATA_PORT(2), PitReadPort, PitWritePort);
+
+    return TRUE;
+}
+
 /* EOF */
index 3fbd4a7..4572263 100644 (file)
@@ -2,7 +2,7 @@
  * COPYRIGHT:       GPL - See COPYING in the top level directory
  * PROJECT:         ReactOS Virtual DOS Machine
  * FILE:            timer.h
- * PURPOSE:         Programmable Interval Timer emulation (header file)
+ * PURPOSE:         Programmable Interval Timer emulation
  * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
  */
 
@@ -48,10 +48,11 @@ extern PPIT_CHANNEL PitChannel2;    // Needed for PC Speaker
 /* FUNCTIONS ******************************************************************/
 
 VOID PitWriteCommand(BYTE Value);
-BYTE PitReadData(BYTE Channel);
 VOID PitWriteData(BYTE Channel, BYTE Value);
+
 VOID PitDecrementCount(DWORD Count);
 DWORD PitGetResolution(VOID);
+BOOLEAN PitInitialize(VOID);
 
 #endif // _TIMER_H_
 
index 4609e3d..9d04d18 100644 (file)
 
 #define NDEBUG
 
+#include "emulator.h"
 #include "vga.h"
+
+#include "io.h"
 #include "bios.h"
 
 /* PRIVATE VARIABLES **********************************************************/
@@ -1082,9 +1085,9 @@ VOID VgaWriteMemory(DWORD Address, LPBYTE Buffer, DWORD Size)
     }
 }
 
-BYTE VgaReadPort(WORD Port)
+BYTE WINAPI VgaReadPort(ULONG Port)
 {
-    DPRINT("VgaReadPort: Port 0x%04X\n", Port);
+    DPRINT("VgaReadPort: Port 0x%08X\n", Port);
 
     switch (Port)
     {
@@ -1181,9 +1184,9 @@ BYTE VgaReadPort(WORD Port)
     return 0;
 }
 
-VOID VgaWritePort(WORD Port, BYTE Data)
+VOID WINAPI VgaWritePort(ULONG Port, BYTE Data)
 {
-    DPRINT("VgaWritePort: Port 0x%04X, Data 0x%02X\n", Port, Data);
+    DPRINT("VgaWritePort: Port 0x%08X, Data 0x%02X\n", Port, Data);
 
     switch (Port)
     {
@@ -1353,6 +1356,23 @@ BOOLEAN VgaInitialize(HANDLE TextHandle)
         Address += ScanlineSize;
     }
 
+    /* Register the I/O Ports */
+    RegisterIoPort(VGA_AC_WRITE , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_AC_READ  , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_SEQ_INDEX, VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_SEQ_DATA , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_DAC_READ_INDEX , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_DAC_WRITE_INDEX, VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_DAC_DATA  , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_MISC_READ , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_MISC_WRITE, VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_CRTC_INDEX, VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_CRTC_DATA , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_GC_INDEX, VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_GC_DATA , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_STAT_MONO , VgaReadPort, VgaWritePort);
+    RegisterIoPort(VGA_STAT_COLOR, VgaReadPort, VgaWritePort);
+
     /* Return success */
     return TRUE;
 }
index 4686a04..a89895e 100644 (file)
@@ -199,12 +199,13 @@ VOID VgaRefreshDisplay(VOID);
 VOID VgaHorizontalRetrace(VOID);
 VOID VgaReadMemory(DWORD Address, LPBYTE Buffer, DWORD Size);
 VOID VgaWriteMemory(DWORD Address, LPBYTE Buffer, DWORD Size);
-BYTE VgaReadPort(WORD Port);
-VOID VgaWritePort(WORD Port, BYTE Data);
 VOID VgaClearMemory(VOID);
 VOID VgaResetPalette(VOID);
 BOOLEAN VgaInitialize(HANDLE TextHandle);
 
+BYTE WINAPI VgaReadPort(ULONG Port);
+VOID WINAPI VgaWritePort(ULONG Port, BYTE Data);
+
 #endif // _VGA_H_
 
 /* EOF */