summaryrefslogtreecommitdiffstats
path: root/private/mvdm/softpc.new/host/src/nt_fulsc.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/mvdm/softpc.new/host/src/nt_fulsc.c2415
1 files changed, 2415 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/host/src/nt_fulsc.c b/private/mvdm/softpc.new/host/src/nt_fulsc.c
new file mode 100644
index 000000000..1fbe4ced0
--- /dev/null
+++ b/private/mvdm/softpc.new/host/src/nt_fulsc.c
@@ -0,0 +1,2415 @@
+#include <windows.h>
+#include "host_def.h"
+#include "insignia.h"
+
+/*
+ * ==========================================================================
+ * Name: nt_fulsc.c
+ * Author: Jerry Sexton
+ * Derived From:
+ * Created On: 27th January 1992
+ * Purpose: This module contains the code required to handle
+ * transitions between graphics and text modes, and
+ * windowed and full-screen displays for SoftPC running
+ * under the x86 monitor.
+ *
+ * (c)Copyright Insignia Solutions Ltd., 1992. All rights reserved.
+ * ==========================================================================
+ */
+
+/*
+ * ==========================================================================
+ * Other Includes
+ * ==========================================================================
+ */
+#ifdef X86GFX
+#include <ntddvdeo.h>
+#endif
+#include <vdm.h>
+#include <stdlib.h>
+#include <string.h>
+#include "conapi.h"
+
+#include "xt.h"
+#include CpuH
+#include "gvi.h"
+#include "gmi.h"
+#include "gfx_upd.h"
+#include "video.h"
+#include "egacpu.h"
+#include "egavideo.h"
+#include "egagraph.h"
+#include "egaports.h"
+#include "egamode.h"
+#include "ckmalloc.h"
+#include "sas.h"
+#include "ica.h"
+#include "ios.h"
+#include "config.h"
+#include "idetect.h"
+#include "debug.h"
+
+#include "nt_thred.h"
+#include "nt_fulsc.h"
+#include "nt_graph.h"
+#include "nt_uis.h"
+#include "host_rrr.h"
+#include "nt_det.h"
+#include "nt_mouse.h"
+#include "nt_event.h"
+#include "ntcheese.h"
+#include "nt_eoi.h"
+#include "nt_reset.h"
+
+/*
+ * ==========================================================================
+ * Global Data
+ * ==========================================================================
+ */
+GLOBAL BOOL ConsoleInitialised = FALSE;
+GLOBAL BOOL ConsoleNoUpdates = FALSE;
+#ifdef X86GFX
+GLOBAL BOOL BiosModeChange = FALSE;
+GLOBAL DWORD mouse_buffer_width = 0,
+ mouse_buffer_height = 0;
+#endif /* X86GFX */
+GLOBAL BOOL blocked_in_gfx_mode = FALSE; /* need to force text mode? */
+#ifndef PROD
+GLOBAL UTINY FullScreenDebug = FALSE;
+#endif /* PROD */
+
+/* We have to prevent bad values from oddball video cards (eg Prodesigner II
+ * EISA) from blatting us before we can load our private baby mode table in
+ * ntio.sys. We have to keep another copy to be copied into memory to prevent
+ * this. We should only need modes 3 & b.
+ */
+GLOBAL UTINY tempbabymode[] =
+/* 80x25 stuff */
+ {
+ 0x50, 0x18, 0x10, 0x00, 0x10, 0x00, 0x03, 0x00, 0x02, 0x67,
+ 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, 0x00, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+ 0x3f, 0x0c, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x0e, 0x00, 0xff,
+/* mode b stuff */
+ 0x5e, 0x32, 0x08, 0x00, 0x97, 0x01, 0x0f, 0x00, 0x06, 0xe7,
+ 0x6d, 0x5d, 0x5e, 0x90, 0x61, 0x8f, 0xbf, 0x1f, 0x00, 0x40,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x8e, 0x99, 0x2f,
+ 0x00, 0xa1, 0xb9, 0xe3, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
+ 0x3f, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x05, 0x0f, 0xff
+};
+
+/*
+ * ==========================================================================
+ * Local Data
+ * ==========================================================================
+ */
+
+/* The resolution and font-size at start-up. */
+LOCAL COORD startUpResolution;
+LOCAL COORD startUpFontSize;
+
+/* General purpose console buffer. */
+LOCAL CHAR_INFO consoleBuffer[MAX_CONSOLE_SIZE];
+
+LOCAL BOOL WinFrozen = FALSE;
+
+/* Console info from startup which is needed for synchronisation */
+LOCAL int ConVGAHeight;
+LOCAL int ConTopLine;
+
+/* saved information for console re-integration */
+LOCAL CONSOLE_SCREEN_BUFFER_INFO ConsBufferInfo;
+LOCAL StartupCharHeight;
+
+LOCAL half_word saved_text_lines; /* No of lines for last SelectMouseBuffer. */
+
+
+/* Variable to check for changes in screen state. */
+GLOBAL DWORD savedScreenState;
+BOOL nt_init_called = 0;
+
+IMPORT CONSOLE_CURSOR_INFO StartupCursor;
+
+IMPORT void low_set_mode(int);
+IMPORT VOID recalc_text(int);
+IMPORT VOID enable_gfx_update_routines(VOID);
+IMPORT VOID disable_gfx_update_routines(VOID);
+#ifdef X86GFX
+IMPORT void vga_misc_inb(io_addr, half_word *);
+#endif /* X86GFX */
+
+
+/*
+ * ==========================================================================
+ * Local Function Declarations
+ * ==========================================================================
+ */
+VOID enableUpdates(VOID);
+VOID disableUpdates(VOID);
+VOID copyConsoleToRegen(SHORT, SHORT, SHORT, SHORT);
+VOID getVDMCursorPosition(VOID);
+VOID setVDMCursorPosition(UTINY, PCOORD);
+VOID waitForInputFocus(VOID);
+GLOBAL int getModeType(VOID);
+#ifdef X86GFX
+VOID AddTempIVTFixups(VOID);
+VOID GfxReset(VOID);
+#endif /* X86GFX */
+
+/*
+ * ==========================================================================
+ * Global Functions
+ * ==========================================================================
+ */
+
+GLOBAL VOID nt_init_event_thread(VOID)
+{
+ note_entrance0("nt_init_event_thread");
+
+ /*
+ * May be called more than once, if event thread enters
+ * resume\block code before normally intialized
+ */
+ if (nt_init_called)
+ return;
+ else
+ nt_init_called++;
+
+
+ if (sc.ScreenState != STREAM_IO) {
+ /*
+ ** Copy the console buffer to the regen buffer.
+ ** Don't want to adjust the copy from top of console window, console
+ ** does it itself if we resize the window. Tim September 92.
+ */
+ copyConsoleToRegen(0, 0, VGA_WIDTH, (SHORT)ConVGAHeight);
+
+ /*
+ ** Tim September 92, adjust cursor position if console window size is
+ ** adjusted.
+ */
+ ConsBufferInfo.dwCursorPosition.Y -= ConTopLine;
+
+ /* Set up SoftPC's cursor. */
+ setVDMCursorPosition((UTINY)StartupCharHeight,
+ &ConsBufferInfo.dwCursorPosition);
+
+ if (sc.ScreenState == WINDOWED)
+ enableUpdates();
+ }
+ else
+ enableUpdates();
+
+ // set kbd state flags in biosdata area, according to the real kbd Leds
+ if (!VDMForWOW) {
+ SyncBiosKbdLedToKbdDevice();
+ // we have sync up the BIOS led states with the system, we now let the
+ // event thread go
+ ResumeThread(ThreadInfo.EventMgr.Handle);
+ }
+
+ KbdResume(); // JonLe Mod
+}
+
+
+#ifdef X86GFX
+/*
+* Find the address of the ROM font, load it up into the correct
+* portion of the regen area and set Int 43 to point to it.
+*
+* Size of font we are loading is known, so don't listen to what
+* the native BIOS returns to us in CX. BIOS might be returning
+* character height we set in recalc_text() above. Tim Oct 92.
+*/
+
+NativeFontAddr nativeFontAddresses[6]; /* pointers to native BIOS ROM fonts */
+ /* 8x14, 8x8 pt1, 8x8 pt2, 9x14, 8x16 and 9x16 */
+
+
+#define GET_BIOS_FONT_ADDRESS(FontIndex) \
+ (((sys_addr)nativeFontAddresses[FontIndex].seg << 4) + \
+ (sys_addr)nativeFontAddresses[FontIndex].off)
+
+/*
+*****************************************************************************
+** locateNativeBIOSfonts() X86 only.
+*****************************************************************************
+** Get the addresses of the BIOS ROM fonts. (Insignia video ROM not loaded)
+** ntdetect.com runs the INT 10 to look the addresses up on system boot and
+** stores them in page 0 at 700.
+** This function is called once on startup X86 only. It gets the addresses of
+** the native ROM fonts and stores them in the nativeFontAddresses[] array.
+*/
+VOID locateNativeBIOSfonts IFN0()
+{
+ int i;
+ sys_addr font_off = 0x700; /* Magic place used by ntdetect.com */
+
+ for(i = 0; i < 6; i++)
+ {
+ sas_loadw(font_off, &nativeFontAddresses[i].off);
+ sas_loadw(font_off+2, &nativeFontAddresses[i].seg);
+ font_off += 4;
+ }
+} /* end of locateNativeBIOSfonts() */
+
+/*
+****************************************************************************
+** loadNativeBIOSfont() X86 only.
+****************************************************************************
+** Loads the appropriate font, specified by current window size, into the
+** font area in video RAM.
+** This function is called on every windowed startup and resume. *Never* on
+** a full-screen startup or resume. The font is loaded so that it will be
+** available for full-screen text mode, but easier to load when windowed.
+** Remember a mode change will load the corect font.
+*/
+VOID loadNativeBIOSfont IFN1( int, vgaHeight )
+{
+ sys_addr fontadd; // location of font
+ UTINY *regenptr; // destination in video
+ int cellsize; // individual character size
+ int skip; // gap between characters
+ int loop, pool;
+ UINT OutputCP;
+
+
+ /*
+ ** ordered this way as 80x50 console is default
+ ** VGA_HEIGHT_4 = 50
+ ** VGA_HEIGHT_3 = 43
+ ** VGA_HEIGHT_2 = 28
+ ** VGA_HEIGHT_1 = 25
+ ** VGA_HEIGHT_0 = 22
+ */
+ if (vgaHeight == VGA_HEIGHT_4 || vgaHeight == VGA_HEIGHT_3){
+ cellsize = 8;
+ fontadd = GET_BIOS_FONT_ADDRESS(F8x8pt1);
+ }else
+ if (vgaHeight == VGA_HEIGHT_2){
+ cellsize = 14;
+ fontadd = GET_BIOS_FONT_ADDRESS(F8x14);
+ }else{
+ cellsize = 16;
+ fontadd = GET_BIOS_FONT_ADDRESS(F8x16);
+ }
+
+ // set Int 43 to point to font
+ sas_storew(0x43 * 4, (word)(fontadd & 0xffff));
+ sas_storew(0x43 * 4 + 2, (word)(fontadd >> 4 & 0xf000));
+
+/* BUGBUG, williamh
+ We should have set int43 to the new font read from the CPI font.
+ This would require at least 4KB buffer in real mode address space.
+ The question is who is going to use this vector? So far, we haven't found
+ any applications use the vector(ROM BIOS is okay because the set video mode
+ function will reset the font and our new font will be lost anyway).
+
+*/
+
+ if (!sc.Registered || (OutputCP = GetConsoleOutputCP()) == 437 ||
+ !LoadCPIFont(OutputCP, (WORD)8, (WORD)cellsize)) {
+ // now load it into the regen memory. We load it in at a0000 where
+ // an app will have to get to it. Luckily, this means we don't
+ // conflict with the text on the screen
+
+ skip = 32 - cellsize;
+
+ regenptr = (half_word *)0xa0000;
+
+ if (cellsize == 8) /* 8x8 font comes in two halves */
+ {
+ for (loop = 0; loop < 128; loop++)
+ {
+ for (pool = 0; pool < cellsize; pool++)
+ *regenptr++ = *(UTINY *)fontadd++;
+ regenptr += skip;
+ }
+ fontadd = GET_BIOS_FONT_ADDRESS(F8x8pt2);
+ for (loop = 0; loop < 128; loop++)
+ {
+ for (pool = 0; pool < cellsize; pool++)
+ *regenptr++ = *(UTINY *)fontadd++;
+ regenptr += skip;
+ }
+ }
+ else
+ {
+ for (loop = 0; loop < 256; loop++)
+ {
+ for (pool = 0; pool < cellsize; pool++)
+ *regenptr++ = *(UTINY *)fontadd++;
+ regenptr += skip;
+ }
+ }
+ }
+} /* end of loadNativeBIOSfont() */
+
+/* this function loads font data from EGA.CPI file located at %systemroot%\system32.
+ It is the same file console server used to load ROM font when the video
+ is in full screen. This function covers code page 437(ROM default). However,
+ the caller should make its best decision to call this function if the
+ output code page is not 437. This function doesn't care what code page
+ was provided.
+ The font size are limitted to(an assumption made by nt video driver and
+ the console server):
+ ** width must be 8 pixels.
+ ** Height must less or equal to 16 pixels.
+
+*/
+
+
+
+BOOL LoadCPIFont(UINT CodePageID, WORD FontWidth, WORD FontHeight)
+{
+ BYTE Buffer[16 * 256];
+ DWORD dw, BytesRead, FilePtr;
+ BYTE *VramAddr, *pSrc;
+ DWORD nChars;
+ PCPIFILEHEADER pCPIFileHeader = (PCPIFILEHEADER)Buffer;
+ PCPICODEPAGEHEADER pCPICodePageHeader = (PCPICODEPAGEHEADER) Buffer;
+ PCPICODEPAGEENTRY pCPICodePageEntry = (PCPICODEPAGEENTRY) Buffer;
+ PCPIFONTHEADER pCPIFontHeader = (PCPIFONTHEADER) Buffer;
+ PCPIFONTDATA pCPIFontData = (PCPIFONTDATA) Buffer;
+ BOOL bDOSCPI = FALSE;
+ HANDLE hCPIFile;
+
+ /* max font height is 16 pixels and font width must be 8 pixels */
+ if (FontHeight > 16 || FontWidth != 8)
+ return FALSE;
+ dw = GetSystemDirectoryA((CHAR *)Buffer, sizeof(Buffer));
+ if (dw == 0 || dw + CPI_FILENAME_LENGTH > sizeof(Buffer))
+ return FALSE;
+ RtlMoveMemory(&Buffer[dw], CPI_FILENAME, CPI_FILENAME_LENGTH);
+ // the file must be opened in READONLY mode or the CreateFileA will fail
+ // because the console sevrer always keeps an opened handle to the file
+ // and the file is opened READONLY.
+
+ hCPIFile = CreateFileA(Buffer, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (hCPIFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ if (!ReadFile(hCPIFile, Buffer, sizeof(CPIFILEHEADER), &BytesRead, NULL) ||
+ BytesRead != sizeof(CPIFILEHEADER)) {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ if (memcmp(pCPIFileHeader->Signature, CPI_SIGNATURE_NT, CPI_SIGNATURE_LENGTH))
+ {
+ if (memcmp(pCPIFileHeader->Signature, CPI_SIGNATURE_DOS,CPI_SIGNATURE_LENGTH))
+ {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ else
+ bDOSCPI = TRUE;
+ }
+
+ // move the file pointer to the code page table header
+ FilePtr = pCPIFileHeader->OffsetToCodePageHeader;
+ if (SetFilePointer(hCPIFile, FilePtr, NULL, FILE_BEGIN) == (DWORD) -1){
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+
+ if (!ReadFile(hCPIFile, Buffer, sizeof(CPICODEPAGEHEADER), &BytesRead, NULL) ||
+ BytesRead != sizeof(CPICODEPAGEHEADER)) {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ // how many code page entries in the file
+ dw = pCPICodePageHeader->NumberOfCodePages;
+ FilePtr += BytesRead;
+
+ // serach for the specific code page
+ while (dw > 0 &&
+ ReadFile(hCPIFile, Buffer, sizeof(CPICODEPAGEENTRY), &BytesRead, NULL) &&
+ BytesRead == sizeof(CPICODEPAGEENTRY)) {
+ if (pCPICodePageEntry->CodePageID == CodePageID)
+ break;
+ if (dw > 1) {
+ if (!bDOSCPI)
+ FilePtr += pCPICodePageEntry->OffsetToNextCodePageEntry;
+ else
+ FilePtr = pCPICodePageEntry->OffsetToNextCodePageEntry;
+
+ if (SetFilePointer(hCPIFile, FilePtr, NULL, FILE_BEGIN) == (DWORD) -1) {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ }
+ dw--;
+ }
+ if (dw == 0) {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ // seek to the font header for the code page
+ if (!bDOSCPI)
+ FilePtr += pCPICodePageEntry->OffsetToFontHeader;
+ else
+ FilePtr = pCPICodePageEntry->OffsetToFontHeader;
+ if (SetFilePointer(hCPIFile, FilePtr, NULL, FILE_BEGIN) == (DWORD) -1) {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ if (!ReadFile(hCPIFile, Buffer, sizeof(CPIFONTHEADER), &BytesRead, NULL) ||
+ BytesRead != sizeof(CPIFONTHEADER)){
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ // number of fonts with the specific code page
+ dw = pCPIFontHeader->NumberOfFonts;
+
+ while(dw != 0 &&
+ ReadFile(hCPIFile, Buffer, sizeof(CPIFONTDATA), &BytesRead, NULL) &&
+ BytesRead == sizeof(CPIFONTDATA))
+ {
+ if (pCPIFontData->FontHeight == FontHeight &&
+ pCPIFontData->FontWidth == FontWidth)
+ {
+ nChars = pCPIFontData->NumberOfCharacters;
+ if (ReadFile(hCPIFile, Buffer, nChars * FontHeight, &BytesRead, NULL) &&
+ BytesRead == nChars * FontHeight)
+ break;
+ else {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ }
+ else {
+ if (SetFilePointer(hCPIFile,
+ (DWORD)pCPIFontData->NumberOfCharacters * (DWORD)pCPIFontData->FontHeight,
+ NULL,
+ FILE_CURRENT) == (DWORD) -1) {
+ CloseHandle(hCPIFile);
+ return FALSE;
+ }
+ dw--;
+ }
+ }
+ if (dw != 0) {
+ VramAddr = (BYTE *)0xa0000;
+ pSrc = Buffer;
+ for(dw = nChars; dw > 0; dw--) {
+ RtlMoveMemory(VramAddr, pSrc, FontHeight);
+ pSrc += FontHeight;
+ // font in VRAM is always 32 bytes
+ VramAddr += 32;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif /* X86GFX */
+
+/*
+***************************************************************************
+** calcScreenParams(), setup our screen screen parameters as determined
+** by current Console state.
+** Called from ConsoleInit() and DoFullScreenResume().
+** Returns current character height (8,14,16) and lines (22-50).
+** Tim Jan 93, extracted common code from init and resume funx.
+***************************************************************************
+*/
+GLOBAL VOID calcScreenParams IFN2( USHORT *, pCharHeight, USHORT *, pVgaHeight )
+{
+ USHORT consoleWidth,
+ consoleHeight,
+ vgaHeight,
+ charHeight,
+ scanLines;
+ half_word temp;
+
+ /* Get console information. */
+ if (!GetConsoleScreenBufferInfo(sc.OutputHandle, &ConsBufferInfo))
+ ErrorExit();
+
+ /* Now sync the SoftPC screen to the console. */
+ if (sc.ScreenState == WINDOWED)
+ {
+ consoleWidth = ConsBufferInfo.srWindow.Right -
+ ConsBufferInfo.srWindow.Left + 1;
+ consoleHeight = ConsBufferInfo.srWindow.Bottom -
+ ConsBufferInfo.srWindow.Top + 1;
+ }
+#ifdef X86GFX
+ else /* FULLSCREEN */
+ {
+ if (!GetConsoleHardwareState(sc.OutputHandle,
+ &startUpResolution,
+ &startUpFontSize))
+ ErrorExit();
+ consoleWidth = startUpResolution.X / startUpFontSize.X;
+ consoleHeight = startUpResolution.Y / startUpFontSize.Y;
+ }
+#endif
+
+ /*
+ * Set the display to the nearest VGA text mode size, which is one of
+ * 80x22, 80x25, 80x28, 80x43 or 80x50.
+ */
+ if (consoleHeight <= MID_VAL(VGA_HEIGHT_0, VGA_HEIGHT_1))
+ {
+ /* 22 lines */
+ vgaHeight = VGA_HEIGHT_0;
+ scanLines = 351;
+ charHeight = 16;
+ }
+ else if (consoleHeight <= MID_VAL(VGA_HEIGHT_1, VGA_HEIGHT_2))
+ {
+ /* 25 lines */
+ vgaHeight = VGA_HEIGHT_1;
+ scanLines = 399;
+ charHeight = 16;
+ }
+ else if (consoleHeight <= MID_VAL(VGA_HEIGHT_2, VGA_HEIGHT_3))
+ {
+ /* 28 lines */
+ vgaHeight = VGA_HEIGHT_2;
+ scanLines = 391;
+ charHeight = 14;
+ }
+ else if (consoleHeight <= MID_VAL(VGA_HEIGHT_3, VGA_HEIGHT_4))
+ {
+ /* 43 lines */
+ vgaHeight = VGA_HEIGHT_3;
+ scanLines = 349;
+ charHeight = 8;
+ }
+ else
+ {
+ /* 50 lines */
+ vgaHeight = VGA_HEIGHT_4;
+ scanLines = 399;
+ charHeight = 8;
+ }
+
+ if (sc.ScreenState == WINDOWED)
+ {
+ /* The app may have shutdown in a gfx mode - force text mode back */
+ if (blocked_in_gfx_mode)
+ {
+ low_set_mode(3);
+ inb(EGA_IPSTAT1_REG,&temp);
+ outb(EGA_AC_INDEX_DATA, EGA_PALETTE_ENABLE); /* re-enable video */
+ (*choose_display_mode)();
+ blocked_in_gfx_mode = FALSE;
+ }
+ /*
+ * Set screen height appropriately for current window size.
+ * Now call video routine to set the character height, updating the
+ * BIOS RAM as it does so.
+ */
+ set_screen_height_recal( scanLines ); /* Tim Oct 92 */
+ recalc_text(charHeight);
+
+ /* badly written apps assume 25 line mode page len is 4096 */
+ if (vgaHeight == 25)
+ sas_storew_no_check(VID_LEN, 0x1000);
+#ifdef X86GFX
+ loadNativeBIOSfont( vgaHeight );
+#endif /* X86GFX */
+
+ }
+#ifdef X86GFX
+ else /* FULLSCREEN */
+ {
+ // Can't see why we wouldn't want this for resume too.
+ // set_char_height( startUpFontSize.Y ); /* Tim Oct 92 */
+
+ /* clear this condition on fullscreen resume */
+ blocked_in_gfx_mode = FALSE;
+
+ /*
+ ** Adjust height appropriately, Tim September 92.
+ ** In full-screen lines is 21 cos 22x16=352, slightly too big.
+ */
+ if( vgaHeight==22 )
+ vgaHeight = 21;
+ charHeight = startUpFontSize.Y;
+ sas_store_no_check(ega_char_height, (half_word) charHeight);
+ sas_store_no_check(vd_rows_on_screen, (half_word) (vgaHeight - 1));
+ /* compatibility with bios 80x25 startup */
+ if (vgaHeight == 25)
+ sas_storew_no_check(VID_LEN, 0x1000);
+ else
+ sas_storew_no_check(VID_LEN, (word) ((vgaHeight + 1) *
+ sas_w_at_no_check(VID_COLS) * 2));
+ }
+#endif /* X86GFX */
+ sas_storew_no_check(VID_COLS, 80); // fixup from 40 char shutdown
+ *pCharHeight = charHeight;
+ *pVgaHeight = vgaHeight;
+
+} /* end of calcScreenParams() */
+
+/***************************************************************************
+ * Function: *
+ * ConsoleInit *
+ * *
+ * Description: *
+ * Does all the graphics work required on SoftPC start-up. *
+ * Will split or modify later to accomodate the SCS initialisation *
+ * that loses the config.sys etc output. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID ConsoleInit(VOID)
+{
+ USHORT charHeight, vgaHeight, cursorLine, topLine;
+
+ note_entrance0("ConsoleInit");
+
+#ifdef X86GFX
+
+ /* Now GetROMsMapped called from config after sas_init */
+
+ /*
+ * Set emulation to a known state when starting up windowed. This has to
+ * be done after the ROMS are mapped but before we start to look at
+ * things like BIOS variables.
+ */
+ GfxReset();
+
+#endif
+ initTextSection();
+
+ /*
+ * Set up input focus details (we do it here as the fullscreen stuff
+ * is what is really interested in it).
+ */
+ sc.Focus = TRUE;
+ sc.FocusEvent = CreateEvent((LPSECURITY_ATTRIBUTES) NULL,
+ FALSE,
+ FALSE,
+ NULL);
+
+#ifdef X86GFX
+#ifdef SEPARATE_DETECT_THREAD
+ /* Create screen state transition detection thread. */
+ CreateDetectThread();
+#endif /* SEPARATE_DETECT_THREAD */
+#endif /* X86GFX */
+
+ /*
+ * We don't want to call paint routines until config.sys processed or if
+ * the monitor is writing directly to the frame buffer (fullscreen), so...
+ */
+ disableUpdates();
+
+ /*
+ ** Get console window size and set up our stuff accordingly.
+ */
+ calcScreenParams( &charHeight, &vgaHeight );
+
+ StartupCharHeight = charHeight;
+#ifdef X86GFX
+ if( sc.ScreenState != WINDOWED )
+ {
+ /*
+ * Do we need to update the emulation? If we don't do this here then
+ * a later state dump of the VGA registers to the VGA emulation may
+ * ignore an equal value of the char height and get_chr_height() will
+ * be out of step.
+ */
+ if (get_char_height() != startUpFontSize.Y)
+ {
+ half_word newht;
+
+ outb(EGA_CRTC_INDEX, 9); /* select char ht reg */
+ inb(EGA_CRTC_DATA, &newht); /* preserve current top 3 bits */
+ newht = (newht & 0xe0) | (startUpFontSize.Y & 0x1f);
+ outb(EGA_CRTC_DATA, newht);
+ }
+ set_char_height( startUpFontSize.Y ); /* Tim Oct 92 */
+
+ /*
+ * Select a graphics screen buffer so we get mouse coordinates in
+ * pixels.
+ */
+ //SelectMouseBuffer(); //Tim. moved to nt_std_handle_notification().
+
+ /*
+ * Prevent mode change happening to ensure dummy paint funcs
+ * are kept. (mode change set from bios mode set up).
+ */
+ set_mode_change_required(FALSE);
+ }
+#endif //X86GFX
+
+ /*
+ * Work out the top line to be displayed in the VGA window, which is line
+ * zero of the console unless the cursor would not be displayed, in which
+ * case the window is moved down until the cursor is on the bottom line.
+ */
+ cursorLine = ConsBufferInfo.dwCursorPosition.Y;
+ if (cursorLine < vgaHeight)
+ topLine = 0;
+ else
+ topLine = cursorLine - vgaHeight + (SHORT) 1;
+
+ ConVGAHeight = vgaHeight;
+ ConTopLine = topLine;
+
+ ConsoleInitialised = TRUE;
+}
+
+
+/***************************************************************************
+ * Function: *
+ * GfxReset *
+ * *
+ * Description: *
+ * Called from ConsoleInit to program up the vga hardware into some *
+ * known state. This compensates on the X86 for not initialising via *
+ * our bios. Essential for windowed running, but probably needed *
+ * for the what-mode-am-i-in stuff as well. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID GfxReset(VOID)
+{
+#ifdef X86GFX
+ half_word temp;
+ DWORD flags;
+
+ /* Check to see if we are currently running windowed or full-screen. */
+ if (!GetConsoleDisplayMode(&flags))
+ ErrorExit();
+ savedScreenState = sc.ScreenState = (flags & CONSOLE_FULLSCREEN_HARDWARE) ?
+ FULLSCREEN : WINDOWED;
+
+ /* Do windowed specific stuff. */
+ if(sc.ScreenState == WINDOWED)
+ {
+ /* Don't need this now cos we use our video BIOS in windowed */
+ /* Tim August 92: low_set_mode(3); */
+ /* sas_fillsw(0xb8000, 0x0720, 16000); */
+ inb(EGA_IPSTAT1_REG,&temp);
+
+ outb(EGA_AC_INDEX_DATA, EGA_PALETTE_ENABLE); /* re-enable video */
+
+ /* Turn off the VTRACE interrupt, enabled by low_set_mode(3)
+ this is a dirty hack and must be fixed properly */
+
+ ega_int_enable = 0;
+ }
+
+#endif
+}
+
+/***************************************************************************
+ * Function: *
+ * ResetConsoleState *
+ * *
+ * Description: *
+ * Attempts to put the console window back to the state in which *
+ * it started up. *
+ * *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID ResetConsoleState(VOID)
+{
+#ifdef X86GFX
+ /*
+ * Table of valid hardware states to be passed to
+ * SetConsoleHardwareState. NOTE: this table is a copy of a static table
+ * in SrvSetConsoleHardwareState, and so must be updated if that table
+ * changes.
+ */
+ SAVED HARDWARE_STATE validStates[] =
+ {
+ ///Now 21{ 22, { 640, 350 }, { 8, 16 } }, /* 80 x 22 mode. */
+ { 21, { 640, 350 }, { 8, 16 } }, /* 80 x 21 mode. */
+ { 25, { 720, 400 }, { 8, 16 } }, /* 80 x 25 mode. */
+ { 28, { 720, 400 }, { 8, 14 } }, /* 80 x 28 mode. */
+ { 43, { 640, 350 }, { 8, 8 } }, /* 80 x 43 mode. */
+#define MODE_50_INDEX 4
+ { 50, { 720, 400 }, { 8, 8 } } /* 80 x 50 mode. */
+ };
+ COORD cursorPos;
+ CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
+ ULONG i,
+ j,
+ videoWidth,
+ mode,
+ tableLen;
+ half_word *from,
+ *videoLine,
+ currentPage,
+ misc;
+ static COORD screenRes; /* value provided by GetConsHwState() */
+ static COORD fontSize; /* value provided by GetConsHwState() */
+
+ PCHAR_INFO to;
+ ULONG videoHeight,
+ nChars;
+ COORD bufferCoord,
+ bufferSize;
+ SMALL_RECT writeRegion;
+
+#endif /* X86GFX */
+ SMALL_RECT newWin;
+ BOOL itfailed = FALSE;
+
+#ifdef X86GFX
+ if (sc.ScreenState == WINDOWED)
+ {
+#endif /* X86GFX */
+
+ closeGraphicsBuffer();
+
+ if (StreamIoSwitchOn && !host_stream_io_enabled) {
+ /* restore screen buffer and window size */
+ SetConsoleScreenBufferSize(sc.OutputHandle, sc.ConsoleBuffInfo.dwSize);
+ newWin.Top = newWin.Left = 0;
+ newWin.Bottom = sc.ConsoleBuffInfo.srWindow.Bottom -
+ sc.ConsoleBuffInfo.srWindow.Top;
+ newWin.Right = sc.ConsoleBuffInfo.srWindow.Right -
+ sc.ConsoleBuffInfo.srWindow.Left;
+ SetConsoleWindowInfo(sc.OutputHandle, TRUE, &newWin);
+ }
+ /*
+ ** Tim September 92, don't resize window on way out of DOS app cos
+ ** MS (Sudeep) said so. Don't want to do the associated recalc_text()
+ ** either.
+ ** This keeps the window re-sizing issue nice and simple, but there'll
+ ** be people who don't like having a DOS window size forced upon them.
+ */
+#if 0
+ /* Now resize the window to start-up size. */
+ newWin.Top = newWin.Left = 0;
+ newWin.Bottom = ConsBufferInfo.srWindow.Bottom -
+ ConsBufferInfo.srWindow.Top;
+ newWin.Right = ConsBufferInfo.srWindow.Right -
+ ConsBufferInfo.srWindow.Left;
+
+ if(!SetConsoleWindowInfo(sc.OutputHandle, TRUE, &newWin))
+ itfailed = TRUE;
+
+ if(!SetConsoleScreenBufferSize(sc.OutputHandle,ConsBufferInfo.dwSize))
+ ErrorExit();
+ if (itfailed) //try 'it' again...
+ if(!SetConsoleWindowInfo(sc.OutputHandle, TRUE, &newWin))
+ ErrorExit();
+
+ /*
+ * Now call video routine to set the character height, updating the
+ * BIOS RAM as it does so.
+ */
+ recalc_text(StartupCharHeight);
+#endif //Zero
+
+#if 0
+ /* williamh. If we really want to do the following thing,
+ we have to copy regen to console buffer.
+ since we are runniing in windowed TEXT mode
+ the console always has our up-to-date regen
+ content, the following actually is not necessary
+ It worked before taking this out it because console
+ doesn't verify the parameters we passed. No console
+ has the checking and we are in trouble if we continue
+ to do so.
+ */
+
+ /* Clear the undisplayed part of the console buffer. */
+ bufferSize.X = MAX_CONSOLE_WIDTH;
+ bufferSize.Y = MAX_CONSOLE_HEIGHT;
+ videoHeight = (SHORT) (sas_hw_at_no_check(vd_rows_on_screen) + 1);
+ to = consoleBuffer + bufferSize.X * videoHeight;
+ nChars = bufferSize.X * ( bufferSize.Y - videoHeight );
+
+ while (nChars--)
+ {
+ to->Char.AsciiChar = 0x20;
+ to->Attributes = 7;
+ to++;
+ }
+ bufferCoord.X = 0;
+ bufferCoord.Y = (SHORT)videoHeight;
+ writeRegion.Left = 0;
+ writeRegion.Top = (SHORT)videoHeight;
+ writeRegion.Right = MAX_CONSOLE_WIDTH-1;
+ writeRegion.Bottom = bufferSize.Y-1;
+ if (!WriteConsoleOutput(sc.OutputHandle,
+ consoleBuffer,
+ bufferSize,
+ bufferCoord,
+ &writeRegion))
+ ErrorExit();
+#endif
+ /*
+ ** Tim, September 92. Put the Console cursor to the same place as the
+ ** SoftPC cursor. We already do this in full-screen text mode below.
+ ** Specifcally to fix weird cursor position problem with 16-bit nmake,
+ ** but seems like a good safety idea anyway.
+ */
+ getVDMCursorPosition();
+
+ doNullRegister(); /* revert console back to ordinary window */
+
+#ifdef X86GFX
+ }
+ else /* FULLSCREEN */
+ {
+ /*
+ * If SoftPC blocks in a text mode, sync console srceen buffer to regen
+ * area.
+ */
+ if (getModeType() == TEXT)
+ {
+ /* Get the current screen buffer info. */
+ if (!GetConsoleScreenBufferInfo(sc.OutputHandle, &bufferInfo))
+ ErrorExit();
+
+ /* Get nearest screen size SetConsoleHardwareState will allow. */
+ tableLen = sizeof(validStates) / sizeof(HARDWARE_STATE);
+ for (mode = 0; mode < tableLen; mode++)
+ if (validStates[mode].LinesOnScreen ==
+ bufferInfo.srWindow.Bottom - bufferInfo.srWindow.Top + 1)
+ break;
+
+ /* Set it to 50 line mode if we had a funny number of lines. */
+ if (mode == tableLen)
+ {
+ assert0(FALSE,
+ "Non standard lines on blocking - setting 50 lines");
+ mode = MODE_50_INDEX;
+ }
+
+ /*
+ ** Tim September 92, if the console hardware state is the same as
+ ** we are about to set it, do not bother setting it.
+ ** This should stop the screen from flashing.
+ */
+ if( !GetConsoleHardwareState(sc.OutputHandle,
+ &screenRes,
+ &fontSize) )
+ assert1( NO,"VDM: GetConsHwState() failed:%#x",GetLastError() );
+
+ /* Sync the console to the regen buffer. */
+ currentPage = sas_hw_at_no_check(vd_current_page);
+ vga_misc_inb(0x3cc, &misc);
+ if (misc & 1) // may be mono mode
+ videoLine = (half_word *) CGA_REGEN_START +
+ (VIDEO_PAGE_SIZE * currentPage);
+ else
+ videoLine = (half_word *) MDA_REGEN_START +
+ (VIDEO_PAGE_SIZE * currentPage);
+ to = consoleBuffer;
+ videoWidth = sas_w_at_no_check(VID_COLS);
+ videoHeight = (SHORT) (sas_hw_at_no_check(vd_rows_on_screen) + 1);
+ bufferSize.X = MAX_CONSOLE_WIDTH;
+ bufferSize.Y = MAX_CONSOLE_HEIGHT;
+ if (bufferSize.X * bufferSize.Y > MAX_CONSOLE_SIZE)
+ {
+ assert1(FALSE, "Buffer size, %d, too large",
+ bufferSize.X * bufferSize.Y);
+ ErrorExit();
+ }
+ for (i = 0; i < videoHeight; i++)
+ {
+ from = videoLine;
+ for (j = 0; j < videoWidth; j++)
+ {
+ to->Char.AsciiChar = *from++;
+ to->Attributes = *from++;
+ to++;
+ }
+ for (; j < (ULONG)bufferSize.X; j++)
+ {
+ to->Char.AsciiChar = 0x20;
+ to->Attributes = 7;
+ to++;
+ }
+ videoLine += videoWidth * 2;
+ }
+ for (; i < (ULONG)bufferSize.Y; i++)
+ for (j = 0; j < (ULONG)bufferSize.X; j++)
+ {
+ to->Char.AsciiChar = 0x20;
+ to->Attributes = 7;
+ to++;
+ }
+ bufferCoord.X = bufferCoord.Y = 0;
+ writeRegion.Left = writeRegion.Top = 0;
+ writeRegion.Right = bufferSize.X - 1;
+ writeRegion.Bottom = bufferSize.Y - 1;
+
+ doNullRegister(); /* revert back to normal console */
+
+ if( screenRes.X != validStates[mode].Resolution.X ||
+ screenRes.Y != validStates[mode].Resolution.Y ||
+ fontSize.X != validStates[mode].FontSize.X ||
+ fontSize.Y != validStates[mode].FontSize.Y ||
+ sas_hw_at_no_check(VID_COLS) == 40 ||
+ fontSize.Y != sas_hw_at_no_check(ega_char_height))
+ {
+ /* Set up the screen. */
+ if( !SetConsoleHardwareState( sc.OutputHandle,
+ validStates[mode].Resolution,
+ validStates[mode].FontSize) ){
+ /*
+ ** Tim Sept 92, attempt a recovery.
+ */
+ assert1( NO, "VDM: SetConsoleHwState() failed:%#x",
+ GetLastError() );
+ }
+ }
+
+
+ /* put VDM screen onto console screen */
+ if (!WriteConsoleOutput(sc.OutputHandle,
+ consoleBuffer,
+ bufferSize,
+ bufferCoord,
+ &writeRegion))
+ ErrorExit();
+
+#if 0 //STF removed with new mouse stuff??
+ /*
+ ** Tim, September 92.
+ ** Try this after the WriteConsoleOutput(), can now copy the
+ ** right stuff from video memory to console.
+ ** For mouse purposes we have selected a graphics buffer, so now
+ ** we must reselect the text buffer.
+ */
+ if (!SetConsoleActiveScreenBuffer(sc.OutputHandle))
+ ErrorExit();
+#endif //STF
+
+ /*
+ * Get the cursor position from the BIOS RAM and tell the
+ * console.
+ * Set up variables getVDMCursorPosition() needs. Tim Jan 93.
+ */
+ sc.PC_W_Height = screenRes.Y;
+ sc.CharHeight = fontSize.Y;
+ getVDMCursorPosition();
+ }
+ else /* GRAPHICS */
+ {
+ /*
+ ** A tricky issue. If we were just in a full-screen graphics
+ ** mode, we are just about to lose the VGA state and can't get
+ ** it back very easily. So do we pretend we are still in the
+ ** graphics mode or pretend we are in a standard text mode?
+ ** Seems like standard text mode is more sensible. Tim Feb 93.
+ */
+ sas_store_no_check( vd_video_mode, 0x3 );
+ blocked_in_gfx_mode = TRUE;
+
+#if 0 //STF removed with new mouse stuff??
+ /*
+ ** Tim, September 92, think we want one of these here too.
+ ** Change to the normal console text buffer.
+ */
+ if (!SetConsoleActiveScreenBuffer(sc.OutputHandle))
+ ErrorExit();
+#endif //STF
+
+ /* Get the current screen buffer info. */
+ if (!GetConsoleScreenBufferInfo(sc.OutputHandle, &bufferInfo))
+ ErrorExit();
+
+ /* Get nearest screen size SetConsoleHardwareState will allow. */
+ tableLen = sizeof(validStates) / sizeof(HARDWARE_STATE);
+ for (mode = 0; mode < tableLen; mode++)
+ if (validStates[mode].LinesOnScreen ==
+ bufferInfo.srWindow.Bottom - bufferInfo.srWindow.Top + 1)
+ break;
+
+ /* Set it to 50 line mode if we had a funny number of lines. */
+ if (mode == tableLen)
+ {
+ assert0(FALSE,
+ "Non standard lines on blocking - setting 50 lines");
+ mode = MODE_50_INDEX;
+ }
+
+ /* Clear the console buffer. */
+ bufferSize.X = MAX_CONSOLE_WIDTH;
+ bufferSize.Y = MAX_CONSOLE_HEIGHT;
+ nChars = bufferSize.X * bufferSize.Y;
+ if (nChars > MAX_CONSOLE_SIZE)
+ {
+ assert1(FALSE, "Buffer size, %d, too large", nChars);
+ ErrorExit();
+ }
+ to = consoleBuffer;
+ while (nChars--)
+ {
+ to->Char.AsciiChar = 0x20;
+ to->Attributes = 7;
+ to++;
+ }
+ bufferCoord.X = bufferCoord.Y = 0;
+ writeRegion.Left = writeRegion.Top = 0;
+ writeRegion.Right = MAX_CONSOLE_WIDTH-1;
+ writeRegion.Bottom = bufferSize.Y-1;
+
+ doNullRegister(); /* revert back to normal console */
+
+ if (!WriteConsoleOutput(sc.OutputHandle,
+ consoleBuffer,
+ bufferSize,
+ bufferCoord,
+ &writeRegion))
+ ErrorExit();
+
+ /* Set the cursor to the top left corner. */
+ cursorPos.X = 0;
+ cursorPos.Y = 0;
+ if (!SetConsoleCursorPosition(sc.OutputHandle, cursorPos))
+ ErrorExit();
+#ifndef PROD
+ if (sc.ScreenState == WINDOWED) // transient switch??
+ assert0(NO, "Mismatched screenstate on shutdown");
+#endif
+
+ /* Set up the screen. */
+ SetConsoleHardwareState(sc.OutputHandle,
+ validStates[mode].Resolution,
+ validStates[mode].FontSize);
+ }
+ /*
+ ** Tim September 92, close graphics screen buffer on way out when in
+ ** full-screen.
+ */
+ closeGraphicsBuffer();
+ }
+#endif /* X86GFX */
+
+ /*Put console's cursor back to the shape it was on startup.*/
+ SetConsoleCursorInfo(sc.OutputHandle, &StartupCursor);
+
+ /* reset the current_* variables in nt_graph.c */
+ resetWindowParams();
+}
+
+
+#ifdef X86GFX
+
+/***************************************************************************
+ * Function: *
+ * TextToGraphics *
+ * *
+ * Description: *
+ * Handles transitions from text to graphics modes when running *
+ * windowed. Waits until the window has input focus and then requests *
+ * a transition to full-screen operation as graphics modes cannot be *
+ * run in a window. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID TextToGraphics(VOID)
+{
+ DWORD flags;
+ SAVED COORD scrSize;
+
+ /* Freeze until the window receives input focus. */
+ //if (! sc.Focus ) //awaiting console fix.
+ if (GetForegroundWindow() != hWndConsole)
+ {
+
+ FreezeWinTitle(); /* Add `-FROZEN' to the console title. */
+
+ /* Now wait until input focus is received. */
+ waitForInputFocus();
+
+ UnFreezeWinTitle(); /* Remove frozen message */
+ }
+
+ /*
+ * We are about to go full-screen but there will be a delay while the
+ * detection thread does its hand-shaking. So disable screen writes before
+ * we switch to prevent inadvertent updates while running full-screen.
+ */
+ disableUpdates();
+
+ /*
+ * Sanity Check for stress problem where forced fullscreen after INT 10
+ * mode change has already started so can apparently go fullscreen twice.
+ */
+ if (!GetConsoleDisplayMode(&flags))
+ ErrorExit();
+
+ /* make sure we haven't been taken back fullscreen */
+ if ((flags & CONSOLE_FULLSCREEN_HARDWARE) == CONSOLE_FULLSCREEN_HARDWARE)
+ {
+#ifndef PROD
+ assert0(NO,"NTVDM:rejected fullscreen switch as console already FS");
+#endif
+ return;
+ }
+
+ /* check for iconified FS console. Only under extreme conditions (stress) */
+ if ((flags & CONSOLE_FULLSCREEN) == CONSOLE_FULLSCREEN)
+ {
+ SetForegroundWindow(hWndConsole); /* focus will send us back FS */
+ }
+ else /* desktop window */
+ {
+ /* The window now has input focus so request to go full-screen. */
+ BiosModeChange = TRUE;
+ if (!SetConsoleDisplayMode(sc.OutputHandle,
+ CONSOLE_FULLSCREEN_MODE,
+ &scrSize))
+ {
+ if (GetLastError() == ERROR_INVALID_PARAMETER)
+ {
+ RcErrorDialogBox(ED_INITFSCREEN, NULL, NULL);
+ }
+ else
+ {
+ ErrorExit();
+ }
+ }
+ BiosModeChange = FALSE;
+ }
+}
+
+/***************************************************************************
+ * Function: *
+ * CheckForFullscreenSwitch *
+ * *
+ * Description: *
+ * Checks to see if there has been a transition between windowed and *
+ * fullscreen and does any console calls necessary. This is called *
+ * on a timer tick before the graphics tick code. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID CheckForFullscreenSwitch(VOID)
+{
+ half_word mode,
+ lines;
+
+ if (sc.ScreenState == STREAM_IO)
+ return;
+
+ /*
+ * Do any console calls relating to screen state changes. They have to be
+ * done now as they cannot be done on the same thread as the screen switch
+ * hand-shaking.
+ */
+ if (sc.ScreenState != savedScreenState)
+ {
+ if (sc.ScreenState == WINDOWED)
+ {
+ if (sc.ModeType == TEXT)
+ {
+
+ /* Remove frozen window indicator if necessary. */
+ UnFreezeWinTitle();
+
+#if 0 //STF removed with new mouse stuff??
+ /* Revert to text buffer. */
+ closeGraphicsBuffer(); /* Tim Oct 92 */
+#endif //STF
+
+ /* Get Window to correct shape */
+ textResize();
+
+ /* Enable screen updates. */
+ enableUpdates();
+
+ /*
+ * Now get the image on the screen (timer updates currently
+ * disabled).
+ */
+ (void)(*update_alg.calc_update)();
+
+ }
+ }
+ else /* FULLSCREEN */
+ {
+ int cnt = 0; /* Counter to break out of the cursor off loop. */
+
+ /* Disable screen updates*/
+ disableUpdates();
+
+ /* Disable mouse 'attached'ness if enabled */
+ if (bPointerOff)
+ {
+ PointerAttachedWindowed = TRUE;
+ MouseDisplay();
+ }
+
+#if 0 //STF removed with new mouse stuff
+ /* remove any graphics buffer from frozen screen */
+ closeGraphicsBuffer();
+#endif
+
+ /* Do mouse scaling */
+ mode = sas_hw_at_no_check(vd_video_mode);
+ lines = sas_hw_at_no_check(vd_rows_on_screen) + 1;
+ SelectMouseBuffer(mode, lines);
+
+ /* force mouse */
+ ica_hw_interrupt(AT_CPU_MOUSE_ADAPTER, AT_CPU_MOUSE_INT, 1);
+
+ /*
+ * Now turn off console cursor - otherwise can ruin screen trying to
+ * draw system's cursor. The VDM will have to worry about the mouse
+ * image.
+ */
+ // while(ShowConsoleCursor(sc.OutputHandle, FALSE) >=0 && cnt++ < 200);
+ } /* FULLSCREEN */
+
+ /* Update saved variable. */
+ savedScreenState = sc.ScreenState;
+ }
+ /* Delayed Client Rect query */
+ if (DelayedReattachMouse)
+ {
+ DelayedReattachMouse = FALSE;
+ MovePointerToWindowCentre();
+ }
+}
+
+/*
+***************************************************************************
+** getNtScreenState() - return 0 for windowed, 1 for full-screen.
+***************************************************************************
+** Tim July 92.
+*/
+GLOBAL UTINY getNtScreenState IFN0()
+{
+ return( (UTINY) sc.ScreenState );
+}
+
+/*
+***************************************************************************
+** hostModeChange() - called from video bios, ega_vide.c:ega_set_mode()
+***************************************************************************
+**
+** When changing to a graphics mode action the transition to full-screen if
+** we are currently windowed.
+**
+** On entry AX should still contain the value when the video BIOS set mode
+** function was called.
+** Call to TextToGraphics() with parameter indicating whether we want a
+** clear screen with the impending host video BIOS mode change.
+**
+** Return a boolean indicating to the real BIOS whether the mode change
+** has occured.
+**
+** Tim August 92.
+*/
+GLOBAL BOOL hostModeChange IFN0()
+{
+ half_word vid_mode;
+
+ vid_mode = getAL() & 0x7f;
+
+ if(getNtScreenState() == WINDOWED)
+ {
+ if (vid_mode > 3 && vid_mode != 7)
+ {
+ /*
+ * We have to tell the hand-shaking code the BIOS is causing
+ * the mode change so that it can do a BIOS mode change when
+ * the switch has been done. This has to be implemented as a
+ * global variable because the hand-shaking is on a different
+ * thread.
+ */
+ TextToGraphics();
+ // rapid Window to full screen and back cause this to fail,
+ // remove call since it will get done on the next timer
+ // event. 28-Feb-1993 Jonle
+ // SelectMouseBuffer();
+ return( TRUE );
+ }
+ else
+ return(FALSE);
+ }
+ else
+ return( FALSE );
+
+} /* end hostModeChange() */
+#endif /* X86GFX */
+
+/***************************************************************************
+ * Function: *
+ * DoFullScreenResume *
+ * *
+ * Description: *
+ * Called by SCS to restart SoftPC when a DOS application restarts *
+ * after being suspended or starts up for the first time after SoftPC *
+ * has been booted by another application which has since terminated. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+
+GLOBAL VOID DoFullScreenResume(VOID)
+{
+ USHORT vgaHeight, height;
+#ifndef X86GFX
+ PVOID pDummy;
+#endif
+
+#ifdef X86GFX
+ DWORD flags;
+
+ /*
+ ** Tim July 92.
+ ** Set sc.ScreenState, a windowed/full-screen transition might
+ ** have happenened when SoftPC was inactive.
+ ** Copied from GfxReset().
+ */
+ if( !GetConsoleDisplayMode(&flags) )
+ ErrorExit();
+ sc.ScreenState = (flags & CONSOLE_FULLSCREEN_HARDWARE) ? FULLSCREEN : WINDOWED;
+
+ /* Put the regen memory in the correct state. */
+ if (sc.ScreenState != savedScreenState)
+ {
+ if (sc.ScreenState == WINDOWED)
+ {
+ enableUpdates(); /* Tim September 92, allow graphics ticks */
+ /*
+ ** Tim Jan 93. Get the next nt_graphics_tick() to decide
+ ** what the current display mode is, set the update and
+ ** paint funx appropriately and redraw the screen.
+ */
+ set_mode_change_required( TRUE );
+
+ /* Ensure idling system enabled & reset */
+ IDLE_ctl(TRUE);
+ IDLE_init();
+ }
+ else
+ {
+ disableUpdates(); /* Tim September 92, stop graphics ticks */
+
+ /* Ensure idling system disabled as can't detect fullscreen idling*/
+ IDLE_ctl(FALSE);
+ }
+ savedScreenState = sc.ScreenState;
+ }
+
+ /* Select a graphics buffer for the mouse if we are running fullscreen. */
+ if (sc.ScreenState == FULLSCREEN)
+ {
+ //SelectMouseBuffer(); //Tim. moved to nt_std_handle_notification().
+
+ /* Lose the regen memory. */
+ LoseRegenMemory();
+ }
+
+ /*
+ ** Tim July 92:
+ ** set the KEYBOARD.SYS internal variable to 0 for windowed and
+ ** 1 for full-screen.
+ ** If a transition has happened when SoftPC was inactive we
+ ** need to get into the appropriate state.
+ */
+ {
+ if( sc.ScreenState==WINDOWED ){
+ sas_store_no_check( (int10_seg<<4)+useHostInt10, WINDOWED );
+ }else{
+ sas_store_no_check( (int10_seg<<4)+useHostInt10, FULLSCREEN );
+ }
+ }
+#endif /* X86GFX */
+
+ // re-register with console for fullscreen switching.
+ if( !RegisterConsoleVDM( VDMForWOW ?
+ CONSOLE_REGISTER_WOW : CONSOLE_REGISTER_VDM,
+#ifdef X86GFX
+ hStartHardwareEvent,
+ hEndHardwareEvent,
+#else
+ NULL,
+ NULL,
+#endif
+
+ NULL, // sectionname no longer used
+ 0, // sectionname no longer used
+ &stateLength,
+#ifndef X86GFX
+ &pDummy,
+#else
+ (PVOID *) &videoState,
+#endif
+ NULL, // sectionname no longer used
+ 0, // sectionname no longer used
+ textBufferSize,
+ (PVOID *) &textBuffer
+ )
+ )
+ ErrorExit();
+
+#ifdef X86GFX
+ sc.Registered = TRUE;
+ /* stateLength can be 0 if fullscreen is disabled in the console */
+ if(stateLength)
+ RtlZeroMemory(videoState, sizeof(VIDEO_HARDWARE_STATE_HEADER));
+#else
+ /*
+ ** Create graphics buffer if we need one. Tim Oct 92.
+ */
+ if( sc.ModeType==GRAPHICS )
+ graphicsResize();
+#endif
+ /*
+ ** Tim September 92.
+ ** If window size is not suitable for a DOS app, snap-to-fit
+ ** appropriately. Put cursor in correct place.
+ ** Do the ConsoleInit() and nt_init_event_thread() type of things.
+ ** Leave full-screen as it was.
+ */
+ if (sc.ScreenState != WINDOWED) {
+ /* Get console info, including the current cursor position. */
+ if (!GetConsoleScreenBufferInfo(sc.OutputHandle, &ConsBufferInfo))
+ ErrorExit();
+ /* Hard-wired for f-s resume - needs to be set properly. */
+ height = 8;
+ /* Set up BIOS variables etc. */
+ setVDMCursorPosition( (UTINY)height,
+ &ConsBufferInfo.dwCursorPosition);
+ /* Copy the console buffer to the regen buffer. */
+ copyConsoleToRegen(0, 0, VGA_WIDTH, (SHORT)ConVGAHeight);
+ }
+
+ /*
+ ** Get console window size and set up our stuff accordingly.
+ */
+ calcScreenParams( &height, &vgaHeight );
+
+ /*
+ ** Window resize code copied out of nt_graph.c:textResize().
+ */
+ {
+ resizeWindow( 80, vgaHeight );
+ }
+
+ /* Copy the console buffer to the regen buffer. */
+ copyConsoleToRegen(0, 0, VGA_WIDTH, vgaHeight);
+
+ /*
+ ** Make sure cursor is not below bottom line.
+ */
+ if( ConsBufferInfo.dwCursorPosition.Y >= vgaHeight ){
+ ConsBufferInfo.dwCursorPosition.Y = vgaHeight-1;
+ }
+ setVDMCursorPosition(( UTINY)height, &ConsBufferInfo.dwCursorPosition);
+
+} /* end of DoFullScreenResume() */
+
+/***************************************************************************
+ * Function: *
+ * GfxCloseDown *
+ * *
+ * Description: *
+ * Hook from host_terminate to ensure section closed so can then start*
+ * more VDMs. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID (Errors handled internally in CloseSection) *
+ * *
+ ***************************************************************************/
+GLOBAL VOID GfxCloseDown(VOID)
+{
+ /* Text and Video sections previously closed here... */
+}
+
+#ifdef X86GFX
+/***************************************************************************
+ * Function: *
+ * FreezeWinTitle *
+ * *
+ * Description: *
+ * Adds -FROZEN to the relevant console window title *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID FreezeWinTitle(VOID)
+{
+ CHAR title[MAX_TITLE_LEN],*ptr;
+ SHORT max;
+ ULONG len;
+
+ if (WinFrozen)
+ return;
+
+ //
+ // The buffer contains the string plus the terminating null.
+ // So keep the string length less the null in len.
+ // Console can fail this call with silly error codes in low memory cases
+ // or if original title contains dubious chars.
+ //
+
+ len = strlen(szFrozenString);
+
+ max = (SHORT) (MAX_TITLE_LEN - len);
+ if (!GetConsoleTitle(title, max))
+ title[0] = '\0';
+
+ //
+ // Remove any trailing spaces or tabs from the title string
+ //
+
+ if(len = strlen(title))
+ {
+ ptr = title + len - 1;
+ while(*ptr == ' ' || *ptr == '\t')
+ *ptr-- = '\0';
+ }
+
+ //
+ // Add " - FROZEN" or the international equivalent to
+ // the end of the title string.
+ //
+
+ strcat(title, szFrozenString);
+ if (!SetConsoleTitle(title))
+ ErrorExit();
+ WinFrozen = TRUE;
+
+}
+
+/***************************************************************************
+ * Function: *
+ * UnFreezeWinTitle *
+ * *
+ * Description: *
+ * Removes -FROZEN from the relevant console window title *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID UnFreezeWinTitle(VOID)
+{
+ CHAR title[MAX_TITLE_LEN];
+ ULONG len,orglen;
+
+ if (! WinFrozen)
+ return;
+
+ if (!GetConsoleTitle(title, MAX_TITLE_LEN))
+ ErrorExit();
+
+
+ //
+ // The buffer contains the string plus the terminating null.
+ // So keep the string length less the null in len.
+ //
+
+ len = strlen(szFrozenString);
+ orglen = strlen(title);
+ title[orglen - len] = '\0';
+ if (!SetConsoleTitle(title))
+ ErrorExit();
+ WinFrozen = FALSE;
+
+ //
+ // Now that we're thawing, put the mouse menu item
+ // back into the system menu.
+ // Andy!
+
+ MouseAttachMenuItem(sc.ActiveOutputBufferHandle);
+}
+#endif
+
+
+/*
+ * ==========================================================================
+ * Local Functions
+ * ==========================================================================
+ */
+
+/***************************************************************************
+ * Function: *
+ * enableUpdates *
+ * *
+ * Description: *
+ * Restarts the reflection of regen buffer updates to paint routines. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+VOID enableUpdates(VOID)
+{
+ enable_gfx_update_routines();
+ ConsoleNoUpdates = FALSE;
+}
+
+/***************************************************************************
+ * Function: *
+ * disableUpdates *
+ * *
+ * Description: *
+ * Stops changes to the regen buffer being reflected to paint *
+ * routines. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+VOID disableUpdates(VOID)
+{
+ disable_gfx_update_routines();
+ ConsoleNoUpdates = TRUE;
+}
+
+/***************************************************************************
+ * Function: *
+ * copyConsoleToRegen *
+ * *
+ * Description: *
+ * Copies the contents of the console buffer to the video regen *
+ * buffer. *
+ * *
+ * Parameters: *
+ * startCol - start column of console buffer *
+ * startLine - start line of console buffer *
+ * width - width of console buffer *
+ * height - height of console buffer *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+VOID copyConsoleToRegen(SHORT startCol, SHORT startLine, SHORT width,
+ SHORT height)
+{
+ CHAR_INFO *from;
+ COORD bufSize,
+ bufCoord;
+ LONG nChars;
+ SMALL_RECT readRegion;
+
+ register half_word *to;
+#ifdef X86GFX
+ half_word misc;
+ register half_word *vc;
+#endif
+
+
+ /* Allocate the buffer to get the console data into */
+ nChars = width * height;
+ assert0(nChars <= MAX_CONSOLE_SIZE, "Console buffer overflow");
+
+ /* Get the console data. */
+ bufSize.X = width;
+ bufSize.Y = height;
+ bufCoord.X = 0;
+ bufCoord.Y = 0;
+ readRegion.Left = startCol;
+ readRegion.Top = startLine;
+ readRegion.Right = startCol + width - (SHORT) 1;
+ readRegion.Bottom = startLine + height - (SHORT) 1;
+ if (!ReadConsoleOutput(sc.OutputHandle,
+ consoleBuffer,
+ bufSize,
+ bufCoord,
+ &readRegion))
+ ErrorExit();
+
+ /* Copy the console data to the regen buffer. */
+ from = consoleBuffer;
+
+#ifndef X86GFX // on MIPS we actually want to write to the VGA bitplanes.
+ to = EGA_planes;
+ while(nChars--)
+ {
+ *to++ = from->Char.AsciiChar;
+ *to = (half_word) from->Attributes;
+ from++;
+ to += 3; // skipping interleaved font planes.
+ }
+ host_mark_screen_refresh();
+#else
+
+ /*
+ * In V86 mode PC memory area is mapped to the bottom 1M of virtual memory,
+ * so the following is legal.
+ */
+ vga_misc_inb(0x3cc, &misc);
+ if (misc & 1) // may be mono mode
+ to = (half_word *) CGA_REGEN_START;
+ else
+ to = (half_word *) MDA_REGEN_START;
+
+ vc = (half_word *) video_copy;
+
+ while (nChars--)
+ {
+ *to++ = *vc++ = from->Char.AsciiChar;
+ *to++ = *vc++ = (half_word) from->Attributes;
+ from++;
+ }
+#endif
+}
+
+/***************************************************************************
+ * Function: *
+ * getVDMCursorPosition *
+ * *
+ * Description: *
+ * Gets the cursor position from BIOS variables and tells the console *
+ * where to place its cursor. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+VOID getVDMCursorPosition(VOID)
+{
+ half_word currentPage;
+ word cursorWord;
+ COORD cursorPos;
+ BOOL setok;
+
+ /* Get the current video page. */
+ currentPage = sas_hw_at_no_check(vd_current_page);
+
+ /* Store cursor position in BIOS variables. */
+ cursorWord = sas_w_at_no_check(VID_CURPOS + (currentPage * 2));
+
+ /* Set the console cursor. */
+ cursorPos.X = (SHORT) (cursorWord & 0xff);
+ cursorPos.Y = (cursorWord >> 8) & (SHORT) 0xff;
+
+ if ((sc.CharHeight * cursorPos.Y) > sc.PC_W_Height)
+ cursorPos.Y = (sc.PC_W_Height / sc.CharHeight) - 1;
+
+ if( !stdoutRedirected ) {
+ setok = SetConsoleCursorPosition(sc.OutputHandle, cursorPos);
+ if (!setok) {
+
+ if (GetLastError() != ERROR_INVALID_HANDLE) // ie. output redirected
+ ErrorExit();
+ }
+ }
+}
+
+/***************************************************************************
+ * Function: *
+ * setVDMCursorPosition *
+ * *
+ * Description: *
+ * Positions SoftPC's cursor, setting the relevant BIOS variables. *
+ * *
+ * Parameters: *
+ * height - the current character height *
+ * cursorPos - the coordinates of the cursor *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+VOID setVDMCursorPosition(UTINY height, PCOORD cursorPos)
+{
+ CONSOLE_CURSOR_INFO cursorInfo;
+ ULONG port6845,
+ cursorStart,
+ cursorEnd,
+ colsOnScreen,
+ videoLen,
+ pageOffset,
+ cursorWord;
+ UTINY currentPage;
+
+ /* Get cursor size. */
+ if(!GetConsoleCursorInfo(sc.OutputHandle, &cursorInfo))
+ ErrorExit();
+
+ /* Work out cursor start and end pixels. */
+ cursorStart = height - (height * cursorInfo.dwSize / 100);
+ if (cursorStart == height)
+ cursorStart--;
+ cursorEnd = height - 1;
+
+ if (sc.ScreenState == WINDOWED)
+ {
+
+ /* Pass cursor size to video ports. */
+ port6845 = sas_w_at_no_check(VID_INDEX);
+ outb((io_addr) port6845, R10_CURS_START);
+ outb((io_addr) (port6845 + 1), (half_word) cursorStart);
+ outb((io_addr) port6845, R11_CURS_END);
+ outb((io_addr) (port6845 + 1), (half_word) cursorEnd);
+ }
+
+ /* Get the current video page. */
+ currentPage = sas_hw_at_no_check(vd_current_page);
+
+ /* Set BIOS variables. */
+ sas_storew_no_check(VID_CURMOD,
+ (word) ((cursorStart << 8) | (cursorEnd & 0xff)));
+
+ /* Work out cursor position. */
+ colsOnScreen = sas_w_at_no_check(VID_COLS);
+ videoLen = sas_w_at_no_check(VID_LEN);
+ pageOffset = cursorPos->Y * colsOnScreen * 2 + (cursorPos->X << 1);
+ cursorWord = (currentPage * videoLen + pageOffset) / 2;
+
+ if (sc.ScreenState == WINDOWED)
+ {
+
+ /* Send cursor position to video ports. */
+ outb((io_addr) port6845, R14_CURS_ADDRH);
+ outb((io_addr) (port6845 + 1), (half_word) (cursorWord >> 8));
+ outb((io_addr) port6845, R15_CURS_ADDRL);
+ outb((io_addr) (port6845 + 1), (half_word) (cursorWord & 0xff));
+ }
+
+ /* Store cursor position in BIOS variables. */
+ sas_storew_no_check(VID_CURPOS + (currentPage * 2),
+ (word) ((cursorPos->Y << 8) | (cursorPos->X & 0xff)));
+
+ if (sc.ScreenState == WINDOWED)
+ {
+#ifdef MONITOR
+ resetNowCur(); /* reset static vars holding cursor pos. */
+#endif
+ do_new_cursor(); /* make sure the emulation knows about it */
+ }
+}
+
+VOID waitForInputFocus()
+{
+ if (WaitForSingleObject(sc.FocusEvent, INFINITE))
+ ErrorExit();
+}
+
+VOID AddTempIVTFixups()
+{
+ /* BOP 17, IRET */
+ UTINY code[] = { 0xc4, 0xc4, 0x17, 0xcf };
+
+ //location is random but should be safe until DOS is initialised!!!
+ sas_stores(0x40000, code, sizeof(code)); // new Int 17 code
+ sas_storew(0x17*4, 0); // Int 17h offset
+ sas_storew((0x17*4) + 2, 0x4000); // Int 17h segment
+}
+
+/***************************************************************************
+ * Function: *
+ * getModeType *
+ * *
+ * Description: *
+ * Look up video mode to determine whether the VGA current mode is *
+ * graphics or text. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * int - TEXT or GRAPHICS. *
+ * *
+ ***************************************************************************/
+int getModeType(VOID)
+{
+ half_word mode;
+ int modeType;
+
+ mode = sas_hw_at_no_check(vd_video_mode);
+ switch(mode)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 7:
+ case 0x20:
+ case 0x40:
+ case 0x41:
+ case 0x42:
+ case 0x43:
+ case 0x44:
+ case 0x45:
+ modeType = TEXT;
+ break;
+ default:
+ modeType = GRAPHICS;
+ break;
+ }
+ return(modeType);
+}
+
+#ifdef X86GFX
+/***************************************************************************
+ * Function: *
+ * host_check_mouse_buffer *
+ * *
+ * Description: *
+ * Called when an INT 10h, AH = 11h is being executed, this function *
+ * checks to see if the number of lines on the screen for a text mode *
+ * has changed and if so selects a new mouse buffer. *
+ * *
+ * Parameters: *
+ * None. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID host_check_mouse_buffer(VOID)
+{
+ half_word mode,
+ sub_func,
+ font_height,
+ text_lines;
+ IU16 scan_lines;
+
+ /* Get the current video mode. */
+ mode = sas_hw_at_no_check(vd_video_mode);
+#ifdef V7VGA
+ if (mode > 0x13)
+ mode += 0x4c;
+ else if ((mode == 1) && (extensions_controller.foreground_latch_1))
+ mode = extensions_controller.foreground_latch_1;
+#endif /* V7VGA */
+
+ /*
+ * Check to see if we are in a text mode whose mouse virtual coordinates
+ * are affected by the number of lines on the screen.
+ */
+ if ((mode == 0x2) || (mode == 0x3) || (mode == 0x7))
+ {
+
+ /* Work out the font height being set. */
+ sub_func = getAL();
+ switch (sub_func)
+ {
+ case 0x10:
+ font_height = getBH();
+ break;
+ case 0x11:
+ font_height = 14;
+ break;
+ case 0x12:
+ font_height = 8;
+ break;
+ case 0x14:
+ font_height = 16;
+ break;
+ default:
+
+ /*
+ * The above are the only functions that re-program the no. of lines
+ * on the screen, so do nothing if we have something else.
+ */
+ return;
+ }
+
+ /* Get the number of scan lines for this mode. */
+ if(!(get_EGA_switches() & 1) && (mode < 4))
+ {
+ scan_lines = 200; /* Low res text mode */
+ }
+ else
+ {
+ switch (get_VGA_lines())
+ {
+ case S200:
+ scan_lines = 200;
+ break;
+ case S350:
+ scan_lines = 350;
+ break;
+ case S400:
+ scan_lines = 400;
+ break;
+ default:
+
+ /* Dodgy value in BIOS data area - don't do anything. */
+ assert0(NO, "invalid VGA lines in BIOS data");
+ return;
+ }
+ }
+
+ /* Now work out the number of text lines on the screen. */
+ text_lines = scan_lines / font_height;
+
+ /* If the number of lines has changed, select a new mouse buffer. */
+ if (text_lines != saved_text_lines)
+ SelectMouseBuffer(mode, text_lines);
+
+ } /* if ((mode == 0x2) || (mode == 0x3) || (mode == 0x7)) */
+}
+
+/***************************************************************************
+ * Function: *
+ * SelectMouseBuffer *
+ * *
+ * Description: *
+ * Selects the correct screen ratio for the video mode.at the *
+ * *
+ * Parameters: *
+ * mode - the video mode for which we are setting a screen buffer. *
+ * lines - for text modes: the number of character lines on the *
+ * screen, 0 denotes the default for this mode. *
+ * *
+ * Return value: *
+ * VOID *
+ * *
+ ***************************************************************************/
+GLOBAL VOID SelectMouseBuffer(half_word mode, half_word lines)
+{
+ DWORD width,
+ height;
+
+
+ /*
+ ** When stdout is being redirected we must not set up the graphics
+ ** buffer for the mouse. Otherwise 32-bit progs like MORE crash
+ ** cos they ask console for the active console handle and get
+ ** confused. We get told by DOS Em. when stdout is being
+ ** redirected and do not set up the buffer.
+ ** Tim Jan 93.
+ */
+ if( stdoutRedirected )
+ return;
+
+ /* Work out the screen resolution. */
+ switch (mode & 0x7f)
+ {
+ case 0x0:
+ case 0x1:
+ width = 640;
+ height = 200;
+ break;
+ case 0x2:
+ case 0x3:
+ case 0x7:
+ switch (lines)
+ {
+ case 0:
+ case 25:
+ saved_text_lines = 25;
+ width = 640;
+ height = 200;
+ break;
+ case 43:
+ saved_text_lines = 43;
+ width = 640;
+ height = 344;
+ break;
+ case 50:
+ saved_text_lines = 50;
+ width = 640;
+ height = 400;
+ break;
+ default:
+ assert1(NO, "strange number of lines for text mode - %d", lines);
+ return;
+ }
+ break;
+ case 0x4:
+ case 0x5:
+ case 0x6:
+ case 0xd:
+ case 0xe:
+ width = 640;
+ height = 200;
+ break;
+ case 0xf:
+ case 0x10:
+ width = 640;
+ height = 350;
+ break;
+ case 0x11:
+ case 0x12:
+ width = 640;
+ height = 480;
+ break;
+ case 0x13:
+ width = 640;
+ height = 200;
+ break;
+ case 0x40:
+ width = 640;
+ height = 400;
+ break;
+ case 0x41:
+ case 0x42:
+ width = 1056;
+ height = 344;
+ break;
+ case 0x43:
+ width = 640;
+ height = 480;
+ break;
+ case 0x44:
+ width = 800;
+ height = 480;
+ break;
+ case 0x45:
+ width = 1056;
+ height = 392;
+ break;
+ case 0x60:
+ width = 752;
+ height = 408;
+ break;
+ case 0x61:
+ width = 720;
+ height = 536;
+ break;
+ case 0x62:
+ width = 800;
+ height = 600;
+ break;
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ width = 1024;
+ height = 768;
+ break;
+ case 0x66:
+ width = 640;
+ height = 400;
+ break;
+ case 0x67:
+ width = 640;
+ height = 480;
+ break;
+ case 0x68:
+ width = 720;
+ height = 540;
+ break;
+ case 0x69:
+ width = 800;
+ height = 600;
+ break;
+ default:
+
+ /* No change if we get an unknown mode. */
+ assert1(NO, "unknown mode - %d", mode);
+ return;
+ }
+
+ //
+ // Set the variables to let apps like Word and Works which call
+ // INT 33h AX = 26h to find out the size of the current virtual
+ // screen.
+ // Andy!
+
+ VirtualX = (word)width;
+ VirtualY = (word)height;
+
+ /* Save current dimensions. */
+ mouse_buffer_width = width;
+ mouse_buffer_height = height;
+
+}
+#endif /* X86GFX */
+
+void host_enable_stream_io(void)
+{
+ sc.ScreenState = STREAM_IO;
+ host_stream_io_enabled = TRUE;
+
+}
+void host_disable_stream_io(void)
+{
+ DWORD mode;
+
+ if(!GetConsoleMode(sc.InputHandle, &mode))
+ DisplayErrorTerm(EHS_FUNC_FAILED,GetLastError(),__FILE__,__LINE__);
+
+ mode |= (ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT);
+ if(!SetConsoleMode(sc.InputHandle,mode))
+ DisplayErrorTerm(EHS_FUNC_FAILED,GetLastError(), __FILE__,__LINE__);
+
+
+ if(!GetConsoleMode(sc.OutputHandle, &mode))
+ DisplayErrorTerm(EHS_FUNC_FAILED,GetLastError(),__FILE__,__LINE__);
+ if(!stdoutRedirected)
+ {
+ mode &= ~(ENABLE_WRAP_AT_EOL_OUTPUT | ENABLE_PROCESSED_OUTPUT);
+
+ if(!SetConsoleMode(sc.OutputHandle,mode))
+ DisplayErrorTerm(EHS_FUNC_FAILED,GetLastError(), __FILE__,__LINE__);
+ }
+
+ ConsoleInit();
+ (void)(*choose_display_mode)();
+ /*
+ ** Copy the console buffer to the regen buffer.
+ ** Don't want to adjust the copy from top of console window, console
+ ** does it itself if we resize the window. Tim September 92.
+ */
+ copyConsoleToRegen(0, 0, VGA_WIDTH, (SHORT)ConVGAHeight);
+
+ /*
+ ** Tim September 92, adjust cursor position if console window size is
+ ** adjusted.
+ */
+ ConsBufferInfo.dwCursorPosition.Y -= ConTopLine;
+
+ /* Set up SoftPC's cursor. */
+ setVDMCursorPosition((UTINY)StartupCharHeight,
+ &ConsBufferInfo.dwCursorPosition);
+
+ if (sc.ScreenState == WINDOWED)
+ enableUpdates();
+
+ MouseAttachMenuItem(sc.ActiveOutputBufferHandle);
+ host_stream_io_enabled = FALSE;
+}