📄 sacmv32.asm
字号:
//============================================================
// 文件名称:sacmV32.asm
// 实现功能:对A3200、A2000、A1600、S530、S480、S240、MS01、DVR等格式的初始化、初始化队列
// 读写队列、声音高低的调节等函数
// 日期: 2003/6/16
//============================================================
.include spce.inc
//== User definition =====================
.define C_RampDelay 80
//---<< System Clock Setting >>----------------------
// Note: Please refer to spce.inc for BODY_TYPE definition.
// This setting affects the validity of C_SystemClock.
//
.define C_SystemClock C_Fosc_49M
//.define C_SystemClock C_Fosc
//----<< Timer definition >>------------------------
.define C_Timer_Setting_8K_For_24MHz 0xF9FF
.define C_Timer_Setting_9K_For_24MHz 0xFAAA
.define C_Timer_Setting_10K_For_24MHz 0xFB33
.define C_Timer_Setting_11K_For_24MHz 0xFBA2
.define C_Timer_Setting_12K_For_24MHz 0xFBFF
.define C_Timer_Setting_16K_For_24MHz 0xFCFF
.define C_Timer_Setting_20K_For_24MHz 0xFD98
.define C_Timer_Setting_24K_For_24MHz 0xFDFF
.define C_Timer_Setting_8K_For_49MHz 0xF3FF
.define C_Timer_Setting_9K_For_49MHz 0xF555
.define C_Timer_Setting_10K_For_49MHz 0xF666
.define C_Timer_Setting_11K_For_49MHz 0xF745
.define C_Timer_Setting_12K_For_49MHz 0xF7FF
.define C_Timer_Setting_16K_For_49MHz 0xF9FF
.define C_Timer_Setting_20K_For_49MHz 0xFB33
.define C_Timer_Setting_24K_For_49MHz 0xFBFF
//---<< Timer setting >>
.define C_S200_Timer_Setting C_Timer_Setting_16K_For_49MHz
.define C_S240_Timer_Setting C_Timer_Setting_20K_For_49MHz
.define C_S480_Timer_Setting C_Timer_Setting_16K_For_49MHz
.define C_S530_Timer_Setting C_Timer_Setting_12K_For_49MHz
.define C_A1600_Timer_Setting C_Timer_Setting_16K_For_49MHz
.define C_A2000_Timer_Setting C_Timer_Setting_16K_For_49MHz
.define C_DVR_Timer_Setting C_Timer_Setting_8K_For_49MHz
.define C_DVR_Rec_Timer_Setting C_Timer_Setting_24K_For_49MHz
.define C_DVR_Play_Timer_Setting C_Timer_Setting_16K_For_49MHz
// For A3200 Timer setting , please go to F_SP_SACM_A3200_Init_,
// F_SP_SACM_2Ch_A3200_Init_
// it is determined by library internally.
// For Ms01 Timer setting , please go to F_SP_SACM_MS01_Init_
//-------------------------------------------------
//==================================================
.PUBLIC F_SP_RampUpDAC1
.PUBLIC F_SP_RampDnDAC1
.PUBLIC F_SP_RampUpDAC2
.PUBLIC F_SP_RampDnDAC2
.PUBLIC _SP_RampUpDAC1
.PUBLIC _SP_RampDnDAC1
.PUBLIC _SP_RampUpDAC2
.PUBLIC _SP_RampDnDAC2
.PUBLIC _SP_InitQueue
.PUBLIC _SP_InitQueue_A2000
.PUBLIC _SP_InitQueue_S530
.PUBLIC _SP_InitQueue_S480
.PUBLIC _SP_InitQueue_S240
.PUBLIC _SP_InitQueue_MS01
.PUBLIC _SP_InitQueue_DVR
.PUBLIC F_SP_InitQueue
.PUBLIC F_SP_InitQueue_A2000
.PUBLIC F_SP_InitQueue_S530
.PUBLIC F_SP_InitQueue_S480
.PUBLIC F_SP_InitQueue_S240
.PUBLIC F_SP_InitQueue_MS01
.PUBLIC F_SP_InitQueue_DVR
.PUBLIC F_SP_ReadQueue
.PUBLIC F_SP_ReadQueue_A2000
.PUBLIC F_SP_ReadQueue_S530
.PUBLIC F_SP_ReadQueue_S480
.PUBLIC F_SP_ReadQueue_S240
.PUBLIC F_SP_ReadQueue_MS01
.PUBLIC F_SP_ReadQueue_DVR
.PUBLIC F_SP_ReadQueue_NIC // Read Queue with no index change
.PUBLIC F_SP_ReadQueue_NIC_A2000
.PUBLIC F_SP_ReadQueue_NIC_S530
.PUBLIC F_SP_ReadQueue_NIC_S480
.PUBLIC F_SP_ReadQueue_NIC_S240
.PUBLIC F_SP_ReadQueue_NIC_MS01
.PUBLIC F_SP_ReadQueue_NIC_DVR
.PUBLIC F_SP_WriteQueue
.PUBLIC F_SP_WriteQueue_A2000
.PUBLIC F_SP_WriteQueue_S530
.PUBLIC F_SP_WriteQueue_S480
.PUBLIC F_SP_WriteQueue_S240
.PUBLIC F_SP_WriteQueue_MS01
.PUBLIC F_SP_WriteQueue_DVR
.PUBLIC F_SP_TestQueue
.PUBLIC F_SP_TestQueue_A2000
.PUBLIC F_SP_TestQueue_S530
.PUBLIC F_SP_TestQueue_S480
.PUBLIC F_SP_TestQueue_S240
.PUBLIC F_SP_TestQueue_MS01
.PUBLIC F_SP_TestQueue_DVR
.PUBLIC _SP_GetResource
.PUBLIC F_RampUpDAC1
.PUBLIC F_RampDnDAC1
.PUBLIC F_RampUpDAC2
.PUBLIC F_RampDnDAC2
.PUBLIC _STD_RampUpDAC1
.PUBLIC _STD_RampDnDAC1
.PUBLIC _STD_RampUpDAC2
.PUBLIC _STD_RampDnDAC2
/////////////////////////////////////////////////////////////////
// Note: This register map to the P_INT_Ctrl(0x7010)
// User's interrupt setting have to combine with this register
// while co-work with SACM library.
//
// See. following function for example:
// F_SP_SACM_A2000_Init_:
// F_SP_SACM_S480_Init_:
// F_SP_SACM_S240_Init_:
// F_SP_SACM_MS01_Init_:
// F_SP_SACM_DVR_Init_:
//////////////////////////////////////////////////
//.external R_InterruptStatus // declared in spce.asm
//////////////////////////////////////////////////
.define C_QueueSize 50
.RAM
.VAR R_Queue
.DW C_QueueSize-1 DUP(0)
.VAR R_ReadIndex
.VAR R_WriteIndex
.CODE
//////////////////////////////////////////////////////
// Ramp Functions
//////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// Function: _SP_RampUpDAC1
// Description: Ramp Up before using DAC to avoid "bow" sound
// from speaker
// Syntax : SP_RampUpDAC1()
// Destory: R1,R2
////////////////////////////////////////////////////////
_SP_RampUpDAC1: .PROC
F_SP_RampUpDAC1:
push r1,r2 to [sp]
r1=[P_DAC1]
r1 &= ~0x003f
cmp r1,0x8000
jb L_RU_NormalUp
je L_RU_End
L_RU_DownLoop:
call F_Delay
r2 = 0x0001
[P_Watchdog_Clear] = r2
r1 -= 0x40
[P_DAC1] = r1
cmp r1,0x8000
jne L_RU_DownLoop
L_RD_DownEnd:
jmp L_RU_End
L_RU_NormalUp:
L_RU_Loop:
call F_Delay
r2 = 0x0001
[P_Watchdog_Clear] = r2
r1 += 0x40
[P_DAC1] = r1
cmp r1, 0x8000
jne L_RU_Loop
L_RU_End:
pop r1,r2 from [sp]
retf
.ENDP
////////////////////////////////////////////////////////
// Function: _SP_RampDnDAC1
// Description: Ramp down after using DAC to avoid "bow" sound
// from speaker
// Syntax : SP_RampDnDAC1()
// Destory: R1,R2
////////////////////////////////////////////////////////
_SP_RampDnDAC1: .PROC
F_SP_RampDnDAC1:
push r1,r2 to [sp]
//int off
r1 = [P_DAC1]
r1 &= ~0x003F
jz L_RD_End
L_RD_Loop:
call F_Delay
r2 = 0x0001
[P_Watchdog_Clear] = r2
r1 -= 0x40
[P_DAC1] = r1
jnz L_RD_Loop
L_RD_End:
pop r1,r2 from [sp]
retf
.ENDP
////////////////////////////////////////////////////////
// Function: _SP_RampUpDAC2
// Description: Ramp Up before using DAC to avoid "bow" sound
// from speaker
// Syntax : SP_RampUpDAC2()
// Destory: R1,R2
////////////////////////////////////////////////////////
_SP_RampUpDAC2: .PROC
F_SP_RampUpDAC2:
push r1,r2 to [sp]
r1=[P_DAC2]
r1 &= ~0x003f
cmp r1,0x8000
jb L_RU_NormalUp_
je L_RU_End
L_RU_DownLoop_:
call F_Delay
r2 = 0x0001
[P_Watchdog_Clear] = r2
r1 -= 0x40
[P_DAC2] = r1
cmp r1,0x8000
jne L_RU_DownLoop_
L_RD_DownEnd_:
jmp L_RU_End_
L_RU_NormalUp_:
L_RU_Loop_:
call F_Delay
r2 = 0x0001
[P_Watchdog_Clear] = r2
r1 += 0x40
[P_DAC2] = r1
cmp r1, 0x8000
jne L_RU_Loop_
L_RU_End_:
pop r1,r2 from [sp]
retf
.ENDP
////////////////////////////////////////////////////////
// Function: _SP_RampDnDAC2
// Description: Ramp down after using DAC to avoid "bow" sound
// from speaker
// Syntax : SP_RampDnDAC2()
// Destory: R1,R2
////////////////////////////////////////////////////////
_SP_RampDnDAC2: .PROC
F_SP_RampDnDAC2:
//int off
push r1,r2 to [sp]
r1 = [P_DAC2]
r1 &= ~0x003F
jz L_RD_End_
L_RD_Loop_:
call F_Delay
r2 = 0x0001
[P_Watchdog_Clear] = r2
r1 -= 0x40
[P_DAC2] = r1
jnz L_RD_Loop_
L_RD_End_:
pop r1,r2 from [sp]
retf
.ENDP
//-------------------------------------------------------
// Function: F_Delay
// Description: Provide delay for Ramp up/down
// The delay time is adjustable by adjusting C_RampDelay
// Destory: R1
//-------------------------------------------------------
F_Delay:
push r1 to [sp]
r1 = C_RampDelay; // Ramp Up/Dn delay per step
L_D_Loop:
r1 -= 1
jnz L_D_Loop
pop r1 from [sp]
RETF
//////////////////////////////////////////////////////
// Queue Functions
//////////////////////////////////////////////////////
////////////////////////////////////////////////////////
// Function: _SP_InitQueue
// Description: Initiate queue for algorism use
// Syntax : SP_InitQueue()
// Destory: R1
////////////////////////////////////////////////////////
_SP_InitQueue: .PROC
_SP_InitQueue_A2000:
_SP_InitQueue_S530:
_SP_InitQueue_S480:
_SP_InitQueue_S240:
_SP_InitQueue_MS01:
_SP_InitQueue_DVR:
F_SP_InitQueue_A2000:
F_SP_InitQueue_S530:
F_SP_InitQueue_S480:
F_SP_InitQueue_S240:
F_SP_InitQueue_MS01:
F_SP_InitQueue_DVR:
F_SP_InitQueue:
R1 = R_Queue
R2 = 0
?L_ClearQueueLoop:
[R1++] = R2
cmp R1, R_Queue+C_QueueSize
jne ?L_ClearQueueLoop
R1 = 0
[R_ReadIndex] = R1
[R_WriteIndex] = R1
RETF
.ENDP
//-------------------------------------------------------
// Function: F_SP_ReadQueue_Xnnn
// Description Get a data form Queue
// Output: R1: Data read
// Destory: R1,R2
//-------------------------------------------------------
F_SP_ReadQueue_A2000:
F_SP_ReadQueue_S530:
F_SP_ReadQueue_S480:
F_SP_ReadQueue_S240:
F_SP_ReadQueue_MS01:
F_SP_ReadQueue_DVR:
F_SP_ReadQueue:
R2 = [R_ReadIndex]
cmp R2,[R_WriteIndex]
je L_RQ_QueueEmpty
R2 += R_Queue // get queue data address
R1 = [R2]
R2 = [R_ReadIndex]
R2 += 1
cmp R2, C_QueueSize
jne L_RQ_NotQueueBottom
R2 = 0
L_RQ_NotQueueBottom:
[R_ReadIndex] = R2
//r2 = 0x0000 // get queue data
retf
L_RQ_QueueEmpty:
//r2 = 0x8000 // queue empty
retf
//-------------------------------------------------------
// Function: F_SP_ReadQueue_NIC_Xnnn
// Description: Get a data from Queue but do
// not change queue index
// Output: R1: Data read
// Destory: R1,R2
//-------------------------------------------------------
F_SP_ReadQueue_NIC:
F_SP_ReadQueue_NIC_A2000:
F_SP_ReadQueue_NIC_S530:
F_SP_ReadQueue_NIC_S480:
F_SP_ReadQueue_NIC_S240:
F_SP_ReadQueue_NIC_MS01:
F_SP_ReadQueue_NIC_DVR:
R2 = [R_ReadIndex]
cmp R2,[R_WriteIndex]
je ?L_RQ_QueueEmpty
R2 += R_Queue // get queue data index
R1 = [R2]
?L_RQ_QueueEmpty:
RETF
//-------------------------------------------------------
// Function: F_SP_WriteQueue_Xnnn
// Description: Put a data to Queue
// Input : R1 Data to write
// Destory: R1,R2
//-------------------------------------------------------
F_SP_WriteQueue_A2000:
F_SP_WriteQueue_S530:
F_SP_WriteQueue_S480:
F_SP_WriteQueue_S240:
F_SP_WriteQueue_MS01:
F_SP_WriteQueue_DVR:
F_SP_WriteQueue:
R2 = [R_WriteIndex] // put data to queue
R2 += R_Queue
[R2] = R1
R2 = [R_WriteIndex]
R2 += 1
cmp R2, C_QueueSize
jne L_WQ_NotQueueBottom
R2 = 0
L_WQ_NotQueueBottom:
[R_WriteIndex] = R2
RETF
//-------------------------------------------------------
// Function: F_SP_ReadQueue_NIC_Xnnn
// Description: Test Queue Status
// Output: R1: queue status
// 0: not Full, not empty
// 1: full
// 2: empty
// Destory: R1
//-------------------------------------------------------
F_SP_TestQueue_A2000:
F_SP_TestQueue_S530:
F_SP_TestQueue_S480:
F_SP_TestQueue_S240:
F_SP_TestQueue_MS01:
F_SP_TestQueue_DVR:
F_SP_TestQueue:
//... Test Queue Empty ...
R1 = [R_ReadIndex]
cmp R1,[R_WriteIndex]
je L_TQ_QueueEmpty
//... Test Queue Full ...
R1 = [R_ReadIndex] // For N Queue Full: 1.R=0 and W=N-1 2. R<>0 and W=R-1
jnz L_TQ_JudgeCond2
R1 = [R_WriteIndex]
cmp R1, C_QueueSize-1 // Cond1
je L_TQ_QueueFull
L_TQ_JudgeCond2:
R1 = [R_ReadIndex]
R1 -=1
cmp R1,[R_WriteIndex]
je L_TQ_QueueFull
r1 = 0 // not Full, not empty
retf
L_TQ_QueueFull:
r1 = 1 // full
retf
L_TQ_QueueEmpty:
r1 = 2 // empty
retf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -