コード例 #1
0
        //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++;
                }
            }
        }
コード例 #2
0
        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; });
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        //~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();
            }
        }
コード例 #5
0
        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();
        }
コード例 #6
0
        //~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();
                }
            }
        }
コード例 #7
0
        //~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);
            }
        }
コード例 #8
0
        //~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()));
        }
コード例 #9
0
        //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();
            }
        }
コード例 #10
0
        //~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();
            }
        }
コード例 #11
0
        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;
            }
        }
コード例 #12
0
        //~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();
            }
        }
コード例 #13
0
 void write_impl(write16smo_delegate delegate_, offs_t offset, uX data, uX mem_mask)
 {
     m_delegate16smo(data.u16);  //m_delegate(data);
 }
コード例 #14
0
        //~handler_entry_read_ioport() = default;


        public override uX read(offs_t offset, uX mem_mask)
        {
            return(new uX(Width, m_port.read()));
        }
コード例 #15
0
 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);
 }
コード例 #16
0
 //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);
 }
コード例 #17
0
 //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()));
 }
コード例 #18
0
            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;
            }
コード例 #19
0
 //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))));
 }
コード例 #20
0
        //~handler_entry_write_nop() = default;


        public override void write(offs_t offset, uX data, uX mem_mask)
        {
        }
コード例 #21
0
 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)));
 }
コード例 #22
0
 //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))));
 }
コード例 #23
0
        //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);
                }
            }
        }
コード例 #24
0
 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;
 }
コード例 #25
0
        //~handler_entry_read_nop() = default;


        public override uX read(offs_t offset, uX mem_mask)
        {
            return(new uX(Width, m_space.unmap()));
        }
コード例 #26
0
        //~handler_entry_write_ioport() = default;


        public override void write(offs_t offset, uX data, uX mem_mask)
        {
            throw new emu_unimplemented();
        }
コード例 #27
0
 //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)));
 }
コード例 #28
0
 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);
 }
コード例 #29
0
 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));
 }