ReactOS  0.4.13-dev-247-g0f29b3f
bios32.c File Reference
#include "ntvdm.h"
#include <reactos/buildno.h>
#include <reactos/version.h>
#include <debug.h>
#include "emulator.h"
#include "cpu/cpu.h"
#include "cpu/bop.h"
#include "int32.h"
#include <isvbop.h>
#include <bios/bios.h>
#include <bios/rom.h>
#include "bios32.h"
#include "bios32p.h"
#include "dskbios32.h"
#include "kbdbios32.h"
#include "vidbios32.h"
#include "moubios32.h"
#include "memory.h"
#include "io.h"
#include "hardware/cmos.h"
#include "hardware/pic.h"
#include "hardware/pit.h"
#include "hardware/ps2.h"
Include dependency graph for bios32.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define BIOS_MODEL   0xFC
 
#define BIOS_SUBMODEL   0x01
 
#define BIOS_REVISION   0x00
 

Functions

 C_ASSERT (sizeof(BiosCopyright) -1<=0x5B)
 
 C_ASSERT (sizeof(BiosDate) -1==0x08)
 
static VOID BiosCharPrint (CHAR Character)
 
static VOID WINAPI BiosException (LPWORD Stack)
 
VOID WINAPI BiosEquipmentService (LPWORD Stack)
 
VOID WINAPI BiosGetMemorySize (LPWORD Stack)
 
static VOID WINAPI BiosMiscService (LPWORD Stack)
 
static VOID WINAPI BiosRomBasic (LPWORD Stack)
 
VOID DosBootsectorInitialize (VOID)
 
VOID WINAPI BiosDiskService (LPWORD Stack)
 
static VOID WINAPI BiosBootstrapLoader (LPWORD Stack)
 
static VOID WINAPI BiosTimeService (LPWORD Stack)
 
static VOID WINAPI BiosSystemTimerInterrupt (LPWORD Stack)
 
static VOID PicSetIRQMask (USHORT off, USHORT on)
 
VOID EnableHwIRQ (UCHAR hwirq, EMULATOR_INT32_PROC func)
 
VOID PicIRQComplete (BYTE IntNum)
 
static VOID WINAPI BiosHandleMasterPicIRQ (LPWORD Stack)
 
static VOID WINAPI BiosHandleSlavePicIRQ (LPWORD Stack)
 
static VOID WINAPI BiosTimerIrq (LPWORD Stack)
 
static VOID BiosHwSetup (VOID)
 
static VOID InitializeBiosInt32 (VOID)
 
static VOID InitializeBiosData (VOID)
 
VOID WINAPI Bios32Post (LPWORD Stack)
 
BOOLEAN Bios32Initialize (VOID)
 
VOID Bios32Cleanup (VOID)
 

Variables

CALLBACK16 BiosContext
 
static const BIOS_CONFIG_TABLE BiosConfigTable
 
static const CHAR BiosCopyright [] = "0000000 NTVDM IBM COMPATIBLE 486 BIOS COPYRIGHT (C) ReactOS Team 1996-"COPYRIGHT_YEAR
 
static const CHAR BiosVersion []
 
static const CHAR BiosDate [] = "06/17/13"
 
static const BYTE Bootstrap []
 
static const BYTE PostCode []
 

Macro Definition Documentation

◆ BIOS_MODEL

#define BIOS_MODEL   0xFC

Definition at line 110 of file bios32.c.

◆ BIOS_REVISION

#define BIOS_REVISION   0x00

Definition at line 112 of file bios32.c.

◆ BIOS_SUBMODEL

#define BIOS_SUBMODEL   0x01

Definition at line 111 of file bios32.c.

◆ NDEBUG

#define NDEBUG

Definition at line 18 of file bios32.c.

Function Documentation

◆ Bios32Cleanup()

VOID Bios32Cleanup ( VOID  )

Definition at line 1285 of file bios32.c.

1286 {
1289  VidBios32Cleanup();
1290  KbdBiosCleanup();
1291 }
VOID VidBios32Cleanup(VOID)
Definition: vidbios32.c:67
VOID MouseBios32Cleanup(VOID)
Definition: moubios32.c:538
VOID DiskBios32Cleanup(VOID)
Definition: dskbios32.c:701
VOID KbdBiosCleanup(VOID)
Definition: kbdbios.c:93

Referenced by BiosCleanup().

◆ Bios32Initialize()

BOOLEAN Bios32Initialize ( VOID  )

Definition at line 1242 of file bios32.c.

1243 {
1244  /*
1245  * Initialize BIOS/Keyboard/Video ROM static data
1246  */
1247 
1248  /* System BIOS Copyright */
1250 
1251  /* System BIOS Version */
1253 
1254  /* System BIOS Date */
1256 
1257  /* Bootstrap code */
1260 
1261  /* BIOS ROM Information */
1263 
1264  /* System BIOS Model (same as Bct->Model) */
1266 
1267  /* Initialize the Keyboard and Video BIOS */
1269  {
1270  /* Stop the VDM */
1272  return FALSE;
1273  }
1274 
1275  /* Redefine our POST function */
1277 
1279  ROM_AREA_END - TO_LINEAR(BIOS_SEGMENT, 0x0000) + 1);
1280 
1281  /* We are done */
1282  return TRUE;
1283 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
BOOLEAN WriteProtectRom(IN PVOID RomLocation, IN ULONG RomSize)
Definition: rom.c:138
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
static const CHAR BiosVersion[]
Definition: bios32.c:139
#define BIOS_MODEL
Definition: bios32.c:110
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
BOOLEAN KbdBiosInitialize(VOID)
Definition: kbdbios.c:85
#define BOP_RESET
Definition: bios.c:33
static const BYTE Bootstrap[]
Definition: bios32.c:147
static const BYTE PostCode[]
Definition: bios32.c:157
static const CHAR BiosCopyright[]
Definition: bios32.c:138
BOOLEAN VidBiosInitialize(VOID)
Definition: vidbios.c:3981
#define TO_LINEAR(seg, off)
Definition: emulator.h:22
#define ROM_AREA_END
Definition: rom.h:15
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
static const CHAR BiosDate[]
Definition: bios32.c:141
BOOLEAN DiskBios32Initialize(VOID)
Definition: dskbios32.c:674
static const BIOS_CONFIG_TABLE BiosConfigTable
Definition: bios32.c:115
BOOLEAN MouseBiosInitialize(VOID)
Definition: moubios32.c:533
BYTE * PBYTE
Definition: pedump.c:66
VOID WINAPI Bios32Post(LPWORD Stack)
Definition: bios32.c:1064
#define BIOS_SEGMENT
Definition: bios.h:29

Referenced by BiosInitialize().

◆ Bios32Post()

VOID WINAPI Bios32Post ( LPWORD  Stack)

Definition at line 1064 of file bios32.c.

1065 {
1066  static BOOLEAN FirstBoot = TRUE;
1067  BYTE ShutdownStatus;
1068 
1069  /*
1070  * Initialize BIOS/Keyboard/Video RAM dynamic data
1071  */
1072 
1073  DPRINT("Bios32Post\n");
1074 
1075  /* Disable interrupts */
1076  setIF(0);
1077 
1078  /* Set the data segment */
1079  setDS(BDA_SEGMENT);
1080 
1081  /* Initialize the stack */
1082  // Temporary stack for POST (to be used only before initializing the INT vectors)
1083  // setSS(0x0000);
1084  // setSP(0x0400);
1085  //
1086  // Stack to be used after the initialization of the INT vectors
1087  setSS(0x0000); // Stack at 00:8000, going downwards
1088  setSP(0x8000);
1089 
1090  /*
1091  * Perform early CMOS shutdown status checks
1092  */
1093 
1094  /* Read the CMOS shutdown status byte and reset it */
1096  ShutdownStatus = IOReadB(CMOS_DATA_PORT);
1098  IOWriteB(CMOS_DATA_PORT, 0x00);
1099 
1100  DPRINT1("Bda->SoftReset = 0x%04X ; ShutdownStatus = 0x%02X\n",
1101  Bda->SoftReset, ShutdownStatus);
1102 
1103  switch (ShutdownStatus)
1104  {
1105  /* Shutdown after Memory Tests (unsupported) */
1106  case 0x01: case 0x02: case 0x03:
1107  /* Shutdown after Protected Mode Tests (unsupported) */
1108  case 0x06: case 0x07: case 0x08:
1109  /* Shutdown after Block Move Test (unsupported) */
1110  case 0x09:
1111  {
1112  DisplayMessage(L"Unsupported CMOS Shutdown Status value 0x%02X. The VDM will shut down.", ShutdownStatus);
1114  return;
1115  }
1116 
1117  /* Shutdown to Boot Loader */
1118  case 0x04:
1119  {
1120  DPRINT1("Fast restart to Bootstrap Loader...\n");
1121  goto Quit; // Reenable interrupts and exit.
1122  }
1123 
1124  /* Flush keyboard, issue an EOI... */
1125  case 0x05:
1126  {
1128 
1129  /* Send EOI */
1132 
1133  // Fall back
1134  }
1135 
1136  /*
1137  * ... and far JMP to user-specified location at 0040:0067
1138  * (Bda->ResumeEntryPoint) with interrupts and NMI disabled.
1139  */
1140  case 0x0A:
1141  {
1142  DPRINT1("Bda->ResumeEntryPoint = %04X:%04X\n",
1145 
1146  /* Position execution pointers and return with interrupts disabled */
1149  return;
1150  }
1151 
1152  /* Soft reset or unexpected shutdown... */
1153  case 0x00:
1154  /* ... or other possible shutdown codes: just continue the POST */
1155  default:
1156  break;
1157  }
1158 
1159  /*
1160  * FIXME: UNIMPLEMENTED!
1161  * Check the word at 0040h:0072h (Bda->SoftReset) and do one of the
1162  * following actions:
1163  * - if the word is 0000h, perform a cold reboot (aka. Reset). Everything gets initialized.
1164  * - if the word is 1234h, perform a warm reboot (aka. Ctrl-Alt-Del). Some stuff is skipped.
1165  */
1166  switch (Bda->SoftReset)
1167  {
1168  case 0x0000:
1169  {
1170  if (!FirstBoot)
1171  {
1172  DisplayMessage(L"NTVDM is performing a COLD reboot! The program you are currently testing does not seem to behave correctly! The VDM will shut down...");
1174  return;
1175  }
1176  break;
1177  }
1178 
1179  case 0x1234:
1180  {
1181  DisplayMessage(L"NTVDM is performing a WARM reboot! This is not supported at the moment. The VDM will shut down...");
1183  return;
1184  }
1185 
1186  default:
1187  break;
1188  }
1189 
1190  FirstBoot = FALSE;
1191 
1192  /* Initialize the BDA */
1194 
1195  /* Initialize the User Data Area at 0050:XXXX */
1196  RtlZeroMemory(SEG_OFF_TO_PTR(0x50, 0x0000), sizeof(USER_DATA_AREA));
1197 
1198 
1199 
1201 
1202  /*
1203  * Initialize IVT and hardware
1204  */
1205 
1206  // WriteUnProtectRom(...);
1207 
1208  /* Register the BIOS 32-bit Interrupts */
1210 
1211  /* Initialize platform hardware (PIC/PIT chips, ...) */
1212  BiosHwSetup();
1213 
1214  /* Initialize the Keyboard, Video and Mouse BIOS */
1215  KbdBios32Post();
1216  VidBiosPost();
1217  MouseBios32Post();
1218  DiskBios32Post();
1219 
1220  // WriteProtectRom(...);
1221 
1223 
1224 
1225 
1227 
1228  /*
1229  * End of the 32-bit POST portion. We then fall back into 16-bit where
1230  * the rest of the POST code is executed, typically calling INT 19h
1231  * to boot up the OS.
1232  */
1233 
1234 Quit:
1235  /* Enable interrupts */
1236  setIF(1);
1237 }
#define PS2_DATA_PORT
Definition: ps2.h:16
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
#define TRUE
Definition: types.h:120
#define CMOS_ADDRESS_PORT
Definition: cmos.h:15
VOID VidBiosPost(VOID)
Definition: vidbios.c:3932
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
PBIOS_DATA_AREA Bda
Definition: bios.c:42
DWORD ResumeEntryPoint
Definition: bios.h:74
VOID KbdBios32Post(VOID)
Definition: kbdbios32.c:361
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
static VOID BiosHwSetup(VOID)
Definition: bios32.c:893
VOID WINAPI setSP(USHORT)
Definition: registers.c:351
VOID WINAPI setSS(USHORT)
Definition: registers.c:501
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
unsigned char BOOLEAN
void DPRINT(...)
Definition: polytest.cpp:61
VOID DiskBios32Post(VOID)
Definition: dskbios32.c:647
#define PIC_MASTER_CMD
Definition: pic.h:15
static VOID InitializeBiosInt32(VOID)
Definition: bios32.c:956
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
CALLBACK16 BiosContext
Definition: bios32.c:45
#define CMOS_DATA_PORT
Definition: halp.h:15
static const WCHAR L[]
Definition: oid.c:1250
#define BDA_SEGMENT
Definition: bios.h:28
unsigned char BYTE
Definition: mem.h:68
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
#define PIC_OCW2_EOI
Definition: pic.h:27
VOID WINAPI setCS(USHORT)
Definition: registers.c:487
#define CMOS_DISABLE_NMI
Definition: cmos.h:17
VOID WINAPI setIF(ULONG)
Definition: registers.c:643
#define PIC_SLAVE_CMD
Definition: pic.h:17
VOID MouseBios32Post(VOID)
Definition: moubios32.c:486
#define DPRINT1
Definition: precomp.h:8
#define HIWORD(l)
Definition: typedefs.h:246
WORD SoftReset
Definition: bios.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static VOID InitializeBiosData(VOID)
Definition: bios32.c:1032
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
#define LOWORD(l)
Definition: pedump.c:82
VOID SearchAndInitRoms(IN PCALLBACK16 Context)
Definition: rom.c:252

Referenced by Bios32Initialize().

◆ BiosBootstrapLoader()

static VOID WINAPI BiosBootstrapLoader ( LPWORD  Stack)
static

Definition at line 567 of file bios32.c.

568 {
569  USHORT BootOrder;
570 
571  USHORT AX, BX, CX, DX, ES;
572  AX = getAX();
573  BX = getBX();
574  CX = getCX();
575  DX = getDX();
576  ES = getES();
577 
578  /*
579  * Read the boot sequence order from the CMOS, old behaviour AMI-style.
580  *
581  * For more information, see:
582  * http://www.virtualbox.org/svn/vbox/trunk/src/VBox/Devices/PC/BIOS/orgs.asm
583  * http://www.virtualbox.org/svn/vbox/trunk/src/VBox/Devices/PC/BIOS/boot.c
584  * http://bochs.sourceforge.net/cgi-bin/lxr/source/iodev/cmos.cc
585  * https://web.archive.org/web/20111209041013/http://www-ivs.cs.uni-magdeburg.de/~zbrog/asm/cmos.html
586  * http://www.bioscentral.com/misc/cmosmap.htm
587  */
589  BootOrder = (IOReadB(CMOS_DATA_PORT) & 0x20) >> 5;
590 
591  /*
592  * BootOrder =
593  * 0: Hard Disk, then Floppy Disk
594  * 1: Floppy Disk, then Hard Disk
595  * In all cases, if booting from those devices failed,
596  * ROM DOS-32 is started. If it fails, INT 18h is called.
597  */
598 
599  DPRINT("BiosBootstrapLoader (BootOrder = 0x%02X) -->\n", BootOrder);
600 
601  /*
602  * Format of the BootOrder command:
603  * 2 bytes. Each half-byte contains the ID of the drive to boot.
604  * Currently defined:
605  * 0x0: 1st Floppy disk
606  * 0x1: 1st Hard disk
607  * Other, or 0xF: Stop boot sequence.
608  */
609  BootOrder = 0xFF00 | ((1 << (4 * BootOrder)) & 0xFF);
610 
611 Retry:
612  switch (BootOrder & 0x0F)
613  {
614  /* Boot from 1st floppy drive */
615  case 0:
616  {
617  setAH(0x02); // Read sectors
618  setAL(0x01); // Number of sectors
619  setDH(0x00); // Head 0
620  setCH(0x00); // Cylinder 0
621  setCL(0x01); // Sector 1
622  setDL(0x00); // First diskette drive (used by loader code, so should not be cleared)
623  setES(0x0000); // Write data in 0000:7C00
624  setBX(0x7C00);
625  BiosDiskService(Stack);
626  if (!(Stack[STACK_FLAGS] & EMULATOR_FLAG_CF)) goto Quit;
627  DPRINT1("An error happened while loading the bootsector from floppy 0, error = %d\n", getAH());
628 
629  break;
630  }
631 
632  /* Boot from 1st HDD drive */
633  case 1:
634  {
635  setAH(0x02); // Read sectors
636  setAL(0x01); // Number of sectors
637  setDH(0x00); // Head 0
638  setCH(0x00); // Cylinder 0
639  setCL(0x01); // Sector 1
640  setDL(0x80); // First HDD drive (used by loader code, so should not be cleared)
641  setES(0x0000); // Write data in 0000:7C00
642  setBX(0x7C00);
643  BiosDiskService(Stack);
644  if (!(Stack[STACK_FLAGS] & EMULATOR_FLAG_CF)) goto Quit;
645  DPRINT1("An error happened while loading the bootsector from HDD 0, error = %d\n", getAH());
646 
647  break;
648  }
649 
650  default:
651  goto StartDos;
652  }
653 
654  /* Go to next drive and invalidate the last half-byte. */
655  BootOrder = (BootOrder >> 4) | 0xF000;
656  goto Retry;
657 
658 StartDos:
659  /* Clear everything, we are going to load DOS32 */
660  setAX(AX);
661  setBX(BX);
662  setCX(CX);
663  setDX(DX);
664  setES(ES);
665  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
666 
667  /* Load our DOS */
669 
670 Quit:
671  /*
672  * Jump to 0000:7C00 to boot the OS.
673  *
674  * Since we are called via the INT32 mechanism, we need to correctly set
675  * CS:IP, not by changing the current one (otherwise the interrupt could
676  * not be clean up and return properly), but by changing the CS:IP in the
677  * stack, so that when the interrupt returns, the modified CS:IP is popped
678  * off the stack and the CPU is correctly repositioned.
679  */
680  Stack[STACK_CS] = 0x0000;
681  Stack[STACK_IP] = 0x7C00;
682 
683  DPRINT("<-- BiosBootstrapLoader\n");
684 }
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
#define CMOS_ADDRESS_PORT
Definition: cmos.h:15
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
VOID WINAPI setCH(UCHAR)
Definition: registers.c:249
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
#define AX
Definition: i386-dis.c:415
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
Definition: bidi.c:78
#define EMULATOR_FLAG_CF
Definition: cpu.h:19
VOID WINAPI setES(USHORT)
Definition: registers.c:529
#define DX
Definition: i386-dis.c:416
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
void DPRINT(...)
Definition: polytest.cpp:61
#define STACK_FLAGS
Definition: int32.h:35
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
VOID DosBootsectorInitialize(VOID)
Definition: dem.c:1089
USHORT WINAPI getES(VOID)
Definition: registers.c:522
#define CMOS_DATA_PORT
Definition: halp.h:15
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
#define STACK_CS
Definition: int32.h:34
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
unsigned short USHORT
Definition: pedump.c:61
VOID WINAPI setDL(UCHAR)
Definition: registers.c:321
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
#define DPRINT1
Definition: precomp.h:8
VOID WINAPI BiosDiskService(LPWORD Stack)
Definition: dskbios32.c:164
#define STACK_IP
Definition: int32.h:33
VOID WINAPI setCL(UCHAR)
Definition: registers.c:263
VOID WINAPI setDH(UCHAR)
Definition: registers.c:307

Referenced by InitializeBiosInt32().

◆ BiosCharPrint()

static VOID BiosCharPrint ( CHAR  Character)
static

Definition at line 168 of file bios32.c.

169 {
170  /* Save AX and BX */
171  USHORT AX = getAX();
172  USHORT BX = getBX();
173 
174  /*
175  * Set the parameters:
176  * AL contains the character to print,
177  * BL contains the character attribute,
178  * BH contains the video page to use.
179  */
180  setAL(Character);
182  setBH(Bda->VideoPage);
183 
184  /* Call the BIOS INT 10h, AH=0Eh "Teletype Output" */
185  setAH(0x0E);
187 
188  /* Restore AX and BX */
189  setBX(BX);
190  setAX(AX);
191 }
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
BYTE VideoPage
Definition: bios.h:66
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
PBIOS_DATA_AREA Bda
Definition: bios.c:42
#define AX
Definition: i386-dis.c:415
#define DEFAULT_ATTRIBUTE
Definition: vidbios.h:21
#define BIOS_VIDEO_INTERRUPT
Definition: vidbios.h:15
CALLBACK16 BiosContext
Definition: bios32.c:45
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
unsigned short USHORT
Definition: pedump.c:61

Referenced by BiosRomBasic().

◆ BiosDiskService()

VOID WINAPI BiosDiskService ( LPWORD  Stack)

Definition at line 164 of file dskbios32.c.

165 {
166  BYTE Drive;
167  PDISK_IMAGE DiskImage;
168 
169  switch (getAH())
170  {
171  /* Disk -- Reset Disk System */
172  case 0x00:
173  {
174  Drive = getDL();
175 
176  if (Drive & 0x80)
177  {
178  AllDisksReset();
179 
180  /* Return success */
181  setAH(0x00);
182  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
183  break;
184  }
185 
186  Drive &= ~0x80;
187 
188  if (Drive >= ARRAYSIZE(FloppyDrive))
189  {
190  DPRINT1("BiosDiskService(0x00): Drive number 0x%02X invalid\n", Drive);
191 
192  /* Return error */
193  setAH(0x01);
194  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
195  break;
196  }
197 
198  // TODO: Reset drive
199 
200  /* Return success */
201  setAH(0x00);
202  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
203  break;
204  }
205 
206  /* Disk -- Get Status of Last Operation */
207  case 0x01:
208  {
209  BYTE LastOperationStatus = 0x00;
210 
211  Drive = getDL();
212  DiskImage = GetDisk(Drive);
213  if (!DiskImage || !IsDiskPresent(DiskImage))
214  {
215  DPRINT1("BiosDiskService(0x01): Disk number 0x%02X invalid\n", Drive);
216 
217  /* Return error */
218  setAH(0x01);
219  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
220  break;
221  }
222 
223  LastOperationStatus = DiskImage->LastOperationStatus;
224 
225  if (Drive & 0x80)
226  Bda->LastDiskOperation = LastOperationStatus;
227  else
228  Bda->LastDisketteOperation = LastOperationStatus;
229 
230  /* Return last error */
231  setAH(LastOperationStatus);
232  if (LastOperationStatus == 0x00)
233  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
234  else
235  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
236 
237  break;
238  }
239 
240  /* Disk -- Read Sectors into Memory */
241  case 0x02:
242  {
243  BYTE Status;
244  BYTE Head = getDH();
245  BYTE NumSectors = getAL();
246 
247  // CH: Low eight bits of cylinder number
248  // CL: High two bits of cylinder (bits 6-7, hard disk only)
249  WORD Cylinder = MAKEWORD(getCH(), (getCL() >> 6) & 0x02);
250 
251  // CL: Sector number 1-63 (bits 0-5)
252  BYTE Sector = (getCL() & 0x3F); // 1-based
253 
254  Drive = getDL();
255  DiskImage = GetDisk(Drive);
256  if (!DiskImage || !IsDiskPresent(DiskImage))
257  {
258  DPRINT1("BiosDiskService(0x02): Disk number 0x%02X invalid\n", Drive);
259 
260  /* Return error */
261  setAH(0x01);
262  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
263  break;
264  }
265 
266  /* Read the sectors */
267  Status = ReadDisk(DiskImage, Cylinder, Head, Sector, NumSectors);
268  if (Status == 0x00)
269  {
270  /* Return success */
271  setAH(0x00);
272  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
273  }
274  else
275  {
276  DPRINT1("BiosDiskService(0x02): Error when reading from disk number 0x%02X (0x%02X)\n", Drive, Status);
277 
278  /* Return error */
279  setAH(Status);
280  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
281  }
282 
283  break;
284  }
285 
286  /* Disk -- Write Disk Sectors */
287  case 0x03:
288  {
289  BYTE Status;
290  BYTE Head = getDH();
291  BYTE NumSectors = getAL();
292 
293  // CH: Low eight bits of cylinder number
294  // CL: High two bits of cylinder (bits 6-7, hard disk only)
295  WORD Cylinder = MAKEWORD(getCH(), (getCL() >> 6) & 0x02);
296 
297  // CL: Sector number 1-63 (bits 0-5)
298  BYTE Sector = (getCL() & 0x3F); // 1-based
299 
300  Drive = getDL();
301  DiskImage = GetDisk(Drive);
302  if (!DiskImage || !IsDiskPresent(DiskImage))
303  {
304  DPRINT1("BiosDiskService(0x03): Disk number 0x%02X invalid\n", Drive);
305 
306  /* Return error */
307  setAH(0x01);
308  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
309  break;
310  }
311 
312  /* Write the sectors */
313  Status = WriteDisk(DiskImage, Cylinder, Head, Sector, NumSectors);
314  if (Status == 0x00)
315  {
316  /* Return success */
317  setAH(0x00);
318  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
319  }
320  else
321  {
322  DPRINT1("BiosDiskService(0x03): Error when writing to disk number 0x%02X (0x%02X)\n", Drive, Status);
323 
324  /* Return error */
325  setAH(Status);
326  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
327  }
328 
329  break;
330  }
331 
332  /* Disk -- Verify Disk Sectors */
333  case 0x04:
334 
335  /* Floppy/Fixed Disk -- Format Track */
336  case 0x05:
337 
338  /* Fixed Disk -- Format Track and Set Bad Sector Flags */
339  case 0x06:
340 
341  /* Fixed Disk -- Format Drive starting at Given Track */
342  case 0x07:
343  goto Default;
344 
345  /* Disk -- Get Drive Parameters */
346  case 0x08:
347  {
348  WORD MaxCylinders;
349  BYTE MaxHeads;
350  BYTE PresentDrives = 0;
351  BYTE i;
352 
353  Drive = getDL();
354  DiskImage = GetDisk(Drive);
355  if (!DiskImage || !IsDiskPresent(DiskImage))
356  {
357  DPRINT1("BiosDiskService(0x08): Disk number 0x%02X invalid\n", Drive);
358 
359  /* Return error */
360  setAH(0x01);
361  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
362  break;
363  }
364 
365  // Minus 2 because it's the maximum cylinder number (not count),
366  // and the last cylinder is reserved (for compatibility with BIOSes
367  // which reserve it for testing purposes).
368  MaxCylinders = DiskImage->DiskInfo.Cylinders - 2;
369  // Minus 1 because it's the maximum head number (not count).
370  MaxHeads = DiskImage->DiskInfo.Heads - 1;
371 
372  // CL: Sector number 1-63 (bits 0-5)
373  // High two bits of cylinder (bits 6-7, hard disk only)
374  setCL((DiskImage->DiskInfo.Sectors & 0x3F) |
375  ((HIBYTE(MaxCylinders) & 0x02) << 6));
376  // CH: Low eight bits of cylinder number
377  setCH(LOBYTE(MaxCylinders));
378 
379  setDH(MaxHeads);
380 
381  if (Drive & 0x80)
382  {
383  /* Count the number of active HDDs */
384  for (i = 0; i < ARRAYSIZE(HardDrive); ++i)
385  {
386  if (IsDiskPresent(HardDrive[i]))
387  ++PresentDrives;
388  }
389 
390  /* Reset ES:DI to NULL */
391  // FIXME: NONONO!! Apps expect (for example, MS-DOS kernel)
392  // that this function does not modify ES:DI if it was called
393  // for a HDD.
394  // setES(0x0000);
395  // setDI(0x0000);
396  }
397  else
398  {
399  /* Count the number of active floppies */
400  for (i = 0; i < ARRAYSIZE(FloppyDrive); ++i)
401  {
403  ++PresentDrives;
404  }
405 
406  /* ES:DI points to the floppy parameter table */
407  setES(HIWORD(((PULONG)BaseAddress)[0x1E]));
408  setDI(LOWORD(((PULONG)BaseAddress)[0x1E]));
409  }
410  setDL(PresentDrives);
411 
412  setBL(DiskImage->DiskType); // DiskGeometryList[DiskImage->DiskType].biosval
413  setAL(0x00);
414 
415  /* Return success */
416  setAH(0x00);
417  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
418  break;
419  }
420 
421  /* Hard Disk -- Initialize Controller with Drive Parameters */
422  case 0x09:
423 
424  /* Hard Disk -- Read Long Sectors */
425  case 0x0A:
426 
427  /* Hard Disk -- Write Long Sectors */
428  case 0x0B:
429  goto Default;
430 
431  /* Hard Disk -- Seek to Cylinder */
432  case 0x0C:
433  {
434  BYTE Status;
435  BYTE Head = getDH();
436 
437  // CH: Low eight bits of cylinder number
438  // CL: High two bits of cylinder (bits 6-7, hard disk only)
439  WORD Cylinder = MAKEWORD(getCH(), (getCL() >> 6) & 0x02);
440 
441  // CL: Sector number 1-63 (bits 0-5)
442  BYTE Sector = (getCL() & 0x3F); // 1-based
443 
444  Drive = getDL();
445  if (!(Drive & 0x80))
446  {
447  DPRINT1("BiosDiskService(0x0C): Disk number 0x%02X is not a HDD\n", Drive);
448 
449  /* Return error */
450  setAH(0x01);
451  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
452  break;
453  }
454 
455  DiskImage = GetDisk(Drive);
456  if (!DiskImage || !IsDiskPresent(DiskImage))
457  {
458  DPRINT1("BiosDiskService(0x0C): Disk number 0x%02X invalid\n", Drive);
459 
460  /* Return error */
461  setAH(0x01);
462  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
463  break;
464  }
465 
466  /* Set position */
467  Status = SeekDisk(DiskImage, Cylinder, Head, Sector);
468  if (Status == 0x00)
469  {
470  /* Return success */
471  setAH(0x00);
472  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
473  }
474  else
475  {
476  DPRINT1("BiosDiskService(0x0C): Error when seeking in disk number 0x%02X (0x%02X)\n", Drive, Status);
477 
478  /* Return error */
479  setAH(Status);
480  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
481  }
482 
483  break;
484  }
485 
486  /* Hard Disk -- Reset Hard Disks */
487  case 0x0D:
488  {
489  // FIXME: Should do what 0x11 does.
491  }
492 
493  /* Hard Disk -- Read Sector Buffer (XT only) */
494  case 0x0E:
495 
496  /* Hard Disk -- Write Sector Buffer (XT only) */
497  case 0x0F:
498  goto Default;
499 
500  /* Hard Disk -- Check if Drive is ready */
501  case 0x10:
502  {
503  Drive = getDL();
504  if (!(Drive & 0x80))
505  {
506  DPRINT1("BiosDiskService(0x10): Disk number 0x%02X is not a HDD\n", Drive);
507 
508  /* Return error */
509  setAH(0x01);
510  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
511  break;
512  }
513 
514  DiskImage = GetDisk(Drive);
515  if (!DiskImage || !IsDiskPresent(DiskImage))
516  {
517  DPRINT1("BiosDiskService(0x10): Disk number 0x%02X invalid\n", Drive);
518 
519  /* Return error */
520  setAH(0x01);
521  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
522  break;
523  }
524 
525  /* Return success */
526  setAH(0x00);
527  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
528  break;
529  }
530 
531  /* Hard Disk -- Recalibrate Drive */
532  case 0x11:
533  {
534  BYTE Status;
535 
536  Drive = getDL();
537  if (!(Drive & 0x80))
538  {
539  DPRINT1("BiosDiskService(0x11): Disk number 0x%02X is not a HDD\n", Drive);
540 
541  /* Return error */
542  setAH(0x01);
543  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
544  break;
545  }
546 
547  DiskImage = GetDisk(Drive);
548  if (!DiskImage || !IsDiskPresent(DiskImage))
549  {
550  DPRINT1("BiosDiskService(0x11): Disk number 0x%02X invalid\n", Drive);
551 
552  /* Return error */
553  setAH(0x01);
554  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
555  break;
556  }
557 
558  /* Set position to zero */
559  Status = SeekDisk(DiskImage, /*Cylinder*/ 0, /*Head*/ 0, /*Sector*/ 1);
560  if (Status == 0x00)
561  {
562  /* Return success */
563  setAH(0x00);
564  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
565  }
566  else
567  {
568  DPRINT1("BiosDiskService(0x11): Error when recalibrating disk number 0x%02X (0x%02X)\n", Drive, Status);
569 
570  /* Return error */
571  setAH(Status);
572  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
573  }
574 
575  break;
576  }
577 
578  /* Hard Disk -- Controller RAM Diagnostic */
579  case 0x12:
580 
581  /* Hard Disk -- Drive Diagnostic */
582  case 0x13:
583 
584  /* Hard Disk -- Controller Internal Diagnostic */
585  case 0x14:
586  goto Default;
587 
588  /* Disk -- Get Disk Type */
589  case 0x15:
590  {
591  Drive = getDL();
592  DiskImage = GetDisk(Drive);
593  if (!DiskImage || !IsDiskPresent(DiskImage))
594  {
595  DPRINT1("BiosDiskService(0x15): Disk number 0x%02X invalid\n", Drive);
596 
597  /* Return error */
598  setAH(0x01);
599  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
600  break;
601  }
602 
603  if (Drive & 0x80)
604  {
605  ULONG NumSectors;
606 
607  /* Hard disk */
608  setAH(0x03);
609 
610  /* Number of 512-byte sectors in CX:DX */
611  NumSectors = (ULONG)((ULONG)DiskImage->DiskInfo.Cylinders * DiskImage->DiskInfo.Heads)
612  * DiskImage->DiskInfo.Sectors;
613  setCX(HIWORD(NumSectors));
614  setDX(LOWORD(NumSectors));
615  }
616  else
617  {
618  /* Floppy */
619  setAH(0x01);
620  }
621 
622  /* Return success */
623  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
624  break;
625  }
626 
627  /* Floppy Disk -- Detect Disk Change */
628  case 0x16:
629 
630  /* Floppy Disk -- Set Disk Type for Format */
631  case 0x17:
632 
633  /* Disk -- Set Media Type for Format */
634  case 0x18:
635  goto Default;
636 
637  default: Default:
638  {
639  DPRINT1("BIOS Function INT 13h, AH = 0x%02X, AL = 0x%02X, BH = 0x%02X NOT IMPLEMENTED\n",
640  getAH(), getAL(), getBH());
641  }
642  }
643 }
BYTE WriteDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector, IN BYTE NumSectors)
Definition: disk.c:413
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
UCHAR WINAPI getCL(VOID)
Definition: registers.c:256
#define LOBYTE(W)
Definition: jmemdos.c:487
WORD Cylinders
Definition: disk.h:21
#define MAKEWORD(a, b)
Definition: typedefs.h:247
VOID WINAPI setCH(UCHAR)
Definition: registers.c:249
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
static PDISK_IMAGE HardDrive[4]
Definition: dskbios32.c:37
#define HIBYTE(W)
Definition: jmemdos.c:486
BOOLEAN IsDiskPresent(IN PDISK_IMAGE DiskImage)
Definition: disk.c:321
BYTE LastOperationStatus
Definition: disk.h:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
PBIOS_DATA_AREA Bda
Definition: bios.c:42
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
UCHAR WINAPI getDH(VOID)
Definition: registers.c:300
BYTE Sectors
Definition: disk.h:23
UCHAR WINAPI getDL(VOID)
Definition: registers.c:314
#define EMULATOR_FLAG_CF
Definition: cpu.h:19
BYTE ReadDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector, IN BYTE NumSectors)
Definition: disk.c:359
VOID WINAPI setES(USHORT)
Definition: registers.c:529
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PWCHAR Drive
Definition: chkdsk.c:73
BYTE LastDiskOperation
Definition: bios.h:81
static VOID AllDisksReset(VOID)
Definition: dskbios32.c:157
#define STACK_FLAGS
Definition: int32.h:35
static PDISK_IMAGE FloppyDrive[2]
Definition: dskbios32.c:36
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
static PDISK_IMAGE GetDisk(IN BYTE DiskNumber)
Definition: dskbios32.c:130
BYTE LastDisketteOperation
Definition: bios.h:57
unsigned short WORD
Definition: ntddk_ex.h:93
UCHAR WINAPI getBH(VOID)
Definition: registers.c:184
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
unsigned char BYTE
Definition: mem.h:68
BYTE DiskType
Definition: disk.h:31
Status
Definition: gdiplustypes.h:24
VOID WINAPI setDI(USHORT)
Definition: registers.c:441
VOID WINAPI setDL(UCHAR)
Definition: registers.c:321
unsigned int * PULONG
Definition: retypes.h:1
BYTE SeekDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector)
Definition: disk.c:328
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
#define DPRINT1
Definition: precomp.h:8
UCHAR WINAPI getCH(VOID)
Definition: registers.c:242
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
BYTE Heads
Definition: disk.h:22
VOID WINAPI setCL(UCHAR)
Definition: registers.c:263
#define LOWORD(l)
Definition: pedump.c:82
DISK_INFO DiskInfo
Definition: disk.h:30
VOID WINAPI setDH(UCHAR)
Definition: registers.c:307

Referenced by BiosBootstrapLoader(), and DiskBios32Post().

◆ BiosEquipmentService()

VOID WINAPI BiosEquipmentService ( LPWORD  Stack)

Definition at line 200 of file bios32.c.

201 {
202  /* Return the equipment list */
204 }
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
PBIOS_DATA_AREA Bda
Definition: bios.c:42
WORD EquipmentList
Definition: bios.h:45

Referenced by BiosInitialize(), and InitializeBiosInt32().

◆ BiosException()

static VOID WINAPI BiosException ( LPWORD  Stack)
static

Definition at line 193 of file bios32.c.

194 {
195  /* Get the exception number and call the emulator API */
196  BYTE ExceptionNumber = LOBYTE(Stack[STACK_INT_NUM]);
197  EmulatorException(ExceptionNumber, Stack);
198 }
#define STACK_INT_NUM
Definition: int32.h:30
#define LOBYTE(W)
Definition: jmemdos.c:487
VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
Definition: emulator.c:85
unsigned char BYTE
Definition: mem.h:68

Referenced by InitializeBiosInt32().

◆ BiosGetMemorySize()

VOID WINAPI BiosGetMemorySize ( LPWORD  Stack)

Definition at line 206 of file bios32.c.

207 {
208  /* Return the conventional memory size in kB, typically 640 kB */
209  setAX(Bda->MemorySize);
210 }
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
PBIOS_DATA_AREA Bda
Definition: bios.c:42
WORD MemorySize
Definition: bios.h:47

Referenced by BiosInitialize(), and InitializeBiosInt32().

◆ BiosHandleMasterPicIRQ()

static VOID WINAPI BiosHandleMasterPicIRQ ( LPWORD  Stack)
static

Definition at line 830 of file bios32.c.

831 {
832  BYTE IrqNumber;
833 
834  IOWriteB(PIC_MASTER_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
835  IrqNumber = IOReadB(PIC_MASTER_CMD);
836 
837  DPRINT("Master - IrqNumber = 0x%02X\n", IrqNumber);
838 
840 }
#define STACK_INT_NUM
Definition: int32.h:30
#define LOBYTE(W)
Definition: jmemdos.c:487
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
void DPRINT(...)
Definition: polytest.cpp:61
#define PIC_MASTER_CMD
Definition: pic.h:15
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
#define PIC_OCW3_READ_ISR
Definition: pic.h:31
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:812
unsigned char BYTE
Definition: mem.h:68

Referenced by InitializeBiosInt32().

◆ BiosHandleSlavePicIRQ()

static VOID WINAPI BiosHandleSlavePicIRQ ( LPWORD  Stack)
static

Definition at line 842 of file bios32.c.

843 {
844  BYTE IrqNumber;
845 
846  IOWriteB(PIC_SLAVE_CMD, PIC_OCW3_READ_ISR /* == 0x0B */);
847  IrqNumber = IOReadB(PIC_SLAVE_CMD);
848 
849  DPRINT("Slave - IrqNumber = 0x%02X\n", IrqNumber);
850 
852 }
#define STACK_INT_NUM
Definition: int32.h:30
#define LOBYTE(W)
Definition: jmemdos.c:487
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
void DPRINT(...)
Definition: polytest.cpp:61
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
#define PIC_OCW3_READ_ISR
Definition: pic.h:31
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:812
unsigned char BYTE
Definition: mem.h:68
#define PIC_SLAVE_CMD
Definition: pic.h:17

Referenced by InitializeBiosInt32().

◆ BiosHwSetup()

static VOID BiosHwSetup ( VOID  )
static

Definition at line 893 of file bios32.c.

894 {
895  /* Initialize the master and the slave PICs (cascade mode) */
898 
899  /*
900  * Set the interrupt vector offsets for each PIC
901  * (base IRQs: 0x08-0x0F for IRQ 0-7, 0x70-0x77 for IRQ 8-15)
902  */
905 
906  /* Tell the master PIC that there is a slave PIC at IRQ 2 */
907  IOWriteB(PIC_MASTER_DATA, 1 << 2);
908  /* Tell the slave PIC its cascade identity */
910 
911  /* Make sure both PICs are in 8086 mode */
914 
915  /* Clear the masks for both PICs */
916  // IOWriteB(PIC_MASTER_DATA, 0x00);
917  // IOWriteB(PIC_SLAVE_DATA , 0x00);
918  /* Disable all IRQs */
919  IOWriteB(PIC_MASTER_DATA, 0xFF);
920  IOWriteB(PIC_SLAVE_DATA , 0xFF);
921 
922 
923  /* Initialize PIT Counter 0 - Mode 2, 16bit binary count */
924  // NOTE: Some BIOSes set it to Mode 3 instead.
925  IOWriteB(PIT_COMMAND_PORT, 0x34);
926  // 18.2Hz refresh rate
927  IOWriteB(PIT_DATA_PORT(0), 0x00);
928  IOWriteB(PIT_DATA_PORT(0), 0x00);
929 
930  /* Initialize PIT Counter 1 - Mode 2, 8bit binary count */
931  IOWriteB(PIT_COMMAND_PORT, 0x54);
932  // DRAM refresh every 15ms: http://www.cs.dartmouth.edu/~spl/Academic/Organization/docs/PC%20Timer%208253.html
933  IOWriteB(PIT_DATA_PORT(1), 18);
934 
935  /* Initialize PIT Counter 2 - Mode 3, 16bit binary count */
936  IOWriteB(PIT_COMMAND_PORT, 0xB6);
937  // Count for 440Hz
938  IOWriteB(PIT_DATA_PORT(2), 0x97);
939  IOWriteB(PIT_DATA_PORT(2), 0x0A);
940 
941 
942  /* Initialize PS/2 keyboard port */
943  // Enable the port
944  IOWriteB(PS2_CONTROL_PORT, 0xAE);
945  // Port interrupts and clock enabled,
946  // enable keyboard scancode translation.
947  // POST passed, force keyboard unlocking.
948  IOWriteB(PS2_CONTROL_PORT, 0x60);
949  IOWriteB(PS2_DATA_PORT , 0x6D);
950  // Enable data reporting
951  IOWriteB(PS2_DATA_PORT , 0xF4);
952 
954 }
#define PIC_MASTER_DATA
Definition: pic.h:16
#define PS2_DATA_PORT
Definition: ps2.h:16
static VOID WINAPI BiosTimerIrq(LPWORD Stack)
Definition: bios32.c:855
#define PIC_SLAVE_DATA
Definition: pic.h:18
#define PIT_COMMAND_PORT
Definition: pit.h:19
#define PIC_MASTER_CMD
Definition: pic.h:15
#define PIC_ICW1_ICW4
Definition: pic.h:21
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
VOID EnableHwIRQ(UCHAR hwirq, EMULATOR_INT32_PROC func)
Definition: bios32.c:798
#define BIOS_PIC_SLAVE_INT
Definition: bios32p.h:21
#define PIC_ICW4_8086
Definition: pic.h:23
#define PS2_CONTROL_PORT
Definition: ps2.h:17
#define PIC_ICW1
Definition: pic.h:20
#define BIOS_PIC_MASTER_INT
Definition: bios32p.h:20
#define PIC_SLAVE_CMD
Definition: pic.h:17
#define PIT_DATA_PORT(x)
Definition: pit.h:18

Referenced by Bios32Post().

◆ BiosMiscService()

static VOID WINAPI BiosMiscService ( LPWORD  Stack)
static

Definition at line 212 of file bios32.c.

213 {
214  switch (getAH())
215  {
216  /* OS Hooks for Multitasking */
217  case 0x80: // Device Open
218  case 0x81: // Device Close
219  case 0x82: // Program Termination
220  case 0x90: // Device Busy
221  case 0x91: // Device POST
222  {
223  /* Return success by default */
224  setAH(0x00);
225  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
226  break;
227  }
228 
229  /* Wait on External Event */
230  case 0x41:
231  {
232  BYTE Value;
233  BOOLEAN Return;
234  static DWORD StartingCount;
235 
236  /* Check if this is the first time this BOP occurred */
237  if (!getCF())
238  {
239  /* Set the starting count */
240  StartingCount = Bda->TickCounter;
241  }
242 
243  if (getBL() != 0 && (Bda->TickCounter - StartingCount) >= getBL())
244  {
245  /* Timeout expired */
246  setCF(0);
247  break;
248  }
249 
250  if (getAL() & (1 << 4))
251  {
252  /* Read from the I/O port */
253  Value = IOReadB(getDX());
254  }
255  else
256  {
257  /* Read from the memory */
259  }
260 
261  switch (getAL() & 7)
262  {
263  /* Any external event */
264  case 0:
265  {
266  /* Return if this is not the first time the BOP occurred */
267  Return = getCF();
268  break;
269  }
270 
271  /* Compare and return if equal */
272  case 1:
273  {
274  Return = Value == getBH();
275  break;
276  }
277 
278  /* Compare and return if not equal */
279  case 2:
280  {
281  Return = Value != getBH();
282  break;
283  }
284 
285  /* Test and return if not zero */
286  case 3:
287  {
288  Return = (Value & getBH()) != 0;
289  break;
290  }
291 
292  /* Test and return if zero */
293  case 4:
294  {
295  Return = (Value & getBH()) == 0;
296  break;
297  }
298 
299  default:
300  {
301  DPRINT1("INT 15h, AH = 41h - Unknown condition type: %u\n", getAL() & 7);
302  Return = TRUE;
303  break;
304  }
305  }
306 
307  /* Repeat the BOP if we shouldn't return */
308  setCF(!Return);
309  break;
310  }
311 
312  /* Keyboard intercept */
313  case 0x4F:
314  {
315  /* CF should be set but let's just set it again just in case */
316  /* Do not modify AL (the hardware scan code), but set CF to continue processing */
317  // setCF(1);
318  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
319  break;
320  }
321 
322  /* Wait */
323  case 0x86:
324  {
325  /*
326  * Interval in microseconds in CX:DX
327  * See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
328  * for more information.
329  */
330 
331  static ULONG CompletionTime = 0;
332 
333  /* Check if we're already looping */
334  if (getCF())
335  {
336  if (GetTickCount() >= CompletionTime)
337  {
338  /* Stop looping */
339  setCF(0);
340 
341  /* Clear the CF on the stack too */
342  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
343  }
344  }
345  else
346  {
347  /* Set the CF on the stack */
348  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
349 
350  /* Set the completion time and start looping */
351  CompletionTime = GetTickCount() + (MAKELONG(getDX(), getCX()) / 1000);
352  setCF(1);
353  }
354 
355  break;
356  }
357 
358  /* Copy Extended Memory */
359  case 0x87:
360  {
361  DWORD Count = (DWORD)getCX() * 2;
362  PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI());
363  DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24);
364  DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16);
365  DWORD DestBase = Gdt[3].Base + (Gdt[3].BaseMid << 16) + (Gdt[3].BaseHigh << 24);
366  DWORD DestLimit = Gdt[3].Limit + (Gdt[3].LimitHigh << 16);
367 
368  /* Check for flags */
369  if (Gdt[2].Granularity) SourceLimit = (SourceLimit << 12) | 0xFFF;
370  if (Gdt[3].Granularity) DestLimit = (DestLimit << 12) | 0xFFF;
371 
372  if ((Count > SourceLimit) || (Count > DestLimit))
373  {
374  setAX(0x80);
375  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
376  break;
377  }
378 
379  /* Copy */
380  RtlMoveMemory((PVOID)((ULONG_PTR)BaseAddress + DestBase),
381  (PVOID)((ULONG_PTR)BaseAddress + SourceBase),
382  Count);
383 
385  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
386  break;
387  }
388 
389  /* Get Extended Memory Size */
390  case 0x88:
391  {
392  UCHAR Low, High;
393 
394  /*
395  * Return the (usable) extended memory (after 1 MB)
396  * size in kB from CMOS.
397  */
402  setAX(MAKEWORD(Low, High));
403 
404  /* Clear CF */
405  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
406  break;
407  }
408 
409  /* Switch to Protected Mode */
410  case 0x89:
411  {
412  DPRINT1("BIOS INT 15h, AH=89h \"Switch to Protected Mode\" is UNIMPLEMENTED");
413 
414  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
415  goto Default;
416  }
417 
418  /* Get Configuration */
419  case 0xC0:
420  {
421  /* Return the BIOS ROM Configuration Table address in ES:BX */
422  // The BCT is found at F000:E6F5 for 100% compatible BIOSes.
424  setBX(0xE6F5);
425 
426  /* Call successful; clear CF */
427  setAH(0x00);
428  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
429  break;
430  }
431 
432  /* Return Extended-Bios Data-Area Segment Address (PS) */
433  case 0xC1:
434  {
435  /* We do not support EBDA yet */
437  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
438  goto Default;
439  }
440 
441  /* Pointing Device BIOS Interface (PS) */
442  case 0xC2:
443  {
444  // FIXME: Reenable this call when we understand why
445  // our included mouse driver doesn't correctly reeanble
446  // mouse reporting!
447  // BiosMousePs2Interface(Stack);
448  // break;
449  goto Default;
450  }
451 
452  /* Get CPU Type and Mask Revision */
453  case 0xC9:
454  {
455  /*
456  * We can see this function as a CPUID replacement.
457  * See Ralf Brown: http://www.ctyme.com/intr/rb-1613.htm
458  * for more information.
459  */
460 
461  /*
462  * Fast486 is a 486DX with FPU included,
463  * but old enough to not support CPUID.
464  */
465  setCX(0x0400);
466 
467  /* Call successful; clear CF */
468  setAH(0x00);
469  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
470  break;
471  }
472 
473  /* Get System Memory Map */
474  case 0xE8:
475  {
476  if (getAL() == 0x01)
477  {
478  /* The amount of memory between 1M and 16M, in kilobytes */
479  ULONG Above1M = (min(MAX_ADDRESS, 0x01000000) - 0x00100000) >> 10;
480 
481  /* The amount of memory above 16M, in 64K blocks */
482  ULONG Above16M = (MAX_ADDRESS > 0x01000000) ? ((MAX_ADDRESS - 0x01000000) >> 16) : 0;
483 
484  setAX(Above1M);
485  setBX(Above16M);
486  setCX(Above1M);
487  setDX(Above16M);
488 
489  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
490  }
491  else if (getAL() == 0x20 && getEDX() == 'SMAP')
492  {
493  ULONG Offset = getEBX();
494  ULONG Length;
495  ULONG BytesWritten = 0;
496  BOOLEAN Hooked;
498 
499  /* Assume the buffer won't be large enough */
500  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
501 
502  while (BytesWritten < getECX() && (ULONG_PTR)Map < (MAX_ADDRESS - sizeof(BIOS_MEMORY_MAP)))
503  {
504  /* Let's ask our memory controller */
505  if (!MemQueryMemoryZone(Offset, &Length, &Hooked))
506  {
507  /* No more memory blocks */
508  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
509  break;
510  }
511 
512  Map->BaseAddress = (ULONGLONG)Offset;
513  Map->Length = (ULONGLONG)Length;
515 
516  /* Go to the next record */
517  Map++;
518  Offset += Length;
519  BytesWritten += sizeof(BIOS_MEMORY_MAP);
520  }
521 
522  setEAX('SMAP');
523  setEBX(Offset);
525  }
526  else
527  {
528  DPRINT1("BIOS Function INT 15h, AH = 0xE8 - unexpected AL = %02X, EDX = %08X\n",
529  getAL(), getEDX());
530  }
531 
532  break;
533  }
534 
535  default: Default:
536  {
537  DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n",
538  getAH());
539 
540  /*
541  * The original signification of the error code 0x86 is that
542  * no PC Cassette is present. The CF is also set in this case.
543  * To keep backward compatibility, newer BIOSes use this value
544  * to indicate an unimplemented call in INT 15h.
545  */
546  setAH(0x86);
547  Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
548  }
549  }
550 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2327
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
BOOLEAN MemQueryMemoryZone(ULONG StartAddress, PULONG Length, PBOOLEAN Hooked)
Definition: memory.c:378
#define TRUE
Definition: types.h:120
#define CMOS_ADDRESS_PORT
Definition: cmos.h:15
#define ERROR_SUCCESS
Definition: deptool.c:10
VOID WINAPI setEAX(ULONG)
Definition: registers.c:107
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
VOID WINAPI setECX(ULONG)
Definition: registers.c:221
#define MAKEWORD(a, b)
Definition: typedefs.h:247
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
ULONG WINAPI getEDX(VOID)
Definition: registers.c:272
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
PBIOS_DATA_AREA Bda
Definition: bios.c:42
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
Definition: strmini.h:380
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
ULONG WINAPI getEBX(VOID)
Definition: registers.c:156
#define DWORD
Definition: nt_native.h:44
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define EMULATOR_FLAG_CF
Definition: cpu.h:19
#define MAX_ADDRESS
VOID WINAPI setES(USHORT)
Definition: registers.c:529
unsigned char * LPBYTE
Definition: typedefs.h:52
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
LONGLONG BaseAddress
Definition: osloader.h:33
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
VOID WINAPI setEBX(ULONG)
Definition: registers.c:163
#define MAKELONG(a, b)
Definition: typedefs.h:248
unsigned char BOOLEAN
#define STACK_FLAGS
Definition: int32.h:35
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
USHORT WINAPI getES(VOID)
Definition: registers.c:522
uint64_t ULONGLONG
Definition: typedefs.h:65
#define CMOS_DATA_PORT
Definition: halp.h:15
unsigned long DWORD
Definition: ntddk_ex.h:95
UCHAR WINAPI getBH(VOID)
Definition: registers.c:184
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Definition: strmini.h:378
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
unsigned char UCHAR
Definition: xmlstorage.h:181
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
unsigned char BYTE
Definition: mem.h:68
DWORD TickCounter
Definition: bios.h:77
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
#define CMOS_DISABLE_NMI
Definition: cmos.h:17
UCHAR WINAPI getBL(VOID)
Definition: registers.c:198
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
#define min(a, b)
Definition: monoChain.cc:55
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
#define ULONG_PTR
Definition: config.h:101
ULONG WINAPI getECX(VOID)
Definition: registers.c:214
LONGLONG Length
Definition: osloader.h:34
struct BIOS_MEMORY_MAP * PBIOS_MEMORY_MAP
ULONG WINAPI getCF(VOID)
Definition: registers.c:566
#define BIOS_SEGMENT
Definition: bios.h:29

Referenced by InitializeBiosInt32().

◆ BiosRomBasic()

static VOID WINAPI BiosRomBasic ( LPWORD  Stack)
static

Definition at line 552 of file bios32.c.

553 {
554  PrintMessageAnsi(BiosCharPrint, "FATAL: INT18: BOOT FAILURE.");
555 
556  /* ROM Basic is unsupported, display a message to the user */
557  DisplayMessage(L"NTVDM doesn't support ROM Basic. The VDM is closing.");
558 
559  /* Stop the VDM */
561 }
static VOID BiosCharPrint(CHAR Character)
Definition: bios32.c:168
VOID PrintMessageAnsi(IN CHAR_PRINT CharPrint, IN LPCSTR Format,...)
Definition: ntvdm.c:409
static const WCHAR L[]
Definition: oid.c:1250
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239

Referenced by InitializeBiosInt32().

◆ BiosSystemTimerInterrupt()

static VOID WINAPI BiosSystemTimerInterrupt ( LPWORD  Stack)
static

Definition at line 782 of file bios32.c.

783 {
784  /* Increase the system tick count */
785  Bda->TickCounter++;
786 }
PBIOS_DATA_AREA Bda
Definition: bios.c:42
DWORD TickCounter
Definition: bios.h:77

Referenced by InitializeBiosInt32().

