⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm_pcm.s

📁 关于DVD的MPEG2用的DSP代码,在DSP的实现MPEG的压缩,解压算法.
💻 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 "user2.h"
#include "memory2.h"
#ifdef	EFFECT
#include "stereo_user.h"
#include "memory.h"
#endif	//EFFECT
#ifdef	MSW_ADD_QSOUND
#include "qx.h"
#endif	// MSW_ADD_QSOUND

	.data
	.list
	.extern	PCM_Config_Word
#ifdef	MSW_ADD_QSOUND
	.extern SUB_QSurround
	.extern	QSOUND_CMD_BUF
#endif	// MSW_ADD_QSOUND
	
	.globl	SUB_pcm_pcm
SUB_pcm_pcm:

#ifndef	EFFECT
	movb	r1, LBFIFO_flag
	movb	r4, LBblknum
#ifdef EXECTIVE
	subi	r4,1			// block count already increment
#endif
	tsti	r1, 0
	beq	no_checking_FIFO
#endif	//EFFECT
	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:	
#ifdef	FILE_OUT
	dlw	r1,PCM_Rd_Ptr	; read current pointer assigned by host
	nop
#else
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
#endif
#ifdef STREAM_SIM
	shr	r1, 16		; make it just the current address portion
#else
	andi	r1,0xffff
#endif
	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
#ifdef STREAM_SIM
				; 28c is PCM FIFO end address in real chip
				; and should contain full address,seg+offset
				; will be set by host for the time being.
	rswi	r1, 0x28c	; write to register
#endif
	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:	
		
	
			
#ifndef	EFFECT
	tsti	r4,0
	bne	Lskip_PTS
	movh	r28,LIfrmsize
	shl	r28,1
	movw	r1,LWbytecount
	add	r1,r28
	movw	LWbytecount,r1	
	jsr	r28,SUB_check_PTS
Lskip_PTS:
#endif

#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

//tchou
#if	0			//testing
//ZhangWei:MIC balance between normal playing and not playing
		dlw	r0,USER_ICFG
		nop
		andi	r0,ICFG_MIC_EXIST_MASK	;bit15 stands for ufone hardware
		tsti	r0,ICFG_MIC_EXIST_MASK
		bz	skip_ufon_only		;skip if non-existence

	movh    r0,LIstatus
	andi	r0,RUN_STOP_MASK	// check if process stopped 

	tsti	r0,STATUS_STOP
	beq		Lend_of_gain_loop	//only for ufone
skip_ufon_only:
#endif
// get the gain value by combining stream gain with user gain

	movw	r4, LWpcmscale		//gain from user
	movw	r0,LWFrameCount
	tsti	r0,40			// 18
	bgte	Lgain_setting_done
	movi	r4,0			// set gain to 0
Lgain_setting_done:
	
	movi	DMASize, 31		;32 words each block
#ifdef	EFFECT
	movi	BlockSkip, 5	;2
#else	//EFFECT
	movi	BlockSkip, 0
#endif	//EFFECT
	movi	BlockSize, 0		;block size = 1.

// apply the gain to the samples
	
	movi	r0, 0xffff		//lower 16-bit mask
	mupi	r1, 0xffff		//upper 16-bit mask
	movi	AGRAdr0, local_FApcm_buf_byte	
        dlw     r3,KARAOKE_0
	movi	TrapReg,0
        andi    r3,0x3
        tsti    r3,3                    // check KARAOKE_0
        beq     Lswap_lr                // R=melody, L=vocal
        tsti    r3,2
        beq     Ll_to_lr                // R=vocal, L=vocal
        tsti    r3,1
        beq     Lr_to_lr                // R=melody, L=melody
                                        // default: R=vocal, L=melody
#ifdef	EFFECT
	loop	8, Lpcm_gain_outer_lr2lr
#else	// EFFECT
	loop	24, Lpcm_gain_outer_lr2lr
#endif	// EFFECT
	loop	32, Lpcm_gain_inner_lr2lr
	mulhf	r6,r4,a0(2)		// r6=r4*L
	mulhf	r8,r4,a0(-2)		// r8=r4*R
	shl	r6,1
	shl	r8,1
	rndhf	a0(2),r6
	rndhf	a0(2),r8
Lpcm_gain_inner_lr2lr:
Lpcm_gain_outer_lr2lr:
	j	Lend_of_gain_loop
Lswap_lr:
#ifdef	EFFECT
	loop	8, Lpcm_gain_outer_slr
#else	// EFFECT
	loop	24, Lpcm_gain_outer_slr
#endif	// EFFECT
	loop	32, Lpcm_gain_inner_slr
	mulhf	r6,r4,a0(2)		// r6=r4*L
	mulhf	r8,r4,a0(0)		// r8=r4*R
	shl	r6,1
	shl	r8,1
	rndhf	a0(-2),r6
	rndhf	a0(4),r8
