bump libpicofe
[picodrive.git] / pico / cd / buffering.c
CommitLineData
cff531af 1/*
2 * Buffering handling
3 * (C) notaz, 2007,2008
4 *
5 * This work is licensed under the terms of MAME license.
6 * See COPYING file in the top-level directory.
7 */
6cadc2da 8
efcba75f 9#include "../pico_int.h"
8b71d0eb 10
8b71d0eb 11int PicoCDBuffers = 0;
12static unsigned char *cd_buffer = NULL;
13static int prev_lba = 0x80000000;
14
15static int hits, reads;
16
9c9cda8c 17#undef dprintf
18#define dprintf(...)
8b71d0eb 19
20void PicoCDBufferInit(void)
21{
ca482e5d 22 void *tmp = NULL;
8b71d0eb 23
24 prev_lba = 0x80000000;
25 hits = reads = 0;
26
27 if (PicoCDBuffers <= 1) {
28 PicoCDBuffers = 0;
a5f80ce4 29 return; /* buffering off */
8b71d0eb 30 }
31
32 /* try alloc'ing until we succeed */
33 while (PicoCDBuffers > 0)
34 {
8022f53d 35 tmp = realloc(cd_buffer, PicoCDBuffers * 2048 + 304);
8b71d0eb 36 if (tmp != NULL) break;
37 PicoCDBuffers >>= 1;
38 }
39
a5f80ce4 40 if (PicoCDBuffers <= 0) return; /* buffering became off */
8b71d0eb 41
a5f80ce4 42 cd_buffer = tmp;
8b71d0eb 43}
44
45
46void PicoCDBufferFree(void)
47{
48 if (cd_buffer) {
49 free(cd_buffer);
50 cd_buffer = NULL;
51 }
52 if (reads)
c6196c0f 53 elprintf(EL_STATUS, "CD buffer hits: %i/%i (%i%%)\n", hits, reads, hits * 100 / reads);
8b71d0eb 54}
55
56
c9e1affc 57void PicoCDBufferFlush(void)
58{
59 prev_lba = 0x80000000;
60}
61
62
63/* this is was a try to fight slow SD access of GP2X */
eff55556 64PICO_INTERNAL void PicoCDBufferRead(void *dest, int lba)
8b71d0eb 65{
66fdc0f0 66 int is_bin, offs, read_len, moved = 0;
8b71d0eb 67 reads++;
68
69 is_bin = Pico_mcd->TOC.Tracks[0].ftype == TYPE_BIN;
70
71 if (PicoCDBuffers <= 0)
72 {
73 /* no buffering */
74 int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
75 pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
76 pm_read(dest, 2048, Pico_mcd->TOC.Tracks[0].F);
77 return;
78 }
79
80 /* hit? */
81 offs = lba - prev_lba;
82 if (offs >= 0 && offs < PicoCDBuffers)
83 {
84 hits++;
85 if (offs == 0) dprintf("CD buffer seek to old %i -> %i\n", prev_lba, lba);
86 memcpy32(dest, (int *)(cd_buffer + offs*2048), 2048/4);
87 return;
88 }
89
90 if (prev_lba + PicoCDBuffers != lba)
91 {
92 int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
93 dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
94 pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
95 }
96
97 dprintf("CD buffer miss %i -> %i\n", prev_lba, lba);
98
99 if (lba < prev_lba && prev_lba - lba < PicoCDBuffers)
100 {
8b71d0eb 101 read_len = prev_lba - lba;
66fdc0f0 102 dprintf("CD buffer move=%i, read_len=%i", PicoCDBuffers - read_len, read_len);
8b71d0eb 103 memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048);
66fdc0f0 104 moved = 1;
8b71d0eb 105 }
106 else
107 {
108 read_len = PicoCDBuffers;
109 }
110
66fdc0f0 111 if (PicoMessage != NULL && read_len >= 512)
112 {
113 PicoMessage("Buffering data...");
114 }
115
8b71d0eb 116 if (is_bin)
117 {
8022f53d 118 int i = 0;
9c9cda8c 119#ifdef _PSP_FW_VERSION
b542be46 120 int bufs = (read_len*2048) / (2048+304);
8022f53d 121 pm_read(cd_buffer, bufs*(2048+304), Pico_mcd->TOC.Tracks[0].F);
122 for (i = 1; i < bufs; i++)
123 // should really use memmove here, but my memcpy32 implementation is also suitable here
124 memcpy32((int *)(cd_buffer + i*2048), (int *)(cd_buffer + i*(2048+304)), 2048/4);
125#endif
b542be46 126 for (; i < read_len - 1; i++)
8b71d0eb 127 {
8022f53d 128 pm_read(cd_buffer + i*2048, 2048 + 304, Pico_mcd->TOC.Tracks[0].F);
129 // pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR); // seeking is slower, in PSP case even more
8b71d0eb 130 }
b542be46 131 // further data might be moved, do not overwrite
132 pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F);
133 pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR);
8b71d0eb 134 }
135 else
136 {
137 pm_read(cd_buffer, read_len*2048, Pico_mcd->TOC.Tracks[0].F);
138 }
139 memcpy32(dest, (int *) cd_buffer, 2048/4);
140 prev_lba = lba;
66fdc0f0 141
142 if (moved)
143 {
144 /* file pointer must point to the same data in file, as would-be data after our buffer */
145 int where_seek;
146 lba += PicoCDBuffers;
147 where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
148 pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
149 }
8b71d0eb 150}
151