summaryrefslogblamecommitdiffstatshomepage
path: root/src/emu/addrmap.h
blob: b201201c4ddb83c56e6c6d359c0ea914a0d1da19 (plain) (tree)
1
2
3
4
5
6
7
8

                                





                                                                            







                                                                            

                          
 
                      













                                                                            

                              

                               
                               
                                
                 

                         







                                                                            



                           





                                                                                                 








                                                                                   

                                 
                                                               


                                                                                                                                                                   


                                                                                                                                                                        



                                                                                         
                            



                                                                                                               









                                                                                                                                                              

                                   
                                                                                        
 

                                                          
 
                                




                                                                                                                       
















                                                                                                                                      



                                                                                                     





                                                                                                             
 
                               
                                              
 




                                              


                                                                                        
                                 


                                                                                                                   
 
                                    


                                                                                                                   
 















                                                                                                 



                                                                                                           
                             
                                                                            

                                                                             
 


                                                                              
                                                                                               
 

                                                                                
                                                                                                 
 

                                                                                                                                       
                                                                                                                                                                             
 


                                                                                           
 
 


                                                                                               
                                                                                  
 

                                                                                                 
                                                                                    
 

                                                                                                                                                        
                                                                                                                                                   
 


                                                                                             
 
 


                                                                                      
                                                                                         
 

                                                                                        
                                                                                           
 

                                                                                                                                               
                                                                                                                                                                
 


                                                                                                      
 
 

                                                                                      

                                                                                                                
                                                                                           
         
 
                                                                                      

                                                                                                                      
                                                                                           
         
 
                                                                                      

                                                                                                                  
                                                                                             
         
 
                                                                                      

                                                                                                                        
                                                                                             
         
 
                                                                                                                                        

                                                                                                                                                                         

                                                                                                       
         
 
                                                                                                                                        

                                                                                                                                                                               

                                                                                                       
         
 
                                                                                      


                                                                                                              
         
 
                                                                                      


                                                                                                                    
         
 

                                       

                                                                                             
 

                                                                                              
 

                                                                                              
 

                                                                                              
 

                                                                                              
 

                                                                                               
 

                                                                                               
 

                                                                                               
 

                                                                                                                                                                                   
 

                                                                                                                                                                                     
 

                                                                                                                                                                                     
 

                                                                                                                                                                                     
 
                       

                                                                                      
                                                                                                     

                            



                                                                        
                                                                      
                                                                                     
                                                                                     

                                                                                 

                                                                                                                 
                                                                                   

                   



                                                                                     



                                                                                      
 








                                                                                      

















                                                                                      








                                                                                      








                                                                                      
                                                
                                                  
 
                                             
                                                                                               
 
                                              

                                                   

                                                    



                                                     

                                                     

                                                      
 
                                               

                                                    

                                                     



                                                      

                                                      

                                                       
 
                                               

                                                    

                                                     



                                                      

                                                      

                                                       
 
                                               

                                                    

                                                     



                                                      

                                                      

                                                       


                           
                                                                                       

  






                                                                               
                                                    
                                                                
                                                                                                                                                                
                       
 
                  


                                                    
                                                          

                                            
                                                                

                      
                                                                                  
                                                                            


                                                                                
 
                                                                                                                            
                                                                             
  
 
                            
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    addrmap.h

    Macros and helper functions for handling address map definitions.

***************************************************************************/

#pragma once

#ifndef __EMU_H__
#error Dont include this file directly; include emu.h instead.
#endif

#ifndef MAME_EMU_ADDRMAP_H
#define MAME_EMU_ADDRMAP_H

#include <type_traits>


//**************************************************************************
//  CONSTANTS
//**************************************************************************

// address map handler types
enum map_handler_type
{
	AMH_NONE = 0,
	AMH_RAM,
	AMH_ROM,
	AMH_NOP,
	AMH_UNMAP,
	AMH_DEVICE_DELEGATE,
	AMH_DEVICE_DELEGATE_M,
	AMH_DEVICE_DELEGATE_S,
	AMH_DEVICE_DELEGATE_SM,
	AMH_DEVICE_DELEGATE_MO,
	AMH_DEVICE_DELEGATE_SMO,
	AMH_PORT,
	AMH_BANK,
	AMH_DEVICE_SUBMAP
};



