📄 pcm_dec.s
字号:
/************************************************************************/
; (c)1996 Copyright M-Pact, Inc. All rights reserved
;
; Revision 1.0
;
;
; Module: PCM_decoder (PCM decoder routine)
;
; Initial version: Jinshi Huang 8/27/97
;
; Calling : none
; Called by: top level
; Return: r31
; Param in:
; Temp reg:
; AGR reg:
; Local buffer:
;************************************************************************
.nolist
#include "regdef.h"
#include "globalv.h"
#include "user.h"
#include "stereo_user.h"
.list
.globl SUB_PCM_decoder
.extern BAblksize
.extern decimation2
.extern Deemphasis_coef
#if QSOUND
.extern filterCoeffs
.extern m48both
.extern m44both
#endif // QSOUND
SUB_PCM_decoder:
#if QSOUND
movh r0,LIstatus
andi r1,r0,SET_PROCESS_NEW
tsti r1,SET_PROCESS_NEW
bne configPLLdone
andi r0,RESET_PROCESS_OLD
movh LIstatus,r0
//---------------------------------------------------------------------
;;; Default filter coefficient is 44.1kHz.
;;; For 48kHz titles, coefficient needs to be loaded here.
mupi r4,MEM_SEG
ori r4,m48both
rlwi r1,Chip_Id
tsti r1,LS500_ID
bne configLs508
// li r1,PLL_DIV_48K_500
li r2,PLL_CTRL_48K_500
j checkPLL48kHz
configLs508:
// li r1,PLL_DIV_48K_508
li r2,PLL_CTRL_48K_508
checkPLL48kHz:
rlwi r0,PLL_Ctrl_Reg2
tst r0,r2
beq configPLL
// rlwi r0,PLL_Clk_Div_Reg
// tst r0,r1
// beq configPLL
mupi r4,MEM_SEG
ori r4,m44both
configPLL:
;;; update QExpander filter coefficient
mupi r3,MEM_SEG
ori r3,filterCoeffs
#if !THREE_STAGE
loop 9,configPLLdone
#else // !THREE_STAGE
loop 7,configPLLdone
#endif // !THREE_STAGE
dlwr r0,r4
addi r4,4
dswr r0,r3
addi r3,4
configPLLdone:
//---------------------------------------------------------------------
#endif // QSOUND
// set up parameters
dlw r20, USER_OCFG
#ifdef I2S
movi DMASize, 15 ;16 words each block
#else
movi DMASize, 31 ;32 words each block
#endif
movi BlockSkip, 0
movi BlockSize, 0 ;block size = 1.
// dlw r21, Stream_Rd_Ptr
LdStrRdPtr r21
dlw r23, Stream_End
andi r10, r20, OCFG_CHANNEL_MASK
shr r10, OCFG_CHANNEL_SHIFT
addi r10, 1 ; offset
mov r17, r10 ; as loop count
andi r24, r20, OCFG_SAMP_FREQ_MASK
shr r24, OCFG_SAMP_FREQ_SHIFT
tsti r24, 0
beq L48k
#if 1
andi r0, r20, OCFG_PCM_FREQ_MASK
#else
dlw r0,0xff00
nop
andi r0, OCFG_PCM_FREQ_MASK
#endif
tsti r0, 0 ; 0/1 - 48/96 kHz output
bne L48k
shl r17, 1 ; double if 96k
L48k:
andi r11, r20, OCFG_WORD_LEN_MASK
shr r11, OCFG_WORD_LEN_SHIFT
addi r12, r11, BAblksize
dlbr r13, r12
andi r22, r21, 0xffff ;lower 16-bit
shr r22, 2 ;to word addr
andi r23, 0xffff ;lower 16-bit
shr r23, 2 ;to word addr
movi AGRSiz0, 0xffff ; linear
movi AGRSiz1, 0xffff
movi AGRSiz2, 0xffff ; linear
movi AGRSiz3, 0xffff
mupi r15,0xff00
ori r15,0xff00 ; upper bytes
mupi r16,0x00ff
ori r16,0x00ff ; lower bytes
// start decoding
movi AGRAdr3, local_FApcm_buf_byte
// start channel loop ******************************************
movi r19, 0
movi r18, 0
Lchannel_loop_start:
// read in one channel data
movi r1, local_IBUF_word ; word addr
movi TrapReg,0
#if THREEPAGE
movi StartAddrHigh,MEM_SEG12
#else // THREEPAGE
movi StartAddrHigh,MEM_SEG
#endif // THREEPAGE
nop
nop
loop r13, block_loop
tst r22, r23
blt dma_blk_ok
subi r22, PCM_IBUF_SIZE/4 ;wrap in word addr
dma_blk_ok:
#if 1 //yyyy
mov LocalAddr, r1
dmarr r22
WaitDma
#endif
#ifdef I2S
addi r22, 16
addi r1, 16 ;16 words each block
#else
addi r22, 32
addi r1, 32 ;32 words each block
#endif
block_loop:
movi TrapReg,1<<2
#if THREEPAGE
movi StartAddrHigh,MEM_SEG
#endif // THREEPAGE
#if BYTESWAP
movi AGRAdr0, local_IBUF_byte
movi TrapReg,0
nop
nop
loop r13, byteswap_outer
#ifdef I2S
loop 16, byteswap_inner
#else
loop 32, byteswap_inner
#endif
and r3,r15,a0(0*4) ; upper bytes
and r4,r16,a0(0*4) ; lower bytes
shr r3, 8
shl r4, 8
or a0(1*4), r3, r4
byteswap_inner:
byteswap_outer:
movi TrapReg,1<<2
#endif // BYTESWAP
// bit alignment
movi AGRAdr0, local_IBUF_byte
movi AGRAdr1, local_mid_buf_byte
tsti r11, 0
beq L16_bit_case
tsti r11, 1
beq L20_bit_case
tsti r11, 2
beq L24_bit_case
L16_bit_case:
movi TrapReg,0
nop
nop
#ifdef I2S
loop 64, L16_bit_loop
#else
loop 128, L16_bit_loop
#endif
mov r3, a0(1*4)
mov a1(1*4), r3 ; L/U
L16_bit_loop:
movi TrapReg,1<<2
j PCM_gain_adjust
L20_bit_case:
mupi r6, 0xffff ; upper 16-bit
movi TrapReg,0
nop
nop
#ifdef I2S
loop 16, L20_bit_loop //160/5
#else
loop 32, L20_bit_loop //160/5
#endif
shr r3, a0(0*4), 4
andi r3, 0xffff //L
shr r4, a0(1*4), 8
shl r5, a0(0*4), 24
or r4, r5
and r4, r6 //U
or a1(1*4), r3, r4 //L/U
shr r3, a0(1*4), 12
andi r3, 0xffff //L
shl r4, a0(0*4), 16 //U
or a1(1*4), r3, r4 //L/U
shr r3, a0(1*4), 20
shl r4, a0(0*4), 12
or r3, r4
andi r3, 0xffff //L
shl r4, a0(0*4), 8
and r4, r6 //U
or a1(1*4), r3, r4 //L/U
shr r3, a0(1*4), 28
shl r4, a0(0*4), 4
or r3, r4
andi r3, 0xffff //L
and r4, r6, a0(1*4) //U
or a1(1*4), r3, r4 //L/U
L20_bit_loop:
movi TrapReg,1<<2
j PCM_gain_adjust
L24_bit_case:
mupi r6, 0xffff ; upper 16-bit
.if 0
loop 64, L24_bit_loop //192/3
shr r3, a0(1*4), 8
andi r3, 0xffff //L
shl r4, a0(0*4), 16 //U
or a1(1*4), r3, r4 //L/U
shr r3, a0(1*4), 24
shl r4, a0(0*4), 8
or r3, r4
andi r3, 0xffff //L
and r4, r6, a0(1*4) //U
or a1(1*4), r3, r4 //L/U
L24_bit_loop:
.endif
movi TrapReg,0
nop
nop
tsti r10,1
bne enter_L24_2ch
tsti r24,0
beq enter_L24_48k
enter_L24_2ch:
#ifdef I2S
loop 32, L24_bit_loop //96/3
#else
loop 64, L24_bit_loop //192/3
#endif
mov r3, a0(1*4)
mov a1(1*4), r3 ; L/U
mov r3, a0(2*4) ; skip third word
mov a1(1*4), r3 ; L/U
L24_bit_loop:
j exit_L24_bit
;***************************************************************************************
; The format reading for 24bits mono of 48k sampling from a0 of local mem is as
; Addr= 0
;
; msb..................................................lsb
; ( Upper 16 bits of 2nd sample,Upper 16 bits of 1st sample)
;
; Addr= 4
; ( Upper 16 bits of 3rd sample,Lower 8 bits of 1st sample,Lower 8 bits of 2nd sample)
;
; Addr= 8
; ( Lower 8 bits of 3rd sample,Lower 8 bits of 4th sample,Upper 16 bits of 4th sample )
;***************************************************************************************
;******************************************************
; Below is the 16 bit DAC sample manipulation
;******************************************************
enter_L24_48k:
loop 64, L24_48k_loop ;192/3
mov r3, a0(1*4)
mov a1(1*4), r3 ; 2 samples/wd for mono
shr r3,a0(1*4),16 ; throw away two 8 bits of lsb
shl r4,a0(1*4),16 ; throw away two 8 bits of lsb
or a1(1*4),r3,r4 ; another 2 samples/wd
L24_48k_loop:
exit_L24_bit:
movi TrapReg,1<<2
// decode X, Y here later
PCM_gain_adjust:
nop //done in "pcm_pcm"
// pack the pcm data according to number of channels
// get sample frequency
movi AGRAdr2, local_mid_buf_byte
movi r0, 0
// andi r1, r20, OCFG_SAMP_FREQ_MASK
// shr r1, OCFG_SAMP_FREQ_SHIFT
// tsti r1, 1
tsti r24,1
beq L96k_case
// ----------------------- 48k ----------------------------------
tsti r10, 1
beq L1_channel
tsti r10, 2
beq L2_channel
tsti r10, 3
beq L3_channel
tsti r10, 4
beq L4_channel
tsti r10, 5
beq L5_channel
tsti r10, 6
beq L6_channel
tsti r10, 7
beq L7_channel
tsti r10, 8
beq L8_channel
//---------------------------------------------------
L1_channel:
movi TrapReg,0
nop
nop
#ifdef I2S
loop 64, L1_channel_loop
mov r3, a2(0*4)
andi r3, 0xffff
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
mov a3(1*4), r0
mov a3(1*4), r0
mov a3(1*4), r0
shr r3, a2(1*4), 16
andi r3, 0xffff
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
mov a3(1*4), r0
mov a3(1*4), r0
mov a3(1*4), r0
L1_channel_loop:
#else
;****************************************************
; For mono, Left/Right has the same data as Sony
;****************************************************
movi r6,0xffff
loop 128, L1_channel_loop
shl r4, a2(0*4),16
and r3, r6,a2(0*4)
or r3, r4
mov a3(1*4), r3
mov a3(1*4), r0 ;clear the 4 non-existing channels
mov a3(1*4), r0
shr r4, a2(1*4), 16
mov r3,r4
shl r3, 16
or r3,r4
mov a3(1*4), r3
mov a3(1*4), r0 ;clear the 4 non-existing channels
mov a3(1*4), r0
L1_channel_loop:
#endif
movi TrapReg,1<<2
j Lchannel_continue
//---------------------------------------------------
L2_channel:
movi TrapReg,0
nop
nop
#ifdef I2S
movi r1, 0xffff
loop 64, L2_channel_loop
and r3, r1, a2(0*4)
mov a3(1*4), r3 //L
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
shr r3, a2(1*4), 16
mov a3(1*4), r3 //R
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
L2_channel_loop:
#else
loop 128, L2_channel_loop
mov r3, a2(1*4)
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
L2_channel_loop:
#endif
movi TrapReg,1<<2
j Lchannel_continue
//---------------------------------------------------
L3_channel:
tsti r19, 0
beq L3_first_blk
tsti r19, 1
beq L3_second_blk
tsti r19, 2
beq L3_third_blk
L3_first_blk:
jsr r29, SUB_3_channel
movi AGRAdr0, local_temp_buf_byte
mov r3, a2(1*4) //save 2 left-over words
mov a0(1*4), r3
mov r3, a2(1*4)
mov a0(1*4), r3
j Lchannel_continue
L3_second_blk:
movi AGRAdr0, local_temp_buf_byte
nop
mov r3, a0(1*4) //get left-over from previous block
mov a3(1*4), r3
mov r3, a0(0*4)
andi r3, 0xffff
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
shr r3, a0(1*4), 16
shl r4, a2(0*4), 16 //get new data
or a3(1*4), r3, r4
shr r3, a2(1*4), 16
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
jsr r29, SUB_3_channel
movi AGRAdr0, local_temp_buf_byte
mov r3, a2(1*4) //save 1 left-over words
mov a0(1*4), r3
j Lchannel_continue
L3_third_blk:
movi AGRAdr0, local_temp_buf_byte
nop
mov r3, a0(1*4) //get left-over from previous block
mov a3(1*4), r3
mov r3, a2(0*4) //get new data
andi r3, 0xffff
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
shr r3, a2(1*4), 16
shl r4, a2(0*4), 16 //get new data
or a3(1*4), r3, r4
shr r3, a2(1*4), 16
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
jsr r29, SUB_3_channel
j Lchannel_continue
//---------------------------------------------------
L4_channel:
movi TrapReg,0
nop
nop
#ifdef I2S
loop 32, L4_channel_loop
#else
loop 64, L4_channel_loop
#endif
mov r3, a2(0*4)
mov a3(1*4), r3
mov r3, a2(0*4)
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
L4_channel_loop:
movi TrapReg,1<<2
j Lchannel_continue
//---------------------------------------------------
L5_channel:
tsti r19, 0
beq L5_first_blk
tsti r19, 1
beq L5_second_blk
tsti r19, 2
beq L5_third_blk
tsti r19, 3
beq L5_fourth_blk
tsti r19, 4
beq L5_fifth_blk
L5_first_blk:
jsr r29, SUB_5_channel
mov r3, a2(1*4)
mov a3(1*4), r3
mov r3, a2(1*4)
mov a3(1*4), r3
mov r3, a2(0*4)
andi r3, 0xffff
mov a3(1*4), r3
movi AGRAdr0, local_temp_buf_byte
mov r3, a2(1*4) //save 1/2 left-over word
mov a0(1*4), r3
j Lchannel_continue
L5_second_blk:
movi AGRAdr0, local_temp_buf_byte
nop
shr r3, a0(1*4), 16 //get 1/2 left-over word
shl r4, a2(0*4), 16
or a3(1*4), r3, r4
shr r3, a2(1*4), 16
shl r4, a2(0*4), 16
or a3(1*4), r3, r4
shr r3, a2(1*4), 16
mov a3(1*4), r3
jsr r29, SUB_5_channel
movi AGRAdr0, local_temp_buf_byte
mov r3, a2(1*4) //save 1 left-over word
mov a0(1*4), r3
j Lchannel_continue
L5_third_blk:
/* movi AGRAdr0, local_temp_buf_byte
nop
mov r3, a0(1*4)
mov a3(1*4), r3
mov r3, a2(1*4)
mov a3(1*4), r3
mov r3, a2(0*4)
andi a3(1*4), r3, 0xffff
jsr r29, SUB_5_channel
*/
L5_fourth_blk:
L5_fifth_blk:
j Lchannel_continue
L6_channel:
L7_channel:
L8_channel:
Lchannel_continue:
nop
nop
j Lupdate_channel_count
//------------------------ 96k -----------------------------------
L96k_case:
tsti r10, 1
beq L1_channel_96k
tsti r10, 2
beq L2_channel_96k
tsti r10, 3
beq L3_channel_96k
tsti r10, 4
beq L4_channel_96k
tsti r10, 5
beq L5_channel_96k
tsti r10, 6
beq L6_channel_96k
tsti r10, 7
beq L7_channel_96k
tsti r10, 8
beq L8_channel_96k
//---------------------------------------------------
L1_channel_96k:
movi TrapReg,0
nop
nop
#ifdef I2S
loop 64, L1_channel_loop_96k
mov r3, a2(1*4)
andi r3, 0xffff //throw away second sample
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
mov a3(1*4), r0
mov a3(1*4), r0
mov a3(1*4), r0
L1_channel_loop_96k:
#else
loop 128, L1_channel_loop_96k
mov r3, a2(1*4)
andi r3, 0xffff //throw away second sample
mov a3(1*4), r3
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
L1_channel_loop_96k:
#endif
movi TrapReg,1<<2
j Lchannel_continue_96k
//---------------------------------------------------
L2_channel_96k:
movi TrapReg,0
nop
nop
#ifdef I2S
movi r1, 0xffff
loop 32, L2_channel_loop_96k
and r3, r1, a2(0*4)
mov a3(1*4), r3 //L
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
shr r3, a2(2*4), 16
mov a3(1*4), r3 //R
mov a3(1*4), r0 //clear the non-existing channels
mov a3(1*4), r0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -