Previous 199869 Revisions Next

r23729 Saturday 15th June, 2013 at 21:05:10 UTC by O. Galibert
memory: Need moar tables [O. Galibert]
[src/emu]memory.c memory.h

trunk/src/emu/memory.c
r23728r23729
6464
6565        0 .. STATIC_COUNT - 1 = fixed handlers
6666        STATIC_COUNT .. SUBTABLE_BASE - 1 = driver-specific handlers
67        SUBTABLE_BASE .. 255 = need to look up lower bits in subtable
67        SUBTABLE_BASE .. TOTAL_MEMORY_BANKS - 1 = need to look up lower bits in subtable
6868
6969    Caveats:
7070
r23728r23729
565565   static const int LEVEL1_BITS    = 18;                       // number of address bits in the level 1 table
566566   static const int LEVEL2_BITS    = 32 - LEVEL1_BITS;         // number of address bits in the level 2 table
567567   static const int SUBTABLE_COUNT = 64;                       // number of slots reserved for subtables
568   static const int SUBTABLE_BASE  = 256 - SUBTABLE_COUNT;     // first index of a subtable
568   static const int SUBTABLE_BASE  = TOTAL_MEMORY_BANKS - SUBTABLE_COUNT;     // first index of a subtable
569569   static const int ENTRY_COUNT    = SUBTABLE_BASE;            // number of legitimate (non-subtable) entries
570570   static const int SUBTABLE_ALLOC = 8;                        // number of subtables to allocate at a time
571571
r23728r23729
604604   void enable_watchpoints(bool enable = true) { m_live_lookup = enable ? s_watchpoint_table : m_table; }
605605
606606   // table mapping helpers
607   void map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT8 staticentry);
607   void map_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT16 staticentry);
608608   void setup_range(offs_t bytestart, offs_t byteend, offs_t bytemask, offs_t bytemirror, UINT64 mask, std::list<UINT32> &entries);
609   UINT8 derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const;
609   UINT16 derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const;
610610
611611   // misc helpers
612612   void mask_all_handlers(offs_t mask);
613   const char *handler_name(UINT8 entry) const;
613   const char *handler_name(UINT16 entry) const;
614614
615615protected:
616616   // determine table indexes based on the address
617617   UINT32 level1_index_large(offs_t address) const { return address >> LEVEL2_BITS; }
618   UINT32 level2_index_large(UINT8 l1entry, offs_t address) const { return (1 << LEVEL1_BITS) + ((l1entry - SUBTABLE_BASE) << LEVEL2_BITS) + (address & ((1 << LEVEL2_BITS) - 1)); }
618   UINT32 level2_index_large(UINT16 l1entry, offs_t address) const { return (1 << LEVEL1_BITS) + ((l1entry - SUBTABLE_BASE) << LEVEL2_BITS) + (address & ((1 << LEVEL2_BITS) - 1)); }
619619   UINT32 level1_index(offs_t address) const { return m_large ? level1_index_large(address) : address; }
620   UINT32 level2_index(UINT8 l1entry, offs_t address) const { return m_large ? level2_index_large(l1entry, address) : 0; }
620   UINT32 level2_index(UINT16 l1entry, offs_t address) const { return m_large ? level2_index_large(l1entry, address) : 0; }
621621
622622   // table population/depopulation
623   void populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handler);
624   void populate_range(offs_t bytestart, offs_t byteend, UINT8 handler);
623   void populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT16 handler);
624   void populate_range(offs_t bytestart, offs_t byteend, UINT16 handler);
625625
626626   // subtable management
627   UINT8 subtable_alloc();
628   void subtable_realloc(UINT8 subentry);
627   UINT16 subtable_alloc();
628   void subtable_realloc(UINT16 subentry);
629629   int subtable_merge();
630   void subtable_release(UINT8 subentry);
631   UINT8 *subtable_open(offs_t l1index);
630   void subtable_release(UINT16 subentry);
631   UINT16 *subtable_open(offs_t l1index);
632632   void subtable_close(offs_t l1index);
633   UINT8 *subtable_ptr(UINT8 entry) { return &m_table[level2_index(entry, 0)]; }
633   UINT16 *subtable_ptr(UINT16 entry) { return &m_table[level2_index(entry, 0)]; }
634634
635635   // internal state
636   UINT8 *                 m_table;                    // pointer to base of table
637   UINT8 *                 m_live_lookup;              // current lookup
636   UINT16 *                m_table;                    // pointer to base of table
637   UINT16 *                m_live_lookup;              // current lookup
638638   address_space &         m_space;                    // pointer back to the space
639639   bool                    m_large;                    // large memory model?
640640
r23728r23729
652652      UINT32              m_usecount;                 // number of times this has been used
653653   };
654654   subtable_data *         m_subtable;                 // info about each subtable
655   UINT8                   m_subtable_alloc;           // number of subtables allocated
655   UINT16                  m_subtable_alloc;           // number of subtables allocated
656656
657657   // static global read-only watchpoint table
658   static UINT8            s_watchpoint_table[1 << LEVEL1_BITS];
658   static UINT16           s_watchpoint_table[1 << LEVEL1_BITS];
659659
660660private:
661661   int handler_refcount[SUBTABLE_BASE-STATIC_COUNT];
662   UINT8 handler_next_free[SUBTABLE_BASE-STATIC_COUNT];
663   UINT8 handler_free;
664   UINT8 get_free_handler();
662   UINT16 handler_next_free[SUBTABLE_BASE-STATIC_COUNT];
663   UINT16 handler_free;
664   UINT16 get_free_handler();
665665   void verify_reference_counts();
666666   void setup_range_solid(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, std::list<UINT32> &entries);
667667   void setup_range_masked(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT64 mask, std::list<UINT32> &entries);
668668
669   void handler_ref(UINT8 entry, int count)
669   void handler_ref(UINT16 entry, int count)
670670   {
671671      assert(entry < SUBTABLE_BASE);
672672      if (entry >= STATIC_COUNT)
673673         handler_refcount[entry - STATIC_COUNT] += count;
674674   }
675675
676   void handler_unref(UINT8 entry)
676   void handler_unref(UINT16 entry)
677677   {
678678      assert(entry < SUBTABLE_BASE);
679679      if (entry >= STATIC_COUNT)
r23728r23729
742742   {
743743      m_space.device().debug()->memory_read_hook(m_space, offset * sizeof(_UintType), mask);
744744
745      UINT8 *oldtable = m_live_lookup;
745      UINT16 *oldtable = m_live_lookup;
746746      m_live_lookup = m_table;
747747      _UintType result;
748748      if (sizeof(_UintType) == 1) result = m_space.read_byte(offset);
r23728r23729
754754   }
755755
756756   // internal state
757   handler_entry_read *        m_handlers[256];        // array of user-installed handlers
757   handler_entry_read *        m_handlers[TOTAL_MEMORY_BANKS];        // array of user-installed handlers
758758};
759759
760760
r23728r23729
810810   {
811811      m_space.device().debug()->memory_write_hook(m_space, offset * sizeof(_UintType), data, mask);
812812
813      UINT8 *oldtable = m_live_lookup;
813      UINT16 *oldtable = m_live_lookup;
814814      m_live_lookup = m_table;
815815      if (sizeof(_UintType) == 1) m_space.write_byte(offset, data);
816816      if (sizeof(_UintType) == 2) m_space.write_word(offset << 1, data, mask);
r23728r23729
820820   }
821821
822822   // internal state
823   handler_entry_write *       m_handlers[256];        // array of user-installed handlers
823   handler_entry_write *       m_handlers[TOTAL_MEMORY_BANKS];        // array of user-installed handlers
824824};
825825
826826
r23728r23729
14591459//**************************************************************************
14601460
14611461// global watchpoint table
1462UINT8 address_table::s_watchpoint_table[1 << LEVEL1_BITS];
1462UINT16 address_table::s_watchpoint_table[1 << LEVEL1_BITS];
14631463
14641464
14651465
r23728r23729
22082208   offs_t bytestart, byteend;
22092209   for (offs_t byteaddress = 0; byteaddress <= m_bytemask; byteaddress = byteend)
22102210   {
2211      UINT8 entry = table.derive_range(byteaddress, bytestart, byteend);
2211      UINT16 entry = table.derive_range(byteaddress, bytestart, byteend);
22122212      fprintf(file, "%08X-%08X    = %02X: %s [offset=%08X]\n",
22132213                  bytestart, byteend, entry, table.handler_name(entry), table.handler(entry).bytestart());
22142214      if (++byteend == 0)
r23728r23729
27872787//-------------------------------------------------
27882788
27892789address_table::address_table(address_space &space, bool large)
2790   : m_table(auto_alloc_array(space.machine(), UINT8, 1 << LEVEL1_BITS)),
2790   : m_table(auto_alloc_array(space.machine(), UINT16, 1 << LEVEL1_BITS)),
27912791      m_live_lookup(m_table),
27922792      m_space(space),
27932793      m_large(large),
r23728r23729
27962796{
27972797   // make our static table all watchpoints
27982798   if (s_watchpoint_table[0] != STATIC_WATCHPOINT)
2799      memset(s_watchpoint_table, STATIC_WATCHPOINT, sizeof(s_watchpoint_table));
2799      for (unsigned int i=0; i != sizeof(s_watchpoint_table)/sizeof(s_watchpoint_table[0]); i++)
2800         s_watchpoint_table[i] = STATIC_WATCHPOINT;
28002801
28012802   // initialize everything to unmapped
2802   memset(m_table, STATIC_UNMAP, 1 << LEVEL1_BITS);
2803   for (unsigned int i=0; i != 1 << LEVEL1_BITS; i++)
2804      m_table[i] = STATIC_UNMAP;
28032805
28042806   // initialize the handlers freelist
28052807   for (int i=0; i != SUBTABLE_BASE-STATIC_COUNT-1; i++)
r23728r23729
28282830//  map
28292831//-------------------------------------------------
28302832
2831void address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT8 entry)
2833void address_table::map_range(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, UINT16 entry)
28322834{
28332835   // convert addresses to bytes
28342836   offs_t bytestart = addrstart;
r23728r23729
28562858   //  verify_reference_counts();
28572859}
28582860
2859UINT8 address_table::get_free_handler()
2861UINT16 address_table::get_free_handler()
28602862{
28612863   if (handler_free == STATIC_INVALID)
28622864      throw emu_fatalerror("Out of handler entries in address table");
28632865
2864   UINT8 handler = handler_free;
2866   UINT16 handler = handler_free;
28652867   handler_free = handler_next_free[handler - STATIC_COUNT];
28662868   return handler;
28672869}
r23728r23729
28932895void address_table::setup_range_solid(offs_t addrstart, offs_t addrend, offs_t addrmask, offs_t addrmirror, std::list<UINT32> &entries)
28942896{
28952897   // Grab a free entry
2896   UINT8 entry = get_free_handler();
2898   UINT16 entry = get_free_handler();
28972899
28982900   // Add it in the "to be setup" list
28992901   entries.push_back(entry);
r23728r23729
29312933
29322934   // Scan the memory to see what has to be done
29332935   std::list<subrange> range_override;
2934   std::map<UINT8, std::list<subrange> > range_partial;
2936   std::map<UINT16, std::list<subrange> > range_partial;
29352937
29362938   offs_t base_mirror = 0;
29372939   do
r23728r23729
29422944      do
29432945      {
29442946         offs_t range_start, range_end;
2945         UINT8 entry = derive_range(base_address, range_start, range_end);
2947         UINT16 entry = derive_range(base_address, range_start, range_end);
29462948         UINT32 stop_address = range_end > end_address ? end_address : range_end;
29472949
29482950         if (entry < STATIC_COUNT || handler(entry).overriden_by_mask(mask))
r23728r23729
29632965   if (!range_override.empty())
29642966   {
29652967      // Grab a free entry
2966      UINT8 entry = get_free_handler();
2968      UINT16 entry = get_free_handler();
29672969
29682970      // configure the entry to our parameters
29692971      handler_entry &curentry = handler(entry);
r23728r23729
29832985   // Ranges in range_partial must duplicated then partially changed
29842986   if (!range_partial.empty())
29852987   {
2986      for (std::map<UINT8, std::list<subrange> >::const_iterator i = range_partial.begin(); i != range_partial.end(); i++)
2988      for (std::map<UINT16, std::list<subrange> >::const_iterator i = range_partial.begin(); i != range_partial.end(); i++)
29872989      {
29882990         // Theorically, if the handler to change matches the
29892991         // characteristics of ours, we can directly change it.  In
r23728r23729
30023004            throw emu_fatalerror("Handlers on different subunits of the same address with different address masks are not supported.");
30033005
30043006         // Grab a new handler and copy it there
3005         UINT8 entry = get_free_handler();
3007         UINT16 entry = get_free_handler();
30063008         handler_entry &curentry = handler(entry);
30073009         curentry.copy(base_entry);
30083010
r23728r23729
30383040   int actual_refcounts[SUBTABLE_BASE-STATIC_COUNT];
30393041   memset(actual_refcounts, 0, sizeof(actual_refcounts));
30403042
3041   bool subtable_seen[256 - SUBTABLE_BASE];
3043   bool subtable_seen[TOTAL_MEMORY_BANKS - SUBTABLE_BASE];
30423044   memset(subtable_seen, 0, sizeof(subtable_seen));
30433045
30443046   for (int level1 = 0; level1 != 1 << LEVEL1_BITS; level1++)
30453047   {
3046      UINT8 l1_entry = m_table[level1];
3048      UINT16 l1_entry = m_table[level1];
30473049      if (l1_entry >= SUBTABLE_BASE)
30483050      {
30493051         assert(m_large);
r23728r23729
30513053            continue;
30523054
30533055         subtable_seen[l1_entry - SUBTABLE_BASE] = true;
3054         const UINT8 *subtable = subtable_ptr(l1_entry);
3056         const UINT16 *subtable = subtable_ptr(l1_entry);
30553057         for (int level2 = 0; level2 != 1 << LEVEL2_BITS; level2++)
30563058         {
3057            UINT8 l2_entry = subtable[level2];
3059            UINT16 l2_entry = subtable[level2];
30583060            assert(l2_entry < SUBTABLE_BASE);
30593061            if (l2_entry >= STATIC_COUNT)
30603062               actual_refcounts[l2_entry - STATIC_COUNT]++;
r23728r23729
30793081//  range of addresses
30803082//-------------------------------------------------
30813083
3082void address_table::populate_range(offs_t bytestart, offs_t byteend, UINT8 handlerindex)
3084void address_table::populate_range(offs_t bytestart, offs_t byteend, UINT16 handlerindex)
30833085{
30843086   offs_t l2mask = (1 << level2_bits()) - 1;
30853087   offs_t l1start = bytestart >> level2_bits();
r23728r23729
30943096   // handle the starting edge if it's not on a block boundary
30953097   if (l2start != 0)
30963098   {
3097      UINT8 *subtable = subtable_open(l1start);
3099      UINT16 *subtable = subtable_open(l1start);
30983100
30993101      // if the start and stop end within the same block, handle that
31003102      if (l1start == l1stop)
r23728r23729
31243126   // handle the trailing edge if it's not on a block boundary
31253127   if (l2stop != l2mask)
31263128   {
3127      UINT8 *subtable = subtable_open(l1stop);
3129      UINT16 *subtable = subtable_open(l1stop);
31283130
31293131      // fill from the beginning
31303132      handler_ref(handlerindex, l2stop+1);
r23728r23729
31463148   handler_ref(handlerindex, l1stop - l1start + 1);
31473149   for (offs_t l1index = l1start; l1index <= l1stop; l1index++)
31483150   {
3149      UINT8 subindex = m_table[l1index];
3151      UINT16 subindex = m_table[l1index];
31503152
31513153      // if we have a subtable here, release it
31523154      if (subindex >= SUBTABLE_BASE)
r23728r23729
31643166//  mirrors
31653167//-------------------------------------------------
31663168
3167void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT8 handlerindex)
3169void address_table::populate_range_mirrored(offs_t bytestart, offs_t byteend, offs_t bytemirror, UINT16 handlerindex)
31683170{
31693171   // determine the mirror bits
31703172   offs_t lmirrorbits = 0;
r23728r23729
31803182         hmirrorbit[hmirrorbits++] = 1 << bit;
31813183
31823184   // loop over mirrors in the level 2 table
3183   UINT8 prev_entry = STATIC_INVALID;
3185   UINT16 prev_entry = STATIC_INVALID;
31843186   int prev_index = 0;
31853187   for (offs_t hmirrorcount = 0; hmirrorcount < (1 << hmirrorbits); hmirrorcount++)
31863188   {
r23728r23729
32533255//  range based on the lookup tables
32543256//-------------------------------------------------
32553257
3256UINT8 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const
3258UINT16 address_table::derive_range(offs_t byteaddress, offs_t &bytestart, offs_t &byteend) const
32573259{
32583260   // look up the initial address to get the entry we care about
3259   UINT8 l1entry;
3260   UINT8 entry = l1entry = m_table[level1_index(byteaddress)];
3261   UINT16 l1entry;
3262   UINT16 entry = l1entry = m_table[level1_index(byteaddress)];
32613263   if (l1entry >= SUBTABLE_BASE)
32623264      entry = m_table[level2_index(l1entry, byteaddress)];
32633265
r23728r23729
32663268   handler(entry).mirrored_start_end(byteaddress, minscan, maxscan);
32673269
32683270   // first scan backwards to find the start address
3269   UINT8 curl1entry = l1entry;
3270   UINT8 curentry = entry;
3271   UINT16 curl1entry = l1entry;
3272   UINT16 curentry = entry;
32713273   bytestart = byteaddress;
32723274   while (1)
32733275   {
r23728r23729
33683370//  and set its usecount to 1
33693371//-------------------------------------------------
33703372
3371UINT8 address_table::subtable_alloc()
3373UINT16 address_table::subtable_alloc()
33723374{
33733375   // loop
33743376   while (1)
33753377   {
33763378      // find a subtable with a usecount of 0
3377      for (UINT8 subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
3379      for (UINT16 subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
33783380         if (m_subtable[subindex].m_usecount == 0)
33793381         {
33803382            // if this is past our allocation budget, allocate some more
r23728r23729
33843386               m_subtable_alloc += SUBTABLE_ALLOC;
33853387               UINT32 newsize = (1 << LEVEL1_BITS) + (m_subtable_alloc << level2_bits());
33863388
3387               UINT8 *newtable = auto_alloc_array_clear(m_space.machine(), UINT8, newsize);
3388               memcpy(newtable, m_table, oldsize);
3389               UINT16 *newtable = auto_alloc_array_clear(m_space.machine(), UINT16, newsize);
3390               memcpy(newtable, m_table, 2*oldsize);
33893391               if (m_live_lookup == m_table)
33903392                  m_live_lookup = newtable;
33913393               auto_free(m_space.machine(), m_table);
33923394               m_table = newtable;
33933395            }
3394
33953396            // bump the usecount and return
33963397            m_subtable[subindex].m_usecount++;
33973398            return subindex + SUBTABLE_BASE;
r23728r23729
34093410//  a subtable
34103411//-------------------------------------------------
34113412
3412void address_table::subtable_realloc(UINT8 subentry)
3413void address_table::subtable_realloc(UINT16 subentry)
34133414{
3414   UINT8 subindex = subentry - SUBTABLE_BASE;
3415   UINT16 subindex = subentry - SUBTABLE_BASE;
34153416
34163417   // sanity check
34173418   if (m_subtable[subindex].m_usecount <= 0)
r23728r23729
34303431int address_table::subtable_merge()
34313432{
34323433   int merged = 0;
3433   UINT8 subindex;
3434   UINT16 subindex;
34343435
34353436   VPRINTF(("Merging subtables....\n"));
34363437
r23728r23729
34523453   for (subindex = 0; subindex < SUBTABLE_COUNT; subindex++)
34533454      if (m_subtable[subindex].m_usecount != 0)
34543455      {
3455         UINT8 *subtable = subtable_ptr(subindex + SUBTABLE_BASE);
3456         UINT16 *subtable = subtable_ptr(subindex + SUBTABLE_BASE);
34563457         UINT32 checksum = m_subtable[subindex].m_checksum;
3457         UINT8 sumindex;
3458         UINT16 sumindex;
34583459
34593460         for (sumindex = subindex + 1; sumindex < SUBTABLE_COUNT; sumindex++)
34603461            if (m_subtable[sumindex].m_usecount != 0 &&
34613462               m_subtable[sumindex].m_checksum == checksum &&
3462               !memcmp(subtable, subtable_ptr(sumindex + SUBTABLE_BASE), 1 << level2_bits()))
3463               !memcmp(subtable, subtable_ptr(sumindex + SUBTABLE_BASE), 2*(1 << level2_bits())))
34633464            {
34643465               int l1index;
34653466
r23728r23729
34863487//  a subtable and free it if we're done
34873488//-------------------------------------------------
34883489
3489void address_table::subtable_release(UINT8 subentry)
3490void address_table::subtable_release(UINT16 subentry)
34903491{
3491   UINT8 subindex = subentry - SUBTABLE_BASE;
3492
3492   UINT16 subindex = subentry - SUBTABLE_BASE;
34933493   // sanity check
34943494   if (m_subtable[subindex].m_usecount <= 0)
34953495      fatalerror("Called subtable_release on a table with a usecount of 0\n");
r23728r23729
35003500   if (m_subtable[subindex].m_usecount == 0)
35013501   {
35023502      m_subtable[subindex].m_checksum = 0;
3503      UINT8 *subtable = subtable_ptr(subentry);
3503      UINT16 *subtable = subtable_ptr(subentry);
35043504      for (int i = 0; i < (1 << LEVEL2_BITS); i++)
35053505         handler_unref(subtable[i]);
35063506   }
r23728r23729
35123512//  modification
35133513//-------------------------------------------------
35143514
3515UINT8 *address_table::subtable_open(offs_t l1index)
3515UINT16 *address_table::subtable_open(offs_t l1index)
35163516{
3517   UINT8 subentry = m_table[l1index];
3517   UINT16 subentry = m_table[l1index];
35183518
35193519   // if we don't have a subtable yet, allocate a new one
35203520   if (subentry < SUBTABLE_BASE)
35213521   {
35223522      int size = 1 << level2_bits();
3523      UINT8 newentry = subtable_alloc();
3523      UINT16 newentry = subtable_alloc();
35243524      handler_ref(subentry, size-1);
3525      memset(subtable_ptr(newentry), subentry, size);
3525      UINT16 *subptr = subtable_ptr(newentry);
3526      for (int i=0; i<size; i++)
3527         subptr[i] = subentry;
35263528      m_table[l1index] = newentry;
35273529      m_subtable[newentry - SUBTABLE_BASE].m_checksum = (subentry + (subentry << 8) + (subentry << 16) + (subentry << 24)) * ((1 << level2_bits())/4);
35283530      subentry = newentry;
r23728r23729
35313533   // if we're sharing this subtable, we also need to allocate a fresh copy
35323534   else if (m_subtable[subentry - SUBTABLE_BASE].m_usecount > 1)
35333535   {
3534      UINT8 newentry = subtable_alloc();
3536      UINT16 newentry = subtable_alloc();
35353537
35363538      // allocate may cause some additional merging -- look up the subentry again
35373539      // when we're done; it should still require a split
r23728r23729
35403542      assert(m_subtable[subentry - SUBTABLE_BASE].m_usecount > 1);
35413543
35423544      int size = 1 << level2_bits();
3543      UINT8 *src = subtable_ptr(subentry);
3545      UINT16 *src = subtable_ptr(subentry);
35443546      for(int i=0; i != size; i++)
35453547         handler_ref(src[i], 1);
35463548
3547      memcpy(subtable_ptr(newentry), src, size);
3549      memcpy(subtable_ptr(newentry), src, 2*size);
35483550      subtable_release(subentry);
35493551      m_table[l1index] = newentry;
35503552      m_subtable[newentry - SUBTABLE_BASE].m_checksum = m_subtable[subentry - SUBTABLE_BASE].m_checksum;
r23728r23729
35743576//  description of a handler
35753577//-------------------------------------------------
35763578
3577const char *address_table::handler_name(UINT8 entry) const
3579const char *address_table::handler_name(UINT16 entry) const
35783580{
35793581   static const char *const strings[] =
35803582   {
r23728r23729
38683870//  find_range - find a byte address in a range
38693871//-------------------------------------------------
38703872
3871direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, UINT8 &entry)
3873direct_read_data::direct_range *direct_read_data::find_range(offs_t byteaddress, UINT16 &entry)
38723874{
38733875   // determine which entry
38743876   byteaddress &= m_space.m_bytemask;
trunk/src/emu/memory.h
r23728r23729
5252//  CONSTANTS
5353//**************************************************************************
5454
55enum { TOTAL_MEMORY_BANKS = 512 };
56
5557// address spaces
5658enum address_spacenum
5759{
r23728r23729
218220
219221   // force a recomputation on the next read
220222   void force_update() { m_byteend = 0; m_bytestart = 1; }
221   void force_update(UINT8 if_match) { if (m_entry == if_match) force_update(); }
223   void force_update(UINT16 if_match) { if (m_entry == if_match) force_update(); }
222224
223225   // custom update callbacks and configuration
224226   direct_update_delegate set_direct_update(direct_update_delegate function);
r23728r23729
241243private:
242244   // internal helpers
243245   bool set_direct_region(offs_t &byteaddress);
244   direct_range *find_range(offs_t byteaddress, UINT8 &entry);
246   direct_range *find_range(offs_t byteaddress, UINT16 &entry);
245247   void remove_intersecting_ranges(offs_t bytestart, offs_t byteend);
246248
247249   // internal state
r23728r23729
251253   offs_t                      m_bytemask;             // byte address mask
252254   offs_t                      m_bytestart;            // minimum valid byte address
253255   offs_t                      m_byteend;              // maximum valid byte address
254   UINT8                       m_entry;                // live entry
255   simple_list<direct_range>   m_rangelist[256];       // list of ranges for each entry
256   UINT16                      m_entry;                // live entry
257   simple_list<direct_range>   m_rangelist[TOTAL_MEMORY_BANKS];  // list of ranges for each entry
256258   simple_list<direct_range>   m_freerangelist;        // list of recycled range entries
257259   direct_update_delegate      m_directupdate;         // fast direct-access update callback
258260};
r23728r23729
706708   running_machine &       m_machine;              // need the machine to free our memory
707709   UINT8 **                m_baseptr;              // pointer to our base pointer in the global array
708710   UINT8 **                m_basedptr;             // same for the decrypted base pointer
709   UINT8                   m_index;                // array index for this handler
711   UINT16                  m_index;                // array index for this handler
710712   bool                    m_anonymous;            // are we anonymous or explicit?
711713   offs_t                  m_bytestart;            // byte-adjusted start offset
712714   offs_t                  m_byteend;              // byte-adjusted end offset
r23728r23729
850852   running_machine &           m_machine;              // reference to the machine
851853   bool                        m_initialized;          // have we completed initialization?
852854
853   UINT8 *                     m_bank_ptr[256];        // array of bank pointers
854   UINT8 *                     m_bankd_ptr[256];       // array of decrypted bank pointers
855   UINT8 *                     m_bank_ptr[TOTAL_MEMORY_BANKS];  // array of bank pointers
856   UINT8 *                     m_bankd_ptr[TOTAL_MEMORY_BANKS]; // array of decrypted bank pointers
855857
856858   simple_list<address_space>  m_spacelist;            // list of address spaces
857859   simple_list<memory_block>   m_blocklist;            // head of the list of memory blocks
858860
859861   tagged_list<memory_bank>    m_banklist;             // data gathered for each bank
860   UINT8                       m_banknext;             // next bank to allocate
862   UINT16                      m_banknext;             // next bank to allocate
861863
862864   tagged_list<memory_share>   m_sharelist;            // map for share lookups
863865

Previous 199869 Revisions Next


© 1997-2024 The MAME Team