//**************************************************************************
//  TYPE DEFINITIONS
//**************************************************************************

// address map handler data
class map_handler_data
{
public:
	map_handler_data() { }

	map_handler_type    m_type = AMH_NONE;  // type of the handler
	u8                  m_bits = 0;         // width of the handler in bits, or 0 for default
	const char *        m_name = nullptr;   // name of the handler
	const char *        m_tag = nullptr;    // tag for I/O ports and banks
};



// ======================> address_map_entry

// address_map_entry is a linked list element describing one address range in a map
class address_map_entry
{
	friend class address_map;

	template <typename T, typename Ret, typename... Params>
	struct is_addrmap_method { static constexpr bool value = std::is_constructible<address_map_constructor, Ret (T::*)(Params...), const char *, T*>::value; };

	template <typename T, typename Ret, typename... Params>
	static std::enable_if_t<is_addrmap_method<T, Ret, Params...>::value, address_map_constructor> make_delegate(Ret (T::*func)(Params...), const char *name, T *obj)
	{ return address_map_constructor(func, name, obj); }

	template <typename T, bool Reqd>
	static device_t &find_device(const device_finder<T, Reqd> &finder) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		device_t *device(target.first.subdevice(target.second));
		if (!device)
			throw emu_fatalerror("Device %s not found in %s\n", target.second, target.first.tag());
		return *device;
	}

	template <typename T, typename U>
	static std::enable_if_t<std::is_convertible<std::add_pointer_t<U>, std::add_pointer_t<T> >::value, T *> make_pointer(U &obj)
	{ return &downcast<T &>(obj); }
	template <typename T, typename U>
	static std::enable_if_t<!std::is_convertible<std::add_pointer_t<U>, std::add_pointer_t<T> >::value, T *> make_pointer(U &obj)
	{ return &dynamic_cast<T &>(obj); }

	template <typename T> static std::enable_if_t<emu::detail::is_device_implementation<T>::value, const char *> get_tag(T &obj) { return obj.tag(); }
	template <typename T> static std::enable_if_t<emu::detail::is_device_interface<T>::value, const char *> get_tag(T &obj) { return obj.device().tag(); }

public:
	// construction/destruction
	address_map_entry(device_t &device, address_map &map, offs_t start, offs_t end);

	// getters
	address_map_entry *next() const { return m_next; }

	// simple inline setters
	address_map_entry &mirror(offs_t _mirror) { m_addrmirror = _mirror; return *this; }
	address_map_entry &select(offs_t _select) { m_addrselect = _select; return *this; }
	address_map_entry &region(const char *tag, offs_t offset) { m_region = tag; m_rgnoffs = offset; return *this; }
	address_map_entry &share(const char *tag) { m_share = tag; return *this; }

	// slightly less simple inline setters
	template<bool _reqd> address_map_entry &region(const memory_region_finder<_reqd> &finder, offs_t offset) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		assert(&target.first == &m_devbase);
		return region(target.second, offset);
	}
	template<typename _ptrt, bool _reqd> address_map_entry &region(const region_ptr_finder<_ptrt, _reqd> &finder, offs_t offset) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		assert(&target.first == &m_devbase);
		return region(target.second, offset);
	}
	template<typename _ptrt, bool _reqd> address_map_entry &share(const shared_ptr_finder<_ptrt, _reqd> &finder) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		assert(&target.first == &m_devbase);
		return share(target.second);
	}

	address_map_entry &rom() { m_read.m_type = AMH_ROM; return *this; }
	address_map_entry &ram() { m_read.m_type = AMH_RAM; m_write.m_type = AMH_RAM; return *this; }
	address_map_entry &readonly() { m_read.m_type = AMH_RAM; return *this; }
	address_map_entry &writeonly() { m_write.m_type = AMH_RAM; return *this; }
	address_map_entry &unmaprw() { m_read.m_type = AMH_UNMAP; m_write.m_type = AMH_UNMAP; return *this; }
	address_map_entry &unmapr() { m_read.m_type = AMH_UNMAP; return *this; }
	address_map_entry &unmapw() { m_write.m_type = AMH_UNMAP; return *this; }
	address_map_entry &noprw() { m_read.m_type = AMH_NOP; m_write.m_type = AMH_NOP; return *this; }
	address_map_entry &nopr() { m_read.m_type = AMH_NOP; return *this; }
	address_map_entry &nopw() { m_write.m_type = AMH_NOP; return *this; }

	// address mask setting
	address_map_entry &mask(offs_t _mask);

	// unit mask setting
	address_map_entry &umask16(u16 _mask);
	address_map_entry &umask32(u32 _mask);
	address_map_entry &umask64(u64 _mask);

	// chip select width setting
	address_map_entry &cswidth(int _cswidth) { m_cswidth = _cswidth; return *this; }

	// I/O port configuration
	address_map_entry &portr(const char *tag) { m_read.m_type = AMH_PORT; m_read.m_tag = tag; return *this; }
	address_map_entry &portw(const char *tag) { m_write.m_type = AMH_PORT; m_write.m_tag = tag; return *this; }
	address_map_entry &portrw(const char *tag) { portr(tag); portw(tag); return *this; }

	// memory bank configuration
	address_map_entry &bankr(const char *tag) { m_read.m_type = AMH_BANK; m_read.m_tag = tag; return *this; }
	address_map_entry &bankw(const char *tag) { m_write.m_type = AMH_BANK; m_write.m_tag = tag; return *this; }
	address_map_entry &bankrw(const char *tag) { bankr(tag); bankw(tag); return *this; }

	template<bool _reqd> address_map_entry &bankr(const memory_bank_finder<_reqd> &finder) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		assert(&target.first == &m_devbase);
		return bankr(target.second);
	}
	template<bool _reqd> address_map_entry &bankw(const memory_bank_finder<_reqd> &finder) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		assert(&target.first == &m_devbase);
		return bankw(target.second);
	}
	template<bool _reqd> address_map_entry &bankrw(const memory_bank_finder<_reqd> &finder) {
		const std::pair<device_t &, const char *> target(finder.finder_target());
		assert(&target.first == &m_devbase);
		return bankrw(target.second);
	}

	// type setters
	address_map_entry &set_read_type(map_handler_type _type) { m_read.m_type = _type; return *this; }
	address_map_entry &set_write_type(map_handler_type _type) { m_write.m_type = _type; return *this; }

	// submap referencing
	address_map_entry &m(const char *tag, address_map_constructor func);
	address_map_entry &m(device_t *device, address_map_constructor func);


	// implicit base -> delegate converter
	template <typename T, typename Ret, typename... Params>
	address_map_entry &r(Ret (T::*read)(Params...), const char *read_name)
	{ return r(emu::detail::make_delegate(*make_pointer<T>(m_devbase), read, read_name)); }

	template <typename T, typename Ret, typename... Params>
	address_map_entry &w(Ret (T::*write)(Params...), const char *write_name)
	{ return w(emu::detail::make_delegate(*make_pointer<T>(m_devbase), write, write_name)); }

	template <typename T, typename RetR, typename... ParamsR, typename U, typename RetW, typename... ParamsW>
	address_map_entry &rw(RetR (T::*read)(ParamsR...), const char *read_name, RetW (U::*write)(ParamsW...), const char *write_name)
	{ return r(emu::detail::make_delegate(*make_pointer<T>(m_devbase), read, read_name)).w(emu::detail::make_delegate(*make_pointer<U>(m_devbase), write, write_name)); }

	template <typename T, typename Ret, typename... Params>
	address_map_entry &m(Ret (T::*map)(Params...), const char *map_name)
	{ return m(&m_devbase, make_delegate(map, map_name, make_pointer<T>(m_devbase))); }


	// device tag -> delegate converter
	template <typename T, typename Ret, typename... Params>
	address_map_entry &r(const char *tag, Ret (T::*read)(Params...), const char *read_name)
	{ return r(emu::detail::make_delegate(m_devbase, tag, read, read_name)); }

	template <typename T, typename Ret, typename... Params>
	address_map_entry &w(const char *tag, Ret (T::*write)(Params...), const char *write_name)
	{ return w(emu::detail::make_delegate(m_devbase, tag, write, write_name)); }

	template <typename T, typename RetR, typename... ParamsR, typename U, typename RetW, typename... ParamsW>
	address_map_entry &rw(const char *tag, RetR (T::*read)(ParamsR...), const char *read_name, RetW (U::*write)(ParamsW...), const char *write_name)
	{ return r(emu::detail::make_delegate(m_devbase, tag, read, read_name)).w(emu::detail::make_delegate(m_devbase, tag, write, write_name)); }

	template <typename T, typename Ret, typename... Params>
	address_map_entry &m(const char *tag, Ret (T::*map)(Params...), const char *map_name)
	{ return m(tag, make_delegate(map, map_name, static_cast<T *>(nullptr))); }


	// device reference -> delegate converter
	template <typename T, typename U, typename Ret, typename... Params>
	address_map_entry &r(T &obj, Ret (U::*read)(Params...), const char *read_name)
	{ return r(emu::detail::make_delegate(*make_pointer<U>(obj), read, read_name)); }

	template <typename T, typename U, typename Ret, typename... Params>
	address_map_entry &w(T &obj, Ret (U::*write)(Params...), const char *write_name)
	{ return w(emu::detail::make_delegate(*make_pointer<U>(obj), write, write_name)); }

	template <typename T, typename U, typename RetR, typename... ParamsR, typename V, typename RetW, typename... ParamsW>
	address_map_entry &rw(T &obj, RetR (U::*read)(ParamsR...), const char *read_name, RetW (V::*write)(ParamsW...), const char *write_name)
	{ return r(emu::detail::make_delegate(*make_pointer<U>(obj), read, read_name)).w(emu::detail::make_delegate(make_pointer<V>(obj), write, write_name)); }

	template <typename T, typename U, typename Ret, typename... Params>
	address_map_entry &m(T &obj, Ret (U::*map)(Params...), const char *map_name)
	{ return m(make_pointer<device_t>(obj), make_delegate(map, map_name, make_pointer<U>(obj))); }


	// device finder -> delegate converter
	template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
	address_map_entry &r(device_finder<T, Reqd> &finder, Ret (U::*read)(Params...), const char *read_name) {
		device_t &device(find_device(finder));
		return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name));
	}

	template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
	address_map_entry &r(const device_finder<T, Reqd> &finder, Ret (U::*read)(Params...), const char *read_name) {
		device_t &device(find_device(finder));
		return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name));
	}

	template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
	address_map_entry &w(device_finder<T, Reqd> &finder, Ret (U::*write)(Params...), const char *write_name) {
		device_t &device(find_device(finder));
		return w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
	}

	template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
	address_map_entry &w(const device_finder<T, Reqd> &finder, Ret (U::*write)(Params...), const char *write_name) {
		device_t &device(find_device(finder));
		return w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
	}

	template <typename T, bool Reqd, typename U, typename RetR, typename... ParamsR, typename V, typename RetW, typename... ParamsW>
	address_map_entry &rw(device_finder<T, Reqd> &finder, RetR (U::*read)(ParamsR...), const char *read_name, RetW (V::*write)(ParamsW...), const char *write_name) {
		device_t &device(find_device(finder));
		return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name))
				.w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
	}

	template <typename T, bool Reqd, typename U, typename RetR, typename... ParamsR, typename V, typename RetW, typename... ParamsW>
	address_map_entry &rw(const device_finder<T, Reqd> &finder, RetR (U::*read)(ParamsR...), const char *read_name, RetW (V::*write)(ParamsW...), const char *write_name) {
		device_t &device(find_device(finder));
		return r(emu::detail::make_delegate(device, DEVICE_SELF, read, read_name))
				.w(emu::detail::make_delegate(device, DEVICE_SELF, write, write_name));
	}

	template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
	address_map_entry &m(device_finder<T, Reqd> &finder, Ret (U::*map)(Params...), const char *map_name) {
		device_t &device(find_device(finder));
		return m(&device, make_delegate(map, map_name, make_pointer<U>(device)));
	}

	template <typename T, bool Reqd, typename U, typename Ret, typename... Params>
	address_map_entry &m(const device_finder<T, Reqd> &finder, Ret (U::*map)(Params...), const char *map_name) {
		device_t &device(find_device(finder));
		return m(&device, make_delegate(map, map_name, make_pointer<U>(device)));
	}


	// lambda -> delegate converter
	template <typename T> address_map_entry &lr8(T &&read, const char *name)
	{ return r(emu::detail::make_lr8_delegate(m_devbase, std::forward<T>(read), name)); }

	template <typename T> address_map_entry &lr16(T &&read, const char *name)
	{ return r(emu::detail::make_lr16_delegate(m_devbase, std::forward<T>(read), name)); }

	template <typename T> address_map_entry &lr32(T &&read, const char *name)
	{ return r(emu::detail::make_lr32_delegate(m_devbase, std::forward<T>(read), name)); }

	template <typename T> address_map_entry &lr64(T &&read, const char *name)
	{ return r(emu::detail::make_lr64_delegate(m_devbase, std::forward<T>(read), name)); }

	template <typename T> address_map_entry &lw8(T &&write, const char *name)
	{ return w(emu::detail::make_lw8_delegate(m_devbase, std::forward<T>(write), name)); }

	template <typename T> address_map_entry &lw16(T &&write, const char *name)
	{ return w(emu::detail::make_lw16_delegate(m_devbase, std::forward<T>(write), name)); }

	template <typename T> address_map_entry &lw32(T &&write, const char *name)
	{ return w(emu::detail::make_lw32_delegate(m_devbase, std::forward<T>(write), name)); }

	template <typename T> address_map_entry &lw64(T &&write, const char *name)
	{ return w(emu::detail::make_lw64_delegate(m_devbase, std::forward<T>(write), name)); }

	template <typename T, typename U> address_map_entry &lrw8(T &&read, const char *read_name, U &&write, const char *write_name)
	{ return r(emu::detail::make_lr8_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw8_delegate(m_devbase, std::forward<U>(write), write_name)); }

	template <typename T, typename U> address_map_entry &lrw16(T &&read, const char *read_name, U &&write, const char *write_name)
	{ return r(emu::detail::make_lr16_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw16_delegate(m_devbase, std::forward<U>(write), write_name)); }

	template <typename T, typename U> address_map_entry &lrw32(T &&read, const char *read_name, U &&write, const char *write_name)
	{ return r(emu::detail::make_lr32_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw32_delegate(m_devbase, std::forward<U>(write), write_name)); }

	template <typename T, typename U> address_map_entry &lrw64(T &&read, const char *read_name, U &&write, const char *write_name)
	{ return r(emu::detail::make_lr64_delegate(m_devbase, std::forward<T>(read), read_name)).w(emu::detail::make_lw64_delegate(m_devbase, std::forward<U>(write), write_name)); }

	// public state
	address_map_entry *     m_next;                 // pointer to the next entry
	address_map &           m_map;                  // reference to our owning map
	device_t &              m_devbase;              // reference to "base" device for tag lookups

	// basic information
	offs_t                  m_addrstart;            // start address
	offs_t                  m_addrend;              // end address
	offs_t                  m_addrmirror;           // mirror bits
	offs_t                  m_addrmask;             // mask bits
	offs_t                  m_addrselect;           // select bits
	u64                     m_mask;                 // mask for which lanes apply
	int                     m_cswidth;              // chip select width override
	map_handler_data        m_read;                 // data for read handler
	map_handler_data        m_write;                // data for write handler
	const char *            m_share;                // tag of a shared memory block
	const char *            m_region;               // tag of region containing the memory backing this entry
	offs_t                  m_rgnoffs;              // offset within the region

	// handlers
	read8_delegate          m_rproto8;              // 8-bit read proto-delegate
	read16_delegate         m_rproto16;             // 16-bit read proto-delegate
	read32_delegate         m_rproto32;             // 32-bit read proto-delegate
	read64_delegate         m_rproto64;             // 64-bit read proto-delegate
	write8_delegate         m_wproto8;              // 8-bit write proto-delegate
	write16_delegate        m_wproto16;             // 16-bit write proto-delegate
	write32_delegate        m_wproto32;             // 32-bit write proto-delegate
	write64_delegate        m_wproto64;             // 64-bit write proto-delegate

	read8m_delegate         m_rproto8m;             // 8-bit read proto-delegate
	read16m_delegate        m_rproto16m;            // 16-bit read proto-delegate
	read32m_delegate        m_rproto32m;            // 32-bit read proto-delegate
	read64m_delegate        m_rproto64m;            // 64-bit read proto-delegate
	write8m_delegate        m_wproto8m;             // 8-bit write proto-delegate
	write16m_delegate       m_wproto16m;            // 16-bit write proto-delegate
	write32m_delegate       m_wproto32m;            // 32-bit write proto-delegate
	write64m_delegate       m_wproto64m;            // 64-bit write proto-delegate

	read8s_delegate         m_rproto8s;             // 8-bit read proto-delegate
	read16s_delegate        m_rproto16s;            // 16-bit read proto-delegate
	read32s_delegate        m_rproto32s;            // 32-bit read proto-delegate
	read64s_delegate        m_rproto64s;            // 64-bit read proto-delegate
	write8s_delegate        m_wproto8s;             // 8-bit write proto-delegate
	write16s_delegate       m_wproto16s;            // 16-bit write proto-delegate
	write32s_delegate       m_wproto32s;            // 32-bit write proto-delegate
	write64s_delegate       m_wproto64s;            // 64-bit write proto-delegate

	read8sm_delegate        m_rproto8sm;            // 8-bit read proto-delegate
	read16sm_delegate       m_rproto16sm;           // 16-bit read proto-delegate
	read32sm_delegate       m_rproto32sm;           // 32-bit read proto-delegate
	read64sm_delegate       m_rproto64sm;           // 64-bit read proto-delegate
	write8sm_delegate       m_wproto8sm;            // 8-bit write proto-delegate
	write16sm_delegate      m_wproto16sm;           // 16-bit write proto-delegate
	write32sm_delegate      m_wproto32sm;           // 32-bit write proto-delegate
	write64sm_delegate      m_wproto64sm;           // 64-bit write proto-delegate

	read8mo_delegate        m_rproto8mo;            // 8-bit read proto-delegate
	read16mo_delegate       m_rproto16mo;           // 16-bit read proto-delegate
	read32mo_delegate       m_rproto32mo;           // 32-bit read proto-delegate
	read64mo_delegate       m_rproto64mo;           // 64-bit read proto-delegate
	write8mo_delegate       m_wproto8mo;            // 8-bit write proto-delegate
	write16mo_delegate      m_wproto16mo;           // 16-bit write proto-delegate
	write32mo_delegate      m_wproto32mo;           // 32-bit write proto-delegate
	write64mo_delegate      m_wproto64mo;           // 64-bit write proto-delegate

	read8smo_delegate       m_rproto8smo;           // 8-bit read proto-delegate
	read16smo_delegate      m_rproto16smo;          // 16-bit read proto-delegate
	read32smo_delegate      m_rproto32smo;          // 32-bit read proto-delegate
	read64smo_delegate      m_rproto64smo;          // 64-bit read proto-delegate
	write8smo_delegate      m_wproto8smo;           // 8-bit write proto-delegate
	write16smo_delegate     m_wproto16smo;          // 16-bit write proto-delegate
	write32smo_delegate     m_wproto32smo;          // 32-bit write proto-delegate
	write64smo_delegate     m_wproto64smo;          // 64-bit write proto-delegate

	device_t               *m_submap_device;
	address_map_constructor m_submap_delegate;

	// information used during processing
	void *                  m_memory;               // pointer to memory backing this entry

	// handler setters for 8-bit delegates
	address_map_entry &r(read8_delegate func);
	address_map_entry &w(write8_delegate func);
	address_map_entry &r(read8m_delegate func);
	address_map_entry &w(write8m_delegate func);
	address_map_entry &r(read8s_delegate func);
	address_map_entry &w(write8s_delegate func);
	address_map_entry &r(read8sm_delegate func);
	address_map_entry &w(write8sm_delegate func);
	address_map_entry &r(read8mo_delegate func);
	address_map_entry &w(write8mo_delegate func);
	address_map_entry &r(read8smo_delegate func);
	address_map_entry &w(write8smo_delegate func);

	// handler setters for 16-bit delegates
	address_map_entry &r(read16_delegate func);
	address_map_entry &w(write16_delegate func);
	address_map_entry &r(read16m_delegate func);
	address_map_entry &w(write16m_delegate func);
	address_map_entry &r(read16s_delegate func);
	address_map_entry &w(write16s_delegate func);
	address_map_entry &r(read16sm_delegate func);
	address_map_entry &w(write16sm_delegate func);
	address_map_entry &r(read16mo_delegate func);
	address_map_entry &w(write16mo_delegate func);
	address_map_entry &r(read16smo_delegate func);
	address_map_entry &w(write16smo_delegate func);

	// handler setters for 32-bit delegates
	address_map_entry &r(read32_delegate func);
	address_map_entry &w(write32_delegate func);
	address_map_entry &r(read32m_delegate func);
	address_map_entry &w(write32m_delegate func);
	address_map_entry &r(read32s_delegate func);
	address_map_entry &w(write32s_delegate func);
	address_map_entry &r(read32sm_delegate func);
	address_map_entry &w(write32sm_delegate func);
	address_map_entry &r(read32mo_delegate func);
	address_map_entry &w(write32mo_delegate func);
	address_map_entry &r(read32smo_delegate func);
	address_map_entry &w(write32smo_delegate func);

	// handler setters for 64-bit delegates
	address_map_entry &r(read64_delegate func);
	address_map_entry &w(write64_delegate func);
	address_map_entry &r(read64m_delegate func);
	address_map_entry &w(write64m_delegate func);
	address_map_entry &r(read64s_delegate func);
	address_map_entry &w(write64s_delegate func);
	address_map_entry &r(read64sm_delegate func);
	address_map_entry &w(write64sm_delegate func);
	address_map_entry &r(read64mo_delegate func);
	address_map_entry &w(write64mo_delegate func);
	address_map_entry &r(read64smo_delegate func);
	address_map_entry &w(write64smo_delegate func);

private:
	// helper functions
	bool unitmask_is_appropriate(u8 width, u64 unitmask, const char *string) const;
};

// ======================> address_map

// address_map holds global map parameters plus the head of the list of entries
class address_map
{
public:
	// construction/destruction
	address_map(device_t &device, int spacenum);
	address_map(device_t &device, address_map_entry *entry);
	address_map(const address_space &space, offs_t start, offs_t end, u64 unitmask, int cswidth, device_t &device, address_map_constructor submap_delegate);
	~address_map();

	// setters
	void global_mask(offs_t mask);
	void unmap_value_low() { m_unmapval = 0; }
	void unmap_value_high() { m_unmapval = ~0; }
	void unmap_value(u8 value) { m_unmapval = value; }

	// add a new entry of the given type
	address_map_entry &operator()(offs_t start, offs_t end);

	// public data
	int                             m_spacenum;     // space number of the map
	device_t *                      m_device;       // associated device
	u8                              m_unmapval;     // unmapped memory value
	offs_t                          m_globalmask;   // global mask
	simple_list<address_map_entry>  m_entrylist;    // list of entries

	void import_submaps(running_machine &machine, device_t &owner, int data_width, endianness_t endian, int addr_shift);
	void map_validity_check(validity_checker &valid, int spacenum) const;
};

#endif // MAME_EMU_ADDRMAP_H