◆ BiosTimerIrq()

static VOID WINAPI BiosTimerIrq ( LPWORD  Stack)
static

Definition at line 855 of file bios32.c.

856 {
857  /*
858  * Perform the system timer interrupt.
859  *
860  * Do not call directly BiosSystemTimerInterrupt(Stack);
861  * because some programs may hook only BIOS_SYS_TIMER_INTERRUPT
862  * for their purpose...
863  */
864 
865  WORD AX = getAX();
866  WORD CX = getCX();
867  WORD DX = getDX();
868  WORD BX = getBX();
869  WORD BP = getBP();
870  WORD SI = getSI();
871  WORD DI = getDI();
872  WORD DS = getDS();
873  WORD ES = getES();
874 
876 
877  setAX(AX);
878  setCX(CX);
879  setDX(DX);
880  setBX(BX);
881  setBP(BP);
882  setSI(SI);
883  setDI(DI);
884  setDS(DS);
885  setES(ES);
886  setCF(0);
887 
888  // BiosSystemTimerInterrupt(Stack);
890 }
#define STACK_INT_NUM
Definition: int32.h:30
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
#define BIOS_SYS_TIMER_INTERRUPT
Definition: bios32p.h:29
#define LOBYTE(W)
Definition: jmemdos.c:487
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setDS(USHORT)
Definition: registers.c:515
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
#define AX
Definition: i386-dis.c:415
Definition: bidi.c:78
Definition: parse.h:75
VOID WINAPI setES(USHORT)
Definition: registers.c:529
#define DX
Definition: i386-dis.c:416
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
VOID WINAPI setSI(USHORT)
Definition: registers.c:411
USHORT WINAPI getES(VOID)
Definition: registers.c:522
VOID PicIRQComplete(BYTE IntNum)
Definition: bios32.c:812
CALLBACK16 BiosContext
Definition: bios32.c:45
unsigned short WORD
Definition: ntddk_ex.h:93
VOID WINAPI setBP(USHORT)
Definition: registers.c:381
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setDI(USHORT)
Definition: registers.c:441
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
Definition: i386_sup.c:15
USHORT WINAPI getBP(VOID)
Definition: registers.c:374

