void CEXIMemoryCard::SetCS(int cs) { if (cs) // not-selected to selected { m_uPosition = 0; } else { switch (command) { case cmdSectorErase: if (m_uPosition > 2) { memorycard->ClearBlock(address & (memory_card_size - 1)); status |= MC_STATUS_BUSY; status &= ~MC_STATUS_READY; //??? CmdDoneLater(5000); } break; case cmdChipErase: if (m_uPosition > 2) { // TODO: Investigate on HW, I (LPFaint99) believe that this only // erases the system area (Blocks 0-4) memorycard->ClearAll(); status &= ~MC_STATUS_BUSY; } break; case cmdPageProgram: if (m_uPosition >= 5) { int count = m_uPosition - 5; int i = 0; status &= ~0x80; while (count--) { memorycard->Write(address, 1, &(programming_buffer[i++])); i &= 127; address = (address & ~0x1FF) | ((address + 1) & 0x1FF); } CmdDoneLater(5000); } break; } } }
void CEXIMemoryCard::SetCS(int cs) { // So that memory card won't be invalidated during flushing if (flushThread.joinable()) { flushThread.join(); } if (cs) // not-selected to selected { m_uPosition = 0; } else { switch (command) { case cmdSectorErase: if (m_uPosition > 2) { memset(memory_card_content + (address & (memory_card_size-1)), 0xFF, 0x2000); status |= MC_STATUS_BUSY; status &= ~MC_STATUS_READY; //??? CmdDoneLater(5000); } break; case cmdChipErase: if (m_uPosition > 2) { memset(memory_card_content, 0xFF, memory_card_size); status &= ~MC_STATUS_BUSY; m_bDirty = true; } break; case cmdPageProgram: if (m_uPosition >= 5) { int count = m_uPosition - 5; int i=0; status &= ~0x80; while (count--) { memory_card_content[address] = programming_buffer[i++]; i &= 127; address = (address & ~0x1FF) | ((address+1) & 0x1FF); } CmdDoneLater(5000); } // Page written to memory card, not just to buffer - let's schedule a flush 0.5b cycles into the future (1 sec) // But first we unschedule already scheduled flushes - no point in flushing once per page for a large write. CoreTiming::RemoveEvent(et_this_card); CoreTiming::ScheduleEvent(500000000, et_this_card, (u64)card_index); break; } } }