📄 pcm_pcm.s
字号:
/************************************************************************/
// (c)1996 Copyright M-Pact, Inc. All rights reserved
//
// Revision 1.0
//
//
// Module: PCM_OUT (PCM output routine)
//
// Initial version: Jinshi Huang 3/17/97
//
// Calling : none
// Called by: top level
// Return: r27, LBPCM_flag
// Param in:
// Temp reg:
// AGR reg:
// Local buffer:
//************************************************************************
.nolist
#include "regdef2.h"
#ifndef EFFECT
#include "ac3_com.h"
#endif //EFFECT
#include "user.h"
#include "memory2.h"
#include "globalv.h"
#ifdef EFFECT
#include "stereo_user.h"
#endif //EFFECT
#ifdef MSW_SAVE_LOCAL
#include "qx.h"
#endif
.data
.list
.extern disp_spectrum
.extern PCM_Config_Word
.extern cs_done_flag
.extern SUB_CS_DEC
#ifdef MSW_ADD_QSOUND
.extern SUB_QXpander
.extern QSOUND_CMD_BUF
#endif // MSW_ADD_QSOUND
.globl SUB_pcm_pcm
SUB_pcm_pcm:
dlb r18, cs_done_flag
nop
tsti r18, CS_DISABLED
beq CSProcessingDone
tsti r18, CS_ENABLED
bne CSProcessingDone
movi r18, CS_PROCESSED
dsb r18, cs_done_flag
#if 0
//===STC=====STC====================Testing
rlwi r18, STC //DBG
nop
nop
dsw r18, 0xff04 //DBG
//===STC=====STC====================
#endif
movw LWSRSentry, r10
jsr r29, SUB_CS_DEC
#if 0
//===STC====STC=====================Testing
rlwi r18, STC // DBG
dlw r12, 0xff04 // DBG
dlw r10, 0xff08
sub r18, r12 // DBG
tst r18, r10
blte cs_stc_done
dsw r18, 0xff08
cs_stc_done:
//===STC====STC=====================
#endif
CSProcessingDone:
dlw r10, FIFO_BLK_PTR
movi r8, PCM_FIFO_0_START // beginning of FIFO_0
movi r9, PCM_FIFO_0_END // to the end of FIFO being read
tsti r10, PCM_FIFO_0_START
beq toggle_ref_ptr
movi r8, PCM_FIFO_1_START // beginning of FIFO_1
movi r9, PCM_FIFO_1_END // end of FIFO_1
toggle_ref_ptr:
//// read location of read fifo
pcmout_wait:
1:
rlwi r1, PCM_Rd_Ptr // read current pointer register (28c)
rlwi r3, PCM_Rd_Ptr // read current pointer register (28c)
tst r1,r3
bne 1b
andi r1,0xffff
tst r1, r8
blt write_to_FIFO
tst r1, r9 //
// blte pcm_not_out // if begin <= ptr <= end, wait
// j write_to_FIFO
bgt write_to_FIFO
delay_loop_start:
loop 64,delay_loop
nop
nop
nop
nop
delay_loop:
rlwi r1, PCM_Rd_Ptr // read current pointer register (28c)
rlwi r3, PCM_Rd_Ptr // read current pointer register (28c)
tst r1,r3
bne delay_loop
sub r3,r9,r1
tsti r3,24 // 3 dWords/sample
bgt delay_loop_start
j pcm_not_out
/**********************************************************************/
// this code should be moved to the kernel later !!!!!
// write to the FIFO
//====write 256 words to main memory. pcmptr2 += offset
//this is modified to write 16-bit format of 6 channels to
//0 - 0x3000 of the DRAM which is the PCM output FIFO.
no_checking_FIFO:
tsti r4, 0
bne second_FIFO_block
////// set the size of the PCM output FIFO for 2 blocks
movi r1, PCM_FIFO_SIZE // size of PCM output FIFO
movi r10, PCM_FIFO_0_START
j write_to_FIFO
second_FIFO_block:
movi r1, 1
movb LBFIFO_flag,r1
movi r10, PCM_FIFO_1_START
write_to_FIFO:
// always check PTS (r4=???)
// tsti r4,0
// bne Lskip_PTS
jsr r28,SUB_check_PTS
Lskip_PTS:
//***************************************************************
// 6 Channels SRS for both I2S and non I2S *
// I/P data: 0x1000 to 0x1c00 *
// Draft area: 0x1900 to 0x1f00 (last 1/4) *
// 0x1600 to 0x1c00 (3rd 1/4) *
// 0x1300 to 0x1900 (2nd 1/4) *
// 0x1000 to 0x1600 (first 1/4) *
//***************************************************************
dlb r2, cs_done_flag
movi r1, CS_ENABLED
tsti r2, CS_DISABLED
beq do_regular_PCM_DMA
tsti r2, CS_PROCESSED
dsb r1, cs_done_flag
bne do_regular_PCM_DMA
movi StartAddrHigh,DataSeg
movi BlockSkip, 0
movi BlockSize, 0 //block size = 1
movi AGRSiz0, 0xffff
movi AGRSiz1, 0xffff
rlwi r8, PCM_Out_Ctrl
andi r8, 0x0080
//***************************************************************
// First deal with last 1/4 *
//***************************************************************
movi AGRAdr0, local_FApcm_buf_byte + 0xc00 - 4 //bottom up
movi AGRAdr1, SP6_draft_before_dram_byte - 4
tsti r8, 0
bne 3f
// For non-I2S Right justify
loop 192, pcm6_right_justify_on_last
mov r1, a0(0*4) // 64 *3 Low Half
shr r2, a0(-1*4),16 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_right_justify_on_last:
j pcm6_center_justify_on_last
3:
// For I2S Center justify
loop 192, pcm6_center_justify_on_last
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 8 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_center_justify_on_last:
movi r3, 0x640 //(word)0x640=(byte)0x1900
shr r9, r10, 2
addi r9,0x180 * 3 //begin from last beginner word
loop 12, write_last_quarter //total of 384 words/64 samples
mov LocalAddr, r3
dmawr r9
WaitDma
addi r3, 32 //32 words each block
addi r9, 32
write_last_quarter:
//***************************************************************
// Then deal with the last second quarter *
//***************************************************************
movi AGRAdr0, local_FApcm_buf_byte + 0xc00 - 0x300-4 //bottom up
movi AGRAdr1, SP6_draft_before_dram_byte -0x300 - 4
tsti r8, 0
bne 3f
// For non-I2S Right justify
loop 192, pcm6_right_justify_on_last_second
mov r1, a0(0*4) // 64 *3 Low Half
shr r2, a0(-1*4),16 // High Half
mov a1(-1*4), r2
mov a1(-1*4), r1
pcm6_right_justify_on_last_second:
j pcm6_center_justify_on_last_second
3:
// For I2S Center justify
loop 192, pcm6_center_justify_on_last_second
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 8 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_center_justify_on_last_second:
movi r3, 0x580 //(word)0x580=(byte)0x1600
shr r9, r10, 2
addi r9,0x180 * 2 //begin from last second beginner word
loop 12, write_last__second_quarter //total of 384 words/64 samples
mov LocalAddr, r3
dmawr r9
WaitDma
addi r3, 32 //32 words each block
addi r9, 32
write_last__second_quarter:
//***************************************************************
// Then deal with the second *
//***************************************************************
movi AGRAdr0, local_FApcm_buf_byte + 0xc00 - 0x600-4 //bottom up
movi AGRAdr1, SP6_draft_before_dram_byte -0x600 - 4
tsti r8, 0
bne 3f
// For non-I2S Right justify
loop 192, pcm6_right_justify_on_second
mov r1, a0(0*4) // 64 *3 Low Half
shr r2, a0(-1*4),16 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_right_justify_on_second:
j pcm6_center_justify_on_second
3:
// For I2S Center justify
loop 192, pcm6_center_justify_on_second
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 8 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_center_justify_on_second:
movi r3, 0x4c0 //(word)0x4c0=(byte)0x1300
shr r9, r10, 2
addi r9,0x180 //begin from second beginner word
loop 12, write__second_quarter //total of 384 words/64 samples
mov LocalAddr, r3
dmawr r9
WaitDma
addi r3, 32 //32 words each block
addi r9, 32
write__second_quarter:
//***************************************************************
// Then deal with the first *
//***************************************************************
movi AGRAdr0, local_FApcm_buf_byte + 0xc00 - 0x900-4 //bottom up
movi AGRAdr1, SP6_draft_before_dram_byte -0x900 - 4
tsti r8, 0
bne 3f
// For non-I2S Right justify
loop 192, pcm6_right_justify_on_first
mov r1, a0(0*4) // 64 *3 Low Half
shr r2, a0(-1*4),16 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_right_justify_on_first:
j pcm6_center_justify_on_first
3:
// For I2S Center justify
loop 192, pcm6_center_justify_on_first
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 8 // High Half
mov a1(-1*4), r1
mov a1(-1*4), r2
pcm6_center_justify_on_first:
movi r3, 0x400 //(word)0x400=(byte)0x1000
shr r9, r10, 2 //begin from first beginner word
loop 12, write_first_quarter //total of 384 words/64 samples
mov LocalAddr, r3
dmawr r9
WaitDma
addi r3, 32 //32 words each block
addi r9, 32
write_first_quarter:
j merge_pcm_spdif
do_regular_PCM_DMA:
//////===== End of SRS 6 Channel Data =====================
#ifdef EFFECT
// copy data to local buffer
movi StartAddrHigh,DataSeg //to second segment
movi DMASize,31
movi r12,local_FApcm_buf_word
movi r11,keyshift_context
shr r11,2
loop 8, get_keyshift_output //total of 8*32 words
mov LocalAddr, r12
dmarr r11
Lwait3: bdb Lwait3
addi r12, 32 //32 words each block
addi r11, 32
get_keyshift_output:
movi StartAddrHigh,MEM_SEG //back to first segment
#endif //EFFECT
// get the gain value by combining stream gain with user gain
dlw r20, USER_OCFG
mupi r0, OCFG_X_MASK_HI
and r1, r20, r0
shr r1, OCFG_X_SHIFT //r1=X
mupi r0, OCFG_Y_MASK_HI
and r2, r20, r0
shr r2, OCFG_Y_SHIFT //r2=Y
mupi r3, 0x007f
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -