sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
cdvdman.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#include "irx_imports.h"
12
13#include "iomanX.h"
14
15#include <cdvdman.h>
16
17#include <cdvd-ioctl.h>
18#include <dev5_mmio_hwport.h>
19#include <errno.h>
20#include <hdd-ioctl.h>
21#include <iop_mmio_hwport.h>
22#include <kerr.h>
23#include <mipscopaccess.h>
24
25IRX_ID("cdvd_driver", 2, 38);
26// Based on the module from SCE SDK 3.1.0.
27
28extern struct irx_export_table _exp_cdvdman;
29
31{
32 int m_number;
33 int m_parent;
34 int m_extent;
35 char m_name[32];
36} cdvdman_dirtbl_entry_t;
37
38typedef struct cdvdman_fhinfo_
39{
40 u32 m_file_lsn;
41 u32 m_read_pos;
42 u32 m_file_size;
43 u32 m_filemode;
44 int m_fd_flags;
45 int m_fd_layer;
46 int m_cache_file_fd;
47 u8 *m_fd_rcvbuf;
48 u32 m_fd_rbsize;
49 void *m_max_cluster;
50 int m_sector_count_total;
51 int m_cluster_cur;
52} cdvdman_fhinfo_t;
53
54typedef struct cdvdman_pathtbl_
55{
56 int m_cache_path_sz;
57 int m_lsn;
58 unsigned int m_nsec;
59 int m_layer;
60 unsigned int m_cache_hit_count;
61} cdvdman_pathtbl_t;
62
64{
65 sceCdlFILE m_file_struct;
66 int m_flags;
67} cdvdman_filetbl_entry_t;
68
69typedef struct iso9660_desc_
70{
71 // cppcheck-suppress unusedStructMember
72 unsigned char m_type[1];
73 unsigned char m_id[5];
74 // cppcheck-suppress unusedStructMember
75 unsigned char m_version[1];
76 // cppcheck-suppress unusedStructMember
77 unsigned char m_unused1[1];
78 // cppcheck-suppress unusedStructMember
79 unsigned char m_system_id[32];
80 // cppcheck-suppress unusedStructMember
81 unsigned char m_volume_id[32];
82 // cppcheck-suppress unusedStructMember
83 unsigned char m_unused2[8];
84 // cppcheck-suppress unusedStructMember
85 unsigned char m_volume_space_size[8];
86 // cppcheck-suppress unusedStructMember
87 unsigned char m_unused3[32];
88 // cppcheck-suppress unusedStructMember
89 unsigned char m_volume_set_size[4];
90 // cppcheck-suppress unusedStructMember
91 unsigned char m_volume_sequence_number[4];
92 // cppcheck-suppress unusedStructMember
93 unsigned char m_logical_block_size[4];
94 // cppcheck-suppress unusedStructMember
95 unsigned char m_path_table_size[8];
96 unsigned char m_type_l_path_table[4];
97 // cppcheck-suppress unusedStructMember
98 unsigned char m_opt_type_l_path_table[4];
99 // cppcheck-suppress unusedStructMember
100 unsigned char m_type_m_path_table[4];
101 // cppcheck-suppress unusedStructMember
102 unsigned char m_opt_type_m_path_table[4];
103 // cppcheck-suppress unusedStructMember
104 unsigned char m_root_directory_record[34];
105 // cppcheck-suppress unusedStructMember
106 unsigned char m_volume_set_id[128];
107 // cppcheck-suppress unusedStructMember
108 unsigned char m_publisher_id[128];
109 // cppcheck-suppress unusedStructMember
110 unsigned char m_preparer_id[128];
111 // cppcheck-suppress unusedStructMember
112 unsigned char m_application_id[128];
113 // cppcheck-suppress unusedStructMember
114 unsigned char m_copyright_file_id[37];
115 // cppcheck-suppress unusedStructMember
116 unsigned char m_abstract_file_id[37];
117 // cppcheck-suppress unusedStructMember
118 unsigned char m_bibliographic_file_id[37];
119 // cppcheck-suppress unusedStructMember
120 unsigned char m_creation_date[17];
121 // cppcheck-suppress unusedStructMember
122 unsigned char m_modification_date[17];
123 // cppcheck-suppress unusedStructMember
124 unsigned char m_expiration_date[17];
125 // cppcheck-suppress unusedStructMember
126 unsigned char m_effective_date[17];
127 // cppcheck-suppress unusedStructMember
128 unsigned char m_file_structure_version[1];
129 // cppcheck-suppress unusedStructMember
130 unsigned char m_unused4[1];
131 // cppcheck-suppress unusedStructMember
132 unsigned char m_application_data[512];
133 // cppcheck-suppress unusedStructMember
134 unsigned char m_unused5[653];
135} iso9660_desc_t;
136
137typedef struct iso9660_path_
138{
139 unsigned char m_name_len[2];
140 unsigned char m_extent[4];
141 unsigned char m_parent[2];
142 unsigned char m_name[];
143} iso9660_path_t;
144
145typedef struct iso9660_dirent_
146{
147 unsigned char m_length[1];
148 unsigned char m_ext_attr_length[1];
149 unsigned char m_extent[8];
150 unsigned char m_size[8];
151 unsigned char m_date[7];
152 unsigned char m_flags[1];
153 unsigned char m_file_unit_size[1];
154 unsigned char m_interleave[1];
155 unsigned char m_volume_sequence_number[4];
156 unsigned char m_name_len[1];
157 unsigned char m_name[];
158} iso9660_dirent_t;
159
160static int cdrom_init(iop_device_t *dev);
161extern void cdvdman_termcall(int with_stop);
162static int cdrom_deinit(iop_device_t *dev);
163static int cdrom_dopen(iop_file_t *f, const char *dirname);
164static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf);
165static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf);
166static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4);
167static int cdrom_close(iop_file_t *f);
168static int cdrom_read(iop_file_t *f, void *buf, int nbytes);
169static int cdrom_ioctl(iop_file_t *f, int arg, void *param);
170static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen);
171static int
172cdrom_devctl(iop_file_t *f, const char *, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen);
173static int cdrom_lseek(iop_file_t *f, int offset, int pos);
174static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer);
175static int sceCdSearchDir(char *dirname, int layer);
176static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer);
177static int cdvdman_cmpname(const char *p, const char *q);
178static int CD_newmedia(int arg);
179static int cdvdman_finddir(int target_parent, const char *target_name);
180static int CD_cachefile(int dsec, int layer);
181static int disc_read(int size, int loc, void *buffer, int layer);
182static int path_tbl_init(u32 blocks, char *fname, int action);
183extern unsigned int optimized_memcpy(char *dst, const char *src, unsigned int n);
184static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *arg), void *arg);
185static int vCancelAlarm(unsigned int (*alarm_cb)(void *arg), void *arg);
186static int vSetEventFlag(int ef, u32 bits);
187static int vDelayThread(int usec);
188static int DvdDual_infochk();
189static void cdvdman_init();
190static void cdvdman_write_scmd(cdvdman_internal_struct_t *s);
191static int intrh_dma_3(void *userdata);
192static int cdvdman_mediactl(int code);
193#ifndef CDVD_VARIANT_XOSD
194static int cdvdman_ncmd_sender_06();
195#endif
196static int cdvdman_gettoc(u8 *toc);
197static int cdvdman_isdvd();
198static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func);
199static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data);
200static void Read2intrCDVD(int read2_flag);
201#ifndef CDVD_VARIANT_XOSD
202static int cdvdman_scmd_sender_03_30(u8 *buf, u32 *status);
203#endif
204static int cdvdman_scmd_sender_3B(int arg1);
205#ifdef CDVD_VARIANT_DNAS
206static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3);
207#endif
208#ifdef CDVD_VARIANT_XOSD
209static unsigned int sceCdChgSpdlCtrl(int mode);
210#endif
211#ifdef CDVD_VARIANT_XOSD
212static int cdvdman_change_drive(int mode);
213static int cdvdman_get_renewal_date(u8 *buffer, u32 *status);
214static int get_cdvd_register(int regnr);
215static int get_disk_type_ex();
216static int sc_ffffffd8(u32 *status);
217static int set_cdvd_dev5_base_addr_atapi(int mode);
218static int update_cd_mode_ps2_atapi(void);
219#endif
220
221static char g_cdvdman_cache_name[256] = "host0:";
222static int g_cdvdman_cache_sector_size_count = 1;
223static int g_cdvdman_srchspd = 0;
224static int g_cdvdman_spinctl = -1;
225static int g_cdvdman_spinnom = -1;
226static int g_cdvdman_trycnt = -1;
227static int g_cdvdman_iocache = 0;
228static unsigned int g_cdvdman_lcn_offset = 0;
229static unsigned int g_cdvdman_numbytes_offset = 0;
230static int g_cdvdman_strmerr = 0;
231
232IOMANX_RETURN_VALUE_IMPL(EIO);
233
234static iop_device_ops_t g_cdvdman_cddev_ops = {
235 &cdrom_init, // init,
236 &cdrom_deinit, // deinit,
237 IOMANX_RETURN_VALUE(EIO), // format,
238 &cdrom_open, // open,
239 &cdrom_close, // close,
240 &cdrom_read, // read,
241 IOMANX_RETURN_VALUE(EIO), // write,
242 &cdrom_lseek, // lseek,
243 &cdrom_ioctl, // ioctl,
244 IOMANX_RETURN_VALUE(EIO), // remove,
245 IOMANX_RETURN_VALUE(EIO), // mkdir,
246 IOMANX_RETURN_VALUE(EIO), // rmdir,
247 &cdrom_dopen, // dopen,
248 &cdrom_close, // close,
249 &cdrom_dread, // dread
250 &cdrom_getstat, // getstat
251 IOMANX_RETURN_VALUE(EIO), // chstat,
252 IOMANX_RETURN_VALUE(EIO), // rename,
253 IOMANX_RETURN_VALUE(EIO), // chdir
254 IOMANX_RETURN_VALUE(EIO), // sync
255 IOMANX_RETURN_VALUE(EIO), // mount,
256 IOMANX_RETURN_VALUE(EIO), // umount,
257 IOMANX_RETURN_VALUE_S64(EIO), // lseek64,
258 &cdrom_devctl, // devctl,
259 IOMANX_RETURN_VALUE(EIO), // readdir,
260 IOMANX_RETURN_VALUE(EIO), // readlink,
261 &cdrom_ioctl2, // ioctl2,
262};
263static iop_device_t g_cdvdman_cddev = {"cdrom", IOP_DT_FSEXT | IOP_DT_FS, 1, "CD-ROM ", &g_cdvdman_cddev_ops};
264static int g_cdvdman_sync_timeout = 15000;
265static int g_cdvdman_stream_timeout = 5000;
266#ifdef CDVD_VARIANT_DNAS
267static iop_sys_clock_t g_readid_systemtime = {0, 0};
268#endif
269static int g_verbose_level = 0;
270static cdvdman_pathtbl_t *g_cdvdman_pathtbl = NULL;
271static unsigned int g_cache_count = 0;
272static unsigned int g_cache_table = 0;
273static unsigned int g_cdvdman_pathtblsize = 0;
274static int g_cache_path_size = 0;
275static int g_cache_path_fd = -1;
276static int g_cdvdman_fs_cdsec = 0;
277static int g_cdvdman_fs_layer = -1;
278static int g_cdvdman_fs_cache = 0;
279static int g_cdvdman_fs_base2 = 0;
280#ifdef CDVD_VARIANT_XOSD
281static vu8 *g_cdvdreg_bf801460 = (vu8 *)0xBF801460; // &iop_mmio_hwport->dev9c[0]
282// static u8 *cdvdreg_bf801462 = 0xBF801462;
283static vu8 *g_cdvdreg_bf801464 = (vu8 *)0xBF801464; // &iop_mmio_hwport->dev9c[4]
284static vu8 *g_cdvdreg_bf80146c = (vu8 *)0xBF80146C; // &iop_mmio_hwport->dev9c[0xC]
285// static u8 *cdvdreg_bf80146e = 0xBF80146E;
286static int g_cd_atapi_evfid = 0xFFFFFFFF;
287static int g_acmd_evfid = 0xFFFFFFFF;
288static int g_adma_evfid = 0xFFFFFFFF;
289#endif
290static int g_cdvdman_clk_flg = 0;
291static int g_cdvdman_cd36key = 0;
292static int g_cdvdman_ee_rpc_fno = 0;
293static int g_cdvdman_mmode = 0;
294static int g_cdvdman_last_cmdfunc = 0;
295static int g_cdvdman_minver_10700 = 0;
296static int g_cdvdman_minver_20200 = 0;
297static int g_cdvdman_minver_20400 = 0;
298static int g_cdvdman_minver_20800 = 0;
299static int g_cdvdman_emudvd9 = 0;
300static int g_cdvdman_minver_50000 = 0;
301static int g_cdvdman_minver_50200 = 0;
302static int g_cdvdman_minver_50400 = 0;
303static int g_cdvdman_minver_50600 = 0;
304static int g_cdvdman_minver_60000 = 0;
305static int g_cdvdman_minver_60200 = 0;
306#ifdef CDVD_VARIANT_OSD
307static int g_cdvdman_minver_60600 = 0;
308#endif
309#ifdef CDVD_VARIANT_XOSD
310static int g_cdvdman_vernotxxx1x = 0;
311#endif
312static int g_cdvdman_minver_x_model_15 = 0;
313#ifdef CDVD_VARIANT_XOSD
314static int g_cdvdman_debug_atapi_intr = 0;
315#endif
316static const char *g_masterdisc_header = "PlayStation Master Disc";
317static char g_cdvdman_ncmd = 0x06;
318static int g_cdvdman_chmedia = 0;
319static int g_cdvdman_chflags[4] = {1, 1, 1, 1};
320static int g_cdvdman_rtindex = 0;
321static int g_cdvdman_retries = 0;
322static u8 *g_cdvdman_ptoc;
323#ifdef CDVD_VARIANT_XOSD
324static int g_cdvdman_csys_evfid;
325#endif
326static int g_scmd_evfid;
327static void *g_cdvdman_temp_buffer_ptr;
328static int g_sfile_evfid;
329static int g_ncmd_evfid;
330#ifdef CDVD_VARIANT_OSD
331static s32 g_cdvdman_apply_scmd_sema;
332#endif
333static int g_fio_fsv_evfid;
334static int g_cdvdman_intr_evfid;
335#ifdef CDVD_VARIANT_XOSD
336static int (*g_cdvdman_atapi_eject_bs_power_callback)(int interrupt_nr, void *userdata);
337#endif
338static sceCdCBFunc g_cdvdman_user_cb;
339static void *g_cdvdman_power_off_callback_userdata;
340static void (*g_cdvdman_cdstm0cb)(int val);
341static sceCdCLOCK g_cdvdman_clock;
342static void (*g_cdvdman_power_off_callback)(void *userdata);
343#ifdef CDVD_VARIANT_XOSD
344static void *g_cdvdman_atapi_eject_bs_power_callback_userdata;
345#endif
346static void (*g_cdvdman_cdstm1cb)(int val);
347static int g_cdvdman_cmdfunc;
348static cdvdman_fhinfo_t g_cdvdman_fhinfo[16];
349static char g_cdvdman_sfname[1024];
350static cdvdman_filetbl_entry_t g_cdvdman_filetbl[64];
351static cdvdman_dirtbl_entry_t g_cdvdman_dirtbl[128];
352static int g_cdvdman_pathtblflag;
353static char g_cdvdman_fs_rbuf[0x800];
354static int g_cdvdman_readptr;
355static iop_sys_clock_t g_cdvdman_read_alarm_cb_timeout;
356static iop_sys_clock_t g_cdvdman_ncmd_timeout;
357static void *g_cdvdman_readbuf;
358static iop_sys_clock_t g_cdvdman_power_off_timeout;
359#ifdef CDVD_VARIANT_OSD
360static int g_cdvdman_config_numblocks;
361#endif
362static char g_cdvdman_fsvrbuf[42128];
363static cdvdman_internal_struct_t g_cdvdman_istruct;
364static const int g_cdvdman_cache_sector_count = 16;
365
366int _start(int ac, char **av)
367{
368 (void)ac;
369 (void)av;
370
371 if ( RegisterLibraryEntries(&_exp_cdvdman) )
372 {
373 return MODULE_NO_RESIDENT_END;
374 }
375 DelDrv(g_cdvdman_cddev.name);
376 if ( AddDrv(&g_cdvdman_cddev) )
377 {
378 cdrom_deinit(&g_cdvdman_cddev);
379 return MODULE_NO_RESIDENT_END;
380 }
381 g_cdvdman_ptoc = (u8 *)&g_cdvdman_fsvrbuf[0x924];
382 g_cdvdman_temp_buffer_ptr = g_cdvdman_fsvrbuf;
383 cdvdman_init();
384#if 0
385 SetRebootTimeLibraryHandlingMode(&_exp_cdvdman, 2);
386#else
387 // Call termination before disabling interrupts
388 _exp_cdvdman.mode &= ~6;
389 _exp_cdvdman.mode |= 2;
390#endif
391 return MODULE_RESIDENT_END;
392}
393
394void *sceGetFsvRbuf(void)
395{
396 return g_cdvdman_fsvrbuf;
397}
398
399static int cdrom_init(iop_device_t *dev)
400{
401 unsigned int i;
403#ifdef CDVD_VARIANT_OSD
404 iop_sema_t sema;
405#endif
406#ifdef CDVD_VARIANT_XOSD
407 USE_DEV5_MMIO_HWPORT();
408#endif
409 int scres_unused;
410
411 (void)dev;
412
413 PRINTF("cdvdman Init\n");
414 g_cdvdman_istruct.m_wait_flag = 1;
415 g_cdvdman_istruct.m_scmd_flag = 1;
416 g_cdvdman_istruct.m_read2_flag = 0;
417 g_cdvdman_istruct.m_stream_flag = 0;
418 g_cdvdman_istruct.m_last_error = SCECdErNO;
419 g_cdvdman_istruct.m_layer_1_lsn = 0;
420 g_cdvdman_istruct.m_use_toc = 0;
421 g_cdvdman_istruct.m_last_read_timeout = 0;
422 g_cdvdman_istruct.m_power_flag = 0;
423 g_cdvdman_istruct.m_current_dvd = 0;
424 g_cdvdman_istruct.m_dual_layer_emulation = 0;
425 g_cdvdman_istruct.m_dec_state = 0;
426 g_cdvdman_istruct.m_check_version = 0;
427 g_cdvdman_istruct.m_dec_shift = 0;
428 g_cdvdman_istruct.m_opo_or_para = -1;
429 g_cdvdman_istruct.m_no_dec_flag = 0;
430#ifdef CDVD_VARIANT_XOSD
431 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
432#endif
433 g_cdvdman_istruct.m_cd_inited = 0;
434#ifdef CDVD_VARIANT_XOSD
435 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = 0;
436 g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open = 1;
437#endif
438 g_cdvdman_istruct.m_tray_is_open = 0;
439 g_cdvdman_ee_rpc_fno = 0;
440 g_cdvdman_spinctl = -1;
441 event.attr = EA_MULTI;
442 event.bits = 0;
443 event.option = 0;
444 g_cdvdman_intr_evfid = CreateEventFlag(&event);
445 g_scmd_evfid = CreateEventFlag(&event);
446 g_ncmd_evfid = CreateEventFlag(&event);
447 g_sfile_evfid = CreateEventFlag(&event);
448 g_fio_fsv_evfid = CreateEventFlag(&event);
449#ifdef CDVD_VARIANT_XOSD
450 g_cdvdman_csys_evfid = CreateEventFlag(&event);
451#endif
452 ClearEventFlag(g_cdvdman_intr_evfid, ~0x4);
453 ClearEventFlag(g_cdvdman_intr_evfid, ~0x10);
454 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
455 SetEventFlag(g_ncmd_evfid, 1);
456 SetEventFlag(g_scmd_evfid, 1);
457 SetEventFlag(g_sfile_evfid, 1);
458 SetEventFlag(g_fio_fsv_evfid, 1);
459#ifdef CDVD_VARIANT_XOSD
460 SetEventFlag(g_cdvdman_csys_evfid, 1);
461#endif
462#ifdef CDVD_VARIANT_OSD
463 sema.attr = 1;
464 sema.initial = 1;
465 sema.max = 1;
466 sema.option = 0;
467 g_cdvdman_apply_scmd_sema = CreateSema(&sema);
468#endif
469 g_cdvdman_spinnom = -1;
470 g_cdvdman_trycnt = -1;
471 sceCdSC(0xFFFFFFF3, &scres_unused);
472 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
473 {
474 g_cdvdman_fhinfo[i].m_fd_flags = 0;
475 }
476#ifdef CDVD_VARIANT_XOSD
477 set_cdvd_dev5_base_addr_atapi(2);
478
479 for ( i = 0; i < 600 && !dev5_mmio_hwport->m_dev5_reg_015; i += 1 )
480 {
481 DelayThread(16000);
482 }
483 g_cdvdman_istruct.m_cd_mode_ps2_atapi =
484 (!(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) && !(dev5_mmio_hwport->m_dev5_reg_015 & 0x80)
485 && dev5_mmio_hwport->m_dev5_reg_00F != 6) ?
486 2 :
487 1;
488 KPRINTF("Mode %s Drive\n", g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1 ? "Atapi" : "PS2");
489 set_cdvd_dev5_base_addr_atapi(g_cdvdman_istruct.m_cd_mode_ps2_atapi);
490#endif
491 return 0;
492}
493
494void cdvdman_termcall(int with_stop)
495{
496 int i;
497 int oldstate;
498 USE_DEV5_MMIO_HWPORT();
499
500 VERBOSE_KPRINTF(1, "CDVD:library Terminate Call %d\n", with_stop);
501#ifdef CDVD_VARIANT_XOSD
502 if ( update_cd_mode_ps2_atapi() == 1 )
503 {
504 set_cdvd_dev5_base_addr_atapi(2);
505 }
506#endif
507 if ( with_stop )
508 {
509 return;
510 }
511 sceCdBreak();
512 sceCdSync(0);
513#ifndef CDVD_VARIANT_XOSD
514 if ( g_cdvdman_istruct.m_cd_inited )
515 {
516 cdvdman_ncmd_sender_06();
517 }
518#endif
519 for ( i = 0; i < 50000 && (dev5_mmio_hwport->m_dev5_reg_017 & 0x80); i += 1 )
520 {
521 DelayThread(100);
522 }
523 sceCdDecSet(0, 0, 0);
524 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
525 {
526 dev5_mmio_hwport->m_dev5_reg_007 = 1;
527 }
528 dmac_ch_set_chcr(3, 0);
529 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
530 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
531 DisableIntr(IOP_IRQ_CDVD, &oldstate);
532 ReleaseIntrHandler(IOP_IRQ_CDVD);
533}
534
535static int cdrom_deinit(iop_device_t *dev)
536{
537 unsigned int i;
538
539 (void)dev;
540
541 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
542 {
543 g_cdvdman_fhinfo[i].m_fd_flags = 0;
544 }
545 DeleteEventFlag(g_fio_fsv_evfid);
546 DeleteEventFlag(g_cdvdman_intr_evfid);
547 DeleteEventFlag(g_ncmd_evfid);
548 DeleteEventFlag(g_scmd_evfid);
549 DeleteEventFlag(g_sfile_evfid);
550#ifdef CDVD_VARIANT_XOSD
551 DeleteEventFlag(g_cdvdman_csys_evfid);
552#endif
553 return 0;
554}
555
556static int cdvdman_devready(void)
557{
558 int i;
559
560 for ( i = 0; i < 100; i += 1 )
561 {
562 // The following direct register access was replaced with call for ioprp300x
564 {
565 g_cdvdman_iocache = 0;
566 return -EIO;
567 }
568 // The following direct register access was replaced with call for ioprp300x
569 if ( (sceCdDiskReady(8) & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag && !g_cdvdman_ee_rpc_fno )
570 {
571 return 1;
572 }
573 DelayThread(10000);
574 }
575 return -EBUSY;
576}
577
578static int cdvdman_l0check(int layer)
579{
580 return !layer
581 && (g_cdvdman_istruct.m_dual_layer_emulation || g_cdvdman_istruct.m_opo_or_para == 1 || g_cdvdman_istruct.m_opo_or_para == 2);
582}
583
584static void cdvdman_iormode(sceCdRMode *rmode, int fmode, int layer)
585{
586 rmode->datapattern = SCECdSecS2048;
587 rmode->trycount = (g_cdvdman_trycnt == -1) ? 16 : g_cdvdman_trycnt;
588 if ( cdvdman_l0check(layer) )
589 {
590 if ( g_cdvdman_spinnom == -1 )
591 {
592 rmode->spindlctrl = (fmode == SCECdSpinX1 || fmode == SCECdSpinMx) ? fmode : SCECdSpinStm;
593 return;
594 }
595 if ( fmode != SCECdSpinX1 && fmode != SCECdSpinMx )
596 {
597 rmode->spindlctrl = SCECdSpinStm;
598 return;
599 }
600 rmode->spindlctrl = (u8)g_cdvdman_spinnom;
601 }
602 else if ( g_cdvdman_spinnom == -1 )
603 {
604 switch ( fmode )
605 {
606 case SCECdSpinStm:
607 rmode->spindlctrl = SCECdSpinStm;
608 break;
609 case SCECdSpinNom:
610 rmode->spindlctrl = SCECdSpinNom;
611 break;
612 case SCECdSpinX1:
613 rmode->spindlctrl = SCECdSpinX1;
614 break;
615 case SCECdSpinX2:
616 rmode->spindlctrl = SCECdSpinX2;
617 break;
618 case SCECdSpinX4:
619 rmode->spindlctrl = SCECdSpinX4;
620 break;
621 case SCECdSpinX12:
622 rmode->spindlctrl = SCECdSpinX12;
623 break;
624 case SCECdSpinMx:
625 rmode->spindlctrl = SCECdSpinMx;
626 break;
627 default:
628 rmode->spindlctrl = SCECdSpinNom;
629 break;
630 }
631 }
632}
633
634static int cdrom_dopen(iop_file_t *f, const char *dirname)
635{
636 unsigned int i;
637 int is_devready;
638 size_t path_name_ind;
639 int file_lsn_tmp;
640 char path_name[128];
641 u32 efbits;
642
643 VERBOSE_PRINTF(1, "fileIO DOPEN name= %s layer %d\n", dirname, f->unit);
644 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
645 for ( i = 0; (i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0]))) && g_cdvdman_fhinfo[i].m_fd_flags;
646 i += 1 )
647 {
648 }
649 if ( i == (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])) )
650 {
651 SetEventFlag(g_fio_fsv_evfid, 1);
652 return -EMFILE;
653 }
654 f->privdata = (void *)i;
655 is_devready = cdvdman_devready();
656 if ( is_devready < 0 )
657 {
658 SetEventFlag(g_fio_fsv_evfid, 1);
659 return is_devready;
660 }
661 strncpy(path_name, dirname, sizeof(path_name));
662 if ( !strcmp(path_name, ".") )
663 {
664 strcpy(path_name, "\\.");
665 }
666 path_name_ind = strlen(path_name);
667 path_name_ind -= (path_name_ind >= 2) ? 2 : 0;
668 if ( strcmp(&path_name[path_name_ind], "\\.") )
669 {
670 strcat(path_name, "\\.");
671 }
672 if ( (unsigned int)(f->unit) >= 2 )
673 {
674 PRINTF("open fail name %s\n", path_name);
675 SetEventFlag(g_fio_fsv_evfid, 1);
676 return -ENOENT;
677 }
678 g_cdvdman_fhinfo[i].m_file_lsn = 0;
679 g_cdvdman_srchspd = 0;
680 file_lsn_tmp = sceCdSearchDir(path_name, f->unit);
681 if ( file_lsn_tmp < 0 )
682 {
683 PRINTF("open fail directory %s\n", path_name);
684 SetEventFlag(g_fio_fsv_evfid, 1);
685 return -ENOENT;
686 }
687 g_cdvdman_fhinfo[i].m_file_lsn = file_lsn_tmp;
688 g_cdvdman_fhinfo[i].m_read_pos = 0;
689 g_cdvdman_fhinfo[i].m_filemode = 0;
690 g_cdvdman_fhinfo[i].m_fd_flags = 1;
691 g_cdvdman_fhinfo[i].m_fd_layer = f->unit;
692 SetEventFlag(g_fio_fsv_evfid, 1);
693 return 0;
694}
695
696static void cdvdman_fillstat(void *dummy, iox_stat_t *buf, cdvdman_filetbl_entry_t *fp)
697{
698 unsigned int i;
699
700 (void)dummy;
701
702 buf->attr = 0;
703 buf->private_5 = 0;
704 buf->private_4 = 0;
705 buf->private_3 = 0;
706 buf->private_2 = 0;
707 buf->private_1 = 0;
708 buf->private_0 = 0;
709 buf->hisize = 0;
710 for ( i = 0; i < (sizeof(buf->mtime) / sizeof(buf->mtime[0])); i += 1 )
711 {
712 buf->mtime[i] = fp->m_file_struct.date[i];
713 buf->atime[i] = fp->m_file_struct.date[i];
714 buf->ctime[i] = fp->m_file_struct.date[i];
715 }
716 buf->size = fp->m_file_struct.size;
717 buf->mode = (((fp->m_flags & 2)) ? (FIO_S_IFDIR | FIO_S_IXUSR | FIO_S_IXGRP | FIO_S_IXOTH) : FIO_S_IFREG)
719}
720
721static int cdvdman_cdfname(char *filename)
722{
723 size_t filename_len;
724
725 filename_len = strlen(filename);
726 if ( filename_len >= 3 && !(filename[filename_len - 2] != ';' && filename[filename_len - 1] != '1') )
727 {
728 return 0;
729 }
730 strcat(filename, ";1");
731 return 1;
732}
733
734static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf)
735{
736 int devready_tmp;
737 cdvdman_filetbl_entry_t fp;
738 char filename[128];
739 u32 efbits;
740
741 VERBOSE_PRINTF(1, "fileIO GETSTAT name= %s layer= %d\n", name, f->unit);
742 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
743 devready_tmp = cdvdman_devready();
744 if ( devready_tmp < 0 )
745 {
746 SetEventFlag(g_fio_fsv_evfid, 1);
747 return devready_tmp;
748 }
749 strncpy(filename, name, sizeof(filename));
750 if ( !strcmp(filename, ".") )
751 {
752 strcpy(filename, "\\.");
753 }
754 if ( !strcmp(filename, "\\") )
755 {
756 strcpy(filename, "\\.");
757 }
758 if ( !strlen(filename) )
759 {
760 strcpy(filename, "\\.");
761 }
762 g_cdvdman_srchspd = 0;
763 // Unofficial: initialize to 0
764 memset(&fp, 0, sizeof(fp));
765 if (
766 !sceCdLayerSearchFile(&fp.m_file_struct, filename, f->unit)
767 && !(cdvdman_cdfname(filename) && sceCdLayerSearchFile(&fp.m_file_struct, filename, f->unit)) )
768 {
769 PRINTF("open fail name %s\n", name);
770 SetEventFlag(g_fio_fsv_evfid, 1);
771 return -ENOENT;
772 }
773 cdvdman_fillstat(filename, buf, &fp);
774 SetEventFlag(g_fio_fsv_evfid, 1);
775 return 1;
776}
777
778// cppcheck-suppress constParameterCallback
779static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf)
780{
781 int devready_tmp;
782 cdvdman_fhinfo_t *fh;
783 cdvdman_filetbl_entry_t fp;
784 u32 efbits;
785
786 memset(&fp, 0, sizeof(fp));
787 VERBOSE_PRINTF(1, "fileIO DREAD\n");
788 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
789 devready_tmp = cdvdman_devready();
790 if ( devready_tmp < 0 )
791 {
792 SetEventFlag(g_fio_fsv_evfid, 1);
793 return devready_tmp;
794 }
795 fh = &g_cdvdman_fhinfo[(int)f->privdata];
796 g_cdvdman_srchspd = 0;
797 devready_tmp = sceCdReadDir(&fp.m_file_struct, fh->m_file_lsn, fh->m_read_pos, fh->m_fd_layer);
798 if ( devready_tmp < 0 )
799 {
800 SetEventFlag(g_fio_fsv_evfid, 1);
801 return -ENOENT;
802 }
803 if ( devready_tmp )
804 {
805 fh->m_read_pos += 1;
806 devready_tmp = strlen(fp.m_file_struct.name);
807 }
808 strncpy(buf->name, fp.m_file_struct.name, sizeof(buf->name));
809 cdvdman_fillstat(fp.m_file_struct.name, &buf->stat, &fp);
810 SetEventFlag(g_fio_fsv_evfid, 1);
811 return devready_tmp;
812}
813
814static int cdvd_odcinit(cdvdman_fhinfo_t *fh, int open_or_close, int id)
815{
816 int cache_remove_result;
817 int cache_result;
818 int cache_file_fd_new;
819 u32 file_size_bsr_3;
820 unsigned int file_size_bsr_17;
821 char cache_filename[512];
822 int state;
823 unsigned int ioctl_arg;
824
825 g_cdvdman_iocache = 0;
826 sprintf(
827 cache_filename,
828 "%sCache_%d_%d_%d_%d",
829 g_cdvdman_cache_name,
830 fh->m_fd_layer,
831 (int)fh->m_file_lsn,
832 (int)fh->m_file_size,
833 id);
834 cache_remove_result = 0;
835 VERBOSE_KPRINTF(1, "Cachefile:%s Open_or_Close:%d\n", cache_filename, open_or_close);
836 cache_result = 0;
837 if ( open_or_close )
838 {
839 u32 i;
840
841 CpuSuspendIntr(&state);
842 fh->m_fd_rbsize = g_cdvdman_cache_sector_size_count ? (g_cdvdman_cache_sector_size_count << 11) : 0x800;
843 fh->m_fd_rcvbuf = (u8 *)AllocSysMemory(ALLOC_LAST, fh->m_fd_rbsize, 0);
844 if ( !fh->m_fd_rcvbuf )
845 {
846 VERBOSE_KPRINTF(1, "Rcvbuf MemAlloc Fail\n");
847 CpuResumeIntr(state);
848 return -ENOMEM;
849 }
850 CpuResumeIntr(state);
851 fh->m_cache_file_fd = -1;
852 cache_result = open(cache_filename, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
853 cache_file_fd_new = cache_result;
854 if ( cache_result >= 0 )
855 {
856 u32 file_size_sectors;
857 unsigned int file_size_bsr_6;
858
859 file_size_sectors = (fh->m_file_size >> 11) + ((!!((fh->m_file_size & 0x7FF))));
860 file_size_bsr_3 = (file_size_sectors >> 3) + (!!(file_size_sectors & 7));
861 file_size_bsr_6 = (file_size_bsr_3 >> 3) + (!!((file_size_bsr_3 & 7)));
862 file_size_bsr_17 = (file_size_bsr_6 >> 11) + (!!((file_size_bsr_6 & 0x7FF)));
863 ioctl_arg = (file_size_bsr_17 + file_size_sectors + 8) << 11;
864 for ( i = 0; i < fh->m_fd_rbsize; i += 1 )
865 {
866 fh->m_fd_rcvbuf[i] = 0;
867 }
868 if ( !strncmp(cache_filename, "pfs", 3) )
869 {
870 cache_result = ioctl2(cache_file_fd_new, PIOCALLOC, &ioctl_arg, 4, 0, 0);
871 }
872 }
873 if ( cache_result >= 0 )
874 {
875 cache_result = lseek(cache_file_fd_new, 0, 0);
876 }
877 if ( cache_result >= 0 )
878 {
879 if ( !g_cdvdman_cache_sector_count )
880 __builtin_trap();
881 for ( i = 0; (int)i < (int)(g_cdvdman_cache_sector_count << 11); i += 1 )
882 {
883 ((char *)g_cdvdman_temp_buffer_ptr)[i] = 0;
884 }
885 for ( i = 0; (int)i < (int)((ioctl_arg >> 11) / g_cdvdman_cache_sector_count); i += 1 )
886 {
887 cache_result = write(cache_file_fd_new, g_cdvdman_temp_buffer_ptr, g_cdvdman_cache_sector_count << 11);
888 if ( cache_result != (g_cdvdman_cache_sector_count << 11) )
889 {
890 if ( cache_result >= 0 )
891 {
892 cache_result = -EIO;
893 }
894 break;
895 }
896 }
897 }
898 if ( cache_result >= 0 )
899 {
900 for ( i = 0; (int)i < (int)((ioctl_arg >> 11)
901 - g_cdvdman_cache_sector_count * ((ioctl_arg >> 11) / g_cdvdman_cache_sector_count));
902 i += 1 )
903 {
904 cache_result = write(cache_file_fd_new, fh->m_fd_rcvbuf, 0x800);
905 if ( cache_result != 0x800 )
906 {
907 if ( cache_result >= 0 )
908 {
909 cache_result = -EIO;
910 }
911 break;
912 }
913 }
914 }
915 }
916 if ( !open_or_close || cache_result < 0 )
917 {
918 if ( fh->m_cache_file_fd != -1 )
919 {
920 cache_remove_result = close(fh->m_cache_file_fd);
921 VERBOSE_KPRINTF(1, "Cache File Close: %d\n", cache_remove_result);
922 if ( cache_remove_result >= 0 )
923 {
924 if ( !strncmp(cache_filename, "pfs", 3) )
925 {
926 cache_remove_result = remove(cache_filename);
927 }
928 else if ( !strncmp(cache_filename, "host", 4) )
929 {
930 cache_remove_result = 0;
931 remove(cache_filename);
932 }
933 VERBOSE_KPRINTF(1, "Cache File %s remove: %d\n", cache_filename, cache_remove_result);
934 }
935 }
936 fh->m_cache_file_fd = -1;
937 fh->m_max_cluster = 0;
938 fh->m_cluster_cur = -1;
939 fh->m_sector_count_total = 0;
940 CpuSuspendIntr(&state);
941 FreeSysMemory(fh->m_fd_rcvbuf);
942 CpuResumeIntr(state);
943 fh->m_fd_rcvbuf = 0;
944 if ( cache_result < 0 )
945 {
946 VERBOSE_KPRINTF(1, "cdvd_odcinit Open Error %d\n", cache_result);
947 }
948 if ( cache_remove_result < 0 )
949 {
950 VERBOSE_KPRINTF(1, "cdvd_odcinit Close Error %d\n", cache_remove_result);
951 }
952 return (!open_or_close) ? cache_remove_result : cache_result;
953 }
954 fh->m_sector_count_total = file_size_bsr_17 << 11;
955 fh->m_cache_file_fd = cache_file_fd_new;
956 fh->m_max_cluster = (void *)file_size_bsr_3;
957 fh->m_cluster_cur = -1;
958 VERBOSE_KPRINTF(1, "Cache File Maked\n");
959 return 0;
960}
961
962static int cdvdman_cache_invalidate(cdvdman_fhinfo_t *fh, int index)
963{
964 u32 i;
965 int fileio_res;
966
967 if ( fh->m_cluster_cur == -1 )
968 {
969 return 0;
970 }
971 fh->m_cluster_cur = -1;
972 for ( i = 0; i < fh->m_fd_rbsize; i += 1 )
973 {
974 fh->m_fd_rcvbuf[i] = 0;
975 }
976 fileio_res = lseek(fh->m_cache_file_fd, 0, 0);
977 if ( fileio_res >= 0 )
978 {
979 for ( i = 0; i < ((unsigned int)fh->m_sector_count_total >> 11); i += 1 )
980 {
981 fileio_res = write(fh->m_cache_file_fd, fh->m_fd_rcvbuf, 0x800);
982 if ( fileio_res < 0 )
983 {
984 break;
985 }
986 }
987 }
988 if ( fileio_res >= 0 )
989 {
990 return fileio_res;
991 }
992 fh->m_fd_flags &= ~4;
993 cdvd_odcinit(fh, 0, index);
994 return fileio_res;
995}
996
997static int cdvdman_invcaches(void)
998{
999 unsigned int i;
1000
1001 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1002 {
1003 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 4) )
1004 {
1005 cdvdman_cache_invalidate(&g_cdvdman_fhinfo[i], i);
1006 }
1007 }
1008 return 0;
1009}
1010
1011static int cdrom_internal_cache_read(const iop_file_t *f, int nbytes)
1012{
1013 cdvdman_fhinfo_t *fh;
1014 s16 readpos_plus_nbytes;
1015 unsigned int readpos_plus_nbytes_bsr_14;
1016 int readpos_bsr_14;
1017 int cluster_cur;
1018 unsigned int i;
1019
1020 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1021 if ( cdvdman_devready() < 0 )
1022 {
1023 g_cdvdman_iocache = 0;
1024 return -EBUSY;
1025 }
1026 if ( fh->m_cluster_cur == -1 )
1027 {
1028 if ( (void *)(8 * fh->m_fd_rbsize) < fh->m_max_cluster )
1029 {
1030 fh->m_cluster_cur = (fh->m_read_pos >> 14) & ~0x7;
1031 if (
1032 lseek(fh->m_cache_file_fd, fh->m_cluster_cur >> 3, 0) < 0
1033 || read(fh->m_cache_file_fd, fh->m_fd_rcvbuf, fh->m_fd_rbsize) < 0 )
1034 {
1035 fh->m_cluster_cur = -1;
1036 return -EIO;
1037 }
1038 }
1039 else
1040 {
1041 fh->m_cluster_cur = -2;
1042 }
1043 }
1044 readpos_plus_nbytes = fh->m_read_pos + nbytes;
1045 readpos_plus_nbytes_bsr_14 = (readpos_plus_nbytes >> 14) - (!(readpos_plus_nbytes & 0x3FFF));
1046 readpos_bsr_14 = fh->m_read_pos >> 14;
1047 VERBOSE_KPRINTF(
1048 1, "max_claster %d meta_size_clst %d claster_cur %d\n", fh->m_max_cluster, 8 * fh->m_fd_rbsize, fh->m_cluster_cur);
1049 cluster_cur = fh->m_cluster_cur;
1050 if ( cluster_cur < 0 )
1051 {
1052 cluster_cur = 0;
1053 }
1054 else if (
1055 (unsigned int)readpos_bsr_14 < (unsigned int)cluster_cur
1056 || readpos_plus_nbytes_bsr_14 >= cluster_cur + 8 * fh->m_fd_rbsize )
1057 {
1058 int cluster_write_tmp2;
1059 unsigned int readpos_band;
1060
1061 if ( lseek(fh->m_cache_file_fd, cluster_cur >> 3, 0) < 0 )
1062 {
1063 fh->m_cluster_cur = -1;
1064 return -EIO;
1065 }
1066 cluster_write_tmp2 = (unsigned int)fh->m_max_cluster >= fh->m_cluster_cur + 8 * fh->m_fd_rbsize ?
1067 fh->m_fd_rbsize :
1068 ((unsigned int)fh->m_max_cluster - fh->m_cluster_cur + 7) >> 3;
1069 if ( write(fh->m_cache_file_fd, fh->m_fd_rcvbuf, cluster_write_tmp2) != cluster_write_tmp2 )
1070 {
1071 fh->m_cluster_cur = -1;
1072 return -EIO;
1073 }
1074 readpos_band = readpos_bsr_14 & ~0x7;
1075 fh->m_cluster_cur = readpos_band;
1076 readpos_band += (readpos_bsr_14 < 0) ? 7 : 0;
1077 if ( (lseek(fh->m_cache_file_fd, readpos_band >> 3, 0) < 0) || (read(fh->m_cache_file_fd, fh->m_fd_rcvbuf, ( (unsigned int)fh->m_max_cluster < fh->m_cluster_cur + 8 * fh->m_fd_rbsize ) ? (((unsigned int)fh->m_max_cluster - fh->m_cluster_cur + 7) >> 3) : (fh->m_fd_rbsize)) < 0) )
1078 {
1079 fh->m_cluster_cur = -1;
1080 return -EIO;
1081 }
1082 cluster_cur = fh->m_cluster_cur;
1083 }
1084 for ( i = readpos_bsr_14; i <= readpos_plus_nbytes_bsr_14; i += 1 )
1085 {
1086 if ( !(((int)fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] >> ((i - cluster_cur) & 7)) & 1) )
1087 {
1088 break;
1089 }
1090 }
1091 return i <= readpos_plus_nbytes_bsr_14;
1092}
1093
1094static int cdrom_internal_write_cache(const iop_file_t *f, unsigned int nbytes)
1095{
1096 int lseek_result;
1097 cdvdman_fhinfo_t *fh;
1098 unsigned int cur;
1099 unsigned int rst;
1100 int cluster_cur;
1101 int write_ret;
1102 unsigned int i;
1103 int tray_open;
1104 int last_err;
1105 sceCdRMode rmode;
1106
1107 g_cdvdman_iocache = 0;
1108 if ( cdvdman_devready() < 0 )
1109 {
1110 return -EBUSY;
1111 }
1112 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1113 if ( nbytes > fh->m_file_size - fh->m_read_pos )
1114 {
1115 nbytes = fh->m_file_size - fh->m_read_pos;
1116 }
1117 if ( !nbytes )
1118 {
1119 return 0;
1120 }
1121 VERBOSE_KPRINTF(1, "_cdvdfile_cache_read %d<->%d\n", fh->m_read_pos, fh->m_read_pos + nbytes);
1122 cur = ((fh->m_read_pos + nbytes) >> 14) - (!((fh->m_read_pos + nbytes) & 0x3FFF));
1123 rst = fh->m_read_pos >> 14;
1124 cluster_cur = (fh->m_cluster_cur >= 0) ? fh->m_cluster_cur : 0;
1125 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1126 write_ret = 0;
1127 VERBOSE_KPRINTF(1, "cache_fill rst:%d<->%d cur:%d cnt:%d\n", rst, cur, fh->m_read_pos, nbytes);
1128 for ( i = rst; i <= cur; i += 1 )
1129 {
1130 VERBOSE_KPRINTF(
1131 1,
1132 "FIO Usr addr LSN:%d SEC:%d ADDR:%08x cpos= %d\n",
1133 fh->m_file_lsn + 8 * i,
1134 8,
1135 g_cdvdman_temp_buffer_ptr,
1136 (i * 0x4000) + fh->m_sector_count_total);
1137 if ( !(((int)fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] >> ((i - cluster_cur) & 7)) & 1) )
1138 {
1139 tray_open = 0;
1140 while ( !sceCdRE(fh->m_file_lsn + 8 * i, 8, g_cdvdman_temp_buffer_ptr, &rmode) )
1141 {
1142 if ( (sceCdStatus() & SCECdStatShellOpen) )
1143 {
1144 g_cdvdman_iocache = 0;
1145 tray_open = 1;
1146 break;
1147 }
1148 DelayThread(10000);
1149 }
1150 sceCdSync(0);
1151 last_err = sceCdGetError();
1152 if ( last_err != SCECdErNO || tray_open )
1153 {
1154 // The following Kprintf was modified for ioprp300x
1155 VERBOSE_KPRINTF(0, "Read Error= 0x%02x Tray open %d\n", last_err, tray_open);
1156 return -ECOMM;
1157 }
1158 lseek_result = lseek(fh->m_cache_file_fd, (i * 0x4000) + fh->m_sector_count_total, 0);
1159 if ( lseek_result < 0 )
1160 {
1161 return lseek_result;
1162 }
1163 write_ret = write(fh->m_cache_file_fd, g_cdvdman_temp_buffer_ptr, 0x4000);
1164 if ( write_ret != 0x4000 )
1165 {
1166 VERBOSE_KPRINTF(1, "write: ret:%d\n", write_ret);
1167 if ( write_ret >= 0 )
1168 {
1169 return -EIO;
1170 }
1171 break;
1172 }
1173 fh->m_fd_rcvbuf[(i - cluster_cur) >> 3] |= 1 << ((i - cluster_cur) & 7);
1174 }
1175 }
1176 return write_ret;
1177}
1178
1179static int cdvdfile_cache_read(const iop_file_t *f, void *buf, int nbyte)
1180{
1181 int nbyte_tmp;
1182 int fd_result;
1183 cdvdman_fhinfo_t *fh;
1184
1185 if ( nbyte < 0 )
1186 {
1187 return -EINVAL;
1188 }
1189 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1190 nbyte_tmp =
1191 ((unsigned int)nbyte > fh->m_file_size - fh->m_read_pos) ? fh->m_file_size - fh->m_read_pos : (unsigned int)nbyte;
1192 VERBOSE_KPRINTF(1, "_cdvdfile_cache_read %d<->%d\n", fh->m_read_pos, fh->m_read_pos + nbyte_tmp);
1193 fd_result = 0;
1194 if ( nbyte_tmp > 0 )
1195 {
1196 fd_result = lseek(fh->m_cache_file_fd, fh->m_read_pos + fh->m_sector_count_total, 0);
1197 if ( fd_result >= 0 )
1198 {
1199 fd_result = read(fh->m_cache_file_fd, buf, nbyte_tmp);
1200 fh->m_read_pos += (fd_result >= 0) ? fd_result : 0;
1201 }
1202 }
1203 return fd_result;
1204}
1205
1206static int cdvdfile_cache_fill_read(const iop_file_t *f, void *buf, int nbytes)
1207{
1208 int op_result;
1209
1210 op_result = cdvdman_devready();
1211 if ( op_result >= 0 )
1212 {
1213 op_result = cdrom_internal_write_cache(f, nbytes);
1214 }
1215 else
1216 {
1217 g_cdvdman_iocache = 0;
1218 }
1219 if ( op_result >= 0 )
1220 {
1221 op_result = cdvdfile_cache_read(f, buf, nbytes);
1222 }
1223 return op_result;
1224}
1225
1226static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4)
1227{
1228 int fds1;
1229 unsigned int i;
1230 int emptyfdfound;
1231 int streamfdfound;
1232 cdvdman_fhinfo_t *fh;
1233 int devready_tmp;
1234 char filename[128];
1235 sceCdlFILE fp;
1236 u32 efbits;
1237
1238 (void)arg4;
1239 devready_tmp = 0;
1240 fds1 = 0;
1241 VERBOSE_PRINTF(1, "fileIO OPEN name= %s mode= 0x%08x layer %d\n", name, mode, f->unit);
1242 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1243 emptyfdfound = 0;
1244 streamfdfound = 0;
1245 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1246 {
1247 if ( !g_cdvdman_fhinfo[i].m_fd_flags && !emptyfdfound )
1248 {
1249 fds1 = i;
1250 emptyfdfound = 1;
1251 }
1252 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 8) )
1253 {
1254 streamfdfound = 1;
1255 }
1256 }
1257 if ( !emptyfdfound || streamfdfound )
1258 {
1259 PRINTF("open fail name %s\n", name);
1260 SetEventFlag(g_fio_fsv_evfid, 1);
1261 return -EMFILE;
1262 }
1263 f->privdata = (void *)fds1;
1264 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1265 strncpy(filename, name, sizeof(filename));
1266 cdvdman_cdfname(filename);
1267 g_cdvdman_srchspd = (!(mode & 0x40000000) && !cdvdman_l0check(f->unit)) ?
1268 ((g_cdvdman_spinnom == -1) ? (u16)mode : g_cdvdman_spinnom != SCECdSpinStm) :
1269 0;
1270 if ( (unsigned int)(f->unit) >= 2u )
1271 {
1272 devready_tmp = -ENOENT;
1273 }
1274 else
1275 {
1276 if ( !strncmp(name, "sce_cdvd_lsn", 12) )
1277 {
1278 strncpy(filename, name, sizeof(filename));
1279 // Unofficial: Avoid out of bounds access
1280 for ( i = 12; i < (sizeof(filename) - 5) && filename[i] && filename[i] != '_'; i += 1 )
1281 ;
1282 if ( !filename[i] || i >= (sizeof(filename) - 5) )
1283 {
1284 devready_tmp = -ENOENT;
1285 }
1286 else
1287 {
1288 fp.size = strtol(&filename[i + 5], 0, 10);
1289 filename[i] = 0;
1290 fp.lsn = strtol(&filename[12], 0, 10);
1291 if ( f->unit )
1292 {
1293 if ( cdvdman_devready() < 0 || !DvdDual_infochk() )
1294 {
1295 devready_tmp = -ENOENT;
1296 }
1297 else
1298 {
1299 fp.lsn += g_cdvdman_istruct.m_layer_1_lsn;
1300 }
1301 }
1302 }
1303 }
1304#ifdef CDVD_VARIANT_OSD
1305 else if ( !strcmp(filename, "sce_dev5;1") )
1306 {
1307 fp.lsn = -1;
1308 fp.size = 0;
1309 }
1310#endif
1311 else
1312 {
1313 devready_tmp = cdvdman_devready();
1314 if ( devready_tmp < 0 )
1315 {
1316 SetEventFlag(g_fio_fsv_evfid, 1);
1317 return devready_tmp;
1318 }
1319 if ( !sceCdLayerSearchFile(&fp, filename, f->unit) )
1320 {
1321 devready_tmp = -ENOENT;
1322 }
1323 }
1324 }
1325 if ( devready_tmp < 0 )
1326 {
1327 PRINTF("open fail name %s\n", filename);
1328 SetEventFlag(g_fio_fsv_evfid, 1);
1329 return devready_tmp;
1330 }
1331 fh->m_fd_flags = 1;
1332 g_cdvdman_srchspd = 0;
1333 if ( (mode & 0x40000000) )
1334 {
1335 sceCdRMode rmode;
1336 memset(&rmode, 0, sizeof(rmode));
1337 rmode.datapattern = SCECdSecS2048;
1338 rmode.spindlctrl = SCECdSpinStm;
1339 rmode.trycount = (g_cdvdman_trycnt != -1) ? g_cdvdman_trycnt : 0;
1340 // The following call to sceCdStStart was inlined
1341 if ( !sceCdStStart(fp.lsn, &rmode) )
1342 {
1343 fh->m_fd_flags = 0;
1344 SetEventFlag(g_fio_fsv_evfid, 1);
1345 return -ENOENT;
1346 }
1347 g_cdvdman_strmerr = 0;
1348 fh->m_fd_flags |= 8;
1349 }
1350 fh->m_file_lsn = fp.lsn;
1351 fh->m_read_pos = 0;
1352 fh->m_filemode = mode & ~0x40000000;
1353 fh->m_file_size = fp.size;
1354 fh->m_fd_layer = f->unit;
1355 if ( (mode & 0x50000000) == 0x10000000 )
1356 {
1357 devready_tmp = -ENODEV;
1358 if ( g_cache_path_fd != -1 )
1359 {
1360 devready_tmp = cdvd_odcinit(fh, 1, (int)f->privdata);
1361 if ( devready_tmp >= 0 )
1362 {
1363 fh->m_fd_flags |= 4;
1364 }
1365 }
1366 }
1367 if ( devready_tmp < 0 )
1368 {
1369 fh->m_fd_flags = 0;
1370 fh->m_fd_layer = 0;
1371 fh->m_filemode = 0;
1372 fh->m_read_pos = 0;
1373 fh->m_file_size = 0;
1374 fh->m_file_lsn = 0;
1375 SetEventFlag(g_fio_fsv_evfid, 1);
1376 return devready_tmp;
1377 }
1378 f->mode = O_RDONLY;
1379 // The following Kprintf was added for ioprp300x
1380 VERBOSE_KPRINTF(1, "open end file_lbn= %d size= %d fds= %d\n", fh->m_file_lsn, fh->m_file_size, fds1);
1381 SetEventFlag(g_fio_fsv_evfid, 1);
1382 return 0;
1383}
1384
1385static int cdrom_close(iop_file_t *f)
1386{
1387 cdvdman_fhinfo_t *fh;
1388 u32 efbits;
1389
1390 VERBOSE_PRINTF(1, "fileIO CLOSE\n");
1391 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1392 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1393 if ( (fh->m_fd_flags & 8) )
1394 {
1395 g_cdvdman_strmerr = 0;
1396 // The following call to sceCdStStop was inlined
1397 if ( !sceCdStStop() )
1398 {
1399 SetEventFlag(g_fio_fsv_evfid, 1);
1400 return -EIO;
1401 }
1402 }
1403 if ( ((fh->m_fd_flags & 0xC) == 4 && cdvd_odcinit(fh, 0, (int)f->privdata) < 0) )
1404 {
1405 SetEventFlag(g_fio_fsv_evfid, 1);
1406 return -EIO;
1407 }
1408 fh->m_file_lsn = 0;
1409 fh->m_file_size = 0;
1410 fh->m_read_pos = 0;
1411 fh->m_fd_flags = 0;
1412 fh->m_fd_layer = 0;
1413 fh->m_filemode = 1;
1414 f->mode = 0;
1415 SetEventFlag(g_fio_fsv_evfid, 1);
1416 return 0;
1417}
1418
1419static int cdrom_internal_read(const iop_file_t *f, char *addr, int nbytes)
1420{
1421 unsigned int sectors;
1422 int op_result;
1423 int nbytes_segment;
1424 int nbytes_div_2048;
1425 unsigned int sec;
1426 unsigned int sectors_count;
1427 int last_err;
1428 sceCdRMode rmode;
1429 int i;
1430 unsigned int filesize_bsr_11;
1431 cdvdman_fhinfo_t *fh;
1432 void *buf;
1433
1434 sectors = 1;
1435 VERBOSE_PRINTF(1, "cdvd fileIO read start\n");
1436 op_result = cdvdman_devready();
1437 if ( op_result < 0 )
1438 {
1439 g_cdvdman_iocache = 0;
1440 return op_result;
1441 }
1442 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1443 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1444 if ( nbytes < 0 )
1445 {
1446 return -EINVAL;
1447 }
1448 if ( (unsigned int)nbytes > fh->m_file_size - fh->m_read_pos )
1449 {
1450 nbytes = fh->m_file_size - fh->m_read_pos;
1451 }
1452 filesize_bsr_11 = (fh->m_file_size >> 11) + (!!((fh->m_file_size & 0x7FF))) + fh->m_file_lsn;
1453 VERBOSE_PRINTF(
1454 1, "fds= %d read file_lbn= %d offset= %d\n", (int)(uiptr)f->privdata, (int)fh->m_file_lsn, (int)fh->m_read_pos);
1455 buf = 0;
1456 for ( i = 0; i < nbytes; i += nbytes_segment )
1457 {
1458 unsigned int lbn;
1459 int pos_extra;
1460 int lbn_tmp;
1461 int pos_sub_2048;
1462 int nbytes_cur;
1463
1464 nbytes_cur = nbytes - i;
1465 if ( g_cdvdman_spinctl != -1 )
1466 {
1467 rmode.spindlctrl = g_cdvdman_spinctl;
1468 switch ( g_cdvdman_spinctl )
1469 {
1470 case SCECdSpinStm:
1471 fh->m_filemode = 0;
1472 break;
1473 case SCECdSpinNom:
1474 fh->m_filemode = 1;
1475 break;
1476 case SCECdSpinX1:
1477 fh->m_filemode = 2;
1478 break;
1479 case SCECdSpinX2:
1480 fh->m_filemode = 3;
1481 break;
1482 case SCECdSpinX4:
1483 fh->m_filemode = 4;
1484 break;
1485 case SCECdSpinX12:
1486 fh->m_filemode = 5;
1487 break;
1488 default:
1489 fh->m_filemode = 1;
1490 break;
1491 }
1492 }
1493 pos_sub_2048 = 0;
1494 lbn = fh->m_file_lsn + ((fh->m_read_pos + i) >> 11);
1495 lbn_tmp = lbn;
1496 pos_extra = (fh->m_read_pos + i) & 0x7FF;
1497 if ( nbytes_cur <= 0x4000 )
1498 {
1499 nbytes_segment = nbytes_cur;
1500 nbytes_div_2048 = (nbytes_cur / 0x800) + (!!((nbytes_cur & 0x7FF)));
1501 sectors = nbytes_div_2048 + (!!pos_extra);
1502 }
1503 else
1504 {
1505 nbytes_segment = 0x4000;
1506 if ( buf && ((fh->m_read_pos + i) & 0x7FF) && g_cdvdman_iocache )
1507 {
1508 lbn += 1;
1509 pos_sub_2048 = 0x800 - pos_extra;
1510 optimized_memcpy(
1511 &addr[i], &((const char *)g_cdvdman_temp_buffer_ptr)[0x800 * (sectors - 1) + pos_extra], 0x800 - pos_extra);
1512 g_cdvdman_iocache = 0;
1513 sectors = 8;
1514 }
1515 else
1516 {
1517 sectors = 8 + (!!(((fh->m_read_pos + i) & 0x7FF)));
1518 }
1519 }
1520 buf = g_cdvdman_temp_buffer_ptr;
1521 if ( (unsigned int)(sectors) > filesize_bsr_11 - lbn )
1522 {
1523 sectors = filesize_bsr_11 - lbn;
1524 }
1525 VERBOSE_PRINTF(1, "sce_Read LBN= %d sectors= %d\n", (int)lbn, (int)sectors);
1526 if (
1527 g_cdvdman_iocache && (lbn >= g_cdvdman_lcn_offset)
1528 && (g_cdvdman_lcn_offset + g_cdvdman_numbytes_offset >= lbn + sectors) )
1529 {
1530 optimized_memcpy(&addr[i], &((char *)buf)[0x800 * (lbn - g_cdvdman_lcn_offset) + pos_extra], nbytes_segment);
1531 }
1532 else if ( ((uiptr)(addr + i) & 3) || pos_extra || (nbytes_segment != 0x4000) )
1533 {
1534 sec = (sectors >= 8) ? sectors : 8;
1535 if ( sec > filesize_bsr_11 - lbn )
1536 {
1537 sec = filesize_bsr_11 - lbn;
1538 }
1539 VERBOSE_PRINTF(1, "FIO Cache LSN:%d SEC:%d ADDR:%08x\n", (int)lbn, (int)sec, (unsigned int)(uiptr)buf);
1540 sectors_count = (sec >= 9) ? (sec - 8) : 0;
1541 if ( sectors_count )
1542 {
1543 while ( !sceCdRE(lbn, sectors_count, buf, &rmode) )
1544 {
1545 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1546 if ( (sceCdStatus() & SCECdStatShellOpen) )
1547 {
1548 g_cdvdman_iocache = 0;
1549 g_cdvdman_spinctl = -1;
1550 return -EIO;
1551 }
1552 DelayThread(10000);
1553 }
1554 sceCdSync(0);
1555 last_err = sceCdGetError();
1556 if ( last_err != SCECdErNO )
1557 {
1558 PRINTF("Read Error= 0x%02x\n", last_err);
1559 g_cdvdman_iocache = 0;
1560 break;
1561 }
1562 }
1563 while ( !sceCdRE(lbn + sectors_count, sec - sectors_count, (char *)buf + 0x800 * sectors_count, &rmode) )
1564 {
1565 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1566 if ( (sceCdStatus() & SCECdStatShellOpen) )
1567 {
1568 g_cdvdman_iocache = 0;
1569 g_cdvdman_spinctl = -1;
1570 return -EIO;
1571 }
1572 DelayThread(10000);
1573 }
1574 sceCdSync(0);
1575 last_err = sceCdGetError();
1576 if ( last_err != SCECdErNO )
1577 {
1578 PRINTF("Read Error= 0x%02x\n", last_err);
1579 g_cdvdman_iocache = 0;
1580 break;
1581 }
1582 g_cdvdman_lcn_offset = lbn_tmp;
1583 g_cdvdman_numbytes_offset = sec;
1584 g_cdvdman_iocache = 1;
1585 optimized_memcpy(
1586 &addr[pos_sub_2048 + i],
1587 &((const char *)g_cdvdman_temp_buffer_ptr)[!pos_sub_2048 ? pos_extra : 0],
1588 nbytes_segment - pos_sub_2048);
1589 }
1590 else
1591 {
1592 VERBOSE_PRINTF(
1593 1, "FIO Usr addr LSN:%d SEC:%d ADDR:%08x\n", (int)lbn, (int)sectors, (unsigned int)(uiptr)(addr + i));
1594 while ( !sceCdRE(lbn, sectors, addr + i, &rmode) )
1595 {
1596 VERBOSE_PRINTF(1, "sce_Read ON Delay\n");
1597 if ( (sceCdStatus() & SCECdStatShellOpen) )
1598 {
1599 g_cdvdman_iocache = 0;
1600 g_cdvdman_spinctl = -1;
1601 return -EIO;
1602 }
1603 DelayThread(10000);
1604 }
1605 sceCdSync(0);
1606 last_err = sceCdGetError();
1607 g_cdvdman_iocache = 0;
1608 if ( last_err != SCECdErNO )
1609 {
1610 PRINTF("Read Error= 0x%02x\n", last_err);
1611 break;
1612 }
1613 }
1614 if ( nbytes_segment <= 0 )
1615 {
1616 g_cdvdman_spinctl = -1;
1617 return nbytes_segment;
1618 }
1619 }
1620 fh->m_read_pos += i;
1621 VERBOSE_PRINTF(1, "fileIO read ended\n");
1622 g_cdvdman_spinctl = -1;
1623 return i;
1624}
1625
1626static int cdrom_stream_read(const iop_file_t *f, char *bbuf, int nbytes)
1627{
1628 cdvdman_fhinfo_t *fh;
1629 sceCdRMode rmode;
1630 int buf;
1631
1632 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1633 g_cdvdman_strmerr = 0;
1634 cdvdman_iormode(&rmode, fh->m_filemode, f->unit);
1635 rmode.spindlctrl = SCECdSpinStm;
1636 rmode.trycount = 0;
1637 // The following sceCdStRead call was inlined
1638 buf = sceCdStRead(nbytes >> 11, (u32 *)bbuf, STMNBLK, (u32 *)&g_cdvdman_strmerr);
1639 fh->m_read_pos += buf << 11;
1640 return buf << 11;
1641}
1642
1643// cppcheck-suppress constParameterCallback
1644static int cdrom_read(iop_file_t *f, void *buf, int nbytes)
1645{
1646 cdvdman_fhinfo_t *fh;
1647 int rc;
1648 u32 efbits;
1649
1650 if ( nbytes < 0 )
1651 {
1652 return -EINVAL;
1653 }
1654 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1655 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1656 if ( cdvdman_mediactl(2) )
1657 {
1658 g_cdvdman_iocache = 0;
1659 cdvdman_invcaches();
1660 }
1661 if ( (fh->m_fd_flags & 8) )
1662 {
1663 rc = cdrom_stream_read(f, (char *)buf, nbytes);
1664 }
1665 else
1666 {
1667 if ( !(fh->m_fd_flags & 4) )
1668 {
1669 rc = cdrom_internal_read(f, (char *)buf, nbytes);
1670 }
1671 else
1672 {
1673 rc = cdrom_internal_cache_read(f, nbytes);
1674 if ( rc )
1675 {
1676 if ( rc != -EBUSY )
1677 {
1678 if ( rc != 1 )
1679 {
1680 fh->m_fd_flags &= ~4;
1681 rc = -EIO;
1682 cdvd_odcinit(fh, 0, (int)f->privdata);
1683 }
1684 else
1685 {
1686 rc = cdvdfile_cache_fill_read(f, buf, nbytes);
1687 VERBOSE_KPRINTF(1, "called _cdvdfile_cache_fill_read %d\n", rc);
1688 }
1689 }
1690 }
1691 else
1692 {
1693 rc = cdvdfile_cache_read(f, buf, nbytes);
1694 VERBOSE_KPRINTF(1, "called _cdvdfile_cache_read %d\n", rc);
1695 }
1696 if ( rc == -EBUSY || rc == -ECOMM )
1697 {
1698 cdvdman_cache_invalidate(fh, (int)f->privdata);
1699 KPRINTF("_cdvdfile_cache Read_err OR Drive_not_ready\n", rc);
1700 }
1701 if ( rc < 0 )
1702 {
1703 rc = cdrom_internal_read(f, (char *)buf, nbytes);
1704 }
1705 }
1706 }
1707 SetEventFlag(g_fio_fsv_evfid, 1);
1708 return rc;
1709}
1710
1711static int cdrom_ioctl(iop_file_t *f, int arg, void *param)
1712{
1713#ifdef CDVD_VARIANT_OSD
1714 USE_IOP_MMIO_HWPORT();
1715#endif
1716
1717 (void)f;
1718
1719 switch ( arg )
1720 {
1721#ifdef CDVD_VARIANT_OSD
1722 case 0x6310:
1723 return get_mips_cop_reg(0, COP0_REG_PRId);
1724 case 0x6311:
1725 if ( get_mips_cop_reg(0, COP0_REG_PRId) < 35 )
1726 {
1727 return -22;
1728 }
1729 if ( *(u32 *)param )
1730 {
1731 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] |= 1;
1732 }
1733 else
1734 {
1735 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] &= ~1;
1736 }
1737 return 0;
1738 case 0x6312:
1739 return get_mips_cop_reg(0, COP0_REG_PRId) >= 35 ? (int)(/* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] & 1) : -22;
1740#endif
1741 case 0x10000:
1742 g_cdvdman_spinnom = -1;
1743 sceCdSpinCtrlIOP((u32)param);
1744 return 0;
1745#ifdef CDVD_VARIANT_OSD
1746 case 0x10008:
1747 sceCdDecSet(*(u32 *)param, *((u32 *)param + 1), *((u32 *)param + 2));
1748 return 0;
1749 case 0x10020:
1750 return sceCdReadKey(*(u32 *)param, *((u32 *)param + 1), *((u32 *)param + 2), (u8 *)param + 12) ? 1 : -16;
1751 case 0x10030:
1752 return sceCdGetDiskType();
1753#endif
1754 default:
1755 return -EIO;
1756 }
1757}
1758
1759// cppcheck-suppress constParameterCallback
1760static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen)
1761{
1762 const cdvdman_fhinfo_t *fh;
1763 int retval;
1764 u32 efbits;
1765
1766 (void)argp;
1767 (void)arglen;
1768 (void)bufp;
1769 (void)buflen;
1770
1771 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1772 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
1773 retval = -EIO;
1774 if ( (fh->m_fd_flags & 8) )
1775 {
1776 switch ( request )
1777 {
1778 case CIOCSTREAMPAUSE:
1779 // The following call to sceCdStPause was inlined
1780 if ( sceCdStPause() )
1781 {
1782 retval = 0;
1783 }
1784 break;
1785 case CIOCSTREAMRESUME:
1786 // The following call to sceCdStResume was inlined
1787 if ( sceCdStResume() )
1788 {
1789 retval = 0;
1790 }
1791 break;
1792 case CIOCSTREAMSTAT:
1793 // The following call to sceCdStStat was inlined
1794 // Unofficial: return 0 instead of negative value
1795 retval = sceCdStStat();
1796 break;
1797 default:
1798 break;
1799 }
1800 }
1801 SetEventFlag(g_fio_fsv_evfid, 1);
1802 return retval;
1803}
1804
1805static int
1806cdrom_devctl(iop_file_t *f, const char *name, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen)
1807{
1808 unsigned int i;
1809 int retval2;
1810 char *sc_tmp_2;
1811 unsigned int sc_tmp_3;
1812 u32 efbits;
1813 int on_dual_tmp;
1814 int scres_unused;
1815
1816 (void)f;
1817 (void)name;
1818 (void)buflen;
1819
1820 retval2 = 0;
1821 if ( cmd != CDIOC_BREAK )
1822 {
1823 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
1824 }
1825 switch ( cmd )
1826 {
1827 case CDIOC_READCLOCK:
1828 for ( i = 0; i < 3 && !retval2; i += 1 )
1829 {
1830 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1831 retval2 = sceCdReadClock((sceCdCLOCK *)bufp);
1832 }
1833 retval2 = (retval2 != 1) ? -EIO : 0;
1834 break;
1835#ifdef CDVD_VARIANT_DNAS
1836 case 0x431D:
1837 for ( i = 0; i < 3 && !retval2; i += 1 )
1838 {
1839 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1840 retval2 = sceCdReadGUID((u64 *)bufp);
1841 }
1842 retval2 = (retval2 != 1) ? -EIO : 0;
1843 break;
1844 case 0x431E:
1845 retval2 = (sceCdReadDiskID((unsigned int *)bufp) != 1) ? -EIO : 0;
1846 break;
1847#endif
1848 case CDIOC_GETDISKTYP:
1849 *(u32 *)bufp = sceCdGetDiskType();
1850 break;
1851 case CDIOC_GETERROR:
1852 *(u32 *)bufp = g_cdvdman_strmerr ? g_cdvdman_strmerr : sceCdGetError();
1853 break;
1854 case CDIOC_TRAYREQ:
1855 retval2 = (sceCdTrayReq(*(u32 *)argp, (u32 *)bufp) != 1) ? -EIO : 0;
1856 break;
1857 case CDIOC_STATUS:
1858 *(u32 *)bufp = sceCdStatus();
1859 break;
1860 case CDIOC_POWEROFF:
1861 for ( i = 0; i < 3 && !retval2; i += 1 )
1862 {
1863 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1864 retval2 = sceCdPowerOff((u32 *)bufp);
1865 }
1866 retval2 = (retval2 != 1) ? -EIO : 0;
1867 break;
1868 case CDIOC_MMODE:
1869 sceCdMmode(*(u32 *)argp);
1870 break;
1871 case CDIOC_DISKRDY:
1872 *(u32 *)bufp = sceCdDiskReady(*(u32 *)argp);
1873 break;
1874#ifdef CDVD_VARIANT_DNAS
1875 case 0x4326:
1876 for ( i = 0; i < 3 && !retval2; i += 1 )
1877 {
1878 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
1879 retval2 = sceCdReadModelID((unsigned int *)bufp);
1880 }
1881 retval2 = (retval2 != 1) ? -EIO : 0;
1882 break;
1883#endif
1884 case CDIOC_STREAMINIT:
1885 // The following call to sceCdStInit was inlined
1886 retval2 = (!sceCdStInit(*(u32 *)argp, *((u32 *)argp + 1), (void *)*((u32 *)argp + 2))) ? -EIO : 0;
1887 break;
1888 case CDIOC_BREAK:
1889 retval2 = (!sceCdBreak()) ? -EIO : 0;
1890 sceCdSync(4);
1891 break;
1892#ifdef CDVD_VARIANT_XOSD
1893 case 0x437F:
1894 sc_tmp_3 = *(u32 *)argp;
1895 retval2 = (sc_tmp_3 - 4 >= 0x15) ? -22 : sceCdSC(0xFFFFFFDD, (int *)&sc_tmp_3);
1896 break;
1897#endif
1898 case CDIOC_SPINNOM:
1899 g_cdvdman_spinnom = SCECdSpinNom;
1900 break;
1901 case CDIOC_SPINSTM:
1902 g_cdvdman_spinnom = SCECdSpinStm;
1903 break;
1904 case CDIOC_TRYCNT:
1905 g_cdvdman_trycnt = *(u8 *)argp;
1906 break;
1907 case 0x4383:
1908 retval2 = (sceCdSeek(*(u32 *)argp) != 1) ? -EIO : 0;
1909 sceCdSync(6);
1910 break;
1911 case CDIOC_STANDBY:
1912 retval2 = (sceCdStandby() != 1) ? -EIO : 0;
1913 sceCdSync(4);
1914 break;
1915 case CDIOC_STOP:
1916 retval2 = (sceCdStop() != 1) ? -EIO : 0;
1917 sceCdSync(4);
1918 break;
1919 case CDIOC_PAUSE:
1920 retval2 = (sceCdPause() != 1) ? -EIO : 0;
1921 sceCdSync(6);
1922 break;
1923 case CDIOC_GETTOC:
1924 switch ( sceCdGetDiskType() )
1925 {
1926 case SCECdPSCD:
1927 case SCECdPSCDDA:
1928 case SCECdPS2CD:
1929 case SCECdPS2CDDA:
1930 retval2 = (sceCdGetToc((u8 *)bufp) != 1) ? -EIO : 0;
1931 break;
1932 default:
1933 break;
1934 }
1935 break;
1936 case CDIOC_SETTIMEOUT:
1937 retval2 = (sceCdSetTimeout(1, *(u32 *)argp) != 1) ? -EIO : 0;
1938 break;
1939 case CDIOC_READDVDDUALINFO:
1940 retval2 = (!sceCdReadDvdDualInfo(&on_dual_tmp, (unsigned int *)bufp)) ? -EIO : 0;
1941 break;
1942 case CDIOC_INIT:
1943 sceCdInit(*(u32 *)argp);
1944 retval2 = 0;
1945 break;
1946 case 0x438C:
1947 g_cdvdman_spinnom = SCECdSpinX1;
1948 break;
1949 case 0x438D:
1950 g_cdvdman_spinnom = SCECdSpinX2;
1951 break;
1952 case 0x438E:
1953 g_cdvdman_spinnom = SCECdSpinX4;
1954 break;
1955 case 0x438F:
1956 g_cdvdman_spinnom = SCECdSpinX12;
1957 break;
1958 case 0x4390:
1959 g_cdvdman_spinnom = SCECdSpinMx;
1960 break;
1961 case 0x4391:
1962 *(u32 *)bufp = sceCdSC(0xFFFFFFF5, &scres_unused);
1963 break;
1964 case 0x4392:
1965 retval2 = (sceCdApplySCmd(*(u8 *)argp, (char *)argp + 4, arglen - 4, bufp) != 1) ? -EIO : 0;
1966 break;
1967 case CDIOC_FSCACHEINIT:
1968 retval2 = -EBUSY;
1969 if ( g_cache_path_fd != -1 )
1970 {
1971 break;
1972 }
1973 retval2 = -EINVAL;
1974 sc_tmp_2 = (char *)argp;
1975 for ( i = 0; i < arglen && sc_tmp_2[i] && sc_tmp_2[i] != ','; i += 1 )
1976 {
1977 g_cdvdman_cache_name[i] = sc_tmp_2[i];
1978 }
1979 sc_tmp_3 = i;
1980 if ( i <= arglen )
1981 {
1982 i += 1;
1983 for ( ; (i < arglen) && sc_tmp_2[i] && sc_tmp_2[i] != ','; i += 1 )
1984 {
1985 }
1986 }
1987 if ( i <= arglen )
1988 {
1989 sc_tmp_2[i] = 0;
1990 g_cdvdman_cache_sector_size_count = strtol((const char *)argp + sc_tmp_3, 0, 10);
1991 retval2 = path_tbl_init(strtol(&sc_tmp_2[i + 1], 0, 10), g_cdvdman_cache_name, 1);
1992 }
1993 break;
1994 case CDIOC_FSCACHEDELETE:
1995 for ( i = 0; i < (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0])); i += 1 )
1996 {
1997 if ( (g_cdvdman_fhinfo[i].m_fd_flags & 4) )
1998 {
1999 break;
2000 }
2001 }
2002 retval2 = (i == (sizeof(g_cdvdman_fhinfo) / sizeof(g_cdvdman_fhinfo[0]))) ? path_tbl_init(0, 0, 0) : -EBUSY;
2003 break;
2004 default:
2005 retval2 = -EIO;
2006 break;
2007 }
2008 if ( cmd != CDIOC_BREAK )
2009 {
2010 SetEventFlag(g_fio_fsv_evfid, 1);
2011 }
2012 return retval2;
2013}
2014
2015// cppcheck-suppress constParameterCallback
2016static int cdrom_lseek(iop_file_t *f, int offset, int pos)
2017{
2018 int retval;
2019 cdvdman_fhinfo_t *fh;
2020 u32 efbits;
2021
2022 retval = -EPERM;
2023 VERBOSE_PRINTF(1, "fileIO SEEK\n");
2024 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
2025 fh = &g_cdvdman_fhinfo[(uiptr)f->privdata];
2026 switch ( pos )
2027 {
2028 case 0:
2029 retval = offset;
2030 break;
2031 case 1:
2032 retval = fh->m_read_pos + offset;
2033 break;
2034 case 2:
2035 retval = fh->m_file_size - offset;
2036 break;
2037 default:
2038 break;
2039 }
2040 if ( retval > (int)(fh->m_file_size) )
2041 {
2042 retval = fh->m_file_size;
2043 }
2044 fh->m_read_pos = retval;
2045 if ( (fh->m_fd_flags & 8) )
2046 {
2047 // The following call to sceCdStSeekF was inlined
2048 if ( !sceCdStSeekF(fh->m_file_lsn + retval / 0x800) )
2049 {
2050 retval = -EIO;
2051 }
2052 }
2053 SetEventFlag(g_fio_fsv_evfid, 1);
2054 return retval;
2055}
2056
2057static unsigned int sync_timeout_alarm_cb(void *userdata)
2058{
2059 const iop_sys_clock_t *sys_clock;
2060
2061 sys_clock = (const iop_sys_clock_t *)userdata;
2062 KPRINTF("Cdvd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
2063 return !sceCdBreak();
2064}
2065
2066int sceCdSetTimeout(int param, int timeout)
2067{
2068 if ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2069 {
2070 return 0;
2071 }
2072 switch ( param )
2073 {
2074 case 1:
2075 g_cdvdman_sync_timeout = timeout;
2076 return 1;
2077 case 2:
2078 g_cdvdman_stream_timeout = timeout;
2079 return 1;
2080 default:
2081 return 0;
2082 }
2083}
2084
2085int sceCdSync(int mode)
2086{
2087 iop_sys_clock_t sysclk;
2088 iop_event_info_t efinfo;
2089 u32 efbits;
2090
2091 VERBOSE_KPRINTF(1, "sceCdSync: Call mode %d Com %x\n", mode, (u8)g_cdvdman_istruct.m_cdvdman_command);
2092 switch ( mode )
2093 {
2094 case 0:
2095 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2096 {
2097 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2098 }
2099 break;
2100 case 1:
2101 return !!(!sceCdCheckCmd() || (g_cdvdman_istruct.m_read2_flag));
2102 case 3:
2103 sysclk.hi = 0;
2104 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
2105 vSetAlarm(&sysclk, sync_timeout_alarm_cb, &sysclk);
2106 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2107 {
2108 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2109 }
2110 vCancelAlarm(sync_timeout_alarm_cb, &sysclk);
2111 break;
2112 case 4:
2113 sysclk.hi = 0;
2114 sysclk.lo = 0x41EB0000;
2115 vSetAlarm(&sysclk, sync_timeout_alarm_cb, &sysclk);
2116 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2117 {
2118 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2119 }
2120 vCancelAlarm(sync_timeout_alarm_cb, &sysclk);
2121 break;
2122 case 5:
2123 while ( !sceCdCheckCmd() )
2124 {
2125 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2126 }
2127 break;
2128 case 6:
2129 sysclk.hi = 0;
2130 sysclk.lo = 0x9000 * g_cdvdman_sync_timeout;
2131 vSetAlarm(&sysclk, sync_timeout_alarm_cb, &sysclk);
2132 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2133 {
2134 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2135 }
2136 vCancelAlarm(sync_timeout_alarm_cb, &sysclk);
2137 break;
2138 case 16:
2139 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2140 || g_cdvdman_istruct.m_stream_flag )
2141 {
2142 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2143 if ( g_cdvdman_ee_rpc_fno )
2144 {
2145 DelayThread(8000);
2146 }
2147 }
2148 break;
2149 case 17:
2150 return !!(
2151 !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag || g_cdvdman_ee_rpc_fno
2152 || (g_cdvdman_istruct.m_stream_flag));
2153 case 32:
2154 WaitEventFlag(g_cdvdman_intr_evfid, 0x21, WEF_OR, &efbits);
2155 ReferEventFlagStatus(g_cdvdman_intr_evfid, &efinfo);
2156 if ( !(efinfo.currBits & 0x20) )
2157 {
2158 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
2159 {
2160 SetEventFlag(g_cdvdman_intr_evfid, 0x20);
2161 }
2162 else
2163 {
2164 WaitEventFlag(g_cdvdman_intr_evfid, 0x20, WEF_AND, &efbits);
2165 }
2166 }
2167 break;
2168 default:
2169 while ( !sceCdCheckCmd() || g_cdvdman_istruct.m_read2_flag )
2170 {
2171 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2172 }
2173 break;
2174 }
2175 VERBOSE_KPRINTF(
2176 1,
2177 "sceCdSync: Command= %d Error= %d\n",
2178 (u8)g_cdvdman_istruct.m_cdvdman_command,
2179 (u8)g_cdvdman_istruct.m_last_error);
2180 return 0;
2181}
2182
2183int sceCdSpinCtrlIOP(u32 speed)
2184{
2185 VERBOSE_KPRINTF(1, "sceCdSpinCtrlIOP speed= %d\n", speed);
2186 g_cdvdman_spinctl = speed;
2187 return 1;
2188}
2189
2190int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
2191{
2192 unsigned int i;
2193 int search_res;
2194 u32 efbits;
2195
2196 if ( PollEventFlag(g_sfile_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
2197 {
2198 return 0;
2199 }
2200 for ( i = 0; i < ((sizeof(g_cdvdman_sfname) / sizeof(g_cdvdman_sfname[0])) - 1) && path[i]; i += 1 )
2201 {
2202 g_cdvdman_sfname[i] = path[i];
2203 }
2204 g_cdvdman_sfname[i] = 0;
2205 g_cdvdman_srchspd = 1;
2206 search_res = CdSearchFileInner((cdvdman_filetbl_entry_t *)fp, g_cdvdman_sfname, layer);
2207 vSetEventFlag(g_sfile_evfid, 1);
2208 return search_res;
2209}
2210
2211int sceCdSearchFile(sceCdlFILE *file, const char *name)
2212{
2213 return sceCdLayerSearchFile(file, name, 0);
2214}
2215
2216int sceCdGetToc(u8 *toc)
2217{
2218 return cdvdman_gettoc(toc);
2219}
2220
2221int sceCdDiskReady(int mode)
2222{
2223 u32 efbits;
2224 USE_DEV5_MMIO_HWPORT();
2225
2226 efbits = 0;
2227 // The following Kprintf was modified for ioprp300x
2228 VERBOSE_KPRINTF(1, "DISK READY call from iop %d\n", mode);
2229#ifdef CDVD_VARIANT_XOSD
2230 if ( g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1 )
2231 {
2232 return mode == 8 ? -1 : 6;
2233 }
2234 switch ( get_disk_type_ex() )
2235 {
2236 case SCECdNODISC:
2237 case 257:
2238 return 2;
2239 default:
2240 break;
2241 }
2242#endif
2243 switch ( mode )
2244 {
2245 case 0:
2246 VERBOSE_KPRINTF(1, "Wait Drive Ready %x\n", dev5_mmio_hwport->m_dev5_reg_005);
2247 while ( g_cdvdman_istruct.m_read2_flag )
2248 {
2249 // The following call to sceCdGetDiskType was inlined
2250#ifdef CDVD_VARIANT_XOSD
2251 switch ( get_disk_type_ex() )
2252#else
2253 switch ( sceCdGetDiskType() )
2254#endif
2255 {
2256 case SCECdDETCT:
2257 case SCECdDETCTCD:
2258 case SCECdDETCTDVDS:
2259 case SCECdDETCTDVDD:
2260 while ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) != 0x40 )
2261 {
2262 vDelayThread(2000);
2263 WaitEventFlag(g_cdvdman_intr_evfid, 1, WEF_AND, &efbits);
2264#ifdef CDVD_VARIANT_XOSD
2265 if ( !get_disk_type_ex() )
2266 {
2267 return 2;
2268 }
2269#endif
2270 }
2271 continue;
2272 default:
2273 break;
2274 }
2275 break;
2276 }
2277 // The following Kprintf was added for ioprp300x
2278 VERBOSE_KPRINTF(1, "Wait Exit\n");
2279 return 2;
2280 case 8:
2281 return (u8)dev5_mmio_hwport->m_dev5_reg_005;
2282 case 1:
2283 default:
2284 if ( (dev5_mmio_hwport->m_dev5_reg_005 & 0xC0) == 0x40 && !g_cdvdman_istruct.m_read2_flag )
2285 {
2286 return 2;
2287 }
2288 VERBOSE_KPRINTF(1, "Drive Not Ready\n");
2289 return 6;
2290 }
2291}
2292
2293int sceCdGetDiskType(void)
2294{
2295#ifdef CDVD_VARIANT_XOSD
2296 int cdvd_register;
2297
2298 VERBOSE_KPRINTF(1, "sceCdGetDiskType Call\n");
2299 cdvd_register = get_cdvd_register(0x0F);
2300 VERBOSE_KPRINTF(1, "sceCdGetDiskType 0x%02x\n", cdvd_register);
2301 return cdvd_register;
2302#else
2303 USE_DEV5_MMIO_HWPORT();
2304
2305 return (u8)dev5_mmio_hwport->m_dev5_reg_00F;
2306#endif
2307}
2308
2309#ifdef CDVD_VARIANT_XOSD
2310static int get_disk_type_ex(void)
2311{
2312 int IntrContext;
2313 int retval;
2314 int state;
2315 USE_DEV5_MMIO_HWPORT();
2316
2317 IntrContext = QueryIntrContext();
2318 if ( IntrContext )
2319 {
2320 CpuSuspendIntr(&state);
2321 }
2322 retval = (g_cdvdman_istruct.m_cd_mode_ps2_atapi == 1) ? 257 : dev5_mmio_hwport->m_dev5_reg_00F;
2323 if ( IntrContext )
2324 {
2325 CpuResumeIntr(state);
2326 }
2327 return retval;
2328}
2329#endif
2330
2331#ifdef CDVD_VARIANT_XOSD
2332int sceCdGetWakeUpReason(void)
2333{
2334 int wakeup_reason_reg;
2335
2336 VERBOSE_KPRINTF(1, "sceCdGetWakeUpReason Call\n");
2337 wakeup_reason_reg = get_cdvd_register(0x15);
2338 if ( wakeup_reason_reg != -1 )
2339 {
2340 wakeup_reason_reg &= 0xF;
2341 }
2342 VERBOSE_KPRINTF(1, "sceCdGetWakeUpReason 0x%02x\n", wakeup_reason_reg);
2343 return wakeup_reason_reg;
2344}
2345#endif
2346
2347int sceCdStatus(void)
2348{
2349 int reg_00A_tmp;
2350#ifndef CDVD_VARIANT_XOSD
2351 u32 status_tmp;
2352#endif
2353#ifndef CDVD_VARIANT_XOSD
2354 USE_DEV5_MMIO_HWPORT();
2355#endif
2356
2357#ifdef CDVD_VARIANT_XOSD
2358 reg_00A_tmp = get_cdvd_register(0x0A);
2359#else
2360 reg_00A_tmp = dev5_mmio_hwport->m_dev5_reg_00A;
2361#endif
2362#ifndef CDVD_VARIANT_XOSD
2363 // The following call to sceCdGetDiskType was inlined
2364 if ( sceCdGetDiskType() == SCECdNODISC )
2365 {
2366 u8 rdata_tmp;
2367
2368 if ( !g_cdvdman_istruct.m_tray_is_open && cdvdman_scmd_sender_03_30(&rdata_tmp, &status_tmp) == 1 && !status_tmp )
2369 {
2370 reg_00A_tmp &= ~SCECdStatShellOpen;
2371 if ( (rdata_tmp & 8) )
2372 {
2373 reg_00A_tmp |= SCECdStatShellOpen;
2374 }
2375 }
2376 if ( (reg_00A_tmp & 0x1E) )
2377 {
2378 reg_00A_tmp = SCECdStatStop;
2379 }
2380 }
2381#endif
2382 if ( g_cdvdman_istruct.m_use_toc )
2383 {
2384 reg_00A_tmp &= ~SCECdStatShellOpen;
2385 }
2386 if ( g_cdvdman_istruct.m_power_flag )
2387 {
2388 return -1;
2389 }
2390 return reg_00A_tmp;
2391}
2392
2393#ifdef CDVD_VARIANT_OSD
2394int sceCdStatus2(void)
2395{
2396 USE_DEV5_MMIO_HWPORT();
2397
2398 return !g_cdvdman_istruct.m_power_flag ? (u8)dev5_mmio_hwport->m_dev5_reg_00A : -1;
2399}
2400#endif
2401
2403{
2404 p->sector = 16 * ((i + 150) % 75 / 10) + (i + 150) % 75 % 10;
2405 p->second = 16 * ((i + 150) / 75 % 60 / 10) + (i + 150) / 75 % 60 % 10;
2406 p->minute = 16 * ((i + 150) / 75 / 60 / 10) + (i + 150) / 75 / 60 % 10;
2407 return p;
2408}
2409
2410// cppcheck-suppress constParameterPointer
2412{
2413 return 75 * (60 * (10 * (p->minute >> 4) + (p->minute & 0xF)) + 10 * (p->second >> 4) + (p->second & 0xF))
2414 + 10 * (p->sector >> 4) + (p->sector & 0xF) - 150;
2415}
2416
2417#ifdef CDVD_VARIANT_DNAS
2418static int read_id_from_rom(int mode, int *buf)
2419{
2420 int chksumint;
2421 unsigned int i;
2422 unsigned int j;
2423 int idinfo[0x20];
2424 int chksumstk;
2425
2426 chksumint = 0;
2427 chksumstk = 0;
2428 for ( i = 0; i < (sizeof(idinfo) / sizeof(idinfo[0])); i += 1 )
2429 {
2430 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2431 {
2432 ((char *)&idinfo)[(i * 4) + j] = ((char *)0xBFBF0000)[(i * 4) + j];
2433 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2434 }
2435 chksumint += chksumstk;
2436 }
2437 for ( ; i < 0x4000; i += 1 )
2438 {
2439 for ( j = 0; j < sizeof(chksumstk); j += 1 )
2440 {
2441 ((char *)&chksumstk)[j] = ((char *)0xBFBF0000)[(i * 4) + j];
2442 }
2443 chksumint += chksumstk;
2444 }
2445 if ( chksumint )
2446 {
2447 KPRINTF("# checksum error %d\n", chksumint);
2448 return 0;
2449 }
2450 if ( mode )
2451 {
2452 *buf = idinfo[11];
2453 }
2454 else
2455 {
2456 *buf = idinfo[2];
2457 buf[1] = idinfo[3];
2458 }
2459 return 1;
2460}
2461
2462static int query_boot_mode_6_nonzero(void)
2463{
2464 int *BootMode;
2465
2466 BootMode = QueryBootMode(6);
2467 return !(!BootMode || (*(u16 *)BootMode & 0xFFFC) != 0x60);
2468}
2469
2470static int query_boot_mode_6_zero(void)
2471{
2472 return !QueryBootMode(6);
2473}
2474
2475static int cdvdman_readID(int mode, int *buf)
2476{
2477 u8 id_val[8];
2478 iop_sys_clock_t sysclk;
2479 u32 id_result;
2480
2481 id_result = -1;
2482 if ( query_boot_mode_6_nonzero() )
2483 {
2484 if ( read_id_from_rom(mode, buf) && mode == 1 )
2485 {
2486 if ( *buf == -1 )
2487 {
2488 *buf = 0x1A0002;
2489 }
2490 return 1;
2491 }
2492 return 0;
2493 }
2494 else
2495 {
2496 if ( query_boot_mode_6_zero() )
2497 {
2498 if ( !sceCdRI(id_val, &id_result) || id_result )
2499 {
2500 return 0;
2501 }
2502 }
2503 else
2504 {
2505 if ( !g_readid_systemtime.lo && !g_readid_systemtime.hi )
2506 {
2507 GetSystemTime(&sysclk);
2508 g_readid_systemtime = sysclk;
2509 }
2510 *(iop_sys_clock_t *)id_val = g_readid_systemtime;
2511 }
2512 if ( mode )
2513 {
2514 *buf = *(u32 *)id_val >> 8;
2515 }
2516 else
2517 {
2518 *buf = id_val[0] | 0x8004600;
2519 buf[1] = *(u32 *)&id_val[4];
2520 }
2521 return 1;
2522 }
2523}
2524
2525int sceCdReadGUID(u64 *guid)
2526{
2527 return cdvdman_readID(0, (int *)guid);
2528}
2529
2530int sceCdReadModelID(unsigned int *id)
2531{
2532 return cdvdman_readID(1, (int *)id);
2533}
2534#endif
2535
2536int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
2537{
2538 cdrom_stm_devctl_t devctl_req;
2539 int buf;
2540
2541 // The following Kprintf was added for ioprp300x
2542 VERBOSE_KPRINTF(1, "sceCdStInit call IOP\n");
2543 memset(&devctl_req, 0, sizeof(devctl_req));
2544 devctl_req.m_cmdid = 5;
2545 devctl_req.m_posszarg1 = bufmax;
2546 devctl_req.m_posszarg2 = bankmax;
2547 devctl_req.m_buffer = buffer;
2548 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2549}
2550
2551// cppcheck-suppress constParameterPointer
2552int sceCdStStart(u32 lbn, sceCdRMode *mode)
2553{
2554 cdrom_stm_devctl_t devctl_req;
2555 int buf;
2556
2557 // The following Kprintf was added for ioprp300x
2558 VERBOSE_KPRINTF(1, "sceCdStStart call IOP\n");
2559 memset(&devctl_req, 0, sizeof(devctl_req));
2560 devctl_req.m_rmode.datapattern = mode->datapattern;
2561 devctl_req.m_rmode.spindlctrl = mode->spindlctrl;
2562 devctl_req.m_cmdid = 1;
2563 devctl_req.m_posszarg1 = lbn;
2564 devctl_req.m_rmode.trycount = mode->trycount;
2565 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2566}
2567
2568int sceCdStSeekF(unsigned int lsn)
2569{
2570 cdrom_stm_devctl_t devctl_req;
2571 int buf;
2572
2573 // The following Kprintf was added for ioprp300x
2574 VERBOSE_KPRINTF(1, "sceCdStSeekF call IOP\n");
2575 memset(&devctl_req, 0, sizeof(devctl_req));
2576 devctl_req.m_cmdid = 9;
2577 devctl_req.m_posszarg1 = lsn;
2578 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2579}
2580
2581int sceCdStSeek(u32 lbn)
2582{
2583 cdrom_stm_devctl_t devctl_req;
2584 int buf;
2585
2586 // The following Kprintf was added for ioprp300x
2587 VERBOSE_KPRINTF(1, "sceCdStSeek call IOP\n");
2588 memset(&devctl_req, 0, sizeof(devctl_req));
2589 devctl_req.m_posszarg1 = lbn;
2590 devctl_req.m_cmdid = 4;
2591 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2592}
2593
2594int sceCdStStop(void)
2595{
2596 cdrom_stm_devctl_t devctl_req;
2597 int buf;
2598
2599 // The following Kprintf was added for ioprp300x
2600 VERBOSE_KPRINTF(1, "sceCdStStop call IOP\n");
2601 memset(&devctl_req, 0, sizeof(devctl_req));
2602 devctl_req.m_cmdid = 3;
2603 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2604}
2605
2606int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
2607{
2608 cdrom_stm_devctl_t devctl_req;
2609 int buf;
2610
2611 (void)mode;
2612
2613 // The following Kprintf was added for ioprp300x
2614 VERBOSE_KPRINTF(1, "sceCdStRead call IOP\n");
2615 memset(&devctl_req, 0, sizeof(devctl_req));
2616 devctl_req.m_cmdid = 1;
2617 devctl_req.m_posszarg2 = sectors;
2618 devctl_req.m_buffer = buffer;
2619 if ( devctl("cdrom_stm0:", 0x4394, &devctl_req, sizeof(devctl_req), &buf, 4) < 0 )
2620 {
2621 buf = 0;
2622 }
2623 *error = devctl_req.m_error;
2624 return buf;
2625}
2626
2627int sceCdStPause(void)
2628{
2629 cdrom_stm_devctl_t devctl_req;
2630 int buf;
2631
2632 // The following Kprintf was added for ioprp300x
2633 VERBOSE_KPRINTF(1, "sceCdStPause call IOP\n");
2634 memset(&devctl_req, 0, sizeof(devctl_req));
2635 devctl_req.m_cmdid = 7;
2636 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2637}
2638
2639int sceCdStResume(void)
2640{
2641 cdrom_stm_devctl_t devctl_req;
2642 int buf;
2643
2644 // The following Kprintf was added for ioprp300x
2645 VERBOSE_KPRINTF(1, "sceCdStResume call IOP\n");
2646 memset(&devctl_req, 0, sizeof(devctl_req));
2647 devctl_req.m_cmdid = 8;
2648 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2649}
2650
2651int sceCdStStat(void)
2652{
2653 cdrom_stm_devctl_t devctl_req;
2654 int buf;
2655
2656 // The following Kprintf was added for ioprp300x
2657 VERBOSE_KPRINTF(1, "sceCdStStat call IOP\n");
2658 memset(&devctl_req, 0, sizeof(devctl_req));
2659 devctl_req.m_cmdid = 6;
2660 return (devctl("cdrom_stm0:", 0x4393, &devctl_req, sizeof(devctl_req), &buf, 4) >= 0) ? buf : 0;
2661}
2662
2663static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer)
2664{
2665 int parent_level;
2666 int i;
2667 unsigned int j;
2668 char name_buf[32];
2669
2670 VERBOSE_PRINTF(1, "CdSearchFile: start name= %s layer= %d\n", name, layer);
2671 if ( g_cdvdman_fs_layer != layer )
2672 {
2673 g_cdvdman_fs_cache = 0;
2674 }
2675 if ( !cdvdman_mediactl(0) && g_cdvdman_fs_cache )
2676 {
2677 VERBOSE_KPRINTF(1, "CdSearchFile: cache dir data used\n");
2678 }
2679 else
2680 {
2681 VERBOSE_PRINTF(1, "CdSearchFile Topen= %s\n", name);
2682 if ( !CD_newmedia(layer) )
2683 {
2684 g_cdvdman_fs_cache = 0;
2685 return 0;
2686 }
2687 g_cdvdman_fs_cache = 1;
2688 }
2689 if ( *name != '\\' )
2690 {
2691 return 0;
2692 }
2693 name_buf[0] = 0;
2694 parent_level = 1;
2695 j = 0;
2696 for ( i = 0; i < 8 && name[i]; i += 1 )
2697 {
2698 for ( j = 0; name[i + j] != '\\'; j += 1 )
2699 {
2700 name_buf[j] = name[i + j];
2701 }
2702 name_buf[j] = 0;
2703 parent_level = cdvdman_finddir(parent_level, name_buf);
2704 if ( parent_level == -1 )
2705 {
2706 name_buf[0] = 0;
2707 break;
2708 }
2709 }
2710 if ( i >= 8 )
2711 {
2712 VERBOSE_PRINTF(1, "%s: path level (%d) error\n", name, i);
2713 return 0;
2714 }
2715 if ( !name_buf[0] )
2716 {
2717 VERBOSE_PRINTF(1, "%s: dir was not found\n", name);
2718 return 0;
2719 }
2720 name_buf[j] = 0;
2721 if ( !CD_cachefile(parent_level, layer) )
2722 {
2723 VERBOSE_PRINTF(1, "CdSearchFile: disc error\n");
2724 return 0;
2725 }
2726 VERBOSE_PRINTF(2, "CdSearchFile: searching %s...\n", name_buf);
2727 for ( j = 0;
2728 j < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) && g_cdvdman_filetbl[j].m_file_struct.name[0];
2729 j += 1 )
2730 {
2731 VERBOSE_PRINTF(1, "%d %s %s\n", (int)j, g_cdvdman_filetbl[j].m_file_struct.name, name_buf);
2732 if ( cdvdman_cmpname(g_cdvdman_filetbl[j].m_file_struct.name, name_buf) )
2733 {
2734 VERBOSE_PRINTF(2, "%s:\t found\n", name_buf);
2735 // The following memcpy was inlined
2736 memcpy(fp, &g_cdvdman_filetbl[j], sizeof(cdvdman_filetbl_entry_t));
2737 fp->m_file_struct.lsn += layer ? g_cdvdman_fs_base2 : 0;
2738 return 1;
2739 }
2740 }
2741 VERBOSE_PRINTF(1, "%s: not found\n", name_buf);
2742 return 0;
2743}
2744
2745static int sceCdSearchDir(char *dirname, int layer)
2746{
2747 sceCdlFILE fp;
2748
2749 VERBOSE_PRINTF(1, "_sceCdSearchDir: dir name %s layer %d\n", dirname, layer);
2750 return sceCdLayerSearchFile(&fp, dirname, layer) ? g_cdvdman_fs_cdsec : SCECdErREADCFR;
2751}
2752
2753static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer)
2754{
2755 VERBOSE_PRINTF(1, "_sceCdReadDir: current= %d dsec= %d layer= %d\n", g_cdvdman_fs_cdsec, dsec, layer);
2756 if ( g_cdvdman_fs_cdsec != dsec || g_cdvdman_fs_layer != layer )
2757 {
2758 if ( g_cdvdman_fs_layer != layer )
2759 {
2760 if ( !CD_newmedia(layer) )
2761 {
2762 return -ENOENT;
2763 }
2764 g_cdvdman_fs_cache = 1;
2765 }
2766 if ( !CD_cachefile(dsec, layer) )
2767 {
2768 return -ENOENT;
2769 }
2770 }
2771 if ( g_cdvdman_filetbl[index].m_file_struct.name[0] )
2772 {
2773 VERBOSE_PRINTF(1, "%s:\t found dir_point %d\n", g_cdvdman_filetbl[index].m_file_struct.name, index);
2774 // The following memcpy was inlined
2775 memcpy(fp, &g_cdvdman_filetbl[index], sizeof(cdvdman_filetbl_entry_t));
2776 return 1;
2777 }
2778 return 0;
2779}
2780
2781static int cdvdman_cmpname(const char *p, const char *q)
2782{
2783 return !strncmp(p, q, 12);
2784}
2785
2786static int CD_newmedia(int arg)
2787{
2788 unsigned int DiskType;
2789 unsigned int i;
2790 iso9660_path_t *path_cur;
2791 int state;
2792 int ptsector;
2793
2794 ptsector = 0;
2795#ifdef CDVD_VARIANT_XOSD
2796 DiskType = get_disk_type_ex();
2797#else
2798 DiskType = sceCdGetDiskType();
2799#endif
2800 switch ( DiskType )
2801 {
2802 case SCECdPSCD:
2803 case SCECdPSCDDA:
2804 case SCECdPS2CD:
2805 case SCECdPS2CDDA:
2806 case SCECdPS2DVD:
2807 case SCECdDVDVR:
2808 case SCECdDVDV:
2809 case SCECdIllegalMedia:
2810 break;
2811 default:
2812 VERBOSE_PRINTF(1, "CD_newmedia: Illegal disc media type =%d\n", (int)DiskType);
2813 return 0;
2814 }
2815 g_cdvdman_fs_base2 = 0;
2816 if ( DiskType == SCECdPS2DVD )
2817 {
2818 if ( !DvdDual_infochk() )
2819 {
2820 VERBOSE_PRINTF(1, "CD_newmedia: Get DvdDual_infochk fail\n");
2821 return 0;
2822 }
2823 g_cdvdman_fs_base2 = arg ? g_cdvdman_istruct.m_layer_1_lsn : 0;
2824 }
2825 if ( disc_read(1, g_cdvdman_fs_base2 + 0x10, g_cdvdman_fs_rbuf, arg) != 1 )
2826 {
2827 VERBOSE_PRINTF(1, "CD_newmedia: Read error in disc_read(PVD)\n");
2828 return 0;
2829 }
2830 CpuSuspendIntr(&state);
2831 for ( i = 0; i < g_cdvdman_pathtblsize; i += 1 )
2832 {
2833 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
2834 g_cdvdman_pathtbl[i].m_layer = 0;
2835 g_cdvdman_pathtbl[i].m_nsec = 0;
2836 g_cdvdman_pathtbl[i].m_lsn = 0;
2837 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
2838 }
2839 g_cache_count = 0;
2840 g_cache_table = 0;
2841 g_cache_path_size = 0;
2842 CpuResumeIntr(state);
2843 if ( strncmp((char *)((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_id, "CD001", 5) )
2844 {
2845 VERBOSE_PRINTF(1, "CD_newmedia: Disc format error in cd_read(PVD)\n");
2846 return 0;
2847 }
2848 switch ( DiskType )
2849 {
2850 case SCECdPSCD:
2851 case SCECdPSCDDA:
2852 case SCECdPS2CD:
2853 case SCECdPS2CDDA:
2854 VERBOSE_PRINTF(1, "CD_newmedia: CD Read mode\n");
2855 ptsector = *(u32 *)(((iso9660_desc_t *)g_cdvdman_fs_rbuf)->m_type_l_path_table);
2856 break;
2857 case SCECdPS2DVD:
2858 case SCECdDVDVR:
2859 case SCECdDVDV:
2860 VERBOSE_PRINTF(1, "CD_newmedia: DVD Read mode\n");
2861 ptsector = 257;
2862 break;
2863 }
2864 if ( disc_read(1, g_cdvdman_fs_base2 + ptsector, g_cdvdman_fs_rbuf, arg) != 1 )
2865 {
2866 VERBOSE_PRINTF(1, "CD_newmedia: Read error (PT:%08x)\n", ptsector);
2867 return 0;
2868 }
2869 VERBOSE_PRINTF(2, "CD_newmedia: sarching dir..\n");
2870 for ( i = 0, path_cur = (iso9660_path_t *)g_cdvdman_fs_rbuf;
2871 i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0]))
2872 && path_cur < (iso9660_path_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)] && path_cur->m_name_len[0];
2873 i += 1,
2874 path_cur = (iso9660_path_t *)(((char *)path_cur) + path_cur->m_name_len[0] + (path_cur->m_name_len[0] & 1)
2875 + sizeof(iso9660_path_t)) )
2876 {
2877 memcpy(&g_cdvdman_dirtbl[i].m_extent, path_cur->m_extent, sizeof(path_cur->m_extent));
2878 g_cdvdman_dirtbl[i].m_number = i;
2879 memcpy(&g_cdvdman_dirtbl[i].m_parent, path_cur->m_parent, sizeof(path_cur->m_parent));
2880 memcpy(g_cdvdman_dirtbl[i].m_name, path_cur->m_name, path_cur->m_name_len[0]);
2881 g_cdvdman_dirtbl[i].m_name[path_cur->m_name_len[0]] = 0;
2882 VERBOSE_PRINTF(
2883 2,
2884 "\t%08x,%04x,%04x,%s\n",
2885 g_cdvdman_dirtbl[i].m_extent,
2886 g_cdvdman_dirtbl[i].m_number,
2887 g_cdvdman_dirtbl[i].m_parent,
2888 g_cdvdman_dirtbl[i].m_name);
2889 }
2890 if ( i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) )
2891 {
2892 g_cdvdman_dirtbl[i].m_parent = 0;
2893 }
2894 g_cdvdman_fs_cdsec = 0;
2895 g_cdvdman_fs_layer = arg;
2896 VERBOSE_PRINTF(2, "CD_newmedia: %d dir entries found\n", (int)i);
2897 return 1;
2898}
2899
2900static int cdvdman_finddir(int target_parent, const char *target_name)
2901{
2902 unsigned int i;
2903
2904 for ( i = 0; i < (sizeof(g_cdvdman_dirtbl) / sizeof(g_cdvdman_dirtbl[0])) && g_cdvdman_dirtbl[i].m_parent; i += 1 )
2905 {
2906 if ( g_cdvdman_dirtbl[i].m_parent == target_parent && !strcmp(target_name, g_cdvdman_dirtbl[i].m_name) )
2907 {
2908 return i + 1;
2909 }
2910 }
2911 return -1;
2912}
2913
2914static int CD_cachefile(int dsec, int layer)
2915{
2916 iso9660_dirent_t *dirent_cur;
2917 unsigned int i;
2918
2919 if ( dsec == g_cdvdman_fs_cdsec )
2920 {
2921 return 1;
2922 }
2923 if (
2924 disc_read(1, g_cdvdman_dirtbl[dsec - 1].m_extent + (layer ? g_cdvdman_fs_base2 : 0), g_cdvdman_fs_rbuf, layer)
2925 != 1 )
2926 {
2927 VERBOSE_PRINTF(1, "CD_cachefile: dir not found\n");
2928 g_cdvdman_fs_cdsec = 0;
2929 return 0;
2930 }
2931 VERBOSE_PRINTF(2, "CD_cachefile: searching...\n");
2932 for ( i = 0, dirent_cur = (iso9660_dirent_t *)g_cdvdman_fs_rbuf;
2933 i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0]))
2934 && dirent_cur < (iso9660_dirent_t *)&g_cdvdman_fs_rbuf[sizeof(g_cdvdman_fs_rbuf)];
2935 i += 1, dirent_cur = (iso9660_dirent_t *)((char *)dirent_cur + dirent_cur->m_length[0]) )
2936 {
2937 int file_year;
2938
2939 if ( !dirent_cur->m_length[0] )
2940 {
2941 break;
2942 }
2943 memcpy(
2944 &g_cdvdman_filetbl[i].m_file_struct.lsn, dirent_cur->m_extent, sizeof(g_cdvdman_filetbl[i].m_file_struct.lsn));
2945 memcpy(
2946 &g_cdvdman_filetbl[i].m_file_struct.size, dirent_cur->m_size, sizeof(g_cdvdman_filetbl[i].m_file_struct.size));
2947 file_year = dirent_cur->m_date[0] + 1900;
2948 g_cdvdman_filetbl[i].m_file_struct.date[7] = file_year >> 8;
2949 g_cdvdman_filetbl[i].m_file_struct.date[6] = file_year;
2950 g_cdvdman_filetbl[i].m_file_struct.date[5] = dirent_cur->m_date[1];
2951 g_cdvdman_filetbl[i].m_file_struct.date[4] = dirent_cur->m_date[2];
2952 g_cdvdman_filetbl[i].m_file_struct.date[3] = dirent_cur->m_date[3];
2953 g_cdvdman_filetbl[i].m_file_struct.date[2] = dirent_cur->m_date[4];
2954 g_cdvdman_filetbl[i].m_file_struct.date[1] = dirent_cur->m_date[5];
2955 g_cdvdman_filetbl[i].m_flags = dirent_cur->m_flags[0];
2956 switch ( i )
2957 {
2958 case 0:
2959 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, ".");
2960 break;
2961 case 1:
2962 strcpy(g_cdvdman_filetbl[i].m_file_struct.name, "..");
2963 break;
2964 default:
2965 memcpy(g_cdvdman_filetbl[i].m_file_struct.name, dirent_cur->m_name, dirent_cur->m_name_len[0]);
2966 g_cdvdman_filetbl[i].m_file_struct.name[dirent_cur->m_name_len[0]] = 0;
2967 break;
2968 }
2969 VERBOSE_PRINTF(
2970 2,
2971 "\t lsn %d size %d name:%d:%s %d/%d/%d %d:%d:%d\n",
2972 (int)(g_cdvdman_filetbl[i].m_file_struct.lsn),
2973 (int)(g_cdvdman_filetbl[i].m_file_struct.size),
2974 dirent_cur->m_name_len[0],
2975 g_cdvdman_filetbl[i].m_file_struct.name,
2976 file_year,
2977 g_cdvdman_filetbl[i].m_file_struct.date[5],
2978 g_cdvdman_filetbl[i].m_file_struct.date[4],
2979 g_cdvdman_filetbl[i].m_file_struct.date[3],
2980 g_cdvdman_filetbl[i].m_file_struct.date[2],
2981 g_cdvdman_filetbl[i].m_file_struct.date[1]);
2982 }
2983 g_cdvdman_fs_cdsec = dsec;
2984 if ( i < (sizeof(g_cdvdman_filetbl) / sizeof(g_cdvdman_filetbl[0])) )
2985 {
2986 g_cdvdman_filetbl[i].m_file_struct.name[0] = 0;
2987 }
2988 VERBOSE_PRINTF(2, "CD_cachefile: %d files found\n", (int)i);
2989 return 1;
2990}
2991
2992static int disc_read(int size, int loc, void *buffer, int layer)
2993{
2994 int f;
2995 int i;
2996 sceCdRMode rmode;
2997 int has_success;
2998
2999 has_success = 1;
3000 f = 0;
3001 rmode.trycount = 16;
3002 VERBOSE_PRINTF(1, "cd_read:lsn= %d size= %d layer= %d\n", loc, size, layer);
3003 if ( cdvdman_l0check(layer) )
3004 {
3005 g_cdvdman_srchspd = 0;
3006 }
3007 switch ( g_cdvdman_srchspd )
3008 {
3009 case SCECdSpinX1:
3010 case SCECdSpinX2:
3011 case SCECdSpinX4:
3012 rmode.spindlctrl = g_cdvdman_srchspd;
3013 break;
3014 case SCECdSpinStm:
3015 case SCECdSpinNom:
3016 rmode.spindlctrl = !!g_cdvdman_srchspd;
3017 break;
3018 default:
3019 rmode.spindlctrl = SCECdSpinNom;
3020 break;
3021 }
3022 rmode.datapattern = SCECdSecS2048;
3023 if ( !g_cdvdman_pathtblflag )
3024 {
3025 has_success = 1;
3026 }
3027 if ( !has_success )
3028 {
3029 int pathcachecnt;
3030
3031 pathcachecnt = (g_cache_count < g_cdvdman_pathtblsize) ? g_cache_count : g_cdvdman_pathtblsize;
3032 for ( i = 0; i < pathcachecnt; i += 1 )
3033 {
3034 VERBOSE_KPRINTF(
3035 1,
3036 "Path table Cache Search lsn:%d:%d nsec:%d:%d layer%d:%d\n",
3037 g_cdvdman_pathtbl[i].m_lsn,
3038 loc,
3039 g_cdvdman_pathtbl[i].m_nsec,
3040 size,
3041 g_cdvdman_pathtbl[i].m_layer,
3042 layer);
3043 if (
3044 g_cdvdman_pathtbl[i].m_lsn == loc && g_cdvdman_pathtbl[i].m_nsec == (unsigned int)size
3045 && g_cdvdman_pathtbl[i].m_layer == layer )
3046 {
3047 break;
3048 }
3049 }
3050 if ( i != pathcachecnt )
3051 {
3052 VERBOSE_KPRINTF(1, "Path table Cache ON:%d\n", g_cdvdman_pathtbl[i].m_cache_path_sz);
3053 if ( lseek(g_cache_path_fd, g_cdvdman_pathtbl[i].m_cache_path_sz, 0) >= 0 )
3054 {
3055 read(g_cache_path_fd, buffer, size << 11);
3056 f = 1;
3057 g_cdvdman_pathtbl[i].m_cache_hit_count += 1;
3058 }
3059 has_success = 1;
3060 }
3061 if ( !has_success )
3062 {
3063 if ( !sceCdRE(loc, size, buffer, &rmode) )
3064 {
3065 return 0;
3066 }
3067 sceCdSync(3);
3068 }
3069 }
3070 if ( !has_success && sceCdGetError() != SCECdErNO )
3071 {
3072 int cache_path_sz;
3073
3074 if ( g_cache_count >= g_cdvdman_pathtblsize )
3075 {
3076 int cachetblo1;
3077 unsigned int cacheblo2;
3078
3079 g_cache_table += 1;
3080 if ( g_cache_table >= g_cdvdman_pathtblsize )
3081 {
3082 g_cache_table = 0;
3083 }
3084 cachetblo1 = g_cache_table;
3085 cacheblo2 = cachetblo1;
3086 for ( i = 0; (unsigned int)i < g_cache_count; i += 1 )
3087 {
3088 if ( cacheblo2 >= g_cdvdman_pathtblsize )
3089 {
3090 cacheblo2 = 0;
3091 }
3092 if (
3093 g_cdvdman_pathtbl[cacheblo2].m_nsec >= (unsigned int)size
3094 && g_cdvdman_pathtbl[cacheblo2].m_cache_hit_count
3095 < (unsigned int)g_cdvdman_pathtbl[cachetblo1].m_cache_hit_count )
3096 {
3097 cachetblo1 = cacheblo2;
3098 }
3099 cacheblo2 += 1;
3100 }
3101 cache_path_sz = g_cdvdman_pathtbl[cachetblo1].m_cache_path_sz;
3102 g_cache_table = cachetblo1;
3103 }
3104 else
3105 {
3106 cache_path_sz = g_cache_path_size;
3107 g_cache_table = g_cache_count;
3108 g_cache_count += 1;
3109 }
3110 if ( lseek(g_cache_path_fd, cache_path_sz, 0) >= 0 )
3111 {
3112 int ptbl_wcache_write_res;
3113
3114 ptbl_wcache_write_res = write(g_cache_path_fd, buffer, size << 11);
3115 if ( ptbl_wcache_write_res == size << 11 )
3116 {
3117 f = 1;
3118 g_cdvdman_pathtbl[g_cache_table].m_cache_path_sz = cache_path_sz;
3119 g_cdvdman_pathtbl[g_cache_table].m_lsn = loc;
3120 g_cdvdman_pathtbl[g_cache_table].m_nsec = size;
3121 g_cdvdman_pathtbl[g_cache_table].m_layer = layer;
3122 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
3123 g_cache_path_size += (g_cache_count < g_cdvdman_pathtblsize) ? ptbl_wcache_write_res : 0;
3124 }
3125 else
3126 {
3127 VERBOSE_KPRINTF(1, "Ptbl_WCache:write %d", ptbl_wcache_write_res);
3128 g_cdvdman_pathtbl[g_cache_table].m_cache_hit_count = 0;
3129 g_cdvdman_pathtbl[g_cache_table].m_layer = 0;
3130 g_cdvdman_pathtbl[g_cache_table].m_nsec = 0;
3131 g_cdvdman_pathtbl[g_cache_table].m_lsn = 0;
3132 }
3133 }
3134 has_success = 1;
3135 }
3136 if ( has_success )
3137 {
3138 if ( f )
3139 {
3140 return size;
3141 }
3142 if ( !sceCdRE(loc, size, buffer, &rmode) )
3143 {
3144 return 0;
3145 }
3146 sceCdSync(3);
3147 if ( sceCdGetError() != SCECdErNO )
3148 {
3149 return size;
3150 }
3151 }
3152 VERBOSE_KPRINTF(1, "cd_read: error code %x\n", sceCdGetError());
3153 return 0;
3154}
3155
3156static int path_tbl_init(u32 blocks, char *fname, int action)
3157{
3158 int num;
3159 int v;
3160 char cachedir[512];
3161 int state;
3162 u32 blocksbs;
3163
3164 num = 0;
3165 v = 0;
3166 if ( action )
3167 {
3168 CpuSuspendIntr(&state);
3169 g_cdvdman_pathtbl = (cdvdman_pathtbl_t *)AllocSysMemory(ALLOC_LAST, sizeof(cdvdman_pathtbl_t) * blocks, 0);
3170 if ( !g_cdvdman_pathtbl )
3171 {
3172 CpuResumeIntr(state);
3173 g_cdvdman_pathtblflag = 0;
3174 return -ENOMEM;
3175 }
3176 CpuResumeIntr(state);
3177 sprintf(cachedir, "%sCache_Path", fname);
3178 v = open(cachedir, O_TRUNC | O_CREAT | O_RDWR, 0x1ff /* 0o777 */);
3179 if ( v >= 0 )
3180 {
3181 u32 i;
3182
3183 g_cache_path_fd = v;
3184 if ( !strncmp(cachedir, "pfs", 3) )
3185 {
3186 blocksbs = blocks << 11;
3187 ioctl2(g_cache_path_fd, PIOCALLOC, &blocksbs, sizeof(blocksbs), 0, 0);
3188 }
3189 for ( i = 0; i < blocks; i += 1 )
3190 {
3191 v = write(g_cache_path_fd, g_cdvdman_fs_rbuf, sizeof(g_cdvdman_fs_rbuf));
3192 if ( v < 0 )
3193 {
3194 break;
3195 }
3196 }
3197 if ( v >= 0 )
3198 {
3199 CpuSuspendIntr(&state);
3200 g_cdvdman_pathtblsize = blocks;
3201 for ( i = 0; i < blocks; i += 1 )
3202 {
3203 g_cdvdman_pathtbl[i].m_cache_hit_count = 0;
3204 g_cdvdman_pathtbl[i].m_layer = 0;
3205 g_cdvdman_pathtbl[i].m_nsec = 0;
3206 g_cdvdman_pathtbl[i].m_lsn = 0;
3207 g_cdvdman_pathtbl[i].m_cache_path_sz = 0;
3208 }
3209 g_cache_path_size = 0;
3210 g_cache_count = 0;
3211 g_cache_table = 0;
3212 g_cdvdman_pathtblflag = 1;
3213 CpuResumeIntr(state);
3214 return 0;
3215 }
3216 }
3217 }
3218 if ( g_cache_path_fd != -1 )
3219 {
3220 num = close(g_cache_path_fd);
3221 if ( num >= 0 )
3222 {
3223 if ( !strncmp(cachedir, "pfs", 3) )
3224 {
3225 num = remove(cachedir);
3226 }
3227 else if ( !strncmp(cachedir, "host", 4) )
3228 {
3229 num = 0;
3230 remove(cachedir);
3231 }
3232 }
3233 }
3234 CpuSuspendIntr(&state);
3235 g_cache_path_fd = -1;
3236 g_cache_count = 0;
3237 g_cache_table = 0;
3238 g_cache_path_size = 0;
3239 g_cdvdman_pathtblflag = 0;
3240 g_cdvdman_pathtblsize = 0;
3241 FreeSysMemory(g_cdvdman_pathtbl);
3242 g_cdvdman_pathtbl = 0;
3243 CpuResumeIntr(state);
3244 if ( v < 0 )
3245 {
3246 VERBOSE_KPRINTF(1, "path_tbl_init Error %d\n", v);
3247 }
3248 return (!action) ? num : v;
3249}
3250
3251// Unofficial: unused obfuscation code was removed
3252
3253// clang-format off
3254__asm__ (
3255 "\t" ".set push" "\n"
3256 "\t" ".set noat" "\n"
3257 "\t" ".set noreorder" "\n"
3258 "\t" ".global optimized_memcpy" "\n"
3259 "\t" "optimized_memcpy:" "\n"
3260 "\t" " srl $a3, $a2, 2" "\n"
3261 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3262 "\t" " or $a3, $a0, $a1" "\n"
3263 "\t" " andi $a3, $a3, 0x3" "\n"
3264 "\t" " bnez $a3, .Loptimized_memcpy_3" "\n"
3265 "\t" " nop" "\n"
3266 "\t" " srl $a3, $a2, 2" "\n"
3267 "\t" " addiu $at, $zero, 0xC" "\n"
3268 "\t" " div $zero, $a3, $at" "\n"
3269 "\t" " mflo $a3" "\n"
3270 "\t" " mfhi $v1" "\n"
3271 "\t" " beqz $v1, .Loptimized_memcpy_2" "\n"
3272 "\t" " nop" "\n"
3273 "\t" ".Loptimized_memcpy_1:" "\n"
3274 "\t" " lw $v0, 0x0($a1)" "\n"
3275 "\t" " addiu $v1, $v1, -0x1" "\n"
3276 "\t" " sw $v0, 0x0($a0)" "\n"
3277 "\t" " addiu $a1, $a1, 0x4" "\n"
3278 "\t" " bnez $v1, .Loptimized_memcpy_1" "\n"
3279 "\t" " addiu $a0, $a0, 0x4" "\n"
3280 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3281 "\t" " nop" "\n"
3282 "\t" ".Loptimized_memcpy_2:" "\n"
3283 "\t" " lw $v0, 0x0($a1)" "\n"
3284 "\t" " lw $v1, 0x4($a1)" "\n"
3285 "\t" " lw $t0, 0x8($a1)" "\n"
3286 "\t" " lw $t1, 0xC($a1)" "\n"
3287 "\t" " lw $t2, 0x10($a1)" "\n"
3288 "\t" " lw $t3, 0x14($a1)" "\n"
3289 "\t" " lw $t4, 0x18($a1)" "\n"
3290 "\t" " lw $t5, 0x1C($a1)" "\n"
3291 "\t" " lw $t6, 0x20($a1)" "\n"
3292 "\t" " lw $t7, 0x24($a1)" "\n"
3293 "\t" " lw $t8, 0x28($a1)" "\n"
3294 "\t" " lw $t9, 0x2C($a1)" "\n"
3295 "\t" " addiu $a3, $a3, -0x1" "\n"
3296 "\t" " sw $v0, 0x0($a0)" "\n"
3297 "\t" " sw $v1, 0x4($a0)" "\n"
3298 "\t" " sw $t0, 0x8($a0)" "\n"
3299 "\t" " sw $t1, 0xC($a0)" "\n"
3300 "\t" " sw $t2, 0x10($a0)" "\n"
3301 "\t" " sw $t3, 0x14($a0)" "\n"
3302 "\t" " sw $t4, 0x18($a0)" "\n"
3303 "\t" " sw $t5, 0x1C($a0)" "\n"
3304 "\t" " sw $t6, 0x20($a0)" "\n"
3305 "\t" " sw $t7, 0x24($a0)" "\n"
3306 "\t" " sw $t8, 0x28($a0)" "\n"
3307 "\t" " sw $t9, 0x2C($a0)" "\n"
3308 "\t" " addiu $a1, $a1, 0x30" "\n"
3309 "\t" " bnez $a3, .Loptimized_memcpy_2" "\n"
3310 "\t" " addiu $a0, $a0, 0x30" "\n"
3311 "\t" " j .Loptimized_memcpy_12" "\n"
3312 "\t" " nop" "\n"
3313 "\t" ".Loptimized_memcpy_3:" "\n"
3314 "\t" " andi $a3, $a0, 0x3" "\n"
3315 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3316 "\t" " andi $a3, $a1, 0x3" "\n"
3317 "\t" " beqz $a3, .Loptimized_memcpy_6" "\n"
3318 "\t" " nop" "\n"
3319 "\t" " srl $a3, $a2, 2" "\n"
3320 "\t" " addiu $at, $zero, 0xC" "\n"
3321 "\t" " div $zero, $a3, $at" "\n"
3322 "\t" " mflo $a3" "\n"
3323 "\t" " mfhi $v1" "\n"
3324 "\t" " beqz $v1, .Loptimized_memcpy_5" "\n"
3325 "\t" " nop" "\n"
3326 "\t" ".Loptimized_memcpy_4:" "\n"
3327 "\t" " lwl $v0, 0x3($a1)" "\n"
3328 "\t" " lwr $v0, 0x0($a1)" "\n"
3329 "\t" " addiu $v1, $v1, -0x1" "\n"
3330 "\t" " swl $v0, 0x3($a0)" "\n"
3331 "\t" " swr $v0, 0x0($a0)" "\n"
3332 "\t" " addiu $a1, $a1, 0x4" "\n"
3333 "\t" " bnez $v1, .Loptimized_memcpy_4" "\n"
3334 "\t" " addiu $a0, $a0, 0x4" "\n"
3335 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3336 "\t" " nop" "\n"
3337 "\t" ".Loptimized_memcpy_5:" "\n"
3338 "\t" " lwl $v0, 0x3($a1)" "\n"
3339 "\t" " lwr $v0, 0x0($a1)" "\n"
3340 "\t" " lwl $v1, 0x7($a1)" "\n"
3341 "\t" " lwr $v1, 0x4($a1)" "\n"
3342 "\t" " lwl $t0, 0xB($a1)" "\n"
3343 "\t" " lwr $t0, 0x8($a1)" "\n"
3344 "\t" " lwl $t1, 0xF($a1)" "\n"
3345 "\t" " lwr $t1, 0xC($a1)" "\n"
3346 "\t" " lwl $t2, 0x13($a1)" "\n"
3347 "\t" " lwr $t2, 0x10($a1)" "\n"
3348 "\t" " lwl $t3, 0x17($a1)" "\n"
3349 "\t" " lwr $t3, 0x14($a1)" "\n"
3350 "\t" " lwl $t4, 0x1B($a1)" "\n"
3351 "\t" " lwr $t4, 0x18($a1)" "\n"
3352 "\t" " lwl $t5, 0x1F($a1)" "\n"
3353 "\t" " lwr $t5, 0x1C($a1)" "\n"
3354 "\t" " lwl $t6, 0x23($a1)" "\n"
3355 "\t" " lwr $t6, 0x20($a1)" "\n"
3356 "\t" " lwl $t7, 0x27($a1)" "\n"
3357 "\t" " lwr $t7, 0x24($a1)" "\n"
3358 "\t" " lwl $t8, 0x2B($a1)" "\n"
3359 "\t" " lwr $t8, 0x28($a1)" "\n"
3360 "\t" " lwl $t9, 0x2F($a1)" "\n"
3361 "\t" " lwr $t9, 0x2C($a1)" "\n"
3362 "\t" " addiu $a3, $a3, -0x1" "\n"
3363 "\t" " swl $v0, 0x3($a0)" "\n"
3364 "\t" " swr $v0, 0x0($a0)" "\n"
3365 "\t" " swl $v1, 0x7($a0)" "\n"
3366 "\t" " swr $v1, 0x4($a0)" "\n"
3367 "\t" " swl $t0, 0xB($a0)" "\n"
3368 "\t" " swr $t0, 0x8($a0)" "\n"
3369 "\t" " swl $t1, 0xF($a0)" "\n"
3370 "\t" " swr $t1, 0xC($a0)" "\n"
3371 "\t" " swl $t2, 0x13($a0)" "\n"
3372 "\t" " swr $t2, 0x10($a0)" "\n"
3373 "\t" " swl $t3, 0x17($a0)" "\n"
3374 "\t" " swr $t3, 0x14($a0)" "\n"
3375 "\t" " swl $t4, 0x1B($a0)" "\n"
3376 "\t" " swr $t4, 0x18($a0)" "\n"
3377 "\t" " swl $t5, 0x1F($a0)" "\n"
3378 "\t" " swr $t5, 0x1C($a0)" "\n"
3379 "\t" " swl $t6, 0x23($a0)" "\n"
3380 "\t" " swr $t6, 0x20($a0)" "\n"
3381 "\t" " swl $t7, 0x27($a0)" "\n"
3382 "\t" " swr $t7, 0x24($a0)" "\n"
3383 "\t" " swl $t8, 0x2B($a0)" "\n"
3384 "\t" " swr $t8, 0x28($a0)" "\n"
3385 "\t" " swl $t9, 0x2F($a0)" "\n"
3386 "\t" " swr $t9, 0x2C($a0)" "\n"
3387 "\t" " addiu $a1, $a1, 0x30" "\n"
3388 "\t" " bnez $a3, .Loptimized_memcpy_5" "\n"
3389 "\t" " addiu $a0, $a0, 0x30" "\n"
3390 "\t" " j .Loptimized_memcpy_12" "\n"
3391 "\t" " nop" "\n"
3392 "\t" ".Loptimized_memcpy_6:" "\n"
3393 "\t" " andi $a3, $a0, 0x3" "\n"
3394 "\t" " beqz $a3, .Loptimized_memcpy_9" "\n"
3395 "\t" " nop" "\n"
3396 "\t" " srl $a3, $a2, 2" "\n"
3397 "\t" " addiu $at, $zero, 0xC" "\n"
3398 "\t" " div $zero, $a3, $at" "\n"
3399 "\t" " mflo $a3" "\n"
3400 "\t" " mfhi $v1" "\n"
3401 "\t" " beqz $v1, .Loptimized_memcpy_8" "\n"
3402 "\t" " nop" "\n"
3403 "\t" ".Loptimized_memcpy_7:" "\n"
3404 "\t" " lw $v0, 0x0($a1)" "\n"
3405 "\t" " addiu $v1, $v1, -0x1" "\n"
3406 "\t" " swl $v0, 0x3($a0)" "\n"
3407 "\t" " swr $v0, 0x0($a0)" "\n"
3408 "\t" " addiu $a1, $a1, 0x4" "\n"
3409 "\t" " bnez $v1, .Loptimized_memcpy_7" "\n"
3410 "\t" " addiu $a0, $a0, 0x4" "\n"
3411 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3412 "\t" " nop" "\n"
3413 "\t" ".Loptimized_memcpy_8:" "\n"
3414 "\t" " lw $v0, 0x0($a1)" "\n"
3415 "\t" " lw $v1, 0x4($a1)" "\n"
3416 "\t" " lw $t0, 0x8($a1)" "\n"
3417 "\t" " lw $t1, 0xC($a1)" "\n"
3418 "\t" " lw $t2, 0x10($a1)" "\n"
3419 "\t" " lw $t3, 0x14($a1)" "\n"
3420 "\t" " lw $t4, 0x18($a1)" "\n"
3421 "\t" " lw $t5, 0x1C($a1)" "\n"
3422 "\t" " lw $t6, 0x20($a1)" "\n"
3423 "\t" " lw $t7, 0x24($a1)" "\n"
3424 "\t" " lw $t8, 0x28($a1)" "\n"
3425 "\t" " lw $t9, 0x2C($a1)" "\n"
3426 "\t" " addiu $a3, $a3, -0x1" "\n"
3427 "\t" " swl $v0, 0x3($a0)" "\n"
3428 "\t" " swr $v0, 0x0($a0)" "\n"
3429 "\t" " swl $v1, 0x7($a0)" "\n"
3430 "\t" " swr $v1, 0x4($a0)" "\n"
3431 "\t" " swl $t0, 0xB($a0)" "\n"
3432 "\t" " swr $t0, 0x8($a0)" "\n"
3433 "\t" " swl $t1, 0xF($a0)" "\n"
3434 "\t" " swr $t1, 0xC($a0)" "\n"
3435 "\t" " swl $t2, 0x13($a0)" "\n"
3436 "\t" " swr $t2, 0x10($a0)" "\n"
3437 "\t" " swl $t3, 0x17($a0)" "\n"
3438 "\t" " swr $t3, 0x14($a0)" "\n"
3439 "\t" " swl $t4, 0x1B($a0)" "\n"
3440 "\t" " swr $t4, 0x18($a0)" "\n"
3441 "\t" " swl $t5, 0x1F($a0)" "\n"
3442 "\t" " swr $t5, 0x1C($a0)" "\n"
3443 "\t" " swl $t6, 0x23($a0)" "\n"
3444 "\t" " swr $t6, 0x20($a0)" "\n"
3445 "\t" " swl $t7, 0x27($a0)" "\n"
3446 "\t" " swr $t7, 0x24($a0)" "\n"
3447 "\t" " swl $t8, 0x2B($a0)" "\n"
3448 "\t" " swr $t8, 0x28($a0)" "\n"
3449 "\t" " swl $t9, 0x2F($a0)" "\n"
3450 "\t" " swr $t9, 0x2C($a0)" "\n"
3451 "\t" " addiu $a1, $a1, 0x30" "\n"
3452 "\t" " bnez $a3, .Loptimized_memcpy_8" "\n"
3453 "\t" " addiu $a0, $a0, 0x30" "\n"
3454 "\t" " j .Loptimized_memcpy_12" "\n"
3455 "\t" " nop" "\n"
3456 "\t" ".Loptimized_memcpy_9:" "\n"
3457 "\t" " srl $a3, $a2, 2" "\n"
3458 "\t" " addiu $at, $zero, 0xC" "\n"
3459 "\t" " div $zero, $a3, $at" "\n"
3460 "\t" " mflo $a3" "\n"
3461 "\t" " mfhi $v1" "\n"
3462 "\t" " beqz $v1, .Loptimized_memcpy_11" "\n"
3463 "\t" " nop" "\n"
3464 "\t" ".Loptimized_memcpy_10:" "\n"
3465 "\t" " lwl $v0, 0x3($a1)" "\n"
3466 "\t" " lwr $v0, 0x0($a1)" "\n"
3467 "\t" " addiu $v1, $v1, -0x1" "\n"
3468 "\t" " sw $v0, 0x0($a0)" "\n"
3469 "\t" " addiu $a1, $a1, 0x4" "\n"
3470 "\t" " bnez $v1, .Loptimized_memcpy_10" "\n"
3471 "\t" " addiu $a0, $a0, 0x4" "\n"
3472 "\t" " beqz $a3, .Loptimized_memcpy_12" "\n"
3473 "\t" " nop" "\n"
3474 "\t" ".Loptimized_memcpy_11:" "\n"
3475 "\t" " lwl $v0, 0x3($a1)" "\n"
3476 "\t" " lwr $v0, 0x0($a1)" "\n"
3477 "\t" " lwl $v1, 0x7($a1)" "\n"
3478 "\t" " lwr $v1, 0x4($a1)" "\n"
3479 "\t" " lwl $t0, 0xB($a1)" "\n"
3480 "\t" " lwr $t0, 0x8($a1)" "\n"
3481 "\t" " lwl $t1, 0xF($a1)" "\n"
3482 "\t" " lwr $t1, 0xC($a1)" "\n"
3483 "\t" " lwl $t2, 0x13($a1)" "\n"
3484 "\t" " lwr $t2, 0x10($a1)" "\n"
3485 "\t" " lwl $t3, 0x17($a1)" "\n"
3486 "\t" " lwr $t3, 0x14($a1)" "\n"
3487 "\t" " lwl $t4, 0x1B($a1)" "\n"
3488 "\t" " lwr $t4, 0x18($a1)" "\n"
3489 "\t" " lwl $t5, 0x1F($a1)" "\n"
3490 "\t" " lwr $t5, 0x1C($a1)" "\n"
3491 "\t" " lwl $t6, 0x23($a1)" "\n"
3492 "\t" " lwr $t6, 0x20($a1)" "\n"
3493 "\t" " lwl $t7, 0x27($a1)" "\n"
3494 "\t" " lwr $t7, 0x24($a1)" "\n"
3495 "\t" " lwl $t8, 0x2B($a1)" "\n"
3496 "\t" " lwr $t8, 0x28($a1)" "\n"
3497 "\t" " lwl $t9, 0x2F($a1)" "\n"
3498 "\t" " lwr $t9, 0x2C($a1)" "\n"
3499 "\t" " addiu $a3, $a3, -0x1" "\n"
3500 "\t" " sw $v0, 0x0($a0)" "\n"
3501 "\t" " sw $v1, 0x4($a0)" "\n"
3502 "\t" " sw $t0, 0x8($a0)" "\n"
3503 "\t" " sw $t1, 0xC($a0)" "\n"
3504 "\t" " sw $t2, 0x10($a0)" "\n"
3505 "\t" " sw $t3, 0x14($a0)" "\n"
3506 "\t" " sw $t4, 0x18($a0)" "\n"
3507 "\t" " sw $t5, 0x1C($a0)" "\n"
3508 "\t" " sw $t6, 0x20($a0)" "\n"
3509 "\t" " sw $t7, 0x24($a0)" "\n"
3510 "\t" " sw $t8, 0x28($a0)" "\n"
3511 "\t" " sw $t9, 0x2C($a0)" "\n"
3512 "\t" " addiu $a1, $a1, 0x30" "\n"
3513 "\t" " bnez $a3, .Loptimized_memcpy_11" "\n"
3514 "\t" " addiu $a0, $a0, 0x30" "\n"
3515 "\t" ".Loptimized_memcpy_12:" "\n"
3516 "\t" " andi $v1, $a2, 0x3" "\n"
3517 "\t" " beqz $v1, .Loptimized_memcpy_14" "\n"
3518 "\t" " nop" "\n"
3519 "\t" ".Loptimized_memcpy_13:" "\n"
3520 "\t" " lb $v0, 0x0($a1)" "\n"
3521 "\t" " addiu $v1, $v1, -0x1" "\n"
3522 "\t" " sb $v0, 0x0($a0)" "\n"
3523 "\t" " addiu $a1, $a1, 0x1" "\n"
3524 "\t" " bnez $v1, .Loptimized_memcpy_13" "\n"
3525 "\t" " addiu $a0, $a0, 0x1" "\n"
3526 "\t" ".Loptimized_memcpy_14:" "\n"
3527 "\t" " addu $v0, $a2, $zero" "\n"
3528 "\t" " jr $ra" "\n"
3529 "\t" " nop" "\n"
3530 "\t" ".set pop" "\n"
3531);
3532// clang-format on
3533
3534#ifdef DEAD_CODE
3535void hex_dump(u8 *addr_start, int length)
3536{
3537 int i;
3538
3539 KPRINTF("Hex Dump addr %08x\n", addr_start);
3540 for ( i = 0; i < length; i += 1 )
3541 {
3542 if ( !(i & 0xF) && i )
3543 {
3544 PRINTF("\n");
3545 }
3546 KPRINTF(" %02x", addr_start[i]);
3547 }
3548 KPRINTF("\n");
3549}
3550#endif
3551
3552static int cdvdman_initcfg(void)
3553{
3554 int i;
3555 u8 m_version[5];
3556 u32 eflag;
3557
3558 eflag = 0;
3559 for ( i = 0; i <= 100; i += 1 )
3560 {
3561 unsigned int mvored;
3562
3563#ifdef CDVD_VARIANT_XOSD
3564 if ( !sceCdMV(m_version, &eflag) )
3565#else
3566 if ( !sceCdMV(m_version, &eflag) && (eflag & 0x80) )
3567#endif
3568 {
3569 vDelayThread(2000);
3570 VERBOSE_KPRINTF(1, "_sceCdMV error\n");
3571 }
3572 mvored = m_version[3] | (m_version[2] << 8) | (m_version[1] << 16);
3573 g_cdvdman_emudvd9 = m_version[2] & 1;
3574 VERBOSE_KPRINTF(1, "MV %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3575 g_cdvdman_minver_10700 = mvored >= 0x10700;
3576 g_cdvdman_minver_20200 = mvored >= 0x20200;
3577 g_cdvdman_minver_20400 = mvored >= 0x20400;
3578 g_cdvdman_minver_20800 = mvored >= 0x20800;
3579 g_cdvdman_minver_50000 = mvored >= 0x50000;
3580 g_cdvdman_minver_50200 = mvored >= 0x50200;
3581 g_cdvdman_minver_50400 = mvored >= 0x50400;
3582 g_cdvdman_minver_50600 = mvored >= 0x50600;
3583#ifdef CDVD_VARIANT_XOSD
3584 VERBOSE_KPRINTF(0, "M Version %02x %02x %02x %02x\n", m_version[0], m_version[1], m_version[2], m_version[3]);
3585 if ( cdvdman_get_renewal_date(m_version, &eflag) )
3586 {
3587 VERBOSE_KPRINTF(
3588 0,
3589 "M Renewal Date 20%02x/%02x/%02x %02x:%02x\n",
3590 m_version[0],
3591 m_version[1],
3592 m_version[2],
3593 m_version[3],
3594 m_version[4]);
3595 }
3596 g_cdvdman_vernotxxx1x = 0;
3597 if ( g_cdvdman_minver_50600 )
3598 {
3599 // cdvdman_verxxxx1 = (mvored & 0xF) == 1; // not referenced!
3600 KPRINTF("X_model ");
3601 switch ( mvored & 0xF0 )
3602 {
3603 case 0x00:
3604 KPRINTF("量産 OR 量産試作機\n");
3605 break;
3606 case 0x10:
3607 KPRINTF("原理試作機\n");
3608 g_cdvdman_vernotxxx1x = 1;
3609 break;
3610 case 0x20:
3611 KPRINTF("手作り試作機\n");
3612 break;
3613 case 0x30:
3614 KPRINTF("型物試作機\n");
3615 break;
3616 default:
3617 KPRINTF("Unkown\n");
3618 break;
3619 }
3620 }
3621 else
3622 {
3623 KPRINTF("X_model 旧原理試作機 Ver5.6未満 Found\n");
3624 }
3625#endif
3626 g_cdvdman_minver_x_model_15 = (mvored & 0xF) == 1;
3627 g_cdvdman_minver_60000 = mvored >= 0x60000;
3628 g_cdvdman_minver_60200 = mvored >= 0x60200;
3629#ifdef CDVD_VARIANT_OSD
3630 g_cdvdman_minver_60600 = mvored >= 0x60600;
3631#endif
3632 return 1;
3633 }
3634 return 0;
3635}
3636
3637static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *arg), void *arg)
3638{
3639 return (QueryIntrContext() ? iSetAlarm : SetAlarm)(sys_clock, alarm_cb, arg);
3640}
3641
3642static int vCancelAlarm(unsigned int (*alarm_cb)(void *arg), void *arg)
3643{
3644 return (QueryIntrContext() ? iCancelAlarm : CancelAlarm)(alarm_cb, arg);
3645}
3646
3647#ifdef DEAD_CODE
3648s32 vSignalSema(s32 sema_id)
3649{
3650 return (QueryIntrContext() ? iSignalSema : SignalSema)(sema_id);
3651}
3652#endif
3653
3654static int vSetEventFlag(int ef, u32 bits)
3655{
3656 return (QueryIntrContext() ? iSetEventFlag : SetEventFlag)(ef, bits);
3657}
3658
3659static int vClearEventFlag(int ef, u32 bits)
3660{
3661 return (QueryIntrContext() ? iClearEventFlag : ClearEventFlag)(ef, bits);
3662}
3663
3664static int vReferEventFlagStatus(int ef, iop_event_info_t *info)
3665{
3666 return (QueryIntrContext() ? iReferEventFlagStatus : ReferEventFlagStatus)(ef, info);
3667}
3668
3669static int vPollEventFlag(int ef, u32 bits, int mode, u32 *efbits)
3670{
3671#ifdef CDVD_VARIANT_XOSD
3672 int retres;
3673 iop_event_info_t efinfo;
3674
3675 if ( !QueryIntrContext() )
3676 {
3677 return PollEventFlag(ef, bits, mode, efbits);
3678 }
3679 retres = iReferEventFlagStatus(ef, &efinfo);
3680 if ( retres )
3681 {
3682 return retres;
3683 }
3684 *efbits = efinfo.currBits;
3685 if ( (mode & 1) ? !(efinfo.currBits & bits) : ((efinfo.currBits & bits) != bits) )
3686 {
3687 return KE_EVF_COND;
3688 }
3689 if ( mode & 0x10 )
3690 {
3691 iClearEventFlag(ef, ~bits);
3692 }
3693 return 0;
3694#else
3695 return PollEventFlag(ef, bits, mode, efbits);
3696#endif
3697}
3698
3699static int vDelayThread(int usec)
3700{
3701 int intrval;
3702 int state;
3703
3704 intrval = CpuSuspendIntr(&state);
3705 CpuResumeIntr(state);
3706 return (!QueryIntrContext() && !intrval) ? DelayThread(usec) : 0;
3707}
3708
3709#ifdef CDVD_VARIANT_XOSD
3710static int get_cdvd_register(int regnr)
3711{
3712 int intrres;
3713 int IntrContext;
3714 int regval;
3715 iop_event_info_t efinfo;
3716 int state;
3717 u32 efbits;
3718
3719 intrres = CpuSuspendIntr(&state);
3720 CpuResumeIntr(state);
3721 IntrContext = QueryIntrContext();
3722 if ( !IntrContext && !intrres )
3723 {
3724 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3725 CpuSuspendIntr(&state);
3726 }
3727 else
3728 {
3729 if ( IntrContext )
3730 {
3731 iReferEventFlagStatus(g_cdvdman_csys_evfid, &efinfo);
3732 }
3733 else
3734 {
3735 ReferEventFlagStatus(g_cdvdman_csys_evfid, &efinfo);
3736 }
3737 if ( !(efinfo.currBits & 1) )
3738 {
3739 return -1;
3740 }
3741 }
3742 if ( update_cd_mode_ps2_atapi() != 1 )
3743 {
3744 regval = ((vu8 *)(0xBF402000))[regnr];
3745 }
3746 else
3747 {
3748 if ( !IntrContext && !intrres )
3749 {
3750 CpuResumeIntr(state);
3751 if ( g_cd_atapi_evfid != -1 )
3752 {
3753 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
3754 }
3755 if ( g_adma_evfid != -1 )
3756 {
3757 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3758 }
3759 if ( g_acmd_evfid != -1 )
3760 {
3761 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
3762 }
3763 CpuSuspendIntr(&state);
3764 }
3765 else
3766 {
3767 if ( g_cd_atapi_evfid != -1 )
3768 {
3769 if ( IntrContext )
3770 {
3771 iReferEventFlagStatus(g_cd_atapi_evfid, &efinfo);
3772 }
3773 else
3774 {
3775 ReferEventFlagStatus(g_cd_atapi_evfid, &efinfo);
3776 }
3777 if ( !(efinfo.currBits & 3) )
3778 {
3779 return -1;
3780 }
3781 }
3782 if ( g_adma_evfid != -1 )
3783 {
3784 if ( IntrContext )
3785 {
3786 iReferEventFlagStatus(g_adma_evfid, &efinfo);
3787 }
3788 else
3789 {
3790 ReferEventFlagStatus(g_adma_evfid, &efinfo);
3791 }
3792 if ( !(efinfo.currBits & 1) )
3793 {
3794 return -1;
3795 }
3796 }
3797 if ( g_acmd_evfid != -1 )
3798 {
3799 if ( IntrContext )
3800 {
3801 iReferEventFlagStatus(g_acmd_evfid, &efinfo);
3802 }
3803 else
3804 {
3805 ReferEventFlagStatus(g_acmd_evfid, &efinfo);
3806 }
3807 }
3808 if ( !(efinfo.currBits & 1) )
3809 {
3810 return -1;
3811 }
3812 }
3813 set_cdvd_dev5_base_addr_atapi(2);
3814 regval = ((vu8 *)(0xBF402000))[regnr];
3815 set_cdvd_dev5_base_addr_atapi(1);
3816 if ( !IntrContext && !intrres )
3817 {
3818 if ( g_acmd_evfid != -1 )
3819 {
3820 SetEventFlag(g_acmd_evfid, 1);
3821 }
3822 if ( g_adma_evfid != -1 )
3823 {
3824 SetEventFlag(g_adma_evfid, 1);
3825 }
3826 if ( g_cd_atapi_evfid != -1 )
3827 {
3828 SetEventFlag(g_cd_atapi_evfid, 3);
3829 }
3830 }
3831 }
3832 if ( !IntrContext && !intrres )
3833 {
3834 CpuResumeIntr(state);
3835 SetEventFlag(g_cdvdman_csys_evfid, 1);
3836 }
3837 return regval;
3838}
3839#endif
3840
3841// cppcheck-suppress constParameterCallback
3842static unsigned int read_timeout_alarm_cb(void *userdata)
3843{
3844 int read_timeout;
3845 const iop_sys_clock_t *sys_clock;
3846
3847 sys_clock = (const iop_sys_clock_t *)userdata;
3848 read_timeout = sys_clock->lo / 0x9000;
3849 KPRINTF("Read Time Out %d(msec)\n", read_timeout);
3850 sceCdSC(0xFFFFFFEE, &read_timeout);
3851 return !sceCdBreak();
3852}
3853
3855{
3856 sceCdCBFunc rc;
3857 u32 efbits;
3858
3859 if ( sceCdSync(1) || PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
3860 {
3861 return 0;
3862 }
3863 rc = g_cdvdman_user_cb;
3864 g_cdvdman_user_cb = function;
3865 vSetEventFlag(g_ncmd_evfid, 1);
3866 return rc;
3867}
3868
3869// cppcheck-suppress funcArgNamesDifferent
3870void *sceCdPOffCallback(void (*func)(void *userdata), void *userdata)
3871{
3872 void *old_cb;
3873 int state;
3874
3875 CpuSuspendIntr(&state);
3876 old_cb = g_cdvdman_power_off_callback;
3877 g_cdvdman_power_off_callback = func;
3878 g_cdvdman_power_off_callback_userdata = userdata;
3879 CpuResumeIntr(state);
3880 return old_cb;
3881}
3882
3883#ifdef CDVD_VARIANT_XOSD
3884void *sceCdSetAtapiEjectCallback(int (*func)(int reason, void *userdata), void *userdata)
3885{
3886 void *old_cb;
3887 int state;
3888
3889 CpuSuspendIntr(&state);
3890 old_cb = g_cdvdman_atapi_eject_bs_power_callback;
3891 g_cdvdman_atapi_eject_bs_power_callback = func;
3892 g_cdvdman_atapi_eject_bs_power_callback_userdata = userdata;
3893 CpuResumeIntr(state);
3894 return old_cb;
3895}
3896#endif
3897
3898int sceCdstm0Cb(void (*p)(int val))
3899{
3900 g_cdvdman_cdstm0cb = p;
3901 return 0;
3902}
3903
3904int sceCdstm1Cb(void (*p)(int val))
3905{
3906 g_cdvdman_cdstm1cb = p;
3907 return 0;
3908}
3909
3910static int cdvdman_intr_cb(cdvdman_internal_struct_t *s)
3911{
3912 sceCdRMode cdrmode;
3913 int oldstate;
3914 int ext_passthrough;
3915 USE_DEV5_MMIO_HWPORT();
3916
3917 ext_passthrough = 0;
3918 s->m_wait_flag = s->m_waf_set_test;
3919 iSetEventFlag(g_cdvdman_intr_evfid, 0x29);
3920 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
3921 if ( s->m_cdvdman_command == SCECdFuncStandby && s->m_last_error == SCECdErTRMOPN )
3922 {
3923 s->m_last_error = (sceCdStatus() == SCECdErFAIL) ? SCECdErTRMOPN : SCECdErNO;
3924 }
3925 if ( s->m_last_error == SCECdErEOM )
3926 {
3927 s->m_last_error = SCECdErNO;
3928 }
3929 VERBOSE_KPRINTF(
3930 1, "Intr call func_num: %d Err= %02x OnTout= %d\n", g_cdvdman_cmdfunc, (u8)s->m_last_error, s->m_last_read_timeout);
3931 if ( !s->m_scmd_flag )
3932 {
3933 cdvdman_write_scmd(s);
3934 }
3935 if (
3936 (((u8)s->m_last_error == SCECdErREAD && g_cdvdman_cmdfunc == SCECdFuncRead)
3937 || ((u8)s->m_last_error == SCECdErABRT && s->m_last_read_timeout && g_cdvdman_last_cmdfunc == SCECdFuncRead))
3938 && !g_cdvdman_minver_20200 && !s->m_stream_flag && !s->m_dvd_flag && !s->m_recover_status
3939 && s->m_read_mode.trycount != 1 )
3940 {
3941 s->m_sync_error = 0;
3942 s->m_interupt_read_state = 0;
3943 if ( s->m_dec_mode_set )
3944 {
3945 s->m_dec_mode_last_set = 1;
3946 }
3947 else
3948 {
3949 VERBOSE_KPRINTF(1, "dec mode 0x00\n");
3950 s->m_read_chunk_reprocial_32 = 1 + (0x20 / ((!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk));
3951 s->m_dintrlsn = (s->m_read_lsn < 0x61) ? (s->m_read_lsn + s->m_read_sectors + 48) : (s->m_read_lsn - 80);
3952 s->m_read_mode.spindlctrl = 16;
3953 if ( !sceCdRead0_Rty(
3954 s->m_dintrlsn,
3955 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
3956 s->m_read_buf,
3957 &s->m_read_mode,
3958 (u8)s->m_cdvdman_command,
3959 0,
3960 0) )
3961 {
3962 s->m_last_error = SCECdErREAD;
3963 s->m_recover_status = 0;
3964 }
3965 else
3966 {
3967 ext_passthrough = 1;
3968 }
3969 }
3970 }
3971 if ( !ext_passthrough )
3972 {
3973 char dev5_reg_013_masked;
3974
3975 VERBOSE_KPRINTF(1, "Recover_Stat:%d\n", s->m_recover_status);
3976 dev5_reg_013_masked = dev5_mmio_hwport->m_dev5_reg_013 & 0xF;
3977 if ( dev5_reg_013_masked )
3978 {
3979 if (
3980 ((u8)s->m_last_error == SCECdErREAD || ((u8)s->m_last_error == SCECdErABRT && s->m_last_read_timeout))
3981 && !s->m_recover_status && !s->m_stream_flag && g_cdvdman_cmdfunc != 9 && g_cdvdman_cmdfunc != SCECdFuncReadCDDA
3982 && (unsigned int)s->m_read_mode.trycount - 1 >= 4 )
3983 {
3984 s->m_sync_error = 0;
3985 s->m_interupt_read_state = 0;
3986 if ( s->m_dec_mode_set )
3987 {
3988 s->m_dec_mode_last_set = 2;
3989 }
3990 else
3991 {
3992 VERBOSE_KPRINTF(1, "dec mode 0x01\n");
3993 cdrmode.trycount = s->m_read_mode.trycount;
3994 cdrmode.spindlctrl = dev5_reg_013_masked + 13;
3995 cdrmode.datapattern = s->m_read_mode.datapattern;
3996 if ( sceCdRead0_Rty(
3997 s->m_read_lsn,
3998 s->m_read_sectors,
3999 s->m_read_buf,
4000 &cdrmode,
4001 (u8)s->m_cdvdman_command,
4002 s->m_read_chunk,
4003 s->m_read_callback) )
4004 {
4005 s->m_last_error = SCECdErNO;
4006 return 1;
4007 }
4008 s->m_last_error = SCECdErREAD;
4009 }
4010 }
4011 }
4012 s->m_last_read_timeout = 0;
4013 switch ( s->m_recover_status )
4014 {
4015 case 1:
4016 s->m_sync_error = 0;
4017 s->m_interupt_read_state = 0;
4018 if (
4019 s->m_last_error != SCECdErNO
4020 || !sceCdRead0_Rty(
4021 s->m_dintrlsn,
4022 (!s->m_read_chunk) ? s->m_read_sectors : s->m_read_chunk,
4023 s->m_read_buf,
4024 &s->m_read_mode,
4025 (u8)s->m_cdvdman_command,
4026 0,
4027 0) )
4028 {
4029 s->m_last_error = SCECdErREAD;
4030 s->m_recover_status = 0;
4031 }
4032 else
4033 {
4034 ext_passthrough = 1;
4035 }
4036 break;
4037 case 2:
4038 s->m_sync_error = 0;
4039 s->m_interupt_read_state = 0;
4040 if ( sceCdRead0(
4041 s->m_read_lsn, s->m_read_sectors, s->m_read_buf, &s->m_read_mode, s->m_read_chunk, s->m_read_callback) )
4042 {
4043 s->m_last_error = SCECdErNO;
4044 s->m_recover_status = 3;
4045 return 1;
4046 }
4047 s->m_last_error = SCECdErREAD;
4048 s->m_recover_status = 0;
4049 break;
4050 case 3:
4051 s->m_recover_status = 0;
4052 break;
4053 default:
4054 break;
4055 }
4056 }
4057 if ( ext_passthrough )
4058 {
4059 s->m_last_error = SCECdErNO;
4060 s->m_dintrlsn += s->m_read_sectors;
4061 s->m_read_chunk_reprocial_32 -= 1;
4062 s->m_recover_status = (!s->m_read_chunk_reprocial_32) ? 2 : 1;
4063 return 1;
4064 }
4065 if ( s->m_dec_state )
4066 {
4067 sceCdDecSet(0, 0, 0);
4068 }
4069 if ( (s->m_read2_flag == 1 || s->m_read2_flag == 3) && !s->m_use_toc )
4070 {
4071 VERBOSE_KPRINTF(1, "call Read2intrCDVD()\n");
4072 Read2intrCDVD(s->m_read2_flag);
4073 }
4074 s->m_sync_error = 0;
4075 s->m_interupt_read_state = 0;
4076 if ( s->m_dec_state == 2 )
4077 {
4078 s->m_dec_state = 0;
4079 }
4080 if ( s->m_stream_flag == 1 && !s->m_use_toc && !s->m_read2_flag )
4081 {
4082 if ( g_cdvdman_cdstm0cb )
4083 {
4084 g_cdvdman_cdstm0cb(1);
4085 }
4086 else
4087 {
4088 VERBOSE_KPRINTF(1, "Intr func0 no seting");
4089 }
4090 }
4091 if ( !s->m_read2_flag )
4092 {
4093 if ( s->m_stream_flag == 2 && !s->m_use_toc )
4094 {
4095 if ( g_cdvdman_cdstm1cb )
4096 {
4097 g_cdvdman_cdstm1cb(1);
4098 }
4099 else
4100 {
4101 VERBOSE_KPRINTF(1, "Intr func1 no seting");
4102 }
4103 }
4104 else
4105 {
4106 g_cdvdman_readptr = 0;
4107 }
4108 }
4109
4110 VERBOSE_KPRINTF(
4111 1, "Intr call user callback func_addr %08x num %d flg %d\n", g_cdvdman_user_cb, g_cdvdman_cmdfunc, s->m_read2_flag);
4112 if ( g_cdvdman_user_cb && g_cdvdman_cmdfunc && !s->m_read2_flag && !s->m_use_toc )
4113 {
4114 int cmdfunc_tmp;
4115
4116 cmdfunc_tmp = g_cdvdman_cmdfunc;
4117 g_cdvdman_cmdfunc = 0;
4118 if ( cmdfunc_tmp == 14 || cmdfunc_tmp == 9 )
4119 {
4120 cmdfunc_tmp = SCECdFuncRead;
4121 }
4122 g_cdvdman_user_cb(cmdfunc_tmp);
4123 }
4124 if ( !g_cdvdman_user_cb )
4125 {
4126 g_cdvdman_cmdfunc = 0;
4127 }
4128 return 1;
4129}
4130
4131static int intrh_cdrom(void *userdata)
4132{
4133 int conds1;
4134 iop_event_info_t efinfo;
4135#ifdef CDVD_VARIANT_XOSD
4136 int condaddr5;
4137#endif
4138 int intr_cb_res;
4139 cdvdman_internal_struct_t *s;
4140 USE_DEV5_MMIO_HWPORT();
4141
4142 s = (cdvdman_internal_struct_t *)userdata;
4143 conds1 = 0;
4144#ifdef CDVD_VARIANT_XOSD
4145 if ( s->m_cd_mode_ps2_atapi == 1 )
4146 {
4147 int spd_intr_stat_cur;
4148 int atapi_intr_reason;
4149
4150 VERBOSE_KPRINTF(1, "Atapi Intr Called %d\n", g_cdvdman_debug_atapi_intr++);
4151 condaddr5 = (unsigned int)GetBaseAddress(5) == 0x1F402000;
4152 set_cdvd_dev5_base_addr_atapi(1);
4153 (void)*(vu16 *)0xBF410028; // r_spd_intr_stat
4154 set_cdvd_dev5_base_addr_atapi(2);
4155 atapi_intr_reason = dev5_mmio_hwport->m_dev5_reg_008;
4156 if ( (atapi_intr_reason & 1) )
4157 {
4158 conds1 = 1;
4159 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4160 VERBOSE_KPRINTF(1, "ATAPI DRAGON CMDCMPL Interrupt\n");
4161 }
4162 if ( atapi_intr_reason & 4 )
4163 {
4164 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4165 conds1 = 1;
4166 iSetEventFlag(g_cdvdman_intr_evfid, 4);
4167 iSetEventFlag(g_cdvdman_intr_evfid, 0x10);
4168 set_cdvd_dev5_base_addr_atapi(1);
4169 VERBOSE_KPRINTF(1, "ATAPI POFFRDY Interrupt\n");
4170 if ( g_cdvdman_power_off_callback )
4171 {
4172 g_cdvdman_power_off_callback(g_cdvdman_power_off_callback_userdata);
4173 }
4174 set_cdvd_dev5_base_addr_atapi(2);
4175 }
4176 if ( (atapi_intr_reason & 8) )
4177 {
4178 conds1 = 1;
4179 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4180 if ( !s->m_medium_removal_state )
4181 {
4182 s->m_atapi_disk_ejected = 0;
4183 }
4184 set_cdvd_dev5_base_addr_atapi(1);
4185 VERBOSE_KPRINTF(1, "ATAPI EJECT Interrupt\n");
4186 if ( s->m_cd_atapi_intr_callback && !s->m_medium_removal_state )
4187 {
4188 VERBOSE_KPRINTF(1, "EJECT Stop Call\n");
4189 s->m_cd_atapi_intr_callback(1);
4190 }
4191 iSetEventFlag(g_cdvdman_intr_evfid, 0x40);
4192 if ( g_cdvdman_atapi_eject_bs_power_callback )
4193 {
4194 VERBOSE_KPRINTF(1, "ATAPI EJECT Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4195 g_cdvdman_atapi_eject_bs_power_callback(1, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4196 }
4197 set_cdvd_dev5_base_addr_atapi(2);
4198 }
4199 if ( (atapi_intr_reason & 0x10) )
4200 {
4201 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4202 conds1 = 1;
4203 set_cdvd_dev5_base_addr_atapi(1);
4204 VERBOSE_KPRINTF(1, "ATAPI BS_Power DET Interrupt\n");
4205 iSetEventFlag(g_cdvdman_intr_evfid, 0x80);
4206 if ( g_cdvdman_atapi_eject_bs_power_callback )
4207 {
4208 VERBOSE_KPRINTF(1, "ATAPI BS_Power Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4209 g_cdvdman_atapi_eject_bs_power_callback(2, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4210 }
4211 }
4212 set_cdvd_dev5_base_addr_atapi(1);
4213 if ( g_cdvdman_vernotxxx1x && conds1 )
4214 {
4215 *(vu16 *)0xBF41002A &= ~0x100; // r_spd_intr_mask
4216 *(vu16 *)0xBF41002A |= 0x100; // r_spd_intr_mask
4217 (void)*(vu16 *)0xBF41002A; // r_spd_intr_mask
4218 }
4219 spd_intr_stat_cur = *(vu16 *)0xBF410028; // r_spd_intr_stat
4220 VERBOSE_KPRINTF(
4221 1,
4222 "Atapi Intr Mode:%d addr:%08x Reason:%02x SPD_INTR_STAT %x\n",
4223 s->m_cd_mode_ps2_atapi,
4224 s->m_cd_atapi_intr_callback,
4225 atapi_intr_reason,
4226 spd_intr_stat_cur);
4227 if ( (spd_intr_stat_cur & 3) && (*g_cdvdreg_bf80146c & 4) )
4228 {
4229 if ( s->m_cd_atapi_intr_callback )
4230 {
4231 s->m_cd_atapi_intr_callback(0);
4232 VERBOSE_KPRINTF(1, "Atapi Intr called\n");
4233 }
4234 if ( !s->m_scmd_flag )
4235 {
4236 VERBOSE_KPRINTF(1, "Intr call set_prev_command.\n");
4237 set_cdvd_dev5_base_addr_atapi(2);
4238 cdvdman_write_scmd(s);
4239 set_cdvd_dev5_base_addr_atapi(1);
4240 }
4241 }
4242 else if ( !conds1 )
4243 {
4244 if ( (*g_cdvdreg_bf80146c & 4) )
4245 {
4246 VERBOSE_KPRINTF(1, "No_Reason Intr\n");
4247 }
4248 else
4249 {
4250 VERBOSE_KPRINTF(1, "already 9611 Power Off Intr\n");
4251 }
4252 }
4253 if ( condaddr5 )
4254 {
4255 set_cdvd_dev5_base_addr_atapi(2);
4256 VERBOSE_KPRINTF(1, "Cur PS2 IO Intr Called\n");
4257 }
4258 return 1;
4259 }
4260 VERBOSE_KPRINTF(1, "Dragon Intr Called\n");
4261 condaddr5 = (unsigned int)GetBaseAddress(5) == 0xBF410000;
4262 if ( condaddr5 )
4263 {
4264 set_cdvd_dev5_base_addr_atapi(2);
4265 }
4266#endif
4267 s->m_waf_set_test = s->m_wait_flag;
4268 if ( (u8)s->m_last_error != SCECdErABRT )
4269 {
4270 s->m_last_error = dev5_mmio_hwport->m_dev5_reg_006;
4271 }
4272 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4273 {
4274 s->m_waf_set_test = (!(dev5_mmio_hwport->m_dev5_reg_005 & 1)) ? 1 : -1;
4275 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4276 conds1 = 1;
4277 }
4278 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4279 {
4280 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4281 iSetEventFlag(g_cdvdman_intr_evfid, 4);
4282 iSetEventFlag(g_cdvdman_intr_evfid, 0x10);
4283 // The following Kprintf was added for ioprp300x
4284 VERBOSE_KPRINTF(1, "PS2 POWER OFF Interrupt\n");
4285 if ( g_cdvdman_power_off_callback )
4286 {
4287 g_cdvdman_power_off_callback(g_cdvdman_power_off_callback_userdata);
4288 }
4289 if ( !conds1 )
4290 {
4291 return 1;
4292 }
4293 }
4294 else
4295 {
4296 s->m_waf_set_test = 1;
4297 s->m_ncmd_intr_count += 1;
4298 dev5_mmio_hwport->m_dev5_reg_008 = 2;
4299 }
4300#ifdef CDVD_VARIANT_XOSD
4301 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 8) )
4302 {
4303 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4304 VERBOSE_KPRINTF(1, "PS2 EJECT Interrupt\n");
4305 iSetEventFlag(g_cdvdman_intr_evfid, 0x40);
4306 if ( !s->m_medium_removal_state )
4307 {
4308 s->m_atapi_disk_ejected = 0;
4309 }
4310 if ( g_cdvdman_atapi_eject_bs_power_callback )
4311 {
4312 VERBOSE_KPRINTF(1, "PS2 EJECT Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4313 g_cdvdman_atapi_eject_bs_power_callback(1, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4314 }
4315 }
4316 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 0x10) )
4317 {
4318 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4319 VERBOSE_KPRINTF(1, "PS2 BS_Power DET Interrupt\n");
4320 iSetEventFlag(g_cdvdman_intr_evfid, 0x80);
4321 if ( g_cdvdman_atapi_eject_bs_power_callback )
4322 {
4323 VERBOSE_KPRINTF(1, "PS2 BS_Power Callback %p\n", g_cdvdman_atapi_eject_bs_power_callback);
4324 g_cdvdman_atapi_eject_bs_power_callback(2, g_cdvdman_atapi_eject_bs_power_callback_userdata);
4325 }
4326 }
4327#endif
4328 iReferEventFlagStatus(g_cdvdman_intr_evfid, &efinfo);
4329 if ( !(efinfo.currBits & 0x20) )
4330 {
4331 // The following Kprintf was added for ioprp300x
4332 VERBOSE_KPRINTF(1, "Now DMA Working evfid:%08x\n", efinfo.currBits);
4333 if ( s->m_last_error == SCECdErNO )
4334 {
4335 s->m_drive_interupt_request = 1;
4336#ifdef CDVD_VARIANT_XOSD
4337 if ( condaddr5 )
4338 {
4339 set_cdvd_dev5_base_addr_atapi(1);
4340 }
4341#endif
4342 return 1;
4343 }
4344 if ( s->m_last_error == SCECdErEOM )
4345 {
4346 intrh_dma_3(s);
4347 }
4348 }
4349 intr_cb_res = cdvdman_intr_cb(s);
4350#ifdef CDVD_VARIANT_XOSD
4351 if ( condaddr5 )
4352 {
4353 set_cdvd_dev5_base_addr_atapi(1);
4354 }
4355#endif
4356 return intr_cb_res;
4357}
4358
4359static u32 cdvdman_l1start(const u8 *toc)
4360{
4361 return toc[23] + (toc[22] << 8) + (toc[21] << 16) - 0x30000 + 1;
4362}
4363
4364static int DvdDual_infochk(void)
4365{
4366#ifdef CDVD_VARIANT_OSD
4367 // From DVD Player 3.11
4368 if ( QueryIntrContext() || !(cdvdman_mediactl(3) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
4369#else
4370 if ( QueryIntrContext() || !(cdvdman_mediactl(4) || (u8)g_cdvdman_istruct.m_opo_or_para == 0xFF) )
4371#endif
4372 {
4373 return 1;
4374 }
4375 g_cdvdman_istruct.m_use_toc = 1;
4376 if ( !cdvdman_gettoc(g_cdvdman_ptoc) )
4377 {
4378 g_cdvdman_istruct.m_use_toc = 0;
4379 g_cdvdman_istruct.m_opo_or_para = -1;
4380 return 0;
4381 }
4382 g_cdvdman_istruct.m_use_toc = 0;
4383 g_cdvdman_istruct.m_layer_1_lsn = cdvdman_l1start(g_cdvdman_ptoc);
4384 g_cdvdman_istruct.m_opo_or_para = ((g_cdvdman_ptoc[14] & 0x60)) ? (((g_cdvdman_ptoc[14] & 0x10)) ? 2 : 1) : 0;
4385 if ( g_cdvdman_istruct.m_dual_layer_emulation )
4386 {
4387 VERBOSE_KPRINTF(1, "CDVD:DualEmuON\n");
4388 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
4389 g_cdvdman_istruct.m_opo_or_para = 0;
4390 }
4391 VERBOSE_KPRINTF(
4392 1,
4393 "DvdDual_info: %02x\tLayer1_LSN:%d opo_or_para %d\n",
4394 g_cdvdman_ptoc[14],
4395 g_cdvdman_istruct.m_layer_1_lsn,
4396 (u8)g_cdvdman_istruct.m_opo_or_para);
4397 return 1;
4398}
4399
4400static u32 sceCdLsnDualChg(u32 lsn)
4401{
4402 int layer_disk_needed;
4403 u32 change_lsn;
4404 sceCdRMode cdrmode;
4405 int has_change_lsn;
4406
4407 layer_disk_needed = 2;
4408 has_change_lsn = 0;
4409 if ( cdvdman_isdvd() && DvdDual_infochk() )
4410 {
4411 if ( g_cdvdman_istruct.m_dual_layer_emulation )
4412 {
4413 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
4414 {
4415 layer_disk_needed = 1;
4416 }
4417 if ( g_cdvdman_istruct.m_current_dvd && lsn < g_cdvdman_istruct.m_current_dvd_lsn )
4418 {
4419 layer_disk_needed = 0;
4420 }
4421 if ( layer_disk_needed == 2 )
4422 {
4423 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
4424 has_change_lsn = 1;
4425 }
4426 else if ( !QueryIntrContext() )
4427 {
4428 u32 traychk;
4429
4430 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
4431 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4432 {
4433 ;
4434 }
4435 cdrmode.trycount = 0;
4436 cdrmode.spindlctrl = SCECdSpinStm;
4437 cdrmode.datapattern = SCECdSecS2048;
4438 g_cdvdman_istruct.m_use_toc = 1;
4439 while ( layer_disk_needed != 2 )
4440 {
4441 if ( cdvdman_isdvd() )
4442 {
4443 int read0_result;
4444
4445 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
4446 sceCdSync(3);
4447 if ( g_cdvdman_istruct.m_last_error == SCECdErNO || read0_result )
4448 {
4449 int i;
4450
4451 for ( i = 0; i < 20; i += 1 )
4452 {
4453 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
4454 {
4455 break;
4456 }
4457 }
4458 if ( i == 20 && g_cdvdman_ptoc[131] == 2 && (g_cdvdman_ptoc[132] & 2) )
4459 {
4460 if ( layer_disk_needed == g_cdvdman_ptoc[133] )
4461 {
4462 g_cdvdman_istruct.m_current_dvd = layer_disk_needed;
4463 layer_disk_needed = 2;
4464 }
4465 else
4466 {
4467 VERBOSE_KPRINTF(0, "CDVD: Layer_%d Disk not Found\n", layer_disk_needed);
4468 VERBOSE_KPRINTF(0, "CDVD: Exchange it for the Layer_%d_Disk Please.\n", layer_disk_needed);
4469 if ( !g_cdvdman_istruct.m_current_dvd && lsn >= g_cdvdman_istruct.m_current_dvd_lsn )
4470 {
4471 layer_disk_needed = 1;
4472 }
4473 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4474 {
4475 ;
4476 }
4477 }
4478 }
4479 else
4480 {
4481 VERBOSE_KPRINTF(0, "CDVD: Not Master Disk %s\n", (const char *)&g_cdvdman_ptoc[i + 104]);
4482 while ( g_cdvdman_minver_60200 ? !cdvdman_scmd_sender_3B(0) : !sceCdTrayReq(SCECdTrayOpen, &traychk) )
4483 {
4484 ;
4485 }
4486 }
4487 }
4488 else
4489 {
4490 VERBOSE_KPRINTF(1, "CDVD: LsnDualChg Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
4491 }
4492 }
4493 else
4494 {
4495 vDelayThread(16000);
4496 }
4497 }
4498 change_lsn = lsn - ((g_cdvdman_istruct.m_current_dvd) ? g_cdvdman_istruct.m_current_dvd_lsn : 0);
4499 g_cdvdman_istruct.m_use_toc = 0;
4500 has_change_lsn = 1;
4501 }
4502 }
4503 else
4504 {
4505 change_lsn =
4506 lsn - ((g_cdvdman_istruct.m_opo_or_para && (lsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn)) ? 0x10 : 0);
4507 has_change_lsn = 1;
4508 }
4509 }
4510 if ( has_change_lsn )
4511 {
4512 VERBOSE_KPRINTF(1, "CDVD: sceCdLsnDualChg lsn %d: change lsn %d\n", lsn, change_lsn);
4513 }
4514 return has_change_lsn ? change_lsn : lsn;
4515}
4516
4517int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
4518{
4519 int read0_result;
4520 int i;
4521 sceCdRMode cdrmode;
4522
4523 *on_dual = 0;
4524 *layer1_start = 0;
4525 g_cdvdman_istruct.m_dual_layer_emulation = 0;
4526#ifndef CDVD_VARIANT_XOSD
4527 if ( !cdvdman_isdvd() )
4528 {
4529 return 1;
4530 }
4531#endif
4532 if ( !g_cdvdman_emudvd9 )
4533 {
4534 if ( !DvdDual_infochk() )
4535 {
4536 return 0;
4537 }
4538 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
4539 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4540 return 1;
4541 }
4542#ifdef CDVD_VARIANT_OSD
4543 if ( !cdvdman_isdvd() )
4544 {
4545 return 1;
4546 }
4547#endif
4548#ifndef CDVD_VARIANT_XOSD
4549 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
4550 {
4551 return 0;
4552 }
4553#endif
4554 cdrmode.trycount = 0;
4555 cdrmode.spindlctrl = SCECdSpinStm;
4556 cdrmode.datapattern = SCECdSecS2048;
4557 read0_result = sceCdRead0(0xE, 1, g_cdvdman_ptoc, &cdrmode, 0, 0);
4558 sceCdSync(3);
4559 if ( g_cdvdman_istruct.m_last_error != SCECdErNO && !read0_result )
4560 {
4561 VERBOSE_KPRINTF(1, "CDVD: ReadDvdDualInfo Read Error %02x, %d\n", (u8)g_cdvdman_istruct.m_last_error, 0);
4562 return 0;
4563 }
4564 for ( i = 0; i < 20; i += 1 )
4565 {
4566 if ( g_cdvdman_ptoc[i + 104] != g_masterdisc_header[i] )
4567 {
4568 break;
4569 }
4570 }
4571 if ( i != 20 )
4572 {
4573 if ( !DvdDual_infochk() )
4574 {
4575 return 0;
4576 }
4577 *on_dual = !!g_cdvdman_istruct.m_opo_or_para;
4578 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4579 return 1;
4580 }
4581 if ( g_cdvdman_ptoc[131] != 2 || !(g_cdvdman_ptoc[132] & 2) )
4582 {
4583 return 1;
4584 }
4585 g_cdvdman_istruct.m_current_dvd = g_cdvdman_ptoc[133];
4586 g_cdvdman_istruct.m_current_dvd_lsn =
4587 g_cdvdman_ptoc[134] + (g_cdvdman_ptoc[135] << 8) + (g_cdvdman_ptoc[136] << 16) + (g_cdvdman_ptoc[137] << 24) + 1;
4588 g_cdvdman_istruct.m_opo_or_para = 0;
4589 g_cdvdman_istruct.m_layer_1_lsn = g_cdvdman_istruct.m_current_dvd_lsn;
4590 g_cdvdman_istruct.m_dual_layer_emulation = 1;
4591 *on_dual = 1;
4592 *layer1_start = g_cdvdman_istruct.m_layer_1_lsn;
4593 VERBOSE_KPRINTF(
4594 1,
4595 "sceCdReadDvdDualInfo():Cur_Disk %d layer1_start %d\n",
4596 (u8)g_cdvdman_istruct.m_current_dvd,
4597 g_cdvdman_istruct.m_current_dvd_lsn);
4598 return 1;
4599}
4600
4601int sceCdSC(int code, int *param)
4602{
4603 void *poffarg_tmp;
4604 int *BootMode;
4605 int state;
4606 u32 efbits;
4607#ifdef CDVD_VARIANT_XOSD
4608 u8 regval;
4609#endif
4610
4611 switch ( code )
4612 {
4613#ifdef CDVD_VARIANT_XOSD
4614 case 0xFFFFFFD6:
4615 CpuSuspendIntr(&state);
4616 set_cdvd_dev5_base_addr_atapi(2);
4617 regval = ((vu8 *)(0xBF402000))[*param];
4618 set_cdvd_dev5_base_addr_atapi(1);
4619 CpuResumeIntr(state);
4620 return regval;
4621 case 0xFFFFFFD7:
4622 CpuSuspendIntr(&state);
4623 *param = (int)&g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open;
4624 CpuResumeIntr(state);
4625 return 1;
4626 case 0xFFFFFFD8:
4627 return sc_ffffffd8((u32 *)param);
4628 case 0xFFFFFFD9:
4629 CpuSuspendIntr(&state);
4630 *param = (int)&g_cdvdman_istruct.m_atapi_disk_ejected;
4631 CpuResumeIntr(state);
4632 return 1;
4633 case 0xFFFFFFDA:
4634 return get_disk_type_ex();
4635 case 0xFFFFFFDB:
4636 CpuSuspendIntr(&state);
4637 *(&g_cdvdman_istruct.m_var_sc_ffffffdb) = (int)param;
4638 CpuResumeIntr(state);
4639 return 1;
4640 case 0xFFFFFFDC:
4641 return g_cdvdman_vernotxxx1x;
4642 case 0xFFFFFFDD:
4643 return get_cdvd_register(*param);
4644 case 0xFFFFFFDF:
4645 g_adma_evfid = *param;
4646 return 1;
4647 case 0xFFFFFFE0:
4648 g_acmd_evfid = *param;
4649 return 1;
4650 case 0xFFFFFFE1:
4651 CpuSuspendIntr(&state);
4652 g_cdvdman_istruct.m_chgsys_callback = (void *)(int)param;
4653 CpuResumeIntr(state);
4654 return 1;
4655 case 0xFFFFFFE4:
4656 g_cd_atapi_evfid = *param;
4657 return 1;
4658 case 0xFFFFFFE5:
4659 CpuSuspendIntr(&state);
4660 g_cdvdman_istruct.m_cd_atapi_intr_callback = (void *)(int)param;
4661 CpuResumeIntr(state);
4662 return 1;
4663#endif
4664 case 0xFFFFFFE6:
4665 CpuSuspendIntr(&state);
4666 *param = (int)g_cdvdman_power_off_callback;
4667 poffarg_tmp = g_cdvdman_power_off_callback_userdata;
4668 CpuResumeIntr(state);
4669 return (int)poffarg_tmp;
4670 case 0xFFFFFFE7:
4671 return g_scmd_evfid;
4672 case 0xFFFFFFE9:
4673 return sceCdLsnDualChg(*param);
4674 case 0xFFFFFFEA:
4675 return DvdDual_infochk();
4676 case 0xFFFFFFEE:
4677 g_cdvdman_istruct.m_last_read_timeout = *param;
4678 return 0;
4679 case 0xFFFFFFEF:
4680 return g_cdvdman_stream_timeout;
4681 case 0xFFFFFFF0:
4682 *param = (int)&g_verbose_level;
4683 return 0xFF;
4684 case 0xFFFFFFF1:
4685 return g_cdvdman_sync_timeout;
4686 case 0xFFFFFFF2:
4687 *param = (int)&g_cdvdman_istruct;
4688 return 0xFF;
4689 case 0xFFFFFFF3:
4690 BootMode = QueryBootMode(4);
4691 switch ( BootMode ? *(u8 *)BootMode : 0xFF )
4692 {
4693 case 0:
4694 case 1:
4695 case 2:
4696 g_cdvdman_mmode = 0xFF;
4697 break;
4698 case 3:
4699 g_cdvdman_mmode = SCECdMmodeCd;
4700 break;
4701 default:
4702 break;
4703 }
4704 return 1;
4705 case 0xFFFFFFF4:
4706#ifdef CDVD_VARIANT_OSD
4707 return 1;
4708#else
4709 // The following call to sceCdGetDiskType was inlined
4710 switch ( sceCdGetDiskType() )
4711 {
4712 case SCECdPSCD:
4713 case SCECdPSCDDA:
4714 case SCECdPS2CD:
4715 case SCECdPS2CDDA:
4716 return g_cdvdman_mmode == SCECdMmodeCd || g_cdvdman_mmode == 0xFF;
4717 case SCECdPS2DVD:
4718 return g_cdvdman_mmode == SCECdMmodeDvd || g_cdvdman_mmode == 0xFF;
4719 case SCECdCDDA:
4720 return g_cdvdman_mmode == 0xFF;
4721 default:
4722 return 0;
4723 }
4724#endif
4725 case 0xFFFFFFF5:
4726 return g_cdvdman_intr_evfid;
4727 case 0xFFFFFFF6:
4728 if ( *param )
4729 {
4730 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
4731 }
4732 else
4733 {
4734 SetEventFlag(g_fio_fsv_evfid, 1);
4735 }
4736 g_cdvdman_ee_rpc_fno = *param;
4737 VERBOSE_KPRINTF(1, "EE_ncmd_working code= %d\n", *param);
4738 return g_cdvdman_ee_rpc_fno;
4739 case 0xFFFFFFF7:
4740 return (u16)_irx_id.v;
4741 case 0xFFFFFFF8:
4742 g_cdvdman_spinctl = *param;
4743 return 1;
4744 case 0xFFFFFFFC:
4745 return g_cdvdman_cd36key;
4746 case 0xFFFFFFFD:
4747 return g_cdvdman_istruct.m_read2_flag;
4748 case 0xFFFFFFFE:
4749 g_cdvdman_istruct.m_last_error = *(u8 *)param;
4750 return (u8)g_cdvdman_istruct.m_last_error;
4751 case 0xFFFFFFFF:
4752 case 0:
4753 case 1:
4754 case 2:
4755 *param = (u8)g_cdvdman_istruct.m_last_error;
4756 if ( code != -1 )
4757 {
4758 g_cdvdman_istruct.m_stream_flag = code;
4759 }
4760 return g_cdvdman_istruct.m_stream_flag;
4761 default:
4762 VERBOSE_KPRINTF(1, "sceCdSC func_num Not found %d\n", code);
4763 return 0;
4764 }
4765}
4766
4767static void cdvdman_init(void)
4768{
4769 int *BootMode;
4770 unsigned int i;
4771 int scres_unused;
4772 u32 argres;
4773#ifdef CDVD_VARIANT_XOSD
4774 int chgsys_tmp;
4775#endif
4776 USE_DEV5_MMIO_HWPORT();
4777
4778#ifdef CDVD_VARIANT_XOSD
4779 {
4780 int state;
4781 CpuSuspendIntr(&state);
4782 g_cdvdman_istruct.m_cd_mode_ps2_atapi = 2;
4783 cdvdman_change_drive(2);
4784 CpuResumeIntr(state);
4785 }
4786#endif
4787 g_cdvdman_user_cb = 0;
4788 g_cdvdman_power_off_callback = 0;
4789 g_cdvdman_cmdfunc = 0;
4790 g_cdvdman_istruct.m_drive_interupt_request = 0;
4791 RegisterIntrHandler(IOP_IRQ_CDVD, 1, intrh_cdrom, &g_cdvdman_istruct);
4792 RegisterIntrHandler(IOP_IRQ_DMA_CDVD, 1, intrh_dma_3, &g_cdvdman_istruct);
4793 EnableIntr(IOP_IRQ_CDVD);
4794 sceCdSC(0xFFFFFFF3, &scres_unused);
4795 dmac_set_dpcr(dmac_get_dpcr() | 0x8000);
4796 dmac_ch_set_chcr(3, 0);
4797#ifdef CDVD_VARIANT_XOSD
4798 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 0x10) )
4799 {
4800 dev5_mmio_hwport->m_dev5_reg_008 = 0x10;
4801 }
4802 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 8) )
4803 {
4804 dev5_mmio_hwport->m_dev5_reg_008 = 8;
4805 }
4806#endif
4807 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 4) )
4808 {
4809 dev5_mmio_hwport->m_dev5_reg_008 = 4;
4810 }
4811 if ( (dev5_mmio_hwport->m_dev5_reg_008 & 1) )
4812 {
4813 dev5_mmio_hwport->m_dev5_reg_008 = 1;
4814 }
4815#ifndef CDVD_VARIANT_XOSD
4816 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4817#endif
4818 g_cdvdman_istruct.m_tray_is_open = !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen);
4819#ifdef CDVD_VARIANT_XOSD
4820 g_cdvdman_clk_flg = sceCdReadClock(&g_cdvdman_clock) ? (!g_cdvdman_clock.stat) : 0;
4821#endif
4822 cdvdman_initcfg();
4823 BootMode = QueryBootMode(6);
4824 g_cdvdman_istruct.m_no_dec_flag = BootMode ? ((*(u16 *)BootMode & 0xFFFC) == 0x60) : 0;
4825 for ( i = 0; i <= 60 && (!sceCdCancelPOffRdy(&argres) || argres); i += 1 )
4826 {
4827 DelayThread(16000);
4828 }
4829#ifdef CDVD_VARIANT_XOSD
4830 {
4831 u32 medium_res;
4832 int MediumRemoval;
4833
4834 for ( i = 0; i <= 60 && (!sceCdSetMediumRemoval(0, &argres) || argres); i += 1 )
4835 {
4836 DelayThread(16000);
4837 }
4838 for ( i = 0; i <= 60 && (!(MediumRemoval = sceCdGetMediumRemoval(&medium_res, &argres)) || argres); i += 1 )
4839 {
4840 DelayThread(16000);
4841 }
4842 g_cdvdman_istruct.m_medium_removal_state = (MediumRemoval && !argres) ? medium_res : 0;
4843 {
4844 int state;
4845
4846 CpuSuspendIntr(&state);
4847 chgsys_tmp = (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen);
4848 g_cdvdman_istruct.m_cd_mode_ps2_atapi =
4849 (chgsys_tmp || (!(dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && dev5_mmio_hwport->m_dev5_reg_00F != 6)) ? 2 : 1;
4850 cdvdman_change_drive(g_cdvdman_istruct.m_cd_mode_ps2_atapi);
4851 CpuResumeIntr(state);
4852 }
4853 if ( chgsys_tmp )
4854 {
4855 sceCdChgSys(1);
4856 }
4857 }
4858#endif
4859}
4860
4861int sceCdInit(int mode)
4862{
4863 VERBOSE_PRINTF(1, "sceCdInit called mode= %d\n", mode);
4864 if ( mode == SCECdEXIT )
4865 {
4866 int oldstate;
4867
4868 g_cdvdman_istruct.m_cd_inited = 0;
4869#ifndef CDVD_VARIANT_XOSD
4870 sceCdBreak();
4871 sceCdSync(3);
4872 cdvdman_ncmd_sender_06();
4873#endif
4874 sceCdSync(0);
4875 VERBOSE_PRINTF(1, "Cdvdman Exit\n");
4876 DisableIntr(IOP_IRQ_CDVD, &oldstate);
4877 ReleaseIntrHandler(IOP_IRQ_CDVD);
4878 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
4879 ReleaseIntrHandler(IOP_IRQ_DMA_CDVD);
4880 }
4881 else
4882 {
4883 VERBOSE_PRINTF(1, "Cdvdman Init\n");
4884 g_cdvdman_istruct.m_read2_flag = 0;
4885 g_cdvdman_istruct.m_dec_shift = 0;
4886 g_cdvdman_istruct.m_check_version = 0;
4887 g_cdvdman_istruct.m_dec_state = 0;
4888#ifdef CDVD_VARIANT_XOSD
4889 if ( update_cd_mode_ps2_atapi() != 1 )
4890#endif
4891 {
4892 sceCdDecSet(0, 0, 0);
4893 }
4894 cdvdman_init();
4895 g_cdvdman_istruct.m_cd_inited = 1;
4896 }
4897 if ( mode == SCECdINIT )
4898 {
4899 u8 ready_status_tmp;
4900 u8 ready_status;
4901
4902 ready_status_tmp = 0;
4903 VERBOSE_PRINTF(1, "sceCdInit Ready check start.\n");
4904 ready_status = 0;
4905 while ( (ready_status & 0xC0) != 0x40 )
4906 {
4907#ifdef CDVD_VARIANT_XOSD
4908 if ( update_cd_mode_ps2_atapi() == 1 || sceCdGetDiskType() == 6 )
4909 break;
4910 g_cdvdman_istruct.m_field_0DC = 0;
4911 if ( sceCdGetDiskType() == SCECdNODISC )
4912 break;
4913#endif
4914 ready_status = sceCdDiskReady(8);
4915 vDelayThread(10000);
4916 if ( ready_status != ready_status_tmp )
4917 {
4918 ready_status_tmp = ready_status;
4919 VERBOSE_PRINTF(1, "sceCdInit Dev5 Status %x\n", ready_status);
4920 }
4921 // The following Kprintf was added for ioprp300x
4922 VERBOSE_PRINTF(1, "sceCdInit Ready check %x\n", ready_status);
4923 }
4924 VERBOSE_PRINTF(1, "sceCdInit Ready check end.\n");
4925 }
4926 g_cdvdman_istruct.m_wait_flag = 1;
4927 g_cdvdman_istruct.m_scmd_flag = 1;
4928 g_cdvdman_istruct.m_last_error = SCECdErNO;
4929 g_cdvdman_istruct.m_last_read_timeout = 0;
4930 g_cdvdman_spinctl = -1;
4931 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
4932 SetEventFlag(g_ncmd_evfid, 1);
4933 SetEventFlag(g_scmd_evfid, 1);
4934 SetEventFlag(g_sfile_evfid, 1);
4935 return 1;
4936}
4937
4938static int set_prev_command(int cmd, const char *sdata, int sdlen, char *rdata, int rdlen, int check_sef)
4939{
4940 int i;
4941 int delaybackoff;
4942 int j;
4943 u32 efbits;
4944#ifdef CDVD_VARIANT_XOSD
4945 int suspendres;
4946#endif
4947
4948#ifdef CDVD_VARIANT_XOSD
4949 {
4950 int state;
4951
4952 suspendres = CpuSuspendIntr(&state);
4953 CpuResumeIntr(state);
4954 suspendres = QueryIntrContext() || suspendres;
4955 }
4956 VERBOSE_KPRINTF(1, "set_prev_command cmd %02x call\n", cmd);
4957 if ( !suspendres )
4958 {
4959 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
4960 }
4961#endif
4962 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
4963 {
4964 // The following Kprintf was added for ioprp300x
4965 VERBOSE_KPRINTF(1, "set_prev_command Double Booking\n");
4966#ifdef CDVD_VARIANT_XOSD
4967 if ( !suspendres )
4968 {
4969 SetEventFlag(g_cdvdman_csys_evfid, 1);
4970 }
4971#endif
4972 return 0;
4973 }
4974 g_cdvdman_istruct.m_scmd = cmd;
4975 g_cdvdman_istruct.m_sdlen = sdlen;
4976 g_cdvdman_istruct.m_rdlen = rdlen;
4977 for ( i = 0; i < sdlen; i += 1 )
4978 {
4979 g_cdvdman_istruct.m_scmd_sd[i] = sdata[i];
4980 }
4981#ifdef CDVD_VARIANT_XOSD
4982 if ( update_cd_mode_ps2_atapi() != 1 )
4983#endif
4984 {
4985 if ( g_cdvdman_istruct.m_wait_flag )
4986 {
4987 g_cdvdman_istruct.m_scmd_flag = 1;
4988 cdvdman_write_scmd(&g_cdvdman_istruct);
4989 }
4990 else if ( QueryIntrContext() )
4991 {
4992 while ( (dmac_ch_get_chcr(3) & 0x1000000) && !g_cdvdman_istruct.m_wait_flag )
4993 {
4994 VERBOSE_KPRINTF(1, "set_prev_command: DMA Wait\n");
4995 }
4996 g_cdvdman_istruct.m_scmd_flag = 1;
4997 cdvdman_write_scmd(&g_cdvdman_istruct);
4998 }
4999 else
5000 {
5001 g_cdvdman_istruct.m_scmd_flag = 0;
5002 }
5003 }
5004#ifdef CDVD_VARIANT_XOSD
5005 else
5006 {
5007 if ( !suspendres )
5008 {
5009 if ( g_cd_atapi_evfid != -1 )
5010 {
5011 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
5012 }
5013 if ( g_adma_evfid != -1 )
5014 {
5015 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5016 }
5017 if ( g_acmd_evfid != -1 )
5018 {
5019 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5020 }
5021 }
5022 {
5023 int state;
5024
5025 CpuSuspendIntr(&state);
5026 set_cdvd_dev5_base_addr_atapi(2);
5027 g_cdvdman_istruct.m_scmd_flag = 1;
5028 VERBOSE_KPRINTF(1, "do_set_prev_command %02x\n", cmd);
5029 cdvdman_write_scmd(&g_cdvdman_istruct);
5030 set_cdvd_dev5_base_addr_atapi(1);
5031 CpuResumeIntr(state);
5032 }
5033 if ( !suspendres )
5034 {
5035 if ( g_acmd_evfid != -1 )
5036 {
5037 SetEventFlag(g_acmd_evfid, 1);
5038 }
5039 if ( g_adma_evfid != -1 )
5040 {
5041 SetEventFlag(g_adma_evfid, 1);
5042 }
5043 if ( g_cd_atapi_evfid != -1 )
5044 {
5045 SetEventFlag(g_cd_atapi_evfid, 3);
5046 }
5047 }
5048 }
5049#endif
5050 delaybackoff = 1;
5051 for ( i = 0; i < 500; i += delaybackoff )
5052 {
5053 if ( g_cdvdman_istruct.m_scmd_flag )
5054 {
5055 for ( j = 0; j < rdlen; j += 1 )
5056 {
5057 rdata[j] = g_cdvdman_istruct.m_scmd_rd[j];
5058 }
5059 if ( check_sef == 1 )
5060 {
5061 vSetEventFlag(g_scmd_evfid, 1);
5062 }
5063#ifdef CDVD_VARIANT_XOSD
5064 VERBOSE_KPRINTF(1, "set_prev_command end :%02x\n", (u8)g_cdvdman_istruct.m_scmd);
5065 if ( !suspendres )
5066 {
5067 SetEventFlag(g_cdvdman_csys_evfid, 1);
5068 }
5069#endif
5070 return (u8)g_cdvdman_istruct.m_scmd;
5071 }
5072 vDelayThread(1000 * delaybackoff);
5073 if ( (i & 1) && delaybackoff < 16 )
5074 {
5075 delaybackoff *= 2;
5076 }
5077 }
5078 g_cdvdman_istruct.m_scmd_flag = 1;
5079 if ( check_sef == 1 )
5080 {
5081 vSetEventFlag(g_scmd_evfid, 1);
5082 }
5083 return 0;
5084}
5085
5086static void cdvdman_write_scmd(cdvdman_internal_struct_t *s)
5087{
5088 int i;
5089 unsigned int j;
5090 unsigned int rdcnt;
5091 char rdptr1[64];
5092 USE_DEV5_MMIO_HWPORT();
5093
5094 // The following Kprintf was added for ioprp300x
5095 VERBOSE_KPRINTF(1, "in:%d out_size:%d \n", (u8)s->m_sdlen, (u8)s->m_rdlen);
5096 // The following Kprintf was added for ioprp300x
5097 VERBOSE_KPRINTF(1, "cmd:%02x pram:%02x\n", (u8)s->m_scmd, (u8)s->m_scmd_sd[0]);
5098 for ( i = 0; i <= 0; i += 1 )
5099 {
5100 int overflowcond;
5101#ifdef CDVD_VARIANT_XOSD
5102 int suspendres;
5103#endif
5104
5105 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5106 {
5107 s->m_scmd_flag = 1;
5108 s->m_scmd = 0;
5109 // The following Kprintf was added for ioprp300x
5110 VERBOSE_KPRINTF(1, "do_set_prev_command BUSY ABNORM END %08x\n", dev5_mmio_hwport->m_dev5_reg_017);
5111 return;
5112 }
5113 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5114 {
5115 ;
5116 }
5117 for ( j = 0; j < (u8)s->m_sdlen; j += 1 )
5118 {
5119 dev5_mmio_hwport->m_dev5_reg_017 = s->m_scmd_sd[j];
5120 }
5121 dev5_mmio_hwport->m_dev5_reg_016 = s->m_scmd;
5122#ifdef CDVD_VARIANT_XOSD
5123 {
5124 int state;
5125 suspendres = CpuSuspendIntr(&state);
5126 CpuResumeIntr(state);
5127 suspendres = QueryIntrContext() || suspendres;
5128 }
5129#endif
5130#ifdef CDVD_VARIANT_XOSD
5131 if ( suspendres )
5132#else
5133 if ( QueryIntrContext() )
5134#endif
5135 {
5136 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
5137 {
5138 if ( j > 12500000 )
5139 {
5140 s->m_scmd_flag = 1;
5141 s->m_scmd = 0;
5142 return;
5143 }
5144 }
5145 }
5146 else
5147 {
5148 for ( j = 0; dev5_mmio_hwport->m_dev5_reg_017 & 0x80; j += 1 )
5149 {
5150 DelayThread(100);
5151 if ( j > 50000 )
5152 {
5153 // The following Kprintf was added for ioprp300x
5154 VERBOSE_KPRINTF(1, "Mecacon Scmd TIMEOUT CMD= %02x\n", (u8)s->m_scmd);
5155 s->m_scmd_flag = 1;
5156 s->m_scmd = 0;
5157 return;
5158 }
5159 }
5160 }
5161 overflowcond = 0;
5162 for ( j = 0; j < (u8)s->m_rdlen; j += 1 )
5163 {
5164 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5165 {
5166 break;
5167 }
5168 rdptr1[j] = dev5_mmio_hwport->m_dev5_reg_018;
5169 }
5170 if ( j >= (u8)s->m_rdlen )
5171 {
5172 overflowcond = 1;
5173 VERBOSE_KPRINTF(1, "Prev Cmd Result Over Flow\n", rdptr1);
5174 }
5175 rdcnt = j;
5176 if ( (!overflowcond && j >= (u8)s->m_rdlen) || s->m_rdlen == 16 )
5177 {
5178 break;
5179 }
5180 VERBOSE_KPRINTF(1, "Prev Cmd Result Illegal Size Try count:%d\n", i);
5181 }
5182 if ( i == 1 )
5183 {
5184 s->m_scmd_flag = 1;
5185 s->m_scmd = 0;
5186 }
5187 else
5188 {
5189 for ( j = 0; j < (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])); j += 1 )
5190 {
5191 s->m_scmd_rd[j] = 0;
5192 }
5193 if ( s->m_rdlen != (sizeof(s->m_scmd_rd) / sizeof(s->m_scmd_rd[0])) )
5194 {
5195 rdcnt = (u8)s->m_rdlen;
5196 }
5197 for ( j = 0; j < rdcnt; j += 1 )
5198 {
5199 s->m_scmd_rd[j] = rdptr1[j];
5200 }
5201 s->m_scmd_flag = 1;
5202 s->m_scmd = 1;
5203 }
5204}
5205
5206#ifdef CDVD_VARIANT_XOSD
5207static int cdvdman_write_scmd_swap_dev5(char cmd, const char *wdata, int sdlen, char *rdata, int rdlen, int check_sef)
5208{
5209 int atapi_check;
5210 int i;
5211 int j;
5212 char rdstart[64];
5213 u32 efbits;
5214 int state;
5215 USE_DEV5_MMIO_HWPORT();
5216
5217 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5218 {
5219 return 0;
5220 }
5221 CpuSuspendIntr(&state);
5222 atapi_check = update_cd_mode_ps2_atapi() == 1;
5223 if ( atapi_check )
5224 {
5225 set_cdvd_dev5_base_addr_atapi(2);
5226 }
5227 for ( i = 0; i <= 0; i += 1 )
5228 {
5229 int cmdresoverflow;
5230
5231 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5232 {
5233 if ( atapi_check )
5234 {
5235 set_cdvd_dev5_base_addr_atapi(1);
5236 }
5237 CpuResumeIntr(state);
5238 if ( check_sef == 1 )
5239 {
5240 vSetEventFlag(g_scmd_evfid, 1);
5241 }
5242 return 0;
5243 }
5244 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5245 {
5246 ;
5247 }
5248 for ( j = 0; j < sdlen; j += 1 )
5249 {
5250 dev5_mmio_hwport->m_dev5_reg_017 = wdata[j];
5251 }
5252 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
5253 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5254 {
5255 ;
5256 }
5257 cmdresoverflow = 0;
5258 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
5259 {
5260 if ( j >= rdlen )
5261 {
5262 cmdresoverflow = 1;
5263 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Over Flow\n");
5264 break;
5265 }
5266 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
5267 }
5268 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
5269 {
5270 break;
5271 }
5272 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Illegal Size Try count:%d\n", i);
5273 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
5274 {
5275 ;
5276 }
5277 for ( j = 0; j < 16 - rdlen; j += 1 )
5278 {
5279 }
5280 }
5281 if ( i == 1 )
5282 {
5283 if ( atapi_check )
5284 {
5285 set_cdvd_dev5_base_addr_atapi(1);
5286 }
5287 CpuResumeIntr(state);
5288 if ( check_sef == 1 )
5289 {
5290 vSetEventFlag(g_scmd_evfid, 1);
5291 }
5292 return 0;
5293 }
5294 for ( j = 0; j < rdlen; j += 1 )
5295 {
5296 rdata[j] = rdstart[j];
5297 }
5298 if ( atapi_check )
5299 {
5300 set_cdvd_dev5_base_addr_atapi(1);
5301 }
5302 CpuResumeIntr(state);
5303 if ( check_sef == 1 )
5304 {
5305 vSetEventFlag(g_scmd_evfid, 1);
5306 }
5307 return 1;
5308}
5309#endif
5310
5311static int cdvdman_send_scmd2(int cmd, const void *sdata, int sdlen, void *rdata, int rdlen, int check_sef)
5312{
5313 int i;
5314 int j;
5315 char rdstart[64];
5316 u32 efbits;
5317 USE_DEV5_MMIO_HWPORT();
5318
5319 if ( check_sef == 1 && vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5320 {
5321 return 0;
5322 }
5323 for ( i = 0; i <= 0; i += 1 )
5324 {
5325 int cmdresoverflow;
5326
5327 if ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5328 {
5329 if ( check_sef == 1 )
5330 {
5331 vSetEventFlag(g_scmd_evfid, 1);
5332 }
5333 return 0;
5334 }
5335 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40) )
5336 {
5337 ;
5338 }
5339 for ( j = 0; j < sdlen; j += 1 )
5340 {
5341 dev5_mmio_hwport->m_dev5_reg_017 = ((u8 *)sdata)[j];
5342 }
5343 dev5_mmio_hwport->m_dev5_reg_016 = cmd;
5344 while ( (dev5_mmio_hwport->m_dev5_reg_017 & 0x80) )
5345 {
5346#ifndef CDVD_VARIANT_XOSD
5347 DelayThread(100);
5348#endif
5349 }
5350 cmdresoverflow = 0;
5351 for ( j = 0; !(dev5_mmio_hwport->m_dev5_reg_017 & 0x40); j += 1 )
5352 {
5353 if ( j >= rdlen )
5354 {
5355 cmdresoverflow = 1;
5356 // The following Kprintf was modified for ioprp300x
5357 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Over Flow\n");
5358 break;
5359 }
5360 rdstart[j] = dev5_mmio_hwport->m_dev5_reg_018;
5361 }
5362 if ( (!cmdresoverflow && j >= rdlen) || rdlen == 16 )
5363 {
5364 break;
5365 }
5366 // The following Kprintf was modified for ioprp300x
5367 VERBOSE_KPRINTF(1, "Prev Cmd2 Result Illegal Size Try count:%d\n", i);
5368 while ( !(dev5_mmio_hwport->m_dev5_reg_017 & 0x20) )
5369 {
5370 ;
5371 }
5372 for ( j = 0; j < 16 - rdlen; j += 1 )
5373 ;
5374 }
5375 if ( i == 1 )
5376 {
5377 if ( check_sef == 1 )
5378 {
5379 vSetEventFlag(g_scmd_evfid, 1);
5380 }
5381 return 0;
5382 }
5383 for ( i = 0; i < rdlen; i += 1 )
5384 {
5385 ((char *)rdata)[i] = rdstart[i];
5386 }
5387 if ( check_sef == 1 )
5388 {
5389 vSetEventFlag(g_scmd_evfid, 1);
5390 }
5391 return 1;
5392}
5393
5394#ifdef CDVD_VARIANT_OSD
5395static unsigned int signal_sema_timeout_callback(void *userdata)
5396{
5397 int sema_id;
5398
5399 sema_id = (int)(u32)(uiptr)userdata;
5400 iSignalSema(sema_id);
5401 return 0;
5402}
5403#endif
5404
5405int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
5406{
5407 int i;
5408
5409#ifdef CDVD_VARIANT_OSD
5410 if ( g_cdvdman_minver_50000 )
5411 {
5412 WaitSema(g_cdvdman_apply_scmd_sema);
5413 }
5414#endif
5415 for ( i = 0; i <= 2500; i += 1 )
5416 {
5417 if ( set_prev_command(cmdNum, (const char *)inBuff, inBuffSize, (char *)outBuff, 16, 1) )
5418 {
5419#ifdef CDVD_VARIANT_OSD
5420 if ( g_cdvdman_minver_50000 )
5421 {
5422 iop_sys_clock_t sysclk;
5423
5424 sysclk.hi = 0;
5425 sysclk.lo = 0x9000;
5426 SetAlarm(&sysclk, signal_sema_timeout_callback, (void *)g_cdvdman_apply_scmd_sema);
5427 }
5428 else
5429#endif
5430 {
5431 DelayThread(2000);
5432 }
5433 return 1;
5434 }
5435 DelayThread(2000);
5436 }
5437 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5438 return 0;
5439}
5440
5441int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
5442{
5443#ifdef CDVD_VARIANT_XOSD
5444 return sceCdApplySCmd(cmdNum, inBuff, inBuffSize, outBuff);
5445#else
5446 int i;
5447
5448 for ( i = 0; i <= 2500; i += 1 )
5449 {
5450 if ( cdvdman_send_scmd2(cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
5451 {
5452 return 1;
5453 }
5454 DelayThread(2000);
5455 }
5456 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5457 return 0;
5458#endif
5459}
5460
5461#ifdef CDVD_VARIANT_OSD
5462int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
5463{
5464 int i;
5465
5466 for ( i = 0; i <= 2500; i += 1 )
5467 {
5468 DelayThread(2000);
5469 if ( set_prev_command((u8)cmdNum, inBuff, inBuffSize, outBuff, 16, 1) )
5470 {
5471 DelayThread(2000);
5472 return 1;
5473 }
5474 }
5475 KPRINTF("CDVD: set_prev_command TIMEOUT 5(SEC)\n");
5476 return 0;
5477}
5478#endif
5479
5480int sceCdBreak(void)
5481{
5482 u32 efbits;
5483 int state;
5484 int oldstate;
5485 USE_DEV5_MMIO_HWPORT();
5486
5487 if ( PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5488 {
5489 return 0;
5490 }
5491 CpuSuspendIntr(&state);
5492 // The following Kprintf was modified for ioprp300x
5493 VERBOSE_KPRINTF(
5494 1,
5495 "Break call: read2_flg= %d func= %d lsn= %d csec= %d nsec= %d %rsec= %d addr= %p waitflg= %d, DriveIntrReq= %d "
5496 "stmflg= %d recover= %d\n",
5497 g_cdvdman_istruct.m_read2_flag,
5498 g_cdvdman_cmdfunc,
5499 g_cdvdman_istruct.m_cdvdman_lsn,
5500 g_cdvdman_istruct.m_cdvdman_csec,
5501 g_cdvdman_istruct.m_cdvdman_nsec,
5502 g_cdvdman_istruct.m_cdvdman_rsec,
5503 g_cdvdman_istruct.m_read_buf,
5504 g_cdvdman_istruct.m_wait_flag,
5505 g_cdvdman_istruct.m_drive_interupt_request,
5506 g_cdvdman_istruct.m_stream_flag,
5507 g_cdvdman_istruct.m_recover_status);
5508 if ( g_cdvdman_istruct.m_last_read_timeout )
5509 {
5510 g_cdvdman_istruct.m_read2_flag = 0;
5511 }
5512 g_cdvdman_istruct.m_last_error = SCECdErABRT;
5513 g_cdvdman_istruct.m_thread_id = GetThreadId();
5514 g_cdvdman_istruct.m_break_cdvdfsv_readchain = 1;
5515 if ( g_cdvdman_istruct.m_dec_state )
5516 {
5517 g_cdvdman_istruct.m_dec_shift = 0;
5518 g_cdvdman_istruct.m_check_version = 0;
5519 g_cdvdman_istruct.m_dec_state = 0;
5520 sceCdDecSet(0, 0, 0);
5521 }
5522 g_cdvdman_istruct.m_recover_status = 0;
5523 if ( QueryIntrContext() )
5524 {
5525 iSetEventFlag(g_cdvdman_intr_evfid, 0x29);
5526 iCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5527 }
5528 else
5529 {
5530 SetEventFlag(g_cdvdman_intr_evfid, 0x29);
5531 CancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
5532 }
5533 if ( !g_cdvdman_istruct.m_wait_flag || g_cdvdman_istruct.m_last_read_timeout )
5534 {
5535 // The following direct register access was replaced with call for ioprp300x
5536 if ( (sceCdDiskReady(8) & 0xC0) == 0x40 )
5537 {
5538 VERBOSE_KPRINTF(1, "cdvd: NonInter END\n");
5539 g_cdvdman_istruct.m_wait_flag = 1;
5540 }
5541 g_cdvdman_last_cmdfunc = g_cdvdman_cmdfunc;
5542 g_cdvdman_cmdfunc = SCECdFuncBreak;
5543 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5544 if ( g_cdvdman_istruct.m_last_read_timeout )
5545 {
5546 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
5547 }
5548 g_cdvdman_istruct.m_drive_interupt_request = 0;
5549 VERBOSE_KPRINTF(1, "cdvd: Abort command On\n");
5550 }
5551 vSetEventFlag(g_ncmd_evfid, 1);
5552 CpuResumeIntr(state);
5553 return 1;
5554}
5555
5556static unsigned int ncmd_timeout_alarm_cb(void *userdata)
5557{
5558 iop_sys_clock_t *sys_clock;
5559
5560 sys_clock = (iop_sys_clock_t *)userdata;
5561 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
5562 sys_clock->lo = 0;
5563 return 0;
5564}
5565
5566static int intrh_dma_3(void *userdata)
5567{
5568 int dmacbres;
5569 int oldstate;
5570 cdvdman_internal_struct_t *s;
5571
5572 s = (cdvdman_internal_struct_t *)userdata;
5573 s->m_dma3_param.m_dma3_msectors -= s->m_dma3_param.m_dma3_csectors;
5574 // The following Kprintf was added for ioprp300x
5575 VERBOSE_KPRINTF(
5576 1,
5577 "_sceCdDmaIntr wk %d: func_num: %d nsec %d cnt %d cdid:%08x\n",
5578 s->m_wait_flag,
5579 g_cdvdman_cmdfunc,
5580 s->m_dma3_param.m_dma3_msectors,
5581 s->m_cdvdman_dma3sec,
5582 &g_cdvdman_istruct);
5583 dmacbres = s->m_dma3_param.m_dma3_callback ? s->m_dma3_param.m_dma3_callback() : 1;
5584 s->m_cdvdman_dma3sec += s->m_dma3_param.m_dma3_csectors;
5585 s->m_dma3_param.m_dma3_csectors = ((u32)s->m_read_chunk > (u32)s->m_dma3_param.m_dma3_msectors) ?
5586 (u32)s->m_dma3_param.m_dma3_msectors :
5587 (u32)s->m_read_chunk;
5588 if ( dmacbres )
5589 {
5590 if ( s->m_dma3_param.m_dma3_msectors )
5591 {
5592 dmac_ch_set_chcr(3, 0);
5593 dmac_ch_get_chcr(3);
5594 dmac_ch_set_madr(3, (u32)s->m_dma3_param.m_dma3_maddress);
5595 dmac_ch_set_bcr(
5596 3,
5597 ((s->m_dma3_param.m_dma3_blkcount * s->m_dma3_param.m_dma3_csectors) << 16) | s->m_dma3_param.m_dma3_blkwords);
5598 dmac_ch_set_chcr(3, 0x41000200);
5599 dmac_ch_get_chcr(3);
5600 iClearEventFlag(g_cdvdman_intr_evfid, ~0x20);
5601 }
5602 else
5603 {
5604 DisableIntr(IOP_IRQ_DMA_CDVD, &oldstate);
5605 iSetEventFlag(g_cdvdman_intr_evfid, 0x20);
5606 }
5607 }
5608 if ( !s->m_dma3_param.m_dma3_msectors && s->m_drive_interupt_request )
5609 {
5610 cdvdman_intr_cb(s);
5611 s->m_drive_interupt_request = 0;
5612 }
5613 return 1;
5614}
5615
5616static int cdvdman_setdma3(cdvdman_dma3_parameter_t *dma3_param)
5617{
5618 USE_DEV5_MMIO_HWPORT();
5619
5620 if ( (dmac_ch_get_chcr(3) & 0x1000000) )
5621 {
5622 dev5_mmio_hwport->m_dev5_reg_007 = 1;
5623 }
5624 g_cdvdman_istruct.m_drive_interupt_request = 0;
5625 g_cdvdman_istruct.m_dma3_param.m_dma3_blkwords = dma3_param->m_dma3_blkwords;
5626 g_cdvdman_istruct.m_dma3_param.m_dma3_blkcount = dma3_param->m_dma3_blkcount;
5627 g_cdvdman_istruct.m_dma3_param.m_dma3_maddress = dma3_param->m_dma3_maddress;
5628 g_cdvdman_istruct.m_dma3_param.m_dma3_callback = dma3_param->m_dma3_callback;
5629 g_cdvdman_istruct.m_dma3_param.m_dma3_csectors = dma3_param->m_dma3_csectors;
5630 g_cdvdman_istruct.m_dma3_param.m_cdvdreg_howto = dma3_param->m_cdvdreg_howto;
5631 g_cdvdman_istruct.m_dma3_param.m_dma3_msectors = dma3_param->m_dma3_msectors;
5632 g_cdvdman_istruct.m_cdvdman_dma3sec = 0;
5633 dmac_ch_set_chcr(3, 0);
5634 dmac_ch_get_chcr(3);
5635 if ( dma3_param->m_dma3_csectors )
5636 {
5637 vClearEventFlag(g_cdvdman_intr_evfid, ~0x20);
5638 EnableIntr(IOP_IRQ_DMA_CDVD);
5639 }
5640 dev5_mmio_hwport->m_dev5_reg_006 = dma3_param->m_cdvdreg_howto;
5641 dmac_ch_set_madr(3, (u32)dma3_param->m_dma3_maddress);
5642 dmac_ch_set_bcr(
5643 3,
5644 (dma3_param->m_dma3_blkcount * (dma3_param->m_dma3_csectors ? dma3_param->m_dma3_csectors : 1)) << 16
5645 | dma3_param->m_dma3_blkwords);
5646 dmac_ch_set_chcr(3, 0x41000200);
5647 return dmac_ch_get_chcr(3);
5648}
5649
5650#ifdef CDVD_VARIANT_XOSD
5651static int update_cd_mode_ps2_atapi(void)
5652{
5653 int is_intr_context;
5654 int saved_cd_mode_ps2_atapi;
5655 int state;
5656
5657 is_intr_context = !QueryIntrContext();
5658 if ( is_intr_context )
5659 {
5660 CpuSuspendIntr(&state);
5661 }
5662 saved_cd_mode_ps2_atapi = g_cdvdman_istruct.m_cd_mode_ps2_atapi;
5663 if ( saved_cd_mode_ps2_atapi == 1 )
5664 {
5665 if ( !(*g_cdvdreg_bf801460 & 2) || (unsigned int)GetBaseAddress(5) != (unsigned int)0xBF410000 )
5666 {
5667 set_cdvd_dev5_base_addr_atapi(1);
5668 }
5669 }
5670 else
5671 {
5672 if ( (*g_cdvdreg_bf801460 & 2) || (unsigned int)GetBaseAddress(5) != (unsigned int)0x1F402000 )
5673 {
5674 set_cdvd_dev5_base_addr_atapi(2);
5675 }
5676 }
5677 if ( is_intr_context )
5678 {
5679 CpuResumeIntr(state);
5680 }
5681 return saved_cd_mode_ps2_atapi;
5682}
5683#endif
5684
5685#ifdef CDVD_VARIANT_XOSD
5686static int set_cdvd_dev5_base_addr_atapi(int mode)
5687{
5688 int is_intr_context;
5689 int state;
5690
5691 is_intr_context = !QueryIntrContext();
5692 if ( is_intr_context )
5693 {
5694 CpuSuspendIntr(&state);
5695 }
5696 if ( mode == 1 )
5697 {
5698 SetBaseAddress(5, 0xBF410000);
5699 VERBOSE_KPRINTF(1, "DEV5-addr : 0x%08lx\n", GetBaseAddress(5));
5700 SetDelay(5, 0xEF101043);
5701 VERBOSE_KPRINTF(1, "DEV5-dely : 0x%08lx\n", GetDelay(5));
5702 *g_cdvdreg_bf801464 |= 0xC;
5703 *g_cdvdreg_bf801460 |= 0x40;
5704 *g_cdvdreg_bf801460 |= 2;
5705 }
5706 else
5707 {
5708 SetBaseAddress(5, 0x1F402000);
5709 VERBOSE_KPRINTF(1, "DEV5-addr : 0x%08lx\n", GetBaseAddress(5));
5710 SetDelay(5, 0x6F060011);
5711 VERBOSE_KPRINTF(1, "DEV5-dely : 0x%08lx\n", GetDelay(5));
5712 *g_cdvdreg_bf801460 &= ~2;
5713 *g_cdvdreg_bf801460 &= ~0x40;
5714 *g_cdvdreg_bf801464 &= 0xF3;
5715 }
5716 if ( is_intr_context )
5717 {
5718 CpuResumeIntr(state);
5719 }
5720 return 1;
5721}
5722#endif
5723
5724#ifdef CDVD_VARIANT_XOSD
5725static int cdvdman_change_drive(int mode)
5726{
5727 ClearEventFlag(g_cdvdman_csys_evfid, ~1);
5728 if ( mode == 1 )
5729 {
5730 VERBOSE_KPRINTF(1, "Init Go SCECdChgWriDrv\n");
5731 ClearEventFlag(g_fio_fsv_evfid, ~1);
5732 ClearEventFlag(g_sfile_evfid, ~1);
5733 ClearEventFlag(g_scmd_evfid, ~1);
5734 ClearEventFlag(g_ncmd_evfid, ~1);
5735 set_cdvd_dev5_base_addr_atapi(1);
5736 if ( g_cd_atapi_evfid != -1 )
5737 {
5738 SetEventFlag(g_cd_atapi_evfid, 3);
5739 }
5740 if ( g_adma_evfid != -1 )
5741 {
5742 SetEventFlag(g_adma_evfid, 1);
5743 }
5744 if ( g_acmd_evfid != -1 )
5745 {
5746 SetEventFlag(g_acmd_evfid, 1);
5747 }
5748 SetEventFlag(g_scmd_evfid, 1);
5749 VERBOSE_KPRINTF(1, "Init Go SCECdChgWriDrv End.\n");
5750 SetEventFlag(g_fio_fsv_evfid, 1);
5751 }
5752 else
5753 {
5754 VERBOSE_KPRINTF(1, "Init Go SCECdChgPs2Drv\n");
5755 ClearEventFlag(g_scmd_evfid, ~1);
5756 if ( g_acmd_evfid != -1 )
5757 {
5758 ClearEventFlag(g_acmd_evfid, ~1);
5759 }
5760 if ( g_adma_evfid != -1 )
5761 {
5762 ClearEventFlag(g_adma_evfid, ~1);
5763 }
5764 if ( g_cd_atapi_evfid != -1 )
5765 {
5766 ClearEventFlag(g_cd_atapi_evfid, ~3);
5767 }
5768 set_cdvd_dev5_base_addr_atapi(mode);
5769 SetEventFlag(g_ncmd_evfid, 1);
5770 SetEventFlag(g_scmd_evfid, 1);
5771 SetEventFlag(g_sfile_evfid, 1);
5772 SetEventFlag(g_fio_fsv_evfid, 1);
5773 VERBOSE_KPRINTF(1, "Init Go SCECdChgPs2Drv End.\n");
5774 }
5775 SetEventFlag(g_cdvdman_csys_evfid, 1);
5776 return 1;
5777}
5778#endif
5779
5780#ifdef CDVD_VARIANT_XOSD
5781// cppcheck-suppress funcArgNamesDifferent
5782int sceCdChgSys(u32 use_writer_drive)
5783{
5784 int current_mode;
5785 u32 efbits;
5786 USE_DEV5_MMIO_HWPORT();
5787
5788 VERBOSE_KPRINTF(1, "sceCdChgSys(%d) start.\n", use_writer_drive);
5789 if ( QueryIntrContext() )
5790 {
5791 return 0;
5792 }
5793 WaitEventFlag(g_cdvdman_csys_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5794 current_mode = update_cd_mode_ps2_atapi();
5795 VERBOSE_KPRINTF(
5796 1, "sceCdChgSys %d call mode:%d->%d\n", use_writer_drive, current_mode, g_cdvdman_istruct.m_cd_mode_ps2_atapi);
5797 if ( !use_writer_drive )
5798 {
5799 g_cdvdman_istruct.m_cd_mode_ps2_atapi = current_mode;
5800 }
5801 if (
5802 use_writer_drive
5803 && (use_writer_drive != (u32)current_mode || g_cdvdman_istruct.m_cd_mode_ps2_atapi != current_mode) )
5804 {
5805 int disc_type;
5806
5807 if ( use_writer_drive == 1 )
5808 {
5809 VERBOSE_KPRINTF(1, "Go SCECdChgWriDrv\n");
5810 VERBOSE_KPRINTF(1, "fio_fsv_evfid\n");
5811 WaitEventFlag(g_fio_fsv_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5812 VERBOSE_KPRINTF(1, "sfile_evfid\n");
5813 WaitEventFlag(g_sfile_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5814 VERBOSE_KPRINTF(1, "sceCdSync\n");
5815 sceCdSync(0);
5816 VERBOSE_KPRINTF(1, "scmd_evfid\n");
5817 WaitEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5818 VERBOSE_KPRINTF(1, "ncmd_evfid\n");
5819 WaitEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5820 set_cdvd_dev5_base_addr_atapi(2);
5821 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5822 if ( g_cdvdman_vernotxxx1x )
5823 {
5824 if ( (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5825 {
5826 g_cdvdman_istruct.m_chgsys_writer_drive_shell_is_open = 1;
5827 }
5828 if (
5829 (!(dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen))
5830 || (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5831 {
5832 int last_err;
5833
5834 last_err = 2;
5835 while ( last_err != SCECdErNO && last_err != SCECdErABRT )
5836 {
5837 VERBOSE_KPRINTF(1, "GO->Atapi sceCdChgSpdlCtrl Call %d\n", 0);
5838 while ( !sceCdChgSpdlCtrl(0) )
5839 {
5840 DelayThread(16000);
5841 }
5842 sceCdSync(3);
5843 last_err = sceCdGetError();
5844 if ( last_err != SCECdErNO )
5845 {
5846 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl ERR 0x%02x\n", last_err);
5847 DelayThread(250000);
5848 }
5849 }
5850 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl OK\n", last_err);
5851 }
5852 }
5853 set_cdvd_dev5_base_addr_atapi(1);
5854 g_cdvdman_istruct.m_cd_mode_ps2_atapi = 1;
5855 if (
5856 g_cdvdman_vernotxxx1x && disc_type != SCECdNODISC && g_cdvdman_istruct.m_chgsys_callback_next_disktype_last
5857 && g_cdvdman_istruct.m_chgsys_callback )
5858 {
5859 int i;
5860
5861 for ( i = 0;
5862 i < 10 && g_cdvdman_istruct.m_chgsys_callback(&g_cdvdman_istruct.m_chgsys_callback_next_disktype, 1);
5863 i += 1 )
5864 {
5865 DelayThread(16000);
5866 }
5867 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = SCECdNODISC;
5868 }
5869 if ( g_cd_atapi_evfid != -1 )
5870 {
5871 SetEventFlag(g_cd_atapi_evfid, 3);
5872 }
5873 if ( g_adma_evfid != -1 )
5874 {
5875 SetEventFlag(g_adma_evfid, 1);
5876 }
5877 if ( g_acmd_evfid != -1 )
5878 {
5879 SetEventFlag(g_acmd_evfid, 1);
5880 }
5881 SetEventFlag(g_scmd_evfid, 1);
5882 SetEventFlag(g_fio_fsv_evfid, 1);
5883 VERBOSE_KPRINTF(1, "Go SCECdChgWriDrv End.\n");
5884 }
5885 else
5886 {
5887 VERBOSE_KPRINTF(1, "Go SCECdChgPs2Drv\n");
5888 VERBOSE_KPRINTF(1, "scmd_evfid\n");
5889 WaitEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5890 if ( g_acmd_evfid != -1 )
5891 {
5892 VERBOSE_KPRINTF(1, "g_acmd_evfid Wait\n");
5893 WaitEventFlag(g_acmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5894 }
5895 if ( g_adma_evfid != -1 )
5896 {
5897 VERBOSE_KPRINTF(1, "g_adma_evfid Wait\n");
5898 WaitEventFlag(g_adma_evfid, 1, WEF_AND | WEF_CLEAR, &efbits);
5899 }
5900 if ( g_cd_atapi_evfid != -1 )
5901 {
5902 VERBOSE_KPRINTF(1, "g_cd_atapi_evfid Wait\n");
5903 WaitEventFlag(g_cd_atapi_evfid, 3, WEF_AND | WEF_CLEAR, &efbits);
5904 }
5905 VERBOSE_KPRINTF(1, "evflg Ok\n");
5906 set_cdvd_dev5_base_addr_atapi(1);
5907 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5908 if ( g_cdvdman_vernotxxx1x )
5909 {
5910 set_cdvd_dev5_base_addr_atapi(2);
5911 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5912 set_cdvd_dev5_base_addr_atapi(1);
5913 VERBOSE_KPRINTF(1, "GO->PS2 STOP ATAPI SPINDL\n");
5914 if ( disc_type == 6 && g_cdvdman_istruct.m_chgsys_callback )
5915 {
5916 int i;
5917
5918 for ( i = 0;
5919 i < 10 && g_cdvdman_istruct.m_chgsys_callback(&g_cdvdman_istruct.m_chgsys_callback_next_disktype, 0);
5920 i += 1 )
5921 {
5922 DelayThread(16000);
5923 }
5924 if ( i == 10 )
5925 {
5926 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5927 }
5928 VERBOSE_KPRINTF(1, "Atapi Set -> Dragon Media %d\n", g_cdvdman_istruct.m_chgsys_callback_next_disktype);
5929 if ( g_cdvdman_istruct.m_chgsys_callback_next_disktype == 256 )
5930 {
5931 g_cdvdman_istruct.m_chgsys_callback_next_disktype_last = g_cdvdman_istruct.m_chgsys_callback_next_disktype;
5932 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCTDVDD;
5933 }
5934 }
5935 }
5936 set_cdvd_dev5_base_addr_atapi(use_writer_drive);
5937 g_cdvdman_istruct.m_cd_mode_ps2_atapi = use_writer_drive;
5938 disc_type = dev5_mmio_hwport->m_dev5_reg_00F;
5939 if ( g_cdvdman_vernotxxx1x )
5940 {
5941 if (
5942 ((dev5_mmio_hwport->m_dev5_reg_015 & 0x80) && !(dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen))
5943 || (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5944 {
5945 int last_err;
5946
5947 last_err = 2;
5948 while ( last_err != SCECdErNO && last_err != SCECdErABRT && last_err != SCECdErPRM )
5949 {
5950 if ( (dev5_mmio_hwport->m_dev5_reg_00A & SCECdStatShellOpen) )
5951 {
5952 g_cdvdman_istruct.m_chgsys_callback_next_disktype = SCECdDETCT;
5953 }
5954 VERBOSE_KPRINTF(
5955 1,
5956 "GO->DRAGON sceCdChgSpdlCtrl Call %d Ps2MediaType %02x\n",
5957 g_cdvdman_istruct.m_chgsys_callback_next_disktype,
5958 disc_type);
5959 while ( !sceCdChgSpdlCtrl(g_cdvdman_istruct.m_chgsys_callback_next_disktype) )
5960 {
5961 DelayThread(16000);
5962 }
5963 sceCdSync(3);
5964 last_err = sceCdGetError();
5965 if ( last_err != SCECdErNO )
5966 {
5967 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl ERR 0x%02x\n", last_err);
5968 DelayThread(250000);
5969 }
5970 }
5971 VERBOSE_KPRINTF(1, "** sceCdChgSpdlCtrl OK\n");
5972 }
5973 }
5974 else
5975 {
5976 VERBOSE_KPRINTF(1, " -> Ps2 May be No media %08x\n", disc_type);
5977 }
5978 SetEventFlag(g_ncmd_evfid, 1);
5979 SetEventFlag(g_scmd_evfid, 1);
5980 SetEventFlag(g_sfile_evfid, 1);
5981 SetEventFlag(g_fio_fsv_evfid, 1);
5982 VERBOSE_KPRINTF(1, "Go SCECdChgPs2Drv End.\n");
5983 }
5984 }
5985 SetEventFlag(g_cdvdman_csys_evfid, 1);
5986 return current_mode;
5987}
5988#endif
5989
5990static int
5991cdvdman_send_ncmd(int ncmd, const void *ndata, int ndlen, int func, cdvdman_dma3_parameter_t *dma3_param, int check_cb)
5992{
5993 int i;
5994 u32 efbits;
5995 USE_DEV5_MMIO_HWPORT();
5996
5997 if ( check_cb == 1 && PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
5998 {
5999 return -1;
6000 }
6001 if (
6002 // The following direct register access was replaced with call for ioprp300x
6003 (sceCdDiskReady(8) & 0xC0) != 0x40 || !g_cdvdman_istruct.m_wait_flag
6004 || !(g_cdvdman_istruct.m_read2_flag != 1 || ncmd == 8) || !(g_cdvdman_istruct.m_read2_flag != 2 || ncmd == 6) )
6005 {
6006 if ( check_cb == 1 )
6007 {
6008 vSetEventFlag(g_ncmd_evfid, 1);
6009 }
6010 // The following direct register access was replaced with call for ioprp300x
6011 VERBOSE_KPRINTF(1, "set_cd_commnad Error\tstat %02x\n", (u8)sceCdDiskReady(8));
6012 return -1;
6013 }
6014 g_cdvdman_iocache = 0;
6015 if ( dma3_param )
6016 {
6017 cdvdman_setdma3(dma3_param);
6018 }
6019 g_cdvdman_cmdfunc = func;
6020 // The following call to sceCdGetDiskType was inlined
6021 if (
6022 !g_cdvdman_minver_10700 && g_cdvdman_ncmd == 0x06 && ncmd && ncmd != g_cdvdman_ncmd && ncmd != 0x07 && ncmd != 0x0E
6023 && ncmd != 0x08
6024#ifdef CDVD_VARIANT_XOSD
6025 && ncmd != 0x0C
6026#endif
6027 && (sceCdGetDiskType() != SCECdCDDA || ncmd == 0x03) )
6028 {
6029 g_cdvdman_ncmd_timeout.hi = 0;
6030 g_cdvdman_ncmd_timeout.lo = 0x6978000;
6031 vSetAlarm(&g_cdvdman_ncmd_timeout, ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
6032 while ( dev5_mmio_hwport->m_dev5_reg_00A != SCECdStatPause )
6033 {
6034 VERBOSE_KPRINTF(1, "Read Pause 1 chk status 0x%02x\n", dev5_mmio_hwport->m_dev5_reg_00A);
6035 if ( !g_cdvdman_ncmd_timeout.lo )
6036 {
6037 g_cdvdman_ncmd = ncmd;
6038 if ( check_cb == 1 )
6039 {
6040 vSetEventFlag(g_ncmd_evfid, 1);
6041 }
6042 KPRINTF("Time Out Pause WAIT set_cd_commnad\n");
6043 return -1;
6044 }
6045 vDelayThread(1000);
6046 }
6047 vCancelAlarm(ncmd_timeout_alarm_cb, &g_cdvdman_ncmd_timeout);
6048 }
6049 g_cdvdman_ncmd = ncmd;
6050 if ( g_cdvdman_istruct.m_dec_state )
6051 {
6052 sceCdDecSet(!!g_cdvdman_istruct.m_dec_shift, 1, g_cdvdman_istruct.m_dec_shift);
6053 }
6054 g_cdvdman_istruct.m_last_read_timeout = 0;
6055 g_cdvdman_istruct.m_cdvdman_command = ncmd;
6056 g_cdvdman_istruct.m_last_error = SCECdErNO;
6057 g_cdvdman_istruct.m_wait_flag = 0;
6058 g_cdvdman_istruct.m_thread_id = GetThreadId();
6059 if ( QueryIntrContext() )
6060 {
6061 iClearEventFlag(g_cdvdman_intr_evfid, ~1);
6062 }
6063 else
6064 {
6065 ClearEventFlag(g_cdvdman_intr_evfid, ~1);
6066 }
6067 for ( i = 0; i < ndlen; i += 1 )
6068 {
6069 dev5_mmio_hwport->m_dev5_reg_005 = ((u8 *)ndata)[i];
6070 }
6071 dev5_mmio_hwport->m_dev5_reg_004 = ncmd;
6072 if ( check_cb == 1 )
6073 {
6074 vSetEventFlag(g_ncmd_evfid, 1);
6075 }
6076 return 0;
6077}
6078
6079int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
6080{
6081 VERBOSE_KPRINTF(1, "Apply NCmd call cmd= 0x%02x\n", cmdNum);
6082 while ( cdvdman_send_ncmd(cmdNum, inBuff, inBuffSize, 0, 0, 1) < 0 )
6083 {
6084 vDelayThread(2000);
6085 }
6086 sceCdSync(4);
6087 return 1;
6088}
6089
6090int sceCdCheckCmd(void)
6091{
6092 return g_cdvdman_istruct.m_wait_flag;
6093}
6094
6095static int cdvdman_mediactl(int code)
6096{
6097 int reg_00B_tmp_1;
6098 int retval;
6099 u32 efbits;
6100 char rdata[1];
6101#ifndef CDVD_VARIANT_XOSD
6102 USE_DEV5_MMIO_HWPORT();
6103#endif
6104
6105 rdata[0] = 0;
6106 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6107 {
6108 return 0;
6109 }
6110#ifdef CDVD_VARIANT_XOSD
6111 reg_00B_tmp_1 = get_cdvd_register(0x0B) & SCECdStatShellOpen;
6112#else
6113 reg_00B_tmp_1 = dev5_mmio_hwport->m_dev5_reg_00B & SCECdStatShellOpen;
6114#endif
6115 if ( reg_00B_tmp_1 == g_cdvdman_chmedia )
6116 {
6117 retval = 0;
6118 if ( g_cdvdman_chflags[code] )
6119 {
6120 g_cdvdman_chflags[code] = 0;
6121 retval = 1;
6122 }
6123 }
6124 else
6125 {
6126 unsigned int i;
6127
6128 for ( i = 0; i < (sizeof(g_cdvdman_chflags) / sizeof(g_cdvdman_chflags[0])); i += 1 )
6129 {
6130 g_cdvdman_chflags[i] = i != (unsigned int)code;
6131 }
6132 retval = 1;
6133 }
6134#ifdef CDVD_VARIANT_XOSD
6135 if ( ((get_cdvd_register(0x0A)) & SCECdStatShellOpen) != reg_00B_tmp_1 )
6136#else
6137 if ( ((dev5_mmio_hwport->m_dev5_reg_00A) & SCECdStatShellOpen) != reg_00B_tmp_1 )
6138#endif
6139 {
6140 while ( !set_prev_command(0x05, NULL, 0, rdata, sizeof(rdata), 0) || rdata[0] )
6141 {
6142 vDelayThread(4000);
6143 }
6144 }
6145#ifdef CDVD_VARIANT_XOSD
6146 g_cdvdman_chmedia = get_cdvd_register(0x0B) & 1;
6147#else
6148 g_cdvdman_chmedia = dev5_mmio_hwport->m_dev5_reg_00B & SCECdStatShellOpen;
6149#endif
6150 vSetEventFlag(g_scmd_evfid, 1);
6151 return retval;
6152}
6153
6154int sceCdGetError(void)
6155{
6156 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
6157 {
6158 VERBOSE_KPRINTF(1, "sceCdGetError: 0x%02x\n", (u8)g_cdvdman_istruct.m_last_error);
6159 }
6160 return (u8)g_cdvdman_istruct.m_last_error;
6161}
6162
6163#ifdef DEAD_CODE
6164int cdvdman_get_last_command(void)
6165{
6166 return (u8)g_cdvdman_istruct.m_cdvdman_command;
6167}
6168#endif
6169
6170int sceCdNop(void)
6171{
6172 return cdvdman_send_ncmd(0x00, NULL, 0, 0, 0, 1) >= 0;
6173}
6174
6175#ifdef DEAD_CODE
6176int cdvdman_ncmd_sender_01(void)
6177{
6178 return cdvdman_send_ncmd(0x01, NULL, 0, 0, 0, 1) >= 0;
6179}
6180#endif
6181
6182#ifndef CDVD_VARIANT_XOSD
6183static int cdvdman_ncmd_sender_06(void)
6184{
6185 int i;
6186 cdvdman_dma3_parameter_t dma3_param;
6187 char ndata[11];
6188
6189 // The following call to sceCdGetDiskType was inlined
6190 if ( sceCdGetDiskType() == SCECdNODISC )
6191 {
6192 return 1;
6193 }
6194 for ( i = 0; i < 48; i += 8 )
6195 {
6196 // The following Kprintf was removed for ioprp300x
6197 KPRINTF("CMD_READP call\n");
6198 ndata[0] = i + 17;
6199 ndata[3] = 0;
6200 ndata[2] = 0;
6201 ndata[1] = 0;
6202 ndata[4] = 8;
6203 ndata[7] = 0;
6204 ndata[6] = 0;
6205 ndata[5] = 0;
6206 ndata[8] = 0;
6207 ndata[9] = 1;
6208 ndata[10] = 0;
6209 dma3_param.m_cdvdreg_howto = 128;
6210 dma3_param.m_dma3_blkwords = 32;
6211 dma3_param.m_dma3_blkcount = 128;
6212 dma3_param.m_dma3_csectors = 0;
6213 dma3_param.m_dma3_msectors = 0;
6214 dma3_param.m_dma3_callback = 0;
6215 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
6216 if ( cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 5, &dma3_param, 1) < 0 )
6217 {
6218 return 0;
6219 }
6220 sceCdSync(3);
6221 }
6222 return 1;
6223}
6224#endif
6225
6226int sceCdStandby(void)
6227{
6228 cdvdman_dma3_parameter_t dma3_param;
6229 char ndata[11];
6230
6231#ifdef CDVD_VARIANT_XOSD
6232 switch ( get_disk_type_ex() )
6233#else
6234 // The following call to sceCdGetDiskType was inlined
6235 switch ( sceCdGetDiskType() )
6236#endif
6237 {
6238 case SCECdPSCD:
6239 case SCECdPSCDDA:
6240 case SCECdPS2CD:
6241 case SCECdPS2CDDA:
6242 case SCECdPS2DVD:
6243 ndata[0] = 16;
6244 ndata[4] = 1;
6245 ndata[9] = 1;
6246 dma3_param.m_cdvdreg_howto = 128;
6247 dma3_param.m_dma3_blkwords = 32;
6248 dma3_param.m_dma3_blkcount = 16;
6249 ndata[3] = 0;
6250 ndata[2] = 0;
6251 ndata[1] = 0;
6252 ndata[7] = 0;
6253 ndata[6] = 0;
6254 ndata[5] = 0;
6255 ndata[8] = 0;
6256 ndata[10] = 0;
6257 dma3_param.m_dma3_csectors = 0;
6258 dma3_param.m_dma3_msectors = 0;
6259 dma3_param.m_dma3_callback = 0;
6260 dma3_param.m_dma3_maddress = g_cdvdman_ptoc;
6261 return cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 5, &dma3_param, 1) >= 0;
6262 default:
6263 return cdvdman_send_ncmd(0x02, NULL, 0, 5, 0, 1) >= 0;
6264 }
6265}
6266
6267int sceCdStop(void)
6268{
6269 return cdvdman_send_ncmd(0x03, NULL, 0, 6, 0, 1) >= 0;
6270}
6271
6272int sceCdPause(void)
6273{
6274 return cdvdman_send_ncmd(0x04, NULL, 0, 7, 0, 1) >= 0;
6275}
6276
6277#ifdef DEAD_CODE
6278int cdvdman_ncmd_sender_0B(void)
6279{
6280 char ndata[1];
6281
6282 ndata[0] = 1;
6283 return cdvdman_send_ncmd(0x0B, ndata, sizeof(ndata), 0, 0, 1) >= 0;
6284}
6285#endif
6286
6287static unsigned int readtoc_timeout_alarm_cb(void *userdata)
6288{
6289 iop_sys_clock_t *sys_clock;
6290 USE_DEV5_MMIO_HWPORT();
6291
6292 sys_clock = (iop_sys_clock_t *)userdata;
6293 KPRINTF("Cmd Time Out %d(msec)\n", sys_clock->lo / 0x9000);
6294 dev5_mmio_hwport->m_dev5_reg_007 = 1;
6295 sys_clock->lo = 0;
6296 return 0;
6297}
6298
6299static int cdvdman_readtoc(u8 *toc, int param, int func)
6300{
6301 int last_err;
6302 cdvdman_dma3_parameter_t dma3_param;
6303 iop_sys_clock_t sysclk;
6304 char ndata[1];
6305
6306#ifdef CDVD_VARIANT_XOSD
6307 switch ( get_disk_type_ex() )
6308#else
6309 // The following call to sceCdGetDiskType was inlined
6310 switch ( sceCdGetDiskType() )
6311#endif
6312 {
6313 case SCECdPS2DVD:
6314 case SCECdDVDVR:
6315 case SCECdDVDV:
6316 dma3_param.m_cdvdreg_howto = 132;
6317 dma3_param.m_dma3_blkwords = 4;
6318 dma3_param.m_dma3_blkcount = 129;
6319 dma3_param.m_dma3_maddress = toc;
6320 dma3_param.m_dma3_msectors = 0;
6321 dma3_param.m_dma3_csectors = 0;
6322 dma3_param.m_dma3_callback = 0;
6323 ndata[0] = param;
6324 break;
6325 case SCECdPSCD:
6326 case SCECdPSCDDA:
6327 case SCECdPS2CD:
6328 case SCECdPS2CDDA:
6329 case SCECdCDDA:
6330 dma3_param.m_cdvdreg_howto = 128;
6331 dma3_param.m_dma3_blkwords = 32;
6332 dma3_param.m_dma3_blkcount = 8;
6333 dma3_param.m_dma3_maddress = toc;
6334 dma3_param.m_dma3_msectors = 0;
6335 dma3_param.m_dma3_csectors = 0;
6336 dma3_param.m_dma3_callback = 0;
6337 ndata[0] = 0;
6338 break;
6339 default:
6340 return 0;
6341 }
6342 if ( cdvdman_send_ncmd(0x09, ndata, sizeof(ndata), func, &dma3_param, 1) < 0 )
6343 {
6344 return 0;
6345 }
6346 sysclk.hi = 0;
6347 sysclk.lo = 0x15F90000;
6348 vSetAlarm(&sysclk, readtoc_timeout_alarm_cb, &sysclk);
6349 sceCdSync(3);
6350 vCancelAlarm(readtoc_timeout_alarm_cb, &sysclk);
6351 last_err = sceCdGetError();
6352 if ( g_cdvdman_minver_10700 && !sceCdPause() )
6353 {
6354 return 0;
6355 }
6356 sceCdSync(3);
6357 return last_err == SCECdErNO;
6358}
6359
6360static int cdvdman_gettoc(u8 *toc)
6361{
6362 // The following Kprintf was added for ioprp300x
6363 VERBOSE_KPRINTF(1, "sceCdReadToc() call 0x%p\n", toc);
6364 return cdvdman_readtoc(toc, 0, 3);
6365}
6366
6367#ifdef CDVD_VARIANT_OSD
6368int sceCdGetToc2(u8 *toc, int param)
6369{
6370 cdvdman_dma3_parameter_t dma3_param;
6371 char ndata[1];
6372
6373 dma3_param.m_cdvdreg_howto = 140;
6374 dma3_param.m_dma3_blkwords = 12;
6375 dma3_param.m_dma3_blkcount = 43;
6376 dma3_param.m_dma3_maddress = toc;
6377 dma3_param.m_dma3_msectors = 0;
6378 dma3_param.m_dma3_csectors = 0;
6379 dma3_param.m_dma3_callback = 0;
6380 ndata[0] = param;
6381 return cdvdman_send_ncmd(0x09, ndata, sizeof(ndata), 0, &dma3_param, 1) >= 0;
6382}
6383#endif
6384
6385u32 sceCdGetReadPos(void)
6386{
6387 int sector_sizes[4];
6388
6389 sector_sizes[0] = 0x800;
6390 sector_sizes[1] = 0x918;
6391 sector_sizes[2] = 0x924;
6392 if ( g_cdvdman_istruct.m_recover_status && g_cdvdman_istruct.m_recover_status != 3 )
6393 {
6394 return 0;
6395 }
6396 if ( g_cdvdman_cmdfunc == SCECdFuncReadCDDA || g_cdvdman_cmdfunc == 12 )
6397 {
6398 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
6399 }
6400 if ( g_cdvdman_istruct.m_read2_flag )
6401 {
6402 return g_cdvdman_readptr * sector_sizes[g_cdvdman_istruct.m_cdvdman_pattern];
6403 }
6404 if ( g_cdvdman_cmdfunc == SCECdFuncRead )
6405 {
6406 return dmac_ch_get_madr(3) - (uiptr)g_cdvdman_readbuf;
6407 }
6408 return 0;
6409}
6410
6411static int cdvdman_speedctl(u32 spindlctrl, int dvdflag, u32 maxlsn)
6412{
6413 u32 maxlsn_chk;
6414
6415 switch ( spindlctrl )
6416 {
6417 case SCECdSpinStm:
6418 return dvdflag ? 2 : 4;
6419 case SCECdSpinNom:
6420 if ( !dvdflag )
6421 {
6422 return 133;
6423 }
6424 if ( g_cdvdman_minver_10700 )
6425 {
6426 return 131;
6427 }
6428#ifdef CDVD_VARIANT_OSD
6429 // From DVD Player 3.11
6430 maxlsn_chk = 0x1C9000;
6431#else
6432 maxlsn_chk = 0x128000;
6433#endif
6434 if ( g_cdvdman_istruct.m_opo_or_para )
6435 {
6436 maxlsn -= (maxlsn >= (u32)g_cdvdman_istruct.m_layer_1_lsn) ? g_cdvdman_istruct.m_layer_1_lsn : 0;
6437#ifdef CDVD_VARIANT_OSD
6438 // From DVD Player 3.11
6439 maxlsn_chk = 0x197000;
6440#else
6441 maxlsn_chk = 0x165000;
6442#endif
6443 }
6444 if ( maxlsn >= maxlsn_chk )
6445 {
6446 VERBOSE_KPRINTF(1, "Kprob Spd D lsn= %d\n", maxlsn);
6447 return 130;
6448 }
6449 return 133;
6450 case SCECdSpinX1:
6451 case 0xE:
6452 return 1;
6453 case SCECdSpinX2:
6454 return 2;
6455 case SCECdSpinX4:
6456 return dvdflag ? 2 : 131;
6457 case SCECdSpinX12:
6458 return dvdflag ? 3 : 4;
6459 case SCECdSpinNm2:
6460 return 64;
6461 case 0xC:
6462 return dvdflag ? 4 : 2;
6463 case 0xF:
6464 return 130;
6465 case 0x10:
6466 return dvdflag ? 130 : 131;
6467 case 0x11:
6468 return dvdflag ? 130 : 132;
6469 case 0x12:
6470 return dvdflag ? 1 : 131;
6471 case SCECdSpinMx:
6472 return dvdflag ? 3 : 5;
6473 default:
6474 return dvdflag ? 131 : 133;
6475 }
6476}
6477
6478static int cdvdman_isdvd(void)
6479{
6480 // The following call to sceCdGetDiskType was inlined
6481#ifdef CDVD_VARIANT_XOSD
6482 switch ( get_disk_type_ex() )
6483#else
6484 switch ( sceCdGetDiskType() )
6485#endif
6486 {
6487 case SCECdPSCD:
6488 case SCECdPSCDDA:
6489 case SCECdPS2CD:
6490 case SCECdPS2CDDA:
6491 case SCECdCDDA:
6492 g_cdvdman_istruct.m_tray_is_open = 1;
6493 return 0;
6494 case SCECdPS2DVD:
6495 case SCECdDVDVR:
6496 case SCECdDVDV:
6497 g_cdvdman_istruct.m_tray_is_open = 1;
6498 return 1;
6499 default:
6500 return 0;
6501 }
6502}
6503
6504static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func)
6505{
6506 cdvdman_dma3_parameter_t dma3_param;
6507 char ndata[11];
6508
6509 g_cdvdman_readbuf = buf;
6510 VERBOSE_KPRINTF(1, "sceCdRead0_Rty Lsn:%d nsec:%d dintrnsec %d func %08x\n", lsn, nsec, dintrsec, func);
6511 *(u32 *)ndata = lsn;
6512 *(u32 *)&ndata[4] = nsec;
6513 ndata[8] = mode->trycount;
6514 ndata[9] = cdvdman_speedctl(mode->spindlctrl, cdvdman_isdvd(), lsn + nsec);
6515 dma3_param.m_dma3_csectors = dintrsec;
6516 dma3_param.m_dma3_callback = (int (*)(void))func;
6517 dma3_param.m_dma3_msectors = nsec;
6518 dma3_param.m_dma3_maddress = buf;
6519 dma3_param.m_dma3_blkcount = (!(u16)dintrsec) ? nsec : 1;
6520 switch ( ncmd )
6521 {
6522 case 0x06:
6523 ndata[10] = mode->datapattern;
6524 switch ( mode->datapattern )
6525 {
6526 case SCECdSecS2328:
6527 dma3_param.m_dma3_blkwords = 6;
6528 dma3_param.m_dma3_blkcount *= 97;
6529 dma3_param.m_cdvdreg_howto = 134;
6530 break;
6531 case SCECdSecS2340:
6532 dma3_param.m_dma3_blkwords = 15;
6533 dma3_param.m_dma3_blkcount *= 39;
6534 dma3_param.m_cdvdreg_howto = 143;
6535 break;
6536 case SCECdSecS2048:
6537 default:
6538 dma3_param.m_dma3_blkwords = 32;
6539 dma3_param.m_dma3_blkcount *= 16;
6540 dma3_param.m_cdvdreg_howto = 128;
6541 break;
6542 }
6543 break;
6544 case 0x08:
6545 dma3_param.m_dma3_blkwords = 12;
6546 dma3_param.m_dma3_blkcount *= 43;
6547 dma3_param.m_cdvdreg_howto = 140;
6548 ndata[10] = 0;
6549 break;
6550 default:
6551 return 0;
6552 }
6553 return cdvdman_send_ncmd(ncmd, ndata, sizeof(ndata), ncmd == 0x06 ? 1 : 14, &dma3_param, 0) >= 0;
6554}
6555
6556int sceCdRead0(u32 lsn, u32 sectors, void *buffer, sceCdRMode *mode, int csec, void *callback)
6557{
6558 cdvdman_dma3_parameter_t dma3_param;
6559 char ndata[11];
6560 u32 efbits;
6561
6562 if ( PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
6563 {
6564 return 0;
6565 }
6566 VERBOSE_KPRINTF(
6567 1,
6568 "DVD/CD sceCdRead0 sec %d num %d spin %d trycnt %d dptn %d adr %08x\n",
6569 lsn,
6570 sectors,
6571 mode->spindlctrl,
6572 mode->trycount,
6573 mode->datapattern,
6574 buffer);
6575 g_cdvdman_readbuf = buffer;
6576 dma3_param.m_dma3_csectors = (csec && (sectors < (u32)csec)) ? sectors : (u32)csec;
6577 dma3_param.m_dma3_callback = (int (*)(void))callback;
6578 dma3_param.m_dma3_msectors = sectors;
6579 dma3_param.m_dma3_blkcount = (!csec) ? sectors : 1;
6580 switch ( mode->datapattern )
6581 {
6582 case SCECdSecS2328:
6583 dma3_param.m_dma3_blkwords = 6;
6584 dma3_param.m_dma3_blkcount *= 97;
6585 dma3_param.m_cdvdreg_howto = 134;
6586 break;
6587 case SCECdSecS2340:
6588 dma3_param.m_dma3_blkwords = 15;
6589 dma3_param.m_dma3_blkcount *= 39;
6590 dma3_param.m_cdvdreg_howto = 143;
6591 break;
6592 case SCECdSecS2048:
6593 default:
6594 dma3_param.m_dma3_blkwords = 32;
6595 dma3_param.m_dma3_blkcount *= 16;
6596 dma3_param.m_cdvdreg_howto = 128;
6597 break;
6598 }
6599 // The following call to sceCdGetDiskType was inlined
6600#ifdef CDVD_VARIANT_OSD
6601 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
6602#else
6603 switch ( sceCdGetDiskType() )
6604 {
6605 case SCECdPSCD:
6606 case SCECdPSCDDA:
6607 case SCECdPS2CD:
6608 case SCECdPS2CDDA:
6609 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
6610 {
6611 vSetEventFlag(g_ncmd_evfid, 1);
6612 return 0;
6613 }
6614 g_cdvdman_istruct.m_dvd_flag = 0;
6615 break;
6616 case SCECdPS2DVD:
6617 if ( g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF )
6618 {
6619 vSetEventFlag(g_ncmd_evfid, 1);
6620 return 0;
6621 }
6622 g_cdvdman_istruct.m_dvd_flag = 1;
6623 break;
6624 default:
6625 vSetEventFlag(g_ncmd_evfid, 1);
6626 return 0;
6627 }
6628#endif
6629 g_cdvdman_istruct.m_read_mode = *mode;
6630 g_cdvdman_istruct.m_read_callback = callback;
6631 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
6632 g_cdvdman_istruct.m_read_lsn = lsn;
6633 g_cdvdman_istruct.m_read_sectors = sectors;
6634 *(u32 *)ndata = lsn;
6635 *(u32 *)&ndata[4] = sectors;
6636 ndata[8] = mode->trycount;
6637 ndata[9] = cdvdman_speedctl(mode->spindlctrl, g_cdvdman_istruct.m_dvd_flag, lsn + sectors);
6638 g_cdvdman_istruct.m_read_buf = buffer;
6639 ndata[10] = mode->datapattern;
6640 dma3_param.m_dma3_maddress = buffer;
6641 VERBOSE_KPRINTF(1, "Read Command call\n");
6642 if ( cdvdman_send_ncmd(0x06, ndata, sizeof(ndata), 1, &dma3_param, 0) < 0 )
6643 {
6644 vSetEventFlag(g_ncmd_evfid, 1);
6645 return 0;
6646 }
6647 vSetEventFlag(g_ncmd_evfid, 1);
6648 return 1;
6649}
6650
6651static int read_cdvd_cb(cdvdman_internal_struct_t *common)
6652{
6653 int sblock;
6654 int i;
6655 u32 cdreadlsn;
6656 int syncdec_res_1;
6657 sceCdlLOCCD cdrloc;
6658
6659 sblock = 0;
6660 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
6661 {
6662 char syncdec_res_4;
6663 int errlsn;
6664
6665 syncdec_res_4 = 0;
6666 if ( common->m_read2_flag == 3 )
6667 {
6668 sblock = 0x924;
6669 cdrloc.minute = cdvdman_syncdec(
6670 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
6671 cdrloc.second = cdvdman_syncdec(
6672 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1]);
6673 cdrloc.sector = cdvdman_syncdec(
6674 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2]);
6675 cdreadlsn = sceCdPosToInt(&cdrloc);
6676 }
6677 else
6678 {
6679 sblock = 0x810;
6680 syncdec_res_1 = (u8)cdvdman_syncdec(
6681 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 3]);
6682 syncdec_res_1 +=
6683 (u8)cdvdman_syncdec(
6684 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 2])
6685 << 8;
6686 syncdec_res_1 +=
6687 (u8)cdvdman_syncdec(
6688 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock) + 1])
6689 << 16;
6690 syncdec_res_4 = cdvdman_syncdec(
6691 common->m_dec_state, common->m_check_version, common->m_dec_shift, g_cdvdman_ptoc[(i * sblock)]);
6692 if ( !common->m_cdvdman_dma3sec && !common->m_interupt_read_state )
6693 {
6694 common->m_interupt_read_state = (syncdec_res_4 & 0xC) | (((syncdec_res_4 & 0xC) && i) ? 0x80 : 0);
6695 }
6696 cdreadlsn = (syncdec_res_1 - 0x30000) + (( common->m_opo_or_para && ((unsigned int)(common->m_cdvdman_lsn + common->m_cdvdman_csec + i) >= common->m_layer_1_lsn && common->m_opo_or_para == 1) ) ? common->m_layer_1_lsn : 0);
6697 }
6698 errlsn = common->m_cdvdman_lsn + common->m_cdvdman_csec + common->m_cdvdman_dma3sec + i;
6699 if ( cdreadlsn != (u32)errlsn )
6700 {
6701 VERBOSE_KPRINTF(
6702 1, "Read_IOP Sector_ID error lsn= %d readlsn= %d layer= %d\n", errlsn, cdreadlsn, (syncdec_res_4 & 1));
6703 break;
6704 }
6705 }
6706 if ( i == common->m_dma3_param.m_dma3_csectors )
6707 {
6708 unsigned int size;
6709
6710 size = 0;
6711 switch ( common->m_cdvdman_pattern )
6712 {
6713 case 0:
6714 size = 0x800;
6715 break;
6716 case 1:
6717 default:
6718 size = 0x918;
6719 break;
6720 case 2:
6721 optimized_memcpy(
6722 &((char *)(common->m_cdvdman_rbuffer))[0x924 * common->m_cdvdman_dma3sec],
6723 (const char *)g_cdvdman_ptoc,
6724 0x924 * i);
6725 break;
6726 }
6727 if ( size )
6728 {
6729 for ( i = 0; i < common->m_dma3_param.m_dma3_csectors; i += 1 )
6730 {
6731 optimized_memcpy(
6732 &((char *)(common->m_cdvdman_rbuffer))[(common->m_cdvdman_dma3sec + i) * size],
6733 (const char *)&g_cdvdman_ptoc[12 + (i * sblock)],
6734 size);
6735 }
6736 }
6737 g_cdvdman_readptr = common->m_cdvdman_csec + common->m_cdvdman_dma3sec;
6738 }
6739 else
6740 {
6741 common->m_sync_error += 1;
6742 }
6743 return 1;
6744}
6745
6746static int cdvdman_read(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int decflag, int shift, int ef1, int ef2)
6747{
6748 int read_res;
6749 int state;
6750 int scres_unused;
6751 int dvd;
6752 int ready;
6753
6754 dvd = cdvdman_isdvd();
6755 if ( dvd )
6756 {
6757 if ( !DvdDual_infochk() )
6758 {
6759 if ( ef1 )
6760 {
6761 vSetEventFlag(ef1, ef2);
6762 }
6763 return 0;
6764 }
6765 lsn = sceCdLsnDualChg(lsn);
6766 }
6767 else if ( mode->datapattern == SCECdSecS2328 || (g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state) )
6768 {
6769 int read0_res;
6770
6771 if ( g_cdvdman_cd36key && !g_cdvdman_istruct.m_dec_state && mode->spindlctrl == SCECdSpinNom )
6772 {
6773 mode->spindlctrl = SCECdSpinStm;
6774 }
6775 CpuSuspendIntr(&state);
6776 read0_res = sceCdRead0(lsn, sectors, buf, mode, 0, 0);
6777 if ( ef1 )
6778 {
6779 vSetEventFlag(ef1, ef2);
6780 }
6781 CpuResumeIntr(state);
6782 return read0_res;
6783 }
6784 CpuSuspendIntr(&state);
6785 ready = sceCdDiskReady(8) & 0xC0;
6786 if ( ready != 0x40 || g_cdvdman_istruct.m_read2_flag )
6787 {
6788 // The following Kprintf was modified for ioprp300x
6789 VERBOSE_KPRINTF(
6790 1,
6791 "sceCdRead: Double Booking error r2f= %d waf= %d rdy= %02x\n",
6792 g_cdvdman_istruct.m_read2_flag,
6793 g_cdvdman_istruct.m_wait_flag,
6794 ready);
6795 if ( ef1 )
6796 {
6797 vSetEventFlag(ef1, ef2);
6798 }
6799 CpuResumeIntr(state);
6800 return 0;
6801 }
6802 if ( decflag )
6803 {
6804 g_cdvdman_istruct.m_dec_shift = shift;
6805 g_cdvdman_istruct.m_dec_state = 1;
6806 }
6807 g_cdvdman_readbuf = buf;
6808 g_cdvdman_readptr = 0;
6809 g_cdvdman_istruct.m_cdvdman_lsn = lsn;
6810 g_cdvdman_istruct.m_cdvdman_csec = 0;
6811 g_cdvdman_istruct.m_cdvdman_nsec = sectors;
6812 g_cdvdman_istruct.m_cdvdman_rbuffer = (int)buf;
6813 g_cdvdman_istruct.m_cdvdman_pattern = dvd ? SCECdSecS2048 : mode->datapattern;
6814 g_cdvdman_istruct.m_cdvdman_cdrmode.trycount = mode->trycount;
6815 g_cdvdman_istruct.m_cdvdman_cdrmode.spindlctrl = mode->spindlctrl;
6816 g_cdvdman_istruct.m_cdvdman_cdrmode.datapattern = dvd ? SCECdSecS2048 : SCECdSecS2340;
6817 g_cdvdman_istruct.m_read2_flag = dvd ? 1 : 3;
6818 g_cdvdman_istruct.m_sync_error = 0;
6819 g_cdvdman_istruct.m_interupt_read_state = 0;
6820 g_cdvdman_istruct.m_cdvdman_rsec = (sectors >= 0x41) ? (((lsn & 0xF)) ? (0x10 - (lsn & 0xF)) : 0x40) : sectors;
6821 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6822 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6823 vSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6824 read_res = (dvd ? sceCdRV : sceCdRead0)(
6825 lsn,
6826 g_cdvdman_istruct.m_cdvdman_rsec,
6827 g_cdvdman_ptoc,
6828 dvd ? mode : &g_cdvdman_istruct.m_cdvdman_cdrmode,
6829 g_cdvdman_cache_sector_count,
6830 read_cdvd_cb);
6831 if ( !read_res )
6832 {
6833 g_cdvdman_istruct.m_last_error = SCECdErREADCFR;
6834 g_cdvdman_istruct.m_cdvdman_rsec = 0;
6835 g_cdvdman_istruct.m_read2_flag = 0;
6836 if ( g_cdvdman_istruct.m_dec_state )
6837 {
6838 g_cdvdman_istruct.m_dec_shift = 0;
6839 g_cdvdman_istruct.m_check_version = 0;
6840 g_cdvdman_istruct.m_dec_state = 0;
6841 sceCdDecSet(0, 0, 0);
6842 }
6843 vCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6844 }
6845 if ( ef1 )
6846 {
6847 vSetEventFlag(ef1, ef2);
6848 }
6849 CpuResumeIntr(state);
6850 return !!read_res;
6851}
6852
6853int sceCdRE(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
6854{
6855 return cdvdman_read(lsn, sectors, buf, mode, 0, 0, 0, 0);
6856}
6857
6858int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
6859{
6860 iop_event_info_t efinfo;
6861 int state;
6862
6863 // Unofficial: initialize to 0
6864 memset(&efinfo, 0, sizeof(efinfo));
6865 CpuSuspendIntr(&state);
6866 vReferEventFlagStatus(g_fio_fsv_evfid, &efinfo);
6867 if ( !(efinfo.currBits & 1) )
6868 {
6869 CpuResumeIntr(state);
6870 return 0;
6871 }
6872 vClearEventFlag(g_fio_fsv_evfid, ~1);
6873 CpuResumeIntr(state);
6874 return cdvdman_read(lbn, sectors, buffer, mode, 0, 0, g_fio_fsv_evfid, 1);
6875}
6876
6877static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data)
6878{
6879 return decflag ? ((u8)(((u8)data << (shift % 8)) | ((u8)data >> (8 - shift % 8))) ^ (u8)decxor) : (u8)data;
6880}
6881
6882static void Read2intrCDVD(int read2_flag)
6883{
6884 iCancelAlarm(read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6885 if ( g_cdvdman_istruct.m_last_error != SCECdErNO || g_cdvdman_retries >= 5 )
6886 {
6887 if ( g_cdvdman_istruct.m_last_error == SCECdErNO )
6888 {
6889 g_cdvdman_istruct.m_last_error = SCECdErREADCF;
6890 }
6891 g_cdvdman_istruct.m_read2_flag = 0;
6892 g_cdvdman_retries = 0;
6893 g_cdvdman_rtindex = 0;
6894 g_cdvdman_readptr = 0;
6895 if ( g_cdvdman_istruct.m_dec_state )
6896 {
6897 g_cdvdman_istruct.m_dec_shift = 0;
6898 g_cdvdman_istruct.m_check_version = 0;
6899 g_cdvdman_istruct.m_dec_state = 0;
6900 }
6901 g_cdvdman_istruct.m_interupt_read_state = 0;
6902 }
6903 else if ( !g_cdvdman_istruct.m_interupt_read_state || g_cdvdman_istruct.m_cdvdman_csec )
6904 {
6905 int scres_unused;
6906
6907 g_cdvdman_istruct.m_interupt_read_state = 0;
6908 if ( g_cdvdman_istruct.m_sync_error )
6909 {
6910 u32 lsn_tmp;
6911
6912 if ( !g_cdvdman_rtindex )
6913 {
6914 g_cdvdman_rtindex = 3;
6915 g_cdvdman_retries += 1;
6916 }
6917 g_cdvdman_istruct.m_sync_error = 0;
6918 lsn_tmp = g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec;
6919 if ( lsn_tmp >= 0x30 )
6920 {
6921 lsn_tmp -= 0x10 * (g_cdvdman_rtindex - 1);
6922 }
6923 else
6924 {
6925 lsn_tmp += 0x10 * (g_cdvdman_rtindex - 1);
6926 }
6927 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
6928 lsn_tmp,
6929 g_cdvdman_istruct.m_cdvdman_rsec,
6930 g_cdvdman_ptoc,
6931 &g_cdvdman_istruct.m_cdvdman_cdrmode,
6932 g_cdvdman_cache_sector_count,
6933 read_cdvd_cb) )
6934 {
6935 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6936 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6937 iSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6938 }
6939 else
6940 {
6941 VERBOSE_KPRINTF(1, "Retry Read Fatal Error\n");
6942 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
6943 g_cdvdman_istruct.m_read2_flag = 0;
6944 g_cdvdman_retries = 0;
6945 g_cdvdman_rtindex = 0;
6946 g_cdvdman_readptr = 0;
6947 if ( g_cdvdman_istruct.m_dec_state )
6948 {
6949 g_cdvdman_istruct.m_dec_shift = 0;
6950 g_cdvdman_istruct.m_check_version = 0;
6951 g_cdvdman_istruct.m_dec_state = 0;
6952 }
6953 }
6954 g_cdvdman_rtindex -= !!g_cdvdman_rtindex;
6955 }
6956 else
6957 {
6958 int cdsectorsz;
6959
6960 g_cdvdman_retries = 0;
6961 switch ( g_cdvdman_istruct.m_cdvdman_pattern )
6962 {
6963 case 0:
6964 cdsectorsz = 0x800;
6965 break;
6966 case 1:
6967 default:
6968 cdsectorsz = 0x918;
6969 break;
6970 case 2:
6971 cdsectorsz = 0x924;
6972 break;
6973 }
6974 g_cdvdman_istruct.m_cdvdman_rbuffer += cdsectorsz * g_cdvdman_istruct.m_cdvdman_rsec;
6975 g_cdvdman_istruct.m_cdvdman_csec += g_cdvdman_istruct.m_cdvdman_rsec;
6976 if ( (unsigned int)g_cdvdman_istruct.m_cdvdman_csec < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec )
6977 {
6978 g_cdvdman_istruct.m_cdvdman_rsec =
6979 ((unsigned int)(g_cdvdman_istruct.m_cdvdman_csec + 0x40) < (unsigned int)g_cdvdman_istruct.m_cdvdman_nsec) ?
6980 0x40 :
6981 (g_cdvdman_istruct.m_cdvdman_nsec - g_cdvdman_istruct.m_cdvdman_csec);
6982 if ( ((read2_flag == 3) ? sceCdRead0 : sceCdRV)(
6983 g_cdvdman_istruct.m_cdvdman_lsn + g_cdvdman_istruct.m_cdvdman_csec,
6984 g_cdvdman_istruct.m_cdvdman_rsec,
6985 g_cdvdman_ptoc,
6986 &g_cdvdman_istruct.m_cdvdman_cdrmode,
6987 g_cdvdman_cache_sector_count,
6988 read_cdvd_cb) )
6989 {
6990 g_cdvdman_read_alarm_cb_timeout.hi = 0;
6991 g_cdvdman_read_alarm_cb_timeout.lo = 0x9000 * sceCdSC(0xFFFFFFF1, &scres_unused);
6992 iSetAlarm(&g_cdvdman_read_alarm_cb_timeout, read_timeout_alarm_cb, &g_cdvdman_read_alarm_cb_timeout);
6993 }
6994 else
6995 {
6996 g_cdvdman_istruct.m_last_error = SCECdErNORDY;
6997 g_cdvdman_istruct.m_read2_flag = 0;
6998 g_cdvdman_readptr = 0;
6999 if ( g_cdvdman_istruct.m_dec_state )
7000 {
7001 g_cdvdman_istruct.m_dec_shift = 0;
7002 g_cdvdman_istruct.m_check_version = 0;
7003 g_cdvdman_istruct.m_dec_state = 0;
7004 }
7005 }
7006 }
7007 else
7008 {
7009 g_cdvdman_istruct.m_read2_flag = 0;
7010 g_cdvdman_readptr = 0;
7011 if ( g_cdvdman_istruct.m_dec_state )
7012 {
7013 g_cdvdman_istruct.m_dec_shift = 0;
7014 g_cdvdman_istruct.m_check_version = 0;
7015 g_cdvdman_istruct.m_dec_state = 0;
7016 }
7017 }
7018 }
7019 }
7020 else
7021 {
7022 g_cdvdman_istruct.m_last_error = ((g_cdvdman_istruct.m_interupt_read_state & 0x80)) ? SCECdErREADCF : SCECdErIPI;
7023 g_cdvdman_istruct.m_interupt_read_state = 0;
7024 VERBOSE_KPRINTF(1, "IPIerr emu Hit Dummy Err %02x\n", (u8)g_cdvdman_istruct.m_last_error);
7025 g_cdvdman_istruct.m_read2_flag = 0;
7026 g_cdvdman_retries = 0;
7027 g_cdvdman_rtindex = 0;
7028 g_cdvdman_readptr = 0;
7029 if ( g_cdvdman_istruct.m_dec_state )
7030 {
7031 g_cdvdman_istruct.m_dec_shift = 0;
7032 g_cdvdman_istruct.m_check_version = 0;
7033 g_cdvdman_istruct.m_dec_state = 0;
7034 }
7035 }
7036}
7037
7038int sceCdReadChain(sceCdRChain *tag, sceCdRMode *mode)
7039{
7040 (void)tag;
7041 (void)mode;
7042
7043 return 0;
7044}
7045
7046static int cdvdman_readfull(u32 lsn, u32 sectors, void *buf, const sceCdRMode *mode, int flag)
7047{
7048 cdvdman_dma3_parameter_t dma3_param;
7049 char ndata[11];
7050
7051 VERBOSE_KPRINTF(1, "lsn:%d nsec:%d buf:% cmdmode:%d\n", lsn, sectors, buf, flag);
7052 // The following Kprintf was added for ioprp300x
7053 VERBOSE_KPRINTF(1, "DA Read lsn= %d nsec= %d datapattern= %d\n", lsn, sectors, mode->datapattern);
7054 g_cdvdman_readbuf = buf;
7055#ifdef CDVD_VARIANT_XOSD
7056 dma3_param.m_dma3_csectors = sectors;
7057 dma3_param.m_dma3_msectors = (u16)sectors;
7058#else
7059 dma3_param.m_dma3_csectors = 0;
7060 dma3_param.m_dma3_msectors = 0;
7061#endif
7062 dma3_param.m_dma3_callback = 0;
7063 dma3_param.m_dma3_blkcount = sectors;
7064 switch ( mode->datapattern )
7065 {
7066 case SCECdSecS2328:
7067 dma3_param.m_dma3_blkwords = 8;
7068 dma3_param.m_dma3_blkcount *= 74;
7069 dma3_param.m_cdvdreg_howto = 136;
7070 break;
7071 case SCECdSecS2340:
7072 dma3_param.m_dma3_blkwords = 12;
7073 dma3_param.m_dma3_blkcount *= 51;
7074 dma3_param.m_cdvdreg_howto = 140;
7075 break;
7076 case SCECdSecS2048:
7077 default:
7078 dma3_param.m_dma3_blkwords = 12;
7079 dma3_param.m_dma3_blkcount *= 49;
7080 dma3_param.m_cdvdreg_howto = 140;
7081 break;
7082 }
7083 // The following call to sceCdGetDiskType() was inlined
7084#ifdef CDVD_VARIANT_XOSD
7085 switch ( get_disk_type_ex() )
7086#else
7087 switch ( sceCdGetDiskType() )
7088#endif
7089 {
7090 case SCECdPSCDDA:
7091 case SCECdPS2CDDA:
7092 case SCECdCDDA:
7093 break;
7094 default:
7095 return 0;
7096 }
7097#ifndef CDVD_VARIANT_OSD
7098 if ( g_cdvdman_mmode != SCECdMmodeCd && g_cdvdman_mmode != 0xFF )
7099 {
7100 return 0;
7101 }
7102#endif
7103 *(u32 *)ndata = lsn;
7104 *(u32 *)&ndata[4] = sectors;
7105 ndata[8] = mode->trycount;
7106 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 0, lsn + sectors);
7107 dma3_param.m_dma3_maddress = buf;
7108 ndata[10] = mode->datapattern;
7109 return cdvdman_send_ncmd((!flag) ? 0x07 : 0x0E, ndata, sizeof(ndata), (!flag) ? 2 : 12, &dma3_param, 1) >= 0;
7110}
7111
7112// cppcheck-suppress constParameterPointer
7113int sceCdReadCDDA(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
7114{
7115 return cdvdman_readfull(lbn, sectors, buffer, mode, 0);
7116}
7117
7118#ifdef CDVD_VARIANT_OSD
7119// cppcheck-suppress constParameterPointer
7120int sceCdReadFull(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
7121{
7122 return g_cdvdman_minver_20800 ? cdvdman_readfull(lsn, sectors, buf, mode, 1) :
7123 cdvdman_readfull(lsn, sectors, buf, mode, 0);
7124}
7125#endif
7126
7127int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
7128{
7129 cdvdman_dma3_parameter_t dma3_param;
7130 char ndata[11];
7131 u32 efbits;
7132
7133 if (
7134#ifdef CDVD_VARIANT_XOSD
7135 get_disk_type_ex() != SCECdPS2DVD
7136#else
7137 // The following call to sceCdGetDiskType was inlined
7139#endif
7140#ifndef CDVD_VARIANT_OSD
7141 || (g_cdvdman_mmode != SCECdMmodeDvd && g_cdvdman_mmode != 0xFF)
7142#endif
7143 || (PollEventFlag(g_ncmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND) )
7144 {
7145 return 0;
7146 }
7147 VERBOSE_KPRINTF(
7148 1, "RV read: sec %d num %d spin %d trycnt %d addr %08x\n", lsn, sectors, mode->spindlctrl, mode->trycount, buf);
7149 g_cdvdman_readbuf = buf;
7150 g_cdvdman_istruct.m_dvd_flag = cdvdman_isdvd();
7151 g_cdvdman_istruct.m_read_mode = *mode;
7152 g_cdvdman_istruct.m_read_lsn = lsn;
7153 g_cdvdman_istruct.m_read_sectors = sectors;
7154 *(u32 *)ndata = lsn;
7155 *(u32 *)&ndata[4] = sectors;
7156 ndata[8] = mode->trycount;
7157 ndata[9] = cdvdman_speedctl(mode->spindlctrl, 1, lsn + sectors);
7158 ndata[10] = 0;
7159 dma3_param.m_dma3_csectors = (arg5 && (sectors < (u32)arg5)) ? sectors : (u32)arg5;
7160 g_cdvdman_istruct.m_read_chunk = dma3_param.m_dma3_csectors;
7161 dma3_param.m_cdvdreg_howto = 140;
7162 dma3_param.m_dma3_blkwords = 12;
7163 g_cdvdman_istruct.m_read_buf = buf;
7164 dma3_param.m_dma3_blkcount = (!arg5) ? sectors : 1;
7165 dma3_param.m_dma3_blkcount *= 43;
7166 dma3_param.m_dma3_msectors = sectors;
7167 dma3_param.m_dma3_callback = (int (*)(void))cb;
7168 g_cdvdman_istruct.m_read_callback = cb;
7169 dma3_param.m_dma3_maddress = buf;
7170 if ( cdvdman_send_ncmd(0x08, ndata, sizeof(ndata), 14, &dma3_param, 0) < 0 )
7171 {
7172 vSetEventFlag(g_ncmd_evfid, 1);
7173 return 0;
7174 }
7175 vSetEventFlag(g_ncmd_evfid, 1);
7176 return 1;
7177}
7178
7179#ifdef CDVD_VARIANT_OSD
7180// cppcheck-suppress constParameterPointer
7181int sceCdReadDVDV(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
7182{
7183 cdvdman_dma3_parameter_t dma3_param;
7184 char ndata[11];
7185
7186#ifdef CDVD_VARIANT_XOSD
7187 switch ( get_disk_type_ex() )
7188#else
7189 // The following call to sceCdGetDiskType was inlined
7190 switch ( sceCdGetDiskType() )
7191#endif
7192 {
7193 case SCECdPS2DVD:
7194 case SCECdDVDVR:
7195 case SCECdDVDV:
7196 break;
7197 default:
7198 return 0;
7199 }
7200 switch ( mode->spindlctrl )
7201 {
7202 case SCECdSpinMax:
7203 case SCECdSpinX4:
7204 ndata[9] = 3;
7205 break;
7206 case SCECdSpinX1:
7207 ndata[9] = 1;
7208 break;
7209 case SCECdSpinX2:
7210 case 0xC:
7211 ndata[9] = 4;
7212 break;
7213 case 0xA:
7214 ndata[9] = 0x40;
7215 break;
7216 case 0xB:
7217 ndata[9] = 2;
7218 break;
7219 default:
7220 ndata[9] = 0x83;
7221 break;
7222 }
7223 *(u32 *)ndata = lbn;
7224 *(u32 *)&ndata[4] = sectors;
7225 dma3_param.m_cdvdreg_howto = 140;
7226 dma3_param.m_dma3_blkwords = 12;
7227 dma3_param.m_dma3_blkcount = 43 * sectors;
7228 ndata[10] = 0;
7229 dma3_param.m_dma3_maddress = buffer;
7230 dma3_param.m_dma3_msectors = 0;
7231 dma3_param.m_dma3_csectors = 0;
7232 dma3_param.m_dma3_callback = 0;
7233 ndata[8] = mode->trycount;
7234 return cdvdman_send_ncmd(0x08, ndata, sizeof(ndata), 9, &dma3_param, 1) >= 0;
7235}
7236#endif
7237
7238int sceCdSeek(u32 lbn)
7239{
7240 char ndata[4];
7241
7242 *(u32 *)ndata = lbn;
7243 if ( cdvdman_isdvd() )
7244 {
7245 if ( !DvdDual_infochk() )
7246 {
7247 return 0;
7248 }
7249 *(u32 *)ndata = sceCdLsnDualChg(lbn);
7250 }
7251 return cdvdman_send_ncmd(0x05, ndata, sizeof(ndata), 4, 0, 1) >= 0;
7252}
7253
7254#ifdef CDVD_VARIANT_XOSD
7255static unsigned int sceCdChgSpdlCtrl(int mode)
7256{
7257 unsigned int retval;
7258 char ndata[1];
7259
7260 ndata[0] = mode;
7261 retval = ~cdvdman_send_ncmd(0x0F, ndata, sizeof(ndata), 0xF, 0, 0);
7262 VERBOSE_KPRINTF(1, "Called sceCdChgSpdlCtrl mode:%d ret= %d\n", mode & 0xFF, retval >> 31);
7263 return retval >> 31;
7264}
7265#endif
7266
7267// cppcheck-suppress funcArgNamesDifferent
7268int sceCdRI(u8 *buffer, u32 *status)
7269{
7270 int retval;
7271 char rdata[9];
7272
7273 retval = set_prev_command(0x12, NULL, 0, rdata, sizeof(rdata), 1);
7274 *status = rdata[0];
7275 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7276 return retval;
7277}
7278
7279int sceCdRM(char *buffer, u32 *status)
7280{
7281 int retval;
7282 int cmd_tmp2;
7283 char rdata[9];
7284 char wdata[1];
7285 u32 efbits;
7286
7287 *status = SCECdErNO;
7288 if ( sceCdMV((u8 *)rdata, status) != 1 || (unsigned int)(rdata[3] | (rdata[2] << 8) | (rdata[1] << 16)) < 0x10500 )
7289 {
7290 strcpy(buffer, "M_NAME_UNKNOWN");
7291 buffer[15] = 0;
7292 *status |= 0x40;
7293 return 1;
7294 }
7295 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
7296 {
7297 return 0;
7298 }
7299 DelayThread(2000);
7300 wdata[0] = 0;
7301 retval = set_prev_command(0x17, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
7302 *status = rdata[0];
7303 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7304 DelayThread(2000);
7305 wdata[0] = 8;
7306 cmd_tmp2 = set_prev_command(0x17, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
7307 *status |= rdata[0];
7308 memcpy(&buffer[8], &rdata[1], sizeof(rdata) - 1);
7309 vSetEventFlag(g_scmd_evfid, 1);
7310 return retval ? (!!cmd_tmp2) : 0;
7311}
7312
7313#ifdef CDVD_VARIANT_OSD
7314// Not implemented XOSD or DVD Player 3.11
7315// cppcheck-suppress funcArgNamesDifferent
7316int sceCdWI(const u8 *buffer, u32 *status)
7317{
7318 int retres;
7319
7320 DelayThread(16000);
7321 *status = SCECdErNO;
7322 retres = set_prev_command(0x13, (const char *)buffer, 8, (char *)status, 1, 1);
7323 DelayThread(16000);
7324 return retres;
7325}
7326
7327// Not implemented XOSD or DVD Player 3.11
7328int sceCdWM(const char *buffer, u32 *status)
7329{
7330 int retres;
7331 char rdata[1];
7332 char wdata[9];
7333
7334 *status = SCECdErNO;
7335 if ( sceCdMV((u8 *)wdata, status) != 1 || (unsigned int)(wdata[3] | (wdata[2] << 8) | (wdata[1] << 16)) < 0x10500 )
7336 {
7337 *status |= 0x40;
7338 return 1;
7339 }
7340 DelayThread(2000);
7341 wdata[0] = 0;
7342 // The following was inlined
7343 memcpy(&wdata[1], &buffer[0], sizeof(wdata) - 1);
7344 retres = set_prev_command(0x18, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7345 *status = rdata[0];
7346 DelayThread(16000);
7347 wdata[0] = 8;
7348 // The following was inlined
7349 memcpy(&wdata[1], &buffer[8], sizeof(wdata) - 1);
7350 retres = set_prev_command(0x18, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && retres;
7351 *status |= rdata[0];
7352 DelayThread(16000);
7353 return !!retres;
7354}
7355
7356// cppcheck-suppress funcArgNamesDifferent
7357int sceCdReadConsoleID(u8 *buffer, u32 *status)
7358{
7359 int retval;
7360 char rdata[9];
7361 char wdata[1];
7362
7363 wdata[0] = 0x45;
7364 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7365 *status = rdata[0];
7366 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7367 return retval;
7368}
7369
7370// Not implemented XOSD or DVD Player 3.11
7371int sceCdWriteConsoleID(const u8 *buffer, u32 *status)
7372{
7373 int retval;
7374 char wdata[9];
7375
7376 DelayThread(16000);
7377 *status = SCECdErNO;
7378 wdata[0] = 0x44;
7379 memcpy(&wdata[1], buffer, 8);
7380 retval = set_prev_command(0x03, wdata, sizeof(wdata), (char *)status, 1, 1);
7381 DelayThread(16000);
7382 return retval;
7383}
7384#endif
7385
7386int sceCdMV(u8 *buffer, u32 *status)
7387{
7388 int retval;
7389 char rdata[4];
7390 char wdata[1];
7391
7392 wdata[0] = 0x00;
7393 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7394#ifdef CDVD_VARIANT_XOSD
7395 *status = SCECdErNO;
7396#else
7397 *status = rdata[0] & 0x80;
7398#endif
7399 VERBOSE_KPRINTF(1, "MV 0x%02x,0x%02x,0x%02x,0x%02x\n", (u8)rdata[0], (u8)rdata[1], (u8)rdata[2], (u8)rdata[3]);
7400#ifndef CDVD_VARIANT_XOSD
7401 rdata[0] &= ~0x80;
7402#endif
7403 memcpy(buffer, rdata, sizeof(rdata));
7404 return retval;
7405}
7406
7407#ifdef CDVD_VARIANT_XOSD
7408static int cdvdman_get_renewal_date(u8 *buffer, u32 *status)
7409{
7410 int retval;
7411 char rdata[6];
7412 char wdata[1];
7413
7414 *status = SCECdErNO;
7415 wdata[0] = 0xFD;
7416 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7417 if ( retval )
7418 {
7419 *status = (u8)rdata[0];
7420 }
7421 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7422 return retval;
7423}
7424#endif
7425
7426#ifndef CDVD_VARIANT_XOSD
7427static int cdvdman_scmd_sender_03_30(u8 *buf, u32 *status)
7428{
7429 int retval;
7430 char rdata[2];
7431 char wdata[2];
7432
7433 if ( g_cdvdman_minver_50000 )
7434 {
7435 return 0;
7436 }
7437 wdata[0] = 0x30;
7438 wdata[1] = 2;
7439 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7440 *status = (u8)rdata[0];
7441 *buf = rdata[1];
7442 return retval;
7443}
7444#endif
7445
7446#ifdef CDVD_VARIANT_OSD
7447int sceCdReadSUBQ(void *buffer, u32 *status)
7448{
7449 int retval;
7450 int i;
7451 int dev5_reg_00E;
7452 int dev5_reg_00D;
7453 int dev5_reg_00C;
7454 char rdata[11];
7455 u32 efbits;
7456 USE_DEV5_MMIO_HWPORT();
7457
7458 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
7459 {
7460 return 0;
7461 }
7462 dev5_mmio_hwport->m_dev5_reg_009 = 0;
7463 retval = cdvdman_send_scmd2(0x02, NULL, 0, rdata, sizeof(rdata), 0);
7464 memcpy(buffer, &rdata[1], sizeof(rdata) - 1);
7465 for ( i = 0; i < 10; i += 1 )
7466 {
7467 int tmp00E;
7468 int tmp00D;
7469 int tmp00C;
7470
7471 dev5_reg_00E = dev5_mmio_hwport->m_dev5_reg_00E;
7472 dev5_reg_00D = dev5_mmio_hwport->m_dev5_reg_00D;
7473 dev5_reg_00C = dev5_mmio_hwport->m_dev5_reg_00C;
7474 tmp00E = dev5_mmio_hwport->m_dev5_reg_00E;
7475 tmp00D = dev5_mmio_hwport->m_dev5_reg_00D;
7476 tmp00C = dev5_mmio_hwport->m_dev5_reg_00C;
7477 if ( dev5_reg_00E == tmp00E && dev5_reg_00D == tmp00D && dev5_reg_00C == tmp00C )
7478 {
7479 break;
7480 }
7481 }
7482 if ( i != 10 )
7483 {
7484 *((u8 *)buffer + 9) = dev5_reg_00E;
7485 *((u8 *)buffer + 8) = dev5_reg_00D;
7486 *((u8 *)buffer + 7) = dev5_reg_00C;
7487 }
7488 *status = rdata[0];
7489 vSetEventFlag(g_scmd_evfid, 1);
7490 return retval;
7491}
7492
7493// cppcheck-suppress funcArgNamesDifferent
7494int sceCdForbidDVDP(u32 *status)
7495{
7496 int retval;
7497 char rdata[1];
7498
7499 // Unofficial: NULL for wdata if length is 0
7500 retval = set_prev_command(0x15, NULL, 0, rdata, sizeof(rdata), 1);
7501 *status = (u8)rdata[0];
7502 return retval;
7503}
7504#endif
7505
7506int sceCdMmode(int media)
7507{
7508 g_cdvdman_mmode = media;
7509 return 1;
7510}
7511
7512#ifdef CDVD_VARIANT_OSD
7513// cppcheck-suppress funcArgNamesDifferent
7514int sceCdForbidRead(u32 *status)
7515{
7516 *status = SCECdErNO;
7517 // Unofficial: NULL for wdata if length is 0
7518 return set_prev_command(0x19, NULL, 0, (char *)status, 1, 1);
7519}
7520
7521int sceCdBootCertify(const u8 *romname)
7522{
7523 char rdata[1];
7524
7525 VERBOSE_KPRINTF(1, "BC %d %d %d %d\n", *romname, romname[1], romname[2], romname[3]);
7526 return set_prev_command(0x1A, (const char *)romname, 4, rdata, sizeof(rdata), 1);
7527}
7528#endif
7529
7530// cppcheck-suppress funcArgNamesDifferent
7531int sceCdCancelPOffRdy(u32 *status)
7532{
7533 *status = SCECdErNO;
7534 // Unofficial: NULL for wdata if length is 0
7535 return g_cdvdman_minver_20400 ? set_prev_command(0x1B, NULL, 0, (char *)status, 1, 1) : 1;
7536}
7537
7538#ifdef CDVD_VARIANT_OSD
7539// cppcheck-suppress funcArgNamesDifferent
7540int sceCdBlueLEDCtl(u8 control, u32 *status)
7541{
7542 char wdata[1];
7543
7544 *status = SCECdErNO;
7545 wdata[0] = control;
7546 return set_prev_command(0x1C, wdata, sizeof(wdata), (char *)status, 1, 1);
7547}
7548#endif
7549
7550static unsigned int power_off_alarm_cb(void *userdata)
7551{
7552 cdvdman_internal_struct_t *s;
7553
7554 s = (cdvdman_internal_struct_t *)userdata;
7555 s->m_power_flag = 0;
7556 return 0;
7557}
7558
7559// cppcheck-suppress funcArgNamesDifferent
7560int sceCdPowerOff(u32 *status)
7561{
7562 int retval;
7563
7564 *status = SCECdErNO;
7565 VERBOSE_KPRINTF(1, "sceCdPowerOff Call\n");
7566#ifndef CDVD_VARIANT_XOSD
7567 if ( !g_cdvdman_minver_x_model_15 )
7568 {
7569 while ( (sceCdStatus() & SCECdStatShellOpen) )
7570 {
7571 u32 traychk;
7572
7573 sceCdTrayReq(SCECdTrayClose, &traychk);
7574 vDelayThread(250000);
7575 }
7576 }
7577#endif
7578 retval = set_prev_command(0x0F, NULL, 0, (char *)status, 1, 1);
7579 if ( !retval )
7580 {
7581 g_cdvdman_istruct.m_power_flag = 0;
7582 return 0;
7583 }
7584 KPRINTF("PowerOff Start...\n");
7585 g_cdvdman_istruct.m_power_flag = 1;
7586 g_cdvdman_power_off_timeout.hi = 0;
7587 g_cdvdman_power_off_timeout.lo = 0xAFC8000;
7588 vSetAlarm(&g_cdvdman_power_off_timeout, power_off_alarm_cb, &g_cdvdman_istruct);
7589 return retval;
7590}
7591
7592int sceCdCtrlADout(int mode, u32 *status)
7593{
7594 char wdata[1];
7595
7596 *status = SCECdErNO;
7597 DelayThread(2000);
7598 VERBOSE_KPRINTF(1, "Audio Digital Out: Set param %d\n", (u8)mode);
7599 wdata[0] = mode;
7600 return set_prev_command(0x14, wdata, sizeof(wdata), (char *)status, 1, 1);
7601}
7602
7603#ifdef CDVD_VARIANT_OSD
7604// cppcheck-suppress funcArgNamesDifferent
7605int sceCdAutoAdjustCtrl(int mode, u32 *status)
7606{
7607 char wdata[1];
7608
7609 *status = SCECdErNO;
7610 DelayThread(2000);
7611 VERBOSE_KPRINTF(1, "Auto Adjust Ctrl: Set param %d\n", (u8)mode);
7612 wdata[0] = mode;
7613 return set_prev_command(0x16, wdata, sizeof(wdata), (char *)status, 1, 1);
7614}
7615
7616// TODO clock argument not const
7617int sceCdWriteWakeUpTime(const sceCdCLOCK *clock, u16 userdata, int flags)
7618{
7619 unsigned int clkmonth;
7620 unsigned int clkday;
7621 char wdata[8];
7622
7623 if ( !g_cdvdman_minver_50000 )
7624 {
7625 return 0;
7626 }
7627 clkmonth = 10 * (clock->month >> 4) + (clock->month & 0xF);
7628 clkday = 10 * (clock->day >> 4) + (clock->day & 0xF);
7629 if (
7630 (10 * (clock->second >> 4) + (clock->second & 0xF) >= 0x3C
7631 || 10 * (clock->minute >> 4) + (clock->minute & 0xF) >= 0x3C
7632 || 10 * (clock->hour >> 4) + (clock->hour & 0xF) >= 0x18 || 10 * (clock->year >> 4) + (clock->year & 0xF) >= 0x64
7633 || clkmonth >= 0xD || !clkmonth || clkday >= 0x20 || !clkday)
7634 && flags != 255 && !(clock->second & 0x80) && !(clock->minute & 0x80) )
7635 {
7636 return 0;
7637 }
7638 wdata[0] = (flags == 255) ? 255 : clock->second;
7639 wdata[1] = clock->minute | ((flags == 1) ? 0x80 : 0);
7640 wdata[2] = clock->hour;
7641 wdata[3] = clock->day;
7642 wdata[4] = clock->month;
7643 wdata[5] = clock->year;
7644 wdata[6] = userdata & 0xFF;
7645 wdata[7] = (userdata >> 8) & 0xFF;
7646 return set_prev_command(0x21, wdata, sizeof(wdata), (char *)&clock->stat, sizeof(clock->stat), 1);
7647}
7648
7649int sceCdReadWakeUpTime(sceCdCLOCK *clock, u16 *userdata, u32 *wakeupreason, int *flags)
7650{
7651 int retval;
7652 char rdata[10];
7653
7654 clock->year = 0;
7655 clock->month = 0;
7656 clock->day = 0;
7657 clock->pad = 0;
7658 clock->hour = 0;
7659 clock->minute = 0;
7660 clock->second = 0;
7661 clock->stat = 0;
7662 *userdata = 0;
7663 *wakeupreason = 0;
7664 *flags = 0;
7665 if ( !g_cdvdman_minver_50000 )
7666 {
7667 *wakeupreason = 256;
7668 return 1;
7669 }
7670 retval = set_prev_command(0x22, NULL, 0, rdata, sizeof(rdata), 1);
7671 if ( !retval )
7672 {
7673 return 0;
7674 }
7675 clock->stat = rdata[0];
7676 clock->second = (u8)rdata[2] == 255 ? -1 : (rdata[2] & 0x7F);
7677 clock->minute = rdata[3] & 0x7F;
7678 clock->pad = 0;
7679 clock->hour = rdata[4];
7680 clock->day = rdata[5];
7681 clock->month = rdata[6];
7682 clock->year = rdata[7];
7683 *userdata = (u8)rdata[8] | ((u8)rdata[9] << 8);
7684 *wakeupreason = (u8)rdata[1];
7685 *flags = (((u8)rdata[2] >> 7) << 1) | (!!(rdata[3] & 0x80));
7686 return retval;
7687}
7688
7689int sceCdSendSCmd1D(int *arg1, unsigned int *arg2, unsigned int *arg3, u32 *status)
7690{
7691 int retval;
7692 char rdata[5];
7693 u32 rdata2tmp;
7694
7695 *arg3 = 0;
7696 *arg2 = 0;
7697 *arg1 = 0;
7698 if ( !g_cdvdman_minver_50000 )
7699 {
7700 *status = 256;
7701 return 1;
7702 }
7703 *status = SCECdErNO;
7704 retval = set_prev_command(0x1D, NULL, 0, rdata, sizeof(rdata), 1);
7705 if ( retval != 1 )
7706 {
7707 return retval;
7708 }
7709 *status = (u8)rdata[0];
7710 *arg1 = (u8)rdata[1];
7711 rdata2tmp = rdata[4] | (rdata[3] << 8) | (rdata[2] << 16);
7712 switch ( *arg1 )
7713 {
7714 case 12:
7715 *arg2 = (rdata2tmp >> 17) & 0x7F;
7716 *arg3 = (rdata2tmp >> 12) & 0x1F;
7717 return 1;
7718 case 15:
7719 *arg2 = (rdata2tmp >> 17) & 0x7F;
7720 *arg3 = (rdata2tmp >> 9) & 0xFF;
7721 return 1;
7722 case 20:
7723 *arg2 = (rdata2tmp >> 17) & 0x7F;
7724 *arg3 = (rdata2tmp >> 4) & 0x1FFF;
7725 return 1;
7726 default:
7727 return 0;
7728 }
7729}
7730
7731int sceRemote2_7(u16 param, u32 *status)
7732{
7733 char wdata[2];
7734
7735 if ( !g_cdvdman_minver_50000 )
7736 {
7737 *status = 256;
7738 return 1;
7739 }
7740 *status = SCECdErNO;
7741 wdata[0] = param & 0xFF;
7742 wdata[1] = (param >> 8) & 0xFF;
7743 return set_prev_command(0x1F, wdata, sizeof(wdata), (char *)status, 1, 1);
7744}
7745
7746int sceRemote2_7Get(u32 *param, u32 *status)
7747{
7748 int retval;
7749 char rdata[3];
7750
7751 *param = 0;
7752 if ( !g_cdvdman_minver_50000 )
7753 {
7754 *status = 256;
7755 return 1;
7756 }
7757 *status = SCECdErNO;
7758 retval = set_prev_command(0x26, NULL, 0, rdata, sizeof(rdata), 1);
7759 *param = ((u8)rdata[2] << 8) | (u8)rdata[1];
7760 *status = (u8)rdata[0];
7761 return retval;
7762}
7763
7764// cppcheck-suppress funcArgNamesDifferent
7765int sceCdReadPS1BootParam(u8 *out, u32 *status)
7766{
7767 int retval;
7768 char rdata[13];
7769
7770 memset(out, 0, 11);
7771 if ( !g_cdvdman_minver_50200 )
7772 {
7773 *status = 256;
7774 return 1;
7775 }
7776 *status = SCECdErNO;
7777 retval = set_prev_command(0x27, NULL, 0, (char *)rdata, sizeof(rdata), 1);
7778 memcpy(out, &rdata[1], sizeof(rdata) - 2);
7779 *status = rdata[0];
7780 return retval;
7781}
7782
7783// cppcheck-suppress funcArgNamesDifferent
7784int sceCdSetFanProfile(u8 param, u32 *status)
7785{
7786 int retval;
7787 char rdata[1];
7788 char wdata[1];
7789
7790 if ( !g_cdvdman_minver_50400 )
7791 {
7792 *status = 256;
7793 return 1;
7794 }
7795 *status = SCECdErNO;
7796 wdata[0] = param;
7797 retval = set_prev_command(0x28, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7798 *status = (u8)rdata[0];
7799 return retval;
7800}
7801
7802int cdvdman_152_get_temperature(u32 *param, u32 *status)
7803{
7804 int retval;
7805 char rdata[3];
7806 char wdata[1];
7807
7808 if ( !g_cdvdman_minver_50400 )
7809 {
7810 *status = 256;
7811 *param = 0;
7812 return 1;
7813 }
7814 *status = SCECdErNO;
7815 wdata[0] = 0xEF;
7816 retval = set_prev_command(0x03, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7817 *param = 3125 * (((u8)rdata[2] | ((u8)rdata[1] << 8)) << 16 >> 18) / 100;
7818 *status = (u8)rdata[0];
7819 return retval;
7820}
7821#endif
7822
7823#ifdef CDVD_VARIANT_XOSD
7824// cppcheck-suppress funcArgNamesDifferent
7825int sceCdNoticeGameStart(u8 arg1, u32 *status)
7826{
7827 int retval;
7828 char rdata[1];
7829 char wdata[1];
7830
7831 if ( !g_cdvdman_minver_50400 )
7832 {
7833 *status = 256;
7834 return 1;
7835 }
7836 *status = SCECdErNO;
7837 wdata[0] = arg1;
7838 retval = set_prev_command(0x29, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7839 *status = (u8)rdata[0];
7840 if ( retval && !rdata[0] )
7841 {
7842 g_cdvdman_istruct.m_medium_removal_state = 0;
7843 }
7844 return retval;
7845}
7846#endif
7847
7848#ifdef CDVD_VARIANT_OSD
7849int sceCdRcBypassCtl(int mode, u32 *status)
7850{
7851 char wdata[1];
7852 USE_IOP_MMIO_HWPORT();
7853
7854 if ( get_mips_cop_reg(0, COP0_REG_PRId) >= 0x23 )
7855 {
7856 if ( mode & 0xFF )
7857 {
7858 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] |= 1;
7859 }
7860 else
7861 {
7862 /* 0xBF808284 */ *(u32 *)&iop_mmio_hwport->sio2.unused[0] &= ~1;
7863 }
7864 *status = SCECdErNO;
7865 return 1;
7866 }
7867 if ( !g_cdvdman_minver_50000 )
7868 {
7869 *status = 256;
7870 return 1;
7871 }
7872 *status = SCECdErNO;
7873 wdata[0] = mode;
7874 return set_prev_command(0x24, wdata, sizeof(wdata), (char *)status, 1, 1);
7875}
7876
7877// cppcheck-suppress funcArgNamesDifferent
7878int sceCdReadRegionParams(u32 *param, u32 *status)
7879{
7880 int retval;
7881 char rdata[15];
7882
7883 memset(param, 0, 15);
7884 if ( !g_cdvdman_minver_60000 )
7885 {
7886 *status = 256;
7887 return 1;
7888 }
7889 *status = SCECdErNO;
7890 retval = set_prev_command(0x36, NULL, 0, rdata, sizeof(rdata), 1);
7891 memcpy(param, &rdata[1], sizeof(rdata) - 1);
7892 *status = rdata[0];
7893 return retval;
7894}
7895
7896// Not implemented XOSD or DVD Player 3.11
7897// TODO const arg2 arg3
7898// cppcheck-suppress funcArgNamesDifferent
7899int sceCdWriteRegionParams(u8 arg1, u32 *arg2, u8 *arg3, u32 *status)
7900{
7901 char wdata[15];
7902
7903 *status = SCECdErNO;
7904 memset(wdata, 0, sizeof(wdata));
7905 if ( !g_cdvdman_minver_60600 )
7906 {
7907 *status = 256;
7908 return 1;
7909 }
7910 wdata[0] = arg1;
7911 // The following was inlined
7912 memcpy(&wdata[1], arg2, 12);
7913 // The following was inlined
7914 memcpy(&wdata[13], arg3, 2);
7915 return set_prev_command(0x3E, wdata, sizeof(wdata), (char *)status, 1, 1);
7916}
7917
7918// cppcheck-suppress funcArgNamesDifferent
7919int sceCdSetLEDsMode(u32 param, u32 *status)
7920{
7921 char wdata[1];
7922
7923 if ( !g_cdvdman_minver_50000 )
7924 {
7925 *status = 256;
7926 return 1;
7927 }
7928 *status = SCECdErNO;
7929 wdata[0] = param;
7930 return set_prev_command(0x25, wdata, sizeof(wdata), (char *)status, 1, 1);
7931}
7932#endif
7933
7934int sceCdReadClock(sceCdCLOCK *clock)
7935{
7936 int retval;
7937
7938 retval = set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7939 clock->pad = 0;
7940 clock->month &= 0x7F;
7941 if ( retval && !clock->stat )
7942 {
7943 memcpy(&g_cdvdman_clock, clock, sizeof(g_cdvdman_clock));
7944 g_cdvdman_clk_flg = 1;
7945 }
7946 else if ( g_cdvdman_clk_flg )
7947 {
7948 memcpy(clock, &g_cdvdman_clock, sizeof(g_cdvdman_clock));
7949 }
7950 else
7951 {
7952 clock->month = 3;
7953 clock->day = 4;
7954 clock->hour = 5;
7955 clock->minute = 6;
7956 clock->year = 0;
7957 clock->second = 7;
7958 }
7959 return retval;
7960}
7961
7962int sceCdRC(sceCdCLOCK *clock)
7963{
7964 return set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7965}
7966
7967#ifdef CDVD_VARIANT_OSD
7968int sceCdWriteClock(sceCdCLOCK *clock)
7969{
7970 return set_prev_command(
7971 0x09, (const char *)&clock->second, sizeof(clock) - 1, (char *)&clock->stat, sizeof(clock->second), 1);
7972}
7973
7974int sceCdReadNVM(u32 address, u16 *data, u8 *result)
7975{
7976 int retval;
7977 char rdata[3];
7978 char wdata[2];
7979
7980 wdata[0] = (address >> 8) & 0xFF;
7981 wdata[1] = address & 0xFF;
7982 retval = set_prev_command(0x0A, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
7983 *result = rdata[0];
7984 *data = (rdata[1] << 8) | rdata[2];
7985 VERBOSE_KPRINTF(1, "RN_call addr= 0x%04x data= 0x%04x stat= 0x%02x\n", address, *data, *result);
7986 return retval;
7987}
7988
7989int sceCdWriteNVM(u32 address, u16 data, u8 *result)
7990{
7991 int retval;
7992 char wdata[4];
7993
7994 wdata[0] = (address >> 8) & 0xFF;
7995 wdata[1] = address & 0xFF;
7996 wdata[2] = (data >> 8) & 0xFF;
7997 wdata[3] = data & 0xFF;
7998 retval = set_prev_command(0x0B, wdata, sizeof(wdata), (char *)result, 1, 1);
7999 VERBOSE_KPRINTF(1, "WN_call addr= 0x%04x data= 0x%04x stat= 0x%02x\n", address, data, *result);
8000 return retval;
8001}
8002#endif
8003
8004int sceCdTrayReq(int param, u32 *traychk)
8005{
8006 char wdata[1];
8007 char rdata[1];
8008#ifdef CDVD_VARIANT_XOSD
8009 int state;
8010#endif
8011
8012 if ( param == SCECdTrayCheck )
8013 {
8014 *traychk = cdvdman_mediactl(1);
8015 VERBOSE_KPRINTF(1, "Tray Req test = %d\n", *traychk);
8016 return 1;
8017 }
8018 if ( g_cdvdman_minver_x_model_15 && param == SCECdTrayClose )
8019 {
8020 return 1;
8021 }
8022 wdata[0] = param;
8023 g_cdvdman_iocache = 0;
8024#ifdef CDVD_VARIANT_XOSD
8025 CpuSuspendIntr(&state);
8026#endif
8027 rdata[0] = !!set_prev_command(0x06, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0];
8028#ifdef CDVD_VARIANT_XOSD
8029 CpuResumeIntr(state);
8030#endif
8031 if ( rdata[0] )
8032 {
8033#ifdef CDVD_VARIANT_XOSD
8034 if ( !param )
8035 {
8036 g_cdvdman_istruct.m_medium_removal_state = 0;
8037 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
8038 }
8039#endif
8040 vDelayThread(11000);
8041 }
8042 return rdata[0];
8043}
8044
8045static int cdvdman_scmd_sender_3B(int arg1)
8046{
8047 char wdata[1];
8048 char rdata[1];
8049
8050 if ( g_cdvdman_minver_x_model_15 && arg1 == 1 )
8051 {
8052 return 1;
8053 }
8054 g_cdvdman_iocache = 0;
8055 wdata[0] = arg1;
8056 if ( set_prev_command(0x3B, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0] )
8057 {
8058 vDelayThread(11000);
8059 return 1;
8060 }
8061 return 0;
8062}
8063
8064#ifdef CDVD_VARIANT_DNAS
8065int sceCdReadDiskID(unsigned int *id)
8066{
8067 sceCdRMode rmode;
8068 char sectbuf[0x800];
8069 u32 efbits;
8070 USE_DEV5_MMIO_HWPORT();
8071
8072 // The following was inlined
8073 memset(id, 0, 5);
8074#ifdef CDVD_VARIANT_XOSD
8075 switch ( get_disk_type_ex() )
8076#else
8077 switch ( sceCdGetDiskType() )
8078#endif
8079 {
8080 case SCECdPS2CD:
8081 case SCECdPS2CDDA:
8082 case SCECdPS2DVD:
8083 break;
8084 default:
8085 return 0;
8086 }
8087 rmode.spindlctrl = 0x12;
8088 rmode.datapattern = SCECdSecS2048;
8089 rmode.trycount = 0;
8090 sceCdRead0(0x4B, 1, sectbuf, &rmode, 0, 0);
8091 sceCdSync(3);
8092 if ( !cdvdman_ncmd_sender_0C(0, 0, 0x4B) )
8093 {
8094 return 0;
8095 }
8096 sceCdSync(3);
8097 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8098 {
8099 return 0;
8100 }
8101 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8102 if ( !(dev5_mmio_hwport->m_dev5_reg_038 & 4) )
8103 {
8104 vSetEventFlag(g_scmd_evfid, 1);
8105 return 0;
8106 }
8107 *(u8 *)id = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
8108 *((u8 *)id + 1) = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
8109 *((u8 *)id + 2) = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
8110 *((u8 *)id + 3) = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
8111 *((u8 *)id + 4) = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
8112 vSetEventFlag(g_scmd_evfid, 1);
8113 return 1;
8114}
8115
8116int sceCdDoesUniqueKeyExist(u32 *status)
8117{
8118 int is_cd;
8119 u8 dev5_reg_038;
8120 sceCdRMode rmode;
8121 char ndata[7];
8122 int state;
8123 u32 efbits;
8124 USE_DEV5_MMIO_HWPORT();
8125
8126 if ( !g_cdvdman_istruct.m_cd_inited )
8127 {
8128 *status = SCECdErCUD;
8129 return 0;
8130 }
8131 *status = SCECdErNO;
8132#ifdef CDVD_VARIANT_XOSD
8133 switch ( get_disk_type_ex() )
8134#else
8135 switch ( sceCdGetDiskType() )
8136#endif
8137 {
8138 case SCECdPS2CD:
8139 case SCECdPS2CDDA:
8140 is_cd = 1;
8141 break;
8142 case SCECdPS2DVD:
8143 is_cd = 0;
8144 break;
8145 default:
8146 *status = SCECdErCUD;
8147 return 0;
8148 }
8149 CpuSuspendIntr(&state);
8150 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8151 {
8152 *status = SCECdErREADCF;
8153 CpuResumeIntr(state);
8154 return 0;
8155 }
8156 if ( (sceCdStatus() & SCECdStatSpin) )
8157 {
8158 CpuResumeIntr(state);
8159 }
8160 else
8161 {
8162 dev5_mmio_hwport->m_dev5_reg_007 = 1;
8163 CpuResumeIntr(state);
8164 sceCdSync(3);
8165 }
8166 CpuSuspendIntr(&state);
8167 rmode.spindlctrl = 0x12;
8168 rmode.datapattern = SCECdSecS2048;
8169 rmode.trycount = 0;
8170 if ( is_cd )
8171 {
8172 unsigned int i;
8173
8174 for ( i = 0; i < 20; i += 1 )
8175 {
8176 sceCdRead0(0x4B + (0x10 * i), 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
8177 CpuResumeIntr(state);
8178 sceCdSync(3);
8179 CpuSuspendIntr(&state);
8180 }
8181 CpuResumeIntr(state);
8182 }
8183 else
8184 {
8185 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
8186 CpuResumeIntr(state);
8187 sceCdSync(3);
8188 }
8189 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8190 CpuSuspendIntr(&state);
8191 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8192 {
8193 *status = SCECdErREADCF;
8194 CpuResumeIntr(state);
8195 vSetEventFlag(g_scmd_evfid, 1);
8196 return 0;
8197 }
8198 // The following was inlined
8199 memset(ndata, 0, sizeof(ndata));
8200 ndata[3] = 0x4B;
8201 if ( cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) < 0 )
8202 {
8203 *status = SCECdErREADCF;
8204 CpuResumeIntr(state);
8205 vSetEventFlag(g_scmd_evfid, 1);
8206 return 0;
8207 }
8208 CpuResumeIntr(state);
8209 sceCdSync(3);
8210 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8211 {
8212 *status = (u8)g_cdvdman_istruct.m_last_error;
8213 vSetEventFlag(g_scmd_evfid, 1);
8214 return 0;
8215 }
8216 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
8217 vSetEventFlag(g_scmd_evfid, 1);
8218 return (dev5_reg_038 & 5) == 5;
8219}
8220#endif
8221
8222#ifdef CDVD_VARIANT_XOSD
8223int sceCdDeobfuscateUsingUniqueKey(u8 *buffer, unsigned int shiftval, int xorval, u32 *status)
8224{
8225 int is_cd;
8226 int retval;
8227 int i;
8228 u8 xor_val_1_stk;
8229 u8 xor_val_2_stk;
8230 u8 xor_val_3_stk;
8231 u8 xor_val_4_stk;
8232 u8 xor_val_1_xstk;
8233 u8 xor_val_2_xstk;
8234 char xorarea[16];
8235 char ndata[7];
8236 sceCdRMode rmode;
8237 int state;
8238 u32 efbits;
8239 USE_DEV5_MMIO_HWPORT();
8240
8241 memset(xorarea, 0, sizeof(xorarea));
8242 memset(buffer, 0, 16);
8243 *status = SCECdErNO;
8244 if ( shiftval >= 8 || xorval < 0 || xorval >= 256 )
8245 {
8246 *status = SCECdErREADCF;
8247 return 0;
8248 }
8249 if ( !g_cdvdman_istruct.m_cd_inited )
8250 {
8251 *status = SCECdErCUD;
8252 return 0;
8253 }
8254 switch ( get_disk_type_ex() )
8255 {
8256 case SCECdPS2CD:
8257 case SCECdPS2CDDA:
8258 is_cd = 1;
8259 break;
8260 case SCECdPS2DVD:
8261 is_cd = 0;
8262 break;
8263 default:
8264 *status = SCECdErCUD;
8265 return 0;
8266 }
8267 CpuSuspendIntr(&state);
8268 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8269 {
8270 *status = SCECdErREADCF;
8271 CpuResumeIntr(state);
8272 return 0;
8273 }
8274 if ( !(sceCdStatus() & SCECdStatSpin) )
8275 {
8276 dev5_mmio_hwport->m_dev5_reg_007 = 1;
8277 CpuResumeIntr(state);
8278 sceCdSync(3);
8279 CpuSuspendIntr(&state);
8280 }
8281 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8282 {
8283 *status = SCECdErREADCF;
8284 CpuResumeIntr(state);
8285 return 0;
8286 }
8287 rmode.spindlctrl = 0x12;
8288 rmode.datapattern = SCECdSecS2048;
8289 rmode.trycount = 0;
8290 if ( is_cd )
8291 {
8292 for ( i = 0; i < 0x14; i += 1 )
8293 {
8294 sceCdRead0(75 + 16 * i, 0x10, g_cdvdman_ptoc, &rmode, 0, 0);
8295 CpuResumeIntr(state);
8296 sceCdSync(3);
8297 CpuSuspendIntr(&state);
8298 }
8299 CpuResumeIntr(state);
8300 }
8301 else
8302 {
8303 sceCdRead0(0x4B, 1, g_cdvdman_ptoc, &rmode, 0, 0);
8304 CpuResumeIntr(state);
8305 sceCdSync(3);
8306 }
8307 WaitEventFlag(g_scmd_evfid, 1, 0, &efbits);
8308 CpuSuspendIntr(&state);
8309 if ( g_cdvdman_istruct.m_stream_flag || g_cdvdman_istruct.m_read2_flag )
8310 {
8311 *status = SCECdErREADCF;
8312 CpuResumeIntr(state);
8313 vSetEventFlag(g_scmd_evfid, 1);
8314 return 0;
8315 }
8316 // The following was inlined
8317 memset(ndata, 0, sizeof(ndata));
8318 ndata[3] = 0x4B;
8319 if ( cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) < 0 )
8320 {
8321 *status = SCECdErREADCF;
8322 CpuResumeIntr(state);
8323 vSetEventFlag(g_scmd_evfid, 1);
8324 return 0;
8325 }
8326 CpuResumeIntr(state);
8327 sceCdSync(3);
8328 if ( g_cdvdman_istruct.m_last_error != SCECdErNO )
8329 {
8330 *status = (u8)g_cdvdman_istruct.m_last_error;
8331 vSetEventFlag(g_scmd_evfid, 1);
8332 return 0;
8333 }
8334 retval = 0;
8335 xor_val_2_xstk = 0;
8336 xor_val_1_xstk = 0;
8337 xor_val_4_stk = 0;
8338 xor_val_3_stk = 0;
8339 xor_val_2_stk = 0;
8340 xor_val_1_stk = 0;
8341 if ( (dev5_mmio_hwport->m_dev5_reg_038 & 5) == 5 )
8342 {
8343 u8 dev5_reg_020;
8344 u8 dev5_reg_039;
8345 u8 dev5_reg_022;
8346 u8 reg_039_tmp1;
8347
8348 dev5_reg_020 = dev5_mmio_hwport->m_dev5_reg_020;
8349 dev5_reg_039 = dev5_mmio_hwport->m_dev5_reg_039;
8350 xor_val_1_stk = dev5_reg_020 ^ dev5_reg_039;
8351 xor_val_2_stk = dev5_reg_039 ^ dev5_mmio_hwport->m_dev5_reg_021;
8352 dev5_reg_022 = dev5_mmio_hwport->m_dev5_reg_022;
8353 reg_039_tmp1 = dev5_mmio_hwport->m_dev5_reg_039;
8354 xor_val_3_stk = dev5_reg_022 ^ reg_039_tmp1;
8355 xor_val_4_stk = reg_039_tmp1 ^ dev5_mmio_hwport->m_dev5_reg_023;
8356 xor_val_1_xstk = dev5_mmio_hwport->m_dev5_reg_024 ^ dev5_mmio_hwport->m_dev5_reg_039;
8357 xor_val_2_xstk = dev5_mmio_hwport->m_dev5_reg_039 ^ dev5_mmio_hwport->m_dev5_reg_034;
8358 retval = 1;
8359 }
8360 vSetEventFlag(g_scmd_evfid, 1);
8361 xorarea[0] = (xor_val_4_stk >> 4) | ((xor_val_1_xstk << 4) & 0x70);
8362 xorarea[1] = (xor_val_3_stk >> 5) | ((xor_val_4_stk << 3) & 0x78);
8363 xorarea[2] = (xor_val_2_stk >> 6) | ((xor_val_3_stk << 2) & 0x7C);
8364 xorarea[3] = (xor_val_1_stk >> 7) | ((xor_val_2_stk << 1) & 0x7E);
8365 sprintf(&xorarea[4], "%d", ((xor_val_1_stk & 0x7F) << 10) | (xor_val_1_xstk >> 3) | ((xor_val_2_xstk >> 3) << 5));
8366 for ( i = 0; i < 9; i += 1 )
8367 {
8368 xorarea[i] = xorarea[i] ^ xorval;
8369 }
8370 if ( shiftval )
8371 {
8372 for ( i = 0; i < 9; i += 1 )
8373 {
8374 buffer[i] = (xorarea[i] << shiftval) | ((int)(u8)xorarea[i ? i - 1 : 8] >> (8 - shiftval));
8375 }
8376 }
8377 else
8378 {
8379 // The following was inlined
8380 memcpy(buffer, xorarea, sizeof(xorarea));
8381 }
8382 return retval;
8383}
8384#endif
8385
8386#ifdef CDVD_VARIANT_OSD
8387int sceCdReadKey(u8 arg1, u8 arg2, unsigned int command, u8 *key)
8388{
8389 int i;
8390 u8 dev5_reg_038;
8391 sceCdRMode rmode;
8392 char sectorbuf[0x800];
8393 u32 efbits;
8394 USE_DEV5_MMIO_HWPORT();
8395
8396 if ( cdvdman_isdvd() && !arg1 )
8397 {
8398 if ( !DvdDual_infochk() )
8399 {
8400 return 0;
8401 }
8402 command = sceCdLsnDualChg(command);
8403 }
8404 rmode.spindlctrl = 0x12;
8405 rmode.datapattern = SCECdSecS2048;
8406 rmode.trycount = 0;
8407 sceCdRead0(command, 1, sectorbuf, &rmode, 0, 0);
8408 sceCdSync(3);
8409 for ( i = 0; i < 300; i += 1 )
8410 {
8411 if ( !cdvdman_ncmd_sender_0C(arg1, arg2, command + i) )
8412 {
8413 return 0;
8414 }
8415 sceCdSync(3);
8416 if ( g_cdvdman_istruct.m_last_error == SCECdErNO )
8417 {
8418 break;
8419 }
8420 }
8421 WaitEventFlag(g_scmd_evfid, 1, WEF_AND, &efbits);
8422 // The following was inlined
8423 memset(key, 0, 16);
8424 dev5_reg_038 = dev5_mmio_hwport->m_dev5_reg_038;
8425 if ( (dev5_reg_038 & 1) )
8426 {
8427 key[0] = dev5_mmio_hwport->m_dev5_reg_020 ^ dev5_mmio_hwport->m_dev5_reg_039;
8428 key[1] = dev5_mmio_hwport->m_dev5_reg_021 ^ dev5_mmio_hwport->m_dev5_reg_039;
8429 key[2] = dev5_mmio_hwport->m_dev5_reg_022 ^ dev5_mmio_hwport->m_dev5_reg_039;
8430 key[3] = dev5_mmio_hwport->m_dev5_reg_023 ^ dev5_mmio_hwport->m_dev5_reg_039;
8431 key[4] = dev5_mmio_hwport->m_dev5_reg_024 ^ dev5_mmio_hwport->m_dev5_reg_039;
8432 }
8433 if ( (dev5_reg_038 & 2) )
8434 {
8435 key[5] = dev5_mmio_hwport->m_dev5_reg_028 ^ dev5_mmio_hwport->m_dev5_reg_039;
8436 key[6] = dev5_mmio_hwport->m_dev5_reg_029 ^ dev5_mmio_hwport->m_dev5_reg_039;
8437 key[7] = dev5_mmio_hwport->m_dev5_reg_02A ^ dev5_mmio_hwport->m_dev5_reg_039;
8438 key[8] = dev5_mmio_hwport->m_dev5_reg_02B ^ dev5_mmio_hwport->m_dev5_reg_039;
8439 key[9] = dev5_mmio_hwport->m_dev5_reg_02C ^ dev5_mmio_hwport->m_dev5_reg_039;
8440 }
8441 if ( (dev5_reg_038 & 4) )
8442 {
8443 key[10] = dev5_mmio_hwport->m_dev5_reg_030 ^ dev5_mmio_hwport->m_dev5_reg_039;
8444 key[11] = dev5_mmio_hwport->m_dev5_reg_031 ^ dev5_mmio_hwport->m_dev5_reg_039;
8445 key[12] = dev5_mmio_hwport->m_dev5_reg_032 ^ dev5_mmio_hwport->m_dev5_reg_039;
8446 key[13] = dev5_mmio_hwport->m_dev5_reg_033 ^ dev5_mmio_hwport->m_dev5_reg_039;
8447 key[14] = dev5_mmio_hwport->m_dev5_reg_034 ^ dev5_mmio_hwport->m_dev5_reg_039;
8448 }
8449 key[15] = dev5_reg_038 & 7;
8450 vSetEventFlag(g_scmd_evfid, 1);
8451 return 1;
8452}
8453#endif
8454
8455#ifdef CDVD_VARIANT_DNAS
8456static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3)
8457{
8458 char ndata[7];
8459
8460 ndata[1] = !!arg2;
8461 ndata[0] = arg1;
8462 ndata[2] = !!(arg2 >> 8);
8463 *(u32 *)&ndata[3] = !arg1 ? arg3 : 0;
8464 return cdvdman_send_ncmd(0x0C, ndata, sizeof(ndata), 0, 0, 1) >= 0;
8465}
8466#endif
8467
8468int sceCdDecSet(u8 enable_xor, u8 enable_shift, u8 shiftval)
8469{
8470#ifdef CDVD_VARIANT_DNAS
8471 USE_DEV5_MMIO_HWPORT();
8472
8473 g_cdvdman_cd36key = enable_shift | shiftval;
8474 dev5_mmio_hwport->m_dev5_reg_03A = ((shiftval & 7) << 4) | ((!!enable_xor) << 1) | (!!enable_shift);
8475#else
8476 (void)enable_xor;
8477 (void)enable_shift;
8478 (void)shiftval;
8479#endif
8480 return 1;
8481}
8482
8483#ifdef CDVD_VARIANT_OSD
8484int sceCdOpenConfig(int block, int mode, int NumBlocks, u32 *status)
8485{
8486 int retval;
8487#ifdef CDVD_VARIANT_XOSD
8488 u32 efbits;
8489#endif
8490 char wdata[3];
8491
8492#ifdef CDVD_VARIANT_XOSD
8493 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8494 {
8495 return 0;
8496 }
8497#endif
8498 DelayThread(16000);
8499 *status = SCECdErNO;
8500 wdata[0] = (u8)mode;
8501 wdata[1] = (u8)block;
8502 wdata[2] = (u8)NumBlocks;
8503 retval = set_prev_command(0x40, wdata, sizeof(wdata), (char *)status, 1, 0);
8504#ifdef CDVD_VARIANT_XOSD
8505 if ( retval == 1 )
8506#endif
8507 {
8508 g_cdvdman_config_numblocks = NumBlocks;
8509 }
8510#ifdef CDVD_VARIANT_XOSD
8511 vSetEventFlag(g_scmd_evfid, 1);
8512#endif
8513 return retval;
8514}
8515
8516// cppcheck-suppress funcArgNamesDifferent
8517int sceCdCloseConfig(u32 *status)
8518{
8519 int retval;
8520
8521 *status = SCECdErNO;
8522 DelayThread(16000);
8523 retval = set_prev_command(0x43, NULL, 0, (char *)status, 1, 1);
8524 g_cdvdman_config_numblocks = 0;
8525 return retval;
8526}
8527
8528static int read_config_process(char *outval, u32 *status)
8529{
8530 int retval;
8531 char rdata[16];
8532
8533 DelayThread(2000);
8534 retval = set_prev_command(0x41, NULL, 0, rdata, sizeof(rdata), 0);
8535 *status = (u8)(rdata[14] + rdata[13] + rdata[12] + rdata[11] + rdata[10] + rdata[9] + rdata[8] + rdata[7] + rdata[6]
8536 + rdata[5] + rdata[4] + rdata[3] + rdata[2] + rdata[0] + rdata[1])
8537 != (u8)rdata[15];
8538 memcpy(outval, rdata, sizeof(rdata) - 1);
8539 return retval;
8540}
8541
8542// cppcheck-suppress funcArgNamesDifferent
8543int sceCdReadConfig(void *buffer, u32 *status)
8544{
8545 int retval;
8546 u32 efbits;
8547
8548 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8549 {
8550 return 0;
8551 }
8552 for ( retval = 0; retval < g_cdvdman_config_numblocks; retval += 1 )
8553 {
8554 if ( !read_config_process((char *)buffer + 15 * retval, status) )
8555 {
8556 VERBOSE_KPRINTF(1, "RC_fail Command busy\n");
8557 break;
8558 }
8559 if ( *status )
8560 {
8561 VERBOSE_KPRINTF(1, "RC_fail status: 0x%02x\n", *status);
8562 break;
8563 }
8564 }
8565 vSetEventFlag(g_scmd_evfid, 1);
8566 return retval;
8567}
8568
8569static int write_config_process(const char *inval, u32 *status)
8570{
8571 char wdata[16];
8572
8573 DelayThread(2000);
8574 *status = SCECdErNO;
8575 memcpy(wdata, inval, 15);
8576 wdata[15] = wdata[14] + wdata[13] + wdata[12] + wdata[11] + wdata[10] + wdata[9] + wdata[8] + wdata[7] + wdata[6]
8577 + wdata[5] + wdata[4] + wdata[3] + wdata[2] + wdata[0] + wdata[1];
8578 return set_prev_command(0x42, wdata, sizeof(wdata), (char *)status, 1, 0);
8579}
8580
8581// cppcheck-suppress funcArgNamesDifferent
8582int sceCdWriteConfig(const void *buffer, u32 *status)
8583{
8584 int retval;
8585 u32 efbits;
8586
8587 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8588 {
8589 return 0;
8590 }
8591 for ( retval = 0; retval < g_cdvdman_config_numblocks; retval += 1 )
8592 {
8593 if ( !write_config_process((char *)buffer + 15 * retval, status) )
8594 {
8595 VERBOSE_KPRINTF(1, "WC_fail Command busy\n");
8596 break;
8597 }
8598 if ( *status )
8599 {
8600 VERBOSE_KPRINTF(1, "WC_fail status: 0x%02x\n", *status);
8601 break;
8602 }
8603 }
8604 vSetEventFlag(g_scmd_evfid, 1);
8605 return retval;
8606}
8607
8608int sceCdSetHDMode(u32 mode)
8609{
8610 char wdata[1];
8611 char rdata[1];
8612
8613 wdata[0] = mode;
8614 return set_prev_command(0x0C, wdata, sizeof(wdata), rdata, sizeof(rdata), 1) && !rdata[0];
8615}
8616#endif
8617
8618#ifdef CDVD_VARIANT_XOSD
8619// cppcheck-suppress funcArgNamesDifferent
8620int sceCdXLEDCtl(u8 arg1, u8 arg2, u32 *param, u32 *status)
8621{
8622 int retval;
8623 char wdata[2];
8624 char rdata[2];
8625
8626 *param = 0;
8627 if ( !g_cdvdman_minver_50600 )
8628 {
8629 *status = 256;
8630 return 1;
8631 }
8632 *status = SCECdErNO;
8633 wdata[0] = arg1;
8634 wdata[1] = arg2;
8635 retval = set_prev_command(0x2D, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
8636 if ( !retval )
8637 {
8638 return 0;
8639 }
8640 *status = (u8)rdata[0];
8641 *param = (u8)rdata[1];
8642 return retval;
8643}
8644#endif
8645
8646#ifdef CDVD_VARIANT_XOSD
8647// cppcheck-suppress funcArgNamesDifferent
8648int sceCdBuzzerCtl(u32 *status)
8649{
8650 if ( !g_cdvdman_minver_50600 )
8651 {
8652 *status = 256;
8653 return 1;
8654 }
8655 *status = SCECdErNO;
8656 return set_prev_command(0x2E, NULL, 0, (char *)status, 1, 1);
8657}
8658#endif
8659
8660#ifdef CDVD_VARIANT_XOSD
8661int cdvdman_167_atapi2dragon(u8 *inbuf, u32 *status)
8662{
8663 if ( !g_cdvdman_minver_50600 )
8664 {
8665 *status = 256;
8666 return 1;
8667 }
8668 *status = SCECdErNO;
8669 return cdvdman_write_scmd_swap_dev5(0x2F, inbuf, 16, (char *)status, 1, 1);
8670}
8671#endif
8672
8673#ifdef CDVD_VARIANT_XOSD
8674int cdvdman_169_dragon2atapi(u8 *outbuf, u32 *status)
8675{
8676 int i;
8677 int retval;
8678 char rdata[9];
8679 u32 efbits;
8680 char wdata[1];
8681
8682 if ( !g_cdvdman_minver_50600 )
8683 {
8684 *status = 256;
8685 return 1;
8686 }
8687 *status = SCECdErNO;
8688 if ( vPollEventFlag(g_scmd_evfid, 1, WEF_AND | WEF_CLEAR, &efbits) == KE_EVF_COND )
8689 {
8690 return 0;
8691 }
8692 memset(outbuf, 0, 16);
8693 if ( *status )
8694 {
8695 vSetEventFlag(g_scmd_evfid, 1);
8696 return 1;
8697 }
8698 retval = 0;
8699 for ( i = 0; i < 2 && !rdata[0]; i += 1 )
8700 {
8701 wdata[0] = i * 8;
8702 retval = 0;
8703 while ( !retval )
8704 {
8705 DelayThread(2000);
8706 retval = cdvdman_write_scmd_swap_dev5(0x30, wdata, sizeof(wdata), rdata, sizeof(rdata), 0);
8707 memcpy(&outbuf[i * 8], &rdata[1], sizeof(rdata) - 1);
8708 *status = rdata[0];
8709 }
8710 }
8711 return retval;
8712}
8713#endif
8714
8715#ifdef CDVD_VARIANT_XOSD
8716// cppcheck-suppress funcArgNamesDifferent
8717int sceCdXBSPowerCtl(u8 arg1, u8 arg2, u32 *param, u32 *status)
8718{
8719 int retval;
8720 char wdata[2];
8721 char rdata[2];
8722
8723 *param = 0;
8724 if ( !g_cdvdman_minver_50600 )
8725 {
8726 *status = 256;
8727 return 1;
8728 }
8729 *status = SCECdErNO;
8730 wdata[0] = arg1;
8731 wdata[1] = arg2;
8732 retval = set_prev_command(0x2C, wdata, sizeof(wdata), rdata, sizeof(rdata), 1);
8733 if ( !retval )
8734 {
8735 return 0;
8736 }
8737 *status = (u8)rdata[0];
8738 *param = (u8)rdata[1];
8739 return retval;
8740}
8741#endif
8742
8743#ifdef CDVD_VARIANT_XOSD
8744// cppcheck-suppress funcArgNamesDifferent
8745int sceCdSetMediumRemoval(u8 wanted_val, u32 *status)
8746{
8747 int retval;
8748 int saved_medium_removal_state;
8749 char wdata[1];
8750 int state;
8751
8752 if ( !g_cdvdman_minver_50600 )
8753 {
8754 *status = 256;
8755 return 1;
8756 }
8757 *status = SCECdErNO;
8758 CpuSuspendIntr(&state);
8759 saved_medium_removal_state = g_cdvdman_istruct.m_medium_removal_state;
8760 g_cdvdman_istruct.m_medium_removal_state = (u8)wanted_val;
8761 wdata[0] = wanted_val;
8762 retval = set_prev_command(0x31, wdata, sizeof(wdata), (char *)status, 1, 1);
8763 if ( !retval || *status )
8764 {
8765 g_cdvdman_istruct.m_medium_removal_state = saved_medium_removal_state;
8766 }
8767 CpuResumeIntr(state);
8768 return retval;
8769}
8770#endif
8771
8772#ifdef CDVD_VARIANT_XOSD
8773// cppcheck-suppress funcArgNamesDifferent
8774int sceCdGetMediumRemoval(u32 *param, u32 *status)
8775{
8776 int retval;
8777 char rdata[2];
8778
8779 *param = 0;
8780 if ( !g_cdvdman_minver_50600 )
8781 {
8782 *status = 256;
8783 return 1;
8784 }
8785 *status = SCECdErNO;
8786 retval = set_prev_command(0x32, NULL, 0, rdata, sizeof(rdata), 1);
8787 if ( !retval )
8788 {
8789 return 0;
8790 }
8791 *status = (u8)rdata[0];
8792 *param = (u8)rdata[1];
8793 if ( !rdata[0] )
8794 {
8795 g_cdvdman_istruct.m_medium_removal_state = *param;
8796 }
8797 return retval;
8798}
8799#endif
8800
8801#ifdef CDVD_VARIANT_XOSD
8802// cppcheck-suppress funcArgNamesDifferent
8803int sceCdXDVRPReset(u8 arg1, u32 *status)
8804{
8805 char wdata[1];
8806
8807 if ( !g_cdvdman_minver_50600 )
8808 {
8809 *status = 256;
8810 return 1;
8811 }
8812 *status = SCECdErNO;
8813 wdata[0] = arg1;
8814 return set_prev_command(0x33, wdata, sizeof(wdata), (char *)status, 1, 1);
8815}
8816#endif
8817
8818#ifdef CDVD_VARIANT_XOSD
8819static int sc_ffffffd8(u32 *status)
8820{
8821 int retval;
8822
8823 if ( !g_cdvdman_minver_50600 )
8824 {
8825 *status = 256;
8826 return 1;
8827 }
8828 *status = SCECdErNO;
8829 retval = set_prev_command(0x34, NULL, 0, (char *)status, 1, 1);
8830 if ( !retval )
8831 {
8832 return 0;
8833 }
8834 g_cdvdman_istruct.m_atapi_disk_ejected = 0;
8835 return retval;
8836}
8837#endif
8838
8839#ifdef CDVD_VARIANT_XOSD
8840#ifdef DEAD_CODE
8841int cdvdman_scmd_sender_35(u32 *param, u32 *status)
8842{
8843 int retval;
8844 char rdata[2];
8845
8846 *param = 0;
8847 if ( !g_cdvdman_minver_50600 )
8848 {
8849 *status = 256;
8850 return 1;
8851 }
8852 *status = SCECdErNO;
8853 retval = set_prev_command(0x35, NULL, 0, rdata, sizeof(rdata), 1);
8854 if ( !retval )
8855 {
8856 return 0;
8857 }
8858 *status = (u8)rdata[0];
8859 *param = (u8)rdata[1];
8860 return retval;
8861}
8862#endif
8863#endif
int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
Definition cdvdman.c:7127
int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
Definition cdvdman.c:5441
int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
int sceCdSpinCtrlIOP(u32 speed)
Definition cdvdman.c:2183
int sceCdReadDiskID(unsigned int *id)
int sceCdDeobfuscateUsingUniqueKey(u8 *buffer, unsigned int shiftval, int xorval, u32 *status)
void * sceCdSetAtapiEjectCallback(int(*cb)(int reason, void *userdata), void *userdata)
#define ENOENT
Definition errno.h:32
#define EINVAL
Definition errno.h:72
#define EMFILE
Definition errno.h:76
#define ENOMEM
Definition errno.h:52
#define EIO
Definition errno.h:38
#define EBUSY
Definition errno.h:60
#define ENODEV
Definition errno.h:66
#define ECOMM
Definition errno.h:164
#define EPERM
Definition errno.h:30
int CpuResumeIntr(int state)
Definition intrman.c:217
int ReleaseIntrHandler(int irq)
Definition intrman.c:157
int QueryIntrContext(void)
int DisableIntr(int irq, int *res)
Definition intrman.c:385
int CpuSuspendIntr(int *state)
Definition intrman.c:195
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition intrman.c:115
int EnableIntr(int irq)
Definition intrman.c:336
#define IOP_DT_FSEXT
Definition iomanX.h:67
struct _iop_file iop_file_t
#define FIO_S_IXGRP
Definition iox_stat.h:72
#define FIO_S_IROTH
Definition iox_stat.h:77
#define FIO_S_IXUSR
Definition iox_stat.h:63
#define FIO_S_IRGRP
Definition iox_stat.h:68
#define FIO_S_IXOTH
Definition iox_stat.h:81
#define FIO_S_IRUSR
Definition iox_stat.h:59
#define FIO_S_IFDIR
Definition iox_stat.h:46
#define FIO_S_IFREG
Definition iox_stat.h:44
int sceCdReadModelID(unsigned int *id)
int sceCdXLEDCtl(u8 arg1, u8 arg2, u32 *result1, u32 *result2)
int sceCdRcBypassCtl(int mode, u32 *status)
@ STMNBLK
int sceCdStatus2(void)
int cdvdman_169_dragon2atapi(u8 *outbuf, u32 *status)
int sceCdReadRegionParams(u32 *arg1, u32 *result)
int sceRemote2_7(u16 param, u32 *status)
int sceCdSetFanProfile(u8 param, u32 *result)
int sceCdDoesUniqueKeyExist(u32 *status)
int sceCdGetMediumRemoval(u32 *result1, u32 *result2)
int sceCdReadPS1BootParam(u8 *out, u32 *result)
int sceCdXDVRPReset(u8 arg1, u32 *result)
int sceCdSetMediumRemoval(u8 arg1, u32 *result)
int sceCdSendSCmd1D(int *arg1, unsigned int *arg2, unsigned int *arg3, u32 *status)
int sceCdGetToc2(u8 *toc, int param)
int sceCdReadGUID(u64 *guid)
void(*) sceCdCBFunc(int reason)
int sceCdGetWakeUpReason(void)
int sceCdXBSPowerCtl(u8 arg1, u8 arg2, u32 *result1, u32 *result2)
int sceRemote2_7Get(u32 *param, u32 *status)
@ SCECdSpinX1
@ SCECdSpinX2
@ SCECdSpinNm2
@ SCECdSpinMax
@ SCECdSpinStm
@ SCECdSpinNom
@ SCECdSpinMx
@ SCECdSpinX12
@ SCECdSpinX4
int sceCdChgSys(u32 arg1)
@ SCECdTrayCheck
@ SCECdTrayOpen
@ SCECdTrayClose
int sceCdReadFull(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
int sceCdBuzzerCtl(u32 *result)
int cdvdman_167_atapi2dragon(u8 *inbuf, u32 *status)
@ SCECdNODISC
@ SCECdIllegalMedia
@ SCECdPSCDDA
@ SCECdPSCD
@ SCECdDETCT
@ SCECdDVDV
@ SCECdDVDVR
@ SCECdPS2DVD
@ SCECdCDDA
@ SCECdPS2CDDA
@ SCECdPS2CD
@ SCECdErEOM
@ SCECdErIPI
@ SCECdErREAD
@ SCECdErNO
@ SCECdErABRT
@ SCECdErREADCF
@ SCECdErREADCFR
@ SCECdErNORDY
@ SCECdErTRMOPN
@ SCECdErCUD
@ SCECdErFAIL
@ SCECdErPRM
int sceCdReadWakeUpTime(sceCdCLOCK *clock, u16 *userdata, u32 *wakeupreason, int *flags)
int sceCdWriteWakeUpTime(const sceCdCLOCK *clock, u16 userdata, int flags)
int cdvdman_152_get_temperature(u32 *param, u32 *status)
int sceCdSetLEDsMode(u32 param, u32 *result)
int sceCdWriteRegionParams(u8 arg1, u32 *arg2, u8 *arg3, u32 *result)
int sceCdBlueLEDCtl(u8 control, u32 *result)
@ SCECdStatSpin
@ SCECdStatPause
@ SCECdStatShellOpen
@ SCECdStatStop
@ SCECdEXIT
@ SCECdINIT
sceCdCBFunc sceCdCallback(sceCdCBFunc newFunc)
Definition libcdvd.c:324
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition libcdvd.c:167
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
Definition libcdvd.c:159
s32 sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition libcdvd.c:172
#define COP0_REG_PRId
int sceCdStStop(void)
Definition ncmd.c:625
int sceCdStRead(u32 sectorType, u32 *buffer, u32 mode, u32 *error)
Definition ncmd.c:583
int sceCdStPause(void)
Definition ncmd.c:648
int sceCdReadKey(unsigned char arg1, unsigned char arg2, unsigned int command, unsigned char *key)
Definition ncmd.c:817
int sceCdGetToc(u8 *toc)
Definition ncmd.c:302
int sceCdRead(u32 lbn, u32 sectors, void *buf, sceCdRMode *mode)
Definition ncmd.c:179
int sceCdPause(void)
Definition ncmd.c:406
int sceCdReadChain(sceCdRChain *readChain, sceCdRMode *mode)
Definition ncmd.c:494
u32 sceCdGetReadPos(void)
Definition ncmd.c:567
int sceCdSync(int mode)
Definition ncmd.c:722
int sceCdStResume(void)
Definition ncmd.c:654
int sceCdSeek(u32 lbn)
Definition ncmd.c:341
int sceCdStStart(u32 lbn, sceCdRMode *mode)
Definition ncmd.c:577
int sceCdStStat(void)
Definition ncmd.c:642
int sceCdStInit(u32 buffSize, u32 numBuffers, void *buf)
Definition ncmd.c:636
int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
Definition ncmd.c:427
int sceCdStandby(void)
Definition ncmd.c:364
int sceCdStSeek(u32 lbn)
Definition ncmd.c:631
int sceCdStop(void)
Definition ncmd.c:385
int sceCdBreak(void)
Definition scmd.c:309
int sceCdGetError(void)
Definition scmd.c:227
int sceCdCancelPOffRdy(u32 *result)
Definition scmd.c:326
int sceCdPowerOff(u32 *result)
Definition scmd.c:365
int sceCdForbidRead(u32 *status)
Definition scmd.c:454
int sceCdReadSUBQ(void *buffer, u32 *status)
Definition scmd.c:504
int sceCdSetHDMode(u32 mode)
Definition scmd.c:581
int sceCdWI(const unsigned char *buffer, u32 *status)
Definition scmd.c:741
int sceCdRI(unsigned char *buffer, u32 *result)
Definition scmd.c:722
int sceCdReadNVM(u32 address, u16 *data, u8 *result)
Definition scmd.c:677
int sceCdCloseConfig(u32 *result)
Definition scmd.c:620
int sceCdStatus(void)
Definition scmd.c:289
int sceCdReadClock(sceCdCLOCK *clock)
Definition scmd.c:116
int sceCdWriteConfig(const void *buffer, u32 *result)
Definition scmd.c:657
int sceCdRM(char *buffer, u32 *result)
Definition scmd.c:837
int sceCdGetDiskType(void)
Definition scmd.c:209
int sceCdCtrlADout(int arg1, u32 *result)
Definition scmd.c:818
int sceCdMmode(int media)
Definition scmd.c:384
int sceCdAutoAdjustCtrl(int mode, u32 *result)
Definition scmd.c:541
int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
Definition scmd.c:267
int sceCdWriteConsoleID(const unsigned char *buffer, u32 *result)
Definition scmd.c:779
int sceCdReadConsoleID(unsigned char *buffer, u32 *result)
Definition scmd.c:760
int sceCdBootCertify(const u8 *romname)
Definition scmd.c:486
int sceCdReadConfig(void *buffer, u32 *result)
Definition scmd.c:638
int sceCdWM(const char *buffer, u32 *result)
Definition scmd.c:856
int sceCdWriteNVM(u32 address, u16 data, u8 *result)
Definition scmd.c:700
int sceCdMV(unsigned char *buffer, u32 *result)
Definition scmd.c:798
int sceCdNoticeGameStart(u8 arg1, u32 *result)
Definition scmd.c:875
int sceCdForbidDVDP(u32 *result)
Definition scmd.c:523
int sceCdOpenConfig(int block, int mode, int NumBlocks, u32 *status)
Definition scmd.c:597
int sceCdTrayReq(int param, u32 *traychk)
Definition scmd.c:245
int sceCdWriteClock(sceCdCLOCK *clock)
Definition scmd.c:188
int sceCdDecSet(unsigned char arg1, unsigned char arg2, unsigned char shift)
Definition scmd.c:560
void * privdata
Definition ioman.h:62
int unit
Definition ioman.h:58
int mode
Definition ioman.h:56
Definition cdvdman.c:31
Definition cdvdman.c:64
#define EA_MULTI
Definition thevent.h:36