| 512 | } |
| 513 | |
| 514 | void ATA::Async(uint cycles) |
| 515 | { |
| 516 | if (!hddImage) |
| 517 | return; |
| 518 | |
| 519 | if ((regStatus & (ATA_STAT_BUSY | ATA_STAT_DRQ)) == 0 || |
| 520 | awaitFlush || (waitingCmd != nullptr)) |
| 521 | { |
| 522 | { |
| 523 | std::lock_guard ioSignallock(ioMutex); |
| 524 | if (ioRead || ioWrite) |
| 525 | //IO Running |
| 526 | return; |
| 527 | } |
| 528 | |
| 529 | //Note, ioThread may still be working. |
| 530 | if (waitingCmd != nullptr) //Are we waiting to continue a command? |
| 531 | { |
| 532 | //Log_Info("Running waiting command"); |
| 533 | void (ATA::*cmd)() = waitingCmd; |
| 534 | waitingCmd = nullptr; |
| 535 | (this->*cmd)(); |
| 536 | } |
| 537 | else if (!writeQueue.IsQueueEmpty()) //Flush cache |
| 538 | { |
| 539 | //Log_Info("Starting async write"); |
| 540 | { |
| 541 | std::lock_guard ioSignallock(ioMutex); |
| 542 | ioWrite = true; |
| 543 | } |
| 544 | ioReady.notify_all(); |
| 545 | } |
| 546 | else if (awaitFlush) //Fire IRQ on flush completion? |
| 547 | { |
| 548 | //Log_Info("Flush done, raise IRQ"); |
| 549 | awaitFlush = false; |
| 550 | PostCmdNoData(); |
| 551 | } |
| 552 | } |
| 553 | } |
| 554 | |
| 555 | s64 ATA::HDD_GetLBA() |
| 556 | { |
no test coverage detected