summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/dirom.cpp
blob: 3ac69bd4531da3e10c3a0f152def4de9733fad13 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include "emu.h"


device_rom_interface::device_rom_interface(const machine_config &mconfig, device_t &device, UINT8 addrwidth, endianness_t endian, UINT8 datawidth) :
    device_memory_interface(mconfig, device),
    m_rom_config("rom", endian, datawidth, addrwidth)
{
}

device_rom_interface::~device_rom_interface()
{
}

const address_space_config *device_rom_interface::memory_space_config(address_spacenum spacenum) const
{
    return spacenum ? nullptr : &m_rom_config;
}

void device_rom_interface::set_rom(const void *base, UINT32 size)
{
    UINT32 mend = m_rom_config.addr_width() == 32 ? 0xffffffff : (1 << m_rom_config.addr_width()) - 1;
    UINT32 rend = size-1;
    if(rend == mend)
	space().install_rom(0, mend, const_cast<void *>(base));
    else {
	// Round up to the nearest power-of-two-minus-one
	UINT32 rmask = rend;
	rmask |= rmask >> 1;
	rmask |= rmask >> 2;
	rmask |= rmask >> 4;
	rmask |= rmask >> 8;
	rmask |= rmask >> 16;
	if(rmask != rend)
	    space().unmap_read(0, mend);
	// Mirror over the high bits.  mend and rmask are both
	// powers-of-two-minus-one, so the xor works
	space().install_rom(0, rend, mend ^ rmask, const_cast<void *>(base));
    }
}

void device_rom_interface::interface_pre_start()
{
    m_rom_direct = &space().direct();

    if(!has_configured_map(0)) {
	memory_region *reg = device().memregion(DEVICE_SELF);
	if(reg)
	    set_rom(reg->base(), reg->bytes());
	else {
	    UINT32 end = m_rom_config.addr_width() == 32 ? 0xffffffff : (1 << m_rom_config.addr_width()) - 1;
	    space().unmap_read(0, end);
	}
    }
}