//template<int Width, int AddrShift> void generate(u8 ukey, uX gumask, uX umask, u32 cswidth, u32 bits_per_access, u8 base_shift, s8 shift, u32 active_count) { var entries = m_entries_for_key[ukey]; // Compute the selection masks if (cswidth == 0) { cswidth = bits_per_access; } uX csmask = make_bitmask_uX(Width, cswidth); //uX csmask = make_bitmask<uX>(cswidth); uX dmask = make_bitmask_uX(Width, bits_per_access); //uX dmask = make_bitmask<uX>(bits_per_access); u32 offset = 0; for (u32 i = 0; i != 8 << Width; i += bits_per_access) { uX numask = dmask << (int)i; if ((umask & numask) != 0) { uX amask = csmask << (int)(i & ~(cswidth - 1)); entries.emplace_back(new entry(amask, numask, shift, (u8)i, (u8)(m_access_endian == ENDIANNESS_BIG ? active_count - 1 - offset : offset))); } if ((gumask & numask) != 0) { offset++; } } }
public handler_entry_read_units(memory_units_descriptor <int_Width, int_AddrShift> descriptor, u8 ukey, handler_entry_read_units <int_Width, int_AddrShift> src) : base(src.m_space, F_UNITS) { m_subunits = 0; uX fullmask = new uX(Width, 0); var entries = descriptor.get_entries_for_key(ukey); foreach (var e in entries) { fullmask |= e.m_dmask; } for (u32 i = 0; i != src.m_subunits; i++) { if ((src.m_subunit_infos[i].m_dmask & fullmask) == 0) { m_subunit_infos[m_subunits] = src.m_subunit_infos[i]; m_subunit_infos[m_subunits].m_handler.ref_(); m_subunits++; } } fill(descriptor, entries); Array.Sort(m_subunit_infos, 0, m_subunits, Comparer <subunit_info> .Create((a, b) => { return(a.m_offset < b.m_offset ? -1 : 1); })); //std::sort(m_subunit_infos, m_subunit_infos + m_subunits, [](const subunit_info &a, const subunit_info &b) { return a.m_offset < b.m_offset; }); }
public override uX read(offs_t offset, uX mem_mask) //template<int Width, int AddrShift> typename emu::detail::handler_entry_size<Width>::uX handler_entry_read_units<Width, AddrShift>::read(offs_t offset, uX mem_mask) const { this.ref_(); uX result = m_unmap; for (int index = 0; index < m_subunits; index++) { subunit_info si = m_subunit_infos[index]; if ((mem_mask & si.m_amask) != 0) { offs_t aoffset = (si.m_ashift >= 0 ? offset >> si.m_ashift : offset << si.m_ashift) + si.m_offset; switch (si.m_width) { case 0: result |= ((handler_entry_read <int_const_0, int_const_0>)si.m_handler).read(aoffset, mem_mask >> si.m_dshift) << si.m_dshift; //result |= uX(static_cast<handler_entry_read<0, 0> *>(si.m_handler)->read(aoffset, mem_mask >> si.m_dshift)) << si.m_dshift; break; case 1: result |= ((handler_entry_read <int_const_1, int_const_n1>)si.m_handler).read(aoffset, mem_mask >> si.m_dshift) << si.m_dshift; //result |= uX(static_cast<handler_entry_read<1, -1> *>(si.m_handler)->read(aoffset, mem_mask >> si.m_dshift)) << si.m_dshift; break; case 2: result |= ((handler_entry_read <int_const_2, int_const_n2>)si.m_handler).read(aoffset, mem_mask >> si.m_dshift) << si.m_dshift; //result |= uX(static_cast<handler_entry_read<2, -2> *>(si.m_handler)->read(aoffset, mem_mask >> si.m_dshift)) << si.m_dshift; break; default: throw new emu_fatalerror("handler_entry_read_units.read() - abort"); //abort(); } } } this.unref(); return(result); }
//~handler_entry_write_delegate() = default; public override void write(offs_t offset, uX data, uX mem_mask) { //write_impl<WRITE>(offset, data, mem_mask); if (m_delegate8 != null) { write_impl(m_delegate8, offset, data, mem_mask); } else if (m_delegate8sm != null) { write_impl(m_delegate8sm, offset, data, mem_mask); } else if (m_delegate8smo != null) { write_impl(m_delegate8smo, offset, data, mem_mask); } else if (m_delegate16 != null) { write_impl(m_delegate16, offset, data, mem_mask); } else if (m_delegate16s != null) { write_impl(m_delegate16s, offset, data, mem_mask); } else if (m_delegate16smo != null) { write_impl(m_delegate16smo, offset, data, mem_mask); } else { throw new emu_unimplemented(); } }
public override void write(offs_t offset, uX data, uX mem_mask) //template<int Width, int AddrShift> void handler_entry_write_units<Width, AddrShift>::write(offs_t offset, uX data, uX mem_mask) { this.ref_(); for (int index = 0; index < m_subunits; index++) { subunit_info si = m_subunit_infos[index]; if ((mem_mask & si.m_amask) != 0) { offs_t aoffset = (si.m_ashift >= 0 ? offset >> si.m_ashift : offset << si.m_ashift) + si.m_offset; switch (si.m_width) { case 0: ((handler_entry_write <int_const_0, int_const_0>)si.m_handler).write(aoffset, data >> si.m_dshift, mem_mask >> si.m_dshift); //static_cast<handler_entry_write<0, 0> *>(si.m_handler)->write(aoffset, data >> si.m_dshift, mem_mask >> si.m_dshift); break; case 1: ((handler_entry_write <int_const_1, int_const_n1>)si.m_handler).write(aoffset, data >> si.m_dshift, mem_mask >> si.m_dshift); //static_cast<handler_entry_write<1, -1> *>(si.m_handler)->write(aoffset, data >> si.m_dshift, mem_mask >> si.m_dshift); break; case 2: ((handler_entry_write <int_const_2, int_const_n2>)si.m_handler).write(aoffset, data >> si.m_dshift, mem_mask >> si.m_dshift); //static_cast<handler_entry_write<2, -2> *>(si.m_handler)->write(aoffset, data >> si.m_dshift, mem_mask >> si.m_dshift); break; default: throw new emu_fatalerror("handler_entry_write_units.write() - abort"); //abort(); } } } this.unref(); }
//~handler_entry_write_memory() = default; //template<int Width, int AddrShift> public override void write(offs_t offset, uX data, uX mem_mask) //void handler_entry_write_memory<Width, AddrShift>::write(offs_t offset, uX data, uX mem_mask) const { if (Width == 0 && AddrShift == 0 && data.width == 0 && mem_mask == 0) { //template<> void handler_entry_write_memory<0, 0>::write(offs_t offset, u8 data, u8 mem_mask) const m_base.m_pointer[(offset - this.m_address_base) & this.m_address_mask] = data.u8; //m_base[(offset - this->m_address_base) & this->m_address_mask] = data; } else { offs_t off = ((offset - this.m_address_base) & this.m_address_mask) >> (Width + AddrShift); //m_base[off] = (m_base[off] & ~mem_mask) | (data & mem_mask); switch (Width) { case 0: m_base.m_pointer[off] = (u8)((m_base.m_pointer[off] & ~mem_mask.u8) | (data.u8 & mem_mask.u8)); break; case 1: var pointerU16 = new PointerU16(m_base.m_pointer); pointerU16[off] = (u16)((pointerU16[off] & ~mem_mask.u16) | (data.u16 & mem_mask.u16)); break; case 2: throw new emu_unimplemented(); case 3: throw new emu_unimplemented(); default: throw new emu_unimplemented(); } } }
//~handler_entry_write_unmapped() = default; public override void write(offs_t offset, uX data, uX mem_mask) { if (m_space.log_unmap() && !m_space.m_manager.machine().side_effects_disabled()) { m_space.device().logerror(m_space.is_octal() ? "{0}: unmapped {1} memory write to {2} = {3} & {4}\n" // %0*o = %0*o & %0*o\n" : "{0}: unmapped {1} memory write to {2} = {3} & {4}\n", // %0*X = %0*X & %0*X\n", m_space.m_manager.machine().describe_context(), m_space.name(), m_space.addrchars(), offset, 2 << Width, data, 2 << Width, mem_mask); } }
//~handler_entry_read_unmapped() = default; public override uX read(offs_t offset, uX mem_mask) { if (m_space.log_unmap() && !m_space.m_manager.machine().side_effects_disabled()) { m_space.device().logerror(m_space.is_octal() ? "{0}: unmapped {1} memory read from {2} & {3}\n" //? "%s: unmapped %s memory read from %0*o & %0*o\n" : "{0}: unmapped {1} memory read from {2} & {3}\n", //: "%s: unmapped %s memory read from %0*X & %0*X\n", m_space.m_manager.machine().describe_context(), m_space.name(), m_space.addrchars(), offset, 2 << Width, mem_mask); } return(new uX(Width, m_space.unmap())); }
//template<typename T> static u8 mask_to_ukey(T mask); u8 mask_to_ukey(uX mask) { switch (mask.width) { case 0: return(mask_to_ukey_u8(mask.u8)); case 1: return(mask_to_ukey_u16(mask.u16)); case 2: return(mask_to_ukey_u32(mask.u32)); case 3: return(mask_to_ukey_u64(mask.u64)); default: throw new emu_unimplemented(); } }
//~handler_entry_read_memory() = default; public override uX read(offs_t offset, uX mem_mask) { //return m_base[((offset - inh::m_address_base) & inh::m_address_mask) >> (Width + AddrShift)]; switch (Width) { case 0: return(new uX(Width, m_base.m_pointer[((offset - m_address_base) & m_address_mask) >> (Width + AddrShift)])); case 1: return(new uX(Width, new PointerU16(m_base.m_pointer)[((offset - m_address_base) & m_address_mask) >> (Width + AddrShift)])); case 2: throw new emu_unimplemented(); case 3: throw new emu_unimplemented(); default: throw new emu_unimplemented(); } }
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()); } m_unmap = new uX(Width, m_space.unmap()); for (int i = 0; i < m_subunits; i++) { m_unmap &= ~m_subunit_infos[i].m_dmask; } }
//~handler_entry_read_delegate() = default; public override uX read(offs_t offset, uX mem_mask) { //return read_impl<READ>(offset, mem_mask); if (m_delegate8 != null) { return(read_impl(m_delegate8, offset, mem_mask)); } else if (m_delegate8m != null) { return(read_impl(m_delegate8m, offset, mem_mask)); } else if (m_delegate8sm != null) { return(read_impl(m_delegate8sm, offset, mem_mask)); } else if (m_delegate8mo != null) { return(read_impl(m_delegate8mo, offset, mem_mask)); } else if (m_delegate8smo != null) { return(read_impl(m_delegate8smo, offset, mem_mask)); } else if (m_delegate16 != null) { return(read_impl(m_delegate16, offset, mem_mask)); } else if (m_delegate16s != null) { return(read_impl(m_delegate16s, offset, mem_mask)); } else { throw new emu_unimplemented(); } }
void write_impl(write16smo_delegate delegate_, offs_t offset, uX data, uX mem_mask) { m_delegate16smo(data.u16); //m_delegate(data); }
//~handler_entry_read_ioport() = default; public override uX read(offs_t offset, uX mem_mask) { return(new uX(Width, m_port.read())); }
void write_impl(write16_delegate delegate_, offs_t offset, uX data, uX mem_mask) { m_delegate16(m_space, ((offset - m_address_base) & m_address_mask) >> (Width + AddrShift), data.u16, mem_mask.u16); //m_delegate(*inh::m_space, ((offset - inh::m_address_base) & inh::m_address_mask) >> (Width + AddrShift), data, mem_mask); }
//template<typename W> // std::enable_if_t<std::is_same<W, write8sm_delegate>::value || // std::is_same<W, write16sm_delegate>::value || // std::is_same<W, write32sm_delegate>::value || // std::is_same<W, write64sm_delegate>::value, // void> write_impl(offs_t offset, uX data, uX mem_mask); void write_impl(write8sm_delegate delegate_, offs_t offset, uX data, uX mem_mask) { m_delegate8sm(((offset - m_address_base) & m_address_mask) >> (Width + AddrShift), data.u8); //m_delegate(((offset - inh::m_address_base) & inh::m_address_mask) >> (Width + AddrShift), data); }
//template<typename R> // std::enable_if_t<std::is_same<R, read8smo_delegate>::value || // std::is_same<R, read16smo_delegate>::value || // std::is_same<R, read32smo_delegate>::value || // std::is_same<R, read64smo_delegate>::value, // uX> read_impl(offs_t offset, uX mem_mask); uX read_impl(read8smo_delegate delegate_, offs_t offset, uX mem_mask) { //return m_delegate(); return(new uX(Width, m_delegate8smo())); }
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; }
//template<typename R> // std::enable_if_t<std::is_same<R, read8sm_delegate>::value || // std::is_same<R, read16sm_delegate>::value || // std::is_same<R, read32sm_delegate>::value || // std::is_same<R, read64sm_delegate>::value, // uX> read_impl(offs_t offset, uX mem_mask); uX read_impl(read8sm_delegate delegate_, offs_t offset, uX mem_mask) { //return m_delegate(((offset - inh::m_address_base) & inh::m_address_mask) >> (Width + AddrShift)); return(new uX(Width, m_delegate8sm(((offset - m_address_base) & m_address_mask) >> (Width + AddrShift)))); }
//~handler_entry_write_nop() = default; public override void write(offs_t offset, uX data, uX mem_mask) { }
uX read_impl(read16_delegate delegate_, offs_t offset, uX mem_mask) { //return m_delegate(*inh::m_space, ((offset - inh::m_address_base) & inh::m_address_mask) >> (Width + AddrShift), mem_mask); return(new uX(Width, m_delegate16(m_space, ((offset - m_address_base) & m_address_mask) >> (Width + AddrShift), mem_mask.u16))); }
//template<typename R> // std::enable_if_t<std::is_same<R, read8m_delegate>::value || // std::is_same<R, read16m_delegate>::value || // std::is_same<R, read32m_delegate>::value || // std::is_same<R, read64m_delegate>::value, // uX> read_impl(offs_t offset, uX mem_mask); uX read_impl(read8m_delegate delegate_, offs_t offset, uX mem_mask) { //return m_delegate(*this->m_space, ((offset - this->m_address_base) & this->m_address_mask) >> (Width + AddrShift)); return(new uX(Width, m_delegate8m(this.m_space, ((offset - m_address_base) & m_address_mask) >> (Width + AddrShift)))); }
//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 entry(uX amask, uX dmask, s8 ashift, u8 dshift, u8 offset) { m_amask = amask; m_dmask = dmask; m_ashift = ashift; m_dshift = dshift; m_offset = offset; }
//~handler_entry_read_nop() = default; public override uX read(offs_t offset, uX mem_mask) { return(new uX(Width, m_space.unmap())); }
//~handler_entry_write_ioport() = default; public override void write(offs_t offset, uX data, uX mem_mask) { throw new emu_unimplemented(); }
//template<typename R> // std::enable_if_t<std::is_same<R, read8mo_delegate>::value || // std::is_same<R, read16mo_delegate>::value || // std::is_same<R, read32mo_delegate>::value || // std::is_same<R, read64mo_delegate>::value, // uX> read_impl(offs_t offset, uX mem_mask); uX read_impl(read8mo_delegate delegate_, offs_t offset, uX mem_mask) { //return m_delegate(*this->m_space); return(new uX(Width, m_delegate8mo(m_space))); }
public override void write(offs_t offset, uX data, uX mem_mask) { dispatch_write <int_const_Level, int_Width, int_AddrShift>(HIGHMASK, offset, data, mem_mask, m_a_dispatch); }
public override uX read(offs_t offset, uX mem_mask) { return(dispatch_read <int_const_Level, int_Width, int_AddrShift>(HIGHMASK, offset, mem_mask, m_a_dispatch)); }