mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00

- 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.
149 lines
3.4 KiB
C
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);
|
|
}
|
|
}
|
|
|