1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * COPYRIGHT: GPL - See COPYING in the top level directory 3*c2c66affSColin Finck * PROJECT: ReactOS Virtual DOS Machine 4*c2c66affSColin Finck * FILE: subsystems/mvdm/ntvdm/bios/bios.c 5*c2c66affSColin Finck * PURPOSE: VDM BIOS Support Library 6*c2c66affSColin Finck * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) 7*c2c66affSColin Finck */ 8*c2c66affSColin Finck 9*c2c66affSColin Finck /* INCLUDES *******************************************************************/ 10*c2c66affSColin Finck 11*c2c66affSColin Finck #include "ntvdm.h" 12*c2c66affSColin Finck 13*c2c66affSColin Finck #define NDEBUG 14*c2c66affSColin Finck #include <debug.h> 15*c2c66affSColin Finck 16*c2c66affSColin Finck #include "emulator.h" 17*c2c66affSColin Finck #include "cpu/callback.h" 18*c2c66affSColin Finck #include "cpu/bop.h" 19*c2c66affSColin Finck 20*c2c66affSColin Finck #include "bios.h" 21*c2c66affSColin Finck #include "bios32/bios32.h" 22*c2c66affSColin Finck #include "rom.h" 23*c2c66affSColin Finck #include "umamgr.h" 24*c2c66affSColin Finck 25*c2c66affSColin Finck #include "io.h" 26*c2c66affSColin Finck #include "hardware/cmos.h" 27*c2c66affSColin Finck 28*c2c66affSColin Finck #include <stdlib.h> 29*c2c66affSColin Finck 30*c2c66affSColin Finck /* DEFINES ********************************************************************/ 31*c2c66affSColin Finck 32*c2c66affSColin Finck /* BOP Identifiers */ 33*c2c66affSColin Finck #define BOP_RESET 0x00 // Windows NTVDM (SoftPC) BIOS calls BOP 0x00 34*c2c66affSColin Finck // to let the virtual machine perform the POST. 35*c2c66affSColin Finck #define BOP_EQUIPLIST 0x11 36*c2c66affSColin Finck #define BOP_GETMEMSIZE 0x12 37*c2c66affSColin Finck 38*c2c66affSColin Finck /* PRIVATE VARIABLES **********************************************************/ 39*c2c66affSColin Finck 40*c2c66affSColin Finck static BOOLEAN Bios32Loaded = FALSE; 41*c2c66affSColin Finck 42*c2c66affSColin Finck PBIOS_DATA_AREA Bda; 43*c2c66affSColin Finck PBIOS_CONFIG_TABLE Bct; 44*c2c66affSColin Finck 45*c2c66affSColin Finck /* PRIVATE FUNCTIONS **********************************************************/ 46*c2c66affSColin Finck 47*c2c66affSColin Finck /* PUBLIC FUNCTIONS ***********************************************************/ 48*c2c66affSColin Finck 49*c2c66affSColin Finck VOID WINAPI 50*c2c66affSColin Finck WinNtVdmBiosReset(LPWORD Stack) 51*c2c66affSColin Finck { 52*c2c66affSColin Finck DisplayMessage(L"You are loading Windows NTVDM BIOS!\n"); 53*c2c66affSColin Finck // Bios32Post(Stack); 54*c2c66affSColin Finck 55*c2c66affSColin Finck DisplayMessage(L"ReactOS NTVDM doesn't support Windows NTVDM BIOS at the moment. The VDM will shut down."); 56*c2c66affSColin Finck EmulatorTerminate(); 57*c2c66affSColin Finck } 58*c2c66affSColin Finck 59*c2c66affSColin Finck BOOLEAN 60*c2c66affSColin Finck BiosInitialize(IN LPCSTR BiosFileName, 61*c2c66affSColin Finck IN LPCSTR RomFiles OPTIONAL) 62*c2c66affSColin Finck { 63*c2c66affSColin Finck BOOLEAN Success = FALSE; 64*c2c66affSColin Finck BOOLEAN Success2 = FALSE; 65*c2c66affSColin Finck LPCSTR RomFile; 66*c2c66affSColin Finck LPSTR ptr; 67*c2c66affSColin Finck ULONG RomAddress; 68*c2c66affSColin Finck CHAR RomFileName[MAX_PATH + 10 + 1]; 69*c2c66affSColin Finck 70*c2c66affSColin Finck /* Disable interrupts */ 71*c2c66affSColin Finck setIF(0); 72*c2c66affSColin Finck 73*c2c66affSColin Finck /* Initialize the BDA and the BCT pointers */ 74*c2c66affSColin Finck Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT , 0x0000); 75*c2c66affSColin Finck // The BCT is found at F000:E6F5 for 100% compatible BIOSes. 76*c2c66affSColin Finck Bct = (PBIOS_CONFIG_TABLE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xE6F5); 77*c2c66affSColin Finck 78*c2c66affSColin Finck /* Register the BIOS support BOPs */ 79*c2c66affSColin Finck RegisterBop(BOP_RESET, WinNtVdmBiosReset); // Needed for Windows NTVDM (SoftPC) BIOS. 80*c2c66affSColin Finck RegisterBop(BOP_EQUIPLIST , BiosEquipmentService); // Needed by Windows NTVDM (SoftPC) BIOS 81*c2c66affSColin Finck RegisterBop(BOP_GETMEMSIZE, BiosGetMemorySize); // and also NTDOS!! 82*c2c66affSColin Finck 83*c2c66affSColin Finck if (BiosFileName == NULL) 84*c2c66affSColin Finck { 85*c2c66affSColin Finck Success = Bios32Loaded = Bios32Initialize(); 86*c2c66affSColin Finck } 87*c2c66affSColin Finck else if (BiosFileName[0] != '\0') 88*c2c66affSColin Finck { 89*c2c66affSColin Finck PVOID BiosLocation = NULL; 90*c2c66affSColin Finck 91*c2c66affSColin Finck Success = LoadBios(BiosFileName, &BiosLocation, NULL); 92*c2c66affSColin Finck DPRINT1("BIOS file '%s' loading %s at address 0x%08x; GetLastError() = %u\n", 93*c2c66affSColin Finck BiosFileName, Success ? "succeeded" : "failed", BiosLocation, GetLastError()); 94*c2c66affSColin Finck } 95*c2c66affSColin Finck else // if (BiosFileName[0] == '\0') 96*c2c66affSColin Finck { 97*c2c66affSColin Finck /* Do nothing */ 98*c2c66affSColin Finck Success = TRUE; 99*c2c66affSColin Finck } 100*c2c66affSColin Finck 101*c2c66affSColin Finck /* Bail out now if we failed to load any BIOS file */ 102*c2c66affSColin Finck if (!Success) return FALSE; 103*c2c66affSColin Finck 104*c2c66affSColin Finck /* Load optional ROMs */ 105*c2c66affSColin Finck if (RomFiles) 106*c2c66affSColin Finck { 107*c2c66affSColin Finck RomFile = RomFiles; 108*c2c66affSColin Finck while (*RomFile) 109*c2c66affSColin Finck { 110*c2c66affSColin Finck strncpy(RomFileName, RomFile, ARRAYSIZE(RomFileName)); 111*c2c66affSColin Finck RomFileName[ARRAYSIZE(RomFileName)-1] = '\0'; 112*c2c66affSColin Finck 113*c2c66affSColin Finck ptr = strchr(RomFileName, '|'); // Since '|' is forbidden as a valid file name, we use it as a separator for the ROM address. 114*c2c66affSColin Finck if (!ptr) goto Skip; 115*c2c66affSColin Finck *ptr++ = '\0'; 116*c2c66affSColin Finck 117*c2c66affSColin Finck RomAddress = strtoul(ptr, NULL, 0); // ROM segment 118*c2c66affSColin Finck RomAddress <<= 4; // Convert to real address 119*c2c66affSColin Finck if (RomAddress == 0) goto Skip; 120*c2c66affSColin Finck 121*c2c66affSColin Finck Success2 = LoadRom(RomFileName, (PVOID)RomAddress, NULL); 122*c2c66affSColin Finck DPRINT1("ROM file '%s' loading %s at address 0x%08x; GetLastError() = %u\n", 123*c2c66affSColin Finck RomFileName, Success2 ? "succeeded" : "failed", RomAddress, GetLastError()); 124*c2c66affSColin Finck 125*c2c66affSColin Finck Skip: 126*c2c66affSColin Finck RomFile += strlen(RomFile) + 1; 127*c2c66affSColin Finck } 128*c2c66affSColin Finck } 129*c2c66affSColin Finck 130*c2c66affSColin Finck /* 131*c2c66affSColin Finck * Boot it up. 132*c2c66affSColin Finck * The CPU is already in reset-mode so that 133*c2c66affSColin Finck * CS:IP points to F000:FFF0 as required. 134*c2c66affSColin Finck */ 135*c2c66affSColin Finck // DisplayMessage(L"CS:IP=%04X:%04X", getCS(), getIP()); 136*c2c66affSColin Finck // setCS(0xF000); 137*c2c66affSColin Finck // setIP(0xFFF0); 138*c2c66affSColin Finck 139*c2c66affSColin Finck // /* Enable interrupts */ 140*c2c66affSColin Finck // setIF(1); 141*c2c66affSColin Finck 142*c2c66affSColin Finck /* Initialize the Upper Memory Area Manager */ 143*c2c66affSColin Finck if (!UmaMgrInitialize()) 144*c2c66affSColin Finck { 145*c2c66affSColin Finck wprintf(L"FATAL: Failed to initialize the UMA manager.\n"); 146*c2c66affSColin Finck return FALSE; 147*c2c66affSColin Finck } 148*c2c66affSColin Finck 149*c2c66affSColin Finck return Success; 150*c2c66affSColin Finck } 151*c2c66affSColin Finck 152*c2c66affSColin Finck VOID 153*c2c66affSColin Finck BiosCleanup(VOID) 154*c2c66affSColin Finck { 155*c2c66affSColin Finck UmaMgrCleanup(); 156*c2c66affSColin Finck 157*c2c66affSColin Finck if (Bios32Loaded) Bios32Cleanup(); 158*c2c66affSColin Finck } 159*c2c66affSColin Finck 160*c2c66affSColin Finck /* EOF */ 161