📄 pcm.s
字号:
;
; Module: user
;
; Initial version: Jinshi Huang 11/6/98
;
; Call : r26 ; set up return address for called subroutine
; pcm_pcm SUB_Audio_Effect
; Permanent:
; Temp reg:
; AGR reg:
; Local buffer:
.nolist
; global include file
#include "regdef.h"
; local include file
#include "user.h"
#include "globalv.h"
#ifdef EFFECT
#include "stereo_user.h"
#endif //EFFECT
.list
.text
.global APP_Exit
.extern APP_Init
.extern APP_Main
.extern SUB_PCM_decoder
.extern SUB_pcm_pcm
.extern SUB_SPF_decoder
.extern SUB_SPF_pcm
.extern SUB_isr
.extern SUB_seek_DTS_SYNC
#ifdef EFFECT
.extern SUB_Audio_Effect
.extern main_audio_task
.extern mid_buf_rd_ptr
.extern mid_buf_wr_ptr
.extern ok_decode_flag
.extern r31_temp
.extern clr_buf_flag
.extern EFFECT_COMMAND
#endif //EFFECT
.extern PCM_Config_Word
.extern MIN_IBUF_VAR
.extern MUTE_FLAG
.extern TEMP_MpegAttr
.globl ProgStart
.globl LoopStart
.globl _start
#if DEBUGGER
.extern SUB_DSP_DEBUGGER
.extern dbg_last_inst
#endif // DEBUGGER
#if DEBUGGER
#define START_DECODE_TIME 0xf200
#define END_DECODE_TIME 0xf204
#define MAX_DURATION 0xf208
#define BLOCK_PERIOD 0xf20c
#define DEBUG_BUF_PTR 0xf210
#define DEBUG_BUF 0xf300
#define DEBUG_BUF_END 0xf400
#endif
.set noreorder
_start:
movi DcacheBase,MEM_SEG
movi StartAddrHigh,MEM_SEG
j ProgStart
.align 4
#if DEBUGGER
j SUB_DSP_DEBUGGER // break point
la r0,dbg_last_inst // RETURN_OFFSET (addr: 0x1f1814)
#else // DEBUGGER
ret
#endif // DEBUGGER
.align 4
#if DEBUGGER
j SUB_DSP_DEBUGGER // debug
#else // DEBUGGER
ret
#endif // DEBUGGER
.align 4
#if DEBUGGER
j SUB_DSP_DEBUGGER // debug
#else //DEBUGGER
#if LS388
ret
#else // LS388
j SUB_isr // interrupt
#endif // LS388
#endif //DEBUGGER
.align 4
ProgStart:
//
// init section
//
li r0,0xffffffff
dsw r0,COMMAND0 // clear command
#if 1 //ENABLE_APP
jsr r31, APP_Init
nop
#endif
movw r20,LWtitlekey0
dsw r20,Drv_RD
rswi r20,0x3c>>2
movb r20,LBtitlekey4
dsw r20,Drv_RD+4
rswi r20,0x38>>2
#if LS388
movi r0,PCM_MIN_IBUF_DEPTH/2 // - used in SUB_consume_data
#else
movi r0,PCM_MIN_IBUF_DEPTH
#endif // LS388
movh LIfrmsize,r0 // use default as depth to start with
#if THREEPAGE
mupi r0,MEM_SEG12 // init input buffer write pointer
#else // THREEPAGE
mupi r0,MEM_SEG // init input buffer write pointer
#endif // THREEPAGE
addi r1,r0,PCM_IBUF_START
movw LWibufRdPtr,r1
// dsw r1,Stream_Wr_Ptr
// dsw r1,Stream_Rd_Ptr
SvStrWrPtr r1
nop
SvStrRdPtr r1
#if LS388
andi r2,r1,0xffff
movh LIold_rd_ptr,r2
rswi r1, Comm_Reg3 //for host
#endif // LS388
dsw r1,Stream_Start
addi r1,PCM_IBUF_SIZE
dsw r1,Stream_End
mupi r0,MEM_SEG // init input buffer write pointer
addi r1,r0,PTS_FIFO_START
dsw r1,PTS_FIFO_Start
// dsw r1,PTS_FIFO_Rd_Ptr
// dsw r1,PTS_FIFO_Wr_Ptr
SvPTSRdPtr r1
SvPTSWrPtr r1
addi r1,r0,PTS_FIFO_END
dsw r1,PTS_FIFO_End
mupi r0,DataSeg
addi r2,r0,OBUF_START
rswi r2,PCM_Start_Addr
addi r2,OBUF_SIZE
rswi r2,PCM_End_Addr
; li r0,0x20000040 //SPDIF PCM
; rswi r0,SPDIF_channel_status
rlwi r0,AUDIO_CTRL //reg 200
ori r0,2
#if LS388
#else
rswi r0,AUDIO_CTRL //turn on Host_PCM_Run
#endif // LS388
movi r0,1
movb LBPCM_flag,r0 // set PCM_flag done
movi r0,0x0
movb LBFIFO_flag,r0
dsw r0,FIFO_BLK_PTR //need this for mute to work
movb LBPCMlow,r0 // set PCM buffer empty
movi r0,1
movb LBblknum,r0 //match convention of AC-3
movi r0,0x800
movh LIMpegAttr,r0 // init for qt_snc
movi r0,0
movb LBDriver,r0 // Default as loader DVD
movw LWbytecount,r0 // init byte count
movw LWoldPTS,r0 // init old PTS
// dsw r0,COMMAND0 // clear command
ori r0,SET_PROCESS_NEW // set process, new
movh LIstatus,r0 // init status
jsr r31,SUB_clear_PCM // clear PCM before enable PCM out
movi r0,0
dsw r0,MUTE_FLAG
#if !LS388
rswi r0,PCM_Run_Halt
#endif // LS388
tsti r0,1
beq Lno_pulse
movi r0,1
#if !LS388
rswi r0,PCM_Run_Halt
#endif // LS388
rlwi r0,AUDIO_CTRL // pulse
ori r0,0x20
#if LS388
#else
rswi r0,AUDIO_CTRL
#endif // LS388
andi r0,0xffdf
#if LS388
#else
rswi r0,AUDIO_CTRL
#endif // LS388
movi r0,0
#if !LS388
rswi r0,PCM_Run_Halt
#endif // LS388
Lno_pulse:
movi r0, PCM_MIN_IBUF_DEPTH //default
dsw r0, MIN_IBUF_VAR
li r0, 0x7fffff //default to unity gain
movw LWpcmscale,r0
jsr r31,SUB_clear_keyshift_context
movi r0,SUB_Audio_Effect
dsw r0,Audio_Effect_Entry
#if LS388
//#ifdef R3K_PCM_OUT_CTRL
//wait_for_r3k_PCM_init:
// rlwi r0,PCM_Out_Ctrl
// andi r0,0x7449
// tsti r0,0x7449
// bne wait_for_r3k_PCM_init
// rlwi r0,PCM_Run_Halt
// tsti r0,0x31
// beq pcm_running
//#endif // R3K_PCM_OUT_CTRL
movi r0, 0x6c0
rswi r0,PCM_Run_Halt
movi r0,0x31
rswi r0,PCM_Run_Halt
pcm_running:
#ifndef R3K_PCM_OUT_CTRL
movi r0,0x3a
rswi r0,AUDIO_CTRL
movi r0,0x1a
rswi r0,AUDIO_CTRL
#endif // R3K_PCM_OUT_CTRL
li r0,0x7fffff
dsw r0,PCM_SCALE
#endif // LS388
//
// enable interrupt
//
#ifdef LS240_PM
rlwi r20,DSP_INT_CTRL
mupi r0,0x0002 ; middle PCM fifo interrupt
ori r0,0x0040 ; first audio sample interrupt
or r20,r0
rswi r20,DSP_INT_CTRL
#endif
movi TrapReg,1<<2 // enable int
LoopStart:
//====================================================================================
// check application command --white
//====================================================================================
#if 1 //ENABLE_APP
nop
j APP_Main // SHENZHEN application
nop
nop
nop
#endif
APP_Exit:
nop
movi DcacheBase,MEM_SEG
nop
nop
nop
///// Corin Added for checking PCM Gain every time////
dlw r1,PCM_SCALE
nop
movw LWpcmscale,r1
//////////////////////////////////////////////////////
//
// get command from memory
//
dlw r0,COMMAND0 // get command from host(DRAM)
nop
andi r0,0xff
tsti r0,CMD_NOP // check if it's a NOP
beq LcheckStatus
tsti r0,0xff
bne ExecCmd // exec and clear command
movi r0,0x100
dsw r0,COMMAND0 // clear command
LcheckStatus:
movh r1,LIstatus // read in current status
andi r0,r1,RUN_STOP_MASK // check if process stopped
tsti r0,STATUS_STOP
#ifndef LS240_PM
/* checking QSOUND command to avoid R3K lock up */
bne Lno_chk_qsnd_cmd
dlw r0,COMMAND1
nop
tsti r0,CMD1_QSOUND
beq Lupdate_qsnd_cmd
tsti r0,CMD1_QSOUND_A
beq Lupdate_qsnd_cmd
tsti r0,CMD1_QSOUND_OFF
bne Lchk_qsnd_done
Lupdate_qsnd_cmd:
movi DcacheBase, DataSeg
nop
dsw r0,QSOUND_CMD_BUF
nop
movi DcacheBase, MEM_SEG
Lchk_qsnd_done:
j LoopStart
Lno_chk_qsnd_cmd:
#else // LS240_PM
beq LCheckSleep // if STOP, see whether to sleep
andi r0,r1,PAUSE
tsti r0,PAUSE
bne LCheckPCM_flag // if not STOP, nor PAUSE, normal path
LCheckSleep:
dlw r1,MUTE_FLAG // if STOP/PAUSE, see whether to sleep
rlwi r0,HOST_CTRL
tsti r1,1
bne LoopStart // if PCM FIFO not running, normal path
mupi r1,0xffff
ori r1,0xffef // DSP colck turned off
and r0,r1
#if !LS388
rswi r0,HOST_CTRL
#endif // LS388
j LoopStart
#endif // LS240_PM
LCheckPCM_flag:
#ifndef EFFECT
movb r1,LBPCM_flag
tsti r1,1 // test bit 0
bne LCheckPCM // skip decoder, wait until set
#endif //EFFECT
#ifndef FILE_OUT
Lcheck_ibuf_depth:
// dlw r1,Stream_Wr_Ptr
// dlw r0,Stream_Rd_Ptr
LdStrWrPtr r1
LdStrRdPtr r0
dlw r2,MIN_IBUF_VAR
nop
tst r1,r0
bgte Lcheck_space
addi r1,PCM_IBUF_SIZE // always assume wr ahead of rd
Lcheck_space:
sub r1,r0
// movh r2,LIfrmsize
// shl r2,1
tst r1, r2
bgte Lcheck_status
li r2,PLL_CTRL_48K
rlwi r0,PLL_Ctrl_Reg2
tst r0,r2
bne go_clear_PCM // clear PCM if CDDA is being played
rlwi r0,STC
// movw r2,LWoldPTS
movw r2,LWStartPTS
sub r1,r0,r2
// tsti r1,0xb40 // check if I/O out of sync
tsti r1,0x1e0 // 1 block duration
// blte LoopStart
blte delay2LoopStart
movw LWoldPTS,r0
movb r0,LBPCMlow
tsti r0,1
beq LoopStart
movi r0,1
movb LBPCMlow,r0
movh r0,LIMpegAttr
andi r1,r0,0x1000
tsti r1,0
bne delay2LoopStart
ori r0,0x1000
movh LIMpegAttr,r0 // set hungry flag
go_clear_PCM:
dlb r0,clr_buf_flag
movi r1,1
tsti r0,0
bne clear_PCM_already
dsb r1,clr_buf_flag
jsr r31,SUB_clear_PCM //tchou clear PCM if PCM underflow
clear_PCM_already:
delay2LoopStart:
#if 0
dlw r0,0xff34
nop
tsti r0,0
bne 1f
movi r0,1
#else
movi r0,16
#endif
1:
nop
loop 16,delay_loop1
nop
nop
nop
nop
delay_loop1:
subi r0,1
tsti r0,0
bne 1b
j LoopStart
#endif
Lcheck_status: // no error message to check for PCM
Ldo_decode:
movh r0,LIMpegAttr
andi r0,0xefff
movh LIMpegAttr,r0 // clear hungry flag
andi r0,0x00b0 //STEP or FF/FB or fast/slow play mode
tsti r0,0
beq Lnormal_decode
#if 1
dlb r0,clr_buf_flag
movi r1,1
tsti r0,0
bne clear_PCM_once
dsb r1,clr_buf_flag
jsr r31,SUB_clear_PCM //tchou
// jsr r27,SUB_clr_all_downmix
clear_PCM_once:
jsr r31,SUB_consume_data //update bytecount w/o decoding
// j rtn_decoder
j LoopStart
#endif // 1
Lnormal_decode:
movi r0,0
dsb r0,clr_buf_flag
#ifdef EFFECT
dlw r0,mid_buf_rd_ptr
dlw r1,mid_buf_wr_ptr
nop
sub r2,r0,r1 //gap from wr_ptr to rd_ptr
tsti r2,0
bgt Lno_mid_wrap
addi r2,MIDDLE_BUF_SIZE
Lno_mid_wrap:
#if DEBUGGER
//xxx dsw r2,0xf100 //debug
#endif //DEBUGGER
tsti r2,256*4*3 //samples produced in each block
blte Lno_decoding
dlw r3,ok_decode_flag
nop
tsti r3,3
bgte Lno_inc
addi r3,1
dsw r3,ok_decode_flag
Lno_inc:
#endif //EFFECT
#ifdef REAL_TIME
rlwi r0,STC
dsw r0,START_DECODE_TIME
#endif
#if DEBUGGER
dlw r2,0xf140
nop
addi r2,1
dsw r2,0xf140
dlw r3,DEBUG_BUF_PTR
nop
dswr r1,r3 //wr
addi r3,4
nop
dswr r0,r3 //rd
addi r3,4
rlwi r1, PCM_Rd_Ptr
// movw r1,LWentry
dswr r1,r3 //pcm_ptr
addi r3,4
// dlw r1,Stream_Rd_Ptr
movb r1,LBblknum
nop
dswr r1,r3 //stream_rd_ptr
addi r3,4
tsti r3,DEBUG_BUF_END
blt Lno_db_wrap
movi r3,DEBUG_BUF
Lno_db_wrap:
dsw r3,DEBUG_BUF_PTR
#endif //DEBUGGER
/////=== Test channel number, do DTS sync seeking =================
dlh r0, DiskAttrib+2
dlh r1, DiskAttrib
tsti r0, 0x800 // test if seek sync over 10 seconds
bgte DTS_CD
tsti r1, 1 // test if a DTS CD
beq DTS_CD
jsr r29, SUB_seek_DTS_SYNC
dlh r1, DiskAttrib
nop
tsti r1, 1
bne DTS_CD
jsr r31, SUB_clear_PCM
DTS_CD:
/////==============================================================
// call decoder
movi r0,MEM_SEG
andi r0,0x3
shl r0,16
la r31,rtn_decoder
or r31,r0
movw r1,LWentry // set up subroutine entry
or r1,r0
j r1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -