diff options
Diffstat (limited to 'private/mvdm/v86/scaffold/i386/fakeinit.c')
-rw-r--r-- | private/mvdm/v86/scaffold/i386/fakeinit.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/private/mvdm/v86/scaffold/i386/fakeinit.c b/private/mvdm/v86/scaffold/i386/fakeinit.c new file mode 100644 index 000000000..ae5d586de --- /dev/null +++ b/private/mvdm/v86/scaffold/i386/fakeinit.c @@ -0,0 +1,123 @@ +// +// Fake Bios support initialization. +// +// This file provides interrim support for rom bios services initialization. +// It is only intended for use until Insignia produces proper rom support +// for NTVDM +// + +#include <windows.h> +#include <stdio.h> +#include <conio.h> +#include <string.h> +#include "softpc.h" +#include "bop.h" +#include "xguest.h" +#include "xbios.h" +#include "xbiosdsk.h" +#include "fun.h" + +#define SERVICE_LENGTH 4 +static BYTE ServiceRoutine[] = { 0xC4 , 0xC4, BOP_UNIMPINT, 0xCF }; + +#define RESET_LENGTH 16 +static BYTE ResetRoutine[] = { 0xEA, 0x00, 0x00, 0x00, 0xE0, // jmpf E000:0 + BIOSDATE_MINE, + 0, 0xFE, 0 }; + +static BYTE WarmBoot[] = { + OPX_MOVAX, BYTESOFFSET(0x30), + OPX_MOV2SEG, MODREGRM(MOD_REGISTER,REG_SS,REG_AX), + OPX_MOVSP, BYTESOFFSET(0x100), + OPX_MOVAX, 0x00, 0x00, + OPX_MOV2SEG, MODREGRM(MOD_REGISTER,REG_DS,REG_AX), + OPX_MOV2SEG, MODREGRM(MOD_REGISTER,REG_ES,REG_AX), + OPX_MOVDX, DRIVE_FD0, 0x00, // WARNING: sync with BIOSBOOT_DRIVE + OPX_MOVCX, 0x01, 0x00, + OPX_MOVBX, BYTESOFFSET(BIOSDATA_BOOT), + OPX_MOVAX, 0x01, DSKFUNC_READSECTORS, + OPX_INT, BIOSINT_DSK, + OPX_JB, -7, + OPX_JMPF, BYTESCOMPOSITE(0, BIOSDATA_BOOT) +}; +#define WARMBOOT_LENGTH sizeof(WarmBoot) + +static BYTE EquipmentRoutine[] = { // INT 11h code + OPX_PUSHDS, + OPX_MOVAX, 0x00, 0x00, + OPX_MOV2SEG, MODREGRM(MOD_REGISTER,REG_DS,REG_AX), + OPX_MOVAXOFF, BYTESOFFSET(BIOSDATA_EQUIP_FLAG), + OPX_POPDS, + OPX_IRET +}; +#define EQUIPMENT_LENGTH sizeof(EquipmentRoutine) + +static BYTE MemoryRoutine[] = { // INT 12h code + OPX_PUSHDS, + OPX_MOVAX, 0x00, 0x00, + OPX_MOV2SEG, MODREGRM(MOD_REGISTER,REG_DS,REG_AX), + OPX_MOVAXOFF, BYTESOFFSET(BIOSDATA_MEMORY_SIZE), + OPX_POPDS, + OPX_IRET +}; +#define MEMORY_LENGTH sizeof(MemoryRoutine) + + +VOID BiosInit(int argc, char *argv[]) { + + PVOID Address, RomAddress; + + // set up IVT with unimplemented interrupt handler + + for (Address = NULL; Address < (PVOID)(0x1D * 4); (PCHAR)Address += 4) { + *(PWORD)Address = 0x100; + *(((PWORD)Address) + 1) = 0xF000; + } + + RomAddress = (PVOID)(0xE000 << 4); + + // set up warm boot handler + memcpy(RomAddress, WarmBoot, WARMBOOT_LENGTH); + Address = RMSEGOFFTOLIN(0, BIOSINT_WBOOT * 4); + *((PWORD)Address) = 0; + *((PWORD)Address + 1) = 0xE000; + (PCHAR)RomAddress += WARMBOOT_LENGTH; + + // set up equipment interrupt handler + memcpy(RomAddress, EquipmentRoutine, EQUIPMENT_LENGTH); + Address = RMSEGOFFTOLIN(0, BIOSINT_EQUIP * 4); + *((PWORD)Address) = RMOFF(RomAddress); + *((PWORD)Address + 1) = RMSEG(RomAddress); + (PCHAR)RomAddress += EQUIPMENT_LENGTH; + + // set up memory size interrupt handler + memcpy(RomAddress, MemoryRoutine, MEMORY_LENGTH); + Address = RMSEGOFFTOLIN(0, BIOSINT_MEMORY * 4); + *((PWORD)Address) = RMOFF(RomAddress); + *((PWORD)Address + 1) = RMSEG(RomAddress); + + RomAddress = (PVOID)((0xF000 << 4) + 0x100); + + Address = (PBYTE)RomAddress + 0xFE53; + *(PCHAR)Address = 0xCF; // IRET at f000:ff53 + + // set up unimplemented interrupt handler + + memcpy(RomAddress, ServiceRoutine, SERVICE_LENGTH); + (PCHAR)RomAddress += SERVICE_LENGTH; + + // set up reset code + memcpy(RMSEGOFFTOLIN(BIOSROM_SEG, BIOSROM_RESET), ResetRoutine, RESET_LENGTH); + + // set up equipment byte and memory size + + *(PWORD)RMSEGOFFTOLIN(BIOSDATA_SEG, BIOSDATA_EQUIP_FLAG) = + BIOSEQUIP_32KPLANAR; + *(PWORD)RMSEGOFFTOLIN(BIOSDATA_SEG, BIOSDATA_MEMORY_SIZE) = + 640; + + // Initialize individual rom modules + + BiosKbdInit(argc, argv, &RomAddress); + BiosVidInit(argc, argv, &RomAddress); +} |