picodrive/pico/cd/buffering.c
notaz cff531af94 clarify PicoDrive's license
- PicoDrive was originally released by fDave with simple
  "free for non-commercial use / For commercial use, separate licencing
  terms must be obtained" license and I kept it in my releases.
- in 2011, fDave re-released his code (same that I used as base
  many years ago) dual licensed with GPLv2 and MAME licenses:
    https://code.google.com/p/cyclone68000/

Based on the above I now proclaim that the whole source code is licensed
under the MAME license as more elaborate form of "for non-commercial use".
If that raises any doubt, I announce that all my modifications (which
is the vast majority of code by now) is licensed under the MAME license,
as it reads in COPYING file in this commit.

This does not affect ym2612.c/sn76496.c that were MAME licensed already
from the beginning.
2013-06-26 03:07:07 +03:00

149 lines
3.4 KiB
C

/*
* Buffering handling
* (C) notaz, 2007,2008
*
* This work is licensed under the terms of MAME license.
* See COPYING file in the top-level directory.
*/
#include "../pico_int.h"
int PicoCDBuffers = 0;
static unsigned char *cd_buffer = NULL;
static int prev_lba = 0x80000000;
static int hits, reads;
void PicoCDBufferInit(void)
{
void *tmp = NULL;
prev_lba = 0x80000000;
hits = reads = 0;
if (PicoCDBuffers <= 1) {
PicoCDBuffers = 0;
return; /* buffering off */
}
/* try alloc'ing until we succeed */
while (PicoCDBuffers > 0)
{
tmp = realloc(cd_buffer, PicoCDBuffers * 2048 + 304);
if (tmp != NULL) break;
PicoCDBuffers >>= 1;
}
if (PicoCDBuffers <= 0) return; /* buffering became off */
cd_buffer = tmp;
}
void PicoCDBufferFree(void)
{
if (cd_buffer) {
free(cd_buffer);
cd_buffer = NULL;
}
if (reads)
elprintf(EL_STATUS, "CD buffer hits: %i/%i (%i%%)\n", hits, reads, hits * 100 / reads);
}
void PicoCDBufferFlush(void)
{
prev_lba = 0x80000000;
}
/* this is was a try to fight slow SD access of GP2X */
PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
{
int is_bin, offs, read_len, moved = 0;
reads++;
is_bin = Pico_mcd->TOC.Tracks[0].ftype == TYPE_BIN;
if (PicoCDBuffers <= 0)
{
/* no buffering */
int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
pm_read(dest, 2048, Pico_mcd->TOC.Tracks[0].F);
return;
}
/* hit? */
offs = lba - prev_lba;
if (offs >= 0 && offs < PicoCDBuffers)
{
hits++;
if (offs == 0) dprintf("CD buffer seek to old %i -> %i\n", prev_lba, lba);
memcpy32(dest, (int *)(cd_buffer + offs*2048), 2048/4);
return;
}
if (prev_lba + PicoCDBuffers != lba)
{
int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
}
dprintf("CD buffer miss %i -> %i\n", prev_lba, lba);
if (lba < prev_lba && prev_lba - lba < PicoCDBuffers)
{
read_len = prev_lba - lba;
dprintf("CD buffer move=%i, read_len=%i", PicoCDBuffers - read_len, read_len);
memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048);
moved = 1;
}
else
{
read_len = PicoCDBuffers;
}
if (PicoMessage != NULL && read_len >= 512)
{
PicoMessage("Buffering data...");
}
if (is_bin)
{
int i = 0;
#if REDUCE_IO_CALLS
int bufs = (read_len*2048) / (2048+304);
pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F);
for (i = 1; i < bufs; i++)
// should really use memmove here, but my memcpy32 implementation is also suitable here
memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4);
#endif
for (; i < read_len - 1; i++)
{
pm_read(cd_buffer + i*2048, 2048 + 304, Pico_mcd->TOC.Tracks[0].F);
// pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); // seeking is slower, in PSP case even more
}
// further data might be moved, do not overwrite
pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F);
pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR);
}
else
{
pm_read(cd_buffer, read_len*2048, Pico_mcd->TOC.Tracks[0].F);
}
memcpy32(dest, (int *) cd_buffer, 2048/4);
prev_lba = lba;
if (moved)
{
/* file pointer must point to the same data in file, as would-be data after our buffer */
int where_seek;
lba += PicoCDBuffers;
where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
}
}