- DOS: the DOS file attributes are one byte.
- BIOS: don't use hardcoded values; use the SEG_OFF_TO_PTR macro introduced earlier; use get/setAX instead of EmulatorGet/SetRegister.

svn path=/branches/ntvdm/; revision=60781
This commit is contained in:
Hermès Bélusca-Maïto 2013-10-27 23:39:52 +00:00
parent 09d991b838
commit 76708ef246
2 changed files with 57 additions and 89 deletions

View file

@ -270,7 +270,7 @@ static LPBYTE VideoModes[] =
static BOOLEAN BiosKbdBufferPush(WORD Data) static BOOLEAN BiosKbdBufferPush(WORD Data)
{ {
/* Get the location of the element after the tail */ /* Get the location of the element after the tail */
WORD NextElement = Bda->KeybdBufferTail + 2; WORD NextElement = Bda->KeybdBufferTail + sizeof(WORD);
/* Wrap it around if it's at or beyond the end */ /* Wrap it around if it's at or beyond the end */
if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart; if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart;
@ -455,11 +455,11 @@ BOOLEAN BiosInitialize(VOID)
{ {
INT i; INT i;
WORD Offset = 0; WORD Offset = 0;
LPWORD IntVecTable = (LPWORD)((ULONG_PTR)BaseAddress); LPWORD IntVecTable = (LPWORD)BaseAddress;
LPBYTE BiosCode = (LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(BIOS_SEGMENT, 0)); LPBYTE BiosCode = (LPBYTE)SEG_OFF_TO_PTR(BIOS_SEGMENT, 0);
/* Initialize the BDA */ /* Initialize the BDA */
Bda = (PBIOS_DATA_AREA)((ULONG_PTR)BaseAddress + TO_LINEAR(BDA_SEGMENT, 0)); Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0);
Bda->EquipmentList = BIOS_EQUIPMENT_LIST; Bda->EquipmentList = BIOS_EQUIPMENT_LIST;
Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer); Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer);
Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD); Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD);
@ -594,8 +594,8 @@ VOID BiosCleanup(VOID)
WORD BiosPeekCharacter(VOID) WORD BiosPeekCharacter(VOID)
{ {
WORD CharacterData; WORD CharacterData = 0;
/* Get the key from the queue, but don't remove it */ /* Get the key from the queue, but don't remove it */
if (BiosKbdBufferTop(&CharacterData)) return CharacterData; if (BiosKbdBufferTop(&CharacterData)) return CharacterData;
else return 0xFFFF; else return 0xFFFF;
@ -777,17 +777,12 @@ VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page)
VOID BiosVideoService(LPWORD Stack) VOID BiosVideoService(LPWORD Stack)
{ {
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX); switch (getAH())
DWORD Ecx = EmulatorGetRegister(EMULATOR_REG_CX);
DWORD Edx = EmulatorGetRegister(EMULATOR_REG_DX);
DWORD Ebx = EmulatorGetRegister(EMULATOR_REG_BX);
switch (HIBYTE(Eax))
{ {
/* Set Video Mode */ /* Set Video Mode */
case 0x00: case 0x00:
{ {
BiosSetVideoMode(LOBYTE(Eax)); BiosSetVideoMode(getAL());
VgaClearMemory(); VgaClearMemory();
break; break;
} }
@ -796,8 +791,8 @@ VOID BiosVideoService(LPWORD Stack)
case 0x01: case 0x01:
{ {
/* Update the BDA */ /* Update the BDA */
Bda->CursorStartLine = HIBYTE(Ecx); Bda->CursorStartLine = getCH();
Bda->CursorEndLine = LOBYTE(Ecx); Bda->CursorEndLine = getCL();
/* Modify the CRTC registers */ /* Modify the CRTC registers */
VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG); VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG);
@ -811,7 +806,7 @@ VOID BiosVideoService(LPWORD Stack)
/* Set Cursor Position */ /* Set Cursor Position */
case 0x02: case 0x02:
{ {
BiosSetCursorPosition(HIBYTE(Edx), LOBYTE(Edx), HIBYTE(Ebx)); BiosSetCursorPosition(getDH(), getDL(), getBH());
break; break;
} }
@ -819,14 +814,12 @@ VOID BiosVideoService(LPWORD Stack)
case 0x03: case 0x03:
{ {
/* Make sure the selected video page exists */ /* Make sure the selected video page exists */
if (HIBYTE(Ebx) >= BIOS_MAX_PAGES) break; if (getBH() >= BIOS_MAX_PAGES) break;
/* Return the result */ /* Return the result */
EmulatorSetRegister(EMULATOR_REG_AX, 0); setAX(0);
EmulatorSetRegister(EMULATOR_REG_CX, setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine));
(Bda->CursorStartLine << 8) | Bda->CursorEndLine); setDX(Bda->CursorPosition[getBH()]);
EmulatorSetRegister(EMULATOR_REG_DX, Bda->CursorPosition[HIBYTE(Ebx)]);
break; break;
} }
@ -837,14 +830,14 @@ VOID BiosVideoService(LPWORD Stack)
* On modern BIOSes, this function returns 0 * On modern BIOSes, this function returns 0
* so that we can ignore the other registers. * so that we can ignore the other registers.
*/ */
EmulatorSetRegister(EMULATOR_REG_AX, 0); setAX(0);
break; break;
} }
/* Select Active Display Page */ /* Select Active Display Page */
case 0x05: case 0x05:
{ {
BiosSetVideoPage(LOBYTE(Eax)); BiosSetVideoPage(getAL());
break; break;
} }
@ -852,21 +845,15 @@ VOID BiosVideoService(LPWORD Stack)
case 0x06: case 0x06:
case 0x07: case 0x07:
{ {
SMALL_RECT Rectangle = SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() };
{
LOBYTE(Ecx),
HIBYTE(Ecx),
LOBYTE(Edx),
HIBYTE(Edx)
};
/* Call the internal function */ /* Call the internal function */
BiosScrollWindow((HIBYTE(Eax) == 0x06) ? SCROLL_DIRECTION_UP BiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP
: SCROLL_DIRECTION_DOWN, : SCROLL_DIRECTION_DOWN,
LOBYTE(Eax), getAL(),
Rectangle, Rectangle,
Bda->VideoPage, Bda->VideoPage,
HIBYTE(Ebx)); getBH());
break; break;
} }
@ -876,19 +863,19 @@ VOID BiosVideoService(LPWORD Stack)
case 0x09: case 0x09:
case 0x0A: case 0x0A:
{ {
WORD CharacterData = MAKEWORD(LOBYTE(Eax), LOBYTE(Ebx)); WORD CharacterData = MAKEWORD(getAL(), getBL());
BYTE Page = HIBYTE(Ebx); BYTE Page = getBH();
DWORD Offset; DWORD Offset;
/* Check if the page exists */ /* Check if the page exists */
if (Page >= BIOS_MAX_PAGES) break; if (Page >= BIOS_MAX_PAGES) break;
/* Find the offset of the character */ /* Find the offset of the character */
Offset = Page * Bda->VideoPageSize Offset = Page * Bda->VideoPageSize +
+ (HIBYTE(Bda->CursorPosition[Page]) * Bda->ScreenColumns (HIBYTE(Bda->CursorPosition[Page]) * Bda->ScreenColumns +
+ LOBYTE(Bda->CursorPosition[Page])) * 2; LOBYTE(Bda->CursorPosition[Page])) * 2;
if (HIBYTE(Eax) == 0x08) if (getAH() == 0x08)
{ {
/* Read from the video memory */ /* Read from the video memory */
VgaReadMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset), VgaReadMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset),
@ -896,14 +883,14 @@ VOID BiosVideoService(LPWORD Stack)
sizeof(WORD)); sizeof(WORD));
/* Return the character in AX */ /* Return the character in AX */
EmulatorSetRegister(EMULATOR_REG_AX, CharacterData); setAX(CharacterData);
} }
else else
{ {
/* Write to video memory */ /* Write to video memory */
VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset), VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset),
(LPVOID)&CharacterData, (LPVOID)&CharacterData,
(HIBYTE(Ebx) == 0x09) ? sizeof(WORD) : sizeof(BYTE)); (getBH() == 0x09) ? sizeof(WORD) : sizeof(BYTE));
} }
break; break;
@ -912,35 +899,26 @@ VOID BiosVideoService(LPWORD Stack)
/* Teletype Output */ /* Teletype Output */
case 0x0E: case 0x0E:
{ {
BiosPrintCharacter(LOBYTE(Eax), LOBYTE(Ebx), HIBYTE(Ebx)); BiosPrintCharacter(getAL(), getBL(), getBH());
break; break;
} }
/* Get Current Video Mode */ /* Get Current Video Mode */
case 0x0F: case 0x0F:
{ {
EmulatorSetRegister(EMULATOR_REG_AX, setAX(MAKEWORD(Bda->VideoMode, Bda->ScreenColumns));
MAKEWORD(Bda->VideoMode, Bda->ScreenColumns)); setBX(MAKEWORD(getBL(), Bda->VideoPage));
EmulatorSetRegister(EMULATOR_REG_BX,
MAKEWORD(LOBYTE(Ebx), Bda->VideoPage));
break; break;
} }
/* Scroll Window */ /* Scroll Window */
case 0x12: case 0x12:
{ {
SMALL_RECT Rectangle = SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() };
{
LOBYTE(Ecx),
HIBYTE(Ecx),
LOBYTE(Edx),
HIBYTE(Edx)
};
/* Call the internal function */ /* Call the internal function */
BiosScrollWindow(LOBYTE(Ebx), BiosScrollWindow(getBL(),
LOBYTE(Eax), getAL(),
Rectangle, Rectangle,
Bda->VideoPage, Bda->VideoPage,
DEFAULT_ATTRIBUTE); DEFAULT_ATTRIBUTE);
@ -951,11 +929,11 @@ VOID BiosVideoService(LPWORD Stack)
/* Display combination code */ /* Display combination code */
case 0x1A: case 0x1A:
{ {
switch(LOBYTE(Eax)) switch(getAL())
{ {
case 0x00: /* Get Display combiantion code */ case 0x00: /* Get Display combiantion code */
EmulatorSetRegister(EMULATOR_REG_AX, MAKEWORD(0x1A, 0x1A)); setAX(MAKEWORD(0x1A, 0x1A));
EmulatorSetRegister(EMULATOR_REG_BX, MAKEWORD(0x08, 0x0)); /* VGA w/ color analog display */ setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */
break; break;
case 0x01: /* Set Display combination code */ case 0x01: /* Set Display combination code */
DPRINT1("Set Display combination code - Unsupported\n"); DPRINT1("Set Display combination code - Unsupported\n");
@ -969,16 +947,14 @@ VOID BiosVideoService(LPWORD Stack)
default: default:
{ {
DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n", DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n",
HIBYTE(Eax)); getAH());
} }
} }
} }
VOID BiosKeyboardService(LPWORD Stack) VOID BiosKeyboardService(LPWORD Stack)
{ {
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX); switch (getAH())
switch (HIBYTE(Eax))
{ {
/* Wait for keystroke and read */ /* Wait for keystroke and read */
case 0x00: case 0x00:
@ -986,7 +962,7 @@ VOID BiosKeyboardService(LPWORD Stack)
case 0x10: // FIXME: Temporarily do the same as INT 16h, 00h case 0x10: // FIXME: Temporarily do the same as INT 16h, 00h
{ {
/* Read the character (and wait if necessary) */ /* Read the character (and wait if necessary) */
EmulatorSetRegister(EMULATOR_REG_AX, BiosGetCharacter()); setAX(BiosGetCharacter());
break; break;
} }
@ -1000,8 +976,8 @@ VOID BiosKeyboardService(LPWORD Stack)
if (Data != 0xFFFF) if (Data != 0xFFFF)
{ {
/* There is a character, clear ZF and return it */ /* There is a character, clear ZF and return it */
EmulatorSetRegister(EMULATOR_REG_AX, Data);
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF; Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF;
setAX(Data);
} }
else else
{ {
@ -1053,29 +1029,23 @@ VOID BiosKeyboardService(LPWORD Stack)
default: default:
{ {
DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n", DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n",
HIBYTE(Eax)); getAH());
} }
} }
} }
VOID BiosTimeService(LPWORD Stack) VOID BiosTimeService(LPWORD Stack)
{ {
DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX); switch (getAH())
DWORD Ecx = EmulatorGetRegister(EMULATOR_REG_CX);
DWORD Edx = EmulatorGetRegister(EMULATOR_REG_DX);
switch (HIBYTE(Eax))
{ {
case 0x00: case 0x00:
{ {
/* Set AL to 1 if midnight had passed, 0 otherwise */ /* Set AL to 1 if midnight had passed, 0 otherwise */
Eax &= 0xFFFFFF00; setAL(Bda->MidnightPassed ? 0x01 : 0x00);
if (Bda->MidnightPassed) Eax |= 1;
/* Return the tick count in CX:DX */ /* Return the tick count in CX:DX */
EmulatorSetRegister(EMULATOR_REG_AX, Eax); setCX(HIWORD(Bda->TickCounter));
EmulatorSetRegister(EMULATOR_REG_CX, HIWORD(Bda->TickCounter)); setDX(LOWORD(Bda->TickCounter));
EmulatorSetRegister(EMULATOR_REG_DX, LOWORD(Bda->TickCounter));
/* Reset the midnight flag */ /* Reset the midnight flag */
Bda->MidnightPassed = FALSE; Bda->MidnightPassed = FALSE;
@ -1086,7 +1056,7 @@ VOID BiosTimeService(LPWORD Stack)
case 0x01: case 0x01:
{ {
/* Set the tick count to CX:DX */ /* Set the tick count to CX:DX */
Bda->TickCounter = MAKELONG(LOWORD(Edx), LOWORD(Ecx)); Bda->TickCounter = MAKELONG(getDX(), getCX());
/* Reset the midnight flag */ /* Reset the midnight flag */
Bda->MidnightPassed = FALSE; Bda->MidnightPassed = FALSE;
@ -1097,7 +1067,7 @@ VOID BiosTimeService(LPWORD Stack)
default: default:
{ {
DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n", DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n",
HIBYTE(Eax)); getAH());
} }
} }
} }
@ -1111,7 +1081,7 @@ VOID BiosSystemTimerInterrupt(LPWORD Stack)
VOID BiosEquipmentService(LPWORD Stack) VOID BiosEquipmentService(LPWORD Stack)
{ {
/* Return the equipment list */ /* Return the equipment list */
EmulatorSetRegister(EMULATOR_REG_AX, Bda->EquipmentList); setAX(Bda->EquipmentList);
} }
VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack) VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
@ -1123,7 +1093,6 @@ VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
{ {
/* Perform the system timer interrupt */ /* Perform the system timer interrupt */
EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT); EmulatorInterrupt(BIOS_SYS_TIMER_INTERRUPT);
break; break;
} }
@ -1144,15 +1113,15 @@ VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack)
if (!(ScanCode & (1 << 7))) if (!(ScanCode & (1 << 7)))
{ {
/* Key press */ /* Key press */
if (VirtualKey == VK_NUMLOCK if (VirtualKey == VK_NUMLOCK ||
|| VirtualKey == VK_CAPITAL VirtualKey == VK_CAPITAL ||
|| VirtualKey == VK_SCROLL VirtualKey == VK_SCROLL ||
|| VirtualKey == VK_INSERT) VirtualKey == VK_INSERT)
{ {
/* For toggle keys, toggle the lowest bit in the keyboard map */ /* For toggle keys, toggle the lowest bit in the keyboard map */
BiosKeyboardMap[VirtualKey] ^= ~(1 << 0); BiosKeyboardMap[VirtualKey] ^= ~(1 << 0);
} }
/* Set the highest bit */ /* Set the highest bit */
BiosKeyboardMap[VirtualKey] |= (1 << 7); BiosKeyboardMap[VirtualKey] |= (1 << 7);

View file

@ -1886,8 +1886,7 @@ VOID DosInt21h(LPWORD Stack)
/* Return the attributes that DOS can understand */ /* Return the attributes that DOS can understand */
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
// setCL(LOBYTE(Attributes)); setCL(LOBYTE(Attributes));
setCX(LOWORD(Attributes));
} }
else if (getAL() == 0x01) else if (getAL() == 0x01)
{ {