Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader/simon.git] / modules / iopcore / cddev / cddev.c
blob397c51c240365f2f7531404c396088a73cd6e507
1 /*
2 Copyright 2009, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review Open-ps2-loader README & LICENSE files for further details.
5 */
7 #include <stdio.h>
8 #include <loadcore.h>
9 #include <ioman.h>
10 #include <io_common.h>
11 #include <thsemap.h>
12 #include <sysclib.h>
13 #include <errno.h>
15 #define MODNAME "cddev"
16 IRX_ID(MODNAME, 1, 1);
18 typedef struct {
19 u32 lsn;
20 u32 size;
21 char name[16];
22 u8 date[8];
23 u32 flag;
24 } cdl_file_t;
26 typedef struct {
27 u8 trycount;
28 u8 spindlctrl;
29 u8 datapattern;
30 u8 pad;
31 } cd_read_mode_t;
33 // cdvdman imports
34 int sceCdInit(int init_mode); // #4
35 int sceCdRead(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode); // #6
36 int sceCdSync(int mode); // #11
37 int sceCdDiskReady(int mode); // #13
38 int sceCdLayerSearchFile(cdl_file_t *fp, const char *name, int layer); // #84
40 // driver ops protypes
41 int cddev_dummy(void);
42 int cddev_init(iop_device_t *dev);
43 int cddev_deinit(iop_device_t *dev);
44 int cddev_open(iop_file_t *f, char *filename, int mode);
45 int cddev_close(iop_file_t *f);
46 int cddev_read(iop_file_t *f, void *buf, u32 size);
47 int cddev_lseek(iop_file_t *f, u32 offset, int where);
49 // driver ops func tab
50 void *cddev_ops[17] = {
51 (void*)cddev_init,
52 (void*)cddev_deinit,
53 (void*)cddev_dummy,
54 (void*)cddev_open,
55 (void*)cddev_close,
56 (void*)cddev_read,
57 (void*)cddev_dummy,
58 (void*)cddev_lseek,
59 (void*)cddev_dummy,
60 (void*)cddev_dummy,
61 (void*)cddev_dummy,
62 (void*)cddev_dummy,
63 (void*)cddev_dummy,
64 (void*)cddev_dummy,
65 (void*)cddev_dummy,
66 (void*)cddev_dummy,
67 (void*)cddev_dummy
70 // driver descriptor
71 static iop_device_t cddev_dev = {
72 "cddev",
73 IOP_DT_FS,
75 "cddev",
76 (struct _iop_device_ops *)&cddev_ops
79 typedef struct {
80 iop_file_t *f;
81 u32 lsn;
82 u32 filesize;
83 u32 position;
84 } FHANDLE;
86 #define MAX_FDHANDLES 64
87 FHANDLE cddev_fdhandles[MAX_FDHANDLES];
89 static int cddev_io_sema;
91 #define CDDEV_FS_SECTORS 30
92 #define CDDEV_FS_BUFSIZE CDDEV_FS_SECTORS * 2048
93 static u8 cddev_fs_buf[CDDEV_FS_BUFSIZE + 2*2048] __attribute__((aligned(64)));
95 //--------------------------------------------------------------
96 int _start(int argc, char** argv)
98 DelDrv("cddev");
99 AddDrv((iop_device_t *)&cddev_dev);
101 sceCdInit(0);
103 return MODULE_RESIDENT_END;
106 //--------------------------------------------------------------
107 int cddev_dummy(void)
109 return -EPERM;
112 //--------------------------------------------------------------
113 int cddev_init(iop_device_t *dev)
115 iop_sema_t smp;
117 smp.initial = 1;
118 smp.max = 1;
119 smp.attr = 1;
120 smp.option = 0;
122 cddev_io_sema = CreateSema(&smp);
124 return 0;
127 //--------------------------------------------------------------
128 int cddev_deinit(iop_device_t *dev)
130 DeleteSema(cddev_io_sema);
132 return 0;
135 //--------------------------------------------------------------
136 FHANDLE *cddev_getfilefreeslot(void)
138 register int i;
139 FHANDLE *fh;
141 for (i=0; i<MAX_FDHANDLES; i++) {
142 fh = (FHANDLE *)&cddev_fdhandles[i];
143 if (fh->f == NULL)
144 return fh;
147 return 0;
150 //--------------------------------------------------------------
151 int cddev_open(iop_file_t *f, char *filename, int mode)
153 register int r = 0;
154 FHANDLE *fh;
155 cdl_file_t cdfile;
157 if (!filename)
158 return -ENOENT;
160 WaitSema(cddev_io_sema);
162 fh = cddev_getfilefreeslot();
163 if (fh) {
164 sceCdDiskReady(0);
165 r = sceCdLayerSearchFile(&cdfile, filename, 0);
166 if (r != 1) {
167 r = sceCdLayerSearchFile(&cdfile, filename, 1);
168 if (r != 1) {
169 r = -ENOENT;
170 SignalSema(cddev_io_sema);
171 return r;
174 f->privdata = fh;
175 fh->f = f;
176 fh->lsn = cdfile.lsn;
177 fh->filesize = cdfile.size;
178 fh->position = 0;
179 r = 0;
181 else
182 r = -EMFILE;
184 SignalSema(cddev_io_sema);
186 return r;
189 //--------------------------------------------------------------
190 int cddev_close(iop_file_t *f)
192 FHANDLE *fh = (FHANDLE *)f->privdata;
194 WaitSema(cddev_io_sema);
196 if (fh)
197 memset(fh, 0, sizeof(FHANDLE));
199 SignalSema(cddev_io_sema);
201 return 0;
204 //--------------------------------------------------------------
205 int cddev_read(iop_file_t *f, void *buf, u32 size)
207 FHANDLE *fh = (FHANDLE *)f->privdata;
208 register int rpos, sectorpos;
209 register u32 nsectors, nbytes;
211 rpos = 0;
213 if ((fh->position + size) > fh->filesize)
214 size = fh->filesize - fh->position;
216 WaitSema(cddev_io_sema);
218 sceCdDiskReady(0);
220 while (size) {
221 nbytes = CDDEV_FS_BUFSIZE;
222 if (size < nbytes)
223 nbytes = size;
225 nsectors = nbytes >> 11;
226 sectorpos = fh->position & 2047;
228 if (sectorpos)
229 nsectors++;
231 if (nbytes & 2047)
232 nsectors++;
234 sceCdRead(fh->lsn + ((fh->position & -2048) >> 11), nsectors, cddev_fs_buf, NULL);
235 sceCdSync(0);
236 memcpy(buf, &cddev_fs_buf[sectorpos], nbytes);
238 rpos += nbytes;
239 buf += nbytes;
240 size -= nbytes;
241 fh->position += nbytes;
244 SignalSema(cddev_io_sema);
246 return rpos;
249 //--------------------------------------------------------------
250 int cddev_lseek(iop_file_t *f, u32 offset, int where)
252 register int r;
253 FHANDLE *fh = (FHANDLE *)f->privdata;
255 WaitSema(cddev_io_sema);
257 switch (where) {
258 case SEEK_CUR:
259 r = fh->position + offset;
260 if (r > fh->filesize) {
261 r = -EINVAL;
262 goto ssema;
264 break;
265 case SEEK_SET:
266 r = offset;
267 if (fh->filesize < offset) {
268 r = -EINVAL;
269 goto ssema;
271 break;
272 case SEEK_END:
273 r = fh->filesize;
274 break;
275 default:
276 r = -EINVAL;
277 goto ssema;
280 fh->position = r;
282 ssema:
283 SignalSema(cddev_io_sema);
285 return r;
288 //-------------------------------------------------------------------------
289 DECLARE_IMPORT_TABLE(cdvdman, 1, 1)
290 DECLARE_IMPORT(4, sceCdInit)
291 DECLARE_IMPORT(6, sceCdRead)
292 DECLARE_IMPORT(11, sceCdSync)
293 DECLARE_IMPORT(13, sceCdDiskReady)
294 DECLARE_IMPORT(84, sceCdLayerSearchFile)
295 END_IMPORT_TABLE