void sam6883_device::update_bank(int bank, offs_t addrstart, offs_t addrend, offs_t offset) { assert((bank >= 0) && (bank < sizeof(m_banks) / sizeof(m_banks[0]))); if (m_banks[bank].m_memory != NULL) { /* this bank is a memory bank */ install_memory(addrstart, MIN(addrend, addrstart + m_banks[bank].m_memory_size - 1), m_banks[bank].m_memory + m_banks[bank].m_memory_offset + offset, m_banks[bank].m_memory_read_only); install_memory(addrstart + m_banks[bank].m_memory_size, addrend, NULL, m_banks[bank].m_memory_read_only); } else { /* this bank uses handlers */ assert(offset == 0); /* changes to the offset are not supported */ if (!m_banks[bank].m_rhandler.isnull()) m_cpu_space->install_read_handler(addrstart, addrend, 0, 0, m_banks[bank].m_rhandler); if (!m_banks[bank].m_whandler.isnull()) m_cpu_space->install_write_handler(addrstart, addrend, 0, 0, m_banks[bank].m_whandler); } }
void SMem_Manager::install_memory(Symbol* state, uint64_t pLTI_ID, Symbol* sti, bool activate_lti, symbol_triple_list& meta_wmes, symbol_triple_list& retrieval_wmes, smem_install_type install_type, uint64_t depth, std::set<uint64_t>* visited) { //////////////////////////////////////////////////////////////////////////// timers->ncb_retrieval->start(); //////////////////////////////////////////////////////////////////////////// // get the ^result header for this state Symbol* result_header = NULL; if (install_type == wm_install) { result_header = state->id->smem_info->result_wme->value; } dprint(DT_SMEM_INSTANCE, "Install memory called for %y %u %y.\n", state, pLTI_ID, sti); // get identifier if not known bool sti_created_here = false; if (install_type == wm_install) { if (sti == NIL) { sti = get_current_iSTI_for_LTI(pLTI_ID, result_header->id->level); sti_created_here = true; } } else { if (sti == NIL) { sti = thisAgent->symbolManager->make_new_identifier('L', NO_WME_LEVEL, NIL); sti->id->level = NO_WME_LEVEL; sti->id->promotion_level = NO_WME_LEVEL; sti->id->LTI_ID = pLTI_ID; sti->id->smem_valid = smem_validation; sti_created_here = true; } } // activate lti if (activate_lti) { lti_activate(pLTI_ID, true); } dprint(DT_SMEM_INSTANCE, "...installing meta wmes for %y\n", sti); // point retrieved to lti if (install_type == wm_install) { if (visited == NULL) { add_triple_to_recall_buffer(meta_wmes, result_header, thisAgent->symbolManager->soarSymbols.smem_sym_retrieved, sti); } else { add_triple_to_recall_buffer(meta_wmes, result_header, thisAgent->symbolManager->soarSymbols.smem_sym_depth_retrieved, sti); } } /* Not sure if this is still needed with this new implementation of smem*/ if (sti_created_here && install_type == wm_install) { // if the identifier was created above we need to // remove a single ref count AFTER the wme // is added (such as to not deallocate the symbol // prematurely) thisAgent->symbolManager->symbol_remove_ref(&sti); } dprint(DT_SMEM_INSTANCE, "...installing children of %y\n", sti); bool triggered = false; /* This previously would only return the children if there were no impasse wmes, input wmes and slots for sti */ if (visited == NULL) { triggered = true; visited = new std::set<uint64_t>; } soar_module::sqlite_statement* expand_q = SQL->web_expand; Symbol* attr_sym; Symbol* value_sym; // get direct children: attr_type, attr_hash, value_type, value_hash, value_letter, value_num, value_lti expand_q->bind_int(1, pLTI_ID); std::set<Symbol*> children; while (expand_q->execute() == soar_module::row) { // make the identifier symbol irrespective of value type attr_sym = rhash_(static_cast<byte>(expand_q->column_int(0)), static_cast<smem_hash_id>(expand_q->column_int(1))); // identifier vs. constant if (expand_q->column_int(4) != SMEM_AUGMENTATIONS_NULL) { dprint(DT_SMEM_INSTANCE, "Child LTI augmentation found. Getting STI for lti_id %u...", static_cast<uint64_t>(expand_q->column_int(4))); value_sym = get_current_iSTI_for_LTI(static_cast<uint64_t>(expand_q->column_int(4)), sti->id->level, 'L'); dprint_noprefix(DT_SMEM_INSTANCE, "%y\n", value_sym); if (depth > 1) { dprint(DT_SMEM_INSTANCE, "Depth parameter > 1, so adding children of %y to add list.\n", value_sym); children.insert(value_sym); } } else { dprint(DT_SMEM_INSTANCE, "Child constant augmentation found. Getting constant for value hash %d %u...", static_cast<byte>(expand_q->column_int(2)), static_cast<smem_hash_id>(expand_q->column_int(3))); value_sym = rhash_(static_cast<byte>(expand_q->column_int(2)), static_cast<smem_hash_id>(expand_q->column_int(3))); dprint_noprefix(DT_SMEM_INSTANCE, "%y\n", value_sym); } // add wme add_triple_to_recall_buffer(retrieval_wmes, sti, attr_sym, value_sym); // deal with ref counts - attribute/values are always created in this function // (thus an extra ref count is set before adding a wme) if (install_type == fake_install && sti_created_here) { thisAgent->symbolManager->symbol_remove_ref(&sti); } thisAgent->symbolManager->symbol_remove_ref(&attr_sym); thisAgent->symbolManager->symbol_remove_ref(&value_sym); } expand_q->reinitialize(); //Attempt to find children for the case of depth. std::set<Symbol*>::iterator iterator; std::set<Symbol*>::iterator end = children.end(); dprint(DT_SMEM_INSTANCE, "...processing add list of children of %y\n", sti); for (iterator = children.begin(); iterator != end; ++iterator) { if (visited->find((*iterator)->id->LTI_ID) == visited->end()) { visited->insert((*iterator)->id->LTI_ID); install_memory(state, (*iterator)->id->LTI_ID, (*iterator), false, meta_wmes, retrieval_wmes, install_type, depth - 1, visited);//choosing not to bla children of retrived node } } dprint(DT_SMEM_INSTANCE, "Done installing memory called for %y %u %y.\n", state, pLTI_ID, sti); if (triggered) { delete visited; } //////////////////////////////////////////////////////////////////////////// timers->ncb_retrieval->stop(); //////////////////////////////////////////////////////////////////////////// }