Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / iopcore / cdvdman / cdvdman.c
blobcb480b9b2a339ae7eb7452e790d278f541d1f9b1
1 /*
2 Copyright 2009-2010, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review Open PS2 Loader README & LICENSE files for further details.
5 */
7 #include "smsutils.h"
8 #include "mass_common.h"
9 #include "mass_stor.h"
10 #include "dev9.h"
11 #include "smb.h"
12 #include "atad.h"
13 #include "ioplib_util.h"
15 #include <loadcore.h>
16 #include <stdio.h>
17 #include <sysclib.h>
18 #include <sysmem.h>
19 #include <thbase.h>
20 #include <thevent.h>
21 #include <intrman.h>
22 #include <ioman.h>
23 #include <thsemap.h>
24 #include <thmsgbx.h>
25 #include <errno.h>
26 #include <io_common.h>
27 #include <usbd.h>
28 #include <ps2ip.h>
29 #include "ioman_add.h"
31 #ifdef __IOPCORE_DEBUG
32 #define DPRINTF(args...) printf(args)
33 #else
34 #define DPRINTF(args...) do { } while(0)
35 #endif
37 #define MODNAME "dev9"
38 IRX_ID(MODNAME, 2, 8);
41 //------------------ Patch Zone ----------------------
42 #ifdef SMB_DRIVER
43 static char g_ISO_name[] = "###### GAMESETTINGS ######";
44 #else
45 static char g_tag[] = "###### GAMESETTINGS ######";
46 #endif
47 static char g_ISO_parts=0x69;
48 static char g_ISO_media=0x69;
49 static char g_gamesetting_alt_read=0;
50 static u16 g_gamesetting_disable_DVDDL=0;
51 static u16 g_gamesetting_0_pss=0;
52 static u32 g_gamesetting_timer=100;
54 #define ISO_MAX_PARTS 16
55 static int g_part_start[ISO_MAX_PARTS] = {
56 0, // is apa header LBA in HDD use, is Long filename in SMB+ISO
72 };
74 static char g_DiskID[] = "\0B00BS"; // the null byte is here to ensure the ISO name string
75 // (stored in array above) is terminated when it's 64 bytes
77 #ifdef SMB_DRIVER
78 static char g_pc_ip[]="xxx.xxx.xxx.xxx";
79 static int g_pc_port = 445; // &g_pc_ip + 16
80 static char g_pc_share[32]="PS2SMB";
81 static char g_pc_prefix[32]="\0";
82 static char g_smb_user[16]="GUEST";
83 static char g_smb_password[16]="\0";
84 #endif
86 //----------------------------------------------------
88 int *p_part_start = &g_part_start[0];
90 extern void *dummy_irx;
91 extern int size_dummy_irx;
93 struct irx_export_table _exp_cdvdman;
94 struct irx_export_table _exp_cdvdstm;
95 #ifdef SMB_DRIVER
96 struct irx_export_table _exp_dev9;
97 #endif
98 #ifdef HDD_DRIVER
99 struct irx_export_table _exp_dev9;
100 struct irx_export_table _exp_atad;
101 #endif
102 #ifdef USB_DRIVER
103 #ifdef __USE_DEV9
104 struct irx_export_table _exp_dev9;
105 #endif
106 #endif
107 struct irx_export_table _exp_smsutils;
108 #ifdef VMC_DRIVER
109 struct irx_export_table _exp_oplutils;
110 #endif
112 // PS2 CDVD hardware registers
113 #define CDVDreg_NCOMMAND (*(volatile unsigned char *)0xBF402004)
114 #define CDVDreg_READY (*(volatile unsigned char *)0xBF402005)
115 #define CDVDreg_NDATAIN (*(volatile unsigned char *)0xBF402005)
116 #define CDVDreg_ERROR (*(volatile unsigned char *)0xBF402006)
117 #define CDVDreg_HOWTO (*(volatile unsigned char *)0xBF402006)
118 #define CDVDreg_ABORT (*(volatile unsigned char *)0xBF402007)
119 #define CDVDreg_PWOFF (*(volatile unsigned char *)0xBF402008)
120 #define CDVDreg_9 (*(volatile unsigned char *)0xBF402008)
121 #define CDVDreg_STATUS (*(volatile unsigned char *)0xBF40200A)
122 #define CDVDreg_B (*(volatile unsigned char *)0xBF40200B)
123 #define CDVDreg_C (*(volatile unsigned char *)0xBF40200C)
124 #define CDVDreg_D (*(volatile unsigned char *)0xBF40200D)
125 #define CDVDreg_E (*(volatile unsigned char *)0xBF40200E)
126 #define CDVDreg_TYPE (*(volatile unsigned char *)0xBF40200F)
127 #define CDVDreg_13 (*(volatile unsigned char *)0xBF402013)
128 #define CDVDreg_SCOMMAND (*(volatile unsigned char *)0xBF402016)
129 #define CDVDreg_SDATAIN (*(volatile unsigned char *)0xBF402017)
130 #define CDVDreg_SDATAOUT (*(volatile unsigned char *)0xBF402018)
131 #define CDVDreg_KEYSTATE (*(volatile unsigned char *)0xBF402038)
132 #define CDVDreg_KEYXOR (*(volatile unsigned char *)0xBF402039)
133 #define CDVDreg_DEC (*(volatile unsigned char *)0xBF40203A)
135 // user cb CDVD events
136 #define SCECdFuncRead 1
137 #define SCECdFuncReadCDDA 2
138 #define SCECdFuncGetToc 3
139 #define SCECdFuncSeek 4
140 #define SCECdFuncStandby 5
141 #define SCECdFuncStop 6
142 #define SCECdFuncPause 7
143 #define SCECdFuncBreak 8
145 // Modes for cdInit()
146 #define CDVD_INIT_INIT 0x00 // init cd system and wait till commands can be issued
147 #define CDVD_INIT_NOCHECK 0x01 // init cd system
148 #define CDVD_INIT_EXIT 0x05 // de-init system
150 // CDVD stats
151 #define CDVD_STAT_STOP 0x00 // disc has stopped spinning
152 #define CDVD_STAT_OPEN 0x01 // tray is open
153 #define CDVD_STAT_SPIN 0x02 // disc is spinning
154 #define CDVD_STAT_READ 0x06 // reading from disc
155 #define CDVD_STAT_PAUSE 0x0A // disc is paused
156 #define CDVD_STAT_SEEK 0x12 // disc is seeking
157 #define CDVD_STAT_ERROR 0x20 // error occurred
159 // cdTrayReq() values
160 #define CDVD_TRAY_OPEN 0 // Tray Open
161 #define CDVD_TRAY_CLOSE 1 // Tray Close
162 #define CDVD_TRAY_CHECK 2 // Tray Check
164 // sceCdDiskReady() values
165 #define CDVD_READY_READY 0x02
166 #define CDVD_READY_NOTREADY 0x06
168 #define CdSpinMax 0
169 #define CdSpinNom 1
170 #define CdSpinStm 0
172 // cdGetError() return values
173 #define CDVD_ERR_FAIL -1 // error in cdGetError()
174 #define CDVD_ERR_NO 0x00 // no error occurred
175 #define CDVD_ERR_ABRT 0x01 // command was aborted due to cdBreak() call
176 #define CDVD_ERR_CMD 0x10 // unsupported command
177 #define CDVD_ERR_OPENS 0x11 // tray is open
178 #define CDVD_ERR_NODISC 0x12 // no disk inserted
179 #define CDVD_ERR_NORDY 0x13 // drive is busy processing another command
180 #define CDVD_ERR_CUD 0x14 // command unsupported for disc currently in drive
181 #define CDVD_ERR_IPI 0x20 // sector address error
182 #define CDVD_ERR_ILI 0x21 // num sectors error
183 #define CDVD_ERR_PRM 0x22 // command parameter error
184 #define CDVD_ERR_READ 0x30 // error while reading
185 #define CDVD_ERR_TRMOPN 0x31 // tray was opened
186 #define CDVD_ERR_EOM 0x32 // outermost error
187 #define CDVD_ERR_READCF 0xFD // error setting command
188 #define CDVD_ERR_READCFR 0xFE // error setting command
190 struct dirTocEntry {
191 short length;
192 u32 fileLBA; // 2
193 u32 fileLBA_bigend; // 6
194 u32 fileSize; // 10
195 u32 fileSize_bigend; // 14
196 u8 dateStamp[6]; // 18
197 u8 reserved1; // 24
198 u8 fileProperties; // 25
199 u8 reserved2[6]; // 26
200 u8 filenameLength; // 32
201 char filename[128]; // 33
202 } __attribute__((packed));
204 typedef struct {
205 u8 stat;
206 u8 second;
207 u8 minute;
208 u8 hour;
209 u8 week;
210 u8 day;
211 u8 month;
212 u8 year;
213 } cd_clock_t;
215 typedef struct {
216 u32 lsn;
217 u32 size;
218 char name[16];
219 u8 date[8];
220 } cd_file_t;
222 typedef struct {
223 u32 lsn;
224 u32 size;
225 char name[16];
226 u8 date[8];
227 u32 flag;
228 } cdl_file_t;
230 typedef struct {
231 u8 minute;
232 u8 second;
233 u8 sector;
234 u8 track;
235 } cd_location_t;
237 typedef struct {
238 u8 trycount;
239 u8 spindlctrl;
240 u8 datapattern;
241 u8 pad;
242 } cd_read_mode_t;
244 typedef struct {
245 int err;
246 int status;
247 int Ststat;
248 int Stbufmax;
249 int Stlsn;
250 int intr_ef;
251 int disc_type_reg;
252 #ifdef ALT_READ_CORE
253 int cdNCmd;
254 int cddiskready;
255 #else
256 u32 cdread_lba;
257 u32 cdread_sectors;
258 void *cdread_buf;
259 cd_read_mode_t cdread_mode;
260 #endif
261 } cdvdman_status_t;
263 typedef struct {
264 iop_file_t *f;
265 u32 lsn;
266 u32 filesize;
267 u32 position;
268 } FHANDLE;
270 // exported functions prototypes
271 int sceCdInit(int init_mode); // #4
272 int sceCdStandby(void); // #5
273 int sceCdRead(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode); // #6
274 int sceCdSeek(u32 lsn); // #7
275 int sceCdGetError(void); // #8
276 int sceCdGetToc(void *toc); // #9
277 int sceCdSearchFile(cd_file_t *fp, const char *name); // #10
278 int sceCdSync(int mode); // #11
279 int sceCdGetDiskType(void); // #12
280 int sceCdDiskReady(int mode); // #13
281 int sceCdTrayReq(int mode, u32 *traycnt); // #14
282 int sceCdStop(void); // #15
283 int sceCdPosToInt(cd_location_t *p); // #16
284 cd_location_t *sceCdIntToPos(int i, cd_location_t *p); // #17
285 int sceCdRI(char *buf, int *stat); // #22
286 int sceCdReadClock(cd_clock_t *rtc); // #24
287 int sceCdStatus(void); // #28
288 int sceCdApplySCmd(int cmd, void *in, u32 in_size, void *out); // #29
289 int *sceCdCallback(void *func); // #37
290 int sceCdPause(void); // #38
291 int sceCdBreak(void); // #39
292 int sceCdReadCdda(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode); // #40
293 int sceCdGetReadPos(void); // #44
294 int sceCdSC(int code, int *param); // #50
295 int sceCdRC(cd_clock_t *rtc); // #51
296 int sceCdStInit(u32 bufmax, u32 bankmax, void *iop_bufaddr); // #56
297 int sceCdStRead(u32 sectors, void *buf, u32 mode, u32 *err); // #57
298 int sceCdStSeek(u32 lsn); // #58
299 int sceCdStStart(u32 lsn, cd_read_mode_t *mode); // #59
300 int sceCdStStat(void); // #60
301 int sceCdStStop(void); // #61
302 int sceCdRead0(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode); // #62
303 int sceCdRM(char *m, u32 *stat); // #64
304 int sceCdStPause(void); // #67
305 int sceCdStResume(void); // #68
306 int sceCdStSeekF(u32 lsn); // #77
307 int sceCdReadDiskID(void *DiskID); // #79
308 int sceCdReadGUID(void *GUID); // #80
309 int sceCdReadModelID(void *ModelID); // #82
310 int sceCdReadDvdDualInfo(int *on_dual, u32 *layer1_start); // #83
311 int sceCdLayerSearchFile(cdl_file_t *fp, const char *name, int layer); // #84
313 // internal functions prototypes
314 void usbd_init(void);
315 void ps2ip_init(void);
316 void fs_init(void);
317 void cdvdman_cdinit();
318 int cdvdman_ReadSect(u32 lsn, u32 nsectors, void *buf);
319 int cdvdman_readMechaconVersion(char *mname, u32 *stat);
320 int cdvdman_readID(int mode, u8 *buf);
321 FHANDLE *cdvdman_getfilefreeslot(void);
322 void cdvdman_trimspaces(char* str);
323 struct dirTocEntry *cdvdman_locatefile(char *name, u32 tocLBA, int tocLength, int layer);
324 int cdvdman_findfile(cd_file_t *pcd_file, const char *name, int layer);
325 int cdvdman_writeSCmd(u8 cmd, void *in, u32 in_size, void *out, u32 out_size);
326 int cdvdman_sendSCmd(u8 cmd, void *in, u32 in_size, void *out, u32 out_size);
327 int cdvdman_cb_event(int reason);
328 unsigned int event_alarm_cb(void *args);
329 void cdvdman_startThreads(void);
330 void cdvdman_create_semaphores(void);
331 void cdvdman_initdev(void);
332 void cdvdman_get_part_specs(u32 lsn);
334 // !!! usbd exports functions pointers !!!
335 int (*pUsbRegisterDriver)(UsbDriver *driver); // #4
336 void *(*pUsbGetDeviceStaticDescriptor)(int devId, void *data, u8 type); // #6
337 int (*pUsbSetDevicePrivateData)(int devId, void *data); // #7
338 int (*pUsbOpenEndpoint)(int devId, UsbEndpointDescriptor *desc); // #9
339 int (*pUsbCloseEndpoint)(int id); // #10
340 int (*pUsbTransfer)(int id, void *data, u32 len, void *option, UsbCallbackProc callback, void *cbArg); // #11
341 int (*pUsbOpenEndpointAligned)(int devId, UsbEndpointDescriptor *desc); // #12
343 // !!! ps2ip exports functions pointers !!!
344 int (*plwip_close)(int s); // #6
345 int (*plwip_connect)(int s, struct sockaddr *name, socklen_t namelen); // #7
346 int (*plwip_recvfrom)(int s, void *header, int hlen, void *payload, int plen, unsigned int flags, struct sockaddr *from, socklen_t *fromlen); // #10
347 int (*plwip_send)(int s, void *dataptr, int size, unsigned int flags); // #11
348 int (*plwip_socket)(int domain, int type, int protocol); // #13
349 u32 (*pinet_addr)(const char *cp); // #24
351 // for "cdrom" devctl
352 #define CDIOC_CMDBASE 0x430C
354 // for "cdrom" ioctl2
355 #define CIOCSTREAMPAUSE 0x630D
356 #define CIOCSTREAMRESUME 0x630E
357 #define CIOCSTREAMSTAT 0x630F
359 // driver ops protypes
360 int cdrom_dummy(void);
361 int cdrom_init(iop_device_t *dev);
362 int cdrom_deinit(iop_device_t *dev);
363 int cdrom_open(iop_file_t *f, char *filename, int mode);
364 int cdrom_close(iop_file_t *f);
365 int cdrom_read(iop_file_t *f, void *buf, u32 size);
366 int cdrom_lseek(iop_file_t *f, u32 offset, int where);
367 int cdrom_getstat(iop_file_t *f, char *filename, iox_stat_t *stat);
368 int cdrom_dopen(iop_file_t *f, char *dirname);
369 int cdrom_dread(iop_file_t *f, iox_dirent_t *dirent);
370 int cdrom_dclose(iop_file_t *f);
371 int cdrom_ioctl(iop_file_t *f, u32 cmd, void *args);
372 s64 cdrom_lseek64(iop_file_t *f, s64 pos, int where);
373 int cdrom_devctl(iop_file_t *f, const char *name, int cmd, void *args, u32 arglen, void *buf, u32 buflen);
374 int cdrom_ioctl2(iop_file_t *f, int cmd, void *args, u32 arglen, void *buf, u32 buflen);
376 // driver ops func tab
377 void *cdrom_ops[27] = {
378 (void*)cdrom_init,
379 (void*)cdrom_deinit,
380 (void*)cdrom_dummy,
381 (void*)cdrom_open,
382 (void*)cdrom_close,
383 (void*)cdrom_read,
384 (void*)cdrom_dummy,
385 (void*)cdrom_lseek,
386 (void*)cdrom_ioctl,
387 (void*)cdrom_dummy,
388 (void*)cdrom_dummy,
389 (void*)cdrom_dummy,
390 (void*)cdrom_dopen,
391 (void*)cdrom_dclose,
392 (void*)cdrom_dread,
393 (void*)cdrom_getstat,
394 (void*)cdrom_dummy,
395 (void*)cdrom_dummy,
396 (void*)cdrom_dummy,
397 (void*)cdrom_dummy,
398 (void*)cdrom_dummy,
399 (void*)cdrom_dummy,
400 (void*)cdrom_lseek64,
401 (void*)cdrom_devctl,
402 (void*)cdrom_dummy,
403 (void*)cdrom_dummy,
404 (void*)cdrom_ioctl2
407 // driver descriptor
408 static iop_ext_device_t cdrom_dev = {
409 "cdrom",
410 IOP_DT_FS | IOP_DT_FSEXT,
412 "CD-ROM ",
413 (struct _iop_ext_device_ops *)&cdrom_ops
416 // devctl funcs
417 int (*devctl_fn)(void *args, void *buf);
418 int devctl_dummy(void *args, void *buf);
419 int devctl_dummy2(void *args, void *buf);
420 int devctl_retonly(void *args, void *buf);
421 int devctl_cdreadclock(void *args, void *buf);
422 int devctl_cdreadGUID(void *args, void *buf);
423 int devctl_cdreadDiskID(void *args, void *buf);
424 int devctl_cdgetdisktype(void *args, void *buf);
425 int devctl_cdgeterror(void *args, void *buf);
426 int devctl_cdtrayreq(void *args, void *buf);
427 int devctl_cdstatus(void *args, void *buf);
428 int devctl_cddiskready(void *args, void *buf);
429 int devctl_cdreadModelID(void *args, void *buf);
430 int devctl_cdStinit(void *args, void *buf);
431 int devctl_cdabort(void *args, void *buf);
432 int devctl_cdstandby(void *args, void *buf);
433 int devctl_cdstop(void *args, void *buf);
434 int devctl_cdpause(void *args, void *buf);
435 int devctl_cdgettoc(void *args, void *buf);
436 int devctl_intref(void *args, void *buf);
438 // devctl funcs array
439 void *devctl_tab[134] = {
440 (void *)devctl_cdreadclock,
441 (void *)devctl_dummy,
442 (void *)devctl_dummy,
443 (void *)devctl_dummy,
444 (void *)devctl_dummy,
445 (void *)devctl_dummy,
446 (void *)devctl_dummy,
447 (void *)devctl_dummy,
448 (void *)devctl_dummy,
449 (void *)devctl_dummy,
450 (void *)devctl_dummy,
451 (void *)devctl_dummy,
452 (void *)devctl_dummy,
453 (void *)devctl_dummy,
454 (void *)devctl_dummy,
455 (void *)devctl_dummy,
456 (void *)devctl_dummy,
457 (void *)devctl_cdreadGUID,
458 (void *)devctl_cdreadDiskID,
459 (void *)devctl_cdgetdisktype,
460 (void *)devctl_cdgeterror,
461 (void *)devctl_cdtrayreq,
462 (void *)devctl_cdstatus,
463 (void *)devctl_retonly,
464 (void *)devctl_retonly,
465 (void *)devctl_cddiskready,
466 (void *)devctl_cdreadModelID,
467 (void *)devctl_cdStinit,
468 (void *)devctl_cdabort,
469 (void *)devctl_dummy,
470 (void *)devctl_dummy,
471 (void *)devctl_dummy,
472 (void *)devctl_dummy,
473 (void *)devctl_dummy,
474 (void *)devctl_dummy,
475 (void *)devctl_dummy,
476 (void *)devctl_dummy,
477 (void *)devctl_dummy,
478 (void *)devctl_dummy,
479 (void *)devctl_dummy,
480 (void *)devctl_dummy,
481 (void *)devctl_dummy,
482 (void *)devctl_dummy,
483 (void *)devctl_dummy,
484 (void *)devctl_dummy,
485 (void *)devctl_dummy,
486 (void *)devctl_dummy,
487 (void *)devctl_dummy,
488 (void *)devctl_dummy,
489 (void *)devctl_dummy,
490 (void *)devctl_dummy,
491 (void *)devctl_dummy,
492 (void *)devctl_dummy,
493 (void *)devctl_dummy,
494 (void *)devctl_dummy,
495 (void *)devctl_dummy,
496 (void *)devctl_dummy,
497 (void *)devctl_dummy,
498 (void *)devctl_dummy,
499 (void *)devctl_dummy,
500 (void *)devctl_dummy,
501 (void *)devctl_dummy,
502 (void *)devctl_dummy,
503 (void *)devctl_dummy,
504 (void *)devctl_dummy,
505 (void *)devctl_dummy,
506 (void *)devctl_dummy,
507 (void *)devctl_dummy,
508 (void *)devctl_dummy,
509 (void *)devctl_dummy,
510 (void *)devctl_dummy,
511 (void *)devctl_dummy,
512 (void *)devctl_dummy,
513 (void *)devctl_dummy,
514 (void *)devctl_dummy,
515 (void *)devctl_dummy,
516 (void *)devctl_dummy,
517 (void *)devctl_dummy,
518 (void *)devctl_dummy,
519 (void *)devctl_dummy,
520 (void *)devctl_dummy,
521 (void *)devctl_dummy,
522 (void *)devctl_dummy,
523 (void *)devctl_dummy,
524 (void *)devctl_dummy,
525 (void *)devctl_dummy,
526 (void *)devctl_dummy,
527 (void *)devctl_dummy,
528 (void *)devctl_dummy,
529 (void *)devctl_dummy,
530 (void *)devctl_dummy,
531 (void *)devctl_dummy,
532 (void *)devctl_dummy,
533 (void *)devctl_dummy,
534 (void *)devctl_dummy,
535 (void *)devctl_dummy,
536 (void *)devctl_dummy,
537 (void *)devctl_dummy,
538 (void *)devctl_dummy,
539 (void *)devctl_dummy,
540 (void *)devctl_dummy,
541 (void *)devctl_dummy,
542 (void *)devctl_dummy,
543 (void *)devctl_dummy,
544 (void *)devctl_dummy,
545 (void *)devctl_dummy,
546 (void *)devctl_dummy,
547 (void *)devctl_dummy,
548 (void *)devctl_dummy,
549 (void *)devctl_dummy,
550 (void *)devctl_dummy,
551 (void *)devctl_dummy,
552 (void *)devctl_dummy,
553 (void *)devctl_dummy,
554 (void *)devctl_dummy,
555 (void *)devctl_dummy,
556 (void *)devctl_dummy2,
557 (void *)devctl_dummy2,
558 (void *)devctl_dummy2,
559 (void *)devctl_dummy,
560 (void *)devctl_cdstandby,
561 (void *)devctl_cdstop,
562 (void *)devctl_cdpause,
563 (void *)devctl_cdgettoc,
564 (void *)devctl_dummy,
565 (void *)devctl_dummy2,
566 (void *)devctl_dummy2,
567 (void *)devctl_dummy,
568 (void *)devctl_dummy,
569 (void *)devctl_dummy,
570 (void *)devctl_dummy,
571 (void *)devctl_dummy,
572 (void *)devctl_dummy,
573 (void *)devctl_intref
576 #define MAX_FDHANDLES 64
577 FHANDLE cdvdman_fdhandles[MAX_FDHANDLES];
579 typedef struct {
580 u32 rootDirtocLBA;
581 u32 rootDirtocLength;
582 } layer_info_t;
584 layer_info_t layer_info[2];
586 static int cdvdman_cdinited = 0;
587 cdvdman_status_t cdvdman_stat;
588 static void *user_cb;
590 #ifndef HDD_DRIVER
591 static int cdvdman_layer1start = 0;
592 #endif
594 static int cdrom_io_sema;
595 static int cdvdman_cdreadsema;
596 static int cdvdman_searchfilesema;
598 #ifndef ALT_READ_CORE
599 static int cdvdman_lockreadsema;
600 static int sync_flag;
601 #endif
603 static char cdvdman_dirname[256];
604 static char cdvdman_filepath[256];
605 static char cdvdman_curdir[256];
607 // buffers
608 #define CDVDMAN_BUF_SECTORS 2
609 static u8 cdvdman_buf[CDVDMAN_BUF_SECTORS*2048] __attribute__((aligned(64)));
611 #define CDVDMAN_FS_SECTORS 2
612 #define CDVDMAN_FS_BUFSIZE CDVDMAN_FS_SECTORS * 2048
613 static u8 cdvdman_fs_buf[CDVDMAN_FS_BUFSIZE + 2*2048] __attribute__((aligned(64)));
615 iop_sys_clock_t cdvdman_sysclock;
617 static int fs_inited = 0;
619 #ifdef HDD_DRIVER
620 int lba_48bit = 0;
621 int atad_inited = 0;
622 static hdl_apa_header apaHeader;
624 typedef struct {
625 u32 part_offset; // in MB
626 u32 data_start; // in sectors
627 u32 part_size; // in KB
628 } cdvdman_partspecs_t;
630 cdvdman_partspecs_t cdvdman_partspecs;
631 #endif
633 #define CDVDMAN_MODULE_VERSION 0x225
634 static int cdvdman_debug_print_flag = 0;
636 static int cdvdman_no_tray_model = 0;
637 static int cdvdman_media_changed = 1;
639 static int cdvdman_cur_disc_type = 0; /* real current disc type */
640 unsigned int ReadPos = 0; /* Current buffer offset in 2048-byte sectors. */
642 //-------------------------------------------------------------------------
643 #ifdef ALT_READ_CORE
645 #define NCMD_INIT 0x00
646 #define NCMD_READ 0x01
647 #define NCMD_READCDDA 0x02
648 #define NCMD_SEEK 0x03
649 #define NCMD_STANDBY 0x04
650 #define NCMD_STOP 0x05
651 #define NCMD_PAUSE 0x06
653 static int cdvdman_NCmdlocksema;
654 static int cdvdman_NCmdsema;
655 static int cdvdman_NCmdsemacount = 0;
656 static int cdvdman_mbxid;
658 typedef struct {
659 int ncmd;
660 u8 nbuf[28];
661 } cdvdman_NCmd_t;
663 typedef struct NCmdMbx {
664 iop_message_t iopmsg;
665 cdvdman_NCmd_t NCmdmsg;
666 struct NCmdMbx *next;
667 } NCmdMbx_t;
669 cdvdman_NCmd_t cdvdman_NCmd;
671 static void *cdvdman_pMbxnext;
672 static void *cdvdman_pMbxcur;
673 static void *cdvdman_pMbxbuf = NULL;
675 #define NCMD_NUMBER 16
676 static u8 cdvdman_Mbxbuf[NCMD_NUMBER*sizeof(NCmdMbx_t)];
678 NCmdMbx_t *cdvdman_setNCmdMbx(void);
679 void cdvdman_getNCmdMbx(NCmdMbx_t *mbxbuf);
680 void cdvdman_sendNCmdMbx(int mbxid, cdvdman_NCmd_t *NCmdmsg, int size);
681 cdvdman_NCmd_t *cdvdman_receiveNCmdMbx(int mbxid);
682 void cdvdman_startNCmdthread(void);
683 void cdvdman_NCmdthread(void *args);
684 int cdvdman_sendNCmd(u8 ncmd, void *ndata, int ndlen);
685 void cdvdman_waitNCmdsema(void);
686 void cdvdman_signalNCmdsema(void);
687 void cdvdman_waitsignalNCmdsema(void);
688 int cdvdman_getNCmdstate(void);
689 void cdvdman_NCmdCall(u8 ncmd, void *ndata);
690 void (*NCmd_fn)(void *ndata);
691 void NCmd_cdInit(void *ndata);
692 void NCmd_cdRead(void *ndata);
693 void NCmd_cdReadCDDA(void *ndata);
694 void NCmd_cdSeek(void *ndata);
695 void NCmd_cdStandby(void *ndata);
696 void NCmd_cdStop(void *ndata);
697 void NCmd_cdPause(void *ndata);
698 int (*cdSync_fn)(void);
699 int cdSync_blk(void);
700 int cdSync_noblk(void);
701 int cdSync_dummy(void);
703 // NCmd funcs array
704 void *NCmd_tab[7] = {
705 (void *)NCmd_cdInit,
706 (void *)NCmd_cdRead,
707 (void *)NCmd_cdReadCDDA,
708 (void *)NCmd_cdSeek,
709 (void *)NCmd_cdStandby,
710 (void *)NCmd_cdStop,
711 (void *)NCmd_cdPause
714 // cdSync funcs array
715 void *cdSync_tab[18] = {
716 (void *)cdSync_blk,
717 (void *)cdSync_noblk,
718 (void *)cdSync_dummy,
719 (void *)cdSync_blk,
720 (void *)cdSync_dummy,
721 (void *)cdSync_blk,
722 (void *)cdSync_dummy,
723 (void *)cdSync_dummy,
724 (void *)cdSync_dummy,
725 (void *)cdSync_dummy,
726 (void *)cdSync_dummy,
727 (void *)cdSync_dummy,
728 (void *)cdSync_dummy,
729 (void *)cdSync_dummy,
730 (void *)cdSync_dummy,
731 (void *)cdSync_dummy,
732 (void *)cdSync_blk,
733 (void *)cdSync_noblk
736 //--------------------------------------------------------------
737 NCmdMbx_t *cdvdman_setNCmdMbx(void)
739 int i, oldstate;
740 NCmdMbx_t *pmbx;
742 if (!cdvdman_pMbxbuf) {
743 // Here we init the thread message buffer
744 cdvdman_pMbxbuf = cdvdman_Mbxbuf;
745 mips_memset(cdvdman_pMbxbuf, 0, sizeof(NCmdMbx_t) * NCMD_NUMBER);
747 pmbx = (NCmdMbx_t *)cdvdman_pMbxbuf;
749 for (i = (NCMD_NUMBER-2); i >= 0; i--) {
750 pmbx->next = (NCmdMbx_t *)(pmbx + 1);
751 pmbx++;
754 cdvdman_pMbxnext = cdvdman_pMbxbuf;
755 pmbx->next = NULL;
758 if (!cdvdman_pMbxnext)
759 return (NCmdMbx_t *)NULL;
761 pmbx = (NCmdMbx_t *)cdvdman_pMbxnext;
762 cdvdman_pMbxnext = pmbx->next;
763 pmbx->next = (NCmdMbx_t *)cdvdman_pMbxcur;
765 cdvdman_pMbxcur = (void *)pmbx;
767 return (NCmdMbx_t *)pmbx;
770 //--------------------------------------------------------------
771 void cdvdman_getNCmdMbx(NCmdMbx_t *pmbx)
773 cdvdman_pMbxcur = (void *)pmbx->next;
774 pmbx->next = (NCmdMbx_t *)cdvdman_pMbxnext;
776 cdvdman_pMbxnext = (void *)pmbx;
779 //--------------------------------------------------------------
780 void cdvdman_sendNCmdMbx(int mbxid, cdvdman_NCmd_t *NCmdmsg, int size)
782 NCmdMbx_t *pmbx;
784 pmbx = cdvdman_setNCmdMbx();
786 if (size > sizeof(cdvdman_NCmd_t)) // 32
787 size = sizeof(cdvdman_NCmd_t); // 32
789 if (size)
790 mips_memcpy((void *)&pmbx->NCmdmsg, (void *)NCmdmsg, size);
792 if (QueryIntrContext())
793 iSendMbx(mbxid, (void *)pmbx);
794 else
795 SendMbx(mbxid, (void *)pmbx);
798 //--------------------------------------------------------------
799 cdvdman_NCmd_t *cdvdman_receiveNCmdMbx(int mbxid)
801 NCmdMbx_t *pmbx;
802 int r;
804 r = ReceiveMbx((void **)&pmbx, mbxid);
805 if (r < 0)
806 return (cdvdman_NCmd_t *)NULL;
808 cdvdman_getNCmdMbx(pmbx);
810 return (cdvdman_NCmd_t *)(&pmbx->NCmdmsg);
813 //--------------------------------------------------------------
814 int cdvdman_sendNCmd(u8 ncmd, void *ndata, int ndlen)
816 if (cdvdman_NCmdlocksema) {
817 if (cdvdman_stat.cdNCmd)
818 return 0;
820 WaitSema(cdvdman_NCmdsema);
823 cdvdman_stat.cdNCmd = 1;
824 cdvdman_NCmd.ncmd = ncmd;
826 if (ndlen)
827 mips_memcpy(cdvdman_NCmd.nbuf, ndata, ndlen);
829 cdvdman_sendNCmdMbx(cdvdman_mbxid, (cdvdman_NCmd_t *)&cdvdman_NCmd, sizeof(cdvdman_NCmd_t));
831 return 1;
834 //--------------------------------------------------------------
835 void cdvdman_waitNCmdsema(void)
837 if (!cdvdman_NCmdsemacount) {
838 cdvdman_NCmdlocksema = 0;
839 WaitSema(cdvdman_NCmdsema);
842 cdvdman_NCmdsemacount++;
845 //--------------------------------------------------------------
846 void cdvdman_signalNCmdsema(void)
848 if (!cdvdman_NCmdsemacount)
849 return;
851 cdvdman_NCmdsemacount--;
853 if (!cdvdman_NCmdsemacount) {
855 SignalSema(cdvdman_NCmdsema);
857 cdvdman_NCmdlocksema = 1;
861 //--------------------------------------------------------------
862 void cdvdman_waitsignalNCmdsema(void)
864 WaitSema(cdvdman_NCmdsema);
865 SignalSema(cdvdman_NCmdsema);
868 //--------------------------------------------------------------
869 int cdvdman_getNCmdstate(void)
871 return cdvdman_stat.cdNCmd;
874 //--------------------------------------------------------------
875 void cdvdman_NCmdthread(void *args)
877 cdvdman_NCmd_t *NCmd;
879 while (1) {
880 NCmd = cdvdman_receiveNCmdMbx(cdvdman_mbxid);
882 cdvdman_NCmdCall(NCmd->ncmd, (void *)NCmd->nbuf);
884 cdvdman_stat.cdNCmd = 0;
886 if (cdvdman_NCmdlocksema)
887 SignalSema(cdvdman_NCmdsema);
889 //SetEventFlag(cdvdman_stat.cdvdman_intr_ef, 1);
893 //--------------------------------------------------------------
894 void cdvdman_startNCmdthread(void)
896 int thid;
897 iop_mbx_t mbx;
898 iop_sema_t smp;
899 iop_thread_t thread_param;
901 mips_memset(&mbx, 0, sizeof(iop_mbx_t));
902 cdvdman_mbxid = CreateMbx(&mbx);
904 smp.initial = 1;
905 smp.max = 1;
906 smp.attr = 0;
907 smp.option = 0;
909 cdvdman_NCmdsema = CreateSema(&smp);
910 cdvdman_NCmdlocksema = 1;
911 cdvdman_NCmdsemacount = 0;
913 thread_param.thread = (void *)cdvdman_NCmdthread;
914 thread_param.stacksize = 0x2000;
915 thread_param.priority = 0x01;
916 thread_param.attr = TH_C;
917 thread_param.option = 0;
919 thid = CreateThread(&thread_param);
920 StartThread(thid, NULL);
923 //--------------------------------------------------------------
924 void cdvdman_NCmdCall(u8 ncmd, void *ndata)
926 if ((u32)(ncmd >= 7))
927 return;
929 NCmd_fn = NCmd_tab[ncmd];
931 NCmd_fn(ndata);
934 //--------------------------------------------------------------
935 void NCmd_cdInit(void *ndata)
937 cdvdman_cdinit();
940 //--------------------------------------------------------------
941 void NCmd_cdRead(void *ndata)
943 int r;
944 u32 lsn, sectors;
945 void *buf;
946 u8 *wdbuf = (u8 *)ndata;
948 cdvdman_stat.err = CDVD_ERR_NO;
950 lsn = *((u32 *)&wdbuf[0]);
951 sectors = *((u32 *)&wdbuf[4]);
952 buf = (void *)*((u32 *)&wdbuf[8]);
954 r = sceCdRead0(lsn, sectors, buf, NULL);
955 if (r == 0)
956 cdvdman_stat.err = CDVD_ERR_READ;
958 cdvdman_stat.status = CDVD_STAT_PAUSE;
960 cdvdman_cb_event(SCECdFuncRead);
963 //--------------------------------------------------------------
964 void NCmd_cdReadCDDA(void *ndata)
966 int r;
967 u32 lsn, sectors;
968 void *buf;
969 u8 *wdbuf = (u8 *)ndata;
971 cdvdman_stat.err = CDVD_ERR_NO;
973 lsn = *((u32 *)&wdbuf[0]);
974 sectors = *((u32 *)&wdbuf[4]);
975 buf = (void *)*((u32 *)&wdbuf[8]);
977 r = sceCdRead0(lsn, sectors, buf, NULL);
978 if (r == 0)
979 cdvdman_stat.err = CDVD_ERR_READ;
981 cdvdman_stat.status = CDVD_STAT_PAUSE;
983 cdvdman_cb_event(SCECdFuncReadCDDA);
986 //--------------------------------------------------------------
987 void NCmd_cdSeek(void *ndata)
989 u32 lsn;
990 u8 *wdbuf = (u8 *)ndata;
992 lsn = *((u32 *)&wdbuf[0]);
994 cdvdman_stat.status = CDVD_STAT_PAUSE;
996 cdvdman_cb_event(SCECdFuncSeek);
999 //--------------------------------------------------------------
1000 void NCmd_cdStandby(void *ndata)
1002 cdvdman_stat.status = CDVD_STAT_SPIN;
1004 cdvdman_cb_event(SCECdFuncStandby);
1007 //--------------------------------------------------------------
1008 void NCmd_cdStop(void *ndata)
1010 cdvdman_stat.status = CDVD_STAT_STOP;
1012 cdvdman_cb_event(SCECdFuncStop);
1015 //--------------------------------------------------------------
1016 void NCmd_cdPause(void *ndata)
1018 cdvdman_stat.err = CDVD_ERR_NO;
1019 cdvdman_stat.status = CDVD_STAT_PAUSE;
1021 cdvdman_cb_event(SCECdFuncPause);
1024 //--------------------------------------------------------------
1025 int cdSync_blk(void)
1027 cdvdman_waitsignalNCmdsema();
1029 return 0;
1032 //--------------------------------------------------------------
1033 int cdSync_dummy(void)
1035 return 0;
1038 //--------------------------------------------------------------
1039 int cdSync_noblk(void)
1041 return cdvdman_getNCmdstate();
1044 #endif // ALT_READ_CORE
1047 //--------------------------------------------------------------
1048 #ifdef USB_DRIVER
1049 void usbd_init(void)
1051 modinfo_t info;
1052 getModInfo("usbd\0\0\0\0", &info);
1054 // Set functions pointers here
1055 pUsbRegisterDriver = info.exports[4];
1056 pUsbGetDeviceStaticDescriptor = info.exports[6];
1057 pUsbSetDevicePrivateData = info.exports[7];
1058 pUsbOpenEndpoint = info.exports[9];
1059 pUsbCloseEndpoint = info.exports[10];
1060 pUsbTransfer = info.exports[11];
1061 pUsbOpenEndpointAligned = info.exports[12];
1063 #endif
1064 #ifdef SMB_DRIVER
1065 void ps2ip_init(void)
1067 modinfo_t info;
1068 getModInfo("ps2ip\0\0\0", &info);
1070 // Set functions pointers here
1071 plwip_close = info.exports[6];
1072 plwip_connect = info.exports[7];
1073 plwip_recvfrom = info.exports[10];
1074 plwip_send = info.exports[11];
1075 plwip_socket = info.exports[13];
1076 pinet_addr = info.exports[24];
1078 #endif
1080 //--------------------------------------------------------------
1081 void fs_init(void)
1083 if (fs_inited)
1084 return;
1086 DPRINTF("fs_init\n");
1088 #ifdef USB_DRIVER
1089 // initialize usbd exports
1090 usbd_init();
1092 FlushDcache();
1094 // initialize the mass driver
1095 mass_stor_init();
1097 // configure mass device
1098 while (mass_stor_configureDevice() <= 0);
1099 #endif
1101 #ifdef SMB_DRIVER
1102 register int i = 0;
1103 char tmp_str[255];
1105 ps2ip_init();
1107 // Open the Connection with SMB server
1108 smb_NegociateProtocol(g_pc_ip, g_pc_port, g_smb_user, g_smb_password);
1110 // zero pad the string to be sure it does not overflow
1111 g_pc_share[31] = '\0';
1113 // open a session
1114 smb_SessionSetupAndX();
1116 // Then tree connect on the share resource
1117 sprintf(tmp_str, "\\\\%s\\%s", g_pc_ip, g_pc_share);
1118 smb_TreeConnectAndX(tmp_str);
1120 char *path_str;
1121 // if g_part_start[0] not zero, then it is a plain ISO
1122 if (g_part_start[0]) {
1123 char *game_name = (char *)&g_part_start[0];
1124 if (g_pc_prefix[0]) {
1125 path_str = (g_ISO_media == 0x12) ? "%s\\CD\\%s.%s%s" : "%s\\DVD\\%s.%s%s";
1126 sprintf(tmp_str, path_str, g_pc_prefix, g_ISO_name + 5, game_name, g_ISO_name);
1127 } else {
1128 path_str = (g_ISO_media == 0x12) ? "CD\\%s.%s%s" : "DVD\\%s.%s%s";
1129 sprintf(tmp_str, path_str, g_ISO_name + 5, game_name, g_ISO_name);
1131 smb_OpenAndX(tmp_str, (u16 *)&g_part_start[i++], 0);
1132 } else {
1133 // Open all parts files
1134 for (i = 0; i < g_ISO_parts; i++) {
1135 if (g_pc_prefix[0])
1136 sprintf(tmp_str, "%s\\%s.%02x", g_pc_prefix, g_ISO_name, i);
1137 else
1138 sprintf(tmp_str, "%s.%02x", g_ISO_name, i);
1139 smb_OpenAndX(tmp_str, (u16 *)&g_part_start[i], 0);
1142 #endif
1144 #ifdef HDD_DRIVER
1145 DPRINTF("fs_init: apa header LBA = %d\n", g_part_start[0]);
1147 int r = ata_device_dma_transfer(0, &apaHeader, g_part_start[0], 2, ATA_DIR_READ);
1148 if (r != 0)
1149 DPRINTF("fs_init: failed to read apa header %d\n", r);
1151 // checking HDL's deadfeed magic
1152 if (apaHeader.checksum != 0xdeadfeed)
1153 DPRINTF("fs_init: failed to find deadfeed magic\n");
1155 mips_memcpy(&cdvdman_partspecs, &apaHeader.part_specs[0], sizeof(cdvdman_partspecs));
1156 #endif
1158 mips_memset(&cdvdman_fdhandles[0], 0, MAX_FDHANDLES * sizeof(FHANDLE));
1160 // Read the volume descriptor
1161 sceCdRead0(16, 1, cdvdman_buf, NULL);
1163 struct dirTocEntry *tocEntryPointer = (struct dirTocEntry *)&cdvdman_buf[0x9c];
1164 layer_info[0].rootDirtocLBA = tocEntryPointer->fileLBA;
1165 layer_info[0].rootDirtocLength = tocEntryPointer->length;
1167 // DVD DL support
1168 if (!g_gamesetting_disable_DVDDL) {
1169 #ifdef HDD_DRIVER
1170 int on_dual;
1171 u32 layer1_start;
1172 sceCdReadDvdDualInfo(&on_dual, &layer1_start);
1173 if (on_dual) {
1174 sceCdRead0(layer1_start + 16, 1, cdvdman_buf, NULL);
1175 tocEntryPointer = (struct dirTocEntry *)&cdvdman_buf[0x9c];
1176 layer_info[1].rootDirtocLBA = layer1_start + tocEntryPointer->fileLBA;
1177 layer_info[1].rootDirtocLength = tocEntryPointer->length;
1179 #else
1180 u32 volSize = (*((u32 *)&cdvdman_buf[0x50]));
1181 sceCdRead0(volSize, 1, cdvdman_buf, NULL);
1182 if ((cdvdman_buf[0x00] == 1) && (!strncmp(&cdvdman_buf[0x01], "CD001", 5))) {
1183 cdvdman_layer1start = volSize - 16;
1184 tocEntryPointer = (struct dirTocEntry *)&cdvdman_buf[0x9c];
1185 layer_info[1].rootDirtocLBA = cdvdman_layer1start + tocEntryPointer->fileLBA;
1186 layer_info[1].rootDirtocLength = tocEntryPointer->length;
1188 #endif
1191 fs_inited = 1;
1194 //-------------------------------------------------------------------------
1195 int sceCdInit(int init_mode)
1197 cdvdman_stat.err = CDVD_ERR_NO;
1199 #ifdef ALT_READ_CORE
1200 g_gamesetting_alt_read = 0; //to shut off warning
1201 cdvdman_stat.cddiskready = CDVD_READY_NOTREADY;
1202 cdvdman_sendNCmd(NCMD_INIT, NULL, 0);
1203 cdvdman_waitsignalNCmdsema();
1204 cdvdman_stat.cddiskready = CDVD_READY_READY;
1205 #else
1206 fs_init();
1207 #endif
1208 cdvdman_cdinited = 1;
1210 return 1;
1213 //-------------------------------------------------------------------------
1214 int sceCdStandby(void)
1216 cdvdman_stat.err = CDVD_ERR_NO;
1217 cdvdman_stat.status = CDVD_STAT_SPIN;
1219 #ifdef ALT_READ_CORE
1220 cdvdman_sendNCmd(NCMD_STANDBY, NULL, 0);
1221 #else
1222 cdvdman_cb_event(SCECdFuncStandby);
1223 #endif
1225 return 1;
1228 //-------------------------------------------------------------------------
1229 int sceCdRead(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode)
1231 DPRINTF("sceCdRead lsn=%d sectors=%d buf=%08x\n", (int)lsn, (int)sectors, (int)buf);
1233 #ifdef ALT_READ_CORE
1234 u8 wdbuf[16];
1235 cdvdman_stat.err = CDVD_ERR_NO;
1237 *((u32 *)&wdbuf[0]) = lsn;
1238 *((u32 *)&wdbuf[4]) = sectors;
1239 *((u32 *)&wdbuf[8]) = (u32)buf;
1241 cdvdman_stat.status = CDVD_STAT_READ;
1243 cdvdman_sendNCmd(NCMD_READ, (void *)wdbuf, 12);
1244 #else
1245 cdvdman_stat.status = CDVD_STAT_READ;
1246 if ((QueryIntrContext()) || (g_gamesetting_alt_read == 0)) {
1247 if (sync_flag == 1) {
1248 DPRINTF("sceCdRead: exiting (sync_flag)...\n");
1249 return 0;
1252 sync_flag = 1;
1253 cdvdman_stat.cdread_lba = lsn;
1254 cdvdman_stat.cdread_sectors = sectors;
1255 cdvdman_stat.cdread_buf = buf;
1256 cdvdman_stat.cdread_mode = *mode;
1258 if (QueryIntrContext())
1259 iSignalSema(cdvdman_lockreadsema);
1260 else
1261 SignalSema(cdvdman_lockreadsema);
1263 else {
1264 sync_flag = 1;
1265 sceCdRead0(lsn, sectors, buf, mode);
1267 cdvdman_stat.status = CDVD_STAT_PAUSE;
1269 cdvdman_cb_event(SCECdFuncRead);
1270 sync_flag = 0;
1272 #endif
1274 return 1;
1277 //-------------------------------------------------------------------------
1278 int sceCdSeek(u32 lsn)
1280 DPRINTF("sceCdSeek %d\n", (int)lsn);
1282 cdvdman_stat.err = CDVD_ERR_NO;
1284 #ifdef ALT_READ_CORE
1285 u8 wdbuf[16];
1287 *((u32 *)&wdbuf[0]) = lsn;
1289 cdvdman_stat.status = CDVD_STAT_SEEK;
1291 cdvdman_sendNCmd(NCMD_SEEK, (void *)wdbuf, 4);
1292 #else
1293 cdvdman_stat.status = CDVD_STAT_PAUSE;
1295 cdvdman_cb_event(SCECdFuncSeek);
1296 #endif
1298 return 1;
1301 //-------------------------------------------------------------------------
1302 int sceCdGetError(void)
1304 DPRINTF("sceCdGetError %d\n", cdvdman_stat.err);
1306 return cdvdman_stat.err;
1309 //-------------------------------------------------------------------------
1310 int sceCdGetToc(void *toc)
1312 cdvdman_stat.err = CDVD_ERR_READ;
1314 return 1;
1317 //-------------------------------------------------------------------------
1318 int sceCdSearchFile(cd_file_t *pcd_file, const char *name)
1320 DPRINTF("sceCdSearchFile %s\n", name);
1322 return cdvdman_findfile(pcd_file, name, 0);
1325 //-------------------------------------------------------------------------
1326 int sceCdSync(int mode)
1328 DPRINTF("sceCdSync %d sync flag = %d\n", mode, sync_flag);
1330 #ifdef ALT_READ_CORE
1331 if (mode >= 18)
1332 return cdSync_dummy();
1334 cdSync_fn = cdSync_tab[mode];
1336 return cdSync_fn();
1337 #else
1338 if (!sync_flag)
1339 return 0;
1341 if ((mode == 1) || (mode == 17))
1342 return 1;
1344 while (sync_flag)
1345 DelayThread(5000);
1347 return 0;
1348 #endif
1351 //-------------------------------------------------------------------------
1352 void cdvdman_initDiskType()
1354 cdvdman_stat.err = CDVD_ERR_NO;
1356 #ifdef HDD_DRIVER
1357 fs_init();
1359 cdvdman_cur_disc_type = (int)apaHeader.discType;
1360 #else
1361 cdvdman_cur_disc_type = (int)g_ISO_media;
1362 #endif
1363 cdvdman_stat.disc_type_reg = cdvdman_cur_disc_type;
1364 DPRINTF("DiskType=0x%x\n", cdvdman_cur_disc_type);
1367 //-------------------------------------------------------------------------
1368 int sceCdGetDiskType(void)
1370 return cdvdman_stat.disc_type_reg;
1373 //-------------------------------------------------------------------------
1374 int sceCdDiskReady(int mode)
1376 DPRINTF("sceCdDiskReady %d\n", mode);
1377 cdvdman_stat.err = CDVD_ERR_NO;
1379 if (cdvdman_cdinited) {
1380 if (mode == 0) {
1381 while (sceCdDiskReady(1) == CDVD_READY_NOTREADY)
1382 DelayThread(5000);
1385 #ifdef ALT_READ_CORE
1386 if (!cdvdman_stat.cdNCmd) {
1387 if (cdvdman_stat.cddiskready)
1388 return CDVD_READY_READY;
1390 #else
1391 if (!sync_flag)
1392 return CDVD_READY_READY;
1393 #endif
1396 return CDVD_READY_NOTREADY;
1399 //-------------------------------------------------------------------------
1400 int sceCdTrayReq(int mode, u32 *traycnt)
1402 DPRINTF("sceCdTrayReq(%d, 0x%X)\n", mode, traycnt);
1404 if (mode == CDVD_TRAY_CHECK) {
1406 if (traycnt)
1407 *traycnt = cdvdman_media_changed;
1409 cdvdman_media_changed = 0;
1411 return 1;
1414 if (cdvdman_no_tray_model == 1) {
1415 return 1;
1418 if (mode == CDVD_TRAY_OPEN) {
1419 cdvdman_stat.status = CDVD_STAT_OPEN;
1420 cdvdman_stat.disc_type_reg = 0;
1422 DelayThread(11000);
1424 cdvdman_stat.err = CDVD_ERR_OPENS; /* not sure about this error code */
1426 return 1;
1428 else if (mode == CDVD_TRAY_CLOSE) {
1429 DelayThread(25000);
1431 cdvdman_stat.status = CDVD_STAT_PAUSE; /* not sure if the status is right, may be - CDVD_STAT_SPIN */
1432 cdvdman_stat.err = CDVD_ERR_NO; /* not sure if this error code is suitable here */
1433 cdvdman_stat.disc_type_reg = cdvdman_cur_disc_type;
1435 cdvdman_media_changed = 1;
1437 return 1;
1440 return 0;
1443 //-------------------------------------------------------------------------
1444 int sceCdStop(void)
1446 cdvdman_stat.err = CDVD_ERR_NO;
1448 #ifdef ALT_READ_CORE
1449 cdvdman_sendNCmd(NCMD_STOP, NULL, 0);
1450 #else
1451 cdvdman_stat.status = CDVD_STAT_STOP;
1452 cdvdman_cb_event(SCECdFuncStop);
1453 #endif
1454 return 1;
1457 //-------------------------------------------------------------------------
1458 int sceCdPosToInt(cd_location_t *p)
1459 { // TODO: Improve with logical ops only
1461 register int result;
1463 result = ((u32)p->minute >> 16) * 10 + ((u32)p->minute & 0xF);
1464 result *= 60;
1465 result += ((u32)p->second >> 16) * 10 + ((u32)p->second & 0xF);
1466 result *= 75;
1467 result += ((u32)p->sector >> 16) * 10 + ((u32)p->sector & 0xF);
1468 result -= 150;
1470 return result;
1473 //-------------------------------------------------------------------------
1474 cd_location_t *sceCdIntToPos(int i, cd_location_t *p)
1475 { // TODO: Improve with logical ops only
1477 register int sc, se, mi;
1479 i += 150;
1480 se = i / 75;
1481 sc = i - se * 75;
1482 mi = se / 60;
1483 se = se - mi * 60;
1484 p->sector = (sc - (sc / 10) * 10) + (sc / 10) * 16;
1485 p->second = (se / 10) * 16 + se - (se / 10) * 10;
1486 p->minute = (mi / 10) * 16 + mi - (mi / 10) * 10;
1488 return p;
1491 //-------------------------------------------------------------------------
1492 int sceCdRI(char *buf, int *stat)
1494 u8 rdbuf[16];
1496 cdvdman_sendSCmd(0x12, NULL, 0, rdbuf, 9);
1498 if (stat)
1499 *stat = (int)rdbuf[0];
1501 mips_memcpy((void *)buf, (void *)&rdbuf[1], 8);
1503 return 1;
1506 //-------------------------------------------------------------------------
1507 int sceCdReadClock(cd_clock_t *rtc)
1509 int rc;
1511 cdvdman_stat.err = CDVD_ERR_NO;
1513 rc = cdvdman_sendSCmd(0x08, NULL, 0, (void *)rtc, 8);
1515 rtc->week = 0;
1516 rtc->month &= 0x7f;
1518 return rc;
1521 //-------------------------------------------------------------------------
1522 int sceCdStatus(void)
1524 DPRINTF("sceCdStatus %d\n", cdvdman_stat.status);
1526 return cdvdman_stat.status;
1529 //-------------------------------------------------------------------------
1530 int sceCdApplySCmd(int cmd, void *in, u32 in_size, void *out)
1532 DPRINTF("sceCdApplySCmd\n");
1534 return cdvdman_sendSCmd(cmd & 0xff, in, in_size, out, 16);
1537 //-------------------------------------------------------------------------
1538 int *sceCdCallback(void *func)
1540 int oldstate;
1541 void *old_cb;
1543 DPRINTF("sceCdCallback %08x\n", (int)func);
1545 old_cb = user_cb;
1547 CpuSuspendIntr(&oldstate);
1549 user_cb = func;
1551 CpuResumeIntr(oldstate);
1553 return (int *)old_cb;
1556 //-------------------------------------------------------------------------
1557 int sceCdPause(void)
1559 cdvdman_stat.err = CDVD_ERR_NO;
1561 #ifdef ALT_READ_CORE
1562 cdvdman_sendNCmd(NCMD_PAUSE, NULL, 0);
1563 #else
1564 cdvdman_stat.status = CDVD_STAT_PAUSE;
1565 cdvdman_cb_event(SCECdFuncPause);
1566 #endif
1568 return 1;
1571 //-------------------------------------------------------------------------
1572 int sceCdBreak(void)
1574 DPRINTF("sceCdBreak\n");
1576 cdvdman_stat.err = CDVD_ERR_NO;
1577 cdvdman_stat.status = CDVD_STAT_PAUSE;
1579 #ifdef ALT_READ_CORE
1580 if (QueryIntrContext() == 0) {
1581 while (cdvdman_stat.cdNCmd)
1582 DelayThread(100000);
1584 #endif
1586 cdvdman_stat.err = CDVD_ERR_ABRT;
1587 cdvdman_cb_event(SCECdFuncBreak);
1589 return 1;
1592 //-------------------------------------------------------------------------
1593 int sceCdReadCdda(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode)
1595 #ifdef ALT_READ_CORE
1596 u8 wdbuf[16];
1597 cdvdman_stat.err = CDVD_ERR_NO;
1599 *((u32 *)&wdbuf[0]) = lsn;
1600 *((u32 *)&wdbuf[4]) = sectors;
1601 *((u32 *)&wdbuf[8]) = (u32)buf;
1603 cdvdman_stat.status = CDVD_STAT_READ;
1605 cdvdman_sendNCmd(NCMD_READCDDA, (void *)wdbuf, 12);
1607 return 1;
1608 #else
1609 return sceCdRead(lsn, sectors, buf, mode);
1610 #endif
1613 //-------------------------------------------------------------------------
1614 int sceCdGetReadPos(void)
1616 DPRINTF("sceCdGetReadPos\n");
1618 return ReadPos;
1621 //-------------------------------------------------------------------------
1622 int sceCdSC(int code, int *param)
1624 DPRINTF("sceCdSC(0x%X, 0x%X)\n", code, param);
1626 if (code == 0xFFFFFFF7) {
1627 return CDVDMAN_MODULE_VERSION;
1629 else if (code == 0xFFFFFFF0) {
1630 *param = (int)&cdvdman_debug_print_flag;
1631 return 0xFF;
1634 /* dummy result */
1635 return 1;
1638 //-------------------------------------------------------------------------
1639 int sceCdRC(cd_clock_t *rtc)
1641 cdvdman_stat.err = CDVD_ERR_NO;
1643 return cdvdman_sendSCmd(0x08, NULL, 0, (void *)rtc, 8);
1646 //-------------------------------------------------------------------------
1647 int sceCdStInit(u32 bufmax, u32 bankmax, void *iop_bufaddr)
1649 cdvdman_stat.err = CDVD_ERR_NO;
1650 cdvdman_stat.Ststat = 0;
1651 cdvdman_stat.Stbufmax = bufmax;
1653 return 1;
1656 //-------------------------------------------------------------------------
1657 int sceCdStRead(u32 sectors, void *buf, u32 mode, u32 *err)
1659 sceCdRead0(cdvdman_stat.Stlsn, sectors, buf, NULL);
1660 cdvdman_stat.Stlsn += sectors;
1662 if (err)
1663 *err = sceCdGetError();
1665 return sectors;
1668 //-------------------------------------------------------------------------
1669 int sceCdStSeek(u32 lsn)
1671 cdvdman_stat.err = CDVD_ERR_NO;
1672 cdvdman_stat.Stlsn = lsn;
1674 return 1;
1677 //-------------------------------------------------------------------------
1678 int sceCdStStart(u32 lsn, cd_read_mode_t *mode)
1680 if (mode->datapattern)
1681 cdvdman_stat.err = CDVD_ERR_READ;
1682 else {
1683 cdvdman_stat.err = CDVD_ERR_NO;
1684 cdvdman_stat.Stlsn = lsn;
1685 cdvdman_stat.Ststat = 0;
1686 cdvdman_stat.status = CDVD_STAT_PAUSE;
1689 return 1;
1692 //-------------------------------------------------------------------------
1693 int sceCdStStat(void)
1695 if (cdvdman_stat.Ststat == 1)
1696 return 0;
1698 return cdvdman_stat.Stbufmax;
1701 //-------------------------------------------------------------------------
1702 int sceCdStStop(void)
1704 cdvdman_stat.Ststat = 1;
1705 cdvdman_stat.err = CDVD_ERR_NO;
1706 cdvdman_stat.status = CDVD_STAT_PAUSE;
1708 return 1;
1711 //-------------------------------------------------------------------------
1712 #ifndef HDD_DRIVER
1713 int cdvdman_ReadSect(u32 lsn, u32 nsectors, void *buf)
1715 register u32 r, sectors_to_read, lbound, ubound, nlsn, offslsn;
1716 register int i, esc_flag = 0;
1717 u8 *p = (u8 *)buf;
1719 lbound = 0;
1720 ubound = (g_ISO_parts > 1) ? 0x80000 : 0xFFFFFFFF;
1721 offslsn = lsn;
1722 r = nlsn = 0;
1723 sectors_to_read = nsectors;
1725 for (i=0; i<g_ISO_parts; i++, lbound=ubound, ubound+=0x80000, offslsn-=0x80000) {
1727 if (lsn>=lbound && lsn<ubound){
1728 if ((lsn + nsectors) > (ubound-1)) {
1729 sectors_to_read = ubound - lsn;
1730 nsectors -= sectors_to_read;
1731 nlsn = ubound;
1733 else
1734 esc_flag = 1;
1736 #ifdef USB_DRIVER
1737 mass_stor_ReadCD(offslsn, sectors_to_read, &p[r], i);
1738 #endif
1739 #ifdef SMB_DRIVER
1740 smb_ReadCD(offslsn, sectors_to_read, &p[r], i);
1741 #endif
1742 r += sectors_to_read << 11;
1743 sectors_to_read = nsectors;
1744 lsn = nlsn;
1747 if (esc_flag)
1748 break;
1751 return 1;
1753 #endif
1755 //-------------------------------------------------------------------------
1756 int sceCdRead0(u32 lsn, u32 sectors, void *buf, cd_read_mode_t *mode)
1758 register int r;
1760 r = QueryIntrContext();
1762 if ((u32)(buf) & 3) {
1763 WaitSema(cdvdman_searchfilesema);
1765 u32 nsectors, nbytes;
1766 u32 rpos = lsn;
1768 while (sectors > 0) {
1769 nsectors = sectors;
1770 if (nsectors > CDVDMAN_BUF_SECTORS)
1771 nsectors = CDVDMAN_BUF_SECTORS;
1773 DPRINTF("sceCdRead0 lsn=%d rpos=%d nsectors=%d buf=%08x\n", (int)lsn, (int)rpos, (int)nsectors, (int)buf);
1775 sceCdRead0(rpos, nsectors, cdvdman_buf, mode);
1777 rpos += nsectors;
1778 sectors -= nsectors;
1779 nbytes = nsectors << 11;
1781 mips_memcpy(buf, cdvdman_buf, nbytes);
1783 buf = (void *)(buf + nbytes);
1785 SignalSema(cdvdman_searchfilesema);
1787 else {
1788 if (r) {
1789 DPRINTF("sceCdRead0 exiting (Intr context)...\n");
1790 return 0;
1793 WaitSema(cdvdman_cdreadsema);
1795 DPRINTF("sceCdRead0 lsn=%d sectors=%d buf=%08x\n", (int)lsn, (int)sectors, (int)buf);
1797 cdvdman_stat.err = CDVD_ERR_NO;
1799 #ifdef HDD_DRIVER
1800 u32 offset = 0;
1801 while (sectors) {
1802 if (!((lsn >= cdvdman_partspecs.part_offset) && (lsn < (cdvdman_partspecs.part_offset + (cdvdman_partspecs.part_size >> 11)))))
1803 cdvdman_get_part_specs(lsn);
1805 if (cdvdman_stat.err != CDVD_ERR_NO)
1806 break;
1808 u32 nsectors = (cdvdman_partspecs.part_offset + (cdvdman_partspecs.part_size >> 11)) - lsn;
1809 if (sectors < nsectors)
1810 nsectors = sectors;
1812 u32 lba = cdvdman_partspecs.data_start + ((lsn - cdvdman_partspecs.part_offset) << 2);
1813 if (ata_device_dma_transfer(0, (void *)(buf + offset), lba, nsectors << 2, ATA_DIR_READ) != 0) {
1814 cdvdman_stat.err = CDVD_ERR_READ;
1815 break;
1817 offset += nsectors << 11;
1818 sectors -= nsectors;
1819 lsn += nsectors;
1820 ReadPos += nsectors;
1823 #else
1824 cdvdman_ReadSect(lsn, sectors, buf);
1825 #endif
1827 DPRINTF("sceCdRead0 ret=%d\n", r);
1829 SignalSema(cdvdman_cdreadsema);
1832 ReadPos = 0; /* Reset the buffer offset indicator. */
1834 return 1;
1837 //-------------------------------------------------------------------------
1838 int cdvdman_readMechaconVersion(char *mname, u32 *stat)
1840 u8 rdbuf[16];
1841 u8 wrbuf[16];
1843 wrbuf[0] = 0;
1844 cdvdman_sendSCmd(0x03, wrbuf, 1, rdbuf, 4);
1846 *stat = rdbuf[0] & 0x80;
1847 rdbuf[0] &= 0x7f;
1849 mips_memcpy(mname, &rdbuf[0], 4);
1851 return 1;
1854 //-------------------------------------------------------------------------
1855 int sceCdRM(char *m, u32 *stat)
1857 register int r;
1858 u8 rdbuf[16];
1859 u8 wrbuf[16];
1861 *stat = 0;
1862 r = cdvdman_readMechaconVersion(rdbuf, stat);
1863 if ((r == 1) && (0x104FE < (rdbuf[3] | (rdbuf[2] << 8) | (rdbuf[1] << 16)))) {
1865 mips_memcpy(&m[0], "M_NAME_UNKNOWN\0\0", 16);
1866 *stat |= 0x40;
1868 else {
1869 wrbuf[0] = 0;
1870 cdvdman_sendSCmd(0x17, wrbuf, 1, rdbuf, 9);
1872 *stat = rdbuf[0];
1873 mips_memcpy(&m[0], &rdbuf[1], 8);
1875 wrbuf[0] = 8;
1876 cdvdman_sendSCmd(0x17, wrbuf, 1, rdbuf, 9);
1878 *stat |= rdbuf[0];
1879 mips_memcpy(&m[8], &rdbuf[1], 8);
1882 return 1;
1885 //-------------------------------------------------------------------------
1886 int sceCdStPause(void)
1888 cdvdman_stat.err = CDVD_ERR_NO;
1890 return 1;
1893 //-------------------------------------------------------------------------
1894 int sceCdStResume(void)
1896 cdvdman_stat.err = CDVD_ERR_NO;
1897 cdvdman_stat.status = CDVD_STAT_PAUSE;
1899 return 1;
1902 //-------------------------------------------------------------------------
1903 int sceCdStSeekF(u32 lsn)
1905 cdvdman_stat.err = CDVD_ERR_NO;
1906 cdvdman_stat.Stlsn = lsn;
1908 return 1;
1911 //-------------------------------------------------------------------------
1912 int sceCdReadDiskID(void *DiskID)
1914 int i;
1915 u8 *p = (u8 *)DiskID;
1917 for (i=0; i<5; i++) {
1918 if (p[i]!=0)
1919 break;
1921 if (i == 5)
1922 *((u16 *)DiskID) = (u16)0xadde;
1923 else
1924 mips_memcpy(DiskID, &g_DiskID[1], 5);
1926 return 1;
1929 //-------------------------------------------------------------------------
1930 int sceCdReadDvdDualInfo(int *on_dual, u32 *layer1_start)
1932 if (g_gamesetting_disable_DVDDL) {
1933 *layer1_start = 0;
1934 *on_dual = 1;
1936 else {
1937 #ifdef HDD_DRIVER
1938 *layer1_start = apaHeader.layer1_start;
1939 *on_dual = (apaHeader.layer1_start > 0) ? 1 : 0;
1940 #else
1941 *layer1_start = cdvdman_layer1start;
1942 *on_dual = (cdvdman_layer1start > 0) ? 1 : 0;
1943 #endif
1946 return 1;
1949 //-------------------------------------------------------------------------
1950 int sceCdLayerSearchFile(cdl_file_t *fp, const char *name, int layer)
1952 DPRINTF("sceCdLayerSearchFile %s\n", name);
1954 return cdvdman_findfile((cd_file_t *)fp, name, layer);
1957 //--------------------------------------------------------------
1958 int cdvdman_readID(int mode, u8 *buf)
1960 u8 lbuf[16];
1961 int stat;
1962 int r;
1964 r = sceCdRI(lbuf, &stat);
1965 if ((r == 0) || (stat))
1966 return 0;
1968 if (mode == 0) { // GUID
1969 u32 *GUID0 = (u32 *)&buf[0];
1970 u32 *GUID1 = (u32 *)&buf[4];
1971 *GUID0 = lbuf[0] | 0x08004600;
1972 *GUID1 = *(u32 *)&lbuf[4];
1974 else { // ModelID
1975 u32 *ModelID = (u32 *)&buf[0];
1976 *ModelID = (*(u32 *)&lbuf[0]) >> 8;
1979 return 1;
1982 //--------------------------------------------------------------
1983 int sceCdReadGUID(void *GUID)
1985 return cdvdman_readID(0, GUID);
1988 //--------------------------------------------------------------
1989 int sceCdReadModelID(void *ModelID)
1991 return cdvdman_readID(1, ModelID);
1994 //--------------------------------------------------------------
1995 int cdrom_dummy(void)
1997 return -EPERM;
2000 //--------------------------------------------------------------
2001 int cdrom_init(iop_device_t *dev)
2003 iop_sema_t smp;
2005 smp.initial = 1;
2006 smp.max = 1;
2007 smp.attr = 1;
2008 smp.option = 0;
2010 cdrom_io_sema = CreateSema(&smp);
2012 smp.initial = 1;
2013 smp.max = 1;
2014 smp.attr = 1;
2015 smp.option = 0;
2017 cdvdman_searchfilesema = CreateSema(&smp);
2019 DPRINTF("cdrom_init\n");
2021 return 0;
2024 //--------------------------------------------------------------
2025 int cdrom_deinit(iop_device_t *dev)
2027 DeleteSema(cdrom_io_sema);
2029 DPRINTF("cdrom_deinit\n");
2031 return 0;
2034 //--------------------------------------------------------------
2035 FHANDLE *cdvdman_getfilefreeslot(void)
2037 register int i;
2038 FHANDLE *fh;
2040 for (i=0; i<MAX_FDHANDLES; i++) {
2041 fh = (FHANDLE *)&cdvdman_fdhandles[i];
2042 if (fh->f == NULL)
2043 return fh;
2046 return 0;
2049 //--------------------------------------------------------------
2050 int cdrom_open(iop_file_t *f, char *filename, int mode)
2052 register int r = 0;
2053 FHANDLE *fh;
2054 cd_file_t cdfile;
2056 if (!filename)
2057 return -ENOENT;
2059 WaitSema(cdrom_io_sema);
2061 fs_init();
2063 DPRINTF("cdrom_open %s mode=%d\n", filename, mode);
2065 fh = cdvdman_getfilefreeslot();
2066 if (fh) {
2067 r = cdvdman_findfile(&cdfile, filename, f->unit);
2068 if (r) {
2069 f->privdata = fh;
2070 fh->f = f;
2071 if (!g_gamesetting_disable_DVDDL) {
2072 if (f->mode == 0)
2073 f->mode = r;
2075 fh->filesize = cdfile.size;
2076 fh->lsn = cdfile.lsn;
2077 fh->position = 0;
2078 r = 0;
2081 else
2082 r = -ENOENT;
2084 else
2085 r = -EMFILE;
2087 DPRINTF("cdrom_open ret=%d lsn=%d size=%d\n", r, (int)fh->lsn, (int)fh->filesize);
2089 SignalSema(cdrom_io_sema);
2091 return r;
2094 //--------------------------------------------------------------
2095 int cdrom_close(iop_file_t *f)
2097 FHANDLE *fh = (FHANDLE *)f->privdata;
2099 WaitSema(cdrom_io_sema);
2101 DPRINTF("cdrom_close\n");
2103 if (fh)
2104 mips_memset(fh, 0, sizeof(FHANDLE));
2106 SignalSema(cdrom_io_sema);
2108 return 0;
2111 //--------------------------------------------------------------
2112 int cdrom_read(iop_file_t *f, void *buf, u32 size)
2114 FHANDLE *fh = (FHANDLE *)f->privdata;
2115 register int rpos, sectorpos;
2116 register u32 nsectors, nbytes;
2118 WaitSema(cdrom_io_sema);
2120 DPRINTF("cdrom_read size=%d file_position=%d\n", (int)size, (int)fh->position);
2122 rpos = 0;
2124 if ((fh->position + size) > fh->filesize)
2125 size = fh->filesize - fh->position;
2127 while (size) {
2128 nbytes = CDVDMAN_FS_BUFSIZE;
2129 if (size < nbytes)
2130 nbytes = size;
2132 nsectors = nbytes >> 11;
2133 sectorpos = fh->position & 2047;
2135 if (sectorpos)
2136 nsectors++;
2138 if (nbytes & 2047)
2139 nsectors++;
2141 sceCdRead0(fh->lsn + ((fh->position & -2048) >> 11), nsectors, cdvdman_fs_buf, NULL);
2142 mips_memcpy(buf, &cdvdman_fs_buf[sectorpos], nbytes);
2144 rpos += nbytes;
2145 buf += nbytes;
2146 size -= nbytes;
2147 fh->position += nbytes;
2150 DPRINTF("cdrom_read ret=%d\n", (int)rpos);
2151 SignalSema(cdrom_io_sema);
2153 return rpos;
2156 //--------------------------------------------------------------
2157 int cdrom_lseek(iop_file_t *f, u32 offset, int where)
2159 register int r;
2160 FHANDLE *fh = (FHANDLE *)f->privdata;
2162 WaitSema(cdrom_io_sema);
2164 DPRINTF("cdrom_lseek offset=%d where=%d\n", (int)offset, (int)where);
2166 switch (where) {
2167 case SEEK_CUR:
2168 r = fh->position + offset;
2169 if (r > fh->filesize) {
2170 r = -EINVAL;
2171 goto ssema;
2173 break;
2174 case SEEK_SET:
2175 r = offset;
2176 if (fh->filesize < offset) {
2177 r = -EINVAL;
2178 goto ssema;
2180 break;
2181 case SEEK_END:
2182 r = fh->filesize - offset;
2183 break;
2184 default:
2185 r = -EINVAL;
2186 goto ssema;
2189 fh->position = r;
2190 if (fh->position > fh->filesize)
2191 fh->position = fh->filesize;
2193 ssema:
2194 DPRINTF("cdrom_lseek file offset=%d\n", (int)fh->position);
2195 SignalSema(cdrom_io_sema);
2197 return r;
2200 //--------------------------------------------------------------
2201 int cdrom_getstat(iop_file_t *f, char *filename, iox_stat_t *stat)
2203 return sceCdLayerSearchFile((cdl_file_t *)&stat->attr, filename, f->unit) - 1;
2206 //--------------------------------------------------------------
2207 int cdrom_dopen(iop_file_t *f, char *dirname)
2209 return cdrom_open(f, dirname, 8);
2212 //--------------------------------------------------------------
2213 int cdrom_dread(iop_file_t *f, iox_dirent_t *dirent)
2215 register int r = 0;
2216 register u32 mode;
2217 FHANDLE *fh = (FHANDLE *)f->privdata;
2218 struct dirTocEntry *tocEntryPointer;
2220 WaitSema(cdrom_io_sema);
2222 DPRINTF("cdrom_dread fh->lsn=%d\n", (int)fh->lsn);
2224 sceCdRead0(fh->lsn, 1, cdvdman_fs_buf, NULL);
2226 do {
2227 r = 0;
2228 tocEntryPointer = (struct dirTocEntry *)&cdvdman_fs_buf[fh->position];
2229 if (tocEntryPointer->length == 0)
2230 break;
2232 fh->position += tocEntryPointer->length;
2233 r = 1;
2235 while (tocEntryPointer->filenameLength == 1);
2237 mode = 0x2124;
2238 if (tocEntryPointer->fileProperties & 2)
2239 mode = 0x116d;
2241 dirent->stat.mode = mode;
2242 dirent->stat.size = tocEntryPointer->fileSize;
2243 strncpy(dirent->name, tocEntryPointer->filename, 256);
2245 DPRINTF("cdrom_dread r=%d mode=%04x name=%s\n", r, (int)mode, dirent->name);
2247 SignalSema(cdrom_io_sema);
2249 return r;
2252 //--------------------------------------------------------------
2253 int cdrom_dclose(iop_file_t *f)
2255 return cdrom_close(f);
2258 //--------------------------------------------------------------
2259 int cdrom_ioctl(iop_file_t *f, u32 cmd, void *args)
2261 register int r = 0;
2263 WaitSema(cdrom_io_sema);
2265 if (cmd != 0x10000) // Spin Ctrl op
2266 r = -EINVAL;
2268 SignalSema(cdrom_io_sema);
2270 return r;
2273 //--------------------------------------------------------------
2274 s64 cdrom_lseek64(iop_file_t *f, s64 pos, int where)
2276 DPRINTF("cdrom_lseek64 where=%d\n", (int)where);
2277 return (s64)cdrom_lseek(f, (u32)pos, where);
2280 //--------------------------------------------------------------
2281 int cdrom_ioctl2(iop_file_t *f, int cmd, void *args, u32 arglen, void *buf, u32 buflen)
2283 register int r = 0;
2285 WaitSema(cdrom_io_sema);
2287 if (cmd == CIOCSTREAMPAUSE)
2288 sceCdStPause();
2289 else if (cmd == CIOCSTREAMRESUME)
2290 sceCdStResume();
2291 else if (cmd == CIOCSTREAMSTAT)
2292 r = sceCdStStat();
2293 else
2294 r = -EINVAL;
2296 SignalSema(cdrom_io_sema);
2298 return r;
2301 //--------------------------------------------------------------
2302 int cdrom_devctl(iop_file_t *f, const char *name, int cmd, void *args, u32 arglen, void *buf, u32 buflen)
2304 register int r;
2306 if (!name)
2307 return -ENOENT;
2309 WaitSema(cdrom_io_sema);
2311 cmd -= CDIOC_CMDBASE;
2312 if (cmd > 133)
2313 return devctl_dummy(args, buf);
2315 devctl_fn = devctl_tab[cmd];
2316 r = devctl_fn(args, buf);
2318 SignalSema(cdrom_io_sema);
2320 return r;
2323 //-------------------------------------------------------------------------
2324 int devctl_dummy(void *args, void *buf)
2326 return -EIO;
2329 //-------------------------------------------------------------------------
2330 int devctl_dummy2(void *args, void *buf)
2332 return 0;
2335 //-------------------------------------------------------------------------
2336 int devctl_retonly(void *args, void *buf)
2338 return 1;
2341 //-------------------------------------------------------------------------
2342 int devctl_cdreadclock(void *args, void *buf)
2344 sceCdReadClock((cd_clock_t *)buf);
2345 return 0;
2348 //-------------------------------------------------------------------------
2349 int devctl_cdreadGUID(void *args, void *buf)
2351 sceCdReadGUID(buf);
2352 return 0;
2355 //-------------------------------------------------------------------------
2356 int devctl_cdreadDiskID(void *args, void *buf)
2358 sceCdReadDiskID(buf);
2359 return 0;
2362 //-------------------------------------------------------------------------
2363 int devctl_cdgetdisktype(void *args, void *buf)
2365 *(int *)buf = sceCdGetDiskType();
2366 return 0;
2369 //-------------------------------------------------------------------------
2370 int devctl_cdgeterror(void *args, void *buf)
2372 *(int *)buf = sceCdGetError();
2373 return 0;
2376 //-------------------------------------------------------------------------
2377 int devctl_cdtrayreq(void *args, void *buf)
2379 sceCdTrayReq(*(int *)args, (u32 *)args);
2380 return 0;
2383 //-------------------------------------------------------------------------
2384 int devctl_cdstatus(void *args, void *buf)
2386 *(int *)buf = sceCdStatus();
2387 return 0;
2390 //-------------------------------------------------------------------------
2391 int devctl_cddiskready(void *args, void *buf)
2393 *(int *)buf = sceCdDiskReady(*(int *)args);
2394 return 0;
2397 //-------------------------------------------------------------------------
2398 int devctl_cdreadModelID(void *args, void *buf)
2400 sceCdReadModelID(buf);
2401 return 0;
2404 //-------------------------------------------------------------------------
2405 int devctl_cdStinit(void *args, void *buf)
2407 u8 *p = (u8 *)buf;
2408 u32 bufmax = *(u32 *)&p[0];
2409 u32 bankmax = *(u32 *)&p[4];
2410 u32 iopbuf = *(u32 *)&p[8];
2412 sceCdStInit(bufmax, bankmax, (void *)iopbuf);
2413 return 0;
2416 //-------------------------------------------------------------------------
2417 int devctl_cdabort(void *args, void *buf)
2419 sceCdBreak();
2420 return 0;
2423 //-------------------------------------------------------------------------
2424 int devctl_cdstandby(void *args, void *buf)
2426 sceCdStandby();
2427 return 0;
2430 //-------------------------------------------------------------------------
2431 int devctl_cdstop(void *args, void *buf)
2433 sceCdStop();
2434 return 0;
2437 //-------------------------------------------------------------------------
2438 int devctl_cdpause(void *args, void *buf)
2440 sceCdPause();
2441 return 0;
2444 //-------------------------------------------------------------------------
2445 int devctl_cdgettoc(void *args, void *buf)
2447 sceCdGetToc(buf);
2448 return 0;
2451 //-------------------------------------------------------------------------
2452 int devctl_intref(void *args, void *buf)
2454 *(int *)buf = cdvdman_stat.intr_ef;
2455 return cdvdman_stat.intr_ef;
2458 //-------------------------------------------------------------------------
2459 void cdvdman_trimspaces(char* str)
2461 int i, len;
2462 char *p;
2464 len = strlen(str);
2465 if (len == 0)
2466 return;
2468 i = len - 1;
2470 for (i = len-1; i != -1; i--) {
2471 p = &str[i];
2472 if ((*p != 0x20) && (*p != 0x2e))
2473 break;
2474 *p = 0;
2477 while (!strcmp(&str[len-3], ";;1")) { // Tenchu: Wrath oh Heaven fix
2478 str[len-2] = '1';
2479 str[len-1] = 0;
2480 len = strlen(str);
2483 while (!strcmp(&str[len-4], ";1;1")) { // SmackDown: shut your mouth fix
2484 str[len-2] = 0;
2485 len = strlen(str);
2489 //-------------------------------------------------------------------------
2490 struct dirTocEntry *cdvdman_locatefile(char *name, u32 tocLBA, int tocLength, int layer)
2492 char *p = (char *)name;
2493 char *slash;
2494 int r, len, filename_len;
2495 int tocPos;
2496 struct dirTocEntry *tocEntryPointer;
2498 lbl_startlocate:
2499 DPRINTF("cdvdman_locatefile start locating, layer=%d\n", layer);
2501 while (*p == '/')
2502 p++;
2504 while (*p == '\\')
2505 p++;
2507 slash = strchr(p, '/');
2509 // if the path doesn't contain a '/' then look for a '\'
2510 if (!slash)
2511 slash = strchr (p, '\\');
2513 len = (u32)slash - (u32)p;
2515 // if a slash was found
2516 if (slash != NULL) {
2518 if (len >= 256)
2519 return NULL;
2521 // copy the path into main 'dir' var
2522 strncpy(cdvdman_dirname, p, len);
2523 cdvdman_dirname[len] = 0;
2525 else {
2526 if (strlen(p) >= 256)
2527 return NULL;
2529 strcpy(cdvdman_dirname, p);
2532 while (tocLength > 0) {
2533 sceCdRead0(tocLBA, 1, cdvdman_buf, NULL);
2534 DPRINTF("cdvdman_locatefile tocLBA read done\n");
2536 tocLength -= 2048;
2537 tocLBA++;
2539 tocPos = 0;
2540 do {
2541 tocEntryPointer = (struct dirTocEntry *)&cdvdman_buf[tocPos];
2543 if (tocEntryPointer->length == 0)
2544 break;
2546 filename_len = tocEntryPointer->filenameLength;
2547 if (filename_len) {
2548 strncpy(cdvdman_curdir, tocEntryPointer->filename, 256); // copy filename
2549 cdvdman_curdir[filename_len] = 0;
2551 DPRINTF("cdvdman_locatefile strcmp %s %s\n", cdvdman_dirname, cdvdman_curdir);
2553 r = strcmp(cdvdman_dirname, cdvdman_curdir);
2554 if ((!r) && (!slash)) { // we searched a file so it's found
2555 DPRINTF("cdvdman_locatefile found file! LBA=%d size=%d\n", (int)tocEntryPointer->fileLBA, (int)tocEntryPointer->fileSize);
2556 return tocEntryPointer;
2558 else if ((!r) && (tocEntryPointer->fileProperties & 2)) { // we found it but it's a directory
2559 tocLBA = tocEntryPointer->fileLBA;
2560 tocLength = tocEntryPointer->fileSize;
2561 p = &slash[1];
2563 if (!g_gamesetting_disable_DVDDL) {
2564 int on_dual;
2565 u32 layer1_start;
2566 sceCdReadDvdDualInfo(&on_dual, &layer1_start);
2568 if (layer)
2569 tocLBA += layer1_start;
2572 goto lbl_startlocate;
2574 else {
2575 tocPos += (tocEntryPointer->length << 16) >> 16;
2579 while (tocPos < 2016);
2582 DPRINTF("cdvdman_locatefile file not found!!!\n");
2584 return NULL;
2587 //-------------------------------------------------------------------------
2588 int cdvdman_findfile(cd_file_t *pcdfile, const char *name, int layer)
2590 register int len;
2591 register u32 lsn;
2592 struct dirTocEntry *tocEntryPointer;
2594 if ((!pcdfile) || (!name))
2595 return 0;
2597 WaitSema(cdvdman_searchfilesema);
2599 DPRINTF("cdvdman_findfile %s layer%d\n", name, layer);
2601 strncpy(cdvdman_filepath, name, 256);
2603 cdvdman_trimspaces(cdvdman_filepath);
2605 DPRINTF("cdvdman_findfile cdvdman_filepath=%s\n", cdvdman_filepath);
2607 if (g_gamesetting_disable_DVDDL)
2608 layer = 0;
2610 if (layer < 2) {
2611 if (layer_info[layer].rootDirtocLBA == 0) {
2612 SignalSema(cdvdman_searchfilesema);
2613 return 0;
2616 tocEntryPointer = cdvdman_locatefile(cdvdman_filepath, layer_info[layer].rootDirtocLBA, layer_info[layer].rootDirtocLength, layer);
2617 if (tocEntryPointer == NULL) {
2618 len = strlen(name);
2619 if (len < 256) {
2620 sprintf(cdvdman_filepath, "%s;1", name);
2621 cdvdman_trimspaces(cdvdman_filepath);
2622 tocEntryPointer = cdvdman_locatefile(cdvdman_filepath, layer_info[layer].rootDirtocLBA, layer_info[layer].rootDirtocLength, layer);
2623 if (tocEntryPointer == NULL) {
2624 SignalSema(cdvdman_searchfilesema);
2625 return 0;
2628 if (len == 0) {
2629 SignalSema(cdvdman_searchfilesema);
2630 return 0;
2634 lsn = tocEntryPointer->fileLBA;
2635 if (layer) {
2636 sceCdReadDvdDualInfo((int *)&pcdfile->lsn, &pcdfile->size);
2637 lsn += pcdfile->size;
2640 pcdfile->lsn = lsn;
2641 if ((g_gamesetting_0_pss) && \
2642 ((!strncmp(&cdvdman_filepath[strlen(cdvdman_filepath)-6], ".PSS", 4)) || \
2643 (!strncmp(&cdvdman_filepath[strlen(cdvdman_filepath)-6], ".pss", 4))))
2644 pcdfile->size = 0;
2645 else
2646 pcdfile->size = tocEntryPointer->fileSize;
2648 strcpy(pcdfile->name, strrchr(name, '\\')+1);
2650 else {
2651 SignalSema(cdvdman_searchfilesema);
2652 return 0;
2655 DPRINTF("cdvdman_findfile found %s\n", name);
2657 SignalSema(cdvdman_searchfilesema);
2659 return 1;
2662 //-------------------------------------------------------------------------
2663 int cdvdman_writeSCmd(u8 cmd, void *in, u32 in_size, void *out, u32 out_size)
2665 int i;
2666 u8 dummy;
2667 u8 *p;
2668 u8 rdbuf[64];
2670 WaitSema(cdvdman_cdreadsema);
2672 if (CDVDreg_SDATAIN & 0x80) {
2673 SignalSema(cdvdman_cdreadsema);
2674 return 0;
2677 if (!(CDVDreg_SDATAIN & 0x40)) {
2678 do {
2679 dummy = CDVDreg_SDATAOUT;
2680 } while (!(CDVDreg_SDATAIN & 0x40));
2683 if (in_size > 0) {
2684 for (i = 0; i < in_size; i++) {
2685 p = (void *)(in + i);
2686 CDVDreg_SDATAIN = *p;
2690 CDVDreg_SCOMMAND = cmd;
2691 dummy = CDVDreg_SCOMMAND;
2693 while (CDVDreg_SDATAIN & 0x80) {;}
2695 i = 0;
2696 if (!(CDVDreg_SDATAIN & 0x40)) {
2697 do {
2698 p = (void *)(rdbuf + i);
2699 *p = CDVDreg_SDATAOUT;
2700 i++;
2701 } while (!(CDVDreg_SDATAIN & 0x40));
2704 if (out_size > i)
2705 out_size = i;
2707 mips_memcpy((void *)out, (void *)rdbuf, out_size);
2709 SignalSema(cdvdman_cdreadsema);
2711 return 1;
2714 //--------------------------------------------------------------
2715 int cdvdman_sendSCmd(u8 cmd, void *in, u32 in_size, void *out, u32 out_size)
2717 int r, retryCount = 0;
2719 retry:
2721 r = cdvdman_writeSCmd(cmd & 0xff, in, in_size, out, out_size);
2722 if (r == 0) {
2723 DelayThread(2000);
2724 if (++retryCount <= 2500)
2725 goto retry;
2728 DelayThread(2000);
2730 return 1;
2733 //--------------------------------------------------------------
2734 static u8 cb_args[8] __attribute__((aligned(16)));
2735 int cdvdman_cb_event(int reason)
2737 iop_sys_clock_t sys_clock;
2738 int oldstate;
2739 u8 *ptr;
2741 if (user_cb) {
2742 CpuSuspendIntr(&oldstate);
2743 //ptr = AllocSysMemory(ALLOC_FIRST, 8, NULL);
2744 ptr = (u8 *)cb_args;
2745 CpuResumeIntr(oldstate);
2747 if (ptr) {
2748 *((u32 *)&ptr[0]) = (u32)user_cb;
2749 *((u32 *)&ptr[4]) = reason;
2751 USec2SysClock(g_gamesetting_timer, &sys_clock);
2753 DPRINTF("cdvdman_cb_event reason: %d - setting cb alarm...\n", reason);
2755 if (QueryIntrContext())
2756 iSetAlarm(&sys_clock, event_alarm_cb, ptr);
2757 else
2758 SetAlarm(&sys_clock, event_alarm_cb, ptr);
2762 return 1;
2765 //-------------------------------------------------------------------------
2766 void (*cbfunc)(int reason);
2768 unsigned int event_alarm_cb(void *args)
2770 register int reason;
2771 u8 *ptr = (u8 *)args;
2773 cbfunc = (void *)*((u32 *)&ptr[0]);
2774 reason = *((u32 *)&ptr[4]);
2776 //FreeSysMemory(args);
2778 cbfunc(reason);
2780 return 0;
2783 //-------------------------------------------------------------------------
2784 #ifndef ALT_READ_CORE
2785 void cdvdman_cdread_Thread(void *args)
2787 while (1) {
2788 WaitSema(cdvdman_lockreadsema);
2790 while (QueryIntrContext())
2791 DelayThread(10000);
2793 sceCdRead0(cdvdman_stat.cdread_lba, cdvdman_stat.cdread_sectors, cdvdman_stat.cdread_buf, &cdvdman_stat.cdread_mode);
2795 sync_flag = 0;
2796 cdvdman_stat.status = CDVD_STAT_PAUSE;
2798 cdvdman_cb_event(SCECdFuncRead);
2802 //-------------------------------------------------------------------------
2803 void cdvdman_startThreads(void)
2805 iop_thread_t thread_param;
2806 register int thid;
2808 cdvdman_stat.status = CDVD_STAT_PAUSE;
2809 cdvdman_stat.err = CDVD_ERR_NO;
2811 thread_param.thread = (void *)cdvdman_cdread_Thread;
2812 thread_param.stacksize = 0x2000;
2813 thread_param.priority = 0x0f;
2814 thread_param.attr = TH_C;
2815 thread_param.option = 0;
2817 thid = CreateThread(&thread_param);
2818 StartThread(thid, NULL);
2820 #endif
2822 //-------------------------------------------------------------------------
2823 void cdvdman_create_semaphores(void)
2825 iop_sema_t smp;
2827 smp.initial = 1;
2828 smp.max = 1;
2829 smp.attr = 0;
2830 smp.option = 0;
2832 cdvdman_cdreadsema = CreateSema(&smp);
2834 #ifndef ALT_READ_CORE
2835 smp.initial = 0;
2836 smp.max = 1;
2837 smp.attr = 0;
2838 smp.option = 0;
2840 cdvdman_lockreadsema = CreateSema(&smp);
2841 #endif
2844 //-------------------------------------------------------------------------
2845 void cdvdman_initdev(void)
2847 iop_event_t event;
2849 event.attr = 2;
2850 event.option = 0;
2851 event.bits = 0;
2853 cdvdman_stat.intr_ef = CreateEventFlag(&event);
2854 ClearEventFlag(cdvdman_stat.intr_ef, 0);
2856 DelDrv("cdrom");
2857 AddDrv((iop_device_t *)&cdrom_dev);
2860 //-------------------------------------------------------------------------
2861 #ifdef HDD_DRIVER
2862 void cdvdman_get_part_specs(u32 lsn)
2864 register int i;
2865 cdvdman_partspecs_t *ps = (cdvdman_partspecs_t *)&apaHeader.part_specs[0];
2867 for (i = 0; i < apaHeader.num_partitions; i++) {
2868 if (lsn >= ps->part_offset) {
2869 if (lsn < (ps->part_offset + (ps->part_size >> 11))) {
2870 mips_memcpy(&cdvdman_partspecs, ps, sizeof(cdvdman_partspecs));
2871 break;
2874 ps++;
2877 if (i >= apaHeader.num_partitions)
2878 cdvdman_stat.err = CDVD_ERR_READ;
2880 #endif
2882 //-------------------------------------------------------------------------
2883 int _start(int argc, char **argv)
2885 // register exports
2886 RegisterLibraryEntries(&_exp_cdvdman);
2887 RegisterLibraryEntries(&_exp_cdvdstm);
2888 #ifdef SMB_DRIVER
2889 RegisterLibraryEntries(&_exp_dev9);
2890 dev9_init();
2891 #endif
2892 #ifdef HDD_DRIVER
2893 #ifdef HD_PRO
2894 #ifdef __IOPCORE_DEBUG
2895 RegisterLibraryEntries(&_exp_dev9);
2896 #endif
2897 #else
2898 RegisterLibraryEntries(&_exp_dev9);
2899 #endif
2900 RegisterLibraryEntries(&_exp_atad);
2902 #ifdef HD_PRO
2903 #ifdef __IOPCORE_DEBUG
2904 dev9_init();
2905 #endif
2906 #else
2907 dev9_init();
2908 #endif
2909 atad_start();
2911 atad_inited = 1;
2912 #endif
2913 #ifdef USB_DRIVER
2914 #ifdef __USE_DEV9
2915 RegisterLibraryEntries(&_exp_dev9);
2916 dev9_init();
2917 #endif
2918 #endif
2919 RegisterLibraryEntries(&_exp_smsutils);
2920 #ifdef VMC_DRIVER
2921 RegisterLibraryEntries(&_exp_oplutils);
2922 #endif
2923 // create SCMD/searchfile semaphores
2924 cdvdman_create_semaphores();
2926 // start cdvdman threads
2927 #ifdef ALT_READ_CORE
2928 cdvdman_startNCmdthread();
2929 #else
2930 cdvdman_startThreads();
2931 #endif
2932 // register cdrom device driver
2933 cdvdman_initdev();
2935 #ifndef SMB_DRIVER
2936 g_tag[0] = 0; // just to shut off warning
2937 #endif
2938 #ifdef HDD_DRIVER
2939 if (g_ISO_media != 0x69)
2940 lba_48bit = g_ISO_media;
2941 g_ISO_parts = 0x69; // just to shut off warning
2942 #endif
2944 // hook MODLOAD's exports
2945 hookMODLOAD();
2947 // init disk type stuff
2948 cdvdman_initDiskType();
2950 return MODULE_RESIDENT_END;
2953 //-------------------------------------------------------------------------
2954 int _shutdown(void)
2956 #ifdef SMB_DRIVER
2957 smb_Disconnect();
2958 #endif
2960 return 0;