From 818e923296281c746e5782b3b456373d8b524f7b Mon Sep 17 00:00:00 2001 From: krcroft Date: Sat, 29 Feb 2020 13:08:22 -0800 Subject: [PATCH] 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. --- src/dos/cdrom_image.cpp | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 663a0494..220424a1 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -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; }