PS2SDK
PS2 Homebrew Libraries
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 
25 IRX_ID("cdvd_driver", 2, 38);
26 // Based on the module from SCE SDK 3.1.0.
27 
28 extern struct irx_export_table _exp_cdvdman;
29 
30 typedef struct cdvdman_dirtbl_entry_
31 {
32  int m_number;
33  int m_parent;
34  int m_extent;
35  char m_name[32];
37 
38 typedef 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;
53 
54 typedef 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;
62 
63 typedef struct cdvdman_filetbl_entry_
64 {
65  sceCdlFILE m_file_struct;
66  int m_flags;
68 
69 typedef 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];
136 
137 typedef 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[];
144 
145 typedef 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[];
159 
160 static int cdrom_init(iop_device_t *dev);
161 extern void cdvdman_termcall(int with_stop);
162 static int cdrom_deinit(iop_device_t *dev);
163 static int cdrom_dopen(iop_file_t *f, const char *dirname);
164 static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf);
165 static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf);
166 static int cdrom_open(iop_file_t *f, const char *name, int mode, int arg4);
167 static int cdrom_close(iop_file_t *f);
168 static int cdrom_read(iop_file_t *f, void *buf, int nbytes);
169 static int cdrom_ioctl(iop_file_t *f, int arg, void *param);
170 static int cdrom_ioctl2(iop_file_t *f, int request, void *argp, size_t arglen, void *bufp, size_t buflen);
171 static int
172 cdrom_devctl(iop_file_t *f, const char *, int cmd, void *argp, unsigned int arglen, void *bufp, unsigned int buflen);
173 static int cdrom_lseek(iop_file_t *f, int offset, int pos);
174 static int CdSearchFileInner(cdvdman_filetbl_entry_t *fp, const char *name, int layer);
175 static int sceCdSearchDir(char *dirname, int layer);
176 static int sceCdReadDir(sceCdlFILE *fp, int dsec, int index, int layer);
177 static int cdvdman_cmpname(const char *p, const char *q);
178 static int CD_newmedia(int arg);
179 static int cdvdman_finddir(int target_parent, const char *target_name);
180 static int CD_cachefile(int dsec, int layer);
181 static int disc_read(int size, int loc, void *buffer, int layer);
182 static int path_tbl_init(u32 blocks, char *fname, int action);
183 extern unsigned int optimized_memcpy(char *dst, const char *src, unsigned int n);
184 static int vSetAlarm(iop_sys_clock_t *sys_clock, unsigned int (*alarm_cb)(void *arg), void *arg);
185 static int vCancelAlarm(unsigned int (*alarm_cb)(void *arg), void *arg);
186 static int vSetEventFlag(int ef, u32 bits);
187 static int vDelayThread(int usec);
188 static int DvdDual_infochk();
189 static void cdvdman_init();
190 static void cdvdman_write_scmd(cdvdman_internal_struct_t *s);
191 static int intrh_dma_3(void *userdata);
192 static int cdvdman_mediactl(int code);
193 #ifndef CDVD_VARIANT_XOSD
194 static int cdvdman_ncmd_sender_06();
195 #endif
196 static int cdvdman_gettoc(u8 *toc);
197 static int cdvdman_isdvd();
198 static int sceCdRead0_Rty(u32 lsn, u32 nsec, void *buf, const sceCdRMode *mode, int ncmd, int dintrsec, void *func);
199 static int cdvdman_syncdec(int decflag, int decxor, int shift, u32 data);
200 static void Read2intrCDVD(int read2_flag);
201 #ifndef CDVD_VARIANT_XOSD
202 static int cdvdman_scmd_sender_03_30(u8 *buf, u32 *status);
203 #endif
204 static int cdvdman_scmd_sender_3B(int arg1);
205 #ifdef CDVD_VARIANT_DNAS
206 static int cdvdman_ncmd_sender_0C(int arg1, u32 arg2, u32 arg3);
207 #endif
208 #ifdef CDVD_VARIANT_XOSD
209 static unsigned int sceCdChgSpdlCtrl(int mode);
210 #endif
211 #ifdef CDVD_VARIANT_XOSD
212 static int cdvdman_change_drive(int mode);
213 static int cdvdman_get_renewal_date(u8 *buffer, u32 *status);
214 static int get_cdvd_register(int regnr);
215 static int get_disk_type_ex();
216 static int sc_ffffffd8(u32 *status);
217 static int set_cdvd_dev5_base_addr_atapi(int mode);
218 static int update_cd_mode_ps2_atapi(void);
219 #endif
220 
221 static char g_cdvdman_cache_name[256] = "host0:";
222 static int g_cdvdman_cache_sector_size_count = 1;
223 static int g_cdvdman_srchspd = 0;
224 static int g_cdvdman_spinctl = -1;
225 static int g_cdvdman_spinnom = -1;
226 static int g_cdvdman_trycnt = -1;
227 static int g_cdvdman_iocache = 0;
228 static unsigned int g_cdvdman_lcn_offset = 0;
229 static unsigned int g_cdvdman_numbytes_offset = 0;
230 static int g_cdvdman_strmerr = 0;
231 
232 IOMANX_RETURN_VALUE_IMPL(EIO);
233 
234 static 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 };
263 static iop_device_t g_cdvdman_cddev = {"cdrom", IOP_DT_FSEXT | IOP_DT_FS, 1, "CD-ROM ", &g_cdvdman_cddev_ops};
264 static int g_cdvdman_sync_timeout = 15000;
265 static int g_cdvdman_stream_timeout = 5000;
266 #ifdef CDVD_VARIANT_DNAS
267 static iop_sys_clock_t g_readid_systemtime = {0, 0};
268 #endif
269 static int g_verbose_level = 0;
270 static cdvdman_pathtbl_t *g_cdvdman_pathtbl = NULL;
271 static unsigned int g_cache_count = 0;
272 static unsigned int g_cache_table = 0;
273 static unsigned int g_cdvdman_pathtblsize = 0;
274 static int g_cache_path_size = 0;
275 static int g_cache_path_fd = -1;
276 static int g_cdvdman_fs_cdsec = 0;
277 static int g_cdvdman_fs_layer = -1;
278 static int g_cdvdman_fs_cache = 0;
279 static int g_cdvdman_fs_base2 = 0;
280 #ifdef CDVD_VARIANT_XOSD
281 static vu8 *g_cdvdreg_bf801460 = (vu8 *)0xBF801460; // &iop_mmio_hwport->dev9c[0]
282 // static u8 *cdvdreg_bf801462 = 0xBF801462;
283 static vu8 *g_cdvdreg_bf801464 = (vu8 *)0xBF801464; // &iop_mmio_hwport->dev9c[4]
284 static vu8 *g_cdvdreg_bf80146c = (vu8 *)0xBF80146C; // &iop_mmio_hwport->dev9c[0xC]
285 // static u8 *cdvdreg_bf80146e = 0xBF80146E;
286 static int g_cd_atapi_evfid = 0xFFFFFFFF;
287 static int g_acmd_evfid = 0xFFFFFFFF;
288 static int g_adma_evfid = 0xFFFFFFFF;
289 #endif
290 static int g_cdvdman_clk_flg = 0;
291 static int g_cdvdman_cd36key = 0;
292 static int g_cdvdman_ee_rpc_fno = 0;
293 static int g_cdvdman_mmode = 0;
294 static int g_cdvdman_last_cmdfunc = 0;
295 static int g_cdvdman_minver_10700 = 0;
296 static int g_cdvdman_minver_20200 = 0;
297 static int g_cdvdman_minver_20400 = 0;
298 static int g_cdvdman_minver_20800 = 0;
299 static int g_cdvdman_emudvd9 = 0;
300 static int g_cdvdman_minver_50000 = 0;
301 static int g_cdvdman_minver_50200 = 0;
302 static int g_cdvdman_minver_50400 = 0;
303 static int g_cdvdman_minver_50600 = 0;
304 static int g_cdvdman_minver_60000 = 0;
305 static int g_cdvdman_minver_60200 = 0;
306 #ifdef CDVD_VARIANT_OSD
307 static int g_cdvdman_minver_60600 = 0;
308 #endif
309 #ifdef CDVD_VARIANT_XOSD
310 static int g_cdvdman_vernotxxx1x = 0;
311 #endif
312 static int g_cdvdman_minver_x_model_15 = 0;
313 #ifdef CDVD_VARIANT_XOSD
314 static int g_cdvdman_debug_atapi_intr = 0;
315 #endif
316 static const char *g_masterdisc_header = "PlayStation Master Disc";
317 static char g_cdvdman_ncmd = 0x06;
318 static int g_cdvdman_chmedia = 0;
319 static int g_cdvdman_chflags[4] = {1, 1, 1, 1};
320 static int g_cdvdman_rtindex = 0;
321 static int g_cdvdman_retries = 0;
322 static u8 *g_cdvdman_ptoc;
323 #ifdef CDVD_VARIANT_XOSD
324 static int g_cdvdman_csys_evfid;
325 #endif
326 static int g_scmd_evfid;
327 static void *g_cdvdman_temp_buffer_ptr;
328 static int g_sfile_evfid;
329 static int g_ncmd_evfid;
330 #ifdef CDVD_VARIANT_OSD
331 static s32 g_cdvdman_apply_scmd_sema;
332 #endif
333 static int g_fio_fsv_evfid;
334 static int g_cdvdman_intr_evfid;
335 #ifdef CDVD_VARIANT_XOSD
336 static int (*g_cdvdman_atapi_eject_bs_power_callback)(int interrupt_nr, void *userdata);
337 #endif
338 static sceCdCBFunc g_cdvdman_user_cb;
339 static void *g_cdvdman_power_off_callback_userdata;
340 static void (*g_cdvdman_cdstm0cb)(int val);
341 static sceCdCLOCK g_cdvdman_clock;
342 static void (*g_cdvdman_power_off_callback)(void *userdata);
343 #ifdef CDVD_VARIANT_XOSD
344 static void *g_cdvdman_atapi_eject_bs_power_callback_userdata;
345 #endif
346 static void (*g_cdvdman_cdstm1cb)(int val);
347 static int g_cdvdman_cmdfunc;
348 static cdvdman_fhinfo_t g_cdvdman_fhinfo[16];
349 static char g_cdvdman_sfname[1024];
350 static cdvdman_filetbl_entry_t g_cdvdman_filetbl[64];
351 static cdvdman_dirtbl_entry_t g_cdvdman_dirtbl[128];
352 static int g_cdvdman_pathtblflag;
353 static char g_cdvdman_fs_rbuf[0x800];
354 static int g_cdvdman_readptr;
355 static iop_sys_clock_t g_cdvdman_read_alarm_cb_timeout;
356 static iop_sys_clock_t g_cdvdman_ncmd_timeout;
357 static void *g_cdvdman_readbuf;
358 static iop_sys_clock_t g_cdvdman_power_off_timeout;
359 #ifdef CDVD_VARIANT_OSD
360 static int g_cdvdman_config_numblocks;
361 #endif
362 static char g_cdvdman_fsvrbuf[42128];
363 static cdvdman_internal_struct_t g_cdvdman_istruct;
364 static const int g_cdvdman_cache_sector_count = 16;
365 
366 int _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 
394 void *sceGetFsvRbuf(void)
395 {
396  return g_cdvdman_fsvrbuf;
397 }
398 
399 static 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 
494 void 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 
535 static 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 
556 static 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
563  if ( (sceCdStatus() & SCECdStatShellOpen) )
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 
578 static 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 
584 static 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 
634 static 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 
696 static 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 
721 static 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 
734 static int cdrom_getstat(iop_file_t *f, const char *name, iox_stat_t *buf)
735 {
736  int devready_tmp;
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
779 static int cdrom_dread(iop_file_t *f, iox_dirent_t *buf)
780 {
781  int devready_tmp;
782  cdvdman_fhinfo_t *fh;
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 
814 static 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 
962 static 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 
997 static 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 
1011 static 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 
1094 static 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 
1179 static 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 
1206 static 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 
1226 static 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 
1385 static 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 
1419 static 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 
1626 static 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
1644 static 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 
1711 static 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
1760 static 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 
1805 static int
1806 cdrom_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
2016 static 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 
2057 static 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 
2066 int 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 
2085 int 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 
2183 int sceCdSpinCtrlIOP(u32 speed)
2184 {
2185  VERBOSE_KPRINTF(1, "sceCdSpinCtrlIOP speed= %d\n", speed);
2186  g_cdvdman_spinctl = speed;
2187  return 1;
2188 }
2189 
2190 int 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 
2211 int sceCdSearchFile(sceCdlFILE *file, const char *name)
2212 {
2213  return sceCdLayerSearchFile(file, name, 0);
2214 }
2215 
2216 int sceCdGetToc(u8 *toc)
2217 {
2218  return cdvdman_gettoc(toc);
2219 }
2220 
2221 int 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 
2293 int 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
2310 static 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
2332 int 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 
2347 int 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
2394 int 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
2418 static 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 
2462 static 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 
2470 static int query_boot_mode_6_zero(void)
2471 {
2472  return !QueryBootMode(6);
2473 }
2474 
2475 static 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 
2525 int sceCdReadGUID(u64 *guid)
2526 {
2527  return cdvdman_readID(0, (int *)guid);
2528 }
2529 
2530 int sceCdReadModelID(unsigned int *id)
2531 {
2532  return cdvdman_readID(1, (int *)id);
2533 }
2534 #endif
2535 
2536 int 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
2552 int 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 
2568 int 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 
2581 int 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 
2594 int 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 
2606 int 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 
2627 int 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 
2639 int 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 
2651 int 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 
2663 static 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 
2745 static 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 
2753 static 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 
2781 static int cdvdman_cmpname(const char *p, const char *q)
2782 {
2783  return !strncmp(p, q, 12);
2784 }
2785 
2786 static 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 
2900 static 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 
2914 static 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 
2992 static 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 
3156 static 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
3535 void 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 
3552 static 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 
3637 static 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 
3642 static 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
3648 s32 vSignalSema(s32 sema_id)
3649 {
3650  return (QueryIntrContext() ? iSignalSema : SignalSema)(sema_id);
3651 }
3652 #endif
3653 
3654 static int vSetEventFlag(int ef, u32 bits)
3655 {
3656  return (QueryIntrContext() ? iSetEventFlag : SetEventFlag)(ef, bits);
3657 }
3658 
3659 static int vClearEventFlag(int ef, u32 bits)
3660 {
3661  return (QueryIntrContext() ? iClearEventFlag : ClearEventFlag)(ef, bits);
3662 }
3663 
3664 static int vReferEventFlagStatus(int ef, iop_event_info_t *info)
3665 {
3666  return (QueryIntrContext() ? iReferEventFlagStatus : ReferEventFlagStatus)(ef, info);
3667 }
3668 
3669 static 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 
3699 static 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
3710 static 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
3842 static 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
3870 void *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
3884 void *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 
3898 int sceCdstm0Cb(void (*p)(int val))
3899 {
3900  g_cdvdman_cdstm0cb = p;
3901  return 0;
3902 }
3903 
3904 int sceCdstm1Cb(void (*p)(int val))
3905 {
3906  g_cdvdman_cdstm1cb = p;
3907  return 0;
3908 }
3909 
3910 static 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 
4131 static 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;
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 
4359 static u32 cdvdman_l1start(const u8 *toc)
4360 {
4361  return toc[23] + (toc[22] << 8) + (toc[21] << 16) - 0x30000 + 1;
4362 }
4363 
4364 static 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 
4400 static 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 
4517 int 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 
4601 int 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 
4767 static 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 
4861 int 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 
4938 static 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 
5086 static 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
5207 static 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 
5311 static 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
5395 static 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 
5405 int 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 
5441 int 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
5462 int 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 
5480 int 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 
5556 static 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 
5566 static int intrh_dma_3(void *userdata)
5567 {
5568  int dmacbres;
5569  int oldstate;
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 
5616 static 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
5651 static 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
5686 static 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
5725 static 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
5782 int 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 
5990 static int
5991 cdvdman_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 
6079 int 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 
6090 int sceCdCheckCmd(void)
6091 {
6092  return g_cdvdman_istruct.m_wait_flag;
6093 }
6094 
6095 static 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 
6154 int 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
6164 int cdvdman_get_last_command(void)
6165 {
6166  return (u8)g_cdvdman_istruct.m_cdvdman_command;
6167 }
6168 #endif
6169 
6170 int sceCdNop(void)
6171 {
6172  return cdvdman_send_ncmd(0x00, NULL, 0, 0, 0, 1) >= 0;
6173 }
6174 
6175 #ifdef DEAD_CODE
6176 int 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
6183 static 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 
6226 int 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 
6267 int sceCdStop(void)
6268 {
6269  return cdvdman_send_ncmd(0x03, NULL, 0, 6, 0, 1) >= 0;
6270 }
6271 
6272 int sceCdPause(void)
6273 {
6274  return cdvdman_send_ncmd(0x04, NULL, 0, 7, 0, 1) >= 0;
6275 }
6276 
6277 #ifdef DEAD_CODE
6278 int 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 
6287 static 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 
6299 static 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 
6360 static 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
6368 int 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 
6385 u32 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 
6411 static 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 
6478 static 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 
6504 static 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 
6556 int 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 
6651 static 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 
6746 static 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 
6853 int 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 
6858 int 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 
6877 static 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 
6882 static 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 
7039 {
7040  (void)tag;
7041  (void)mode;
7042 
7043  return 0;
7044 }
7045 
7046 static 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
7113 int 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
7120 int 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 
7127 int 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
7181 int 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 
7238 int 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
7255 static 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
7268 int 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 
7279 int 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
7316 int 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
7328 int 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
7357 int 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
7371 int 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 
7386 int 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
7408 static 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
7427 static 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
7447 int 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
7494 int 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 
7506 int sceCdMmode(int media)
7507 {
7508  g_cdvdman_mmode = media;
7509  return 1;
7510 }
7511 
7512 #ifdef CDVD_VARIANT_OSD
7513 // cppcheck-suppress funcArgNamesDifferent
7514 int 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 
7521 int 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
7531 int 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
7540 int 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 
7550 static unsigned int power_off_alarm_cb(void *userdata)
7551 {
7553 
7554  s = (cdvdman_internal_struct_t *)userdata;
7555  s->m_power_flag = 0;
7556  return 0;
7557 }
7558 
7559 // cppcheck-suppress funcArgNamesDifferent
7560 int 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 
7592 int 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
7605 int 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
7617 int 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 
7649 int 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 
7689 int 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 
7731 int 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 
7746 int 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
7765 int 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
7784 int 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 
7802 int 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
7825 int 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
7849 int 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
7878 int 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
7899 int 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
7919 int 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 
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 
7962 int sceCdRC(sceCdCLOCK *clock)
7963 {
7964  return set_prev_command(0x08, NULL, 0, (char *)clock, 8, 1);
7965 }
7966 
7967 #ifdef CDVD_VARIANT_OSD
7968 int 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 
7974 int 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 
7989 int 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 
8004 int 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 
8045 static 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
8065 int 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 
8116 int 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
8223 int 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
8387 int 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
8456 static 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 
8468 int 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
8484 int 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
8517 int 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 
8528 static 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
8543 int 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 
8569 static 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
8582 int 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 
8608 int 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
8620 int 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
8648 int 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
8661 int 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
8674 int 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
8717 int 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
8745 int 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
8774 int 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
8803 int 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
8819 static 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
8841 int 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
sceCdReadSUBQ
int sceCdReadSUBQ(void *buffer, u32 *status)
sceCdlLOCCD::sector
u8 sector
Definition: libcdvd-common.h:228
sceRemote2_7Get
int sceRemote2_7Get(u32 *param, u32 *status)
sceCdNoticeGameStart
int sceCdNoticeGameStart(u8 arg1, u32 *result)
iomanX.h
sceCdPOffCallback
void * sceCdPOffCallback(void(*func)(void *userdata), void *userdata)
Definition: cdvdman.c:3870
sceCdPowerOff
int sceCdPowerOff(u32 *result)
Definition: cdvdman.c:7560
sceCdDoesUniqueKeyExist
int sceCdDoesUniqueKeyExist(u32 *status)
RegisterIntrHandler
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *arg), void *arg)
Definition: intrman.c:115
sceCdOpenConfig
int sceCdOpenConfig(int block, int mode, int NumBlocks, u32 *status)
SCECdStatShellOpen
@ SCECdStatShellOpen
Definition: libcdvd-common.h:175
sceCdSetHDMode
int sceCdSetHDMode(u32 mode)
SCECdNODISC
@ SCECdNODISC
Definition: libcdvd-common.h:112
sceCdlFILE::name
char name[16]
Definition: libcdvd-common.h:215
sceCdBootCertify
int sceCdBootCertify(const u8 *romname)
iox_stat_t
Definition: iox_stat.h:92
sceCdCtrlADout
int sceCdCtrlADout(int mode, u32 *status)
Definition: cdvdman.c:7592
ReleaseIntrHandler
int ReleaseIntrHandler(int irq)
Definition: intrman.c:157
sceCdReadWakeUpTime
int sceCdReadWakeUpTime(sceCdCLOCK *clock, u16 *userdata, u32 *wakeupreason, int *flags)
sceCdSetTimeout
int sceCdSetTimeout(int param, int timeout)
Definition: cdvdman.c:2066
sceCdGetMediumRemoval
int sceCdGetMediumRemoval(u32 *result1, u32 *result2)
sceCdWriteConfig
int sceCdWriteConfig(const void *buffer, u32 *result)
sceCdXDVRPReset
int sceCdXDVRPReset(u8 arg1, u32 *result)
sceCdSync
int sceCdSync(int mode)
Definition: cdi.c:109
sceCdTrayReq
int sceCdTrayReq(int param, u32 *traychk)
Definition: cdi.c:162
ECOMM
#define ECOMM
Definition: errno.h:155
SCECdErFAIL
@ SCECdErFAIL
Definition: libcdvd-common.h:71
cdvdman_fhinfo_
Definition: cdvdman.c:38
IOP_DT_FSEXT
#define IOP_DT_FSEXT
Definition: iomanX.h:66
sceCdCLOCK::year
u8 year
Definition: libcdvd-common.h:205
FIO_S_IFDIR
#define FIO_S_IFDIR
Definition: iox_stat.h:45
SCECdSpinX1
@ SCECdSpinX1
Definition: libcdvd-common.h:48
sceCdRChain
Definition: libcdvd-common.h:245
_iop_file::privdata
void * privdata
Definition: ioman.h:61
sceCdReadModelID
int sceCdReadModelID(unsigned int *id)
cdvdman_169_dragon2atapi
int cdvdman_169_dragon2atapi(u8 *outbuf, u32 *status)
request
Definition: thread.c:17
SCECdINIT
@ SCECdINIT
Definition: libcdvd-common.h:282
SCECdTrayOpen
@ SCECdTrayOpen
Definition: libcdvd-common.h:163
iop_sema_t
Definition: thsemap.h:38
sceCdReadKey
int sceCdReadKey(unsigned char arg1, unsigned char arg2, unsigned int command, unsigned char *key)
ENOMEM
#define ENOMEM
Definition: errno.h:43
cdvdman_dma3_parameter_
Definition: cdvdman.h:53
EPERM
#define EPERM
Definition: errno.h:21
sceCdBlueLEDCtl
int sceCdBlueLEDCtl(u8 control, u32 *result)
iop_mmio_hwport.h
s_info
Definition: xprintf.c:78
sceCdRead
int sceCdRead(u32 lbn, u32 sectors, void *buffer, sceCdRMode *mode)
Definition: cdi.c:98
sceCdCLOCK
Definition: libcdvd-common.h:188
EA_MULTI
#define EA_MULTI
Definition: thevent.h:35
sceCdBreak
int sceCdBreak(void)
Definition: cdi.c:25
DisableIntr
int DisableIntr(int irq, int *res)
Definition: intrman.c:385
SCECdPSCD
@ SCECdPSCD
Definition: libcdvd-common.h:122
sceCdRMode::trycount
u8 trycount
Definition: libcdvd-common.h:236
SCECdTrayCheck
@ SCECdTrayCheck
Definition: libcdvd-common.h:167
SCECdSpinStm
@ SCECdSpinStm
Definition: libcdvd-common.h:41
FIO_S_IFREG
#define FIO_S_IFREG
Definition: iox_stat.h:43
sceCdStandby
int sceCdStandby(void)
Definition: cdi.c:147
QueryIntrContext
int QueryIntrContext(void)
toc
static cdda_toc toc
Definition: cdrom.c:52
sceCdGetDiskType
int sceCdGetDiskType(void)
Definition: cdi.c:35
sceCdStInit
int sceCdStInit(u32 bufmax, u32 bankmax, void *buffer)
Definition: cdi.c:167
cdvd-ioctl.h
SCECdErNORDY
@ SCECdErNORDY
Definition: libcdvd-common.h:84
sceCdRM
int sceCdRM(char *buffer, u32 *status)
Definition: cdvdman.c:7279
sceCdlLOCCD::second
u8 second
Definition: libcdvd-common.h:226
CpuSuspendIntr
int CpuSuspendIntr(int *state)
Definition: intrman.c:195
sceCdDeobfuscateUsingUniqueKey
int sceCdDeobfuscateUsingUniqueKey(u8 *buffer, unsigned int shiftval, int xorval, u32 *status)
sceCdCLOCK::hour
u8 hour
Definition: libcdvd-common.h:197
iop_event_info_t::currBits
u32 currBits
Definition: thevent.h:53
event
Definition: thcommon.h:71
mipscopaccess.h
EIO
#define EIO
Definition: errno.h:29
sceCdReadDvdDualInfo
int sceCdReadDvdDualInfo(int *on_dual, unsigned int *layer1_start)
Definition: cdvdman.c:4517
SCECdPSCDDA
@ SCECdPSCDDA
Definition: libcdvd-common.h:124
SCECdDVDVR
@ SCECdDVDVR
Definition: libcdvd-common.h:133
sceCdForbidRead
int sceCdForbidRead(u32 *result)
cdvdman_152_get_temperature
int cdvdman_152_get_temperature(u32 *param, u32 *status)
sceRemote2_7
int sceRemote2_7(u16 param, u32 *status)
iso9660_path_
Definition: cdvdman.c:137
SCECdErPRM
@ SCECdErPRM
Definition: libcdvd-common.h:93
ENOENT
#define ENOENT
Definition: errno.h:23
SCECdPS2CDDA
@ SCECdPS2CDDA
Definition: libcdvd-common.h:128
SCECdEXIT
@ SCECdEXIT
Definition: libcdvd-common.h:286
sceCdCLOCK::month
u8 month
Definition: libcdvd-common.h:203
SCECdTrayClose
@ SCECdTrayClose
Definition: libcdvd-common.h:165
sceCdWriteRegionParams
int sceCdWriteRegionParams(u8 arg1, u32 *arg2, u8 *arg3, u32 *result)
sceCdWriteNVM
int sceCdWriteNVM(u32 address, u16 data, u8 *result)
sceCdRE
int sceCdRE(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
Definition: cdvdman.c:6853
sceCdIntToPos
sceCdlLOCCD * sceCdIntToPos(u32 i, sceCdlLOCCD *p)
Definition: cdvdman.c:2402
sceCdStSeek
int sceCdStSeek(u32 lbn)
Definition: cdi.c:197
iso9660_dirent_
Definition: cdvdman.c:145
sceCdStRead
int sceCdStRead(u32 sectors, u32 *buffer, u32 mode, u32 *error)
Definition: cdi.c:179
sceCdlFILE
Definition: libcdvd-common.h:208
sceCdSetAtapiEjectCallback
void * sceCdSetAtapiEjectCallback(int(*cb)(int reason, void *userdata), void *userdata)
hdd-ioctl.h
SCECdPS2DVD
@ SCECdPS2DVD
Definition: libcdvd-common.h:130
cdvdman.h
_iop_file::mode
int mode
Definition: ioman.h:55
sceCdGetError
int sceCdGetError(void)
Definition: cdi.c:40
SCECdErCUD
@ SCECdErCUD
Definition: libcdvd-common.h:86
FIO_S_IXOTH
#define FIO_S_IXOTH
Definition: iox_stat.h:80
sceCdApplyNCmd
int sceCdApplyNCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize)
Definition: cdvdman.c:6079
sceCdXBSPowerCtl
int sceCdXBSPowerCtl(u8 arg1, u8 arg2, u32 *result1, u32 *result2)
SCECdStatStop
@ SCECdStatStop
Definition: libcdvd-common.h:173
EnableIntr
int EnableIntr(int irq)
Definition: intrman.c:336
SCECdDETCT
@ SCECdDETCT
Definition: libcdvd-common.h:114
sceCdStStart
int sceCdStStart(u32 lbn, sceCdRMode *mode)
Definition: cdi.c:202
sceCdReadChain
int sceCdReadChain(sceCdRChain *tag, sceCdRMode *mode)
Definition: cdvdman.c:7038
sceCdReadNVM
int sceCdReadNVM(u32 address, u16 *data, u8 *result)
sceCdStStop
int sceCdStStop(void)
Definition: cdi.c:214
FIO_S_IXUSR
#define FIO_S_IXUSR
Definition: iox_stat.h:62
sceCdReadPS1BootParam
int sceCdReadPS1BootParam(u8 *out, u32 *result)
cdvdman_pathtbl_
Definition: cdvdman.c:54
sceCdMV
int sceCdMV(u8 *buffer, u32 *status)
Definition: cdvdman.c:7386
SCECdPS2CD
@ SCECdPS2CD
Definition: libcdvd-common.h:126
sceCdForbidDVDP
int sceCdForbidDVDP(u32 *result)
EBUSY
#define EBUSY
Definition: errno.h:51
cdvdman_167_atapi2dragon
int cdvdman_167_atapi2dragon(u8 *inbuf, u32 *status)
SCECdErABRT
@ SCECdErABRT
Definition: libcdvd-common.h:75
sceCdSpinCtrlIOP
int sceCdSpinCtrlIOP(u32 speed)
Definition: cdvdman.c:2183
sceCdStPause
int sceCdStPause(void)
Definition: cdi.c:219
irx_export_table
Definition: irx.h:90
sceCdCallback
sceCdCBFunc sceCdCallback(sceCdCBFunc function)
Definition: cdi.c:16
sceCdChgSys
int sceCdChgSys(u32 arg1)
cdvdman_filetbl_entry_
Definition: cdvdman.c:63
_iop_file::unit
int unit
Definition: ioman.h:57
_iop_file
Definition: ioman.h:53
FIO_S_IXGRP
#define FIO_S_IXGRP
Definition: iox_stat.h:71
FIO_S_IROTH
#define FIO_S_IROTH
Definition: iox_stat.h:76
SCECdStatSpin
@ SCECdStatSpin
Definition: libcdvd-common.h:177
sceCdWriteConsoleID
int sceCdWriteConsoleID(const u8 *buffer, u32 *status)
sceCdCBFunc
void(* sceCdCBFunc)(int reason)
Definition: libcdvd-common.h:278
sceCdCLOCK::stat
u8 stat
Definition: libcdvd-common.h:191
sceCdPause
int sceCdPause(void)
Definition: cdi.c:93
sceCdSendSCmd1D
int sceCdSendSCmd1D(int *arg1, unsigned int *arg2, unsigned int *arg3, u32 *status)
SCECdSpinX4
@ SCECdSpinX4
Definition: libcdvd-common.h:53
FIO_S_IRUSR
#define FIO_S_IRUSR
Definition: iox_stat.h:58
sceCdReadGUID
int sceCdReadGUID(u64 *guid)
sceCdInit
int sceCdInit(int mode)
Definition: cdi.c:64
sceCdCloseConfig
int sceCdCloseConfig(u32 *result)
CpuResumeIntr
int CpuResumeIntr(int state)
Definition: intrman.c:217
sceCdCancelPOffRdy
int sceCdCancelPOffRdy(u32 *result)
Definition: cdvdman.c:7531
SCECdErIPI
@ SCECdErIPI
Definition: libcdvd-common.h:89
iox_dirent_t
Definition: iox_stat.h:111
sceCdGetToc2
int sceCdGetToc2(u8 *toc, int param)
_iop_device_ops
Definition: ioman.h:79
sceCdCLOCK::pad
u8 pad
Definition: libcdvd-common.h:199
sceCdlFILE::date
u8 date[8]
Definition: libcdvd-common.h:217
sceCdMmode
int sceCdMmode(int media)
Definition: cdi.c:86
sceCdXLEDCtl
int sceCdXLEDCtl(u8 arg1, u8 arg2, u32 *result1, u32 *result2)
sceCdStop
int sceCdStop(void)
Definition: cdi.c:157
sceCdPosToInt
u32 sceCdPosToInt(sceCdlLOCCD *p)
Definition: cdvdman.c:2411
sceCdStSeekF
int sceCdStSeekF(unsigned int lsn)
Definition: cdvdman.c:2568
sceCdApplySCmd3
int sceCdApplySCmd3(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
cdrom_stm_devctl_
Definition: cdvd-ioctl.h:61
sceCdGetReadPos
u32 sceCdGetReadPos(void)
Definition: cdi.c:45
sceCdCLOCK::day
u8 day
Definition: libcdvd-common.h:201
sceCdSearchFile
int sceCdSearchFile(sceCdlFILE *file, const char *name)
Definition: cdi.c:114
sceCdRV
int sceCdRV(u32 lsn, u32 sectors, void *buf, sceCdRMode *mode, int arg5, void *cb)
Definition: cdvdman.c:7127
sceCdRMode::datapattern
u8 datapattern
Definition: libcdvd-common.h:240
sceCdReadFull
int sceCdReadFull(unsigned int lsn, unsigned int sectors, void *buf, sceCdRMode *mode)
sceCdWriteClock
int sceCdWriteClock(sceCdCLOCK *clock)
SCECdSpinMax
@ SCECdSpinMax
Definition: libcdvd-common.h:39
sceCdGetWakeUpReason
int sceCdGetWakeUpReason(void)
sceCdSetFanProfile
int sceCdSetFanProfile(u8 param, u32 *result)
sceCdStatus2
int sceCdStatus2(void)
sceCdSeek
int sceCdSeek(u32 lbn)
Definition: cdi.c:142
sceCdWriteWakeUpTime
int sceCdWriteWakeUpTime(const sceCdCLOCK *clock, u16 userdata, int flags)
iop_event_info_t
Definition: thevent.h:44
sceCdAutoAdjustCtrl
int sceCdAutoAdjustCtrl(int mode, u32 *result)
COP0_REG_PRId
@ COP0_REG_PRId
Definition: mipscopaccess.h:42
SCECdErNO
@ SCECdErNO
Definition: libcdvd-common.h:73
sceCdReadRegionParams
int sceCdReadRegionParams(u32 *arg1, u32 *result)
EINVAL
#define EINVAL
Definition: errno.h:63
sceCdReadClock
int sceCdReadClock(sceCdCLOCK *clock)
Definition: cdvdman.c:7934
cdvdman_internal_struct_
Definition: cdvdman.h:64
SCECdSpinMx
@ SCECdSpinMx
Definition: libcdvd-common.h:61
SCECdErEOM
@ SCECdErEOM
Definition: libcdvd-common.h:100
sceCdReadDiskID
int sceCdReadDiskID(unsigned int *id)
SCECdErTRMOPN
@ SCECdErTRMOPN
Definition: libcdvd-common.h:98
sceCdlLOCCD::minute
u8 minute
Definition: libcdvd-common.h:224
sceCdRMode
Definition: libcdvd-common.h:233
SCECdSpinNm2
@ SCECdSpinNm2
Definition: libcdvd-common.h:57
sceCdSetMediumRemoval
int sceCdSetMediumRemoval(u8 arg1, u32 *result)
_iop_device
Definition: ioman.h:64
dev5_mmio_hwport.h
SCECdCDDA
@ SCECdCDDA
Definition: libcdvd-common.h:135
sceCdApplySCmd2
int sceCdApplySCmd2(u8 cmdNum, const void *inBuff, unsigned long int inBuffSize, void *outBuff)
Definition: cdvdman.c:5441
sceCdRcBypassCtl
int sceCdRcBypassCtl(int mode, u32 *status)
sceCdReadConfig
int sceCdReadConfig(void *buffer, u32 *result)
SCECdDVDV
@ SCECdDVDV
Definition: libcdvd-common.h:137
sceCdDiskReady
int sceCdDiskReady(int mode)
Definition: cdi.c:30
iso9660_desc_
Definition: cdvdman.c:69
SCECdErREAD
@ SCECdErREAD
Definition: libcdvd-common.h:96
sceCdlLOCCD
Definition: libcdvd-common.h:221
sceCdCLOCK::minute
u8 minute
Definition: libcdvd-common.h:195
sceCdStStat
int sceCdStStat(void)
Definition: cdi.c:209
sceCdWM
int sceCdWM(const char *buffer, u32 *status)
STMNBLK
@ STMNBLK
Definition: libcdvd-common.h:365
sceCdLayerSearchFile
int sceCdLayerSearchFile(sceCdlFILE *fp, const char *path, int layer)
Definition: cdvdman.c:2190
sceCdGetToc
int sceCdGetToc(u8 *toc)
Definition: cdi.c:57
iop_event_t
Definition: thevent.h:37
sceCdStResume
int sceCdStResume(void)
Definition: cdi.c:224
sceCdCLOCK::second
u8 second
Definition: libcdvd-common.h:193
sceCdBuzzerCtl
int sceCdBuzzerCtl(u32 *result)
sceCdReadConsoleID
int sceCdReadConsoleID(u8 *buffer, u32 *result)
SCECdErREADCFR
@ SCECdErREADCFR
Definition: libcdvd-common.h:106
SCECdSpinX2
@ SCECdSpinX2
Definition: libcdvd-common.h:51
sceCdRMode::spindlctrl
u8 spindlctrl
Definition: libcdvd-common.h:238
SCECdErREADCF
@ SCECdErREADCF
Definition: libcdvd-common.h:104
sceCdStatus
int sceCdStatus(void)
Definition: cdi.c:152
sceCdWI
int sceCdWI(const u8 *buffer, u32 *result)
SCECdIllegalMedia
@ SCECdIllegalMedia
Definition: libcdvd-common.h:139
SCECdSpinNom
@ SCECdSpinNom
Definition: libcdvd-common.h:46
_iop_sys_clock
Definition: thbase.h:87
sceCdDecSet
int sceCdDecSet(unsigned char enable_xor, unsigned char enable_shift, unsigned char shiftval)
Definition: cdvdman.c:8468
sceCdApplySCmd
int sceCdApplySCmd(u8 cmdNum, const void *inBuff, u16 inBuffSize, void *outBuff)
Definition: cdvdman.c:5405
SCECdSpinX12
@ SCECdSpinX12
Definition: libcdvd-common.h:55
sceCdSetLEDsMode
int sceCdSetLEDsMode(u32 param, u32 *result)
errno.h
kerr.h
sceCdRI
int sceCdRI(u8 *buffer, u32 *result)
Definition: cdvdman.c:7268
cdvdman_dirtbl_entry_
Definition: cdvdman.c:30
SCECdStatPause
@ SCECdStatPause
Definition: libcdvd-common.h:181
EMFILE
#define EMFILE
Definition: errno.h:67
ENODEV
#define ENODEV
Definition: errno.h:57
FIO_S_IRGRP
#define FIO_S_IRGRP
Definition: iox_stat.h:67