Lpcm_gain_inner_slr:
Lpcm_gain_outer_slr:
	j	Lend_of_gain_loop
Ll_to_lr:
#ifdef	EFFECT
	loop	8, Lpcm_gain_outer_l2lr
#else	// EFFECT
	loop	24, Lpcm_gain_outer_l2lr
#endif	// EFFECT
	loop	32, Lpcm_gain_inner_l2lr
	mulhf	r6,r4,a0(2)		// r6=r4*L
	mulhf	r8,r4,a0(-2)		// r8=r4*R
	shl	r6,1
	shl	r8,1
	rndhf	a0(2),r6
	rndhf	a0(2),r6
Lpcm_gain_inner_l2lr:
Lpcm_gain_outer_l2lr:
	j	Lend_of_gain_loop
Lr_to_lr:
#ifdef	EFFECT
	loop	8, Lpcm_gain_outer_r2lr
#else	// EFFECT
	loop	24, Lpcm_gain_outer_r2lr
#endif	// EFFECT
	loop	32, Lpcm_gain_inner_r2lr
	mulhf	r6,r4,a0(2)		// r6=r4*L
	mulhf	r8,r4,a0(-2)		// r8=r4*R
	shl	r6,1
	shl	r8,1
	rndhf	a0(2),r8
	rndhf	a0(2),r8
Lpcm_gain_inner_r2lr:
Lpcm_gain_outer_r2lr:
Lend_of_gain_loop:

#ifdef	MSW_ADD_QSOUND
	;; EFFECT must be defined so that we get 256 words of LR Stereo data.
	;; Each word contains a stereo pair (the order is R|L).
	;; The first thing to do is go to the end of the buffer and repack the
	;; data so that it is in the same format as we would get the ac3 6 channels.
	;; We start at the ends so that we does not trash any samples.
	;; I could just add it into the previous volume loop stuff.  But keep
	;; it completely seperate now for simplicity reasons

//	dlh	r0,COMMAND1
	dlh	r0,QSOUND_CMD_BUF
	nop
	tsti	r0,CMD1_QSOUND_A
	beq	foundPCMQSound
	tsti	r0,CMD1_QSOUND
	bne	noPCMQSound
foundPCMQSound:	

	movi	AGRSiz0, 0xffff
	movi	AGRSiz1, 0xffff


#ifdef	MSW_SAVE_LOCAL

	;; saved local memory I use in dram 32 words each of buffer, data
	;; and coeff - I do not actually use all 32 words of each component
	;; but it makes it a lot easier to save (can ignore whether three
	;; stage and/or highpass...).

	movi	r0, olddmaStuff
	shr	r0, 2 ; convert to word address
	movi	SizeSkip, (31 << 11 | 31 << 6 | 0)
	movi	r1, (local_buf>>2); convert to word
	mov	LocalAddr, r1
	dmawr	r0
qswaita:bdb	qswaita
	addi	r0,32
	
	movi	r1, (local_coeffs>>2); convert to word
	mov	LocalAddr, r1
	dmawr	r0
qswaitb:bdb	qswaitb
	addi	r0,32
		
	movi	r1, (local_data>>2); convert to word
	mov	LocalAddr, r1
	dmawr	r0
qswaitc:bdb	qswaitc
#endif	// MSW_SAVE_LOCAL
	

	;; stash r10 as we are going to destroy it.
	dsw	r10,dramlocalr10
	
	;; call qxpander
	jsr	r27, SUB_QXpander
	;; restore r10
	dlw	r10,dramlocalr10
#ifdef MSW_SAVE_LOCAL
	;; restore the locations that I used...
	movi	r0, olddmaStuff
	shr	r0, 2 ; convert to word address
	movi	SizeSkip, (31 << 11 | 31 << 6 | 0)
	movi	r1, (local_buf>>2); convert to word
	mov	LocalAddr,r1
	dmarr	r0
qswaitd:bdb	qswaitd
	addi	r0,32
	
	movi	r1, (local_coeffs>>2); convert to word
	mov	LocalAddr, r1
	dmarr	r0
qswaite:bdb	qswaite
	addi	r0,32
		
	movi	r1, (local_data>>2); convert to word
	mov	LocalAddr, r1
	dmawr	r0
qswaitf:bdb	qswaitf

#endif	// MSW_SAVE_LOCAL

	;; restore default dma stuff prior to my call
	movi	DMASize, 31		;32 words each block
#ifdef	EFFECT	
;	movi	BlockSkip, 5	;2
#else	//EFFECT
;	movi	BlockSkip, 0
#endif	//EFFECT
;	movi	BlockSize, 0		;block size = 1.

noPCMQSound:
#endif	// MSW_ADD_QSOUND
		
#if !LS388
	movi	TrapReg,1<<2
