From b20613401f923ef2c6dced03db1c14e2833512a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 8 Dec 2013 14:22:27 +0000 Subject: [PATCH] [NTVDM] Rewrite the VGA emulation. Nah, it's a joke! - Store VGA registers setup in VGA_REGISTERS structure. - Improve BiosSetVideoMode and introduce a VgaSetRegisters function for setting VGA regs. - Initialize Bda->CrtBasePort: it is used to determine the address of some I/O ports which depend on whether we are in color or monochrome mode. - Add UnregisterIoPort in io.c (and fix some DPRINTs) (needed for VGA). - When setting the misc. VGA register, check whether we're going to monochrome emulation, and reset some port addresses in that case. svn path=/branches/ntvdm/; revision=61246 --- subsystems/ntvdm/bios.c | 435 ++++++++++++++++++++++------------------ subsystems/ntvdm/io.c | 10 +- subsystems/ntvdm/io.h | 3 +- subsystems/ntvdm/vga.c | 278 +++++++++++++++---------- subsystems/ntvdm/vga.h | 226 +++++++++++++-------- 5 files changed, 564 insertions(+), 388 deletions(-) diff --git a/subsystems/ntvdm/bios.c b/subsystems/ntvdm/bios.c index 1a9fd081e91..3b28f6d1dfa 100644 --- a/subsystems/ntvdm/bios.c +++ b/subsystems/ntvdm/bios.c @@ -21,6 +21,16 @@ #include "int32.h" #include "registers.h" +/* MACROS *********************************************************************/ + +// +// These macros are defined for ease-of-use of some VGA I/O ports +// whose addresses depend whether we are in Monochrome or Colour mode. +// +#define VGA_INSTAT1_READ Bda->CrtBasePort + 6 // VGA_INSTAT1_READ_MONO or VGA_INSTAT1_READ_COLOR +#define VGA_CRTC_INDEX Bda->CrtBasePort // VGA_CRTC_INDEX_MONO or VGA_CRTC_INDEX_COLOR +#define VGA_CRTC_DATA Bda->CrtBasePort + 1 // VGA_CRTC_DATA_MONO or VGA_CRTC_DATA_COLOR + /* PRIVATE VARIABLES **********************************************************/ PBIOS_DATA_AREA Bda; @@ -33,258 +43,239 @@ static CONSOLE_SCREEN_BUFFER_INFO BiosSavedBufferInfo; * VGA Register Configurations for BIOS Video Modes * The configurations come from DosBox. */ -static BYTE VideoMode_40x25_text[] = +static VGA_REGISTERS VideoMode_40x25_text = { /* Miscellaneous Register */ 0x67, /* Sequencer Registers */ - 0x00, 0x08, 0x03, 0x00, 0x07, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF, + {0x00, 0x08, 0x03, 0x00, 0x07}, /* CRTC Registers */ - 0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3, - 0xFF, + {0x2D, 0x27, 0x28, 0x90, 0x2B, 0xA0, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x1F, 0x96, 0xB9, 0xA3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00} }; -static BYTE VideoMode_80x25_text[] = +static VGA_REGISTERS VideoMode_80x25_text = { /* Miscellaneous Register */ 0x67, /* Sequencer Registers */ - 0x00, 0x00, 0x03, 0x00, 0x07, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF, + {0x00, 0x00, 0x03, 0x00, 0x07}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x55, 0x81, 0xBF, 0x1F, 0x00, 0x4F, 0x0D, 0x0E, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x1F, 0x96, 0xB9, 0xA3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0E, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x0C, 0x00, 0x0F, 0x08, 0x00} }; -static BYTE VideoMode_320x200_4color[] = +static VGA_REGISTERS VideoMode_320x200_4color = { /* Miscellaneous Register */ 0x63, /* Sequencer Registers */ - 0x00, 0x09, 0x00, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0F, 0x0F, 0xFF, + {0x00, 0x09, 0x00, 0x00, 0x02}, /* CRTC Registers */ - 0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2, - 0xFF, + {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xA2, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0F, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x01, 0x00, 0x0F, 0x00, 0x00} }; -static BYTE VideoMode_640x200_2color[] = +static VGA_REGISTERS VideoMode_640x200_2color = { /* Miscellaneous Register */ 0x63, /* Sequencer Registers */ - 0x00, 0x09, 0x0F, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF, + {0x00, 0x09, 0x0F, 0x00, 0x02}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC1, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xC2, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, - 0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00 + {0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, + 0x17, 0x17, 0x17, 0x17, 0x01, 0x00, 0x01, 0x00, 0x00} }; -static BYTE VideoMode_320x200_16color[] = +static VGA_REGISTERS VideoMode_320x200_16color = { /* Miscellaneous Register */ 0x63, /* Sequencer Registers */ - 0x00, 0x09, 0x0F, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF, + {0x00, 0x09, 0x0F, 0x00, 0x02}, /* CRTC Registers */ - 0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3, - 0xFF, + {0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00} }; -static BYTE VideoMode_640x200_16color[] = +static VGA_REGISTERS VideoMode_640x200_16color = { /* Miscellaneous Register */ 0x63, /* Sequencer Registers */ - 0x00, 0x01, 0x0F, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF, + {0x00, 0x01, 0x0F, 0x00, 0x02}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00} }; -static BYTE VideoMode_640x350_16color[] = +static VGA_REGISTERS VideoMode_640x350_16color = { /* Miscellaneous Register */ 0xA3, /* Sequencer Registers */ - 0x00, 0x01, 0x0F, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF, + {0x00, 0x01, 0x0F, 0x00, 0x02}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00} }; -static BYTE VideoMode_640x480_2color[] = +static VGA_REGISTERS VideoMode_640x480_2color = { /* Miscellaneous Register */ 0xE3, /* Sequencer Registers */ - 0x00, 0x01, 0x0F, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF, + {0x00, 0x01, 0x0F, 0x00, 0x02}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xC3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, - 0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00} }; -static BYTE VideoMode_640x480_16color[] = +static VGA_REGISTERS VideoMode_640x480_16color = { /* Miscellaneous Register */ 0xE3, /* Sequencer Registers */ - 0x00, 0x01, 0x0F, 0x00, 0x02, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF, + {0x00, 0x01, 0x0F, 0x00, 0x02}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0x3E, 0x3F, 0x01, 0x00, 0x0F, 0x00, 0x00} }; -static BYTE VideoMode_320x200_256color[] = +static VGA_REGISTERS VideoMode_320x200_256color = { /* Miscellaneous Register */ 0x63, /* Sequencer Registers */ - 0x00, 0x01, 0x0F, 0x00, 0x0E, - - /* GC Registers */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF, + {0x00, 0x01, 0x0F, 0x00, 0x0E}, /* CRTC Registers */ - 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3, - 0xFF, + {0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3, + 0xFF}, + + /* GC Registers */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF}, /* AC Registers */ - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, - 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00 + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00} }; -static LPBYTE VideoModes[] = +/* See http://wiki.osdev.org/Drawing_In_Protected_Mode#Locating_Video_Memory */ +static PVGA_REGISTERS VideoModes[] = { - VideoMode_40x25_text, /* Mode 00h */ - VideoMode_40x25_text, /* Mode 01h */ - VideoMode_80x25_text, /* Mode 02h */ - VideoMode_80x25_text, /* Mode 03h */ - VideoMode_320x200_4color, /* Mode 04h */ - VideoMode_320x200_4color, /* Mode 05h */ - VideoMode_640x200_2color, /* Mode 06h */ - NULL, /* Mode 07h */ - NULL, /* Mode 08h */ - NULL, /* Mode 09h */ - NULL, /* Mode 0Ah */ - NULL, /* Mode 0Bh */ - NULL, /* Mode 0Ch */ - VideoMode_320x200_16color, /* Mode 0Dh */ - VideoMode_640x200_16color, /* Mode 0Eh */ - NULL, /* Mode 0Fh */ - VideoMode_640x350_16color, /* Mode 10h */ - VideoMode_640x480_2color, /* Mode 11h */ - VideoMode_640x480_16color, /* Mode 12h */ - VideoMode_320x200_256color, /* Mode 13h */ -}; - -static CONST COLORREF EgaPalette[VGA_MAX_COLORS / 4] = -{ - RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA), - RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA), - RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF), - RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF), - RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA), - RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA), - RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF), - RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF), - RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA), - RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA), - RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF), - RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF), - RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA), - RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA), - RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF), - RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF) + &VideoMode_40x25_text, /* Mode 00h */ // 16 color (mono) + &VideoMode_40x25_text, /* Mode 01h */ // 16 color + &VideoMode_80x25_text, /* Mode 02h */ // 16 color (mono) + &VideoMode_80x25_text, /* Mode 03h */ // 16 color + &VideoMode_320x200_4color, /* Mode 04h */ + &VideoMode_320x200_4color, /* Mode 05h */ // same (m) + &VideoMode_640x200_2color, /* Mode 06h */ // 640*200 2 color + NULL, /* Mode 07h */ // MDA monochrome text 80*25 + NULL, /* Mode 08h */ // PCjr + NULL, /* Mode 09h */ // PCjr + NULL, /* Mode 0Ah */ // PCjr + NULL, /* Mode 0Bh */ // Reserved + NULL, /* Mode 0Ch */ // Reserved + &VideoMode_320x200_16color, /* Mode 0Dh */ // EGA 320*200 16 color + &VideoMode_640x200_16color, /* Mode 0Eh */ // EGA 640*200 16 color + NULL, /* Mode 0Fh */ // EGA 640*350 mono + &VideoMode_640x350_16color, /* Mode 10h */ // EGA 640*350 16 color + &VideoMode_640x480_2color, /* Mode 11h */ // VGA 640*480 mono + &VideoMode_640x480_16color, /* Mode 12h */ + &VideoMode_320x200_256color, /* Mode 13h */ }; /* PRIVATE FUNCTIONS **********************************************************/ @@ -388,6 +379,86 @@ static VOID BiosWriteWindow(LPWORD Buffer, SMALL_RECT Rectangle, BYTE Page) } } +static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers) +{ + INT i; + + if (Registers == NULL) return FALSE; + + /* Clear interrupts */ + setIF(0); + + /* + * Set the CRT base address according to the selected mode, + * monochrome or color. The following macros: + * VGA_INSTAT1_READ, VGA_CRTC_INDEX and VGA_CRTC_DATA are then + * used to access the correct VGA I/O ports. + */ + Bda->CrtBasePort = (Registers->Misc & 0x01) ? VGA_CRTC_INDEX_COLOR + : VGA_CRTC_INDEX_MONO; + + /* Write the misc register */ + VgaWritePort(VGA_MISC_WRITE, Registers->Misc); + + /* Synchronous reset on */ + VgaWritePort(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG); + VgaWritePort(VGA_SEQ_DATA , VGA_SEQ_RESET_AR); + + /* Write the sequencer registers */ + for (i = 1; i < VGA_SEQ_MAX_REG; i++) + { + VgaWritePort(VGA_SEQ_INDEX, i); + VgaWritePort(VGA_SEQ_DATA, Registers->Sequencer[i]); + } + + /* Synchronous reset off */ + VgaWritePort(VGA_SEQ_INDEX, VGA_SEQ_RESET_REG); + VgaWritePort(VGA_SEQ_DATA , VGA_SEQ_RESET_SR | VGA_SEQ_RESET_AR); + + /* Unlock CRTC registers 0-7 */ + VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_END_HORZ_BLANKING_REG); + VgaWritePort(VGA_CRTC_DATA, VgaReadPort(VGA_CRTC_DATA) | 0x80); + VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_VERT_RETRACE_END_REG); + VgaWritePort(VGA_CRTC_DATA, VgaReadPort(VGA_CRTC_DATA) & ~0x80); + // Make sure they remain unlocked + Registers->CRT[VGA_CRTC_END_HORZ_BLANKING_REG] |= 0x80; + Registers->CRT[VGA_CRTC_VERT_RETRACE_END_REG] &= ~0x80; + + /* Write the CRTC registers */ + for (i = 0; i < VGA_CRTC_MAX_REG; i++) + { + VgaWritePort(VGA_CRTC_INDEX, i); + VgaWritePort(VGA_CRTC_DATA, Registers->CRT[i]); + } + + /* Write the GC registers */ + for (i = 0; i < VGA_GC_MAX_REG; i++) + { + VgaWritePort(VGA_GC_INDEX, i); + VgaWritePort(VGA_GC_DATA, Registers->Graphics[i]); + } + + /* Write the AC registers */ + for (i = 0; i < VGA_AC_MAX_REG; i++) + { + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, i); + VgaWritePort(VGA_AC_WRITE, Registers->Attribute[i]); + } + + /* Set the PEL mask */ + VgaWritePort(VGA_DAC_MASK, 0xFF); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + + /* Set interrupts */ + setIF(1); + + return TRUE; +} + /* PUBLIC FUNCTIONS ***********************************************************/ BYTE BiosGetVideoMode(VOID) @@ -399,47 +470,21 @@ BOOLEAN BiosSetVideoMode(BYTE ModeNumber) { INT i; COORD Resolution; - LPBYTE Values = VideoModes[ModeNumber]; + PVGA_REGISTERS VgaMode = VideoModes[ModeNumber]; - DPRINT1("Switching to mode %Xh; Values = 0x%p\n", ModeNumber, Values); + DPRINT1("Switching to mode %Xh; VgaMode = 0x%p\n", ModeNumber, VgaMode); - if (Values == NULL) return FALSE; + if (!VgaSetRegisters(VgaMode)) return FALSE; - /* Write the misc register */ - VgaWritePort(VGA_MISC_WRITE, *(Values++)); - - /* Write the sequencer registers */ - for (i = 0; i < VGA_SEQ_MAX_REG; i++) - { - VgaWritePort(VGA_SEQ_INDEX, i); - VgaWritePort(VGA_SEQ_DATA, *(Values++)); - } - - /* Write the GC registers */ - for (i = 0; i < VGA_GC_MAX_REG; i++) - { - VgaWritePort(VGA_GC_INDEX, i); - VgaWritePort(VGA_GC_DATA, *(Values++)); - } - - /* Write the CRTC registers */ - for (i = 0; i < VGA_CRTC_MAX_REG; i++) - { - VgaWritePort(VGA_CRTC_INDEX, i); - VgaWritePort(VGA_CRTC_DATA, *(Values++)); - } - - /* Write the AC registers */ - for (i = 0; i < VGA_AC_MAX_REG; i++) - { - VgaWritePort(VGA_AC_INDEX, i); - VgaWritePort(VGA_AC_WRITE, *(Values++)); - } + // /* Disable screen and enable palette access */ + // VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + // VgaWritePort(VGA_AC_INDEX, 0x00); if ((ModeNumber == 0x0D) || (ModeNumber == 0x0E) || (ModeNumber == 0x10)) { /* EGA modes */ - for (i = 0; i < VGA_MAX_COLORS / 4; i++) + extern CONST COLORREF EgaPalette[VGA_MAX_COLORS / 4]; + for (i = 0; i < sizeof(EgaPalette)/sizeof(EgaPalette[0]); i++) { VgaWritePort(VGA_DAC_WRITE_INDEX, i); VgaWritePort(VGA_DAC_DATA, VGA_COLOR_TO_DAC(GetRValue(EgaPalette[i]))); @@ -453,6 +498,13 @@ BOOLEAN BiosSetVideoMode(BYTE ModeNumber) VgaResetPalette(); } + // /* Enable screen and disable palette access */ + // VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + // VgaWritePort(VGA_AC_INDEX, 0x20); + + // Bda->CrtModeControl; + // Bda->CrtColorPaletteMask; + /* Update the values in the BDA */ Bda->VideoMode = ModeNumber; Bda->VideoPage = 0; @@ -506,6 +558,7 @@ BOOLEAN BiosInitialize(VOID) Bda->MemorySize = 0x0280; Bda->KeybdBufferStart = FIELD_OFFSET(BIOS_DATA_AREA, KeybdBuffer); Bda->KeybdBufferEnd = Bda->KeybdBufferStart + BIOS_KBD_BUFFER_SIZE * sizeof(WORD); + Bda->KeybdBufferHead = Bda->KeybdBufferTail = 0; /* Initialize the 32-bit Interrupt system */ InitializeInt32(BIOS_SEGMENT); @@ -641,16 +694,16 @@ WORD BiosGetCharacter(VOID) WORD CharacterData = 0; /* Check if there is a key available */ - if (Bda->KeybdBufferHead != Bda->KeybdBufferTail) + if (BiosKbdBufferTop(&CharacterData)) { - /* Get the key from the queue, and remove it */ - BiosKbdBufferTop(&CharacterData); + /* A key was available, remove it from the queue */ BiosKbdBufferPop(); } else { - /* Set the handler CF to repeat the BOP */ + /* No key available. Set the handler CF to repeat the BOP */ EmulatorSetFlag(EMULATOR_FLAG_CF); + // CharacterData = 0xFFFF; } return CharacterData; @@ -1019,10 +1072,8 @@ VOID WINAPI BiosVideoService(LPWORD Stack) /* Set Single Palette Register */ case 0x00: { - /* Reset the flip-flop */ - VgaReadPort(VGA_STAT_COLOR); - /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state VgaWritePort(VGA_AC_INDEX, getBL()); /* Write the data */ @@ -1034,10 +1085,8 @@ VOID WINAPI BiosVideoService(LPWORD Stack) /* Set Overscan Color */ case 0x01: { - /* Reset the flip-flop */ - VgaReadPort(VGA_STAT_COLOR); - /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); /* Write the data */ @@ -1055,10 +1104,8 @@ VOID WINAPI BiosVideoService(LPWORD Stack) /* Set the palette registers */ for (i = 0; i <= VGA_AC_PAL_F_REG; i++) { - /* Reset the flip-flop */ - VgaReadPort(VGA_STAT_COLOR); - /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state VgaWritePort(VGA_AC_INDEX, i); /* Write the data */ @@ -1075,10 +1122,8 @@ VOID WINAPI BiosVideoService(LPWORD Stack) /* Get Single Palette Register */ case 0x07: { - /* Reset the flip-flop */ - VgaReadPort(VGA_STAT_COLOR); - /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state VgaWritePort(VGA_AC_INDEX, getBL()); /* Read the data */ @@ -1090,10 +1135,8 @@ VOID WINAPI BiosVideoService(LPWORD Stack) /* Get Overscan Color */ case 0x08: { - /* Reset the flip-flop */ - VgaReadPort(VGA_STAT_COLOR); - /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); /* Read the data */ @@ -1111,10 +1154,8 @@ VOID WINAPI BiosVideoService(LPWORD Stack) /* Get the palette registers */ for (i = 0; i <= VGA_AC_PAL_F_REG; i++) { - /* Reset the flip-flop */ - VgaReadPort(VGA_STAT_COLOR); - /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state VgaWritePort(VGA_AC_INDEX, i); /* Read the data */ diff --git a/subsystems/ntvdm/io.c b/subsystems/ntvdm/io.c index 7ce0cbf29af..cadab31e610 100644 --- a/subsystems/ntvdm/io.c +++ b/subsystems/ntvdm/io.c @@ -36,12 +36,18 @@ VOID WINAPI RegisterIoPort(ULONG Port, if (IoPortProc[Port].In == NULL) IoPortProc[Port].In = InHandler; else - DPRINT1("IoPortProc[%d].In already registered\n", Port); + DPRINT1("IoPortProc[0x%X].In already registered\n", Port); if (IoPortProc[Port].Out == NULL) IoPortProc[Port].Out = OutHandler; else - DPRINT1("IoPortProc[%d].Out already registered\n", Port); + DPRINT1("IoPortProc[0x%X].Out already registered\n", Port); +} + +VOID WINAPI UnregisterIoPort(ULONG Port) +{ + IoPortProc[Port].In = NULL; + IoPortProc[Port].Out = NULL; } VOID WINAPI diff --git a/subsystems/ntvdm/io.h b/subsystems/ntvdm/io.h index 115b91005e0..bc1e3120404 100644 --- a/subsystems/ntvdm/io.h +++ b/subsystems/ntvdm/io.h @@ -23,6 +23,8 @@ VOID WINAPI RegisterIoPort(ULONG Port, EMULATOR_IN_PROC InHandler, EMULATOR_OUT_PROC OutHandler); +VOID WINAPI UnregisterIoPort(ULONG Port); + VOID WINAPI EmulatorReadIo ( PFAST486_STATE State, @@ -41,7 +43,6 @@ VOID WINAPI EmulatorWriteIo UCHAR DataSize ); - #endif // _IO_H_ /* EOF */ diff --git a/subsystems/ntvdm/vga.c b/subsystems/ntvdm/vga.c index 8d16ae3bdf3..f6d91ab003b 100644 --- a/subsystems/ntvdm/vga.c +++ b/subsystems/ntvdm/vga.c @@ -21,6 +21,27 @@ static CONST DWORD MemoryBase[] = { 0xA0000, 0xA0000, 0xB0000, 0xB8000 }; static CONST DWORD MemoryLimit[] = { 0xAFFFF, 0xAFFFF, 0xB7FFF, 0xBFFFF }; + +/*static*/ CONST COLORREF EgaPalette[VGA_MAX_COLORS / 4] = +{ + RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA), + RGB(0xAA, 0x00, 0x00), RGB(0xAA, 0x00, 0xAA), RGB(0xAA, 0xAA, 0x00), RGB(0xAA, 0xAA, 0xAA), + RGB(0x00, 0x00, 0x55), RGB(0x00, 0x00, 0xFF), RGB(0x00, 0xAA, 0x55), RGB(0x00, 0xAA, 0xFF), + RGB(0xAA, 0x00, 0x55), RGB(0xAA, 0x00, 0xFF), RGB(0xAA, 0xAA, 0x55), RGB(0xAA, 0xAA, 0xFF), + RGB(0x00, 0x55, 0x00), RGB(0x00, 0x55, 0xAA), RGB(0x00, 0xFF, 0x00), RGB(0x00, 0xFF, 0xAA), + RGB(0xAA, 0x55, 0x00), RGB(0xAA, 0x55, 0xAA), RGB(0xAA, 0xFF, 0x00), RGB(0xAA, 0xFF, 0xAA), + RGB(0x00, 0x55, 0x55), RGB(0x00, 0x55, 0xFF), RGB(0x00, 0xFF, 0x55), RGB(0x00, 0xFF, 0xFF), + RGB(0xAA, 0x55, 0x55), RGB(0xAA, 0x55, 0xFF), RGB(0xAA, 0xFF, 0x55), RGB(0xAA, 0xFF, 0xFF), + RGB(0x55, 0x00, 0x00), RGB(0x55, 0x00, 0xAA), RGB(0x55, 0xAA, 0x00), RGB(0x55, 0xAA, 0xAA), + RGB(0xFF, 0x00, 0x00), RGB(0xFF, 0x00, 0xAA), RGB(0xFF, 0xAA, 0x00), RGB(0xFF, 0xAA, 0xAA), + RGB(0x55, 0x00, 0x55), RGB(0x55, 0x00, 0xFF), RGB(0x55, 0xAA, 0x55), RGB(0x55, 0xAA, 0xFF), + RGB(0xFF, 0x00, 0x55), RGB(0xFF, 0x00, 0xFF), RGB(0xFF, 0xAA, 0x55), RGB(0xFF, 0xAA, 0xFF), + RGB(0x55, 0x55, 0x00), RGB(0x55, 0x55, 0xAA), RGB(0x55, 0xFF, 0x00), RGB(0x55, 0xFF, 0xAA), + RGB(0xFF, 0x55, 0x00), RGB(0xFF, 0x55, 0xAA), RGB(0xFF, 0xFF, 0x00), RGB(0xFF, 0xFF, 0xAA), + RGB(0x55, 0x55, 0x55), RGB(0x55, 0x55, 0xFF), RGB(0x55, 0xFF, 0x55), RGB(0x55, 0xFF, 0xFF), + RGB(0xFF, 0x55, 0x55), RGB(0xFF, 0x55, 0xFF), RGB(0xFF, 0xFF, 0x55), RGB(0xFF, 0xFF, 0xFF) +}; + static CONST COLORREF VgaDefaultPalette[VGA_MAX_COLORS] = { RGB(0x00, 0x00, 0x00), RGB(0x00, 0x00, 0xAA), RGB(0x00, 0xAA, 0x00), RGB(0x00, 0xAA, 0xAA), @@ -98,21 +119,26 @@ static HPALETTE PaletteHandle = NULL; static BOOLEAN DoubleVision = FALSE; static BYTE VgaLatchRegisters[VGA_NUM_BANKS] = {0, 0, 0, 0}; + static BYTE VgaMiscRegister; +static BYTE VgaFeatureRegister; static BYTE VgaSeqIndex = VGA_SEQ_RESET_REG; static BYTE VgaSeqRegisters[VGA_SEQ_MAX_REG]; -static BYTE VgaGcIndex = VGA_GC_RESET_REG; -static BYTE VgaGcRegisters[VGA_GC_MAX_REG]; - static BYTE VgaCrtcIndex = VGA_CRTC_HORZ_TOTAL_REG; static BYTE VgaCrtcRegisters[VGA_CRTC_MAX_REG]; -static BYTE VgaAcIndex = VGA_AC_PAL_0_REG; +static BYTE VgaGcIndex = VGA_GC_RESET_REG; +static BYTE VgaGcRegisters[VGA_GC_MAX_REG]; + static BOOLEAN VgaAcLatch = FALSE; +static BYTE VgaAcIndex = VGA_AC_PAL_0_REG; static BYTE VgaAcRegisters[VGA_AC_MAX_REG]; +// static VGA_REGISTERS VgaRegisters; + +static BYTE VgaDacMask = 0xFF; static WORD VgaDacIndex = 0; static BOOLEAN VgaDacReadWrite = FALSE; static BYTE VgaDacRegisters[VGA_PALETTE_SIZE]; @@ -210,8 +236,6 @@ static inline DWORD VgaTranslateWriteAddress(DWORD Address) static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane) { BYTE WriteMode = VgaGcRegisters[VGA_GC_MODE_REG] & 3; - BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3; - BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7; BYTE BitMask = VgaGcRegisters[VGA_GC_BITMASK_REG]; if (WriteMode == 1) @@ -223,6 +247,7 @@ static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane) if (WriteMode != 2) { /* Write modes 0 and 3 rotate the data to the right first */ + BYTE RotateCount = VgaGcRegisters[VGA_GC_ROTATE_REG] & 7; Data = LOBYTE(((DWORD)Data >> RotateCount) | ((DWORD)Data << (8 - RotateCount))); } else @@ -247,6 +272,8 @@ static inline BYTE VgaTranslateByteForWriting(BYTE Data, BYTE Plane) if (WriteMode != 3) { /* Write modes 0 and 2 then perform a logical operation on the data and latch */ + BYTE LogicalOperation = (VgaGcRegisters[VGA_GC_ROTATE_REG] >> 3) & 3; + if (LogicalOperation == 1) Data &= VgaLatchRegisters[Plane]; else if (LogicalOperation == 2) Data |= VgaLatchRegisters[Plane]; else if (LogicalOperation == 3) Data ^= VgaLatchRegisters[Plane]; @@ -1028,7 +1055,7 @@ VOID VgaReadMemory(DWORD Address, LPBYTE Buffer, DWORD Size) DPRINT("VgaReadMemory: Address 0x%08X, Size %lu\n", Address, Size); /* Ignore if video RAM access is disabled */ - if (!(VgaMiscRegister & VGA_MISC_RAM_ENABLED)) return; + if ((VgaMiscRegister & VGA_MISC_RAM_ENABLED) == 0) return; /* Loop through each byte */ for (i = 0; i < Size; i++) @@ -1054,7 +1081,7 @@ VOID VgaWriteMemory(DWORD Address, LPBYTE Buffer, DWORD Size) DPRINT("VgaWriteMemory: Address 0x%08X, Size %lu\n", Address, Size); /* Ignore if video RAM access is disabled */ - if (!(VgaMiscRegister & VGA_MISC_RAM_ENABLED)) return; + if ((VgaMiscRegister & VGA_MISC_RAM_ENABLED) == 0) return; /* Also ignore if write access to all planes is disabled */ if ((VgaSeqRegisters[VGA_SEQ_MASK_REG] & 0x0F) == 0x00) return; @@ -1097,81 +1124,18 @@ VOID VgaWriteMemory(DWORD Address, LPBYTE Buffer, DWORD Size) BYTE WINAPI VgaReadPort(ULONG Port) { - DPRINT("VgaReadPort: Port 0x%08X\n", Port); + DPRINT("VgaReadPort: Port 0x%X\n", Port); switch (Port) { - case VGA_AC_INDEX: - { - return VgaAcIndex; - } - - case VGA_AC_READ: - { - return VgaAcRegisters[VgaAcIndex]; - } - - case VGA_SEQ_INDEX: - { - return VgaSeqIndex; - } - - case VGA_SEQ_DATA: - { - return VgaSeqRegisters[VgaSeqIndex]; - } - - case VGA_DAC_READ_INDEX: - { - /* This returns the read/write state */ - return VgaDacReadWrite ? 0 : 3; - } - - case VGA_DAC_WRITE_INDEX: - { - return VgaDacIndex / 3; - } - - case VGA_DAC_DATA: - { - /* Ignore reads in write mode */ - if (!VgaDacReadWrite) - { - BYTE Data = VgaDacRegisters[VgaDacIndex++]; - VgaDacIndex %= VGA_PALETTE_SIZE; - return Data; - } - - break; - } - case VGA_MISC_READ: - { return VgaMiscRegister; - } - case VGA_CRTC_INDEX: - { - return VgaCrtcIndex; - } + case VGA_INSTAT0_READ: + return 0; // Not implemented - case VGA_CRTC_DATA: - { - return VgaCrtcRegisters[VgaCrtcIndex]; - } - - case VGA_GC_INDEX: - { - return VgaGcIndex; - } - - case VGA_GC_DATA: - { - return VgaGcRegisters[VgaGcIndex]; - } - - case VGA_STAT_MONO: - case VGA_STAT_COLOR: + case VGA_INSTAT1_READ_MONO: + case VGA_INSTAT1_READ_COLOR: { BYTE Result = 0; @@ -1189,18 +1153,121 @@ BYTE WINAPI VgaReadPort(ULONG Port) return Result; } + + case VGA_FEATURE_READ: + return VgaFeatureRegister; + + case VGA_AC_INDEX: + return VgaAcIndex; + + case VGA_AC_READ: + return VgaAcRegisters[VgaAcIndex]; + + case VGA_SEQ_INDEX: + return VgaSeqIndex; + + case VGA_SEQ_DATA: + return VgaSeqRegisters[VgaSeqIndex]; + + case VGA_DAC_MASK: + return VgaDacMask; + + case VGA_DAC_READ_INDEX: + /* This returns the read/write state */ + return (VgaDacReadWrite ? 0 : 3); + + case VGA_DAC_WRITE_INDEX: + return (VgaDacIndex / 3); + + case VGA_DAC_DATA: + { + /* Ignore reads in write mode */ + if (!VgaDacReadWrite) + { + BYTE Data = VgaDacRegisters[VgaDacIndex++]; + VgaDacIndex %= VGA_PALETTE_SIZE; + return Data; + } + + break; + } + + case VGA_CRTC_INDEX_MONO: + case VGA_CRTC_INDEX_COLOR: + return VgaCrtcIndex; + + case VGA_CRTC_DATA_MONO: + case VGA_CRTC_DATA_COLOR: + return VgaCrtcRegisters[VgaCrtcIndex]; + + case VGA_GC_INDEX: + return VgaGcIndex; + + case VGA_GC_DATA: + return VgaGcRegisters[VgaGcIndex]; + + default: + DPRINT1("VgaReadPort: Unknown port 0x%X\n", Port); + break; } - + return 0; } VOID WINAPI VgaWritePort(ULONG Port, BYTE Data) { - DPRINT("VgaWritePort: Port 0x%08X, Data 0x%02X\n", Port, Data); + DPRINT("VgaWritePort: Port 0x%X, Data 0x%02X\n", Port, Data); switch (Port) { + case VGA_MISC_WRITE: + { + VgaMiscRegister = Data; + + if (VgaMiscRegister & 0x01) + { + /* Color emulation */ + DPRINT1("Color emulation\n"); + + /* Register the new I/O Ports */ + RegisterIoPort(0x3D4, VgaReadPort, VgaWritePort); // VGA_CRTC_INDEX_COLOR + RegisterIoPort(0x3D5, VgaReadPort, VgaWritePort); // VGA_CRTC_DATA_COLOR + RegisterIoPort(0x3DA, VgaReadPort, VgaWritePort); // VGA_INSTAT1_READ_COLOR, VGA_FEATURE_WRITE_COLOR + + /* Unregister the old ones */ + UnregisterIoPort(0x3B4); // VGA_CRTC_INDEX_MONO + UnregisterIoPort(0x3B5); // VGA_CRTC_DATA_MONO + UnregisterIoPort(0x3BA); // VGA_INSTAT1_READ_MONO, VGA_FEATURE_WRITE_MONO + } + else + { + /* Monochrome emulation */ + DPRINT1("Monochrome emulation\n"); + + /* Register the new I/O Ports */ + RegisterIoPort(0x3B4, VgaReadPort, VgaWritePort); // VGA_CRTC_INDEX_MONO + RegisterIoPort(0x3B5, VgaReadPort, VgaWritePort); // VGA_CRTC_DATA_MONO + RegisterIoPort(0x3BA, VgaReadPort, VgaWritePort); // VGA_INSTAT1_READ_MONO, VGA_FEATURE_WRITE_MONO + + /* Unregister the old ones */ + UnregisterIoPort(0x3D4); // VGA_CRTC_INDEX_COLOR + UnregisterIoPort(0x3D5); // VGA_CRTC_DATA_COLOR + UnregisterIoPort(0x3DA); // VGA_INSTAT1_READ_COLOR, VGA_FEATURE_WRITE_COLOR + } + + // if (VgaMiscRegister & 0x02) { /* Enable RAM access */ } else { /* Disable RAM access */ } + break; + } + + case VGA_FEATURE_WRITE_MONO: + case VGA_FEATURE_WRITE_COLOR: + { + VgaFeatureRegister = Data; + break; + } + case VGA_AC_INDEX: + // case VGA_AC_WRITE: { if (!VgaAcLatch) { @@ -1215,7 +1282,6 @@ VOID WINAPI VgaWritePort(ULONG Port, BYTE Data) /* Toggle the latch */ VgaAcLatch = !VgaAcLatch; - break; } @@ -1233,6 +1299,12 @@ VOID WINAPI VgaWritePort(ULONG Port, BYTE Data) break; } + case VGA_DAC_MASK: + { + VgaDacMask = Data; + break; + } + case VGA_DAC_READ_INDEX: { VgaDacReadWrite = FALSE; @@ -1254,20 +1326,16 @@ VOID WINAPI VgaWritePort(ULONG Port, BYTE Data) break; } - case VGA_MISC_WRITE: - { - VgaMiscRegister = Data; - break; - } - - case VGA_CRTC_INDEX: + case VGA_CRTC_INDEX_MONO: + case VGA_CRTC_INDEX_COLOR: { /* Set the CRTC index register */ if (Data < VGA_CRTC_MAX_REG) VgaCrtcIndex = Data; break; } - case VGA_CRTC_DATA: + case VGA_CRTC_DATA_MONO: + case VGA_CRTC_DATA_COLOR: { /* Call the CRTC function */ VgaWriteCrtc(Data); @@ -1287,6 +1355,10 @@ VOID WINAPI VgaWritePort(ULONG Port, BYTE Data) VgaWriteGc(Data); break; } + + default: + DPRINT1("VgaWritePort: Unknown port 0x%X\n", Port); + break; } } @@ -1324,6 +1396,21 @@ BOOLEAN VgaInitialize(HANDLE TextHandle) /* Set the global handle */ TextConsoleBuffer = TextHandle; + /* Register the I/O Ports */ + RegisterIoPort(0x3CC, VgaReadPort, NULL); // VGA_MISC_READ + RegisterIoPort(0x3C2, VgaReadPort, VgaWritePort); // VGA_MISC_WRITE, VGA_INSTAT0_READ + RegisterIoPort(0x3CA, VgaReadPort, NULL); // VGA_FEATURE_READ + RegisterIoPort(0x3C0, VgaReadPort, VgaWritePort); // VGA_AC_INDEX, VGA_AC_WRITE + RegisterIoPort(0x3C1, VgaReadPort, NULL); // VGA_AC_READ + RegisterIoPort(0x3C4, VgaReadPort, VgaWritePort); // VGA_SEQ_INDEX + RegisterIoPort(0x3C5, VgaReadPort, VgaWritePort); // VGA_SEQ_DATA + RegisterIoPort(0x3C6, VgaReadPort, VgaWritePort); // VGA_DAC_MASK + RegisterIoPort(0x3C7, VgaReadPort, VgaWritePort); // VGA_DAC_READ_INDEX + RegisterIoPort(0x3C8, VgaReadPort, VgaWritePort); // VGA_DAC_WRITE_INDEX + RegisterIoPort(0x3C9, VgaReadPort, VgaWritePort); // VGA_DAC_DATA + RegisterIoPort(0x3CE, VgaReadPort, VgaWritePort); // VGA_GC_INDEX + RegisterIoPort(0x3CF, VgaReadPort, VgaWritePort); // VGA_GC_DATA + /* Clear the VGA memory */ VgaClearMemory(); @@ -1366,23 +1453,6 @@ BOOLEAN VgaInitialize(HANDLE TextHandle) Address += ScanlineSize; } - /* Register the I/O Ports */ - RegisterIoPort(VGA_AC_WRITE , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_AC_READ , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_SEQ_INDEX, VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_SEQ_DATA , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_DAC_READ_INDEX , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_DAC_WRITE_INDEX, VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_DAC_DATA , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_MISC_READ , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_MISC_WRITE, VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_CRTC_INDEX, VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_CRTC_DATA , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_GC_INDEX, VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_GC_DATA , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_STAT_MONO , VgaReadPort, VgaWritePort); - RegisterIoPort(VGA_STAT_COLOR, VgaReadPort, VgaWritePort); - /* Return success */ return TRUE; } diff --git a/subsystems/ntvdm/vga.h b/subsystems/ntvdm/vga.h index a89895e6f81..7b9fc2fcfae 100644 --- a/subsystems/ntvdm/vga.h +++ b/subsystems/ntvdm/vga.h @@ -15,24 +15,6 @@ /* DEFINES ********************************************************************/ -/* Register I/O ports */ -#define VGA_AC_INDEX 0x3C0 -#define VGA_AC_WRITE 0x3C0 -#define VGA_AC_READ 0x3C1 -#define VGA_SEQ_INDEX 0x3C4 -#define VGA_SEQ_DATA 0x3C5 -#define VGA_DAC_READ_INDEX 0x3C7 -#define VGA_DAC_WRITE_INDEX 0x3C8 -#define VGA_DAC_DATA 0x3C9 -#define VGA_MISC_READ 0x3CC -#define VGA_MISC_WRITE 0x3C2 -#define VGA_CRTC_INDEX 0x3D4 -#define VGA_CRTC_DATA 0x3D5 -#define VGA_GC_INDEX 0x3CE -#define VGA_GC_DATA 0x3CF -#define VGA_STAT_MONO 0x3BA -#define VGA_STAT_COLOR 0x3DA - #define VGA_NUM_BANKS 4 #define VGA_BANK_SIZE 0x10000 #define VGA_MAX_COLORS 256 @@ -43,72 +25,81 @@ #define VGA_DAC_TO_COLOR(x) (((x) << 2) | ((x) >> 6)) #define VGA_COLOR_TO_DAC(x) ((x) >> 2) -/* Sequencer reset register bits */ -#define VGA_SEQ_RESET_AR (1 << 0) -#define VGA_SEQ_RESET_SR (1 << 1) -/* Sequencer clock register bits */ -#define VGA_SEQ_CLOCK_98DM (1 << 0) -#define VGA_SEQ_CLOCK_SLR (1 << 2) -#define VGA_SEQ_CLOCK_DCR (1 << 3) -#define VGA_SEQ_CLOCK_S4 (1 << 4) -#define VGA_SEQ_CLOCK_SD (1 << 5) -/* Sequencer memory register bits */ -#define VGA_SEQ_MEM_EXT (1 << 1) -#define VGA_SEQ_MEM_OE (1 << 2) -#define VGA_SEQ_MEM_C4 (1 << 3) +/* Register I/O ports */ -/* Graphics controller mode register bits */ -#define VGA_GC_MODE_READ (1 << 3) -#define VGA_GC_MODE_OE (1 << 4) -#define VGA_GC_MODE_SHIFTREG (1 << 5) -#define VGA_GC_MODE_SHIFT256 (1 << 6) +#define VGA_MISC_READ 0x3CC +#define VGA_MISC_WRITE 0x3C2 -/* Graphics controller miscellaneous register bits */ -#define VGA_GC_MISC_NOALPHA (1 << 0) -#define VGA_GC_MISC_OE (1 << 1) +#define VGA_INSTAT0_READ 0x3C2 -/* CRTC overflow register bits */ -#define VGA_CRTC_OVERFLOW_VT8 (1 << 0) -#define VGA_CRTC_OVERFLOW_VDE8 (1 << 1) -#define VGA_CRTC_OVERFLOW_VRS8 (1 << 2) -#define VGA_CRTC_OVERFLOW_SVB8 (1 << 3) -#define VGA_CRTC_OVERFLOW_LC8 (1 << 4) -#define VGA_CRTC_OVERFLOW_VT9 (1 << 5) -#define VGA_CRTC_OVERFLOW_VDE9 (1 << 6) -#define VGA_CRTC_OVERFLOW_VRS9 (1 << 7) +#define VGA_INSTAT1_READ_MONO 0x3BA +#define VGA_INSTAT1_READ_COLOR 0x3DA -/* CRTC underline register bits */ -#define VGA_CRTC_UNDERLINE_DWORD (1 << 6) +#define VGA_FEATURE_READ 0x3CA +#define VGA_FEATURE_WRITE_MONO 0x3BA +#define VGA_FEATURE_WRITE_COLOR 0x3DA -/* CRTC max scanline register bits */ -#define VGA_CRTC_MAXSCANLINE_DOUBLE (1 << 7) +#define VGA_AC_INDEX 0x3C0 +#define VGA_AC_WRITE 0x3C0 +#define VGA_AC_READ 0x3C1 -/* CRTC mode control register bits */ -#define VGA_CRTC_MODE_CONTROL_WRAP (1 << 5) -#define VGA_CRTC_MODE_CONTROL_BYTE (1 << 6) -#define VGA_CRTC_MODE_CONTROL_SYNC (1 << 7) +#define VGA_SEQ_INDEX 0x3C4 +#define VGA_SEQ_DATA 0x3C5 -/* AC control register bits */ -#define VGA_AC_CONTROL_ATGE (1 << 0) -#define VGA_AC_CONTROL_MONO (1 << 1) -#define VGA_AC_CONTROL_LGE (1 << 2) -#define VGA_AC_CONTROL_BLINK (1 << 3) -#define VGA_AC_CONTROL_PPM (1 << 5) -#define VGA_AC_CONTROL_8BIT (1 << 6) -#define VGA_AC_CONTROL_P54S (1 << 7) +#define VGA_DAC_MASK 0x3C6 +#define VGA_DAC_READ_INDEX 0x3C7 +#define VGA_DAC_WRITE_INDEX 0x3C8 +#define VGA_DAC_DATA 0x3C9 + +#define VGA_CRTC_INDEX_MONO 0x3B4 +#define VGA_CRTC_DATA_MONO 0x3B5 +#define VGA_CRTC_INDEX_COLOR 0x3D4 +#define VGA_CRTC_DATA_COLOR 0x3D5 + +#define VGA_GC_INDEX 0x3CE +#define VGA_GC_DATA 0x3CF + + + +// +// Miscellaneous and Status Registers +// /* Miscellaneous register bits */ -#define VGA_MISC_COLOR (1 << 0) -#define VGA_MISC_RAM_ENABLED (1 << 1) -#define VGA_MISC_OE_INVERT (1 << 5) -#define VGA_MISC_HSYNCP (1 << 6) -#define VGA_MISC_VSYNCP (1 << 7) +#define VGA_MISC_COLOR (1 << 0) +#define VGA_MISC_RAM_ENABLED (1 << 1) +// #define VGA_MISC_CSEL1 (1 << 2) +// #define VGA_MISC_CSEL2 (1 << 3) +#define VGA_MISC_OE_INVERT (1 << 5) +#define VGA_MISC_HSYNCP (1 << 6) +#define VGA_MISC_VSYNCP (1 << 7) /* Status register flags */ -#define VGA_STAT_DD (1 << 0) -#define VGA_STAT_VRETRACE (1 << 3) +#define VGA_STAT_DD (1 << 0) +#define VGA_STAT_VRETRACE (1 << 3) + + +// +// Sequencer Registers +// + +/* Sequencer reset register bits */ +#define VGA_SEQ_RESET_AR (1 << 0) +#define VGA_SEQ_RESET_SR (1 << 1) + +/* Sequencer clock register bits */ +#define VGA_SEQ_CLOCK_98DM (1 << 0) +#define VGA_SEQ_CLOCK_SLR (1 << 2) +#define VGA_SEQ_CLOCK_DCR (1 << 3) +#define VGA_SEQ_CLOCK_S4 (1 << 4) +#define VGA_SEQ_CLOCK_SD (1 << 5) + +/* Sequencer memory register bits */ +#define VGA_SEQ_MEM_EXT (1 << 1) +#define VGA_SEQ_MEM_OE (1 << 2) +#define VGA_SEQ_MEM_C4 (1 << 3) enum { @@ -120,19 +111,31 @@ enum VGA_SEQ_MAX_REG }; -enum -{ - VGA_GC_RESET_REG, - VGA_GC_ENABLE_RESET_REG, - VGA_GC_COLOR_COMPARE_REG, - VGA_GC_ROTATE_REG, - VGA_GC_READ_MAP_SEL_REG, - VGA_GC_MODE_REG, - VGA_GC_MISC_REG, - VGA_GC_COLOR_IGNORE_REG, - VGA_GC_BITMASK_REG, - VGA_GC_MAX_REG -}; + +// +// CRT Controller Registers +// + +/* CRTC overflow register bits */ +#define VGA_CRTC_OVERFLOW_VT8 (1 << 0) +#define VGA_CRTC_OVERFLOW_VDE8 (1 << 1) +#define VGA_CRTC_OVERFLOW_VRS8 (1 << 2) +#define VGA_CRTC_OVERFLOW_SVB8 (1 << 3) +#define VGA_CRTC_OVERFLOW_LC8 (1 << 4) +#define VGA_CRTC_OVERFLOW_VT9 (1 << 5) +#define VGA_CRTC_OVERFLOW_VDE9 (1 << 6) +#define VGA_CRTC_OVERFLOW_VRS9 (1 << 7) + +/* CRTC underline register bits */ +#define VGA_CRTC_UNDERLINE_DWORD (1 << 6) + +/* CRTC max scanline register bits */ +#define VGA_CRTC_MAXSCANLINE_DOUBLE (1 << 7) + +/* CRTC mode control register bits */ +#define VGA_CRTC_MODE_CONTROL_WRAP (1 << 5) +#define VGA_CRTC_MODE_CONTROL_BYTE (1 << 6) +#define VGA_CRTC_MODE_CONTROL_SYNC (1 << 7) enum { @@ -164,6 +167,50 @@ enum VGA_CRTC_MAX_REG }; + +// +// Graphics Controller Registers +// + +/* Graphics controller mode register bits */ +#define VGA_GC_MODE_READ (1 << 3) +#define VGA_GC_MODE_OE (1 << 4) +#define VGA_GC_MODE_SHIFTREG (1 << 5) +#define VGA_GC_MODE_SHIFT256 (1 << 6) + +/* Graphics controller miscellaneous register bits */ +#define VGA_GC_MISC_NOALPHA (1 << 0) +#define VGA_GC_MISC_OE (1 << 1) + +enum +{ + VGA_GC_RESET_REG, + VGA_GC_ENABLE_RESET_REG, + VGA_GC_COLOR_COMPARE_REG, + VGA_GC_ROTATE_REG, + VGA_GC_READ_MAP_SEL_REG, + VGA_GC_MODE_REG, + VGA_GC_MISC_REG, + VGA_GC_COLOR_IGNORE_REG, + VGA_GC_BITMASK_REG, + VGA_GC_MAX_REG +}; + + +// +// Attribute Controller Registers +// They are a relinquish of the CGA/EGA era. +// + +/* AC mode control register bits */ +#define VGA_AC_CONTROL_ATGE (1 << 0) +#define VGA_AC_CONTROL_MONO (1 << 1) +#define VGA_AC_CONTROL_LGE (1 << 2) +#define VGA_AC_CONTROL_BLINK (1 << 3) +#define VGA_AC_CONTROL_PPM (1 << 5) +#define VGA_AC_CONTROL_8BIT (1 << 6) +#define VGA_AC_CONTROL_P54S (1 << 7) + enum { VGA_AC_PAL_0_REG, @@ -190,6 +237,17 @@ enum VGA_AC_MAX_REG }; + +typedef struct _VGA_REGISTERS +{ + UCHAR Misc; + UCHAR Sequencer[VGA_SEQ_MAX_REG]; + UCHAR CRT[VGA_CRTC_MAX_REG]; + UCHAR Graphics[VGA_GC_MAX_REG]; + UCHAR Attribute[VGA_AC_MAX_REG]; +} VGA_REGISTERS, *PVGA_REGISTERS; + + /* FUNCTIONS ******************************************************************/ DWORD VgaGetVideoBaseAddress(VOID);