- 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
This commit is contained in:
Hermès Bélusca-Maïto 2013-11-26 20:20:51 +00:00
parent d358641f7c
commit 4fb7f6e1d7
21 changed files with 445 additions and 284 deletions

View file

@ -10,6 +10,7 @@ list(APPEND SOURCE
dos.c
emulator.c
int32.c
io.c
pic.c
ps2.c
registers.c

View 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);

View 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;
}

View file

@ -39,10 +39,6 @@
#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);

View 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;

View file

@ -11,16 +11,12 @@
#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);

View 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

100
subsystems/ntvdm/io.c Normal file
View file

@ -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 */

47
subsystems/ntvdm/io.h Normal file
View file

@ -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 */

View 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())
{

View 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
@ -38,6 +39,11 @@
#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 ******************************************************************/

View 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 */

View 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_

View 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 */

View file

@ -25,10 +25,12 @@
/* 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_

View 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;
}

View 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 */

View 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 */

View 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_

View file

@ -10,7 +10,10 @@
#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;
}

View 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 */