Referenced by BiosHwSetup().

◆ BiosTimeService()

static VOID WINAPI BiosTimeService ( LPWORD  Stack)
static

Definition at line 686 of file bios32.c.

687 {
688  switch (getAH())
689  {
690  /* Get System Time */
691  case 0x00:
692  {
693  /* Set AL to 1 if midnight had passed, 0 otherwise */
694  setAL(Bda->MidnightPassed ? 0x01 : 0x00);
695 
696  /* Return the tick count in CX:DX */
699 
700  /* Reset the midnight flag */
702 
703  break;
704  }
705 
706  /* Set System Time */
707  case 0x01:
708  {
709  /* Set the tick count to CX:DX */
711 
712  /* Reset the midnight flag */
714 
715  break;
716  }
717 
718  /* Get Real-Time Clock Time */
719  case 0x02:
720  {
721  UCHAR StatusB;
722 
725 
728 
731 
732  /* Daylight Savings Time */
734  StatusB = IOReadB(CMOS_DATA_PORT);
735  setDL(StatusB & 0x01);
736 
737  /* Clear CF */
738  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
739  break;
740  }
741 
742  // /* Set Real-Time Clock Time */
743  // case 0x03:
744  // {
745  // break;
746  // }
747 
748  /* Get Real-Time Clock Date */
749  case 0x04:
750  {
753 
756 
759 
762 
763  /* Clear CF */
764  Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
765  break;
766  }
767 
768  // /* Set Real-Time Clock Date */
769  // case 0x05:
770  // {
771  // break;
772  // }
773 
774  default:
775  {
776  DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n",
777  getAH());
778  }
779  }
780 }
#define CMOS_ADDRESS_PORT
Definition: cmos.h:15
USHORT WINAPI getCX(VOID)
Definition: registers.c:228
VOID WINAPI setCH(UCHAR)
Definition: registers.c:249
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
PBIOS_DATA_AREA Bda
Definition: bios.c:42
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
#define EMULATOR_FLAG_CF
Definition: cpu.h:19
BYTE MidnightPassed
Definition: bios.h:78
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define STACK_FLAGS
Definition: int32.h:35
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
#define CMOS_DATA_PORT
Definition: halp.h:15
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
unsigned char UCHAR
Definition: xmlstorage.h:181
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
DWORD TickCounter
Definition: bios.h:77
VOID WINAPI setDL(UCHAR)
Definition: registers.c:321
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
#define DPRINT1
Definition: precomp.h:8
#define HIWORD(l)
Definition: typedefs.h:246
VOID WINAPI setCL(UCHAR)
Definition: registers.c:263
#define LOWORD(l)
Definition: pedump.c:82
VOID WINAPI setDH(UCHAR)
Definition: registers.c:307

Referenced by InitializeBiosInt32().

◆ C_ASSERT() [1/2]

C_ASSERT ( sizeof(BiosCopyright) -1<=  0x5B)

◆ C_ASSERT() [2/2]

C_ASSERT ( sizeof(BiosDate) -  1 = =0x08)

◆ DosBootsectorInitialize()

VOID DosBootsectorInitialize ( VOID  )

Definition at line 1089 of file dem.c.

1090 {
1091  /* We write the bootsector at 0000:7C00 */
1092  ULONG_PTR StartAddress = (ULONG_PTR)SEG_OFF_TO_PTR(0x0000, 0x7C00);
1093  ULONG_PTR Address = StartAddress;
1094  CHAR DosKernelFileName[] = ""; // No DOS BIOS file name, therefore we will load DOS32
1095 
1096  DPRINT("DosBootsectorInitialize\n");
1097 
1098  /* Write the "bootsector" */
1100  Address += sizeof(Bootsector1);
1101  RtlCopyMemory((PVOID)Address, DosKernelFileName, sizeof(DosKernelFileName));
1102  Address += sizeof(DosKernelFileName);
1104  Address += sizeof(Bootsector2);
1105 
1106  /* Initialize the callback context */
1107  InitializeContext(&DosContext, 0x0000,
1108  (ULONG_PTR)MEM_ALIGN_UP(0x7C00 + Address - StartAddress, sizeof(WORD)));
1109 
1110  /* Register the DOS Loading BOP */
1112 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
VOID InitializeContext(IN PCALLBACK16 Context, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:60
char CHAR
Definition: xmlstorage.h:175
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
static VOID WINAPI DosInitialize(LPWORD Stack)
Definition: dem.c:1129
uint32_t ULONG_PTR
Definition: typedefs.h:63
CALLBACK16 DosContext
Definition: dos.c:40
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
#define BOP_LOAD_DOS
Definition: dem.h:23
static BYTE Bootsector2[]
Definition: dem.c:1082
unsigned short WORD
Definition: ntddk_ex.h:93
#define MEM_ALIGN_UP(ptr, align)
Definition: emulator.h:20
#define ULONG_PTR
Definition: config.h:101
static BYTE Bootsector1[]
Definition: dem.c:1076

Referenced by BiosBootstrapLoader().

◆ EnableHwIRQ()

VOID EnableHwIRQ ( UCHAR  hwirq,
EMULATOR_INT32_PROC  func 
)

Definition at line 798 of file bios32.c.

799 {
800  UCHAR vector;
801 
802  PicSetIRQMask(1 << hwirq, 0);
803  if (hwirq < 8)
804  vector = BIOS_PIC_MASTER_INT + hwirq;
805  else
806  vector = BIOS_PIC_SLAVE_INT + hwirq - 8;
807 
809 }
static VOID PicSetIRQMask(USHORT off, USHORT on)
Definition: bios32.c:790
GLenum func
Definition: glext.h:6028
#define RegisterBiosInt32(IntNumber, IntHandler)
Definition: bios32p.h:34
#define BIOS_PIC_SLAVE_INT
Definition: bios32p.h:21
unsigned char UCHAR
Definition: xmlstorage.h:181
#define BIOS_PIC_MASTER_INT
Definition: bios32p.h:20

Referenced by BiosHwSetup(), KbdBios32Post(), and MouseBios32Post().

◆ InitializeBiosData()

static VOID InitializeBiosData ( VOID  )
static

Definition at line 1032 of file bios32.c.

1033 {
1034  UCHAR Low, High;
1035 
1036  /* Initialize the BDA contents */
1037  RtlZeroMemory(Bda, sizeof(*Bda));
1038 
1039  /*
1040  * Retrieve the basic equipment list from the CMOS
1041  */
1044  // TODO: Update it if required.
1045  Bda->EquipmentList &= 0x00FF; // High byte cleared for now...
1046 
1047  /*
1048  * Retrieve the conventional memory size
1049  * in kB from the CMOS, typically 640 kB.
1050  */
1056 }
#define CMOS_ADDRESS_PORT
Definition: cmos.h:15
#define MAKEWORD(a, b)
Definition: typedefs.h:247
PBIOS_DATA_AREA Bda
Definition: bios.c:42
Definition: strmini.h:380
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
WORD MemorySize
Definition: bios.h:47
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
#define CMOS_DATA_PORT
Definition: halp.h:15
Definition: strmini.h:378
unsigned char UCHAR
Definition: xmlstorage.h:181
#define CMOS_DISABLE_NMI
Definition: cmos.h:17
WORD EquipmentList
Definition: bios.h:45
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

Referenced by Bios32Post().

◆ InitializeBiosInt32()

static VOID InitializeBiosInt32 ( VOID  )
static

Definition at line 956 of file bios32.c.

957 {
958  USHORT i;
959 
960  /* Initialize the callback context */
962 
963  /* Register the default BIOS interrupt vectors */
964 
965  /*
966  * Zero out all of the IVT (0x00 -- 0xFF). Some applications
967  * indeed expect to have free vectors at the end of the IVT.
968  */
969  RtlZeroMemory(BaseAddress, 0x0100 * sizeof(ULONG));
970 
971 #if defined(ADVANCED_DEBUGGING) && (ADVANCED_DEBUGGING_LEVEL >= 3)
972  // Initialize all the interrupt vectors to the default one.
973  for (i = 0x00; i <= 0xFF; i++)
975 #endif
976 
977  /* Initialize the exception interrupt vectors to a default Exception handler */
978  for (i = 0x00; i <= 0x07; i++)
980 
981  /* Initialize HW interrupt vectors to a default HW handler */
982  for (i = BIOS_PIC_MASTER_INT; i < BIOS_PIC_MASTER_INT + 8; i++) // 0x08 -- 0x0F
984  for (i = BIOS_PIC_SLAVE_INT ; i < BIOS_PIC_SLAVE_INT + 8; i++) // 0x70 -- 0x77
986 
987  /* Initialize software vector handlers */
988  // BIOS_VIDEO_INTERRUPT : 0x10 (vidbios32.c)
991  // BIOS_DISK_INTERRUPT : 0x13 (dskbios32.c)
992  // BIOS_SERIAL_INTERRUPT : 0x14 -- UNIMPLEMENTED
994  // BIOS_KBD_INTERRUPT : 0x16 (kbdbios32.c)
995  // BIOS_PRINTER_INTERRUPT: 0x17 -- UNIMPLEMENTED
999  // BIOS_KBD_CTRL_BREAK_INTERRUPT: 0x1B -- UNIMPLEMENTED
1001 
1002  /* Vectors that should be implemented (see above) */
1003  RegisterBiosInt32(0x14, NULL);
1004  RegisterBiosInt32(0x17, NULL);
1005  RegisterBiosInt32(0x1B, NULL);
1006  RegisterBiosInt32(0x4A, NULL); // User Alarm Handler
1007 
1008  /* Relocated services by the BIOS (when needed) */
1009  RegisterBiosInt32(0x40, NULL); // ROM BIOS Diskette Handler relocated by Hard Disk BIOS
1010  RegisterBiosInt32(0x42, NULL); // Relocated Default INT 10h Video Services
1011 
1012  /* Miscellaneous unimplemented vector handlers that should better have a default one */
1013  RegisterBiosInt32(0x4B, NULL); // Virtual DMA Specification Services
1014  RegisterBiosInt32(0x5C, NULL); // NetBIOS
1015 
1016  // ROM-BASIC interrupts span from 0x80 up to 0xEF.
1017  // They don't have any default handler at the moment.
1018 
1019  /* Some vectors are in fact addresses to tables */
1020  ((PULONG)BaseAddress)[0x1D] = NULL32; // Video Parameter Tables
1021  ((PULONG)BaseAddress)[0x1E] = NULL32; // Diskette Parameters
1022  ((PULONG)BaseAddress)[0x1F] = NULL32; // 8x8 Graphics Font
1023  ((PULONG)BaseAddress)[0x41] = NULL32; // Hard Disk 0 Parameter Table Address
1024  ((PULONG)BaseAddress)[0x43] = NULL32; // Character Table (EGA, MCGA, VGA)
1025  ((PULONG)BaseAddress)[0x46] = NULL32; // Hard Disk 1 Drive Parameter Table Address
1026  /* Tables that are always uninitialized */
1027  ((PULONG)BaseAddress)[0x44] = NULL32; // ROM BIOS Character Font, Characters 00h-7Fh (PCjr)
1028  ((PULONG)BaseAddress)[0x48] = NULL32; // Cordless Keyboard Translation (PCjr)
1029  ((PULONG)BaseAddress)[0x49] = NULL32; // Non-Keyboard Scan-code Translation Table (PCJr)
1030 }
#define BIOS_TIME_INTERRUPT
Definition: bios32p.h:28
#define BIOS_SYS_TIMER_INTERRUPT
Definition: bios32p.h:29
VOID InitializeContext(IN PCALLBACK16 Context, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:60
static VOID WINAPI BiosHandleSlavePicIRQ(LPWORD Stack)
Definition: bios32.c:842
#define BIOS_BOOTSTRAP_LOADER
Definition: bios32p.h:27
static VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack)
Definition: bios32.c:782
static VOID WINAPI BiosMiscService(LPWORD Stack)
Definition: bios32.c:212
VOID WINAPI BiosEquipmentService(LPWORD Stack)
Definition: bios32.c:200
#define RegisterBiosInt32(IntNumber, IntHandler)
Definition: bios32p.h:34
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static VOID WINAPI BiosException(LPWORD Stack)
Definition: bios32.c:193
static VOID WINAPI BiosHandleMasterPicIRQ(LPWORD Stack)
Definition: bios32.c:830
#define BIOS_MISC_INTERRUPT
Definition: bios32p.h:25
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
static VOID WINAPI BiosRomBasic(LPWORD Stack)
Definition: bios32.c:552
CALLBACK16 BiosContext
Definition: bios32.c:45
#define BIOS_PIC_SLAVE_INT
Definition: bios32p.h:21
#define BIOS_MEMORY_SIZE
Definition: bios32p.h:24
#define NULL32
Definition: ntvdm.h:70
static VOID WINAPI BiosTimeService(LPWORD Stack)
Definition: bios32.c:686
VOID WINAPI BiosGetMemorySize(LPWORD Stack)
Definition: bios32.c:206
#define BIOS_ROM_BASIC
Definition: bios32p.h:26
unsigned short USHORT
Definition: pedump.c:61
#define BIOS_PIC_MASTER_INT
Definition: bios32p.h:20
static VOID WINAPI BiosBootstrapLoader(LPWORD Stack)
Definition: bios32.c:567
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define BIOS_EQUIPMENT_INTERRUPT
Definition: bios32p.h:23
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define BIOS_SEGMENT
Definition: bios.h:29

Referenced by Bios32Post().

◆ PicIRQComplete()

VOID PicIRQComplete ( BYTE  IntNum)

Definition at line 812 of file bios32.c.

813 {
814  /*
815  * If this was a PIC IRQ, send an End-of-Interrupt to the PIC.
816  */
817  if (IntNum >= BIOS_PIC_MASTER_INT && IntNum < BIOS_PIC_MASTER_INT + 8)
818  {
819  /* It was an IRQ from the master PIC */
821  }
822  else if (IntNum >= BIOS_PIC_SLAVE_INT && IntNum < BIOS_PIC_SLAVE_INT + 8)
823  {
824  /* It was an IRQ from the slave PIC */
827  }
828 }
#define PIC_MASTER_CMD
Definition: pic.h:15
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
#define BIOS_PIC_SLAVE_INT
Definition: bios32p.h:21
#define PIC_OCW2_EOI
Definition: pic.h:27
#define BIOS_PIC_MASTER_INT
Definition: bios32p.h:20
#define PIC_SLAVE_CMD
Definition: pic.h:17

Referenced by BiosHandleMasterPicIRQ(), BiosHandleSlavePicIRQ(), BiosKeyboardIrq(), BiosMouseIrq(), BiosTimerIrq(), and DosMouseIrq().

◆ PicSetIRQMask()

static VOID PicSetIRQMask ( USHORT  off,
USHORT  on 
)
static

Definition at line 790 of file bios32.c.

791 {
792  UCHAR pic1off = off, pic1on = on, pic2off = off>>8, pic2on = on>>8;
793  IOWriteB(PIC_MASTER_DATA, (IOReadB(PIC_MASTER_DATA) & ~pic1off) | pic1on);
794  IOWriteB(PIC_SLAVE_DATA , (IOReadB(PIC_SLAVE_DATA ) & ~pic2off) | pic2on);
795 }
#define PIC_MASTER_DATA
Definition: pic.h:16
UCHAR IOReadB(USHORT Port)
Definition: io.c:64
#define PIC_SLAVE_DATA
Definition: pic.h:18
VOID IOWriteB(USHORT Port, UCHAR Buffer)
Definition: io.c:111
unsigned char UCHAR
Definition: xmlstorage.h:181
off
Definition: i386-dis.c:3909

Referenced by EnableHwIRQ().

Variable Documentation

◆ BiosConfigTable

const BIOS_CONFIG_TABLE BiosConfigTable
static
Initial value:
=
{
sizeof(BIOS_CONFIG_TABLE) - sizeof(((BIOS_CONFIG_TABLE*)0)->Length),
{
0x78,
0x00,
0x10,
0x00,
0x00
}
}
#define BIOS_REVISION
Definition: bios32.c:112
#define BIOS_MODEL
Definition: bios32.c:110
struct _BIOS_CONFIG_TABLE BIOS_CONFIG_TABLE
#define BIOS_SUBMODEL
Definition: bios32.c:111

Definition at line 115 of file bios32.c.

Referenced by Bios32Initialize().

◆ BiosContext

◆ BiosCopyright

const CHAR BiosCopyright[] = "0000000 NTVDM IBM COMPATIBLE 486 BIOS COPYRIGHT (C) ReactOS Team 1996-"COPYRIGHT_YEAR
static

Definition at line 138 of file bios32.c.

Referenced by Bios32Initialize().

◆ BiosDate

const CHAR BiosDate[] = "06/17/13"
static

Definition at line 141 of file bios32.c.

Referenced by Bios32Initialize(), and CmpGetBiosDate().

◆ BiosVersion

const CHAR BiosVersion[]
static
Initial value:
= "ReactOS NTVDM 32-bit BIOS Version "KERNEL_VERSION_STR"\0"
"BIOS32 Version "KERNEL_VERSION_STR" (Build "KERNEL_VERSION_BUILD_STR")"

Definition at line 139 of file bios32.c.

Referenced by Bios32Initialize(), CmpGetBiosVersion(), and CmpInitializeMachineDependentConfiguration().

◆ Bootstrap

const BYTE Bootstrap[]
static
Initial value:
=
{
0xEA,
0x5B, 0xE0, 0x00, 0xF0,
}

Definition at line 147 of file bios32.c.

Referenced by Bios32Initialize().

◆ PostCode

const BYTE PostCode[]
static
Initial value:
=
{
}
#define LOBYTE(W)
Definition: jmemdos.c:487
#define BIOS_BOOTSTRAP_LOADER
Definition: bios32p.h:27
#define HIBYTE(W)
Definition: jmemdos.c:486
#define BOP_UNSIMULATE
Definition: isvbop.h:31
#define BOP_RESET
Definition: bios.c:33
#define BIOS_ROM_BASIC
Definition: bios32p.h:26
#define EMULATOR_BOP
Definition: bop.h:16

Definition at line 157 of file bios32.c.

Referenced by Bios32Initialize().