diff options
Diffstat (limited to '')
-rw-r--r-- | private/mvdm/softpc.new/host/src/sim32.c | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/host/src/sim32.c b/private/mvdm/softpc.new/host/src/sim32.c new file mode 100644 index 000000000..5bcfcf37d --- /dev/null +++ b/private/mvdm/softpc.new/host/src/sim32.c @@ -0,0 +1,462 @@ +/* + * sim32.c - Sim32 for Microsoft NT SoftPC. + * + * Ade Brownlow + * Wed Jun 5 91 + * + * %W% %G% (c) Insignia Solutions 1991 + * + * This module provides the Microsoft sim32 interface with the additional sas + * functionality and some host sas routines. We also provide cpu idling facilities. + * + * This module in effect provides (along with the cpu) what Microsoft term as the IEU - + * see documentation. + */ + +#ifdef SIM32 + +#ifdef CPU_40_STYLE +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#endif /* CPU_40_STYLE */ + +#include <windows.h> +#include "insignia.h" +#include "host_def.h" + +#include <stdlib.h> +#include <stdio.h> +#include "xt.h" +#include "sim32.h" +#include "sas.h" +#include "gmi.h" +#include "ckmalloc.h" +#include CpuH + + +#ifdef CPU_40_STYLE +#include "nt_mem.h" +#endif /* CPU_40_STYLE */ + +/********************************************************/ +/* IMPORTS & EXPORTS */ + +/* Sas/gmi Sim32 crossovers */ +GLOBAL BOOL Sim32FlushVDMPointer (double_word, word, UTINY *, BOOL); +GLOBAL BOOL Sim32FreeVDMPointer (double_word, word, UTINY *, BOOL); +GLOBAL BOOL Sim32GetVDMMemory (double_word, word, UTINY *, BOOL); +GLOBAL BOOL Sim32SetVDMMemory (double_word, word, UTINY *, BOOL); +GLOBAL sys_addr sim32_effective_addr (double_word, BOOL); + +GLOBAL UTINY *sas_alter_size(sys_addr); +GLOBAL UTINY *host_sas_init(sys_addr); +GLOBAL UTINY *host_sas_term(void); + +/* Microsoft sas extensions */ +GLOBAL IMEMBLOCK *sas_mem_map (void); +GLOBAL void sas_clear_map(void); + +IMPORT ULONG Sas_wrap_mask; + + + +#ifndef MONITOR +// +// Pointer to a scratch video buffer. Updated by sim32 routines +// when intel video addr is requested. + +IU8 *ScratchVideoBuffer = 0; +#define VIDEO_REGEN_START 0xa0000 +#define VIDEO_REGEN_END 0xbffff +#define VID_BUFF_SIZE 0x20000 + + +#define IsVideoMemory(LinAddr) \ + ((LinAddr) >= VIDEO_REGEN_START && (LinAddr) <= VIDEO_REGEN_END) + + +IU8 *GetVideoMemory(ULONG iaddr) +{ + + // + // If there isn't a video scratch buffer, allocate one. + // This will stick around until ntvdm terminates. Could be + // optimized to free the buffer when not in use. + // + if (!ScratchVideoBuffer) { + ScratchVideoBuffer = malloc(VID_BUFF_SIZE); + if (!ScratchVideoBuffer) { + return NULL; + } + } + + // + // We could do this more efficiently, by only copying + // minimum area needed, but then we need to keep track of + // what to update on the flush and do ref counting. + // Since video memory access by host code is rare + // (only seen in demWrite\demRead so far) be simple minded. + // + sas_loads (VIDEO_REGEN_START, + ScratchVideoBuffer, + VID_BUFF_SIZE + ); + + return ScratchVideoBuffer + (iaddr - VIDEO_REGEN_START); +} + + +BOOL SetVideoMemory(ULONG iaddr) +{ + ULONG VideoOffset = iaddr - VIDEO_REGEN_START; + + if (!ScratchVideoBuffer) { + return FALSE; + } + + sas_stores(iaddr, + ScratchVideoBuffer + VideoOffset, + VID_BUFF_SIZE - VideoOffset + ); + + return TRUE; +} + +#endif + + + +/********************************************************/ +/* MACROS */ +/* macro to convert the supplied address to intel address */ +#define convert_addr(a,b,c,d) \ + { \ + if ((a = sim32_effective_addr (b,c)) == (sys_addr)-1)\ + {\ + return (d);\ + }\ + } + +/********************************************************/ +/* The actual sim32 interfaces, most of these routines can be more or less mapped directly + * to existing routines in sas or gmi. + * + * WARNING: This routine returns a pointer into M, and + * WILL NOT work for backward M. + */ +UCHAR *Sim32pGetVDMPointer(ULONG addr, UCHAR pm) +{ + sys_addr iaddr; + + if (pm && (addr == 0)) + return(NULL); + + convert_addr (iaddr, addr, pm, NULL); +//STF - need sas_wrap_mask with PE....iaddr &= Sas_wrap_mask; + + if (IsVideoMemory(iaddr)) { + return GetVideoMemory(iaddr); + } + + return (NtGetPtrToLinAddrByte(iaddr)); +} + +/* + * See Sim32pGetVDMPointer + * + * This call must be maintaned as is because it is exported for VDD's + * in product 1.0. + */ +UCHAR *ExpSim32GetVDMPointer IFN3(double_word, addr, double_word, size, UCHAR, pm) +{ + return Sim32pGetVDMPointer(addr, (UCHAR)pm); +} + + +GLOBAL BOOL Sim32FlushVDMPointer IFN4(double_word, addr, word, size, UTINY *, buff, BOOL, pm) +{ + sys_addr iaddr; + convert_addr (iaddr, addr, pm, 0); + +//STF - need sas_wrap_mask with PE....iaddr &= Sas_wrap_mask; + +#ifndef MONITOR + if (IsVideoMemory(iaddr) && !SetVideoMemory(iaddr)) { + return FALSE; + } +#endif //MONITOR + + + sas_overwrite_memory(iaddr, (ULONG)size); + return (TRUE); +} + + +GLOBAL BOOL Sim32FreeVDMPointer IFN4(double_word, addr, word, size, UTINY *, buff, BOOL, pm) +{ + /* we haven't allocated any new memory so always return success */ + return (TRUE); +} + +GLOBAL BOOL Sim32GetVDMMemory IFN4(double_word, addr, word, size, UTINY *, buff, BOOL, pm) +{ + sys_addr iaddr; + convert_addr (iaddr, addr, pm, FALSE); + /* effectivly a sas_loads */ + sas_loads (iaddr, buff, (sys_addr)size); + + /* always return success */ + return (TRUE); +} + +GLOBAL BOOL Sim32SetVDMMemory IFN4(double_word, addr, word, size, UTINY *, buff, BOOL, pm) +{ + sys_addr iaddr; + convert_addr (iaddr, addr, pm, FALSE); + /* effectivly a sas_stores */ + sas_stores (iaddr, buff, (sys_addr)size); + + /* always return success */ + return (TRUE); +} + +/********************************************************/ +/* Support routines for sim32 above */ +GLOBAL sys_addr sim32_effective_addr IFN2(double_word, addr, BOOL, pm) +{ + word seg, off; + double_word descr_addr; + DESCR entry; + + seg = (word)(addr>>16); + off = (word)(addr & 0xffff); + + if (pm == FALSE) + { + return ((double_word)seg << 4) + off; + } + else + { + if ( selector_outside_table(seg, &descr_addr) == 1 ) + { + /* + This should not happen, but is a check the real effective_addr + includes. Return error -1. + */ +#ifndef PROD + printf("NTVDM:sim32:effective addr: Error for addr %#x (seg %#x)\n",addr, seg); + HostDebugBreak(); +#endif + return ((sys_addr)-1); + } + else + { + read_descriptor(descr_addr, &entry); + return entry.base + off; + } + } +} + + +/********************************************************/ +/* Microsoft extensions to sas interface */ +LOCAL IMEMBLOCK *imap_start=NULL, *imap_end=NULL; +GLOBAL IMEMBLOCK *sas_mem_map () +{ + /* produce a memory map for the whole of intel space */ + sys_addr iaddr; + int mem_type; + + if (imap_start) + sas_clear_map(); + + for (iaddr=0; iaddr < Length_of_M_area; iaddr++) + { + mem_type = sas_memory_type (iaddr); + if (!imap_end) + { + /* this is the first record */ + check_malloc (imap_start, 1, IMEMBLOCK); + imap_start->Next = NULL; + imap_end = imap_start; + imap_end->Type = mem_type; + imap_end->StartAddress = iaddr; + continue; + } + if (imap_end->Type != mem_type) + { + /* end of a memory section & start of a new one */ + imap_end->EndAddress = iaddr-1; + check_malloc (imap_end->Next, 1,IMEMBLOCK); + imap_end = imap_end->Next; + imap_end->Next = NULL; + imap_end->Type =mem_type; + imap_end->StartAddress = iaddr; + } + } + /* terminate last record */ + imap_end->EndAddress = iaddr; + return (imap_start); +} + +GLOBAL void sas_clear_map() +{ + IMEMBLOCK *p, *q; + for (p=imap_start; p; p=q) + { + q=p->Next; + free(p); + } + imap_start=imap_end=NULL; +} + +/********************************************************/ +/* Microsoft specific sas stuff (ie host sas) */ + +#define SIXTEENMEG 1024*1024*12 + +LOCAL UTINY *reserve_for_sas = NULL; + +#ifndef CPU_40_STYLE + +LOCAL sys_addr current_sas_size =0; /* A local Length_of_M_area */ + +GLOBAL UTINY *host_sas_init IFN1(sys_addr, size) +{ + UTINY *rez; + DWORD M_plus_type_size; + + /* allocate 16 MEG of virtual memory */ + if (!reserve_for_sas) + { + if (!(reserve_for_sas = (UTINY *)VirtualAlloc ((void *)NULL, SIXTEENMEG, + MEM_RESERVE, PAGE_READWRITE))) + { +#ifndef PROD + printf ("NTVDM:Failed to reserve 16 Meg virtual memory for sas\n"); +#endif + exit (0); + } + } + + /* now commit to our size */ + M_plus_type_size = size + NOWRAP_PROTECTION + + ((size + NOWRAP_PROTECTION) >> 12); + rez = (UTINY *)VirtualAlloc ((void *) reserve_for_sas, + M_plus_type_size, + MEM_COMMIT, + PAGE_READWRITE); + if (rez) + Length_of_M_area = current_sas_size = size; + return (rez); + +} + + +GLOBAL UTINY *host_sas_term() +{ + if (!reserve_for_sas) + return (NULL); + + /* deallocate the reserves */ + VirtualFree (reserve_for_sas, SIXTEENMEG, MEM_RELEASE); + + /* null out reserve pointer */ + reserve_for_sas = NULL; + + Length_of_M_area = current_sas_size = 0; + + return (NULL); +} + +GLOBAL UTINY *sas_alter_size IFN1(sys_addr, new) +{ + UTINY *tmp; + if (!reserve_for_sas) + { +#ifndef PROD + printf ("NTVDM:Sas trying to alter size before reserve setup\n"); +#endif + return (NULL); + } + + /* if we are already at the right size return success */ + if (new == current_sas_size) + { + return (reserve_for_sas); + } + + if (new > current_sas_size) + { + /* move to end of current commited area */ + tmp = reserve_for_sas + current_sas_size; + if (!VirtualAlloc ((void *)tmp, (DWORD)(new - current_sas_size), MEM_COMMIT, + PAGE_READWRITE)) + { + printf ("NTVDM:Virtual Allocate for resize from %d to %d FAILED!\n", + current_sas_size, new); + return (NULL); + } + } + else + { + /* move to the place where sas needs to end */ + tmp = reserve_for_sas + new; + + /* now decommit the unneeded memory */ + if (!VirtualFree ((void *)tmp, (DWORD)(current_sas_size - new), MEM_DECOMMIT)) + { + printf ("NTVDM:Virtual Allocate for resize from %d to %d FAILED!\n", + current_sas_size, new); + return (NULL); + } + } + Length_of_M_area = current_sas_size = new; + return (reserve_for_sas); +} + + + +#else /* CPU_40_STYLE */ + + +// Intel space allocation and deallocation control function for the A4 CPU + +GLOBAL UTINY *host_sas_init IFN1(sys_addr, size) +{ + + /* Initialise memory management system and allocation bottom 1M+64K */ + if(!(Start_of_M_area = InitIntelMemory(size))) + { + /* Initialise function failed, exit */ +#ifndef PROD + printf ("NTVDM:Failed to allocate virtual memory for sas\n"); +#endif + + exit(0); + } + + Length_of_M_area = size; + return(Start_of_M_area); +} + + +GLOBAL UTINY *host_sas_term() +{ + /* Has any Intel memory been allocated ? */ + if(Start_of_M_area) + { + /* Free allocated intel memory and control structures */ + FreeIntelMemory(); + + reserve_for_sas = NULL; /* null out reserve pointer */ + Length_of_M_area = 0; + } + + return(NULL); +} + +#endif /* CPU_40_STYLE */ + +#endif /* SIM32 */ |