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