void fill(memory_units_descriptor <int_Width, int_AddrShift> descriptor, std.vector <memory_units_descriptor <int_Width, int_AddrShift> .entry> entries) { handler_entry handler = descriptor.get_subunit_handler(); handler.ref_((int)entries.size()); foreach (var e in entries) { m_subunit_infos[m_subunits++] = new subunit_info(handler, e.m_amask, e.m_dmask, e.m_ashift, e.m_offset, e.m_dshift, descriptor.get_subunit_width()); } }
//template<int Width, int AddrShift> public memory_units_descriptor(u8 access_width, endianness_t access_endian, handler_entry handler, offs_t addrstart, offs_t addrend, offs_t mask, uX unitmask, int cswidth) //memory_units_descriptor(u8 access_width, endianness_t access_endian, handler_entry handler, offs_t addrstart, offs_t addrend, offs_t mask, uX unitmask, int cswidth); { m_handler = handler; m_access_width = access_width; m_access_endian = access_endian; u32 bits_per_access = 8U << access_width; u32 NATIVE_MASK = Width + AddrShift >= 0 ? make_bitmask32(Width + AddrShift) : 0; // Compute the real base addresses m_addrstart = addrstart & ~NATIVE_MASK; m_addrend = addrend & ~NATIVE_MASK; // Compute the masks and the keys uX [] umasks = new uX[4]; //std.array<uX, 4> umasks; umasks.Fill(unitmask); //umasks.fill(unitmask); uX smask; uX emask; if (access_endian == ENDIANNESS_BIG) { smask = make_bitmask_uX(Width, 8 * (u32)sizeof_(uX.WidthToType(Width)) - ((addrstart - m_addrstart) << (3 - AddrShift))); //smask = make_bitmask<uX>(8 * sizeof(uX) - ((addrstart - m_addrstart) << (3 - AddrShift))); emask = ~make_bitmask_uX(Width, 8 * (u32)sizeof_(uX.WidthToType(Width)) - ((addrend - m_addrend + 1) << (3 - AddrShift))); //emask = ~make_bitmask<uX>(8 * sizeof(uX) - ((addrend - m_addrend + 1) << (3 - AddrShift))); } else { smask = ~make_bitmask_uX(Width, (addrstart - m_addrstart) << (3 - AddrShift)); //smask = ~make_bitmask<uX>((addrstart - m_addrstart) << (3 - AddrShift)); emask = make_bitmask_uX(Width, (addrend - m_addrend + 1) << (3 - AddrShift)); //emask = make_bitmask<uX>((addrend - m_addrend + 1) << (3 - AddrShift)); } umasks[handler_entry.START] &= smask; umasks[handler_entry.END] &= emask; umasks[handler_entry.START | handler_entry.END] &= smask & emask; for (u32 i = 0; i < 4; i++) { m_keymap[i] = mask_to_ukey(umasks[i]); //m_keymap[i] = mask_to_ukey<uX>(umasks[i]); } // Compute the shift uX dmask = make_bitmask_uX(Width, bits_per_access); //uX dmask = make_bitmask<uX>(bits_per_access); u32 active_count = 0; for (u32 i = 0; i != 8 << Width; i += (u32)bits_per_access) { if ((unitmask & (dmask << (int)i)) != 0) { active_count++; } } u32 active_count_log = active_count == 1 ? 0U : active_count == 2 ? 1U : active_count == 4 ? 2U : active_count == 8 ? 3U : 0xff; if (active_count_log == 0xff) { throw new emu_fatalerror("memory_units_descriptor() - abort"); //abort(); } s8 base_shift = (s8)(Width - access_width - active_count_log); s8 shift = (s8)(base_shift + access_width + AddrShift); // Build the handler characteristics m_handler_start = shift < 0 ? addrstart << -shift : addrstart >> shift; m_handler_mask = shift < 0 ? (mask << -shift) | make_bitmask32(-shift) : mask >> shift; //m_handler_mask = shift < 0 ? (mask << -shift) | make_bitmask<offs_t>(-shift) : mask >> shift; for (u32 i = 0; i < 4; i++) { if (m_entries_for_key.find(m_keymap[i]) == null) //if (m_entries_for_key.find(m_keymap[i]) == m_entries_for_key.end()) { m_entries_for_key[m_keymap[i]] = new std.vector <entry>(); generate(m_keymap[i], unitmask, umasks[i], (u32)cswidth, bits_per_access, (u8)base_shift, shift, active_count); } } }
public u8 m_width; // access width (0..3) public subunit_info(handler_entry handler, uX amask, uX dmask, s8 ashift, u8 offset, u8 dshift, u8 width) { this.m_handler = handler; this.m_amask = amask; this.m_dmask = dmask; this.m_ashift = ashift; this.m_offset = offset; this.m_dshift = dshift; this.m_width = width; }