- Simplify PicIRQComplete helper function.
- Set up temporary stack for the BIOS.
- Initialize the "User Data Area" that is found at 0050:xxxx (see http://helppc.netcore2k.net/table/memory-map for more details).
- Some INT --> UINT
- Simplify few macros.
- Simplify DOS initialization; add few functions that will be useful later on.
- Remove trailing whitespace.
svn path=/trunk/; revision=68159
DWORD EGAPtr; // 0xa8
BYTE Reserved12[68]; // 0xac
BYTE Reserved13[16]; // 0xf0
-
- DWORD Reserved14; // 0x100
- BYTE Reserved15[12]; // 0x104
- BYTE Reserved16[17]; // 0x110
- BYTE Reserved17[15]; // 0x121
- BYTE Reserved18[3]; // 0x130
} BIOS_DATA_AREA, *PBIOS_DATA_AREA;
-C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
+C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x100);
+
+/*
+ * User Data Area at 0050:XXXX
+ *
+ * See: http://helppc.netcore2k.net/table/memory-map
+ * for more information.
+ */
+typedef struct
+{
+ BYTE PrintScreen; // 0x00
+ BYTE Basic0[3]; // 0x01
+ BYTE SingleDisketteFlag; // 0x04
+ BYTE PostArea[10]; // 0x05
+ BYTE Basic1; // 0x0f
+ WORD Basic2; // 0x10
+ DWORD Basic3; // 0x12
+ DWORD Basic4; // 0x16
+ DWORD Basic5; // 0x1a
+ WORD Reserved0; // 0x1e
+ WORD DynStorage; // 0x20
+ BYTE DisketteInitStorage[14]; // 0x22
+ DWORD Reserved1; // 0x30
+} USER_DATA_AREA, *PUSER_DATA_AREA;
+C_ASSERT(sizeof(USER_DATA_AREA) == 0x34);
/*
* BIOS Configuration Table at F000:E6F5 for 100% compatible BIOSes.
Return = (Value & getBH()) != 0;
break;
}
-
+
/* Test and return if zero */
case 4:
{
}
-VOID PicIRQComplete(LPWORD Stack)
+VOID PicIRQComplete(BYTE IntNum)
{
- /* Get the interrupt number */
- BYTE IntNum = LOBYTE(Stack[STACK_INT_NUM]);
-
/*
* If this was a PIC IRQ, send an End-of-Interrupt to the PIC.
*/
-
if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
{
/* It was an IRQ from the master PIC */
DPRINT("Master - IrqNumber = 0x%02X\n", IrqNumber);
- PicIRQComplete(Stack);
+ PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
DPRINT("Slave - IrqNumber = 0x%02X\n", IrqNumber);
- PicIRQComplete(Stack);
+ PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
// Timer IRQ 0
*/
Int32Call(&BiosContext, BIOS_SYS_TIMER_INTERRUPT);
// BiosSystemTimerInterrupt(Stack);
- PicIRQComplete(Stack);
+ PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
/* Disable interrupts */
setIF(0);
+ /* Set the data segment */
+ setDS(BDA_SEGMENT);
+
/* Initialize the stack */
- // That's what says IBM... (stack at 30:00FF going downwards)
+ // Temporary stack for POST (to be used only before initializing the INT vectors)
// setSS(0x0000);
// setSP(0x0400);
- setSS(0x0050); // Stack at 50:0400, going downwards
- setSP(0x0400);
-
- /* Set data segment */
- setDS(BDA_SEGMENT);
+ //
+ // Stack to be used after the initialization of the INT vectors
+ setSS(0x0000); // Stack at 00:8000, going downwards
+ setSP(0x8000);
/*
* Perform early CMOS shutdown status checks
InitializeBiosData();
InitializeBiosInfo();
+ /* Initialize the User Data Area at 0050:XXXX */
+ RtlZeroMemory(SEG_OFF_TO_PTR(0x50, 0x0000), sizeof(USER_DATA_AREA));
+
/*
* Initialize IVT and hardware
*/
} while(0);
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func);
-VOID PicIRQComplete(LPWORD Stack);
+VOID PicIRQComplete(BYTE IntNum);
#endif // _BIOS32P_H_
case 0x11:
{
WORD Character;
-
+
if (BiosKbdBufferTop(&Character))
{
/* There is a character, clear ZF and return it */
Character, ScanCode, Bda->KeybdShiftFlags);
Quit:
- PicIRQComplete(Stack);
+ PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
/* PUBLIC FUNCTIONS ***********************************************************/
// Mouse IRQ 12
static VOID WINAPI BiosMouseIrq(LPWORD Stack)
{
- PicIRQComplete(Stack);
+ PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
VOID BiosMousePs2Interface(LPWORD Stack)
#include "ntvdm.h"
#include "emulator.h"
+#include <isvbop.h>
+
#include "utils.h"
#include "dem.h"
switch (FuncNum)
{
- case 0x11: // Load the DOS kernel
+ /* Load the DOS kernel */
+ case 0x11:
{
BOOLEAN Success = FALSE;
+ LPCSTR DosKernelFileName = "ntdos.sys";
HANDLE hDosKernel;
ULONG ulDosKernelSize = 0;
DPRINT1("You are loading Windows NT DOS!\n");
/* Open the DOS kernel file */
- hDosKernel = FileOpen("ntdos.sys", &ulDosKernelSize);
-
- /* If we failed, bail out */
+ hDosKernel = FileOpen(DosKernelFileName, &ulDosKernelSize);
if (hDosKernel == NULL) goto Quit;
/*
ulDosKernelSize,
&ulDosKernelSize);
- DPRINT1("Windows NT DOS loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+ DPRINT1("Windows NT DOS file '%s' loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+ DosKernelFileName,
(Success ? "succeeded" : "failed"),
getDI(), 0x0000,
ulDosKernelSize,
if (!Success)
{
/* We failed everything, stop the VDM */
+ DisplayMessage(L"Windows NT DOS kernel file '%S' loading failed (Error: %u). The VDM will shut down.",
+ DosKernelFileName, GetLastError());
EmulatorTerminate();
return;
}
//
/* 16-bit bootstrap code at 0000:7C00 */
-/* Of course, this is not in real bootsector format, because we don't care */
+/* Of course, this is not in real bootsector format, because we don't care about it for now */
static BYTE Bootsector1[] =
{
- LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_LOAD_DOS, // Call DOS Loading
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_LOAD_DOS
};
/* This portion of code is run if we failed to load the DOS */
+// NOTE: This may also be done by the BIOS32.
static BYTE Bootsector2[] =
{
- 0xEA, // jmp far ptr
- 0x5B, 0xE0, 0x00, 0xF0, // F000:E05B /** HACK! What to do instead?? **/
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_UNSIMULATE
};
static VOID WINAPI DosInitialize(LPWORD Stack);
{
/* We write the bootsector at 0000:7C00 */
ULONG_PTR Address = (ULONG_PTR)SEG_OFF_TO_PTR(0x0000, 0x7C00);
- CHAR DosKernelFileName[] = ""; // No DOS file name, therefore we'll load DOS32
+ CHAR DosKernelFileName[] = ""; // No DOS BIOS file name, therefore we will load DOS32
DPRINT("DosBootsectorInitialize\n");
//
-// This function is called by the DOS bootsector. We finish to load
-// the DOS, then we jump to 0070:0000.
+// This function is called by the DOS bootsector in case we load DOS32.
+// It sets up the DOS32 start code then jumps to 0070:0000.
//
-/* 16-bit startup code at 0070:0000 */
+/* 16-bit startup code for DOS32 at 0070:0000 */
static BYTE Startup[] =
{
- LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_START_DOS, // Call DOS Start
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_START_DOS,
+ LOBYTE(EMULATOR_BOP), HIBYTE(EMULATOR_BOP), BOP_UNSIMULATE
};
static VOID WINAPI DosStart(LPWORD Stack);
static VOID WINAPI DosInitialize(LPWORD Stack)
{
- BOOLEAN Success = FALSE;
-
- /* Get the DOS kernel file name (NULL-terminated) */
+ /* Get the DOS BIOS file name (NULL-terminated) */
// FIXME: Isn't it possible to use some DS:SI instead??
- LPCSTR DosKernelFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
- setIP(getIP() + strlen(DosKernelFileName) + 1); // Skip it
+ LPCSTR DosBiosFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
+ setIP(getIP() + strlen(DosBiosFileName) + 1); // Skip it
- DPRINT("DosInitialize('%s')\n", DosKernelFileName);
+ DPRINT("DosInitialize('%s')\n", DosBiosFileName);
+
+ /*
+ * We succeeded, deregister the DOS Loading BOP
+ * so that no app will be able to call us back.
+ */
+ RegisterBop(BOP_LOAD_DOS, NULL);
/* Register the DOS BOPs */
RegisterBop(BOP_DOS, DosSystemBop );
RegisterBop(BOP_CMD, DosCmdInterpreterBop);
- if (DosKernelFileName && DosKernelFileName[0] != '\0')
+ if (DosBiosFileName && DosBiosFileName[0] != '\0')
{
+ BOOLEAN Success = FALSE;
HANDLE hDosBios;
ULONG ulDosBiosSize = 0;
/* Open the DOS BIOS file */
- hDosBios = FileOpen(DosKernelFileName, &ulDosBiosSize);
-
- /* If we failed, bail out */
- if (hDosBios == NULL) goto QuitCustom;
+ hDosBios = FileOpen(DosBiosFileName, &ulDosBiosSize);
+ if (hDosBios == NULL) goto Quit;
/* Attempt to load the DOS BIOS into memory */
Success = FileLoadByHandle(hDosBios,
ulDosBiosSize,
&ulDosBiosSize);
- DPRINT1("DOS BIOS loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+ DPRINT1("DOS BIOS file '%s' loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
+ DosBiosFileName,
(Success ? "succeeded" : "failed"),
0x0070, 0x0000,
ulDosBiosSize,
/* Close the DOS BIOS file */
FileClose(hDosBios);
- if (!Success) goto QuitCustom;
-
- /* Position execution pointers and return */
- setCS(0x0070);
- setIP(0x0000);
-
- /* Return control */
-QuitCustom:
+Quit:
if (!Success)
- DisplayMessage(L"Custom DOS '%S' loading failed, what to do??", DosKernelFileName);
+ {
+ DisplayMessage(L"DOS BIOS file '%S' loading failed (Error: %u). The VDM will shut down.",
+ DosBiosFileName, GetLastError());
+ return;
+ }
}
else
{
- Success = DosBIOSInitialize();
- // Success &= DosKRNLInitialize();
-
- if (!Success) goto Quit32;
-
- /* Write the "bootsector" */
+ /* Load the 16-bit startup code for DOS32 and register its Starting BOP */
RtlCopyMemory(SEG_OFF_TO_PTR(0x0070, 0x0000), Startup, sizeof(Startup));
- /* Register the DOS Starting BOP */
+ // This is the equivalent of BOP_LOAD_DOS, function 0x11 "Load the DOS kernel"
+ // for the Windows NT DOS.
RegisterBop(BOP_START_DOS, DosStart);
-
- /* Position execution pointers and return */
- setCS(0x0070);
- setIP(0x0000);
-
- /* Return control */
-Quit32:
- if (!Success)
- DisplayMessage(L"DOS32 loading failed, what to do??");
}
- if (Success)
- {
- /*
- * We succeeded, deregister the DOS Loading BOP
- * so that no app will be able to call us back.
- */
- RegisterBop(BOP_LOAD_DOS, NULL);
- }
+ /* Position execution pointers for DOS startup and return */
+ setCS(0x0070);
+ setIP(0x0000);
}
static VOID WINAPI DosStart(LPWORD Stack)
{
+ BOOLEAN Success;
#ifdef STANDALONE
DWORD Result;
CHAR ApplicationName[MAX_PATH];
*/
RegisterBop(BOP_START_DOS, NULL);
+ Success = DosBIOSInitialize();
+// Success &= DosKRNLInitialize();
+ if (!Success)
+ {
+ DisplayMessage(L"DOS32 loading failed (Error: %u). The VDM will shut down.", GetLastError());
+ EmulatorTerminate();
+ return;
+ }
+
/* Load the mouse driver */
DosMouseInitialize();
#undef FreeEnvironmentStrings
#define FreeEnvironmentStrings FreeEnvironmentStringsA
-#define CHARACTER_ADDRESS 0x007000FF /* 0070:00FF */
-
/* PRIVATE VARIABLES **********************************************************/
// static BYTE CurrentDrive;
&BytesWritten);
}
-BOOLEAN DosBIOSInitialize(VOID)
+BOOLEAN DosBuildSysEnvBlock(VOID)
{
- PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
-
LPSTR SourcePtr, Environment;
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
-#if 0
- UCHAR i;
- CHAR CurrentDirectory[MAX_PATH];
- CHAR DosDirectory[DOS_DIR_LENGTH];
- LPSTR Path;
-
- FILE *Stream;
- WCHAR Buffer[256];
-#endif
-
- /* Initialize the MCB */
- Mcb->BlockType = 'Z';
- Mcb->Size = USER_MEMORY_SIZE;
- Mcb->OwnerPsp = 0;
-
- /* Initialize the link MCB to the UMB area */
- Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
- Mcb->BlockType = 'M';
- Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
- Mcb->OwnerPsp = SYSTEM_PSP;
-
- /* Initialize the UMB area */
- Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
- Mcb->BlockType = 'Z';
- Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
- Mcb->OwnerPsp = 0;
-
/* Get the environment strings */
SourcePtr = Environment = GetEnvironmentStrings();
if (Environment == NULL) return FALSE;
/* Free the memory allocated for environment strings */
FreeEnvironmentStrings(Environment);
+ return TRUE;
+}
+
+BOOLEAN DosBIOSInitialize(VOID)
+{
+#if 0
+ UCHAR i;
+ CHAR CurrentDirectory[MAX_PATH];
+ CHAR DosDirectory[DOS_DIR_LENGTH];
+ LPSTR Path;
+
+ FILE *Stream;
+ WCHAR Buffer[256];
+#endif
+
+ /* Set the data segment */
+ setDS(DOS_DATA_SEGMENT);
+
+ /* Initialize the DOS stack */
+ // Stack just before FIRST_MCB_SEGMENT and after SYSTEM_ENV_BLOCK
+ // FIXME: Add a block of fixed size for the stack in DOS_DATA instead!
+ setSS(0x0F00);
+ setSP(0x0FF0);
+ setBP(0x091E); // DOS base stack pointer relic value
+
+ /* Initialize memory management */
+ DosInitializeMemory();
+
+ /* Build the system master environment block (inherited by the shell) */
+ if (!DosBuildSysEnvBlock())
+ {
+ DPRINT1("An error occurred when setting up the system environment block.\n");
+ }
+
#if 0
/* Return the DOS "list of lists" in ES:BX */
setES(DOS_DATA_SEGMENT);
setBX(DOS_DATA_OFFSET(SysVars.FirstDpb));
-
break;
}
/*
* This call should leave the flags on the stack for some reason,
* so move the stack by one word.
+ * See: http://www.techhelpmanual.com/565-int_25h_26h__absolute_disk_read_write.html
*/
Stack[STACK_INT_NUM] = Stack[STACK_IP];
Stack[STACK_IP] = Stack[STACK_CS];
/*
* This call should leave the flags on the stack for some reason,
* so move the stack by one word.
+ * See: http://www.techhelpmanual.com/565-int_25h_26h__absolute_disk_read_write.html
*/
Stack[STACK_INT_NUM] = Stack[STACK_IP];
Stack[STACK_IP] = Stack[STACK_CS];
DWORD DriverEntry;
if (!XmsGetDriverEntry(&DriverEntry)) break;
- if (getAL() == 0x00)
- {
- /* The driver is loaded */
- setAL(0x80);
- }
- else if (getAL() == 0x10)
- {
- setES(HIWORD(DriverEntry));
- setBX(LOWORD(DriverEntry));
- }
- else
+ switch (getAL())
{
- DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL = %xh\n", getAL());
+ /* Installation Check */
+ case 0x00:
+ {
+ /* The driver is loaded */
+ setAL(0x80);
+ break;
+ }
+
+ /* Get Driver Address */
+ case 0x10:
+ {
+ setES(HIWORD(DriverEntry));
+ setBX(LOWORD(DriverEntry));
+ break;
+ }
+
+ default:
+ DPRINT1("Unknown DOS XMS Function: INT 0x2F, AH = 43h, AL = %xh\n", getAL());
+ break;
}
break;
RegisterDosInt32(0x27, DosInt27h ); // Terminate and Stay Resident
RegisterDosInt32(0x28, DosIdle ); // DOS Idle Interrupt
RegisterDosInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output
- RegisterDosInt32(0x2F, DosInt2Fh );
+ RegisterDosInt32(0x2F, DosInt2Fh ); // Multiplex Interrupt
/* Unimplemented DOS interrupts */
RegisterDosInt32(0x2A, NULL); // Network - Installation Check
return (WORD)GetLastError();
}
}
-
+
DescriptorId = DosFindFreeDescriptor();
if (DescriptorId == 0xFF)
{
{
/* Not ready */
*Length = 0;
- }
+ }
}
return TRUE;
}
PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
- if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
+ if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
+ ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE);
EmsReadMemory,
EmsWriteMemory);
-
/* Create the device */
Node = DosCreateDeviceEx(DOS_DEVATTR_IOCTL | DOS_DEVATTR_CHARACTER,
EMS_DEVICE_NAME,
if (Entry && Entry->Handle != 0)
{
- INT i;
+ UINT i;
UCHAR Handles = 0;
for (i = 0; i < XMS_MAX_HANDLES; i++)
{
WORD Segment;
WORD MaxAvailable;
-
+
Segment = DosResizeMemory(getDX(), getBX(), &MaxAvailable);
if (Segment)
/* It is, split it into two blocks */
NextMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
-
+
/* Initialize the new MCB structure */
NextMcb->BlockType = Mcb->BlockType;
NextMcb->Size = Mcb->Size - NewSize - 1;
/* Return the maximum possible size */
if (MaxAvailable) *MaxAvailable = ReturnSize;
}
-
+
return Success;
}
Mcb->OwnerPsp = NewOwner;
}
+VOID DosInitializeMemory(VOID)
+{
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
+
+ /* Initialize the MCB */
+ Mcb->BlockType = 'Z';
+ Mcb->Size = USER_MEMORY_SIZE;
+ Mcb->OwnerPsp = 0;
+
+ /* Initialize the link MCB to the UMB area */
+ Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
+ Mcb->BlockType = 'M';
+ Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
+ Mcb->OwnerPsp = SYSTEM_PSP;
+
+ /* Initialize the UMB area */
+ Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
+ Mcb->BlockType = 'Z';
+ Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
+ Mcb->OwnerPsp = 0;
+}
+
+/* EOF */
/* TYPEDEFS *******************************************************************/
-#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
+#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)SEG_OFF_TO_PTR((seg), 0))
enum DOS_ALLOC_STRATEGY
{
BOOLEAN DosUnlinkUmb(VOID);
VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner);
+VOID DosInitializeMemory(VOID);
+
#endif // _DOS_MEMORY_H_
/* EOF */
/* DEFINITIONS ****************************************************************/
-#define DOS_CMDLINE_LENGTH 127
+#define DOS_CMDLINE_LENGTH 127
#define DOS_PROGRAM_NAME_TAG 0x0001
-#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
+#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)SEG_OFF_TO_PTR((seg), 0))
typedef enum
{
DOS_LOAD_AND_EXECUTE = 0x00,
- DOS_LOAD_ONLY = 0x01,
- DOS_LOAD_OVERLAY = 0x03
+ DOS_LOAD_ONLY = 0x01,
+ DOS_LOAD_OVERLAY = 0x03
} DOS_EXEC_TYPE;
#pragma pack(push, 1)
typedef struct _DOS_REGISTER_STATE
{
WORD AX, BX, CX, DX, SI, DI, BP, DS, ES;
+// WORD IP, CS, Flags; // They are supposed to be already
+ // pushed on stack by the DOS caller.
} DOS_REGISTER_STATE, *PDOS_REGISTER_STATE;
#pragma pack(pop)
-/* VARIABLES ******************************************************************/
-
-extern WORD CurrentPsp;
-
/* FUNCTIONS ******************************************************************/
VOID DosClonePsp(WORD DestSegment, WORD SourceSegment);
DosUpdateButtons(ButtonState);
/* Complete the IRQ */
- PicIRQComplete(Stack);
+ PicIRQComplete(LOBYTE(Stack[STACK_INT_NUM]));
}
static VOID WINAPI DosMouseService(LPWORD Stack)
/* DEFINES ********************************************************************/
/* Basic Memory Management */
-#define MEM_ALIGN_UP(ptr, align) MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
#define MEM_ALIGN_DOWN(ptr, align) (PVOID)((ULONG_PTR)(ptr) & ~((align) - 1l))
+#define MEM_ALIGN_UP(ptr, align) MEM_ALIGN_DOWN((ULONG_PTR)(ptr) + (align) - 1l, (align))
#define TO_LINEAR(seg, off) (((seg) << 4) + (off))
#define MAX_SEGMENT 0xFFFF
#define MAX_OFFSET 0xFFFF
#define MAX_ADDRESS 0x1000000 // 16 MB of RAM; see also: kernel32/client/vdm.c!BaseGetVdmConfigInfo
-#define FAR_POINTER(x) \
- (PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR(HIWORD(x), LOWORD(x)))
-
#define SEG_OFF_TO_PTR(seg, off) \
(PVOID)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), (off)))
+#define FAR_POINTER(x) SEG_OFF_TO_PTR(HIWORD(x), LOWORD(x))
+
#define REAL_TO_PHYS(ptr) (PVOID)((ULONG_PTR)(ptr) + (ULONG_PTR)BaseAddress)
#define PHYS_TO_REAL(ptr) (PVOID)((ULONG_PTR)(ptr) - (ULONG_PTR)BaseAddress)
{
/* Update the NMI enabled flag */
NmiEnabled = !(Value & CMOS_DISABLE_NMI);
-
+
/* Get the register number */
Value &= ~CMOS_DISABLE_NMI;
BYTE PicGetInterrupt(VOID)
{
- INT i;
+ UINT i;
/* Search the master PIC interrupts by priority */
for (i = 0; i < 8; i++)
}
}
}
-
+
/* Spurious interrupt */
if (MasterPic.InServiceRegister & (1 << 2)) return SlavePic.IntOffset + 7;
else return MasterPic.IntOffset + 7;
/*
* Adjust the interrupt request number according to the parameters,
* by adding an offset == 8 to the interrupt number.
- *
+ *
* Indeed VDDs calling this function usually subtracts 8 so that they give:
*
* ms | line | corresponding interrupt number
VGA_MAX_COLORS * sizeof(PALETTEENTRY));
TextPalette = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
- sizeof(LOGPALETTE) +
+ sizeof(LOGPALETTE) +
(VGA_AC_PAL_F_REG + 1) * sizeof(PALETTEENTRY));
if ((Palette == NULL) || (TextPalette == NULL)) goto Cleanup;
case VGA_SEQ_INDEX:
return VgaSeqIndex;
-
+
case VGA_SEQ_DATA:
return VgaSeqRegisters[VgaSeqIndex];
for (i = 0; i < Size; i++)
{
VideoAddress = VgaTranslateReadAddress(Address + i);
-
+
/* Copy the value to the buffer */
BufPtr[i] = VgaMemory[VideoAddress];
}
if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
/* If the A20 line is disabled, mask bit 20 */
- if (!A20Line) Address &= ~(1 << 20);
+ if (!A20Line) Address &= ~(1 << 20);
if ((Address + Size - 1) >= MAX_ADDRESS)
{
}
else
{
- for (i = FirstPage; i <= LastPage; i++)
+ for (i = FirstPage; i <= LastPage; i++)
{
Offset = (i == FirstPage) ? (Address & (PAGE_SIZE - 1)) : 0;
Length = ((i == LastPage) ? (Address + Size - (LastPage << 12)) : PAGE_SIZE) - Offset;
UNREFERENCED_PARAMETER(State);
/* If the A20 line is disabled, mask bit 20 */
- if (!A20Line) Address &= ~(1 << 20);
+ if (!A20Line) Address &= ~(1 << 20);
if (Address >= MAX_ADDRESS) return;
Size = min(Size, MAX_ADDRESS - Address);
}
else
{
- for (i = FirstPage; i <= LastPage; i++)
+ for (i = FirstPage; i <= LastPage; i++)
{
Offset = (i == FirstPage) ? (Address & (PAGE_SIZE - 1)) : 0;
Length = ((i == LastPage) ? (Address + Size - (LastPage << 12)) : PAGE_SIZE) - Offset;
ULONG Address,
PVOID Buffer,
ULONG Size
-);
+);
/* FUNCTIONS ******************************************************************/