www.pudn.com > sn068s.zip > SPC.NI
%ifndef SNEeSe_SPC_i %define SNEeSe_SPC_i %define VAR_CYCLE_RATIO %define SPC2MHz %include "regs.ni" %include "cycles.ni" %ifndef SNEeSe_SPC700_asm %define _SPC_CTRL 0xF1 extern _SPCRAM extern _TotalCycles extern _SPC_T0_cycle_latch,_SPC_T0_target,_SPC_T0_position extern _SPC_T0_cycle_latch,_SPC_T0_counter extern _SPC_T1_cycle_latch,_SPC_T1_target,_SPC_T1_position extern _SPC_T1_cycle_latch,_SPC_T1_counter extern _SPC_T2_cycle_latch,_SPC_T2_target,_SPC_T2_position extern _SPC_T2_cycle_latch,_SPC_T2_counter %endif ;%1 = timer %macro Update_SPC_Timer 1 test byte [_SPCRAM+_SPC_CTRL],1 << %1 je %%done mov ecx,[_SPC_T%1_cycle_latch] mov edx,[_TotalCycles] sub edx,ecx mov eax,edx %ifdef SPC2MHz %if %1 != 2 mov dl,0 %else and edx,~31 %endif %else %if %1 != 2 and edx,~127 %else and edx,~15 %endif %endif add ecx,edx mov dx,[_SPC_T%1_target] %ifdef SPC2MHz %if %1 != 2 shr eax,8 %else shr eax,5 %endif %else %if %1 != 2 shr eax,7 %else shr eax,4 %endif %endif add ax,[_SPC_T%1_position] mov [_SPC_T%1_position],ax mov [_SPC_T%1_cycle_latch],ecx cmp ax,dx jb %%done mov ecx,edx xor dx,dx div cx add al,[_SPC_T%1_counter] and al,15 mov [_SPC_T%1_counter],al mov [_SPC_T%1_position],dx %%done: %endmacro ;%1 = SaveCycles %macro Execute_SPC 0-1 0 pusha %ifidni %1,SaveCycles cmp byte [In_CPU],0 jz %%not_in_cpu ;GET_CYCLES eax mov eax,[_EventTrip] add dword eax,R_65c816_Cycles jmp %%got_cycles %%not_in_cpu: mov eax,[_SNES_Cycles] %%got_cycles: cmp eax,CYCLES_REFRESH_START jb %%before_refresh add eax,byte CYCLES_IN_REFRESH %%before_refresh: ; Update CPU and SPC cycles mov edi,[SPC_last_cycles] mov [SPC_last_cycles],eax sub eax,edi add eax,[SPC_CPU_cycles] %endif %if 0 SPC runs at 2048000 clock. NTSC 65c816 timing. Masterclock: 21.477272..MHz. (189e7 / 88 Hz) Dotclock: 5.36931818..MHz. Optimal conversion factors: 118125:11264 Line rate: 15.6997607655502~KHz. Frame rate: 59.92275~Hz. PAL 65c816 timing. Masterclock: 21.28137MHz. Dotclock: 5.3203425MHz. Line rate: 15.55655701~KHz. Frame rate: 49.86075967~Hz. %endif %ifdef SPC_CYCLES_DIV_BEFORE_MUL xor edx,edx mov edi,[_SPC_CPU_cycle_divisor] div edi mov edi,[_SPC_CPU_cycle_multiplicand] mov [SPC_CPU_cycles],edx ; Save remainder mul edi %else mov edi,[_SPC_CPU_cycle_multiplicand] mul edi mov edi,[_SPC_CPU_cycle_divisor] add eax,[SPC_CPU_cycles_mul] adc edx,byte 0 div edi xor edi,edi mov [SPC_CPU_cycles_mul],edx ; Save remainder mov [SPC_CPU_cycles],edi %endif add eax,[_SPC_Cycles] ; Add new balance of SPC cycles mov [_SPC_Cycles],eax cmp [_TotalCycles],eax jb %%need_execute ; Check for and handle 35-minute wrap test eax,eax js %%no_cycles cmp dword [_TotalCycles],byte 0 jns %%no_cycles call _Wrap_SPC_Cyclecounter %%need_execute: call _SPC_START %%no_cycles: popa %endmacro %endif ; SNEeSe_SPC_i