public handler_entry_read_dispatch(int HighBits, int Width, int AddrShift, int Endian, address_space space, handler_entry.range init, handler_entry_read handler) : base(Width, AddrShift, Endian, space, handler_entry.F_DISPATCH) { this.HighBits = HighBits; LowBits = (u32)handler_entry_dispatch_lowbits(HighBits, Width, AddrShift); BITCOUNT = (u32)HighBits > LowBits ? (u32)HighBits - LowBits : 0; COUNT = 1U << (int)BITCOUNT; BITMASK = make_bitmask32(BITCOUNT); LOWMASK = make_bitmask32(LowBits); HIGHMASK = make_bitmask32((u32)HighBits) ^ LOWMASK; if (handler == null) { handler = space.get_unmap_r(); } handler.ref_((s32)COUNT); m_dispatch = new handler_entry_read[COUNT]; m_ranges = new handler_entry.range[COUNT]; for (UInt32 i = 0; i != COUNT; i++) { m_dispatch[i] = handler; m_ranges[i] = init; } }
Pointer <handler_entry.range> m_u_ranges; //handler_entry::range *m_u_ranges; public handler_entry_read_dispatch(address_space space, handler_entry.range init, handler_entry_read <int_Width, int_AddrShift> handler) : base(space, handler_entry.F_DISPATCH) { m_ranges_array.resize(1); m_ranges_array[0] = new range_array(); m_dispatch_array.resize(1); m_dispatch_array[0] = new handler_array(); m_a_ranges = m_ranges_array[0].data(); m_a_dispatch = m_dispatch_array[0].data(); m_u_ranges = m_ranges_array[0].data(); m_u_dispatch = m_dispatch_array[0].data(); if (handler == null) { handler = space.get_unmap_r <int_Width, int_AddrShift>(); } handler.ref_((s32)COUNT); for (unsigned i = 0; i != COUNT; i++) { m_u_dispatch[i] = handler; m_u_ranges[i] = new range(init); } }
void mismatched_patch(memory_units_descriptor <int_Width, int_AddrShift> descriptor, u8 rkey, std.vector <mapping> mappings, ref handler_entry_read <int_Width, int_AddrShift> target) { u8 ukey = descriptor.rkey_to_ukey(rkey); handler_entry_read <int_Width, int_AddrShift> original = target.is_units() ? target : null; handler_entry_read <int_Width, int_AddrShift> replacement = null; foreach (var p in mappings) { if (p.ukey == ukey && p.original == original) { replacement = p.patched; break; } } if (replacement == null) { if (original != null) { replacement = new handler_entry_read_units <int_Width, int_AddrShift>(descriptor, ukey, (handler_entry_read_units <int_Width, int_AddrShift>)original); } else { replacement = new handler_entry_read_units <int_Width, int_AddrShift>(descriptor, ukey, m_space); } mappings.emplace_back(new mapping() { original = original, patched = replacement, ukey = ukey }); } else { replacement.ref_(); } target.unref(); target = replacement; }
void populate_mirror_subdispatch(offs_t entry, offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read handler) { var cur = m_dispatch[entry]; if (cur.is_dispatch()) { cur.populate_mirror(start, end, ostart, oend, mirror, handler); } else { var subdispatch = new handler_entry_read_dispatch((int)LowBits, Width, AddrShift, Endian, m_space, m_ranges[entry], cur); cur.unref(); m_dispatch[entry] = subdispatch; subdispatch.populate_mirror(start, end, ostart, oend, mirror, handler); } }
public override void populate_mirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read handler) { offs_t hmirror = mirror & HIGHMASK; offs_t lmirror = mirror & LOWMASK; if (lmirror != 0) { // If lmirror is non-zero, then each mirror instance is a single entry offs_t add = 1 + ~hmirror; offs_t offset = 0; offs_t base_entry = start >> (int)LowBits; start &= LOWMASK; end &= LOWMASK; do { if (offset != 0) { handler.ref_(); } populate_mirror_subdispatch(base_entry | (offset >> (int)LowBits), start, end, ostart | offset, oend | offset, lmirror, handler); offset = (offset + add) & hmirror; } while (offset != 0); } else { // If lmirror is zero, call the nomirror version as needed offs_t add = 1 + ~hmirror; offs_t offset = 0; do { if (offset != 0) { handler.ref_(); } populate_nomirror(start | offset, end | offset, ostart | offset, oend | offset, handler); offset = (offset + add) & hmirror; } while (offset != 0); } }
//void dump_map(std::vector<memory_entry> &map) const override; //std::string name() const override; public override void populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read handler) { offs_t start_entry = start >> (int)LowBits; offs_t end_entry = end >> (int)LowBits; range_cut_before(ostart - 1, (int)start_entry); range_cut_after(oend + 1, (int)end_entry); if (LowBits <= Width + AddrShift) { handler.ref_((int)(end_entry - start_entry)); for (offs_t ent = start_entry; ent <= end_entry; ent++) { m_dispatch[ent].unref(); m_dispatch[ent] = handler; m_ranges[ent].set(ostart, oend); } } else if (start_entry == end_entry) { if ((start & LOWMASK) == 0 && (end & LOWMASK) == LOWMASK) { m_dispatch[start_entry].unref(); m_dispatch[start_entry] = handler; m_ranges[start_entry].set(ostart, oend); } else { populate_nomirror_subdispatch(start_entry, start & LOWMASK, end & LOWMASK, ostart, oend, handler); } } else { if ((start & LOWMASK) != 0) { populate_nomirror_subdispatch(start_entry, start & LOWMASK, LOWMASK, ostart, oend, handler); start_entry++; if (start_entry <= end_entry) { handler.ref_(); } } if ((end & LOWMASK) != LOWMASK) { populate_nomirror_subdispatch(end_entry, 0, end & LOWMASK, ostart, oend, handler); end_entry--; if (start_entry <= end_entry) { handler.ref_(); } } if (start_entry <= end_entry) { handler.ref_((int)(end_entry - start_entry)); for (offs_t ent = start_entry; ent <= end_entry; ent++) { m_dispatch[ent].unref(); m_dispatch[ent] = handler; m_ranges[ent].set(ostart, oend); } } } }
//void *get_ptr(offs_t offset) const override; public override void lookup(offs_t address, ref offs_t start, ref offs_t end, ref handler_entry_read handler) { offs_t slot = (address >> (int)LowBits) & BITMASK; var h = m_dispatch[slot]; if (h.is_dispatch()) { h.lookup(address, ref start, ref end, ref handler); } else { start = m_ranges[slot].start; end = m_ranges[slot].end; handler = h; } }
void populate_mirror_subdispatch(offs_t entry, offs_t start, offs_t end, offs_t ostart, offs_t oend, offs_t mirror, handler_entry_read <int_Width, int_AddrShift> handler) { var cur = m_u_dispatch[entry]; if (cur.is_dispatch()) { cur.populate_mirror(start, end, ostart, oend, mirror, handler); } else { var subdispatch = new handler_entry_read_dispatch <int_const_LowBits, int_Width, int_AddrShift>(m_space, m_u_ranges[entry], cur); //auto subdispatch = new handler_entry_read_dispatch<LowBits, Width, AddrShift>(handler_entry::m_space, m_u_ranges[entry], cur); cur.unref(); m_u_dispatch[entry] = subdispatch; subdispatch.populate_mirror(start, end, ostart, oend, mirror, handler); } }
public override void populate_nomirror(offs_t start, offs_t end, offs_t ostart, offs_t oend, handler_entry_read <int_Width, int_AddrShift> handler) { offs_t start_entry = (start & HIGHMASK) >> (int)LowBits; offs_t end_entry = (end & HIGHMASK) >> (int)LowBits; range_cut_before(ostart - 1, (int)start_entry); range_cut_after(oend + 1, (int)end_entry); if (LowBits <= Width + AddrShift) { if (handler.is_view()) { int delta = (int)(dispatch_entry(ostart) - handler.dispatch_entry(ostart)); handler.init_handlers(start >> (int)LowBits, end >> (int)LowBits, LowBits, ostart, oend, m_u_dispatch + delta, m_u_ranges + delta); } handler.ref_((int)(end_entry - start_entry)); for (offs_t ent = start_entry; ent <= end_entry; ent++) { m_u_dispatch[ent].unref(); m_u_dispatch[ent] = handler; m_u_ranges[ent].set(ostart, oend); } } else if (start_entry == end_entry) { if ((start & LOWMASK) == 0 && (end & LOWMASK) == LOWMASK) { if (handler.is_view()) { int delta = (int)(dispatch_entry(ostart) - handler.dispatch_entry(ostart)); handler.init_handlers(start >> (int)LowBits, end >> (int)LowBits, LowBits, ostart, oend, m_u_dispatch + delta, m_u_ranges + delta); } m_u_dispatch[start_entry].unref(); m_u_dispatch[start_entry] = handler; m_u_ranges[start_entry].set(ostart, oend); } else { populate_nomirror_subdispatch(start_entry, start, end, ostart, oend, handler); } } else { if ((start & LOWMASK) != 0) { populate_nomirror_subdispatch(start_entry, start, start | LOWMASK, ostart, oend, handler); start_entry++; start = (start | LOWMASK) + 1; if (start_entry <= end_entry) { handler.ref_(); } } if ((end & LOWMASK) != LOWMASK) { populate_nomirror_subdispatch(end_entry, end & ~LOWMASK, end, ostart, oend, handler); end_entry--; end = (end & ~LOWMASK) - 1; if (start_entry <= end_entry) { handler.ref_(); } } if (start_entry <= end_entry) { if (handler.is_view()) { int delta = (int)(dispatch_entry(ostart) - handler.dispatch_entry(ostart)); handler.init_handlers(start >> (int)LowBits, end >> (int)LowBits, LowBits, ostart, oend, m_u_dispatch + delta, m_u_ranges + delta); } handler.ref_((int)(end_entry - start_entry)); for (offs_t ent = start_entry; ent <= end_entry; ent++) { m_u_dispatch[ent].unref(); m_u_dispatch[ent] = handler; m_u_ranges[ent].set(ostart, oend); } } } }
protected abstract handler_entry_read_passthrough <int_Width, int_AddrShift> instantiate(handler_entry_read <int_Width, int_AddrShift> next);
handler_entry_read_passthrough(address_space space, memory_passthrough_handler mph, handler_entry_read <int_Width, int_AddrShift> next) : base(space, handler_entry.F_PASSTHROUGH) { m_mph = mph; m_next = next; next.ref_(); mph.add_handler(this); }
handler_entry_read <int_Width, int_AddrShift> m_next; //handler_entry_read<Width, AddrShift, Endian> *m_next; handler_entry_read_passthrough(address_space space, memory_passthrough_handler mph) : base(space, handler_entry.F_PASSTHROUGH) { m_mph = mph; m_next = null; }