16#include <irx_imports.h>
25IRX_ID(
"Sound_Device_Library", 3, 3);
28#define SD_DMA_CS (1 << 9)
29#define SD_DMA_START (1 << 24)
30#define SD_DMA_DIR_SPU2IOP 0
31#define SD_DMA_DIR_IOP2SPU 1
36#define SD_INTERNAL_MMIO_ATTR 0x2300
37#define SD_INTERNAL_MMIO_STD 0x2500
38#define SD_INTERNAL_MMIO_UNK1AE 0x2600
39#define SD_INTERNAL_MMIO_ADMAS 0x2700
40#define SD_INTERNAL_MMIO_STATX 0x2800
89 sceSdBlockTransHandler m_cb;
104typedef int (*SdCleanHandler)(
int core);
106static int GetEEA(
int core);
107static void InitSpu2_Inner(
void);
108static void libsd_do_busyloop(
int count);
109static u32 DmaStartStop(
int mainarg,
void *vararg2, u32 vararg3);
110static u32 VoiceTrans_Write_IOMode(
const u16 *iopaddr, u32 size,
int core);
111static u32 BlockTransWriteFrom(u8 *iopaddr, u32 size,
int core,
int mode, u8 *startaddr);
112static u32 BlockTransRead(u8 *iopaddr, u32 size,
int core, u16 mode);
113static void reset_vars(
void);
116static vu16 *
const g_ParamRegList[] =
165static const u32 g_EffectSizes[] =
541static const u16 g_NotePitchTable[] =
685static const u16 g_CoreAttrShifts[] =
692static const u16 g_VoiceDataInit[] =
706static const u32 g_ClearEffectData[256]
__attribute__((__aligned__(16)));
708static int g_VoiceTransStatus[2];
710static int g_VoiceTransIoMode[2];
712static int g_SpdifSettings;
716static int g_VoiceTransCompleteBool[2];
718static int g_VoiceTransCompleteEf[2];
720static int g_vars_inited;
722static SdIntrCallback g_Spu2IrqCallback;
724static sceSdSpu2IntrHandler g_Spu2IntrHandler;
726static void *g_Spu2IntrHandlerData;
728static sceSdTransIntrHandler g_TransIntrHandlers[2];
732static SdCleanHandler g_CleanHandlers[2];
735static u32 g_CleanRegionMax[2];
736static u32 g_CleanRegionCur[2];
738static u32 g_BlockTransBuff[2];
739static u8 *g_BlockTransAddr[2];
740static u32 g_BlockTransSize[2];
742static SdIntrCallback g_TransIntrCallbacks[2];
743static u32 g_EffectAddr[2];
745int _start(
int ac,
char **av)
753 regres = RegisterLibraryEntries(&_exp_libsd);
756 return MODULE_NO_RESIDENT_END;
759 return MODULE_RESIDENT_END;
766 pair->m_pair[0] = (val >> 16) & 0xFFFF;
767 pair->m_pair[1] = val;
770static void SetEffectData(
int core,
const struct mode_data_struct *mode_data)
774 USE_SPU2_MMIO_HWPORT();
776 mode_flags = mode_data->m_mode_flags;
778 mode_flags = 0xFFFFFFFF;
779 if ( (mode_flags & 1) )
780 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_apf1_size, mode_data->m_d_apf1_size);
781 if ( (mode_flags & 2) )
782 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_apf2_size, mode_data->m_d_apf2_size);
783 if ( (mode_flags & 4) )
784 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_iir_vol = mode_data->m_d_iir_vol;
785 if ( (mode_flags & 8) )
786 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_comb1_vol = mode_data->m_d_comb1_vol;
787 if ( (mode_flags & 0x10) )
788 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_comb2_vol = mode_data->m_d_comb2_vol;
789 if ( (mode_flags & 0x20) )
790 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_comb3_vol = mode_data->m_d_comb3_vol;
791 if ( (mode_flags & 0x40) )
792 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_comb4_vol = mode_data->m_d_comb4_vol;
793 if ( (mode_flags & 0x80) )
794 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_wall_vol = mode_data->m_d_wall_vol;
795 if ( (mode_flags & 0x100) )
796 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_apf1_vol = mode_data->m_d_apf1_vol;
797 if ( (mode_flags & 0x200) )
798 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_apf2_vol = mode_data->m_d_apf2_vol;
799 if ( (mode_flags & 0x400) )
800 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_same_l_dst, mode_data->m_d_same_l_dst);
801 if ( (mode_flags & 0x800) )
802 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_same_r_dst, mode_data->m_d_same_r_dst);
803 if ( (mode_flags & 0x1000) )
804 SetEffectRegisterPair(
805 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb1_l_src, mode_data->m_d_comb1_l_src);
806 if ( (mode_flags & 0x2000) )
807 SetEffectRegisterPair(
808 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb1_r_src, mode_data->m_d_comb1_r_src);
809 if ( (mode_flags & 0x4000) )
810 SetEffectRegisterPair(
811 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb2_l_src, mode_data->m_d_comb2_l_src);
812 if ( (mode_flags & 0x8000) )
813 SetEffectRegisterPair(
814 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb2_r_src, mode_data->m_d_comb2_r_src);
815 if ( (mode_flags & 0x10000) )
816 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_same_l_src, mode_data->m_d_same_l_src);
817 if ( (mode_flags & 0x20000) )
818 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_same_r_src, mode_data->m_d_same_r_src);
819 if ( (mode_flags & 0x40000) )
820 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_diff_l_dst, mode_data->m_d_diff_l_dst);
821 if ( (mode_flags & 0x80000) )
822 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_diff_r_dst, mode_data->m_d_diff_r_dst);
823 if ( (mode_flags & 0x100000) )
824 SetEffectRegisterPair(
825 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb3_l_src, mode_data->m_d_comb3_l_src);
826 if ( (mode_flags & 0x200000) )
827 SetEffectRegisterPair(
828 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb3_r_src, mode_data->m_d_comb3_r_src);
829 if ( (mode_flags & 0x400000) )
830 SetEffectRegisterPair(
831 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb4_l_src, mode_data->m_d_comb4_l_src);
832 if ( (mode_flags & 0x800000) )
833 SetEffectRegisterPair(
834 &spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_comb4_r_src, mode_data->m_d_comb4_r_src);
835 if ( (mode_flags & 0x1000000) )
836 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_diff_l_src, mode_data->m_d_diff_l_src);
837 if ( (mode_flags & 0x2000000) )
838 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_diff_r_src, mode_data->m_d_diff_r_src);
839 if ( (mode_flags & 0x4000000) )
840 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_apf1_l_dst, mode_data->m_d_apf1_l_dst);
841 if ( (mode_flags & 0x8000000) )
842 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_apf1_r_dst, mode_data->m_d_apf1_r_dst);
843 if ( (mode_flags & 0x10000000) )
844 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_apf2_l_dst, mode_data->m_d_apf2_l_dst);
845 if ( (mode_flags & 0x20000000) )
846 SetEffectRegisterPair(&spu2_mmio_hwport->m_u.m_m.m_core_regs[core].m_cregs.m_apf2_r_dst, mode_data->m_d_apf2_r_dst);
847 if ( (mode_flags & 0x40000000) )
848 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_in_coef_l = mode_data->m_d_in_coef_l;
849 if ( (mode_flags & 0x80000000) )
850 spu2_mmio_hwport->m_u.m_e.m_different_regs[core].m_in_coef_r = mode_data->m_d_in_coef_r;
853int sceSdClearEffectWorkArea(
int core,
int channel,
int effect_mode)
859 SdIntrCallback callback_tmp;
860 sceSdTransIntrHandler handler_tmp;
863 if ( effect_mode > SD_EFFECT_MODE_PIPE )
869 if ( DmaStartStop((channel << 4) | 4, 0, 0) )
871 if ( g_VoiceTransIoMode[channel] != 1 )
876 effect_size = g_EffectSizes[effect_mode] << 3;
877 effect_addr = (GetEEA(core) - (effect_size - 1)) >> 1;
878 if ( (effect_size & 0x3F) )
880 effect_size &= 0x3FFFFFF;
881 aligned_addr = (GetEEA(core) - (effect_size - 1)) >> 1;
884 handler_tmp = g_TransIntrHandlers[channel];
885 callback_tmp = g_TransIntrCallbacks[channel];
886 g_TransIntrHandlers[channel] = 0;
887 g_TransIntrCallbacks[channel] = 0;
891 xferres = sceSdVoiceTrans(channel, 0, (u8 *)g_ClearEffectData, (u32 *)(effect_addr << 1), 0x40);
893 xferres = sceSdVoiceTransStatus(channel, 1);
894 effect_addr = aligned_addr;
900 for ( i = 0;; i += 1 )
904 size = (effect_size <= 0x400) ? effect_size : 0x400;
905 xferres = sceSdVoiceTrans(channel, 0, (u8 *)g_ClearEffectData, (u32 *)((effect_addr + (i << 9)) << 1), size);
909 xferres = sceSdVoiceTransStatus(channel, 1);
912 if ( effect_size <= 0x400 )
917 effect_size -= 0x400;
921 g_TransIntrHandlers[channel] = handler_tmp;
922 g_TransIntrCallbacks[channel] = callback_tmp;
926static int CleanHandler(
int core)
930 g_CleanRegionCur[core] += 1;
931 if ( (
int)g_CleanRegionCur[core] >= (
int)(g_CleanRegionMax[core] - 1) )
932 g_CleanHandlers[core] = 0;
933 DmaStartStop((core << 4) | 2, g_CleanRegionBuffer[core].m_elements[g_CleanRegionCur[core]].m_spuaddr, 0);
935 (core << 4) | 6, (u8 *)g_ClearEffectData, g_CleanRegionBuffer[core].m_elements[g_CleanRegionCur[core]].m_size);
939int sceSdCleanEffectWorkArea(
int core,
int channel,
int effect_mode)
947 if ( effect_mode > SD_EFFECT_MODE_PIPE )
953 if ( DmaStartStop((channel << 4) | 4, 0, 0) )
955 if ( g_VoiceTransIoMode[channel] != 1 )
957 effect_size = g_EffectSizes[effect_mode] << 3;
958 effect_addr = GetEEA(core) - (effect_size - 1);
959 if ( (effect_size & 0x3F) )
961 effect_size &= 0x3FFFFFF;
962 xferres = sceSdVoiceTrans(channel, 8, (u8 *)g_ClearEffectData, (u32 *)effect_addr, 0x40);
965 effect_addr = GetEEA(core) - (effect_size - 1);
967 effect_addr += 0x100;
968 effect_size -= 0x400;
969 for ( i = 0;; i += 1 )
971 g_CleanRegionBuffer[channel].m_elements[i].m_spuaddr = (u32 *)effect_addr;
972 g_CleanRegionBuffer[channel].m_elements[i].m_size = (effect_size <= 0x400) ? effect_size : 0x400;
973 if ( effect_size <= 0x400 )
975 effect_addr += 0x100;
976 effect_size -= 0x400;
978 g_CleanRegionMax[channel] = i + 1;
979 g_CleanHandlers[channel] = CleanHandler;
980 g_CleanRegionCur[channel] = 0;
981 xferres = sceSdVoiceTrans(channel, 0, (u8 *)g_ClearEffectData, (u32 *)effect_addr, 0x400);
990 attr->mode = g_EffectAttr[core].mode;
991 attr->delay = g_EffectAttr[core].delay;
992 attr->feedback = g_EffectAttr[core].feedback;
994 attr->depth_L = sceSdGetParam(core | SD_PARAM_EVOLL);
995 attr->depth_R = sceSdGetParam(core | SD_PARAM_EVOLR);
1003 int effects_enabled;
1009 mode_data.m_mode_flags = 0;
1011 clearram = !!(mode & SD_EFFECT_MODE_CLEAR);
1012 effect_mode = clearram ? g_EffectAttr[core].mode : 0;
1013 channel = clearram && !!(mode & 0x200);
1016 if ( mode > SD_EFFECT_MODE_PIPE )
1018 g_EffectAttr[core].mode = mode;
1019 g_EffectAddr[core] = GetEEA(core) - ((g_EffectSizes[mode] << 3) - 1);
1021 memcpy(&mode_data, &g_EffectParams[mode],
sizeof(mode_data));
1024 case SD_EFFECT_MODE_ECHO:
1025 g_EffectAttr[core].feedback = 0x80;
1026 g_EffectAttr[core].delay = 0x80;
1028 case SD_EFFECT_MODE_DELAY:
1029 g_EffectAttr[core].feedback = 0;
1030 g_EffectAttr[core].delay = 0x80;
1033 g_EffectAttr[core].feedback = 0;
1034 g_EffectAttr[core].delay = 0;
1037 if ( mode >= SD_EFFECT_MODE_ECHO && mode <= SD_EFFECT_MODE_DELAY )
1041 delay = attr->delay;
1042 g_EffectAttr[core].delay = delay;
1043 g_EffectAttr[core].feedback = attr->feedback;
1046 mode_data.m_d_same_l_dst = (s16)((u16)delay << 6) - (s16)mode_data.m_d_apf1_size;
1049 mode_data.m_d_same_l_src = delay + mode_data.m_d_same_r_src;
1050 mode_data.m_d_same_r_dst = delay - mode_data.m_d_apf2_size;
1051 mode_data.m_d_comb1_l_src = delay + mode_data.m_d_comb1_r_src;
1052 mode_data.m_d_apf1_l_dst = delay + mode_data.m_d_apf2_l_dst;
1053 mode_data.m_d_apf1_r_dst = delay + mode_data.m_d_apf2_r_dst;
1054 mode_data.m_d_wall_vol = 0x102 * g_EffectAttr[core].feedback;
1058 effects_enabled = (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) >> 7) & 1;
1059 if ( effects_enabled )
1063 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & (~SD_ENABLE_EFFECTS));
1067 retval = (effects_enabled && clearram) ? sceSdClearEffectWorkArea(core, channel, effect_mode) : 0;
1072 sceSdSetParam(core | SD_PARAM_EVOLL, attr->depth_L);
1073 sceSdSetParam(core | SD_PARAM_EVOLR, attr->depth_R);
1074 SetEffectData(core, &mode_data);
1077 sceSdSetAddr(core | SD_ADDR_ESA, g_EffectAddr[core]);
1078 retval = clearram ? sceSdClearEffectWorkArea(core, channel, mode) : 0;
1081 if ( effects_enabled )
1085 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) | SD_ENABLE_EFFECTS);
1091static int GetEEA(
int core)
1094 return sceSdGetAddr(core | SD_ADDR_EEA);
1102 int effects_enabled;
1106 mode_data.m_mode_flags = 0;
1108 clearram = !!(mode & 0x100);
1109 channel = clearram && !!(mode & 0x200);
1111 if ( mode > SD_EFFECT_MODE_PIPE )
1113 g_EffectAttr[core].mode = mode;
1114 g_EffectAttr[core].delay = 0;
1115 g_EffectAttr[core].feedback = 0;
1116 g_EffectAddr[core] = GetEEA(core) - ((g_EffectSizes[mode] << 3) - 1);
1118 memcpy(&mode_data, &g_EffectParams[mode],
sizeof(mode_data));
1120 effects_enabled = (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) >> 7) & 1;
1121 if ( effects_enabled )
1125 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_ENABLE_EFFECTS);
1129 sceSdSetParam(core | SD_PARAM_EVOLL, 0);
1130 sceSdSetParam(core | SD_PARAM_EVOLR, 0);
1131 SetEffectData(core, &mode_data);
1133 sceSdSetAddr(core | SD_ADDR_ESA, g_EffectAddr[core]);
1134 if ( effects_enabled )
1138 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) | SD_ENABLE_EFFECTS);
1141 return clearram ? sceSdCleanEffectWorkArea(core, channel, mode) : 0;
1151 if ( mode > SD_EFFECT_MODE_PIPE )
1153 if ( g_EffectAttr[core].mode != mode )
1155 if ( mode >= SD_EFFECT_MODE_ECHO && mode <= SD_EFFECT_MODE_DELAY )
1160 memcpy(&mode_data, &g_EffectParams[mode],
sizeof(mode_data));
1161 mode_data.m_mode_flags = 0xC011C80;
1162 delay = attr->delay;
1163 g_EffectAttr[core].delay = delay;
1164 g_EffectAttr[core].feedback = attr->feedback;
1167 mode_data.m_d_same_l_dst = (s16)(((u16)delay << 6) - (s16)mode_data.m_d_apf1_size);
1170 mode_data.m_d_same_l_src = delay + mode_data.m_d_same_r_src;
1171 mode_data.m_d_same_r_dst = delay - mode_data.m_d_apf2_size;
1172 mode_data.m_d_comb1_l_src = delay + mode_data.m_d_comb1_r_src;
1173 mode_data.m_d_apf1_l_dst = delay + mode_data.m_d_apf2_l_dst;
1174 mode_data.m_d_apf1_r_dst = delay + mode_data.m_d_apf2_r_dst;
1175 mode_data.m_d_wall_vol = 0x102 * g_EffectAttr[core].feedback;
1176 SetEffectData(core, &mode_data);
1179 sceSdSetParam(core | SD_PARAM_EVOLL, attr->depth_L);
1180 sceSdSetParam(core | SD_PARAM_EVOLR, attr->depth_R);
1184static void InitSpu2_Inner(
void)
1187 USE_IOP_MMIO_HWPORT();
1189 iop_mmio_hwport->ssbus2.ind_4_address = 0xBF900000;
1190 iop_mmio_hwport->ssbus2.ind_9_address = 0xBF900800;
1192 iop_mmio_hwport->dmac1.dpcr1 |= 0x80000;
1193 iop_mmio_hwport->dmac2.dpcr2 |= 8;
1195 iop_mmio_hwport->ssbus1.ind_4_delay = 0x200B31E1;
1196 iop_mmio_hwport->ssbus2.ind_9_delay = 0x200B31E1;
1199static void InitSpu2(
void)
1201 USE_SPU2_MMIO_HWPORT();
1204 spu2_mmio_hwport->m_u.m_e.m_spdif_mode = 0x0900;
1205 spu2_mmio_hwport->m_u.m_e.m_spdif_media = 0x200;
1206 spu2_mmio_hwport->m_u.m_e.m_unknown7ca = 8;
1210static void InitCoreVolume(
int flag)
1213 USE_SPU2_MMIO_HWPORT();
1215 spu2_mmio_hwport->m_u.m_e.m_spdif_out = 0xC032;
1218 for ( i = 0; i < 2; i += 1 )
1220 SD_CORE_0 | SD_INTERNAL_MMIO_ATTR,
1221 (flag ? SD_ENABLE_EFFECTS : 0) | (i ? SD_ENABLE_EX_INPUT : 0) | SD_MUTE | SD_SPU2_ON);
1224 for ( i = 0; i < 2; i += 1 )
1226 sceSdSetSwitch(i | SD_SWITCH_VMIXL, 0xFFFFFF);
1227 sceSdSetSwitch(i | SD_SWITCH_VMIXEL, 0xFFFFFF);
1228 sceSdSetSwitch(i | SD_SWITCH_VMIXR, 0xFFFFFF);
1229 sceSdSetSwitch(i | SD_SWITCH_VMIXER, 0xFFFFFF);
1230 sceSdSetParam(i | SD_PARAM_MMIX, 0xFF0 + (i * 0xC));
1236 for ( i = 0; i < 2; i += 1 )
1238 sceSdSetParam(i | SD_PARAM_MVOLL, 0);
1239 sceSdSetParam(i | SD_PARAM_MVOLR, 0);
1240 sceSdSetParam(i | SD_PARAM_EVOLL, 0);
1241 sceSdSetParam(i | SD_PARAM_EVOLR, 0);
1246 for ( i = 0; i < 2; i += 1 )
1247 sceSdSetAddr(i | SD_ADDR_EEA, (0x000E + i) << 17);
1251 for ( i = 0; i < 2; i += 1 )
1255 sceSdSetParam(i | SD_PARAM_AVOLL, i ? 0x7FFF : 0);
1256 sceSdSetParam(i | SD_PARAM_AVOLR, i ? 0x7FFF : 0);
1257 sceSdSetParam(i | SD_PARAM_BVOLL, 0);
1258 sceSdSetParam(i | SD_PARAM_BVOLR, 0);
1262int sceSdVoiceTrans(s16 chan, u16 mode, u8 *iopaddr, u32 *spuaddr, u32 size)
1269 if ( DmaStartStop((core << 4) | 4, 0, 0) )
1271 if ( g_VoiceTransIoMode[core] != 1 )
1276 g_TransIntrData[core].m_mode = core | 0x900;
1277 g_BlockHandlerIntrData[core].m_cb = 0;
1278 g_BlockHandlerIntrData[core].m_userdata = 0;
1279 g_VoiceTransStatus[core] = 0;
1280 DmaStartStop((core << 4) | 2, spuaddr, 0);
1282 iClearEventFlag(g_VoiceTransCompleteEf[core], ~1);
1284 ClearEventFlag(g_VoiceTransCompleteEf[core], ~1);
1285 g_VoiceTransIoMode[core] = 0;
1286 return DmaStartStop((core << 4) | 5, iopaddr, (size & 0x3FFFFFF) + ((size & 0x3F) ? 0x40 : 0));
1287 case SD_TRANS_WRITE:
1288 g_TransIntrData[core].m_mode = core | 0x500;
1289 g_BlockHandlerIntrData[core].m_cb = 0;
1290 g_BlockHandlerIntrData[core].m_userdata = 0;
1291 DmaStartStop((core << 4) | 2, spuaddr, 0);
1293 iClearEventFlag(g_VoiceTransCompleteEf[core], ~1);
1295 ClearEventFlag(g_VoiceTransCompleteEf[core], ~1);
1296 g_VoiceTransIoMode[core] = 0;
1297 if ( !(mode & SD_TRANS_MODE_IO) )
1299 g_VoiceTransStatus[core] = 0;
1300 return DmaStartStop((core << 4) | 6, iopaddr, (size & 0x3FFFFFF) + ((size & 0x3F) ? 0x40 : 0));
1302 g_VoiceTransStatus[core] = 1;
1303 return VoiceTrans_Write_IOMode((u16 *)iopaddr, (size & 0x3FFFFFF) + ((size & 0x3F) ? 0x40 : 0), core);
1309u32 sceSdVoiceTransStatus(s16 channel, s16 flag)
1315 if ( g_VoiceTransStatus[core] == 1 || g_VoiceTransIoMode[core] == 1 )
1320 if ( g_VoiceTransCompleteBool[core] )
1322 g_VoiceTransCompleteBool[core] = 0;
1323 g_VoiceTransIoMode[core] = 1;
1329 WaitEventFlag(g_VoiceTransCompleteEf[core], 1, 0, &efres);
1330 g_VoiceTransCompleteBool[core] = 0;
1331 g_VoiceTransIoMode[core] = 1;
1336 return g_VoiceTransIoMode[core];
1339int sceSdStopTrans(
int channel)
1344 g_TransIntrData[core].m_mode = core;
1345 g_BlockHandlerIntrData[core].m_cb = 0;
1346 g_BlockHandlerIntrData[core].m_userdata = 0;
1347 return DmaStartStop((core << 4) | 0xA, 0, 0);
1350int sceSdBlockTrans(s16 chan, u16 mode, u8 *iopaddr, u32 size, ...)
1361 va_start(va2, size);
1362 vararg_elm1 = va_arg(va2, uiptr);
1363 vararg_elm2 = va_arg(va2, uiptr);
1364 vararg_elm3 = va_arg(va2, uiptr);
1367 started = DmaStartStop((core << 4) | 4, 0, 0);
1368 transfer_dir = mode & 3;
1369 switch ( transfer_dir )
1376 g_TransIntrData[core].m_mode = core | 0xA00;
1377 g_BlockHandlerIntrData[core].m_cb = 0;
1378 g_BlockHandlerIntrData[core].m_userdata = 0;
1379 if ( (mode & 0x80) )
1383 g_TransIntrData[core].m_mode = core;
1386 g_BlockHandlerIntrData[core].m_cb = (
void *)vararg_elm1;
1387 g_BlockHandlerIntrData[core].m_userdata = (
void *)vararg_elm2;
1388 g_TransIntrData[core].m_mode |= 0x8000;
1390 else if ( (mode & SD_TRANS_LOOP) )
1393 g_TransIntrData[core].m_mode |= SD_TRANS_LOOP << 8;
1395 retres_1 = BlockTransRead(iopaddr, size, core, mode);
1398 g_BlockHandlerIntrData[core].m_cb = 0;
1399 g_BlockHandlerIntrData[core].m_userdata = 0;
1400 g_TransIntrData[core].m_mode = core;
1401 return DmaStartStop((core << 4) | 0xA, 0, 0);
1402 case SD_TRANS_WRITE:
1403 case SD_TRANS_WRITE_FROM:
1408 g_TransIntrData[core].m_mode = core | 0x600;
1409 g_BlockHandlerIntrData[core].m_cb = 0;
1410 g_BlockHandlerIntrData[core].m_userdata = 0;
1411 if ( (mode & 0x80) )
1415 g_TransIntrData[core].m_mode = core;
1418 g_BlockHandlerIntrData[core].m_cb = (
void *)vararg_elm2;
1419 g_BlockHandlerIntrData[core].m_userdata = (
void *)vararg_elm3;
1420 g_TransIntrData[core].m_mode |= 0x8000;
1422 else if ( (mode & SD_TRANS_LOOP) )
1425 g_TransIntrData[core].m_mode |= SD_TRANS_LOOP << 8;
1428 BlockTransWriteFrom(iopaddr, size, chan, mode, (transfer_dir == SD_TRANS_WRITE_FROM) ? (
void *)vararg_elm1 : 0);
1435 g_BlockHandlerIntrData[core].m_cb = 0;
1436 g_BlockHandlerIntrData[core].m_userdata = 0;
1437 g_TransIntrData[core].m_mode = core;
1442u32 sceSdBlockTransStatus(s16 channel, s16 flag)
1446 USE_IOP_MMIO_HWPORT();
1451 return (g_BlockTransBuff[core] << 24)
1452 | (((sceSdGetParam(core | SD_INTERNAL_MMIO_ADMAS) & 7) ?
1453 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr :
1458static int InitSpdif()
1461 USE_SPU2_MMIO_HWPORT();
1463 spu2_mmio_hwport->m_u.m_e.m_spdif_out = 0;
1464 libsd_do_busyloop(2);
1465 spu2_mmio_hwport->m_u.m_e.m_spdif_out = 0x8000;
1466 libsd_do_busyloop(1);
1469 for ( i = 0; i < 2; i += 1 )
1471 sceSdSetParam(i | SD_PARAM_MVOLL, 0);
1472 sceSdSetParam(i | SD_PARAM_MVOLR, 0);
1476 for ( i = 0; i < 2; i += 1 )
1477 sceSdSetParam(i | SD_INTERNAL_MMIO_ADMAS, 0);
1480 for ( i = 0; i < 2; i += 1 )
1481 sceSdSetParam(i | SD_INTERNAL_MMIO_ATTR, 0);
1482 libsd_do_busyloop(1);
1485 for ( i = 0; i < 2; i += 1 )
1486 sceSdSetParam(i | SD_INTERNAL_MMIO_ATTR, SD_SPU2_ON);
1489 for ( i = 0; i < 2; i += 1 )
1491 sceSdSetParam(i | SD_PARAM_MVOLL, 0);
1492 sceSdSetParam(i | SD_PARAM_MVOLR, 0);
1495 for ( i = 0; (sceSdGetParam(SD_CORE_0 | SD_INTERNAL_MMIO_STATX) & 0x7FF)
1496 && (sceSdGetParam(SD_CORE_1 | SD_INTERNAL_MMIO_STATX) & 0x7FF) && i < 0xF00;
1498 libsd_do_busyloop(1);
1501 for ( i = 0; i < 2; i += 1 )
1502 sceSdSetSwitch(i | SD_SWITCH_KOFF, 0xFFFFFF);
1505 for ( i = 0; i < 2; i += 1 )
1507 sceSdSetSwitch(i | SD_SWITCH_PMON, 0);
1508 sceSdSetSwitch(i | SD_SWITCH_NON, 0);
1513static void SetDmaWrite(
int chan)
1516 USE_IOP_MMIO_HWPORT();
1518 dmachanptr = chan ? &iop_mmio_hwport->ssbus2.ind_9_delay : &iop_mmio_hwport->ssbus1.ind_4_delay;
1519 *dmachanptr &= ~0xF000000;
1522static void SetDmaRead(
int chan)
1525 USE_IOP_MMIO_HWPORT();
1527 dmachanptr = chan ? &iop_mmio_hwport->ssbus2.ind_9_delay : &iop_mmio_hwport->ssbus1.ind_4_delay;
1528 *dmachanptr = (*dmachanptr & ~0xF000000) | 0x2000000;
1531static void __attribute__((optimize(
"no-unroll-loops"))) libsd_do_busyloop_inner(
void)
1537 for ( i = 0; i < 120; i += 1 )
1540 __asm__ __volatile__(
"" :
"+g"(loopmul) : :);
1544static void libsd_do_busyloop(
int count)
1548 for ( i = 0; i <
count; i += 1 )
1549 libsd_do_busyloop_inner();
1552static u32 DmaStartStop(
int mainarg,
void *vararg2, u32 vararg3)
1556 u32 blocktransbufitem;
1561 USE_IOP_MMIO_HWPORT();
1564 core = (mainarg >> 4) & 1;
1565 switch ( mainarg & 0xF )
1569 sceSdSetAddr(core | SD_ADDR_TSA, (uiptr)vararg2);
1573 if ( (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & SD_DMA_IN_PROCESS) )
1575 if ( ((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr & SD_DMA_START) )
1578 if ( sceSdGetParam(core | SD_INTERNAL_MMIO_ADMAS) )
1584 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) | SD_DMA_READ);
1587 vararg3_cal = (vararg3 >> 6) + (!!(vararg3 & 0x3F));
1588 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr = (uiptr)vararg2;
1589#pragma GCC diagnostic push
1590#pragma GCC diagnostic ignored "-Wstrict-aliasing"
1591 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[0] = 16;
1592#pragma GCC diagnostic pop
1593 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[1] = vararg3_cal;
1594 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr =
1595 SD_DMA_START | SD_DMA_CS | SD_DMA_DIR_SPU2IOP;
1596 return vararg3_cal << 6;
1601 core | SD_INTERNAL_MMIO_ATTR, (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA) | SD_DMA_WRITE);
1604 vararg3_cal = (vararg3 >> 6) + (!!(vararg3 & 0x3F));
1605 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr = (uiptr)vararg2;
1606#pragma GCC diagnostic push
1607#pragma GCC diagnostic ignored "-Wstrict-aliasing"
1608 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[0] = 16;
1609#pragma GCC diagnostic pop
1610 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[1] = vararg3_cal;
1611 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr =
1612 SD_DMA_START | SD_DMA_CS | SD_DMA_DIR_IOP2SPU;
1613 return vararg3_cal << 6;
1615 blocktransbufitem = 0;
1617 if ( ((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr & SD_DMA_START) )
1619 blocktransbufitem = g_BlockTransBuff[core];
1620 dma_addr = (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr;
1621 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr &= ~SD_DMA_START;
1623 if ( (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & SD_CORE_DMA) )
1626 for ( i = 0; !(sceSdGetParam(core | SD_INTERNAL_MMIO_STATX) & 0x80) && i < 0x1000000; i += 1 )
1632 if ( (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & SD_CORE_DMA) )
1636 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
1639 for ( i = 0; (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & SD_CORE_DMA) && i < 0xF00; i += 1 )
1644 hichk = !!(sceSdGetParam(core | SD_INTERNAL_MMIO_ADMAS) & 7);
1646 sceSdSetParam(core | SD_INTERNAL_MMIO_ADMAS, 0);
1648 iSetEventFlag(g_VoiceTransCompleteEf[core], 1);
1650 SetEventFlag(g_VoiceTransCompleteEf[core], 1);
1651 g_VoiceTransCompleteBool[core] = 0;
1652 g_VoiceTransIoMode[core] = 1;
1653 g_CleanHandlers[core] = 0;
1654 return (dma_addr && hichk) ? ((dma_addr & ~0xFF000000) | (blocktransbufitem << 24)) : 0;
1660static u32 VoiceTrans_Write_IOMode(
const u16 *iopaddr, u32 size,
int core)
1669 for ( size_tmp = size; size_tmp; size_tmp -=
count )
1671 count = (size_tmp <= 0x40) ? size_tmp : 0x40;
1673 for ( i = 0; i < (
count / 2); i += 1 )
1674 sceSdSetParam(core | SD_INTERNAL_MMIO_STD, iopaddr[i]);
1679 core | SD_INTERNAL_MMIO_ATTR, (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA) | SD_DMA_IO);
1683 for ( i = 0; (sceSdGetParam(core | SD_INTERNAL_MMIO_STATX) & SD_IO_IN_PROCESS) && i < 0xF00; i += 1 )
1684 libsd_do_busyloop(1);
1689 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
1691 g_VoiceTransIoMode[core] = 1;
1696static void do_finish_block_clean_xfer(
int core)
1699 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
1700 sceSdSetParam(core | SD_INTERNAL_MMIO_ADMAS, 0);
1703static int TransInterrupt(
IntrData *intr)
1711 USE_IOP_MMIO_HWPORT();
1713 mode = intr->m_mode;
1714 switch ( mode & 0xC00 )
1717 dma_dir = SD_DMA_DIR_IOP2SPU;
1720 dma_dir = SD_DMA_DIR_SPU2IOP;
1726 switch ( mode & 0x300 )
1733 for ( i = 0; !(sceSdGetParam(core | SD_INTERNAL_MMIO_STATX) & 0x80) && i < 0x1000000; i += 1 )
1737 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
1738 for ( i = 0; (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & SD_CORE_DMA) && i < 0xF00; i += 1 )
1741 if ( dma_dir == SD_DMA_DIR_SPU2IOP )
1743 if ( g_CleanHandlers[core] )
1744 g_CleanHandlers[core](core);
1747 iSetEventFlag(g_VoiceTransCompleteEf[core], 1);
1748 if ( g_TransIntrHandlers[core] )
1750 g_VoiceTransIoMode[core] = 1;
1751 g_TransIntrHandlers[core](core, intr->m_data);
1753 else if ( !g_TransIntrCallbacks[core] )
1754 g_VoiceTransCompleteBool[core] = 1;
1757 g_VoiceTransIoMode[core] = 1;
1758 g_TransIntrCallbacks[core](0);
1764 if ( (mode & 0x8000) )
1766 if ( g_BlockHandlerIntrData[core].m_cb )
1768 g_BlockHandlerIntrData[core].m_cb(core, g_BlockHandlerIntrData[core].m_userdata, &dma_addr, &dma_size);
1771 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[1] =
1772 (dma_size >> 6) + (dma_size - (dma_size & 0x3FFFFFF) > 0);
1773 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr = (uiptr)dma_addr;
1774 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr =
1775 dma_dir | SD_DMA_START | SD_DMA_CS;
1779 do_finish_block_clean_xfer(core);
1780 g_BlockHandlerIntrData[core].m_cb = 0;
1781 g_BlockHandlerIntrData[core].m_userdata = 0;
1785 do_finish_block_clean_xfer(core);
1786 if ( dma_dir == SD_DMA_DIR_SPU2IOP )
1791 if ( (mode & (SD_TRANS_LOOP << 8)) )
1794 g_BlockTransBuff[core] = 1 - g_BlockTransBuff[core];
1796 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[1] =
1797 (int)g_BlockTransSize[core] / 0x40 + ((
int)g_BlockTransSize[core] % 0x40 > 0);
1798 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr =
1799 (uiptr)(g_BlockTransAddr[core] + g_BlockTransBuff[core] * g_BlockTransSize[core]);
1800 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr =
1801 dma_dir | SD_DMA_START | SD_DMA_CS;
1804 do_finish_block_clean_xfer(core);
1805 if ( dma_dir == SD_DMA_DIR_SPU2IOP )
1807 if ( g_TransIntrHandlers[core] )
1808 g_TransIntrHandlers[core](core, intr->m_data);
1809 else if ( g_TransIntrCallbacks[core] )
1810 g_TransIntrCallbacks[core](0);
1819static u32 BlockTransWriteFrom(u8 *iopaddr, u32 size,
int core,
int mode, u8 *startaddr)
1825 USE_IOP_MMIO_HWPORT();
1828 startaddr_tmp = startaddr;
1829 g_BlockTransAddr[core] = iopaddr;
1830 g_BlockTransBuff[core] = 0;
1831 g_BlockTransSize[core] = size;
1834 size_align = size - (startaddr - iopaddr);
1835 if ( (u32)(startaddr - iopaddr) >= size )
1839 other_align = startaddr - iopaddr - size;
1840 if ( !(mode & SD_TRANS_LOOP) || other_align >= size )
1842 g_BlockTransBuff[core] += 1;
1843 size_align = size - other_align;
1845 if ( size_align % 0x400 > 0 )
1847 size_align = (size_align / 0x400 + 1) << 10;
1848 startaddr_tmp = iopaddr + g_BlockTransBuff[core] * size + size - size_align;
1853 startaddr_tmp = iopaddr;
1858 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
1861 sceSdSetAddr(core | SD_ADDR_TSA, 0);
1862 sceSdSetParam(core | SD_INTERNAL_MMIO_ADMAS, 1 << core);
1864 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr = (uiptr)startaddr_tmp;
1865#pragma GCC diagnostic push
1866#pragma GCC diagnostic ignored "-Wstrict-aliasing"
1867 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[0] = 16;
1868#pragma GCC diagnostic pop
1869 size_align_r6 = ((size_align < 0) ? (size_align + 63) : size_align) >> 6;
1870 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[1] =
1871 size_align_r6 + (size_align - (size_align_r6 << 6) > 0);
1872 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr =
1873 SD_DMA_START | SD_DMA_CS | SD_DMA_DIR_IOP2SPU;
1877static u32 BlockTransRead(u8 *iopaddr, u32 size,
int core, u16 mode)
1880 USE_IOP_MMIO_HWPORT();
1883 g_BlockTransAddr[core] = iopaddr;
1884 g_BlockTransBuff[core] = 0;
1885 g_BlockTransSize[core] = size;
1888 sceSdSetParam(core | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
1891 sceSdSetAddr(core | SD_ADDR_TSA, (((mode & ~0xF0FF) << 1) + 0x400) << 1);
1892 sceSdSetParam(core | SD_INTERNAL_MMIO_UNK1AE, (mode & ~0xFFF) >> 11);
1893 libsd_do_busyloop(3);
1895 sceSdSetParam(core | SD_INTERNAL_MMIO_ADMAS, 4);
1897 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->madr = (uiptr)iopaddr;
1898#pragma GCC diagnostic push
1899#pragma GCC diagnostic ignored "-Wstrict-aliasing"
1900 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[0] = 16;
1901#pragma GCC diagnostic pop
1902 ((vu16 *)&((core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->bcr))[1] =
1903 (int)g_BlockTransSize[core] / 0x40 + ((
int)g_BlockTransSize[core] % 0x40 > 0);
1904 (core ? &iop_mmio_hwport->dmac2.newch[0] : &iop_mmio_hwport->dmac1.oldch[4])->chcr = SD_DMA_START | SD_DMA_CS;
1908static int SifDmaBatch(
void *ee_addr,
void *iop_addr,
int size)
1916 xferparam.dest = ee_addr;
1917 xferparam.src = iop_addr;
1918 xferparam.size = size;
1921 dmat = sceSifSetDma(&xferparam, SIF_DMA_TO_EE);
1925 for ( i = 0, dma_status = 0; i >= 0 && dma_status >= 0; i += 1 )
1928 dma_status = sceSifDmaStat(dmat);
1931 return (i < 0) ? -1 : 0;
1934int sceSdProcBatch(
const sceSdBatch *batch, u32 *rets, u32 num)
1938 for ( cnt = 0; cnt < num; cnt += 1 )
1943 switch ( batch[cnt].func )
1945 case SD_BATCH_SETPARAM:
1946 sceSdSetParam(batch[cnt].entry, batch[cnt].value);
1948 case SD_BATCH_SETSWITCH:
1949 sceSdSetSwitch(batch[cnt].entry, batch[cnt].value);
1951 case SD_BATCH_SETADDR:
1952 sceSdSetAddr(batch[cnt].entry, batch[cnt].value);
1954 case SD_BATCH_SETCORE:
1955 sceSdSetCoreAttr(batch[cnt].entry, batch[cnt].value);
1957 case SD_BATCH_WRITEIOP:
1958 *(u32 *)batch[cnt].value = batch[cnt].entry;
1960 case SD_BATCH_WRITEEE:
1961 g_BatchData = batch[cnt].entry;
1962 Param = SifDmaBatch((
void *)batch[cnt].value, &g_BatchData,
sizeof(g_BatchData));
1964 case SD_BATCH_EERETURN:
1965 Param = SifDmaBatch((
void *)batch[cnt].value, rets, batch[cnt].entry);
1967 case SD_BATCH_GETPARAM:
1968 Param = sceSdGetParam(batch[cnt].entry);
1970 case SD_BATCH_GETSWITCH:
1971 Param = sceSdGetSwitch(batch[cnt].entry);
1973 case SD_BATCH_GETADDR:
1974 Param = sceSdGetAddr(batch[cnt].entry);
1976 case SD_BATCH_GETCORE:
1977 Param = sceSdGetCoreAttr(batch[cnt].entry);
1988int sceSdProcBatchEx(
const sceSdBatch *batch, u32 *rets, u32 num, u32 voice)
1995 for ( cnt = 0; cnt < num; cnt += 1 )
2000 switch ( batch[cnt].func )
2002 case SD_BATCH_SETPARAM:
2003 if ( (batch[cnt].entry & 0x3E) == 0x3E )
2005 for ( i = 0; i < 24; i += 1 )
2007 if ( ((1 << i) & voice) )
2010 sceSdSetParam((batch[cnt].entry & ~0x3E) | (i << 1), batch[cnt].value);
2016 sceSdSetParam(batch[cnt].entry, batch[cnt].value);
2018 case SD_BATCH_SETSWITCH:
2019 sceSdSetSwitch(batch[cnt].entry, batch[cnt].value);
2021 case SD_BATCH_SETADDR:
2022 if ( (batch[cnt].entry & 0x7E) == 0x7E )
2024 for ( i = 0; i < 24; i += 1 )
2026 if ( ((1 << i) & voice) )
2029 sceSdSetAddr((batch[cnt].entry & ~0x3E) | (i << 1), batch[cnt].value);
2035 sceSdSetAddr(batch[cnt].entry, batch[cnt].value);
2037 case SD_BATCH_SETCORE:
2038 sceSdSetCoreAttr(batch[cnt].entry, batch[cnt].value);
2040 case SD_BATCH_WRITEIOP:
2041 *(u32 *)batch[cnt].value = batch[cnt].entry;
2043 case SD_BATCH_WRITEEE:
2044 g_BatchData = batch[cnt].entry;
2045 Param = SifDmaBatch((
void *)batch[cnt].value, &g_BatchData,
sizeof(g_BatchData));
2047 case SD_BATCH_EERETURN:
2048 Param = SifDmaBatch((
void *)batch[cnt].value, rets, batch[cnt].entry);
2050 case SD_BATCH_GETPARAM:
2051 if ( (batch[cnt].entry & 0x3E) == 0x3E )
2053 for ( i = 0; i < 24; i += 1 )
2055 if ( ((1 << i) & voice) )
2056 Param = sceSdGetParam((batch[cnt].entry & ~0x3E) | (i << 1));
2064 Param = sceSdGetParam(batch[cnt].entry);
2066 case SD_BATCH_GETSWITCH:
2067 Param = sceSdGetSwitch(batch[cnt].entry);
2069 case SD_BATCH_GETADDR:
2070 if ( (batch[cnt].entry & 0x7E) == 0x7E )
2072 for ( i = 0; i < 24; i += 1 )
2074 if ( ((1 << i) & voice) )
2076 Param = sceSdGetAddr((batch[cnt].entry & ~0x3E) | (i << 1));
2085 Param = sceSdGetAddr(batch[cnt].entry);
2087 case SD_BATCH_GETCORE:
2088 Param = sceSdGetCoreAttr(batch[cnt].entry);
2100void sceSdSetParam(u16 entry, u16 value)
2103 g_ParamRegList[((entry >> 8) & 0xFF)]
2104 [((entry & 0x3E) << 2) + (((entry & 1) * (0x400 - 984 * (!!(entry & 0x80)))) >> 1)] = value;
2107u16 sceSdGetParam(u16 entry)
2110 return g_ParamRegList[((entry >> 8) & 0xFF)]
2111 [((entry & 0x3E) << 2) + (((entry & 1) * (0x400 - 984 * (!!(entry & 0x80)))) >> 1)];
2114void sceSdSetSwitch(u16 entry, u32 value)
2118 regptr = &g_ParamRegList[((entry >> 8) & 0xFF)][(entry & 1) << 9];
2120 regptr[1] = (value >> 16) & 0xFF;
2123u32 sceSdGetSwitch(u16 entry)
2127 regptr = &g_ParamRegList[((entry >> 8) & 0xFF)][(entry & 1) << 9];
2128 return regptr[0] | (regptr[1] << 16);
2131void sceSdSetAddr(u16 entry, u32 value)
2135 reg1 = &g_ParamRegList[((entry >> 8) & 0xFF)][((entry & 1) << 9) + 3 * (entry & 0x3E)];
2136 reg1[0] = value >> 17;
2137 if ( (entry & 0xFF00) != SD_ADDR_EEA )
2138 reg1[1] = (value >> 1) & ~7;
2141u32 sceSdGetAddr(u16 entry)
2149 reg1 = &g_ParamRegList[((entry >> 8) & 0xFF)][((entry & 1) << 9) + 3 * (entry & 0x3E)];
2150 regmask = entry & 0xFF00;
2151 rethi = reg1[0] << 17;
2152 if ( regmask != SD_ADDR_EEA )
2154 retlo = reg1[1] << 1;
2155 if ( regmask == SD_VADDR_LSAX || regmask == SD_VADDR_NAX )
2157 rethi = reg1[0] << 17;
2158 retlo = reg1[1] << 1;
2161 return rethi | retlo;
2164u16 sceSdNote2Pitch(u16 center_note, u16 center_fine, u16 note, s16 fine)
2175 _fine = fine + center_fine;
2176 _fine2 = _fine / 0x80;
2177 _note = note + _fine2 - center_note;
2178 offset2 = _fine % 0x80;
2179 val2 = ((_note / 6) >> 1) - (_note < 0);
2180 offset1 = _note - 12 * val2;
2182 if ( (offset1 < 0) || (!offset1 && offset2 < 0) )
2189 offset2 += (_fine2 + 1) << 7;
2193 retval = (g_NotePitchTable[offset1] * g_NotePitchTable[offset2 + 12]) >> 16;
2194 return (val < 0) ? (u32)(retval + (1 << (-val - 1))) >> -val : (u32)retval;
2197u16 sceSdPitch2Note(u16 center_note, u16 center_fine, u16 pitch)
2206 pitch = (pitch > 0x3FFF) ? 0x3FFF : pitch;
2207 for ( i1 = 0; i1 < 14; i1 += 1 )
2209 if ( ((pitch >> i1) & 1) )
2212 val = pitch << (15 - bit);
2213 for ( i2 = 11; val < g_NotePitchTable[i2] && i2 > 0; i2 -= 1 )
2216 if ( !g_NotePitchTable[i2] )
2219 val /= g_NotePitchTable[i2];
2220 for ( i5 = 127; val < g_NotePitchTable[i5 + 12] && i5 > 0; i5 -= 1 )
2223 return (((center_fine + i5 + 1) & 0x7E)
2224 + ((i2 + center_note + 12 * (bit - 12) + ((u16)(center_fine + i5 + 1) >> 7)) << 8))
2228static int SetSpdifMode(
int val)
2232 USE_SPU2_MMIO_HWPORT();
2234 spdif_out_new = spu2_mmio_hwport->m_u.m_e.m_spdif_out & ~0x1A8;
2235 spdif_mode_new = spu2_mmio_hwport->m_u.m_e.m_spdif_mode & ~0xBF06;
2236 switch ( val & 0xF )
2239 spdif_out_new |= 0x20;
2242 spdif_out_new |= 0x100;
2243 spdif_mode_new |= 2;
2248 spdif_out_new |= 0x100;
2253 spdif_mode_new |= (val & 0x80) ? 0x8000 : 0;
2254 switch ( val & 0xF00 )
2257 spu2_mmio_hwport->m_u.m_e.m_spdif_media = 0;
2258 spdif_mode_new |= 0x100;
2261 spu2_mmio_hwport->m_u.m_e.m_spdif_media = 0x200;
2262 spdif_mode_new |= 0x1900;
2265 spu2_mmio_hwport->m_u.m_e.m_spdif_media = 0x200;
2266 spdif_mode_new |= 0x900;
2269 spu2_mmio_hwport->m_u.m_e.m_spdif_out = spdif_out_new;
2270 spu2_mmio_hwport->m_u.m_e.m_spdif_mode = spdif_mode_new;
2271 g_SpdifSettings = val;
2275void sceSdSetCoreAttr(u16 entry, u16 value)
2282 switch ( entry & ~0xFFFF0001 )
2284 case SD_CORE_SPDIF_MODE:
2285 SetSpdifMode(value);
2287 case SD_CORE_NOISE_CLK:
2290 core | SD_INTERNAL_MMIO_ATTR, (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~0x3F00) | ((value & 0x3F) << 8));
2295 setting_tmp = g_CoreAttrShifts[((entry & 0xE) >> 1) - 1];
2298 core | SD_INTERNAL_MMIO_ATTR,
2299 (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) & ~(1 << setting_tmp)) | ((value & 1) << setting_tmp));
2305u16 sceSdGetCoreAttr(u16 entry)
2310 switch ( entry & 0xE )
2312 case SD_CORE_EFFECT_ENABLE:
2314 return (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) >> 7) & 1;
2315 case SD_CORE_IRQ_ENABLE:
2317 return (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) >> 6) & 1;
2318 case SD_CORE_MUTE_ENABLE:
2320 return (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) >> 14) & 1;
2321 case SD_CORE_NOISE_CLK:
2323 return (sceSdGetParam(core | SD_INTERNAL_MMIO_ATTR) >> 8) & 0x3F;
2324 case SD_CORE_SPDIF_MODE:
2325 return g_SpdifSettings & 0xFFFF;
2331SdIntrCallback sceSdSetTransCallback(s32 core, SdIntrCallback cb)
2333 SdIntrCallback oldtmp;
2337 oldtmp = g_TransIntrCallbacks[core];
2338 g_TransIntrCallbacks[core] = cb;
2342sceSdTransIntrHandler sceSdSetTransIntrHandler(
int channel, sceSdTransIntrHandler func,
void *arg)
2344 sceSdTransIntrHandler oldtmp;
2349 oldtmp = g_TransIntrHandlers[core];
2350 g_TransIntrHandlers[core] = func;
2351 g_TransIntrData[core].m_data = arg;
2355void *sceSdGetTransIntrHandlerArgument(
int arg)
2357 return g_TransIntrData[arg].m_data;
2360SdIntrCallback sceSdSetIRQCallback(SdIntrCallback cb)
2362 SdIntrCallback oldtmp;
2364 oldtmp = g_Spu2IrqCallback;
2365 g_Spu2IrqCallback = cb;
2369sceSdSpu2IntrHandler sceSdSetSpu2IntrHandler(sceSdSpu2IntrHandler func,
void *arg)
2371 sceSdSpu2IntrHandler oldtmp;
2373 oldtmp = g_Spu2IntrHandler;
2374 g_Spu2IntrHandler = func;
2375 g_Spu2IntrHandlerData = arg;
2379void *sceSdGetSpu2IntrHandlerArgument()
2381 return g_Spu2IntrHandlerData;
2384static int Spu2Interrupt(
void *data)
2387 USE_SPU2_MMIO_HWPORT();
2390 if ( !g_Spu2IntrHandler && !g_Spu2IrqCallback )
2392 while ( (val = (spu2_mmio_hwport->m_u.m_e.m_spdif_irqinfo & 0xC) >> 2) )
2396 for ( i = 0; i < 2; i += 1 )
2397 if ( val & (1 << i) )
2399 sceSdSetParam(i | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(i | SD_INTERNAL_MMIO_ATTR) & ~0x40);
2400 if ( g_Spu2IntrHandler )
2401 g_Spu2IntrHandler(val, g_Spu2IntrHandlerData);
2402 else if ( g_Spu2IrqCallback )
2403 g_Spu2IrqCallback(0);
2408static int InitVoices(
void)
2414 sceSdSetParam(SD_CORE_0 | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(SD_CORE_0 | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
2416 sceSdSetAddr(SD_CORE_0 | SD_ADDR_TSA, 0x5000);
2419 for ( i = 0; i < (int)(
sizeof(g_VoiceDataInit) /
sizeof(g_VoiceDataInit[0])); i += 1 )
2420 sceSdSetParam(SD_CORE_0 | SD_INTERNAL_MMIO_STD, g_VoiceDataInit[i]);
2424 SD_CORE_0 | SD_INTERNAL_MMIO_ATTR, (sceSdGetParam(SD_CORE_0 | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA) | SD_DMA_IO);
2426 for ( i = 0; (sceSdGetParam(SD_CORE_0 | SD_INTERNAL_MMIO_STATX) & SD_IO_IN_PROCESS) && i <= 0x1000000; i += 1 )
2427 libsd_do_busyloop(1);
2430 sceSdSetParam(SD_CORE_0 | SD_INTERNAL_MMIO_ATTR, sceSdGetParam(SD_CORE_0 | SD_INTERNAL_MMIO_ATTR) & ~SD_CORE_DMA);
2434 for ( i = 0; i < 24; i += 1 )
2436 for ( j = 0; j < 2; j += 1 )
2437 sceSdSetParam(SD_VOICE(j ^ 1, i) | SD_VPARAM_VOLL, 0);
2438 for ( j = 0; j < 2; j += 1 )
2439 sceSdSetParam(SD_VOICE(j ^ 1, i) | SD_VPARAM_VOLR, 0);
2440 for ( j = 0; j < 2; j += 1 )
2441 sceSdSetParam(SD_VOICE(j ^ 1, i) | SD_VPARAM_PITCH, 0x3FFF);
2442 for ( j = 0; j < 2; j += 1 )
2443 sceSdSetParam(SD_VOICE(j ^ 1, i) | SD_VPARAM_ADSR1, 0);
2444 for ( j = 0; j < 2; j += 1 )
2445 sceSdSetParam(SD_VOICE(j ^ 1, i) | SD_VPARAM_ADSR2, 0);
2447 for ( j = 0; j < 2; j += 1 )
2448 sceSdSetAddr(SD_VOICE(j ^ 1, i) | SD_VADDR_SSA, 0x5000);
2453 for ( i = 0; i < 2; i += 1 )
2454 sceSdSetSwitch((i ^ 1) | SD_SWITCH_KON, 0xFFFFFF);
2457 libsd_do_busyloop(3);
2461 for ( i = 0; i < 2; i += 1 )
2462 sceSdSetSwitch((i ^ 1) | SD_SWITCH_KOFF, 0xFFFFFF);
2465 libsd_do_busyloop(3);
2468 for ( i = 0; i < 2; i += 1 )
2469 sceSdSetSwitch(i | SD_SWITCH_ENDX, 0);
2473static int Reset(
int flag)
2486 for ( i = 0; i < 2; i += 1 )
2488 g_VoiceTransStatus[i] = 0;
2489 g_VoiceTransIoMode[i] = 1;
2490 g_VoiceTransCompleteBool[i] = 0;
2491 g_TransIntrHandlers[i] = 0;
2492 g_CleanHandlers[i] = 0;
2493 g_TransIntrData[i].m_mode = i;
2494 g_TransIntrData[i].m_data = 0;
2495 g_BlockHandlerIntrData[i].m_cb = 0;
2496 g_BlockHandlerIntrData[i].m_userdata = 0;
2497 g_TransIntrCallbacks[i] = 0;
2499 g_Spu2IntrHandler = 0;
2500 g_Spu2IntrHandlerData = 0;
2501 g_Spu2IrqCallback = 0;
2502 if ( !(flag & 0xF) )
2504 bzero(g_EffectAttr,
sizeof(g_EffectAttr));
2506 for ( i = 0; i < 2; i += 1 )
2507 g_EffectAddr[i] = 0x1DFFF0 + (0x20000 * i);
2510 for ( i = 0; i < 2; i += 1 )
2511 sceSdSetAddr(i | SD_ADDR_ESA, (((0x000E + i) << 16) | 0xFFF8) << 1);
2517 for ( i = 0; i < 2; i += 1 )
2519 if ( g_VoiceTransCompleteEf[i] <= 0 )
2520 g_VoiceTransCompleteEf[i] = CreateEventFlag(&efparam);
2524 iSetEventFlag(g_VoiceTransCompleteEf[i], 1);
2526 SetEventFlag(g_VoiceTransCompleteEf[i], 1);
2529 return (g_VoiceTransCompleteEf[0] <= 0 || g_VoiceTransCompleteEf[1] <= 0) ? -301 : 0;
2532static void reset_vars(
void)
2538 for ( i = 0; i < 2; i += 1 )
2539 g_VoiceTransCompleteEf[i] = 0;
2542int sceSdInit(
int flag)
2547 if ( !(flag & 0xF) )
2549 resetres = Reset(flag);
2551 InitCoreVolume(flag & 0xF);
2555 RegisterIntrHandler(IOP_IRQ_DMA_SPU, 1, (
int (*)(
void *))TransInterrupt, &g_TransIntrData[0]);
2556 RegisterIntrHandler(IOP_IRQ_DMA_SPU2, 1, (
int (*)(
void *))TransInterrupt, &g_TransIntrData[1]);
2557 RegisterIntrHandler(IOP_IRQ_SPU, 1, (
int (*)(
void *))Spu2Interrupt, g_Spu2IntrHandlerData);
2568 for ( i = 0; i < 2; i += 1 )
2569 DmaStartStop((i << 4) | 0xA, 0, 0);
2571 for ( i = 0; i < 2; i += 1 )
2572 if ( g_VoiceTransCompleteEf[i] > 0 )
2573 DeleteEventFlag(g_VoiceTransCompleteEf[i]);
int CpuResumeIntr(int state)
int RegisterIntrHandler(int irq, int mode, int(*handler)(void *), void *arg)
int ReleaseIntrHandler(int irq)
int QueryIntrContext(void)
int DisableIntr(int irq, int *res)
int CpuSuspendIntr(int *state)
u32 count
start sector of fragmented bd/file