mirror of
https://github.com/holub/mame
synced 2025-04-21 16:01:56 +03:00
Merge pull request #509 from ajrhacker/master
Refactoring memory map validity checking [ARJ]
This commit is contained in:
commit
7e4ff974ac
2
3rdparty/genie/src/actions/make/make_cpp.lua
vendored
2
3rdparty/genie/src/actions/make/make_cpp.lua
vendored
@ -359,7 +359,7 @@
|
||||
|
||||
if #cfg.forcedincludes > 0 then
|
||||
_p(' FORCE_INCLUDE += -include %s'
|
||||
,premake.esc(table.concat(cfg.forcedincludes, ";")))
|
||||
,_MAKE.esc(table.concat(cfg.forcedincludes, ";")))
|
||||
end
|
||||
|
||||
_p(' ALL_CPPFLAGS += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), " "))
|
||||
|
2
3rdparty/genie/src/host/scripts.c
vendored
2
3rdparty/genie/src/host/scripts.c
vendored
@ -197,7 +197,7 @@ const char* builtin_scripts[] = {
|
||||
"NT = @')\n_p('endif')\n_p('')\n_p('SHELLTYPE := msdos')\n_p('ifeq (,$(ComSpec)$(COMSPEC))')\n_p(' SHELLTYPE := posix')\n_p('endif')\n_p('ifeq (/bin,$(findstring /bin,$(SHELL)))')\n_p(' SHELLTYPE := posix')\n_p('endif')\n_p('ifeq (/bin,$(findstring /bin,$(MAKESHELL)))')\n_p(' SHELLTYPE := posix')\n_p('endif')\n_p('')\n_p('ifeq (posix,$(SHELLTYPE))')\n_p(' MKDIR = $(SILENT) mkdir -p \"$(1)\"')\n_p(' COPY = $(SILENT) cp -fR \"$(1)\" \"$(2)\"')\n_p(' RM= $(SILENT) rm -f \"$(1)\"')\n_p('else')\n_p(' MKDIR = $(SILENT) mkdir \"$(subst /,\\\\\\\\,$(1))\" 2> nul || exit 0')\n_p(' COPY = $(SILENT) copy /Y \"$(subst /,\\\\\\\\,$(1))\" \"$(subst /,\\\\\\\\,$(2))\"')\n_p(' RM = $(SILENT) del /F \"$(subst /,\\\\\\\\,$(1))\" 2> nul || exit 0')\n_p('endif')\n_p('')\n_p('CC = %s', cc.cc)\n_p('CXX = %s', cc.cxx)\n_p('AR = %s', cc.ar)\n_p('')\n_p('ifndef RESCOMP')\n_p(' ifdef WINDRES')\n_p(' RESCOMP = $(WINDRES)')\n_p(' else')\n_p(' RESCOMP = windres')\n_p(' endif')\n_p('endif')\n_p('')\nend\nfunction pr"
|
||||
"emake.gmake_cpp_config(prj, cfg, cc)\n_p('ifeq ($(config),%s)', _MAKE.esc(cfg.shortname))\ncpp.platformtools(cfg, cc)\n_p(' ' .. (table.contains(premake.make.override,\"OBJDIR\") and \"override \" or \"\") .. 'OBJDIR = %s', _MAKE.esc(cfg.objectsdir))\n_p(' ' .. (table.contains(premake.make.override,\"TARGETDIR\") and \"override \" or \"\") .. 'TARGETDIR = %s', _MAKE.esc(cfg.buildtarget.directory))\n_p(' ' .. (table.contains(premake.make.override,\"TARGET\") and \"override \" or \"\") .. 'TARGET = $(TARGETDIR)/%s', _MAKE.esc(cfg.buildtarget.name))\n_p(' DEFINES +=%s', make.list(cc.getdefines(cfg.defines)))\n_p(' INCLUDES +=%s', make.list(cc.getincludedirs(cfg.includedirs)))\ncpp.pchconfig(cfg)\ncpp.flags(cfg, cc)\ncpp.linker(prj, cfg, cc)\n_p(' OBJECTS := \\\\')\nfor _, file in ipairs(prj.files) do\nif path.iscppfile(file) then\nif not table.icontains(cfg.excludes, file) then\n_p('\\t$(OBJDIR)/%s.o \\\\'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n)\nend\nend\nend\n_p('')\n_p(' d"
|
||||
"efine PREBUILDCMDS')\nif #cfg.prebuildcommands > 0 then\n_p('\\t@echo Running pre-build commands')\n_p('\\t%s', table.implode(cfg.prebuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p(' endef')\n_p(' define PRELINKCMDS')\nif #cfg.prelinkcommands > 0 then\n_p('\\t@echo Running pre-link commands')\n_p('\\t%s', table.implode(cfg.prelinkcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p(' endef')\n_p(' define POSTBUILDCMDS')\nif #cfg.postbuildcommands > 0 then\n_p('\\t@echo Running post-build commands')\n_p('\\t%s', table.implode(cfg.postbuildcommands, \"\", \"\", \"\\n\\t\"))\nend\n_p(' endef')\nmake.settings(cfg, cc)\n_p('endif')\n_p('')\nend\nfunction cpp.platformtools(cfg, cc)\nlocal platform = cc.platforms[cfg.platform]\nif platform.cc then\n_p(' CC = %s', platform.cc)\nend\nif platform.cxx then\n_p(' CXX = %s', platform.cxx)\nend\nif platform.ar then\n_p(' AR = %s', platform.ar)\nend\nend\nfunction cpp.flags(cfg, cc)\nif cfg.pchheader and not cfg.flags.NoPCH then\n_p(' FORCE_INCLUDE +="
|
||||
"-include $(OBJDIR)/$(notdir $(PCH))')\nend\nif #cfg.forcedincludes > 0 then\n_p(' FORCE_INCLUDE += -include %s'\n,premake.esc(table.concat(cfg.forcedincludes, \";\")))\nend\n_p(' ALL_CPPFLAGS += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), \" \"))\n_p(' ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))\n_p(' ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_cpp)))\n_p(' ALL_OBJCFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_objc)))\n_p(' ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',\n make.list(table.join(cc.getdefines(cfg.resdefines),\n cc.getincludedirs(cfg.resincludedirs), cfg.resoptions)))\nend\nfunction cpp.linker(prj, cfg"
|
||||
"-include $(OBJDIR)/$(notdir $(PCH))')\nend\nif #cfg.forcedincludes > 0 then\n_p(' FORCE_INCLUDE += -include %s'\n,_MAKE.esc(table.concat(cfg.forcedincludes, \";\")))\nend\n_p(' ALL_CPPFLAGS += $(CPPFLAGS) %s $(DEFINES) $(INCLUDES)', table.concat(cc.getcppflags(cfg), \" \"))\n_p(' ALL_CFLAGS += $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cfg.buildoptions, cfg.buildoptions_c)))\n_p(' ALL_CXXFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_cpp)))\n_p(' ALL_OBJCFLAGS += $(CXXFLAGS) $(CFLAGS) $(ALL_CPPFLAGS) $(ARCH)%s', make.list(table.join(cc.getcflags(cfg), cc.getcxxflags(cfg), cfg.buildoptions, cfg.buildoptions_objc)))\n_p(' ALL_RESFLAGS += $(RESFLAGS) $(DEFINES) $(INCLUDES)%s',\n make.list(table.join(cc.getdefines(cfg.resdefines),\n cc.getincludedirs(cfg.resincludedirs), cfg.resoptions)))\nend\nfunction cpp.linker(prj, cfg"
|
||||
", cc)\n_p(' ALL_LDFLAGS += $(LDFLAGS)%s', make.list(table.join(cc.getlibdirflags(cfg), cc.getldflags(cfg), cfg.linkoptions)))\n_p(' LDDEPS +=%s', make.list(_MAKE.esc(premake.getlinks(cfg, \"siblings\", \"fullpath\"))))\n_p(' LIBS += $(LDDEPS)%s', make.list(cc.getlinkflags(cfg)))\nif cfg.kind == \"StaticLib\" then\nif cfg.platform:startswith(\"Universal\") then\n_p(' LINKCMD = libtool -o $(TARGET)')\nelse\nif (not prj.options.ArchiveSplit) then\nif cc.llvm then\n_p(' LINKCMD = $(AR) rcs $(TARGET)')\nelse\n_p(' LINKCMD = $(AR) -rcs $(TARGET)')\nend\nelse\nif cc.llvm then\n_p(' LINKCMD = $(AR) qc $(TARGET)')\n_p(' LINKCMD_NDX= $(AR) cs $(TARGET)')\nelse\n_p(' LINKCMD = $(AR) -qc $(TARGET)')\n_p(' LINKCMD_NDX= $(AR) -cs $(TARGET)')\nend\nend\nend\nelse\nlocal tool = iif(cfg.language == \"C\", \"CC\", \"CXX\")\n_p(' LINKCMD = $(%s) -o $(TARGET) $(OBJECTS) $(RESOURCES) $(ARCH) $(ALL_LDFLAGS) $(LIBS)', tool)\nend\nend\nfunction cpp.pchconfig(cfg)\nif not cfg.pchheader or cfg.fla"
|
||||
"gs.NoPCH then\nreturn\nend\nlocal pch = cfg.pchheader\nfor _, incdir in ipairs(cfg.includedirs) do\nlocal abspath = path.getabsolute(path.join(cfg.project.location, incdir))\nlocal testname = path.join(abspath, pch)\nif os.isfile(testname) then\npch = path.getrelative(cfg.location, testname)\nbreak\nend\nend\n_p(' PCH = %s', _MAKE.esc(pch))\n_p(' GCH = $(OBJDIR)/$(notdir $(PCH)).gch')\nend\nfunction cpp.pchrules(prj)\n_p('ifneq (,$(PCH))')\n_p('$(GCH): $(PCH)')\n_p('\\t@echo $(notdir $<)')\nlocal cmd = iif(prj.language == \"C\", \"$(CC) -x c-header $(ALL_CFLAGS)\", \"$(CXX) -x c++-header $(ALL_CXXFLAGS)\")\n_p('\\t$(SILENT) %s -MMD -MP $(DEFINES) $(INCLUDES) -o \"$@\" -MF \"$(@:%%.gch=%%.d)\" -c \"$<\"', cmd)\n_p('endif')\n_p('')\nend\nfunction cpp.fileRules(prj)\nfor _, file in ipairs(prj.files or {}) do\nif path.iscppfile(file) then\n_p('$(OBJDIR)/%s.o: %s'\n, _MAKE.esc(path.trimdots(path.removeext(file)))\n, _MAKE.esc(file)\n)\nif (path.isobjcfile(file) and prj.msgcompile_objc) then\n_p('\\t"
|
||||
"@echo ' .. prj.msgcompile_objc)\nelseif prj.msgcompile then\n_p('\\t@echo ' .. prj.msgcompile)\nelse\n_p('\\t@echo $(notdir $<)')\nend\nif (path.isobjcfile(file)) then\n_p('\\t$(SILENT) $(CXX) $(ALL_OBJCFLAGS) $(FORCE_INCLUDE) -o \"$@\" -MF $(@:%%.o=%%.d) -c \"$<\"')\nelse\ncpp.buildcommand(path.iscfile(file) and not prj.options.ForceCPP, \"o\")\nend\nfor _, task in ipairs(prj.postcompiletasks or {}) do\n_p('\\t$(SILENT) %s', task)\n_p('')\nend\n_p('')\nelseif (path.getextension(file) == \".rc\") then\n_p('$(OBJDIR)/%s.res: %s', _MAKE.esc(path.getbasename(file)), _MAKE.esc(file))\nif prj.msgresource then\n_p('\\t@echo ' .. prj.msgresource)\nelse\n_p('\\t@echo $(notdir $<)')\nend\n_p('\\t$(SILENT) $(RESCOMP) $< -O coff -o \"$@\" $(ALL_RESFLAGS)')\n_p('')\nend\nend\nend\nfunction cpp.dependencyRules(prj)\nfor _, dependency in ipairs(prj.dependency or {}) do\nfor _, dep in ipairs(dependency or {}) do\nif (dep[3]==nil or dep[3]==false) then\n_p('$(OBJDIR)/%s.o: %s'\n, _MAKE.esc(path.trimdots(path.removeext(path.ge"
|
||||
|
@ -9,7 +9,6 @@ newoption {
|
||||
premake.check_paths = true
|
||||
premake.make.override = { "TARGET" }
|
||||
MAME_DIR = (path.getabsolute("..") .. "/")
|
||||
MAME_DIR = string.gsub(MAME_DIR, "(%s)", "\\%1")
|
||||
local MAME_BUILD_DIR = (MAME_DIR .. _OPTIONS["build-dir"] .. "/")
|
||||
local naclToolchain = ""
|
||||
|
||||
@ -527,9 +526,9 @@ if (_OPTIONS["SOURCES"] == nil) then
|
||||
end
|
||||
dofile (path.join("target", _OPTIONS["target"],_OPTIONS["subtarget"] .. ".lua"))
|
||||
else
|
||||
OUT_STR = os.outputof( PYTHON .. " " .. MAME_DIR .. "scripts/build/makedep.py " .. MAME_DIR .. " " .. _OPTIONS["SOURCES"] .. " target " .. _OPTIONS["subtarget"])
|
||||
OUT_STR = os.outputof( PYTHON .. " " .. _MAKE.esc(MAME_DIR) .. "scripts/build/makedep.py " .. _MAKE.esc(MAME_DIR) .. " " .. _OPTIONS["SOURCES"] .. " target " .. _OPTIONS["subtarget"])
|
||||
load(OUT_STR)()
|
||||
os.outputof( PYTHON .. " " .. MAME_DIR .. "scripts/build/makedep.py " .. MAME_DIR .. " " .. _OPTIONS["SOURCES"] .. " drivers " .. _OPTIONS["subtarget"] .. " > ".. GEN_DIR .. _OPTIONS["target"] .. "/" .. _OPTIONS["subtarget"].."/drivlist.cpp")
|
||||
os.outputof( PYTHON .. " " .. _MAKE.esc(MAME_DIR) .. "scripts/build/makedep.py " .. _MAKE.esc(MAME_DIR) .. " " .. _OPTIONS["SOURCES"] .. " drivers " .. _OPTIONS["subtarget"] .. " > " .. _MAKE.esc(GEN_DIR) .. _OPTIONS["target"] .. "/" .. _OPTIONS["subtarget"] .. "/drivlist.cpp")
|
||||
end
|
||||
configuration { "gmake" }
|
||||
flags {
|
||||
|
@ -88,7 +88,7 @@ end
|
||||
targetextension ".bc"
|
||||
if os.getenv("EMSCRIPTEN") then
|
||||
postbuildcommands {
|
||||
os.getenv("EMSCRIPTEN") .. "/emcc -O3 -s DISABLE_EXCEPTION_CATCHING=2 -s USE_SDL=2 --memory-init-file 0 -s ALLOW_MEMORY_GROWTH=0 -s TOTAL_MEMORY=268435456 -s EXCEPTION_CATCHING_WHITELIST='[\"__ZN15running_machine17start_all_devicesEv\"]' -s EXPORTED_FUNCTIONS=\"['_main', '_malloc', '__Z14js_get_machinev', '__Z9js_get_uiv', '__Z12js_get_soundv', '__ZN10ui_manager12set_show_fpsEb', '__ZNK10ui_manager8show_fpsEv', '__ZN13sound_manager4muteEbh', '_SDL_PauseAudio']\" $(TARGET) -o " .. MAME_DIR .. _OPTIONS["target"] .. _OPTIONS["subtarget"] .. ".js --post-js " .. MAME_DIR .. "src/osd/sdl/emscripten_post.js",
|
||||
os.getenv("EMSCRIPTEN") .. "/emcc -O3 -s DISABLE_EXCEPTION_CATCHING=2 -s USE_SDL=2 --memory-init-file 0 -s ALLOW_MEMORY_GROWTH=0 -s TOTAL_MEMORY=268435456 -s EXCEPTION_CATCHING_WHITELIST='[\"__ZN15running_machine17start_all_devicesEv\"]' -s EXPORTED_FUNCTIONS=\"['_main', '_malloc', '__Z14js_get_machinev', '__Z9js_get_uiv', '__Z12js_get_soundv', '__ZN10ui_manager12set_show_fpsEb', '__ZNK10ui_manager8show_fpsEv', '__ZN13sound_manager4muteEbh', '_SDL_PauseAudio']\" $(TARGET) -o " .. _MAKE.esc(MAME_DIR) .. _OPTIONS["target"] .. _OPTIONS["subtarget"] .. ".js --post-js " .. _MAKE.esc(MAME_DIR) .. "src/osd/sdl/emscripten_post.js",
|
||||
}
|
||||
end
|
||||
|
||||
@ -197,13 +197,13 @@ end
|
||||
|
||||
if _OPTIONS["targetos"]=="macosx" and (not override_resources) then
|
||||
linkoptions {
|
||||
"-sectcreate __TEXT __info_plist " .. GEN_DIR .. "/resource/" .. _subtarget .. "-Info.plist"
|
||||
"-sectcreate __TEXT __info_plist " .. _MAKE.esc(GEN_DIR) .. "resource/" .. _subtarget .. "-Info.plist"
|
||||
}
|
||||
custombuildtask {
|
||||
{ MAME_DIR .. "src/version.cpp" , GEN_DIR .. "/resource/" .. _subtarget .. "-Info.plist", { MAME_DIR .. "scripts/build/verinfo.py" }, {"@echo Emitting " .. _subtarget .. "-Info.plist" .. "...", PYTHON .. " $(1) -p -b " .. _subtarget .. " $(<) > $(@)" }},
|
||||
{ MAME_DIR .. "src/version.cpp" , GEN_DIR .. "resource/" .. _subtarget .. "-Info.plist", { MAME_DIR .. "scripts/build/verinfo.py" }, {"@echo Emitting " .. _subtarget .. "-Info.plist" .. "...", PYTHON .. " $(1) -p -b " .. _subtarget .. " $(<) > $(@)" }},
|
||||
}
|
||||
dependency {
|
||||
{ "$(TARGET)" , GEN_DIR .. "/resource/" .. _subtarget .. "-Info.plist", true },
|
||||
{ "$(TARGET)" , GEN_DIR .. "resource/" .. _subtarget .. "-Info.plist", true },
|
||||
}
|
||||
|
||||
end
|
||||
@ -219,7 +219,7 @@ end
|
||||
rcfile,
|
||||
}
|
||||
dependency {
|
||||
{ "$(OBJDIR)/".._subtarget ..".res" , GEN_DIR .. "/resource/" .. rctarget .. "vers.rc", true },
|
||||
{ "$(OBJDIR)/".._subtarget ..".res" , GEN_DIR .. "resource/" .. rctarget .. "vers.rc", true },
|
||||
}
|
||||
else
|
||||
rctarget = "mame"
|
||||
@ -227,7 +227,7 @@ end
|
||||
MAME_DIR .. "src/mame/osd/windows/mame/mame.rc",
|
||||
}
|
||||
dependency {
|
||||
{ "$(OBJDIR)/mame.res" , GEN_DIR .. "/resource/" .. rctarget .. "vers.rc", true },
|
||||
{ "$(OBJDIR)/mame.res" , GEN_DIR .. "resource/" .. rctarget .. "vers.rc", true },
|
||||
}
|
||||
end
|
||||
end
|
||||
@ -261,14 +261,14 @@ if _OPTIONS["FORCE_VERSION_COMPILE"]=="1" then
|
||||
end
|
||||
configuration { "mingw*" }
|
||||
custombuildtask {
|
||||
{ MAME_DIR .. "src/version.cpp" , GEN_DIR .. "/resource/" .. rctarget .. "vers.rc", { MAME_DIR .. "scripts/build/verinfo.py" }, {"@echo Emitting " .. rctarget .. "vers.rc" .. "...", PYTHON .. " $(1) -r -b " .. rctarget .. " $(<) > $(@)" }},
|
||||
{ MAME_DIR .. "src/version.cpp" , GEN_DIR .. "resource/" .. rctarget .. "vers.rc", { MAME_DIR .. "scripts/build/verinfo.py" }, {"@echo Emitting " .. rctarget .. "vers.rc" .. "...", PYTHON .. " $(1) -r -b " .. rctarget .. " $(<) > $(@)" }},
|
||||
}
|
||||
|
||||
configuration { "vs*" }
|
||||
prebuildcommands {
|
||||
"mkdir " .. path.translate(GEN_DIR .. "/resource/","\\") .. " 2>NUL",
|
||||
"mkdir " .. path.translate(GEN_DIR .. "resource/","\\") .. " 2>NUL",
|
||||
"@echo Emitting ".. rctarget .. "vers.rc...",
|
||||
PYTHON .. " " .. path.translate(MAME_DIR .. "scripts/build/verinfo.py","\\") .. " -r -b " .. rctarget .. " " .. path.translate(MAME_DIR .. "src/version.cpp","\\") .. " > " .. path.translate(GEN_DIR .. "/resource/" .. rctarget .. "vers.rc", "\\") ,
|
||||
PYTHON .. " " .. path.translate(MAME_DIR .. "scripts/build/verinfo.py","\\") .. " -r -b " .. rctarget .. " " .. path.translate(MAME_DIR .. "src/version.cpp","\\") .. " > " .. path.translate(GEN_DIR .. "resource/" .. rctarget .. "vers.rc", "\\") ,
|
||||
}
|
||||
|
||||
|
||||
|
@ -9,6 +9,15 @@
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "validity.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// PARAMETERS
|
||||
//**************************************************************************
|
||||
|
||||
#define DETECT_OVERLAPPING_MEMORY (0)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -332,7 +341,7 @@ address_map::address_map(device_t &device, address_spacenum spacenum)
|
||||
|
||||
// and then the configuration for the current address space
|
||||
const address_space_config *spaceconfig = memintf->space_config(spacenum);
|
||||
if (!device.interface(memintf))
|
||||
if (spaceconfig == nullptr)
|
||||
throw emu_fatalerror("No memory address space configuration found for device '%s', space %d\n", device.tag(), spacenum);
|
||||
|
||||
// construct the internal device map (first so it takes priority)
|
||||
@ -614,3 +623,145 @@ void address_map::uplift_submaps(running_machine &machine, device_t &device, dev
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// map_validity_check - perform validity checks on
|
||||
// one of the device's address maps
|
||||
//-------------------------------------------------
|
||||
|
||||
void address_map::map_validity_check(validity_checker &valid, const device_t &device, address_spacenum spacenum) const
|
||||
{
|
||||
// it's safe to assume here that the device has a memory interface and a config for this space
|
||||
const address_space_config &spaceconfig = *device.memory().space_config(spacenum);
|
||||
int datawidth = spaceconfig.m_databus_width;
|
||||
int alignunit = datawidth / 8;
|
||||
|
||||
bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true;
|
||||
|
||||
// if this is an empty map, just ignore it
|
||||
if (m_entrylist.first() == nullptr)
|
||||
return;
|
||||
|
||||
// validate the global map parameters
|
||||
if (m_spacenum != spacenum)
|
||||
osd_printf_error("Space %d has address space %d handlers!\n", spacenum, m_spacenum);
|
||||
if (m_databits != datawidth)
|
||||
osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig.m_name, datawidth, m_databits);
|
||||
|
||||
// loop over entries and look for errors
|
||||
for (address_map_entry *entry = m_entrylist.first(); entry != nullptr; entry = entry->next())
|
||||
{
|
||||
UINT32 bytestart = spaceconfig.addr2byte(entry->m_addrstart);
|
||||
UINT32 byteend = spaceconfig.addr2byte_end(entry->m_addrend);
|
||||
|
||||
// look for overlapping entries
|
||||
if (!detected_overlap)
|
||||
{
|
||||
for (address_map_entry *scan = m_entrylist.first(); scan != entry; scan = scan->next())
|
||||
if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart &&
|
||||
((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) ||
|
||||
(entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE)))
|
||||
{
|
||||
osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type);
|
||||
detected_overlap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// look for inverted start/end pairs
|
||||
if (byteend < bytestart)
|
||||
osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend);
|
||||
|
||||
// look for misaligned entries
|
||||
if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1))
|
||||
osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, alignunit);
|
||||
|
||||
// if this is a program space, auto-assign implicit ROM entries
|
||||
if (entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr)
|
||||
{
|
||||
entry->m_region = device.tag();
|
||||
entry->m_rgnoffs = entry->m_addrstart;
|
||||
}
|
||||
|
||||
// if this entry references a memory region, validate it
|
||||
if (entry->m_region != nullptr && entry->m_share == nullptr)
|
||||
{
|
||||
// make sure we can resolve the full path to the region
|
||||
bool found = false;
|
||||
std::string entry_region = entry->m_devbase.subtag(entry->m_region);
|
||||
|
||||
// look for the region
|
||||
device_iterator deviter(device.mconfig().root_device());
|
||||
for (device_t *dev = deviter.first(); dev != nullptr; dev = deviter.next())
|
||||
for (const rom_entry *romp = rom_first_region(*dev); romp != nullptr && !found; romp = rom_next_region(romp))
|
||||
{
|
||||
if (rom_region_name(*dev, romp) == entry_region)
|
||||
{
|
||||
// verify the address range is within the region's bounds
|
||||
offs_t length = ROMREGION_GETLENGTH(romp);
|
||||
if (entry->m_rgnoffs + (byteend - bytestart + 1) > length)
|
||||
osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// error if not found
|
||||
if (!found)
|
||||
osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig.m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
|
||||
}
|
||||
|
||||
// make sure all devices exist
|
||||
if (entry->m_read.m_type == AMH_DEVICE_DELEGATE)
|
||||
{
|
||||
// extract the device tag from the proto-delegate
|
||||
const char *devtag = nullptr;
|
||||
switch (entry->m_read.m_bits)
|
||||
{
|
||||
case 8: devtag = entry->m_rproto8.device_name(); break;
|
||||
case 16: devtag = entry->m_rproto16.device_name(); break;
|
||||
case 32: devtag = entry->m_rproto32.device_name(); break;
|
||||
case 64: devtag = entry->m_rproto64.device_name(); break;
|
||||
}
|
||||
if (entry->m_devbase.subdevice(devtag) == nullptr)
|
||||
osd_printf_error("%s space memory map entry reads from nonexistant device '%s'\n", spaceconfig.m_name,
|
||||
devtag != nullptr ? devtag : "<unspecified>");
|
||||
}
|
||||
if (entry->m_write.m_type == AMH_DEVICE_DELEGATE)
|
||||
{
|
||||
// extract the device tag from the proto-delegate
|
||||
const char *devtag = nullptr;
|
||||
switch (entry->m_write.m_bits)
|
||||
{
|
||||
case 8: devtag = entry->m_wproto8.device_name(); break;
|
||||
case 16: devtag = entry->m_wproto16.device_name(); break;
|
||||
case 32: devtag = entry->m_wproto32.device_name(); break;
|
||||
case 64: devtag = entry->m_wproto64.device_name(); break;
|
||||
}
|
||||
if (entry->m_devbase.subdevice(devtag) == nullptr)
|
||||
osd_printf_error("%s space memory map entry writes to nonexistant device '%s'\n", spaceconfig.m_name,
|
||||
devtag != nullptr ? devtag : "<unspecified>");
|
||||
}
|
||||
if (entry->m_setoffsethd.m_type == AMH_DEVICE_DELEGATE)
|
||||
{
|
||||
// extract the device tag from the proto-delegate
|
||||
const char *devtag = entry->m_soproto.device_name();
|
||||
if (entry->m_devbase.subdevice(devtag) == nullptr)
|
||||
osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig.m_name,
|
||||
devtag != nullptr ? devtag : "<unspecified>");
|
||||
}
|
||||
|
||||
// make sure ports exist
|
||||
// if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) ||
|
||||
// (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL))
|
||||
// osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig.m_name, entry->m_read.m_tag);
|
||||
|
||||
// validate bank and share tags
|
||||
if (entry->m_read.m_type == AMH_BANK)
|
||||
valid.validate_tag(entry->m_read.m_tag);
|
||||
if (entry->m_write.m_type == AMH_BANK)
|
||||
valid.validate_tag(entry->m_write.m_tag);
|
||||
if (entry->m_share != nullptr)
|
||||
valid.validate_tag(entry->m_share);
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ enum map_handler_type
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// forward declarations
|
||||
class validity_checker;
|
||||
|
||||
|
||||
// address map handler data
|
||||
class map_handler_data
|
||||
{
|
||||
@ -289,6 +293,7 @@ public:
|
||||
simple_list<address_map_entry> m_entrylist; // list of entries
|
||||
|
||||
void uplift_submaps(running_machine &machine, device_t &device, device_t &owner, endianness_t endian);
|
||||
void map_validity_check(validity_checker &valid, const device_t &device, address_spacenum spacenum) const;
|
||||
};
|
||||
|
||||
|
||||
@ -309,6 +314,7 @@ void ADDRESS_MAP_NAME(_name)(address_map &map, device_t &device) \
|
||||
typedef write##_bits##_delegate write_delegate ATTR_UNUSED; \
|
||||
address_map_entry##_bits *curentry = NULL; \
|
||||
(void)curentry; \
|
||||
assert(&device != nullptr); \
|
||||
map.configure(_space, _bits); \
|
||||
typedef _class drivdata_class ATTR_UNUSED;
|
||||
#define DEVICE_ADDRESS_MAP_START(_name, _bits, _class) \
|
||||
@ -318,6 +324,7 @@ void _class :: _name(::address_map &map, device_t &device) \
|
||||
typedef write##_bits##_delegate write_delegate ATTR_UNUSED; \
|
||||
address_map_entry##_bits *curentry = NULL; \
|
||||
(void)curentry; \
|
||||
assert(&device != nullptr); \
|
||||
map.configure(AS_PROGRAM, _bits); \
|
||||
typedef _class drivdata_class ATTR_UNUSED;
|
||||
#define ADDRESS_MAP_END \
|
||||
|
@ -74,7 +74,10 @@ public:
|
||||
device_delegate(const thistype &src, device_t &search_root) : basetype(src), device_delegate_helper(src.m_device_name) { bind_relative_to(search_root); }
|
||||
|
||||
// perform the binding
|
||||
void bind_relative_to(device_t &search_root) { if (!basetype::isnull()) basetype::late_bind(bound_object(search_root)); }
|
||||
void bind_relative_to(device_t &search_root) { assert(&search_root != nullptr); if (!basetype::isnull()) basetype::late_bind(bound_object(search_root)); }
|
||||
|
||||
// getter (for validation purposes)
|
||||
const char *device_name() const { return m_device_name; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -12,14 +12,6 @@
|
||||
#include "validity.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// PARAMETERS
|
||||
//**************************************************************************
|
||||
|
||||
#define DETECT_OVERLAPPING_MEMORY (0)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CONSTANTS
|
||||
//**************************************************************************
|
||||
@ -238,127 +230,16 @@ bool device_memory_interface::memory_readop(offs_t offset, int size, UINT64 &val
|
||||
|
||||
void device_memory_interface::interface_validity_check(validity_checker &valid) const
|
||||
{
|
||||
bool detected_overlap = DETECT_OVERLAPPING_MEMORY ? false : true;
|
||||
|
||||
// loop over all address spaces
|
||||
for (address_spacenum spacenum = AS_0; spacenum < ADDRESS_SPACES; ++spacenum)
|
||||
{
|
||||
const address_space_config *spaceconfig = space_config(spacenum);
|
||||
if (spaceconfig != nullptr)
|
||||
if (space_config(spacenum) != nullptr)
|
||||
{
|
||||
int datawidth = spaceconfig->m_databus_width;
|
||||
int alignunit = datawidth / 8;
|
||||
// construct the map
|
||||
::address_map addrmap(const_cast<device_t &>(device()), spacenum);
|
||||
|
||||
// construct the maps
|
||||
auto map = global_alloc(::address_map(const_cast<device_t &>(device()), spacenum));
|
||||
|
||||
// if this is an empty map, just skip it
|
||||
if (map->m_entrylist.first() == nullptr)
|
||||
{
|
||||
global_free(map);
|
||||
continue;
|
||||
}
|
||||
|
||||
// validate the global map parameters
|
||||
if (map->m_spacenum != spacenum)
|
||||
osd_printf_error("Space %d has address space %d handlers!\n", spacenum, map->m_spacenum);
|
||||
if (map->m_databits != datawidth)
|
||||
osd_printf_error("Wrong memory handlers provided for %s space! (width = %d, memory = %08x)\n", spaceconfig->m_name, datawidth, map->m_databits);
|
||||
|
||||
// loop over entries and look for errors
|
||||
for (address_map_entry *entry = map->m_entrylist.first(); entry != nullptr; entry = entry->next())
|
||||
{
|
||||
UINT32 bytestart = spaceconfig->addr2byte(entry->m_addrstart);
|
||||
UINT32 byteend = spaceconfig->addr2byte_end(entry->m_addrend);
|
||||
|
||||
// look for overlapping entries
|
||||
if (!detected_overlap)
|
||||
{
|
||||
address_map_entry *scan;
|
||||
for (scan = map->m_entrylist.first(); scan != entry; scan = scan->next())
|
||||
if (entry->m_addrstart <= scan->m_addrend && entry->m_addrend >= scan->m_addrstart &&
|
||||
((entry->m_read.m_type != AMH_NONE && scan->m_read.m_type != AMH_NONE) ||
|
||||
(entry->m_write.m_type != AMH_NONE && scan->m_write.m_type != AMH_NONE)))
|
||||
{
|
||||
osd_printf_warning("%s space has overlapping memory (%X-%X,%d,%d) vs (%X-%X,%d,%d)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_read.m_type, entry->m_write.m_type, scan->m_addrstart, scan->m_addrend, scan->m_read.m_type, scan->m_write.m_type);
|
||||
detected_overlap = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// look for inverted start/end pairs
|
||||
if (byteend < bytestart)
|
||||
osd_printf_error("Wrong %s memory read handler start = %08x > end = %08x\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend);
|
||||
|
||||
// look for misaligned entries
|
||||
if ((bytestart & (alignunit - 1)) != 0 || (byteend & (alignunit - 1)) != (alignunit - 1))
|
||||
osd_printf_error("Wrong %s memory read handler start = %08x, end = %08x ALIGN = %d\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, alignunit);
|
||||
|
||||
// if this is a program space, auto-assign implicit ROM entries
|
||||
if (entry->m_read.m_type == AMH_ROM && entry->m_region == nullptr)
|
||||
{
|
||||
entry->m_region = device().tag();
|
||||
entry->m_rgnoffs = entry->m_addrstart;
|
||||
}
|
||||
|
||||
// if this entry references a memory region, validate it
|
||||
if (entry->m_region != nullptr && entry->m_share == nullptr)
|
||||
{
|
||||
// make sure we can resolve the full path to the region
|
||||
bool found = false;
|
||||
std::string entry_region = entry->m_devbase.subtag(entry->m_region);
|
||||
|
||||
// look for the region
|
||||
device_iterator deviter(device().mconfig().root_device());
|
||||
for (device_t *device = deviter.first(); device != nullptr; device = deviter.next())
|
||||
for (const rom_entry *romp = rom_first_region(*device); romp != nullptr && !found; romp = rom_next_region(romp))
|
||||
{
|
||||
if (rom_region_name(*device, romp) == entry_region)
|
||||
{
|
||||
// verify the address range is within the region's bounds
|
||||
offs_t length = ROMREGION_GETLENGTH(romp);
|
||||
if (entry->m_rgnoffs + (byteend - bytestart + 1) > length)
|
||||
osd_printf_error("%s space memory map entry %X-%X extends beyond region '%s' size (%X)\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region, length);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// error if not found
|
||||
if (!found)
|
||||
osd_printf_error("%s space memory map entry %X-%X references non-existant region '%s'\n", spaceconfig->m_name, entry->m_addrstart, entry->m_addrend, entry->m_region);
|
||||
}
|
||||
|
||||
// make sure all devices exist
|
||||
// FIXME: This doesn't work! AMH_DEVICE_DELEGATE entries don't even set m_tag, the device tag is inside the proto-delegate
|
||||
if (entry->m_read.m_type == AMH_DEVICE_DELEGATE && entry->m_read.m_tag != nullptr)
|
||||
{
|
||||
std::string temp(entry->m_read.m_tag);
|
||||
if (device().siblingdevice(temp.c_str()) == nullptr)
|
||||
osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_read.m_tag);
|
||||
}
|
||||
if (entry->m_write.m_type == AMH_DEVICE_DELEGATE && entry->m_write.m_tag != nullptr)
|
||||
{
|
||||
std::string temp(entry->m_write.m_tag);
|
||||
if (device().siblingdevice(temp.c_str()) == nullptr)
|
||||
osd_printf_error("%s space memory map entry references nonexistant device '%s'\n", spaceconfig->m_name, entry->m_write.m_tag);
|
||||
}
|
||||
|
||||
// make sure ports exist
|
||||
// if ((entry->m_read.m_type == AMH_PORT && entry->m_read.m_tag != NULL && portlist.find(entry->m_read.m_tag) == NULL) ||
|
||||
// (entry->m_write.m_type == AMH_PORT && entry->m_write.m_tag != NULL && portlist.find(entry->m_write.m_tag) == NULL))
|
||||
// osd_printf_error("%s space memory map entry references nonexistant port tag '%s'\n", spaceconfig->m_name, entry->m_read.m_tag);
|
||||
|
||||
// validate bank and share tags
|
||||
if (entry->m_read.m_type == AMH_BANK)
|
||||
valid.validate_tag(entry->m_read.m_tag);
|
||||
if (entry->m_write.m_type == AMH_BANK)
|
||||
valid.validate_tag(entry->m_write.m_tag);
|
||||
if (entry->m_share != nullptr)
|
||||
valid.validate_tag(entry->m_share);
|
||||
}
|
||||
|
||||
// release the address map
|
||||
global_free(map);
|
||||
// let the map check itself
|
||||
addrmap.map_validity_check(valid, device(), spacenum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user