| 82 | } |
| 83 | |
| 84 | bool ATA::IO_Write() |
| 85 | { |
| 86 | WriteQueueEntry entry; |
| 87 | if (!writeQueue.Dequeue(&entry)) |
| 88 | { |
| 89 | std::lock_guard ioSignallock(ioMutex); |
| 90 | ioWrite = false; |
| 91 | return false; |
| 92 | } |
| 93 | |
| 94 | const u64 imagePos = entry.sector * 512; |
| 95 | if (FileSystem::FSeek64(hddImage, imagePos, SEEK_SET) != 0) |
| 96 | { |
| 97 | Console.Error("DEV9: ATA: File seek error"); |
| 98 | pxAssert(false); |
| 99 | abort(); |
| 100 | } |
| 101 | if (hddSparse) |
| 102 | { |
| 103 | u32 written = 0; |
| 104 | while (written != entry.length) |
| 105 | { |
| 106 | IO_SparseCacheUpdateLocation(imagePos + written); |
| 107 | // Align to sparse block size. |
| 108 | u32 writeSize = static_cast<u32>(hddSparseBlockSize - ((imagePos + written) % hddSparseBlockSize)); |
| 109 | // Limit to size of write. |
| 110 | writeSize = std::min(writeSize, entry.length - written); |
| 111 | |
| 112 | pxAssert(writeSize > 0); |
| 113 | pxAssert(writeSize <= hddSparseBlockSize); |
| 114 | pxAssert((imagePos + written) >= HddSparseStart); |
| 115 | pxAssert((imagePos + written) - HddSparseStart + writeSize <= hddSparseBlockSize); |
| 116 | |
| 117 | bool sparseWrite = IsAllZero(&entry.data[written], writeSize); |
| 118 | |
| 119 | if (sparseWrite) |
| 120 | { |
| 121 | #if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD) |
| 122 | std::unique_ptr<u8[]> zeroBlock = std::make_unique<u8[]>(writeSize); |
| 123 | memset(zeroBlock.get(), 0, writeSize); |
| 124 | pxAssert(memcmp(&entry.data[written], zeroBlock.get(), writeSize) == 0); |
| 125 | #endif |
| 126 | |
| 127 | if (!IO_SparseZero(imagePos + written, writeSize)) |
| 128 | { |
| 129 | Console.Error("DEV9: ATA: File sparse write error"); |
| 130 | |
| 131 | // hddNativeHandle is owned by hddImage. |
| 132 | // do not close it. |
| 133 | hddNativeHandle = INVALID_HANDLE_VALUE; |
| 134 | |
| 135 | hddSparse = false; |
| 136 | hddSparseBlock = nullptr; |
| 137 | hddSparseBlockValid = false; |
| 138 | |
| 139 | // Fallthough into other if statment. |
| 140 | sparseWrite = false; |
| 141 | } |