#endif // !LS388
	
	movi	r3, local_FApcm_buf_word	; word addr
	movi	AGRAdr1, local_FApcm_buf_byte
	shr	r9, r10, 2		; to word addr
	
#if !LS388
	dlw     r2,SPDIF_SET_FLAG
#endif // !LS388

#ifdef	EFFECT
	movi	StartAddrHigh,DataSeg
#endif	//EFFECT	

#if !LS388
	movi	TrapReg,0
	nop
	nop

	tsti	r2,1
	bne		skip_data_manipulation
#endif // !LS388

#if 0	// -------------------------------------------
	movi	BlockSkip, 4	
	movi	BlockSize, 1		;block size = 2
	movi	AGRAdr0,SP_draft_before_dram_byte - 4
	movi	AGRAdr1, local_FApcm_buf_byte + 1020	; 255 * 4 =1020

;	movi	AGRSiz0,0xffff
	movi	AGRSiz1,0xffff

	loop	256,spdif_raw_data	
	shr	r1,a1(0),8		
	mov	a0(-4),r1
	movhf	r2,a1(-4)
	mov	a0(-4),r2

spdif_raw_data:
	addi	r9,4

	loop	16, write_spdif_pcm_buf	;total of 256*2 words
	
	mov	LocalAddr, r3	
	dmawr	r9			     ;r10=FPApcmbufptr[outchan]=pcmptr2(init)
wait_dma_spdif_21:
	mov	r2,StatusPort
	tsti	r2,DmaDoneBit
	bz	wait_dma_spdif_21		;wait for dma done

	addi	r3, 32			;32 words each block

	addi	r9, 16 * 6		;32*3
write_spdif_pcm_buf:
	j	merge_pcm_spdif

skip_data_manipulation:

#ifdef	EFFECT
	loop	8, write_pcm_buf	;total of 256 words
#else	//EFFECT
	loop	24, write_pcm_buf	;total of 256*3 words
#endif	//EFFECT	
	mov	LocalAddr, r3	
	dmawr	r9			;r10=FPApcmbufptr[outchan]=pcmptr2(init)
wait_dma_21:
	mov	r2,StatusPort
	tsti	r2,DmaDoneBit
	bz	wait_dma_21		;wait for dma done

	addi	r3, 32			;32 words each block
#ifdef	EFFECT
	addi	r9, 32*6		;32*3
#else	//EFFECT
	addi	r9, 32
#endif	//EFFECT
	
write_pcm_buf:
	movi	r3, local_FApcm_buf_word	; word addr
	shr	r9, r10, 2		; to word addr
	addi	r9,1

	loop	256,pcm_local_data_shift  
	shr		r2,a1(0),16
	mov		a1(1*4),r2
pcm_local_data_shift:

#ifdef	EFFECT
	loop	8, write_pcm_hi_buf		;total of 256 words
#else	//EFFECT
	loop	24, write_pcm_hi_buf	;total of 256*3 words
#endif	//EFFECT	
	mov	LocalAddr, r3	
	dmawr	r9				;r10=FPApcmbufptr[outchan]=pcmptr2(init)
wait_dma_hi_21:
	mov	r2,StatusPort
	tsti	r2,DmaDoneBit
	bz	wait_dma_hi_21		;wait for dma done

	addi	r3, 32			;32 words each block
#ifdef	EFFECT
	addi	r9, 32*6		;32*3
#else	//EFFECT
	addi	r9, 32
#endif	//EFFECT
write_pcm_hi_buf:

#else	// -------------------------------------------
	movi	BlockSkip, 4	
	movi	BlockSize, 1		;block size = 2
	movi	AGRAdr0,SP_draft_before_dram_byte - 4
	movi	AGRAdr1, local_FApcm_buf_byte + 1020	; 255 * 4 =1020

	movi	AGRSiz1,0xffff
//*****************************************
//	Modified especially for Esona I2S D/A
//*****************************************

	rlwi	r1,PCM_Out_Ctrl
	andi	r1,0x0030
	tsti	r1,0
	bne		do_mpg_center_justified		; for non i2s

	loop	256,spdif_16bits_pcm_data
#if 0
	shr		r1,a1(0),16		
	mov		a0(-4),r1
	mov		r2,a1(-4)
	mov		a0(-4),r2
#else
	mov		r1,a1(0)
	mov		a0(-4),r1
	shr		r2,a1(-4),16
	mov		a0(-4),r2
#endif
spdif_16bits_pcm_data:
	j		spdif_raw_data	

do_mpg_center_justified:
/////////////////////////////////////////////////
	loop	256,spdif_raw_data
#if 0
	shr	r1,a1(0),16
	shl	r2,a1(0),16
	nop
	nop
	or	a1(0),r2,r1
	nop
	nop

	shr	r1,a1(0),8		
	mov	a0(-4),r1
	movhf	r2,a1(-4)
	mov	a0(-4),r2
