SekRunPS Cyclone integration
[picodrive.git] / Pico / cd / buffering.c
CommitLineData
8b71d0eb 1#include "../PicoInt.h"
2
3//#include <stdlib.h>
4
5int PicoCDBuffers = 0;
6static unsigned char *cd_buffer = NULL;
7static int prev_lba = 0x80000000;
8
9static int hits, reads;
10
11
12void PicoCDBufferInit(void)
13{
14 void *tmp;
15
16 prev_lba = 0x80000000;
17 hits = reads = 0;
18
19 if (PicoCDBuffers <= 1) {
20 PicoCDBuffers = 0;
21 return; /* buffering off */
22 }
23
24 /* try alloc'ing until we succeed */
25 while (PicoCDBuffers > 0)
26 {
27 tmp = realloc(cd_buffer, PicoCDBuffers * 2048);
28 if (tmp != NULL) break;
29 PicoCDBuffers >>= 1;
30 }
31
32 if (PicoCDBuffers <= 0) return; /* buffering became off */
33
34 cd_buffer = tmp;
35}
36
37
38void PicoCDBufferFree(void)
39{
40 if (cd_buffer) {
41 free(cd_buffer);
42 cd_buffer = NULL;
43 }
44 if (reads)
45 printf("CD buffer hits: %i/%i (%i%%)\n", hits, reads, hits * 100 / reads);
46}
47
48
49/* this is a try to fight slow SD access of GP2X */
50void PicoCDBufferRead(void *dest, int lba)
51{
52 int is_bin, offs, read_len;
53 reads++;
54
55 is_bin = Pico_mcd->TOC.Tracks[0].ftype == TYPE_BIN;
56
57 if (PicoCDBuffers <= 0)
58 {
59 /* no buffering */
60 int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
61 pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
62 pm_read(dest, 2048, Pico_mcd->TOC.Tracks[0].F);
63 return;
64 }
65
66 /* hit? */
67 offs = lba - prev_lba;
68 if (offs >= 0 && offs < PicoCDBuffers)
69 {
70 hits++;
71 if (offs == 0) dprintf("CD buffer seek to old %i -> %i\n", prev_lba, lba);
72 memcpy32(dest, (int *)(cd_buffer + offs*2048), 2048/4);
73 return;
74 }
75
76 if (prev_lba + PicoCDBuffers != lba)
77 {
78 int where_seek = is_bin ? (lba * 2352 + 16) : (lba << 11);
79 dprintf("CD buffer seek %i -> %i\n", prev_lba, lba);
80 pm_seek(Pico_mcd->TOC.Tracks[0].F, where_seek, SEEK_SET);
81 }
82
83 dprintf("CD buffer miss %i -> %i\n", prev_lba, lba);
84
85 if (lba < prev_lba && prev_lba - lba < PicoCDBuffers)
86 {
87 dprintf("CD buffer move");
88 read_len = prev_lba - lba;
89 memmove(cd_buffer + read_len*2048, cd_buffer, (PicoCDBuffers - read_len)*2048);
90 }
91 else
92 {
93 read_len = PicoCDBuffers;
94 }
95
96 if (is_bin)
97 {
98 int i;
99 for (i = 0; i < read_len; i++)
100 {
101 pm_read(cd_buffer + i*2048, 2048, Pico_mcd->TOC.Tracks[0].F);
102 pm_seek(Pico_mcd->TOC.Tracks[0].F, 304, SEEK_CUR);
103 }
104 }
105 else
106 {
107 pm_read(cd_buffer, read_len*2048, Pico_mcd->TOC.Tracks[0].F);
108 }
109 memcpy32(dest, (int *) cd_buffer, 2048/4);
110 prev_lba = lba;
111}
112