1
0
Fork 0

Let the code describe the functionality when reading sectors

Moves to using a member vector to provide a persistent buffer,
instead of repeatedly allocating and deleting memory on every
invocation (during DAE, this can be called hundreds of times
per second, with requsts of up 24 sectors or ~56KB of memory
per call).

The buffer is only resized upward, which avoids 'zig-zag'
re-allocations when switching between raw (2352-byte) and cooked
(2048-byte) sectors.

Only writes as much data was was successfully read into
the DOS program's buffer, avoiding (potential) garbage-fill.
This commit is contained in:
krcroft 2020-02-29 13:08:22 -08:00 committed by Patryk Obara
parent c76cc09d97
commit 818e923296

View file

@ -788,19 +788,38 @@ bool CDROM_Interface_Image::ReadSectors(PhysPt buffer,
const uint32_t sector,
const uint16_t num)
{
int sectorSize = (raw ? BYTES_PER_RAW_REDBOOK_FRAME : BYTES_PER_COOKED_REDBOOK_FRAME);
Bitu buflen = num * sectorSize;
Bit8u* buf = new Bit8u[buflen];
const uint16_t sectorSize = (raw ? BYTES_PER_RAW_REDBOOK_FRAME
: BYTES_PER_COOKED_REDBOOK_FRAME);
const uint32_t requested_bytes = num * sectorSize;
// Resize our underlying vector if it's not big enough
if (readBuffer.size() < requested_bytes)
readBuffer.resize(requested_bytes);
// Setup state-tracking variables to be used in the read-loop
bool success = true; //Gobliiins reads 0 sectors
for (unsigned long i = 0; i < num; i++) {
success = ReadSector(&buf[i * sectorSize], raw, sector + i);
if (!success) {
uint32_t bytes_read = 0;
uint32_t current_sector = sector;
uint8_t* buffer_position = readBuffer.data();
// Read until we have enough or fail
while(bytes_read < requested_bytes) {
success = ReadSector(buffer_position, raw, current_sector);
if (!success)
break;
}
current_sector++;
bytes_read += sectorSize;
buffer_position += sectorSize;
}
MEM_BlockWrite(buffer, buf, buflen);
delete[] buf;
// Write only the successfully read bytes
MEM_BlockWrite(buffer, readBuffer.data(), bytes_read);
#ifdef DEBUG
LOG_MSG("CDROM: Read %u %s sectors at sector %u: "
"%s after %u sectors (%u bytes)",
num, raw ? "raw" : "cooked", sector,
success ? "Succeeded" : "Failed",
ceil_divide(bytes_read, sectorSize), bytes_read);
#endif
return success;
}