#else
	shl	r1,a1(0),8
	mov	a0(-4),r1
//	shr	r2,a1(0),8
	shr	r2,a1(-4),8
	mov	a0(-4),r2
#endif
spdif_raw_data:
	addi	r9,4

	loop	16, write_spdif_pcm_buf	;total of 256*2 words
	
	mov	LocalAddr, r3	
	dmawr	r9			     ;r10=FPApcmbufptr[outchan]=pcmptr2(init)
	WaitDma

	addi	r3, 32			;32 words each block

	addi	r9, 16 * 6		;32*3
write_spdif_pcm_buf:

	subi	r9,(16*16*6+4)
	subi	r3,(32*16)

	movi	BlockSkip, 4	
	movi	BlockSize, 1		;block size = 2
	movi	AGRAdr1,SP_draft_before_dram_byte - 4
//*****************************************
//	Modified especially for Esona I2S D/A
//*****************************************

	rlwi	r1,PCM_Out_Ctrl
	andi	r1,0x0030
	tsti	r1,0
	beq		i2s_analog		; for non i2s


from_mpg_center_justified:
/////////////////////////////////////tanchou/////
	loop	256,spdif_to_pcm
#if 0
	shr	r1,a1(0),8		
	mov	a1(-4),r1
	shr	r1,a1(0),8		
	mov	a1(-4),r1
#else
	shr	r1,a1(-4),8
	shr	r2,a1(4),8
	mov	a1(-4),r2
	mov	a1(-4),r1
#endif
spdif_to_pcm:
	j	do_analog_pcm

i2s_analog:
	loop	256,swap_analog_pcm_data
	mov		r1,a1(-4)
	mov		r2,a1(4)
	mov		a1(-4),r2
	mov		a1(-4),r1
swap_analog_pcm_data:

do_analog_pcm:
	loop	16, write_pcm_buf	;total of 256*2 words

	mov	LocalAddr, r3	
	dmawr	r9			     ;r10=FPApcmbufptr[outchan]=pcmptr2(init)
	WaitDma

	addi	r3, 32			;32 words each block
	addi	r9, 16 * 6		;32*3
write_pcm_buf:

#endif	// -------------------------------------------

#if ENABLE_PSM
    nop
    jsr     r25,disp_spectrum
    nop
#endif		/* ENABLE_PSM */

merge_pcm_spdif:
	movi	TrapReg,1<<2
#ifdef	EFFECT
	movi	StartAddrHigh,MEM_SEG
#endif	//EFFECT	
	movi	BlockSkip, 0	
	movi	BlockSize, 0	

	
;; Make sure PCMOUT is enabled. This is only necessary for the
;; first time.

//	dlw	r1, PCM_Config_Word
//	nop				;pipeline 
//	rswi	r1, PCM_Out_Ctrl	; write to register

	dlw	r0,MUTE_FLAG
#ifdef	LS388
	movi	r1,0x31
#else	//LS388
	movi	r1, 0x1			; enable PCM output
#endif	//LS388
	tsti	r0,1
	beq	Lalready_on
#ifndef	R3K_PCM_OUT_CTRL
	rswi	r1, PCM_Run_Halt	; write to register
#endif	// R3K_PCM_OUT_CTRL
	dsw	r1,MUTE_FLAG
Lalready_on:	

	movi	r9, PCM_FIFO_1_START
	tsti	r10, PCM_FIFO_0_START
	beq	toggle_FIFO_ptr
	movi	r9, PCM_FIFO_0_START
toggle_FIFO_ptr:
	dsw	r9, FIFO_BLK_PTR	;toggle block ptr 

	movi	r1, 1
	movb	LBPCM_flag, r1		;set the flag

#ifndef	EFFECT
	rlwi	r0,STC
	movw	LWStartPTS,r0
#endif
	
#ifdef	LS240_PM
	j	Lnot_sleep
pcm_not_out:	
#ifndef	R3K_PCM_OUT_CTRL
	rlwi	r0,HOST_CTRL
	mupi	r1,0xffff
	ori	r1,0xffef	; DSP colck turned off

+	and	r0,r1
	rswi	r1,HOST_CTRL
#endif	// R3K_PCM_OUT_CTRL
Lnot_sleep:	
#else
pcm_not_out:
#endif	

#ifdef	EFFECT
	j	r31
#else	//EFFECT
	j	r27
#endif	//EFFECT	
	

#ifdef	MSW_ADD_QSOUND
#ifdef	MSW_SAVE_LOCAL
	.data
	.align 2
olddmaStuff:
	.fill	96,4,0		; to hold what ever exists in my local memory spaces
#endif	// MSW_SAVE_LOCAL
dramlocalr10:
	.data
	.align	2
	.word	0
#endif	// MSW_ADD_QSOUND

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -