MCPcopy Create free account
hub / github.com/AppleWin/AppleWin / AllocMemImage

Function AllocMemImage

source/Memory.cpp:1881–1987  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1879}
1880
1881static LPBYTE AllocMemImage(void)
1882{
1883#ifdef _WIN32
1884 LPBYTE baseAddr = NULL;
1885
1886 // Allocate memory for 'memimage' (and the alias 'mem')
1887 // . Setup so we have 2 consecutive virtual 64K regions pointing to the same physical 64K region.
1888 // . This is a fix (and optimisation) for 6502 opcodes that do a 16-bit read at 6502 address $FFFF. (GH#1285)
1889 SYSTEM_INFO info;
1890 GetSystemInfo(&info);
1891 bool res = (info.dwAllocationGranularity == _6502_MEM_LEN);
1892
1893 if (res)
1894 {
1895 UINT retry = 10;
1896 do
1897 {
1898 res = false;
1899 const SIZE_T totalVirtualSize = _6502_MEM_LEN * num64KPages;
1900 baseAddr = (LPBYTE)VirtualAlloc(0, totalVirtualSize, MEM_RESERVE, PAGE_NOACCESS);
1901 if (baseAddr == NULL)
1902 break;
1903 VirtualFree(baseAddr, 0, MEM_RELEASE);
1904
1905 // Create a file mapping object of [64K] size that is backed by the system paging file.
1906 g_hMemImage = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, _6502_MEM_LEN, NULL);
1907 // NB. Returns NULL on failure (not INVALID_HANDLE_VALUE)
1908 if (g_hMemImage == NULL)
1909 break;
1910
1911 UINT count = 0;
1912 while (count < num64KPages)
1913 {
1914 // MSDN: "To specify a suggested base address for the view, use the MapViewOfFileEx function. However, this practice is not recommended."
1915 // The OS (ie. another process) may've beaten us to this suggested baseAddr. This is why we retry multiple times.
1916 if (!MapViewOfFileEx(g_hMemImage, FILE_MAP_ALL_ACCESS, 0, 0, _6502_MEM_LEN, baseAddr + count * _6502_MEM_LEN))
1917 break;
1918 count++;
1919 }
1920
1921 res = (count == num64KPages);
1922 if (res)
1923 break;
1924
1925 // Failed this time, so clean-up and retry...
1926 FreeMemImage();
1927 }
1928 while (retry--);
1929
1930#if 1
1931 if (res) // test
1932 {
1933 baseAddr[0x0000] = 0x11;
1934 baseAddr[0xffff] = 0x22;
1935 USHORT value = *((USHORT*)(baseAddr + 0xffff));
1936 _ASSERT(value == 0x1122);
1937 }
1938#endif

Callers 1

MemInitializeFunction · 0.85

Calls 2

FreeMemImageFunction · 0.85
LogFileOutputFunction · 0.85

Tested by

no test coverage detected