spec2def(ntvdm.exe ntvdm.spec)
list(APPEND SOURCE
+ bios/bios32/bios32.c
+ bios/bios32/kbdbios32.c
+ bios/bios32/vidbios32.c
bios/bios.c
- bios/kbdbios.c
- bios/vidbios.c
hardware/cmos.c
hardware/pic.c
hardware/ps2.c
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: bios.c
- * PURPOSE: VDM BIOS
- * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * PURPOSE: VDM BIOS Support Library
+ * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *******************************************************************/
#define NDEBUG
-#include "emulator.h"
#include "bios.h"
-#include "io.h"
-#include "hardware/cmos.h"
-#include "hardware/pic.h"
-#include "hardware/timer.h"
-
-#include "int32.h"
-
/* PRIVATE VARIABLES **********************************************************/
-PBIOS_DATA_AREA Bda;
+static BOOLEAN Bios32Loaded = FALSE;
/* PRIVATE FUNCTIONS **********************************************************/
-static VOID WINAPI BiosException(LPWORD Stack)
-{
- /* Get the exception number and call the emulator API */
- BYTE ExceptionNumber = LOBYTE(Stack[STACK_INT_NUM]);
- EmulatorException(ExceptionNumber, Stack);
-}
-
-static VOID WINAPI BiosEquipmentService(LPWORD Stack)
-{
- /* Return the equipment list */
- setAX(Bda->EquipmentList);
-}
-
-static VOID WINAPI BiosGetMemorySize(LPWORD Stack)
-{
- /* Return the conventional memory size in kB, typically 640 kB */
- setAX(Bda->MemorySize);
-}
-
-static VOID WINAPI BiosMiscService(LPWORD Stack)
-{
- switch (getAH())
- {
- /* Wait */
- case 0x86:
- {
- /*
- * Interval in microseconds in CX:DX
- * See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
- * for more information.
- */
- Sleep(MAKELONG(getDX(), getCX()));
-
- /* Clear CF */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
- break;
- }
-
- /* Copy Extended Memory */
- case 0x87:
- {
- DWORD Count = (DWORD)getCX() * 2;
- PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI());
- DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24);
- DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16);
- DWORD DestBase = Gdt[3].Base + (Gdt[3].BaseMid << 16) + (Gdt[3].BaseHigh << 24);
- DWORD DestLimit = Gdt[3].Limit + (Gdt[3].LimitHigh << 16);
-
- /* Check for flags */
- if (Gdt[2].Granularity) SourceLimit = (SourceLimit << 12) | 0xFFF;
- if (Gdt[3].Granularity) DestLimit = (DestLimit << 12) | 0xFFF;
-
- if ((Count > SourceLimit) || (Count > DestLimit))
- {
- setAX(0x80);
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
-
- break;
- }
-
- /* Copy */
- RtlMoveMemory((PVOID)((ULONG_PTR)BaseAddress + DestBase),
- (PVOID)((ULONG_PTR)BaseAddress + SourceBase),
- Count);
-
- setAX(ERROR_SUCCESS);
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- break;
- }
-
- /* Get Extended Memory Size */
- case 0x88:
- {
- UCHAR Low, High;
-
- /*
- * Return the (usable) extended memory (after 1 MB)
- * size in kB from CMOS.
- */
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_LOW);
- Low = IOReadB(CMOS_DATA_PORT);
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_HIGH);
- High = IOReadB(CMOS_DATA_PORT);
- setAX(MAKEWORD(Low, High));
-
- /* Clear CF */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
- break;
- }
-
- default:
- {
- DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
- getAH());
- }
- }
-}
-
-static VOID WINAPI BiosTimeService(LPWORD Stack)
-{
- switch (getAH())
- {
- case 0x00:
- {
- /* Set AL to 1 if midnight had passed, 0 otherwise */
- setAL(Bda->MidnightPassed ? 0x01 : 0x00);
-
- /* Return the tick count in CX:DX */
- setCX(HIWORD(Bda->TickCounter));
- setDX(LOWORD(Bda->TickCounter));
-
- /* Reset the midnight flag */
- Bda->MidnightPassed = FALSE;
-
- break;
- }
-
- case 0x01:
- {
- /* Set the tick count to CX:DX */
- Bda->TickCounter = MAKELONG(getDX(), getCX());
-
- /* Reset the midnight flag */
- Bda->MidnightPassed = FALSE;
-
- break;
- }
-
- default:
- {
- DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n",
- getAH());
- }
- }
-}
-
-static VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack)
-{
- /* Increase the system tick count */
- Bda->TickCounter++;
-}
-
-
-// From SeaBIOS
-static VOID PicSetIRQMask(USHORT off, USHORT on)
-{
- UCHAR pic1off = off, pic1on = on, pic2off = off>>8, pic2on = on>>8;
- IOWriteB(PIC_MASTER_DATA, (IOReadB(PIC_MASTER_DATA) & ~pic1off) | pic1on);
- IOWriteB(PIC_SLAVE_DATA , (IOReadB(PIC_SLAVE_DATA ) & ~pic2off) | pic2on);
-}
-
-// From SeaBIOS
-VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
-{
- UCHAR vector;
-
- PicSetIRQMask(1 << hwirq, 0);
- if (hwirq < 8)
- vector = BIOS_PIC_MASTER_INT + hwirq;
- else
- vector = BIOS_PIC_SLAVE_INT + hwirq - 8;
-
- RegisterInt32(vector, func);
-}
-
-
-VOID PicIRQComplete(LPWORD Stack)
-{
- /* 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 */
- IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
- }
- else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
- {
- /* It was an IRQ from the slave PIC */
- IOWriteB(PIC_SLAVE_CMD , PIC_OCW2_EOI);
- IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
- }
-}
-
-static VOID WINAPI BiosHandleMasterPicIRQ(LPWORD Stack)
-{
- BYTE IrqNumber;
-
- IOWriteB(PIC_MASTER_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
- IrqNumber = IOReadB(PIC_MASTER_CMD);
-
- DPRINT("Master - IrqNumber = 0x%x\n", IrqNumber);
-
- PicIRQComplete(Stack);
-}
-
-static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
-{
- BYTE IrqNumber;
-
- IOWriteB(PIC_SLAVE_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
- IrqNumber = IOReadB(PIC_SLAVE_CMD);
-
- DPRINT("Slave - IrqNumber = 0x%x\n", IrqNumber);
-
- PicIRQComplete(Stack);
-}
-
-// Timer IRQ 0
-static VOID WINAPI BiosTimerIrq(LPWORD Stack)
-{
- /*
- * Perform the system timer interrupt.
- *
- * Do not call directly BiosSystemTimerInterrupt(Stack);
- * because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
- * for their purpose...
- */
- EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT);
- PicIRQComplete(Stack);
-}
-
-
-static VOID BiosHwSetup(VOID)
-{
- /* Initialize the master and the slave PICs (cascade mode) */
- IOWriteB(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
- IOWriteB(PIC_SLAVE_CMD , PIC_ICW1 | PIC_ICW1_ICW4);
-
- /*
- * Set the interrupt vector offsets for each PIC
- * (base IRQs: 0x08-0x0F for IRQ 0-7, 0x70-0x77 for IRQ 8-15)
- */
- IOWriteB(PIC_MASTER_DATA, BIOS_PIC_MASTER_INT);
- IOWriteB(PIC_SLAVE_DATA , BIOS_PIC_SLAVE_INT );
-
- /* Tell the master PIC that there is a slave PIC at IRQ 2 */
- IOWriteB(PIC_MASTER_DATA, 1 << 2);
- /* Tell the slave PIC its cascade identity */
- IOWriteB(PIC_SLAVE_DATA , 2);
-
- /* Make sure both PICs are in 8086 mode */
- IOWriteB(PIC_MASTER_DATA, PIC_ICW4_8086);
- IOWriteB(PIC_SLAVE_DATA , PIC_ICW4_8086);
-
- /* Clear the masks for both PICs */
- // IOWriteB(PIC_MASTER_DATA, 0x00);
- // IOWriteB(PIC_SLAVE_DATA , 0x00);
- /* Disable all IRQs */
- IOWriteB(PIC_MASTER_DATA, 0xFF);
- IOWriteB(PIC_SLAVE_DATA , 0xFF);
-
-
- /* Initialize PIT Counter 0 */
- IOWriteB(PIT_COMMAND_PORT, 0x34);
- IOWriteB(PIT_DATA_PORT(0), 0x00);
- IOWriteB(PIT_DATA_PORT(0), 0x00);
-
- /* Initialize PIT Counter 1 */
- IOWriteB(PIT_COMMAND_PORT, 0x74);
- IOWriteB(PIT_DATA_PORT(1), 0x00);
- IOWriteB(PIT_DATA_PORT(1), 0x00);
-
- /* Initialize PIT Counter 2 */
- IOWriteB(PIT_COMMAND_PORT, 0xB4);
- IOWriteB(PIT_DATA_PORT(2), 0x00);
- IOWriteB(PIT_DATA_PORT(2), 0x00);
-
- EnableHwIRQ(0, BiosTimerIrq);
-}
-
/* PUBLIC FUNCTIONS ***********************************************************/
-/*
- * The BIOS POST (Power On-Self Test)
- */
-BOOLEAN BiosInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput)
+BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName,
+ IN HANDLE ConsoleInput,
+ IN HANDLE ConsoleOutput)
{
- UCHAR Low, High;
- UCHAR i;
-
- /* Initialize the BDA */
- Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
- Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
-
- /*
- * Retrieve the conventional memory size
- * in kB from CMOS, typically 640 kB.
- */
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
- Low = IOReadB(CMOS_DATA_PORT);
- IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
- High = IOReadB(CMOS_DATA_PORT);
- Bda->MemorySize = MAKEWORD(Low, High);
-
- /* Initialize the 32-bit Interrupt system */
- InitializeInt32(BIOS_SEGMENT);
-
- /* Register the BIOS 32-bit Interrupts */
-
- /* Initialize the exception vector interrupts to a default Exception handler */
- for (i = 0; i < 8; i++)
- RegisterInt32(i, BiosException);
-
- /* Initialize HW vector interrupts to a default HW handler */
- for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
- RegisterInt32(i, BiosHandleMasterPicIRQ);
- for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT + 8; i++)
- RegisterInt32(i, BiosHandleSlavePicIRQ);
-
- /* Initialize software vector handlers */
- RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
- RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
- RegisterInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
- RegisterInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
- RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
-
- /* Some interrupts are in fact addresses to tables */
- ((PDWORD)BaseAddress)[0x1E] = (DWORD)NULL;
- ((PDWORD)BaseAddress)[0x41] = (DWORD)NULL;
- ((PDWORD)BaseAddress)[0x46] = (DWORD)NULL;
- ((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
- ((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
-
- /* Initialize platform hardware (PIC/PIT chips, ...) */
- BiosHwSetup();
-
- /* Initialize the Keyboard BIOS */
- if (!KbdBiosInitialize(ConsoleInput)) return FALSE;
-
- /* Set the console input mode */
- SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
-
- /* Initialize the Video BIOS */
- if (!VidBiosInitialize(ConsoleOutput)) return FALSE;
-
- return TRUE;
+ Bios32Loaded = Bios32Initialize(ConsoleInput, ConsoleOutput);
+ return Bios32Loaded;
}
VOID BiosCleanup(VOID)
{
- VidBiosCleanup();
- KbdBiosCleanup();
+ if (Bios32Loaded) Bios32Cleanup();
}
/* EOF */
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
* FILE: bios.h
- * PURPOSE: VDM BIOS
- * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ * PURPOSE: VDM BIOS Support Library
+ * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
#ifndef _BIOS_H_
/* INCLUDES *******************************************************************/
#include "ntvdm.h"
-#include "kbdbios.h"
-#include "vidbios.h"
+#include "bios32/bios32.h"
/* DEFINES ********************************************************************/
#define ROM_AREA_START 0xE0000
#define ROM_AREA_END 0xFFFFF
+#if 0
+
#define BDA_SEGMENT 0x40
#define BIOS_SEGMENT 0xF000
-#define BIOS_PIC_MASTER_INT 0x08
-#define BIOS_PIC_SLAVE_INT 0x70
-
-#define BIOS_EQUIPMENT_INTERRUPT 0x11
-#define BIOS_MEMORY_SIZE 0x12
-#define BIOS_MISC_INTERRUPT 0x15
-#define BIOS_TIME_INTERRUPT 0x1A
-#define BIOS_SYS_TIMER_INTERRUPT 0x1C
-
-#define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now
-
/*
* BIOS Data Area at 0040:XXXX
*
C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
+#endif
+
/* FUNCTIONS ******************************************************************/
extern PBIOS_DATA_AREA Bda;
-/**HACK!!**/typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);/**HACK!!**/
-
-VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func);
-VOID PicIRQComplete(LPWORD Stack);
-
-BOOLEAN BiosInitialize(HANDLE ConsoleInput, HANDLE ConsoleOutput);
+BOOLEAN BiosInitialize(IN LPCWSTR BiosFileName,
+ IN HANDLE ConsoleInput,
+ IN HANDLE ConsoleOutput);
VOID BiosCleanup(VOID);
#endif // _BIOS_H_
--- /dev/null
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: bios32.c
+ * PURPOSE: VDM 32-bit BIOS
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "emulator.h"
+#include "bios32.h"
+
+#include "io.h"
+#include "hardware/cmos.h"
+#include "hardware/pic.h"
+#include "hardware/timer.h"
+
+#include "int32.h"
+
+/* PRIVATE VARIABLES **********************************************************/
+
+PBIOS_DATA_AREA Bda;
+
+/* PRIVATE FUNCTIONS **********************************************************/
+
+static VOID WINAPI BiosException(LPWORD Stack)
+{
+ /* Get the exception number and call the emulator API */
+ BYTE ExceptionNumber = LOBYTE(Stack[STACK_INT_NUM]);
+ EmulatorException(ExceptionNumber, Stack);
+}
+
+static VOID WINAPI BiosEquipmentService(LPWORD Stack)
+{
+ /* Return the equipment list */
+ setAX(Bda->EquipmentList);
+}
+
+static VOID WINAPI BiosGetMemorySize(LPWORD Stack)
+{
+ /* Return the conventional memory size in kB, typically 640 kB */
+ setAX(Bda->MemorySize);
+}
+
+static VOID WINAPI BiosMiscService(LPWORD Stack)
+{
+ switch (getAH())
+ {
+ /* Wait */
+ case 0x86:
+ {
+ /*
+ * Interval in microseconds in CX:DX
+ * See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
+ * for more information.
+ */
+ Sleep(MAKELONG(getDX(), getCX()));
+
+ /* Clear CF */
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+
+ break;
+ }
+
+ /* Copy Extended Memory */
+ case 0x87:
+ {
+ DWORD Count = (DWORD)getCX() * 2;
+ PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI());
+ DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24);
+ DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16);
+ DWORD DestBase = Gdt[3].Base + (Gdt[3].BaseMid << 16) + (Gdt[3].BaseHigh << 24);
+ DWORD DestLimit = Gdt[3].Limit + (Gdt[3].LimitHigh << 16);
+
+ /* Check for flags */
+ if (Gdt[2].Granularity) SourceLimit = (SourceLimit << 12) | 0xFFF;
+ if (Gdt[3].Granularity) DestLimit = (DestLimit << 12) | 0xFFF;
+
+ if ((Count > SourceLimit) || (Count > DestLimit))
+ {
+ setAX(0x80);
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+
+ break;
+ }
+
+ /* Copy */
+ RtlMoveMemory((PVOID)((ULONG_PTR)BaseAddress + DestBase),
+ (PVOID)((ULONG_PTR)BaseAddress + SourceBase),
+ Count);
+
+ setAX(ERROR_SUCCESS);
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+ break;
+ }
+
+ /* Get Extended Memory Size */
+ case 0x88:
+ {
+ UCHAR Low, High;
+
+ /*
+ * Return the (usable) extended memory (after 1 MB)
+ * size in kB from CMOS.
+ */
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_LOW);
+ Low = IOReadB(CMOS_DATA_PORT);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_ACTUAL_EXT_MEMORY_HIGH);
+ High = IOReadB(CMOS_DATA_PORT);
+ setAX(MAKEWORD(Low, High));
+
+ /* Clear CF */
+ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
+ getAH());
+ }
+ }
+}
+
+static VOID WINAPI BiosTimeService(LPWORD Stack)
+{
+ switch (getAH())
+ {
+ case 0x00:
+ {
+ /* Set AL to 1 if midnight had passed, 0 otherwise */
+ setAL(Bda->MidnightPassed ? 0x01 : 0x00);
+
+ /* Return the tick count in CX:DX */
+ setCX(HIWORD(Bda->TickCounter));
+ setDX(LOWORD(Bda->TickCounter));
+
+ /* Reset the midnight flag */
+ Bda->MidnightPassed = FALSE;
+
+ break;
+ }
+
+ case 0x01:
+ {
+ /* Set the tick count to CX:DX */
+ Bda->TickCounter = MAKELONG(getDX(), getCX());
+
+ /* Reset the midnight flag */
+ Bda->MidnightPassed = FALSE;
+
+ break;
+ }
+
+ default:
+ {
+ DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n",
+ getAH());
+ }
+ }
+}
+
+static VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack)
+{
+ /* Increase the system tick count */
+ Bda->TickCounter++;
+}
+
+
+// From SeaBIOS
+static VOID PicSetIRQMask(USHORT off, USHORT on)
+{
+ UCHAR pic1off = off, pic1on = on, pic2off = off>>8, pic2on = on>>8;
+ IOWriteB(PIC_MASTER_DATA, (IOReadB(PIC_MASTER_DATA) & ~pic1off) | pic1on);
+ IOWriteB(PIC_SLAVE_DATA , (IOReadB(PIC_SLAVE_DATA ) & ~pic2off) | pic2on);
+}
+
+// From SeaBIOS
+VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
+{
+ UCHAR vector;
+
+ PicSetIRQMask(1 << hwirq, 0);
+ if (hwirq < 8)
+ vector = BIOS_PIC_MASTER_INT + hwirq;
+ else
+ vector = BIOS_PIC_SLAVE_INT + hwirq - 8;
+
+ RegisterInt32(vector, func);
+}
+
+
+VOID PicIRQComplete(LPWORD Stack)
+{
+ /* 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 */
+ IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
+ }
+ else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
+ {
+ /* It was an IRQ from the slave PIC */
+ IOWriteB(PIC_SLAVE_CMD , PIC_OCW2_EOI);
+ IOWriteB(PIC_MASTER_CMD, PIC_OCW2_EOI);
+ }
+}
+
+static VOID WINAPI BiosHandleMasterPicIRQ(LPWORD Stack)
+{
+ BYTE IrqNumber;
+
+ IOWriteB(PIC_MASTER_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
+ IrqNumber = IOReadB(PIC_MASTER_CMD);
+
+ DPRINT("Master - IrqNumber = 0x%x\n", IrqNumber);
+
+ PicIRQComplete(Stack);
+}
+
+static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
+{
+ BYTE IrqNumber;
+
+ IOWriteB(PIC_SLAVE_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
+ IrqNumber = IOReadB(PIC_SLAVE_CMD);
+
+ DPRINT("Slave - IrqNumber = 0x%x\n", IrqNumber);
+
+ PicIRQComplete(Stack);
+}
+
+// Timer IRQ 0
+static VOID WINAPI BiosTimerIrq(LPWORD Stack)
+{
+ /*
+ * Perform the system timer interrupt.
+ *
+ * Do not call directly BiosSystemTimerInterrupt(Stack);
+ * because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
+ * for their purpose...
+ */
+ EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT);
+ PicIRQComplete(Stack);
+}
+
+
+static VOID BiosHwSetup(VOID)
+{
+ /* Initialize the master and the slave PICs (cascade mode) */
+ IOWriteB(PIC_MASTER_CMD, PIC_ICW1 | PIC_ICW1_ICW4);
+ IOWriteB(PIC_SLAVE_CMD , PIC_ICW1 | PIC_ICW1_ICW4);
+
+ /*
+ * Set the interrupt vector offsets for each PIC
+ * (base IRQs: 0x08-0x0F for IRQ 0-7, 0x70-0x77 for IRQ 8-15)
+ */
+ IOWriteB(PIC_MASTER_DATA, BIOS_PIC_MASTER_INT);
+ IOWriteB(PIC_SLAVE_DATA , BIOS_PIC_SLAVE_INT );
+
+ /* Tell the master PIC that there is a slave PIC at IRQ 2 */
+ IOWriteB(PIC_MASTER_DATA, 1 << 2);
+ /* Tell the slave PIC its cascade identity */
+ IOWriteB(PIC_SLAVE_DATA , 2);
+
+ /* Make sure both PICs are in 8086 mode */
+ IOWriteB(PIC_MASTER_DATA, PIC_ICW4_8086);
+ IOWriteB(PIC_SLAVE_DATA , PIC_ICW4_8086);
+
+ /* Clear the masks for both PICs */
+ // IOWriteB(PIC_MASTER_DATA, 0x00);
+ // IOWriteB(PIC_SLAVE_DATA , 0x00);
+ /* Disable all IRQs */
+ IOWriteB(PIC_MASTER_DATA, 0xFF);
+ IOWriteB(PIC_SLAVE_DATA , 0xFF);
+
+
+ /* Initialize PIT Counter 0 */
+ IOWriteB(PIT_COMMAND_PORT, 0x34);
+ IOWriteB(PIT_DATA_PORT(0), 0x00);
+ IOWriteB(PIT_DATA_PORT(0), 0x00);
+
+ /* Initialize PIT Counter 1 */
+ IOWriteB(PIT_COMMAND_PORT, 0x74);
+ IOWriteB(PIT_DATA_PORT(1), 0x00);
+ IOWriteB(PIT_DATA_PORT(1), 0x00);
+
+ /* Initialize PIT Counter 2 */
+ IOWriteB(PIT_COMMAND_PORT, 0xB4);
+ IOWriteB(PIT_DATA_PORT(2), 0x00);
+ IOWriteB(PIT_DATA_PORT(2), 0x00);
+
+ EnableHwIRQ(0, BiosTimerIrq);
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * The BIOS POST (Power On-Self Test)
+ */
+BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput,
+ IN HANDLE ConsoleOutput)
+{
+ UCHAR Low, High;
+ UCHAR i;
+
+ /* Initialize the BDA */
+ Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
+ Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
+
+ /*
+ * Retrieve the conventional memory size
+ * in kB from CMOS, typically 640 kB.
+ */
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_LOW);
+ Low = IOReadB(CMOS_DATA_PORT);
+ IOWriteB(CMOS_ADDRESS_PORT, CMOS_REG_BASE_MEMORY_HIGH);
+ High = IOReadB(CMOS_DATA_PORT);
+ Bda->MemorySize = MAKEWORD(Low, High);
+
+ /* Initialize the 32-bit Interrupt system */
+ InitializeInt32(BIOS_SEGMENT);
+
+ /* Register the BIOS 32-bit Interrupts */
+
+ /* Initialize the exception vector interrupts to a default Exception handler */
+ for (i = 0; i < 8; i++)
+ RegisterInt32(i, BiosException);
+
+ /* Initialize HW vector interrupts to a default HW handler */
+ for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++)
+ RegisterInt32(i, BiosHandleMasterPicIRQ);
+ for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT + 8; i++)
+ RegisterInt32(i, BiosHandleSlavePicIRQ);
+
+ /* Initialize software vector handlers */
+ RegisterInt32(BIOS_EQUIPMENT_INTERRUPT, BiosEquipmentService );
+ RegisterInt32(BIOS_MEMORY_SIZE , BiosGetMemorySize );
+ RegisterInt32(BIOS_MISC_INTERRUPT , BiosMiscService );
+ RegisterInt32(BIOS_TIME_INTERRUPT , BiosTimeService );
+ RegisterInt32(BIOS_SYS_TIMER_INTERRUPT, BiosSystemTimerInterrupt);
+
+ /* Some interrupts are in fact addresses to tables */
+ ((PDWORD)BaseAddress)[0x1E] = (DWORD)NULL;
+ ((PDWORD)BaseAddress)[0x41] = (DWORD)NULL;
+ ((PDWORD)BaseAddress)[0x46] = (DWORD)NULL;
+ ((PDWORD)BaseAddress)[0x48] = (DWORD)NULL;
+ ((PDWORD)BaseAddress)[0x49] = (DWORD)NULL;
+
+ /* Initialize platform hardware (PIC/PIT chips, ...) */
+ BiosHwSetup();
+
+ /* Initialize the Keyboard BIOS */
+ if (!KbdBios32Initialize(ConsoleInput)) return FALSE;
+
+ /* Set the console input mode */
+ SetConsoleMode(ConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT);
+
+ /* Initialize the Video BIOS */
+ if (!VidBios32Initialize(ConsoleOutput)) return FALSE;
+
+ return TRUE;
+}
+
+VOID Bios32Cleanup(VOID)
+{
+ VidBios32Cleanup();
+ KbdBios32Cleanup();
+}
+
+/* EOF */
--- /dev/null
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: bios32.h
+ * PURPOSE: VDM 32-bit BIOS
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#ifndef _BIOS32_H_
+#define _BIOS32_H_
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+#include "kbdbios32.h"
+#include "vidbios32.h"
+
+/* DEFINES ********************************************************************/
+
+#define BIOS_PIC_MASTER_INT 0x08
+#define BIOS_PIC_SLAVE_INT 0x70
+
+#define BIOS_EQUIPMENT_INTERRUPT 0x11
+#define BIOS_MEMORY_SIZE 0x12
+#define BIOS_MISC_INTERRUPT 0x15
+#define BIOS_TIME_INTERRUPT 0x1A
+#define BIOS_SYS_TIMER_INTERRUPT 0x1C
+
+#define BIOS_EQUIPMENT_LIST 0x2C // HACK: Disable FPU for now
+
+
+#define ROM_AREA_START 0xE0000
+#define ROM_AREA_END 0xFFFFF
+
+#define BDA_SEGMENT 0x40
+#define BIOS_SEGMENT 0xF000
+
+/*
+ * BIOS Data Area at 0040:XXXX
+ *
+ * See: http://webpages.charter.net/danrollins/techhelp/0093.HTM
+ * and: http://www.bioscentral.com/misc/bda.htm
+ * for more information.
+ */
+#pragma pack(push, 1)
+typedef struct
+{
+ WORD SerialPorts[4]; // 0x00
+ WORD ParallelPorts[3]; // 0x08
+ WORD EbdaSegment; // 0x0e - ParallelPort in PC/XT
+ WORD EquipmentList; // 0x10
+ BYTE Reserved0; // 0x12 - Errors in PCjr infrared keyboard link
+ WORD MemorySize; // 0x13
+ WORD Reserved1; // 0x15 - Scratch pad for manufacturing error tests
+ WORD KeybdShiftFlags; // 0x17
+ BYTE AlternateKeypad; // 0x19
+ WORD KeybdBufferHead; // 0x1a
+ WORD KeybdBufferTail; // 0x1c
+ WORD KeybdBuffer[BIOS_KBD_BUFFER_SIZE]; // 0x1e
+ BYTE DriveRecalibrate; // 0x3e
+ BYTE DriveMotorStatus; // 0x3f
+ BYTE MotorShutdownCounter; // 0x40
+ BYTE LastDisketteOperation; // 0x41
+ BYTE Reserved2[7]; // 0x42
+ BYTE VideoMode; // 0x49
+ WORD ScreenColumns; // 0x4a
+ WORD VideoPageSize; // 0x4c
+ WORD VideoPageOffset; // 0x4e
+ WORD CursorPosition[BIOS_MAX_PAGES]; // 0x50
+ BYTE CursorEndLine; // 0x60
+ BYTE CursorStartLine; // 0x61
+ BYTE VideoPage; // 0x62
+ WORD CrtBasePort; // 0x63
+ BYTE CrtModeControl; // 0x65
+ BYTE CrtColorPaletteMask; // 0x66
+ BYTE CassetteData[5]; // 0x67
+ DWORD TickCounter; // 0x6c
+ BYTE MidnightPassed; // 0x70
+ BYTE BreakFlag; // 0x71
+ WORD SoftReset; // 0x72
+ BYTE LastDiskOperation; // 0x74
+ BYTE NumDisks; // 0x75
+ BYTE DriveControlByte; // 0x76
+ BYTE DiskPortOffset; // 0x77
+ BYTE LptTimeOut[4]; // 0x78
+ BYTE ComTimeOut[4]; // 0x7c
+ WORD KeybdBufferStart; // 0x80
+ WORD KeybdBufferEnd; // 0x82
+ BYTE ScreenRows; // 0x84
+ WORD CharacterHeight; // 0x85
+ BYTE EGAFlags[2]; // 0x87
+ BYTE VGAFlags[2]; // 0x89
+ DWORD Reserved3; // 0x8b
+ BYTE Reserved4; // 0x8f
+ BYTE Reserved5[2]; // 0x90
+ BYTE Reserved6[2]; // 0x92
+ BYTE Reserved7[2]; // 0x94
+ WORD Reserved8; // 0x96
+ DWORD Reserved9; // 0x98
+ DWORD Reserved10; // 0x9c
+ DWORD Reserved11[2]; // 0xa0
+ 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;
+#pragma pack(pop)
+
+C_ASSERT(sizeof(BIOS_DATA_AREA) == 0x133);
+
+/* FUNCTIONS ******************************************************************/
+
+extern PBIOS_DATA_AREA Bda;
+
+/**HACK!!**/typedef VOID (WINAPI *EMULATOR_INT32_PROC)(LPWORD Stack);/**HACK!!**/
+
+VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func);
+VOID PicIRQComplete(LPWORD Stack);
+
+BOOLEAN Bios32Initialize(IN HANDLE ConsoleInput,
+ IN HANDLE ConsoleOutput);
+VOID Bios32Cleanup(VOID);
+
+#endif // _BIOS32_H_
+
+/* EOF */
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
- * FILE: kbdbios.c
- * PURPOSE: VDM Keyboard BIOS
+ * FILE: kbdbios32.c
+ * PURPOSE: VDM Keyboard 32-bit BIOS
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
#define NDEBUG
#include "emulator.h"
-// #include "kbdbios.h"
-#include "bios.h"
+// #include "kbdbios32.h"
+#include "bios32.h"
#include "io.h"
#include "hardware/ps2.h"
/* PUBLIC FUNCTIONS ***********************************************************/
-BOOLEAN KbdBiosInitialize(HANDLE ConsoleInput)
+BOOLEAN KbdBios32Initialize(HANDLE ConsoleInput)
{
/* Initialize the BDA */
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
return TRUE;
}
-VOID KbdBiosCleanup(VOID)
+VOID KbdBios32Cleanup(VOID)
{
}
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
- * FILE: kbdbios.h
- * PURPOSE: VDM Keyboard BIOS
+ * FILE: kbdbios32.h
+ * PURPOSE: VDM Keyboard 32-bit BIOS
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
-#ifndef _KBDBIOS_H_
-#define _KBDBIOS_H_
+#ifndef _KBDBIOS32_H_
+#define _KBDBIOS32_H_
/* INCLUDES *******************************************************************/
WORD BiosPeekCharacter(VOID);
WORD BiosGetCharacter(VOID);
-BOOLEAN KbdBiosInitialize(HANDLE ConsoleInput);
-VOID KbdBiosCleanup(VOID);
+BOOLEAN KbdBios32Initialize(HANDLE ConsoleInput);
+VOID KbdBios32Cleanup(VOID);
-#endif // _KBDBIOS_H_
+#endif // _KBDBIOS32_H_
/* EOF */
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
- * FILE: vidbios.c
- * PURPOSE: VDM Video BIOS
+ * FILE: vidbios32.c
+ * PURPOSE: VDM Video 32-bit BIOS
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
#define NDEBUG
#include "emulator.h"
-// #include "vidbios.h"
-#include "bios.h"
+// #include "vidbios32.h"
+#include "bios32.h"
#include "io.h"
#include "hardware/vga.h"
/* PUBLIC FUNCTIONS ***********************************************************/
-BOOLEAN VidBiosInitialize(HANDLE ConsoleOutput)
+BOOLEAN VidBios32Initialize(HANDLE ConsoleOutput)
{
/* Some interrupts are in fact addresses to tables */
((PDWORD)BaseAddress)[0x1D] = (DWORD)NULL;
return TRUE;
}
-VOID VidBiosCleanup(VOID)
+VOID VidBios32Cleanup(VOID)
{
}
/*
* COPYRIGHT: GPL - See COPYING in the top level directory
* PROJECT: ReactOS Virtual DOS Machine
- * FILE: vidbios.h
- * PURPOSE: VDM Video BIOS
+ * FILE: vidbios32.h
+ * PURPOSE: VDM Video 32-bit BIOS
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
-#ifndef _VIDBIOS_H_
-#define _VIDBIOS_H_
+#ifndef _VIDBIOS32_H_
+#define _VIDBIOS32_H_
/* INCLUDES *******************************************************************/
VOID VidBiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page);
-BOOLEAN VidBiosInitialize(HANDLE BiosConsoleOutput);
-VOID VidBiosCleanup(VOID);
+BOOLEAN VidBios32Initialize(HANDLE BiosConsoleOutput);
+VOID VidBios32Cleanup(VOID);
-#endif // _VIDBIOS_H_
+#endif // _VIDBIOS32_H_
/* EOF */
if (hCmosRam != INVALID_HANDLE_VALUE)
{
- BOOL Success = FALSE;
+ BOOL Success;
/* Attempt to fill the CMOS memory with the RAM file */
SetLastError(0); // For debugging purposes
#include "resource.h"
/*
- * Activate this line if you want to be able to test NTVDM with:
+ * Activate this line if you want to run NTVDM in standalone mode with:
* ntvdm.exe <program>
*/
-#define TESTING
+#define STANDALONE
/* VARIABLES ******************************************************************/
INT wmain(INT argc, WCHAR *argv[])
{
- CHAR CommandLine[DOS_CMDLINE_LENGTH];
+#ifndef STANDALONE
+ wprintf(L"\nReactOS Virtual DOS Machine\n\n"
+ L"OS integration (BaseVDM) unimplemented\n");
+ return 0;
+#else
-#ifndef TESTING
- UNREFERENCED_PARAMETER(argc);
- UNREFERENCED_PARAMETER(argv);
+ CHAR CommandLine[DOS_CMDLINE_LENGTH];
- /* The DOS command line must be ASCII */
- WideCharToMultiByte(CP_ACP, 0, GetCommandLine(), -1, CommandLine, sizeof(CommandLine), NULL, NULL);
-#else
if (argc == 2 && argv[1] != NULL)
{
WideCharToMultiByte(CP_ACP, 0, argv[1], -1, CommandLine, sizeof(CommandLine), NULL, NULL);
L"Usage: NTVDM <executable>\n");
return 0;
}
-#endif
DPRINT1("\n\n\nNTVDM - Starting '%s'...\n\n\n", CommandLine);
}
/* Initialize the system BIOS */
- if (!BiosInitialize(ConsoleInput, ConsoleOutput))
+ if (!BiosInitialize(NULL, ConsoleInput, ConsoleOutput))
{
wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
goto Cleanup;
DPRINT1("\n\n\nNTVDM - Exiting...\n\n\n");
return 0;
+
+#endif
}
/* EOF */