//------------------------------------------------- // rebuild_execute_list - rebuild the list of // executing CPUs, moving suspended CPUs to the // end //------------------------------------------------- void rebuild_execute_list() { // if we haven't yet set a scheduling quantum, do it now if (m_quantum_list.empty()) { // set the core scheduling quantum, ensuring it's no longer than 60Hz attotime min_quantum = machine().config().maximum_quantum(attotime.from_hz(60)); // if the configuration specifies a device to make perfect, pick that as the minimum device_execute_interface exec = machine().config().perfect_quantum_device(); if (exec != null) { min_quantum = std.min(new attotime(0, exec.minimum_quantum()), min_quantum); } // inform the timer system of our decision add_scheduling_quantum(min_quantum, attotime.never); } // start with an empty list //device_execute_interface **active_tailptr = &m_execute_list; //*active_tailptr = NULL; // also make an empty list of suspended devices //device_execute_interface *suspend_list = NULL; //device_execute_interface **suspend_tailptr = &suspend_list; List <device_execute_interface> active_list = new List <device_execute_interface>(); List <device_execute_interface> suspend_list = new List <device_execute_interface>(); // iterate over all devices foreach (device_execute_interface exec in new execute_interface_enumerator(machine().root_device())) { // append to the appropriate list exec.m_nextexec = null; if (exec.m_suspend == 0) { //*active_tailptr = exec; //active_tailptr = &exec.m_nextexec; active_list.Add(exec); } else { //*suspend_tailptr = exec; //suspend_tailptr = &exec.m_nextexec; suspend_list.Add(exec); } } // append the suspend list to the end of the active list //*active_tailptr = suspend_list; active_list.AddRange(suspend_list); if (active_list.Count > 0) { m_execute_list = active_list[0]; for (int i = 0; i < active_list.Count; i++) { if (i < active_list.Count - 1) { active_list[i].m_nextexec = active_list[i + 1]; } else { active_list[i].m_nextexec = null; } } } }
//------------------------------------------------- // first_dirty_rect -- return the first dirty // rectangle in the list //------------------------------------------------- public sparse_dirty_rect first_dirty_rect(rectangle cliprect) { // if what we have is valid, just return it again if (m_rect_list_bounds == cliprect) { return(m_rect_list.empty() ? null : m_rect_list.first()); } // reclaim the dirty list and start over m_rect_allocator.reclaim_all(m_rect_list); // compute dirty space rectangle coordinates int sx = cliprect.min_x >> m_granularity; int ex = cliprect.max_x >> m_granularity; int sy = cliprect.min_y >> m_granularity; int ey = cliprect.max_y >> m_granularity; int tilesize = 1 << m_granularity; // loop over all grid rows that intersect our cliprect for (int y = sy; y <= ey; y++) { PointerU8 dirtybase = m_bitmap.pix(y); //uint8_t *dirtybase = &m_bitmap.pix(y); sparse_dirty_rect currect = null; // loop over all grid columns that intersect our cliprect for (int x = sx; x <= ex; x++) { // if this tile is not dirty, end our current run and continue if (dirtybase[x] == 0) { if (currect != null) { currect.m_rect &= cliprect; //*currect &= cliprect; } currect = null; continue; } // if we can't add to an existing rect, create a new one if (currect == null) { // allocate a new rect and add it to the list currect = m_rect_list.append(m_rect_allocator.alloc()); // make a rect describing this grid square currect.m_rect.min_x = x << m_granularity; currect.m_rect.max_x = currect.m_rect.min_x + tilesize - 1; currect.m_rect.min_y = y << m_granularity; currect.m_rect.max_y = currect.m_rect.min_y + tilesize - 1; } // if we can add to the previous rect, just expand its width else { currect.m_rect.max_x += tilesize; } } // clip the last rect to the cliprect if (currect != null) { currect.m_rect &= cliprect; } } // mark the list as valid m_rect_list_bounds = cliprect; return(m_rect_list.empty() ? null : m_rect_list.first()); }