📄 sacmv40.asm
字号:
// Return : None
////////////////////////////////////////////////////////
F_SP_SACM_MS01_Init_:
FIR_MOV OFF;
R1 = C_SystemClock; // CPU Clock setting
[P_SystemClock] = R1;
R1 = 0X0030; // TimerA CKA=Fosc/2 CKB=1 Tout:off
[P_TimerA_Ctrl] = R1;
R1= C_MS01_Timer_Setting; // TimerA setting
[P_TimerA_Data] = R1;
// R1 = 0X0000; // TimerB CKC=Fosc/2 Tout:off
// [P_TimerB_Ctrl] = R1;
// R1= C_MS01_Timer_Setting; // TimerB setting
// [P_TimerB_Data] = R1;
R1 = 0x00AC // Latch DAC1 by TimerA; Latch DAC2 by TimerA; MIC_IN conversion by TimerA
// R1 = 0x00CC // Latch DAC1 by TimerA; Latch DAC2 by TimerB; MIC_IN conversion by TimerA
// R1 = 0x012C // Latch DAC1 by TimerB; Latch DAC2 by TimerA; MIC_IN conversion by TimerA
// R1 = 0x014C // Latch DAC1 by TimerB; Latch DAC2 by TimerB; MIC_IN conversion by TimerA
[P_DAC_Ctrl] = R1 // b2 of P_DAC_Ctrl must be set to 1 in SPCE500A. SPCE060A doesn't use this bit
R1 = 0xffff; // no need to clear FIQ here by arthur
[P_INT_Clear] = R1;
R1 = [R_InterruptStatus] //
R1 |= C_FIQ_TMA // Enable Timer A FIQ
// R1 |= C_FIQ_TMB // Enable Timer B FIQ
[R_InterruptStatus] = R1 //
[P_INT_Ctrl] = R1 //
fiq on;
retf
////////////////////////////////////////////////////////
// Function: F_SP_SACM_DVR1600_Init_
// Description: Hardware initilazation, System Clock, DAC, INT
//
// Syntax : F_SP_SACM_Init_
// Destory: R1
// Parameter : None
// Return : None
////////////////////////////////////////////////////////
// call by decode.asm to initilaize the hardware for decode
F_SP_SACM_DVR1600_Init_:
FIR_MOV OFF;
R1 = C_SystemClock; // CPU Clock setting
[P_SystemClock] = R1;
R1 = 0X0030; // TimerA CKA=Fosc/2 CKB=1 Tout:off
[P_TimerA_Ctrl] = R1;
R1= C_DVR1600_Timer_Setting; // TimerA setting
[P_TimerA_Data] = R1;
// R1 = 0X0000; // TimerB CKC=Fosc/2 Tout:off
// [P_TimerB_Ctrl] = R1;
// R1= C_DVR1600_Timer_Setting; // TimerB setting
// [P_TimerB_Data] = R1;
R1 = 0x00AC // Latch DAC1 by TimerA; Latch DAC2 by TimerA; MIC_IN conversion by TimerA
// R1 = 0x00CC // Latch DAC1 by TimerA; Latch DAC2 by TimerB; MIC_IN conversion by TimerA
// R1 = 0x012C // Latch DAC1 by TimerB; Latch DAC2 by TimerA; MIC_IN conversion by TimerA
// R1 = 0x014C // Latch DAC1 by TimerB; Latch DAC2 by TimerB; MIC_IN conversion by TimerA
[P_DAC_Ctrl] = R1 // b2 of P_DAC_Ctrl must be set to 1 in SPCE500A. SPCE060A doesn't use this bit
r1 = 0x0115; // 061A: AGC enable; MIC IN; ADC enable
[P_ADC_Ctrl] = r1;
R1 = 0xffff; // no need to clear FIQ here by arthur
[P_INT_Clear] = R1;
R1=0x0000 // Mic_In
// R1 = 0x0001 // Line_in 1
[P_ADC_MUX_Ctrl] = R1
R1 = [R_InterruptStatus] //
R1 = [P_INT_Mask] //
R1 |= C_FIQ_TMA // Enable Timer A FIQ
// R1 |= C_FIQ_TMB // Enable Timer B FIQ
[R_InterruptStatus] = R1 //
[P_INT_Ctrl] = R1 //
FIQ on;
IRQ on;
retf
////////////////////////////////////////////////////////
// Function: _SP_SACM_DVR1600_ADC_Timer_Init_
// Description: Select A1600_Rec ADC Sampling Rate
// called by library
//
// Destory: R1
// Parameter : None
// Return : None
////////////////////////////////////////////////////////
_SP_SACM_DVR1600_ADC_Timer_Init_:
F_SP_SACM_DVR1600_ADC_Timer_Init_:
push r1 to [sp];
R1 = C_DVR1600_ADC_Timer_Setting;
[P_TimerA_Data] = R1;
pop r1 from [sp];
retf;
////////////////////////////////////////////////////////
// Function: _SP_SACM_DVR1600_DAC_Timer_Init_
// Description: Select A1600_Play DAC Sampling Rate,
// called by library
//
// Destory: R1
// Parameter : None
// Return : None
////////////////////////////////////////////////////////
_SP_SACM_DVR1600_DAC_Timer_Init_:
F_SP_SACM_DVR1600_DAC_Timer_Init_:
push r1 to [sp];
R1 = C_DVR1600_DAC_Timer_Setting;
[P_TimerA_Data] = R1;
pop r1 from [sp];
retf;
////////////////////////////////////////////////////////
// Function: _SP_SACM_DVR1600_ADC_TimerDiv2_Init_
// Description: Select A1600_Rec ADC Sampling Rate
// called by library
//
// Destory: R1
// Parameter : None
// Return : None
////////////////////////////////////////////////////////
_SP_SACM_DVR1600_ADC_TimerDiv2_Init_:
F_SP_SACM_DVR1600_ADC_TimerDiv2_Init_:
push r1 to [sp];
R1 = 0xFFFF;
R1 -= C_DVR1600_ADC_Timer_Setting;
R1 = R1 LSL 1;
R1 =-R1;
R1 += 0xFFFF;
[P_TimerA_Data] = R1;
pop r1 from [sp];
retf;
////////////////////////////////////////////////////////
// Function: _SP_SACM_DVR1600_DAC_TimerDiv2_Init_
// Description: Select A1600_Play DAC Sampling Rate,
// called by library
//
// Destory: R1
// Parameter : None
// Return : None
////////////////////////////////////////////////////////
_SP_SACM_DVR1600_DAC_TimerDiv2_Init_:
F_SP_SACM_DVR1600_DAC_TimerDiv2_Init_:
push r1 to [sp];
R1 = 0xFFFF;
R1 -= C_DVR1600_DAC_Timer_Setting;
R1 = R1 LSL 1;
R1 =-R1;
R1 += 0xFFFF;
[P_TimerA_Data] = R1;
pop r1 from [sp];
retf;
//--------------------------------------------------------------------
//-- Function: F_SACM_DVR1600_GetADC
//-- Parameter: N/A
//-- Return: R1 = ADC data
//-- Description: This function called by library to get
// ADC data for recording. It can be from either Microphone
// or line-in.
// User would have to modified the function body
// based on the need to fulfill this request from
// library.
// User should store the value in register(R2-R5)if use them.
//--------------------------------------------------------------------
F_SACM_DVR1600_GetADC:
R1 = [R_ADC_Channel];
cmp R1,0;
jnz ?L_WaitLinIn;
//For Mic
?L_Mic:
r1 = [P_ADC] // from 500A/061A microphone or 500A Lin-in
retf
// For Line in
?L_WaitLinIn: // Wait for ADC ready
.if BODY_TYPE == SPCE500A
r1 = [P_ADC] ; // from 500A/061A microphone or 500A Lin-in
.endif
.if BODY_TYPE == SPCE061A
R1 = [P_ADC_MUX_Ctrl]
R1 &= 0x8000
jz ?L_WaitLinIn;
r1 = [P_ADC_LINEIN_Data] // from 061A line-in only
.endif
retf
//---------------------------------------------------------------
//Function : _SP_SwitchChannel
//Description: This function switches the A/D channel based on
// the parameter.
//Used register: r1
//Return: none
//---------------------------------------------------------------
_SP_SwitchChannel: .proc
push BP to [SP];
BP = SP + 1;
R1 = [BP + 3]; //RceMonitorOff
call F_SP_SwitchChannel;
pop BP from [SP];
retf
.ENDP
//---------------------------------------------------------------
//Function : F_SP_SwitchChannel
//Description: This function switches the A/D channel based on
// the parameter.
//Used register: r1
//Return: none
//---------------------------------------------------------------
F_SP_SwitchChannel:
push R2 to [sp]
[R_ADC_Channel] = R1;
//
// SPCE500A Setting
//
.if BODY_TYPE == SPCE500A
// Check if microphone selected
cmp R1,0;
jnz ?L_LineIn;
// Wait for ADC ready
?L_Wait_AD_ready_0:
R1=0x0015; // 500A: MIC IN, Auto,AGC,Enable ADC
[P_ADC_Ctrl] = r1;
jmp ?L_Done;
// Wait for ADC ready
?L_LineIn:
R1=0x0013; // 500A: LINE IN, Auto,Enable ADC
[P_ADC_Ctrl] = r1;
?L_Done:
.endif
//
// SPCE500A Setting
//
.if BODY_TYPE == SPCE061A
// Check if microphone selected
cmp R1,0;
jnz ?L_LineIn;
// Wait for ADC ready
?L_Wait_AD_ready_0:
r2 = [P_ADC_Status];
r2 = r2 & 0x8000;
jz ?L_Wait_AD_ready_0
r2 = 0x0115; // 061A: Mic, Enable ADC
[P_ADC_Ctrl] = r2;
[P_ADC_MUX_Ctrl] = R1; // Switch channel to Mic
R2 = [P_ADC]
jmp ?L_Done;
// Wait for ADC ready
?L_LineIn:
?L_Wait_AD_ready_1:
r2 = [P_ADC_Status];
r2 = r2 & 0x8000;
jz ?L_Wait_AD_ready_1
r2 = 0x0103; // 061A: LINE IN, Enable ADC
[P_ADC_Ctrl] = r2;
[P_ADC_MUX_Ctrl] = R1; // Switch channel to Line_in
R2 = [P_ADC_LINEIN_Data];
?L_Done:
.endif
pop R2 from [sp];
retf;
////////////////////////////////////////////////////////
// Function: F_SP_RampDnDAC1
// Description: Ramp down after using DAC to avoid "bow" sound
// from speaker
// Syntax : F_SP_RampDnDAC1
// Destory: R1
////////////////////////////////////////////////////////
_SP_RampDnDAC1: .PROC
F_SP_RampDnDAC1:
push R1 to [SP];
R1 = [P_DAC1];
R1 &= 0xffc0;
jz ?_Branch_0;
?_Loop_0:
call F_SACM_Delay;
R1 -= 0x0040;
[P_DAC1] = R1;
jnz ?_Loop_0;
?_Branch_0:
pop R1 from [SP];
retf;
.ENDP
////////////////////////////////////////////////////////
// Function: F_SP_RampDnDAC2
// Description: Ramp down after using DAC to avoid "bow" sound
// from speaker
// Syntax : F_SP_RampDnDAC2
// Destory: R1
////////////////////////////////////////////////////////
_SP_RampDnDAC2: .PROC
F_SP_RampDnDAC2:
push R1 to [SP];
R1 = [P_DAC2];
R1 &= 0xffc0;
jz ?_Branch_0;
?_Loop_0:
call F_SACM_Delay;
R1 -= 0x0040;
[P_DAC2] = R1;
jnz ?_Loop_0;
?_Branch_0:
pop R1 from [SP];
retf
.ENDP
////////////////////////////////////////////////////////
// Function: F_SP_RampUpDAC1
// Description: Ramp Up before using DAC to avoid "bow" sound
// from speaker
// Syntax : F_SP_RampUpDAC1()
// Destory: R1
////////////////////////////////////////////////////////
_SP_RampUpDAC1: .PROC
F_SP_RampUpDAC1:
push R1 to [SP];
R1 = [P_DAC1];
R1 &= 0xffc0;
cmp R1, 0x8000;
jb ?_Loop_0;
je ?_Branch_0;
?_Loop_1:
call F_SACM_Delay;
R1 -= 0x0040;
[P_DAC1] = R1;
cmp R1, 0x8000;
jne ?_Loop_1;
jmp ?_Branch_0;
?_Loop_0:
call F_SACM_Delay;
R1 += 0x0040;
[P_DAC1] = R1;
cmp R1, 0x8000;
jne ?_Loop_0;
?_Branch_0:
pop R1 from [SP];
retf;
.ENDP
////////////////////////////////////////////////////////
// Function: F_SP_RampUpDAC2
// Description: Ramp Up before using DAC to avoid "bow" sound
// from speaker
// Syntax : F_SP_RampUpDAC2()
// Destory: R1
////////////////////////////////////////////////////////
_SP_RampUpDAC2: .PROC
F_SP_RampUpDAC2:
push R1 to [SP];
R1 = [P_DAC2];
R1 &= 0xffc0;
cmp R1, 0x8000;
jb ?_Loop_0;
je ?_Branch_0;
?_Loop_1:
call F_SACM_Delay;
R1 -= 0x0040;
[P_DAC2] = R1;
cmp R1, 0x8000;
jne ?_Loop_1;
jmp ?_Branch_0;
?_Loop_0:
call F_SACM_Delay;
R1 += 0x0040;
[P_DAC2] = R1;
cmp R1, 0x8000;
jne ?_Loop_0;
?_Branch_0:
pop R1 from [SP];
retf;
.ENDP
//.if 0
//-------------------------------------------------------
// Function: F_SACM_Delay
// Description: Provide delay for Ramp up/down
// The delay time is adjustable by adjusting C_SACM_RAMP_DELAY
// Destory: R1
//-------------------------------------------------------
F_SACM_Delay: .proc
push R1 to [SP];
R1 = C_SACM_RAMP_DELAY; // Ramp Up/Dn delay per step
?_Loop_0:
R1 -= 0x0001;
jnz ?_Loop_0;
pop R1 from [SP];
retf;
.endp
//.endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -